From 295ffce55e0198e7a9f7d46b33f5c2b4147bf821 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Wed, 3 Mar 2010 14:24:57 -0800 Subject: Update to FreeType 2.3.12 --- Android.mk | 4 +- include/freetype/config/ftconfig.h | 36 +- include/freetype/config/ftoption.h | 31 +- include/freetype/config/ftstdlib.h | 1 + include/freetype/freetype.h | 35 +- include/freetype/ftglyph.h | 2 +- include/freetype/ftimage.h | 101 +++-- include/freetype/ftincrem.h | 8 +- include/freetype/ftmodapi.h | 6 +- include/freetype/ftoutln.h | 7 +- include/freetype/ftsnames.h | 34 +- include/freetype/ftstroke.h | 2 +- include/freetype/fttypes.h | 1 + include/freetype/ftxf86.h | 3 + include/freetype/internal/autohint.h | 26 ++ include/freetype/internal/ftcalc.h | 3 +- include/freetype/internal/ftdriver.h | 173 ++++++++ include/freetype/internal/ftgloadr.h | 18 +- include/freetype/internal/ftobjs.h | 526 +++++++++++++++++++++++ include/freetype/internal/ftpic.h | 67 +++ include/freetype/internal/ftserv.h | 292 +++++++++++++ include/freetype/internal/fttrace.h | 5 + include/freetype/internal/internal.h | 1 + include/freetype/internal/psaux.h | 13 +- include/freetype/internal/pshints.h | 47 +- include/freetype/internal/services/svbdf.h | 20 + include/freetype/internal/services/svcid.h | 25 ++ include/freetype/internal/services/svgldict.h | 22 + include/freetype/internal/services/svmm.h | 25 ++ include/freetype/internal/services/svpostnm.h | 21 + include/freetype/internal/services/svpscmap.h | 37 +- include/freetype/internal/services/svpsinfo.h | 27 ++ include/freetype/internal/services/svsfnt.h | 22 + include/freetype/internal/services/svttcmap.h | 23 +- include/freetype/internal/services/svttglyf.h | 19 + include/freetype/internal/sfnt.h | 135 ++++++ include/freetype/internal/t1types.h | 6 +- include/freetype/internal/tttypes.h | 4 +- src/autofit/afcjk.c | 67 ++- src/autofit/afcjk.h | 3 +- src/autofit/afdummy.c | 6 +- src/autofit/afdummy.h | 3 +- src/autofit/afglobal.c | 63 ++- src/autofit/afglobal.h | 6 +- src/autofit/afhints.c | 9 +- src/autofit/afindic.c | 18 +- src/autofit/afindic.h | 3 +- src/autofit/aflatin.c | 126 ++++-- src/autofit/aflatin.h | 9 +- src/autofit/aflatin2.c | 76 +++- src/autofit/aflatin2.h | 3 +- src/autofit/afloader.c | 24 +- src/autofit/afmodule.c | 15 +- src/autofit/afmodule.h | 4 +- src/autofit/afpic.c | 92 ++++ src/autofit/afpic.h | 64 +++ src/autofit/aftypes.h | 55 ++- src/autofit/autofit.c | 1 + src/base/basepic.c | 83 ++++ src/base/basepic.h | 62 +++ src/base/ftadvanc.c | 2 +- src/base/ftbase.c | 6 +- src/base/ftbase.h | 6 +- src/base/ftbbox.c | 27 +- src/base/ftbitmap.c | 8 +- src/base/ftcalc.c | 34 +- src/base/ftdbgmem.c | 4 +- src/base/ftgloadr.c | 7 + src/base/ftglyph.c | 27 +- src/base/ftinit.c | 111 ++++- src/base/ftnames.c | 94 ---- src/base/ftobjs.c | 148 ++++++- src/base/ftoutln.c | 4 +- src/base/ftpatent.c | 17 +- src/base/ftpic.c | 54 +++ src/base/ftrfork.c | 4 +- src/base/ftsnames.c | 94 ++++ src/base/ftstream.c | 56 +-- src/base/ftstroke.c | 64 ++- src/base/ftsynth.c | 29 +- src/base/ftsystem.c | 9 +- src/base/fttrigon.c | 10 +- src/cff/cff.c | 1 + src/cff/cffcmap.c | 17 +- src/cff/cffcmap.h | 6 +- src/cff/cffdrivr.c | 121 +++--- src/cff/cffdrivr.h | 3 +- src/cff/cffgload.c | 261 ++++++++---- src/cff/cffgload.h | 16 +- src/cff/cffload.c | 70 ++- src/cff/cffload.h | 3 +- src/cff/cffobjs.c | 61 +-- src/cff/cffparse.c | 161 +++++-- src/cff/cffparse.h | 35 +- src/cff/cffpic.c | 99 +++++ src/cff/cffpic.h | 80 ++++ src/cff/cfftypes.h | 2 +- src/psaux/afmparse.c | 31 +- src/psaux/afmparse.h | 4 +- src/psaux/psauxmod.h | 4 + src/psaux/psconv.c | 10 +- src/psaux/psconv.h | 6 +- src/psaux/psobjs.c | 39 +- src/psaux/psobjs.h | 2 +- src/psaux/t1cmap.c | 8 +- src/psaux/t1decode.c | 360 ++++++++++------ src/pshinter/pshalgo.c | 14 +- src/pshinter/pshinter.c | 1 + src/pshinter/pshmod.c | 17 +- src/pshinter/pshmod.h | 2 +- src/pshinter/pshpic.c | 67 +++ src/pshinter/pshpic.h | 53 +++ src/pshinter/pshrec.c | 101 +++-- src/psnames/psmodule.c | 73 ++-- src/psnames/psmodule.h | 2 +- src/psnames/psnames.c | 1 + src/psnames/pspic.c | 77 ++++ src/psnames/pspic.h | 54 +++ src/raster/ftmisc.h | 25 ++ src/raster/ftraster.c | 578 +++++++++++++++---------- src/raster/ftrend1.c | 46 +- src/raster/ftrend1.h | 4 +- src/raster/raster.c | 1 + src/raster/rastpic.c | 89 ++++ src/raster/rastpic.h | 50 +++ src/sfnt/sfdriver.c | 194 +++++---- src/sfnt/sfdriver.h | 2 +- src/sfnt/sfnt.c | 1 + src/sfnt/sfntpic.c | 101 +++++ src/sfnt/sfntpic.h | 88 ++++ src/sfnt/sfobjs.c | 35 +- src/sfnt/ttbdf.c | 16 +- src/sfnt/ttcmap.c | 591 ++++++++++++++++++++------ src/sfnt/ttcmap.h | 40 ++ src/sfnt/ttcmapc.h | 55 +++ src/sfnt/ttkern.c | 13 +- src/sfnt/ttload.c | 25 +- src/sfnt/ttmtx.c | 6 +- src/sfnt/ttpost.c | 3 +- src/sfnt/ttsbit.c | 2 +- src/sfnt/ttsbit0.c | 56 ++- src/smooth/ftgrays.c | 137 +++--- src/smooth/ftgrays.h | 1 + src/smooth/ftsmooth.c | 64 +-- src/smooth/ftsmooth.h | 8 +- src/smooth/ftspic.c | 97 +++++ src/smooth/ftspic.h | 50 +++ src/smooth/smooth.c | 1 + src/truetype/truetype.c | 1 + src/truetype/ttdriver.c | 91 ++-- src/truetype/ttdriver.h | 2 +- src/truetype/ttgload.c | 317 ++++++++------ src/truetype/ttgxvar.c | 83 ++-- src/truetype/ttgxvar.h | 2 +- src/truetype/ttinterp.c | 54 ++- src/truetype/ttobjs.c | 20 +- src/truetype/ttobjs.h | 38 +- src/truetype/ttpic.c | 79 ++++ src/truetype/ttpic.h | 59 +++ src/truetype/ttpload.c | 34 +- 160 files changed, 6556 insertions(+), 1900 deletions(-) create mode 100644 include/freetype/internal/ftpic.h create mode 100644 src/autofit/afpic.c create mode 100644 src/autofit/afpic.h create mode 100644 src/base/basepic.c create mode 100644 src/base/basepic.h delete mode 100644 src/base/ftnames.c create mode 100644 src/base/ftpic.c create mode 100644 src/base/ftsnames.c create mode 100644 src/cff/cffpic.c create mode 100644 src/cff/cffpic.h create mode 100644 src/pshinter/pshpic.c create mode 100644 src/pshinter/pshpic.h create mode 100644 src/psnames/pspic.c create mode 100644 src/psnames/pspic.h create mode 100644 src/raster/rastpic.c create mode 100644 src/raster/rastpic.h create mode 100644 src/sfnt/sfntpic.c create mode 100644 src/sfnt/sfntpic.h create mode 100644 src/sfnt/ttcmapc.h create mode 100644 src/smooth/ftspic.c create mode 100644 src/smooth/ftspic.h create mode 100644 src/truetype/ttpic.c create mode 100644 src/truetype/ttpic.h diff --git a/Android.mk b/Android.mk index ee6f253..12c0b6a 100644 --- a/Android.mk +++ b/Android.mk @@ -1,10 +1,10 @@ # this is now the default FreeType build for Android # ifndef USE_FREETYPE -USE_FREETYPE := 2.3.9 +USE_FREETYPE := 2.3.12 endif -ifeq ($(USE_FREETYPE),2.3.9) +ifeq ($(USE_FREETYPE),2.3.12) LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) diff --git a/include/freetype/config/ftconfig.h b/include/freetype/config/ftconfig.h index 3c0b8b1..43d587e 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-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,6 @@ /* */ /*************************************************************************/ - #ifndef __FTCONFIG_H__ #define __FTCONFIG_H__ @@ -306,9 +305,38 @@ FT_BEGIN_HEADER /* Provide assembler fragments for performance-critical functions. */ /* These must be defined `static __inline__' with GCC. */ +#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 t, t2; + + + __asm + { + smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ + mov a, t, asr #31 /* a = (hi >> 31) */ + add a, a, #0x8000 /* a += 0x8000 */ + adds t2, t2, a /* t2 += a */ + adc t, t, #0 /* t += carry */ + mov a, t2, lsr #16 /* a = t2 >> 16 */ + orr a, a, t, lsl #16 /* a |= t << 16 */ + } + return a; + } + +#endif /* __CC_ARM || __ARMCC__ */ + + #ifdef __GNUC__ -#if defined( __arm__ ) && !defined( __thumb__ ) +#if defined( __arm__ ) && !defined( __thumb__ ) && \ + !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) #define FT_MULFIX_ASSEMBLER FT_MulFix_arm /* documentation is in freetype.h */ @@ -333,7 +361,7 @@ FT_BEGIN_HEADER return a; } -#endif /* __arm__ && !__thumb__ */ +#endif /* __arm__ && !__thumb__ && !( __CC_ARM || __ARMCC__ ) */ #if defined( i386 ) #define FT_MULFIX_ASSEMBLER FT_MulFix_i386 diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h index 597a2bb..0258e1b 100644 --- a/include/freetype/config/ftoption.h +++ b/include/freetype/config/ftoption.h @@ -4,7 +4,8 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,9 +86,9 @@ FT_BEGIN_HEADER /* */ /* This macro has no impact on the FreeType API, only on its */ /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ - /* FT_Render_Glyph still generates a bitmap that is 3 times larger than */ - /* the original size; the difference will be that each triplet of */ - /* subpixels has R=G=B. */ + /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ + /* the original size in case this macro isn't defined; however, each */ + /* triplet of subpixels has R=G=B. */ /* */ /* This is done to allow FreeType clients to run unmodified, forcing */ /* them to display normal gray-level anti-aliased glyphs. */ @@ -312,8 +313,9 @@ FT_BEGIN_HEADER /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ /* contain no glyph data, but supply it via a callback function. */ - /* This allows FreeType to be used with the PostScript language, using */ - /* the GhostScript interpreter. */ + /* This is required by clients supporting document formats which */ + /* supply font data incrementally as the document is parsed, such */ + /* as the Ghostscript interpreter for the PostScript language. */ /* */ /* #define FT_CONFIG_OPTION_INCREMENTAL */ @@ -396,6 +398,20 @@ FT_BEGIN_HEADER #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + /*************************************************************************/ + /* */ + /* Position Independent Code */ + /* */ + /* If this macro is set (which is _not_ the default), FreeType2 will */ + /* avoid creating constants that require address fixups. Instead the */ + /* constants will be moved into a struct and additional intialization */ + /* code will be used. */ + /* */ + /* Setting this macro is needed for systems that prohibit address */ + /* fixups, such as BREW. */ + /* */ +/* #define FT_CONFIG_OPTION_PIC */ + /*************************************************************************/ /*************************************************************************/ @@ -439,7 +455,7 @@ FT_BEGIN_HEADER /* does not contain any glyph name though. */ /* */ /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftnames.h'. */ + /* `freetype/ftsnames.h'. */ /* */ #define TT_CONFIG_OPTION_SFNT_NAMES @@ -457,6 +473,7 @@ FT_BEGIN_HEADER #define TT_CONFIG_CMAP_FORMAT_8 #define TT_CONFIG_CMAP_FORMAT_10 #define TT_CONFIG_CMAP_FORMAT_12 +#define TT_CONFIG_CMAP_FORMAT_13 #define TT_CONFIG_CMAP_FORMAT_14 diff --git a/include/freetype/config/ftstdlib.h b/include/freetype/config/ftstdlib.h index ce5557a..30ec14e 100644 --- a/include/freetype/config/ftstdlib.h +++ b/include/freetype/config/ftstdlib.h @@ -61,6 +61,7 @@ #define FT_CHAR_BIT CHAR_BIT #define FT_INT_MAX INT_MAX +#define FT_INT_MIN INT_MIN #define FT_UINT_MAX UINT_MAX #define FT_ULONG_MAX ULONG_MAX diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 364388b..942a740 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -4,7 +4,8 @@ /* */ /* FreeType high-level API and common types (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -231,6 +232,10 @@ FT_BEGIN_HEADER /* vertAdvance :: */ /* Advance height for vertical layout. */ /* */ + /* */ + /* If not disabled with @FT_LOAD_NO_HINTING, the values represent */ + /* dimensions of the hinted glyph (in case hinting is applicable). */ + /* */ typedef struct FT_Glyph_Metrics_ { FT_Pos width; @@ -519,10 +524,7 @@ FT_BEGIN_HEADER /* */ /* Despite the name, this enumeration lists specific character */ /* repertories (i.e., charsets), and not text encoding methods (e.g., */ - /* UTF-8, UTF-16, GB2312_EUC, etc.). */ - /* */ - /* Because of 32-bit charcodes defined in Unicode (i.e., surrogates), */ - /* all character codes must be expressed as FT_Longs. */ + /* UTF-8, UTF-16, etc.). */ /* */ /* Other encodings might be defined in the future. */ /* */ @@ -536,6 +538,10 @@ FT_BEGIN_HEADER /* Latin-1. Most fonts include a Unicode charmap, but not all */ /* of them. */ /* */ + /* For example, if you want to access Unicode value U+1F028 (and */ + /* the font contains it), use value 0x1F028 as the input value for */ + /* @FT_Get_Char_Index. */ + /* */ /* FT_ENCODING_MS_SYMBOL :: */ /* Corresponds to the Microsoft Symbol encoding, used to encode */ /* mathematical symbols in the 32..255 character code range. For */ @@ -1476,8 +1482,13 @@ FT_BEGIN_HEADER /* important to perform correct WYSIWYG layout. */ /* Only relevant for outline glyphs. */ /* */ - /* advance :: This is the transformed advance width for the */ - /* glyph (in 26.6 fractional pixel format). */ + /* advance :: This shorthand is, depending on */ + /* @FT_LOAD_IGNORE_TRANSFORM, the transformed */ + /* advance width for the glyph (in 26.6 */ + /* fractional pixel format). As specified with */ + /* @FT_LOAD_VERTICAL_LAYOUT, it uses either the */ + /* `horiAdvance' or the `vertAdvance' value of */ + /* `metrics' field. */ /* */ /* format :: This field indicates the format of the image */ /* contained in the glyph slot. Typically */ @@ -1651,6 +1662,11 @@ FT_BEGIN_HEADER /* */ /* FreeType error code. 0~means success. */ /* */ + /* */ + /* In case you want to provide your own memory allocating routines, */ + /* use @FT_New_Library instead, followed by a call to */ + /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */ + /* */ FT_EXPORT( FT_Error ) FT_Init_FreeType( FT_Library *alibrary ); @@ -1737,7 +1753,8 @@ FT_BEGIN_HEADER /* data :: A pointer to the parameter data. */ /* */ /* */ - /* The ID and function of parameters are driver-specific. */ + /* The ID and function of parameters are driver-specific. See the */ + /* various FT_PARAM_TAG_XXX flags for more information. */ /* */ typedef struct FT_Parameter_ { @@ -3757,7 +3774,7 @@ FT_BEGIN_HEADER */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 3 -#define FREETYPE_PATCH 9 +#define FREETYPE_PATCH 12 /*************************************************************************/ diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h index cacccf0..0b8f0c0 100644 --- a/include/freetype/ftglyph.h +++ b/include/freetype/ftglyph.h @@ -468,7 +468,7 @@ FT_BEGIN_HEADER /* // convert to a bitmap (default render mode + destroying old) */ /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ /* { */ - /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_DEFAULT, */ + /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, */ /* 0, 1 ); */ /* if ( error ) // `glyph' unchanged */ /* ... */ diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h index ccc2f71..0272e92 100644 --- a/include/freetype/ftimage.h +++ b/include/freetype/ftimage.h @@ -5,7 +5,8 @@ /* FreeType glyph image formats and default raster interface */ /* (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -51,10 +52,9 @@ FT_BEGIN_HEADER /* FT_Pos */ /* */ /* */ - /* The type FT_Pos is a 32-bit integer 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. */ + /* 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. */ /* */ typedef signed long FT_Pos; @@ -99,6 +99,20 @@ FT_BEGIN_HEADER /* */ /* yMax :: The vertical maximum (top-most). */ /* */ + /* */ + /* The bounding box is specified with the coordinates of the lower */ + /* left and the upper right corner. In PostScript, those values are */ + /* often called (llx,lly) and (urx,ury), respectively. */ + /* */ + /* If `yMin' is negative, this value gives the glyph's descender. */ + /* Otherwise, the glyph doesn't descend below the baseline. */ + /* Similarly, if `ymax' is positive, this value gives the glyph's */ + /* ascender. */ + /* */ + /* `xMin' gives the horizontal distance from the glyph's origin to */ + /* the left edge of the glyph's bounding box. If `xMin' is negative, */ + /* the glyph extends to the left of the origin. */ + /* */ typedef struct FT_BBox_ { FT_Pos xMin, yMin; @@ -254,6 +268,9 @@ FT_BEGIN_HEADER /* flow. In all cases, the pitch is an offset to add */ /* to a bitmap pointer in order to go down one row. */ /* */ + /* For the B/W rasterizer, `pitch' is always an even */ + /* number. */ + /* */ /* buffer :: A typeless pointer to the bitmap buffer. This */ /* value should be aligned on 32-bit boundaries in */ /* most cases. */ @@ -318,14 +335,23 @@ FT_BEGIN_HEADER /* elements, giving the outline's point coordinates. */ /* */ /* tags :: A pointer to an array of `n_points' chars, giving */ - /* each outline point's type. If bit~0 is unset, the */ - /* point is `off' the curve, i.e., a Bézier control */ - /* point, while it is `on' when set. */ + /* each outline point's type. */ + /* */ + /* If bit~0 is unset, the point is `off' the curve, */ + /* i.e., a Bézier control point, while it is `on' if */ + /* set. */ /* */ /* Bit~1 is meaningful for `off' points only. If set, */ /* it indicates a third-order Bézier arc control point; */ /* and a second-order control point if unset. */ /* */ + /* If bit~2 is set, bits 5-7 contain the drop-out mode */ + /* (as defined in the OpenType specification; the value */ + /* is the same as the argument to the SCANMODE */ + /* instruction). */ + /* */ + /* Bits 3 and~4 are reserved for internal purposes. */ + /* */ /* contours :: An array of `n_contours' shorts, giving the end */ /* point of each contour within the outline. For */ /* example, the first contour is defined by the points */ @@ -336,6 +362,12 @@ FT_BEGIN_HEADER /* and give hints to the scan-converter and hinter on */ /* how to convert/grid-fit it. See @FT_OUTLINE_FLAGS. */ /* */ + /* */ + /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ + /* first point of each contour. The drop-out mode as given with */ + /* @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and */ + /* @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden. */ + /* */ typedef struct FT_Outline_ { short n_contours; /* number of contours in glyph */ @@ -349,6 +381,11 @@ FT_BEGIN_HEADER } FT_Outline; + /* Following limits must be consistent with */ + /* FT_Outline.{n_contours,n_points} */ +#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX +#define FT_OUTLINE_POINTS_MAX SHRT_MAX + /*************************************************************************/ /* */ @@ -371,7 +408,7 @@ FT_BEGIN_HEADER /* FT_OUTLINE_EVEN_ODD_FILL :: */ /* By default, outlines are filled using the non-zero winding rule. */ /* If set to 1, the outline will be filled using the even-odd fill */ - /* rule (only works with the smooth raster). */ + /* rule (only works with the smooth rasterizer). */ /* */ /* FT_OUTLINE_REVERSE_FILL :: */ /* By default, outside contours of an outline are oriented in */ @@ -384,15 +421,17 @@ FT_BEGIN_HEADER /* By default, the scan converter will try to detect drop-outs in */ /* an outline and correct the glyph bitmap to ensure consistent */ /* shape continuity. If set, this flag hints the scan-line */ - /* converter to ignore such cases. */ + /* converter to ignore such cases. See below for more information. */ /* */ /* FT_OUTLINE_SMART_DROPOUTS :: */ /* Select smart dropout control. If unset, use simple dropout */ - /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. */ + /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See */ + /* below for more information. */ /* */ /* FT_OUTLINE_INCLUDE_STUBS :: */ /* If set, turn pixels on for `stubs', otherwise exclude them. */ - /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. */ + /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for */ + /* more information. */ /* */ /* FT_OUTLINE_HIGH_PRECISION :: */ /* This flag indicates that the scan-line converter should try to */ @@ -409,6 +448,13 @@ FT_BEGIN_HEADER /* scan-converter. */ /* */ /* */ + /* The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */ + /* and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth */ + /* rasterizer. */ + /* */ + /* There exists a second mechanism to pass the drop-out mode to the */ + /* B/W rasterizer; see the `tags' field in @FT_Outline. */ + /* */ /* Please refer to the description of the `SCANTYPE' instruction in */ /* the OpenType specification (in file `ttinst1.doc') how simple */ /* drop-outs, smart drop-outs, and stubs are defined. */ @@ -455,15 +501,17 @@ FT_BEGIN_HEADER #define FT_CURVE_TAG( flag ) ( flag & 3 ) -#define FT_CURVE_TAG_ON 1 -#define FT_CURVE_TAG_CONIC 0 -#define FT_CURVE_TAG_CUBIC 2 +#define FT_CURVE_TAG_ON 1 +#define FT_CURVE_TAG_CONIC 0 +#define FT_CURVE_TAG_CUBIC 2 + +#define FT_CURVE_TAG_HAS_SCANMODE 4 -#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ -#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ -#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ - FT_CURVE_TAG_TOUCH_Y ) +#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ + FT_CURVE_TAG_TOUCH_Y ) #define FT_Curve_Tag_On FT_CURVE_TAG_ON #define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC @@ -532,8 +580,8 @@ FT_BEGIN_HEADER /* FT_Outline_ConicToFunc */ /* */ /* */ - /* A function pointer type use to describe the signature of a `conic */ - /* to' function during outline walking/decomposition. */ + /* A function pointer type used to describe the signature of a `conic */ + /* to' function during outline walking or decomposition. */ /* */ /* A `conic to' is emitted to indicate a second-order Bézier arc in */ /* the outline. */ @@ -565,7 +613,7 @@ FT_BEGIN_HEADER /* */ /* */ /* A function pointer type used to describe the signature of a `cubic */ - /* to' function during outline walking/decomposition. */ + /* to' function during outline walking or decomposition. */ /* */ /* A `cubic to' is emitted to indicate a third-order Bézier arc. */ /* */ @@ -598,8 +646,7 @@ FT_BEGIN_HEADER /* */ /* */ /* A structure to hold various function pointers used during outline */ - /* decomposition in order to emit segments, conic, and cubic Béziers, */ - /* as well as `move to' and `close to' operations. */ + /* decomposition in order to emit segments, conic, and cubic Béziers. */ /* */ /* */ /* move_to :: The `move to' emitter. */ @@ -626,7 +673,7 @@ FT_BEGIN_HEADER /* y' = (x << shift) - delta */ /* } */ /* */ - /* Set the value of `shift' and `delta' to~0 to get the original */ + /* Set the values of `shift' and `delta' to~0 to get the original */ /* point coordinates. */ /* */ typedef struct FT_Outline_Funcs_ @@ -1011,7 +1058,7 @@ FT_BEGIN_HEADER /* */ /* gray_spans :: The gray span drawing callback. */ /* */ - /* black_spans :: The black span drawing callback. */ + /* black_spans :: The black span drawing callback. UNIMPLEMENTED! */ /* */ /* bit_test :: The bit test callback. UNIMPLEMENTED! */ /* */ @@ -1048,7 +1095,7 @@ FT_BEGIN_HEADER const void* source; int flags; FT_SpanFunc gray_spans; - FT_SpanFunc black_spans; + FT_SpanFunc black_spans; /* doesn't work! */ FT_Raster_BitTest_Func bit_test; /* doesn't work! */ FT_Raster_BitSet_Func bit_set; /* doesn't work! */ void* user; diff --git a/include/freetype/ftincrem.h b/include/freetype/ftincrem.h index 96abede..aaf689f 100644 --- a/include/freetype/ftincrem.h +++ b/include/freetype/ftincrem.h @@ -4,7 +4,7 @@ /* */ /* FreeType incremental loading (specification). */ /* */ -/* Copyright 2002, 2003, 2006, 2007, 2008 by */ +/* Copyright 2002, 2003, 2006, 2007, 2008, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -101,7 +101,10 @@ FT_BEGIN_HEADER * Top bearing, in font units. * * advance :: - * Glyph advance, in font units. + * Horizontal component of glyph advance, in font units. + * + * advance_v :: + * Vertical component of glyph advance, in font units. * * @note: * These correspond to horizontal or vertical metrics depending on the @@ -114,6 +117,7 @@ FT_BEGIN_HEADER FT_Long bearing_x; FT_Long bearing_y; FT_Long advance; + FT_Long advance_v; /* since 2.3.12 */ } FT_Incremental_MetricsRec; diff --git a/include/freetype/ftmodapi.h b/include/freetype/ftmodapi.h index b051d34..3c9b876 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 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -259,6 +259,10 @@ FT_BEGIN_HEADER /* from a given memory object. It is thus possible to use libraries */ /* with distinct memory allocators within the same program. */ /* */ + /* Normally, you would call this function (followed by a call to */ + /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ + /* instead of @FT_Init_FreeType to initialize the FreeType library. */ + /* */ /* */ /* memory :: A handle to the original memory object. */ /* */ diff --git a/include/freetype/ftoutln.h b/include/freetype/ftoutln.h index d7d01e8..2829a05 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-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,9 +85,8 @@ FT_BEGIN_HEADER /* */ /* */ /* Walk over an outline's structure to decompose it into individual */ - /* segments and Bézier arcs. This function is also able to emit */ - /* `move to' and `close to' operations to indicate the start and end */ - /* of new contours in the outline. */ + /* segments and Bézier arcs. This function also emits `move to' */ + /* operations to indicate the start of new contours in the outline. */ /* */ /* */ /* outline :: A pointer to the source target. */ diff --git a/include/freetype/ftsnames.h b/include/freetype/ftsnames.h index 477e1e3..485e4e1 100644 --- a/include/freetype/ftsnames.h +++ b/include/freetype/ftsnames.h @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -147,7 +147,8 @@ FT_BEGIN_HEADER /* */ /* */ /* The `string' array returned in the `aname' structure is not */ - /* null-terminated. */ + /* null-terminated. The application should deallocate it if it is no */ + /* longer in use. */ /* */ /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ /* `name' table entries, then do a loop until you get the right */ @@ -159,6 +160,35 @@ FT_BEGIN_HEADER FT_SfntName *aname ); + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred family subfamily names in `name' + * table since OpenType version 1.4. For backwards compatibility with + * legacy systems which has 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred subfamily names in `name' table since + * OpenType version 1.4. For backwards compatibility with legacy + * systems which has 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG( 'i', 'g', 'p', 's' ) + /* */ diff --git a/include/freetype/ftstroke.h b/include/freetype/ftstroke.h index ae90500..3afb87d 100644 --- a/include/freetype/ftstroke.h +++ b/include/freetype/ftstroke.h @@ -598,7 +598,7 @@ FT_BEGIN_HEADER * * @description: * Call this function after @FT_Stroker_GetBorderCounts to - * export the all borders to your own @FT_Outline structure. + * export all borders to your own @FT_Outline structure. * * Note that this function appends the border points and * contours to your outline, but does not try to resize its diff --git a/include/freetype/fttypes.h b/include/freetype/fttypes.h index 54f08e3..e78012d 100644 --- a/include/freetype/fttypes.h +++ b/include/freetype/fttypes.h @@ -474,6 +474,7 @@ FT_BEGIN_HEADER /* this macro. */ /* */ #define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + (FT_Tag) \ ( ( (FT_ULong)_x1 << 24 ) | \ ( (FT_ULong)_x2 << 16 ) | \ ( (FT_ULong)_x3 << 8 ) | \ diff --git a/include/freetype/ftxf86.h b/include/freetype/ftxf86.h index ae9ff07..8c68afd 100644 --- a/include/freetype/ftxf86.h +++ b/include/freetype/ftxf86.h @@ -49,6 +49,9 @@ FT_BEGIN_HEADER /* however, there are special cases (like in PDF devices) where it is */ /* important to differentiate, in spite of FreeType's uniform API. */ /* */ + /* This function is in the X11/xf86 namespace for historical reasons */ + /* and in no way depends on that windowing system. */ + /* */ /*************************************************************************/ diff --git a/include/freetype/internal/autohint.h b/include/freetype/internal/autohint.h index ee00402..7e3a08a 100644 --- a/include/freetype/internal/autohint.h +++ b/include/freetype/internal/autohint.h @@ -196,6 +196,32 @@ FT_BEGIN_HEADER } FT_AutoHinter_ServiceRec, *FT_AutoHinter_Service; +#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_ \ + }; + +#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_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/include/freetype/internal/ftcalc.h b/include/freetype/internal/ftcalc.h index 58def34..f8b4324 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 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -165,6 +165,7 @@ FT_BEGIN_HEADER #define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) #define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) #define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) +#define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 ) #define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ : ( -( ( 32 - (x) ) & -64 ) ) ) diff --git a/include/freetype/internal/ftdriver.h b/include/freetype/internal/ftdriver.h index 854abad..1d06997 100644 --- a/include/freetype/internal/ftdriver.h +++ b/include/freetype/internal/ftdriver.h @@ -240,6 +240,179 @@ FT_BEGIN_HEADER #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + /*************************************************************************/ + /* */ + /* */ + /* FT_DECLARE_DRIVER */ + /* */ + /* */ + /* Used to create a forward declaration of a */ + /* FT_Driver_ClassRec stract instance. */ + /* */ + /* */ + /* FT_DEFINE_DRIVER */ + /* */ + /* */ + /* 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 */ + /* */ + /* 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 */ + /* 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. */ + /* */ + /* 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 + +#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_) \ + 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_ \ + }; + +#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 class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + 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; \ + } + + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/include/freetype/internal/ftgloadr.h b/include/freetype/internal/ftgloadr.h index 548481a..ce4dc6c 100644 --- a/include/freetype/internal/ftgloadr.h +++ b/include/freetype/internal/ftgloadr.h @@ -121,15 +121,15 @@ FT_BEGIN_HEADER FT_UInt n_contours ); -#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ - ( (_count) == 0 || (int)((_loader)->base.outline.n_points + \ - (_loader)->current.outline.n_points + \ - (_count)) <= (int)(_loader)->max_points ) - -#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ - ( (_count) == 0 || (int)((_loader)->base.outline.n_contours + \ - (_loader)->current.outline.n_contours + \ - (_count)) <= (int)(_loader)->max_contours ) +#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_points + \ + (_loader)->current.outline.n_points + \ + (unsigned long)(_count)) <= (_loader)->max_points ) + +#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_contours + \ + (_loader)->current.outline.n_contours + \ + (unsigned long)(_count)) <= (_loader)->max_contours ) #define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours ) \ ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index 1f22343..574cf58 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -35,6 +35,7 @@ #include FT_INTERNAL_DRIVER_H #include FT_INTERNAL_AUTOHINT_H #include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_PIC_H #ifdef FT_CONFIG_OPTION_INCREMENTAL #include FT_INCREMENTAL_H @@ -205,6 +206,45 @@ 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_ \ + }; +#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_; \ + } +#endif /* FT_CONFIG_OPTION_PIC */ /* create a new charmap and add it to charmap->face */ FT_BASE( FT_Error ) @@ -765,6 +805,10 @@ FT_BEGIN_HEADER /* */ /* debug_hooks :: XXX */ /* */ + /* pic_container :: Contains global structs and tables, instead */ + /* of defining them globallly. */ + /* */ + typedef struct FT_LibraryRec_ { FT_Memory memory; /* library's memory manager */ @@ -795,6 +839,10 @@ FT_BEGIN_HEADER FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ #endif +#ifdef FT_CONFIG_OPTION_PIC + FT_PIC_Container pic_container; +#endif + } FT_LibraryRec; @@ -866,6 +914,484 @@ FT_BEGIN_HEADER FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster; #endif + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftimage.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* FT_DEFINE_OUTLINE_FUNCS */ + /* */ + /* */ + /* 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. */ + /* 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_ \ + }; + +#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; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /* */ + /* */ + /* FT_DEFINE_RASTER_FUNCS */ + /* */ + /* */ + /* 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. */ + /* 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_ \ + }; + +#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_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftrender.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + + /*************************************************************************/ + /* */ + /* */ + /* FT_DEFINE_GLYPH */ + /* */ + /* */ + /* 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. */ + /* 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_ \ + }; + +#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_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /* */ + /* */ + /* FT_DECLARE_RENDERER */ + /* */ + /* */ + /* Used to create a forward declaration of a */ + /* FT_Renderer_Class stract instance. */ + /* */ + /* */ + /* FT_DEFINE_RENDERER */ + /* */ + /* */ + /* 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 */ + /* 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 */ + /* 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. */ + /* */ + /* 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_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 class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + 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; \ + } + + + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftmodapi.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifdef FT_CONFIG_OPTION_PIC + + /*************************************************************************/ + /* */ + /* */ + /* FT_Module_Creator */ + /* */ + /* */ + /* A function used to create (allocate) a new module class object. */ + /* The object's members are initialized, but the module itself is */ + /* not. */ + /* */ + /* */ + /* memory :: A handle to the memory manager. */ + /* output_class :: Initialized with the newly allocated class. */ + /* */ + typedef FT_Error + (*FT_Module_Creator)( FT_Memory memory, + FT_Module_Class** output_class ); + + /*************************************************************************/ + /* */ + /* */ + /* FT_Module_Destroyer */ + /* */ + /* */ + /* A function used to destroy (deallocate) a module class object. */ + /* */ + /* */ + /* memory :: A handle to the memory manager. */ + /* clazz :: Module class to destroy. */ + /* */ + typedef void + (*FT_Module_Destroyer)( FT_Memory memory, + FT_Module_Class* clazz ); + +#endif + + /*************************************************************************/ + /* */ + /* */ + /* FT_DECLARE_MODULE */ + /* */ + /* */ + /* Used to create a forward declaration of a */ + /* FT_Module_Class stract instance. */ + /* */ + /* */ + /* FT_DEFINE_MODULE */ + /* */ + /* */ + /* Used to initialize an instance of 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 */ + /* 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 */ + /* 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. */ + /* */ + /* 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). */ + /* */ + /* */ + /* FT_DEFINE_ROOT_MODULE */ + /* */ + /* */ + /* 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 */ + /* */ +#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_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 class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + 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; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + FT_END_HEADER diff --git a/include/freetype/internal/ftpic.h b/include/freetype/internal/ftpic.h new file mode 100644 index 0000000..1b31957 --- /dev/null +++ b/include/freetype/internal/ftpic.h @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* ftpic.h */ +/* */ +/* The FreeType position independent code services (declaration). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Modules that ordinarily have const global data that need address */ + /* can instead define pointers here. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTPIC_H__ +#define __FTPIC_H__ + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC + + typedef struct FT_PIC_Container_ + { + /* pic containers for base */ + void* base; + /* pic containers for modules */ + 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. */ + FT_BASE( FT_Error ) + ft_pic_container_init( FT_Library library ); + + + /* Destroy the contents of the container. */ + FT_BASE( void ) + ft_pic_container_destroy( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __FTPIC_H__ */ + + +/* END */ diff --git a/include/freetype/internal/ftserv.h b/include/freetype/internal/ftserv.h index 2db3e87..569b9f7 100644 --- a/include/freetype/internal/ftserv.h +++ b/include/freetype/internal/ftserv.h @@ -163,6 +163,298 @@ FT_BEGIN_HEADER typedef const FT_ServiceDescRec* FT_ServiceDesc; + /*************************************************************************/ + /* */ + /* */ + /* FT_DEFINE_SERVICEDESCREC1 .. FT_DEFINE_SERVICEDESCREC6 */ + /* */ + /* */ + /* Used to initialize an array of FT_ServiceDescRec structs. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated array is returned. */ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* */ + /* These functions should be manyally called from the pic_init and */ + /* pic_free functions of your module (see FT_DEFINE_MODULE) */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the array will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC4(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) \ + 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}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC5(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) \ + 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}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC6(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) \ + 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}, \ + {NULL, NULL} \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1) \ + 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; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*2 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = NULL; \ + clazz[1].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2) \ + 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; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*3 ) ) \ + 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 = NULL; \ + clazz[2].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3) \ + 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; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*4 ) ) \ + 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 = NULL; \ + clazz[3].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC4(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) \ + 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; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*5 ) ) \ + 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 = NULL; \ + clazz[4].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC5(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) \ + 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; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*6 ) ) \ + 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 = NULL; \ + clazz[5].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC6(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) \ + 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; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*7 ) ) \ + 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 = NULL; \ + clazz[6].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } +#endif /* FT_CONFIG_OPTION_PIC */ /* * Parse a list of FT_ServiceDescRec descriptors and look for diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h index 4d38a46..e9b383a 100644 --- a/include/freetype/internal/fttrace.h +++ b/include/freetype/internal/fttrace.h @@ -31,16 +31,19 @@ FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ FT_TRACE_DEF( objs ) /* base objects (ftobjs.c) */ FT_TRACE_DEF( outline ) /* outline management (ftoutln.c) */ FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ +FT_TRACE_DEF( gloader ) /* glyph loader (ftgloadr.c) */ FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ 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) */ /* Cache sub-system */ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ /* SFNT driver components */ +FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */ FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */ @@ -48,6 +51,7 @@ FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ FT_TRACE_DEF( ttmtx ) /* metrics-related tables (ttmtx.c) */ FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ +FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */ /* TrueType driver components */ FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */ @@ -58,6 +62,7 @@ FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */ FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ /* Type 1 driver components */ +FT_TRACE_DEF( t1afm ) FT_TRACE_DEF( t1driver ) FT_TRACE_DEF( t1gload ) FT_TRACE_DEF( t1hint ) diff --git a/include/freetype/internal/internal.h b/include/freetype/internal/internal.h index 27d5dc5..f500a65 100644 --- a/include/freetype/internal/internal.h +++ b/include/freetype/internal/internal.h @@ -25,6 +25,7 @@ #define FT_INTERNAL_OBJECTS_H +#define FT_INTERNAL_PIC_H #define FT_INTERNAL_STREAM_H #define FT_INTERNAL_MEMORY_H #define FT_INTERNAL_DEBUG_H diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h index 7fb4c99..a96e0df 100644 --- a/include/freetype/internal/psaux.h +++ b/include/freetype/internal/psaux.h @@ -360,7 +360,7 @@ FT_BEGIN_HEADER FT_Error (*to_bytes)( PS_Parser parser, FT_Byte* bytes, - FT_Long max_bytes, + FT_Offset max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ); @@ -533,8 +533,6 @@ FT_BEGIN_HEADER /* */ /* max_contours :: Maximal number of contours in builder outline. */ /* */ - /* last :: The last point position. */ - /* */ /* pos_x :: The horizontal translation (if composite glyph). */ /* */ /* pos_y :: The vertical translation (if composite glyph). */ @@ -567,8 +565,6 @@ FT_BEGIN_HEADER FT_Outline* base; FT_Outline* current; - FT_Vector last; - FT_Pos pos_x; FT_Pos pos_y; @@ -579,7 +575,6 @@ FT_BEGIN_HEADER T1_ParseState parse_state; FT_Bool load_points; FT_Bool no_recurse; - FT_Bool shift; FT_Bool metrics_only; @@ -694,9 +689,11 @@ FT_BEGIN_HEADER T1_Decoder_Callback parse_callback; T1_Decoder_FuncsRec funcs; - FT_Int* buildchar; + FT_Long* buildchar; FT_UInt len_buildchar; + FT_Bool seac; + } T1_DecoderRec; @@ -758,7 +755,7 @@ FT_BEGIN_HEADER FT_Int (*get_index)( const char* name, - FT_UInt len, + FT_Offset len, void* user_data ); void* user_data; diff --git a/include/freetype/internal/pshints.h b/include/freetype/internal/pshints.h index 48452c0..0c35765 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 by */ +/* Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -157,7 +157,8 @@ FT_BEGIN_HEADER * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). * * coords :: - * Array of 2 integers, used as (position,length) stem descriptor. + * Array of 2 coordinates in 16.16 format, used as (position,length) + * stem descriptor. * * @note: * Use vertical coordinates (y) for horizontal stems (dim=0). Use @@ -175,9 +176,9 @@ FT_BEGIN_HEADER * */ typedef void - (*T1_Hints_SetStemFunc)( T1_Hints hints, - FT_UInt dimension, - FT_Long* coords ); + (*T1_Hints_SetStemFunc)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); /************************************************************************* @@ -197,8 +198,8 @@ FT_BEGIN_HEADER * 0 for horizontal stems, 1 for vertical ones. * * coords :: - * An array of 6 integers, holding 3 (position,length) pairs for the - * counter-controlled stems. + * An array of 6 values in 16.16 format, holding 3 (position,length) + * pairs for the counter-controlled stems. * * @note: * Use vertical coordinates (y) for horizontal stems (dim=0). Use @@ -209,9 +210,9 @@ FT_BEGIN_HEADER * */ typedef void - (*T1_Hints_SetStem3Func)( T1_Hints hints, - FT_UInt dimension, - FT_Long* coords ); + (*T1_Hints_SetStem3Func)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); /************************************************************************* @@ -446,7 +447,7 @@ FT_BEGIN_HEADER * The number of stems. * * coords :: - * An array of `count' (position,length) pairs. + * An array of `count' (position,length) pairs in 16.16 format. * * @note: * Use vertical coordinates (y) for horizontal stems (dim=0). Use @@ -678,6 +679,30 @@ 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_ \ + }; + +#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_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/include/freetype/internal/services/svbdf.h b/include/freetype/internal/services/svbdf.h index 0f7fc61..9264239 100644 --- a/include/freetype/internal/services/svbdf.h +++ b/include/freetype/internal/services/svbdf.h @@ -45,6 +45,26 @@ FT_BEGIN_HEADER FT_BDF_GetPropertyFunc get_property; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \ + static const FT_Service_BDFRec class_ = \ + { \ + get_charset_id_, get_property_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \ + void \ + FT_Init_Class_##class_( FT_Service_BDFRec* clazz ) \ + { \ + clazz->get_charset_id = get_charset_id_; \ + clazz->get_property = get_property_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/include/freetype/internal/services/svcid.h b/include/freetype/internal/services/svcid.h index 2e391f2..9b874b5 100644 --- a/include/freetype/internal/services/svcid.h +++ b/include/freetype/internal/services/svcid.h @@ -46,6 +46,31 @@ FT_BEGIN_HEADER FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_, \ + get_is_cid_, get_cid_from_glyph_index_ ) \ + static const FT_Service_CIDRec class_ = \ + { \ + get_ros_, get_is_cid_, get_cid_from_glyph_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_, \ + get_is_cid_, get_cid_from_glyph_index_ ) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_CIDRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_ros = get_ros_; \ + clazz->get_is_cid = get_is_cid_; \ + clazz->get_cid_from_glyph_index = get_cid_from_glyph_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/include/freetype/internal/services/svgldict.h b/include/freetype/internal/services/svgldict.h index e5e56b2..d66a41d 100644 --- a/include/freetype/internal/services/svgldict.h +++ b/include/freetype/internal/services/svgldict.h @@ -51,6 +51,28 @@ FT_BEGIN_HEADER FT_GlyphDict_NameIndexFunc name_index; /* optional */ }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \ + static const FT_Service_GlyphDictRec class_ = \ + { \ + get_name_, name_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_GlyphDictRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_name = get_name_; \ + clazz->name_index = name_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/include/freetype/internal/services/svmm.h b/include/freetype/internal/services/svmm.h index 8a99ec4..66e1da2 100644 --- a/include/freetype/internal/services/svmm.h +++ b/include/freetype/internal/services/svmm.h @@ -68,6 +68,31 @@ FT_BEGIN_HEADER FT_Set_Var_Design_Func set_var_design; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_, \ + set_mm_blend_, get_mm_var_, set_var_design_) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_, \ + set_mm_blend_, get_mm_var_, set_var_design_) \ + void \ + FT_Init_Class_##class_( FT_Service_MultiMastersRec* clazz ) \ + { \ + clazz->get_mm = get_mm_; \ + clazz->set_mm_design = set_mm_design_; \ + clazz->set_mm_blend = set_mm_blend_; \ + clazz->get_mm_var = get_mm_var_; \ + clazz->set_var_design = set_var_design_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/include/freetype/internal/services/svpostnm.h b/include/freetype/internal/services/svpostnm.h index 282da68..106c54f 100644 --- a/include/freetype/internal/services/svpostnm.h +++ b/include/freetype/internal/services/svpostnm.h @@ -46,6 +46,27 @@ FT_BEGIN_HEADER FT_PsName_GetFunc get_ps_font_name; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \ + static const FT_Service_PsFontNameRec class_ = \ + { \ + get_ps_font_name_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsFontNameRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_ps_font_name = get_ps_font_name_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/include/freetype/internal/services/svpscmap.h b/include/freetype/internal/services/svpscmap.h index c4e25ed..961030c 100644 --- a/include/freetype/internal/services/svpscmap.h +++ b/include/freetype/internal/services/svpscmap.h @@ -98,7 +98,7 @@ FT_BEGIN_HEADER (*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes, FT_UInt32 unicode ); - typedef FT_ULong + typedef FT_UInt32 (*PS_Unicodes_CharNextFunc)( PS_Unicodes unicodes, FT_UInt32 *unicode ); @@ -117,6 +117,41 @@ FT_BEGIN_HEADER const unsigned short* adobe_expert_encoding; }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_) \ + static const FT_Service_PsCMapsRec class_ = \ + { \ + unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsCMapsRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->unicode_value = unicode_value_; \ + clazz->unicodes_init = unicodes_init_; \ + clazz->unicodes_char_index = unicodes_char_index_; \ + clazz->unicodes_char_next = unicodes_char_next_; \ + clazz->macintosh_name = macintosh_name_; \ + clazz->adobe_std_strings = adobe_std_strings_; \ + clazz->adobe_std_encoding = adobe_std_encoding_; \ + clazz->adobe_expert_encoding = adobe_expert_encoding_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/include/freetype/internal/services/svpsinfo.h b/include/freetype/internal/services/svpsinfo.h index 124c6f9..91ba91e 100644 --- a/include/freetype/internal/services/svpsinfo.h +++ b/include/freetype/internal/services/svpsinfo.h @@ -53,6 +53,33 @@ FT_BEGIN_HEADER PS_GetFontPrivateFunc ps_get_font_private; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_, \ + ps_get_font_extra_, has_glyph_names_, get_font_private_) \ + static const FT_Service_PsInfoRec class_ = \ + { \ + get_font_info_, ps_get_font_extra_, has_glyph_names_, \ + get_font_private_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_, \ + ps_get_font_extra_, has_glyph_names_, get_font_private_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsInfoRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->ps_get_font_info = get_font_info_; \ + clazz->ps_get_font_extra = ps_get_font_extra_; \ + clazz->ps_has_glyph_names = has_glyph_names_; \ + clazz->ps_get_font_private = get_font_private_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/include/freetype/internal/services/svsfnt.h b/include/freetype/internal/services/svsfnt.h index b4a85d9..30bb162 100644 --- a/include/freetype/internal/services/svsfnt.h +++ b/include/freetype/internal/services/svsfnt.h @@ -58,6 +58,7 @@ FT_BEGIN_HEADER (*FT_SFNT_TableInfoFunc)( FT_Face face, FT_UInt idx, FT_ULong *tag, + FT_ULong *offset, FT_ULong *length ); @@ -68,6 +69,27 @@ FT_BEGIN_HEADER FT_SFNT_TableInfoFunc table_info; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_) \ + static const FT_Service_SFNT_TableRec class_ = \ + { \ + load_, get_, info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_) \ + void \ + FT_Init_Class_##class_( FT_Service_SFNT_TableRec* clazz ) \ + { \ + clazz->load_table = load_; \ + clazz->get_table = get_; \ + clazz->table_info = info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/include/freetype/internal/services/svttcmap.h b/include/freetype/internal/services/svttcmap.h index 553ecb0..8af0035 100644 --- a/include/freetype/internal/services/svttcmap.h +++ b/include/freetype/internal/services/svttcmap.h @@ -1,6 +1,6 @@ /***************************************************************************/ /* */ -/* svsttcmap.h */ +/* svttcmap.h */ /* */ /* The FreeType TrueType/sfnt cmap extra information service. */ /* */ @@ -74,6 +74,27 @@ FT_BEGIN_HEADER TT_CMap_Info_GetFunc get_cmap_info; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_) \ + static const FT_Service_TTCMapsRec class_ = \ + { \ + get_cmap_info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_TTCMapsRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_cmap_info = get_cmap_info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/include/freetype/internal/services/svttglyf.h b/include/freetype/internal/services/svttglyf.h index e57d484..ab2dc9a 100644 --- a/include/freetype/internal/services/svttglyf.h +++ b/include/freetype/internal/services/svttglyf.h @@ -37,6 +37,25 @@ FT_BEGIN_HEADER TT_Glyf_GetLocationFunc get_location; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ ) \ + static const FT_Service_TTGlyfRec class_ = \ + { \ + get_location_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ ) \ + void \ + FT_Init_Class_##class_( FT_Service_TTGlyfRec* clazz ) \ + { \ + clazz->get_location = get_location_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h index 7e8f684..6326deb 100644 --- a/include/freetype/internal/sfnt.h +++ b/include/freetype/internal/sfnt.h @@ -753,6 +753,141 @@ FT_BEGIN_HEADER /* transitional */ typedef SFNT_Interface* SFNT_Service; +#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_) \ + }; + +#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_) \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h index ff021b0..5f73063 100644 --- a/include/freetype/internal/t1types.h +++ b/include/freetype/internal/t1types.h @@ -58,7 +58,9 @@ FT_BEGIN_HEADER /* */ /* code_first :: The lowest valid character code in the encoding. */ /* */ - /* code_last :: The highest valid character code in the encoding. */ + /* code_last :: The highest valid character code in the encoding */ + /* + 1. When equal to code_first there are no valid */ + /* character codes. */ /* */ /* char_index :: An array of corresponding glyph indices. */ /* */ @@ -230,7 +232,7 @@ FT_BEGIN_HEADER /* undocumented, optional: has the same meaning as len_buildchar */ /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25 */ FT_UInt len_buildchar; - FT_Int* buildchar; + FT_Long* buildchar; /* since version 2.1 - interface to PostScript hinter */ const void* pshinter; diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h index 85fc27f..acbb863 100644 --- a/include/freetype/internal/tttypes.h +++ b/include/freetype/internal/tttypes.h @@ -902,7 +902,7 @@ FT_BEGIN_HEADER FT_Byte* table; FT_Byte* table_end; FT_Byte* strings; - FT_UInt32 strings_size; + FT_ULong strings_size; FT_UInt num_strikes; FT_Bool loaded; @@ -1401,7 +1401,7 @@ FT_BEGIN_HEADER FT_Byte* vert_metrics; FT_ULong vert_metrics_size; - FT_UInt num_locations; + FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ FT_Byte* glyph_locations; FT_Byte* hdmx_table; diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c index de3ce11..ae64422 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, 2007, 2008 by */ +/* Copyright 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, */ @@ -58,9 +58,12 @@ if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) face->charmap = NULL; - + else + { /* latin's version would suffice */ af_latin_metrics_init_widths( metrics, face, 0x7530 ); + af_latin_metrics_check_digits( metrics, face ); + } FT_Set_Charmap( face, oldmap ); @@ -1017,7 +1020,7 @@ AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; - FT_Int n_edges; + FT_PtrDist n_edges; AF_Edge edge; AF_Edge anchor = 0; FT_Pos delta = 0; @@ -1441,35 +1444,33 @@ static const AF_Script_UniRangeRec af_cjk_uniranges[] = { #if 0 - { 0x0100UL, 0xFFFFUL }, /* why this? */ + AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ #endif - { 0x2E80UL, 0x2EFFUL }, /* CJK Radicals Supplement */ - { 0x2F00UL, 0x2FDFUL }, /* Kangxi Radicals */ - { 0x3000UL, 0x303FUL }, /* CJK Symbols and Punctuation */ - { 0x3040UL, 0x309FUL }, /* Hiragana */ - { 0x30A0UL, 0x30FFUL }, /* Katakana */ - { 0x3100UL, 0x312FUL }, /* Bopomofo */ - { 0x3130UL, 0x318FUL }, /* Hangul Compatibility Jamo */ - { 0x31A0UL, 0x31BFUL }, /* Bopomofo Extended */ - { 0x31C0UL, 0x31EFUL }, /* CJK Strokes */ - { 0x31F0UL, 0x31FFUL }, /* Katakana Phonetic Extensions */ - { 0x3200UL, 0x32FFUL }, /* Enclosed CJK Letters and Months */ - { 0x3300UL, 0x33FFUL }, /* CJK Compatibility */ - { 0x3400UL, 0x4DBFUL }, /* CJK Unified Ideographs Extension A */ - { 0x4DC0UL, 0x4DFFUL }, /* Yijing Hexagram Symbols */ - { 0x4E00UL, 0x9FFFUL }, /* CJK Unified Ideographs */ - { 0xF900UL, 0xFAFFUL }, /* CJK Compatibility Ideographs */ - { 0xFE30UL, 0xFE4FUL }, /* CJK Compatibility Forms */ - { 0xFF00UL, 0xFFEFUL }, /* Halfwidth and Fullwidth Forms */ - { 0x20000UL, 0x2A6DFUL }, /* CJK Unified Ideographs Extension B */ - { 0x2F800UL, 0x2FA1FUL }, /* CJK Compatibility Ideographs Supplement */ - { 0UL, 0UL } + AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */ + AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */ + AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), /* CJK Symbols and Punctuation */ + AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), /* Hiragana */ + AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), /* Katakana */ + AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), /* Bopomofo */ + AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), /* Hangul Compatibility Jamo */ + AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), /* Bopomofo Extended */ + AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), /* CJK Strokes */ + AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), /* Katakana Phonetic Extensions */ + AF_UNIRANGE_REC( 0x3200UL, 0x32FFUL ), /* Enclosed CJK Letters and Months */ + AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), /* CJK Compatibility */ + AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), /* CJK Unified Ideographs Extension A */ + AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), /* Yijing Hexagram Symbols */ + AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), /* CJK Unified Ideographs */ + AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), /* CJK Compatibility Ideographs */ + AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), /* CJK Compatibility Forms */ + AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), /* Halfwidth and Fullwidth Forms */ + AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), /* CJK Unified Ideographs Extension B */ + AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), /* CJK Compatibility Ideographs Supplement */ + AF_UNIRANGE_REC( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_cjk_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class, AF_SCRIPT_CJK, af_cjk_uniranges, @@ -1481,19 +1482,17 @@ (AF_Script_InitHintsFunc) af_cjk_hints_init, (AF_Script_ApplyHintsFunc) af_cjk_hints_apply - }; + ) #else /* !AF_CONFIG_OPTION_CJK */ static const AF_Script_UniRangeRec af_cjk_uniranges[] = { - { 0, 0 } + AF_UNIRANGE_REC( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_cjk_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class, AF_SCRIPT_CJK, af_cjk_uniranges, @@ -1505,7 +1504,7 @@ (AF_Script_InitHintsFunc) NULL, (AF_Script_ApplyHintsFunc) NULL - }; + ) #endif /* !AF_CONFIG_OPTION_CJK */ diff --git a/src/autofit/afcjk.h b/src/autofit/afcjk.h index 9f77fda..0b20d4a 100644 --- a/src/autofit/afcjk.h +++ b/src/autofit/afcjk.h @@ -27,8 +27,7 @@ FT_BEGIN_HEADER /* the CJK-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_cjk_script_class; + AF_DECLARE_SCRIPT_CLASS(af_cjk_script_class) FT_LOCAL( FT_Error ) diff --git a/src/autofit/afdummy.c b/src/autofit/afdummy.c index ed96e96..42b2fcb 100644 --- a/src/autofit/afdummy.c +++ b/src/autofit/afdummy.c @@ -42,9 +42,7 @@ } - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_dummy_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_dummy_script_class, AF_SCRIPT_NONE, NULL, @@ -56,7 +54,7 @@ (AF_Script_InitHintsFunc) af_dummy_hints_init, (AF_Script_ApplyHintsFunc) af_dummy_hints_apply - }; + ) /* END */ diff --git a/src/autofit/afdummy.h b/src/autofit/afdummy.h index 2a5faf8..b69ef43 100644 --- a/src/autofit/afdummy.h +++ b/src/autofit/afdummy.h @@ -29,8 +29,7 @@ FT_BEGIN_HEADER * be performed. This is the default for non-latin glyphs! */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_dummy_script_class; + AF_DECLARE_SCRIPT_CLASS(af_dummy_script_class) /* */ diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c index bfb9091..ac29361 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, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 2003, 2004, 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, */ @@ -21,6 +21,7 @@ #include "aflatin.h" #include "afcjk.h" #include "afindic.h" +#include "afpic.h" #include "aferrors.h" @@ -28,6 +29,11 @@ #include "aflatin2.h" #endif +#ifndef FT_CONFIG_OPTION_PIC + +/* when updating this table, don't forget to update + AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */ + /* populate this list when you add new scripts */ static AF_ScriptClass const af_script_classes[] = { @@ -41,10 +47,14 @@ NULL /* do not remove */ }; +#endif /* FT_CONFIG_OPTION_PIC */ + /* index of default script in `af_script_classes' */ #define AF_SCRIPT_LIST_DEFAULT 2 - /* indicates an uncovered glyph */ -#define AF_SCRIPT_LIST_NONE 255 + /* 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 /* @@ -55,7 +65,7 @@ typedef struct AF_FaceGlobalsRec_ { FT_Face face; - FT_UInt glyph_count; /* same as face->num_glyphs */ + FT_Long glyph_count; /* same as face->num_glyphs */ FT_Byte* glyph_scripts; AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; @@ -72,7 +82,7 @@ FT_Face face = globals->face; FT_CharMap old_charmap = face->charmap; FT_Byte* gscripts = globals->glyph_scripts; - FT_UInt ss; + FT_UInt ss, i; /* the value 255 means `uncovered glyph' */ @@ -92,9 +102,9 @@ } /* scan each script in a Unicode charmap */ - for ( ss = 0; af_script_classes[ss]; ss++ ) + for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ ) { - AF_ScriptClass clazz = af_script_classes[ss]; + AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[ss]; AF_Script_UniRange range; @@ -114,7 +124,7 @@ gindex = FT_Get_Char_Index( face, charcode ); if ( gindex != 0 && - gindex < globals->glyph_count && + gindex < (FT_ULong)globals->glyph_count && gscripts[gindex] == AF_SCRIPT_LIST_NONE ) { gscripts[gindex] = (FT_Byte)ss; @@ -127,7 +137,7 @@ if ( gindex == 0 || charcode > range->last ) break; - if ( gindex < globals->glyph_count && + if ( gindex < (FT_ULong)globals->glyph_count && gscripts[gindex] == AF_SCRIPT_LIST_NONE ) { gscripts[gindex] = (FT_Byte)ss; @@ -136,13 +146,23 @@ } } + /* mark ASCII digits */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt gindex = FT_Get_Char_Index( face, i ); + + + if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) + gscripts[gindex] |= AF_DIGIT; + } + Exit: /* * By default, all uncovered glyphs are set to the latin script. * XXX: Shouldn't we disable hinting or do something similar? */ { - FT_UInt nn; + FT_Long nn; for ( nn = 0; nn < globals->glyph_count; nn++ ) @@ -201,7 +221,7 @@ { if ( globals->metrics[nn] ) { - AF_ScriptClass clazz = af_script_classes[nn]; + AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[nn]; FT_ASSERT( globals->metrics[nn]->clazz == clazz ); @@ -232,12 +252,12 @@ FT_UInt gidx; AF_ScriptClass clazz; FT_UInt script = options & 15; - const FT_UInt script_max = sizeof ( af_script_classes ) / - sizeof ( af_script_classes[0] ); + const FT_Offset script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) / + sizeof ( AF_SCRIPT_CLASSES_GET[0] ); FT_Error error = AF_Err_Ok; - if ( gindex >= globals->glyph_count ) + if ( gindex >= (FT_ULong)globals->glyph_count ) { error = AF_Err_Invalid_Argument; goto Exit; @@ -245,9 +265,9 @@ gidx = script; if ( gidx == 0 || gidx + 1 >= script_max ) - gidx = globals->glyph_scripts[gindex]; + gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_LIST_NONE; - clazz = af_script_classes[gidx]; + clazz = AF_SCRIPT_CLASSES_GET[gidx]; if ( script == 0 ) script = clazz->script; @@ -286,4 +306,15 @@ } + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ) + { + if ( gindex < (FT_ULong)globals->glyph_count ) + return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT ); + + return (FT_Bool)0; + } + + /* END */ diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h index cf52c08..0d8fb5f 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, 2004, 2005, 2007 by */ +/* Copyright 2003, 2004, 2005, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -56,6 +56,10 @@ FT_BEGIN_HEADER FT_LOCAL( void ) af_face_globals_free( AF_FaceGlobals globals ); + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ); + /* */ diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c index 8ab1761..a5aec80 100644 --- a/src/autofit/afhints.c +++ b/src/autofit/afhints.c @@ -34,7 +34,7 @@ { FT_Int old_max = axis->max_segments; FT_Int new_max = old_max; - FT_Int big_max = FT_INT_MAX / sizeof ( *segment ); + FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) ); if ( old_max >= big_max ) @@ -77,7 +77,7 @@ { FT_Int old_max = axis->max_edges; FT_Int new_max = old_max; - FT_Int big_max = FT_INT_MAX / sizeof ( *edge ); + FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) ); if ( old_max >= big_max ) @@ -645,6 +645,7 @@ FT_Int contour_index = 0; + FT_UNUSED( first ); for ( point = points; point < point_limit; point++, vec++, tag++ ) { point->fx = (FT_Short)vec->x; @@ -940,7 +941,7 @@ } { - FT_UInt min, max, mid; + FT_PtrDist min, max, mid; FT_Pos fpos; @@ -952,7 +953,7 @@ /* for small edge counts, a linear search is better */ if ( max <= 8 ) { - FT_UInt nn; + FT_PtrDist nn; for ( nn = 0; nn < max; nn++ ) if ( edges[nn].fpos >= u ) diff --git a/src/autofit/afindic.c b/src/autofit/afindic.c index 3d27f52..1d9e9ea 100644 --- a/src/autofit/afindic.c +++ b/src/autofit/afindic.c @@ -81,16 +81,14 @@ static const AF_Script_UniRangeRec af_indic_uniranges[] = { #if 0 - { 0x0100, 0xFFFF }, /* why this? */ + AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ #endif - { 0x0900, 0x0DFF}, /* Indic Range */ - { 0, 0 } + AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL), /* Indic Range */ + AF_UNIRANGE_REC( 0UL, 0UL) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_indic_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_indic_script_class, AF_SCRIPT_INDIC, af_indic_uniranges, @@ -102,7 +100,7 @@ (AF_Script_InitHintsFunc) af_indic_hints_init, (AF_Script_ApplyHintsFunc) af_indic_hints_apply - }; + ) #else /* !AF_CONFIG_OPTION_INDIC */ @@ -112,9 +110,7 @@ }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_indic_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_indic_script_class, AF_SCRIPT_INDIC, af_indic_uniranges, @@ -126,7 +122,7 @@ (AF_Script_InitHintsFunc) NULL, (AF_Script_ApplyHintsFunc) NULL - }; + ) #endif /* !AF_CONFIG_OPTION_INDIC */ diff --git a/src/autofit/afindic.h b/src/autofit/afindic.h index b242b26..662a982 100644 --- a/src/autofit/afindic.h +++ b/src/autofit/afindic.h @@ -27,8 +27,7 @@ FT_BEGIN_HEADER /* the Indic-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - 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 ba59e5b..e6882d5 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, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 2003, 2004, 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, */ @@ -16,6 +16,9 @@ /***************************************************************************/ +#include +#include FT_ADVANCES_H + #include "aflatin.h" #include "aferrors.h" @@ -146,7 +149,8 @@ #define AF_LATIN_MAX_TEST_CHARACTERS 12 - static const char* const af_latin_blue_chars[AF_LATIN_MAX_BLUES] = + static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES] + [AF_LATIN_MAX_TEST_CHARACTERS + 1] = { "THEZOCQS", "HEZLOCUS", @@ -195,7 +199,8 @@ for ( ; p < limit && *p; p++ ) { FT_UInt glyph_index; - FT_Int best_point, best_y, best_first, best_last; + FT_Pos best_y; /* same as points.y */ + FT_Int best_point, best_first, best_last; FT_Vector* points; FT_Bool round = 0; @@ -328,7 +333,7 @@ * we couldn't find a single glyph to compute this blue zone, * we will simply ignore it then */ - AF_LOG(( "empty!\n" )); + AF_LOG(( "empty\n" )); continue; } @@ -379,7 +384,7 @@ blue->flags |= AF_LATIN_BLUE_TOP; /* - * The following flags is used later to adjust the y and x scales + * The following flag is used later to adjust the y and x scales * in order to optimize the pixel grid alignment of the top of small * letters. */ @@ -393,6 +398,52 @@ } + FT_LOCAL_DEF( void ) + af_latin_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_UInt i; + FT_Bool started = 0, same_width = 1; + FT_Fixed advance, old_advance = 0; + + + /* check whether all ASCII digits have the same advance width; */ + /* digit `0' is 0x30 in all supported charmaps */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt glyph_index; + + + glyph_index = FT_Get_Char_Index( face, i ); + if ( glyph_index == 0 ) + continue; + + if ( FT_Get_Advance( face, glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + &advance ) ) + continue; + + if ( started ) + { + if ( advance != old_advance ) + { + same_width = 0; + break; + } + } + else + { + old_advance = advance; + started = 1; + } + } + + metrics->root.digits_have_same_width = same_width; + } + + FT_LOCAL_DEF( FT_Error ) af_latin_metrics_init( AF_LatinMetrics metrics, FT_Face face ) @@ -426,6 +477,7 @@ /* For now, compute the standard width and height from the `o'. */ af_latin_metrics_init_widths( metrics, face, 'o' ); af_latin_metrics_init_blues( metrics, face ); + af_latin_metrics_check_digits( metrics, face ); } FT_Set_Charmap( face, oldmap ); @@ -1567,7 +1619,7 @@ /* not hinted, appear a lot bolder or thinner than the */ /* vertical stems. */ - FT_Int delta; + FT_Pos delta; dist = ( dist + 22 ) & ~63; @@ -1651,7 +1703,7 @@ AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; - FT_Int n_edges; + FT_PtrDist n_edges; AF_Edge edge; AF_Edge anchor = 0; FT_Int has_serifs = 0; @@ -2127,39 +2179,37 @@ static const AF_Script_UniRangeRec af_latin_uniranges[] = { - { 0x0020 , 0x007F }, /* Basic Latin (no control chars) */ - { 0x00A0 , 0x00FF }, /* Latin-1 Supplement (no control chars) */ - { 0x0100 , 0x017F }, /* Latin Extended-A */ - { 0x0180 , 0x024F }, /* Latin Extended-B */ - { 0x0250 , 0x02AF }, /* IPA Extensions */ - { 0x02B0 , 0x02FF }, /* Spacing Modifier Letters */ - { 0x0300 , 0x036F }, /* Combining Diacritical Marks */ - { 0x0370 , 0x03FF }, /* Greek and Coptic */ - { 0x0400 , 0x04FF }, /* Cyrillic */ - { 0x0500 , 0x052F }, /* Cyrillic Supplement */ - { 0x1D00 , 0x1D7F }, /* Phonetic Extensions */ - { 0x1D80 , 0x1DBF }, /* Phonetic Extensions Supplement */ - { 0x1DC0 , 0x1DFF }, /* Combining Diacritical Marks Supplement */ - { 0x1E00 , 0x1EFF }, /* Latin Extended Additional */ - { 0x1F00 , 0x1FFF }, /* Greek Extended */ - { 0x2000 , 0x206F }, /* General Punctuation */ - { 0x2070 , 0x209F }, /* Superscripts and Subscripts */ - { 0x20A0 , 0x20CF }, /* Currency Symbols */ - { 0x2150 , 0x218F }, /* Number Forms */ - { 0x2460 , 0x24FF }, /* Enclosed Alphanumerics */ - { 0x2C60 , 0x2C7F }, /* Latin Extended-C */ - { 0x2DE0 , 0x2DFF }, /* Cyrillic Extended-A */ - { 0xA640U , 0xA69FU }, /* Cyrillic Extended-B */ - { 0xA720U , 0xA7FFU }, /* Latin Extended-D */ - { 0xFB00U , 0xFB06U }, /* Alphab. Present. Forms (Latin Ligs) */ - { 0x1D400UL, 0x1D7FFUL }, /* Mathematical Alphanumeric Symbols */ - { 0 , 0 } + AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */ + AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */ + AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */ + AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */ + AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */ + AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */ + AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */ + AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), /* Greek and Coptic */ + AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */ + AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), /* Cyrillic Supplement */ + AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */ + AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */ + AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Supplement */ + AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ + AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ + AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ + AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */ + AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */ + AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ + 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( 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( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_latin_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_latin_script_class, AF_SCRIPT_LATIN, af_latin_uniranges, @@ -2171,7 +2221,7 @@ (AF_Script_InitHintsFunc) af_latin_hints_init, (AF_Script_ApplyHintsFunc) af_latin_hints_apply - }; + ) /* END */ diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h index 3251d37..660b10c 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, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,8 +27,7 @@ FT_BEGIN_HEADER /* the latin-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_latin_script_class; + AF_DECLARE_SCRIPT_CLASS(af_latin_script_class) /* constants are given with units_per_em == 2048 in mind */ @@ -138,6 +137,10 @@ FT_BEGIN_HEADER FT_Face face, FT_ULong charcode ); + FT_LOCAL( void ) + af_latin_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ); + /*************************************************************************/ /*************************************************************************/ diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c index 14327b1..f58ef38 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, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 2003, 2004, 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, */ @@ -16,6 +16,8 @@ /***************************************************************************/ +#include FT_ADVANCES_H + #include "aflatin.h" #include "aflatin2.h" #include "aferrors.h" @@ -154,7 +156,7 @@ #define AF_LATIN_MAX_TEST_CHARACTERS 12 - static const char* const af_latin2_blue_chars[AF_LATIN_MAX_BLUES] = + static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES][AF_LATIN_MAX_TEST_CHARACTERS+1] = { "THEZOCQS", "HEZLOCUS", @@ -336,7 +338,7 @@ * we couldn't find a single glyph to compute this blue zone, * we will simply ignore it then */ - AF_LOG(( "empty!\n" )); + AF_LOG(( "empty\n" )); continue; } @@ -401,6 +403,52 @@ } + FT_LOCAL_DEF( void ) + af_latin2_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_UInt i; + FT_Bool started = 0, same_width = 1; + FT_Fixed advance, old_advance = 0; + + + /* check whether all ASCII digits have the same advance width; */ + /* digit `0' is 0x30 in all supported charmaps */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt glyph_index; + + + glyph_index = FT_Get_Char_Index( face, i ); + if ( glyph_index == 0 ) + continue; + + if ( FT_Get_Advance( face, glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + &advance ) ) + continue; + + if ( started ) + { + if ( advance != old_advance ) + { + same_width = 0; + break; + } + } + else + { + old_advance = advance; + started = 1; + } + } + + metrics->root.digits_have_same_width = same_width; + } + + FT_LOCAL_DEF( FT_Error ) af_latin2_metrics_init( AF_LatinMetrics metrics, FT_Face face ) @@ -434,6 +482,7 @@ /* For now, compute the standard width and height from the `o'. */ af_latin2_metrics_init_widths( metrics, face, 'o' ); af_latin2_metrics_init_blues( metrics, face ); + af_latin2_metrics_check_digits( metrics, face ); } FT_Set_Charmap( face, oldmap ); @@ -1739,7 +1788,6 @@ AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; - FT_Int n_edges; AF_Edge edge; AF_Edge anchor = 0; FT_Int has_serifs = 0; @@ -2050,8 +2098,12 @@ /* We don't handle horizontal edges since we can't easily assure that */ /* the third (lowest) stem aligns with the base line; it might end up */ /* one pixel higher or lower. */ + #if 0 - n_edges = edge_limit - edges; + { + FT_Int n_edges = edge_limit - edges; + + if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) { AF_Edge edge1, edge2, edge3; @@ -2097,7 +2149,9 @@ edge3->link->flags |= AF_EDGE_DONE; } } + } #endif + if ( has_serifs || !anchor ) { /* @@ -2266,15 +2320,13 @@ static const AF_Script_UniRangeRec af_latin2_uniranges[] = { - { 32, 127 }, /* XXX: TODO: Add new Unicode ranges here! */ - { 160, 255 }, - { 0, 0 } + AF_UNIRANGE_REC( 32UL, 127UL ), /* XXX: TODO: Add new Unicode ranges here! */ + AF_UNIRANGE_REC( 160UL, 255UL ), + AF_UNIRANGE_REC( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_latin2_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_latin2_script_class, AF_SCRIPT_LATIN2, af_latin2_uniranges, @@ -2286,7 +2338,7 @@ (AF_Script_InitHintsFunc) af_latin2_hints_init, (AF_Script_ApplyHintsFunc) af_latin2_hints_apply - }; + ) /* END */ diff --git a/src/autofit/aflatin2.h b/src/autofit/aflatin2.h index 34eda05..925c621 100644 --- a/src/autofit/aflatin2.h +++ b/src/autofit/aflatin2.h @@ -27,8 +27,7 @@ FT_BEGIN_HEADER /* the latin-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - 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 4e48c2f..bf25cd1 100644 --- a/src/autofit/afloader.c +++ b/src/autofit/afloader.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter glyph loading routines (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 2003, 2004, 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, */ @@ -19,7 +19,6 @@ #include "afloader.h" #include "afhints.h" #include "afglobal.h" -#include "aflatin.h" #include "aferrors.h" @@ -220,6 +219,7 @@ FT_Pos pp1x = loader->pp1.x; FT_Pos pp2x = loader->pp2.x; + loader->pp1.x = FT_PIX_ROUND( pp1x ); loader->pp2.x = FT_PIX_ROUND( pp2x ); @@ -232,6 +232,7 @@ FT_Pos pp1x = loader->pp1.x; FT_Pos pp2x = loader->pp2.x; + loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); @@ -413,7 +414,8 @@ slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y ); /* for mono-width fonts (like Andale, Courier, etc.) we need */ - /* to keep the original rounded advance width */ + /* to keep the original rounded advance width; ditto for */ + /* digits if all have the same advance width */ #if 0 if ( !FT_IS_FIXED_WIDTH( slot->face ) ) slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; @@ -421,13 +423,9 @@ slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, x_scale ); #else - if ( !FT_IS_FIXED_WIDTH( slot->face ) ) - { - /* non-spacing glyphs must stay as-is */ - if ( slot->metrics.horiAdvance ) - slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - } - else + if ( FT_IS_FIXED_WIDTH( slot->face ) || + ( af_face_globals_is_digit( loader->globals, glyph_index ) && + metrics->digits_have_same_width ) ) { slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, metrics->scaler.x_scale ); @@ -437,6 +435,12 @@ slot->lsb_delta = 0; slot->rsb_delta = 0; } + else + { + /* non-spacing glyphs must stay as-is */ + if ( slot->metrics.horiAdvance ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + } #endif slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c index cd5e1cc..ec2d707 100644 --- a/src/autofit/afmodule.c +++ b/src/autofit/afmodule.c @@ -18,6 +18,7 @@ #include "afmodule.h" #include "afloader.h" +#include "afpic.h" #ifdef AF_DEBUG int _af_debug; @@ -66,19 +67,15 @@ } - FT_CALLBACK_TABLE_DEF - const FT_AutoHinter_ServiceRec af_autofitter_service = - { + FT_DEFINE_AUTOHINTER_SERVICE(af_autofitter_service, NULL, NULL, NULL, (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph - }; + ) + FT_DEFINE_MODULE(autofit_module_class, - FT_CALLBACK_TABLE_DEF - const FT_Module_Class autofit_module_class = - { FT_MODULE_HINTER, sizeof ( FT_AutofitterRec ), @@ -86,12 +83,12 @@ 0x10000L, /* version 1.0 of the autofitter */ 0x20000L, /* requires FreeType 2.0 or above */ - (const void*)&af_autofitter_service, + (const void*)&AF_AF_AUTOFITTER_SERVICE_GET, (FT_Module_Constructor)af_autofitter_init, (FT_Module_Destructor) af_autofitter_done, (FT_Module_Requester) NULL - }; + ) /* END */ diff --git a/src/autofit/afmodule.h b/src/autofit/afmodule.h index 36268a0..d979239 100644 --- a/src/autofit/afmodule.h +++ b/src/autofit/afmodule.h @@ -20,13 +20,13 @@ #define __AFMODULE_H__ #include +#include FT_INTERNAL_OBJECTS_H #include FT_MODULE_H FT_BEGIN_HEADER - FT_CALLBACK_TABLE - const FT_Module_Class autofit_module_class; +FT_DECLARE_MODULE(autofit_module_class) FT_END_HEADER diff --git a/src/autofit/afpic.c b/src/autofit/afpic.c new file mode 100644 index 0000000..76822c3 --- /dev/null +++ b/src/autofit/afpic.c @@ -0,0 +1,92 @@ +/***************************************************************************/ +/* */ +/* afpic.c */ +/* */ +/* The FreeType position independent code services for autofit module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "afpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from afmodule.c */ + void FT_Init_Class_af_autofitter_service( FT_Library, FT_AutoHinter_ServiceRec*); + + /* forward declaration of PIC init functions from script classes */ +#include "aflatin.h" +#include "aflatin2.h" +#include "afcjk.h" +#include "afdummy.h" +#include "afindic.h" + + void + autofit_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->autofit ) + { + FT_FREE( pic_container->autofit ); + pic_container->autofit = NULL; + } + } + + FT_Error + autofit_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_UInt ss; + FT_Error error = FT_Err_Ok; + AFModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->autofit = container; + + /* initialize pointer table - this is how the module usually expects this data */ + for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ ) + { + container->af_script_classes[ss] = &container->af_script_classes_rec[ss]; + } + container->af_script_classes[AF_SCRIPT_CLASSES_COUNT-1] = NULL; + + /* add call to initialization function when you add new scripts */ + ss = 0; + FT_Init_Class_af_dummy_script_class(&container->af_script_classes_rec[ss++]); +#ifdef FT_OPTION_AUTOFIT2 + FT_Init_Class_af_latin2_script_class(&container->af_script_classes_rec[ss++]); +#endif + FT_Init_Class_af_latin_script_class(&container->af_script_classes_rec[ss++]); + FT_Init_Class_af_cjk_script_class(&container->af_script_classes_rec[ss++]); + 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:*/ + if(error) + autofit_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/src/autofit/afpic.h b/src/autofit/afpic.h new file mode 100644 index 0000000..80e62d3 --- /dev/null +++ b/src/autofit/afpic.h @@ -0,0 +1,64 @@ +/***************************************************************************/ +/* */ +/* afpic.h */ +/* */ +/* The FreeType position independent code services for autofit module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __AFPIC_H__ +#define __AFPIC_H__ + + +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 + +#else /* FT_CONFIG_OPTION_PIC */ + +#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 +#else + #define AF_SCRIPT_CLASSES_COUNT 5 +#endif +#define AF_SCRIPT_CLASSES_REC_COUNT (AF_SCRIPT_CLASSES_COUNT-1) + + 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; + } AFModulePIC; + +#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) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __AFPIC_H__ */ + + +/* END */ diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h index 626a388..5574f0c 100644 --- a/src/autofit/aftypes.h +++ b/src/autofit/aftypes.h @@ -285,6 +285,7 @@ extern void* _af_debug_hints; { AF_ScriptClass clazz; AF_ScalerRec scaler; + FT_Bool digits_have_same_width; } AF_ScriptMetricsRec, *AF_ScriptMetrics; @@ -321,6 +322,8 @@ extern void* _af_debug_hints; } AF_Script_UniRangeRec; +#define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) } + typedef const AF_Script_UniRangeRec *AF_Script_UniRange; @@ -329,7 +332,7 @@ extern void* _af_debug_hints; AF_Script script; AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */ - FT_UInt script_metrics_size; + FT_Offset script_metrics_size; AF_Script_InitMetricsFunc script_metrics_init; AF_Script_ScaleMetricsFunc script_metrics_scale; AF_Script_DoneMetricsFunc script_metrics_done; @@ -339,6 +342,56 @@ extern void* _af_debug_hints; } AF_ScriptClassRec; +/* Declare and define vtables for classes */ +#ifndef FT_CONFIG_OPTION_PIC + +#define AF_DECLARE_SCRIPT_CLASS(script_class) \ + FT_CALLBACK_TABLE const AF_ScriptClassRec \ + script_class; + +#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size, \ + m_init, m_scale, m_done, h_init, h_apply) \ + FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec \ + script_class = \ + { \ + script_, \ + ranges, \ + \ + m_size, \ + \ + m_init, \ + m_scale, \ + m_done, \ + \ + h_init, \ + h_apply \ + }; + +#else + +#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, \ + m_init, m_scale, m_done, h_init, h_apply) \ + FT_LOCAL_DEF(void) \ + FT_Init_Class_##script_class(AF_ScriptClassRec* ac) \ + { \ + ac->script = script_; \ + ac->script_uni_ranges = ranges; \ + \ + ac->script_metrics_size = m_size; \ + \ + ac->script_metrics_init = m_init; \ + ac->script_metrics_scale = m_scale; \ + ac->script_metrics_done = m_done; \ + \ + ac->script_hints_init = h_init; \ + ac->script_hints_apply = h_apply; \ + } +#endif + /* */ diff --git a/src/autofit/autofit.c b/src/autofit/autofit.c index 2fe66a9..83b613e 100644 --- a/src/autofit/autofit.c +++ b/src/autofit/autofit.c @@ -18,6 +18,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include +#include "afpic.c" #include "afangles.c" #include "afglobal.c" #include "afhints.c" diff --git a/src/base/basepic.c b/src/base/basepic.c new file mode 100644 index 0000000..c0bccb6 --- /dev/null +++ b/src/base/basepic.c @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* basepic.c */ +/* */ +/* The FreeType position independent code services for base. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 +#include FT_FREETYPE_H +#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*); + void FT_Init_Class_ft_bitmap_glyph_class(FT_Glyph_Class*); + + /* forward declaration of PIC init functions from ftinit.c */ + FT_Error ft_create_default_module_classes(FT_Library); + void ft_destroy_default_module_classes(FT_Library); + + void + ft_base_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->base ) + { + /* Destroy default module classes (in case FT_Add_Default_Modules was used) */ + ft_destroy_default_module_classes( library ); + + FT_FREE( pic_container->base ); + pic_container->base = NULL; + } + } + + + FT_Error + 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; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->base = container; + + /* initialize default modules list and pointers */ + error = ft_create_default_module_classes( library ); + if ( error ) + goto Exit; + + /* 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); + +Exit: + if(error) + ft_base_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/src/base/basepic.h b/src/base/basepic.h new file mode 100644 index 0000000..bb17745 --- /dev/null +++ b/src/base/basepic.h @@ -0,0 +1,62 @@ +/***************************************************************************/ +/* */ +/* basepic.h */ +/* */ +/* The FreeType position independent code services for base. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __BASEPIC_H__ +#define __BASEPIC_H__ + + +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 + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_GLYPH_H + + typedef struct BasePIC_ + { + FT_Module_Class** default_module_classes; + FT_Glyph_Class ft_outline_glyph_class; + FT_Glyph_Class ft_bitmap_glyph_class; + } 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) + + void + ft_base_pic_free( FT_Library library ); + + FT_Error + ft_base_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ + +FT_END_HEADER + +#endif /* __BASEPIC_H__ */ + + +/* END */ diff --git a/src/base/ftadvanc.c b/src/base/ftadvanc.c index 504f9d2..8ab7fcb 100644 --- a/src/base/ftadvanc.c +++ b/src/base/ftadvanc.c @@ -140,7 +140,7 @@ if ( flags & FT_ADVANCE_FLAG_FAST_ONLY ) return FT_Err_Unimplemented_Feature; - flags |= FT_LOAD_ADVANCE_ONLY; + flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; for ( nn = 0; nn < count; nn++ ) { error = FT_Load_Glyph( face, start + nn, flags ); diff --git a/src/base/ftbase.c b/src/base/ftbase.c index d1fe6e6..6a27ea9 100644 --- a/src/base/ftbase.c +++ b/src/base/ftbase.c @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 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, */ @@ -20,14 +20,16 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT +#include "ftpic.c" +#include "basepic.c" #include "ftadvanc.c" #include "ftcalc.c" #include "ftdbgmem.c" #include "ftgloadr.c" -#include "ftnames.c" #include "ftobjs.c" #include "ftoutln.c" #include "ftrfork.c" +#include "ftsnames.c" #include "ftstream.c" #include "fttrigon.c" #include "ftutil.c" diff --git a/src/base/ftbase.h b/src/base/ftbase.h index 9cae85d..1dc49f3 100644 --- a/src/base/ftbase.h +++ b/src/base/ftbase.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private functions used in base module (specification). */ /* */ -/* Copyright 2008 by */ +/* Copyright 2008, 2010 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,7 +29,7 @@ FT_BEGIN_HEADER /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */ /* font, and try to load a face specified by the face_index. */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL( FT_Error ) open_face_PS_from_sfnt_stream( FT_Library library, FT_Stream stream, FT_Long face_index, @@ -40,7 +40,7 @@ FT_BEGIN_HEADER /* Create a new FT_Face given a buffer and a driver name. */ /* From ftmac.c. */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL( FT_Error ) open_face_from_buffer( FT_Library library, FT_Byte* base, FT_ULong size, diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c index 532ab13..2de592d 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 by */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2010 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_IMAGE_H #include FT_OUTLINE_H #include FT_INTERNAL_CALC_H +#include FT_INTERNAL_OBJECTS_H typedef struct TBBox_Rec_ @@ -139,7 +140,7 @@ /* */ /* */ /* This function is used as a `conic_to' emitter during */ - /* FT_Raster_Decompose(). It checks a conic Bezier curve with the */ + /* FT_Outline_Decompose(). It checks a conic Bezier curve with the */ /* current bounding box, and computes its extrema if necessary to */ /* update it. */ /* */ @@ -506,7 +507,7 @@ /* */ /* */ /* This function is used as a `cubic_to' emitter during */ - /* FT_Raster_Decompose(). It checks a cubic Bezier curve with the */ + /* FT_Outline_Decompose(). It checks a cubic Bezier curve with the */ /* current bounding box, and computes its extrema if necessary to */ /* update it. */ /* */ @@ -559,6 +560,13 @@ return 0; } +FT_DEFINE_OUTLINE_FUNCS(bbox_interface, + (FT_Outline_MoveTo_Func) BBox_Move_To, + (FT_Outline_LineTo_Func) BBox_Move_To, + (FT_Outline_ConicTo_Func)BBox_Conic_To, + (FT_Outline_CubicTo_Func)BBox_Cubic_To, + 0, 0 + ) /* documentation is in ftbbox.h */ @@ -628,18 +636,13 @@ /* the two boxes are different, now walk over the outline to */ /* get the Bezier arc extrema. */ - static const FT_Outline_Funcs bbox_interface = - { - (FT_Outline_MoveTo_Func) BBox_Move_To, - (FT_Outline_LineTo_Func) BBox_Move_To, - (FT_Outline_ConicTo_Func)BBox_Conic_To, - (FT_Outline_CubicTo_Func)BBox_Cubic_To, - 0, 0 - }; - FT_Error error; TBBox_Rec user; +#ifdef FT_CONFIG_OPTION_PIC + FT_Outline_Funcs bbox_interface; + Init_Class_bbox_interface(&bbox_interface); +#endif user.bbox = bbox; diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c index 8810cfa..46fcce6 100644 --- a/src/base/ftbitmap.c +++ b/src/base/ftbitmap.c @@ -228,8 +228,12 @@ if ( !bitmap || !bitmap->buffer ) return FT_Err_Invalid_Argument; - xstr = FT_PIX_ROUND( xStrength ) >> 6; - ystr = FT_PIX_ROUND( yStrength ) >> 6; + if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) || + ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) ) + return FT_Err_Invalid_Argument; + + xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6; + ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6; if ( xstr == 0 && ystr == 0 ) return FT_Err_Ok; diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c index 04295a6..3892fab 100644 --- a/src/base/ftcalc.c +++ b/src/base/ftcalc.c @@ -110,12 +110,12 @@ FT_EXPORT_DEF( FT_Int32 ) FT_Sqrt32( FT_Int32 x ) { - FT_ULong val, root, newroot, mask; + FT_UInt32 val, root, newroot, mask; root = 0; - mask = 0x40000000L; - val = (FT_ULong)x; + mask = (FT_UInt32)0x40000000UL; + val = (FT_UInt32)x; do { @@ -362,6 +362,7 @@ long s; + /* XXX: this function does not allow 64-bit arguments */ if ( a == 0 || b == c ) return a; @@ -377,12 +378,12 @@ FT_Int64 temp, temp2; - ft_multo64( a, b, &temp ); + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); temp2.hi = 0; temp2.lo = (FT_UInt32)(c >> 1); FT_Add64( &temp, &temp2, &temp ); - a = ft_div64by32( temp.hi, temp.lo, c ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); } else a = 0x7FFFFFFFL; @@ -416,8 +417,8 @@ FT_Int64 temp; - ft_multo64( a, b, &temp ); - a = ft_div64by32( temp.hi, temp.lo, c ); + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); } else a = 0x7FFFFFFFL; @@ -539,13 +540,14 @@ FT_UInt32 q; - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); + /* XXX: this function does not allow 64-bit arguments */ + s = (FT_Int32)a; a = FT_ABS( a ); + s ^= (FT_Int32)b; b = FT_ABS( b ); if ( b == 0 ) { /* check for division by 0 */ - q = 0x7FFFFFFFL; + q = (FT_UInt32)0x7FFFFFFFL; } else if ( ( a >> 16 ) == 0 ) { @@ -562,7 +564,7 @@ temp2.hi = 0; temp2.lo = (FT_UInt32)( b >> 1 ); FT_Add64( &temp, &temp2, &temp ); - q = ft_div64by32( temp.hi, temp.lo, b ); + q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); } return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); @@ -840,7 +842,7 @@ FT_Pos out_x, FT_Pos out_y ) { - FT_Int result; + FT_Long result; /* avoid overflow on 16-bit system */ /* deal with the trivial cases quickly */ @@ -889,8 +891,9 @@ FT_Int64 z1, z2; - ft_multo64( in_x, out_y, &z1 ); - ft_multo64( in_y, out_x, &z2 ); + /* XXX: this function does not allow 64-bit arguments */ + ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); + ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 ); if ( z1.hi > z2.hi ) result = +1; @@ -906,7 +909,8 @@ #endif } - return result; + /* XXX: only the sign of return value, +1/0/-1 must be used */ + return (FT_Int)result; } diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c index 8b2a330..160269d 100644 --- a/src/base/ftdbgmem.c +++ b/src/base/ftdbgmem.c @@ -421,7 +421,7 @@ "FreeType: %ld bytes of memory leaked in %ld blocks\n", leaks, leak_count ); - printf( "FreeType: No memory leaks detected!\n" ); + printf( "FreeType: no memory leaks detected\n" ); } } @@ -989,7 +989,7 @@ #else /* !FT_DEBUG_MEMORY */ /* ANSI C doesn't like empty source files */ - static const FT_Byte _debug_mem_dummy = 0; + typedef int _debug_mem_dummy; #endif /* !FT_DEBUG_MEMORY */ diff --git a/src/base/ftgloadr.c b/src/base/ftgloadr.c index ab52621..ac0010d 100644 --- a/src/base/ftgloadr.c +++ b/src/base/ftgloadr.c @@ -218,6 +218,9 @@ { new_max = FT_PAD_CEIL( new_max, 8 ); + if ( new_max > FT_OUTLINE_POINTS_MAX ) + return FT_Err_Array_Too_Large; + if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || FT_RENEW_ARRAY( base->tags, old_max, new_max ) ) goto Exit; @@ -246,6 +249,10 @@ if ( new_max > old_max ) { new_max = FT_PAD_CEIL( new_max, 4 ); + + if ( new_max > FT_OUTLINE_CONTOURS_MAX ) + return FT_Err_Array_Too_Large; + if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) goto Exit; diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c index 4130cb1..3505d6d 100644 --- a/src/base/ftglyph.c +++ b/src/base/ftglyph.c @@ -34,6 +34,7 @@ #include FT_BITMAP_H #include FT_INTERNAL_OBJECTS_H +#include "basepic.h" /*************************************************************************/ /* */ @@ -129,9 +130,7 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Glyph_Class ft_bitmap_glyph_class = - { + FT_DEFINE_GLYPH(ft_bitmap_glyph_class, sizeof ( FT_BitmapGlyphRec ), FT_GLYPH_FORMAT_BITMAP, @@ -141,7 +140,7 @@ 0, /* FT_Glyph_TransformFunc */ ft_bitmap_glyph_bbox, 0 /* FT_Glyph_PrepareFunc */ - }; + ) /*************************************************************************/ @@ -255,9 +254,7 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Glyph_Class ft_outline_glyph_class = - { + FT_DEFINE_GLYPH( ft_outline_glyph_class, sizeof ( FT_OutlineGlyphRec ), FT_GLYPH_FORMAT_OUTLINE, @@ -267,7 +264,7 @@ ft_outline_glyph_transform, ft_outline_glyph_bbox, ft_outline_glyph_prepare - }; + ) /*************************************************************************/ @@ -373,11 +370,11 @@ /* if it is a bitmap, that's easy :-) */ if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - clazz = &ft_bitmap_glyph_class; + clazz = FT_BITMAP_GLYPH_CLASS_GET; - /* it it is an outline too */ + /* if it is an outline */ else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - clazz = &ft_outline_glyph_class; + clazz = FT_OUTLINE_GLYPH_CLASS_GET; else { @@ -518,6 +515,10 @@ const FT_Glyph_Class* clazz; +#ifdef FT_CONFIG_OPTION_PIC + FT_Library library = FT_GLYPH( glyph )->library; +#endif + /* check argument */ if ( !the_glyph ) @@ -533,7 +534,7 @@ clazz = glyph->clazz; /* when called with a bitmap glyph, do nothing and return successfully */ - if ( clazz == &ft_bitmap_glyph_class ) + if ( clazz == FT_BITMAP_GLYPH_CLASS_GET ) goto Exit; if ( !clazz || !clazz->glyph_prepare ) @@ -546,7 +547,7 @@ dummy.format = clazz->glyph_format; /* create result bitmap glyph */ - error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class, + error = ft_new_glyph( glyph->library, FT_BITMAP_GLYPH_CLASS_GET, (FT_Glyph*)(void*)&bitmap ); if ( error ) goto Exit; diff --git a/src/base/ftinit.c b/src/base/ftinit.c index dac30b0..1914228 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 by */ +/* Copyright 1996-2001, 2002, 2005, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,6 +42,7 @@ #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include FT_MODULE_H +#include "basepic.h" /*************************************************************************/ @@ -53,6 +54,8 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_init +#ifndef FT_CONFIG_OPTION_PIC + #undef FT_USE_MODULE #ifdef __cplusplus #define FT_USE_MODULE( type, x ) extern "C" const type x; @@ -74,6 +77,99 @@ 0 }; +#else /* FT_CONFIG_OPTION_PIC */ + +#ifdef __cplusplus +#define FT_EXTERNC extern "C" +#else +#define FT_EXTERNC extern +#endif + + /* declare the module's class creation/destruction functions */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + FT_EXTERNC FT_Error FT_Create_Class_##x( FT_Library library, FT_Module_Class** output_class ); \ + FT_EXTERNC void FT_Destroy_Class_##x( FT_Library library, FT_Module_Class* clazz ); + +#include FT_CONFIG_MODULES_H + + + /* count all module classes */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) MODULE_CLASS_##x, + + enum { +#include FT_CONFIG_MODULES_H + FT_NUM_MODULE_CLASSES + }; + + /* destroy all module classes */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + if ( classes[i] ) { FT_Destroy_Class_##x(library, classes[i]); } \ + i++; \ + + FT_BASE_DEF( void ) + ft_destroy_default_module_classes( FT_Library library ) + { + FT_Module_Class** classes; + FT_Memory memory; + FT_UInt i; + BasePIC* pic_container = (BasePIC*)library->pic_container.base; + + if ( !pic_container->default_module_classes ) + return; + + memory = library->memory; + classes = pic_container->default_module_classes; + i = 0; + +#include FT_CONFIG_MODULES_H + + FT_FREE( classes ); + pic_container->default_module_classes = 0; + } + + /* initialize all module classes and the pointer table */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + error = FT_Create_Class_##x(library, &clazz); \ + if (error) goto Exit; \ + classes[i++] = clazz; + + FT_BASE_DEF( FT_Error ) + ft_create_default_module_classes( FT_Library library ) + { + FT_Error error; + FT_Memory memory; + FT_Module_Class** classes; + FT_Module_Class* clazz; + FT_UInt i; + BasePIC* pic_container = (BasePIC*)library->pic_container.base; + + memory = library->memory; + pic_container->default_module_classes = 0; + + if ( FT_ALLOC(classes, sizeof(FT_Module_Class*) * (FT_NUM_MODULE_CLASSES + 1) ) ) + return error; + /* initialize all pointers to 0, especially the last one */ + for (i = 0; i < FT_NUM_MODULE_CLASSES; i++) + classes[i] = 0; + classes[FT_NUM_MODULE_CLASSES] = 0; + + i = 0; + +#include FT_CONFIG_MODULES_H + +Exit: + if (error) ft_destroy_default_module_classes( library ); + else pic_container->default_module_classes = classes; + + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ /* documentation is in ftmodapi.h */ @@ -86,16 +182,15 @@ /* test for valid `library' delayed to FT_Add_Module() */ - cur = ft_default_modules; + cur = FT_DEFAULT_MODULES_GET; while ( *cur ) { error = FT_Add_Module( library, *cur ); /* notify errors, but don't stop */ if ( error ) - { - FT_ERROR(( "FT_Add_Default_Module: Cannot install `%s', error = 0x%x\n", + FT_TRACE0(( "FT_Add_Default_Module:" + " Cannot install `%s', error = 0x%x\n", (*cur)->module_name, error )); - } cur++; } } @@ -127,13 +222,7 @@ if ( error ) FT_Done_Memory( memory ); else - { - (*alibrary)->version_major = FREETYPE_MAJOR; - (*alibrary)->version_minor = FREETYPE_MINOR; - (*alibrary)->version_patch = FREETYPE_PATCH; - FT_Add_Default_Modules( *alibrary ); - } return error; } diff --git a/src/base/ftnames.c b/src/base/ftnames.c deleted file mode 100644 index 7fde5c4..0000000 --- a/src/base/ftnames.c +++ /dev/null @@ -1,94 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftnames.c */ -/* */ -/* Simple interface to access SFNT name tables (which are used */ -/* to hold font names, copyright info, notices, etc.) (body). */ -/* */ -/* This is _not_ used to retrieve glyph names! */ -/* */ -/* Copyright 1996-2001, 2002 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 -#include FT_SFNT_NAMES_H -#include FT_INTERNAL_TRUETYPE_TYPES_H -#include FT_INTERNAL_STREAM_H - - -#ifdef TT_CONFIG_OPTION_SFNT_NAMES - - - /* documentation is in ftnames.h */ - - FT_EXPORT_DEF( FT_UInt ) - FT_Get_Sfnt_Name_Count( FT_Face face ) - { - return (face && FT_IS_SFNT( face )) ? ((TT_Face)face)->num_names : 0; - } - - - /* documentation is in ftnames.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Sfnt_Name( FT_Face face, - FT_UInt idx, - FT_SfntName *aname ) - { - FT_Error error = FT_Err_Invalid_Argument; - - - if ( aname && face && FT_IS_SFNT( face ) ) - { - TT_Face ttface = (TT_Face)face; - - - if ( idx < (FT_UInt)ttface->num_names ) - { - TT_NameEntryRec* entry = ttface->name_table.names + idx; - - - /* load name on demand */ - if ( entry->stringLength > 0 && entry->string == NULL ) - { - FT_Memory memory = face->memory; - FT_Stream stream = face->stream; - - - if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || - FT_STREAM_SEEK( entry->stringOffset ) || - FT_STREAM_READ( entry->string, entry->stringLength ) ) - { - FT_FREE( entry->string ); - entry->stringLength = 0; - } - } - - aname->platform_id = entry->platformID; - aname->encoding_id = entry->encodingID; - aname->language_id = entry->languageID; - aname->name_id = entry->nameID; - aname->string = (FT_Byte*)entry->string; - aname->string_len = entry->stringLength; - - error = FT_Err_Ok; - } - } - - return error; - } - - -#endif /* TT_CONFIG_OPTION_SFNT_NAMES */ - - -/* END */ diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 72dea33..a32b2cd 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -4,7 +4,8 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -37,7 +38,9 @@ #include FT_SERVICE_KERNING_H #include FT_SERVICE_TRUETYPE_ENGINE_H +#ifdef FT_CONFIG_OPTION_MAC_FONTS #include "ftbase.h" +#endif #define GRID_FIT_METRICS @@ -348,6 +351,9 @@ /* free bitmap buffer if needed */ ft_glyphslot_free_bitmap( slot ); + /* slot->internal might be NULL in out-of-memory situations */ + if ( slot->internal ) + { /* free glyph loader */ if ( FT_DRIVER_USES_OUTLINES( driver ) ) { @@ -356,6 +362,7 @@ } FT_FREE( slot->internal ); + } } @@ -588,17 +595,17 @@ * Determine whether we need to auto-hint or not. * The general rules are: * - * - Do only auto-hinting if we have a hinter module, - * a scalable font format dealing with outlines, - * and no transforms except simple slants. + * - Do only auto-hinting if we have a hinter module, a scalable font + * format dealing with outlines, and no transforms except simple + * slants and/or rotations by integer multiples of 90 degrees. * - * - Then, autohint if FT_LOAD_FORCE_AUTOHINT is set - * or if we don't have a native font hinter. + * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't + * have a native font hinter. * * - Otherwise, auto-hint for LIGHT hinting mode. * - * - Exception: The font is `tricky' and requires - * the native hinter to load properly. + * - Exception: The font is `tricky' and requires the native hinter to + * load properly. */ if ( hinter && @@ -607,8 +614,10 @@ FT_DRIVER_IS_SCALABLE( driver ) && FT_DRIVER_USES_OUTLINES( driver ) && !FT_IS_TRICKY( face ) && - face->internal->transform_matrix.yy > 0 && - face->internal->transform_matrix.yx == 0 ) + ( ( face->internal->transform_matrix.yx == 0 && + face->internal->transform_matrix.xx != 0 ) || + ( face->internal->transform_matrix.xx == 0 && + face->internal->transform_matrix.yx != 0 ) ) ) { if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) || !FT_DRIVER_HAS_HINTER( driver ) ) @@ -733,11 +742,30 @@ renderer, slot, &internal->transform_matrix, &internal->transform_delta ); + else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* apply `standard' transformation if no renderer is available */ + if ( &internal->transform_matrix ) + FT_Outline_Transform( &slot->outline, + &internal->transform_matrix ); + + if ( &internal->transform_delta ) + FT_Outline_Translate( &slot->outline, + internal->transform_delta.x, + internal->transform_delta.y ); + } + /* transform advance */ FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); } } + FT_TRACE5(( " x advance: %d\n" , slot->advance.x )); + FT_TRACE5(( " y advance: %d\n" , slot->advance.y )); + + FT_TRACE5(( " linear x advance: %d\n" , slot->linearHoriAdvance )); + FT_TRACE5(( " linear y advance: %d\n" , slot->linearVertAdvance )); + /* do we need to render the image now? */ if ( !error && slot->format != FT_GLYPH_FORMAT_BITMAP && @@ -2398,12 +2426,24 @@ ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, FT_Pos advance ) { + FT_Pos height = metrics->height; + + + /* compensate for glyph with bbox above/below the baseline */ + if ( metrics->horiBearingY < 0 ) + { + if ( height < metrics->horiBearingY ) + height = metrics->horiBearingY; + } + else if ( metrics->horiBearingY > 0 ) + height -= metrics->horiBearingY; + /* the factor 1.2 is a heuristical value */ if ( !advance ) - advance = metrics->height * 12 / 10; + advance = height * 12 / 10; - metrics->vertBearingX = -( metrics->width / 2 ); - metrics->vertBearingY = ( advance - metrics->height ) / 2; + metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2; + metrics->vertBearingY = ( advance - height ) / 2; metrics->vertAdvance = advance; } @@ -3048,7 +3088,12 @@ FT_CMap cmap = FT_CMAP( face->charmap ); - result = cmap->clazz->char_index( cmap, charcode ); + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode ); } return result; } @@ -3128,8 +3173,20 @@ FT_CMap vcmap = FT_CMAP( charmap ); - result = vcmap->clazz->char_var_index( vcmap, ucmap, charcode, - variantSelector ); + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_index( vcmap, ucmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); } } @@ -3157,8 +3214,20 @@ FT_CMap vcmap = FT_CMAP( charmap ); - result = vcmap->clazz->char_var_default( vcmap, charcode, - variantSelector ); + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_default( vcmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); } } @@ -3213,7 +3282,14 @@ FT_Memory memory = FT_FACE_MEMORY( face ); - result = vcmap->clazz->charvariant_list( vcmap, memory, charcode ); + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + + result = vcmap->clazz->charvariant_list( vcmap, memory, + (FT_UInt32)charcode ); } } return result; @@ -3240,8 +3316,14 @@ FT_Memory memory = FT_FACE_MEMORY( face ); + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + result = vcmap->clazz->variantchar_list( vcmap, memory, - variantSelector ); + (FT_UInt32)variantSelector ); } } @@ -3291,7 +3373,7 @@ ((FT_Byte*)buffer)[0] = 0; if ( face && - glyph_index <= (FT_UInt)face->num_glyphs && + (FT_Long)glyph_index <= face->num_glyphs && FT_HAS_GLYPH_NAMES( face ) ) { FT_Service_GlyphDict service; @@ -3391,6 +3473,7 @@ FT_ULong *length ) { FT_Service_SFNT_Table service; + FT_ULong offset; if ( !face || !FT_IS_SFNT( face ) ) @@ -3400,7 +3483,7 @@ if ( service == NULL ) return FT_Err_Unimplemented_Feature; - return service->table_info( face, table_index, tag, length ); + return service->table_info( face, table_index, tag, &offset, length ); } @@ -4123,6 +4206,13 @@ library->memory = memory; +#ifdef FT_CONFIG_OPTION_PIC + /* initialize position independent code containers */ + error = ft_pic_container_init( library ); + if ( error ) + goto Fail; +#endif + /* allocate the render pool */ library->raster_pool_size = FT_RENDER_POOL_SIZE; #if FT_RENDER_POOL_SIZE > 0 @@ -4130,12 +4220,19 @@ goto Fail; #endif + library->version_major = FREETYPE_MAJOR; + library->version_minor = FREETYPE_MINOR; + library->version_patch = FREETYPE_PATCH; + /* That's ok now */ *alibrary = library; return FT_Err_Ok; Fail: +#ifdef FT_CONFIG_OPTION_PIC + ft_pic_container_destroy( library ); +#endif FT_FREE( library ); return error; } @@ -4216,7 +4313,7 @@ { FT_Done_Face( FT_FACE( faces->head->data ) ); if ( faces->head ) - FT_ERROR(( "FT_Done_Library: failed to free some faces\n" )); + FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" )); } } } @@ -4252,6 +4349,11 @@ FT_FREE( library->raster_pool ); library->raster_pool_size = 0; +#ifdef FT_CONFIG_OPTION_PIC + /* Destroy pic container contents */ + ft_pic_container_destroy( library ); +#endif + FT_FREE( library ); return FT_Err_Ok; } diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c index 49ef82e..5bb6ef3 100644 --- a/src/base/ftoutln.c +++ b/src/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -304,7 +304,7 @@ *anoutline = null_outline; - if ( FT_NEW_ARRAY( anoutline->points, numPoints * 2L ) || + if ( FT_NEW_ARRAY( anoutline->points, numPoints ) || FT_NEW_ARRAY( anoutline->tags, numPoints ) || FT_NEW_ARRAY( anoutline->contours, numContours ) ) goto Fail; diff --git a/src/base/ftpatent.c b/src/base/ftpatent.c index 9f129d8..af29786 100644 --- a/src/base/ftpatent.c +++ b/src/base/ftpatent.c @@ -5,7 +5,7 @@ /* FreeType API for checking patented TrueType bytecode instructions */ /* (body). */ /* */ -/* Copyright 2007, 2008 by David Turner. */ +/* Copyright 2007, 2008, 2010 by David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -103,6 +103,7 @@ } Exit: + FT_UNUSED( error ); FT_FRAME_EXIT(); return result; } @@ -113,7 +114,7 @@ FT_ULong tag ) { FT_Stream stream = face->stream; - FT_Error error; + FT_Error error = FT_Err_Ok; FT_Service_SFNT_Table service; FT_Bool result = FALSE; @@ -122,15 +123,19 @@ if ( service ) { - FT_ULong offset, size; + FT_UInt i = 0; + FT_ULong tag_i = 0, offset_i = 0, length_i = 0; - error = service->table_info( face, tag, &offset, &size ); + for ( i = 0; !error && tag_i != tag ; i++ ) + error = service->table_info( face, i, + &tag_i, &offset_i, &length_i ); + if ( error || - FT_STREAM_SEEK( offset ) ) + FT_STREAM_SEEK( offset_i ) ) goto Exit; - result = _tt_check_patents_in_range( stream, size ); + result = _tt_check_patents_in_range( stream, length_i ); } Exit: diff --git a/src/base/ftpic.c b/src/base/ftpic.c new file mode 100644 index 0000000..d5271a9 --- /dev/null +++ b/src/base/ftpic.c @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* ftpic.c */ +/* */ +/* The FreeType position independent code services (body). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "basepic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* documentation is in ftpic.h */ + + FT_BASE_DEF( FT_Error ) + ft_pic_container_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + + FT_MEM_SET( pic_container, 0, sizeof(*pic_container) ); + + error = ft_base_pic_init( library ); + if(error) + return error; + + return FT_Err_Ok; + } + + + /* Destroy the contents of the container. */ + FT_BASE_DEF( void ) + ft_pic_container_destroy( FT_Library library ) + { + ft_base_pic_free( library ); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c index d59a076..133c2de 100644 --- a/src/base/ftrfork.c +++ b/src/base/ftrfork.c @@ -752,9 +752,9 @@ const char *insertion ) { char* new_name; - char* tmp; + const char* tmp; const char* slash; - unsigned new_length; + size_t new_length; FT_Error error = FT_Err_Ok; FT_UNUSED( error ); diff --git a/src/base/ftsnames.c b/src/base/ftsnames.c new file mode 100644 index 0000000..3447888 --- /dev/null +++ b/src/base/ftsnames.c @@ -0,0 +1,94 @@ +/***************************************************************************/ +/* */ +/* ftsnames.c */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (body). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2001, 2002, 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. */ +/* */ +/***************************************************************************/ + + +#include +#include FT_SFNT_NAMES_H +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_STREAM_H + + +#ifdef TT_CONFIG_OPTION_SFNT_NAMES + + + /* documentation is in ftsnames.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ) + { + return ( face && FT_IS_SFNT( face ) ) ? ((TT_Face)face)->num_names : 0; + } + + + /* documentation is in ftsnames.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ) + { + FT_Error error = FT_Err_Invalid_Argument; + + + if ( aname && face && FT_IS_SFNT( face ) ) + { + TT_Face ttface = (TT_Face)face; + + + if ( idx < (FT_UInt)ttface->num_names ) + { + TT_NameEntryRec* entry = ttface->name_table.names + idx; + + + /* load name on demand */ + if ( entry->stringLength > 0 && entry->string == NULL ) + { + FT_Memory memory = face->memory; + FT_Stream stream = face->stream; + + + if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || + FT_STREAM_SEEK( entry->stringOffset ) || + FT_STREAM_READ( entry->string, entry->stringLength ) ) + { + FT_FREE( entry->string ); + entry->stringLength = 0; + } + } + + aname->platform_id = entry->platformID; + aname->encoding_id = entry->encodingID; + aname->language_id = entry->languageID; + aname->name_id = entry->nameID; + aname->string = (FT_Byte*)entry->string; + aname->string_len = entry->stringLength; + + error = FT_Err_Ok; + } + } + + return error; + } + + +#endif /* TT_CONFIG_OPTION_SFNT_NAMES */ + + +/* END */ diff --git a/src/base/ftstream.c b/src/base/ftstream.c index cff67e0..b638599 100644 --- a/src/base/ftstream.c +++ b/src/base/ftstream.c @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008 by */ +/* Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -60,13 +60,12 @@ FT_Error error = FT_Err_Ok; - stream->pos = pos; - if ( stream->read ) { if ( stream->read( stream, pos, 0, 0 ) ) { - FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_Seek:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", pos, stream->size )); error = FT_Err_Invalid_Stream_Operation; @@ -75,12 +74,16 @@ /* note that seeking to the first position after the file is valid */ else if ( pos > stream->size ) { - FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_Seek:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", pos, stream->size )); error = FT_Err_Invalid_Stream_Operation; } + if ( !error ) + stream->pos = pos; + return error; } @@ -124,7 +127,8 @@ if ( pos >= stream->size ) { - FT_ERROR(( "FT_Stream_ReadAt: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadAt:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", pos, stream->size )); return FT_Err_Invalid_Stream_Operation; @@ -145,8 +149,8 @@ if ( read_bytes < count ) { - FT_ERROR(( "FT_Stream_ReadAt:" )); - FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", + FT_ERROR(( "FT_Stream_ReadAt:" + " invalid read; expected %lu bytes, got %lu\n", count, read_bytes )); error = FT_Err_Invalid_Stream_Operation; @@ -211,7 +215,7 @@ FT_Stream_ReleaseFrame( FT_Stream stream, FT_Byte** pbytes ) { - if ( stream->read ) + if ( stream && stream->read ) { FT_Memory memory = stream->memory; @@ -256,8 +260,8 @@ stream->base, count ); if ( read_bytes < count ) { - FT_ERROR(( "FT_Stream_EnterFrame:" )); - FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", + FT_ERROR(( "FT_Stream_EnterFrame:" + " invalid read; expected %lu bytes, got %lu\n", count, read_bytes )); FT_FREE( stream->base ); @@ -273,8 +277,8 @@ if ( stream->pos >= stream->size || stream->pos + count > stream->size ) { - FT_ERROR(( "FT_Stream_EnterFrame:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_EnterFrame:" + " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", stream->pos, count, stream->size )); error = FT_Err_Invalid_Stream_Operation; @@ -459,7 +463,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadChar: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadChar:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -505,8 +510,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadShort:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadShort:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -552,8 +557,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadShortLE:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadShortLE:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -599,8 +604,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadOffset:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadOffset:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -645,9 +650,10 @@ return result; Fail: - FT_ERROR(( "FT_Stream_ReadLong: invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadLong:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); return 0; } @@ -691,10 +697,10 @@ return result; Fail: - FT_ERROR(( "FT_Stream_ReadLongLE:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadLongLE:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); return 0; } diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c index 3f5421f..75bcbde 100644 --- a/src/base/ftstroke.c +++ b/src/base/ftstroke.c @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -706,7 +706,7 @@ FT_Bool valid; FT_StrokeBorderRec borders[2]; - FT_Memory memory; + FT_Library library; } FT_StrokerRec; @@ -729,7 +729,7 @@ if ( !FT_NEW( stroker ) ) { - stroker->memory = memory; + stroker->library = library; ft_stroke_border_init( &stroker->borders[0], memory ); ft_stroke_border_init( &stroker->borders[1], memory ); @@ -777,13 +777,13 @@ { if ( stroker ) { - FT_Memory memory = stroker->memory; + FT_Memory memory = stroker->library->memory; ft_stroke_border_done( &stroker->borders[0] ); ft_stroke_border_done( &stroker->borders[1] ); - stroker->memory = NULL; + stroker->library = NULL; FT_FREE( stroker ); } } @@ -859,6 +859,31 @@ error = ft_stroke_border_lineto( border, &delta, FALSE ); } + else if ( stroker->line_cap == FT_STROKER_LINECAP_BUTT ) + { + /* add a butt ending */ + FT_Vector delta; + FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); + FT_Fixed radius = stroker->radius; + FT_StrokeBorder border = stroker->borders + side; + + + FT_Vector_From_Polar( &delta, radius, angle + rotate ); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + FT_Vector_From_Polar( &delta, radius, angle - rotate ); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + } Exit: return error; @@ -954,7 +979,8 @@ thcos = FT_Cos( theta ); sigma = FT_MulFix( stroker->miter_limit, thcos ); - if ( sigma >= 0x10000L ) + /* FT_Sin(x) = 0 for x <= 57 */ + if ( sigma >= 0x10000L || ft_pos_abs( theta ) <= 57 ) miter = FALSE; if ( miter ) /* this is a miter (broken angle) */ @@ -1335,7 +1361,7 @@ phi1 = (angle_mid + angle_in ) / 2; phi2 = (angle_mid + angle_out ) / 2; length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) ); - length2 = FT_DivFix( stroker->radius, FT_Cos(theta2) ); + length2 = FT_DivFix( stroker->radius, FT_Cos( theta2 ) ); for ( side = 0; side <= 1; side++ ) { @@ -1710,13 +1736,10 @@ } else { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ + /* if both first and last points are conic, */ + /* start at their middle */ v_start.x = ( v_start.x + v_last.x ) / 2; v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; } point--; tags--; @@ -1844,8 +1867,13 @@ return FT_Err_Invalid_Outline; } - +/* declare an extern to access ft_outline_glyph_class global allocated + in ftglyph.c, and use the FT_OUTLINE_GLYPH_CLASS_GET macro to access + it when FT_CONFIG_OPTION_PIC is defined */ +#ifndef FT_CONFIG_OPTION_PIC extern const FT_Glyph_Class ft_outline_glyph_class; +#endif +#include "basepic.h" /* documentation is in ftstroke.h */ @@ -1857,13 +1885,14 @@ { FT_Error error = FT_Err_Invalid_Argument; FT_Glyph glyph = NULL; - + FT_Library library = stroker->library; + FT_UNUSED(library); if ( pglyph == NULL ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) + if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { @@ -1930,13 +1959,14 @@ { FT_Error error = FT_Err_Invalid_Argument; FT_Glyph glyph = NULL; - + FT_Library library = stroker->library; + FT_UNUSED(library); if ( pglyph == NULL ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) + if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c index 443d272..ba3c633 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 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,11 +18,21 @@ #include #include FT_SYNTHESIS_H +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H #include FT_OUTLINE_H #include FT_BITMAP_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_synth + /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -90,8 +100,8 @@ if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) { - error = FT_Outline_Embolden( &slot->outline, xstr ); /* 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 */ @@ -106,6 +116,18 @@ xstr = 1 << 6; ystr &= ~63; + /* + * XXX: overflow check for 16-bit system, for compatibility + * with FT_GlyphSlot_Embolden() since freetype-2.1.10. + * unfortunately, this function return no informations + * about the cause of error. + */ + if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN ) + { + FT_TRACE1(( "FT_GlyphSlot_Embolden:" )); + FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr )); + return; + } error = FT_GlyphSlot_Own_Bitmap( slot ); if ( error ) return; @@ -129,8 +151,9 @@ slot->metrics.vertBearingY += ystr; slot->metrics.vertAdvance += ystr; + /* XXX: 16-bit overflow case must be excluded before here */ if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - slot->bitmap_top += ystr >> 6; + slot->bitmap_top += (FT_Int)( ystr >> 6 ); } diff --git a/src/base/ftsystem.c b/src/base/ftsystem.c index f64908f..4d06d6d 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-2001, 2002, 2006, 2008 by */ +/* Copyright 1996-2001, 2002, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -205,7 +205,8 @@ file = STREAM_FILE( stream ); - ft_fseek( file, offset, SEEK_SET ); + if ( stream->pos != offset ) + ft_fseek( file, offset, SEEK_SET ); return (unsigned long)ft_fread( buffer, 1, count, file ); } @@ -226,8 +227,8 @@ file = ft_fopen( filepathname, "rb" ); if ( !file ) { - FT_ERROR(( "FT_Stream_Open:" )); - FT_ERROR(( " could not open `%s'\n", filepathname )); + FT_ERROR(( "FT_Stream_Open:" + " could not open `%s'\n", filepathname )); return FT_Err_Cannot_Open_Resource; } diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c index 9f51394..fdf433a 100644 --- a/src/base/fttrigon.c +++ b/src/base/fttrigon.c @@ -72,10 +72,10 @@ val = ( val >= 0 ) ? val : -val; v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)val & 0xFFFFL; + v2 = (FT_UInt32)(val & 0xFFFFL); - k1 = FT_TRIG_SCALE >> 16; /* constant */ - k2 = 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 */ @@ -86,7 +86,7 @@ hi += lo1 >> 16; if ( lo1 < lo3 ) - hi += 0x10000UL; + hi += (FT_UInt32)0x10000UL; val = (FT_Fixed)hi; @@ -433,7 +433,7 @@ if ( shift > 0 ) { - FT_Int32 half = 1L << ( shift - 1 ); + FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; diff --git a/src/cff/cff.c b/src/cff/cff.c index e6d8954..fccfd44 100644 --- a/src/cff/cff.c +++ b/src/cff/cff.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include +#include "cffpic.c" #include "cffdrivr.c" #include "cffparse.c" #include "cffload.c" diff --git a/src/cff/cffcmap.c b/src/cff/cffcmap.c index 578d048..46d603e 100644 --- a/src/cff/cffcmap.c +++ b/src/cff/cffcmap.c @@ -65,7 +65,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) cff_cmap_encoding_char_next( CFF_CMapStd cmap, FT_UInt32 *pchar_code ) { @@ -99,9 +99,7 @@ } - FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec - cff_cmap_encoding_class_rec = - { + FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec, sizeof ( CFF_CMapStdRec ), (FT_CMap_InitFunc) cff_cmap_encoding_init, @@ -110,7 +108,7 @@ (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, NULL, NULL, NULL, NULL, NULL - }; + ) /*************************************************************************/ @@ -194,7 +192,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) cff_cmap_unicode_char_next( PS_Unicodes unicodes, FT_UInt32 *pchar_code ) { @@ -207,9 +205,7 @@ } - FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec - cff_cmap_unicode_class_rec = - { + FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec, sizeof ( PS_UnicodesRec ), (FT_CMap_InitFunc) cff_cmap_unicode_init, @@ -218,7 +214,6 @@ (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, NULL, NULL, NULL, NULL, NULL - }; - + ) /* END */ diff --git a/src/cff/cffcmap.h b/src/cff/cffcmap.h index 3809b85..3f7f67b 100644 --- a/src/cff/cffcmap.h +++ b/src/cff/cffcmap.h @@ -43,8 +43,7 @@ FT_BEGIN_HEADER } CFF_CMapStdRec; - FT_CALLBACK_TABLE const FT_CMap_ClassRec - cff_cmap_encoding_class_rec; + FT_DECLARE_CMAP_CLASS(cff_cmap_encoding_class_rec) /*************************************************************************/ @@ -57,8 +56,7 @@ FT_BEGIN_HEADER /* unicode (synthetic) cmaps */ - FT_CALLBACK_TABLE const FT_CMap_ClassRec - cff_cmap_unicode_class_rec; + FT_DECLARE_CMAP_CLASS(cff_cmap_unicode_class_rec) FT_END_HEADER diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c index 3dd86f2..dad0b65 100644 --- a/src/cff/cffdrivr.c +++ b/src/cff/cffdrivr.c @@ -21,7 +21,6 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_IDS_H #include FT_SERVICE_CID_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SERVICE_POSTSCRIPT_INFO_H @@ -32,8 +31,10 @@ #include "cffgload.h" #include "cffload.h" #include "cffcmap.h" +#include "cffparse.h" #include "cfferrs.h" +#include "cffpic.h" #include FT_SERVICE_XFREE86_NAME_H #include FT_SERVICE_GLYPH_DICT_H @@ -199,7 +200,7 @@ FT_GlyphSlot slot = face->glyph; - flags |= FT_LOAD_ADVANCE_ONLY; + flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; for ( nn = 0; nn < count; nn++ ) { @@ -238,10 +239,10 @@ FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) { - FT_ERROR(( "cff_get_glyph_name:" )); - FT_ERROR(( " cannot get glyph name from CFF & CEF fonts\n" )); - FT_ERROR(( " " )); - FT_ERROR(( " without the `PSNames' module\n" )); + FT_ERROR(( "cff_get_glyph_name:" + " cannot get glyph name from CFF & CEF fonts\n" + " " + " without the `PSNames' module\n" )); error = CFF_Err_Unknown_File_Format; goto Exit; } @@ -309,11 +310,10 @@ } - static const FT_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, - }; + (FT_GlyphDict_NameIndexFunc)cff_get_name_index + ) /* @@ -378,13 +378,12 @@ } - static const FT_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, (PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */ - }; + ) /* @@ -402,10 +401,9 @@ } - static const FT_Service_PsFontNameRec cff_service_ps_name = - { + FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name, (FT_PsName_GetFunc)cff_get_ps_name - }; + ) /* @@ -424,16 +422,16 @@ { 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 ); cmap_info->language = 0; cmap_info->format = 0; - if ( cmap->clazz != &cff_cmap_encoding_class_rec && - cmap->clazz != &cff_cmap_unicode_class_rec ) + if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET && + cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET ) { - FT_Face face = FT_CMAP_FACE( cmap ); - FT_Library library = FT_FACE_LIBRARY( face ); FT_Module sfnt = FT_Get_Module( library, "sfnt" ); FT_Service_TTCMaps service = (FT_Service_TTCMaps)ft_module_get_service( sfnt, @@ -448,10 +446,9 @@ } - static const FT_Service_TTCMapsRec cff_service_get_cmap_info = - { + FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info, (TT_CMap_Info_GetFunc)cff_get_cmap_info - }; + ) /* @@ -498,8 +495,19 @@ *ordering = cff->ordering; } + /* + * XXX: According to Adobe TechNote #5176, the supplement in CFF + * can be a real number. We truncate it to fit public API + * since freetype-2.3.6. + */ if ( supplement ) - *supplement = dict->cid_supplement; + { + if ( dict->cid_supplement < FT_INT_MIN || + dict->cid_supplement > FT_INT_MAX ) + FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n", + dict->cid_supplement )); + *supplement = (FT_Int)dict->cid_supplement; + } } Fail: @@ -570,12 +578,11 @@ } - static const FT_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 - }; + ) /*************************************************************************/ @@ -589,20 +596,24 @@ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ - - static const FT_ServiceDescRec cff_services[] = - { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF }, - { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info }, - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name }, #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES - { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict }, + FT_DEFINE_SERVICEDESCREC6(cff_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_CFF_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET + ) +#else + FT_DEFINE_SERVICEDESCREC5(cff_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET + ) #endif - { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info }, - { FT_SERVICE_ID_CID, &cff_service_cid_info }, - { NULL, NULL } - }; - FT_CALLBACK_DEF( FT_Module_Interface ) cff_get_interface( FT_Module driver, /* CFF_Driver */ @@ -612,10 +623,13 @@ FT_Module_Interface result; - result = ft_service_list_lookup( cff_services, module_interface ); + result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface ); if ( result != NULL ) return result; + if ( !driver ) + return NULL; + /* we pass our request to the `sfnt' module */ sfnt = FT_Get_Module( driver->library, "sfnt" ); @@ -625,11 +639,13 @@ /* The FT_DriverInterface structure is defined in ftdriver.h. */ - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec cff_driver_class = - { - /* begin with the FT_Module_Class fields */ - { +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define CFF_SIZE_SELECT cff_size_select +#else +#define CFF_SIZE_SELECT 0 +#endif + + FT_DEFINE_DRIVER(cff_driver_class, FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | FT_MODULE_DRIVER_HAS_HINTER, @@ -644,7 +660,6 @@ cff_driver_init, cff_driver_done, cff_get_interface, - }, /* now the specific driver fields */ sizeof( TT_FaceRec ), @@ -658,10 +673,8 @@ cff_slot_init, cff_slot_done, -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - ft_stub_set_char_sizes, - ft_stub_set_pixel_sizes, -#endif + ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ Load_Glyph, @@ -671,12 +684,8 @@ cff_size_request, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - cff_size_select -#else - 0 /* FT_Size_SelectFunc */ -#endif - }; + CFF_SIZE_SELECT + ) /* END */ diff --git a/src/cff/cffdrivr.h b/src/cff/cffdrivr.h index 553848c..50e8138 100644 --- a/src/cff/cffdrivr.h +++ b/src/cff/cffdrivr.h @@ -27,8 +27,7 @@ FT_BEGIN_HEADER - FT_CALLBACK_TABLE - const FT_Driver_ClassRec cff_driver_class; + FT_DECLARE_DRIVER( cff_driver_class ) FT_END_HEADER diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c index 2718a27..9330c05 100644 --- a/src/cff/cffgload.c +++ b/src/cff/cffgload.c @@ -4,7 +4,8 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,11 +19,9 @@ #include #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H #include FT_OUTLINE_H -#include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include "cffobjs.h" @@ -115,6 +114,9 @@ cff_op_closepath, cff_op_callothersubr, cff_op_pop, + cff_op_seac, + cff_op_sbw, + cff_op_setcurrentpoint, /* do not remove */ cff_op_max @@ -203,7 +205,10 @@ 2, /* hsbw */ 0, 0, - 0 + 0, + 5, /* seac */ + 4, /* sbw */ + 2 /* setcurrentpoint */ }; @@ -321,17 +326,23 @@ /* subroutines. */ /* */ /* */ - /* num_subrs :: The number of glyph subroutines. */ + /* in_charstring_type :: The `CharstringType' value of the top DICT */ + /* dictionary. */ + /* */ + /* num_subrs :: The number of glyph subroutines. */ /* */ /* */ /* The bias value. */ static FT_Int - cff_compute_bias( FT_UInt num_subrs ) + cff_compute_bias( FT_Int in_charstring_type, + FT_UInt num_subrs ) { FT_Int result; - if ( num_subrs < 1240 ) + if ( in_charstring_type == 1 ) + result = 0; + else if ( num_subrs < 1240 ) result = 107; else if ( num_subrs < 33900U ) result = 1131; @@ -382,9 +393,12 @@ cff_builder_init( &decoder->builder, face, size, slot, hinting ); /* initialize Type2 decoder */ + decoder->cff = cff; decoder->num_globals = cff->num_global_subrs; decoder->globals = cff->global_subrs; - decoder->globals_bias = cff_compute_bias( decoder->num_globals ); + decoder->globals_bias = cff_compute_bias( + cff->top_font.font_dict.charstring_type, + decoder->num_globals ); decoder->hint_mode = hint_mode; } @@ -436,7 +450,9 @@ decoder->num_locals = sub->num_local_subrs; decoder->locals = sub->local_subrs; - decoder->locals_bias = cff_compute_bias( decoder->num_locals ); + decoder->locals_bias = cff_compute_bias( + decoder->cff->top_font.font_dict.charstring_type, + decoder->num_locals ); decoder->glyph_width = sub->private_dict.default_width; decoder->nominal_width = sub->private_dict.nominal_width; @@ -474,8 +490,6 @@ point->x = x >> 16; point->y = y >> 16; *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); - - builder->last = *point; } outline->n_points++; @@ -554,27 +568,24 @@ cff_builder_close_contour( CFF_Builder* builder ) { FT_Outline* outline = builder->current; + FT_Int first; if ( !outline ) return; - /* XXXX: We must not include the last point in the path if it */ - /* is located on the first point. */ + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ if ( outline->n_points > 1 ) { - FT_Int first = 0; FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; - if ( outline->n_contours > 1 ) - { - first = outline->contours[outline->n_contours - 2] + 1; - p1 = outline->points + first; - } - /* `delete' last point only if it coincides with the first */ /* point and if it is not a control point (which can happen). */ if ( p1->x == p2->x && p1->y == p2->y ) @@ -583,8 +594,18 @@ } if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether begin point and last point are the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } } @@ -674,7 +695,7 @@ data.length = length; face->root.internal->incremental_interface->funcs->free_glyph_data( - face->root.internal->incremental_interface->object,&data ); + face->root.internal->incremental_interface->object, &data ); } else #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -690,6 +711,7 @@ static FT_Error cff_operator_seac( CFF_Decoder* decoder, + FT_Pos asb, FT_Pos adx, FT_Pos ady, FT_Int bchar, @@ -702,8 +724,18 @@ FT_Vector left_bearing, advance; FT_Byte* charstring; FT_ULong charstring_len; + FT_Pos glyph_width; + if ( decoder->seac ) + { + FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); + return CFF_Err_Syntax_Error; + } + + adx += decoder->builder.left_bearing.x; + ady += decoder->builder.left_bearing.y; + #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts don't necessarily have valid charsets. */ /* They use the character code, not the glyph index, in this case. */ @@ -724,8 +756,8 @@ if ( bchar_index < 0 || achar_index < 0 ) { - FT_ERROR(( "cff_operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); + FT_ERROR(( "cff_operator_seac:" + " invalid seac character code arguments\n" )); return CFF_Err_Syntax_Error; } @@ -774,8 +806,11 @@ &charstring, &charstring_len ); if ( !error ) { + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, charstring_len ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -783,16 +818,17 @@ cff_free_glyph_data( face, &charstring, charstring_len ); } - /* Save the left bearing and width of the base character */ - /* as they will be erased by the next load. */ + /* Save the left bearing, advance and glyph width of the base */ + /* character as they will be erased by the next load. */ left_bearing = builder->left_bearing; advance = builder->advance; + glyph_width = decoder->glyph_width; builder->left_bearing.x = 0; builder->left_bearing.y = 0; - builder->pos_x = adx; + builder->pos_x = adx - asb; builder->pos_y = ady; /* Now load `achar' on top of the base outline. */ @@ -800,8 +836,11 @@ &charstring, &charstring_len ); if ( !error ) { + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, charstring_len ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -809,10 +848,11 @@ cff_free_glyph_data( face, &charstring, charstring_len ); } - /* Restore the left side bearing and advance width */ - /* of the base character. */ + /* Restore the left side bearing, advance and glyph width */ + /* of the base character. */ builder->left_bearing = left_bearing; builder->advance = advance; + decoder->glyph_width = glyph_width; builder->pos_x = 0; builder->pos_y = 0; @@ -854,6 +894,8 @@ FT_Pos x, y; FT_Fixed seed; FT_Fixed* stack; + FT_Int charstring_type = + decoder->cff->top_font.font_dict.charstring_type; T2_Hints_Funcs hinter; @@ -863,9 +905,10 @@ decoder->read_width = 1; /* compute random seed from stack address of parameter */ - seed = (FT_Fixed)(char*)&seed ^ - (FT_Fixed)(char*)&decoder ^ - (FT_Fixed)(char*)&charstring_base; + seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ + (FT_PtrDist)(char*)&decoder ^ + (FT_PtrDist)(char*)&charstring_base ) & + FT_ULONG_MAX ) ; seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; if ( seed == 0 ) seed = 0x7384; @@ -920,18 +963,18 @@ ip += 2; } else if ( v < 247 ) - val = (FT_Long)v - 139; + val = (FT_Int32)v - 139; else if ( v < 251 ) { if ( ip >= limit ) goto Syntax_Error; - val = ( (FT_Long)v - 247 ) * 256 + *ip++ + 108; + val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108; } else if ( v < 255 ) { if ( ip >= limit ) goto Syntax_Error; - val = -( (FT_Long)v - 251 ) * 256 - *ip++ - 108; + val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108; } else { @@ -942,7 +985,8 @@ ( (FT_Int32)ip[2] << 8 ) | ip[3]; ip += 4; - shift = 0; + if ( charstring_type == 2 ) + shift = 0; } if ( decoder->top - stack >= CFF_MAX_OPERANDS ) goto Stack_Overflow; @@ -1016,6 +1060,12 @@ case 0: op = cff_op_dotsection; break; + case 1: /* this is actually the Type1 vstem3 operator */ + op = cff_op_vstem; + break; + case 2: /* this is actually the Type1 hstem3 operator */ + op = cff_op_hstem; + break; case 3: op = cff_op_and; break; @@ -1025,6 +1075,12 @@ case 5: op = cff_op_not; break; + case 6: + op = cff_op_seac; + break; + case 7: + op = cff_op_sbw; + break; case 8: op = cff_op_store; break; @@ -1088,6 +1144,9 @@ case 30: op = cff_op_roll; break; + case 33: + op = cff_op_setcurrentpoint; + break; case 34: op = cff_op_hflex; break; @@ -1155,7 +1214,7 @@ op = cff_op_hvcurveto; break; default: - ; + break; } if ( op == cff_op_unknown ) @@ -1870,6 +1929,21 @@ } break; + case cff_op_seac: + FT_TRACE4(( " seac\n" )); + + error = cff_operator_seac( decoder, + args[0], args[1], args[2], + (FT_Int)( args[3] >> 16 ), + (FT_Int)( args[4] >> 16 ) ); + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + + /* return now! */ + FT_TRACE4(( "\n" )); + return error; + case cff_op_endchar: FT_TRACE4(( " endchar\n" )); @@ -1879,10 +1953,8 @@ /* Save glyph width so that the subglyphs don't overwrite it. */ FT_Pos glyph_width = decoder->glyph_width; - error = cff_operator_seac( decoder, - args[-4], - args[-3], + 0L, args[-4], args[-3], (FT_Int)( args[-2] >> 16 ), (FT_Int)( args[-1] >> 16 ) ); @@ -2090,7 +2162,7 @@ FT_TRACE4(( " dup\n" )); args[1] = args[0]; - args++; + args += 2; break; case cff_op_put: @@ -2101,7 +2173,7 @@ FT_TRACE4(( " put\n" )); - if ( idx >= 0 && idx < decoder->len_buildchar ) + if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) decoder->buildchar[idx] = val; } break; @@ -2114,7 +2186,7 @@ FT_TRACE4(( " get\n" )); - if ( idx >= 0 && idx < decoder->len_buildchar ) + if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) val = decoder->buildchar[idx]; args[0] = val; @@ -2154,10 +2226,42 @@ FT_TRACE4(( " hsbw (invalid op)\n" )); - decoder->glyph_width = decoder->nominal_width + - (args[1] >> 16); - x = args[0]; - y = 0; + decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 ); + + decoder->builder.left_bearing.x = args[0]; + decoder->builder.left_bearing.y = 0; + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y; + args = stack; + break; + + case cff_op_sbw: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " sbw (invalid op)\n" )); + + decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 ); + + decoder->builder.left_bearing.x = args[0]; + decoder->builder.left_bearing.y = args[1]; + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y + args[1]; + args = stack; + break; + + case cff_op_setcurrentpoint: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y + args[1]; args = stack; break; @@ -2168,8 +2272,10 @@ FT_TRACE4(( " callothersubr (invalid op)\n" )); - /* don't modify stack; handle the subr as `unknown' so that */ - /* following `pop' operands use the arguments on stack */ + /* subsequent `pop' operands should add the arguments, */ + /* this is the implementation described for `unknown' other */ + /* subroutines in the Type1 spec. */ + args -= 2 + ( args[-2] >> 16 ); break; case cff_op_pop: @@ -2241,8 +2347,8 @@ if ( idx >= decoder->num_locals ) { - FT_ERROR(( "cff_decoder_parse_charstrings:" )); - FT_ERROR(( " invalid local subr index\n" )); + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid local subr index\n" )); goto Syntax_Error; } @@ -2263,7 +2369,7 @@ if ( !zone->base || zone->limit == zone->base ) { FT_ERROR(( "cff_decoder_parse_charstrings:" - " invoking empty subrs!\n" )); + " invoking empty subrs\n" )); goto Syntax_Error; } @@ -2283,8 +2389,8 @@ if ( idx >= decoder->num_globals ) { - FT_ERROR(( "cff_decoder_parse_charstrings:" )); - FT_ERROR(( " invalid global subr index\n" )); + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid global subr index\n" )); goto Syntax_Error; } @@ -2305,7 +2411,7 @@ if ( !zone->base || zone->limit == zone->base ) { FT_ERROR(( "cff_decoder_parse_charstrings:" - " invoking empty subrs!\n" )); + " invoking empty subrs\n" )); goto Syntax_Error; } @@ -2354,15 +2460,15 @@ return error; Syntax_Error: - FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error!\n" )); + FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); return CFF_Err_Invalid_File_Format; Stack_Underflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow!\n" )); + FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); return CFF_Err_Too_Few_Arguments; Stack_Overflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow!\n" )); + FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); return CFF_Err_Stack_Overflow; } @@ -2565,8 +2671,8 @@ FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index ); - FT_Int top_upm = cff->top_font.font_dict.units_per_em; - FT_Int sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em; + FT_ULong top_upm = cff->top_font.font_dict.units_per_em; + FT_ULong sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em; font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; @@ -2658,23 +2764,25 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ - if ( !error && - face->root.internal->incremental_interface && + if ( !error && + face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; metrics.bearing_x = decoder.builder.left_bearing.x; - metrics.bearing_y = decoder.builder.left_bearing.y; + metrics.bearing_y = 0; metrics.advance = decoder.builder.advance.x; + metrics.advance_v = decoder.builder.advance.y; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, glyph_index, FALSE, &metrics ); + decoder.builder.left_bearing.x = metrics.bearing_x; - decoder.builder.left_bearing.y = metrics.bearing_y; decoder.builder.advance.x = metrics.advance; - decoder.builder.advance.y = 0; + decoder.builder.advance.y = metrics.advance_v; } #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -2711,9 +2819,14 @@ 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 ) @@ -2750,8 +2863,8 @@ glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; - /* apply the font matrix -- `xx' has already been normalized */ - if ( !( font_matrix.yy == 0x10000L && + if ( !( font_matrix.xx == 0x10000L && + font_matrix.yy == 0x10000L && font_matrix.xy == 0 && font_matrix.yx == 0 ) ) FT_Outline_Transform( &glyph->root.outline, &font_matrix ); @@ -2804,10 +2917,14 @@ metrics->horiBearingY = cbox.yMax; if ( has_vertical_info ) - metrics->vertBearingX = -metrics->width / 2; - else - ft_synthesize_vertical_metrics( metrics, - metrics->vertAdvance ); + metrics->vertBearingX = metrics->horiBearingX - + metrics->horiAdvance / 2; + else + { + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } } } diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h index 667134e..38937be 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 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 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, */ @@ -28,8 +28,9 @@ FT_BEGIN_HEADER -#define CFF_MAX_OPERANDS 48 -#define CFF_MAX_SUBRS_CALLS 32 +#define CFF_MAX_OPERANDS 48 +#define CFF_MAX_SUBRS_CALLS 32 +#define CFF_MAX_TRANS_ELEMENTS 32 /*************************************************************************/ @@ -53,8 +54,6 @@ FT_BEGIN_HEADER /* */ /* current :: The current glyph outline. */ /* */ - /* last :: The last point position. */ - /* */ /* pos_x :: The horizontal translation (if composite glyph). */ /* */ /* pos_y :: The vertical translation (if composite glyph). */ @@ -88,8 +87,6 @@ FT_BEGIN_HEADER FT_Outline* base; FT_Outline* current; - FT_Vector last; - FT_Pos pos_x; FT_Pos pos_y; @@ -141,8 +138,7 @@ FT_BEGIN_HEADER FT_Bool read_width; FT_Bool width_only; FT_Int num_hints; - FT_Fixed* buildchar; - FT_Int len_buildchar; + FT_Fixed buildchar[CFF_MAX_TRANS_ELEMENTS]; FT_UInt num_locals; FT_UInt num_globals; @@ -158,6 +154,8 @@ FT_BEGIN_HEADER FT_Render_Mode hint_mode; + FT_Bool seac; + } CFF_Decoder; diff --git a/src/cff/cffload.c b/src/cff/cffload.c index 22163fb..64d1395 100644 --- a/src/cff/cffload.c +++ b/src/cff/cffload.c @@ -736,6 +736,7 @@ { FT_Error error = FT_Err_Ok; FT_UInt i; + FT_Long j; FT_UShort max_cid = 0; @@ -750,8 +751,11 @@ if ( FT_NEW_ARRAY( charset->cids, max_cid ) ) goto Exit; - for ( i = 0; i < num_glyphs; i++ ) - charset->cids[charset->sids[i]] = (FT_UShort)i; + /* When multiple GIDs map to the same CID, we choose the lowest */ + /* GID. This is not described in any spec, but it matches the */ + /* behaviour of recent Acroread versions. */ + for ( j = num_glyphs - 1; j >= 0 ; j-- ) + charset->cids[charset->sids[j]] = (FT_UShort)j; charset->max_cid = max_cid; charset->num_glyphs = num_glyphs; @@ -842,7 +846,20 @@ goto Exit; for ( j = 1; j < num_glyphs; j++ ) - charset->sids[j] = FT_GET_USHORT(); + { + FT_UShort sid = FT_GET_USHORT(); + + + /* this constant is given in the CFF specification */ + if ( sid < 65000L ) + charset->sids[j] = sid; + else + { + FT_TRACE0(( "cff_charset_load:" + " invalid SID value %d set to zero\n", sid )); + charset->sids[j] = 0; + } + } FT_FRAME_EXIT(); } @@ -875,6 +892,20 @@ goto Exit; } + /* check whether the range contains at least one valid glyph; */ + /* the constant is given in the CFF specification */ + if ( glyph_sid >= 65000L ) { + FT_ERROR(( "cff_charset_load: invalid SID range\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* try to rescue some of the SIDs if `nleft' is too large */ + if ( nleft > 65000L - 1L || glyph_sid >= 65000L - nleft ) { + FT_ERROR(( "cff_charset_load: invalid SID range trimmed\n" )); + nleft = ( FT_UInt )( 65000L - 1L - glyph_sid ); + } + /* Fill in the range of sids -- `nleft + 1' glyphs. */ for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ ) charset->sids[j] = glyph_sid; @@ -883,7 +914,7 @@ break; default: - FT_ERROR(( "cff_charset_load: invalid table format!\n" )); + FT_ERROR(( "cff_charset_load: invalid table format\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -906,7 +937,7 @@ if ( num_glyphs > 229 ) { FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe ISO-Latin)!\n" )); + "predefined charset (Adobe ISO-Latin)\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -924,7 +955,7 @@ if ( num_glyphs > 166 ) { FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe Expert)!\n" )); + "predefined charset (Adobe Expert)\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -942,7 +973,7 @@ if ( num_glyphs > 87 ) { FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe Expert Subset)!\n" )); + "predefined charset (Adobe Expert Subset)\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -1127,7 +1158,7 @@ break; default: - FT_ERROR(( "cff_encoding_load: invalid table format!\n" )); + FT_ERROR(( "cff_encoding_load: invalid table format\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -1222,7 +1253,7 @@ break; default: - FT_ERROR(( "cff_encoding_load: invalid table format!\n" )); + FT_ERROR(( "cff_encoding_load: invalid table format\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -1240,7 +1271,8 @@ CFF_Index idx, FT_UInt font_index, FT_Stream stream, - FT_ULong base_offset ) + FT_ULong base_offset, + FT_Library library ) { FT_Error error; CFF_ParserRec parser; @@ -1250,7 +1282,7 @@ CFF_Private priv = &font->private_dict; - cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict ); + cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library ); /* set defaults */ FT_MEM_ZERO( top, sizeof ( *top ) ); @@ -1301,7 +1333,7 @@ priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); - cff_parser_init( &parser, CFF_CODE_PRIVATE, priv ); + cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library ); if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || FT_FRAME_ENTER( font->font_dict.private_size ) ) @@ -1354,7 +1386,8 @@ FT_LOCAL_DEF( FT_Error ) - cff_font_load( FT_Stream stream, + cff_font_load( FT_Library library, + FT_Stream stream, FT_Int face_index, CFF_Font font, FT_Bool pure_cff ) @@ -1394,7 +1427,7 @@ font->header_size < 4 || font->absolute_offsize > 4 ) { - FT_TRACE2(( "[not a CFF font header!]\n" )); + FT_TRACE2(( "[not a CFF font header]\n" )); error = CFF_Err_Unknown_File_Format; goto Exit; } @@ -1432,7 +1465,8 @@ &font->font_dict_index, face_index, stream, - base_offset ); + base_offset, + library ); if ( error ) goto Exit; @@ -1462,7 +1496,7 @@ if ( fd_index.count > CFF_MAX_CID_FONTS ) { - FT_ERROR(( "cff_font_load: FD array too large in CID font\n" )); + FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); goto Fail_CID; } @@ -1480,7 +1514,7 @@ { sub = font->subfonts[idx]; error = cff_subfont_load( sub, &fd_index, idx, - stream, base_offset ); + stream, base_offset, library ); if ( error ) goto Fail_CID; } @@ -1503,7 +1537,7 @@ /* read the charstrings index now */ if ( dict->charstrings_offset == 0 ) { - FT_ERROR(( "cff_font_load: no charstrings offset!\n" )); + FT_ERROR(( "cff_font_load: no charstrings offset\n" )); error = CFF_Err_Unknown_File_Format; goto Exit; } diff --git a/src/cff/cffload.h b/src/cff/cffload.h index 02498bd..2b313ac 100644 --- a/src/cff/cffload.h +++ b/src/cff/cffload.h @@ -58,7 +58,8 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - cff_font_load( FT_Stream stream, + cff_font_load( FT_Library library, + FT_Stream stream, FT_Int face_index, CFF_Font font, FT_Bool pure_cff ); diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c index 3525ea3..bd56c4b 100644 --- a/src/cff/cffobjs.c +++ b/src/cff/cffobjs.c @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 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, */ @@ -30,6 +30,7 @@ #include "cffload.h" #include "cffcmap.h" #include "cfferrs.h" +#include "cffpic.h" /*************************************************************************/ @@ -223,8 +224,8 @@ CFF_Font font = (CFF_Font)face->extra.data; CFF_Internal internal = (CFF_Internal)size->internal; - FT_Int top_upm = font->top_font.font_dict.units_per_em; - FT_UInt i; + FT_ULong top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; funcs->set_scale( internal->topfont, @@ -234,7 +235,7 @@ for ( i = font->num_subfonts; i > 0; i-- ) { CFF_SubFont sub = font->subfonts[i - 1]; - FT_Int sub_upm = sub->font_dict.units_per_em; + FT_ULong sub_upm = sub->font_dict.units_per_em; FT_Pos x_scale, y_scale; @@ -295,8 +296,8 @@ CFF_Font font = (CFF_Font)cffface->extra.data; CFF_Internal internal = (CFF_Internal)size->internal; - FT_Int top_upm = font->top_font.font_dict.units_per_em; - FT_UInt i; + FT_ULong top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; funcs->set_scale( internal->topfont, @@ -306,7 +307,7 @@ for ( i = font->num_subfonts; i > 0; i-- ) { CFF_SubFont sub = font->subfonts[i - 1]; - FT_Int sub_upm = sub->font_dict.units_per_em; + FT_ULong sub_upm = sub->font_dict.units_per_em; FT_Pos x_scale, y_scale; @@ -408,6 +409,7 @@ PSHinter_Service pshinter; FT_Bool pure_cff = 1; FT_Bool sfnt_format = 0; + FT_Library library = cffface->driver->root.library; #if 0 @@ -419,14 +421,14 @@ goto Bad_Format; #else sfnt = (SFNT_Service)FT_Get_Module_Interface( - cffface->driver->root.library, "sfnt" ); + library, "sfnt" ); if ( !sfnt ) goto Bad_Format; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); pshinter = (PSHinter_Service)FT_Get_Module_Interface( - cffface->driver->root.library, "pshinter" ); + library, "pshinter" ); #endif /* create input stream from resource */ @@ -507,7 +509,7 @@ goto Exit; face->extra.data = cff; - error = cff_font_load( stream, face_index, cff, pure_cff ); + error = cff_font_load( library, stream, face_index, cff, pure_cff ); if ( error ) goto Exit; @@ -528,10 +530,10 @@ /* which aren't CID-keyed */ if ( dict->cid_registry == 0xFFFFU && !psnames ) { - FT_ERROR(( "cff_face_init:" )); - FT_ERROR(( " cannot open CFF & CEF fonts\n" )); - FT_ERROR(( " " )); - FT_ERROR(( " without the `PSNames' module\n" )); + FT_ERROR(( "cff_face_init:" + " cannot open CFF & CEF fonts\n" + " " + " without the `PSNames' module\n" )); goto Bad_Format; } @@ -582,7 +584,7 @@ if ( sub->units_per_em ) { - FT_Int scaling; + FT_Long scaling; if ( top->units_per_em > 1 && sub->units_per_em > 1 ) @@ -655,10 +657,11 @@ cffface->num_glyphs = cff->charstrings_index.count; /* set global bbox, as well as EM size */ - cffface->bbox.xMin = dict->font_bbox.xMin >> 16; - cffface->bbox.yMin = dict->font_bbox.yMin >> 16; - cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16; - cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16; + cffface->bbox.xMin = dict->font_bbox.xMin >> 16; + cffface->bbox.yMin = dict->font_bbox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16; + cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16; cffface->units_per_EM = (FT_UShort)( dict->units_per_em ); @@ -764,22 +767,22 @@ /* */ /* Compute face flags. */ /* */ - flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ - FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ - FT_FACE_FLAG_HINTER; /* has native hinter */ + flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE | /* scalable outlines */ + FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ + FT_FACE_FLAG_HINTER ); /* has native hinter */ if ( sfnt_format ) - flags |= FT_FACE_FLAG_SFNT; + flags |= (FT_UInt32)FT_FACE_FLAG_SFNT; /* fixed width font? */ if ( dict->is_fixed_pitch ) - flags |= FT_FACE_FLAG_FIXED_WIDTH; + flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH; /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ #if 0 /* kerning available? */ if ( face->kern_pairs ) - flags |= FT_FACE_FLAG_KERNING; + flags |= (FT_UInt32)FT_FACE_FLAG_KERNING; #endif cffface->face_flags = flags; @@ -868,7 +871,7 @@ nn = (FT_UInt)cffface->num_charmaps; - FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL ); + FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, &cmaprec, NULL ); /* if no Unicode charmap was previously selected, select this one */ if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) @@ -887,19 +890,19 @@ { cmaprec.encoding_id = TT_ADOBE_ID_STANDARD; cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; - clazz = &cff_cmap_encoding_class_rec; + clazz = &FT_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 = &cff_cmap_encoding_class_rec; + clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; } else { cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM; cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; - clazz = &cff_cmap_encoding_class_rec; + clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; } FT_CMap_New( clazz, NULL, &cmaprec, NULL ); diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c index 290595f..01266a1 100644 --- a/src/cff/cffparse.c +++ b/src/cff/cffparse.c @@ -22,6 +22,7 @@ #include FT_INTERNAL_DEBUG_H #include "cfferrs.h" +#include "cffpic.h" /*************************************************************************/ @@ -34,47 +35,20 @@ #define FT_COMPONENT trace_cffparse - enum - { - cff_kind_none = 0, - cff_kind_num, - cff_kind_fixed, - cff_kind_fixed_thousand, - cff_kind_string, - cff_kind_bool, - cff_kind_delta, - cff_kind_callback, - - cff_kind_max /* do not remove */ - }; - - - /* now generate handlers for the most simple fields */ - typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser ); - - typedef struct CFF_Field_Handler_ - { - int kind; - int code; - FT_UInt offset; - FT_Byte size; - CFF_Field_Reader reader; - FT_UInt array_max; - FT_UInt count_offset; - - } CFF_Field_Handler; FT_LOCAL_DEF( void ) cff_parser_init( CFF_Parser parser, FT_UInt code, - void* object ) + void* object, + FT_Library library) { FT_MEM_ZERO( parser, sizeof ( *parser ) ); parser->top = parser->stack; parser->object_code = code; parser->object = object; + parser->library = library; } @@ -156,8 +130,8 @@ static FT_Fixed cff_parse_real( FT_Byte* start, FT_Byte* limit, - FT_Int power_ten, - FT_Int* scaling ) + FT_Long power_ten, + FT_Long* scaling ) { FT_Byte* p = start; FT_UInt nib; @@ -165,7 +139,7 @@ FT_Long result, number, rest, exponent; FT_Int sign = 0, exponent_sign = 0; - FT_Int exponent_add, integer_length, fraction_length; + FT_Long exponent_add, integer_length, fraction_length; if ( scaling ) @@ -181,6 +155,8 @@ integer_length = 0; fraction_length = 0; + FT_UNUSED( rest ); + /* First of all, read the integer part. */ phase = 4; @@ -310,7 +286,7 @@ { if ( exponent > 0 ) { - FT_Int new_fraction_length, shift; + FT_Long new_fraction_length, shift; /* Make `scaling' as small as possible. */ @@ -410,7 +386,7 @@ /* but return `10^scaling' times the number read in */ static FT_Fixed cff_parse_fixed_scaled( FT_Byte** d, - FT_Int scaling ) + FT_Long scaling ) { return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL ) : ( cff_parse_integer( d[0], d[1] ) * @@ -423,7 +399,7 @@ /* the scaling factor (as a power of 10) */ static FT_Fixed cff_parse_fixed_dynamic( FT_Byte** d, - FT_Int* scaling ) + FT_Long* scaling ) { FT_ASSERT( scaling ); @@ -476,7 +452,7 @@ if ( parser->top >= parser->stack + 6 ) { - FT_Int scaling; + FT_Long scaling; error = CFF_Err_Ok; @@ -578,7 +554,12 @@ { dict->cid_registry = (FT_UInt)cff_parse_num ( data++ ); dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ ); - dict->cid_supplement = (FT_ULong)cff_parse_num( data ); + if ( **data == 30 ) + FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" )); + dict->cid_supplement = cff_parse_num( data ); + if ( dict->cid_supplement < 0 ) + FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n", + dict->cid_supplement )); error = CFF_Err_Ok; } @@ -599,6 +580,11 @@ #define CFF_FIELD_DELTA( code, name, max ) \ CFF_FIELD( code, name, cff_kind_delta ) +#define CFFCODE_TOPDICT 0x1000 +#define CFFCODE_PRIVATE 0x2000 + +#ifndef FT_CONFIG_OPTION_PIC + #define CFF_FIELD_CALLBACK( code, name ) \ { \ cff_kind_callback, \ @@ -630,9 +616,6 @@ FT_FIELD_OFFSET( num_ ## name ) \ }, -#define CFFCODE_TOPDICT 0x1000 -#define CFFCODE_PRIVATE 0x2000 - static const CFF_Field_Handler cff_field_handlers[] = { @@ -642,13 +625,99 @@ }; +#else /* FT_CONFIG_OPTION_PIC */ + + void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz) + { + FT_Memory memory = library->memory; + if ( clazz ) + FT_FREE( clazz ); + } + + FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class) + { + CFF_Field_Handler* clazz; + FT_Error error; + FT_Memory memory = library->memory; + int i=0; + +#undef CFF_FIELD +#undef CFF_FIELD_DELTA +#undef CFF_FIELD_CALLBACK +#define CFF_FIELD_CALLBACK( code, name ) i++; +#define CFF_FIELD( code, name, kind ) i++; +#define CFF_FIELD_DELTA( code, name, max ) i++; + +#include "cfftoken.h" + i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/ + + if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) ) + return error; + + i=0; +#undef CFF_FIELD +#undef CFF_FIELD_DELTA +#undef CFF_FIELD_CALLBACK + +#define CFF_FIELD_CALLBACK( code_, name_ ) \ + clazz[i].kind = cff_kind_callback; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = 0; \ + clazz[i].size = 0; \ + clazz[i].reader = cff_parse_ ## name_; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + i++; + +#undef CFF_FIELD +#define CFF_FIELD( code_, name_, kind_ ) \ + clazz[i].kind = kind_; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + i++; \ + +#undef CFF_FIELD_DELTA +#define CFF_FIELD_DELTA( code_, name_, max_ ) \ + clazz[i].kind = cff_kind_delta; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = max_; \ + clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ + i++; + +#include "cfftoken.h" + + clazz[i].kind = 0; + clazz[i].code = 0; + clazz[i].offset = 0; + clazz[i].size = 0; + clazz[i].reader = 0; + clazz[i].array_max = 0; + clazz[i].count_offset = 0; + + *output_class = clazz; + return FT_Err_Ok; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + FT_LOCAL_DEF( FT_Error ) cff_parser_run( CFF_Parser parser, FT_Byte* start, FT_Byte* limit ) { - FT_Byte* p = start; - FT_Error error = CFF_Err_Ok; + FT_Byte* p = start; + FT_Error error = CFF_Err_Ok; + FT_Library library = parser->library; + FT_UNUSED(library); parser->top = parser->stack; @@ -676,8 +745,10 @@ p++; for (;;) { + /* An unterminated floating point number at the */ + /* end of a dictionary is invalid but harmless. */ if ( p >= limit ) - goto Syntax_Error; + goto Exit; v = p[0] >> 4; if ( v == 15 ) break; @@ -718,7 +789,7 @@ } code = code | parser->object_code; - for ( field = cff_field_handlers; field->kind; field++ ) + for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ ) { if ( field->code == (FT_Int)code ) { diff --git a/src/cff/cffparse.h b/src/cff/cffparse.h index 8f3fa58..7e2c00a 100644 --- a/src/cff/cffparse.h +++ b/src/cff/cffparse.h @@ -36,6 +36,7 @@ FT_BEGIN_HEADER typedef struct CFF_ParserRec_ { + FT_Library library; FT_Byte* start; FT_Byte* limit; FT_Byte* cursor; @@ -52,7 +53,8 @@ FT_BEGIN_HEADER FT_LOCAL( void ) cff_parser_init( CFF_Parser parser, FT_UInt code, - void* object ); + void* object, + FT_Library library); FT_LOCAL( FT_Error ) cff_parser_run( CFF_Parser parser, @@ -60,6 +62,37 @@ FT_BEGIN_HEADER FT_Byte* limit ); + enum + { + cff_kind_none = 0, + cff_kind_num, + cff_kind_fixed, + cff_kind_fixed_thousand, + cff_kind_string, + cff_kind_bool, + cff_kind_delta, + cff_kind_callback, + + cff_kind_max /* do not remove */ + }; + + + /* now generate handlers for the most simple fields */ + typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser ); + + typedef struct CFF_Field_Handler_ + { + int kind; + int code; + FT_UInt offset; + FT_Byte size; + CFF_Field_Reader reader; + FT_UInt array_max; + FT_UInt count_offset; + + } CFF_Field_Handler; + + FT_END_HEADER diff --git a/src/cff/cffpic.c b/src/cff/cffpic.c new file mode 100644 index 0000000..568956d --- /dev/null +++ b/src/cff/cffpic.c @@ -0,0 +1,99 @@ +/***************************************************************************/ +/* */ +/* cffpic.c */ +/* */ +/* The FreeType position independent code services for cff module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "cffpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from cffdrivr.c */ + FT_Error FT_Create_Class_cff_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_cff_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_cff_service_ps_info( FT_Library, FT_Service_PsInfoRec*); + void FT_Init_Class_cff_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*); + void FT_Init_Class_cff_service_ps_name( FT_Library, FT_Service_PsFontNameRec*); + void FT_Init_Class_cff_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*); + void FT_Init_Class_cff_service_cid_info( FT_Library, FT_Service_CIDRec*); + + /* forward declaration of PIC init functions from cffparse.c */ + FT_Error FT_Create_Class_cff_field_handlers( FT_Library, CFF_Field_Handler**); + void FT_Destroy_Class_cff_field_handlers( FT_Library, CFF_Field_Handler*); + + /* forward declaration of PIC init functions from cffcmap.c */ + void FT_Init_Class_cff_cmap_encoding_class_rec( FT_Library, FT_CMap_ClassRec*); + void FT_Init_Class_cff_cmap_unicode_class_rec( FT_Library, FT_CMap_ClassRec*); + + void + cff_driver_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->cff ) + { + CffModulePIC* container = (CffModulePIC*)pic_container->cff; + if(container->cff_services) + FT_Destroy_Class_cff_services(library, container->cff_services); + container->cff_services = NULL; + if(container->cff_field_handlers) + FT_Destroy_Class_cff_field_handlers(library, container->cff_field_handlers); + container->cff_field_handlers = NULL; + FT_FREE( container ); + pic_container->cff = NULL; + } + } + + FT_Error + cff_driver_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + CffModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->cff = container; + + /* 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(library, &container->cff_service_glyph_dict); + FT_Init_Class_cff_service_ps_name(library, &container->cff_service_ps_name); + FT_Init_Class_cff_service_get_cmap_info(library, &container->cff_service_get_cmap_info); + FT_Init_Class_cff_service_cid_info(library, &container->cff_service_cid_info); + FT_Init_Class_cff_cmap_encoding_class_rec(library, &container->cff_cmap_encoding_class_rec); + FT_Init_Class_cff_cmap_unicode_class_rec(library, &container->cff_cmap_unicode_class_rec); +Exit: + if(error) + cff_driver_class_pic_free(library); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/src/cff/cffpic.h b/src/cff/cffpic.h new file mode 100644 index 0000000..e29d068 --- /dev/null +++ b/src/cff/cffpic.h @@ -0,0 +1,80 @@ +/***************************************************************************/ +/* */ +/* cffpic.h */ +/* */ +/* The FreeType position independent code services for cff module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __CFFPIC_H__ +#define __CFFPIC_H__ + + +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 + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_SERVICE_GLYPH_DICT_H +#include "cffparse.h" +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_TT_CMAP_H +#include FT_SERVICE_CID_H + + 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; + } 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) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __CFFPIC_H__ */ + + +/* END */ diff --git a/src/cff/cfftypes.h b/src/cff/cfftypes.h index 546ea3b..df92e9a 100644 --- a/src/cff/cfftypes.h +++ b/src/cff/cfftypes.h @@ -130,7 +130,7 @@ FT_BEGIN_HEADER /* these should only be used for the top-level font dictionary */ FT_UInt cid_registry; FT_UInt cid_ordering; - FT_ULong cid_supplement; + FT_Long cid_supplement; FT_Long cid_font_version; FT_Long cid_font_revision; diff --git a/src/psaux/afmparse.c b/src/psaux/afmparse.c index 63a786e..91a17e2 100644 --- a/src/psaux/afmparse.c +++ b/src/psaux/afmparse.c @@ -4,7 +4,7 @@ /* */ /* AFM parser (body). */ /* */ -/* Copyright 2006, 2007, 2008 by */ +/* Copyright 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, */ @@ -18,7 +18,6 @@ #include #include FT_FREETYPE_H #include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_DEBUG_H #include "afmparse.h" #include "psconv.h" @@ -367,11 +366,11 @@ FT_LOCAL_DEF( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_Int n ) + FT_UInt n ) { AFM_Stream stream = parser->stream; char* str; - FT_Int i; + FT_UInt i; if ( n > AFM_MAX_ARGUMENTS ) @@ -379,7 +378,7 @@ for ( i = 0; i < n; i++ ) { - FT_UInt len; + FT_Offset len; AFM_Value val = vals + i; @@ -441,7 +440,7 @@ FT_LOCAL_DEF( char* ) afm_parser_next_key( AFM_Parser parser, FT_Bool line, - FT_UInt* len ) + FT_Offset* len ) { AFM_Stream stream = parser->stream; char* key = 0; /* make stupid compiler happy */ @@ -489,7 +488,7 @@ } if ( len ) - *len = ( key ) ? AFM_STREAM_KEY_LEN( stream, key ) + *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key ) : 0; return key; @@ -498,7 +497,7 @@ static AFM_Token afm_tokenize( const char* key, - FT_UInt len ) + FT_Offset len ) { int n; @@ -586,7 +585,7 @@ AFM_FontInfo fi = parser->FontInfo; AFM_TrackKern tk; char* key; - FT_UInt len; + FT_Offset len; int n = -1; @@ -687,7 +686,7 @@ AFM_FontInfo fi = parser->FontInfo; AFM_KernPair kp; char* key; - FT_UInt len; + FT_Offset len; int n = -1; @@ -775,9 +774,9 @@ static FT_Error afm_parse_kern_data( AFM_Parser parser ) { - FT_Error error; - char* key; - FT_UInt len; + FT_Error error; + char* key; + FT_Offset len; while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) @@ -819,8 +818,8 @@ FT_UInt n, AFM_Token end_section ) { - char* key; - FT_UInt len; + char* key; + FT_Offset len; while ( n-- > 0 ) @@ -851,7 +850,7 @@ AFM_FontInfo fi = parser->FontInfo; FT_Error error = PSaux_Err_Syntax_Error; char* key; - FT_UInt len; + FT_Offset len; FT_Int metrics_sets = 0; diff --git a/src/psaux/afmparse.h b/src/psaux/afmparse.h index c2fce75..de2a530 100644 --- a/src/psaux/afmparse.h +++ b/src/psaux/afmparse.h @@ -71,13 +71,13 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_Int n ); + FT_UInt n ); /* read the next key from the next line or column */ FT_LOCAL( char* ) afm_parser_next_key( AFM_Parser parser, FT_Bool line, - FT_UInt* len ); + FT_Offset* len ); FT_END_HEADER diff --git a/src/psaux/psauxmod.h b/src/psaux/psauxmod.h index 92ac056..35e042d 100644 --- a/src/psaux/psauxmod.h +++ b/src/psaux/psauxmod.h @@ -26,6 +26,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class; diff --git a/src/psaux/psconv.c b/src/psaux/psconv.c index d824b59..1531d8f 100644 --- a/src/psaux/psconv.c +++ b/src/psaux/psconv.c @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (body). */ /* */ -/* Copyright 2006, 2008 by */ +/* Copyright 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,10 +18,8 @@ #include #include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_DEBUG_H #include "psconv.h" -#include "psobjs.h" #include "psauxerr.h" @@ -241,7 +239,7 @@ PS_Conv_StringDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ) + FT_Offset n ) { FT_Byte* p; FT_UInt r = 0; @@ -336,7 +334,7 @@ PS_Conv_ASCIIHexDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ) + FT_Offset n ) { FT_Byte* p; FT_UInt r = 0; @@ -425,7 +423,7 @@ PS_Conv_EexecDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n, + FT_Offset n, FT_UShort* seed ) { FT_Byte* p; diff --git a/src/psaux/psconv.h b/src/psaux/psconv.h index e511241..84854ba 100644 --- a/src/psaux/psconv.h +++ b/src/psaux/psconv.h @@ -46,20 +46,20 @@ FT_BEGIN_HEADER PS_Conv_StringDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ); + FT_Offset n ); #endif FT_LOCAL( FT_UInt ) PS_Conv_ASCIIHexDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ); + FT_Offset n ); FT_LOCAL( FT_UInt ) PS_Conv_EexecDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n, + FT_Offset n, FT_UShort* seed ); diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c index 52e30a4..fe8398a 100644 --- a/src/psaux/psobjs.c +++ b/src/psaux/psobjs.c @@ -19,6 +19,7 @@ #include #include FT_INTERNAL_POSTSCRIPT_AUX_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include "psobjs.h" #include "psconv.h" @@ -564,8 +565,8 @@ cur++; if ( cur >= limit || *cur != '>' ) /* >> */ { - FT_ERROR(( "ps_parser_skip_PS_token: " - "unexpected closing delimiter `>'\n" )); + FT_ERROR(( "ps_parser_skip_PS_token:" + " unexpected closing delimiter `>'\n" )); error = PSaux_Err_Invalid_File_Format; goto Exit; } @@ -590,9 +591,10 @@ Exit: if ( cur == parser->cursor ) { - FT_ERROR(( "ps_parser_skip_PS_token: " - "current token is `%c', which is self-delimiting " - "but invalid at this point\n", + FT_ERROR(( "ps_parser_skip_PS_token:" + " current token is `%c' which is self-delimiting\n" + " " + " but invalid at this point\n", *cur )); error = PSaux_Err_Invalid_File_Format; @@ -1153,8 +1155,10 @@ } else { - FT_ERROR(( "ps_parser_load_field: expected a name or string " - "but found token of type %d instead\n", + FT_ERROR(( "ps_parser_load_field:" + " expected a name or string\n" + " " + " but found token of type %d instead\n", token.type )); error = PSaux_Err_Invalid_File_Format; goto Exit; @@ -1191,8 +1195,8 @@ if ( result < 0 ) { - FT_ERROR(( "ps_parser_load_field: " - "expected four integers in bounding box\n" )); + FT_ERROR(( "ps_parser_load_field:" + " expected four integers in bounding box\n" )); error = PSaux_Err_Invalid_File_Format; goto Exit; } @@ -1309,7 +1313,7 @@ FT_LOCAL_DEF( FT_Error ) ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, - FT_Long max_bytes, + FT_Offset max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ) { @@ -1551,16 +1555,9 @@ FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - if ( builder->shift ) - { - x >>= 16; - y >>= 16; - } - point->x = x; - point->y = y; + point->x = FIXED_TO_INT( x ); + point->y = FIXED_TO_INT( y ); *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); - - builder->last = *point; } outline->n_points++; } @@ -1668,8 +1665,8 @@ if ( outline->n_contours > 0 ) { - /* Don't add contours only consisting of one point, i.e., */ - /* check whether begin point and last point are the same. */ + /* Don't add contours only consisting of one point, i.e., */ + /* check whether the first and the last point is the same. */ if ( first == outline->n_points - 1 ) { outline->n_contours--; diff --git a/src/psaux/psobjs.h b/src/psaux/psobjs.h index c2cbf2c..e380c60 100644 --- a/src/psaux/psobjs.h +++ b/src/psaux/psobjs.h @@ -111,7 +111,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, - FT_Long max_bytes, + FT_Offset max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ); diff --git a/src/psaux/t1cmap.c b/src/psaux/t1cmap.c index 67a23db..f933e4d 100644 --- a/src/psaux/t1cmap.c +++ b/src/psaux/t1cmap.c @@ -95,7 +95,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_std_char_next( T1_CMapStd cmap, FT_UInt32 *pchar_code ) { @@ -179,7 +179,7 @@ cmap->first = encoding->code_first; - cmap->count = (FT_UInt)( encoding->code_last - cmap->first + 1 ); + cmap->count = (FT_UInt)( encoding->code_last - cmap->first ); cmap->indices = encoding->char_index; FT_ASSERT( cmap->indices != NULL ); @@ -213,7 +213,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_custom_char_next( T1_CMapCustom cmap, FT_UInt32 *pchar_code ) { @@ -312,7 +312,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_unicode_char_next( PS_Unicodes unicodes, FT_UInt32 *pchar_code ) { diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c index bda2324..31554ff 100644 --- a/src/psaux/t1decode.c +++ b/src/psaux/t1decode.c @@ -4,7 +4,8 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +18,7 @@ #include +#include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include FT_OUTLINE_H @@ -144,7 +146,8 @@ FT_String* name = (FT_String*)decoder->glyph_names[n]; - if ( name && name[0] == glyph_name[0] && + if ( name && + name[0] == glyph_name[0] && ft_strcmp( name, glyph_name ) == 0 ) return n; } @@ -193,26 +196,52 @@ #endif FT_Vector left_bearing, advance; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + T1_Face face = (T1_Face)decoder->builder.face; +#endif + + + if ( decoder->seac ) + { + FT_ERROR(( "t1operator_seac: invalid nested seac\n" )); + return PSaux_Err_Syntax_Error; + } /* seac weirdness */ adx += decoder->builder.left_bearing.x; /* `glyph_names' is set to 0 for CID fonts which do not */ /* include an encoding. How can we deal with these? */ +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( decoder->glyph_names == 0 && + !face->root.internal->incremental_interface ) +#else if ( decoder->glyph_names == 0 ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " glyph names table not available in this font!\n" )); + FT_ERROR(( "t1operator_seac:" + " glyph names table not available in this font\n" )); return PSaux_Err_Syntax_Error; } - bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); - achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( face->root.internal->incremental_interface ) + { + /* the caller must handle the font encoding also */ + bchar_index = bchar; + achar_index = achar; + } + else +#endif + { + bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); + achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); + } if ( bchar_index < 0 || achar_index < 0 ) { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); + FT_ERROR(( "t1operator_seac:" + " invalid seac character code arguments\n" )); return PSaux_Err_Syntax_Error; } @@ -243,8 +272,8 @@ /* subglyph 1 = accent character */ subg->index = achar_index; subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = (FT_Int)( adx - asb ); - subg->arg2 = (FT_Int)ady; + subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb ); + subg->arg2 = (FT_Int)FIXED_TO_INT( ady ); /* set up remaining glyph fields */ glyph->num_subglyphs = 2; @@ -260,7 +289,10 @@ FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = t1_decoder_parse_glyph( decoder, bchar_index ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -278,7 +310,11 @@ /* Now load `achar' on top of */ /* the base outline */ + + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = t1_decoder_parse_glyph( decoder, achar_index ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -327,9 +363,15 @@ FT_Pos x, y, orig_x, orig_y; FT_Int known_othersubr_result_cnt = 0; FT_Int unknown_othersubr_result_cnt = 0; + FT_Bool large_int; + FT_Fixed seed; T1_Hints_Funcs hinter; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool bol = TRUE; +#endif + /* we don't want to touch the source code -- use macro trick */ #define start_point t1_builder_start_point @@ -339,6 +381,16 @@ #define add_contour t1_builder_add_contour #define close_contour t1_builder_close_contour + + /* compute random seed from stack address of parameter */ + seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ + (FT_PtrDist)(char*)&decoder ^ + (FT_PtrDist)(char*)&charstring_base ) & + FT_ULONG_MAX ) ; + seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; + if ( seed == 0 ) + seed = 0x7384; + /* First of all, initialize the decoder */ decoder->top = decoder->stack; decoder->zone = decoder->zones; @@ -351,14 +403,15 @@ /* a font that reads BuildCharArray without setting */ /* its values first is buggy, but ... */ FT_ASSERT( ( decoder->len_buildchar == 0 ) == - ( decoder->buildchar == NULL ) ); + ( decoder->buildchar == NULL ) ); if ( decoder->len_buildchar > 0 ) ft_memset( &decoder->buildchar[0], 0, sizeof( decoder->buildchar[0] ) * decoder->len_buildchar ); - FT_TRACE4(( "\nStart charstring\n" )); + FT_TRACE4(( "\n" + "Start charstring\n" )); zone->base = charstring_base; limit = zone->limit = charstring_base + charstring_len; @@ -373,18 +426,26 @@ if ( hinter ) hinter->open( hinter->hints ); + large_int = FALSE; + /* now, execute loop */ while ( ip < limit ) { FT_Long* top = decoder->top; T1_Operator op = op_none; - FT_Long value = 0; + FT_Int32 value = 0; FT_ASSERT( known_othersubr_result_cnt == 0 || unknown_othersubr_result_cnt == 0 ); - FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( bol ) + { + FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); + bol = FALSE; + } +#endif /*********************************************************************/ /* */ @@ -455,8 +516,8 @@ case 12: if ( ip > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid escape (12+EOF)\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+EOF)\n" )); goto Syntax_Error; } @@ -491,8 +552,8 @@ break; default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid escape (12+%d)\n", + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+%d)\n", ip[-1] )); goto Syntax_Error; } @@ -501,42 +562,69 @@ case 255: /* four bytes integer */ if ( ip + 4 > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unexpected EOF in integer\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); 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_Long)ip[0] << 24 ) | + ( (FT_Long)ip[1] << 16 ) | + ( (FT_Long)ip[2] << 8 ) | + ip[3] ); ip += 4; + + /* According to the specification, values > 32000 or < -32000 must */ + /* be followed by a `div' operator to make the result be in the */ + /* range [-32000;32000]. We expect that the second argument of */ + /* `div' is not a large number. Additionally, we don't handle */ + /* stuff like ` div div' or */ + /* div div'. This is probably not allowed */ + /* anyway. */ + if ( value > 32000 || value < -32000 ) + { + if ( large_int ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + } + else + large_int = TRUE; + } + else + { + if ( !large_int ) + value <<= 16; + } + break; default: if ( ip[-1] >= 32 ) { if ( ip[-1] < 247 ) - value = (FT_Long)ip[-1] - 139; + value = (FT_Int32)ip[-1] - 139; else { if ( ++ip > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected EOF in integer\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); goto Syntax_Error; } if ( ip[-2] < 251 ) - value = ( ( (FT_Long)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; + value = ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; else - value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); + value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); } + + if ( !large_int ) + value <<= 16; } else { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid byte (%d)\n", ip[-1] )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid byte (%d)\n", ip[-1] )); goto Syntax_Error; } } @@ -558,6 +646,14 @@ } } + if ( large_int && !( op == op_none || op == op_div ) ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + + large_int = FALSE; + } + /*********************************************************************/ /* */ /* Push value on stack, or process operator */ @@ -567,11 +663,16 @@ { if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) { - FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" )); goto Syntax_Error; } - FT_TRACE4(( " %ld", value )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( large_int ) + FT_TRACE4(( " %ld", value )); + else + FT_TRACE4(( " %ld", (FT_Int32)( value >> 16 ) )); +#endif *top++ = value; decoder->top = top; @@ -582,15 +683,18 @@ FT_Int arg_cnt; - FT_TRACE4(( " callothersubr" )); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " callothersubr\n" )); + bol = TRUE; +#endif if ( top - decoder->stack < 2 ) goto Stack_Underflow; top -= 2; - subr_no = (FT_Int)top[1]; - arg_cnt = (FT_Int)top[0]; + subr_no = (FT_Int)( top[1] >> 16 ); + arg_cnt = (FT_Int)( top[0] >> 16 ); /***********************************************************/ /* */ @@ -667,8 +771,8 @@ if ( decoder->flex_state == 0 || decoder->num_flex_vectors != 7 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unexpected flex end\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected flex end\n" )); goto Syntax_Error; } @@ -684,7 +788,6 @@ if ( hinter ) hinter->reset( hinter->hints, builder->current->n_points ); - break; case 12: @@ -707,16 +810,16 @@ if ( !blend ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected multiple masters operator!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected multiple masters operator\n" )); goto Syntax_Error; } num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 ); if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "incorrect number of mm arguments\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " incorrect number of multiple masters arguments\n" )); goto Syntax_Error; } @@ -752,12 +855,6 @@ break; } -#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS - - /* We cannot yet enable these since currently */ - /* our T1 stack stores integers which lack the */ - /* precision to express the values */ - case 19: /* 1 19 callothersubr */ /* => replace elements starting from index cvi( ) */ @@ -770,10 +867,10 @@ if ( arg_cnt != 1 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[0]; + idx = (FT_Int)( top[0] >> 16 ); - if ( idx < 0 || - idx + blend->num_designs > decoder->face->len_buildchar ) + if ( idx < 0 || + idx + blend->num_designs > decoder->len_buildchar ) goto Unexpected_OtherSubr; ft_memcpy( &decoder->buildchar[idx], @@ -811,7 +908,7 @@ if ( arg_cnt != 2 ) goto Unexpected_OtherSubr; - top[0] *= top[1]; /* XXX (over|under)flow */ + top[0] = FT_MulFix( top[0], top[1] ); known_othersubr_result_cnt = 1; break; @@ -822,24 +919,23 @@ if ( arg_cnt != 2 || top[1] == 0 ) goto Unexpected_OtherSubr; - top[0] /= top[1]; /* XXX (over|under)flow */ + top[0] = FT_DivFix( top[0], top[1] ); known_othersubr_result_cnt = 1; break; -#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */ - case 24: - /* 2 24 callothersubr */ - /* => set BuildCharArray[cvi( )] = */ + /* 2 24 callothersubr */ + /* ==> set BuildCharArray[cvi( )] = */ { FT_Int idx; PS_Blend blend = decoder->blend; + if ( arg_cnt != 2 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[1]; + idx = (FT_Int)( top[1] >> 16 ); if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; @@ -849,17 +945,18 @@ break; case 25: - /* 1 25 callothersubr pop */ - /* => push BuildCharArray[cvi( idx )] */ - /* onto T1 stack */ + /* 1 25 callothersubr pop */ + /* ==> push BuildCharArray[cvi( idx )] */ + /* onto T1 stack */ { FT_Int idx; PS_Blend blend = decoder->blend; + if ( arg_cnt != 1 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[0]; + idx = (FT_Int)( top[0] >> 16 ); if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; @@ -875,13 +972,13 @@ /* mark ==> set BuildCharArray[cvi( )] = , */ /* leave mark on T1 stack */ /* ==> set BuildCharArray[cvi( )] = */ - XXX who has left his mark on the (PostScript) stack ?; + XXX which routine has left its mark on the (PostScript) stack?; break; #endif case 27: /* 4 27 callothersubr pop */ - /* ==> push onto T1 stack if <= , */ + /* ==> push onto T1 stack if <= , */ /* otherwise push */ if ( arg_cnt != 4 ) goto Unexpected_OtherSubr; @@ -892,28 +989,40 @@ known_othersubr_result_cnt = 1; break; -#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS case 28: /* 0 28 callothersubr pop */ /* => push random value from interval [0, 1) onto stack */ if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; - top[0] = FT_rand(); + { + FT_Fixed Rand; + + + Rand = seed; + if ( Rand >= 0x8000L ) + Rand++; + + top[0] = Rand; + + seed = FT_MulFix( seed, 0x10000L - seed ); + if ( seed == 0 ) + seed += 0x2873; + } + known_othersubr_result_cnt = 1; break; -#endif default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unknown othersubr [%d %d], wish me luck!\n", + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unknown othersubr [%d %d], wish me luck\n", arg_cnt, subr_no )); unknown_othersubr_result_cnt = arg_cnt; break; Unexpected_OtherSubr: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid othersubr [%d %d]!\n", arg_cnt, subr_no )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid othersubr [%d %d]\n", arg_cnt, subr_no )); goto Syntax_Error; } @@ -950,9 +1059,9 @@ default: if ( top - decoder->stack != num_args ) - FT_TRACE0(( "t1_decoder_parse_charstrings: " - "too much operands on the stack " - "(seen %d, expected %d)\n", + FT_TRACE0(( "t1_decoder_parse_charstrings:" + " too much operands on the stack" + " (seen %d, expected %d)\n", top - decoder->stack, num_args )); break; } @@ -964,28 +1073,26 @@ switch ( op ) { case op_endchar: - FT_TRACE4(( " endchar" )); + FT_TRACE4(( " endchar\n" )); close_contour( builder ); /* close hints recording session */ if ( hinter ) { - if (hinter->close( hinter->hints, builder->current->n_points )) + if ( hinter->close( hinter->hints, builder->current->n_points ) ) goto Syntax_Error; /* apply hints to the loaded glyph outline now */ hinter->apply( hinter->hints, builder->current, - (PSH_Globals) builder->hints_globals, + (PSH_Globals)builder->hints_globals, decoder->hint_mode ); } /* add current outline to the glyph slot */ FT_GlyphLoader_Add( builder->loader ); - FT_TRACE4(( "\n" )); - /* the compiler should optimize away this empty loop but ... */ #ifdef FT_DEBUG_LEVEL_TRACE @@ -1019,8 +1126,8 @@ builder->advance.x = top[1]; builder->advance.y = 0; - orig_x = builder->last.x = x = builder->pos_x + top[0]; - orig_y = builder->last.y = y = builder->pos_y; + orig_x = x = builder->pos_x + top[0]; + orig_y = y = builder->pos_y; FT_UNUSED( orig_y ); @@ -1033,9 +1140,12 @@ break; case op_seac: - /* return immediately after the processing */ - return t1operator_seac( decoder, top[0], top[1], top[2], - (FT_Int)top[3], (FT_Int)top[4] ); + return t1operator_seac( decoder, + top[0], + top[1], + top[2], + (FT_Int)( top[3] >> 16 ), + (FT_Int)( top[4] >> 16 ) ); case op_sbw: FT_TRACE4(( " sbw" )); @@ -1047,8 +1157,8 @@ builder->advance.x = top[2]; builder->advance.y = top[3]; - builder->last.x = x = builder->pos_x + top[0]; - builder->last.y = y = builder->pos_y + top[1]; + x = builder->pos_x + top[0]; + y = builder->pos_y + top[1]; /* the `metrics_only' indicates that we only want to compute */ /* the glyph's metrics (lsb + advance width), not load the */ @@ -1134,7 +1244,7 @@ break; case op_rrcurveto: - FT_TRACE4(( " rcurveto" )); + FT_TRACE4(( " rrcurveto" )); if ( start_point( builder, x, y ) || check_points( builder, 3 ) ) @@ -1193,16 +1303,13 @@ case op_div: FT_TRACE4(( " div" )); - if ( top[1] ) - { - *top = top[0] / top[1]; - ++top; - } - else - { - FT_ERROR(( "t1_decoder_parse_charstrings: division by 0\n" )); - goto Syntax_Error; - } + /* if `large_int' is set, we divide unscaled numbers; */ + /* otherwise, we divide numbers in 16.16 format -- */ + /* in both cases, it is the same operation */ + *top = FT_DivFix( top[0], top[1] ); + ++top; + + large_int = FALSE; break; case op_callsubr: @@ -1212,18 +1319,18 @@ FT_TRACE4(( " callsubr" )); - idx = (FT_Int)top[0]; + idx = (FT_Int)( top[0] >> 16 ); if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid subrs index\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid subrs index\n" )); goto Syntax_Error; } if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "too many nested subrs\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " too many nested subrs\n" )); goto Syntax_Error; } @@ -1250,8 +1357,8 @@ if ( !zone->base ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invoking empty subrs!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invoking empty subrs\n" )); goto Syntax_Error; } @@ -1273,8 +1380,8 @@ if ( unknown_othersubr_result_cnt == 0 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "no more operands for othersubr!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no more operands for othersubr\n" )); goto Syntax_Error; } @@ -1287,7 +1394,8 @@ if ( zone <= decoder->zones ) { - FT_ERROR(( "t1_decoder_parse_charstrings: unexpected return\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected return\n" )); goto Syntax_Error; } @@ -1311,7 +1419,6 @@ /* top[0] += builder->left_bearing.y; */ hinter->stem( hinter->hints, 1, top ); } - break; case op_hstem3: @@ -1320,19 +1427,17 @@ /* record horizontal counter-controlled hints */ if ( hinter ) hinter->stem3( hinter->hints, 1, top ); - break; case op_vstem: FT_TRACE4(( " vstem" )); - /* record vertical hint */ + /* record vertical hint */ if ( hinter ) { top[0] += orig_x; hinter->stem( hinter->hints, 0, top ); } - break; case op_vstem3: @@ -1354,20 +1459,28 @@ case op_setcurrentpoint: FT_TRACE4(( " setcurrentpoint" )); - /* From the T1 specs, section 6.4: */ + /* From the T1 specification, section 6.4: */ /* */ /* The setcurrentpoint command is used only in */ /* conjunction with results from OtherSubrs procedures. */ - /* known_othersubr_result_cnt != 0 is already handled above */ + /* known_othersubr_result_cnt != 0 is already handled */ + /* above. */ + + /* Note, however, that both Ghostscript and Adobe */ + /* Distiller handle this situation by silently ignoring */ + /* the inappropriate `setcurrentpoint' instruction. So */ + /* we do the same. */ +#if 0 + if ( decoder->flex_state != 1 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected `setcurrentpoint'\n" )); - + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected `setcurrentpoint'\n" )); goto Syntax_Error; } else +#endif decoder->flex_state = 0; break; @@ -1377,8 +1490,8 @@ break; default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unhandled opcode %d\n", op )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unhandled opcode %d\n", op )); goto Syntax_Error; } @@ -1389,6 +1502,11 @@ decoder->top = top; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( "\n" )); + bol = TRUE; +#endif + } /* general operator processing */ } /* while ip < limit */ @@ -1437,8 +1555,8 @@ FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) { - FT_ERROR(( "t1_decoder_init: " )); - FT_ERROR(( "the `psnames' module is not available\n" )); + FT_ERROR(( "t1_decoder_init:" + " the `psnames' module is not available\n" )); return PSaux_Err_Unimplemented_Feature; } diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c index f9ab3da..417dcee 100644 --- a/src/pshinter/pshalgo.c +++ b/src/pshinter/pshalgo.c @@ -103,7 +103,7 @@ if ( idx >= table->max_hints ) { - FT_ERROR(( "psh_hint_table_record: invalid hint index %d\n", idx )); + FT_TRACE0(( "psh_hint_table_record: invalid hint index %d\n", idx )); return; } @@ -137,7 +137,7 @@ if ( table->num_hints < table->max_hints ) table->sort_global[table->num_hints++] = hint; else - FT_ERROR(( "psh_hint_table_record: too many sorted hints! BUG!\n" )); + FT_TRACE0(( "psh_hint_table_record: too many sorted hints! BUG!\n" )); } @@ -230,7 +230,7 @@ FT_UInt idx; - FT_ERROR(( "psh_hint_table_init: missing/incorrect hint masks!\n" )); + FT_TRACE0(( "psh_hint_table_init: missing/incorrect hint masks\n" )); count = table->max_hints; for ( idx = 0; idx < count; idx++ ) @@ -282,8 +282,8 @@ { hint2 = sort[0]; if ( psh_hint_overlap( hint, hint2 ) ) - FT_ERROR(( "psh_hint_table_activate_mask:" - " found overlapping hints\n" )) + FT_TRACE0(( "psh_hint_table_activate_mask:" + " found overlapping hints\n" )) } #else count2 = 0; @@ -295,8 +295,8 @@ if ( count < table->max_hints ) table->sort[count++] = hint; else - FT_ERROR(( "psh_hint_tableactivate_mask:" - " too many active hints\n" )); + FT_TRACE0(( "psh_hint_tableactivate_mask:" + " too many active hints\n" )); } } } diff --git a/src/pshinter/pshinter.c b/src/pshinter/pshinter.c index 8e3f193..b35a2a9 100644 --- a/src/pshinter/pshinter.c +++ b/src/pshinter/pshinter.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include +#include "pshpic.c" #include "pshrec.c" #include "pshglob.c" #include "pshalgo.c" diff --git a/src/pshinter/pshmod.c b/src/pshinter/pshmod.c index 4eb3d91..91da5d7 100644 --- a/src/pshinter/pshmod.c +++ b/src/pshinter/pshmod.c @@ -20,6 +20,7 @@ #include FT_INTERNAL_OBJECTS_H #include "pshrec.h" #include "pshalgo.h" +#include "pshpic.h" /* the Postscript Hinter module structure */ @@ -92,30 +93,26 @@ } - static - const PSHinter_Interface pshinter_interface = - { + FT_DEFINE_PSHINTER_INTERFACE(pshinter_interface, pshinter_get_globals_funcs, pshinter_get_t1_funcs, pshinter_get_t2_funcs - }; + ) - FT_CALLBACK_TABLE_DEF - const FT_Module_Class pshinter_module_class = - { + FT_DEFINE_MODULE(pshinter_module_class, + 0, sizeof ( PS_Hinter_ModuleRec ), "pshinter", 0x10000L, 0x20000L, - &pshinter_interface, /* module-specific interface */ + &FTPSHINTER_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 */ - }; - + ) /* END */ diff --git a/src/pshinter/pshmod.h b/src/pshinter/pshmod.h index 1a91025..0ae7e96 100644 --- a/src/pshinter/pshmod.h +++ b/src/pshinter/pshmod.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Module_Class ) pshinter_module_class; + FT_DECLARE_MODULE( pshinter_module_class ) FT_END_HEADER diff --git a/src/pshinter/pshpic.c b/src/pshinter/pshpic.c new file mode 100644 index 0000000..51a0879 --- /dev/null +++ b/src/pshinter/pshpic.c @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* pshpic.c */ +/* */ +/* The FreeType position independent code services for pshinter module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pshpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from pshmod.c */ + void FT_Init_Class_pshinter_interface( FT_Library, PSHinter_Interface*); + + void + pshinter_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->pshinter ) + { + FT_FREE( pic_container->pshinter ); + pic_container->pshinter = NULL; + } + } + + FT_Error + pshinter_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + PSHinterPIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->pshinter = container; + + /* add call to initialization function when you add new scripts */ + FT_Init_Class_pshinter_interface(library, &container->pshinter_interface); + +/*Exit:*/ + if(error) + pshinter_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + +/* END */ diff --git a/src/pshinter/pshpic.h b/src/pshinter/pshpic.h new file mode 100644 index 0000000..3555d8e --- /dev/null +++ b/src/pshinter/pshpic.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* pshpic.h */ +/* */ +/* The FreeType position independent code services for pshinter module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __PSHPIC_H__ +#define __PSHPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC + +#define FTPSHINTER_INTERFACE_GET pshinter_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + typedef struct PSHinterPIC_ + { + PSHinter_Interface pshinter_interface; + } PSHinterPIC; + +#define GET_PIC(lib) ((PSHinterPIC*)((lib)->pic_container.autofit)) +#define FTPSHINTER_INTERFACE_GET (GET_PIC(library)->pshinter_interface) + + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __PSHPIC_H__ */ + + +/* END */ diff --git a/src/pshinter/pshrec.c b/src/pshinter/pshrec.c index 2a885ef..0910cc5 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 by */ +/* Copyright 2001, 2002, 2003, 2004, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,8 @@ #include FT_FREETYPE_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H + #include "pshrec.h" #include "pshalgo.h" @@ -62,7 +64,7 @@ { FT_UInt old_max = table->max_hints; FT_UInt new_max = count; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( new_max > old_max ) @@ -81,7 +83,7 @@ FT_Memory memory, PS_Hint *ahint ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt count; PS_Hint hint = 0; @@ -137,7 +139,7 @@ { FT_UInt old_max = ( mask->max_bits + 7 ) >> 3; FT_UInt new_max = ( count + 7 ) >> 3; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( new_max > old_max ) @@ -184,7 +186,7 @@ FT_Int idx, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_Byte* p; @@ -234,7 +236,7 @@ { FT_UInt old_max = table->max_masks; FT_UInt new_max = count; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( new_max > old_max ) @@ -254,7 +256,7 @@ PS_Mask *amask ) { FT_UInt count; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; PS_Mask mask = 0; @@ -285,7 +287,7 @@ FT_Memory memory, PS_Mask *amask ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt count; PS_Mask mask; @@ -314,7 +316,7 @@ FT_UInt bit_count, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; PS_Mask mask; @@ -407,7 +409,7 @@ FT_Memory memory ) { FT_UInt temp; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; /* swap index1 and index2 so that index1 < index2 */ @@ -481,8 +483,8 @@ table->num_masks--; } else - FT_ERROR(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n", - index1, index2 )); + FT_TRACE0(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n", + index1, index2 )); Exit: return error; @@ -497,7 +499,7 @@ FT_Memory memory ) { FT_Int index1, index2; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; for ( index1 = table->num_masks - 1; index1 > 0; index1-- ) @@ -558,8 +560,8 @@ FT_UInt idx, FT_Memory memory ) { - PS_Mask mask; - FT_Error error = 0; + PS_Mask mask; + FT_Error error = PSH_Err_Ok; /* get last hint mask */ @@ -619,7 +621,7 @@ FT_UInt end_point, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; /* reset current mask, if any */ @@ -644,7 +646,7 @@ FT_Memory memory, FT_Int *aindex ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt flags = 0; @@ -715,7 +717,7 @@ FT_Int hint3, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt count = dim->counters.num_masks; PS_Mask counter = dim->counters.masks; @@ -789,7 +791,7 @@ ps_dimension_done( &hints->dimension[0], memory ); ps_dimension_done( &hints->dimension[1], memory ); - hints->error = 0; + hints->error = PSH_Err_Ok; hints->memory = 0; } @@ -800,7 +802,7 @@ { FT_MEM_ZERO( hints, sizeof ( *hints ) ); hints->memory = memory; - return 0; + return PSH_Err_Ok; } @@ -813,7 +815,7 @@ { case PS_HINT_TYPE_1: case PS_HINT_TYPE_2: - hints->error = 0; + hints->error = PSH_Err_Ok; hints->hint_type = hint_type; ps_dimension_init( &hints->dimension[0] ); @@ -824,7 +826,7 @@ hints->error = PSH_Err_Invalid_Argument; hints->hint_type = hint_type; - FT_ERROR(( "ps_hints_open: invalid charstring type!\n" )); + FT_TRACE0(( "ps_hints_open: invalid charstring type\n" )); break; } } @@ -842,8 +844,8 @@ /* limit "dimension" to 0..1 */ if ( dimension < 0 || dimension > 1 ) { - FT_ERROR(( "ps_hints_stem: invalid dimension (%d) used\n", - dimension )); + FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n", + dimension )); dimension = ( dimension != 0 ); } @@ -878,8 +880,8 @@ } default: - FT_ERROR(( "ps_hints_stem: called with invalid hint type (%d)\n", - hints->hint_type )); + FT_TRACE0(( "ps_hints_stem: called with invalid hint type (%d)\n", + hints->hint_type )); break; } } @@ -888,11 +890,11 @@ /* add one Type1 counter stem to the current hints table */ static void - ps_hints_t1stem3( PS_Hints hints, - FT_Int dimension, - FT_Long* stems ) + ps_hints_t1stem3( PS_Hints hints, + FT_Int dimension, + FT_Fixed* stems ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( !hints->error ) @@ -906,8 +908,8 @@ /* limit "dimension" to 0..1 */ if ( dimension < 0 || dimension > 1 ) { - FT_ERROR(( "ps_hints_t1stem3: invalid dimension (%d) used\n", - dimension )); + FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n", + dimension )); dimension = ( dimension != 0 ); } @@ -919,9 +921,10 @@ /* add the three stems to our hints/masks table */ for ( count = 0; count < 3; count++, stems += 2 ) { - error = ps_dimension_add_t1stem( - dim, (FT_Int)stems[0], (FT_Int)stems[1], - memory, &idx[count] ); + error = ps_dimension_add_t1stem( dim, + (FT_Int)FIXED_TO_INT( stems[0] ), + (FT_Int)FIXED_TO_INT( stems[1] ), + memory, &idx[count] ); if ( error ) goto Fail; } @@ -934,7 +937,7 @@ } else { - FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type!\n" )); + FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type\n" )); error = PSH_Err_Invalid_Argument; goto Fail; } @@ -953,7 +956,7 @@ ps_hints_t1reset( PS_Hints hints, FT_UInt end_point ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( !hints->error ) @@ -1008,8 +1011,8 @@ /* check bit count; must be equal to current total hint count */ if ( bit_count != count1 + count2 ) { - FT_ERROR(( "ps_hints_t2mask: " - "called with invalid bitcount %d (instead of %d)\n", + FT_TRACE0(( "ps_hints_t2mask:" + " called with invalid bitcount %d (instead of %d)\n", bit_count, count1 + count2 )); /* simply ignore the operator */ @@ -1053,8 +1056,8 @@ /* check bit count, must be equal to current total hint count */ if ( bit_count != count1 + count2 ) { - FT_ERROR(( "ps_hints_t2counter: " - "called with invalid bitcount %d (instead of %d)\n", + FT_TRACE0(( "ps_hints_t2counter:" + " called with invalid bitcount %d (instead of %d)\n", bit_count, count1 + count2 )); /* simply ignore the operator */ @@ -1124,11 +1127,17 @@ } static void - t1_hints_stem( T1_Hints hints, - FT_Int dimension, - FT_Long* coords ) + t1_hints_stem( T1_Hints hints, + FT_Int dimension, + FT_Fixed* coords ) { - ps_hints_stem( (PS_Hints)hints, dimension, 1, coords ); + FT_Pos stems[2]; + + + stems[0] = FIXED_TO_INT( coords[0] ); + stems[1] = FIXED_TO_INT( coords[1] ); + + ps_hints_stem( (PS_Hints)hints, dimension, 1, stems ); } @@ -1183,7 +1192,7 @@ for ( n = 0; n < count * 2; n++ ) { y += coords[n]; - stems[n] = ( y + 0x8000L ) >> 16; + stems[n] = FIXED_TO_INT( y ); } /* compute lengths */ diff --git a/src/psnames/psmodule.c b/src/psnames/psmodule.c index 41942a9..00b363f 100644 --- a/src/psnames/psmodule.c +++ b/src/psnames/psmodule.c @@ -24,6 +24,7 @@ #include "pstables.h" #include "psnamerr.h" +#include "pspic.h" #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -33,7 +34,7 @@ #define VARIANT_BIT 0x80000000UL -#define BASE_GLYPH( code ) ( (code) & ~VARIANT_BIT ) +#define BASE_GLYPH( code ) ( (FT_UInt32)( (code) & ~VARIANT_BIT ) ) /* Return the Unicode value corresponding to a given glyph. Note that */ @@ -57,7 +58,7 @@ /* `uniXXXXYYYYZZZZ'... */ FT_Int count; - FT_ULong value = 0; + FT_UInt32 value = 0; const char* p = glyph_name + 3; @@ -92,7 +93,7 @@ if ( *p == '\0' ) return value; if ( *p == '.' ) - return value | VARIANT_BIT; + return (FT_UInt32)( value | VARIANT_BIT ); } } @@ -101,7 +102,7 @@ if ( glyph_name[0] == 'u' ) { FT_Int count; - FT_ULong value = 0; + FT_UInt32 value = 0; const char* p = glyph_name + 1; @@ -132,7 +133,7 @@ if ( *p == '\0' ) return value; if ( *p == '.' ) - return value | VARIANT_BIT; + return (FT_UInt32)( value | VARIANT_BIT ); } } @@ -154,9 +155,10 @@ /* now look up the glyph in the Adobe Glyph List */ if ( !dot ) - return ft_get_adobe_glyph_index( glyph_name, p ); + return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p ); else - return ft_get_adobe_glyph_index( glyph_name, dot ) | VARIANT_BIT; + return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) | + VARIANT_BIT ); } } @@ -435,7 +437,7 @@ } - static FT_ULong + static FT_UInt32 ps_unicodes_char_next( PS_Unicodes table, FT_UInt32 *unicode ) { @@ -516,38 +518,43 @@ } - static - const FT_Service_PsCMapsRec pscmaps_interface = - { #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - + 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, (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, + (PS_Macintosh_NameFunc) ps_get_macintosh_name, + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + + t1_standard_encoding, + t1_expert_encoding + ) + #else + FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, 0, 0, 0, 0, -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - (PS_Macintosh_NameFunc) ps_get_macintosh_name, (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, t1_standard_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 + ) - static const FT_ServiceDescRec pscmaps_services[] = - { - { FT_SERVICE_ID_POSTSCRIPT_CMAPS, &pscmaps_interface }, - { NULL, NULL } - }; static FT_Pointer @@ -556,16 +563,20 @@ { FT_UNUSED( module ); - return ft_service_list_lookup( pscmaps_services, service_id ); + return ft_service_list_lookup( FT_PSCMAPS_SERVICES_GET, service_id ); } #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ +#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES +#define PUT_PS_NAMES_SERVICE(a) 0 +#else +#define PUT_PS_NAMES_SERVICE(a) a +#endif - FT_CALLBACK_TABLE_DEF - const FT_Module_Class psnames_module_class = - { + FT_DEFINE_MODULE(psnames_module_class, + 0, /* this is not a font driver, nor a renderer */ sizeof ( FT_ModuleRec ), @@ -573,18 +584,12 @@ 0x10000L, /* driver version */ 0x20000L, /* driver requires FreeType 2 or above */ -#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - 0, - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 -#else - (void*)&pscmaps_interface, /* module specific interface */ + PUT_PS_NAMES_SERVICE((void*)&FT_PSCMAPS_INTERFACE_GET), /* module specific interface */ (FT_Module_Constructor)0, (FT_Module_Destructor) 0, - (FT_Module_Requester) psnames_get_service -#endif - }; + (FT_Module_Requester) PUT_PS_NAMES_SERVICE(psnames_get_service) + ) + /* END */ diff --git a/src/psnames/psmodule.h b/src/psnames/psmodule.h index 232fdfb..28fa148 100644 --- a/src/psnames/psmodule.h +++ b/src/psnames/psmodule.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Module_Class ) psnames_module_class; + FT_DECLARE_MODULE( psnames_module_class ) FT_END_HEADER diff --git a/src/psnames/psnames.c b/src/psnames/psnames.c index d6ed998..1ede225 100644 --- a/src/psnames/psnames.c +++ b/src/psnames/psnames.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include +#include "pspic.c" #include "psmodule.c" diff --git a/src/psnames/pspic.c b/src/psnames/pspic.c new file mode 100644 index 0000000..ed7dadd --- /dev/null +++ b/src/psnames/pspic.c @@ -0,0 +1,77 @@ +/***************************************************************************/ +/* */ +/* pspic.c */ +/* */ +/* The FreeType position independent code services for psnames module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pspic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from psmodule.c */ + FT_Error FT_Create_Class_pscmaps_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_pscmaps_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_pscmaps_interface( FT_Library, FT_Service_PsCMapsRec*); + + void + psnames_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->psnames ) + { + PSModulePIC* container = (PSModulePIC*)pic_container->psnames; + if(container->pscmaps_services) + FT_Destroy_Class_pscmaps_services(library, container->pscmaps_services); + container->pscmaps_services = NULL; + FT_FREE( container ); + pic_container->psnames = NULL; + } + } + + FT_Error + psnames_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + PSModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + 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 */ + error = FT_Create_Class_pscmaps_services(library, &container->pscmaps_services); + if(error) + goto Exit; + FT_Init_Class_pscmaps_interface(library, &container->pscmaps_interface); + +Exit: + if(error) + psnames_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/src/psnames/pspic.h b/src/psnames/pspic.h new file mode 100644 index 0000000..75a14fd --- /dev/null +++ b/src/psnames/pspic.h @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* pspic.h */ +/* */ +/* The FreeType position independent code services for psnames module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __PSPIC_H__ +#define __PSPIC_H__ + + +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 + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + typedef struct PSModulePIC_ + { + 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) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __PSPIC_H__ */ + + +/* END */ diff --git a/src/raster/ftmisc.h b/src/raster/ftmisc.h index d9d73e3..f04b540 100644 --- a/src/raster/ftmisc.h +++ b/src/raster/ftmisc.h @@ -52,6 +52,31 @@ (FT_ULong)_x4 ) + /* from include/freetype2/ftsystem.h */ + + typedef struct FT_MemoryRec_* FT_Memory; + + typedef void* (*FT_Alloc_Func)( FT_Memory memory, + long size ); + + typedef void (*FT_Free_Func)( FT_Memory memory, + void* block ); + + typedef void* (*FT_Realloc_Func)( FT_Memory memory, + long cur_size, + long new_size, + void* block ); + + typedef struct FT_MemoryRec_ + { + void* user; + + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + + } FT_MemoryRec; + /* from src/ftcalc.c */ #include diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c index eb9c4a4..23ad592 100644 --- a/src/raster/ftraster.c +++ b/src/raster/ftraster.c @@ -49,6 +49,10 @@ #ifdef _STANDALONE_ +#define FT_CONFIG_STANDARD_LIBRARY_H + +#include /* for memset */ + #include "ftmisc.h" #include "ftimage.h" @@ -58,6 +62,8 @@ #include "ftraster.h" #include FT_INTERNAL_CALC_H /* for FT_MulDiv only */ +#include "rastpic.h" + #endif /* !_STANDALONE_ */ @@ -72,13 +78,15 @@ /* profile is simply an array of scanline intersections on a given */ /* dimension. A profile's main attributes are */ /* */ - /* o its scanline position boundaries, i.e. `Ymin' and `Ymax'. */ + /* o its scanline position boundaries, i.e. `Ymin' and `Ymax' */ /* */ /* o an array of intersection coordinates for each scanline */ - /* between `Ymin' and `Ymax'. */ + /* between `Ymin' and `Ymax' */ /* */ /* o a direction, indicating whether it was built going `up' or */ - /* `down', as this is very important for filling rules. */ + /* `down', as this is very important for filling rules */ + /* */ + /* o its drop-out mode */ /* */ /* 2 - Sweeping the target map's scanlines in order to compute segment */ /* `spans' which are then filled. Additionally, this pass */ @@ -88,15 +96,15 @@ /* built from the bottom of the render pool, used as a stack. The */ /* following graphics shows the profile list under construction: */ /* */ - /* ____________________________________________________________ _ _ */ - /* | | | | | */ - /* | profile | coordinates for | profile | coordinates for |--> */ - /* | 1 | profile 1 | 2 | profile 2 |--> */ - /* |_________|___________________|_________|_________________|__ _ _ */ + /* __________________________________________________________ _ _ */ + /* | | | | | */ + /* | profile | coordinates for | profile | coordinates for |--> */ + /* | 1 | profile 1 | 2 | profile 2 |--> */ + /* |_________|_________________|_________|_________________|__ _ _ */ /* */ - /* ^ ^ */ - /* | | */ - /* start of render pool top */ + /* ^ ^ */ + /* | | */ + /* start of render pool top */ /* */ /* The top of the profile stack is kept in the `top' variable. */ /* */ @@ -140,11 +148,11 @@ /*************************************************************************/ /* define DEBUG_RASTER if you want to compile a debugging version */ -#define xxxDEBUG_RASTER +/* #define DEBUG_RASTER */ - /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */ - /* 5-levels anti-aliasing */ -#undef FT_RASTER_OPTION_ANTI_ALIASING + /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */ + /* 5-levels anti-aliasing */ +/* #define FT_RASTER_OPTION_ANTI_ALIASING */ /* The size of the two-lines intermediate bitmap used */ /* for anti-aliasing, in bytes. */ @@ -197,9 +205,22 @@ #define Raster_Err_Invalid -4 #define Raster_Err_Unsupported -5 -#define ft_memset memset +#define ft_memset memset + +#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 /* _STANDALONE_ */ +#else /* !_STANDALONE_ */ #include FT_INTERNAL_OBJECTS_H @@ -215,7 +236,7 @@ #define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph -#endif /* _STANDALONE_ */ +#endif /* !_STANDALONE_ */ #ifndef FT_MEM_SET @@ -304,13 +325,10 @@ } TPoint; - typedef enum TFlow_ - { - Flow_None = 0, - Flow_Up = 1, - Flow_Down = -1 - - } TFlow; + /* values for the `flags' bit field */ +#define Flow_Up 0x8 +#define Overshoot_Top 0x10 +#define Overshoot_Bottom 0x20 /* States of each line, arc, and profile */ @@ -329,18 +347,21 @@ struct TProfile_ { - FT_F26Dot6 X; /* current coordinate during sweep */ - PProfile link; /* link to next profile - various purpose */ - PLong offset; /* start of profile's data in render pool */ - int flow; /* Profile orientation: Asc/Descending */ - long height; /* profile's height in scanlines */ - long start; /* profile's starting scanline */ - - unsigned countL; /* number of lines to step before this */ - /* profile becomes drawable */ - - PProfile next; /* next profile in same contour, used */ - /* during drop-out control */ + FT_F26Dot6 X; /* current coordinate during sweep */ + PProfile link; /* link to next profile (various purposes) */ + PLong offset; /* start of profile's data in render pool */ + unsigned flags; /* Bit 0-2: drop-out mode */ + /* Bit 3: profile orientation (up/down) */ + /* Bit 4: is top profile? */ + /* Bit 5: is bottom profile? */ + long height; /* profile's height in scanlines */ + long start; /* profile's starting scanline */ + + unsigned countL; /* number of lines to step before this */ + /* profile becomes drawable */ + + PProfile next; /* next profile in same contour, used */ + /* during drop-out control */ }; typedef PProfile TProfileList; @@ -373,7 +394,7 @@ #define FT_UNUSED_RASTER do { } while ( 0 ) -#else /* FT_STATIC_RASTER */ +#else /* !FT_STATIC_RASTER */ #define RAS_ARGS PWorker worker, @@ -385,7 +406,7 @@ #define FT_UNUSED_RASTER FT_UNUSED( worker ) -#endif /* FT_STATIC_RASTER */ +#endif /* !FT_STATIC_RASTER */ typedef struct TWorker_ TWorker, *PWorker; @@ -415,65 +436,68 @@ #define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) #define SCALED( x ) ( ( (x) << ras.scale_shift ) - ras.precision_half ) - /* Note that I have moved the location of some fields in the */ - /* structure to ensure that the most used variables are used */ - /* at the top. Thus, their offset can be coded with less */ - /* opcodes, and it results in a smaller executable. */ +#define IS_BOTTOM_OVERSHOOT( x ) ( CEILING( x ) - x >= ras.precision_half ) +#define IS_TOP_OVERSHOOT( x ) ( x - FLOOR( x ) >= ras.precision_half ) + + /* The most used variables are positioned at the top of the structure. */ + /* Thus, their offset can be coded with less opcodes, resulting in a */ + /* smaller executable. */ struct TWorker_ { - Int precision_bits; /* precision related variables */ - Int precision; - Int precision_half; - Long precision_mask; - Int precision_shift; - Int precision_step; - Int precision_jitter; - - Int scale_shift; /* == precision_shift for bitmaps */ + Int precision_bits; /* precision related variables */ + Int precision; + Int precision_half; + Long precision_mask; + Int precision_shift; + Int precision_step; + Int precision_jitter; + + Int scale_shift; /* == precision_shift for bitmaps */ /* == precision_shift+1 for pixmaps */ - PLong buff; /* The profiles buffer */ - PLong sizeBuff; /* Render pool size */ - PLong maxBuff; /* Profiles buffer size */ - PLong top; /* Current cursor in buffer */ + PLong buff; /* The profiles buffer */ + PLong sizeBuff; /* Render pool size */ + PLong maxBuff; /* Profiles buffer size */ + PLong top; /* Current cursor in buffer */ - FT_Error error; + FT_Error error; - Int numTurns; /* number of Y-turns in outline */ + Int numTurns; /* number of Y-turns in outline */ - TPoint* arc; /* current Bezier arc pointer */ + TPoint* arc; /* current Bezier arc pointer */ - UShort bWidth; /* target bitmap width */ - PByte bTarget; /* target bitmap buffer */ - PByte gTarget; /* target pixmap buffer */ + UShort bWidth; /* target bitmap width */ + PByte bTarget; /* target bitmap buffer */ + PByte gTarget; /* target pixmap buffer */ - Long lastX, lastY, minY, maxY; + Long lastX, lastY; + Long minY, maxY; - UShort num_Profs; /* current number of profiles */ + UShort num_Profs; /* current number of profiles */ - Bool fresh; /* signals a fresh new profile which */ - /* 'start' field must be completed */ - Bool joint; /* signals that the last arc ended */ + Bool fresh; /* signals a fresh new profile which */ + /* `start' field must be completed */ + Bool joint; /* signals that the last arc ended */ /* exactly on a scanline. Allows */ /* removal of doublets */ - PProfile cProfile; /* current profile */ - PProfile fProfile; /* head of linked list of profiles */ - PProfile gProfile; /* contour's first profile in case */ + PProfile cProfile; /* current profile */ + PProfile fProfile; /* head of linked list of profiles */ + PProfile gProfile; /* contour's first profile in case */ /* of impact */ - TStates state; /* rendering state */ + TStates state; /* rendering state */ FT_Bitmap target; /* description of target bit/pixmap */ FT_Outline outline; - Long traceOfs; /* current offset in target bitmap */ - Long traceG; /* current offset in target pixmap */ + Long traceOfs; /* current offset in target bitmap */ + Long traceG; /* current offset in target pixmap */ - Short traceIncr; /* sweep's increment in target bitmap */ + Short traceIncr; /* sweep's increment in target bitmap */ - Short gray_min_x; /* current min x during gray rendering */ - Short gray_max_x; /* current max x during gray rendering */ + Short gray_min_x; /* current min x during gray rendering */ + Short gray_max_x; /* current max x during gray rendering */ /* dispatch variables */ @@ -482,31 +506,31 @@ Function_Sweep_Span* Proc_Sweep_Drop; Function_Sweep_Step* Proc_Sweep_Step; - Byte dropOutControl; /* current drop_out control method */ + Byte dropOutControl; /* current drop_out control method */ - Bool second_pass; /* indicates whether a horizontal pass */ + Bool second_pass; /* indicates whether a horizontal pass */ /* should be performed to control */ /* drop-out accurately when calling */ /* Render_Glyph. Note that there is */ /* no horizontal pass during gray */ /* rendering. */ - TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ + TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ - TBand band_stack[16]; /* band stack used for sub-banding */ - Int band_top; /* band stack top */ + TBand band_stack[16]; /* band stack used for sub-banding */ + Int band_top; /* band stack top */ #ifdef FT_RASTER_OPTION_ANTI_ALIASING - Byte* grays; + Byte* grays; - Byte gray_lines[RASTER_GRAY_LINES]; + Byte gray_lines[RASTER_GRAY_LINES]; /* Intermediate table used to render the */ /* graylevels pixmaps. */ /* gray_lines is a buffer holding two */ /* monochrome scanlines */ - Short gray_width; /* width in bytes of one monochrome */ + Short gray_width; /* width in bytes of one monochrome */ /* intermediate scanline of gray_lines. */ /* Each gray pixel takes 2 bits long there */ @@ -520,12 +544,12 @@ typedef struct TRaster_ { - char* buffer; - long buffer_size; - void* memory; - PWorker worker; - Byte grays[5]; - Short gray_width; + char* buffer; + long buffer_size; + void* memory; + PWorker worker; + Byte grays[5]; + Short gray_width; } TRaster, *PRaster; @@ -534,34 +558,72 @@ static TWorker cur_ras; #define ras cur_ras -#else +#else /* !FT_STATIC_RASTER */ #define ras (*worker) -#endif /* FT_STATIC_RASTER */ +#endif /* !FT_STATIC_RASTER */ #ifdef FT_RASTER_OPTION_ANTI_ALIASING - static const char count_table[256] = + /* A lookup table used to quickly count set bits in four gray 2x2 */ + /* cells. The values of the table have been produced with the */ + /* following code: */ + /* */ + /* for ( i = 0; i < 256; i++ ) */ + /* { */ + /* l = 0; */ + /* j = i; */ + /* */ + /* for ( c = 0; c < 4; c++ ) */ + /* { */ + /* l <<= 4; */ + /* */ + /* if ( j & 0x80 ) l++; */ + /* if ( j & 0x40 ) l++; */ + /* */ + /* j = ( j << 2 ) & 0xFF; */ + /* } */ + /* printf( "0x%04X", l ); */ + /* } */ + /* */ + + static const short count_table[256] = { - 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8 -a }; + 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012, + 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022, + 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, + 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, + 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, + 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, + 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212, + 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222, + 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, + 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, + 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, + 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, + 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, + 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, + 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012, + 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022, + 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, + 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, + 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, + 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, + 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212, + 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222 + }; #endif /* FT_RASTER_OPTION_ANTI_ALIASING */ @@ -593,9 +655,9 @@ a }; { if ( High ) { - ras.precision_bits = 10; - ras.precision_step = 128; - ras.precision_jitter = 24; + ras.precision_bits = 12; + ras.precision_step = 256; + ras.precision_jitter = 50; } else { @@ -622,14 +684,18 @@ a }; /* Create a new profile in the render pool. */ /* */ /* */ - /* aState :: The state/orientation of the new profile. */ + /* aState :: The state/orientation of the new profile. */ + /* */ + /* overshoot :: Whether the profile's unrounded start position */ + /* differs by at least a half pixel. */ /* */ /* */ /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ /* profile. */ /* */ static Bool - New_Profile( RAS_ARGS TStates aState ) + New_Profile( RAS_ARGS TStates aState, + Bool overshoot ) { if ( !ras.fProfile ) { @@ -644,30 +710,36 @@ a }; return FAILURE; } + ras.cProfile->flags = 0; + ras.cProfile->start = 0; + ras.cProfile->height = 0; + ras.cProfile->offset = ras.top; + ras.cProfile->link = (PProfile)0; + ras.cProfile->next = (PProfile)0; + ras.cProfile->flags = ras.dropOutControl; + switch ( aState ) { case Ascending_State: - ras.cProfile->flow = Flow_Up; + ras.cProfile->flags |= Flow_Up; + if ( overshoot ) + ras.cProfile->flags |= Overshoot_Bottom; + FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile )); break; case Descending_State: - ras.cProfile->flow = Flow_Down; + if ( overshoot ) + ras.cProfile->flags |= Overshoot_Top; FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile )); break; default: - FT_ERROR(( "New_Profile: invalid profile direction!\n" )); + FT_ERROR(( "New_Profile: invalid profile direction\n" )); ras.error = Raster_Err_Invalid; return FAILURE; } - ras.cProfile->start = 0; - ras.cProfile->height = 0; - ras.cProfile->offset = ras.top; - ras.cProfile->link = (PProfile)0; - ras.cProfile->next = (PProfile)0; - if ( !ras.gProfile ) ras.gProfile = ras.cProfile; @@ -687,11 +759,15 @@ a }; /* */ /* Finalize the current profile. */ /* */ + /* */ + /* overshoot :: Whether the profile's unrounded end position differs */ + /* by at least a half pixel. */ + /* */ /* */ /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ /* */ static Bool - End_Profile( RAS_ARG ) + End_Profile( RAS_ARGS Bool overshoot ) { Long h; PProfile oldProfile; @@ -701,7 +777,7 @@ a }; if ( h < 0 ) { - FT_ERROR(( "End_Profile: negative height encountered!\n" )); + FT_ERROR(( "End_Profile: negative height encountered\n" )); ras.error = Raster_Err_Neg_Height; return FAILURE; } @@ -711,15 +787,24 @@ a }; FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n", (long)ras.cProfile, ras.cProfile->start, h )); - oldProfile = ras.cProfile; ras.cProfile->height = h; - ras.cProfile = (PProfile)ras.top; + if ( overshoot ) + { + if ( ras.cProfile->flags & Flow_Up ) + ras.cProfile->flags |= Overshoot_Top; + else + ras.cProfile->flags |= Overshoot_Bottom; + } - ras.top += AlignProfileSize; + oldProfile = ras.cProfile; + ras.cProfile = (PProfile)ras.top; + + ras.top += AlignProfileSize; ras.cProfile->height = 0; ras.cProfile->offset = ras.top; - oldProfile->next = ras.cProfile; + + oldProfile->next = ras.cProfile; ras.num_Profs++; } @@ -822,23 +907,21 @@ a }; else p->link = NULL; - switch ( p->flow ) + if ( p->flags & Flow_Up ) + { + bottom = (Int)p->start; + top = (Int)( p->start + p->height - 1 ); + } + else { - case Flow_Down: bottom = (Int)( p->start - p->height + 1 ); top = (Int)p->start; p->start = bottom; p->offset += p->height - 1; - break; - - case Flow_Up: - default: - bottom = (Int)p->start; - top = (Int)( p->start + p->height - 1 ); } - if ( Insert_Y_Turn( RAS_VARS bottom ) || - Insert_Y_Turn( RAS_VARS top + 1 ) ) + if ( Insert_Y_Turn( RAS_VARS bottom ) || + Insert_Y_Turn( RAS_VARS top + 1 ) ) return FAILURE; p = p->link; @@ -1230,7 +1313,7 @@ a }; } else { - *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x, + *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x, e - y1, y2 - y1 ); arc -= degree; e += ras.precision; @@ -1335,13 +1418,15 @@ a }; case Unknown_State: if ( y > ras.lastY ) { - if ( New_Profile( RAS_VARS Ascending_State ) ) + if ( New_Profile( RAS_VARS Ascending_State, + IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } else { if ( y < ras.lastY ) - if ( New_Profile( RAS_VARS Descending_State ) ) + if ( New_Profile( RAS_VARS Descending_State, + IS_TOP_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } break; @@ -1349,8 +1434,9 @@ a }; case Ascending_State: if ( y < ras.lastY ) { - if ( End_Profile( RAS_VAR ) || - New_Profile( RAS_VARS Descending_State ) ) + if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) || + New_Profile( RAS_VARS Descending_State, + IS_TOP_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } break; @@ -1358,8 +1444,9 @@ a }; case Descending_State: if ( y > ras.lastY ) { - if ( End_Profile( RAS_VAR ) || - New_Profile( RAS_VARS Ascending_State ) ) + if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) || + New_Profile( RAS_VARS Ascending_State, + IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } break; @@ -1374,13 +1461,13 @@ a }; { case Ascending_State: if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, - x, y, ras.minY, ras.maxY ) ) + x, y, ras.minY, ras.maxY ) ) return FAILURE; break; case Descending_State: if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, - x, y, ras.minY, ras.maxY ) ) + x, y, ras.minY, ras.maxY ) ) return FAILURE; break; @@ -1431,8 +1518,10 @@ a }; ras.arc = ras.arcs; ras.arc[2].x = ras.lastX; ras.arc[2].y = ras.lastY; - ras.arc[1].x = cx; ras.arc[1].y = cy; - ras.arc[0].x = x; ras.arc[0].y = y; + ras.arc[1].x = cx; + ras.arc[1].y = cy; + ras.arc[0].x = x; + ras.arc[0].y = y; do { @@ -1472,13 +1561,17 @@ a }; state_bez = y1 < y3 ? Ascending_State : Descending_State; if ( ras.state != state_bez ) { + Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); + + /* finalize current profile if any */ - if ( ras.state != Unknown_State && - End_Profile( RAS_VAR ) ) + if ( ras.state != Unknown_State && + End_Profile( RAS_VARS o ) ) goto Fail; /* create a new profile */ - if ( New_Profile( RAS_VARS state_bez ) ) + if ( New_Profile( RAS_VARS state_bez, o ) ) goto Fail; } @@ -1547,9 +1640,12 @@ a }; ras.arc = ras.arcs; ras.arc[3].x = ras.lastX; ras.arc[3].y = ras.lastY; - ras.arc[2].x = cx1; ras.arc[2].y = cy1; - ras.arc[1].x = cx2; ras.arc[1].y = cy2; - ras.arc[0].x = x; ras.arc[0].y = y; + ras.arc[2].x = cx1; + ras.arc[2].y = cy1; + ras.arc[1].x = cx2; + ras.arc[1].y = cy2; + ras.arc[0].x = x; + ras.arc[0].y = y; do { @@ -1601,11 +1697,16 @@ a }; /* detect a change of direction */ if ( ras.state != state_bez ) { - if ( ras.state != Unknown_State && - End_Profile( RAS_VAR ) ) + Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); + + + /* finalize current profile if any */ + if ( ras.state != Unknown_State && + End_Profile( RAS_VARS o ) ) goto Fail; - if ( New_Profile( RAS_VARS state_bez ) ) + if ( New_Profile( RAS_VARS state_bez, o ) ) goto Fail; } @@ -1698,8 +1799,13 @@ a }; v_control = v_start; point = points + first; - tags = ras.outline.tags + first; - tag = FT_CURVE_TAG( tags[0] ); + tags = ras.outline.tags + first; + + /* set scan mode if necessary */ + if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE ) + ras.dropOutControl = (Byte)tags[0] >> 5; + + tag = FT_CURVE_TAG( tags[0] ); /* A contour cannot start with a cubic control point! */ if ( tag == FT_CURVE_TAG_CUBIC ) @@ -1905,27 +2011,36 @@ a }; for ( i = 0; i < ras.outline.n_contours; i++ ) { + Bool o; + + ras.state = Unknown_State; ras.gProfile = NULL; if ( Decompose_Curve( RAS_VARS (unsigned short)start, - ras.outline.contours[i], - flipped ) ) + ras.outline.contours[i], + flipped ) ) return FAILURE; start = ras.outline.contours[i] + 1; - /* We must now see whether the extreme arcs join or not */ + /* we must now check whether the extreme arcs join or not */ if ( FRAC( ras.lastY ) == 0 && ras.lastY >= ras.minY && ras.lastY <= ras.maxY ) - if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow ) + if ( ras.gProfile && + ( ras.gProfile->flags & Flow_Up ) == + ( ras.cProfile->flags & Flow_Up ) ) ras.top--; /* Note that ras.gProfile can be nil if the contour was too small */ /* to be drawn. */ lastProfile = ras.cProfile; - if ( End_Profile( RAS_VAR ) ) + if ( ras.cProfile->flags & Flow_Up ) + o = IS_TOP_OVERSHOOT( ras.lastY ); + else + o = IS_BOTTOM_OVERSHOOT( ras.lastY ); + if ( End_Profile( RAS_VARS o ) ) return FAILURE; /* close the `next profile in contour' linked list */ @@ -2045,7 +2160,7 @@ a }; while ( current ) { current->X = *current->offset; - current->offset += current->flow; + current->offset += current->flags & Flow_Up ? 1 : -1; current->height--; current = current->link; } @@ -2220,16 +2335,19 @@ a }; if ( e1 > e2 ) { + Int dropOutControl = left->flags & 7; + + if ( e1 == e2 + ras.precision ) { - switch ( ras.dropOutControl ) + switch ( dropOutControl ) { case 0: /* simple drop-outs including stubs */ pxl = e2; break; case 4: /* smart drop-outs including stubs */ - pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; case 1: /* simple drop-outs excluding stubs */ @@ -2237,11 +2355,10 @@ a }; /* Drop-out Control Rules #4 and #6 */ - /* The spec is not very clear regarding those rules. It */ - /* presents a method that is way too costly to implement */ - /* while the general idea seems to get rid of `stubs'. */ + /* The specification neither provides an exact definition */ + /* of a `stub' nor gives exact rules to exclude them. */ /* */ - /* Here, we only get rid of stubs recognized if: */ + /* Here the constraints we use to recognize a stub. */ /* */ /* upper stub: */ /* */ @@ -2255,27 +2372,31 @@ a }; /* - P_Left is the successor of P_Right in that contour */ /* - y is the bottom of P_Left */ /* */ + /* We draw a stub if the following constraints are met. */ + /* */ + /* - for an upper or lower stub, there is top or bottom */ + /* overshoot, respectively */ + /* - the covered interval is greater or equal to a half */ + /* pixel */ + + /* upper stub test */ + if ( left->next == right && + left->height <= 0 && + !( left->flags & Overshoot_Top && + x2 - x1 >= ras.precision_half ) ) + return; - /* FIXXXME: uncommenting this line solves the disappearing */ - /* bit problem in the `7' of verdana 10pts, but */ - /* makes a new one in the `C' of arial 14pts */ -#if 0 - if ( x2 - x1 < ras.precision_half ) -#endif - { - /* upper stub test */ - if ( left->next == right && left->height <= 0 ) - return; - - /* lower stub test */ - if ( right->next == left && left->start == y ) - return; - } + /* lower stub test */ + if ( right->next == left && + left->start == y && + !( left->flags & Overshoot_Bottom && + x2 - x1 >= ras.precision_half ) ) + return; - if ( ras.dropOutControl == 1 ) + if ( dropOutControl == 1 ) pxl = e2; else - pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; default: /* modes 2, 3, 6, 7 */ @@ -2415,16 +2536,19 @@ a }; if ( e1 > e2 ) { + Int dropOutControl = left->flags & 7; + + if ( e1 == e2 + ras.precision ) { - switch ( ras.dropOutControl ) + switch ( dropOutControl ) { case 0: /* simple drop-outs including stubs */ pxl = e2; break; case 4: /* smart drop-outs including stubs */ - pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; case 1: /* simple drop-outs excluding stubs */ @@ -2432,17 +2556,23 @@ a }; /* see Vertical_Sweep_Drop for details */ /* rightmost stub test */ - if ( left->next == right && left->height <= 0 ) + if ( left->next == right && + left->height <= 0 && + !( left->flags & Overshoot_Top && + x2 - x1 >= ras.precision_half ) ) return; /* leftmost stub test */ - if ( right->next == left && left->start == y ) + if ( right->next == left && + left->start == y && + !( left->flags & Overshoot_Bottom && + x2 - x1 >= ras.precision_half ) ) return; - if ( ras.dropOutControl == 1 ) + if ( dropOutControl == 1 ) pxl = e2; else - pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; default: /* modes 2, 3, 6, 7 */ @@ -2543,10 +2673,10 @@ a }; static void Vertical_Gray_Sweep_Step( RAS_ARG ) { - Int c1, c2; - PByte pix, bit, bit2; - char* count = (char*)count_table; - Byte* grays; + Int c1, c2; + PByte pix, bit, bit2; + short* count = (short*)count_table; + Byte* grays; ras.traceOfs += ras.gray_width; @@ -2665,16 +2795,19 @@ a }; if ( e1 > e2 ) { + Int dropOutControl = left->flags & 7; + + if ( e1 == e2 + ras.precision ) { - switch ( ras.dropOutControl ) + switch ( dropOutControl ) { case 0: /* simple drop-outs including stubs */ e1 = e2; break; case 4: /* smart drop-outs including stubs */ - e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); + e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; case 1: /* simple drop-outs excluding stubs */ @@ -2689,10 +2822,10 @@ a }; if ( right->next == left && left->start == y ) return; - if ( ras.dropOutControl == 1 ) + if ( dropOutControl == 1 ) e1 = e2; else - e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); + e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; @@ -2806,7 +2939,7 @@ a }; y = min_Y; y_height = 0; - if ( ras.numTurns > 0 && + if ( ras.numTurns > 0 && ras.sizeBuff[-ras.numTurns] == min_Y ) ras.numTurns--; @@ -2824,16 +2957,10 @@ a }; { DelOld( &waiting, P ); - switch ( P->flow ) - { - case Flow_Up: + if ( P->flags & Flow_Up ) InsNew( &draw_left, P ); - break; - - case Flow_Down: + else InsNew( &draw_right, P ); - break; - } } P = Q; @@ -2876,7 +3003,10 @@ a }; { if ( e1 > e2 || e2 == e1 + ras.precision ) { - if ( ras.dropOutControl != 2 ) + Int dropOutControl = P_Left->flags & 7; + + + if ( dropOutControl != 2 ) { /* a drop-out was detected */ @@ -3070,7 +3200,7 @@ a }; Set_High_Precision( RAS_VARS ras.outline.flags & - FT_OUTLINE_HIGH_PRECISION ); + FT_OUTLINE_HIGH_PRECISION ); ras.scale_shift = ras.precision_shift; if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) @@ -3146,7 +3276,7 @@ a }; Set_High_Precision( RAS_VARS ras.outline.flags & - FT_OUTLINE_HIGH_PRECISION ); + FT_OUTLINE_HIGH_PRECISION ); ras.scale_shift = ras.precision_shift + 1; if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) @@ -3234,7 +3364,6 @@ a }; raster->grays[n] = n * 255 / 4; raster->gray_width = RASTER_GRAY_LINES / 2; - #else FT_UNUSED( raster ); #endif @@ -3411,23 +3540,24 @@ a }; #ifdef FT_RASTER_OPTION_ANTI_ALIASING worker->grays = raster->grays; worker->gray_width = raster->gray_width; + + FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 ); #endif - return ( ( params->flags & FT_RASTER_FLAG_AA ) - ? Render_Gray_Glyph( RAS_VAR ) - : Render_Glyph( RAS_VAR ) ); + return ( params->flags & FT_RASTER_FLAG_AA ) + ? Render_Gray_Glyph( RAS_VAR ) + : Render_Glyph( RAS_VAR ); } - const FT_Raster_Funcs ft_standard_raster = - { + FT_DEFINE_RASTER_FUNCS( ft_standard_raster, FT_GLYPH_FORMAT_OUTLINE, (FT_Raster_New_Func) ft_black_new, (FT_Raster_Reset_Func) ft_black_reset, (FT_Raster_Set_Mode_Func)ft_black_set_mode, (FT_Raster_Render_Func) ft_black_render, (FT_Raster_Done_Func) ft_black_done - }; + ) /* END */ diff --git a/src/raster/ftrend1.c b/src/raster/ftrend1.c index 3cc8d07..1ed8af6 100644 --- a/src/raster/ftrend1.c +++ b/src/raster/ftrend1.c @@ -21,6 +21,7 @@ #include FT_OUTLINE_H #include "ftrend1.h" #include "ftraster.h" +#include "rastpic.h" #include "rasterrs.h" @@ -118,6 +119,7 @@ } /* check rendering mode */ +#ifndef FT_CONFIG_OPTION_PIC if ( mode != FT_RENDER_MODE_MONO ) { /* raster1 is only capable of producing monochrome bitmaps */ @@ -130,6 +132,25 @@ if ( render->clazz == &ft_raster5_renderer_class ) return Raster_Err_Cannot_Render_Glyph; } +#else /* FT_CONFIG_OPTION_PIC */ + /* When PIC is enabled, we cannot get to the class object */ + /* so instead we check the final character in the class name */ + /* ("raster5" or "raster1"). Yes this is a hack. */ + /* The "correct" thing to do is have different render function */ + /* for each of the classes. */ + if ( mode != FT_RENDER_MODE_MONO ) + { + /* raster1 is only capable of producing monochrome bitmaps */ + if ( render->clazz->root.module_name[6] == '1' ) + return Raster_Err_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; + } +#endif /* FT_CONFIG_OPTION_PIC */ outline = &slot->outline; @@ -208,10 +229,8 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_raster1_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_raster1_renderer_class, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -224,7 +243,7 @@ (FT_Module_Constructor)ft_raster1_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -233,18 +252,17 @@ (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, (FT_Renderer_SetModeFunc) ft_raster1_set_mode, - (FT_Raster_Funcs*) &ft_standard_raster - }; + (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + ) /* This renderer is _NOT_ part of the default modules; you will need */ /* to register it by hand in your application. It should only be */ /* used for backwards-compatibility with FT 1.x anyway. */ /* */ - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_raster5_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_raster5_renderer_class, + + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -257,7 +275,7 @@ (FT_Module_Constructor)ft_raster1_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -266,8 +284,8 @@ (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, (FT_Renderer_SetModeFunc) ft_raster1_set_mode, - (FT_Raster_Funcs*) &ft_standard_raster - }; + (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + ) /* END */ diff --git a/src/raster/ftrend1.h b/src/raster/ftrend1.h index 76e9a5f..4cf1286 100644 --- a/src/raster/ftrend1.h +++ b/src/raster/ftrend1.h @@ -27,13 +27,13 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster1_renderer_class; + FT_DECLARE_RENDERER( ft_raster1_renderer_class ) /* this renderer is _NOT_ part of the default modules, you'll need */ /* to register it by hand in your application. It should only be */ /* used for backwards-compatibility with FT 1.x anyway. */ /* */ - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster5_renderer_class; + FT_DECLARE_RENDERER( ft_raster5_renderer_class ) FT_END_HEADER diff --git a/src/raster/raster.c b/src/raster/raster.c index f13a67a..1202a11 100644 --- a/src/raster/raster.c +++ b/src/raster/raster.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include +#include "rastpic.c" #include "ftraster.c" #include "ftrend1.c" diff --git a/src/raster/rastpic.c b/src/raster/rastpic.c new file mode 100644 index 0000000..3c26487 --- /dev/null +++ b/src/raster/rastpic.c @@ -0,0 +1,89 @@ +/***************************************************************************/ +/* */ +/* rastpic.c */ +/* */ +/* The FreeType position independent code services for raster module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "rastpic.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*); + + void + ft_raster1_renderer_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->raster ) + { + RasterPIC* container = (RasterPIC*)pic_container->raster; + if(--container->ref_count) + return; + FT_FREE( container ); + pic_container->raster = NULL; + } + } + + + FT_Error + ft_raster1_renderer_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + RasterPIC* container; + FT_Memory memory = library->memory; + + /* since this function also serve raster5 renderer, + it implements reference counting */ + if(pic_container->raster) + { + ((RasterPIC*)pic_container->raster)->ref_count++; + return error; + } + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + 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 */ + 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) + { + return ft_raster1_renderer_class_pic_init(library); + } + void ft_raster5_renderer_class_pic_free(FT_Library library) + { + ft_raster1_renderer_class_pic_free(library); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/src/raster/rastpic.h b/src/raster/rastpic.h new file mode 100644 index 0000000..dcd82b8 --- /dev/null +++ b/src/raster/rastpic.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* rastpic.h */ +/* */ +/* The FreeType position independent code services for raster module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __RASTPIC_H__ +#define __RASTPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_STANDARD_RASTER_GET ft_standard_raster + +#else /* FT_CONFIG_OPTION_PIC */ + + typedef struct RasterPIC_ + { + 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) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __RASTPIC_H__ */ + + +/* END */ diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c index 142ef76..1097efb 100644 --- a/src/sfnt/sfdriver.c +++ b/src/sfnt/sfdriver.c @@ -17,12 +17,14 @@ #include +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_SFNT_H #include FT_INTERNAL_OBJECTS_H #include "sfdriver.h" #include "ttload.h" #include "sfobjs.h" +#include "sfntpic.h" #include "sferrors.h" @@ -48,6 +50,15 @@ #include FT_SERVICE_SFNT_H #include FT_SERVICE_TT_CMAP_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_sfdriver + /* * SFNT TABLE SERVICE @@ -103,27 +114,28 @@ sfnt_table_info( TT_Face face, FT_UInt idx, FT_ULong *tag, + FT_ULong *offset, FT_ULong *length ) { - if ( !tag || !length ) + if ( !tag || !offset || !length ) return SFNT_Err_Invalid_Argument; if ( idx >= face->num_tables ) return SFNT_Err_Table_Missing; *tag = face->dir_tables[idx].Tag; + *offset = face->dir_tables[idx].Offset; *length = face->dir_tables[idx].Length; return SFNT_Err_Ok; } - static const FT_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 - }; + ) #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -155,11 +167,19 @@ sfnt_get_name_index( TT_Face face, FT_String* glyph_name ) { - FT_Face root = &face->root; - FT_Long i; + 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 + FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", + FT_UINT_MAX, root->num_glyphs )); - for ( i = 0; i < root->num_glyphs; i++ ) + for ( i = 0; i < max_gid; i++ ) { FT_String* gname; FT_Error error = tt_face_get_ps_name( face, i, &gname ); @@ -169,18 +189,17 @@ continue; if ( !ft_strcmp( glyph_name, gname ) ) - return (FT_UInt)i; + return i; } return 0; } - static const FT_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 - }; + ) #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -300,19 +319,17 @@ return result; } - static const FT_Service_PsFontNameRec sfnt_service_ps_name = - { + FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name, (FT_PsName_GetFunc)sfnt_get_ps_name - }; + ) /* * TT CMAP INFO */ - static const FT_Service_TTCMapsRec tt_service_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 @@ -353,11 +370,10 @@ } - static const FT_Service_BDFRec sfnt_service_bdf = - { + FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf, (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id, - (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop, - }; + (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop + ) #endif /* TT_CONFIG_OPTION_BDF */ @@ -366,20 +382,35 @@ * SERVICE LIST */ - static const FT_ServiceDescRec sfnt_services[] = - { - { FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table }, - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name }, -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - { FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict }, -#endif -#ifdef TT_CONFIG_OPTION_BDF - { FT_SERVICE_ID_BDF, &sfnt_service_bdf }, +#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 + ) +#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 + ) +#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 + ) +#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 + ) #endif - { FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info }, - - { NULL, NULL } - }; FT_CALLBACK_DEF( FT_Module_Interface ) @@ -388,7 +419,7 @@ { FT_UNUSED( module ); - return ft_service_list_lookup( sfnt_services, module_interface ); + return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface ); } @@ -519,10 +550,18 @@ #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define PUT_EMBEDDED_BITMAPS(a) a +#else +#define PUT_EMBEDDED_BITMAPS(a) 0 +#endif +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#define PUT_PS_NAMES(a) a +#else +#define PUT_PS_NAMES(a) 0 +#endif - static - const SFNT_Interface sfnt_interface = - { + FT_DEFINE_SFNT_INTERFACE(sfnt_interface, tt_face_goto_table, sfnt_init_face, @@ -532,10 +571,8 @@ tt_face_load_any, -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_sfnt_header_stub, - tt_face_load_directory_stub, -#endif + 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, @@ -547,53 +584,32 @@ tt_face_load_name, tt_face_free_name, -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_hdmx_stub, - tt_face_free_hdmx_stub, -#endif + 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, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* see `ttload.h' */ - tt_face_load_bhed, -#else - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_load_bhed), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_set_sbit_strike_stub, - tt_face_load_sbit_stub, + 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, - tt_load_sbit_metrics, -#endif + tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */ -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - tt_face_load_sbit_image, -#else - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_free_sbit_stub, -#endif + tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES /* see `ttpost.h' */ - tt_face_get_ps_name, - tt_face_free_ps_names, -#else - 0, - 0, -#endif + PUT_PS_NAMES(tt_face_get_ps_name), + PUT_PS_NAMES(tt_face_free_ps_names), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_charmap_stub, - tt_face_free_charmap_stub, -#endif + tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ /* since version 2.1.8 */ @@ -604,27 +620,19 @@ tt_face_load_font_dir, tt_face_load_hmtx, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* see `ttsbit.h' and `sfnt.h' */ - tt_face_load_eblc, - tt_face_free_eblc, + PUT_EMBEDDED_BITMAPS(tt_face_load_eblc), + PUT_EMBEDDED_BITMAPS(tt_face_free_eblc), - tt_face_set_sbit_strike, - tt_face_load_strike_metrics, -#else - 0, - 0, - 0, - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike), + PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics), tt_face_get_metrics - }; + ) - FT_CALLBACK_TABLE_DEF - const FT_Module_Class sfnt_module_class = - { + FT_DEFINE_MODULE(sfnt_module_class, + 0, /* not a font driver or renderer */ sizeof( FT_ModuleRec ), @@ -632,12 +640,12 @@ 0x10000L, /* driver version 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or higher */ - (const void*)&sfnt_interface, /* module specific interface */ + (const void*)&FT_SFNT_INTERFACE_GET, /* module specific interface */ (FT_Module_Constructor)0, (FT_Module_Destructor) 0, (FT_Module_Requester) sfnt_get_interface - }; + ) /* END */ diff --git a/src/sfnt/sfdriver.h b/src/sfnt/sfdriver.h index 92db796..5de25d5 100644 --- a/src/sfnt/sfdriver.h +++ b/src/sfnt/sfdriver.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Module_Class ) sfnt_module_class; + FT_DECLARE_MODULE( sfnt_module_class ) FT_END_HEADER diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c index 45a820b..fc507b4 100644 --- a/src/sfnt/sfnt.c +++ b/src/sfnt/sfnt.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include +#include "sfntpic.c" #include "ttload.c" #include "ttmtx.c" #include "ttcmap.c" diff --git a/src/sfnt/sfntpic.c b/src/sfnt/sfntpic.c new file mode 100644 index 0000000..fd3cf4e --- /dev/null +++ b/src/sfnt/sfntpic.c @@ -0,0 +1,101 @@ +/***************************************************************************/ +/* */ +/* sfntpic.c */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "sfntpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from sfdriver.c */ + FT_Error FT_Create_Class_sfnt_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_sfnt_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec*); + void FT_Init_Class_sfnt_interface( FT_Library, SFNT_Interface*); + void FT_Init_Class_sfnt_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*); + void FT_Init_Class_sfnt_service_ps_name( FT_Library, FT_Service_PsFontNameRec*); + void FT_Init_Class_tt_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*); + void FT_Init_Class_sfnt_service_sfnt_table( FT_Service_SFNT_TableRec*); + + /* forward declaration of PIC init functions from ttcmap.c */ + FT_Error FT_Create_Class_tt_cmap_classes( FT_Library, TT_CMap_Class**); + void FT_Destroy_Class_tt_cmap_classes( FT_Library, TT_CMap_Class*); + + void + sfnt_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->sfnt ) + { + sfntModulePIC* container = (sfntModulePIC*)pic_container->sfnt; + if(container->sfnt_services) + 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; + } + } + + + FT_Error + sfnt_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + sfntModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + 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 */ + 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) + goto Exit; + FT_Init_Class_sfnt_service_glyph_dict(library, &container->sfnt_service_glyph_dict); + FT_Init_Class_sfnt_service_ps_name(library, &container->sfnt_service_ps_name); + FT_Init_Class_tt_service_get_cmap_info(library, &container->tt_service_get_cmap_info); + FT_Init_Class_sfnt_service_sfnt_table(&container->sfnt_service_sfnt_table); +#ifdef TT_CONFIG_OPTION_BDF + FT_Init_Class_sfnt_service_bdf(&container->sfnt_service_bdf); +#endif + FT_Init_Class_sfnt_interface(library, &container->sfnt_interface); + +Exit: + if(error) + sfnt_module_class_pic_free(library); + return error; + } + + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/src/sfnt/sfntpic.h b/src/sfnt/sfntpic.h new file mode 100644 index 0000000..6943b42 --- /dev/null +++ b/src/sfnt/sfntpic.h @@ -0,0 +1,88 @@ +/***************************************************************************/ +/* */ +/* sfntpic.h */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __SFNTPIC_H__ +#define __SFNTPIC_H__ + + +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 + +#else /* FT_CONFIG_OPTION_PIC */ + +/* 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_ + { + 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; +#ifdef TT_CONFIG_OPTION_BDF + FT_Service_BDFRec sfnt_service_bdf; +#endif + 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) + +#endif /* FT_CONFIG_OPTION_PIC */ + +/* */ + +FT_END_HEADER + +#endif /* __SFNTPIC_H__ */ + + +/* END */ diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index c826b92..b74b1a9 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -26,6 +26,7 @@ #include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_SFNT_NAMES_H #include "sferrors.h" #ifdef TT_CONFIG_OPTION_BDF @@ -527,13 +528,27 @@ #endif FT_Bool has_outline; FT_Bool is_apple_sbit; + FT_Bool ignore_preferred_family = FALSE; + FT_Bool ignore_preferred_subfamily = FALSE; SFNT_Service sfnt = (SFNT_Service)face->sfnt; FT_UNUSED( face_index ); - FT_UNUSED( num_params ); - FT_UNUSED( params ); + /* Check parameters */ + + { + FT_Int i; + + + for ( i = 0; i < num_params; i++ ) + { + if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY ) + ignore_preferred_family = TRUE; + else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY ) + ignore_preferred_subfamily = TRUE; + } + } /* Load tables */ @@ -722,26 +737,30 @@ /* Foundation (WPF). This flag has been introduced in version */ /* 1.5 of the OpenType specification (May 2008). */ + face->root.family_name = NULL; + face->root.style_name = NULL; if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) { - GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !ignore_preferred_family ) + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); if ( !face->root.family_name ) GET_NAME( FONT_FAMILY, &face->root.family_name ); - GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !ignore_preferred_subfamily ) + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); if ( !face->root.style_name ) GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); } else { GET_NAME( WWS_FAMILY, &face->root.family_name ); - if ( !face->root.family_name ) + if ( !face->root.family_name && !ignore_preferred_family ) GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); if ( !face->root.family_name ) GET_NAME( FONT_FAMILY, &face->root.family_name ); GET_NAME( WWS_SUBFAMILY, &face->root.style_name ); - if ( !face->root.style_name ) + if ( !face->root.style_name && !ignore_preferred_subfamily ) GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); if ( !face->root.style_name ) GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); @@ -749,8 +768,8 @@ /* now set up root fields */ { - FT_Face root = &face->root; - FT_Int32 flags = root->face_flags; + FT_Face root = &face->root; + FT_Long flags = root->face_flags; /*********************************************************************/ diff --git a/src/sfnt/ttbdf.c b/src/sfnt/ttbdf.c index 6c95387..206cece 100644 --- a/src/sfnt/ttbdf.c +++ b/src/sfnt/ttbdf.c @@ -84,7 +84,7 @@ FT_Byte* p = bdf->table; FT_UInt version = FT_NEXT_USHORT( p ); FT_UInt num_strikes = FT_NEXT_USHORT( p ); - FT_UInt32 strings = FT_NEXT_ULONG ( p ); + FT_ULong strings = FT_NEXT_ULONG ( p ); FT_UInt count; FT_Byte* strike; @@ -141,13 +141,13 @@ const char* property_name, BDF_PropertyRec *aprop ) { - TT_BDF bdf = &face->bdf; - FT_Size size = FT_FACE(face)->size; - FT_Error error = 0; - FT_Byte* p; - FT_UInt count; - FT_Byte* strike; - FT_UInt property_len; + TT_BDF bdf = &face->bdf; + FT_Size size = FT_FACE(face)->size; + FT_Error error = 0; + FT_Byte* p; + FT_UInt count; + FT_Byte* strike; + FT_Offset property_len; aprop->type = BDF_PROPERTY_TYPE_NONE; diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c index 6830391..b283f6d 100644 --- a/src/sfnt/ttcmap.c +++ b/src/sfnt/ttcmap.c @@ -25,6 +25,7 @@ #include FT_INTERNAL_STREAM_H #include "ttload.h" #include "ttcmap.h" +#include "sfntpic.h" /*************************************************************************/ @@ -124,7 +125,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap0_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -157,17 +158,14 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 0; + cmap_info->format = 0; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap0_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap0_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, @@ -176,11 +174,11 @@ (FT_CMap_CharNextFunc) tt_cmap0_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 0, (TT_CMap_ValidateFunc) tt_cmap0_validate, (TT_CMap_Info_GetFunc) tt_cmap0_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_0 */ @@ -462,7 +460,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap2_char_next( TT_CMap cmap, FT_UInt32 *pcharcode ) { @@ -536,17 +534,14 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 2; + cmap_info->format = 2; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap2_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap2_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, @@ -555,11 +550,11 @@ (FT_CMap_CharNextFunc) tt_cmap2_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 2, (TT_CMap_ValidateFunc) tt_cmap2_validate, (TT_CMap_Info_GetFunc) tt_cmap2_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_2 */ @@ -664,7 +659,7 @@ p = table + 6; cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; - cmap->cur_charcode = 0xFFFFFFFFUL; + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; cmap->cur_gindex = 0; return SFNT_Err_Ok; @@ -742,7 +737,7 @@ if ( cmap->cur_charcode >= 0xFFFFUL ) goto Fail; - charcode = cmap->cur_charcode + 1; + charcode = (FT_UInt)cmap->cur_charcode + 1; if ( charcode < cmap->cur_start ) charcode = cmap->cur_start; @@ -804,7 +799,7 @@ } Fail: - cmap->cur_charcode = 0xFFFFFFFFUL; + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; cmap->cur_gindex = 0; } @@ -1093,7 +1088,7 @@ FT_UInt num_segs2, start, end, offset; FT_Int delta; FT_UInt max, min, mid, num_segs; - FT_UInt charcode = *pcharcode; + FT_UInt charcode = (FT_UInt)*pcharcode; FT_UInt gindex = 0; FT_Byte* p; @@ -1335,7 +1330,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap4_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1375,17 +1370,14 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 4; + cmap_info->format = 4; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap4_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap4_class_rec, sizeof ( TT_CMap4Rec ), (FT_CMap_InitFunc) tt_cmap4_init, (FT_CMap_DoneFunc) NULL, @@ -1393,11 +1385,11 @@ (FT_CMap_CharNextFunc) tt_cmap4_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 4, (TT_CMap_ValidateFunc) tt_cmap4_validate, (TT_CMap_Info_GetFunc) tt_cmap4_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_4 */ @@ -1489,7 +1481,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap6_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1537,17 +1529,14 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 6; + cmap_info->format = 6; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap6_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap6_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, @@ -1556,11 +1545,11 @@ (FT_CMap_CharNextFunc) tt_cmap6_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 6, (TT_CMap_ValidateFunc) tt_cmap6_validate, (TT_CMap_Info_GetFunc) tt_cmap6_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_6 */ @@ -1635,7 +1624,7 @@ FT_INVALID_TOO_SHORT; length = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 8208 ) + if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 ) FT_INVALID_TOO_SHORT; is32 = table + 12; @@ -1745,7 +1734,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap8_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1793,17 +1782,14 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 8; + cmap_info->format = 8; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap8_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap8_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, @@ -1812,11 +1798,11 @@ (FT_CMap_CharNextFunc) tt_cmap8_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 8, (TT_CMap_ValidateFunc) tt_cmap8_validate, (TT_CMap_Info_GetFunc) tt_cmap8_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_8 */ @@ -1863,7 +1849,8 @@ p = table + 16; count = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 20 + count * 2 ) + if ( length > (FT_ULong)( valid->limit - table ) || + length < 20 + count * 2 ) FT_INVALID_TOO_SHORT; /* check glyph indices */ @@ -1905,7 +1892,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap10_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1944,17 +1931,14 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 10; + cmap_info->format = 10; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap10_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap10_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, @@ -1963,11 +1947,11 @@ (FT_CMap_CharNextFunc) tt_cmap10_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 10, (TT_CMap_ValidateFunc) tt_cmap10_validate, (TT_CMap_Info_GetFunc) tt_cmap10_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_10 */ @@ -2048,7 +2032,8 @@ p = table + 12; num_groups = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 16 + 12 * num_groups ) + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) FT_INVALID_TOO_SHORT; /* check groups, they must be in increasing order */ @@ -2225,7 +2210,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap12_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -2243,8 +2228,10 @@ if ( cmap12->valid ) { gindex = cmap12->cur_gindex; + + /* XXX: check cur_charcode overflow is expected */ if ( gindex ) - *pchar_code = cmap12->cur_charcode; + *pchar_code = (FT_UInt32)cmap12->cur_charcode; } else gindex = 0; @@ -2252,7 +2239,8 @@ else gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); - return gindex; + /* XXX: check gindex overflow is expected */ + return (FT_UInt32)gindex; } @@ -2263,17 +2251,14 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 12; + cmap_info->format = 12; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap12_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap12_class_rec, sizeof ( TT_CMap12Rec ), (FT_CMap_InitFunc) tt_cmap12_init, @@ -2282,15 +2267,331 @@ (FT_CMap_CharNextFunc) tt_cmap12_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 12, (TT_CMap_ValidateFunc) tt_cmap12_validate, (TT_CMap_Info_GetFunc) tt_cmap12_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_12 */ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 13 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 13 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* count 12 ULONG number of groups */ + /* 16 */ + /* */ + /* This header is followed by `count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* glyphId 8 ULONG glyph ID for the whole group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + + typedef struct TT_CMap13Rec_ + { + TT_CMapRec cmap; + FT_Bool valid; + FT_ULong cur_charcode; + FT_UInt cur_gindex; + FT_ULong cur_group; + FT_ULong num_groups; + + } TT_CMap13Rec, *TT_CMap13; + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_init( TT_CMap13 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 12; + cmap->num_groups = FT_PEEK_ULONG( table ); + + cmap->valid = 0; + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; + + + if ( table + 16 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 4; + length = TT_NEXT_ULONG( p ); + + p = table + 12; + num_groups = TT_NEXT_ULONG( p ); + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_ULong n, start, end, glyph_id, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + + last = end; + } + } + + return SFNT_Err_Ok; + } + + + /* search the index of the charcode next to cmap->cur_charcode */ + /* cmap->cur_group should be set up properly by caller */ + /* */ + static void + tt_cmap13_next( TT_CMap13 cmap ) + { + FT_Byte* p; + FT_ULong start, end, glyph_id, char_code; + FT_ULong n; + FT_UInt gindex; + + + if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) + goto Fail; + + char_code = cmap->cur_charcode + 1; + + n = cmap->cur_group; + + for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) + { + p = cmap->cmap.data + 16 + 12 * n; + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_PEEK_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + if ( char_code <= end ) + { + gindex = (FT_UInt)glyph_id; + + if ( gindex ) + { + cmap->cur_charcode = char_code;; + cmap->cur_gindex = gindex; + cmap->cur_group = n; + + return; + } + } + } + + Fail: + cmap->valid = 0; + } + + + static FT_UInt + tt_cmap13_char_map_binary( TT_CMap cmap, + FT_UInt32* pchar_code, + FT_Bool next ) + { + FT_UInt gindex = 0; + FT_Byte* p = cmap->data + 12; + FT_UInt32 num_groups = TT_PEEK_ULONG( p ); + FT_UInt32 char_code = *pchar_code; + FT_UInt32 start, end; + FT_UInt32 max, min, mid; + + + if ( !num_groups ) + return 0; + + /* make compiler happy */ + mid = num_groups; + end = 0xFFFFFFFFUL; + + if ( next ) + char_code++; + + min = 0; + max = num_groups; + + /* binary search */ + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = cmap->data + 16 + 12 * mid; + + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + max = mid; + else if ( char_code > end ) + min = mid + 1; + else + { + gindex = (FT_UInt)TT_PEEK_ULONG( p ); + + break; + } + } + + if ( next ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + + + /* if `char_code' is not in any group, then `mid' is */ + /* the group nearest to `char_code' */ + /* */ + + if ( char_code > end ) + { + mid++; + if ( mid == num_groups ) + return 0; + } + + cmap13->valid = 1; + cmap13->cur_charcode = char_code; + cmap13->cur_group = mid; + + if ( !gindex ) + { + tt_cmap13_next( cmap13 ); + + if ( cmap13->valid ) + gindex = cmap13->cur_gindex; + } + else + cmap13->cur_gindex = gindex; + + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap13_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap13_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + FT_UInt gindex; + + + if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) + return 0; + + /* no need to search */ + if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) + { + tt_cmap13_next( cmap13 ); + if ( cmap13->valid ) + { + gindex = cmap13->cur_gindex; + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + else + gindex = 0; + } + else + gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); + + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 13; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return SFNT_Err_Ok; + } + + + 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, + + NULL, NULL, NULL, NULL, NULL + , + 13, + (TT_CMap_ValidateFunc) tt_cmap13_validate, + (TT_CMap_Info_GetFunc) tt_cmap13_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_13 */ + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -2363,7 +2664,7 @@ * cmap 14 query functions. The data is overwritten * on each call to these functions. */ - FT_UInt max_results; + FT_UInt32 max_results; FT_UInt32* results; FT_Memory memory; @@ -2384,10 +2685,10 @@ static FT_Error tt_cmap14_ensure( TT_CMap14 cmap, - FT_UInt num_results, + FT_UInt32 num_results, FT_Memory memory ) { - FT_UInt old_max = cmap->max_results; + FT_UInt32 old_max = cmap->max_results; FT_Error error = 0; @@ -2429,7 +2730,8 @@ FT_ULong num_selectors = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 10 + 11 * num_selectors ) + if ( length > (FT_ULong)( valid->limit - table ) || + length < 10 + 11 * num_selectors ) FT_INVALID_TOO_SHORT; /* check selectors, they must be in increasing order */ @@ -2491,7 +2793,7 @@ FT_ULong i, lastUni = 0; - if ( ndp + numMappings * 4 > valid->limit ) + if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ) FT_INVALID_TOO_SHORT; for ( i = 0; i < numMappings; ++i ) @@ -2532,7 +2834,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap14_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -2550,7 +2852,7 @@ { FT_UNUSED( cmap ); - cmap_info->format = 14; + cmap_info->format = 14; /* subtable 14 does not define a language field */ cmap_info->language = 0xFFFFFFFFUL; @@ -2610,7 +2912,7 @@ { FT_UInt32 mid = ( min + max ) >> 1; FT_Byte* p = base + 5 * mid; - FT_UInt32 uni = TT_NEXT_UINT24( p ); + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); if ( char_code < uni ) @@ -2659,10 +2961,10 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap14_char_var_index( TT_CMap cmap, - TT_CMap ucmap, - FT_ULong charcode, - FT_ULong variantSelector) + tt_cmap14_char_var_index( TT_CMap cmap, + TT_CMap ucmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector) { FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); FT_ULong defOff; @@ -2692,9 +2994,9 @@ FT_CALLBACK_DEF( FT_Int ) - tt_cmap14_char_var_isdefault( TT_CMap cmap, - FT_ULong charcode, - FT_ULong variantSelector ) + tt_cmap14_char_var_isdefault( TT_CMap cmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector ) { FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); FT_ULong defOff; @@ -2725,10 +3027,10 @@ FT_Memory memory ) { TT_CMap14 cmap14 = (TT_CMap14)cmap; - FT_UInt count = cmap14->num_selectors; + FT_UInt32 count = cmap14->num_selectors; FT_Byte* p = cmap->data + 10; FT_UInt32* result; - FT_UInt i; + FT_UInt32 i; if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) @@ -2737,7 +3039,7 @@ result = cmap14->results; for ( i = 0; i < count; ++i ) { - result[i] = TT_NEXT_UINT24( p ); + result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 8; } result[i] = 0; @@ -2749,10 +3051,10 @@ FT_CALLBACK_DEF( FT_UInt32 * ) tt_cmap14_char_variants( TT_CMap cmap, FT_Memory memory, - FT_ULong charCode ) + FT_UInt32 charCode ) { TT_CMap14 cmap14 = (TT_CMap14) cmap; - FT_UInt count = cmap14->num_selectors; + FT_UInt32 count = cmap14->num_selectors; FT_Byte* p = cmap->data + 10; FT_UInt32* q; @@ -2787,7 +3089,7 @@ static FT_UInt tt_cmap14_def_char_count( FT_Byte *p ) { - FT_UInt32 numRanges = TT_NEXT_ULONG( p ); + FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); FT_UInt tot = 0; @@ -2814,14 +3116,14 @@ cnt = tt_cmap14_def_char_count( p ); - numRanges = TT_NEXT_ULONG( p ); + numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) return NULL; for ( q = cmap14->results; numRanges > 0; --numRanges ) { - FT_UInt uni = TT_NEXT_UINT24( p ); + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); cnt = FT_NEXT_BYTE( p ) + 1; @@ -2849,7 +3151,7 @@ FT_UInt32 *ret; - numMappings = TT_NEXT_ULONG( p ); + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) return NULL; @@ -2857,7 +3159,7 @@ ret = cmap14->results; for ( i = 0; i < numMappings; ++i ) { - ret[i] = TT_NEXT_UINT24( p ); + ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; } ret[i] = 0; @@ -2869,7 +3171,7 @@ FT_CALLBACK_DEF( FT_UInt32 * ) tt_cmap14_variant_chars( TT_CMap cmap, FT_Memory memory, - FT_ULong variantSelector ) + FT_UInt32 variantSelector ) { FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); @@ -2911,9 +3213,9 @@ p = cmap->data + nondefOff; dp = cmap->data + defOff; - numMappings = TT_NEXT_ULONG( p ); + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); dcnt = tt_cmap14_def_char_count( dp ); - numRanges = TT_NEXT_ULONG( dp ); + numRanges = (FT_UInt32)TT_NEXT_ULONG( dp ); if ( numMappings == 0 ) return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, @@ -2926,10 +3228,10 @@ return NULL; ret = cmap14->results; - duni = TT_NEXT_UINT24( dp ); + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); dcnt = FT_NEXT_BYTE( dp ); di = 1; - nuni = TT_NEXT_UINT24( p ); + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; ni = 1; i = 0; @@ -2946,7 +3248,7 @@ if ( di > numRanges ) break; - duni = TT_NEXT_UINT24( dp ); + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); dcnt = FT_NEXT_BYTE( dp ); } else @@ -2959,7 +3261,7 @@ if ( ni > numMappings ) break; - nuni = TT_NEXT_UINT24( p ); + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; } } @@ -2972,7 +3274,7 @@ ret[i++] = nuni; while ( ni < numMappings ) { - ret[i++] = TT_NEXT_UINT24( p ); + ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; ++ni; } @@ -2987,7 +3289,7 @@ while ( di < numRanges ) { - duni = TT_NEXT_UINT24( dp ); + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); dcnt = FT_NEXT_BYTE( dp ); for ( k = 0; k <= dcnt; ++k ) @@ -3003,10 +3305,7 @@ } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap14_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap14_class_rec, sizeof ( TT_CMap14Rec ), (FT_CMap_InitFunc) tt_cmap14_init, @@ -3020,51 +3319,66 @@ (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 - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_14 */ +#ifndef FT_CONFIG_OPTION_PIC + static const TT_CMap_Class tt_cmap_classes[] = { -#ifdef TT_CONFIG_CMAP_FORMAT_0 - &tt_cmap0_class_rec, -#endif +#define TTCMAPCITEM(a) &a, +#include "ttcmapc.h" + NULL, + }; -#ifdef TT_CONFIG_CMAP_FORMAT_2 - &tt_cmap2_class_rec, -#endif +#else /*FT_CONFIG_OPTION_PIC*/ -#ifdef TT_CONFIG_CMAP_FORMAT_4 - &tt_cmap4_class_rec, -#endif + void FT_Destroy_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class* clazz) + { + FT_Memory memory = library->memory; + if ( clazz ) + FT_FREE( clazz ); + } -#ifdef TT_CONFIG_CMAP_FORMAT_6 - &tt_cmap6_class_rec, -#endif + 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; -#ifdef TT_CONFIG_CMAP_FORMAT_8 - &tt_cmap8_class_rec, -#endif +#define TTCMAPCITEM(a) i++; +#include "ttcmapc.h" -#ifdef TT_CONFIG_CMAP_FORMAT_10 - &tt_cmap10_class_rec, -#endif + /* 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 ) ) + return error; -#ifdef TT_CONFIG_CMAP_FORMAT_12 - &tt_cmap12_class_rec, -#endif + /* the location of the class instances follows the array of pointers */ + recs = (TT_CMap_ClassRec*) (((char*)clazz)+(sizeof(*clazz)*(i+1))); + i=0; -#ifdef TT_CONFIG_CMAP_FORMAT_14 - &tt_cmap14_class_rec, -#endif +#undef TTCMAPCITEM +#define TTCMAPCITEM(a) \ + FT_Init_Class_##a(&recs[i]); \ + clazz[i] = &recs[i]; \ + i++; +#include "ttcmapc.h" - NULL, - }; + clazz[i] = NULL; + + *output_class = clazz; + return FT_Err_Ok; + } + +#endif /*FT_CONFIG_OPTION_PIC*/ /* parse the `cmap' table and build the corresponding TT_CMap objects */ @@ -3077,6 +3391,8 @@ FT_Byte* limit = table + face->cmap_size; FT_UInt volatile num_cmaps; FT_Byte* volatile p = table; + FT_Library library = FT_FACE_LIBRARY(face); + FT_UNUSED(library); if ( p + 4 > limit ) @@ -3086,7 +3402,8 @@ if ( TT_NEXT_USHORT( p ) != 0 ) { p -= 2; - FT_ERROR(( "tt_face_build_cmaps: unsupported `cmap' table format = %d\n", + FT_ERROR(( "tt_face_build_cmaps:" + " unsupported `cmap' table format = %d\n", TT_PEEK_USHORT( p ) )); return SFNT_Err_Invalid_Table; } @@ -3109,7 +3426,7 @@ { FT_Byte* volatile cmap = table + offset; volatile FT_UInt format = TT_PEEK_USHORT( cmap ); - const TT_CMap_Class* volatile pclazz = tt_cmap_classes; + const TT_CMap_Class* volatile pclazz = FT_TT_CMAP_CLASSES_GET; TT_CMap_Class volatile clazz; @@ -3153,8 +3470,8 @@ } else { - FT_ERROR(( "tt_face_build_cmaps:" )); - FT_ERROR(( " broken cmap sub-table ignored!\n" )); + FT_TRACE0(( "tt_face_build_cmaps:" + " broken cmap sub-table ignored\n" )); } break; } @@ -3162,8 +3479,8 @@ if ( *pclazz == NULL ) { - FT_ERROR(( "tt_face_build_cmaps:" )); - FT_ERROR(( " unsupported cmap sub-table ignored!\n" )); + FT_TRACE0(( "tt_face_build_cmaps:" + " unsupported cmap sub-table ignored\n" )); } } } diff --git a/src/sfnt/ttcmap.h b/src/sfnt/ttcmap.h index a10a3e2..15a4a21 100644 --- a/src/sfnt/ttcmap.h +++ b/src/sfnt/ttcmap.h @@ -55,6 +55,46 @@ 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_ \ + }; + +#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_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ typedef struct TT_ValidatorRec_ { diff --git a/src/sfnt/ttcmapc.h b/src/sfnt/ttcmapc.h new file mode 100644 index 0000000..4c9c6a5 --- /dev/null +++ b/src/sfnt/ttcmapc.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* ttcmapc.h */ +/* */ +/* TT CMAP classes definitions (specification only). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifdef TT_CONFIG_CMAP_FORMAT_0 + TTCMAPCITEM(tt_cmap0_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_2 + TTCMAPCITEM(tt_cmap2_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_4 + TTCMAPCITEM(tt_cmap4_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_6 + TTCMAPCITEM(tt_cmap6_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_8 + TTCMAPCITEM(tt_cmap8_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_10 + TTCMAPCITEM(tt_cmap10_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_12 + TTCMAPCITEM(tt_cmap12_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + TTCMAPCITEM(tt_cmap13_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_14 + TTCMAPCITEM(tt_cmap14_class_rec) +#endif + + /* END */ diff --git a/src/sfnt/ttkern.c b/src/sfnt/ttkern.c index 67d5115..c154080 100644 --- a/src/sfnt/ttkern.c +++ b/src/sfnt/ttkern.c @@ -22,7 +22,6 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include "ttkern.h" -#include "ttload.h" #include "sferrors.h" @@ -60,14 +59,16 @@ if ( table_size < 4 ) /* the case of a malformed table */ { - FT_ERROR(( "kerning table is too small - ignored\n" )); + FT_ERROR(( "tt_face_load_kern:" + " kerning table is too small - ignored\n" )); error = SFNT_Err_Table_Missing; goto Exit; } if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) ) { - FT_ERROR(( "could not extract kerning table\n" )); + FT_ERROR(( "tt_face_load_kern:" + " could not extract kerning table\n" )); goto Exit; } @@ -86,7 +87,7 @@ { FT_UInt num_pairs, length, coverage; FT_Byte* p_next; - FT_UInt32 mask = 1UL << nn; + FT_UInt32 mask = (FT_UInt32)1UL << nn; if ( p + 6 > p_limit ) @@ -125,8 +126,8 @@ */ if ( num_pairs > 0 ) { - FT_UInt count; - FT_UInt old_pair; + FT_ULong count; + FT_ULong old_pair; old_pair = FT_NEXT_ULONG( p ); diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c index c45a1ed..3ad33bd 100644 --- a/src/sfnt/ttload.c +++ b/src/sfnt/ttload.c @@ -5,7 +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 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 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, */ @@ -91,9 +91,9 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( zero_length ) - FT_TRACE4(( "ignoring empty table!\n" )); + FT_TRACE4(( "ignoring empty table\n" )); else - FT_TRACE4(( "could not find table!\n" )); + FT_TRACE4(( "could not find table\n" )); #endif return NULL; @@ -168,10 +168,10 @@ check_table_dir( SFNT_Header sfnt, FT_Stream stream ) { - FT_Error error; - FT_UInt nn, valid_entries = 0; - FT_UInt has_head = 0, has_sing = 0, has_meta = 0; - FT_ULong offset = sfnt->offset + 12; + FT_Error error; + FT_UShort nn, valid_entries = 0; + FT_UInt has_head = 0, has_sing = 0, has_meta = 0; + FT_ULong offset = sfnt->offset + 12; static const FT_Frame_Field table_dir_entry_fields[] = { @@ -364,7 +364,8 @@ error = check_table_dir( &sfnt, stream ); if ( error ) { - FT_TRACE2(( "tt_face_load_font_dir: invalid table directory for TrueType!\n" )); + FT_TRACE2(( "tt_face_load_font_dir:" + " invalid table directory for TrueType\n" )); goto Exit; } @@ -685,8 +686,10 @@ /* we add 4 phantom points later */ if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) { - FT_ERROR(( "Too much twilight points in `maxp' table;\n" )); - FT_ERROR(( " some glyphs might be rendered incorrectly.\n" )); + FT_TRACE0(( "tt_face_load_maxp:" + " too much twilight points in `maxp' table;\n" + " " + " some glyphs might be rendered incorrectly\n" )); maxProfile->maxTwilightPoints = 0xFFFFU - 4; } @@ -779,7 +782,7 @@ if ( storage_start > storage_limit ) { - FT_ERROR(( "invalid `name' table\n" )); + FT_ERROR(( "tt_face_load_name: invalid `name' table\n" )); error = SFNT_Err_Name_Table_Missing; goto Exit; } diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c index 2a7d22c..53e6ac7 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, 2007, 2008 by */ +/* Copyright 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, */ @@ -161,7 +161,9 @@ if ( num_shorts < 0 ) { - FT_ERROR(( "%cmtx has more metrics than glyphs.\n" )); + 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 diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c index ce628e2..aa0bf1e 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 by */ +/* Copyright 1996-2001, 2002, 2003, 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, */ @@ -29,7 +29,6 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include "ttpost.h" -#include "ttload.h" #include "sferrors.h" diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c index eadaade..833bb2a 100644 --- a/src/sfnt/ttsbit.c +++ b/src/sfnt/ttsbit.c @@ -494,7 +494,7 @@ if ( version != 0x00020000L || num_strikes >= 0x10000L ) { - FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version!\n" )); + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); error = SFNT_Err_Invalid_File_Format; goto Exit; diff --git a/src/sfnt/ttsbit0.c b/src/sfnt/ttsbit0.c index 3ebcbbd..38bcf21 100644 --- a/src/sfnt/ttsbit0.c +++ b/src/sfnt/ttsbit0.c @@ -62,7 +62,7 @@ if ( table_size < 8 ) { - FT_ERROR(( "tt_face_load_sbit_strikes: table too short!\n" )); + FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); error = SFNT_Err_Invalid_File_Format; goto Exit; } @@ -80,7 +80,7 @@ if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) { - FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version!\n" )); + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); error = SFNT_Err_Invalid_File_Format; goto Fail; } @@ -469,6 +469,41 @@ } + /* + * 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, @@ -514,6 +549,8 @@ } /* 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; @@ -524,21 +561,23 @@ for ( h = height; h > 0; h--, line += pitch ) { FT_Byte* write = line; - FT_Int w = width; + 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; + rval = *p++; + nbits = x_pos; } else if ( nbits < w ) { - rval |= *p++; + if ( p < limit ) + rval |= *p++; nbits += 8 - w; } else @@ -554,6 +593,7 @@ w = width - w; } + /* handle medial bytes */ for ( ; w >= 8; w -= 8 ) { rval |= *p++; @@ -562,11 +602,13 @@ rval <<= 8; } + /* handle final byte if necessary */ if ( w > 0 ) { if ( nbits < w ) { - rval |= *p++; + if ( p < limit ) + rval |= *p++; *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); nbits += 8 - w; diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c index 10fa2ae..846e454 100644 --- a/src/smooth/ftgrays.c +++ b/src/smooth/ftgrays.c @@ -4,7 +4,7 @@ /* */ /* A new `perfect' anti-aliasing renderer (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007, 2008 by */ +/* Copyright 2000-2001, 2002, 2003, 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, */ @@ -170,6 +170,34 @@ #endif /* !FT_DEBUG_LEVEL_TRACE */ +#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_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 /* !_STANDALONE_ */ @@ -181,6 +209,8 @@ #include "ftsmerrs.h" +#include "ftspic.h" + #define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph #define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline #define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory @@ -188,7 +218,6 @@ #endif /* !_STANDALONE_ */ - #ifndef FT_MEM_SET #define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) #endif @@ -201,27 +230,19 @@ #ifndef FT_STATIC_RASTER - #define RAS_ARG PWorker worker #define RAS_ARG_ PWorker worker, #define RAS_VAR worker #define RAS_VAR_ worker, -#define ras (*worker) - - #else /* FT_STATIC_RASTER */ - #define RAS_ARG /* empty */ #define RAS_ARG_ /* empty */ #define RAS_VAR /* empty */ #define RAS_VAR_ /* empty */ - static TWorker ras; - - #endif /* FT_STATIC_RASTER */ @@ -254,7 +275,7 @@ /* need to define them to "float" or "double" when experimenting with */ /* new algorithms */ - typedef int TCoord; /* integer scanline/pixel coordinate */ + typedef long TCoord; /* integer scanline/pixel coordinate */ typedef long TPos; /* sub-pixel coordinate */ /* determine the type used to store cell areas. This normally takes at */ @@ -285,8 +306,8 @@ typedef struct TCell_ { - int x; - int cover; + TPos x; /* same with TWorker.ex */ + TCoord cover; /* same with TWorker.cover */ TArea area; PCell next; @@ -301,12 +322,12 @@ TPos count_ex, count_ey; TArea area; - int cover; + TCoord cover; int invalid; PCell cells; - int max_cells; - int num_cells; + FT_PtrDist max_cells; + FT_PtrDist num_cells; TCoord cx, cy; TPos x, y; @@ -338,11 +359,18 @@ long buffer_size; PCell* ycells; - int ycount; + TPos ycount; } TWorker, *PWorker; +#ifndef FT_STATIC_RASTER +#define ras (*worker) +#else + static TWorker ras; +#endif + + typedef struct TRaster_ { void* buffer; @@ -428,7 +456,7 @@ gray_find_cell( RAS_ARG ) { PCell *pcell, cell; - int x = ras.ex; + TPos x = ras.ex; if ( x > ras.count_ex ) @@ -560,9 +588,9 @@ TPos x2, TCoord y2 ) { - TCoord ex1, ex2, fx1, fx2, delta; + TCoord ex1, ex2, fx1, fx2, delta, mod, lift, rem; long p, first, dx; - int incr, lift, mod, rem; + int incr; dx = x2 - x1; @@ -584,7 +612,7 @@ if ( ex1 == ex2 ) { delta = y2 - y1; - ras.area += (TArea)( fx1 + fx2 ) * delta; + ras.area += (TArea)(( fx1 + fx2 ) * delta); ras.cover += delta; return; } @@ -612,7 +640,7 @@ mod += (TCoord)dx; } - ras.area += (TArea)( fx1 + first ) * delta; + ras.area += (TArea)(( fx1 + first ) * delta); ras.cover += delta; ex1 += incr; @@ -642,7 +670,7 @@ delta++; } - ras.area += (TArea)ONE_PIXEL * delta; + ras.area += (TArea)(ONE_PIXEL * delta); ras.cover += delta; y1 += delta; ex1 += incr; @@ -651,7 +679,7 @@ } delta = y2 - y1; - ras.area += (TArea)( fx2 + ONE_PIXEL - first ) * delta; + ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta); ras.cover += delta; } @@ -664,10 +692,10 @@ gray_render_line( RAS_ARG_ TPos to_x, TPos to_y ) { - TCoord ey1, ey2, fy1, fy2; + TCoord ey1, ey2, fy1, fy2, mod; TPos dx, dy, x, x2; long p, first; - int delta, rem, mod, lift, incr; + int delta, rem, lift, incr; ey1 = TRUNC( ras.last_ey ); @@ -711,7 +739,7 @@ { TCoord ex = TRUNC( ras.x ); TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 ); - TPos area; + TArea area; first = ONE_PIXEL; @@ -726,7 +754,7 @@ ras.cover += delta; ey1 += incr; - gray_set_cell( &ras, ex, ey1 ); + gray_set_cell( RAS_VAR_ ex, ey1 ); delta = (int)( first + first - ONE_PIXEL ); area = (TArea)two_fx * delta; @@ -736,7 +764,7 @@ ras.cover += delta; ey1 += incr; - gray_set_cell( &ras, ex, ey1 ); + gray_set_cell( RAS_VAR_ ex, ey1 ); } delta = (int)( fy2 - ONE_PIXEL + first ); @@ -1104,13 +1132,13 @@ /* record current cell, if any */ - gray_record_cell( worker ); + gray_record_cell( RAS_VAR ); /* start to a new position */ x = UPSCALE( to->x ); y = UPSCALE( to->y ); - gray_start_cell( worker, TRUNC( x ), TRUNC( y ) ); + gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); worker->x = x; worker->y = y; @@ -1122,7 +1150,7 @@ gray_line_to( const FT_Vector* to, PWorker worker ) { - gray_render_line( worker, UPSCALE( to->x ), UPSCALE( to->y ) ); + gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) ); return 0; } @@ -1132,7 +1160,7 @@ const FT_Vector* to, PWorker worker ) { - gray_render_conic( worker, control, to ); + gray_render_conic( RAS_VAR_ control, to ); return 0; } @@ -1143,7 +1171,7 @@ const FT_Vector* to, PWorker worker ) { - gray_render_cubic( worker, control1, control2, to ); + gray_render_cubic( RAS_VAR_ control1, control2, to ); return 0; } @@ -1203,7 +1231,7 @@ gray_hline( RAS_ARG_ TCoord x, TCoord y, TPos area, - int acount ) + TCoord acount ) { FT_Span* span; int count; @@ -1243,6 +1271,10 @@ if ( x >= 32767 ) x = 32767; + /* FT_Span.y is an integer, so limit our coordinates appropriately */ + if ( y >= FT_INT_MAX ) + y = FT_INT_MAX; + if ( coverage ) { /* see whether we can add this span to the current list */ @@ -1281,7 +1313,7 @@ #endif /* FT_DEBUG_LEVEL_TRACE */ ras.num_gray_spans = 0; - ras.span_y = y; + ras.span_y = (int)y; count = 0; span = ras.gray_spans; @@ -1317,7 +1349,7 @@ printf( "%3d:", yindex ); for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) - printf( " (%3d, c:%4d, a:%6d)", cell->x, cell->cover, cell->area ); + printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area ); printf( "\n" ); } } @@ -1349,7 +1381,7 @@ for ( ; cell != NULL; cell = cell->next ) { - TArea area; + TPos area; if ( cell->x > x && cover != 0 ) @@ -1666,23 +1698,25 @@ } TBand; - - static int - gray_convert_glyph_inner( RAS_ARG ) - { - static - const FT_Outline_Funcs func_interface = - { + FT_DEFINE_OUTLINE_FUNCS(func_interface, (FT_Outline_MoveTo_Func) gray_move_to, (FT_Outline_LineTo_Func) gray_line_to, (FT_Outline_ConicTo_Func)gray_conic_to, (FT_Outline_CubicTo_Func)gray_cubic_to, 0, 0 - }; + ) + + static int + gray_convert_glyph_inner( RAS_ARG ) + { volatile int error = 0; +#ifdef FT_CONFIG_OPTION_PIC + FT_Outline_Funcs func_interface; + Init_Class_func_interface(&func_interface); +#endif if ( ft_setjmp( ras.jump_buffer ) == 0 ) { @@ -1829,7 +1863,7 @@ if ( middle == bottom ) { #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE7(( "gray_convert_glyph: Rotten glyph!\n" )); + FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); #endif return 1; } @@ -1917,7 +1951,7 @@ ras.clip_box.yMax = 32767L; } - gray_init_cells( worker, raster->buffer, raster->buffer_size ); + gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size ); ras.outline = *outline; ras.num_cells = 0; @@ -1937,7 +1971,7 @@ ras.render_span_data = &ras; } - return gray_convert_glyph( worker ); + return gray_convert_glyph( RAS_VAR ); } @@ -2037,8 +2071,7 @@ } - const FT_Raster_Funcs ft_grays_raster = - { + FT_DEFINE_RASTER_FUNCS(ft_grays_raster, FT_GLYPH_FORMAT_OUTLINE, (FT_Raster_New_Func) gray_raster_new, @@ -2046,7 +2079,7 @@ (FT_Raster_Set_Mode_Func)0, (FT_Raster_Render_Func) gray_raster_render, (FT_Raster_Done_Func) gray_raster_done - }; + ) /* END */ diff --git a/src/smooth/ftgrays.h b/src/smooth/ftgrays.h index 2d40954..f20f55f 100644 --- a/src/smooth/ftgrays.h +++ b/src/smooth/ftgrays.h @@ -28,6 +28,7 @@ #include "ftimage.h" #else #include +#include FT_CONFIG_CONFIG_H /* for FT_CONFIG_OPTION_PIC */ #include FT_IMAGE_H #endif diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c index a6db504..eed6353 100644 --- a/src/smooth/ftsmooth.c +++ b/src/smooth/ftsmooth.c @@ -17,10 +17,12 @@ #include +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H #include FT_OUTLINE_H #include "ftsmooth.h" #include "ftgrays.h" +#include "ftspic.h" #include "ftsmerrs.h" @@ -153,7 +155,7 @@ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } - /* allocate new one, depends on pixel format */ + /* allocate new one */ pitch = width; if ( hmul ) { @@ -192,6 +194,19 @@ } } +#endif + +#if FT_UINT_MAX > 0xFFFFU + + /* Required check is ( pitch * height < FT_ULONG_MAX ), */ + /* but we care realistic cases only. Always pitch <= width. */ + if ( width > 0xFFFFU || height > 0xFFFFU ) + { + FT_ERROR(( "ft_smooth_render_generic: glyph too large: %d x %d\n", + width, height )); + return Smooth_Err_Raster_Overflow; + } + #endif bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; @@ -310,12 +325,19 @@ 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 ) goto Exit; slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = x_left; - slot->bitmap_top = y_top; + slot->bitmap_left = (FT_Int)x_left; + slot->bitmap_top = (FT_Int)y_top; Exit: if ( outline && origin ) @@ -376,10 +398,8 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_smooth_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_smooth_renderer_class, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -392,7 +412,7 @@ (FT_Module_Constructor)ft_smooth_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -401,14 +421,12 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - (FT_Raster_Funcs*) &ft_grays_raster - }; + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_smooth_lcd_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_smooth_lcd_renderer_class, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -421,7 +439,7 @@ (FT_Module_Constructor)ft_smooth_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -430,15 +448,11 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - (FT_Raster_Funcs*) &ft_grays_raster - }; + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) + FT_DEFINE_RENDERER(ft_smooth_lcdv_renderer_class, - - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_smooth_lcdv_renderer_class = - { - { FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -451,7 +465,7 @@ (FT_Module_Constructor)ft_smooth_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -460,8 +474,8 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - (FT_Raster_Funcs*) &ft_grays_raster - }; + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) /* END */ diff --git a/src/smooth/ftsmooth.h b/src/smooth/ftsmooth.h index 62cced4..3708790 100644 --- a/src/smooth/ftsmooth.h +++ b/src/smooth/ftsmooth.h @@ -28,15 +28,15 @@ FT_BEGIN_HEADER #ifndef FT_CONFIG_OPTION_NO_STD_RASTER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_std_renderer_class; + FT_DECLARE_RENDERER( ft_std_renderer_class ) #endif #ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_renderer_class; + FT_DECLARE_RENDERER( ft_smooth_renderer_class ) - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_lcd_renderer_class; + FT_DECLARE_RENDERER( ft_smooth_lcd_renderer_class ) - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_lcd_v_renderer_class; + FT_DECLARE_RENDERER( ft_smooth_lcd_v_renderer_class ) #endif diff --git a/src/smooth/ftspic.c b/src/smooth/ftspic.c new file mode 100644 index 0000000..aa547fc --- /dev/null +++ b/src/smooth/ftspic.c @@ -0,0 +1,97 @@ +/***************************************************************************/ +/* */ +/* ftspic.c */ +/* */ +/* The FreeType position independent code services for smooth module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "ftspic.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*); + + void + ft_smooth_renderer_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->smooth ) + { + SmoothPIC* container = (SmoothPIC*)pic_container->smooth; + if(--container->ref_count) + return; + FT_FREE( container ); + pic_container->smooth = NULL; + } + } + + + FT_Error + ft_smooth_renderer_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + SmoothPIC* container; + FT_Memory memory = library->memory; + + /* since this function also serve smooth_lcd and smooth_lcdv renderers, + it implements reference counting */ + if(pic_container->smooth) + { + ((SmoothPIC*)pic_container->smooth)->ref_count++; + return error; + } + + /* allocate pointer, clear and set global container pointer */ + 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 */ + 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) + { + return ft_smooth_renderer_class_pic_init(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) + { + return ft_smooth_renderer_class_pic_init(library); + } + void ft_smooth_lcdv_renderer_class_pic_free(FT_Library library) + { + ft_smooth_renderer_class_pic_free(library); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/src/smooth/ftspic.h b/src/smooth/ftspic.h new file mode 100644 index 0000000..c7e0ce9 --- /dev/null +++ b/src/smooth/ftspic.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* ftspic.h */ +/* */ +/* The FreeType position independent code services for smooth module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __FTSPIC_H__ +#define __FTSPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_GRAYS_RASTER_GET ft_grays_raster + +#else /* FT_CONFIG_OPTION_PIC */ + + typedef struct SmoothPIC_ + { + 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) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __FTSPIC_H__ */ + + +/* END */ diff --git a/src/smooth/smooth.c b/src/smooth/smooth.c index ff6be3e..a8ac51f 100644 --- a/src/smooth/smooth.c +++ b/src/smooth/smooth.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include +#include "ftspic.c" #include "ftgrays.c" #include "ftsmooth.c" diff --git a/src/truetype/truetype.c b/src/truetype/truetype.c index b36473a..4bd1209 100644 --- a/src/truetype/truetype.c +++ b/src/truetype/truetype.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include +#include "ttpic.c" #include "ttdriver.c" /* driver interface */ #include "ttpload.c" /* tables loader */ #include "ttgload.c" /* glyph loader */ diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index 42feb05..d723b57 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -4,7 +4,8 @@ /* */ /* TrueType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +21,6 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_IDS_H #include FT_SERVICE_XFREE86_NAME_H #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -41,6 +41,7 @@ #include "tterrors.h" +#include "ttpic.h" /*************************************************************************/ /* */ @@ -298,7 +299,15 @@ if ( !size ) return TT_Err_Invalid_Size_Handle; - if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) + if ( !face ) + return TT_Err_Invalid_Argument; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( glyph_index >= (FT_UInt)face->num_glyphs && + !face->internal->incremental_interface ) +#else + if ( glyph_index >= (FT_UInt)face->num_glyphs ) +#endif return TT_Err_Invalid_Argument; if ( load_flags & FT_LOAD_NO_HINTING ) @@ -344,14 +353,13 @@ /*************************************************************************/ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - static const FT_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 - }; + ) #endif static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = @@ -371,22 +379,24 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ }; - static const FT_Service_TTGlyfRec tt_service_truetype_glyf = - { + FT_DEFINE_SERVICE_TTGLYFREC(tt_service_truetype_glyf, (TT_Glyf_GetLocationFunc)tt_face_get_location - }; + ) - static const FT_ServiceDescRec tt_services[] = - { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE }, #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - { FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters }, + FT_DEFINE_SERVICEDESCREC4(tt_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_MULTI_MASTERS, &FT_TT_SERVICE_GX_MULTI_MASTERS_GET, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET + ) +#else + FT_DEFINE_SERVICEDESCREC3(tt_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET + ) #endif - { FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine }, - { FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf }, - { NULL, NULL } - }; - FT_CALLBACK_DEF( FT_Module_Interface ) tt_get_interface( FT_Module driver, /* TT_Driver */ @@ -396,11 +406,13 @@ FT_Module sfntd; SFNT_Service sfnt; - - result = ft_service_list_lookup( tt_services, tt_interface ); + result = ft_service_list_lookup( FT_TT_SERVICES_GET, tt_interface ); if ( result != NULL ) return result; + if ( !driver ) + return NULL; + /* only return the default interface from the SFNT module */ sfntd = FT_Get_Module( driver->library, "sfnt" ); if ( sfntd ) @@ -416,18 +428,25 @@ /* The FT_DriverInterface structure is defined in ftdriver.h. */ - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec tt_driver_class = - { - { - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE | #ifdef TT_USE_BYTECODE_INTERPRETER - FT_MODULE_DRIVER_HAS_HINTER, +#define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER +#else +#define TT_HINTER_FLAG 0 +#endif + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define TT_SIZE_SELECT tt_size_select #else - 0, +#define TT_SIZE_SELECT 0 #endif + FT_DEFINE_DRIVER(tt_driver_class, + + + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + TT_HINTER_FLAG, + sizeof ( TT_DriverRec ), "truetype", /* driver name */ @@ -439,7 +458,6 @@ tt_driver_init, tt_driver_done, tt_get_interface, - }, sizeof ( TT_FaceRec ), sizeof ( TT_SizeRec ), @@ -452,10 +470,9 @@ tt_slot_init, 0, /* FT_Slot_DoneFunc */ -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - ft_stub_set_char_sizes, - ft_stub_set_pixel_sizes, -#endif + ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + Load_Glyph, tt_get_kerning, @@ -463,12 +480,8 @@ tt_get_advances, tt_size_request, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - tt_size_select -#else - 0 /* FT_Size_SelectFunc */ -#endif - }; + TT_SIZE_SELECT + ) /* END */ diff --git a/src/truetype/ttdriver.h b/src/truetype/ttdriver.h index f6f26e4..aae00f2 100644 --- a/src/truetype/ttdriver.h +++ b/src/truetype/ttdriver.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Driver_ClassRec ) tt_driver_class; + FT_DECLARE_DRIVER( tt_driver_class ) FT_END_HEADER diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 06e9ccd..57ea0ba 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -4,7 +4,8 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -69,7 +70,7 @@ /* `check' is true, take care of monospaced fonts by returning the */ /* advance width maximum. */ /* */ - FT_LOCAL_DEF(void) + FT_LOCAL_DEF( void ) TT_Get_HMetrics( TT_Face face, FT_UInt idx, FT_Bool check, @@ -80,6 +81,9 @@ if ( check && face->postscript.isFixedPitch ) *aw = face->horizontal.advance_Width_Max; + + FT_TRACE5(( " advance width (font units): %d\n", *aw )); + FT_TRACE5(( " left side bearing (font units): %d\n", *lsb )); } @@ -96,7 +100,7 @@ /* The monospace `check' is probably not meaningful here, but we leave */ /* it in for a consistent interface. */ /* */ - FT_LOCAL_DEF(void) + FT_LOCAL_DEF( void ) TT_Get_VMetrics( TT_Face face, FT_UInt idx, FT_Bool check, @@ -131,6 +135,91 @@ #endif + FT_TRACE5(( " advance height (font units): %d\n", *ah )); + FT_TRACE5(( " top side bearing (font units): %d\n", *tsb )); + } + + + static void + tt_get_metrics( TT_Loader loader, + FT_UInt glyph_index ) + { + TT_Face face = (TT_Face)loader->face; + + FT_Short left_bearing = 0, top_bearing = 0; + FT_UShort advance_width = 0, advance_height = 0; + + + TT_Get_HMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &left_bearing, + &advance_width ); + TT_Get_VMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &top_bearing, + &advance_height ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* If this is an incrementally loaded font check whether there are */ + /* overriding metrics for this glyph. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + FT_Error error; + + + metrics.bearing_x = left_bearing; + metrics.bearing_y = 0; + metrics.advance = advance_width; + metrics.advance_v = 0; + + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, FALSE, &metrics ); + if ( error ) + goto Exit; + + left_bearing = (FT_Short)metrics.bearing_x; + advance_width = (FT_UShort)metrics.advance; + +#if 0 + + /* GWW: Do I do the same for vertical metrics? */ + metrics.bearing_x = 0; + metrics.bearing_y = top_bearing; + metrics.advance = advance_height; + + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, TRUE, &metrics ); + if ( error ) + goto Exit; + + top_bearing = (FT_Short)metrics.bearing_y; + advance_height = (FT_UShort)metrics.advance; + +#endif /* 0 */ + + } + + Exit: + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + loader->left_bearing = left_bearing; + loader->advance = advance_width; + loader->top_bearing = top_bearing; + loader->vadvance = advance_height; + + if ( !loader->linear_def ) + { + loader->linear_def = 1; + loader->linear = advance_width; + } } @@ -317,7 +406,7 @@ if ( n_ins > face->max_profile.maxSizeOfInstructions ) { - FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions (%d)\n", + FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n", n_ins )); error = TT_Err_Too_Many_Hints; goto Fail; @@ -325,7 +414,7 @@ if ( ( limit - p ) < n_ins ) { - FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" )); + FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); error = TT_Err_Too_Many_Hints; goto Fail; } @@ -633,7 +722,13 @@ #ifdef TT_USE_BYTECODE_INTERPRETER - n_ins = loader->glyph->control_len; + if ( loader->glyph->control_len > 0xFFFFL ) + { + FT_TRACE1(( "TT_Hint_Glyph: too long instructions " )); + FT_TRACE1(( "(0x%lx byte) is truncated\n", + loader->glyph->control_len )); + } + n_ins = (FT_UInt)( loader->glyph->control_len ); #endif origin = zone->cur[zone->n_points - 4].x; @@ -680,6 +775,9 @@ FT_Bool debug; FT_Error error; + FT_GlyphLoader gloader = loader->gloader; + FT_Outline current_outline = gloader->current.outline; + error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph, loader->exec->glyphIns, n_ins ); @@ -695,6 +793,10 @@ error = TT_Run_Context( loader->exec, debug ); if ( error && loader->exec->pedantic_hinting ) return error; + + /* store drop-out mode in bits 5-7; set bit 2 also as a marker */ + current_outline.tags[0] |= + ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE; } #endif @@ -929,15 +1031,15 @@ /* This algorithm is a guess and works much better than the above. */ /* */ FT_Fixed mac_xscale = FT_SqrtFixed( - FT_MulFix( subglyph->transform.xx, - subglyph->transform.xx ) + - FT_MulFix( subglyph->transform.xy, - subglyph->transform.xy ) ); + (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_MulFix( subglyph->transform.yy, - subglyph->transform.yy ) + - FT_MulFix( subglyph->transform.yx, - subglyph->transform.yx ) ); + (FT_Int32)FT_MulFix( subglyph->transform.yy, + subglyph->transform.yy ) + + (FT_Int32)FT_MulFix( subglyph->transform.yx, + subglyph->transform.yx ) ); x = FT_MulFix( x, mac_xscale ); @@ -1030,7 +1132,7 @@ /* check it */ if ( n_ins > ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions ) { - FT_TRACE0(( "TT_Process_Composite_Glyph: Too many instructions (%d)\n", + FT_TRACE0(( "TT_Process_Composite_Glyph: too many instructions (%d)\n", n_ins )); return TT_Err_Too_Many_Hints; @@ -1053,8 +1155,7 @@ /* Some points are likely touched during execution of */ /* instructions on components. So let's untouch them. */ for ( i = start_point; i < loader->zone.n_points; i++ ) - loader->zone.tags[i] &= ~( FT_CURVE_TAG_TOUCH_X | - FT_CURVE_TAG_TOUCH_Y ); + loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH; loader->zone.n_points += 4; @@ -1090,9 +1191,10 @@ static FT_Error load_truetype_glyph( TT_Loader loader, FT_UInt glyph_index, - FT_UInt recurse_count ) + FT_UInt recurse_count, + FT_Bool header_only ) { - FT_Error error; + FT_Error error = TT_Err_Ok; FT_Fixed x_scale, y_scale; FT_ULong offset; TT_Face face = (TT_Face)loader->face; @@ -1139,75 +1241,7 @@ y_scale = 0x10000L; } - /* get metrics, horizontal and vertical */ - { - FT_Short left_bearing = 0, top_bearing = 0; - FT_UShort advance_width = 0, advance_height = 0; - - - TT_Get_HMetrics( face, glyph_index, - (FT_Bool)!( loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), - &left_bearing, - &advance_width ); - TT_Get_VMetrics( face, glyph_index, - (FT_Bool)!( loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), - &top_bearing, - &advance_height ); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - /* If this is an incrementally loaded font see if there are */ - /* overriding metrics for this glyph. */ - if ( face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs->get_glyph_metrics ) - { - FT_Incremental_MetricsRec metrics; - - - metrics.bearing_x = left_bearing; - metrics.bearing_y = 0; - metrics.advance = advance_width; - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, FALSE, &metrics ); - if ( error ) - goto Exit; - left_bearing = (FT_Short)metrics.bearing_x; - advance_width = (FT_UShort)metrics.advance; - -#if 0 - - /* GWW: Do I do the same for vertical metrics? */ - metrics.bearing_x = 0; - metrics.bearing_y = top_bearing; - metrics.advance = advance_height; - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, TRUE, &metrics ); - if ( error ) - goto Exit; - top_bearing = (FT_Short)metrics.bearing_y; - advance_height = (FT_UShort)metrics.advance; - -#endif /* 0 */ - - } - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - loader->left_bearing = left_bearing; - loader->advance = advance_width; - loader->top_bearing = top_bearing; - loader->vadvance = advance_height; - - if ( !loader->linear_def ) - { - loader->linear_def = 1; - loader->linear = advance_width; - } - } + tt_get_metrics( loader, glyph_index ); /* Set `offset' to the start of the glyph relative to the start of */ /* the `glyf' table, and `byte_len' to the length of the glyph in */ @@ -1245,9 +1279,15 @@ if ( loader->byte_len > 0 ) { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* for the incremental interface, `glyf_offset' is always zero */ + if ( !loader->glyf_offset && + !face->root.internal->incremental_interface ) +#else if ( !loader->glyf_offset ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ { - FT_TRACE2(( "no `glyf' table but non-zero `loca' entry!\n" )); + FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); error = TT_Err_Invalid_Table; goto Exit; } @@ -1260,9 +1300,9 @@ opened_frame = 1; - /* read first glyph header */ + /* read glyph header first */ error = face->read_glyph_header( loader ); - if ( error ) + if ( error || header_only ) goto Exit; } @@ -1273,6 +1313,9 @@ loader->bbox.yMin = 0; loader->bbox.yMax = 0; + if ( header_only ) + goto Exit; + TT_LOADER_SET_PP( loader ); #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -1388,8 +1431,11 @@ { if ( subglyph->flags & ARGS_ARE_XY_VALUES ) { - subglyph->arg1 += deltas[i].x; - subglyph->arg2 += deltas[i].y; + /* XXX: overflow check for subglyph->{arg1,arg2}. */ + /* deltas[i].{x,y} must be within signed 16-bit, */ + /* but the restriction of summed delta is not clear */ + subglyph->arg1 += (FT_Int16)deltas[i].x; + subglyph->arg2 += (FT_Int16)deltas[i].y; } } @@ -1459,7 +1505,7 @@ num_base_points = gloader->base.outline.n_points; error = load_truetype_glyph( loader, subglyph->index, - recurse_count + 1 ); + recurse_count + 1, FALSE ); if ( error ) goto Exit; @@ -1579,17 +1625,35 @@ glyph->metrics.horiBearingY = bbox.yMax; glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - /* Now take care of vertical metrics. In the case where there is */ - /* no vertical information within the font (relatively common), make */ - /* up some metrics by `hand'... */ + /* adjust advance width to the value contained in the hdmx table */ + if ( !face->postscript.isFixedPitch && + IS_HINTED( loader->load_flags ) ) + { + FT_Byte* widthp; + + + widthp = tt_face_get_device_metrics( face, + size->root.metrics.x_ppem, + glyph_index ); + + if ( widthp ) + glyph->metrics.horiAdvance = *widthp << 6; + } + /* set glyph dimensions */ + glyph->metrics.width = bbox.xMax - bbox.xMin; + glyph->metrics.height = bbox.yMax - bbox.yMin; + + /* Now take care of vertical metrics. In the case where there is */ + /* no vertical information within the font (relatively common), */ + /* create some metrics manually */ { FT_Pos top; /* scaled vertical top side bearing */ FT_Pos advance; /* scaled vertical advance height */ /* Get the unscaled top bearing and advance height. */ - if ( face->vertical_info && + if ( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ) { top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax, @@ -1664,37 +1728,19 @@ /* scale the metrics */ if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) { - top = FT_MulFix( top, y_scale ); + top = FT_MulFix( top, y_scale ); advance = FT_MulFix( advance, y_scale ); } /* XXX: for now, we have no better algorithm for the lsb, but it */ /* should work fine. */ /* */ - glyph->metrics.vertBearingX = ( bbox.xMin - bbox.xMax ) / 2; + glyph->metrics.vertBearingX = glyph->metrics.horiBearingX - + glyph->metrics.horiAdvance / 2; glyph->metrics.vertBearingY = top; glyph->metrics.vertAdvance = advance; } - /* adjust advance width to the value contained in the hdmx table */ - if ( !face->postscript.isFixedPitch && - IS_HINTED( loader->load_flags ) ) - { - FT_Byte* widthp; - - - widthp = tt_face_get_device_metrics( face, - size->root.metrics.x_ppem, - glyph_index ); - - if ( widthp ) - glyph->metrics.horiAdvance = *widthp << 6; - } - - /* set glyph dimensions */ - glyph->metrics.width = bbox.xMax - bbox.xMin; - glyph->metrics.height = bbox.yMax - bbox.yMin; - return 0; } @@ -1742,6 +1788,7 @@ glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; glyph->format = FT_GLYPH_FORMAT_BITMAP; + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) { glyph->bitmap_left = metrics.vertBearingX; @@ -1764,7 +1811,8 @@ tt_loader_init( TT_Loader loader, TT_Size size, TT_GlyphSlot glyph, - FT_Int32 load_flags ) + FT_Int32 load_flags, + FT_Bool glyf_table_only ) { TT_Face face; FT_Stream stream; @@ -1778,7 +1826,7 @@ #ifdef TT_USE_BYTECODE_INTERPRETER /* load execution context */ - if ( IS_HINTED( load_flags ) ) + if ( IS_HINTED( load_flags ) && !glyf_table_only ) { TT_ExecContext exec; FT_Bool grayscale; @@ -1851,7 +1899,7 @@ loader->glyf_offset = 0; else if ( error ) { - FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" )); + FT_ERROR(( "tt_loader_init: could not access glyph table\n" )); return error; } else @@ -1859,6 +1907,7 @@ } /* get face's glyph loader */ + if ( !glyf_table_only ) { FT_GlyphLoader gloader = glyph->internal->loader; @@ -1930,7 +1979,25 @@ { error = load_sbit_image( size, glyph, glyph_index, load_flags ); if ( !error ) + { + FT_Face root = &face->root; + + + if ( FT_IS_SCALABLE( root ) ) + { + /* for the bbox we need the header only */ + (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); + (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); + glyph->linearHoriAdvance = loader.linear; + glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax - + loader.vadvance; + if ( face->postscript.isFixedPitch && + ( load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 ) + glyph->linearHoriAdvance = face->horizontal.advance_Width_Max; + } + return TT_Err_Ok; + } } #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ @@ -1942,7 +2009,7 @@ if ( load_flags & FT_LOAD_SBITS_ONLY ) return TT_Err_Invalid_Argument; - error = tt_loader_init( &loader, size, glyph, load_flags ); + error = tt_loader_init( &loader, size, glyph, load_flags, FALSE ); if ( error ) return error; @@ -1951,7 +2018,7 @@ glyph->outline.flags = 0; /* main loading loop */ - error = load_truetype_glyph( &loader, glyph_index, 0 ); + error = load_truetype_glyph( &loader, glyph_index, 0, FALSE ); if ( !error ) { if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE ) @@ -1998,7 +2065,7 @@ break; } } - else + else glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; } diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index 515e734..ef25aaf 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -4,7 +4,7 @@ /* */ /* TrueType GX Font Variation loader */ /* */ -/* Copyright 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,30 +16,31 @@ /***************************************************************************/ -/***************************************************************************/ -/* */ -/* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ -/* */ -/* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */ -/* */ -/* The documentation for `fvar' is inconsistent. At one point it says */ -/* that `countSizePairs' should be 3, at another point 2. It should be 2. */ -/* */ -/* The documentation for `gvar' is not intelligible; `cvar' refers you to */ -/* `gvar' and is thus also incomprehensible. */ -/* */ -/* The documentation for `avar' appears correct, but Apple has no fonts */ -/* with an `avar' table, so it is hard to test. */ -/* */ -/* Many thanks to John Jenkins (at Apple) in figuring this out. */ -/* */ -/* */ -/* Apple's `kern' table has some references to tuple indices, but as there */ -/* is no indication where these indices are defined, nor how to */ -/* interpolate the kerning values (different tuples have different */ -/* classes) this issue is ignored. */ -/* */ -/***************************************************************************/ + /*************************************************************************/ + /* */ + /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ + /* */ + /* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */ + /* */ + /* The documentation for `fvar' is inconsistent. At one point it says */ + /* that `countSizePairs' should be 3, at another point 2. It should */ + /* be 2. */ + /* */ + /* The documentation for `gvar' is not intelligible; `cvar' refers you */ + /* to `gvar' and is thus also incomprehensible. */ + /* */ + /* The documentation for `avar' appears correct, but Apple has no fonts */ + /* with an `avar' table, so it is hard to test. */ + /* */ + /* Many thanks to John Jenkins (at Apple) in figuring this out. */ + /* */ + /* */ + /* Apple's `kern' table has some references to tuple indices, but as */ + /* there is no indication where these indices are defined, nor how to */ + /* interpolate the kerning values (different tuples have different */ + /* classes) this issue is ignored. */ + /* */ + /*************************************************************************/ #include @@ -47,11 +48,9 @@ #include FT_CONFIG_CONFIG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_MULTIPLE_MASTERS_H -#include "ttdriver.h" #include "ttpload.h" #include "ttgxvar.h" @@ -95,11 +94,8 @@ #define ALL_POINTS (FT_UShort*)( -1 ) - enum - { - GX_PT_POINTS_ARE_WORDS = 0x80, - GX_PT_POINT_RUN_COUNT_MASK = 0x7F - }; +#define GX_PT_POINTS_ARE_WORDS 0x80 +#define GX_PT_POINT_RUN_COUNT_MASK 0x7F /*************************************************************************/ @@ -158,6 +154,9 @@ runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK; first = points[i++] = FT_GET_USHORT(); + if ( runcnt < 1 ) + goto Exit; + /* first point not included in runcount */ for ( j = 0; j < runcnt; ++j ) points[i++] = (FT_UShort)( first += FT_GET_USHORT() ); @@ -166,11 +165,15 @@ { first = points[i++] = FT_GET_BYTE(); + if ( runcnt < 1 ) + goto Exit; + for ( j = 0; j < runcnt; ++j ) points[i++] = (FT_UShort)( first += FT_GET_BYTE() ); } } + Exit: return points; } @@ -205,12 +208,12 @@ /* */ static FT_Short* ft_var_readpackeddeltas( FT_Stream stream, - FT_Int delta_cnt ) + FT_Offset delta_cnt ) { FT_Short *deltas; - FT_Int runcnt; - FT_Int i; - FT_Int j; + FT_UInt runcnt; + FT_Offset i; + FT_UInt j; FT_Memory memory = stream->memory; FT_Error error = TT_Err_Ok; @@ -1132,7 +1135,7 @@ if ( blend == NULL ) { - FT_TRACE2(( "no blend specified!\n" )); + FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); error = TT_Err_Ok; goto Exit; @@ -1140,7 +1143,7 @@ if ( face->cvt == NULL ) { - FT_TRACE2(( "no `cvt ' table!\n" )); + FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); error = TT_Err_Ok; goto Exit; @@ -1149,7 +1152,7 @@ error = face->goto_table( face, TTAG_cvar, stream, &table_len ); if ( error ) { - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); error = TT_Err_Ok; goto Exit; @@ -1164,7 +1167,7 @@ table_start = FT_Stream_FTell( stream ); if ( FT_GET_LONG() != 0x00010000L ) { - FT_TRACE2(( "bad table version!\n" )); + FT_TRACE2(( "bad table version\n" )); error = TT_Err_Ok; goto FExit; diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h index 706cb4d..82dfc44 100644 --- a/src/truetype/ttgxvar.h +++ b/src/truetype/ttgxvar.h @@ -84,7 +84,7 @@ FT_BEGIN_HEADER FT_Fixed* normalizedcoords; FT_MM_Var* mmvar; - FT_Int mmvar_len; + FT_Offset mmvar_len; FT_Bool avar_checked; GX_AVarSegment avar_segment; diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 2279a62..13aa9a2 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -791,9 +791,9 @@ /* allocate object */ if ( FT_NEW( exec ) ) - goto Exit; + goto Fail; - /* initialize it */ + /* initialize it; in case of error this deallocates `exec' too */ error = Init_Context( exec, memory ); if ( error ) goto Fail; @@ -802,13 +802,10 @@ driver->context = exec; } - Exit: return driver->context; Fail: - FT_FREE( exec ); - - return 0; + return NULL; } @@ -2197,7 +2194,7 @@ FT_ASSERT( !CUR.face->unpatented_hinting ); #endif - return TT_DotFix14( dx, dy, + return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, CUR.GS.projVector.x, CUR.GS.projVector.y ); } @@ -2223,7 +2220,7 @@ Dual_Project( EXEC_OP_ FT_Pos dx, FT_Pos dy ) { - return TT_DotFix14( dx, dy, + return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, CUR.GS.dualVector.x, CUR.GS.dualVector.y ); } @@ -4293,13 +4290,21 @@ CUR.numFDefs++; } + /* Although FDEF takes unsigned 32-bit integer, */ + /* func # must be within unsigned 16-bit integer */ + if ( n > 0xFFFFU ) + { + CUR.error = TT_Err_Too_Many_Function_Defs; + return; + } + rec->range = CUR.curRange; - rec->opc = n; + rec->opc = (FT_UInt16)n; rec->start = CUR.IP + 1; rec->active = TRUE; if ( n > CUR.maxFunc ) - CUR.maxFunc = n; + CUR.maxFunc = (FT_UInt16)n; /* Now skip the whole function definition. */ /* We don't allow nested IDEFS & FDEFs. */ @@ -4556,13 +4561,20 @@ CUR.numIDefs++; } - def->opc = args[0]; + /* opcode must be unsigned 8-bit integer */ + if ( 0 > args[0] || args[0] > 0x00FF ) + { + CUR.error = TT_Err_Too_Many_Instruction_Defs; + return; + } + + def->opc = (FT_Byte)args[0]; def->start = CUR.IP+1; def->range = CUR.curRange; def->active = TRUE; if ( (FT_ULong)args[0] > CUR.maxIns ) - CUR.maxIns = args[0]; + CUR.maxIns = (FT_Byte)args[0]; /* Now skip the whole function definition. */ /* We don't allow nested IDEFs & FDEFs. */ @@ -5530,20 +5542,20 @@ { if ( CUR.GS.both_x_axis ) { - dx = TT_MulFix14( args[0], 0x4000 ); + dx = TT_MulFix14( (FT_UInt32)args[0], 0x4000 ); dy = 0; } else { dx = 0; - dy = TT_MulFix14( args[0], 0x4000 ); + dy = TT_MulFix14( (FT_UInt32)args[0], 0x4000 ); } } else #endif { - dx = TT_MulFix14( args[0], CUR.GS.freeVector.x ); - dy = TT_MulFix14( args[0], CUR.GS.freeVector.y ); + dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x ); + dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y ); } while ( CUR.GS.loop > 0 ) @@ -5709,8 +5721,8 @@ if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ { - CUR.zp0.org[point].x = TT_MulFix14( distance, CUR.GS.freeVector.x ); - CUR.zp0.org[point].y = TT_MulFix14( distance, CUR.GS.freeVector.y ), + 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]; } @@ -5897,10 +5909,12 @@ if ( CUR.GS.gep1 == 0 ) { CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + - TT_MulFix14( cvt_dist, CUR.GS.freeVector.x ); + TT_MulFix14( (FT_UInt32)cvt_dist, + CUR.GS.freeVector.x ); CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + - TT_MulFix14( cvt_dist, CUR.GS.freeVector.y ); + TT_MulFix14( (FT_UInt32)cvt_dist, + CUR.GS.freeVector.y ); CUR.zp1.cur[point] = CUR.zp0.cur[point]; } diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 2649a67..11d662d 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -18,9 +18,7 @@ #include #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H #include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_SFNT_H @@ -150,7 +148,9 @@ static FT_Bool tt_check_trickyness( FT_String* name ) { - static const char* const trick_names[] = +#define TRICK_NAMES_MAX_CHARACTERS 16 +#define TRICK_NAMES_COUNT 7 + static const char trick_names[TRICK_NAMES_COUNT][TRICK_NAMES_MAX_CHARACTERS+1] = { "DFKaiSho-SB", /* dfkaisb.ttf */ "DFKaiShu", @@ -159,7 +159,6 @@ "MingLiU", /* mingliu.ttf & mingliu.ttc */ "PMingLiU", /* mingliu.ttc */ "MingLi43", /* mingli.ttf */ - NULL }; int nn; @@ -169,7 +168,7 @@ /* Note that we only check the face name at the moment; it might */ /* be worth to do more checks for a few special cases. */ - for ( nn = 0; trick_names[nn] != NULL; nn++ ) + for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ ) if ( ft_strstr( name, trick_names[nn] ) ) return TRUE; @@ -612,18 +611,15 @@ /* Set default metrics */ { - FT_Size_Metrics* metrics = &size->metrics; - TT_Size_Metrics* metrics2 = &size->ttmetrics; + TT_Size_Metrics* metrics = &size->ttmetrics; - metrics->x_ppem = 0; - metrics->y_ppem = 0; - metrics2->rotated = FALSE; - metrics2->stretched = FALSE; + metrics->rotated = FALSE; + metrics->stretched = FALSE; /* set default compensation (all 0) */ for ( i = 0; i < 4; i++ ) - metrics2->compensations[i] = 0; + metrics->compensations[i] = 0; } /* allocate function defs, instruction defs, cvt, and storage area */ diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h index d4b8228..30c8669 100644 --- a/src/truetype/ttobjs.h +++ b/src/truetype/ttobjs.h @@ -4,7 +4,7 @@ /* */ /* Objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 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, */ @@ -194,45 +194,13 @@ FT_BEGIN_HEADER } TT_Transform; - /*************************************************************************/ - /* */ - /* Subglyph loading record. Used to load composite components. */ - /* */ - typedef struct TT_SubglyphRec_ - { - FT_Long index; /* subglyph index; initialized with -1 */ - FT_Bool is_scaled; /* is the subglyph scaled? */ - FT_Bool is_hinted; /* should it be hinted? */ - FT_Bool preserve_pps; /* preserve phantom points? */ - - FT_Long file_offset; - - FT_BBox bbox; - FT_Pos left_bearing; - FT_Pos advance; - - TT_GlyphZoneRec zone; - - FT_Long arg1; /* first argument */ - FT_Long arg2; /* second argument */ - - FT_UShort element_flag; /* current load element flag */ - - TT_Transform transform; /* transformation matrix */ - - FT_Vector pp1, pp2; /* phantom points (horizontal) */ - FT_Vector pp3, pp4; /* phantom points (vertical) */ - - } TT_SubGlyphRec, *TT_SubGlyph_Stack; - - /*************************************************************************/ /* */ /* A note regarding non-squared pixels: */ /* */ /* (This text will probably go into some docs at some time; for now, it */ - /* is kept here to explain some definitions in the TIns_Metrics */ - /* record). */ + /* is kept here to explain some definitions in the TT_Size_Metrics */ + /* record). */ /* */ /* The CVT is a one-dimensional array containing values that control */ /* certain important characteristics in a font, like the height of all */ diff --git a/src/truetype/ttpic.c b/src/truetype/ttpic.c new file mode 100644 index 0000000..27ec4a1 --- /dev/null +++ b/src/truetype/ttpic.c @@ -0,0 +1,79 @@ +/***************************************************************************/ +/* */ +/* ttpic.c */ +/* */ +/* The FreeType position independent code services for truetype module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "ttpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ttdriver.c */ + FT_Error FT_Create_Class_tt_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_tt_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_tt_service_gx_multi_masters(FT_Service_MultiMastersRec*); + void FT_Init_Class_tt_service_truetype_glyf(FT_Service_TTGlyfRec*); + + void + tt_driver_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->truetype ) + { + TTModulePIC* container = (TTModulePIC*)pic_container->truetype; + if(container->tt_services) + FT_Destroy_Class_tt_services(library, container->tt_services); + container->tt_services = NULL; + FT_FREE( container ); + pic_container->truetype = NULL; + } + } + + FT_Error + tt_driver_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + TTModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + 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 */ + error = FT_Create_Class_tt_services(library, &container->tt_services); + if(error) + goto Exit; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Init_Class_tt_service_gx_multi_masters(&container->tt_service_gx_multi_masters); +#endif + FT_Init_Class_tt_service_truetype_glyf(&container->tt_service_truetype_glyf); +Exit: + if(error) + tt_driver_class_pic_free(library); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/src/truetype/ttpic.h b/src/truetype/ttpic.h new file mode 100644 index 0000000..84de0fe --- /dev/null +++ b/src/truetype/ttpic.h @@ -0,0 +1,59 @@ +/***************************************************************************/ +/* */ +/* ttpic.h */ +/* */ +/* The FreeType position independent code services for truetype module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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 __TTPIC_H__ +#define __TTPIC_H__ + + +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 + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_TRUETYPE_GLYF_H + + typedef struct TTModulePIC_ + { + FT_ServiceDescRec* tt_services; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Service_MultiMastersRec tt_service_gx_multi_masters; +#endif + FT_Service_TTGlyfRec tt_service_truetype_glyf; + } 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) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __TTPIC_H__ */ + + +/* END */ diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c index dc538fb..a311b03 100644 --- a/src/truetype/ttpload.c +++ b/src/truetype/ttpload.c @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2004, 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, */ @@ -58,7 +58,6 @@ /* */ /* FreeType error code. 0 means success. */ /* */ - FT_LOCAL_DEF( FT_Error ) tt_face_load_loca( TT_Face face, FT_Stream stream ) @@ -92,11 +91,11 @@ if ( table_len >= 0x40000L ) { - FT_TRACE2(( "table too large!\n" )); + FT_TRACE2(( "table too large\n" )); error = TT_Err_Invalid_Table; goto Exit; } - face->num_locations = (FT_UInt)( table_len >> shift ); + face->num_locations = table_len >> shift; } else { @@ -104,20 +103,20 @@ if ( table_len >= 0x20000L ) { - FT_TRACE2(( "table too large!\n" )); + FT_TRACE2(( "table too large\n" )); error = TT_Err_Invalid_Table; goto Exit; } - face->num_locations = (FT_UInt)( table_len >> shift ); + face->num_locations = table_len >> shift; } - if ( face->num_locations != (FT_UInt)face->root.num_glyphs ) + if ( face->num_locations != (FT_ULong)face->root.num_glyphs ) { FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n", face->num_locations, face->root.num_glyphs )); /* we only handle the case where `maxp' gives a larger value */ - if ( face->num_locations < (FT_UInt)face->root.num_glyphs ) + if ( face->num_locations < (FT_ULong)face->root.num_glyphs ) { FT_Long new_loca_len = (FT_Long)face->root.num_glyphs << shift; @@ -140,7 +139,7 @@ if ( new_loca_len <= dist ) { - face->num_locations = (FT_Long)face->root.num_glyphs; + face->num_locations = face->root.num_glyphs; table_len = new_loca_len; FT_TRACE2(( "adjusting num_locations to %d\n", @@ -204,12 +203,11 @@ } } - /* It isn't mentioned explicitly that the `loca' table must be */ - /* ordered, but implicitly it refers to the length of an entry */ - /* as the difference between the current and the next position. */ - /* Anyway, there do exist (malformed) fonts which don't obey */ - /* this rule, so we are only able to provide an upper bound for */ - /* the size. */ + /* The `loca' table must be ordered; it refers to the length of */ + /* an entry as the difference between the current and the next */ + /* position. However, there do exist (malformed) fonts which */ + /* don't obey this rule, so we are only able to provide an */ + /* upper bound for the size. */ /* */ /* We get (intentionally) a wrong, non-zero result in case the */ /* `glyf' table is missing. */ @@ -267,7 +265,7 @@ error = face->goto_table( face, TTAG_cvt, stream, &table_len ); if ( error ) { - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); face->cvt_size = 0; face->cvt = NULL; @@ -352,7 +350,7 @@ face->font_program_size = 0; error = TT_Err_Ok; - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); } else { @@ -413,7 +411,7 @@ face->cvt_program_size = 0; error = TT_Err_Ok; - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); } else { -- cgit v1.2.3