[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). */
/* */
/* 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. */
/* */
/* 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 ) ) || \
( defined( __MWERKS__ ) && defined( macintosh ) )
/* 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"
#endif
#if defined( __LP64__ ) && \
( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
#define DARWIN_NO_CARBON 1
@ -348,14 +353,14 @@ FT_BEGIN_HEADER
register FT_Int32 t, t2;
asm __volatile__ (
__asm__ __volatile__ (
"smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */
"mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */
"add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
"adds %1, %1, %0\n\t" /* %1 += %0 */
"adc %2, %2, #0\n\t" /* %2 += carry */
"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"(b) );
return a;
@ -395,6 +400,43 @@ FT_BEGIN_HEADER
#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 */

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -424,6 +424,19 @@
#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:

View file

@ -4,8 +4,7 @@
/* */
/* User-selectable configuration macros (specification only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
/* 2010 by */
/* Copyright 1996-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* 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 */
/*************************************************************************/
/* */
/* 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 */
@ -363,6 +378,39 @@ FT_BEGIN_HEADER
/* #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 */
@ -575,7 +623,7 @@ FT_BEGIN_HEADER
/* composite flags array which can be used to disambiguate, but old */
/* 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 */
/* */
#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
@ -676,6 +724,19 @@ FT_BEGIN_HEADER
/* */
#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). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
/* 2010 by */
/* Copyright 1996-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* 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. */
/* */
/* vertBearingY :: */
/* Top side bearing for vertical layout. */
/* Top side bearing for vertical layout. Larger positive values */
/* mean further below the vertical glyph origin. */
/* */
/* vertAdvance :: */
/* Advance height for vertical layout. */
/* Advance height for vertical layout. Positive values mean the */
/* glyph has a positive advance downward. */
/* */
/* <Note> */
/* 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 */
/* @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 */
/* 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.
*
* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ::
* Indicates that the font driver should ignore the global advance
* 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).
* Ignored. Deprecated.
*
* FT_LOAD_NO_RECURSE ::
* This flag is only used internally. It merely indicates that the
@ -3808,7 +3803,7 @@ FT_BEGIN_HEADER
*/
#define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 4
#define FREETYPE_PATCH 4
#define FREETYPE_PATCH 5
/*************************************************************************/

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -73,6 +73,14 @@ FT_BEGIN_HEADER
/* <Return> */
/* 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_Outline_Get_BBox( FT_Outline* outline,
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 */
/* gzip */
/* lzw */
/* bzip2 */
/* lcd_filtering */
/* */
/***************************************************************************/

View file

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

View file

@ -4,7 +4,7 @@
/* */
/* Access of TrueType's `gasp' table (specification). */
/* */
/* Copyright 2007, 2008 by */
/* Copyright 2007, 2008, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -63,18 +63,26 @@
*
* FT_GASP_DO_GRIDFIT ::
* 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 ::
* Anti-aliased rendering should be performed at the specified ppem.
* If not set, do monochrome rendering.
*
* 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 ::
* Grid-fitting must be used with ClearType's symmetric smoothing.
*
* @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
* protected by patents.
*

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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 */
/* 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 */
/* one can compute the width and height of the glyph image (be it in */
/* integer or 26.6 pixels) as: */

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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( Autofit, 0x100, "autofitter module" )
FT_MODERRDEF( BDF, 0x200, "BDF module" )
FT_MODERRDEF( Cache, 0x300, "cache module" )
FT_MODERRDEF( CFF, 0x400, "CFF module" )
FT_MODERRDEF( CID, 0x500, "CID module" )
FT_MODERRDEF( Gzip, 0x600, "Gzip module" )
FT_MODERRDEF( LZW, 0x700, "LZW module" )
FT_MODERRDEF( OTvalid, 0x800, "OpenType validation module" )
FT_MODERRDEF( PCF, 0x900, "PCF module" )
FT_MODERRDEF( PFR, 0xA00, "PFR module" )
FT_MODERRDEF( PSaux, 0xB00, "PS auxiliary module" )
FT_MODERRDEF( PShinter, 0xC00, "PS hinter module" )
FT_MODERRDEF( PSnames, 0xD00, "PS names module" )
FT_MODERRDEF( Raster, 0xE00, "raster module" )
FT_MODERRDEF( SFNT, 0xF00, "SFNT module" )
FT_MODERRDEF( Smooth, 0x1000, "smooth raster module" )
FT_MODERRDEF( TrueType, 0x1100, "TrueType module" )
FT_MODERRDEF( Type1, 0x1200, "Type 1 module" )
FT_MODERRDEF( Type42, 0x1300, "Type 42 module" )
FT_MODERRDEF( Winfonts, 0x1400, "Windows FON/FNT module" )
FT_MODERRDEF( Bzip2, 0x300, "Bzip2 module" )
FT_MODERRDEF( Cache, 0x400, "cache module" )
FT_MODERRDEF( CFF, 0x500, "CFF module" )
FT_MODERRDEF( CID, 0x600, "CID module" )
FT_MODERRDEF( Gzip, 0x700, "Gzip module" )
FT_MODERRDEF( LZW, 0x800, "LZW module" )
FT_MODERRDEF( OTvalid, 0x900, "OpenType validation module" )
FT_MODERRDEF( PCF, 0xA00, "PCF module" )
FT_MODERRDEF( PFR, 0xB00, "PFR module" )
FT_MODERRDEF( PSaux, 0xC00, "PS auxiliary module" )
FT_MODERRDEF( PShinter, 0xD00, "PS hinter module" )
FT_MODERRDEF( PSnames, 0xE00, "PS names module" )
FT_MODERRDEF( Raster, 0xF00, "raster module" )
FT_MODERRDEF( SFNT, 0x1000, "SFNT module" )
FT_MODERRDEF( Smooth, 0x1100, "smooth raster module" )
FT_MODERRDEF( TrueType, 0x1200, "TrueType module" )
FT_MODERRDEF( Type1, 0x1300, "Type 1 module" )
FT_MODERRDEF( Type42, 0x1400, "Type 42 module" )
FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" )
#ifdef FT_MODERR_END_LIST

View file

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

View file

@ -212,6 +212,14 @@ FT_BEGIN_HEADER
/* */
/* 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_Set_Renderer( FT_Library library,
FT_Renderer renderer,

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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_BYTE() FT_GET_MACRO( FT_Stream_GetChar, FT_Byte )
#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_Short )
#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_UShort )
#define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_Long )
#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_ULong )
#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetLong, FT_Long )
#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong )
#define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong )
#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_Short )
#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_UShort )
#define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_Long )
#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_ULong )
#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetULong, FT_Long )
#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetULong, 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_USHORT_LE() FT_GET_MACRO( FT_Stream_GetShortLE, FT_UShort )
#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, FT_Long )
#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, FT_ULong )
#define FT_GET_SHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Short )
#define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UShort )
#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_Long )
#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_ULong )
#endif
#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_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_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadShort, FT_UShort, var )
#define FT_READ_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_Long, var )
#define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_ULong, var )
#define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_Long, var )
#define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_ULong, 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_ReadUShort, FT_UShort, 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_ReadUOffset, FT_ULong, 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_ReadULong, FT_ULong, var )
#define FT_READ_SHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_Short, var )
#define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_UShort, var )
#define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_Long, var )
#define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_ULong, 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_ReadUShortLE, FT_UShort, 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_ReadULongLE, FT_ULong, var )
#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
@ -431,25 +431,25 @@ FT_BEGIN_HEADER
FT_BASE( FT_Char )
FT_Stream_GetChar( FT_Stream stream );
/* read a 16-bit big-endian integer from an entered frame */
FT_BASE( FT_Short )
FT_Stream_GetShort( FT_Stream stream );
/* read a 16-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_UShort )
FT_Stream_GetUShort( FT_Stream stream );
/* read a 24-bit big-endian integer from an entered frame */
FT_BASE( FT_Long )
FT_Stream_GetOffset( FT_Stream stream );
/* read a 24-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_ULong )
FT_Stream_GetUOffset( FT_Stream stream );
/* read a 32-bit big-endian integer from an entered frame */
FT_BASE( FT_Long )
FT_Stream_GetLong( FT_Stream stream );
/* read a 32-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_ULong )
FT_Stream_GetULong( FT_Stream stream );
/* read a 16-bit little-endian integer from an entered frame */
FT_BASE( FT_Short )
FT_Stream_GetShortLE( FT_Stream stream );
/* read a 16-bit little-endian unsigned integer from an entered frame */
FT_BASE( FT_UShort )
FT_Stream_GetUShortLE( FT_Stream stream );
/* read a 32-bit little-endian integer from an entered frame */
FT_BASE( FT_Long )
FT_Stream_GetLongLE( FT_Stream stream );
/* read a 32-bit little-endian unsigned integer from an entered frame */
FT_BASE( FT_ULong )
FT_Stream_GetULongLE( FT_Stream stream );
/* read a byte from a stream */
@ -457,29 +457,29 @@ FT_BEGIN_HEADER
FT_Stream_ReadChar( FT_Stream stream,
FT_Error* error );
/* read a 16-bit big-endian integer from a stream */
FT_BASE( FT_Short )
FT_Stream_ReadShort( FT_Stream stream,
/* read a 16-bit big-endian unsigned integer from a stream */
FT_BASE( FT_UShort )
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,
/* read a 24-bit big-endian unsigned integer from a stream */
FT_BASE( FT_ULong )
FT_Stream_ReadUOffset( FT_Stream stream,
FT_Error* error );
/* read a 32-bit big-endian integer from a stream */
FT_BASE( FT_Long )
FT_Stream_ReadLong( FT_Stream stream,
FT_BASE( FT_ULong )
FT_Stream_ReadULong( 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,
/* 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 integer from a stream */
FT_BASE( FT_Long )
FT_Stream_ReadLongLE( FT_Stream stream,
/* 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 */

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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( gxvlcar )
/* autofit components */
FT_TRACE_DEF( afcjk )
FT_TRACE_DEF( aflatin )
FT_TRACE_DEF( aflatin2 )
FT_TRACE_DEF( afwarp )
/* END */

View file

@ -5,7 +5,7 @@
/* Basic SFNT/TrueType tables definitions and interface */
/* (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. */
/* */
/* 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
* FT_Err_Table_Missing for an invalid value.
*
* @output:
* @inout:
* 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 ::
* The length of the SFNT table.
* The length of the SFNT table (or the number of SFNT tables, depending
* on `tag').
*
* @return:
* FreeType error code. 0~means success.

View file

@ -1,6 +1,6 @@
# modules.cfg
#
# Copyright 2005, 2006, 2007, 2009 by
# Copyright 2005, 2006, 2007, 2009, 2010 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# 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.
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.
#
# AUX_MODULES += otvalid

View file

@ -5,7 +5,7 @@
/* Routines used to compute vector angles with limited accuracy */
/* and very high speed. It also contains sorting routines (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006 by */
/* Copyright 2003-2006, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -77,7 +77,7 @@
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). */
/* */
/* Copyright 2006, 2007 by */
/* Copyright 2006, 2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -20,6 +20,7 @@
#define __AFCJK_H__
#include "afhints.h"
#include "aflatin.h"
FT_BEGIN_HEADER
@ -29,23 +30,106 @@ FT_BEGIN_HEADER
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 )
af_cjk_metrics_init( AF_LatinMetrics metrics,
af_cjk_metrics_init( AF_CJKMetrics metrics,
FT_Face face );
FT_LOCAL( void )
af_cjk_metrics_scale( AF_LatinMetrics metrics,
af_cjk_metrics_scale( AF_CJKMetrics metrics,
AF_Scaler scaler );
FT_LOCAL( FT_Error )
af_cjk_hints_init( AF_GlyphHints hints,
AF_LatinMetrics metrics );
AF_CJKMetrics metrics );
FT_LOCAL( FT_Error )
af_cjk_hints_apply( AF_GlyphHints hints,
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 */
/* performed (body). */
/* */
/* Copyright 2003, 2004, 2005 by */
/* Copyright 2003-2005, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -19,6 +19,7 @@
#include "afdummy.h"
#include "afhints.h"
#include "aferrors.h"
static FT_Error
@ -27,7 +28,7 @@
{
af_glyph_hints_rescale( hints,
metrics );
return 0;
return AF_Err_Ok;
}
@ -38,11 +39,11 @@
FT_UNUSED( hints );
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,
NULL,

View file

@ -5,7 +5,7 @@
/* Auto-fitter dummy routines to be used if no hinting should be */
/* performed (specification). */
/* */
/* Copyright 2003, 2004, 2005 by */
/* Copyright 2003-2005, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* 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!
*/
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). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by */
/* Copyright 2003-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -31,8 +31,8 @@
#ifndef FT_CONFIG_OPTION_PIC
/* when updating this table, don't forget to update
AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */
/* when updating this table, don't forget to update */
/* AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */
/* populate this list when you add new scripts */
static AF_ScriptClass const af_script_classes[] =
@ -47,7 +47,7 @@
NULL /* do not remove */
};
#endif /* FT_CONFIG_OPTION_PIC */
#endif /* !FT_CONFIG_OPTION_PIC */
/* index of default script in `af_script_classes' */
#define AF_SCRIPT_LIST_DEFAULT 2
@ -85,7 +85,7 @@
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,
AF_SCRIPT_LIST_NONE,
globals->glyph_count );
@ -126,9 +126,7 @@
if ( gindex != 0 &&
gindex < (FT_ULong)globals->glyph_count &&
gscripts[gindex] == AF_SCRIPT_LIST_NONE )
{
gscripts[gindex] = (FT_Byte)ss;
}
for (;;)
{
@ -139,12 +137,10 @@
if ( gindex < (FT_ULong)globals->glyph_count &&
gscripts[gindex] == AF_SCRIPT_LIST_NONE )
{
gscripts[gindex] = (FT_Byte)ss;
}
}
}
}
/* mark ASCII digits */
for ( i = 0x30; i <= 0x39; i++ )

View file

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

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -21,6 +21,8 @@
#include FT_INTERNAL_CALC_H
/* Get new segment for given axis. */
FT_LOCAL_DEF( FT_Error )
af_axis_hints_new_segment( AF_AxisHints axis,
FT_Memory memory,
@ -61,6 +63,8 @@
}
/* Get new edge for given axis, direction, and position. */
FT_LOCAL( FT_Error )
af_axis_hints_new_edge( AF_AxisHints axis,
FT_Int fpos,
@ -125,7 +129,7 @@
}
#ifdef AF_DEBUG
#ifdef FT_DEBUG_AUTOFIT
#include FT_CONFIG_STANDARD_LIBRARY_H
@ -160,6 +164,9 @@
#define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 )
#ifdef __cplusplus
extern "C" {
#endif
void
af_glyph_hints_dump_points( AF_GlyphHints hints )
{
@ -169,20 +176,20 @@
printf( "Table of points:\n" );
printf( " [ index | xorg | yorg | xscale | yscale "
"| xfit | yfit | flags ]\n" );
printf( " [ index | xorg | yorg | xscale | yscale"
" | xfit | yfit | flags ]\n" );
for ( point = points; point < limit; point++ )
{
printf( " [ %5d | %5d | %5d | %-5.2f | %-5.2f "
"| %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n",
printf( " [ %5d | %5d | %5d | %6.2f | %6.2f"
" | %5.2f | %5.2f | %c%c%c%c%c%c ]\n",
point - points,
point->fx,
point->fy,
point->ox/64.0,
point->oy/64.0,
point->x/64.0,
point->y/64.0,
point->ox / 64.0,
point->oy / 64.0,
point->x / 64.0,
point->y / 64.0,
( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ',
( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ',
( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ',
@ -192,6 +199,9 @@
}
printf( "\n" );
}
#ifdef __cplusplus
}
#endif
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
af_glyph_hints_dump_segments( AF_GlyphHints hints )
{
@ -244,7 +258,7 @@
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,
dimension == AF_DIMENSION_HORZ ? (int)seg->first->ox / 64.0
: (int)seg->first->oy / 64.0,
@ -253,13 +267,84 @@
AF_INDEX_NUM( seg->serif, segments ),
seg->height,
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" );
}
}
#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
af_glyph_hints_dump_edges( AF_GlyphHints hints )
{
@ -276,7 +361,7 @@
/*
* 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",
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
@ -286,7 +371,7 @@
for ( edge = edges; edge < limit; edge++ )
{
printf ( " [ %5d | %5.2g | %5s | %4d |"
" %5d | %c | %5.2f | %5.2f | %s ]\n",
" %5d | %c | %5.2f | %5.2f | %11s ]\n",
edge - edges,
(int)edge->opos / 64.0,
af_dir_str( (AF_Direction)edge->dir ),
@ -295,16 +380,23 @@
edge->blue_edge ? 'y' : 'n',
edge->opos / 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" );
}
}
#ifdef __cplusplus
}
#endif
#else /* !AF_DEBUG */
#else /* !FT_DEBUG_AUTOFIT */
/* 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
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
af_glyph_hints_dump_edges( AF_GlyphHints 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 )
af_direction_compute( FT_Pos dx,
FT_Pos dy )
@ -369,6 +494,8 @@
}
}
/* return no direction if arm lengths differ too much */
/* (value 14 is heuristic) */
ss *= 14;
if ( FT_ABS( ll ) <= FT_ABS( ss ) )
dir = AF_DIR_NONE;
@ -397,7 +524,7 @@
/*
* 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++ )
{
@ -426,6 +553,8 @@
}
/* Reset metrics. */
FT_LOCAL_DEF( void )
af_glyph_hints_rescale( AF_GlyphHints hints,
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 )
af_glyph_hints_reload( AF_GlyphHints hints,
FT_Outline* outline )
@ -457,12 +589,12 @@
hints->axis[1].num_segments = 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;
old_max = hints->max_contours;
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 ) )
goto Exit;
@ -479,7 +611,7 @@
old_max = hints->max_points;
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 ) )
goto Exit;
@ -545,7 +677,7 @@
point->flags = AF_FLAG_CUBIC;
break;
default:
point->flags = 0;
point->flags = AF_FLAG_NONE;
}
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_limit = contour + hints->num_contours;
@ -611,6 +743,8 @@
in_dir = af_direction_compute( out_x, out_y );
point->out_dir = (FT_Char)in_dir;
/* check for weak points */
if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) )
{
Is_Weak_Point:
@ -639,6 +773,8 @@
}
/* Store the hinted outline in an FT_Outline structure. */
FT_LOCAL_DEF( void )
af_glyph_hints_save( AF_GlyphHints hints,
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 )
af_glyph_hints_align_edge_points( AF_GlyphHints hints,
AF_Dimension dim )
@ -704,7 +843,6 @@
break;
point = point->next;
}
}
}
@ -744,8 +882,8 @@
****************************************************************/
/* hint the strong points -- this is equivalent to the TrueType `IP' */
/* hinting instruction */
/* Hint the strong points -- this is equivalent to the TrueType `IP' */
/* hinting instruction. */
FT_LOCAL_DEF( void )
af_glyph_hints_align_strong_points( AF_GlyphHints hints,
@ -827,11 +965,12 @@
max = edge_limit - edges;
#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 )
{
FT_PtrDist nn;
for ( nn = 0; nn < max; nn++ )
if ( edges[nn].fpos >= u )
break;
@ -863,6 +1002,7 @@
}
}
/* point is not on an edge */
{
AF_Edge before = edges + min - 1;
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
af_iup_shift( AF_Point p1,
AF_Point p2,
@ -906,6 +1050,7 @@
AF_Point p;
FT_Pos delta = ref->u - ref->v;
if ( delta == 0 )
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
af_iup_interp( AF_Point p1,
AF_Point p2,
@ -985,6 +1137,9 @@
}
/* Hint the weak points -- this is equivalent to the TrueType `IUP' */
/* hinting instruction. */
FT_LOCAL_DEF( void )
af_glyph_hints_align_weak_points( AF_GlyphHints hints,
AF_Dimension dim )
@ -1053,14 +1208,15 @@
FT_ASSERT( point <= end_point &&
( point->flags & touch_flag ) != 0 );
/* skip any touched neighbhours */
while ( point < end_point && ( point[1].flags & touch_flag ) != 0 )
/* skip any touched neighbours */
while ( point < end_point &&
( point[1].flags & touch_flag ) != 0 )
point++;
last_touched = point;
/* find the next touched point, if any */
point ++;
point++;
for (;;)
{
if ( point > end_point )
@ -1080,9 +1236,8 @@
EndContour:
/* special case: only one point was touched */
if ( last_touched == first_touched )
{
af_iup_shift( first_point, end_point, first_touched );
}
else /* interpolate the last part */
{
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 )
af_glyph_hints_scale_dim( AF_GlyphHints hints,
@ -1137,6 +1294,6 @@
}
}
#endif /* AF_USE_WARPER */
#endif /* AF_CONFIG_OPTION_USE_WARPER */
/* END */

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -55,6 +55,151 @@ FT_BEGIN_HEADER
} 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 */
typedef enum AF_Flags_
{
@ -139,7 +284,6 @@ FT_BEGIN_HEADER
AF_Point first; /* first 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;
@ -155,32 +299,31 @@ FT_BEGIN_HEADER
FT_Fixed scale; /* used to speed up interpolation between edges */
AF_Width blue_edge; /* non-NULL if this is a blue edge */
AF_Edge link;
AF_Edge serif;
FT_Short num_linked;
AF_Edge link; /* link edge */
AF_Edge serif; /* primary edge for serifs */
FT_Short num_linked; /* number of linked edges */
FT_Int score; /* used during stem matching */
FT_Int score;
AF_Segment first;
AF_Segment last;
AF_Segment first; /* first segment in edge */
AF_Segment last; /* last segment in edge */
} AF_EdgeRec;
typedef struct AF_AxisHintsRec_
{
FT_Int num_segments;
FT_Int max_segments;
AF_Segment segments;
FT_Int num_segments; /* number of used segments */
FT_Int max_segments; /* number of allocated segments */
AF_Segment segments; /* segments array */
#ifdef AF_SORT_SEGMENTS
FT_Int mid_segments;
#endif
FT_Int num_edges;
FT_Int max_edges;
AF_Edge edges;
FT_Int num_edges; /* number of used edges */
FT_Int max_edges; /* number of allocated edges */
AF_Edge edges; /* edges array */
AF_Direction major_dir;
AF_Direction major_dir; /* either vertical or horizontal */
} AF_AxisHintsRec, *AF_AxisHints;
@ -195,15 +338,13 @@ FT_BEGIN_HEADER
FT_Fixed y_scale;
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 num_points;
AF_Point points;
FT_Int max_contours;
FT_Int num_contours;
AF_Point* contours;
FT_Int max_contours; /* number of allocated contours */
FT_Int num_contours; /* number of used contours */
AF_Point* contours; /* contours array */
AF_AxisHintsRec axis[AF_DIMENSION_MAX];
@ -222,7 +363,7 @@ FT_BEGIN_HEADER
#define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) )
#ifdef AF_DEBUG
#ifdef FT_DEBUG_AUTOFIT
#define AF_HINTS_DO_HORIZONTAL( h ) \
( !_af_debug_disable_horz_hints && \
@ -237,7 +378,7 @@ FT_BEGIN_HEADER
#define AF_HINTS_DO_BLUES( h ) ( !_af_debug_disable_blue_hints )
#else /* !AF_DEBUG */
#else /* !FT_DEBUG_AUTOFIT */
#define AF_HINTS_DO_HORIZONTAL( h ) \
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )
@ -250,7 +391,7 @@ FT_BEGIN_HEADER
#define AF_HINTS_DO_BLUES( h ) 1
#endif /* !AF_DEBUG */
#endif /* !FT_DEBUG_AUTOFIT */
FT_LOCAL( AF_Direction )
@ -274,12 +415,6 @@ FT_BEGIN_HEADER
af_glyph_hints_init( AF_GlyphHints hints,
FT_Memory memory );
/*
* recompute all AF_Point in a AF_GlyphHints from the definitions
* in a source outline
*/
FT_LOCAL( void )
af_glyph_hints_rescale( AF_GlyphHints hints,
AF_ScriptMetrics metrics );
@ -304,7 +439,7 @@ FT_BEGIN_HEADER
af_glyph_hints_align_weak_points( AF_GlyphHints hints,
AF_Dimension dim );
#ifdef AF_USE_WARPER
#ifdef AF_CONFIG_OPTION_USE_WARPER
FT_LOCAL( void )
af_glyph_hints_scale_dim( AF_GlyphHints hints,
AF_Dimension dim,

View file

@ -4,7 +4,7 @@
/* */
/* 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>. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -27,22 +27,41 @@
#include "afcjk.h"
#ifdef AF_USE_WARPER
#ifdef AF_CONFIG_OPTION_USE_WARPER
#include "afwarp.h"
#endif
static FT_Error
af_indic_metrics_init( AF_LatinMetrics metrics,
af_indic_metrics_init( AF_CJKMetrics metrics,
FT_Face face )
{
/* use CJK routines */
return af_cjk_metrics_init( metrics, face );
/* skip blue zone init in CJK routines */
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
af_indic_metrics_scale( AF_LatinMetrics metrics,
af_indic_metrics_scale( AF_CJKMetrics metrics,
AF_Scaler scaler )
{
/* use CJK routines */
@ -52,7 +71,7 @@
static FT_Error
af_indic_hints_init( AF_GlyphHints hints,
AF_LatinMetrics metrics )
AF_CJKMetrics metrics )
{
/* use CJK routines */
return af_cjk_hints_init( hints, metrics );
@ -62,7 +81,7 @@
static FT_Error
af_indic_hints_apply( AF_GlyphHints hints,
FT_Outline* outline,
AF_LatinMetrics metrics)
AF_CJKMetrics metrics )
{
/* use CJK routines */
return af_cjk_hints_apply( hints, outline, metrics );
@ -84,6 +103,12 @@
AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */
#endif
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)
};
@ -92,7 +117,7 @@
AF_SCRIPT_INDIC,
af_indic_uniranges,
sizeof( AF_LatinMetricsRec ),
sizeof( AF_CJKMetricsRec ),
(AF_Script_InitMetricsFunc) af_indic_metrics_init,
(AF_Script_ScaleMetricsFunc)af_indic_metrics_scale,
@ -114,7 +139,7 @@
AF_SCRIPT_INDIC,
af_indic_uniranges,
sizeof( AF_LatinMetricsRec ),
sizeof( AF_CJKMetricsRec ),
(AF_Script_InitMetricsFunc) NULL,
(AF_Script_ScaleMetricsFunc)NULL,

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -18,16 +18,27 @@
#include <ft2build.h>
#include FT_ADVANCES_H
#include FT_INTERNAL_DEBUG_H
#include "aflatin.h"
#include "aferrors.h"
#ifdef AF_USE_WARPER
#ifdef AF_CONFIG_OPTION_USE_WARPER
#include "afwarp.h"
#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_aflatin
/*************************************************************************/
/*************************************************************************/
/***** *****/
@ -36,6 +47,10 @@
/*************************************************************************/
/*************************************************************************/
/* Find segments and links, compute all stem widths, and initialize */
/* standard width and height for the glyph with given charcode. */
FT_LOCAL_DEF( void )
af_latin_metrics_init_widths( AF_LatinMetrics metrics,
FT_Face face,
@ -69,8 +84,12 @@
FT_ZERO( dummy );
dummy->units_per_em = metrics->units_per_em;
scaler->x_scale = scaler->y_scale = 0x10000L;
scaler->x_delta = scaler->y_delta = 0;
scaler->x_scale = 0x10000L;
scaler->y_scale = 0x10000L;
scaler->x_delta = 0;
scaler->y_delta = 0;
scaler->face = face;
scaler->render_mode = FT_RENDER_MODE_NORMAL;
scaler->flags = 0;
@ -115,7 +134,7 @@
dist = -dist;
if ( num_widths < AF_LATIN_MAX_WIDTHS )
axis->widths[ num_widths++ ].org = dist;
axis->widths[num_widths++].org = dist;
}
}
@ -161,6 +180,9 @@
};
/* Find all blue zones. Flat segments give the reference points, */
/* round segments the overshoot positions. */
static void
af_latin_metrics_init_blues( AF_LatinMetrics metrics,
FT_Face face )
@ -177,11 +199,11 @@
/* we compute the blues simply by loading each character from the */
/* 'af_latin_blue_chars[blues]' string, then compute its top-most or */
/* `af_latin_blue_chars[blues]' string, then finding its top-most or */
/* bottom-most points (depending on `AF_IS_TOP_BLUE') */
AF_LOG(( "blue zones computation\n" ));
AF_LOG(( "------------------------------------------------\n" ));
FT_TRACE5(( "blue zones computation\n" ));
FT_TRACE5(( "------------------------------------------------\n" ));
for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
{
@ -191,7 +213,7 @@
FT_Pos* blue_shoot;
AF_LOG(( "blue %3d: ", bb ));
FT_TRACE5(( "blue %3d: ", bb ));
num_flats = 0;
num_rounds = 0;
@ -205,7 +227,7 @@
FT_Bool round = 0;
AF_LOG(( "'%c'", *p ));
FT_TRACE5(( "'%c'", *p ));
/* load the character in the face -- skip unknown or empty ones */
glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
@ -229,7 +251,9 @@
FT_Int last = -1;
for ( nn = 0; nn < glyph->outline.n_contours; first = last+1, nn++ )
for ( nn = 0;
nn < glyph->outline.n_contours;
first = last + 1, nn++ )
{
FT_Int old_best_point = best_point;
FT_Int pp;
@ -268,7 +292,7 @@
best_last = last;
}
}
AF_LOG(( "%5d", best_y ));
FT_TRACE5(( "%5d", best_y ));
}
/* now check whether the point belongs to a straight or round */
@ -311,12 +335,12 @@
} while ( next != best_point );
/* now, set the `round' flag depending on the segment's kind */
/* now set the `round' flag depending on the segment's kind */
round = FT_BOOL(
FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_CURVE_TAG_ON ||
FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_CURVE_TAG_ON );
AF_LOG(( "%c ", round ? 'r' : 'f' ));
FT_TRACE5(( "%c ", round ? 'r' : 'f' ));
}
if ( round )
@ -325,7 +349,7 @@
flats[num_flats++] = best_y;
}
AF_LOG(( "\n" ));
FT_TRACE5(( "\n" ));
if ( num_flats == 0 && num_rounds == 0 )
{
@ -333,7 +357,7 @@
* we couldn't find a single glyph to compute this blue zone,
* we will simply ignore it then
*/
AF_LOG(( "empty\n" ));
FT_TRACE5(( "empty\n" ));
continue;
}
@ -343,9 +367,9 @@
af_sort_pos( num_rounds, rounds );
af_sort_pos( num_flats, flats );
blue = & axis->blues[axis->blue_count];
blue_ref = & blue->ref.org;
blue_shoot = & blue->shoot.org;
blue = &axis->blues[axis->blue_count];
blue_ref = &blue->ref.org;
blue_shoot = &blue->shoot.org;
axis->blue_count++;
@ -376,7 +400,8 @@
if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref )
*blue_shoot = *blue_ref = ( shoot + ref ) / 2;
*blue_ref =
*blue_shoot = ( shoot + ref ) / 2;
}
blue->flags = 0;
@ -391,13 +416,17 @@
if ( bb == AF_LATIN_BLUE_SMALL_TOP )
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 ));
}
FT_TRACE5(( "\n" ));
return;
}
/* Check whether all ASCII digits have the same advance width. */
FT_LOCAL_DEF( void )
af_latin_metrics_check_digits( AF_LatinMetrics metrics,
FT_Face face )
@ -407,7 +436,6 @@
FT_Fixed advance, old_advance = 0;
/* check whether all ASCII digits have the same advance width; */
/* digit `0' is 0x30 in all supported charmaps */
for ( i = 0x30; i <= 0x39; i++ )
{
@ -444,6 +472,8 @@
}
/* Initialize global metrics. */
FT_LOCAL_DEF( FT_Error )
af_latin_metrics_init( AF_LatinMetrics metrics,
FT_Face face )
@ -458,6 +488,7 @@
FT_ENCODING_APPLE_ROMAN,
FT_ENCODING_ADOBE_STANDARD,
FT_ENCODING_ADOBE_LATIN_1,
FT_ENCODING_NONE /* end of list */
};
@ -485,6 +516,9 @@
}
/* Adjust scaling value, then scale and shift widths */
/* and blue zones (if applicable) for given dimension. */
static void
af_latin_metrics_scale_dim( AF_LatinMetrics metrics,
AF_Scaler scaler,
@ -550,12 +584,10 @@
else
#endif
if ( dim == AF_DIMENSION_VERT )
{
scale = FT_MulDiv( scale, fitted, scaled );
}
}
}
}
axis->scale = scale;
axis->delta = delta;
@ -571,7 +603,7 @@
metrics->root.scaler.y_delta = delta;
}
/* scale the standard widths */
/* scale the widths */
for ( nn = 0; nn < axis->width_count; nn++ )
{
AF_Width width = axis->widths + nn;
@ -582,7 +614,7 @@
}
/* an extra-light axis corresponds to a standard width that is */
/* smaller than 0.75 pixels */
/* smaller than 5/8 pixels */
axis->extra_light =
(FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 );
@ -605,9 +637,17 @@
dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale );
if ( dist <= 48 && dist >= -48 )
{
FT_Pos delta1, delta2;
#if 0
FT_Pos delta1;
#endif
FT_Pos delta2;
/* use discrete values for blue zone widths */
#if 0
/* generic, original code */
delta1 = blue->shoot.org - blue->ref.org;
delta2 = delta1;
if ( delta1 < 0 )
@ -628,6 +668,28 @@
blue->ref.fit = FT_PIX_ROUND( blue->ref.cur );
blue->shoot.fit = blue->ref.fit + delta2;
#else
/* simplified version due to abs(dist) <= 48 */
delta2 = dist;
if ( dist < 0 )
delta2 = -delta2;
if ( delta2 < 32 )
delta2 = 0;
else if ( delta < 48 )
delta2 = 32;
else
delta2 = 64;
if ( dist < 0 )
delta2 = -delta2;
blue->ref.fit = FT_PIX_ROUND( blue->ref.cur );
blue->shoot.fit = blue->ref.fit - delta2;
#endif
blue->flags |= AF_LATIN_BLUE_ACTIVE;
}
}
@ -635,6 +697,8 @@
}
/* Scale global values in both directions. */
FT_LOCAL_DEF( void )
af_latin_metrics_scale( AF_LatinMetrics metrics,
AF_Scaler scaler )
@ -655,6 +719,9 @@
/*************************************************************************/
/*************************************************************************/
/* Walk over all contours and compute its segments. */
FT_LOCAL_DEF( FT_Error )
af_latin_hints_compute_segments( AF_GlyphHints hints,
AF_Dimension dim )
@ -808,7 +875,6 @@
min_pos = max_pos = point->u;
segment->first = point;
segment->last = point;
segment->contour = contour;
on_edge = 1;
}
@ -874,6 +940,8 @@
}
/* Link segments to form stems and serifs. */
FT_LOCAL_DEF( void )
af_latin_hints_link_segments( AF_GlyphHints hints,
AF_Dimension dim )
@ -899,18 +967,18 @@
if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )
continue;
/* search for stems having opposite directions, */
/* with seg1 to the `left' of seg2 */
for ( seg2 = segments; seg2 < segment_limit; seg2++ )
if ( seg1->dir + seg2->dir == 0 && seg2->pos > seg1->pos )
{
FT_Pos pos1 = seg1->pos;
FT_Pos pos2 = seg2->pos;
FT_Pos dist = pos2 - pos1;
if ( dist < 0 )
dist = -dist;
if ( seg1->dir + seg2->dir == 0 && pos2 > pos1 )
{
/* compute distance between the two segments */
FT_Pos dist = pos2 - pos1;
FT_Pos min = seg1->min_coord;
FT_Pos max = seg1->max_coord;
FT_Pos len, score;
@ -922,11 +990,16 @@
if ( max > seg2->max_coord )
max = seg2->max_coord;
/* compute maximum coordinate difference of the two segments */
len = max - min;
if ( len >= len_threshold )
{
/* small coordinate differences cause a higher score, and */
/* segments with a greater distance cause a higher score also */
score = dist + len_score / len;
/* and we search for the smallest score */
/* of the sum of the two values */
if ( score < seg1->score )
{
seg1->score = score;
@ -943,7 +1016,7 @@
}
}
/* now, compute the `serif' segments */
/* now compute the `serif' segments, cf. explanations in `afhints.h' */
for ( seg1 = segments; seg1 < segment_limit; seg1++ )
{
seg2 = seg1->link;
@ -960,6 +1033,8 @@
}
/* Link segments to edges, using feature analysis for selection. */
FT_LOCAL_DEF( FT_Error )
af_latin_hints_compute_edges( AF_GlyphHints hints,
AF_Dimension dim )
@ -973,7 +1048,9 @@
AF_Segment segment_limit = segments + axis->num_segments;
AF_Segment seg;
#if 0
AF_Direction up_dir;
#endif
FT_Fixed scale;
FT_Pos edge_distance_threshold;
FT_Pos segment_length_threshold;
@ -984,11 +1061,13 @@
scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale
: hints->y_scale;
#if 0
up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP
: AF_DIR_RIGHT;
#endif
/*
* We ignore all segments that are less than 1 pixels in length,
* We ignore all segments that are less than 1 pixel in length
* to avoid many problems with serif fonts. We compute the
* corresponding threshold in font units.
*/
@ -999,20 +1078,21 @@
/*********************************************************************/
/* */
/* We will begin by generating a sorted table of edges for the */
/* current direction. To do so, we simply scan each segment and try */
/* to find an edge in our table that corresponds to its position. */
/* We begin by generating a sorted table of edges for the current */
/* direction. To do so, we simply scan each segment and try to find */
/* an edge in our table that corresponds to its position. */
/* */
/* If no edge is found, we create and insert a new edge in the */
/* sorted table. Otherwise, we simply add the segment to the edge's */
/* list which will be processed in the second step to compute the */
/* list which gets processed in the second step to compute the */
/* edge's properties. */
/* */
/* Note that the edges table is sorted along the segment/edge */
/* Note that the table of edges is sorted along the segment/edge */
/* position. */
/* */
/*********************************************************************/
/* assure that edge distance threshold is at most 0.25px */
edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold,
scale );
if ( edge_distance_threshold > 64 / 4 )
@ -1023,7 +1103,7 @@
for ( seg = segments; seg < segment_limit; seg++ )
{
AF_Edge found = 0;
AF_Edge found = NULL;
FT_Int ee;
@ -1072,9 +1152,10 @@
edge->first = seg;
edge->last = seg;
edge->fpos = seg->pos;
edge->dir = seg->dir;
edge->opos = edge->pos = FT_MulFix( seg->pos, scale );
edge->fpos = seg->pos;
edge->opos = FT_MulFix( seg->pos, scale );
edge->pos = edge->opos;
seg->edge_next = seg;
}
else
@ -1091,9 +1172,9 @@
/*********************************************************************/
/* */
/* Good, we will now compute each edge's properties according to */
/* segments found on its position. Basically, these are: */
/* the segments found on its position. Basically, these are */
/* */
/* - edge's main direction */
/* - the edge's main direction */
/* - stem edge, serif edge or both (which defaults to stem then) */
/* - rounded edge, straight or both (which defaults to straight) */
/* - link for edge */
@ -1126,13 +1207,15 @@
} while ( seg != edge->first );
}
/* now, compute each edge properties */
/* now compute each edge properties */
for ( edge = edges; edge < edge_limit; edge++ )
{
FT_Int is_round = 0; /* does it contain round segments? */
FT_Int is_straight = 0; /* does it contain straight segments? */
#if 0
FT_Pos ups = 0; /* number of upwards segments */
FT_Pos downs = 0; /* number of downwards segments */
#endif
seg = edge->first;
@ -1148,11 +1231,13 @@
else
is_straight++;
#if 0
/* check for segment direction */
if ( seg->dir == up_dir )
ups += seg->max_coord-seg->min_coord;
ups += seg->max_coord - seg->min_coord;
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 */
/* be ignored */
@ -1228,7 +1313,7 @@
edge->dir = 0; /* both up and down! */
#endif
/* gets rid of serifs if link is set */
/* get rid of serifs if link is set */
/* XXX: This gets rid of many unpleasant artefacts! */
/* Example: the `c' in cour.pfa at size 13 */
@ -1242,6 +1327,8 @@
}
/* Detect segments and edges for given dimension. */
FT_LOCAL_DEF( FT_Error )
af_latin_hints_detect_features( AF_GlyphHints hints,
AF_Dimension dim )
@ -1256,18 +1343,21 @@
error = af_latin_hints_compute_edges( hints, dim );
}
return error;
}
/* Compute all edges which lie within blue zones. */
FT_LOCAL_DEF( void )
af_latin_hints_compute_blue_edges( AF_GlyphHints hints,
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_limit = edge + axis->num_edges;
AF_LatinAxis latin = &metrics->axis[ AF_DIMENSION_VERT ];
AF_LatinAxis latin = &metrics->axis[AF_DIMENSION_VERT];
FT_Fixed scale = latin->scale;
@ -1283,8 +1373,10 @@
/* compute the initial threshold as a fraction of the EM size */
/* (the value 40 is heuristic) */
best_dist = FT_MulFix( metrics->units_per_em / 40, scale );
/* assure a minimum distance of 0.5px */
if ( best_dist > 64 / 2 )
best_dist = 64 / 2;
@ -1294,7 +1386,7 @@
FT_Bool is_top_blue, is_major_dir;
/* skip inactive blue zones (i.e., those that are too small) */
/* skip inactive blue zones (i.e., those that are too large) */
if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) )
continue;
@ -1322,12 +1414,13 @@
if ( dist < best_dist )
{
best_dist = dist;
best_blue = & blue->ref;
best_blue = &blue->ref;
}
/* now, compare it to the overshoot position if the edge is */
/* rounded, and if the edge is over the reference position of a */
/* top zone, or under the reference position of a bottom zone */
/* now compare it to the overshoot position and check whether */
/* the edge is rounded, and whether the edge is over the */
/* reference position of a top zone, or under the reference */
/* position of a bottom zone */
if ( edge->flags & AF_EDGE_ROUND && dist != 0 )
{
FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org );
@ -1335,7 +1428,6 @@
if ( is_top_blue ^ is_under_ref )
{
blue = latin->blues + bb;
dist = edge->fpos - blue->shoot.org;
if ( dist < 0 )
dist = -dist;
@ -1344,7 +1436,7 @@
if ( dist < best_dist )
{
best_dist = dist;
best_blue = & blue->shoot;
best_blue = &blue->shoot;
}
}
}
@ -1357,6 +1449,8 @@
}
/* Initalize hinting engine. */
static FT_Error
af_latin_hints_init( AF_GlyphHints hints,
AF_LatinMetrics metrics )
@ -1370,7 +1464,7 @@
/*
* correct x_scale and y_scale if needed, since they may have
* been modified `af_latin_metrics_scale_dim' above
* been modified by `af_latin_metrics_scale_dim' above
*/
hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale;
hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta;
@ -1380,7 +1474,7 @@
/* compute flags depending on render mode, etc. */
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 )
{
metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
@ -1418,13 +1512,13 @@
* We also do it if the face is italic.
*/
if ( mode == FT_RENDER_MODE_LIGHT ||
(face->style_flags & FT_STYLE_FLAG_ITALIC) != 0 )
( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 )
scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
hints->scaler_flags = scaler_flags;
hints->other_flags = other_flags;
return 0;
return AF_Err_Ok;
}
@ -1436,8 +1530,8 @@
/*************************************************************************/
/*************************************************************************/
/* snap a given width in scaled coordinates to one of the */
/* current standard widths */
/* Snap a given width in scaled coordinates to one of the */
/* current standard widths. */
static FT_Pos
af_latin_snap_width( AF_Width widths,
@ -1484,7 +1578,9 @@
}
/* compute the snapped width of a given stem */
/* Compute the snapped width of a given stem, ignoring very thin ones. */
/* There is a lot of voodoo in this function; changing the hard-coded */
/* parameters influence the whole hinting process. */
static FT_Pos
af_latin_compute_stem_width( AF_GlyphHints hints,
@ -1516,11 +1612,12 @@
/* smooth hinting process: very lightly quantize the stem width */
/* leave the widths of serifs alone */
if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )
if ( ( stem_flags & AF_EDGE_SERIF ) &&
vertical &&
( dist < 3 * 64 ) )
goto Done_Width;
else if ( ( base_flags & AF_EDGE_ROUND ) )
else if ( base_flags & AF_EDGE_ROUND )
{
if ( dist < 80 )
dist = 64;
@ -1572,6 +1669,7 @@
else
{
/* strong hinting process: snap the stem width to integer pixels */
FT_Pos org_dist = dist;
@ -1646,7 +1744,7 @@
}
/* align one stem edge relative to the previous stem edge */
/* Align one stem edge relative to the previous stem edge. */
static void
af_latin_align_linked_edge( AF_GlyphHints hints,
@ -1664,13 +1762,16 @@
stem_edge->pos = base_edge->pos + fitted_width;
AF_LOG(( "LINK: edge %d (opos=%.2f) linked to (%.2f), "
"dist was %.2f, now %.2f\n",
FT_TRACE5(( " LINK: edge %d (opos=%.2f) linked to (%.2f),"
" dist was %.2f, now %.2f\n",
stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,
stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
}
/* Shift the coordinates of the `serif' edge by the same amount */
/* as the corresponding `base' edge has been moved already. */
static void
af_latin_align_serif_edge( AF_GlyphHints hints,
AF_Edge base,
@ -1678,7 +1779,7 @@
{
FT_UNUSED( hints );
serif->pos = base->pos + (serif->opos - base->opos);
serif->pos = base->pos + ( serif->opos - base->opos );
}
@ -1693,6 +1794,8 @@
/*************************************************************************/
/* The main grid-fitting routine. */
FT_LOCAL_DEF( void )
af_latin_hint_edges( AF_GlyphHints hints,
AF_Dimension dim )
@ -1702,10 +1805,13 @@
AF_Edge edge_limit = edges + axis->num_edges;
FT_PtrDist n_edges;
AF_Edge edge;
AF_Edge anchor = 0;
AF_Edge anchor = NULL;
FT_Int has_serifs = 0;
FT_TRACE5(("%s edge hinting\n", dim == AF_DIMENSION_VERT ? "horizontal"
: "vertical"));
/* we begin by aligning all stems relative to the blue zone */
/* if needed -- that's only for horizontal edges */
@ -1714,7 +1820,7 @@
for ( edge = edges; edge < edge_limit; edge++ )
{
AF_Width blue;
AF_Edge edge1, edge2;
AF_Edge edge1, edge2; /* these edges form the stem to check */
if ( edge->flags & AF_EDGE_DONE )
@ -1725,9 +1831,9 @@
edge2 = edge->link;
if ( blue )
{
edge1 = edge;
}
/* flip edges if the other stem is aligned to a blue zone */
else if ( edge2 && edge2->blue_edge )
{
blue = edge2->blue_edge;
@ -1738,9 +1844,9 @@
if ( !edge1 )
continue;
AF_LOG(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), "
"was (%.2f)\n",
edge1-edges, edge1->opos / 64.0, blue->fit / 64.0,
FT_TRACE5(( " BLUE: edge %d (opos=%.2f) snapped to (%.2f),"
" was (%.2f)\n",
edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
edge1->pos / 64.0 ));
edge1->pos = blue->fit;
@ -1757,7 +1863,7 @@
}
}
/* now we will align all stem edges, trying to maintain the */
/* now we align all other stem edges, trying to maintain the */
/* relative order of stems in the glyph */
for ( edge = edges; edge < edge_limit; edge++ )
{
@ -1780,7 +1886,7 @@
/* this should not happen, but it's better to be safe */
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_latin_align_linked_edge( hints, dim, edge2, edge );
edge->flags |= AF_EDGE_DONE;
@ -1789,6 +1895,8 @@
if ( !anchor )
{
/* if we reach this if clause, no stem has been aligned yet */
FT_Pos org_len, org_center, cur_len;
FT_Pos cur_pos1, error1, error2, u_off, d_off;
@ -1798,10 +1906,19 @@
hints, dim, org_len,
(AF_Edge_Flags)edge->flags,
(AF_Edge_Flags)edge2->flags );
/* some voodoo to specially round edges for small stem widths; */
/* the idea is to align the center of a stem, then shifting */
/* the stem edges to suitable positions */
if ( cur_len <= 64 )
u_off = d_off = 32;
{
/* width <= 1px */
u_off = 32;
d_off = 32;
}
else
{
/* 1px < width < 1.5px */
u_off = 38;
d_off = 26;
}
@ -1809,7 +1926,6 @@
if ( cur_len < 96 )
{
org_center = edge->opos + ( org_len >> 1 );
cur_pos1 = FT_PIX_ROUND( org_center );
error1 = org_center - ( cur_pos1 - u_off );
@ -1831,10 +1947,10 @@
else
edge->pos = FT_PIX_ROUND( edge->opos );
AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) "
"snapped to (%.2f) (%.2f)\n",
edge-edges, edge->opos / 64.0,
edge2-edges, edge2->opos / 64.0,
FT_TRACE5(( " ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)"
" snapped to (%.2f) (%.2f)\n",
edge - edges, edge->opos / 64.0,
edge2 - edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 ));
anchor = edge;
@ -1858,7 +1974,13 @@
(AF_Edge_Flags)edge2->flags );
if ( edge2->flags & AF_EDGE_DONE )
{
FT_TRACE5(( " ADJUST: edge %d (pos=%.2f) moved to %.2f\n",
edge - edges, edge->pos / 64.0,
( edge2->pos - cur_len ) / 64.0 ));
edge->pos = edge2->pos - cur_len;
}
else if ( cur_len < 96 )
{
@ -1868,7 +1990,10 @@
cur_pos1 = FT_PIX_ROUND( org_center );
if (cur_len <= 64 )
u_off = d_off = 32;
{
u_off = 32;
d_off = 32;
}
else
{
u_off = 38;
@ -1891,10 +2016,10 @@
edge->pos = cur_pos1 - cur_len / 2;
edge2->pos = cur_pos1 + cur_len / 2;
AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) "
"snapped to (%.2f) and (%.2f)\n",
edge-edges, edge->opos / 64.0,
edge2-edges, edge2->opos / 64.0,
FT_TRACE5(( " STEM: %d (opos=%.2f) to %d (opos=%.2f)"
" snapped to (%.2f) and (%.2f)\n",
edge - edges, edge->opos / 64.0,
edge2 - edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 ));
}
else
@ -1921,10 +2046,10 @@
edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
edge2->pos = edge->pos + cur_len;
AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) "
"snapped to (%.2f) and (%.2f)\n",
edge-edges, edge->opos / 64.0,
edge2-edges, edge2->opos / 64.0,
FT_TRACE5(( " STEM: %d (opos=%.2f) to %d (opos=%.2f)"
" snapped to (%.2f) and (%.2f)\n",
edge - edges, edge->opos / 64.0,
edge2 - edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 ));
}
@ -1933,8 +2058,8 @@
if ( edge > edges && edge->pos < edge[-1].pos )
{
AF_LOG(( "BOUND: %d (pos=%.2f) to (%.2f)\n",
edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
FT_TRACE5(( " BOUND: %d (pos=%.2f) to (%.2f)\n",
edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
edge->pos = edge[-1].pos;
}
}
@ -2028,18 +2153,19 @@
if ( delta < 64 + 16 )
{
af_latin_align_serif_edge( hints, edge->serif, edge );
AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) "
"aligned to (%.2f)\n",
edge-edges, edge->opos / 64.0,
FT_TRACE5(( " SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)"
" aligned to (%.2f)\n",
edge - edges, edge->opos / 64.0,
edge->serif - edges, edge->serif->opos / 64.0,
edge->pos / 64.0 ));
}
else if ( !anchor )
{
AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
edge->pos = FT_PIX_ROUND( edge->opos );
anchor = edge;
FT_TRACE5(( " SERIF_ANCHOR: edge %d (opos=%.2f)"
" snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
}
else
{
@ -2064,18 +2190,21 @@
FT_MulDiv( edge->opos - before->opos,
after->pos - before->pos,
after->opos - before->opos );
AF_LOG(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f) "
"from %d (opos=%.2f)\n",
edge-edges, edge->opos / 64.0,
edge->pos / 64.0, before - edges,
before->opos / 64.0 ));
FT_TRACE5(( " SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)"
" from %d (opos=%.2f)\n",
edge - edges, edge->opos / 64.0,
edge->pos / 64.0,
before - edges, before->opos / 64.0 ));
}
else
{
edge->pos = anchor->pos +
( ( edge->opos - anchor->opos + 16 ) & ~31 );
AF_LOG(( "SERIF_LINK2: edge %d (opos=%.2f) snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
FT_TRACE5(( " SERIF_LINK2: edge %d (opos=%.2f)"
" snapped to (%.2f)\n",
edge - edges, edge->opos / 64.0, edge->pos / 64.0 ));
}
}
@ -2090,9 +2219,13 @@
edge->pos = edge[1].pos;
}
}
FT_TRACE5(( "\n" ));
}
/* Apply the complete hinting algorithm to a latin glyph. */
static FT_Error
af_latin_hints_apply( AF_GlyphHints hints,
FT_Outline* outline,
@ -2107,7 +2240,7 @@
goto Exit;
/* analyze glyph outline */
#ifdef AF_USE_WARPER
#ifdef AF_CONFIG_OPTION_USE_WARPER
if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ||
AF_HINTS_DO_HORIZONTAL( hints ) )
#else
@ -2131,17 +2264,19 @@
/* grid-fit the outline */
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
{
#ifdef AF_USE_WARPER
if ( ( dim == AF_DIMENSION_HORZ &&
metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) )
#ifdef AF_CONFIG_OPTION_USE_WARPER
if ( dim == AF_DIMENSION_HORZ &&
metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT )
{
AF_WarperRec warper;
FT_Fixed scale;
FT_Pos delta;
af_warper_compute( &warper, hints, dim, &scale, &delta );
af_glyph_hints_scale_dim( hints, dim, scale, delta );
af_warper_compute( &warper, hints, (AF_Dimension)dim,
&scale, &delta );
af_glyph_hints_scale_dim( hints, (AF_Dimension)dim,
scale, delta );
continue;
}
#endif

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -30,7 +30,7 @@ FT_BEGIN_HEADER
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 ) \
( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 )
@ -76,8 +76,8 @@ FT_BEGIN_HEADER
enum
{
AF_LATIN_BLUE_ACTIVE = 1 << 0,
AF_LATIN_BLUE_TOP = 1 << 1,
AF_LATIN_BLUE_ACTIVE = 1 << 0, /* set if zone height is <= 3/4px */
AF_LATIN_BLUE_TOP = 1 << 1, /* result of AF_LATIN_IS_TOP_BLUE */
AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, /* used for scale adjustment */
/* optimization */
AF_LATIN_BLUE_FLAG_MAX
@ -98,14 +98,13 @@ FT_BEGIN_HEADER
FT_Fixed scale;
FT_Pos delta;
FT_UInt width_count;
AF_WidthRec widths[AF_LATIN_MAX_WIDTHS];
FT_Pos edge_distance_threshold;
FT_Pos standard_width;
FT_Bool extra_light;
FT_UInt width_count; /* number of used widths */
AF_WidthRec widths[AF_LATIN_MAX_WIDTHS]; /* widths array */
FT_Pos edge_distance_threshold; /* used for creating edges */
FT_Pos standard_width; /* the default stem thickness */
FT_Bool extra_light; /* is standard width very light? */
/* ignored for horizontal metrics */
FT_Bool control_overshoot;
FT_UInt blue_count;
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). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by */
/* Copyright 2003-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -23,10 +23,21 @@
#include "aferrors.h"
#ifdef AF_USE_WARPER
#ifdef AF_CONFIG_OPTION_USE_WARPER
#include "afwarp.h"
#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 )
af_latin2_hints_compute_segments( AF_GlyphHints hints,
AF_Dimension dim );
@ -156,7 +167,8 @@
#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",
"HEZLOCUS",
@ -186,8 +198,8 @@
/* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */
/* bottom-most points (depending on `AF_IS_TOP_BLUE') */
AF_LOG(( "blue zones computation\n" ));
AF_LOG(( "------------------------------------------------\n" ));
FT_TRACE5(( "blue zones computation\n" ));
FT_TRACE5(( "------------------------------------------------\n" ));
for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
{
@ -197,7 +209,7 @@
FT_Pos* blue_shoot;
AF_LOG(( "blue %3d: ", bb ));
FT_TRACE5(( "blue %3d: ", bb ));
num_flats = 0;
num_rounds = 0;
@ -210,7 +222,7 @@
FT_Bool round;
AF_LOG(( "'%c'", *p ));
FT_TRACE5(( "'%c'", *p ));
/* load the character in the face -- skip unknown or empty ones */
glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
@ -273,7 +285,7 @@
best_last = last;
}
}
AF_LOG(( "%5d", best_y ));
FT_TRACE5(( "%5d", best_y ));
}
/* 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[ end ] ) != FT_CURVE_TAG_ON );
AF_LOG(( "%c ", round ? 'r' : 'f' ));
FT_TRACE5(( "%c ", round ? 'r' : 'f' ));
}
if ( round )
@ -330,7 +342,7 @@
flats[num_flats++] = best_y;
}
AF_LOG(( "\n" ));
FT_TRACE5(( "\n" ));
if ( num_flats == 0 && num_rounds == 0 )
{
@ -338,7 +350,7 @@
* we couldn't find a single glyph to compute this blue zone,
* we will simply ignore it then
*/
AF_LOG(( "empty\n" ));
FT_TRACE5(( "empty\n" ));
continue;
}
@ -396,7 +408,7 @@
if ( bb == AF_LATIN_BLUE_SMALL_TOP )
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;
@ -548,7 +560,10 @@
if ( scaled != fitted )
{
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
}
@ -579,7 +594,7 @@
}
/* an extra-light axis corresponds to a standard width that is */
/* smaller than 0.75 pixels */
/* smaller than 5/8 pixels */
axis->extra_light =
(FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 );
@ -624,9 +639,11 @@
blue->ref.fit = FT_PIX_ROUND( blue->ref.cur );
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",
nn, blue->ref.cur/64.0, blue->ref.fit/64.0,
blue->shoot.cur/64.0, blue->shoot.fit/64.0 ));
FT_TRACE5(( ">> activating blue zone %d:"
" ref.cur=%.2g ref.fit=%.2g"
" 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;
}
@ -779,7 +796,6 @@
segment->dir = first->out_dir;
segment->first = first;
segment->last = point;
segment->contour = contour;
segment->pos = (FT_Short)(( min_u + max_u ) >> 1);
segment->min_coord = (FT_Short) min_v;
segment->max_coord = (FT_Short) max_v;
@ -1137,7 +1153,8 @@
/* insert a new edge in the list and */
/* 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 )
goto Exit;
@ -1205,8 +1222,10 @@
{
FT_Int is_round = 0; /* does it contain round segments? */
FT_Int is_straight = 0; /* does it contain straight segments? */
#if 0
FT_Pos ups = 0; /* number of upwards segments */
FT_Pos downs = 0; /* number of downwards segments */
#endif
seg = edge->first;
@ -1222,11 +1241,13 @@
else
is_straight++;
#if 0
/* check for segment direction */
if ( seg->dir == up_dir )
ups += seg->max_coord-seg->min_coord;
else
downs += seg->max_coord-seg->min_coord;
#endif
/* check for links -- if seg->serif is set, then seg->link must */
/* be ignored */
@ -1463,7 +1484,7 @@
/* compute flags depending on render mode, etc. */
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 )
{
metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
@ -1753,7 +1774,7 @@
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",
stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,
stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
@ -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 */
/* if needed -- that's only for horizontal edges */
@ -1830,7 +1852,7 @@
if ( !edge1 )
continue;
AF_LOG(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), "
FT_TRACE5(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), "
"was (%.2f)\n",
edge1-edges, edge1->opos / 64.0, blue->fit / 64.0,
edge1->pos / 64.0 ));
@ -1878,7 +1900,7 @@
/* this should not happen, but it's better to be safe */
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 );
edge->flags |= AF_EDGE_DONE;
@ -1929,8 +1951,8 @@
else
edge->pos = FT_PIX_ROUND( edge->opos );
AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) "
"snapped to (%.2f) (%.2f)\n",
FT_TRACE5(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)"
" snapped to (%.2f) (%.2f)\n",
edge-edges, edge->opos / 64.0,
edge2-edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 ));
@ -1945,7 +1967,7 @@
anchor_drift = ( (anchor->pos - anchor->opos) +
(edge2->pos - edge2->opos)) >> 1;
AF_LOG(( "DRIFT: %.2f\n", anchor_drift/64.0 ));
FT_TRACE5(( "DRIFT: %.2f\n", anchor_drift/64.0 ));
}
else
{
@ -1965,12 +1987,13 @@
org_left = 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;
if ( edge2->flags & AF_EDGE_DONE )
{
AF_LOG(( "\n" ));
FT_TRACE5(( "\n" ));
edge->pos = edge2->pos - cur_len;
}
else
@ -1985,14 +2008,14 @@
/* note: don't even try to fit tiny stems */
if ( cur_len < 32 )
{
AF_LOG(( "tiny stem\n" ));
FT_TRACE5(( "tiny stem\n" ));
goto AlignStem;
}
/* if the span is within a single pixel, don't touch it */
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;
}
@ -2015,14 +2038,14 @@
delta = FT_ABS(fit - org);
displacements[count] = fit - org;
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;
fit = (org <= 32) ? 16 : 48;
delta = FT_ABS(fit - org);
displacements[count] = fit - org;
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);
displacements[count] = fit - org;
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 */
org = org_right;
@ -2040,7 +2063,7 @@
delta = FT_ABS(fit - org);
displacements[count] = fit - org;
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 */
{
@ -2059,15 +2082,16 @@
cur_center = org_center + best_disp;
}
AF_LOG(( "\n" ));
FT_TRACE5(( "\n" ));
}
AlignStem:
edge->pos = cur_center - (cur_len >> 1);
edge2->pos = edge->pos + cur_len;
AF_LOG(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f) "
"snapped to (%.2f) and (%.2f), org_len = %.2f cur_len=%.2f\n",
FT_TRACE5(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f)"
" snapped to (%.2f) and (%.2f),"
" org_len=%.2f cur_len=%.2f\n",
edge-edges, edge->opos / 64.0,
edge2-edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0,
@ -2078,7 +2102,7 @@
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->pos = edge[-1].pos;
}
@ -2179,15 +2203,16 @@
if ( delta < 64 + 16 )
{
af_latin2_align_serif_edge( hints, edge->serif, edge );
AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) "
"aligned to (%.2f)\n",
FT_TRACE5(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)"
" aligned to (%.2f)\n",
edge-edges, edge->opos / 64.0,
edge->serif - edges, edge->serif->opos / 64.0,
edge->pos / 64.0 ));
}
else if ( !anchor )
{
AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n",
FT_TRACE5(( "SERIF_ANCHOR: edge %d (opos=%.2f)"
" snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
edge->pos = FT_PIX_ROUND( edge->opos );
anchor = edge;
@ -2215,14 +2240,18 @@
FT_MulDiv( edge->opos - before->opos,
after->pos - before->pos,
after->opos - before->opos );
AF_LOG(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f) from %d (opos=%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0, before - edges, before->opos / 64.0 ));
FT_TRACE5(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)"
" from %d (opos=%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0,
before - edges, before->opos / 64.0 ));
}
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)"
" snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
}
}
@ -2255,7 +2284,7 @@
goto Exit;
/* analyze glyph outline */
#ifdef AF_USE_WARPER
#ifdef AF_CONFIG_OPTION_USE_WARPER
if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ||
AF_HINTS_DO_HORIZONTAL( hints ) )
#else
@ -2279,7 +2308,7 @@
/* grid-fit the outline */
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
{
#ifdef AF_USE_WARPER
#ifdef AF_CONFIG_OPTION_USE_WARPER
if ( ( dim == AF_DIMENSION_HORZ &&
metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) )
{
@ -2321,7 +2350,7 @@
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( 0UL, 0UL )
};

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -22,6 +22,8 @@
#include "aferrors.h"
/* Initialize glyph loader. */
FT_LOCAL_DEF( FT_Error )
af_loader_init( AF_Loader loader,
FT_Memory memory )
@ -29,13 +31,15 @@
FT_ZERO( loader );
af_glyph_hints_init( &loader->hints, memory );
#ifdef AF_DEBUG
#ifdef FT_DEBUG_AUTOFIT
_af_debug_hints = &loader->hints;
#endif
return FT_GlyphLoader_New( memory, &loader->gloader );
}
/* Reset glyph loader and compute globals if necessary. */
FT_LOCAL_DEF( FT_Error )
af_loader_reset( AF_Loader loader,
FT_Face face )
@ -64,6 +68,8 @@
}
/* Finalize glyph loader. */
FT_LOCAL_DEF( void )
af_loader_done( AF_Loader loader )
{
@ -72,7 +78,7 @@
loader->face = NULL;
loader->globals = NULL;
#ifdef AF_DEBUG
#ifdef FT_DEBUG_AUTOFIT
_af_debug_hints = NULL;
#endif
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
af_loader_load_g( AF_Loader loader,
AF_Scaler scaler,
@ -169,7 +179,7 @@
&gloader->current.outline,
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 */
if ( scaler->render_mode != FT_RENDER_MODE_LIGHT )
{
@ -265,7 +275,7 @@
gloader->current.num_subglyphs = 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++ )
{
FT_Vector pp1, pp2;
@ -305,7 +315,7 @@
num_points = gloader->base.outline.n_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 |
FT_SUBGLYPH_FLAG_XY_SCALE |
@ -459,15 +469,13 @@
slot->format = FT_GLYPH_FORMAT_OUTLINE;
}
#ifdef DEBUG_HINTER
af_debug_hinter = hinter;
#endif
Exit:
return error;
}
/* Load a glyph. */
FT_LOCAL_DEF( FT_Error )
af_loader_load_glyph( AF_Loader loader,
FT_Face face,

View file

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

View file

@ -4,7 +4,7 @@
/* */
/* Auto-fitter module implementation (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006 by */
/* Copyright 2003-2006, 2009, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -20,8 +20,7 @@
#include "afloader.h"
#include "afpic.h"
#ifdef AF_DEBUG
int _af_debug;
#ifdef FT_DEBUG_AUTOFIT
int _af_debug_disable_horz_hints;
int _af_debug_disable_vert_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,
(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,
sizeof ( FT_AutofitterRec ),
@ -87,8 +87,7 @@
(FT_Module_Constructor)af_autofitter_init,
(FT_Module_Destructor) af_autofitter_done,
(FT_Module_Requester) NULL
)
(FT_Module_Requester) NULL )
/* END */

View file

@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for autofit module. */
/* */
/* Copyright 2009, 2010 by */
/* Copyright 2009, 2010, 2011 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -24,7 +24,8 @@
#ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from afmodule.c */
void FT_Init_Class_af_autofitter_service( FT_Library, FT_AutoHinter_ServiceRec*);
void FT_Init_Class_af_autofitter_service( FT_Library,
FT_AutoHinter_ServiceRec* );
/* forward declaration of PIC init functions from script classes */
#include "aflatin.h"
@ -38,6 +39,8 @@
{
FT_PIC_Container* pic_container = &library->pic_container;
FT_Memory memory = library->memory;
if ( pic_container->autofit )
{
FT_FREE( pic_container->autofit );
@ -62,28 +65,37 @@
FT_MEM_SET( container, 0, sizeof ( *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++ )
{
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 */
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
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
FT_Init_Class_af_latin_script_class(&container->af_script_classes_rec[ss++]);
FT_Init_Class_af_cjk_script_class(&container->af_script_classes_rec[ss++]);
FT_Init_Class_af_indic_script_class(&container->af_script_classes_rec[ss++]);
FT_Init_Class_af_latin_script_class(
&container->af_script_classes_rec[ss++] );
FT_Init_Class_af_cjk_script_class(
&container->af_script_classes_rec[ss++] );
FT_Init_Class_af_indic_script_class(
&container->af_script_classes_rec[ss++] );
FT_Init_Class_af_autofitter_service(library, &container->af_autofitter_service);
FT_Init_Class_af_autofitter_service(
library, &container->af_autofitter_service );
/*Exit:*/
if(error)
autofit_module_class_pic_free(library);
/* Exit: */
if ( error )
autofit_module_class_pic_free( library );
return error;
}

View file

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

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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 */
#define xxAF_DEBUG
#ifdef AF_DEBUG
#ifdef FT_DEBUG_AUTOFIT
#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_vert_hints;
extern int _af_debug_disable_blue_hints;
extern void* _af_debug_hints;
#else /* !AF_DEBUG */
#define AF_LOG( x ) do { } while ( 0 ) /* nothing */
#endif /* !AF_DEBUG */
#endif /* FT_DEBUG_AUTOFIT */
/*************************************************************************/
@ -159,36 +149,11 @@ extern void* _af_debug_hints;
FT_END_STMNT
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** O U T L I N E S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* opaque handle to glyph-specific hints -- see `afhints.h' for more
* details
*/
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:
*
* - A set of Unicode ranges to test whether the face supports the
@ -342,15 +307,16 @@ extern void* _af_debug_hints;
} AF_ScriptClassRec;
/* Declare and define vtables for classes */
/* Declare and define vtables for classes */
#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 \
script_class;
#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size, \
m_init, m_scale, m_done, h_init, h_apply) \
#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, m_size, \
m_init, m_scale, m_done, h_init, h_apply ) \
FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec \
script_class = \
{ \
@ -367,16 +333,16 @@ extern void* _af_debug_hints;
h_apply \
};
#else
#else /* FT_CONFIG_OPTION_PIC */
#define AF_DECLARE_SCRIPT_CLASS(script_class) \
FT_LOCAL(void) \
FT_Init_Class_##script_class(AF_ScriptClassRec* ac);
#define AF_DECLARE_SCRIPT_CLASS( script_class ) \
FT_LOCAL( void ) \
FT_Init_Class_##script_class( AF_ScriptClassRec* ac );
#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size, \
m_init, m_scale, m_done, h_init, h_apply) \
FT_LOCAL_DEF(void) \
FT_Init_Class_##script_class(AF_ScriptClassRec* ac) \
#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, m_size, \
m_init, m_scale, m_done, h_init, h_apply ) \
FT_LOCAL_DEF( void ) \
FT_Init_Class_##script_class( AF_ScriptClassRec* ac ) \
{ \
ac->script = script_; \
ac->script_uni_ranges = ranges; \
@ -390,7 +356,8 @@ extern void* _af_debug_hints;
ac->script_hints_init = h_init; \
ac->script_hints_apply = h_apply; \
}
#endif
#endif /* FT_CONFIG_OPTION_PIC */
/* */

View file

@ -4,7 +4,7 @@
/* */
/* Auto-fitter warping algorithm (body). */
/* */
/* Copyright 2006, 2007 by */
/* Copyright 2006, 2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* 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"
#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
static const AF_WarpScore
af_warper_weights[64] =
@ -43,6 +63,11 @@
#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
af_warper_compute_line_best( AF_Warper warper,
FT_Fixed scale,
@ -82,7 +107,7 @@
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"
" x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n",
idx_min, idx_max, xx1, xx2,
@ -100,6 +125,7 @@
FT_Int idx;
/* score the length of the segments for the given range */
for ( idx = idx_min; idx <= idx_max; idx++, y++ )
scores[idx] += af_warper_weights[y & 63] * len;
}
@ -129,6 +155,9 @@
}
/* Compute optimal scaling and delta values for a given glyph and */
/* dimension. */
FT_LOCAL_DEF( void )
af_warper_compute( AF_Warper warper,
AF_GlyphHints hints,
@ -215,6 +244,7 @@
warper->t1 = AF_WARPER_FLOOR( warper->x1 );
warper->t2 = AF_WARPER_CEIL( warper->x2 );
/* examine a half pixel wide range around the maximum coordinates */
warper->x1min = warper->x1 & ~31;
warper->x1max = warper->x1min + 32;
warper->x2min = warper->x2 & ~31;
@ -234,10 +264,12 @@
warper->x2min = warper->x2;
}
/* examine (at most) a pixel wide range around the natural width */
warper->wmin = warper->x2min - warper->x1max;
warper->wmax = warper->x2max - warper->x1min;
#if 1
/* some heuristics to reduce the number of widths to be examined */
{
int margin = 16;
@ -273,6 +305,8 @@
FT_Pos xx1, xx2;
/* compute min and max positions for given width, */
/* assuring that they stay within the coordinate ranges */
xx1 = warper->x1;
xx2 = warper->x2;
if ( w >= warper->w0 )
@ -304,6 +338,7 @@
else
base_distort += xx2 - warper->x2;
/* give base distortion a greater weight while scoring */
base_distort *= 10;
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 */

View file

@ -4,7 +4,7 @@
/* */
/* Auto-fitter module (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
/* Copyright 2003-2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -34,7 +34,7 @@
#include "afloader.c"
#include "afmodule.c"
#ifdef AF_USE_WARPER
#ifdef AF_CONFIG_OPTION_USE_WARPER
#include "afwarp.c"
#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.
#
# 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)/afloader.c \
$(AUTOF_DIR)/afmodule.c \
$(AUTOF_DIR)/afpic.c \
$(AUTOF_DIR)/afwarp.c
# AUTOF driver headers
#
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)

View file

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

View file

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

View file

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

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -354,8 +354,8 @@
}
FT_BASE_DEF( FT_Short )
FT_Stream_GetShort( FT_Stream stream )
FT_BASE_DEF( FT_UShort )
FT_Stream_GetUShort( FT_Stream stream )
{
FT_Byte* p;
FT_Short result;
@ -366,15 +366,15 @@
result = 0;
p = stream->cursor;
if ( p + 1 < stream->limit )
result = FT_NEXT_SHORT( p );
result = FT_NEXT_USHORT( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Short )
FT_Stream_GetShortLE( FT_Stream stream )
FT_BASE_DEF( FT_UShort )
FT_Stream_GetUShortLE( FT_Stream stream )
{
FT_Byte* p;
FT_Short result;
@ -385,15 +385,15 @@
result = 0;
p = stream->cursor;
if ( p + 1 < stream->limit )
result = FT_NEXT_SHORT_LE( p );
result = FT_NEXT_USHORT_LE( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Long )
FT_Stream_GetOffset( FT_Stream stream )
FT_BASE_DEF( FT_ULong )
FT_Stream_GetUOffset( FT_Stream stream )
{
FT_Byte* p;
FT_Long result;
@ -404,14 +404,14 @@
result = 0;
p = stream->cursor;
if ( p + 2 < stream->limit )
result = FT_NEXT_OFF3( p );
result = FT_NEXT_UOFF3( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Long )
FT_Stream_GetLong( FT_Stream stream )
FT_BASE_DEF( FT_ULong )
FT_Stream_GetULong( FT_Stream stream )
{
FT_Byte* p;
FT_Long result;
@ -422,14 +422,14 @@
result = 0;
p = stream->cursor;
if ( p + 3 < stream->limit )
result = FT_NEXT_LONG( p );
result = FT_NEXT_ULONG( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Long )
FT_Stream_GetLongLE( FT_Stream stream )
FT_BASE_DEF( FT_ULong )
FT_Stream_GetULongLE( FT_Stream stream )
{
FT_Byte* p;
FT_Long result;
@ -440,7 +440,7 @@
result = 0;
p = stream->cursor;
if ( p + 3 < stream->limit )
result = FT_NEXT_LONG_LE( p );
result = FT_NEXT_ULONG_LE( p );
stream->cursor = p;
return result;
}
@ -483,8 +483,8 @@
}
FT_BASE_DEF( FT_Short )
FT_Stream_ReadShort( FT_Stream stream,
FT_BASE_DEF( FT_UShort )
FT_Stream_ReadUShort( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[2];
@ -511,7 +511,7 @@
}
if ( p )
result = FT_NEXT_SHORT( p );
result = FT_NEXT_USHORT( p );
}
else
goto Fail;
@ -522,7 +522,7 @@
Fail:
*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",
stream->pos, stream->size ));
@ -530,8 +530,8 @@
}
FT_BASE_DEF( FT_Short )
FT_Stream_ReadShortLE( FT_Stream stream,
FT_BASE_DEF( FT_UShort )
FT_Stream_ReadUShortLE( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[2];
@ -558,7 +558,7 @@
}
if ( p )
result = FT_NEXT_SHORT_LE( p );
result = FT_NEXT_USHORT_LE( p );
}
else
goto Fail;
@ -569,7 +569,7 @@
Fail:
*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",
stream->pos, stream->size ));
@ -577,8 +577,8 @@
}
FT_BASE_DEF( FT_Long )
FT_Stream_ReadOffset( FT_Stream stream,
FT_BASE_DEF( FT_ULong )
FT_Stream_ReadUOffset( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[3];
@ -605,7 +605,7 @@
}
if ( p )
result = FT_NEXT_OFF3( p );
result = FT_NEXT_UOFF3( p );
}
else
goto Fail;
@ -616,7 +616,7 @@
Fail:
*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",
stream->pos, stream->size ));
@ -624,8 +624,8 @@
}
FT_BASE_DEF( FT_Long )
FT_Stream_ReadLong( FT_Stream stream,
FT_BASE_DEF( FT_ULong )
FT_Stream_ReadULong( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[4];
@ -652,7 +652,7 @@
}
if ( p )
result = FT_NEXT_LONG( p );
result = FT_NEXT_ULONG( p );
}
else
goto Fail;
@ -663,7 +663,7 @@
Fail:
*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",
stream->pos, stream->size ));
@ -671,8 +671,8 @@
}
FT_BASE_DEF( FT_Long )
FT_Stream_ReadLongLE( FT_Stream stream,
FT_BASE_DEF( FT_ULong )
FT_Stream_ReadULongLE( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[4];
@ -699,7 +699,7 @@
}
if ( p )
result = FT_NEXT_LONG_LE( p );
result = FT_NEXT_ULONG_LE( p );
}
else
goto Fail;
@ -710,7 +710,7 @@
Fail:
*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",
stream->pos, stream->size ));

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -704,7 +704,6 @@
FT_Fixed miter_limit;
FT_Fixed radius;
FT_Bool valid;
FT_StrokeBorderRec borders[2];
FT_Library library;
@ -719,7 +718,7 @@
{
FT_Error error;
FT_Memory memory;
FT_Stroker stroker;
FT_Stroker stroker = NULL;
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
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).
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):
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
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). */
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -17,6 +17,7 @@
#include <ft2build.h>
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H
#include FT_CACHE_H
#include "ftcglyph.h"
@ -237,7 +238,8 @@
FT_CALLBACK_DEF( FT_Bool )
ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode,
FT_Pointer ftcface_id,
FTC_Cache cache )
FTC_Cache cache,
FT_Bool* list_changed )
{
FTC_GNode gnode = (FTC_GNode)ftcgnode;
FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
@ -245,6 +247,8 @@
FT_Bool result;
if ( list_changed )
*list_changed = FALSE;
result = FT_BOOL( family->attrs.scaler.face_id == face_id );
if ( result )
{

View file

@ -4,7 +4,8 @@
/* */
/* 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. */
/* */
/* 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_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
@ -83,6 +84,25 @@
(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 */
@ -117,7 +137,8 @@
/* 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;
}
@ -191,7 +212,9 @@
cache->slack -= FTC_HASH_MAX_LOAD;
cache->p = p;
}
else /* the hash table is balanced */
/* otherwise, the hash table is balanced */
else
break;
}
}
@ -202,16 +225,9 @@
ftc_node_hash_unlink( FTC_Node node0,
FTC_Cache cache )
{
FTC_Node *pnode;
FT_UInt idx;
FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node0->hash );
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 (;;)
{
FTC_Node node = *pnode;
@ -242,16 +258,9 @@
ftc_node_hash_link( FTC_Node node,
FTC_Cache cache )
{
FTC_Node *pnode;
FT_UInt idx;
FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node->hash );
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;
*pnode = node;
@ -414,7 +423,7 @@
FTC_Node node )
{
node->hash = hash;
node->cache_index = (FT_UInt16) cache->index;
node->cache_index = (FT_UInt16)cache->index;
node->ref_count = 0;
ftc_node_hash_link( node, cache );
@ -456,7 +465,7 @@
{
error = cache->clazz.node_new( &node, query, cache );
}
FTC_CACHE_TRYLOOP_END();
FTC_CACHE_TRYLOOP_END( NULL );
if ( error )
node = NULL;
@ -481,11 +490,11 @@
FT_Pointer query,
FTC_Node *anode )
{
FT_UFast idx;
FTC_Node* bucket;
FTC_Node* pnode;
FTC_Node node;
FT_Error error = FTC_Err_Ok;
FT_Bool list_changed = FALSE;
FTC_Node_CompareFunc compare = cache->clazz.node_compare;
@ -493,24 +502,43 @@
if ( cache == NULL || anode == NULL )
return FTC_Err_Invalid_Argument;
idx = hash & cache->mask;
if ( idx < cache->p )
idx = hash & ( cache->mask * 2 + 1 );
/* Go to the `top' node of the list sharing same masked hash */
bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash );
bucket = cache->buckets + idx;
pnode = bucket;
/* Lookup a node with exactly same hash and queried properties. */
/* NOTE: _nodcomp() may change the linked list to reduce memory. */
for (;;)
{
node = *pnode;
if ( node == NULL )
goto NewNode;
if ( node->hash == hash && compare( node, query, cache ) )
if ( node->hash == hash &&
compare( node, query, cache, &list_changed ) )
break;
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 )
{
*pnode = node->link;
@ -527,6 +555,7 @@
ftc_node_mru_up( node, manager );
}
*anode = node;
return error;
NewNode:
@ -545,7 +574,7 @@
FTC_Node frees = NULL;
count = cache->p + cache->mask;
count = cache->p + cache->mask + 1;
for ( i = 0; i < count; i++ )
{
FTC_Node* bucket = cache->buckets + i;
@ -555,12 +584,14 @@
for ( ;; )
{
FTC_Node node = *pnode;
FT_Bool list_changed = FALSE;
if ( node == NULL )
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;
node->link = frees;

View file

@ -4,7 +4,8 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -72,6 +73,19 @@ FT_BEGIN_HEADER
#define FTC_NODE__NEXT( x ) FTC_NODE( (x)->mru.next )
#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
FT_BASE( void )
@ -102,7 +116,8 @@ FT_BEGIN_HEADER
typedef FT_Bool
(*FTC_Node_CompareFunc)( FTC_Node node,
FT_Pointer key,
FTC_Cache cache );
FTC_Cache cache,
FT_Bool* list_changed );
typedef void
@ -162,7 +177,7 @@ FT_BEGIN_HEADER
FT_LOCAL( void )
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
* is capable of flushing the cache adequately to make room for the
* new cache object.
@ -184,7 +199,7 @@ FT_BEGIN_HEADER
/* 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
* 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
* be modified.
*
@ -205,28 +220,49 @@ FT_BEGIN_HEADER
FTC_Cache _cache = FTC_CACHE(cache); \
FT_PtrDist _hash = (FT_PtrDist)(hash); \
FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \
FT_UFast _idx; \
FT_Bool _list_changed = FALSE; \
\
\
error = FTC_Err_Ok; \
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 (;;) \
{ \
_node = *_pnode; \
if ( _node == NULL ) \
goto _NewNode; \
\
if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) ) \
if ( _node->hash == _hash && \
_nodcomp( _node, query, _cache, &_list_changed ) ) \
break; \
\
_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 ) \
{ \
*_pnode = _node->link; \
@ -234,6 +270,7 @@ FT_BEGIN_HEADER
*_bucket = _node; \
} \
\
/* Update MRU list */ \
{ \
FTC_Manager _manager = _cache->manager; \
void* _nl = &_manager->nodes_list; \
@ -268,7 +305,7 @@ FT_BEGIN_HEADER
* loop to flush the cache repeatedly in case of memory overflows.
*
* 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:
*
@ -290,11 +327,14 @@ FT_BEGIN_HEADER
FT_UInt _try_done;
#define FTC_CACHE_TRYLOOP_END() \
#define FTC_CACHE_TRYLOOP_END( list_changed ) \
if ( !error || error != FTC_Err_Out_Of_Memory ) \
break; \
\
_try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \
if ( _try_done > 0 && ( list_changed ) ) \
*(FT_Bool*)( list_changed ) = TRUE; \
\
if ( _try_done == 0 ) \
break; \
\

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -57,13 +57,15 @@
FT_LOCAL( FT_Bool )
ftc_snode_compare( FTC_Node snode,
FT_Pointer gquery,
FTC_Cache cache );
FTC_Cache cache,
FT_Bool* list_changed );
FT_LOCAL( FT_Bool )
ftc_gnode_compare( FTC_Node gnode,
FT_Pointer gquery,
FTC_Cache cache );
FTC_Cache cache,
FT_Bool* list_changed );
FT_LOCAL( FT_Error )

View file

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

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -17,6 +17,7 @@
#include <ft2build.h>
#include FT_INTERNAL_OBJECTS_H
#include FT_CACHE_H
#include "ftcglyph.h"
#include FT_ERRORS_H
@ -64,25 +65,34 @@
FT_LOCAL_DEF( FT_Bool )
ftc_gnode_compare( FTC_Node ftcgnode,
FT_Pointer ftcgquery,
FTC_Cache cache )
FTC_Cache cache,
FT_Bool* list_changed )
{
FTC_GNode gnode = (FTC_GNode)ftcgnode;
FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
FT_UNUSED( cache );
if ( list_changed )
*list_changed = FALSE;
return FT_BOOL( gnode->family == gquery->family &&
gnode->gindex == gquery->gindex );
}
#ifdef FTC_INLINE
FT_LOCAL_DEF( FT_Bool )
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). */
/* */
/* Copyright 2000-2001, 2003, 2004, 2006, 2007 by */
/* Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* 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 */
FTC_Family family );
#ifdef FTC_INLINE
/* returns TRUE iff the query's glyph index correspond to the node; */
/* this assumes that the `family' and `hash' fields of the query are */
/* already correctly set */
FT_LOCAL( FT_Bool )
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 */
/* to implement the `node_remove_faceid' cache method correctly */
@ -307,7 +313,7 @@ FT_BEGIN_HEADER
FT_BEGIN_STMNT \
\
error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \
FTC_GQUERY( query ), node ); \
FTC_GQUERY( query ), &node ); \
\
FT_END_STMNT

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */

View file

@ -238,7 +238,7 @@
FTC_MruNode *anode )
{
FT_Error error;
FTC_MruNode node;
FTC_MruNode node = NULL;
FT_Memory memory = list->memory;

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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 );
FT_UInt total;
FT_UInt node_count;
total = clazz->family_get_count( family, cache->manager );
@ -239,6 +240,10 @@
FTC_GNode_Init( FTC_GNODE( snode ), start, family );
snode->count = count;
for ( node_count = 0; node_count < count; node_count++ )
{
snode->sbits[node_count].width = 255;
}
error = ftc_snode_load( snode,
cache->manager,
@ -319,7 +324,8 @@
FT_LOCAL_DEF( FT_Bool )
ftc_snode_compare( FTC_Node ftcsnode,
FT_Pointer ftcgquery,
FTC_Cache cache )
FTC_Cache cache,
FT_Bool* list_changed )
{
FTC_SNode snode = (FTC_SNode)ftcsnode;
FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
@ -328,6 +334,8 @@
FT_Bool result;
if (list_changed)
*list_changed = FALSE;
result = FT_BOOL( gnode->family == gquery->family &&
(FT_UInt)( gindex - gnode->gindex ) < snode->count );
if ( result )
@ -368,7 +376,7 @@
*
*/
if ( sbit->buffer == NULL && sbit->width != 255 )
if ( sbit->buffer == NULL && sbit->width == 255 )
{
FT_ULong size;
FT_Error error;
@ -381,7 +389,7 @@
{
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 */
@ -396,13 +404,18 @@
}
#ifdef FTC_INLINE
FT_LOCAL_DEF( FT_Bool )
FTC_SNode_Compare( FTC_SNode snode,
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 */

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -83,10 +83,15 @@ FT_BEGIN_HEADER
#endif
#ifdef FTC_INLINE
FT_LOCAL( FT_Bool )
FTC_SNode_Compare( FTC_SNode snode,
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 )
{
CFF_FontRecDict dict = &cff->top_font.font_dict;
PS_FontInfoRec *font_info;
PS_FontInfoRec *font_info = NULL;
FT_Memory memory = face->root.memory;

View file

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

View file

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

View file

@ -4,8 +4,7 @@
/* */
/* OpenType objects manager (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
/* 2010 by */
/* Copyright 1996-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* 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_Font font = (CFF_Font)face->extra.data;
CFF_Internal internal;
CFF_Internal internal = NULL;
PS_PrivateRec priv;
FT_Memory memory = cffsize->face->memory;
@ -421,6 +420,7 @@
{
for ( idx = 7; idx < length; idx++ )
name[idx - 7] = name[idx];
length -= 7;
}
}
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 )
cff_face_init( FT_Stream stream,
FT_Face cffface, /* CFF_Face */
@ -523,7 +568,7 @@
/* now load and parse the CFF table in the file */
{
CFF_Font cff;
CFF_Font cff = NULL;
CFF_FontRecDict dict;
FT_Memory memory = cffface->memory;
FT_Int32 flags;
@ -758,6 +803,9 @@
/* case, the remaining string in `fullp' will be used as */
/* the style name. */
style_name = cff_strcpy( memory, fullp );
/* remove the style part from the family name (if present) */
remove_style( cffface->family_name, style_name );
}
break;
}

View file

@ -5,7 +5,7 @@
/* Basic OpenType/CFF type definitions and interface (specification */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -212,8 +212,7 @@ FT_BEGIN_HEADER
} CFF_SubFontRec, *CFF_SubFont;
/* maximum number of sub-fonts in a CID-keyed file */
#define CFF_MAX_CID_FONTS 32
#define CFF_MAX_CID_FONTS 256
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.
#
# 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_DRV_SRC := $(CFF_DIR)/cffobjs.c \
$(CFF_DIR)/cffload.c \
CFF_DRV_SRC := $(CFF_DIR)/cffcmap.c \
$(CFF_DIR)/cffdrivr.c \
$(CFF_DIR)/cffgload.c \
$(CFF_DIR)/cffload.c \
$(CFF_DIR)/cffobjs.c \
$(CFF_DIR)/cffparse.c \
$(CFF_DIR)/cffcmap.c \
$(CFF_DIR)/cffdrivr.c
$(CFF_DIR)/cffpic.c
# CFF driver headers
#
CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \
$(CFF_DIR)/cfferrs.h \
$(CFF_DIR)/cfftoken.h \
$(CFF_DIR)/cfftypes.h \
$(CFF_DIR)/cfferrs.h
$(CFF_DIR)/cfftypes.h
# CFF driver object(s)

View file

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

View file

@ -51,6 +51,19 @@
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;
FT_Bytes lookuptbl_head;
FT_UShort min_gid;
FT_UShort max_gid;
GXV_StateTable_ValidatorRec statetable;
GXV_XStateTable_ValidatorRec xstatetable;

View file

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

View file

@ -65,6 +65,22 @@
#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
gxv_just_wdp_entry_validate( FT_Bytes table,
FT_Bytes limit,
@ -72,24 +88,37 @@
{
FT_Bytes p = table;
FT_ULong justClass;
#ifdef GXV_LOAD_UNUSED_VARS
FT_Fixed beforeGrowLimit;
FT_Fixed beforeShrinkGrowLimit;
FT_Fixed afterGrowLimit;
FT_Fixed afterShrinkGrowLimit;
FT_UShort growFlags;
FT_UShort shrinkFlags;
#endif
GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 );
justClass = FT_NEXT_ULONG( p );
#ifndef GXV_LOAD_UNUSED_VARS
p += 4 + 4 + 4 + 4 + 2 + 2;
#else
beforeGrowLimit = FT_NEXT_ULONG( p );
beforeShrinkGrowLimit = FT_NEXT_ULONG( p );
afterGrowLimit = FT_NEXT_ULONG( p );
afterShrinkGrowLimit = FT_NEXT_ULONG( p );
growFlags = 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;
}
@ -153,8 +182,9 @@
FT_Fixed lowerLimit;
FT_Fixed upperLimit;
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort order;
#endif
FT_UShort decomposedCount;
FT_UInt i;
@ -163,9 +193,20 @@
GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
lowerLimit = FT_NEXT_ULONG( p );
upperLimit = FT_NEXT_ULONG( p );
#ifdef GXV_LOAD_UNUSED_VARS
order = FT_NEXT_USHORT( p );
#else
p += 2;
#endif
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++ )
{
FT_UShort glyphs;
@ -173,6 +214,7 @@
GXV_LIMIT_CHECK( 2 );
glyphs = FT_NEXT_USHORT( p );
gxv_just_check_max_gid( glyphs, "type0:glyphs", valid );
}
valid->subtable_length = p - table;
@ -191,6 +233,8 @@
GXV_LIMIT_CHECK( 2 );
addGlyph = FT_NEXT_USHORT( p );
gxv_just_check_max_gid( addGlyph, "type1:addGlyph", valid );
valid->subtable_length = p - table;
}
@ -201,16 +245,27 @@
GXV_Validator valid )
{
FT_Bytes p = table;
#ifdef GXV_LOAD_UNUSED_VARS
FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */
#endif
FT_UShort addGlyph;
FT_UShort substGlyph;
GXV_LIMIT_CHECK( 4 + 2 + 2 );
#ifdef GXV_LOAD_UNUSED_VARS
substThreshhold = FT_NEXT_ULONG( p );
#else
p += 4;
#endif
addGlyph = 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;
}
@ -234,6 +289,21 @@
maximumLimit = FT_NEXT_ULONG( p );
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 );
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;
}
@ -274,6 +349,10 @@
actionType = FT_NEXT_USHORT( 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 )
gxv_just_actSubrecord_type0_validate( p, limit, valid );
else if ( actionType == 1 )
@ -389,10 +468,13 @@
FT_Bytes limit,
GXV_Validator valid )
{
#ifdef GXV_LOAD_UNUSED_VARS
/* TODO: validate markClass & currentClass */
FT_UShort setMark;
FT_UShort dontAdvance;
FT_UShort markClass;
FT_UShort currentClass;
#endif
FT_UNUSED( state );
FT_UNUSED( glyphOffset_p );
@ -400,13 +482,14 @@
FT_UNUSED( limit );
FT_UNUSED( valid );
#ifndef GXV_LOAD_UNUSED_VARS
FT_UNUSED( flags );
#else
setMark = (FT_UShort)( ( flags >> 15 ) & 1 );
dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
markClass = (FT_UShort)( ( flags >> 7 ) & 0x7F );
currentClass = (FT_UShort)( flags & 0x7F );
/* TODO: validate markClass & currentClass */
#endif
}
@ -428,9 +511,15 @@
coverage = FT_NEXT_USHORT( p );
subFeatureFlags = FT_NEXT_ULONG( p );
GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s)",
coverage,
( 0x4000 & coverage ) == 0 ? "ascending" : "descending" ));
GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s) ", coverage ));
if ( ( coverage & 0x4000 ) == 0 )
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_load_func = NULL;
@ -557,7 +646,6 @@
{
FT_Bytes p = table;
FT_Bytes limit = 0;
FT_Offset table_size;
GXV_ValidatorRec validrec;
GXV_Validator valid = &validrec;
@ -582,7 +670,6 @@
GXV_INIT;
limit = valid->root->limit;
table_size = limit - table;
GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 );
version = FT_NEXT_ULONG( p );

View file

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

View file

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

View file

@ -98,10 +98,24 @@
GXV_TRACE(( " %02d", 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 )
{
GXV_TRACE(( " non-zero bits found in reserved range\n" ));
FT_INVALID_DATA;
GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
}
else
GXV_TRACE(( "\n" ));

View file

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

View file

@ -155,8 +155,7 @@
ligActionOffset, lat_base - p ));
/* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */
if ( valid->root->level >= FT_VALIDATE_PARANOID )
FT_INVALID_OFFSET;
GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
}
else if ( lat_limit < p )
{
@ -164,23 +163,46 @@
ligActionOffset, p - lat_limit ));
/* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */
if ( valid->root->level >= FT_VALIDATE_PARANOID )
FT_INVALID_OFFSET;
GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
}
else
{
/* validate entry in ligActionTable */
FT_ULong lig_action;
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort last;
FT_UShort store;
#endif
FT_ULong offset;
lig_action = FT_NEXT_ULONG( p );
#ifdef GXV_LOAD_UNUSED_VARS
last = (FT_UShort)( ( lig_action >> 31 ) & 1 );
store = (FT_UShort)( ( lig_action >> 30 ) & 1 );
#endif
/* Apple spec defines this offset as a word offset */
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,
GXV_Validator valid )
{
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort setComponent;
FT_UShort dontAdvance;
#endif
FT_UShort offset;
FT_UNUSED( state );
@ -203,8 +227,10 @@
FT_UNUSED( limit );
#ifdef GXV_LOAD_UNUSED_VARS
setComponent = (FT_UShort)( ( flags >> 15 ) & 1 );
dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
#endif
offset = (FT_UShort)( flags & 0x3FFFU );
@ -237,6 +263,9 @@
GXV_LIMIT_CHECK( 2 );
lig_gid = FT_NEXT_USHORT( p );
if ( valid->face->num_glyphs < lig_gid )
GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
}
}
GXV_EXIT;

View file

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

View file

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

View file

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

View file

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

View file

@ -168,16 +168,50 @@
{
/* validate entry in ligActionTable */
FT_ULong lig_action;
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort last;
FT_UShort store;
#endif
FT_ULong offset;
lig_action = FT_NEXT_ULONG( p );
#ifdef GXV_LOAD_UNUSED_VARS
last = (FT_UShort)( ( lig_action >> 31 ) & 1 );
store = (FT_UShort)( ( lig_action >> 30 ) & 1 );
#endif
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,
GXV_Validator valid )
{
#ifdef GXV_LOAD_UNUSED_VARS
FT_UShort setComponent;
FT_UShort dontAdvance;
FT_UShort performAction;
#endif
FT_UShort reserved;
FT_UShort ligActionIndex;
@ -201,9 +237,11 @@
FT_UNUSED( limit );
#ifdef GXV_LOAD_UNUSED_VARS
setComponent = (FT_UShort)( ( flags >> 15 ) & 1 );
dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
performAction = (FT_UShort)( ( flags >> 13 ) & 1 );
#endif
reserved = (FT_UShort)( flags & 0x1FFF );
ligActionIndex = glyphOffset_p->u;
@ -241,6 +279,8 @@
GXV_LIMIT_CHECK( 2 );
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;
#ifndef GXV_LOAD_TRACE_VARS
GXV_LIMIT_CHECK( count * 2 );
#else
while ( p < table + count * 2 + table_index * 2 )
{
FT_UShort insert_glyphID;
@ -129,6 +132,7 @@
}
GXV_TRACE(( "\n" ));
#endif
}
@ -141,12 +145,14 @@
FT_Bytes limit,
GXV_Validator valid )
{
#ifdef GXV_LOAD_UNUSED_VARS
FT_Bool setMark;
FT_Bool dontAdvance;
FT_Bool currentIsKashidaLike;
FT_Bool markedIsKashidaLike;
FT_Bool currentInsertBefore;
FT_Bool markedInsertBefore;
#endif
FT_Byte currentInsertCount;
FT_Byte markedInsertCount;
FT_Byte currentInsertList;
@ -155,12 +161,14 @@
FT_UNUSED( state );
#ifdef GXV_LOAD_UNUSED_VARS
setMark = FT_BOOL( ( flags >> 15 ) & 1 );
dontAdvance = FT_BOOL( ( flags >> 14 ) & 1 );
currentIsKashidaLike = FT_BOOL( ( flags >> 13 ) & 1 );
markedIsKashidaLike = FT_BOOL( ( flags >> 12 ) & 1 );
currentInsertBefore = FT_BOOL( ( flags >> 11 ) & 1 );
markedInsertBefore = FT_BOOL( ( flags >> 10 ) & 1 );
#endif
currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F );
markedInsertCount = (FT_Byte)( flags & 0x001F );

View file

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

View file

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

View file

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

View file

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

View file

@ -31,29 +31,11 @@ on linux/alpha.
Encodings
*********
The variety of encodings that accompanies pcf fonts appears to encompass the
small set defined in freetype.h. On the other hand, each pcf font defines
two properties that specify encoding and registry.
Use `FT_Get_BDF_Charset_ID' to access the encoding and registry.
I decided to make these two properties directly accessible, leaving to the
client application the work of interpreting them. For instance:
#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.
The driver always exports `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

View file

@ -2,7 +2,7 @@
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
Permission is hereby granted, free of charge, to any person obtaining a copy
@ -136,8 +136,8 @@ FT_BEGIN_HEADER
{
FT_FaceRec root;
FT_StreamRec gzip_stream;
FT_Stream gzip_source;
FT_StreamRec comp_stream;
FT_Stream comp_source;
char* charset_encoding;
char* charset_registry;

View file

@ -2,7 +2,8 @@
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
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_GZIP_H
#include FT_LZW_H
#include FT_BZIP2_H
#include FT_ERRORS_H
#include FT_BDF_H
#include FT_TRUETYPE_IDS_H
@ -248,11 +250,11 @@ THE SOFTWARE.
FT_TRACE4(( "PCF_Face_Done: done face\n" ));
/* close gzip/LZW stream if any */
if ( pcfface->stream == &face->gzip_stream )
/* close compressed stream if any */
if ( pcfface->stream == &face->comp_stream )
{
FT_Stream_Close( &face->gzip_stream );
pcfface->stream = face->gzip_source;
FT_Stream_Close( &face->comp_stream );
pcfface->stream = face->comp_source;
}
}
@ -278,7 +280,8 @@ THE SOFTWARE.
PCF_Face_Done( pcfface );
#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
{
@ -286,7 +289,7 @@ THE SOFTWARE.
/* 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 )
goto Fail;
@ -301,7 +304,7 @@ THE SOFTWARE.
/* 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 )
goto Fail;
@ -309,11 +312,26 @@ THE SOFTWARE.
}
#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 )
goto Fail;
face->gzip_source = stream;
pcfface->stream = &face->gzip_stream;
face->comp_source = stream;
pcfface->stream = &face->comp_stream;
stream = pcfface->stream;
@ -321,7 +339,9 @@ THE SOFTWARE.
if ( error )
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;

View file

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

View file

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

View file

@ -4,8 +4,7 @@
/* */
/* Auxiliary functions for PostScript fonts (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
/* 2010 by */
/* Copyright 1996-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -188,11 +187,11 @@
{
FT_Error error;
FT_Offset new_size = table->capacity;
FT_Long in_offset;
FT_PtrDist in_offset;
in_offset = (FT_Long)((FT_Byte*)object - table->block);
if ( (FT_ULong)in_offset >= table->capacity )
in_offset = (FT_Byte*)object - table->block;
if ( in_offset < 0 || (FT_Offset)in_offset >= table->capacity )
in_offset = -1;
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.
#
# 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_DRV_SRC := $(PSHINTER_DIR)/pshrec.c \
PSHINTER_DRV_SRC := $(PSHINTER_DIR)/pshalgo.c \
$(PSHINTER_DIR)/pshglob.c \
$(PSHINTER_DIR)/pshmod.c \
$(PSHINTER_DIR)/pshalgo.c
$(PSHINTER_DIR)/pshpic.c \
$(PSHINTER_DIR)/pshrec.c
# 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.
#
# 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_DRV_SRC := $(PSNAMES_DIR)/psmodule.c
PSNAMES_DRV_SRC := $(PSNAMES_DIR)/psmodule.c \
$(PSNAMES_DIR)/pspic.c
# PSNames driver headers
#
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)

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -651,11 +651,33 @@
static void
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 )
{
ras.precision_bits = 12;
ras.precision_step = 256;
ras.precision_jitter = 50;
ras.precision_jitter = 30;
}
else
{
@ -2403,6 +2425,14 @@
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 */
e1 = pxl == e1 ? e2 : e1;
@ -2579,6 +2609,14 @@
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 */
e1 = pxl == e1 ? e2 : e1;

View file

@ -161,10 +161,18 @@
/* compute the control box, and grid fit it */
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.yMin = FT_PIX_FLOOR( cbox.yMin );
cbox.xMax = FT_PIX_CEIL( cbox.xMax );
cbox.yMax = FT_PIX_CEIL( cbox.yMax );
#endif
width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 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.
#
# 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_DRV_SRC := $(RASTER_DIR)/ftraster.c \
$(RASTER_DIR)/ftrend1.c
$(RASTER_DIR)/ftrend1.c \
$(RASTER_DIR)/rastpic.c
# 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.
#
# 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)/ttbdf.c \
$(SFNT_DIR)/sfobjs.c \
$(SFNT_DIR)/sfdriver.c
$(SFNT_DIR)/sfdriver.c \
$(SFNT_DIR)/sfntpic.c
# SFNT driver headers
#

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -117,15 +117,20 @@
FT_ULong *offset,
FT_ULong *length )
{
if ( !tag || !offset || !length )
if ( !offset || !length )
return SFNT_Err_Invalid_Argument;
if ( !tag )
*length = face->num_tables;
else
{
if ( idx >= face->num_tables )
return SFNT_Err_Table_Missing;
*tag = face->dir_tables[idx].Tag;
*offset = face->dir_tables[idx].Offset;
*length = face->dir_tables[idx].Length;
}
return SFNT_Err_Ok;
}

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -356,7 +356,7 @@
FT_FRAME_START( 8 ),
FT_FRAME_LONG( version ),
FT_FRAME_LONG( count ),
FT_FRAME_LONG( count ), /* this is ULong in the specs */
FT_FRAME_END
};
@ -390,6 +390,17 @@
if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
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 */
if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
return error;

View file

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

View file

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -163,7 +163,7 @@
{
FT_TRACE0(( "tt_face_load_hmtx:"
" %cmtx has more metrics than glyphs.\n",
vertical ? "v" : "h" ));
vertical ? 'v' : 'h' ));
/* Adobe simply ignores this problem. So we shall do the same. */
#if 0

View file

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

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