summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicardo Cerqueira <cyanogenmod@cerqueira.org>2013-11-01 16:04:19 +0000
committerRicardo Cerqueira <cyanogenmod@cerqueira.org>2013-11-01 16:04:19 +0000
commit5b18c5874f85aa819ddef822b95a66ca070421dc (patch)
treec75d7dc57e133b09dc56c1e6e58f74b2f86238ba
parent8afe960626dbf326354b836fd4d63e05b6974195 (diff)
parent899c67b6cfcd2010784fbf08c5415af16c526e0c (diff)
downloadandroid_external_freetype-stable/cm-11.0-XNF8Y.tar.gz
android_external_freetype-stable/cm-11.0-XNF8Y.tar.bz2
android_external_freetype-stable/cm-11.0-XNF8Y.zip
Android 4.4 Release 1.0
-rw-r--r--Android.mk8
-rw-r--r--include/freetype/config/ftconfig.h49
-rw-r--r--include/freetype/config/ftheader.h41
-rw-r--r--include/freetype/config/ftoption.h92
-rw-r--r--include/freetype/config/ftstdlib.h4
-rw-r--r--include/freetype/freetype.h124
-rw-r--r--include/freetype/ftadvanc.h21
-rw-r--r--include/freetype/ftautoh.h349
-rw-r--r--include/freetype/ftbitmap.h8
-rw-r--r--include/freetype/ftcache.h89
-rw-r--r--include/freetype/ftcffdrv.h151
-rw-r--r--include/freetype/ftchapters.h16
-rw-r--r--include/freetype/fterrdef.h6
-rw-r--r--include/freetype/fterrors.h23
-rw-r--r--include/freetype/ftglyph.h2
-rw-r--r--include/freetype/ftimage.h15
-rw-r--r--include/freetype/ftlcdfil.h38
-rw-r--r--include/freetype/ftmodapi.h168
-rw-r--r--include/freetype/ftmoderr.h64
-rw-r--r--include/freetype/ftoutln.h26
-rw-r--r--include/freetype/ftstroke.h14
-rw-r--r--include/freetype/ftsynth.h7
-rw-r--r--include/freetype/fttrigon.h10
-rw-r--r--include/freetype/ftttdrv.h150
-rw-r--r--include/freetype/fttypes.h28
-rw-r--r--include/freetype/internal/autohint.h71
-rw-r--r--include/freetype/internal/ftcalc.h50
-rw-r--r--include/freetype/internal/ftdebug.h28
-rw-r--r--include/freetype/internal/ftdriver.h398
-rw-r--r--include/freetype/internal/ftmemory.h176
-rw-r--r--include/freetype/internal/ftobjs.h810
-rw-r--r--include/freetype/internal/ftpic.h32
-rw-r--r--include/freetype/internal/ftrfork.h41
-rw-r--r--include/freetype/internal/ftserv.h115
-rw-r--r--include/freetype/internal/ftstream.h87
-rw-r--r--include/freetype/internal/fttrace.h10
-rw-r--r--include/freetype/internal/ftvalid.h15
-rw-r--r--include/freetype/internal/psaux.h10
-rw-r--r--include/freetype/internal/pshints.h42
-rw-r--r--include/freetype/internal/services/svprop.h81
-rw-r--r--include/freetype/internal/sfnt.h454
-rw-r--r--include/freetype/internal/t1types.h6
-rw-r--r--include/freetype/internal/tttypes.h121
-rw-r--r--include/freetype/ttnameid.h20
-rw-r--r--include/freetype/tttables.h18
-rw-r--r--include/freetype/tttags.h4
-rw-r--r--src/autofit/afangles.c65
-rw-r--r--src/autofit/afcjk.c38
-rw-r--r--src/autofit/afcjk.h11
-rw-r--r--src/autofit/afdummy.c9
-rw-r--r--src/autofit/afglobal.c95
-rw-r--r--src/autofit/afglobal.h46
-rw-r--r--src/autofit/afhints.c222
-rw-r--r--src/autofit/afhints.h20
-rw-r--r--src/autofit/afindic.c8
-rw-r--r--src/autofit/afindic.h4
-rw-r--r--src/autofit/aflatin.c371
-rw-r--r--src/autofit/aflatin.h19
-rw-r--r--src/autofit/aflatin2.c180
-rw-r--r--src/autofit/aflatin2.h4
-rw-r--r--src/autofit/afloader.c53
-rw-r--r--src/autofit/afloader.h30
-rw-r--r--src/autofit/afmodule.c219
-rw-r--r--src/autofit/afmodule.h21
-rw-r--r--src/autofit/afpic.c51
-rw-r--r--src/autofit/afpic.h48
-rw-r--r--src/autofit/aftypes.h38
-rw-r--r--src/base/basepic.c47
-rw-r--r--src/base/basepic.h45
-rw-r--r--src/base/ftadvanc.c20
-rw-r--r--src/base/ftbbox.c251
-rw-r--r--src/base/ftbitmap.c113
-rw-r--r--src/base/ftcalc.c110
-rw-r--r--src/base/ftdbgmem.c105
-rw-r--r--src/base/ftdebug.c28
-rw-r--r--src/base/ftgloadr.c9
-rw-r--r--src/base/ftglyph.c30
-rw-r--r--src/base/ftinit.c8
-rw-r--r--src/base/ftlcdfil.c14
-rw-r--r--src/base/ftmm.c20
-rw-r--r--src/base/ftobjs.c493
-rw-r--r--src/base/ftoutln.c298
-rw-r--r--src/base/ftpic.c3
-rw-r--r--src/base/ftrfork.c44
-rw-r--r--src/base/ftsnames.c2
-rw-r--r--src/base/ftstream.c55
-rw-r--r--src/base/ftstroke.c25
-rw-r--r--src/base/ftsynth.c25
-rw-r--r--src/base/ftsystem.c8
-rw-r--r--src/base/fttrigon.c286
-rw-r--r--src/base/fttype1.c4
-rw-r--r--src/base/ftutil.c79
-rw-r--r--src/base/ftwinfnt.c2
-rw-r--r--src/base/md5.c295
-rw-r--r--src/base/md5.h45
-rw-r--r--src/cache/ftcbasic.c275
-rw-r--r--src/cache/ftccache.c11
-rw-r--r--src/cache/ftccache.h13
-rw-r--r--src/cache/ftccback.h5
-rw-r--r--src/cache/ftccmap.c111
-rw-r--r--src/cache/ftcmanag.h6
-rw-r--r--src/cache/ftcsbits.c10
-rw-r--r--src/cff/cf2arrst.c241
-rw-r--r--src/cff/cf2arrst.h100
-rw-r--r--src/cff/cf2blues.c578
-rw-r--r--src/cff/cf2blues.h185
-rw-r--r--src/cff/cf2error.c52
-rw-r--r--src/cff/cf2error.h119
-rw-r--r--src/cff/cf2fixed.h95
-rw-r--r--src/cff/cf2font.c401
-rw-r--r--src/cff/cf2font.h114
-rw-r--r--src/cff/cf2ft.c639
-rw-r--r--src/cff/cf2ft.h147
-rw-r--r--src/cff/cf2glue.h144
-rw-r--r--src/cff/cf2hints.c1733
-rw-r--r--src/cff/cf2hints.h287
-rw-r--r--src/cff/cf2intrp.c1538
-rw-r--r--src/cff/cf2intrp.h83
-rw-r--r--src/cff/cf2read.c112
-rw-r--r--src/cff/cf2read.h68
-rw-r--r--src/cff/cf2stack.c205
-rw-r--r--src/cff/cf2stack.h106
-rw-r--r--src/cff/cf2types.h78
-rw-r--r--src/cff/cff.c13
-rw-r--r--src/cff/cffcmap.c6
-rw-r--r--src/cff/cffdrivr.c180
-rw-r--r--src/cff/cffgload.c223
-rw-r--r--src/cff/cffgload.h41
-rw-r--r--src/cff/cffload.c92
-rw-r--r--src/cff/cffobjs.c75
-rw-r--r--src/cff/cffobjs.h12
-rw-r--r--src/cff/cffparse.c157
-rw-r--r--src/cff/cffpic.c72
-rw-r--r--src/cff/cffpic.h81
-rw-r--r--src/cff/cfftypes.h5
-rw-r--r--src/pfr/pfrload.c28
-rw-r--r--src/psaux/afmparse.c45
-rw-r--r--src/psaux/psconv.c208
-rw-r--r--src/psaux/psconv.h10
-rw-r--r--src/psaux/psobjs.c141
-rw-r--r--src/psaux/t1decode.c70
-rw-r--r--src/pshinter/pshalgo.c17
-rw-r--r--src/pshinter/pshalgo.h11
-rw-r--r--src/pshinter/pshglob.c51
-rw-r--r--src/pshinter/pshmod.c17
-rw-r--r--src/pshinter/pshpic.c17
-rw-r--r--src/pshinter/pshpic.h16
-rw-r--r--src/pshinter/pshrec.c53
-rw-r--r--src/psnames/psmodule.c58
-rw-r--r--src/psnames/pspic.c19
-rw-r--r--src/psnames/pspic.h23
-rw-r--r--src/raster/ftmisc.h21
-rw-r--r--src/raster/ftraster.c122
-rw-r--r--src/raster/ftrend1.c21
-rw-r--r--src/raster/rastpic.c32
-rw-r--r--src/raster/rastpic.h18
-rw-r--r--src/sfnt/pngshim.c336
-rw-r--r--src/sfnt/pngshim.h48
-rw-r--r--src/sfnt/sfdriver.c318
-rw-r--r--src/sfnt/sferrors.h4
-rw-r--r--src/sfnt/sfnt.c3
-rw-r--r--src/sfnt/sfntpic.c37
-rw-r--r--src/sfnt/sfntpic.h81
-rw-r--r--src/sfnt/sfobjs.c128
-rw-r--r--src/sfnt/ttbdf.c16
-rw-r--r--src/sfnt/ttcmap.c389
-rw-r--r--src/sfnt/ttcmap.h99
-rw-r--r--src/sfnt/ttcmapc.h19
-rw-r--r--src/sfnt/ttkern.c2
-rw-r--r--src/sfnt/ttload.c60
-rw-r--r--src/sfnt/ttmtx.c195
-rw-r--r--src/sfnt/ttpost.c22
-rw-r--r--src/sfnt/ttsbit.c2017
-rw-r--r--src/sfnt/ttsbit.h18
-rw-r--r--src/sfnt/ttsbit0.c1011
-rw-r--r--src/smooth/ftgrays.c102
-rw-r--r--src/smooth/ftsmooth.c80
-rw-r--r--src/smooth/ftspic.c37
-rw-r--r--src/smooth/ftspic.h17
-rw-r--r--src/truetype/truetype.c3
-rw-r--r--src/truetype/ttdriver.c132
-rw-r--r--src/truetype/ttgload.c367
-rw-r--r--src/truetype/ttgxvar.c105
-rw-r--r--src/truetype/ttinterp.c1563
-rw-r--r--src/truetype/ttinterp.h79
-rw-r--r--src/truetype/ttobjs.c87
-rw-r--r--src/truetype/ttobjs.h25
-rw-r--r--src/truetype/ttpic.c21
-rw-r--r--src/truetype/ttpic.h39
-rw-r--r--src/truetype/ttpload.c26
-rw-r--r--src/truetype/ttsubpix.c1011
-rw-r--r--src/truetype/ttsubpix.h110
192 files changed, 18299 insertions, 7827 deletions
diff --git a/Android.mk b/Android.mk
index 51ae31b..e357397 100644
--- a/Android.mk
+++ b/Android.mk
@@ -37,13 +37,17 @@ LOCAL_SRC_FILES:= \
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/builds \
- $(LOCAL_PATH)/include
+ $(LOCAL_PATH)/include \
+ external/libpng \
+ external/zlib
LOCAL_CFLAGS += -W -Wall
LOCAL_CFLAGS += -fPIC -DPIC
LOCAL_CFLAGS += "-DDARWIN_NO_CARBON"
LOCAL_CFLAGS += "-DFT2_BUILD_LIBRARY"
+LOCAL_SHARED_LIBRARIES += libpng libz
+
# the following is for testing only, and should not be used in final builds
# of the product
#LOCAL_CFLAGS += "-DTT_CONFIG_OPTION_BYTECODE_INTERPRETER"
@@ -52,5 +56,5 @@ LOCAL_CFLAGS += -O2
LOCAL_MODULE:= libft2
-include $(BUILD_STATIC_LIBRARY)
+include $(BUILD_SHARED_LIBRARY)
endif
diff --git a/include/freetype/config/ftconfig.h b/include/freetype/config/ftconfig.h
index 5628569..5dce30e 100644
--- a/include/freetype/config/ftconfig.h
+++ b/include/freetype/config/ftconfig.h
@@ -4,7 +4,7 @@
/* */
/* ANSI-specific configuration file (specification only). */
/* */
-/* Copyright 1996-2004, 2006-2008, 2010-2011 by */
+/* Copyright 1996-2004, 2006-2008, 2010-2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -200,6 +200,30 @@ FT_BEGIN_HEADER
/* */
typedef unsigned XXX FT_UInt32;
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Int64 */
+ /* */
+ /* A typedef for a 64bit signed integer type. The size depends on */
+ /* the configuration. Only defined if there is real 64bit support; */
+ /* otherwise, it gets emulated with a structure (if necessary). */
+ /* */
+ typedef signed XXX FT_Int64;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_UInt64 */
+ /* */
+ /* A typedef for a 64bit unsigned integer type. The size depends on */
+ /* the configuration. Only defined if there is real 64bit support; */
+ /* otherwise, it gets emulated with a structure (if necessary). */
+ /* */
+ typedef unsigned XXX FT_UInt64;
+
/* */
#endif
@@ -239,13 +263,15 @@ FT_BEGIN_HEADER
/* FT_LONG64 must be defined if a 64-bit type is available */
#define FT_LONG64
-#define FT_INT64 long
+#define FT_INT64 long
+#define FT_UINT64 unsigned long
#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
/* this compiler provides the __int64 type */
#define FT_LONG64
-#define FT_INT64 __int64
+#define FT_INT64 __int64
+#define FT_UINT64 unsigned __int64
#elif defined( __BORLANDC__ ) /* Borland C++ */
@@ -254,7 +280,8 @@ FT_BEGIN_HEADER
/* this compiler provides the __int64 type */
#define FT_LONG64
-#define FT_INT64 __int64
+#define FT_INT64 __int64
+#define FT_UINT64 unsigned __int64
#elif defined( __WATCOMC__ ) /* Watcom C++ */
@@ -263,13 +290,15 @@ FT_BEGIN_HEADER
#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */
#define FT_LONG64
-#define FT_INT64 long long int
+#define FT_INT64 long long int
+#define FT_UINT64 unsigned long long int
#elif defined( __GNUC__ )
/* GCC provides the `long long' type */
#define FT_LONG64
-#define FT_INT64 long long int
+#define FT_INT64 long long int
+#define FT_UINT64 unsigned long long int
#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
@@ -293,6 +322,11 @@ FT_BEGIN_HEADER
#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */
+#ifdef FT_LONG64
+ typedef FT_INT64 FT_Int64;
+ typedef FT_UINT64 FT_UInt64;
+#endif
+
#define FT_BEGIN_STMNT do {
#define FT_END_STMNT } while ( 0 )
@@ -355,7 +389,8 @@ FT_BEGIN_HEADER
"mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */
"orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */
: "=r"(a), "=&r"(t2), "=&r"(t)
- : "r"(a), "r"(b) );
+ : "r"(a), "r"(b)
+ : "cc" );
return a;
}
diff --git a/include/freetype/config/ftheader.h b/include/freetype/config/ftheader.h
index 2a7b8c4..8371a31 100644
--- a/include/freetype/config/ftheader.h
+++ b/include/freetype/config/ftheader.h
@@ -4,7 +4,7 @@
/* */
/* Build macros of the FreeType 2 library. */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */
+/* Copyright 1996-2008, 2010, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -318,6 +318,45 @@
/*************************************************************************
*
* @macro:
+ * FT_AUTOHINTER_H
+ *
+ * @description:
+ * A macro used in #include statements to name the file containing
+ * structures and macros related to the auto-hinting module.
+ *
+ */
+#define FT_AUTOHINTER_H <freetype/ftautoh.h>
+
+
+ /*************************************************************************
+ *
+ * @macro:
+ * FT_CFF_DRIVER_H
+ *
+ * @description:
+ * A macro used in #include statements to name the file containing
+ * structures and macros related to the CFF driver module.
+ *
+ */
+#define FT_CFF_DRIVER_H <freetype/ftcffdrv.h>
+
+
+ /*************************************************************************
+ *
+ * @macro:
+ * FT_TRUETYPE_DRIVER_H
+ *
+ * @description:
+ * A macro used in #include statements to name the file containing
+ * structures and macros related to the TrueType driver module.
+ *
+ */
+#define FT_TRUETYPE_DRIVER_H <freetype/ftttdrv.h>
+
+
+ /*************************************************************************
+ *
+ * @macro:
* FT_TYPE1_TABLES_H
*
* @description:
diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h
index c41f089..bc239bf 100644
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -4,7 +4,7 @@
/* */
/* User-selectable configuration macros (specification only). */
/* */
-/* Copyright 1996-2011 by */
+/* Copyright 1996-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -216,6 +216,20 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
+ /* PNG bitmap support. */
+ /* */
+ /* FreeType now handles loading color bitmap glyphs in the PNG format. */
+ /* This requires help from the external libpng library. Uncompressed */
+ /* color bitmaps do not need any external libraries and will be */
+ /* supported regardless of this configuration. */
+ /* */
+ /* Define this macro if you want to enable this `feature'. */
+ /* */
+#define FT_CONFIG_OPTION_USE_PNG
+
+
+ /*************************************************************************/
+ /* */
/* DLL export compilation */
/* */
/* When compiling FreeType as a DLL, some systems/compilers need a */
@@ -560,6 +574,28 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
+ /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */
+ /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */
+ /* replaces the native TrueType hinting mechanism when anything but */
+ /* FT_RENDER_MODE_MONO is requested. */
+ /* */
+ /* Enabling this causes the TrueType driver to ignore instructions under */
+ /* certain conditions. This is done in accordance with the guide here, */
+ /* with some minor differences: */
+ /* */
+ /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */
+ /* */
+ /* By undefining this, you only compile the code necessary to hint */
+ /* TrueType glyphs with native TT hinting. */
+ /* */
+ /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */
+ /* defined. */
+ /* */
+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+
+ /*************************************************************************/
+ /* */
/* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */
/* of the TrueType bytecode interpreter is used that doesn't implement */
/* any of the patented opcodes and algorithms. The patents related to */
@@ -669,7 +705,7 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
- /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */
+ /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */
/* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */
/* required. */
/* */
@@ -716,6 +752,25 @@ FT_BEGIN_HEADER
/*************************************************************************/
/*************************************************************************/
/**** ****/
+ /**** C F F D R I V E R C O N F I G U R A T I O N ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */
+ /* engine gets compiled into FreeType. If defined, it is possible to */
+ /* switch between the two engines using the `hinting-engine' property of */
+ /* the cff driver module. */
+ /* */
+/* #define CFF_CONFIG_OPTION_OLD_ENGINE */
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
/**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/
/**** ****/
/*************************************************************************/
@@ -752,37 +807,10 @@ FT_BEGIN_HEADER
/*
- * Define this variable if you want to keep the layout of internal
- * structures that was used prior to FreeType 2.2. This also compiles in
- * a few obsolete functions to avoid linking problems on typical Unix
- * distributions.
- *
- * For embedded systems or building a new distribution from scratch, it
- * is recommended to disable the macro since it reduces the library's code
- * size and activates a few memory-saving optimizations as well.
+ * This macro is obsolete. Support has been removed in FreeType
+ * version 2.5.
*/
-#define FT_CONFIG_OPTION_OLD_INTERNALS
-
-
- /*
- * To detect legacy cache-lookup call from a rogue client (<= 2.1.7),
- * we restrict the number of charmaps in a font. The current API of
- * FTC_CMapCache_Lookup() takes cmap_index & charcode, but old API
- * takes charcode only. To determine the passed value is for cmap_index
- * or charcode, the possible cmap_index is restricted not to exceed
- * the minimum possible charcode by a rogue client. It is also very
- * unlikely that a rogue client is interested in Unicode values 0 to 15.
- *
- * NOTE: The original threshold was 4 deduced from popular number of
- * cmap subtables in UCS-4 TrueType fonts, but now it is not
- * irregular for OpenType fonts to have more than 4 subtables,
- * because variation selector subtables are available for Apple
- * and Microsoft platforms.
- */
-
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-#define FT_MAX_CHARMAP_CACHEABLE 15
-#endif
+/* #define FT_CONFIG_OPTION_OLD_INTERNALS */
/*
diff --git a/include/freetype/config/ftstdlib.h b/include/freetype/config/ftstdlib.h
index 11d5d0e..b940efc 100644
--- a/include/freetype/config/ftstdlib.h
+++ b/include/freetype/config/ftstdlib.h
@@ -5,7 +5,7 @@
/* ANSI-specific library and header configuration file (specification */
/* only). */
/* */
-/* Copyright 2002-2007, 2009, 2011 by */
+/* Copyright 2002-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, */
@@ -159,7 +159,7 @@
/* on certain platforms */
#define ft_longjmp longjmp
-#define ft_setjmp( b ) setjmp( *(jmp_buf*) &(b) ) /* same thing here */
+#define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) /* same thing here */
/* the following is only used for debugging purposes, i.e., if */
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 63c291a..0d5680b 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -4,7 +4,7 @@
/* */
/* FreeType high-level API and common types (specification only). */
/* */
-/* Copyright 1996-2012 by */
+/* Copyright 1996-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,6 +16,10 @@
/***************************************************************************/
+#ifndef __FREETYPE_H__
+#define __FREETYPE_H__
+
+
#ifndef FT_FREETYPE_H
#error "`ft2build.h' hasn't been included yet!"
#error "Please always use macros to include FreeType header files."
@@ -25,14 +29,10 @@
#endif
-#ifndef __FREETYPE_H__
-#define __FREETYPE_H__
-
-
#include <ft2build.h>
#include FT_CONFIG_CONFIG_H
-#include FT_ERRORS_H
#include FT_TYPES_H
+#include FT_ERRORS_H
FT_BEGIN_HEADER
@@ -237,6 +237,10 @@ FT_BEGIN_HEADER
/* If not disabled with @FT_LOAD_NO_HINTING, the values represent */
/* dimensions of the hinted glyph (in case hinting is applicable). */
/* */
+ /* Stroking a glyph with an outside border does not increase */
+ /* `horiAdvance' or `vertAdvance'; you have to manually adjust these */
+ /* values to account for the added width and height. */
+ /* */
typedef struct FT_Glyph_Metrics_
{
FT_Pos width;
@@ -844,8 +848,8 @@ FT_BEGIN_HEADER
/* expressed in font units (see */
/* `units_per_EM'). The box is large enough */
/* to contain any glyph from the font. Thus, */
- /* `bbox.yMax' can be seen as the `maximal */
- /* ascender', and `bbox.yMin' as the `minimal */
+ /* `bbox.yMax' can be seen as the `maximum */
+ /* ascender', and `bbox.yMin' as the `minimum */
/* descender'. Only relevant for scalable */
/* formats. */
/* */
@@ -871,19 +875,22 @@ FT_BEGIN_HEADER
/* usually negative. Only relevant for */
/* scalable formats. */
/* */
- /* height :: The height is the vertical distance */
+ /* height :: This value is the vertical distance */
/* between two consecutive baselines, */
/* expressed in font units. It is always */
/* positive. Only relevant for scalable */
/* formats. */
/* */
- /* max_advance_width :: The maximal advance width, in font units, */
+ /* If you want the global glyph height, use */
+ /* `ascender - descender'. */
+ /* */
+ /* max_advance_width :: The maximum advance width, in font units, */
/* for all glyphs in this face. This can be */
/* used to make word wrapping computations */
/* faster. Only relevant for scalable */
/* formats. */
/* */
- /* max_advance_height :: The maximal advance height, in font units, */
+ /* max_advance_height :: The maximum advance height, in font units, */
/* for all glyphs in this face. This is only */
/* relevant for vertical layouts, and is set */
/* to `height' for fonts that do not provide */
@@ -1105,8 +1112,8 @@ FT_BEGIN_HEADER
* FT_HAS_VERTICAL( face )
*
* @description:
- * A macro that returns true whenever a face object contains vertical
- * metrics.
+ * A macro that returns true whenever a face object contains real
+ * vertical metrics (and not only synthesized ones).
*
*/
#define FT_HAS_VERTICAL( face ) \
@@ -1338,7 +1345,7 @@ FT_BEGIN_HEADER
/* height :: The height in 26.6 fractional pixels. See */
/* @FT_FaceRec for the details. */
/* */
- /* max_advance :: The maximal advance width in 26.6 fractional */
+ /* max_advance :: The maximum advance width in 26.6 fractional */
/* pixels. See @FT_FaceRec for the details. */
/* */
/* <Note> */
@@ -2227,6 +2234,12 @@ FT_BEGIN_HEADER
/* particular bitmap strike. Use @FT_Select_Size instead in that */
/* case. */
/* */
+ /* The relation between the requested size and the resulting glyph */
+ /* size is dependent entirely on how the size is defined in the */
+ /* source face. The font designer chooses the final size of each */
+ /* glyph relative to this size. For more information refer to */
+ /* `http://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html' */
+ /* */
FT_EXPORT( FT_Error )
FT_Request_Size( FT_Face face,
FT_Size_Request req );
@@ -2296,6 +2309,11 @@ FT_BEGIN_HEADER
/* <Return> */
/* FreeType error code. 0~means success. */
/* */
+ /* <Note> */
+ /* You should not rely on the resulting glyphs matching, or being */
+ /* constrained, to this pixel size. Refer to @FT_Request_Size to */
+ /* understand how requested sizes relate to actual sizes. */
+ /* */
FT_EXPORT( FT_Error )
FT_Set_Pixel_Sizes( FT_Face face,
FT_UInt pixel_width,
@@ -2409,14 +2427,20 @@ FT_BEGIN_HEADER
* behaviour to more specific and useful cases.
*
* FT_LOAD_NO_SCALE ::
- * Don't scale the outline glyph loaded, but keep it in font units.
+ * Don't scale the loaded outline glyph but keep it in font units.
*
* This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and
* unsets @FT_LOAD_RENDER.
*
+ * If the font is `tricky' (see @FT_FACE_FLAG_TRICKY for more), using
+ * FT_LOAD_NO_SCALE usually yields meaningless outlines because the
+ * subglyphs must be scaled and positioned with hinting instructions.
+ * This can be solved by loading the font without FT_LOAD_NO_SCALE and
+ * setting the character size to `font->units_per_EM'.
+ *
* FT_LOAD_NO_HINTING ::
- * Disable hinting. This generally generates `blurrier' bitmap glyph
- * when the glyph is rendered in any of the anti-aliased modes. See
+ * Disable hinting. This generally generates `blurrier' bitmap glyphs
+ * when the glyph are rendered in any of the anti-aliased modes. See
* also the note below.
*
* This flag is implied by @FT_LOAD_NO_SCALE.
@@ -2435,8 +2459,14 @@ FT_BEGIN_HEADER
* @FT_LOAD_NO_SCALE always sets this flag.
*
* FT_LOAD_VERTICAL_LAYOUT ::
- * Load the glyph for vertical text layout. _Don't_ use it as it is
- * problematic currently.
+ * Load the glyph for vertical text layout. In particular, the
+ * `advance' value in the @FT_GlyphSlotRec structure is set to the
+ * `vertAdvance' value of the `metrics' field.
+ *
+ * In case @FT_HAS_VERTICAL doesn't return true, you shouldn't use
+ * this flag currently. Reason is that in this case vertical metrics
+ * get synthesized, and those values are not always consistent across
+ * various font formats.
*
* FT_LOAD_FORCE_AUTOHINT ::
* Indicates that the auto-hinter is preferred over the font's native
@@ -2493,6 +2523,14 @@ FT_BEGIN_HEADER
* FT_LOAD_NO_AUTOHINT ::
* Disable auto-hinter. See also the note below.
*
+ * FT_LOAD_COLOR ::
+ * This flag is used to request loading of color embedded-bitmap
+ * images. The resulting color bitmaps, if available, will have the
+ * @FT_PIXEL_MODE_BGRA format. When the flag is not used and color
+ * bitmaps are found, they will be converted to 256-level gray
+ * bitmaps transparently. Those bitmaps will be in the
+ * @FT_PIXEL_MODE_GRAY format.
+ *
* @note:
* By default, hinting is enabled and the font's native hinter (see
* @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can
@@ -2507,6 +2545,13 @@ FT_BEGIN_HEADER
* Besides deciding which hinter to use, you can also decide which
* hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details.
*
+ * Note that the auto-hinter needs a valid Unicode cmap (either a native
+ * one or synthesized by FreeType) for producing correct results. If a
+ * font provides an incorrect mapping (for example, assigning the
+ * character code U+005A, LATIN CAPITAL LETTER Z, to a glyph depicting a
+ * mathematical integral sign), the auto-hinter might produce useless
+ * results.
+ *
*/
#define FT_LOAD_DEFAULT 0x0
#define FT_LOAD_NO_SCALE ( 1L << 0 )
@@ -2523,6 +2568,8 @@ FT_BEGIN_HEADER
#define FT_LOAD_MONOCHROME ( 1L << 12 )
#define FT_LOAD_LINEAR_DESIGN ( 1L << 13 )
#define FT_LOAD_NO_AUTOHINT ( 1L << 15 )
+ /* Bits 16..19 are used by `FT_LOAD_TARGET_' */
+#define FT_LOAD_COLOR ( 1L << 20 )
/* */
@@ -2580,7 +2627,8 @@ FT_BEGIN_HEADER
*
* If @FT_LOAD_RENDER is also set, the glyph is rendered in the
* corresponding mode (i.e., the mode which matches the used algorithm
- * best) unless @FT_LOAD_MONOCHROME is set.
+ * best). An exeption is FT_LOAD_TARGET_MONO since it implies
+ * @FT_LOAD_MONOCHROME.
*
* You can use a hinting algorithm that doesn't correspond to the same
* rendering mode. As an example, it is possible to use the `light'
@@ -2922,7 +2970,7 @@ FT_BEGIN_HEADER
/* */
/* glyph_index :: The glyph index. */
/* */
- /* buffer_max :: The maximal number of bytes available in the */
+ /* buffer_max :: The maximum number of bytes available in the */
/* buffer. */
/* */
/* <Output> */
@@ -3081,9 +3129,15 @@ FT_BEGIN_HEADER
/* <Note> */
/* If you use FreeType to manipulate the contents of font files */
/* directly, be aware that the glyph index returned by this function */
- /* doesn't always correspond to the internal indices used within */
- /* the file. This is done to ensure that value~0 always corresponds */
- /* to the `missing glyph'. */
+ /* doesn't always correspond to the internal indices used within the */
+ /* file. This is done to ensure that value~0 always corresponds to */
+ /* the `missing glyph'. If the first glyph is not named `.notdef', */
+ /* then for Type~1 and Type~42 fonts, `.notdef' will be moved into */
+ /* the glyph ID~0 position, and whatever was there will be moved to */
+ /* the position `.notdef' had. For Type~1 fonts, if there is no */
+ /* `.notdef' glyph at all, then one will be created at index~0 and */
+ /* whatever was there will be moved to the last index -- Type~42 */
+ /* fonts are considered invalid under this condition. */
/* */
FT_EXPORT( FT_UInt )
FT_Get_Char_Index( FT_Face face,
@@ -3383,9 +3437,13 @@ FT_BEGIN_HEADER
/* code range for CJK characters. */
/* */
/* An IVS is registered and unique; for further details please refer */
- /* to Unicode Technical Report #37, the Ideographic Variation */
- /* Database. To date (October 2007), the character with the most */
- /* variants is U+908A, having 8~such IVS. */
+ /* to Unicode Technical Standard #37, the Ideographic Variation */
+ /* Database: */
+ /* */
+ /* http://www.unicode.org/reports/tr37/ */
+ /* */
+ /* To date (November 2012), the character with the most variants is */
+ /* U+9089, having 31 such IVS. */
/* */
/* Adobe and MS decided to support IVS with a new cmap subtable */
/* (format~14). It is an odd subtable because it is not a mapping of */
@@ -3614,7 +3672,7 @@ FT_BEGIN_HEADER
/* */
/* <Description> */
/* A very simple function used to perform the computation `(a*b)/c' */
- /* with maximal accuracy (it uses a 64-bit intermediate integer */
+ /* with maximum accuracy (it uses a 64-bit intermediate integer */
/* whenever necessary). */
/* */
/* This function isn't necessarily as fast as some processor specific */
@@ -3649,8 +3707,8 @@ FT_BEGIN_HEADER
/* */
/* <Description> */
/* A very simple function used to perform the computation */
- /* `(a*b)/0x10000' with maximal accuracy. Most of the time this is */
- /* used to multiply a given value by a 16.16 fixed float factor. */
+ /* `(a*b)/0x10000' with maximum accuracy. Most of the time this is */
+ /* used to multiply a given value by a 16.16 fixed-point factor. */
/* */
/* <Input> */
/* a :: The first multiplier. */
@@ -3694,8 +3752,8 @@ FT_BEGIN_HEADER
/* */
/* <Description> */
/* A very simple function used to perform the computation */
- /* `(a*0x10000)/b' with maximal accuracy. Most of the time, this is */
- /* used to divide a given value by a 16.16 fixed float factor. */
+ /* `(a*0x10000)/b' with maximum accuracy. Most of the time, this is */
+ /* used to divide a given value by a 16.16 fixed-point factor. */
/* */
/* <Input> */
/* a :: The first multiplier. */
@@ -3834,7 +3892,7 @@ FT_BEGIN_HEADER
*/
#define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 4
-#define FREETYPE_PATCH 9
+#define FREETYPE_PATCH 12
/*************************************************************************/
diff --git a/include/freetype/ftadvanc.h b/include/freetype/ftadvanc.h
index b2451be..012b74b 100644
--- a/include/freetype/ftadvanc.h
+++ b/include/freetype/ftadvanc.h
@@ -4,7 +4,7 @@
/* */
/* Quick computation of advance widths (specification only). */
/* */
-/* Copyright 2008 by */
+/* Copyright 2008, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -82,8 +82,7 @@ FT_BEGIN_HEADER
/* */
/* <Description> */
/* Retrieve the advance value of a given glyph outline in an */
- /* @FT_Face. By default, the unhinted advance is returned in font */
- /* units. */
+ /* @FT_Face. */
/* */
/* <Input> */
/* face :: The source @FT_Face handle. */
@@ -94,8 +93,9 @@ FT_BEGIN_HEADER
/* calling @FT_Load_Glyph, used to determine what kind */
/* of advances you need. */
/* <Output> */
- /* padvance :: The advance value, in either font units or 16.16 */
- /* format. */
+ /* padvance :: The advance value. If scaling is performed (based on */
+ /* the value of `load_flags'), the advance value is in */
+ /* 16.16 format. Otherwise, it is in font units. */
/* */
/* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the */
/* vertical advance corresponding to a vertical layout. */
@@ -127,8 +127,7 @@ FT_BEGIN_HEADER
/* */
/* <Description> */
/* Retrieve the advance values of several glyph outlines in an */
- /* @FT_Face. By default, the unhinted advances are returned in font */
- /* units. */
+ /* @FT_Face. */
/* */
/* <Input> */
/* face :: The source @FT_Face handle. */
@@ -141,8 +140,12 @@ FT_BEGIN_HEADER
/* calling @FT_Load_Glyph. */
/* */
/* <Output> */
- /* padvance :: The advances, in either font units or 16.16 format. */
- /* This array must contain at least `count' elements. */
+ /* padvance :: The advance values. This array, to be provided by the */
+ /* caller, must contain at least `count' elements. */
+ /* */
+ /* If scaling is performed (based on the value of */
+ /* `load_flags'), the advance values are in 16.16 format. */
+ /* Otherwise, they are in font units. */
/* */
/* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the */
/* vertical advances corresponding to a vertical layout. */
diff --git a/include/freetype/ftautoh.h b/include/freetype/ftautoh.h
new file mode 100644
index 0000000..62ce96d
--- /dev/null
+++ b/include/freetype/ftautoh.h
@@ -0,0 +1,349 @@
+/***************************************************************************/
+/* */
+/* ftautoh.h */
+/* */
+/* FreeType API for controlling the auto-hinter (specification only). */
+/* */
+/* Copyright 2012 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __FTAUTOH_H__
+#define __FTAUTOH_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#ifdef FREETYPE_H
+#error "freetype.h of FreeType 1 has been loaded!"
+#error "Please fix the directory search order for header files"
+#error "so that freetype.h of FreeType 2 is found first."
+#endif
+
+
+FT_BEGIN_HEADER
+
+
+ /**************************************************************************
+ *
+ * @section:
+ * auto_hinter
+ *
+ * @title:
+ * The auto-hinter
+ *
+ * @abstract:
+ * Controlling the auto-hinting module.
+ *
+ * @description:
+ * While FreeType's auto-hinter doesn't expose API functions by itself,
+ * it is possible to control its behaviour with @FT_Property_Set and
+ * @FT_Property_Get. The following lists the available properties
+ * together with the necessary macros and structures.
+ *
+ * Note that the auto-hinter's module name is `autofitter' for
+ * historical reasons.
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * @property:
+ * glyph-to-script-map
+ *
+ * @description:
+ * The auto-hinter provides various script modules to hint glyphs.
+ * Examples of supported scripts are Latin or CJK. Before a glyph is
+ * auto-hinted, the Unicode character map of the font gets examined, and
+ * the script is then determined based on Unicode character ranges, see
+ * below.
+ *
+ * OpenType fonts, however, often provide much more glyphs than
+ * character codes (small caps, superscripts, ligatures, swashes, etc.),
+ * to be controlled by so-called `features'. Handling OpenType features
+ * can be quite complicated and thus needs a separate library on top of
+ * FreeType.
+ *
+ * The mapping between glyph indices and scripts (in the auto-hinter
+ * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an
+ * array with `num_glyphs' elements, as found in the font's @FT_Face
+ * structure. The `glyph-to-script-map' property returns a pointer to
+ * this array which can be modified as needed. Note that the
+ * modification should happen before the first glyph gets processed by
+ * the auto-hinter so that the global analysis of the font shapes
+ * actually uses the modified mapping.
+ *
+ * The following example code demonstrates how to access it (omitting
+ * the error handling).
+ *
+ * {
+ * FT_Library library;
+ * FT_Face face;
+ * FT_Prop_GlyphToScriptMap prop;
+ *
+ *
+ * FT_Init_FreeType( &library );
+ * FT_New_Face( library, "foo.ttf", 0, &face );
+ *
+ * prop.face = face;
+ *
+ * FT_Property_Get( library, "autofitter",
+ * "glyph-to-script-map", &prop );
+ *
+ * // adjust `prop.map' as needed right here
+ *
+ * FT_Load_Glyph( face, ..., FT_LOAD_FORCE_AUTOHINT );
+ * }
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * @enum:
+ * FT_AUTOHINTER_SCRIPT_XXX
+ *
+ * @description:
+ * A list of constants used for the @glyph-to-script-map property to
+ * specify the script submodule the auto-hinter should use for hinting a
+ * particular glyph.
+ *
+ * @values:
+ * FT_AUTOHINTER_SCRIPT_NONE ::
+ * Don't auto-hint this glyph.
+ *
+ * FT_AUTOHINTER_SCRIPT_LATIN ::
+ * Apply the latin auto-hinter. For the auto-hinter, `latin' is a
+ * very broad term, including Cyrillic and Greek also since characters
+ * from those scripts share the same design constraints.
+ *
+ * By default, characters from the following Unicode ranges are
+ * assigned to this submodule.
+ *
+ * {
+ * U+0020 - U+007F // Basic Latin (no control characters)
+ * U+00A0 - U+00FF // Latin-1 Supplement (no control characters)
+ * U+0100 - U+017F // Latin Extended-A
+ * U+0180 - U+024F // Latin Extended-B
+ * U+0250 - U+02AF // IPA Extensions
+ * U+02B0 - U+02FF // Spacing Modifier Letters
+ * U+0300 - U+036F // Combining Diacritical Marks
+ * U+0370 - U+03FF // Greek and Coptic
+ * U+0400 - U+04FF // Cyrillic
+ * U+0500 - U+052F // Cyrillic Supplement
+ * U+1D00 - U+1D7F // Phonetic Extensions
+ * U+1D80 - U+1DBF // Phonetic Extensions Supplement
+ * U+1DC0 - U+1DFF // Combining Diacritical Marks Supplement
+ * U+1E00 - U+1EFF // Latin Extended Additional
+ * U+1F00 - U+1FFF // Greek Extended
+ * U+2000 - U+206F // General Punctuation
+ * U+2070 - U+209F // Superscripts and Subscripts
+ * U+20A0 - U+20CF // Currency Symbols
+ * U+2150 - U+218F // Number Forms
+ * U+2460 - U+24FF // Enclosed Alphanumerics
+ * U+2C60 - U+2C7F // Latin Extended-C
+ * U+2DE0 - U+2DFF // Cyrillic Extended-A
+ * U+2E00 - U+2E7F // Supplemental Punctuation
+ * U+A640 - U+A69F // Cyrillic Extended-B
+ * U+A720 - U+A7FF // Latin Extended-D
+ * U+FB00 - U+FB06 // Alphab. Present. Forms (Latin Ligatures)
+ * U+1D400 - U+1D7FF // Mathematical Alphanumeric Symbols
+ * U+1F100 - U+1F1FF // Enclosed Alphanumeric Supplement
+ * }
+ *
+ * FT_AUTOHINTER_SCRIPT_CJK ::
+ * Apply the CJK auto-hinter, covering Chinese, Japanese, Korean, old
+ * Vietnamese, and some other scripts.
+ *
+ * By default, characters from the following Unicode ranges are
+ * assigned to this submodule.
+ *
+ * {
+ * U+1100 - U+11FF // Hangul Jamo
+ * U+2E80 - U+2EFF // CJK Radicals Supplement
+ * U+2F00 - U+2FDF // Kangxi Radicals
+ * U+2FF0 - U+2FFF // Ideographic Description Characters
+ * U+3000 - U+303F // CJK Symbols and Punctuation
+ * U+3040 - U+309F // Hiragana
+ * U+30A0 - U+30FF // Katakana
+ * U+3100 - U+312F // Bopomofo
+ * U+3130 - U+318F // Hangul Compatibility Jamo
+ * U+3190 - U+319F // Kanbun
+ * U+31A0 - U+31BF // Bopomofo Extended
+ * U+31C0 - U+31EF // CJK Strokes
+ * U+31F0 - U+31FF // Katakana Phonetic Extensions
+ * U+3200 - U+32FF // Enclosed CJK Letters and Months
+ * U+3300 - U+33FF // CJK Compatibility
+ * U+3400 - U+4DBF // CJK Unified Ideographs Extension A
+ * U+4DC0 - U+4DFF // Yijing Hexagram Symbols
+ * U+4E00 - U+9FFF // CJK Unified Ideographs
+ * U+A960 - U+A97F // Hangul Jamo Extended-A
+ * U+AC00 - U+D7AF // Hangul Syllables
+ * U+D7B0 - U+D7FF // Hangul Jamo Extended-B
+ * U+F900 - U+FAFF // CJK Compatibility Ideographs
+ * U+FE10 - U+FE1F // Vertical forms
+ * U+FE30 - U+FE4F // CJK Compatibility Forms
+ * U+FF00 - U+FFEF // Halfwidth and Fullwidth Forms
+ * U+1B000 - U+1B0FF // Kana Supplement
+ * U+1D300 - U+1D35F // Tai Xuan Hing Symbols
+ * U+1F200 - U+1F2FF // Enclosed Ideographic Supplement
+ * U+20000 - U+2A6DF // CJK Unified Ideographs Extension B
+ * U+2A700 - U+2B73F // CJK Unified Ideographs Extension C
+ * U+2B740 - U+2B81F // CJK Unified Ideographs Extension D
+ * U+2F800 - U+2FA1F // CJK Compatibility Ideographs Supplement
+ * }
+ *
+ * FT_AUTOHINTER_SCRIPT_INDIC ::
+ * Apply the indic auto-hinter, covering all major scripts from the
+ * Indian sub-continent and some other related scripts like Thai, Lao,
+ * or Tibetan.
+ *
+ * By default, characters from the following Unicode ranges are
+ * assigned to this submodule.
+ *
+ * {
+ * U+0900 - U+0DFF // Indic Range
+ * U+0F00 - U+0FFF // Tibetan
+ * U+1900 - U+194F // Limbu
+ * U+1B80 - U+1BBF // Sundanese
+ * U+1C80 - U+1CDF // Meetei Mayak
+ * U+A800 - U+A82F // Syloti Nagri
+ * U+11800 - U+118DF // Sharada
+ * }
+ *
+ * Note that currently Indic support is rudimentary only, missing blue
+ * zone support.
+ *
+ */
+#define FT_AUTOHINTER_SCRIPT_NONE 0
+#define FT_AUTOHINTER_SCRIPT_LATIN 1
+#define FT_AUTOHINTER_SCRIPT_CJK 2
+#define FT_AUTOHINTER_SCRIPT_INDIC 3
+
+
+ /**************************************************************************
+ *
+ * @struct:
+ * FT_Prop_GlyphToScriptMap
+ *
+ * @description:
+ * The data exchange structure for the @glyph-to-script-map property.
+ *
+ */
+ typedef struct FT_Prop_GlyphToScriptMap_
+ {
+ FT_Face face;
+ FT_Byte* map;
+
+ } FT_Prop_GlyphToScriptMap;
+
+
+ /**************************************************************************
+ *
+ * @property:
+ * fallback-script
+ *
+ * @description:
+ * If no auto-hinter script module can be assigned to a glyph, a
+ * fallback script gets assigned to it (see also the
+ * @glyph-to-script-map property). By default, this is
+ * @FT_AUTOHINTER_SCRIPT_CJK. Using the `fallback-script' property,
+ * this fallback value can be changed.
+ *
+ * {
+ * FT_Library library;
+ * FT_UInt fallback_script = FT_AUTOHINTER_SCRIPT_NONE;
+ *
+ *
+ * FT_Init_FreeType( &library );
+ *
+ * FT_Property_Set( library, "autofitter",
+ * "fallback-script", &fallback_script );
+ * }
+ *
+ * @note:
+ * This property can be used with @FT_Property_Get also.
+ *
+ * It's important to use the right timing for changing this value: The
+ * creation of the glyph-to-script map which eventually uses the
+ * fallback script value gets triggered either by setting or reading a
+ * face-specific property like @glyph-to-script-map, or by auto-hinting
+ * any glyph from that face. In particular, if you have already created
+ * an @FT_Face structure but not loaded any glyph (using the
+ * auto-hinter), a change of the fallback glyph will affect this face.
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * @property:
+ * increase-x-height
+ *
+ * @description:
+ * For ppem values in the range 6~<= ppem <= `increase-x-height', round
+ * up the font's x~height much more often than normally. If the value
+ * is set to~0, which is the default, this feature is switched off. Use
+ * this property to improve the legibility of small font sizes if
+ * necessary.
+ *
+ * {
+ * FT_Library library;
+ * FT_Face face;
+ * FT_Prop_IncreaseXHeight prop;
+ *
+ *
+ * FT_Init_FreeType( &library );
+ * FT_New_Face( library, "foo.ttf", 0, &face );
+ * FT_Set_Char_Size( face, 10 * 64, 0, 72, 0 );
+ *
+ * prop.face = face;
+ * prop.limit = 14;
+ *
+ * FT_Property_Set( library, "autofitter",
+ * "increase-x-height", &prop );
+ * }
+ *
+ * @note:
+ * This property can be used with @FT_Property_Get also.
+ *
+ * Set this value right after calling @FT_Set_Char_Size, but before
+ * loading any glyph (using the auto-hinter).
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * @struct:
+ * FT_Prop_IncreaseXHeight
+ *
+ * @description:
+ * The data exchange structure for the @increase-x-height property.
+ *
+ */
+ typedef struct FT_Prop_IncreaseXHeight_
+ {
+ FT_Face face;
+ FT_UInt limit;
+
+ } FT_Prop_IncreaseXHeight;
+
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __FTAUTOH_H__ */
+
+
+/* END */
diff --git a/include/freetype/ftbitmap.h b/include/freetype/ftbitmap.h
index 9274236..7dbf5ba 100644
--- a/include/freetype/ftbitmap.h
+++ b/include/freetype/ftbitmap.h
@@ -4,7 +4,7 @@
/* */
/* FreeType utility functions for bitmaps (specification). */
/* */
-/* Copyright 2004, 2005, 2006, 2008 by */
+/* Copyright 2004-2006, 2008, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -135,9 +135,9 @@ FT_BEGIN_HEADER
/* FT_Bitmap_Convert */
/* */
/* <Description> */
- /* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, or 8bpp to a */
- /* bitmap object with depth 8bpp, making the number of used bytes per */
- /* line (a.k.a. the `pitch') a multiple of `alignment'. */
+ /* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp */
+ /* to a bitmap object with depth 8bpp, making the number of used */
+ /* bytes line (a.k.a. the `pitch') a multiple of `alignment'. */
/* */
/* <Input> */
/* library :: A handle to a library object. */
diff --git a/include/freetype/ftcache.h b/include/freetype/ftcache.h
index 6af5306..4ec9587 100644
--- a/include/freetype/ftcache.h
+++ b/include/freetype/ftcache.h
@@ -4,7 +4,7 @@
/* */
/* FreeType Cache subsystem (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */
+/* Copyright 1996-2008, 2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -214,17 +214,6 @@ FT_BEGIN_HEADER
/* */
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /* these macros are incompatible with LLP64, should not be used */
-
-#define FT_POINTER_TO_ULONG( p ) ( (FT_ULong)(FT_Pointer)(p) )
-
-#define FTC_FACE_ID_HASH( i ) \
- ((FT_UInt32)(( FT_POINTER_TO_ULONG( i ) >> 3 ) ^ \
- ( FT_POINTER_TO_ULONG( i ) << 7 ) ) )
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
/*************************************************************************/
/*************************************************************************/
@@ -381,7 +370,7 @@ FT_BEGIN_HEADER
/* should never try to discard it yourself. */
/* */
/* The @FT_Face object doesn't necessarily have a current size object */
- /* (i.e., face->size can be 0). If you need a specific `font size', */
+ /* (i.e., face->size can be~0). If you need a specific `font size', */
/* use @FTC_Manager_LookupSize instead. */
/* */
/* Never change the face's transformation matrix (i.e., never call */
@@ -705,17 +694,6 @@ FT_BEGIN_HEADER
(d1)->width == (d2)->width && \
(d1)->flags == (d2)->flags )
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /* this macro is incompatible with LLP64, should not be used */
-
-#define FTC_IMAGE_TYPE_HASH( d ) \
- (FT_UFast)( FTC_FACE_ID_HASH( (d)->face_id ) ^ \
- ( (d)->width << 8 ) ^ (d)->height ^ \
- ( (d)->flags << 4 ) )
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
/*************************************************************************/
/* */
@@ -723,7 +701,7 @@ FT_BEGIN_HEADER
/* FTC_ImageCache */
/* */
/* <Description> */
- /* A handle to an glyph image cache object. They are designed to */
+ /* A handle to a glyph image cache object. They are designed to */
/* hold many distinct glyph images while not exceeding a certain */
/* memory threshold. */
/* */
@@ -1071,67 +1049,6 @@ FT_BEGIN_HEADER
/* */
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /*@***********************************************************************/
- /* */
- /* <Struct> */
- /* FTC_FontRec */
- /* */
- /* <Description> */
- /* A simple structure used to describe a given `font' to the cache */
- /* manager. Note that a `font' is the combination of a given face */
- /* with a given character size. */
- /* */
- /* <Fields> */
- /* face_id :: The ID of the face to use. */
- /* */
- /* pix_width :: The character width in integer pixels. */
- /* */
- /* pix_height :: The character height in integer pixels. */
- /* */
- typedef struct FTC_FontRec_
- {
- FTC_FaceID face_id;
- FT_UShort pix_width;
- FT_UShort pix_height;
-
- } FTC_FontRec;
-
-
- /* */
-
-
-#define FTC_FONT_COMPARE( f1, f2 ) \
- ( (f1)->face_id == (f2)->face_id && \
- (f1)->pix_width == (f2)->pix_width && \
- (f1)->pix_height == (f2)->pix_height )
-
- /* this macro is incompatible with LLP64, should not be used */
-#define FTC_FONT_HASH( f ) \
- (FT_UInt32)( FTC_FACE_ID_HASH((f)->face_id) ^ \
- ((f)->pix_width << 8) ^ \
- ((f)->pix_height) )
-
- typedef FTC_FontRec* FTC_Font;
-
-
- FT_EXPORT( FT_Error )
- FTC_Manager_Lookup_Face( FTC_Manager manager,
- FTC_FaceID face_id,
- FT_Face *aface );
-
- FT_EXPORT( FT_Error )
- FTC_Manager_Lookup_Size( FTC_Manager manager,
- FTC_Font font,
- FT_Face *aface,
- FT_Size *asize );
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
- /* */
-
FT_END_HEADER
#endif /* __FTCACHE_H__ */
diff --git a/include/freetype/ftcffdrv.h b/include/freetype/ftcffdrv.h
new file mode 100644
index 0000000..ccbcbcc
--- /dev/null
+++ b/include/freetype/ftcffdrv.h
@@ -0,0 +1,151 @@
+/***************************************************************************/
+/* */
+/* ftcffdrv.h */
+/* */
+/* FreeType API for controlling the CFF driver (specification only). */
+/* */
+/* Copyright 2013 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __FTCFFDRV_H__
+#define __FTCFFDRV_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#ifdef FREETYPE_H
+#error "freetype.h of FreeType 1 has been loaded!"
+#error "Please fix the directory search order for header files"
+#error "so that freetype.h of FreeType 2 is found first."
+#endif
+
+
+FT_BEGIN_HEADER
+
+
+ /**************************************************************************
+ *
+ * @section:
+ * cff_driver
+ *
+ * @title:
+ * The CFF driver
+ *
+ * @abstract:
+ * Controlling the CFF driver module.
+ *
+ * @description:
+ * While FreeType's CFF driver doesn't expose API functions by itself,
+ * it is possible to control its behaviour with @FT_Property_Set and
+ * @FT_Property_Get. The following lists the available properties
+ * together with the necessary macros and structures.
+ *
+ * The CFF driver's module name is `cff'.
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * @property:
+ * hinting-engine
+ *
+ * @description:
+ * Thanks to Adobe, which contributed a new hinting (and parsing)
+ * engine, an application can select between `freetype' and `adobe' if
+ * compiled with CFF_CONFIG_OPTION_OLD_ENGINE. If this configuration
+ * macro isn't defined, `hinting-engine' does nothing.
+ *
+ * The default engine is `freetype' if CFF_CONFIG_OPTION_OLD_ENGINE is
+ * defined, and `adobe' otherwise.
+ *
+ * The following example code demonstrates how to select Adobe's hinting
+ * engine (omitting the error handling).
+ *
+ * {
+ * FT_Library library;
+ * FT_Face face;
+ * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE;
+ *
+ *
+ * FT_Init_FreeType( &library );
+ *
+ * FT_Property_Set( library, "cff",
+ * "hinting-engine", &hinting_engine );
+ * }
+ *
+ * @note:
+ * This property can be used with @FT_Property_Get also.
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * @enum:
+ * FT_CFF_HINTING_XXX
+ *
+ * @description:
+ * A list of constants used for the @hinting-engine property to select
+ * the hinting engine for CFF fonts.
+ *
+ * @values:
+ * FT_CFF_HINTING_FREETYPE ::
+ * Use the old FreeType hinting engine.
+ *
+ * FT_CFF_HINTING_ADOBE ::
+ * Use the hinting engine contributed by Adobe.
+ *
+ */
+#define FT_CFF_HINTING_FREETYPE 0
+#define FT_CFF_HINTING_ADOBE 1
+
+
+ /**************************************************************************
+ *
+ * @property:
+ * no-stem-darkening
+ *
+ * @description:
+ * By default, the Adobe CFF engine darkens stems at smaller sizes,
+ * regardless of hinting, to enhance contrast. Setting this property,
+ * stem darkening gets switched off.
+ *
+ * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set.
+ *
+ * {
+ * FT_Library library;
+ * FT_Face face;
+ * FT_Bool no_stem_darkening = TRUE;
+ *
+ *
+ * FT_Init_FreeType( &library );
+ *
+ * FT_Property_Set( library, "cff",
+ * "no-stem-darkening", &no_stem_darkening );
+ * }
+ *
+ * @note:
+ * This property can be used with @FT_Property_Get also.
+ *
+ */
+
+
+ /* */
+
+FT_END_HEADER
+
+
+#endif /* __FTCFFDRV_H__ */
+
+
+/* END */
diff --git a/include/freetype/ftchapters.h b/include/freetype/ftchapters.h
index 6cdf54e..c55670d 100644
--- a/include/freetype/ftchapters.h
+++ b/include/freetype/ftchapters.h
@@ -67,6 +67,22 @@
/***************************************************************************/
/* */
/* <Chapter> */
+/* module_specific */
+/* */
+/* <Title> */
+/* Controlling FreeType Modules */
+/* */
+/* <Sections> */
+/* auto_hinter */
+/* cff_driver */
+/* tt_driver */
+/* */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* */
+/* <Chapter> */
/* cache_subsystem */
/* */
/* <Title> */
diff --git a/include/freetype/fterrdef.h b/include/freetype/fterrdef.h
index fb4b53b..76c7b9e 100644
--- a/include/freetype/fterrdef.h
+++ b/include/freetype/fterrdef.h
@@ -4,7 +4,7 @@
/* */
/* FreeType error codes (specification). */
/* */
-/* Copyright 2002, 2004, 2006, 2007, 2010-2011 by */
+/* Copyright 2002, 2004, 2006, 2007, 2010-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -56,6 +56,8 @@
"array allocation size too large" )
FT_ERRORDEF_( Missing_Module, 0x0B, \
"missing module" )
+ FT_ERRORDEF_( Missing_Property, 0x0C, \
+ "missing property" )
/* glyph/character errors */
@@ -215,6 +217,8 @@
"ignore" )
FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, \
"no Unicode glyph name found" )
+ FT_ERRORDEF_( Glyph_Too_Big, 0xA4, \
+ "glyph to big for hinting" )
/* BDF errors */
diff --git a/include/freetype/fterrors.h b/include/freetype/fterrors.h
index a54699f..0fa3e4d 100644
--- a/include/freetype/fterrors.h
+++ b/include/freetype/fterrors.h
@@ -4,7 +4,7 @@
/* */
/* FreeType error code handling (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2004, 2007 by */
+/* Copyright 1996-2002, 2004, 2007, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -28,9 +28,8 @@
/* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */
/* defined in ftoption.h in order to make the higher byte indicate */
/* the module where the error has happened (this is not compatible */
- /* with standard builds of FreeType 2). You can then use the macro */
- /* FT_ERROR_BASE macro to extract the generic error code from an */
- /* FT_Error value. */
+ /* with standard builds of FreeType 2). See the file `ftmoderr.h' for */
+ /* more details. */
/* */
/* */
/* II - Error Message strings */
@@ -101,12 +100,6 @@
#undef FT_NEED_EXTERN_C
-#undef FT_ERR_XCAT
-#undef FT_ERR_CAT
-
-#define FT_ERR_XCAT( x, y ) x ## y
-#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
-
/* FT_ERR_PREFIX is used as a prefix for error identifiers. */
/* By default, we use `FT_Err_'. */
@@ -150,11 +143,11 @@
/* this macro is used to define an error */
-#define FT_ERRORDEF_( e, v, s ) \
+#define FT_ERRORDEF_( e, v, s ) \
FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s )
/* this is only used for <module>_Err_Ok, which must be 0! */
-#define FT_NOERRORDEF_( e, v, s ) \
+#define FT_NOERRORDEF_( e, v, s ) \
FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s )
@@ -194,11 +187,9 @@
#undef FT_NEED_EXTERN_C
#undef FT_ERR_BASE
- /* FT_KEEP_ERR_PREFIX is needed for ftvalid.h */
-#ifndef FT_KEEP_ERR_PREFIX
+ /* FT_ERR_PREFIX is needed internally */
+#ifndef FT2_BUILD_LIBRARY
#undef FT_ERR_PREFIX
-#else
-#undef FT_KEEP_ERR_PREFIX
#endif
#endif /* __FTERRORS_H__ */
diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h
index 3de69f7..31dc331 100644
--- a/include/freetype/ftglyph.h
+++ b/include/freetype/ftglyph.h
@@ -94,7 +94,7 @@ FT_BEGIN_HEADER
/* */
/* <Description> */
/* The root glyph structure contains a given glyph image plus its */
- /* advance width in 16.16 fixed float format. */
+ /* advance width in 16.16 fixed-point format. */
/* */
/* <Fields> */
/* library :: A handle to the FreeType library object. */
diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h
index 04b5e04..3b826b1 100644
--- a/include/freetype/ftimage.h
+++ b/include/freetype/ftimage.h
@@ -5,8 +5,7 @@
/* FreeType glyph image formats and default raster interface */
/* (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
-/* 2010 by */
+/* Copyright 1996-2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -54,7 +53,7 @@ FT_BEGIN_HEADER
/* <Description> */
/* The type FT_Pos is used to store vectorial coordinates. Depending */
/* on the context, these can represent distances in integer font */
- /* units, or 16.16, or 26.6 fixed float pixel coordinates. */
+ /* units, or 16.16, or 26.6 fixed-point pixel coordinates. */
/* */
typedef signed long FT_Pos;
@@ -169,6 +168,15 @@ FT_BEGIN_HEADER
/* times taller than the original glyph image. See also */
/* @FT_RENDER_MODE_LCD_V. */
/* */
+ /* FT_PIXEL_MODE_BGRA :: */
+ /* An image with four 8-bit channels per pixel, representing a */
+ /* color image (such as emoticons) with alpha channel. For each */
+ /* pixel, the format is BGRA, which means, the blue channel comes */
+ /* first in memory. The color channels are pre-multiplied and in */
+ /* the sRGB colorspace. For example, full red at half-translucent */
+ /* opacity will be represented as `00,00,80,80', not `00,00,FF,80'. */
+ /* See also @FT_LOAD_COLOR. */
+ /* */
typedef enum FT_Pixel_Mode_
{
FT_PIXEL_MODE_NONE = 0,
@@ -178,6 +186,7 @@ FT_BEGIN_HEADER
FT_PIXEL_MODE_GRAY4,
FT_PIXEL_MODE_LCD,
FT_PIXEL_MODE_LCD_V,
+ FT_PIXEL_MODE_BGRA,
FT_PIXEL_MODE_MAX /* do not remove */
diff --git a/include/freetype/ftlcdfil.h b/include/freetype/ftlcdfil.h
index 0b55ebe..8b253f1 100644
--- a/include/freetype/ftlcdfil.h
+++ b/include/freetype/ftlcdfil.h
@@ -53,6 +53,44 @@ FT_BEGIN_HEADER
* *not* implemented in default builds of the library. You need to
* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file
* in order to activate it.
+ *
+ * FreeType generates alpha coverage maps, which are linear by nature.
+ * For instance, the value 0x80 in bitmap representation means that
+ * (within numerical precision) 0x80/0xff fraction of that pixel is
+ * covered by the glyph's outline. The blending function for placing
+ * text over a background is
+ *
+ * {
+ * dst = alpha * src + (1 - alpha) * dst ,
+ * }
+ *
+ * which is known as OVER. However, when calculating the output of the
+ * OVER operator, the source colors should first be transformed to a
+ * linear color space, then alpha blended in that space, and transformed
+ * back to the output color space.
+ *
+ * When linear light blending is used, the default FIR5 filtering
+ * weights (as given by FT_LCD_FILTER_DEFAULT) are no longer optimal, as
+ * they have been designed for black on white rendering while lacking
+ * gamma correction. To preserve color neutrality, weights for a FIR5
+ * filter should be chosen according to two free parameters `a' and `c',
+ * and the FIR weights should be
+ *
+ * {
+ * [a - c, a + c, 2 * a, a + c, a - c] .
+ * }
+ *
+ * This formula generates equal weights for all the color primaries
+ * across the filter kernel, which makes it colorless. One suggested
+ * set of weights is
+ *
+ * {
+ * [0x10, 0x50, 0x60, 0x50, 0x10] ,
+ * }
+ *
+ * where `a' has value 0x30 and `b' value 0x20. The weights in filter
+ * may have a sum larger than 0x100, which increases coloration slightly
+ * but also improves contrast.
*/
diff --git a/include/freetype/ftmodapi.h b/include/freetype/ftmodapi.h
index 8f2e017..8abffb5 100644
--- a/include/freetype/ftmodapi.h
+++ b/include/freetype/ftmodapi.h
@@ -4,7 +4,7 @@
/* */
/* FreeType modules public interface (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009, 2010 by */
+/* Copyright 1996-2003, 2006, 2008-2010, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -42,11 +42,38 @@ FT_BEGIN_HEADER
/* Module Management */
/* */
/* <Abstract> */
- /* How to add, upgrade, and remove modules from FreeType. */
+ /* How to add, upgrade, remove, and control modules from FreeType. */
/* */
/* <Description> */
/* The definitions below are used to manage modules within FreeType. */
/* Modules can be added, upgraded, and removed at runtime. */
+ /* Additionally, some module properties can be controlled also. */
+ /* */
+ /* Here is a list of possible values of the `module_name' field in */
+ /* the @FT_Module_Class structure. */
+ /* */
+ /* { */
+ /* autofitter */
+ /* bdf */
+ /* cff */
+ /* gxvalid */
+ /* otvalid */
+ /* pcf */
+ /* pfr */
+ /* psaux */
+ /* pshinter */
+ /* psnames */
+ /* raster1, raster5 */
+ /* sfnt */
+ /* smooth, smooth-lcd, smooth-lcdv */
+ /* truetype */
+ /* type1 */
+ /* type42 */
+ /* t1cid */
+ /* winfonts */
+ /* } */
+ /* */
+ /* Note that the FreeType Cache sub-system is not a FreeType module. */
/* */
/*************************************************************************/
@@ -118,7 +145,7 @@ FT_BEGIN_HEADER
/* A function used to query a given module for a specific interface. */
/* */
/* <Input> */
- /* module :: The module to finalize. */
+ /* module :: The module to be searched. */
/* */
/* name :: The name of the interface in the module. */
/* */
@@ -249,6 +276,137 @@ FT_BEGIN_HEADER
FT_Module module );
+ /**********************************************************************
+ *
+ * @function:
+ * FT_Property_Set
+ *
+ * @description:
+ * Set a property for a given module.
+ *
+ * @input:
+ * library ::
+ * A handle to the library the module is part of.
+ *
+ * module_name ::
+ * The module name.
+ *
+ * property_name ::
+ * The property name. Properties are described in the `Synopsis'
+ * subsection of the module's documentation.
+ *
+ * Note that only a few modules have properties.
+ *
+ * value ::
+ * A generic pointer to a variable or structure which gives the new
+ * value of the property. The exact definition of `value' is
+ * dependent on the property; see the `Synopsis' subsection of the
+ * module's documentation.
+ *
+ * @return:
+ * FreeType error code. 0~means success.
+ *
+ * @note:
+ * If `module_name' isn't a valid module name, or `property_name'
+ * doesn't specify a valid property, or if `value' doesn't represent a
+ * valid value for the given property, an error is returned.
+ *
+ * The following example sets property `bar' (a simple integer) in
+ * module `foo' to value~1.
+ *
+ * {
+ * FT_UInt bar;
+ *
+ *
+ * bar = 1;
+ * FT_Property_Set( library, "foo", "bar", &bar );
+ * }
+ *
+ * Note that the FreeType Cache sub-system doesn't recognize module
+ * property changes. To avoid glyph lookup confusion within the cache
+ * you should call @FTC_Manager_Reset to completely flush the cache if
+ * a module property gets changed after @FTC_Manager_New has been
+ * called.
+ *
+ * It is not possible to set properties of the FreeType Cache
+ * sub-system itself with FT_Property_Set; use @FTC_Property_Set
+ * instead.
+ *
+ * @since:
+ * 2.4.11
+ *
+ */
+ FT_EXPORT( FT_Error )
+ FT_Property_Set( FT_Library library,
+ const FT_String* module_name,
+ const FT_String* property_name,
+ const void* value );
+
+
+ /**********************************************************************
+ *
+ * @function:
+ * FT_Property_Get
+ *
+ * @description:
+ * Get a module's property value.
+ *
+ * @input:
+ * library ::
+ * A handle to the library the module is part of.
+ *
+ * module_name ::
+ * The module name.
+ *
+ * property_name ::
+ * The property name. Properties are described in the `Synopsis'
+ * subsection of the module's documentation.
+ *
+ * @inout:
+ * value ::
+ * A generic pointer to a variable or structure which gives the
+ * value of the property. The exact definition of `value' is
+ * dependent on the property; see the `Synopsis' subsection of the
+ * module's documentation.
+ *
+ * @return:
+ * FreeType error code. 0~means success.
+ *
+ * @note:
+ * If `module_name' isn't a valid module name, or `property_name'
+ * doesn't specify a valid property, or if `value' doesn't represent a
+ * valid value for the given property, an error is returned.
+ *
+ * The following example gets property `baz' (a range) in module `foo'.
+ *
+ * {
+ * typedef range_
+ * {
+ * FT_Int32 min;
+ * FT_Int32 max;
+ *
+ * } range;
+ *
+ * range baz;
+ *
+ *
+ * FT_Property_Get( library, "foo", "baz", &baz );
+ * }
+ *
+ * It is not possible to retrieve properties of the FreeType Cache
+ * sub-system with FT_Property_Get; use @FTC_Property_Get instead.
+ *
+ * @since:
+ * 2.4.11
+ *
+ */
+ FT_EXPORT( FT_Error )
+ FT_Property_Get( FT_Library library,
+ const FT_String* module_name,
+ const FT_String* property_name,
+ void* value );
+
+
/*************************************************************************/
/* */
/* <Function> */
@@ -430,13 +588,13 @@ FT_BEGIN_HEADER
* scale glyph components with bytecode instructions. It produces
* bad output for most other fonts.
*
- * FT_TRUETYPE_ENGINE_TYPE_PATENTED ::
+ * FT_TRUETYPE_ENGINE_TYPE_PATENTED ::
* The library implements a bytecode interpreter that covers
* the full instruction set of the TrueType virtual machine (this
* was governed by patents until May 2010, hence the name).
*
* @since:
- * 2.2
+ * 2.2
*
*/
typedef enum FT_TrueTypeEngineType_
diff --git a/include/freetype/ftmoderr.h b/include/freetype/ftmoderr.h
index 1bf3b38..5a27db1 100644
--- a/include/freetype/ftmoderr.h
+++ b/include/freetype/ftmoderr.h
@@ -4,7 +4,7 @@
/* */
/* FreeType module error offsets (specification). */
/* */
-/* Copyright 2001, 2002, 2003, 2004, 2005, 2010 by */
+/* Copyright 2001-2005, 2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -18,17 +18,57 @@
/*************************************************************************/
/* */
- /* This file is used to define the FreeType module error offsets. */
+ /* This file is used to define the FreeType module error codes. */
/* */
- /* The lower byte gives the error code, the higher byte gives the */
- /* module. The base module has error offset 0. For example, the error */
- /* `FT_Err_Invalid_File_Format' has value 0x003, the error */
- /* `TT_Err_Invalid_File_Format' has value 0x1103, the error */
- /* `T1_Err_Invalid_File_Format' has value 0x1203, etc. */
+ /* If the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in `ftoption.h' is */
+ /* set, the lower byte of an error value identifies the error code as */
+ /* usual. In addition, the higher byte identifies the module. For */
+ /* example, the error `FT_Err_Invalid_File_Format' has value 0x0003, the */
+ /* error `TT_Err_Invalid_File_Format' has value 0x1303, the error */
+ /* `T1_Err_Invalid_File_Format' has value 0x1403, etc. */
+ /* */
+ /* Note that `FT_Err_Ok', `TT_Err_Ok', etc. are always equal to zero, */
+ /* including the high byte. */
+ /* */
+ /* If FT_CONFIG_OPTION_USE_MODULE_ERRORS isn't set, the higher byte of */
+ /* an error value is set to zero. */
+ /* */
+ /* To hide the various `XXX_Err_' prefixes in the source code, FreeType */
+ /* provides some macros in `fttypes.h'. */
+ /* */
+ /* FT_ERR( err ) */
+ /* Add current error module prefix (as defined with the */
+ /* `FT_ERR_PREFIX' macro) to `err'. For example, in the BDF module */
+ /* the line */
+ /* */
+ /* error = FT_ERR( Invalid_Outline ); */
+ /* */
+ /* expands to */
+ /* */
+ /* error = BDF_Err_Invalid_Outline; */
+ /* */
+ /* For simplicity, you can always use `FT_Err_Ok' directly instead */
+ /* of `FT_ERR( Ok )'. */
+ /* */
+ /* FT_ERR_EQ( errcode, err ) */
+ /* FT_ERR_NEQ( errcode, err ) */
+ /* Compare error code `errcode' with the error `err' for equality */
+ /* and inequality, respectively. Example: */
+ /* */
+ /* if ( FT_ERR_EQ( error, Invalid_Outline ) ) */
+ /* ... */
+ /* */
+ /* Using this macro you don't have to think about error prefixes. */
+ /* Of course, if module errors are not active, the above example is */
+ /* the same as */
+ /* */
+ /* if ( error == FT_Err_Invalid_Outline ) */
+ /* ... */
+ /* */
+ /* FT_ERROR_BASE( errcode ) */
+ /* FT_ERROR_MODULE( errcode ) */
+ /* Get base error and module error code, respectively. */
/* */
- /* Undefine the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in ftoption.h */
- /* to make the higher byte always zero (disabling the module error */
- /* mechanism). */
/* */
/* It can also be used to create a module error message table easily */
/* with something like */
@@ -48,9 +88,6 @@
/* #include FT_MODULE_ERRORS_H */
/* } */
/* */
- /* To use such a table, all errors must be ANDed with 0xFF00 to remove */
- /* the error code. */
- /* */
/*************************************************************************/
@@ -124,6 +161,7 @@
FT_MODERRDEF( Type1, 0x1300, "Type 1 module" )
FT_MODERRDEF( Type42, 0x1400, "Type 42 module" )
FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" )
+ FT_MODERRDEF( GXvalid, 0x1600, "GX validation module" )
#ifdef FT_MODERR_END_LIST
diff --git a/include/freetype/ftoutln.h b/include/freetype/ftoutln.h
index 1cf3c3f..fd69f28 100644
--- a/include/freetype/ftoutln.h
+++ b/include/freetype/ftoutln.h
@@ -5,7 +5,7 @@
/* Support for the FT_Outline type used to store glyph shapes of */
/* most scalable font formats (specification). */
/* */
-/* Copyright 1996-2003, 2005-2011 by */
+/* Copyright 1996-2003, 2005-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -59,6 +59,7 @@ FT_BEGIN_HEADER
/* FT_Outline_Translate */
/* FT_Outline_Transform */
/* FT_Outline_Embolden */
+ /* FT_Outline_EmboldenXY */
/* FT_Outline_Reverse */
/* FT_Outline_Check */
/* */
@@ -124,9 +125,11 @@ FT_BEGIN_HEADER
/* outline will *not* necessarily be *freed*, when */
/* destroying the library, by @FT_Done_FreeType. */
/* */
- /* numPoints :: The maximal number of points within the outline. */
+ /* numPoints :: The maximum number of points within the outline. */
+ /* Must be smaller than or equal to 0xFFFF (65535). */
/* */
- /* numContours :: The maximal number of contours within the outline. */
+ /* numContours :: The maximum number of contours within the outline. */
+ /* This value must be in the range 0 to `numPoints'. */
/* */
/* <Output> */
/* anoutline :: A handle to the new outline. */
@@ -353,6 +356,23 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Function> */
+ /* FT_Outline_EmboldenXY */
+ /* */
+ /* <Description> */
+ /* Embolden an outline. The new outline will be `xstrength' pixels */
+ /* wider and `ystrength' pixels higher. Otherwise, it is similar to */
+ /* @FT_Outline_Embolden, which uses the same strength in both */
+ /* directions. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FT_Outline_EmboldenXY( FT_Outline* outline,
+ FT_Pos xstrength,
+ FT_Pos ystrength );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
/* FT_Outline_Reverse */
/* */
/* <Description> */
diff --git a/include/freetype/ftstroke.h b/include/freetype/ftstroke.h
index 49ae2bc..a498e4a 100644
--- a/include/freetype/ftstroke.h
+++ b/include/freetype/ftstroke.h
@@ -4,7 +4,7 @@
/* */
/* FreeType path stroker (specification). */
/* */
-/* Copyright 2002-2006, 2008, 2009, 2011 by */
+/* Copyright 2002-2006, 2008, 2009, 2011-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -271,7 +271,7 @@ FT_BEGIN_HEADER
* miter_limit ::
* The miter limit for the FT_STROKER_LINEJOIN_MITER_FIXED and
* FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles,
- * expressed as 16.16 fixed point value.
+ * expressed as 16.16 fixed-point value.
*
* @note:
* The radius is expressed in the same units as the outline
@@ -682,6 +682,11 @@ FT_BEGIN_HEADER
*
* @note:
* The source glyph is untouched in case of error.
+ *
+ * Adding stroke may yield a significantly wider and taller glyph
+ * depending on how large of a radius was used to stroke the glyph. You
+ * may need to manually adjust horizontal and vertical advance amounts
+ * to account for this added size.
*/
FT_EXPORT( FT_Error )
FT_Glyph_Stroke( FT_Glyph *pglyph,
@@ -719,6 +724,11 @@ FT_BEGIN_HEADER
*
* @note:
* The source glyph is untouched in case of error.
+ *
+ * Adding stroke may yield a significantly wider and taller glyph
+ * depending on how large of a radius was used to stroke the glyph. You
+ * may need to manually adjust horizontal and vertical advance amounts
+ * to account for this added size.
*/
FT_EXPORT( FT_Error )
FT_Glyph_StrokeBorder( FT_Glyph *pglyph,
diff --git a/include/freetype/ftsynth.h b/include/freetype/ftsynth.h
index a068b79..2074503 100644
--- a/include/freetype/ftsynth.h
+++ b/include/freetype/ftsynth.h
@@ -5,7 +5,7 @@
/* FreeType synthesizing code for emboldening and slanting */
/* (specification). */
/* */
-/* Copyright 2000-2001, 2003, 2006, 2008 by */
+/* Copyright 2000-2001, 2003, 2006, 2008, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -61,8 +61,9 @@ FT_BEGIN_HEADER
/* taste). This function is actually a convenience function, providing */
/* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */
/* */
- /* For emboldened outlines the metrics are estimates only; if you need */
- /* precise values you should call @FT_Outline_Get_CBox. */
+ /* For emboldened outlines the height, width, and advance metrics are */
+ /* increased by the strength of the emboldening. You can also call */
+ /* @FT_Outline_Get_CBox to get precise values. */
FT_EXPORT( void )
FT_GlyphSlot_Embolden( FT_GlyphSlot slot );
diff --git a/include/freetype/fttrigon.h b/include/freetype/fttrigon.h
index 6b77d2e..65143cb 100644
--- a/include/freetype/fttrigon.h
+++ b/include/freetype/fttrigon.h
@@ -4,7 +4,7 @@
/* */
/* FreeType trigonometric functions (specification). */
/* */
-/* Copyright 2001, 2003, 2005, 2007 by */
+/* Copyright 2001, 2003, 2005, 2007, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -46,7 +46,7 @@ FT_BEGIN_HEADER
*
* @description:
* This type is used to model angle values in FreeType. Note that the
- * angle is a 16.16 fixed float value expressed in degrees.
+ * angle is a 16.16 fixed-point value expressed in degrees.
*
*/
typedef FT_Fixed FT_Angle;
@@ -106,7 +106,7 @@ FT_BEGIN_HEADER
* FT_Sin
*
* @description:
- * Return the sinus of a given angle in fixed point format.
+ * Return the sinus of a given angle in fixed-point format.
*
* @input:
* angle ::
@@ -130,7 +130,7 @@ FT_BEGIN_HEADER
* FT_Cos
*
* @description:
- * Return the cosinus of a given angle in fixed point format.
+ * Return the cosinus of a given angle in fixed-point format.
*
* @input:
* angle ::
@@ -154,7 +154,7 @@ FT_BEGIN_HEADER
* FT_Tan
*
* @description:
- * Return the tangent of a given angle in fixed point format.
+ * Return the tangent of a given angle in fixed-point format.
*
* @input:
* angle ::
diff --git a/include/freetype/ftttdrv.h b/include/freetype/ftttdrv.h
new file mode 100644
index 0000000..d5d3f1c
--- /dev/null
+++ b/include/freetype/ftttdrv.h
@@ -0,0 +1,150 @@
+/***************************************************************************/
+/* */
+/* ftttdrv.h */
+/* */
+/* FreeType API for controlling the TrueType driver */
+/* (specification only). */
+/* */
+/* Copyright 2013 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __FTTTDRV_H__
+#define __FTTTDRV_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#ifdef FREETYPE_H
+#error "freetype.h of FreeType 1 has been loaded!"
+#error "Please fix the directory search order for header files"
+#error "so that freetype.h of FreeType 2 is found first."
+#endif
+
+
+FT_BEGIN_HEADER
+
+
+ /**************************************************************************
+ *
+ * @section:
+ * tt_driver
+ *
+ * @title:
+ * The TrueType driver
+ *
+ * @abstract:
+ * Controlling the TrueType driver module.
+ *
+ * @description:
+ * While FreeType's TrueType driver doesn't expose API functions by
+ * itself, it is possible to control its behaviour with @FT_Property_Set
+ * and @FT_Property_Get. The following lists the available properties
+ * together with the necessary macros and structures.
+ *
+ * The TrueType driver's module name is `truetype'.
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * @property:
+ * interpreter-version
+ *
+ * @description:
+ * Currently, two versions are available which represent the bytecode
+ * interpreter with and without subpixel hinting support,
+ * respectively. The default is subpixel support if
+ * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel
+ * support otherwise (since it isn't available then).
+ *
+ * If subpixel hinting is on, many TrueType bytecode instructions
+ * behave differently compared to B/W or grayscale rendering. The
+ * main idea is to render at a much increased horizontal resolution,
+ * then sampling down the created output to subpixel precision.
+ * However, many older fonts are not suited to this and must be
+ * specially taken care of by applying (hardcoded) font-specific
+ * tweaks.
+ *
+ * Details on subpixel hinting and some of the necessary tweaks can be
+ * found in Greg Hitchcock's whitepaper at
+ * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'.
+ *
+ * The following example code demonstrates how to activate subpixel
+ * hinting (omitting the error handling).
+ *
+ * {
+ * FT_Library library;
+ * FT_Face face;
+ * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_38;
+ *
+ *
+ * FT_Init_FreeType( &library );
+ *
+ * FT_Property_Set( library, "truetype",
+ * "interpreter-version",
+ * &interpreter_version );
+ * }
+ *
+ * @note:
+ * This property can be used with @FT_Property_Get also.
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * @enum:
+ * TT_INTERPRETER_VERSION_XXX
+ *
+ * @description:
+ * A list of constants used for the @interpreter-version property to
+ * select the hinting engine for Truetype fonts.
+ *
+ * The numeric value in the constant names represents the version
+ * number as returned by the `GETINFO' bytecode instruction.
+ *
+ * @values:
+ * TT_INTERPRETER_VERSION_35 ::
+ * Version~35 corresponds to MS rasterizer v.1.7 as used e.g. in
+ * Windows~98; only grayscale and B/W rasterizing is supported.
+ *
+ * TT_INTERPRETER_VERSION_38 ::
+ * Version~38 corresponds to MS rasterizer v.1.9; it is roughly
+ * equivalent to the hinting provided by DirectWrite ClearType (as
+ * can be found, for example, in the Internet Explorer~9 running on
+ * Windows~7).
+ *
+ * @note:
+ * This property controls the behaviour of the bytecode interpreter
+ * and thus how outlines get hinted. It does *not* control how glyph
+ * get rasterized! In particular, it does not control subpixel color
+ * filtering.
+ *
+ * If FreeType has not been compiled with configuration option
+ * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 causes an
+ * `FT_Err_Unimplemented_Feature' error.
+ *
+ */
+#define TT_INTERPRETER_VERSION_35 35
+#define TT_INTERPRETER_VERSION_38 38
+
+
+ /* */
+
+FT_END_HEADER
+
+
+#endif /* __FTTTDRV_H__ */
+
+
+/* END */
diff --git a/include/freetype/fttypes.h b/include/freetype/fttypes.h
index 3255527..027e59c 100644
--- a/include/freetype/fttypes.h
+++ b/include/freetype/fttypes.h
@@ -4,7 +4,7 @@
/* */
/* FreeType simple types definitions (specification only). */
/* */
-/* Copyright 1996-2002, 2004, 2006-2009, 2012 by */
+/* Copyright 1996-2002, 2004, 2006-2009, 2012, 2013 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 @@ FT_BEGIN_HEADER
/* FT_F2Dot14 */
/* */
/* <Description> */
- /* A signed 2.14 fixed float type used for unit vectors. */
+ /* A signed 2.14 fixed-point type used for unit vectors. */
/* */
typedef signed short FT_F2Dot14;
@@ -266,7 +266,7 @@ FT_BEGIN_HEADER
/* FT_F26Dot6 */
/* */
/* <Description> */
- /* A signed 26.6 fixed float type used for vectorial pixel */
+ /* A signed 26.6 fixed-point type used for vectorial pixel */
/* coordinates. */
/* */
typedef signed long FT_F26Dot6;
@@ -278,7 +278,7 @@ FT_BEGIN_HEADER
/* FT_Fixed */
/* */
/* <Description> */
- /* This type is used to store 16.16 fixed float values, like scaling */
+ /* This type is used to store 16.16 fixed-point values, like scaling */
/* values or matrix coefficients. */
/* */
typedef signed long FT_Fixed;
@@ -362,7 +362,7 @@ FT_BEGIN_HEADER
/* */
/* <Description> */
/* A simple structure used to store a 2x2 matrix. Coefficients are */
- /* in 16.16 fixed float format. The computation performed is: */
+ /* in 16.16 fixed-point format. The computation performed is: */
/* */
/* { */
/* x' = x*xx + y*xy */
@@ -571,14 +571,24 @@ FT_BEGIN_HEADER
/* */
#define FT_IS_EMPTY( list ) ( (list).head == 0 )
+#define FT_BOOL( x ) ( (FT_Bool)( x ) )
- /* return base error code (without module-specific prefix) */
-#define FT_ERROR_BASE( x ) ( (x) & 0xFF )
+ /* concatenate C tokens */
+#define FT_ERR_XCAT( x, y ) x ## y
+#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
+
+ /* see `ftmoderr.h' for descriptions of the following macros */
+
+#define FT_ERR( e ) FT_ERR_CAT( FT_ERR_PREFIX, e )
- /* return module error code */
+#define FT_ERROR_BASE( x ) ( (x) & 0xFF )
#define FT_ERROR_MODULE( x ) ( (x) & 0xFF00U )
-#define FT_BOOL( x ) ( (FT_Bool)( x ) )
+#define FT_ERR_EQ( x, e ) \
+ ( FT_ERROR_BASE( x ) == FT_ERROR_BASE( FT_ERR( e ) ) )
+#define FT_ERR_NEQ( x, e ) \
+ ( FT_ERROR_BASE( x ) != FT_ERROR_BASE( FT_ERR( e ) ) )
+
FT_END_HEADER
diff --git a/include/freetype/internal/autohint.h b/include/freetype/internal/autohint.h
index 231bdd4..545de93 100644
--- a/include/freetype/internal/autohint.h
+++ b/include/freetype/internal/autohint.h
@@ -4,7 +4,7 @@
/* */
/* High-level `autohint' module-specific interface (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2007 by */
+/* Copyright 1996-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, */
@@ -86,20 +86,20 @@ FT_BEGIN_HEADER
/* FT_AutoHinter_GlobalGetFunc */
/* */
/* <Description> */
- /* Retrieves the global hints computed for a given face object the */
+ /* Retrieve the global hints computed for a given face object. The */
/* resulting data is dissociated from the face and will survive a */
/* call to FT_Done_Face(). It must be discarded through the API */
/* FT_AutoHinter_GlobalDoneFunc(). */
/* */
/* <Input> */
- /* hinter :: A handle to the source auto-hinter. */
+ /* hinter :: A handle to the source auto-hinter. */
/* */
- /* face :: A handle to the source face object. */
+ /* face :: A handle to the source face object. */
/* */
/* <Output> */
- /* global_hints :: A typeless pointer to the global hints. */
+ /* global_hints :: A typeless pointer to the global hints. */
/* */
- /* global_len :: The size in bytes of the global hints. */
+ /* global_len :: The size in bytes of the global hints. */
/* */
typedef void
(*FT_AutoHinter_GlobalGetFunc)( FT_AutoHinter hinter,
@@ -114,7 +114,7 @@ FT_BEGIN_HEADER
/* FT_AutoHinter_GlobalDoneFunc */
/* */
/* <Description> */
- /* Discards the global hints retrieved through */
+ /* Discard the global hints retrieved through */
/* FT_AutoHinter_GlobalGetFunc(). This is the only way these hints */
/* are freed from memory. */
/* */
@@ -168,8 +168,8 @@ FT_BEGIN_HEADER
/* This function is capable of loading composite glyphs by hinting */
/* each sub-glyph independently (which improves quality). */
/* */
- /* It will call the font driver with FT_Load_Glyph(), with */
- /* FT_LOAD_NO_SCALE set. */
+ /* It will call the font driver with @FT_Load_Glyph, with */
+ /* @FT_LOAD_NO_SCALE set. */
/* */
typedef FT_Error
(*FT_AutoHinter_GlyphLoadFunc)( FT_AutoHinter hinter,
@@ -182,43 +182,56 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Struct> */
- /* FT_AutoHinter_ServiceRec */
+ /* FT_AutoHinter_InterfaceRec */
/* */
/* <Description> */
/* The auto-hinter module's interface. */
/* */
- typedef struct FT_AutoHinter_ServiceRec_
+ typedef struct FT_AutoHinter_InterfaceRec_
{
FT_AutoHinter_GlobalResetFunc reset_face;
FT_AutoHinter_GlobalGetFunc get_global_hints;
FT_AutoHinter_GlobalDoneFunc done_global_hints;
FT_AutoHinter_GlyphLoadFunc load_glyph;
- } FT_AutoHinter_ServiceRec, *FT_AutoHinter_Service;
+ } FT_AutoHinter_InterfaceRec, *FT_AutoHinter_Interface;
+
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \
- done_global_hints_, load_glyph_) \
- FT_CALLBACK_TABLE_DEF \
- const FT_AutoHinter_ServiceRec class_ = \
- { \
- reset_face_, get_global_hints_, done_global_hints_, load_glyph_ \
+#define FT_DEFINE_AUTOHINTER_INTERFACE( \
+ class_, \
+ reset_face_, \
+ get_global_hints_, \
+ done_global_hints_, \
+ load_glyph_ ) \
+ FT_CALLBACK_TABLE_DEF \
+ const FT_AutoHinter_InterfaceRec class_ = \
+ { \
+ reset_face_, \
+ get_global_hints_, \
+ done_global_hints_, \
+ load_glyph_ \
};
#else /* FT_CONFIG_OPTION_PIC */
-#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \
- done_global_hints_, load_glyph_) \
- void \
- FT_Init_Class_##class_( FT_Library library, \
- FT_AutoHinter_ServiceRec* clazz) \
- { \
- FT_UNUSED(library); \
- clazz->reset_face = reset_face_; \
- clazz->get_global_hints = get_global_hints_; \
- clazz->done_global_hints = done_global_hints_; \
- clazz->load_glyph = load_glyph_; \
+#define FT_DEFINE_AUTOHINTER_INTERFACE( \
+ class_, \
+ reset_face_, \
+ get_global_hints_, \
+ done_global_hints_, \
+ load_glyph_ ) \
+ void \
+ FT_Init_Class_ ## class_( FT_Library library, \
+ FT_AutoHinter_InterfaceRec* clazz ) \
+ { \
+ FT_UNUSED( library ); \
+ \
+ clazz->reset_face = reset_face_; \
+ clazz->get_global_hints = get_global_hints_; \
+ clazz->done_global_hints = done_global_hints_; \
+ clazz->load_glyph = load_glyph_; \
}
#endif /* FT_CONFIG_OPTION_PIC */
diff --git a/include/freetype/internal/ftcalc.h b/include/freetype/internal/ftcalc.h
index f8b4324..faac3a3 100644
--- a/include/freetype/internal/ftcalc.h
+++ b/include/freetype/internal/ftcalc.h
@@ -4,7 +4,7 @@
/* */
/* Arithmetic computations (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */
+/* Copyright 1996-2006, 2008, 2009, 2012-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -33,7 +33,7 @@ FT_BEGIN_HEADER
/* FT_FixedSqrt */
/* */
/* <Description> */
- /* Computes the square root of a 16.16 fixed point value. */
+ /* Computes the square root of a 16.16 fixed-point value. */
/* */
/* <Input> */
/* x :: The value to compute the root for. */
@@ -48,29 +48,6 @@ FT_BEGIN_HEADER
FT_SqrtFixed( FT_Int32 x );
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* FT_Sqrt32 */
- /* */
- /* <Description> */
- /* Computes the square root of an Int32 integer (which will be */
- /* handled as an unsigned long value). */
- /* */
- /* <Input> */
- /* x :: The value to compute the root for. */
- /* */
- /* <Return> */
- /* The result of `sqrt(x)'. */
- /* */
- FT_EXPORT( FT_Int32 )
- FT_Sqrt32( FT_Int32 x );
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
/*************************************************************************/
/* */
/* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */
@@ -78,8 +55,6 @@ FT_BEGIN_HEADER
/*************************************************************************/
-#ifdef TT_USE_BYTECODE_INTERPRETER
-
/*************************************************************************/
/* */
/* <Function> */
@@ -87,7 +62,7 @@ FT_BEGIN_HEADER
/* */
/* <Description> */
/* A very simple function used to perform the computation `(a*b)/c' */
- /* (without rounding) with maximal accuracy (it uses a 64-bit */
+ /* (without rounding) with maximum accuracy (it uses a 64-bit */
/* intermediate integer whenever necessary). */
/* */
/* This function isn't necessarily as fast as some processor specific */
@@ -108,8 +83,6 @@ FT_BEGIN_HEADER
FT_Long b,
FT_Long c );
-#endif /* TT_USE_BYTECODE_INTERPRETER */
-
/*
* A variant of FT_Matrix_Multiply which scales its result afterwards.
@@ -129,7 +102,6 @@ FT_BEGIN_HEADER
* A variant of FT_Vector_Transform. See comments for
* FT_Matrix_Multiply_Scaled.
*/
-
FT_BASE( void )
FT_Vector_Transform_Scaled( FT_Vector* vector,
const FT_Matrix* matrix,
@@ -160,6 +132,22 @@ FT_BEGIN_HEADER
FT_Pos out_y );
+ /*
+ * Return the most significant bit index.
+ */
+ FT_BASE( FT_Int )
+ FT_MSB( FT_UInt32 z );
+
+
+ /*
+ * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses
+ * two fixed-point arguments instead.
+ */
+ FT_BASE( FT_Fixed )
+ FT_Hypot( FT_Fixed x,
+ FT_Fixed y );
+
+
#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 )
#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 )
#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 )
diff --git a/include/freetype/internal/ftdebug.h b/include/freetype/internal/ftdebug.h
index 7baae35..1ee120f 100644
--- a/include/freetype/internal/ftdebug.h
+++ b/include/freetype/internal/ftdebug.h
@@ -4,7 +4,7 @@
/* */
/* Debugging and logging component (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008, 2009 by */
+/* Copyright 1996-2002, 2004, 2006-2009, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -185,7 +185,8 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
- /* Define the FT_ASSERT macro. */
+ /* Define the FT_ASSERT and FT_THROW macros. The call to `FT_Throw' */
+ /* makes it possible to easily set a breakpoint at this function. */
/* */
/*************************************************************************/
@@ -199,10 +200,18 @@ FT_BEGIN_HEADER
__LINE__, __FILE__ ); \
} while ( 0 )
+#define FT_THROW( e ) \
+ ( FT_Throw( FT_ERR_CAT( FT_ERR_PREFIX, e ), \
+ __LINE__, \
+ __FILE__ ) | \
+ FT_ERR_CAT( FT_ERR_PREFIX, e ) )
+
#else /* !FT_DEBUG_LEVEL_ERROR */
#define FT_ASSERT( condition ) do { } while ( 0 )
+#define FT_THROW( e ) FT_ERR_CAT( FT_ERR_PREFIX, e )
+
#endif /* !FT_DEBUG_LEVEL_ERROR */
@@ -226,6 +235,12 @@ FT_BEGIN_HEADER
FT_Panic( const char* fmt,
... );
+ /* report file name and line number of an error */
+ FT_BASE( int )
+ FT_Throw( FT_Error error,
+ int line,
+ const char* file );
+
#endif /* FT_DEBUG_LEVEL_ERROR */
@@ -233,15 +248,6 @@ FT_BEGIN_HEADER
ft_debug_init( void );
-#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
-
- /* We disable the warning `conditional expression is constant' here */
- /* in order to compile cleanly with the maximum level of warnings. */
-#pragma warning( disable : 4127 )
-
-#endif /* _MSC_VER */
-
-
FT_END_HEADER
#endif /* __FTDEBUG_H__ */
diff --git a/include/freetype/internal/ftdriver.h b/include/freetype/internal/ftdriver.h
index 6f6b206..940218e 100644
--- a/include/freetype/internal/ftdriver.h
+++ b/include/freetype/internal/ftdriver.h
@@ -4,7 +4,7 @@
/* */
/* FreeType font driver interface (specification). */
/* */
-/* Copyright 1996-2003, 2006, 2008, 2011 by */
+/* Copyright 1996-2003, 2006, 2008, 2011-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -60,22 +60,6 @@ FT_BEGIN_HEADER
(*FT_Size_SelectFunc)( FT_Size size,
FT_ULong size_index );
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- typedef FT_Error
- (*FT_Size_ResetPointsFunc)( FT_Size size,
- FT_F26Dot6 char_width,
- FT_F26Dot6 char_height,
- FT_UInt horz_resolution,
- FT_UInt vert_resolution );
-
- typedef FT_Error
- (*FT_Size_ResetPixelsFunc)( FT_Size size,
- FT_UInt pixel_width,
- FT_UInt pixel_height );
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
typedef FT_Error
(*FT_Slot_LoadFunc)( FT_GlyphSlot slot,
FT_Size size,
@@ -181,72 +165,42 @@ FT_BEGIN_HEADER
/* */
typedef struct FT_Driver_ClassRec_
{
- FT_Module_Class root;
-
- FT_Long face_object_size;
- FT_Long size_object_size;
- FT_Long slot_object_size;
-
- FT_Face_InitFunc init_face;
- FT_Face_DoneFunc done_face;
+ FT_Module_Class root;
- FT_Size_InitFunc init_size;
- FT_Size_DoneFunc done_size;
+ FT_Long face_object_size;
+ FT_Long size_object_size;
+ FT_Long slot_object_size;
- FT_Slot_InitFunc init_slot;
- FT_Slot_DoneFunc done_slot;
+ FT_Face_InitFunc init_face;
+ FT_Face_DoneFunc done_face;
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
+ FT_Size_InitFunc init_size;
+ FT_Size_DoneFunc done_size;
- FT_Size_ResetPointsFunc set_char_sizes;
- FT_Size_ResetPixelsFunc set_pixel_sizes;
+ FT_Slot_InitFunc init_slot;
+ FT_Slot_DoneFunc done_slot;
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
+ FT_Slot_LoadFunc load_glyph;
- FT_Slot_LoadFunc load_glyph;
-
- FT_Face_GetKerningFunc get_kerning;
- FT_Face_AttachFunc attach_file;
- FT_Face_GetAdvancesFunc get_advances;
+ FT_Face_GetKerningFunc get_kerning;
+ FT_Face_AttachFunc attach_file;
+ FT_Face_GetAdvancesFunc get_advances;
/* since version 2.2 */
- FT_Size_RequestFunc request_size;
- FT_Size_SelectFunc select_size;
+ FT_Size_RequestFunc request_size;
+ FT_Size_SelectFunc select_size;
} FT_Driver_ClassRec, *FT_Driver_Class;
- /*
- * The following functions are used as stubs for `set_char_sizes' and
- * `set_pixel_sizes'; the code uses `request_size' and `select_size'
- * functions instead.
- *
- * Implementation is in `src/base/ftobjs.c'.
- */
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- FT_BASE( FT_Error )
- ft_stub_set_char_sizes( FT_Size size,
- FT_F26Dot6 width,
- FT_F26Dot6 height,
- FT_UInt horz_res,
- FT_UInt vert_res );
-
- FT_BASE( FT_Error )
- ft_stub_set_pixel_sizes( FT_Size size,
- FT_UInt width,
- FT_UInt height );
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
/*************************************************************************/
/* */
/* <Macro> */
/* FT_DECLARE_DRIVER */
/* */
/* <Description> */
- /* Used to create a forward declaration of a */
- /* FT_Driver_ClassRec stract instance. */
+ /* Used to create a forward declaration of an FT_Driver_ClassRec */
+ /* struct instance. */
/* */
/* <Macro> */
/* FT_DEFINE_DRIVER */
@@ -254,160 +208,194 @@ FT_BEGIN_HEADER
/* <Description> */
/* Used to initialize an instance of FT_Driver_ClassRec struct. */
/* */
- /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */
- /* to called with a pointer where the allocated stracture is returned.*/
- /* And when it is no longer needed a Destroy function needs */
- /* to be called to release that allocation. */
- /* fcinit.c (ft_create_default_module_classes) already contains */
- /* a mechanism to call these functions for the default modules */
- /* described in ftmodule.h */
+ /* When FT_CONFIG_OPTION_PIC is defined a `create' function has to be */
+ /* called with a pointer where the allocated structure is returned. */
+ /* And when it is no longer needed a `destroy' function needs to be */
+ /* called to release that allocation. */
+ /* */
+ /* `fcinit.c' (ft_create_default_module_classes) already contains a */
+ /* mechanism to call these functions for the default modules */
+ /* described in `ftmodule.h'. */
/* */
- /* Notice that the created Create and Destroy functions call */
- /* pic_init and pic_free function to allow you to manually allocate */
- /* and initialize any additional global data, like module specific */
+ /* Notice that the created `create' and `destroy' functions call */
+ /* `pic_init' and `pic_free' to allow you to manually allocate and */
+ /* initialize any additional global data, like a module specific */
/* interface, and put them in the global pic container defined in */
- /* ftpic.h. if you don't need them just implement the functions as */
- /* empty to resolve the link error. Also the pic_init and pic_free */
- /* functions should be declared in pic.h, to be referred by driver */
- /* definition calling FT_DEFINE_DRIVER() in following. */
+ /* `ftpic.h'. If you don't need them just implement the functions as */
+ /* empty to resolve the link error. Also the `pic_init' and */
+ /* `pic_free' functions should be declared in `pic.h', to be referred */
+ /* by driver definition calling `FT_DEFINE_DRIVER' in following. */
/* */
/* When FT_CONFIG_OPTION_PIC is not defined the struct will be */
- /* allocated in the global scope (or the scope where the macro */
- /* is used). */
+ /* allocated in the global scope (or the scope where the macro is */
+ /* used). */
/* */
#ifndef FT_CONFIG_OPTION_PIC
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \
- a_, b_,
-#else
- #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_)
-#endif
-
-#define FT_DECLARE_DRIVER(class_) \
+#define FT_DECLARE_DRIVER( class_ ) \
FT_CALLBACK_TABLE \
const FT_Driver_ClassRec class_;
-#define FT_DEFINE_DRIVER(class_, \
- flags_, size_, name_, version_, requires_, \
- interface_, init_, done_, get_interface_, \
- face_object_size_, size_object_size_, \
- slot_object_size_, init_face_, done_face_, \
- init_size_, done_size_, init_slot_, done_slot_, \
- old_set_char_sizes_, old_set_pixel_sizes_, \
- load_glyph_, get_kerning_, attach_file_, \
- get_advances_, request_size_, select_size_ ) \
- FT_CALLBACK_TABLE_DEF \
- const FT_Driver_ClassRec class_ = \
- { \
- FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_, \
- init_,done_,get_interface_) \
- \
- face_object_size_, \
- size_object_size_, \
- slot_object_size_, \
- \
- init_face_, \
- done_face_, \
- \
- init_size_, \
- done_size_, \
- \
- init_slot_, \
- done_slot_, \
- \
- FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \
- \
- load_glyph_, \
- \
- get_kerning_, \
- attach_file_, \
- get_advances_, \
- \
- request_size_, \
- select_size_ \
+#define FT_DEFINE_DRIVER( \
+ class_, \
+ flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_, \
+ face_object_size_, \
+ size_object_size_, \
+ slot_object_size_, \
+ init_face_, \
+ done_face_, \
+ init_size_, \
+ done_size_, \
+ init_slot_, \
+ done_slot_, \
+ load_glyph_, \
+ get_kerning_, \
+ attach_file_, \
+ get_advances_, \
+ request_size_, \
+ select_size_ ) \
+ FT_CALLBACK_TABLE_DEF \
+ const FT_Driver_ClassRec class_ = \
+ { \
+ FT_DEFINE_ROOT_MODULE( flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_ ) \
+ \
+ face_object_size_, \
+ size_object_size_, \
+ slot_object_size_, \
+ \
+ init_face_, \
+ done_face_, \
+ \
+ init_size_, \
+ done_size_, \
+ \
+ init_slot_, \
+ done_slot_, \
+ \
+ load_glyph_, \
+ \
+ get_kerning_, \
+ attach_file_, \
+ get_advances_, \
+ \
+ request_size_, \
+ select_size_ \
};
#else /* FT_CONFIG_OPTION_PIC */
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \
- clazz->set_char_sizes = a_; \
- clazz->set_pixel_sizes = b_;
-#else
- #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_)
-#endif
-
-#define FT_DECLARE_DRIVER(class_) FT_DECLARE_MODULE(class_)
-
-#define FT_DEFINE_DRIVER(class_, \
- flags_, size_, name_, version_, requires_, \
- interface_, init_, done_, get_interface_, \
- face_object_size_, size_object_size_, \
- slot_object_size_, init_face_, done_face_, \
- init_size_, done_size_, init_slot_, done_slot_, \
- old_set_char_sizes_, old_set_pixel_sizes_, \
- load_glyph_, get_kerning_, attach_file_, \
- get_advances_, request_size_, select_size_ ) \
- \
- void \
- FT_Destroy_Class_##class_( FT_Library library, \
- FT_Module_Class* clazz ) \
- { \
- FT_Memory memory = library->memory; \
- FT_Driver_Class dclazz = (FT_Driver_Class)clazz; \
- class_##_pic_free( library ); \
- if ( dclazz ) \
- FT_FREE( dclazz ); \
- } \
- \
- FT_Error \
- FT_Create_Class_##class_( FT_Library library, \
- FT_Module_Class** output_class ) \
- { \
- FT_Driver_Class clazz; \
- FT_Error error; \
- FT_Memory memory = library->memory; \
- \
- if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \
- return error; \
- \
- error = class_##_pic_init( library ); \
- if(error) \
- { \
- FT_FREE( clazz ); \
- return error; \
- } \
- \
- FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_, \
- init_,done_,get_interface_) \
- \
- clazz->face_object_size = face_object_size_; \
- clazz->size_object_size = size_object_size_; \
- clazz->slot_object_size = slot_object_size_; \
- \
- clazz->init_face = init_face_; \
- clazz->done_face = done_face_; \
- \
- clazz->init_size = init_size_; \
- clazz->done_size = done_size_; \
- \
- clazz->init_slot = init_slot_; \
- clazz->done_slot = done_slot_; \
- \
- FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \
- \
- clazz->load_glyph = load_glyph_; \
- \
- clazz->get_kerning = get_kerning_; \
- clazz->attach_file = attach_file_; \
- clazz->get_advances = get_advances_; \
- \
- clazz->request_size = request_size_; \
- clazz->select_size = select_size_; \
- \
- *output_class = (FT_Module_Class*)clazz; \
- return FT_Err_Ok; \
+#define FT_DECLARE_DRIVER( class_ ) FT_DECLARE_MODULE( class_ )
+
+#define FT_DEFINE_DRIVER( \
+ class_, \
+ flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_, \
+ face_object_size_, \
+ size_object_size_, \
+ slot_object_size_, \
+ init_face_, \
+ done_face_, \
+ init_size_, \
+ done_size_, \
+ init_slot_, \
+ done_slot_, \
+ load_glyph_, \
+ get_kerning_, \
+ attach_file_, \
+ get_advances_, \
+ request_size_, \
+ select_size_ ) \
+ void \
+ FT_Destroy_Class_ ## class_( FT_Library library, \
+ FT_Module_Class* clazz ) \
+ { \
+ FT_Memory memory = library->memory; \
+ FT_Driver_Class dclazz = (FT_Driver_Class)clazz; \
+ \
+ \
+ class_ ## _pic_free( library ); \
+ if ( dclazz ) \
+ FT_FREE( dclazz ); \
+ } \
+ \
+ \
+ FT_Error \
+ FT_Create_Class_ ## class_( FT_Library library, \
+ FT_Module_Class** output_class ) \
+ { \
+ FT_Driver_Class clazz = NULL; \
+ FT_Error error; \
+ FT_Memory memory = library->memory; \
+ \
+ \
+ if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \
+ return error; \
+ \
+ error = class_ ## _pic_init( library ); \
+ if ( error ) \
+ { \
+ FT_FREE( clazz ); \
+ return error; \
+ } \
+ \
+ FT_DEFINE_ROOT_MODULE( flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_ ) \
+ \
+ clazz->face_object_size = face_object_size_; \
+ clazz->size_object_size = size_object_size_; \
+ clazz->slot_object_size = slot_object_size_; \
+ \
+ clazz->init_face = init_face_; \
+ clazz->done_face = done_face_; \
+ \
+ clazz->init_size = init_size_; \
+ clazz->done_size = done_size_; \
+ \
+ clazz->init_slot = init_slot_; \
+ clazz->done_slot = done_slot_; \
+ \
+ clazz->load_glyph = load_glyph_; \
+ \
+ clazz->get_kerning = get_kerning_; \
+ clazz->attach_file = attach_file_; \
+ clazz->get_advances = get_advances_; \
+ \
+ clazz->request_size = request_size_; \
+ clazz->select_size = select_size_; \
+ \
+ *output_class = (FT_Module_Class*)clazz; \
+ \
+ return FT_Err_Ok; \
}
diff --git a/include/freetype/internal/ftmemory.h b/include/freetype/internal/ftmemory.h
index 026aa63..3d51aee 100644
--- a/include/freetype/internal/ftmemory.h
+++ b/include/freetype/internal/ftmemory.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType memory management macros (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2010 by */
+/* Copyright 1996-2002, 2004-2007, 2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -141,8 +141,10 @@ FT_BEGIN_HEADER
const void* P );
-#define FT_MEM_ALLOC( ptr, size ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, (size), &error ) )
+#define FT_MEM_ALLOC( ptr, size ) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, \
+ (FT_Long)(size), \
+ &error ) )
#define FT_MEM_FREE( ptr ) \
FT_BEGIN_STMNT \
@@ -154,45 +156,60 @@ FT_BEGIN_HEADER
FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) )
#define FT_MEM_REALLOC( ptr, cursz, newsz ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, 1, \
- (cursz), (newsz), \
- (ptr), &error ) )
-
-#define FT_MEM_QALLOC( ptr, size ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, (size), &error ) )
+ FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \
+ 1, \
+ (FT_Long)(cursz), \
+ (FT_Long)(newsz), \
+ (ptr), \
+ &error ) )
+
+#define FT_MEM_QALLOC( ptr, size ) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, \
+ (FT_Long)(size), \
+ &error ) )
#define FT_MEM_QNEW( ptr ) \
FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) )
-#define FT_MEM_QREALLOC( ptr, cursz, newsz ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, 1, \
- (cursz), (newsz), \
- (ptr), &error ) )
-
-#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \
- (cursz), (newsz), \
- (ptr), &error ) )
-
-#define FT_MEM_ALLOC_MULT( ptr, count, item_size ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (item_size), \
- 0, (count), \
- NULL, &error ) )
-
-#define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (itmsz), \
- (oldcnt), (newcnt), \
- (ptr), &error ) )
-
-#define FT_MEM_QALLOC_MULT( ptr, count, item_size ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (item_size), \
- 0, (count), \
- NULL, &error ) )
-
-#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \
- FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (itmsz), \
- (oldcnt), (newcnt), \
- (ptr), &error ) )
+#define FT_MEM_QREALLOC( ptr, cursz, newsz ) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \
+ 1, \
+ (FT_Long)(cursz), \
+ (FT_Long)(newsz), \
+ (ptr), \
+ &error ) )
+
+#define FT_MEM_ALLOC_MULT( ptr, count, item_size ) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \
+ (FT_Long)(item_size), \
+ 0, \
+ (FT_Long)(count), \
+ NULL, \
+ &error ) )
+
+#define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \
+ (FT_Long)(itmsz), \
+ (FT_Long)(oldcnt), \
+ (FT_Long)(newcnt), \
+ (ptr), \
+ &error ) )
+
+#define FT_MEM_QALLOC_MULT( ptr, count, item_size ) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \
+ (FT_Long)(item_size), \
+ 0, \
+ (FT_Long)(count), \
+ NULL, \
+ &error ) )
+
+#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \
+ (FT_Long)(itmsz), \
+ (FT_Long)(oldcnt), \
+ (FT_Long)(newcnt), \
+ (ptr), \
+ &error ) )
#define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 )
@@ -236,26 +253,37 @@ FT_BEGIN_HEADER
/* _typed_ in order to automatically compute array element sizes. */
/* */
-#define FT_MEM_NEW_ARRAY( ptr, count ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \
- 0, (count), \
- NULL, &error ) )
-
-#define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \
- (cursz), (newsz), \
- (ptr), &error ) )
-
-#define FT_MEM_QNEW_ARRAY( ptr, count ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \
- 0, (count), \
- NULL, &error ) )
-
-#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \
- FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \
- (cursz), (newsz), \
- (ptr), &error ) )
-
+#define FT_MEM_NEW_ARRAY( ptr, count ) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \
+ sizeof ( *(ptr) ), \
+ 0, \
+ (FT_Long)(count), \
+ NULL, \
+ &error ) )
+
+#define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz ) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \
+ sizeof ( *(ptr) ), \
+ (FT_Long)(cursz), \
+ (FT_Long)(newsz), \
+ (ptr), \
+ &error ) )
+
+#define FT_MEM_QNEW_ARRAY( ptr, count ) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \
+ sizeof ( *(ptr) ), \
+ 0, \
+ (FT_Long)(count), \
+ NULL, \
+ &error ) )
+
+#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \
+ sizeof ( *(ptr) ), \
+ (FT_Long)(cursz), \
+ (FT_Long)(newsz), \
+ (ptr), \
+ &error ) )
#define FT_ALLOC( ptr, size ) \
FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) )
@@ -303,37 +331,6 @@ FT_BEGIN_HEADER
FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) )
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- FT_BASE( FT_Error )
- FT_Alloc( FT_Memory memory,
- FT_Long size,
- void* *P );
-
- FT_BASE( FT_Error )
- FT_QAlloc( FT_Memory memory,
- FT_Long size,
- void* *p );
-
- FT_BASE( FT_Error )
- FT_Realloc( FT_Memory memory,
- FT_Long current,
- FT_Long size,
- void* *P );
-
- FT_BASE( FT_Error )
- FT_QRealloc( FT_Memory memory,
- FT_Long current,
- FT_Long size,
- void* *p );
-
- FT_BASE( void )
- FT_Free( FT_Memory memory,
- void* *P );
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
FT_BASE( FT_Pointer )
ft_mem_strdup( FT_Memory memory,
const char* str,
@@ -345,6 +342,7 @@ FT_BEGIN_HEADER
FT_ULong size,
FT_Error *p_error );
+
#define FT_MEM_STRDUP( dst, str ) \
(dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error )
diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
index fc18275..8a309b8 100644
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType private base classes (specification). */
/* */
-/* Copyright 1996-2006, 2008, 2010, 2012 by */
+/* Copyright 1996-2006, 2008, 2010, 2012-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -206,46 +206,79 @@ FT_BEGIN_HEADER
} FT_CMap_ClassRec;
+
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_DECLARE_CMAP_CLASS(class_) \
- FT_CALLBACK_TABLE const FT_CMap_ClassRec class_;
-
-#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_, \
- char_next_, char_var_index_, char_var_default_, variant_list_, \
- charvariant_list_, variantchar_list_) \
- FT_CALLBACK_TABLE_DEF \
- const FT_CMap_ClassRec class_ = \
- { \
- size_, init_, done_, char_index_, char_next_, char_var_index_, \
- char_var_default_, variant_list_, charvariant_list_, variantchar_list_ \
+#define FT_DECLARE_CMAP_CLASS( class_ ) \
+ FT_CALLBACK_TABLE const FT_CMap_ClassRec class_;
+
+#define FT_DEFINE_CMAP_CLASS( \
+ class_, \
+ size_, \
+ init_, \
+ done_, \
+ char_index_, \
+ char_next_, \
+ char_var_index_, \
+ char_var_default_, \
+ variant_list_, \
+ charvariant_list_, \
+ variantchar_list_ ) \
+ FT_CALLBACK_TABLE_DEF \
+ const FT_CMap_ClassRec class_ = \
+ { \
+ size_, \
+ init_, \
+ done_, \
+ char_index_, \
+ char_next_, \
+ char_var_index_, \
+ char_var_default_, \
+ variant_list_, \
+ charvariant_list_, \
+ variantchar_list_ \
};
+
#else /* FT_CONFIG_OPTION_PIC */
-#define FT_DECLARE_CMAP_CLASS(class_) \
- void FT_Init_Class_##class_( FT_Library library, FT_CMap_ClassRec* clazz);
-
-#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_, \
- char_next_, char_var_index_, char_var_default_, variant_list_, \
- charvariant_list_, variantchar_list_) \
- void \
- FT_Init_Class_##class_( FT_Library library, \
- FT_CMap_ClassRec* clazz) \
- { \
- FT_UNUSED(library); \
- clazz->size = size_; \
- clazz->init = init_; \
- clazz->done = done_; \
- clazz->char_index = char_index_; \
- clazz->char_next = char_next_; \
- clazz->char_var_index = char_var_index_; \
- clazz->char_var_default = char_var_default_; \
- clazz->variant_list = variant_list_; \
- clazz->charvariant_list = charvariant_list_; \
- clazz->variantchar_list = variantchar_list_; \
+#define FT_DECLARE_CMAP_CLASS( class_ ) \
+ void \
+ FT_Init_Class_ ## class_( FT_Library library, \
+ FT_CMap_ClassRec* clazz );
+
+#define FT_DEFINE_CMAP_CLASS( \
+ class_, \
+ size_, \
+ init_, \
+ done_, \
+ char_index_, \
+ char_next_, \
+ char_var_index_, \
+ char_var_default_, \
+ variant_list_, \
+ charvariant_list_, \
+ variantchar_list_ ) \
+ void \
+ FT_Init_Class_ ## class_( FT_Library library, \
+ FT_CMap_ClassRec* clazz ) \
+ { \
+ FT_UNUSED( library ); \
+ \
+ clazz->size = size_; \
+ clazz->init = init_; \
+ clazz->done = done_; \
+ clazz->char_index = char_index_; \
+ clazz->char_next = char_next_; \
+ clazz->char_var_index = char_var_index_; \
+ clazz->char_var_default = char_var_default_; \
+ clazz->variant_list = variant_list_; \
+ clazz->charvariant_list = charvariant_list_; \
+ clazz->variantchar_list = variantchar_list_; \
}
+
#endif /* FT_CONFIG_OPTION_PIC */
+
/* create a new charmap and add it to charmap->face */
FT_BASE( FT_Error )
FT_CMap_New( FT_CMap_Class clazz,
@@ -270,13 +303,13 @@ FT_BEGIN_HEADER
/* */
/* <Fields> */
/* max_points :: */
- /* The maximal number of points used to store the vectorial outline */
+ /* The maximum number of points used to store the vectorial outline */
/* of any glyph in this face. If this value cannot be known in */
/* advance, or if the face isn't scalable, this should be set to 0. */
/* Only relevant for scalable formats. */
/* */
/* max_contours :: */
- /* The maximal number of contours used to store the vectorial */
+ /* The maximum number of contours used to store the vectorial */
/* outline of any glyph in this face. If this value cannot be */
/* known in advance, or if the face isn't scalable, this should be */
/* set to 0. Only relevant for scalable formats. */
@@ -319,10 +352,6 @@ FT_BEGIN_HEADER
/* */
typedef struct FT_Face_InternalRec_
{
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- FT_UShort reserved1;
- FT_Short reserved2;
-#endif
FT_Matrix transform_matrix;
FT_Vector transform_delta;
FT_Int transform_flags;
@@ -411,6 +440,7 @@ FT_BEGIN_HEADER
/*************************************************************************/
/*************************************************************************/
+ /*************************************************************************/
/**** ****/
/**** ****/
/**** M O D U L E S ****/
@@ -503,7 +533,7 @@ FT_BEGIN_HEADER
ft_module_get_service( FT_Module module,
const char* service_id );
- /* */
+ /* */
/*************************************************************************/
@@ -511,7 +541,7 @@ FT_BEGIN_HEADER
/*************************************************************************/
/**** ****/
/**** ****/
- /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/
+ /**** F A C E, S I Z E & G L Y P H S L O T O B J E C T S ****/
/**** ****/
/**** ****/
/*************************************************************************/
@@ -926,12 +956,13 @@ FT_BEGIN_HEADER
FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster;
#endif
+
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** ****/
- /**** PIC-Support Macros for ftimage.h ****/
+ /**** P I C S U P P O R T ****/
/**** ****/
/**** ****/
/*************************************************************************/
@@ -939,6 +970,9 @@ FT_BEGIN_HEADER
/*************************************************************************/
+ /* PIC support macros for ftimage.h */
+
+
/*************************************************************************/
/* */
/* <Macro> */
@@ -947,38 +981,57 @@ FT_BEGIN_HEADER
/* <Description> */
/* Used to initialize an instance of FT_Outline_Funcs struct. */
/* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */
- /* called with a pre-allocated stracture to be filled. */
+ /* be called with a pre-allocated structure to be filled. */
/* When FT_CONFIG_OPTION_PIC is not defined the struct will be */
/* allocated in the global scope (or the scope where the macro */
/* is used). */
/* */
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_, \
- cubic_to_, shift_, delta_) \
- static const FT_Outline_Funcs class_ = \
- { \
- move_to_, line_to_, conic_to_, cubic_to_, shift_, delta_ \
+#define FT_DEFINE_OUTLINE_FUNCS( \
+ class_, \
+ move_to_, \
+ line_to_, \
+ conic_to_, \
+ cubic_to_, \
+ shift_, \
+ delta_ ) \
+ static const FT_Outline_Funcs class_ = \
+ { \
+ move_to_, \
+ line_to_, \
+ conic_to_, \
+ cubic_to_, \
+ shift_, \
+ delta_ \
};
#else /* FT_CONFIG_OPTION_PIC */
-#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_, \
- cubic_to_, shift_, delta_) \
- static FT_Error \
- Init_Class_##class_( FT_Outline_Funcs* clazz ) \
- { \
- clazz->move_to = move_to_; \
- clazz->line_to = line_to_; \
- clazz->conic_to = conic_to_; \
- clazz->cubic_to = cubic_to_; \
- clazz->shift = shift_; \
- clazz->delta = delta_; \
- return FT_Err_Ok; \
+#define FT_DEFINE_OUTLINE_FUNCS( \
+ class_, \
+ move_to_, \
+ line_to_, \
+ conic_to_, \
+ cubic_to_, \
+ shift_, \
+ delta_ ) \
+ static FT_Error \
+ Init_Class_ ## class_( FT_Outline_Funcs* clazz ) \
+ { \
+ clazz->move_to = move_to_; \
+ clazz->line_to = line_to_; \
+ clazz->conic_to = conic_to_; \
+ clazz->cubic_to = cubic_to_; \
+ clazz->shift = shift_; \
+ clazz->delta = delta_; \
+ \
+ return FT_Err_Ok; \
}
#endif /* FT_CONFIG_OPTION_PIC */
+
/*************************************************************************/
/* */
/* <Macro> */
@@ -987,51 +1040,56 @@ FT_BEGIN_HEADER
/* <Description> */
/* Used to initialize an instance of FT_Raster_Funcs struct. */
/* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */
- /* called with a pre-allocated stracture to be filled. */
+ /* be called with a pre-allocated structure to be filled. */
/* When FT_CONFIG_OPTION_PIC is not defined the struct will be */
/* allocated in the global scope (or the scope where the macro */
/* is used). */
/* */
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_, \
- raster_reset_, raster_set_mode_, \
- raster_render_, raster_done_) \
- const FT_Raster_Funcs class_ = \
- { \
- glyph_format_, raster_new_, raster_reset_, \
- raster_set_mode_, raster_render_, raster_done_ \
+#define FT_DEFINE_RASTER_FUNCS( \
+ class_, \
+ glyph_format_, \
+ raster_new_, \
+ raster_reset_, \
+ raster_set_mode_, \
+ raster_render_, \
+ raster_done_ ) \
+ const FT_Raster_Funcs class_ = \
+ { \
+ glyph_format_, \
+ raster_new_, \
+ raster_reset_, \
+ raster_set_mode_, \
+ raster_render_, \
+ raster_done_ \
};
#else /* FT_CONFIG_OPTION_PIC */
-#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_, \
- raster_reset_, raster_set_mode_, raster_render_, raster_done_) \
- void \
- FT_Init_Class_##class_( FT_Raster_Funcs* clazz ) \
- { \
- clazz->glyph_format = glyph_format_; \
- clazz->raster_new = raster_new_; \
- clazz->raster_reset = raster_reset_; \
- clazz->raster_set_mode = raster_set_mode_; \
- clazz->raster_render = raster_render_; \
- clazz->raster_done = raster_done_; \
+#define FT_DEFINE_RASTER_FUNCS( \
+ class_, \
+ glyph_format_, \
+ raster_new_, \
+ raster_reset_, \
+ raster_set_mode_, \
+ raster_render_, \
+ raster_done_ ) \
+ void \
+ FT_Init_Class_ ## class_( FT_Raster_Funcs* clazz ) \
+ { \
+ clazz->glyph_format = glyph_format_; \
+ clazz->raster_new = raster_new_; \
+ clazz->raster_reset = raster_reset_; \
+ clazz->raster_set_mode = raster_set_mode_; \
+ clazz->raster_render = raster_render_; \
+ clazz->raster_done = raster_done_; \
}
#endif /* FT_CONFIG_OPTION_PIC */
- /*************************************************************************/
- /*************************************************************************/
- /*************************************************************************/
- /**** ****/
- /**** ****/
- /**** PIC-Support Macros for ftrender.h ****/
- /**** ****/
- /**** ****/
- /*************************************************************************/
- /*************************************************************************/
- /*************************************************************************/
+ /* PIC support macros for ftrender.h */
/*************************************************************************/
@@ -1042,40 +1100,64 @@ FT_BEGIN_HEADER
/* <Description> */
/* Used to initialize an instance of FT_Glyph_Class struct. */
/* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */
- /* called with a pre-allocated stracture to be filled. */
+ /* be called with a pre-allocated stcture to be filled. */
/* When FT_CONFIG_OPTION_PIC is not defined the struct will be */
/* allocated in the global scope (or the scope where the macro */
/* is used). */
/* */
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_, \
- transform_, bbox_, prepare_) \
- FT_CALLBACK_TABLE_DEF \
- const FT_Glyph_Class class_ = \
- { \
- size_, format_, init_, done_, copy_, transform_, bbox_, prepare_ \
+#define FT_DEFINE_GLYPH( \
+ class_, \
+ size_, \
+ format_, \
+ init_, \
+ done_, \
+ copy_, \
+ transform_, \
+ bbox_, \
+ prepare_ ) \
+ FT_CALLBACK_TABLE_DEF \
+ const FT_Glyph_Class class_ = \
+ { \
+ size_, \
+ format_, \
+ init_, \
+ done_, \
+ copy_, \
+ transform_, \
+ bbox_, \
+ prepare_ \
};
#else /* FT_CONFIG_OPTION_PIC */
-#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_, \
- transform_, bbox_, prepare_) \
- void \
- FT_Init_Class_##class_( FT_Glyph_Class* clazz ) \
- { \
- clazz->glyph_size = size_; \
- clazz->glyph_format = format_; \
- clazz->glyph_init = init_; \
- clazz->glyph_done = done_; \
- clazz->glyph_copy = copy_; \
- clazz->glyph_transform = transform_; \
- clazz->glyph_bbox = bbox_; \
- clazz->glyph_prepare = prepare_; \
+#define FT_DEFINE_GLYPH( \
+ class_, \
+ size_, \
+ format_, \
+ init_, \
+ done_, \
+ copy_, \
+ transform_, \
+ bbox_, \
+ prepare_ ) \
+ void \
+ FT_Init_Class_ ## class_( FT_Glyph_Class* clazz ) \
+ { \
+ clazz->glyph_size = size_; \
+ clazz->glyph_format = format_; \
+ clazz->glyph_init = init_; \
+ clazz->glyph_done = done_; \
+ clazz->glyph_copy = copy_; \
+ clazz->glyph_transform = transform_; \
+ clazz->glyph_bbox = bbox_; \
+ clazz->glyph_prepare = prepare_; \
}
#endif /* FT_CONFIG_OPTION_PIC */
+
/*************************************************************************/
/* */
/* <Macro> */
@@ -1083,7 +1165,7 @@ FT_BEGIN_HEADER
/* */
/* <Description> */
/* Used to create a forward declaration of a */
- /* FT_Renderer_Class stract instance. */
+ /* FT_Renderer_Class struct instance. */
/* */
/* <Macro> */
/* FT_DEFINE_RENDERER */
@@ -1091,22 +1173,23 @@ FT_BEGIN_HEADER
/* <Description> */
/* Used to initialize an instance of FT_Renderer_Class struct. */
/* */
- /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */
- /* to called with a pointer where the allocated stracture is returned.*/
- /* And when it is no longer needed a Destroy function needs */
- /* to be called to release that allocation. */
- /* fcinit.c (ft_create_default_module_classes) already contains */
+ /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion will need */
+ /* to be called with a pointer where the allocated structure is */
+ /* returned. And when it is no longer needed a `destroy' function */
+ /* needs to be called to release that allocation. */
+ /* `fcinit.c' (ft_create_default_module_classes) already contains */
/* a mechanism to call these functions for the default modules */
- /* described in ftmodule.h */
+ /* described in `ftmodule.h'. */
/* */
- /* Notice that the created Create and Destroy functions call */
- /* pic_init and pic_free function to allow you to manually allocate */
- /* and initialize any additional global data, like module specific */
+ /* Notice that the created `create' and `destroy' functions call */
+ /* `pic_init' and `pic_free' to allow you to manually allocate and */
+ /* initialize any additional global data, like a module specific */
/* interface, and put them in the global pic container defined in */
- /* ftpic.h. if you don't need them just implement the functions as */
- /* empty to resolve the link error. Also the pic_init and pic_free */
- /* functions should be declared in pic.h, to be referred by renderer */
- /* definition calling FT_DEFINE_RENDERER() in following. */
+ /* `ftpic.h'. If you don't need them just implement the functions as */
+ /* empty to resolve the link error. Also the `pic_init' and */
+ /* `pic_free' functions should be declared in `pic.h', to be referred */
+ /* by the renderer definition calling `FT_DEFINE_RENDERER' in the */
+ /* following. */
/* */
/* When FT_CONFIG_OPTION_PIC is not defined the struct will be */
/* allocated in the global scope (or the scope where the macro */
@@ -1114,99 +1197,130 @@ FT_BEGIN_HEADER
/* */
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_DECLARE_RENDERER(class_) \
- FT_EXPORT_VAR( const FT_Renderer_Class ) class_;
-
-#define FT_DEFINE_RENDERER(class_, \
- flags_, size_, name_, version_, requires_, \
- interface_, init_, done_, get_interface_, \
- glyph_format_, render_glyph_, transform_glyph_, \
- get_glyph_cbox_, set_mode_, raster_class_ ) \
- FT_CALLBACK_TABLE_DEF \
- const FT_Renderer_Class class_ = \
- { \
- FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_, \
- interface_,init_,done_,get_interface_) \
- glyph_format_, \
- \
- render_glyph_, \
- transform_glyph_, \
- get_glyph_cbox_, \
- set_mode_, \
- \
- raster_class_ \
+#define FT_DECLARE_RENDERER( class_ ) \
+ FT_EXPORT_VAR( const FT_Renderer_Class ) class_;
+
+#define FT_DEFINE_RENDERER( \
+ class_, \
+ flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_, \
+ glyph_format_, \
+ render_glyph_, \
+ transform_glyph_, \
+ get_glyph_cbox_, \
+ set_mode_, \
+ raster_class_ ) \
+ FT_CALLBACK_TABLE_DEF \
+ const FT_Renderer_Class class_ = \
+ { \
+ FT_DEFINE_ROOT_MODULE( flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_ ) \
+ glyph_format_, \
+ \
+ render_glyph_, \
+ transform_glyph_, \
+ get_glyph_cbox_, \
+ set_mode_, \
+ \
+ raster_class_ \
};
#else /* FT_CONFIG_OPTION_PIC */
-#define FT_DECLARE_RENDERER(class_) FT_DECLARE_MODULE(class_)
-
-#define FT_DEFINE_RENDERER(class_, \
- flags_, size_, name_, version_, requires_, \
- interface_, init_, done_, get_interface_, \
- glyph_format_, render_glyph_, transform_glyph_, \
- get_glyph_cbox_, set_mode_, raster_class_ ) \
- \
- void \
- FT_Destroy_Class_##class_( FT_Library library, \
- FT_Module_Class* clazz ) \
- { \
- FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz; \
- FT_Memory memory = library->memory; \
- class_##_pic_free( library ); \
- if ( rclazz ) \
- FT_FREE( rclazz ); \
- } \
- \
- FT_Error \
- FT_Create_Class_##class_( FT_Library library, \
- FT_Module_Class** output_class ) \
- { \
- FT_Renderer_Class* clazz; \
- FT_Error error; \
- FT_Memory memory = library->memory; \
- \
- if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \
- return error; \
- \
- error = class_##_pic_init( library ); \
- if(error) \
- { \
- FT_FREE( clazz ); \
- return error; \
- } \
- \
- FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_, \
- interface_,init_,done_,get_interface_) \
- \
- clazz->glyph_format = glyph_format_; \
- \
- clazz->render_glyph = render_glyph_; \
- clazz->transform_glyph = transform_glyph_; \
- clazz->get_glyph_cbox = get_glyph_cbox_; \
- clazz->set_mode = set_mode_; \
- \
- clazz->raster_class = raster_class_; \
- \
- *output_class = (FT_Module_Class*)clazz; \
- return FT_Err_Ok; \
+#define FT_DECLARE_RENDERER( class_ ) FT_DECLARE_MODULE( class_ )
+
+#define FT_DEFINE_RENDERER( \
+ class_, \
+ flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_, \
+ glyph_format_, \
+ render_glyph_, \
+ transform_glyph_, \
+ get_glyph_cbox_, \
+ set_mode_, \
+ raster_class_ ) \
+ void \
+ FT_Destroy_Class_ ## class_( FT_Library library, \
+ FT_Module_Class* clazz ) \
+ { \
+ FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz; \
+ FT_Memory memory = library->memory; \
+ \
+ \
+ class_ ## _pic_free( library ); \
+ if ( rclazz ) \
+ FT_FREE( rclazz ); \
+ } \
+ \
+ \
+ FT_Error \
+ FT_Create_Class_ ## class_( FT_Library library, \
+ FT_Module_Class** output_class ) \
+ { \
+ FT_Renderer_Class* clazz = NULL; \
+ FT_Error error; \
+ FT_Memory memory = library->memory; \
+ \
+ \
+ if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \
+ return error; \
+ \
+ error = class_ ## _pic_init( library ); \
+ if ( error ) \
+ { \
+ FT_FREE( clazz ); \
+ return error; \
+ } \
+ \
+ FT_DEFINE_ROOT_MODULE( flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_ ) \
+ \
+ clazz->glyph_format = glyph_format_; \
+ \
+ clazz->render_glyph = render_glyph_; \
+ clazz->transform_glyph = transform_glyph_; \
+ clazz->get_glyph_cbox = get_glyph_cbox_; \
+ clazz->set_mode = set_mode_; \
+ \
+ clazz->raster_class = raster_class_; \
+ \
+ *output_class = (FT_Module_Class*)clazz; \
+ \
+ return FT_Err_Ok; \
}
-
-
#endif /* FT_CONFIG_OPTION_PIC */
- /*************************************************************************/
- /*************************************************************************/
- /*************************************************************************/
- /**** ****/
- /**** ****/
- /**** PIC-Support Macros for ftmodapi.h ****/
- /**** ****/
- /**** ****/
- /*************************************************************************/
- /*************************************************************************/
- /*************************************************************************/
+
+ /* PIC support macros for ftmodapi.h **/
#ifdef FT_CONFIG_OPTION_PIC
@@ -1247,6 +1361,7 @@ FT_BEGIN_HEADER
#endif
+
/*************************************************************************/
/* */
/* <Macro> */
@@ -1254,30 +1369,31 @@ FT_BEGIN_HEADER
/* */
/* <Description> */
/* Used to create a forward declaration of a */
- /* FT_Module_Class stract instance. */
+ /* FT_Module_Class struct instance. */
/* */
/* <Macro> */
/* FT_DEFINE_MODULE */
/* */
/* <Description> */
- /* Used to initialize an instance of FT_Module_Class struct. */
+ /* Used to initialize an instance of an FT_Module_Class struct. */
/* */
- /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */
- /* to called with a pointer where the allocated stracture is returned.*/
- /* And when it is no longer needed a Destroy function needs */
- /* to be called to release that allocation. */
- /* fcinit.c (ft_create_default_module_classes) already contains */
+ /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion needs to */
+ /* be called with a pointer where the allocated structure is */
+ /* returned. And when it is no longer needed a `destroy' function */
+ /* needs to be called to release that allocation. */
+ /* `fcinit.c' (ft_create_default_module_classes) already contains */
/* a mechanism to call these functions for the default modules */
- /* described in ftmodule.h */
+ /* described in `ftmodule.h'. */
/* */
- /* Notice that the created Create and Destroy functions call */
- /* pic_init and pic_free function to allow you to manually allocate */
- /* and initialize any additional global data, like module specific */
+ /* Notice that the created `create' and `destroy' functions call */
+ /* `pic_init' and `pic_free' to allow you to manually allocate and */
+ /* initialize any additional global data, like a module specific */
/* interface, and put them in the global pic container defined in */
- /* ftpic.h. if you don't need them just implement the functions as */
- /* empty to resolve the link error. Also the pic_init and pic_free */
- /* functions should be declared in pic.h, to be referred by module */
- /* definition calling FT_DEFINE_MODULE() in following. */
+ /* `ftpic.h'. If you don't need them just implement the functions as */
+ /* empty to resolve the link error. Also the `pic_init' and */
+ /* `pic_free' functions should be declared in `pic.h', to be referred */
+ /* by the module definition calling `FT_DEFINE_MODULE' in the */
+ /* following. */
/* */
/* When FT_CONFIG_OPTION_PIC is not defined the struct will be */
/* allocated in the global scope (or the scope where the macro */
@@ -1287,119 +1403,159 @@ FT_BEGIN_HEADER
/* FT_DEFINE_ROOT_MODULE */
/* */
/* <Description> */
- /* Used to initialize an instance of FT_Module_Class struct inside */
- /* another stract that contains it or in a function that initializes */
- /* that containing stract */
+ /* Used to initialize an instance of an FT_Module_Class struct inside */
+ /* another struct that contains it or in a function that initializes */
+ /* that containing struct. */
/* */
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_DECLARE_MODULE(class_) \
- FT_CALLBACK_TABLE \
- const FT_Module_Class class_; \
-
-#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_, \
- interface_, init_, done_, get_interface_) \
- { \
- flags_, \
- size_, \
- \
- name_, \
- version_, \
- requires_, \
- \
- interface_, \
- \
- init_, \
- done_, \
- get_interface_, \
+#define FT_DECLARE_MODULE( class_ ) \
+ FT_CALLBACK_TABLE \
+ const FT_Module_Class class_;
+
+#define FT_DEFINE_ROOT_MODULE( \
+ flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_ ) \
+ { \
+ flags_, \
+ size_, \
+ \
+ name_, \
+ version_, \
+ requires_, \
+ \
+ interface_, \
+ \
+ init_, \
+ done_, \
+ get_interface_, \
},
-#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_, \
- interface_, init_, done_, get_interface_) \
- FT_CALLBACK_TABLE_DEF \
- const FT_Module_Class class_ = \
- { \
- flags_, \
- size_, \
- \
- name_, \
- version_, \
- requires_, \
- \
- interface_, \
- \
- init_, \
- done_, \
- get_interface_, \
+#define FT_DEFINE_MODULE( \
+ class_, \
+ flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_ ) \
+ FT_CALLBACK_TABLE_DEF \
+ const FT_Module_Class class_ = \
+ { \
+ flags_, \
+ size_, \
+ \
+ name_, \
+ version_, \
+ requires_, \
+ \
+ interface_, \
+ \
+ init_, \
+ done_, \
+ get_interface_, \
};
#else /* FT_CONFIG_OPTION_PIC */
-#define FT_DECLARE_MODULE(class_) \
- FT_Error FT_Create_Class_##class_( FT_Library library, \
- FT_Module_Class** output_class ); \
- void FT_Destroy_Class_##class_( FT_Library library, \
- FT_Module_Class* clazz );
-
-#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_, \
- interface_, init_, done_, get_interface_) \
- clazz->root.module_flags = flags_; \
- clazz->root.module_size = size_; \
- clazz->root.module_name = name_; \
- clazz->root.module_version = version_; \
- clazz->root.module_requires = requires_; \
- \
- clazz->root.module_interface = interface_; \
- \
- clazz->root.module_init = init_; \
- clazz->root.module_done = done_; \
- clazz->root.get_interface = get_interface_;
-
-#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_, \
- interface_, init_, done_, get_interface_) \
- \
- void \
- FT_Destroy_Class_##class_( FT_Library library, \
- FT_Module_Class* clazz ) \
- { \
- FT_Memory memory = library->memory; \
- class_##_pic_free( library ); \
- if ( clazz ) \
- FT_FREE( clazz ); \
- } \
- \
- FT_Error \
- FT_Create_Class_##class_( FT_Library library, \
- FT_Module_Class** output_class ) \
- { \
- FT_Memory memory = library->memory; \
- FT_Module_Class* clazz; \
- FT_Error error; \
- \
- if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \
- return error; \
- error = class_##_pic_init( library ); \
- if(error) \
- { \
- FT_FREE( clazz ); \
- return error; \
- } \
- \
- clazz->module_flags = flags_; \
- clazz->module_size = size_; \
- clazz->module_name = name_; \
- clazz->module_version = version_; \
- clazz->module_requires = requires_; \
- \
- clazz->module_interface = interface_; \
- \
- clazz->module_init = init_; \
- clazz->module_done = done_; \
- clazz->get_interface = get_interface_; \
- \
- *output_class = clazz; \
- return FT_Err_Ok; \
+#define FT_DECLARE_MODULE( class_ ) \
+ FT_Error \
+ FT_Create_Class_ ## class_( FT_Library library, \
+ FT_Module_Class** output_class ); \
+ void \
+ FT_Destroy_Class_ ## class_( FT_Library library, \
+ FT_Module_Class* clazz );
+
+#define FT_DEFINE_ROOT_MODULE( \
+ flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_ ) \
+ clazz->root.module_flags = flags_; \
+ clazz->root.module_size = size_; \
+ clazz->root.module_name = name_; \
+ clazz->root.module_version = version_; \
+ clazz->root.module_requires = requires_; \
+ \
+ clazz->root.module_interface = interface_; \
+ \
+ clazz->root.module_init = init_; \
+ clazz->root.module_done = done_; \
+ clazz->root.get_interface = get_interface_;
+
+#define FT_DEFINE_MODULE( \
+ class_, \
+ flags_, \
+ size_, \
+ name_, \
+ version_, \
+ requires_, \
+ interface_, \
+ init_, \
+ done_, \
+ get_interface_ ) \
+ void \
+ FT_Destroy_Class_ ## class_( FT_Library library, \
+ FT_Module_Class* clazz ) \
+ { \
+ FT_Memory memory = library->memory; \
+ \
+ \
+ class_ ## _pic_free( library ); \
+ if ( clazz ) \
+ FT_FREE( clazz ); \
+ } \
+ \
+ \
+ FT_Error \
+ FT_Create_Class_ ## class_( FT_Library library, \
+ FT_Module_Class** output_class ) \
+ { \
+ FT_Memory memory = library->memory; \
+ FT_Module_Class* clazz = NULL; \
+ FT_Error error; \
+ \
+ \
+ if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \
+ return error; \
+ error = class_ ## _pic_init( library ); \
+ if ( error ) \
+ { \
+ FT_FREE( clazz ); \
+ return error; \
+ } \
+ \
+ clazz->module_flags = flags_; \
+ clazz->module_size = size_; \
+ clazz->module_name = name_; \
+ clazz->module_version = version_; \
+ clazz->module_requires = requires_; \
+ \
+ clazz->module_interface = interface_; \
+ \
+ clazz->module_init = init_; \
+ clazz->module_done = done_; \
+ clazz->get_interface = get_interface_; \
+ \
+ *output_class = clazz; \
+ \
+ return FT_Err_Ok; \
}
#endif /* FT_CONFIG_OPTION_PIC */
diff --git a/include/freetype/internal/ftpic.h b/include/freetype/internal/ftpic.h
index 5b674e6..485ce7a 100644
--- a/include/freetype/internal/ftpic.h
+++ b/include/freetype/internal/ftpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services (declaration). */
/* */
-/* 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, */
@@ -31,29 +31,33 @@ FT_BEGIN_HEADER
#ifdef FT_CONFIG_OPTION_PIC
- typedef struct FT_PIC_Container_
+ typedef struct FT_PIC_Container_
{
/* pic containers for base */
- void* base;
+ void* base;
+
/* pic containers for modules */
- void* autofit;
- void* cff;
- void* pshinter;
- void* psnames;
- void* raster;
- void* sfnt;
- void* smooth;
- void* truetype;
+ void* autofit;
+ void* cff;
+ void* pshinter;
+ void* psnames;
+ void* raster;
+ void* sfnt;
+ void* smooth;
+ void* truetype;
+
} FT_PIC_Container;
- /* Initialize the various function tables, structs, etc. stored in the container. */
+
+ /* Initialize the various function tables, structs, etc. */
+ /* stored in the container. */
FT_BASE( FT_Error )
- ft_pic_container_init( FT_Library library );
+ ft_pic_container_init( FT_Library library );
/* Destroy the contents of the container. */
FT_BASE( void )
- ft_pic_container_destroy( FT_Library library );
+ ft_pic_container_destroy( FT_Library library );
#endif /* FT_CONFIG_OPTION_PIC */
diff --git a/include/freetype/internal/ftrfork.h b/include/freetype/internal/ftrfork.h
index 77e1020..6307f2d 100644
--- a/include/freetype/internal/ftrfork.h
+++ b/include/freetype/internal/ftrfork.h
@@ -4,7 +4,7 @@
/* */
/* Embedded resource forks accessor (specification). */
/* */
-/* Copyright 2004, 2006, 2007 by */
+/* Copyright 2004, 2006, 2007, 2012 by */
/* Masatake YAMATO and Redhat K.K. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -80,26 +80,37 @@ FT_BEGIN_HEADER
} ft_raccess_guess_rec;
#ifndef FT_CONFIG_OPTION_PIC
+
/* this array is a storage in non-PIC mode, so ; is needed in END */
-#define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \
- const type name[] = {
-#define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \
- { raccess_guess_##func_suffix, FT_RFork_Rule_##type_suffix },
-#define CONST_FT_RFORK_RULE_ARRAY_END };
+#define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \
+ const type name[] = {
+#define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \
+ { raccess_guess_ ## func_suffix, \
+ FT_RFork_Rule_ ## type_suffix },
+#define CONST_FT_RFORK_RULE_ARRAY_END };
+
#else /* FT_CONFIG_OPTION_PIC */
+
/* this array is a function in PIC mode, so no ; is needed in END */
-#define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \
- void FT_Init_##name ( type* storage ) { \
- type *local = storage; \
- int i = 0;
-#define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \
- local[i].func = raccess_guess_##func_suffix; \
- local[i].type = FT_RFork_Rule_##type_suffix; \
- i++;
-#define CONST_FT_RFORK_RULE_ARRAY_END }
+#define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \
+ void \
+ FT_Init_ ## name( type* storage ) \
+ { \
+ type* local = storage; \
+ \
+ \
+ int i = 0;
+#define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \
+ local[i].func = raccess_guess_ ## func_suffix; \
+ local[i].type = FT_RFork_Rule_ ## type_suffix; \
+ i++;
+#define CONST_FT_RFORK_RULE_ARRAY_END }
+
#endif /* FT_CONFIG_OPTION_PIC */
+
#endif /* FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
+
/*************************************************************************/
/* */
/* <Function> */
diff --git a/include/freetype/internal/ftserv.h b/include/freetype/internal/ftserv.h
index 4f481db..4ac988b 100644
--- a/include/freetype/internal/ftserv.h
+++ b/include/freetype/internal/ftserv.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType services (specification only). */
/* */
-/* Copyright 2003-2007, 2009, 2012 by */
+/* Copyright 2003-2007, 2009, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -34,12 +34,12 @@
FT_BEGIN_HEADER
-#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
-
- /* we disable the warning `conditional expression is constant' here */
- /* in order to compile cleanly with the maximum level of warnings */
+#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
+ /* We disable the warning `conditional expression is */
+ /* constant' in order to compile cleanly with the maximum */
+ /* level of warnings. */
+#pragma warning( push )
#pragma warning( disable : 4127 )
-
#endif /* _MSC_VER */
/*
@@ -92,6 +92,7 @@ FT_BEGIN_HEADER
#endif /* !C++ */
+
/*
* @macro:
* FT_FACE_FIND_GLOBAL_SERVICE
@@ -167,7 +168,13 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Macro> */
- /* FT_DEFINE_SERVICEDESCREC1 .. FT_DEFINE_SERVICEDESCREC6 */
+ /* FT_DEFINE_SERVICEDESCREC1 */
+ /* FT_DEFINE_SERVICEDESCREC2 */
+ /* FT_DEFINE_SERVICEDESCREC3 */
+ /* FT_DEFINE_SERVICEDESCREC4 */
+ /* FT_DEFINE_SERVICEDESCREC5 */
+ /* FT_DEFINE_SERVICEDESCREC6 */
+ /* FT_DEFINE_SERVICEDESCREC7 */
/* */
/* <Description> */
/* Used to initialize an array of FT_ServiceDescRec structures. */
@@ -264,6 +271,26 @@ FT_BEGIN_HEADER
{ NULL, NULL } \
};
+#define FT_DEFINE_SERVICEDESCREC7( class_, \
+ serv_id_1, serv_data_1, \
+ serv_id_2, serv_data_2, \
+ serv_id_3, serv_data_3, \
+ serv_id_4, serv_data_4, \
+ serv_id_5, serv_data_5, \
+ serv_id_6, serv_data_6, \
+ serv_id_7, serv_data_7 ) \
+ static const FT_ServiceDescRec class_[] = \
+ { \
+ { serv_id_1, serv_data_1 }, \
+ { serv_id_2, serv_data_2 }, \
+ { serv_id_3, serv_data_3 }, \
+ { serv_id_4, serv_data_4 }, \
+ { serv_id_5, serv_data_5 }, \
+ { serv_id_6, serv_data_6 }, \
+ { serv_id_7, serv_data_7 }, \
+ { NULL, NULL } \
+ };
+
#else /* FT_CONFIG_OPTION_PIC */
#define FT_DEFINE_SERVICEDESCREC1( class_, \
@@ -283,7 +310,7 @@ FT_BEGIN_HEADER
FT_Create_Class_ ## class_( FT_Library library, \
FT_ServiceDescRec** output_class ) \
{ \
- FT_ServiceDescRec* clazz; \
+ FT_ServiceDescRec* clazz = NULL; \
FT_Error error; \
FT_Memory memory = library->memory; \
\
@@ -319,7 +346,7 @@ FT_BEGIN_HEADER
FT_Create_Class_ ## class_( FT_Library library, \
FT_ServiceDescRec** output_class ) \
{ \
- FT_ServiceDescRec* clazz; \
+ FT_ServiceDescRec* clazz = NULL; \
FT_Error error; \
FT_Memory memory = library->memory; \
\
@@ -358,7 +385,7 @@ FT_BEGIN_HEADER
FT_Create_Class_ ## class_( FT_Library library, \
FT_ServiceDescRec** output_class ) \
{ \
- FT_ServiceDescRec* clazz; \
+ FT_ServiceDescRec* clazz = NULL; \
FT_Error error; \
FT_Memory memory = library->memory; \
\
@@ -400,7 +427,7 @@ FT_BEGIN_HEADER
FT_Create_Class_ ## class_( FT_Library library, \
FT_ServiceDescRec** output_class ) \
{ \
- FT_ServiceDescRec* clazz; \
+ FT_ServiceDescRec* clazz = NULL; \
FT_Error error; \
FT_Memory memory = library->memory; \
\
@@ -445,7 +472,7 @@ FT_BEGIN_HEADER
FT_Create_Class_ ## class_( FT_Library library, \
FT_ServiceDescRec** output_class ) \
{ \
- FT_ServiceDescRec* clazz; \
+ FT_ServiceDescRec* clazz = NULL; \
FT_Error error; \
FT_Memory memory = library->memory; \
\
@@ -493,7 +520,7 @@ FT_BEGIN_HEADER
FT_Create_Class_ ## class_( FT_Library library, \
FT_ServiceDescRec** output_class) \
{ \
- FT_ServiceDescRec* clazz; \
+ FT_ServiceDescRec* clazz = NULL; \
FT_Error error; \
FT_Memory memory = library->memory; \
\
@@ -521,6 +548,59 @@ FT_BEGIN_HEADER
return FT_Err_Ok; \
}
+#define FT_DEFINE_SERVICEDESCREC7( class_, \
+ serv_id_1, serv_data_1, \
+ serv_id_2, serv_data_2, \
+ serv_id_3, serv_data_3, \
+ serv_id_4, serv_data_4, \
+ serv_id_5, serv_data_5, \
+ serv_id_6, serv_data_6, \
+ serv_id_7, serv_data_7 ) \
+ void \
+ FT_Destroy_Class_ ## class_( FT_Library library, \
+ FT_ServiceDescRec* clazz ) \
+ { \
+ FT_Memory memory = library->memory; \
+ \
+ \
+ if ( clazz ) \
+ FT_FREE( clazz ); \
+ } \
+ \
+ FT_Error \
+ FT_Create_Class_ ## class_( FT_Library library, \
+ FT_ServiceDescRec** output_class) \
+ { \
+ FT_ServiceDescRec* clazz = NULL; \
+ FT_Error error; \
+ FT_Memory memory = library->memory; \
+ \
+ \
+ if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 8 ) ) \
+ return error; \
+ \
+ clazz[0].serv_id = serv_id_1; \
+ clazz[0].serv_data = serv_data_1; \
+ clazz[1].serv_id = serv_id_2; \
+ clazz[1].serv_data = serv_data_2; \
+ clazz[2].serv_id = serv_id_3; \
+ clazz[2].serv_data = serv_data_3; \
+ clazz[3].serv_id = serv_id_4; \
+ clazz[3].serv_data = serv_data_4; \
+ clazz[4].serv_id = serv_id_5; \
+ clazz[4].serv_data = serv_data_5; \
+ clazz[5].serv_id = serv_id_6; \
+ clazz[5].serv_data = serv_data_6; \
+ clazz[6].serv_id = serv_id_7; \
+ clazz[6].serv_data = serv_data_7; \
+ clazz[7].serv_id = NULL; \
+ clazz[7].serv_data = NULL; \
+ \
+ *output_class = clazz; \
+ \
+ return FT_Err_Ok; \
+ }
+
#endif /* FT_CONFIG_OPTION_PIC */
@@ -573,7 +653,9 @@ FT_BEGIN_HEADER
/*
* A magic number used within the services cache.
*/
-#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)-2) /* magic number */
+
+ /* ensure that value `1' has the same width as a pointer */
+#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)~(FT_PtrDist)1)
/*
@@ -671,6 +753,7 @@ FT_BEGIN_HEADER
#define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h>
#define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h>
#define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h>
+#define FT_SERVICE_PROPERTIES_H <freetype/internal/services/svprop.h>
#define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h>
#define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h>
#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h>
@@ -680,6 +763,10 @@ FT_BEGIN_HEADER
/* */
+#if defined( _MSC_VER )
+#pragma warning( pop )
+#endif
+
FT_END_HEADER
#endif /* __FTSERV_H__ */
diff --git a/include/freetype/internal/ftstream.h b/include/freetype/internal/ftstream.h
index 8b18500..2661858 100644
--- a/include/freetype/internal/ftstream.h
+++ b/include/freetype/internal/ftstream.h
@@ -4,7 +4,7 @@
/* */
/* Stream handling (specification). */
/* */
-/* Copyright 1996-2002, 2004-2006, 2011 by */
+/* Copyright 1996-2002, 2004-2006, 2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -154,67 +154,60 @@ FT_BEGIN_HEADER
/* */
#define FT_BYTE_( p, i ) ( ((const FT_Byte*)(p))[(i)] )
-#define FT_INT8_( p, i ) ( ((const FT_Char*)(p))[(i)] )
#define FT_INT16( x ) ( (FT_Int16)(x) )
#define FT_UINT16( x ) ( (FT_UInt16)(x) )
#define FT_INT32( x ) ( (FT_Int32)(x) )
#define FT_UINT32( x ) ( (FT_UInt32)(x) )
-#define FT_BYTE_I16( p, i, s ) ( FT_INT16( FT_BYTE_( p, i ) ) << (s) )
+
#define FT_BYTE_U16( p, i, s ) ( FT_UINT16( FT_BYTE_( p, i ) ) << (s) )
-#define FT_BYTE_I32( p, i, s ) ( FT_INT32( FT_BYTE_( p, i ) ) << (s) )
#define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) )
-#define FT_INT8_I16( p, i, s ) ( FT_INT16( FT_INT8_( p, i ) ) << (s) )
-#define FT_INT8_U16( p, i, s ) ( FT_UINT16( FT_INT8_( p, i ) ) << (s) )
-#define FT_INT8_I32( p, i, s ) ( FT_INT32( FT_INT8_( p, i ) ) << (s) )
-#define FT_INT8_U32( p, i, s ) ( FT_UINT32( FT_INT8_( p, i ) ) << (s) )
-
-#define FT_PEEK_SHORT( p ) FT_INT16( FT_INT8_I16( p, 0, 8) | \
- FT_BYTE_I16( p, 1, 0) )
+#define FT_PEEK_SHORT( p ) FT_INT16( FT_BYTE_U16( p, 0, 8) | \
+ FT_BYTE_U16( p, 1, 0) )
#define FT_PEEK_USHORT( p ) FT_UINT16( FT_BYTE_U16( p, 0, 8 ) | \
FT_BYTE_U16( p, 1, 0 ) )
-#define FT_PEEK_LONG( p ) FT_INT32( FT_INT8_I32( p, 0, 24 ) | \
- FT_BYTE_I32( p, 1, 16 ) | \
- FT_BYTE_I32( p, 2, 8 ) | \
- FT_BYTE_I32( p, 3, 0 ) )
+#define FT_PEEK_LONG( p ) FT_INT32( FT_BYTE_U32( p, 0, 24 ) | \
+ FT_BYTE_U32( p, 1, 16 ) | \
+ FT_BYTE_U32( p, 2, 8 ) | \
+ FT_BYTE_U32( p, 3, 0 ) )
#define FT_PEEK_ULONG( p ) FT_UINT32( FT_BYTE_U32( p, 0, 24 ) | \
FT_BYTE_U32( p, 1, 16 ) | \
FT_BYTE_U32( p, 2, 8 ) | \
FT_BYTE_U32( p, 3, 0 ) )
-#define FT_PEEK_OFF3( p ) FT_INT32( FT_INT8_I32( p, 0, 16 ) | \
- FT_BYTE_I32( p, 1, 8 ) | \
- FT_BYTE_I32( p, 2, 0 ) )
+#define FT_PEEK_OFF3( p ) FT_INT32( FT_BYTE_U32( p, 0, 16 ) | \
+ FT_BYTE_U32( p, 1, 8 ) | \
+ FT_BYTE_U32( p, 2, 0 ) )
#define FT_PEEK_UOFF3( p ) FT_UINT32( FT_BYTE_U32( p, 0, 16 ) | \
FT_BYTE_U32( p, 1, 8 ) | \
FT_BYTE_U32( p, 2, 0 ) )
-#define FT_PEEK_SHORT_LE( p ) FT_INT16( FT_INT8_I16( p, 1, 8 ) | \
- FT_BYTE_I16( p, 0, 0 ) )
+#define FT_PEEK_SHORT_LE( p ) FT_INT16( FT_BYTE_U16( p, 1, 8 ) | \
+ FT_BYTE_U16( p, 0, 0 ) )
#define FT_PEEK_USHORT_LE( p ) FT_UINT16( FT_BYTE_U16( p, 1, 8 ) | \
FT_BYTE_U16( p, 0, 0 ) )
-#define FT_PEEK_LONG_LE( p ) FT_INT32( FT_INT8_I32( p, 3, 24 ) | \
- FT_BYTE_I32( p, 2, 16 ) | \
- FT_BYTE_I32( p, 1, 8 ) | \
- FT_BYTE_I32( p, 0, 0 ) )
+#define FT_PEEK_LONG_LE( p ) FT_INT32( FT_BYTE_U32( p, 3, 24 ) | \
+ FT_BYTE_U32( p, 2, 16 ) | \
+ FT_BYTE_U32( p, 1, 8 ) | \
+ FT_BYTE_U32( p, 0, 0 ) )
#define FT_PEEK_ULONG_LE( p ) FT_UINT32( FT_BYTE_U32( p, 3, 24 ) | \
FT_BYTE_U32( p, 2, 16 ) | \
FT_BYTE_U32( p, 1, 8 ) | \
FT_BYTE_U32( p, 0, 0 ) )
-#define FT_PEEK_OFF3_LE( p ) FT_INT32( FT_INT8_I32( p, 2, 16 ) | \
- FT_BYTE_I32( p, 1, 8 ) | \
- FT_BYTE_I32( p, 0, 0 ) )
+#define FT_PEEK_OFF3_LE( p ) FT_INT32( FT_BYTE_U32( p, 2, 16 ) | \
+ FT_BYTE_U32( p, 1, 8 ) | \
+ FT_BYTE_U32( p, 0, 0 ) )
#define FT_PEEK_UOFF3_LE( p ) FT_UINT32( FT_BYTE_U32( p, 2, 16 ) | \
FT_BYTE_U32( p, 1, 8 ) | \
@@ -493,37 +486,41 @@ FT_BEGIN_HEADER
#define FT_STREAM_POS() \
FT_Stream_Pos( stream )
-#define FT_STREAM_SEEK( position ) \
- FT_SET_ERROR( FT_Stream_Seek( stream, position ) )
+#define FT_STREAM_SEEK( position ) \
+ FT_SET_ERROR( FT_Stream_Seek( stream, \
+ (FT_ULong)(position) ) )
-#define FT_STREAM_SKIP( distance ) \
- FT_SET_ERROR( FT_Stream_Skip( stream, distance ) )
+#define FT_STREAM_SKIP( distance ) \
+ FT_SET_ERROR( FT_Stream_Skip( stream, \
+ (FT_Long)(distance) ) )
-#define FT_STREAM_READ( buffer, count ) \
- FT_SET_ERROR( FT_Stream_Read( stream, \
- (FT_Byte*)buffer, \
- count ) )
+#define FT_STREAM_READ( buffer, count ) \
+ FT_SET_ERROR( FT_Stream_Read( stream, \
+ (FT_Byte*)(buffer), \
+ (FT_ULong)(count) ) )
-#define FT_STREAM_READ_AT( position, buffer, count ) \
- FT_SET_ERROR( FT_Stream_ReadAt( stream, \
- position, \
- (FT_Byte*)buffer, \
- count ) )
+#define FT_STREAM_READ_AT( position, buffer, count ) \
+ FT_SET_ERROR( FT_Stream_ReadAt( stream, \
+ (FT_ULong)(position), \
+ (FT_Byte*)buffer, \
+ (FT_ULong)(count) ) )
#define FT_STREAM_READ_FIELDS( fields, object ) \
FT_SET_ERROR( FT_Stream_ReadFields( stream, fields, object ) )
-#define FT_FRAME_ENTER( size ) \
- FT_SET_ERROR( \
- FT_DEBUG_INNER( FT_Stream_EnterFrame( stream, size ) ) )
+#define FT_FRAME_ENTER( size ) \
+ FT_SET_ERROR( \
+ FT_DEBUG_INNER( FT_Stream_EnterFrame( stream, \
+ (FT_ULong)(size) ) ) )
-#define FT_FRAME_EXIT() \
+#define FT_FRAME_EXIT() \
FT_DEBUG_INNER( FT_Stream_ExitFrame( stream ) )
#define FT_FRAME_EXTRACT( size, bytes ) \
FT_SET_ERROR( \
- FT_DEBUG_INNER( FT_Stream_ExtractFrame( stream, size, \
+ FT_DEBUG_INNER( FT_Stream_ExtractFrame( stream, \
+ (FT_ULong)(size), \
(FT_Byte**)&(bytes) ) ) )
#define FT_FRAME_RELEASE( bytes ) \
diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h
index fbefdbd..a9d98b6 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -4,7 +4,7 @@
/* */
/* Tracing handling (specification only). */
/* */
-/* Copyright 2002, 2004-2007, 2009, 2011 by */
+/* Copyright 2002, 2004-2007, 2009, 2011-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -38,6 +38,7 @@ FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */
FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */
FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */
FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */
+FT_TRACE_DEF( bitmap ) /* bitmap checksum (ftobjs.c) */
/* Cache sub-system */
FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */
@@ -73,6 +74,7 @@ FT_TRACE_DEF( t1parse )
/* PostScript helper module `psaux' */
FT_TRACE_DEF( t1decode )
FT_TRACE_DEF( psobjs )
+FT_TRACE_DEF( psconv )
/* PostScript hinting module `pshinter' */
FT_TRACE_DEF( pshrec )
@@ -86,6 +88,10 @@ FT_TRACE_DEF( cffload )
FT_TRACE_DEF( cffobjs )
FT_TRACE_DEF( cffparse )
+FT_TRACE_DEF( cf2blues )
+FT_TRACE_DEF( cf2hints )
+FT_TRACE_DEF( cf2interp )
+
/* Type 42 driver component */
FT_TRACE_DEF( t42 )
@@ -136,6 +142,8 @@ FT_TRACE_DEF( gxvprop )
FT_TRACE_DEF( gxvlcar )
/* autofit components */
+FT_TRACE_DEF( afmodule )
+FT_TRACE_DEF( afhints )
FT_TRACE_DEF( afcjk )
FT_TRACE_DEF( aflatin )
FT_TRACE_DEF( aflatin2 )
diff --git a/include/freetype/internal/ftvalid.h b/include/freetype/internal/ftvalid.h
index 00cd85e..12ad036 100644
--- a/include/freetype/internal/ftvalid.h
+++ b/include/freetype/internal/ftvalid.h
@@ -4,7 +4,7 @@
/* */
/* FreeType validation support (specification). */
/* */
-/* Copyright 2004 by */
+/* Copyright 2004, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -76,6 +76,14 @@ FT_BEGIN_HEADER
} FT_ValidationLevel;
+#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
+ /* We disable the warning `structure was padded due to */
+ /* __declspec(align())' in order to compile cleanly with */
+ /* the maximum level of warnings. */
+#pragma warning( push )
+#pragma warning( disable : 4324 )
+#endif /* _MSC_VER */
+
/* validator structure */
typedef struct FT_ValidatorRec_
{
@@ -88,8 +96,11 @@ FT_BEGIN_HEADER
} FT_ValidatorRec;
+#if defined( _MSC_VER )
+#pragma warning( pop )
+#endif
-#define FT_VALIDATOR( x ) ((FT_Validator)( x ))
+#define FT_VALIDATOR( x ) ( (FT_Validator)( x ) )
FT_BASE( void )
diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h
index a96e0df..e903114 100644
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -5,7 +5,7 @@
/* Auxiliary functions and data structures related to PostScript fonts */
/* (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */
+/* Copyright 1996-2004, 2006, 2008, 2009, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -101,6 +101,9 @@ FT_BEGIN_HEADER
/* capacity :: The current size of the heap block. Increments by */
/* 1kByte chunks. */
/* */
+ /* init :: Set to 0xDEADBEEF if `elements' and `lengths' have */
+ /* been allocated. */
+ /* */
/* max_elems :: The maximum number of elements in table. */
/* */
/* num_elems :: The current number of elements in table. */
@@ -183,6 +186,7 @@ FT_BEGIN_HEADER
T1_FIELD_TYPE_STRING,
T1_FIELD_TYPE_KEY,
T1_FIELD_TYPE_BBOX,
+ T1_FIELD_TYPE_MM_BBOX,
T1_FIELD_TYPE_INTEGER_ARRAY,
T1_FIELD_TYPE_FIXED_ARRAY,
T1_FIELD_TYPE_CALLBACK,
@@ -225,7 +229,7 @@ FT_BEGIN_HEADER
T1_Field_ParseFunc reader;
FT_UInt offset; /* offset of field in object */
FT_Byte size; /* size of field in bytes */
- FT_UInt array_max; /* maximal number of elements for */
+ FT_UInt array_max; /* maximum number of elements for */
/* array */
FT_UInt count_offset; /* offset of element count for */
/* arrays; must not be zero if in */
@@ -531,7 +535,7 @@ FT_BEGIN_HEADER
/* */
/* max_points :: maximum points in builder outline */
/* */
- /* max_contours :: Maximal number of contours in builder outline. */
+ /* max_contours :: Maximum number of contours in builder outline. */
/* */
/* pos_x :: The horizontal translation (if composite glyph). */
/* */
diff --git a/include/freetype/internal/pshints.h b/include/freetype/internal/pshints.h
index 5b7b698..3fb18dc 100644
--- a/include/freetype/internal/pshints.h
+++ b/include/freetype/internal/pshints.h
@@ -6,7 +6,7 @@
/* recorders (specification only). These are used to support native */
/* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */
/* */
-/* Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2009 by */
+/* Copyright 2001-2003, 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, */
@@ -679,27 +679,37 @@ FT_BEGIN_HEADER
typedef PSHinter_Interface* PSHinter_Service;
+
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_, \
- get_t1_funcs_, get_t2_funcs_) \
- static const PSHinter_Interface class_ = \
- { \
- get_globals_funcs_, get_t1_funcs_, get_t2_funcs_ \
+#define FT_DEFINE_PSHINTER_INTERFACE( \
+ class_, \
+ get_globals_funcs_, \
+ get_t1_funcs_, \
+ get_t2_funcs_ ) \
+ static const PSHinter_Interface class_ = \
+ { \
+ get_globals_funcs_, \
+ get_t1_funcs_, \
+ get_t2_funcs_ \
};
#else /* FT_CONFIG_OPTION_PIC */
-#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_, \
- get_t1_funcs_, get_t2_funcs_) \
- void \
- FT_Init_Class_##class_( FT_Library library, \
- PSHinter_Interface* clazz) \
- { \
- FT_UNUSED(library); \
- clazz->get_globals_funcs = get_globals_funcs_; \
- clazz->get_t1_funcs = get_t1_funcs_; \
- clazz->get_t2_funcs = get_t2_funcs_; \
+#define FT_DEFINE_PSHINTER_INTERFACE( \
+ class_, \
+ get_globals_funcs_, \
+ get_t1_funcs_, \
+ get_t2_funcs_ ) \
+ void \
+ FT_Init_Class_ ## class_( FT_Library library, \
+ PSHinter_Interface* clazz ) \
+ { \
+ FT_UNUSED( library ); \
+ \
+ clazz->get_globals_funcs = get_globals_funcs_; \
+ clazz->get_t1_funcs = get_t1_funcs_; \
+ clazz->get_t2_funcs = get_t2_funcs_; \
}
#endif /* FT_CONFIG_OPTION_PIC */
diff --git a/include/freetype/internal/services/svprop.h b/include/freetype/internal/services/svprop.h
new file mode 100644
index 0000000..22da0bb
--- /dev/null
+++ b/include/freetype/internal/services/svprop.h
@@ -0,0 +1,81 @@
+/***************************************************************************/
+/* */
+/* svprop.h */
+/* */
+/* The FreeType property service (specification). */
+/* */
+/* Copyright 2012 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __SVPROP_H__
+#define __SVPROP_H__
+
+
+FT_BEGIN_HEADER
+
+
+#define FT_SERVICE_ID_PROPERTIES "properties"
+
+
+ typedef FT_Error
+ (*FT_Properties_SetFunc)( FT_Module module,
+ const char* property_name,
+ const void* value );
+
+ typedef FT_Error
+ (*FT_Properties_GetFunc)( FT_Module module,
+ const char* property_name,
+ void* value );
+
+
+ FT_DEFINE_SERVICE( Properties )
+ {
+ FT_Properties_SetFunc set_property;
+ FT_Properties_GetFunc get_property;
+ };
+
+
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \
+ set_property_, \
+ get_property_ ) \
+ static const FT_Service_PropertiesRec class_ = \
+ { \
+ set_property_, \
+ get_property_ \
+ };
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \
+ set_property_, \
+ get_property_ ) \
+ void \
+ FT_Init_Class_ ## class_( FT_Service_PropertiesRec* clazz ) \
+ { \
+ clazz->set_property = set_property_; \
+ clazz->get_property = get_property_; \
+ }
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+ /* */
+
+
+FT_END_HEADER
+
+
+#endif /* __SVPROP_H__ */
+
+
+/* END */
diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h
index 905ca8c..6b5e41f 100644
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -4,7 +4,7 @@
/* */
/* High-level `sfnt' driver interface (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
+/* Copyright 1996-2006, 2009, 2012-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -125,77 +125,6 @@ FT_BEGIN_HEADER
(*TT_Done_Face_Func)( TT_Face face );
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /*************************************************************************/
- /* */
- /* <FuncType> */
- /* TT_Load_SFNT_HeaderRec_Func */
- /* */
- /* <Description> */
- /* Loads the header of a SFNT font file. Supports collections. */
- /* */
- /* <Input> */
- /* face :: A handle to the target face object. */
- /* */
- /* stream :: The input stream. */
- /* */
- /* face_index :: The index of the TrueType font, if we are opening a */
- /* collection. */
- /* */
- /* <Output> */
- /* sfnt :: The SFNT header. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* The stream cursor must be at the font file's origin. */
- /* */
- /* This function recognizes fonts embedded in a `TrueType */
- /* collection'. */
- /* */
- /* This function checks that the header is valid by looking at the */
- /* values of `search_range', `entry_selector', and `range_shift'. */
- /* */
- typedef FT_Error
- (*TT_Load_SFNT_HeaderRec_Func)( TT_Face face,
- FT_Stream stream,
- FT_Long face_index,
- SFNT_Header sfnt );
-
-
- /*************************************************************************/
- /* */
- /* <FuncType> */
- /* TT_Load_Directory_Func */
- /* */
- /* <Description> */
- /* Loads the table directory into a face object. */
- /* */
- /* <Input> */
- /* face :: A handle to the target face object. */
- /* */
- /* stream :: The input stream. */
- /* */
- /* sfnt :: The SFNT header. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* The stream cursor must be on the first byte after the 4-byte font */
- /* format tag. This is the case just after a call to */
- /* TT_Load_Format_Tag(). */
- /* */
- typedef FT_Error
- (*TT_Load_Directory_Func)( TT_Face face,
- FT_Stream stream,
- SFNT_Header sfnt );
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
/*************************************************************************/
/* */
/* <FuncType> */
@@ -363,88 +292,6 @@ FT_BEGIN_HEADER
TT_SBit_MetricsRec *ametrics );
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /*************************************************************************/
- /* */
- /* <FuncType> */
- /* TT_Set_SBit_Strike_OldFunc */
- /* */
- /* <Description> */
- /* Select an sbit strike for a given size request. */
- /* */
- /* <Input> */
- /* face :: The target face object. */
- /* */
- /* req :: The size request. */
- /* */
- /* <Output> */
- /* astrike_index :: The index of the sbit strike. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. Returns an error if no */
- /* sbit strike exists for the selected ppem values. */
- /* */
- typedef FT_Error
- (*TT_Set_SBit_Strike_OldFunc)( TT_Face face,
- FT_UInt x_ppem,
- FT_UInt y_ppem,
- FT_ULong* astrike_index );
-
-
- /*************************************************************************/
- /* */
- /* <FuncType> */
- /* TT_CharMap_Load_Func */
- /* */
- /* <Description> */
- /* Loads a given TrueType character map into memory. */
- /* */
- /* <Input> */
- /* face :: A handle to the parent face object. */
- /* */
- /* stream :: A handle to the current stream object. */
- /* */
- /* <InOut> */
- /* cmap :: A pointer to a cmap object. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* The function assumes that the stream is already in use (i.e., */
- /* opened). In case of error, all partially allocated tables are */
- /* released. */
- /* */
- typedef FT_Error
- (*TT_CharMap_Load_Func)( TT_Face face,
- void* cmap,
- FT_Stream input );
-
-
- /*************************************************************************/
- /* */
- /* <FuncType> */
- /* TT_CharMap_Free_Func */
- /* */
- /* <Description> */
- /* Destroys a character mapping table. */
- /* */
- /* <Input> */
- /* face :: A handle to the parent face object. */
- /* */
- /* cmap :: A handle to a cmap object. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- typedef FT_Error
- (*TT_CharMap_Free_Func)( TT_Face face,
- void* cmap );
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
/*************************************************************************/
/* */
/* <FuncType> */
@@ -657,11 +504,6 @@ FT_BEGIN_HEADER
TT_Load_Any_Func load_any;
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- TT_Load_SFNT_HeaderRec_Func load_sfnt_header;
- TT_Load_Directory_Func load_directory;
-#endif
-
/* these functions are called by `load_face' but they can also */
/* be called from external modules, if there is a need to do so */
TT_Load_Table_Func load_head;
@@ -674,12 +516,6 @@ FT_BEGIN_HEADER
TT_Load_Table_Func load_name;
TT_Free_Table_Func free_name;
- /* optional tables */
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- TT_Load_Table_Func load_hdmx_stub;
- TT_Free_Table_Func free_hdmx_stub;
-#endif
-
/* this field was called `load_kerning' up to version 2.1.10 */
TT_Load_Table_Func load_kern;
@@ -690,43 +526,12 @@ FT_BEGIN_HEADER
/* version 2.1.10 */
TT_Load_Table_Func load_bhed;
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /* see `ttsbit.h' */
- TT_Set_SBit_Strike_OldFunc set_sbit_strike_stub;
- TT_Load_Table_Func load_sbits_stub;
-
- /*
- * The following two fields appeared in version 2.1.8, and were placed
- * between `load_sbits' and `load_sbit_image'. We support them as a
- * special exception since they are used by Xfont library within the
- * X.Org xserver, and because the probability that other rogue clients
- * use the other version 2.1.7 fields below is _extremely_ low.
- *
- * Note that this forces us to disable an interesting memory-saving
- * optimization though...
- */
-
- TT_Find_SBit_Image_Func find_sbit_image;
- TT_Load_SBit_Metrics_Func load_sbit_metrics;
-
-#endif
-
TT_Load_SBit_Image_Func load_sbit_image;
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- TT_Free_Table_Func free_sbits_stub;
-#endif
-
/* see `ttpost.h' */
TT_Get_PS_Name_Func get_psname;
TT_Free_Table_Func free_psnames;
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- TT_CharMap_Load_Func load_charmap_stub;
- TT_CharMap_Free_Func free_charmap_stub;
-#endif
-
/* starting here, the structure differs from version 2.1.7 */
/* this field was introduced in version 2.1.8, named `get_psname' */
@@ -755,136 +560,141 @@ FT_BEGIN_HEADER
#ifndef FT_CONFIG_OPTION_PIC
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a) \
- a,
-#else
- #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a)
-#endif
-#define FT_INTERNAL(a) \
- a,
-
-#define FT_DEFINE_SFNT_INTERFACE(class_, \
- goto_table_, init_face_, load_face_, done_face_, get_interface_, \
- load_any_, load_sfnt_header_, load_directory_, load_head_, \
- load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_, \
- load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_, \
- load_kern_, load_gasp_, load_pclt_, load_bhed_, \
- set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_, \
- load_sbit_metrics_, load_sbit_image_, free_sbits_stub_, \
- get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_, \
- get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_, \
- set_sbit_strike_, load_strike_metrics_, get_metrics_ ) \
- static const SFNT_Interface class_ = \
- { \
- FT_INTERNAL(goto_table_) \
- FT_INTERNAL(init_face_) \
- FT_INTERNAL(load_face_) \
- FT_INTERNAL(done_face_) \
- FT_INTERNAL(get_interface_) \
- FT_INTERNAL(load_any_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory_) \
- FT_INTERNAL(load_head_) \
- FT_INTERNAL(load_hhea_) \
- FT_INTERNAL(load_cmap_) \
- FT_INTERNAL(load_maxp_) \
- FT_INTERNAL(load_os2_) \
- FT_INTERNAL(load_post_) \
- FT_INTERNAL(load_name_) \
- FT_INTERNAL(free_name_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub_) \
- FT_INTERNAL(load_kern_) \
- FT_INTERNAL(load_gasp_) \
- FT_INTERNAL(load_pclt_) \
- FT_INTERNAL(load_bhed_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics_) \
- FT_INTERNAL(load_sbit_image_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub_) \
- FT_INTERNAL(get_psname_) \
- FT_INTERNAL(free_psnames_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub_) \
- FT_INTERNAL(get_kerning_) \
- FT_INTERNAL(load_font_dir_) \
- FT_INTERNAL(load_hmtx_) \
- FT_INTERNAL(load_eblc_) \
- FT_INTERNAL(free_eblc_) \
- FT_INTERNAL(set_sbit_strike_) \
- FT_INTERNAL(load_strike_metrics_) \
- FT_INTERNAL(get_metrics_) \
+#define FT_DEFINE_SFNT_INTERFACE( \
+ class_, \
+ goto_table_, \
+ init_face_, \
+ load_face_, \
+ done_face_, \
+ get_interface_, \
+ load_any_, \
+ load_head_, \
+ load_hhea_, \
+ load_cmap_, \
+ load_maxp_, \
+ load_os2_, \
+ load_post_, \
+ load_name_, \
+ free_name_, \
+ load_kern_, \
+ load_gasp_, \
+ load_pclt_, \
+ load_bhed_, \
+ load_sbit_image_, \
+ get_psname_, \
+ free_psnames_, \
+ get_kerning_, \
+ load_font_dir_, \
+ load_hmtx_, \
+ load_eblc_, \
+ free_eblc_, \
+ set_sbit_strike_, \
+ load_strike_metrics_, \
+ get_metrics_ ) \
+ static const SFNT_Interface class_ = \
+ { \
+ goto_table_, \
+ init_face_, \
+ load_face_, \
+ done_face_, \
+ get_interface_, \
+ load_any_, \
+ load_head_, \
+ load_hhea_, \
+ load_cmap_, \
+ load_maxp_, \
+ load_os2_, \
+ load_post_, \
+ load_name_, \
+ free_name_, \
+ load_kern_, \
+ load_gasp_, \
+ load_pclt_, \
+ load_bhed_, \
+ load_sbit_image_, \
+ get_psname_, \
+ free_psnames_, \
+ get_kerning_, \
+ load_font_dir_, \
+ load_hmtx_, \
+ load_eblc_, \
+ free_eblc_, \
+ set_sbit_strike_, \
+ load_strike_metrics_, \
+ get_metrics_, \
};
#else /* FT_CONFIG_OPTION_PIC */
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_) \
- clazz->a = a_;
-#else
- #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_)
-#endif
-#define FT_INTERNAL(a, a_) \
- clazz->a = a_;
-
-#define FT_DEFINE_SFNT_INTERFACE(class_, \
- goto_table_, init_face_, load_face_, done_face_, get_interface_, \
- load_any_, load_sfnt_header_, load_directory_, load_head_, \
- load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_, \
- load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_, \
- load_kern_, load_gasp_, load_pclt_, load_bhed_, \
- set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_, \
- load_sbit_metrics_, load_sbit_image_, free_sbits_stub_, \
- get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_, \
- get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_, \
- set_sbit_strike_, load_strike_metrics_, get_metrics_ ) \
- void \
- FT_Init_Class_##class_( FT_Library library, SFNT_Interface* clazz ) \
- { \
- FT_UNUSED(library); \
- FT_INTERNAL(goto_table,goto_table_) \
- FT_INTERNAL(init_face,init_face_) \
- FT_INTERNAL(load_face,load_face_) \
- FT_INTERNAL(done_face,done_face_) \
- FT_INTERNAL(get_interface,get_interface_) \
- FT_INTERNAL(load_any,load_any_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header,load_sfnt_header_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory,load_directory_) \
- FT_INTERNAL(load_head,load_head_) \
- FT_INTERNAL(load_hhea,load_hhea_) \
- FT_INTERNAL(load_cmap,load_cmap_) \
- FT_INTERNAL(load_maxp,load_maxp_) \
- FT_INTERNAL(load_os2,load_os2_) \
- FT_INTERNAL(load_post,load_post_) \
- FT_INTERNAL(load_name,load_name_) \
- FT_INTERNAL(free_name,free_name_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub,load_hdmx_stub_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub,free_hdmx_stub_) \
- FT_INTERNAL(load_kern,load_kern_) \
- FT_INTERNAL(load_gasp,load_gasp_) \
- FT_INTERNAL(load_pclt,load_pclt_) \
- FT_INTERNAL(load_bhed,load_bhed_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub,set_sbit_strike_stub_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub,load_sbits_stub_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image,find_sbit_image_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics,load_sbit_metrics_) \
- FT_INTERNAL(load_sbit_image,load_sbit_image_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub,free_sbits_stub_) \
- FT_INTERNAL(get_psname,get_psname_) \
- FT_INTERNAL(free_psnames,free_psnames_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub,load_charmap_stub_) \
- FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub,free_charmap_stub_) \
- FT_INTERNAL(get_kerning,get_kerning_) \
- FT_INTERNAL(load_font_dir,load_font_dir_) \
- FT_INTERNAL(load_hmtx,load_hmtx_) \
- FT_INTERNAL(load_eblc,load_eblc_) \
- FT_INTERNAL(free_eblc,free_eblc_) \
- FT_INTERNAL(set_sbit_strike,set_sbit_strike_) \
- FT_INTERNAL(load_strike_metrics,load_strike_metrics_) \
- FT_INTERNAL(get_metrics,get_metrics_) \
+#define FT_INTERNAL( a, a_ ) \
+ clazz->a = a_;
+
+#define FT_DEFINE_SFNT_INTERFACE( \
+ class_, \
+ goto_table_, \
+ init_face_, \
+ load_face_, \
+ done_face_, \
+ get_interface_, \
+ load_any_, \
+ load_head_, \
+ load_hhea_, \
+ load_cmap_, \
+ load_maxp_, \
+ load_os2_, \
+ load_post_, \
+ load_name_, \
+ free_name_, \
+ load_kern_, \
+ load_gasp_, \
+ load_pclt_, \
+ load_bhed_, \
+ load_sbit_image_, \
+ get_psname_, \
+ free_psnames_, \
+ get_kerning_, \
+ load_font_dir_, \
+ load_hmtx_, \
+ load_eblc_, \
+ free_eblc_, \
+ set_sbit_strike_, \
+ load_strike_metrics_, \
+ get_metrics_ ) \
+ void \
+ FT_Init_Class_ ## class_( FT_Library library, \
+ SFNT_Interface* clazz ) \
+ { \
+ FT_UNUSED( library ); \
+ \
+ clazz->goto_table = goto_table_; \
+ clazz->init_face = init_face_; \
+ clazz->load_face = load_face_; \
+ clazz->done_face = done_face_; \
+ clazz->get_interface = get_interface_; \
+ clazz->load_any = load_any_; \
+ clazz->load_head = load_head_; \
+ clazz->load_hhea = load_hhea_; \
+ clazz->load_cmap = load_cmap_; \
+ clazz->load_maxp = load_maxp_; \
+ clazz->load_os2 = load_os2_; \
+ clazz->load_post = load_post_; \
+ clazz->load_name = load_name_; \
+ clazz->free_name = free_name_; \
+ clazz->load_kern = load_kern_; \
+ clazz->load_gasp = load_gasp_; \
+ clazz->load_pclt = load_pclt_; \
+ clazz->load_bhed = load_bhed_; \
+ clazz->load_sbit_image = load_sbit_image_; \
+ clazz->get_psname = get_psname_; \
+ clazz->free_psnames = free_psnames_; \
+ clazz->get_kerning = get_kerning_; \
+ clazz->load_font_dir = load_font_dir_; \
+ clazz->load_hmtx = load_hmtx_; \
+ clazz->load_eblc = load_eblc_; \
+ clazz->free_eblc = free_eblc_; \
+ clazz->set_sbit_strike = set_sbit_strike_; \
+ clazz->load_strike_metrics = load_strike_metrics_; \
+ clazz->get_metrics = get_metrics_; \
}
#endif /* FT_CONFIG_OPTION_PIC */
diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h
index f859de2..e20237c 100644
--- a/include/freetype/internal/t1types.h
+++ b/include/freetype/internal/t1types.h
@@ -5,7 +5,7 @@
/* Basic Type1/Type2 type definitions and interface (specification */
/* only). */
/* */
-/* Copyright 1996-2004, 2006, 2008, 2009, 2011 by */
+/* Copyright 1996-2004, 2006, 2008, 2009, 2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -205,10 +205,6 @@ FT_BEGIN_HEADER
FT_CharMapRec charmaprecs[2];
FT_CharMap charmaps[2];
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- PS_Unicodes unicode_map;
-#endif
-
/* support for Multiple Masters fonts */
PS_Blend blend;
diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
index 57b1731..1bbfe49 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -5,7 +5,7 @@
/* Basic SFNT/TrueType type definitions and interface (specification */
/* only). */
/* */
-/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by */
+/* Copyright 1996-2002, 2004-2008, 2012-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -311,87 +311,6 @@ FT_BEGIN_HEADER
} TT_GaspRec;
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* TT_HdmxEntryRec */
- /* */
- /* <Description> */
- /* A small structure used to model the pre-computed widths of a given */
- /* size. They are found in the `hdmx' table. */
- /* */
- /* <Fields> */
- /* ppem :: The pixels per EM value at which these metrics apply. */
- /* */
- /* max_width :: The maximum advance width for this metric. */
- /* */
- /* widths :: An array of widths. Note: These are 8-bit bytes. */
- /* */
- typedef struct TT_HdmxEntryRec_
- {
- FT_Byte ppem;
- FT_Byte max_width;
- FT_Byte* widths;
-
- } TT_HdmxEntryRec, *TT_HdmxEntry;
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* TT_HdmxRec */
- /* */
- /* <Description> */
- /* A structure used to model the `hdmx' table, which contains */
- /* pre-computed widths for a set of given sizes/dimensions. */
- /* */
- /* <Fields> */
- /* version :: The version number. */
- /* */
- /* num_records :: The number of hdmx records. */
- /* */
- /* records :: An array of hdmx records. */
- /* */
- typedef struct TT_HdmxRec_
- {
- FT_UShort version;
- FT_Short num_records;
- TT_HdmxEntry records;
-
- } TT_HdmxRec, *TT_Hdmx;
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* TT_Kern0_PairRec */
- /* */
- /* <Description> */
- /* A structure used to model a kerning pair for the kerning table */
- /* format 0. The engine now loads this table if it finds one in the */
- /* font file. */
- /* */
- /* <Fields> */
- /* left :: The index of the left glyph in pair. */
- /* */
- /* right :: The index of the right glyph in pair. */
- /* */
- /* value :: The kerning distance. A positive value spaces the */
- /* glyphs, a negative one makes them closer. */
- /* */
- typedef struct TT_Kern0_PairRec_
- {
- FT_UShort left; /* index of left glyph in pair */
- FT_UShort right; /* index of right glyph in pair */
- FT_FWord value; /* kerning value */
-
- } TT_Kern0_PairRec, *TT_Kern0_Pair;
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
@@ -1269,9 +1188,6 @@ FT_BEGIN_HEADER
TT_HoriHeader horizontal; /* TrueType horizontal header */
TT_MaxProfile max_profile;
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- FT_ULong max_components; /* stubbed to 0 */
-#endif
FT_Bool vertical_info;
TT_VertHeader vertical; /* TT Vertical header, if present */
@@ -1308,11 +1224,6 @@ FT_BEGIN_HEADER
/* */
/***********************************************************************/
- /* horizontal device metrics */
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- TT_HdmxRec hdmx;
-#endif
-
/* grid-fitting and scaling table */
TT_GaspRec gasp; /* the `gasp' table */
@@ -1320,11 +1231,6 @@ FT_BEGIN_HEADER
TT_PCLT pclt;
/* embedded bitmaps support */
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- FT_ULong num_sbit_strikes;
- TT_SBit_Strike sbit_strikes;
-#endif
-
FT_ULong num_sbit_scales;
TT_SBit_Scale sbit_scales;
@@ -1338,12 +1244,6 @@ FT_BEGIN_HEADER
/* */
/***********************************************************************/
- /* the glyph locations */
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- FT_UShort num_locations_stub;
- FT_Long* glyph_locations_stub;
-#endif
-
/* the font program, if any */
FT_ULong font_program_size;
FT_Byte* font_program;
@@ -1356,13 +1256,6 @@ FT_BEGIN_HEADER
FT_ULong cvt_size;
FT_Short* cvt;
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- /* the format 0 kerning table, if any */
- FT_Int num_kern_pairs;
- FT_Int kern_table_index;
- TT_Kern0_Pair kern_pairs;
-#endif
-
/* A pointer to the bytecode interpreter to use. This is also */
/* used to hook the debugger for the `ttdebug' utility. */
TT_Interpreter interpreter;
@@ -1383,11 +1276,8 @@ FT_BEGIN_HEADER
const char* postscript_name;
- /* since version 2.1.8, but was originally placed after */
- /* `glyph_locations_stub' */
FT_ULong glyf_len;
- /* since version 2.1.8, but was originally placed before `extra' */
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_Bool doblend;
GX_Blend blend;
@@ -1428,6 +1318,13 @@ FT_BEGIN_HEADER
FT_ULong horz_metrics_offset;
FT_ULong vert_metrics_offset;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* since 2.4.12 */
+ FT_ULong sph_found_func_flags; /* special functions found */
+ /* for this face */
+ FT_Bool sph_compatibility_mode;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
} TT_FaceRec;
@@ -1443,7 +1340,7 @@ FT_BEGIN_HEADER
/* <Fields> */
/* memory :: A handle to the memory manager. */
/* */
- /* max_points :: The maximal size in points of the zone. */
+ /* max_points :: The maximum size in points of the zone. */
/* */
/* max_contours :: Max size in links contours of the zone. */
/* */
diff --git a/include/freetype/ttnameid.h b/include/freetype/ttnameid.h
index 66aef04..173f88c 100644
--- a/include/freetype/ttnameid.h
+++ b/include/freetype/ttnameid.h
@@ -4,7 +4,7 @@
/* */
/* TrueType name ID definitions (specification only). */
/* */
-/* Copyright 1996-2002, 2003, 2004, 2006, 2007, 2008 by */
+/* Copyright 1996-2004, 2006-2008, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -316,11 +316,12 @@ FT_BEGIN_HEADER
/* */
/* Possible values of the language identifier field in the name records */
/* of the TTF `name' table if the `platform' identifier code is */
- /* TT_PLATFORM_MACINTOSH. */
+ /* TT_PLATFORM_MACINTOSH. These values are also used as return values */
+ /* for function @FT_Get_CMap_Language_ID. */
/* */
/* The canonical source for the Apple assigned Language ID's is at */
/* */
- /* http://fonts.apple.com/TTRefMan/RM06/Chap6name.html */
+ /* https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html */
/* */
#define TT_MAC_LANGID_ENGLISH 0
#define TT_MAC_LANGID_FRENCH 1
@@ -461,21 +462,10 @@ FT_BEGIN_HEADER
/* of the TTF `name' table if the `platform' identifier code is */
/* TT_PLATFORM_MICROSOFT. */
/* */
- /* The canonical source for the MS assigned LCID's (seems to) be at */
+ /* The canonical source for the MS assigned LCIDs is */
/* */
/* http://www.microsoft.com/globaldev/reference/lcid-all.mspx */
/* */
- /* It used to be at various places, among them */
- /* */
- /* http://www.microsoft.com/typography/OTSPEC/lcid-cp.txt */
- /* http://www.microsoft.com/globaldev/reference/loclanghome.asp */
- /* http://support.microsoft.com/support/kb/articles/Q224/8/04.ASP */
- /* http://msdn.microsoft.com/library/en-us/passport25/ */
- /* NET_Passport_VBScript_Documentation/Single_Sign_In/ */
- /* Advanced_Single_Sign_In/Localization_and_LCIDs.asp */
- /* */
- /* Hopefully, it seems now that the Globaldev site prevails... */
- /* (updated by Antoine, 2004-02-17) */
#define TT_MS_LANGID_ARABIC_GENERAL 0x0001
#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401
diff --git a/include/freetype/tttables.h b/include/freetype/tttables.h
index 02236c2..fe07117 100644
--- a/include/freetype/tttables.h
+++ b/include/freetype/tttables.h
@@ -5,7 +5,7 @@
/* Basic SFNT/TrueType tables definitions and interface */
/* (specification only). */
/* */
-/* Copyright 1996-2005, 2008-2011 by */
+/* Copyright 1996-2005, 2008-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -600,6 +600,16 @@ FT_BEGIN_HEADER
/* by the sfnt, truetype, and opentype drivers. See @FT_Sfnt_Tag for */
/* a list. */
/* */
+ /* Here an example how to access the `vhea' table: */
+ /* */
+ /* { */
+ /* TT_VertHeader* vert_header; */
+ /* */
+ /* */
+ /* vert_header = */
+ /* (TT_VertHeader*)FT_Get_Sfnt_Table( face, ft_sfnt_vhea ); */
+ /* } */
+ /* */
FT_EXPORT( void* )
FT_Get_Sfnt_Table( FT_Face face,
FT_Sfnt_Tag tag );
@@ -702,7 +712,8 @@ FT_BEGIN_HEADER
* FreeType error code. 0~means success.
*
* @note:
- * SFNT tables with length zero are treated as missing.
+ * While parsing fonts, FreeType handles SFNT tables with length zero as
+ * missing.
*
*/
FT_EXPORT( FT_Error )
@@ -729,6 +740,9 @@ FT_BEGIN_HEADER
/* The language ID of `charmap'. If `charmap' doesn't belong to a */
/* TrueType/sfnt face, just return~0 as the default value. */
/* */
+ /* For a format~14 cmap (to access Unicode IVS), the return value is */
+ /* 0xFFFFFFFF. */
+ /* */
FT_EXPORT( FT_ULong )
FT_Get_CMap_Language_ID( FT_CharMap charmap );
diff --git a/include/freetype/tttags.h b/include/freetype/tttags.h
index 307ce4b..be8c524 100644
--- a/include/freetype/tttags.h
+++ b/include/freetype/tttags.h
@@ -4,7 +4,7 @@
/* */
/* Tags for TrueType and OpenType tables (specification only). */
/* */
-/* Copyright 1996-2001, 2004, 2005, 2007, 2008 by */
+/* Copyright 1996-2001, 2004, 2005, 2007, 2008, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -40,6 +40,8 @@ FT_BEGIN_HEADER
#define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' )
#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' )
#define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' )
+#define TTAG_CBDT FT_MAKE_TAG( 'C', 'B', 'D', 'T' )
+#define TTAG_CBLC FT_MAKE_TAG( 'C', 'B', 'L', 'C' )
#define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' )
#define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' )
#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' )
diff --git a/src/autofit/afangles.c b/src/autofit/afangles.c
index 790af17..b44a5ba 100644
--- a/src/autofit/afangles.c
+++ b/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/src/autofit/afcjk.c b/src/autofit/afcjk.c
index 8e407c8..f69a528 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for CJK script (body). */
/* */
-/* Copyright 2006-2012 by */
+/* Copyright 2006-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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;
}
@@ -478,7 +481,8 @@
FT_Bool under_ref = FT_BOOL( shoot < ref );
- if ( (AF_CJK_BLUE_TOP == bb || AF_CJK_BLUE_RIGHT == bb) ^ under_ref )
+ if ( ( AF_CJK_BLUE_TOP == bb ||
+ AF_CJK_BLUE_RIGHT == bb ) ^ under_ref )
*blue_shoot = *blue_ref = ( shoot + ref ) / 2;
}
@@ -556,14 +560,14 @@
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 );
}
FT_Set_Charmap( face, oldmap );
- return AF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -699,7 +703,7 @@
{
AF_Point pt = seg->first;
AF_Point last = seg->last;
- AF_Flags f0 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL);
+ AF_Flags f0 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL );
AF_Flags f1;
@@ -708,7 +712,7 @@
for ( ; pt != last; f0 = f1 )
{
pt = pt->next;
- f1 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL);
+ f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL );
if ( !f0 && !f1 )
break;
@@ -718,7 +722,7 @@
}
}
- return AF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -892,7 +896,7 @@
AF_Dimension dim )
{
AF_AxisHints axis = &hints->axis[dim];
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Memory memory = hints->memory;
AF_CJKAxis laxis = &((AF_CJKMetrics)hints->metrics)->axis[dim];
@@ -962,14 +966,15 @@
/* can make a single edge. */
if ( link )
{
- AF_Segment seg1 = edge->first;
- AF_Segment link1;
+ AF_Segment seg1 = edge->first;
FT_Pos dist2 = 0;
do
{
- link1 = seg1->link;
+ AF_Segment link1 = seg1->link;
+
+
if ( link1 )
{
dist2 = AF_SEGMENT_DIST( link, link1 );
@@ -2190,6 +2195,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 +2234,7 @@
AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class,
AF_SCRIPT_CJK,
af_cjk_uniranges,
+ 0x7530, /* ç”° */
sizeof ( AF_CJKMetricsRec ),
@@ -2250,6 +2257,7 @@
AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class,
AF_SCRIPT_CJK,
af_cjk_uniranges,
+ 0,
sizeof ( AF_CJKMetricsRec ),
diff --git a/src/autofit/afcjk.h b/src/autofit/afcjk.h
index 8416c0d..ab816f2 100644
--- a/src/autofit/afcjk.h
+++ b/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/src/autofit/afdummy.c b/src/autofit/afdummy.c
index 4bf278c..2294455 100644
--- a/src/autofit/afdummy.c
+++ b/src/autofit/afdummy.c
@@ -5,7 +5,7 @@
/* Auto-fitter dummy routines to be used if no hinting should be */
/* performed (body). */
/* */
-/* Copyright 2003-2005, 2011 by */
+/* Copyright 2003-2005, 2011, 2013 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 @@
{
af_glyph_hints_rescale( hints,
metrics );
- return AF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -39,13 +39,14 @@
FT_UNUSED( hints );
FT_UNUSED( outline );
- return AF_Err_Ok;
+ return FT_Err_Ok;
}
AF_DEFINE_SCRIPT_CLASS( af_dummy_script_class,
- AF_SCRIPT_NONE,
+ AF_SCRIPT_DUMMY,
NULL,
+ 0,
sizeof ( AF_ScriptMetricsRec ),
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index 3e0c02d..3e41465 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter routines to compute global hinting values (body). */
/* */
-/* Copyright 2003-2011 by */
+/* Copyright 2003-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -49,55 +49,33 @@
#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. */
static FT_Error
af_face_globals_compute_script_coverage( AF_FaceGlobals globals )
{
- FT_Error error = AF_Err_Ok;
+ FT_Error error;
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;
+ error = FT_Err_Ok;
goto Exit;
}
@@ -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;
}
@@ -253,18 +237,18 @@
FT_UInt script = options & 15;
const FT_Offset script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) /
sizeof ( AF_SCRIPT_CLASSES_GET[0] );
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( gindex >= (FT_ULong)globals->glyph_count )
{
- error = AF_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
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/src/autofit/afglobal.h b/src/autofit/afglobal.h
index cc6860b..2e24900 100644
--- a/src/autofit/afglobal.h
+++ b/src/autofit/afglobal.h
@@ -5,7 +5,7 @@
/* Auto-fitter routines to compute global hinting values */
/* (specification). */
/* */
-/* Copyright 2003-2005, 2007, 2009, 2011 by */
+/* Copyright 2003-2005, 2007, 2009, 2011-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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/src/autofit/afhints.c b/src/autofit/afhints.c
index f51066f..e8defaa 100644
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines (body). */
/* */
-/* Copyright 2003-2007, 2009-2011 by */
+/* Copyright 2003-2007, 2009-2013 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 FT_INTERNAL_CALC_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. */
@@ -28,7 +39,7 @@
FT_Memory memory,
AF_Segment *asegment )
{
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
AF_Segment segment = NULL;
@@ -41,7 +52,7 @@
if ( old_max >= big_max )
{
- error = AF_Err_Out_Of_Memory;
+ error = FT_THROW( Out_Of_Memory );
goto Exit;
}
@@ -70,9 +81,9 @@
FT_Int fpos,
AF_Direction dir,
FT_Memory memory,
- AF_Edge *aedge )
+ AF_Edge *anedge )
{
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
AF_Edge edge = NULL;
AF_Edge edges;
@@ -86,7 +97,7 @@
if ( old_max >= big_max )
{
- error = AF_Err_Out_Of_Memory;
+ error = FT_THROW( Out_Of_Memory );
goto Exit;
}
@@ -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
@@ -296,7 +316,7 @@
axis = &hints->axis[dim];
*num_segments = axis->num_segments;
- return AF_Err_Ok;
+ return FT_Err_Ok;
}
#ifdef __cplusplus
}
@@ -320,20 +340,20 @@
if ( !offset )
- return AF_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT;
axis = &hints->axis[dim];
if ( idx < 0 || idx >= axis->num_segments )
- return AF_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
seg = &axis->segments[idx];
- *offset = (dim == AF_DIMENSION_HORZ) ? seg->first->ox
- : seg->first->oy;
+ *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox
+ : seg->first->oy;
- return AF_Err_Ok;
+ return FT_Err_Ok;
}
#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;
}
@@ -571,7 +593,7 @@
af_glyph_hints_reload( AF_GlyphHints hints,
FT_Outline* outline )
{
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
AF_Point points;
FT_UInt old_max, new_max;
FT_Fixed x_scale = hints->x_scale;
@@ -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/src/autofit/afhints.h b/src/autofit/afhints.h
index 1c52e0d..776b3c8 100644
--- a/src/autofit/afhints.h
+++ b/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/src/autofit/afindic.c b/src/autofit/afindic.c
index 9c74838..8c24972 100644
--- a/src/autofit/afindic.c
+++ b/src/autofit/afindic.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for Indic scripts (body). */
/* */
-/* Copyright 2007, 2011 by */
+/* Copyright 2007, 2011-2013 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 );
@@ -56,7 +56,7 @@
FT_Set_Charmap( face, oldmap );
- return AF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -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/src/autofit/afindic.h b/src/autofit/afindic.h
index 662a982..c252cf2 100644
--- a/src/autofit/afindic.h
+++ b/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/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 30145a2..ef0157a 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for latin script (body). */
/* */
-/* Copyright 2003-2011 by */
+/* Copyright 2003-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -20,6 +20,7 @@
#include FT_ADVANCES_H
#include FT_INTERNAL_DEBUG_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,41 +548,20 @@
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 );
}
FT_Set_Charmap( face, oldmap );
- return AF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -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 )
{
@@ -677,7 +743,7 @@
if ( delta2 < 32 )
delta2 = 0;
- else if ( delta < 48 )
+ else if ( delta2 < 48 )
delta2 = 32;
else
delta2 = 64;
@@ -705,6 +771,7 @@
{
metrics->root.scaler.render_mode = scaler->render_mode;
metrics->root.scaler.face = scaler->face;
+ metrics->root.scaler.flags = scaler->flags;
af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );
af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );
@@ -728,7 +795,7 @@
{
AF_AxisHints axis = &hints->axis[dim];
FT_Memory memory = hints->memory;
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
AF_Segment segment = NULL;
AF_SegmentRec seg0;
AF_Point* contour = hints->contours;
@@ -848,7 +915,7 @@
on_edge = 0;
segment = NULL;
- /* fallthrough */
+ /* fall through */
}
}
@@ -884,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;
@@ -1040,7 +1107,7 @@
AF_Dimension dim )
{
AF_AxisHints axis = &hints->axis[dim];
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Memory memory = hints->memory;
AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
@@ -1169,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 */
@@ -1367,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 */
@@ -1380,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;
@@ -1476,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;
@@ -1518,7 +1583,7 @@
hints->scaler_flags = scaler_flags;
hints->other_flags = other_flags;
- return AF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -1722,7 +1787,7 @@
if ( delta < 0 )
delta = -delta;
- if (delta >= 16)
+ if ( delta >= 16 )
{
dist = org_dist;
if ( dist < 48 )
@@ -1762,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 ));
@@ -1808,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 */
@@ -1844,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;
@@ -1856,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 )
@@ -1890,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;
}
@@ -1947,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
{
@@ -1989,7 +2080,7 @@
cur_pos1 = FT_PIX_ROUND( org_center );
- if (cur_len <= 64 )
+ if ( cur_len <= 64 )
{
u_off = 32;
d_off = 32;
@@ -2016,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 );
@@ -2046,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;
}
}
@@ -2154,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 ));
@@ -2164,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
@@ -2191,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,
@@ -2201,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
}
@@ -2333,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 )
};
@@ -2344,6 +2470,7 @@
AF_DEFINE_SCRIPT_CLASS( af_latin_script_class,
AF_SCRIPT_LATIN,
af_latin_uniranges,
+ 'o',
sizeof ( AF_LatinMetricsRec ),
diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h
index c5c2d13..d9170b3 100644
--- a/src/autofit/aflatin.h
+++ b/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/src/autofit/aflatin2.c b/src/autofit/aflatin2.c
index ea6af8d..b1e9658 100644
--- a/src/autofit/aflatin2.c
+++ b/src/autofit/aflatin2.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for latin script (body). */
/* */
-/* Copyright 2003-2011 by */
+/* Copyright 2003-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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;
@@ -465,7 +475,7 @@
af_latin2_metrics_init( AF_LatinMetrics metrics,
FT_Face face )
{
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_CharMap oldmap = face->charmap;
FT_UInt ee;
@@ -491,14 +501,13 @@
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 );
}
FT_Set_Charmap( face, oldmap );
- return AF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -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 )
@@ -658,6 +685,7 @@
{
metrics->root.scaler.render_mode = scaler->render_mode;
metrics->root.scaler.face = scaler->face;
+ metrics->root.scaler.flags = scaler->flags;
af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );
af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );
@@ -680,7 +708,7 @@
{
AF_AxisHints axis = &hints->axis[dim];
FT_Memory memory = hints->memory;
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
AF_Segment segment = NULL;
AF_SegmentRec seg0;
AF_Point* contour = hints->contours;
@@ -796,17 +824,17 @@
segment->dir = first->out_dir;
segment->first = first;
segment->last = point;
- segment->pos = (FT_Short)(( min_u + max_u ) >> 1);
+ segment->pos = (FT_Short)( ( min_u + max_u ) >> 1 );
segment->min_coord = (FT_Short) min_v;
segment->max_coord = (FT_Short) max_v;
- segment->height = (FT_Short)(max_v - min_v);
+ segment->height = (FT_Short)( max_v - min_v );
/* a segment is round if it doesn't have successive */
/* on-curve points. */
{
AF_Point pt = first;
AF_Point last = point;
- AF_Flags f0 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL);
+ AF_Flags f0 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL );
AF_Flags f1;
@@ -815,7 +843,7 @@
for ( ; pt != last; f0 = f1 )
{
pt = pt->next;
- f1 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL);
+ f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL );
if ( !f0 && !f1 )
break;
@@ -832,7 +860,7 @@
break;
/* jump to the start of the next segment, if any */
- while ( FT_ABS(point->out_dir) != major_dir )
+ while ( FT_ABS( point->out_dir ) != major_dir )
{
point = point->next;
@@ -900,16 +928,17 @@
FT_UInt count = axis->num_segments;
FT_UInt ii, jj;
- for (ii = 0; ii < count; ii++)
+ for ( ii = 0; ii < count; ii++ )
{
if ( segments[ii].dir > 0 )
{
- for (jj = ii+1; jj < count; jj++)
+ for ( jj = ii + 1; jj < count; jj++ )
{
if ( segments[jj].dir < 0 )
{
AF_SegmentRec tmp;
+
tmp = segments[ii];
segments[ii] = segments[jj];
segments[jj] = tmp;
@@ -1036,7 +1065,7 @@
AF_Dimension dim )
{
AF_AxisHints axis = &hints->axis[dim];
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Memory memory = hints->memory;
AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
@@ -1070,7 +1099,7 @@
if ( dim == AF_DIMENSION_HORZ )
{
if ( laxis->width_count > 0 )
- segment_length_threshold = (laxis->standard_width * 10 ) >> 4;
+ segment_length_threshold = ( laxis->standard_width * 10 ) >> 4;
else
segment_length_threshold = FT_DivFix( 64, hints->y_scale );
}
@@ -1116,10 +1145,11 @@
{
FT_Pos dist = seg->serif->pos - seg->pos;
- if (dist < 0)
+
+ if ( dist < 0 )
dist = -dist;
- if (dist >= laxis->standard_width >> 1)
+ if ( dist >= laxis->standard_width >> 1 )
{
/* unlink this serif, it is too distant from its reference stem */
seg->serif = NULL;
@@ -1417,7 +1447,7 @@
compare = &blue->ref;
dist = edge->fpos - compare->org;
- if (dist < 0)
+ if ( dist < 0 )
dist = -dist;
dist = FT_MulFix( dist, scale );
@@ -1521,8 +1551,8 @@
* In `light' hinting mode we disable horizontal hinting completely.
* We also do it if the face is italic.
*/
- if ( mode == FT_RENDER_MODE_LIGHT ||
- (face->style_flags & FT_STYLE_FLAG_ITALIC) != 0 )
+ if ( mode == FT_RENDER_MODE_LIGHT ||
+ ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 )
scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
hints->scaler_flags = scaler_flags;
@@ -1603,8 +1633,8 @@
FT_Int sign = 0;
FT_Int vertical = ( dim == AF_DIMENSION_VERT );
+ FT_UNUSED( base_flags );
- FT_UNUSED(base_flags);
if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ||
axis->extra_light )
@@ -1734,7 +1764,7 @@
if ( delta < 0 )
delta = -delta;
- if (delta >= 16)
+ if ( delta >= 16 )
{
dist = org_dist;
if ( dist < 48 )
@@ -1788,7 +1818,7 @@
{
FT_UNUSED( hints );
- serif->pos = base->pos + (serif->opos - base->opos);
+ serif->pos = base->pos + ( serif->opos - base->opos );
}
@@ -1870,9 +1900,10 @@
{
anchor = edge;
- anchor_drift = (anchor->pos - anchor->opos);
- if (edge2)
- anchor_drift = (anchor_drift + (edge2->pos - edge2->opos)) >> 1;
+ anchor_drift = ( anchor->pos - anchor->opos );
+ if ( edge2 )
+ anchor_drift = ( anchor_drift +
+ ( edge2->pos - edge2->opos ) ) >> 1;
}
}
}
@@ -1964,8 +1995,8 @@
edge2->flags |= AF_EDGE_DONE;
- anchor_drift = ( (anchor->pos - anchor->opos) +
- (edge2->pos - edge2->opos)) >> 1;
+ anchor_drift = ( ( anchor->pos - anchor->opos ) +
+ ( edge2->pos - edge2->opos ) ) >> 1;
FT_TRACE5(( "DRIFT: %.2f\n", anchor_drift/64.0 ));
}
@@ -1984,8 +2015,8 @@
(AF_Edge_Flags)edge->flags,
(AF_Edge_Flags)edge2->flags );
- org_left = org_pos + ((org_len - cur_len) >> 1);
- org_right = org_pos + ((org_len + cur_len) >> 1);
+ org_left = org_pos + ( ( org_len - cur_len ) >> 1 );
+ org_right = org_pos + ( ( org_len + cur_len ) >> 1 );
FT_TRACE5(( "ALIGN: left=%.2f right=%.2f ",
org_left / 64.0, org_right / 64.0 ));
@@ -2013,13 +2044,13 @@
}
/* if the span is within a single pixel, don't touch it */
- if ( FT_PIX_FLOOR(org_left) == FT_PIX_CEIL(org_right) )
+ if ( FT_PIX_FLOOR( org_left ) == FT_PIX_CEIL( org_right ) )
{
FT_TRACE5(( "single pixel stem\n" ));
goto AlignStem;
}
- if (cur_len <= 96)
+ if ( cur_len <= 96 )
{
/* we want to avoid the absolute worst case which is
* when the left and right edges of the span each represent
@@ -2027,43 +2058,43 @@
* to 25/75%, since this is much more pleasant to the eye with
* very acceptable distortion
*/
- FT_Pos frac_left = (org_left) & 63;
- FT_Pos frac_right = (org_right) & 63;
+ FT_Pos frac_left = org_left & 63;
+ FT_Pos frac_right = org_right & 63;
if ( frac_left >= 22 && frac_left <= 42 &&
frac_right >= 22 && frac_right <= 42 )
{
org = frac_left;
- fit = (org <= 32) ? 16 : 48;
- delta = FT_ABS(fit - org);
+ fit = ( org <= 32 ) ? 16 : 48;
+ delta = FT_ABS( fit - org );
displacements[count] = fit - org;
scores[count++] = delta;
- FT_TRACE5(( "dispA=%.2f (%d) ", (fit - org) / 64.0, delta ));
+ FT_TRACE5(( "dispA=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
org = frac_right;
- fit = (org <= 32) ? 16 : 48;
- delta = FT_ABS(fit - org);
+ fit = ( org <= 32 ) ? 16 : 48;
+ delta = FT_ABS( fit - org );
displacements[count] = fit - org;
scores[count++] = delta;
- FT_TRACE5(( "dispB=%.2f (%d) ", (fit - org) / 64.0, delta ));
+ FT_TRACE5(( "dispB=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
}
}
/* snapping the left edge to the grid */
org = org_left;
- fit = FT_PIX_ROUND(org);
- delta = FT_ABS(fit - org);
+ fit = FT_PIX_ROUND( org );
+ delta = FT_ABS( fit - org );
displacements[count] = fit - org;
scores[count++] = delta;
- FT_TRACE5(( "dispC=%.2f (%d) ", (fit - org) / 64.0, delta ));
+ FT_TRACE5(( "dispC=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
/* snapping the right edge to the grid */
org = org_right;
- fit = FT_PIX_ROUND(org);
- delta = FT_ABS(fit - org);
+ fit = FT_PIX_ROUND( org );
+ delta = FT_ABS( fit - org );
displacements[count] = fit - org;
scores[count++] = delta;
- FT_TRACE5(( "dispD=%.2f (%d) ", (fit - org) / 64.0, delta ));
+ FT_TRACE5(( "dispD=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
/* now find the best displacement */
{
@@ -2071,9 +2102,9 @@
FT_Pos best_disp = displacements[0];
FT_UInt nn;
- for (nn = 1; nn < count; nn++)
+ for ( nn = 1; nn < count; nn++ )
{
- if (scores[nn] < best_score)
+ if ( scores[nn] < best_score )
{
best_score = scores[nn];
best_disp = displacements[nn];
@@ -2086,7 +2117,7 @@
}
AlignStem:
- edge->pos = cur_center - (cur_len >> 1);
+ edge->pos = cur_center - ( cur_len >> 1 );
edge2->pos = edge->pos + cur_len;
FT_TRACE5(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f)"
@@ -2359,6 +2390,7 @@
AF_DEFINE_SCRIPT_CLASS( af_latin2_script_class,
AF_SCRIPT_LATIN2,
af_latin2_uniranges,
+ 'o',
sizeof ( AF_LatinMetricsRec ),
diff --git a/src/autofit/aflatin2.h b/src/autofit/aflatin2.h
index 925c621..cbfa395 100644
--- a/src/autofit/aflatin2.h
+++ b/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/src/autofit/afloader.c b/src/autofit/afloader.c
index 34ef9d8..17a6fb7 100644
--- a/src/autofit/afloader.c
+++ b/src/autofit/afloader.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter glyph loading routines (body). */
/* */
-/* Copyright 2003-2009, 2011-2012 by */
+/* Copyright 2003-2009, 2011-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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 = FT_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;
@@ -104,9 +112,11 @@
AF_GlyphHints hints = &loader->hints;
FT_GlyphSlot slot = face->glyph;
FT_Slot_Internal internal = slot->internal;
+ FT_Int32 flags;
- error = FT_Load_Glyph( face, glyph_index, load_flags );
+ flags = load_flags | FT_LOAD_LINEAR_DESIGN;
+ error = FT_Load_Glyph( face, glyph_index, flags );
if ( error )
goto Exit;
@@ -124,10 +134,6 @@
FT_Vector_Transform( &loader->trans_delta, &inverse );
}
- /* set linear metrics */
- slot->linearHoriAdvance = slot->metrics.horiAdvance;
- slot->linearVertAdvance = slot->metrics.vertAdvance;
-
switch ( slot->format )
{
case FT_GLYPH_FORMAT_OUTLINE:
@@ -137,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 );
@@ -343,14 +349,14 @@
if ( start_point + k >= num_base_points ||
l >= (FT_UInt)num_new_points )
{
- error = AF_Err_Invalid_Composite;
+ error = FT_THROW( Invalid_Composite );
goto Exit;
}
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;
@@ -381,7 +387,7 @@
default:
/* we don't support other formats (yet?) */
- error = AF_Err_Unimplemented_Feature;
+ error = FT_THROW( Unimplemented_Feature );
}
Hint_Metrics:
@@ -484,18 +490,19 @@
/* 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;
if ( !size )
- return AF_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
FT_ZERO( &scaler );
@@ -508,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/src/autofit/afloader.h b/src/autofit/afloader.h
index eec0e92..1f34d17 100644
--- a/src/autofit/afloader.h
+++ b/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/src/autofit/afmodule.c b/src/autofit/afmodule.c
index 20b6218..b1bb5ee 100644
--- a/src/autofit/afmodule.c
+++ b/src/autofit/afmodule.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter module implementation (body). */
/* */
-/* Copyright 2003-2006, 2009, 2011 by */
+/* Copyright 2003-2006, 2009, 2011-2013 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,235 @@
#endif
#include FT_INTERNAL_OBJECTS_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 = FT_Err_Ok;
+ AF_FaceGlobals globals;
+
+
+ if ( !face )
+ return FT_THROW( 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 = FT_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_set: missing property `%s'\n",
+ property_name ));
+ return FT_THROW( 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 = FT_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;
+
+
+ error = af_property_get_face_globals( prop->face, &globals, module );
+ if ( !error )
+ prop->map = globals->glyph_scripts;
- } FT_AutofitterRec, *FT_Autofitter;
+ 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 FT_THROW( 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( FT_Module ft_module ) /* AF_Module */
{
- return af_loader_init( module->loader, module->root.library->memory );
+ AF_Module module = (AF_Module)ft_module;
+
+
+ module->fallback_script = AF_SCRIPT_FALLBACK;
+
+ return af_loader_init( module );
}
FT_CALLBACK_DEF( void )
- af_autofitter_done( FT_Autofitter module )
+ af_autofitter_done( FT_Module ft_module ) /* AF_Module */
{
- af_loader_done( module->loader );
+ AF_Module module = (AF_Module)ft_module;
+
+
+ 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/src/autofit/afmodule.h b/src/autofit/afmodule.h
index d979239..c4e8f8f 100644
--- a/src/autofit/afmodule.h
+++ b/src/autofit/afmodule.h
@@ -23,9 +23,30 @@
#include FT_INTERNAL_OBJECTS_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/src/autofit/afpic.c b/src/autofit/afpic.c
index 87074af..45e1448 100644
--- a/src/autofit/afpic.c
+++ b/src/autofit/afpic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for autofit module. */
/* */
-/* Copyright 2009, 2010, 2011 by */
+/* Copyright 2009-2013 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;
}
}
@@ -58,8 +80,8 @@
{
FT_PIC_Container* pic_container = &library->pic_container;
FT_UInt ss;
- FT_Error error = AF_Err_Ok;
- AFModulePIC* container;
+ FT_Error error = FT_Err_Ok;
+ 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/src/autofit/afpic.h b/src/autofit/afpic.h
index 21b0ff9..0acf803 100644
--- a/src/autofit/afpic.h
+++ b/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 FT_INTERNAL_PIC_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/src/autofit/aftypes.h b/src/autofit/aftypes.h
index 21e442c..9acd7ad 100644
--- a/src/autofit/aftypes.h
+++ b/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/src/base/basepic.c b/src/base/basepic.c
index d754eb1..0af770e 100644
--- a/src/base/basepic.c
+++ b/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 FT_INTERNAL_OBJECTS_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 );
+
+ void
+ FT_Init_Class_ft_bitmap_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 );
+#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,12 +69,13 @@
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 ) ) )
+ if ( FT_ALLOC( container, sizeof ( *container ) ) )
return error;
FT_MEM_SET( container, 0, sizeof ( *container ) );
pic_container->base = container;
@@ -72,21 +85,23 @@
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 )
+ Exit:
+ if ( error )
ft_base_pic_free( library );
return error;
}
-
#endif /* FT_CONFIG_OPTION_PIC */
diff --git a/src/base/basepic.h b/src/base/basepic.h
index bf90bef..329d7c8 100644
--- a/src/base/basepic.h
+++ b/src/base/basepic.h
@@ -25,11 +25,13 @@ FT_BEGIN_HEADER
#include FT_INTERNAL_PIC_H
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class
-#define FT_BITMAP_GLYPH_CLASS_GET &ft_bitmap_glyph_class
-#define FT_DEFAULT_MODULES_GET ft_default_modules
+
+#define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class
+#define FT_BITMAP_GLYPH_CLASS_GET &ft_bitmap_glyph_class
+#define FT_DEFAULT_MODULES_GET ft_default_modules
+
#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
-#define FT_RACCESS_GUESS_TABLE_GET ft_raccess_guess_table
+#define FT_RACCESS_GUESS_TABLE_GET ft_raccess_guess_table
#endif
#else /* FT_CONFIG_OPTION_PIC */
@@ -41,25 +43,35 @@ FT_BEGIN_HEADER
#endif
- typedef struct BasePIC_
+ typedef struct BasePIC_
{
- FT_Module_Class** default_module_classes;
- FT_Glyph_Class ft_outline_glyph_class;
- FT_Glyph_Class ft_bitmap_glyph_class;
+ FT_Module_Class** default_module_classes;
+ FT_Glyph_Class ft_outline_glyph_class;
+ FT_Glyph_Class ft_bitmap_glyph_class;
+
#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
- ft_raccess_guess_rec ft_raccess_guess_table[FT_RACCESS_N_RULES];
+ ft_raccess_guess_rec ft_raccess_guess_table[FT_RACCESS_N_RULES];
#endif
+
} BasePIC;
-#define GET_PIC(lib) ((BasePIC*)((lib)->pic_container.base))
-#define FT_OUTLINE_GLYPH_CLASS_GET (&GET_PIC(library)->ft_outline_glyph_class)
-#define FT_BITMAP_GLYPH_CLASS_GET (&GET_PIC(library)->ft_bitmap_glyph_class)
-#define FT_DEFAULT_MODULES_GET (GET_PIC(library)->default_module_classes)
+
+#define GET_PIC( lib ) ( (BasePIC*)( (lib)->pic_container.base ) )
+
+#define FT_OUTLINE_GLYPH_CLASS_GET \
+ ( &GET_PIC( library )->ft_outline_glyph_class )
+#define FT_BITMAP_GLYPH_CLASS_GET \
+ ( &GET_PIC( library )->ft_bitmap_glyph_class )
+#define FT_DEFAULT_MODULES_GET \
+ ( GET_PIC( library )->default_module_classes )
+
#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
-#define FT_RACCESS_GUESS_TABLE_GET (GET_PIC(library)->ft_raccess_guess_table)
+#define FT_RACCESS_GUESS_TABLE_GET \
+ ( GET_PIC( library )->ft_raccess_guess_table )
#endif
- /* see basepic.c for the implementation. */
+
+ /* see basepic.c for the implementation */
void
ft_base_pic_free( FT_Library library );
@@ -67,7 +79,8 @@ FT_BEGIN_HEADER
ft_base_pic_init( FT_Library library );
#endif /* FT_CONFIG_OPTION_PIC */
- /* */
+
+ /* */
FT_END_HEADER
diff --git a/src/base/ftadvanc.c b/src/base/ftadvanc.c
index a8bb43d..5207847 100644
--- a/src/base/ftadvanc.c
+++ b/src/base/ftadvanc.c
@@ -4,7 +4,7 @@
/* */
/* Quick computation of advance widths (body). */
/* */
-/* Copyright 2008, 2009, 2011 by */
+/* Copyright 2008, 2009, 2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,6 +17,8 @@
#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+
#include FT_ADVANCES_H
#include FT_INTERNAL_OBJECTS_H
@@ -35,7 +37,7 @@
return FT_Err_Ok;
if ( face->size == NULL )
- return FT_Err_Invalid_Size_Handle;
+ return FT_THROW( Invalid_Size_Handle );
if ( flags & FT_LOAD_VERTICAL_LAYOUT )
scale = face->size->metrics.y_scale;
@@ -76,10 +78,10 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( gindex >= (FT_UInt)face->num_glyphs )
- return FT_Err_Invalid_Glyph_Index;
+ return FT_THROW( Invalid_Glyph_Index );
func = face->driver->clazz->get_advances;
if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
@@ -91,7 +93,7 @@
if ( !error )
return _ft_face_scale_advances( face, padvance, 1, flags );
- if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )
+ if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
return error;
}
@@ -114,12 +116,12 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
num = (FT_UInt)face->num_glyphs;
end = start + count;
if ( start >= num || end < start || end > num )
- return FT_Err_Invalid_Glyph_Index;
+ return FT_THROW( Invalid_Glyph_Index );
if ( count == 0 )
return FT_Err_Ok;
@@ -131,14 +133,14 @@
if ( !error )
return _ft_face_scale_advances( face, padvances, count, flags );
- if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )
+ if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
return error;
}
error = FT_Err_Ok;
if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
for ( nn = 0; nn < count; nn++ )
diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c
index 4b8e911..6d1c44c 100644
--- a/src/base/ftbbox.c
+++ b/src/base/ftbbox.c
@@ -4,7 +4,7 @@
/* */
/* FreeType bbox computation (body). */
/* */
-/* Copyright 1996-2001, 2002, 2004, 2006, 2010 by */
+/* Copyright 1996-2002, 2004, 2006, 2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used */
@@ -25,6 +25,8 @@
#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+
#include FT_BBOX_H
#include FT_IMAGE_H
#include FT_OUTLINE_H
@@ -222,65 +224,100 @@
FT_Pos* min,
FT_Pos* max )
{
- FT_Pos stack[32*3 + 1], *arc;
-
+ FT_Pos q1, q2, q3, q4;
- arc = stack;
- arc[0] = p1;
- arc[1] = p2;
- arc[2] = p3;
- arc[3] = p4;
+ q1 = p1;
+ q2 = p2;
+ q3 = p3;
+ q4 = p4;
- do
+ /* for a conic segment to possibly reach new maximum */
+ /* one of its off-points must be above the current value */
+ while ( q2 > *max || q3 > *max )
{
- FT_Pos y1 = arc[0];
- FT_Pos y2 = arc[1];
- FT_Pos y3 = arc[2];
- FT_Pos y4 = arc[3];
-
-
- if ( y1 == y4 )
+ /* determine which half contains the maximum and split */
+ if ( q1 + q2 > q3 + q4 ) /* first half */
{
- if ( y1 == y2 && y1 == y3 ) /* flat */
- goto Test;
+ q4 = q4 + q3;
+ q3 = q3 + q2;
+ q2 = q2 + q1;
+ q4 = q4 + q3;
+ q3 = q3 + q2;
+ q4 = ( q4 + q3 ) / 8;
+ q3 = q3 / 4;
+ q2 = q2 / 2;
}
- else if ( y1 < y4 )
+ else /* second half */
{
- if ( y2 >= y1 && y2 <= y4 && y3 >= y1 && y3 <= y4 ) /* ascending */
- goto Test;
+ q1 = q1 + q2;
+ q2 = q2 + q3;
+ q3 = q3 + q4;
+ q1 = q1 + q2;
+ q2 = q2 + q3;
+ q1 = ( q1 + q2 ) / 8;
+ q2 = q2 / 4;
+ q3 = q3 / 2;
}
- else
+
+ /* check if either end reached the maximum */
+ if ( q1 == q2 && q1 >= q3 )
{
- if ( y2 >= y4 && y2 <= y1 && y3 >= y4 && y3 <= y1 ) /* descending */
- {
- y2 = y1;
- y1 = y4;
- y4 = y2;
- goto Test;
- }
+ *max = q1;
+ break;
}
+ if ( q3 == q4 && q2 <= q4 )
+ {
+ *max = q4;
+ break;
+ }
+ }
- /* unknown direction -- split the arc in two */
- arc[6] = y4;
- arc[1] = y1 = ( y1 + y2 ) / 2;
- arc[5] = y4 = ( y4 + y3 ) / 2;
- y2 = ( y2 + y3 ) / 2;
- arc[2] = y1 = ( y1 + y2 ) / 2;
- arc[4] = y4 = ( y4 + y2 ) / 2;
- arc[3] = ( y1 + y4 ) / 2;
-
- arc += 3;
- goto Suite;
+ q1 = p1;
+ q2 = p2;
+ q3 = p3;
+ q4 = p4;
- Test:
- if ( y1 < *min ) *min = y1;
- if ( y4 > *max ) *max = y4;
- arc -= 3;
+ /* for a conic segment to possibly reach new minimum */
+ /* one of its off-points must be below the current value */
+ while ( q2 < *min || q3 < *min )
+ {
+ /* determine which half contains the minimum and split */
+ if ( q1 + q2 < q3 + q4 ) /* first half */
+ {
+ q4 = q4 + q3;
+ q3 = q3 + q2;
+ q2 = q2 + q1;
+ q4 = q4 + q3;
+ q3 = q3 + q2;
+ q4 = ( q4 + q3 ) / 8;
+ q3 = q3 / 4;
+ q2 = q2 / 2;
+ }
+ else /* second half */
+ {
+ q1 = q1 + q2;
+ q2 = q2 + q3;
+ q3 = q3 + q4;
+ q1 = q1 + q2;
+ q2 = q2 + q3;
+ q1 = ( q1 + q2 ) / 8;
+ q2 = q2 / 4;
+ q3 = q3 / 2;
+ }
- Suite:
- ;
- } while ( arc >= stack );
+ /* check if either end reached the minimum */
+ if ( q1 == q2 && q1 <= q3 )
+ {
+ *min = q1;
+ break;
+ }
+ if ( q3 == q4 && q2 >= q4 )
+ {
+ *min = q4;
+ break;
+ }
+ }
}
#else
@@ -358,107 +395,57 @@
return;
}
- /* There are some split points. Find them. */
+ /* There are some split points. Find them. */
+ /* We already made sure that a, b, and c below cannot be all zero. */
{
FT_Pos a = y4 - 3*y3 + 3*y2 - y1;
FT_Pos b = y3 - 2*y2 + y1;
FT_Pos c = y2 - y1;
FT_Pos d;
FT_Fixed t;
+ FT_Int shift;
/* We need to solve `ax^2+2bx+c' here, without floating points! */
/* The trick is to normalize to a different representation in order */
- /* to use our 16.16 fixed point routines. */
+ /* to use our 16.16 fixed-point routines. */
/* */
/* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after normalization. */
/* These values must fit into a single 16.16 value. */
/* */
- /* We normalize a, b, and c to `8.16' fixed float values to ensure */
- /* that its product is held in a `16.16' value. */
+ /* We normalize a, b, and c to `8.16' fixed-point values to ensure */
+ /* that their product is held in a `16.16' value including the sign. */
+ /* Necessarily, we need to shift `a', `b', and `c' so that the most */
+ /* significant bit of their absolute values is at position 22. */
+ /* */
+ /* This also means that we are using 23 bits of precision to compute */
+ /* the zeros, independently of the range of the original polynomial */
+ /* coefficients. */
+ /* */
+ /* This algorithm should ensure reasonably accurate values for the */
+ /* zeros. Note that they are only expressed with 16 bits when */
+ /* computing the extrema (the zeros need to be in 0..1 exclusive */
+ /* to be considered part of the arc). */
- {
- FT_ULong t1, t2;
- int shift = 0;
-
-
- /* The following computation is based on the fact that for */
- /* any value `y', if `n' is the position of the most */
- /* significant bit of `abs(y)' (starting from 0 for the */
- /* least significant bit), then `y' is in the range */
- /* */
- /* -2^n..2^n-1 */
- /* */
- /* We want to shift `a', `b', and `c' concurrently in order */
- /* to ensure that they all fit in 8.16 values, which maps */
- /* to the integer range `-2^23..2^23-1'. */
- /* */
- /* Necessarily, we need to shift `a', `b', and `c' so that */
- /* the most significant bit of its absolute values is at */
- /* _most_ at position 23. */
- /* */
- /* We begin by computing `t1' as the bitwise `OR' of the */
- /* absolute values of `a', `b', `c'. */
-
- t1 = (FT_ULong)( ( a >= 0 ) ? a : -a );
- t2 = (FT_ULong)( ( b >= 0 ) ? b : -b );
- t1 |= t2;
- t2 = (FT_ULong)( ( c >= 0 ) ? c : -c );
- t1 |= t2;
-
- /* Now we can be sure that the most significant bit of `t1' */
- /* is the most significant bit of either `a', `b', or `c', */
- /* depending on the greatest integer range of the particular */
- /* variable. */
- /* */
- /* Next, we compute the `shift', by shifting `t1' as many */
- /* times as necessary to move its MSB to position 23. This */
- /* corresponds to a value of `t1' that is in the range */
- /* 0x40_0000..0x7F_FFFF. */
- /* */
- /* Finally, we shift `a', `b', and `c' by the same amount. */
- /* This ensures that all values are now in the range */
- /* -2^23..2^23, i.e., they are now expressed as 8.16 */
- /* fixed-float numbers. This also means that we are using */
- /* 24 bits of precision to compute the zeros, independently */
- /* of the range of the original polynomial coefficients. */
- /* */
- /* This algorithm should ensure reasonably accurate values */
- /* for the zeros. Note that they are only expressed with */
- /* 16 bits when computing the extrema (the zeros need to */
- /* be in 0..1 exclusive to be considered part of the arc). */
-
- if ( t1 == 0 ) /* all coefficients are 0! */
- return;
+ shift = FT_MSB( FT_ABS( a ) | FT_ABS( b ) | FT_ABS( c ) );
- if ( t1 > 0x7FFFFFUL )
- {
- do
- {
- shift++;
- t1 >>= 1;
-
- } while ( t1 > 0x7FFFFFUL );
-
- /* this loses some bits of precision, but we use 24 of them */
- /* for the computation anyway */
- a >>= shift;
- b >>= shift;
- c >>= shift;
- }
- else if ( t1 < 0x400000UL )
- {
- do
- {
- shift++;
- t1 <<= 1;
+ if ( shift > 22 )
+ {
+ shift -= 22;
- } while ( t1 < 0x400000UL );
+ /* this loses some bits of precision, but we use 23 of them */
+ /* for the computation anyway */
+ a >>= shift;
+ b >>= shift;
+ c >>= shift;
+ }
+ else
+ {
+ shift = 22 - shift;
- a <<= shift;
- b <<= shift;
- c <<= shift;
- }
+ a <<= shift;
+ b <<= shift;
+ c <<= shift;
}
/* handle a == 0 */
@@ -581,10 +568,10 @@ FT_DEFINE_OUTLINE_FUNCS(bbox_interface,
if ( !abbox )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( !outline )
- return FT_Err_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
/* if outline is empty, return (0,0,0,0) */
if ( outline->n_points == 0 || outline->n_contours <= 0 )
diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
index 84fa322..975818e 100644
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -4,7 +4,7 @@
/* */
/* FreeType utility functions for bitmaps (body). */
/* */
-/* Copyright 2004-2009, 2011 by */
+/* Copyright 2004-2009, 2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,6 +17,8 @@
#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+
#include FT_BITMAP_H
#include FT_IMAGE_H
#include FT_INTERNAL_OBJECTS_H
@@ -135,7 +137,7 @@
new_pitch = ( width + xpixels );
break;
default:
- return FT_Err_Invalid_Glyph_Format;
+ return FT_THROW( Invalid_Glyph_Format );
}
/* if no need to allocate memory */
@@ -223,14 +225,14 @@
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( !bitmap || !bitmap->buffer )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||
( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;
@@ -238,7 +240,7 @@
if ( xstr == 0 && ystr == 0 )
return FT_Err_Ok;
else if ( xstr < 0 || ystr < 0 )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
switch ( bitmap->pixel_mode )
{
@@ -277,6 +279,10 @@
case FT_PIXEL_MODE_LCD_V:
ystr *= 3;
break;
+
+ case FT_PIXEL_MODE_BGRA:
+ /* We don't embolden color glyphs. */
+ return FT_Err_Ok;
}
error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );
@@ -369,6 +375,59 @@
}
+ FT_Byte
+ ft_gray_for_premultiplied_srgb_bgra( const FT_Byte* bgra )
+ {
+ FT_Long a = bgra[3];
+ FT_Long b = bgra[0];
+ FT_Long g = bgra[1];
+ FT_Long r = bgra[2];
+ FT_Long l;
+
+
+ /*
+ * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722
+ * coefficients for RGB channels *on the linear colors*.
+ * A gamma of 2.2 is fair to assume. And then, we need to
+ * undo the premultiplication too.
+ *
+ * http://accessibility.kde.org/hsl-adjusted.php
+ *
+ * We do the computation with integers only.
+ */
+
+ /* Undo premultification, get the number in a 16.16 form. */
+ b = FT_MulDiv( b, 65536, a );
+ g = FT_MulDiv( g, 65536, a );
+ r = FT_MulDiv( r, 65536, a );
+ a = a * 256;
+
+ /* Apply gamma of 2.0 instead of 2.2. */
+ b = FT_MulFix( b, b );
+ g = FT_MulFix( g, g );
+ r = FT_MulFix( r, r );
+
+ /* Apply coefficients. */
+ b = FT_MulFix( b, 4731 /* 0.0722 * 65536 */ );
+ g = FT_MulFix( g, 46871 /* 0.7152 * 65536 */ );
+ r = FT_MulFix( r, 13933 /* 0.2126 * 65536 */ );
+
+ l = r + g + b;
+
+ /*
+ * Final transparency can be determined this way:
+ *
+ * - If alpha is zero, we want 0.
+ * - If alpha is zero and luminosity is zero, we want 255.
+ * - If alpha is zero and luminosity is one, we want 0.
+ *
+ * So the formula is a * (1 - l).
+ */
+
+ return (FT_Byte)( FT_MulFix( 65535 - l, a ) >> 8 );
+ }
+
+
/* documentation is in ftbitmap.h */
FT_EXPORT_DEF( FT_Error )
@@ -382,7 +441,7 @@
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
memory = library->memory;
@@ -394,6 +453,7 @@
case FT_PIXEL_MODE_GRAY4:
case FT_PIXEL_MODE_LCD:
case FT_PIXEL_MODE_LCD_V:
+ case FT_PIXEL_MODE_BGRA:
{
FT_Int pad;
FT_Long old_size;
@@ -419,7 +479,7 @@
if ( target->pitch > 0 &&
(FT_ULong)target->rows > FT_ULONG_MAX / target->pitch )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( target->rows * target->pitch > old_size &&
FT_QREALLOC( target->buffer,
@@ -429,7 +489,7 @@
break;
default:
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
}
switch ( source->pixel_mode )
@@ -606,6 +666,37 @@
}
break;
+ case FT_PIXEL_MODE_BGRA:
+ {
+ FT_Byte* s = source->buffer;
+ FT_Byte* t = target->buffer;
+ FT_Int s_pitch = source->pitch;
+ FT_Int t_pitch = target->pitch;
+ FT_Int i;
+
+
+ target->num_grays = 256;
+
+ for ( i = source->rows; i > 0; i-- )
+ {
+ FT_Byte* ss = s;
+ FT_Byte* tt = t;
+ FT_Int j;
+
+
+ for ( j = source->width; j > 0; j-- )
+ {
+ tt[0] = ft_gray_for_premultiplied_srgb_bgra( ss );
+
+ ss += 4;
+ tt += 1;
+ }
+
+ s += s_pitch;
+ t += t_pitch;
+ }
+ }
+ break;
default:
;
@@ -650,10 +741,10 @@
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( !bitmap )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
memory = library->memory;
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index 2aeea04..0ec0d78 100644
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -4,7 +4,7 @@
/* */
/* Arithmetic computations (body). */
/* */
-/* Copyright 1996-2006, 2008, 2012 by */
+/* Copyright 1996-2006, 2008, 2012-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -34,6 +34,7 @@
#include <ft2build.h>
#include FT_GLYPH_H
+#include FT_TRIGONOMETRY_H
#include FT_INTERNAL_CALC_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_OBJECTS_H
@@ -42,13 +43,9 @@
#undef FT_MulFix
#endif
-/* we need to define a 64-bits data type here */
+/* we need to emulate a 64-bit data type if a real one isn't available */
-#ifdef FT_LONG64
-
- typedef FT_INT64 FT_Int64;
-
-#else
+#ifndef FT_LONG64
typedef struct FT_Int64_
{
@@ -57,7 +54,7 @@
} FT_Int64;
-#endif /* FT_LONG64 */
+#endif /* !FT_LONG64 */
/*************************************************************************/
@@ -103,39 +100,57 @@
}
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
+ FT_BASE_DEF ( FT_Int )
+ FT_MSB( FT_UInt32 z )
+ {
+ FT_Int shift = 0;
- /* documentation is in ftcalc.h */
+ /* determine msb bit index in `shift' */
+ if ( z >= ( 1L << 16 ) )
+ {
+ z >>= 16;
+ shift += 16;
+ }
+ if ( z >= ( 1L << 8 ) )
+ {
+ z >>= 8;
+ shift += 8;
+ }
+ if ( z >= ( 1L << 4 ) )
+ {
+ z >>= 4;
+ shift += 4;
+ }
+ if ( z >= ( 1L << 2 ) )
+ {
+ z >>= 2;
+ shift += 2;
+ }
+ if ( z >= ( 1L << 1 ) )
+ {
+ z >>= 1;
+ shift += 1;
+ }
- FT_EXPORT_DEF( FT_Int32 )
- FT_Sqrt32( FT_Int32 x )
- {
- FT_UInt32 val, root, newroot, mask;
+ return shift;
+ }
- root = 0;
- mask = (FT_UInt32)0x40000000UL;
- val = (FT_UInt32)x;
+ /* documentation is in ftcalc.h */
- do
- {
- newroot = root + mask;
- if ( newroot <= val )
- {
- val -= newroot;
- root = newroot + mask;
- }
+ FT_BASE_DEF( FT_Fixed )
+ FT_Hypot( FT_Fixed x,
+ FT_Fixed y )
+ {
+ FT_Vector v;
- root >>= 1;
- mask >>= 2;
- } while ( mask != 0 );
+ v.x = x;
+ v.y = y;
- return root;
+ return FT_Vector_Length( &v );
}
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
#ifdef FT_LONG64
@@ -163,8 +178,6 @@
}
-#ifdef TT_USE_BYTECODE_INTERPRETER
-
/* documentation is in ftcalc.h */
FT_BASE_DEF( FT_Long )
@@ -187,8 +200,6 @@
return ( s > 0 ) ? d : -d;
}
-#endif /* TT_USE_BYTECODE_INTERPRETER */
-
/* documentation is in freetype.h */
@@ -235,16 +246,25 @@
FT_Int32 s;
FT_UInt32 q;
+
s = 1;
- if ( a < 0 ) { a = -a; s = -1; }
- if ( b < 0 ) { b = -b; s = -s; }
+ if ( a < 0 )
+ {
+ a = -a;
+ s = -1;
+ }
+ if ( b < 0 )
+ {
+ b = -b;
+ s = -s;
+ }
if ( b == 0 )
/* check for division by 0 */
q = 0x7FFFFFFFL;
else
/* compute result directly */
- q = (FT_UInt32)( ( ( (FT_Int64)a << 16 ) + ( b >> 1 ) ) / b );
+ q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b );
return ( s < 0 ? -(FT_Long)q : (FT_Long)q );
}
@@ -392,8 +412,6 @@
}
-#ifdef TT_USE_BYTECODE_INTERPRETER
-
FT_BASE_DEF( FT_Long )
FT_MulDiv_No_Round( FT_Long a,
FT_Long b,
@@ -426,8 +444,6 @@
return ( s < 0 ? -a : a );
}
-#endif /* TT_USE_BYTECODE_INTERPRETER */
-
/* documentation is in freetype.h */
@@ -552,7 +568,7 @@
else if ( ( a >> 16 ) == 0 )
{
/* compute result directly */
- q = (FT_UInt32)( ( a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b;
+ q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b;
}
else
{
@@ -560,8 +576,8 @@
FT_Int64 temp, temp2;
- temp.hi = (FT_Int32) ( a >> 16 );
- temp.lo = (FT_UInt32)( a << 16 );
+ temp.hi = (FT_Int32)( a >> 16 );
+ temp.lo = (FT_UInt32)a << 16;
temp2.hi = 0;
temp2.lo = (FT_UInt32)( b >> 1 );
FT_Add64( &temp, &temp2, &temp );
@@ -727,14 +743,14 @@
if ( !matrix )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* compute discriminant */
delta = FT_MulFix( matrix->xx, matrix->yy ) -
FT_MulFix( matrix->xy, matrix->yx );
if ( !delta )
- return FT_Err_Invalid_Argument; /* matrix can't be inverted */
+ return FT_THROW( Invalid_Argument ); /* matrix can't be inverted */
matrix->xy = - FT_DivFix( matrix->xy, delta );
matrix->yx = - FT_DivFix( matrix->yx, delta );
diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c
index 12fed04..6fb86fe 100644
--- a/src/base/ftdbgmem.c
+++ b/src/base/ftdbgmem.c
@@ -4,7 +4,7 @@
/* */
/* Memory debugger (body). */
/* */
-/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2009 by */
+/* Copyright 2001-2006, 2009, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -344,85 +344,80 @@
ft_mem_table_destroy( FT_MemTable table )
{
FT_ULong i;
+ FT_Long leak_count = 0;
+ FT_ULong leaks = 0;
FT_DumpMemory( table->memory );
- if ( table )
+ /* remove all blocks from the table, revealing leaked ones */
+ for ( i = 0; i < table->size; i++ )
{
- FT_Long leak_count = 0;
- FT_ULong leaks = 0;
+ FT_MemNode *pnode = table->buckets + i, next, node = *pnode;
- /* remove all blocks from the table, revealing leaked ones */
- for ( i = 0; i < table->size; i++ )
+ while ( node )
{
- FT_MemNode *pnode = table->buckets + i, next, node = *pnode;
+ next = node->link;
+ node->link = 0;
-
- while ( node )
+ if ( node->size > 0 )
{
- next = node->link;
- node->link = 0;
-
- if ( node->size > 0 )
- {
- printf(
- "leaked memory block at address %p, size %8ld in (%s:%ld)\n",
- node->address, node->size,
- FT_FILENAME( node->source->file_name ),
- node->source->line_no );
+ printf(
+ "leaked memory block at address %p, size %8ld in (%s:%ld)\n",
+ node->address, node->size,
+ FT_FILENAME( node->source->file_name ),
+ node->source->line_no );
- leak_count++;
- leaks += node->size;
+ leak_count++;
+ leaks += node->size;
- ft_mem_table_free( table, node->address );
- }
+ ft_mem_table_free( table, node->address );
+ }
- node->address = NULL;
- node->size = 0;
+ node->address = NULL;
+ node->size = 0;
- ft_mem_table_free( table, node );
- node = next;
- }
- table->buckets[i] = 0;
+ ft_mem_table_free( table, node );
+ node = next;
}
+ table->buckets[i] = 0;
+ }
- ft_mem_table_free( table, table->buckets );
- table->buckets = NULL;
-
- table->size = 0;
- table->nodes = 0;
+ ft_mem_table_free( table, table->buckets );
+ table->buckets = NULL;
- /* remove all sources */
- for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ )
- {
- FT_MemSource source, next;
+ table->size = 0;
+ table->nodes = 0;
+ /* remove all sources */
+ for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ )
+ {
+ FT_MemSource source, next;
- for ( source = table->sources[i]; source != NULL; source = next )
- {
- next = source->link;
- ft_mem_table_free( table, source );
- }
- table->sources[i] = NULL;
+ for ( source = table->sources[i]; source != NULL; source = next )
+ {
+ next = source->link;
+ ft_mem_table_free( table, source );
}
- printf(
- "FreeType: total memory allocations = %ld\n", table->alloc_total );
- printf(
- "FreeType: maximum memory footprint = %ld\n", table->alloc_max );
+ table->sources[i] = NULL;
+ }
- ft_mem_table_free( table, table );
+ printf( "FreeType: total memory allocations = %ld\n",
+ table->alloc_total );
+ printf( "FreeType: maximum memory footprint = %ld\n",
+ table->alloc_max );
- if ( leak_count > 0 )
- ft_mem_debug_panic(
- "FreeType: %ld bytes of memory leaked in %ld blocks\n",
- leaks, leak_count );
+ ft_mem_table_free( table, table );
- printf( "FreeType: no memory leaks detected\n" );
- }
+ if ( leak_count > 0 )
+ ft_mem_debug_panic(
+ "FreeType: %ld bytes of memory leaked in %ld blocks\n",
+ leaks, leak_count );
+
+ printf( "FreeType: no memory leaks detected\n" );
}
diff --git a/src/base/ftdebug.c b/src/base/ftdebug.c
index 2adbeab..b9156d1 100644
--- a/src/base/ftdebug.c
+++ b/src/base/ftdebug.c
@@ -4,7 +4,7 @@
/* */
/* Debugging and logging component (body). */
/* */
-/* Copyright 1996-2001, 2002, 2004, 2008 by */
+/* Copyright 1996-2001, 2002, 2004, 2008, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -51,7 +51,8 @@
/* documentation is in ftdebug.h */
FT_BASE_DEF( void )
- FT_Message( const char* fmt, ... )
+ FT_Message( const char* fmt,
+ ... )
{
va_list ap;
@@ -65,7 +66,8 @@
/* documentation is in ftdebug.h */
FT_BASE_DEF( void )
- FT_Panic( const char* fmt, ... )
+ FT_Panic( const char* fmt,
+ ... )
{
va_list ap;
@@ -77,6 +79,21 @@
exit( EXIT_FAILURE );
}
+
+ /* documentation is in ftdebug.h */
+
+ FT_BASE_DEF( int )
+ FT_Throw( FT_Error error,
+ int line,
+ const char* file )
+ {
+ FT_UNUSED( error );
+ FT_UNUSED( line );
+ FT_UNUSED( file );
+
+ return 0;
+ }
+
#endif /* FT_DEBUG_LEVEL_ERROR */
@@ -164,6 +181,9 @@
while ( *p && *p != ':' )
p++;
+ if ( !*p )
+ break;
+
if ( *p == ':' && p > q )
{
FT_Int n, i, len = (FT_Int)( p - q );
@@ -192,7 +212,7 @@
p++;
if ( *p )
{
- level = *p++ - '0';
+ level = *p - '0';
if ( level < 0 || level > 7 )
level = -1;
}
diff --git a/src/base/ftgloadr.c b/src/base/ftgloadr.c
index 8483450..663db26 100644
--- a/src/base/ftgloadr.c
+++ b/src/base/ftgloadr.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType glyph loader (body). */
/* */
-/* Copyright 2002, 2003, 2004, 2005, 2006, 2010 by */
+/* Copyright 2002-2006, 2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,6 +17,7 @@
#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_GLYPH_LOADER_H
#include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_OBJECTS_H
@@ -219,7 +220,7 @@
new_max = FT_PAD_CEIL( new_max, 8 );
if ( new_max > FT_OUTLINE_POINTS_MAX )
- return FT_Err_Array_Too_Large;
+ return FT_THROW( Array_Too_Large );
if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
FT_RENEW_ARRAY( base->tags, old_max, new_max ) )
@@ -251,7 +252,7 @@
new_max = FT_PAD_CEIL( new_max, 4 );
if ( new_max > FT_OUTLINE_CONTOURS_MAX )
- return FT_Err_Array_Too_Large;
+ return FT_THROW( Array_Too_Large );
if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
goto Exit;
@@ -318,7 +319,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/src/base/ftglyph.c b/src/base/ftglyph.c
index 591b57a..5dd28a8 100644
--- a/src/base/ftglyph.c
+++ b/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, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -29,6 +29,8 @@
#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+
#include FT_GLYPH_H
#include FT_OUTLINE_H
#include FT_BITMAP_H
@@ -65,7 +67,7 @@
if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
{
- error = FT_Err_Invalid_Glyph_Format;
+ error = FT_THROW( Invalid_Glyph_Format );
goto Exit;
}
@@ -166,7 +168,7 @@
/* check format in glyph slot */
if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
{
- error = FT_Err_Invalid_Glyph_Format;
+ error = FT_THROW( Invalid_Glyph_Format );
goto Exit;
}
@@ -314,7 +316,7 @@
/* check arguments */
if ( !target )
{
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -322,7 +324,7 @@
if ( !source || !source->clazz )
{
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -361,12 +363,12 @@
if ( !slot )
- return FT_Err_Invalid_Slot_Handle;
+ return FT_THROW( Invalid_Slot_Handle );
library = slot->library;
if ( !aglyph )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* if it is a bitmap, that's easy :-) */
if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
@@ -388,7 +390,7 @@
if ( !clazz )
{
- error = FT_Err_Invalid_Glyph_Format;
+ error = FT_THROW( Invalid_Glyph_Format );
goto Exit;
}
@@ -427,7 +429,7 @@
if ( !glyph || !glyph->clazz )
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
else
{
clazz = glyph->clazz;
@@ -441,7 +443,7 @@
FT_Vector_Transform( &glyph->advance, matrix );
}
else
- error = FT_Err_Invalid_Glyph_Format;
+ error = FT_THROW( Invalid_Glyph_Format );
}
return error;
}
@@ -510,7 +512,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 +549,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 */
@@ -600,7 +602,7 @@
return error;
Bad:
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
diff --git a/src/base/ftinit.c b/src/base/ftinit.c
index 91f8e2a..85f321f 100644
--- a/src/base/ftinit.c
+++ b/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, 2013 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;
@@ -166,7 +166,7 @@
pic_container->default_module_classes = 0;
- if ( FT_ALLOC( classes, sizeof ( FT_Module_Class* ) *
+ if ( FT_ALLOC( classes, sizeof ( FT_Module_Class* ) *
( FT_NUM_MODULE_CLASSES + 1 ) ) )
return error;
@@ -242,7 +242,7 @@
if ( !memory )
{
FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" ));
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
}
/* build a library out of it, then fill it with the set of */
diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c
index 0da4ba1..852fb32 100644
--- a/src/base/ftlcdfil.c
+++ b/src/base/ftlcdfil.c
@@ -4,7 +4,7 @@
/* */
/* FreeType API for color filtering of subpixel bitmap glyphs (body). */
/* */
-/* Copyright 2006, 2008, 2009, 2010 by */
+/* Copyright 2006, 2008-2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,6 +17,8 @@
#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+
#include FT_LCD_FILTER_H
#include FT_IMAGE_H
#include FT_INTERNAL_OBJECTS_H
@@ -271,7 +273,7 @@
unsigned char *weights )
{
if ( !library || !weights )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
ft_memcpy( library->lcd_weights, weights, 5 );
@@ -292,7 +294,7 @@
if ( !library )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
switch ( filter )
{
@@ -339,7 +341,7 @@
#endif
default:
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
library->lcd_filter = filter;
@@ -356,7 +358,7 @@
FT_UNUSED( library );
FT_UNUSED( weights );
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
}
@@ -367,7 +369,7 @@
FT_UNUSED( library );
FT_UNUSED( filter );
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
}
#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
diff --git a/src/base/ftmm.c b/src/base/ftmm.c
index 0307729..18ff879 100644
--- a/src/base/ftmm.c
+++ b/src/base/ftmm.c
@@ -4,7 +4,7 @@
/* */
/* Multiple Master font support (body). */
/* */
-/* Copyright 1996-2001, 2003, 2004, 2009 by */
+/* Copyright 1996-2001, 2003, 2004, 2009, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,6 +17,8 @@
#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+
#include FT_MULTIPLE_MASTERS_H
#include FT_INTERNAL_OBJECTS_H
#include FT_SERVICE_MULTIPLE_MASTERS_H
@@ -42,9 +44,9 @@
*aservice = NULL;
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
- error = FT_Err_Invalid_Argument;
+ error = FT_ERR( Invalid_Argument );
if ( FT_HAS_MULTIPLE_MASTERS( face ) )
{
@@ -73,7 +75,7 @@
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
- error = FT_Err_Invalid_Argument;
+ error = FT_ERR( Invalid_Argument );
if ( service->get_mm )
error = service->get_mm( face, amaster );
}
@@ -95,7 +97,7 @@
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
- error = FT_Err_Invalid_Argument;
+ error = FT_ERR( Invalid_Argument );
if ( service->get_mm_var )
error = service->get_mm_var( face, amaster );
}
@@ -118,7 +120,7 @@
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
- error = FT_Err_Invalid_Argument;
+ error = FT_ERR( Invalid_Argument );
if ( service->set_mm_design )
error = service->set_mm_design( face, num_coords, coords );
}
@@ -141,7 +143,7 @@
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
- error = FT_Err_Invalid_Argument;
+ error = FT_ERR( Invalid_Argument );
if ( service->set_var_design )
error = service->set_var_design( face, num_coords, coords );
}
@@ -164,7 +166,7 @@
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
- error = FT_Err_Invalid_Argument;
+ error = FT_ERR( Invalid_Argument );
if ( service->set_mm_blend )
error = service->set_mm_blend( face, num_coords, coords );
}
@@ -190,7 +192,7 @@
error = ft_face_get_mm_service( face, &service );
if ( !error )
{
- error = FT_Err_Invalid_Argument;
+ error = FT_ERR( Invalid_Argument );
if ( service->set_mm_blend )
error = service->set_mm_blend( face, num_coords, coords );
}
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 36ee797..ac2a39c 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType private base classes (body). */
/* */
-/* Copyright 1996-2012 by */
+/* Copyright 1996-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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
@@ -40,6 +41,32 @@
#include "ftbase.h"
#endif
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+#include FT_BITMAP_H
+
+#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
+ /* We disable the warning `conversion from XXX to YYY, */
+ /* possible loss of data' in order to compile cleanly with */
+ /* the maximum level of warnings: `md5.c' is non-FreeType */
+ /* code, and it gets used during development builds only. */
+#pragma warning( push )
+#pragma warning( disable : 4244 )
+#endif /* _MSC_VER */
+
+ /* it's easiest to include `md5.c' directly */
+#define free md5_free /* suppress a shadow warning */
+#include "md5.c"
+#undef free
+
+#if defined( _MSC_VER )
+#pragma warning( pop )
+#endif
+
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
+
#define GRID_FIT_METRICS
@@ -136,10 +163,10 @@
*astream = 0;
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( !args )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
memory = library->memory;
@@ -177,7 +204,7 @@
#endif
else
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
if ( error )
FT_FREE( stream );
@@ -384,7 +411,7 @@
if ( !face || !face->driver )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
driver = face->driver;
clazz = driver->clazz;
@@ -574,7 +601,7 @@
if ( !face || !face->size || !face->glyph )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
/* The validity test for `glyph_index' is performed by the */
/* font drivers. */
@@ -651,7 +678,7 @@
if ( autohint )
{
- FT_AutoHinter_Service hinting;
+ FT_AutoHinter_Interface hinting;
/* try to load embedded bitmaps first if available */
@@ -680,7 +707,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,
@@ -814,7 +841,7 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
glyph_index = (FT_UInt)char_code;
if ( face->charmap )
@@ -965,7 +992,7 @@
first = face->charmaps;
if ( !first )
- return FT_Err_Invalid_CharMap_Handle;
+ return FT_THROW( Invalid_CharMap_Handle );
/*
* The original TrueType specification(s) only specified charmap
@@ -1043,7 +1070,7 @@
}
}
- return FT_Err_Invalid_CharMap_Handle;
+ return FT_THROW( Invalid_CharMap_Handle );
}
@@ -1165,7 +1192,7 @@
/* is returned. */
/* no error should happen, but we want to play safe */
- if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle )
+ if ( error2 && FT_ERR_NEQ( error2, Invalid_CharMap_Handle ) )
{
error = error2;
goto Fail;
@@ -1206,7 +1233,7 @@
/* test for valid `library' and `aface' delayed to FT_Open_Face() */
if ( !pathname )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
args.flags = FT_OPEN_PATHNAME;
args.pathname = (char*)pathname;
@@ -1232,7 +1259,7 @@
/* test for valid `library' and `face' delayed to FT_Open_Face() */
if ( !file_base )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
args.flags = FT_OPEN_MEMORY;
args.memory_base = file_base;
@@ -1304,10 +1331,10 @@
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( !base )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
*astream = 0;
memory = library->memory;
@@ -1421,7 +1448,7 @@
if ( FT_READ_ULONG( tag ) )
return error;
if ( tag != TTAG_typ1 )
- return FT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
if ( FT_READ_USHORT( numTables ) )
return error;
@@ -1458,7 +1485,7 @@
if ( face_index >= 0 && pstable_index == face_index )
return FT_Err_Ok;
}
- return FT_Err_Table_Missing;
+ return FT_THROW( Table_Missing );
}
@@ -1504,7 +1531,7 @@
error = open_face_from_buffer( library,
sfnt_ps,
length,
- face_index < 0 ? face_index : 0,
+ FT_MIN( face_index, 0 ),
is_sfnt_cid ? "cid" : "type1",
aface );
Exit:
@@ -1512,7 +1539,7 @@
FT_Error error1;
- if ( error == FT_Err_Unknown_File_Format )
+ if ( FT_ERR_EQ( error, Unknown_File_Format ) )
{
error1 = FT_Stream_Seek( stream, pos );
if ( error1 )
@@ -1540,7 +1567,7 @@
FT_Long face_index,
FT_Face *aface )
{
- FT_Error error = FT_Err_Cannot_Open_Resource;
+ FT_Error error = FT_ERR( Cannot_Open_Resource );
FT_Memory memory = library->memory;
FT_Byte* pfb_data = NULL;
int i, type, flags;
@@ -1633,7 +1660,7 @@
pfb_data[pfb_pos++] = 0;
}
- error = FT_Err_Cannot_Open_Resource;
+ error = FT_ERR( Cannot_Open_Resource );
if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
goto Exit2;
@@ -1695,7 +1722,7 @@
if ( face_index == -1 )
face_index = 0;
if ( face_index >= resource_cnt )
- return FT_Err_Cannot_Open_Resource;
+ return FT_THROW( Cannot_Open_Resource );
flag_offset = offsets[face_index];
error = FT_Stream_Seek( stream, flag_offset );
@@ -1705,7 +1732,7 @@
if ( FT_READ_LONG( rlen ) )
goto Exit;
if ( rlen == -1 )
- return FT_Err_Cannot_Open_Resource;
+ return FT_THROW( Cannot_Open_Resource );
error = open_face_PS_from_sfnt_stream( library,
stream,
@@ -1812,7 +1839,7 @@
if ( NULL == stream )
- return FT_Err_Invalid_Stream_Operation;
+ return FT_THROW( Invalid_Stream_Operation );
error = FT_Stream_Seek( stream, 0 );
if ( error )
@@ -1829,7 +1856,7 @@
header[ 1] > 33 ||
header[63] != 0 ||
header[2 + header[1]] != 0 )
- return FT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
dlen = ( header[0x53] << 24 ) |
( header[0x54] << 16 ) |
@@ -1862,7 +1889,7 @@
#define FT_COMPONENT trace_raccess
FT_Memory memory = library->memory;
- FT_Error error = FT_Err_Unknown_File_Format;
+ FT_Error error = FT_ERR( Unknown_File_Format );
int i;
char * file_names[FT_RACCESS_N_RULES];
@@ -1901,7 +1928,7 @@
i, args2.pathname, offsets[i] ));
error = FT_Stream_New( library, &args2, &stream2 );
- if ( is_darwin_vfs && error == FT_Err_Cannot_Open_Stream )
+ if ( is_darwin_vfs && FT_ERR_EQ( error, Cannot_Open_Stream ) )
vfs_rfork_has_no_font = TRUE;
if ( error )
@@ -1930,7 +1957,7 @@
/* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */
if ( error )
- error = FT_Err_Unknown_File_Format;
+ error = FT_ERR( Unknown_File_Format );
return error;
@@ -1959,7 +1986,7 @@
error = IsMacBinary( library, stream, face_index, aface );
- if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format )
+ if ( FT_ERR_EQ( error, Unknown_File_Format ) )
{
#undef FT_COMPONENT
@@ -1976,9 +2003,9 @@
}
- if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format ||
- FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) &&
- ( args->flags & FT_OPEN_PATHNAME ) )
+ if ( ( FT_ERR_EQ( error, Unknown_File_Format ) ||
+ FT_ERR_EQ( error, Invalid_Stream_Operation ) ) &&
+ ( args->flags & FT_OPEN_PATHNAME ) )
error = load_face_in_embedded_rfork( library, stream,
face_index, aface, args );
return error;
@@ -2011,7 +2038,7 @@
/* FT_Stream_New() */
if ( ( !aface && face_index >= 0 ) || !args )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&
args->stream );
@@ -2048,18 +2075,19 @@
goto Success;
}
else
- error = FT_Err_Invalid_Handle;
+ error = FT_THROW( Invalid_Handle );
FT_Stream_Free( stream, external_stream );
goto Fail;
}
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... */
@@ -2084,7 +2112,7 @@
#ifdef FT_CONFIG_OPTION_MAC_FONTS
if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
- FT_ERROR_BASE( error ) == FT_Err_Table_Missing )
+ FT_ERR_EQ( error, Table_Missing ) )
{
/* TrueType but essential tables are missing */
if ( FT_Stream_Seek( stream, 0 ) )
@@ -2104,39 +2132,39 @@
}
#endif
- if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
+ if ( FT_ERR_NEQ( error, Unknown_File_Format ) )
goto Fail3;
}
}
- 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_ERR_NEQ( error, Cannot_Open_Stream ) &&
+ FT_ERR_NEQ( error, Unknown_File_Format ) &&
+ FT_ERR_NEQ( error, 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_ERR_NEQ( error, Unknown_File_Format ) )
+ goto Fail2;
#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
/* no driver is able to handle this format */
- error = FT_Err_Unknown_File_Format;
+ error = FT_THROW( Unknown_File_Format );
Fail2:
FT_Stream_Free( stream, external_stream );
@@ -2258,7 +2286,7 @@
/* test for valid `face' delayed to FT_Attach_Stream() */
if ( !filepathname )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
open.stream = NULL;
open.flags = FT_OPEN_PATHNAME;
@@ -2284,11 +2312,11 @@
/* test for valid `parameters' delayed to FT_Stream_New() */
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
driver = face->driver;
if ( !driver )
- return FT_Err_Invalid_Driver_Handle;
+ return FT_THROW( Invalid_Driver_Handle );
error = FT_Stream_New( driver->root.library, parameters, &stream );
if ( error )
@@ -2297,7 +2325,7 @@
/* we implement FT_Attach_Stream in each driver through the */
/* `attach_file' interface */
- error = FT_Err_Unimplemented_Feature;
+ error = FT_ERR( Unimplemented_Feature );
clazz = driver->clazz;
if ( clazz->attach_file )
error = clazz->attach_file( face, stream );
@@ -2334,7 +2362,7 @@
FT_ListNode node;
- error = FT_Err_Invalid_Face_Handle;
+ error = FT_ERR( Invalid_Face_Handle );
if ( face && face->driver )
{
face->internal->refcount--;
@@ -2380,13 +2408,13 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( !asize )
- return FT_Err_Invalid_Size_Handle;
+ return FT_THROW( Invalid_Size_Handle );
if ( !face->driver )
- return FT_Err_Invalid_Driver_Handle;
+ return FT_THROW( Invalid_Driver_Handle );
*asize = 0;
@@ -2438,15 +2466,15 @@
if ( !size )
- return FT_Err_Invalid_Size_Handle;
+ return FT_THROW( Invalid_Size_Handle );
face = size->face;
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
driver = face->driver;
if ( !driver )
- return FT_Err_Invalid_Driver_Handle;
+ return FT_THROW( Invalid_Driver_Handle );
memory = driver->root.memory;
@@ -2467,7 +2495,7 @@
destroy_size( memory, size, driver );
}
else
- error = FT_Err_Invalid_Size_Handle;
+ error = FT_THROW( Invalid_Size_Handle );
return error;
}
@@ -2486,11 +2514,11 @@
if ( !FT_HAS_FIXED_SIZES( face ) )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
/* FT_Bitmap_Size doesn't provide enough info... */
if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
w = FT_REQUEST_WIDTH ( req );
h = FT_REQUEST_HEIGHT( req );
@@ -2513,6 +2541,8 @@
if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width )
{
+ FT_TRACE3(( "FT_Match_Size: bitmap strike %d matches\n", i ));
+
if ( size_index )
*size_index = (FT_ULong)i;
@@ -2520,7 +2550,7 @@
}
}
- return FT_Err_Invalid_Pixel_Size;
+ return FT_THROW( Invalid_Pixel_Size );
}
@@ -2763,10 +2793,10 @@
if ( !face || !FT_HAS_FIXED_SIZES( face ) )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( strike_index < 0 || strike_index >= face->num_fixed_sizes )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
clazz = face->driver->clazz;
@@ -2816,11 +2846,11 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( !req || req->width < 0 || req->height < 0 ||
req->type >= FT_SIZE_REQUEST_TYPE_MAX )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
clazz = face->driver->clazz;
@@ -2869,9 +2899,6 @@
if ( error )
return error;
- FT_TRACE3(( "FT_Request_Size: bitmap strike %lu matched\n",
- strike_index ));
-
return FT_Select_Size( face, (FT_Int)strike_index );
}
@@ -2971,10 +2998,10 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( !akerning )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
driver = face->driver;
@@ -3030,14 +3057,14 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( !akerning )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
FT_FACE_FIND_SERVICE( face, service, KERNING );
if ( !service )
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
error = service->get_track( face,
point_size,
@@ -3059,10 +3086,10 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( encoding == FT_ENCODING_NONE )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */
/* charmap available, i.e., one with UCS-4 characters, if possible. */
@@ -3073,7 +3100,7 @@
cur = face->charmaps;
if ( !cur )
- return FT_Err_Invalid_CharMap_Handle;
+ return FT_THROW( Invalid_CharMap_Handle );
limit = cur + face->num_charmaps;
@@ -3095,7 +3122,7 @@
}
}
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
@@ -3110,13 +3137,13 @@
if ( !face )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
cur = face->charmaps;
if ( !cur )
- return FT_Err_Invalid_CharMap_Handle;
+ return FT_THROW( Invalid_CharMap_Handle );
if ( FT_Get_CMap_Format( charmap ) == 14 )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
limit = cur + face->num_charmaps;
@@ -3137,7 +3164,7 @@
return 0;
}
}
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
@@ -3176,7 +3203,7 @@
{
FT_CMap_Class clazz = cmap->clazz;
FT_Face face = cmap->charmap.face;
- FT_Memory memory = FT_FACE_MEMORY(face);
+ FT_Memory memory = FT_FACE_MEMORY( face );
if ( clazz->done )
@@ -3245,7 +3272,7 @@
if ( clazz == NULL || charmap == NULL || charmap->face == NULL )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
face = charmap->face;
memory = FT_FACE_MEMORY( face );
@@ -3578,7 +3605,7 @@
FT_Pointer buffer,
FT_UInt buffer_max )
{
- FT_Error error = FT_Err_Invalid_Argument;
+ FT_Error error = FT_ERR( Invalid_Argument );
/* clean up buffer */
@@ -3667,11 +3694,11 @@
if ( !face || !FT_IS_SFNT( face ) )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
if ( service == NULL )
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
return service->load_table( face, tag, offset, buffer, length );
}
@@ -3690,11 +3717,11 @@
if ( !face || !FT_IS_SFNT( face ) )
- return FT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
if ( service == NULL )
- return FT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
return service->table_info( face, table_index, tag, &offset, length );
}
@@ -3757,11 +3784,11 @@
if ( size == NULL )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
face = size->face;
if ( face == NULL || face->driver == NULL )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* we don't need anything more complex than that; all size objects */
/* are already listed by the face */
@@ -3953,15 +3980,15 @@
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( !renderer )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
node = FT_List_Find( &library->renderers, renderer );
if ( !node )
{
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -4019,12 +4046,12 @@
else
renderer = FT_Lookup_Renderer( library, slot->format, &node );
- error = FT_Err_Unimplemented_Feature;
+ error = FT_ERR( Unimplemented_Feature );
while ( renderer )
{
error = renderer->render( renderer, slot, render_mode, NULL );
- if ( !error ||
- FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph )
+ if ( !error ||
+ FT_ERR_NEQ( error, Cannot_Render_Glyph ) )
break;
/* FT_Err_Cannot_Render_Glyph is returned if the render mode */
@@ -4044,6 +4071,47 @@
}
}
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_bitmap
+
+ /* we convert to a single bitmap format for computing the checksum */
+ {
+ FT_Bitmap bitmap;
+ FT_Error err;
+
+
+ FT_Bitmap_New( &bitmap );
+
+ err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 );
+ if ( !err )
+ {
+ MD5_CTX ctx;
+ unsigned char md5[16];
+ int i;
+
+
+ MD5_Init( &ctx);
+ MD5_Update( &ctx, bitmap.buffer, bitmap.rows * bitmap.pitch );
+ MD5_Final( md5, &ctx );
+
+ FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n"
+ " ",
+ bitmap.rows, bitmap.pitch ));
+ for ( i = 0; i < 16; i++ )
+ FT_TRACE3(( "%02X", md5[i] ));
+ FT_TRACE3(( "\n" ));
+ }
+
+ FT_Bitmap_Done( library, &bitmap );
+ }
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_objs
+
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
return error;
}
@@ -4058,7 +4126,7 @@
if ( !slot || !slot->face )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
library = FT_FACE_LIBRARY( slot->face );
@@ -4138,14 +4206,14 @@
FREETYPE_MINOR )
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( !clazz )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* check freetype version */
if ( clazz->module_requires > FREETYPE_VER_FIXED )
- return FT_Err_Invalid_Version;
+ return FT_THROW( Invalid_Version );
/* look for a module with the same name in the library's table */
for ( nn = 0; nn < library->num_modules; nn++ )
@@ -4155,7 +4223,7 @@
{
/* this installed module has the same name, compare their versions */
if ( clazz->module_version <= module->clazz->module_version )
- return FT_Err_Lower_Module_Version;
+ return FT_THROW( Lower_Module_Version );
/* remove the module from our list, then exit the loop to replace */
/* it by our new version.. */
@@ -4169,7 +4237,7 @@
if ( library->num_modules >= FT_MAX_MODULES )
{
- error = FT_Err_Too_Many_Drivers;
+ error = FT_THROW( Too_Many_Drivers );
goto Exit;
}
@@ -4301,19 +4369,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;
@@ -4349,7 +4416,7 @@
/* try to find the module from the table, then remove it from there */
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( module )
{
@@ -4378,7 +4445,119 @@
}
}
}
- return FT_Err_Invalid_Driver_Handle;
+ return FT_THROW( Invalid_Driver_Handle );
+ }
+
+
+ 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_THROW( Invalid_Library_Handle );
+
+ if ( !module_name || !property_name || !value )
+ return FT_THROW( 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_THROW( 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_THROW( 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_THROW( 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_THROW( 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_EXPORT_DEF( 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_EXPORT_DEF( 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 );
}
@@ -4417,7 +4596,7 @@
if ( !memory )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
#ifdef FT_DEBUG_LEVEL_ERROR
/* init debugging support */
@@ -4504,7 +4683,7 @@
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
library->refcount--;
if ( library->refcount > 0 )
@@ -4651,70 +4830,6 @@
}
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- FT_BASE_DEF( FT_Error )
- ft_stub_set_char_sizes( FT_Size size,
- FT_F26Dot6 width,
- FT_F26Dot6 height,
- FT_UInt horz_res,
- FT_UInt vert_res )
- {
- FT_Size_RequestRec req;
- FT_Driver driver = size->face->driver;
-
-
- if ( driver->clazz->request_size )
- {
- req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
- req.width = width;
- req.height = height;
-
- if ( horz_res == 0 )
- horz_res = vert_res;
-
- if ( vert_res == 0 )
- vert_res = horz_res;
-
- if ( horz_res == 0 )
- horz_res = vert_res = 72;
-
- req.horiResolution = horz_res;
- req.vertResolution = vert_res;
-
- return driver->clazz->request_size( size, &req );
- }
-
- return 0;
- }
-
-
- FT_BASE_DEF( FT_Error )
- ft_stub_set_pixel_sizes( FT_Size size,
- FT_UInt width,
- FT_UInt height )
- {
- FT_Size_RequestRec req;
- FT_Driver driver = size->face->driver;
-
-
- if ( driver->clazz->request_size )
- {
- req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
- req.width = width << 6;
- req.height = height << 6;
- req.horiResolution = 0;
- req.vertResolution = 0;
-
- return driver->clazz->request_size( size, &req );
- }
-
- return 0;
- }
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Error )
@@ -4726,7 +4841,7 @@
FT_Int *p_arg2,
FT_Matrix *p_transform )
{
- FT_Error error = FT_Err_Invalid_Argument;
+ FT_Error error = FT_ERR( Invalid_Argument );
if ( glyph &&
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index 9ae276d..54ca5cd 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -4,7 +4,7 @@
/* */
/* FreeType outline management (body). */
/* */
-/* Copyright 1996-2008, 2010, 2012 by */
+/* Copyright 1996-2008, 2010, 2012-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -26,6 +26,7 @@
#include <ft2build.h>
#include FT_OUTLINE_H
#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_CALC_H
#include FT_INTERNAL_DEBUG_H
#include FT_TRIGONOMETRY_H
@@ -73,7 +74,7 @@
if ( !outline || !func_interface )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
shift = func_interface->shift;
delta = func_interface->delta;
@@ -286,7 +287,7 @@
return error;
Invalid_Outline:
- return FT_Err_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
}
@@ -300,10 +301,17 @@
if ( !anoutline || !memory )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
*anoutline = null_outline;
+ if ( numContours < 0 ||
+ (FT_UInt)numContours > numPoints )
+ return FT_THROW( Invalid_Argument );
+
+ if ( numPoints > FT_OUTLINE_POINTS_MAX )
+ return FT_THROW( Array_Too_Large );
+
if ( FT_NEW_ARRAY( anoutline->points, numPoints ) ||
FT_NEW_ARRAY( anoutline->tags, numPoints ) ||
FT_NEW_ARRAY( anoutline->contours, numContours ) )
@@ -332,7 +340,7 @@
FT_Outline *anoutline )
{
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
return FT_Outline_New_Internal( library->memory, numPoints,
numContours, anoutline );
@@ -380,7 +388,7 @@
}
Bad:
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
@@ -396,7 +404,7 @@
if ( !source || !target ||
source->n_points != target->n_points ||
source->n_contours != target->n_contours )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( source == target )
return FT_Err_Ok;
@@ -435,7 +443,7 @@
return FT_Err_Ok;
}
else
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
@@ -448,7 +456,7 @@
/* check for valid `outline' in FT_Outline_Done_Internal() */
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
return FT_Outline_Done_Internal( library->memory, outline );
}
@@ -602,21 +610,21 @@
if ( !library )
- return FT_Err_Invalid_Library_Handle;
+ return FT_THROW( Invalid_Library_Handle );
if ( !outline || !params )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
renderer = library->cur_renderer;
node = library->renderers.head;
params->source = (void*)outline;
- error = FT_Err_Cannot_Render_Glyph;
+ error = FT_ERR( Cannot_Render_Glyph );
while ( renderer )
{
error = renderer->raster_render( renderer->raster, params );
- if ( !error || FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph )
+ if ( !error || FT_ERR_NEQ( error, Cannot_Render_Glyph ) )
break;
/* FT_Err_Cannot_Render_Glyph is returned if the render mode */
@@ -650,7 +658,7 @@
if ( !abitmap )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* other checks are delayed to FT_Outline_Render() */
@@ -882,85 +890,126 @@
FT_Outline_Embolden( FT_Outline* outline,
FT_Pos strength )
{
+ return FT_Outline_EmboldenXY( outline, strength, strength );
+ }
+
+
+ /* documentation is in ftoutln.h */
+
+ FT_EXPORT_DEF( FT_Error )
+ FT_Outline_EmboldenXY( FT_Outline* outline,
+ FT_Pos xstrength,
+ FT_Pos ystrength )
+ {
FT_Vector* points;
FT_Vector v_prev, v_first, v_next, v_cur;
- FT_Angle rotate, angle_in, angle_out;
FT_Int c, n, first;
FT_Int orientation;
if ( !outline )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
- strength /= 2;
- if ( strength == 0 )
+ xstrength /= 2;
+ ystrength /= 2;
+ if ( xstrength == 0 && ystrength == 0 )
return FT_Err_Ok;
orientation = FT_Outline_Get_Orientation( outline );
if ( orientation == FT_ORIENTATION_NONE )
{
if ( outline->n_contours )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
else
return FT_Err_Ok;
}
- if ( orientation == FT_ORIENTATION_TRUETYPE )
- rotate = -FT_ANGLE_PI2;
- else
- rotate = FT_ANGLE_PI2;
-
points = outline->points;
first = 0;
for ( c = 0; c < outline->n_contours; c++ )
{
- int last = outline->contours[c];
+ FT_Vector in, out, shift;
+ FT_Fixed l_in, l_out, l, q, d;
+ int last = outline->contours[c];
v_first = points[first];
v_prev = points[last];
v_cur = v_first;
- for ( n = first; n <= last; n++ )
+ /* compute incoming normalized vector */
+ in.x = v_cur.x - v_prev.x;
+ in.y = v_cur.y - v_prev.y;
+ l_in = FT_Vector_Length( &in );
+ if ( l_in )
{
- FT_Vector in, out;
- FT_Angle angle_diff;
- FT_Pos d;
- FT_Fixed scale;
-
+ in.x = FT_DivFix( in.x, l_in );
+ in.y = FT_DivFix( in.y, l_in );
+ }
+ for ( n = first; n <= last; n++ )
+ {
if ( n < last )
v_next = points[n + 1];
else
v_next = v_first;
- /* compute the in and out vectors */
- in.x = v_cur.x - v_prev.x;
- in.y = v_cur.y - v_prev.y;
-
+ /* compute outgoing normalized vector */
out.x = v_next.x - v_cur.x;
out.y = v_next.y - v_cur.y;
+ l_out = FT_Vector_Length( &out );
+ if ( l_out )
+ {
+ out.x = FT_DivFix( out.x, l_out );
+ out.y = FT_DivFix( out.y, l_out );
+ }
- angle_in = FT_Atan2( in.x, in.y );
- angle_out = FT_Atan2( out.x, out.y );
- angle_diff = FT_Angle_Diff( angle_in, angle_out );
- scale = FT_Cos( angle_diff / 2 );
+ d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y );
- if ( scale < 0x4000L && scale > -0x4000L )
- in.x = in.y = 0;
- else
+ /* shift only if turn is less than ~160 degrees */
+ if ( d > -0xF000L )
{
- d = FT_DivFix( strength, scale );
+ d = d + 0x10000L;
- FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate );
+ /* shift components are aligned along lateral bisector */
+ /* and directed according to the outline orientation. */
+ shift.x = in.y + out.y;
+ shift.y = in.x + out.x;
+
+ if ( orientation == FT_ORIENTATION_TRUETYPE )
+ shift.x = -shift.x;
+ else
+ shift.y = -shift.y;
+
+ /* restrict shift magnitude to better handle collapsing segments */
+ q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x );
+ if ( orientation == FT_ORIENTATION_TRUETYPE )
+ q = -q;
+
+ l = FT_MIN( l_in, l_out );
+
+ /* non-strict inequalities avoid divide-by-zero when q == l == 0 */
+ if ( FT_MulFix( xstrength, q ) <= FT_MulFix( d, l ) )
+ shift.x = FT_MulDiv( shift.x, xstrength, d );
+ else
+ shift.x = FT_MulDiv( shift.x, l, q );
+
+
+ if ( FT_MulFix( ystrength, q ) <= FT_MulFix( d, l ) )
+ shift.y = FT_MulDiv( shift.y, ystrength, d );
+ else
+ shift.y = FT_MulDiv( shift.y, l, q );
}
+ else
+ shift.x = shift.y = 0;
- outline->points[n].x = v_cur.x + strength + in.x;
- outline->points[n].y = v_cur.y + strength + in.y;
+ outline->points[n].x = v_cur.x + xstrength + shift.x;
+ outline->points[n].y = v_cur.y + ystrength + shift.y;
- v_prev = v_cur;
- v_cur = v_next;
+ in = out;
+ l_in = l_out;
+ v_cur = v_next;
}
first = last + 1;
@@ -975,23 +1024,12 @@
FT_EXPORT_DEF( FT_Orientation )
FT_Outline_Get_Orientation( FT_Outline* outline )
{
- FT_Pos xmin = 32768L;
- FT_Pos xmin_ymin = 32768L;
- FT_Pos xmin_ymax = -32768L;
- FT_Vector* xmin_first = NULL;
- FT_Vector* xmin_last = NULL;
-
- short* contour;
-
- FT_Vector* first;
- FT_Vector* last;
- FT_Vector* prev;
- FT_Vector* point;
-
- int i;
- FT_Pos ray_y[3];
- FT_Orientation result[3] =
- { FT_ORIENTATION_NONE, FT_ORIENTATION_NONE, FT_ORIENTATION_NONE };
+ FT_BBox cbox;
+ FT_Int xshift, yshift;
+ FT_Vector* points;
+ FT_Vector v_prev, v_cur;
+ FT_Int c, n, first;
+ FT_Pos area = 0;
if ( !outline || outline->n_points <= 0 )
@@ -1002,127 +1040,41 @@
/* cubic or quadratic curves, this test deals with the polygon */
/* only which is spanned up by the control points. */
- first = outline->points;
- for ( contour = outline->contours;
- contour < outline->contours + outline->n_contours;
- contour++, first = last + 1 )
- {
- FT_Pos contour_xmin = 32768L;
- FT_Pos contour_xmax = -32768L;
- FT_Pos contour_ymin = 32768L;
- FT_Pos contour_ymax = -32768L;
-
-
- last = outline->points + *contour;
+ FT_Outline_Get_CBox( outline, &cbox );
- /* skip degenerate contours */
- if ( last < first + 2 )
- continue;
-
- for ( point = first; point <= last; ++point )
- {
- if ( point->x < contour_xmin )
- contour_xmin = point->x;
-
- if ( point->x > contour_xmax )
- contour_xmax = point->x;
-
- if ( point->y < contour_ymin )
- contour_ymin = point->y;
-
- if ( point->y > contour_ymax )
- contour_ymax = point->y;
- }
-
- if ( contour_xmin < xmin &&
- contour_xmin != contour_xmax &&
- contour_ymin != contour_ymax )
- {
- xmin = contour_xmin;
- xmin_ymin = contour_ymin;
- xmin_ymax = contour_ymax;
- xmin_first = first;
- xmin_last = last;
- }
- }
+ xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14;
+ xshift = FT_MAX( xshift, 0 );
- if ( xmin == 32768L )
- return FT_ORIENTATION_TRUETYPE;
+ yshift = FT_MSB( cbox.yMax - cbox.yMin ) - 14;
+ yshift = FT_MAX( yshift, 0 );
- ray_y[0] = ( xmin_ymin * 3 + xmin_ymax ) >> 2;
- ray_y[1] = ( xmin_ymin + xmin_ymax ) >> 1;
- ray_y[2] = ( xmin_ymin + xmin_ymax * 3 ) >> 2;
+ points = outline->points;
- for ( i = 0; i < 3; i++ )
+ first = 0;
+ for ( c = 0; c < outline->n_contours; c++ )
{
- FT_Pos left_x;
- FT_Pos right_x;
- FT_Vector* left1;
- FT_Vector* left2;
- FT_Vector* right1;
- FT_Vector* right2;
-
+ FT_Int last = outline->contours[c];
- RedoRay:
- left_x = 32768L;
- right_x = -32768L;
- left1 = left2 = right1 = right2 = NULL;
+ v_prev = points[last];
- prev = xmin_last;
- for ( point = xmin_first; point <= xmin_last; prev = point, ++point )
+ for ( n = first; n <= last; n++ )
{
- FT_Pos tmp_x;
-
-
- if ( point->y == ray_y[i] || prev->y == ray_y[i] )
- {
- ray_y[i]++;
- goto RedoRay;
- }
-
- if ( ( point->y < ray_y[i] && prev->y < ray_y[i] ) ||
- ( point->y > ray_y[i] && prev->y > ray_y[i] ) )
- continue;
-
- tmp_x = FT_MulDiv( point->x - prev->x,
- ray_y[i] - prev->y,
- point->y - prev->y ) + prev->x;
-
- if ( tmp_x < left_x )
- {
- left_x = tmp_x;
- left1 = prev;
- left2 = point;
- }
-
- if ( tmp_x > right_x )
- {
- right_x = tmp_x;
- right1 = prev;
- right2 = point;
- }
+ v_cur = points[n];
+ area += ( ( v_cur.y - v_prev.y ) >> yshift ) *
+ ( ( v_cur.x + v_prev.x ) >> xshift );
+ v_prev = v_cur;
}
- if ( left1 && right1 )
- {
- if ( left1->y < left2->y && right1->y > right2->y )
- result[i] = FT_ORIENTATION_TRUETYPE;
- else if ( left1->y > left2->y && right1->y < right2->y )
- result[i] = FT_ORIENTATION_POSTSCRIPT;
- else
- result[i] = FT_ORIENTATION_NONE;
- }
+ first = last + 1;
}
- if ( result[0] != FT_ORIENTATION_NONE &&
- ( result[0] == result[1] || result[0] == result[2] ) )
- return result[0];
-
- if ( result[1] != FT_ORIENTATION_NONE && result[1] == result[2] )
- return result[1];
-
- return FT_ORIENTATION_TRUETYPE;
+ if ( area > 0 )
+ return FT_ORIENTATION_POSTSCRIPT;
+ else if ( area < 0 )
+ return FT_ORIENTATION_TRUETYPE;
+ else
+ return FT_ORIENTATION_NONE;
}
diff --git a/src/base/ftpic.c b/src/base/ftpic.c
index b74e90d..1c87101 100644
--- a/src/base/ftpic.c
+++ b/src/base/ftpic.c
@@ -29,7 +29,8 @@
ft_pic_container_init( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Error error = FT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
+
FT_MEM_SET( pic_container, 0, sizeof ( *pic_container ) );
diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c
index 01d8625..8049117 100644
--- a/src/base/ftrfork.c
+++ b/src/base/ftrfork.c
@@ -4,7 +4,7 @@
/* */
/* Embedded resource forks accessor (body). */
/* */
-/* Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010 by */
+/* Copyright 2004-2010, 2013 by */
/* Masatake YAMATO and Redhat K.K. */
/* */
/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */
@@ -86,7 +86,7 @@
/* map_len = head[12] .. head[15] */
if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset )
- return FT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
error = FT_Stream_Seek( stream, map_pos );
if ( error )
@@ -108,7 +108,7 @@
allmatch = 0;
}
if ( !allzeros && !allmatch )
- return FT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
/* If we have reached this point then it is probably a mac resource */
/* file. Now, does it contain any interesting resources? */
@@ -121,7 +121,7 @@
if ( FT_READ_USHORT( type_list ) )
return error;
if ( type_list == -1 )
- return FT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
error = FT_Stream_Seek( stream, map_pos + type_list );
if ( error )
@@ -233,7 +233,7 @@
}
}
- return FT_Err_Cannot_Open_Resource;
+ return FT_THROW( Cannot_Open_Resource );
}
@@ -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++ )
@@ -435,7 +435,7 @@
*result_file_name = NULL;
if ( NULL == stream )
- return FT_Err_Cannot_Open_Stream;
+ return FT_THROW( Cannot_Open_Stream );
return raccess_guess_apple_generic( library, stream, base_file_name,
magic, result_offset );
@@ -457,7 +457,7 @@
*result_file_name = NULL;
if ( NULL == stream )
- return FT_Err_Cannot_Open_Stream;
+ return FT_THROW( Cannot_Open_Stream );
return raccess_guess_apple_generic( library, stream, base_file_name,
magic, result_offset );
@@ -481,7 +481,7 @@
memory = library->memory;
newpath = raccess_make_file_name( memory, base_file_name, "._" );
if ( !newpath )
- return FT_Err_Out_Of_Memory;
+ return FT_THROW( Out_Of_Memory );
error = raccess_guess_linux_double_from_file_name( library, newpath,
result_offset );
@@ -507,7 +507,7 @@
FT_Error error;
char* newpath = NULL;
FT_Memory memory;
- FT_Long base_file_len = ft_strlen( base_file_name );
+ FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name );
FT_UNUSED( stream );
@@ -515,7 +515,7 @@
memory = library->memory;
if ( base_file_len + 6 > FT_INT_MAX )
- return FT_Err_Array_Too_Large;
+ return FT_THROW( Array_Too_Large );
if ( FT_ALLOC( newpath, base_file_len + 6 ) )
return error;
@@ -543,7 +543,7 @@
FT_Error error;
char* newpath = NULL;
FT_Memory memory;
- FT_Long base_file_len = ft_strlen( base_file_name );
+ FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name );
FT_UNUSED( stream );
@@ -551,7 +551,7 @@
memory = library->memory;
if ( base_file_len + 18 > FT_INT_MAX )
- return FT_Err_Array_Too_Large;
+ return FT_THROW( Array_Too_Large );
if ( FT_ALLOC( newpath, base_file_len + 18 ) )
return error;
@@ -584,7 +584,7 @@
newpath = raccess_make_file_name( memory, base_file_name,
"resource.frk/" );
if ( !newpath )
- return FT_Err_Out_Of_Memory;
+ return FT_THROW( Out_Of_Memory );
*result_file_name = newpath;
*result_offset = 0;
@@ -610,7 +610,7 @@
newpath = raccess_make_file_name( memory, base_file_name, ".resource/" );
if ( !newpath )
- return FT_Err_Out_Of_Memory;
+ return FT_THROW( Out_Of_Memory );
*result_file_name = newpath;
*result_offset = 0;
@@ -637,7 +637,7 @@
newpath = raccess_make_file_name( memory, base_file_name, "%" );
if ( !newpath )
- return FT_Err_Out_Of_Memory;
+ return FT_THROW( Out_Of_Memory );
error = raccess_guess_linux_double_from_file_name( library, newpath,
result_offset );
@@ -669,7 +669,7 @@
newpath = raccess_make_file_name( memory, base_file_name,
".AppleDouble/" );
if ( !newpath )
- return FT_Err_Out_Of_Memory;
+ return FT_THROW( Out_Of_Memory );
error = raccess_guess_linux_double_from_file_name( library, newpath,
result_offset );
@@ -708,7 +708,7 @@
if ( FT_READ_LONG( magic_from_stream ) )
return error;
if ( magic_from_stream != magic )
- return FT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
if ( FT_READ_LONG( version_number ) )
return error;
@@ -721,7 +721,7 @@
if ( FT_READ_USHORT( n_of_entries ) )
return error;
if ( n_of_entries == 0 )
- return FT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
for ( i = 0; i < n_of_entries; i++ )
{
@@ -744,7 +744,7 @@
}
}
- return FT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
}
@@ -827,7 +827,7 @@
FT_Long *offsets,
FT_Error *errors )
{
- int i;
+ FT_Int i;
FT_UNUSED( library );
FT_UNUSED( stream );
@@ -838,7 +838,7 @@
{
new_names[i] = NULL;
offsets[i] = 0;
- errors[i] = FT_Err_Unimplemented_Feature;
+ errors[i] = FT_ERR( Unimplemented_Feature );
}
}
diff --git a/src/base/ftsnames.c b/src/base/ftsnames.c
index 3447888..260e91c 100644
--- a/src/base/ftsnames.c
+++ b/src/base/ftsnames.c
@@ -44,7 +44,7 @@
FT_UInt idx,
FT_SfntName *aname )
{
- FT_Error error = FT_Err_Invalid_Argument;
+ FT_Error error = FT_ERR( Invalid_Argument );
if ( aname && face && FT_IS_SFNT( face ) )
diff --git a/src/base/ftstream.c b/src/base/ftstream.c
index fc2868e..d965333 100644
--- a/src/base/ftstream.c
+++ b/src/base/ftstream.c
@@ -4,7 +4,7 @@
/* */
/* I/O stream support (body). */
/* */
-/* Copyright 2000-2002, 2004-2006, 2008-2011 by */
+/* Copyright 2000-2002, 2004-2006, 2008-2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -68,7 +68,7 @@
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
pos, stream->size ));
- error = FT_Err_Invalid_Stream_Operation;
+ error = FT_THROW( Invalid_Stream_Operation );
}
}
/* note that seeking to the first position after the file is valid */
@@ -78,7 +78,7 @@
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
pos, stream->size ));
- error = FT_Err_Invalid_Stream_Operation;
+ error = FT_THROW( Invalid_Stream_Operation );
}
if ( !error )
@@ -93,7 +93,7 @@
FT_Long distance )
{
if ( distance < 0 )
- return FT_Err_Invalid_Stream_Operation;
+ return FT_THROW( Invalid_Stream_Operation );
return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) );
}
@@ -131,7 +131,7 @@
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
pos, stream->size ));
- return FT_Err_Invalid_Stream_Operation;
+ return FT_THROW( Invalid_Stream_Operation );
}
if ( stream->read )
@@ -153,7 +153,7 @@
" invalid read; expected %lu bytes, got %lu\n",
count, read_bytes ));
- error = FT_Err_Invalid_Stream_Operation;
+ error = FT_THROW( Invalid_Stream_Operation );
}
return error;
@@ -254,7 +254,7 @@
" frame size (%lu) larger than stream size (%lu)\n",
count, stream->size ));
- error = FT_Err_Invalid_Stream_Operation;
+ error = FT_THROW( Invalid_Stream_Operation );
goto Exit;
}
@@ -277,7 +277,7 @@
count, read_bytes ));
FT_FREE( stream->base );
- error = FT_Err_Invalid_Stream_Operation;
+ error = FT_THROW( Invalid_Stream_Operation );
}
stream->cursor = stream->base;
stream->limit = stream->cursor + count;
@@ -293,7 +293,7 @@
" invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
stream->pos, count, stream->size ));
- error = FT_Err_Invalid_Stream_Operation;
+ error = FT_THROW( Invalid_Stream_Operation );
goto Exit;
}
@@ -474,7 +474,7 @@
return result;
Fail:
- *error = FT_Err_Invalid_Stream_Operation;
+ *error = FT_THROW( Invalid_Stream_Operation );
FT_ERROR(( "FT_Stream_ReadChar:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
@@ -521,7 +521,7 @@
return result;
Fail:
- *error = FT_Err_Invalid_Stream_Operation;
+ *error = FT_THROW( Invalid_Stream_Operation );
FT_ERROR(( "FT_Stream_ReadUShort:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
@@ -568,7 +568,7 @@
return result;
Fail:
- *error = FT_Err_Invalid_Stream_Operation;
+ *error = FT_THROW( Invalid_Stream_Operation );
FT_ERROR(( "FT_Stream_ReadUShortLE:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
@@ -615,7 +615,7 @@
return result;
Fail:
- *error = FT_Err_Invalid_Stream_Operation;
+ *error = FT_THROW( Invalid_Stream_Operation );
FT_ERROR(( "FT_Stream_ReadUOffset:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
@@ -662,7 +662,7 @@
return result;
Fail:
- *error = FT_Err_Invalid_Stream_Operation;
+ *error = FT_THROW( Invalid_Stream_Operation );
FT_ERROR(( "FT_Stream_ReadULong:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
@@ -709,7 +709,7 @@
return result;
Fail:
- *error = FT_Err_Invalid_Stream_Operation;
+ *error = FT_THROW( Invalid_Stream_Operation );
FT_ERROR(( "FT_Stream_ReadULongLE:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
@@ -727,8 +727,9 @@
FT_Bool frame_accessed = 0;
FT_Byte* cursor;
+
if ( !fields || !stream )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
cursor = stream->cursor;
@@ -760,7 +761,7 @@
if ( cursor + len > stream->limit )
{
- error = FT_Err_Invalid_Stream_Operation;
+ error = FT_THROW( Invalid_Stream_Operation );
goto Exit;
}
@@ -776,43 +777,43 @@
case ft_frame_byte:
case ft_frame_schar: /* read a single byte */
- value = FT_NEXT_BYTE(cursor);
+ value = FT_NEXT_BYTE( cursor );
sign_shift = 24;
break;
case ft_frame_short_be:
case ft_frame_ushort_be: /* read a 2-byte big-endian short */
- value = FT_NEXT_USHORT(cursor);
+ value = FT_NEXT_USHORT( cursor) ;
sign_shift = 16;
break;
case ft_frame_short_le:
case ft_frame_ushort_le: /* read a 2-byte little-endian short */
- value = FT_NEXT_USHORT_LE(cursor);
+ value = FT_NEXT_USHORT_LE( cursor );
sign_shift = 16;
break;
case ft_frame_long_be:
case ft_frame_ulong_be: /* read a 4-byte big-endian long */
- value = FT_NEXT_ULONG(cursor);
+ value = FT_NEXT_ULONG( cursor );
sign_shift = 0;
break;
case ft_frame_long_le:
case ft_frame_ulong_le: /* read a 4-byte little-endian long */
- value = FT_NEXT_ULONG_LE(cursor);
+ value = FT_NEXT_ULONG_LE( cursor );
sign_shift = 0;
break;
case ft_frame_off3_be:
case ft_frame_uoff3_be: /* read a 3-byte big-endian long */
- value = FT_NEXT_UOFF3(cursor);
+ value = FT_NEXT_UOFF3( cursor );
sign_shift = 8;
break;
case ft_frame_off3_le:
case ft_frame_uoff3_le: /* read a 3-byte little-endian long */
- value = FT_NEXT_UOFF3_LE(cursor);
+ value = FT_NEXT_UOFF3_LE( cursor );
sign_shift = 8;
break;
@@ -831,15 +832,15 @@
p = (FT_Byte*)structure + fields->offset;
switch ( fields->size )
{
- case (8 / FT_CHAR_BIT):
+ case ( 8 / FT_CHAR_BIT ):
*(FT_Byte*)p = (FT_Byte)value;
break;
- case (16 / FT_CHAR_BIT):
+ case ( 16 / FT_CHAR_BIT ):
*(FT_UShort*)p = (FT_UShort)value;
break;
- case (32 / FT_CHAR_BIT):
+ case ( 32 / FT_CHAR_BIT ):
*(FT_UInt32*)p = (FT_UInt32)value;
break;
diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c
index 5399efe..ee61cec 100644
--- a/src/base/ftstroke.c
+++ b/src/base/ftstroke.c
@@ -4,7 +4,7 @@
/* */
/* FreeType path stroker (body). */
/* */
-/* Copyright 2002-2006, 2008-2011 by */
+/* Copyright 2002-2006, 2008-2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -789,13 +789,13 @@
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;
if ( !library )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
memory = library->memory;
@@ -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;
@@ -1955,7 +1954,7 @@
if ( !stroker || border > 1 )
{
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -2061,7 +2060,7 @@
if ( !outline || !stroker )
- return FT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
FT_Stroker_Rewind( stroker );
@@ -2239,7 +2238,7 @@
return error;
Invalid_Outline:
- return FT_Err_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
}
@@ -2259,7 +2258,7 @@
FT_Stroker stroker,
FT_Bool destroy )
{
- FT_Error error = FT_Err_Invalid_Argument;
+ FT_Error error = FT_ERR( Invalid_Argument );
FT_Glyph glyph = NULL;
FT_Library library = stroker->library;
@@ -2335,7 +2334,7 @@
FT_Bool inside,
FT_Bool destroy )
{
- FT_Error error = FT_Err_Invalid_Argument;
+ FT_Error error = FT_ERR( Invalid_Argument );
FT_Glyph glyph = NULL;
FT_Library library = stroker->library;
diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c
index d4ec0da..241d37f 100644
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -4,7 +4,7 @@
/* */
/* FreeType synthesizing code for emboldening and slanting (body). */
/* */
-/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2010 by */
+/* Copyright 2000-2006, 2010, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -33,6 +33,7 @@
#undef FT_COMPONENT
#define FT_COMPONENT trace_synth
+
/*************************************************************************/
/*************************************************************************/
/**** ****/
@@ -62,7 +63,7 @@
transform.xx = 0x10000L;
transform.yx = 0x00000L;
- transform.xy = 0x06000L;
+ transform.xy = 0x0366AL;
transform.yy = 0x10000L;
FT_Outline_Transform( outline, &transform );
@@ -72,7 +73,7 @@
/*************************************************************************/
/*************************************************************************/
/**** ****/
- /**** EXPERIMENTAL EMBOLDENING/OUTLINING SUPPORT ****/
+ /**** EXPERIMENTAL EMBOLDENING SUPPORT ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
@@ -101,12 +102,7 @@
if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
{
/* ignore error */
- (void)FT_Outline_Embolden( &slot->outline, xstr );
-
- /* this is more than enough for most glyphs; if you need accurate */
- /* values, you have to call FT_Outline_Get_CBox */
- xstr = xstr * 2;
- ystr = xstr;
+ (void)FT_Outline_EmboldenXY( &slot->outline, xstr, ystr );
}
else /* slot->format == FT_GLYPH_FORMAT_BITMAP */
{
@@ -143,13 +139,10 @@
if ( slot->advance.y )
slot->advance.y += ystr;
- slot->metrics.width += xstr;
- slot->metrics.height += ystr;
- slot->metrics.horiBearingY += ystr;
- slot->metrics.horiAdvance += xstr;
- slot->metrics.vertBearingX -= xstr / 2;
- slot->metrics.vertBearingY += ystr;
- slot->metrics.vertAdvance += ystr;
+ slot->metrics.width += xstr;
+ slot->metrics.height += ystr;
+ slot->metrics.horiAdvance += xstr;
+ slot->metrics.vertAdvance += ystr;
/* XXX: 16-bit overflow case must be excluded before here */
if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
diff --git a/src/base/ftsystem.c b/src/base/ftsystem.c
index 7e203be..2c6ddac 100644
--- a/src/base/ftsystem.c
+++ b/src/base/ftsystem.c
@@ -4,7 +4,7 @@
/* */
/* ANSI-specific FreeType low-level system interface (body). */
/* */
-/* Copyright 1996-2002, 2006, 2008-2011 by */
+/* Copyright 1996-2002, 2006, 2008-2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -228,7 +228,7 @@
if ( !stream )
- return FT_Err_Invalid_Stream_Handle;
+ return FT_THROW( Invalid_Stream_Handle );
stream->descriptor.pointer = NULL;
stream->pathname.pointer = (char*)filepathname;
@@ -243,7 +243,7 @@
FT_ERROR(( "FT_Stream_Open:"
" could not open `%s'\n", filepathname ));
- return FT_Err_Cannot_Open_Resource;
+ return FT_THROW( Cannot_Open_Resource );
}
ft_fseek( file, 0, SEEK_END );
@@ -253,7 +253,7 @@
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " opened `%s' but zero-sized\n", filepathname ));
ft_fclose( file );
- return FT_Err_Cannot_Open_Stream;
+ return FT_THROW( Cannot_Open_Stream );
}
ft_fseek( file, 0, SEEK_SET );
diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c
index fdf433a..4ffdcb7 100644
--- a/src/base/fttrigon.c
+++ b/src/base/fttrigon.c
@@ -4,7 +4,7 @@
/* */
/* FreeType trigonometric functions (body). */
/* */
-/* Copyright 2001, 2002, 2003, 2004, 2005 by */
+/* Copyright 2001-2005, 2012-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -15,31 +15,46 @@
/* */
/***************************************************************************/
+ /*************************************************************************/
+ /* */
+ /* This is a fixed-point CORDIC implementation of trigonometric */
+ /* functions as well as transformations between Cartesian and polar */
+ /* coordinates. The angles are represented as 16.16 fixed-point values */
+ /* in degrees, i.e., the angular resolution is 2^-16 degrees. Note that */
+ /* only vectors longer than 2^16*180/pi (or at least 22 bits) on a */
+ /* discrete Cartesian grid can have the same or better angular */
+ /* resolution. Therefore, to maintain this precision, some functions */
+ /* require an interim upscaling of the vectors, whereas others operate */
+ /* with 24-bit long vectors directly. */
+ /* */
+ /*************************************************************************/
#include <ft2build.h>
#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_CALC_H
#include FT_TRIGONOMETRY_H
- /* the following is 0.2715717684432231 * 2^30 */
-#define FT_TRIG_COSCALE 0x11616E8EUL
+ /* the Cordic shrink factor 0.858785336480436 * 2^32 */
+#define FT_TRIG_SCALE 0xDBD95B16UL
+
+ /* the highest bit in overflow-safe vector components, */
+ /* MSB of 0.858785336480436 * sqrt(0.5) * 2^30 */
+#define FT_TRIG_SAFE_MSB 29
/* 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[] =
{
- 4157273L, 2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L,
- 58666L, 29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,
+ 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
@@ -50,7 +65,7 @@
s = val;
- val = ( val >= 0 ) ? val : -val;
+ val = FT_ABS( val );
v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL;
val = (FT_Fixed)( v >> 32 );
@@ -58,7 +73,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
@@ -69,19 +84,19 @@
s = val;
- val = ( val >= 0 ) ? val : -val;
+ val = FT_ABS( 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 */
lo2 = ( k2 * v2 ) >> 16;
- lo3 = ( lo1 >= lo2 ) ? lo1 : lo2;
+ lo3 = FT_MAX( lo1, lo2 );
lo1 += lo2;
hi += lo1 >> 16;
@@ -93,91 +108,35 @@
return ( s >= 0 ) ? val : -val;
}
-#endif /* !FT_CONFIG_HAS_INT64 */
+#endif /* !FT_LONG64 */
static FT_Int
ft_trig_prenorm( FT_Vector* vec )
{
- FT_Fixed x, y, z;
- FT_Int shift;
+ FT_Pos x, y;
+ FT_Int shift;
x = vec->x;
y = vec->y;
- z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
- shift = 0;
+ shift = FT_MSB( FT_ABS( x ) | FT_ABS( y ) );
-#if 1
- /* determine msb bit index in `shift' */
- if ( z >= ( 1L << 16 ) )
- {
- z >>= 16;
- shift += 16;
- }
- if ( z >= ( 1L << 8 ) )
- {
- z >>= 8;
- shift += 8;
- }
- if ( z >= ( 1L << 4 ) )
- {
- z >>= 4;
- shift += 4;
- }
- if ( z >= ( 1L << 2 ) )
+ if ( shift <= FT_TRIG_SAFE_MSB )
{
- z >>= 2;
- shift += 2;
- }
- if ( z >= ( 1L << 1 ) )
- {
- z >>= 1;
- shift += 1;
- }
-
- if ( shift <= 27 )
- {
- shift = 27 - shift;
- vec->x = x << shift;
- vec->y = y << shift;
+ shift = FT_TRIG_SAFE_MSB - shift;
+ vec->x = (FT_Pos)( (FT_ULong)x << shift );
+ vec->y = (FT_Pos)( (FT_ULong)y << shift );
}
else
{
- shift -= 27;
- vec->x = x >> shift;
- vec->y = y >> shift;
- shift = -shift;
- }
-
-#else /* 0 */
-
- if ( z < ( 1L << 27 ) )
- {
- do
- {
- shift++;
- z <<= 1;
- } while ( z < ( 1L << 27 ) );
- vec->x = x << shift;
- vec->y = y << shift;
- }
- else if ( z > ( 1L << 28 ) )
- {
- do
- {
- shift++;
- z >>= 1;
- } while ( z > ( 1L << 28 ) );
-
+ shift -= FT_TRIG_SAFE_MSB;
vec->x = x >> shift;
vec->y = y >> shift;
shift = -shift;
}
-#endif /* 0 */
-
return shift;
}
@@ -187,65 +146,50 @@
FT_Angle theta )
{
FT_Int i;
- FT_Fixed x, y, xtemp;
+ FT_Fixed x, y, xtemp, b;
const FT_Fixed *arctanptr;
x = vec->x;
y = vec->y;
- /* Get angle between -90 and 90 degrees */
- while ( theta <= -FT_ANGLE_PI2 )
+ /* Rotate inside [-PI/4,PI/4] sector */
+ while ( theta < -FT_ANGLE_PI4 )
{
- x = -x;
- y = -y;
- theta += FT_ANGLE_PI;
+ xtemp = y;
+ y = -x;
+ x = xtemp;
+ theta += FT_ANGLE_PI2;
}
- while ( theta > FT_ANGLE_PI2 )
+ while ( theta > FT_ANGLE_PI4 )
{
- x = -x;
- y = -y;
- theta -= FT_ANGLE_PI;
+ xtemp = -y;
+ y = x;
+ x = xtemp;
+ theta -= FT_ANGLE_PI2;
}
- /* 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 */
- i = 0;
- do
+ /* Pseudorotations, with right shifts */
+ for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ )
{
if ( theta < 0 )
{
- xtemp = x + ( y >> i );
- y = y - ( x >> i );
+ xtemp = x + ( ( y + b ) >> i );
+ y = y - ( ( x + b ) >> i );
x = xtemp;
theta += *arctanptr++;
}
else
{
- xtemp = x - ( y >> i );
- y = y + ( x >> i );
+ xtemp = x - ( ( y + b ) >> i );
+ y = y + ( ( x + b ) >> i );
x = xtemp;
theta -= *arctanptr++;
}
- } while ( ++i < FT_TRIG_MAX_ITERS );
+ }
vec->x = x;
vec->y = y;
@@ -255,66 +199,67 @@
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, b;
const FT_Fixed *arctanptr;
x = vec->x;
y = vec->y;
- /* Get the vector into the right half plane */
- theta = 0;
- if ( x < 0 )
+ /* Get the vector into [-PI/4,PI/4] sector */
+ if ( y > x )
{
- x = -x;
- y = -y;
- theta = 2 * FT_ANGLE_PI2;
- }
-
- if ( y > 0 )
- theta = - theta;
-
- arctanptr = ft_trig_arctan_table;
-
- if ( y < 0 )
- {
- /* Rotate positive */
- yi = y + ( x << 1 );
- x = x - ( y << 1 );
- y = yi;
- theta -= *arctanptr++; /* Subtract angle */
+ if ( y > -x )
+ {
+ theta = FT_ANGLE_PI2;
+ xtemp = y;
+ y = -x;
+ x = xtemp;
+ }
+ else
+ {
+ theta = y > 0 ? FT_ANGLE_PI : -FT_ANGLE_PI;
+ x = -x;
+ y = -y;
+ }
}
else
{
- /* Rotate negative */
- yi = y - ( x << 1 );
- x = x + ( y << 1 );
- y = yi;
- theta += *arctanptr++; /* Add angle */
+ if ( y < -x )
+ {
+ theta = -FT_ANGLE_PI2;
+ xtemp = -y;
+ y = x;
+ x = xtemp;
+ }
+ else
+ {
+ theta = 0;
+ }
}
- i = 0;
- do
+ arctanptr = ft_trig_arctan_table;
+
+ /* Pseudorotations, with right shifts */
+ for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ )
{
- if ( y < 0 )
+ if ( y > 0 )
{
- /* Rotate positive */
- yi = y + ( x >> i );
- x = x - ( y >> i );
- y = yi;
- theta -= *arctanptr++;
+ xtemp = x + ( ( y + b ) >> i );
+ y = y - ( ( x + b ) >> i );
+ x = xtemp;
+ theta += *arctanptr++;
}
else
{
- /* Rotate negative */
- yi = y - ( x >> i );
- x = x + ( y >> i );
- y = yi;
- theta += *arctanptr++;
+ xtemp = x - ( ( y + b ) >> i );
+ y = y + ( ( x + b ) >> i );
+ x = xtemp;
+ theta -= *arctanptr++;
}
- } while ( ++i < FT_TRIG_MAX_ITERS );
+ }
/* round theta */
if ( theta >= 0 )
@@ -335,11 +280,11 @@
FT_Vector v;
- v.x = FT_TRIG_COSCALE >> 2;
+ v.x = FT_TRIG_SCALE >> 8;
v.y = 0;
ft_trig_pseudo_rotate( &v, angle );
- return v.x / ( 1 << 12 );
+ return ( v.x + 0x80L ) >> 8;
}
@@ -360,7 +305,7 @@
FT_Vector v;
- v.x = FT_TRIG_COSCALE >> 2;
+ v.x = FT_TRIG_SCALE >> 8;
v.y = 0;
ft_trig_pseudo_rotate( &v, angle );
@@ -395,11 +340,11 @@
FT_Vector_Unit( FT_Vector* vec,
FT_Angle angle )
{
- vec->x = FT_TRIG_COSCALE >> 2;
+ vec->x = FT_TRIG_SCALE >> 8;
vec->y = 0;
ft_trig_pseudo_rotate( vec, angle );
- vec->x >>= 12;
- vec->y >>= 12;
+ vec->x = ( vec->x + 0x80L ) >> 8;
+ vec->y = ( vec->y + 0x80L ) >> 8;
}
@@ -442,8 +387,8 @@
else
{
shift = -shift;
- vec->x = v.x << shift;
- vec->y = v.y << shift;
+ vec->x = (FT_Pos)( (FT_ULong)v.x << shift );
+ vec->y = (FT_Pos)( (FT_ULong)v.y << shift );
}
}
}
@@ -463,11 +408,11 @@
/* handle trivial cases */
if ( v.x == 0 )
{
- return ( v.y >= 0 ) ? v.y : -v.y;
+ return FT_ABS( v.y );
}
else if ( v.y == 0 )
{
- return ( v.x >= 0 ) ? v.x : -v.x;
+ return FT_ABS( v.x );
}
/* general case */
@@ -479,7 +424,7 @@
if ( shift > 0 )
return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift;
- return v.x << -shift;
+ return (FT_Fixed)( (FT_UInt32)v.x << -shift );
}
@@ -504,7 +449,8 @@
v.x = ft_trig_downscale( v.x );
- *length = ( shift >= 0 ) ? ( v.x >> shift ) : ( v.x << -shift );
+ *length = ( shift >= 0 ) ? ( v.x >> shift )
+ : (FT_Fixed)( (FT_UInt32)v.x << -shift );
*angle = v.y;
}
diff --git a/src/base/fttype1.c b/src/base/fttype1.c
index c30124f..1d17402 100644
--- a/src/base/fttype1.c
+++ b/src/base/fttype1.c
@@ -28,7 +28,7 @@
FT_Get_PS_Font_Info( FT_Face face,
PS_FontInfoRec* afont_info )
{
- FT_Error error = FT_Err_Invalid_Argument;
+ FT_Error error = FT_ERR( Invalid_Argument );
if ( face )
@@ -73,7 +73,7 @@
FT_Get_PS_Font_Private( FT_Face face,
PS_PrivateRec* afont_private )
{
- FT_Error error = FT_Err_Invalid_Argument;
+ FT_Error error = FT_ERR( Invalid_Argument );
if ( face )
diff --git a/src/base/ftutil.c b/src/base/ftutil.c
index 5f77be5..879d027 100644
--- a/src/base/ftutil.c
+++ b/src/base/ftutil.c
@@ -4,7 +4,7 @@
/* */
/* FreeType utility file for memory and list management (body). */
/* */
-/* Copyright 2002, 2004, 2005, 2006, 2007 by */
+/* Copyright 2002, 2004-2007, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -75,12 +75,12 @@
{
block = memory->alloc( memory, size );
if ( block == NULL )
- error = FT_Err_Out_Of_Memory;
+ error = FT_THROW( Out_Of_Memory );
}
else if ( size < 0 )
{
/* may help catch/prevent security issues */
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
}
*p_error = error;
@@ -98,6 +98,7 @@
{
FT_Error error = FT_Err_Ok;
+
block = ft_mem_qrealloc( memory, item_size,
cur_count, new_count, block, &error );
if ( !error && new_count > cur_count )
@@ -127,7 +128,7 @@
if ( cur_count < 0 || new_count < 0 || item_size < 0 )
{
/* may help catch/prevent nasty security issues */
- error = FT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
}
else if ( new_count == 0 || item_size == 0 )
{
@@ -136,7 +137,7 @@
}
else if ( new_count > FT_INT_MAX/item_size )
{
- error = FT_Err_Array_Too_Large;
+ error = FT_THROW( Array_Too_Large );
}
else if ( cur_count == 0 )
{
@@ -153,7 +154,7 @@
block2 = memory->realloc( memory, cur_size, new_size, block );
if ( block2 == NULL )
- error = FT_Err_Out_Of_Memory;
+ error = FT_THROW( Out_Of_Memory );
else
block = block2;
}
@@ -432,70 +433,4 @@
}
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- FT_BASE_DEF( FT_Error )
- FT_Alloc( FT_Memory memory,
- FT_Long size,
- void* *P )
- {
- FT_Error error;
-
-
- (void)FT_ALLOC( *P, size );
- return error;
- }
-
-
- FT_BASE_DEF( FT_Error )
- FT_QAlloc( FT_Memory memory,
- FT_Long size,
- void* *p )
- {
- FT_Error error;
-
-
- (void)FT_QALLOC( *p, size );
- return error;
- }
-
-
- FT_BASE_DEF( FT_Error )
- FT_Realloc( FT_Memory memory,
- FT_Long current,
- FT_Long size,
- void* *P )
- {
- FT_Error error;
-
-
- (void)FT_REALLOC( *P, current, size );
- return error;
- }
-
-
- FT_BASE_DEF( FT_Error )
- FT_QRealloc( FT_Memory memory,
- FT_Long current,
- FT_Long size,
- void* *p )
- {
- FT_Error error;
-
-
- (void)FT_QREALLOC( *p, current, size );
- return error;
- }
-
-
- FT_BASE_DEF( void )
- FT_Free( FT_Memory memory,
- void* *P )
- {
- if ( *P )
- FT_MEM_FREE( *P );
- }
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
/* END */
diff --git a/src/base/ftwinfnt.c b/src/base/ftwinfnt.c
index bc2e90e..463ae76 100644
--- a/src/base/ftwinfnt.c
+++ b/src/base/ftwinfnt.c
@@ -32,7 +32,7 @@
FT_Error error;
- error = FT_Err_Invalid_Argument;
+ error = FT_ERR( Invalid_Argument );
if ( face != NULL )
{
diff --git a/src/base/md5.c b/src/base/md5.c
new file mode 100644
index 0000000..2f01c93
--- /dev/null
+++ b/src/base/md5.c
@@ -0,0 +1,295 @@
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001. No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's. No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible. Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
+ */
+
+#ifndef HAVE_OPENSSL
+
+#include <string.h>
+
+#include "md5.h"
+
+/*
+ * The basic MD5 functions.
+ *
+ * F and G are optimized compared to their RFC 1321 definitions for
+ * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
+ * implementation.
+ */
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+
+/*
+ * The MD5 transformation for all four rounds.
+ */
+#define STEP(f, a, b, c, d, x, t, s) \
+ (a) += f((b), (c), (d)) + (x) + (t); \
+ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
+ (a) += (b);
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization. Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+ (*(MD5_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+ SET(n)
+#else
+#define SET(n) \
+ (ctx->block[(n)] = \
+ (MD5_u32plus)ptr[(n) * 4] | \
+ ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
+ ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
+ ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+ (ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters. There are no alignment requirements.
+ */
+static void *body(MD5_CTX *ctx, void *data, unsigned long size)
+{
+ unsigned char *ptr;
+ MD5_u32plus a, b, c, d;
+ MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+
+ ptr = (unsigned char *)data;
+
+ a = ctx->a;
+ b = ctx->b;
+ c = ctx->c;
+ d = ctx->d;
+
+ do {
+ saved_a = a;
+ saved_b = b;
+ saved_c = c;
+ saved_d = d;
+
+/* Round 1 */
+ STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
+ STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
+ STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
+ STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
+ STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
+ STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
+ STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
+ STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
+ STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
+ STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
+ STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
+ STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
+ STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
+ STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
+ STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
+ STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
+
+/* Round 2 */
+ STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
+ STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
+ STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
+ STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
+ STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
+ STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
+ STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
+ STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
+ STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
+ STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
+ STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
+ STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
+ STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
+ STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
+ STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
+ STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
+
+/* Round 3 */
+ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
+ STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
+ STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
+ STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
+ STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
+ STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
+ STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
+ STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
+ STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
+ STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
+ STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
+ STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
+ STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
+ STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
+ STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
+ STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
+
+/* Round 4 */
+ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
+ STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
+ STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
+ STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
+ STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
+ STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
+ STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
+ STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
+ STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
+ STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
+ STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
+ STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
+ STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
+ STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
+ STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
+ STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
+
+ a += saved_a;
+ b += saved_b;
+ c += saved_c;
+ d += saved_d;
+
+ ptr += 64;
+ } while (size -= 64);
+
+ ctx->a = a;
+ ctx->b = b;
+ ctx->c = c;
+ ctx->d = d;
+
+ return ptr;
+}
+
+void MD5_Init(MD5_CTX *ctx)
+{
+ ctx->a = 0x67452301;
+ ctx->b = 0xefcdab89;
+ ctx->c = 0x98badcfe;
+ ctx->d = 0x10325476;
+
+ ctx->lo = 0;
+ ctx->hi = 0;
+}
+
+void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size)
+{
+ MD5_u32plus saved_lo;
+ unsigned long used, free;
+
+ saved_lo = ctx->lo;
+ if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+ ctx->hi++;
+ ctx->hi += size >> 29;
+
+ used = saved_lo & 0x3f;
+
+ if (used) {
+ free = 64 - used;
+
+ if (size < free) {
+ memcpy(&ctx->buffer[used], data, size);
+ return;
+ }
+
+ memcpy(&ctx->buffer[used], data, free);
+ data = (unsigned char *)data + free;
+ size -= free;
+ body(ctx, ctx->buffer, 64);
+ }
+
+ if (size >= 64) {
+ data = body(ctx, data, size & ~(unsigned long)0x3f);
+ size &= 0x3f;
+ }
+
+ memcpy(ctx->buffer, data, size);
+}
+
+void MD5_Final(unsigned char *result, MD5_CTX *ctx)
+{
+ unsigned long used, free;
+
+ used = ctx->lo & 0x3f;
+
+ ctx->buffer[used++] = 0x80;
+
+ free = 64 - used;
+
+ if (free < 8) {
+ memset(&ctx->buffer[used], 0, free);
+ body(ctx, ctx->buffer, 64);
+ used = 0;
+ free = 64;
+ }
+
+ memset(&ctx->buffer[used], 0, free - 8);
+
+ ctx->lo <<= 3;
+ ctx->buffer[56] = ctx->lo;
+ ctx->buffer[57] = ctx->lo >> 8;
+ ctx->buffer[58] = ctx->lo >> 16;
+ ctx->buffer[59] = ctx->lo >> 24;
+ ctx->buffer[60] = ctx->hi;
+ ctx->buffer[61] = ctx->hi >> 8;
+ ctx->buffer[62] = ctx->hi >> 16;
+ ctx->buffer[63] = ctx->hi >> 24;
+
+ body(ctx, ctx->buffer, 64);
+
+ result[0] = ctx->a;
+ result[1] = ctx->a >> 8;
+ result[2] = ctx->a >> 16;
+ result[3] = ctx->a >> 24;
+ result[4] = ctx->b;
+ result[5] = ctx->b >> 8;
+ result[6] = ctx->b >> 16;
+ result[7] = ctx->b >> 24;
+ result[8] = ctx->c;
+ result[9] = ctx->c >> 8;
+ result[10] = ctx->c >> 16;
+ result[11] = ctx->c >> 24;
+ result[12] = ctx->d;
+ result[13] = ctx->d >> 8;
+ result[14] = ctx->d >> 16;
+ result[15] = ctx->d >> 24;
+
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+#endif
diff --git a/src/base/md5.h b/src/base/md5.h
new file mode 100644
index 0000000..f1a6857
--- /dev/null
+++ b/src/base/md5.h
@@ -0,0 +1,45 @@
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001. No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * See md5.c for more information.
+ */
+
+#ifdef HAVE_OPENSSL
+#include <openssl/md5.h>
+#elif !defined(_MD5_H)
+#define _MD5_H
+
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned int MD5_u32plus;
+
+typedef struct {
+ MD5_u32plus lo, hi;
+ MD5_u32plus a, b, c, d;
+ unsigned char buffer[64];
+ MD5_u32plus block[16];
+} MD5_CTX;
+
+extern void MD5_Init(MD5_CTX *ctx);
+extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size);
+extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
+
+#endif
diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c
index d4fc353..84d336d 100644
--- a/src/cache/ftcbasic.c
+++ b/src/cache/ftcbasic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType basic cache interface (body). */
/* */
-/* Copyright 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 by */
+/* Copyright 2003-2007, 2009-2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -30,44 +30,6 @@
#define FT_COMPONENT trace_cache
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /*
- * These structures correspond to the FTC_Font and FTC_ImageDesc types
- * that were defined in version 2.1.7.
- */
- typedef struct FTC_OldFontRec_
- {
- FTC_FaceID face_id;
- FT_UShort pix_width;
- FT_UShort pix_height;
-
- } FTC_OldFontRec, *FTC_OldFont;
-
-
- typedef struct FTC_OldImageDescRec_
- {
- FTC_OldFontRec font;
- FT_UInt32 flags;
-
- } FTC_OldImageDescRec, *FTC_OldImageDesc;
-
-
- /*
- * Notice that FTC_OldImageDescRec and FTC_ImageTypeRec are nearly
- * identical, bit-wise. The only difference is that the `width' and
- * `height' fields are expressed as 16-bit integers in the old structure,
- * and as normal `int' in the new one.
- *
- * We are going to perform a weird hack to detect which structure is
- * being passed to the image and sbit caches. If the new structure's
- * `width' is larger than 0x10000, we assume that we are really receiving
- * an FTC_OldImageDesc.
- */
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
/*
* Basic Families
*
@@ -226,7 +188,7 @@
}
}
else
- error = FTC_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
}
}
@@ -328,7 +290,7 @@
/* some argument checks are delayed to FTC_Cache_Lookup */
if ( !aglyph )
{
- error = FTC_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -336,26 +298,6 @@
if ( anode )
*anode = NULL;
-#if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU )
-
- /*
- * This one is a major hack used to detect whether we are passed a
- * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one.
- */
- if ( (FT_ULong)type->width >= 0x10000L )
- {
- FTC_OldImageDesc desc = (FTC_OldImageDesc)type;
-
-
- query.attrs.scaler.face_id = desc->font.face_id;
- query.attrs.scaler.width = desc->font.pix_width;
- query.attrs.scaler.height = desc->font.pix_height;
- query.attrs.load_flags = desc->flags;
- }
- else
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
{
if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )
{
@@ -424,7 +366,7 @@
/* some argument checks are delayed to FTC_Cache_Lookup */
if ( !aglyph || !scaler )
{
- error = FTC_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -467,142 +409,11 @@
}
-
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /* yet another backwards-legacy structure */
- typedef struct FTC_OldImage_Desc_
- {
- FTC_FontRec font;
- FT_UInt image_type;
-
- } FTC_OldImage_Desc;
-
-
-#define FTC_OLD_IMAGE_FORMAT( x ) ( (x) & 7 )
-
-
-#define ftc_old_image_format_bitmap 0x0000
-#define ftc_old_image_format_outline 0x0001
-
-#define ftc_old_image_format_mask 0x000F
-
-#define ftc_old_image_flag_monochrome 0x0010
-#define ftc_old_image_flag_unhinted 0x0020
-#define ftc_old_image_flag_autohinted 0x0040
-#define ftc_old_image_flag_unscaled 0x0080
-#define ftc_old_image_flag_no_sbits 0x0100
-
- /* monochrome bitmap */
-#define ftc_old_image_mono ftc_old_image_format_bitmap | \
- ftc_old_image_flag_monochrome
-
- /* anti-aliased bitmap */
-#define ftc_old_image_grays ftc_old_image_format_bitmap
-
- /* scaled outline */
-#define ftc_old_image_outline ftc_old_image_format_outline
-
-
- static void
- ftc_image_type_from_old_desc( FTC_ImageType typ,
- FTC_OldImage_Desc* desc )
- {
- typ->face_id = desc->font.face_id;
- typ->width = desc->font.pix_width;
- typ->height = desc->font.pix_height;
-
- /* convert image type flags to load flags */
- {
- FT_UInt load_flags = FT_LOAD_DEFAULT;
- FT_UInt type = desc->image_type;
-
-
- /* determine load flags, depending on the font description's */
- /* image type */
-
- if ( FTC_OLD_IMAGE_FORMAT( type ) == ftc_old_image_format_bitmap )
- {
- if ( type & ftc_old_image_flag_monochrome )
- load_flags |= FT_LOAD_MONOCHROME;
-
- /* disable embedded bitmaps loading if necessary */
- if ( type & ftc_old_image_flag_no_sbits )
- load_flags |= FT_LOAD_NO_BITMAP;
- }
- else
- {
- /* we want an outline, don't load embedded bitmaps */
- load_flags |= FT_LOAD_NO_BITMAP;
-
- if ( type & ftc_old_image_flag_unscaled )
- load_flags |= FT_LOAD_NO_SCALE;
- }
-
- /* always render glyphs to bitmaps */
- load_flags |= FT_LOAD_RENDER;
-
- if ( type & ftc_old_image_flag_unhinted )
- load_flags |= FT_LOAD_NO_HINTING;
-
- if ( type & ftc_old_image_flag_autohinted )
- load_flags |= FT_LOAD_FORCE_AUTOHINT;
-
- typ->flags = load_flags;
- }
- }
-
-
- FT_EXPORT( FT_Error )
- FTC_Image_Cache_New( FTC_Manager manager,
- FTC_ImageCache *acache );
-
- FT_EXPORT( FT_Error )
- FTC_Image_Cache_Lookup( FTC_ImageCache icache,
- FTC_OldImage_Desc* desc,
- FT_UInt gindex,
- FT_Glyph *aglyph );
-
-
- FT_EXPORT_DEF( FT_Error )
- FTC_Image_Cache_New( FTC_Manager manager,
- FTC_ImageCache *acache )
- {
- return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache );
- }
-
-
-
- FT_EXPORT_DEF( FT_Error )
- FTC_Image_Cache_Lookup( FTC_ImageCache icache,
- FTC_OldImage_Desc* desc,
- FT_UInt gindex,
- FT_Glyph *aglyph )
- {
- FTC_ImageTypeRec type0;
-
-
- if ( !desc )
- return FTC_Err_Invalid_Argument;
-
- ftc_image_type_from_old_desc( &type0, desc );
-
- return FTC_ImageCache_Lookup( (FTC_ImageCache)icache,
- &type0,
- gindex,
- aglyph,
- NULL );
- }
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
- /*
- *
- * basic small bitmap cache
- *
- */
-
+ /*
+ *
+ * basic small bitmap cache
+ *
+ */
FT_CALLBACK_TABLE_DEF
const FTC_SFamilyClassRec ftc_basic_sbit_family_class =
@@ -668,29 +479,10 @@
/* other argument checks delayed to FTC_Cache_Lookup */
if ( !ansbit )
- return FTC_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
*ansbit = NULL;
-#if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU )
-
- /* This one is a major hack used to detect whether we are passed a
- * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one.
- */
- if ( (FT_ULong)type->width >= 0x10000L )
- {
- FTC_OldImageDesc desc = (FTC_OldImageDesc)type;
-
-
- query.attrs.scaler.face_id = desc->font.face_id;
- query.attrs.scaler.width = desc->font.pix_width;
- query.attrs.scaler.height = desc->font.pix_height;
- query.attrs.load_flags = desc->flags;
- }
- else
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
{
if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )
{
@@ -765,7 +557,7 @@
/* other argument checks delayed to FTC_Cache_Lookup */
if ( !ansbit || !scaler )
- return FTC_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
*ansbit = NULL;
@@ -807,49 +599,4 @@
}
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- FT_EXPORT( FT_Error )
- FTC_SBit_Cache_New( FTC_Manager manager,
- FTC_SBitCache *acache );
-
- FT_EXPORT( FT_Error )
- FTC_SBit_Cache_Lookup( FTC_SBitCache cache,
- FTC_OldImage_Desc* desc,
- FT_UInt gindex,
- FTC_SBit *ansbit );
-
-
- FT_EXPORT_DEF( FT_Error )
- FTC_SBit_Cache_New( FTC_Manager manager,
- FTC_SBitCache *acache )
- {
- return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache );
- }
-
-
- FT_EXPORT_DEF( FT_Error )
- FTC_SBit_Cache_Lookup( FTC_SBitCache cache,
- FTC_OldImage_Desc* desc,
- FT_UInt gindex,
- FTC_SBit *ansbit )
- {
- FTC_ImageTypeRec type0;
-
-
- if ( !desc )
- return FTC_Err_Invalid_Argument;
-
- ftc_image_type_from_old_desc( &type0, desc );
-
- return FTC_SBitCache_Lookup( (FTC_SBitCache)cache,
- &type0,
- gindex,
- ansbit,
- NULL );
- }
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
/* END */
diff --git a/src/cache/ftccache.c b/src/cache/ftccache.c
index f01c403..f20dd45 100644
--- a/src/cache/ftccache.c
+++ b/src/cache/ftccache.c
@@ -4,8 +4,7 @@
/* */
/* The FreeType internal cache interface (body). */
/* */
-/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, */
-/* 2011 by */
+/* Copyright 2000-2007, 2009-2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -270,11 +269,7 @@
/* remove a node from the cache manager */
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- FT_BASE_DEF( void )
-#else
FT_LOCAL_DEF( void )
-#endif
ftc_node_destroy( FTC_Node node,
FTC_Manager manager )
{
@@ -493,14 +488,14 @@
FTC_Node* bucket;
FTC_Node* pnode;
FTC_Node node;
- FT_Error error = FTC_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Bool list_changed = FALSE;
FTC_Node_CompareFunc compare = cache->clazz.node_compare;
if ( cache == NULL || anode == NULL )
- return FTC_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* Go to the `top' node of the list sharing same masked hash */
bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash );
diff --git a/src/cache/ftccache.h b/src/cache/ftccache.h
index d60984f..4155f32 100644
--- a/src/cache/ftccache.h
+++ b/src/cache/ftccache.h
@@ -4,8 +4,7 @@
/* */
/* FreeType internal cache interface (specification). */
/* */
-/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, */
-/* 2011 by */
+/* Copyright 2000-2007, 2009-2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -87,12 +86,6 @@ FT_BEGIN_HEADER
ftc_get_top_node_for_hash( ( cache ), ( hash ) )
#endif
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- FT_BASE( void )
- ftc_node_destroy( FTC_Node node,
- FTC_Manager manager );
-#endif
-
/*************************************************************************/
/*************************************************************************/
@@ -223,7 +216,7 @@ FT_BEGIN_HEADER
FT_Bool _list_changed = FALSE; \
\
\
- error = FTC_Err_Ok; \
+ error = FT_Err_Ok; \
node = NULL; \
\
/* Go to the `top' node of the list sharing same masked hash */ \
@@ -328,7 +321,7 @@ FT_BEGIN_HEADER
#define FTC_CACHE_TRYLOOP_END( list_changed ) \
- if ( !error || error != FTC_Err_Out_Of_Memory ) \
+ if ( !error || FT_ERR_NEQ( error, Out_Of_Memory ) ) \
break; \
\
_try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \
diff --git a/src/cache/ftccback.h b/src/cache/ftccback.h
index 80ec9ce..9528279 100644
--- a/src/cache/ftccback.h
+++ b/src/cache/ftccback.h
@@ -4,7 +4,7 @@
/* */
/* Callback functions of the caching sub-system (specification only). */
/* */
-/* Copyright 2004, 2005, 2006, 2011 by */
+/* Copyright 2004-2006, 2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -81,11 +81,10 @@
FT_LOCAL( void )
ftc_cache_done( FTC_Cache cache );
-#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
FT_LOCAL( void )
ftc_node_destroy( FTC_Node node,
FTC_Manager manager );
-#endif
+
#endif /* __FTCCBACK_H__ */
diff --git a/src/cache/ftccmap.c b/src/cache/ftccmap.c
index ad436ef..848349b 100644
--- a/src/cache/ftccmap.c
+++ b/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-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -32,43 +31,6 @@
#define FT_COMPONENT trace_cache
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- typedef enum FTC_OldCMapType_
- {
- FTC_OLD_CMAP_BY_INDEX = 0,
- FTC_OLD_CMAP_BY_ENCODING = 1,
- FTC_OLD_CMAP_BY_ID = 2
-
- } FTC_OldCMapType;
-
-
- typedef struct FTC_OldCMapIdRec_
- {
- FT_UInt platform;
- FT_UInt encoding;
-
- } FTC_OldCMapIdRec, *FTC_OldCMapId;
-
-
- typedef struct FTC_OldCMapDescRec_
- {
- FTC_FaceID face_id;
- FTC_OldCMapType type;
-
- union
- {
- FT_UInt index;
- FT_Encoding encoding;
- FTC_OldCMapIdRec id;
-
- } u;
-
- } FTC_OldCMapDescRec, *FTC_OldCMapDesc;
-
-#endif /* FT_CONFIG_OLD_INTERNALS */
-
-
/*************************************************************************/
/* */
/* Each FTC_CMapNode contains a simple array to map a range of character */
@@ -121,7 +83,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
/*************************************************************************/
@@ -267,21 +229,6 @@
}
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /*
- * Unfortunately, it is not possible to support binary backwards
- * compatibility in the cmap cache. The FTC_CMapCache_Lookup signature
- * changes were too deep, and there is no clever hackish way to detect
- * what kind of structure we are being passed.
- *
- * On the other hand it seems that no production code is using this
- * function on Unix distributions.
- */
-
-#endif
-
-
/* documentation is in ftcache.h */
FT_EXPORT_DEF( FT_UInt )
@@ -316,57 +263,9 @@
return 0;
}
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- /*
- * If cmap_index is greater than the maximum number of cachable
- * charmaps, we assume the request is from a legacy rogue client
- * using old internal header. See include/config/ftoption.h.
- */
- if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE && !no_cmap_change )
- {
- FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id;
-
-
- char_code = (FT_UInt32)cmap_index;
- query.face_id = desc->face_id;
-
-
- switch ( desc->type )
- {
- case FTC_OLD_CMAP_BY_INDEX:
- query.cmap_index = desc->u.index;
- query.char_code = (FT_UInt32)cmap_index;
- break;
-
- case FTC_OLD_CMAP_BY_ENCODING:
- {
- FT_Face face;
-
-
- error = FTC_Manager_LookupFace( cache->manager, desc->face_id,
- &face );
- if ( error )
- return 0;
-
- FT_Select_Charmap( face, desc->u.encoding );
-
- return FT_Get_Char_Index( face, char_code );
- }
-
- default:
- return 0;
- }
- }
- else
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
- {
- query.face_id = face_id;
- query.cmap_index = (FT_UInt)cmap_index;
- query.char_code = char_code;
- }
+ query.face_id = face_id;
+ query.cmap_index = (FT_UInt)cmap_index;
+ query.char_code = char_code;
hash = FTC_CMAP_HASH( face_id, cmap_index, char_code );
diff --git a/src/cache/ftcmanag.h b/src/cache/ftcmanag.h
index d6c8516..0aec33c 100644
--- a/src/cache/ftcmanag.h
+++ b/src/cache/ftcmanag.h
@@ -4,7 +4,7 @@
/* */
/* FreeType Cache Manager (specification). */
/* */
-/* Copyright 2000-2001, 2003, 2004, 2006, 2010 by */
+/* Copyright 2000-2001, 2003, 2004, 2006, 2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -94,8 +94,8 @@ FT_BEGIN_HEADER
FT_Memory memory;
FTC_Node nodes_list;
- FT_ULong max_weight;
- FT_ULong cur_weight;
+ FT_Offset max_weight;
+ FT_Offset cur_weight;
FT_UInt num_nodes;
FTC_Cache caches[FTC_MAX_CACHES];
diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c
index 8bf8d60..6df1c19 100644
--- a/src/cache/ftcsbits.c
+++ b/src/cache/ftcsbits.c
@@ -4,7 +4,7 @@
/* */
/* FreeType sbits manager (body). */
/* */
-/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010, 2011 by */
+/* Copyright 2000-2006, 2009-2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -116,7 +116,7 @@
if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count )
{
FT_ERROR(( "ftc_snode_load: invalid glyph index" ));
- return FTC_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
sbit = snode->sbits + ( gindex - gnode->gindex );
@@ -189,13 +189,13 @@
/* we mark unloaded glyphs with `sbit.buffer == 0' */
/* and `width == 255', `height == 0' */
/* */
- if ( error && error != FTC_Err_Out_Of_Memory )
+ if ( error && FT_ERR_NEQ( error, Out_Of_Memory ) )
{
BadGlyph:
sbit->width = 255;
sbit->height = 0;
sbit->buffer = NULL;
- error = FTC_Err_Ok;
+ error = FT_Err_Ok;
if ( asize )
*asize = 0;
}
@@ -223,7 +223,7 @@
total = clazz->family_get_count( family, cache->manager );
if ( total == 0 || gindex >= total )
{
- error = FTC_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
diff --git a/src/cff/cf2arrst.c b/src/cff/cf2arrst.c
new file mode 100644
index 0000000..c8d6f13
--- /dev/null
+++ b/src/cff/cf2arrst.c
@@ -0,0 +1,241 @@
+/***************************************************************************/
+/* */
+/* cf2arrst.c */
+/* */
+/* Adobe's code for Array Stacks (body). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#include "cf2ft.h"
+#include FT_INTERNAL_DEBUG_H
+
+#include "cf2glue.h"
+#include "cf2arrst.h"
+
+#include "cf2error.h"
+
+
+ /*
+ * CF2_ArrStack uses an error pointer, to enable shared errors.
+ * Shared errors are necessary when multiple objects allow the program
+ * to continue after detecting errors. Only the first error should be
+ * recorded.
+ */
+
+ FT_LOCAL_DEF( void )
+ cf2_arrstack_init( CF2_ArrStack arrstack,
+ FT_Memory memory,
+ FT_Error* error,
+ size_t sizeItem )
+ {
+ FT_ASSERT( arrstack != NULL );
+
+ /* initialize the structure */
+ arrstack->memory = memory;
+ arrstack->error = error;
+ arrstack->sizeItem = sizeItem;
+ arrstack->allocated = 0;
+ arrstack->chunk = 10; /* chunks of 10 items */
+ arrstack->count = 0;
+ arrstack->totalSize = 0;
+ arrstack->ptr = NULL;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_arrstack_finalize( CF2_ArrStack arrstack )
+ {
+ FT_Memory memory = arrstack->memory; /* for FT_FREE */
+
+
+ FT_ASSERT( arrstack != NULL );
+
+ arrstack->allocated = 0;
+ arrstack->count = 0;
+ arrstack->totalSize = 0;
+
+ /* free the data buffer */
+ FT_FREE( arrstack->ptr );
+ }
+
+
+ /* allocate or reallocate the buffer size; */
+ /* return false on memory error */
+ static FT_Bool
+ cf2_arrstack_setNumElements( CF2_ArrStack arrstack,
+ size_t numElements )
+ {
+ FT_ASSERT( arrstack != NULL );
+
+ {
+ FT_Error error = FT_Err_Ok; /* for FT_REALLOC */
+ FT_Memory memory = arrstack->memory; /* for FT_REALLOC */
+
+ FT_Long newSize = (FT_Long)( numElements * arrstack->sizeItem );
+
+
+ if ( numElements > LONG_MAX / arrstack->sizeItem )
+ goto exit;
+
+
+ FT_ASSERT( newSize > 0 ); /* avoid realloc with zero size */
+
+ if ( !FT_REALLOC( arrstack->ptr, arrstack->totalSize, newSize ) )
+ {
+ arrstack->allocated = numElements;
+ arrstack->totalSize = newSize;
+
+ if ( arrstack->count > numElements )
+ {
+ /* we truncated the list! */
+ CF2_SET_ERROR( arrstack->error, Stack_Overflow );
+ arrstack->count = numElements;
+ return FALSE;
+ }
+
+ return TRUE; /* success */
+ }
+ }
+
+ exit:
+ /* if there's not already an error, store this one */
+ CF2_SET_ERROR( arrstack->error, Out_Of_Memory );
+
+ return FALSE;
+ }
+
+
+ /* set the count, ensuring allocation is sufficient */
+ FT_LOCAL_DEF( void )
+ cf2_arrstack_setCount( CF2_ArrStack arrstack,
+ size_t numElements )
+ {
+ FT_ASSERT( arrstack != NULL );
+
+ if ( numElements > arrstack->allocated )
+ {
+ /* expand the allocation first */
+ if ( !cf2_arrstack_setNumElements( arrstack, numElements ) )
+ return;
+ }
+
+ arrstack->count = numElements;
+ }
+
+
+ /* clear the count */
+ FT_LOCAL_DEF( void )
+ cf2_arrstack_clear( CF2_ArrStack arrstack )
+ {
+ FT_ASSERT( arrstack != NULL );
+
+ arrstack->count = 0;
+ }
+
+
+ /* current number of items */
+ FT_LOCAL_DEF( size_t )
+ cf2_arrstack_size( const CF2_ArrStack arrstack )
+ {
+ FT_ASSERT( arrstack != NULL );
+
+ return arrstack->count;
+ }
+
+
+ FT_LOCAL_DEF( void* )
+ cf2_arrstack_getBuffer( const CF2_ArrStack arrstack )
+ {
+ FT_ASSERT( arrstack != NULL );
+
+ return arrstack->ptr;
+ }
+
+
+ /* return pointer to the given element */
+ FT_LOCAL_DEF( void* )
+ cf2_arrstack_getPointer( const CF2_ArrStack arrstack,
+ size_t idx )
+ {
+ void* newPtr;
+
+
+ FT_ASSERT( arrstack != NULL );
+
+ if ( idx >= arrstack->count )
+ {
+ /* overflow */
+ CF2_SET_ERROR( arrstack->error, Stack_Overflow );
+ idx = 0; /* choose safe default */
+ }
+
+ newPtr = (FT_Byte*)arrstack->ptr + idx * arrstack->sizeItem;
+
+ return newPtr;
+ }
+
+
+ /* push (append) an element at the end of the list; */
+ /* return false on memory error */
+ /* TODO: should there be a length param for extra checking? */
+ FT_LOCAL_DEF( void )
+ cf2_arrstack_push( CF2_ArrStack arrstack,
+ const void* ptr )
+ {
+ FT_ASSERT( arrstack != NULL );
+
+ if ( arrstack->count == arrstack->allocated )
+ {
+ /* grow the buffer by one chunk */
+ if ( !cf2_arrstack_setNumElements(
+ arrstack, arrstack->allocated + arrstack->chunk ) )
+ {
+ /* on error, ignore the push */
+ return;
+ }
+ }
+
+ FT_ASSERT( ptr != NULL );
+
+ {
+ size_t offset = arrstack->count * arrstack->sizeItem;
+ void* newPtr = (FT_Byte*)arrstack->ptr + offset;
+
+
+ FT_MEM_COPY( newPtr, ptr, arrstack->sizeItem );
+ arrstack->count += 1;
+ }
+ }
+
+
+/* END */
diff --git a/src/cff/cf2arrst.h b/src/cff/cf2arrst.h
new file mode 100644
index 0000000..ff5ad8b
--- /dev/null
+++ b/src/cff/cf2arrst.h
@@ -0,0 +1,100 @@
+/***************************************************************************/
+/* */
+/* cf2arrst.h */
+/* */
+/* Adobe's code for Array Stacks (specification). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CF2ARRST_H__
+#define __CF2ARRST_H__
+
+
+#include "cf2error.h"
+
+
+FT_BEGIN_HEADER
+
+
+ /* need to define the struct here (not opaque) so it can be allocated by */
+ /* clients */
+ typedef struct CF2_ArrStackRec_
+ {
+ FT_Memory memory;
+ FT_Error* error;
+
+ size_t sizeItem; /* bytes per element */
+ size_t allocated; /* items allocated */
+ size_t chunk; /* allocation increment in items */
+ size_t count; /* number of elements allocated */
+ size_t totalSize; /* total bytes allocated */
+
+ void* ptr; /* ptr to data */
+
+ } CF2_ArrStackRec, *CF2_ArrStack;
+
+
+ FT_LOCAL( void )
+ cf2_arrstack_init( CF2_ArrStack arrstack,
+ FT_Memory memory,
+ FT_Error* error,
+ size_t sizeItem );
+ FT_LOCAL( void )
+ cf2_arrstack_finalize( CF2_ArrStack arrstack );
+
+ FT_LOCAL( void )
+ cf2_arrstack_setCount( CF2_ArrStack arrstack,
+ size_t numElements );
+ FT_LOCAL( void )
+ cf2_arrstack_clear( CF2_ArrStack arrstack );
+ FT_LOCAL( size_t )
+ cf2_arrstack_size( const CF2_ArrStack arrstack );
+
+ FT_LOCAL( void* )
+ cf2_arrstack_getBuffer( const CF2_ArrStack arrstack );
+ FT_LOCAL( void* )
+ cf2_arrstack_getPointer( const CF2_ArrStack arrstack,
+ size_t idx );
+
+ FT_LOCAL( void )
+ cf2_arrstack_push( CF2_ArrStack arrstack,
+ const void* ptr );
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2ARRST_H__ */
+
+
+/* END */
diff --git a/src/cff/cf2blues.c b/src/cff/cf2blues.c
new file mode 100644
index 0000000..5b34839
--- /dev/null
+++ b/src/cff/cf2blues.c
@@ -0,0 +1,578 @@
+/***************************************************************************/
+/* */
+/* cf2blues.c */
+/* */
+/* Adobe's code for handling Blue Zones (body). */
+/* */
+/* Copyright 2009-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#include "cf2ft.h"
+#include FT_INTERNAL_DEBUG_H
+
+#include "cf2blues.h"
+#include "cf2hints.h"
+#include "cf2font.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_cf2blues
+
+
+ /*
+ * For blue values, the FreeType parser produces an array of integers,
+ * while the Adobe CFF engine produces an array of fixed.
+ * Define a macro to convert FreeType to fixed.
+ */
+#define cf2_blueToFixed( x ) cf2_intToFixed( x )
+
+
+ FT_LOCAL_DEF( void )
+ cf2_blues_init( CF2_Blues blues,
+ CF2_Font font )
+ {
+ /* pointer to parsed font object */
+ CFF_Decoder* decoder = font->decoder;
+
+ CF2_Fixed zoneHeight;
+ CF2_Fixed maxZoneHeight = 0;
+ CF2_Fixed csUnitsPerPixel;
+
+ size_t numBlueValues;
+ size_t numOtherBlues;
+ size_t numFamilyBlues;
+ size_t numFamilyOtherBlues;
+
+ FT_Pos* blueValues;
+ FT_Pos* otherBlues;
+ FT_Pos* familyBlues;
+ FT_Pos* familyOtherBlues;
+
+ size_t i;
+ CF2_Fixed emBoxBottom, emBoxTop;
+
+ CF2_Int unitsPerEm = font->unitsPerEm;
+
+
+ if ( unitsPerEm == 0 )
+ unitsPerEm = 1000;
+
+ FT_ZERO( blues );
+ blues->scale = font->innerTransform.d;
+
+ cf2_getBlueMetrics( decoder,
+ &blues->blueScale,
+ &blues->blueShift,
+ &blues->blueFuzz );
+
+ cf2_getBlueValues( decoder, &numBlueValues, &blueValues );
+ cf2_getOtherBlues( decoder, &numOtherBlues, &otherBlues );
+ cf2_getFamilyBlues( decoder, &numFamilyBlues, &familyBlues );
+ cf2_getFamilyOtherBlues( decoder, &numFamilyOtherBlues, &familyOtherBlues );
+
+ /*
+ * synthetic em box hint heuristic
+ *
+ * Apply this when ideographic dictionary (LanguageGroup 1) has no
+ * real alignment zones. Adobe tools generate dummy zones at -250 and
+ * 1100 for a 1000 unit em. Fonts with ICF-based alignment zones
+ * should not enable the heuristic. When the heuristic is enabled,
+ * the font's blue zones are ignored.
+ *
+ */
+
+ /* get em box from OS/2 typoAscender/Descender */
+ /* TODO: FreeType does not parse these metrics. Skip them for now. */
+#if 0
+ FCM_getHorizontalLineMetrics( &e,
+ font->font,
+ &ascender,
+ &descender,
+ &linegap );
+ if ( ascender - descender == unitsPerEm )
+ {
+ emBoxBottom = cf2_intToFixed( descender );
+ emBoxTop = cf2_intToFixed( ascender );
+ }
+ else
+#endif
+ {
+ emBoxBottom = CF2_ICF_Bottom;
+ emBoxTop = CF2_ICF_Top;
+ }
+
+ if ( cf2_getLanguageGroup( decoder ) == 1 &&
+ ( numBlueValues == 0 ||
+ ( numBlueValues == 4 &&
+ cf2_blueToFixed( blueValues[0] ) < emBoxBottom &&
+ cf2_blueToFixed( blueValues[1] ) < emBoxBottom &&
+ cf2_blueToFixed( blueValues[2] ) > emBoxTop &&
+ cf2_blueToFixed( blueValues[3] ) > emBoxTop ) ) )
+ {
+ /*
+ * Construct hint edges suitable for synthetic ghost hints at top
+ * and bottom of em box. +-CF2_MIN_COUNTER allows for unhinted
+ * features above or below the last hinted edge. This also gives a
+ * net 1 pixel boost to the height of ideographic glyphs.
+ *
+ * Note: Adjust synthetic hints outward by epsilon (0x.0001) to
+ * avoid interference. E.g., some fonts have real hints at
+ * 880 and -120.
+ */
+
+ blues->emBoxBottomEdge.csCoord = emBoxBottom - CF2_FIXED_EPSILON;
+ blues->emBoxBottomEdge.dsCoord = cf2_fixedRound(
+ FT_MulFix(
+ blues->emBoxBottomEdge.csCoord,
+ blues->scale ) ) -
+ CF2_MIN_COUNTER;
+ blues->emBoxBottomEdge.scale = blues->scale;
+ blues->emBoxBottomEdge.flags = CF2_GhostBottom |
+ CF2_Locked |
+ CF2_Synthetic;
+
+ blues->emBoxTopEdge.csCoord = emBoxTop + CF2_FIXED_EPSILON +
+ 2 * font->darkenY;
+ blues->emBoxTopEdge.dsCoord = cf2_fixedRound(
+ FT_MulFix(
+ blues->emBoxTopEdge.csCoord,
+ blues->scale ) ) +
+ CF2_MIN_COUNTER;
+ blues->emBoxTopEdge.scale = blues->scale;
+ blues->emBoxTopEdge.flags = CF2_GhostTop |
+ CF2_Locked |
+ CF2_Synthetic;
+
+ blues->doEmBoxHints = TRUE; /* enable the heuristic */
+
+ return;
+ }
+
+ /* copy `BlueValues' and `OtherBlues' to a combined array of top and */
+ /* bottom zones */
+ for ( i = 0; i < numBlueValues; i += 2 )
+ {
+ blues->zone[blues->count].csBottomEdge =
+ cf2_blueToFixed( blueValues[i] );
+ blues->zone[blues->count].csTopEdge =
+ cf2_blueToFixed( blueValues[i + 1] );
+
+ zoneHeight = blues->zone[blues->count].csTopEdge -
+ blues->zone[blues->count].csBottomEdge;
+
+ if ( zoneHeight < 0 )
+ {
+ FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" ));
+ continue; /* reject this zone */
+ }
+
+ if ( zoneHeight > maxZoneHeight )
+ {
+ /* take maximum before darkening adjustment */
+ /* so overshoot suppression point doesn't change */
+ maxZoneHeight = zoneHeight;
+ }
+
+ /* adjust both edges of top zone upward by twice darkening amount */
+ if ( i != 0 )
+ {
+ blues->zone[blues->count].csTopEdge += 2 * font->darkenY;
+ blues->zone[blues->count].csBottomEdge += 2 * font->darkenY;
+ }
+
+ /* first `BlueValue' is bottom zone; others are top */
+ if ( i == 0 )
+ {
+ blues->zone[blues->count].bottomZone =
+ TRUE;
+ blues->zone[blues->count].csFlatEdge =
+ blues->zone[blues->count].csTopEdge;
+ }
+ else
+ {
+ blues->zone[blues->count].bottomZone =
+ FALSE;
+ blues->zone[blues->count].csFlatEdge =
+ blues->zone[blues->count].csBottomEdge;
+ }
+
+ blues->count += 1;
+ }
+
+ for ( i = 0; i < numOtherBlues; i += 2 )
+ {
+ blues->zone[blues->count].csBottomEdge =
+ cf2_blueToFixed( otherBlues[i] );
+ blues->zone[blues->count].csTopEdge =
+ cf2_blueToFixed( otherBlues[i + 1] );
+
+ zoneHeight = blues->zone[blues->count].csTopEdge -
+ blues->zone[blues->count].csBottomEdge;
+
+ if ( zoneHeight < 0 )
+ {
+ FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" ));
+ continue; /* reject this zone */
+ }
+
+ if ( zoneHeight > maxZoneHeight )
+ {
+ /* take maximum before darkening adjustment */
+ /* so overshoot suppression point doesn't change */
+ maxZoneHeight = zoneHeight;
+ }
+
+ /* Note: bottom zones are not adjusted for darkening amount */
+
+ /* all OtherBlues are bottom zone */
+ blues->zone[blues->count].bottomZone =
+ TRUE;
+ blues->zone[blues->count].csFlatEdge =
+ blues->zone[blues->count].csTopEdge;
+
+ blues->count += 1;
+ }
+
+ /* Adjust for FamilyBlues */
+
+ /* Search for the nearest flat edge in `FamilyBlues' or */
+ /* `FamilyOtherBlues'. According to the Black Book, any matching edge */
+ /* must be within one device pixel */
+
+ csUnitsPerPixel = FT_DivFix( cf2_intToFixed( 1 ), blues->scale );
+
+ /* loop on all zones in this font */
+ for ( i = 0; i < blues->count; i++ )
+ {
+ size_t j;
+ CF2_Fixed minDiff;
+ CF2_Fixed flatFamilyEdge, diff;
+ /* value for this font */
+ CF2_Fixed flatEdge = blues->zone[i].csFlatEdge;
+
+
+ if ( blues->zone[i].bottomZone )
+ {
+ /* In a bottom zone, the top edge is the flat edge. */
+ /* Search `FamilyOtherBlues' for bottom zones; look for closest */
+ /* Family edge that is within the one pixel threshold. */
+
+ minDiff = CF2_FIXED_MAX;
+
+ for ( j = 0; j < numFamilyOtherBlues; j += 2 )
+ {
+ /* top edge */
+ flatFamilyEdge = cf2_blueToFixed( familyOtherBlues[j + 1] );
+
+ diff = cf2_fixedAbs( flatEdge - flatFamilyEdge );
+
+ if ( diff < minDiff && diff < csUnitsPerPixel )
+ {
+ blues->zone[i].csFlatEdge = flatFamilyEdge;
+ minDiff = diff;
+
+ if ( diff == 0 )
+ break;
+ }
+ }
+
+ /* check the first member of FamilyBlues, which is a bottom zone */
+ if ( numFamilyBlues >= 2 )
+ {
+ /* top edge */
+ flatFamilyEdge = cf2_blueToFixed( familyBlues[1] );
+
+ diff = cf2_fixedAbs( flatEdge - flatFamilyEdge );
+
+ if ( diff < minDiff && diff < csUnitsPerPixel )
+ blues->zone[i].csFlatEdge = flatFamilyEdge;
+ }
+ }
+ else
+ {
+ /* In a top zone, the bottom edge is the flat edge. */
+ /* Search `FamilyBlues' for top zones; skip first zone, which is a */
+ /* bottom zone; look for closest Family edge that is within the */
+ /* one pixel threshold */
+
+ minDiff = CF2_FIXED_MAX;
+
+ for ( j = 2; j < numFamilyBlues; j += 2 )
+ {
+ /* bottom edge */
+ flatFamilyEdge = cf2_blueToFixed( familyBlues[j] );
+
+ /* adjust edges of top zone upward by twice darkening amount */
+ flatFamilyEdge += 2 * font->darkenY; /* bottom edge */
+
+ diff = cf2_fixedAbs( flatEdge - flatFamilyEdge );
+
+ if ( diff < minDiff && diff < csUnitsPerPixel )
+ {
+ blues->zone[i].csFlatEdge = flatFamilyEdge;
+ minDiff = diff;
+
+ if ( diff == 0 )
+ break;
+ }
+ }
+ }
+ }
+
+ /* TODO: enforce separation of zones, including BlueFuzz */
+
+ /* Adjust BlueScale; similar to AdjustBlueScale() in coretype */
+ /* `bcsetup.c'. */
+
+ if ( maxZoneHeight > 0 )
+ {
+ if ( blues->blueScale > FT_DivFix( cf2_intToFixed( 1 ),
+ maxZoneHeight ) )
+ {
+ /* clamp at maximum scale */
+ blues->blueScale = FT_DivFix( cf2_intToFixed( 1 ),
+ maxZoneHeight );
+ }
+
+ /*
+ * TODO: Revisit the bug fix for 613448. The minimum scale
+ * requirement catches a number of library fonts. For
+ * example, with default BlueScale (.039625) and 0.4 minimum,
+ * the test below catches any font with maxZoneHeight < 10.1.
+ * There are library fonts ranging from 2 to 10 that get
+ * caught, including e.g., Eurostile LT Std Medium with
+ * maxZoneHeight of 6.
+ *
+ */
+#if 0
+ if ( blueScale < .4 / maxZoneHeight )
+ {
+ tetraphilia_assert( 0 );
+ /* clamp at minimum scale, per bug 0613448 fix */
+ blueScale = .4 / maxZoneHeight;
+ }
+#endif
+
+ }
+
+ /*
+ * Suppress overshoot and boost blue zones at small sizes. Boost
+ * amount varies linearly from 0.5 pixel near 0 to 0 pixel at
+ * blueScale cutoff.
+ * Note: This boost amount is different from the coretype heuristic.
+ *
+ */
+
+ if ( blues->scale < blues->blueScale )
+ {
+ blues->suppressOvershoot = TRUE;
+
+ /* Change rounding threshold for `dsFlatEdge'. */
+ /* Note: constant changed from 0.5 to 0.6 to avoid a problem with */
+ /* 10ppem Arial */
+
+ blues->boost = FT_MulFix(
+ cf2_floatToFixed( .6 ),
+ ( cf2_intToFixed( 1 ) -
+ FT_DivFix( blues->scale,
+ blues->blueScale ) ) );
+ if ( blues->boost > 0x7FFF )
+ {
+ /* boost must remain less than 0.5, or baseline could go negative */
+ blues->boost = 0x7FFF;
+ }
+ }
+
+ /* boost and darkening have similar effects; don't do both */
+ if ( font->stemDarkened )
+ blues->boost = 0;
+
+ /* set device space alignment for each zone; */
+ /* apply boost amount before rounding flat edge */
+
+ for ( i = 0; i < blues->count; i++ )
+ {
+ if ( blues->zone[i].bottomZone )
+ blues->zone[i].dsFlatEdge = cf2_fixedRound(
+ FT_MulFix(
+ blues->zone[i].csFlatEdge,
+ blues->scale ) -
+ blues->boost );
+ else
+ blues->zone[i].dsFlatEdge = cf2_fixedRound(
+ FT_MulFix(
+ blues->zone[i].csFlatEdge,
+ blues->scale ) +
+ blues->boost );
+ }
+ }
+
+
+ /*
+ * Check whether `stemHint' is captured by one of the blue zones.
+ *
+ * Zero, one or both edges may be valid; only valid edges can be
+ * captured. For compatibility with CoolType, search top and bottom
+ * zones in the same pass (see `BlueLock'). If a hint is captured,
+ * return true and position the edge(s) in one of 3 ways:
+ *
+ * 1) If `BlueScale' suppresses overshoot, position the captured edge
+ * at the flat edge of the zone.
+ * 2) If overshoot is not suppressed and `BlueShift' requires
+ * overshoot, position the captured edge a minimum of 1 device pixel
+ * from the flat edge.
+ * 3) If overshoot is not suppressed or required, position the captured
+ * edge at the nearest device pixel.
+ *
+ */
+ FT_LOCAL_DEF( FT_Bool )
+ cf2_blues_capture( const CF2_Blues blues,
+ CF2_Hint bottomHintEdge,
+ CF2_Hint topHintEdge )
+ {
+ /* TODO: validate? */
+ CF2_Fixed csFuzz = blues->blueFuzz;
+
+ /* new position of captured edge */
+ CF2_Fixed dsNew;
+
+ /* amount that hint is moved when positioned */
+ CF2_Fixed dsMove = 0;
+
+ FT_Bool captured = FALSE;
+ CF2_UInt i;
+
+
+ /* assert edge flags are consistent */
+ FT_ASSERT( !cf2_hint_isTop( bottomHintEdge ) &&
+ !cf2_hint_isBottom( topHintEdge ) );
+
+ /* TODO: search once without blue fuzz for compatibility with coretype? */
+ for ( i = 0; i < blues->count; i++ )
+ {
+ if ( blues->zone[i].bottomZone &&
+ cf2_hint_isBottom( bottomHintEdge ) )
+ {
+ if ( ( blues->zone[i].csBottomEdge - csFuzz ) <=
+ bottomHintEdge->csCoord &&
+ bottomHintEdge->csCoord <=
+ ( blues->zone[i].csTopEdge + csFuzz ) )
+ {
+ /* bottom edge captured by bottom zone */
+
+ if ( blues->suppressOvershoot )
+ dsNew = blues->zone[i].dsFlatEdge;
+
+ else if ( ( blues->zone[i].csTopEdge - bottomHintEdge->csCoord ) >=
+ blues->blueShift )
+ {
+ /* guarantee minimum of 1 pixel overshoot */
+ dsNew = FT_MIN(
+ cf2_fixedRound( bottomHintEdge->dsCoord ),
+ blues->zone[i].dsFlatEdge - cf2_intToFixed( 1 ) );
+ }
+
+ else
+ {
+ /* simply round captured edge */
+ dsNew = cf2_fixedRound( bottomHintEdge->dsCoord );
+ }
+
+ dsMove = dsNew - bottomHintEdge->dsCoord;
+ captured = TRUE;
+
+ break;
+ }
+ }
+
+ if ( !blues->zone[i].bottomZone && cf2_hint_isTop( topHintEdge ) )
+ {
+ if ( ( blues->zone[i].csBottomEdge - csFuzz ) <=
+ topHintEdge->csCoord &&
+ topHintEdge->csCoord <=
+ ( blues->zone[i].csTopEdge + csFuzz ) )
+ {
+ /* top edge captured by top zone */
+
+ if ( blues->suppressOvershoot )
+ dsNew = blues->zone[i].dsFlatEdge;
+
+ else if ( ( topHintEdge->csCoord - blues->zone[i].csBottomEdge ) >=
+ blues->blueShift )
+ {
+ /* guarantee minimum of 1 pixel overshoot */
+ dsNew = FT_MAX(
+ cf2_fixedRound( topHintEdge->dsCoord ),
+ blues->zone[i].dsFlatEdge + cf2_intToFixed( 1 ) );
+ }
+
+ else
+ {
+ /* simply round captured edge */
+ dsNew = cf2_fixedRound( topHintEdge->dsCoord );
+ }
+
+ dsMove = dsNew - topHintEdge->dsCoord;
+ captured = TRUE;
+
+ break;
+ }
+ }
+ }
+
+ if ( captured )
+ {
+ /* move both edges and flag them `locked' */
+ if ( cf2_hint_isValid( bottomHintEdge ) )
+ {
+ bottomHintEdge->dsCoord += dsMove;
+ cf2_hint_lock( bottomHintEdge );
+ }
+
+ if ( cf2_hint_isValid( topHintEdge ) )
+ {
+ topHintEdge->dsCoord += dsMove;
+ cf2_hint_lock( topHintEdge );
+ }
+ }
+
+ return captured;
+ }
+
+
+/* END */
diff --git a/src/cff/cf2blues.h b/src/cff/cf2blues.h
new file mode 100644
index 0000000..2f38fca
--- /dev/null
+++ b/src/cff/cf2blues.h
@@ -0,0 +1,185 @@
+/***************************************************************************/
+/* */
+/* cf2blues.h */
+/* */
+/* Adobe's code for handling Blue Zones (specification). */
+/* */
+/* Copyright 2009-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+ /*
+ * A `CF2_Blues' object stores the blue zones (horizontal alignment
+ * zones) of a font. These are specified in the CFF private dictionary
+ * by `BlueValues', `OtherBlues', `FamilyBlues', and `FamilyOtherBlues'.
+ * Each zone is defined by a top and bottom edge in character space.
+ * Further, each zone is either a top zone or a bottom zone, as recorded
+ * by `bottomZone'.
+ *
+ * The maximum number of `BlueValues' and `FamilyBlues' is 7 each.
+ * However, these are combined to produce a total of 7 zones.
+ * Similarly, the maximum number of `OtherBlues' and `FamilyOtherBlues'
+ * is 5 and these are combined to produce an additional 5 zones.
+ *
+ * Blue zones are used to `capture' hints and force them to a common
+ * alignment point. This alignment is recorded in device space in
+ * `dsFlatEdge'. Except for this value, a `CF2_Blues' object could be
+ * constructed independently of scaling. Construction may occur once
+ * the matrix is known. Other features implemented in the Capture
+ * method are overshoot suppression, overshoot enforcement, and Blue
+ * Boost.
+ *
+ * Capture is determined by `BlueValues' and `OtherBlues', but the
+ * alignment point may be adjusted to the scaled flat edge of
+ * `FamilyBlues' or `FamilyOtherBlues'. No alignment is done to the
+ * curved edge of a zone.
+ *
+ */
+
+
+#ifndef __CF2BLUES_H__
+#define __CF2BLUES_H__
+
+
+#include "cf2glue.h"
+
+
+FT_BEGIN_HEADER
+
+
+ /*
+ * `CF2_Hint' is shared by `cf2hints.h' and
+ * `cf2blues.h', but `cf2blues.h' depends on
+ * `cf2hints.h', so define it here. Note: The typedef is in
+ * `cf2glue.h'.
+ *
+ */
+ enum
+ {
+ CF2_GhostBottom = 0x1, /* a single bottom edge */
+ CF2_GhostTop = 0x2, /* a single top edge */
+ CF2_PairBottom = 0x4, /* the bottom edge of a stem hint */
+ CF2_PairTop = 0x8, /* the top edge of a stem hint */
+ CF2_Locked = 0x10, /* this edge has been aligned */
+ /* by a blue zone */
+ CF2_Synthetic = 0x20 /* this edge was synthesized */
+ };
+
+
+ /*
+ * Default value for OS/2 typoAscender/Descender when their difference
+ * is not equal to `unitsPerEm'. The default is based on -250 and 1100
+ * in `CF2_Blues', assuming 1000 units per em here.
+ *
+ */
+ enum
+ {
+ CF2_ICF_Top = cf2_intToFixed( 880 ),
+ CF2_ICF_Bottom = cf2_intToFixed( -120 )
+ };
+
+
+ /*
+ * Constant used for hint adjustment and for synthetic em box hint
+ * placement.
+ */
+#define CF2_MIN_COUNTER cf2_floatToFixed( 0.5 )
+
+
+ /* shared typedef is in cf2glue.h */
+ struct CF2_HintRec_
+ {
+ CF2_UInt flags; /* attributes of the edge */
+ size_t index; /* index in original stem hint array */
+ /* (if not synthetic) */
+ CF2_Fixed csCoord;
+ CF2_Fixed dsCoord;
+ CF2_Fixed scale;
+ };
+
+
+ typedef struct CF2_BlueRec_
+ {
+ CF2_Fixed csBottomEdge;
+ CF2_Fixed csTopEdge;
+ CF2_Fixed csFlatEdge; /* may be from either local or Family zones */
+ CF2_Fixed dsFlatEdge; /* top edge of bottom zone or bottom edge */
+ /* of top zone (rounded) */
+ FT_Bool bottomZone;
+
+ } CF2_BlueRec;
+
+
+ /* max total blue zones is 12 */
+ enum
+ {
+ CF2_MAX_BLUES = 7,
+ CF2_MAX_OTHERBLUES = 5
+ };
+
+
+ typedef struct CF2_BluesRec_
+ {
+ CF2_Fixed scale;
+ CF2_UInt count;
+ FT_Bool suppressOvershoot;
+ FT_Bool doEmBoxHints;
+
+ CF2_Fixed blueScale;
+ CF2_Fixed blueShift;
+ CF2_Fixed blueFuzz;
+
+ CF2_Fixed boost;
+
+ CF2_HintRec emBoxTopEdge;
+ CF2_HintRec emBoxBottomEdge;
+
+ CF2_BlueRec zone[CF2_MAX_BLUES + CF2_MAX_OTHERBLUES];
+
+ } CF2_BluesRec, *CF2_Blues;
+
+
+ FT_LOCAL( void )
+ cf2_blues_init( CF2_Blues blues,
+ CF2_Font font );
+ FT_LOCAL( FT_Bool )
+ cf2_blues_capture( const CF2_Blues blues,
+ CF2_Hint bottomHintEdge,
+ CF2_Hint topHintEdge );
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2BLUES_H__ */
+
+
+/* END */
diff --git a/src/cff/cf2error.c b/src/cff/cf2error.c
new file mode 100644
index 0000000..b5595a3
--- /dev/null
+++ b/src/cff/cf2error.c
@@ -0,0 +1,52 @@
+/***************************************************************************/
+/* */
+/* cf2error.c */
+/* */
+/* Adobe's code for error handling (body). */
+/* */
+/* Copyright 2006-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#include "cf2ft.h"
+#include "cf2error.h"
+
+
+ FT_LOCAL_DEF( void )
+ cf2_setError( FT_Error* error,
+ FT_Error value )
+ {
+ if ( error && *error == 0 )
+ *error = value;
+ }
+
+
+/* END */
diff --git a/src/cff/cf2error.h b/src/cff/cf2error.h
new file mode 100644
index 0000000..6453ebc
--- /dev/null
+++ b/src/cff/cf2error.h
@@ -0,0 +1,119 @@
+/***************************************************************************/
+/* */
+/* cf2error.h */
+/* */
+/* Adobe's code for error handling (specification). */
+/* */
+/* Copyright 2006-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CF2ERROR_H__
+#define __CF2ERROR_H__
+
+
+#include FT_MODULE_ERRORS_H
+
+#undef __FTERRORS_H__
+
+#undef FT_ERR_PREFIX
+#define FT_ERR_PREFIX CF2_Err_
+#define FT_ERR_BASE FT_Mod_Err_CF2
+
+
+#include FT_ERRORS_H
+#include "cf2ft.h"
+
+
+FT_BEGIN_HEADER
+
+
+ /*
+ * A poor-man error facility.
+ *
+ * This code being written in vanilla C, doesn't have the luxury of a
+ * language-supported exception mechanism such as the one available in
+ * Java. Instead, we are stuck with using error codes that must be
+ * carefully managed and preserved. However, it is convenient for us to
+ * model our error mechanism on a Java-like exception mechanism.
+ * When we assign an error code we are thus `throwing' an error.
+ *
+ * The perservation of an error code is done by coding convention.
+ * Upon a function call if the error code is anything other than
+ * `FT_Err_Ok', which is guaranteed to be zero, we
+ * will return without altering that error. This will allow the
+ * error to propogate and be handled at the appropriate location in
+ * the code.
+ *
+ * This allows a style of code where the error code is initialized
+ * up front and a block of calls are made with the error code only
+ * being checked after the block. If a new error occurs, the original
+ * error will be preserved and a functional no-op should result in any
+ * subsequent function that has an initial error code not equal to
+ * `FT_Err_Ok'.
+ *
+ * Errors are encoded by calling the `FT_THROW' macro. For example,
+ *
+ * {
+ * FT_Error e;
+ *
+ *
+ * ...
+ * e = FT_THROW( Out_Of_Memory );
+ * }
+ *
+ */
+
+
+ /* Set error code to a particular value. */
+ FT_LOCAL( void )
+ cf2_setError( FT_Error* error,
+ FT_Error value );
+
+
+ /*
+ * A macro that conditionally sets an error code.
+ *
+ * This macro will first check whether `error' is set;
+ * if not, it will set it to `e'.
+ *
+ */
+#define CF2_SET_ERROR( error, e ) \
+ cf2_setError( error, FT_THROW( e ) )
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2ERROR_H__ */
+
+
+/* END */
diff --git a/src/cff/cf2fixed.h b/src/cff/cf2fixed.h
new file mode 100644
index 0000000..ed1452a
--- /dev/null
+++ b/src/cff/cf2fixed.h
@@ -0,0 +1,95 @@
+/***************************************************************************/
+/* */
+/* cf2fixed.h */
+/* */
+/* Adobe's code for Fixed Point Mathematics (specification only). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CF2FIXED_H__
+#define __CF2FIXED_H__
+
+
+FT_BEGIN_HEADER
+
+
+ /* rasterizer integer and fixed point arithmetic must be 32-bit */
+
+#define CF2_Fixed CF2_F16Dot16
+ typedef FT_Int32 CF2_Frac; /* 2.30 fixed point */
+
+
+#define CF2_FIXED_MAX ( (CF2_Fixed)0x7FFFFFFFL )
+#define CF2_FIXED_MIN ( (CF2_Fixed)0x80000000L )
+#define CF2_FIXED_ONE 0x10000L
+#define CF2_FIXED_EPSILON 0x0001
+
+ /* in C 89, left and right shift of negative numbers is */
+ /* implementation specific behaviour in the general case */
+
+#define cf2_intToFixed( i ) \
+ ( (CF2_Fixed)( (FT_UInt32)(i) << 16 ) )
+#define cf2_fixedToInt( x ) \
+ ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
+#define cf2_fixedRound( x ) \
+ ( (CF2_Fixed)( ( (x) + 0x8000 ) & 0xFFFF0000L ) )
+#define cf2_floatToFixed( f ) \
+ ( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) )
+#define cf2_fixedAbs( x ) \
+ ( (x) < 0 ? -(x) : (x) )
+#define cf2_fixedFloor( x ) \
+ ( (CF2_Fixed)( (x) & 0xFFFF0000L ) )
+#define cf2_fixedFraction( x ) \
+ ( (x) - cf2_fixedFloor( x ) )
+#define cf2_fracToFixed( x ) \
+ ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 ) \
+ : ( ( (x) + 0x2000 ) >> 14 ) )
+
+
+ /* signed numeric types */
+ typedef enum CF2_NumberType_
+ {
+ CF2_NumberFixed, /* 16.16 */
+ CF2_NumberFrac, /* 2.30 */
+ CF2_NumberInt /* 32.0 */
+
+ } CF2_NumberType;
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2FIXED_H__ */
+
+
+/* END */
diff --git a/src/cff/cf2font.c b/src/cff/cf2font.c
new file mode 100644
index 0000000..8b2331d
--- /dev/null
+++ b/src/cff/cf2font.c
@@ -0,0 +1,401 @@
+/***************************************************************************/
+/* */
+/* cf2font.c */
+/* */
+/* Adobe's code for font instances (body). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#include "cf2ft.h"
+
+#include "cf2glue.h"
+#include "cf2font.h"
+#include "cf2error.h"
+#include "cf2intrp.h"
+
+
+ /* Compute a stem darkening amount in character space. */
+ static void
+ cf2_computeDarkening( CF2_Fixed emRatio,
+ CF2_Fixed ppem,
+ CF2_Fixed stemWidth,
+ CF2_Fixed* darkenAmount,
+ CF2_Fixed boldenAmount,
+ FT_Bool stemDarkened )
+ {
+ /* Internal calculations are done in units per thousand for */
+ /* convenience. */
+ CF2_Fixed stemWidthPer1000, scaledStem;
+
+
+ *darkenAmount = 0;
+
+ if ( boldenAmount == 0 && !stemDarkened )
+ return;
+
+ /* protect against range problems and divide by zero */
+ if ( emRatio < cf2_floatToFixed( .01 ) )
+ return;
+
+ if ( stemDarkened )
+ {
+ /* convert from true character space to 1000 unit character space; */
+ /* add synthetic emboldening effect */
+
+ /* we have to assure that the computation of `scaledStem' */
+ /* and `stemWidthPer1000' don't overflow */
+
+ stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio );
+
+ if ( emRatio > CF2_FIXED_ONE &&
+ stemWidthPer1000 <= ( stemWidth + boldenAmount ) )
+ {
+ stemWidthPer1000 = 0; /* to pacify compiler */
+ scaledStem = cf2_intToFixed( 2333 );
+ }
+ else
+ {
+ scaledStem = FT_MulFix( stemWidthPer1000, ppem );
+
+ if ( ppem > CF2_FIXED_ONE &&
+ scaledStem <= stemWidthPer1000 )
+ scaledStem = cf2_intToFixed( 2333 );
+ }
+
+ /*
+ * Total darkening amount is computed in 1000 unit character space
+ * using the modified 5 part curve as Avalon rasterizer.
+ * The darkening amount is smaller for thicker stems.
+ * It becomes zero when the stem is thicker than 2.333 pixels.
+ *
+ * In Avalon rasterizer,
+ *
+ * darkenAmount = 0.5 pixels if scaledStem <= 0.5 pixels,
+ * darkenAmount = 0.333 pixels if 1 <= scaledStem <= 1.667 pixels,
+ * darkenAmount = 0 pixel if scaledStem >= 2.333 pixels,
+ *
+ * and piecewise linear in-between.
+ *
+ */
+ if ( scaledStem < cf2_intToFixed( 500 ) )
+ *darkenAmount = FT_DivFix( cf2_intToFixed( 400 ), ppem );
+
+ else if ( scaledStem < cf2_intToFixed( 1000 ) )
+ *darkenAmount = FT_DivFix( cf2_intToFixed( 525 ), ppem ) -
+ FT_MulFix( stemWidthPer1000,
+ cf2_floatToFixed( .25 ) );
+
+ else if ( scaledStem < cf2_intToFixed( 1667 ) )
+ *darkenAmount = FT_DivFix( cf2_intToFixed( 275 ), ppem );
+
+ else if ( scaledStem < cf2_intToFixed( 2333 ) )
+ *darkenAmount = FT_DivFix( cf2_intToFixed( 963 ), ppem ) -
+ FT_MulFix( stemWidthPer1000,
+ cf2_floatToFixed( .413 ) );
+
+ /* use half the amount on each side and convert back to true */
+ /* character space */
+ *darkenAmount = FT_DivFix( *darkenAmount, 2 * emRatio );
+ }
+
+ /* add synthetic emboldening effect in character space */
+ *darkenAmount += boldenAmount / 2;
+ }
+
+
+ /* set up values for the current FontDict and matrix */
+
+ /* caller's transform is adjusted for subpixel positioning */
+ static void
+ cf2_font_setup( CF2_Font font,
+ const CF2_Matrix* transform )
+ {
+ /* pointer to parsed font object */
+ CFF_Decoder* decoder = font->decoder;
+
+ FT_Bool needExtraSetup;
+
+ /* character space units */
+ CF2_Fixed boldenX = font->syntheticEmboldeningAmountX;
+ CF2_Fixed boldenY = font->syntheticEmboldeningAmountY;
+
+ CF2_Fixed ppem;
+
+
+ /* clear previous error */
+ font->error = FT_Err_Ok;
+
+ /* if a CID fontDict has changed, we need to recompute some cached */
+ /* data */
+ needExtraSetup = font->lastSubfont != cf2_getSubfont( decoder );
+
+ /* if ppem has changed, we need to recompute some cached data */
+ /* note: because of CID font matrix concatenation, ppem and transform */
+ /* do not necessarily track. */
+ ppem = cf2_getPpemY( decoder );
+ if ( font->ppem != ppem )
+ {
+ font->ppem = ppem;
+ needExtraSetup = TRUE;
+ }
+
+ /* copy hinted flag on each call */
+ font->hinted = font->renderingFlags & CF2_FlagsHinted;
+
+ /* determine if transform has changed; */
+ /* include Fontmatrix but ignore translation */
+ if ( ft_memcmp( transform,
+ &font->currentTransform,
+ 4 * sizeof ( CF2_Fixed ) ) != 0 )
+ {
+ /* save `key' information for `cache of one' matrix data; */
+ /* save client transform, without the translation */
+ font->currentTransform = *transform;
+ font->currentTransform.tx =
+ font->currentTransform.ty = cf2_intToFixed( 0 );
+
+ /* TODO: FreeType transform is simple scalar; for now, use identity */
+ /* for outer */
+ font->innerTransform = *transform;
+ font->outerTransform.a =
+ font->outerTransform.d = cf2_intToFixed( 1 );
+ font->outerTransform.b =
+ font->outerTransform.c = cf2_intToFixed( 0 );
+
+ needExtraSetup = TRUE;
+ }
+
+ /*
+ * font->darkened is set to true if there is a stem darkening request or
+ * the font is synthetic emboldened.
+ * font->darkened controls whether to adjust blue zones, winding order,
+ * and hinting.
+ *
+ */
+ if ( font->stemDarkened != ( font->renderingFlags & CF2_FlagsDarkened ) )
+ {
+ font->stemDarkened = font->renderingFlags & CF2_FlagsDarkened;
+
+ /* blue zones depend on darkened flag */
+ needExtraSetup = TRUE;
+ }
+
+ /* recompute variables that are dependent on transform or FontDict or */
+ /* darken flag */
+ if ( needExtraSetup )
+ {
+ /* StdVW is found in the private dictionary; */
+ /* recompute darkening amounts whenever private dictionary or */
+ /* transform change */
+ /* Note: a rendering flag turns darkening on or off, so we want to */
+ /* store the `on' amounts; */
+ /* darkening amount is computed in character space */
+ /* TODO: testing size-dependent darkening here; */
+ /* what to do for rotations? */
+
+ CF2_Fixed emRatio;
+ CF2_Fixed stdHW;
+ CF2_Int unitsPerEm = font->unitsPerEm;
+
+
+ if ( unitsPerEm == 0 )
+ unitsPerEm = 1000;
+
+ ppem = FT_MAX( cf2_intToFixed( 4 ),
+ font->ppem ); /* use minimum ppem of 4 */
+
+#if 0
+ /* since vstem is measured in the x-direction, we use the `a' member */
+ /* of the fontMatrix */
+ emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->a );
+#endif
+
+ /* Freetype does not preserve the fontMatrix when parsing; use */
+ /* unitsPerEm instead. */
+ /* TODO: check precision of this */
+ emRatio = cf2_intToFixed( 1000 ) / unitsPerEm;
+ font->stdVW = cf2_getStdVW( decoder );
+
+ if ( font->stdVW <= 0 )
+ font->stdVW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
+
+ if ( boldenX > 0 )
+ {
+ /* Ensure that boldenX is at least 1 pixel for synthetic bold font */
+ /* (similar to what Avalon does) */
+ boldenX = FT_MAX( boldenX,
+ FT_DivFix( cf2_intToFixed( unitsPerEm ), ppem ) );
+
+ /* Synthetic emboldening adds at least 1 pixel to darkenX, while */
+ /* stem darkening adds at most half pixel. Since the purpose of */
+ /* stem darkening (readability at small sizes) is met with */
+ /* synthetic emboldening, no need to add stem darkening for a */
+ /* synthetic bold font. */
+ cf2_computeDarkening( emRatio,
+ ppem,
+ font->stdVW,
+ &font->darkenX,
+ boldenX,
+ FALSE );
+ }
+ else
+ cf2_computeDarkening( emRatio,
+ ppem,
+ font->stdVW,
+ &font->darkenX,
+ 0,
+ font->stemDarkened );
+
+#if 0
+ /* since hstem is measured in the y-direction, we use the `d' member */
+ /* of the fontMatrix */
+ /* TODO: use the same units per em as above; check this */
+ emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->d );
+#endif
+
+ /* set the default stem width, because it must be the same for all */
+ /* family members; */
+ /* choose a constant for StdHW that depends on font contrast */
+ stdHW = cf2_getStdHW( decoder );
+
+ if ( stdHW > 0 && font->stdVW > 2 * stdHW )
+ font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
+ else
+ {
+ /* low contrast font gets less hstem darkening */
+ font->stdHW = FT_DivFix( cf2_intToFixed( 110 ), emRatio );
+ }
+
+ cf2_computeDarkening( emRatio,
+ ppem,
+ font->stdHW,
+ &font->darkenY,
+ boldenY,
+ font->stemDarkened );
+
+ if ( font->darkenX != 0 || font->darkenY != 0 )
+ font->darkened = TRUE;
+ else
+ font->darkened = FALSE;
+
+ font->reverseWinding = FALSE; /* initial expectation is CCW */
+
+ /* compute blue zones for this instance */
+ cf2_blues_init( &font->blues, font );
+ }
+ }
+
+
+ /* equivalent to AdobeGetOutline */
+ FT_LOCAL_DEF( FT_Error )
+ cf2_getGlyphOutline( CF2_Font font,
+ CF2_Buffer charstring,
+ const CF2_Matrix* transform,
+ CF2_F16Dot16* glyphWidth )
+ {
+ FT_Error lastError = FT_Err_Ok;
+
+ FT_Vector translation;
+
+#if 0
+ FT_Vector advancePoint;
+#endif
+
+ CF2_Fixed advWidth = 0;
+ FT_Bool needWinding;
+
+
+ /* Note: use both integer and fraction for outlines. This allows bbox */
+ /* to come out directly. */
+
+ translation.x = transform->tx;
+ translation.y = transform->ty;
+
+ /* set up values based on transform */
+ cf2_font_setup( font, transform );
+ if ( font->error )
+ goto exit; /* setup encountered an error */
+
+ /* reset darken direction */
+ font->reverseWinding = FALSE;
+
+ /* winding order only affects darkening */
+ needWinding = font->darkened;
+
+ while ( 1 )
+ {
+ /* reset output buffer */
+ cf2_outline_reset( &font->outline );
+
+ /* build the outline, passing the full translation */
+ cf2_interpT2CharString( font,
+ charstring,
+ (CF2_OutlineCallbacks)&font->outline,
+ &translation,
+ FALSE,
+ 0,
+ 0,
+ &advWidth );
+
+ if ( font->error )
+ goto exit;
+
+ if ( !needWinding )
+ break;
+
+ /* check winding order */
+ if ( font->outline.root.windingMomentum >= 0 ) /* CFF is CCW */
+ break;
+
+ /* invert darkening and render again */
+ /* TODO: this should be a parameter to getOutline-computeOffset */
+ font->reverseWinding = TRUE;
+
+ needWinding = FALSE; /* exit after next iteration */
+ }
+
+ /* finish storing client outline */
+ cf2_outline_close( &font->outline );
+
+ exit:
+ /* FreeType just wants the advance width; there is no translation */
+ *glyphWidth = advWidth;
+
+ /* free resources and collect errors from objects we've used */
+ cf2_setError( &font->error, lastError );
+
+ return font->error;
+ }
+
+
+/* END */
diff --git a/src/cff/cf2font.h b/src/cff/cf2font.h
new file mode 100644
index 0000000..f9dd1bb
--- /dev/null
+++ b/src/cff/cf2font.h
@@ -0,0 +1,114 @@
+/***************************************************************************/
+/* */
+/* cf2font.h */
+/* */
+/* Adobe's code for font instances (specification). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CF2FONT_H__
+#define __CF2FONT_H__
+
+
+#include "cf2ft.h"
+#include "cf2blues.h"
+
+
+FT_BEGIN_HEADER
+
+
+#define CF2_OPERAND_STACK_SIZE 48
+#define CF2_MAX_SUBR 10 /* maximum subroutine nesting */
+
+
+ /* typedef is in `cf2glue.h' */
+ struct CF2_FontRec_
+ {
+ FT_Memory memory;
+ FT_Error error; /* shared error for this instance */
+
+ CF2_RenderingFlags renderingFlags;
+
+ /* variables that depend on Transform: */
+ /* the following have zero translation; */
+ /* inner * outer = font * original */
+
+ CF2_Matrix currentTransform; /* original client matrix */
+ CF2_Matrix innerTransform; /* for hinting; erect, scaled */
+ CF2_Matrix outerTransform; /* post hinting; includes rotations */
+ CF2_Fixed ppem; /* transform-dependent */
+
+ CF2_Int unitsPerEm;
+
+ CF2_Fixed syntheticEmboldeningAmountX; /* character space units */
+ CF2_Fixed syntheticEmboldeningAmountY; /* character space units */
+
+ /* FreeType related members */
+ CF2_OutlineRec outline; /* freetype glyph outline functions */
+ CFF_Decoder* decoder;
+ CFF_SubFont lastSubfont; /* FreeType parsed data; */
+ /* top font or subfont */
+
+ /* these flags can vary from one call to the next */
+ FT_Bool hinted;
+ FT_Bool darkened; /* true if stemDarkened or synthetic bold */
+ /* i.e. darkenX != 0 || darkenY != 0 */
+ FT_Bool stemDarkened;
+
+ /* variables that depend on both FontDict and Transform */
+ CF2_Fixed stdVW; /* in character space; depends on dict entry */
+ CF2_Fixed stdHW; /* in character space; depends on dict entry */
+ CF2_Fixed darkenX; /* character space units */
+ CF2_Fixed darkenY; /* depends on transform */
+ /* and private dict (StdVW) */
+ FT_Bool reverseWinding; /* darken assuming */
+ /* counterclockwise winding */
+
+ CF2_BluesRec blues; /* computed zone data */
+ };
+
+
+ FT_LOCAL( FT_Error )
+ cf2_getGlyphOutline( CF2_Font font,
+ CF2_Buffer charstring,
+ const CF2_Matrix* transform,
+ CF2_F16Dot16* glyphWidth );
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2FONT_H__ */
+
+
+/* END */
diff --git a/src/cff/cf2ft.c b/src/cff/cf2ft.c
new file mode 100644
index 0000000..c09a024
--- /dev/null
+++ b/src/cff/cf2ft.c
@@ -0,0 +1,639 @@
+/***************************************************************************/
+/* */
+/* cf2ft.c */
+/* */
+/* FreeType Glue Component to Adobe's Interpreter (body). */
+/* */
+/* Copyright 2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#include "cf2ft.h"
+#include FT_INTERNAL_DEBUG_H
+
+#include "cf2font.h"
+#include "cf2error.h"
+
+
+#define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */
+
+
+ /*
+ * This check should avoid most internal overflow cases. Clients should
+ * generally respond to `Glyph_Too_Big' by getting a glyph outline
+ * at EM size, scaling it and filling it as a graphics operation.
+ *
+ */
+ static FT_Error
+ cf2_checkTransform( const CF2_Matrix* transform,
+ CF2_Int unitsPerEm )
+ {
+ CF2_Fixed maxScale;
+
+
+ FT_ASSERT( unitsPerEm > 0 );
+
+ FT_ASSERT( transform->a > 0 && transform->d > 0 );
+ FT_ASSERT( transform->b == 0 && transform->c == 0 );
+ FT_ASSERT( transform->tx == 0 && transform->ty == 0 );
+
+ if ( unitsPerEm > 0x7FFF )
+ return FT_THROW( Glyph_Too_Big );
+
+ maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) );
+
+ if ( transform->a > maxScale || transform->d > maxScale )
+ return FT_THROW( Glyph_Too_Big );
+
+ return FT_Err_Ok;
+ }
+
+
+ static void
+ cf2_setGlyphWidth( CF2_Outline outline,
+ CF2_Fixed width )
+ {
+ CFF_Decoder* decoder = outline->decoder;
+
+
+ FT_ASSERT( decoder );
+
+ decoder->glyph_width = cf2_fixedToInt( width );
+ }
+
+
+ /* Clean up font instance. */
+ static void
+ cf2_free_instance( void* ptr )
+ {
+ CF2_Font font = (CF2_Font)ptr;
+
+
+ if ( font )
+ {
+ FT_Memory memory = font->memory;
+
+
+ (void)memory;
+ }
+ }
+
+
+ /********************************************/
+ /* */
+ /* functions for handling client outline; */
+ /* FreeType uses coordinates in 26.6 format */
+ /* */
+ /********************************************/
+
+ static void
+ cf2_builder_moveTo( CF2_OutlineCallbacks callbacks,
+ const CF2_CallbackParams params )
+ {
+ /* downcast the object pointer */
+ CF2_Outline outline = (CF2_Outline)callbacks;
+ CFF_Builder* builder;
+
+ (void)params; /* only used in debug mode */
+
+
+ FT_ASSERT( outline && outline->decoder );
+ FT_ASSERT( params->op == CF2_PathOpMoveTo );
+
+ builder = &outline->decoder->builder;
+
+ /* note: two successive moves simply close the contour twice */
+ cff_builder_close_contour( builder );
+ builder->path_begun = 0;
+ }
+
+
+ static void
+ cf2_builder_lineTo( CF2_OutlineCallbacks callbacks,
+ const CF2_CallbackParams params )
+ {
+ /* downcast the object pointer */
+ CF2_Outline outline = (CF2_Outline)callbacks;
+ CFF_Builder* builder;
+
+
+ FT_ASSERT( outline && outline->decoder );
+ FT_ASSERT( params->op == CF2_PathOpLineTo );
+
+ builder = &outline->decoder->builder;
+
+ if ( !builder->path_begun )
+ {
+ /* record the move before the line; also check points and set */
+ /* `path_begun' */
+ cff_builder_start_point( builder,
+ params->pt0.x,
+ params->pt0.y );
+ }
+
+ /* `cff_builder_add_point1' includes a check_points call for one point */
+ cff_builder_add_point1( builder,
+ params->pt1.x,
+ params->pt1.y );
+ }
+
+
+ static void
+ cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks,
+ const CF2_CallbackParams params )
+ {
+ /* downcast the object pointer */
+ CF2_Outline outline = (CF2_Outline)callbacks;
+ CFF_Builder* builder;
+
+
+ FT_ASSERT( outline && outline->decoder );
+ FT_ASSERT( params->op == CF2_PathOpCubeTo );
+
+ builder = &outline->decoder->builder;
+
+ if ( !builder->path_begun )
+ {
+ /* record the move before the line; also check points and set */
+ /* `path_begun' */
+ cff_builder_start_point( builder,
+ params->pt0.x,
+ params->pt0.y );
+ }
+
+ /* prepare room for 3 points: 2 off-curve, 1 on-curve */
+ cff_check_points( builder, 3 );
+
+ cff_builder_add_point( builder,
+ params->pt1.x,
+ params->pt1.y, 0 );
+ cff_builder_add_point( builder,
+ params->pt2.x,
+ params->pt2.y, 0 );
+ cff_builder_add_point( builder,
+ params->pt3.x,
+ params->pt3.y, 1 );
+ }
+
+
+ static void
+ cf2_outline_init( CF2_Outline outline,
+ FT_Memory memory,
+ FT_Error* error )
+ {
+ FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) );
+
+ outline->root.memory = memory;
+ outline->root.error = error;
+
+ outline->root.moveTo = cf2_builder_moveTo;
+ outline->root.lineTo = cf2_builder_lineTo;
+ outline->root.cubeTo = cf2_builder_cubeTo;
+ }
+
+
+ /* get scaling and hint flag from GlyphSlot */
+ static void
+ cf2_getScaleAndHintFlag( CFF_Decoder* decoder,
+ CF2_Fixed* x_scale,
+ CF2_Fixed* y_scale,
+ FT_Bool* hinted,
+ FT_Bool* scaled )
+ {
+ FT_ASSERT( decoder && decoder->builder.glyph );
+
+ /* note: FreeType scale includes a factor of 64 */
+ *hinted = decoder->builder.glyph->hint;
+ *scaled = decoder->builder.glyph->scaled;
+
+ if ( *hinted )
+ {
+ *x_scale = FT_DivFix( decoder->builder.glyph->x_scale,
+ cf2_intToFixed( 64 ) );
+ *y_scale = FT_DivFix( decoder->builder.glyph->y_scale,
+ cf2_intToFixed( 64 ) );
+ }
+ else
+ {
+ /* for unhinted outlines, `cff_slot_load' does the scaling, */
+ /* thus render at `unity' scale */
+
+ *x_scale = 0x0400; /* 1/64 as 16.16 */
+ *y_scale = 0x0400;
+ }
+ }
+
+
+ /* get units per em from `FT_Face' */
+ /* TODO: should handle font matrix concatenation? */
+ static FT_UShort
+ cf2_getUnitsPerEm( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->builder.face );
+ FT_ASSERT( decoder->builder.face->root.units_per_EM );
+
+ return decoder->builder.face->root.units_per_EM;
+ }
+
+
+ /* Main entry point: Render one glyph. */
+ FT_LOCAL_DEF( FT_Error )
+ cf2_decoder_parse_charstrings( CFF_Decoder* decoder,
+ FT_Byte* charstring_base,
+ FT_ULong charstring_len )
+ {
+ FT_Memory memory;
+ FT_Error error = FT_Err_Ok;
+ CF2_Font font;
+
+
+ FT_ASSERT( decoder && decoder->cff );
+
+ memory = decoder->builder.memory;
+
+ /* CF2 data is saved here across glyphs */
+ font = (CF2_Font)decoder->cff->cf2_instance.data;
+
+ /* on first glyph, allocate instance structure */
+ if ( decoder->cff->cf2_instance.data == NULL )
+ {
+ decoder->cff->cf2_instance.finalizer =
+ (FT_Generic_Finalizer)cf2_free_instance;
+
+ if ( FT_ALLOC( decoder->cff->cf2_instance.data,
+ sizeof ( CF2_FontRec ) ) )
+ return FT_THROW( Out_Of_Memory );
+
+ font = (CF2_Font)decoder->cff->cf2_instance.data;
+
+ font->memory = memory;
+
+ /* initialize a client outline, to be shared by each glyph rendered */
+ cf2_outline_init( &font->outline, font->memory, &font->error );
+ }
+
+ /* save decoder; it is a stack variable and will be different on each */
+ /* call */
+ font->decoder = decoder;
+ font->outline.decoder = decoder;
+
+ {
+ /* build parameters for Adobe engine */
+
+ CFF_Builder* builder = &decoder->builder;
+ CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face );
+
+ /* local error */
+ FT_Error error2 = FT_Err_Ok;
+ CF2_BufferRec buf;
+ CF2_Matrix transform;
+ CF2_F16Dot16 glyphWidth;
+
+ FT_Bool hinted;
+ FT_Bool scaled;
+
+
+ /* FreeType has already looked up the GID; convert to */
+ /* `RegionBuffer', assuming that the input has been validated */
+ FT_ASSERT( charstring_base + charstring_len >= charstring_base );
+
+ FT_ZERO( &buf );
+ buf.start =
+ buf.ptr = charstring_base;
+ buf.end = charstring_base + charstring_len;
+
+ FT_ZERO( &transform );
+
+ cf2_getScaleAndHintFlag( decoder,
+ &transform.a,
+ &transform.d,
+ &hinted,
+ &scaled );
+
+ font->renderingFlags = 0;
+ if ( hinted )
+ font->renderingFlags |= CF2_FlagsHinted;
+ if ( scaled && !driver->no_stem_darkening )
+ font->renderingFlags |= CF2_FlagsDarkened;
+
+ /* now get an outline for this glyph; */
+ /* also get units per em to validate scale */
+ font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder );
+
+ error2 = cf2_checkTransform( &transform, font->unitsPerEm );
+ if ( error2 )
+ return error2;
+
+ error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth );
+ if ( error2 )
+ return FT_ERR( Invalid_File_Format );
+
+ cf2_setGlyphWidth( &font->outline, glyphWidth );
+
+ return FT_Err_Ok;
+ }
+ }
+
+
+ /* get pointer to current FreeType subfont (based on current glyphID) */
+ FT_LOCAL_DEF( CFF_SubFont )
+ cf2_getSubfont( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return decoder->current_subfont;
+ }
+
+
+ /* get `y_ppem' from `CFF_Size' */
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_getPpemY( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder &&
+ decoder->builder.face &&
+ decoder->builder.face->root.size );
+ FT_ASSERT( decoder->builder.face->root.size->metrics.y_ppem );
+
+ return cf2_intToFixed(
+ decoder->builder.face->root.size->metrics.y_ppem );
+ }
+
+
+ /* get standard stem widths for the current subfont; */
+ /* FreeType stores these as integer font units */
+ /* (note: variable names seem swapped) */
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_getStdVW( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return cf2_intToFixed(
+ decoder->current_subfont->private_dict.standard_height );
+ }
+
+
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_getStdHW( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return cf2_intToFixed(
+ decoder->current_subfont->private_dict.standard_width );
+ }
+
+
+ /* note: FreeType stores 1000 times the actual value for `BlueScale' */
+ FT_LOCAL_DEF( void )
+ cf2_getBlueMetrics( CFF_Decoder* decoder,
+ CF2_Fixed* blueScale,
+ CF2_Fixed* blueShift,
+ CF2_Fixed* blueFuzz )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ *blueScale = FT_DivFix(
+ decoder->current_subfont->private_dict.blue_scale,
+ cf2_intToFixed( 1000 ) );
+ *blueShift = cf2_intToFixed(
+ decoder->current_subfont->private_dict.blue_shift );
+ *blueFuzz = cf2_intToFixed(
+ decoder->current_subfont->private_dict.blue_fuzz );
+ }
+
+
+ /* get blue values counts and arrays; the FreeType parser has validated */
+ /* the counts and verified that each is an even number */
+ FT_LOCAL_DEF( void )
+ cf2_getBlueValues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ *count = decoder->current_subfont->private_dict.num_blue_values;
+ *data = (FT_Pos*)
+ &decoder->current_subfont->private_dict.blue_values;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_getOtherBlues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ *count = decoder->current_subfont->private_dict.num_other_blues;
+ *data = (FT_Pos*)
+ &decoder->current_subfont->private_dict.other_blues;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_getFamilyBlues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ *count = decoder->current_subfont->private_dict.num_family_blues;
+ *data = (FT_Pos*)
+ &decoder->current_subfont->private_dict.family_blues;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_getFamilyOtherBlues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ *count = decoder->current_subfont->private_dict.num_family_other_blues;
+ *data = (FT_Pos*)
+ &decoder->current_subfont->private_dict.family_other_blues;
+ }
+
+
+ FT_LOCAL_DEF( CF2_Int )
+ cf2_getLanguageGroup( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return decoder->current_subfont->private_dict.language_group;
+ }
+
+
+ /* convert unbiased subroutine index to `CF2_Buffer' and */
+ /* return 0 on success */
+ FT_LOCAL_DEF( CF2_Int )
+ cf2_initGlobalRegionBuffer( CFF_Decoder* decoder,
+ CF2_UInt idx,
+ CF2_Buffer buf )
+ {
+ FT_ASSERT( decoder && decoder->globals );
+
+ FT_ZERO( buf );
+
+ idx += decoder->globals_bias;
+ if ( idx >= decoder->num_globals )
+ return TRUE; /* error */
+
+ buf->start =
+ buf->ptr = decoder->globals[idx];
+ buf->end = decoder->globals[idx + 1];
+
+ return FALSE; /* success */
+ }
+
+
+ /* convert AdobeStandardEncoding code to CF2_Buffer; */
+ /* used for seac component */
+ FT_LOCAL_DEF( FT_Error )
+ cf2_getSeacComponent( CFF_Decoder* decoder,
+ CF2_UInt code,
+ CF2_Buffer buf )
+ {
+ CF2_Int gid;
+ FT_Byte* charstring;
+ FT_ULong len;
+ FT_Error error;
+
+
+ FT_ASSERT( decoder );
+
+ FT_ZERO( buf );
+
+ gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code );
+ if ( gid < 0 )
+ return FT_THROW( Invalid_Glyph_Format );
+
+ error = cff_get_glyph_data( decoder->builder.face,
+ gid,
+ &charstring,
+ &len );
+ /* TODO: for now, just pass the FreeType error through */
+ if ( error )
+ return error;
+
+ /* assume input has been validated */
+ FT_ASSERT( charstring + len >= charstring );
+
+ buf->start = charstring;
+ buf->end = charstring + len;
+ buf->ptr = buf->start;
+
+ return FT_Err_Ok;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_freeSeacComponent( CFF_Decoder* decoder,
+ CF2_Buffer buf )
+ {
+ FT_ASSERT( decoder );
+
+ cff_free_glyph_data( decoder->builder.face,
+ (FT_Byte**)&buf->start,
+ (FT_ULong)( buf->end - buf->start ) );
+ }
+
+
+ FT_LOCAL_DEF( CF2_Int )
+ cf2_initLocalRegionBuffer( CFF_Decoder* decoder,
+ CF2_UInt idx,
+ CF2_Buffer buf )
+ {
+ FT_ASSERT( decoder && decoder->locals );
+
+ FT_ZERO( buf );
+
+ idx += decoder->locals_bias;
+ if ( idx >= decoder->num_locals )
+ return TRUE; /* error */
+
+ buf->start =
+ buf->ptr = decoder->locals[idx];
+ buf->end = decoder->locals[idx + 1];
+
+ return FALSE; /* success */
+ }
+
+
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_getDefaultWidthX( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return cf2_intToFixed(
+ decoder->current_subfont->private_dict.default_width );
+ }
+
+
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_getNominalWidthX( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return cf2_intToFixed(
+ decoder->current_subfont->private_dict.nominal_width );
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_outline_reset( CF2_Outline outline )
+ {
+ CFF_Decoder* decoder = outline->decoder;
+
+
+ FT_ASSERT( decoder );
+
+ outline->root.windingMomentum = 0;
+
+ FT_GlyphLoader_Rewind( decoder->builder.loader );
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_outline_close( CF2_Outline outline )
+ {
+ CFF_Decoder* decoder = outline->decoder;
+
+
+ FT_ASSERT( decoder );
+
+ cff_builder_close_contour( &decoder->builder );
+
+ FT_GlyphLoader_Add( decoder->builder.loader );
+ }
+
+
+/* END */
diff --git a/src/cff/cf2ft.h b/src/cff/cf2ft.h
new file mode 100644
index 0000000..731da3c
--- /dev/null
+++ b/src/cff/cf2ft.h
@@ -0,0 +1,147 @@
+/***************************************************************************/
+/* */
+/* cf2ft.h */
+/* */
+/* FreeType Glue Component to Adobe's Interpreter (specification). */
+/* */
+/* Copyright 2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CF2FT_H__
+#define __CF2FT_H__
+
+
+#include "cf2types.h"
+
+
+ /* TODO: disable asserts for now */
+#define CF2_NDEBUG
+
+
+#include FT_SYSTEM_H
+
+#include "cf2glue.h"
+#include "cffgload.h" /* for CFF_Decoder */
+
+
+FT_BEGIN_HEADER
+
+
+ FT_LOCAL( FT_Error )
+ cf2_decoder_parse_charstrings( CFF_Decoder* decoder,
+ FT_Byte* charstring_base,
+ FT_ULong charstring_len );
+
+ FT_LOCAL( CFF_SubFont )
+ cf2_getSubfont( CFF_Decoder* decoder );
+
+
+ FT_LOCAL( CF2_Fixed )
+ cf2_getPpemY( CFF_Decoder* decoder );
+ FT_LOCAL( CF2_Fixed )
+ cf2_getStdVW( CFF_Decoder* decoder );
+ FT_LOCAL( CF2_Fixed )
+ cf2_getStdHW( CFF_Decoder* decoder );
+
+ FT_LOCAL( void )
+ cf2_getBlueMetrics( CFF_Decoder* decoder,
+ CF2_Fixed* blueScale,
+ CF2_Fixed* blueShift,
+ CF2_Fixed* blueFuzz );
+ FT_LOCAL( void )
+ cf2_getBlueValues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data );
+ FT_LOCAL( void )
+ cf2_getOtherBlues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data );
+ FT_LOCAL( void )
+ cf2_getFamilyBlues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data );
+ FT_LOCAL( void )
+ cf2_getFamilyOtherBlues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data );
+
+ FT_LOCAL( CF2_Int )
+ cf2_getLanguageGroup( CFF_Decoder* decoder );
+
+ FT_LOCAL( CF2_Int )
+ cf2_initGlobalRegionBuffer( CFF_Decoder* decoder,
+ CF2_UInt idx,
+ CF2_Buffer buf );
+ FT_LOCAL( FT_Error )
+ cf2_getSeacComponent( CFF_Decoder* decoder,
+ CF2_UInt code,
+ CF2_Buffer buf );
+ FT_LOCAL( void )
+ cf2_freeSeacComponent( CFF_Decoder* decoder,
+ CF2_Buffer buf );
+ FT_LOCAL( CF2_Int )
+ cf2_initLocalRegionBuffer( CFF_Decoder* decoder,
+ CF2_UInt idx,
+ CF2_Buffer buf );
+
+ FT_LOCAL( CF2_Fixed )
+ cf2_getDefaultWidthX( CFF_Decoder* decoder );
+ FT_LOCAL( CF2_Fixed )
+ cf2_getNominalWidthX( CFF_Decoder* decoder );
+
+
+ /*
+ * FreeType client outline
+ *
+ * process output from the charstring interpreter
+ */
+ typedef struct CF2_OutlineRec_
+ {
+ CF2_OutlineCallbacksRec root; /* base class must be first */
+ CFF_Decoder* decoder;
+
+ } CF2_OutlineRec, *CF2_Outline;
+
+
+ FT_LOCAL( void )
+ cf2_outline_reset( CF2_Outline outline );
+ FT_LOCAL( void )
+ cf2_outline_close( CF2_Outline outline );
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2FT_H__ */
+
+
+/* END */
diff --git a/src/cff/cf2glue.h b/src/cff/cf2glue.h
new file mode 100644
index 0000000..a24da39
--- /dev/null
+++ b/src/cff/cf2glue.h
@@ -0,0 +1,144 @@
+/***************************************************************************/
+/* */
+/* cf2glue.h */
+/* */
+/* Adobe's code for shared stuff (specification only). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CF2GLUE_H__
+#define __CF2GLUE_H__
+
+
+/* common includes for other modules */
+#include "cf2error.h"
+#include "cf2fixed.h"
+#include "cf2arrst.h"
+#include "cf2read.h"
+
+
+FT_BEGIN_HEADER
+
+
+ /* rendering parameters */
+
+ /* apply hints to rendered glyphs */
+#define CF2_FlagsHinted 1
+ /* for testing */
+#define CF2_FlagsDarkened 2
+
+ /* type for holding the flags */
+ typedef CF2_Int CF2_RenderingFlags;
+
+
+ /* elements of a glyph outline */
+ typedef enum CF2_PathOp_
+ {
+ CF2_PathOpMoveTo = 1, /* change the current point */
+ CF2_PathOpLineTo = 2, /* line */
+ CF2_PathOpQuadTo = 3, /* quadratic curve */
+ CF2_PathOpCubeTo = 4 /* cubic curve */
+
+ } CF2_PathOp;
+
+
+ /* a matrix of fixed point values */
+ typedef struct CF2_Matrix_
+ {
+ CF2_F16Dot16 a;
+ CF2_F16Dot16 b;
+ CF2_F16Dot16 c;
+ CF2_F16Dot16 d;
+ CF2_F16Dot16 tx;
+ CF2_F16Dot16 ty;
+
+ } CF2_Matrix;
+
+
+ /* these typedefs are needed by more than one header file */
+ /* and gcc compiler doesn't allow redefinition */
+ typedef struct CF2_FontRec_ CF2_FontRec, *CF2_Font;
+ typedef struct CF2_HintRec_ CF2_HintRec, *CF2_Hint;
+
+
+ /* A common structure for all callback parameters. */
+ /* */
+ /* Some members may be unused. For example, `pt0' is not used for */
+ /* `moveTo' and `pt3' is not used for `quadTo'. The initial point `pt0' */
+ /* is included for each path element for generality; curve conversions */
+ /* need it. The `op' parameter allows one function to handle multiple */
+ /* element types. */
+
+ typedef struct CF2_CallbackParamsRec_
+ {
+ FT_Vector pt0;
+ FT_Vector pt1;
+ FT_Vector pt2;
+ FT_Vector pt3;
+
+ CF2_Int op;
+
+ } CF2_CallbackParamsRec, *CF2_CallbackParams;
+
+
+ /* forward reference */
+ typedef struct CF2_OutlineCallbacksRec_ CF2_OutlineCallbacksRec,
+ *CF2_OutlineCallbacks;
+
+ /* callback function pointers */
+ typedef void
+ (*CF2_Callback_Type)( CF2_OutlineCallbacks callbacks,
+ const CF2_CallbackParams params );
+
+
+ struct CF2_OutlineCallbacksRec_
+ {
+ CF2_Callback_Type moveTo;
+ CF2_Callback_Type lineTo;
+ CF2_Callback_Type quadTo;
+ CF2_Callback_Type cubeTo;
+
+ CF2_Int windingMomentum; /* for winding order detection */
+
+ FT_Memory memory;
+ FT_Error* error;
+ };
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2GLUE_H__ */
+
+
+/* END */
diff --git a/src/cff/cf2hints.c b/src/cff/cf2hints.c
new file mode 100644
index 0000000..1666e4f
--- /dev/null
+++ b/src/cff/cf2hints.c
@@ -0,0 +1,1733 @@
+/***************************************************************************/
+/* */
+/* cf2hints.c */
+/* */
+/* Adobe's code for handling CFF hints (body). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#include "cf2ft.h"
+#include FT_INTERNAL_DEBUG_H
+
+#include "cf2glue.h"
+#include "cf2font.h"
+#include "cf2hints.h"
+#include "cf2intrp.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_cf2hints
+
+
+ typedef struct CF2_HintMoveRec_
+ {
+ size_t j; /* index of upper hint map edge */
+ CF2_Fixed moveUp; /* adjustment to optimum position */
+
+ } CF2_HintMoveRec, *CF2_HintMove;
+
+
+ /* Compute angular momentum for winding order detection. It is called */
+ /* for all lines and curves, but not necessarily in element order. */
+ static CF2_Int
+ cf2_getWindingMomentum( CF2_Fixed x1,
+ CF2_Fixed y1,
+ CF2_Fixed x2,
+ CF2_Fixed y2 )
+ {
+ /* cross product of pt1 position from origin with pt2 position from */
+ /* pt1; we reduce the precision so that the result fits into 32 bits */
+
+ return ( x1 >> 16 ) * ( ( y2 - y1 ) >> 16 ) -
+ ( y1 >> 16 ) * ( ( x2 - x1 ) >> 16 );
+ }
+
+
+ /*
+ * Construct from a StemHint; this is used as a parameter to
+ * `cf2_blues_capture'.
+ * `hintOrigin' is the character space displacement of a seac accent.
+ * Adjust stem hint for darkening here.
+ *
+ */
+ static void
+ cf2_hint_init( CF2_Hint hint,
+ const CF2_ArrStack stemHintArray,
+ size_t indexStemHint,
+ const CF2_Font font,
+ CF2_Fixed hintOrigin,
+ CF2_Fixed scale,
+ FT_Bool bottom )
+ {
+ CF2_Fixed width;
+ const CF2_StemHintRec* stemHint;
+
+
+ FT_ZERO( hint );
+
+ stemHint = (const CF2_StemHintRec*)cf2_arrstack_getPointer(
+ stemHintArray,
+ indexStemHint );
+
+ width = stemHint->max - stemHint->min;
+
+ if ( width == cf2_intToFixed( -21 ) )
+ {
+ /* ghost bottom */
+
+ if ( bottom )
+ {
+ hint->csCoord = stemHint->max;
+ hint->flags = CF2_GhostBottom;
+ }
+ else
+ hint->flags = 0;
+ }
+
+ else if ( width == cf2_intToFixed( -20 ) )
+ {
+ /* ghost top */
+
+ if ( bottom )
+ hint->flags = 0;
+ else
+ {
+ hint->csCoord = stemHint->min;
+ hint->flags = CF2_GhostTop;
+ }
+ }
+
+ else if ( width < 0 )
+ {
+ /* inverted pair */
+
+ /*
+ * Hints with negative widths were produced by an early version of a
+ * non-Adobe font tool. The Type 2 spec allows edge (ghost) hints
+ * with negative widths, but says
+ *
+ * All other negative widths have undefined meaning.
+ *
+ * CoolType has a silent workaround that negates the hint width; for
+ * permissive mode, we do the same here.
+ *
+ * Note: Such fonts cannot use ghost hints, but should otherwise work.
+ * Note: Some poor hints in our faux fonts can produce negative
+ * widths at some blends. For example, see a light weight of
+ * `u' in ASerifMM.
+ *
+ */
+ if ( bottom )
+ {
+ hint->csCoord = stemHint->max;
+ hint->flags = CF2_PairBottom;
+ }
+ else
+ {
+ hint->csCoord = stemHint->min;
+ hint->flags = CF2_PairTop;
+ }
+ }
+
+ else
+ {
+ /* normal pair */
+
+ if ( bottom )
+ {
+ hint->csCoord = stemHint->min;
+ hint->flags = CF2_PairBottom;
+ }
+ else
+ {
+ hint->csCoord = stemHint->max;
+ hint->flags = CF2_PairTop;
+ }
+ }
+
+ /* Now that ghost hints have been detected, adjust this edge for */
+ /* darkening. Bottoms are not changed; tops are incremented by twice */
+ /* `darkenY'. */
+ if ( cf2_hint_isTop( hint ) )
+ hint->csCoord += 2 * font->darkenY;
+
+ hint->csCoord += hintOrigin;
+ hint->scale = scale;
+ hint->index = indexStemHint; /* index in original stem hint array */
+
+ /* if original stem hint has been used, use the same position */
+ if ( hint->flags != 0 && stemHint->used )
+ {
+ if ( cf2_hint_isTop( hint ) )
+ hint->dsCoord = stemHint->maxDS;
+ else
+ hint->dsCoord = stemHint->minDS;
+
+ cf2_hint_lock( hint );
+ }
+ else
+ hint->dsCoord = FT_MulFix( hint->csCoord, scale );
+ }
+
+
+ /* initialize an invalid hint map element */
+ static void
+ cf2_hint_initZero( CF2_Hint hint )
+ {
+ FT_ZERO( hint );
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ cf2_hint_isValid( const CF2_Hint hint )
+ {
+ return hint->flags != 0;
+ }
+
+
+ static FT_Bool
+ cf2_hint_isPair( const CF2_Hint hint )
+ {
+ return ( hint->flags &
+ ( CF2_PairBottom | CF2_PairTop ) ) != 0;
+ }
+
+
+ static FT_Bool
+ cf2_hint_isPairTop( const CF2_Hint hint )
+ {
+ return ( hint->flags & CF2_PairTop ) != 0;
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ cf2_hint_isTop( const CF2_Hint hint )
+ {
+ return ( hint->flags &
+ ( CF2_PairTop | CF2_GhostTop ) ) != 0;
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ cf2_hint_isBottom( const CF2_Hint hint )
+ {
+ return ( hint->flags &
+ ( CF2_PairBottom | CF2_GhostBottom ) ) != 0;
+ }
+
+
+ static FT_Bool
+ cf2_hint_isLocked( const CF2_Hint hint )
+ {
+ return ( hint->flags & CF2_Locked ) != 0;
+ }
+
+
+ static FT_Bool
+ cf2_hint_isSynthetic( const CF2_Hint hint )
+ {
+ return ( hint->flags & CF2_Synthetic ) != 0;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_hint_lock( CF2_Hint hint )
+ {
+ hint->flags |= CF2_Locked;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_hintmap_init( CF2_HintMap hintmap,
+ CF2_Font font,
+ CF2_HintMap initialMap,
+ CF2_ArrStack hintMoves,
+ CF2_Fixed scale )
+ {
+ FT_ZERO( hintmap );
+
+ /* copy parameters from font instance */
+ hintmap->hinted = font->hinted;
+ hintmap->scale = scale;
+ hintmap->font = font;
+ hintmap->initialHintMap = initialMap;
+ /* will clear in `cf2_hintmap_adjustHints' */
+ hintmap->hintMoves = hintMoves;
+ }
+
+
+ static FT_Bool
+ cf2_hintmap_isValid( const CF2_HintMap hintmap )
+ {
+ return hintmap->isValid;
+ }
+
+
+ /* transform character space coordinate to device space using hint map */
+ static CF2_Fixed
+ cf2_hintmap_map( CF2_HintMap hintmap,
+ CF2_Fixed csCoord )
+ {
+ FT_ASSERT( hintmap->isValid ); /* must call Build before Map */
+ FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES );
+
+ if ( hintmap->count == 0 || ! hintmap->hinted )
+ {
+ /* there are no hints; use uniform scale and zero offset */
+ return FT_MulFix( csCoord, hintmap->scale );
+ }
+ else
+ {
+ /* start linear search from last hit */
+ CF2_UInt i = hintmap->lastIndex;
+
+
+ /* search up */
+ while ( i < hintmap->count - 1 &&
+ csCoord >= hintmap->edge[i + 1].csCoord )
+ i += 1;
+
+ /* search down */
+ while ( i > 0 && csCoord < hintmap->edge[i].csCoord )
+ i -= 1;
+
+ hintmap->lastIndex = i;
+
+ if ( i == 0 && csCoord < hintmap->edge[0].csCoord )
+ {
+ /* special case for points below first edge: use uniform scale */
+ return FT_MulFix( csCoord - hintmap->edge[0].csCoord,
+ hintmap->scale ) +
+ hintmap->edge[0].dsCoord;
+ }
+ else
+ {
+ /*
+ * Note: entries with duplicate csCoord are allowed.
+ * Use edge[i], the highest entry where csCoord >= entry[i].csCoord
+ */
+ return FT_MulFix( csCoord - hintmap->edge[i].csCoord,
+ hintmap->edge[i].scale ) +
+ hintmap->edge[i].dsCoord;
+ }
+ }
+ }
+
+
+ /*
+ * This hinting policy moves a hint pair in device space so that one of
+ * its two edges is on a device pixel boundary (its fractional part is
+ * zero). `cf2_hintmap_insertHint' guarantees no overlap in CS
+ * space. Ensure here that there is no overlap in DS.
+ *
+ * In the first pass, edges are adjusted relative to adjacent hints.
+ * Those that are below have already been adjusted. Those that are
+ * above have not yet been adjusted. If a hint above blocks an
+ * adjustment to an optimal position, we will try again in a second
+ * pass. The second pass is top-down.
+ *
+ */
+
+ static void
+ cf2_hintmap_adjustHints( CF2_HintMap hintmap )
+ {
+ size_t i, j;
+
+
+ cf2_arrstack_clear( hintmap->hintMoves ); /* working storage */
+
+ /*
+ * First pass is bottom-up (font hint order) without look-ahead.
+ * Locked edges are already adjusted.
+ * Unlocked edges begin with dsCoord from `initialHintMap'.
+ * Save edges that are not optimally adjusted in `hintMoves' array,
+ * and process them in second pass.
+ */
+
+ for ( i = 0; i < hintmap->count; i++ )
+ {
+ FT_Bool isPair = cf2_hint_isPair( &hintmap->edge[i] );
+
+
+ /* index of upper edge (same value for ghost hint) */
+ j = isPair ? i + 1 : i;
+
+ FT_ASSERT( j < hintmap->count );
+ FT_ASSERT( cf2_hint_isValid( &hintmap->edge[i] ) );
+ FT_ASSERT( cf2_hint_isValid( &hintmap->edge[j] ) );
+ FT_ASSERT( cf2_hint_isLocked( &hintmap->edge[i] ) ==
+ cf2_hint_isLocked( &hintmap->edge[j] ) );
+
+ if ( !cf2_hint_isLocked( &hintmap->edge[i] ) )
+ {
+ /* hint edge is not locked, we can adjust it */
+ CF2_Fixed fracDown = cf2_fixedFraction( hintmap->edge[i].dsCoord );
+ CF2_Fixed fracUp = cf2_fixedFraction( hintmap->edge[j].dsCoord );
+
+ /* calculate all four possibilities; moves down are negative */
+ CF2_Fixed downMoveDown = 0 - fracDown;
+ CF2_Fixed upMoveDown = 0 - fracUp;
+ CF2_Fixed downMoveUp = fracDown == 0
+ ? 0
+ : cf2_intToFixed( 1 ) - fracDown;
+ CF2_Fixed upMoveUp = fracUp == 0
+ ? 0
+ : cf2_intToFixed( 1 ) - fracUp;
+
+ /* smallest move up */
+ CF2_Fixed moveUp = FT_MIN( downMoveUp, upMoveUp );
+ /* smallest move down */
+ CF2_Fixed moveDown = FT_MAX( downMoveDown, upMoveDown );
+
+ /* final amount to move edge or edge pair */
+ CF2_Fixed move;
+
+ CF2_Fixed downMinCounter = CF2_MIN_COUNTER;
+ CF2_Fixed upMinCounter = CF2_MIN_COUNTER;
+ FT_Bool saveEdge = FALSE;
+
+
+ /* minimum counter constraint doesn't apply when adjacent edges */
+ /* are synthetic */
+ /* TODO: doesn't seem a big effect; for now, reduce the code */
+#if 0
+ if ( i == 0 ||
+ cf2_hint_isSynthetic( &hintmap->edge[i - 1] ) )
+ downMinCounter = 0;
+
+ if ( j >= hintmap->count - 1 ||
+ cf2_hint_isSynthetic( &hintmap->edge[j + 1] ) )
+ upMinCounter = 0;
+#endif
+
+ /* is there room to move up? */
+ /* there is if we are at top of array or the next edge is at or */
+ /* beyond proposed move up? */
+ if ( j >= hintmap->count - 1 ||
+ hintmap->edge[j + 1].dsCoord >=
+ hintmap->edge[j].dsCoord + moveUp + upMinCounter )
+ {
+ /* there is room to move up; is there also room to move down? */
+ if ( i == 0 ||
+ hintmap->edge[i - 1].dsCoord <=
+ hintmap->edge[i].dsCoord + moveDown - downMinCounter )
+ {
+ /* move smaller absolute amount */
+ move = ( -moveDown < moveUp ) ? moveDown : moveUp; /* optimum */
+ }
+ else
+ move = moveUp;
+ }
+ else
+ {
+ /* is there room to move down? */
+ if ( i == 0 ||
+ hintmap->edge[i - 1].dsCoord <=
+ hintmap->edge[i].dsCoord + moveDown - downMinCounter )
+ {
+ move = moveDown;
+ saveEdge = moveUp < -moveDown; /* true if non-optimum move */
+ }
+ else
+ {
+ /* no room to move either way without overlapping or reducing */
+ /* the counter too much */
+ move = 0;
+ saveEdge = TRUE;
+ }
+ }
+
+ /* Identify non-moves and moves down that aren't optimal, and save */
+ /* them for second pass. */
+ /* Do this only if there is an unlocked edge above (which could */
+ /* possibly move). */
+ if ( saveEdge &&
+ j < hintmap->count - 1 &&
+ !cf2_hint_isLocked( &hintmap->edge[j + 1] ) )
+ {
+ CF2_HintMoveRec savedMove;
+
+
+ savedMove.j = j;
+ /* desired adjustment in second pass */
+ savedMove.moveUp = moveUp - move;
+
+ cf2_arrstack_push( hintmap->hintMoves, &savedMove );
+ }
+
+ /* move the edge(s) */
+ hintmap->edge[i].dsCoord += move;
+ if ( isPair )
+ hintmap->edge[j].dsCoord += move;
+ }
+
+ /* assert there are no overlaps in device space */
+ FT_ASSERT( i == 0 ||
+ hintmap->edge[i - 1].dsCoord <= hintmap->edge[i].dsCoord );
+ FT_ASSERT( i < j ||
+ hintmap->edge[i].dsCoord <= hintmap->edge[j].dsCoord );
+
+ /* adjust the scales, avoiding divide by zero */
+ if ( i > 0 )
+ {
+ if ( hintmap->edge[i].csCoord != hintmap->edge[i - 1].csCoord )
+ hintmap->edge[i - 1].scale =
+ FT_DivFix(
+ hintmap->edge[i].dsCoord - hintmap->edge[i - 1].dsCoord,
+ hintmap->edge[i].csCoord - hintmap->edge[i - 1].csCoord );
+ }
+
+ if ( isPair )
+ {
+ if ( hintmap->edge[j].csCoord != hintmap->edge[j - 1].csCoord )
+ hintmap->edge[j - 1].scale =
+ FT_DivFix(
+ hintmap->edge[j].dsCoord - hintmap->edge[j - 1].dsCoord,
+ hintmap->edge[j].csCoord - hintmap->edge[j - 1].csCoord );
+
+ i += 1; /* skip upper edge on next loop */
+ }
+ }
+
+ /* second pass tries to move non-optimal hints up, in case there is */
+ /* room now */
+ for ( i = cf2_arrstack_size( hintmap->hintMoves ); i > 0; i-- )
+ {
+ CF2_HintMove hintMove = (CF2_HintMove)
+ cf2_arrstack_getPointer( hintmap->hintMoves, i - 1 );
+
+
+ j = hintMove->j;
+
+ /* this was tested before the push, above */
+ FT_ASSERT( j < hintmap->count - 1 );
+
+ /* is there room to move up? */
+ if ( hintmap->edge[j + 1].dsCoord >=
+ hintmap->edge[j].dsCoord + hintMove->moveUp + CF2_MIN_COUNTER )
+ {
+ /* there is more room now, move edge up */
+ hintmap->edge[j].dsCoord += hintMove->moveUp;
+
+ if ( cf2_hint_isPair( &hintmap->edge[j] ) )
+ {
+ FT_ASSERT( j > 0 );
+ hintmap->edge[j - 1].dsCoord += hintMove->moveUp;
+ }
+ }
+ }
+ }
+
+
+ /* insert hint edges into map, sorted by csCoord */
+ static void
+ cf2_hintmap_insertHint( CF2_HintMap hintmap,
+ CF2_Hint bottomHintEdge,
+ CF2_Hint topHintEdge )
+ {
+ CF2_UInt indexInsert;
+
+ /* set default values, then check for edge hints */
+ FT_Bool isPair = TRUE;
+ CF2_Hint firstHintEdge = bottomHintEdge;
+ CF2_Hint secondHintEdge = topHintEdge;
+
+
+ /* one or none of the input params may be invalid when dealing with */
+ /* edge hints; at least one edge must be valid */
+ FT_ASSERT( cf2_hint_isValid( bottomHintEdge ) ||
+ cf2_hint_isValid( topHintEdge ) );
+
+ /* determine how many and which edges to insert */
+ if ( !cf2_hint_isValid( bottomHintEdge ) )
+ {
+ /* insert only the top edge */
+ firstHintEdge = topHintEdge;
+ isPair = FALSE;
+ }
+ else if ( !cf2_hint_isValid( topHintEdge ) )
+ {
+ /* insert only the bottom edge */
+ isPair = FALSE;
+ }
+
+ /* paired edges must be in proper order */
+ FT_ASSERT( !isPair ||
+ topHintEdge->csCoord >= bottomHintEdge->csCoord );
+
+ /* linear search to find index value of insertion point */
+ indexInsert = 0;
+ for ( ; indexInsert < hintmap->count; indexInsert++ )
+ {
+ if ( hintmap->edge[indexInsert].csCoord > firstHintEdge->csCoord )
+ break;
+ }
+
+ /*
+ * Discard any hints that overlap in character space. Most often,
+ * this is while building the initial map, but in theory, it can also
+ * occur because of darkening.
+ *
+ */
+ if ( indexInsert < hintmap->count )
+ {
+ /* we are inserting before an existing edge: */
+ /* verify that a new pair does not straddle the next edge */
+ if ( isPair &&
+ hintmap->edge[indexInsert].csCoord < secondHintEdge->csCoord )
+ return; /* ignore overlapping stem hint */
+
+ /* verify that we are not inserting between paired edges */
+ if ( cf2_hint_isPairTop( &hintmap->edge[indexInsert] ) )
+ return; /* ignore overlapping stem hint */
+ }
+
+ /* recompute device space locations using initial hint map */
+ if ( cf2_hintmap_isValid( hintmap->initialHintMap ) &&
+ !cf2_hint_isLocked( firstHintEdge ) )
+ {
+ if ( isPair )
+ {
+ /* Use hint map to position the center of stem, and nominal scale */
+ /* to position the two edges. This preserves the stem width. */
+ CF2_Fixed midpoint = cf2_hintmap_map(
+ hintmap->initialHintMap,
+ ( secondHintEdge->csCoord +
+ firstHintEdge->csCoord ) / 2 );
+ CF2_Fixed halfWidth = FT_MulFix(
+ ( secondHintEdge->csCoord -
+ firstHintEdge->csCoord ) / 2,
+ hintmap->scale );
+
+
+ firstHintEdge->dsCoord = midpoint - halfWidth;
+ secondHintEdge->dsCoord = midpoint + halfWidth;
+ }
+ else
+ firstHintEdge->dsCoord = cf2_hintmap_map( hintmap->initialHintMap,
+ firstHintEdge->csCoord );
+ }
+
+ /* discard any hints that overlap in device space; this can occur */
+ /* because locked hints have been moved to align with blue zones */
+ if ( indexInsert > 0 )
+ {
+ /* we are inserting after an existing edge */
+ if ( firstHintEdge->dsCoord < hintmap->edge[indexInsert - 1].dsCoord )
+ return;
+ }
+
+ if ( indexInsert < hintmap->count )
+ {
+ /* we are inserting before an existing edge */
+ if ( isPair )
+ {
+ if ( secondHintEdge->dsCoord > hintmap->edge[indexInsert].dsCoord )
+ return;
+ }
+ else
+ {
+ if ( firstHintEdge->dsCoord > hintmap->edge[indexInsert].dsCoord )
+ return;
+ }
+ }
+
+ /* make room to insert */
+ {
+ CF2_Int iSrc = hintmap->count - 1;
+ CF2_Int iDst = isPair ? hintmap->count + 1 : hintmap->count;
+
+ CF2_Int count = hintmap->count - indexInsert;
+
+
+ if ( iDst >= CF2_MAX_HINT_EDGES )
+ {
+ FT_TRACE4(( "cf2_hintmap_insertHint: too many hintmaps\n" ));
+ return;
+ }
+
+ while ( count-- )
+ hintmap->edge[iDst--] = hintmap->edge[iSrc--];
+
+ /* insert first edge */
+ hintmap->edge[indexInsert] = *firstHintEdge; /* copy struct */
+ hintmap->count += 1;
+
+ if ( isPair )
+ {
+ /* insert second edge */
+ hintmap->edge[indexInsert + 1] = *secondHintEdge; /* copy struct */
+ hintmap->count += 1;
+ }
+ }
+
+ return;
+ }
+
+
+ /*
+ * Build a map from hints and mask.
+ *
+ * This function may recur one level if `hintmap->initialHintMap' is not yet
+ * valid.
+ * If `initialMap' is true, simply build initial map.
+ *
+ * Synthetic hints are used in two ways. A hint at zero is inserted, if
+ * needed, in the initial hint map, to prevent translations from
+ * propagating across the origin. If synthetic em box hints are enabled
+ * for ideographic dictionaries, then they are inserted in all hint
+ * maps, including the initial one.
+ *
+ */
+ FT_LOCAL_DEF( void )
+ cf2_hintmap_build( CF2_HintMap hintmap,
+ CF2_ArrStack hStemHintArray,
+ CF2_ArrStack vStemHintArray,
+ CF2_HintMask hintMask,
+ CF2_Fixed hintOrigin,
+ FT_Bool initialMap )
+ {
+ FT_Byte* maskPtr;
+
+ CF2_Font font = hintmap->font;
+ CF2_HintMaskRec tempHintMask;
+
+ size_t bitCount, i;
+ FT_Byte maskByte;
+
+
+ /* check whether initial map is constructed */
+ if ( !initialMap && !cf2_hintmap_isValid( hintmap->initialHintMap ) )
+ {
+ /* make recursive call with initialHintMap and temporary mask; */
+ /* temporary mask will get all bits set, below */
+ cf2_hintmask_init( &tempHintMask, hintMask->error );
+ cf2_hintmap_build( hintmap->initialHintMap,
+ hStemHintArray,
+ vStemHintArray,
+ &tempHintMask,
+ hintOrigin,
+ TRUE );
+ }
+
+ if ( !cf2_hintmask_isValid( hintMask ) )
+ {
+ /* without a hint mask, assume all hints are active */
+ cf2_hintmask_setAll( hintMask,
+ cf2_arrstack_size( hStemHintArray ) +
+ cf2_arrstack_size( vStemHintArray ) );
+ }
+
+ /* begin by clearing the map */
+ hintmap->count = 0;
+ hintmap->lastIndex = 0;
+
+ /* make a copy of the hint mask so we can modify it */
+ tempHintMask = *hintMask;
+ maskPtr = cf2_hintmask_getMaskPtr( &tempHintMask );
+
+ /* use the hStem hints only, which are first in the mask */
+ /* TODO: compare this to cffhintmaskGetBitCount */
+ bitCount = cf2_arrstack_size( hStemHintArray );
+
+ /* synthetic embox hints get highest priority */
+ if ( font->blues.doEmBoxHints )
+ {
+ CF2_HintRec dummy;
+
+
+ cf2_hint_initZero( &dummy ); /* invalid hint map element */
+
+ /* ghost bottom */
+ cf2_hintmap_insertHint( hintmap,
+ &font->blues.emBoxBottomEdge,
+ &dummy );
+ /* ghost top */
+ cf2_hintmap_insertHint( hintmap,
+ &dummy,
+ &font->blues.emBoxTopEdge );
+ }
+
+ /* insert hints captured by a blue zone or already locked (higher */
+ /* priority) */
+ for ( i = 0, maskByte = 0x80; i < bitCount; i++ )
+ {
+ if ( maskByte & *maskPtr )
+ {
+ /* expand StemHint into two `CF2_Hint' elements */
+ CF2_HintRec bottomHintEdge, topHintEdge;
+
+
+ cf2_hint_init( &bottomHintEdge,
+ hStemHintArray,
+ i,
+ font,
+ hintOrigin,
+ hintmap->scale,
+ TRUE /* bottom */ );
+ cf2_hint_init( &topHintEdge,
+ hStemHintArray,
+ i,
+ font,
+ hintOrigin,
+ hintmap->scale,
+ FALSE /* top */ );
+
+ if ( cf2_hint_isLocked( &bottomHintEdge ) ||
+ cf2_hint_isLocked( &topHintEdge ) ||
+ cf2_blues_capture( &font->blues,
+ &bottomHintEdge,
+ &topHintEdge ) )
+ {
+ /* insert captured hint into map */
+ cf2_hintmap_insertHint( hintmap, &bottomHintEdge, &topHintEdge );
+
+ *maskPtr &= ~maskByte; /* turn off the bit for this hint */
+ }
+ }
+
+ if ( ( i & 7 ) == 7 )
+ {
+ /* move to next mask byte */
+ maskPtr++;
+ maskByte = 0x80;
+ }
+ else
+ maskByte >>= 1;
+ }
+
+ /* initial hint map includes only captured hints plus maybe one at 0 */
+
+ /*
+ * TODO: There is a problem here because we are trying to build a
+ * single hint map containing all captured hints. It is
+ * possible for there to be conflicts between captured hints,
+ * either because of darkening or because the hints are in
+ * separate hint zones (we are ignoring hint zones for the
+ * initial map). An example of the latter is MinionPro-Regular
+ * v2.030 glyph 883 (Greek Capital Alpha with Psili) at 15ppem.
+ * A stem hint for the psili conflicts with the top edge hint
+ * for the base character. The stem hint gets priority because
+ * of its sort order. In glyph 884 (Greek Capital Alpha with
+ * Psili and Oxia), the top of the base character gets a stem
+ * hint, and the psili does not. This creates different initial
+ * maps for the two glyphs resulting in different renderings of
+ * the base character. Will probably defer this either as not
+ * worth the cost or as a font bug. I don't think there is any
+ * good reason for an accent to be captured by an alignment
+ * zone. -darnold 2/12/10
+ */
+
+ if ( initialMap )
+ {
+ /* Apply a heuristic that inserts a point for (0,0), unless it's */
+ /* already covered by a mapping. This locks the baseline for glyphs */
+ /* that have no baseline hints. */
+
+ if ( hintmap->count == 0 ||
+ hintmap->edge[0].csCoord > 0 ||
+ hintmap->edge[hintmap->count - 1].csCoord < 0 )
+ {
+ /* all edges are above 0 or all edges are below 0; */
+ /* construct a locked edge hint at 0 */
+
+ CF2_HintRec edge, invalid;
+
+
+ cf2_hint_initZero( &edge );
+
+ edge.flags = CF2_GhostBottom |
+ CF2_Locked |
+ CF2_Synthetic;
+ edge.scale = hintmap->scale;
+
+ cf2_hint_initZero( &invalid );
+ cf2_hintmap_insertHint( hintmap, &edge, &invalid );
+ }
+ }
+ else
+ {
+ /* insert remaining hints */
+
+ maskPtr = cf2_hintmask_getMaskPtr( &tempHintMask );
+
+ for ( i = 0, maskByte = 0x80; i < bitCount; i++ )
+ {
+ if ( maskByte & *maskPtr )
+ {
+ CF2_HintRec bottomHintEdge, topHintEdge;
+
+
+ cf2_hint_init( &bottomHintEdge,
+ hStemHintArray,
+ i,
+ font,
+ hintOrigin,
+ hintmap->scale,
+ TRUE /* bottom */ );
+ cf2_hint_init( &topHintEdge,
+ hStemHintArray,
+ i,
+ font,
+ hintOrigin,
+ hintmap->scale,
+ FALSE /* top */ );
+
+ cf2_hintmap_insertHint( hintmap, &bottomHintEdge, &topHintEdge );
+ }
+
+ if ( ( i & 7 ) == 7 )
+ {
+ /* move to next mask byte */
+ maskPtr++;
+ maskByte = 0x80;
+ }
+ else
+ maskByte >>= 1;
+ }
+ }
+
+ /*
+ * Note: The following line is a convenient place to break when
+ * debugging hinting. Examine `hintmap->edge' for the list of
+ * enabled hints, then step over the call to see the effect of
+ * adjustment. We stop here first on the recursive call that
+ * creates the initial map, and then on each counter group and
+ * hint zone.
+ */
+
+ /* adjust positions of hint edges that are not locked to blue zones */
+ cf2_hintmap_adjustHints( hintmap );
+
+ /* save the position of all hints that were used in this hint map; */
+ /* if we use them again, we'll locate them in the same position */
+ if ( !initialMap )
+ {
+ for ( i = 0; i < hintmap->count; i++ )
+ {
+ if ( !cf2_hint_isSynthetic( &hintmap->edge[i] ) )
+ {
+ /* Note: include both valid and invalid edges */
+ /* Note: top and bottom edges are copied back separately */
+ CF2_StemHint stemhint = (CF2_StemHint)
+ cf2_arrstack_getPointer( hStemHintArray,
+ hintmap->edge[i].index );
+
+
+ if ( cf2_hint_isTop( &hintmap->edge[i] ) )
+ stemhint->maxDS = hintmap->edge[i].dsCoord;
+ else
+ stemhint->minDS = hintmap->edge[i].dsCoord;
+
+ stemhint->used = TRUE;
+ }
+ }
+ }
+
+ /* hint map is ready to use */
+ hintmap->isValid = TRUE;
+
+ /* remember this mask has been used */
+ cf2_hintmask_setNew( hintMask, FALSE );
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_glyphpath_init( CF2_GlyphPath glyphpath,
+ CF2_Font font,
+ CF2_OutlineCallbacks callbacks,
+ CF2_Fixed scaleY,
+ /* CF2_Fixed hShift, */
+ CF2_ArrStack hStemHintArray,
+ CF2_ArrStack vStemHintArray,
+ CF2_HintMask hintMask,
+ CF2_Fixed hintOriginY,
+ const CF2_Blues blues,
+ const FT_Vector* fractionalTranslation )
+ {
+ FT_ZERO( glyphpath );
+
+ glyphpath->font = font;
+ glyphpath->callbacks = callbacks;
+
+ cf2_arrstack_init( &glyphpath->hintMoves,
+ font->memory,
+ &font->error,
+ sizeof ( CF2_HintMoveRec ) );
+
+ cf2_hintmap_init( &glyphpath->initialHintMap,
+ font,
+ &glyphpath->initialHintMap,
+ &glyphpath->hintMoves,
+ scaleY );
+ cf2_hintmap_init( &glyphpath->firstHintMap,
+ font,
+ &glyphpath->initialHintMap,
+ &glyphpath->hintMoves,
+ scaleY );
+ cf2_hintmap_init( &glyphpath->hintMap,
+ font,
+ &glyphpath->initialHintMap,
+ &glyphpath->hintMoves,
+ scaleY );
+
+ glyphpath->scaleX = font->innerTransform.a;
+ glyphpath->scaleC = font->innerTransform.c;
+ glyphpath->scaleY = font->innerTransform.d;
+
+ glyphpath->fractionalTranslation = *fractionalTranslation;
+
+#if 0
+ glyphpath->hShift = hShift; /* for fauxing */
+#endif
+
+ glyphpath->hStemHintArray = hStemHintArray;
+ glyphpath->vStemHintArray = vStemHintArray;
+ glyphpath->hintMask = hintMask; /* ptr to current mask */
+ glyphpath->hintOriginY = hintOriginY;
+ glyphpath->blues = blues;
+ glyphpath->darken = font->darkened; /* TODO: should we make copies? */
+ glyphpath->xOffset = font->darkenX;
+ glyphpath->yOffset = font->darkenY;
+ glyphpath->miterLimit = 2 * FT_MAX(
+ cf2_fixedAbs( glyphpath->xOffset ),
+ cf2_fixedAbs( glyphpath->yOffset ) );
+
+ /* .1 character space unit */
+ glyphpath->snapThreshold = cf2_floatToFixed( 0.1f );
+
+ glyphpath->moveIsPending = TRUE;
+ glyphpath->pathIsOpen = FALSE;
+ glyphpath->elemIsQueued = FALSE;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_glyphpath_finalize( CF2_GlyphPath glyphpath )
+ {
+ cf2_arrstack_finalize( &glyphpath->hintMoves );
+ }
+
+
+ /*
+ * Hint point in y-direction and apply outerTransform.
+ * Input `current' hint map (which is actually delayed by one element).
+ * Input x,y point in Character Space.
+ * Output x,y point in Device Space, including translation.
+ */
+ static void
+ cf2_glyphpath_hintPoint( CF2_GlyphPath glyphpath,
+ CF2_HintMap hintmap,
+ FT_Vector* ppt,
+ CF2_Fixed x,
+ CF2_Fixed y )
+ {
+ FT_Vector pt; /* hinted point in upright DS */
+
+
+ pt.x = FT_MulFix( glyphpath->scaleX, x ) +
+ FT_MulFix( glyphpath->scaleC, y );
+ pt.y = cf2_hintmap_map( hintmap, y );
+
+ ppt->x = FT_MulFix( glyphpath->font->outerTransform.a, pt.x ) +
+ FT_MulFix( glyphpath->font->outerTransform.c, pt.y ) +
+ glyphpath->fractionalTranslation.x;
+ ppt->y = FT_MulFix( glyphpath->font->outerTransform.b, pt.x ) +
+ FT_MulFix( glyphpath->font->outerTransform.d, pt.y ) +
+ glyphpath->fractionalTranslation.y;
+ }
+
+
+ /*
+ * From two line segments, (u1,u2) and (v1,v2), compute a point of
+ * intersection on the corresponding lines.
+ * Return false if no intersection is found, or if the intersection is
+ * too far away from the ends of the line segments, u2 and v1.
+ *
+ */
+ static FT_Bool
+ cf2_glyphpath_computeIntersection( CF2_GlyphPath glyphpath,
+ const FT_Vector* u1,
+ const FT_Vector* u2,
+ const FT_Vector* v1,
+ const FT_Vector* v2,
+ FT_Vector* intersection )
+ {
+ /*
+ * Let `u' be a zero-based vector from the first segment, `v' from the
+ * second segment.
+ * Let `w 'be the zero-based vector from `u1' to `v1'.
+ * `perp' is the `perpendicular dot product'; see
+ * http://mathworld.wolfram.com/PerpDotProduct.html.
+ * `s' is the parameter for the parametric line for the first segment
+ * (`u').
+ *
+ * See notation in
+ * http://softsurfer.com/Archive/algorithm_0104/algorithm_0104B.htm.
+ * Calculations are done in 16.16, but must handle the squaring of
+ * line lengths in character space. We scale all vectors by 1/32 to
+ * avoid overflow. This allows values up to 4095 to be squared. The
+ * scale factor cancels in the divide.
+ *
+ * TODO: the scale factor could be computed from UnitsPerEm.
+ *
+ */
+
+#define cf2_perp( a, b ) \
+ ( FT_MulFix( a.x, b.y ) - FT_MulFix( a.y, b.x ) )
+
+ /* round and divide by 32 */
+#define CF2_CS_SCALE( x ) \
+ ( ( (x) + 0x10 ) >> 5 )
+
+ FT_Vector u, v, w; /* scaled vectors */
+ CF2_Fixed denominator, s;
+
+
+ u.x = CF2_CS_SCALE( u2->x - u1->x );
+ u.y = CF2_CS_SCALE( u2->y - u1->y );
+ v.x = CF2_CS_SCALE( v2->x - v1->x );
+ v.y = CF2_CS_SCALE( v2->y - v1->y );
+ w.x = CF2_CS_SCALE( v1->x - u1->x );
+ w.y = CF2_CS_SCALE( v1->y - u1->y );
+
+ denominator = cf2_perp( u, v );
+
+ if ( denominator == 0 )
+ return FALSE; /* parallel or coincident lines */
+
+ s = FT_DivFix( cf2_perp( w, v ), denominator );
+
+ intersection->x = u1->x + FT_MulFix( s, u2->x - u1->x );
+ intersection->y = u1->y + FT_MulFix( s, u2->y - u1->y );
+
+ /*
+ * Special case snapping for horizontal and vertical lines.
+ * This cleans up intersections and reduces problems with winding
+ * order detection.
+ * Sample case is sbc cd KozGoPr6N-Medium.otf 20 16685.
+ * Note: these calculations are in character space.
+ *
+ */
+
+ if ( u1->x == u2->x &&
+ cf2_fixedAbs( intersection->x - u1->x ) < glyphpath->snapThreshold )
+ intersection->x = u1->x;
+ if ( u1->y == u2->y &&
+ cf2_fixedAbs( intersection->y - u1->y ) < glyphpath->snapThreshold )
+ intersection->y = u1->y;
+
+ if ( v1->x == v2->x &&
+ cf2_fixedAbs( intersection->x - v1->x ) < glyphpath->snapThreshold )
+ intersection->x = v1->x;
+ if ( v1->y == v2->y &&
+ cf2_fixedAbs( intersection->y - v1->y ) < glyphpath->snapThreshold )
+ intersection->y = v1->y;
+
+ /* limit the intersection distance from midpoint of u2 and v1 */
+ if ( cf2_fixedAbs( intersection->x - ( u2->x + v1->x ) / 2 ) >
+ glyphpath->miterLimit ||
+ cf2_fixedAbs( intersection->y - ( u2->y + v1->y ) / 2 ) >
+ glyphpath->miterLimit )
+ return FALSE;
+
+ return TRUE;
+ }
+
+
+ /*
+ * Push the cached element (glyphpath->prevElem*) to the outline
+ * consumer. When a darkening offset is used, the end point of the
+ * cached element may be adjusted to an intersection point or it may be
+ * connected by a line to the current element. This calculation must
+ * use a HintMap that was valid at the time the element was saved. For
+ * the first point in a subpath, that is a saved HintMap. For most
+ * elements, it just means the caller has delayed building a HintMap
+ * from the current HintMask.
+ *
+ * Transform each point with outerTransform and call the outline
+ * callbacks. This is a general 3x3 transform:
+ *
+ * x' = a*x + c*y + tx, y' = b*x + d*y + ty
+ *
+ * but it uses 4 elements from CF2_Font and the translation part
+ * from CF2_GlyphPath.
+ *
+ */
+ static void
+ cf2_glyphpath_pushPrevElem( CF2_GlyphPath glyphpath,
+ CF2_HintMap hintmap,
+ FT_Vector* nextP0,
+ FT_Vector nextP1,
+ FT_Bool close )
+ {
+ CF2_CallbackParamsRec params;
+
+ FT_Vector* prevP0;
+ FT_Vector* prevP1;
+
+ FT_Vector intersection = { 0, 0 };
+ FT_Bool useIntersection = FALSE;
+
+
+ FT_ASSERT( glyphpath->prevElemOp == CF2_PathOpLineTo ||
+ glyphpath->prevElemOp == CF2_PathOpCubeTo );
+
+ if ( glyphpath->prevElemOp == CF2_PathOpLineTo )
+ {
+ prevP0 = &glyphpath->prevElemP0;
+ prevP1 = &glyphpath->prevElemP1;
+ }
+ else
+ {
+ prevP0 = &glyphpath->prevElemP2;
+ prevP1 = &glyphpath->prevElemP3;
+ }
+
+ /* optimization: if previous and next elements are offset by the same */
+ /* amount, then there will be no gap, and no need to compute an */
+ /* intersection. */
+ if ( prevP1->x != nextP0->x || prevP1->y != nextP0->y )
+ {
+ /* previous element does not join next element: */
+ /* adjust end point of previous element to the intersection */
+ useIntersection = cf2_glyphpath_computeIntersection( glyphpath,
+ prevP0,
+ prevP1,
+ nextP0,
+ &nextP1,
+ &intersection );
+ if ( useIntersection )
+ {
+ /* modify the last point of the cached element (either line or */
+ /* curve) */
+ *prevP1 = intersection;
+ }
+ }
+
+ params.pt0 = glyphpath->currentDS;
+
+ switch( glyphpath->prevElemOp )
+ {
+ case CF2_PathOpLineTo:
+ params.op = CF2_PathOpLineTo;
+
+ /* note: pt2 and pt3 are unused */
+ cf2_glyphpath_hintPoint( glyphpath,
+ hintmap,
+ &params.pt1,
+ glyphpath->prevElemP1.x,
+ glyphpath->prevElemP1.y );
+
+ glyphpath->callbacks->lineTo( glyphpath->callbacks, &params );
+
+ glyphpath->currentDS = params.pt1;
+
+ break;
+
+ case CF2_PathOpCubeTo:
+ params.op = CF2_PathOpCubeTo;
+
+ /* TODO: should we intersect the interior joins (p1-p2 and p2-p3)? */
+ cf2_glyphpath_hintPoint( glyphpath,
+ hintmap,
+ &params.pt1,
+ glyphpath->prevElemP1.x,
+ glyphpath->prevElemP1.y );
+ cf2_glyphpath_hintPoint( glyphpath,
+ hintmap,
+ &params.pt2,
+ glyphpath->prevElemP2.x,
+ glyphpath->prevElemP2.y );
+ cf2_glyphpath_hintPoint( glyphpath,
+ hintmap,
+ &params.pt3,
+ glyphpath->prevElemP3.x,
+ glyphpath->prevElemP3.y );
+
+ glyphpath->callbacks->cubeTo( glyphpath->callbacks, &params );
+
+ glyphpath->currentDS = params.pt3;
+
+ break;
+ }
+
+ if ( !useIntersection || close )
+ {
+ /* insert connecting line between end of previous element and start */
+ /* of current one */
+ /* note: at the end of a subpath, we might do both, so use `nextP0' */
+ /* before we change it, below */
+
+ cf2_glyphpath_hintPoint( glyphpath,
+ hintmap,
+ &params.pt1,
+ nextP0->x,
+ nextP0->y );
+
+ if ( params.pt1.x != glyphpath->currentDS.x ||
+ params.pt1.y != glyphpath->currentDS.y )
+ {
+ /* length is nonzero */
+ params.op = CF2_PathOpLineTo;
+ params.pt0 = glyphpath->currentDS;
+
+ /* note: pt2 and pt3 are unused */
+ glyphpath->callbacks->lineTo( glyphpath->callbacks, &params );
+
+ glyphpath->currentDS = params.pt1;
+ }
+ }
+
+ if ( useIntersection )
+ {
+ /* return intersection point to caller */
+ *nextP0 = intersection;
+ }
+ }
+
+
+ /* push a MoveTo element based on current point and offset of current */
+ /* element */
+ static void
+ cf2_glyphpath_pushMove( CF2_GlyphPath glyphpath,
+ FT_Vector start )
+ {
+ CF2_CallbackParamsRec params;
+
+
+ params.op = CF2_PathOpMoveTo;
+ params.pt0 = glyphpath->currentDS;
+
+ /* Test if move has really happened yet; it would have called */
+ /* `cf2_hintmap_build' to set `isValid'. */
+ if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) )
+ {
+ /* we are here iff first subpath is missing a moveto operator: */
+ /* synthesize first moveTo to finish initialization of hintMap */
+ cf2_glyphpath_moveTo( glyphpath,
+ glyphpath->start.x,
+ glyphpath->start.y );
+ }
+
+ cf2_glyphpath_hintPoint( glyphpath,
+ &glyphpath->hintMap,
+ &params.pt1,
+ start.x,
+ start.y );
+
+ /* note: pt2 and pt3 are unused */
+ glyphpath->callbacks->moveTo( glyphpath->callbacks, &params );
+
+ glyphpath->currentDS = params.pt1;
+ glyphpath->offsetStart0 = start;
+ }
+
+
+ /*
+ * All coordinates are in character space.
+ * On input, (x1, y1) and (x2, y2) give line segment.
+ * On output, (x, y) give offset vector.
+ * We use a piecewise approximation to trig functions.
+ *
+ * TODO: Offset true perpendicular and proper length
+ * supply the y-translation for hinting here, too,
+ * that adds yOffset unconditionally to *y.
+ */
+ static void
+ cf2_glyphpath_computeOffset( CF2_GlyphPath glyphpath,
+ CF2_Fixed x1,
+ CF2_Fixed y1,
+ CF2_Fixed x2,
+ CF2_Fixed y2,
+ CF2_Fixed* x,
+ CF2_Fixed* y )
+ {
+ CF2_Fixed dx = x2 - x1;
+ CF2_Fixed dy = y2 - y1;
+
+
+ /* note: negative offsets don't work here; negate deltas to change */
+ /* quadrants, below */
+ if ( glyphpath->font->reverseWinding )
+ {
+ dx = -dx;
+ dy = -dy;
+ }
+
+ *x = *y = 0;
+
+ if ( !glyphpath->darken )
+ return;
+
+ /* add momentum for this path element */
+ glyphpath->callbacks->windingMomentum +=
+ cf2_getWindingMomentum( x1, y1, x2, y2 );
+
+ /* note: allow mixed integer and fixed multiplication here */
+ if ( dx >= 0 )
+ {
+ if ( dy >= 0 )
+ {
+ /* first quadrant, +x +y */
+
+ if ( dx > 2 * dy )
+ {
+ /* +x */
+ *x = 0;
+ *y = 0;
+ }
+ else if ( dy > 2 * dx )
+ {
+ /* +y */
+ *x = glyphpath->xOffset;
+ *y = glyphpath->yOffset;
+ }
+ else
+ {
+ /* +x +y */
+ *x = FT_MulFix( cf2_floatToFixed( 0.7 ),
+ glyphpath->xOffset );
+ *y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ),
+ glyphpath->yOffset );
+ }
+ }
+ else
+ {
+ /* fourth quadrant, +x -y */
+
+ if ( dx > -2 * dy )
+ {
+ /* +x */
+ *x = 0;
+ *y = 0;
+ }
+ else if ( -dy > 2 * dx )
+ {
+ /* -y */
+ *x = -glyphpath->xOffset;
+ *y = glyphpath->yOffset;
+ }
+ else
+ {
+ /* +x -y */
+ *x = FT_MulFix( cf2_floatToFixed( -0.7 ),
+ glyphpath->xOffset );
+ *y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ),
+ glyphpath->yOffset );
+ }
+ }
+ }
+ else
+ {
+ if ( dy >= 0 )
+ {
+ /* second quadrant, -x +y */
+
+ if ( -dx > 2 * dy )
+ {
+ /* -x */
+ *x = 0;
+ *y = 2 * glyphpath->yOffset;
+ }
+ else if ( dy > -2 * dx )
+ {
+ /* +y */
+ *x = glyphpath->xOffset;
+ *y = glyphpath->yOffset;
+ }
+ else
+ {
+ /* -x +y */
+ *x = FT_MulFix( cf2_floatToFixed( 0.7 ),
+ glyphpath->xOffset );
+ *y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ),
+ glyphpath->yOffset );
+ }
+ }
+ else
+ {
+ /* third quadrant, -x -y */
+
+ if ( -dx > -2 * dy )
+ {
+ /* -x */
+ *x = 0;
+ *y = 2 * glyphpath->yOffset;
+ }
+ else if ( -dy > -2 * dx )
+ {
+ /* -y */
+ *x = -glyphpath->xOffset;
+ *y = glyphpath->xOffset;
+ }
+ else
+ {
+ /* -x -y */
+ *x = FT_MulFix( cf2_floatToFixed( -0.7 ),
+ glyphpath->xOffset );
+ *y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ),
+ glyphpath->yOffset );
+ }
+ }
+ }
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath,
+ CF2_Fixed x,
+ CF2_Fixed y )
+ {
+ cf2_glyphpath_closeOpenPath( glyphpath );
+
+ /* save the parameters of the move for later, when we'll know how to */
+ /* offset it; */
+ /* also save last move point */
+ glyphpath->currentCS.x = glyphpath->start.x = x;
+ glyphpath->currentCS.y = glyphpath->start.y = y;
+
+ glyphpath->moveIsPending = TRUE;
+
+ /* ensure we have a valid map with current mask */
+ if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) ||
+ cf2_hintmask_isNew( glyphpath->hintMask ) )
+ cf2_hintmap_build( &glyphpath->hintMap,
+ glyphpath->hStemHintArray,
+ glyphpath->vStemHintArray,
+ glyphpath->hintMask,
+ glyphpath->hintOriginY,
+ FALSE );
+
+ /* save a copy of current HintMap to use when drawing initial point */
+ glyphpath->firstHintMap = glyphpath->hintMap; /* structure copy */
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath,
+ CF2_Fixed x,
+ CF2_Fixed y )
+ {
+ CF2_Fixed xOffset, yOffset;
+ FT_Vector P0, P1;
+
+
+ /* can't compute offset of zero length line, so ignore them */
+ if ( glyphpath->currentCS.x == x && glyphpath->currentCS.y == y )
+ return;
+
+ cf2_glyphpath_computeOffset( glyphpath,
+ glyphpath->currentCS.x,
+ glyphpath->currentCS.y,
+ x,
+ y,
+ &xOffset,
+ &yOffset );
+
+ /* construct offset points */
+ P0.x = glyphpath->currentCS.x + xOffset;
+ P0.y = glyphpath->currentCS.y + yOffset;
+ P1.x = x + xOffset;
+ P1.y = y + yOffset;
+
+ if ( glyphpath->moveIsPending )
+ {
+ /* emit offset 1st point as MoveTo */
+ cf2_glyphpath_pushMove( glyphpath, P0 );
+
+ glyphpath->moveIsPending = FALSE; /* adjust state machine */
+ glyphpath->pathIsOpen = TRUE;
+
+ glyphpath->offsetStart1 = P1; /* record second point */
+ }
+
+ if ( glyphpath->elemIsQueued )
+ {
+ FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) );
+
+ cf2_glyphpath_pushPrevElem( glyphpath,
+ &glyphpath->hintMap,
+ &P0,
+ P1,
+ FALSE );
+ }
+
+ /* queue the current element with offset points */
+ glyphpath->elemIsQueued = TRUE;
+ glyphpath->prevElemOp = CF2_PathOpLineTo;
+ glyphpath->prevElemP0 = P0;
+ glyphpath->prevElemP1 = P1;
+
+ /* update current map */
+ if ( cf2_hintmask_isNew( glyphpath->hintMask ) )
+ cf2_hintmap_build( &glyphpath->hintMap,
+ glyphpath->hStemHintArray,
+ glyphpath->vStemHintArray,
+ glyphpath->hintMask,
+ glyphpath->hintOriginY,
+ FALSE );
+
+ glyphpath->currentCS.x = x; /* pre-offset current point */
+ glyphpath->currentCS.y = y;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath,
+ CF2_Fixed x1,
+ CF2_Fixed y1,
+ CF2_Fixed x2,
+ CF2_Fixed y2,
+ CF2_Fixed x3,
+ CF2_Fixed y3 )
+ {
+ CF2_Fixed xOffset1, yOffset1, xOffset3, yOffset3;
+ FT_Vector P0, P1, P2, P3;
+
+
+ /* TODO: ignore zero length portions of curve?? */
+ cf2_glyphpath_computeOffset( glyphpath,
+ glyphpath->currentCS.x,
+ glyphpath->currentCS.y,
+ x1,
+ y1,
+ &xOffset1,
+ &yOffset1 );
+ cf2_glyphpath_computeOffset( glyphpath,
+ x2,
+ y2,
+ x3,
+ y3,
+ &xOffset3,
+ &yOffset3 );
+
+ /* add momentum from the middle segment */
+ glyphpath->callbacks->windingMomentum +=
+ cf2_getWindingMomentum( x1, y1, x2, y2 );
+
+ /* construct offset points */
+ P0.x = glyphpath->currentCS.x + xOffset1;
+ P0.y = glyphpath->currentCS.y + yOffset1;
+ P1.x = x1 + xOffset1;
+ P1.y = y1 + yOffset1;
+ /* note: preserve angle of final segment by using offset3 at both ends */
+ P2.x = x2 + xOffset3;
+ P2.y = y2 + yOffset3;
+ P3.x = x3 + xOffset3;
+ P3.y = y3 + yOffset3;
+
+ if ( glyphpath->moveIsPending )
+ {
+ /* emit offset 1st point as MoveTo */
+ cf2_glyphpath_pushMove( glyphpath, P0 );
+
+ glyphpath->moveIsPending = FALSE;
+ glyphpath->pathIsOpen = TRUE;
+
+ glyphpath->offsetStart1 = P1; /* record second point */
+ }
+
+ if ( glyphpath->elemIsQueued )
+ {
+ FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) );
+
+ cf2_glyphpath_pushPrevElem( glyphpath,
+ &glyphpath->hintMap,
+ &P0,
+ P1,
+ FALSE );
+ }
+
+ /* queue the current element with offset points */
+ glyphpath->elemIsQueued = TRUE;
+ glyphpath->prevElemOp = CF2_PathOpCubeTo;
+ glyphpath->prevElemP0 = P0;
+ glyphpath->prevElemP1 = P1;
+ glyphpath->prevElemP2 = P2;
+ glyphpath->prevElemP3 = P3;
+
+ /* update current map */
+ if ( cf2_hintmask_isNew( glyphpath->hintMask ) )
+ cf2_hintmap_build( &glyphpath->hintMap,
+ glyphpath->hStemHintArray,
+ glyphpath->vStemHintArray,
+ glyphpath->hintMask,
+ glyphpath->hintOriginY,
+ FALSE );
+
+ glyphpath->currentCS.x = x3; /* pre-offset current point */
+ glyphpath->currentCS.y = y3;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath )
+ {
+ if ( glyphpath->pathIsOpen )
+ {
+ FT_ASSERT( cf2_hintmap_isValid( &glyphpath->firstHintMap ) );
+
+ /* since we need to apply an offset to the implicit lineto, we make */
+ /* it explicit here */
+ cf2_glyphpath_lineTo( glyphpath,
+ glyphpath->start.x,
+ glyphpath->start.y );
+
+ /* Draw previous element (the explicit LineTo we just created, */
+ /* above) and connect it to the start point, but with the offset we */
+ /* saved from the first element. */
+ /* Use the saved HintMap, too. */
+ FT_ASSERT( glyphpath->elemIsQueued );
+
+ cf2_glyphpath_pushPrevElem( glyphpath,
+ &glyphpath->firstHintMap,
+ &glyphpath->offsetStart0,
+ glyphpath->offsetStart1,
+ TRUE );
+
+ /* reset state machine */
+ glyphpath->moveIsPending = TRUE;
+ glyphpath->pathIsOpen = FALSE;
+ glyphpath->elemIsQueued = FALSE;
+ }
+ }
+
+
+/* END */
diff --git a/src/cff/cf2hints.h b/src/cff/cf2hints.h
new file mode 100644
index 0000000..c4fa922
--- /dev/null
+++ b/src/cff/cf2hints.h
@@ -0,0 +1,287 @@
+/***************************************************************************/
+/* */
+/* cf2hints.h */
+/* */
+/* Adobe's code for handling CFF hints (body). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CF2HINTS_H__
+#define __CF2HINTS_H__
+
+
+FT_BEGIN_HEADER
+
+
+ enum
+ {
+ CF2_MAX_HINTS = 96 /* maximum # of hints */
+ };
+
+
+ /*
+ * A HintMask object stores a bit mask that specifies which hints in the
+ * charstring are active at a given time. Hints in CFF must be declared
+ * at the start, before any drawing operators, with horizontal hints
+ * preceding vertical hints. The HintMask is ordered the same way, with
+ * horizontal hints immediately followed by vertical hints. Clients are
+ * responsible for knowing how many of each type are present.
+ *
+ * The maximum total number of hints is 96, as specified by the CFF
+ * specification.
+ *
+ * A HintMask is built 0 or more times while interpreting a charstring, by
+ * the HintMask operator. There is only one HintMask, but it is built or
+ * rebuilt each time there is a hint substitution (HintMask operator) in
+ * the charstring. A default HintMask with all bits set is built if there
+ * has been no HintMask operator prior to the first drawing operator.
+ *
+ */
+
+ typedef struct CF2_HintMaskRec_
+ {
+ FT_Error* error;
+
+ FT_Bool isValid;
+ FT_Bool isNew;
+
+ size_t bitCount;
+ size_t byteCount;
+
+ FT_Byte mask[( CF2_MAX_HINTS + 7 ) / 8];
+
+ } CF2_HintMaskRec, *CF2_HintMask;
+
+
+ typedef struct CF2_StemHintRec_
+ {
+ FT_Bool used; /* DS positions are valid */
+
+ CF2_Fixed min; /* original character space value */
+ CF2_Fixed max;
+
+ CF2_Fixed minDS; /* DS position after first use */
+ CF2_Fixed maxDS;
+
+ } CF2_StemHintRec, *CF2_StemHint;
+
+
+ /*
+ * A HintMap object stores a piecewise linear function for mapping
+ * y-coordinates from character space to device space, providing
+ * appropriate pixel alignment to stem edges.
+ *
+ * The map is implemented as an array of `CF2_Hint' elements, each
+ * representing an edge. When edges are paired, as from stem hints, the
+ * bottom edge must immediately precede the top edge in the array.
+ * Element character space AND device space positions must both increase
+ * monotonically in the array. `CF2_Hint' elements are also used as
+ * parameters to `cf2_blues_capture'.
+ *
+ * The `cf2_hintmap_build' method must be called before any drawing
+ * operation (beginning with a Move operator) and at each hint
+ * substitution (HintMask operator).
+ *
+ * The `cf2_hintmap_map' method is called to transform y-coordinates at
+ * each drawing operation (move, line, curve).
+ *
+ */
+
+ /* TODO: make this a CF2_ArrStack and add a deep copy method */
+ enum
+ {
+ CF2_MAX_HINT_EDGES = CF2_MAX_HINTS * 2
+ };
+
+
+ typedef struct CF2_HintMapRec_
+ {
+ CF2_Font font;
+
+ /* initial map based on blue zones */
+ struct CF2_HintMapRec_* initialHintMap;
+
+ /* working storage for 2nd pass adjustHints */
+ CF2_ArrStack hintMoves;
+
+ FT_Bool isValid;
+ FT_Bool hinted;
+
+ CF2_Fixed scale;
+ CF2_UInt count;
+
+ /* start search from this index */
+ CF2_UInt lastIndex;
+
+ CF2_HintRec edge[CF2_MAX_HINT_EDGES]; /* 192 */
+
+ } CF2_HintMapRec, *CF2_HintMap;
+
+
+ FT_LOCAL( FT_Bool )
+ cf2_hint_isValid( const CF2_Hint hint );
+ FT_LOCAL( FT_Bool )
+ cf2_hint_isTop( const CF2_Hint hint );
+ FT_LOCAL( FT_Bool )
+ cf2_hint_isBottom( const CF2_Hint hint );
+ FT_LOCAL( void )
+ cf2_hint_lock( CF2_Hint hint );
+
+
+ FT_LOCAL( void )
+ cf2_hintmap_init( CF2_HintMap hintmap,
+ CF2_Font font,
+ CF2_HintMap initialMap,
+ CF2_ArrStack hintMoves,
+ CF2_Fixed scale );
+ FT_LOCAL( void )
+ cf2_hintmap_build( CF2_HintMap hintmap,
+ CF2_ArrStack hStemHintArray,
+ CF2_ArrStack vStemHintArray,
+ CF2_HintMask hintMask,
+ CF2_Fixed hintOrigin,
+ FT_Bool initialMap );
+
+
+ /*
+ * GlyphPath is a wrapper for drawing operations that scales the
+ * coordinates according to the render matrix and HintMap. It also tracks
+ * open paths to control ClosePath and to insert MoveTo for broken fonts.
+ *
+ */
+ typedef struct CF2_GlyphPathRec_
+ {
+ /* TODO: gather some of these into a hinting context */
+
+ CF2_Font font; /* font instance */
+ CF2_OutlineCallbacks callbacks; /* outline consumer */
+
+
+ CF2_HintMapRec hintMap; /* current hint map */
+ CF2_HintMapRec firstHintMap; /* saved copy */
+ CF2_HintMapRec initialHintMap; /* based on all captured hints */
+
+ CF2_ArrStackRec hintMoves; /* list of hint moves for 2nd pass */
+
+ CF2_Fixed scaleX; /* matrix a */
+ CF2_Fixed scaleC; /* matrix c */
+ CF2_Fixed scaleY; /* matrix d */
+
+ FT_Vector fractionalTranslation; /* including deviceXScale */
+#if 0
+ CF2_Fixed hShift; /* character space horizontal shift */
+ /* (for fauxing) */
+#endif
+
+ FT_Bool pathIsOpen; /* true after MoveTo */
+ FT_Bool darken; /* true if stem darkening */
+ FT_Bool moveIsPending; /* true between MoveTo and offset MoveTo */
+
+ /* references used to call `cf2_hintmap_build', if necessary */
+ CF2_ArrStack hStemHintArray;
+ CF2_ArrStack vStemHintArray;
+ CF2_HintMask hintMask; /* ptr to the current mask */
+ CF2_Fixed hintOriginY; /* copy of current origin */
+ const CF2_BluesRec* blues;
+
+ CF2_Fixed xOffset; /* character space offsets */
+ CF2_Fixed yOffset;
+
+ /* character space miter limit threshold */
+ CF2_Fixed miterLimit;
+ /* vertical/horzizontal snap distance in character space */
+ CF2_Fixed snapThreshold;
+
+ FT_Vector offsetStart0; /* first and second points of first */
+ FT_Vector offsetStart1; /* element with offset applied */
+
+ /* current point, character space, before offset */
+ FT_Vector currentCS;
+ /* current point, device space */
+ FT_Vector currentDS;
+ FT_Vector start; /* start point of subpath */
+
+ /* the following members constitute the `queue' of one element */
+ FT_Bool elemIsQueued;
+ CF2_Int prevElemOp;
+
+ FT_Vector prevElemP0;
+ FT_Vector prevElemP1;
+ FT_Vector prevElemP2;
+ FT_Vector prevElemP3;
+
+ } CF2_GlyphPathRec, *CF2_GlyphPath;
+
+
+ FT_LOCAL( void )
+ cf2_glyphpath_init( CF2_GlyphPath glyphpath,
+ CF2_Font font,
+ CF2_OutlineCallbacks callbacks,
+ CF2_Fixed scaleY,
+ /* CF2_Fixed hShift, */
+ CF2_ArrStack hStemHintArray,
+ CF2_ArrStack vStemHintArray,
+ CF2_HintMask hintMask,
+ CF2_Fixed hintOrigin,
+ const CF2_Blues blues,
+ const FT_Vector* fractionalTranslation );
+ FT_LOCAL( void )
+ cf2_glyphpath_finalize( CF2_GlyphPath glyphpath );
+
+ FT_LOCAL( void )
+ cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath,
+ CF2_Fixed x,
+ CF2_Fixed y );
+ FT_LOCAL( void )
+ cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath,
+ CF2_Fixed x,
+ CF2_Fixed y );
+ FT_LOCAL( void )
+ cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath,
+ CF2_Fixed x1,
+ CF2_Fixed y1,
+ CF2_Fixed x2,
+ CF2_Fixed y2,
+ CF2_Fixed x3,
+ CF2_Fixed y3 );
+ FT_LOCAL( void )
+ cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath );
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2HINTS_H__ */
+
+
+/* END */
diff --git a/src/cff/cf2intrp.c b/src/cff/cf2intrp.c
new file mode 100644
index 0000000..5b73e60
--- /dev/null
+++ b/src/cff/cf2intrp.c
@@ -0,0 +1,1538 @@
+/***************************************************************************/
+/* */
+/* cf2intrp.c */
+/* */
+/* Adobe's CFF Interpreter (body). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#include "cf2ft.h"
+#include FT_INTERNAL_DEBUG_H
+
+#include "cf2glue.h"
+#include "cf2font.h"
+#include "cf2stack.h"
+#include "cf2hints.h"
+
+#include "cf2error.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_cf2interp
+
+
+ /* some operators are not implemented yet */
+#define CF2_FIXME FT_TRACE4(( "cf2_interpT2CharString:" \
+ " operator not implemented yet\n" ))
+
+
+
+ FT_LOCAL_DEF( void )
+ cf2_hintmask_init( CF2_HintMask hintmask,
+ FT_Error* error )
+ {
+ FT_ZERO( hintmask );
+
+ hintmask->error = error;
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ cf2_hintmask_isValid( const CF2_HintMask hintmask )
+ {
+ return hintmask->isValid;
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ cf2_hintmask_isNew( const CF2_HintMask hintmask )
+ {
+ return hintmask->isNew;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_hintmask_setNew( CF2_HintMask hintmask,
+ FT_Bool val )
+ {
+ hintmask->isNew = val;
+ }
+
+
+ /* clients call `getMaskPtr' in order to iterate */
+ /* through hint mask */
+
+ FT_LOCAL_DEF( FT_Byte* )
+ cf2_hintmask_getMaskPtr( CF2_HintMask hintmask )
+ {
+ return hintmask->mask;
+ }
+
+
+ static size_t
+ cf2_hintmask_setCounts( CF2_HintMask hintmask,
+ size_t bitCount )
+ {
+ if ( bitCount > CF2_MAX_HINTS )
+ {
+ /* total of h and v stems must be <= 96 */
+ CF2_SET_ERROR( hintmask->error, Invalid_Glyph_Format );
+ return 0;
+ }
+
+ hintmask->bitCount = bitCount;
+ hintmask->byteCount = ( hintmask->bitCount + 7 ) / 8;
+
+ hintmask->isValid = TRUE;
+ hintmask->isNew = TRUE;
+
+ return bitCount;
+ }
+
+
+ /* consume the hintmask bytes from the charstring, advancing the src */
+ /* pointer */
+ static void
+ cf2_hintmask_read( CF2_HintMask hintmask,
+ CF2_Buffer charstring,
+ size_t bitCount )
+ {
+ size_t i;
+
+#ifndef CF2_NDEBUG
+ /* these are the bits in the final mask byte that should be zero */
+ /* Note: this variable is only used in an assert expression below */
+ /* and then only if CF2_NDEBUG is not defined */
+ CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1;
+#endif
+
+
+ /* initialize counts and isValid */
+ if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 )
+ return;
+
+ FT_ASSERT( hintmask->byteCount > 0 );
+
+ FT_TRACE4(( " (maskbytes:" ));
+
+ /* set mask and advance interpreter's charstring pointer */
+ for ( i = 0; i < hintmask->byteCount; i++ )
+ {
+ hintmask->mask[i] = (FT_Byte)cf2_buf_readByte( charstring );
+ FT_TRACE4(( " 0x%02X", hintmask->mask[i] ));
+ }
+
+ FT_TRACE4(( ")\n" ));
+
+ /* assert any unused bits in last byte are zero unless there's a prior */
+ /* error */
+ /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1 */
+#ifndef CF2_NDEBUG
+ FT_ASSERT( ( hintmask->mask[hintmask->byteCount - 1] & mask ) == 0 ||
+ *hintmask->error );
+#endif
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_hintmask_setAll( CF2_HintMask hintmask,
+ size_t bitCount )
+ {
+ size_t i;
+ CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1;
+
+
+ /* initialize counts and isValid */
+ if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 )
+ return;
+
+ FT_ASSERT( hintmask->byteCount > 0 );
+ FT_ASSERT( hintmask->byteCount <
+ sizeof ( hintmask->mask ) / sizeof ( hintmask->mask[0] ) );
+
+ /* set mask to all ones */
+ for ( i = 0; i < hintmask->byteCount; i++ )
+ hintmask->mask[i] = 0xFF;
+
+ /* clear unused bits */
+ /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1 */
+ hintmask->mask[hintmask->byteCount - 1] &= ~mask;
+ }
+
+
+ /* Type2 charstring opcodes */
+ enum
+ {
+ cf2_cmdRESERVED_0, /* 0 */
+ cf2_cmdHSTEM, /* 1 */
+ cf2_cmdRESERVED_2, /* 2 */
+ cf2_cmdVSTEM, /* 3 */
+ cf2_cmdVMOVETO, /* 4 */
+ cf2_cmdRLINETO, /* 5 */
+ cf2_cmdHLINETO, /* 6 */
+ cf2_cmdVLINETO, /* 7 */
+ cf2_cmdRRCURVETO, /* 8 */
+ cf2_cmdRESERVED_9, /* 9 */
+ cf2_cmdCALLSUBR, /* 10 */
+ cf2_cmdRETURN, /* 11 */
+ cf2_cmdESC, /* 12 */
+ cf2_cmdRESERVED_13, /* 13 */
+ cf2_cmdENDCHAR, /* 14 */
+ cf2_cmdRESERVED_15, /* 15 */
+ cf2_cmdRESERVED_16, /* 16 */
+ cf2_cmdRESERVED_17, /* 17 */
+ cf2_cmdHSTEMHM, /* 18 */
+ cf2_cmdHINTMASK, /* 19 */
+ cf2_cmdCNTRMASK, /* 20 */
+ cf2_cmdRMOVETO, /* 21 */
+ cf2_cmdHMOVETO, /* 22 */
+ cf2_cmdVSTEMHM, /* 23 */
+ cf2_cmdRCURVELINE, /* 24 */
+ cf2_cmdRLINECURVE, /* 25 */
+ cf2_cmdVVCURVETO, /* 26 */
+ cf2_cmdHHCURVETO, /* 27 */
+ cf2_cmdEXTENDEDNMBR, /* 28 */
+ cf2_cmdCALLGSUBR, /* 29 */
+ cf2_cmdVHCURVETO, /* 30 */
+ cf2_cmdHVCURVETO /* 31 */
+ };
+
+ enum
+ {
+ cf2_escDOTSECTION, /* 0 */
+ cf2_escRESERVED_1, /* 1 */
+ cf2_escRESERVED_2, /* 2 */
+ cf2_escAND, /* 3 */
+ cf2_escOR, /* 4 */
+ cf2_escNOT, /* 5 */
+ cf2_escRESERVED_6, /* 6 */
+ cf2_escRESERVED_7, /* 7 */
+ cf2_escRESERVED_8, /* 8 */
+ cf2_escABS, /* 9 */
+ cf2_escADD, /* 10 like otherADD */
+ cf2_escSUB, /* 11 like otherSUB */
+ cf2_escDIV, /* 12 */
+ cf2_escRESERVED_13, /* 13 */
+ cf2_escNEG, /* 14 */
+ cf2_escEQ, /* 15 */
+ cf2_escRESERVED_16, /* 16 */
+ cf2_escRESERVED_17, /* 17 */
+ cf2_escDROP, /* 18 */
+ cf2_escRESERVED_19, /* 19 */
+ cf2_escPUT, /* 20 like otherPUT */
+ cf2_escGET, /* 21 like otherGET */
+ cf2_escIFELSE, /* 22 like otherIFELSE */
+ cf2_escRANDOM, /* 23 like otherRANDOM */
+ cf2_escMUL, /* 24 like otherMUL */
+ cf2_escRESERVED_25, /* 25 */
+ cf2_escSQRT, /* 26 */
+ cf2_escDUP, /* 27 like otherDUP */
+ cf2_escEXCH, /* 28 like otherEXCH */
+ cf2_escINDEX, /* 29 */
+ cf2_escROLL, /* 30 */
+ cf2_escRESERVED_31, /* 31 */
+ cf2_escRESERVED_32, /* 32 */
+ cf2_escRESERVED_33, /* 33 */
+ cf2_escHFLEX, /* 34 */
+ cf2_escFLEX, /* 35 */
+ cf2_escHFLEX1, /* 36 */
+ cf2_escFLEX1 /* 37 */
+ };
+
+
+ /* `stemHintArray' does not change once we start drawing the outline. */
+ static void
+ cf2_doStems( const CF2_Font font,
+ CF2_Stack opStack,
+ CF2_ArrStack stemHintArray,
+ CF2_Fixed* width,
+ FT_Bool* haveWidth,
+ CF2_Fixed hintOffset )
+ {
+ CF2_UInt i;
+ CF2_UInt count = cf2_stack_count( opStack );
+ FT_Bool hasWidthArg = count & 1;
+
+ /* variable accumulates delta values from operand stack */
+ CF2_Fixed position = hintOffset;
+
+ if ( hasWidthArg && ! *haveWidth )
+ *width = cf2_stack_getReal( opStack, 0 ) +
+ cf2_getNominalWidthX( font->decoder );
+
+ if ( font->decoder->width_only )
+ goto exit;
+
+ for ( i = hasWidthArg ? 1 : 0; i < count; i += 2 )
+ {
+ /* construct a CF2_StemHint and push it onto the list */
+ CF2_StemHintRec stemhint;
+
+
+ stemhint.min =
+ position += cf2_stack_getReal( opStack, i );
+ stemhint.max =
+ position += cf2_stack_getReal( opStack, i + 1 );
+
+ stemhint.used = FALSE;
+ stemhint.maxDS =
+ stemhint.minDS = 0;
+
+ cf2_arrstack_push( stemHintArray, &stemhint ); /* defer error check */
+ }
+
+ cf2_stack_clear( opStack );
+
+ exit:
+ /* cf2_doStems must define a width (may be default) */
+ *haveWidth = TRUE;
+ }
+
+
+ static void
+ cf2_doFlex( CF2_Stack opStack,
+ CF2_Fixed* curX,
+ CF2_Fixed* curY,
+ CF2_GlyphPath glyphPath,
+ const FT_Bool* readFromStack,
+ FT_Bool doConditionalLastRead )
+ {
+ CF2_Fixed vals[14];
+ CF2_UInt index;
+ FT_Bool isHFlex;
+ CF2_Int top, i, j;
+
+
+ vals[0] = *curX;
+ vals[1] = *curY;
+ index = 0;
+ isHFlex = readFromStack[9] == FALSE;
+ top = isHFlex ? 9 : 10;
+
+ for ( i = 0; i < top; i++ )
+ {
+ vals[i + 2] = vals[i];
+ if ( readFromStack[i] )
+ vals[i + 2] += cf2_stack_getReal( opStack, index++ );
+ }
+
+ if ( isHFlex )
+ vals[9 + 2] = *curY;
+
+ if ( doConditionalLastRead )
+ {
+ FT_Bool lastIsX = cf2_fixedAbs( vals[10] - *curX ) >
+ cf2_fixedAbs( vals[11] - *curY );
+ CF2_Fixed lastVal = cf2_stack_getReal( opStack, index );
+
+
+ if ( lastIsX )
+ {
+ vals[12] = vals[10] + lastVal;
+ vals[13] = *curY;
+ }
+ else
+ {
+ vals[12] = *curX;
+ vals[13] = vals[11] + lastVal;
+ }
+ }
+ else
+ {
+ if ( readFromStack[10] )
+ vals[12] = vals[10] + cf2_stack_getReal( opStack, index++ );
+ else
+ vals[12] = *curX;
+
+ if ( readFromStack[11] )
+ vals[13] = vals[11] + cf2_stack_getReal( opStack, index );
+ else
+ vals[13] = *curY;
+ }
+
+ for ( j = 0; j < 2; j++ )
+ cf2_glyphpath_curveTo( glyphPath, vals[j * 6 + 2],
+ vals[j * 6 + 3],
+ vals[j * 6 + 4],
+ vals[j * 6 + 5],
+ vals[j * 6 + 6],
+ vals[j * 6 + 7] );
+
+ cf2_stack_clear( opStack );
+
+ *curX = vals[12];
+ *curY = vals[13];
+ }
+
+
+ /*
+ * `error' is a shared error code used by many objects in this
+ * routine. Before the code continues from an error, it must check and
+ * record the error in `*error'. The idea is that this shared
+ * error code will record the first error encountered. If testing
+ * for an error anyway, the cost of `goto exit' is small, so we do it,
+ * even if continuing would be safe. In this case, `lastError' is
+ * set, so the testing and storing can be done in one place, at `exit'.
+ *
+ * Continuing after an error is intended for objects which do their own
+ * testing of `*error', e.g., array stack functions. This allows us to
+ * avoid an extra test after the call.
+ *
+ * Unimplemented opcodes are ignored.
+ *
+ */
+ FT_LOCAL_DEF( void )
+ cf2_interpT2CharString( CF2_Font font,
+ CF2_Buffer buf,
+ CF2_OutlineCallbacks callbacks,
+ const FT_Vector* translation,
+ FT_Bool doingSeac,
+ CF2_Fixed curX,
+ CF2_Fixed curY,
+ CF2_Fixed* width )
+ {
+ /* lastError is used for errors that are immediately tested */
+ FT_Error lastError = FT_Err_Ok;
+
+ /* pointer to parsed font object */
+ CFF_Decoder* decoder = font->decoder;
+
+ FT_Error* error = &font->error;
+ FT_Memory memory = font->memory;
+
+ CF2_Fixed scaleY = font->innerTransform.d;
+ CF2_Fixed nominalWidthX = cf2_getNominalWidthX( decoder );
+
+ /* save this for hinting seac accents */
+ CF2_Fixed hintOriginY = curY;
+
+ CF2_Stack opStack = NULL;
+ FT_Byte op1; /* first opcode byte */
+
+ /* instruction limit; 20,000,000 matches Avalon */
+ FT_UInt32 instructionLimit = 20000000UL;
+
+ CF2_ArrStackRec subrStack;
+
+ FT_Bool haveWidth;
+ CF2_Buffer charstring = NULL;
+
+ CF2_Int charstringIndex = -1; /* initialize to empty */
+
+ /* TODO: placeholders for hint structures */
+
+ /* objects used for hinting */
+ CF2_ArrStackRec hStemHintArray;
+ CF2_ArrStackRec vStemHintArray;
+
+ CF2_HintMaskRec hintMask;
+ CF2_GlyphPathRec glyphPath;
+
+
+ /* initialize the remaining objects */
+ cf2_arrstack_init( &subrStack,
+ memory,
+ error,
+ sizeof ( CF2_BufferRec ) );
+ cf2_arrstack_init( &hStemHintArray,
+ memory,
+ error,
+ sizeof ( CF2_StemHintRec ) );
+ cf2_arrstack_init( &vStemHintArray,
+ memory,
+ error,
+ sizeof ( CF2_StemHintRec ) );
+
+ /* initialize CF2_StemHint arrays */
+ cf2_hintmask_init( &hintMask, error );
+
+ /* initialize path map to manage drawing operations */
+
+ /* Note: last 4 params are used to handle `MoveToPermissive', which */
+ /* may need to call `hintMap.Build' */
+ /* TODO: MoveToPermissive is gone; are these still needed? */
+ cf2_glyphpath_init( &glyphPath,
+ font,
+ callbacks,
+ scaleY,
+ /* hShift, */
+ &hStemHintArray,
+ &vStemHintArray,
+ &hintMask,
+ hintOriginY,
+ &font->blues,
+ translation );
+
+ /*
+ * Initialize state for width parsing. From the CFF Spec:
+ *
+ * The first stack-clearing operator, which must be one of hstem,
+ * hstemhm, vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto,
+ * rmoveto, or endchar, takes an additional argument - the width (as
+ * described earlier), which may be expressed as zero or one numeric
+ * argument.
+ *
+ * What we implement here uses the first validly specified width, but
+ * does not detect errors for specifying more than one width.
+ *
+ * If one of the above operators occurs without explicitly specifying
+ * a width, we assume the default width.
+ *
+ */
+ haveWidth = FALSE;
+ *width = cf2_getDefaultWidthX( decoder );
+
+ /*
+ * Note: at this point, all pointers to resources must be NULL
+ * and all local objects must be initialized.
+ * There must be no branches to exit: above this point.
+ *
+ */
+
+ /* allocate an operand stack */
+ opStack = cf2_stack_init( memory, error );
+ if ( !opStack )
+ {
+ lastError = FT_THROW( Out_Of_Memory );
+ goto exit;
+ }
+
+ /* initialize subroutine stack by placing top level charstring as */
+ /* first element (max depth plus one for the charstring) */
+ /* Note: Caller owns and must finalize the first charstring. */
+ /* Our copy of it does not change that requirement. */
+ cf2_arrstack_setCount( &subrStack, CF2_MAX_SUBR + 1 );
+
+ charstring = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack );
+ *charstring = *buf; /* structure copy */
+
+ charstringIndex = 0; /* entry is valid now */
+
+ /* catch errors so far */
+ if ( *error )
+ goto exit;
+
+ /* main interpreter loop */
+ while ( 1 )
+ {
+ if ( cf2_buf_isEnd( charstring ) )
+ {
+ /* If we've reached the end of the charstring, simulate a */
+ /* cf2_cmdRETURN or cf2_cmdENDCHAR. */
+ if ( charstringIndex )
+ op1 = cf2_cmdRETURN; /* end of buffer for subroutine */
+ else
+ op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */
+ }
+ else
+ op1 = (FT_Byte)cf2_buf_readByte( charstring );
+
+ /* check for errors once per loop */
+ if ( *error )
+ goto exit;
+
+ instructionLimit--;
+ if ( instructionLimit == 0 )
+ {
+ lastError = FT_THROW( Invalid_Glyph_Format );
+ goto exit;
+ }
+
+ switch( op1 )
+ {
+ case cf2_cmdRESERVED_0:
+ case cf2_cmdRESERVED_2:
+ case cf2_cmdRESERVED_9:
+ case cf2_cmdRESERVED_13:
+ case cf2_cmdRESERVED_15:
+ case cf2_cmdRESERVED_16:
+ case cf2_cmdRESERVED_17:
+ /* we may get here if we have a prior error */
+ FT_TRACE4(( " unknown op (%d)\n", op1 ));
+ break;
+
+ case cf2_cmdHSTEMHM:
+ case cf2_cmdHSTEM:
+ FT_TRACE4(( op1 == cf2_cmdHSTEMHM ? " hstemhm\n" : " hstem\n" ));
+
+ /* never add hints after the mask is computed */
+ if ( cf2_hintmask_isValid( &hintMask ) )
+ FT_TRACE4(( "cf2_interpT2CharString:"
+ " invalid horizontal hint mask\n" ));
+
+ cf2_doStems( font,
+ opStack,
+ &hStemHintArray,
+ width,
+ &haveWidth,
+ 0 );
+
+ if ( font->decoder->width_only )
+ goto exit;
+
+ break;
+
+ case cf2_cmdVSTEMHM:
+ case cf2_cmdVSTEM:
+ FT_TRACE4(( op1 == cf2_cmdVSTEMHM ? " vstemhm\n" : " vstem\n" ));
+
+ /* never add hints after the mask is computed */
+ if ( cf2_hintmask_isValid( &hintMask ) )
+ FT_TRACE4(( "cf2_interpT2CharString:"
+ " invalid vertical hint mask\n" ));
+
+ cf2_doStems( font,
+ opStack,
+ &vStemHintArray,
+ width,
+ &haveWidth,
+ 0 );
+
+ if ( font->decoder->width_only )
+ goto exit;
+
+ break;
+
+ case cf2_cmdVMOVETO:
+ FT_TRACE4(( " vmoveto\n" ));
+
+ if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
+ *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
+
+ /* width is defined or default after this */
+ haveWidth = TRUE;
+
+ if ( font->decoder->width_only )
+ goto exit;
+
+ curY += cf2_stack_popFixed( opStack );
+
+ cf2_glyphpath_moveTo( &glyphPath, curX, curY );
+
+ break;
+
+ case cf2_cmdRLINETO:
+ {
+ CF2_UInt index;
+ CF2_UInt count = cf2_stack_count( opStack );
+
+
+ FT_TRACE4(( " rlineto\n" ));
+
+ for ( index = 0; index < count; index += 2 )
+ {
+ curX += cf2_stack_getReal( opStack, index + 0 );
+ curY += cf2_stack_getReal( opStack, index + 1 );
+
+ cf2_glyphpath_lineTo( &glyphPath, curX, curY );
+ }
+
+ cf2_stack_clear( opStack );
+ }
+ continue; /* no need to clear stack again */
+
+ case cf2_cmdHLINETO:
+ case cf2_cmdVLINETO:
+ {
+ CF2_UInt index;
+ CF2_UInt count = cf2_stack_count( opStack );
+
+ FT_Bool isX = op1 == cf2_cmdHLINETO;
+
+
+ FT_TRACE4(( isX ? " hlineto\n" : " vlineto\n" ));
+
+ for ( index = 0; index < count; index++ )
+ {
+ CF2_Fixed v = cf2_stack_getReal( opStack, index );
+
+
+ if ( isX )
+ curX += v;
+ else
+ curY += v;
+
+ isX = !isX;
+
+ cf2_glyphpath_lineTo( &glyphPath, curX, curY );
+ }
+
+ cf2_stack_clear( opStack );
+ }
+ continue;
+
+ case cf2_cmdRCURVELINE:
+ case cf2_cmdRRCURVETO:
+ {
+ CF2_UInt count = cf2_stack_count( opStack );
+ CF2_UInt index = 0;
+
+
+ FT_TRACE4(( op1 == cf2_cmdRCURVELINE ? " rcurveline\n"
+ : " rrcurveto\n" ));
+
+ while ( index + 6 <= count )
+ {
+ CF2_Fixed x1 = cf2_stack_getReal( opStack, index + 0 ) + curX;
+ CF2_Fixed y1 = cf2_stack_getReal( opStack, index + 1 ) + curY;
+ CF2_Fixed x2 = cf2_stack_getReal( opStack, index + 2 ) + x1;
+ CF2_Fixed y2 = cf2_stack_getReal( opStack, index + 3 ) + y1;
+ CF2_Fixed x3 = cf2_stack_getReal( opStack, index + 4 ) + x2;
+ CF2_Fixed y3 = cf2_stack_getReal( opStack, index + 5 ) + y2;
+
+
+ cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
+
+ curX = x3;
+ curY = y3;
+ index += 6;
+ }
+
+ if ( op1 == cf2_cmdRCURVELINE )
+ {
+ curX += cf2_stack_getReal( opStack, index + 0 );
+ curY += cf2_stack_getReal( opStack, index + 1 );
+
+ cf2_glyphpath_lineTo( &glyphPath, curX, curY );
+ }
+
+ cf2_stack_clear( opStack );
+ }
+ continue; /* no need to clear stack again */
+
+ case cf2_cmdCALLGSUBR:
+ case cf2_cmdCALLSUBR:
+ {
+ CF2_UInt subrIndex;
+
+
+ FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr"
+ : " callsubr" ));
+
+ if ( charstringIndex > CF2_MAX_SUBR )
+ {
+ /* max subr plus one for charstring */
+ lastError = FT_THROW( Invalid_Glyph_Format );
+ goto exit; /* overflow of stack */
+ }
+
+ /* push our current CFF charstring region on subrStack */
+ charstring = (CF2_Buffer)
+ cf2_arrstack_getPointer( &subrStack,
+ charstringIndex + 1 );
+
+ /* set up the new CFF region and pointer */
+ subrIndex = cf2_stack_popInt( opStack );
+
+ switch ( op1 )
+ {
+ case cf2_cmdCALLGSUBR:
+ FT_TRACE4(( "(%d)\n", subrIndex + decoder->globals_bias ));
+
+ if ( cf2_initGlobalRegionBuffer( decoder,
+ subrIndex,
+ charstring ) )
+ {
+ lastError = FT_THROW( Invalid_Glyph_Format );
+ goto exit; /* subroutine lookup or stream error */
+ }
+ break;
+
+ default:
+ /* cf2_cmdCALLSUBR */
+ FT_TRACE4(( "(%d)\n", subrIndex + decoder->locals_bias ));
+
+ if ( cf2_initLocalRegionBuffer( decoder,
+ subrIndex,
+ charstring ) )
+ {
+ lastError = FT_THROW( Invalid_Glyph_Format );
+ goto exit; /* subroutine lookup or stream error */
+ }
+ }
+
+ charstringIndex += 1; /* entry is valid now */
+ }
+ continue; /* do not clear the stack */
+
+ case cf2_cmdRETURN:
+ FT_TRACE4(( " return\n" ));
+
+ if ( charstringIndex < 1 )
+ {
+ /* Note: cannot return from top charstring */
+ lastError = FT_THROW( Invalid_Glyph_Format );
+ goto exit; /* underflow of stack */
+ }
+
+ /* restore position in previous charstring */
+ charstring = (CF2_Buffer)
+ cf2_arrstack_getPointer( &subrStack,
+ --charstringIndex );
+ continue; /* do not clear the stack */
+
+ case cf2_cmdESC:
+ {
+ FT_Byte op2 = (FT_Byte)cf2_buf_readByte( charstring );
+
+
+ switch ( op2 )
+ {
+ case cf2_escDOTSECTION:
+ /* something about `flip type of locking' -- ignore it */
+ FT_TRACE4(( " dotsection\n" ));
+
+ break;
+
+ /* TODO: should these operators be supported? */
+ case cf2_escAND: /* in spec */
+ FT_TRACE4(( " and\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escOR: /* in spec */
+ FT_TRACE4(( " or\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escNOT: /* in spec */
+ FT_TRACE4(( " not\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escABS: /* in spec */
+ FT_TRACE4(( " abs\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escADD: /* in spec */
+ FT_TRACE4(( " add\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escSUB: /* in spec */
+ FT_TRACE4(( " sub\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escDIV: /* in spec */
+ FT_TRACE4(( " div\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escNEG: /* in spec */
+ FT_TRACE4(( " neg\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escEQ: /* in spec */
+ FT_TRACE4(( " eq\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escDROP: /* in spec */
+ FT_TRACE4(( " drop\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escPUT: /* in spec */
+ FT_TRACE4(( " put\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escGET: /* in spec */
+ FT_TRACE4(( " get\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escIFELSE: /* in spec */
+ FT_TRACE4(( " ifelse\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escRANDOM: /* in spec */
+ FT_TRACE4(( " random\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escMUL: /* in spec */
+ FT_TRACE4(( " mul\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escSQRT: /* in spec */
+ FT_TRACE4(( " sqrt\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escDUP: /* in spec */
+ FT_TRACE4(( " dup\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escEXCH: /* in spec */
+ FT_TRACE4(( " exch\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escINDEX: /* in spec */
+ FT_TRACE4(( " index\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escROLL: /* in spec */
+ FT_TRACE4(( " roll\n" ));
+
+ CF2_FIXME;
+ break;
+
+ case cf2_escHFLEX:
+ {
+ static const FT_Bool readFromStack[12] =
+ {
+ TRUE /* dx1 */, FALSE /* dy1 */,
+ TRUE /* dx2 */, TRUE /* dy2 */,
+ TRUE /* dx3 */, FALSE /* dy3 */,
+ TRUE /* dx4 */, FALSE /* dy4 */,
+ TRUE /* dx5 */, FALSE /* dy5 */,
+ TRUE /* dx6 */, FALSE /* dy6 */
+ };
+
+
+ FT_TRACE4(( " hflex\n" ));
+
+ cf2_doFlex( opStack,
+ &curX,
+ &curY,
+ &glyphPath,
+ readFromStack,
+ FALSE /* doConditionalLastRead */ );
+ }
+ continue;
+
+ case cf2_escFLEX:
+ {
+ static const FT_Bool readFromStack[12] =
+ {
+ TRUE /* dx1 */, TRUE /* dy1 */,
+ TRUE /* dx2 */, TRUE /* dy2 */,
+ TRUE /* dx3 */, TRUE /* dy3 */,
+ TRUE /* dx4 */, TRUE /* dy4 */,
+ TRUE /* dx5 */, TRUE /* dy5 */,
+ TRUE /* dx6 */, TRUE /* dy6 */
+ };
+
+
+ FT_TRACE4(( " flex\n" ));
+
+ cf2_doFlex( opStack,
+ &curX,
+ &curY,
+ &glyphPath,
+ readFromStack,
+ FALSE /* doConditionalLastRead */ );
+ }
+ break; /* TODO: why is this not a continue? */
+
+ case cf2_escHFLEX1:
+ {
+ static const FT_Bool readFromStack[12] =
+ {
+ TRUE /* dx1 */, TRUE /* dy1 */,
+ TRUE /* dx2 */, TRUE /* dy2 */,
+ TRUE /* dx3 */, FALSE /* dy3 */,
+ TRUE /* dx4 */, FALSE /* dy4 */,
+ TRUE /* dx5 */, TRUE /* dy5 */,
+ TRUE /* dx6 */, FALSE /* dy6 */
+ };
+
+
+ FT_TRACE4(( " hflex1\n" ));
+
+ cf2_doFlex( opStack,
+ &curX,
+ &curY,
+ &glyphPath,
+ readFromStack,
+ FALSE /* doConditionalLastRead */ );
+ }
+ continue;
+
+ case cf2_escFLEX1:
+ {
+ static const FT_Bool readFromStack[12] =
+ {
+ TRUE /* dx1 */, TRUE /* dy1 */,
+ TRUE /* dx2 */, TRUE /* dy2 */,
+ TRUE /* dx3 */, TRUE /* dy3 */,
+ TRUE /* dx4 */, TRUE /* dy4 */,
+ TRUE /* dx5 */, TRUE /* dy5 */,
+ FALSE /* dx6 */, FALSE /* dy6 */
+ };
+
+
+ FT_TRACE4(( " flex1\n" ));
+
+ cf2_doFlex( opStack,
+ &curX,
+ &curY,
+ &glyphPath,
+ readFromStack,
+ TRUE /* doConditionalLastRead */ );
+ }
+ continue;
+
+ case cf2_escRESERVED_1:
+ case cf2_escRESERVED_2:
+ case cf2_escRESERVED_6:
+ case cf2_escRESERVED_7:
+ case cf2_escRESERVED_8:
+ case cf2_escRESERVED_13:
+ case cf2_escRESERVED_16:
+ case cf2_escRESERVED_17:
+ case cf2_escRESERVED_19:
+ case cf2_escRESERVED_25:
+ case cf2_escRESERVED_31:
+ case cf2_escRESERVED_32:
+ case cf2_escRESERVED_33:
+ default:
+ FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
+
+ }; /* end of switch statement checking `op2' */
+
+ } /* case cf2_cmdESC */
+ break;
+
+ case cf2_cmdENDCHAR:
+ FT_TRACE4(( " endchar\n" ));
+
+ if ( cf2_stack_count( opStack ) == 1 ||
+ cf2_stack_count( opStack ) == 5 )
+ {
+ if ( !haveWidth )
+ *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
+ }
+
+ /* width is defined or default after this */
+ haveWidth = TRUE;
+
+ if ( font->decoder->width_only )
+ goto exit;
+
+ /* close path if still open */
+ cf2_glyphpath_closeOpenPath( &glyphPath );
+
+ if ( cf2_stack_count( opStack ) > 1 )
+ {
+ /* must be either 4 or 5 -- */
+ /* this is a (deprecated) implied `seac' operator */
+
+ CF2_UInt achar;
+ CF2_UInt bchar;
+ CF2_BufferRec component;
+ CF2_Fixed dummyWidth; /* ignore component width */
+ FT_Error error2;
+
+
+ if ( doingSeac )
+ {
+ lastError = FT_THROW( Invalid_Glyph_Format );
+ goto exit; /* nested seac */
+ }
+
+ achar = cf2_stack_popInt( opStack );
+ bchar = cf2_stack_popInt( opStack );
+
+ curY = cf2_stack_popFixed( opStack );
+ curX = cf2_stack_popFixed( opStack );
+
+ error2 = cf2_getSeacComponent( decoder, achar, &component );
+ if ( error2 )
+ {
+ lastError = error2; /* pass FreeType error through */
+ goto exit;
+ }
+ cf2_interpT2CharString( font,
+ &component,
+ callbacks,
+ translation,
+ TRUE,
+ curX,
+ curY,
+ &dummyWidth );
+ cf2_freeSeacComponent( decoder, &component );
+
+ error2 = cf2_getSeacComponent( decoder, bchar, &component );
+ if ( error2 )
+ {
+ lastError = error2; /* pass FreeType error through */
+ goto exit;
+ }
+ cf2_interpT2CharString( font,
+ &component,
+ callbacks,
+ translation,
+ TRUE,
+ 0,
+ 0,
+ &dummyWidth );
+ cf2_freeSeacComponent( decoder, &component );
+ }
+ goto exit;
+
+ case cf2_cmdCNTRMASK:
+ case cf2_cmdHINTMASK:
+ /* the final \n in the tracing message gets added in */
+ /* `cf2_hintmask_read' (which also traces the mask bytes) */
+ FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" ));
+
+ /* if there are arguments on the stack, there this is an */
+ /* implied cf2_cmdVSTEMHM */
+ if ( cf2_stack_count( opStack ) != 0 )
+ {
+ /* never add hints after the mask is computed */
+ if ( cf2_hintmask_isValid( &hintMask ) )
+ FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" ));
+ }
+
+ cf2_doStems( font,
+ opStack,
+ &vStemHintArray,
+ width,
+ &haveWidth,
+ 0 );
+
+ if ( font->decoder->width_only )
+ goto exit;
+
+ if ( op1 == cf2_cmdHINTMASK )
+ {
+ /* consume the hint mask bytes which follow the operator */
+ cf2_hintmask_read( &hintMask,
+ charstring,
+ cf2_arrstack_size( &hStemHintArray ) +
+ cf2_arrstack_size( &vStemHintArray ) );
+ }
+ else
+ {
+ /*
+ * Consume the counter mask bytes which follow the operator:
+ * Build a temporary hint map, just to place and lock those
+ * stems participating in the counter mask. These are most
+ * likely the dominant hstems, and are grouped together in a
+ * few counter groups, not necessarily in correspondence
+ * with the hint groups. This reduces the chances of
+ * conflicts between hstems that are initially placed in
+ * separate hint groups and then brought together. The
+ * positions are copied back to `hStemHintArray', so we can
+ * discard `counterMask' and `counterHintMap'.
+ *
+ */
+ CF2_HintMapRec counterHintMap;
+ CF2_HintMaskRec counterMask;
+
+
+ cf2_hintmap_init( &counterHintMap,
+ font,
+ &glyphPath.initialHintMap,
+ &glyphPath.hintMoves,
+ scaleY );
+ cf2_hintmask_init( &counterMask, error );
+
+ cf2_hintmask_read( &counterMask,
+ charstring,
+ cf2_arrstack_size( &hStemHintArray ) +
+ cf2_arrstack_size( &vStemHintArray ) );
+ cf2_hintmap_build( &counterHintMap,
+ &hStemHintArray,
+ &vStemHintArray,
+ &counterMask,
+ 0,
+ FALSE );
+ }
+ break;
+
+ case cf2_cmdRMOVETO:
+ FT_TRACE4(( " rmoveto\n" ));
+
+ if ( cf2_stack_count( opStack ) > 2 && !haveWidth )
+ *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
+
+ /* width is defined or default after this */
+ haveWidth = TRUE;
+
+ if ( font->decoder->width_only )
+ goto exit;
+
+ curY += cf2_stack_popFixed( opStack );
+ curX += cf2_stack_popFixed( opStack );
+
+ cf2_glyphpath_moveTo( &glyphPath, curX, curY );
+
+ break;
+
+ case cf2_cmdHMOVETO:
+ FT_TRACE4(( " hmoveto\n" ));
+
+ if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
+ *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
+
+ /* width is defined or default after this */
+ haveWidth = TRUE;
+
+ if ( font->decoder->width_only )
+ goto exit;
+
+ curX += cf2_stack_popFixed( opStack );
+
+ cf2_glyphpath_moveTo( &glyphPath, curX, curY );
+
+ break;
+
+ case cf2_cmdRLINECURVE:
+ {
+ CF2_UInt count = cf2_stack_count( opStack );
+ CF2_UInt index = 0;
+
+
+ FT_TRACE4(( " rlinecurve\n" ));
+
+ while ( index + 6 < count )
+ {
+ curX += cf2_stack_getReal( opStack, index + 0 );
+ curY += cf2_stack_getReal( opStack, index + 1 );
+
+ cf2_glyphpath_lineTo( &glyphPath, curX, curY );
+ index += 2;
+ }
+
+ while ( index < count )
+ {
+ CF2_Fixed x1 = cf2_stack_getReal( opStack, index + 0 ) + curX;
+ CF2_Fixed y1 = cf2_stack_getReal( opStack, index + 1 ) + curY;
+ CF2_Fixed x2 = cf2_stack_getReal( opStack, index + 2 ) + x1;
+ CF2_Fixed y2 = cf2_stack_getReal( opStack, index + 3 ) + y1;
+ CF2_Fixed x3 = cf2_stack_getReal( opStack, index + 4 ) + x2;
+ CF2_Fixed y3 = cf2_stack_getReal( opStack, index + 5 ) + y2;
+
+
+ cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
+
+ curX = x3;
+ curY = y3;
+ index += 6;
+ }
+
+ cf2_stack_clear( opStack );
+ }
+ continue; /* no need to clear stack again */
+
+ case cf2_cmdVVCURVETO:
+ {
+ CF2_UInt count = cf2_stack_count( opStack );
+ CF2_UInt index = 0;
+
+
+ FT_TRACE4(( " vvcurveto\n" ));
+
+ while ( index < count )
+ {
+ CF2_Fixed x1, y1, x2, y2, x3, y3;
+
+
+ if ( ( count - index ) & 1 )
+ {
+ x1 = cf2_stack_getReal( opStack, index ) + curX;
+
+ ++index;
+ }
+ else
+ x1 = curX;
+
+ y1 = cf2_stack_getReal( opStack, index + 0 ) + curY;
+ x2 = cf2_stack_getReal( opStack, index + 1 ) + x1;
+ y2 = cf2_stack_getReal( opStack, index + 2 ) + y1;
+ x3 = x2;
+ y3 = cf2_stack_getReal( opStack, index + 3 ) + y2;
+
+ cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
+
+ curX = x3;
+ curY = y3;
+ index += 4;
+ }
+
+ cf2_stack_clear( opStack );
+ }
+ continue; /* no need to clear stack again */
+
+ case cf2_cmdHHCURVETO:
+ {
+ CF2_UInt count = cf2_stack_count( opStack );
+ CF2_UInt index = 0;
+
+
+ FT_TRACE4(( " hhcurveto\n" ));
+
+ while ( index < count )
+ {
+ CF2_Fixed x1, y1, x2, y2, x3, y3;
+
+
+ if ( ( count - index ) & 1 )
+ {
+ y1 = cf2_stack_getReal( opStack, index ) + curY;
+
+ ++index;
+ }
+ else
+ y1 = curY;
+
+ x1 = cf2_stack_getReal( opStack, index + 0 ) + curX;
+ x2 = cf2_stack_getReal( opStack, index + 1 ) + x1;
+ y2 = cf2_stack_getReal( opStack, index + 2 ) + y1;
+ x3 = cf2_stack_getReal( opStack, index + 3 ) + x2;
+ y3 = y2;
+
+ cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
+
+ curX = x3;
+ curY = y3;
+ index += 4;
+ }
+
+ cf2_stack_clear( opStack );
+ }
+ continue; /* no need to clear stack again */
+
+ case cf2_cmdVHCURVETO:
+ case cf2_cmdHVCURVETO:
+ {
+ CF2_UInt count = cf2_stack_count( opStack );
+ CF2_UInt index = 0;
+
+ FT_Bool alternate = op1 == cf2_cmdHVCURVETO;
+
+
+ FT_TRACE4(( alternate ? " hvcurveto\n" : " vhcurveto\n" ));
+
+ while ( index < count )
+ {
+ CF2_Fixed x1, x2, x3, y1, y2, y3;
+
+
+ if ( alternate )
+ {
+ x1 = cf2_stack_getReal( opStack, index + 0 ) + curX;
+ y1 = curY;
+ x2 = cf2_stack_getReal( opStack, index + 1 ) + x1;
+ y2 = cf2_stack_getReal( opStack, index + 2 ) + y1;
+ y3 = cf2_stack_getReal( opStack, index + 3 ) + y2;
+
+ if ( count - index == 5 )
+ {
+ x3 = cf2_stack_getReal( opStack, index + 4 ) + x2;
+
+ ++index;
+ }
+ else
+ x3 = x2;
+
+ alternate = FALSE;
+ }
+ else
+ {
+ x1 = curX;
+ y1 = cf2_stack_getReal( opStack, index + 0 ) + curY;
+ x2 = cf2_stack_getReal( opStack, index + 1 ) + x1;
+ y2 = cf2_stack_getReal( opStack, index + 2 ) + y1;
+ x3 = cf2_stack_getReal( opStack, index + 3 ) + x2;
+
+ if ( count - index == 5 )
+ {
+ y3 = cf2_stack_getReal( opStack, index + 4 ) + y2;
+
+ ++index;
+ }
+ else
+ y3 = y2;
+
+ alternate = TRUE;
+ }
+
+ cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
+
+ curX = x3;
+ curY = y3;
+ index += 4;
+ }
+
+ cf2_stack_clear( opStack );
+ }
+ continue; /* no need to clear stack again */
+
+ case cf2_cmdEXTENDEDNMBR:
+ {
+ CF2_Int v;
+
+
+ v = (FT_Short)( ( cf2_buf_readByte( charstring ) << 8 ) |
+ cf2_buf_readByte( charstring ) );
+
+ FT_TRACE4(( " %d", v ));
+
+ cf2_stack_pushInt( opStack, v );
+ }
+ continue;
+
+ default:
+ /* numbers */
+ {
+ if ( /* op1 >= 32 && */ op1 <= 246 )
+ {
+ CF2_Int v;
+
+
+ v = op1 - 139;
+
+ FT_TRACE4(( " %d", v ));
+
+ /* -107 .. 107 */
+ cf2_stack_pushInt( opStack, v );
+ }
+
+ else if ( /* op1 >= 247 && */ op1 <= 250 )
+ {
+ CF2_Int v;
+
+
+ v = op1;
+ v -= 247;
+ v *= 256;
+ v += cf2_buf_readByte( charstring );
+ v += 108;
+
+ FT_TRACE4(( " %d", v ));
+
+ /* 108 .. 1131 */
+ cf2_stack_pushInt( opStack, v );
+ }
+
+ else if ( /* op1 >= 251 && */ op1 <= 254 )
+ {
+ CF2_Int v;
+
+
+ v = op1;
+ v -= 251;
+ v *= 256;
+ v += cf2_buf_readByte( charstring );
+ v = -v - 108;
+
+ FT_TRACE4(( " %d", v ));
+
+ /* -1131 .. -108 */
+ cf2_stack_pushInt( opStack, v );
+ }
+
+ else /* op1 == 255 */
+ {
+ CF2_Fixed v;
+
+
+ v = (CF2_Fixed)
+ ( ( (FT_UInt32)cf2_buf_readByte( charstring ) << 24 ) |
+ ( (FT_UInt32)cf2_buf_readByte( charstring ) << 16 ) |
+ ( (FT_UInt32)cf2_buf_readByte( charstring ) << 8 ) |
+ (FT_UInt32)cf2_buf_readByte( charstring ) );
+
+ FT_TRACE4(( " %.2f", v / 65536.0 ));
+
+ cf2_stack_pushFixed( opStack, v );
+ }
+ }
+ continue; /* don't clear stack */
+
+ } /* end of switch statement checking `op1' */
+
+ cf2_stack_clear( opStack );
+
+ } /* end of main interpreter loop */
+
+ /* we get here if the charstring ends without cf2_cmdENDCHAR */
+ FT_TRACE4(( "cf2_interpT2CharString:"
+ " charstring ends without ENDCHAR\n" ));
+
+ exit:
+ /* check whether last error seen is also the first one */
+ cf2_setError( error, lastError );
+
+ /* free resources from objects we've used */
+ cf2_glyphpath_finalize( &glyphPath );
+ cf2_arrstack_finalize( &vStemHintArray );
+ cf2_arrstack_finalize( &hStemHintArray );
+ cf2_arrstack_finalize( &subrStack );
+ cf2_stack_free( opStack );
+
+ FT_TRACE4(( "\n" ));
+
+ return;
+ }
+
+
+/* END */
diff --git a/src/cff/cf2intrp.h b/src/cff/cf2intrp.h
new file mode 100644
index 0000000..b5d8947
--- /dev/null
+++ b/src/cff/cf2intrp.h
@@ -0,0 +1,83 @@
+/***************************************************************************/
+/* */
+/* cf2font.h */
+/* */
+/* Adobe's CFF Interpreter (specification). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CF2INTRP_H__
+#define __CF2INTRP_H__
+
+
+#include "cf2ft.h"
+#include "cf2hints.h"
+
+
+FT_BEGIN_HEADER
+
+
+ FT_LOCAL( void )
+ cf2_hintmask_init( CF2_HintMask hintmask,
+ FT_Error* error );
+ FT_LOCAL( FT_Bool )
+ cf2_hintmask_isValid( const CF2_HintMask hintmask );
+ FT_LOCAL( FT_Bool )
+ cf2_hintmask_isNew( const CF2_HintMask hintmask );
+ FT_LOCAL( void )
+ cf2_hintmask_setNew( CF2_HintMask hintmask,
+ FT_Bool val );
+ FT_LOCAL( FT_Byte* )
+ cf2_hintmask_getMaskPtr( CF2_HintMask hintmask );
+ FT_LOCAL( void )
+ cf2_hintmask_setAll( CF2_HintMask hintmask,
+ size_t bitCount );
+
+ FT_LOCAL( void )
+ cf2_interpT2CharString( CF2_Font font,
+ CF2_Buffer charstring,
+ CF2_OutlineCallbacks callbacks,
+ const FT_Vector* translation,
+ FT_Bool doingSeac,
+ CF2_Fixed curX,
+ CF2_Fixed curY,
+ CF2_Fixed* width );
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2INTRP_H__ */
+
+
+/* END */
diff --git a/src/cff/cf2read.c b/src/cff/cf2read.c
new file mode 100644
index 0000000..cb671ec
--- /dev/null
+++ b/src/cff/cf2read.c
@@ -0,0 +1,112 @@
+/***************************************************************************/
+/* */
+/* cf2read.c */
+/* */
+/* Adobe's code for stream handling (body). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#include "cf2ft.h"
+#include FT_INTERNAL_DEBUG_H
+
+#include "cf2glue.h"
+
+#include "cf2error.h"
+
+
+ /* Define CF2_IO_FAIL as 1 to enable random errors and random */
+ /* value errors in I/O. */
+#define CF2_IO_FAIL 0
+
+
+#if CF2_IO_FAIL
+
+ /* set the .00 value to a nonzero probability */
+ static int
+ randomError2( void )
+ {
+ /* for region buffer ReadByte (interp) function */
+ return (double)rand() / RAND_MAX < .00;
+ }
+
+ /* set the .00 value to a nonzero probability */
+ static CF2_Int
+ randomValue()
+ {
+ return (double)rand() / RAND_MAX < .00 ? rand() : 0;
+ }
+
+#endif /* CF2_IO_FAIL */
+
+
+ /* Region Buffer */
+ /* */
+ /* Can be constructed from a copied buffer managed by */
+ /* `FCM_getDatablock'. */
+ /* Reads bytes with check for end of buffer. */
+
+ /* reading past the end of the buffer sets error and returns zero */
+ FT_LOCAL_DEF( CF2_Int )
+ cf2_buf_readByte( CF2_Buffer buf )
+ {
+ if ( buf->ptr < buf->end )
+ {
+#if CF2_IO_FAIL
+ if ( randomError2() )
+ {
+ CF2_SET_ERROR( buf->error, Invalid_Stream_Operation );
+ return 0;
+ }
+
+ return *(buf->ptr)++ + randomValue();
+#else
+ return *(buf->ptr)++;
+#endif
+ }
+ else
+ {
+ CF2_SET_ERROR( buf->error, Invalid_Stream_Operation );
+ return 0;
+ }
+ }
+
+
+ /* note: end condition can occur without error */
+ FT_LOCAL_DEF( FT_Bool )
+ cf2_buf_isEnd( CF2_Buffer buf )
+ {
+ return buf->ptr >= buf->end;
+ }
+
+
+/* END */
diff --git a/src/cff/cf2read.h b/src/cff/cf2read.h
new file mode 100644
index 0000000..7ef7c8c
--- /dev/null
+++ b/src/cff/cf2read.h
@@ -0,0 +1,68 @@
+/***************************************************************************/
+/* */
+/* cf2read.h */
+/* */
+/* Adobe's code for stream handling (specification). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CF2READ_H__
+#define __CF2READ_H__
+
+
+FT_BEGIN_HEADER
+
+
+ typedef struct CF2_BufferRec_
+ {
+ FT_Error* error;
+ const FT_Byte* start;
+ const FT_Byte* end;
+ const FT_Byte* ptr;
+
+ } CF2_BufferRec, *CF2_Buffer;
+
+
+ FT_LOCAL( CF2_Int )
+ cf2_buf_readByte( CF2_Buffer buf );
+ FT_LOCAL( FT_Bool )
+ cf2_buf_isEnd( CF2_Buffer buf );
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2READ_H__ */
+
+
+/* END */
diff --git a/src/cff/cf2stack.c b/src/cff/cf2stack.c
new file mode 100644
index 0000000..8332b5d
--- /dev/null
+++ b/src/cff/cf2stack.c
@@ -0,0 +1,205 @@
+/***************************************************************************/
+/* */
+/* cf2stack.c */
+/* */
+/* Adobe's code for emulating a CFF stack (body). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#include "cf2ft.h"
+#include FT_INTERNAL_DEBUG_H
+
+#include "cf2glue.h"
+#include "cf2font.h"
+#include "cf2stack.h"
+
+#include "cf2error.h"
+
+
+ /* Allocate and initialize an instance of CF2_Stack. */
+ /* Note: This function returns NULL on error (does not set */
+ /* `error'). */
+ FT_LOCAL_DEF( CF2_Stack )
+ cf2_stack_init( FT_Memory memory,
+ FT_Error* e )
+ {
+ FT_Error error = FT_Err_Ok; /* for FT_QNEW */
+
+ CF2_Stack stack = NULL;
+
+
+ if ( !FT_QNEW( stack ) )
+ {
+ /* initialize the structure; FT_QNEW zeroes it */
+ stack->memory = memory;
+ stack->error = e;
+ stack->top = &stack->buffer[0]; /* empty stack */
+ }
+
+ return stack;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_stack_free( CF2_Stack stack )
+ {
+ if ( stack )
+ {
+ FT_Memory memory = stack->memory;
+
+
+ /* free the main structure */
+ FT_FREE( stack );
+ }
+ }
+
+
+ FT_LOCAL_DEF( CF2_UInt )
+ cf2_stack_count( CF2_Stack stack )
+ {
+ return (CF2_UInt)( stack->top - &stack->buffer[0] );
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_stack_pushInt( CF2_Stack stack,
+ CF2_Int val )
+ {
+ if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
+ {
+ CF2_SET_ERROR( stack->error, Stack_Overflow );
+ return; /* stack overflow */
+ }
+
+ stack->top->u.i = val;
+ stack->top->type = CF2_NumberInt;
+ ++stack->top;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_stack_pushFixed( CF2_Stack stack,
+ CF2_Fixed val )
+ {
+ if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
+ {
+ CF2_SET_ERROR( stack->error, Stack_Overflow );
+ return; /* stack overflow */
+ }
+
+ stack->top->u.r = val;
+ stack->top->type = CF2_NumberFixed;
+ ++stack->top;
+ }
+
+
+ /* this function is only allowed to pop an integer type */
+ FT_LOCAL_DEF( CF2_Int )
+ cf2_stack_popInt( CF2_Stack stack )
+ {
+ if ( stack->top == &stack->buffer[0] )
+ {
+ CF2_SET_ERROR( stack->error, Stack_Underflow );
+ return 0; /* underflow */
+ }
+ if ( stack->top[-1].type != CF2_NumberInt )
+ {
+ CF2_SET_ERROR( stack->error, Syntax_Error );
+ return 0; /* type mismatch */
+ }
+
+ --stack->top;
+
+ return stack->top->u.i;
+ }
+
+
+ /* Note: type mismatch is silently cast */
+ /* TODO: check this */
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_stack_popFixed( CF2_Stack stack )
+ {
+ if ( stack->top == &stack->buffer[0] )
+ {
+ CF2_SET_ERROR( stack->error, Stack_Underflow );
+ return cf2_intToFixed( 0 ); /* underflow */
+ }
+
+ --stack->top;
+
+ switch ( stack->top->type )
+ {
+ case CF2_NumberInt:
+ return cf2_intToFixed( stack->top->u.i );
+ case CF2_NumberFrac:
+ return cf2_fracToFixed( stack->top->u.f );
+ default:
+ return stack->top->u.r;
+ }
+ }
+
+
+ /* Note: type mismatch is silently cast */
+ /* TODO: check this */
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_stack_getReal( CF2_Stack stack,
+ CF2_UInt idx )
+ {
+ FT_ASSERT( cf2_stack_count( stack ) <= CF2_OPERAND_STACK_SIZE );
+
+ if ( idx >= cf2_stack_count( stack ) )
+ {
+ CF2_SET_ERROR( stack->error, Stack_Overflow );
+ return cf2_intToFixed( 0 ); /* bounds error */
+ }
+
+ switch ( stack->buffer[idx].type )
+ {
+ case CF2_NumberInt:
+ return cf2_intToFixed( stack->buffer[idx].u.i );
+ case CF2_NumberFrac:
+ return cf2_fracToFixed( stack->buffer[idx].u.f );
+ default:
+ return stack->buffer[idx].u.r;
+ }
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_stack_clear( CF2_Stack stack )
+ {
+ stack->top = &stack->buffer[0];
+ }
+
+
+/* END */
diff --git a/src/cff/cf2stack.h b/src/cff/cf2stack.h
new file mode 100644
index 0000000..7d6d196
--- /dev/null
+++ b/src/cff/cf2stack.h
@@ -0,0 +1,106 @@
+/***************************************************************************/
+/* */
+/* cf2stack.h */
+/* */
+/* Adobe's code for emulating a CFF stack (specification). */
+/* */
+/* Copyright 2007-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CF2STACK_H__
+#define __CF2STACK_H__
+
+
+FT_BEGIN_HEADER
+
+
+ /* CFF operand stack; specified maximum of 48 or 192 values */
+ typedef struct CF2_StackNumber_
+ {
+ union
+ {
+ CF2_Fixed r; /* 16.16 fixed point */
+ CF2_Frac f; /* 2.30 fixed point (for font matrix) */
+ CF2_Int i;
+ } u;
+
+ CF2_NumberType type;
+
+ } CF2_StackNumber;
+
+
+ typedef struct CF2_StackRec_
+ {
+ FT_Memory memory;
+ FT_Error* error;
+ CF2_StackNumber buffer[CF2_OPERAND_STACK_SIZE];
+ CF2_StackNumber* top;
+
+ } CF2_StackRec, *CF2_Stack;
+
+
+ FT_LOCAL( CF2_Stack )
+ cf2_stack_init( FT_Memory memory,
+ FT_Error* error );
+ FT_LOCAL( void )
+ cf2_stack_free( CF2_Stack stack );
+
+ FT_LOCAL( CF2_UInt )
+ cf2_stack_count( CF2_Stack stack );
+
+ FT_LOCAL( void )
+ cf2_stack_pushInt( CF2_Stack stack,
+ CF2_Int val );
+ FT_LOCAL( void )
+ cf2_stack_pushFixed( CF2_Stack stack,
+ CF2_Fixed val );
+
+ FT_LOCAL( CF2_Int )
+ cf2_stack_popInt( CF2_Stack stack );
+ FT_LOCAL( CF2_Fixed )
+ cf2_stack_popFixed( CF2_Stack stack );
+
+ FT_LOCAL( CF2_Fixed )
+ cf2_stack_getReal( CF2_Stack stack,
+ CF2_UInt idx );
+
+ FT_LOCAL( void )
+ cf2_stack_clear( CF2_Stack stack );
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2STACK_H__ */
+
+
+/* END */
diff --git a/src/cff/cf2types.h b/src/cff/cf2types.h
new file mode 100644
index 0000000..ac6a022
--- /dev/null
+++ b/src/cff/cf2types.h
@@ -0,0 +1,78 @@
+/***************************************************************************/
+/* */
+/* cf2types.h */
+/* */
+/* Adobe's code for defining data types (specification only). */
+/* */
+/* Copyright 2011-2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __CF2TYPES_H__
+#define __CF2TYPES_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+
+FT_BEGIN_HEADER
+
+
+ /*
+ * The data models that we expect to support are as follows:
+ *
+ * name char short int long long-long pointer example
+ * -----------------------------------------------------
+ * ILP32 8 16 32 32 64* 32 32-bit MacOS, x86
+ * LLP64 8 16 32 32 64 64 x64
+ * LP64 8 16 32 64 64 64 64-bit MacOS
+ *
+ * *) type may be supported by emulation on a 32-bit architecture
+ *
+ */
+
+
+ /* integers at least 32 bits wide */
+#define CF2_UInt FT_UFast
+#define CF2_Int FT_Fast
+
+
+ /* fixed-float numbers */
+ typedef FT_Int32 CF2_F16Dot16;
+
+
+FT_END_HEADER
+
+
+#endif /* __CF2TYPES_H__ */
+
+
+/* END */
diff --git a/src/cff/cff.c b/src/cff/cff.c
index fccfd44..c3840b5 100644
--- a/src/cff/cff.c
+++ b/src/cff/cff.c
@@ -4,7 +4,7 @@
/* */
/* FreeType OpenType driver component (body only). */
/* */
-/* Copyright 1996-2001, 2002 by */
+/* Copyright 1996-2001, 2002, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -19,6 +19,7 @@
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include <ft2build.h>
+
#include "cffpic.c"
#include "cffdrivr.c"
#include "cffparse.c"
@@ -27,4 +28,14 @@
#include "cffgload.c"
#include "cffcmap.c"
+#include "cf2arrst.c"
+#include "cf2blues.c"
+#include "cf2error.c"
+#include "cf2font.c"
+#include "cf2ft.c"
+#include "cf2hints.c"
+#include "cf2intrp.c"
+#include "cf2read.c"
+#include "cf2stack.c"
+
/* END */
diff --git a/src/cff/cffcmap.c b/src/cff/cffcmap.c
index 1298371..f6e03c6 100644
--- a/src/cff/cffcmap.c
+++ b/src/cff/cffcmap.c
@@ -4,7 +4,7 @@
/* */
/* CFF character mapping table (cmap) support (body). */
/* */
-/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2010 by */
+/* Copyright 2002-2007, 2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,6 +16,8 @@
/***************************************************************************/
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
#include "cffcmap.h"
#include "cffload.h"
@@ -145,7 +147,7 @@
/* can't build Unicode map for CID-keyed font */
/* because we don't know glyph names. */
if ( !charset->sids )
- return CFF_Err_No_Unicode_Glyph_Name;
+ return FT_THROW( No_Unicode_Glyph_Name );
return psnames->unicodes_init( memory,
unicodes,
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index eb4c14e..c8ca96b 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -4,7 +4,7 @@
/* */
/* OpenType font driver implementation (body). */
/* */
-/* Copyright 1996-2012 by */
+/* Copyright 1996-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -37,6 +37,8 @@
#include FT_SERVICE_XFREE86_NAME_H
#include FT_SERVICE_GLYPH_DICT_H
+#include FT_SERVICE_PROPERTIES_H
+#include FT_CFF_DRIVER_H
/*************************************************************************/
@@ -115,7 +117,7 @@
if ( sfnt )
kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
- return CFF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -160,7 +162,7 @@
if ( !slot )
- return CFF_Err_Invalid_Slot_Handle;
+ return FT_THROW( Invalid_Slot_Handle );
/* check whether we want a scaled outline or bitmap */
if ( !size )
@@ -174,7 +176,7 @@
{
/* these two objects must have the same parent */
if ( cffsize->face != cffslot->face )
- return CFF_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
}
/* now load the glyph outline if necessary */
@@ -195,7 +197,7 @@
FT_Fixed* advances )
{
FT_UInt nn;
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_GlyphSlot slot = face->glyph;
@@ -239,7 +241,7 @@
" cannot get glyph name from CFF & CEF fonts\n"
" "
" without the `PSNames' module\n" ));
- error = CFF_Err_Missing_Module;
+ error = FT_THROW( Missing_Module );
goto Exit;
}
@@ -252,7 +254,7 @@
if ( gname )
FT_STRCPYN( buffer, gname, buffer_max );
- error = CFF_Err_Ok;
+ error = FT_Err_Ok;
Exit:
return error;
@@ -298,7 +300,8 @@
}
- FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict,
+ FT_DEFINE_SERVICE_GLYPHDICTREC(
+ cff_service_glyph_dict,
(FT_GlyphDict_GetNameFunc) cff_get_glyph_name,
(FT_GlyphDict_NameIndexFunc)cff_get_name_index
)
@@ -321,7 +324,7 @@
PS_FontInfoRec* afont_info )
{
CFF_Font cff = (CFF_Font)face->extra.data;
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( cff && cff->font_info == NULL )
@@ -360,7 +363,8 @@
}
- FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info,
+ FT_DEFINE_SERVICE_PSINFOREC(
+ cff_service_ps_info,
(PS_GetFontInfoFunc) cff_ps_get_font_info,
(PS_GetFontExtraFunc) NULL,
(PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
@@ -384,7 +388,8 @@
}
- FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name,
+ FT_DEFINE_SERVICE_PSFONTNAMEREC(
+ cff_service_ps_name,
(FT_PsName_GetFunc)cff_get_ps_name
)
@@ -404,16 +409,17 @@
TT_CMapInfo *cmap_info )
{
FT_CMap cmap = FT_CMAP( charmap );
- FT_Error error = CFF_Err_Ok;
- FT_Face face = FT_CMAP_FACE( cmap );
- FT_Library library = FT_FACE_LIBRARY( face );
+ FT_Error error = FT_Err_Ok;
+
+ FT_Face face = FT_CMAP_FACE( cmap );
+ FT_Library library = FT_FACE_LIBRARY( face );
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 =
@@ -429,7 +435,8 @@
}
- FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info,
+ FT_DEFINE_SERVICE_TTCMAPSREC(
+ cff_service_get_cmap_info,
(TT_CMap_Info_GetFunc)cff_get_cmap_info
)
@@ -444,7 +451,7 @@
const char* *ordering,
FT_Int *supplement )
{
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
CFF_Font cff = (CFF_Font)face->extra.data;
@@ -455,7 +462,7 @@
if ( dict->cid_registry == 0xFFFFU )
{
- error = CFF_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Fail;
}
@@ -499,7 +506,7 @@
cff_get_is_cid( CFF_Face face,
FT_Bool *is_cid )
{
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
CFF_Font cff = (CFF_Font)face->extra.data;
@@ -523,7 +530,7 @@
FT_UInt glyph_index,
FT_UInt *cid )
{
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
CFF_Font cff;
@@ -537,13 +544,13 @@
if ( dict->cid_registry == 0xFFFFU )
{
- error = CFF_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Fail;
}
if ( glyph_index > cff->num_glyphs )
{
- error = CFF_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Fail;
}
@@ -558,13 +565,100 @@
}
- FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info,
+ FT_DEFINE_SERVICE_CIDREC(
+ cff_service_cid_info,
(FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros,
(FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid,
(FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index
)
+ /*
+ * PROPERTY SERVICE
+ *
+ */
+ static FT_Error
+ cff_property_set( FT_Module module, /* CFF_Driver */
+ const char* property_name,
+ const void* value )
+ {
+ FT_Error error = FT_Err_Ok;
+ CFF_Driver driver = (CFF_Driver)module;
+
+
+ if ( !ft_strcmp( property_name, "hinting-engine" ) )
+ {
+ FT_UInt* hinting_engine = (FT_UInt*)value;
+
+
+#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
+ if ( *hinting_engine != FT_CFF_HINTING_ADOBE )
+ error = FT_ERR( Unimplemented_Feature );
+ else
+#endif
+ driver->hinting_engine = *hinting_engine;
+
+ return error;
+ }
+ else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
+ {
+ FT_Bool* no_stem_darkening = (FT_Bool*)value;
+
+
+ driver->no_stem_darkening = *no_stem_darkening;
+
+ return error;
+ }
+
+ FT_TRACE0(( "cff_property_set: missing property `%s'\n",
+ property_name ));
+ return FT_THROW( Missing_Property );
+ }
+
+
+ static FT_Error
+ cff_property_get( FT_Module module, /* CFF_Driver */
+ const char* property_name,
+ const void* value )
+ {
+ FT_Error error = FT_Err_Ok;
+ CFF_Driver driver = (CFF_Driver)module;
+
+ FT_UInt hinting_engine = driver->hinting_engine;
+ FT_Bool no_stem_darkening = driver->no_stem_darkening;
+
+
+ if ( !ft_strcmp( property_name, "hinting-engine" ) )
+ {
+ FT_UInt* val = (FT_UInt*)value;
+
+
+ *val = hinting_engine;
+
+ return error;
+ }
+ else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
+ {
+ FT_Bool* val = (FT_Bool*)value;
+
+
+ *val = no_stem_darkening;
+
+ return error;
+ }
+
+ FT_TRACE0(( "cff_property_get: missing property `%s'\n",
+ property_name ));
+ return FT_THROW( Missing_Property );
+ }
+
+
+ FT_DEFINE_SERVICE_PROPERTIESREC(
+ cff_service_properties,
+ (FT_Properties_SetFunc)cff_property_set,
+ (FT_Properties_GetFunc)cff_property_get )
+
+
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
@@ -576,25 +670,31 @@
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
+
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
- FT_DEFINE_SERVICEDESCREC6(cff_services,
+ FT_DEFINE_SERVICEDESCREC7(
+ 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,
+ FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET
)
#else
- FT_DEFINE_SERVICEDESCREC5(cff_services,
+ 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_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,
+ FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET
)
#endif
+
FT_CALLBACK_DEF( FT_Module_Interface )
cff_get_interface( FT_Module driver, /* CFF_Driver */
const char* module_interface )
@@ -604,7 +704,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 +713,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;
@@ -641,7 +741,8 @@
#define CFF_SIZE_SELECT 0
#endif
- FT_DEFINE_DRIVER( cff_driver_class,
+ FT_DEFINE_DRIVER(
+ cff_driver_class,
FT_MODULE_FONT_DRIVER |
FT_MODULE_DRIVER_SCALABLE |
@@ -670,9 +771,6 @@
cff_slot_init,
cff_slot_done,
- ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
cff_glyph_load,
cff_get_kerning,
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 84847fd..1904ca0 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -4,7 +4,7 @@
/* */
/* OpenType Glyph Loader (body). */
/* */
-/* Copyright 1996-2012 by */
+/* Copyright 1996-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -21,10 +21,12 @@
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H
#include FT_OUTLINE_H
+#include FT_CFF_DRIVER_H
#include "cffobjs.h"
#include "cffload.h"
#include "cffgload.h"
+#include "cf2ft.h" /* for cf2_decoder_parse_charstrings */
#include "cfferrs.h"
@@ -39,6 +41,8 @@
#define FT_COMPONENT trace_cffgload
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+
typedef enum CFF_Operator_
{
cff_op_unknown = 0,
@@ -209,6 +213,8 @@
2 /* setcurrentpoint */
};
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
+
/*************************************************************************/
/*************************************************************************/
@@ -412,7 +418,7 @@
CFF_Builder *builder = &decoder->builder;
CFF_Font cff = (CFF_Font)builder->face->extra.data;
CFF_SubFont sub = &cff->top_font;
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
/* manage CID fonts */
@@ -424,7 +430,7 @@
if ( fd_index >= cff->num_subfonts )
{
FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
- error = CFF_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -455,22 +461,24 @@
decoder->glyph_width = sub->private_dict.default_width;
decoder->nominal_width = sub->private_dict.nominal_width;
+ decoder->current_subfont = sub; /* for Adobe's CFF handler */
+
Exit:
return error;
}
/* check that there is enough space for `count' more points */
- static FT_Error
- check_points( CFF_Builder* builder,
- FT_Int count )
+ FT_LOCAL_DEF( FT_Error )
+ cff_check_points( CFF_Builder* builder,
+ FT_Int count )
{
return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
}
/* add a new point, do not check space */
- static void
+ FT_LOCAL_DEF( void )
cff_builder_add_point( CFF_Builder* builder,
FT_Pos x,
FT_Pos y,
@@ -484,9 +492,22 @@
FT_Vector* point = outline->points + outline->n_points;
FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+ CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face );
+
- point->x = x >> 16;
- point->y = y >> 16;
+ if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
+ {
+ point->x = x >> 16;
+ point->y = y >> 16;
+ }
+ else
+#endif
+ {
+ /* cf2_decoder_parse_charstrings uses 16.16 coordinates */
+ point->x = x >> 10;
+ point->y = y >> 10;
+ }
*control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
}
@@ -495,7 +516,7 @@
/* check space for a new on-curve point, then add it */
- static FT_Error
+ FT_LOCAL_DEF( FT_Error )
cff_builder_add_point1( CFF_Builder* builder,
FT_Pos x,
FT_Pos y )
@@ -503,7 +524,7 @@
FT_Error error;
- error = check_points( builder, 1 );
+ error = cff_check_points( builder, 1 );
if ( !error )
cff_builder_add_point( builder, x, y, 1 );
@@ -522,7 +543,7 @@
if ( !builder->load_points )
{
outline->n_contours++;
- return CFF_Err_Ok;
+ return FT_Err_Ok;
}
error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
@@ -540,12 +561,12 @@
/* if a path was begun, add its first on-curve point */
- static FT_Error
+ FT_LOCAL_DEF( FT_Error )
cff_builder_start_point( CFF_Builder* builder,
FT_Pos x,
FT_Pos y )
{
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
/* test whether we are building a new contour */
@@ -562,7 +583,7 @@
/* close the current contour */
- static void
+ FT_LOCAL_DEF( void )
cff_builder_close_contour( CFF_Builder* builder )
{
FT_Outline* outline = builder->current;
@@ -607,7 +628,7 @@
}
- static FT_Int
+ FT_LOCAL_DEF( FT_Int )
cff_lookup_glyph_by_stdcharcode( CFF_Font cff,
FT_Int charcode )
{
@@ -636,7 +657,7 @@
}
- static FT_Error
+ FT_LOCAL_DEF( FT_Error )
cff_get_glyph_data( TT_Face face,
FT_UInt glyph_index,
FT_Byte** pointer,
@@ -672,7 +693,7 @@
}
- static void
+ FT_LOCAL_DEF( void )
cff_free_glyph_data( TT_Face face,
FT_Byte** pointer,
FT_ULong length )
@@ -707,6 +728,8 @@
}
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+
static FT_Error
cff_operator_seac( CFF_Decoder* decoder,
FT_Pos asb,
@@ -728,7 +751,7 @@
if ( decoder->seac )
{
FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
- return CFF_Err_Syntax_Error;
+ return FT_THROW( Syntax_Error );
}
adx += decoder->builder.left_bearing.x;
@@ -756,7 +779,7 @@
{
FT_ERROR(( "cff_operator_seac:"
" invalid seac character code arguments\n" ));
- return CFF_Err_Syntax_Error;
+ return FT_THROW( Syntax_Error );
}
/* If we are trying to load a composite glyph, do not load the */
@@ -925,7 +948,7 @@
limit = zone->limit = charstring_base + charstring_len;
ip = zone->cursor = zone->base;
- error = CFF_Err_Ok;
+ error = FT_Err_Ok;
x = builder->pos_x;
y = builder->pos_y;
@@ -953,11 +976,14 @@
/* this is an operand, push it on the stack */
+
+ /* if we use shifts, all computations are done with unsigned */
+ /* values; the conversion to a signed value is the last step */
if ( v == 28 )
{
if ( ip + 1 >= limit )
goto Syntax_Error;
- val = (FT_Short)( ( (FT_Short)ip[0] << 8 ) | ip[1] );
+ val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
ip += 2;
}
else if ( v < 247 )
@@ -978,10 +1004,10 @@
{
if ( ip + 3 >= limit )
goto Syntax_Error;
- val = ( (FT_Int32)ip[0] << 24 ) |
- ( (FT_Int32)ip[1] << 16 ) |
- ( (FT_Int32)ip[2] << 8 ) |
- ip[3];
+ val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
+ ( (FT_UInt32)ip[1] << 16 ) |
+ ( (FT_UInt32)ip[2] << 8 ) |
+ (FT_UInt32)ip[3] );
ip += 4;
if ( charstring_type == 2 )
shift = 0;
@@ -989,12 +1015,12 @@
if ( decoder->top - stack >= CFF_MAX_OPERANDS )
goto Stack_Overflow;
- val <<= shift;
+ val = (FT_Int32)( (FT_UInt32)val << shift );
*decoder->top++ = val;
#ifdef FT_DEBUG_LEVEL_TRACE
if ( !( val & 0xFFFFL ) )
- FT_TRACE4(( " %ld", (FT_Int32)( val >> 16 ) ));
+ FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
else
FT_TRACE4(( " %.2f", val / 65536.0 ));
#endif
@@ -1411,8 +1437,8 @@
case cff_op_rlineto:
FT_TRACE4(( " rlineto\n" ));
- if ( cff_builder_start_point ( builder, x, y ) ||
- check_points( builder, num_args / 2 ) )
+ if ( cff_builder_start_point( builder, x, y ) ||
+ cff_check_points( builder, num_args / 2 ) )
goto Fail;
if ( num_args < 2 )
@@ -1446,8 +1472,8 @@
if ( num_args == 0 )
break;
- if ( cff_builder_start_point ( builder, x, y ) ||
- check_points( builder, num_args ) )
+ if ( cff_builder_start_point( builder, x, y ) ||
+ cff_check_points( builder, num_args ) )
goto Fail;
args = stack;
@@ -1480,8 +1506,8 @@
nargs = num_args - num_args % 6;
- if ( cff_builder_start_point ( builder, x, y ) ||
- check_points( builder, nargs / 2 ) )
+ if ( cff_builder_start_point( builder, x, y ) ||
+ cff_check_points( builder, nargs / 2 ) )
goto Fail;
args -= nargs;
@@ -1529,7 +1555,7 @@
nargs--;
}
- if ( check_points( builder, 3 * ( nargs / 4 ) ) )
+ if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
goto Fail;
while ( args < decoder->top )
@@ -1573,7 +1599,7 @@
nargs--;
}
- if ( check_points( builder, 3 * ( nargs / 4 ) ) )
+ if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
goto Fail;
while ( args < decoder->top )
@@ -1613,7 +1639,7 @@
nargs = num_args & ~2;
args -= nargs;
- if ( check_points( builder, ( nargs / 4 ) * 3 ) )
+ if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
goto Stack_Underflow;
phase = ( op == cff_op_hvcurveto );
@@ -1666,8 +1692,8 @@
nargs = num_args & ~1;
num_lines = ( nargs - 6 ) / 2;
- if ( cff_builder_start_point( builder, x, y ) ||
- check_points( builder, num_lines + 3 ) )
+ if ( cff_builder_start_point( builder, x, y ) ||
+ cff_check_points( builder, num_lines + 3 ) )
goto Fail;
args -= nargs;
@@ -1711,8 +1737,8 @@
nargs = nargs - nargs % 6 + 2;
num_curves = ( nargs - 2 ) / 6;
- if ( cff_builder_start_point ( builder, x, y ) ||
- check_points( builder, num_curves * 3 + 2 ) )
+ if ( cff_builder_start_point( builder, x, y ) ||
+ cff_check_points( builder, num_curves * 3 + 2 ) )
goto Fail;
args -= nargs;
@@ -1752,7 +1778,7 @@
/* -- make sure we have enough space for the start point if it */
/* needs to be added */
if ( cff_builder_start_point( builder, x, y ) ||
- check_points( builder, 6 ) )
+ cff_check_points( builder, 6 ) )
goto Fail;
/* record the starting point's y position for later use */
@@ -1801,7 +1827,7 @@
/* adding six more points; 4 control points, 2 on-curve points */
if ( cff_builder_start_point( builder, x, y ) ||
- check_points( builder, 6 ) )
+ cff_check_points( builder, 6 ) )
goto Fail;
/* record the starting point's y-position for later use */
@@ -1854,7 +1880,7 @@
/* adding six more points; 4 control points, 2 on-curve points */
if ( cff_builder_start_point( builder, x, y ) ||
- check_points( builder, 6 ) )
+ cff_check_points( builder, 6 ) )
goto Fail;
/* record the starting point's x, y position for later use */
@@ -1917,7 +1943,7 @@
FT_TRACE4(( " flex\n" ));
if ( cff_builder_start_point( builder, x, y ) ||
- check_points( builder, 6 ) )
+ cff_check_points( builder, 6 ) )
goto Fail;
for ( count = 6; count > 0; count-- )
@@ -1968,7 +1994,7 @@
else
{
if ( !error )
- error = CFF_Err_Ok;
+ error = FT_Err_Ok;
cff_builder_close_contour( builder );
@@ -2470,7 +2496,7 @@
FT_ERROR(( " %d", ip[0] ));
FT_ERROR(( "\n" ));
- return CFF_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
}
decoder->top = args;
@@ -2489,17 +2515,19 @@
Syntax_Error:
FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
- return CFF_Err_Invalid_File_Format;
+ return FT_THROW( Invalid_File_Format );
Stack_Underflow:
FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
- return CFF_Err_Too_Few_Arguments;
+ return FT_THROW( Too_Few_Arguments );
Stack_Overflow:
FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
- return CFF_Err_Stack_Overflow;
+ return FT_THROW( Stack_Overflow );
}
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
+
/*************************************************************************/
/*************************************************************************/
@@ -2526,7 +2554,7 @@
cff_compute_max_advance( TT_Face face,
FT_Int* max_advance )
{
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
CFF_Decoder decoder;
FT_Int glyph_index;
CFF_Font cff = (CFF_Font)face->other;
@@ -2564,12 +2592,12 @@
}
/* ignore the error if one has occurred -- skip to next glyph */
- error = CFF_Err_Ok;
+ error = FT_Err_Ok;
}
*max_advance = decoder.builder.advance.x;
- return CFF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -2585,7 +2613,7 @@
FT_Error error;
CFF_Decoder decoder;
TT_Face face = (TT_Face)glyph->root.face;
- FT_Bool hinting, force_scaling;
+ FT_Bool hinting, scaled, force_scaling;
CFF_Font cff = (CFF_Font)face->extra.data;
FT_Matrix font_matrix;
@@ -2606,11 +2634,11 @@
glyph_index = cff_charset_cid_to_gindex( &cff->charset,
glyph_index );
if ( glyph_index == 0 )
- return CFF_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
}
else if ( glyph_index >= cff->num_glyphs )
- return CFF_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( load_flags & FT_LOAD_NO_RECURSE )
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
@@ -2653,6 +2681,11 @@
if ( !error )
{
+ FT_Bool has_vertical_info;
+ FT_UShort advance;
+ FT_Short dummy;
+
+
glyph->root.outline.n_points = 0;
glyph->root.outline.n_contours = 0;
@@ -2679,6 +2712,39 @@
glyph->root.bitmap_left = metrics.horiBearingX;
glyph->root.bitmap_top = metrics.horiBearingY;
}
+
+ /* compute linear advance widths */
+
+ ( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
+ glyph_index,
+ &dummy,
+ &advance );
+ glyph->root.linearHoriAdvance = advance;
+
+ has_vertical_info = FT_BOOL(
+ face->vertical_info &&
+ face->vertical.number_Of_VMetrics > 0 );
+
+ /* get the vertical metrics from the vtmx table if we have one */
+ if ( has_vertical_info )
+ {
+ ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
+ glyph_index,
+ &dummy,
+ &advance );
+ glyph->root.linearVertAdvance = advance;
+ }
+ else
+ {
+ /* make up vertical ones */
+ if ( face->os2.version != 0xFFFFU )
+ glyph->root.linearVertAdvance = (FT_Pos)
+ ( face->os2.sTypoAscender - face->os2.sTypoDescender );
+ else
+ glyph->root.linearVertAdvance = (FT_Pos)
+ ( face->horizontal.Ascender - face->horizontal.Descender );
+ }
+
return error;
}
}
@@ -2688,7 +2754,7 @@
/* return immediately if we only want the embedded bitmaps */
if ( load_flags & FT_LOAD_SBITS_ONLY )
- return CFF_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* if we have a CID subfont, use its matrix (which has already */
/* been multiplied with the root matrix) */
@@ -2700,6 +2766,7 @@
FT_Byte fd_index = cff_fd_select_get( &cff->fd_select,
glyph_index );
+
if ( fd_index >= cff->num_subfonts )
fd_index = (FT_Byte)( cff->num_subfonts - 1 );
@@ -2727,12 +2794,21 @@
glyph->root.outline.n_points = 0;
glyph->root.outline.n_contours = 0;
- hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
- ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
+ /* top-level code ensures that FT_LOAD_NO_HINTING is set */
+ /* if FT_LOAD_NO_SCALE is active */
+ hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
+ scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
+ glyph->hint = hinting;
+ glyph->scaled = scaled;
glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */
{
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+ CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( face );
+#endif
+
+
FT_Byte* charstring;
FT_ULong charstring_len;
@@ -2756,9 +2832,26 @@
if ( error )
goto Glyph_Build_Finished;
- error = cff_decoder_parse_charstrings( &decoder,
- charstring,
- charstring_len );
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+ /* choose which CFF renderer to use */
+ if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
+ error = cff_decoder_parse_charstrings( &decoder,
+ charstring,
+ charstring_len );
+ else
+#endif
+ {
+ error = cf2_decoder_parse_charstrings( &decoder,
+ charstring,
+ charstring_len );
+
+ /* Adobe's engine uses 16.16 numbers everywhere; */
+ /* as a consequence, glyphs larger than 2000ppem get rejected */
+ if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
+ {
+ /* XXX to be implemented */
+ }
+ }
cff_free_glyph_data( face, &charstring, charstring_len );
@@ -2856,14 +2949,8 @@
glyph->root.linearHoriAdvance = decoder.glyph_width;
glyph->root.internal->glyph_transformed = 0;
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- has_vertical_info = FT_BOOL( face->vertical_info &&
- face->vertical.number_Of_VMetrics > 0 &&
- face->vertical.long_metrics );
-#else
has_vertical_info = FT_BOOL( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 );
-#endif
/* get the vertical metrics from the vtmx table if we have one */
if ( has_vertical_info )
diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h
index 38937be..41df7db 100644
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -4,7 +4,7 @@
/* */
/* OpenType Glyph Loader (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */
+/* Copyright 1996-2004, 2006-2009, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -106,6 +106,41 @@ FT_BEGIN_HEADER
} CFF_Builder;
+ FT_LOCAL( FT_Error )
+ cff_check_points( CFF_Builder* builder,
+ FT_Int count );
+
+ FT_LOCAL( void )
+ cff_builder_add_point( CFF_Builder* builder,
+ FT_Pos x,
+ FT_Pos y,
+ FT_Byte flag );
+ FT_LOCAL( FT_Error )
+ cff_builder_add_point1( CFF_Builder* builder,
+ FT_Pos x,
+ FT_Pos y );
+ FT_LOCAL( FT_Error )
+ cff_builder_start_point( CFF_Builder* builder,
+ FT_Pos x,
+ FT_Pos y );
+ FT_LOCAL( void )
+ cff_builder_close_contour( CFF_Builder* builder );
+
+
+ FT_LOCAL( FT_Int )
+ cff_lookup_glyph_by_stdcharcode( CFF_Font cff,
+ FT_Int charcode );
+ FT_LOCAL( FT_Error )
+ cff_get_glyph_data( TT_Face face,
+ FT_UInt glyph_index,
+ FT_Byte** pointer,
+ FT_ULong* length );
+ FT_LOCAL( void )
+ cff_free_glyph_data( TT_Face face,
+ FT_Byte** pointer,
+ FT_ULong length );
+
+
/* execution context charstring zone */
typedef struct CFF_Decoder_Zone_
@@ -156,6 +191,8 @@ FT_BEGIN_HEADER
FT_Bool seac;
+ CFF_SubFont current_subfont; /* for current glyph_index */
+
} CFF_Decoder;
@@ -181,10 +218,12 @@ FT_BEGIN_HEADER
#endif /* 0 */
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
FT_LOCAL( FT_Error )
cff_decoder_parse_charstrings( CFF_Decoder* decoder,
FT_Byte* charstring_base,
FT_ULong charstring_len );
+#endif
FT_LOCAL( FT_Error )
cff_slot_load( CFF_GlyphSlot glyph,
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 2be6ba0..64b4971 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -4,7 +4,7 @@
/* */
/* OpenType and CFF data/program tables loader (body). */
/* */
-/* Copyright 1996-2011 by */
+/* Copyright 1996-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -250,7 +250,7 @@
if ( offsize < 1 || offsize > 4 )
{
- error = CFF_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -269,7 +269,7 @@
if ( size == 0 )
{
- error = CFF_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -318,7 +318,7 @@
static FT_Error
cff_index_load_offsets( CFF_Index idx )
{
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Stream stream = idx->stream;
FT_Memory memory = stream->memory;
@@ -384,9 +384,10 @@
FT_Byte*** table,
FT_Byte** pool )
{
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Memory memory = idx->stream->memory;
- FT_Byte** t = NULL;
+
+ FT_Byte** t = NULL;
FT_Byte* new_bytes = NULL;
@@ -471,7 +472,7 @@
FT_Byte** pbytes,
FT_ULong* pbyte_len )
{
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( idx && idx->count > element )
@@ -556,7 +557,7 @@
}
}
else
- error = CFF_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
Exit:
return error;
@@ -696,7 +697,7 @@
break;
default: /* hmm... that's wrong */
- error = CFF_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
}
Exit:
@@ -780,7 +781,7 @@
FT_UInt num_glyphs,
FT_Memory memory )
{
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UInt i;
FT_Long j;
FT_UShort max_cid = 0;
@@ -859,7 +860,7 @@
FT_Bool invert )
{
FT_Memory memory = stream->memory;
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UShort glyph_sid;
@@ -943,7 +944,7 @@
default:
FT_ERROR(( "cff_charset_load: invalid table format\n" ));
- error = CFF_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
}
@@ -966,7 +967,7 @@
{
FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
"predefined charset (Adobe ISO-Latin)\n" ));
- error = CFF_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -984,7 +985,7 @@
{
FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
"predefined charset (Adobe Expert)\n" ));
- error = CFF_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1002,7 +1003,7 @@
{
FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
"predefined charset (Adobe Expert Subset)\n" ));
- error = CFF_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1016,7 +1017,7 @@
break;
default:
- error = CFF_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
}
@@ -1057,7 +1058,7 @@
FT_ULong base_offset,
FT_ULong offset )
{
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UInt count;
FT_UInt j;
FT_UShort glyph_sid;
@@ -1067,7 +1068,7 @@
/* Check for charset->sids. If we do not have this, we fail. */
if ( !charset->sids )
{
- error = CFF_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1187,7 +1188,7 @@
default:
FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
- error = CFF_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1280,7 +1281,7 @@
default:
FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
- error = CFF_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
}
@@ -1313,7 +1314,7 @@
/* set defaults */
FT_MEM_ZERO( top, sizeof ( *top ) );
- top->underline_position = -100L << 16;
+ top->underline_position = -( 100L << 16 );
top->underline_thickness = 50L << 16;
top->charstring_type = 2;
top->font_matrix.xx = 0x10000L;
@@ -1439,6 +1440,7 @@
FT_ULong base_offset;
CFF_FontRecDict dict;
CFF_IndexRec string_index;
+ FT_Int subfont_index;
FT_ZERO( font );
@@ -1459,7 +1461,7 @@
font->absolute_offsize > 4 )
{
FT_TRACE2(( " not a CFF font header\n" ));
- error = CFF_Err_Unknown_File_Format;
+ error = FT_THROW( Unknown_File_Format );
goto Exit;
}
@@ -1483,13 +1485,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 )
+ {
+ /* 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 = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ font->num_faces = font->name_index.count;
+ }
+ else
{
- FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
- face_index ));
- error = CFF_Err_Invalid_Argument;
+ 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 = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
}
/* in case of a font format check, simply exit now */
@@ -1500,7 +1524,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 );
@@ -1576,7 +1600,7 @@
if ( dict->charstrings_offset == 0 )
{
FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
- error = CFF_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1615,7 +1639,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 );
@@ -1660,6 +1684,12 @@
FT_FREE( font->global_subrs );
FT_FREE( font->strings );
FT_FREE( font->string_pool );
+
+ if ( font->cf2_instance.finalizer )
+ {
+ font->cf2_instance.finalizer( font->cf2_instance.data );
+ FT_FREE( font->cf2_instance.data );
+ }
}
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index 6ad0e50..dd750d1 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -4,7 +4,7 @@
/* */
/* OpenType objects manager (body). */
/* */
-/* Copyright 1996-2012 by */
+/* Copyright 1996-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,6 +17,7 @@
#include <ft2build.h>
+
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_CALC_H
#include FT_INTERNAL_STREAM_H
@@ -24,12 +25,15 @@
#include FT_TRUETYPE_IDS_H
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_SFNT_H
+#include FT_CFF_DRIVER_H
+
#include "cffobjs.h"
#include "cffload.h"
#include "cffcmap.h"
-#include "cfferrs.h"
#include "cffpic.h"
+#include "cfferrs.h"
+
/*************************************************************************/
/* */
@@ -153,7 +157,7 @@
cff_size_init( FT_Size cffsize ) /* CFF_Size */
{
CFF_Size size = (CFF_Size)cffsize;
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size );
@@ -253,7 +257,7 @@
}
}
- return CFF_Err_Ok;
+ return FT_Err_Ok;
}
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
@@ -325,7 +329,7 @@
}
}
- return CFF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -367,7 +371,7 @@
}
}
- return CFF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -401,7 +405,7 @@
remove_subset_prefix( FT_String* name )
{
FT_Int32 idx = 0;
- FT_Int32 length = strlen( name ) + 1;
+ FT_Int32 length = (FT_Int32)strlen( name ) + 1;
FT_Bool continue_search = 1;
@@ -438,8 +442,8 @@
FT_Int32 family_name_length, style_name_length;
- family_name_length = strlen( family_name );
- style_name_length = strlen( style_name );
+ family_name_length = (FT_Int32)strlen( family_name );
+ style_name_length = (FT_Int32)strlen( style_name );
if ( family_name_length > style_name_length )
{
@@ -496,7 +500,7 @@
if ( !sfnt )
{
FT_ERROR(( "cff_face_init: cannot access `sfnt' module\n" ));
- error = CFF_Err_Missing_Module;
+ error = FT_THROW( Missing_Module );
goto Exit;
}
@@ -518,21 +522,13 @@
if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */
{
FT_TRACE2(( " not an OpenType/CFF font\n" ));
- error = CFF_Err_Unknown_File_Format;
+ error = FT_THROW( Unknown_File_Format );
goto Exit;
}
/* if we are performing a simple font format check, exit immediately */
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;
- }
+ return FT_Err_Ok;
sfnt_format = 1;
@@ -544,7 +540,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;
}
@@ -554,10 +551,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 */
@@ -570,7 +563,7 @@
/* rewind to start of file; we are going to load a pure-CFF font */
if ( FT_STREAM_SEEK( 0 ) )
goto Exit;
- error = CFF_Err_Ok;
+ error = FT_Err_Ok;
}
/* now load and parse the CFF table in the file */
@@ -611,7 +604,7 @@
" cannot open CFF & CEF fonts\n"
" "
" without the `PSNames' module\n" ));
- error = CFF_Err_Missing_Module;
+ error = FT_THROW( Missing_Module );
goto Exit;
}
@@ -968,9 +961,10 @@
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 )
+ if ( error &&
+ FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) )
goto Exit;
error = FT_Err_Ok;
@@ -1000,19 +994,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 );
@@ -1056,16 +1050,25 @@
FT_LOCAL_DEF( FT_Error )
- cff_driver_init( FT_Module module )
+ cff_driver_init( FT_Module module ) /* CFF_Driver */
{
- FT_UNUSED( module );
+ CFF_Driver driver = (CFF_Driver)module;
+
+
+ /* set default property values */
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+ driver->hinting_engine = FT_CFF_HINTING_FREETYPE;
+#else
+ driver->hinting_engine = FT_CFF_HINTING_ADOBE;
+#endif
+ driver->no_stem_darkening = FALSE;
- return CFF_Err_Ok;
+ return FT_Err_Ok;
}
FT_LOCAL_DEF( void )
- cff_driver_done( FT_Module module )
+ cff_driver_done( FT_Module module ) /* CFF_Driver */
{
FT_UNUSED( module );
}
diff --git a/src/cff/cffobjs.h b/src/cff/cffobjs.h
index 3c81cee..b375c20 100644
--- a/src/cff/cffobjs.h
+++ b/src/cff/cffobjs.h
@@ -4,7 +4,7 @@
/* */
/* OpenType objects manager (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */
+/* Copyright 1996-2004, 2006-2008, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -112,12 +112,14 @@ FT_BEGIN_HEADER
/***********************************************************************/
/* */
- /* TrueType driver class. */
+ /* CFF driver class. */
/* */
typedef struct CFF_DriverRec_
{
FT_DriverRec root;
- void* extension_component;
+
+ FT_UInt hinting_engine;
+ FT_Bool no_stem_darkening;
} CFF_DriverRec;
@@ -167,10 +169,10 @@ FT_BEGIN_HEADER
/* Driver functions */
/* */
FT_LOCAL( FT_Error )
- cff_driver_init( FT_Module module );
+ cff_driver_init( FT_Module module ); /* CFF_Driver */
FT_LOCAL( void )
- cff_driver_done( FT_Module module );
+ cff_driver_done( FT_Module module ); /* CFF_Driver */
FT_END_HEADER
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index 61fa87c..9622212 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -4,7 +4,7 @@
/* */
/* CFF token stream parser (body) */
/* */
-/* Copyright 1996-2004, 2007-2011 by */
+/* Copyright 1996-2004, 2007-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -65,7 +65,7 @@
if ( p + 2 > limit )
goto Bad;
- val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
+ val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
p += 2;
}
else if ( v == 29 )
@@ -73,10 +73,10 @@
if ( p + 4 > limit )
goto Bad;
- val = ( (FT_Long)p[0] << 24 ) |
- ( (FT_Long)p[1] << 16 ) |
- ( (FT_Long)p[2] << 8 ) |
- p[3];
+ val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
+ ( (FT_ULong)p[1] << 16 ) |
+ ( (FT_ULong)p[2] << 8 ) |
+ (FT_ULong)p[3] );
p += 4;
}
else if ( v < 247 )
@@ -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,20 +298,25 @@
/* 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;
- result = number << 16;
+ result = (FT_Long)( (FT_ULong)number << 16 );
*scaling = exponent;
}
}
@@ -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;
+ result = (FT_Long)( (FT_ULong)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 (FT_Long)( (FT_ULong)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 );
}
@@ -436,7 +501,7 @@
else
{
*scaling = 0;
- return number << 16;
+ return (FT_Long)( (FT_ULong)number << 16 );
}
}
}
@@ -450,7 +515,7 @@
FT_Vector* offset = &dict->font_offset;
FT_ULong* upm = &dict->units_per_em;
FT_Byte** data = parser->stack;
- FT_Error error = CFF_Err_Stack_Underflow;
+ FT_Error error = FT_ERR( Stack_Underflow );
if ( parser->top >= parser->stack + 6 )
@@ -458,7 +523,7 @@
FT_Long scaling;
- error = CFF_Err_Ok;
+ error = FT_Err_Ok;
dict->has_font_matrix = TRUE;
@@ -523,7 +588,7 @@
FT_Error error;
- error = CFF_Err_Stack_Underflow;
+ error = FT_ERR( Stack_Underflow );
if ( parser->top >= parser->stack + 4 )
{
@@ -531,7 +596,7 @@
bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) );
- error = CFF_Err_Ok;
+ error = FT_Err_Ok;
FT_TRACE4(( " [%d %d %d %d]\n",
bbox->xMin / 65536,
@@ -552,7 +617,7 @@
FT_Error error;
- error = CFF_Err_Stack_Underflow;
+ error = FT_ERR( Stack_Underflow );
if ( parser->top >= parser->stack + 2 )
{
@@ -561,7 +626,7 @@
FT_TRACE4(( " %lu %lu\n",
dict->private_size, dict->private_offset ));
- error = CFF_Err_Ok;
+ error = FT_Err_Ok;
}
return error;
@@ -576,7 +641,7 @@
FT_Error error;
- error = CFF_Err_Stack_Underflow;
+ error = FT_ERR( Stack_Underflow );
if ( parser->top >= parser->stack + 3 )
{
@@ -588,7 +653,7 @@
if ( dict->cid_supplement < 0 )
FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
dict->cid_supplement ));
- error = CFF_Err_Ok;
+ error = FT_Err_Ok;
FT_TRACE4(( " %d %d %d\n",
dict->cid_registry,
@@ -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;
@@ -857,7 +922,7 @@
*output_class = clazz;
- return CFF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -870,7 +935,7 @@
FT_Byte* limit )
{
FT_Byte* p = start;
- FT_Error error = CFF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Library library = parser->library;
FT_UNUSED( library );
@@ -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 )
{
@@ -1096,15 +1161,15 @@
return error;
Stack_Overflow:
- error = CFF_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
Stack_Underflow:
- error = CFF_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
Syntax_Error:
- error = CFF_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
diff --git a/src/cff/cffpic.c b/src/cff/cffpic.c
index 1c19d58..f22e4f0 100644
--- a/src/cff/cffpic.c
+++ b/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, 2013 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -23,65 +23,51 @@
#include "cffpic.h"
#include "cfferrs.h"
+
#ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from cffdrivr.c */
FT_Error
- FT_Create_Class_cff_services(
- FT_Library library,
- FT_ServiceDescRec** output_class );
-
+ FT_Create_Class_cff_services( FT_Library library,
+ FT_ServiceDescRec** output_class );
void
- FT_Destroy_Class_cff_services(
- FT_Library library,
- FT_ServiceDescRec* clazz );
-
+ FT_Destroy_Class_cff_services( FT_Library library,
+ FT_ServiceDescRec* clazz );
void
- FT_Init_Class_cff_service_ps_info(
- FT_Library library,
- FT_Service_PsInfoRec* clazz );
-
+ FT_Init_Class_cff_service_ps_info( FT_Library library,
+ FT_Service_PsInfoRec* clazz );
void
- FT_Init_Class_cff_service_glyph_dict(
- FT_Library library,
- FT_Service_GlyphDictRec* clazz );
-
+ FT_Init_Class_cff_service_glyph_dict( FT_Library library,
+ FT_Service_GlyphDictRec* clazz );
void
- FT_Init_Class_cff_service_ps_name(
- FT_Library library,
- FT_Service_PsFontNameRec* clazz );
-
+ FT_Init_Class_cff_service_ps_name( FT_Library library,
+ FT_Service_PsFontNameRec* clazz );
void
- FT_Init_Class_cff_service_get_cmap_info(
- FT_Library library,
- FT_Service_TTCMapsRec* clazz );
-
+ FT_Init_Class_cff_service_get_cmap_info( FT_Library library,
+ FT_Service_TTCMapsRec* clazz );
void
- FT_Init_Class_cff_service_cid_info(
- FT_Library library,
- FT_Service_CIDRec* clazz );
+ FT_Init_Class_cff_service_cid_info( FT_Library library,
+ FT_Service_CIDRec* clazz );
/* forward declaration of PIC init functions from cffparse.c */
FT_Error
- FT_Create_Class_cff_field_handlers(
- FT_Library library,
- CFF_Field_Handler** output_class );
-
+ FT_Create_Class_cff_field_handlers( FT_Library library,
+ CFF_Field_Handler** output_class );
void
- FT_Destroy_Class_cff_field_handlers(
- FT_Library library,
- CFF_Field_Handler* clazz );
+ FT_Destroy_Class_cff_field_handlers( FT_Library library,
+ CFF_Field_Handler* clazz );
+
void
cff_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->cff )
{
- CffModulePIC* container = ( CffModulePIC* )pic_container->cff;
+ CffModulePIC* container = (CffModulePIC*)pic_container->cff;
if ( container->cff_services )
@@ -102,8 +88,8 @@
cff_driver_class_pic_init( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Error error = CFF_Err_Ok;
- CffModulePIC* container;
+ FT_Error error = FT_Err_Ok;
+ CffModulePIC* container = NULL;
FT_Memory memory = library->memory;
@@ -113,15 +99,18 @@
FT_MEM_SET( container, 0, sizeof ( *container ) );
pic_container->cff = 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_cff_services( library,
&container->cff_services );
if ( error )
goto Exit;
+
error = FT_Create_Class_cff_field_handlers(
library, &container->cff_field_handlers );
if ( error )
goto Exit;
+
FT_Init_Class_cff_service_ps_info(
library, &container->cff_service_ps_info );
FT_Init_Class_cff_service_glyph_dict(
@@ -136,7 +125,8 @@
library, &container->cff_cmap_encoding_class_rec );
FT_Init_Class_cff_cmap_unicode_class_rec(
library, &container->cff_cmap_unicode_class_rec );
-Exit:
+
+ Exit:
if ( error )
cff_driver_class_pic_free( library );
return error;
diff --git a/src/cff/cffpic.h b/src/cff/cffpic.h
index 342edd8..50bab4c 100644
--- a/src/cff/cffpic.h
+++ b/src/cff/cffpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for cff module. */
/* */
-/* Copyright 2009 by */
+/* Copyright 2009, 2012, 2013 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -24,16 +24,19 @@ FT_BEGIN_HEADER
#include FT_INTERNAL_PIC_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_SERVICE_PROPERTIES_GET cff_service_properties
+#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 */
@@ -43,30 +46,48 @@ FT_BEGIN_HEADER
#include FT_SERVICE_POSTSCRIPT_NAME_H
#include FT_SERVICE_TT_CMAP_H
#include FT_SERVICE_CID_H
+#include FT_SERVICE_PROPERTIES_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_Service_PropertiesRec cff_service_properties;
+ 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_SERVICE_PROPERTIES_GET \
+ ( GET_PIC( library )->cff_service_properties )
+#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/src/cff/cfftypes.h b/src/cff/cfftypes.h
index 7c99036..8727446 100644
--- a/src/cff/cfftypes.h
+++ b/src/cff/cfftypes.h
@@ -5,7 +5,7 @@
/* Basic OpenType/CFF type definitions and interface (specification */
/* only). */
/* */
-/* Copyright 1996-2003, 2006-2008, 2010-2011 by */
+/* Copyright 1996-2003, 2006-2008, 2010-2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -270,6 +270,9 @@ FT_BEGIN_HEADER
FT_String* registry;
FT_String* ordering;
+ /* since version 2.4.12 */
+ FT_Generic cf2_instance;
+
} CFF_FontRec, *CFF_Font;
diff --git a/src/pfr/pfrload.c b/src/pfr/pfrload.c
index 325322e..c19fceb 100644
--- a/src/pfr/pfrload.c
+++ b/src/pfr/pfrload.c
@@ -4,7 +4,7 @@
/* */
/* FreeType PFR loader (body). */
/* */
-/* Copyright 2002, 2003, 2004, 2005, 2007, 2009, 2010 by */
+/* Copyright 2002-2005, 2007, 2009, 2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -49,7 +49,7 @@
PFR_ExtraItem item_list,
FT_Pointer item_data )
{
- FT_Error error = PFR_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Byte* p = *pp;
FT_UInt num_items, item_type, item_size;
@@ -91,7 +91,7 @@
Too_Short:
FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" ));
- error = PFR_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -236,7 +236,7 @@
goto Exit;
if ( idx >= num_log_fonts )
- return PFR_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( FT_STREAM_SKIP( idx * 5 ) ||
FT_READ_USHORT( size ) ||
@@ -329,7 +329,7 @@
Too_Short:
FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" ));
- error = PFR_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Fail;
}
@@ -353,7 +353,7 @@
PFR_Strike strike;
FT_UInt flags0;
FT_UInt n, count, size1;
- FT_Error error = PFR_Err_Ok;
+ FT_Error error = FT_Err_Ok;
PFR_CHECK( 5 );
@@ -427,7 +427,7 @@
return error;
Too_Short:
- error = PFR_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
FT_ERROR(( "pfr_extra_item_load_bitmap_info:"
" invalid bitmap info table\n" ));
goto Exit;
@@ -449,7 +449,7 @@
FT_Byte* limit,
PFR_PhyFont phy_font )
{
- FT_Error error = PFR_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Memory memory = phy_font->memory;
FT_PtrDist len = limit - p;
@@ -477,7 +477,7 @@
{
FT_UInt count, num_vert, num_horz;
FT_Int* snaps = NULL;
- FT_Error error = PFR_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Memory memory = phy_font->memory;
@@ -506,7 +506,7 @@
return error;
Too_Short:
- error = PFR_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
FT_ERROR(( "pfr_exta_item_load_stem_snaps:"
" invalid stem snaps table\n" ));
goto Exit;
@@ -521,7 +521,7 @@
PFR_PhyFont phy_font )
{
PFR_KernItem item = NULL;
- FT_Error error = PFR_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Memory memory = phy_font->memory;
@@ -604,7 +604,7 @@
Too_Short:
FT_FREE( item );
- error = PFR_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
FT_ERROR(( "pfr_extra_item_load_kerning_pairs:"
" invalid kerning pairs table\n" ));
goto Exit;
@@ -631,7 +631,7 @@
FT_Memory memory,
FT_String* *astring )
{
- FT_Error error = PFR_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_String* result = NULL;
FT_UInt n, ok;
@@ -932,7 +932,7 @@
return error;
Too_Short:
- error = PFR_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" ));
goto Fail;
}
diff --git a/src/psaux/afmparse.c b/src/psaux/afmparse.c
index 5f3f9e6..6a40e11 100644
--- a/src/psaux/afmparse.c
+++ b/src/psaux/afmparse.c
@@ -4,7 +4,7 @@
/* */
/* AFM parser (body). */
/* */
-/* Copyright 2006-2010, 2012 by */
+/* Copyright 2006-2010, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,6 +17,7 @@
#include <ft2build.h>
#include FT_FREETYPE_H
+#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_POSTSCRIPT_AUX_H
#include "afmparse.h"
@@ -119,7 +120,6 @@
afm_stream_read_one( AFM_Stream stream )
{
char* str;
- int ch;
afm_stream_skip_spaces( stream );
@@ -130,7 +130,9 @@
while ( 1 )
{
- ch = AFM_GETC();
+ int ch = AFM_GETC();
+
+
if ( AFM_IS_SPACE( ch ) )
break;
else if ( AFM_IS_NEWLINE( ch ) )
@@ -159,7 +161,6 @@
afm_stream_read_string( AFM_Stream stream )
{
char* str;
- int ch;
afm_stream_skip_spaces( stream );
@@ -171,7 +172,9 @@
/* scan to eol */
while ( 1 )
{
- ch = AFM_GETC();
+ int ch = AFM_GETC();
+
+
if ( AFM_IS_NEWLINE( ch ) )
{
stream->status = AFM_STREAM_STATUS_EOL;
@@ -545,7 +548,7 @@
parser->FontInfo = NULL;
parser->get_index = NULL;
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
}
@@ -572,10 +575,10 @@
{
*aint = val.u.i;
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
}
else
- return PSaux_Err_Syntax_Error;
+ return FT_THROW( Syntax_Error );
}
@@ -637,7 +640,7 @@
case AFM_TOKEN_ENDKERNDATA:
case AFM_TOKEN_ENDFONTMETRICS:
fi->NumTrackKern = n + 1;
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
case AFM_TOKEN_UNKNOWN:
break;
@@ -648,7 +651,7 @@
}
Fail:
- return PSaux_Err_Syntax_Error;
+ return FT_THROW( Syntax_Error );
}
@@ -753,7 +756,7 @@
ft_qsort( fi->KernPairs, fi->NumKernPair,
sizeof ( AFM_KernPairRec ),
afm_compare_kern_pairs );
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
case AFM_TOKEN_UNKNOWN:
break;
@@ -764,7 +767,7 @@
}
Fail:
- return PSaux_Err_Syntax_Error;
+ return FT_THROW( Syntax_Error );
}
@@ -795,7 +798,7 @@
case AFM_TOKEN_ENDKERNDATA:
case AFM_TOKEN_ENDFONTMETRICS:
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
case AFM_TOKEN_UNKNOWN:
break;
@@ -806,7 +809,7 @@
}
Fail:
- return PSaux_Err_Syntax_Error;
+ return FT_THROW( Syntax_Error );
}
@@ -832,11 +835,11 @@
if ( token == end_section || token == AFM_TOKEN_ENDFONTMETRICS )
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
}
Fail:
- return PSaux_Err_Syntax_Error;
+ return FT_THROW( Syntax_Error );
}
@@ -845,19 +848,19 @@
{
FT_Memory memory = parser->memory;
AFM_FontInfo fi = parser->FontInfo;
- FT_Error error = PSaux_Err_Syntax_Error;
+ FT_Error error = FT_ERR( Syntax_Error );
char* key;
FT_Offset len;
FT_Int metrics_sets = 0;
if ( !fi )
- return PSaux_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
key = afm_parser_next_key( parser, 1, &len );
if ( !key || len != 16 ||
ft_strncmp( key, "StartFontMetrics", 16 ) != 0 )
- return PSaux_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
{
@@ -872,7 +875,7 @@
if ( metrics_sets != 0 && metrics_sets != 2 )
{
- error = PSaux_Err_Unimplemented_Feature;
+ error = FT_THROW( Unimplemented_Feature );
goto Fail;
}
@@ -938,7 +941,7 @@
/* fall through since we only support kern data */
case AFM_TOKEN_ENDFONTMETRICS:
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
default:
break;
diff --git a/src/psaux/psconv.c b/src/psaux/psconv.c
index 9ea7fb9..d0d8861 100644
--- a/src/psaux/psconv.c
+++ b/src/psaux/psconv.c
@@ -4,7 +4,7 @@
/* */
/* Some convenience conversions (body). */
/* */
-/* Copyright 2006, 2008, 2009, 2012 by */
+/* Copyright 2006, 2008, 2009, 2012-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -18,11 +18,22 @@
#include <ft2build.h>
#include FT_INTERNAL_POSTSCRIPT_AUX_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 = (FT_Fixed)( (FT_UInt32)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/src/psaux/psconv.h b/src/psaux/psconv.h
index 84854ba..d91c762 100644
--- a/src/psaux/psconv.h
+++ b/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/src/psaux/psobjs.c b/src/psaux/psobjs.c
index 06df6e6..dd976d3 100644
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -4,7 +4,7 @@
/* */
/* Auxiliary functions for PostScript fonts (body). */
/* */
-/* Copyright 1996-2012 by */
+/* Copyright 1996-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -113,8 +113,8 @@
static FT_Error
- reallocate_t1_table( PS_Table table,
- FT_Long new_size )
+ reallocate_t1_table( PS_Table table,
+ FT_Offset new_size )
{
FT_Memory memory = table->memory;
FT_Byte* old_base = table->block;
@@ -138,7 +138,7 @@
table->capacity = new_size;
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
}
@@ -173,13 +173,13 @@
if ( idx < 0 || idx >= table->max_elems )
{
FT_ERROR(( "ps_table_add: invalid index\n" ));
- return PSaux_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
if ( length < 0 )
{
FT_ERROR(( "ps_table_add: invalid length\n" ));
- return PSaux_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
/* grow the base block if needed */
@@ -216,7 +216,7 @@
FT_MEM_COPY( table->block + table->cursor, object, length );
table->cursor += length;
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
}
@@ -341,7 +341,7 @@
{
FT_Byte* cur = *acur;
FT_Int embed = 0;
- FT_Error error = PSaux_Err_Invalid_File_Format;
+ FT_Error error = FT_ERR( Invalid_File_Format );
unsigned int i;
@@ -397,7 +397,7 @@
embed--;
if ( embed == 0 )
{
- error = PSaux_Err_Ok;
+ error = FT_Err_Ok;
break;
}
}
@@ -416,7 +416,7 @@
FT_Byte* limit )
{
FT_Byte* cur = *acur;
- FT_Error err = PSaux_Err_Ok;
+ FT_Error err = FT_Err_Ok;
while ( ++cur < limit )
@@ -433,7 +433,7 @@
if ( cur < limit && *cur != '>' )
{
FT_ERROR(( "skip_string: missing closing delimiter `>'\n" ));
- err = PSaux_Err_Invalid_File_Format;
+ err = FT_THROW( Invalid_File_Format );
}
else
cur++;
@@ -456,12 +456,12 @@
{
FT_Byte* cur;
FT_Int embed = 0;
- FT_Error error = PSaux_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_ASSERT( **acur == '{' );
- for ( cur = *acur; cur < limit && error == PSaux_Err_Ok; ++cur )
+ for ( cur = *acur; cur < limit && error == FT_Err_Ok; ++cur )
{
switch ( *cur )
{
@@ -494,7 +494,7 @@
end:
if ( embed != 0 )
- error = PSaux_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
*acur = cur;
@@ -519,7 +519,7 @@
FT_Byte* cur = parser->cursor;
FT_Byte* limit = parser->limit;
- FT_Error error = PSaux_Err_Ok;
+ FT_Error error = FT_Err_Ok;
skip_spaces( &cur, limit ); /* this also skips comments */
@@ -567,7 +567,7 @@
{
FT_ERROR(( "ps_parser_skip_PS_token:"
" unexpected closing delimiter `>'\n" ));
- error = PSaux_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
cur++;
@@ -597,7 +597,7 @@
" but invalid at this point\n",
*cur ));
- error = PSaux_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
}
parser->error = error;
@@ -644,7 +644,7 @@
token->type = T1_TOKEN_TYPE_STRING;
token->start = cur;
- if ( skip_literal_string( &cur, limit ) == PSaux_Err_Ok )
+ if ( skip_literal_string( &cur, limit ) == FT_Err_Ok )
token->limit = cur;
break;
@@ -653,7 +653,7 @@
token->type = T1_TOKEN_TYPE_ARRAY;
token->start = cur;
- if ( skip_procedure( &cur, limit ) == PSaux_Err_Ok )
+ if ( skip_procedure( &cur, limit ) == FT_Err_Ok )
token->limit = cur;
break;
@@ -1027,12 +1027,13 @@
FT_UInt max_objects,
FT_ULong* pflags )
{
- T1_TokenRec token;
- FT_Byte* cur;
- FT_Byte* limit;
- FT_UInt count;
- FT_UInt idx;
- FT_Error error;
+ T1_TokenRec token;
+ FT_Byte* cur;
+ FT_Byte* limit;
+ FT_UInt count;
+ FT_UInt idx;
+ FT_Error error;
+ T1_FieldType type;
/* this also skips leading whitespace */
@@ -1045,8 +1046,10 @@
cur = token.start;
limit = token.limit;
+ type = field->type;
+
/* we must detect arrays in /FontBBox */
- if ( field->type == T1_FIELD_TYPE_BBOX )
+ if ( type == T1_FIELD_TYPE_BBOX )
{
T1_TokenRec token2;
FT_Byte* old_cur = parser->cursor;
@@ -1062,17 +1065,21 @@
parser->limit = old_limit;
if ( token2.type == T1_TOKEN_TYPE_ARRAY )
+ {
+ type = T1_FIELD_TYPE_MM_BBOX;
goto FieldArray;
+ }
}
else if ( token.type == T1_TOKEN_TYPE_ARRAY )
{
+ count = max_objects;
+
FieldArray:
/* if this is an array and we have no blend, an error occurs */
if ( max_objects == 0 )
goto Fail;
- count = max_objects;
- idx = 1;
+ idx = 1;
/* don't include delimiters */
cur++;
@@ -1088,7 +1095,7 @@
skip_spaces( &cur, limit );
- switch ( field->type )
+ switch ( type )
{
case T1_FIELD_TYPE_BOOL:
val = ps_tobool( &cur, limit );
@@ -1160,7 +1167,7 @@
" "
" but found token of type %d instead\n",
token.type ));
- error = PSaux_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1197,7 +1204,7 @@
{
FT_ERROR(( "ps_parser_load_field:"
" expected four integers in bounding box\n" ));
- error = PSaux_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1208,6 +1215,54 @@
}
break;
+ case T1_FIELD_TYPE_MM_BBOX:
+ {
+ FT_Memory memory = parser->memory;
+ FT_Fixed* temp;
+ FT_Int result;
+ FT_UInt i;
+
+
+ if ( FT_NEW_ARRAY( temp, max_objects * 4 ) )
+ goto Exit;
+
+ for ( i = 0; i < 4; i++ )
+ {
+ result = ps_tofixedarray( &cur, limit, max_objects,
+ temp + i * max_objects, 0 );
+ if ( result < 0 )
+ {
+ FT_ERROR(( "ps_parser_load_field:"
+ " expected %d integers in the %s subarray\n"
+ " "
+ " of /FontBBox in the /Blend dictionary\n",
+ max_objects,
+ i == 0 ? "first"
+ : ( i == 1 ? "second"
+ : ( i == 2 ? "third"
+ : "fourth" ) ) ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+
+ skip_spaces( &cur, limit );
+ }
+
+ for ( i = 0; i < max_objects; i++ )
+ {
+ FT_BBox* bbox = (FT_BBox*)objects[i];
+
+
+ bbox->xMin = FT_RoundFix( temp[i ] );
+ bbox->yMin = FT_RoundFix( temp[i + max_objects] );
+ bbox->xMax = FT_RoundFix( temp[i + 2 * max_objects] );
+ bbox->yMax = FT_RoundFix( temp[i + 3 * max_objects] );
+ }
+
+ FT_FREE( temp );
+ }
+ break;
+
default:
/* an error occurred */
goto Fail;
@@ -1221,13 +1276,13 @@
FT_UNUSED( pflags );
#endif
- error = PSaux_Err_Ok;
+ error = FT_Err_Ok;
Exit:
return error;
Fail:
- error = PSaux_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1245,7 +1300,7 @@
T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS];
T1_Token token;
FT_Int num_elements;
- FT_Error error = PSaux_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Byte* old_cursor;
FT_Byte* old_limit;
T1_FieldRec fieldrec = *(T1_Field)field;
@@ -1260,7 +1315,7 @@
T1_MAX_TABLE_ELEMENTS, &num_elements );
if ( num_elements < 0 )
{
- error = PSaux_Err_Ignore;
+ error = FT_ERR( Ignore );
goto Exit;
}
if ( (FT_UInt)num_elements > field->array_max )
@@ -1317,7 +1372,7 @@
FT_Long* pnum_bytes,
FT_Bool delimiters )
{
- FT_Error error = PSaux_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Byte* cur;
@@ -1332,7 +1387,7 @@
if ( *cur != '<' )
{
FT_ERROR(( "ps_parser_to_bytes: Missing starting delimiter `<'\n" ));
- error = PSaux_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1349,7 +1404,7 @@
if ( cur < parser->limit && *cur != '>' )
{
FT_ERROR(( "ps_parser_to_bytes: Missing closing delimiter `>'\n" ));
- error = PSaux_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1419,7 +1474,7 @@
FT_Byte* limit,
FT_Memory memory )
{
- parser->error = PSaux_Err_Ok;
+ parser->error = FT_Err_Ok;
parser->base = base;
parser->limit = limit;
parser->cursor = base;
@@ -1592,13 +1647,13 @@
if ( !outline )
{
FT_ERROR(( "t1_builder_add_contour: no outline to add points to\n" ));
- return PSaux_Err_Invalid_File_Format;
+ return FT_THROW( Invalid_File_Format );
}
if ( !builder->load_points )
{
outline->n_contours++;
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
}
error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
@@ -1621,13 +1676,13 @@
FT_Pos x,
FT_Pos y )
{
- FT_Error error = PSaux_Err_Invalid_File_Format;
+ FT_Error error = FT_ERR( Invalid_File_Format );
/* test whether we are building a new contour */
if ( builder->parse_state == T1_Parse_Have_Path )
- error = PSaux_Err_Ok;
+ error = FT_Err_Ok;
else
{
builder->parse_state = T1_Parse_Have_Path;
diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
index ea67841..6ce370b 100644
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -4,7 +4,7 @@
/* */
/* PostScript Type 1 decoding routines (body). */
/* */
-/* Copyright 2000-2011 by */
+/* Copyright 2000-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -205,7 +205,13 @@
if ( decoder->seac )
{
FT_ERROR(( "t1operator_seac: invalid nested seac\n" ));
- return PSaux_Err_Syntax_Error;
+ return FT_THROW( Syntax_Error );
+ }
+
+ if ( decoder->builder.metrics_only )
+ {
+ FT_ERROR(( "t1operator_seac: unexpected seac\n" ));
+ return FT_THROW( Syntax_Error );
}
/* seac weirdness */
@@ -222,7 +228,7 @@
{
FT_ERROR(( "t1operator_seac:"
" glyph names table not available in this font\n" ));
- return PSaux_Err_Syntax_Error;
+ return FT_THROW( Syntax_Error );
}
#ifdef FT_CONFIG_OPTION_INCREMENTAL
@@ -243,7 +249,7 @@
{
FT_ERROR(( "t1operator_seac:"
" invalid seac character code arguments\n" ));
- return PSaux_Err_Syntax_Error;
+ return FT_THROW( Syntax_Error );
}
/* if we are trying to load a composite glyph, do not load the */
@@ -409,7 +415,7 @@
limit = zone->limit = charstring_base + charstring_len;
ip = zone->cursor = zone->base;
- error = PSaux_Err_Ok;
+ error = FT_Err_Ok;
x = orig_x = builder->pos_x;
y = orig_y = builder->pos_y;
@@ -559,10 +565,10 @@
goto Syntax_Error;
}
- value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) |
- ( (FT_Long)ip[1] << 16 ) |
- ( (FT_Long)ip[2] << 8 ) |
- ip[3] );
+ value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
+ ( (FT_UInt32)ip[1] << 16 ) |
+ ( (FT_UInt32)ip[2] << 8 ) |
+ (FT_UInt32)ip[3] );
ip += 4;
/* According to the specification, values > 32000 or < -32000 must */
@@ -585,7 +591,7 @@
else
{
if ( !large_int )
- value <<= 16;
+ value = (FT_Int32)( (FT_UInt32)value << 16 );
}
break;
@@ -605,13 +611,13 @@
}
if ( ip[-2] < 251 )
- value = ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108;
+ value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
else
- value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
+ value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
}
if ( !large_int )
- value <<= 16;
+ value = (FT_Int32)( (FT_UInt32)value << 16 );
}
else
{
@@ -750,9 +756,9 @@
decoder->flex_state = 1;
decoder->num_flex_vectors = 0;
if ( ( error = t1_builder_start_point( builder, x, y ) )
- != PSaux_Err_Ok ||
+ != FT_Err_Ok ||
( error = t1_builder_check_points( builder, 6 ) )
- != PSaux_Err_Ok )
+ != FT_Err_Ok )
goto Fail;
break;
@@ -1123,7 +1129,7 @@
FT_TRACE4(( "\n" ));
/* return now! */
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
case op_hsbw:
FT_TRACE4(( " hsbw" ));
@@ -1143,7 +1149,7 @@
/* the glyph's metrics (lsb + advance width), not load the */
/* rest of it; so exit immediately */
if ( builder->metrics_only )
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
break;
@@ -1172,7 +1178,7 @@
/* the glyph's metrics (lsb + advance width), not load the */
/* rest of it; so exit immediately */
if ( builder->metrics_only )
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
break;
@@ -1191,7 +1197,7 @@
FT_TRACE4(( " hlineto" ));
if ( ( error = t1_builder_start_point( builder, x, y ) )
- != PSaux_Err_Ok )
+ != FT_Err_Ok )
goto Fail;
x += top[0];
@@ -1213,9 +1219,9 @@
FT_TRACE4(( " hvcurveto" ));
if ( ( error = t1_builder_start_point( builder, x, y ) )
- != PSaux_Err_Ok ||
+ != FT_Err_Ok ||
( error = t1_builder_check_points( builder, 3 ) )
- != PSaux_Err_Ok )
+ != FT_Err_Ok )
goto Fail;
x += top[0];
@@ -1231,7 +1237,7 @@
FT_TRACE4(( " rlineto" ));
if ( ( error = t1_builder_start_point( builder, x, y ) )
- != PSaux_Err_Ok )
+ != FT_Err_Ok )
goto Fail;
x += top[0];
@@ -1239,7 +1245,7 @@
Add_Line:
if ( ( error = t1_builder_add_point1( builder, x, y ) )
- != PSaux_Err_Ok )
+ != FT_Err_Ok )
goto Fail;
break;
@@ -1260,9 +1266,9 @@
FT_TRACE4(( " rrcurveto" ));
if ( ( error = t1_builder_start_point( builder, x, y ) )
- != PSaux_Err_Ok ||
+ != FT_Err_Ok ||
( error = t1_builder_check_points( builder, 3 ) )
- != PSaux_Err_Ok )
+ != FT_Err_Ok )
goto Fail;
x += top[0];
@@ -1282,9 +1288,9 @@
FT_TRACE4(( " vhcurveto" ));
if ( ( error = t1_builder_start_point( builder, x, y ) )
- != PSaux_Err_Ok ||
+ != FT_Err_Ok ||
( error = t1_builder_check_points( builder, 3 ) )
- != PSaux_Err_Ok )
+ != FT_Err_Ok )
goto Fail;
y += top[0];
@@ -1300,7 +1306,7 @@
FT_TRACE4(( " vlineto" ));
if ( ( error = t1_builder_start_point( builder, x, y ) )
- != PSaux_Err_Ok )
+ != FT_Err_Ok )
goto Fail;
y += top[0];
@@ -1539,10 +1545,10 @@
return error;
Syntax_Error:
- return PSaux_Err_Syntax_Error;
+ return FT_THROW( Syntax_Error );
Stack_Underflow:
- return PSaux_Err_Stack_Underflow;
+ return FT_THROW( Stack_Underflow );
}
@@ -1579,7 +1585,7 @@
{
FT_ERROR(( "t1_decoder_init:"
" the `psnames' module is not available\n" ));
- return PSaux_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
}
decoder->psnames = psnames;
@@ -1599,7 +1605,7 @@
decoder->funcs = t1_decoder_funcs;
- return PSaux_Err_Ok;
+ return FT_Err_Ok;
}
diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c
index d798978..343472d 100644
--- a/src/pshinter/pshalgo.c
+++ b/src/pshinter/pshalgo.c
@@ -4,8 +4,7 @@
/* */
/* PostScript hinting algorithm (body). */
/* */
-/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 */
-/* by */
+/* Copyright 2001-2010, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used */
@@ -402,13 +401,13 @@
FT_Fixed delta,
FT_Int dimension )
{
- PSH_Hint hint;
- FT_UInt count;
+ FT_UInt count;
for ( count = 0; count < table->max_hints; count++ )
{
- hint = table->hints + count;
+ PSH_Hint hint = table->hints + count;
+
hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta;
hint->cur_len = FT_MulFix( hint->org_len, scale );
@@ -563,7 +562,7 @@
else if ( len > 0 )
{
/* This is a very small stem; we simply align it to the
- * pixel grid, trying to find the minimal displacement.
+ * pixel grid, trying to find the minimum displacement.
*
* left = pos
* right = pos + len
@@ -1162,8 +1161,8 @@
int result = PSH_DIR_NONE;
- ax = ( dx >= 0 ) ? dx : -dx;
- ay = ( dy >= 0 ) ? dy : -dy;
+ ax = FT_ABS( dx );
+ ay = FT_ABS( dy );
if ( ay * 12 < ax )
{
@@ -2194,7 +2193,7 @@
/* something to do? */
if ( outline->n_points == 0 || outline->n_contours == 0 )
- return PSH_Err_Ok;
+ return FT_Err_Ok;
#ifdef DEBUG_HINTER
diff --git a/src/pshinter/pshalgo.h b/src/pshinter/pshalgo.h
index 1a248a7..c70f31e 100644
--- a/src/pshinter/pshalgo.h
+++ b/src/pshinter/pshalgo.h
@@ -4,7 +4,7 @@
/* */
/* PostScript hinting algorithm (specification). */
/* */
-/* Copyright 2001, 2002, 2003, 2008 by */
+/* Copyright 2001-2003, 2008, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -22,7 +22,6 @@
#include "pshrec.h"
#include "pshglob.h"
-#include FT_TRIGONOMETRY_H
FT_BEGIN_HEADER
@@ -168,8 +167,6 @@ FT_BEGIN_HEADER
FT_UInt flags2;
FT_Char dir_in;
FT_Char dir_out;
- FT_Angle angle_in;
- FT_Angle angle_out;
PSH_Hint hint;
FT_Pos org_u;
FT_Pos org_v;
@@ -186,12 +183,6 @@ FT_BEGIN_HEADER
} PSH_PointRec;
-#define PSH_POINT_EQUAL_ORG( a, b ) ( (a)->org_u == (b)->org_u && \
- (a)->org_v == (b)->org_v )
-
-#define PSH_POINT_ANGLE( a, b ) FT_Atan2( (b)->org_u - (a)->org_u, \
- (b)->org_v - (a)->org_v )
-
typedef struct PSH_ContourRec_
{
PSH_Point start;
diff --git a/src/pshinter/pshglob.c b/src/pshinter/pshglob.c
index 31231ad..9285efc 100644
--- a/src/pshinter/pshglob.c
+++ b/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/src/pshinter/pshmod.c b/src/pshinter/pshmod.c
index 91da5d7..cdeaca1 100644
--- a/src/pshinter/pshmod.c
+++ b/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/src/pshinter/pshpic.c b/src/pshinter/pshpic.c
index 1e0f9a9..568f4ac 100644
--- a/src/pshinter/pshpic.c
+++ b/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, 2013 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 )
@@ -48,13 +49,13 @@
pshinter_module_class_pic_init( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Error error = PSH_Err_Ok;
- PSHinterPIC* container;
+ FT_Error error = FT_Err_Ok;
+ PSHinterPIC* container = NULL;
FT_Memory memory = library->memory;
/* allocate pointer, clear and set global container pointer */
- if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+ if ( FT_ALLOC( container, sizeof ( *container ) ) )
return error;
FT_MEM_SET( container, 0, sizeof ( *container ) );
pic_container->pshinter = container;
@@ -63,13 +64,13 @@
FT_Init_Class_pshinter_interface(
library, &container->pshinter_interface );
-/*Exit:*/
- if( error )
+ if ( error )
pshinter_module_class_pic_free( library );
+
return error;
}
-
#endif /* FT_CONFIG_OPTION_PIC */
+
/* END */
diff --git a/src/pshinter/pshpic.h b/src/pshinter/pshpic.h
index c10bdd9..b46f853 100644
--- a/src/pshinter/pshpic.h
+++ b/src/pshinter/pshpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for pshinter module. */
/* */
-/* Copyright 2009 by */
+/* Copyright 2009, 2012, 2013 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 FT_INTERNAL_PIC_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.pshinter ) )
+
+#define PSHINTER_INTERFACE_GET ( GET_PIC( library )->pshinter_interface )
/* see pshpic.c for the implementation */
void
diff --git a/src/pshinter/pshrec.c b/src/pshinter/pshrec.c
index 0910cc5..cd66ea8 100644
--- a/src/pshinter/pshrec.c
+++ b/src/pshinter/pshrec.c
@@ -4,7 +4,7 @@
/* */
/* FreeType PostScript hints recorder (body). */
/* */
-/* Copyright 2001, 2002, 2003, 2004, 2007, 2009 by */
+/* Copyright 2001-2004, 2007, 2009, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -64,7 +64,7 @@
{
FT_UInt old_max = table->max_hints;
FT_UInt new_max = count;
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( new_max > old_max )
@@ -83,7 +83,7 @@
FT_Memory memory,
PS_Hint *ahint )
{
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UInt count;
PS_Hint hint = 0;
@@ -139,7 +139,7 @@
{
FT_UInt old_max = ( mask->max_bits + 7 ) >> 3;
FT_UInt new_max = ( count + 7 ) >> 3;
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( new_max > old_max )
@@ -186,7 +186,7 @@
FT_Int idx,
FT_Memory memory )
{
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Byte* p;
@@ -236,7 +236,7 @@
{
FT_UInt old_max = table->max_masks;
FT_UInt new_max = count;
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( new_max > old_max )
@@ -256,7 +256,7 @@
PS_Mask *amask )
{
FT_UInt count;
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
PS_Mask mask = 0;
@@ -287,7 +287,7 @@
FT_Memory memory,
PS_Mask *amask )
{
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UInt count;
PS_Mask mask;
@@ -316,7 +316,7 @@
FT_UInt bit_count,
FT_Memory memory )
{
- FT_Error error = PSH_Err_Ok;
+ FT_Error error;
PS_Mask mask;
@@ -384,7 +384,7 @@
FT_UInt count;
- count = ( count1 <= count2 ) ? count1 : count2;
+ count = FT_MIN( count1, count2 );
for ( ; count >= 8; count -= 8 )
{
if ( p1[0] & p2[0] )
@@ -409,7 +409,7 @@
FT_Memory memory )
{
FT_UInt temp;
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
/* swap index1 and index2 so that index1 < index2 */
@@ -499,7 +499,7 @@
FT_Memory memory )
{
FT_Int index1, index2;
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
for ( index1 = table->num_masks - 1; index1 > 0; index1-- )
@@ -561,7 +561,7 @@
FT_Memory memory )
{
PS_Mask mask;
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
/* get last hint mask */
@@ -583,12 +583,13 @@
FT_UInt end_point )
{
FT_UInt count = dim->masks.num_masks;
- PS_Mask mask;
if ( count > 0 )
{
- mask = dim->masks.masks + count - 1;
+ PS_Mask mask = dim->masks.masks + count - 1;
+
+
mask->end_point = end_point;
}
}
@@ -621,7 +622,7 @@
FT_UInt end_point,
FT_Memory memory )
{
- FT_Error error = PSH_Err_Ok;
+ FT_Error error;
/* reset current mask, if any */
@@ -646,7 +647,7 @@
FT_Memory memory,
FT_Int *aindex )
{
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UInt flags = 0;
@@ -717,7 +718,7 @@
FT_Int hint3,
FT_Memory memory )
{
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UInt count = dim->counters.num_masks;
PS_Mask counter = dim->counters.masks;
@@ -791,7 +792,7 @@
ps_dimension_done( &hints->dimension[0], memory );
ps_dimension_done( &hints->dimension[1], memory );
- hints->error = PSH_Err_Ok;
+ hints->error = FT_Err_Ok;
hints->memory = 0;
}
@@ -802,7 +803,7 @@
{
FT_MEM_ZERO( hints, sizeof ( *hints ) );
hints->memory = memory;
- return PSH_Err_Ok;
+ return FT_Err_Ok;
}
@@ -815,7 +816,7 @@
{
case PS_HINT_TYPE_1:
case PS_HINT_TYPE_2:
- hints->error = PSH_Err_Ok;
+ hints->error = FT_Err_Ok;
hints->hint_type = hint_type;
ps_dimension_init( &hints->dimension[0] );
@@ -823,7 +824,7 @@
break;
default:
- hints->error = PSH_Err_Invalid_Argument;
+ hints->error = FT_THROW( Invalid_Argument );
hints->hint_type = hint_type;
FT_TRACE0(( "ps_hints_open: invalid charstring type\n" ));
@@ -894,7 +895,7 @@
FT_Int dimension,
FT_Fixed* stems )
{
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( !hints->error )
@@ -938,7 +939,7 @@
else
{
FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type\n" ));
- error = PSH_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Fail;
}
}
@@ -956,7 +957,7 @@
ps_hints_t1reset( PS_Hints hints,
FT_UInt end_point )
{
- FT_Error error = PSH_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( !hints->error )
@@ -979,7 +980,7 @@
else
{
/* invalid hint type */
- error = PSH_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Fail;
}
}
diff --git a/src/psnames/psmodule.c b/src/psnames/psmodule.c
index 3619174..0a5bcb7 100644
--- a/src/psnames/psmodule.c
+++ b/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, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,6 +17,7 @@
#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_OBJECTS_H
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
@@ -369,7 +370,7 @@
/* No unicode chars here! */
FT_FREE( table->maps );
if ( !error )
- error = PSnames_Err_No_Unicode_Glyph_Name;
+ error = FT_THROW( No_Unicode_Glyph_Name );
}
else
{
@@ -377,7 +378,7 @@
if ( count < num_glyphs / 2 )
{
(void)FT_RENEW_ARRAY( table->maps, num_glyphs, count );
- error = PSnames_Err_Ok;
+ error = FT_Err_Ok;
}
/* Sort the table in increasing order of unicode values, */
@@ -521,7 +522,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 +534,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 +577,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 +599,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/src/psnames/pspic.c b/src/psnames/pspic.c
index 467ab73..3820f65 100644
--- a/src/psnames/pspic.c
+++ b/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, 2013 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;
@@ -62,18 +64,19 @@
psnames_module_class_pic_init( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Error error = PSnames_Err_Ok;
- PSModulePIC* container;
+ FT_Error error = FT_Err_Ok;
+ PSModulePIC* container = NULL;
FT_Memory memory = library->memory;
/* allocate pointer, clear and set global container pointer */
- if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+ if ( FT_ALLOC( container, sizeof ( *container ) ) )
return error;
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/src/psnames/pspic.h b/src/psnames/pspic.h
index 1169b89..6ff002c 100644
--- a/src/psnames/pspic.h
+++ b/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 FT_INTERNAL_PIC_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/src/raster/ftmisc.h b/src/raster/ftmisc.h
index 7773924..703155a 100644
--- a/src/raster/ftmisc.h
+++ b/src/raster/ftmisc.h
@@ -115,6 +115,27 @@
return ( s > 0 ) ? d : -d;
}
+
+ static FT_Long
+ FT_MulDiv_No_Round( FT_Long a,
+ FT_Long b,
+ FT_Long c )
+ {
+ FT_Int s;
+ FT_Long d;
+
+
+ s = 1;
+ if ( a < 0 ) { a = -a; s = -1; }
+ if ( b < 0 ) { b = -b; s = -s; }
+ if ( c < 0 ) { c = -c; s = -s; }
+
+ d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c
+ : 0x7FFFFFFFL );
+
+ return ( s > 0 ) ? d : -d;
+ }
+
#endif /* __FTMISC_H__ */
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index f85845e..4865994 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType glyph rasterizer (body). */
/* */
-/* Copyright 1996-2003, 2005, 2007-2012 by */
+/* Copyright 1996-2003, 2005, 2007-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -60,7 +60,7 @@
#include <ft2build.h>
#include "ftraster.h"
-#include FT_INTERNAL_CALC_H /* for FT_MulDiv only */
+#include FT_INTERNAL_CALC_H /* for FT_MulDiv and FT_MulDiv_No_Round */
#include "rastpic.h"
@@ -179,6 +179,9 @@
#ifdef _STANDALONE_
+ /* Auxiliary macros for token concatenation. */
+#define FT_ERR_XCAT( x, y ) x ## y
+#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
/* This macro is used to indicate that a function parameter is unused. */
/* Its purpose is simply to reduce compiler warnings. Note also that */
@@ -187,7 +190,7 @@
#define FT_UNUSED( x ) (x) = (x)
/* Disable the tracing mechanism for simplicity -- developers can */
- /* activate it easily by redefining these two macros. */
+ /* activate it easily by redefining these macros. */
#ifndef FT_ERROR
#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */
#endif
@@ -198,6 +201,10 @@
#define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */
#endif
+#ifndef FT_THROW
+#define FT_THROW( e ) FT_ERR_CAT( Raster_Err_, e )
+#endif
+
#define Raster_Err_None 0
#define Raster_Err_Not_Ini -1
#define Raster_Err_Overflow -2
@@ -224,11 +231,11 @@
#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H /* for FT_TRACE() and FT_ERROR() */
+#include FT_INTERNAL_DEBUG_H /* for FT_TRACE, FT_ERROR, and FT_THROW */
#include "rasterrs.h"
-#define Raster_Err_None Raster_Err_Ok
+#define Raster_Err_None FT_Err_Ok
#define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized
#define Raster_Err_Overflow Raster_Err_Raster_Overflow
#define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height
@@ -255,7 +262,8 @@
/* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */
/* for clipping computations. It simply uses the FT_MulDiv() function */
/* defined in `ftcalc.h'. */
-#define SMulDiv FT_MulDiv
+#define SMulDiv FT_MulDiv
+#define SMulDiv_No_Round FT_MulDiv_No_Round
/* The rasterizer is a very general purpose component; please leave */
/* the following redefinitions there (you never know your target */
@@ -302,6 +310,7 @@
typedef short Short;
typedef unsigned short UShort, *PUShort;
typedef long Long, *PLong;
+ typedef unsigned long ULong;
typedef unsigned char Byte, *PByte;
typedef char Bool;
@@ -440,9 +449,9 @@
#define FLOOR( x ) ( (x) & -ras.precision )
#define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision )
-#define TRUNC( x ) ( (signed long)(x) >> ras.precision_bits )
+#define TRUNC( x ) ( (Long)(x) >> ras.precision_bits )
#define FRAC( x ) ( (x) & ( ras.precision - 1 ) )
-#define SCALED( x ) ( ( (x) << ras.scale_shift ) - ras.precision_half )
+#define SCALED( x ) ( ( (ULong)(x) << ras.scale_shift ) - ras.precision_half )
#define IS_BOTTOM_OVERSHOOT( x ) ( CEILING( x ) - x >= ras.precision_half )
#define IS_TOP_OVERSHOOT( x ) ( x - FLOOR( x ) >= ras.precision_half )
@@ -654,7 +663,7 @@
/* Set precision variables according to param flag. */
/* */
/* <Input> */
- /* High :: Set to True for high precision (typically for ppem < 18), */
+ /* High :: Set to True for high precision (typically for ppem < 24), */
/* false otherwise. */
/* */
static void
@@ -734,7 +743,7 @@
if ( ras.top >= ras.maxBuff )
{
- ras.error = Raster_Err_Overflow;
+ ras.error = FT_THROW( Overflow );
return FAILURE;
}
@@ -764,7 +773,7 @@
default:
FT_ERROR(( "New_Profile: invalid profile direction\n" ));
- ras.error = Raster_Err_Invalid;
+ ras.error = FT_THROW( Invalid );
return FAILURE;
}
@@ -797,8 +806,7 @@
static Bool
End_Profile( RAS_ARGS Bool overshoot )
{
- Long h;
- PProfile oldProfile;
+ Long h;
h = (Long)( ras.top - ras.cProfile->offset );
@@ -806,12 +814,15 @@
if ( h < 0 )
{
FT_ERROR(( "End_Profile: negative height encountered\n" ));
- ras.error = Raster_Err_Neg_Height;
+ ras.error = FT_THROW( Neg_Height );
return FAILURE;
}
if ( h > 0 )
{
+ PProfile oldProfile;
+
+
FT_TRACE6(( "Ending profile %p, start = %ld, height = %ld\n",
ras.cProfile, ras.cProfile->start, h ));
@@ -839,7 +850,7 @@
if ( ras.top >= ras.maxBuff )
{
FT_TRACE1(( "overflow in End_Profile\n" ));
- ras.error = Raster_Err_Overflow;
+ ras.error = FT_THROW( Overflow );
return FAILURE;
}
@@ -868,7 +879,7 @@
Insert_Y_Turn( RAS_ARGS Int y )
{
PLong y_turns;
- Int y2, n;
+ Int n;
n = ras.numTurns - 1;
@@ -882,7 +893,9 @@
if ( n >= 0 && y > y_turns[n] )
while ( n >= 0 )
{
- y2 = (Int)y_turns[n];
+ Int y2 = (Int)y_turns[n];
+
+
y_turns[n] = y;
y = y2;
n--;
@@ -893,7 +906,7 @@
ras.maxBuff--;
if ( ras.maxBuff <= ras.top )
{
- ras.error = Raster_Err_Overflow;
+ ras.error = FT_THROW( Overflow );
return FAILURE;
}
ras.numTurns++;
@@ -918,7 +931,6 @@
static Bool
Finalize_Profile_Table( RAS_ARG )
{
- Int bottom, top;
UShort n;
PProfile p;
@@ -930,6 +942,9 @@
{
while ( n > 0 )
{
+ Int bottom, top;
+
+
if ( n > 1 )
p->link = (PProfile)( p->offset + p->height );
else
@@ -1144,20 +1159,20 @@
size = e2 - e1 + 1;
if ( ras.top + size >= ras.maxBuff )
{
- ras.error = Raster_Err_Overflow;
+ ras.error = FT_THROW( Overflow );
return FAILURE;
}
if ( Dx > 0 )
{
- Ix = SMulDiv( ras.precision, Dx, Dy);
+ Ix = SMulDiv_No_Round( ras.precision, Dx, Dy );
Rx = ( ras.precision * Dx ) % Dy;
Dx = 1;
}
else
{
- Ix = SMulDiv( ras.precision, -Dx, Dy) * -1;
- Rx = ( ras.precision * -Dx ) % Dy;
+ Ix = -SMulDiv_No_Round( ras.precision, -Dx, Dy );
+ Rx = ( ras.precision * -Dx ) % Dy;
Dx = -1;
}
@@ -1319,7 +1334,7 @@
if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff )
{
ras.top = top;
- ras.error = Raster_Err_Overflow;
+ ras.error = FT_THROW( Overflow );
return FAILURE;
}
@@ -1994,7 +2009,7 @@
return SUCCESS;
Invalid_Outline:
- ras.error = Raster_Err_Invalid;
+ ras.error = FT_THROW( Invalid );
Fail:
return FAILURE;
@@ -2023,8 +2038,6 @@
int i;
unsigned start;
- PProfile lastProfile;
-
ras.fProfile = NULL;
ras.joint = FALSE;
@@ -2042,7 +2055,8 @@
for ( i = 0; i < ras.outline.n_contours; i++ )
{
- Bool o;
+ PProfile lastProfile;
+ Bool o;
ras.state = Unknown_State;
@@ -2266,8 +2280,6 @@
PProfile right )
{
Long e1, e2;
- int c1, c2;
- Byte f1, f2;
Byte* target;
FT_UNUSED( y );
@@ -2286,6 +2298,10 @@
if ( e2 >= 0 && e1 < ras.bWidth )
{
+ int c1, c2;
+ Byte f1, f2;
+
+
if ( e1 < 0 )
e1 = 0;
if ( e2 >= ras.bWidth )
@@ -2509,21 +2525,24 @@
PProfile left,
PProfile right )
{
- Long e1, e2;
- PByte bits;
- Byte f1;
-
FT_UNUSED( left );
FT_UNUSED( right );
if ( x2 - x1 < ras.precision )
{
+ Long e1, e2;
+
+
e1 = CEILING( x1 );
e2 = FLOOR ( x2 );
if ( e1 == e2 )
{
+ Byte f1;
+ PByte bits;
+
+
bits = ras.bTarget + ( y >> 3 );
f1 = (Byte)( 0x80 >> ( y & 7 ) );
@@ -2720,8 +2739,6 @@
static void
Vertical_Gray_Sweep_Step( RAS_ARG )
{
- Int c1, c2;
- PByte pix, bit, bit2;
short* count = (short*)count_table;
Byte* grays;
@@ -2730,6 +2747,9 @@
if ( ras.traceOfs > ras.gray_width )
{
+ PByte pix;
+
+
pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4;
grays = ras.grays;
@@ -2740,6 +2760,9 @@
Int last_bit = last_pixel & 3;
Bool over = 0;
+ Int c1, c2;
+ PByte bit, bit2;
+
if ( ras.gray_max_x >= last_cell && last_bit != 3 )
{
@@ -2832,7 +2855,6 @@
{
Long e1, e2;
PByte pixel;
- Byte color;
/* During the horizontal sweep, we only take care of drop-outs */
@@ -2886,6 +2908,9 @@
if ( e1 >= 0 )
{
+ Byte color;
+
+
if ( x2 - x1 >= ras.precision_half )
color = ras.grays[2];
else
@@ -2963,7 +2988,7 @@
/* check the Y-turns */
if ( ras.numTurns == 0 )
{
- ras.error = Raster_Err_Invalid;
+ ras.error = FT_THROW( Invalid );
return FAILURE;
}
@@ -3204,7 +3229,7 @@
if ( ras.band_top >= 7 || k < i )
{
ras.band_top = 0;
- ras.error = Raster_Err_Invalid;
+ ras.error = FT_THROW( Invalid );
return ras.error;
}
@@ -3393,7 +3418,7 @@
{
FT_UNUSED_RASTER;
- return Raster_Err_Unsupported;
+ return FT_THROW( Unsupported );
}
#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */
@@ -3498,7 +3523,8 @@
raster->buffer = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 );
- raster->buffer_size = pool_base + pool_size - (char*)raster->buffer;
+ raster->buffer_size = (long)( pool_base + pool_size -
+ (char*)raster->buffer );
raster->worker = worker;
}
else
@@ -3548,37 +3574,37 @@
if ( !raster || !raster->buffer || !raster->buffer_size )
- return Raster_Err_Not_Ini;
+ return FT_THROW( Not_Ini );
if ( !outline )
- return Raster_Err_Invalid;
+ return FT_THROW( Invalid );
/* return immediately if the outline is empty */
if ( outline->n_points == 0 || outline->n_contours <= 0 )
return Raster_Err_None;
if ( !outline->contours || !outline->points )
- return Raster_Err_Invalid;
+ return FT_THROW( Invalid );
if ( outline->n_points !=
outline->contours[outline->n_contours - 1] + 1 )
- return Raster_Err_Invalid;
+ return FT_THROW( Invalid );
worker = raster->worker;
/* this version of the raster does not support direct rendering, sorry */
if ( params->flags & FT_RASTER_FLAG_DIRECT )
- return Raster_Err_Unsupported;
+ return FT_THROW( Unsupported );
if ( !target_map )
- return Raster_Err_Invalid;
+ return FT_THROW( Invalid );
/* nothing to do */
if ( !target_map->width || !target_map->rows )
return Raster_Err_None;
if ( !target_map->buffer )
- return Raster_Err_Invalid;
+ return FT_THROW( Invalid );
ras.outline = *outline;
ras.target = *target_map;
diff --git a/src/raster/ftrend1.c b/src/raster/ftrend1.c
index 859cb7d..aa7f6d5 100644
--- a/src/raster/ftrend1.c
+++ b/src/raster/ftrend1.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType glyph rasterizer interface (body). */
/* */
-/* Copyright 1996-2003, 2005, 2006, 2011 by */
+/* Copyright 1996-2003, 2005, 2006, 2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,6 +17,7 @@
#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_OBJECTS_H
#include FT_OUTLINE_H
#include "ftrend1.h"
@@ -37,7 +38,7 @@
library->raster_pool,
library->raster_pool_size );
- return Raster_Err_Ok;
+ return FT_Err_Ok;
}
@@ -61,12 +62,12 @@
const FT_Matrix* matrix,
const FT_Vector* delta )
{
- FT_Error error = Raster_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( slot->format != render->glyph_format )
{
- error = Raster_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -114,7 +115,7 @@
/* check glyph image format */
if ( slot->format != render->glyph_format )
{
- error = Raster_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -124,13 +125,13 @@
{
/* raster1 is only capable of producing monochrome bitmaps */
if ( render->clazz == &ft_raster1_renderer_class )
- return Raster_Err_Cannot_Render_Glyph;
+ return FT_THROW( Cannot_Render_Glyph );
}
else
{
/* raster5 is only capable of producing 5-gray-levels bitmaps */
if ( render->clazz == &ft_raster5_renderer_class )
- return Raster_Err_Cannot_Render_Glyph;
+ return FT_THROW( Cannot_Render_Glyph );
}
#else /* FT_CONFIG_OPTION_PIC */
/* When PIC is enabled, we cannot get to the class object */
@@ -142,13 +143,13 @@
{
/* raster1 is only capable of producing monochrome bitmaps */
if ( render->clazz->root.module_name[6] == '1' )
- return Raster_Err_Cannot_Render_Glyph;
+ return FT_THROW( Cannot_Render_Glyph );
}
else
{
/* raster5 is only capable of producing 5-gray-levels bitmaps */
if ( render->clazz->root.module_name[6] == '5' )
- return Raster_Err_Cannot_Render_Glyph;
+ return FT_THROW( Cannot_Render_Glyph );
}
#endif /* FT_CONFIG_OPTION_PIC */
@@ -179,7 +180,7 @@
if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX )
{
- error = Raster_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
diff --git a/src/raster/rastpic.c b/src/raster/rastpic.c
index 2883e3f..5e9f7cc 100644
--- a/src/raster/rastpic.c
+++ b/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, 2013 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -22,22 +22,26 @@
#include "rastpic.h"
#include "rasterrs.h"
+
#ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from ftraster.c */
void
FT_Init_Class_ft_standard_raster( FT_Raster_Funcs* funcs );
+
void
ft_raster1_renderer_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->raster )
{
- RasterPIC* container = (RasterPIC*)pic_container->raster;
+ RasterPIC* container = (RasterPIC*)pic_container->raster;
+
+
if ( --container->ref_count )
return;
FT_FREE( container );
@@ -49,14 +53,14 @@
FT_Error
ft_raster1_renderer_class_pic_init( FT_Library library )
{
- FT_PIC_Container* pic_container = &library->pic_container;
- FT_Error error = Raster_Err_Ok;
- RasterPIC* container;
- FT_Memory memory = library->memory;
+ FT_PIC_Container* pic_container = &library->pic_container;
+ FT_Error error = FT_Err_Ok;
+ RasterPIC* container = NULL;
+ FT_Memory memory = library->memory;
- /* since this function also serve raster5 renderer,
- it implements reference counting */
+ /* since this function also serves raster5 renderer, */
+ /* it implements reference counting */
if ( pic_container->raster )
{
((RasterPIC*)pic_container->raster)->ref_count++;
@@ -68,16 +72,17 @@
return error;
FT_MEM_SET( container, 0, sizeof ( *container ) );
pic_container->raster = container;
+
container->ref_count = 1;
- /* 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_standard_raster( &container->ft_standard_raster );
-/*Exit:*/
- if( error )
- ft_raster1_renderer_class_pic_free( library );
+
return error;
}
+
/* re-route these init and free functions to the above functions */
FT_Error
ft_raster5_renderer_class_pic_init( FT_Library library )
@@ -85,6 +90,7 @@
return ft_raster1_renderer_class_pic_init( library );
}
+
void
ft_raster5_renderer_class_pic_free( FT_Library library )
{
diff --git a/src/raster/rastpic.h b/src/raster/rastpic.h
index 7822a24..e0ddba6 100644
--- a/src/raster/rastpic.h
+++ b/src/raster/rastpic.h
@@ -24,19 +24,25 @@ FT_BEGIN_HEADER
#include FT_INTERNAL_PIC_H
+
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_STANDARD_RASTER_GET ft_standard_raster
+
+#define FT_STANDARD_RASTER_GET ft_standard_raster
#else /* FT_CONFIG_OPTION_PIC */
- typedef struct RasterPIC_
+ typedef struct RasterPIC_
{
- int ref_count;
- FT_Raster_Funcs ft_standard_raster;
+ int ref_count;
+ FT_Raster_Funcs ft_standard_raster;
+
} RasterPIC;
-#define GET_PIC(lib) ((RasterPIC*)((lib)->pic_container.raster))
-#define FT_STANDARD_RASTER_GET (GET_PIC(library)->ft_standard_raster)
+
+#define GET_PIC( lib ) \
+ ( (RasterPIC*)( (lib)->pic_container.raster ) )
+#define FT_STANDARD_RASTER_GET ( GET_PIC( library )->ft_standard_raster )
+
/* see rastpic.c for the implementation */
void
diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c
new file mode 100644
index 0000000..408f879
--- /dev/null
+++ b/src/sfnt/pngshim.c
@@ -0,0 +1,336 @@
+/***************************************************************************/
+/* */
+/* pngshim.c */
+/* */
+/* PNG Bitmap glyph support. */
+/* */
+/* Copyright 2013 by Google, Inc. */
+/* Written by Stuart Gill and Behdad Esfahbod. */
+/* */
+/* 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_STREAM_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_CONFIG_STANDARD_LIBRARY_H
+
+
+#ifdef FT_CONFIG_OPTION_USE_PNG
+
+ /* We always include <stjmp.h>, so make libpng shut up! */
+#define PNG_SKIP_SETJMP_CHECK 1
+#include <png.h>
+#include "pngshim.h"
+
+#include "sferrors.h"
+
+
+ /* This code is freely based on cairo-png.c. There's so many ways */
+ /* to call libpng, and the way cairo does it is defacto standard. */
+
+ static int
+ multiply_alpha( int alpha,
+ int color )
+ {
+ int temp = ( alpha * color ) + 0x80;
+
+
+ return ( temp + ( temp >> 8 ) ) >> 8;
+ }
+
+
+ /* Premultiplies data and converts RGBA bytes => native endian. */
+ static void
+ premultiply_data( png_structp png,
+ png_row_infop row_info,
+ png_bytep data )
+ {
+ unsigned int i;
+
+ FT_UNUSED( png );
+
+
+ for ( i = 0; i < row_info->rowbytes; i += 4 )
+ {
+ unsigned char* base = &data[i];
+ unsigned int alpha = base[3];
+
+
+ if ( alpha == 0 )
+ base[0] = base[1] = base[2] = base[3] = 0;
+
+ else
+ {
+ unsigned int red = base[0];
+ unsigned int green = base[1];
+ unsigned int blue = base[2];
+
+
+ if ( alpha != 0xFF )
+ {
+ red = multiply_alpha( alpha, red );
+ green = multiply_alpha( alpha, green );
+ blue = multiply_alpha( alpha, blue );
+ }
+
+ base[0] = blue;
+ base[1] = green;
+ base[2] = red;
+ base[3] = alpha;
+ }
+ }
+ }
+
+
+ /* Converts RGBx bytes to BGRA. */
+ static void
+ convert_bytes_to_data( png_structp png,
+ png_row_infop row_info,
+ png_bytep data )
+ {
+ unsigned int i;
+
+ FT_UNUSED( png );
+
+
+ for ( i = 0; i < row_info->rowbytes; i += 4 )
+ {
+ unsigned char* base = &data[i];
+ unsigned int red = base[0];
+ unsigned int green = base[1];
+ unsigned int blue = base[2];
+
+
+ base[0] = blue;
+ base[1] = green;
+ base[2] = red;
+ base[3] = 0xFF;
+ }
+ }
+
+
+ /* Use error callback to avoid png writing to stderr. */
+ static void
+ error_callback( png_structp png,
+ png_const_charp error_msg )
+ {
+ FT_Error* error = png_get_error_ptr( png );
+
+ FT_UNUSED( error_msg );
+
+
+ *error = FT_THROW( Out_Of_Memory );
+#ifdef PNG_SETJMP_SUPPORTED
+ longjmp( png_jmpbuf( png ), 1 );
+#endif
+ /* if we get here, then we have no choice but to abort ... */
+ }
+
+
+ /* Use warning callback to avoid png writing to stderr. */
+ static void
+ warning_callback( png_structp png,
+ png_const_charp error_msg )
+ {
+ FT_UNUSED( png );
+ FT_UNUSED( error_msg );
+
+ /* Just ignore warnings. */
+ }
+
+
+ static void
+ read_data_from_FT_Stream( png_structp png,
+ png_bytep data,
+ png_size_t length )
+ {
+ FT_Error error;
+ png_voidp p = png_get_io_ptr( png );
+ FT_Stream stream = (FT_Stream)p;
+
+
+ if ( FT_FRAME_ENTER( length ) )
+ {
+ FT_Error* e = png_get_error_ptr( png );
+
+
+ *e = FT_THROW( Invalid_Stream_Read );
+ png_error( png, NULL );
+
+ return;
+ }
+
+ memcpy( data, stream->cursor, length );
+
+ FT_FRAME_EXIT();
+ }
+
+
+ static FT_Error
+ Load_SBit_Png( FT_Bitmap* map,
+ FT_Int x_offset,
+ FT_Int y_offset,
+ FT_Int pix_bits,
+ TT_SBit_Metrics metrics,
+ FT_Memory memory,
+ FT_Byte* data,
+ FT_UInt png_len )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_StreamRec stream;
+
+ png_structp png;
+ png_infop info;
+ png_uint_32 imgWidth, imgHeight;
+
+ int bitdepth, color_type, interlace;
+ FT_Int i;
+ png_byte* *rows;
+
+
+ if ( x_offset < 0 || x_offset + metrics->width > map->width ||
+ y_offset < 0 || y_offset + metrics->height > map->rows ||
+ pix_bits != 32 || map->pixel_mode != FT_PIXEL_MODE_BGRA )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ FT_Stream_OpenMemory( &stream, data, png_len );
+
+ png = png_create_read_struct( PNG_LIBPNG_VER_STRING,
+ &error,
+ error_callback,
+ warning_callback );
+ if ( !png )
+ {
+ error = FT_THROW( Out_Of_Memory );
+ goto Exit;
+ }
+
+ info = png_create_info_struct( png );
+ if ( !info )
+ {
+ error = FT_THROW( Out_Of_Memory );
+ png_destroy_read_struct( &png, NULL, NULL );
+ goto Exit;
+ }
+
+ if ( ft_setjmp( png_jmpbuf( png ) ) )
+ {
+ error = FT_THROW( Invalid_File_Format );
+ goto DestroyExit;
+ }
+
+ png_set_read_fn( png, &stream, read_data_from_FT_Stream );
+
+ png_read_info( png, info );
+ png_get_IHDR( png, info,
+ &imgWidth, &imgHeight,
+ &bitdepth, &color_type, &interlace,
+ NULL, NULL );
+
+ if ( error != FT_Err_Ok ||
+ (FT_Int)imgWidth != metrics->width ||
+ (FT_Int)imgHeight != metrics->height )
+ goto DestroyExit;
+
+ /* convert palette/gray image to rgb */
+ if ( color_type == PNG_COLOR_TYPE_PALETTE )
+ png_set_palette_to_rgb( png );
+
+ /* expand gray bit depth if needed */
+ if ( color_type == PNG_COLOR_TYPE_GRAY )
+ {
+#if PNG_LIBPNG_VER >= 10209
+ png_set_expand_gray_1_2_4_to_8( png );
+#else
+ png_set_gray_1_2_4_to_8( png );
+#endif
+ }
+
+ /* transform transparency to alpha */
+ if ( png_get_valid(png, info, PNG_INFO_tRNS ) )
+ png_set_tRNS_to_alpha( png );
+
+ if ( bitdepth == 16 )
+ png_set_strip_16( png );
+
+ if ( bitdepth < 8 )
+ png_set_packing( png );
+
+ /* convert grayscale to RGB */
+ if ( color_type == PNG_COLOR_TYPE_GRAY ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
+ png_set_gray_to_rgb( png );
+
+ if ( interlace != PNG_INTERLACE_NONE )
+ png_set_interlace_handling( png );
+
+ png_set_filler( png, 0xFF, PNG_FILLER_AFTER );
+
+ /* recheck header after setting EXPAND options */
+ png_read_update_info(png, info );
+ png_get_IHDR( png, info,
+ &imgWidth, &imgHeight,
+ &bitdepth, &color_type, &interlace,
+ NULL, NULL );
+
+ if ( bitdepth != 8 ||
+ !( color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA ) )
+ {
+ error = FT_THROW( Invalid_File_Format );
+ goto DestroyExit;
+ }
+
+ switch ( color_type )
+ {
+ default:
+ /* Shouldn't happen, but fall through. */
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ png_set_read_user_transform_fn( png, premultiply_data );
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ /* Humm, this smells. Carry on though. */
+ png_set_read_user_transform_fn( png, convert_bytes_to_data );
+ break;
+ }
+
+ if ( FT_NEW_ARRAY( rows, imgHeight ) )
+ {
+ error = FT_THROW( Out_Of_Memory );
+ goto DestroyExit;
+ }
+
+ for ( i = 0; i < (FT_Int)imgHeight; i++ )
+ rows[i] = map->buffer + ( y_offset + i ) * map->pitch + x_offset * 4;
+
+ png_read_image( png, rows );
+
+ FT_FREE( rows );
+
+ png_read_end( png, info );
+
+ DestroyExit:
+ png_destroy_read_struct( &png, &info, NULL );
+ FT_Stream_Close( &stream );
+
+ Exit:
+ return error;
+ }
+
+#endif /* FT_CONFIG_OPTION_USE_PNG */
+
+
+/* END */
diff --git a/src/sfnt/pngshim.h b/src/sfnt/pngshim.h
new file mode 100644
index 0000000..8a2e69c
--- /dev/null
+++ b/src/sfnt/pngshim.h
@@ -0,0 +1,48 @@
+/***************************************************************************/
+/* */
+/* pngshim.h */
+/* */
+/* PNG Bitmap glyph support. */
+/* */
+/* Copyright 2013 by Google, Inc. */
+/* Written by Stuart Gill and Behdad Esfahbod. */
+/* */
+/* 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 __PNGSHIM_H__
+#define __PNGSHIM_H__
+
+
+#include <ft2build.h>
+#include "ttload.h"
+
+
+FT_BEGIN_HEADER
+
+#ifdef FT_CONFIG_OPTION_USE_PNG
+
+ FT_LOCAL( FT_Error )
+ Load_SBit_Png( FT_Bitmap* map,
+ FT_Int x_offset,
+ FT_Int y_offset,
+ FT_Int pix_bits,
+ TT_SBit_Metrics metrics,
+ FT_Memory memory,
+ FT_Byte* data,
+ FT_UInt png_len );
+
+#endif
+
+FT_END_HEADER
+
+#endif /* __PNGSHIM_H__ */
+
+
+/* END */
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index 847d83d..a368b8c 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -4,7 +4,7 @@
/* */
/* High-level SFNT driver interface (body). */
/* */
-/* Copyright 1996-2007, 2009-2011 by */
+/* Copyright 1996-2007, 2009-2013 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,
@@ -118,37 +119,37 @@
FT_ULong *length )
{
if ( !offset || !length )
- return SFNT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( !tag )
*length = face->num_tables;
else
{
if ( idx >= face->num_tables )
- return SFNT_Err_Table_Missing;
+ return FT_THROW( Table_Missing );
*tag = face->dir_tables[idx].Tag;
*offset = face->dir_tables[idx].Offset;
*length = face->dir_tables[idx].Length;
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- 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 )
@@ -254,7 +257,7 @@
FT_Memory memory = face->root.memory;
TT_NameEntryRec* name = face->name_table.names + found_win;
FT_UInt len = name->stringLength / 2;
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UNUSED( error );
@@ -296,7 +299,7 @@
FT_Memory memory = face->root.memory;
TT_NameEntryRec* name = face->name_table.names + found_apple;
FT_UInt len = name->stringLength;
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UNUSED( error );
@@ -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
@@ -367,7 +371,7 @@
*acharset_registry = registry.u.atom;
}
else
- error = SFNT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
}
}
@@ -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,149 +440,25 @@
#else
FT_UNUSED( module );
#endif
- return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface );
- }
-
-
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_load_sfnt_header_stub( TT_Face face,
- FT_Stream stream,
- FT_Long face_index,
- SFNT_Header header )
- {
- FT_UNUSED( face );
- FT_UNUSED( stream );
- FT_UNUSED( face_index );
- FT_UNUSED( header );
-
- return SFNT_Err_Unimplemented_Feature;
- }
-
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_load_directory_stub( TT_Face face,
- FT_Stream stream,
- SFNT_Header header )
- {
- FT_UNUSED( face );
- FT_UNUSED( stream );
- FT_UNUSED( header );
-
- return SFNT_Err_Unimplemented_Feature;
- }
-
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_load_hdmx_stub( TT_Face face,
- FT_Stream stream )
- {
- FT_UNUSED( face );
- FT_UNUSED( stream );
-
- return SFNT_Err_Unimplemented_Feature;
- }
-
-
- FT_CALLBACK_DEF( void )
- tt_face_free_hdmx_stub( TT_Face face )
- {
- FT_UNUSED( face );
- }
-
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_set_sbit_strike_stub( TT_Face face,
- FT_UInt x_ppem,
- FT_UInt y_ppem,
- FT_ULong* astrike_index )
- {
- /*
- * We simply forge a FT_Size_Request and call the real function
- * that does all the work.
- *
- * This stub might be called by libXfont in the X.Org Xserver,
- * compiled against version 2.1.8 or newer.
- */
-
- FT_Size_RequestRec req;
-
-
- req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
- req.width = (FT_F26Dot6)x_ppem;
- req.height = (FT_F26Dot6)y_ppem;
- req.horiResolution = 0;
- req.vertResolution = 0;
-
- *astrike_index = 0x7FFFFFFFUL;
- return tt_face_set_sbit_strike( face, &req, astrike_index );
+ return ft_service_list_lookup( SFNT_SERVICES_GET, module_interface );
}
- FT_CALLBACK_DEF( FT_Error )
- tt_face_load_sbit_stub( TT_Face face,
- FT_Stream stream )
- {
- FT_UNUSED( face );
- FT_UNUSED( stream );
-
- /*
- * This function was originally implemented to load the sbit table.
- * However, it has been replaced by `tt_face_load_eblc', and this stub
- * is only there for some rogue clients which would want to call it
- * directly (which doesn't make much sense).
- */
- return SFNT_Err_Unimplemented_Feature;
- }
-
-
- FT_CALLBACK_DEF( void )
- tt_face_free_sbit_stub( TT_Face face )
- {
- /* nothing to do in this stub */
- FT_UNUSED( face );
- }
-
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_load_charmap_stub( TT_Face face,
- void* cmap,
- FT_Stream input )
- {
- FT_UNUSED( face );
- FT_UNUSED( cmap );
- FT_UNUSED( input );
-
- return SFNT_Err_Unimplemented_Feature;
- }
-
-
- FT_CALLBACK_DEF( FT_Error )
- tt_face_free_charmap_stub( TT_Face face,
- void* cmap )
- {
- FT_UNUSED( face );
- FT_UNUSED( cmap );
-
- return SFNT_Err_Ok;
- }
-
-#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,
@@ -587,9 +468,6 @@
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_head,
tt_face_load_hhea,
tt_face_load_cmap,
@@ -600,54 +478,39 @@
tt_face_load_name,
tt_face_free_name,
- tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
tt_face_load_kern,
tt_face_load_gasp,
tt_face_load_pclt,
/* see `ttload.h' */
- 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_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_bhed ),
- tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+ PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ),
/* see `ttpost.h' */
- 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 */
+ PUT_PS_NAMES( tt_face_get_ps_name ),
+ PUT_PS_NAMES( tt_face_free_ps_names ),
/* since version 2.1.8 */
-
tt_face_get_kerning,
/* since version 2.2 */
-
tt_face_load_font_dir,
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 +519,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/src/sfnt/sferrors.h b/src/sfnt/sferrors.h
index 564a3fe..e981e1d 100644
--- a/src/sfnt/sferrors.h
+++ b/src/sfnt/sferrors.h
@@ -4,7 +4,7 @@
/* */
/* SFNT error codes (specification only). */
/* */
-/* Copyright 2001, 2004, 2012 by */
+/* Copyright 2001, 2004, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -33,8 +33,6 @@
#define FT_ERR_PREFIX SFNT_Err_
#define FT_ERR_BASE FT_Mod_Err_SFNT
-#define FT_KEEP_ERR_PREFIX
-
#include FT_ERRORS_H
#endif /* __SFERRORS_H__ */
diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c
index fc507b4..d62ed4e 100644
--- a/src/sfnt/sfnt.c
+++ b/src/sfnt/sfnt.c
@@ -4,7 +4,7 @@
/* */
/* Single object library component. */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
+/* Copyright 1996-2006, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -28,6 +28,7 @@
#include "sfdriver.c"
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+#include "pngshim.c"
#include "ttsbit.c"
#endif
diff --git a/src/sfnt/sfntpic.c b/src/sfnt/sfntpic.c
index 1372376..b3fb24b 100644
--- a/src/sfnt/sfntpic.c
+++ b/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, 2013 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -22,57 +22,52 @@
#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,
FT_ServiceDescRec* clazz );
-
void
FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec* clazz );
-
void
FT_Init_Class_sfnt_interface( FT_Library library,
SFNT_Interface* clazz );
-
void
FT_Init_Class_sfnt_service_glyph_dict(
FT_Library library,
FT_Service_GlyphDictRec* clazz );
-
void
FT_Init_Class_sfnt_service_ps_name(
FT_Library library,
FT_Service_PsFontNameRec* clazz );
-
void
FT_Init_Class_tt_service_get_cmap_info(
FT_Library library,
FT_Service_TTCMapsRec* clazz );
-
void
FT_Init_Class_sfnt_service_sfnt_table(
FT_Service_SFNT_TableRec* clazz );
+
/* forward declaration of PIC init functions from ttcmap.c */
FT_Error
FT_Create_Class_tt_cmap_classes( FT_Library library,
TT_CMap_Class** output_class );
-
void
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 +79,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,25 +92,27 @@
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 = FT_Err_Ok;
+ sfntModulePIC* container = NULL;
+ FT_Memory memory = library->memory;
/* allocate pointer, clear and set global container pointer */
- if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+ if ( FT_ALLOC( container, sizeof ( *container ) ) )
return error;
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 +131,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/src/sfnt/sfntpic.h b/src/sfnt/sfntpic.h
index f7993d1..b09a914 100644
--- a/src/sfnt/sfntpic.h
+++ b/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 FT_INTERNAL_PIC_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 FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_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/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index d7be631..f975e71 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -4,7 +4,7 @@
/* */
/* SFNT object management (base). */
/* */
-/* Copyright 1996-2008, 2010-2011 by */
+/* Copyright 1996-2008, 2010-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -64,13 +64,17 @@
for ( n = 0; n < len; n++ )
{
code = FT_NEXT_USHORT( read );
+
+ if ( code == 0 )
+ break;
+
if ( code < 32 || code > 127 )
code = '?';
string[n] = (char)code;
}
- string[len] = 0;
+ string[n] = 0;
return string;
}
@@ -95,13 +99,17 @@
for ( n = 0; n < len; n++ )
{
code = *read++;
+
+ if ( code == 0 )
+ break;
+
if ( code < 32 || code > 127 )
code = '?';
string[n] = (char)code;
}
- string[len] = 0;
+ string[n] = 0;
return string;
}
@@ -137,7 +145,7 @@
FT_String** name )
{
FT_Memory memory = face->root.memory;
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_String* result = NULL;
FT_UShort n;
TT_NameEntryRec* rec;
@@ -378,7 +386,7 @@
tag != 0x00020000UL )
{
FT_TRACE2(( " not a font using the SFNT container format\n" ));
- return SFNT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
}
face->ttc_header.tag = TTAG_ttcf;
@@ -394,7 +402,7 @@
return error;
if ( face->ttc_header.count == 0 )
- return SFNT_Err_Invalid_Table;
+ return FT_THROW( Invalid_Table );
/* a rough size estimate: let's conservatively assume that there */
/* is just a single table info in each subfont header (12 + 16*1 = */
@@ -402,7 +410,7 @@
/* size of the TTC header plus `28*count' bytes for all subfont */
/* headers */
if ( (FT_ULong)face->ttc_header.count > stream->size / ( 28 + 4 ) )
- return SFNT_Err_Array_Too_Large;
+ return FT_THROW( Array_Too_Large );
/* now read the offsets of each font in the file */
if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
@@ -457,7 +465,7 @@
if ( !sfnt )
{
FT_ERROR(( "sfnt_init_face: cannot access `sfnt' module\n" ));
- return SFNT_Err_Missing_Module;
+ return FT_THROW( Missing_Module );
}
face->sfnt = sfnt;
@@ -478,7 +486,7 @@
face_index = 0;
if ( face_index >= face->ttc_header.count )
- return SFNT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
return error;
@@ -495,42 +503,42 @@
}
-#define LOAD_( x ) \
- do { \
- FT_TRACE2(( "`" #x "' " )); \
- FT_TRACE3(( "-->\n" )); \
- \
- error = sfnt->load_##x( face, stream ); \
- \
- FT_TRACE2(( "%s\n", ( !error ) \
- ? "loaded" \
- : ( error == SFNT_Err_Table_Missing ) \
- ? "missing" \
- : "failed to load" )); \
- FT_TRACE3(( "\n" )); \
+#define LOAD_( x ) \
+ do { \
+ FT_TRACE2(( "`" #x "' " )); \
+ FT_TRACE3(( "-->\n" )); \
+ \
+ error = sfnt->load_ ## x( face, stream ); \
+ \
+ FT_TRACE2(( "%s\n", ( !error ) \
+ ? "loaded" \
+ : FT_ERR_EQ( error, Table_Missing ) \
+ ? "missing" \
+ : "failed to load" )); \
+ FT_TRACE3(( "\n" )); \
} while ( 0 )
-#define LOADM_( x, vertical ) \
- do { \
- FT_TRACE2(( "`%s" #x "' ", \
- vertical ? "vertical " : "" )); \
- FT_TRACE3(( "-->\n" )); \
- \
- error = sfnt->load_##x( face, stream, vertical ); \
- \
- FT_TRACE2(( "%s\n", ( !error ) \
- ? "loaded" \
- : ( error == SFNT_Err_Table_Missing ) \
- ? "missing" \
- : "failed to load" )); \
- FT_TRACE3(( "\n" )); \
+#define LOADM_( x, vertical ) \
+ do { \
+ FT_TRACE2(( "`%s" #x "' ", \
+ vertical ? "vertical " : "" )); \
+ FT_TRACE3(( "-->\n" )); \
+ \
+ error = sfnt->load_ ## x( face, stream, vertical ); \
+ \
+ FT_TRACE2(( "%s\n", ( !error ) \
+ ? "loaded" \
+ : FT_ERR_EQ( error, Table_Missing ) \
+ ? "missing" \
+ : "failed to load" )); \
+ 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 )
@@ -547,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 */
{
@@ -619,7 +628,7 @@
if ( face->header.Units_Per_EM == 0 )
{
- error = SFNT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -647,9 +656,9 @@
if ( !error )
{
LOADM_( hmtx, 0 );
- if ( error == SFNT_Err_Table_Missing )
+ if ( FT_ERR_EQ( error, Table_Missing ) )
{
- error = SFNT_Err_Hmtx_Table_Missing;
+ error = FT_THROW( Hmtx_Table_Missing );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font and there are */
@@ -659,12 +668,12 @@
get_glyph_metrics )
{
face->horizontal.number_Of_HMetrics = 0;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
}
#endif
}
}
- else if ( error == SFNT_Err_Table_Missing )
+ else if ( FT_ERR_EQ( error, Table_Missing ) )
{
/* No `hhea' table necessary for SFNT Mac fonts. */
if ( face->format_tag == TTAG_true )
@@ -672,11 +681,11 @@
FT_TRACE2(( "This is an SFNT Mac font.\n" ));
has_outline = 0;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
}
else
{
- error = SFNT_Err_Horiz_Header_Missing;
+ error = FT_THROW( Horiz_Header_Missing );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font and there are */
@@ -686,7 +695,7 @@
get_glyph_metrics )
{
face->horizontal.number_Of_HMetrics = 0;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
}
#endif
@@ -705,7 +714,7 @@
face->vertical_info = 1;
}
- if ( error && error != SFNT_Err_Table_Missing )
+ if ( error && FT_ERR_NEQ( error, Table_Missing ) )
goto Exit;
LOAD_( os2 );
@@ -727,8 +736,8 @@
/* a font which contains neither bitmaps nor outlines is */
/* still valid (although rather useless in most cases); */
/* however, you can find such stripped fonts in PDFs */
- if ( error == SFNT_Err_Table_Missing )
- error = SFNT_Err_Ok;
+ if ( FT_ERR_EQ( error, Table_Missing ) )
+ error = FT_Err_Ok;
else
goto Exit;
}
@@ -737,7 +746,7 @@
LOAD_( pclt );
if ( error )
{
- if ( error != SFNT_Err_Table_Missing )
+ if ( FT_ERR_NEQ( error, Table_Missing ) )
goto Exit;
face->pclt.Version = 0;
@@ -803,7 +812,7 @@
FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
- if ( psnames_error == SFNT_Err_Ok &&
+ if ( !psnames_error &&
face->postscript.FormatType != 0x00030000L )
flags |= FT_FACE_FLAG_GLYPH_NAMES;
#endif
@@ -910,11 +919,7 @@
FT_UInt i, count;
-#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
count = face->sbit_num_strikes;
-#else
- count = (FT_UInt)face->num_sbit_strikes;
-#endif
if ( count > 0 )
{
@@ -1115,7 +1120,6 @@
}
/* freeing the horizontal metrics */
-#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
{
FT_Stream stream = FT_FACE_STREAM( face );
@@ -1125,10 +1129,6 @@
face->horz_metrics_size = 0;
face->vert_metrics_size = 0;
}
-#else
- FT_FREE( face->horizontal.long_metrics );
- FT_FREE( face->horizontal.short_metrics );
-#endif
/* freeing the vertical ones, if any */
if ( face->vertical_info )
diff --git a/src/sfnt/ttbdf.c b/src/sfnt/ttbdf.c
index 18845c3..9401dae 100644
--- a/src/sfnt/ttbdf.c
+++ b/src/sfnt/ttbdf.c
@@ -4,7 +4,7 @@
/* */
/* TrueType and OpenType embedded BDF properties (body). */
/* */
-/* Copyright 2005, 2006, 2010 by */
+/* Copyright 2005, 2006, 2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -74,7 +74,7 @@
length < 8 ||
FT_FRAME_EXTRACT( length, bdf->table ) )
{
- error = SFNT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -131,7 +131,7 @@
BadTable:
FT_FRAME_RELEASE( bdf->table );
FT_ZERO( bdf );
- error = SFNT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -143,7 +143,7 @@
{
TT_BDF bdf = &face->bdf;
FT_Size size = FT_FACE(face)->size;
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Byte* p;
FT_UInt count;
FT_Byte* strike;
@@ -163,7 +163,7 @@
p = bdf->table + 8;
strike = p + 4 * count;
- error = SFNT_Err_Invalid_Argument;
+ error = FT_ERR( Invalid_Argument );
if ( size == NULL || property_name == NULL )
goto Exit;
@@ -215,7 +215,7 @@
{
aprop->type = BDF_PROPERTY_TYPE_ATOM;
aprop->u.atom = (const char*)bdf->strings + value;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
}
break;
@@ -223,13 +223,13 @@
case 0x02:
aprop->type = BDF_PROPERTY_TYPE_INTEGER;
aprop->u.integer = (FT_Int32)value;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
case 0x03:
aprop->type = BDF_PROPERTY_TYPE_CARDINAL;
aprop->u.cardinal = value;
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
default:
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index 1dfd987..1507202 100644
--- a/src/sfnt/ttcmap.c
+++ b/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, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -56,7 +56,7 @@
FT_Byte* table )
{
cmap->data = table;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -110,7 +110,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -161,24 +161,28 @@
cmap_info->format = 0;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- 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 */
@@ -365,7 +369,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -537,24 +541,28 @@
cmap_info->format = 2;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- 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 */
@@ -662,7 +670,7 @@
cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
cmap->cur_gindex = 0;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -812,7 +820,7 @@
FT_UInt length = TT_NEXT_USHORT( p );
FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids;
FT_UInt num_segs;
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( length < 16 )
@@ -1373,23 +1381,27 @@
cmap_info->format = 4;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- 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 */
@@ -1456,7 +1468,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -1532,24 +1544,28 @@
cmap_info->format = 6;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- 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 */
@@ -1700,7 +1716,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -1785,24 +1801,28 @@
cmap_info->format = 8;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- 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 */
@@ -1867,7 +1887,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -1934,24 +1954,28 @@
cmap_info->format = 10;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- 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 */
@@ -2010,7 +2034,7 @@
cmap->valid = 0;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -2063,7 +2087,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -2254,24 +2278,28 @@
cmap_info->format = 12;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- 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 */
@@ -2330,7 +2358,7 @@
cmap->valid = 0;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -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 )
@@ -2383,7 +2411,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -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 )
{
@@ -2570,24 +2597,28 @@
cmap_info->format = 13;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
- 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 = FT_Err_Ok;
if ( num_results > cmap->max_results )
@@ -2713,11 +2744,11 @@
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;
+ return FT_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 ) )
@@ -2819,7 +2850,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -2857,7 +2888,7 @@
/* subtable 14 does not define a language field */
cmap_info->language = 0xFFFFFFFFUL;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -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,50 +3365,62 @@
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"
clazz[i] = NULL;
*output_class = clazz;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
#endif /*FT_CONFIG_OPTION_PIC*/
@@ -3398,7 +3442,7 @@
if ( !p || p + 4 > limit )
- return SFNT_Err_Invalid_Table;
+ return FT_THROW( Invalid_Table );
/* only recognize format 0 */
if ( TT_NEXT_USHORT( p ) != 0 )
@@ -3407,14 +3451,16 @@
FT_ERROR(( "tt_face_build_cmaps:"
" unsupported `cmap' table format = %d\n",
TT_PEEK_USHORT( p ) ));
- return SFNT_Err_Invalid_Table;
+ return FT_THROW( Invalid_Table );
}
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;
@@ -3444,7 +3490,7 @@
if ( clazz->format == format )
{
volatile TT_ValidatorRec valid;
- volatile FT_Error error = SFNT_Err_Ok;
+ volatile FT_Error error = FT_Err_Ok;
ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit,
@@ -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 ) )
@@ -3493,7 +3538,7 @@
}
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
diff --git a/src/sfnt/ttcmap.h b/src/sfnt/ttcmap.h
index 94f7978..0fde167 100644
--- a/src/sfnt/ttcmap.h
+++ b/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/src/sfnt/ttcmapc.h b/src/sfnt/ttcmapc.h
index 4c9c6a5..2ea2043 100644
--- a/src/sfnt/ttcmapc.h
+++ b/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/src/sfnt/ttkern.c b/src/sfnt/ttkern.c
index 4688898..60ee546 100644
--- a/src/sfnt/ttkern.c
+++ b/src/sfnt/ttkern.c
@@ -61,7 +61,7 @@
{
FT_ERROR(( "tt_face_load_kern:"
" kerning table is too small - ignored\n" ));
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
goto Exit;
}
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index 5fb9aea..fbe70f7 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -5,8 +5,7 @@
/* Load the basic TrueType tables, i.e., tables that can be either in */
/* TTF or OTF fonts (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
-/* 2010 by */
+/* Copyright 1996-2010, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -143,7 +142,7 @@
goto Exit;
}
else
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
Exit:
return error;
@@ -238,7 +237,7 @@
if ( table.Length < 0x36 )
{
FT_TRACE2(( "check_table_dir: `head' table too small\n" ));
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
goto Exit;
}
@@ -250,7 +249,7 @@
{
FT_TRACE2(( "check_table_dir:"
" no magic number found in `head' table\n"));
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
goto Exit;
}
@@ -268,14 +267,14 @@
if ( sfnt->num_tables == 0 )
{
FT_TRACE2(( "check_table_dir: no tables found\n" ));
- error = SFNT_Err_Unknown_File_Format;
+ error = FT_THROW( Unknown_File_Format );
goto Exit;
}
/* if `sing' and `meta' tables are present, there is no `head' table */
if ( has_head || ( has_sing && has_meta ) )
{
- error = SFNT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
}
else
@@ -286,7 +285,7 @@
#else
FT_TRACE2(( " neither `head' nor `sing' table found\n" ));
#endif
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
}
Exit:
@@ -354,7 +353,7 @@
#if 0
if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 ) ||
sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 )
- return SFNT_Err_Unknown_File_Format;
+ return FT_THROW( Unknown_File_Format );
#endif
/* load the table directory */
@@ -362,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;
@@ -480,7 +482,7 @@
table = tt_face_lookup_table( face, tag );
if ( !table )
{
- error = SFNT_Err_Table_Missing;
+ error = FT_THROW( Table_Missing );
goto Exit;
}
@@ -495,7 +497,7 @@
{
*length = size;
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
if ( length )
@@ -624,7 +626,7 @@
FT_Error error;
TT_MaxProfile* maxProfile = &face->max_profile;
- const FT_Frame_Field maxp_fields[] =
+ static const FT_Frame_Field maxp_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE TT_MaxProfile
@@ -635,7 +637,7 @@
FT_FRAME_END
};
- const FT_Frame_Field maxp_fields_extra[] =
+ static const FT_Frame_Field maxp_fields_extra[] =
{
FT_FRAME_START( 26 ),
FT_FRAME_USHORT( maxPoints ),
@@ -721,7 +723,7 @@
/*************************************************************************/
/* */
/* <Function> */
- /* tt_face_load_names */
+ /* tt_face_load_name */
/* */
/* <Description> */
/* Loads the name records. */
@@ -799,7 +801,7 @@
if ( storage_start > storage_limit )
{
FT_ERROR(( "tt_face_load_name: invalid `name' table\n" ));
- error = SFNT_Err_Name_Table_Missing;
+ error = FT_THROW( Name_Table_Missing );
goto Exit;
}
@@ -952,7 +954,7 @@
FT_Error error;
TT_OS2* os2;
- const FT_Frame_Field os2_fields[] =
+ static const FT_Frame_Field os2_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE TT_OS2
@@ -1004,7 +1006,7 @@
FT_FRAME_END
};
- const FT_Frame_Field os2_fields_extra[] =
+ static const FT_Frame_Field os2_fields_extra[] =
{
FT_FRAME_START( 8 ),
FT_FRAME_ULONG( ulCodePageRange1 ),
@@ -1012,7 +1014,7 @@
FT_FRAME_END
};
- const FT_Frame_Field os2_fields_extra2[] =
+ static const FT_Frame_Field os2_fields_extra2[] =
{
FT_FRAME_START( 10 ),
FT_FRAME_SHORT ( sxHeight ),
@@ -1125,7 +1127,7 @@
FT_TRACE3(( "isFixedPitch: %s\n", post->isFixedPitch
? " yes" : " no" ));
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -1233,18 +1235,18 @@
if ( face->gasp.version >= 2 )
{
face->gasp.numRanges = 0;
- error = SFNT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
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/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c
index 73ac8b2..371a9ed 100644
--- a/src/sfnt/ttmtx.c
+++ b/src/sfnt/ttmtx.c
@@ -4,7 +4,7 @@
/* */
/* Load the metrics tables common to TTF and OTF fonts (body). */
/* */
-/* Copyright 2006-2009, 2011 by */
+/* Copyright 2006-2009, 2011-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -35,13 +35,6 @@
#define FT_COMPONENT trace_ttmtx
- /*
- * Unfortunately, we can't enable our memory optimizations if
- * FT_CONFIG_OPTION_OLD_INTERNALS is defined. This is because at least
- * one rogue client (libXfont in the X.Org XServer) is directly accessing
- * the metrics.
- */
-
/*************************************************************************/
/* */
/* <Function> */
@@ -60,8 +53,6 @@
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
-#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
-
FT_LOCAL_DEF( FT_Error )
tt_face_load_hmtx( TT_Face face,
FT_Stream stream,
@@ -97,142 +88,6 @@
return error;
}
-#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */
-
- FT_LOCAL_DEF( FT_Error )
- tt_face_load_hmtx( TT_Face face,
- FT_Stream stream,
- FT_Bool vertical )
- {
- FT_Error error;
- FT_Memory memory = stream->memory;
-
- FT_ULong table_len;
- FT_Long num_shorts, num_longs, num_shorts_checked;
-
- TT_LongMetrics* longs;
- TT_ShortMetrics** shorts;
- FT_Byte* p;
-
-
- if ( vertical )
- {
- void* lm = &face->vertical.long_metrics;
- void** sm = &face->vertical.short_metrics;
-
-
- error = face->goto_table( face, TTAG_vmtx, stream, &table_len );
- if ( error )
- goto Fail;
-
- num_longs = face->vertical.number_Of_VMetrics;
- if ( (FT_ULong)num_longs > table_len / 4 )
- num_longs = (FT_Long)( table_len / 4 );
-
- face->vertical.number_Of_VMetrics = 0;
-
- longs = (TT_LongMetrics*)lm;
- shorts = (TT_ShortMetrics**)sm;
- }
- else
- {
- void* lm = &face->horizontal.long_metrics;
- void** sm = &face->horizontal.short_metrics;
-
-
- error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
- if ( error )
- goto Fail;
-
- num_longs = face->horizontal.number_Of_HMetrics;
- if ( (FT_ULong)num_longs > table_len / 4 )
- num_longs = (FT_Long)( table_len / 4 );
-
- face->horizontal.number_Of_HMetrics = 0;
-
- longs = (TT_LongMetrics*)lm;
- shorts = (TT_ShortMetrics**)sm;
- }
-
- /* never trust derived values */
-
- num_shorts = face->max_profile.numGlyphs - num_longs;
- num_shorts_checked = ( table_len - num_longs * 4L ) / 2;
-
- if ( num_shorts < 0 )
- {
- FT_TRACE0(( "tt_face_load_hmtx:"
- " %cmtx has more metrics than glyphs.\n",
- vertical ? 'v' : 'h' ));
-
- /* Adobe simply ignores this problem. So we shall do the same. */
-#if 0
- error = vertical ? SFNT_Err_Invalid_Vert_Metrics
- : SFNT_Err_Invalid_Horiz_Metrics;
- goto Exit;
-#else
- num_shorts = 0;
-#endif
- }
-
- if ( FT_QNEW_ARRAY( *longs, num_longs ) ||
- FT_QNEW_ARRAY( *shorts, num_shorts ) )
- goto Fail;
-
- if ( FT_FRAME_ENTER( table_len ) )
- goto Fail;
-
- p = stream->cursor;
-
- {
- TT_LongMetrics cur = *longs;
- TT_LongMetrics limit = cur + num_longs;
-
-
- for ( ; cur < limit; cur++ )
- {
- cur->advance = FT_NEXT_USHORT( p );
- cur->bearing = FT_NEXT_SHORT( p );
- }
- }
-
- /* do we have an inconsistent number of metric values? */
- {
- TT_ShortMetrics* cur = *shorts;
- TT_ShortMetrics* limit = cur +
- FT_MIN( num_shorts, num_shorts_checked );
-
-
- for ( ; cur < limit; cur++ )
- *cur = FT_NEXT_SHORT( p );
-
- /* We fill up the missing left side bearings with the */
- /* last valid value. Since this will occur for buggy CJK */
- /* fonts usually only, nothing serious will happen. */
- if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 )
- {
- FT_Short val = (*shorts)[num_shorts_checked - 1];
-
-
- limit = *shorts + num_shorts;
- for ( ; cur < limit; cur++ )
- *cur = val;
- }
- }
-
- FT_FRAME_EXIT();
-
- if ( vertical )
- face->vertical.number_Of_VMetrics = (FT_UShort)num_longs;
- else
- face->horizontal.number_Of_HMetrics = (FT_UShort)num_longs;
-
- Fail:
- return error;
- }
-
-#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */
-
/*************************************************************************/
/* */
@@ -260,7 +115,7 @@
FT_Error error;
TT_HoriHeader* header;
- const FT_Frame_Field metrics_header_fields[] =
+ static const FT_Frame_Field metrics_header_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE TT_HoriHeader
@@ -343,8 +198,6 @@
/* */
/* advance :: The advance width resp. advance height. */
/* */
-#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
-
FT_LOCAL_DEF( FT_Error )
tt_face_get_metrics( TT_Face face,
FT_Bool vertical,
@@ -419,50 +272,8 @@
*aadvance = 0;
}
- return SFNT_Err_Ok;
- }
-
-#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */
-
- FT_LOCAL_DEF( FT_Error )
- tt_face_get_metrics( TT_Face face,
- FT_Bool vertical,
- FT_UInt gindex,
- FT_Short* abearing,
- FT_UShort* aadvance )
- {
- void* v = &face->vertical;
- void* h = &face->horizontal;
- TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v
- : (TT_HoriHeader*)h;
- TT_LongMetrics longs_m;
- FT_UShort k = header->number_Of_HMetrics;
-
-
- if ( k == 0 ||
- !header->long_metrics ||
- gindex >= (FT_UInt)face->max_profile.numGlyphs )
- {
- *abearing = *aadvance = 0;
- return SFNT_Err_Ok;
- }
-
- if ( gindex < (FT_UInt)k )
- {
- longs_m = (TT_LongMetrics)header->long_metrics + gindex;
- *abearing = longs_m->bearing;
- *aadvance = longs_m->advance;
- }
- else
- {
- *abearing = ((TT_ShortMetrics*)header->short_metrics)[gindex - k];
- *aadvance = ((TT_LongMetrics)header->long_metrics)[k - 1].advance;
- }
-
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
-#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */
-
/* END */
diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c
index 6f4bb1d..47a85c0 100644
--- a/src/sfnt/ttpost.c
+++ b/src/sfnt/ttpost.c
@@ -5,7 +5,7 @@
/* Postcript name table processing for TrueType and OpenType fonts */
/* (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010 by */
+/* Copyright 1996-2003, 2006-2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -178,7 +178,7 @@
if ( num_glyphs > face->max_profile.numGlyphs )
{
- error = SFNT_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -284,7 +284,7 @@
table->glyph_indices = glyph_indices;
table->glyph_names = name_strings;
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
Fail1:
{
@@ -325,7 +325,7 @@
/* check the number of glyphs */
if ( num_glyphs > face->max_profile.numGlyphs || num_glyphs > 258 )
{
- error = SFNT_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -345,7 +345,7 @@
if ( idx < 0 || idx > num_glyphs )
{
- error = SFNT_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Fail;
}
}
@@ -360,7 +360,7 @@
table->offsets = offset_table;
}
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
Fail:
FT_FREE( offset_table );
@@ -402,7 +402,7 @@
else if ( format == 0x00028000L )
error = load_format_25( face, stream, post_limit );
else
- error = SFNT_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
face->postscript_names.loaded = 1;
@@ -488,15 +488,15 @@
if ( !face )
- return SFNT_Err_Invalid_Face_Handle;
+ return FT_THROW( Invalid_Face_Handle );
if ( idx >= (FT_UInt)face->max_profile.numGlyphs )
- return SFNT_Err_Invalid_Glyph_Index;
+ return FT_THROW( Invalid_Glyph_Index );
#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
psnames = (FT_Service_PsCMaps)face->psnames;
if ( !psnames )
- return SFNT_Err_Unimplemented_Feature;
+ return FT_THROW( Unimplemented_Feature );
#endif
names = &face->postscript_names;
@@ -556,7 +556,7 @@
/* nothing to do for format == 0x00030000L */
End:
- return SFNT_Err_Ok;
+ return FT_Err_Ok;
}
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 283ba7e..cd3e5a4 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -4,10 +4,12 @@
/* */
/* TrueType and OpenType embedded bitmap support (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
-/* 2010 by */
+/* Copyright 2005-2009, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
+/* Copyright 2013 by Google, Inc. */
+/* Google Author(s): Behdad Esfahbod. */
+/* */
/* 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 */
@@ -16,29 +18,18 @@
/* */
/***************************************************************************/
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
-
- /*
- * Alas, the memory-optimized sbit loader can't be used when implementing
- * the `old internals' hack
- */
-#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
-
-#include "ttsbit0.c"
-
-#else /* FT_CONFIG_OPTION_OLD_INTERNALS */
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H
+#include FT_BITMAP_H
#include "ttsbit.h"
#include "sferrors.h"
+#include "pngshim.h"
+
/*************************************************************************/
/* */
@@ -50,1398 +41,1108 @@
#define FT_COMPONENT trace_ttsbit
- /*************************************************************************/
- /* */
- /* <Function> */
- /* blit_sbit */
- /* */
- /* <Description> */
- /* Blits a bitmap from an input stream into a given target. Supports */
- /* x and y offsets as well as byte padded lines. */
- /* */
- /* <Input> */
- /* target :: The target bitmap/pixmap. */
- /* */
- /* source :: The input packed bitmap data. */
- /* */
- /* line_bits :: The number of bits per line. */
- /* */
- /* byte_padded :: A flag which is true if lines are byte-padded. */
- /* */
- /* x_offset :: The horizontal offset. */
- /* */
- /* y_offset :: The vertical offset. */
- /* */
- /* <Note> */
- /* IMPORTANT: The x and y offsets are relative to the top corner of */
- /* the target bitmap (unlike the normal TrueType */
- /* convention). A positive y offset indicates a downwards */
- /* direction! */
- /* */
- static void
- blit_sbit( FT_Bitmap* target,
- FT_Byte* source,
- FT_Int line_bits,
- FT_Bool byte_padded,
- FT_Int x_offset,
- FT_Int y_offset,
- FT_Int source_height )
+ FT_LOCAL_DEF( FT_Error )
+ tt_face_load_eblc( TT_Face face,
+ FT_Stream stream )
{
- FT_Byte* line_buff;
- FT_Int line_incr;
- FT_Int height;
+ FT_Error error = FT_Err_Ok;
+ FT_Fixed version;
+ FT_ULong num_strikes, table_size;
+ FT_Byte* p;
+ FT_Byte* p_limit;
+ FT_UInt count;
- FT_UShort acc;
- FT_UInt loaded;
+ face->sbit_num_strikes = 0;
- /* first of all, compute starting write position */
- line_incr = target->pitch;
- line_buff = target->buffer;
+ /* this table is optional */
+ error = face->goto_table( face, TTAG_CBLC, stream, &table_size );
+ if ( error )
+ error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
+ if ( error )
+ error = face->goto_table( face, TTAG_bloc, stream, &table_size );
+ if ( error )
+ goto Exit;
- if ( line_incr < 0 )
- line_buff -= line_incr * ( target->rows - 1 );
+ if ( table_size < 8 )
+ {
+ FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
- line_buff += ( x_offset >> 3 ) + y_offset * line_incr;
+ if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
+ goto Exit;
+
+ face->sbit_table_size = table_size;
- /***********************************************************************/
- /* */
- /* We use the extra-classic `accumulator' trick to extract the bits */
- /* from the source byte stream. */
- /* */
- /* Namely, the variable `acc' is a 16-bit accumulator containing the */
- /* last `loaded' bits from the input stream. The bits are shifted to */
- /* the upmost position in `acc'. */
- /* */
- /***********************************************************************/
+ p = face->sbit_table;
+ p_limit = p + table_size;
- acc = 0; /* clear accumulator */
- loaded = 0; /* no bits were loaded */
+ version = FT_NEXT_ULONG( p );
+ num_strikes = FT_NEXT_ULONG( p );
- for ( height = source_height; height > 0; height-- )
+ if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
{
- FT_Byte* cur = line_buff; /* current write cursor */
- FT_Int count = line_bits; /* # of bits to extract per line */
- FT_Byte shift = (FT_Byte)( x_offset & 7 ); /* current write shift */
- FT_Byte space = (FT_Byte)( 8 - shift );
+ FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Fail;
+ }
+ /*
+ * Count the number of strikes available in the table. We are a bit
+ * paranoid there and don't trust the data.
+ */
+ count = (FT_UInt)num_strikes;
+ if ( 8 + 48UL * count > table_size )
+ count = (FT_UInt)( ( p_limit - p ) / 48 );
- /* first of all, read individual source bytes */
- if ( count >= 8 )
- {
- count -= 8;
- {
- do
- {
- FT_Byte val;
-
-
- /* ensure that there are at least 8 bits in the accumulator */
- if ( loaded < 8 )
- {
- acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
- loaded += 8;
- }
-
- /* now write one byte */
- val = (FT_Byte)( acc >> 8 );
- if ( shift )
- {
- cur[0] |= (FT_Byte)( val >> shift );
- cur[1] |= (FT_Byte)( val << space );
- }
- else
- cur[0] |= val;
-
- cur++;
- acc <<= 8; /* remove bits from accumulator */
- loaded -= 8;
- count -= 8;
-
- } while ( count >= 0 );
- }
+ face->sbit_num_strikes = count;
- /* restore `count' to correct value */
- count += 8;
- }
+ FT_TRACE3(( "sbit_num_strikes: %u\n", count ));
+ Exit:
+ return error;
- /* now write remaining bits (count < 8) */
- if ( count > 0 )
- {
- FT_Byte val;
+ Fail:
+ FT_FRAME_RELEASE( face->sbit_table );
+ face->sbit_table_size = 0;
+ goto Exit;
+ }
- /* ensure that there are at least `count' bits in the accumulator */
- if ( (FT_Int)loaded < count )
- {
- acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
- loaded += 8;
- }
-
- /* now write remaining bits */
- val = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) );
- cur[0] |= (FT_Byte)( val >> shift );
+ FT_LOCAL_DEF( void )
+ tt_face_free_eblc( TT_Face face )
+ {
+ FT_Stream stream = face->root.stream;
- if ( count > space )
- cur[1] |= (FT_Byte)( val << space );
- acc <<= count;
- loaded -= count;
- }
+ FT_FRAME_RELEASE( face->sbit_table );
+ face->sbit_table_size = 0;
+ face->sbit_num_strikes = 0;
+ }
- /* now, skip to next line */
- if ( byte_padded )
- {
- acc = 0;
- loaded = 0; /* clear accumulator on byte-padded lines */
- }
- line_buff += line_incr;
- }
+ FT_LOCAL_DEF( FT_Error )
+ tt_face_set_sbit_strike( TT_Face face,
+ FT_Size_Request req,
+ FT_ULong* astrike_index )
+ {
+ return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
}
- static const FT_Frame_Field sbit_metrics_fields[] =
+ FT_LOCAL_DEF( FT_Error )
+ tt_face_load_strike_metrics( TT_Face face,
+ FT_ULong strike_index,
+ FT_Size_Metrics* metrics )
{
-#undef FT_STRUCTURE
-#define FT_STRUCTURE TT_SBit_MetricsRec
+ FT_Byte* strike;
- FT_FRAME_START( 8 ),
- FT_FRAME_BYTE( height ),
- FT_FRAME_BYTE( width ),
- FT_FRAME_CHAR( horiBearingX ),
- FT_FRAME_CHAR( horiBearingY ),
- FT_FRAME_BYTE( horiAdvance ),
+ if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
+ return FT_THROW( Invalid_Argument );
- FT_FRAME_CHAR( vertBearingX ),
- FT_FRAME_CHAR( vertBearingY ),
- FT_FRAME_BYTE( vertAdvance ),
- FT_FRAME_END
- };
+ strike = face->sbit_table + 8 + strike_index * 48;
+ metrics->x_ppem = (FT_UShort)strike[44];
+ metrics->y_ppem = (FT_UShort)strike[45];
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Load_SBit_Const_Metrics */
- /* */
- /* <Description> */
- /* Loads the metrics for `EBLC' index tables format 2 and 5. */
- /* */
- /* <Input> */
- /* range :: The target range. */
- /* */
- /* stream :: The input stream. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- static FT_Error
- Load_SBit_Const_Metrics( TT_SBit_Range range,
- FT_Stream stream )
+ metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */
+ metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */
+ metrics->height = metrics->ascender - metrics->descender;
+
+ /* XXX: Is this correct? */
+ metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */
+ strike[18] + /* max_width */
+ (FT_Char)strike[23] /* min_advance_SB */
+ ) << 6;
+
+ return FT_Err_Ok;
+ }
+
+
+ typedef struct TT_SBitDecoderRec_
{
- FT_Error error;
+ TT_Face face;
+ FT_Stream stream;
+ FT_Bitmap* bitmap;
+ TT_SBit_Metrics metrics;
+ FT_Bool metrics_loaded;
+ FT_Bool bitmap_allocated;
+ FT_Byte bit_depth;
+ FT_ULong ebdt_start;
+ FT_ULong ebdt_size;
- if ( FT_READ_ULONG( range->image_size ) )
- return error;
+ FT_ULong strike_index_array;
+ FT_ULong strike_index_count;
+ FT_Byte* eblc_base;
+ FT_Byte* eblc_limit;
- return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics );
- }
+ } TT_SBitDecoderRec, *TT_SBitDecoder;
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Load_SBit_Range_Codes */
- /* */
- /* <Description> */
- /* Loads the range codes for `EBLC' index tables format 4 and 5. */
- /* */
- /* <Input> */
- /* range :: The target range. */
- /* */
- /* stream :: The input stream. */
- /* */
- /* load_offsets :: A flag whether to load the glyph offset table. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
static FT_Error
- Load_SBit_Range_Codes( TT_SBit_Range range,
- FT_Stream stream,
- FT_Bool load_offsets )
+ tt_sbit_decoder_init( TT_SBitDecoder decoder,
+ TT_Face face,
+ FT_ULong strike_index,
+ TT_SBit_MetricsRec* metrics )
{
FT_Error error;
- FT_ULong count, n, size;
- FT_Memory memory = stream->memory;
+ FT_Stream stream = face->root.stream;
+ FT_ULong ebdt_size;
- if ( FT_READ_ULONG( count ) )
+ error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size );
+ if ( error )
+ error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
+ if ( error )
+ error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
+ if ( error )
goto Exit;
- range->num_glyphs = count;
+ decoder->face = face;
+ decoder->stream = stream;
+ decoder->bitmap = &face->root.glyph->bitmap;
+ decoder->metrics = metrics;
- /* Allocate glyph offsets table if needed */
- if ( load_offsets )
- {
- if ( FT_NEW_ARRAY( range->glyph_offsets, count ) )
- goto Exit;
+ decoder->metrics_loaded = 0;
+ decoder->bitmap_allocated = 0;
- size = count * 4L;
- }
- else
- size = count * 2L;
+ decoder->ebdt_start = FT_STREAM_POS();
+ decoder->ebdt_size = ebdt_size;
- /* Allocate glyph codes table and access frame */
- if ( FT_NEW_ARRAY ( range->glyph_codes, count ) ||
- FT_FRAME_ENTER( size ) )
- goto Exit;
+ decoder->eblc_base = face->sbit_table;
+ decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
- for ( n = 0; n < count; n++ )
+ /* now find the strike corresponding to the index */
{
- range->glyph_codes[n] = FT_GET_USHORT();
+ FT_Byte* p;
- if ( load_offsets )
- range->glyph_offsets[n] = (FT_ULong)range->image_offset +
- FT_GET_USHORT();
- }
- FT_FRAME_EXIT();
+ if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
+ {
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+
+ p = decoder->eblc_base + 8 + 48 * strike_index;
+
+ decoder->strike_index_array = FT_NEXT_ULONG( p );
+ p += 4;
+ decoder->strike_index_count = FT_NEXT_ULONG( p );
+ p += 34;
+ decoder->bit_depth = *p;
+
+ if ( decoder->strike_index_array > face->sbit_table_size ||
+ decoder->strike_index_array + 8 * decoder->strike_index_count >
+ face->sbit_table_size )
+ error = FT_THROW( Invalid_File_Format );
+ }
Exit:
return error;
}
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Load_SBit_Range */
- /* */
- /* <Description> */
- /* Loads a given `EBLC' index/range table. */
- /* */
- /* <Input> */
- /* range :: The target range. */
- /* */
- /* stream :: The input stream. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- static FT_Error
- Load_SBit_Range( TT_SBit_Range range,
- FT_Stream stream )
+ static void
+ tt_sbit_decoder_done( TT_SBitDecoder decoder )
{
- FT_Error error;
- FT_Memory memory = stream->memory;
-
-
- switch( range->index_format )
- {
- case 1: /* variable metrics with 4-byte offsets */
- case 3: /* variable metrics with 2-byte offsets */
- {
- FT_ULong num_glyphs, n;
- FT_Int size_elem;
- FT_Bool large = FT_BOOL( range->index_format == 1 );
+ FT_UNUSED( decoder );
+ }
+ static FT_Error
+ tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder,
+ FT_UInt load_flags )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_UInt width, height;
+ FT_Bitmap* map = decoder->bitmap;
+ FT_Long size;
- if ( range->last_glyph < range->first_glyph )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
- num_glyphs = range->last_glyph - range->first_glyph + 1L;
- range->num_glyphs = num_glyphs;
- num_glyphs++; /* XXX: BEWARE - see spec */
+ if ( !decoder->metrics_loaded )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
- size_elem = large ? 4 : 2;
+ width = decoder->metrics->width;
+ height = decoder->metrics->height;
- if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) ||
- FT_FRAME_ENTER( num_glyphs * size_elem ) )
- goto Exit;
+ map->width = (int)width;
+ map->rows = (int)height;
- for ( n = 0; n < num_glyphs; n++ )
- range->glyph_offsets[n] = (FT_ULong)( range->image_offset +
- ( large ? FT_GET_ULONG()
- : FT_GET_USHORT() ) );
- FT_FRAME_EXIT();
- }
+ switch ( decoder->bit_depth )
+ {
+ case 1:
+ map->pixel_mode = FT_PIXEL_MODE_MONO;
+ map->pitch = ( map->width + 7 ) >> 3;
+ map->num_grays = 2;
break;
- case 2: /* all glyphs have identical metrics */
- error = Load_SBit_Const_Metrics( range, stream );
+ case 2:
+ map->pixel_mode = FT_PIXEL_MODE_GRAY2;
+ map->pitch = ( map->width + 3 ) >> 2;
+ map->num_grays = 4;
break;
case 4:
- error = Load_SBit_Range_Codes( range, stream, 1 );
+ map->pixel_mode = FT_PIXEL_MODE_GRAY4;
+ map->pitch = ( map->width + 1 ) >> 1;
+ map->num_grays = 16;
break;
- case 5:
- error = Load_SBit_Const_Metrics( range, stream );
- if ( !error )
- error = Load_SBit_Range_Codes( range, stream, 0 );
+ case 8:
+ map->pixel_mode = FT_PIXEL_MODE_GRAY;
+ map->pitch = map->width;
+ map->num_grays = 256;
+ break;
+
+ case 32:
+ if ( load_flags & FT_LOAD_COLOR )
+ {
+ map->pixel_mode = FT_PIXEL_MODE_BGRA;
+ map->pitch = map->width * 4;
+ map->num_grays = 256;
+ }
+ else
+ {
+ map->pixel_mode = FT_PIXEL_MODE_GRAY;
+ map->pitch = map->width;
+ map->num_grays = 256;
+ }
break;
default:
- error = SFNT_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
}
+ size = map->rows * map->pitch;
+
+ /* check that there is no empty image */
+ if ( size == 0 )
+ goto Exit; /* exit successfully! */
+
+ error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
+ if ( error )
+ goto Exit;
+
+ decoder->bitmap_allocated = 1;
+
Exit:
return error;
}
- /*************************************************************************/
- /* */
- /* <Function> */
- /* tt_face_load_eblc */
- /* */
- /* <Description> */
- /* Loads the table of embedded bitmap sizes for this face. */
- /* */
- /* <Input> */
- /* face :: The target face object. */
- /* */
- /* stream :: The input stream. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- FT_LOCAL_DEF( FT_Error )
- tt_face_load_eblc( TT_Face face,
- FT_Stream stream )
+ static FT_Error
+ tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder,
+ FT_Byte* *pp,
+ FT_Byte* limit,
+ FT_Bool big )
{
- FT_Error error = SFNT_Err_Ok;
- FT_Memory memory = stream->memory;
- FT_Fixed version;
- FT_ULong num_strikes;
- FT_ULong table_base;
+ FT_Byte* p = *pp;
+ TT_SBit_Metrics metrics = decoder->metrics;
- static const FT_Frame_Field sbit_line_metrics_fields[] =
- {
-#undef FT_STRUCTURE
-#define FT_STRUCTURE TT_SBit_LineMetricsRec
-
- /* no FT_FRAME_START */
- FT_FRAME_CHAR( ascender ),
- FT_FRAME_CHAR( descender ),
- FT_FRAME_BYTE( max_width ),
-
- FT_FRAME_CHAR( caret_slope_numerator ),
- FT_FRAME_CHAR( caret_slope_denominator ),
- FT_FRAME_CHAR( caret_offset ),
-
- FT_FRAME_CHAR( min_origin_SB ),
- FT_FRAME_CHAR( min_advance_SB ),
- FT_FRAME_CHAR( max_before_BL ),
- FT_FRAME_CHAR( min_after_BL ),
- FT_FRAME_CHAR( pads[0] ),
- FT_FRAME_CHAR( pads[1] ),
- FT_FRAME_END
- };
-
- static const FT_Frame_Field strike_start_fields[] =
- {
-#undef FT_STRUCTURE
-#define FT_STRUCTURE TT_SBit_StrikeRec
-
- /* no FT_FRAME_START */
- FT_FRAME_ULONG( ranges_offset ),
- FT_FRAME_SKIP_LONG,
- FT_FRAME_ULONG( num_ranges ),
- FT_FRAME_ULONG( color_ref ),
- FT_FRAME_END
- };
-
- static const FT_Frame_Field strike_end_fields[] =
+
+ if ( p + 5 > limit )
+ goto Fail;
+
+ metrics->height = p[0];
+ metrics->width = p[1];
+ metrics->horiBearingX = (FT_Char)p[2];
+ metrics->horiBearingY = (FT_Char)p[3];
+ metrics->horiAdvance = p[4];
+
+ p += 5;
+ if ( big )
{
- /* no FT_FRAME_START */
- FT_FRAME_USHORT( start_glyph ),
- FT_FRAME_USHORT( end_glyph ),
- FT_FRAME_BYTE ( x_ppem ),
- FT_FRAME_BYTE ( y_ppem ),
- FT_FRAME_BYTE ( bit_depth ),
- FT_FRAME_CHAR ( flags ),
- FT_FRAME_END
- };
+ if ( p + 3 > limit )
+ goto Fail;
+ metrics->vertBearingX = (FT_Char)p[0];
+ metrics->vertBearingY = (FT_Char)p[1];
+ metrics->vertAdvance = p[2];
- face->num_sbit_strikes = 0;
+ p += 3;
+ }
- /* this table is optional */
- error = face->goto_table( face, TTAG_EBLC, stream, 0 );
- if ( error )
- error = face->goto_table( face, TTAG_bloc, stream, 0 );
- if ( error )
- goto Exit;
+ decoder->metrics_loaded = 1;
+ *pp = p;
+ return FT_Err_Ok;
- table_base = FT_STREAM_POS();
- if ( FT_FRAME_ENTER( 8L ) )
- goto Exit;
+ Fail:
+ FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" ));
+ return FT_THROW( Invalid_Argument );
+ }
- version = FT_GET_LONG();
- num_strikes = FT_GET_ULONG();
- FT_FRAME_EXIT();
+ /* forward declaration */
+ static FT_Error
+ tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_UInt glyph_index,
+ FT_Int x_pos,
+ FT_Int y_pos );
- /* check version number and strike count */
- if ( version != 0x00020000L ||
- num_strikes >= 0x10000L )
- {
- FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
- error = SFNT_Err_Invalid_File_Format;
+ typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_Byte* p,
+ FT_Byte* plimit,
+ FT_Int x_pos,
+ FT_Int y_pos );
- goto Exit;
- }
- /* allocate the strikes table */
- if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) )
- goto Exit;
+ static FT_Error
+ tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_Byte* p,
+ FT_Byte* limit,
+ FT_Int x_pos,
+ FT_Int y_pos )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_Byte* line;
+ FT_Int bit_height, bit_width, pitch, width, height, line_bits, h;
+ FT_Bitmap* bitmap;
- face->num_sbit_strikes = num_strikes;
+ FT_UNUSED( load_flags );
- /* now read each strike table separately */
- {
- TT_SBit_Strike strike = face->sbit_strikes;
- FT_ULong count = num_strikes;
+ /* check that we can write the glyph into the bitmap */
+ bitmap = decoder->bitmap;
+ bit_width = bitmap->width;
+ bit_height = bitmap->rows;
+ pitch = bitmap->pitch;
+ line = bitmap->buffer;
- if ( FT_FRAME_ENTER( 48L * num_strikes ) )
- goto Exit;
+ width = decoder->metrics->width;
+ height = decoder->metrics->height;
- while ( count > 0 )
- {
- if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike ) ||
- FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) ||
- FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) ||
- FT_STREAM_READ_FIELDS( strike_end_fields, strike ) )
- break;
-
- count--;
- strike++;
- }
+ line_bits = width * decoder->bit_depth;
- FT_FRAME_EXIT();
+ if ( x_pos < 0 || x_pos + width > bit_width ||
+ y_pos < 0 || y_pos + height > bit_height )
+ {
+ FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:"
+ " invalid bitmap dimensions\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
}
- /* allocate the index ranges for each strike table */
+ if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit )
{
- TT_SBit_Strike strike = face->sbit_strikes;
- FT_ULong count = num_strikes;
+ FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+ /* now do the blit */
+ line += y_pos * pitch + ( x_pos >> 3 );
+ x_pos &= 7;
- while ( count > 0 )
+ if ( x_pos == 0 ) /* the easy one */
+ {
+ for ( h = height; h > 0; h--, line += pitch )
{
- TT_SBit_Range range;
- FT_ULong count2 = strike->num_ranges;
+ FT_Byte* pwrite = line;
+ FT_Int w;
- /* read each range */
- if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) ||
- FT_FRAME_ENTER( strike->num_ranges * 8L ) )
- goto Exit;
-
- if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) )
- goto Exit;
-
- range = strike->sbit_ranges;
- while ( count2 > 0 )
+ for ( w = line_bits; w >= 8; w -= 8 )
{
- range->first_glyph = FT_GET_USHORT();
- range->last_glyph = FT_GET_USHORT();
- range->table_offset = table_base + strike->ranges_offset +
- FT_GET_ULONG();
- count2--;
- range++;
+ pwrite[0] = (FT_Byte)( pwrite[0] | *p++ );
+ pwrite += 1;
}
- FT_FRAME_EXIT();
+ if ( w > 0 )
+ pwrite[0] = (FT_Byte)( pwrite[0] | ( *p++ & ( 0xFF00U >> w ) ) );
+ }
+ }
+ else /* x_pos > 0 */
+ {
+ for ( h = height; h > 0; h--, line += pitch )
+ {
+ FT_Byte* pwrite = line;
+ FT_Int w;
+ FT_UInt wval = 0;
+
- /* Now, read each index table */
- count2 = strike->num_ranges;
- range = strike->sbit_ranges;
- while ( count2 > 0 )
+ for ( w = line_bits; w >= 8; w -= 8 )
{
- /* Read the header */
- if ( FT_STREAM_SEEK( range->table_offset ) ||
- FT_FRAME_ENTER( 8L ) )
- goto Exit;
+ wval = (FT_UInt)( wval | *p++ );
+ pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
+ pwrite += 1;
+ wval <<= 8;
+ }
- range->index_format = FT_GET_USHORT();
- range->image_format = FT_GET_USHORT();
- range->image_offset = FT_GET_ULONG();
+ if ( w > 0 )
+ wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
- FT_FRAME_EXIT();
+ /* all bits read and there are `x_pos + w' bits to be written */
- error = Load_SBit_Range( range, stream );
- if ( error )
- goto Exit;
+ pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
- count2--;
- range++;
+ if ( x_pos + w > 8 )
+ {
+ pwrite++;
+ wval <<= 8;
+ pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
}
-
- count--;
- strike++;
}
}
Exit:
+ if ( !error )
+ FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" ));
return error;
}
- /*************************************************************************/
- /* */
- /* <Function> */
- /* tt_face_free_eblc */
- /* */
- /* <Description> */
- /* Releases the embedded bitmap tables. */
- /* */
- /* <Input> */
- /* face :: The target face object. */
- /* */
- FT_LOCAL_DEF( void )
- tt_face_free_eblc( TT_Face face )
+ /*
+ * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
+ * (with pointer `pwrite'). In the example below, the width is 3 pixel,
+ * and `x_pos' is 1 pixel.
+ *
+ * p p+1
+ * | | |
+ * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |...
+ * | | |
+ * +-------+ +-------+ +-------+ ...
+ * . . .
+ * . . .
+ * v . .
+ * +-------+ . .
+ * | | .
+ * | 7 6 5 4 3 2 1 0 | .
+ * | | .
+ * pwrite . .
+ * . .
+ * v .
+ * +-------+ .
+ * | |
+ * | 7 6 5 4 3 2 1 0 |
+ * | |
+ * pwrite+1 .
+ * .
+ * v
+ * +-------+
+ * | |
+ * | 7 6 5 4 3 2 1 0 |
+ * | |
+ * pwrite+2
+ *
+ */
+
+ static FT_Error
+ tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_Byte* p,
+ FT_Byte* limit,
+ FT_Int x_pos,
+ FT_Int y_pos )
{
- FT_Memory memory = face->root.memory;
- TT_SBit_Strike strike = face->sbit_strikes;
- TT_SBit_Strike strike_limit = strike + face->num_sbit_strikes;
+ FT_Error error = FT_Err_Ok;
+ FT_Byte* line;
+ FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits;
+ FT_Bitmap* bitmap;
+ FT_UShort rval;
+ FT_UNUSED( load_flags );
- if ( strike )
- {
- for ( ; strike < strike_limit; strike++ )
- {
- TT_SBit_Range range = strike->sbit_ranges;
- TT_SBit_Range range_limit = range + strike->num_ranges;
+ /* check that we can write the glyph into the bitmap */
+ bitmap = decoder->bitmap;
+ bit_width = bitmap->width;
+ bit_height = bitmap->rows;
+ pitch = bitmap->pitch;
+ line = bitmap->buffer;
- if ( range )
- {
- for ( ; range < range_limit; range++ )
- {
- /* release the glyph offsets and codes tables */
- /* where appropriate */
- FT_FREE( range->glyph_offsets );
- FT_FREE( range->glyph_codes );
- }
- }
- FT_FREE( strike->sbit_ranges );
- strike->num_ranges = 0;
- }
- FT_FREE( face->sbit_strikes );
+ width = decoder->metrics->width;
+ height = decoder->metrics->height;
+
+ line_bits = width * decoder->bit_depth;
+
+ if ( x_pos < 0 || x_pos + width > bit_width ||
+ y_pos < 0 || y_pos + height > bit_height )
+ {
+ FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:"
+ " invalid bitmap dimensions\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
}
- face->num_sbit_strikes = 0;
- }
+ if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit )
+ {
+ FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
- FT_LOCAL_DEF( FT_Error )
- tt_face_set_sbit_strike( TT_Face face,
- FT_Size_Request req,
- FT_ULong* astrike_index )
- {
- return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
- }
+ /* now do the blit */
+ /* adjust `line' to point to the first byte of the bitmap */
+ line += y_pos * pitch + ( x_pos >> 3 );
+ x_pos &= 7;
- FT_LOCAL_DEF( FT_Error )
- tt_face_load_strike_metrics( TT_Face face,
- FT_ULong strike_index,
- FT_Size_Metrics* metrics )
- {
- TT_SBit_Strike strike;
+ /* the higher byte of `rval' is used as a buffer */
+ rval = 0;
+ nbits = 0;
+ for ( h = height; h > 0; h--, line += pitch )
+ {
+ FT_Byte* pwrite = line;
+ FT_Int w = line_bits;
- if ( strike_index >= face->num_sbit_strikes )
- return SFNT_Err_Invalid_Argument;
- strike = face->sbit_strikes + strike_index;
+ /* handle initial byte (in target bitmap) specially if necessary */
+ if ( x_pos )
+ {
+ w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos;
- metrics->x_ppem = strike->x_ppem;
- metrics->y_ppem = strike->y_ppem;
+ if ( h == height )
+ {
+ rval = *p++;
+ nbits = x_pos;
+ }
+ else if ( nbits < w )
+ {
+ if ( p < limit )
+ rval |= *p++;
+ nbits += 8 - w;
+ }
+ else
+ {
+ rval >>= 8;
+ nbits -= w;
+ }
- metrics->ascender = strike->hori.ascender << 6;
- metrics->descender = strike->hori.descender << 6;
+ *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) &
+ ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );
+ rval <<= 8;
- /* XXX: Is this correct? */
- metrics->max_advance = ( strike->hori.min_origin_SB +
- strike->hori.max_width +
- strike->hori.min_advance_SB ) << 6;
+ w = line_bits - w;
+ }
- metrics->height = metrics->ascender - metrics->descender;
+ /* handle medial bytes */
+ for ( ; w >= 8; w -= 8 )
+ {
+ rval |= *p++;
+ *pwrite++ |= ( rval >> nbits ) & 0xFF;
- return SFNT_Err_Ok;
+ rval <<= 8;
+ }
+
+ /* handle final byte if necessary */
+ if ( w > 0 )
+ {
+ if ( nbits < w )
+ {
+ if ( p < limit )
+ rval |= *p++;
+ *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
+ nbits += 8 - w;
+
+ rval <<= 8;
+ }
+ else
+ {
+ *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
+ nbits -= w;
+ }
+ }
+ }
+
+ Exit:
+ if ( !error )
+ FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" ));
+ return error;
}
- /*************************************************************************/
- /* */
- /* <Function> */
- /* find_sbit_range */
- /* */
- /* <Description> */
- /* Scans a given strike's ranges and return, for a given glyph */
- /* index, the corresponding sbit range, and `EBDT' offset. */
- /* */
- /* <Input> */
- /* glyph_index :: The glyph index. */
- /* */
- /* strike :: The source/current sbit strike. */
- /* */
- /* <Output> */
- /* arange :: The sbit range containing the glyph index. */
- /* */
- /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means the glyph index was found. */
- /* */
static FT_Error
- find_sbit_range( FT_UInt glyph_index,
- TT_SBit_Strike strike,
- TT_SBit_Range *arange,
- FT_ULong *aglyph_offset )
+ tt_sbit_decoder_load_compound( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_Byte* p,
+ FT_Byte* limit,
+ FT_Int x_pos,
+ FT_Int y_pos )
{
- TT_SBit_RangeRec *range, *range_limit;
+ FT_Error error = FT_Err_Ok;
+ FT_UInt num_components, nn;
+ FT_Char horiBearingX = decoder->metrics->horiBearingX;
+ FT_Char horiBearingY = decoder->metrics->horiBearingY;
+ FT_Byte horiAdvance = decoder->metrics->horiAdvance;
+ FT_Char vertBearingX = decoder->metrics->vertBearingX;
+ FT_Char vertBearingY = decoder->metrics->vertBearingY;
+ FT_Byte vertAdvance = decoder->metrics->vertAdvance;
- /* check whether the glyph index is within this strike's */
- /* glyph range */
- if ( glyph_index < (FT_UInt)strike->start_glyph ||
- glyph_index > (FT_UInt)strike->end_glyph )
- goto Fail;
- /* scan all ranges in strike */
- range = strike->sbit_ranges;
- range_limit = range + strike->num_ranges;
- if ( !range )
+ if ( p + 2 > limit )
goto Fail;
- for ( ; range < range_limit; range++ )
+ num_components = FT_NEXT_USHORT( p );
+ if ( p + 4 * num_components > limit )
{
- if ( glyph_index >= (FT_UInt)range->first_glyph &&
- glyph_index <= (FT_UInt)range->last_glyph )
- {
- FT_UShort delta = (FT_UShort)( glyph_index - range->first_glyph );
+ FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" ));
+ goto Fail;
+ }
+ FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n",
+ num_components ));
- switch ( range->index_format )
- {
- case 1:
- case 3:
- *aglyph_offset = range->glyph_offsets[delta];
- break;
-
- case 2:
- *aglyph_offset = range->image_offset +
- range->image_size * delta;
- break;
-
- case 4:
- case 5:
- {
- FT_ULong n;
-
-
- for ( n = 0; n < range->num_glyphs; n++ )
- {
- if ( (FT_UInt)range->glyph_codes[n] == glyph_index )
- {
- if ( range->index_format == 4 )
- *aglyph_offset = range->glyph_offsets[n];
- else
- *aglyph_offset = range->image_offset +
- n * range->image_size;
- goto Found;
- }
- }
- }
+ for ( nn = 0; nn < num_components; nn++ )
+ {
+ FT_UInt gindex = FT_NEXT_USHORT( p );
+ FT_Byte dx = FT_NEXT_BYTE( p );
+ FT_Byte dy = FT_NEXT_BYTE( p );
- /* fall-through */
- default:
- goto Fail;
- }
- Found:
- /* return successfully! */
- *arange = range;
- return SFNT_Err_Ok;
- }
+ /* NB: a recursive call */
+ error = tt_sbit_decoder_load_image( decoder, load_flags, gindex,
+ x_pos + dx, y_pos + dy );
+ if ( error )
+ break;
}
- Fail:
- *arange = 0;
- *aglyph_offset = 0;
+ FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" ));
- return SFNT_Err_Invalid_Argument;
- }
+ decoder->metrics->horiBearingX = horiBearingX;
+ decoder->metrics->horiBearingY = horiBearingY;
+ decoder->metrics->horiAdvance = horiAdvance;
+ decoder->metrics->vertBearingX = vertBearingX;
+ decoder->metrics->vertBearingY = vertBearingY;
+ decoder->metrics->vertAdvance = vertAdvance;
+ decoder->metrics->width = (FT_Byte)decoder->bitmap->width;
+ decoder->metrics->height = (FT_Byte)decoder->bitmap->rows;
+ Exit:
+ return error;
- /*************************************************************************/
- /* */
- /* <Function> */
- /* tt_find_sbit_image */
- /* */
- /* <Description> */
- /* Checks whether an embedded bitmap (an `sbit') exists for a given */
- /* glyph, at a given strike. */
- /* */
- /* <Input> */
- /* face :: The target face object. */
- /* */
- /* glyph_index :: The glyph index. */
- /* */
- /* strike_index :: The current strike index. */
- /* */
- /* <Output> */
- /* arange :: The SBit range containing the glyph index. */
- /* */
- /* astrike :: The SBit strike containing the glyph index. */
- /* */
- /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. Returns */
- /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */
- /* glyph. */
- /* */
- FT_LOCAL( FT_Error )
- tt_find_sbit_image( TT_Face face,
- FT_UInt glyph_index,
- FT_ULong strike_index,
- TT_SBit_Range *arange,
- TT_SBit_Strike *astrike,
- FT_ULong *aglyph_offset )
- {
- FT_Error error;
- TT_SBit_Strike strike;
+ Fail:
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
- if ( !face->sbit_strikes ||
- ( face->num_sbit_strikes <= strike_index ) )
- goto Fail;
+#ifdef FT_CONFIG_OPTION_USE_PNG
- strike = &face->sbit_strikes[strike_index];
+ static FT_Error
+ tt_sbit_decoder_load_png( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_Byte* p,
+ FT_Byte* limit,
+ FT_Int x_pos,
+ FT_Int y_pos )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_ULong png_len;
- error = find_sbit_range( glyph_index, strike,
- arange, aglyph_offset );
- if ( error )
- goto Fail;
+ FT_UNUSED( load_flags );
- *astrike = strike;
- return SFNT_Err_Ok;
+ if ( limit - p < 4 )
+ {
+ FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
- Fail:
- /* no embedded bitmap for this glyph in face */
- *arange = 0;
- *astrike = 0;
- *aglyph_offset = 0;
+ png_len = FT_NEXT_ULONG( p );
+ if ( (FT_ULong)( limit - p ) < png_len )
+ {
+ FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+
+ error = Load_SBit_Png( decoder->bitmap,
+ x_pos,
+ y_pos,
+ decoder->bit_depth,
+ decoder->metrics,
+ decoder->stream->memory,
+ p,
+ png_len );
- return SFNT_Err_Invalid_Argument;
+ Exit:
+ if ( !error )
+ FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" ));
+ return error;
}
+#endif /* FT_CONFIG_OPTION_USE_PNG */
- /*************************************************************************/
- /* */
- /* <Function> */
- /* tt_load_sbit_metrics */
- /* */
- /* <Description> */
- /* Gets the big metrics for a given SBit. */
- /* */
- /* <Input> */
- /* stream :: The input stream. */
- /* */
- /* range :: The SBit range containing the glyph. */
- /* */
- /* <Output> */
- /* big_metrics :: A big SBit metrics structure for the glyph. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* The stream cursor must be positioned at the glyph's offset within */
- /* the `EBDT' table before the call. */
- /* */
- /* If the image format uses variable metrics, the stream cursor is */
- /* positioned just after the metrics header in the `EBDT' table on */
- /* function exit. */
- /* */
- FT_LOCAL( FT_Error )
- tt_load_sbit_metrics( FT_Stream stream,
- TT_SBit_Range range,
- TT_SBit_Metrics metrics )
+
+ static FT_Error
+ tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_UInt glyph_format,
+ FT_ULong glyph_start,
+ FT_ULong glyph_size,
+ FT_Int x_pos,
+ FT_Int y_pos )
{
- FT_Error error = SFNT_Err_Ok;
+ FT_Error error;
+ FT_Stream stream = decoder->stream;
+ FT_Byte* p;
+ FT_Byte* p_limit;
+ FT_Byte* data;
- switch ( range->image_format )
+ /* seek into the EBDT table now */
+ if ( glyph_start + glyph_size > decoder->ebdt_size )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
+ FT_FRAME_EXTRACT( glyph_size, data ) )
+ goto Exit;
+
+ p = data;
+ p_limit = p + glyph_size;
+
+ /* read the data, depending on the glyph format */
+ switch ( glyph_format )
{
case 1:
case 2:
case 8:
- /* variable small metrics */
- {
- TT_SBit_SmallMetricsRec smetrics;
-
- static const FT_Frame_Field sbit_small_metrics_fields[] =
- {
-#undef FT_STRUCTURE
-#define FT_STRUCTURE TT_SBit_SmallMetricsRec
-
- FT_FRAME_START( 5 ),
- FT_FRAME_BYTE( height ),
- FT_FRAME_BYTE( width ),
- FT_FRAME_CHAR( bearingX ),
- FT_FRAME_CHAR( bearingY ),
- FT_FRAME_BYTE( advance ),
- FT_FRAME_END
- };
-
-
- /* read small metrics */
- if ( FT_STREAM_READ_FIELDS( sbit_small_metrics_fields, &smetrics ) )
- goto Exit;
-
- /* convert it to a big metrics */
- metrics->height = smetrics.height;
- metrics->width = smetrics.width;
- metrics->horiBearingX = smetrics.bearingX;
- metrics->horiBearingY = smetrics.bearingY;
- metrics->horiAdvance = smetrics.advance;
-
- /* these metrics are made up at a higher level when */
- /* needed. */
- metrics->vertBearingX = 0;
- metrics->vertBearingY = 0;
- metrics->vertAdvance = 0;
- }
+ case 17:
+ error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
break;
case 6:
case 7:
case 9:
- /* variable big metrics */
- if ( FT_STREAM_READ_FIELDS( sbit_metrics_fields, metrics ) )
- goto Exit;
+ case 18:
+ error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
break;
- case 5:
- default: /* constant metrics */
- if ( range->index_format == 2 || range->index_format == 5 )
- *metrics = range->metrics;
- else
- return SFNT_Err_Invalid_File_Format;
- }
-
- Exit:
- return error;
- }
+ default:
+ error = FT_Err_Ok;
+ }
+ if ( error )
+ goto Fail;
- /*************************************************************************/
- /* */
- /* <Function> */
- /* crop_bitmap */
- /* */
- /* <Description> */
- /* Crops a bitmap to its tightest bounding box, and adjusts its */
- /* metrics. */
- /* */
- /* <InOut> */
- /* map :: The bitmap. */
- /* */
- /* metrics :: The corresponding metrics structure. */
- /* */
- static void
- crop_bitmap( FT_Bitmap* map,
- TT_SBit_Metrics metrics )
- {
- /***********************************************************************/
- /* */
- /* In this situation, some bounding boxes of embedded bitmaps are too */
- /* large. We need to crop it to a reasonable size. */
- /* */
- /* --------- */
- /* | | ----- */
- /* | *** | |***| */
- /* | * | | * | */
- /* | * | ------> | * | */
- /* | * | | * | */
- /* | * | | * | */
- /* | *** | |***| */
- /* --------- ----- */
- /* */
- /***********************************************************************/
-
- FT_Int rows, count;
- FT_Long line_len;
- FT_Byte* line;
-
-
- /***********************************************************************/
- /* */
- /* first of all, check the top-most lines of the bitmap, and remove */
- /* them if they're empty. */
- /* */
{
- line = (FT_Byte*)map->buffer;
- rows = map->rows;
- line_len = map->pitch;
+ TT_SBitDecoder_LoadFunc loader;
- for ( count = 0; count < rows; count++ )
+ switch ( glyph_format )
{
- FT_Byte* cur = line;
- FT_Byte* limit = line + line_len;
-
-
- for ( ; cur < limit; cur++ )
- if ( cur[0] )
- goto Found_Top;
+ case 1:
+ case 6:
+ loader = tt_sbit_decoder_load_byte_aligned;
+ break;
- /* the current line was empty - skip to next one */
- line = limit;
- }
+ case 2:
+ case 5:
+ case 7:
+ loader = tt_sbit_decoder_load_bit_aligned;
+ break;
- Found_Top:
- /* check that we have at least one filled line */
- if ( count >= rows )
- goto Empty_Bitmap;
+ case 8:
+ if ( p + 1 > p_limit )
+ goto Fail;
- /* now, crop the empty upper lines */
- if ( count > 0 )
- {
- line = (FT_Byte*)map->buffer;
+ p += 1; /* skip padding */
+ /* fall-through */
- FT_MEM_MOVE( line, line + count * line_len,
- ( rows - count ) * line_len );
+ case 9:
+ loader = tt_sbit_decoder_load_compound;
+ break;
- metrics->height = (FT_Byte)( metrics->height - count );
- metrics->horiBearingY = (FT_Char)( metrics->horiBearingY - count );
- metrics->vertBearingY = (FT_Char)( metrics->vertBearingY - count );
+#ifdef FT_CONFIG_OPTION_USE_PNG
+ case 17: /* small metrics, PNG image data */
+ case 18: /* big metrics, PNG image data */
+ case 19: /* metrics in EBLC, PNG image data */
+ loader = tt_sbit_decoder_load_png;
+ break;
+#endif /* FT_CONFIG_OPTION_USE_PNG */
- map->rows -= count;
- rows -= count;
+ default:
+ error = FT_THROW( Invalid_Table );
+ goto Fail;
}
- }
- /***********************************************************************/
- /* */
- /* second, crop the lower lines */
- /* */
- {
- line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len;
-
- for ( count = 0; count < rows; count++ )
+ if ( !decoder->bitmap_allocated )
{
- FT_Byte* cur = line;
- FT_Byte* limit = line + line_len;
-
-
- for ( ; cur < limit; cur++ )
- if ( cur[0] )
- goto Found_Bottom;
-
- /* the current line was empty - skip to previous one */
- line -= line_len;
+ error = tt_sbit_decoder_alloc_bitmap( decoder, load_flags );
+ if ( error )
+ goto Fail;
}
- Found_Bottom:
- if ( count > 0 )
+ if ( decoder->bit_depth == 32 &&
+ decoder->bitmap->pixel_mode != FT_PIXEL_MODE_BGRA )
{
- metrics->height = (FT_Byte)( metrics->height - count );
- rows -= count;
- map->rows -= count;
- }
- }
-
- /***********************************************************************/
- /* */
- /* third, get rid of the space on the left side of the glyph */
- /* */
- do
- {
- FT_Byte* limit;
-
+ /* Flatten color bitmaps if color was not requested. */
- line = (FT_Byte*)map->buffer;
- limit = line + rows * line_len;
+ FT_Library library = decoder->face->root.glyph->library;
+ FT_Memory memory = decoder->stream->memory;
- for ( ; line < limit; line += line_len )
- if ( line[0] & 0x80 )
- goto Found_Left;
+ FT_Bitmap color, *orig;
- /* shift the whole glyph one pixel to the left */
- line = (FT_Byte*)map->buffer;
- limit = line + rows * line_len;
- for ( ; line < limit; line += line_len )
- {
- FT_Int n, width = map->width;
- FT_Byte old;
- FT_Byte* cur = line;
-
-
- old = (FT_Byte)(cur[0] << 1);
- for ( n = 8; n < width; n += 8 )
+ if ( decoder->bitmap->pixel_mode != FT_PIXEL_MODE_GRAY ||
+ x_pos != 0 || y_pos != 0 )
{
- FT_Byte val;
-
-
- val = cur[1];
- cur[0] = (FT_Byte)( old | ( val >> 7 ) );
- old = (FT_Byte)( val << 1 );
- cur++;
+ /* Shouldn't happen. */
+ error = FT_THROW( Invalid_Table );
+ goto Fail;
}
- cur[0] = old;
- }
- map->width--;
- metrics->horiBearingX++;
- metrics->vertBearingX++;
- metrics->width--;
+ FT_Bitmap_New( &color );
- } while ( map->width > 0 );
+ color.rows = decoder->bitmap->rows;
+ color.width = decoder->bitmap->width;
+ color.pitch = color.width * 4;
+ color.pixel_mode = FT_PIXEL_MODE_BGRA;
- Found_Left:
+ if ( FT_ALLOC( color.buffer, color.rows * color.pitch ) )
+ goto Fail;
- /***********************************************************************/
- /* */
- /* finally, crop the bitmap width to get rid of the space on the right */
- /* side of the glyph. */
- /* */
- do
- {
- FT_Int right = map->width - 1;
- FT_Byte* limit;
- FT_Byte mask;
+ orig = decoder->bitmap;
+ decoder->bitmap = &color;
+ error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos );
- line = (FT_Byte*)map->buffer + ( right >> 3 );
- limit = line + rows * line_len;
- mask = (FT_Byte)( 0x80 >> ( right & 7 ) );
+ decoder->bitmap = orig;
- for ( ; line < limit; line += line_len )
- if ( line[0] & mask )
- goto Found_Right;
+ /* explicitly test against FT_Err_Ok to avoid compiler warnings */
+ /* (we do an assignment within a conditional) */
+ if ( error ||
+ ( error = FT_Bitmap_Convert( library,
+ &color,
+ decoder->bitmap,
+ 1 ) ) != FT_Err_Ok )
+ {
+ FT_Bitmap_Done( library, &color );
+ goto Fail;
+ }
- /* crop the whole glyph to the right */
- map->width--;
- metrics->width--;
+ FT_Bitmap_Done( library, &color );
+ }
- } while ( map->width > 0 );
+ else
+ error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos );
+ }
- Found_Right:
- /* all right, the bitmap was cropped */
- return;
+ Fail:
+ FT_FRAME_RELEASE( data );
- Empty_Bitmap:
- map->width = 0;
- map->rows = 0;
- map->pitch = 0;
- map->pixel_mode = FT_PIXEL_MODE_MONO;
+ Exit:
+ return error;
}
static FT_Error
- Load_SBit_Single( FT_Bitmap* map,
- FT_Int x_offset,
- FT_Int y_offset,
- FT_Int pix_bits,
- FT_UShort image_format,
- TT_SBit_Metrics metrics,
- FT_Stream stream )
+ tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
+ FT_UInt load_flags,
+ FT_UInt glyph_index,
+ FT_Int x_pos,
+ FT_Int y_pos )
{
- FT_Error error;
+ /*
+ * First, we find the correct strike range that applies to this
+ * glyph index.
+ */
+
+ FT_Byte* p = decoder->eblc_base + decoder->strike_index_array;
+ FT_Byte* p_limit = decoder->eblc_limit;
+ FT_ULong num_ranges = decoder->strike_index_count;
+ FT_UInt start, end, index_format, image_format;
+ FT_ULong image_start = 0, image_end = 0, image_offset;
- /* check that the source bitmap fits into the target pixmap */
- if ( x_offset < 0 || x_offset + metrics->width > map->width ||
- y_offset < 0 || y_offset + metrics->height > map->rows )
+ for ( ; num_ranges > 0; num_ranges-- )
{
- error = SFNT_Err_Invalid_Argument;
+ start = FT_NEXT_USHORT( p );
+ end = FT_NEXT_USHORT( p );
- goto Exit;
- }
+ if ( glyph_index >= start && glyph_index <= end )
+ goto FoundRange;
- {
- FT_Int glyph_width = metrics->width;
- FT_Int glyph_height = metrics->height;
- FT_Int glyph_size;
- FT_Int line_bits = pix_bits * glyph_width;
- FT_Bool pad_bytes = 0;
+ p += 4; /* ignore index offset */
+ }
+ goto NoBitmap;
+ FoundRange:
+ image_offset = FT_NEXT_ULONG( p );
- /* compute size of glyph image */
- switch ( image_format )
- {
- case 1: /* byte-padded formats */
- case 6:
- {
- FT_Int line_length;
+ /* overflow check */
+ p = decoder->eblc_base + decoder->strike_index_array;
+ if ( image_offset > (FT_ULong)( p_limit - p ) )
+ goto Failure;
+ p += image_offset;
+ if ( p + 8 > p_limit )
+ goto NoBitmap;
- switch ( pix_bits )
- {
- case 1:
- line_length = ( glyph_width + 7 ) >> 3;
- break;
- case 2:
- line_length = ( glyph_width + 3 ) >> 2;
- break;
- case 4:
- line_length = ( glyph_width + 1 ) >> 1;
- break;
- default:
- line_length = glyph_width;
- }
+ /* now find the glyph's location and extend within the ebdt table */
+ index_format = FT_NEXT_USHORT( p );
+ image_format = FT_NEXT_USHORT( p );
+ image_offset = FT_NEXT_ULONG ( p );
- glyph_size = glyph_height * line_length;
- pad_bytes = 1;
- }
- break;
+ switch ( index_format )
+ {
+ case 1: /* 4-byte offsets relative to `image_offset' */
+ {
+ p += 4 * ( glyph_index - start );
+ if ( p + 8 > p_limit )
+ goto NoBitmap;
- case 2:
- case 5:
- case 7:
- line_bits = glyph_width * pix_bits;
- glyph_size = ( glyph_height * line_bits + 7 ) >> 3;
- break;
+ image_start = FT_NEXT_ULONG( p );
+ image_end = FT_NEXT_ULONG( p );
- default: /* invalid format */
- return SFNT_Err_Invalid_File_Format;
+ if ( image_start == image_end ) /* missing glyph */
+ goto NoBitmap;
}
+ break;
- /* Now read data and draw glyph into target pixmap */
- if ( FT_FRAME_ENTER( glyph_size ) )
- goto Exit;
+ case 2: /* big metrics, constant image size */
+ {
+ FT_ULong image_size;
- /* don't forget to multiply `x_offset' by `map->pix_bits' as */
- /* the sbit blitter doesn't make a difference between pixmap */
- /* depths. */
- blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes,
- x_offset * pix_bits, y_offset, metrics->height );
- FT_FRAME_EXIT();
- }
+ if ( p + 12 > p_limit )
+ goto NoBitmap;
- Exit:
- return error;
- }
+ image_size = FT_NEXT_ULONG( p );
+ if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
+ goto NoBitmap;
- static FT_Error
- Load_SBit_Image( TT_SBit_Strike strike,
- TT_SBit_Range range,
- FT_ULong ebdt_pos,
- FT_ULong glyph_offset,
- FT_GlyphSlot slot,
- FT_Int x_offset,
- FT_Int y_offset,
- FT_Stream stream,
- TT_SBit_Metrics metrics,
- FT_Int depth )
- {
- FT_Memory memory = stream->memory;
- FT_Bitmap* map = &slot->bitmap;
- FT_Error error;
+ image_start = image_size * ( glyph_index - start );
+ image_end = image_start + image_size;
+ }
+ break;
+ case 3: /* 2-byte offsets relative to 'image_offset' */
+ {
+ p += 2 * ( glyph_index - start );
+ if ( p + 4 > p_limit )
+ goto NoBitmap;
- /* place stream at beginning of glyph data and read metrics */
- if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
- goto Exit;
+ image_start = FT_NEXT_USHORT( p );
+ image_end = FT_NEXT_USHORT( p );
- error = tt_load_sbit_metrics( stream, range, metrics );
- if ( error )
- goto Exit;
+ if ( image_start == image_end ) /* missing glyph */
+ goto NoBitmap;
+ }
+ break;
- /* This function is recursive. At the top-level call, we */
- /* compute the dimensions of the higher-level glyph to */
- /* allocate the final pixmap buffer. */
- if ( depth == 0 )
- {
- FT_Long size;
+ case 4: /* sparse glyph array with (glyph,offset) pairs */
+ {
+ FT_ULong mm, num_glyphs;
- map->width = metrics->width;
- map->rows = metrics->height;
+ if ( p + 4 > p_limit )
+ goto NoBitmap;
- switch ( strike->bit_depth )
- {
- case 1:
- map->pixel_mode = FT_PIXEL_MODE_MONO;
- map->pitch = ( map->width + 7 ) >> 3;
- break;
+ num_glyphs = FT_NEXT_ULONG( p );
- case 2:
- map->pixel_mode = FT_PIXEL_MODE_GRAY2;
- map->pitch = ( map->width + 3 ) >> 2;
- break;
+ /* overflow check for p + ( num_glyphs + 1 ) * 4 */
+ if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) )
+ goto NoBitmap;
- case 4:
- map->pixel_mode = FT_PIXEL_MODE_GRAY4;
- map->pitch = ( map->width + 1 ) >> 1;
- break;
+ for ( mm = 0; mm < num_glyphs; mm++ )
+ {
+ FT_UInt gindex = FT_NEXT_USHORT( p );
- case 8:
- map->pixel_mode = FT_PIXEL_MODE_GRAY;
- map->pitch = map->width;
- break;
- default:
- return SFNT_Err_Invalid_File_Format;
- }
+ if ( gindex == glyph_index )
+ {
+ image_start = FT_NEXT_USHORT( p );
+ p += 2;
+ image_end = FT_PEEK_USHORT( p );
+ break;
+ }
+ p += 2;
+ }
- size = map->rows * map->pitch;
+ if ( mm >= num_glyphs )
+ goto NoBitmap;
+ }
+ break;
- /* check that there is no empty image */
- if ( size == 0 )
- goto Exit; /* exit successfully! */
+ case 5: /* constant metrics with sparse glyph codes */
+ case 19:
+ {
+ FT_ULong image_size, mm, num_glyphs;
- error = ft_glyphslot_alloc_bitmap( slot, size );
- if (error)
- goto Exit;
- }
- switch ( range->image_format )
- {
- case 1: /* single sbit image - load it */
- case 2:
- case 5:
- case 6:
- case 7:
- return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
- range->image_format, metrics, stream );
+ if ( p + 16 > p_limit )
+ goto NoBitmap;
- case 8: /* compound format */
- if ( FT_STREAM_SKIP( 1L ) )
- {
- error = SFNT_Err_Invalid_Stream_Skip;
- goto Exit;
- }
- /* fallthrough */
+ image_size = FT_NEXT_ULONG( p );
- case 9:
- break;
+ if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
+ goto NoBitmap;
- default: /* invalid image format */
- return SFNT_Err_Invalid_File_Format;
- }
+ num_glyphs = FT_NEXT_ULONG( p );
- /* All right, we have a compound format. First of all, read */
- /* the array of elements. */
- {
- TT_SBit_Component components = NULL;
- TT_SBit_Component comp;
- FT_UShort num_components, count;
+ /* overflow check for p + 2 * num_glyphs */
+ if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) )
+ goto NoBitmap;
+ for ( mm = 0; mm < num_glyphs; mm++ )
+ {
+ FT_UInt gindex = FT_NEXT_USHORT( p );
- if ( FT_READ_USHORT( num_components ) ||
- FT_NEW_ARRAY( components, num_components ) )
- goto Exit;
- count = num_components;
+ if ( gindex == glyph_index )
+ break;
+ }
- if ( FT_FRAME_ENTER( 4L * num_components ) )
- goto Fail_Memory;
+ if ( mm >= num_glyphs )
+ goto NoBitmap;
- for ( comp = components; count > 0; count--, comp++ )
- {
- comp->glyph_code = FT_GET_USHORT();
- comp->x_offset = FT_GET_CHAR();
- comp->y_offset = FT_GET_CHAR();
+ image_start = image_size * mm;
+ image_end = image_start + image_size;
}
+ break;
- FT_FRAME_EXIT();
+ default:
+ goto NoBitmap;
+ }
- /* Now recursively load each element glyph */
- count = num_components;
- comp = components;
- for ( ; count > 0; count--, comp++ )
- {
- TT_SBit_Range elem_range;
- TT_SBit_MetricsRec elem_metrics;
- FT_ULong elem_offset;
+ if ( image_start > image_end )
+ goto NoBitmap;
+ image_end -= image_start;
+ image_start = image_offset + image_start;
- /* find the range for this element */
- error = find_sbit_range( comp->glyph_code,
- strike,
- &elem_range,
- &elem_offset );
- if ( error )
- goto Fail_Memory;
-
- /* now load the element, recursively */
- error = Load_SBit_Image( strike,
- elem_range,
- ebdt_pos,
- elem_offset,
- slot,
- x_offset + comp->x_offset,
- y_offset + comp->y_offset,
- stream,
- &elem_metrics,
- depth + 1 );
- if ( error )
- goto Fail_Memory;
- }
+ FT_TRACE3(( "tt_sbit_decoder_load_image:"
+ " found sbit (format %d) for glyph index %d\n",
+ image_format, glyph_index ));
- Fail_Memory:
- FT_FREE( components );
- }
+ return tt_sbit_decoder_load_bitmap( decoder,
+ load_flags,
+ image_format,
+ image_start,
+ image_end,
+ x_pos,
+ y_pos );
- Exit:
- return error;
+ Failure:
+ return FT_THROW( Invalid_Table );
+
+ NoBitmap:
+ FT_TRACE4(( "tt_sbit_decoder_load_image:"
+ " no sbit found for glyph index %d\n", glyph_index ));
+
+ return FT_THROW( Invalid_Argument );
}
- /*************************************************************************/
- /* */
- /* <Function> */
- /* tt_face_load_sbit_image */
- /* */
- /* <Description> */
- /* Loads a given glyph sbit image from the font resource. This also */
- /* returns its metrics. */
- /* */
- /* <Input> */
- /* face :: The target face object. */
- /* */
- /* strike_index :: The current strike index. */
- /* */
- /* glyph_index :: The current glyph index. */
- /* */
- /* load_flags :: The glyph load flags (the code checks for the flag */
- /* FT_LOAD_CROP_BITMAP). */
- /* */
- /* stream :: The input stream. */
- /* */
- /* <Output> */
- /* map :: The target pixmap. */
- /* */
- /* metrics :: A big sbit metrics structure for the glyph image. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. Returns an error if no */
- /* glyph sbit exists for the index. */
- /* */
- /* <Note> */
- /* The `map.buffer' field is always freed before the glyph is loaded. */
- /* */
- FT_LOCAL_DEF( FT_Error )
+ FT_LOCAL( FT_Error )
tt_face_load_sbit_image( TT_Face face,
FT_ULong strike_index,
FT_UInt glyph_index,
@@ -1450,59 +1151,27 @@
FT_Bitmap *map,
TT_SBit_MetricsRec *metrics )
{
- FT_Error error;
- FT_ULong ebdt_pos, glyph_offset;
+ TT_SBitDecoderRec decoder[1];
+ FT_Error error;
- TT_SBit_Strike strike;
- TT_SBit_Range range;
+ FT_UNUSED( load_flags );
+ FT_UNUSED( stream );
+ FT_UNUSED( map );
- /* Check whether there is a glyph sbit for the current index */
- error = tt_find_sbit_image( face, glyph_index, strike_index,
- &range, &strike, &glyph_offset );
- if ( error )
- goto Exit;
-
- /* now, find the location of the `EBDT' table in */
- /* the font file */
- error = face->goto_table( face, TTAG_EBDT, stream, 0 );
- if ( error )
- error = face->goto_table( face, TTAG_bdat, stream, 0 );
- if ( error )
- goto Exit;
-
- ebdt_pos = FT_STREAM_POS();
-
- error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
- face->root.glyph, 0, 0, stream, metrics, 0 );
- if ( error )
- goto Exit;
-
- /* setup vertical metrics if needed */
- if ( strike->flags & 1 )
+ error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
+ if ( !error )
{
- /* in case of a horizontal strike only */
- FT_Int advance;
-
-
- advance = strike->hori.ascender - strike->hori.descender;
-
- /* some heuristic values */
-
- metrics->vertBearingX = (FT_Char)(-metrics->width / 2 );
- metrics->vertBearingY = (FT_Char)( ( advance - metrics->height ) / 2 );
- metrics->vertAdvance = (FT_Char)( advance * 12 / 10 );
+ error = tt_sbit_decoder_load_image( decoder,
+ load_flags,
+ glyph_index,
+ 0,
+ 0 );
+ tt_sbit_decoder_done( decoder );
}
- /* Crop the bitmap now, unless specified otherwise */
- if ( load_flags & FT_LOAD_CROP_BITMAP )
- crop_bitmap( map, metrics );
-
- Exit:
return error;
}
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
-/* END */
+/* EOF */
diff --git a/src/sfnt/ttsbit.h b/src/sfnt/ttsbit.h
index 7ea2af1..ea0b5f8 100644
--- a/src/sfnt/ttsbit.h
+++ b/src/sfnt/ttsbit.h
@@ -4,7 +4,7 @@
/* */
/* TrueType and OpenType embedded bitmap support (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */
+/* Copyright 1996-2008, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -45,22 +45,6 @@ FT_BEGIN_HEADER
FT_ULong strike_index,
FT_Size_Metrics* metrics );
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- FT_LOCAL( FT_Error )
- tt_find_sbit_image( TT_Face face,
- FT_UInt glyph_index,
- FT_ULong strike_index,
- TT_SBit_Range *arange,
- TT_SBit_Strike *astrike,
- FT_ULong *aglyph_offset );
-
- FT_LOCAL( FT_Error )
- tt_load_sbit_metrics( FT_Stream stream,
- TT_SBit_Range range,
- TT_SBit_Metrics metrics );
-
-#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
FT_LOCAL( FT_Error )
tt_face_load_sbit_image( TT_Face face,
FT_ULong strike_index,
diff --git a/src/sfnt/ttsbit0.c b/src/sfnt/ttsbit0.c
deleted file mode 100644
index 38bcf21..0000000
--- a/src/sfnt/ttsbit0.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-/***************************************************************************/
-/* */
-/* ttsbit0.c */
-/* */
-/* TrueType and OpenType embedded bitmap support (body). */
-/* This is a heap-optimized version. */
-/* */
-/* Copyright 2005, 2006, 2007, 2008, 2009 by */
-/* David Turner, Robert Wilhelm, and Werner Lemberg. */
-/* */
-/* This file is part of the FreeType project, and may only be used, */
-/* modified, and distributed under the terms of the FreeType project */
-/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
-/* this file you indicate that you have read the license and */
-/* understand and accept it fully. */
-/* */
-/***************************************************************************/
-
-
-/* This file is included by ttsbit.c */
-
-
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
-#include "ttsbit.h"
-
-#include "sferrors.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_ttsbit
-
-
- FT_LOCAL_DEF( FT_Error )
- tt_face_load_eblc( TT_Face face,
- FT_Stream stream )
- {
- FT_Error error = SFNT_Err_Ok;
- FT_Fixed version;
- FT_ULong num_strikes, table_size;
- FT_Byte* p;
- FT_Byte* p_limit;
- FT_UInt count;
-
-
- face->sbit_num_strikes = 0;
-
- /* this table is optional */
- error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
- if ( error )
- error = face->goto_table( face, TTAG_bloc, stream, &table_size );
- if ( error )
- goto Exit;
-
- if ( table_size < 8 )
- {
- FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
- goto Exit;
-
- face->sbit_table_size = table_size;
-
- p = face->sbit_table;
- p_limit = p + table_size;
-
- version = FT_NEXT_ULONG( p );
- num_strikes = FT_NEXT_ULONG( p );
-
- if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
- {
- FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
- error = SFNT_Err_Invalid_File_Format;
- goto Fail;
- }
-
- /*
- * Count the number of strikes available in the table. We are a bit
- * paranoid there and don't trust the data.
- */
- count = (FT_UInt)num_strikes;
- if ( 8 + 48UL * count > table_size )
- count = (FT_UInt)( ( p_limit - p ) / 48 );
-
- face->sbit_num_strikes = count;
-
- FT_TRACE3(( "sbit_num_strikes: %u\n", count ));
- Exit:
- return error;
-
- Fail:
- FT_FRAME_RELEASE( face->sbit_table );
- face->sbit_table_size = 0;
- goto Exit;
- }
-
-
- FT_LOCAL_DEF( void )
- tt_face_free_eblc( TT_Face face )
- {
- FT_Stream stream = face->root.stream;
-
-
- FT_FRAME_RELEASE( face->sbit_table );
- face->sbit_table_size = 0;
- face->sbit_num_strikes = 0;
- }
-
-
- FT_LOCAL_DEF( FT_Error )
- tt_face_set_sbit_strike( TT_Face face,
- FT_Size_Request req,
- FT_ULong* astrike_index )
- {
- return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
- }
-
-
- FT_LOCAL_DEF( FT_Error )
- tt_face_load_strike_metrics( TT_Face face,
- FT_ULong strike_index,
- FT_Size_Metrics* metrics )
- {
- FT_Byte* strike;
-
-
- if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
- return SFNT_Err_Invalid_Argument;
-
- strike = face->sbit_table + 8 + strike_index * 48;
-
- metrics->x_ppem = (FT_UShort)strike[44];
- metrics->y_ppem = (FT_UShort)strike[45];
-
- metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */
- metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */
- metrics->height = metrics->ascender - metrics->descender;
-
- /* XXX: Is this correct? */
- metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */
- strike[18] + /* max_width */
- (FT_Char)strike[23] /* min_advance_SB */
- ) << 6;
-
- return SFNT_Err_Ok;
- }
-
-
- typedef struct TT_SBitDecoderRec_
- {
- TT_Face face;
- FT_Stream stream;
- FT_Bitmap* bitmap;
- TT_SBit_Metrics metrics;
- FT_Bool metrics_loaded;
- FT_Bool bitmap_allocated;
- FT_Byte bit_depth;
-
- FT_ULong ebdt_start;
- FT_ULong ebdt_size;
-
- FT_ULong strike_index_array;
- FT_ULong strike_index_count;
- FT_Byte* eblc_base;
- FT_Byte* eblc_limit;
-
- } TT_SBitDecoderRec, *TT_SBitDecoder;
-
-
- static FT_Error
- tt_sbit_decoder_init( TT_SBitDecoder decoder,
- TT_Face face,
- FT_ULong strike_index,
- TT_SBit_MetricsRec* metrics )
- {
- FT_Error error;
- FT_Stream stream = face->root.stream;
- FT_ULong ebdt_size;
-
-
- error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
- if ( error )
- error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
- if ( error )
- goto Exit;
-
- decoder->face = face;
- decoder->stream = stream;
- decoder->bitmap = &face->root.glyph->bitmap;
- decoder->metrics = metrics;
-
- decoder->metrics_loaded = 0;
- decoder->bitmap_allocated = 0;
-
- decoder->ebdt_start = FT_STREAM_POS();
- decoder->ebdt_size = ebdt_size;
-
- decoder->eblc_base = face->sbit_table;
- decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
-
- /* now find the strike corresponding to the index */
- {
- FT_Byte* p;
-
-
- if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- p = decoder->eblc_base + 8 + 48 * strike_index;
-
- decoder->strike_index_array = FT_NEXT_ULONG( p );
- p += 4;
- decoder->strike_index_count = FT_NEXT_ULONG( p );
- p += 34;
- decoder->bit_depth = *p;
-
- if ( decoder->strike_index_array > face->sbit_table_size ||
- decoder->strike_index_array + 8 * decoder->strike_index_count >
- face->sbit_table_size )
- error = SFNT_Err_Invalid_File_Format;
- }
-
- Exit:
- return error;
- }
-
-
- static void
- tt_sbit_decoder_done( TT_SBitDecoder decoder )
- {
- FT_UNUSED( decoder );
- }
-
-
- static FT_Error
- tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder )
- {
- FT_Error error = SFNT_Err_Ok;
- FT_UInt width, height;
- FT_Bitmap* map = decoder->bitmap;
- FT_Long size;
-
-
- if ( !decoder->metrics_loaded )
- {
- error = SFNT_Err_Invalid_Argument;
- goto Exit;
- }
-
- width = decoder->metrics->width;
- height = decoder->metrics->height;
-
- map->width = (int)width;
- map->rows = (int)height;
-
- switch ( decoder->bit_depth )
- {
- case 1:
- map->pixel_mode = FT_PIXEL_MODE_MONO;
- map->pitch = ( map->width + 7 ) >> 3;
- break;
-
- case 2:
- map->pixel_mode = FT_PIXEL_MODE_GRAY2;
- map->pitch = ( map->width + 3 ) >> 2;
- break;
-
- case 4:
- map->pixel_mode = FT_PIXEL_MODE_GRAY4;
- map->pitch = ( map->width + 1 ) >> 1;
- break;
-
- case 8:
- map->pixel_mode = FT_PIXEL_MODE_GRAY;
- map->pitch = map->width;
- break;
-
- default:
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- size = map->rows * map->pitch;
-
- /* check that there is no empty image */
- if ( size == 0 )
- goto Exit; /* exit successfully! */
-
- error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
- if ( error )
- goto Exit;
-
- decoder->bitmap_allocated = 1;
-
- Exit:
- return error;
- }
-
-
- static FT_Error
- tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder,
- FT_Byte* *pp,
- FT_Byte* limit,
- FT_Bool big )
- {
- FT_Byte* p = *pp;
- TT_SBit_Metrics metrics = decoder->metrics;
-
-
- if ( p + 5 > limit )
- goto Fail;
-
- metrics->height = p[0];
- metrics->width = p[1];
- metrics->horiBearingX = (FT_Char)p[2];
- metrics->horiBearingY = (FT_Char)p[3];
- metrics->horiAdvance = p[4];
-
- p += 5;
- if ( big )
- {
- if ( p + 3 > limit )
- goto Fail;
-
- metrics->vertBearingX = (FT_Char)p[0];
- metrics->vertBearingY = (FT_Char)p[1];
- metrics->vertAdvance = p[2];
-
- p += 3;
- }
-
- decoder->metrics_loaded = 1;
- *pp = p;
- return SFNT_Err_Ok;
-
- Fail:
- return SFNT_Err_Invalid_Argument;
- }
-
-
- /* forward declaration */
- static FT_Error
- tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
- FT_UInt glyph_index,
- FT_Int x_pos,
- FT_Int y_pos );
-
- typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder,
- FT_Byte* p,
- FT_Byte* plimit,
- FT_Int x_pos,
- FT_Int y_pos );
-
-
- static FT_Error
- tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder,
- FT_Byte* p,
- FT_Byte* limit,
- FT_Int x_pos,
- FT_Int y_pos )
- {
- FT_Error error = SFNT_Err_Ok;
- FT_Byte* line;
- FT_Int bit_height, bit_width, pitch, width, height, h;
- FT_Bitmap* bitmap;
-
-
- if ( !decoder->bitmap_allocated )
- {
- error = tt_sbit_decoder_alloc_bitmap( decoder );
- if ( error )
- goto Exit;
- }
-
- /* check that we can write the glyph into the bitmap */
- bitmap = decoder->bitmap;
- bit_width = bitmap->width;
- bit_height = bitmap->rows;
- pitch = bitmap->pitch;
- line = bitmap->buffer;
-
- width = decoder->metrics->width;
- height = decoder->metrics->height;
-
- if ( x_pos < 0 || x_pos + width > bit_width ||
- y_pos < 0 || y_pos + height > bit_height )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- if ( p + ( ( width + 7 ) >> 3 ) * height > limit )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- /* now do the blit */
- line += y_pos * pitch + ( x_pos >> 3 );
- x_pos &= 7;
-
- if ( x_pos == 0 ) /* the easy one */
- {
- for ( h = height; h > 0; h--, line += pitch )
- {
- FT_Byte* write = line;
- FT_Int w;
-
-
- for ( w = width; w >= 8; w -= 8 )
- {
- write[0] = (FT_Byte)( write[0] | *p++ );
- write += 1;
- }
-
- if ( w > 0 )
- write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) );
- }
- }
- else /* x_pos > 0 */
- {
- for ( h = height; h > 0; h--, line += pitch )
- {
- FT_Byte* write = line;
- FT_Int w;
- FT_UInt wval = 0;
-
-
- for ( w = width; w >= 8; w -= 8 )
- {
- wval = (FT_UInt)( wval | *p++ );
- write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
- write += 1;
- wval <<= 8;
- }
-
- if ( w > 0 )
- wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
-
- /* all bits read and there are `x_pos + w' bits to be written */
-
- write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
-
- if ( x_pos + w > 8 )
- {
- write++;
- wval <<= 8;
- write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
- }
- }
- }
-
- Exit:
- return error;
- }
-
-
- /*
- * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
- * (with pointer `write'). In the example below, the width is 3 pixel,
- * and `x_pos' is 1 pixel.
- *
- * p p+1
- * | | |
- * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |...
- * | | |
- * +-------+ +-------+ +-------+ ...
- * . . .
- * . . .
- * v . .
- * +-------+ . .
- * | | .
- * | 7 6 5 4 3 2 1 0 | .
- * | | .
- * write . .
- * . .
- * v .
- * +-------+ .
- * | |
- * | 7 6 5 4 3 2 1 0 |
- * | |
- * write+1 .
- * .
- * v
- * +-------+
- * | |
- * | 7 6 5 4 3 2 1 0 |
- * | |
- * write+2
- *
- */
-
- static FT_Error
- tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder,
- FT_Byte* p,
- FT_Byte* limit,
- FT_Int x_pos,
- FT_Int y_pos )
- {
- FT_Error error = SFNT_Err_Ok;
- FT_Byte* line;
- FT_Int bit_height, bit_width, pitch, width, height, h, nbits;
- FT_Bitmap* bitmap;
- FT_UShort rval;
-
-
- if ( !decoder->bitmap_allocated )
- {
- error = tt_sbit_decoder_alloc_bitmap( decoder );
- if ( error )
- goto Exit;
- }
-
- /* check that we can write the glyph into the bitmap */
- bitmap = decoder->bitmap;
- bit_width = bitmap->width;
- bit_height = bitmap->rows;
- pitch = bitmap->pitch;
- line = bitmap->buffer;
-
- width = decoder->metrics->width;
- height = decoder->metrics->height;
-
- if ( x_pos < 0 || x_pos + width > bit_width ||
- y_pos < 0 || y_pos + height > bit_height )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- if ( p + ( ( width * height + 7 ) >> 3 ) > limit )
- {
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
- /* now do the blit */
-
- /* adjust `line' to point to the first byte of the bitmap */
- line += y_pos * pitch + ( x_pos >> 3 );
- x_pos &= 7;
-
- /* the higher byte of `rval' is used as a buffer */
- rval = 0;
- nbits = 0;
-
- for ( h = height; h > 0; h--, line += pitch )
- {
- FT_Byte* write = line;
- FT_Int w = width;
-
-
- /* handle initial byte (in target bitmap) specially if necessary */
- if ( x_pos )
- {
- w = ( width < 8 - x_pos ) ? width : 8 - x_pos;
-
- if ( h == height )
- {
- rval = *p++;
- nbits = x_pos;
- }
- else if ( nbits < w )
- {
- if ( p < limit )
- rval |= *p++;
- nbits += 8 - w;
- }
- else
- {
- rval >>= 8;
- nbits -= w;
- }
-
- *write++ |= ( ( rval >> nbits ) & 0xFF ) &
- ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );
- rval <<= 8;
-
- w = width - w;
- }
-
- /* handle medial bytes */
- for ( ; w >= 8; w -= 8 )
- {
- rval |= *p++;
- *write++ |= ( rval >> nbits ) & 0xFF;
-
- rval <<= 8;
- }
-
- /* handle final byte if necessary */
- if ( w > 0 )
- {
- if ( nbits < w )
- {
- if ( p < limit )
- rval |= *p++;
- *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
- nbits += 8 - w;
-
- rval <<= 8;
- }
- else
- {
- *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
- nbits -= w;
- }
- }
- }
-
- Exit:
- return error;
- }
-
-
- static FT_Error
- tt_sbit_decoder_load_compound( TT_SBitDecoder decoder,
- FT_Byte* p,
- FT_Byte* limit,
- FT_Int x_pos,
- FT_Int y_pos )
- {
- FT_Error error = SFNT_Err_Ok;
- FT_UInt num_components, nn;
-
- FT_Char horiBearingX = decoder->metrics->horiBearingX;
- FT_Char horiBearingY = decoder->metrics->horiBearingY;
- FT_Byte horiAdvance = decoder->metrics->horiAdvance;
- FT_Char vertBearingX = decoder->metrics->vertBearingX;
- FT_Char vertBearingY = decoder->metrics->vertBearingY;
- FT_Byte vertAdvance = decoder->metrics->vertAdvance;
-
-
- if ( p + 2 > limit )
- goto Fail;
-
- num_components = FT_NEXT_USHORT( p );
- if ( p + 4 * num_components > limit )
- goto Fail;
-
- if ( !decoder->bitmap_allocated )
- {
- error = tt_sbit_decoder_alloc_bitmap( decoder );
- if ( error )
- goto Exit;
- }
-
- for ( nn = 0; nn < num_components; nn++ )
- {
- FT_UInt gindex = FT_NEXT_USHORT( p );
- FT_Byte dx = FT_NEXT_BYTE( p );
- FT_Byte dy = FT_NEXT_BYTE( p );
-
-
- /* NB: a recursive call */
- error = tt_sbit_decoder_load_image( decoder, gindex,
- x_pos + dx, y_pos + dy );
- if ( error )
- break;
- }
-
- decoder->metrics->horiBearingX = horiBearingX;
- decoder->metrics->horiBearingY = horiBearingY;
- decoder->metrics->horiAdvance = horiAdvance;
- decoder->metrics->vertBearingX = vertBearingX;
- decoder->metrics->vertBearingY = vertBearingY;
- decoder->metrics->vertAdvance = vertAdvance;
- decoder->metrics->width = (FT_UInt)decoder->bitmap->width;
- decoder->metrics->height = (FT_UInt)decoder->bitmap->rows;
-
- Exit:
- return error;
-
- Fail:
- error = SFNT_Err_Invalid_File_Format;
- goto Exit;
- }
-
-
- static FT_Error
- tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder,
- FT_UInt glyph_format,
- FT_ULong glyph_start,
- FT_ULong glyph_size,
- FT_Int x_pos,
- FT_Int y_pos )
- {
- FT_Error error;
- FT_Stream stream = decoder->stream;
- FT_Byte* p;
- FT_Byte* p_limit;
- FT_Byte* data;
-
-
- /* seek into the EBDT table now */
- if ( glyph_start + glyph_size > decoder->ebdt_size )
- {
- error = SFNT_Err_Invalid_Argument;
- goto Exit;
- }
-
- if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
- FT_FRAME_EXTRACT( glyph_size, data ) )
- goto Exit;
-
- p = data;
- p_limit = p + glyph_size;
-
- /* read the data, depending on the glyph format */
- switch ( glyph_format )
- {
- case 1:
- case 2:
- case 8:
- error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
- break;
-
- case 6:
- case 7:
- case 9:
- error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
- break;
-
- default:
- error = SFNT_Err_Ok;
- }
-
- if ( error )
- goto Fail;
-
- {
- TT_SBitDecoder_LoadFunc loader;
-
-
- switch ( glyph_format )
- {
- case 1:
- case 6:
- loader = tt_sbit_decoder_load_byte_aligned;
- break;
-
- case 2:
- case 5:
- case 7:
- loader = tt_sbit_decoder_load_bit_aligned;
- break;
-
- case 8:
- if ( p + 1 > p_limit )
- goto Fail;
-
- p += 1; /* skip padding */
- /* fall-through */
-
- case 9:
- loader = tt_sbit_decoder_load_compound;
- break;
-
- default:
- goto Fail;
- }
-
- error = loader( decoder, p, p_limit, x_pos, y_pos );
- }
-
- Fail:
- FT_FRAME_RELEASE( data );
-
- Exit:
- return error;
- }
-
-
- static FT_Error
- tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
- FT_UInt glyph_index,
- FT_Int x_pos,
- FT_Int y_pos )
- {
- /*
- * First, we find the correct strike range that applies to this
- * glyph index.
- */
-
- FT_Byte* p = decoder->eblc_base + decoder->strike_index_array;
- FT_Byte* p_limit = decoder->eblc_limit;
- FT_ULong num_ranges = decoder->strike_index_count;
- FT_UInt start, end, index_format, image_format;
- FT_ULong image_start = 0, image_end = 0, image_offset;
-
-
- for ( ; num_ranges > 0; num_ranges-- )
- {
- start = FT_NEXT_USHORT( p );
- end = FT_NEXT_USHORT( p );
-
- if ( glyph_index >= start && glyph_index <= end )
- goto FoundRange;
-
- p += 4; /* ignore index offset */
- }
- goto NoBitmap;
-
- FoundRange:
- image_offset = FT_NEXT_ULONG( p );
-
- /* overflow check */
- if ( decoder->eblc_base + decoder->strike_index_array + image_offset <
- decoder->eblc_base )
- goto Failure;
-
- p = decoder->eblc_base + decoder->strike_index_array + image_offset;
- if ( p + 8 > p_limit )
- goto NoBitmap;
-
- /* now find the glyph's location and extend within the ebdt table */
- index_format = FT_NEXT_USHORT( p );
- image_format = FT_NEXT_USHORT( p );
- image_offset = FT_NEXT_ULONG ( p );
-
- switch ( index_format )
- {
- case 1: /* 4-byte offsets relative to `image_offset' */
- {
- p += 4 * ( glyph_index - start );
- if ( p + 8 > p_limit )
- goto NoBitmap;
-
- image_start = FT_NEXT_ULONG( p );
- image_end = FT_NEXT_ULONG( p );
-
- if ( image_start == image_end ) /* missing glyph */
- goto NoBitmap;
- }
- break;
-
- case 2: /* big metrics, constant image size */
- {
- FT_ULong image_size;
-
-
- if ( p + 12 > p_limit )
- goto NoBitmap;
-
- image_size = FT_NEXT_ULONG( p );
-
- if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
- goto NoBitmap;
-
- image_start = image_size * ( glyph_index - start );
- image_end = image_start + image_size;
- }
- break;
-
- case 3: /* 2-byte offsets relative to 'image_offset' */
- {
- p += 2 * ( glyph_index - start );
- if ( p + 4 > p_limit )
- goto NoBitmap;
-
- image_start = FT_NEXT_USHORT( p );
- image_end = FT_NEXT_USHORT( p );
-
- if ( image_start == image_end ) /* missing glyph */
- goto NoBitmap;
- }
- break;
-
- case 4: /* sparse glyph array with (glyph,offset) pairs */
- {
- FT_ULong mm, num_glyphs;
-
-
- if ( p + 4 > p_limit )
- goto NoBitmap;
-
- num_glyphs = FT_NEXT_ULONG( p );
-
- /* overflow check */
- if ( p + ( num_glyphs + 1 ) * 4 < p )
- goto Failure;
-
- if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
- goto NoBitmap;
-
- for ( mm = 0; mm < num_glyphs; mm++ )
- {
- FT_UInt gindex = FT_NEXT_USHORT( p );
-
-
- if ( gindex == glyph_index )
- {
- image_start = FT_NEXT_USHORT( p );
- p += 2;
- image_end = FT_PEEK_USHORT( p );
- break;
- }
- p += 2;
- }
-
- if ( mm >= num_glyphs )
- goto NoBitmap;
- }
- break;
-
- case 5: /* constant metrics with sparse glyph codes */
- {
- FT_ULong image_size, mm, num_glyphs;
-
-
- if ( p + 16 > p_limit )
- goto NoBitmap;
-
- image_size = FT_NEXT_ULONG( p );
-
- if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
- goto NoBitmap;
-
- num_glyphs = FT_NEXT_ULONG( p );
-
- /* overflow check */
- if ( p + 2 * num_glyphs < p )
- goto Failure;
-
- if ( p + 2 * num_glyphs > p_limit )
- goto NoBitmap;
-
- for ( mm = 0; mm < num_glyphs; mm++ )
- {
- FT_UInt gindex = FT_NEXT_USHORT( p );
-
-
- if ( gindex == glyph_index )
- break;
- }
-
- if ( mm >= num_glyphs )
- goto NoBitmap;
-
- image_start = image_size * mm;
- image_end = image_start + image_size;
- }
- break;
-
- default:
- goto NoBitmap;
- }
-
- if ( image_start > image_end )
- goto NoBitmap;
-
- image_end -= image_start;
- image_start = image_offset + image_start;
-
- return tt_sbit_decoder_load_bitmap( decoder,
- image_format,
- image_start,
- image_end,
- x_pos,
- y_pos );
-
- Failure:
- return SFNT_Err_Invalid_Table;
-
- NoBitmap:
- return SFNT_Err_Invalid_Argument;
- }
-
-
- FT_LOCAL( FT_Error )
- tt_face_load_sbit_image( TT_Face face,
- FT_ULong strike_index,
- FT_UInt glyph_index,
- FT_UInt load_flags,
- FT_Stream stream,
- FT_Bitmap *map,
- TT_SBit_MetricsRec *metrics )
- {
- TT_SBitDecoderRec decoder[1];
- FT_Error error;
-
- FT_UNUSED( load_flags );
- FT_UNUSED( stream );
- FT_UNUSED( map );
-
-
- error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
- if ( !error )
- {
- error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 );
- tt_sbit_decoder_done( decoder );
- }
-
- return error;
- }
-
-/* EOF */
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 4c0eea5..d2158e7 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -4,7 +4,7 @@
/* */
/* A new `perfect' anti-aliasing renderer (body). */
/* */
-/* Copyright 2000-2003, 2005-2012 by */
+/* Copyright 2000-2003, 2005-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -94,6 +94,11 @@
#ifdef _STANDALONE_
+ /* Auxiliary macros for token concatenation. */
+#define FT_ERR_XCAT( x, y ) x ## y
+#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
+
+
/* define this to dump debugging information */
/* #define FT_DEBUG_LEVEL_TRACE */
@@ -154,6 +159,21 @@ typedef ptrdiff_t FT_PtrDist;
va_end( ap );
}
+
+ /* empty function useful for setting a breakpoint to catch errors */
+ int
+ FT_Throw( int error,
+ int line,
+ const char* file )
+ {
+ FT_UNUSED( error );
+ FT_UNUSED( line );
+ FT_UNUSED( file );
+
+ return 0;
+ }
+
+
/* we don't handle tracing levels in stand-alone mode; */
#ifndef FT_TRACE5
#define FT_TRACE5( varformat ) FT_Message varformat
@@ -165,11 +185,19 @@ typedef ptrdiff_t FT_PtrDist;
#define FT_ERROR( varformat ) FT_Message varformat
#endif
+#define FT_THROW( e ) \
+ ( FT_Throw( FT_ERR_CAT( ErrRaster, e ), \
+ __LINE__, \
+ __FILE__ ) | \
+ FT_ERR_CAT( ErrRaster, e ) )
+
#else /* !FT_DEBUG_LEVEL_TRACE */
#define FT_TRACE5( x ) do { } while ( 0 ) /* nothing */
#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */
#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */
+#define FT_THROW( e ) FT_ERR_CAT( ErrRaster_, e )
+
#endif /* !FT_DEBUG_LEVEL_TRACE */
@@ -202,6 +230,7 @@ typedef ptrdiff_t FT_PtrDist;
raster_done_ \
};
+
#else /* !_STANDALONE_ */
@@ -215,13 +244,14 @@ typedef ptrdiff_t FT_PtrDist;
#include "ftspic.h"
-#define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph
-#define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline
+#define Smooth_Err_Invalid_Mode Smooth_Err_Cannot_Render_Glyph
+#define Smooth_Err_Memory_Overflow Smooth_Err_Out_Of_Memory
#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory
-#define ErrRaster_Invalid_Argument Smooth_Err_Invalid_Argument
+
#endif /* !_STANDALONE_ */
+
#ifndef FT_MEM_SET
#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c )
#endif
@@ -312,7 +342,7 @@ typedef ptrdiff_t FT_PtrDist;
#endif /* PIXEL_BITS >= 8 */
- /* maximal number of gray spans in a call to the span callback */
+ /* maximum number of gray spans in a call to the span callback */
#define FT_MAX_GRAY_SPANS 32
@@ -600,7 +630,7 @@ typedef ptrdiff_t FT_PtrDist;
TPos x2,
TCoord y2 )
{
- TCoord ex1, ex2, fx1, fx2, delta, mod, lift, rem;
+ TCoord ex1, ex2, fx1, fx2, delta, mod;
long p, first, dx;
int incr;
@@ -661,6 +691,9 @@ typedef ptrdiff_t FT_PtrDist;
if ( ex1 != ex2 )
{
+ TCoord lift, rem;
+
+
p = ONE_PIXEL * ( y2 - y1 + delta );
lift = (TCoord)( p / dx );
rem = (TCoord)( p % dx );
@@ -1091,11 +1124,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. */
@@ -1227,9 +1260,7 @@ typedef ptrdiff_t FT_PtrDist;
TPos area,
TCoord acount )
{
- FT_Span* span;
- int count;
- int coverage;
+ int coverage;
/* compute the coverage line's coverage, depending on the */
@@ -1271,6 +1302,10 @@ typedef ptrdiff_t FT_PtrDist;
if ( coverage )
{
+ FT_Span* span;
+ int count;
+
+
/* see whether we can add this span to the current list */
count = ras.num_gray_spans;
span = ras.gray_spans + count - 1;
@@ -1400,7 +1435,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 */
+
}
@@ -1467,7 +1521,7 @@ typedef ptrdiff_t FT_PtrDist;
if ( !outline || !func_interface )
- return ErrRaster_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
shift = func_interface->shift;
delta = func_interface->delta;
@@ -1680,7 +1734,7 @@ typedef ptrdiff_t FT_PtrDist;
return error;
Invalid_Outline:
- return ErrRaster_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
}
#endif /* _STANDALONE_ */
@@ -1718,7 +1772,7 @@ typedef ptrdiff_t FT_PtrDist;
gray_record_cell( RAS_VAR );
}
else
- error = ErrRaster_Memory_Overflow;
+ error = FT_THROW( Memory_Overflow );
return error;
}
@@ -1871,21 +1925,21 @@ typedef ptrdiff_t FT_PtrDist;
if ( !raster || !raster->buffer || !raster->buffer_size )
- return ErrRaster_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( !outline )
- return ErrRaster_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
/* return immediately if the outline is empty */
if ( outline->n_points == 0 || outline->n_contours <= 0 )
return 0;
if ( !outline->contours || !outline->points )
- return ErrRaster_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
if ( outline->n_points !=
outline->contours[outline->n_contours - 1] + 1 )
- return ErrRaster_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
worker = raster->worker;
@@ -1893,19 +1947,19 @@ typedef ptrdiff_t FT_PtrDist;
if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
{
if ( !target_map )
- return ErrRaster_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* nothing to do */
if ( !target_map->width || !target_map->rows )
return 0;
if ( !target_map->buffer )
- return ErrRaster_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
/* this version does not support monochrome rendering */
if ( !( params->flags & FT_RASTER_FLAG_AA ) )
- return ErrRaster_Invalid_Mode;
+ return FT_THROW( Invalid_Mode );
/* compute clipping box */
if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c
index 00499cc..89088cd 100644
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -4,7 +4,7 @@
/* */
/* Anti-aliasing renderer interface (body). */
/* */
-/* Copyright 2000-2006, 2009-2012 by */
+/* Copyright 2000-2006, 2009-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -61,12 +61,12 @@
const FT_Matrix* matrix,
const FT_Vector* delta )
{
- FT_Error error = Smooth_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( slot->format != render->glyph_format )
{
- error = Smooth_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -109,31 +109,43 @@
#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
FT_Pos height_org, width_org;
#endif
- FT_Bitmap* bitmap;
- FT_Memory memory;
- FT_Int hmul = mode == FT_RENDER_MODE_LCD;
- FT_Int vmul = mode == FT_RENDER_MODE_LCD_V;
- FT_Pos x_shift, y_shift, x_left, y_top;
+ FT_Bitmap* bitmap = &slot->bitmap;
+ FT_Memory memory = render->root.memory;
+ FT_Int hmul = mode == FT_RENDER_MODE_LCD;
+ FT_Int vmul = mode == FT_RENDER_MODE_LCD_V;
+ FT_Pos x_shift = 0;
+ FT_Pos y_shift = 0;
+ FT_Pos x_left, y_top;
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 )
{
- error = Smooth_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
/* check mode */
if ( mode != required_mode )
- return Smooth_Err_Cannot_Render_Glyph;
+ {
+ error = FT_THROW( 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 );
@@ -148,24 +160,23 @@
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 = FT_THROW( 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 = FT_THROW( Raster_Overflow );
+ goto Exit;
}
else
height = ( cbox.yMax - cbox.yMin ) >> 6;
- bitmap = &slot->bitmap;
- memory = render->root.memory;
-
#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
width_org = width;
height_org = height;
@@ -221,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 = FT_THROW( Raster_Overflow );
+ goto Exit;
}
#endif
@@ -240,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;
@@ -288,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 );
@@ -295,6 +313,8 @@
/* render outline into bitmap */
error = render->raster_render( render->raster, &params );
+ if ( error )
+ goto Exit;
/* expand it horizontally */
if ( hmul )
@@ -346,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 = FT_THROW( 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 = FT_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/src/smooth/ftspic.c b/src/smooth/ftspic.c
index 601bcf9..67a2b83 100644
--- a/src/smooth/ftspic.c
+++ b/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, 2013 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -22,17 +22,19 @@
#include "ftspic.h"
#include "ftsmerrs.h"
+
#ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from ftgrays.c */
void
FT_Init_Class_ft_grays_raster( FT_Raster_Funcs* funcs );
+
void
ft_smooth_renderer_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->smooth )
@@ -42,6 +44,7 @@
if ( --container->ref_count )
return;
+
FT_FREE( container );
pic_container->smooth = NULL;
}
@@ -52,8 +55,8 @@
ft_smooth_renderer_class_pic_init( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Error error = Smooth_Err_Ok;
- SmoothPIC* container;
+ FT_Error error = FT_Err_Ok;
+ SmoothPIC* container = NULL;
FT_Memory memory = library->memory;
@@ -66,37 +69,45 @@
}
/* allocate pointer, clear and set global container pointer */
- if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+ if ( FT_ALLOC( container, sizeof ( *container ) ) )
return error;
FT_MEM_SET( container, 0, sizeof ( *container ) );
pic_container->smooth = container;
+
container->ref_count = 1;
- /* 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_grays_raster( &container->ft_grays_raster );
-/*Exit:*/
- if ( error )
- ft_smooth_renderer_class_pic_free( library );
+
return error;
}
+
/* re-route these init and free functions to the above functions */
- FT_Error ft_smooth_lcd_renderer_class_pic_init( FT_Library library )
+ FT_Error
+ ft_smooth_lcd_renderer_class_pic_init( FT_Library library )
{
return ft_smooth_renderer_class_pic_init( library );
}
- void ft_smooth_lcd_renderer_class_pic_free( FT_Library library )
+
+ void
+ ft_smooth_lcd_renderer_class_pic_free( FT_Library library )
{
ft_smooth_renderer_class_pic_free( library );
}
- FT_Error ft_smooth_lcdv_renderer_class_pic_init( FT_Library library )
+
+ FT_Error
+ ft_smooth_lcdv_renderer_class_pic_init( FT_Library library )
{
return ft_smooth_renderer_class_pic_init( library );
}
- void ft_smooth_lcdv_renderer_class_pic_free( FT_Library library )
+
+ void
+ ft_smooth_lcdv_renderer_class_pic_free( FT_Library library )
{
ft_smooth_renderer_class_pic_free( library );
}
diff --git a/src/smooth/ftspic.h b/src/smooth/ftspic.h
index 4686f5e..334b51c 100644
--- a/src/smooth/ftspic.h
+++ b/src/smooth/ftspic.h
@@ -25,18 +25,23 @@ FT_BEGIN_HEADER
#include FT_INTERNAL_PIC_H
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_GRAYS_RASTER_GET ft_grays_raster
+
+#define FT_GRAYS_RASTER_GET ft_grays_raster
#else /* FT_CONFIG_OPTION_PIC */
- typedef struct SmoothPIC_
+ typedef struct SmoothPIC_
{
- int ref_count;
- FT_Raster_Funcs ft_grays_raster;
+ int ref_count;
+ FT_Raster_Funcs ft_grays_raster;
+
} SmoothPIC;
-#define GET_PIC(lib) ((SmoothPIC*)((lib)->pic_container.smooth))
-#define FT_GRAYS_RASTER_GET (GET_PIC(library)->ft_grays_raster)
+
+#define GET_PIC( lib ) \
+ ( (SmoothPIC*)( (lib)->pic_container.smooth ) )
+#define FT_GRAYS_RASTER_GET ( GET_PIC( library )->ft_grays_raster )
+
/* see ftspic.c for the implementation */
void
diff --git a/src/truetype/truetype.c b/src/truetype/truetype.c
index 4bd1209..576912b 100644
--- a/src/truetype/truetype.c
+++ b/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/src/truetype/ttdriver.c b/src/truetype/ttdriver.c
index 3669d45..fb25706 100644
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -4,7 +4,7 @@
/* */
/* TrueType font driver implementation (body). */
/* */
-/* Copyright 1996-2012 by */
+/* Copyright 1996-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -29,6 +29,8 @@
#include FT_SERVICE_TRUETYPE_ENGINE_H
#include FT_SERVICE_TRUETYPE_GLYF_H
+#include FT_SERVICE_PROPERTIES_H
+#include FT_TRUETYPE_DRIVER_H
#include "ttdriver.h"
#include "ttgload.h"
@@ -52,6 +54,73 @@
#define FT_COMPONENT trace_ttdriver
+ /*
+ * PROPERTY SERVICE
+ *
+ */
+ static FT_Error
+ tt_property_set( FT_Module module, /* TT_Driver */
+ const char* property_name,
+ const void* value )
+ {
+ FT_Error error = FT_Err_Ok;
+ TT_Driver driver = (TT_Driver)module;
+
+
+ if ( !ft_strcmp( property_name, "interpreter-version" ) )
+ {
+ FT_UInt* interpreter_version = (FT_UInt*)value;
+
+
+#ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( *interpreter_version != TT_INTERPRETER_VERSION_35 )
+ error = FT_ERR( Unimplemented_Feature );
+ else
+#endif
+ driver->interpreter_version = *interpreter_version;
+
+ return error;
+ }
+
+ FT_TRACE0(( "tt_property_set: missing property `%s'\n",
+ property_name ));
+ return FT_THROW( Missing_Property );
+ }
+
+
+ static FT_Error
+ tt_property_get( FT_Module module, /* TT_Driver */
+ const char* property_name,
+ const void* value )
+ {
+ FT_Error error = FT_Err_Ok;
+ TT_Driver driver = (TT_Driver)module;
+
+ FT_UInt interpreter_version = driver->interpreter_version;
+
+
+ if ( !ft_strcmp( property_name, "interpreter-version" ) )
+ {
+ FT_UInt* val = (FT_UInt*)value;
+
+
+ *val = interpreter_version;
+
+ return error;
+ }
+
+ FT_TRACE0(( "tt_property_get: missing property `%s'\n",
+ property_name ));
+ return FT_THROW( Missing_Property );
+ }
+
+
+ FT_DEFINE_SERVICE_PROPERTIESREC(
+ tt_service_properties,
+ (FT_Properties_SetFunc)tt_property_set,
+ (FT_Properties_GetFunc)tt_property_get )
+
+
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
@@ -163,7 +232,7 @@
}
}
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
/*************************************************************************/
@@ -187,7 +256,7 @@
{
TT_Face ttface = (TT_Face)size->face;
TT_Size ttsize = (TT_Size)size;
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
ttsize->strike_index = strike_index;
@@ -221,7 +290,7 @@
FT_Size_Request req )
{
TT_Size ttsize = (TT_Size)size;
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
@@ -294,13 +363,13 @@
if ( !slot )
- return TT_Err_Invalid_Slot_Handle;
+ return FT_THROW( Invalid_Slot_Handle );
if ( !size )
- return TT_Err_Invalid_Size_Handle;
+ return FT_THROW( Invalid_Size_Handle );
if ( !face )
- return TT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
if ( glyph_index >= (FT_UInt)face->num_glyphs &&
@@ -308,7 +377,7 @@
#else
if ( glyph_index >= (FT_UInt)face->num_glyphs )
#endif
- return TT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( load_flags & FT_LOAD_NO_HINTING )
{
@@ -353,13 +422,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 +448,28 @@
#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_SERVICEDESCREC5(
+ 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,
+ FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET )
#else
- FT_DEFINE_SERVICEDESCREC3(tt_services,
+ FT_DEFINE_SERVICEDESCREC4(
+ 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,
+ FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET )
#endif
+
FT_CALLBACK_DEF( FT_Module_Interface )
tt_get_interface( FT_Module driver, /* TT_Driver */
const char* tt_interface )
@@ -408,7 +480,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 +489,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,18 +517,19 @@
/* 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,
+ FT_DEFINE_DRIVER(
+ tt_driver_class,
FT_MODULE_FONT_DRIVER |
FT_MODULE_DRIVER_SCALABLE |
@@ -485,9 +558,6 @@
tt_slot_init,
0, /* FT_Slot_DoneFunc */
- ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
-
tt_glyph_load,
tt_get_kerning,
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index ce8c888..f640a6c 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -4,7 +4,7 @@
/* */
/* TrueType Glyph Loader (body). */
/* */
-/* Copyright 1996-2012 */
+/* Copyright 1996-2013 */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -23,6 +23,7 @@
#include FT_INTERNAL_SFNT_H
#include FT_TRUETYPE_TAGS_H
#include FT_OUTLINE_H
+#include FT_TRUETYPE_DRIVER_H
#include "ttgload.h"
#include "ttpload.h"
@@ -32,6 +33,7 @@
#endif
#include "tterrors.h"
+#include "ttsubpix.h"
/*************************************************************************/
@@ -131,7 +133,10 @@
tt_get_metrics( TT_Loader loader,
FT_UInt glyph_index )
{
- TT_Face face = (TT_Face)loader->face;
+ TT_Face face = (TT_Face)loader->face;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
+#endif
FT_Short left_bearing = 0, top_bearing = 0;
FT_UShort advance_width = 0, advance_height = 0;
@@ -149,6 +154,18 @@
loader->top_bearing = top_bearing;
loader->vadvance = advance_height;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
+ {
+ 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 +269,6 @@
}
-#undef IS_HINTED
-#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 )
-
-
/*************************************************************************/
/* */
/* The following functions are used by default with TrueType fonts. */
@@ -286,7 +299,7 @@
loader->cursor = stream->cursor;
loader->limit = stream->limit;
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -308,7 +321,7 @@
if ( p + 10 > limit )
- return TT_Err_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
loader->n_contours = FT_NEXT_SHORT( p );
@@ -324,7 +337,7 @@
loader->bbox.yMax ));
loader->cursor = p;
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -409,14 +422,14 @@
{
FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n",
n_ins ));
- error = TT_Err_Too_Many_Hints;
+ error = FT_THROW( Too_Many_Hints );
goto Fail;
}
if ( ( limit - p ) < n_ins )
{
FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
- error = TT_Err_Too_Many_Hints;
+ error = FT_THROW( Too_Many_Hints );
goto Fail;
}
@@ -546,7 +559,7 @@
return error;
Invalid_Outline:
- error = TT_Err_Invalid_Outline;
+ error = FT_THROW( Invalid_Outline );
goto Fail;
}
@@ -667,7 +680,7 @@
return error;
Invalid_Composite:
- error = TT_Err_Invalid_Composite;
+ error = FT_THROW( Invalid_Composite );
goto Fail;
}
@@ -714,6 +727,11 @@
TT_Hint_Glyph( TT_Loader loader,
FT_Bool is_composite )
{
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ TT_Face face = (TT_Face)loader->face;
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
+#endif
+
TT_GlyphZone zone = &loader->zone;
FT_Pos origin;
@@ -813,7 +831,18 @@
loader->pp4 = zone->cur[zone->n_points - 1];
}
- return TT_Err_Ok;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
+ {
+ 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 /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+ return FT_Err_Ok;
}
@@ -831,7 +860,7 @@
TT_Process_Simple_Glyph( TT_Loader loader )
{
FT_GlyphLoader gloader = loader->gloader;
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Outline* outline;
FT_Int n_points;
@@ -889,25 +918,83 @@
loader->zone.n_points + 4 );
}
- /* scale the glyph */
- if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
{
- FT_Vector* vec = outline->points;
- 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;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ TT_Face face = (TT_Face)loader->face;
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( 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
+
+ FT_Vector* vec = outline->points;
+ FT_Vector* limit = outline->points + n_points;
+
+ FT_Fixed x_scale = 0; /* pacify compiler */
+ FT_Fixed y_scale = 0;
+
+ FT_Bool do_scale = FALSE;
- for ( ; vec < limit; vec++ )
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
- vec->x = FT_MulFix( vec->x, x_scale );
- vec->y = FT_MulFix( vec->y, y_scale );
+ /* scale, but only if enabled and only if TT hinting is being used */
+ if ( IS_HINTED( loader->load_flags ) )
+ x_scale_factor = sph_test_tweak_x_scaling( face,
+ family,
+ ppem,
+ style,
+ loader->glyph_index );
+ /* scale the glyph */
+ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
+ x_scale_factor != 1000 )
+ {
+ x_scale = FT_MulDiv( ((TT_Size)loader->size)->metrics.x_scale,
+ x_scale_factor, 1000 );
+ 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 );
+ do_scale = TRUE;
+ }
}
+ else
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- loader->pp1 = outline->points[n_points - 4];
- loader->pp2 = outline->points[n_points - 3];
- loader->pp3 = outline->points[n_points - 2];
- loader->pp4 = outline->points[n_points - 1];
+ {
+ /* scale the glyph */
+ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
+ {
+ x_scale = ((TT_Size)loader->size)->metrics.x_scale;
+ y_scale = ((TT_Size)loader->size)->metrics.y_scale;
+
+ do_scale = TRUE;
+ }
+ }
+
+ if ( do_scale )
+ {
+ for ( ; vec < limit; vec++ )
+ {
+ vec->x = FT_MulFix( vec->x, x_scale );
+ vec->y = FT_MulFix( vec->y, y_scale );
+ }
+
+ loader->pp1 = outline->points[n_points - 4];
+ loader->pp2 = outline->points[n_points - 3];
+ loader->pp3 = outline->points[n_points - 2];
+ loader->pp4 = outline->points[n_points - 1];
+ }
}
if ( IS_HINTED( loader->load_flags ) )
@@ -974,7 +1061,7 @@
l += num_base_points;
if ( k >= num_base_points ||
l >= num_points )
- return TT_Err_Invalid_Composite;
+ return FT_THROW( Invalid_Composite );
p1 = gloader->base.outline.points + k;
p2 = gloader->base.outline.points + l;
@@ -988,7 +1075,7 @@
y = subglyph->arg2;
if ( !x && !y )
- return TT_Err_Ok;
+ return FT_Err_Ok;
/* Use a default value dependent on */
/* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */
@@ -1033,16 +1120,10 @@
/* */
/* This algorithm is a guess and works much better than the above. */
/* */
- FT_Fixed mac_xscale = FT_SqrtFixed(
- (FT_Int32)FT_MulFix( subglyph->transform.xx,
- subglyph->transform.xx ) +
- (FT_Int32)FT_MulFix( subglyph->transform.xy,
- subglyph->transform.xy ) );
- FT_Fixed mac_yscale = FT_SqrtFixed(
- (FT_Int32)FT_MulFix( subglyph->transform.yy,
- subglyph->transform.yy ) +
- (FT_Int32)FT_MulFix( subglyph->transform.yx,
- subglyph->transform.yx ) );
+ FT_Fixed mac_xscale = FT_Hypot( subglyph->transform.xx,
+ subglyph->transform.xy );
+ FT_Fixed mac_yscale = FT_Hypot( subglyph->transform.yy,
+ subglyph->transform.yx );
x = FT_MulFix( x, mac_xscale );
@@ -1074,7 +1155,7 @@
base_vec + num_base_points,
x, y );
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -1143,7 +1224,7 @@
FT_TRACE1(( "TT_Process_Composite_Glyph: "
"too many instructions (%d) for glyph with length %d\n",
n_ins, loader->byte_len ));
- return TT_Err_Too_Many_Hints;
+ return FT_THROW( Too_Many_Hints );
}
tmp = loader->exec->glyphSize;
@@ -1157,7 +1238,7 @@
return error;
}
else if ( n_ins == 0 )
- return TT_Err_Ok;
+ return FT_Err_Ok;
if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
return error;
@@ -1213,7 +1294,7 @@
FT_UInt recurse_count,
FT_Bool header_only )
{
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Fixed x_scale, y_scale;
FT_ULong offset;
TT_Face face = (TT_Face)loader->face;
@@ -1236,14 +1317,14 @@
if ( recurse_count > 1 &&
recurse_count > face->max_profile.maxComponentDepth )
{
- error = TT_Err_Invalid_Composite;
+ error = FT_THROW( Invalid_Composite );
goto Exit;
}
/* check glyph index */
if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
{
- error = TT_Err_Invalid_Glyph_Index;
+ error = FT_THROW( Invalid_Glyph_Index );
goto Exit;
}
@@ -1307,7 +1388,7 @@
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
{
FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" ));
- error = TT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -1374,7 +1455,7 @@
loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
}
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
}
@@ -1588,7 +1669,7 @@
else
{
/* invalid composite count (negative but not -1) */
- error = TT_Err_Invalid_Outline;
+ error = FT_THROW( Invalid_Outline );
goto Exit;
}
@@ -1618,11 +1699,15 @@
compute_glyph_metrics( TT_Loader loader,
FT_UInt glyph_index )
{
+ TT_Face face = (TT_Face)loader->face;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
+#endif
+
FT_BBox bbox;
- TT_Face face = (TT_Face)loader->face;
FT_Fixed y_scale;
TT_GlyphSlot glyph = loader->glyph;
- TT_Size size = (TT_Size)loader->size;
+ TT_Size size = (TT_Size)loader->size;
y_scale = 0x10000L;
@@ -1653,8 +1738,30 @@
size->root.metrics.x_ppem,
glyph_index );
- if ( widthp )
- glyph->metrics.horiAdvance = *widthp << 6;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
+ {
+ FT_Bool ignore_x_mode;
+
+
+ ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) !=
+ FT_RENDER_MODE_MONO );
+
+ if ( widthp &&
+ ( ( ignore_x_mode && loader->exec->compatible_widths ) ||
+ !ignore_x_mode ||
+ SPH_OPTION_BITMAP_WIDTHS ) )
+ glyph->metrics.horiAdvance = *widthp << 6;
+ }
+ else
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+ {
+ if ( widthp )
+ glyph->metrics.horiAdvance = *widthp << 6;
+ }
}
/* set glyph dimensions */
@@ -1833,7 +1940,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;
@@ -1849,6 +1958,23 @@
TT_ExecContext exec;
FT_Bool grayscale;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
+
+ FT_Bool subpixel_hinting = FALSE;
+ FT_Bool grayscale_hinting = TRUE;
+
+#if 0
+ /* not used yet */
+ FT_Bool compatible_widths;
+ FT_Bool symmetrical_smoothing;
+ FT_Bool bgr;
+ FT_Bool subpixel_positioned;
+#endif
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+ FT_Bool reexecute = FALSE;
+
if ( !size->cvt_ready )
{
@@ -1863,24 +1989,113 @@
exec = size->debug ? size->context
: ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
if ( !exec )
- return TT_Err_Could_Not_Find_Context;
+ return FT_THROW( Could_Not_Find_Context );
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
+ {
+ 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;
+ }
+ else
+ grayscale = grayscale_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 = TT_INTERPRETER_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
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- grayscale =
- FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO );
+ {
+ grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
+ FT_RENDER_MODE_MONO );
+ }
TT_Load_Context( exec, face, size );
- /* a change from mono to grayscale rendering (and vice versa) */
- /* requires a re-execution of the CVT program */
- if ( grayscale != exec->grayscale )
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
- FT_UInt i;
+ /* 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_TRACE4(( "tt_loader_init: subpixel hinting change,"
+ " re-executing `prep' table\n" ));
+
+ exec->subpixel_hinting = subpixel_hinting;
+ reexecute = TRUE;
+ }
+
+ /* a change from mono to grayscale rendering (and vice versa) */
+ /* requires a re-execution of the CVT program */
+ if ( grayscale != exec->grayscale_hinting )
+ {
+ FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
+ " re-executing `prep' table\n" ));
+
+ exec->grayscale_hinting = grayscale_hinting;
+ reexecute = TRUE;
+ }
+ }
+ else
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- FT_TRACE4(( "tt_loader_init: grayscale change,"
- " re-executing `prep' table\n" ));
+ {
+ /* a change from mono to grayscale rendering (and vice versa) */
+ /* requires a re-execution of the CVT program */
+ if ( grayscale != exec->grayscale )
+ {
+ FT_TRACE4(( "tt_loader_init: grayscale change,"
+ " re-executing `prep' table\n" ));
+
+ exec->grayscale = grayscale;
+ reexecute = TRUE;
+ }
+ }
+
+ if ( reexecute )
+ {
+ FT_UInt i;
- exec->grayscale = grayscale;
for ( i = 0; i < size->cvt_size; i++ )
size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
@@ -1918,7 +2133,7 @@
FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 );
- if ( error == TT_Err_Table_Missing )
+ if ( FT_ERR_EQ( error, Table_Missing ) )
loader->glyf_offset = 0;
else if ( error )
{
@@ -1946,7 +2161,7 @@
loader->glyph = (FT_GlyphSlot)glyph;
loader->stream = stream;
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -1983,13 +2198,11 @@
FT_UInt glyph_index,
FT_Int32 load_flags )
{
- TT_Face face;
FT_Error error;
TT_LoaderRec loader;
- face = (TT_Face)glyph->face;
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
@@ -2003,10 +2216,7 @@
error = load_sbit_image( size, glyph, glyph_index, load_flags );
if ( !error )
{
- FT_Face root = &face->root;
-
-
- if ( FT_IS_SCALABLE( root ) )
+ if ( FT_IS_SCALABLE( glyph->face ) )
{
/* for the bbox we need the header only */
(void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
@@ -2014,9 +2224,16 @@
glyph->linearHoriAdvance = loader.linear;
glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax -
loader.vadvance;
+
+ /* sanity check: if `horiAdvance' in the sbit metric */
+ /* structure isn't set, use `linearHoriAdvance' */
+ if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
+ glyph->metrics.horiAdvance =
+ FT_MulFix( glyph->linearHoriAdvance,
+ size->root.metrics.x_scale );
}
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
}
@@ -2024,10 +2241,10 @@
/* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )
- return TT_Err_Invalid_Size_Handle;
+ return FT_THROW( Invalid_Size_Handle );
if ( load_flags & FT_LOAD_SBITS_ONLY )
- return TT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
if ( error )
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 69b702f..7899d36 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -4,7 +4,7 @@
/* */
/* TrueType GX Font Variation loader */
/* */
-/* Copyright 2004-2011 by */
+/* Copyright 2004-2013 by */
/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -61,9 +61,9 @@
#define FT_Stream_FTell( stream ) \
- ( (stream)->cursor - (stream)->base )
+ (FT_ULong)( (stream)->cursor - (stream)->base )
#define FT_Stream_SeekSet( stream, off ) \
- ( (stream)->cursor = (stream)->base+(off) )
+ ( (stream)->cursor = (stream)->base + (off) )
/*************************************************************************/
@@ -91,7 +91,9 @@
/* indicates that there is a delta for every point without needing to */
/* enumerate all of them. */
/* */
-#define ALL_POINTS (FT_UShort*)( -1 )
+
+ /* ensure that value `0' has the same width as a pointer */
+#define ALL_POINTS (FT_UShort*)~(FT_PtrDist)0
#define GX_PT_POINTS_ARE_WORDS 0x80
@@ -130,7 +132,7 @@
FT_Int j;
FT_Int first;
FT_Memory memory = stream->memory;
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UNUSED( error );
@@ -215,7 +217,7 @@
FT_Offset i;
FT_UInt j;
FT_Memory memory = stream->memory;
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UNUSED( error );
@@ -283,7 +285,7 @@
FT_Memory memory = stream->memory;
GX_Blend blend = face->blend;
GX_AVarSegment segment;
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_ULong version;
FT_Long axisCount;
FT_Int i, j;
@@ -412,7 +414,7 @@
if ( gvar_head.version != (FT_Long)0x00010000L ||
gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )
{
- error = TT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -501,11 +503,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 +525,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 +538,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;
@@ -619,7 +612,7 @@
FT_Stream stream = face->root.stream;
FT_Memory memory = face->root.memory;
FT_ULong table_len;
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_ULong fvar_start;
FT_Int i, j;
FT_MM_Var* mmvar = NULL;
@@ -690,7 +683,7 @@
fvar_head.offsetToData + fvar_head.axisCount * 20U +
fvar_head.instanceCount * fvar_head.instanceSize > table_len )
{
- error = TT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -712,7 +705,7 @@
mmvar->num_axis =
fvar_head.axisCount;
mmvar->num_designs =
- (FT_UInt)-1; /* meaningless in this context; each glyph */
+ ~0U; /* meaningless in this context; each glyph */
/* may have a different number of designs */
/* (or tuples, as called by Apple) */
mmvar->num_namedstyles =
@@ -856,7 +849,7 @@
FT_UInt num_coords,
FT_Fixed* coords )
{
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
GX_Blend blend;
FT_MM_Var* mmvar;
FT_UInt i;
@@ -884,14 +877,14 @@
if ( num_coords != mmvar->num_axis )
{
- error = TT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
for ( i = 0; i < num_coords; ++i )
if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L )
{
- error = TT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -992,7 +985,7 @@
FT_UInt num_coords,
FT_Fixed* coords )
{
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Fixed* normalized = NULL;
GX_Blend blend;
FT_MM_Var* mmvar;
@@ -1013,7 +1006,7 @@
if ( num_coords != mmvar->num_axis )
{
- error = TT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -1029,24 +1022,16 @@
{
if ( coords[i] > a->maximum || coords[i] < a->minimum )
{
- error = TT_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
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 +1046,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;
}
@@ -1141,7 +1122,7 @@
{
FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" ));
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
}
@@ -1149,7 +1130,7 @@
{
FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" ));
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
}
@@ -1158,13 +1139,13 @@
{
FT_TRACE2(( "is missing\n" ));
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
}
if ( FT_FRAME_ENTER( table_len ) )
{
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
}
@@ -1173,7 +1154,7 @@
{
FT_TRACE2(( "bad table version\n" ));
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
goto FExit;
}
@@ -1344,7 +1325,7 @@
if ( !face->doblend || blend == NULL )
- return TT_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* to be freed by the caller */
if ( FT_NEW_ARRAY( delta_xy, n_points ) )
@@ -1354,7 +1335,7 @@
if ( glyph_index >= blend->gv_glyphcnt ||
blend->glyphoffsets[glyph_index] ==
blend->glyphoffsets[glyph_index + 1] )
- return TT_Err_Ok; /* no variation data for this glyph */
+ return FT_Err_Ok; /* no variation data for this glyph */
if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) ||
FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] -
@@ -1404,7 +1385,7 @@
}
else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
{
- error = TT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Fail3;
}
else
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 3acb24a..798d4a9 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -4,7 +4,7 @@
/* */
/* TrueType bytecode interpreter (body). */
/* */
-/* Copyright 1996-2012 */
+/* Copyright 1996-2013 */
/* by David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -25,20 +25,16 @@
#include FT_INTERNAL_CALC_H
#include FT_TRIGONOMETRY_H
#include FT_SYSTEM_H
+#include FT_TRUETYPE_DRIVER_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
-
-
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
@@ -52,7 +48,7 @@
/* */
/* In order to detect infinite loops in the code, we set up a counter */
/* within the run loop. A single stroke of interpretation is now */
- /* limited to a maximal number of opcodes defined below. */
+ /* limited to a maximum number of opcodes defined below. */
/* */
#define MAX_RUNNABLE_OPCODES 1000000L
@@ -136,6 +132,11 @@
#define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args )
+#define SUBPIXEL_HINTING \
+ ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \
+ TT_INTERPRETER_VERSION_38 )
+
+
/*************************************************************************/
/* */
/* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */
@@ -232,6 +233,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
@@ -301,7 +310,7 @@
exec->IP = IP;
exec->curRange = range;
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -337,7 +346,7 @@
exec->codeRangeTable[range - 1].base = (FT_Byte*)base;
exec->codeRangeTable[range - 1].size = length;
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -370,7 +379,7 @@
exec->codeRangeTable[range - 1].base = NULL;
exec->codeRangeTable[range - 1].size = 0;
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -428,7 +437,7 @@
FT_FREE( exec );
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -478,7 +487,7 @@
exec->face = NULL;
exec->size = NULL;
- return TT_Err_Ok;
+ return FT_Err_Ok;
Fail_Memory:
FT_ERROR(( "Init_Context: not enough memory for %p\n", exec ));
@@ -530,7 +539,7 @@
*size = new_max;
}
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -637,7 +646,7 @@
exec->instruction_trap = FALSE;
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -680,7 +689,7 @@
for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
size->codeRangeTable[i] = exec->codeRangeTable[i];
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
@@ -716,7 +725,7 @@
if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) )
- != TT_Err_Ok )
+ != FT_Err_Ok )
return error;
exec->zp0 = exec->pts;
@@ -753,7 +762,7 @@
if ( !debug )
return TT_RunIns( exec );
else
- return TT_Err_Ok;
+ return FT_Err_Ok;
#endif
}
@@ -1463,7 +1472,7 @@
#else
- /* compute (a*b)/2^14 with maximal accuracy and rounding */
+ /* compute (a*b)/2^14 with maximum accuracy and rounding */
static FT_Int32
TT_MulFix14( FT_Int32 a,
FT_Int b )
@@ -1476,7 +1485,7 @@
l = (FT_UInt32)( ( a & 0xFFFFU ) * b );
m = ( a >> 16 ) * b;
- lo = l + (FT_UInt32)( m << 16 );
+ lo = l + ( (FT_UInt32)m << 16 );
hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l );
/* divide the result by 2^14 with rounding */
@@ -1488,12 +1497,12 @@
l = lo + 0x2000U;
hi += l < lo;
- return ( hi << 18 ) | ( l >> 14 );
+ return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) );
}
#endif
- /* compute (ax*bx+ay*by)/2^14 with maximal accuracy and rounding */
+ /* compute (ax*bx+ay*by)/2^14 with maximum accuracy and rounding */
static FT_Int32
TT_DotFix14( FT_Int32 ax,
FT_Int32 ay,
@@ -1508,14 +1517,14 @@
l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx );
m = ( ax >> 16 ) * bx;
- lo1 = l + (FT_UInt32)( m << 16 );
+ lo1 = l + ( (FT_UInt32)m << 16 );
hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l );
/* compute ay*by as 64-bit value */
l = (FT_UInt32)( ( ay & 0xFFFFU ) * by );
m = ( ay >> 16 ) * by;
- lo2 = l + (FT_UInt32)( m << 16 );
+ lo2 = l + ( (FT_UInt32)m << 16 );
hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l );
/* add them */
@@ -1531,100 +1540,10 @@
l = lo + 0x2000U;
hi += ( l < lo );
- return ( hi << 18 ) | ( l >> 14 );
+ return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) );
}
- /* return length of given vector */
-
-#if 0
-
- static FT_Int32
- TT_VecLen( FT_Int32 x,
- FT_Int32 y )
- {
- FT_Int32 m, hi1, hi2, hi;
- FT_UInt32 l, lo1, lo2, lo;
-
-
- /* compute x*x as 64-bit value */
- lo = (FT_UInt32)( x & 0xFFFFU );
- hi = x >> 16;
-
- l = lo * lo;
- m = hi * lo;
- hi = hi * hi;
-
- lo1 = l + (FT_UInt32)( m << 17 );
- hi1 = hi + ( m >> 15 ) + ( lo1 < l );
-
- /* compute y*y as 64-bit value */
- lo = (FT_UInt32)( y & 0xFFFFU );
- hi = y >> 16;
-
- l = lo * lo;
- m = hi * lo;
- hi = hi * hi;
-
- lo2 = l + (FT_UInt32)( m << 17 );
- hi2 = hi + ( m >> 15 ) + ( lo2 < l );
-
- /* add them to get 'x*x+y*y' as 64-bit value */
- lo = lo1 + lo2;
- hi = hi1 + hi2 + ( lo < lo1 );
-
- /* compute the square root of this value */
- {
- FT_UInt32 root, rem, test_div;
- FT_Int count;
-
-
- root = 0;
-
- {
- rem = 0;
- count = 32;
- do
- {
- rem = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 );
- hi = ( hi << 2 ) | ( lo >> 30 );
- lo <<= 2;
- root <<= 1;
- test_div = ( root << 1 ) + 1;
-
- if ( rem >= test_div )
- {
- rem -= test_div;
- root += 1;
- }
- } while ( --count );
- }
-
- return (FT_Int32)root;
- }
- }
-
-#else
-
- /* this version uses FT_Vector_Length which computes the same value */
- /* much, much faster.. */
- /* */
- static FT_F26Dot6
- TT_VecLen( FT_F26Dot6 X,
- FT_F26Dot6 Y )
- {
- FT_Vector v;
-
-
- v.x = X;
- v.y = Y;
-
- return FT_Vector_Length( &v );
- }
-
-#endif
-
-
/*************************************************************************/
/* */
/* <Function> */
@@ -1661,14 +1580,14 @@
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 );
- CUR.tt_metrics.ratio = TT_VecLen( x, y );
+ 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 = FT_Hypot( x, y );
}
}
}
@@ -1679,7 +1598,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 +1619,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() );
}
@@ -1786,7 +1705,7 @@
if ( aRange < 1 || aRange > 3 )
{
- CUR.error = TT_Err_Bad_Argument;
+ CUR.error = FT_THROW( Bad_Argument );
return FAILURE;
}
@@ -1794,7 +1713,7 @@
if ( range->base == NULL ) /* invalid coderange */
{
- CUR.error = TT_Err_Invalid_CodeRange;
+ CUR.error = FT_THROW( Invalid_CodeRange );
return FAILURE;
}
@@ -1804,7 +1723,7 @@
if ( aIP > range->size )
{
- CUR.error = TT_Err_Code_Overflow;
+ CUR.error = FT_THROW( Code_Overflow );
return FAILURE;
}
@@ -1850,9 +1769,12 @@
if ( v != 0 )
{
- zone->cur[point].x += TT_MULDIV( distance,
- v * 0x10000L,
- CUR.F_dot_P );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( !SUBPIXEL_HINTING ||
+ ( !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 +1783,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 +1822,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,7 +1848,12 @@
{
FT_UNUSED_EXEC;
- zone->cur[point].x += distance;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( !SUBPIXEL_HINTING ||
+ !CUR.ignore_x_mode )
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ zone->cur[point].x += distance;
+
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
@@ -2193,7 +2114,7 @@
}
else
{
- val = - FT_PIX_CEIL( compensation - distance );
+ val = -FT_PIX_CEIL( compensation - distance );
if ( val > 0 )
val = 0;
}
@@ -2404,8 +2325,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 +2539,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 +2552,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;
@@ -2716,98 +2624,33 @@
/* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */
/* R is undefined. */
/* */
-
-
static FT_Bool
Normalize( EXEC_OP_ FT_F26Dot6 Vx,
FT_F26Dot6 Vy,
FT_UnitVector* R )
{
FT_F26Dot6 W;
- FT_Bool S1, S2;
FT_UNUSED_EXEC;
- if ( FT_ABS( Vx ) < 0x10000L && FT_ABS( Vy ) < 0x10000L )
+ if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L )
{
- Vx *= 0x100;
- Vy *= 0x100;
-
- W = TT_VecLen( Vx, Vy );
-
- if ( W == 0 )
+ if ( Vx == 0 && Vy == 0 )
{
/* XXX: UNDOCUMENTED! It seems that it is possible to try */
/* to normalize the vector (0,0). Return immediately. */
return SUCCESS;
}
- R->x = (FT_F2Dot14)FT_MulDiv( Vx, 0x4000L, W );
- R->y = (FT_F2Dot14)FT_MulDiv( Vy, 0x4000L, W );
-
- return SUCCESS;
+ Vx *= 0x4000;
+ Vy *= 0x4000;
}
- W = TT_VecLen( Vx, Vy );
-
- Vx = FT_MulDiv( Vx, 0x4000L, W );
- Vy = FT_MulDiv( Vy, 0x4000L, W );
-
- W = Vx * Vx + Vy * Vy;
-
- /* Now, we want that Sqrt( W ) = 0x4000 */
- /* Or 0x10000000 <= W < 0x10004000 */
-
- if ( Vx < 0 )
- {
- Vx = -Vx;
- S1 = TRUE;
- }
- else
- S1 = FALSE;
+ W = FT_Hypot( Vx, Vy );
- if ( Vy < 0 )
- {
- Vy = -Vy;
- S2 = TRUE;
- }
- else
- S2 = FALSE;
-
- while ( W < 0x10000000L )
- {
- /* We need to increase W by a minimal amount */
- if ( Vx < Vy )
- Vx++;
- else
- Vy++;
-
- W = Vx * Vx + Vy * Vy;
- }
-
- while ( W >= 0x10004000L )
- {
- /* We need to decrease W by a minimal amount */
- if ( Vx < Vy )
- Vx--;
- else
- Vy--;
-
- W = Vx * Vx + Vy * Vy;
- }
-
- /* Note that in various cases, we can only */
- /* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */
-
- if ( S1 )
- Vx = -Vx;
-
- if ( S2 )
- Vy = -Vy;
-
- R->x = (FT_F2Dot14)Vx; /* Type conversion */
- R->y = (FT_F2Dot14)Vy; /* Type conversion */
+ R->x = (FT_F2Dot14)TT_DivFix14( Vx, W );
+ R->y = (FT_F2Dot14)TT_DivFix14( Vy, W );
return SUCCESS;
}
@@ -2835,7 +2678,7 @@
BOUNDS( aIdx2, CUR.zp1.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return FAILURE;
}
@@ -3091,10 +2934,10 @@
CUR.func_round = (TT_Round_Func)Round_Super_45;
-#define DO_SLOOP \
- if ( args[0] < 0 ) \
- CUR.error = TT_Err_Bad_Argument; \
- else \
+#define DO_SLOOP \
+ if ( args[0] < 0 ) \
+ CUR.error = FT_THROW( Bad_Argument ); \
+ else \
CUR.GS.loop = args[0];
@@ -3110,14 +2953,9 @@
CUR.GS.single_width_cutin = (FT_F26Dot6)args[0];
- /* XXX: UNDOCUMENTED! or bug in the Windows engine? */
- /* */
- /* It seems that the value that is read here is */
- /* expressed in 16.16 format rather than in font */
- /* units. */
- /* */
-#define DO_SSW \
- CUR.GS.single_width_value = (FT_F26Dot6)( args[0] >> 10 );
+#define DO_SSW \
+ CUR.GS.single_width_value = FT_MulFix( args[0], \
+ CUR.tt_metrics.scale );
#define DO_FLIPON \
@@ -3181,21 +3019,21 @@
args[0] = CUR.top;
-#define DO_CINDEX \
- { \
- FT_Long L; \
- \
- \
- L = args[0]; \
- \
- if ( L <= 0 || L > CUR.args ) \
- { \
- if ( CUR.pedantic_hinting ) \
- CUR.error = TT_Err_Invalid_Reference; \
- args[0] = 0; \
- } \
- else \
- args[0] = CUR.stack[CUR.args - L]; \
+#define DO_CINDEX \
+ { \
+ FT_Long L; \
+ \
+ \
+ L = args[0]; \
+ \
+ if ( L <= 0 || L > CUR.args ) \
+ { \
+ if ( CUR.pedantic_hinting ) \
+ CUR.error = FT_THROW( Invalid_Reference ); \
+ args[0] = 0; \
+ } \
+ else \
+ args[0] = CUR.stack[CUR.args - L]; \
}
@@ -3203,24 +3041,24 @@
if ( args[1] != 0 ) \
{ \
if ( args[0] == 0 && CUR.args == 0 ) \
- CUR.error = TT_Err_Bad_Argument; \
+ CUR.error = FT_THROW( Bad_Argument ); \
CUR.IP += args[0]; \
if ( CUR.IP < 0 || \
( CUR.callTop > 0 && \
CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
- CUR.error = TT_Err_Bad_Argument; \
+ CUR.error = FT_THROW( Bad_Argument ); \
CUR.step_ins = FALSE; \
}
#define DO_JMPR \
if ( args[0] == 0 && CUR.args == 0 ) \
- CUR.error = TT_Err_Bad_Argument; \
+ CUR.error = FT_THROW( Bad_Argument ); \
CUR.IP += args[0]; \
if ( CUR.IP < 0 || \
( CUR.callTop > 0 && \
CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
- CUR.error = TT_Err_Bad_Argument; \
+ CUR.error = FT_THROW( Bad_Argument ); \
CUR.step_ins = FALSE;
@@ -3228,12 +3066,12 @@
if ( args[1] == 0 ) \
{ \
if ( args[0] == 0 && CUR.args == 0 ) \
- CUR.error = TT_Err_Bad_Argument; \
+ CUR.error = FT_THROW( Bad_Argument ); \
CUR.IP += args[0]; \
if ( CUR.IP < 0 || \
( CUR.callTop > 0 && \
CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
- CUR.error = TT_Err_Bad_Argument; \
+ CUR.error = FT_THROW( Bad_Argument ); \
CUR.step_ins = FALSE; \
}
@@ -3292,13 +3130,13 @@
#define DO_DIV \
if ( args[1] == 0 ) \
- CUR.error = TT_Err_Divide_By_Zero; \
+ CUR.error = FT_THROW( 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 \
@@ -3316,6 +3154,45 @@
#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 ( SUBPIXEL_HINTING && \
+ CUR.ignore_x_mode && \
+ ( ( I == 24 && \
+ ( CUR.face->sph_found_func_flags & \
+ ( SPH_FDEF_SPACING_1 | \
+ SPH_FDEF_SPACING_2 ) ) ) || \
+ ( I == 22 && \
+ ( CUR.sph_in_func_flags & \
+ SPH_FDEF_TYPEMAN_STROKES ) ) || \
+ ( I == 8 && \
+ ( CUR.face->sph_found_func_flags & \
+ SPH_FDEF_VACUFORM_ROUND_1 ) && \
+ CUR.iup_called ) ) ) \
+ args[0] = 0; \
+ else \
+ args[0] = CUR.storage[I]; \
+ } \
+ }
+
+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
#define DO_RS \
{ \
@@ -3335,6 +3212,8 @@
args[0] = CUR.storage[I]; \
}
+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
#define DO_WS \
{ \
@@ -3402,12 +3281,12 @@
} \
} \
else \
- CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \
+ CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \
}
-#define DO_DEBUG \
- CUR.error = TT_Err_Debug_OpCode;
+#define DO_DEBUG \
+ CUR.error = FT_THROW( Debug_OpCode );
#define DO_ROUND \
@@ -3435,10 +3314,10 @@
#undef ARRAY_BOUND_ERROR
-#define ARRAY_BOUND_ERROR \
- { \
- CUR.error = TT_Err_Invalid_Reference; \
- return; \
+#define ARRAY_BOUND_ERROR \
+ { \
+ CUR.error = FT_THROW( Invalid_Reference ); \
+ return; \
}
@@ -4417,7 +4296,7 @@
if ( L <= 0 || L > CUR.args )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
}
else
{
@@ -4487,7 +4366,7 @@
}
Fail_Overflow:
- CUR.error = TT_Err_Code_Overflow;
+ CUR.error = FT_THROW( Code_Overflow );
return FAILURE;
}
@@ -4592,6 +4471,106 @@
TT_DefRecord* rec;
TT_DefRecord* limit;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* arguments to opcodes are skipped by `SKIP_Code' */
+ FT_Byte opcode_pattern[9][12] = {
+ /* #0 inline delta function 1 */
+ {
+ 0x4B, /* PPEM */
+ 0x53, /* GTEQ */
+ 0x23, /* SWAP */
+ 0x4B, /* PPEM */
+ 0x51, /* LTEQ */
+ 0x5A, /* AND */
+ 0x58, /* IF */
+ 0x38, /* SHPIX */
+ 0x1B, /* ELSE */
+ 0x21, /* POP */
+ 0x21, /* POP */
+ 0x59 /* EIF */
+ },
+ /* #1 inline delta function 2 */
+ {
+ 0x4B, /* PPEM */
+ 0x54, /* EQ */
+ 0x58, /* IF */
+ 0x38, /* SHPIX */
+ 0x1B, /* ELSE */
+ 0x21, /* POP */
+ 0x21, /* POP */
+ 0x59 /* EIF */
+ },
+ /* #2 diagonal stroke function */
+ {
+ 0x20, /* DUP */
+ 0x20, /* DUP */
+ 0xB0, /* PUSHB_1 */
+ /* 1 */
+ 0x60, /* ADD */
+ 0x46, /* GC_cur */
+ 0xB0, /* PUSHB_1 */
+ /* 64 */
+ 0x23, /* SWAP */
+ 0x42 /* WS */
+ },
+ /* #3 VacuFormRound function */
+ {
+ 0x45, /* RCVT */
+ 0x23, /* SWAP */
+ 0x46, /* GC_cur */
+ 0x60, /* ADD */
+ 0x20, /* DUP */
+ 0xB0 /* PUSHB_1 */
+ /* 38 */
+ },
+ /* #4 TTFautohint bytecode (old) */
+ {
+ 0x20, /* DUP */
+ 0x64, /* ABS */
+ 0xB0, /* PUSHB_1 */
+ /* 32 */
+ 0x60, /* ADD */
+ 0x66, /* FLOOR */
+ 0x23, /* SWAP */
+ 0xB0 /* PUSHB_1 */
+ },
+ /* #5 spacing function 1 */
+ {
+ 0x01, /* SVTCA_x */
+ 0xB0, /* PUSHB_1 */
+ /* 24 */
+ 0x43, /* RS */
+ 0x58 /* IF */
+ },
+ /* #6 spacing function 2 */
+ {
+ 0x01, /* SVTCA_x */
+ 0x18, /* RTG */
+ 0xB0, /* PUSHB_1 */
+ /* 24 */
+ 0x43, /* RS */
+ 0x58 /* IF */
+ },
+ /* #7 TypeMan Talk DiagEndCtrl function */
+ {
+ 0x01, /* SVTCA_x */
+ 0x20, /* DUP */
+ 0xB0, /* PUSHB_1 */
+ /* 3 */
+ 0x25, /* CINDEX */
+ },
+ /* #8 TypeMan Talk Align */
+ {
+ 0x06, /* SPVTL */
+ 0x7D, /* RDTG */
+ },
+ };
+ FT_UShort opcode_patterns = 9;
+ FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
+ 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. */
@@ -4611,7 +4590,7 @@
/* check that there is enough room for new functions */
if ( CUR.numFDefs >= CUR.maxFDefs )
{
- CUR.error = TT_Err_Too_Many_Function_Defs;
+ CUR.error = FT_THROW( Too_Many_Function_Defs );
return;
}
CUR.numFDefs++;
@@ -4621,28 +4600,149 @@
/* func # must be within unsigned 16-bit integer */
if ( n > 0xFFFFU )
{
- CUR.error = TT_Err_Too_Many_Function_Defs;
+ CUR.error = FT_THROW( Too_Many_Function_Defs );
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;
+ rec->sph_fdef_flags = 0x0000;
if ( n > CUR.maxFunc )
CUR.maxFunc = (FT_UInt16)n;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* We don't know for sure these are typeman functions, */
+ /* however they are only active when RS 22 is called */
+ if ( n >= 64 && n <= 66 )
+ rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES;
+#endif
+
/* Now skip the whole function definition. */
/* We don't allow nested IDEFS & FDEFs. */
while ( SKIP_Code() == SUCCESS )
{
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ if ( SUBPIXEL_HINTING )
+ {
+ for ( i = 0; i < opcode_patterns; i++ )
+ {
+ if ( opcode_pointer[i] < opcode_size[i] &&
+ CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
+ {
+ opcode_pointer[i] += 1;
+
+ if ( opcode_pointer[i] == opcode_size[i] )
+ {
+ FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
+ i, n,
+ CUR.face->root.family_name,
+ CUR.face->root.style_name ));
+
+ switch ( i )
+ {
+ case 0:
+ rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1;
+ CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
+ break;
+
+ case 1:
+ rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2;
+ CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
+ break;
+
+ case 2:
+ switch ( n )
+ {
+ /* needs to be implemented still */
+ case 58:
+ rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE;
+ CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
+ }
+ break;
+
+ case 3:
+ switch ( n )
+ {
+ case 0:
+ rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1;
+ CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
+ }
+ break;
+
+ case 4:
+ /* probably not necessary to detect anymore */
+ rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1;
+ CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
+ break;
+
+ case 5:
+ switch ( n )
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ case 7:
+ case 8:
+ rec->sph_fdef_flags |= SPH_FDEF_SPACING_1;
+ CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
+ }
+ break;
+
+ case 6:
+ switch ( n )
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ case 7:
+ case 8:
+ rec->sph_fdef_flags |= SPH_FDEF_SPACING_2;
+ CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
+ }
+ break;
+
+ case 7:
+ rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+ CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+ break;
+
+ case 8:
+#if 0
+ rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+ CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+#endif
+ break;
+ }
+ opcode_pointer[i] = 0;
+ }
+ }
+
+ else
+ opcode_pointer[i] = 0;
+ }
+
+ /* Set sph_compatibility_mode only when deltas are detected */
+ CUR.face->sph_compatibility_mode =
+ ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
+ ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
+ }
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
switch ( CUR.opcode )
{
case 0x89: /* IDEF */
case 0x2C: /* FDEF */
- CUR.error = TT_Err_Nested_DEFS;
+ CUR.error = FT_THROW( Nested_DEFS );
return;
case 0x2D: /* ENDF */
@@ -4667,9 +4767,13 @@
FT_UNUSED_ARG;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ CUR.sph_in_func_flags = 0x0000;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */
{
- CUR.error = TT_Err_ENDF_In_Exec_Stream;
+ CUR.error = FT_THROW( ENDF_In_Exec_Stream );
return;
}
@@ -4751,10 +4855,21 @@
if ( !def->active )
goto Fail;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode &&
+ ( ( CUR.iup_called &&
+ ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
+ ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) )
+ goto Fail;
+ else
+ CUR.sph_in_func_flags = def->sph_fdef_flags;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
/* check the call stack */
if ( CUR.callTop >= CUR.callSize )
{
- CUR.error = TT_Err_Stack_Overflow;
+ CUR.error = FT_THROW( Stack_Overflow );
return;
}
@@ -4772,10 +4887,11 @@
def->start );
CUR.step_ins = FALSE;
+
return;
Fail:
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
}
@@ -4828,10 +4944,19 @@
if ( !def->active )
goto Fail;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode &&
+ ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
+ goto Fail;
+ else
+ CUR.sph_in_func_flags = def->sph_fdef_flags;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
/* check stack */
if ( CUR.callTop >= CUR.callSize )
{
- CUR.error = TT_Err_Stack_Overflow;
+ CUR.error = FT_THROW( Stack_Overflow );
return;
}
@@ -4851,10 +4976,11 @@
CUR.step_ins = FALSE;
}
+
return;
Fail:
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
}
@@ -4885,7 +5011,7 @@
/* check that there is enough room for a new instruction */
if ( CUR.numIDefs >= CUR.maxIDefs )
{
- CUR.error = TT_Err_Too_Many_Instruction_Defs;
+ CUR.error = FT_THROW( Too_Many_Instruction_Defs );
return;
}
CUR.numIDefs++;
@@ -4894,7 +5020,7 @@
/* opcode must be unsigned 8-bit integer */
if ( 0 > args[0] || args[0] > 0x00FF )
{
- CUR.error = TT_Err_Too_Many_Instruction_Defs;
+ CUR.error = FT_THROW( Too_Many_Instruction_Defs );
return;
}
@@ -4915,7 +5041,7 @@
{
case 0x89: /* IDEF */
case 0x2C: /* FDEF */
- CUR.error = TT_Err_Nested_DEFS;
+ CUR.error = FT_THROW( Nested_DEFS );
return;
case 0x2D: /* ENDF */
return;
@@ -4949,7 +5075,7 @@
if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
{
- CUR.error = TT_Err_Stack_Overflow;
+ CUR.error = FT_THROW( Stack_Overflow );
return;
}
@@ -4976,7 +5102,7 @@
if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
{
- CUR.error = TT_Err_Stack_Overflow;
+ CUR.error = FT_THROW( Stack_Overflow );
return;
}
@@ -5006,7 +5132,7 @@
if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
{
- CUR.error = TT_Err_Stack_Overflow;
+ CUR.error = FT_THROW( Stack_Overflow );
return;
}
@@ -5031,7 +5157,7 @@
if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
{
- CUR.error = TT_Err_Stack_Overflow;
+ CUR.error = FT_THROW( Stack_Overflow );
return;
}
@@ -5074,7 +5200,7 @@
if ( BOUNDSL( L, CUR.zp2.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
R = 0;
}
else
@@ -5111,7 +5237,7 @@
if ( BOUNDS( L, CUR.zp2.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5155,7 +5281,7 @@
BOUNDS( K, CUR.zp1.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
D = 0;
}
else
@@ -5184,15 +5310,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 );
}
@@ -5200,6 +5326,13 @@
}
}
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
+ if ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode && FT_ABS( D ) == 64 )
+ D += 1;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
args[0] = D;
}
@@ -5225,7 +5358,7 @@
BOUNDS( p1, CUR.zp2.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5265,6 +5398,12 @@
A = v1->x - v2->x;
B = v1->y - v2->y;
+
+ if ( A == 0 && B == 0 )
+ {
+ A = 0x4000;
+ aOpc = 0;
+ }
}
if ( ( aOpc & 1 ) != 0 )
@@ -5303,7 +5442,7 @@
default:
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5332,7 +5471,7 @@
default:
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5361,7 +5500,7 @@
default:
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5390,7 +5529,7 @@
default:
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5421,7 +5560,7 @@
if ( K < 1 || K > 2 )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5519,7 +5658,7 @@
if ( CUR.top < CUR.GS.loop )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Too_Few_Arguments;
+ CUR.error = FT_THROW( Too_Few_Arguments );
goto Fail;
}
@@ -5533,7 +5672,7 @@
{
if ( CUR.pedantic_hinting )
{
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
}
@@ -5568,7 +5707,7 @@
BOUNDS( L, CUR.pts.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5596,7 +5735,7 @@
BOUNDS( L, CUR.pts.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5630,7 +5769,7 @@
if ( BOUNDS( p, zp.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
*refp = 0;
return FAILURE;
}
@@ -5657,12 +5796,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;
@@ -5732,7 +5867,7 @@
if ( CUR.top < CUR.GS.loop )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
goto Fail;
}
@@ -5748,11 +5883,18 @@
{
if ( CUR.pedantic_hinting )
{
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
}
else
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* doesn't follow Cleartype spec but produces better result */
+ if ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode )
+ MOVE_Zp2_Point( point, 0, dy, TRUE );
+ else
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
MOVE_Zp2_Point( point, dx, dy, TRUE );
CUR.GS.loop--;
@@ -5772,7 +5914,7 @@
/* */
/* UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) */
/* contour in the twilight zone, namely contour number */
- /* zero. */
+ /* zero which includes all points of it. */
/* */
static void
Ins_SHC( INS_ARG )
@@ -5791,7 +5933,7 @@
if ( BOUNDS( contour, bounds ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5839,7 +5981,7 @@
if ( BOUNDS( args[0], 2 ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5877,12 +6019,15 @@
{
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 )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
goto Fail;
}
@@ -5891,13 +6036,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,13 +6062,95 @@
{
if ( CUR.pedantic_hinting )
{
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
}
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 sph_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 ( SUBPIXEL_HINTING &&
+ 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.face->sph_compatibility_mode &&
+ CUR.GS.freeVector.y != 0 )
+ {
+ MOVE_Zp2_Point( point, dx, dy, TRUE );
+
+ /* save new point */
+ if ( CUR.GS.freeVector.y != 0 )
+ {
+ B2 = CUR.zp2.cur[point].y;
+
+ /* reverse any disallowed moves */
+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
+ ( B1 & 63 ) != 0 &&
+ ( B2 & 63 ) != 0 &&
+ B1 != B2 )
+ MOVE_Zp2_Point( point, -dx, -dy, TRUE );
+ }
+ }
+ else if ( CUR.face->sph_compatibility_mode )
+ {
+ if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
+ {
+ dx = FT_PIX_ROUND( B1 + dx ) - B1;
+ dy = FT_PIX_ROUND( B1 + dy ) - B1;
+ }
+
+ /* skip post-iup deltas */
+ if ( CUR.iup_called &&
+ ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
+ ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
+ goto Skip;
+
+ 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, 0, dy, TRUE );
+
+ /* save new point */
+ if ( CUR.GS.freeVector.y != 0 )
+ {
+ B2 = CUR.zp2.cur[point].y;
+
+ /* reverse any disallowed moves */
+ if ( ( B1 & 63 ) == 0 &&
+ ( B2 & 63 ) != 0 &&
+ B1 != B2 )
+ MOVE_Zp2_Point( point, 0, -dy, TRUE );
+ }
+ }
+ else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
+ MOVE_Zp2_Point( point, dx, dy, TRUE );
+ }
+ else
+ MOVE_Zp2_Point( point, dx, dy, TRUE );
+ }
+
+ Skip:
+
+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
MOVE_Zp2_Point( point, dx, dy, TRUE );
+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
CUR.GS.loop--;
}
@@ -5945,6 +6172,21 @@
FT_UShort point;
FT_F26Dot6 distance;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_F26Dot6 control_value_cutin;
+
+
+ if ( SUBPIXEL_HINTING )
+ {
+ 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];
@@ -5952,7 +6194,7 @@
BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -5968,6 +6210,15 @@
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 ( SUBPIXEL_HINTING &&
+ 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;
@@ -5988,8 +6239,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];
@@ -5997,15 +6248,25 @@
if ( BOUNDS( point, CUR.zp0.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
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 ( SUBPIXEL_HINTING &&
+ 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;
@@ -6028,18 +6289,29 @@
{
FT_ULong cvtEntry;
FT_UShort point;
- FT_F26Dot6 distance,
- org_dist;
+ FT_F26Dot6 distance;
+ FT_F26Dot6 org_dist;
+ FT_F26Dot6 control_value_cutin;
- cvtEntry = (FT_ULong)args[1];
- point = (FT_UShort)args[0];
+ control_value_cutin = CUR.GS.control_value_cutin;
+ cvtEntry = (FT_ULong)args[1];
+ point = (FT_UShort)args[0];
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode &&
+ CUR.GS.freeVector.x != 0 &&
+ CUR.GS.freeVector.y == 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 ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
goto Fail;
}
@@ -6067,21 +6339,45 @@
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 if not in sph_compatibility_mode or ignore_x_mode. */
+ /* Determined via experimentation and may be incorrect... */
+ if ( !SUBPIXEL_HINTING ||
+ ( !CUR.ignore_x_mode ||
+ !CUR.face->sph_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 ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode &&
+ ( 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 ( SUBPIXEL_HINTING &&
+ 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 );
@@ -6102,16 +6398,26 @@
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 ( SUBPIXEL_HINTING &&
+ 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];
if ( BOUNDS( point, CUR.zp1.n_points ) ||
BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
goto Fail;
}
@@ -6138,15 +6444,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 );
}
@@ -6166,9 +6472,20 @@
/* round flag */
if ( ( CUR.opcode & 4 ) != 0 )
+ {
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( SUBPIXEL_HINTING &&
+ 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,
@@ -6180,13 +6497,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;
}
}
@@ -6221,11 +6538,28 @@
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 ( SUBPIXEL_HINTING &&
+ 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 */
@@ -6234,7 +6568,7 @@
BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
goto Fail;
}
@@ -6280,7 +6614,20 @@
cvt_dist = -cvt_dist;
}
- /* control value cutin and round */
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode &&
+ 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 )
{
@@ -6301,7 +6648,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;
}
@@ -6310,9 +6657,23 @@
CUR.tt_metrics.compensations[CUR.opcode & 3] );
}
else
+ {
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* do cvt cut-in always in MIRP for sph */
+ if ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode &&
+ CUR.GS.gep0 == CUR.GS.gep1 )
+ {
+ if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
+ cvt_dist = org_dist;
+ }
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
distance = ROUND_None(
cvt_dist,
CUR.tt_metrics.compensations[CUR.opcode & 3] );
+ }
/* minimum distance test */
@@ -6320,18 +6681,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
+ if ( 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.ignore_x_mode &&
+ 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
+ if ( SUBPIXEL_HINTING )
+ {
+ B2 = CUR.zp1.cur[point].y;
+
+ /* Reverse move if necessary */
+ if ( CUR.ignore_x_mode )
+ {
+ if ( CUR.face->sph_compatibility_mode &&
+ CUR.GS.freeVector.y != 0 &&
+ ( B1 & 63 ) == 0 &&
+ ( B2 & 63 ) != 0 )
+ reverse_move = TRUE;
+
+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
+ CUR.GS.freeVector.y != 0 &&
+ ( B2 & 63 ) != 0 &&
+ ( B1 & 63 ) != 0 )
+ 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;
@@ -6357,11 +6765,22 @@
FT_UNUSED_ARG;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode &&
+ CUR.iup_called &&
+ ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
+ {
+ CUR.error = FT_THROW( Invalid_Reference );
+ goto Fail;
+ }
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
if ( CUR.top < CUR.GS.loop ||
BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
goto Fail;
}
@@ -6375,7 +6794,7 @@
{
if ( CUR.pedantic_hinting )
{
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
}
@@ -6409,7 +6828,7 @@
a0, a1,
b0, b1;
- FT_F26Dot6 discriminant;
+ FT_F26Dot6 discriminant, dotproduct;
FT_F26Dot6 dx, dy,
dax, day,
@@ -6434,10 +6853,12 @@
BOUNDS( point, CUR.zp2.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
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;
@@ -6449,15 +6870,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;
@@ -6498,7 +6929,7 @@
BOUNDS( p2, CUR.zp0.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -6533,7 +6964,7 @@
if ( CUR.top < CUR.GS.loop )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
goto Fail;
}
@@ -6547,7 +6978,7 @@
if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
goto Fail;
}
@@ -6581,9 +7012,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 );
@@ -6603,7 +7034,7 @@
{
if ( CUR.pedantic_hinting )
{
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
continue;
@@ -6618,9 +7049,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 );
@@ -6629,9 +7060,24 @@
cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base );
if ( org_dist )
- new_dist = ( old_range != 0 )
- ? TT_MULDIV( org_dist, cur_range, old_range )
- : cur_dist;
+ {
+ if ( old_range )
+ new_dist = FT_MulDiv( org_dist, cur_range, old_range );
+ else
+ {
+ /* This is the same as what MS does for the invalid case: */
+ /* */
+ /* delta = (Original_Pt - Original_RP1) - */
+ /* (Current_Pt - Current_RP1) */
+ /* */
+ /* In FreeType speak: */
+ /* */
+ /* new_dist = cur_dist - */
+ /* org_dist - cur_dist; */
+
+ new_dist = -org_dist;
+ }
+ }
else
new_dist = 0;
@@ -6662,7 +7108,7 @@
if ( BOUNDS( point, CUR.zp0.n_points ) )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
@@ -6791,12 +7237,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;
}
@@ -6851,6 +7297,16 @@
contour = 0;
point = 0;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode )
+ {
+ CUR.iup_called = TRUE;
+ 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;
@@ -6920,6 +7376,16 @@
FT_UShort A;
FT_ULong C;
FT_Long B;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_UShort B1, B2;
+
+
+ if ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode &&
+ CUR.iup_called &&
+ ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
+ goto Fail;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
@@ -6932,7 +7398,7 @@
if ( CUR.args < n )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Too_Few_Arguments;
+ CUR.error = FT_THROW( Too_Few_Arguments );
n = CUR.args;
}
@@ -6950,7 +7416,7 @@
if ( CUR.args < 2 )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Too_Few_Arguments;
+ CUR.error = FT_THROW( Too_Few_Arguments );
CUR.args = 0;
goto Fail;
}
@@ -6993,12 +7459,82 @@
B++;
B = B * 64 / ( 1L << CUR.GS.delta_shift );
- CUR_Func_move( &CUR.zp0, A, B );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ if ( 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;
+
+#if 0
+ /* Standard Subpixel Hinting: Allow y move. */
+ /* This messes up dejavu and may not be needed... */
+ if ( !CUR.face->sph_compatibility_mode &&
+ CUR.GS.freeVector.y != 0 )
+ CUR_Func_move( &CUR.zp0, A, B );
+ else
+#endif /* 0 */
+
+ /* Compatibility Mode: Allow x or y move if point touched in */
+ /* Y direction. */
+ if ( CUR.face->sph_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 sph_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.face->sph_compatibility_mode &&
+ ( B1 & 63 ) == 0 &&
+ ( B2 & 63 ) != 0 ) ||
+ ( ( CUR.sph_tweak_flags &
+ SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
+ ( B1 & 63 ) != 0 &&
+ ( B2 & 63 ) != 0 ) ) )
+ CUR_Func_move( &CUR.zp0, A, -B );
+ }
+ }
+ else
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+ CUR_Func_move( &CUR.zp0, A, B );
}
}
else
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
}
Fail:
@@ -7030,7 +7566,7 @@
if ( CUR.args < n )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Too_Few_Arguments;
+ CUR.error = FT_THROW( Too_Few_Arguments );
n = CUR.args;
}
@@ -7047,7 +7583,7 @@
if ( CUR.args < 2 )
{
if ( CUR.pedantic_hinting )
- CUR.error = TT_Err_Too_Few_Arguments;
+ CUR.error = FT_THROW( Too_Few_Arguments );
CUR.args = 0;
goto Fail;
}
@@ -7061,7 +7597,7 @@
{
if ( CUR.pedantic_hinting )
{
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
return;
}
}
@@ -7123,22 +7659,119 @@
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 ( SUBPIXEL_HINTING &&
+ ( args[0] & 1 ) != 0 &&
+ CUR.ignore_x_mode )
+ {
+ K = CUR.rasterizer_version;
+ FT_TRACE7(( "Setting rasterizer version %d\n",
+ CUR.rasterizer_version ));
+ }
+ else
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ if ( ( args[0] & 1 ) != 0 )
+ K = TT_INTERPRETER_VERSION_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 ( SUBPIXEL_HINTING &&
+ CUR.ignore_x_mode &&
+ CUR.rasterizer_version >= TT_INTERPRETER_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;
}
@@ -7161,7 +7794,7 @@
if ( CUR.callTop >= CUR.callSize )
{
- CUR.error = TT_Err_Stack_Overflow;
+ CUR.error = FT_THROW( Stack_Overflow );
return;
}
@@ -7180,7 +7813,7 @@
}
}
- CUR.error = TT_Err_Invalid_Opcode;
+ CUR.error = FT_THROW( Invalid_Opcode );
}
@@ -7507,13 +8140,31 @@
FT_EXPORT_DEF( FT_Error )
TT_RunIns( TT_ExecContext exc )
{
- FT_Long ins_counter = 0; /* executed instructions counter */
+ FT_Long ins_counter = 0; /* executed instructions counter */
+ FT_UShort i;
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_Byte opcode_pattern[1][2] = {
+ /* #8 TypeMan Talk Align */
+ {
+ 0x06, /* SPVTL */
+ 0x7D, /* RDTG */
+ },
+ };
+ FT_UShort opcode_patterns = 1;
+ FT_UShort opcode_pointer[1] = { 0 };
+ FT_UShort opcode_size[1] = { 1 };
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
#ifdef TT_CONFIG_OPTION_STATIC_RASTER
cur = *exc;
#endif
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ 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 )
@@ -7560,12 +8211,9 @@
/* One can also interpret it as the index of the last argument. */
if ( CUR.args < 0 )
{
- FT_UShort i;
-
-
if ( CUR.pedantic_hinting )
{
- CUR.error = TT_Err_Too_Few_Arguments;
+ CUR.error = FT_THROW( Too_Few_Arguments );
goto LErrorLabel_;
}
@@ -7582,12 +8230,45 @@
/* statement. */
if ( CUR.new_top > CUR.stackSize )
{
- CUR.error = TT_Err_Stack_Overflow;
+ CUR.error = FT_THROW( Stack_Overflow );
goto LErrorLabel_;
}
CUR.step_ins = TRUE;
- CUR.error = TT_Err_Ok;
+ CUR.error = FT_Err_Ok;
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ if ( SUBPIXEL_HINTING )
+ {
+ for ( i = 0; i < opcode_patterns; i++ )
+ {
+ if ( opcode_pointer[i] < opcode_size[i] &&
+ CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
+ {
+ opcode_pointer[i] += 1;
+
+ if ( opcode_pointer[i] == opcode_size[i] )
+ {
+ FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n",
+ i,
+ CUR.face->root.family_name,
+ CUR.face->root.style_name ));
+
+ switch ( i )
+ {
+ case 0:
+ break;
+ }
+ opcode_pointer[i] = 0;
+ }
+ }
+ else
+ opcode_pointer[i] = 0;
+ }
+ }
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH
@@ -7801,7 +8482,6 @@
Ins_MDAP( EXEC_ARG_ args );
break;
-
case 0x30: /* IUP */
case 0x31: /* IUP */
Ins_IUP( EXEC_ARG_ args );
@@ -7861,7 +8541,7 @@
break;
Set_Invalid_Ref:
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
break;
case 0x43: /* RS */
@@ -8151,11 +8831,12 @@
#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */
- if ( CUR.error != TT_Err_Ok )
+ if ( CUR.error )
{
switch ( CUR.error )
{
- case TT_Err_Invalid_Opcode: /* looking for redefined instructions */
+ /* looking for redefined instructions */
+ case FT_ERR( Invalid_Opcode ):
{
TT_DefRecord* def = CUR.IDefs;
TT_DefRecord* limit = def + CUR.numIDefs;
@@ -8170,7 +8851,7 @@
if ( CUR.callTop >= CUR.callSize )
{
- CUR.error = TT_Err_Invalid_Reference;
+ CUR.error = FT_THROW( Invalid_Reference );
goto LErrorLabel_;
}
@@ -8190,7 +8871,7 @@
}
}
- CUR.error = TT_Err_Invalid_Opcode;
+ CUR.error = FT_THROW( Invalid_Opcode );
goto LErrorLabel_;
#if 0
@@ -8216,14 +8897,14 @@
/* increment instruction counter and check if we didn't */
/* run this program for too long (e.g. infinite loops). */
if ( ++ins_counter > MAX_RUNNABLE_OPCODES )
- return TT_Err_Execution_Too_Long;
+ return FT_THROW( Execution_Too_Long );
LSuiteLabel_:
if ( CUR.IP >= CUR.codeSize )
{
if ( CUR.callTop > 0 )
{
- CUR.error = TT_Err_Code_Overflow;
+ CUR.error = FT_THROW( Code_Overflow );
goto LErrorLabel_;
}
else
@@ -8237,10 +8918,10 @@
*exc = cur;
#endif
- return TT_Err_Ok;
+ return FT_Err_Ok;
LErrorCodeOverflow_:
- CUR.error = TT_Err_Code_Overflow;
+ CUR.error = FT_THROW( Code_Overflow );
LErrorLabel_:
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
index 6d0fc03..69f5011 100644
--- a/src/truetype/ttinterp.h
+++ b/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-2013 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 SPH_MAX_NAME_SIZE 32
+#define SPH_MAX_CLASS_MEMBERS 100
+
+ typedef struct SPH_TweakRule_
+ {
+ const char family[SPH_MAX_NAME_SIZE];
+ const FT_UInt ppem;
+ const char style[SPH_MAX_NAME_SIZE];
+ const FT_ULong glyph;
+
+ } SPH_TweakRule;
+
+
+ typedef struct SPH_ScaleRule_
+ {
+ const char family[SPH_MAX_NAME_SIZE];
+ const FT_UInt ppem;
+ const char style[SPH_MAX_NAME_SIZE];
+ const FT_ULong glyph;
+ const FT_ULong scale;
+
+ } SPH_ScaleRule;
+
+
+ typedef struct SPH_Font_Class_
+ {
+ const char name[SPH_MAX_NAME_SIZE];
+ const char member[SPH_MAX_CLASS_MEMBERS][SPH_MAX_NAME_SIZE];
+
+ } SPH_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 ) */
+
+ /* 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 */
+
+ FT_ULong sph_in_func_flags; /* flags to indicate if in */
+ /* special functions */
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
} TT_ExecContextRec;
extern const TT_GraphicsState tt_default_graphics_state;
+#ifdef TT_USE_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_USE_BYTECODE_INTERPRETER */
/*************************************************************************/
@@ -270,6 +344,8 @@ FT_BEGIN_HEADER
FT_EXPORT( TT_ExecContext )
TT_New_Context( TT_Driver driver );
+
+#ifdef TT_USE_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_USE_BYTECODE_INTERPRETER */
/*************************************************************************/
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index 814c713..7897efa 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -4,7 +4,7 @@
/* */
/* Objects manager (body). */
/* */
-/* Copyright 1996-2011 */
+/* Copyright 1996-2013 */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -21,6 +21,7 @@
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_SFNT_H
+#include FT_TRUETYPE_DRIVER_H
#include "ttgload.h"
#include "ttpload.h"
@@ -244,7 +245,7 @@
tt_check_trickyness_sfnt_ids( TT_Face face )
{
#define TRICK_SFNT_IDS_PER_FACE 3
-#define TRICK_SFNT_IDS_NUM_FACES 13
+#define TRICK_SFNT_IDS_NUM_FACES 17
static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
[TRICK_SFNT_IDS_PER_FACE] = {
@@ -317,6 +318,26 @@
{ 0x00000000, 0x00000000 }, /* cvt */
{ 0x0d3de9cb, 0x00000141 }, /* fpgm */
{ 0xd4127766, 0x00002280 } /* prep */
+ },
+ { /* NEC FA-Gothic, 1996 */
+ { 0x00000000, 0x00000000 }, /* cvt */
+ { 0x4a692698, 0x000001f0 }, /* fpgm */
+ { 0x340d4346, 0x00001fca } /* prep */
+ },
+ { /* NEC FA-Minchou, 1996 */
+ { 0x00000000, 0x00000000 }, /* cvt */
+ { 0xcd34c604, 0x00000166 }, /* fpgm */
+ { 0x6cf31046, 0x000022b0 } /* prep */
+ },
+ { /* NEC FA-RoundGothicB, 1996 */
+ { 0x00000000, 0x00000000 }, /* cvt */
+ { 0x5da75315, 0x0000019d }, /* fpgm */
+ { 0x40745a5f, 0x000022e0 } /* prep */
+ },
+ { /* NEC FA-RoundGothicM, 1996 */
+ { 0x00000000, 0x00000000 }, /* cvt */
+ { 0xf055fc48, 0x000001c2 }, /* fpgm */
+ { 0x3900ded3, 0x00001e18 } /* prep */
}
};
@@ -501,7 +522,7 @@
if ( !sfnt )
{
FT_ERROR(( "tt_face_init: cannot access `sfnt' module\n" ));
- error = TT_Err_Missing_Module;
+ error = FT_THROW( Missing_Module );
goto Exit;
}
@@ -531,7 +552,7 @@
/* If we are performing a simple font format check, exit immediately. */
if ( face_index < 0 )
- return TT_Err_Ok;
+ return FT_Err_Ok;
/* Load font directory */
error = sfnt->load_face( stream, face, face_index, num_params, params );
@@ -631,7 +652,7 @@
return error;
Bad_Format:
- error = TT_Err_Unknown_File_Format;
+ error = FT_THROW( Unknown_File_Format );
goto Exit;
}
@@ -732,7 +753,7 @@
exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
if ( !exec )
- return TT_Err_Could_Not_Find_Context;
+ return FT_THROW( Could_Not_Find_Context );
TT_Load_Context( exec, face, size );
@@ -744,7 +765,7 @@
exec->threshold = 0;
exec->instruction_trap = FALSE;
- exec->F_dot_P = 0x10000L;
+ exec->F_dot_P = 0x4000L;
exec->pedantic_hinting = pedantic;
@@ -785,7 +806,7 @@
}
}
else
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
if ( !error )
TT_Save_Context( exec, size );
@@ -826,7 +847,7 @@
exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
if ( !exec )
- return TT_Err_Could_Not_Find_Context;
+ return FT_THROW( Could_Not_Find_Context );
TT_Load_Context( exec, face, size );
@@ -856,7 +877,27 @@
}
}
else
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
+
+ /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */
+ /* graphics state variables to be modified by the CVT program. */
+
+ exec->GS.dualVector.x = 0x4000;
+ exec->GS.dualVector.y = 0;
+ exec->GS.projVector.x = 0x4000;
+ exec->GS.projVector.y = 0x0;
+ exec->GS.freeVector.x = 0x4000;
+ exec->GS.freeVector.y = 0x0;
+
+ exec->GS.rp0 = 0;
+ exec->GS.rp1 = 0;
+ exec->GS.rp2 = 0;
+
+ exec->GS.gep0 = 1;
+ exec->GS.gep1 = 1;
+ exec->GS.gep2 = 1;
+
+ exec->GS.loop = 1;
/* save as default graphics state */
size->GS = exec->GS;
@@ -1003,7 +1044,7 @@
tt_size_ready_bytecode( TT_Size size,
FT_Bool pedantic )
{
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( !size->bytecode_ready )
@@ -1070,7 +1111,7 @@
tt_size_init( FT_Size ttsize ) /* TT_Size */
{
TT_Size size = (TT_Size)ttsize;
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
#ifdef TT_USE_BYTECODE_INTERPRETER
size->bytecode_ready = 0;
@@ -1126,7 +1167,7 @@
tt_size_reset( TT_Size size )
{
TT_Face face;
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Size_Metrics* metrics;
@@ -1140,7 +1181,7 @@
*metrics = size->root.metrics;
if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
- return TT_Err_Invalid_PPem;
+ return FT_THROW( Invalid_PPem );
/* This bit flag, if set, indicates that the ppems must be */
/* rounded to integers. Nearly all TrueType fonts have this bit */
@@ -1170,16 +1211,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;
}
@@ -1219,15 +1258,21 @@
if ( !TT_New_Context( driver ) )
- return TT_Err_Could_Not_Find_Context;
+ return FT_THROW( Could_Not_Find_Context );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ driver->interpreter_version = TT_INTERPRETER_VERSION_38;
#else
+ driver->interpreter_version = TT_INTERPRETER_VERSION_35;
+#endif
+
+#else /* !TT_USE_BYTECODE_INTERPRETER */
FT_UNUSED( ttdriver );
-#endif
+#endif /* !TT_USE_BYTECODE_INTERPRETER */
- return TT_Err_Ok;
+ return FT_Err_Ok;
}
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index 47e4129..a11dd37 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -4,7 +4,7 @@
/* */
/* Objects manager (specification). */
/* */
-/* Copyright 1996-2009, 2011-2012 by */
+/* Copyright 1996-2009, 2011-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -173,11 +173,13 @@ 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? */
+ FT_ULong sph_fdef_flags; /* flags to identify special functions */
} TT_DefRecord, *TT_DefArray;
@@ -190,7 +192,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;
@@ -345,11 +347,12 @@ FT_BEGIN_HEADER
/* */
typedef struct TT_DriverRec_
{
- FT_DriverRec root;
+ FT_DriverRec root;
+
TT_ExecContext context; /* execution context */
TT_GlyphZoneRec zone; /* glyph loader points zone */
- void* extension_component;
+ FT_UInt interpreter_version;
} TT_DriverRec;
@@ -427,6 +430,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/src/truetype/ttpic.c b/src/truetype/ttpic.c
index 65ca845..edefae7 100644
--- a/src/truetype/ttpic.c
+++ b/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, 2013 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -22,30 +22,29 @@
#include "ttpic.h"
#include "tterrors.h"
+
#ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from ttdriver.c */
FT_Error
FT_Create_Class_tt_services( FT_Library library,
FT_ServiceDescRec** output_class );
-
void
FT_Destroy_Class_tt_services( FT_Library library,
FT_ServiceDescRec* clazz );
-
void
FT_Init_Class_tt_service_gx_multi_masters(
FT_Service_MultiMastersRec* sv_mm );
-
void
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 )
@@ -66,18 +65,19 @@
tt_driver_class_pic_init( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Error error = TT_Err_Ok;
- TTModulePIC* container;
+ FT_Error error = FT_Err_Ok;
+ TTModulePIC* container = NULL;
FT_Memory memory = library->memory;
/* allocate pointer, clear and set global container pointer */
- if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+ if ( FT_ALLOC( container, sizeof ( *container ) ) )
return error;
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,7 +88,8 @@
#endif
FT_Init_Class_tt_service_truetype_glyf(
&container->tt_service_truetype_glyf );
-Exit:
+
+ Exit:
if ( error )
tt_driver_class_pic_free( library );
return error;
diff --git a/src/truetype/ttpic.h b/src/truetype/ttpic.h
index 48f43a5..cfb4ee6 100644
--- a/src/truetype/ttpic.h
+++ b/src/truetype/ttpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for truetype module. */
/* */
-/* Copyright 2009 by */
+/* Copyright 2009, 2012, 2013 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -23,29 +23,43 @@
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
+#define TT_SERVICE_PROPERTIES_GET tt_service_properties
#else /* FT_CONFIG_OPTION_PIC */
#include FT_MULTIPLE_MASTERS_H
#include FT_SERVICE_MULTIPLE_MASTERS_H
#include FT_SERVICE_TRUETYPE_GLYF_H
+#include FT_SERVICE_PROPERTIES_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;
+ FT_Service_MultiMastersRec tt_service_gx_multi_masters;
#endif
- FT_Service_TTGlyfRec tt_service_truetype_glyf;
+ FT_Service_TTGlyfRec tt_service_truetype_glyf;
+ FT_Service_PropertiesRec tt_service_properties;
+
} 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 )
+#define TT_SERVICE_PROPERTIES_GET \
+ ( GET_PIC( library )->tt_service_properties )
+
/* see ttpic.c for the implementation */
void
@@ -58,6 +72,7 @@ FT_BEGIN_HEADER
/* */
+
FT_END_HEADER
#endif /* __TTPIC_H__ */
diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
index bb6005d..9723a51 100644
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -4,7 +4,7 @@
/* */
/* TrueType-specific tables loader (body). */
/* */
-/* Copyright 1996-2002, 2004-2012 by */
+/* Copyright 1996-2002, 2004-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -72,7 +72,7 @@
/* it is possible that a font doesn't have a glyf table at all */
/* or its size is zero */
- if ( error == TT_Err_Table_Missing )
+ if ( FT_ERR_EQ( error, Table_Missing ) )
face->glyf_len = 0;
else if ( error )
goto Exit;
@@ -81,7 +81,7 @@
error = face->goto_table( face, TTAG_loca, stream, &table_len );
if ( error )
{
- error = TT_Err_Locations_Missing;
+ error = FT_THROW( Locations_Missing );
goto Exit;
}
@@ -92,7 +92,7 @@
if ( table_len >= 0x40000L )
{
FT_TRACE2(( "table too large\n" ));
- error = TT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
face->num_locations = table_len >> shift;
@@ -104,7 +104,7 @@
if ( table_len >= 0x20000L )
{
FT_TRACE2(( "table too large\n" ));
- error = TT_Err_Invalid_Table;
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
face->num_locations = table_len >> shift;
@@ -296,7 +296,7 @@
face->cvt_size = 0;
face->cvt = NULL;
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
goto Exit;
}
@@ -334,7 +334,7 @@
FT_UNUSED( face );
FT_UNUSED( stream );
- return TT_Err_Ok;
+ return FT_Err_Ok;
#endif
}
@@ -375,7 +375,7 @@
{
face->font_program = NULL;
face->font_program_size = 0;
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
FT_TRACE2(( "is missing\n" ));
}
@@ -396,7 +396,7 @@
FT_UNUSED( face );
FT_UNUSED( stream );
- return TT_Err_Ok;
+ return FT_Err_Ok;
#endif
}
@@ -436,7 +436,7 @@
{
face->cvt_program = NULL;
face->cvt_program_size = 0;
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
FT_TRACE2(( "is missing\n" ));
}
@@ -457,7 +457,7 @@
FT_UNUSED( face );
FT_UNUSED( stream );
- return TT_Err_Ok;
+ return FT_Err_Ok;
#endif
}
@@ -495,7 +495,7 @@
/* this table is optional */
error = face->goto_table( face, TTAG_hdmx, stream, &table_size );
if ( error || table_size < 8 )
- return TT_Err_Ok;
+ return FT_Err_Ok;
if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) )
goto Exit;
@@ -525,7 +525,7 @@
if ( version != 0 || num_records > 255 || record_size > 0x10001L )
{
- error = TT_Err_Invalid_File_Format;
+ error = FT_THROW( Invalid_File_Format );
goto Fail;
}
diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c
new file mode 100644
index 0000000..28470ad
--- /dev/null
+++ b/src/truetype/ttsubpix.c
@@ -0,0 +1,1011 @@
+/***************************************************************************/
+/* */
+/* ttsubpix.c */
+/* */
+/* TrueType Subpixel Hinting. */
+/* */
+/* Copyright 2010-2013 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_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 FT_TRUETYPE_DRIVER_H
+
+#include "ttsubpix.h"
+
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ /*************************************************************************/
+ /* */
+ /* 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 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
+
+ static const SPH_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 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 */
+
+
+ /* 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
+
+ const SPH_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",
+ "",
+ },
+ },
+ };
+
+
+ /* Force special legacy fixes for fonts. */
+#define COMPATIBILITY_MODE_RULES_SIZE 1
+
+ const SPH_TweakRule COMPATIBILITY_MODE_Rules
+ [COMPATIBILITY_MODE_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+ /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting. */
+#define PIXEL_HINTING_RULES_SIZE 2
+
+ const SPH_TweakRule PIXEL_HINTING_Rules
+ [PIXEL_HINTING_RULES_SIZE] =
+ {
+ /* these characters are almost always safe */
+ { "Courier New", 12, "Italic", 'z' },
+ { "Courier New", 11, "Italic", 'z' },
+ };
+
+
+ /* Subpixel hinting ignores SHPIX rules on X. Force SHPIX for these. */
+#define DO_SHPIX_RULES_SIZE 1
+
+ const 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 4
+
+ const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules
+ [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] =
+ {
+ /* fix vwxyz thinness*/
+ { "Consolas", 0, "", 0 },
+ /* Fix thin middle stems */
+ { "Core MS Legacy Fonts", 0, "Regular", 0 },
+ /* Cyrillic small letter I */
+ { "Legacy Sans Fonts", 0, "", 0 },
+ /* Fix artifacts with some Regular & Bold */
+ { "Verdana Clones", 0, "", 0 },
+ };
+
+
+#define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1
+
+ const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions
+ [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
+ {
+ /* Fixes < and > */
+ { "Courier New", 0, "Regular", 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_DELTAP_RULES_SIZE 2
+
+ const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules
+ [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] =
+ {
+ /* Maintain thickness of diagonal in 'N' */
+ { "Times New Roman", 0, "Regular/Bold Class", 'N' },
+ { "Georgia", 0, "Regular/Bold Class", 'N' },
+ };
+
+
+ /* Skip Y moves that move a point off a Y pixel boundary. */
+#define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE 1
+
+ const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules
+ [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+#define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1
+
+ const 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 2
+
+ const 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 },
+ };
+
+
+#define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1
+
+ const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions
+ [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+ /* Allow a Direct_Move along X freedom vector if matched. */
+#define ALLOW_X_DMOVE_RULES_SIZE 1
+
+ const SPH_TweakRule ALLOW_X_DMOVE_Rules
+ [ALLOW_X_DMOVE_RULES_SIZE] =
+ {
+ /* Fixes vanishing diagonal in 4 */
+ { "Verdana", 0, "Regular", '4' },
+ };
+
+
+ /* Return MS rasterizer version 35 if matched. */
+#define RASTERIZER_35_RULES_SIZE 8
+
+ const 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 1
+
+ const SPH_TweakRule NORMAL_ROUND_Rules
+ [NORMAL_ROUND_RULES_SIZE] =
+ {
+ /* Fix serif thickness for certain ppems */
+ /* Can probably be generalized somehow */
+ { "Courier New", 0, "", 0 },
+ };
+
+
+ /* Skip IUP instructions if matched. */
+#define SKIP_IUP_RULES_SIZE 1
+
+ const 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
+
+ const SPH_TweakRule MIAP_HACK_Rules
+ [MIAP_HACK_RULES_SIZE] =
+ {
+ { "Geneva", 12, "", 0 },
+ };
+
+
+ /* Skip DELTAP instructions if matched. */
+#define ALWAYS_SKIP_DELTAP_RULES_SIZE 23
+
+ const SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules
+ [ALWAYS_SKIP_DELTAP_RULES_SIZE] =
+ {
+ { "Georgia", 0, "Regular", 'k' },
+ /* fix various problems with e in different versions */
+ { "Trebuchet MS", 14, "Regular", 'e' },
+ { "Trebuchet MS", 13, "Regular", 'e' },
+ { "Trebuchet MS", 15, "Regular", 'e' },
+ { "Trebuchet MS", 0, "Italic", 'v' },
+ { "Trebuchet MS", 0, "Italic", 'w' },
+ { "Trebuchet MS", 0, "Regular", 'Y' },
+ { "Arial", 11, "Regular", 's' },
+ /* prevent problems with '3' and others */
+ { "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", 'a' },
+ { "Arial", 25, "Bold", 'a' },
+ { "Arial", 24, "Bold", 's' },
+ { "Arial", 25, "Bold", 's' },
+ { "Arial", 34, "Bold", 's' },
+ { "Arial", 35, "Bold", 's' },
+ { "Arial", 36, "Bold", 's' },
+ { "Arial", 25, "Regular", 's' },
+ { "Arial", 26, "Regular", 's' },
+ };
+
+
+ /* Always do DELTAP instructions if matched. */
+#define ALWAYS_DO_DELTAP_RULES_SIZE 1
+
+ const SPH_TweakRule ALWAYS_DO_DELTAP_Rules
+ [ALWAYS_DO_DELTAP_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+ /* Don't allow ALIGNRP after IUP. */
+#define NO_ALIGNRP_AFTER_IUP_RULES_SIZE 1
+
+ static const SPH_TweakRule NO_ALIGNRP_AFTER_IUP_Rules
+ [NO_ALIGNRP_AFTER_IUP_RULES_SIZE] =
+ {
+ /* Prevent creation of dents in outline */
+ { "-", 0, "", 0 },
+ };
+
+
+ /* Don't allow DELTAP after IUP. */
+#define NO_DELTAP_AFTER_IUP_RULES_SIZE 1
+
+ static const SPH_TweakRule NO_DELTAP_AFTER_IUP_Rules
+ [NO_DELTAP_AFTER_IUP_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+ /* Don't allow CALL after IUP. */
+#define NO_CALL_AFTER_IUP_RULES_SIZE 1
+
+ static const SPH_TweakRule NO_CALL_AFTER_IUP_Rules
+ [NO_CALL_AFTER_IUP_RULES_SIZE] =
+ {
+ /* Prevent creation of dents in outline */
+ { "-", 0, "", 0 },
+ };
+
+
+ /* De-embolden these glyphs slightly. */
+#define DEEMBOLDEN_RULES_SIZE 9
+
+ static const 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 2
+
+ static const SPH_TweakRule EMBOLDEN_Rules
+ [EMBOLDEN_RULES_SIZE] =
+ {
+ { "Courier New", 0, "Regular", 0 },
+ { "Courier New", 0, "Italic", 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
+
+ static const 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
+
+ static const 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
+
+ static const 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
+
+ static const 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
+
+ static const SPH_TweakRule COMPATIBLE_WIDTHS_Rules
+ [COMPATIBLE_WIDTHS_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+#define X_SCALING_RULES_SIZE 1
+
+ static const SPH_ScaleRule X_SCALING_Rules
+ [X_SCALING_RULES_SIZE] =
+ {
+ { "-", 0, "", 0, 1000 },
+ };
+
+#endif /* FORCE_NATURAL_WIDTHS */
+
+
+ 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 < SPH_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 < SPH_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,
+ const FT_String* family,
+ FT_UInt ppem,
+ const FT_String* style,
+ FT_UInt glyph_index,
+ const 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;
+ }
+
+
+ static FT_UInt
+ scale_test_tweak( TT_Face face,
+ const FT_String* family,
+ FT_UInt ppem,
+ const FT_String* style,
+ FT_UInt glyph_index,
+ const 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;
+ }
+
+
+ FT_LOCAL_DEF( FT_UInt )
+ sph_test_tweak_x_scaling( TT_Face face,
+ const FT_String* family,
+ FT_UInt ppem,
+ const FT_String* style,
+ FT_UInt glyph_index )
+ {
+ return scale_test_tweak( face, family, ppem, style, glyph_index,
+ X_SCALING_Rules, X_SCALING_RULES_SIZE );
+ }
+
+
+#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( ALWAYS_DO_DELTAP );
+ TWEAK_RULES( ALWAYS_SKIP_DELTAP );
+ TWEAK_RULES( DEEMBOLDEN );
+ 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_IUP );
+
+ TWEAK_RULES( SKIP_OFFPIXEL_Y_MOVES );
+ TWEAK_RULES_EXCEPTIONS( SKIP_OFFPIXEL_Y_MOVES );
+
+ TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES_DELTAP );
+
+ 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 )
+ {
+ if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 )
+ {
+ loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
+ loader->exec->size->cvt_ready = FALSE;
+
+ tt_size_ready_bytecode(
+ loader->exec->size,
+ FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) );
+ }
+ else
+ loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
+ }
+ else
+ {
+ if ( loader->exec->rasterizer_version !=
+ SPH_OPTION_SET_RASTERIZER_VERSION )
+ {
+ loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
+ loader->exec->size->cvt_ready = FALSE;
+
+ tt_size_ready_bytecode(
+ loader->exec->size,
+ FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) );
+ }
+ else
+ loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
+ }
+
+ 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->face->sph_compatibility_mode = TRUE;
+
+
+ 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;
+ }
+ }
+
+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+ /* ANSI C doesn't like empty source files */
+ typedef int _tt_subpix_dummy;
+
+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+
+/* END */
diff --git a/src/truetype/ttsubpix.h b/src/truetype/ttsubpix.h
new file mode 100644
index 0000000..8a54fc7
--- /dev/null
+++ b/src/truetype/ttsubpix.h
@@ -0,0 +1,110 @@
+/***************************************************************************/
+/* */
+/* ttsubpix.h */
+/* */
+/* TrueType Subpixel Hinting. */
+/* */
+/* Copyright 2010-2013 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __TTSUBPIX_H__
+#define __TTSUBPIX_H__
+
+#include <ft2build.h>
+#include "ttobjs.h"
+#include "ttinterp.h"
+
+
+FT_BEGIN_HEADER
+
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ /*************************************************************************/
+ /* */
+ /* ID flags to identify special functions at FDEF and runtime. */
+ /* */
+ /* */
+#define SPH_FDEF_INLINE_DELTA_1 0x0000001
+#define SPH_FDEF_INLINE_DELTA_2 0x0000002
+#define SPH_FDEF_DIAGONAL_STROKE 0x0000004
+#define SPH_FDEF_VACUFORM_ROUND_1 0x0000008
+#define SPH_FDEF_TTFAUTOHINT_1 0x0000010
+#define SPH_FDEF_SPACING_1 0x0000020
+#define SPH_FDEF_SPACING_2 0x0000040
+#define SPH_FDEF_TYPEMAN_STROKES 0x0000080
+#define SPH_FDEF_TYPEMAN_DIAGENDCTRL 0x0000100
+
+
+ /*************************************************************************/
+ /* */
+ /* Tweak flags that are set for each glyph by the below rules. */
+ /* */
+ /* */
+#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001
+#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000002
+#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000004
+#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000008
+#define SPH_TWEAK_DEEMBOLDEN 0x0000010
+#define SPH_TWEAK_DO_SHPIX 0x0000020
+#define SPH_TWEAK_EMBOLDEN 0x0000040
+#define SPH_TWEAK_MIAP_HACK 0x0000080
+#define SPH_TWEAK_NORMAL_ROUND 0x0000100
+#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0000200
+#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0000400
+#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0000800
+#define SPH_TWEAK_PIXEL_HINTING 0x0001000
+#define SPH_TWEAK_RASTERIZER_35 0x0002000
+#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0004000
+#define SPH_TWEAK_SKIP_IUP 0x0008000
+#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0010000
+#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0020000
+#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0040000
+#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP 0x0080000
+
+
+ FT_LOCAL( FT_Bool )
+ sph_test_tweak( TT_Face face,
+ const FT_String* family,
+ FT_UInt ppem,
+ const FT_String* style,
+ FT_UInt glyph_index,
+ const SPH_TweakRule* rule,
+ FT_UInt num_rules );
+
+ FT_LOCAL( FT_UInt )
+ sph_test_tweak_x_scaling( TT_Face face,
+ const FT_String* family,
+ FT_UInt ppem,
+ const FT_String* style,
+ FT_UInt glyph_index );
+
+ FT_LOCAL( void )
+ sph_set_tweaks( TT_Loader loader,
+ FT_UInt glyph_index );
+
+
+ /* 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
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+
+FT_END_HEADER
+
+#endif /* __TTSUBPIX_H__ */
+
+/* END */