updated freetype to 2.3.0

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19960 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2007-01-25 19:12:34 +00:00
parent ca48070032
commit 76b72c03e8
133 changed files with 5954 additions and 4628 deletions

View File

@ -4,7 +4,7 @@
/* */
/* Build macros of the FreeType 2 library. */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -88,7 +88,7 @@
/* limited to the infamous 8.3 naming rule required by DOS (and */
/* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */
/* */
/* The second reason is that is allows for more flexibility in the */
/* The second reason is that it allows for more flexibility in the */
/* way FreeType 2 is installed on a given system. */
/* */
/*************************************************************************/
@ -222,7 +222,7 @@
* FT_IMAGE_H
*
* @description:
* A macro used in #include statements to name the file containing types
* A macro used in #include statements to name the file containing type
* definitions related to glyph images (i.e., bitmaps, outlines,
* scan-converter parameters).
*
@ -282,7 +282,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* API used to manage multiple @FT_Size objects per face.
* API which manages multiple @FT_Size objects per face.
*
*/
#define FT_SIZES_H <freetype/ftsizes.h>
@ -334,10 +334,9 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* enumeration values used to identify name strings, languages,
* encodings, etc. This file really contains a _large_ set of constant
* macro definitions, taken from the TrueType and OpenType
* specifications.
* enumeration values which identify name strings, languages, encodings,
* etc. This file really contains a _large_ set of constant macro
* definitions, taken from the TrueType and OpenType specifications.
*
*/
#define FT_TRUETYPE_IDS_H <freetype/ttnameid.h>
@ -363,7 +362,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of TrueType four-byte `tags' used to identify blocks in
* definitions of TrueType four-byte `tags' which identify blocks in
* SFNT-based font formats (i.e., TrueType and OpenType).
*
*/
@ -377,7 +376,8 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of an API to access BDF-specific strings from a face.
* definitions of an API which accesses BDF-specific strings from a
* face.
*
*/
#define FT_BDF_H <freetype/ftbdf.h>
@ -390,7 +390,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of an API to support for gzip-compressed files.
* definitions of an API which supports gzip-compressed files.
*
*/
#define FT_GZIP_H <freetype/ftgzip.h>
@ -403,7 +403,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of an API to support for LZW-compressed files.
* definitions of an API which supports LZW-compressed files.
*
*/
#define FT_LZW_H <freetype/ftlzw.h>
@ -416,7 +416,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of an API to support Windows FNT files.
* definitions of an API which supports Windows FNT files.
*
*/
#define FT_WINFONTS_H <freetype/ftwinfnt.h>
@ -484,7 +484,7 @@
* `glyph image' API of the FreeType 2 cache sub-system.
*
* It is used to define a cache for @FT_Glyph elements. You can also
* see the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to
* use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to
* store small glyph bitmaps, as it will use less memory.
*
* This macro is deprecated. Simply include @FT_CACHE_H to have all
@ -568,7 +568,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* optional FreeType 2 API used to access embedded `name' strings in
* optional FreeType 2 API which accesses embedded `name' strings in
* SFNT-based font formats (i.e., TrueType and OpenType).
*
*/
@ -582,7 +582,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* optional FreeType 2 API used to validate OpenType tables (BASE, GDEF,
* optional FreeType 2 API which validates OpenType tables (BASE, GDEF,
* GPOS, GSUB, JSTF).
*
*/
@ -596,7 +596,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* optional FreeType 2 API used to validate TrueTypeGX/AAT tables (feat,
* optional FreeType 2 API which validates TrueTypeGX/AAT tables (feat,
* mort, morx, bsln, just, kern, opbd, trak, prop).
*
*/
@ -610,7 +610,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API used to access PFR-specific data.
* FreeType 2 API which accesses PFR-specific data.
*
*/
#define FT_PFR_H <freetype/ftpfr.h>
@ -623,7 +623,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API used to stroke outline path.
* FreeType 2 API which provides functions to stroke outline paths.
*/
#define FT_STROKER_H <freetype/ftstroke.h>
@ -635,7 +635,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API used to perform artificial obliquing and emboldening.
* FreeType 2 API which performs artificial obliquing and emboldening.
*/
#define FT_SYNTHESIS_H <freetype/ftsynth.h>
@ -647,7 +647,7 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API used to provide functions specific to the XFree86 and
* FreeType 2 API which provides functions specific to the XFree86 and
* X.Org X11 servers.
*/
#define FT_XFREE86_H <freetype/ftxf86.h>
@ -660,11 +660,36 @@
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API used to perform trigonometric computations (e.g.,
* FreeType 2 API which performs trigonometric computations (e.g.,
* cosines and arc tangents).
*/
#define FT_TRIGONOMETRY_H <freetype/fttrigon.h>
/*************************************************************************
*
* @macro:
* FT_LCD_FILTER_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which performs color filtering for subpixel rendering.
*/
#define FT_LCD_FILTER_H <freetype/ftlcdfil.h>
/*************************************************************************
*
* @macro:
* FT_GASP_H
*
* @description:
* A macro used in #include statements to name the file containing the
* FreeType 2 API which returns entries from the TrueType GASP table.
*/
#define FT_GASP_H <freetype/ftgasp.h>
/* */
#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h>

View File

@ -4,7 +4,7 @@
/* */
/* User-selectable configuration macros (specification only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -75,6 +75,26 @@ FT_BEGIN_HEADER
/*************************************************************************/
/*************************************************************************/
/* */
/* Uncomment the line below if you want to activate sub-pixel rendering */
/* (a.k.a. LCD rendering, or ClearType) in this build of the library. */
/* */
/* Note that this feature is covered by several Microsoft patents */
/* and should not be activated in any default build of the library. */
/* */
/* 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. */
/* */
/* This is done to allow FreeType clients to run unmodified, forcing */
/* them to display normal gray-level anti-aliased glyphs. */
/* */
#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING
/*************************************************************************/
/* */
/* Many compilers provide a non-ANSI 64-bit data type that can be used */
@ -448,7 +468,7 @@ FT_BEGIN_HEADER
/* FT_PARAM_TAG_UNPATENTED_HINTING; or when the debug hook */
/* FT_DEBUG_HOOK_UNPATENTED_HINTING is globally activated. */
/* */
//#define TT_CONFIG_OPTION_UNPATENTED_HINTING
#define TT_CONFIG_OPTION_UNPATENTED_HINTING
/*************************************************************************/
@ -572,13 +592,7 @@ FT_BEGIN_HEADER
#define AF_CONFIG_OPTION_CJK
/* */
/*
* This temporary macro is used to control various optimizations for
* reducing the heap footprint of memory-mapped TrueType files.
*/
#define FT_OPTIMIZE_MEMORY
/* */
/*
@ -594,6 +608,16 @@ FT_BEGIN_HEADER
#define FT_CONFIG_OPTION_OLD_INTERNALS
/*
* This variable is defined if either unpatented or native TrueType
* hinting is requested by the definitions above.
*/
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#define TT_USE_BYTECODE_INTERPRETER
#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING
#define TT_USE_BYTECODE_INTERPRETER
#endif
FT_END_HEADER

View File

@ -168,12 +168,12 @@
#include <setjmp.h>
#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */
/* jmp_buf is defined as a macro */
/* on certain platforms */
#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */
/* jmp_buf is defined as a macro */
/* on certain platforms */
#define ft_longjmp longjmp /* likewise */
#define ft_setjmp setjmp /* same thing here */
#define ft_longjmp longjmp
#define ft_setjmp( b ) setjmp( *(jmp_buf*) &(b) ) /* same thing here */
/* the following is only used for debugging purposes, i.e., if */

View File

@ -4,7 +4,7 @@
/* */
/* FreeType high-level API and common types (specification only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -913,7 +913,9 @@ FT_BEGIN_HEADER
FT_Generic generic;
/*# the following are only relevant to scalable outlines */
/*# The following member variables (down to `underline_thickness') */
/*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */
/*# for bitmap fonts. */
FT_BBox bbox;
FT_UShort units_per_EM;
@ -1270,6 +1272,8 @@ FT_BEGIN_HEADER
/* glyphs. As this would be a definite performance hit, it is up to */
/* client applications to perform such computations. */
/* */
/* The FT_Size_Metrics structure is valid for bitmap fonts also. */
/* */
typedef struct FT_Size_Metrics_
{
FT_UShort x_ppem; /* horizontal pixels per EM */
@ -1795,6 +1799,9 @@ FT_BEGIN_HEADER
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* You must not deallocate the memory before calling @FT_Done_Face. */
/* */
FT_EXPORT( FT_Error )
FT_New_Memory_Face( FT_Library library,
const FT_Byte* file_base,
@ -3306,8 +3313,8 @@ FT_BEGIN_HEADER
* macros.
*/
#define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 2
#define FREETYPE_PATCH 1
#define FREETYPE_MINOR 3
#define FREETYPE_PATCH 0
/*************************************************************************/
@ -3345,7 +3352,6 @@ FT_BEGIN_HEADER
FT_Int *aminor,
FT_Int *apatch );
/* */

View File

@ -3,7 +3,7 @@
/* ftbitmap.h */
/* */
/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */
/* bitmaps into 8bpp format (specification). */
/* bitmaps into 8bpp format (specification). */
/* */
/* Copyright 2004, 2005, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */

View File

@ -56,6 +56,8 @@
/* bdf_fonts */
/* pfr_fonts */
/* winfnt_fonts */
/* font_formats */
/* gasp_table */
/* */
/***************************************************************************/
@ -93,5 +95,6 @@
/* module_management */
/* gzip */
/* lzw */
/* lcd_filtering */
/* */
/***************************************************************************/

View File

@ -0,0 +1,113 @@
/***************************************************************************/
/* */
/* ftgasp.h */
/* */
/* Access of TrueType's `gasp' table (specification). */
/* */
/* Copyright 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#ifndef _FT_GASP_H_
#define _FT_GASP_H_
#include <ft2build.h>
#include FT_FREETYPE_H
/***************************************************************************
*
* @section:
* gasp_table
*
* @title:
* Gasp Table
*
* @abstract:
* Retrieving TrueType `gasp' table entries
*
* @description:
* The function @FT_Get_Gasp can be used to query a TrueType or OpenType
* font for specific entries in their `gasp' table, if any. This is
* mainly useful when implementing native TrueType hinting with the
* bytecode interpreter to duplicate the Windows text rendering results.
*/
/*************************************************************************
*
* @enum:
* FT_GASP_XXX
*
* @description:
* A list of values and/or bit-flags returned by the @FT_Get_Gasp
* function.
*
* @values:
* FT_GASP_NO_TABLE ::
* This special value means that there is no GASP table in this face.
* It is up to the client to decide what to do.
*
* FT_GASP_DO_GRIDFIT ::
* Grid-fitting and hinting should be performed at the specified ppem.
* This *really* means TrueType bytecode interpretation.
*
* FT_GASP_DO_GRAY ::
* Anti-aliased rendering should be performed at the specified ppem.
*
* FT_GASP_SYMMETRIC_SMOOTHING ::
* Smoothing along multiple axes must be used with ClearType.
*
* FT_GASP_SYMMETRIC_GRIDFIT ::
* Grid-fitting must be used with ClearType's symmetric smoothing.
*
* @note:
* `ClearType' is Microsoft's implementation of LCD rendering, partly
* protected by patents.
*
* @since:
* 2.3.0
*/
#define FT_GASP_NO_TABLE -1
#define FT_GASP_DO_GRIDFIT 0x01
#define FT_GASP_DO_GRAY 0x02
#define FT_GASP_SYMMETRIC_SMOOTHING 0x08
#define FT_GASP_SYMMETRIC_GRIDFIT 0x10
/*************************************************************************
*
* @func:
* FT_Get_Gasp
*
* @description:
* Read the `gasp' table from a TrueType or OpenType font file and
* return the entry corresponding to a given character pixel size.
*
* @input:
* face :: The source face handle.
* ppem :: The vertical character pixel size.
*
* @return:
* Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE is there is no
* `gasp' table in the face.
*
* @since:
* 2.3.0
*/
FT_EXPORT( FT_Int )
FT_Get_Gasp( FT_Face face,
FT_UInt ppem );
/* */
#endif /* _FT_GASP_H_ */
/* END */

View File

@ -229,11 +229,11 @@ FT_BEGIN_HEADER
*
* @struct:
* FT_Incremental_FuncsRec
*
*
* @description:
* A table of functions for accessing fonts that load data
* incrementally. Used in @FT_Incremental_InterfaceRec.
*
*
* @fields:
* get_glyph_data ::
* The function to get glyph data. Must not be null.
@ -243,7 +243,7 @@ FT_BEGIN_HEADER
*
* get_glyph_metrics ::
* The function to get glyph metrics. May be null if the font does
* not provide overriding glyph metrics.
* not provide overriding glyph metrics.
*/
typedef struct FT_Incremental_FuncsRec_
{
@ -293,7 +293,7 @@ FT_BEGIN_HEADER
{
const FT_Incremental_FuncsRec* funcs;
FT_Incremental object;
} FT_Incremental_InterfaceRec;
@ -321,7 +321,7 @@ FT_BEGIN_HEADER
*/
#define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' )
/* */
/* */
FT_END_HEADER

View File

@ -0,0 +1,166 @@
/***************************************************************************/
/* */
/* ftlcdfil.h */
/* */
/* FreeType API for color filtering of subpixel bitmap glyphs */
/* (specification). */
/* */
/* Copyright 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#ifndef __FT_LCD_FILTER_H__
#define __FT_LCD_FILTER_H__
#include <ft2build.h>
#include FT_FREETYPE_H
FT_BEGIN_HEADER
/***************************************************************************
*
* @section:
* lcd_filtering
*
* @title:
* LCD Filtering
*
* @abstract:
* Reduce color fringes of LCD-optimized bitmaps.
*
* @description:
* The @FT_Library_SetLcdFilter API can be used to specify a low-pass
* filter which is then applied to LCD-optimized bitmaps generated
* through @FT_Render_Glyph. This is useful to reduce color fringes
* which would occur with unfiltered rendering.
*
* Note that no filter is active by default, and that this function is
* *not* implemented in default builds of the library. You need to
* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file
* in order to activate it.
*/
/****************************************************************************
*
* @func:
* FT_LcdFilter
*
* @description:
* A list of values to identify various types of LCD filters.
*
* @values:
* FT_LCD_FILTER_NONE ::
* Do not perform filtering. When used with subpixel rendering, this
* results in sometimes severe color fringes.
*
* FT_LCD_FILTER_DEFAULT ::
* The default filter reduces color fringes considerably, at the cost
* of a slight blurriness in the output.
*
* FT_LCD_FILTER_LIGHT ::
* The light filter is a variant that produces less blurriness at the
* cost of slightly more color fringes than the default one. It might
* be better, depending on taste, your monitor, or your personal vision.
*
* FT_LCD_FILTER_LEGACY ::
* This filter corresponds to the original libXft color filter. It
* provides high contrast output but can exhibit really bad color
* fringes if glyphs are not extremely well hinted to the pixel grid.
* In other words, it only works well if the TrueType bytecode
* interpreter is enabled *and* high-quality hinted fonts are used.
*
* This filter is only provided for comparison purposes, and might be
* disabled or stay unsupported in the future.
*
* @since:
* 2.3.0
*/
typedef enum
{
FT_LCD_FILTER_NONE = 0,
FT_LCD_FILTER_DEFAULT = 1,
FT_LCD_FILTER_LIGHT = 2,
FT_LCD_FILTER_LEGACY = 16,
FT_LCD_FILTER_MAX /* do not remove */
} FT_LcdFilter;
/**************************************************************************
*
* @func:
* FT_Library_SetLcdFilter
*
* @description:
* This function is used to apply color filtering to LCD decimated
* bitmaps, like the ones used when calling @FT_Render_Glyph with
* @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V.
*
* @input:
* library ::
* A handle to the target library instance.
*
* filter ::
* The filter type.
*
* You can use @FT_LCD_FILTER_NONE here to disable this feature, or
* @FT_LCD_FILTER_DEFAULT to use a default filter that should work
* well on most LCD screens.
*
* @return:
* FreeType error code. 0 means success.
*
* @note:
* This feature is always disabled by default. Clients must make an
* explicit call to this function with a `filter' value other than
* @FT_LCD_FILTER_NONE in order to enable it.
*
* Due to *PATENTS* covering subpixel rendering, this function doesn't
* do anything except returning `FT_Err_Unimplemented_Feature' if the
* configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not
* defined in your build of the library, which should correspond to all
* default builds of FreeType.
*
* The filter affects glyph bitmaps rendered through @FT_Render_Glyph,
* @FT_Outline_Get_Bitmap, @FT_Load_Glyph, and @FT_Load_Char.
*
* It does _not_ affect the output of @FT_Outline_Render and
* @FT_Outline_Get_Bitmap.
*
* If this feature is activated, the dimensions of LCD glyph bitmaps are
* either larger or taller than the dimensions of the corresponding
* outline with regards to the pixel grid. For example, for
* @FT_RENDER_MODE_LCD, the filter adds up to 3 pixels to the left, and
* up to 3 pixels to the right.
*
* The bitmap offset values are adjusted correctly, so clients shouldn't
* need to modify their layout and glyph positioning code when enabling
* the filter.
*
* @since:
* 2.3.0
*/
FT_EXPORT( FT_Error )
FT_Library_SetLcdFilter( FT_Library library,
FT_LcdFilter filter );
/* */
FT_END_HEADER
#endif /* __FT_LCD_FILTER_H__ */
/* END */

View File

@ -154,10 +154,10 @@ FT_BEGIN_HEADER
FT_EXPORT( FT_Error )
FT_OpenType_Validate( FT_Face face,
FT_UInt validation_flags,
FT_Bytes *BASE_table,
FT_Bytes *GDEF_table,
FT_Bytes *GPOS_table,
FT_Bytes *GSUB_table,
FT_Bytes *BASE_table,
FT_Bytes *GDEF_table,
FT_Bytes *GPOS_table,
FT_Bytes *GSUB_table,
FT_Bytes *JSTF_table );
/* */

View File

@ -442,13 +442,13 @@ FT_BEGIN_HEADER
*
* @enum:
* FT_Orientation
*
*
* @description:
* A list of values used to describe an outline's contour orientation.
*
* The TrueType and Postscript specifications use different conventions
* to determine whether outline contours should be filled or unfilled.
*
*
* @values:
* FT_ORIENTATION_TRUETYPE ::
* According to the TrueType specification, clockwise contours must
@ -480,7 +480,7 @@ FT_BEGIN_HEADER
FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE,
FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT,
FT_ORIENTATION_NONE
} FT_Orientation;
@ -488,7 +488,7 @@ FT_BEGIN_HEADER
*
* @function:
* FT_Outline_Get_Orientation
*
*
* @description:
* This function analyzes a glyph outline and tries to compute its
* fill orientation (see @FT_Orientation). This is done by computing

View File

@ -64,7 +64,7 @@ FT_BEGIN_HEADER
*
* @values:
* FT_WinFNT_ID_DEFAULT ::
* This is used for font enumeration and font creation as a
* This is used for font enumeration and font creation as a
* `don't care' value. Valid font files don't contain this value.
* When querying for information about the character set of the font
* that is currently selected into a specified device context, this
@ -95,7 +95,7 @@ FT_BEGIN_HEADER
* Windows have. It is one of the OEM codepages from
*
* http://www.microsoft.com/globaldev/reference/cphome.mspx,
*
*
* and is used for the `DOS boxes', to support legacy applications.
* A German Windows version for example usually uses ANSI codepage
* 1252 and OEM codepage 850.
@ -130,10 +130,10 @@ FT_BEGIN_HEADER
*
* FT_WinFNT_ID_CP1253 ::
* A superset of Greek ISO 8859-7 (with minor modifications).
*
*
* FT_WinFNT_ID_CP1254 ::
* A superset of Turkish ISO 8859-9.
*
*
* FT_WinFNT_ID_CP1255 ::
* A superset of Hebrew ISO 8859-8 (with some modifications).
*

View File

@ -4,7 +4,7 @@
/* */
/* Support functions for X11. */
/* */
/* Copyright 2002, 2003, 2004 by */
/* Copyright 2002, 2003, 2004, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -31,24 +31,44 @@
FT_BEGIN_HEADER
/* this comment is intentionally disabled for now, to prevent this */
/* function from appearing in the API Reference. */
/*@***********************************************************************/
/*************************************************************************/
/* */
/* <Function> */
/* FT_Get_X11_Font_Format */
/* <Section> */
/* font_formats */
/* */
/* <Title> */
/* Font Formats */
/* */
/* <Abstract> */
/* Getting the font format. */
/* */
/* <Description> */
/* Return a string describing the format of a given face as an X11 */
/* FONT_PROPERTY. It should only be used by the FreeType 2 font */
/* backend of the XFree86 font server. */
/* The single function in this section can be used to get the font */
/* format. Note that this information is not needed normally; */
/* however, there are special cases (like in PDF devices) where it is */
/* important to differentiate, inspite of FreeType's uniform API. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* <Function> */
/* FT_Get_X11_Font_Format */
/* */
/* <Description> */
/* Return a string describing the format of a given face, using values */
/* which can be used as an X11 FONT_PROPERTY. Possible values are */
/* `TrueType', `Type 1', `BDF', `PCF', `Type 42', `CID Type 1', `CFF', */
/* `PFR', and `Windows FNT'. */
/* */
/* <Input> */
/* face :: Input face handle. */
/* face :: */
/* Input face handle. */
/* */
/* <Return> */
/* Font format string. NULL in case of error. */
/* Font format string. NULL in case of error. */
/* */
FT_EXPORT( const char* )
FT_Get_X11_Font_Format( FT_Face face );

View File

@ -78,7 +78,7 @@ FT_BEGIN_HEADER
/*************************************************************************/
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#ifdef TT_USE_BYTECODE_INTERPRETER
/*************************************************************************/
/* */
@ -108,7 +108,31 @@ FT_BEGIN_HEADER
FT_Long b,
FT_Long c );
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
#endif /* TT_USE_BYTECODE_INTERPRETER */
/*
* Return -1, 0, or +1, depending on the orientation of a given corner.
* We use the Cartesian coordinate system, with positive vertical values
* going upwards. The function returns +1 if the corner turns to the
* left, -1 to the right, and 0 for undecidable cases.
*/
FT_BASE( FT_Int )
ft_corner_orientation( FT_Pos in_x,
FT_Pos in_y,
FT_Pos out_x,
FT_Pos out_y );
/*
* Return TRUE if a corner is flat or nearly flat. This is equivalent to
* saying that the angle difference between the `in' and `out' vectors is
* very small.
*/
FT_BASE( FT_Int )
ft_corner_is_flat( FT_Pos in_x,
FT_Pos in_y,
FT_Pos out_x,
FT_Pos out_y );
#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 )

View File

@ -69,6 +69,7 @@ FT_BEGIN_HEADER
{
FT_Outline outline; /* outline */
FT_Vector* extra_points; /* extra points table */
FT_Vector* extra_points2; /* second extra points table */
FT_UInt num_subglyphs; /* number of subglyphs */
FT_SubGlyph subglyphs; /* subglyphs */

View File

@ -29,6 +29,7 @@
#include <ft2build.h>
#include FT_RENDER_H
#include FT_SIZES_H
#include FT_LCD_FILTER_H
#include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_GLYPH_LOADER_H
#include FT_INTERNAL_DRIVER_H
@ -211,6 +212,12 @@ FT_BEGIN_HEADER
/* this data when first opened. This field exists only if */
/* @FT_CONFIG_OPTION_INCREMENTAL is defined. */
/* */
/* ignore_unpatented_hinter :: */
/* This boolean flag instructs the glyph loader to ignore the */
/* native font hinter, if one is found. This is exclusively used */
/* in the case when the unpatented hinter is compiled within the */
/* library. */
/* */
typedef struct FT_Face_InternalRec_
{
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
@ -227,6 +234,8 @@ FT_BEGIN_HEADER
FT_Incremental_InterfaceRec* incremental_interface;
#endif
FT_Bool ignore_unpatented_hinter;
} FT_Face_InternalRec;
@ -621,12 +630,17 @@ FT_BEGIN_HEADER
/* Set this debug hook to a non-null pointer to force unpatented hinting */
/* for all faces when both TT_CONFIG_OPTION_BYTECODE_INTERPRETER and */
/* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined. this is only used */
/* for all faces when both TT_USE_BYTECODE_INTERPRETER and */
/* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined. This is only used */
/* during debugging. */
#define FT_DEBUG_HOOK_UNPATENTED_HINTING 1
typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap,
FT_Render_Mode render_mode,
FT_Library library );
/*************************************************************************/
/* */
/* <Struct> */
@ -700,6 +714,13 @@ FT_BEGIN_HEADER
FT_DebugHook_Func debug_hooks[4];
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
FT_LcdFilter lcd_filter;
FT_Int lcd_extra; /* number of extra pixels */
FT_Byte lcd_weights[7]; /* filter weights, if any */
FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */
#endif
} FT_LibraryRec;

View File

@ -414,7 +414,7 @@ FT_BEGIN_HEADER
/* */
/* Useful to optimize access to memory-based streams transparently. */
/* */
/* All extracted frames must be `freed` with a call to the function */
/* All extracted frames must be `freed' with a call to the function */
/* FT_Stream_ReleaseFrame(). */
/* */
FT_BASE( FT_Error )

View File

@ -39,7 +39,7 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* handle to a validation object */
typedef struct FT_ValidatorRec_* FT_Validator;
typedef struct FT_ValidatorRec_ volatile* FT_Validator;
/*************************************************************************/
@ -98,6 +98,8 @@ FT_BEGIN_HEADER
const FT_Byte* limit,
FT_ValidationLevel level );
/* Do not use this. It's broken and will cause your validator to crash */
/* if you run it on an invalid font. */
FT_BASE( FT_Int )
ft_validator_run( FT_Validator valid );

View File

@ -154,6 +154,7 @@ FT_BEGIN_HEADER
T1_TOKEN_TYPE_ANY,
T1_TOKEN_TYPE_STRING,
T1_TOKEN_TYPE_ARRAY,
T1_TOKEN_TYPE_KEY, /* aka `name' */
/* do not remove */
T1_TOKEN_TYPE_MAX
@ -199,6 +200,9 @@ FT_BEGIN_HEADER
T1_FIELD_LOCATION_FONT_INFO,
T1_FIELD_LOCATION_PRIVATE,
T1_FIELD_LOCATION_BBOX,
T1_FIELD_LOCATION_LOADER,
T1_FIELD_LOCATION_FACE,
T1_FIELD_LOCATION_BLEND,
/* do not remove */
T1_FIELD_LOCATION_MAX
@ -224,86 +228,96 @@ FT_BEGIN_HEADER
/* array */
FT_UInt count_offset; /* offset of element count for */
/* arrays */
FT_UInt dict; /* where we expect it */
} T1_FieldRec;
#define T1_FIELD_DICT_FONTDICT ( 1 << 0 ) /* also FontInfo and FDArray */
#define T1_FIELD_DICT_PRIVATE ( 1 << 1 )
#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname ) \
{ \
_ident, T1CODE, _type, \
0, \
FT_FIELD_OFFSET( _fname ), \
FT_FIELD_SIZE( _fname ), \
0, 0 \
#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname, _dict ) \
{ \
_ident, T1CODE, _type, \
0, \
FT_FIELD_OFFSET( _fname ), \
FT_FIELD_SIZE( _fname ), \
0, 0, \
_dict \
},
#define T1_NEW_CALLBACK_FIELD( _ident, _reader ) \
{ \
_ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \
(T1_Field_ParseFunc)_reader, \
0, 0, \
0, 0 \
#define T1_NEW_CALLBACK_FIELD( _ident, _reader, _dict ) \
{ \
_ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \
(T1_Field_ParseFunc)_reader, \
0, 0, \
0, 0, \
_dict \
},
#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max ) \
{ \
_ident, T1CODE, _type, \
0, \
FT_FIELD_OFFSET( _fname ), \
FT_FIELD_SIZE_DELTA( _fname ), \
_max, \
FT_FIELD_OFFSET( num_ ## _fname ) \
#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max, _dict ) \
{ \
_ident, T1CODE, _type, \
0, \
FT_FIELD_OFFSET( _fname ), \
FT_FIELD_SIZE_DELTA( _fname ), \
_max, \
FT_FIELD_OFFSET( num_ ## _fname ), \
_dict \
},
#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max ) \
{ \
_ident, T1CODE, _type, \
0, \
FT_FIELD_OFFSET( _fname ), \
FT_FIELD_SIZE_DELTA( _fname ), \
_max, 0 \
#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max, _dict ) \
{ \
_ident, T1CODE, _type, \
0, \
FT_FIELD_OFFSET( _fname ), \
FT_FIELD_SIZE_DELTA( _fname ), \
_max, 0, \
_dict \
},
#define T1_FIELD_BOOL( _ident, _fname ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname )
#define T1_FIELD_BOOL( _ident, _fname, _dict ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname, _dict )
#define T1_FIELD_NUM( _ident, _fname ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname )
#define T1_FIELD_NUM( _ident, _fname, _dict ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname, _dict )
#define T1_FIELD_FIXED( _ident, _fname ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname )
#define T1_FIELD_FIXED( _ident, _fname, _dict ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname, _dict )
#define T1_FIELD_FIXED_1000( _ident, _fname ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname )
#define T1_FIELD_FIXED_1000( _ident, _fname, _dict ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname, \
_dict )
#define T1_FIELD_STRING( _ident, _fname ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname )
#define T1_FIELD_STRING( _ident, _fname, _dict ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname, _dict )
#define T1_FIELD_KEY( _ident, _fname ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname )
#define T1_FIELD_KEY( _ident, _fname, _dict ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname, _dict )
#define T1_FIELD_BBOX( _ident, _fname ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname )
#define T1_FIELD_BBOX( _ident, _fname, _dict ) \
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname, _dict )
#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax ) \
#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax, _dict ) \
T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \
_fname, _fmax )
_fname, _fmax, _dict )
#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax ) \
#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax, _dict ) \
T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \
_fname, _fmax )
_fname, _fmax, _dict )
#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax ) \
#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax, _dict ) \
T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \
_fname, _fmax )
_fname, _fmax, _dict )
#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax ) \
#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax, _dict ) \
T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \
_fname, _fmax )
_fname, _fmax, _dict )
#define T1_FIELD_CALLBACK( _ident, _name ) \
T1_NEW_CALLBACK_FIELD( _ident, _name )
#define T1_FIELD_CALLBACK( _ident, _name, _dict ) \
T1_NEW_CALLBACK_FIELD( _ident, _name, _dict )
/*************************************************************************/
@ -683,6 +697,9 @@ FT_BEGIN_HEADER
T1_Decoder_Callback parse_callback;
T1_Decoder_FuncsRec funcs;
FT_Int* buildchar;
FT_UInt len_buildchar;
} T1_DecoderRec;
@ -712,8 +729,10 @@ FT_BEGIN_HEADER
} AFM_Parser_FuncsRec;
typedef struct AFM_StreamRec_* AFM_Stream;
/*************************************************************************/
/* */
/* <Struct> */
@ -801,6 +820,57 @@ FT_BEGIN_HEADER
/* backwards-compatible type definition */
typedef PSAux_ServiceRec PSAux_Interface;
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** Some convenience functions *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
#define IS_PS_NEWLINE( ch ) \
( (ch) == '\r' || \
(ch) == '\n' )
#define IS_PS_SPACE( ch ) \
( (ch) == ' ' || \
IS_PS_NEWLINE( ch ) || \
(ch) == '\t' || \
(ch) == '\f' || \
(ch) == '\0' )
#define IS_PS_SPECIAL( ch ) \
( (ch) == '/' || \
(ch) == '(' || (ch) == ')' || \
(ch) == '<' || (ch) == '>' || \
(ch) == '[' || (ch) == ']' || \
(ch) == '{' || (ch) == '}' || \
(ch) == '%' )
#define IS_PS_DELIM( ch ) \
( IS_PS_SPACE( ch ) || \
IS_PS_SPECIAL( ch ) )
#define IS_PS_DIGIT( ch ) \
( (ch) >= '0' && (ch) <= '9' )
#define IS_PS_XDIGIT( ch ) \
( IS_PS_DIGIT( ch ) || \
( (ch) >= 'A' && (ch) <= 'F' ) || \
( (ch) >= 'a' && (ch) <= 'f' ) )
#define IS_PS_BASE85( ch ) \
( (ch) >= '!' && (ch) <= 'u' )
#define IS_PS_TOKEN( cur, limit, token ) \
( (char)(cur)[0] == (token)[0] && \
( (cur) + sizeof ( (token) ) == (limit) || \
( (cur) + sizeof( (token) ) < (limit) && \
IS_PS_DELIM( (cur)[sizeof ( (token) ) - 1] ) ) ) && \
ft_strncmp( (char*)(cur), (token), sizeof ( (token) ) - 1 ) == 0 )
FT_END_HEADER
#endif /* __PSAUX_H__ */

View File

@ -36,12 +36,12 @@ FT_BEGIN_HEADER
FT_DEFINE_SERVICE( Kerning )
{
FT_Kerning_TrackGetFunc get_track;
FT_Kerning_TrackGetFunc get_track;
};
/* */
FT_END_HEADER

View File

@ -29,13 +29,13 @@ FT_BEGIN_HEADER
typedef FT_Error
(*otv_validate_func)( FT_Face face,
FT_UInt ot_flags,
FT_Bytes *base,
FT_Bytes *gdef,
FT_Bytes *gpos,
FT_Bytes *gsub,
FT_Bytes *jstf );
(*otv_validate_func)( FT_Face volatile face,
FT_UInt ot_flags,
FT_Bytes *base,
FT_Bytes *gdef,
FT_Bytes *gpos,
FT_Bytes *gsub,
FT_Bytes *jstf );
FT_DEFINE_SERVICE( OTvalidate )

View File

@ -75,15 +75,24 @@ FT_BEGIN_HEADER
* NULL if invalid index.
*/
typedef const char*
(*PS_Glyph_NameFunc)( FT_Pointer data,
FT_UInt string_index );
(*PS_GetGlyphNameFunc)( FT_Pointer data,
FT_UInt string_index );
/*
* A function used to release the glyph name returned by
* PS_GetGlyphNameFunc, when needed
*/
typedef void
(*PS_FreeGlyphNameFunc)( FT_Pointer data,
const char* name );
typedef FT_Error
(*PS_Unicodes_InitFunc)( FT_Memory memory,
PS_Unicodes unicodes,
FT_UInt num_glyphs,
PS_Glyph_NameFunc get_glyph_name,
FT_Pointer glyph_data );
(*PS_Unicodes_InitFunc)( FT_Memory memory,
PS_Unicodes unicodes,
FT_UInt num_glyphs,
PS_GetGlyphNameFunc get_glyph_name,
PS_FreeGlyphNameFunc free_glyph_name,
FT_Pointer glyph_data );
typedef FT_UInt
(*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes,

View File

@ -18,11 +18,11 @@
/* */
/***************************************************************************/
/* Development of this service is support of
/* Development of this service is support of
Information-technology Promotion Agency, Japan. */
#ifndef __SVTTCMAP_H__
#define __SVTTCMAP_H__
#define __SVTTCMAP_H__
#include FT_INTERNAL_SERVICE_H
#include FT_TRUETYPE_TABLES_H
@ -64,8 +64,8 @@ FT_BEGIN_HEADER
FT_DEFINE_SERVICE( TTCMaps )
{
TT_CMap_Info_GetFunc get_cmap_info;
};
};
/* */

View File

@ -45,7 +45,7 @@ FT_BEGIN_HEADER
/* */
FT_END_HEADER

View File

@ -738,13 +738,13 @@ FT_BEGIN_HEADER
/* the table directory */
TT_Load_Table_Func load_font_dir;
TT_Load_Metrics_Func load_hmtx;
TT_Load_Table_Func load_eblc;
TT_Free_Table_Func free_eblc;
TT_Set_SBit_Strike_Func set_sbit_strike;
TT_Load_Strike_Metrics_Func load_strike_metrics;
TT_Get_Metrics_Func get_metrics;
} SFNT_Interface;

View File

@ -203,11 +203,22 @@ FT_BEGIN_HEADER
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
PS_Unicodes unicode_map;
#endif
#endif
/* support for Multiple Masters fonts */
PS_Blend blend;
/* undocumented, optional: indices of subroutines that express */
/* the NormalizeDesignVector and the ConvertDesignVector procedure, */
/* respectively, as Type 2 charstrings; -1 if keywords not present */
FT_Int ndv_idx;
FT_Int cdv_idx;
/* 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;
/* since version 2.1 - interface to PostScript hinter */
const void* pshinter;

View File

@ -5,7 +5,7 @@
/* Basic SFNT/TrueType type definitions and interface (specification */
/* only). */
/* */
/* Copyright 1996-2001, 2002, 2004, 2005, 2006 by */
/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -1395,7 +1395,6 @@ FT_BEGIN_HEADER
/* since version 2.2 */
#ifdef FT_OPTIMIZE_MEMORY
FT_Byte* horz_metrics;
FT_ULong horz_metrics_size;
@ -1420,12 +1419,15 @@ FT_BEGIN_HEADER
FT_UInt num_kern_tables;
FT_UInt32 kern_avail_bits;
FT_UInt32 kern_order_bits;
#endif
#ifdef TT_CONFIG_OPTION_BDF
TT_BDFRec bdf;
#endif /* TT_CONFIG_OPTION_BDF */
/* since 2.3.0 */
FT_ULong horz_metrics_offset;
FT_ULong vert_metrics_offset;
} TT_FaceRec;
@ -1458,19 +1460,24 @@ FT_BEGIN_HEADER
/* */
/* contours :: The contours end points. */
/* */
/* first_point :: Offset of the current subglyph's first point. */
/* */
typedef struct TT_GlyphZoneRec_
{
FT_Memory memory;
FT_UShort max_points;
FT_UShort max_contours;
FT_UShort n_points; /* number of points in zone */
FT_Short n_contours; /* number of contours */
FT_UShort n_points; /* number of points in zone */
FT_Short n_contours; /* number of contours */
FT_Vector* org; /* original point coordinates */
FT_Vector* cur; /* current point coordinates */
FT_Vector* org; /* original point coordinates */
FT_Vector* cur; /* current point coordinates */
FT_Vector* orus; /* original (unscaled) point coordinates */
FT_Byte* tags; /* current touch flags */
FT_UShort* contours; /* contour end points */
FT_Byte* tags; /* current touch flags */
FT_UShort* contours; /* contour end points */
FT_UShort first_point; /* offset of first (#0) point */
} TT_GlyphZoneRec, *TT_GlyphZone;
@ -1521,6 +1528,10 @@ FT_BEGIN_HEADER
FT_Vector pp3;
FT_Vector pp4;
/* since version 2.2.1 */
FT_Byte* cursor;
FT_Byte* limit;
} TT_LoaderRec;

View File

@ -5,7 +5,7 @@
/* Basic Type 1/Type 2 tables definitions and interface (specification */
/* only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -256,6 +256,15 @@ FT_BEGIN_HEADER
FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1];
/* since 2.3.0 */
/* undocumented, optional: the default design instance; */
/* corresponds to default_weight_vector -- */
/* num_default_design_vector == 0 means it is not present */
/* in the font and associated metrics files */
FT_UInt default_design_vector[T1_MAX_MM_DESIGNS];
FT_UInt num_default_design_vector;
} PS_BlendRec, *PS_Blend;

View File

@ -619,7 +619,7 @@ FT_BEGIN_HEADER
* to access the whole font file. Otherwise, you can use one of the
* definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new
* one with @FT_MAKE_TAG.
*
*
* offset ::
* The starting offset in the table (or file if tag == 0).
*
@ -630,7 +630,7 @@ FT_BEGIN_HEADER
*
* @inout:
* length ::
* If the `length' parameter is NULL, then try to load the whole table.
* If the `length' parameter is NULL, then try to load the whole table.
* Return an error code if it fails.
*
* Else, if `*length' is 0, exit immediately while returning the

View File

@ -5,7 +5,7 @@
/* Routines used to compute vector angles with limited accuracy */
/* and very high speed. It also contains sorting routines (body). */
/* */
/* Copyright 2003, 2004, 2005 by */
/* Copyright 2003, 2004, 2005, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -20,7 +20,123 @@
#include "aftypes.h"
#if 1
#if 0
FT_LOCAL_DEF( FT_Int )
af_corner_is_flat( FT_Pos x_in,
FT_Pos y_in,
FT_Pos x_out,
FT_Pos y_out )
{
FT_Pos ax = x_in;
FT_Pos ay = y_in;
FT_Pos d_in, d_out, d_corner;
if ( ax < 0 )
ax = -ax;
if ( ay < 0 )
ay = -ay;
d_in = ax + ay;
ax = x_out;
if ( ax < 0 )
ax = -ax;
ay = y_out;
if ( ay < 0 )
ay = -ay;
d_out = ax + ay;
ax = x_out + x_in;
if ( ax < 0 )
ax = -ax;
ay = y_out + y_in;
if ( ay < 0 )
ay = -ay;
d_corner = ax + ay;
return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
}
FT_LOCAL_DEF( FT_Int )
af_corner_orientation( FT_Pos x_in,
FT_Pos y_in,
FT_Pos x_out,
FT_Pos y_out )
{
FT_Pos delta;
delta = x_in * y_out - y_in * x_out;
if ( delta == 0 )
return 0;
else
return 1 - 2 * ( delta < 0 );
}
#endif
/*
* We are not using `af_angle_atan' anymore, but we keep the source
* code below just in case...
*/
#if 0
/*
* The trick here is to realize that we don't need a very accurate angle
* approximation. We are going to use the result of `af_angle_atan' to
* only compare the sign of angle differences, or check whether its
* magnitude is very small.
*
* The approximation
*
* dy * PI / (|dx|+|dy|)
*
* should be enough, and much faster to compute.
*/
FT_LOCAL_DEF( AF_Angle )
af_angle_atan( FT_Fixed dx,
FT_Fixed dy )
{
AF_Angle angle;
FT_Fixed ax = dx;
FT_Fixed ay = dy;
if ( ax < 0 )
ax = -ax;
if ( ay < 0 )
ay = -ay;
ax += ay;
if ( ax == 0 )
angle = 0;
else
{
angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay );
if ( dx < 0 )
{
if ( angle >= 0 )
angle = AF_ANGLE_PI - angle;
else
angle = -AF_ANGLE_PI - angle;
}
}
return angle;
}
#elif 0
/* the following table has been automatically generated with */
/* the `mather.py' Python script */
@ -124,222 +240,6 @@
}
#else /* 0 */
/*
* a python script used to generate the following table
*
import sys, math
units = 256
scale = units/math.pi
comma = ""
print ""
print "table of arctan( 1/2^n ) for PI = " + repr( units / 65536.0 ) + " units"
r = [-1] + range( 32 )
for n in r:
if n >= 0:
x = 1.0 / ( 2.0 ** n ) # tangent value
else:
x = 2.0 ** ( -n )
angle = math.atan( x ) # arctangent
angle2 = angle * scale # arctangent in FT_Angle units
# determine which integer value for angle gives the best tangent
lo = int( angle2 )
hi = lo + 1
tlo = math.tan( lo / scale )
thi = math.tan( hi / scale )
errlo = abs( tlo - x )
errhi = abs( thi - x )
angle2 = hi
if errlo < errhi:
angle2 = lo
if angle2 <= 0:
break
sys.stdout.write( comma + repr( int( angle2 ) ) )
comma = ", "
*
* end of python script
*/
/* this table was generated for AF_ANGLE_PI = 256 */
#define AF_ANGLE_MAX_ITERS 8
#define AF_TRIG_MAX_ITERS 8
static const FT_Fixed
af_angle_arctan_table[9] =
{
90, 64, 38, 20, 10, 5, 3, 1, 1
};
static FT_Int
af_angle_prenorm( FT_Vector* vec )
{
FT_Fixed x, y, z;
FT_Int shift;
x = vec->x;
y = vec->y;
z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
shift = 0;
if ( z < ( 1L << 27 ) )
{
do
{
shift++;
z <<= 1;
} while ( z < ( 1L << 27 ) );
vec->x = x << shift;
vec->y = y << shift;
}
else if ( z > ( 1L << 28 ) )
{
do
{
shift++;
z >>= 1;
} while ( z > ( 1L << 28 ) );
vec->x = x >> shift;
vec->y = y >> shift;
shift = -shift;
}
return shift;
}
static void
af_angle_pseudo_polarize( FT_Vector* vec )
{
FT_Fixed theta;
FT_Fixed yi, i;
FT_Fixed x, y;
const FT_Fixed *arctanptr;
x = vec->x;
y = vec->y;
/* Get the vector into the right half plane */
theta = 0;
if ( x < 0 )
{
x = -x;
y = -y;
theta = AF_ANGLE_PI;
}
if ( y > 0 )
theta = -theta;
arctanptr = af_angle_arctan_table;
if ( y < 0 )
{
/* Rotate positive */
yi = y + ( x << 1 );
x = x - ( y << 1 );
y = yi;
theta -= *arctanptr++; /* Subtract angle */
}
else
{
/* Rotate negative */
yi = y - ( x << 1 );
x = x + ( y << 1 );
y = yi;
theta += *arctanptr++; /* Add angle */
}
i = 0;
do
{
if ( y < 0 )
{
/* Rotate positive */
yi = y + ( x >> i );
x = x - ( y >> i );
y = yi;
theta -= *arctanptr++;
}
else
{
/* Rotate negative */
yi = y - ( x >> i );
x = x + ( y >> i );
y = yi;
theta += *arctanptr++;
}
} while ( ++i < AF_TRIG_MAX_ITERS );
#if 0
/* round theta */
if ( theta >= 0 )
theta = FT_PAD_ROUND( theta, 2 );
else
theta = -FT_PAD_ROUND( -theta, 2 );
#endif
vec->x = x;
vec->y = theta;
}
/* cf. documentation in fttrigon.h */
FT_LOCAL_DEF( AF_Angle )
af_angle_atan( FT_Fixed dx,
FT_Fixed dy )
{
FT_Vector v;
if ( dx == 0 && dy == 0 )
return 0;
v.x = dx;
v.y = dy;
af_angle_prenorm( &v );
af_angle_pseudo_polarize( &v );
return v.y;
}
FT_LOCAL_DEF( AF_Angle )
af_angle_diff( AF_Angle angle1,
AF_Angle angle2 )
{
AF_Angle delta = angle2 - angle1;
delta %= AF_ANGLE_2PI;
if ( delta < 0 )
delta += AF_ANGLE_2PI;
if ( delta > AF_ANGLE_PI )
delta -= AF_ANGLE_2PI;
return delta;
}
#endif /* 0 */
@ -389,45 +289,4 @@ for n in r:
}
#ifdef TEST
#include <stdio.h>
#include <math.h>
int main( void )
{
int angle;
int dist;
for ( dist = 100; dist < 1000; dist++ )
{
for ( angle = AF_ANGLE_PI; angle < AF_ANGLE_2PI * 4; angle++ )
{
double a = ( angle * 3.1415926535 ) / ( 1.0 * AF_ANGLE_PI );
int dx, dy, angle1, angle2, delta;
dx = dist * cos( a );
dy = dist * sin( a );
angle1 = ( ( atan2( dy, dx ) * AF_ANGLE_PI ) / 3.1415926535 );
angle2 = af_angle_atan( dx, dy );
delta = ( angle2 - angle1 ) % AF_ANGLE_2PI;
if ( delta < 0 )
delta = -delta;
if ( delta >= 2 )
{
printf( "dist:%4d angle:%4d => (%4d,%4d) angle1:%4d angle2:%4d\n",
dist, angle, dx, dy, angle1, angle2 );
}
}
}
return 0;
}
#endif /* TEST */
/* END */

View File

@ -1437,7 +1437,9 @@
static const AF_Script_UniRangeRec af_cjk_uniranges[] =
{
{ 0x0100, 0xFFFF },
#if 0
{ 0x0100, 0xFFFF }, /* why this? */
#endif
{ 0x2E80, 0x2EFF }, /* CJK Radicals Supplement */
{ 0x2F00, 0x2FDF }, /* Kangxi Radicals */
{ 0x3000, 0x303F }, /* CJK Symbols and Punctuation */

View File

@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006 by */
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -18,6 +18,7 @@
#include "afhints.h"
#include "aferrors.h"
#include FT_INTERNAL_CALC_H
FT_LOCAL_DEF( FT_Error )
@ -53,7 +54,9 @@
}
segment = axis->segments + axis->num_segments++;
#if 0
FT_ZERO( segment );
#endif
Exit:
*asegment = segment;
@ -188,8 +191,7 @@
void
af_glyph_hints_dump_segments( AF_GlyphHints hints )
{
AF_Point points = hints->points;
FT_Int dimension;
FT_Int dimension;
for ( dimension = 1; dimension >= 0; dimension-- )
@ -203,19 +205,18 @@
printf ( "Table of %s segments:\n",
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
printf ( " [ index | pos | dir | link | serif |"
" numl | first | start ]\n" );
" height | extra ]\n" );
for ( seg = segments; seg < limit; seg++ )
{
printf ( " [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",
printf ( " [ %5d | %4d | %5s | %4d | %5d | %5d | %5d ]\n",
seg - segments,
(int)seg->pos,
af_dir_str( seg->dir ),
af_dir_str( (AF_Direction)seg->dir ),
AF_INDEX_NUM( seg->link, segments ),
AF_INDEX_NUM( seg->serif, segments ),
(int)seg->num_linked,
seg->first - points,
seg->last - points );
seg->height,
seg->height - ( seg->max_coord - seg->min_coord ) );
}
printf( "\n" );
}
@ -251,7 +252,7 @@
" %5d | %c | %5.2f | %5.2f ]\n",
edge - edges,
(int)edge->fpos,
af_dir_str( edge->dir ),
af_dir_str( (AF_Direction)edge->dir ),
AF_INDEX_NUM( edge->link, edges ),
AF_INDEX_NUM( edge->serif, edges ),
edge->blue_edge ? 'y' : 'n',
@ -262,8 +263,32 @@
}
}
#endif /* AF_DEBUG */
#else /* !AF_DEBUG */
/* these empty stubs are only used to link the `ftgrid' test program */
/* when debugging is disabled */
void
af_glyph_hints_dump_points( AF_GlyphHints hints )
{
FT_UNUSED( hints );
}
void
af_glyph_hints_dump_segments( AF_GlyphHints hints )
{
FT_UNUSED( hints );
}
void
af_glyph_hints_dump_edges( AF_GlyphHints hints )
{
FT_UNUSED( hints );
}
#endif /* !AF_DEBUG */
/* compute the direction value of a given vector */
@ -271,51 +296,48 @@
af_direction_compute( FT_Pos dx,
FT_Pos dy )
{
#if 1
AF_Direction dir = AF_DIR_NONE;
FT_Pos ll, ss; /* long and short arm lengths */
AF_Direction dir; /* candidate direction */
/* atan(1/12) == 4.7 degrees */
if ( dx < 0 )
if ( dy >= dx )
{
if ( dy < 0 )
if ( dy >= -dx )
{
if ( -dx * 12 < -dy )
dir = AF_DIR_DOWN;
else if ( -dy * 12 < -dx )
dir = AF_DIR_LEFT;
dir = AF_DIR_UP;
ll = dy;
ss = dx;
}
else /* dy >= 0 */
else
{
if ( -dx * 12 < dy )
dir = AF_DIR_UP;
else if ( dy * 12 < -dx )
dir = AF_DIR_LEFT;
dir = AF_DIR_LEFT;
ll = -dx;
ss = dy;
}
}
else /* dx >= 0 */
else /* dy < dx */
{
if ( dy < 0 )
if ( dy >= -dx )
{
if ( dx * 12 < -dy )
dir = AF_DIR_DOWN;
else if ( -dy * 12 < dx )
dir = AF_DIR_RIGHT;
dir = AF_DIR_RIGHT;
ll = dx;
ss = dy;
}
else /* dy >= 0 */
else
{
if ( dx * 12 < dy )
dir = AF_DIR_UP;
else if ( dy * 12 < dx )
dir = AF_DIR_RIGHT;
dir = AF_DIR_DOWN;
ll = dy;
ss = dx;
}
}
ss *= 12;
if ( FT_ABS(ll) <= FT_ABS(ss) )
dir = AF_DIR_NONE;
return dir;
#else /* 0 */
@ -348,6 +370,122 @@
/* compute all inflex points in a given glyph */
#if 1
static void
af_glyph_hints_compute_inflections( AF_GlyphHints hints )
{
AF_Point* contour = hints->contours;
AF_Point* contour_limit = contour + hints->num_contours;
/* do each contour separately */
for ( ; contour < contour_limit; contour++ )
{
AF_Point point = contour[0];
AF_Point first = point;
AF_Point start = point;
AF_Point end = point;
AF_Point before;
AF_Point after;
FT_Pos in_x, in_y, out_x, out_y;
AF_Angle orient_prev, orient_cur;
FT_Int finished = 0;
/* compute first segment in contour */
first = point;
start = end = first;
do
{
end = end->next;
if ( end == first )
goto Skip;
in_x = end->fx - start->fx;
in_y = end->fy - start->fy;
} while ( in_x == 0 && in_y == 0 );
/* extend the segment start whenever possible */
before = start;
do
{
do
{
start = before;
before = before->prev;
if ( before == first )
goto Skip;
out_x = start->fx - before->fx;
out_y = start->fy - before->fy;
} while ( out_x == 0 && out_y == 0 );
orient_prev = ft_corner_orientation( in_x, in_y, out_x, out_y );
} while ( orient_prev == 0 );
first = start;
in_x = out_x;
in_y = out_y;
/* now process all segments in the contour */
do
{
/* first, extend current segment's end whenever possible */
after = end;
do
{
do
{
end = after;
after = after->next;
if ( after == first )
finished = 1;
out_x = after->fx - end->fx;
out_y = after->fy - end->fy;
} while ( out_x == 0 && out_y == 0 );
orient_cur = ft_corner_orientation( in_x, in_y, out_x, out_y );
} while ( orient_cur == 0 );
if ( ( orient_prev + orient_cur ) == 0 )
{
/* we have an inflection point here */
do
{
start->flags |= AF_FLAG_INFLECTION;
start = start->next;
} while ( start != end );
start->flags |= AF_FLAG_INFLECTION;
}
start = end;
end = after;
orient_prev = orient_cur;
in_x = out_x;
in_y = out_y;
} while ( !finished );
Skip:
;
}
}
#else /* old code */
static void
af_glyph_hints_compute_inflections( AF_GlyphHints hints )
{
@ -455,6 +593,8 @@
}
}
#endif /* old code */
FT_LOCAL_DEF( void )
af_glyph_hints_init( AF_GlyphHints hints,
@ -702,6 +842,17 @@
}
else if ( point->out_dir == point->in_dir )
{
#if 1
if ( point->out_dir != AF_DIR_NONE )
goto Is_Weak_Point;
if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) )
goto Is_Weak_Point;
#else /* old code */
AF_Angle angle_in, angle_out, delta;
@ -715,6 +866,9 @@
if ( delta < 2 && delta > -2 )
goto Is_Weak_Point;
#endif /* old code */
}
else if ( point->in_dir == -point->out_dir )
goto Is_Weak_Point;
@ -1152,7 +1306,7 @@
AF_Point points = hints->points;
AF_Point points_limit = points + hints->num_points;
AF_Point point;
if ( dim == AF_DIMENSION_HORZ )
{

View File

@ -125,6 +125,7 @@ FT_BEGIN_HEADER
FT_Short pos; /* position of segment */
FT_Short min_coord; /* minimum coordinate of segment */
FT_Short max_coord; /* maximum coordinate of segment */
FT_Short height; /* the hinted segment height */
AF_Edge edge; /* the segment's parent edge */
AF_Segment edge_next; /* link to next segment in parent edge */
@ -213,6 +214,24 @@ FT_BEGIN_HEADER
#define AF_HINTS_TEST_SCALER( h, f ) ( (h)->scaler_flags & (f) )
#define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) )
#ifdef AF_DEBUG
#define AF_HINTS_DO_HORIZONTAL( h ) \
( !_af_debug_disable_horz_hints && \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )
#define AF_HINTS_DO_VERTICAL( h ) \
( !_af_debug_disable_vert_hints && \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
#define AF_HINTS_DO_ADVANCE( h ) \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
#define AF_HINTS_DO_BLUES( h ) ( !_af_debug_disable_blue_hints )
#else /* !AF_DEBUG */
#define AF_HINTS_DO_HORIZONTAL( h ) \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )
@ -222,6 +241,10 @@ FT_BEGIN_HEADER
#define AF_HINTS_DO_ADVANCE( h ) \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
#define AF_HINTS_DO_BLUES( h ) 1
#endif /* !AF_DEBUG */
FT_LOCAL( AF_Direction )
af_direction_compute( FT_Pos dx,

View File

@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for latin script (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006 by */
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -471,7 +471,7 @@
if ( blue )
{
FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
FT_Pos fitted = FT_PIX_ROUND( scaled );
FT_Pos fitted = ( scaled + 40 ) & ~63;
if ( scaled != fitted )
@ -590,6 +590,7 @@
FT_Memory memory = hints->memory;
FT_Error error = AF_Err_Ok;
AF_Segment segment = NULL;
AF_SegmentRec seg0;
AF_Point* contour = hints->contours;
AF_Point* contour_limit = contour + hints->num_contours;
AF_Direction major_dir, segment_dir;
@ -601,6 +602,11 @@
FT_Pos max_coord = -32000;
#endif
FT_ZERO( &seg0 );
seg0.score = 32000;
seg0.flags = AF_EDGE_NORMAL;
major_dir = (AF_Direction)FT_ABS( axis->major_dir );
segment_dir = major_dir;
@ -717,6 +723,8 @@
segment->min_coord = (FT_Short)min_pos;
segment->max_coord = (FT_Short)max_pos;
segment->height = (FT_Short)( segment->max_coord -
segment->min_coord );
on_edge = 0;
segment = NULL;
@ -742,15 +750,12 @@
if ( error )
goto Exit;
segment[0] = seg0;
segment->dir = (FT_Char)segment_dir;
segment->flags = AF_EDGE_NORMAL;
min_pos = max_pos = point->u;
segment->first = point;
segment->last = point;
segment->contour = contour;
segment->score = 32000;
segment->len = 0;
segment->link = NULL;
on_edge = 1;
#ifdef AF_HINT_METRICS
@ -767,6 +772,58 @@
} /* contours */
/* now slightly increase the height of segments when this makes */
/* sense -- this is used to better detect and ignore serifs */
{
AF_Segment segments = axis->segments;
AF_Segment segments_end = segments + axis->num_segments;
for ( segment = segments; segment < segments_end; segment++ )
{
AF_Point first = segment->first;
AF_Point last = segment->last;
FT_Pos first_v = first->v;
FT_Pos last_v = last->v;
if ( first == last )
continue;
if ( first_v < last_v )
{
AF_Point p;
p = first->prev;
if ( p->v < first_v )
segment->height = (FT_Short)( segment->height +
( ( first_v - p->v ) >> 1 ) );
p = last->next;
if ( p->v > last_v )
segment->height = (FT_Short)( segment->height +
( ( p->v - last_v ) >> 1 ) );
}
else
{
AF_Point p;
p = first->prev;
if ( p->v > first_v )
segment->height = (FT_Short)( segment->height +
( ( p->v - first_v ) >> 1 ) );
p = last->next;
if ( p->v < last_v )
segment->height = (FT_Short)( segment->height +
( ( last_v - p->v ) >> 1 ) );
}
}
}
#ifdef AF_HINT_METRICS
/* we need to ensure that there are edges on the left-most and */
/* right-most points of the glyph in order to hint the metrics; */
@ -810,14 +867,11 @@
if ( error )
goto Exit;
segment[0] = seg0;
segment->dir = segment_dir;
segment->flags = AF_EDGE_NORMAL;
segment->first = min_point;
segment->last = min_point;
segment->pos = min_pos;
segment->score = 32000;
segment->len = 0;
segment->link = NULL;
segment = NULL;
}
@ -830,14 +884,11 @@
if ( error )
goto Exit;
segment[0] = seg0;
segment->dir = segment_dir;
segment->flags = AF_EDGE_NORMAL;
segment->first = max_point;
segment->last = max_point;
segment->pos = max_pos;
segment->score = 32000;
segment->len = 0;
segment->link = NULL;
segment = NULL;
}
@ -865,7 +916,7 @@
if ( len_threshold == 0 )
len_threshold = 1;
len_score = AF_LATIN_CONSTANT( hints->metrics, 3000 );
len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );
/* now compare each segment to the others */
for ( seg1 = segments; seg1 < segment_limit; seg1++ )
@ -926,7 +977,6 @@
if ( seg2 )
{
seg2->num_linked++;
if ( seg2->link != seg1 )
{
seg1->link = 0;
@ -953,6 +1003,7 @@
AF_Direction up_dir;
FT_Fixed scale;
FT_Pos edge_distance_threshold;
FT_Pos segment_length_threshold;
axis->num_edges = 0;
@ -963,6 +1014,16 @@
up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP
: AF_DIR_RIGHT;
/*
* We ignore all segments that are less than 1 pixels in length,
* to avoid many problems with serif fonts. We compute the
* corresponding threshold in font units.
*/
if ( dim == AF_DIMENSION_HORZ )
segment_length_threshold = FT_DivFix( 96, hints->y_scale );
else
segment_length_threshold = 0;
/*********************************************************************/
/* */
/* We will begin by generating a sorted table of edges for the */
@ -993,6 +1054,9 @@
FT_Int ee;
if ( seg->height < segment_length_threshold )
continue;
/* look for an edge corresponding to the segment */
for ( ee = 0; ee < axis->num_edges; ee++ )
{
@ -1110,9 +1174,11 @@
/* check for links -- if seg->serif is set, then seg->link must */
/* be ignored */
is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );
is_serif = (FT_Bool)( seg->serif &&
seg->serif->edge &&
seg->serif->edge != edge );
if ( seg->link || is_serif )
if ( ( seg->link && seg->link->edge != NULL ) || is_serif )
{
AF_Edge edge2;
AF_Segment seg2;
@ -1524,6 +1590,8 @@
else
{
/* strong hinting process: snap the stem width to integer pixels */
FT_Pos org_dist = dist;
dist = af_latin_snap_width( axis->widths, axis->width_count, dist );
@ -1559,7 +1627,28 @@
dist = ( dist + 64 ) >> 1;
else if ( dist < 128 )
{
/* We only round to an integer width if the corresponding */
/* distortion is less than 1/4 pixel. Otherwise this */
/* makes everything worse since the diagonals, which are */
/* not hinted, appear a lot bolder or thinner than the */
/* vertical stems. */
FT_Int delta;
dist = ( dist + 22 ) & ~63;
delta = dist - org_dist;
if ( delta < 0 )
delta = -delta;
if (delta >= 16)
{
dist = org_dist;
if ( dist < 48 )
dist = ( dist + 64 ) >> 1;
}
}
else
/* round otherwise to prevent color fringes in LCD mode */
dist = ( dist + 32 ) & ~63;
@ -1592,6 +1681,11 @@
stem_edge->pos = base_edge->pos + fitted_width;
AF_LOG(( "LINK: edge %d (opos=%.2f) linked to (%.2f), "
"dist was %.2f, now %.2f\n",
stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,
stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
}
@ -1633,7 +1727,7 @@
/* we begin by aligning all stems relative to the blue zone */
/* if needed -- that's only for horizontal edges */
if ( dim == AF_DIMENSION_VERT )
if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) )
{
for ( edge = edges; edge < edge_limit; edge++ )
{
@ -1662,6 +1756,11 @@
if ( !edge1 )
continue;
AF_LOG(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), "
"was (%.2f)\n",
edge1-edges, edge1->opos / 64.0, blue->fit / 64.0,
edge1->pos / 64.0 ));
edge1->pos = blue->fit;
edge1->flags |= AF_EDGE_DONE;
@ -1697,8 +1796,10 @@
/* now align the stem */
/* this should not happen, but it's better to be safe */
if ( edge2->blue_edge || edge2 < edge )
if ( edge2->blue_edge )
{
AF_LOG(( "ASSERTION FAILED for edge %d\n", edge2-edges ));
af_latin_align_linked_edge( hints, dim, edge2, edge );
edge->flags |= AF_EDGE_DONE;
continue;
@ -1743,12 +1844,16 @@
cur_pos1 += d_off;
edge->pos = cur_pos1 - cur_len / 2;
edge2->pos = cur_pos1 + cur_len / 2;
edge2->pos = edge->pos + cur_len;
}
else
edge->pos = FT_PIX_ROUND( edge->opos );
AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) "
"snapped to (%.2f) (%.2f)\n",
edge-edges, edge->opos / 64.0,
edge2-edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 ));
anchor = edge;
edge->flags |= AF_EDGE_DONE;
@ -1770,7 +1875,10 @@
(AF_Edge_Flags)edge->flags,
(AF_Edge_Flags)edge2->flags );
if ( cur_len < 96 )
if ( edge2->flags & AF_EDGE_DONE )
edge->pos = edge2->pos - cur_len;
else if ( cur_len < 96 )
{
FT_Pos u_off, d_off;
@ -1800,6 +1908,12 @@
edge->pos = cur_pos1 - cur_len / 2;
edge2->pos = cur_pos1 + cur_len / 2;
AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) "
"snapped to (%.2f) and (%.2f)\n",
edge-edges, edge->opos / 64.0,
edge2-edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 ));
}
else
{
@ -1824,13 +1938,23 @@
edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
edge2->pos = edge->pos + cur_len;
AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) "
"snapped to (%.2f) and (%.2f)\n",
edge-edges, edge->opos / 64.0,
edge2-edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 ));
}
edge->flags |= AF_EDGE_DONE;
edge2->flags |= AF_EDGE_DONE;
if ( edge > edges && edge->pos < edge[-1].pos )
{
AF_LOG(( "BOUND: %d (pos=%.2f) to (%.2f)\n",
edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
edge->pos = edge[-1].pos;
}
}
}
@ -1904,19 +2028,63 @@
*/
for ( edge = edges; edge < edge_limit; edge++ )
{
FT_Pos delta;
if ( edge->flags & AF_EDGE_DONE )
continue;
delta = 1000;
if ( edge->serif )
{
delta = edge->serif->opos - edge->opos;
if ( delta < 0 )
delta = -delta;
}
if ( delta < 64 + 16 )
{
af_latin_align_serif_edge( hints, edge->serif, edge );
AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) "
"aligned to (%.2f)\n",
edge-edges, edge->opos / 64.0,
edge->serif - edges, edge->serif->opos / 64.0,
edge->pos / 64.0 ));
}
else if ( !anchor )
{
AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
edge->pos = FT_PIX_ROUND( edge->opos );
anchor = edge;
}
else
edge->pos = anchor->pos +
FT_PIX_ROUND( edge->opos - anchor->opos );
{
AF_Edge before, after;
for ( before = edge - 1; before >= edges; before-- )
if ( before->flags & AF_EDGE_DONE )
break;
for ( after = edge + 1; after < edge_limit; after++ )
if ( after->flags & AF_EDGE_DONE )
break;
if ( before >= edges && before < edge &&
after < edge_limit && after > edge )
edge->pos = before->pos +
FT_MulDiv( edge->opos - before->opos,
after->pos - before->pos,
after->opos - before->opos );
else
edge->pos = anchor->pos +
FT_PIX_ROUND( edge->opos - anchor->opos );
AF_LOG(( "SERIF_LINK: edge %d (opos=%.2f) snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
}
edge->flags |= AF_EDGE_DONE;

View File

@ -30,7 +30,9 @@
FT_ZERO( loader );
af_glyph_hints_init( &loader->hints, memory );
#ifdef AF_DEBUG
_af_debug_hints = &loader->hints;
#endif
return FT_GlyphLoader_New( memory, &loader->gloader );
}
@ -71,6 +73,9 @@
loader->face = NULL;
loader->globals = NULL;
#ifdef AF_DEBUG
_af_debug_hints = NULL;
#endif
FT_GlyphLoader_Done( loader->gloader );
loader->gloader = NULL;
}
@ -201,6 +206,12 @@
loader->pp1.x = FT_PIX_ROUND( pp1x_uh );
loader->pp2.x = FT_PIX_ROUND( pp2x_uh );
if ( loader->pp1.x >= new_lsb )
loader->pp1.x -= 64;
if ( loader->pp2.x <= pp2x_uh )
loader->pp2.x += 64;
slot->lsb_delta = loader->pp1.x - pp1x_uh;
slot->rsb_delta = loader->pp2.x - pp2x_uh;
}

View File

@ -4,7 +4,7 @@
/* */
/* Auto-fitter module implementation (body). */
/* */
/* Copyright 2003, 2004, 2005 by */
/* Copyright 2003, 2004, 2005, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -19,6 +19,14 @@
#include "afmodule.h"
#include "afloader.h"
#ifdef AF_DEBUG
int _af_debug;
int _af_debug_disable_horz_hints;
int _af_debug_disable_vert_hints;
int _af_debug_disable_blue_hints;
void* _af_debug_hints;
#endif
#include FT_INTERNAL_OBJECTS_H

View File

@ -4,7 +4,7 @@
/* */
/* Auto-fitter types (specification only). */
/* */
/* Copyright 2003, 2004, 2005, 2006 by */
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -59,14 +59,19 @@ FT_BEGIN_HEADER
#ifdef AF_DEBUG
#include <stdio.h>
#define AF_LOG( x ) do { if ( _af_debug ) printf x; } while ( 0 )
#define AF_LOG( x ) printf x
extern int _af_debug;
extern int _af_debug_disable_horz_hints;
extern int _af_debug_disable_vert_hints;
extern int _af_debug_disable_blue_hints;
extern void* _af_debug_hints;
#else
#else /* !AF_DEBUG */
#define AF_LOG( x ) do ; while ( 0 ) /* nothing */
#endif /* AF_DEBUG */
#endif /* !AF_DEBUG */
/*************************************************************************/
@ -118,6 +123,7 @@ FT_BEGIN_HEADER
#define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 )
#if 0
/*
* compute the angle of a given 2-D vector
*/
@ -126,7 +132,6 @@ FT_BEGIN_HEADER
FT_Pos dy );
#if 0
/*
* compute `angle2 - angle1'; the result is always within
* the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1]

View File

@ -38,7 +38,7 @@ UseFreeTypeHeaders ;
local _sources = system init glyph mm bdf
bbox debug xf86 type1 pfr
stroke winfnt otval bitmap synth
gxval
gxval lcdfil gasp
;
FT2_Library $(FT2_LIB) : ft$(_sources).c ;

View File

@ -49,7 +49,7 @@
FT_UNUSED( library );
FT_Stream_OpenMemory( stream, base, size );
}
}
FT_BASE_DEF( FT_Error )
@ -57,7 +57,7 @@
FT_ULong pos )
{
return FT_Stream_Seek( stream, pos );
}
}
FT_BASE_DEF( FT_Error )
@ -65,7 +65,7 @@
FT_Long distance )
{
return FT_Stream_Skip( stream, distance );
}
}
FT_BASE_DEF( FT_Error )
@ -74,7 +74,7 @@
FT_ULong count )
{
return FT_Stream_Read( stream, buffer, count );
}
}
FT_BASE_DEF( FT_Error )
@ -84,7 +84,7 @@
FT_ULong count )
{
return FT_Stream_ReadAt( stream, pos, buffer, count );
}
}
FT_BASE_DEF( FT_Error )
@ -93,7 +93,7 @@
FT_Byte** pbytes )
{
return FT_Stream_ExtractFrame( stream, count, pbytes );
}
}
FT_BASE_DEF( void )
@ -101,14 +101,14 @@
FT_Byte** pbytes )
{
FT_Stream_ReleaseFrame( stream, pbytes );
}
}
FT_BASE_DEF( FT_Error )
FT_Access_Frame( FT_Stream stream,
FT_ULong count )
{
return FT_Stream_EnterFrame( stream, count );
}
}
FT_BASE_DEF( void )
@ -116,6 +116,6 @@
{
FT_Stream_ExitFrame( stream );
}
/* END */

View File

@ -4,7 +4,7 @@
/* */
/* Single object library component (body only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -20,16 +20,16 @@
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include "ftutil.c"
#include "ftdbgmem.c"
#include "ftstream.c"
#include "ftcalc.c"
#include "fttrigon.c"
#include "ftoutln.c"
#include "ftdbgmem.c"
#include "ftgloadr.c"
#include "ftobjs.c"
#include "ftnames.c"
#include "ftobjs.c"
#include "ftoutln.c"
#include "ftrfork.c"
#include "ftstream.c"
#include "fttrigon.c"
#include "ftutil.c"
#if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON )
#include "ftmac.c"

View File

@ -5,7 +5,7 @@
/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */
/* bitmaps into 8bpp format (body). */
/* */
/* Copyright 2004, 2005, 2006 by */
/* Copyright 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -104,10 +104,11 @@
int pitch;
int new_pitch;
FT_UInt ppb;
FT_Int i;
FT_Int i, width;
unsigned char* buffer;
width = bitmap->width;
pitch = bitmap->pitch;
if ( pitch < 0 )
pitch = -pitch;
@ -170,15 +171,21 @@
if ( bitmap->pitch > 0 )
{
FT_Int len = ( width + ppb - 1 ) / ppb;
for ( i = 0; i < bitmap->rows; i++ )
FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),
bitmap->buffer + pitch * i, pitch );
bitmap->buffer + pitch * i, len );
}
else
{
FT_Int len = ( width + ppb - 1 ) / ppb;
for ( i = 0; i < bitmap->rows; i++ )
FT_MEM_COPY( buffer + new_pitch * i,
bitmap->buffer + pitch * i, pitch );
bitmap->buffer + pitch * i, len );
}
FT_FREE( bitmap->buffer );

View File

@ -159,7 +159,7 @@
}
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#ifdef TT_USE_BYTECODE_INTERPRETER
/* documentation is in ftcalc.h */
@ -183,7 +183,7 @@
return ( s > 0 ) ? d : -d;
}
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
#endif /* TT_USE_BYTECODE_INTERPRETER */
/* documentation is in freetype.h */
@ -228,7 +228,7 @@
}
#else /* FT_LONG64 */
#else /* !FT_LONG64 */
static void
@ -302,12 +302,11 @@
FT_Int64* y,
FT_Int64 *z )
{
register FT_UInt32 lo, hi, max;
register FT_UInt32 lo, hi;
max = x->lo > y->lo ? x->lo : y->lo;
lo = x->lo + y->lo;
hi = x->hi + y->hi + ( lo < max );
lo = x->lo + y->lo;
hi = x->hi + y->hi + ( lo < x->lo );
z->lo = lo;
z->hi = hi;
@ -316,6 +315,23 @@
/* documentation is in freetype.h */
/* The FT_MulDiv function has been optimized thanks to ideas from */
/* Graham Asher. The trick is to optimize computation when everything */
/* fits within 32-bits (a rather common case). */
/* */
/* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */
/* */
/* 46340 is FLOOR(SQRT(2^31-1)). */
/* */
/* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */
/* */
/* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */
/* */
/* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */
/* */
/* and 2*0x157F0 = 176096 */
/* */
FT_EXPORT_DEF( FT_Long )
FT_MulDiv( FT_Long a,
FT_Long b,
@ -353,7 +369,7 @@
}
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#ifdef TT_USE_BYTECODE_INTERPRETER
FT_BASE_DEF( FT_Long )
FT_MulDiv_No_Round( FT_Long a,
@ -387,7 +403,7 @@
return ( s < 0 ? -a : a );
}
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
#endif /* TT_USE_BYTECODE_INTERPRETER */
/* documentation is in freetype.h */
@ -396,7 +412,32 @@
FT_MulFix( FT_Long a,
FT_Long b )
{
#if 1
/* use inline assembly to speed up things a bit */
#if defined( __GNUC__ ) && defined( i386 )
FT_Long result;
__asm__ __volatile__ (
"imul %%edx\n"
"movl %%edx, %%ecx\n"
"sarl $31, %%ecx\n"
"addl $0x8000, %%ecx\n"
"addl %%ecx, %%eax\n"
"adcl $0, %%edx\n"
"shrl $16, %%eax\n"
"shll $16, %%edx\n"
"addl %%edx, %%eax\n"
"mov %%eax, %0\n"
: "=r"(result)
: "a"(a), "d"(b)
: "%ecx"
);
return result;
#elif 1
FT_Long sa, sb;
FT_ULong ua, ub;
@ -405,24 +446,22 @@
return a;
sa = ( a >> ( sizeof ( a ) * 8 - 1 ) );
a = ( a ^ sa ) - sa;
a = ( a ^ sa ) - sa;
sb = ( b >> ( sizeof ( b ) * 8 - 1 ) );
b = ( b ^ sb ) - sb;
b = ( b ^ sb ) - sb;
ua = (FT_ULong)a;
ub = (FT_ULong)b;
if ( ua <= 2048 && ub <= 1048576L )
{
ua = ( ua * ub + 0x8000 ) >> 16;
}
ua = ( ua * ub + 0x8000U ) >> 16;
else
{
FT_ULong al = ua & 0xFFFF;
FT_ULong al = ua & 0xFFFFU;
ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) +
( ( al * ( ub & 0xFFFF ) + 0x8000 ) >> 16 );
( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 );
}
sa ^= sb,
@ -439,23 +478,21 @@
if ( a == 0 || b == 0x10000L )
return a;
s = a; a = FT_ABS(a);
s ^= b; b = FT_ABS(b);
s = a; a = FT_ABS( a );
s ^= b; b = FT_ABS( b );
ua = (FT_ULong)a;
ub = (FT_ULong)b;
if ( ua <= 2048 && ub <= 1048576L )
{
ua = ( ua * ub + 0x8000L ) >> 16;
}
ua = ( ua * ub + 0x8000UL ) >> 16;
else
{
FT_ULong al = ua & 0xFFFFL;
FT_ULong al = ua & 0xFFFFUL;
ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) +
( ( al * ( ub & 0xFFFFL ) + 0x8000L ) >> 16 );
( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 );
}
return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua );
@ -531,7 +568,7 @@
/* apparently, the second version of this code is not compiled correctly */
/* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */
/* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */
#if 1
@ -568,7 +605,7 @@
if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */
return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL );
/* Return Max/Min Int32 if division overflow. */
/* This includes division by zero! */
/* This includes division by zero! */
q = 0;
for ( i = 0; i < 32; i++ )
{
@ -664,4 +701,123 @@
}
/* documentation is in ftcalc.h */
FT_BASE_DEF( FT_Int )
ft_corner_orientation( FT_Pos in_x,
FT_Pos in_y,
FT_Pos out_x,
FT_Pos out_y )
{
FT_Int result;
/* deal with the trivial cases quickly */
if ( in_y == 0 )
{
if ( in_x >= 0 )
result = out_y;
else
result = -out_y;
}
else if ( in_x == 0 )
{
if ( in_y >= 0 )
result = -out_x;
else
result = out_x;
}
else if ( out_y == 0 )
{
if ( out_x >= 0 )
result = in_y;
else
result = -in_y;
}
else if ( out_x == 0 )
{
if ( out_y >= 0 )
result = -in_x;
else
result = in_x;
}
else /* general case */
{
#ifdef FT_LONG64
FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;
if ( delta == 0 )
result = 0;
else
result = 1 - 2 * ( delta < 0 );
#else
FT_Int64 z1, z2;
ft_multo64( in_x, out_y, &z1 );
ft_multo64( in_y, out_x, &z2 );
if ( z1.hi > z2.hi )
result = +1;
else if ( z1.hi < z2.hi )
result = -1;
else if ( z1.lo > z2.lo )
result = +1;
else if ( z1.lo < z2.lo )
result = -1;
else
result = 0;
#endif
}
return result;
}
/* documentation is in ftcalc.h */
FT_BASE_DEF( FT_Int )
ft_corner_is_flat( FT_Pos in_x,
FT_Pos in_y,
FT_Pos out_x,
FT_Pos out_y )
{
FT_Pos ax = in_x;
FT_Pos ay = in_y;
FT_Pos d_in, d_out, d_corner;
if ( ax < 0 )
ax = -ax;
if ( ay < 0 )
ay = -ay;
d_in = ax + ay;
ax = out_x;
if ( ax < 0 )
ax = -ax;
ay = out_y;
if ( ay < 0 )
ay = -ay;
d_out = ax + ay;
ax = out_x + in_x;
if ( ax < 0 )
ax = -ax;
ay = out_y + in_y;
if ( ay < 0 )
ay = -ay;
d_corner = ax + ay;
return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
}
/* END */

View File

@ -460,7 +460,9 @@
FT_MemSource node, *pnode;
hash = (FT_UInt32)(void*)_ft_debug_file +
/* cast to FT_PtrDist first since void* can be larger */
/* than FT_UInt32 and GCC 4.1.1 emits a warning */
hash = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file +
(FT_UInt32)( 5 * _ft_debug_lineno );
pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];

View File

@ -0,0 +1,61 @@
/***************************************************************************/
/* */
/* ftgasp.c */
/* */
/* Access of TrueType's `gasp' table (body). */
/* */
/* Copyright 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include <ft2build.h>
#include FT_GASP_H
#include FT_INTERNAL_TRUETYPE_TYPES_H
FT_EXPORT_DEF( FT_Int )
FT_Get_Gasp( FT_Face face,
FT_UInt ppem )
{
FT_Int result = FT_GASP_NO_TABLE;
if ( face && FT_IS_SFNT( face ) )
{
TT_Face ttface = (TT_Face)face;
if ( ttface->gasp.numRanges > 0 )
{
TT_GaspRange range = ttface->gasp.gaspRanges;
TT_GaspRange range_end = range + ttface->gasp.numRanges;
while ( ppem > range->maxPPEM )
{
range++;
if ( range >= range_end )
goto Exit;
}
result = range->gaspFlag;
/* ensure that we don't have spurious bits */
if ( ttface->gasp.version == 0 )
result &= 3;
}
}
Exit:
return result;
}
/* END */

View File

@ -4,7 +4,7 @@
/* */
/* The FreeType glyph loader (body). */
/* */
/* Copyright 2002, 2003, 2004, 2005 by */
/* Copyright 2002, 2003, 2004, 2005, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -112,6 +112,8 @@
FT_FREE( loader->base.extra_points );
FT_FREE( loader->base.subglyphs );
loader->base.extra_points2 = NULL;
loader->max_points = 0;
loader->max_contours = 0;
loader->max_subglyphs = 0;
@ -149,8 +151,13 @@
/* handle extra points table - if any */
if ( loader->use_extra )
loader->current.extra_points =
loader->base.extra_points + base->n_points;
{
loader->current.extra_points = loader->base.extra_points +
base->n_points;
loader->current.extra_points2 = loader->base.extra_points2 +
base->n_points;
}
}
@ -161,9 +168,12 @@
FT_Memory memory = loader->memory;
if ( !FT_NEW_ARRAY( loader->base.extra_points, loader->max_points ) )
if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )
{
loader->use_extra = 1;
loader->use_extra = 1;
loader->base.extra_points2 = loader->base.extra_points +
loader->max_points;
FT_GlyphLoader_Adjust_Points( loader );
}
return error;
@ -212,9 +222,18 @@
FT_RENEW_ARRAY( base->tags, old_max, new_max ) )
goto Exit;
if ( loader->use_extra &&
FT_RENEW_ARRAY( loader->base.extra_points, old_max, new_max ) )
goto Exit;
if ( loader->use_extra )
{
if ( FT_RENEW_ARRAY( loader->base.extra_points,
old_max * 2, new_max * 2 ) )
goto Exit;
FT_ARRAY_MOVE( loader->base.extra_points + new_max,
loader->base.extra_points + old_max,
old_max );
loader->base.extra_points2 = loader->base.extra_points + new_max;
}
adjust = 1;
loader->max_points = new_max;
@ -355,8 +374,12 @@
/* do we need to copy the extra points? */
if ( target->use_extra && source->use_extra )
{
FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points,
num_points );
FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2,
num_points );
}
out->n_points = (short)num_points;
out->n_contours = (short)num_contours;

View File

@ -4,7 +4,7 @@
/* */
/* FreeType API for validating TrueTyepGX/AAT tables (body). */
/* */
/* Copyright 2004, 2005 by */
/* Copyright 2004, 2005, 2006 by */
/* Masatake YAMATO, Redhat K.K, */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
@ -62,7 +62,7 @@
tables,
table_length );
else
error = FT_Err_Invalid_Argument;
error = FT_Err_Unimplemented_Feature;
Exit:
return error;
@ -108,7 +108,7 @@
validation_flags,
ckern_table );
else
error = FT_Err_Invalid_Argument;
error = FT_Err_Unimplemented_Feature;
Exit:
return error;

View File

@ -0,0 +1,351 @@
/***************************************************************************/
/* */
/* ftlcdfil.c */
/* */
/* FreeType API for color filtering of subpixel bitmap glyphs (body). */
/* */
/* Copyright 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include <ft2build.h>
#include FT_LCD_FILTER_H
#include FT_IMAGE_H
#include FT_INTERNAL_OBJECTS_H
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
/* define USE_LEGACY to implement the legacy filter */
#define USE_LEGACY
/* FIR filter used by the default and light filters */
static void
_ft_lcd_filter_fir( FT_Bitmap* bitmap,
FT_Render_Mode mode,
FT_Library library )
{
FT_Byte* weights = library->lcd_weights;
FT_UInt width = (FT_UInt)bitmap->width;
FT_UInt height = (FT_UInt)bitmap->rows;
/* horizontal in-place FIR filter */
if ( mode == FT_RENDER_MODE_LCD && width >= 4 )
{
FT_Byte* line = bitmap->buffer;
for ( ; height > 0; height--, line += bitmap->pitch )
{
FT_UInt fir[5];
FT_UInt val1, xx;
val1 = line[0];
fir[0] = weights[2] * val1;
fir[1] = weights[3] * val1;
fir[2] = weights[4] * val1;
fir[3] = 0;
fir[4] = 0;
val1 = line[1];
fir[0] += weights[1] * val1;
fir[1] += weights[2] * val1;
fir[2] += weights[3] * val1;
fir[3] += weights[4] * val1;
for ( xx = 2; xx < width; xx++ )
{
FT_UInt val, pix;
val = line[xx];
pix = fir[0] + weights[0] * val;
fir[0] = fir[1] + weights[1] * val;
fir[1] = fir[2] + weights[2] * val;
fir[2] = fir[3] + weights[3] * val;
fir[3] = weights[4] * val;
pix >>= 8;
pix |= -( pix >> 8 );
line[xx - 2] = (FT_Byte)pix;
}
{
FT_UInt pix;
pix = fir[0] >> 8;
pix |= -( pix >> 8 );
line[xx - 2] = (FT_Byte)pix;
pix = fir[1] >> 8;
pix |= -( pix >> 8 );
line[xx - 1] = (FT_Byte)pix;
}
}
}
/* vertical in-place FIR filter */
else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 )
{
FT_Byte* column = bitmap->buffer;
FT_Int pitch = bitmap->pitch;
for ( ; width > 0; width--, column++ )
{
FT_Byte* col = column;
FT_UInt fir[5];
FT_UInt val1, yy;
val1 = col[0];
fir[0] = weights[2] * val1;
fir[1] = weights[3] * val1;
fir[2] = weights[4] * val1;
fir[3] = 0;
fir[4] = 0;
col += pitch;
val1 = col[0];
fir[0] += weights[1] * val1;
fir[1] += weights[2] * val1;
fir[2] += weights[3] * val1;
fir[3] += weights[4] * val1;
col += pitch;
for ( yy = 2; yy < height; yy++ )
{
FT_UInt val, pix;
val = col[0];
pix = fir[0] + weights[0] * val;
fir[0] = fir[1] + weights[1] * val;
fir[1] = fir[2] + weights[2] * val;
fir[2] = fir[3] + weights[3] * val;
fir[3] = weights[4] * val;
pix >>= 8;
pix |= -( pix >> 8 );
col[-2 * pitch] = (FT_Byte)pix;
col += pitch;
}
{
FT_UInt pix;
pix = fir[0] >> 8;
pix |= -( pix >> 8 );
col[-2 * pitch] = (FT_Byte)pix;
pix = fir[1] >> 8;
pix |= -( pix >> 8 );
col[-pitch] = (FT_Byte)pix;
}
}
}
}
#ifdef USE_LEGACY
/* FIR filter used by the default and light filters */
static void
_ft_lcd_filter_legacy( FT_Bitmap* bitmap,
FT_Render_Mode mode,
FT_Library library )
{
FT_UInt width = (FT_UInt)bitmap->width;
FT_UInt height = (FT_UInt)bitmap->rows;
FT_Int pitch = bitmap->pitch;
static const int filters[3][3] =
{
{ 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 },
{ 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 },
{ 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 }
};
FT_UNUSED( library );
/* horizontal in-place FIR filter */
if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
{
FT_Byte* line = bitmap->buffer;
for ( ; height > 0; height--, line += pitch )
{
FT_UInt xx;
for ( xx = 0; xx < width; xx += 3 )
{
FT_UInt r = 0;
FT_UInt g = 0;
FT_UInt b = 0;
FT_UInt p;
p = line[xx];
r += filters[0][0] * p;
g += filters[0][1] * p;
b += filters[0][2] * p;
p = line[xx + 1];
r += filters[1][0] * p;
g += filters[1][1] * p;
b += filters[1][2] * p;
p = line[xx + 2];
r += filters[2][0] * p;
g += filters[2][1] * p;
b += filters[2][2] * p;
line[xx] = (FT_Byte)( r / 65536 );
line[xx + 1] = (FT_Byte)( g / 65536 );
line[xx + 2] = (FT_Byte)( b / 65536 );
}
}
}
else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
{
FT_Byte* column = bitmap->buffer;
for ( ; width > 0; width--, column++ )
{
FT_Byte* col = column;
FT_Byte* col_end = col + height * pitch;
for ( ; col < col_end; col += 3 * pitch )
{
FT_UInt r = 0;
FT_UInt g = 0;
FT_UInt b = 0;
FT_UInt p;
p = col[0];
r += filters[0][0] * p;
g += filters[0][1] * p;
b += filters[0][2] * p;
p = col[pitch];
r += filters[1][0] * p;
g += filters[1][1] * p;
b += filters[1][2] * p;
p = col[pitch * 2];
r += filters[2][0] * p;
g += filters[2][1] * p;
b += filters[2][2] * p;
col[0] = (FT_Byte)( r / 65536 );
col[pitch] = (FT_Byte)( g / 65536 );
col[2 * pitch] = (FT_Byte)( b / 65536 );
}
}
}
}
#endif /* USE_LEGACY */
FT_EXPORT( FT_Error )
FT_Library_SetLcdFilter( FT_Library library,
FT_LcdFilter filter )
{
static const FT_Byte light_filter[5] =
{ 0, 85, 86, 85, 0 };
/* the values here sum up to a value larger than 256, */
/* providing a cheap gamma correction */
static const FT_Byte default_filter[5] =
{ 0x10, 0x40, 0x70, 0x40, 0x10 };
if ( library == NULL )
return FT_Err_Invalid_Argument;
switch ( filter )
{
case FT_LCD_FILTER_NONE:
library->lcd_filter_func = NULL;
library->lcd_extra = 0;
break;
case FT_LCD_FILTER_DEFAULT:
#if defined( FT_FORCE_LEGACY_LCD_FILTER )
library->lcd_filter_func = _ft_lcd_filter_legacy;
library->lcd_extra = 0;
#elif defined( FT_FORCE_LIGHT_LCD_FILTER )
memcpy( library->lcd_weights, light_filter, 5 );
library->lcd_filter_func = _ft_lcd_filter_fir;
library->lcd_extra = 2;
#else
memcpy( library->lcd_weights, default_filter, 5 );
library->lcd_filter_func = _ft_lcd_filter_fir;
library->lcd_extra = 2;
#endif
break;
case FT_LCD_FILTER_LIGHT:
memcpy( library->lcd_weights, light_filter, 5 );
library->lcd_filter_func = _ft_lcd_filter_fir;
library->lcd_extra = 2;
break;
#ifdef USE_LEGACY
case FT_LCD_FILTER_LEGACY:
library->lcd_filter_func = _ft_lcd_filter_legacy;
library->lcd_extra = 0;
break;
#endif
default:
return FT_Err_Invalid_Argument;
}
library->lcd_filter = filter;
return 0;
}
#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
FT_EXPORT( FT_Error )
FT_Library_SetLcdFilter( FT_Library library,
FT_LcdFilter filter )
{
FT_UNUSED( library );
FT_UNUSED( filter );
return FT_Err_Unimplemented_Feature;
}
#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
/* END */

View File

@ -3,7 +3,10 @@
/* ftmac.c */
/* */
/* Mac FOND support. Written by just@letterror.com. */
/* Heavily Fixed by mpsuzuki, George Williams and Sean McBride */
/* Heavily modified by mpsuzuki, George Williams, and Sean McBride. */
/* */
/* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */
/* classic platforms built by MPW. */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */
@ -53,6 +56,12 @@
- If there is a TrueType font (an `sfnt' resource), read it into memory,
wrap it into a memory stream, load the TrueType driver and delegate
the rest of the work to it, by calling FT_Open_Face().
- Some suitcase fonts (notably Onyx) might point the `LWFN' file to
itself, even though it doesn't contains `POST' resources. To handle
this special case without opening the file an extra time, we just
ignore errors from the `LWFN' and fallback to the `sfnt' if both are
available.
*/
@ -60,67 +69,25 @@
#include FT_FREETYPE_H
#include FT_INTERNAL_STREAM_H
#if defined( __GNUC__ ) || defined( __IBMC__ )
/* This is for Mac OS X. Without redefinition, OS_INLINE */
/* expands to `static inline' which doesn't survive the */
/* -ansi compilation flag of GCC. */
#undef OS_INLINE
#define OS_INLINE static __inline__
#include <Carbon/Carbon.h>
#else
#include <Resources.h>
#include <Fonts.h>
#include <Errors.h>
#include <Files.h>
#include <TextUtils.h>
#endif
#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO
#include <FSp_fopen.h>
#endif
#include FT_MAC_H
/* FSSpec functions are deprecated since Mac OS X 10.4 */
#ifndef HAVE_FSSPEC
#if TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON
#define HAVE_FSSPEC 1
#else
#define HAVE_FSSPEC 0
#endif
#endif
/* most FSRef functions were introduced since Mac OS 9 */
#ifndef HAVE_FSREF
#if TARGET_API_MAC_OSX
#define HAVE_FSREF 1
#else
#define HAVE_FSREF 0
#endif
#endif
#ifndef HFS_MAXPATHLEN
#define HFS_MAXPATHLEN 1024
#endif
/* QuickDraw is deprecated since Mac OS X 10.4 */
#ifndef HAVE_QUICKDRAW_CARBON
#if TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON
#define HAVE_QUICKDRAW_CARBON 1
#else
#define HAVE_QUICKDRAW_CARBON 0
#endif
#endif
#include FT_MAC_H
/* undefine blocking-macros in ftmac.h */
#undef FT_GetFile_From_Mac_Name( a, b, c )
#undef FT_GetFile_From_Mac_ATS_Name( a, b, c )
#undef FT_New_Face_From_FSSpec( a, b, c, d )
/* AppleTypeService is available since Mac OS X */
#ifndef HAVE_ATS
#if TARGET_API_MAC_OSX
#define HAVE_ATS 1
#else
#define HAVE_ATS 0
#endif
#endif
/* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over
TrueType in case *both* are available (this is not common,
@ -130,8 +97,6 @@
#endif
#if !HAVE_QUICKDRAW_CARBON /* QuickDraw is deprecated since Mac OS X 10.4 */
FT_EXPORT_DEF( FT_Error )
FT_GetFile_From_Mac_Name( const char* fontName,
FSSpec* pathSpec,
@ -140,106 +105,6 @@
return FT_Err_Unimplemented_Feature;
}
#else
FT_EXPORT_DEF( FT_Error )
FT_GetFile_From_Mac_Name( const char* fontName,
FSSpec* pathSpec,
FT_Long* face_index )
{
OptionBits options = kFMUseGlobalScopeOption;
FMFontFamilyIterator famIter;
OSStatus status = FMCreateFontFamilyIterator( NULL, NULL,
options,
&famIter );
FMFont the_font = 0;
FMFontFamily family = 0;
*face_index = 0;
while ( status == 0 && !the_font )
{
status = FMGetNextFontFamily( &famIter, &family );
if ( status == 0 )
{
int stat2;
FMFontFamilyInstanceIterator instIter;
Str255 famNameStr;
char famName[256];
/* get the family name */
FMGetFontFamilyName( family, famNameStr );
CopyPascalStringToC( famNameStr, famName );
/* iterate through the styles */
FMCreateFontFamilyInstanceIterator( family, &instIter );
*face_index = 0;
stat2 = 0;
while ( stat2 == 0 && !the_font )
{
FMFontStyle style;
FMFontSize size;
FMFont font;
stat2 = FMGetNextFontFamilyInstance( &instIter, &font,
&style, &size );
if ( stat2 == 0 && size == 0 )
{
char fullName[256];
/* build up a complete face name */
ft_strcpy( fullName, famName );
if ( style & bold )
ft_strcat( fullName, " Bold" );
if ( style & italic )
ft_strcat( fullName, " Italic" );
/* compare with the name we are looking for */
if ( ft_strcmp( fullName, fontName ) == 0 )
{
/* found it! */
the_font = font;
}
else
++(*face_index);
}
}
FMDisposeFontFamilyInstanceIterator( &instIter );
}
}
FMDisposeFontFamilyIterator( &famIter );
if ( the_font )
{
FMGetFontContainer( the_font, pathSpec );
return FT_Err_Ok;
}
else
return FT_Err_Unknown_File_Format;
}
#endif /* HAVE_QUICKDRAW_CARBON */
#if !HAVE_ATS
FT_EXPORT_DEF( FT_Error )
FT_GetFile_From_Mac_ATS_Name( const char* fontName,
FSSpec* pathSpec,
FT_Long* face_index )
{
return FT_Err_Unimplemented_Feature;
}
#else
FT_EXPORT_DEF( FT_Error )
FT_GetFile_From_Mac_ATS_Name( const char* fontName,
@ -287,143 +152,11 @@
return FT_Err_Ok;
}
#endif /* HAVE_ATS */
#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO
#define STREAM_FILE( stream ) ( (FT_FILE*)stream->descriptor.pointer )
FT_CALLBACK_DEF( void )
ft_FSp_stream_close( FT_Stream stream )
{
ft_fclose( STREAM_FILE( stream ) );
stream->descriptor.pointer = NULL;
stream->size = 0;
stream->base = 0;
}
FT_CALLBACK_DEF( unsigned long )
ft_FSp_stream_io( FT_Stream stream,
unsigned long offset,
unsigned char* buffer,
unsigned long count )
{
FT_FILE* file;
file = STREAM_FILE( stream );
ft_fseek( file, offset, SEEK_SET );
return (unsigned long)ft_fread( buffer, 1, count, file );
}
#endif /* __MWERKS__ && !TARGET_RT_MAC_MACHO */
#if HAVE_FSSPEC && !HAVE_FSREF
static OSErr
FT_FSPathMakeSpec( const UInt8* pathname,
FSSpec* spec_p,
Boolean isDirectory )
{
const char *p, *q;
short vRefNum;
long dirID;
Str255 nodeName;
OSErr err;
p = q = (const char *)pathname;
dirID = 0;
vRefNum = 0;
while ( 1 )
{
q = p + FT_MIN( 255, ft_strlen( p ) );
if ( q == p )
return 0;
if ( 255 < ft_strlen( (char *)pathname ) )
{
while ( p < q && *q != ':' )
q--;
}
if ( p < q )
*(char *)nodeName = q - p;
else if ( ft_strlen( p ) < 256 )
*(char *)nodeName = ft_strlen( p );
else
return errFSNameTooLong;
ft_strncpy( (char *)nodeName + 1, (char *)p, *(char *)nodeName );
err = FSMakeFSSpec( vRefNum, dirID, nodeName, spec_p );
if ( err || '\0' == *q )
return err;
vRefNum = spec_p->vRefNum;
dirID = spec_p->parID;
p = q;
}
}
static OSErr
FT_FSpMakePath( const FSSpec* spec_p,
UInt8* path,
UInt32 maxPathSize )
{
OSErr err;
FSSpec spec = *spec_p;
short vRefNum;
long dirID;
Str255 parDir_name;
FT_MEM_SET( path, 0, maxPathSize );
while ( 1 )
{
int child_namelen = ft_strlen( (char *)path );
unsigned char node_namelen = spec.name[0];
unsigned char* node_name = spec.name + 1;
if ( node_namelen + child_namelen > maxPathSize )
return errFSNameTooLong;
FT_MEM_MOVE( path + node_namelen + 1, path, child_namelen );
FT_MEM_COPY( path, node_name, node_namelen );
if ( child_namelen > 0 )
path[node_namelen] = ':';
vRefNum = spec.vRefNum;
dirID = spec.parID;
parDir_name[0] = '\0';
err = FSMakeFSSpec( vRefNum, dirID, parDir_name, &spec );
if ( noErr != err || dirID == spec.parID )
break;
}
return noErr;
}
#endif /* HAVE_FSSPEC && !HAVE_FSREF */
static OSErr
FT_FSPathMakeRes( const UInt8* pathname,
short* res )
{
#if HAVE_FSREF
OSErr err;
FSRef ref;
@ -440,22 +173,6 @@
*res = FSOpenResFile( &ref, fsRdPerm );
err = ResError();
#else
OSErr err;
FSSpec spec;
if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) )
return FT_Err_Cannot_Open_Resource;
/* at present, no support for dfont format without FSRef */
/* (see above), try original resource-fork font */
*res = FSpOpenResFile( &spec, fsRdPerm );
err = ResError();
#endif /* HAVE_FSREF */
return err;
}
@ -464,9 +181,6 @@
static OSType
get_file_type_from_path( const UInt8* pathname )
{
#if HAVE_FSREF
FSRef ref;
FSCatalogInfo info;
@ -479,23 +193,6 @@
return ( OSType ) 0;
return ((FInfo *)(info.finderInfo))->fdType;
#else
FSSpec spec;
FInfo finfo;
if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) )
return ( OSType ) 0;
if ( noErr != FSpGetFInfo( &spec, &finfo ) )
return ( OSType ) 0;
return finfo.fdType;
#endif /* HAVE_FSREF */
}
@ -536,7 +233,8 @@
/* The count is 1 greater than the value in the FOND. */
/* Isn't that cute? :-) */
return 1 + *( (short*)( fond_data + sizeof ( FamRec ) ) );
return EndianS16_BtoN( *( (short*)( fond_data +
sizeof ( FamRec ) ) ) ) + 1;
}
@ -549,13 +247,14 @@
fond = (FamRec*)fond_data;
face_all = *( (short *)( fond_data + sizeof ( FamRec ) ) ) + 1;
face_all = EndianS16_BtoN( *( (short *)( fond_data +
sizeof ( FamRec ) ) ) ) + 1;
assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
face = 0;
for ( i = 0; i < face_all; i++ )
{
if ( 0 == assoc[i].fontSize )
if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) )
face++;
}
return face;
@ -597,19 +296,19 @@
/* if the face at this index is not scalable,
fall back to the first one (old behavior) */
if ( assoc->fontSize == 0 )
if ( EndianS16_BtoN( assoc->fontSize ) == 0 )
{
*have_sfnt = 1;
*sfnt_id = assoc->fontID;
*sfnt_id = EndianS16_BtoN( assoc->fontID );
}
else if ( base_assoc->fontSize == 0 )
{
*have_sfnt = 1;
*sfnt_id = base_assoc->fontID;
*sfnt_id = EndianS16_BtoN( base_assoc->fontID );
}
}
if ( fond->ffStylOff )
if ( EndianS32_BtoN( fond->ffStylOff ) )
{
unsigned char* p = (unsigned char*)fond_data;
StyleTable* style;
@ -619,10 +318,10 @@
int i;
p += fond->ffStylOff;
p += EndianS32_BtoN( fond->ffStylOff );
style = (StyleTable*)p;
p += sizeof ( StyleTable );
string_count = *(unsigned short*)(p);
string_count = EndianS16_BtoN( *(short*)(p) );
p += sizeof ( short );
for ( i = 0; i < string_count && i < 64; i++ )
@ -679,9 +378,6 @@
UInt8* path_lwfn,
int path_size )
{
#if HAVE_FSREF
FSRef ref, par_ref;
int dirname_len;
@ -720,44 +416,6 @@
return FT_Err_Cannot_Open_Resource;
return FT_Err_Ok;
#else
int i;
FSSpec spec;
/* pathname for FSSpec is always HFS format */
if ( ft_strlen( (char *)path_fond ) > path_size )
return FT_Err_Invalid_Argument;
ft_strcpy( (char *)path_lwfn, (char *)path_fond );
i = ft_strlen( (char *)path_lwfn ) - 1;
while ( i > 0 && ':' != path_lwfn[i] )
i--;
if ( i + 1 + base_lwfn[0] > path_size )
return FT_Err_Invalid_Argument;
if ( ':' == path_lwfn[i] )
{
ft_strcpy( (char *)path_lwfn + i + 1, (char *)base_lwfn + 1 );
path_lwfn[i + 1 + base_lwfn[0]] = '\0';
}
else
{
ft_strcpy( (char *)path_lwfn, (char *)base_lwfn + 1 );
path_lwfn[base_lwfn[0]] = '\0';
}
if ( noErr != FT_FSPathMakeSpec( path_lwfn, &spec, FALSE ) )
return FT_Err_Cannot_Open_Resource;
return FT_Err_Ok;
#endif /* HAVE_FSREF */
}
@ -770,13 +428,13 @@
Str255 lwfn_file_name;
UInt8 buff[HFS_MAXPATHLEN];
FT_Error err;
short num_faces;
have_sfnt = have_lwfn = 0;
HLock( fond );
parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );
HUnlock( fond );
if ( lwfn_file_name[0] )
{
@ -787,9 +445,12 @@
}
if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
return 1;
num_faces = 1;
else
return count_faces_scalable( *fond );
num_faces = count_faces_scalable( *fond );
HUnlock( fond );
return num_faces;
}
@ -1010,6 +671,8 @@
error = FT_Open_Face( library, &args, face_index, aface );
if ( error == FT_Err_Ok )
(*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
else
FT_Stream_Free( stream, 0 );
return error;
}
@ -1150,7 +813,7 @@
Str255 lwfn_file_name;
UInt8 path_lwfn[HFS_MAXPATHLEN];
OSErr err;
FT_Error error;
FT_Error error = FT_Err_Ok;
GetResInfo( fond, &fond_id, &fond_type, fond_name );
@ -1170,8 +833,6 @@
if ( noErr != ResError() )
goto found_no_lwfn_file;
#if HAVE_FSREF
{
UInt8 path_fond[HFS_MAXPATHLEN];
FSRef ref;
@ -1191,61 +852,24 @@
if ( FT_Err_Ok == error )
have_lwfn = 1;
}
#elif HAVE_FSSPEC
{
UInt8 path_fond[HFS_MAXPATHLEN];
FCBPBRec pb;
Str255 fond_file_name;
FSSpec spec;
FT_MEM_SET( &spec, 0, sizeof ( FSSpec ) );
FT_MEM_SET( &pb, 0, sizeof ( FCBPBRec ) );
pb.ioNamePtr = fond_file_name;
pb.ioVRefNum = 0;
pb.ioRefNum = res;
pb.ioFCBIndx = 0;
err = PBGetFCBInfoSync( &pb );
if ( noErr != err )
goto found_no_lwfn_file;
err = FSMakeFSSpec( pb.ioFCBVRefNum, pb.ioFCBParID,
fond_file_name, &spec );
if ( noErr != err )
goto found_no_lwfn_file;
err = FT_FSpMakePath( &spec, path_fond, sizeof ( path_fond ) );
if ( noErr != err )
goto found_no_lwfn_file;
error = lookup_lwfn_by_fond( path_fond, lwfn_file_name,
path_lwfn, sizeof ( path_lwfn ) );
if ( FT_Err_Ok == error )
have_lwfn = 1;
}
#endif /* HAVE_FSREF, HAVE_FSSPEC */
}
if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
return FT_New_Face_From_LWFN( library,
path_lwfn,
face_index,
aface );
error = FT_New_Face_From_LWFN( library,
path_lwfn,
face_index,
aface );
else
error = FT_Err_Unknown_File_Format;
found_no_lwfn_file:
if ( have_sfnt )
return FT_New_Face_From_SFNT( library,
sfnt_id,
face_index,
aface );
if ( have_sfnt && FT_Err_Ok != error )
error = FT_New_Face_From_SFNT( library,
sfnt_id,
face_index,
aface );
return FT_Err_Unknown_File_Format;
return error;
}
@ -1336,13 +960,6 @@
FT_Long face_index,
FT_Face* aface )
{
#if !HAVE_FSREF
return FT_Err_Unimplemented_Feature;
#else
FT_Error error;
FT_Open_Args args;
OSErr err;
@ -1364,9 +981,6 @@
args.flags = FT_OPEN_PATHNAME;
args.pathname = (char*)pathname;
return FT_Open_Face( library, &args, face_index, aface );
#endif /* HAVE_FSREF */
}
@ -1385,9 +999,6 @@
FT_Long face_index,
FT_Face* aface )
{
#if HAVE_FSREF
FSRef ref;
@ -1395,37 +1006,6 @@
return FT_Err_Invalid_Argument;
else
return FT_New_Face_From_FSRef( library, &ref, face_index, aface );
#elif HAVE_FSSPEC
FT_Error error;
FT_Open_Args args;
OSErr err;
UInt8 pathname[HFS_MAXPATHLEN];
if ( !spec )
return FT_Err_Invalid_Argument;
err = FT_FSpMakePath( spec, pathname, sizeof ( pathname ) );
if ( err )
error = FT_Err_Cannot_Open_Resource;
error = FT_New_Face_From_Resource( library, pathname, face_index, aface );
if ( error != 0 || *aface != NULL )
return error;
/* fallback to datafork font */
args.flags = FT_OPEN_PATHNAME;
args.pathname = (char*)pathname;
return FT_Open_Face( library, &args, face_index, aface );
#else
return FT_Err_Unimplemented_Feature;
#endif /* HAVE_FSREF, HAVE_FSSPEC */
}

View File

@ -174,7 +174,7 @@
/* documentation is in ftmm.h */
/* This is exactly the same as the previous function. It exists for */
/* orthogonality. */

View File

@ -4,7 +4,7 @@
/* */
/* The FreeType private base classes (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -78,11 +78,10 @@
FT_BASE_DEF( FT_Int )
ft_validator_run( FT_Validator valid )
{
int result;
/* This function doesn't work! None should call it. */
FT_UNUSED( valid );
result = ft_setjmp( valid->jump_buffer );
return result;
return -1;
}
@ -90,8 +89,17 @@
ft_validator_error( FT_Validator valid,
FT_Error error )
{
/* since the cast below also disables the compiler's */
/* type check, we introduce a dummy variable, which */
/* will be optimized away */
volatile jmp_buf* jump_buffer = &valid->jump_buffer;
valid->error = error;
ft_longjmp( valid->jump_buffer, 1 );
/* throw away volatileness; use `jump_buffer' or the */
/* compiler may warn about an unused local variable */
ft_longjmp( *(jmp_buf*) jump_buffer, 1 );
}
@ -541,8 +549,8 @@
if ( !face || !face->size || !face->glyph )
return FT_Err_Invalid_Face_Handle;
if ( glyph_index >= (FT_UInt)face->num_glyphs )
return FT_Err_Invalid_Argument;
/* The validity test for `glyph_index' is performed by the */
/* font drivers. */
slot = face->glyph;
ft_glyphslot_clear( slot );
@ -565,22 +573,44 @@
load_flags &= ~FT_LOAD_RENDER;
}
if ( FT_LOAD_TARGET_MODE( load_flags ) == FT_RENDER_MODE_LIGHT )
load_flags |= FT_LOAD_FORCE_AUTOHINT;
/*
* 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.
*
* - Then, autohint 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 requires the unpatented
* bytecode interpreter to load properly.
*/
/* auto-hinter is preferred and should be used */
if ( ( !FT_DRIVER_HAS_HINTER( driver ) ||
( load_flags & FT_LOAD_FORCE_AUTOHINT ) ) &&
!( load_flags & FT_LOAD_NO_HINTING ) &&
!( load_flags & FT_LOAD_NO_AUTOHINT ) )
autohint = 0;
if ( hinter &&
( load_flags & FT_LOAD_NO_HINTING ) == 0 &&
( load_flags & FT_LOAD_NO_AUTOHINT ) == 0 &&
FT_DRIVER_IS_SCALABLE( driver ) &&
FT_DRIVER_USES_OUTLINES( driver ) &&
face->internal->transform_matrix.yy > 0 &&
face->internal->transform_matrix.yx == 0 )
{
/* check whether it works for this face */
autohint =
FT_BOOL( hinter &&
FT_DRIVER_IS_SCALABLE( driver ) &&
FT_DRIVER_USES_OUTLINES( driver ) &&
face->internal->transform_matrix.yy > 0 &&
face->internal->transform_matrix.yx == 0 );
if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) != 0 ||
!FT_DRIVER_HAS_HINTER( driver ) )
autohint = 1;
else
{
FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
if ( mode == FT_RENDER_MODE_LIGHT ||
face->internal->ignore_unpatented_hinter )
autohint = 1;
}
}
if ( autohint )
@ -1341,6 +1371,7 @@
FT_Long flag_offset;
FT_Long rlen;
int is_cff;
FT_Long face_index_in_resource = 0;
if ( face_index == -1 )
@ -1372,7 +1403,7 @@
error = open_face_from_buffer( library,
sfnt_data,
rlen,
face_index,
face_index_in_resource,
is_cff ? "cff" : "truetype",
aface );
@ -1414,6 +1445,9 @@
error = Mac_Read_POST_Resource( library, stream, data_offsets, count,
face_index, aface );
FT_FREE( data_offsets );
/* POST exists in an LWFN providing a single face */
if ( !error )
(*aface)->num_faces = 1;
return error;
}
@ -1423,9 +1457,14 @@
&data_offsets, &count );
if ( !error )
{
FT_Long face_index_internal = face_index % count;
error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count,
face_index, aface );
face_index_internal, aface );
FT_FREE( data_offsets );
if ( !error )
(*aface)->num_faces = count;
}
return error;
@ -1531,7 +1570,7 @@
error = IsMacResource( library, stream2, offsets[i],
face_index, aface );
FT_Stream_Close( stream2 );
FT_Stream_Free( stream2, 0 );
FT_TRACE3(( "%s\n", error ? "failed": "successful" ));
@ -2050,7 +2089,7 @@
FT_Match_Size( FT_Face face,
FT_Size_Request req,
FT_Bool ignore_width,
FT_ULong* index )
FT_ULong* size_index )
{
FT_Int i;
FT_Long w, h;
@ -2084,8 +2123,8 @@
if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width )
{
if ( index )
*index = (FT_ULong)i;
if ( size_index )
*size_index = (FT_ULong)i;
return FT_Err_Ok;
}
@ -2544,6 +2583,9 @@
if ( !face )
return FT_Err_Invalid_Face_Handle;
if ( encoding == FT_ENCODING_NONE )
return FT_Err_Invalid_Argument;
/* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */
/* charmap available, i.e., one with UCS-4 characters, if possible. */
/* */
@ -3718,10 +3760,38 @@
if ( library->generic.finalizer )
library->generic.finalizer( library );
/* Close all modules in the library */
/* Close all faces in the library. If we don't do
* this, we can have some subtle memory leaks.
* Example:
*
* - the cff font driver uses the pshinter module in cff_size_done
* - if the pshinter module is destroyed before the cff font driver,
* opened FT_Face objects managed by the driver are not properly
* destroyed, resulting in a memory leak
*/
{
FT_UInt n;
for ( n = 0; n < library->num_modules; n++ )
{
FT_Module module = library->modules[n];
FT_List faces;
if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 )
continue;
faces = &FT_DRIVER(module)->faces_list;
while ( faces->head )
FT_Done_Face( FT_FACE( faces->head->data ) );
}
}
/* Close all other modules in the library */
#if 1
/* XXX Modules are removed in the reversed order so that */
/* type42 module is removed before truetype module. This */
/* type42 module is removed before truetype module. This */
/* avoids double free in some occasions. It is a hack. */
while ( library->num_modules > 0 )
FT_Remove_Module( library,
@ -3861,7 +3931,7 @@
#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
FT_EXPORT_DEF( FT_Error )
FT_Get_SubGlyph_Info( FT_GlyphSlot glyph,
FT_UInt sub_index,
@ -3872,14 +3942,14 @@
FT_Matrix *p_transform )
{
FT_Error error = FT_Err_Invalid_Argument;
if ( glyph != NULL &&
if ( glyph != NULL &&
glyph->format == FT_GLYPH_FORMAT_COMPOSITE &&
sub_index < glyph->num_subglyphs )
{
FT_SubGlyph subg = glyph->subglyphs + sub_index;
*p_index = subg->index;
*p_flags = subg->flags;

View File

@ -4,7 +4,7 @@
/* */
/* FreeType API for validating OpenType tables (body). */
/* */
/* Copyright 2004 by */
/* Copyright 2004, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -62,7 +62,7 @@
GSUB_table,
JSTF_table );
else
error = FT_Err_Invalid_Argument;
error = FT_Err_Unimplemented_Feature;
Exit:
return error;

View File

@ -4,7 +4,7 @@
/* */
/* FreeType outline management (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -732,7 +732,7 @@
return ( n % 2 );
}
static FT_Bool
ft_contour_enclosed( FT_Outline* outline,
FT_UShort c )
@ -934,7 +934,8 @@
FT_Outline_Get_Orientation( FT_Outline* outline )
{
FT_Pos xmin = 32768L;
FT_Vector* xmin_point = NULL;
FT_Pos xmin_ymin = 32768L;
FT_Pos xmin_ymax = -32768L;
FT_Vector* xmin_first = NULL;
FT_Vector* xmin_last = NULL;
@ -943,22 +944,31 @@
FT_Vector* first;
FT_Vector* last;
FT_Vector* prev;
FT_Vector* next;
FT_Vector* point;
int i;
FT_Pos ray_y[3];
FT_Orientation result[3];
if ( !outline || outline->n_points <= 0 )
return FT_ORIENTATION_TRUETYPE;
/* We use the nonzero winding rule to find the orientation. */
/* Since glyph outlines behave much more `regular' than arbitrary */
/* cubic or quadratic curves, this test deals with the polygon */
/* only which is spanned up by the control points. */
first = outline->points;
for ( contour = outline->contours;
contour < outline->contours + outline->n_contours;
contour++, first = last + 1 )
{
FT_Vector* point;
FT_Int on_curve;
FT_Int on_curve_count = 0;
FT_Pos tmp_xmin = 32768L;
FT_Vector* tmp_xmin_point = NULL;
FT_Pos contour_xmin = 32768L;
FT_Pos contour_xmax = -32768L;
FT_Pos contour_ymin = 32768L;
FT_Pos contour_ymax = -32768L;
last = outline->points + *contour;
@ -968,55 +978,108 @@
for ( point = first; point <= last; ++point )
{
/* Count on-curve points. If there are less than 3 on-curve */
/* points, just bypass this contour. */
on_curve = outline->tags[point - outline->points] & 1;
on_curve_count += on_curve;
if ( point->x < contour_xmin )
contour_xmin = point->x;
if ( point->x < tmp_xmin && on_curve )
{
tmp_xmin = point->x;
tmp_xmin_point = point;
}
if ( point->x > contour_xmax )
contour_xmax = point->x;
if ( point->y < contour_ymin )
contour_ymin = point->y;
if ( point->y > contour_ymax )
contour_ymax = point->y;
}
if ( on_curve_count > 2 && tmp_xmin < xmin )
if ( contour_xmin < xmin &&
contour_xmin != contour_xmax &&
contour_ymin != contour_ymax )
{
xmin = tmp_xmin;
xmin_point = tmp_xmin_point;
xmin = contour_xmin;
xmin_ymin = contour_ymin;
xmin_ymax = contour_ymax;
xmin_first = first;
xmin_last = last;
}
}
if ( !xmin_point )
if ( xmin == 32768 )
return FT_ORIENTATION_TRUETYPE;
prev = ( xmin_point == xmin_first ) ? xmin_last : xmin_point - 1;
next = ( xmin_point == xmin_last ) ? xmin_first : xmin_point + 1;
ray_y[0] = ( xmin_ymin * 3 + xmin_ymax ) >> 2;
ray_y[1] = ( xmin_ymin + xmin_ymax ) >> 1;
ray_y[2] = ( xmin_ymin + xmin_ymax * 3 ) >> 2;
/* Skip off-curve points */
while ( ( outline->tags[prev - outline->points] & 1 ) == 0 )
for ( i = 0; i < 3; i++ )
{
if ( prev == xmin_first )
prev = xmin_last;
else
--prev;
FT_Pos left_x;
FT_Pos right_x;
FT_Vector* left1;
FT_Vector* left2;
FT_Vector* right1;
FT_Vector* right2;
RedoRay:
left_x = 32768L;
right_x = -32768L;
left1 = left2 = right1 = right2 = NULL;
prev = xmin_last;
for ( point = xmin_first; point <= xmin_last; prev = point, ++point )
{
FT_Pos tmp_x;
if ( point->y == ray_y[i] || prev->y == ray_y[i] )
{
ray_y[i]++;
goto RedoRay;
}
if ( ( point->y < ray_y[i] && prev->y < ray_y[i] ) ||
( point->y > ray_y[i] && prev->y > ray_y[i] ) )
continue;
tmp_x = FT_MulDiv( point->x - prev->x,
ray_y[i] - prev->y,
point->y - prev->y ) + prev->x;
if ( tmp_x < left_x )
{
left_x = tmp_x;
left1 = prev;
left2 = point;
}
if ( tmp_x > right_x )
{
right_x = tmp_x;
right1 = prev;
right2 = point;
}
}
if ( left1 && right1 )
{
if ( left1->y < left2->y && right1->y > right2->y )
result[i] = FT_ORIENTATION_TRUETYPE;
else if ( left1->y > left2->y && right1->y < right2->y )
result[i] = FT_ORIENTATION_POSTSCRIPT;
else
result[i] = FT_ORIENTATION_NONE;
}
}
while ( ( outline->tags[next - outline->points] & 1 ) == 0 )
{
if ( next == xmin_last )
next = xmin_first;
else
++next;
}
if ( result[0] != FT_ORIENTATION_NONE &&
( result[0] == result[1] || result[0] == result[2] ) )
return result[0];
if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) >
FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) )
return FT_ORIENTATION_POSTSCRIPT;
else
return FT_ORIENTATION_TRUETYPE;
if ( result[1] != FT_ORIENTATION_NONE && result[1] == result[2] )
return result[1];
return FT_ORIENTATION_TRUETYPE;
}

View File

@ -647,7 +647,7 @@
error = raccess_guess_apple_double( library, stream2, file_name,
&nouse, result_offset );
FT_Stream_Close( stream2 );
FT_Stream_Free( stream2, 0 );
return error;
}

View File

@ -137,8 +137,11 @@
return;
}
/* assume the layout is horizontal */
slot->advance.x += xstr;
if ( slot->advance.x )
slot->advance.x += xstr;
if ( slot->advance.y )
slot->advance.y += ystr;
slot->metrics.width += xstr;
slot->metrics.height += ystr;

View File

@ -120,12 +120,16 @@
FT_Error error = FT_Err_Ok;
if ( cur_count < 0 || new_count < 0 || item_size <= 0 )
/* Note that we now accept `item_size == 0' as a valid parameter, in
* order to cover very weird cases where an ALLOC_MULT macro would be
* called.
*/
if ( cur_count < 0 || new_count < 0 || item_size < 0 )
{
/* may help catch/prevent nasty security issues */
error = FT_Err_Invalid_Argument;
}
else if ( new_count == 0 )
else if ( new_count == 0 || item_size == 0 )
{
ft_mem_free( memory, block );
block = NULL;

View File

@ -3,7 +3,7 @@
#
# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006 by
# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
@ -32,8 +32,10 @@ BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base)
#
# ftsystem, ftinit, and ftdebug are handled by freetype.mk
#
BASE_SRC := $(BASE_DIR)/ftapi.c \
$(BASE_DIR)/ftcalc.c \
# All files listed here should be included in `ftbase.c' (for a `single'
# build).
#
BASE_SRC := $(BASE_DIR)/ftcalc.c \
$(BASE_DIR)/ftdbgmem.c \
$(BASE_DIR)/ftgloadr.c \
$(BASE_DIR)/ftnames.c \

View File

@ -8,14 +8,14 @@ Introduction
************
BDF (Bitmap Distribution Format) is a bitmap font format defined by Adobe,
which is intended to be easily understood by both humans and computers.
which is intended to be easily understood by both humans and computers.
This code implements a BDF driver for the FreeType library, following the
Adobe Specification V 2.2. The specification of the BDF font format is
available from Adobe's web site:
http://partners.adobe.com/asn/developer/PDFS/TN/5005.BDF_Spec.pdf
Many good bitmap fonts in bdf format come with XFree86 (www.XFree86.org).
Many good bitmap fonts in bdf format come with XFree86 (www.XFree86.org).
They do not define vertical metrics, because the X Consortium BDF
specification has removed them.
@ -40,13 +40,13 @@ client application the work of interpreting them. For instance:
FT_New_Face( library, ..., &face );
bdfface = (BDF_Public_Face)face;
if ( ( bdfface->charset_registry == "ISO10646" ) &&
if ( ( bdfface->charset_registry == "ISO10646" ) &&
( bdfface->charset_encoding == "1" ) )
[..]
Thus the driver always exports `ft_encoding_none' as face->charmap.encoding.
Thus the driver always exports `ft_encoding_none' as face->charmap.encoding.
FT_Get_Char_Index's behavior is unmodified, that is, it converts the ULong
value given as argument into the corresponding glyph number.

View File

@ -3,7 +3,7 @@
FreeType font driver for bdf files
Copyright (C) 2001, 2002 by
Francesco Zappa Nardelli
Francesco Zappa Nardelli
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -161,7 +161,7 @@ FT_BEGIN_HEADER
{
const char* key;
void* data;
} _hashnode, *hashnode;

View File

@ -435,6 +435,8 @@ THE SOFTWARE.
/* convert from 722.7 decipoints to 72 points per inch */
bsize->size =
(FT_Pos)( ( prop->value.int32 * 64 * 7200 + 36135L ) / 72270L );
else
bsize->size = bsize->width << 6;
prop = bdf_get_font_property( font, "PIXEL_SIZE" );
if ( prop )
@ -646,16 +648,17 @@ THE SOFTWARE.
FT_UInt glyph_index,
FT_Int32 load_flags )
{
BDF_Face face = (BDF_Face)FT_SIZE_FACE( size );
BDF_Face bdf = (BDF_Face)FT_SIZE_FACE( size );
FT_Face face = FT_FACE( bdf );
FT_Error error = BDF_Err_Ok;
FT_Bitmap* bitmap = &slot->bitmap;
bdf_glyph_t glyph;
int bpp = face->bdffont->bpp;
int bpp = bdf->bdffont->bpp;
FT_UNUSED( load_flags );
if ( !face )
if ( !face || glyph_index >= (FT_UInt)face->num_glyphs )
{
error = BDF_Err_Invalid_Argument;
goto Exit;
@ -663,12 +666,12 @@ THE SOFTWARE.
/* index 0 is the undefined glyph */
if ( glyph_index == 0 )
glyph_index = face->default_glyph;
glyph_index = bdf->default_glyph;
else
glyph_index--;
/* slot, bitmap => freetype, glyph => bdflib */
glyph = face->bdffont->glyphs[glyph_index];
glyph = bdf->bdffont->glyphs[glyph_index];
bitmap->rows = glyph.bbx.height;
bitmap->width = glyph.bbx.width;
@ -710,7 +713,7 @@ THE SOFTWARE.
* used here, provided such fonts do exist.
*/
ft_synthesize_vertical_metrics( &slot->metrics,
face->bdffont->bbx.height << 6 );
bdf->bdffont->bbx.height << 6 );
Exit:
return error;

View File

@ -2204,7 +2204,7 @@
bdf_options_t* opts,
bdf_font_t* *font )
{
unsigned long lineno;
unsigned long lineno = 0; /* make compiler happy */
_bdf_parse_t *p;
FT_Memory memory = extmemory;
@ -2224,7 +2224,7 @@
error = _bdf_readstream( stream, _bdf_parse_start,
(void *)p, &lineno );
if ( error )
goto Exit;
goto Fail;
if ( p->font != 0 )
{
@ -2316,7 +2316,7 @@
if ( FT_RENEW_ARRAY( p->font->comments,
p->font->comments_len,
p->font->comments_len + 1 ) )
goto Exit;
goto Fail;
p->font->comments[p->font->comments_len] = 0;
}
@ -2337,6 +2337,15 @@
}
return error;
Fail:
bdf_free_font( p->font );
memory = extmemory;
FT_FREE( p->font );
goto Exit;
}

View File

@ -4,7 +4,7 @@
# Copyright 2001, 2002, 2006 by
# Francesco Zappa Nardelli
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights

View File

@ -305,9 +305,13 @@
* more than a few charmaps, so if the index is very large...
*
* It is also very unlikely that a rogue client is interested
* in Unicode values 0 to 3.
* in Unicode values 0 to 15.
*
* NOTE: The original threshold was 4, but we found a font from the
* Adobe Acrobat Reader Pack, named `KozMinProVI-Regular.otf',
* which contains more than 5 charmaps.
*/
if ( cmap_index >= 4 )
if ( cmap_index >= 16 )
{
FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id;

View File

@ -120,9 +120,10 @@
/*************************************************************************/
FT_CALLBACK_DEF( const char* )
cff_sid_to_glyph_name( CFF_Font cff,
cff_sid_to_glyph_name( TT_Face face,
FT_UInt idx )
{
CFF_Font cff = (CFF_Font)face->extra.data;
CFF_Charset charset = &cff->charset;
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
FT_UInt sid = charset->sids[idx];
@ -132,6 +133,17 @@
}
FT_CALLBACK_DEF( void )
cff_sid_free_glyph_name( TT_Face face,
const char* gname )
{
FT_Memory memory = FT_FACE_MEMORY( face );
FT_FREE( gname );
}
FT_CALLBACK_DEF( FT_Error )
cff_cmap_unicode_init( PS_Unicodes unicodes )
{
@ -149,8 +161,9 @@
return psnames->unicodes_init( memory,
unicodes,
cff->num_glyphs,
(PS_Glyph_NameFunc)&cff_sid_to_glyph_name,
(FT_Pointer)cff );
(PS_GetGlyphNameFunc)&cff_sid_to_glyph_name,
(PS_FreeGlyphNameFunc)&cff_sid_free_glyph_name,
(FT_Pointer)face );
}

View File

@ -39,14 +39,14 @@ FT_BEGIN_HEADER
{
FT_CMapRec cmap;
FT_UShort* gids; /* up to 256 elements */
} CFF_CMapStdRec;
FT_CALLBACK_TABLE const FT_CMap_ClassRec
cff_cmap_encoding_class_rec;
/*************************************************************************/
/*************************************************************************/
/***** *****/

View File

@ -4,7 +4,7 @@
/* */
/* OpenType font driver implementation (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -302,9 +302,57 @@
}
static FT_Error
cff_ps_get_font_info( CFF_Face face,
PS_FontInfoRec* afont_info )
{
CFF_Font cff = (CFF_Font)face->extra.data;
FT_Error error = FT_Err_Ok;
if ( cff && cff->font_info == NULL )
{
CFF_FontRecDict dict = &cff->top_font.font_dict;
PS_FontInfoRec *font_info;
FT_Memory memory = face->root.memory;
if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
goto Fail;
font_info->version = cff_index_get_sid_string( &cff->string_index,
dict->version,
cff->psnames );
font_info->notice = cff_index_get_sid_string( &cff->string_index,
dict->notice,
cff->psnames );
font_info->full_name = cff_index_get_sid_string( &cff->string_index,
dict->full_name,
cff->psnames );
font_info->family_name = cff_index_get_sid_string( &cff->string_index,
dict->family_name,
cff->psnames );
font_info->weight = cff_index_get_sid_string( &cff->string_index,
dict->weight,
cff->psnames );
font_info->italic_angle = dict->italic_angle;
font_info->is_fixed_pitch = dict->is_fixed_pitch;
font_info->underline_position = (FT_Short)dict->underline_position;
font_info->underline_thickness = (FT_Short)dict->underline_thickness;
cff->font_info = font_info;
}
*afont_info = *cff->font_info;
Fail:
return error;
}
static const FT_Service_PsInfoRec cff_service_ps_info =
{
(PS_GetFontInfoFunc) NULL, /* unsupported with CFF fonts */
(PS_GetFontInfoFunc) cff_ps_get_font_info,
(PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
(PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */
};

View File

@ -4,7 +4,7 @@
/* */
/* OpenType Glyph Loader (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -2275,16 +2275,29 @@
FT_UInt glyph_index,
FT_Int32 load_flags )
{
FT_Error error;
CFF_Decoder decoder;
TT_Face face = (TT_Face)glyph->root.face;
FT_Bool hinting;
CFF_Font cff = (CFF_Font)face->extra.data;
FT_Error error;
CFF_Decoder decoder;
TT_Face face = (TT_Face)glyph->root.face;
FT_Bool hinting;
CFF_Font cff = (CFF_Font)face->extra.data;
FT_Matrix font_matrix;
FT_Vector font_offset;
FT_Matrix font_matrix;
FT_Vector font_offset;
/* in a CID-keyed font, consider `glyph_index' as a CID and map */
/* it immediately to the real glyph_index -- if it isn't a */
/* subsetted font, glyph_indices and CIDs are identical, though */
if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
cff->charset.cids )
{
glyph_index = cff_charset_cid_to_gindex( &cff->charset, glyph_index );
if ( glyph_index == 0 )
return CFF_Err_Invalid_Argument;
}
else if ( glyph_index >= cff->num_glyphs )
return CFF_Err_Invalid_Argument;
if ( load_flags & FT_LOAD_NO_RECURSE )
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
@ -2376,18 +2389,6 @@
FT_ULong charstring_len;
/* in a CID-keyed font, consider `glyph_index' as a CID and map */
/* it immediately to the real glyph_index -- if it isn't a */
/* subsetted font, glyph_indices and CIDs are identical, though */
if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
cff->charset.cids )
{
if ( glyph_index < cff->charset.max_cid )
glyph_index = cff->charset.cids[glyph_index];
else
glyph_index = 0;
}
cff_decoder_init( &decoder, face, size, glyph, hinting,
FT_LOAD_TARGET_MODE( load_flags ) );
@ -2421,13 +2422,15 @@
/* See how charstring loads at cff_index_access_element() in */
/* cffload.c. */
{
CFF_IndexRec csindex = cff->charstrings_index;
CFF_Index csindex = &cff->charstrings_index;
glyph->root.control_data =
csindex.bytes + csindex.offsets[glyph_index] - 1;
glyph->root.control_len =
charstring_len;
if ( csindex->offsets )
{
glyph->root.control_data = csindex->bytes +
csindex->offsets[glyph_index] - 1;
glyph->root.control_len = charstring_len;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
/* */
/* OpenType & CFF data/program tables loader (specification). */
/* */
/* Copyright 1996-2001, 2002, 2003 by */
/* Copyright 1996-2001, 2002, 2003, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -52,6 +52,11 @@ FT_BEGIN_HEADER
FT_Byte** pbytes );
FT_LOCAL( FT_UInt )
cff_charset_cid_to_gindex( CFF_Charset charset,
FT_UInt cid );
FT_LOCAL( FT_Error )
cff_font_load( FT_Stream stream,
FT_Int face_index,

View File

@ -4,7 +4,7 @@
/* */
/* OpenType objects manager (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -207,13 +207,13 @@
{
CFF_Face cffface = (CFF_Face)size->face;
SFNT_Service sfnt = (SFNT_Service)cffface->sfnt;
FT_ULong index;
FT_ULong strike_index;
if ( sfnt->set_sbit_strike( cffface, req, &index ) )
if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) )
cffsize->strike_index = 0xFFFFFFFFUL;
else
return cff_size_select( size, index );
return cff_size_select( size, strike_index );
}
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

View File

@ -4,7 +4,7 @@
/* */
/* OpenType objects manager (specification). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -120,7 +120,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
cff_size_select( FT_Size size,
FT_ULong index );
FT_ULong strike_index );
#endif

View File

@ -5,7 +5,7 @@
/* Basic OpenType/CFF type definitions and interface (specification */
/* only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -23,6 +23,7 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TYPE1_TABLES_H
FT_BEGIN_HEADER
@ -39,6 +40,9 @@ FT_BEGIN_HEADER
/* <Fields> */
/* stream :: The source input stream. */
/* */
/* start :: The position of the first index byte in the */
/* input stream. */
/* */
/* count :: The number of elements in the index. */
/* */
/* off_size :: The size in bytes of object offsets in index. */
@ -46,16 +50,21 @@ FT_BEGIN_HEADER
/* data_offset :: The position of first data byte in the index's */
/* bytes. */
/* */
/* offsets :: A table of element offsets in the index. */
/* data_size :: The size of the data table in this index. */
/* */
/* offsets :: A table of element offsets in the index. Must be */
/* loaded explicitly. */
/* */
/* bytes :: If the index is loaded in memory, its bytes. */
/* */
typedef struct CFF_IndexRec_
{
FT_Stream stream;
FT_ULong start;
FT_UInt count;
FT_Byte off_size;
FT_ULong data_offset;
FT_ULong data_size;
FT_ULong* offsets;
FT_Byte* bytes;
@ -85,6 +94,8 @@ FT_BEGIN_HEADER
FT_UShort* cids; /* the inverse mapping of `sids'; only needed */
/* for CID-keyed fonts */
FT_UInt max_cid;
FT_UInt num_glyphs;
} CFF_CharsetRec, *CFF_Charset;
@ -245,6 +256,9 @@ FT_BEGIN_HEADER
/* interface to Postscript Names service */
void* psnames;
/* since version 2.3.0 */
PS_FontInfoRec* font_info; /* font info dictionary */
} CFF_FontRec, *CFF_Font;

View File

@ -230,6 +230,9 @@
if ( error )
return error;
/* TODO: initialize decoder.len_buildchar and decoder.buildchar */
/* if we ever support CID-keyed multiple master fonts */
decoder.builder.metrics_only = 1;
decoder.builder.load_points = 0;
@ -245,6 +248,8 @@
*max_advance = decoder.builder.advance.x;
psaux->t1_decoder_funcs->done( &decoder );
return CID_Err_Ok;
}
@ -270,6 +275,12 @@
FT_Vector font_offset;
if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
{
error = CID_Err_Invalid_Argument;
goto Exit;
}
if ( load_flags & FT_LOAD_NO_RECURSE )
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
@ -284,128 +295,132 @@
cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
{
error = psaux->t1_decoder_funcs->init( &decoder,
cidglyph->face,
cidsize,
cidglyph,
0, /* glyph names -- XXX */
0, /* blend == 0 */
hinting,
FT_LOAD_TARGET_MODE( load_flags ),
cid_load_glyph );
error = psaux->t1_decoder_funcs->init( &decoder,
cidglyph->face,
cidsize,
cidglyph,
0, /* glyph names -- XXX */
0, /* blend == 0 */
hinting,
FT_LOAD_TARGET_MODE( load_flags ),
cid_load_glyph );
if ( error )
goto Exit;
/* set up the decoder */
decoder.builder.no_recurse = FT_BOOL(
( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
/* TODO: initialize decoder.len_buildchar and decoder.buildchar */
/* if we ever support CID-keyed multiple master fonts */
error = cid_load_glyph( &decoder, glyph_index );
/* set up the decoder */
decoder.builder.no_recurse = FT_BOOL(
( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
font_matrix = decoder.font_matrix;
font_offset = decoder.font_offset;
error = cid_load_glyph( &decoder, glyph_index );
if ( error )
goto Exit;
/* save new glyph tables */
psaux->t1_decoder_funcs->done( &decoder );
}
font_matrix = decoder.font_matrix;
font_offset = decoder.font_offset;
/* now, set the metrics -- this is rather simple, as */
/* save new glyph tables */
psaux->t1_decoder_funcs->done( &decoder );
/* now set the metrics -- this is rather simple, as */
/* the left side bearing is the xMin, and the top side */
/* bearing the yMax */
if ( !error )
cidglyph->outline.flags &= FT_OUTLINE_OWNER;
cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
/* for composite glyphs, return only left side bearing and */
/* advance width */
if ( load_flags & FT_LOAD_NO_RECURSE )
{
cidglyph->outline.flags &= FT_OUTLINE_OWNER;
cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
FT_Slot_Internal internal = cidglyph->internal;
/* for composite glyphs, return only left side bearing and */
/* advance width */
if ( load_flags & FT_LOAD_NO_RECURSE )
cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x;
cidglyph->metrics.horiAdvance = decoder.builder.advance.x;
internal->glyph_matrix = font_matrix;
internal->glyph_delta = font_offset;
internal->glyph_transformed = 1;
}
else
{
FT_BBox cbox;
FT_Glyph_Metrics* metrics = &cidglyph->metrics;
FT_Vector advance;
/* copy the _unscaled_ advance width */
metrics->horiAdvance = decoder.builder.advance.x;
cidglyph->linearHoriAdvance = decoder.builder.advance.x;
cidglyph->internal->glyph_transformed = 0;
/* make up vertical ones */
metrics->vertAdvance = ( face->cid.font_bbox.yMax -
face->cid.font_bbox.yMin ) >> 16;
cidglyph->linearVertAdvance = metrics->vertAdvance;
cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
if ( size && cidsize->metrics.y_ppem < 24 )
cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
/* apply the font matrix */
FT_Outline_Transform( &cidglyph->outline, &font_matrix );
FT_Outline_Translate( &cidglyph->outline,
font_offset.x,
font_offset.y );
advance.x = metrics->horiAdvance;
advance.y = 0;
FT_Vector_Transform( &advance, &font_matrix );
metrics->horiAdvance = advance.x + font_offset.x;
advance.x = 0;
advance.y = metrics->vertAdvance;
FT_Vector_Transform( &advance, &font_matrix );
metrics->vertAdvance = advance.y + font_offset.y;
if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
{
FT_Slot_Internal internal = cidglyph->internal;
/* scale the outline and the metrics */
FT_Int n;
FT_Outline* cur = decoder.builder.base;
FT_Vector* vec = cur->points;
FT_Fixed x_scale = glyph->x_scale;
FT_Fixed y_scale = glyph->y_scale;
cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x;
cidglyph->metrics.horiAdvance = decoder.builder.advance.x;
/* First of all, scale the points */
if ( !hinting || !decoder.builder.hints_funcs )
for ( n = cur->n_points; n > 0; n--, vec++ )
{
vec->x = FT_MulFix( vec->x, x_scale );
vec->y = FT_MulFix( vec->y, y_scale );
}
internal->glyph_matrix = font_matrix;
internal->glyph_delta = font_offset;
internal->glyph_transformed = 1;
/* Then scale the metrics */
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
}
else
{
FT_BBox cbox;
FT_Glyph_Metrics* metrics = &cidglyph->metrics;
FT_Vector advance;
/* compute the other metrics */
FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
/* copy the _unscaled_ advance width */
metrics->horiAdvance = decoder.builder.advance.x;
cidglyph->linearHoriAdvance = decoder.builder.advance.x;
cidglyph->internal->glyph_transformed = 0;
metrics->width = cbox.xMax - cbox.xMin;
metrics->height = cbox.yMax - cbox.yMin;
/* make up vertical ones */
metrics->vertAdvance = ( face->cid.font_bbox.yMax -
face->cid.font_bbox.yMin ) >> 16;
cidglyph->linearVertAdvance = metrics->vertAdvance;
metrics->horiBearingX = cbox.xMin;
metrics->horiBearingY = cbox.yMax;
cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
if ( size && cidsize->metrics.y_ppem < 24 )
cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
/* apply the font matrix */
FT_Outline_Transform( &cidglyph->outline, &font_matrix );
FT_Outline_Translate( &cidglyph->outline,
font_offset.x,
font_offset.y );
advance.x = metrics->horiAdvance;
advance.y = 0;
FT_Vector_Transform( &advance, &font_matrix );
metrics->horiAdvance = advance.x + font_offset.x;
advance.x = 0;
advance.y = metrics->vertAdvance;
FT_Vector_Transform( &advance, &font_matrix );
metrics->vertAdvance = advance.y + font_offset.y;
if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
{
/* scale the outline and the metrics */
FT_Int n;
FT_Outline* cur = decoder.builder.base;
FT_Vector* vec = cur->points;
FT_Fixed x_scale = glyph->x_scale;
FT_Fixed y_scale = glyph->y_scale;
/* First of all, scale the points */
if ( !hinting || !decoder.builder.hints_funcs )
for ( n = cur->n_points; n > 0; n--, vec++ )
{
vec->x = FT_MulFix( vec->x, x_scale );
vec->y = FT_MulFix( vec->y, y_scale );
}
/* Then scale the metrics */
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
}
/* compute the other metrics */
FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
metrics->width = cbox.xMax - cbox.xMin;
metrics->height = cbox.yMax - cbox.yMin;
metrics->horiBearingX = cbox.xMin;
metrics->horiBearingY = cbox.yMax;
/* make up vertical ones */
ft_synthesize_vertical_metrics( metrics,
metrics->vertAdvance );
}
/* make up vertical ones */
ft_synthesize_vertical_metrics( metrics,
metrics->vertAdvance );
}
Exit:
return error;
}

View File

@ -4,7 +4,7 @@
/* */
/* CID-keyed Type1 font loader (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -240,10 +240,10 @@
#include "cidtoken.h"
T1_FIELD_CALLBACK( "FDArray", parse_fd_array )
T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix )
T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 )
T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, 0 )
{ 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 }
{ 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }
};

View File

@ -4,7 +4,7 @@
/* */
/* CID-keyed Type1 parser (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -83,7 +83,8 @@
goto Exit;
Again:
/* now, read the rest of the file until we find a `StartData' */
/* now, read the rest of the file until we find */
/* `StartData' or `/sfnts' */
{
FT_Byte buffer[256 + 10];
FT_Int read_len = 256 + 10;
@ -92,7 +93,7 @@
for ( offset = (FT_ULong)FT_STREAM_POS(); ; offset += 256 )
{
FT_Int stream_len;
FT_Int stream_len;
stream_len = stream->size - FT_STREAM_POS();
@ -116,6 +117,11 @@
offset += p - buffer + 10;
goto Found;
}
else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 )
{
offset += p - buffer + 7;
goto Found;
}
}
FT_MEM_MOVE( buffer, p, 10 );
@ -125,8 +131,9 @@
}
Found:
/* We have found the start of the binary data. Now rewind and */
/* extract the frame corresponding to the PostScript section. */
/* We have found the start of the binary data or the `/sfnts' token. */
/* Now rewind and extract the frame corresponding to this PostScript */
/* section. */
ps_len = offset - base_offset;
if ( FT_STREAM_SEEK( base_offset ) ||
@ -140,9 +147,10 @@
parser->root.limit = parser->root.cursor + ps_len;
parser->num_dict = -1;
/* Finally, we check whether `StartData' was real -- it could be */
/* in a comment or string. We also get its arguments to find out */
/* whether the data is represented in binary or hex format. */
/* Finally, we check whether `StartData' or `/sfnts' was real -- */
/* it could be in a comment or string. We also get the arguments */
/* of `StartData' to find out whether the data is represented in */
/* binary or hex format. */
arg1 = parser->root.cursor;
cid_parser_skip_PS_token( parser );
@ -159,7 +167,7 @@
if ( parser->root.error )
break;
if ( *cur == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
{
if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
parser->binary_length = ft_atol( (const char *)arg2 );
@ -168,6 +176,12 @@
cur = parser->root.cursor;
goto Exit;
}
else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 )
{
FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));
error = CID_Err_Unknown_File_Format;
goto Exit;
}
cid_parser_skip_PS_token( parser );
cid_parser_skip_spaces ( parser );

View File

@ -4,7 +4,7 @@
/* */
/* CID token definitions (specification only). */
/* */
/* Copyright 1996-2001, 2002, 2003 by */
/* Copyright 1996-2001, 2002, 2003, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -21,17 +21,17 @@
#undef T1CODE
#define T1CODE T1_FIELD_LOCATION_CID_INFO
T1_FIELD_KEY ( "CIDFontName", cid_font_name )
T1_FIELD_NUM ( "CIDFontVersion", cid_version )
T1_FIELD_NUM ( "CIDFontType", cid_font_type )
T1_FIELD_STRING( "Registry", registry )
T1_FIELD_STRING( "Ordering", ordering )
T1_FIELD_NUM ( "Supplement", supplement )
T1_FIELD_NUM ( "UIDBase", uid_base )
T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset )
T1_FIELD_NUM ( "FDBytes", fd_bytes )
T1_FIELD_NUM ( "GDBytes", gd_bytes )
T1_FIELD_NUM ( "CIDCount", cid_count )
T1_FIELD_KEY ( "CIDFontName", cid_font_name, 0 )
T1_FIELD_NUM ( "CIDFontVersion", cid_version, 0 )
T1_FIELD_NUM ( "CIDFontType", cid_font_type, 0 )
T1_FIELD_STRING( "Registry", registry, 0 )
T1_FIELD_STRING( "Ordering", ordering, 0 )
T1_FIELD_NUM ( "Supplement", supplement, 0 )
T1_FIELD_NUM ( "UIDBase", uid_base, 0 )
T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset, 0 )
T1_FIELD_NUM ( "FDBytes", fd_bytes, 0 )
T1_FIELD_NUM ( "GDBytes", gd_bytes, 0 )
T1_FIELD_NUM ( "CIDCount", cid_count, 0 )
#undef FT_STRUCTURE
@ -39,15 +39,15 @@
#undef T1CODE
#define T1CODE T1_FIELD_LOCATION_FONT_INFO
T1_FIELD_STRING( "version", version )
T1_FIELD_STRING( "Notice", notice )
T1_FIELD_STRING( "FullName", full_name )
T1_FIELD_STRING( "FamilyName", family_name )
T1_FIELD_STRING( "Weight", weight )
T1_FIELD_NUM ( "ItalicAngle", italic_angle )
T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch )
T1_FIELD_NUM ( "UnderlinePosition", underline_position )
T1_FIELD_NUM ( "UnderlineThickness", underline_thickness )
T1_FIELD_STRING( "version", version, 0 )
T1_FIELD_STRING( "Notice", notice, 0 )
T1_FIELD_STRING( "FullName", full_name, 0 )
T1_FIELD_STRING( "FamilyName", family_name, 0 )
T1_FIELD_STRING( "Weight", weight, 0 )
T1_FIELD_NUM ( "ItalicAngle", italic_angle, 0 )
T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, 0 )
T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 )
T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 )
#undef FT_STRUCTURE
@ -55,15 +55,15 @@
#undef T1CODE
#define T1CODE T1_FIELD_LOCATION_FONT_DICT
T1_FIELD_NUM ( "PaintType", paint_type )
T1_FIELD_NUM ( "FontType", font_type )
T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset )
T1_FIELD_NUM ( "SDBytes", sd_bytes )
T1_FIELD_NUM ( "SubrCount", num_subrs )
T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar )
T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold )
T1_FIELD_FIXED( "ExpansionFactor", expansion_factor )
T1_FIELD_FIXED( "StrokeWidth", stroke_width )
T1_FIELD_NUM ( "PaintType", paint_type, 0 )
T1_FIELD_NUM ( "FontType", font_type, 0 )
T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset, 0 )
T1_FIELD_NUM ( "SDBytes", sd_bytes, 0 )
T1_FIELD_NUM ( "SubrCount", num_subrs, 0 )
T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar, 0 )
T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold, 0 )
T1_FIELD_FIXED( "ExpansionFactor", expansion_factor, 0 )
T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 )
#undef FT_STRUCTURE
@ -71,33 +71,33 @@
#undef T1CODE
#define T1CODE T1_FIELD_LOCATION_PRIVATE
T1_FIELD_NUM ( "UniqueID", unique_id )
T1_FIELD_NUM ( "lenIV", lenIV )
T1_FIELD_NUM ( "LanguageGroup", language_group )
T1_FIELD_NUM ( "password", password )
T1_FIELD_NUM ( "UniqueID", unique_id, 0 )
T1_FIELD_NUM ( "lenIV", lenIV, 0 )
T1_FIELD_NUM ( "LanguageGroup", language_group, 0 )
T1_FIELD_NUM ( "password", password, 0 )
T1_FIELD_FIXED_1000( "BlueScale", blue_scale )
T1_FIELD_NUM ( "BlueShift", blue_shift )
T1_FIELD_NUM ( "BlueFuzz", blue_fuzz )
T1_FIELD_FIXED_1000( "BlueScale", blue_scale, 0 )
T1_FIELD_NUM ( "BlueShift", blue_shift, 0 )
T1_FIELD_NUM ( "BlueFuzz", blue_fuzz, 0 )
T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 )
T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 )
T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 )
T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 )
T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14, 0 )
T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10, 0 )
T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14, 0 )
T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, 0 )
T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 )
T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 )
T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 )
T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1, 0 )
T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1, 0 )
T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2, 0 )
T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 )
T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 )
T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, 0 )
T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, 0 )
#undef FT_STRUCTURE
#define FT_STRUCTURE FT_BBox
#undef T1CODE
#define T1CODE T1_FIELD_LOCATION_BBOX
T1_FIELD_BBOX( "FontBBox", xMin )
T1_FIELD_BBOX( "FontBBox", xMin, 0 )
/* END */

View File

@ -554,6 +554,28 @@
}
static FT_ULong
ft_gzip_get_uncompressed_size( FT_Stream stream )
{
FT_Error error;
FT_ULong old_pos;
FT_ULong result = 0;
old_pos = stream->pos;
if ( !FT_Stream_Seek( stream, stream->size - 4 ) )
{
result = (FT_ULong)FT_Stream_ReadLong( stream, &error );
if ( error )
result = 0;
FT_Stream_Seek( stream, old_pos );
}
return result;
}
FT_EXPORT_DEF( FT_Error )
FT_Stream_OpenGzip( FT_Stream stream,
FT_Stream source )
@ -586,6 +608,52 @@
stream->descriptor.pointer = zip;
}
/*
* We use the following trick to try to dramatically improve the
* performance while dealing with small files. If the original stream
* size is less than a certain threshold, we try to load the whole font
* file into memory. This saves us from using the 32KB buffer needed
* to inflate the file, plus the two 4KB intermediate input/output
* buffers used in the `FT_GZipFile' structure.
*/
{
FT_ULong zip_size = ft_gzip_get_uncompressed_size( source );
if ( zip_size != 0 && zip_size < 40 * 1024 )
{
FT_Byte* zip_buff;
if ( !FT_ALLOC( zip_buff, zip_size ) )
{
FT_ULong count;
count = ft_gzip_file_io( zip, 0, zip_buff, zip_size );
if ( count == zip_size )
{
ft_gzip_file_done( zip );
FT_FREE( zip );
stream->descriptor.pointer = NULL;
stream->size = zip_size;
stream->pos = 0;
stream->base = zip_buff;
stream->read = NULL;
stream->close = ft_gzip_stream_close;
goto Exit;
}
ft_gzip_file_io( zip, 0, NULL, 0 );
FT_FREE( zip_buff );
}
error = 0;
}
}
stream->size = 0x7FFFFFFFL; /* don't know the real size! */
stream->pos = 0;
stream->base = 0;

View File

@ -131,6 +131,9 @@ uIntf *v /* working area: values in order of bit length */
uInt z; /* number of entries in current table */
/* Make comiler happy */
r.base = 0;
/* Generate counts for each bit length */
p = c;
#define C0 *p++ = 0;

View File

@ -4,7 +4,7 @@
/* */
/* FreeType's OpenType validation module implementation (body). */
/* */
/* Copyright 2004, 2005 by */
/* Copyright 2004, 2005, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -39,10 +39,10 @@
static FT_Error
otv_load_table( FT_Face face,
FT_Tag tag,
FT_Byte* *table,
FT_ULong *table_len )
otv_load_table( FT_Face face,
FT_Tag tag,
FT_Byte* volatile* table,
FT_ULong* table_len )
{
FT_Error error;
FT_Memory memory = FT_FACE_MEMORY( face );
@ -65,18 +65,22 @@
static FT_Error
otv_validate( FT_Face face,
FT_UInt ot_flags,
FT_Bytes *ot_base,
FT_Bytes *ot_gdef,
FT_Bytes *ot_gpos,
FT_Bytes *ot_gsub,
FT_Bytes *ot_jstf )
otv_validate( FT_Face volatile face,
FT_UInt ot_flags,
FT_Bytes *ot_base,
FT_Bytes *ot_gdef,
FT_Bytes *ot_gpos,
FT_Bytes *ot_gsub,
FT_Bytes *ot_jstf )
{
FT_Error error = OTV_Err_Ok;
FT_Byte *base, *gdef, *gpos, *gsub, *jstf;
FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf;
FT_ValidatorRec valid;
FT_Error error = OTV_Err_Ok;
FT_Byte* volatile base;
FT_Byte* volatile gdef;
FT_Byte* volatile gpos;
FT_Byte* volatile gsub;
FT_Byte* volatile jstf;
FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf;
FT_ValidatorRec volatile valid;
base = gdef = gpos = gsub = jstf = NULL;
@ -124,7 +128,7 @@
if ( base )
{
ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT );
if ( ft_validator_run( &valid ) == 0 )
if ( ft_setjmp( valid.jump_buffer ) == 0 )
otv_BASE_validate( base, &valid );
error = valid.error;
if ( error )
@ -134,7 +138,7 @@
if ( gpos )
{
ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT );
if ( ft_validator_run( &valid ) == 0 )
if ( ft_setjmp( valid.jump_buffer ) == 0 )
otv_GPOS_validate( gpos, face->num_glyphs, &valid );
error = valid.error;
if ( error )
@ -144,7 +148,7 @@
if ( gsub )
{
ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT );
if ( ft_validator_run( &valid ) == 0 )
if ( ft_setjmp( valid.jump_buffer ) == 0 )
otv_GSUB_validate( gsub, face->num_glyphs, &valid );
error = valid.error;
if ( error )
@ -154,7 +158,7 @@
if ( gdef )
{
ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT );
if ( ft_validator_run( &valid ) == 0 )
if ( ft_setjmp( valid.jump_buffer ) == 0 )
otv_GDEF_validate( gdef, gsub, gpos, &valid );
error = valid.error;
if ( error )
@ -164,7 +168,7 @@
if ( jstf )
{
ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT );
if ( ft_validator_run( &valid ) == 0 )
if ( ft_setjmp( valid.jump_buffer ) == 0 )
otv_JSTF_validate( jstf, gsub, gpos, face->num_glyphs, &valid );
error = valid.error;
if ( error )
@ -194,14 +198,14 @@
static
const FT_Service_OTvalidateRec otvalid_interface =
const FT_Service_OTvalidateRec otvalid_interface =
{
otv_validate
};
static
const FT_ServiceDescRec otvalid_services[] =
const FT_ServiceDescRec otvalid_services[] =
{
{ FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface },
{ NULL, NULL }

View File

@ -13,11 +13,11 @@ Glyph images are loaded into memory only on demand, thus leading to a small
memory footprint.
Informations on the PCF font format can only be worked out from
``pcfread.c'', and ``pcfwrite.c'', to be found, for instance, in the XFree86
`pcfread.c', and `pcfwrite.c', to be found, for instance, in the XFree86
(www.xfree86.org) source tree (xc/lib/font/bitmap/).
Many good bitmap fonts in bdf format come with XFree86: they can be
compiled into the pcf format using the ``bdftopcf'' utility.
compiled into the pcf format using the `bdftopcf' utility.
Supported hardware
@ -46,11 +46,11 @@ client application the work of interpreting them. For instance:
FT_New_Face( library,..., &face );
pcfface = (PCF_Public_Face)face;
if ((pcfface->charset_registry == "ISO10646") &&
if ((pcfface->charset_registry == "ISO10646") &&
(pcfface->charset_encoding) == "1")) [..]
Thus the driver always export ``ft_encoding_none'' as
Thus the driver always export `ft_encoding_none' as
face->charmap.encoding. FT_Get_Char_Index() behavior is unmodified, that
is, it converts the ULong value given as argument into the corresponding
glyph number.

View File

@ -4,7 +4,7 @@
# Copyright 2000, 2006 by
# Francesco Zappa Nardelli
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights

View File

@ -203,19 +203,23 @@ THE SOFTWARE.
/* free properties */
{
PCF_Property prop = face->properties;
PCF_Property prop;
FT_Int i;
for ( i = 0; i < face->nprops; i++ )
if ( face->properties )
{
prop = &face->properties[i];
for ( i = 0; i < face->nprops; i++ )
{
prop = &face->properties[i];
FT_FREE( prop->name );
if ( prop->isString )
FT_FREE( prop->value.atom );
if ( prop ) {
FT_FREE( prop->name );
if ( prop->isString )
FT_FREE( prop->value.atom );
}
}
}
FT_FREE( face->properties );
}
@ -258,6 +262,8 @@ THE SOFTWARE.
FT_Error error2;
PCF_Face_Done( pcfface );
/* this didn't work, try gzip support! */
error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream );
if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature )
@ -357,6 +363,7 @@ THE SOFTWARE.
Fail:
FT_TRACE2(( "[not a valid PCF file]\n" ));
PCF_Face_Done( pcfface );
error = PCF_Err_Unknown_File_Format; /* error */
goto Exit;
}
@ -435,7 +442,7 @@ THE SOFTWARE.
FT_TRACE4(( "load_glyph %d ---", glyph_index ));
if ( !face )
if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs )
{
error = PCF_Err_Invalid_Argument;
goto Exit;

View File

@ -2,7 +2,7 @@
FreeType font driver for pcf fonts
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 by
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by
Francesco Zappa Nardelli
Permission is hereby granted, free of charge, to any person obtaining a copy
@ -102,7 +102,8 @@ THE SOFTWARE.
return PCF_Err_Cannot_Open_Resource;
if ( toc->version != PCF_FILE_VERSION ||
toc->count > FT_ARRAY_MAX( face->toc.tables ) )
toc->count > FT_ARRAY_MAX( face->toc.tables ) ||
toc->count == 0 )
return PCF_Err_Invalid_File_Format;
if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) )
@ -116,6 +117,41 @@ THE SOFTWARE.
tables++;
}
/* Sort tables and check for overlaps. Because they are almost */
/* always ordered already, an in-place bubble sort with simultaneous */
/* boundary checking seems appropriate. */
tables = face->toc.tables;
for ( n = 0; n < toc->count - 1; n++ )
{
FT_UInt i, have_change;
have_change = 0;
for ( i = 0; i < toc->count - 1 - n; i++ )
{
PCF_TableRec tmp;
if ( tables[i].offset > tables[i + 1].offset )
{
tmp = tables[i];
tables[i] = tables[i + 1];
tables[i + 1] = tmp;
have_change = 1;
}
if ( ( tables[i].size > tables[i + 1].offset ) ||
( tables[i].offset > tables[i + 1].offset - tables[i].size ) )
return PCF_Err_Invalid_Offset;
}
if ( !have_change )
break;
}
#if defined( FT_DEBUG_LEVEL_TRACE )
{
@ -130,7 +166,8 @@ THE SOFTWARE.
tables = face->toc.tables;
for ( i = 0; i < toc->count; i++ )
{
for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ )
for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] );
j++ )
if ( tables[i].type == (FT_UInt)( 1 << j ) )
name = tableNames[j];
@ -153,13 +190,15 @@ THE SOFTWARE.
}
#define PCF_METRIC_SIZE 12
static
const FT_Frame_Field pcf_metric_header[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE PCF_MetricRec
FT_FRAME_START( 12 ),
FT_FRAME_START( PCF_METRIC_SIZE ),
FT_FRAME_SHORT_LE( leftSideBearing ),
FT_FRAME_SHORT_LE( rightSideBearing ),
FT_FRAME_SHORT_LE( characterWidth ),
@ -176,7 +215,7 @@ THE SOFTWARE.
#undef FT_STRUCTURE
#define FT_STRUCTURE PCF_MetricRec
FT_FRAME_START( 12 ),
FT_FRAME_START( PCF_METRIC_SIZE ),
FT_FRAME_SHORT( leftSideBearing ),
FT_FRAME_SHORT( rightSideBearing ),
FT_FRAME_SHORT( characterWidth ),
@ -187,13 +226,15 @@ THE SOFTWARE.
};
#define PCF_COMPRESSED_METRIC_SIZE 5
static
const FT_Frame_Field pcf_compressed_metric_header[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE PCF_Compressed_MetricRec
FT_FRAME_START( 5 ),
FT_FRAME_START( PCF_COMPRESSED_METRIC_SIZE ),
FT_FRAME_BYTE( leftSideBearing ),
FT_FRAME_BYTE( rightSideBearing ),
FT_FRAME_BYTE( characterWidth ),
@ -221,7 +262,7 @@ THE SOFTWARE.
? pcf_metric_msb_header
: pcf_metric_header;
/* the following sets 'error' but doesn't return in case of failure */
/* the following sets `error' but doesn't return in case of failure */
(void)FT_STREAM_READ_FIELDS( fields, metric );
}
else
@ -261,23 +302,26 @@ THE SOFTWARE.
for ( i = 0; i < ntables; i++ )
if ( tables[i].type == type )
{
if ( stream->pos > tables[i].offset ) {
if ( stream->pos > tables[i].offset )
{
error = PCF_Err_Invalid_Stream_Skip;
goto Fail;
}
if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) {
if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) )
{
error = PCF_Err_Invalid_Stream_Skip;
goto Fail;
}
*asize = tables[i].size; /* unused - to be removed */
*asize = tables[i].size;
*aformat = tables[i].format;
return PCF_Err_Ok;
}
Fail:
*asize = 0;
return error;
}
@ -298,13 +342,15 @@ THE SOFTWARE.
}
#define PCF_PROPERTY_SIZE 9
static
const FT_Frame_Field pcf_property_header[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE PCF_ParsePropertyRec
FT_FRAME_START( 9 ),
FT_FRAME_START( PCF_PROPERTY_SIZE ),
FT_FRAME_LONG_LE( name ),
FT_FRAME_BYTE ( isString ),
FT_FRAME_LONG_LE( value ),
@ -318,7 +364,7 @@ THE SOFTWARE.
#undef FT_STRUCTURE
#define FT_STRUCTURE PCF_ParsePropertyRec
FT_FRAME_START( 9 ),
FT_FRAME_START( PCF_PROPERTY_SIZE ),
FT_FRAME_LONG( name ),
FT_FRAME_BYTE( isString ),
FT_FRAME_LONG( value ),
@ -353,8 +399,8 @@ THE SOFTWARE.
PCF_Face face )
{
PCF_ParseProperty props = 0;
PCF_Property properties = 0;
FT_Int nprops, i;
PCF_Property properties;
FT_UInt nprops, i;
FT_ULong format, size;
FT_Error error;
FT_Memory memory = FT_FACE(face)->memory;
@ -390,6 +436,15 @@ THE SOFTWARE.
FT_TRACE4(( " nprop = %d\n", nprops ));
/* rough estimate */
if ( nprops > size / PCF_PROPERTY_SIZE )
{
error = PCF_Err_Invalid_Table;
goto Bail;
}
face->nprops = nprops;
if ( FT_NEW_ARRAY( props, nprops ) )
goto Bail;
@ -427,6 +482,13 @@ THE SOFTWARE.
FT_TRACE4(( " string_size = %ld\n", string_size ));
/* rough estimate */
if ( string_size > size - nprops * PCF_PROPERTY_SIZE )
{
error = PCF_Err_Invalid_Table;
goto Bail;
}
if ( FT_NEW_ARRAY( strings, string_size ) )
goto Bail;
@ -437,13 +499,24 @@ THE SOFTWARE.
if ( FT_NEW_ARRAY( properties, nprops ) )
goto Bail;
face->properties = properties;
for ( i = 0; i < nprops; i++ )
{
/* XXX: make atom */
if ( FT_NEW_ARRAY( properties[i].name,
ft_strlen( strings + props[i].name ) + 1 ) )
FT_Long name_offset = props[i].name;
if ( ( name_offset < 0 ) ||
( (FT_ULong)name_offset > string_size ) )
{
error = PCF_Err_Invalid_Offset;
goto Bail;
ft_strcpy( properties[i].name, strings + props[i].name );
}
if ( FT_NEW_ARRAY( properties[i].name,
ft_strlen( strings + name_offset ) + 1 ) )
goto Bail;
ft_strcpy( properties[i].name, strings + name_offset );
FT_TRACE4(( " %s:", properties[i].name ));
@ -451,8 +524,18 @@ THE SOFTWARE.
if ( props[i].isString )
{
FT_Long value_offset = props[i].value;
if ( ( value_offset < 0 ) ||
( (FT_ULong)value_offset > string_size ) )
{
error = PCF_Err_Invalid_Offset;
goto Bail;
}
if ( FT_NEW_ARRAY( properties[i].value.atom,
ft_strlen( strings + props[i].value ) + 1 ) )
ft_strlen( strings + value_offset ) + 1 ) )
goto Bail;
ft_strcpy( properties[i].value.atom, strings + props[i].value );
@ -466,13 +549,7 @@ THE SOFTWARE.
}
}
face->properties = properties;
face->nprops = nprops;
FT_FREE( props );
FT_FREE( strings );
return PCF_Err_Ok;
error = PCF_Err_Ok;
Bail:
FT_FREE( props );
@ -488,11 +565,9 @@ THE SOFTWARE.
{
FT_Error error = PCF_Err_Ok;
FT_Memory memory = FT_FACE(face)->memory;
FT_ULong format = 0;
FT_ULong size = 0;
FT_ULong format, size;
PCF_Metric metrics = 0;
int i;
int nmetrics = -1;
FT_ULong nmetrics, i;
error = pcf_seek_to_table_type( stream,
@ -504,7 +579,8 @@ THE SOFTWARE.
if ( error )
return error;
error = FT_READ_ULONG_LE( format );
if ( FT_READ_ULONG_LE( format ) )
goto Bail;
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
!PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) )
@ -524,16 +600,30 @@ THE SOFTWARE.
else
(void)FT_READ_USHORT_LE( nmetrics );
}
if ( error || nmetrics == -1 )
if ( error )
return PCF_Err_Invalid_File_Format;
face->nmetrics = nmetrics;
FT_TRACE4(( "pcf_get_metrics:\n" ));
FT_TRACE4(( " number of metrics: %d\n", nmetrics ));
/* rough estimate */
if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
{
if ( nmetrics > size / PCF_METRIC_SIZE )
return PCF_Err_Invalid_Table;
}
else
{
if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE )
return PCF_Err_Invalid_Table;
}
if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
return PCF_Err_Out_Of_Memory;
FT_TRACE4(( "pcf_get_metrics:\n" ));
metrics = face->metrics;
for ( i = 0; i < nmetrics; i++ )
{
@ -541,7 +631,7 @@ THE SOFTWARE.
metrics[i].bits = 0;
FT_TRACE4(( " idx %d: width=%d, "
FT_TRACE5(( " idx %d: width=%d, "
"lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",
i,
( metrics + i )->characterWidth,
@ -557,6 +647,8 @@ THE SOFTWARE.
if ( error )
FT_FREE( face->metrics );
Bail:
return error;
}
@ -597,14 +689,16 @@ THE SOFTWARE.
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
return PCF_Err_Invalid_File_Format;
FT_TRACE4(( "pcf_get_bitmaps:\n" ));
FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps ));
if ( nbitmaps != face->nmetrics )
return PCF_Err_Invalid_File_Format;
if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
return error;
FT_TRACE4(( "pcf_get_bitmaps:\n" ));
for ( i = 0; i < nbitmaps; i++ )
{
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
@ -612,7 +706,7 @@ THE SOFTWARE.
else
(void)FT_READ_LONG_LE( offsets[i] );
FT_TRACE4(( " bitmap %d: offset %ld (0x%lX)\n",
FT_TRACE5(( " bitmap %d: offset %ld (0x%lX)\n",
i, offsets[i], offsets[i] ));
}
if ( error )
@ -640,15 +734,22 @@ THE SOFTWARE.
FT_UNUSED( sizebitmaps ); /* only used for debugging */
for ( i = 0; i < nbitmaps; i++ )
face->metrics[i].bits = stream->pos + offsets[i];
{
/* rough estimate */
if ( ( offsets[i] < 0 ) ||
( (FT_ULong)offsets[i] > size ) )
{
FT_ERROR(( "pcf_get_bitmaps:"));
FT_ERROR(( " invalid offset to bitmap data of glyph %d\n", i ));
}
else
face->metrics[i].bits = stream->pos + offsets[i];
}
face->bitmapsFormat = format;
FT_FREE ( offsets );
return error;
Bail:
FT_FREE ( offsets );
FT_FREE( offsets );
return error;
}
@ -734,7 +835,7 @@ THE SOFTWARE.
tmpEncoding[j].glyph = (FT_Short)encodingOffset;
FT_TRACE4(( " code %d (0x%04X): idx %d\n",
FT_TRACE5(( " code %d (0x%04X): idx %d\n",
tmpEncoding[j].enc, tmpEncoding[j].enc,
tmpEncoding[j].glyph ));
@ -828,7 +929,8 @@ THE SOFTWARE.
if ( error )
goto Bail;
error = FT_READ_ULONG_LE( format );
if ( FT_READ_ULONG_LE( format ) )
goto Bail;
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
!PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
@ -876,7 +978,6 @@ THE SOFTWARE.
accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */
accel->ink_maxbounds = accel->maxbounds;
}
return error;
Bail:
return error;
@ -1082,11 +1183,12 @@ THE SOFTWARE.
else
root->family_name = NULL;
/* Note: We shift all glyph indices by +1 since we must
/*
* Note: We shift all glyph indices by +1 since we must
* respect the convention that glyph 0 always corresponds
* to the "missing glyph".
* to the `missing glyph'.
*
* This implies bumping the number of "available" glyphs by 1.
* This implies bumping the number of `available' glyphs by 1.
*/
root->num_glyphs = face->nmetrics + 1;
@ -1171,7 +1273,7 @@ THE SOFTWARE.
Exit:
if ( error )
{
/* this is done to respect the behaviour of the original */
/* This is done to respect the behaviour of the original */
/* PCF font driver. */
error = PCF_Err_Invalid_File_Format;
}

View File

@ -2,7 +2,11 @@
Copyright 1990, 1994, 1998 The Open Group
All Rights Reserved.
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
@ -43,12 +47,12 @@ in this Software without prior written authorization from The Open Group.
for ( ; --nbytes >= 0; buf++ )
{
unsigned int val = *buf;
val = ( ( val >> 1 ) & 0x55 ) | ( ( val << 1 ) & 0xAA );
val = ( ( val >> 2 ) & 0x33 ) | ( ( val << 2 ) & 0xCC );
val = ( ( val >> 4 ) & 0x0F ) | ( ( val << 4 ) & 0xF0 );
*buf = (unsigned char)val;
}
}

View File

@ -13,7 +13,7 @@ UseFreeTypeHeaders ;
if $(FT2_MULTI)
{
_sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap pfrsbit ;
_sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap pfrsbit ;
}
else
{

View File

@ -16,7 +16,7 @@
/***************************************************************************/
#include "pfrcmap.h"
#include "pfrcmap.h"
#include "pfrobjs.h"
#include FT_INTERNAL_DEBUG_H
@ -29,12 +29,12 @@
cmap->num_chars = face->phy_font.num_chars;
cmap->chars = face->phy_font.chars;
/* just for safety, check that the character entries are correctly */
/* sorted in increasing character code order */
{
FT_UInt n;
for ( n = 1; n < cmap->num_chars; n++ )
{
@ -42,7 +42,7 @@
FT_ASSERT( 0 );
}
}
return 0;
}

View File

@ -31,7 +31,7 @@ FT_BEGIN_HEADER
FT_CMapRec cmap;
FT_UInt num_chars;
PFR_Char chars;
} PFR_CMapRec, *PFR_CMap;

View File

@ -54,11 +54,11 @@ FT_BEGIN_HEADER
{
FT_UInt type;
PFR_ExtraItem_ParseFunc parser;
} PFR_ExtraItemRec;
typedef const struct PFR_ExtraItemRec_* PFR_ExtraItem;
FT_LOCAL( FT_Error )
pfr_extra_items_skip( FT_Byte* *pp,
@ -109,7 +109,7 @@ FT_BEGIN_HEADER
FT_Memory memory );
/* */
FT_END_HEADER
#endif /* __PFRLOAD_H__ */

View File

@ -4,7 +4,7 @@
/* */
/* FreeType PFR object methods (body). */
/* */
/* Copyright 2002, 2003, 2004, 2005, 2006 by */
/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -122,15 +122,29 @@
if ( error )
goto Exit;
/* now, set-up all root face fields */
/* now set up all root face fields */
{
PFR_PhyFont phy_font = &face->phy_font;
pfrface->face_index = face_index;
pfrface->num_glyphs = phy_font->num_chars;
pfrface->num_glyphs = phy_font->num_chars + 1;
pfrface->face_flags = FT_FACE_FLAG_SCALABLE;
/* if all characters point to the same gps_offset 0, we */
/* assume that the font only contains bitmaps */
{
FT_UInt nn;
for ( nn = 0; nn < phy_font->num_chars; nn++ )
if ( phy_font->chars[nn].gps_offset != 0 )
break;
if ( nn == phy_font->num_chars )
pfrface->face_flags = 0; /* not scalable */
}
if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 )
pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
@ -296,8 +310,11 @@
if ( gindex > 0 )
gindex--;
/* check that the glyph index is correct */
FT_ASSERT( gindex < face->phy_font.num_chars );
if ( !face || gindex >= face->phy_font.num_chars )
{
error = PFR_Err_Invalid_Argument;
goto Exit;
}
/* try to load an embedded bitmap */
if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 )
@ -476,13 +493,14 @@
goto Exit;
{
FT_UInt count = item->pair_count;
FT_UInt size = item->pair_size;
FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count );
FT_UInt probe = power * size;
FT_UInt extra = count - power;
FT_Byte* base = stream->cursor;
FT_Bool twobytes = FT_BOOL( item->flags & 1 );
FT_UInt count = item->pair_count;
FT_UInt size = item->pair_size;
FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count );
FT_UInt probe = power * size;
FT_UInt extra = count - power;
FT_Byte* base = stream->cursor;
FT_Bool twobytes = FT_BOOL( item->flags & 1 );
FT_Bool twobyte_adj = FT_BOOL( item->flags & 2 );
FT_Byte* p;
FT_UInt32 cpair;
@ -500,7 +518,13 @@
goto Found;
if ( cpair < pair )
{
if ( twobyte_adj )
p += 2;
else
p++;
base = p;
}
}
while ( probe > size )
@ -533,7 +557,7 @@
Found:
if ( item->flags & 2 )
if ( twobyte_adj )
value = FT_PEEK_SHORT( p );
else
value = p[0];

View File

@ -331,11 +331,53 @@
FT_UInt n )
{
FT_Byte* p;
FT_UInt r = 0;
FT_UInt r = 0;
FT_UInt w = 0;
FT_UInt pad = 0x01;
n *= 2;
for ( p = *cursor; r < n && p < limit; p++ )
#if 1
p = *cursor;
if ( n > (FT_UInt)( limit - p ) )
n = (FT_UInt)( limit - p );
/* we try to process two nibbles at a time to be as fast as possible */
for ( ; r < n; r++ )
{
FT_UInt c = p[r];
if ( IS_PS_SPACE( c ) )
continue;
if ( c OP 0x80 )
break;
c = ft_char_table[c & 0x7F];
if ( (unsigned)c >= 16 )
break;
pad = ( pad << 4 ) | c;
if ( pad & 0x100 )
{
buffer[w++] = (FT_Byte)pad;
pad = 0x01;
}
}
if ( pad != 0x01 )
buffer[w++] = (FT_Byte)( pad << 4 );
*cursor = p + r;
return w;
#else /* 0 */
for ( r = 0; r < n; r++ )
{
FT_Char c;
@ -348,10 +390,10 @@
c = ft_char_table[*p & 0x7f];
if ( c < 0 || c >= 16 )
if ( (unsigned)c >= 16 )
break;
if ( r % 2 )
if ( r & 1 )
{
*buffer = (FT_Byte)(*buffer + c);
buffer++;
@ -365,6 +407,9 @@
*cursor = p;
return ( r + 1 ) / 2;
#endif /* 0 */
}
@ -375,11 +420,32 @@
FT_UInt n,
FT_UShort* seed )
{
FT_Byte* p;
FT_UInt r;
FT_UShort s = *seed;
FT_Byte* p;
FT_UInt r;
FT_UInt s = *seed;
#if 1
p = *cursor;
if ( n > (FT_UInt)(limit - p) )
n = (FT_UInt)(limit - p);
for ( r = 0; r < n; r++ )
{
FT_UInt val = p[r];
FT_UInt b = ( val ^ ( s >> 8 ) );
s = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
buffer[r] = (FT_Byte) b;
}
*cursor = p + n;
*seed = (FT_UShort)s;
#else /* 0 */
for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
{
FT_Byte b = (FT_Byte)( *p ^ ( s >> 8 ) );
@ -388,10 +454,11 @@
s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
*buffer++ = b;
}
*cursor = p;
*seed = s;
#endif /* 0 */
return r;
}

View File

@ -63,42 +63,6 @@ FT_BEGIN_HEADER
FT_UShort* seed );
#define IS_PS_NEWLINE( ch ) \
( ( ch ) == '\r' || \
( ch ) == '\n' )
#define IS_PS_SPACE( ch ) \
( ( ch ) == ' ' || \
IS_PS_NEWLINE( ch ) || \
( ch ) == '\t' || \
( ch ) == '\f' || \
( ch ) == '\0' )
#define IS_PS_SPECIAL( ch ) \
( ( ch ) == '/' || \
( ch ) == '(' || \
( ch ) == ')' || \
( ch ) == '<' || \
( ch ) == '>' || \
( ch ) == '[' || \
( ch ) == ']' || \
( ch ) == '{' || \
( ch ) == '}' || \
( ch ) == '%' )
#define IS_PS_DELIM( ch ) \
( IS_PS_SPACE( ch ) || \
IS_PS_SPECIAL( ch ) )
#define IS_PS_DIGIT( ch ) ( ( ch ) >= '0' && ( ch ) <= '9' )
#define IS_PS_XDIGIT( ch ) \
( IS_PS_DIGIT( ( ch ) ) || \
( ( ch ) >= 'A' && ( ch ) <= 'F' ) || \
( ( ch ) >= 'a' && ( ch ) <= 'f' ) )
#define IS_PS_BASE85( ch ) ( ( ch ) >= '!' && ( ch ) <= 'u' )
FT_END_HEADER
#endif /* __PSCONV_H__ */

View File

@ -26,6 +26,16 @@
#include "psauxerr.h"
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_psobjs
/*************************************************************************/
/*************************************************************************/
/***** *****/
@ -118,7 +128,7 @@
}
/* copy elements and shift offsets */
if (old_base )
if ( old_base )
{
FT_MEM_COPY( table->block, old_base, table->capacity );
shift_elements( table, old_base );
@ -312,45 +322,94 @@
}
/* first character must be `(' */
#define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' )
static void
/* first character must be `('; */
/* *acur is positioned at the character after the closing `)' */
static FT_Error
skip_literal_string( FT_Byte* *acur,
FT_Byte* limit )
{
FT_Byte* cur = *acur;
FT_Int embed = 0;
FT_Byte* cur = *acur;
FT_Int embed = 0;
FT_Error error = PSaux_Err_Invalid_File_Format;
unsigned int i;
while ( cur < limit )
{
if ( *cur == '\\' )
cur++;
else if ( *cur == '(' )
FT_Byte c = *cur;
++cur;
if ( c == '\\' )
{
/* Red Book 3rd ed., section `Literal Text Strings', p. 29: */
/* A backslash can introduce three different types */
/* of escape sequences: */
/* - a special escaped char like \r, \n, etc. */
/* - a one-, two-, or three-digit octal number */
/* - none of the above in which case the backslash is ignored */
if ( cur == limit )
/* error (or to be ignored?) */
break;
switch ( *cur )
{
/* skip `special' escape */
case 'n':
case 'r':
case 't':
case 'b':
case 'f':
case '\\':
case '(':
case ')':
++cur;
break;
default:
/* skip octal escape or ignore backslash */
for ( i = 0; i < 3 && cur < limit; ++i )
{
if ( ! IS_OCTAL_DIGIT( *cur ) )
break;
++cur;
}
}
}
else if ( c == '(' )
embed++;
else if ( *cur == ')' )
else if ( c == ')' )
{
embed--;
if ( embed == 0 )
{
cur++;
error = PSaux_Err_Ok;
break;
}
}
cur++;
}
*acur = cur;
return error;
}
/* first character must be `<' */
static void
skip_string( PS_Parser parser )
static FT_Error
skip_string( FT_Byte* *acur,
FT_Byte* limit )
{
FT_Byte* cur = parser->cursor;
FT_Byte* limit = parser->limit;
FT_Byte* cur = *acur;
FT_Error err = PSaux_Err_Ok;
while ( ++cur < limit )
@ -367,12 +426,72 @@
if ( cur < limit && *cur != '>' )
{
FT_ERROR(( "skip_string: missing closing delimiter `>'\n" ));
parser->error = PSaux_Err_Invalid_File_Format;
err = PSaux_Err_Invalid_File_Format;
}
else
cur++;
parser->cursor = cur;
*acur = cur;
return err;
}
/* first character must be the opening brace that */
/* starts the procedure */
/* NB: [ and ] need not match: */
/* `/foo {[} def' is a valid PostScript fragment, */
/* even within a Type1 font */
static FT_Error
skip_procedure( FT_Byte* *acur,
FT_Byte* limit )
{
FT_Byte* cur;
FT_Int embed = 0;
FT_Error error = PSaux_Err_Ok;
FT_ASSERT( **acur == '{' );
for ( cur = *acur; cur < limit && error == PSaux_Err_Ok; ++cur )
{
switch ( *cur )
{
case '{':
++embed;
break;
case '}':
--embed;
if ( embed == 0 )
{
++cur;
goto end;
}
break;
case '(':
error = skip_literal_string( &cur, limit );
break;
case '<':
error = skip_string( &cur, limit );
break;
case '%':
skip_comment( &cur, limit );
break;
}
}
end:
if ( embed != 0 )
error = PSaux_Err_Invalid_File_Format;
*acur = cur;
return error;
}
@ -393,6 +512,7 @@
FT_Byte* cur = parser->cursor;
FT_Byte* limit = parser->limit;
FT_Error error = PSaux_Err_Ok;
skip_spaces( &cur, limit ); /* this also skips comments */
@ -400,16 +520,23 @@
goto Exit;
/* self-delimiting, single-character tokens */
if ( *cur == '[' || *cur == ']' ||
*cur == '{' || *cur == '}' )
if ( *cur == '[' || *cur == ']' )
{
cur++;
goto Exit;
}
/* skip balanced expressions (procedures and strings) */
if ( *cur == '{' ) /* {...} */
{
error = skip_procedure( &cur, limit );
goto Exit;
}
if ( *cur == '(' ) /* (...) */
{
skip_literal_string( &cur, limit );
error = skip_literal_string( &cur, limit );
goto Exit;
}
@ -419,11 +546,11 @@
{
cur++;
cur++;
goto Exit;
}
parser->cursor = cur;
skip_string( parser );
return;
else
error = skip_string( &cur, limit );
goto Exit;
}
if ( *cur == '>' )
@ -433,7 +560,7 @@
{
FT_ERROR(( "ps_parser_skip_PS_token: "
"unexpected closing delimiter `>'\n" ));
parser->error = PSaux_Err_Invalid_File_Format;
error = PSaux_Err_Invalid_File_Format;
goto Exit;
}
cur++;
@ -446,20 +573,27 @@
/* anything else */
while ( cur < limit )
{
if ( *cur == ')' )
{
FT_ERROR(( "ps_parser_skip_PS_token: "
"unexpected closing delimiter `)'\n" ));
parser->error = PSaux_Err_Invalid_File_Format;
goto Exit;
}
else if ( IS_PS_DELIM( *cur ) )
/* *cur might be invalid (e.g., ')' or '}'), but this */
/* is handled by the test `cur == parser->cursor' below */
if ( IS_PS_DELIM( *cur ) )
break;
cur++;
}
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",
*cur ));
error = PSaux_Err_Invalid_File_Format;
}
FT_ASSERT( parser->error == PSaux_Err_Ok );
parser->error = error;
parser->cursor = cur;
}
@ -480,7 +614,6 @@
{
FT_Byte* cur;
FT_Byte* limit;
FT_Byte starter, ender;
FT_Int embed;
@ -503,26 +636,27 @@
case '(':
token->type = T1_TOKEN_TYPE_STRING;
token->start = cur;
skip_literal_string( &cur, limit );
if ( cur < limit )
if ( skip_literal_string( &cur, limit ) == PSaux_Err_Ok )
token->limit = cur;
break;
/************* check for programs/array *****************/
case '{':
token->type = T1_TOKEN_TYPE_ARRAY;
ender = '}';
goto Lookup_Ender;
token->type = T1_TOKEN_TYPE_ARRAY;
token->start = cur;
if ( skip_procedure( &cur, limit ) == PSaux_Err_Ok )
token->limit = cur;
break;
/************* check for table/array ********************/
/* XXX: in theory we should also look for "<<" */
/* since this is semantically equivalent to "["; */
/* in practice it doesn't matter (?) */
case '[':
token->type = T1_TOKEN_TYPE_ARRAY;
ender = ']';
/* fall through */
Lookup_Ender:
token->type = T1_TOKEN_TYPE_ARRAY;
embed = 1;
starter = *cur;
token->start = cur++;
/* we need this to catch `[ ]' */
@ -532,9 +666,11 @@
while ( cur < limit && !parser->error )
{
if ( *cur == starter )
/* XXX: this is wrong because it does not */
/* skip comments, procedures, and strings */
if ( *cur == '[' )
embed++;
else if ( *cur == ender )
else if ( *cur == ']' )
{
embed--;
if ( embed <= 0 )
@ -555,7 +691,7 @@
/* ************ otherwise, it is any token **************/
default:
token->start = cur;
token->type = T1_TOKEN_TYPE_ANY;
token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY );
ps_parser_skip_PS_token( parser );
cur = parser->cursor;
if ( !parser->error )
@ -572,6 +708,9 @@
}
/* NB: `tokens' can be NULL if we only want to count */
/* the number of array elements */
FT_LOCAL_DEF( void )
ps_parser_to_token_array( PS_Parser parser,
T1_Token tokens,
@ -607,7 +746,7 @@
if ( !token.type )
break;
if ( cur < limit )
if ( tokens != NULL && cur < limit )
*cur = token;
cur++;
@ -622,6 +761,8 @@
/* first character must be a delimiter or a part of a number */
/* NB: `coords' can be NULL if we just want to skip the */
/* array; in this case we ignore `max_coords' */
static FT_Int
ps_tocoordarray( FT_Byte* *acur,
@ -654,21 +795,26 @@
/* now, read the coordinates */
while ( cur < limit )
{
FT_Short dummy;
/* skip whitespace in front of data */
skip_spaces( &cur, limit );
if ( cur >= limit )
goto Exit;
if ( count >= max_coords )
if ( coords != NULL && count >= max_coords )
break;
if ( c == ender )
if ( *cur == ender )
{
cur++;
break;
}
coords[count] =
/* call PS_Conv_ToFixed() even if coords == NULL */
/* to properly parse number at `cur' */
*( coords != NULL ? &coords[count] : &dummy ) =
(FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );
count++;
@ -683,6 +829,8 @@
/* first character must be a delimiter or a part of a number */
/* NB: `values' can be NULL if we just want to skip the */
/* array in this case we ignore `max_values' */
static FT_Int
ps_tofixedarray( FT_Byte* *acur,
@ -716,21 +864,27 @@
/* now, read the values */
while ( cur < limit )
{
FT_Fixed dummy;
/* skip whitespace in front of data */
skip_spaces( &cur, limit );
if ( cur >= limit )
goto Exit;
if ( count >= max_values )
if ( values != NULL && count >= max_values )
break;
if ( c == ender )
if ( *cur == ender )
{
cur++;
break;
}
values[count] = PS_Conv_ToFixed( &cur, limit, power_ten );
/* call PS_Conv_ToFixed() even if coords == NULL */
/* to properly parse number at `cur' */
*( values != NULL ? &values[count] : &dummy ) =
PS_Conv_ToFixed( &cur, limit, power_ten );
count++;
if ( !ender )
@ -957,18 +1111,41 @@
if ( cur >= limit )
break;
if ( field->type == T1_FIELD_TYPE_KEY )
/* we allow both a string or a name */
/* for cases like /FontName (foo) def */
if ( token.type == T1_TOKEN_TYPE_KEY )
{
/* don't include leading `/' */
len--;
cur++;
}
else
else if ( token.type == T1_TOKEN_TYPE_STRING )
{
/* don't include delimiting parentheses */
/* don't include delimiting parentheses */
/* XXX we don't handle <<...>> here */
/* XXX should we convert octal escapes? */
/* if so, what encoding should we use? */
cur++;
len -= 2;
}
else
{
FT_ERROR(( "ps_parser_load_field: expected a name or string "
"but found token of type %d instead\n",
token.type ));
error = PSaux_Err_Invalid_File_Format;
goto Exit;
}
/* for this to work (FT_String**)q must have been */
/* initialized to NULL */
if ( *(FT_String**)q != NULL )
{
FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n",
field->ident ));
FT_FREE( *(FT_String**)q );
*(FT_String**)q = NULL;
}
if ( FT_ALLOC( string, len + 1 ) )
goto Exit;
@ -1038,11 +1215,10 @@
T1_FieldRec fieldrec = *(T1_Field)field;
#if 1
fieldrec.type = T1_FIELD_TYPE_INTEGER;
if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY )
if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY ||
field->type == T1_FIELD_TYPE_BBOX )
fieldrec.type = T1_FIELD_TYPE_FIXED;
#endif
ps_parser_to_token_array( parser, elements,
T1_MAX_TABLE_ELEMENTS, &num_elements );
@ -1057,9 +1233,10 @@
old_cursor = parser->cursor;
old_limit = parser->limit;
/* we store the elements count */
*(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =
(FT_Byte)num_elements;
/* we store the elements count if necessary */
if ( field->type != T1_FIELD_TYPE_BBOX )
*(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =
(FT_Byte)num_elements;
/* we now load each element, adjusting the field.offset on each one */
token = elements;
@ -1105,8 +1282,8 @@
{
FT_Error error = PSaux_Err_Ok;
FT_Byte* cur;
ps_parser_skip_spaces( parser );
cur = parser->cursor;

View File

@ -276,7 +276,8 @@
return psnames->unicodes_init( memory,
unicodes,
face->type1.num_glyphs,
(PS_Glyph_NameFunc)&t1_get_glyph_name,
(PS_GetGlyphNameFunc)&t1_get_glyph_name,
(PS_FreeGlyphNameFunc)NULL,
(FT_Pointer)face );
}

View File

@ -4,7 +4,7 @@
/* */
/* PostScript Type 1 decoding routines (body). */
/* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005 by */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -65,6 +65,7 @@
op_pop,
op_return,
op_setcurrentpoint,
op_unknown15,
op_max /* never remove this one */
@ -99,7 +100,8 @@
1, /* callsubr */
0, /* pop */
0, /* return */
2 /* setcurrentpoint */
2, /* setcurrentpoint */
2 /* opcode 15 (undocumented and obsolete) */
};
@ -323,6 +325,8 @@
FT_Byte* limit;
T1_Builder builder = &decoder->builder;
FT_Pos x, y, orig_x, orig_y;
FT_Int known_othersubr_result_cnt = 0;
FT_Int unknown_othersubr_result_cnt = 0;
T1_Hints_Funcs hinter;
@ -344,6 +348,19 @@
hinter = (T1_Hints_Funcs)builder->hints_funcs;
/* a font that reads BuildCharArray without setting */
/* its values first is buggy, but ... */
FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
( decoder->buildchar == NULL ) );
if ( decoder->len_buildchar > 0 )
memset( &decoder->buildchar[0],
0,
sizeof( decoder->buildchar[0] ) *
decoder->len_buildchar );
FT_TRACE4(( "\nStart charstring\n" ));
zone->base = charstring_base;
limit = zone->limit = charstring_base + charstring_len;
ip = zone->cursor = zone->base;
@ -365,6 +382,11 @@
FT_Long value = 0;
FT_ASSERT( known_othersubr_result_cnt == 0 ||
unknown_othersubr_result_cnt == 0 );
FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
/*********************************************************************/
/* */
/* Decode operator or operand */
@ -414,7 +436,7 @@
break;
case 15: /* undocumented, obsolete operator */
op = op_none;
op = op_unknown15;
break;
case 21:
@ -520,6 +542,23 @@
}
}
if ( unknown_othersubr_result_cnt > 0 )
{
switch ( op )
{
case op_callsubr:
case op_return:
case op_none:
case op_pop:
break;
default:
/* all operands have been transferred by previous pops */
unknown_othersubr_result_cnt = 0;
break;
}
}
/*********************************************************************/
/* */
/* Push value on stack, or process operator */
@ -540,16 +579,59 @@
}
else if ( op == op_callothersubr ) /* callothersubr */
{
FT_Int subr_no;
FT_Int arg_cnt;
FT_TRACE4(( " callothersubr" ));
if ( top - decoder->stack < 2 )
goto Stack_Underflow;
top -= 2;
switch ( (FT_Int)top[1] )
subr_no = (FT_Int)top[1];
arg_cnt = (FT_Int)top[0];
/***********************************************************/
/* */
/* remove all operands to callothersubr from the stack */
/* */
/* for handled othersubrs, where we know the number of */
/* arguments, we increase the stack by the value of */
/* known_othersubr_result_cnt */
/* */
/* for unhandled othersubrs the following pops adjust the */
/* stack pointer as necessary */
if ( arg_cnt > top - decoder->stack )
goto Stack_Underflow;
top -= arg_cnt;
known_othersubr_result_cnt = 0;
unknown_othersubr_result_cnt = 0;
/* XXX TODO: The checks to `arg_count == <whatever>' */
/* might not be correct; an othersubr expects a certain */
/* number of operands on the PostScript stack (as opposed */
/* to the T1 stack) but it doesn't have to put them there */
/* by itself; previous othersubrs might have left the */
/* operands there if they were not followed by an */
/* appropriate number of pops */
/* */
/* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */
/* accept a font that contains charstrings like */
/* */
/* 100 200 2 20 callothersubr */
/* 300 1 20 callothersubr pop */
/* */
/* Perhaps this is the reason why BuildCharArray exists. */
switch ( subr_no )
{
case 1: /* start flex feature */
if ( top[0] != 0 )
if ( arg_cnt != 0 )
goto Unexpected_OtherSubr;
decoder->flex_state = 1;
@ -564,7 +646,7 @@
FT_Int idx;
if ( top[0] != 0 )
if ( arg_cnt != 0 )
goto Unexpected_OtherSubr;
/* note that we should not add a point for index 0; */
@ -580,7 +662,7 @@
break;
case 0: /* end flex feature */
if ( top[0] != 3 )
if ( arg_cnt != 3 )
goto Unexpected_OtherSubr;
if ( decoder->flex_state == 0 ||
@ -591,40 +673,15 @@
goto Syntax_Error;
}
/* now consume the remaining `pop pop setcurpoint' */
if ( ip + 6 > limit ||
ip[0] != 12 || ip[1] != 17 || /* pop */
ip[2] != 12 || ip[3] != 17 || /* pop */
ip[4] != 12 || ip[5] != 33 ) /* setcurpoint */
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid flex charstring\n" ));
goto Syntax_Error;
}
ip += 6;
decoder->flex_state = 0;
/* the two `results' are popped by the following setcurrentpoint */
known_othersubr_result_cnt = 2;
break;
case 3: /* change hints */
if ( top[0] != 1 )
if ( arg_cnt != 1 )
goto Unexpected_OtherSubr;
/* eat the following `pop' */
if ( ip + 2 > limit )
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid escape (12+%d)\n", ip[-1] ));
goto Syntax_Error;
}
if ( ip[0] != 12 || ip[1] != 17 )
{
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
FT_ERROR(( "`pop' expected, found (%d %d)\n", ip[0], ip[1] ));
goto Syntax_Error;
}
ip += 2;
known_othersubr_result_cnt = 1;
if ( hinter )
hinter->reset( hinter->hints, builder->current->n_points );
@ -656,18 +713,14 @@
goto Syntax_Error;
}
num_points = (FT_UInt)top[1] - 13 + ( top[1] == 18 );
if ( top[0] != (FT_Int)( num_points * blend->num_designs ) )
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" ));
goto Syntax_Error;
}
top -= blend->num_designs * num_points;
if ( top < decoder->stack )
goto Stack_Underflow;
/* we want to compute: */
/* */
/* a0*w0 + a1*w1 + ... + ak*wk */
@ -695,16 +748,178 @@
*values++ = tmp;
}
/* note that `top' will be incremented later by calls to `pop' */
known_othersubr_result_cnt = num_points;
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:
/* <idx> 1 19 callothersubr */
/* => replace elements starting from index cvi( <idx> ) */
/* of BuildCharArray with WeightVector */
{
FT_Int idx;
PS_Blend blend = decoder->blend;
if ( arg_cnt != 1 || blend == NULL )
goto Unexpected_OtherSubr;
idx = top[0];
if ( idx < 0 ||
idx + blend->num_designs > decoder->face->len_buildchar )
goto Unexpected_OtherSubr;
memcpy( &decoder->buildchar[idx],
blend->weight_vector,
blend->num_designs *
sizeof( blend->weight_vector[ 0 ] ) );
}
break;
case 20:
/* <arg1> <arg2> 2 20 callothersubr pop */
/* ==> push <arg1> + <arg2> onto T1 stack */
if ( arg_cnt != 2 )
goto Unexpected_OtherSubr;
top[0] += top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
case 21:
/* <arg1> <arg2> 2 21 callothersubr pop */
/* ==> push <arg1> - <arg2> onto T1 stack */
if ( arg_cnt != 2 )
goto Unexpected_OtherSubr;
top[0] -= top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
case 22:
/* <arg1> <arg2> 2 22 callothersubr pop */
/* ==> push <arg1> * <arg2> onto T1 stack */
if ( arg_cnt != 2 )
goto Unexpected_OtherSubr;
top[0] *= top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
case 23:
/* <arg1> <arg2> 2 23 callothersubr pop */
/* ==> push <arg1> / <arg2> onto T1 stack */
if ( arg_cnt != 2 || top[1] == 0 )
goto Unexpected_OtherSubr;
top[0] /= top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */
case 24:
/* <val> <idx> 2 24 callothersubr */
/* => set BuildCharArray[cvi( <idx> )] = <val> */
{
FT_Int idx;
PS_Blend blend = decoder->blend;
if ( arg_cnt != 2 || blend == NULL )
goto Unexpected_OtherSubr;
idx = top[1];
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
goto Unexpected_OtherSubr;
decoder->buildchar[idx] = top[0];
}
break;
case 25:
/* <idx> 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];
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
goto Unexpected_OtherSubr;
top[0] = decoder->buildchar[idx];
}
known_othersubr_result_cnt = 1;
break;
#if 0
case 26:
/* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */
/* leave mark on T1 stack */
/* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */
XXX who has left his mark on the (PostScript) stack ?;
break;
#endif
case 27:
/* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
/* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
/* otherwise push <res2> */
if ( arg_cnt != 4 )
goto Unexpected_OtherSubr;
if ( top[2] > top[3] )
top[0] = top[1];
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();
known_othersubr_result_cnt = 1;
break;
#endif
default:
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", top[0], top[1] ));
"invalid othersubr [%d %d]!\n", arg_cnt, subr_no ));
goto Syntax_Error;
}
top += known_othersubr_result_cnt;
decoder->top = top;
}
else /* general operator */
@ -712,9 +927,38 @@
FT_Int num_args = t1_args_count[op];
FT_ASSERT( num_args >= 0 );
if ( top - decoder->stack < num_args )
goto Stack_Underflow;
/* XXX Operators usually take their operands from the */
/* bottom of the stack, i.e., the operands are */
/* decoder->stack[0], ..., decoder->stack[num_args - 1]; */
/* only div, callsubr, and callothersubr are different. */
/* In practice it doesn't matter (?). */
#ifdef FT_DEBUG_LEVEL_TRACE
switch ( op )
{
case op_callsubr:
case op_div:
case op_callothersubr:
case op_pop:
case op_return:
break;
default:
if ( top - decoder->stack != num_args )
FT_TRACE0(( "\nMore operands on the stack than expected "
"(have %d, expected %d)\n",
top - decoder->stack, num_args ));
break;
}
#endif /* FT_DEBUG_LEVEL_TRACE */
top -= num_args;
switch ( op )
@ -740,8 +984,30 @@
/* 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
if ( decoder->len_buildchar > 0 )
{
FT_UInt i;
FT_TRACE4(( "BuildCharArray = [ " ));
for ( i = 0; i < decoder->len_buildchar; ++i )
FT_TRACE4(( "%d ", decoder->buildchar[ i ] ));
FT_TRACE4(( "]\n" ));
}
#endif /* FT_DEBUG_LEVEL_TRACE */
FT_TRACE4(( "\n" ));
/* return now! */
FT_TRACE4(( "\n\n" ));
return PSaux_Err_Ok;
case op_hsbw:
@ -997,8 +1263,22 @@
case op_pop:
FT_TRACE4(( " pop" ));
/* theoretically, the arguments are already on the stack */
top++;
if ( known_othersubr_result_cnt > 0 )
{
known_othersubr_result_cnt--;
/* ignore, we pushed the operands ourselves */
break;
}
if ( unknown_othersubr_result_cnt == 0 )
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"no more operands for othersubr!\n" ));
goto Syntax_Error;
}
unknown_othersubr_result_cnt--;
top++; /* `push' the operand to callothersubr onto the stack */
break;
case op_return:
@ -1073,9 +1353,27 @@
case op_setcurrentpoint:
FT_TRACE4(( " setcurrentpoint" ));
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
FT_ERROR(( "unexpected `setcurrentpoint'\n" ));
goto Syntax_Error;
/* From the T1 specs, 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 */
if ( decoder->flex_state != 1 )
{
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
FT_ERROR(( "unexpected `setcurrentpoint'\n" ));
goto Syntax_Error;
}
else
decoder->flex_state = 0;
break;
case op_unknown15:
FT_TRACE4(( " opcode_15" ));
/* nothing to do except to pop the two arguments */
break;
default:
FT_ERROR(( "t1_decoder_parse_charstrings: "
@ -1083,6 +1381,11 @@
goto Syntax_Error;
}
/* XXX Operators usually clear the operand stack; */
/* only div, callsubr, callothersubr, pop, and */
/* return are different. */
/* In practice it doesn't matter (?). */
decoder->top = top;
} /* general operator processing */
@ -1143,6 +1446,10 @@
t1_builder_init( &decoder->builder, face, size, slot, hinting );
/* decoder->buildchar and decoder->len_buildchar have to be */
/* initialized by the caller since we cannot know the length */
/* of the BuildCharArray */
decoder->num_glyphs = (FT_UInt)face->num_glyphs;
decoder->glyph_names = glyph_names;
decoder->hint_mode = hint_mode;
@ -1151,7 +1458,7 @@
decoder->funcs = t1_decoder_funcs;
return 0;
return PSaux_Err_Ok;
}

View File

@ -4,7 +4,7 @@
/* */
/* PostScript hinting algorithm (body). */
/* */
/* Copyright 2001, 2002, 2003, 2004, 2005 by */
/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used */
@ -19,6 +19,7 @@
#include <ft2build.h>
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_CALC_H
#include "pshalgo.h"
#include "pshnterr.h"
@ -879,6 +880,104 @@
/*************************************************************************/
/*************************************************************************/
#if 1
#define psh_corner_is_flat ft_corner_is_flat
#define psh_corner_orientation ft_corner_orientation
#else
FT_LOCAL_DEF( FT_Int )
psh_corner_is_flat( FT_Pos x_in,
FT_Pos y_in,
FT_Pos x_out,
FT_Pos y_out )
{
FT_Pos ax = x_in;
FT_Pos ay = y_in;
FT_Pos d_in, d_out, d_corner;
if ( ax < 0 )
ax = -ax;
if ( ay < 0 )
ay = -ay;
d_in = ax + ay;
ax = x_out;
if ( ax < 0 )
ax = -ax;
ay = y_out;
if ( ay < 0 )
ay = -ay;
d_out = ax + ay;
ax = x_out + x_in;
if ( ax < 0 )
ax = -ax;
ay = y_out + y_in;
if ( ay < 0 )
ay = -ay;
d_corner = ax + ay;
return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
}
static FT_Int
psh_corner_orientation( FT_Pos in_x,
FT_Pos in_y,
FT_Pos out_x,
FT_Pos out_y )
{
FT_Int result;
/* deal with the trivial cases quickly */
if ( in_y == 0 )
{
if ( in_x >= 0 )
result = out_y;
else
result = -out_y;
}
else if ( in_x == 0 )
{
if ( in_y >= 0 )
result = -out_x;
else
result = out_x;
}
else if ( out_y == 0 )
{
if ( out_x >= 0 )
result = in_y;
else
result = -in_y;
}
else if ( out_x == 0 )
{
if ( out_y >= 0 )
result = -in_x;
else
result = in_x;
}
else /* general case */
{
long long delta = (long long)in_x * out_y - (long long)in_y * out_x;
if ( delta == 0 )
result = 0;
else
result = 1 - 2 * ( delta < 0 );
}
return result;
}
#endif /* !1 */
#ifdef COMPUTE_INFLEXS
/* compute all inflex points in a given glyph */
@ -891,8 +990,8 @@
for ( n = 0; n < glyph->num_contours; n++ )
{
PSH_Point first, start, end, before, after;
FT_Angle angle_in, angle_seg, angle_out;
FT_Angle diff_in, diff_out;
FT_Pos in_x, in_y, out_x, out_y;
FT_Int orient_prev, orient_cur;
FT_Int finished = 0;
@ -910,9 +1009,10 @@
if ( end == first )
goto Skip;
} while ( PSH_POINT_EQUAL_ORG( end, first ) );
in_x = end->org_u - start->org_u;
in_y = end->org_v - start->org_v;
angle_seg = PSH_POINT_ANGLE( start, end );
} while ( in_x == 0 && in_y == 0 );
/* extend the segment start whenever possible */
before = start;
@ -925,14 +1025,18 @@
if ( before == first )
goto Skip;
} while ( PSH_POINT_EQUAL_ORG( before, start ) );
out_x = start->org_u - before->org_u;
out_y = start->org_v - before->org_v;
angle_in = PSH_POINT_ANGLE( before, start );
} while ( out_x == 0 && out_y == 0 );
} while ( angle_in == angle_seg );
orient_prev = psh_corner_orientation( in_x, in_y, out_x, out_y );
first = start;
diff_in = FT_Angle_Diff( angle_in, angle_seg );
} while ( orient_prev == 0 );
first = start;
in_x = out_x;
in_y = out_y;
/* now, process all segments in the contour */
do
@ -948,19 +1052,17 @@
if ( after == first )
finished = 1;
} while ( PSH_POINT_EQUAL_ORG( end, after ) );
out_x = after->org_u - end->org_u;
out_y = after->org_v - end->org_v;
angle_out = PSH_POINT_ANGLE( end, after );
} while ( out_x == 0 && out_y == 0 );
} while ( angle_out == angle_seg );
orient_cur = psh_corner_orientation( in_x, in_y, out_x, out_y );
diff_out = FT_Angle_Diff( angle_seg, angle_out );
} while ( orient_cur == 0 );
if ( ( diff_in ^ diff_out ) < 0 )
if ( ( orient_cur ^ orient_prev ) < 0 )
{
/* diff_in and diff_out have different signs, we have */
/* inflection points here... */
do
{
psh_point_set_inflex( start );
@ -971,10 +1073,11 @@
psh_point_set_inflex( start );
}
start = end;
end = after;
angle_seg = angle_out;
diff_in = diff_out;
start = end;
end = after;
orient_prev = orient_cur;
in_x = out_x;
in_y = out_y;
} while ( !finished );
@ -1199,28 +1302,11 @@
/* detect smooth points */
if ( point->flags & PSH_POINT_OFF )
point->flags |= PSH_POINT_SMOOTH;
else if ( point->dir_in != PSH_DIR_NONE ||
point->dir_out != PSH_DIR_NONE )
else if ( point->dir_in == point->dir_out )
{
if ( point->dir_in == point->dir_out )
point->flags |= PSH_POINT_SMOOTH;
}
else
{
FT_Angle angle_in, angle_out, diff;
angle_in = FT_Atan2( dxi, dyi );
angle_out = FT_Atan2( dxo, dyo );
diff = angle_in - angle_out;
if ( diff < 0 )
diff = -diff;
if ( diff > FT_ANGLE_PI )
diff = FT_ANGLE_2PI - diff;
if ( diff < FT_ANGLE_PI / 16 )
if ( point->dir_out != PSH_DIR_NONE ||
psh_corner_is_flat( dxi, dyi, dxo, dyo ) )
point->flags |= PSH_POINT_SMOOTH;
}
}
@ -1382,115 +1468,147 @@
/* -major_dir. */
static void
psh_hint_table_find_strong_point( PSH_Hint_Table table,
PSH_Point point,
FT_Int threshold,
FT_Int major_dir )
psh_hint_table_find_strong_points( PSH_Hint_Table table,
PSH_Point point,
FT_UInt count,
FT_Int threshold,
FT_Int major_dir )
{
PSH_Hint* sort = table->sort;
FT_UInt num_hints = table->num_hints;
FT_Int point_dir = 0;
if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) )
point_dir = point->dir_in;
else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) )
point_dir = point->dir_out;
if ( point_dir )
for ( ; count > 0; count--, point++ )
{
FT_UInt flag;
FT_Int point_dir = 0;
FT_Pos org_u = point->org_u;
for ( ; num_hints > 0; num_hints--, sort++ )
if ( psh_point_is_strong( point ) )
continue;
if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) )
point_dir = point->dir_in;
else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) )
point_dir = point->dir_out;
if ( point_dir )
{
PSH_Hint hint = sort[0];
FT_Pos d;
if ( point_dir == major_dir )
{
flag = PSH_POINT_EDGE_MIN;
d = point->org_u - hint->org_pos;
FT_UInt nn;
if ( FT_ABS( d ) < threshold )
for ( nn = 0; nn < num_hints; nn++ )
{
Is_Strong:
psh_point_set_strong( point );
point->flags2 |= flag;
point->hint = hint;
break;
PSH_Hint hint = sort[nn];
FT_Pos d = org_u - hint->org_pos;
if ( d < threshold && -d < threshold )
{
psh_point_set_strong( point );
point->flags2 |= PSH_POINT_EDGE_MIN;
point->hint = hint;
break;
}
}
}
else if ( point_dir == -major_dir )
{
flag = PSH_POINT_EDGE_MAX;
d = point->org_u - hint->org_pos - hint->org_len;
FT_UInt nn;
if ( FT_ABS( d ) < threshold )
goto Is_Strong;
for ( nn = 0; nn < num_hints; nn++ )
{
PSH_Hint hint = sort[nn];
FT_Pos d = org_u - hint->org_pos - hint->org_len;
if ( d < threshold && -d < threshold )
{
psh_point_set_strong( point );
point->flags2 |= PSH_POINT_EDGE_MAX;
point->hint = hint;
break;
}
}
}
}
}
#if 1
else if ( psh_point_is_extremum( point ) )
{
/* treat extrema as special cases for stem edge alignment */
FT_UInt min_flag, max_flag;
if ( major_dir == PSH_DIR_HORIZONTAL )
else if ( psh_point_is_extremum( point ) )
{
min_flag = PSH_POINT_POSITIVE;
max_flag = PSH_POINT_NEGATIVE;
}
else
{
min_flag = PSH_POINT_NEGATIVE;
max_flag = PSH_POINT_POSITIVE;
}
/* treat extrema as special cases for stem edge alignment */
FT_UInt nn, min_flag, max_flag;
for ( ; num_hints > 0; num_hints--, sort++ )
{
PSH_Hint hint = sort[0];
FT_Pos d;
FT_Int flag;
if ( major_dir == PSH_DIR_HORIZONTAL )
{
min_flag = PSH_POINT_POSITIVE;
max_flag = PSH_POINT_NEGATIVE;
}
else
{
min_flag = PSH_POINT_NEGATIVE;
max_flag = PSH_POINT_POSITIVE;
}
if ( point->flags2 & min_flag )
{
flag = PSH_POINT_EDGE_MIN;
d = point->org_u - hint->org_pos;
if ( FT_ABS( d ) < threshold )
for ( nn = 0; nn < num_hints; nn++ )
{
Is_Strong2:
point->flags2 |= flag;
point->hint = hint;
psh_point_set_strong( point );
break;
PSH_Hint hint = sort[nn];
FT_Pos d = org_u - hint->org_pos;
if ( d < threshold && -d < threshold )
{
point->flags2 |= PSH_POINT_EDGE_MIN;
point->hint = hint;
psh_point_set_strong( point );
break;
}
}
}
else if ( point->flags2 & max_flag )
{
flag = PSH_POINT_EDGE_MAX;
d = point->org_u - hint->org_pos - hint->org_len;
for ( nn = 0; nn < num_hints; nn++ )
{
PSH_Hint hint = sort[nn];
FT_Pos d = org_u - hint->org_pos - hint->org_len;
if ( FT_ABS( d ) < threshold )
goto Is_Strong2;
if ( d < threshold && -d < threshold )
{
point->flags2 |= PSH_POINT_EDGE_MAX;
point->hint = hint;
psh_point_set_strong( point );
break;
}
}
}
if ( point->org_u >= hint->org_pos &&
point->org_u <= hint->org_pos + hint->org_len )
if ( point->hint == NULL )
{
point->hint = hint;
for ( nn = 0; nn < num_hints; nn++ )
{
PSH_Hint hint = sort[nn];
if ( org_u >= hint->org_pos &&
org_u <= hint->org_pos + hint->org_len )
{
point->hint = hint;
break;
}
}
}
}
}
#endif /* 1 */
}
}
@ -1544,9 +1662,8 @@
psh_hint_table_activate_mask( table, mask );
for ( ; count > 0; count--, point++ )
psh_hint_table_find_strong_point( table, point,
threshold, major_dir );
psh_hint_table_find_strong_points( table, point, count,
threshold, major_dir );
}
first = next;
}
@ -1560,12 +1677,9 @@
psh_hint_table_activate_mask( table, table->hint_masks->masks );
for ( ; count > 0; count--, point++ )
{
if ( !psh_point_is_strong( point ) )
psh_hint_table_find_strong_point( table, point,
threshold, major_dir );
}
psh_hint_table_find_strong_points( table, point, count,
threshold, major_dir );
}
/* now, certain points may have been attached to a hint and */
@ -1710,6 +1824,8 @@
}
#define PSH_MAX_STRONG_INTERNAL 16
static void
psh_glyph_interpolate_normal_points( PSH_Glyph glyph,
FT_Int dimension )
@ -1718,14 +1834,64 @@
#if 1
/* first technique: a point is strong if it is a local extremum */
PSH_Dimension dim = &glyph->globals->dimension[dimension];
FT_Fixed scale = dim->scale_mult;
PSH_Dimension dim = &glyph->globals->dimension[dimension];
FT_Fixed scale = dim->scale_mult;
FT_Memory memory = glyph->memory;
FT_UInt count = glyph->num_points;
PSH_Point point = glyph->points;
PSH_Point* strongs = NULL;
PSH_Point strongs_0[PSH_MAX_STRONG_INTERNAL];
FT_UInt num_strongs = 0;
PSH_Point points = glyph->points;
PSH_Point points_end = points + glyph->num_points;
PSH_Point point;
for ( ; count > 0; count--, point++ )
/* first count the number of strong points */
for ( point = points; point < points_end; point++ )
{
if ( psh_point_is_strong( point ) )
num_strongs++;
}
if ( num_strongs == 0 ) /* nothing to do here */
return;
/* allocate an array to store a list of points, */
/* stored in increasing org_u order */
if ( num_strongs <= PSH_MAX_STRONG_INTERNAL )
strongs = strongs_0;
else
{
FT_Error error;
if ( FT_NEW_ARRAY( strongs, num_strongs ) )
return;
}
num_strongs = 0;
for ( point = points; point < points_end; point++ )
{
PSH_Point* insert;
if ( !psh_point_is_strong( point ) )
continue;
for ( insert = strongs + num_strongs; insert > strongs; insert-- )
{
if ( insert[-1]->org_u <= point->org_u )
break;
insert[0] = insert[-1];
}
insert[0] = point;
num_strongs++;
}
/* now try to interpolate all normal points */
for ( point = points; point < points_end; point++ )
{
if ( psh_point_is_strong( point ) )
continue;
@ -1744,82 +1910,70 @@
point->flags &= ~PSH_POINT_SMOOTH;
}
/* find best enclosing point coordinates */
/* find best enclosing point coordinates then interpolate */
{
PSH_Point before = 0;
PSH_Point after = 0;
FT_Pos diff_before = -32000;
FT_Pos diff_after = 32000;
FT_Pos u = point->org_u;
FT_Int count2 = glyph->num_points;
PSH_Point cur = glyph->points;
PSH_Point before, after;
FT_UInt nn;
for ( ; count2 > 0; count2--, cur++ )
for ( nn = 0; nn < num_strongs; nn++ )
if ( strongs[nn]->org_u > point->org_u )
break;
if ( nn == 0 ) /* point before the first strong point */
{
if ( psh_point_is_strong( cur ) )
{
FT_Pos diff = cur->org_u - u;
after = strongs[0];
if ( diff <= 0 )
{
if ( diff > diff_before )
{
diff_before = diff;
before = cur;
}
}
else if ( diff >= 0 )
{
if ( diff < diff_after )
{
diff_after = diff;
after = cur;
}
}
}
}
if ( !before )
{
if ( !after )
continue;
/* we are before the first strong point coordinate; */
/* simply translate the point */
point->cur_u = after->cur_u +
FT_MulFix( point->org_u - after->org_u, scale );
}
else if ( !after )
{
/* we are after the last strong point coordinate; */
/* simply translate the point */
point->cur_u = before->cur_u +
FT_MulFix( point->org_u - before->org_u, scale );
FT_MulFix( point->org_u - after->org_u,
scale );
}
else
{
if ( diff_before == 0 )
point->cur_u = before->cur_u;
before = strongs[nn - 1];
else if ( diff_after == 0 )
point->cur_u = after->cur_u;
for ( nn = num_strongs; nn > 0; nn-- )
if ( strongs[nn - 1]->org_u < point->org_u )
break;
if ( nn == num_strongs ) /* point is after last strong point */
{
before = strongs[nn - 1];
else
point->cur_u = before->cur_u +
FT_MulDiv( u - before->org_u,
after->cur_u - before->cur_u,
after->org_u - before->org_u );
}
FT_MulFix( point->org_u - before->org_u,
scale );
}
else
{
FT_Pos u;
after = strongs[nn];
/* now interpolate point between before and after */
u = point->org_u;
if ( u == before->org_u )
point->cur_u = before->cur_u;
else if ( u == after->org_u )
point->cur_u = after->cur_u;
else
point->cur_u = before->cur_u +
FT_MulDiv( u - before->org_u,
after->cur_u - before->cur_u,
after->org_u - before->org_u );
}
}
psh_point_set_fitted( point );
}
}
if ( strongs != strongs_0 )
FT_FREE( strongs );
#endif /* 1 */
}

View File

@ -182,11 +182,12 @@
/* Build a table that maps Unicode values to glyph indices. */
static FT_Error
ps_unicodes_init( FT_Memory memory,
PS_Unicodes table,
FT_UInt num_glyphs,
PS_Glyph_NameFunc get_glyph_name,
FT_Pointer glyph_data )
ps_unicodes_init( FT_Memory memory,
PS_Unicodes table,
FT_UInt num_glyphs,
PS_GetGlyphNameFunc get_glyph_name,
PS_FreeGlyphNameFunc free_glyph_name,
FT_Pointer glyph_data )
{
FT_Error error;
@ -220,6 +221,9 @@
map->glyph_index = n;
map++;
}
if ( free_glyph_name )
free_glyph_name( glyph_data, gname );
}
}

View File

@ -4,7 +4,7 @@
/* */
/* The FreeType glyph rasterizer (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2005 by */
/* Copyright 1996-2001, 2002, 2003, 2005, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -378,19 +378,19 @@
#else /* FT_STATIC_RASTER */
#define RAS_ARGS TRaster_Instance* raster,
#define RAS_ARG TRaster_Instance* raster
#define RAS_ARGS PWorker worker,
#define RAS_ARG PWorker worker
#define RAS_VARS raster,
#define RAS_VAR raster
#define RAS_VARS worker,
#define RAS_VAR worker
#define FT_UNUSED_RASTER FT_UNUSED( raster )
#define FT_UNUSED_RASTER FT_UNUSED( worker )
#endif /* FT_STATIC_RASTER */
typedef struct TRaster_Instance_ TRaster_Instance;
typedef struct TWorker_ TWorker, *PWorker;
/* prototypes used for sweep function dispatch */
@ -422,7 +422,7 @@
/* at the top. Thus, their offset can be coded with less */
/* opcodes, and it results in a smaller executable. */
struct TRaster_Instance_
struct TWorker_
{
Int precision_bits; /* precision related variables */
Int precision;
@ -498,15 +498,9 @@
TBand band_stack[16]; /* band stack used for sub-banding */
Int band_top; /* band stack top */
Int count_table[256]; /* Look-up table used to quickly count */
/* set bits in a gray 2x2 cell */
void* memory;
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
Byte grays[5]; /* Palette of gray levels used for */
/* render. */
Byte* grays;
Byte gray_lines[RASTER_GRAY_LINES];
/* Intermediate table used to render the */
@ -523,30 +517,53 @@
#endif /* FT_RASTER_ANTI_ALIASING */
#if 0
PByte flags; /* current flags table */
PUShort outs; /* current outlines table */
FT_Vector* coords;
UShort nPoints; /* number of points in current glyph */
Short nContours; /* number of contours in current glyph */
#endif
};
typedef struct TRaster_
{
char* buffer;
long buffer_size;
void* memory;
PWorker worker;
Byte grays[5];
Short gray_width;
} TRaster, *PRaster;
#ifdef FT_STATIC_RASTER
static TRaster_Instance cur_ras;
static TWorker cur_ras;
#define ras cur_ras
#else
#define ras (*raster)
#define ras (*worker)
#endif /* FT_STATIC_RASTER */
static const char 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 };
/*************************************************************************/
/*************************************************************************/
/** **/
@ -2494,7 +2511,7 @@
{
Int c1, c2;
PByte pix, bit, bit2;
Int* count = ras.count_table;
char* count = (char*)count_table;
Byte* grays;
@ -3153,32 +3170,19 @@
static void
ft_black_init( TRaster_Instance* raster )
ft_black_init( PRaster raster )
{
FT_UInt n;
FT_ULong c;
/* setup count table */
for ( n = 0; n < 256; n++ )
{
c = ( n & 0x55 ) + ( ( n & 0xAA ) >> 1 );
c = ( ( c << 6 ) & 0x3000 ) |
( ( c << 4 ) & 0x0300 ) |
( ( c << 2 ) & 0x0030 ) |
(c & 0x0003 );
ras.count_table[n] = (UInt)c;
}
FT_UNUSED( raster );
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
FT_UInt n;
/* set default 5-levels gray palette */
for ( n = 0; n < 5; n++ )
raster->grays[n] = n * 255 / 4;
ras.gray_width = RASTER_GRAY_LINES / 2;
raster->gray_width = RASTER_GRAY_LINES / 2;
#endif
}
@ -3195,7 +3199,7 @@
ft_black_new( void* memory,
FT_Raster *araster )
{
static TRaster_Instance the_raster;
static TRaster the_raster;
*araster = (FT_Raster)&the_raster;
@ -3218,11 +3222,11 @@
static int
ft_black_new( FT_Memory memory,
TRaster_Instance** araster )
ft_black_new( FT_Memory memory,
PRaster *araster )
{
FT_Error error;
TRaster_Instance* raster;
FT_Error error;
PRaster raster;
*araster = 0;
@ -3239,7 +3243,7 @@
static void
ft_black_done( TRaster_Instance* raster )
ft_black_done( PRaster raster )
{
FT_Memory memory = (FT_Memory)raster->memory;
FT_FREE( raster );
@ -3250,21 +3254,34 @@
static void
ft_black_reset( TRaster_Instance* raster,
char* pool_base,
long pool_size )
ft_black_reset( PRaster raster,
char* pool_base,
long pool_size )
{
if ( (&ras) && pool_base && pool_size >= 4096 )
if ( raster )
{
/* save the pool */
ras.buff = (PLong)pool_base;
ras.sizeBuff = ras.buff + pool_size / sizeof ( Long );
if ( pool_base && pool_size >= (long)sizeof(TWorker) + 2048 )
{
PWorker worker = (PWorker)pool_base;
raster->buffer = pool_base + ( (sizeof ( *worker ) + 7 ) & ~7 );
raster->buffer_size = ( ( pool_base + pool_size ) -
(char*)raster->buffer ) / sizeof ( Long );
raster->worker = worker;
}
else
{
raster->buffer = NULL;
raster->buffer_size = 0;
raster->worker = NULL;
}
}
}
static void
ft_black_set_mode( TRaster_Instance* raster,
ft_black_set_mode( PRaster raster,
unsigned long mode,
const char* palette )
{
@ -3273,11 +3290,11 @@
if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )
{
/* set 5-levels gray palette */
ras.grays[0] = palette[0];
ras.grays[1] = palette[1];
ras.grays[2] = palette[2];
ras.grays[3] = palette[3];
ras.grays[4] = palette[4];
raster->grays[0] = palette[0];
raster->grays[1] = palette[1];
raster->grays[2] = palette[2];
raster->grays[3] = palette[3];
raster->grays[4] = palette[4];
}
#else
@ -3291,14 +3308,15 @@
static int
ft_black_render( TRaster_Instance* raster,
ft_black_render( PRaster raster,
const FT_Raster_Params* params )
{
const FT_Outline* outline = (const FT_Outline*)params->source;
const FT_Bitmap* target_map = params->target;
PWorker worker;
if ( !(&ras) || !ras.buff || !ras.sizeBuff )
if ( !raster || !raster->buffer || !raster->buffer_size )
return Raster_Err_Not_Ini;
/* return immediately if the outline is empty */
@ -3311,6 +3329,8 @@
if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 )
return Raster_Err_Invalid;
worker = raster->worker;
/* this version of the raster does not support direct rendering, sorry */
if ( params->flags & FT_RASTER_FLAG_DIRECT )
return Raster_Err_Unsupported;
@ -3321,6 +3341,14 @@
ras.outline = *outline;
ras.target = *target_map;
worker->buff = (PLong) raster->buffer;
worker->sizeBuff = worker->buff +
raster->buffer_size / sizeof ( Long );
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
worker->grays = raster->grays;
worker->gray_width = raster->gray_width;
#endif
return ( ( params->flags & FT_RASTER_FLAG_AA )
? Render_Gray_Glyph( RAS_VAR )
: Render_Glyph( RAS_VAR ) );

View File

@ -3,7 +3,7 @@
#
# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006 by
# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,

View File

@ -412,9 +412,9 @@
{
FT_UNUSED( face );
FT_UNUSED( stream );
return FT_Err_Unimplemented_Feature;
}
}
FT_CALLBACK_DEF( void )
@ -449,8 +449,8 @@
*astrike_index = 0x7FFFFFFFUL;
return tt_face_set_sbit_strike( face, &req, astrike_index );
}
return tt_face_set_sbit_strike( face, &req, astrike_index );
}
FT_CALLBACK_DEF( FT_Error )
@ -459,15 +459,15 @@
{
FT_UNUSED( face );
FT_UNUSED( stream );
/*
* This function was originally implemented to load the sbit table.
* This function was originally implemented to load the sbit table.
* However, it has been replaced by `tt_face_load_eblc', and this stub
* is only there for some rogue clients which would want to call it
* directly (which doesn't make much sense).
*/
return FT_Err_Unimplemented_Feature;
}
}
FT_CALLBACK_DEF( void )
@ -476,8 +476,8 @@
/* nothing to do in this stub */
FT_UNUSED( face );
}
FT_CALLBACK_DEF( FT_Error )
tt_face_load_charmap_stub( TT_Face face,
void* cmap,
@ -486,9 +486,9 @@
FT_UNUSED( face );
FT_UNUSED( cmap );
FT_UNUSED( input );
return FT_Err_Unimplemented_Feature;
}
}
FT_CALLBACK_DEF( FT_Error )
@ -497,10 +497,10 @@
{
FT_UNUSED( face );
FT_UNUSED( cmap );
return 0;
}
}
#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
@ -600,7 +600,7 @@
0,
0,
0,
#endif
#endif
tt_face_get_metrics
};

View File

@ -4,7 +4,7 @@
/* */
/* SFNT object management (base). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -75,37 +75,6 @@
}
/* convert a UCS-4 name entry to ASCII */
static FT_String*
tt_name_entry_ascii_from_ucs4( TT_NameEntry entry,
FT_Memory memory )
{
FT_String* string;
FT_UInt len, code, n;
FT_Byte* read = (FT_Byte*)entry->string;
FT_Error error;
len = (FT_UInt)entry->stringLength / 4;
if ( FT_NEW_ARRAY( string, len + 1 ) )
return NULL;
for ( n = 0; n < len; n++ )
{
code = (FT_UInt)FT_NEXT_ULONG( read );
if ( code < 32 || code > 127 )
code = '?';
string[n] = (char)code;
}
string[len] = 0;
return string;
}
/* convert an Apple Roman or symbol name entry to ASCII */
static FT_String*
tt_name_entry_ascii_from_other( TT_NameEntry entry,
@ -165,9 +134,11 @@
FT_String* result = NULL;
FT_UShort n;
TT_NameEntryRec* rec;
FT_Int found_apple = -1;
FT_Int found_win = -1;
FT_Int found_unicode = -1;
FT_Int found_apple = -1;
FT_Int found_apple_roman = -1;
FT_Int found_apple_english = -1;
FT_Int found_win = -1;
FT_Int found_unicode = -1;
FT_Bool is_english = 0;
@ -200,9 +171,14 @@
break;
case TT_PLATFORM_MACINTOSH:
/* This is a bit special because some fonts will use either */
/* an English language id, or a Roman encoding id, to indicate */
/* the English version of its font name. */
/* */
if ( rec->languageID == TT_MAC_LANGID_ENGLISH )
found_apple = n;
found_apple_english = n;
else if ( rec->encodingID == TT_MAC_ID_ROMAN )
found_apple_roman = n;
break;
case TT_PLATFORM_MICROSOFT:
@ -232,6 +208,10 @@
}
}
found_apple = found_apple_roman;
if ( found_apple_english >= 0 )
found_apple = found_apple_english;
/* some fonts contain invalid Unicode or Macintosh formatted entries; */
/* we will thus favor names encoded in Windows formats if available */
/* (provided it is an English name) */
@ -242,13 +222,19 @@
rec = face->name_table.names + found_win;
switch ( rec->encodingID )
{
/* all Unicode strings are encoded using UTF-16BE */
case TT_MS_ID_UNICODE_CS:
case TT_MS_ID_SYMBOL_CS:
convert = tt_name_entry_ascii_from_utf16;
break;
case TT_MS_ID_UCS_4:
convert = tt_name_entry_ascii_from_ucs4;
/* Apparently, if this value is found in a name table entry, it is */
/* documented as `full Unicode repertoire'. Experience with the */
/* MsGothic font shipped with Windows Vista shows that this really */
/* means UTF-16 encoded names (UCS-4 values are only used within */
/* charmaps). */
convert = tt_name_entry_ascii_from_utf16;
break;
default:
@ -915,7 +901,7 @@
FT_UInt i, count;
#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS
#if !defined FT_CONFIG_OPTION_OLD_INTERNALS
count = face->sbit_num_strikes;
#else
count = (FT_UInt)face->num_sbit_strikes;
@ -1022,7 +1008,7 @@
}
/* freeing the horizontal metrics */
#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS
#if !defined FT_CONFIG_OPTION_OLD_INTERNALS
{
FT_Stream stream = FT_FACE_STREAM( face );

Some files were not shown because too many files have changed in this diff Show More