[CHG] FreeType updated to version 2.4.5

This commit is contained in:
Crayon2000 2011-06-27 02:19:20 +00:00
parent 37f4fe28aa
commit d95429c495
113 changed files with 4068 additions and 1257 deletions

View file

@ -4,7 +4,7 @@
/* */ /* */
/* ANSI-specific configuration file (specification only). */ /* ANSI-specific configuration file (specification only). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2010 by */ /* Copyright 1996-2004, 2006-2008, 2010-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -127,7 +127,12 @@ FT_BEGIN_HEADER
#if ( defined( __APPLE__ ) && !defined( DARWIN_NO_CARBON ) ) || \ #if ( defined( __APPLE__ ) && !defined( DARWIN_NO_CARBON ) ) || \
( defined( __MWERKS__ ) && defined( macintosh ) ) ( defined( __MWERKS__ ) && defined( macintosh ) )
/* no Carbon frameworks for 64bit 10.4.x */ /* no Carbon frameworks for 64bit 10.4.x */
/* AvailabilityMacros.h is available since Mac OS X 10.2, */
/* so guess the system version by maximum errno before inclusion */
#include <errno.h>
#ifdef ECANCELED /* defined since 10.2 */
#include "AvailabilityMacros.h" #include "AvailabilityMacros.h"
#endif
#if defined( __LP64__ ) && \ #if defined( __LP64__ ) && \
( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 ) ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
#define DARWIN_NO_CARBON 1 #define DARWIN_NO_CARBON 1
@ -348,14 +353,14 @@ FT_BEGIN_HEADER
register FT_Int32 t, t2; register FT_Int32 t, t2;
asm __volatile__ ( __asm__ __volatile__ (
"smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */
"mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */
"add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
"adds %1, %1, %0\n\t" /* %1 += %0 */ "adds %1, %1, %0\n\t" /* %1 += %0 */
"adc %2, %2, #0\n\t" /* %2 += carry */ "adc %2, %2, #0\n\t" /* %2 += carry */
"mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */
"orr %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */
: "=r"(a), "=&r"(t2), "=&r"(t) : "=r"(a), "=&r"(t2), "=&r"(t)
: "r"(a), "r"(b) ); : "r"(a), "r"(b) );
return a; return a;
@ -395,6 +400,43 @@ FT_BEGIN_HEADER
#endif /* __GNUC__ */ #endif /* __GNUC__ */
#ifdef _MSC_VER /* Visual C++ */
#ifdef _M_IX86
#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
/* documentation is in freetype.h */
static __inline FT_Int32
FT_MulFix_i386( FT_Int32 a,
FT_Int32 b )
{
register FT_Int32 result;
__asm
{
mov eax, a
mov edx, b
imul edx
mov ecx, edx
sar ecx, 31
add ecx, 8000h
add eax, ecx
adc edx, 0
shr eax, 16
shl edx, 16
add eax, edx
mov result, eax
}
return result;
}
#endif /* _M_IX86 */
#endif /* _MSC_VER */
#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ #endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Build macros of the FreeType 2 library. */ /* Build macros of the FreeType 2 library. */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -424,6 +424,19 @@
#define FT_LZW_H <freetype/ftlzw.h> #define FT_LZW_H <freetype/ftlzw.h>
/*************************************************************************
*
* @macro:
* FT_BZIP2_H
*
* @description:
* A macro used in #include statements to name the file containing the
* definitions of an API which supports bzip2-compressed files.
*
*/
#define FT_BZIP2_H <freetype/ftbzip2.h>
/************************************************************************* /*************************************************************************
* *
* @macro: * @macro:

View file

@ -4,8 +4,7 @@
/* */ /* */
/* User-selectable configuration macros (specification only). */ /* User-selectable configuration macros (specification only). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ /* Copyright 1996-2011 by */
/* 2010 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -188,6 +187,22 @@ FT_BEGIN_HEADER
/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ /* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */
/*************************************************************************/
/* */
/* Bzip2-compressed file support. */
/* */
/* FreeType now handles font files that have been compressed with the */
/* `bzip2' program. This is mostly used to parse many of the PCF */
/* files that come with XFree86. The implementation uses `libbz2' to */
/* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */
/* Contrary to gzip, bzip2 currently is not included and need to use */
/* the system available bzip2 implementation. */
/* */
/* Define this macro if you want to enable this `feature'. */
/* */
/* #define FT_CONFIG_OPTION_USE_BZIP2 */
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* DLL export compilation */ /* DLL export compilation */
@ -363,6 +378,39 @@ FT_BEGIN_HEADER
/* #define FT_DEBUG_LEVEL_TRACE */ /* #define FT_DEBUG_LEVEL_TRACE */
/*************************************************************************/
/* */
/* Autofitter debugging */
/* */
/* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */
/* control the autofitter behaviour for debugging purposes with global */
/* boolean variables (consequently, you should *never* enable this */
/* while compiling in `release' mode): */
/* */
/* _af_debug_disable_horz_hints */
/* _af_debug_disable_vert_hints */
/* _af_debug_disable_blue_hints */
/* */
/* Additionally, the following functions provide dumps of various */
/* internal autofit structures to stdout (using `printf'): */
/* */
/* af_glyph_hints_dump_points */
/* af_glyph_hints_dump_segments */
/* af_glyph_hints_dump_edges */
/* */
/* As an argument, they use another global variable: */
/* */
/* _af_debug_hints */
/* */
/* Please have a look at the `ftgrid' demo program to see how those */
/* variables and macros should be used. */
/* */
/* Do not #undef these macros here since the build system might define */
/* them for certain configurations only. */
/* */
/* #define FT_DEBUG_AUTOFIT */
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* Memory Debugging */ /* Memory Debugging */
@ -575,7 +623,7 @@ FT_BEGIN_HEADER
/* composite flags array which can be used to disambiguate, but old */ /* composite flags array which can be used to disambiguate, but old */
/* fonts will not have them. */ /* fonts will not have them. */
/* */ /* */
/* http://partners.adobe.com/asn/developer/opentype/glyf.html */ /* http://www.microsoft.com/typography/otspec/glyf.htm */
/* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */
/* */ /* */
#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED #undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
@ -676,6 +724,19 @@ FT_BEGIN_HEADER
/* */ /* */
#define AF_CONFIG_OPTION_INDIC #define AF_CONFIG_OPTION_INDIC
/*************************************************************************/
/* */
/* Compile autofit module with warp hinting. The idea of the warping */
/* code is to slightly scale and shift a glyph within a single dimension */
/* so that as much of its segments are aligned (more or less) on the */
/* grid. To find out the optimal scaling and shifting value, various */
/* parameter combinations are tried and scored. */
/* */
/* This experimental option is only active if the render mode is */
/* FT_RENDER_MODE_LIGHT. */
/* */
/* #define AF_CONFIG_OPTION_USE_WARPER */
/* */ /* */

View file

@ -4,8 +4,7 @@
/* */ /* */
/* FreeType high-level API and common types (specification only). */ /* FreeType high-level API and common types (specification only). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ /* Copyright 1996-2011 by */
/* 2010 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -227,10 +226,12 @@ FT_BEGIN_HEADER
/* Left side bearing for vertical layout. */ /* Left side bearing for vertical layout. */
/* */ /* */
/* vertBearingY :: */ /* vertBearingY :: */
/* Top side bearing for vertical layout. */ /* Top side bearing for vertical layout. Larger positive values */
/* mean further below the vertical glyph origin. */
/* */ /* */
/* vertAdvance :: */ /* vertAdvance :: */
/* Advance height for vertical layout. */ /* Advance height for vertical layout. Positive values mean the */
/* glyph has a positive advance downward. */
/* */ /* */
/* <Note> */ /* <Note> */
/* If not disabled with @FT_LOAD_NO_HINTING, the values represent */ /* If not disabled with @FT_LOAD_NO_HINTING, the values represent */
@ -1058,7 +1059,7 @@ FT_BEGIN_HEADER
/* */ /* */
/* It is not possible to autohint such fonts using */ /* It is not possible to autohint such fonts using */
/* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */
/* @FT_LOAD_NO_HINTING. You have to set both FT_LOAD_NO_HINTING */ /* @FT_LOAD_NO_HINTING. You have to set both @FT_LOAD_NO_HINTING */
/* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */
/* probably never want this except for demonstration purposes. */ /* probably never want this except for demonstration purposes. */
/* */ /* */
@ -2445,13 +2446,7 @@ FT_BEGIN_HEADER
* in fonts. By default, FreeType tries to handle broken fonts also. * in fonts. By default, FreeType tries to handle broken fonts also.
* *
* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ::
* Indicates that the font driver should ignore the global advance * Ignored. Deprecated.
* width defined in the font. By default, that value is used as the
* advance width for all glyphs when the face has
* @FT_FACE_FLAG_FIXED_WIDTH set.
*
* This flag exists for historical reasons (to support buggy CJK
* fonts).
* *
* FT_LOAD_NO_RECURSE :: * FT_LOAD_NO_RECURSE ::
* This flag is only used internally. It merely indicates that the * This flag is only used internally. It merely indicates that the
@ -3808,7 +3803,7 @@ FT_BEGIN_HEADER
*/ */
#define FREETYPE_MAJOR 2 #define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 4 #define FREETYPE_MINOR 4
#define FREETYPE_PATCH 4 #define FREETYPE_PATCH 5
/*************************************************************************/ /*************************************************************************/

View file

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType exact bbox computation (specification). */ /* FreeType exact bbox computation (specification). */
/* */ /* */
/* Copyright 1996-2001, 2003, 2007 by */ /* Copyright 1996-2001, 2003, 2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -73,6 +73,14 @@ FT_BEGIN_HEADER
/* <Return> */ /* <Return> */
/* FreeType error code. 0~means success. */ /* FreeType error code. 0~means success. */
/* */ /* */
/* <Note> */
/* If the font is tricky and the glyph has been loaded with */
/* @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get */
/* reasonable values for the BBox it is necessary to load the glyph */
/* at a large ppem value (so that the hinting instructions can */
/* properly shift and scale the subglyphs), then extracting the BBox */
/* which can be eventually converted back to font units. */
/* */
FT_EXPORT( FT_Error ) FT_EXPORT( FT_Error )
FT_Outline_Get_BBox( FT_Outline* outline, FT_Outline_Get_BBox( FT_Outline* outline,
FT_BBox *abbox ); FT_BBox *abbox );

View file

@ -0,0 +1,102 @@
/***************************************************************************/
/* */
/* ftbzip2.h */
/* */
/* Bzip2-compressed stream support. */
/* */
/* Copyright 2010 by */
/* Joel Klinghed. */
/* */
/* 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 __FTBZIP2_H__
#define __FTBZIP2_H__
#include <ft2build.h>
#include FT_FREETYPE_H
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Section> */
/* bzip2 */
/* */
/* <Title> */
/* BZIP2 Streams */
/* */
/* <Abstract> */
/* Using bzip2-compressed font files. */
/* */
/* <Description> */
/* This section contains the declaration of Bzip2-specific functions. */
/* */
/*************************************************************************/
/************************************************************************
*
* @function:
* FT_Stream_OpenBzip2
*
* @description:
* Open a new stream to parse bzip2-compressed font files. This is
* mainly used to support the compressed `*.pcf.bz2' fonts that come
* with XFree86.
*
* @input:
* stream ::
* The target embedding stream.
*
* source ::
* The source stream.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* The source stream must be opened _before_ calling this function.
*
* Calling the internal function `FT_Stream_Close' on the new stream will
* *not* call `FT_Stream_Close' on the source stream. None of the stream
* objects will be released to the heap.
*
* The stream implementation is very basic and resets the decompression
* process each time seeking backwards is needed within the stream.
*
* In certain builds of the library, bzip2 compression recognition is
* automatically handled when calling @FT_New_Face or @FT_Open_Face.
* This means that if no font driver is capable of handling the raw
* compressed file, the library will try to open a bzip2 compressed stream
* from it and re-open the face with it.
*
* This function may return `FT_Err_Unimplemented_Feature' if your build
* of FreeType was not compiled with bzip2 support.
*/
FT_EXPORT( FT_Error )
FT_Stream_OpenBzip2( FT_Stream stream,
FT_Stream source );
/* */
FT_END_HEADER
#endif /* __FTBZIP2_H__ */
/* END */

View file

@ -98,6 +98,7 @@
/* module_management */ /* module_management */
/* gzip */ /* gzip */
/* lzw */ /* lzw */
/* bzip2 */
/* lcd_filtering */ /* lcd_filtering */
/* */ /* */
/***************************************************************************/ /***************************************************************************/

View file

@ -214,7 +214,6 @@
FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, \ FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, \
"no Unicode glyph name found" ) "no Unicode glyph name found" )
/* BDF errors */ /* BDF errors */
FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \ FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Access of TrueType's `gasp' table (specification). */ /* Access of TrueType's `gasp' table (specification). */
/* */ /* */
/* Copyright 2007, 2008 by */ /* Copyright 2007, 2008, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -63,18 +63,26 @@
* *
* FT_GASP_DO_GRIDFIT :: * FT_GASP_DO_GRIDFIT ::
* Grid-fitting and hinting should be performed at the specified ppem. * Grid-fitting and hinting should be performed at the specified ppem.
* This *really* means TrueType bytecode interpretation. * This *really* means TrueType bytecode interpretation. If this bit
* is not set, no hinting gets applied.
* *
* FT_GASP_DO_GRAY :: * FT_GASP_DO_GRAY ::
* Anti-aliased rendering should be performed at the specified ppem. * Anti-aliased rendering should be performed at the specified ppem.
* If not set, do monochrome rendering.
* *
* FT_GASP_SYMMETRIC_SMOOTHING :: * FT_GASP_SYMMETRIC_SMOOTHING ::
* Smoothing along multiple axes must be used with ClearType. * If set, smoothing along multiple axes must be used with ClearType.
* *
* FT_GASP_SYMMETRIC_GRIDFIT :: * FT_GASP_SYMMETRIC_GRIDFIT ::
* Grid-fitting must be used with ClearType's symmetric smoothing. * Grid-fitting must be used with ClearType's symmetric smoothing.
* *
* @note: * @note:
* The bit-flags `FT_GASP_DO_GRIDFIT' and `FT_GASP_DO_GRAY' are to be
* used for standard font rasterization only. Independently of that,
* `FT_GASP_SYMMETRIC_SMOOTHING' and `FT_GASP_SYMMETRIC_GRIDFIT' are to
* be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT' and
* `FT_GASP_DO_GRAY' are consequently ignored).
*
* `ClearType' is Microsoft's implementation of LCD rendering, partly * `ClearType' is Microsoft's implementation of LCD rendering, partly
* protected by patents. * protected by patents.
* *

View file

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType convenience functions to handle glyphs (specification). */ /* FreeType convenience functions to handle glyphs (specification). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ /* Copyright 1996-2003, 2006, 2008, 2009, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -384,6 +384,13 @@ FT_BEGIN_HEADER
/* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS */ /* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS */
/* is another name for this constant. */ /* is another name for this constant. */
/* */ /* */
/* If the font is tricky and the glyph has been loaded with */
/* @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get */
/* reasonable values for the CBox it is necessary to load the glyph */
/* at a large ppem value (so that the hinting instructions can */
/* properly shift and scale the subglyphs), then extracting the CBox */
/* which can be eventually converted back to font units. */
/* */
/* Note that the maximum coordinates are exclusive, which means that */ /* Note that the maximum coordinates are exclusive, which means that */
/* one can compute the width and height of the glyph image (be it in */ /* one can compute the width and height of the glyph image (be it in */
/* integer or 26.6 pixels) as: */ /* integer or 26.6 pixels) as: */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType module error offsets (specification). */ /* FreeType module error offsets (specification). */
/* */ /* */
/* Copyright 2001, 2002, 2003, 2004, 2005 by */ /* Copyright 2001, 2002, 2003, 2004, 2005, 2010 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -105,24 +105,25 @@
FT_MODERRDEF( Base, 0x000, "base module" ) FT_MODERRDEF( Base, 0x000, "base module" )
FT_MODERRDEF( Autofit, 0x100, "autofitter module" ) FT_MODERRDEF( Autofit, 0x100, "autofitter module" )
FT_MODERRDEF( BDF, 0x200, "BDF module" ) FT_MODERRDEF( BDF, 0x200, "BDF module" )
FT_MODERRDEF( Cache, 0x300, "cache module" ) FT_MODERRDEF( Bzip2, 0x300, "Bzip2 module" )
FT_MODERRDEF( CFF, 0x400, "CFF module" ) FT_MODERRDEF( Cache, 0x400, "cache module" )
FT_MODERRDEF( CID, 0x500, "CID module" ) FT_MODERRDEF( CFF, 0x500, "CFF module" )
FT_MODERRDEF( Gzip, 0x600, "Gzip module" ) FT_MODERRDEF( CID, 0x600, "CID module" )
FT_MODERRDEF( LZW, 0x700, "LZW module" ) FT_MODERRDEF( Gzip, 0x700, "Gzip module" )
FT_MODERRDEF( OTvalid, 0x800, "OpenType validation module" ) FT_MODERRDEF( LZW, 0x800, "LZW module" )
FT_MODERRDEF( PCF, 0x900, "PCF module" ) FT_MODERRDEF( OTvalid, 0x900, "OpenType validation module" )
FT_MODERRDEF( PFR, 0xA00, "PFR module" ) FT_MODERRDEF( PCF, 0xA00, "PCF module" )
FT_MODERRDEF( PSaux, 0xB00, "PS auxiliary module" ) FT_MODERRDEF( PFR, 0xB00, "PFR module" )
FT_MODERRDEF( PShinter, 0xC00, "PS hinter module" ) FT_MODERRDEF( PSaux, 0xC00, "PS auxiliary module" )
FT_MODERRDEF( PSnames, 0xD00, "PS names module" ) FT_MODERRDEF( PShinter, 0xD00, "PS hinter module" )
FT_MODERRDEF( Raster, 0xE00, "raster module" ) FT_MODERRDEF( PSnames, 0xE00, "PS names module" )
FT_MODERRDEF( SFNT, 0xF00, "SFNT module" ) FT_MODERRDEF( Raster, 0xF00, "raster module" )
FT_MODERRDEF( Smooth, 0x1000, "smooth raster module" ) FT_MODERRDEF( SFNT, 0x1000, "SFNT module" )
FT_MODERRDEF( TrueType, 0x1100, "TrueType module" ) FT_MODERRDEF( Smooth, 0x1100, "smooth raster module" )
FT_MODERRDEF( Type1, 0x1200, "Type 1 module" ) FT_MODERRDEF( TrueType, 0x1200, "TrueType module" )
FT_MODERRDEF( Type42, 0x1300, "Type 42 module" ) FT_MODERRDEF( Type1, 0x1300, "Type 1 module" )
FT_MODERRDEF( Winfonts, 0x1400, "Windows FON/FNT module" ) FT_MODERRDEF( Type42, 0x1400, "Type 42 module" )
FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" )
#ifdef FT_MODERR_END_LIST #ifdef FT_MODERR_END_LIST

View file

@ -5,7 +5,7 @@
/* Support for the FT_Outline type used to store glyph shapes of */ /* Support for the FT_Outline type used to store glyph shapes of */
/* most scalable font formats (specification). */ /* most scalable font formats (specification). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 by */ /* Copyright 1996-2003, 2005-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -227,6 +227,9 @@ FT_BEGIN_HEADER
/* <Output> */ /* <Output> */
/* acbox :: The outline's control box. */ /* acbox :: The outline's control box. */
/* */ /* */
/* <Note> */
/* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */
/* */
FT_EXPORT( void ) FT_EXPORT( void )
FT_Outline_Get_CBox( const FT_Outline* outline, FT_Outline_Get_CBox( const FT_Outline* outline,
FT_BBox *acbox ); FT_BBox *acbox );
@ -332,7 +335,7 @@ FT_BEGIN_HEADER
/* handled incorrectly. */ /* handled incorrectly. */
/* */ /* */
/* If you need `better' metrics values you should call */ /* If you need `better' metrics values you should call */
/* @FT_Outline_Get_CBox ot @FT_Outline_Get_BBox. */ /* @FT_Outline_Get_CBox or @FT_Outline_Get_BBox. */
/* */ /* */
/* Example call: */ /* Example call: */
/* */ /* */

View file

@ -212,6 +212,14 @@ FT_BEGIN_HEADER
/* */ /* */
/* This doesn't change the current renderer for other formats. */ /* This doesn't change the current renderer for other formats. */
/* */ /* */
/* Currently, only the B/W renderer, if compiled with */
/* FT_RASTER_OPTION_ANTI_ALIASING (providing a 5-levels */
/* anti-aliasing mode; this option must be set directly in */
/* `ftraster.c' and is undefined by default) accepts a single tag */
/* `pal5' to set its gray palette as a character string with */
/* 5~elements. Consequently, the third and fourth argument are zero */
/* normally. */
/* */
FT_EXPORT( FT_Error ) FT_EXPORT( FT_Error )
FT_Set_Renderer( FT_Library library, FT_Set_Renderer( FT_Library library,
FT_Renderer renderer, FT_Renderer renderer,

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Stream handling (specification). */ /* Stream handling (specification). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2004, 2005, 2006 by */ /* Copyright 1996-2002, 2004-2006, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -292,18 +292,18 @@ FT_BEGIN_HEADER
#define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetChar, FT_Char ) #define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetChar, FT_Char )
#define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetChar, FT_Byte ) #define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetChar, FT_Byte )
#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_Short ) #define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_Short )
#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_UShort ) #define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_UShort )
#define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_Long ) #define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_Long )
#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_ULong ) #define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_ULong )
#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetLong, FT_Long ) #define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetULong, FT_Long )
#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong ) #define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetULong, FT_ULong )
#define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong ) #define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetULong, FT_ULong )
#define FT_GET_SHORT_LE() FT_GET_MACRO( FT_Stream_GetShortLE, FT_Short ) #define FT_GET_SHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Short )
#define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetShortLE, FT_UShort ) #define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UShort )
#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, FT_Long ) #define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_Long )
#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, FT_ULong ) #define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_ULong )
#endif #endif
#define FT_READ_MACRO( func, type, var ) \ #define FT_READ_MACRO( func, type, var ) \
@ -312,17 +312,17 @@ FT_BEGIN_HEADER
#define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var ) #define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var )
#define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var ) #define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var )
#define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadShort, FT_Short, var ) #define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_Short, var )
#define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadShort, FT_UShort, var ) #define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_UShort, var )
#define FT_READ_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_Long, var ) #define FT_READ_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_Long, var )
#define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_ULong, var ) #define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_ULong, var )
#define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_Long, var ) #define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_Long, var )
#define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_ULong, var ) #define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_ULong, var )
#define FT_READ_SHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_Short, var ) #define FT_READ_SHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Short, var )
#define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_UShort, var ) #define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UShort, var )
#define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_Long, var ) #define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Long, var )
#define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_ULong, var ) #define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_ULong, var )
#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM #ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
@ -431,25 +431,25 @@ FT_BEGIN_HEADER
FT_BASE( FT_Char ) FT_BASE( FT_Char )
FT_Stream_GetChar( FT_Stream stream ); FT_Stream_GetChar( FT_Stream stream );
/* read a 16-bit big-endian integer from an entered frame */ /* read a 16-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_Short ) FT_BASE( FT_UShort )
FT_Stream_GetShort( FT_Stream stream ); FT_Stream_GetUShort( FT_Stream stream );
/* read a 24-bit big-endian integer from an entered frame */ /* read a 24-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_Long ) FT_BASE( FT_ULong )
FT_Stream_GetOffset( FT_Stream stream ); FT_Stream_GetUOffset( FT_Stream stream );
/* read a 32-bit big-endian integer from an entered frame */ /* read a 32-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_Long ) FT_BASE( FT_ULong )
FT_Stream_GetLong( FT_Stream stream ); FT_Stream_GetULong( FT_Stream stream );
/* read a 16-bit little-endian integer from an entered frame */ /* read a 16-bit little-endian unsigned integer from an entered frame */
FT_BASE( FT_Short ) FT_BASE( FT_UShort )
FT_Stream_GetShortLE( FT_Stream stream ); FT_Stream_GetUShortLE( FT_Stream stream );
/* read a 32-bit little-endian integer from an entered frame */ /* read a 32-bit little-endian unsigned integer from an entered frame */
FT_BASE( FT_Long ) FT_BASE( FT_ULong )
FT_Stream_GetLongLE( FT_Stream stream ); FT_Stream_GetULongLE( FT_Stream stream );
/* read a byte from a stream */ /* read a byte from a stream */
@ -457,30 +457,30 @@ FT_BEGIN_HEADER
FT_Stream_ReadChar( FT_Stream stream, FT_Stream_ReadChar( FT_Stream stream,
FT_Error* error ); FT_Error* error );
/* read a 16-bit big-endian integer from a stream */ /* read a 16-bit big-endian unsigned integer from a stream */
FT_BASE( FT_Short ) FT_BASE( FT_UShort )
FT_Stream_ReadShort( FT_Stream stream, FT_Stream_ReadUShort( FT_Stream stream,
FT_Error* error );
/* read a 24-bit big-endian integer from a stream */
FT_BASE( FT_Long )
FT_Stream_ReadOffset( FT_Stream stream,
FT_Error* error ); FT_Error* error );
/* read a 32-bit big-endian integer from a stream */ /* read a 24-bit big-endian unsigned integer from a stream */
FT_BASE( FT_Long ) FT_BASE( FT_ULong )
FT_Stream_ReadLong( FT_Stream stream, FT_Stream_ReadUOffset( FT_Stream stream,
FT_Error* error );
/* read a 16-bit little-endian integer from a stream */
FT_BASE( FT_Short )
FT_Stream_ReadShortLE( FT_Stream stream,
FT_Error* error ); FT_Error* error );
/* read a 32-bit little-endian integer from a stream */ /* read a 32-bit big-endian integer from a stream */
FT_BASE( FT_Long ) FT_BASE( FT_ULong )
FT_Stream_ReadLongLE( FT_Stream stream, FT_Stream_ReadULong( FT_Stream stream,
FT_Error* error ); FT_Error* error );
/* read a 16-bit little-endian unsigned integer from a stream */
FT_BASE( FT_UShort )
FT_Stream_ReadUShortLE( FT_Stream stream,
FT_Error* error );
/* read a 32-bit little-endian unsigned integer from a stream */
FT_BASE( FT_ULong )
FT_Stream_ReadULongLE( FT_Stream stream,
FT_Error* error );
/* Read a structure from a stream. The structure must be described */ /* Read a structure from a stream. The structure must be described */
/* by an array of FT_Frame_Field records. */ /* by an array of FT_Frame_Field records. */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Tracing handling (specification only). */ /* Tracing handling (specification only). */
/* */ /* */
/* Copyright 2002, 2004, 2005, 2006, 2007 by */ /* Copyright 2002, 2004-2007, 2009, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -135,5 +135,10 @@ FT_TRACE_DEF( gxvtrak )
FT_TRACE_DEF( gxvprop ) FT_TRACE_DEF( gxvprop )
FT_TRACE_DEF( gxvlcar ) FT_TRACE_DEF( gxvlcar )
/* autofit components */
FT_TRACE_DEF( afcjk )
FT_TRACE_DEF( aflatin )
FT_TRACE_DEF( aflatin2 )
FT_TRACE_DEF( afwarp )
/* END */ /* END */

View file

@ -5,7 +5,7 @@
/* Basic SFNT/TrueType tables definitions and interface */ /* Basic SFNT/TrueType tables definitions and interface */
/* (specification only). */ /* (specification only). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010 by */ /* Copyright 1996-2005, 2008-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -687,12 +687,16 @@ FT_BEGIN_HEADER
* The index of an SFNT table. The function returns * The index of an SFNT table. The function returns
* FT_Err_Table_Missing for an invalid value. * FT_Err_Table_Missing for an invalid value.
* *
* @output: * @inout:
* tag :: * tag ::
* The name tag of the SFNT table. * The name tag of the SFNT table. If the value is NULL, `table_index'
* is ignored, and `length' returns the number of SFNT tables in the
* font.
* *
* @output:
* length :: * length ::
* The length of the SFNT table. * The length of the SFNT table (or the number of SFNT tables, depending
* on `tag').
* *
* @return: * @return:
* FreeType error code. 0~means success. * FreeType error code. 0~means success.

View file

@ -1,6 +1,6 @@
# modules.cfg # modules.cfg
# #
# Copyright 2005, 2006, 2007, 2009 by # Copyright 2005, 2006, 2007, 2009, 2010 by
# David Turner, Robert Wilhelm, and Werner Lemberg. # David Turner, Robert Wilhelm, and Werner Lemberg.
# #
# This file is part of the FreeType project, and may only be used, modified, # This file is part of the FreeType project, and may only be used, modified,
@ -122,6 +122,11 @@ AUX_MODULES += gzip
# See include/freetype/ftlzw.h for the API. # See include/freetype/ftlzw.h for the API.
AUX_MODULES += lzw AUX_MODULES += lzw
# Support for streams compressed with bzip2 (files with suffix .bz2).
#
# See include/freetype/ftbzip2.h for the API.
AUX_MODULES += bzip2
# OpenType table validation. Needs ftotval.c below. # OpenType table validation. Needs ftotval.c below.
# #
# AUX_MODULES += otvalid # AUX_MODULES += otvalid

View file

@ -5,7 +5,7 @@
/* Routines used to compute vector angles with limited accuracy */ /* Routines used to compute vector angles with limited accuracy */
/* and very high speed. It also contains sorting routines (body). */ /* and very high speed. It also contains sorting routines (body). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006 by */ /* Copyright 2003-2006, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -77,7 +77,7 @@
return 1 - 2 * ( delta < 0 ); return 1 - 2 * ( delta < 0 );
} }
#endif #endif /* 0 */
/* /*

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter hinting routines for CJK script (specification). */ /* Auto-fitter hinting routines for CJK script (specification). */
/* */ /* */
/* Copyright 2006, 2007 by */ /* Copyright 2006, 2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -20,6 +20,7 @@
#define __AFCJK_H__ #define __AFCJK_H__
#include "afhints.h" #include "afhints.h"
#include "aflatin.h"
FT_BEGIN_HEADER FT_BEGIN_HEADER
@ -29,23 +30,106 @@ FT_BEGIN_HEADER
AF_DECLARE_SCRIPT_CLASS(af_cjk_script_class) AF_DECLARE_SCRIPT_CLASS(af_cjk_script_class)
/* CJK (global) metrics management */
/*
* CJK glyphs tend to fill the square. So we have both vertical and
* horizontal blue zones. But some glyphs have flat bounding strokes that
* leave some space between neighbour glyphs.
*/
enum
{
AF_CJK_BLUE_TOP,
AF_CJK_BLUE_BOTTOM,
AF_CJK_BLUE_LEFT,
AF_CJK_BLUE_RIGHT,
AF_CJK_BLUE_MAX
};
#define AF_CJK_MAX_WIDTHS 16
#define AF_CJK_MAX_BLUES AF_CJK_BLUE_MAX
enum
{
AF_CJK_BLUE_ACTIVE = 1 << 0,
AF_CJK_BLUE_IS_TOP = 1 << 1,
AF_CJK_BLUE_IS_RIGHT = 1 << 2,
AF_CJK_BLUE_ADJUSTMENT = 1 << 3, /* used for scale adjustment */
/* optimization */
AF_CJK_BLUE_FLAG_MAX
};
typedef struct AF_CJKBlueRec_
{
AF_WidthRec ref;
AF_WidthRec shoot; /* undershoot */
FT_UInt flags;
} AF_CJKBlueRec, *AF_CJKBlue;
typedef struct AF_CJKAxisRec_
{
FT_Fixed scale;
FT_Pos delta;
FT_UInt width_count;
AF_WidthRec widths[AF_CJK_MAX_WIDTHS];
FT_Pos edge_distance_threshold;
FT_Pos standard_width;
FT_Bool extra_light;
/* used for horizontal metrics too for CJK */
FT_Bool control_overshoot;
FT_UInt blue_count;
AF_CJKBlueRec blues[AF_CJK_BLUE_MAX];
FT_Fixed org_scale;
FT_Pos org_delta;
} AF_CJKAxisRec, *AF_CJKAxis;
typedef struct AF_CJKMetricsRec_
{
AF_ScriptMetricsRec root;
FT_UInt units_per_em;
AF_CJKAxisRec axis[AF_DIMENSION_MAX];
} AF_CJKMetricsRec, *AF_CJKMetrics;
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
af_cjk_metrics_init( AF_LatinMetrics metrics, af_cjk_metrics_init( AF_CJKMetrics metrics,
FT_Face face ); FT_Face face );
FT_LOCAL( void ) FT_LOCAL( void )
af_cjk_metrics_scale( AF_LatinMetrics metrics, af_cjk_metrics_scale( AF_CJKMetrics metrics,
AF_Scaler scaler ); AF_Scaler scaler );
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
af_cjk_hints_init( AF_GlyphHints hints, af_cjk_hints_init( AF_GlyphHints hints,
AF_LatinMetrics metrics ); AF_CJKMetrics metrics );
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
af_cjk_hints_apply( AF_GlyphHints hints, af_cjk_hints_apply( AF_GlyphHints hints,
FT_Outline* outline, FT_Outline* outline,
AF_LatinMetrics metrics ); AF_CJKMetrics metrics );
/* Shared. called from afindic.c */
FT_LOCAL( void )
af_cjk_metrics_check_digits( AF_CJKMetrics metrics,
FT_Face face );
FT_LOCAL( void )
af_cjk_metrics_init_widths( AF_CJKMetrics metrics,
FT_Face face,
FT_ULong charcode );
/* */ /* */

View file

@ -5,7 +5,7 @@
/* Auto-fitter dummy routines to be used if no hinting should be */ /* Auto-fitter dummy routines to be used if no hinting should be */
/* performed (body). */ /* performed (body). */
/* */ /* */
/* Copyright 2003, 2004, 2005 by */ /* Copyright 2003-2005, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -19,6 +19,7 @@
#include "afdummy.h" #include "afdummy.h"
#include "afhints.h" #include "afhints.h"
#include "aferrors.h"
static FT_Error static FT_Error
@ -27,7 +28,7 @@
{ {
af_glyph_hints_rescale( hints, af_glyph_hints_rescale( hints,
metrics ); metrics );
return 0; return AF_Err_Ok;
} }
@ -38,11 +39,11 @@
FT_UNUSED( hints ); FT_UNUSED( hints );
FT_UNUSED( outline ); FT_UNUSED( outline );
return 0; return AF_Err_Ok;
} }
AF_DEFINE_SCRIPT_CLASS(af_dummy_script_class, AF_DEFINE_SCRIPT_CLASS( af_dummy_script_class,
AF_SCRIPT_NONE, AF_SCRIPT_NONE,
NULL, NULL,

View file

@ -5,7 +5,7 @@
/* Auto-fitter dummy routines to be used if no hinting should be */ /* Auto-fitter dummy routines to be used if no hinting should be */
/* performed (specification). */ /* performed (specification). */
/* */ /* */
/* Copyright 2003, 2004, 2005 by */ /* Copyright 2003-2005, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -29,7 +29,7 @@ FT_BEGIN_HEADER
* be performed. This is the default for non-latin glyphs! * be performed. This is the default for non-latin glyphs!
*/ */
AF_DECLARE_SCRIPT_CLASS(af_dummy_script_class) AF_DECLARE_SCRIPT_CLASS( af_dummy_script_class )
/* */ /* */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter routines to compute global hinting values (body). */ /* Auto-fitter routines to compute global hinting values (body). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by */ /* Copyright 2003-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -31,8 +31,8 @@
#ifndef FT_CONFIG_OPTION_PIC #ifndef FT_CONFIG_OPTION_PIC
/* when updating this table, don't forget to update /* when updating this table, don't forget to update */
AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */ /* AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */
/* populate this list when you add new scripts */ /* populate this list when you add new scripts */
static AF_ScriptClass const af_script_classes[] = static AF_ScriptClass const af_script_classes[] =
@ -47,7 +47,7 @@
NULL /* do not remove */ NULL /* do not remove */
}; };
#endif /* FT_CONFIG_OPTION_PIC */ #endif /* !FT_CONFIG_OPTION_PIC */
/* index of default script in `af_script_classes' */ /* index of default script in `af_script_classes' */
#define AF_SCRIPT_LIST_DEFAULT 2 #define AF_SCRIPT_LIST_DEFAULT 2
@ -85,7 +85,7 @@
FT_UInt ss, i; FT_UInt ss, i;
/* the value 255 means `uncovered glyph' */ /* the value AF_SCRIPT_LIST_NONE means `uncovered glyph' */
FT_MEM_SET( globals->glyph_scripts, FT_MEM_SET( globals->glyph_scripts,
AF_SCRIPT_LIST_NONE, AF_SCRIPT_LIST_NONE,
globals->glyph_count ); globals->glyph_count );
@ -126,9 +126,7 @@
if ( gindex != 0 && if ( gindex != 0 &&
gindex < (FT_ULong)globals->glyph_count && gindex < (FT_ULong)globals->glyph_count &&
gscripts[gindex] == AF_SCRIPT_LIST_NONE ) gscripts[gindex] == AF_SCRIPT_LIST_NONE )
{
gscripts[gindex] = (FT_Byte)ss; gscripts[gindex] = (FT_Byte)ss;
}
for (;;) for (;;)
{ {
@ -139,9 +137,7 @@
if ( gindex < (FT_ULong)globals->glyph_count && if ( gindex < (FT_ULong)globals->glyph_count &&
gscripts[gindex] == AF_SCRIPT_LIST_NONE ) gscripts[gindex] == AF_SCRIPT_LIST_NONE )
{
gscripts[gindex] = (FT_Byte)ss; gscripts[gindex] = (FT_Byte)ss;
}
} }
} }
} }

View file

@ -5,7 +5,7 @@
/* Auto-fitter routines to compute global hinting values */ /* Auto-fitter routines to compute global hinting values */
/* (specification). */ /* (specification). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2007, 2009 by */ /* Copyright 2003-2005, 2007, 2009, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -17,8 +17,8 @@
/***************************************************************************/ /***************************************************************************/
#ifndef __AF_GLOBAL_H__ #ifndef __AFGLOBAL_H__
#define __AF_GLOBAL_H__ #define __AFGLOBAL_H__
#include "aftypes.h" #include "aftypes.h"
@ -65,7 +65,7 @@ FT_BEGIN_HEADER
FT_END_HEADER FT_END_HEADER
#endif /* __AF_GLOBALS_H__ */ #endif /* __AFGLOBAL_H__ */
/* END */ /* END */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter hinting routines (body). */ /* Auto-fitter hinting routines (body). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ /* Copyright 2003-2007, 2009-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -21,6 +21,8 @@
#include FT_INTERNAL_CALC_H #include FT_INTERNAL_CALC_H
/* Get new segment for given axis. */
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_axis_hints_new_segment( AF_AxisHints axis, af_axis_hints_new_segment( AF_AxisHints axis,
FT_Memory memory, FT_Memory memory,
@ -61,6 +63,8 @@
} }
/* Get new edge for given axis, direction, and position. */
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
af_axis_hints_new_edge( AF_AxisHints axis, af_axis_hints_new_edge( AF_AxisHints axis,
FT_Int fpos, FT_Int fpos,
@ -125,7 +129,7 @@
} }
#ifdef AF_DEBUG #ifdef FT_DEBUG_AUTOFIT
#include FT_CONFIG_STANDARD_LIBRARY_H #include FT_CONFIG_STANDARD_LIBRARY_H
@ -160,6 +164,9 @@
#define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 ) #define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 )
#ifdef __cplusplus
extern "C" {
#endif
void void
af_glyph_hints_dump_points( AF_GlyphHints hints ) af_glyph_hints_dump_points( AF_GlyphHints hints )
{ {
@ -169,20 +176,20 @@
printf( "Table of points:\n" ); printf( "Table of points:\n" );
printf( " [ index | xorg | yorg | xscale | yscale " printf( " [ index | xorg | yorg | xscale | yscale"
"| xfit | yfit | flags ]\n" ); " | xfit | yfit | flags ]\n" );
for ( point = points; point < limit; point++ ) for ( point = points; point < limit; point++ )
{ {
printf( " [ %5d | %5d | %5d | %-5.2f | %-5.2f " printf( " [ %5d | %5d | %5d | %6.2f | %6.2f"
"| %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n", " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n",
point - points, point - points,
point->fx, point->fx,
point->fy, point->fy,
point->ox/64.0, point->ox / 64.0,
point->oy/64.0, point->oy / 64.0,
point->x/64.0, point->x / 64.0,
point->y/64.0, point->y / 64.0,
( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ', ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ',
( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ', ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ',
( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ', ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ',
@ -192,6 +199,9 @@
} }
printf( "\n" ); printf( "\n" );
} }
#ifdef __cplusplus
}
#endif
static const char* static const char*
@ -222,7 +232,11 @@
} }
/* A function to dump the array of linked segments. */ /* Dump the array of linked segments. */
#ifdef __cplusplus
extern "C" {
#endif
void void
af_glyph_hints_dump_segments( AF_GlyphHints hints ) af_glyph_hints_dump_segments( AF_GlyphHints hints )
{ {
@ -240,11 +254,11 @@
printf ( "Table of %s segments:\n", printf ( "Table of %s segments:\n",
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
printf ( " [ index | pos | dir | link | serif |" printf ( " [ index | pos | dir | link | serif |"
" height | extra | flags ]\n" ); " height | extra | flags ]\n" );
for ( seg = segments; seg < limit; seg++ ) for ( seg = segments; seg < limit; seg++ )
{ {
printf ( " [ %5d | %5.2g | %5s | %4d | %5d | %5d | %5d | %s ]\n", printf ( " [ %5d | %5.2g | %5s | %4d | %5d | %6d | %5d | %11s ]\n",
seg - segments, seg - segments,
dimension == AF_DIMENSION_HORZ ? (int)seg->first->ox / 64.0 dimension == AF_DIMENSION_HORZ ? (int)seg->first->ox / 64.0
: (int)seg->first->oy / 64.0, : (int)seg->first->oy / 64.0,
@ -253,13 +267,84 @@
AF_INDEX_NUM( seg->serif, segments ), AF_INDEX_NUM( seg->serif, segments ),
seg->height, seg->height,
seg->height - ( seg->max_coord - seg->min_coord ), seg->height - ( seg->max_coord - seg->min_coord ),
af_edge_flags_to_string( seg->flags ) ); af_edge_flags_to_string( (AF_Edge_Flags)seg->flags ) );
} }
printf( "\n" ); printf( "\n" );
} }
} }
#ifdef __cplusplus
}
#endif
/* Fetch number of segments. */
#ifdef __cplusplus
extern "C" {
#endif
FT_Error
af_glyph_hints_get_num_segments( AF_GlyphHints hints,
FT_Int dimension,
FT_Int* num_segments )
{
AF_Dimension dim;
AF_AxisHints axis;
dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT;
axis = &hints->axis[dim];
*num_segments = axis->num_segments;
return AF_Err_Ok;
}
#ifdef __cplusplus
}
#endif
/* Fetch offset of segments into user supplied offset array. */
#ifdef __cplusplus
extern "C" {
#endif
FT_Error
af_glyph_hints_get_segment_offset( AF_GlyphHints hints,
FT_Int dimension,
FT_Int idx,
FT_Pos* offset )
{
AF_Dimension dim;
AF_AxisHints axis;
AF_Segment seg;
if ( !offset )
return AF_Err_Invalid_Argument;
dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT;
axis = &hints->axis[dim];
if ( idx < 0 || idx >= axis->num_segments )
return AF_Err_Invalid_Argument;
seg = &axis->segments[idx];
*offset = (dim == AF_DIMENSION_HORZ) ? seg->first->ox
: seg->first->oy;
return AF_Err_Ok;
}
#ifdef __cplusplus
}
#endif
/* Dump the array of linked edges. */
#ifdef __cplusplus
extern "C" {
#endif
void void
af_glyph_hints_dump_edges( AF_GlyphHints hints ) af_glyph_hints_dump_edges( AF_GlyphHints hints )
{ {
@ -276,17 +361,17 @@
/* /*
* note: AF_DIMENSION_HORZ corresponds to _vertical_ edges * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges
* since they have constant a X coordinate. * since they have a constant X coordinate.
*/ */
printf ( "Table of %s edges:\n", printf ( "Table of %s edges:\n",
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
printf ( " [ index | pos | dir | link |" printf ( " [ index | pos | dir | link |"
" serif | blue | opos | pos | flags ]\n" ); " serif | blue | opos | pos | flags ]\n" );
for ( edge = edges; edge < limit; edge++ ) for ( edge = edges; edge < limit; edge++ )
{ {
printf ( " [ %5d | %5.2g | %5s | %4d |" printf ( " [ %5d | %5.2g | %5s | %4d |"
" %5d | %c | %5.2f | %5.2f | %s ]\n", " %5d | %c | %5.2f | %5.2f | %11s ]\n",
edge - edges, edge - edges,
(int)edge->opos / 64.0, (int)edge->opos / 64.0,
af_dir_str( (AF_Direction)edge->dir ), af_dir_str( (AF_Direction)edge->dir ),
@ -295,16 +380,23 @@
edge->blue_edge ? 'y' : 'n', edge->blue_edge ? 'y' : 'n',
edge->opos / 64.0, edge->opos / 64.0,
edge->pos / 64.0, edge->pos / 64.0,
af_edge_flags_to_string( edge->flags ) ); af_edge_flags_to_string( (AF_Edge_Flags)edge->flags ) );
} }
printf( "\n" ); printf( "\n" );
} }
} }
#ifdef __cplusplus
}
#endif
#else /* !AF_DEBUG */ #else /* !FT_DEBUG_AUTOFIT */
/* these empty stubs are only used to link the `ftgrid' test program */ /* these empty stubs are only used to link the `ftgrid' test program */
/* when debugging is disabled */ /* if debugging is disabled */
#ifdef __cplusplus
extern "C" {
#endif
void void
af_glyph_hints_dump_points( AF_GlyphHints hints ) af_glyph_hints_dump_points( AF_GlyphHints hints )
@ -320,16 +412,49 @@
} }
FT_Error
af_glyph_hints_get_num_segments( AF_GlyphHints hints,
FT_Int dimension,
FT_Int* num_segments )
{
FT_UNUSED( hints );
FT_UNUSED( dimension );
FT_UNUSED( num_segments );
return 0;
}
FT_Error
af_glyph_hints_get_segment_offset( AF_GlyphHints hints,
FT_Int dimension,
FT_Int idx,
FT_Pos* offset )
{
FT_UNUSED( hints );
FT_UNUSED( dimension );
FT_UNUSED( idx );
FT_UNUSED( offset );
return 0;
}
void void
af_glyph_hints_dump_edges( AF_GlyphHints hints ) af_glyph_hints_dump_edges( AF_GlyphHints hints )
{ {
FT_UNUSED( hints ); FT_UNUSED( hints );
} }
#endif /* !AF_DEBUG */ #ifdef __cplusplus
}
#endif
#endif /* !FT_DEBUG_AUTOFIT */
/* compute the direction value of a given vector */ /* Compute the direction value of a given vector. */
FT_LOCAL_DEF( AF_Direction ) FT_LOCAL_DEF( AF_Direction )
af_direction_compute( FT_Pos dx, af_direction_compute( FT_Pos dx,
FT_Pos dy ) FT_Pos dy )
@ -369,6 +494,8 @@
} }
} }
/* return no direction if arm lengths differ too much */
/* (value 14 is heuristic) */
ss *= 14; ss *= 14;
if ( FT_ABS( ll ) <= FT_ABS( ss ) ) if ( FT_ABS( ll ) <= FT_ABS( ss ) )
dir = AF_DIR_NONE; dir = AF_DIR_NONE;
@ -397,7 +524,7 @@
/* /*
* note that we don't need to free the segment and edge * note that we don't need to free the segment and edge
* buffers, since they are really within the hints->points array * buffers since they are really within the hints->points array
*/ */
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
{ {
@ -408,8 +535,8 @@
axis->max_segments = 0; axis->max_segments = 0;
FT_FREE( axis->segments ); FT_FREE( axis->segments );
axis->num_edges = 0; axis->num_edges = 0;
axis->max_edges = 0; axis->max_edges = 0;
FT_FREE( axis->edges ); FT_FREE( axis->edges );
} }
@ -426,6 +553,8 @@
} }
/* Reset metrics. */
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_glyph_hints_rescale( AF_GlyphHints hints, af_glyph_hints_rescale( AF_GlyphHints hints,
AF_ScriptMetrics metrics ) AF_ScriptMetrics metrics )
@ -435,6 +564,9 @@
} }
/* Recompute all AF_Point in AF_GlyphHints from the definitions */
/* in a source outline. */
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_glyph_hints_reload( AF_GlyphHints hints, af_glyph_hints_reload( AF_GlyphHints hints,
FT_Outline* outline ) FT_Outline* outline )
@ -457,12 +589,12 @@
hints->axis[1].num_segments = 0; hints->axis[1].num_segments = 0;
hints->axis[1].num_edges = 0; hints->axis[1].num_edges = 0;
/* first of all, reallocate the contours array when necessary */ /* first of all, reallocate the contours array if necessary */
new_max = (FT_UInt)outline->n_contours; new_max = (FT_UInt)outline->n_contours;
old_max = hints->max_contours; old_max = hints->max_contours;
if ( new_max > old_max ) if ( new_max > old_max )
{ {
new_max = ( new_max + 3 ) & ~3; new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */
if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
goto Exit; goto Exit;
@ -479,7 +611,7 @@
old_max = hints->max_points; old_max = hints->max_points;
if ( new_max > old_max ) if ( new_max > old_max )
{ {
new_max = ( new_max + 2 + 7 ) & ~7; new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */
if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
goto Exit; goto Exit;
@ -545,7 +677,7 @@
point->flags = AF_FLAG_CUBIC; point->flags = AF_FLAG_CUBIC;
break; break;
default: default:
point->flags = 0; point->flags = AF_FLAG_NONE;
} }
point->prev = prev; point->prev = prev;
@ -563,7 +695,7 @@
} }
} }
/* set-up the contours array */ /* set up the contours array */
{ {
AF_Point* contour = hints->contours; AF_Point* contour = hints->contours;
AF_Point* contour_limit = contour + hints->num_contours; AF_Point* contour_limit = contour + hints->num_contours;
@ -611,6 +743,8 @@
in_dir = af_direction_compute( out_x, out_y ); in_dir = af_direction_compute( out_x, out_y );
point->out_dir = (FT_Char)in_dir; point->out_dir = (FT_Char)in_dir;
/* check for weak points */
if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) ) if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) )
{ {
Is_Weak_Point: Is_Weak_Point:
@ -639,6 +773,8 @@
} }
/* Store the hinted outline in an FT_Outline structure. */
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_glyph_hints_save( AF_GlyphHints hints, af_glyph_hints_save( AF_GlyphHints hints,
FT_Outline* outline ) FT_Outline* outline )
@ -671,6 +807,9 @@
****************************************************************/ ****************************************************************/
/* Align all points of an edge to the same coordinate value, */
/* either horizontally or vertically. */
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_glyph_hints_align_edge_points( AF_GlyphHints hints, af_glyph_hints_align_edge_points( AF_GlyphHints hints,
AF_Dimension dim ) AF_Dimension dim )
@ -704,7 +843,6 @@
break; break;
point = point->next; point = point->next;
} }
} }
} }
@ -744,8 +882,8 @@
****************************************************************/ ****************************************************************/
/* hint the strong points -- this is equivalent to the TrueType `IP' */ /* Hint the strong points -- this is equivalent to the TrueType `IP' */
/* hinting instruction */ /* hinting instruction. */
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_glyph_hints_align_strong_points( AF_GlyphHints hints, af_glyph_hints_align_strong_points( AF_GlyphHints hints,
@ -827,11 +965,12 @@
max = edge_limit - edges; max = edge_limit - edges;
#if 1 #if 1
/* for small edge counts, a linear search is better */ /* for a small number of edges, a linear search is better */
if ( max <= 8 ) if ( max <= 8 )
{ {
FT_PtrDist nn; FT_PtrDist nn;
for ( nn = 0; nn < max; nn++ ) for ( nn = 0; nn < max; nn++ )
if ( edges[nn].fpos >= u ) if ( edges[nn].fpos >= u )
break; break;
@ -863,6 +1002,7 @@
} }
} }
/* point is not on an edge */
{ {
AF_Edge before = edges + min - 1; AF_Edge before = edges + min - 1;
AF_Edge after = edges + min + 0; AF_Edge after = edges + min + 0;
@ -898,6 +1038,10 @@
****************************************************************/ ****************************************************************/
/* Shift the original coordinates of all points between `p1' and */
/* `p2' to get hinted coordinates, using the same difference as */
/* given by `ref'. */
static void static void
af_iup_shift( AF_Point p1, af_iup_shift( AF_Point p1,
AF_Point p2, AF_Point p2,
@ -906,6 +1050,7 @@
AF_Point p; AF_Point p;
FT_Pos delta = ref->u - ref->v; FT_Pos delta = ref->u - ref->v;
if ( delta == 0 ) if ( delta == 0 )
return; return;
@ -917,6 +1062,13 @@
} }
/* Interpolate the original coordinates of all points between `p1' and */
/* `p2' to get hinted coordinates, using `ref1' and `ref2' as the */
/* reference points. The `u' and `v' members are the current and */
/* original coordinate values, respectively. */
/* */
/* Details can be found in the TrueType bytecode specification. */
static void static void
af_iup_interp( AF_Point p1, af_iup_interp( AF_Point p1,
AF_Point p2, AF_Point p2,
@ -985,6 +1137,9 @@
} }
/* Hint the weak points -- this is equivalent to the TrueType `IUP' */
/* hinting instruction. */
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_glyph_hints_align_weak_points( AF_GlyphHints hints, af_glyph_hints_align_weak_points( AF_GlyphHints hints,
AF_Dimension dim ) AF_Dimension dim )
@ -1050,17 +1205,18 @@
for (;;) for (;;)
{ {
FT_ASSERT( point <= end_point && FT_ASSERT( point <= end_point &&
( point->flags & touch_flag ) != 0 ); ( point->flags & touch_flag ) != 0 );
/* skip any touched neighbhours */ /* skip any touched neighbours */
while ( point < end_point && ( point[1].flags & touch_flag ) != 0 ) while ( point < end_point &&
( point[1].flags & touch_flag ) != 0 )
point++; point++;
last_touched = point; last_touched = point;
/* find the next touched point, if any */ /* find the next touched point, if any */
point ++; point++;
for (;;) for (;;)
{ {
if ( point > end_point ) if ( point > end_point )
@ -1080,9 +1236,8 @@
EndContour: EndContour:
/* special case: only one point was touched */ /* special case: only one point was touched */
if ( last_touched == first_touched ) if ( last_touched == first_touched )
{
af_iup_shift( first_point, end_point, first_touched ); af_iup_shift( first_point, end_point, first_touched );
}
else /* interpolate the last part */ else /* interpolate the last part */
{ {
if ( last_touched < end_point ) if ( last_touched < end_point )
@ -1112,7 +1267,9 @@
} }
#ifdef AF_USE_WARPER #ifdef AF_CONFIG_OPTION_USE_WARPER
/* Apply (small) warp scale and warp delta for given dimension. */
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_glyph_hints_scale_dim( AF_GlyphHints hints, af_glyph_hints_scale_dim( AF_GlyphHints hints,
@ -1137,6 +1294,6 @@
} }
} }
#endif /* AF_USE_WARPER */ #endif /* AF_CONFIG_OPTION_USE_WARPER */
/* END */ /* END */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter hinting routines (specification). */ /* Auto-fitter hinting routines (specification). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */ /* Copyright 2003-2008, 2010-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -25,10 +25,10 @@
FT_BEGIN_HEADER FT_BEGIN_HEADER
/* /*
* The definition of outline glyph hints. These are shared by all * The definition of outline glyph hints. These are shared by all
* script analysis routines (until now). * script analysis routines (until now).
*/ */
typedef enum AF_Dimension_ typedef enum AF_Dimension_
{ {
@ -55,6 +55,151 @@ FT_BEGIN_HEADER
} AF_Direction; } AF_Direction;
/*
* The following explanations are mostly taken from the article
*
* Real-Time Grid Fitting of Typographic Outlines
*
* by David Turner and Werner Lemberg
*
* http://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf
*
*
* Segments
*
* `af_{cjk,latin,...}_hints_compute_segments' are the functions to
* find segments in an outline. A segment is a series of consecutive
* points that are approximately aligned along a coordinate axis. The
* analysis to do so is specific to a script.
*
* A segment must have at least two points, except in the case of
* `fake' segments that are generated to hint metrics appropriately,
* and which consist of a single point.
*
*
* Edges
*
* As soon as segments are defined, the auto-hinter groups them into
* edges. An edge corresponds to a single position on the main
* dimension that collects one or more segments (allowing for a small
* threshold).
*
* The auto-hinter first tries to grid fit edges, then to align
* segments on the edges unless it detects that they form a serif.
*
* `af_{cjk,latin,...}_hints_compute_edges' are the functions to find
* edges; they are specific to a script.
*
*
* A H
* | |
* | |
* | |
* | |
* C | | F
* +------<-----+ +-----<------+
* | B G |
* | |
* | |
* +--------------->------------------+
* D E
*
*
* Stems
*
* Segments need to be `linked' to other ones in order to detect stems.
* A stem is made of two segments that face each other in opposite
* directions and that are sufficiently close to each other. Using
* vocabulary from the TrueType specification, stem segments form a
* `black distance'.
*
* In the above ASCII drawing, the horizontal segments are BC, DE, and
* FG; the vertical segments are AB, CD, EF, and GH.
*
* Each segment has at most one `best' candidate to form a black
* distance, or no candidate at all. Notice that two distinct segments
* can have the same candidate, which frequently means a serif.
*
* A stem is recognized by the following condition:
*
* best segment_1 = segment_2 && best segment_2 = segment_1
*
* The best candidate is stored in field `link' in structure
* `AF_Segment'.
*
* Stems are detected by `af_{cjk,latin,...}_hint_edges'.
*
* In the above ASCII drawing, the best candidate for both AB and CD is
* GH, while the best candidate for GH is AB. Similarly, the best
* candidate for EF and GH is AB, while the best candidate for AB is
* GH.
*
*
* Serifs
*
* On the opposite, a serif has
*
* best segment_1 = segment_2 && best segment_2 != segment_1
*
* where segment_1 corresponds to the serif segment (CD and EF in the
* above ASCII drawing).
*
* The best candidate is stored in field `serif' in structure
* `AF_Segment' (and `link' is set to NULL).
*
* Serifs are detected by `af_{cjk,latin,...}_hint_edges'.
*
*
* Touched points
*
* A point is called `touched' if it has been processed somehow by the
* auto-hinter. It basically means that it shouldn't be moved again
* (or moved only under certain constraints to preserve the already
* applied processing).
*
*
* Flat and round segments
*
* Segments are `round' or `flat', depending on the series of points
* that define them. A segment is round if the next and previous point
* of an extremum (which can be either a single point or sequence of
* points) are both conic or cubic control points. Otherwise, a
* segment with an extremum is flat.
*
*
* Strong Points
*
* Experience has shown that points which are not part of an edge need
* to be interpolated linearly between their two closest edges, even if
* these are not part of the contour of those particular points.
* Typical candidates for this are
*
* - angle points (i.e., points where the `in' and `out' direction
* differ greatly)
*
* - inflection points (i.e., where the `in' and `out' angles are the
* same, but the curvature changes sign)
*
* `af_glyph_hints_align_strong_points' is the function which takes
* care of such situations; it is equivalent to the TrueType `IP'
* hinting instruction.
*
*
* Weak Points
*
* Other points in the outline must be interpolated using the
* coordinates of their previous and next unfitted contour neighbours.
* These are called `weak points' and are touched by the function
* `af_glyph_hints_align_weak_points', equivalent to the TrueType `IUP'
* hinting instruction. Typical candidates are control points and
* points on the contour without a major direction.
*
* The major effect is to reduce possible distortion caused by
* alignment of edges and strong points, thus weak points are processed
* after strong points.
*/
/* point hint flags */ /* point hint flags */
typedef enum AF_Flags_ typedef enum AF_Flags_
{ {
@ -137,9 +282,8 @@ FT_BEGIN_HEADER
FT_Pos score; /* used during stem matching */ FT_Pos score; /* used during stem matching */
FT_Pos len; /* used during stem matching */ FT_Pos len; /* used during stem matching */
AF_Point first; /* first point in edge segment */ AF_Point first; /* first point in edge segment */
AF_Point last; /* last point in edge segment */ AF_Point last; /* last point in edge segment */
AF_Point* contour; /* ptr to first point of segment's contour */
} AF_SegmentRec; } AF_SegmentRec;
@ -155,32 +299,31 @@ FT_BEGIN_HEADER
FT_Fixed scale; /* used to speed up interpolation between edges */ FT_Fixed scale; /* used to speed up interpolation between edges */
AF_Width blue_edge; /* non-NULL if this is a blue edge */ AF_Width blue_edge; /* non-NULL if this is a blue edge */
AF_Edge link; AF_Edge link; /* link edge */
AF_Edge serif; AF_Edge serif; /* primary edge for serifs */
FT_Short num_linked; FT_Short num_linked; /* number of linked edges */
FT_Int score; /* used during stem matching */
FT_Int score; AF_Segment first; /* first segment in edge */
AF_Segment last; /* last segment in edge */
AF_Segment first;
AF_Segment last;
} AF_EdgeRec; } AF_EdgeRec;
typedef struct AF_AxisHintsRec_ typedef struct AF_AxisHintsRec_
{ {
FT_Int num_segments; FT_Int num_segments; /* number of used segments */
FT_Int max_segments; FT_Int max_segments; /* number of allocated segments */
AF_Segment segments; AF_Segment segments; /* segments array */
#ifdef AF_SORT_SEGMENTS #ifdef AF_SORT_SEGMENTS
FT_Int mid_segments; FT_Int mid_segments;
#endif #endif
FT_Int num_edges; FT_Int num_edges; /* number of used edges */
FT_Int max_edges; FT_Int max_edges; /* number of allocated edges */
AF_Edge edges; AF_Edge edges; /* edges array */
AF_Direction major_dir; AF_Direction major_dir; /* either vertical or horizontal */
} AF_AxisHintsRec, *AF_AxisHints; } AF_AxisHintsRec, *AF_AxisHints;
@ -195,15 +338,13 @@ FT_BEGIN_HEADER
FT_Fixed y_scale; FT_Fixed y_scale;
FT_Pos y_delta; FT_Pos y_delta;
FT_Pos edge_distance_threshold; FT_Int max_points; /* number of allocated points */
FT_Int num_points; /* number of used points */
AF_Point points; /* points array */
FT_Int max_points; FT_Int max_contours; /* number of allocated contours */
FT_Int num_points; FT_Int num_contours; /* number of used contours */
AF_Point points; AF_Point* contours; /* contours array */
FT_Int max_contours;
FT_Int num_contours;
AF_Point* contours;
AF_AxisHintsRec axis[AF_DIMENSION_MAX]; AF_AxisHintsRec axis[AF_DIMENSION_MAX];
@ -222,7 +363,7 @@ FT_BEGIN_HEADER
#define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) ) #define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) )
#ifdef AF_DEBUG #ifdef FT_DEBUG_AUTOFIT
#define AF_HINTS_DO_HORIZONTAL( h ) \ #define AF_HINTS_DO_HORIZONTAL( h ) \
( !_af_debug_disable_horz_hints && \ ( !_af_debug_disable_horz_hints && \
@ -237,7 +378,7 @@ FT_BEGIN_HEADER
#define AF_HINTS_DO_BLUES( h ) ( !_af_debug_disable_blue_hints ) #define AF_HINTS_DO_BLUES( h ) ( !_af_debug_disable_blue_hints )
#else /* !AF_DEBUG */ #else /* !FT_DEBUG_AUTOFIT */
#define AF_HINTS_DO_HORIZONTAL( h ) \ #define AF_HINTS_DO_HORIZONTAL( h ) \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )
@ -250,7 +391,7 @@ FT_BEGIN_HEADER
#define AF_HINTS_DO_BLUES( h ) 1 #define AF_HINTS_DO_BLUES( h ) 1
#endif /* !AF_DEBUG */ #endif /* !FT_DEBUG_AUTOFIT */
FT_LOCAL( AF_Direction ) FT_LOCAL( AF_Direction )
@ -274,12 +415,6 @@ FT_BEGIN_HEADER
af_glyph_hints_init( AF_GlyphHints hints, af_glyph_hints_init( AF_GlyphHints hints,
FT_Memory memory ); FT_Memory memory );
/*
* recompute all AF_Point in a AF_GlyphHints from the definitions
* in a source outline
*/
FT_LOCAL( void ) FT_LOCAL( void )
af_glyph_hints_rescale( AF_GlyphHints hints, af_glyph_hints_rescale( AF_GlyphHints hints,
AF_ScriptMetrics metrics ); AF_ScriptMetrics metrics );
@ -304,7 +439,7 @@ FT_BEGIN_HEADER
af_glyph_hints_align_weak_points( AF_GlyphHints hints, af_glyph_hints_align_weak_points( AF_GlyphHints hints,
AF_Dimension dim ); AF_Dimension dim );
#ifdef AF_USE_WARPER #ifdef AF_CONFIG_OPTION_USE_WARPER
FT_LOCAL( void ) FT_LOCAL( void )
af_glyph_hints_scale_dim( AF_GlyphHints hints, af_glyph_hints_scale_dim( AF_GlyphHints hints,
AF_Dimension dim, AF_Dimension dim,

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter hinting routines for Indic scripts (body). */ /* Auto-fitter hinting routines for Indic scripts (body). */
/* */ /* */
/* Copyright 2007 by */ /* Copyright 2007, 2011 by */
/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ /* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -27,23 +27,42 @@
#include "afcjk.h" #include "afcjk.h"
#ifdef AF_USE_WARPER #ifdef AF_CONFIG_OPTION_USE_WARPER
#include "afwarp.h" #include "afwarp.h"
#endif #endif
static FT_Error static FT_Error
af_indic_metrics_init( AF_LatinMetrics metrics, af_indic_metrics_init( AF_CJKMetrics metrics,
FT_Face face ) FT_Face face )
{ {
/* use CJK routines */ /* skip blue zone init in CJK routines */
return af_cjk_metrics_init( metrics, face ); FT_CharMap oldmap = face->charmap;
metrics->units_per_em = face->units_per_EM;
if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
face->charmap = NULL;
else
{
af_cjk_metrics_init_widths( metrics, face, 0x7530 );
#if 0
/* either need indic specific blue_chars[] or just skip blue zones */
af_cjk_metrics_init_blues( metrics, face, af_cjk_blue_chars );
#endif
af_cjk_metrics_check_digits( metrics, face );
}
FT_Set_Charmap( face, oldmap );
return AF_Err_Ok;
} }
static void static void
af_indic_metrics_scale( AF_LatinMetrics metrics, af_indic_metrics_scale( AF_CJKMetrics metrics,
AF_Scaler scaler ) AF_Scaler scaler )
{ {
/* use CJK routines */ /* use CJK routines */
af_cjk_metrics_scale( metrics, scaler ); af_cjk_metrics_scale( metrics, scaler );
@ -51,8 +70,8 @@
static FT_Error static FT_Error
af_indic_hints_init( AF_GlyphHints hints, af_indic_hints_init( AF_GlyphHints hints,
AF_LatinMetrics metrics ) AF_CJKMetrics metrics )
{ {
/* use CJK routines */ /* use CJK routines */
return af_cjk_hints_init( hints, metrics ); return af_cjk_hints_init( hints, metrics );
@ -60,9 +79,9 @@
static FT_Error static FT_Error
af_indic_hints_apply( AF_GlyphHints hints, af_indic_hints_apply( AF_GlyphHints hints,
FT_Outline* outline, FT_Outline* outline,
AF_LatinMetrics metrics) AF_CJKMetrics metrics )
{ {
/* use CJK routines */ /* use CJK routines */
return af_cjk_hints_apply( hints, outline, metrics ); return af_cjk_hints_apply( hints, outline, metrics );
@ -84,6 +103,12 @@
AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */
#endif #endif
AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL), /* Indic Range */ AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL), /* Indic Range */
AF_UNIRANGE_REC( 0x0F00UL, 0x0FFFUL), /* Tibetan */
AF_UNIRANGE_REC( 0x1900UL, 0x194FUL), /* Limbu */
AF_UNIRANGE_REC( 0x1B80UL, 0x1BBFUL), /* Sundanese */
AF_UNIRANGE_REC( 0x1C80UL, 0x1CDFUL), /* Meetei Mayak */
AF_UNIRANGE_REC( 0xA800UL, 0xA82FUL), /* Syloti Nagri */
AF_UNIRANGE_REC( 0x11800UL, 0x118DFUL), /* Sharada */
AF_UNIRANGE_REC( 0UL, 0UL) AF_UNIRANGE_REC( 0UL, 0UL)
}; };
@ -92,7 +117,7 @@
AF_SCRIPT_INDIC, AF_SCRIPT_INDIC,
af_indic_uniranges, af_indic_uniranges,
sizeof( AF_LatinMetricsRec ), sizeof( AF_CJKMetricsRec ),
(AF_Script_InitMetricsFunc) af_indic_metrics_init, (AF_Script_InitMetricsFunc) af_indic_metrics_init,
(AF_Script_ScaleMetricsFunc)af_indic_metrics_scale, (AF_Script_ScaleMetricsFunc)af_indic_metrics_scale,
@ -114,7 +139,7 @@
AF_SCRIPT_INDIC, AF_SCRIPT_INDIC,
af_indic_uniranges, af_indic_uniranges,
sizeof( AF_LatinMetricsRec ), sizeof( AF_CJKMetricsRec ),
(AF_Script_InitMetricsFunc) NULL, (AF_Script_InitMetricsFunc) NULL,
(AF_Script_ScaleMetricsFunc)NULL, (AF_Script_ScaleMetricsFunc)NULL,

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter hinting routines for latin script (specification). */ /* Auto-fitter hinting routines for latin script (specification). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */ /* Copyright 2003-2007, 2009, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -30,8 +30,8 @@ FT_BEGIN_HEADER
AF_DECLARE_SCRIPT_CLASS(af_latin_script_class) AF_DECLARE_SCRIPT_CLASS(af_latin_script_class)
/* constants are given with units_per_em == 2048 in mind */ /* constants are given with units_per_em == 2048 in mind */
#define AF_LATIN_CONSTANT( metrics, c ) \ #define AF_LATIN_CONSTANT( metrics, c ) \
( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 ) ( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 )
@ -76,10 +76,10 @@ FT_BEGIN_HEADER
enum enum
{ {
AF_LATIN_BLUE_ACTIVE = 1 << 0, AF_LATIN_BLUE_ACTIVE = 1 << 0, /* set if zone height is <= 3/4px */
AF_LATIN_BLUE_TOP = 1 << 1, AF_LATIN_BLUE_TOP = 1 << 1, /* result of AF_LATIN_IS_TOP_BLUE */
AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, /* used for scale adjustment */ AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, /* used for scale adjustment */
/* optimization */ /* optimization */
AF_LATIN_BLUE_FLAG_MAX AF_LATIN_BLUE_FLAG_MAX
}; };
@ -98,14 +98,13 @@ FT_BEGIN_HEADER
FT_Fixed scale; FT_Fixed scale;
FT_Pos delta; FT_Pos delta;
FT_UInt width_count; FT_UInt width_count; /* number of used widths */
AF_WidthRec widths[AF_LATIN_MAX_WIDTHS]; AF_WidthRec widths[AF_LATIN_MAX_WIDTHS]; /* widths array */
FT_Pos edge_distance_threshold; FT_Pos edge_distance_threshold; /* used for creating edges */
FT_Pos standard_width; FT_Pos standard_width; /* the default stem thickness */
FT_Bool extra_light; FT_Bool extra_light; /* is standard width very light? */
/* ignored for horizontal metrics */ /* ignored for horizontal metrics */
FT_Bool control_overshoot;
FT_UInt blue_count; FT_UInt blue_count;
AF_LatinBlueRec blues[AF_LATIN_BLUE_MAX]; AF_LatinBlueRec blues[AF_LATIN_BLUE_MAX];

View file

@ -1,10 +1,10 @@
/***************************************************************************/ /***************************************************************************/
/* */ /* */
/* aflatin.c */ /* aflatin2.c */
/* */ /* */
/* Auto-fitter hinting routines for latin script (body). */ /* Auto-fitter hinting routines for latin script (body). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by */ /* Copyright 2003-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -23,13 +23,24 @@
#include "aferrors.h" #include "aferrors.h"
#ifdef AF_USE_WARPER #ifdef AF_CONFIG_OPTION_USE_WARPER
#include "afwarp.h" #include "afwarp.h"
#endif #endif
/*************************************************************************/
/* */
/* 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_aflatin2
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_latin2_hints_compute_segments( AF_GlyphHints hints, af_latin2_hints_compute_segments( AF_GlyphHints hints,
AF_Dimension dim ); AF_Dimension dim );
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_latin2_hints_link_segments( AF_GlyphHints hints, af_latin2_hints_link_segments( AF_GlyphHints hints,
@ -45,8 +56,8 @@
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_latin2_metrics_init_widths( AF_LatinMetrics metrics, af_latin2_metrics_init_widths( AF_LatinMetrics metrics,
FT_Face face, FT_Face face,
FT_ULong charcode ) FT_ULong charcode )
{ {
/* scan the array of segments in each direction */ /* scan the array of segments in each direction */
AF_GlyphHintsRec hints[1]; AF_GlyphHintsRec hints[1];
@ -156,7 +167,8 @@
#define AF_LATIN_MAX_TEST_CHARACTERS 12 #define AF_LATIN_MAX_TEST_CHARACTERS 12
static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES][AF_LATIN_MAX_TEST_CHARACTERS+1] = static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES]
[AF_LATIN_MAX_TEST_CHARACTERS+1] =
{ {
"THEZOCQS", "THEZOCQS",
"HEZLOCUS", "HEZLOCUS",
@ -169,7 +181,7 @@
static void static void
af_latin2_metrics_init_blues( AF_LatinMetrics metrics, af_latin2_metrics_init_blues( AF_LatinMetrics metrics,
FT_Face face ) FT_Face face )
{ {
FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS];
FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS];
@ -182,12 +194,12 @@
FT_GlyphSlot glyph = face->glyph; FT_GlyphSlot glyph = face->glyph;
/* we compute the blues simply by loading each character from the */ /* we compute the blues simply by loading each character from the */
/* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */ /* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */
/* bottom-most points (depending on `AF_IS_TOP_BLUE') */ /* bottom-most points (depending on `AF_IS_TOP_BLUE') */
AF_LOG(( "blue zones computation\n" )); FT_TRACE5(( "blue zones computation\n" ));
AF_LOG(( "------------------------------------------------\n" )); FT_TRACE5(( "------------------------------------------------\n" ));
for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
{ {
@ -197,7 +209,7 @@
FT_Pos* blue_shoot; FT_Pos* blue_shoot;
AF_LOG(( "blue %3d: ", bb )); FT_TRACE5(( "blue %3d: ", bb ));
num_flats = 0; num_flats = 0;
num_rounds = 0; num_rounds = 0;
@ -210,7 +222,7 @@
FT_Bool round; FT_Bool round;
AF_LOG(( "'%c'", *p )); FT_TRACE5(( "'%c'", *p ));
/* load the character in the face -- skip unknown or empty ones */ /* load the character in the face -- skip unknown or empty ones */
glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
@ -273,7 +285,7 @@
best_last = last; best_last = last;
} }
} }
AF_LOG(( "%5d", best_y )); FT_TRACE5(( "%5d", best_y ));
} }
/* now check whether the point belongs to a straight or round */ /* now check whether the point belongs to a straight or round */
@ -321,7 +333,7 @@
FT_CURVE_TAG( glyph->outline.tags[start] ) != FT_CURVE_TAG_ON || FT_CURVE_TAG( glyph->outline.tags[start] ) != FT_CURVE_TAG_ON ||
FT_CURVE_TAG( glyph->outline.tags[ end ] ) != FT_CURVE_TAG_ON ); FT_CURVE_TAG( glyph->outline.tags[ end ] ) != FT_CURVE_TAG_ON );
AF_LOG(( "%c ", round ? 'r' : 'f' )); FT_TRACE5(( "%c ", round ? 'r' : 'f' ));
} }
if ( round ) if ( round )
@ -330,7 +342,7 @@
flats[num_flats++] = best_y; flats[num_flats++] = best_y;
} }
AF_LOG(( "\n" )); FT_TRACE5(( "\n" ));
if ( num_flats == 0 && num_rounds == 0 ) if ( num_flats == 0 && num_rounds == 0 )
{ {
@ -338,7 +350,7 @@
* we couldn't find a single glyph to compute this blue zone, * we couldn't find a single glyph to compute this blue zone,
* we will simply ignore it then * we will simply ignore it then
*/ */
AF_LOG(( "empty\n" )); FT_TRACE5(( "empty\n" ));
continue; continue;
} }
@ -396,7 +408,7 @@
if ( bb == AF_LATIN_BLUE_SMALL_TOP ) if ( bb == AF_LATIN_BLUE_SMALL_TOP )
blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; blue->flags |= AF_LATIN_BLUE_ADJUSTMENT;
AF_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); FT_TRACE5(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));
} }
return; return;
@ -451,7 +463,7 @@
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_latin2_metrics_init( AF_LatinMetrics metrics, af_latin2_metrics_init( AF_LatinMetrics metrics,
FT_Face face ) FT_Face face )
{ {
FT_Error error = AF_Err_Ok; FT_Error error = AF_Err_Ok;
FT_CharMap oldmap = face->charmap; FT_CharMap oldmap = face->charmap;
@ -492,8 +504,8 @@
static void static void
af_latin2_metrics_scale_dim( AF_LatinMetrics metrics, af_latin2_metrics_scale_dim( AF_LatinMetrics metrics,
AF_Scaler scaler, AF_Scaler scaler,
AF_Dimension dim ) AF_Dimension dim )
{ {
FT_Fixed scale; FT_Fixed scale;
FT_Pos delta; FT_Pos delta;
@ -548,7 +560,10 @@
if ( scaled != fitted ) if ( scaled != fitted )
{ {
scale = FT_MulDiv( scale, fitted, scaled ); scale = FT_MulDiv( scale, fitted, scaled );
AF_LOG(( "== scaled x-top = %.2g fitted = %.2g, scaling = %.4g\n", scaled/64.0, fitted/64.0, (fitted*1.0)/scaled )); FT_TRACE5(( "== scaled x-top = %.2g"
" fitted = %.2g, scaling = %.4g\n",
scaled / 64.0, fitted / 64.0,
( fitted * 1.0 ) / scaled ));
} }
#endif #endif
} }
@ -579,7 +594,7 @@
} }
/* an extra-light axis corresponds to a standard width that is */ /* an extra-light axis corresponds to a standard width that is */
/* smaller than 0.75 pixels */ /* smaller than 5/8 pixels */
axis->extra_light = axis->extra_light =
(FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 );
@ -624,9 +639,11 @@
blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); blue->ref.fit = FT_PIX_ROUND( blue->ref.cur );
blue->shoot.fit = blue->ref.fit + delta2; blue->shoot.fit = blue->ref.fit + delta2;
AF_LOG(( ">> activating blue zone %d: ref.cur=%.2g ref.fit=%.2g shoot.cur=%.2g shoot.fit=%.2g\n", FT_TRACE5(( ">> activating blue zone %d:"
nn, blue->ref.cur/64.0, blue->ref.fit/64.0, " ref.cur=%.2g ref.fit=%.2g"
blue->shoot.cur/64.0, blue->shoot.fit/64.0 )); " shoot.cur=%.2g shoot.fit=%.2g\n",
nn, blue->ref.cur / 64.0, blue->ref.fit / 64.0,
blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 ));
blue->flags |= AF_LATIN_BLUE_ACTIVE; blue->flags |= AF_LATIN_BLUE_ACTIVE;
} }
@ -637,7 +654,7 @@
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_latin2_metrics_scale( AF_LatinMetrics metrics, af_latin2_metrics_scale( AF_LatinMetrics metrics,
AF_Scaler scaler ) AF_Scaler scaler )
{ {
metrics->root.scaler.render_mode = scaler->render_mode; metrics->root.scaler.render_mode = scaler->render_mode;
metrics->root.scaler.face = scaler->face; metrics->root.scaler.face = scaler->face;
@ -659,7 +676,7 @@
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_latin2_hints_compute_segments( AF_GlyphHints hints, af_latin2_hints_compute_segments( AF_GlyphHints hints,
AF_Dimension dim ) AF_Dimension dim )
{ {
AF_AxisHints axis = &hints->axis[dim]; AF_AxisHints axis = &hints->axis[dim];
FT_Memory memory = hints->memory; FT_Memory memory = hints->memory;
@ -779,7 +796,6 @@
segment->dir = first->out_dir; segment->dir = first->out_dir;
segment->first = first; segment->first = first;
segment->last = point; segment->last = point;
segment->contour = contour;
segment->pos = (FT_Short)(( min_u + max_u ) >> 1); segment->pos = (FT_Short)(( min_u + max_u ) >> 1);
segment->min_coord = (FT_Short) min_v; segment->min_coord = (FT_Short) min_v;
segment->max_coord = (FT_Short) max_v; segment->max_coord = (FT_Short) max_v;
@ -917,7 +933,7 @@
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_latin2_hints_link_segments( AF_GlyphHints hints, af_latin2_hints_link_segments( AF_GlyphHints hints,
AF_Dimension dim ) AF_Dimension dim )
{ {
AF_AxisHints axis = &hints->axis[dim]; AF_AxisHints axis = &hints->axis[dim];
AF_Segment segments = axis->segments; AF_Segment segments = axis->segments;
@ -1017,7 +1033,7 @@
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_latin2_hints_compute_edges( AF_GlyphHints hints, af_latin2_hints_compute_edges( AF_GlyphHints hints,
AF_Dimension dim ) AF_Dimension dim )
{ {
AF_AxisHints axis = &hints->axis[dim]; AF_AxisHints axis = &hints->axis[dim];
FT_Error error = AF_Err_Ok; FT_Error error = AF_Err_Ok;
@ -1137,7 +1153,8 @@
/* insert a new edge in the list and */ /* insert a new edge in the list and */
/* sort according to the position */ /* sort according to the position */
error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, memory, &edge ); error = af_axis_hints_new_edge( axis, seg->pos, seg->dir,
memory, &edge );
if ( error ) if ( error )
goto Exit; goto Exit;
@ -1205,8 +1222,10 @@
{ {
FT_Int is_round = 0; /* does it contain round segments? */ FT_Int is_round = 0; /* does it contain round segments? */
FT_Int is_straight = 0; /* does it contain straight segments? */ FT_Int is_straight = 0; /* does it contain straight segments? */
#if 0
FT_Pos ups = 0; /* number of upwards segments */ FT_Pos ups = 0; /* number of upwards segments */
FT_Pos downs = 0; /* number of downwards segments */ FT_Pos downs = 0; /* number of downwards segments */
#endif
seg = edge->first; seg = edge->first;
@ -1222,11 +1241,13 @@
else else
is_straight++; is_straight++;
#if 0
/* check for segment direction */ /* check for segment direction */
if ( seg->dir == up_dir ) if ( seg->dir == up_dir )
ups += seg->max_coord-seg->min_coord; ups += seg->max_coord-seg->min_coord;
else else
downs += seg->max_coord-seg->min_coord; downs += seg->max_coord-seg->min_coord;
#endif
/* check for links -- if seg->serif is set, then seg->link must */ /* check for links -- if seg->serif is set, then seg->link must */
/* be ignored */ /* be ignored */
@ -1318,7 +1339,7 @@
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_latin2_hints_detect_features( AF_GlyphHints hints, af_latin2_hints_detect_features( AF_GlyphHints hints,
AF_Dimension dim ) AF_Dimension dim )
{ {
FT_Error error; FT_Error error;
@ -1336,7 +1357,7 @@
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_latin2_hints_compute_blue_edges( AF_GlyphHints hints, af_latin2_hints_compute_blue_edges( AF_GlyphHints hints,
AF_LatinMetrics metrics ) AF_LatinMetrics metrics )
{ {
AF_AxisHints axis = &hints->axis[ AF_DIMENSION_VERT ]; AF_AxisHints axis = &hints->axis[ AF_DIMENSION_VERT ];
AF_Edge edge = axis->edges; AF_Edge edge = axis->edges;
@ -1442,7 +1463,7 @@
static FT_Error static FT_Error
af_latin2_hints_init( AF_GlyphHints hints, af_latin2_hints_init( AF_GlyphHints hints,
AF_LatinMetrics metrics ) AF_LatinMetrics metrics )
{ {
FT_Render_Mode mode; FT_Render_Mode mode;
FT_UInt32 scaler_flags, other_flags; FT_UInt32 scaler_flags, other_flags;
@ -1463,7 +1484,7 @@
/* compute flags depending on render mode, etc. */ /* compute flags depending on render mode, etc. */
mode = metrics->root.scaler.render_mode; mode = metrics->root.scaler.render_mode;
#if 0 /* #ifdef AF_USE_WARPER */ #if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */
if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
{ {
metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
@ -1524,8 +1545,8 @@
static FT_Pos static FT_Pos
af_latin2_snap_width( AF_Width widths, af_latin2_snap_width( AF_Width widths,
FT_Int count, FT_Int count,
FT_Pos width ) FT_Pos width )
{ {
int n; int n;
FT_Pos best = 64 + 32 + 2; FT_Pos best = 64 + 32 + 2;
@ -1571,10 +1592,10 @@
static FT_Pos static FT_Pos
af_latin2_compute_stem_width( AF_GlyphHints hints, af_latin2_compute_stem_width( AF_GlyphHints hints,
AF_Dimension dim, AF_Dimension dim,
FT_Pos width, FT_Pos width,
AF_Edge_Flags base_flags, AF_Edge_Flags base_flags,
AF_Edge_Flags stem_flags ) AF_Edge_Flags stem_flags )
{ {
AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics;
AF_LatinAxis axis = & metrics->axis[dim]; AF_LatinAxis axis = & metrics->axis[dim];
@ -1739,9 +1760,9 @@
static void static void
af_latin2_align_linked_edge( AF_GlyphHints hints, af_latin2_align_linked_edge( AF_GlyphHints hints,
AF_Dimension dim, AF_Dimension dim,
AF_Edge base_edge, AF_Edge base_edge,
AF_Edge stem_edge ) AF_Edge stem_edge )
{ {
FT_Pos dist = stem_edge->opos - base_edge->opos; FT_Pos dist = stem_edge->opos - base_edge->opos;
@ -1753,17 +1774,17 @@
stem_edge->pos = base_edge->pos + fitted_width; stem_edge->pos = base_edge->pos + fitted_width;
AF_LOG(( "LINK: edge %d (opos=%.2f) linked to (%.2f), " FT_TRACE5(( "LINK: edge %d (opos=%.2f) linked to (%.2f), "
"dist was %.2f, now %.2f\n", "dist was %.2f, now %.2f\n",
stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0, stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,
stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 )); stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
} }
static void static void
af_latin2_align_serif_edge( AF_GlyphHints hints, af_latin2_align_serif_edge( AF_GlyphHints hints,
AF_Edge base, AF_Edge base,
AF_Edge serif ) AF_Edge serif )
{ {
FT_UNUSED( hints ); FT_UNUSED( hints );
@ -1784,7 +1805,7 @@
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_latin2_hint_edges( AF_GlyphHints hints, af_latin2_hint_edges( AF_GlyphHints hints,
AF_Dimension dim ) AF_Dimension dim )
{ {
AF_AxisHints axis = &hints->axis[dim]; AF_AxisHints axis = &hints->axis[dim];
AF_Edge edges = axis->edges; AF_Edge edges = axis->edges;
@ -1796,7 +1817,8 @@
AF_LOG(( "==== hinting %s edges =====\n", dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); FT_TRACE5(( "==== hinting %s edges =====\n",
dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ));
/* we begin by aligning all stems relative to the blue zone */ /* we begin by aligning all stems relative to the blue zone */
/* if needed -- that's only for horizontal edges */ /* if needed -- that's only for horizontal edges */
@ -1830,10 +1852,10 @@
if ( !edge1 ) if ( !edge1 )
continue; continue;
AF_LOG(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), " FT_TRACE5(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), "
"was (%.2f)\n", "was (%.2f)\n",
edge1-edges, edge1->opos / 64.0, blue->fit / 64.0, edge1-edges, edge1->opos / 64.0, blue->fit / 64.0,
edge1->pos / 64.0 )); edge1->pos / 64.0 ));
edge1->pos = blue->fit; edge1->pos = blue->fit;
edge1->flags |= AF_EDGE_DONE; edge1->flags |= AF_EDGE_DONE;
@ -1878,7 +1900,7 @@
/* this should not happen, but it's better to be safe */ /* this should not happen, but it's better to be safe */
if ( edge2->blue_edge ) if ( edge2->blue_edge )
{ {
AF_LOG(( "ASSERTION FAILED for edge %d\n", edge2-edges )); FT_TRACE5(( "ASSERTION FAILED for edge %d\n", edge2-edges ));
af_latin2_align_linked_edge( hints, dim, edge2, edge ); af_latin2_align_linked_edge( hints, dim, edge2, edge );
edge->flags |= AF_EDGE_DONE; edge->flags |= AF_EDGE_DONE;
@ -1929,11 +1951,11 @@
else else
edge->pos = FT_PIX_ROUND( edge->opos ); edge->pos = FT_PIX_ROUND( edge->opos );
AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) " FT_TRACE5(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)"
"snapped to (%.2f) (%.2f)\n", " snapped to (%.2f) (%.2f)\n",
edge-edges, edge->opos / 64.0, edge-edges, edge->opos / 64.0,
edge2-edges, edge2->opos / 64.0, edge2-edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 )); edge->pos / 64.0, edge2->pos / 64.0 ));
anchor = edge; anchor = edge;
edge->flags |= AF_EDGE_DONE; edge->flags |= AF_EDGE_DONE;
@ -1945,7 +1967,7 @@
anchor_drift = ( (anchor->pos - anchor->opos) + anchor_drift = ( (anchor->pos - anchor->opos) +
(edge2->pos - edge2->opos)) >> 1; (edge2->pos - edge2->opos)) >> 1;
AF_LOG(( "DRIFT: %.2f\n", anchor_drift/64.0 )); FT_TRACE5(( "DRIFT: %.2f\n", anchor_drift/64.0 ));
} }
else else
{ {
@ -1965,12 +1987,13 @@
org_left = org_pos + ((org_len - cur_len) >> 1); org_left = org_pos + ((org_len - cur_len) >> 1);
org_right = org_pos + ((org_len + cur_len) >> 1); org_right = org_pos + ((org_len + cur_len) >> 1);
AF_LOG(( "ALIGN: left=%.2f right=%.2f ", org_left/64.0, org_right/64.0 )); FT_TRACE5(( "ALIGN: left=%.2f right=%.2f ",
org_left / 64.0, org_right / 64.0 ));
cur_center = org_center; cur_center = org_center;
if ( edge2->flags & AF_EDGE_DONE ) if ( edge2->flags & AF_EDGE_DONE )
{ {
AF_LOG(( "\n" )); FT_TRACE5(( "\n" ));
edge->pos = edge2->pos - cur_len; edge->pos = edge2->pos - cur_len;
} }
else else
@ -1985,14 +2008,14 @@
/* note: don't even try to fit tiny stems */ /* note: don't even try to fit tiny stems */
if ( cur_len < 32 ) if ( cur_len < 32 )
{ {
AF_LOG(( "tiny stem\n" )); FT_TRACE5(( "tiny stem\n" ));
goto AlignStem; goto AlignStem;
} }
/* if the span is within a single pixel, don't touch it */ /* if the span is within a single pixel, don't touch it */
if ( FT_PIX_FLOOR(org_left) == FT_PIX_CEIL(org_right) ) if ( FT_PIX_FLOOR(org_left) == FT_PIX_CEIL(org_right) )
{ {
AF_LOG(( "single pixel stem\n" )); FT_TRACE5(( "single pixel stem\n" ));
goto AlignStem; goto AlignStem;
} }
@ -2015,14 +2038,14 @@
delta = FT_ABS(fit - org); delta = FT_ABS(fit - org);
displacements[count] = fit - org; displacements[count] = fit - org;
scores[count++] = delta; scores[count++] = delta;
AF_LOG(( "dispA=%.2f (%d) ", (fit - org)/64.0, delta )); FT_TRACE5(( "dispA=%.2f (%d) ", (fit - org) / 64.0, delta ));
org = frac_right; org = frac_right;
fit = (org <= 32) ? 16 : 48; fit = (org <= 32) ? 16 : 48;
delta = FT_ABS(fit - org); delta = FT_ABS(fit - org);
displacements[count] = fit - org; displacements[count] = fit - org;
scores[count++] = delta; scores[count++] = delta;
AF_LOG(( "dispB=%.2f (%d) ", (fit - org)/64.0, delta )); FT_TRACE5(( "dispB=%.2f (%d) ", (fit - org) / 64.0, delta ));
} }
} }
@ -2032,7 +2055,7 @@
delta = FT_ABS(fit - org); delta = FT_ABS(fit - org);
displacements[count] = fit - org; displacements[count] = fit - org;
scores[count++] = delta; scores[count++] = delta;
AF_LOG(( "dispC=%.2f (%d) ", (fit - org)/64.0, delta )); FT_TRACE5(( "dispC=%.2f (%d) ", (fit - org) / 64.0, delta ));
/* snapping the right edge to the grid */ /* snapping the right edge to the grid */
org = org_right; org = org_right;
@ -2040,7 +2063,7 @@
delta = FT_ABS(fit - org); delta = FT_ABS(fit - org);
displacements[count] = fit - org; displacements[count] = fit - org;
scores[count++] = delta; scores[count++] = delta;
AF_LOG(( "dispD=%.2f (%d) ", (fit - org)/64.0, delta )); FT_TRACE5(( "dispD=%.2f (%d) ", (fit - org) / 64.0, delta ));
/* now find the best displacement */ /* now find the best displacement */
{ {
@ -2059,27 +2082,28 @@
cur_center = org_center + best_disp; cur_center = org_center + best_disp;
} }
AF_LOG(( "\n" )); FT_TRACE5(( "\n" ));
} }
AlignStem: AlignStem:
edge->pos = cur_center - (cur_len >> 1); edge->pos = cur_center - (cur_len >> 1);
edge2->pos = edge->pos + cur_len; edge2->pos = edge->pos + cur_len;
AF_LOG(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f) " FT_TRACE5(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f)"
"snapped to (%.2f) and (%.2f), org_len = %.2f cur_len=%.2f\n", " snapped to (%.2f) and (%.2f),"
edge-edges, edge->opos / 64.0, " org_len=%.2f cur_len=%.2f\n",
edge2-edges, edge2->opos / 64.0, edge-edges, edge->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0, edge2-edges, edge2->opos / 64.0,
org_len / 64.0, cur_len / 64.0 )); edge->pos / 64.0, edge2->pos / 64.0,
org_len / 64.0, cur_len / 64.0 ));
edge->flags |= AF_EDGE_DONE; edge->flags |= AF_EDGE_DONE;
edge2->flags |= AF_EDGE_DONE; edge2->flags |= AF_EDGE_DONE;
if ( edge > edges && edge->pos < edge[-1].pos ) if ( edge > edges && edge->pos < edge[-1].pos )
{ {
AF_LOG(( "BOUND: %d (pos=%.2f) to (%.2f)\n", FT_TRACE5(( "BOUND: %d (pos=%.2f) to (%.2f)\n",
edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
edge->pos = edge[-1].pos; edge->pos = edge[-1].pos;
} }
} }
@ -2179,16 +2203,17 @@
if ( delta < 64 + 16 ) if ( delta < 64 + 16 )
{ {
af_latin2_align_serif_edge( hints, edge->serif, edge ); af_latin2_align_serif_edge( hints, edge->serif, edge );
AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) " FT_TRACE5(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)"
"aligned to (%.2f)\n", " aligned to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge-edges, edge->opos / 64.0,
edge->serif - edges, edge->serif->opos / 64.0, edge->serif - edges, edge->serif->opos / 64.0,
edge->pos / 64.0 )); edge->pos / 64.0 ));
} }
else if ( !anchor ) else if ( !anchor )
{ {
AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n", FT_TRACE5(( "SERIF_ANCHOR: edge %d (opos=%.2f)"
edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); " snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
edge->pos = FT_PIX_ROUND( edge->opos ); edge->pos = FT_PIX_ROUND( edge->opos );
anchor = edge; anchor = edge;
} }
@ -2215,15 +2240,19 @@
FT_MulDiv( edge->opos - before->opos, FT_MulDiv( edge->opos - before->opos,
after->pos - before->pos, after->pos - before->pos,
after->opos - before->opos ); after->opos - before->opos );
AF_LOG(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f) from %d (opos=%.2f)\n", FT_TRACE5(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)"
edge-edges, edge->opos / 64.0, edge->pos / 64.0, before - edges, before->opos / 64.0 )); " from %d (opos=%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0,
before - edges, before->opos / 64.0 ));
} }
else else
{ {
edge->pos = anchor->pos + (( edge->opos - anchor->opos + 16) & ~31); edge->pos = anchor->pos +
( ( edge->opos - anchor->opos + 16 ) & ~31 );
AF_LOG(( "SERIF_LINK2: edge %d (opos=%.2f) snapped to (%.2f)\n", FT_TRACE5(( "SERIF_LINK2: edge %d (opos=%.2f)"
edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); " snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
} }
} }
@ -2243,8 +2272,8 @@
static FT_Error static FT_Error
af_latin2_hints_apply( AF_GlyphHints hints, af_latin2_hints_apply( AF_GlyphHints hints,
FT_Outline* outline, FT_Outline* outline,
AF_LatinMetrics metrics ) AF_LatinMetrics metrics )
{ {
FT_Error error; FT_Error error;
int dim; int dim;
@ -2255,7 +2284,7 @@
goto Exit; goto Exit;
/* analyze glyph outline */ /* analyze glyph outline */
#ifdef AF_USE_WARPER #ifdef AF_CONFIG_OPTION_USE_WARPER
if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT || if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ||
AF_HINTS_DO_HORIZONTAL( hints ) ) AF_HINTS_DO_HORIZONTAL( hints ) )
#else #else
@ -2279,7 +2308,7 @@
/* grid-fit the outline */ /* grid-fit the outline */
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
{ {
#ifdef AF_USE_WARPER #ifdef AF_CONFIG_OPTION_USE_WARPER
if ( ( dim == AF_DIMENSION_HORZ && if ( ( dim == AF_DIMENSION_HORZ &&
metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) ) metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) )
{ {
@ -2321,7 +2350,7 @@
static const AF_Script_UniRangeRec af_latin2_uniranges[] = static const AF_Script_UniRangeRec af_latin2_uniranges[] =
{ {
AF_UNIRANGE_REC( 32UL, 127UL ), /* XXX: TODO: Add new Unicode ranges here! */ AF_UNIRANGE_REC( 32UL, 127UL ), /* TODO: Add new Unicode ranges here! */
AF_UNIRANGE_REC( 160UL, 255UL ), AF_UNIRANGE_REC( 160UL, 255UL ),
AF_UNIRANGE_REC( 0UL, 0UL ) AF_UNIRANGE_REC( 0UL, 0UL )
}; };

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter glyph loading routines (body). */ /* Auto-fitter glyph loading routines (body). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* Copyright 2003-2009, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -22,6 +22,8 @@
#include "aferrors.h" #include "aferrors.h"
/* Initialize glyph loader. */
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_loader_init( AF_Loader loader, af_loader_init( AF_Loader loader,
FT_Memory memory ) FT_Memory memory )
@ -29,13 +31,15 @@
FT_ZERO( loader ); FT_ZERO( loader );
af_glyph_hints_init( &loader->hints, memory ); af_glyph_hints_init( &loader->hints, memory );
#ifdef AF_DEBUG #ifdef FT_DEBUG_AUTOFIT
_af_debug_hints = &loader->hints; _af_debug_hints = &loader->hints;
#endif #endif
return FT_GlyphLoader_New( memory, &loader->gloader ); return FT_GlyphLoader_New( memory, &loader->gloader );
} }
/* Reset glyph loader and compute globals if necessary. */
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_loader_reset( AF_Loader loader, af_loader_reset( AF_Loader loader,
FT_Face face ) FT_Face face )
@ -64,6 +68,8 @@
} }
/* Finalize glyph loader. */
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_loader_done( AF_Loader loader ) af_loader_done( AF_Loader loader )
{ {
@ -72,7 +78,7 @@
loader->face = NULL; loader->face = NULL;
loader->globals = NULL; loader->globals = NULL;
#ifdef AF_DEBUG #ifdef FT_DEBUG_AUTOFIT
_af_debug_hints = NULL; _af_debug_hints = NULL;
#endif #endif
FT_GlyphLoader_Done( loader->gloader ); FT_GlyphLoader_Done( loader->gloader );
@ -80,6 +86,10 @@
} }
/* Load a single glyph component. This routine calls itself */
/* recursively, if necessary, and does the main work of */
/* `af_loader_load_glyph.' */
static FT_Error static FT_Error
af_loader_load_g( AF_Loader loader, af_loader_load_g( AF_Loader loader,
AF_Scaler scaler, AF_Scaler scaler,
@ -169,8 +179,8 @@
&gloader->current.outline, &gloader->current.outline,
metrics ); metrics );
/* we now need to hint the metrics according to the change in */ /* we now need to adjust the metrics according to the change in */
/* width/positioning that occurred during the hinting process */ /* width/positioning that occurred during the hinting process */
if ( scaler->render_mode != FT_RENDER_MODE_LIGHT ) if ( scaler->render_mode != FT_RENDER_MODE_LIGHT )
{ {
FT_Pos old_rsb, old_lsb, new_lsb; FT_Pos old_rsb, old_lsb, new_lsb;
@ -265,7 +275,7 @@
gloader->current.num_subglyphs = num_subglyphs; gloader->current.num_subglyphs = num_subglyphs;
num_base_subgs = gloader->base.num_subglyphs; num_base_subgs = gloader->base.num_subglyphs;
/* now, read each subglyph independently */ /* now read each subglyph independently */
for ( nn = 0; nn < num_subglyphs; nn++ ) for ( nn = 0; nn < num_subglyphs; nn++ )
{ {
FT_Vector pp1, pp2; FT_Vector pp1, pp2;
@ -305,7 +315,7 @@
num_points = gloader->base.outline.n_points; num_points = gloader->base.outline.n_points;
num_new_points = num_points - num_base_points; num_new_points = num_points - num_base_points;
/* now perform the transform required for this subglyph */ /* now perform the transformation required for this subglyph */
if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE | if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE |
FT_SUBGLYPH_FLAG_XY_SCALE | FT_SUBGLYPH_FLAG_XY_SCALE |
@ -444,7 +454,7 @@
#endif #endif
slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,
metrics->scaler.y_scale ); metrics->scaler.y_scale );
slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );
@ -459,15 +469,13 @@
slot->format = FT_GLYPH_FORMAT_OUTLINE; slot->format = FT_GLYPH_FORMAT_OUTLINE;
} }
#ifdef DEBUG_HINTER
af_debug_hinter = hinter;
#endif
Exit: Exit:
return error; return error;
} }
/* Load a glyph. */
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_loader_load_glyph( AF_Loader loader, af_loader_load_glyph( AF_Loader loader,
FT_Face face, FT_Face face,

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter glyph loading routines (specification). */ /* Auto-fitter glyph loading routines (specification). */
/* */ /* */
/* Copyright 2003, 2004, 2005 by */ /* Copyright 2003-2005, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -16,8 +16,8 @@
/***************************************************************************/ /***************************************************************************/
#ifndef __AF_LOADER_H__ #ifndef __AFLOADER_H__
#define __AF_LOADER_H__ #define __AFLOADER_H__
#include "afhints.h" #include "afhints.h"
#include "afglobal.h" #include "afglobal.h"
@ -67,7 +67,7 @@ FT_BEGIN_HEADER
FT_END_HEADER FT_END_HEADER
#endif /* __AF_LOADER_H__ */ #endif /* __AFLOADER_H__ */
/* END */ /* END */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter module implementation (body). */ /* Auto-fitter module implementation (body). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006 by */ /* Copyright 2003-2006, 2009, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -20,8 +20,7 @@
#include "afloader.h" #include "afloader.h"
#include "afpic.h" #include "afpic.h"
#ifdef AF_DEBUG #ifdef FT_DEBUG_AUTOFIT
int _af_debug;
int _af_debug_disable_horz_hints; int _af_debug_disable_horz_hints;
int _af_debug_disable_vert_hints; int _af_debug_disable_vert_hints;
int _af_debug_disable_blue_hints; int _af_debug_disable_blue_hints;
@ -67,14 +66,15 @@
} }
FT_DEFINE_AUTOHINTER_SERVICE(af_autofitter_service, FT_DEFINE_AUTOHINTER_SERVICE(
af_autofitter_service,
NULL, NULL,
NULL, NULL,
NULL, NULL,
(FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph )
)
FT_DEFINE_MODULE(autofit_module_class, FT_DEFINE_MODULE(
autofit_module_class,
FT_MODULE_HINTER, FT_MODULE_HINTER,
sizeof ( FT_AutofitterRec ), sizeof ( FT_AutofitterRec ),
@ -87,8 +87,7 @@
(FT_Module_Constructor)af_autofitter_init, (FT_Module_Constructor)af_autofitter_init,
(FT_Module_Destructor) af_autofitter_done, (FT_Module_Destructor) af_autofitter_done,
(FT_Module_Requester) NULL (FT_Module_Requester) NULL )
)
/* END */ /* END */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* The FreeType position independent code services for autofit module. */ /* The FreeType position independent code services for autofit module. */
/* */ /* */
/* Copyright 2009, 2010 by */ /* Copyright 2009, 2010, 2011 by */
/* Oran Agra and Mickey Gabel. */ /* Oran Agra and Mickey Gabel. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -24,7 +24,8 @@
#ifdef FT_CONFIG_OPTION_PIC #ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from afmodule.c */ /* forward declaration of PIC init functions from afmodule.c */
void FT_Init_Class_af_autofitter_service( FT_Library, FT_AutoHinter_ServiceRec*); void FT_Init_Class_af_autofitter_service( FT_Library,
FT_AutoHinter_ServiceRec* );
/* forward declaration of PIC init functions from script classes */ /* forward declaration of PIC init functions from script classes */
#include "aflatin.h" #include "aflatin.h"
@ -34,10 +35,12 @@
#include "afindic.h" #include "afindic.h"
void void
autofit_module_class_pic_free( FT_Library library ) autofit_module_class_pic_free( FT_Library library )
{ {
FT_PIC_Container* pic_container = &library->pic_container; FT_PIC_Container* pic_container = &library->pic_container;
FT_Memory memory = library->memory; FT_Memory memory = library->memory;
if ( pic_container->autofit ) if ( pic_container->autofit )
{ {
FT_FREE( pic_container->autofit ); FT_FREE( pic_container->autofit );
@ -62,28 +65,37 @@
FT_MEM_SET( container, 0, sizeof ( *container ) ); FT_MEM_SET( container, 0, sizeof ( *container ) );
pic_container->autofit = container; pic_container->autofit = container;
/* initialize pointer table - this is how the module usually expects this data */ /* initialize pointer table - */
/* this is how the module usually expects this data */
for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ ) for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ )
{ {
container->af_script_classes[ss] = &container->af_script_classes_rec[ss]; container->af_script_classes[ss] =
&container->af_script_classes_rec[ss];
} }
container->af_script_classes[AF_SCRIPT_CLASSES_COUNT-1] = NULL; container->af_script_classes[AF_SCRIPT_CLASSES_COUNT - 1] = NULL;
/* add call to initialization function when you add new scripts */ /* add call to initialization function when you add new scripts */
ss = 0; ss = 0;
FT_Init_Class_af_dummy_script_class(&container->af_script_classes_rec[ss++]); FT_Init_Class_af_dummy_script_class(
&container->af_script_classes_rec[ss++] );
#ifdef FT_OPTION_AUTOFIT2 #ifdef FT_OPTION_AUTOFIT2
FT_Init_Class_af_latin2_script_class(&container->af_script_classes_rec[ss++]); FT_Init_Class_af_latin2_script_class(
&container->af_script_classes_rec[ss++] );
#endif #endif
FT_Init_Class_af_latin_script_class(&container->af_script_classes_rec[ss++]); FT_Init_Class_af_latin_script_class(
FT_Init_Class_af_cjk_script_class(&container->af_script_classes_rec[ss++]); &container->af_script_classes_rec[ss++] );
FT_Init_Class_af_indic_script_class(&container->af_script_classes_rec[ss++]); FT_Init_Class_af_cjk_script_class(
&container->af_script_classes_rec[ss++] );
FT_Init_Class_af_indic_script_class(
&container->af_script_classes_rec[ss++] );
FT_Init_Class_af_autofitter_service(library, &container->af_autofitter_service); FT_Init_Class_af_autofitter_service(
library, &container->af_autofitter_service );
/*Exit:*/ /* Exit: */
if(error)
autofit_module_class_pic_free(library); if ( error )
autofit_module_class_pic_free( library );
return error; return error;
} }

View file

@ -4,7 +4,7 @@
/* */ /* */
/* The FreeType position independent code services for autofit module. */ /* The FreeType position independent code services for autofit module. */
/* */ /* */
/* Copyright 2009 by */ /* Copyright 2009, 2011 by */
/* Oran Agra and Mickey Gabel. */ /* Oran Agra and Mickey Gabel. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -33,24 +33,29 @@ FT_BEGIN_HEADER
#include "aftypes.h" #include "aftypes.h"
/* increase these when you add new scripts, and update autofit_module_class_pic_init */ /* increase these when you add new scripts, */
/* and update autofit_module_class_pic_init */
#ifdef FT_OPTION_AUTOFIT2 #ifdef FT_OPTION_AUTOFIT2
#define AF_SCRIPT_CLASSES_COUNT 6 #define AF_SCRIPT_CLASSES_COUNT 6
#else #else
#define AF_SCRIPT_CLASSES_COUNT 5 #define AF_SCRIPT_CLASSES_COUNT 5
#endif #endif
#define AF_SCRIPT_CLASSES_REC_COUNT (AF_SCRIPT_CLASSES_COUNT-1) #define AF_SCRIPT_CLASSES_REC_COUNT ( AF_SCRIPT_CLASSES_COUNT - 1 )
typedef struct AFModulePIC_ typedef struct AFModulePIC_
{ {
AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT]; AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT];
AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT]; AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT];
FT_AutoHinter_ServiceRec af_autofitter_service; FT_AutoHinter_ServiceRec af_autofitter_service;
} AFModulePIC; } AFModulePIC;
#define GET_PIC(lib) ((AFModulePIC*)((lib)->pic_container.autofit)) #define GET_PIC( lib ) \
#define AF_SCRIPT_CLASSES_GET (GET_PIC(FT_FACE_LIBRARY(globals->face))->af_script_classes) ( (AFModulePIC*)((lib)->pic_container.autofit) )
#define AF_AF_AUTOFITTER_SERVICE_GET (GET_PIC(library)->af_autofitter_service) #define AF_SCRIPT_CLASSES_GET \
( GET_PIC( FT_FACE_LIBRARY(globals->face) )->af_script_classes )
#define AF_AF_AUTOFITTER_SERVICE_GET \
( GET_PIC( library )->af_autofitter_service )
#endif /* FT_CONFIG_OPTION_PIC */ #endif /* FT_CONFIG_OPTION_PIC */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter types (specification only). */ /* Auto-fitter types (specification only). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* Copyright 2003-2009, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -53,26 +53,16 @@ FT_BEGIN_HEADER
/*************************************************************************/ /*************************************************************************/
/*************************************************************************/ /*************************************************************************/
#define xxAF_USE_WARPER /* only define to use warp hinting */ #ifdef FT_DEBUG_AUTOFIT
#define xxAF_DEBUG
#ifdef AF_DEBUG
#include FT_CONFIG_STANDARD_LIBRARY_H #include FT_CONFIG_STANDARD_LIBRARY_H
#define AF_LOG( x ) do { if ( _af_debug ) printf x; } while ( 0 )
extern int _af_debug;
extern int _af_debug_disable_horz_hints; extern int _af_debug_disable_horz_hints;
extern int _af_debug_disable_vert_hints; extern int _af_debug_disable_vert_hints;
extern int _af_debug_disable_blue_hints; extern int _af_debug_disable_blue_hints;
extern void* _af_debug_hints; extern void* _af_debug_hints;
#else /* !AF_DEBUG */ #endif /* FT_DEBUG_AUTOFIT */
#define AF_LOG( x ) do { } while ( 0 ) /* nothing */
#endif /* !AF_DEBUG */
/*************************************************************************/ /*************************************************************************/
@ -159,36 +149,11 @@ extern void* _af_debug_hints;
FT_END_STMNT FT_END_STMNT
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** O U T L I N E S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* opaque handle to glyph-specific hints -- see `afhints.h' for more /* opaque handle to glyph-specific hints -- see `afhints.h' for more
* details * details
*/ */
typedef struct AF_GlyphHintsRec_* AF_GlyphHints; typedef struct AF_GlyphHintsRec_* AF_GlyphHints;
/* This structure is used to model an input glyph outline to
* the auto-hinter. The latter will set the `hints' field
* depending on the glyph's script.
*/
typedef struct AF_OutlineRec_
{
FT_Face face;
FT_Outline outline;
FT_UInt outline_resolution;
FT_Int advance;
FT_UInt metrics_resolution;
AF_GlyphHints hints;
} AF_OutlineRec;
/*************************************************************************/ /*************************************************************************/
/*************************************************************************/ /*************************************************************************/
@ -241,7 +206,7 @@ extern void* _af_debug_hints;
/*************************************************************************/ /*************************************************************************/
/* /*
* The list of know scripts. Each different script corresponds to the * The list of known scripts. Each different script corresponds to the
* following information: * following information:
* *
* - A set of Unicode ranges to test whether the face supports the * - A set of Unicode ranges to test whether the face supports the
@ -342,55 +307,57 @@ extern void* _af_debug_hints;
} AF_ScriptClassRec; } AF_ScriptClassRec;
/* Declare and define vtables for classes */
/* Declare and define vtables for classes */
#ifndef FT_CONFIG_OPTION_PIC #ifndef FT_CONFIG_OPTION_PIC
#define AF_DECLARE_SCRIPT_CLASS(script_class) \ #define AF_DECLARE_SCRIPT_CLASS( script_class ) \
FT_CALLBACK_TABLE const AF_ScriptClassRec \ FT_CALLBACK_TABLE const AF_ScriptClassRec \
script_class; script_class;
#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size, \ #define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, m_size, \
m_init, m_scale, m_done, h_init, h_apply) \ m_init, m_scale, m_done, h_init, h_apply ) \
FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec \ FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec \
script_class = \ script_class = \
{ \ { \
script_, \ script_, \
ranges, \ ranges, \
\ \
m_size, \ m_size, \
\ \
m_init, \ m_init, \
m_scale, \ m_scale, \
m_done, \ m_done, \
\ \
h_init, \ h_init, \
h_apply \ h_apply \
}; };
#else #else /* FT_CONFIG_OPTION_PIC */
#define AF_DECLARE_SCRIPT_CLASS(script_class) \ #define AF_DECLARE_SCRIPT_CLASS( script_class ) \
FT_LOCAL(void) \ FT_LOCAL( void ) \
FT_Init_Class_##script_class(AF_ScriptClassRec* ac); FT_Init_Class_##script_class( AF_ScriptClassRec* ac );
#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size, \ #define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, m_size, \
m_init, m_scale, m_done, h_init, h_apply) \ m_init, m_scale, m_done, h_init, h_apply ) \
FT_LOCAL_DEF(void) \ FT_LOCAL_DEF( void ) \
FT_Init_Class_##script_class(AF_ScriptClassRec* ac) \ FT_Init_Class_##script_class( AF_ScriptClassRec* ac ) \
{ \ { \
ac->script = script_; \ ac->script = script_; \
ac->script_uni_ranges = ranges; \ ac->script_uni_ranges = ranges; \
\ \
ac->script_metrics_size = m_size; \ ac->script_metrics_size = m_size; \
\ \
ac->script_metrics_init = m_init; \ ac->script_metrics_init = m_init; \
ac->script_metrics_scale = m_scale; \ ac->script_metrics_scale = m_scale; \
ac->script_metrics_done = m_done; \ ac->script_metrics_done = m_done; \
\ \
ac->script_hints_init = h_init; \ ac->script_hints_init = h_init; \
ac->script_hints_apply = h_apply; \ ac->script_hints_apply = h_apply; \
} }
#endif
#endif /* FT_CONFIG_OPTION_PIC */
/* */ /* */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter warping algorithm (body). */ /* Auto-fitter warping algorithm (body). */
/* */ /* */
/* Copyright 2006, 2007 by */ /* Copyright 2006, 2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -16,10 +16,30 @@
/***************************************************************************/ /***************************************************************************/
/*
* The idea of the warping code is to slightly scale and shift a glyph
* within a single dimension so that as much of its segments are aligned
* (more or less) on the grid. To find out the optimal scaling and
* shifting value, various parameter combinations are tried and scored.
*/
#include "afwarp.h" #include "afwarp.h"
#ifdef AF_USE_WARPER #ifdef AF_CONFIG_OPTION_USE_WARPER
/*************************************************************************/
/* */
/* 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_afwarp
/* The weights cover the range 0/64 - 63/64 of a pixel. Obviously, */
/* values around a half pixel (which means exactly between two grid */
/* lines) gets the worst weight. */
#if 1 #if 1
static const AF_WarpScore static const AF_WarpScore
af_warper_weights[64] = af_warper_weights[64] =
@ -43,6 +63,11 @@
#endif #endif
/* Score segments for a given `scale' and `delta' in the range */
/* `xx1' to `xx2', and store the best result in `warper'. If */
/* the new best score is equal to the old one, prefer the */
/* value with a smaller distortion (around `base_distort'). */
static void static void
af_warper_compute_line_best( AF_Warper warper, af_warper_compute_line_best( AF_Warper warper,
FT_Fixed scale, FT_Fixed scale,
@ -82,12 +107,12 @@
if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 ) if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 )
{ {
AF_LOG(( "invalid indices:\n" FT_TRACE5(( "invalid indices:\n"
" min=%d max=%d, xx1=%ld xx2=%ld,\n" " min=%d max=%d, xx1=%ld xx2=%ld,\n"
" x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n", " x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n",
idx_min, idx_max, xx1, xx2, idx_min, idx_max, xx1, xx2,
warper->x1min, warper->x1max, warper->x1min, warper->x1max,
warper->x2min, warper->x2max )); warper->x2min, warper->x2max ));
return; return;
} }
} }
@ -100,6 +125,7 @@
FT_Int idx; FT_Int idx;
/* score the length of the segments for the given range */
for ( idx = idx_min; idx <= idx_max; idx++, y++ ) for ( idx = idx_min; idx <= idx_max; idx++, y++ )
scores[idx] += af_warper_weights[y & 63] * len; scores[idx] += af_warper_weights[y & 63] * len;
} }
@ -115,9 +141,9 @@
AF_WarpScore distort = base_distort + ( idx - idx0 ); AF_WarpScore distort = base_distort + ( idx - idx0 );
if ( score > warper->best_score || if ( score > warper->best_score ||
( score == warper->best_score && ( score == warper->best_score &&
distort < warper->best_distort ) ) distort < warper->best_distort ) )
{ {
warper->best_score = score; warper->best_score = score;
warper->best_distort = distort; warper->best_distort = distort;
@ -129,6 +155,9 @@
} }
/* Compute optimal scaling and delta values for a given glyph and */
/* dimension. */
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_warper_compute( AF_Warper warper, af_warper_compute( AF_Warper warper,
AF_GlyphHints hints, AF_GlyphHints hints,
@ -215,6 +244,7 @@
warper->t1 = AF_WARPER_FLOOR( warper->x1 ); warper->t1 = AF_WARPER_FLOOR( warper->x1 );
warper->t2 = AF_WARPER_CEIL( warper->x2 ); warper->t2 = AF_WARPER_CEIL( warper->x2 );
/* examine a half pixel wide range around the maximum coordinates */
warper->x1min = warper->x1 & ~31; warper->x1min = warper->x1 & ~31;
warper->x1max = warper->x1min + 32; warper->x1max = warper->x1min + 32;
warper->x2min = warper->x2 & ~31; warper->x2min = warper->x2 & ~31;
@ -234,10 +264,12 @@
warper->x2min = warper->x2; warper->x2min = warper->x2;
} }
/* examine (at most) a pixel wide range around the natural width */
warper->wmin = warper->x2min - warper->x1max; warper->wmin = warper->x2min - warper->x1max;
warper->wmax = warper->x2max - warper->x1min; warper->wmax = warper->x2max - warper->x1min;
#if 1 #if 1
/* some heuristics to reduce the number of widths to be examined */
{ {
int margin = 16; int margin = 16;
@ -273,6 +305,8 @@
FT_Pos xx1, xx2; FT_Pos xx1, xx2;
/* compute min and max positions for given width, */
/* assuring that they stay within the coordinate ranges */
xx1 = warper->x1; xx1 = warper->x1;
xx2 = warper->x2; xx2 = warper->x2;
if ( w >= warper->w0 ) if ( w >= warper->w0 )
@ -304,6 +338,7 @@
else else
base_distort += xx2 - warper->x2; base_distort += xx2 - warper->x2;
/* give base distortion a greater weight while scoring */
base_distort *= 10; base_distort *= 10;
new_scale = org_scale + FT_DivFix( w - warper->w0, X2 - X1 ); new_scale = org_scale + FT_DivFix( w - warper->w0, X2 - X1 );
@ -329,10 +364,11 @@
} }
} }
#else /* !AF_USE_WARPER */ #else /* !AF_CONFIG_OPTION_USE_WARPER */
char af_warper_dummy = 0; /* make compiler happy */ /* ANSI C doesn't like empty source files */
typedef int _af_warp_dummy;
#endif /* !AF_USE_WARPER */ #endif /* !AF_CONFIG_OPTION_USE_WARPER */
/* END */ /* END */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter module (body). */ /* Auto-fitter module (body). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006, 2007 by */ /* Copyright 2003-2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -34,7 +34,7 @@
#include "afloader.c" #include "afloader.c"
#include "afmodule.c" #include "afmodule.c"
#ifdef AF_USE_WARPER #ifdef AF_CONFIG_OPTION_USE_WARPER
#include "afwarp.c" #include "afwarp.c"
#endif #endif

View file

@ -3,7 +3,7 @@
# #
# Copyright 2003, 2004, 2005, 2006, 2007 by # Copyright 2003, 2004, 2005, 2006, 2007, 2011 by
# David Turner, Robert Wilhelm, and Werner Lemberg. # David Turner, Robert Wilhelm, and Werner Lemberg.
# #
# This file is part of the FreeType project, and may only be used, modified, # This file is part of the FreeType project, and may only be used, modified,
@ -34,13 +34,14 @@ AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \
$(AUTOF_DIR)/aflatin.c \ $(AUTOF_DIR)/aflatin.c \
$(AUTOF_DIR)/afloader.c \ $(AUTOF_DIR)/afloader.c \
$(AUTOF_DIR)/afmodule.c \ $(AUTOF_DIR)/afmodule.c \
$(AUTOF_DIR)/afpic.c \
$(AUTOF_DIR)/afwarp.c $(AUTOF_DIR)/afwarp.c
# AUTOF driver headers # AUTOF driver headers
# #
AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \ AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \
$(AUTOF_DIR)/aftypes.h \ $(AUTOF_DIR)/aferrors.h \
$(AUTOF_DIR)/aferrors.h $(AUTOF_DIR)/aftypes.h
# AUTOF driver object(s) # AUTOF driver object(s)

View file

@ -105,7 +105,7 @@
int new_pitch; int new_pitch;
FT_UInt bpp; FT_UInt bpp;
FT_Int i, width, height; FT_Int i, width, height;
unsigned char* buffer; unsigned char* buffer = NULL;
width = bitmap->width; width = bitmap->width;

View file

@ -4,8 +4,7 @@
/* */ /* */
/* The FreeType private base classes (body). */ /* The FreeType private base classes (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ /* Copyright 1996-2011 by */
/* 2010 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -131,7 +130,7 @@
{ {
FT_Error error; FT_Error error;
FT_Memory memory; FT_Memory memory;
FT_Stream stream; FT_Stream stream = NULL;
*astream = 0; *astream = 0;
@ -375,7 +374,7 @@
FT_Driver driver; FT_Driver driver;
FT_Driver_Class clazz; FT_Driver_Class clazz;
FT_Memory memory; FT_Memory memory;
FT_GlyphSlot slot; FT_GlyphSlot slot = NULL;
if ( !face || !face->driver ) if ( !face || !face->driver )
@ -561,6 +560,7 @@
FT_Library library; FT_Library library;
FT_Bool autohint = FALSE; FT_Bool autohint = FALSE;
FT_Module hinter; FT_Module hinter;
TT_Face ttface = (TT_Face)face;
if ( !face || !face->size || !face->glyph ) if ( !face || !face->size || !face->glyph )
@ -601,7 +601,8 @@
* - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
* have a native font hinter. * have a native font hinter.
* *
* - Otherwise, auto-hint for LIGHT hinting mode. * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't
* any hinting bytecode in the TrueType/OpenType font.
* *
* - Exception: The font is `tricky' and requires the native hinter to * - Exception: The font is `tricky' and requires the native hinter to
* load properly. * load properly.
@ -626,8 +627,13 @@
FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
if ( mode == FT_RENDER_MODE_LIGHT || /* the check for `num_locations' assures that we actually */
face->internal->ignore_unpatented_hinter ) /* test for instructions in a TTF and not in a CFF-based OTF */
if ( mode == FT_RENDER_MODE_LIGHT ||
face->internal->ignore_unpatented_hinter ||
( FT_IS_SFNT( face ) &&
ttface->num_locations &&
ttface->max_profile.maxSizeOfInstructions == 0 ) )
autohint = TRUE; autohint = TRUE;
} }
} }
@ -1283,7 +1289,7 @@
{ {
FT_Error error; FT_Error error;
FT_Memory memory; FT_Memory memory;
FT_Stream stream; FT_Stream stream = NULL;
if ( !library ) if ( !library )
@ -1458,7 +1464,7 @@
FT_ULong offset, length; FT_ULong offset, length;
FT_Long pos; FT_Long pos;
FT_Bool is_sfnt_cid; FT_Bool is_sfnt_cid;
FT_Byte* sfnt_ps; FT_Byte* sfnt_ps = NULL;
FT_UNUSED( num_params ); FT_UNUSED( num_params );
FT_UNUSED( params ); FT_UNUSED( params );
@ -1525,7 +1531,7 @@
{ {
FT_Error error = FT_Err_Cannot_Open_Resource; FT_Error error = FT_Err_Cannot_Open_Resource;
FT_Memory memory = library->memory; FT_Memory memory = library->memory;
FT_Byte* pfb_data; FT_Byte* pfb_data = NULL;
int i, type, flags; int i, type, flags;
FT_Long len; FT_Long len;
FT_Long pfb_len, pfb_pos, pfb_lenpos; FT_Long pfb_len, pfb_pos, pfb_lenpos;
@ -1667,7 +1673,7 @@
FT_Face *aface ) FT_Face *aface )
{ {
FT_Memory memory = library->memory; FT_Memory memory = library->memory;
FT_Byte* sfnt_data; FT_Byte* sfnt_data = NULL;
FT_Error error; FT_Error error;
FT_Long flag_offset; FT_Long flag_offset;
FT_Long rlen; FT_Long rlen;
@ -3148,7 +3154,7 @@
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FT_Face face; FT_Face face;
FT_Memory memory; FT_Memory memory;
FT_CMap cmap; FT_CMap cmap = NULL;
if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) if ( clazz == NULL || charmap == NULL || charmap->face == NULL )
@ -3887,6 +3893,7 @@
error = set_mode( renderer, parameters->tag, parameters->data ); error = set_mode( renderer, parameters->tag, parameters->data );
if ( error ) if ( error )
break; break;
parameters++;
} }
} }

View file

@ -159,8 +159,8 @@
FT_Long tag_internal, rpos; FT_Long tag_internal, rpos;
FT_Memory memory = library->memory; FT_Memory memory = library->memory;
FT_Long temp; FT_Long temp;
FT_Long *offsets_internal; FT_Long *offsets_internal = NULL;
FT_RFork_Ref *ref; FT_RFork_Ref *ref = NULL;
error = FT_Stream_Seek( stream, map_offset ); error = FT_Stream_Seek( stream, map_offset );
@ -527,7 +527,7 @@
Only meaningful on systems with hfs+ drivers (or Macs). Only meaningful on systems with hfs+ drivers (or Macs).
*/ */
FT_Error error; FT_Error error;
char* newpath; char* newpath = NULL;
FT_Memory memory; FT_Memory memory;
FT_Long base_file_len = ft_strlen( base_file_name ); FT_Long base_file_len = ft_strlen( base_file_name );
@ -563,7 +563,7 @@
Only meaningful on systems with Mac OS X (> 10.1). Only meaningful on systems with Mac OS X (> 10.1).
*/ */
FT_Error error; FT_Error error;
char* newpath; char* newpath = NULL;
FT_Memory memory; FT_Memory memory;
FT_Long base_file_len = ft_strlen( base_file_name ); FT_Long base_file_len = ft_strlen( base_file_name );

View file

@ -4,7 +4,7 @@
/* */ /* */
/* I/O stream support (body). */ /* I/O stream support (body). */
/* */ /* */
/* Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008, 2009, 2010 by */ /* Copyright 2000-2002, 2004-2006, 2008-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -354,8 +354,8 @@
} }
FT_BASE_DEF( FT_Short ) FT_BASE_DEF( FT_UShort )
FT_Stream_GetShort( FT_Stream stream ) FT_Stream_GetUShort( FT_Stream stream )
{ {
FT_Byte* p; FT_Byte* p;
FT_Short result; FT_Short result;
@ -366,15 +366,15 @@
result = 0; result = 0;
p = stream->cursor; p = stream->cursor;
if ( p + 1 < stream->limit ) if ( p + 1 < stream->limit )
result = FT_NEXT_SHORT( p ); result = FT_NEXT_USHORT( p );
stream->cursor = p; stream->cursor = p;
return result; return result;
} }
FT_BASE_DEF( FT_Short ) FT_BASE_DEF( FT_UShort )
FT_Stream_GetShortLE( FT_Stream stream ) FT_Stream_GetUShortLE( FT_Stream stream )
{ {
FT_Byte* p; FT_Byte* p;
FT_Short result; FT_Short result;
@ -385,15 +385,15 @@
result = 0; result = 0;
p = stream->cursor; p = stream->cursor;
if ( p + 1 < stream->limit ) if ( p + 1 < stream->limit )
result = FT_NEXT_SHORT_LE( p ); result = FT_NEXT_USHORT_LE( p );
stream->cursor = p; stream->cursor = p;
return result; return result;
} }
FT_BASE_DEF( FT_Long ) FT_BASE_DEF( FT_ULong )
FT_Stream_GetOffset( FT_Stream stream ) FT_Stream_GetUOffset( FT_Stream stream )
{ {
FT_Byte* p; FT_Byte* p;
FT_Long result; FT_Long result;
@ -404,14 +404,14 @@
result = 0; result = 0;
p = stream->cursor; p = stream->cursor;
if ( p + 2 < stream->limit ) if ( p + 2 < stream->limit )
result = FT_NEXT_OFF3( p ); result = FT_NEXT_UOFF3( p );
stream->cursor = p; stream->cursor = p;
return result; return result;
} }
FT_BASE_DEF( FT_Long ) FT_BASE_DEF( FT_ULong )
FT_Stream_GetLong( FT_Stream stream ) FT_Stream_GetULong( FT_Stream stream )
{ {
FT_Byte* p; FT_Byte* p;
FT_Long result; FT_Long result;
@ -422,14 +422,14 @@
result = 0; result = 0;
p = stream->cursor; p = stream->cursor;
if ( p + 3 < stream->limit ) if ( p + 3 < stream->limit )
result = FT_NEXT_LONG( p ); result = FT_NEXT_ULONG( p );
stream->cursor = p; stream->cursor = p;
return result; return result;
} }
FT_BASE_DEF( FT_Long ) FT_BASE_DEF( FT_ULong )
FT_Stream_GetLongLE( FT_Stream stream ) FT_Stream_GetULongLE( FT_Stream stream )
{ {
FT_Byte* p; FT_Byte* p;
FT_Long result; FT_Long result;
@ -440,7 +440,7 @@
result = 0; result = 0;
p = stream->cursor; p = stream->cursor;
if ( p + 3 < stream->limit ) if ( p + 3 < stream->limit )
result = FT_NEXT_LONG_LE( p ); result = FT_NEXT_ULONG_LE( p );
stream->cursor = p; stream->cursor = p;
return result; return result;
} }
@ -483,8 +483,8 @@
} }
FT_BASE_DEF( FT_Short ) FT_BASE_DEF( FT_UShort )
FT_Stream_ReadShort( FT_Stream stream, FT_Stream_ReadUShort( FT_Stream stream,
FT_Error* error ) FT_Error* error )
{ {
FT_Byte reads[2]; FT_Byte reads[2];
@ -511,7 +511,7 @@
} }
if ( p ) if ( p )
result = FT_NEXT_SHORT( p ); result = FT_NEXT_USHORT( p );
} }
else else
goto Fail; goto Fail;
@ -522,7 +522,7 @@
Fail: Fail:
*error = FT_Err_Invalid_Stream_Operation; *error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadShort:" FT_ERROR(( "FT_Stream_ReadUShort:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n", " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size )); stream->pos, stream->size ));
@ -530,8 +530,8 @@
} }
FT_BASE_DEF( FT_Short ) FT_BASE_DEF( FT_UShort )
FT_Stream_ReadShortLE( FT_Stream stream, FT_Stream_ReadUShortLE( FT_Stream stream,
FT_Error* error ) FT_Error* error )
{ {
FT_Byte reads[2]; FT_Byte reads[2];
@ -558,7 +558,7 @@
} }
if ( p ) if ( p )
result = FT_NEXT_SHORT_LE( p ); result = FT_NEXT_USHORT_LE( p );
} }
else else
goto Fail; goto Fail;
@ -569,7 +569,7 @@
Fail: Fail:
*error = FT_Err_Invalid_Stream_Operation; *error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadShortLE:" FT_ERROR(( "FT_Stream_ReadUShortLE:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n", " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size )); stream->pos, stream->size ));
@ -577,8 +577,8 @@
} }
FT_BASE_DEF( FT_Long ) FT_BASE_DEF( FT_ULong )
FT_Stream_ReadOffset( FT_Stream stream, FT_Stream_ReadUOffset( FT_Stream stream,
FT_Error* error ) FT_Error* error )
{ {
FT_Byte reads[3]; FT_Byte reads[3];
@ -605,7 +605,7 @@
} }
if ( p ) if ( p )
result = FT_NEXT_OFF3( p ); result = FT_NEXT_UOFF3( p );
} }
else else
goto Fail; goto Fail;
@ -616,7 +616,7 @@
Fail: Fail:
*error = FT_Err_Invalid_Stream_Operation; *error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadOffset:" FT_ERROR(( "FT_Stream_ReadUOffset:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n", " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size )); stream->pos, stream->size ));
@ -624,8 +624,8 @@
} }
FT_BASE_DEF( FT_Long ) FT_BASE_DEF( FT_ULong )
FT_Stream_ReadLong( FT_Stream stream, FT_Stream_ReadULong( FT_Stream stream,
FT_Error* error ) FT_Error* error )
{ {
FT_Byte reads[4]; FT_Byte reads[4];
@ -652,7 +652,7 @@
} }
if ( p ) if ( p )
result = FT_NEXT_LONG( p ); result = FT_NEXT_ULONG( p );
} }
else else
goto Fail; goto Fail;
@ -663,7 +663,7 @@
Fail: Fail:
*error = FT_Err_Invalid_Stream_Operation; *error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadLong:" FT_ERROR(( "FT_Stream_ReadULong:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n", " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size )); stream->pos, stream->size ));
@ -671,8 +671,8 @@
} }
FT_BASE_DEF( FT_Long ) FT_BASE_DEF( FT_ULong )
FT_Stream_ReadLongLE( FT_Stream stream, FT_Stream_ReadULongLE( FT_Stream stream,
FT_Error* error ) FT_Error* error )
{ {
FT_Byte reads[4]; FT_Byte reads[4];
@ -699,7 +699,7 @@
} }
if ( p ) if ( p )
result = FT_NEXT_LONG_LE( p ); result = FT_NEXT_ULONG_LE( p );
} }
else else
goto Fail; goto Fail;
@ -710,7 +710,7 @@
Fail: Fail:
*error = FT_Err_Invalid_Stream_Operation; *error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadLongLE:" FT_ERROR(( "FT_Stream_ReadULongLE:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n", " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size )); stream->pos, stream->size ));

View file

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType path stroker (body). */ /* FreeType path stroker (body). */
/* */ /* */
/* Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by */ /* Copyright 2002-2006, 2008-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -704,7 +704,6 @@
FT_Fixed miter_limit; FT_Fixed miter_limit;
FT_Fixed radius; FT_Fixed radius;
FT_Bool valid;
FT_StrokeBorderRec borders[2]; FT_StrokeBorderRec borders[2];
FT_Library library; FT_Library library;
@ -719,7 +718,7 @@
{ {
FT_Error error; FT_Error error;
FT_Memory memory; FT_Memory memory;
FT_Stroker stroker; FT_Stroker stroker = NULL;
if ( !library ) if ( !library )

View file

@ -13,7 +13,7 @@ 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 Adobe Specification V 2.2. The specification of the BDF font format is
available from Adobe's web site: available from Adobe's web site:
http://partners.adobe.com/asn/developer/PDFS/TN/5005.BDF_Spec.pdf http://partners.adobe.com/public/developer/en/font/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 They do not define vertical metrics, because the X Consortium BDF
@ -119,7 +119,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*** Portions of the driver (that is, bdflib.c and bdf.h): *** Portions of the driver (that is, bdflib.c and bdf.h):
Copyright 2000 Computing Research Labs, New Mexico State University Copyright 2000 Computing Research Labs, New Mexico State University
Copyright 2001-2002 Francesco Zappa Nardelli Copyright 2001-2002, 2011 Francesco Zappa Nardelli
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),

View file

@ -0,0 +1,510 @@
/***************************************************************************/
/* */
/* ftbzip2.c */
/* */
/* FreeType support for .bz2 compressed files. */
/* */
/* This optional component relies on libbz2. It should mainly be used to */
/* parse compressed PCF fonts, as found with many X11 server */
/* distributions. */
/* */
/* Copyright 2010 by */
/* Joel Klinghed. */
/* */
/* Based on src/gzip/ftgzip.c, Copyright 2002 - 2010 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include <ft2build.h>
#include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_DEBUG_H
#include FT_BZIP2_H
#include FT_CONFIG_STANDARD_LIBRARY_H
#include FT_MODULE_ERRORS_H
#undef __FTERRORS_H__
#define FT_ERR_PREFIX Bzip2_Err_
#define FT_ERR_BASE FT_Mod_Err_Bzip2
#include FT_ERRORS_H
#ifdef FT_CONFIG_OPTION_USE_BZIP2
#ifdef FT_CONFIG_OPTION_PIC
#error "bzip2 code does not support PIC yet"
#endif
#define BZ_NO_STDIO /* Do not need FILE */
#include <bzlib.h>
/***************************************************************************/
/***************************************************************************/
/***** *****/
/***** B Z I P 2 M E M O R Y M A N A G E M E N T *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
/* it is better to use FreeType memory routines instead of raw
'malloc/free' */
typedef void *(* alloc_func)(void*, int, int);
typedef void (* free_func)(void*, void*);
static void*
ft_bzip2_alloc( FT_Memory memory,
int items,
int size )
{
FT_ULong sz = (FT_ULong)size * items;
FT_Error error;
FT_Pointer p = NULL;
(void)FT_ALLOC( p, sz );
return p;
}
static void
ft_bzip2_free( FT_Memory memory,
void* address )
{
FT_MEM_FREE( address );
}
/***************************************************************************/
/***************************************************************************/
/***** *****/
/***** B Z I P 2 F I L E D E S C R I P T O R *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
#define FT_BZIP2_BUFFER_SIZE 4096
typedef struct FT_BZip2FileRec_
{
FT_Stream source; /* parent/source stream */
FT_Stream stream; /* embedding stream */
FT_Memory memory; /* memory allocator */
bz_stream bzstream; /* bzlib input stream */
FT_Byte input[FT_BZIP2_BUFFER_SIZE]; /* input read buffer */
FT_Byte buffer[FT_BZIP2_BUFFER_SIZE]; /* output buffer */
FT_ULong pos; /* position in output */
FT_Byte* cursor;
FT_Byte* limit;
} FT_BZip2FileRec, *FT_BZip2File;
/* check and skip .bz2 header - we don't support `transparent' compression */
static FT_Error
ft_bzip2_check_header( FT_Stream stream )
{
FT_Error error = Bzip2_Err_Ok;
FT_Byte head[4];
if ( FT_STREAM_SEEK( 0 ) ||
FT_STREAM_READ( head, 4 ) )
goto Exit;
/* head[0] && head[1] are the magic numbers; */
/* head[2] is the version, and head[3] the blocksize */
if ( head[0] != 0x42 ||
head[1] != 0x5a ||
head[2] != 0x68 ) /* only support bzip2 (huffman) */
{
error = Bzip2_Err_Invalid_File_Format;
goto Exit;
}
Exit:
return error;
}
static FT_Error
ft_bzip2_file_init( FT_BZip2File zip,
FT_Stream stream,
FT_Stream source )
{
bz_stream* bzstream = &zip->bzstream;
FT_Error error = Bzip2_Err_Ok;
zip->stream = stream;
zip->source = source;
zip->memory = stream->memory;
zip->limit = zip->buffer + FT_BZIP2_BUFFER_SIZE;
zip->cursor = zip->limit;
zip->pos = 0;
/* check .bz2 header */
{
stream = source;
error = ft_bzip2_check_header( stream );
if ( error )
goto Exit;
if ( FT_STREAM_SEEK( 0 ) )
goto Exit;
}
/* initialize bzlib */
bzstream->bzalloc = (alloc_func)ft_bzip2_alloc;
bzstream->bzfree = (free_func) ft_bzip2_free;
bzstream->opaque = zip->memory;
bzstream->avail_in = 0;
bzstream->next_in = (char*)zip->buffer;
if ( BZ2_bzDecompressInit( bzstream, 0, 0 ) != BZ_OK ||
bzstream->next_in == NULL )
error = Bzip2_Err_Invalid_File_Format;
Exit:
return error;
}
static void
ft_bzip2_file_done( FT_BZip2File zip )
{
bz_stream* bzstream = &zip->bzstream;
BZ2_bzDecompressEnd( bzstream );
/* clear the rest */
bzstream->bzalloc = NULL;
bzstream->bzfree = NULL;
bzstream->opaque = NULL;
bzstream->next_in = NULL;
bzstream->next_out = NULL;
bzstream->avail_in = 0;
bzstream->avail_out = 0;
zip->memory = NULL;
zip->source = NULL;
zip->stream = NULL;
}
static FT_Error
ft_bzip2_file_reset( FT_BZip2File zip )
{
FT_Stream stream = zip->source;
FT_Error error;
if ( !FT_STREAM_SEEK( 0 ) )
{
bz_stream* bzstream = &zip->bzstream;
BZ2_bzDecompressEnd( bzstream );
bzstream->avail_in = 0;
bzstream->next_in = (char*)zip->input;
bzstream->avail_out = 0;
bzstream->next_out = (char*)zip->buffer;
zip->limit = zip->buffer + FT_BZIP2_BUFFER_SIZE;
zip->cursor = zip->limit;
zip->pos = 0;
BZ2_bzDecompressInit( bzstream, 0, 0 );
}
return error;
}
static FT_Error
ft_bzip2_file_fill_input( FT_BZip2File zip )
{
bz_stream* bzstream = &zip->bzstream;
FT_Stream stream = zip->source;
FT_ULong size;
if ( stream->read )
{
size = stream->read( stream, stream->pos, zip->input,
FT_BZIP2_BUFFER_SIZE );
if ( size == 0 )
return Bzip2_Err_Invalid_Stream_Operation;
}
else
{
size = stream->size - stream->pos;
if ( size > FT_BZIP2_BUFFER_SIZE )
size = FT_BZIP2_BUFFER_SIZE;
if ( size == 0 )
return Bzip2_Err_Invalid_Stream_Operation;
FT_MEM_COPY( zip->input, stream->base + stream->pos, size );
}
stream->pos += size;
bzstream->next_in = (char*)zip->input;
bzstream->avail_in = size;
return Bzip2_Err_Ok;
}
static FT_Error
ft_bzip2_file_fill_output( FT_BZip2File zip )
{
bz_stream* bzstream = &zip->bzstream;
FT_Error error = Bzip2_Err_Ok;
zip->cursor = zip->buffer;
bzstream->next_out = (char*)zip->cursor;
bzstream->avail_out = FT_BZIP2_BUFFER_SIZE;
while ( bzstream->avail_out > 0 )
{
int err;
if ( bzstream->avail_in == 0 )
{
error = ft_bzip2_file_fill_input( zip );
if ( error )
break;
}
err = BZ2_bzDecompress( bzstream );
if ( err == BZ_STREAM_END )
{
zip->limit = (FT_Byte*)bzstream->next_out;
if ( zip->limit == zip->cursor )
error = Bzip2_Err_Invalid_Stream_Operation;
break;
}
else if ( err != BZ_OK )
{
error = Bzip2_Err_Invalid_Stream_Operation;
break;
}
}
return error;
}
/* fill output buffer; `count' must be <= FT_BZIP2_BUFFER_SIZE */
static FT_Error
ft_bzip2_file_skip_output( FT_BZip2File zip,
FT_ULong count )
{
FT_Error error = Bzip2_Err_Ok;
FT_ULong delta;
for (;;)
{
delta = (FT_ULong)( zip->limit - zip->cursor );
if ( delta >= count )
delta = count;
zip->cursor += delta;
zip->pos += delta;
count -= delta;
if ( count == 0 )
break;
error = ft_bzip2_file_fill_output( zip );
if ( error )
break;
}
return error;
}
static FT_ULong
ft_bzip2_file_io( FT_BZip2File zip,
FT_ULong pos,
FT_Byte* buffer,
FT_ULong count )
{
FT_ULong result = 0;
FT_Error error;
/* Reset inflate stream if we're seeking backwards. */
/* Yes, that is not too efficient, but it saves memory :-) */
if ( pos < zip->pos )
{
error = ft_bzip2_file_reset( zip );
if ( error )
goto Exit;
}
/* skip unwanted bytes */
if ( pos > zip->pos )
{
error = ft_bzip2_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) );
if ( error )
goto Exit;
}
if ( count == 0 )
goto Exit;
/* now read the data */
for (;;)
{
FT_ULong delta;
delta = (FT_ULong)( zip->limit - zip->cursor );
if ( delta >= count )
delta = count;
FT_MEM_COPY( buffer, zip->cursor, delta );
buffer += delta;
result += delta;
zip->cursor += delta;
zip->pos += delta;
count -= delta;
if ( count == 0 )
break;
error = ft_bzip2_file_fill_output( zip );
if ( error )
break;
}
Exit:
return result;
}
/***************************************************************************/
/***************************************************************************/
/***** *****/
/***** B Z E M B E D D I N G S T R E A M *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
static void
ft_bzip2_stream_close( FT_Stream stream )
{
FT_BZip2File zip = (FT_BZip2File)stream->descriptor.pointer;
FT_Memory memory = stream->memory;
if ( zip )
{
/* finalize bzip file descriptor */
ft_bzip2_file_done( zip );
FT_FREE( zip );
stream->descriptor.pointer = NULL;
}
}
static FT_ULong
ft_bzip2_stream_io( FT_Stream stream,
FT_ULong pos,
FT_Byte* buffer,
FT_ULong count )
{
FT_BZip2File zip = (FT_BZip2File)stream->descriptor.pointer;
return ft_bzip2_file_io( zip, pos, buffer, count );
}
FT_EXPORT_DEF( FT_Error )
FT_Stream_OpenBzip2( FT_Stream stream,
FT_Stream source )
{
FT_Error error;
FT_Memory memory = source->memory;
FT_BZip2File zip = NULL;
/*
* check the header right now; this prevents allocating unnecessary
* objects when we don't need them
*/
error = ft_bzip2_check_header( source );
if ( error )
goto Exit;
FT_ZERO( stream );
stream->memory = memory;
if ( !FT_QNEW( zip ) )
{
error = ft_bzip2_file_init( zip, stream, source );
if ( error )
{
FT_FREE( zip );
goto Exit;
}
stream->descriptor.pointer = zip;
}
stream->size = 0x7FFFFFFFL; /* don't know the real size! */
stream->pos = 0;
stream->base = 0;
stream->read = ft_bzip2_stream_io;
stream->close = ft_bzip2_stream_close;
Exit:
return error;
}
#else /* !FT_CONFIG_OPTION_USE_BZIP2 */
FT_EXPORT_DEF( FT_Error )
FT_Stream_OpenBzip2( FT_Stream stream,
FT_Stream source )
{
FT_UNUSED( stream );
FT_UNUSED( source );
return Bzip2_Err_Unimplemented_Feature;
}
#endif /* !FT_CONFIG_OPTION_USE_BZIP2 */
/* END */

View file

@ -0,0 +1,63 @@
#
# FreeType 2 BZIP2 support configuration rules
#
# Copyright 2010 by
# Joel Klinghed.
#
# Based on src/lzw/rules.mk, Copyright 2004-2006 by
# Albert Chin-A-Young.
#
# 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.
# BZIP2 driver directory
#
BZIP2_DIR := $(SRC_DIR)/bzip2
# compilation flags for the driver
#
BZIP2_COMPILE := $(FT_COMPILE)
# BZIP2 support sources (i.e., C files)
#
BZIP2_DRV_SRC := $(BZIP2_DIR)/ftbzip2.c
# BZIP2 driver object(s)
#
# BZIP2_DRV_OBJ_M is used during `multi' builds
# BZIP2_DRV_OBJ_S is used during `single' builds
#
BZIP2_DRV_OBJ_M := $(OBJ_DIR)/ftbzip2.$O
BZIP2_DRV_OBJ_S := $(OBJ_DIR)/ftbzip2.$O
# BZIP2 support source file for single build
#
BZIP2_DRV_SRC_S := $(BZIP2_DIR)/ftbzip2.c
# BZIP2 support - single object
#
$(BZIP2_DRV_OBJ_S): $(BZIP2_DRV_SRC_S) $(BZIP2_DRV_SRC) $(FREETYPE_H) $(BZIP2_DRV_H)
$(BZIP2_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BZIP2_DRV_SRC_S))
# BZIP2 support - multiple objects
#
$(OBJ_DIR)/%.$O: $(BZIP2_DIR)/%.c $(FREETYPE_H) $(BZIP2_DRV_H)
$(BZIP2_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
# update main driver object lists
#
DRV_OBJS_S += $(BZIP2_DRV_OBJ_S)
DRV_OBJS_M += $(BZIP2_DRV_OBJ_M)
# EOF

View file

@ -4,7 +4,7 @@
/* */ /* */
/* The FreeType basic cache interface (body). */ /* The FreeType basic cache interface (body). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ /* Copyright 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -17,6 +17,7 @@
#include <ft2build.h> #include <ft2build.h>
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_DEBUG_H
#include FT_CACHE_H #include FT_CACHE_H
#include "ftcglyph.h" #include "ftcglyph.h"
@ -237,7 +238,8 @@
FT_CALLBACK_DEF( FT_Bool ) FT_CALLBACK_DEF( FT_Bool )
ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode, ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode,
FT_Pointer ftcface_id, FT_Pointer ftcface_id,
FTC_Cache cache ) FTC_Cache cache,
FT_Bool* list_changed )
{ {
FTC_GNode gnode = (FTC_GNode)ftcgnode; FTC_GNode gnode = (FTC_GNode)ftcgnode;
FTC_FaceID face_id = (FTC_FaceID)ftcface_id; FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
@ -245,6 +247,8 @@
FT_Bool result; FT_Bool result;
if ( list_changed )
*list_changed = FALSE;
result = FT_BOOL( family->attrs.scaler.face_id == face_id ); result = FT_BOOL( family->attrs.scaler.face_id == face_id );
if ( result ) if ( result )
{ {

View file

@ -4,7 +4,8 @@
/* */ /* */
/* The FreeType internal cache interface (body). */ /* The FreeType internal cache interface (body). */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, */
/* 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -32,7 +33,7 @@
#define FTC_HASH_MIN_LOAD 1 #define FTC_HASH_MIN_LOAD 1
#define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD ) #define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD )
/* this one _must_ be a power of 2! */ /* this one _must_ be a power of 2! */
#define FTC_HASH_INITIAL_SIZE 8 #define FTC_HASH_INITIAL_SIZE 8
@ -83,6 +84,25 @@
(FTC_MruNode)node ); (FTC_MruNode)node );
} }
/* get a top bucket for specified hash from cache,
* body for FTC_NODE__TOP_FOR_HASH( cache, hash )
*/
FT_LOCAL_DEF( FTC_Node* )
ftc_get_top_node_for_hash( FTC_Cache cache,
FT_PtrDist hash )
{
FTC_Node* pnode;
FT_UInt idx;
idx = (FT_UInt)( hash & cache->mask );
if ( idx < cache->p )
idx = (FT_UInt)( hash & ( 2 * cache->mask + 1 ) );
pnode = cache->buckets + idx;
return pnode;
}
#endif /* !FTC_INLINE */ #endif /* !FTC_INLINE */
@ -96,9 +116,9 @@
for (;;) for (;;)
{ {
FTC_Node node, *pnode; FTC_Node node, *pnode;
FT_UFast p = cache->p; FT_UFast p = cache->p;
FT_UFast mask = cache->mask; FT_UFast mask = cache->mask;
FT_UFast count = mask + p + 1; /* number of buckets */ FT_UFast count = mask + p + 1; /* number of buckets */
/* do we need to shrink the buckets array? */ /* do we need to shrink the buckets array? */
@ -117,7 +137,8 @@
/* if we can't expand the array, leave immediately */ /* if we can't expand the array, leave immediately */
if ( FT_RENEW_ARRAY( cache->buckets, (mask+1)*2, (mask+1)*4 ) ) if ( FT_RENEW_ARRAY( cache->buckets,
( mask + 1 ) * 2, ( mask + 1 ) * 4 ) )
break; break;
} }
@ -191,7 +212,9 @@
cache->slack -= FTC_HASH_MAX_LOAD; cache->slack -= FTC_HASH_MAX_LOAD;
cache->p = p; cache->p = p;
} }
else /* the hash table is balanced */
/* otherwise, the hash table is balanced */
else
break; break;
} }
} }
@ -202,16 +225,9 @@
ftc_node_hash_unlink( FTC_Node node0, ftc_node_hash_unlink( FTC_Node node0,
FTC_Cache cache ) FTC_Cache cache )
{ {
FTC_Node *pnode; FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node0->hash );
FT_UInt idx;
idx = (FT_UInt)( node0->hash & cache->mask );
if ( idx < cache->p )
idx = (FT_UInt)( node0->hash & ( 2 * cache->mask + 1 ) );
pnode = cache->buckets + idx;
for (;;) for (;;)
{ {
FTC_Node node = *pnode; FTC_Node node = *pnode;
@ -242,16 +258,9 @@
ftc_node_hash_link( FTC_Node node, ftc_node_hash_link( FTC_Node node,
FTC_Cache cache ) FTC_Cache cache )
{ {
FTC_Node *pnode; FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node->hash );
FT_UInt idx;
idx = (FT_UInt)( node->hash & cache->mask );
if ( idx < cache->p )
idx = (FT_UInt)( node->hash & (2 * cache->mask + 1 ) );
pnode = cache->buckets + idx;
node->link = *pnode; node->link = *pnode;
*pnode = node; *pnode = node;
@ -413,8 +422,8 @@
FT_PtrDist hash, FT_PtrDist hash,
FTC_Node node ) FTC_Node node )
{ {
node->hash = hash; node->hash = hash;
node->cache_index = (FT_UInt16) cache->index; node->cache_index = (FT_UInt16)cache->index;
node->ref_count = 0; node->ref_count = 0;
ftc_node_hash_link( node, cache ); ftc_node_hash_link( node, cache );
@ -456,7 +465,7 @@
{ {
error = cache->clazz.node_new( &node, query, cache ); error = cache->clazz.node_new( &node, query, cache );
} }
FTC_CACHE_TRYLOOP_END(); FTC_CACHE_TRYLOOP_END( NULL );
if ( error ) if ( error )
node = NULL; node = NULL;
@ -481,11 +490,11 @@
FT_Pointer query, FT_Pointer query,
FTC_Node *anode ) FTC_Node *anode )
{ {
FT_UFast idx;
FTC_Node* bucket; FTC_Node* bucket;
FTC_Node* pnode; FTC_Node* pnode;
FTC_Node node; FTC_Node node;
FT_Error error = FTC_Err_Ok; FT_Error error = FTC_Err_Ok;
FT_Bool list_changed = FALSE;
FTC_Node_CompareFunc compare = cache->clazz.node_compare; FTC_Node_CompareFunc compare = cache->clazz.node_compare;
@ -493,24 +502,43 @@
if ( cache == NULL || anode == NULL ) if ( cache == NULL || anode == NULL )
return FTC_Err_Invalid_Argument; return FTC_Err_Invalid_Argument;
idx = hash & cache->mask; /* Go to the `top' node of the list sharing same masked hash */
if ( idx < cache->p ) bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash );
idx = hash & ( cache->mask * 2 + 1 );
bucket = cache->buckets + idx; /* Lookup a node with exactly same hash and queried properties. */
pnode = bucket; /* NOTE: _nodcomp() may change the linked list to reduce memory. */
for (;;) for (;;)
{ {
node = *pnode; node = *pnode;
if ( node == NULL ) if ( node == NULL )
goto NewNode; goto NewNode;
if ( node->hash == hash && compare( node, query, cache ) ) if ( node->hash == hash &&
compare( node, query, cache, &list_changed ) )
break; break;
pnode = &node->link; pnode = &node->link;
} }
if ( list_changed )
{
/* Update bucket by modified linked list */
bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash );
/* Update pnode by modified linked list */
while ( *pnode != node )
{
if ( *pnode == NULL )
{
FT_ERROR(( "FTC_Cache_Lookup: oops!!! node missing\n" ));
goto NewNode;
}
else
pnode = &((*pnode)->link);
}
}
/* Reorder the list to move the found node to the `top' */
if ( node != *bucket ) if ( node != *bucket )
{ {
*pnode = node->link; *pnode = node->link;
@ -527,6 +555,7 @@
ftc_node_mru_up( node, manager ); ftc_node_mru_up( node, manager );
} }
*anode = node; *anode = node;
return error; return error;
NewNode: NewNode:
@ -545,7 +574,7 @@
FTC_Node frees = NULL; FTC_Node frees = NULL;
count = cache->p + cache->mask; count = cache->p + cache->mask + 1;
for ( i = 0; i < count; i++ ) for ( i = 0; i < count; i++ )
{ {
FTC_Node* bucket = cache->buckets + i; FTC_Node* bucket = cache->buckets + i;
@ -555,12 +584,14 @@
for ( ;; ) for ( ;; )
{ {
FTC_Node node = *pnode; FTC_Node node = *pnode;
FT_Bool list_changed = FALSE;
if ( node == NULL ) if ( node == NULL )
break; break;
if ( cache->clazz.node_remove_faceid( node, face_id, cache ) ) if ( cache->clazz.node_remove_faceid( node, face_id,
cache, &list_changed ) )
{ {
*pnode = node->link; *pnode = node->link;
node->link = frees; node->link = frees;

View file

@ -4,7 +4,8 @@
/* */ /* */
/* FreeType internal cache interface (specification). */ /* FreeType internal cache interface (specification). */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, */
/* 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -24,7 +25,7 @@
FT_BEGIN_HEADER FT_BEGIN_HEADER
#define _FTC_FACE_ID_HASH( i ) \ #define _FTC_FACE_ID_HASH( i ) \
((FT_PtrDist)(( (FT_PtrDist)(i) >> 3 ) ^ ( (FT_PtrDist)(i) << 7 ))) ((FT_PtrDist)(( (FT_PtrDist)(i) >> 3 ) ^ ( (FT_PtrDist)(i) << 7 )))
/* handle to cache object */ /* handle to cache object */
@ -72,6 +73,19 @@ FT_BEGIN_HEADER
#define FTC_NODE__NEXT( x ) FTC_NODE( (x)->mru.next ) #define FTC_NODE__NEXT( x ) FTC_NODE( (x)->mru.next )
#define FTC_NODE__PREV( x ) FTC_NODE( (x)->mru.prev ) #define FTC_NODE__PREV( x ) FTC_NODE( (x)->mru.prev )
#ifdef FTC_INLINE
#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \
( ( cache )->buckets + \
( ( ( ( hash ) & ( cache )->mask ) < ( cache )->p ) \
? ( ( hash ) & ( ( cache )->mask * 2 + 1 ) ) \
: ( ( hash ) & ( cache )->mask ) ) )
#else
FT_LOCAL( FTC_Node* )
ftc_get_top_node_for_hash( FTC_Cache cache,
FT_PtrDist hash );
#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \
ftc_get_top_node_for_hash( ( cache ), ( hash ) )
#endif
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
FT_BASE( void ) FT_BASE( void )
@ -102,7 +116,8 @@ FT_BEGIN_HEADER
typedef FT_Bool typedef FT_Bool
(*FTC_Node_CompareFunc)( FTC_Node node, (*FTC_Node_CompareFunc)( FTC_Node node,
FT_Pointer key, FT_Pointer key,
FTC_Cache cache ); FTC_Cache cache,
FT_Bool* list_changed );
typedef void typedef void
@ -162,7 +177,7 @@ FT_BEGIN_HEADER
FT_LOCAL( void ) FT_LOCAL( void )
FTC_Cache_Done( FTC_Cache cache ); FTC_Cache_Done( FTC_Cache cache );
/* Call this function to lookup the cache. If no corresponding /* Call this function to look up the cache. If no corresponding
* node is found, a new one is automatically created. This function * node is found, a new one is automatically created. This function
* is capable of flushing the cache adequately to make room for the * is capable of flushing the cache adequately to make room for the
* new cache object. * new cache object.
@ -184,7 +199,7 @@ FT_BEGIN_HEADER
/* Remove all nodes that relate to a given face_id. This is useful /* Remove all nodes that relate to a given face_id. This is useful
* when un-installing fonts. Note that if a cache node relates to * when un-installing fonts. Note that if a cache node relates to
* the face_id, but is locked (i.e., has `ref_count > 0'), the node * the face_id but is locked (i.e., has `ref_count > 0'), the node
* will _not_ be destroyed, but its internal face_id reference will * will _not_ be destroyed, but its internal face_id reference will
* be modified. * be modified.
* *
@ -205,28 +220,49 @@ FT_BEGIN_HEADER
FTC_Cache _cache = FTC_CACHE(cache); \ FTC_Cache _cache = FTC_CACHE(cache); \
FT_PtrDist _hash = (FT_PtrDist)(hash); \ FT_PtrDist _hash = (FT_PtrDist)(hash); \
FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \
FT_UFast _idx; \ FT_Bool _list_changed = FALSE; \
\ \
\ \
error = FTC_Err_Ok; \ error = FTC_Err_Ok; \
node = NULL; \ node = NULL; \
_idx = _hash & _cache->mask; \
if ( _idx < _cache->p ) \
_idx = _hash & ( _cache->mask*2 + 1 ); \
\ \
_bucket = _pnode = _cache->buckets + _idx; \ /* Go to the `top' node of the list sharing same masked hash */ \
_bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \
\
/* Look up a node with identical hash and queried properties. */ \
/* NOTE: _nodcomp() may change the linked list to reduce memory. */ \
for (;;) \ for (;;) \
{ \ { \
_node = *_pnode; \ _node = *_pnode; \
if ( _node == NULL ) \ if ( _node == NULL ) \
goto _NewNode; \ goto _NewNode; \
\ \
if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) ) \ if ( _node->hash == _hash && \
_nodcomp( _node, query, _cache, &_list_changed ) ) \
break; \ break; \
\ \
_pnode = &_node->link; \ _pnode = &_node->link; \
} \ } \
\ \
if ( _list_changed ) \
{ \
/* Update _bucket by possibly modified linked list */ \
_bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \
\
/* Update _pnode by possibly modified linked list */ \
while ( *_pnode != _node ) \
{ \
if ( *_pnode == NULL ) \
{ \
FT_ERROR(( "FTC_CACHE_LOOKUP_CMP: oops!!! node missing\n" )); \
goto _NewNode; \
} \
else \
_pnode = &((*_pnode)->link); \
} \
} \
\
/* Reorder the list to move the found node to the `top' */ \
if ( _node != *_bucket ) \ if ( _node != *_bucket ) \
{ \ { \
*_pnode = _node->link; \ *_pnode = _node->link; \
@ -234,6 +270,7 @@ FT_BEGIN_HEADER
*_bucket = _node; \ *_bucket = _node; \
} \ } \
\ \
/* Update MRU list */ \
{ \ { \
FTC_Manager _manager = _cache->manager; \ FTC_Manager _manager = _cache->manager; \
void* _nl = &_manager->nodes_list; \ void* _nl = &_manager->nodes_list; \
@ -268,7 +305,7 @@ FT_BEGIN_HEADER
* loop to flush the cache repeatedly in case of memory overflows. * loop to flush the cache repeatedly in case of memory overflows.
* *
* It is used when creating a new cache node, or within a lookup * It is used when creating a new cache node, or within a lookup
* that needs to allocate data (e.g., the sbit cache lookup). * that needs to allocate data (e.g. the sbit cache lookup).
* *
* Example: * Example:
* *
@ -290,11 +327,14 @@ FT_BEGIN_HEADER
FT_UInt _try_done; FT_UInt _try_done;
#define FTC_CACHE_TRYLOOP_END() \ #define FTC_CACHE_TRYLOOP_END( list_changed ) \
if ( !error || error != FTC_Err_Out_Of_Memory ) \ if ( !error || error != FTC_Err_Out_Of_Memory ) \
break; \ break; \
\ \
_try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \
if ( _try_done > 0 && ( list_changed ) ) \
*(FT_Bool*)( list_changed ) = TRUE; \
\
if ( _try_done == 0 ) \ if ( _try_done == 0 ) \
break; \ break; \
\ \

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Callback functions of the caching sub-system (specification only). */ /* Callback functions of the caching sub-system (specification only). */
/* */ /* */
/* Copyright 2004, 2005, 2006 by */ /* Copyright 2004, 2005, 2006, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -57,13 +57,15 @@
FT_LOCAL( FT_Bool ) FT_LOCAL( FT_Bool )
ftc_snode_compare( FTC_Node snode, ftc_snode_compare( FTC_Node snode,
FT_Pointer gquery, FT_Pointer gquery,
FTC_Cache cache ); FTC_Cache cache,
FT_Bool* list_changed );
FT_LOCAL( FT_Bool ) FT_LOCAL( FT_Bool )
ftc_gnode_compare( FTC_Node gnode, ftc_gnode_compare( FTC_Node gnode,
FT_Pointer gquery, FT_Pointer gquery,
FTC_Cache cache ); FTC_Cache cache,
FT_Bool* list_changed );
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )

View file

@ -5,7 +5,7 @@
/* FreeType CharMap cache (body) */ /* FreeType CharMap cache (body) */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
/* 2010 by */ /* 2010, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -22,6 +22,7 @@
#include FT_CACHE_H #include FT_CACHE_H
#include "ftcmanag.h" #include "ftcmanag.h"
#include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_DEBUG_H
#include "ftccback.h" #include "ftccback.h"
@ -190,13 +191,16 @@
FT_CALLBACK_DEF( FT_Bool ) FT_CALLBACK_DEF( FT_Bool )
ftc_cmap_node_compare( FTC_Node ftcnode, ftc_cmap_node_compare( FTC_Node ftcnode,
FT_Pointer ftcquery, FT_Pointer ftcquery,
FTC_Cache cache ) FTC_Cache cache,
FT_Bool* list_changed )
{ {
FTC_CMapNode node = (FTC_CMapNode)ftcnode; FTC_CMapNode node = (FTC_CMapNode)ftcnode;
FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
FT_UNUSED( cache ); FT_UNUSED( cache );
if ( list_changed )
*list_changed = FALSE;
if ( node->face_id == query->face_id && if ( node->face_id == query->face_id &&
node->cmap_index == query->cmap_index ) node->cmap_index == query->cmap_index )
{ {
@ -213,12 +217,16 @@
FT_CALLBACK_DEF( FT_Bool ) FT_CALLBACK_DEF( FT_Bool )
ftc_cmap_node_remove_faceid( FTC_Node ftcnode, ftc_cmap_node_remove_faceid( FTC_Node ftcnode,
FT_Pointer ftcface_id, FT_Pointer ftcface_id,
FTC_Cache cache ) FTC_Cache cache,
FT_Bool* list_changed )
{ {
FTC_CMapNode node = (FTC_CMapNode)ftcnode; FTC_CMapNode node = (FTC_CMapNode)ftcnode;
FTC_FaceID face_id = (FTC_FaceID)ftcface_id; FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
FT_UNUSED( cache ); FT_UNUSED( cache );
if ( list_changed )
*list_changed = FALSE;
return FT_BOOL( node->face_id == face_id ); return FT_BOOL( node->face_id == face_id );
} }

View file

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType Glyph Image (FT_Glyph) cache (body). */ /* FreeType Glyph Image (FT_Glyph) cache (body). */
/* */ /* */
/* Copyright 2000-2001, 2003, 2004, 2006, 2009 by */ /* Copyright 2000-2001, 2003, 2004, 2006, 2009, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -17,6 +17,7 @@
#include <ft2build.h> #include <ft2build.h>
#include FT_INTERNAL_OBJECTS_H
#include FT_CACHE_H #include FT_CACHE_H
#include "ftcglyph.h" #include "ftcglyph.h"
#include FT_ERRORS_H #include FT_ERRORS_H
@ -64,25 +65,34 @@
FT_LOCAL_DEF( FT_Bool ) FT_LOCAL_DEF( FT_Bool )
ftc_gnode_compare( FTC_Node ftcgnode, ftc_gnode_compare( FTC_Node ftcgnode,
FT_Pointer ftcgquery, FT_Pointer ftcgquery,
FTC_Cache cache ) FTC_Cache cache,
FT_Bool* list_changed )
{ {
FTC_GNode gnode = (FTC_GNode)ftcgnode; FTC_GNode gnode = (FTC_GNode)ftcgnode;
FTC_GQuery gquery = (FTC_GQuery)ftcgquery; FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
FT_UNUSED( cache ); FT_UNUSED( cache );
if ( list_changed )
*list_changed = FALSE;
return FT_BOOL( gnode->family == gquery->family && return FT_BOOL( gnode->family == gquery->family &&
gnode->gindex == gquery->gindex ); gnode->gindex == gquery->gindex );
} }
#ifdef FTC_INLINE
FT_LOCAL_DEF( FT_Bool ) FT_LOCAL_DEF( FT_Bool )
FTC_GNode_Compare( FTC_GNode gnode, FTC_GNode_Compare( FTC_GNode gnode,
FTC_GQuery gquery ) FTC_GQuery gquery,
FTC_Cache cache,
FT_Bool* list_changed )
{ {
return ftc_gnode_compare( FTC_NODE( gnode ), gquery, NULL ); return ftc_gnode_compare( FTC_NODE( gnode ), gquery,
cache, list_changed );
} }
#endif
/*************************************************************************/ /*************************************************************************/
/*************************************************************************/ /*************************************************************************/

View file

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType abstract glyph cache (specification). */ /* FreeType abstract glyph cache (specification). */
/* */ /* */
/* Copyright 2000-2001, 2003, 2004, 2006, 2007 by */ /* Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -180,12 +180,18 @@ FT_BEGIN_HEADER
FT_UInt gindex, /* glyph index for node */ FT_UInt gindex, /* glyph index for node */
FTC_Family family ); FTC_Family family );
#ifdef FTC_INLINE
/* returns TRUE iff the query's glyph index correspond to the node; */ /* returns TRUE iff the query's glyph index correspond to the node; */
/* this assumes that the `family' and `hash' fields of the query are */ /* this assumes that the `family' and `hash' fields of the query are */
/* already correctly set */ /* already correctly set */
FT_LOCAL( FT_Bool ) FT_LOCAL( FT_Bool )
FTC_GNode_Compare( FTC_GNode gnode, FTC_GNode_Compare( FTC_GNode gnode,
FTC_GQuery gquery ); FTC_GQuery gquery,
FTC_Cache cache,
FT_Bool* list_changed );
#endif
/* call this function to clear a node's family -- this is necessary */ /* call this function to clear a node's family -- this is necessary */
/* to implement the `node_remove_faceid' cache method correctly */ /* to implement the `node_remove_faceid' cache method correctly */
@ -307,7 +313,7 @@ FT_BEGIN_HEADER
FT_BEGIN_STMNT \ FT_BEGIN_STMNT \
\ \
error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \ error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \
FTC_GQUERY( query ), node ); \ FTC_GQUERY( query ), &node ); \
\ \
FT_END_STMNT FT_END_STMNT

View file

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType Cache Manager (specification). */ /* FreeType Cache Manager (specification). */
/* */ /* */
/* Copyright 2000-2001, 2003, 2004, 2006 by */ /* Copyright 2000-2001, 2003, 2004, 2006, 2010 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */

View file

@ -161,7 +161,7 @@
*plist = NULL; *plist = NULL;
} }
else if ( node == first ) else if ( node == first )
*plist = next; *plist = next;
} }
@ -238,7 +238,7 @@
FTC_MruNode *anode ) FTC_MruNode *anode )
{ {
FT_Error error; FT_Error error;
FTC_MruNode node; FTC_MruNode node = NULL;
FT_Memory memory = list->memory; FT_Memory memory = list->memory;
@ -264,14 +264,14 @@
list->clazz.node_done( node, list->data ); list->clazz.node_done( node, list->data );
} }
else if ( FT_ALLOC( node, list->clazz.node_size ) ) else if ( FT_ALLOC( node, list->clazz.node_size ) )
goto Exit; goto Exit;
error = list->clazz.node_init( node, key, list->data ); error = list->clazz.node_init( node, key, list->data );
if ( error ) if ( error )
goto Fail; goto Fail;
FTC_MruNode_Prepend( &list->nodes, node ); FTC_MruNode_Prepend( &list->nodes, node );
list->num_nodes++; list->num_nodes++;
Exit: Exit:
*anode = node; *anode = node;
@ -316,7 +316,7 @@
if ( list->clazz.node_done ) if ( list->clazz.node_done )
list->clazz.node_done( node, list->data ); list->clazz.node_done( node, list->data );
FT_FREE( node ); FT_FREE( node );
} }

View file

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType sbits manager (body). */ /* FreeType sbits manager (body). */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010 by */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -217,6 +217,7 @@
FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache ); FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache );
FT_UInt total; FT_UInt total;
FT_UInt node_count;
total = clazz->family_get_count( family, cache->manager ); total = clazz->family_get_count( family, cache->manager );
@ -239,6 +240,10 @@
FTC_GNode_Init( FTC_GNODE( snode ), start, family ); FTC_GNode_Init( FTC_GNODE( snode ), start, family );
snode->count = count; snode->count = count;
for ( node_count = 0; node_count < count; node_count++ )
{
snode->sbits[node_count].width = 255;
}
error = ftc_snode_load( snode, error = ftc_snode_load( snode,
cache->manager, cache->manager,
@ -319,7 +324,8 @@
FT_LOCAL_DEF( FT_Bool ) FT_LOCAL_DEF( FT_Bool )
ftc_snode_compare( FTC_Node ftcsnode, ftc_snode_compare( FTC_Node ftcsnode,
FT_Pointer ftcgquery, FT_Pointer ftcgquery,
FTC_Cache cache ) FTC_Cache cache,
FT_Bool* list_changed )
{ {
FTC_SNode snode = (FTC_SNode)ftcsnode; FTC_SNode snode = (FTC_SNode)ftcsnode;
FTC_GQuery gquery = (FTC_GQuery)ftcgquery; FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
@ -328,6 +334,8 @@
FT_Bool result; FT_Bool result;
if (list_changed)
*list_changed = FALSE;
result = FT_BOOL( gnode->family == gquery->family && result = FT_BOOL( gnode->family == gquery->family &&
(FT_UInt)( gindex - gnode->gindex ) < snode->count ); (FT_UInt)( gindex - gnode->gindex ) < snode->count );
if ( result ) if ( result )
@ -368,7 +376,7 @@
* *
*/ */
if ( sbit->buffer == NULL && sbit->width != 255 ) if ( sbit->buffer == NULL && sbit->width == 255 )
{ {
FT_ULong size; FT_ULong size;
FT_Error error; FT_Error error;
@ -381,7 +389,7 @@
{ {
error = ftc_snode_load( snode, cache->manager, gindex, &size ); error = ftc_snode_load( snode, cache->manager, gindex, &size );
} }
FTC_CACHE_TRYLOOP_END(); FTC_CACHE_TRYLOOP_END( list_changed );
ftcsnode->ref_count--; /* unlock the node */ ftcsnode->ref_count--; /* unlock the node */
@ -396,13 +404,18 @@
} }
#ifdef FTC_INLINE
FT_LOCAL_DEF( FT_Bool ) FT_LOCAL_DEF( FT_Bool )
FTC_SNode_Compare( FTC_SNode snode, FTC_SNode_Compare( FTC_SNode snode,
FTC_GQuery gquery, FTC_GQuery gquery,
FTC_Cache cache ) FTC_Cache cache,
FT_Bool* list_changed )
{ {
return ftc_snode_compare( FTC_NODE( snode ), gquery, cache ); return ftc_snode_compare( FTC_NODE( snode ), gquery,
cache, list_changed );
} }
#endif
/* END */ /* END */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* A small-bitmap cache (specification). */ /* A small-bitmap cache (specification). */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2006 by */ /* Copyright 2000-2001, 2002, 2003, 2006, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -83,10 +83,15 @@ FT_BEGIN_HEADER
#endif #endif
#ifdef FTC_INLINE
FT_LOCAL( FT_Bool ) FT_LOCAL( FT_Bool )
FTC_SNode_Compare( FTC_SNode snode, FTC_SNode_Compare( FTC_SNode snode,
FTC_GQuery gquery, FTC_GQuery gquery,
FTC_Cache cache ); FTC_Cache cache,
FT_Bool* list_changed);
#endif
/* */ /* */

View file

@ -328,7 +328,7 @@
if ( cff && cff->font_info == NULL ) if ( cff && cff->font_info == NULL )
{ {
CFF_FontRecDict dict = &cff->top_font.font_dict; CFF_FontRecDict dict = &cff->top_font.font_dict;
PS_FontInfoRec *font_info; PS_FontInfoRec *font_info = NULL;
FT_Memory memory = face->root.memory; FT_Memory memory = face->root.memory;

View file

@ -4,8 +4,7 @@
/* */ /* */
/* OpenType Glyph Loader (body). */ /* OpenType Glyph Loader (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ /* Copyright 1996-2011 by */
/* 2010 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -1159,8 +1158,8 @@
op = cff_op_flex1; op = cff_op_flex1;
break; break;
default: default:
/* decrement ip for syntax error message */ FT_TRACE4(( " unknown op (12, %d)\n", v ));
ip--; break;
} }
} }
break; break;
@ -1213,11 +1212,12 @@
op = cff_op_hvcurveto; op = cff_op_hvcurveto;
break; break;
default: default:
FT_TRACE4(( " unknown op (%d)\n", v ));
break; break;
} }
if ( op == cff_op_unknown ) if ( op == cff_op_unknown )
goto Syntax_Error; continue;
/* check arguments */ /* check arguments */
req_args = cff_argument_counts[op]; req_args = cff_argument_counts[op];
@ -1438,9 +1438,14 @@
FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n" FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
: " vlineto\n" )); : " vlineto\n" ));
if ( num_args < 1 ) if ( num_args < 0 )
goto Stack_Underflow; goto Stack_Underflow;
/* there exist subsetted fonts (found in PDFs) */
/* which call `hlineto' without arguments */
if ( num_args == 0 )
break;
if ( cff_builder_start_point ( builder, x, y ) || if ( cff_builder_start_point ( builder, x, y ) ||
check_points( builder, num_args ) ) check_points( builder, num_args ) )
goto Fail; goto Fail;
@ -2701,7 +2706,7 @@
glyph_index ); glyph_index );
if ( fd_index >= cff->num_subfonts ) if ( fd_index >= cff->num_subfonts )
fd_index = cff->num_subfonts - 1; fd_index = (FT_Byte)( cff->num_subfonts - 1 );
top_upm = cff->top_font.font_dict.units_per_em; top_upm = cff->top_font.font_dict.units_per_em;
sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em; sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;

View file

@ -387,7 +387,7 @@
{ {
FT_Error error = CFF_Err_Ok; FT_Error error = CFF_Err_Ok;
FT_Memory memory = idx->stream->memory; FT_Memory memory = idx->stream->memory;
FT_Byte** t; FT_Byte** t = NULL;
FT_Byte* new_bytes = NULL; FT_Byte* new_bytes = NULL;
@ -1514,7 +1514,7 @@
if ( dict->cid_registry != 0xFFFFU ) if ( dict->cid_registry != 0xFFFFU )
{ {
CFF_IndexRec fd_index; CFF_IndexRec fd_index;
CFF_SubFont sub; CFF_SubFont sub = NULL;
FT_UInt idx; FT_UInt idx;

View file

@ -4,8 +4,7 @@
/* */ /* */
/* OpenType objects manager (body). */ /* OpenType objects manager (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ /* Copyright 1996-2011 by */
/* 2010 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -162,7 +161,7 @@
{ {
CFF_Face face = (CFF_Face)cffsize->face; CFF_Face face = (CFF_Face)cffsize->face;
CFF_Font font = (CFF_Font)face->extra.data; CFF_Font font = (CFF_Font)face->extra.data;
CFF_Internal internal; CFF_Internal internal = NULL;
PS_PrivateRec priv; PS_PrivateRec priv;
FT_Memory memory = cffsize->face->memory; FT_Memory memory = cffsize->face->memory;
@ -421,6 +420,7 @@
{ {
for ( idx = 7; idx < length; idx++ ) for ( idx = 7; idx < length; idx++ )
name[idx - 7] = name[idx]; name[idx - 7] = name[idx];
length -= 7;
} }
} }
else else
@ -429,6 +429,51 @@
} }
/* Remove the style part from the family name (if present). */
static void
remove_style( FT_String* family_name,
const FT_String* style_name )
{
FT_Int32 family_name_length, style_name_length;
family_name_length = strlen( family_name );
style_name_length = strlen( style_name );
if ( family_name_length > style_name_length )
{
FT_Int idx;
for ( idx = 1; idx <= style_name_length; ++idx )
{
if ( family_name[family_name_length - idx] !=
style_name[style_name_length - idx] )
break;
}
if ( idx > style_name_length )
{
/* family_name ends with style_name; remove it */
idx = family_name_length - style_name_length - 1;
/* also remove special characters */
/* between real family name and style */
while ( idx > 0 &&
( family_name[idx] == '-' ||
family_name[idx] == ' ' ||
family_name[idx] == '_' ||
family_name[idx] == '+' ) )
--idx;
if ( idx > 0 )
family_name[idx + 1] = '\0';
}
}
}
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
cff_face_init( FT_Stream stream, cff_face_init( FT_Stream stream,
FT_Face cffface, /* CFF_Face */ FT_Face cffface, /* CFF_Face */
@ -436,14 +481,14 @@
FT_Int num_params, FT_Int num_params,
FT_Parameter* params ) FT_Parameter* params )
{ {
CFF_Face face = (CFF_Face)cffface; CFF_Face face = (CFF_Face)cffface;
FT_Error error; FT_Error error;
SFNT_Service sfnt; SFNT_Service sfnt;
FT_Service_PsCMaps psnames; FT_Service_PsCMaps psnames;
PSHinter_Service pshinter; PSHinter_Service pshinter;
FT_Bool pure_cff = 1; FT_Bool pure_cff = 1;
FT_Bool sfnt_format = 0; FT_Bool sfnt_format = 0;
FT_Library library = cffface->driver->root.library; FT_Library library = cffface->driver->root.library;
sfnt = (SFNT_Service)FT_Get_Module_Interface( sfnt = (SFNT_Service)FT_Get_Module_Interface(
@ -523,7 +568,7 @@
/* now load and parse the CFF table in the file */ /* now load and parse the CFF table in the file */
{ {
CFF_Font cff; CFF_Font cff = NULL;
CFF_FontRecDict dict; CFF_FontRecDict dict;
FT_Memory memory = cffface->memory; FT_Memory memory = cffface->memory;
FT_Int32 flags; FT_Int32 flags;
@ -758,6 +803,9 @@
/* case, the remaining string in `fullp' will be used as */ /* case, the remaining string in `fullp' will be used as */
/* the style name. */ /* the style name. */
style_name = cff_strcpy( memory, fullp ); style_name = cff_strcpy( memory, fullp );
/* remove the style part from the family name (if present) */
remove_style( cffface->family_name, style_name );
} }
break; break;
} }

View file

@ -5,7 +5,7 @@
/* Basic OpenType/CFF type definitions and interface (specification */ /* Basic OpenType/CFF type definitions and interface (specification */
/* only). */ /* only). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 2010 by */ /* Copyright 1996-2003, 2006-2008, 2010-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -212,8 +212,7 @@ FT_BEGIN_HEADER
} CFF_SubFontRec, *CFF_SubFont; } CFF_SubFontRec, *CFF_SubFont;
/* maximum number of sub-fonts in a CID-keyed file */ #define CFF_MAX_CID_FONTS 256
#define CFF_MAX_CID_FONTS 32
typedef struct CFF_FontRec_ typedef struct CFF_FontRec_

View file

@ -3,7 +3,7 @@
# #
# Copyright 1996-2000, 2001, 2003 by # Copyright 1996-2000, 2001, 2003, 2011 by
# David Turner, Robert Wilhelm, and Werner Lemberg. # David Turner, Robert Wilhelm, and Werner Lemberg.
# #
# This file is part of the FreeType project, and may only be used, modified, # This file is part of the FreeType project, and may only be used, modified,
@ -23,19 +23,20 @@ CFF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CFF_DIR))
# CFF driver sources (i.e., C files) # CFF driver sources (i.e., C files)
# #
CFF_DRV_SRC := $(CFF_DIR)/cffobjs.c \ CFF_DRV_SRC := $(CFF_DIR)/cffcmap.c \
$(CFF_DIR)/cffload.c \ $(CFF_DIR)/cffdrivr.c \
$(CFF_DIR)/cffgload.c \ $(CFF_DIR)/cffgload.c \
$(CFF_DIR)/cffload.c \
$(CFF_DIR)/cffobjs.c \
$(CFF_DIR)/cffparse.c \ $(CFF_DIR)/cffparse.c \
$(CFF_DIR)/cffcmap.c \ $(CFF_DIR)/cffpic.c
$(CFF_DIR)/cffdrivr.c
# CFF driver headers # CFF driver headers
# #
CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \ CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \
$(CFF_DIR)/cfferrs.h \
$(CFF_DIR)/cfftoken.h \ $(CFF_DIR)/cfftoken.h \
$(CFF_DIR)/cfftypes.h \ $(CFF_DIR)/cfftypes.h
$(CFF_DIR)/cfferrs.h
# CFF driver object(s) # CFF driver object(s)

View file

@ -304,8 +304,7 @@
binSrchHeader->unitSize, binSrchHeader->nUnits, binSrchHeader->unitSize, binSrchHeader->nUnits,
searchRange, entrySelector, rangeShift )); searchRange, entrySelector, rangeShift ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
FT_INVALID_DATA;
} }
} }
@ -442,8 +441,7 @@
{ {
GXV_TRACE(( "too short, glyphs %d - %d are missing\n", GXV_TRACE(( "too short, glyphs %d - %d are missing\n",
i, valid->face->num_glyphs )); i, valid->face->num_glyphs ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
FT_INVALID_GLYPH_ID;
break; break;
} }
@ -531,8 +529,7 @@
GXV_TRACE(( "reverse ordered segment specification:" GXV_TRACE(( "reverse ordered segment specification:"
" lastGlyph[%d]=%d < lastGlyph[%d]=%d\n", " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n",
unit, lastGlyph, unit - 1 , gid )); unit, lastGlyph, unit - 1 , gid ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
FT_INVALID_GLYPH_ID;
} }
if ( lastGlyph < firstGlyph ) if ( lastGlyph < firstGlyph )
@ -540,8 +537,7 @@
GXV_TRACE(( "reverse ordered range specification at unit %d:", GXV_TRACE(( "reverse ordered range specification at unit %d:",
" lastGlyph %d < firstGlyph %d ", " lastGlyph %d < firstGlyph %d ",
unit, lastGlyph, firstGlyph )); unit, lastGlyph, firstGlyph ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
FT_INVALID_GLYPH_ID;
if ( valid->root->level == FT_VALIDATE_TIGHT ) if ( valid->root->level == FT_VALIDATE_TIGHT )
continue; /* ftxvalidator silently skips such an entry */ continue; /* ftxvalidator silently skips such an entry */
@ -604,8 +600,7 @@
GXV_TRACE(( "reverse ordered segment specification:" GXV_TRACE(( "reverse ordered segment specification:"
" lastGlyph[%d]=%d < lastGlyph[%d]=%d\n", " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n",
unit, lastGlyph, unit - 1 , gid )); unit, lastGlyph, unit - 1 , gid ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
FT_INVALID_GLYPH_ID;
} }
if ( lastGlyph < firstGlyph ) if ( lastGlyph < firstGlyph )
@ -613,8 +608,7 @@
GXV_TRACE(( "reverse ordered range specification at unit %d:", GXV_TRACE(( "reverse ordered range specification at unit %d:",
" lastGlyph %d < firstGlyph %d ", " lastGlyph %d < firstGlyph %d ",
unit, lastGlyph, firstGlyph )); unit, lastGlyph, firstGlyph ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
FT_INVALID_GLYPH_ID;
if ( valid->root->level == FT_VALIDATE_TIGHT ) if ( valid->root->level == FT_VALIDATE_TIGHT )
continue; /* ftxvalidator silently skips such an entry */ continue; /* ftxvalidator silently skips such an entry */
@ -705,8 +699,7 @@
{ {
GXV_TRACE(( "current gid 0x%04x < previous gid 0x%04x\n", GXV_TRACE(( "current gid 0x%04x < previous gid 0x%04x\n",
glyph, prev_glyph )); glyph, prev_glyph ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
FT_INVALID_GLYPH_ID;
} }
prev_glyph = glyph; prev_glyph = glyph;
@ -834,8 +827,7 @@
{ {
GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n", GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n",
face->num_glyphs, gid )); face->num_glyphs, gid ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
FT_INVALID_GLYPH_ID;
} }
return 0; return 0;
@ -1101,8 +1093,7 @@
if ( ( maxEntry + 1 ) * entrySize > *length_p ) if ( ( maxEntry + 1 ) * entrySize > *length_p )
{ {
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_TOO_SHORT );
FT_INVALID_TOO_SHORT;
/* ftxvalidator and FontValidator both warn and continue */ /* ftxvalidator and FontValidator both warn and continue */
maxEntry = (FT_Byte)( *length_p / entrySize - 1 ); maxEntry = (FT_Byte)( *length_p / entrySize - 1 );
@ -1126,8 +1117,7 @@
{ {
GXV_TRACE(( " newState offset 0x%04x is out of stateArray\n", GXV_TRACE(( " newState offset 0x%04x is out of stateArray\n",
newState )); newState ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
FT_INVALID_OFFSET;
continue; continue;
} }
@ -1135,8 +1125,7 @@
{ {
GXV_TRACE(( " newState offset 0x%04x is not aligned to %d-classes\n", GXV_TRACE(( " newState offset 0x%04x is not aligned to %d-classes\n",
newState, 1 + maxClassID )); newState, 1 + maxClassID ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
FT_INVALID_OFFSET;
continue; continue;
} }
@ -1173,8 +1162,7 @@
break; break;
default: default:
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT );
FT_INVALID_FORMAT;
goto Exit; goto Exit;
} }
@ -1503,8 +1491,7 @@
{ {
GXV_TRACE(( " newState index 0x%04x points out of stateArray\n", GXV_TRACE(( " newState index 0x%04x points out of stateArray\n",
newState_idx )); newState_idx ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
FT_INVALID_OFFSET;
} }
state = (FT_UShort)( newState_idx / ( 1 + maxClassID ) ); state = (FT_UShort)( newState_idx / ( 1 + maxClassID ) );
@ -1513,8 +1500,7 @@
FT_TRACE4(( "-> new state = %d (supposed)\n" FT_TRACE4(( "-> new state = %d (supposed)\n"
"but newState index 0x%04x is not aligned to %d-classes\n", "but newState index 0x%04x is not aligned to %d-classes\n",
state, newState_idx, 1 + maxClassID )); state, newState_idx, 1 + maxClassID ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
FT_INVALID_OFFSET;
} }
switch ( GXV_GLYPHOFFSET_FMT( xstatetable ) ) switch ( GXV_GLYPHOFFSET_FMT( xstatetable ) )
@ -1548,8 +1534,7 @@
break; break;
default: default:
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT );
FT_INVALID_FORMAT;
goto Exit; goto Exit;
} }

View file

@ -51,6 +51,19 @@
FT_BEGIN_HEADER FT_BEGIN_HEADER
/* some variables are not evaluated or only used in trace */
#ifdef FT_DEBUG_LEVEL_TRACE
#define GXV_LOAD_TRACE_VARS
#else
#undef GXV_LOAD_TRACE_VARS
#endif
#undef GXV_LOAD_UNUSED_VARS /* debug purpose */
#define IS_PARANOID_VALIDATION ( valid->root->level >= FT_VALIDATE_PARANOID )
#define GXV_SET_ERR_IF_PARANOID( err ) { if ( IS_PARANOID_VALIDATION ) ( err ); }
/*************************************************************************/ /*************************************************************************/
/*************************************************************************/ /*************************************************************************/
/***** *****/ /***** *****/
@ -234,6 +247,9 @@ FT_BEGIN_HEADER
GXV_Lookup_Fmt4_Transit_Func lookupfmt4_trans; GXV_Lookup_Fmt4_Transit_Func lookupfmt4_trans;
FT_Bytes lookuptbl_head; FT_Bytes lookuptbl_head;
FT_UShort min_gid;
FT_UShort max_gid;
GXV_StateTable_ValidatorRec statetable; GXV_StateTable_ValidatorRec statetable;
GXV_XStateTable_ValidatorRec xstatetable; GXV_XStateTable_ValidatorRec xstatetable;

View file

@ -92,8 +92,7 @@
{ {
GXV_TRACE(( "feature number %d is out of range %d\n", GXV_TRACE(( "feature number %d is out of range %d\n",
feature, gxv_feat_registry_length )); feature, gxv_feat_registry_length ));
if ( valid->root->level == FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
FT_INVALID_DATA;
goto Exit; goto Exit;
} }
@ -101,8 +100,7 @@
{ {
GXV_TRACE(( "feature number %d is in defined range but doesn't exist\n", GXV_TRACE(( "feature number %d is in defined range but doesn't exist\n",
feature )); feature ));
if ( valid->root->level == FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
FT_INVALID_DATA;
goto Exit; goto Exit;
} }
@ -222,9 +220,8 @@
if ( settingTable < reserved_size ) if ( settingTable < reserved_size )
FT_INVALID_OFFSET; FT_INVALID_OFFSET;
if ( valid->root->level == FT_VALIDATE_PARANOID && if ( ( featureFlags & GXV_FEAT_MASK_UNUSED ) == 0 )
( featureFlags & GXV_FEAT_MASK_UNUSED ) == 0 ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
FT_INVALID_DATA;
exclusive = FT_BOOL( featureFlags & GXV_FEAT_MASK_EXCLUSIVE_SETTINGS ); exclusive = FT_BOOL( featureFlags & GXV_FEAT_MASK_EXCLUSIVE_SETTINGS );
if ( exclusive ) if ( exclusive )
@ -252,9 +249,8 @@
{ {
gxv_feat_setting_validate( p, limit, exclusive, valid ); gxv_feat_setting_validate( p, limit, exclusive, valid );
if ( valid->root->level == FT_VALIDATE_PARANOID && if ( (FT_Int)GXV_FEAT_DATA( setting ) <= last_setting )
(FT_Int)GXV_FEAT_DATA( setting ) <= last_setting ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT );
FT_INVALID_FORMAT;
last_setting = (FT_Int)GXV_FEAT_DATA( setting ); last_setting = (FT_Int)GXV_FEAT_DATA( setting );
/* setting + nameIndex */ /* setting + nameIndex */
@ -312,8 +308,8 @@
featureNameCount = FT_NEXT_USHORT( p ); featureNameCount = FT_NEXT_USHORT( p );
GXV_TRACE(( " (featureNameCount = %d)\n", featureNameCount )); GXV_TRACE(( " (featureNameCount = %d)\n", featureNameCount ));
if ( valid->root->level != FT_VALIDATE_PARANOID ) if ( !( IS_PARANOID_VALIDATION ) )
p += 6; /* skip (none) and (none) */ p += 6; /* skip (none) and (none) */
else else
{ {
if ( FT_NEXT_USHORT( p ) != 0 ) if ( FT_NEXT_USHORT( p ) != 0 )
@ -329,9 +325,8 @@
{ {
gxv_feat_name_validate( p, limit, valid ); gxv_feat_name_validate( p, limit, valid );
if ( valid->root->level == FT_VALIDATE_PARANOID && if ( (FT_Int)GXV_FEAT_DATA( feature ) <= last_feature )
(FT_Int)GXV_FEAT_DATA( feature ) <= last_feature ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT );
FT_INVALID_FORMAT;
last_feature = GXV_FEAT_DATA( feature ); last_feature = GXV_FEAT_DATA( feature );
p += 2 + 2 + 4 + 2 + 2; p += 2 + 2 + 4 + 2 + 2;

View file

@ -65,6 +65,22 @@
#define GXV_JUST_DATA( a ) GXV_TABLE_DATA( just, a ) #define GXV_JUST_DATA( a ) GXV_TABLE_DATA( just, a )
/* GX just table does not define their subset of GID */
static void
gxv_just_check_max_gid( FT_UShort gid,
const FT_String* msg_tag,
GXV_Validator valid )
{
if ( gid < valid->face->num_glyphs )
return;
GXV_TRACE(( "just table includes too large %s"
" GID=%d > %d (in maxp)\n",
msg_tag, gid, valid->face->num_glyphs ));
GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
}
static void static void
gxv_just_wdp_entry_validate( FT_Bytes table, gxv_just_wdp_entry_validate( FT_Bytes table,
FT_Bytes limit, FT_Bytes limit,
@ -72,24 +88,37 @@
{ {
FT_Bytes p = table; FT_Bytes p = table;
FT_ULong justClass; FT_ULong justClass;
#ifdef GXV_LOAD_UNUSED_VARS
FT_Fixed beforeGrowLimit; FT_Fixed beforeGrowLimit;
FT_Fixed beforeShrinkGrowLimit; FT_Fixed beforeShrinkGrowLimit;
FT_Fixed afterGrowLimit; FT_Fixed afterGrowLimit;
FT_Fixed afterShrinkGrowLimit; FT_Fixed afterShrinkGrowLimit;
FT_UShort growFlags; FT_UShort growFlags;
FT_UShort shrinkFlags; FT_UShort shrinkFlags;
#endif
GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 ); GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 );
justClass = FT_NEXT_ULONG( p ); justClass = FT_NEXT_ULONG( p );
#ifndef GXV_LOAD_UNUSED_VARS
p += 4 + 4 + 4 + 4 + 2 + 2;
#else
beforeGrowLimit = FT_NEXT_ULONG( p ); beforeGrowLimit = FT_NEXT_ULONG( p );
beforeShrinkGrowLimit = FT_NEXT_ULONG( p ); beforeShrinkGrowLimit = FT_NEXT_ULONG( p );
afterGrowLimit = FT_NEXT_ULONG( p ); afterGrowLimit = FT_NEXT_ULONG( p );
afterShrinkGrowLimit = FT_NEXT_ULONG( p ); afterShrinkGrowLimit = FT_NEXT_ULONG( p );
growFlags = FT_NEXT_USHORT( p ); growFlags = FT_NEXT_USHORT( p );
shrinkFlags = FT_NEXT_USHORT( p ); shrinkFlags = FT_NEXT_USHORT( p );
#endif
/* TODO: decode flags for human readability */ /* According to Apple spec, only 7bits in justClass is used */
if ( ( justClass & 0xFFFFFF80 ) != 0 )
{
GXV_TRACE(( "just table includes non-zero value"
" in unused justClass higher bits"
" of WidthDeltaPair" ));
GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
}
valid->subtable_length = p - table; valid->subtable_length = p - table;
} }
@ -153,8 +182,9 @@
FT_Fixed lowerLimit; FT_Fixed lowerLimit;
FT_Fixed upperLimit; FT_Fixed upperLimit;
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort order; FT_UShort order;
#endif
FT_UShort decomposedCount; FT_UShort decomposedCount;
FT_UInt i; FT_UInt i;
@ -163,9 +193,20 @@
GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
lowerLimit = FT_NEXT_ULONG( p ); lowerLimit = FT_NEXT_ULONG( p );
upperLimit = FT_NEXT_ULONG( p ); upperLimit = FT_NEXT_ULONG( p );
#ifdef GXV_LOAD_UNUSED_VARS
order = FT_NEXT_USHORT( p ); order = FT_NEXT_USHORT( p );
#else
p += 2;
#endif
decomposedCount = FT_NEXT_USHORT( p ); decomposedCount = FT_NEXT_USHORT( p );
if ( lowerLimit >= upperLimit )
{
GXV_TRACE(( "just table includes invalid range spec:"
" lowerLimit(%d) > upperLimit(%d)\n" ));
GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
}
for ( i = 0; i < decomposedCount; i++ ) for ( i = 0; i < decomposedCount; i++ )
{ {
FT_UShort glyphs; FT_UShort glyphs;
@ -173,6 +214,7 @@
GXV_LIMIT_CHECK( 2 ); GXV_LIMIT_CHECK( 2 );
glyphs = FT_NEXT_USHORT( p ); glyphs = FT_NEXT_USHORT( p );
gxv_just_check_max_gid( glyphs, "type0:glyphs", valid );
} }
valid->subtable_length = p - table; valid->subtable_length = p - table;
@ -191,6 +233,8 @@
GXV_LIMIT_CHECK( 2 ); GXV_LIMIT_CHECK( 2 );
addGlyph = FT_NEXT_USHORT( p ); addGlyph = FT_NEXT_USHORT( p );
gxv_just_check_max_gid( addGlyph, "type1:addGlyph", valid );
valid->subtable_length = p - table; valid->subtable_length = p - table;
} }
@ -201,16 +245,27 @@
GXV_Validator valid ) GXV_Validator valid )
{ {
FT_Bytes p = table; FT_Bytes p = table;
#ifdef GXV_LOAD_UNUSED_VARS
FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */ FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */
#endif
FT_UShort addGlyph; FT_UShort addGlyph;
FT_UShort substGlyph; FT_UShort substGlyph;
GXV_LIMIT_CHECK( 4 + 2 + 2 ); GXV_LIMIT_CHECK( 4 + 2 + 2 );
#ifdef GXV_LOAD_UNUSED_VARS
substThreshhold = FT_NEXT_ULONG( p ); substThreshhold = FT_NEXT_ULONG( p );
#else
p += 4;
#endif
addGlyph = FT_NEXT_USHORT( p ); addGlyph = FT_NEXT_USHORT( p );
substGlyph = FT_NEXT_USHORT( p ); substGlyph = FT_NEXT_USHORT( p );
if ( addGlyph != 0xFFFF )
gxv_just_check_max_gid( addGlyph, "type2:addGlyph", valid );
gxv_just_check_max_gid( substGlyph, "type2:substGlyph", valid );
valid->subtable_length = p - table; valid->subtable_length = p - table;
} }
@ -234,6 +289,21 @@
maximumLimit = FT_NEXT_ULONG( p ); maximumLimit = FT_NEXT_ULONG( p );
valid->subtable_length = p - table; valid->subtable_length = p - table;
if ( variantsAxis != 0x64756374 ) /* 'duct' */
GXV_TRACE(( "variantsAxis 0x%08x is non default value",
variantsAxis ));
if ( minimumLimit > noStretchValue )
GXV_TRACE(( "type4:minimumLimit 0x%08x > noStretchValue 0x%08x\n",
minimumLimit, noStretchValue ));
else if ( noStretchValue > maximumLimit )
GXV_TRACE(( "type4:noStretchValue 0x%08x > maximumLimit 0x%08x\n",
noStretchValue, maximumLimit ));
else if ( !IS_PARANOID_VALIDATION )
return;
FT_INVALID_DATA;
} }
@ -251,6 +321,11 @@
flags = FT_NEXT_USHORT( p ); flags = FT_NEXT_USHORT( p );
glyph = FT_NEXT_USHORT( p ); glyph = FT_NEXT_USHORT( p );
if ( flags )
GXV_TRACE(( "type5: nonzero value 0x%04x in unused flags\n",
flags ));
gxv_just_check_max_gid( glyph, "type5:glyph", valid );
valid->subtable_length = p - table; valid->subtable_length = p - table;
} }
@ -274,6 +349,10 @@
actionType = FT_NEXT_USHORT( p ); actionType = FT_NEXT_USHORT( p );
actionLength = FT_NEXT_ULONG( p ); actionLength = FT_NEXT_ULONG( p );
/* actionClass is related with justClass using 7bit only */
if ( ( actionClass & 0xFF80 ) != 0 )
GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
if ( actionType == 0 ) if ( actionType == 0 )
gxv_just_actSubrecord_type0_validate( p, limit, valid ); gxv_just_actSubrecord_type0_validate( p, limit, valid );
else if ( actionType == 1 ) else if ( actionType == 1 )
@ -389,10 +468,13 @@
FT_Bytes limit, FT_Bytes limit,
GXV_Validator valid ) GXV_Validator valid )
{ {
#ifdef GXV_LOAD_UNUSED_VARS
/* TODO: validate markClass & currentClass */
FT_UShort setMark; FT_UShort setMark;
FT_UShort dontAdvance; FT_UShort dontAdvance;
FT_UShort markClass; FT_UShort markClass;
FT_UShort currentClass; FT_UShort currentClass;
#endif
FT_UNUSED( state ); FT_UNUSED( state );
FT_UNUSED( glyphOffset_p ); FT_UNUSED( glyphOffset_p );
@ -400,13 +482,14 @@
FT_UNUSED( limit ); FT_UNUSED( limit );
FT_UNUSED( valid ); FT_UNUSED( valid );
#ifndef GXV_LOAD_UNUSED_VARS
FT_UNUSED( flags );
#else
setMark = (FT_UShort)( ( flags >> 15 ) & 1 ); setMark = (FT_UShort)( ( flags >> 15 ) & 1 );
dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
markClass = (FT_UShort)( ( flags >> 7 ) & 0x7F ); markClass = (FT_UShort)( ( flags >> 7 ) & 0x7F );
currentClass = (FT_UShort)( flags & 0x7F ); currentClass = (FT_UShort)( flags & 0x7F );
#endif
/* TODO: validate markClass & currentClass */
} }
@ -428,9 +511,15 @@
coverage = FT_NEXT_USHORT( p ); coverage = FT_NEXT_USHORT( p );
subFeatureFlags = FT_NEXT_ULONG( p ); subFeatureFlags = FT_NEXT_ULONG( p );
GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s)", GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s) ", coverage ));
coverage, if ( ( coverage & 0x4000 ) == 0 )
( 0x4000 & coverage ) == 0 ? "ascending" : "descending" )); GXV_TRACE(( "ascending\n" ));
else
GXV_TRACE(( "descending\n" ));
if ( subFeatureFlags )
GXV_TRACE(( " justClassTable: nonzero value (0x%08x)"
" in unused subFeatureFlags\n", subFeatureFlags ));
valid->statetable.optdata = NULL; valid->statetable.optdata = NULL;
valid->statetable.optdata_load_func = NULL; valid->statetable.optdata_load_func = NULL;
@ -557,7 +646,6 @@
{ {
FT_Bytes p = table; FT_Bytes p = table;
FT_Bytes limit = 0; FT_Bytes limit = 0;
FT_Offset table_size;
GXV_ValidatorRec validrec; GXV_ValidatorRec validrec;
GXV_Validator valid = &validrec; GXV_Validator valid = &validrec;
@ -582,7 +670,6 @@
GXV_INIT; GXV_INIT;
limit = valid->root->limit; limit = valid->root->limit;
table_size = limit - table;
GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 ); GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 );
version = FT_NEXT_ULONG( p ); version = FT_NEXT_ULONG( p );

View file

@ -127,7 +127,9 @@
{ {
FT_UShort gid_left; FT_UShort gid_left;
FT_UShort gid_right; FT_UShort gid_right;
#ifdef GXV_LOAD_UNUSED_VARS
FT_Short kernValue; FT_Short kernValue;
#endif
/* left */ /* left */
@ -156,7 +158,11 @@
FT_INVALID_DATA; FT_INVALID_DATA;
/* skip the kern value */ /* skip the kern value */
#ifdef GXV_LOAD_UNUSED_VARS
kernValue = FT_NEXT_SHORT( p ); kernValue = FT_NEXT_SHORT( p );
#else
p += 2;
#endif
} }
GXV_EXIT; GXV_EXIT;
@ -261,18 +267,24 @@
FT_Bytes limit, FT_Bytes limit,
GXV_Validator valid ) GXV_Validator valid )
{ {
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort push; FT_UShort push;
FT_UShort dontAdvance; FT_UShort dontAdvance;
#endif
FT_UShort valueOffset; FT_UShort valueOffset;
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort kernAction; FT_UShort kernAction;
FT_UShort kernValue; FT_UShort kernValue;
#endif
FT_UNUSED( state ); FT_UNUSED( state );
FT_UNUSED( glyphOffset_p ); FT_UNUSED( glyphOffset_p );
#ifdef GXV_LOAD_UNUSED_VARS
push = (FT_UShort)( ( flags >> 15 ) & 1 ); push = (FT_UShort)( ( flags >> 15 ) & 1 );
dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
#endif
valueOffset = (FT_UShort)( flags & 0x3FFF ); valueOffset = (FT_UShort)( flags & 0x3FFF );
{ {
@ -288,8 +300,12 @@
limit = table + vt_rec->valueTable + vt_rec->valueTable_length; limit = table + vt_rec->valueTable + vt_rec->valueTable_length;
GXV_LIMIT_CHECK( 2 + 2 ); GXV_LIMIT_CHECK( 2 + 2 );
#ifdef GXV_LOAD_UNUSED_VARS
kernAction = FT_NEXT_USHORT( p ); kernAction = FT_NEXT_USHORT( p );
kernValue = FT_NEXT_USHORT( p ); kernValue = FT_NEXT_USHORT( p );
#else
p += 4;
#endif
} }
} }
@ -475,10 +491,12 @@
{ {
GXV_TRACE(( "maxGID=%d, but glyphCount=%d\n", GXV_TRACE(( "maxGID=%d, but glyphCount=%d\n",
valid->face->num_glyphs, glyphCount )); valid->face->num_glyphs, glyphCount ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
FT_INVALID_GLYPH_ID;
} }
if ( flags != 0 )
GXV_TRACE(( "kern subtable fmt3 has nonzero value"
" (%d) in unused flag\n", flags ));
/* /*
* just skip kernValue[kernValueCount] * just skip kernValue[kernValueCount]
*/ */
@ -545,20 +563,24 @@
GXV_Validator valid ) GXV_Validator valid )
{ {
/* new Apple-dialect */ /* new Apple-dialect */
#ifdef GXV_LOAD_TRACE_VARS
FT_Bool kernVertical; FT_Bool kernVertical;
FT_Bool kernCrossStream; FT_Bool kernCrossStream;
FT_Bool kernVariation; FT_Bool kernVariation;
#endif
FT_UNUSED( valid ); FT_UNUSED( valid );
/* reserved bits = 0 */ /* reserved bits = 0 */
if ( coverage & 0x1FFC ) if ( coverage & 0x1FFC )
return 0; return FALSE;
#ifdef GXV_LOAD_TRACE_VARS
kernVertical = FT_BOOL( ( coverage >> 15 ) & 1 ); kernVertical = FT_BOOL( ( coverage >> 15 ) & 1 );
kernCrossStream = FT_BOOL( ( coverage >> 14 ) & 1 ); kernCrossStream = FT_BOOL( ( coverage >> 14 ) & 1 );
kernVariation = FT_BOOL( ( coverage >> 13 ) & 1 ); kernVariation = FT_BOOL( ( coverage >> 13 ) & 1 );
#endif
*format = (FT_UShort)( coverage & 0x0003 ); *format = (FT_UShort)( coverage & 0x0003 );
@ -568,7 +590,7 @@
GXV_TRACE(( "kerning values in Apple format subtable are ignored\n" )); GXV_TRACE(( "kerning values in Apple format subtable are ignored\n" ));
return 1; return TRUE;
} }
@ -578,20 +600,24 @@
GXV_Validator valid ) GXV_Validator valid )
{ {
/* classic Apple-dialect */ /* classic Apple-dialect */
#ifdef GXV_LOAD_TRACE_VARS
FT_Bool horizontal; FT_Bool horizontal;
FT_Bool cross_stream; FT_Bool cross_stream;
#endif
/* check expected flags, but don't check if MS-dialect is impossible */ /* check expected flags, but don't check if MS-dialect is impossible */
if ( !( coverage & 0xFD00 ) && KERN_ALLOWS_MS( valid ) ) if ( !( coverage & 0xFD00 ) && KERN_ALLOWS_MS( valid ) )
return 0; return FALSE;
/* reserved bits = 0 */ /* reserved bits = 0 */
if ( coverage & 0x02FC ) if ( coverage & 0x02FC )
return 0; return FALSE;
#ifdef GXV_LOAD_TRACE_VARS
horizontal = FT_BOOL( ( coverage >> 15 ) & 1 ); horizontal = FT_BOOL( ( coverage >> 15 ) & 1 );
cross_stream = FT_BOOL( ( coverage >> 13 ) & 1 ); cross_stream = FT_BOOL( ( coverage >> 13 ) & 1 );
#endif
*format = (FT_UShort)( coverage & 0x0003 ); *format = (FT_UShort)( coverage & 0x0003 );
@ -601,11 +627,11 @@
/* format 1 requires GX State Machine, too new for classic */ /* format 1 requires GX State Machine, too new for classic */
if ( *format == 1 ) if ( *format == 1 )
return 0; return FALSE;
GXV_TRACE(( "kerning values in Apple format subtable are ignored\n" )); GXV_TRACE(( "kerning values in Apple format subtable are ignored\n" ));
return 1; return TRUE;
} }
@ -615,22 +641,26 @@
GXV_Validator valid ) GXV_Validator valid )
{ {
/* classic Microsoft-dialect */ /* classic Microsoft-dialect */
#ifdef GXV_LOAD_TRACE_VARS
FT_Bool horizontal; FT_Bool horizontal;
FT_Bool minimum; FT_Bool minimum;
FT_Bool cross_stream; FT_Bool cross_stream;
FT_Bool override; FT_Bool override;
#endif
FT_UNUSED( valid ); FT_UNUSED( valid );
/* reserved bits = 0 */ /* reserved bits = 0 */
if ( coverage & 0xFDF0 ) if ( coverage & 0xFDF0 )
return 0; return FALSE;
#ifdef GXV_LOAD_TRACE_VARS
horizontal = FT_BOOL( coverage & 1 ); horizontal = FT_BOOL( coverage & 1 );
minimum = FT_BOOL( ( coverage >> 1 ) & 1 ); minimum = FT_BOOL( ( coverage >> 1 ) & 1 );
cross_stream = FT_BOOL( ( coverage >> 2 ) & 1 ); cross_stream = FT_BOOL( ( coverage >> 2 ) & 1 );
override = FT_BOOL( ( coverage >> 3 ) & 1 ); override = FT_BOOL( ( coverage >> 3 ) & 1 );
#endif
*format = (FT_UShort)( ( coverage >> 8 ) & 0x0003 ); *format = (FT_UShort)( ( coverage >> 8 ) & 0x0003 );
@ -643,7 +673,7 @@
GXV_TRACE(( GXV_TRACE((
"kerning values in Microsoft format 2 subtable are ignored\n" )); "kerning values in Microsoft format 2 subtable are ignored\n" ));
return 1; return TRUE;
} }
@ -714,10 +744,14 @@
GXV_Validator valid ) GXV_Validator valid )
{ {
FT_Bytes p = table; FT_Bytes p = table;
#ifdef GXV_LOAD_TRACE_VARS
FT_UShort version = 0; /* MS only: subtable version, unused */ FT_UShort version = 0; /* MS only: subtable version, unused */
#endif
FT_ULong length; /* MS: 16bit, Apple: 32bit*/ FT_ULong length; /* MS: 16bit, Apple: 32bit*/
FT_UShort coverage; FT_UShort coverage;
#ifdef GXV_LOAD_TRACE_VARS
FT_UShort tupleIndex = 0; /* Apple only */ FT_UShort tupleIndex = 0; /* Apple only */
#endif
FT_UShort u16[2]; FT_UShort u16[2];
FT_UShort format = 255; /* subtable format */ FT_UShort format = 255; /* subtable format */
@ -732,23 +766,35 @@
switch ( gxv_kern_coverage_validate( coverage, &format, valid ) ) switch ( gxv_kern_coverage_validate( coverage, &format, valid ) )
{ {
case KERN_DIALECT_MS: case KERN_DIALECT_MS:
#ifdef GXV_LOAD_TRACE_VARS
version = u16[0]; version = u16[0];
#endif
length = u16[1]; length = u16[1];
#ifdef GXV_LOAD_TRACE_VARS
tupleIndex = 0; tupleIndex = 0;
#endif
GXV_TRACE(( "Subtable version = %d\n", version )); GXV_TRACE(( "Subtable version = %d\n", version ));
GXV_TRACE(( "Subtable length = %d\n", length )); GXV_TRACE(( "Subtable length = %d\n", length ));
break; break;
case KERN_DIALECT_APPLE: case KERN_DIALECT_APPLE:
#ifdef GXV_LOAD_TRACE_VARS
version = 0; version = 0;
#endif
length = ( u16[0] << 16 ) + u16[1]; length = ( u16[0] << 16 ) + u16[1];
#ifdef GXV_LOAD_TRACE_VARS
tupleIndex = 0; tupleIndex = 0;
#endif
GXV_TRACE(( "Subtable length = %d\n", length )); GXV_TRACE(( "Subtable length = %d\n", length ));
if ( KERN_IS_NEW( valid ) ) if ( KERN_IS_NEW( valid ) )
{ {
GXV_LIMIT_CHECK( 2 ); GXV_LIMIT_CHECK( 2 );
#ifdef GXV_LOAD_TRACE_VARS
tupleIndex = FT_NEXT_USHORT( p ); tupleIndex = FT_NEXT_USHORT( p );
#else
p += 2;
#endif
GXV_TRACE(( "Subtable tupleIndex = %d\n", tupleIndex )); GXV_TRACE(( "Subtable tupleIndex = %d\n", tupleIndex ));
} }
break; break;

View file

@ -47,16 +47,14 @@
GXV_TRACE(( "featureType %d is out of registered range, " GXV_TRACE(( "featureType %d is out of registered range, "
"setting %d is unchecked\n", "setting %d is unchecked\n",
f->featureType, f->featureSetting )); f->featureType, f->featureSetting ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
FT_INVALID_DATA;
} }
else if ( !gxv_feat_registry[f->featureType].existence ) else if ( !gxv_feat_registry[f->featureType].existence )
{ {
GXV_TRACE(( "featureType %d is within registered area " GXV_TRACE(( "featureType %d is within registered area "
"but undefined, setting %d is unchecked\n", "but undefined, setting %d is unchecked\n",
f->featureType, f->featureSetting )); f->featureType, f->featureSetting ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
FT_INVALID_DATA;
} }
else else
{ {
@ -74,8 +72,7 @@
if ( f->featureSetting > nSettings_max ) if ( f->featureSetting > nSettings_max )
{ {
GXV_TRACE(( "out of defined range %d", nSettings_max )); GXV_TRACE(( "out of defined range %d", nSettings_max ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
FT_INVALID_DATA;
} }
GXV_TRACE(( "\n" )); GXV_TRACE(( "\n" ));
} }
@ -176,7 +173,9 @@
{ {
FT_UShort length; FT_UShort length;
FT_UShort coverage; FT_UShort coverage;
#ifdef GXV_LOAD_UNUSED_VARS
FT_ULong subFeatureFlags; FT_ULong subFeatureFlags;
#endif
FT_UInt type; FT_UInt type;
FT_UInt rest; FT_UInt rest;
@ -184,7 +183,11 @@
GXV_LIMIT_CHECK( 2 + 2 + 4 ); GXV_LIMIT_CHECK( 2 + 2 + 4 );
length = FT_NEXT_USHORT( p ); length = FT_NEXT_USHORT( p );
coverage = FT_NEXT_USHORT( p ); coverage = FT_NEXT_USHORT( p );
#ifdef GXV_LOAD_UNUSED_VARS
subFeatureFlags = FT_NEXT_ULONG( p ); subFeatureFlags = FT_NEXT_ULONG( p );
#else
p += 4;
#endif
GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n", GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n",
i + 1, nSubtables, length )); i + 1, nSubtables, length ));
@ -204,6 +207,7 @@
func( p, p + rest, valid ); func( p, p + rest, valid );
p += rest; p += rest;
/* TODO: validate subFeatureFlags */
} }
valid->subtable_length = p - table; valid->subtable_length = p - table;
@ -218,7 +222,9 @@
GXV_Validator valid ) GXV_Validator valid )
{ {
FT_Bytes p = table; FT_Bytes p = table;
#ifdef GXV_LOAD_UNUSED_VARS
FT_ULong defaultFlags; FT_ULong defaultFlags;
#endif
FT_ULong chainLength; FT_ULong chainLength;
FT_UShort nFeatureFlags; FT_UShort nFeatureFlags;
FT_UShort nSubtables; FT_UShort nSubtables;
@ -227,7 +233,11 @@
GXV_NAME_ENTER( "mort chain header" ); GXV_NAME_ENTER( "mort chain header" );
GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
#ifdef GXV_LOAD_UNUSED_VARS
defaultFlags = FT_NEXT_ULONG( p ); defaultFlags = FT_NEXT_ULONG( p );
#else
p += 4;
#endif
chainLength = FT_NEXT_ULONG( p ); chainLength = FT_NEXT_ULONG( p );
nFeatureFlags = FT_NEXT_USHORT( p ); nFeatureFlags = FT_NEXT_USHORT( p );
nSubtables = FT_NEXT_USHORT( p ); nSubtables = FT_NEXT_USHORT( p );
@ -238,6 +248,7 @@
gxv_mort_subtables_validate( p, table + chainLength, nSubtables, valid ); gxv_mort_subtables_validate( p, table + chainLength, nSubtables, valid );
valid->subtable_length = chainLength; valid->subtable_length = chainLength;
/* TODO: validate defaultFlags */
GXV_EXIT; GXV_EXIT;
} }

View file

@ -98,10 +98,24 @@
GXV_TRACE(( " %02d", verb )); GXV_TRACE(( " %02d", verb ));
GXV_TRACE(( " %s\n", GXV_Mort_IndicScript_Msg[verb] )); GXV_TRACE(( " %s\n", GXV_Mort_IndicScript_Msg[verb] ));
if ( markFirst > 0 && markLast > 0 )
{
GXV_TRACE(( " [odd] a glyph is marked as the first and last"
" in Indic rearrangement\n" ));
GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
}
if ( markFirst > 0 && dontAdvance > 0 )
{
GXV_TRACE(( " [odd] the first glyph is marked as dontAdvance"
" in Indic rearrangement\n" ));
GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
}
if ( 0 < reserved ) if ( 0 < reserved )
{ {
GXV_TRACE(( " non-zero bits found in reserved range\n" )); GXV_TRACE(( " non-zero bits found in reserved range\n" ));
FT_INVALID_DATA; GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
} }
else else
GXV_TRACE(( "\n" )); GXV_TRACE(( "\n" ));

View file

@ -106,8 +106,6 @@
{ {
FT_UShort substTable; FT_UShort substTable;
FT_UShort substTable_limit; FT_UShort substTable_limit;
FT_UShort min_gid;
FT_UShort max_gid;
FT_UNUSED( tag ); FT_UNUSED( tag );
FT_UNUSED( state ); FT_UNUSED( state );
@ -121,9 +119,10 @@
((GXV_mort_subtable_type1_StateOptRec *) ((GXV_mort_subtable_type1_StateOptRec *)
(valid->statetable.optdata))->substitutionTable_length ); (valid->statetable.optdata))->substitutionTable_length );
min_gid = (FT_UShort)( ( substTable - wordOffset * 2 ) / 2 ); valid->min_gid = (FT_UShort)( ( substTable - wordOffset * 2 ) / 2 );
max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 ); valid->max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 );
max_gid = (FT_UShort)( FT_MAX( max_gid, valid->face->num_glyphs ) ); valid->max_gid = (FT_UShort)( FT_MAX( valid->max_gid,
valid->face->num_glyphs ) );
/* XXX: check range? */ /* XXX: check range? */
@ -140,8 +139,10 @@
FT_Bytes limit, FT_Bytes limit,
GXV_Validator valid ) GXV_Validator valid )
{ {
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort setMark; FT_UShort setMark;
FT_UShort dontAdvance; FT_UShort dontAdvance;
#endif
FT_UShort reserved; FT_UShort reserved;
FT_Short markOffset; FT_Short markOffset;
FT_Short currentOffset; FT_Short currentOffset;
@ -150,8 +151,10 @@
FT_UNUSED( limit ); FT_UNUSED( limit );
#ifdef GXV_LOAD_UNUSED_VARS
setMark = (FT_UShort)( flags >> 15 ); setMark = (FT_UShort)( flags >> 15 );
dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
#endif
reserved = (FT_Short)( flags & 0x3FFF ); reserved = (FT_Short)( flags & 0x3FFF );
markOffset = (FT_Short)( glyphOffset_p->ul >> 16 ); markOffset = (FT_Short)( glyphOffset_p->ul >> 16 );
@ -160,8 +163,7 @@
if ( 0 < reserved ) if ( 0 < reserved )
{ {
GXV_TRACE(( " non-zero bits found in reserved range\n" )); GXV_TRACE(( " non-zero bits found in reserved range\n" ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
FT_INVALID_DATA;
} }
gxv_mort_subtable_type1_offset_to_subst_validate( markOffset, gxv_mort_subtable_type1_offset_to_subst_validate( markOffset,
@ -200,13 +202,12 @@
if ( dst_gid >= 0xFFFFU ) if ( dst_gid >= 0xFFFFU )
continue; continue;
if ( dst_gid > valid->face->num_glyphs ) if ( dst_gid < valid->min_gid || valid->max_gid < dst_gid )
{ {
GXV_TRACE(( "substTable include too large gid[%d]=%d >" GXV_TRACE(( "substTable include a strange gid[%d]=%d >"
" max defined gid #%d\n", " out of define range (%d..%d)\n",
i, dst_gid, valid->face->num_glyphs )); i, dst_gid, valid->min_gid, valid->max_gid ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
FT_INVALID_GLYPH_ID;
} }
} }

View file

@ -155,8 +155,7 @@
ligActionOffset, lat_base - p )); ligActionOffset, lat_base - p ));
/* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */ /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
FT_INVALID_OFFSET;
} }
else if ( lat_limit < p ) else if ( lat_limit < p )
{ {
@ -164,23 +163,46 @@
ligActionOffset, p - lat_limit )); ligActionOffset, p - lat_limit ));
/* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */ /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
FT_INVALID_OFFSET;
} }
else else
{ {
/* validate entry in ligActionTable */ /* validate entry in ligActionTable */
FT_ULong lig_action; FT_ULong lig_action;
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort last; FT_UShort last;
FT_UShort store; FT_UShort store;
#endif
FT_ULong offset; FT_ULong offset;
lig_action = FT_NEXT_ULONG( p ); lig_action = FT_NEXT_ULONG( p );
#ifdef GXV_LOAD_UNUSED_VARS
last = (FT_UShort)( ( lig_action >> 31 ) & 1 ); last = (FT_UShort)( ( lig_action >> 31 ) & 1 );
store = (FT_UShort)( ( lig_action >> 30 ) & 1 ); store = (FT_UShort)( ( lig_action >> 30 ) & 1 );
#endif
/* Apple spec defines this offset as a word offset */
offset = lig_action & 0x3FFFFFFFUL; offset = lig_action & 0x3FFFFFFFUL;
if ( offset * 2 < optdata->ligatureTable )
{
GXV_TRACE(( "too short offset 0x%08x:"
" 2 x offset < ligatureTable (%d byte rewind)\n",
offset, optdata->ligatureTable - offset * 2 ));
GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
} else if ( offset * 2 >
optdata->ligatureTable + optdata->ligatureTable_length )
{
GXV_TRACE(( "too long offset 0x%08x:"
" 2 x offset > ligatureTable + ligatureTable_length"
" (%d byte overrun)\n",
offset,
optdata->ligatureTable + optdata->ligatureTable_length
- offset * 2 ));
GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
}
} }
} }
@ -194,8 +216,10 @@
FT_Bytes limit, FT_Bytes limit,
GXV_Validator valid ) GXV_Validator valid )
{ {
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort setComponent; FT_UShort setComponent;
FT_UShort dontAdvance; FT_UShort dontAdvance;
#endif
FT_UShort offset; FT_UShort offset;
FT_UNUSED( state ); FT_UNUSED( state );
@ -203,8 +227,10 @@
FT_UNUSED( limit ); FT_UNUSED( limit );
#ifdef GXV_LOAD_UNUSED_VARS
setComponent = (FT_UShort)( ( flags >> 15 ) & 1 ); setComponent = (FT_UShort)( ( flags >> 15 ) & 1 );
dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
#endif
offset = (FT_UShort)( flags & 0x3FFFU ); offset = (FT_UShort)( flags & 0x3FFFU );
@ -237,6 +263,9 @@
GXV_LIMIT_CHECK( 2 ); GXV_LIMIT_CHECK( 2 );
lig_gid = FT_NEXT_USHORT( p ); lig_gid = FT_NEXT_USHORT( p );
if ( valid->face->num_glyphs < lig_gid )
GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
} }
} }
GXV_EXIT; GXV_EXIT;

View file

@ -121,6 +121,9 @@
offset < optdata->entryTable + *(optdata->entryTable_length_p) ) offset < optdata->entryTable + *(optdata->entryTable_length_p) )
GXV_TRACE(( " offset runs into EntryTable" )); GXV_TRACE(( " offset runs into EntryTable" ));
#ifndef GXV_LOAD_TRACE_VARS
GXV_LIMIT_CHECK( count * 2 );
#else
while ( p < table + offset + ( count * 2 ) ) while ( p < table + offset + ( count * 2 ) )
{ {
FT_UShort insert_glyphID; FT_UShort insert_glyphID;
@ -130,8 +133,8 @@
insert_glyphID = FT_NEXT_USHORT( p ); insert_glyphID = FT_NEXT_USHORT( p );
GXV_TRACE(( " 0x%04x", insert_glyphID )); GXV_TRACE(( " 0x%04x", insert_glyphID ));
} }
GXV_TRACE(( "\n" )); GXV_TRACE(( "\n" ));
#endif
} }
@ -144,12 +147,14 @@
FT_Bytes limit, FT_Bytes limit,
GXV_Validator valid ) GXV_Validator valid )
{ {
#ifdef GXV_LOAD_UNUSED_VARS
FT_Bool setMark; FT_Bool setMark;
FT_Bool dontAdvance; FT_Bool dontAdvance;
FT_Bool currentIsKashidaLike; FT_Bool currentIsKashidaLike;
FT_Bool markedIsKashidaLike; FT_Bool markedIsKashidaLike;
FT_Bool currentInsertBefore; FT_Bool currentInsertBefore;
FT_Bool markedInsertBefore; FT_Bool markedInsertBefore;
#endif
FT_Byte currentInsertCount; FT_Byte currentInsertCount;
FT_Byte markedInsertCount; FT_Byte markedInsertCount;
FT_UShort currentInsertList; FT_UShort currentInsertList;
@ -158,12 +163,14 @@
FT_UNUSED( state ); FT_UNUSED( state );
#ifdef GXV_LOAD_UNUSED_VARS
setMark = FT_BOOL( ( flags >> 15 ) & 1 ); setMark = FT_BOOL( ( flags >> 15 ) & 1 );
dontAdvance = FT_BOOL( ( flags >> 14 ) & 1 ); dontAdvance = FT_BOOL( ( flags >> 14 ) & 1 );
currentIsKashidaLike = FT_BOOL( ( flags >> 13 ) & 1 ); currentIsKashidaLike = FT_BOOL( ( flags >> 13 ) & 1 );
markedIsKashidaLike = FT_BOOL( ( flags >> 12 ) & 1 ); markedIsKashidaLike = FT_BOOL( ( flags >> 12 ) & 1 );
currentInsertBefore = FT_BOOL( ( flags >> 11 ) & 1 ); currentInsertBefore = FT_BOOL( ( flags >> 11 ) & 1 );
markedInsertBefore = FT_BOOL( ( flags >> 10 ) & 1 ); markedInsertBefore = FT_BOOL( ( flags >> 10 ) & 1 );
#endif
currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F ); currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F );
markedInsertCount = (FT_Byte)( flags & 0x001F ); markedInsertCount = (FT_Byte)( flags & 0x001F );

View file

@ -68,7 +68,9 @@
{ {
FT_ULong length; FT_ULong length;
FT_ULong coverage; FT_ULong coverage;
#ifdef GXV_LOAD_UNUSED_VARS
FT_ULong subFeatureFlags; FT_ULong subFeatureFlags;
#endif
FT_ULong type; FT_ULong type;
FT_ULong rest; FT_ULong rest;
@ -76,7 +78,11 @@
GXV_LIMIT_CHECK( 4 + 4 + 4 ); GXV_LIMIT_CHECK( 4 + 4 + 4 );
length = FT_NEXT_ULONG( p ); length = FT_NEXT_ULONG( p );
coverage = FT_NEXT_ULONG( p ); coverage = FT_NEXT_ULONG( p );
#ifdef GXV_LOAD_UNUSED_VARS
subFeatureFlags = FT_NEXT_ULONG( p ); subFeatureFlags = FT_NEXT_ULONG( p );
#else
p += 4;
#endif
GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n", GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n",
i + 1, nSubtables, length )); i + 1, nSubtables, length ));
@ -97,6 +103,7 @@
func( p, p + rest, valid ); func( p, p + rest, valid );
/* TODO: subFeatureFlags should be unique in a table? */
p += rest; p += rest;
} }
@ -112,7 +119,9 @@
GXV_Validator valid ) GXV_Validator valid )
{ {
FT_Bytes p = table; FT_Bytes p = table;
#ifdef GXV_LOAD_UNUSED_VARS
FT_ULong defaultFlags; FT_ULong defaultFlags;
#endif
FT_ULong chainLength; FT_ULong chainLength;
FT_ULong nFeatureFlags; FT_ULong nFeatureFlags;
FT_ULong nSubtables; FT_ULong nSubtables;
@ -121,7 +130,11 @@
GXV_NAME_ENTER( "morx chain header" ); GXV_NAME_ENTER( "morx chain header" );
GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 );
#ifdef GXV_LOAD_UNUSED_VARS
defaultFlags = FT_NEXT_ULONG( p ); defaultFlags = FT_NEXT_ULONG( p );
#else
p += 4;
#endif
chainLength = FT_NEXT_ULONG( p ); chainLength = FT_NEXT_ULONG( p );
nFeatureFlags = FT_NEXT_ULONG( p ); nFeatureFlags = FT_NEXT_ULONG( p );
nSubtables = FT_NEXT_ULONG( p ); nSubtables = FT_NEXT_ULONG( p );
@ -138,6 +151,8 @@
valid->subtable_length = chainLength; valid->subtable_length = chainLength;
/* TODO: defaultFlags should be compared with the flags in tables */
GXV_EXIT; GXV_EXIT;
} }

View file

@ -47,11 +47,15 @@
FT_Bytes limit, FT_Bytes limit,
GXV_Validator valid ) GXV_Validator valid )
{ {
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort markFirst; FT_UShort markFirst;
FT_UShort dontAdvance; FT_UShort dontAdvance;
FT_UShort markLast; FT_UShort markLast;
#endif
FT_UShort reserved; FT_UShort reserved;
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort verb; FT_UShort verb;
#endif
FT_UNUSED( state ); FT_UNUSED( state );
FT_UNUSED( glyphOffset_p ); FT_UNUSED( glyphOffset_p );
@ -59,12 +63,16 @@
FT_UNUSED( limit ); FT_UNUSED( limit );
#ifdef GXV_LOAD_UNUSED_VARS
markFirst = (FT_UShort)( ( flags >> 15 ) & 1 ); markFirst = (FT_UShort)( ( flags >> 15 ) & 1 );
dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
markLast = (FT_UShort)( ( flags >> 13 ) & 1 ); markLast = (FT_UShort)( ( flags >> 13 ) & 1 );
#endif
reserved = (FT_UShort)( flags & 0x1FF0 ); reserved = (FT_UShort)( flags & 0x1FF0 );
#ifdef GXV_LOAD_UNUSED_VARS
verb = (FT_UShort)( flags & 0x000F ); verb = (FT_UShort)( flags & 0x000F );
#endif
if ( 0 < reserved ) if ( 0 < reserved )
{ {

View file

@ -108,8 +108,10 @@
FT_Bytes limit, FT_Bytes limit,
GXV_Validator valid ) GXV_Validator valid )
{ {
#ifdef GXV_LOAD_TRACE_VARS
FT_UShort setMark; FT_UShort setMark;
FT_UShort dontAdvance; FT_UShort dontAdvance;
#endif
FT_UShort reserved; FT_UShort reserved;
FT_Short markIndex; FT_Short markIndex;
FT_Short currentIndex; FT_Short currentIndex;
@ -122,8 +124,10 @@
FT_UNUSED( limit ); FT_UNUSED( limit );
#ifdef GXV_LOAD_TRACE_VARS
setMark = (FT_UShort)( ( flags >> 15 ) & 1 ); setMark = (FT_UShort)( ( flags >> 15 ) & 1 );
dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
#endif
reserved = (FT_UShort)( flags & 0x3FFF ); reserved = (FT_UShort)( flags & 0x3FFF );
@ -136,8 +140,7 @@
if ( 0 < reserved ) if ( 0 < reserved )
{ {
GXV_TRACE(( " non-zero bits found in reserved range\n" )); GXV_TRACE(( " non-zero bits found in reserved range\n" ));
if ( valid->root->level >= FT_VALIDATE_PARANOID ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
FT_INVALID_DATA;
} }
GXV_TRACE(( "markIndex = %d, currentIndex = %d\n", GXV_TRACE(( "markIndex = %d, currentIndex = %d\n",

View file

@ -168,16 +168,50 @@
{ {
/* validate entry in ligActionTable */ /* validate entry in ligActionTable */
FT_ULong lig_action; FT_ULong lig_action;
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort last; FT_UShort last;
FT_UShort store; FT_UShort store;
#endif
FT_ULong offset; FT_ULong offset;
lig_action = FT_NEXT_ULONG( p ); lig_action = FT_NEXT_ULONG( p );
#ifdef GXV_LOAD_UNUSED_VARS
last = (FT_UShort)( ( lig_action >> 31 ) & 1 ); last = (FT_UShort)( ( lig_action >> 31 ) & 1 );
store = (FT_UShort)( ( lig_action >> 30 ) & 1 ); store = (FT_UShort)( ( lig_action >> 30 ) & 1 );
#endif
offset = lig_action & 0x3FFFFFFFUL; offset = lig_action & 0x3FFFFFFFUL;
/* this offset is 30-bit signed value to add to GID */
/* it is different from the location offset in mort */
if ( ( offset & 0x3FFF0000UL ) == 0x3FFF0000UL )
{
if ( offset + valid->face->num_glyphs > 0x40000000UL )
return;
GXV_TRACE(( "ligature action table includes"
" too negative offset moving all GID"
" below defined range: 0x%04x\n",
offset & 0xFFFFU ));
GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
}
else if ( ( offset & 0x3FFF0000UL ) == 0x0000000UL )
{
if ( offset + valid->face->num_glyphs < 0 )
return;
GXV_TRACE(( "ligature action table includes"
" too large offset moving all GID"
" over defined range: 0x%04x\n",
offset & 0xFFFFU ));
GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
}
GXV_TRACE(( "ligature action table includes"
" invalid offset to add to 16-bit GID:"
" 0x%08x\n", offset ));
GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
} }
} }
@ -191,9 +225,11 @@
FT_Bytes limit, FT_Bytes limit,
GXV_Validator valid ) GXV_Validator valid )
{ {
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort setComponent; FT_UShort setComponent;
FT_UShort dontAdvance; FT_UShort dontAdvance;
FT_UShort performAction; FT_UShort performAction;
#endif
FT_UShort reserved; FT_UShort reserved;
FT_UShort ligActionIndex; FT_UShort ligActionIndex;
@ -201,9 +237,11 @@
FT_UNUSED( limit ); FT_UNUSED( limit );
#ifdef GXV_LOAD_UNUSED_VARS
setComponent = (FT_UShort)( ( flags >> 15 ) & 1 ); setComponent = (FT_UShort)( ( flags >> 15 ) & 1 );
dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
performAction = (FT_UShort)( ( flags >> 13 ) & 1 ); performAction = (FT_UShort)( ( flags >> 13 ) & 1 );
#endif
reserved = (FT_UShort)( flags & 0x1FFF ); reserved = (FT_UShort)( flags & 0x1FFF );
ligActionIndex = glyphOffset_p->u; ligActionIndex = glyphOffset_p->u;
@ -241,6 +279,8 @@
GXV_LIMIT_CHECK( 2 ); GXV_LIMIT_CHECK( 2 );
lig_gid = FT_NEXT_USHORT( p ); lig_gid = FT_NEXT_USHORT( p );
if ( lig_gid < valid->face->num_glyphs )
GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
} }
} }

View file

@ -118,6 +118,9 @@
FT_Bytes p = table + table_index * 2; FT_Bytes p = table + table_index * 2;
#ifndef GXV_LOAD_TRACE_VARS
GXV_LIMIT_CHECK( count * 2 );
#else
while ( p < table + count * 2 + table_index * 2 ) while ( p < table + count * 2 + table_index * 2 )
{ {
FT_UShort insert_glyphID; FT_UShort insert_glyphID;
@ -129,6 +132,7 @@
} }
GXV_TRACE(( "\n" )); GXV_TRACE(( "\n" ));
#endif
} }
@ -141,12 +145,14 @@
FT_Bytes limit, FT_Bytes limit,
GXV_Validator valid ) GXV_Validator valid )
{ {
#ifdef GXV_LOAD_UNUSED_VARS
FT_Bool setMark; FT_Bool setMark;
FT_Bool dontAdvance; FT_Bool dontAdvance;
FT_Bool currentIsKashidaLike; FT_Bool currentIsKashidaLike;
FT_Bool markedIsKashidaLike; FT_Bool markedIsKashidaLike;
FT_Bool currentInsertBefore; FT_Bool currentInsertBefore;
FT_Bool markedInsertBefore; FT_Bool markedInsertBefore;
#endif
FT_Byte currentInsertCount; FT_Byte currentInsertCount;
FT_Byte markedInsertCount; FT_Byte markedInsertCount;
FT_Byte currentInsertList; FT_Byte currentInsertList;
@ -155,12 +161,14 @@
FT_UNUSED( state ); FT_UNUSED( state );
#ifdef GXV_LOAD_UNUSED_VARS
setMark = FT_BOOL( ( flags >> 15 ) & 1 ); setMark = FT_BOOL( ( flags >> 15 ) & 1 );
dontAdvance = FT_BOOL( ( flags >> 14 ) & 1 ); dontAdvance = FT_BOOL( ( flags >> 14 ) & 1 );
currentIsKashidaLike = FT_BOOL( ( flags >> 13 ) & 1 ); currentIsKashidaLike = FT_BOOL( ( flags >> 13 ) & 1 );
markedIsKashidaLike = FT_BOOL( ( flags >> 12 ) & 1 ); markedIsKashidaLike = FT_BOOL( ( flags >> 12 ) & 1 );
currentInsertBefore = FT_BOOL( ( flags >> 11 ) & 1 ); currentInsertBefore = FT_BOOL( ( flags >> 11 ) & 1 );
markedInsertBefore = FT_BOOL( ( flags >> 10 ) & 1 ); markedInsertBefore = FT_BOOL( ( flags >> 10 ) & 1 );
#endif
currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F ); currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F );
markedInsertCount = (FT_Byte)( flags & 0x001F ); markedInsertCount = (FT_Byte)( flags & 0x001F );

View file

@ -96,7 +96,10 @@
if ( glyph->advance.x != (FT_Pos)0 || if ( glyph->advance.x != (FT_Pos)0 ||
glyph->advance.y != (FT_Pos)0 ) glyph->advance.y != (FT_Pos)0 )
{
GXV_TRACE(( " found non-zero advance in zero-advance glyph\n" ));
FT_INVALID_DATA; FT_INVALID_DATA;
}
GXV_EXIT; GXV_EXIT;
} }
@ -119,7 +122,10 @@
offset = (FT_UShort)( property & GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET ); offset = (FT_UShort)( property & GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET );
if ( offset == 0 ) if ( offset == 0 )
FT_INVALID_DATA; {
GXV_TRACE(( " found zero offset to property\n" ));
FT_INVALID_OFFSET;
}
complement = (char)( offset >> 8 ); complement = (char)( offset >> 8 );
if ( complement & 0x08 ) if ( complement & 0x08 )
@ -131,7 +137,10 @@
/* The gid for complement must be greater than 0 */ /* The gid for complement must be greater than 0 */
if ( glyph <= complement ) if ( glyph <= complement )
{
GXV_TRACE(( " found non-positive glyph complement\n" ));
FT_INVALID_DATA; FT_INVALID_DATA;
}
} }
else else
{ {
@ -150,18 +159,27 @@
if ( property & GXV_PROP_ATTACHING_TO_RIGHT ) if ( property & GXV_PROP_ATTACHING_TO_RIGHT )
{ {
if ( GXV_PROP_DATA( version ) == 0x00010000UL ) if ( GXV_PROP_DATA( version ) == 0x00010000UL )
{
GXV_TRACE(( " found older version (1.0) in new version table\n" ));
FT_INVALID_DATA; FT_INVALID_DATA;
}
} }
if ( property & GXV_PROP_RESERVED ) if ( property & GXV_PROP_RESERVED )
{
GXV_TRACE(( " found non-zero bits in reserved bits\n" ));
FT_INVALID_DATA; FT_INVALID_DATA;
}
if ( ( property & GXV_PROP_DIRECTIONALITY_CLASS ) > 11 ) if ( ( property & GXV_PROP_DIRECTIONALITY_CLASS ) > 11 )
{ {
/* TODO: Too restricted. Use the validation level. */ /* TODO: Too restricted. Use the validation level. */
if ( GXV_PROP_DATA( version ) == 0x00010000UL || if ( GXV_PROP_DATA( version ) == 0x00010000UL ||
GXV_PROP_DATA( version ) == 0x00020000UL ) GXV_PROP_DATA( version ) == 0x00020000UL )
{
GXV_TRACE(( " found too old version in directionality class\n" ));
FT_INVALID_DATA; FT_INVALID_DATA;
}
} }
} }
@ -264,16 +282,26 @@
format = FT_NEXT_USHORT( p ); format = FT_NEXT_USHORT( p );
defaultProp = FT_NEXT_USHORT( p ); defaultProp = FT_NEXT_USHORT( p );
GXV_TRACE(( " version 0x%08x\n", version ));
GXV_TRACE(( " format 0x%04x\n", format ));
GXV_TRACE(( " defaultProp 0x%04x\n", defaultProp ));
/* only versions 1.0, 2.0, 3.0 are defined (1996) */ /* only versions 1.0, 2.0, 3.0 are defined (1996) */
if ( version != 0x00010000UL && if ( version != 0x00010000UL &&
version != 0x00020000UL && version != 0x00020000UL &&
version != 0x00030000UL ) version != 0x00030000UL )
{
GXV_TRACE(( " found unknown version\n" ));
FT_INVALID_FORMAT; FT_INVALID_FORMAT;
}
/* only formats 0x0000, 0x0001 are defined (1996) */ /* only formats 0x0000, 0x0001 are defined (1996) */
if ( format > 1 ) if ( format > 1 )
{
GXV_TRACE(( " found unknown format\n" ));
FT_INVALID_FORMAT; FT_INVALID_FORMAT;
}
gxv_prop_property_validate( defaultProp, 0, valid ); gxv_prop_property_validate( defaultProp, 0, valid );

View file

@ -97,10 +97,10 @@
{ {
FT_Bytes p = table; FT_Bytes p = table;
FT_Fixed track; FT_Fixed track, t;
FT_UShort nameIndex; FT_UShort nameIndex;
FT_UShort offset; FT_UShort offset;
FT_UShort i; FT_UShort i, j;
GXV_NAME_ENTER( "trackTable" ); GXV_NAME_ENTER( "trackTable" );
@ -108,9 +108,11 @@
GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU; GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU;
GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000; GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000;
GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) );
for ( i = 0; i < nTracks; i ++ ) for ( i = 0; i < nTracks; i ++ )
{ {
GXV_LIMIT_CHECK( 4 + 2 + 2 ); p = table + i * ( 4 + 2 + 2 );
track = FT_NEXT_LONG( p ); track = FT_NEXT_LONG( p );
nameIndex = FT_NEXT_USHORT( p ); nameIndex = FT_NEXT_USHORT( p );
offset = FT_NEXT_USHORT( p ); offset = FT_NEXT_USHORT( p );
@ -121,6 +123,15 @@
GXV_TRAK_DATA( trackValueOffset_max ) = offset; GXV_TRAK_DATA( trackValueOffset_max ) = offset;
gxv_sfntName_validate( nameIndex, 256, 32767, valid ); gxv_sfntName_validate( nameIndex, 256, 32767, valid );
for ( j = i; j < nTracks; j ++ )
{
p = table + j * ( 4 + 2 + 2 );
t = FT_NEXT_LONG( p );
if ( t == track )
GXV_TRACE(( "duplicated entries found for track value 0x%x\n",
track ));
}
} }
valid->subtable_length = p - table; valid->subtable_length = p - table;
@ -198,7 +209,6 @@
{ {
FT_Bytes p = table; FT_Bytes p = table;
FT_Bytes limit = 0; FT_Bytes limit = 0;
FT_Offset table_size;
GXV_ValidatorRec validrec; GXV_ValidatorRec validrec;
GXV_Validator valid = &validrec; GXV_Validator valid = &validrec;
@ -220,7 +230,6 @@
valid->face = face; valid->face = face;
limit = valid->root->limit; limit = valid->root->limit;
table_size = limit - table;
FT_TRACE3(( "validating `trak' table\n" )); FT_TRACE3(( "validating `trak' table\n" ));
GXV_INIT; GXV_INIT;

View file

@ -8,7 +8,7 @@
/* parse compressed PCF fonts, as found with many X11 server */ /* parse compressed PCF fonts, as found with many X11 server */
/* distributions. */ /* distributions. */
/* */ /* */
/* Copyright 2002, 2003, 2004, 2005, 2006, 2009, 2010 by */ /* Copyright 2002-2006, 2009-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -571,7 +571,7 @@
old_pos = stream->pos; old_pos = stream->pos;
if ( !FT_Stream_Seek( stream, stream->size - 4 ) ) if ( !FT_Stream_Seek( stream, stream->size - 4 ) )
{ {
result = (FT_ULong)FT_Stream_ReadLong( stream, &error ); result = FT_Stream_ReadULong( stream, &error );
if ( error ) if ( error )
result = 0; result = 0;
@ -588,7 +588,7 @@
{ {
FT_Error error; FT_Error error;
FT_Memory memory = source->memory; FT_Memory memory = source->memory;
FT_GZipFile zip; FT_GZipFile zip = NULL;
/* /*
@ -628,7 +628,7 @@
if ( zip_size != 0 && zip_size < 40 * 1024 ) if ( zip_size != 0 && zip_size < 40 * 1024 )
{ {
FT_Byte* zip_buff; FT_Byte* zip_buff = NULL;
if ( !FT_ALLOC( zip_buff, zip_size ) ) if ( !FT_ALLOC( zip_buff, zip_size ) )

View file

@ -349,7 +349,7 @@
{ {
FT_Error error; FT_Error error;
FT_Memory memory = source->memory; FT_Memory memory = source->memory;
FT_LZWFile zip; FT_LZWFile zip = NULL;
/* /*

View file

@ -31,29 +31,11 @@ on linux/alpha.
Encodings Encodings
********* *********
The variety of encodings that accompanies pcf fonts appears to encompass the Use `FT_Get_BDF_Charset_ID' to access the encoding and registry.
small set defined in freetype.h. On the other hand, each pcf font defines
two properties that specify encoding and registry.
I decided to make these two properties directly accessible, leaving to the The driver always exports `ft_encoding_none' as face->charmap.encoding.
client application the work of interpreting them. For instance: FT_Get_Char_Index() behavior is unmodified, that is, it converts the ULong
value given as argument into the corresponding glyph number.
#include "pcftypes.h" /* include/freetype/internal/pcftypes.h */
FT_Face face;
PCF_Public_Face pcfface;
FT_New_Face( library,..., &face );
pcfface = (PCF_Public_Face)face;
if ((pcfface->charset_registry == "ISO10646") &&
(pcfface->charset_encoding) == "1")) [..]
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.
Known problems Known problems

View file

@ -2,7 +2,7 @@
FreeType font driver for pcf fonts FreeType font driver for pcf fonts
Copyright (C) 2000, 2001, 2002, 2003, 2006 by Copyright (C) 2000, 2001, 2002, 2003, 2006, 2010 by
Francesco Zappa Nardelli Francesco Zappa Nardelli
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
@ -136,8 +136,8 @@ FT_BEGIN_HEADER
{ {
FT_FaceRec root; FT_FaceRec root;
FT_StreamRec gzip_stream; FT_StreamRec comp_stream;
FT_Stream gzip_source; FT_Stream comp_source;
char* charset_encoding; char* charset_encoding;
char* charset_registry; char* charset_registry;

View file

@ -2,7 +2,8 @@
FreeType font driver for pcf files FreeType font driver for pcf files
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009,
2010 by
Francesco Zappa Nardelli Francesco Zappa Nardelli
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
@ -32,6 +33,7 @@ THE SOFTWARE.
#include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_OBJECTS_H
#include FT_GZIP_H #include FT_GZIP_H
#include FT_LZW_H #include FT_LZW_H
#include FT_BZIP2_H
#include FT_ERRORS_H #include FT_ERRORS_H
#include FT_BDF_H #include FT_BDF_H
#include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_IDS_H
@ -248,11 +250,11 @@ THE SOFTWARE.
FT_TRACE4(( "PCF_Face_Done: done face\n" )); FT_TRACE4(( "PCF_Face_Done: done face\n" ));
/* close gzip/LZW stream if any */ /* close compressed stream if any */
if ( pcfface->stream == &face->gzip_stream ) if ( pcfface->stream == &face->comp_stream )
{ {
FT_Stream_Close( &face->gzip_stream ); FT_Stream_Close( &face->comp_stream );
pcfface->stream = face->gzip_source; pcfface->stream = face->comp_source;
} }
} }
@ -277,8 +279,9 @@ THE SOFTWARE.
{ {
PCF_Face_Done( pcfface ); PCF_Face_Done( pcfface );
#if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \ #if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \
defined( FT_CONFIG_OPTION_USE_LZW ) defined( FT_CONFIG_OPTION_USE_LZW ) || \
defined( FT_CONFIG_OPTION_USE_BZIP2 )
#ifdef FT_CONFIG_OPTION_USE_ZLIB #ifdef FT_CONFIG_OPTION_USE_ZLIB
{ {
@ -286,7 +289,7 @@ THE SOFTWARE.
/* this didn't work, try gzip support! */ /* this didn't work, try gzip support! */
error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); error2 = FT_Stream_OpenGzip( &face->comp_stream, stream );
if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature ) if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature )
goto Fail; goto Fail;
@ -301,7 +304,7 @@ THE SOFTWARE.
/* this didn't work, try LZW support! */ /* this didn't work, try LZW support! */
error3 = FT_Stream_OpenLZW( &face->gzip_stream, stream ); error3 = FT_Stream_OpenLZW( &face->comp_stream, stream );
if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature ) if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature )
goto Fail; goto Fail;
@ -309,11 +312,26 @@ THE SOFTWARE.
} }
#endif /* FT_CONFIG_OPTION_USE_LZW */ #endif /* FT_CONFIG_OPTION_USE_LZW */
#ifdef FT_CONFIG_OPTION_USE_BZIP2
if ( error )
{
FT_Error error4;
/* this didn't work, try Bzip2 support! */
error4 = FT_Stream_OpenBzip2( &face->comp_stream, stream );
if ( FT_ERROR_BASE( error4 ) == FT_Err_Unimplemented_Feature )
goto Fail;
error = error4;
}
#endif /* FT_CONFIG_OPTION_USE_BZIP2 */
if ( error ) if ( error )
goto Fail; goto Fail;
face->gzip_source = stream; face->comp_source = stream;
pcfface->stream = &face->gzip_stream; pcfface->stream = &face->comp_stream;
stream = pcfface->stream; stream = pcfface->stream;
@ -321,7 +339,9 @@ THE SOFTWARE.
if ( error ) if ( error )
goto Fail; goto Fail;
#else /* !(FT_CONFIG_OPTION_USE_ZLIB || FT_CONFIG_OPTION_USE_LZW) */ #else /* !(FT_CONFIG_OPTION_USE_ZLIB ||
FT_CONFIG_OPTION_USE_LZW ||
FT_CONFIG_OPTION_USE_BZIP2) */
goto Fail; goto Fail;

View file

@ -399,7 +399,7 @@ THE SOFTWARE.
PCF_Face face ) PCF_Face face )
{ {
PCF_ParseProperty props = 0; PCF_ParseProperty props = 0;
PCF_Property properties; PCF_Property properties = NULL;
FT_ULong nprops, i; FT_ULong nprops, i;
FT_ULong format, size; FT_ULong format, size;
FT_Error error; FT_Error error;
@ -663,9 +663,9 @@ THE SOFTWARE.
pcf_get_bitmaps( FT_Stream stream, pcf_get_bitmaps( FT_Stream stream,
PCF_Face face ) PCF_Face face )
{ {
FT_Error error = PCF_Err_Ok; FT_Error error = PCF_Err_Ok;
FT_Memory memory = FT_FACE(face)->memory; FT_Memory memory = FT_FACE(face)->memory;
FT_Long* offsets; FT_Long* offsets = NULL;
FT_Long bitmapSizes[GLYPHPADOPTIONS]; FT_Long bitmapSizes[GLYPHPADOPTIONS];
FT_ULong format, size; FT_ULong format, size;
FT_ULong nbitmaps, i, sizebitmaps = 0; FT_ULong nbitmaps, i, sizebitmaps = 0;
@ -772,7 +772,7 @@ THE SOFTWARE.
int firstRow, lastRow; int firstRow, lastRow;
int nencoding, encodingOffset; int nencoding, encodingOffset;
int i, j; int i, j;
PCF_Encoding tmpEncoding, encoding = 0; PCF_Encoding tmpEncoding = NULL, encoding = 0;
error = pcf_seek_to_table_type( stream, error = pcf_seek_to_table_type( stream,

View file

@ -476,7 +476,7 @@
PFR_PhyFont phy_font ) PFR_PhyFont phy_font )
{ {
FT_UInt count, num_vert, num_horz; FT_UInt count, num_vert, num_horz;
FT_Int* snaps; FT_Int* snaps = NULL;
FT_Error error = PFR_Err_Ok; FT_Error error = PFR_Err_Ok;
FT_Memory memory = phy_font->memory; FT_Memory memory = phy_font->memory;

View file

@ -4,8 +4,7 @@
/* */ /* */
/* Auxiliary functions for PostScript fonts (body). */ /* Auxiliary functions for PostScript fonts (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ /* Copyright 1996-2011 by */
/* 2010 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -186,13 +185,13 @@
/* grow the base block if needed */ /* grow the base block if needed */
if ( table->cursor + length > table->capacity ) if ( table->cursor + length > table->capacity )
{ {
FT_Error error; FT_Error error;
FT_Offset new_size = table->capacity; FT_Offset new_size = table->capacity;
FT_Long in_offset; FT_PtrDist in_offset;
in_offset = (FT_Long)((FT_Byte*)object - table->block); in_offset = (FT_Byte*)object - table->block;
if ( (FT_ULong)in_offset >= table->capacity ) if ( in_offset < 0 || (FT_Offset)in_offset >= table->capacity )
in_offset = -1; in_offset = -1;
while ( new_size < table->cursor + length ) while ( new_size < table->cursor + length )

View file

@ -3,7 +3,7 @@
# #
# Copyright 2001, 2003 by # Copyright 2001, 2003, 2011 by
# David Turner, Robert Wilhelm, and Werner Lemberg. # David Turner, Robert Wilhelm, and Werner Lemberg.
# #
# This file is part of the FreeType project, and may only be used, modified, # This file is part of the FreeType project, and may only be used, modified,
@ -25,10 +25,11 @@ PSHINTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSHINTER_DIR))
# PSHINTER driver sources (i.e., C files) # PSHINTER driver sources (i.e., C files)
# #
PSHINTER_DRV_SRC := $(PSHINTER_DIR)/pshrec.c \ PSHINTER_DRV_SRC := $(PSHINTER_DIR)/pshalgo.c \
$(PSHINTER_DIR)/pshglob.c \ $(PSHINTER_DIR)/pshglob.c \
$(PSHINTER_DIR)/pshmod.c \ $(PSHINTER_DIR)/pshmod.c \
$(PSHINTER_DIR)/pshalgo.c $(PSHINTER_DIR)/pshpic.c \
$(PSHINTER_DIR)/pshrec.c
# PSHINTER driver headers # PSHINTER driver headers

View file

@ -3,7 +3,7 @@
# #
# Copyright 1996-2000, 2001, 2003 by # Copyright 1996-2000, 2001, 2003, 2011 by
# David Turner, Robert Wilhelm, and Werner Lemberg. # David Turner, Robert Wilhelm, and Werner Lemberg.
# #
# This file is part of the FreeType project, and may only be used, modified, # This file is part of the FreeType project, and may only be used, modified,
@ -25,14 +25,15 @@ PSNAMES_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSNAMES_DIR))
# PSNames driver sources (i.e., C files) # PSNames driver sources (i.e., C files)
# #
PSNAMES_DRV_SRC := $(PSNAMES_DIR)/psmodule.c PSNAMES_DRV_SRC := $(PSNAMES_DIR)/psmodule.c \
$(PSNAMES_DIR)/pspic.c
# PSNames driver headers # PSNames driver headers
# #
PSNAMES_DRV_H := $(PSNAMES_DRV_SRC:%.c=%.h) \ PSNAMES_DRV_H := $(PSNAMES_DRV_SRC:%.c=%.h) \
$(PSNAMES_DIR)/pstables.h \ $(PSNAMES_DIR)/psnamerr.h \
$(PSNAMES_DIR)/psnamerr.h $(PSNAMES_DIR)/pstables.h
# PSNames driver object(s) # PSNames driver object(s)

View file

@ -4,7 +4,7 @@
/* */ /* */
/* The FreeType glyph rasterizer (body). */ /* The FreeType glyph rasterizer (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2005, 2007, 2008, 2009, 2010 by */ /* Copyright 1996-2001, 2002, 2003, 2005, 2007, 2008, 2009, 2010, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -651,11 +651,33 @@
static void static void
Set_High_Precision( RAS_ARGS Int High ) Set_High_Precision( RAS_ARGS Int High )
{ {
/*
* `precision_step' is used in `Bezier_Up' to decide when to split a
* given y-monotonous Bezier arc that crosses a scanline before
* approximating it as a straight segment. The default value of 32 (for
* low accuracy) corresponds to
*
* 32 / 64 == 0.5 pixels ,
*
* while for the high accuracy case we have
*
* 256/ (1 << 12) = 0.0625 pixels .
*
* `precision_jitter' is an epsilon threshold used in
* `Vertical_Sweep_Span' to deal with small imperfections in the Bezier
* decomposition (after all, we are working with approximations only);
* it avoids switching on additional pixels which would cause artifacts
* otherwise.
*
* The value of `precision_jitter' has been determined heuristically.
*
*/
if ( High ) if ( High )
{ {
ras.precision_bits = 12; ras.precision_bits = 12;
ras.precision_step = 256; ras.precision_step = 256;
ras.precision_jitter = 50; ras.precision_jitter = 30;
} }
else else
{ {
@ -2403,6 +2425,14 @@
return; /* no drop-out control */ return; /* no drop-out control */
} }
/* undocumented but confirmed: If the drop-out would result in a */
/* pixel outside of the bounding box, use the pixel inside of the */
/* bounding box instead */
if ( pxl < 0 )
pxl = e1;
else if ( TRUNC( pxl ) >= ras.bWidth )
pxl = e2;
/* check that the other pixel isn't set */ /* check that the other pixel isn't set */
e1 = pxl == e1 ? e2 : e1; e1 = pxl == e1 ? e2 : e1;
@ -2579,6 +2609,14 @@
return; /* no drop-out control */ return; /* no drop-out control */
} }
/* undocumented but confirmed: If the drop-out would result in a */
/* pixel outside of the bounding box, use the pixel inside of the */
/* bounding box instead */
if ( pxl < 0 )
pxl = e1;
else if ( TRUNC( pxl ) >= ras.target.rows )
pxl = e2;
/* check that the other pixel isn't set */ /* check that the other pixel isn't set */
e1 = pxl == e1 ? e2 : e1; e1 = pxl == e1 ? e2 : e1;

View file

@ -161,10 +161,18 @@
/* compute the control box, and grid fit it */ /* compute the control box, and grid fit it */
FT_Outline_Get_CBox( outline, &cbox ); FT_Outline_Get_CBox( outline, &cbox );
/* undocumented but confirmed: bbox values get rounded */
#if 1
cbox.xMin = FT_PIX_ROUND( cbox.xMin );
cbox.yMin = FT_PIX_ROUND( cbox.yMin );
cbox.xMax = FT_PIX_ROUND( cbox.xMax );
cbox.yMax = FT_PIX_ROUND( cbox.yMax );
#else
cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
cbox.xMax = FT_PIX_CEIL( cbox.xMax ); cbox.xMax = FT_PIX_CEIL( cbox.xMax );
cbox.yMax = FT_PIX_CEIL( cbox.yMax ); cbox.yMax = FT_PIX_CEIL( cbox.yMax );
#endif
width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );
height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );

View file

@ -3,7 +3,7 @@
# #
# Copyright 1996-2000, 2001, 2003, 2008, 2009 by # Copyright 1996-2000, 2001, 2003, 2008, 2009, 2011 by
# David Turner, Robert Wilhelm, and Werner Lemberg. # David Turner, Robert Wilhelm, and Werner Lemberg.
# #
# This file is part of the FreeType project, and may only be used, modified, # This file is part of the FreeType project, and may only be used, modified,
@ -25,7 +25,8 @@ RASTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(RASTER_DIR))
# raster driver sources (i.e., C files) # raster driver sources (i.e., C files)
# #
RASTER_DRV_SRC := $(RASTER_DIR)/ftraster.c \ RASTER_DRV_SRC := $(RASTER_DIR)/ftraster.c \
$(RASTER_DIR)/ftrend1.c $(RASTER_DIR)/ftrend1.c \
$(RASTER_DIR)/rastpic.c
# raster driver headers # raster driver headers

View file

@ -3,7 +3,7 @@
# #
# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by # Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2011 by
# David Turner, Robert Wilhelm, and Werner Lemberg. # David Turner, Robert Wilhelm, and Werner Lemberg.
# #
# This file is part of the FreeType project, and may only be used, modified, # This file is part of the FreeType project, and may only be used, modified,
@ -33,7 +33,8 @@ SFNT_DRV_SRC := $(SFNT_DIR)/ttload.c \
$(SFNT_DIR)/ttkern.c \ $(SFNT_DIR)/ttkern.c \
$(SFNT_DIR)/ttbdf.c \ $(SFNT_DIR)/ttbdf.c \
$(SFNT_DIR)/sfobjs.c \ $(SFNT_DIR)/sfobjs.c \
$(SFNT_DIR)/sfdriver.c $(SFNT_DIR)/sfdriver.c \
$(SFNT_DIR)/sfntpic.c
# SFNT driver headers # SFNT driver headers
# #

View file

@ -4,7 +4,7 @@
/* */ /* */
/* High-level SFNT driver interface (body). */ /* High-level SFNT driver interface (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ /* Copyright 1996-2007, 2009-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -117,15 +117,20 @@
FT_ULong *offset, FT_ULong *offset,
FT_ULong *length ) FT_ULong *length )
{ {
if ( !tag || !offset || !length ) if ( !offset || !length )
return SFNT_Err_Invalid_Argument; return SFNT_Err_Invalid_Argument;
if ( idx >= face->num_tables ) if ( !tag )
return SFNT_Err_Table_Missing; *length = face->num_tables;
else
{
if ( idx >= face->num_tables )
return SFNT_Err_Table_Missing;
*tag = face->dir_tables[idx].Tag; *tag = face->dir_tables[idx].Tag;
*offset = face->dir_tables[idx].Offset; *offset = face->dir_tables[idx].Offset;
*length = face->dir_tables[idx].Length; *length = face->dir_tables[idx].Length;
}
return SFNT_Err_Ok; return SFNT_Err_Ok;
} }

View file

@ -4,7 +4,7 @@
/* */ /* */
/* SFNT object management (base). */ /* SFNT object management (base). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */ /* Copyright 1996-2008, 2010-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -356,7 +356,7 @@
FT_FRAME_START( 8 ), FT_FRAME_START( 8 ),
FT_FRAME_LONG( version ), FT_FRAME_LONG( version ),
FT_FRAME_LONG( count ), FT_FRAME_LONG( count ), /* this is ULong in the specs */
FT_FRAME_END FT_FRAME_END
}; };
@ -390,6 +390,17 @@
if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) ) if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
return error; return error;
if ( face->ttc_header.count == 0 )
return SFNT_Err_Invalid_Table;
/* a rough size estimate: let's conservatively assume that there */
/* is just a single table info in each subfont header (12 + 16*1 = */
/* 28 bytes), thus we have (at least) `12 + 4*count' bytes for the */
/* size of the TTC header plus `28*count' bytes for all subfont */
/* headers */
if ( (FT_ULong)face->ttc_header.count > stream->size / ( 28 + 4 ) )
return SFNT_Err_Array_Too_Large;
/* now read the offsets of each font in the file */ /* now read the offsets of each font in the file */
if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) ) if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
return error; return error;

View file

@ -1213,7 +1213,7 @@
FT_Memory memory = stream->memory; FT_Memory memory = stream->memory;
FT_UInt j,num_ranges; FT_UInt j,num_ranges;
TT_GaspRange gaspranges; TT_GaspRange gaspranges = NULL;
/* the gasp table is optional */ /* the gasp table is optional */

View file

@ -4,7 +4,7 @@
/* */ /* */
/* Load the metrics tables common to TTF and OTF fonts (body). */ /* Load the metrics tables common to TTF and OTF fonts (body). */
/* */ /* */
/* Copyright 2006, 2007, 2008, 2009 by */ /* Copyright 2006-2009, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -163,7 +163,7 @@
{ {
FT_TRACE0(( "tt_face_load_hmtx:" FT_TRACE0(( "tt_face_load_hmtx:"
" %cmtx has more metrics than glyphs.\n", " %cmtx has more metrics than glyphs.\n",
vertical ? "v" : "h" )); vertical ? 'v' : 'h' ));
/* Adobe simply ignores this problem. So we shall do the same. */ /* Adobe simply ignores this problem. So we shall do the same. */
#if 0 #if 0

View file

@ -1343,7 +1343,7 @@
/* All right, we have a compound format. First of all, read */ /* All right, we have a compound format. First of all, read */
/* the array of elements. */ /* the array of elements. */
{ {
TT_SBit_Component components; TT_SBit_Component components = NULL;
TT_SBit_Component comp; TT_SBit_Component comp;
FT_UShort num_components, count; FT_UShort num_components, count;

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