updated freetype to 2.3.5

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21879 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2007-08-09 21:33:28 +00:00
parent a9fa028de4
commit 6a2b62ec79
76 changed files with 4718 additions and 911 deletions
@@ -302,7 +302,9 @@ FT_BEGIN_HEADER
/* The size in bytes of the render pool used by the scan-line converter */ /* The size in bytes of the render pool used by the scan-line converter */
/* to do all of its work. */ /* to do all of its work. */
/* */ /* */
/* This must be greater than 4KByte. */ /* This must be greater than 4KByte if you use FreeType to rasterize */
/* glyphs; otherwise, you may set it to zero to avoid unnecessary */
/* allocation of the render pool. */
/* */ /* */
#define FT_RENDER_POOL_SIZE 16384L #define FT_RENDER_POOL_SIZE 16384L
@@ -461,12 +463,47 @@ FT_BEGIN_HEADER
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* Define TT_CONFIG_OPTION_UNPATENTED_HINTING (in addition to */ /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */
/* TT_CONFIG_OPTION_BYTECODE_INTERPRETER) to compile the unpatented */ /* of the TrueType bytecode interpreter is used that doesn't implement */
/* work-around hinting system. Note that for the moment, the algorithm */ /* any of the patented opcodes and algorithms. Note that the */
/* is only used when selected at runtime through the parameter tag */ /* the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you */
/* FT_PARAM_TAG_UNPATENTED_HINTING; or when the debug hook */ /* define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; with other words, */
/* FT_DEBUG_HOOK_UNPATENTED_HINTING is globally activated. */ /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */
/* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */
/* */
/* This macro is only useful for a small number of font files (mostly */
/* for Asian scripts) that require bytecode interpretation to properly */
/* load glyphs. For all other fonts, this produces unpleasant results, */
/* thus the unpatented interpreter is never used to load glyphs from */
/* TrueType fonts unless one of the following two options is used. */
/* */
/* - The unpatented interpreter is explicitly activated by the user */
/* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */
/* when opening the FT_Face. */
/* */
/* - FreeType detects that the FT_Face corresponds to one of the */
/* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */
/* contains a hard-coded list of font names and other matching */
/* parameters (see function `tt_face_init' in file */
/* `src/truetype/ttobjs.c'). */
/* */
/* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */
/* */
/* { */
/* FT_Parameter parameter; */
/* FT_Open_Args open_args; */
/* */
/* */
/* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */
/* */
/* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */
/* open_args.pathname = my_font_pathname; */
/* open_args.num_params = 1; */
/* open_args.params = &parameter; */
/* */
/* error = FT_Open_Face( library, &open_args, index, &face ); */
/* ... */
/* } */
/* */ /* */
#define TT_CONFIG_OPTION_UNPATENTED_HINTING #define TT_CONFIG_OPTION_UNPATENTED_HINTING
@@ -591,6 +628,11 @@ FT_BEGIN_HEADER
/* */ /* */
#define AF_CONFIG_OPTION_CJK #define AF_CONFIG_OPTION_CJK
/*************************************************************************/
/* */
/* Compile autofit module with Indic script support. */
/* */
#define AF_CONFIG_OPTION_INDIC
/* */ /* */
@@ -78,15 +78,6 @@
/**********************************************************************/ /**********************************************************************/
#include <ctype.h>
#define ft_isalnum isalnum
#define ft_isdigit isdigit
#define ft_islower islower
#define ft_isupper isupper
#define ft_isxdigit isxdigit
#include <string.h> #include <string.h>
#define ft_memchr memchr #define ft_memchr memchr
+67 -5
View File
@@ -2111,9 +2111,16 @@ FT_BEGIN_HEADER
/* FreeType error code. 0 means success. */ /* FreeType error code. 0 means success. */
/* */ /* */
/* <Note> */ /* <Note> */
/* If either the horizontal or vertical resolution is zero, it is set */ /* If either the character width or height is zero, it is set equal */
/* to a default value of 72dpi. */ /* to the other value. */
/* */ /* */
/* If either the horizontal or vertical resolution is zero, it is set */
/* equal to the other value. */
/* */
/* A character width or height smaller than 1pt is set to 1pt; if */
/* both resolution values are zero, they are set to 72dpi. */
/* */
FT_EXPORT( FT_Error ) FT_EXPORT( FT_Error )
FT_Set_Char_Size( FT_Face face, FT_Set_Char_Size( FT_Face face,
FT_F26Dot6 char_width, FT_F26Dot6 char_width,
@@ -2731,8 +2738,7 @@ FT_BEGIN_HEADER
/* */ /* */
/* <Description> */ /* <Description> */
/* Retrieve the ASCII name of a given glyph in a face. This only */ /* Retrieve the ASCII name of a given glyph in a face. This only */
/* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns */ /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns 1. */
/* TRUE. */
/* */ /* */
/* <Input> */ /* <Input> */
/* face :: A handle to a source face object. */ /* face :: A handle to a source face object. */
@@ -3323,7 +3329,7 @@ FT_BEGIN_HEADER
*/ */
#define FREETYPE_MAJOR 2 #define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 3 #define FREETYPE_MINOR 3
#define FREETYPE_PATCH 4 #define FREETYPE_PATCH 5
/*************************************************************************/ /*************************************************************************/
@@ -3361,6 +3367,62 @@ FT_BEGIN_HEADER
FT_Int *aminor, FT_Int *aminor,
FT_Int *apatch ); FT_Int *apatch );
/*************************************************************************/
/* */
/* <Function> */
/* FT_Face_CheckTrueTypePatents */
/* */
/* <Description> */
/* Parse all bytecode instructions of a TrueType font file to check */
/* whether any of the patented opcodes are used. This is only useful */
/* if you want to be able to use the unpatented hinter with */
/* fonts that do *not* use these opcodes. */
/* */
/* Note that this function parses *all* glyph instructions in the */
/* font file, which may be slow. */
/* */
/* <Input> */
/* face :: A face handle. */
/* */
/* <Return> */
/* 1 if this is a TrueType font that uses one of the patented */
/* opcodes, 0 otherwise. */
/* */
/* <Since> */
/* 2.3.5 */
/* */
FT_EXPORT( FT_Bool )
FT_Face_CheckTrueTypePatents( FT_Face face );
/*************************************************************************/
/* */
/* <Function> */
/* FT_Face_SetUnpatentedHinting */
/* */
/* <Description> */
/* Enable or disable the unpatented hinter for a given face. */
/* Only enable it if you have determined that the face doesn't */
/* use any patented opcodes (see @FT_Face_CheckTrueTypePatents). */
/* */
/* <Input> */
/* face :: A face handle. */
/* */
/* value :: New boolean setting. */
/* */
/* <Return> */
/* The old setting value. This will always be false if this is not */
/* a SFNT font, or if the unpatented hinter is not compiled in this */
/* instance of the library. */
/* */
/* <Since> */
/* 2.3.5 */
/* */
FT_EXPORT( FT_Bool )
FT_Face_SetUnpatentedHinting( FT_Face face,
FT_Bool value );
/* */ /* */
+115 -5
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* FreeType Cache subsystem (specification). */ /* FreeType Cache subsystem (specification). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -411,14 +411,14 @@ FT_BEGIN_HEADER
/* */ /* */
/* height :: The character height. */ /* height :: The character height. */
/* */ /* */
/* pixel :: A Boolean. If TRUE, the `width' and `height' fields */ /* pixel :: A Boolean. If 1, the `width' and `height' fields are */
/* are interpreted as integer pixel character sizes. */ /* interpreted as integer pixel character sizes. */
/* Otherwise, they are expressed as 1/64th of points. */ /* Otherwise, they are expressed as 1/64th of points. */
/* */ /* */
/* x_res :: Only used when `pixel' is FALSE to indicate the */ /* x_res :: Only used when `pixel' is value 0 to indicate the */
/* horizontal resolution in dpi. */ /* horizontal resolution in dpi. */
/* */ /* */
/* y_res :: Only used when `pixel' is FALSE to indicate the */ /* y_res :: Only used when `pixel' is value 0 to indicate the */
/* vertical resolution in dpi. */ /* vertical resolution in dpi. */
/* */ /* */
/* <Note> */ /* <Note> */
@@ -776,6 +776,60 @@ FT_BEGIN_HEADER
FTC_Node *anode ); FTC_Node *anode );
/*************************************************************************/
/* */
/* <Function> */
/* FTC_ImageCache_LookupScaler */
/* */
/* <Description> */
/* A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec */
/* to specify the face ID and its size. */
/* */
/* <Input> */
/* cache :: A handle to the source glyph image cache. */
/* */
/* scaler :: A pointer to a scaler descriptor. */
/* */
/* load_flags :: The corresponding load flags. */
/* */
/* gindex :: The glyph index to retrieve. */
/* */
/* <Output> */
/* aglyph :: The corresponding @FT_Glyph object. 0 in case of */
/* failure. */
/* */
/* anode :: Used to return the address of of the corresponding */
/* cache node after incrementing its reference count */
/* (see note below). */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The returned glyph is owned and managed by the glyph image cache. */
/* Never try to transform or discard it manually! You can however */
/* create a copy with @FT_Glyph_Copy and modify the new one. */
/* */
/* If `anode' is _not_ NULL, it receives the address of the cache */
/* node containing the glyph image, after increasing its reference */
/* count. This ensures that the node (as well as the @FT_Glyph) will */
/* always be kept in the cache until you call @FTC_Node_Unref to */
/* `release' it. */
/* */
/* If `anode' is NULL, the cache node is left unchanged, which means */
/* that the @FT_Glyph could be flushed out of the cache on the next */
/* call to one of the caching sub-system APIs. Don't assume that it */
/* is persistent! */
/* */
FT_EXPORT( FT_Error )
FTC_ImageCache_LookupScaler( FTC_ImageCache cache,
FTC_Scaler scaler,
FT_ULong load_flags,
FT_UInt gindex,
FT_Glyph *aglyph,
FTC_Node *anode );
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* <Type> */ /* <Type> */
@@ -930,6 +984,62 @@ FT_BEGIN_HEADER
FTC_Node *anode ); FTC_Node *anode );
/*************************************************************************/
/* */
/* <Function> */
/* FTC_SBitCache_LookupScaler */
/* */
/* <Description> */
/* A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec */
/* to specify the face ID and its size. */
/* */
/* <Input> */
/* cache :: A handle to the source sbit cache. */
/* */
/* scaler :: A pointer to the scaler descriptor. */
/* */
/* load_flags :: The corresponding load flags. */
/* */
/* gindex :: The glyph index. */
/* */
/* <Output> */
/* sbit :: A handle to a small bitmap descriptor. */
/* */
/* anode :: Used to return the address of of the corresponding */
/* cache node after incrementing its reference count */
/* (see note below). */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The small bitmap descriptor and its bit buffer are owned by the */
/* cache and should never be freed by the application. They might */
/* as well disappear from memory on the next cache lookup, so don't */
/* treat them as persistent data. */
/* */
/* The descriptor's `buffer' field is set to 0 to indicate a missing */
/* glyph bitmap. */
/* */
/* If `anode' is _not_ NULL, it receives the address of the cache */
/* node containing the bitmap, after increasing its reference count. */
/* This ensures that the node (as well as the image) will always be */
/* kept in the cache until you call @FTC_Node_Unref to `release' it. */
/* */
/* If `anode' is NULL, the cache node is left unchanged, which means */
/* that the bitmap could be flushed out of the cache on the next */
/* call to one of the caching sub-system APIs. Don't assume that it */
/* is persistent! */
/* */
FT_EXPORT( FT_Error )
FTC_SBitCache_LookupScaler( FTC_SBitCache cache,
FTC_Scaler scaler,
FT_ULong load_flags,
FT_UInt gindex,
FTC_SBit *sbit,
FTC_Node *anode );
/* */ /* */
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
+5 -1
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* FreeType error codes (specification). */ /* FreeType error codes (specification). */
/* */ /* */
/* Copyright 2002, 2004, 2006 by */ /* Copyright 2002, 2004, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -230,6 +230,10 @@
"`BBX' field missing" ) "`BBX' field missing" )
FT_ERRORDEF_( Bbx_Too_Big, 0xB7, \ FT_ERRORDEF_( Bbx_Too_Big, 0xB7, \
"`BBX' too big" ) "`BBX' too big" )
FT_ERRORDEF_( Corrupted_Font_Header, 0xB8, \
"Font header corrupted or missing fields" )
FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xB9, \
"Font glyphs corrupted or missing fields" )
/* END */ /* END */
+1 -1
View File
@@ -316,7 +316,7 @@ FT_BEGIN_HEADER
/************************************************************************** /**************************************************************************
* *
* @section: * @section:
* ttengine * truetype_engine
* *
* @title: * @title:
* The TrueType Engine * The TrueType Engine
+6 -6
View File
@@ -297,8 +297,8 @@ FT_BEGIN_HEADER
* The source outline. * The source outline.
* *
* opened :: * opened ::
* A boolean. If TRUE, the outline is treated as an open path * A boolean. If 1, the outline is treated as an open path instead
* instead of a closed one. * of a closed one.
* *
* @return: * @return:
* FreeType error code. 0 means success. * FreeType error code. 0 means success.
@@ -334,7 +334,7 @@ FT_BEGIN_HEADER
* A pointer to the start vector. * A pointer to the start vector.
* *
* open :: * open ::
* A boolean. If TRUE, the sub-path is treated as an open one. * A boolean. If 1, the sub-path is treated as an open one.
* *
* @return: * @return:
* FreeType error code. 0 means success. * FreeType error code. 0 means success.
@@ -649,7 +649,7 @@ FT_BEGIN_HEADER
* A stroker handle. * A stroker handle.
* *
* destroy :: * destroy ::
* A Boolean. If TRUE, the source glyph object is destroyed * A Boolean. If 1, the source glyph object is destroyed
* on success. * on success.
* *
* @return: * @return:
@@ -682,11 +682,11 @@ FT_BEGIN_HEADER
* A stroker handle. * A stroker handle.
* *
* inside :: * inside ::
* A Boolean. If TRUE, return the inside border, otherwise * A Boolean. If 1, return the inside border, otherwise
* the outside border. * the outside border.
* *
* destroy :: * destroy ::
* A Boolean. If TRUE, the source glyph object is destroyed * A Boolean. If 1, the source glyph object is destroyed
* on success. * on success.
* *
* @return: * @return:
+3 -2
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* FreeType simple types definitions (specification only). */ /* FreeType simple types definitions (specification only). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2004, 2006 by */ /* Copyright 1996-2001, 2002, 2004, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -94,7 +94,8 @@ FT_BEGIN_HEADER
/* FT_Bool */ /* FT_Bool */
/* */ /* */
/* <Description> */ /* <Description> */
/* A typedef of unsigned char, used for simple booleans. */ /* A typedef of unsigned char, used for simple booleans. As usual, */
/* values 1 and 0 represent true and false, respectively. */
/* */ /* */
typedef unsigned char FT_Bool; typedef unsigned char FT_Bool;
@@ -89,6 +89,25 @@ FT_BEGIN_HEADER
ft_highpow2( FT_UInt32 value ); ft_highpow2( FT_UInt32 value );
/*
* character classification functions -- since these are used to parse
* font files, we must not use those in <ctypes.h> which are
* locale-dependent
*/
#define ft_isdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U )
#define ft_isxdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U || \
( (unsigned)(x) - 'a' ) < 6U || \
( (unsigned)(x) - 'A' ) < 6U )
/* the next two macros assume ASCII representation */
#define ft_isupper( x ) ( ( (unsigned)(x) - 'A' ) < 26U )
#define ft_islower( x ) ( ( (unsigned)(x) - 'a' ) < 26U )
#define ft_isalpha( x ) ( ft_isupper( x ) || ft_islower( x ) )
#define ft_isalnum( x ) ( ft_isdigit( x ) || ft_isalpha( x ) )
/*************************************************************************/ /*************************************************************************/
/*************************************************************************/ /*************************************************************************/
/*************************************************************************/ /*************************************************************************/
@@ -4,7 +4,7 @@
/* */ /* */
/* The FreeType services (specification only). */ /* The FreeType services (specification only). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006 by */ /* Copyright 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -315,6 +315,7 @@ FT_BEGIN_HEADER
#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> #define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h>
#define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h> #define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h>
#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h> #define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h>
#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h>
/* */ /* */
@@ -52,6 +52,7 @@ FT_BEGIN_HEADER
typedef struct TT_CMapInfo_ typedef struct TT_CMapInfo_
{ {
FT_ULong language; FT_ULong language;
FT_Long format;
} TT_CMapInfo; } TT_CMapInfo;
@@ -0,0 +1,48 @@
/***************************************************************************/
/* */
/* svttglyf.h */
/* */
/* The FreeType TrueType glyph service. */
/* */
/* Copyright 2007 by David Turner. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* 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 __SVTTGLYF_H__
#define __SVTTGLYF_H__
#include FT_INTERNAL_SERVICE_H
#include FT_TRUETYPE_TABLES_H
FT_BEGIN_HEADER
#define FT_SERVICE_ID_TT_GLYF "tt-glyf"
typedef FT_ULong
(*TT_Glyf_GetLocationFunc)( FT_Face face,
FT_UInt gindex,
FT_ULong *psize );
FT_DEFINE_SERVICE( TTGlyf )
{
TT_Glyf_GetLocationFunc get_location;
};
/* */
FT_END_HEADER
#endif /* __SVTTGLYF_H__ */
/* END */
@@ -725,6 +725,26 @@ FT_BEGIN_HEADER
FT_EXPORT( FT_ULong ) FT_EXPORT( FT_ULong )
FT_Get_CMap_Language_ID( FT_CharMap charmap ); FT_Get_CMap_Language_ID( FT_CharMap charmap );
/*************************************************************************/
/* */
/* <Function> */
/* FT_Get_CMap_Format */
/* */
/* <Description> */
/* Return TrueType/sfnt specific cmap format. */
/* */
/* <Input> */
/* charmap :: */
/* The target charmap. */
/* */
/* <Return> */
/* The format of `charmap'. If `charmap' doesn't belong to a */
/* TrueType/sfnt face, return -1. */
/* */
FT_EXPORT( FT_Long )
FT_Get_CMap_Format( FT_CharMap charmap );
/* */ /* */
+1 -1
View File
@@ -21,7 +21,7 @@ UseFreeTypeHeaders ;
if $(FT2_MULTI) if $(FT2_MULTI)
{ {
_sources = afangles afglobal afhints aflatin afloader afmodule afdummy afwarp ; _sources = afangles afglobal afhints aflatin afcjk afindic afloader afmodule afdummy afwarp ;
} }
else else
{ {
+3 -7
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter hinting routines for CJK script (body). */ /* Auto-fitter hinting routines for CJK script (body). */
/* */ /* */
/* Copyright 2006 by */ /* Copyright 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -332,7 +332,6 @@
AF_Segment segment_limit = segments + axis->num_segments; AF_Segment segment_limit = segments + axis->num_segments;
AF_Segment seg; AF_Segment seg;
AF_Direction up_dir;
FT_Fixed scale; FT_Fixed scale;
FT_Pos edge_distance_threshold; FT_Pos edge_distance_threshold;
@@ -342,9 +341,6 @@
scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale
: hints->y_scale; : hints->y_scale;
up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP
: AF_DIR_RIGHT;
/*********************************************************************/ /*********************************************************************/
/* */ /* */
/* We begin by generating a sorted table of edges for the current */ /* We begin by generating a sorted table of edges for the current */
@@ -431,7 +427,7 @@
/* insert a new edge in the list and */ /* insert a new edge in the list and */
/* sort according to the position */ /* sort according to the position */
error = af_axis_hints_new_edge( axis, seg->pos, memory, &edge ); error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, memory, &edge );
if ( error ) if ( error )
goto Exit; goto Exit;
@@ -1365,7 +1361,7 @@
FT_UNUSED( metrics ); FT_UNUSED( metrics );
error = af_glyph_hints_reload( hints, outline ); error = af_glyph_hints_reload( hints, outline, 0 );
if ( error ) if ( error )
goto Exit; goto Exit;
+20 -2
View File
@@ -20,21 +20,29 @@
#include "afdummy.h" #include "afdummy.h"
#include "aflatin.h" #include "aflatin.h"
#include "afcjk.h" #include "afcjk.h"
#include "afindic.h"
#include "aferrors.h" #include "aferrors.h"
#ifdef FT_OPTION_AUTOFIT2
#include "aflatin2.h"
#endif
/* populate this list when you add new scripts */ /* populate this list when you add new scripts */
static AF_ScriptClass const af_script_classes[] = static AF_ScriptClass const af_script_classes[] =
{ {
&af_dummy_script_class, &af_dummy_script_class,
#ifdef FT_OPTION_AUTOFIT2
&af_latin2_script_class,
#endif
&af_latin_script_class, &af_latin_script_class,
&af_cjk_script_class, &af_cjk_script_class,
&af_indic_script_class,
NULL /* do not remove */ NULL /* do not remove */
}; };
/* index of default script in `af_script_classes' */ /* index of default script in `af_script_classes' */
#define AF_SCRIPT_LIST_DEFAULT 1 #define AF_SCRIPT_LIST_DEFAULT 2
/* indicates an uncovered glyph */ /* indicates an uncovered glyph */
#define AF_SCRIPT_LIST_NONE 255 #define AF_SCRIPT_LIST_NONE 255
@@ -217,11 +225,15 @@
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_face_globals_get_metrics( AF_FaceGlobals globals, af_face_globals_get_metrics( AF_FaceGlobals globals,
FT_UInt gindex, FT_UInt gindex,
FT_UInt options,
AF_ScriptMetrics *ametrics ) AF_ScriptMetrics *ametrics )
{ {
AF_ScriptMetrics metrics = NULL; AF_ScriptMetrics metrics = NULL;
FT_UInt gidx; FT_UInt gidx;
AF_ScriptClass clazz; AF_ScriptClass clazz;
FT_UInt script = options & 15;
const FT_UInt script_max = sizeof ( af_script_classes ) /
sizeof ( af_script_classes[0] );
FT_Error error = AF_Err_Ok; FT_Error error = AF_Err_Ok;
@@ -231,8 +243,14 @@
goto Exit; goto Exit;
} }
gidx = script;
if ( gidx == 0 || gidx + 1 >= script_max )
gidx = globals->glyph_scripts[gindex]; gidx = globals->glyph_scripts[gindex];
clazz = af_script_classes[gidx]; clazz = af_script_classes[gidx];
if ( script == 0 )
script = clazz->script;
metrics = globals->metrics[clazz->script]; metrics = globals->metrics[clazz->script];
if ( metrics == NULL ) if ( metrics == NULL )
{ {
+2 -1
View File
@@ -5,7 +5,7 @@
/* Auto-fitter routines to compute global hinting values */ /* Auto-fitter routines to compute global hinting values */
/* (specification). */ /* (specification). */
/* */ /* */
/* Copyright 2003, 2004, 2005 by */ /* Copyright 2003, 2004, 2005, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -50,6 +50,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
af_face_globals_get_metrics( AF_FaceGlobals globals, af_face_globals_get_metrics( AF_FaceGlobals globals,
FT_UInt gindex, FT_UInt gindex,
FT_UInt options,
AF_ScriptMetrics *ametrics ); AF_ScriptMetrics *ametrics );
FT_LOCAL( void ) FT_LOCAL( void )
+209 -273
View File
@@ -54,9 +54,6 @@
} }
segment = axis->segments + axis->num_segments++; segment = axis->segments + axis->num_segments++;
#if 0
FT_ZERO( segment );
#endif
Exit: Exit:
*asegment = segment; *asegment = segment;
@@ -67,6 +64,7 @@
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
af_axis_hints_new_edge( AF_AxisHints axis, af_axis_hints_new_edge( AF_AxisHints axis,
FT_Int fpos, FT_Int fpos,
AF_Direction dir,
FT_Memory memory, FT_Memory memory,
AF_Edge *aedge ) AF_Edge *aedge )
{ {
@@ -101,8 +99,16 @@
edges = axis->edges; edges = axis->edges;
edge = edges + axis->num_edges; edge = edges + axis->num_edges;
while ( edge > edges && edge[-1].fpos > fpos ) while ( edge > edges )
{ {
if ( edge[-1].fpos < fpos )
break;
/* we want the edge with same position and minor direction */
/* to appear before those in the major one in the list */
if ( edge[-1].fpos == fpos && dir == axis->major_dir )
break;
edge[0] = edge[-1]; edge[0] = edge[-1];
edge--; edge--;
} }
@@ -111,6 +117,7 @@
FT_ZERO( edge ); FT_ZERO( edge );
edge->fpos = (FT_Short)fpos; edge->fpos = (FT_Short)fpos;
edge->dir = (FT_Char)dir;
Exit: Exit:
*aedge = edge; *aedge = edge;
@@ -187,6 +194,34 @@
} }
static const char*
af_edge_flags_to_string( AF_Edge_Flags flags )
{
static char temp[32];
int pos = 0;
if ( flags & AF_EDGE_ROUND )
{
memcpy( temp + pos, "round", 5 );
pos += 5;
}
if ( flags & AF_EDGE_SERIF )
{
if ( pos > 0 )
temp[pos++] = ' ';
memcpy( temp + pos, "serif", 5 );
pos += 5;
}
if ( pos == 0 )
return "normal";
temp[pos] = 0;
return temp;
}
/* A function to dump the array of linked segments. */ /* A function to dump the array of linked segments. */
void void
af_glyph_hints_dump_segments( AF_GlyphHints hints ) af_glyph_hints_dump_segments( AF_GlyphHints hints )
@@ -205,18 +240,20 @@
printf ( "Table of %s segments:\n", printf ( "Table of %s segments:\n",
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
printf ( " [ index | pos | dir | link | serif |" printf ( " [ index | pos | dir | link | serif |"
" height | extra ]\n" ); " height | extra | flags ]\n" );
for ( seg = segments; seg < limit; seg++ ) for ( seg = segments; seg < limit; seg++ )
{ {
printf ( " [ %5d | %4d | %5s | %4d | %5d | %5d | %5d ]\n", printf ( " [ %5d | %5.2g | %5s | %4d | %5d | %5d | %5d | %s ]\n",
seg - segments, seg - segments,
(int)seg->pos, dimension == AF_DIMENSION_HORZ ? (int)seg->first->ox / 64.0
: (int)seg->first->oy / 64.0,
af_dir_str( (AF_Direction)seg->dir ), af_dir_str( (AF_Direction)seg->dir ),
AF_INDEX_NUM( seg->link, segments ), AF_INDEX_NUM( seg->link, segments ),
AF_INDEX_NUM( seg->serif, segments ), AF_INDEX_NUM( seg->serif, segments ),
seg->height, seg->height,
seg->height - ( seg->max_coord - seg->min_coord ) ); seg->height - ( seg->max_coord - seg->min_coord ),
af_edge_flags_to_string( seg->flags ) );
} }
printf( "\n" ); printf( "\n" );
} }
@@ -244,20 +281,21 @@
printf ( "Table of %s edges:\n", printf ( "Table of %s edges:\n",
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
printf ( " [ index | pos | dir | link |" printf ( " [ index | pos | dir | link |"
" serif | blue | opos | pos ]\n" ); " serif | blue | opos | pos | flags ]\n" );
for ( edge = edges; edge < limit; edge++ ) for ( edge = edges; edge < limit; edge++ )
{ {
printf ( " [ %5d | %4d | %5s | %4d |" printf ( " [ %5d | %5.2g | %5s | %4d |"
" %5d | %c | %5.2f | %5.2f ]\n", " %5d | %c | %5.2f | %5.2f | %s ]\n",
edge - edges, edge - edges,
(int)edge->fpos, (int)edge->opos / 64.0,
af_dir_str( (AF_Direction)edge->dir ), af_dir_str( (AF_Direction)edge->dir ),
AF_INDEX_NUM( edge->link, edges ), AF_INDEX_NUM( edge->link, edges ),
AF_INDEX_NUM( edge->serif, edges ), AF_INDEX_NUM( edge->serif, edges ),
edge->blue_edge ? 'y' : 'n', edge->blue_edge ? 'y' : 'n',
edge->opos / 64.0, edge->opos / 64.0,
edge->pos / 64.0 ); edge->pos / 64.0,
af_edge_flags_to_string( edge->flags ) );
} }
printf( "\n" ); printf( "\n" );
} }
@@ -296,9 +334,6 @@
af_direction_compute( FT_Pos dx, af_direction_compute( FT_Pos dx,
FT_Pos dy ) FT_Pos dy )
{ {
#if 1
FT_Pos ll, ss; /* long and short arm lengths */ FT_Pos ll, ss; /* long and short arm lengths */
AF_Direction dir; /* candidate direction */ AF_Direction dir; /* candidate direction */
@@ -334,45 +369,16 @@
} }
} }
ss *= 12; ss *= 14;
if ( FT_ABS(ll) <= FT_ABS(ss) ) if ( FT_ABS( ll ) <= FT_ABS( ss ) )
dir = AF_DIR_NONE; dir = AF_DIR_NONE;
return dir; return dir;
#else /* 0 */
AF_Direction dir;
FT_Pos ax = FT_ABS( dx );
FT_Pos ay = FT_ABS( dy );
dir = AF_DIR_NONE;
/* atan(1/12) == 4.7 degrees */
/* test for vertical direction */
if ( ax * 12 < ay )
{
dir = dy > 0 ? AF_DIR_UP : AF_DIR_DOWN;
}
/* test for horizontal direction */
else if ( ay * 12 < ax )
{
dir = dx > 0 ? AF_DIR_RIGHT : AF_DIR_LEFT;
}
return dir;
#endif /* 0 */
} }
/* compute all inflex points in a given glyph */ /* compute all inflex points in a given glyph */
#if 1
static void static void
af_glyph_hints_compute_inflections( AF_GlyphHints hints ) af_glyph_hints_compute_inflections( AF_GlyphHints hints )
{ {
@@ -484,117 +490,6 @@
} }
} }
#else /* old code */
static void
af_glyph_hints_compute_inflections( AF_GlyphHints hints )
{
AF_Point* contour = hints->contours;
AF_Point* contour_limit = contour + hints->num_contours;
/* do each contour separately */
for ( ; contour < contour_limit; contour++ )
{
AF_Point point = contour[0];
AF_Point first = point;
AF_Point start = point;
AF_Point end = point;
AF_Point before;
AF_Point after;
AF_Angle angle_in, angle_seg, angle_out;
AF_Angle diff_in, diff_out;
FT_Int finished = 0;
/* compute first segment in contour */
first = point;
start = end = first;
do
{
end = end->next;
if ( end == first )
goto Skip;
} while ( end->fx == first->fx && end->fy == first->fy );
angle_seg = af_angle_atan( end->fx - start->fx,
end->fy - start->fy );
/* extend the segment start whenever possible */
before = start;
do
{
do
{
start = before;
before = before->prev;
if ( before == first )
goto Skip;
} while ( before->fx == start->fx && before->fy == start->fy );
angle_in = af_angle_atan( start->fx - before->fx,
start->fy - before->fy );
} while ( angle_in == angle_seg );
first = start;
AF_ANGLE_DIFF( diff_in, angle_in, angle_seg );
/* now, process all segments in the contour */
do
{
/* first, extend current segment's end whenever possible */
after = end;
do
{
do
{
end = after;
after = after->next;
if ( after == first )
finished = 1;
} while ( end->fx == after->fx && end->fy == after->fy );
angle_out = af_angle_atan( after->fx - end->fx,
after->fy - end->fy );
} while ( angle_out == angle_seg );
AF_ANGLE_DIFF( diff_out, angle_seg, angle_out );
if ( ( diff_in ^ diff_out ) < 0 )
{
/* diff_in and diff_out have different signs, we have */
/* inflection points here... */
do
{
start->flags |= AF_FLAG_INFLECTION;
start = start->next;
} while ( start != end );
start->flags |= AF_FLAG_INFLECTION;
}
start = end;
end = after;
angle_seg = angle_out;
diff_in = diff_out;
} while ( !finished );
Skip:
;
}
}
#endif /* old code */
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_glyph_hints_init( AF_GlyphHints hints, af_glyph_hints_init( AF_GlyphHints hints,
@@ -656,7 +551,8 @@
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_glyph_hints_reload( AF_GlyphHints hints, af_glyph_hints_reload( AF_GlyphHints hints,
FT_Outline* outline ) FT_Outline* outline,
FT_Bool get_inflections )
{ {
FT_Error error = AF_Err_Ok; FT_Error error = AF_Err_Ok;
AF_Point points; AF_Point points;
@@ -739,10 +635,14 @@
AF_Point point_limit = points + hints->num_points; AF_Point point_limit = points + hints->num_points;
/* compute coordinates & Bezier flags */ /* compute coordinates & Bezier flags, next and prev */
{ {
FT_Vector* vec = outline->points; FT_Vector* vec = outline->points;
char* tag = outline->tags; char* tag = outline->tags;
AF_Point first = points;
AF_Point end = points + outline->contours[0];
AF_Point prev = end;
FT_Int contour_index = 0;
for ( point = points; point < point_limit; point++, vec++, tag++ ) for ( point = points; point < point_limit; point++, vec++, tag++ )
@@ -763,39 +663,17 @@
default: default:
point->flags = 0; point->flags = 0;
} }
}
}
/* compute `next' and `prev' */
{
FT_Int contour_index;
AF_Point prev;
AF_Point first;
AF_Point end;
contour_index = 0;
first = points;
end = points + outline->contours[0];
prev = end;
for ( point = points; point < point_limit; point++ )
{
point->prev = prev; point->prev = prev;
if ( point < end ) prev->next = point;
{
point->next = point + 1;
prev = point; prev = point;
}
else if ( point == end )
{ {
point->next = first; if ( ++contour_index < outline->n_contours )
contour_index++;
if ( point + 1 < point_limit )
{ {
end = points + outline->contours[contour_index];
first = point + 1; first = point + 1;
end = points + outline->contours[contour_index];
prev = end; prev = end;
} }
} }
@@ -819,24 +697,36 @@
/* compute directions of in & out vectors */ /* compute directions of in & out vectors */
{ {
AF_Point first = points;
AF_Point prev = NULL;
FT_Pos in_x = 0;
FT_Pos in_y = 0;
AF_Direction in_dir = AF_DIR_NONE;
for ( point = points; point < point_limit; point++ ) for ( point = points; point < point_limit; point++ )
{ {
AF_Point prev;
AF_Point next; AF_Point next;
FT_Pos in_x, in_y, out_x, out_y; FT_Pos out_x, out_y;
prev = point->prev; if ( point == first )
in_x = point->fx - prev->fx; {
in_y = point->fy - prev->fy; prev = first->prev;
in_x = first->fx - prev->fx;
in_y = first->fy - prev->fy;
in_dir = af_direction_compute( in_x, in_y );
first = prev + 1;
}
point->in_dir = (FT_Char)af_direction_compute( in_x, in_y ); point->in_dir = (FT_Char)in_dir;
next = point->next; next = point->next;
out_x = next->fx - point->fx; out_x = next->fx - point->fx;
out_y = next->fy - point->fy; out_y = next->fy - point->fy;
point->out_dir = (FT_Char)af_direction_compute( out_x, out_y ); in_dir = af_direction_compute( out_x, out_y );
point->out_dir = (FT_Char)in_dir;
if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) ) if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) )
{ {
@@ -845,41 +735,25 @@
} }
else if ( point->out_dir == point->in_dir ) else if ( point->out_dir == point->in_dir )
{ {
#if 1
if ( point->out_dir != AF_DIR_NONE ) if ( point->out_dir != AF_DIR_NONE )
goto Is_Weak_Point; goto Is_Weak_Point;
if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) ) if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) )
goto Is_Weak_Point; goto Is_Weak_Point;
#else /* old code */
AF_Angle angle_in, angle_out, delta;
if ( point->out_dir != AF_DIR_NONE )
goto Is_Weak_Point;
angle_in = af_angle_atan( in_x, in_y );
angle_out = af_angle_atan( out_x, out_y );
AF_ANGLE_DIFF( delta, angle_in, angle_out );
if ( delta < 2 && delta > -2 )
goto Is_Weak_Point;
#endif /* old code */
} }
else if ( point->in_dir == -point->out_dir ) else if ( point->in_dir == -point->out_dir )
goto Is_Weak_Point; goto Is_Weak_Point;
in_x = out_x;
in_y = out_y;
prev = point;
} }
} }
} }
/* compute inflection points */ /* compute inflection points -- */
/* disabled due to no longer perceived benefits */
if ( 0 && get_inflections )
af_glyph_hints_compute_inflections( hints ); af_glyph_hints_compute_inflections( hints );
Exit: Exit:
@@ -924,45 +798,63 @@
AF_Dimension dim ) AF_Dimension dim )
{ {
AF_AxisHints axis = & hints->axis[dim]; AF_AxisHints axis = & hints->axis[dim];
AF_Edge edges = axis->edges; AF_Segment segments = axis->segments;
AF_Edge edge_limit = edges + axis->num_edges; AF_Segment segment_limit = segments + axis->num_segments;
AF_Edge edge; AF_Segment seg;
for ( edge = edges; edge < edge_limit; edge++ )
{
/* move the points of each segment */
/* in each edge to the edge's position */
AF_Segment seg = edge->first;
do
{
AF_Point point = seg->first;
for (;;)
{
if ( dim == AF_DIMENSION_HORZ ) if ( dim == AF_DIMENSION_HORZ )
{
for ( seg = segments; seg < segment_limit; seg++ )
{
AF_Edge edge = seg->edge;
AF_Point point, first, last;
if ( edge == NULL )
continue;
first = seg->first;
last = seg->last;
point = first;
for (;;)
{ {
point->x = edge->pos; point->x = edge->pos;
point->flags |= AF_FLAG_TOUCH_X; point->flags |= AF_FLAG_TOUCH_X;
if ( point == last )
break;
point = point->next;
}
}
} }
else else
{
for ( seg = segments; seg < segment_limit; seg++ )
{
AF_Edge edge = seg->edge;
AF_Point point, first, last;
if ( edge == NULL )
continue;
first = seg->first;
last = seg->last;
point = first;
for (;;)
{ {
point->y = edge->pos; point->y = edge->pos;
point->flags |= AF_FLAG_TOUCH_Y; point->flags |= AF_FLAG_TOUCH_Y;
}
if ( point == seg->last ) if ( point == last )
break; break;
point = point->next; point = point->next;
} }
}
seg = seg->edge_next;
} while ( seg != edge->first );
} }
} }
@@ -1056,6 +948,25 @@
min = 0; min = 0;
max = edge_limit - edges; max = edge_limit - edges;
#if 1
/* for small edge counts, a linear search is better */
if ( max <= 8 )
{
FT_UInt nn;
for ( nn = 0; nn < max; nn++ )
if ( edges[nn].fpos >= u )
break;
if ( edges[nn].fpos == u )
{
u = edges[nn].pos;
goto Store_Point;
}
min = nn;
}
else
#endif
while ( min < max ) while ( min < max )
{ {
mid = ( max + min ) >> 1; mid = ( max + min ) >> 1;
@@ -1117,6 +1028,8 @@
AF_Point p; AF_Point p;
FT_Pos delta = ref->u - ref->v; FT_Pos delta = ref->u - ref->v;
if ( delta == 0 )
return;
for ( p = p1; p < ref; p++ ) for ( p = p1; p < ref; p++ )
p->u = p->v + delta; p->u = p->v + delta;
@@ -1235,53 +1148,76 @@
for ( ; contour < contour_limit; contour++ ) for ( ; contour < contour_limit; contour++ )
{ {
AF_Point first_touched, last_touched;
point = *contour; point = *contour;
end_point = point->prev; end_point = point->prev;
first_point = point; first_point = point;
while ( point <= end_point && !( point->flags & touch_flag ) ) /* find first touched point */
point++; for (;;)
if ( point <= end_point )
{ {
AF_Point first_touched = point; if ( point > end_point ) /* no touched point in contour */
AF_Point cur_touched = point; goto NextContour;
point++;
while ( point <= end_point )
{
if ( point->flags & touch_flag ) if ( point->flags & touch_flag )
{ break;
/* we found two successive touched points; we interpolate */
/* all contour points between them */
af_iup_interp( cur_touched + 1, point - 1,
cur_touched, point );
cur_touched = point;
}
point++; point++;
} }
if ( cur_touched == first_touched ) first_touched = point;
{ last_touched = point;
/* this is a special case: only one point was touched in the */
/* contour; we thus simply shift the whole contour */ for (;;)
af_iup_shift( first_point, end_point, cur_touched ); {
} FT_ASSERT( point <= end_point &&
else ( point->flags & touch_flag ) != 0 );
{
/* now interpolate after the last touched point to the end */ /* skip any touched neighbhours */
/* of the contour */ while ( point < end_point && ( point[1].flags & touch_flag ) != 0 )
af_iup_interp( cur_touched + 1, end_point, point++;
cur_touched, first_touched );
last_touched = point;
/* find the next touched point, if any */
point ++;
for (;;)
{
if ( point > end_point )
goto EndContour;
if ( ( point->flags & touch_flag ) != 0 )
break;
point++;
}
/* interpolate between last_touched and point */
af_iup_interp( last_touched + 1, point - 1,
last_touched, point );
}
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 )
af_iup_interp( last_touched + 1, end_point,
last_touched, first_touched );
/* if the first contour point isn't touched, interpolate */
/* from the contour start to the first touched point */
if ( first_touched > points ) if ( first_touched > points )
af_iup_interp( first_point, first_touched - 1, af_iup_interp( first_point, first_touched - 1,
cur_touched, first_touched ); last_touched, first_touched );
}
} }
NextContour:
;
} }
/* now save the interpolated values back to x/y */ /* now save the interpolated values back to x/y */
+7 -1
View File
@@ -21,6 +21,7 @@
#include "aftypes.h" #include "aftypes.h"
#define xxAF_SORT_SEGMENTS
FT_BEGIN_HEADER FT_BEGIN_HEADER
@@ -171,6 +172,9 @@ FT_BEGIN_HEADER
FT_Int num_segments; FT_Int num_segments;
FT_Int max_segments; FT_Int max_segments;
AF_Segment segments; AF_Segment segments;
#ifdef AF_SORT_SEGMENTS
FT_Int mid_segments;
#endif
FT_Int num_edges; FT_Int num_edges;
FT_Int max_edges; FT_Int max_edges;
@@ -262,6 +266,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error) FT_LOCAL( FT_Error)
af_axis_hints_new_edge( AF_AxisHints axis, af_axis_hints_new_edge( AF_AxisHints axis,
FT_Int fpos, FT_Int fpos,
AF_Direction dir,
FT_Memory memory, FT_Memory memory,
AF_Edge *edge ); AF_Edge *edge );
@@ -281,7 +286,8 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
af_glyph_hints_reload( AF_GlyphHints hints, af_glyph_hints_reload( AF_GlyphHints hints,
FT_Outline* outline ); FT_Outline* outline,
FT_Bool get_inflections );
FT_LOCAL( void ) FT_LOCAL( void )
af_glyph_hints_save( AF_GlyphHints hints, af_glyph_hints_save( AF_GlyphHints hints,
+134
View File
@@ -0,0 +1,134 @@
/***************************************************************************/
/* */
/* afindic.c */
/* */
/* Auto-fitter hinting routines for Indic scripts (body). */
/* */
/* Copyright 2007 by */
/* Rahul Bhalerao <[email protected]>, <[email protected]>. */
/* */
/* 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 "aftypes.h"
#include "aflatin.h"
#ifdef AF_CONFIG_OPTION_INDIC
#include "afindic.h"
#include "aferrors.h"
#include "afcjk.h"
#ifdef AF_USE_WARPER
#include "afwarp.h"
#endif
static FT_Error
af_indic_metrics_init( AF_LatinMetrics metrics,
FT_Face face )
{
/* use CJK routines */
return af_cjk_metrics_init( metrics, face );
}
static void
af_indic_metrics_scale( AF_LatinMetrics metrics,
AF_Scaler scaler )
{
/* use CJK routines */
af_cjk_metrics_scale( metrics, scaler );
}
static FT_Error
af_indic_hints_init( AF_GlyphHints hints,
AF_LatinMetrics metrics )
{
/* use CJK routines */
return af_cjk_hints_init( hints, metrics );
}
static FT_Error
af_indic_hints_apply( AF_GlyphHints hints,
FT_Outline* outline,
AF_LatinMetrics metrics)
{
/* use CJK routines */
return af_cjk_hints_apply( hints, outline, metrics );
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** I N D I C S C R I P T C L A S S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
static const AF_Script_UniRangeRec af_indic_uniranges[] =
{
#if 0
{ 0x0100, 0xFFFF }, /* why this? */
#endif
{ 0x0900, 0x0DFF}, /* Indic Range */
{ 0, 0 }
};
FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
af_indic_script_class =
{
AF_SCRIPT_INDIC,
af_indic_uniranges,
sizeof( AF_LatinMetricsRec ),
(AF_Script_InitMetricsFunc) af_indic_metrics_init,
(AF_Script_ScaleMetricsFunc)af_indic_metrics_scale,
(AF_Script_DoneMetricsFunc) NULL,
(AF_Script_InitHintsFunc) af_indic_hints_init,
(AF_Script_ApplyHintsFunc) af_indic_hints_apply
};
#else /* !AF_CONFIG_OPTION_INDIC */
static const AF_Script_UniRangeRec af_indic_uniranges[] =
{
{ 0, 0 }
};
FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
af_indic_script_class =
{
AF_SCRIPT_INDIC,
af_indic_uniranges,
sizeof( AF_LatinMetricsRec ),
(AF_Script_InitMetricsFunc) NULL,
(AF_Script_ScaleMetricsFunc)NULL,
(AF_Script_DoneMetricsFunc) NULL,
(AF_Script_InitHintsFunc) NULL,
(AF_Script_ApplyHintsFunc) NULL
};
#endif /* !AF_CONFIG_OPTION_INDIC */
/* END */
+41
View File
@@ -0,0 +1,41 @@
/***************************************************************************/
/* */
/* afindic.h */
/* */
/* Auto-fitter hinting routines for Indic scripts (specification). */
/* */
/* Copyright 2007 by */
/* Rahul Bhalerao <[email protected]>, <[email protected]>. */
/* */
/* 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 __AFINDIC_H__
#define __AFINDIC_H__
#include "afhints.h"
FT_BEGIN_HEADER
/* the Indic-specific script class */
FT_CALLBACK_TABLE const AF_ScriptClassRec
af_indic_script_class;
/* */
FT_END_HEADER
#endif /* __AFINDIC_H__ */
/* END */
+51 -113
View File
@@ -74,7 +74,7 @@
af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy );
error = af_glyph_hints_reload( hints, &face->glyph->outline ); error = af_glyph_hints_reload( hints, &face->glyph->outline, 0 );
if ( error ) if ( error )
goto Exit; goto Exit;
@@ -269,6 +269,7 @@
/* now check whether the point belongs to a straight or round */ /* now check whether the point belongs to a straight or round */
/* segment; we first need to find in which contour the extremum */ /* segment; we first need to find in which contour the extremum */
/* lies, then inspect its previous and next points */ /* lies, then inspect its previous and next points */
if ( best_point >= 0 )
{ {
FT_Int prev, next; FT_Int prev, next;
FT_Pos dist; FT_Pos dist;
@@ -488,12 +489,15 @@
if ( scaled != fitted ) if ( scaled != fitted )
{ {
#if 0
if ( dim == AF_DIMENSION_HORZ ) if ( dim == AF_DIMENSION_HORZ )
{ {
if ( fitted < scaled ) if ( fitted < scaled )
scale -= scale / 50; /* scale *= 0.98 */ scale -= scale / 50; /* scale *= 0.98 */
} }
else else
#endif
if ( dim == AF_DIMENSION_VERT )
{ {
scale = FT_MulDiv( scale, fitted, scaled ); scale = FT_MulDiv( scale, fitted, scaled );
} }
@@ -527,7 +531,8 @@
/* an extra-light axis corresponds to a standard width that is */ /* an extra-light axis corresponds to a standard width that is */
/* smaller than 0.75 pixels */ /* smaller than 0.75 pixels */
axis->extra_light = FT_MulFix( axis->standard_width, scale ) < 32 + 8; axis->extra_light =
(FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 );
if ( dim == AF_DIMENSION_VERT ) if ( dim == AF_DIMENSION_VERT )
{ {
@@ -611,13 +616,6 @@
AF_Point* contour_limit = contour + hints->num_contours; AF_Point* contour_limit = contour + hints->num_contours;
AF_Direction major_dir, segment_dir; AF_Direction major_dir, segment_dir;
#ifdef AF_HINT_METRICS
AF_Point min_point = 0;
AF_Point max_point = 0;
FT_Pos min_coord = 32000;
FT_Pos max_coord = -32000;
#endif
FT_ZERO( &seg0 ); FT_ZERO( &seg0 );
seg0.score = 32000; seg0.score = 32000;
@@ -665,19 +663,6 @@
FT_Bool passed; FT_Bool passed;
#ifdef AF_HINT_METRICS
if ( point->u < min_coord )
{
min_coord = point->u;
min_point = point;
}
if ( point->u > max_coord )
{
max_coord = point->u;
max_point = point;
}
#endif
if ( point == last ) /* skip singletons -- just in case */ if ( point == last ) /* skip singletons -- just in case */
continue; continue;
@@ -773,14 +758,6 @@
segment->last = point; segment->last = point;
segment->contour = contour; segment->contour = contour;
on_edge = 1; on_edge = 1;
#ifdef AF_HINT_METRICS
if ( point == max_point )
max_point = 0;
if ( point == min_point )
min_point = 0;
#endif
} }
point = point->next; point = point->next;
@@ -840,77 +817,6 @@
} }
} }
#ifdef AF_HINT_METRICS
/* we need to ensure that there are edges on the left-most and */
/* right-most points of the glyph in order to hint the metrics; */
/* we do this by inserting fake segments when needed */
if ( dim == AF_DIMENSION_HORZ )
{
AF_Point point = hints->points;
AF_Point point_limit = point + hints->num_points;
FT_Pos min_pos = 32000;
FT_Pos max_pos = -32000;
min_point = 0;
max_point = 0;
/* compute minimum and maximum points */
for ( ; point < point_limit; point++ )
{
FT_Pos x = point->fx;
if ( x < min_pos )
{
min_pos = x;
min_point = point;
}
if ( x > max_pos )
{
max_pos = x;
max_point = point;
}
}
/* insert minimum segment */
if ( min_point )
{
/* clear all segment fields */
error = af_axis_hints_new_segment( axis, memory, &segment );
if ( error )
goto Exit;
segment[0] = seg0;
segment->dir = segment_dir;
segment->first = min_point;
segment->last = min_point;
segment->pos = min_pos;
segment = NULL;
}
/* insert maximum segment */
if ( max_point )
{
/* clear all segment fields */
error = af_axis_hints_new_segment( axis, memory, &segment );
if ( error )
goto Exit;
segment[0] = seg0;
segment->dir = segment_dir;
segment->first = max_point;
segment->last = max_point;
segment->pos = max_pos;
segment = NULL;
}
}
#endif /* AF_HINT_METRICS */
Exit: Exit:
return error; return error;
} }
@@ -938,11 +844,11 @@
{ {
/* the fake segments are introduced to hint the metrics -- */ /* the fake segments are introduced to hint the metrics -- */
/* we must never link them to anything */ /* we must never link them to anything */
if ( seg1->first == seg1->last ) if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )
continue; continue;
for ( seg2 = seg1 + 1; seg2 < segment_limit; seg2++ ) for ( seg2 = segments; seg2 < segment_limit; seg2++ )
if ( seg1->dir + seg2->dir == 0 ) if ( seg1->dir + seg2->dir == 0 && seg2->pos > seg1->pos )
{ {
FT_Pos pos1 = seg1->pos; FT_Pos pos1 = seg1->pos;
FT_Pos pos2 = seg2->pos; FT_Pos pos2 = seg2->pos;
@@ -1089,7 +995,7 @@
if ( dist < 0 ) if ( dist < 0 )
dist = -dist; dist = -dist;
if ( dist < edge_distance_threshold ) if ( dist < edge_distance_threshold && edge->dir == seg->dir )
{ {
found = edge; found = edge;
break; break;
@@ -1103,7 +1009,7 @@
/* insert a new edge in the list and */ /* insert a new edge in the list and */
/* sort according to the position */ /* sort according to the position */
error = af_axis_hints_new_edge( axis, seg->pos, memory, &edge ); error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, memory, &edge );
if ( error ) if ( error )
goto Exit; goto Exit;
@@ -1113,6 +1019,7 @@
edge->first = seg; edge->first = seg;
edge->last = seg; edge->last = seg;
edge->fpos = seg->pos; edge->fpos = seg->pos;
edge->dir = seg->dir;
edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); edge->opos = edge->pos = FT_MulFix( seg->pos, scale );
seg->edge_next = seg; seg->edge_next = seg;
} }
@@ -1253,6 +1160,7 @@
if ( is_round > 0 && is_round >= is_straight ) if ( is_round > 0 && is_round >= is_straight )
edge->flags |= AF_EDGE_ROUND; edge->flags |= AF_EDGE_ROUND;
#if 0
/* set the edge's main direction */ /* set the edge's main direction */
edge->dir = AF_DIR_NONE; edge->dir = AF_DIR_NONE;
@@ -1264,6 +1172,7 @@
else if ( ups == downs ) else if ( ups == downs )
edge->dir = 0; /* both up and down! */ edge->dir = 0; /* both up and down! */
#endif
/* gets rid of serifs if link is set */ /* gets rid of serifs if link is set */
/* XXX: This gets rid of many unpleasant artefacts! */ /* XXX: This gets rid of many unpleasant artefacts! */
@@ -2096,17 +2005,25 @@
if ( before >= edges && before < edge && if ( before >= edges && before < edge &&
after < edge_limit && after > edge ) after < edge_limit && after > edge )
{
edge->pos = before->pos + edge->pos = before->pos +
FT_MulDiv( edge->opos - before->opos, FT_MulDiv( edge->opos - before->opos,
after->pos - before->pos, after->pos - before->pos,
after->opos - before->opos ); after->opos - before->opos );
AF_LOG(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f) "
"from %d (opos=%.2f)\n",
edge-edges, edge->opos / 64.0,
edge->pos / 64.0, before - edges,
before->opos / 64.0 ));
}
else else
{
edge->pos = anchor->pos + edge->pos = anchor->pos +
FT_PIX_ROUND( edge->opos - anchor->opos ); ( ( edge->opos - anchor->opos + 16 ) & ~31 );
AF_LOG(( "SERIF_LINK2: edge %d (opos=%.2f) snapped to (%.2f)\n",
AF_LOG(( "SERIF_LINK: edge %d (opos=%.2f) snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
} }
}
edge->flags |= AF_EDGE_DONE; edge->flags |= AF_EDGE_DONE;
@@ -2131,7 +2048,7 @@
int dim; int dim;
error = af_glyph_hints_reload( hints, outline ); error = af_glyph_hints_reload( hints, outline, 1 );
if ( error ) if ( error )
goto Exit; goto Exit;
@@ -2200,11 +2117,32 @@
/*************************************************************************/ /*************************************************************************/
/* XXX: this should probably fine tuned to differentiate better between */
/* scripts... */
static const AF_Script_UniRangeRec af_latin_uniranges[] = static const AF_Script_UniRangeRec af_latin_uniranges[] =
{ {
{ 32, 127 }, /* XXX: TODO: Add new Unicode ranges here! */ { 0x0020, 0x007F }, /* Basic Latin (no control characters) */
{ 160, 255 }, { 0x00A0, 0x00FF }, /* Latin-1 Supplement (no control characters) */
{ 0, 0 } { 0x0100, 0x017F }, /* Latin Extended-A */
{ 0x0180, 0x024F }, /* Latin Extended-B */
{ 0x0250, 0x02AF }, /* IPA Extensions */
{ 0x02B0, 0x02FF }, /* Spacing Modifier Letters */
{ 0x0300, 0x036F }, /* Combining Diacritical Marks */
{ 0x0370, 0x03FF }, /* Greek and Coptic */
{ 0x0400, 0x04FF }, /* Cyrillic */
{ 0x0500, 0x052F }, /* Cyrillic Supplement */
{ 0x1D00, 0x1D7F }, /* Phonetic Extensions */
{ 0x1D80, 0x1DBF }, /* Phonetic Extensions Supplement */
{ 0x1DC0, 0x1DFF }, /* Combining Diacritical Marks Supplement */
{ 0x1E00, 0x1EFF }, /* Latin Extended Additional */
{ 0x1F00, 0x1FFF }, /* Greek Extended */
{ 0x2000, 0x206F }, /* General Punctuation */
{ 0x2070, 0x209F }, /* Superscripts and Subscripts */
{ 0x20A0, 0x20CF }, /* Currency Symbols */
{ 0x2150, 0x218F }, /* Number Forms */
{ 0x2460, 0x24FF }, /* Enclosed Alphanumerics */
{ 0 , 0 }
}; };
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
/***************************************************************************/
/* */
/* aflatin2.h */
/* */
/* Auto-fitter hinting routines for latin script (specification). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* 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 __AFLATIN2_H__
#define __AFLATIN2_H__
#include "afhints.h"
FT_BEGIN_HEADER
/* the latin-specific script class */
FT_CALLBACK_TABLE const AF_ScriptClassRec
af_latin2_script_class;
/* */
FT_END_HEADER
#endif /* __AFLATIN_H__ */
/* END */
+11 -5
View File
@@ -173,7 +173,7 @@
/* width/positioning that occurred during the hinting process */ /* width/positioning that occurred during the hinting process */
if ( scaler->render_mode != FT_RENDER_MODE_LIGHT ) if ( scaler->render_mode != FT_RENDER_MODE_LIGHT )
{ {
FT_Pos old_advance, old_rsb, old_lsb, new_lsb; FT_Pos old_rsb, old_lsb, new_lsb;
FT_Pos pp1x_uh, pp2x_uh; FT_Pos pp1x_uh, pp2x_uh;
AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ];
AF_Edge edge1 = axis->edges; /* leftmost edge */ AF_Edge edge1 = axis->edges; /* leftmost edge */
@@ -183,7 +183,6 @@
if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) )
{ {
old_advance = loader->pp2.x - loader->pp1.x;
old_rsb = loader->pp2.x - edge2->opos; old_rsb = loader->pp2.x - edge2->opos;
old_lsb = edge1->opos; old_lsb = edge1->opos;
new_lsb = edge1->pos; new_lsb = edge1->pos;
@@ -391,12 +390,12 @@
FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
FT_Vector_Transform( &vvector, &loader->trans_matrix ); FT_Vector_Transform( &vvector, &loader->trans_matrix );
} }
#if 1
/* we must translate our final outline by -pp1.x and compute */ /* we must translate our final outline by -pp1.x and compute */
/* the new metrics */ /* the new metrics */
if ( loader->pp1.x ) if ( loader->pp1.x )
FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );
#endif
FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
@@ -493,10 +492,17 @@
if ( !error ) if ( !error )
{ {
AF_ScriptMetrics metrics; AF_ScriptMetrics metrics;
FT_UInt options = 0;
#ifdef FT_OPTION_AUTOFIT2
/* XXX: undocumented hook to activate the latin2 hinter */
if ( load_flags & ( 1UL << 20 ) )
options = 2;
#endif
error = af_face_globals_get_metrics( loader->globals, gindex, error = af_face_globals_get_metrics( loader->globals, gindex,
&metrics ); options, &metrics );
if ( !error ) if ( !error )
{ {
loader->metrics = metrics; loader->metrics = metrics;
+5
View File
@@ -265,6 +265,11 @@ extern void* _af_debug_hints;
AF_SCRIPT_NONE = 0, AF_SCRIPT_NONE = 0,
AF_SCRIPT_LATIN = 1, AF_SCRIPT_LATIN = 1,
AF_SCRIPT_CJK = 2, AF_SCRIPT_CJK = 2,
AF_SCRIPT_INDIC = 3,
#ifdef FT_OPTION_AUTOFIT2
AF_SCRIPT_LATIN2,
#endif
/* add new scripts here. Don't forget to update the list in */ /* add new scripts here. Don't forget to update the list in */
/* `afglobal.c'. */ /* `afglobal.c'. */
+7 -1
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter module (body). */ /* Auto-fitter module (body). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006 by */ /* Copyright 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -21,9 +21,15 @@
#include "afangles.c" #include "afangles.c"
#include "afglobal.c" #include "afglobal.c"
#include "afhints.c" #include "afhints.c"
#include "afdummy.c" #include "afdummy.c"
#include "aflatin.c" #include "aflatin.c"
#ifdef FT_OPTION_AUTOFIT2
#include "aflatin2.c"
#endif
#include "afcjk.c" #include "afcjk.c"
#include "afindic.c"
#include "afloader.c" #include "afloader.c"
#include "afmodule.c" #include "afmodule.c"
+3 -2
View File
@@ -3,7 +3,7 @@
# #
# Copyright 2003, 2004, 2005, 2006 by # Copyright 2003, 2004, 2005, 2006, 2007 by
# David Turner, Robert Wilhelm, and Werner Lemberg. # David Turner, Robert Wilhelm, and Werner Lemberg.
# #
# This file is part of the FreeType project, and may only be used, modified, # This file is part of the FreeType project, and may only be used, modified,
@@ -26,11 +26,12 @@ AUTOF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(AUTOF_DIR))
# AUTOF driver sources (i.e., C files) # AUTOF driver sources (i.e., C files)
# #
AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \ AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \
$(AUTOF_DIR)/afcjk.c \
$(AUTOF_DIR)/afdummy.c \ $(AUTOF_DIR)/afdummy.c \
$(AUTOF_DIR)/afglobal.c \ $(AUTOF_DIR)/afglobal.c \
$(AUTOF_DIR)/afhints.c \ $(AUTOF_DIR)/afhints.c \
$(AUTOF_DIR)/afindic.c \
$(AUTOF_DIR)/aflatin.c \ $(AUTOF_DIR)/aflatin.c \
$(AUTOF_DIR)/afcjk.c \
$(AUTOF_DIR)/afloader.c \ $(AUTOF_DIR)/afloader.c \
$(AUTOF_DIR)/afmodule.c \ $(AUTOF_DIR)/afmodule.c \
$(AUTOF_DIR)/afwarp.c $(AUTOF_DIR)/afwarp.c
+1 -1
View File
@@ -38,7 +38,7 @@ UseFreeTypeHeaders ;
local _sources = system init glyph mm bdf local _sources = system init glyph mm bdf
bbox debug xf86 type1 pfr bbox debug xf86 type1 pfr
stroke winfnt otval bitmap synth stroke winfnt otval bitmap synth
gxval lcdfil gasp gxval lcdfil gasp patent
; ;
FT2_Library $(FT2_LIB) : ft$(_sources).c ; FT2_Library $(FT2_LIB) : ft$(_sources).c ;
-1
View File
@@ -743,7 +743,6 @@
} }
else /* general case */ else /* general case */
{ {
#ifdef FT_LONG64 #ifdef FT_LONG64
FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x; FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;
+3 -3
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* FreeType convenience functions to handle glyphs (body). */ /* FreeType convenience functions to handle glyphs (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -376,6 +376,8 @@
const FT_Glyph_Class* clazz; const FT_Glyph_Class* clazz;
*target = 0;
/* check arguments */ /* check arguments */
if ( !target || !source || !source->clazz ) if ( !target || !source || !source->clazz )
{ {
@@ -383,8 +385,6 @@
goto Exit; goto Exit;
} }
*target = 0;
clazz = source->clazz; clazz = source->clazz;
error = ft_new_glyph( source->library, clazz, &copy ); error = ft_new_glyph( source->library, clazz, &copy );
if ( error ) if ( error )
+26 -16
View File
@@ -105,6 +105,10 @@
FSSpec* pathSpec, FSSpec* pathSpec,
FT_Long* face_index ) FT_Long* face_index )
{ {
FT_UNUSED( fontName );
FT_UNUSED( pathSpec );
FT_UNUSED( face_index );
return FT_Err_Unimplemented_Feature; return FT_Err_Unimplemented_Feature;
} }
@@ -118,6 +122,12 @@
FT_ATSFontGetFileReference( ATSFontRef ats_font_id, FT_ATSFontGetFileReference( ATSFontRef ats_font_id,
FSRef* ats_font_ref ) FSRef* ats_font_ref )
{ {
#if __LP64__
FT_UNUSED( ats_font_id );
FT_UNUSED( ats_font_ref );
return fnfErr;
#else
OSStatus err; OSStatus err;
FSSpec spec; FSSpec spec;
@@ -127,6 +137,7 @@
err = FSpMakeFSRef( &spec, ats_font_ref ); err = FSpMakeFSRef( &spec, ats_font_ref );
return err; return err;
#endif
} }
@@ -204,11 +215,12 @@
FT_Long* face_index ) FT_Long* face_index )
{ {
#if __LP64__ #if __LP64__
FT_UNUSED( fontName );
FT_UNUSED( pathSpec );
FT_UNUSED( face_index );
return FT_Err_Unimplemented_Feature; return FT_Err_Unimplemented_Feature;
#else #else
FSRef ref; FSRef ref;
FT_Error err; FT_Error err;
@@ -222,7 +234,6 @@
return FT_Err_Unknown_File_Format; return FT_Err_Unknown_File_Format;
return FT_Err_Ok; return FT_Err_Ok;
#endif #endif
} }
@@ -448,9 +459,9 @@
static FT_Error static FT_Error
lookup_lwfn_by_fond( const UInt8* path_fond, lookup_lwfn_by_fond( const UInt8* path_fond,
const StringPtr base_lwfn, ConstStr255Param base_lwfn,
UInt8* path_lwfn, UInt8* path_lwfn,
int path_size ) size_t path_size )
{ {
FSRef ref, par_ref; FSRef ref, par_ref;
int dirname_len; int dirname_len;
@@ -472,12 +483,8 @@
if ( ft_strlen( (char *)path_lwfn ) + 1 + base_lwfn[0] > path_size ) if ( ft_strlen( (char *)path_lwfn ) + 1 + base_lwfn[0] > path_size )
return FT_Err_Invalid_Argument; return FT_Err_Invalid_Argument;
/* now we have absolute dirname in lookup_path */ /* now we have absolute dirname in path_lwfn */
if ( path_lwfn[0] == '/' )
ft_strcat( (char *)path_lwfn, "/" ); ft_strcat( (char *)path_lwfn, "/" );
else
ft_strcat( (char *)path_lwfn, ":" );
dirname_len = ft_strlen( (char *)path_lwfn ); dirname_len = ft_strlen( (char *)path_lwfn );
ft_strcat( (char *)path_lwfn, (char *)base_lwfn + 1 ); ft_strcat( (char *)path_lwfn, (char *)base_lwfn + 1 );
path_lwfn[dirname_len + base_lwfn[0]] = '\0'; path_lwfn[dirname_len + base_lwfn[0]] = '\0';
@@ -507,7 +514,6 @@
have_sfnt = have_lwfn = 0; have_sfnt = have_lwfn = 0;
HLock( fond );
parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 ); parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );
if ( lwfn_file_name[0] ) if ( lwfn_file_name[0] )
@@ -523,7 +529,6 @@
else else
num_faces = count_faces_scalable( *fond ); num_faces = count_faces_scalable( *fond );
HUnlock( fond );
return num_faces; return num_faces;
} }
@@ -810,9 +815,7 @@
return error; return error;
} }
HLock( sfnt );
ft_memcpy( sfnt_data, *sfnt, sfnt_size ); ft_memcpy( sfnt_data, *sfnt, sfnt_size );
HUnlock( sfnt );
ReleaseResource( sfnt ); ReleaseResource( sfnt );
is_cff = sfnt_size > 4 && sfnt_data[0] == 'O' && is_cff = sfnt_size > 4 && sfnt_data[0] == 'O' &&
@@ -894,9 +897,7 @@
if ( ResError() != noErr || fond_type != 'FOND' ) if ( ResError() != noErr || fond_type != 'FOND' )
return FT_Err_Invalid_File_Format; return FT_Err_Invalid_File_Format;
HLock( fond );
parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index ); parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );
HUnlock( fond );
if ( lwfn_file_name[0] ) if ( lwfn_file_name[0] )
{ {
@@ -1073,6 +1074,14 @@
FT_Long face_index, FT_Long face_index,
FT_Face* aface ) FT_Face* aface )
{ {
#if __LP64__
FT_UNUSED( library );
FT_UNUSED( spec );
FT_UNUSED( face_index );
FT_UNUSED( aface );
return FT_Err_Unimplemented_Feature;
#else
FSRef ref; FSRef ref;
@@ -1080,6 +1089,7 @@
return FT_Err_Invalid_Argument; return FT_Err_Invalid_Argument;
else else
return FT_New_Face_From_FSRef( library, &ref, face_index, aface ); return FT_New_Face_From_FSRef( library, &ref, face_index, aface );
#endif
} }
+43 -20
View File
@@ -92,14 +92,14 @@
/* since the cast below also disables the compiler's */ /* since the cast below also disables the compiler's */
/* type check, we introduce a dummy variable, which */ /* type check, we introduce a dummy variable, which */
/* will be optimized away */ /* will be optimized away */
volatile jmp_buf* jump_buffer = &valid->jump_buffer; volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer;
valid->error = error; valid->error = error;
/* throw away volatileness; use `jump_buffer' or the */ /* throw away volatileness; use `jump_buffer' or the */
/* compiler may warn about an unused local variable */ /* compiler may warn about an unused local variable */
ft_longjmp( *(jmp_buf*) jump_buffer, 1 ); ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 );
} }
@@ -787,6 +787,9 @@
FT_Int n; FT_Int n;
if ( !face )
return;
for ( n = 0; n < face->num_charmaps; n++ ) for ( n = 0; n < face->num_charmaps; n++ )
{ {
FT_CMap cmap = FT_CMAP( face->charmaps[n] ); FT_CMap cmap = FT_CMAP( face->charmaps[n] );
@@ -1198,7 +1201,7 @@
{ {
FT_Open_Args args; FT_Open_Args args;
FT_Error error; FT_Error error;
FT_Stream stream; FT_Stream stream = NULL;
FT_Memory memory = library->memory; FT_Memory memory = library->memory;
@@ -2223,16 +2226,14 @@
FT_Request_Metrics( FT_Face face, FT_Request_Metrics( FT_Face face,
FT_Size_Request req ) FT_Size_Request req )
{ {
FT_Driver_Class clazz;
FT_Size_Metrics* metrics; FT_Size_Metrics* metrics;
clazz = face->driver->clazz;
metrics = &face->size->metrics; metrics = &face->size->metrics;
if ( FT_IS_SCALABLE( face ) ) if ( FT_IS_SCALABLE( face ) )
{ {
FT_Long w, h, scaled_w = 0, scaled_h = 0; FT_Long w = 0, h = 0, scaled_w = 0, scaled_h = 0;
switch ( req->type ) switch ( req->type )
@@ -2245,16 +2246,16 @@
w = h = face->ascender - face->descender; w = h = face->ascender - face->descender;
break; break;
case FT_SIZE_REQUEST_TYPE_CELL:
w = face->max_advance_width;
h = face->ascender - face->descender;
break;
case FT_SIZE_REQUEST_TYPE_BBOX: case FT_SIZE_REQUEST_TYPE_BBOX:
w = face->bbox.xMax - face->bbox.xMin; w = face->bbox.xMax - face->bbox.xMin;
h = face->bbox.yMax - face->bbox.yMin; h = face->bbox.yMax - face->bbox.yMin;
break; break;
case FT_SIZE_REQUEST_TYPE_CELL:
w = face->max_advance_width;
h = face->ascender - face->descender;
break;
case FT_SIZE_REQUEST_TYPE_SCALES: case FT_SIZE_REQUEST_TYPE_SCALES:
metrics->x_scale = (FT_Fixed)req->width; metrics->x_scale = (FT_Fixed)req->width;
metrics->y_scale = (FT_Fixed)req->height; metrics->y_scale = (FT_Fixed)req->height;
@@ -2263,11 +2264,8 @@
else if ( !metrics->y_scale ) else if ( !metrics->y_scale )
metrics->y_scale = metrics->x_scale; metrics->y_scale = metrics->x_scale;
goto Calculate_Ppem; goto Calculate_Ppem;
break;
default: case FT_SIZE_REQUEST_TYPE_MAX:
/* this never happens */
return;
break; break;
} }
@@ -2435,11 +2433,14 @@
if ( char_height < 1 * 64 ) if ( char_height < 1 * 64 )
char_height = 1 * 64; char_height = 1 * 64;
if ( !horz_resolution )
horz_resolution = vert_resolution = 72;
req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
req.width = char_width; req.width = char_width;
req.height = char_height; req.height = char_height;
req.horiResolution = ( horz_resolution ) ? horz_resolution : 72; req.horiResolution = horz_resolution;
req.vertResolution = ( vert_resolution ) ? vert_resolution : 72; req.vertResolution = vert_resolution;
return FT_Request_Size( face, &req ); return FT_Request_Size( face, &req );
} }
@@ -2551,7 +2552,6 @@
{ {
FT_Service_Kerning service; FT_Service_Kerning service;
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FT_Driver driver;
if ( !face ) if ( !face )
@@ -2560,8 +2560,6 @@
if ( !akerning ) if ( !akerning )
return FT_Err_Invalid_Argument; return FT_Err_Invalid_Argument;
driver = face->driver;
FT_FACE_FIND_SERVICE( face, service, KERNING ); FT_FACE_FIND_SERVICE( face, service, KERNING );
if ( !service ) if ( !service )
return FT_Err_Unimplemented_Feature; return FT_Err_Unimplemented_Feature;
@@ -3030,6 +3028,30 @@
} }
/* documentation is in tttables.h */
FT_EXPORT_DEF( FT_Long )
FT_Get_CMap_Format( FT_CharMap charmap )
{
FT_Service_TTCMaps service;
FT_Face face;
TT_CMapInfo cmap_info;
if ( !charmap || !charmap->face )
return -1;
face = charmap->face;
FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
if ( service == NULL )
return -1;
if ( service->get_cmap_info( charmap, &cmap_info ))
return -1;
return cmap_info.format;
}
/* documentation is in ftsizes.h */ /* documentation is in ftsizes.h */
FT_EXPORT_DEF( FT_Error ) FT_EXPORT_DEF( FT_Error )
@@ -3703,6 +3725,7 @@
/* allocate the render pool */ /* allocate the render pool */
library->raster_pool_size = FT_RENDER_POOL_SIZE; library->raster_pool_size = FT_RENDER_POOL_SIZE;
if ( FT_RENDER_POOL_SIZE > 0 )
if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
goto Fail; goto Fail;
+2
View File
@@ -84,6 +84,8 @@
last = outline->contours[n]; last = outline->contours[n];
if ( last < 0 )
goto Invalid_Outline;
limit = outline->points + last; limit = outline->points + last;
v_start = outline->points[first]; v_start = outline->points[first];
+281
View File
@@ -0,0 +1,281 @@
/***************************************************************************/
/* */
/* ftpatent.c */
/* */
/* FreeType API for checking patented TrueType bytecode instructions */
/* (body). */
/* */
/* Copyright 2007 by David Turner. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* 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_FREETYPE_H
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_STREAM_H
#include FT_SERVICE_SFNT_H
#include FT_SERVICE_TRUETYPE_GLYF_H
static FT_Bool
_tt_check_patents_in_range( FT_Stream stream,
FT_ULong size )
{
FT_Bool result = FALSE;
FT_Error error;
FT_Bytes p, end;
if ( FT_FRAME_ENTER( size ) )
return 0;
p = stream->cursor;
end = p + size;
while ( p < end )
{
switch (p[0])
{
case 0x06: /* SPvTL // */
case 0x07: /* SPvTL + */
case 0x08: /* SFvTL // */
case 0x09: /* SFvTL + */
case 0x0A: /* SPvFS */
case 0x0B: /* SFvFS */
result = TRUE;
goto Exit;
case 0x40:
if ( p + 1 >= end )
goto Exit;
p += p[1] + 2;
break;
case 0x41:
if ( p + 1 >= end )
goto Exit;
p += p[1] * 2 + 2;
break;
case 0x71: /* DELTAP2 */
case 0x72: /* DELTAP3 */
case 0x73: /* DELTAC0 */
case 0x74: /* DELTAC1 */
case 0x75: /* DELTAC2 */
result = TRUE;
goto Exit;
case 0xB0:
case 0xB1:
case 0xB2:
case 0xB3:
case 0xB4:
case 0xB5:
case 0xB6:
case 0xB7:
p += ( p[0] - 0xB0 ) + 2;
break;
case 0xB8:
case 0xB9:
case 0xBA:
case 0xBB:
case 0xBC:
case 0xBD:
case 0xBE:
case 0xBF:
p += ( p[0] - 0xB8 ) * 2 + 3;
break;
default:
p += 1;
break;
}
}
Exit:
FT_FRAME_EXIT();
return result;
}
static FT_Bool
_tt_check_patents_in_table( FT_Face face,
FT_ULong tag )
{
FT_Stream stream = face->stream;
FT_Error error;
FT_Service_SFNT_Table service;
FT_Bool result = FALSE;
FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
if ( service )
{
FT_ULong offset, size;
error = service->table_info( face, tag, &offset, &size );
if ( error ||
FT_STREAM_SEEK( offset ) )
goto Exit;
result = _tt_check_patents_in_range( stream, size );
}
Exit:
return result;
}
static FT_Bool
_tt_face_check_patents( FT_Face face )
{
FT_Stream stream = face->stream;
FT_UInt gindex;
FT_Error error;
FT_Bool result;
FT_Service_TTGlyf service;
result = _tt_check_patents_in_table( face, TTAG_fpgm );
if ( result )
goto Exit;
result = _tt_check_patents_in_table( face, TTAG_prep );
if ( result )
goto Exit;
FT_FACE_FIND_SERVICE( face, service, TT_GLYF );
if ( service == NULL )
goto Exit;
for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ )
{
FT_ULong offset, num_ins, size;
FT_Int num_contours;
offset = service->get_location( face, gindex, &size );
if ( size == 0 )
continue;
if ( FT_STREAM_SEEK( offset ) ||
FT_READ_SHORT( num_contours ) )
continue;
if ( num_contours >= 0 ) /* simple glyph */
{
if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) )
continue;
}
else /* compound glyph */
{
FT_Bool has_instr = 0;
if ( FT_STREAM_SKIP( 8 ) )
continue;
/* now read each component */
for (;;)
{
FT_UInt flags, toskip;
if( FT_READ_USHORT( flags ) )
break;
toskip = 2 + 1 + 1;
if ( ( flags & ( 1 << 0 ) ) != 0 ) /* ARGS_ARE_WORDS */
toskip += 2;
if ( ( flags & ( 1 << 3 ) ) != 0 ) /* WE_HAVE_A_SCALE */
toskip += 2;
else if ( ( flags & ( 1 << 6 ) ) != 0 ) /* WE_HAVE_X_Y_SCALE */
toskip += 4;
else if ( ( flags & ( 1 << 7 ) ) != 0 ) /* WE_HAVE_A_2x2 */
toskip += 8;
if ( ( flags & ( 1 << 8 ) ) != 0 ) /* WE_HAVE_INSTRUCTIONS */
has_instr = 1;
if ( FT_STREAM_SKIP( toskip ) )
goto NextGlyph;
if ( ( flags & ( 1 << 5 ) ) == 0 ) /* MORE_COMPONENTS */
break;
}
if ( !has_instr )
goto NextGlyph;
}
if ( FT_READ_USHORT( num_ins ) )
continue;
result = _tt_check_patents_in_range( stream, num_ins );
if ( result )
goto Exit;
NextGlyph:
;
}
Exit:
return result;
}
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Bool )
FT_Face_CheckTrueTypePatents( FT_Face face )
{
FT_Bool result = FALSE;
if ( face && FT_IS_SFNT( face ) )
result = _tt_face_check_patents( face );
return result;
}
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Bool )
FT_Face_SetUnpatentedHinting( FT_Face face,
FT_Bool value )
{
FT_Bool result = 0;
#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
!defined( TT_CONFIG_OPTION_BYTECODE_INTEPRETER )
if ( face && FT_IS_SFNT( face ) )
{
result = !face->internal->ignore_unpatented_hinter;
face->internal->ignore_unpatented_hinter = !value;
}
#else
FT_UNUSED( face );
FT_UNUSED( value );
#endif
return result;
}
/* END */
+21
View File
@@ -1537,6 +1537,12 @@
s = _bdf_list_join( &p->list, ' ', &slen ); s = _bdf_list_join( &p->list, ' ', &slen );
if ( !s )
{
error = BDF_Err_Invalid_File_Format;
goto Exit;
}
if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) ) if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) )
goto Exit; goto Exit;
@@ -2117,6 +2123,13 @@
_bdf_list_shift( &p->list, 1 ); _bdf_list_shift( &p->list, 1 );
s = _bdf_list_join( &p->list, ' ', &slen ); s = _bdf_list_join( &p->list, ' ', &slen );
if ( !s )
{
error = BDF_Err_Invalid_File_Format;
goto Exit;
}
if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) ) if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) )
goto Exit; goto Exit;
FT_MEM_COPY( p->font->name, s, slen + 1 ); FT_MEM_COPY( p->font->name, s, slen + 1 );
@@ -2301,11 +2314,19 @@
{ {
/* The ENDFONT field was never reached or did not exist. */ /* The ENDFONT field was never reached or did not exist. */
if ( !( p->flags & _BDF_GLYPHS ) ) if ( !( p->flags & _BDF_GLYPHS ) )
{
/* Error happened while parsing header. */ /* Error happened while parsing header. */
FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno )); FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno ));
error = BDF_Err_Corrupted_Font_Header;
goto Exit;
}
else else
{
/* Error happened when parsing glyphs. */ /* Error happened when parsing glyphs. */
FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno )); FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno ));
error = BDF_Err_Corrupted_Font_Glyphs;
goto Exit;
}
} }
} }
+112 -1
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* The FreeType basic cache interface (body). */ /* The FreeType basic cache interface (body). */
/* */ /* */
/* Copyright 2003, 2004, 2005, 2006 by */ /* Copyright 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -383,6 +383,62 @@
} }
/* documentation is in ftcache.h */
FT_EXPORT_DEF( FT_Error )
FTC_ImageCache_LookupScaler( FTC_ImageCache cache,
FTC_Scaler scaler,
FT_ULong load_flags,
FT_UInt gindex,
FT_Glyph *aglyph,
FTC_Node *anode )
{
FTC_BasicQueryRec query;
FTC_INode node = 0; /* make compiler happy */
FT_Error error;
FT_UInt32 hash;
/* some argument checks are delayed to FTC_Cache_Lookup */
if ( !aglyph || !scaler )
{
error = FTC_Err_Invalid_Argument;
goto Exit;
}
*aglyph = NULL;
if ( anode )
*anode = NULL;
query.attrs.scaler = scaler[0];
query.attrs.load_flags = load_flags;
hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
FTC_GCACHE_LOOKUP_CMP( cache,
ftc_basic_family_compare,
FTC_GNode_Compare,
hash, gindex,
&query,
node,
error );
if ( !error )
{
*aglyph = FTC_INODE( node )->glyph;
if ( anode )
{
*anode = FTC_NODE( node );
FTC_NODE( node )->ref_count++;
}
}
Exit:
return error;
}
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
/* yet another backwards-legacy structure */ /* yet another backwards-legacy structure */
@@ -652,6 +708,61 @@
} }
/* documentation is in ftcache.h */
FT_EXPORT_DEF( FT_Error )
FTC_SBitCache_LookupScaler( FTC_SBitCache cache,
FTC_Scaler scaler,
FT_ULong load_flags,
FT_UInt gindex,
FTC_SBit *ansbit,
FTC_Node *anode )
{
FT_Error error;
FTC_BasicQueryRec query;
FTC_SNode node = 0; /* make compiler happy */
FT_UInt32 hash;
if ( anode )
*anode = NULL;
/* other argument checks delayed to FTC_Cache_Lookup */
if ( !ansbit || !scaler )
return FTC_Err_Invalid_Argument;
*ansbit = NULL;
query.attrs.scaler = scaler[0];
query.attrs.load_flags = load_flags;
/* beware, the hash must be the same for all glyph ranges! */
hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
gindex / FTC_SBIT_ITEMS_PER_NODE;
FTC_GCACHE_LOOKUP_CMP( cache,
ftc_basic_family_compare,
FTC_SNode_Compare,
hash, gindex,
&query,
node,
error );
if ( error )
goto Exit;
*ansbit = node->sbits + ( gindex - FTC_GNODE( node )->gindex );
if ( anode )
{
*anode = FTC_NODE( node );
FTC_NODE( node )->ref_count++;
}
Exit:
return error;
}
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
FT_EXPORT( FT_Error ) FT_EXPORT( FT_Error )
+9 -3
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* The FreeType internal cache interface (body). */ /* The FreeType internal cache interface (body). */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -46,7 +46,10 @@
ftc_node_mru_link( FTC_Node node, ftc_node_mru_link( FTC_Node node,
FTC_Manager manager ) FTC_Manager manager )
{ {
FTC_MruNode_Prepend( (FTC_MruNode*)&manager->nodes_list, void *nl = &manager->nodes_list;
FTC_MruNode_Prepend( (FTC_MruNode*)nl,
(FTC_MruNode)node ); (FTC_MruNode)node );
manager->num_nodes++; manager->num_nodes++;
} }
@@ -57,7 +60,10 @@
ftc_node_mru_unlink( FTC_Node node, ftc_node_mru_unlink( FTC_Node node,
FTC_Manager manager ) FTC_Manager manager )
{ {
FTC_MruNode_Remove( (FTC_MruNode*)&manager->nodes_list, void *nl = &manager->nodes_list;
FTC_MruNode_Remove( (FTC_MruNode*)nl,
(FTC_MruNode)node ); (FTC_MruNode)node );
manager->num_nodes--; manager->num_nodes--;
} }
+3 -2
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* FreeType internal cache interface (specification). */ /* FreeType internal cache interface (specification). */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -233,10 +233,11 @@ FT_BEGIN_HEADER
\ \
{ \ { \
FTC_Manager _manager = _cache->manager; \ FTC_Manager _manager = _cache->manager; \
void* _nl = &_manager->nodes_list; \
\ \
\ \
if ( _node != _manager->nodes_list ) \ if ( _node != _manager->nodes_list ) \
FTC_MruNode_Up( (FTC_MruNode*)&_manager->nodes_list, \ FTC_MruNode_Up( (FTC_MruNode*)_nl, \
(FTC_MruNode)_node ); \ (FTC_MruNode)_node ); \
} \ } \
goto _Ok; \ goto _Ok; \
+1 -2
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* FreeType CharMap cache (body) */ /* FreeType CharMap cache (body) */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -341,7 +341,6 @@
return FT_Get_Char_Index( face, char_code ); return FT_Get_Char_Index( face, char_code );
} }
break;
default: default:
return 0; return 0;
+5 -2
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* FreeType abstract glyph cache (specification). */ /* FreeType abstract glyph cache (specification). */
/* */ /* */
/* Copyright 2000-2001, 2003, 2004, 2006 by */ /* Copyright 2000-2001, 2003, 2004, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -303,8 +303,11 @@ FT_BEGIN_HEADER
#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \
gindex, query, node, error ) \ gindex, query, node, error ) \
FT_BEGIN_STMNT \ FT_BEGIN_STMNT \
void* _n = &(node); \
\
\
error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \ error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \
FTC_GQUERY( query ), (FTC_Node*)&(node) ); \ FTC_GQUERY( query ), (FTC_Node*)_n ); \
FT_END_STMNT FT_END_STMNT
#endif /* !FTC_INLINE */ #endif /* !FTC_INLINE */
+34 -10
View File
@@ -372,12 +372,13 @@
/* this function is used to select the locals subrs array */ /* this function is used to select the locals subrs array */
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( FT_Error )
cff_decoder_prepare( CFF_Decoder* decoder, cff_decoder_prepare( CFF_Decoder* decoder,
FT_UInt glyph_index ) FT_UInt glyph_index )
{ {
CFF_Font cff = (CFF_Font)decoder->builder.face->extra.data; CFF_Font cff = (CFF_Font)decoder->builder.face->extra.data;
CFF_SubFont sub = &cff->top_font; CFF_SubFont sub = &cff->top_font;
FT_Error error = CFF_Err_Ok;
/* manage CID fonts */ /* manage CID fonts */
@@ -386,6 +387,13 @@
FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index ); FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index );
if ( fd_index >= cff->num_subfonts )
{
FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
sub = cff->subfonts[fd_index]; sub = cff->subfonts[fd_index];
} }
@@ -395,6 +403,9 @@
decoder->glyph_width = sub->private_dict.default_width; decoder->glyph_width = sub->private_dict.default_width;
decoder->nominal_width = sub->private_dict.nominal_width; decoder->nominal_width = sub->private_dict.nominal_width;
Exit:
return error;
} }
@@ -2249,9 +2260,11 @@
&charstring, &charstring_len ); &charstring, &charstring_len );
if ( !error ) if ( !error )
{ {
cff_decoder_prepare( &decoder, glyph_index ); error = cff_decoder_prepare( &decoder, glyph_index );
if ( !error )
error = cff_decoder_parse_charstrings( &decoder, error = cff_decoder_parse_charstrings( &decoder,
charstring, charstring_len ); charstring,
charstring_len );
cff_free_glyph_data( face, &charstring, &charstring_len ); cff_free_glyph_data( face, &charstring, &charstring_len );
} }
@@ -2400,9 +2413,12 @@
&charstring, &charstring_len ); &charstring, &charstring_len );
if ( !error ) if ( !error )
{ {
cff_decoder_prepare( &decoder, glyph_index ); error = cff_decoder_prepare( &decoder, glyph_index );
if ( !error )
{
error = cff_decoder_parse_charstrings( &decoder, error = cff_decoder_parse_charstrings( &decoder,
charstring, charstring_len ); charstring,
charstring_len );
cff_free_glyph_data( face, &charstring, charstring_len ); cff_free_glyph_data( face, &charstring, charstring_len );
@@ -2433,6 +2449,7 @@
} }
} }
} }
}
/* save new glyph tables */ /* save new glyph tables */
cff_builder_done( &decoder.builder ); cff_builder_done( &decoder.builder );
@@ -2462,9 +2479,12 @@
#endif /* FT_CONFIG_OPTION_INCREMENTAL */ #endif /* FT_CONFIG_OPTION_INCREMENTAL */
if ( !error )
{
if ( cff->num_subfonts >= 1 ) if ( cff->num_subfonts >= 1 )
{ {
FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index ); FT_Byte fd_index = cff_fd_select_get( &cff->fd_select,
glyph_index );
font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
@@ -2479,8 +2499,7 @@
/* Now, set the metrics -- this is rather simple, as */ /* Now, set the metrics -- this is rather simple, as */
/* the left side bearing is the xMin, and the top side */ /* the left side bearing is the xMin, and the top side */
/* bearing the yMax. */ /* bearing the yMax. */
if ( !error )
{
/* For composite glyphs, return only left side bearing and */ /* For composite glyphs, return only left side bearing and */
/* advance width. */ /* advance width. */
if ( load_flags & FT_LOAD_NO_RECURSE ) if ( load_flags & FT_LOAD_NO_RECURSE )
@@ -2547,11 +2566,16 @@
glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
/* apply the font matrix */ /* apply the font matrix */
if ( !( font_matrix.xx == 0x10000L &&
font_matrix.yy == 0x10000L &&
font_matrix.xy == 0 &&
font_matrix.yx == 0 ) )
FT_Outline_Transform( &glyph->root.outline, &font_matrix ); FT_Outline_Transform( &glyph->root.outline, &font_matrix );
if ( !( font_offset.x == 0 &&
font_offset.y == 0 ) )
FT_Outline_Translate( &glyph->root.outline, FT_Outline_Translate( &glyph->root.outline,
font_offset.x, font_offset.x, font_offset.y );
font_offset.y );
advance.x = metrics->horiAdvance; advance.x = metrics->horiAdvance;
advance.y = 0; advance.y = 0;
+2 -2
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* OpenType Glyph Loader (specification). */ /* OpenType Glyph Loader (specification). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -175,7 +175,7 @@ FT_BEGIN_HEADER
FT_Bool hinting, FT_Bool hinting,
FT_Render_Mode hint_mode ); FT_Render_Mode hint_mode );
FT_LOCAL( void ) FT_LOCAL( FT_Error )
cff_decoder_prepare( CFF_Decoder* decoder, cff_decoder_prepare( CFF_Decoder* decoder,
FT_UInt glyph_index ); FT_UInt glyph_index );
+7 -2
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* CID-keyed Type1 Glyph Loader (body). */ /* CID-keyed Type1 Glyph Loader (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -45,7 +45,7 @@
FT_Byte* p; FT_Byte* p;
FT_UInt fd_select; FT_UInt fd_select;
FT_Stream stream = face->cid_stream; FT_Stream stream = face->cid_stream;
FT_Error error = 0; FT_Error error = CID_Err_Ok;
FT_Byte* charstring = 0; FT_Byte* charstring = 0;
FT_Memory memory = face->root.memory; FT_Memory memory = face->root.memory;
FT_ULong glyph_length = 0; FT_ULong glyph_length = 0;
@@ -111,6 +111,11 @@
glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
FT_FRAME_EXIT(); FT_FRAME_EXIT();
if ( fd_select >= (FT_UInt)cid->num_dicts )
{
error = CID_Err_Invalid_Offset;
goto Exit;
}
if ( glyph_length == 0 ) if ( glyph_length == 0 )
goto Exit; goto Exit;
if ( FT_ALLOC( charstring, glyph_length ) ) if ( FT_ALLOC( charstring, glyph_length ) )
+8 -1
View File
@@ -98,7 +98,11 @@
stream_len = stream->size - FT_STREAM_POS(); stream_len = stream->size - FT_STREAM_POS();
if ( stream_len == 0 ) if ( stream_len == 0 )
{
FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
error = CID_Err_Unknown_File_Format;
goto Exit; goto Exit;
}
read_len = FT_MIN( read_len, stream_len ); read_len = FT_MIN( read_len, stream_len );
if ( FT_STREAM_READ( p, read_len ) ) if ( FT_STREAM_READ( p, read_len ) )
@@ -165,7 +169,10 @@
while ( cur < limit ) while ( cur < limit )
{ {
if ( parser->root.error ) if ( parser->root.error )
break; {
error = parser->root.error;
goto Exit;
}
if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
{ {
+84 -70
View File
@@ -8,7 +8,7 @@
/* be used to parse compressed PCF fonts, as found with many X11 server */ /* be used to parse compressed PCF fonts, as found with many X11 server */
/* distributions. */ /* distributions. */
/* */ /* */
/* Copyright 2005, 2006 by David Turner. */ /* Copyright 2005, 2006, 2007 by David Turner. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */ /* modified, and distributed under the terms of the FreeType project */
@@ -23,55 +23,84 @@
#include FT_INTERNAL_STREAM_H #include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_DEBUG_H
/* refill input buffer, return 0 on success, or -1 if eof */
static int static int
ft_lzwstate_refill( FT_LzwState state ) ft_lzwstate_refill( FT_LzwState state )
{ {
int result = -1; FT_ULong count;
if ( !state->in_eof ) if ( state->in_eof )
{ return -1;
FT_ULong count = FT_Stream_TryRead( state->source,
state->in_buff,
sizeof ( state->in_buff ) );
state->in_cursor = state->in_buff; count = FT_Stream_TryRead( state->source,
state->in_limit = state->in_buff + count; state->buf_tab,
state->in_eof = FT_BOOL( count < sizeof ( state->in_buff ) ); state->num_bits ); /* WHY? */
if ( count > 0 ) state->buf_size = (FT_UInt)count;
result = 0; state->buf_total += count;
} state->in_eof = FT_BOOL( count < state->num_bits );
return result; state->buf_offset = 0;
state->buf_size = ( state->buf_size << 3 ) - ( state->num_bits - 1 );
if ( count == 0 ) /* end of file */
return -1;
return 0;
} }
/* return new code of 'num_bits', or -1 if eof */
static FT_Int32 static FT_Int32
ft_lzwstate_get_code( FT_LzwState state, ft_lzwstate_get_code( FT_LzwState state )
FT_UInt num_bits )
{ {
FT_Int32 result = -1; FT_UInt num_bits = state->num_bits;
FT_UInt32 pad = state->pad; FT_Int offset = state->buf_offset;
FT_UInt pad_bits = state->pad_bits; FT_Byte* p;
FT_Int result;
while ( num_bits > pad_bits ) if ( state->buf_clear ||
offset >= state->buf_size ||
state->free_ent >= state->free_bits )
{ {
if ( state->in_cursor >= state->in_limit && if ( state->free_ent >= state->free_bits )
ft_lzwstate_refill( state ) < 0 ) {
goto Exit; state->num_bits = ++num_bits;
state->free_bits = state->num_bits < state->max_bits
pad |= (FT_UInt32)(*state->in_cursor++) << pad_bits; ? (FT_UInt)( ( 1UL << num_bits ) - 256 )
pad_bits += 8; : state->max_free + 1;
} }
result = (FT_Int32)( pad & LZW_MASK( num_bits ) ); if ( state->buf_clear )
state->pad_bits = pad_bits - num_bits; {
state->pad = pad >> num_bits; state->num_bits = num_bits = LZW_INIT_BITS;
state->free_bits = (FT_UInt)( ( 1UL << num_bits ) - 256 );
state->buf_clear = 0;
}
if ( ft_lzwstate_refill( state ) < 0 )
return -1;
offset = 0;
}
state->buf_offset = offset + num_bits;
p = &state->buf_tab[offset >> 3];
offset &= 7;
result = *p++ >> offset;
offset = 8 - offset;
num_bits -= offset;
if ( num_bits >= 8 )
{
result |= *p++ << offset;
offset += 8;
num_bits -= 8;
}
if ( num_bits > 0 )
result |= ( *p & LZW_MASK( num_bits ) ) << offset;
Exit:
return result; return result;
} }
@@ -146,12 +175,11 @@
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
ft_lzwstate_reset( FT_LzwState state ) ft_lzwstate_reset( FT_LzwState state )
{ {
state->in_cursor = state->in_buff;
state->in_limit = state->in_buff;
state->in_eof = 0; state->in_eof = 0;
state->pad_bits = 0; state->buf_offset = 0;
state->pad = 0; state->buf_size = 0;
state->buf_clear = 0;
state->buf_total = 0;
state->stack_top = 0; state->stack_top = 0;
state->num_bits = LZW_INIT_BITS; state->num_bits = LZW_INIT_BITS;
state->phase = FT_LZW_PHASE_START; state->phase = FT_LZW_PHASE_START;
@@ -202,7 +230,7 @@
ft_lzwstate_stack_grow( state ) < 0 ) \ ft_lzwstate_stack_grow( state ) < 0 ) \
goto Eof; \ goto Eof; \
\ \
state->stack[ state->stack_top++ ] = (FT_Byte)(c); \ state->stack[state->stack_top++] = (FT_Byte)(c); \
FT_END_STMNT FT_END_STMNT
@@ -213,8 +241,6 @@
{ {
FT_ULong result = 0; FT_ULong result = 0;
FT_UInt num_bits = state->num_bits;
FT_UInt free_ent = state->free_ent;
FT_UInt old_char = state->old_char; FT_UInt old_char = state->old_char;
FT_UInt old_code = state->old_code; FT_UInt old_code = state->old_code;
FT_UInt in_code = state->in_code; FT_UInt in_code = state->in_code;
@@ -243,15 +269,16 @@
if ( state->max_bits > LZW_MAX_BITS ) if ( state->max_bits > LZW_MAX_BITS )
goto Eof; goto Eof;
num_bits = LZW_INIT_BITS; state->num_bits = LZW_INIT_BITS;
free_ent = ( state->block_mode ? LZW_FIRST : LZW_CLEAR ) - 256; state->free_ent = ( state->block_mode ? LZW_FIRST
: LZW_CLEAR ) - 256;
in_code = 0; in_code = 0;
state->free_bits = num_bits < state->max_bits state->free_bits = state->num_bits < state->max_bits
? (FT_UInt)( ( 1UL << num_bits ) - 256 ) ? (FT_UInt)( ( 1UL << state->num_bits ) - 256 )
: state->max_free + 1; : state->max_free + 1;
c = ft_lzwstate_get_code( state, num_bits ); c = ft_lzwstate_get_code( state );
if ( c < 0 ) if ( c < 0 )
goto Eof; goto Eof;
@@ -274,7 +301,7 @@
NextCode: NextCode:
c = ft_lzwstate_get_code( state, num_bits ); c = ft_lzwstate_get_code( state );
if ( c < 0 ) if ( c < 0 )
goto Eof; goto Eof;
@@ -282,14 +309,10 @@
if ( code == LZW_CLEAR && state->block_mode ) if ( code == LZW_CLEAR && state->block_mode )
{ {
free_ent = ( LZW_FIRST - 1 ) - 256; /* why not LZW_FIRST-256 ? */ /* why not LZW_FIRST-256 ? */
num_bits = LZW_INIT_BITS; state->free_ent = ( LZW_FIRST - 1 ) - 256;
state->buf_clear = 1;
state->free_bits = num_bits < state->max_bits c = ft_lzwstate_get_code( state );
? (FT_UInt)( ( 1UL << num_bits ) - 256 )
: state->max_free + 1;
c = ft_lzwstate_get_code( state, num_bits );
if ( c < 0 ) if ( c < 0 )
goto Eof; goto Eof;
@@ -301,7 +324,7 @@
if ( code >= 256U ) if ( code >= 256U )
{ {
/* special case for KwKwKwK */ /* special case for KwKwKwK */
if ( code - 256U >= free_ent ) if ( code - 256U >= state->free_ent )
{ {
FTLZW_STACK_PUSH( old_char ); FTLZW_STACK_PUSH( old_char );
code = old_code; code = old_code;
@@ -335,25 +358,18 @@
} }
/* now create new entry */ /* now create new entry */
if ( free_ent < state->max_free ) if ( state->free_ent < state->max_free )
{ {
if ( free_ent >= state->prefix_size && if ( state->free_ent >= state->prefix_size &&
ft_lzwstate_prefix_grow( state ) < 0 ) ft_lzwstate_prefix_grow( state ) < 0 )
goto Eof; goto Eof;
FT_ASSERT( free_ent < state->prefix_size ); FT_ASSERT( state->free_ent < state->prefix_size );
state->prefix[free_ent] = (FT_UShort)old_code; state->prefix[state->free_ent] = (FT_UShort)old_code;
state->suffix[free_ent] = (FT_Byte) old_char; state->suffix[state->free_ent] = (FT_Byte) old_char;
if ( ++free_ent == state->free_bits ) state->free_ent += 1;
{
num_bits++;
state->free_bits = num_bits < state->max_bits
? (FT_UInt)( ( 1UL << num_bits ) - 256 )
: state->max_free + 1;
}
} }
old_code = in_code; old_code = in_code;
@@ -367,8 +383,6 @@
} }
Exit: Exit:
state->num_bits = num_bits;
state->free_ent = free_ent;
state->old_code = old_code; state->old_code = old_code;
state->old_char = old_char; state->old_char = old_char;
state->in_code = in_code; state->in_code = in_code;
+6 -8
View File
@@ -8,7 +8,7 @@
/* be used to parse compressed PCF fonts, as found with many X11 server */ /* be used to parse compressed PCF fonts, as found with many X11 server */
/* distributions. */ /* distributions. */
/* */ /* */
/* Copyright 2005, 2006 by David Turner. */ /* Copyright 2005, 2006, 2007 by David Turner. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */ /* modified, and distributed under the terms of the FreeType project */
@@ -112,13 +112,13 @@
typedef struct _FT_LzwStateRec typedef struct _FT_LzwStateRec
{ {
FT_LzwPhase phase; FT_LzwPhase phase;
FT_Int in_eof; FT_Int in_eof;
FT_Byte* in_cursor; /* current buffer pos */
FT_Byte* in_limit; /* current buffer limit */
FT_UInt32 pad; /* a pad value where incoming bits were read */ FT_Byte buf_tab[16];
FT_Int pad_bits; /* number of meaningful bits in pad value */ FT_Int buf_offset;
FT_Int buf_size;
FT_Bool buf_clear;
FT_Int buf_total;
FT_UInt max_bits; /* max code bits, from file header */ FT_UInt max_bits; /* max code bits, from file header */
FT_Int block_mode; /* block mode flag, from file header */ FT_Int block_mode; /* block mode flag, from file header */
@@ -138,8 +138,6 @@
FT_Byte* stack; /* character stack */ FT_Byte* stack; /* character stack */
FT_UInt stack_top; FT_UInt stack_top;
FT_UInt stack_size; FT_UInt stack_size;
FT_Byte in_buff[FT_LZW_IN_BUFF_SIZE]; /* small read-buffer */
FT_Byte stack_0[FT_LZW_DEFAULT_STACK_SIZE]; /* minimize heap alloc */ FT_Byte stack_0[FT_LZW_DEFAULT_STACK_SIZE]; /* minimize heap alloc */
FT_Stream source; /* source stream */ FT_Stream source; /* source stream */
+8 -3
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* FreeType PFR cmap handling (body). */ /* FreeType PFR cmap handling (body). */
/* */ /* */
/* Copyright 2002 by */ /* Copyright 2002, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -24,6 +24,7 @@
FT_CALLBACK_DEF( FT_Error ) FT_CALLBACK_DEF( FT_Error )
pfr_cmap_init( PFR_CMap cmap ) pfr_cmap_init( PFR_CMap cmap )
{ {
FT_Error error = PFR_Err_Ok;
PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap ); PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap );
@@ -39,11 +40,15 @@
for ( n = 1; n < cmap->num_chars; n++ ) for ( n = 1; n < cmap->num_chars; n++ )
{ {
if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code ) if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code )
FT_ASSERT( 0 ); {
error = PFR_Err_Invalid_Table;
goto Exit;
}
} }
} }
return 0; Exit:
return error;
} }
+41 -16
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* FreeType PFR glyph loader (body). */ /* FreeType PFR glyph loader (body). */
/* */ /* */
/* Copyright 2002, 2003, 2005 by */ /* Copyright 2002, 2003, 2005, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -59,8 +59,10 @@
glyph->y_control = NULL; glyph->y_control = NULL;
glyph->max_xy_control = 0; glyph->max_xy_control = 0;
#if 0
glyph->num_x_control = 0; glyph->num_x_control = 0;
glyph->num_y_control = 0; glyph->num_y_control = 0;
#endif
FT_FREE( glyph->subs ); FT_FREE( glyph->subs );
@@ -131,7 +133,12 @@
/* check that we have begun a new path */ /* check that we have begun a new path */
FT_ASSERT( glyph->path_begun != 0 ); if ( !glyph->path_begun )
{
error = PFR_Err_Invalid_Table;
FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" ));
goto Exit;
}
error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 ); error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 );
if ( !error ) if ( !error )
@@ -145,6 +152,7 @@
outline->n_points++; outline->n_points++;
} }
Exit:
return error; return error;
} }
@@ -161,7 +169,12 @@
/* check that we have begun a new path */ /* check that we have begun a new path */
FT_ASSERT( glyph->path_begun != 0 ); if ( !glyph->path_begun )
{
error = PFR_Err_Invalid_Table;
FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" ));
goto Exit;
}
error = FT_GLYPHLOADER_CHECK_POINTS( loader, 3, 0 ); error = FT_GLYPHLOADER_CHECK_POINTS( loader, 3, 0 );
if ( !error ) if ( !error )
@@ -180,6 +193,7 @@
outline->n_points = (FT_Short)( outline->n_points + 3 ); outline->n_points = (FT_Short)( outline->n_points + 3 );
} }
Exit:
return error; return error;
} }
@@ -244,7 +258,8 @@
flags = PFR_NEXT_BYTE( p ); flags = PFR_NEXT_BYTE( p );
/* test for composite glyphs */ /* test for composite glyphs */
FT_ASSERT( ( flags & PFR_GLYPH_IS_COMPOUND ) == 0 ); if ( flags & PFR_GLYPH_IS_COMPOUND )
goto Failure;
x_count = 0; x_count = 0;
y_count = 0; y_count = 0;
@@ -339,7 +354,7 @@
for (;;) for (;;)
{ {
FT_Int format, args_format = 0, args_count, n; FT_UInt format, format_low, args_format = 0, args_count, n;
/***************************************************************/ /***************************************************************/
@@ -347,6 +362,7 @@
/* */ /* */
PFR_CHECK( 1 ); PFR_CHECK( 1 );
format = PFR_NEXT_BYTE( p ); format = PFR_NEXT_BYTE( p );
format_low = format & 15;
switch ( format >> 4 ) switch ( format >> 4 )
{ {
@@ -366,22 +382,26 @@
case 5: /* move to outside contour */ case 5: /* move to outside contour */
FT_TRACE6(( "- move to outside" )); FT_TRACE6(( "- move to outside" ));
Line1: Line1:
args_format = format & 15; args_format = format_low;
args_count = 1; args_count = 1;
break; break;
case 2: /* horizontal line to */ case 2: /* horizontal line to */
FT_TRACE6(( "- horizontal line to cx.%d", format & 15 )); FT_TRACE6(( "- horizontal line to cx.%d", format_low ));
if ( format_low > x_count )
goto Failure;
pos[0].x = glyph->x_control[format_low];
pos[0].y = pos[3].y; pos[0].y = pos[3].y;
pos[0].x = glyph->x_control[format & 15];
pos[3] = pos[0]; pos[3] = pos[0];
args_count = 0; args_count = 0;
break; break;
case 3: /* vertical line to */ case 3: /* vertical line to */
FT_TRACE6(( "- vertical line to cy.%d", format & 15 )); FT_TRACE6(( "- vertical line to cy.%d", format_low ));
if ( format_low > y_count )
goto Failure;
pos[0].x = pos[3].x; pos[0].x = pos[3].x;
pos[0].y = glyph->y_control[format & 15]; pos[0].y = glyph->y_control[format_low];
pos[3] = pos[0]; pos[3] = pos[0];
args_count = 0; args_count = 0;
break; break;
@@ -401,7 +421,7 @@
default: /* general curve to */ default: /* general curve to */
FT_TRACE6(( "- general curve" )); FT_TRACE6(( "- general curve" ));
args_count = 4; args_count = 4;
args_format = format & 15; args_format = format_low;
} }
/***********************************************************/ /***********************************************************/
@@ -410,7 +430,8 @@
cur = pos; cur = pos;
for ( n = 0; n < args_count; n++ ) for ( n = 0; n < args_count; n++ )
{ {
FT_Int idx, delta; FT_UInt idx;
FT_Int delta;
/* read the X argument */ /* read the X argument */
@@ -419,6 +440,8 @@
case 0: /* 8-bit index */ case 0: /* 8-bit index */
PFR_CHECK( 1 ); PFR_CHECK( 1 );
idx = PFR_NEXT_BYTE( p ); idx = PFR_NEXT_BYTE( p );
if ( idx > x_count )
goto Failure;
cur->x = glyph->x_control[idx]; cur->x = glyph->x_control[idx];
FT_TRACE7(( " cx#%d", idx )); FT_TRACE7(( " cx#%d", idx ));
break; break;
@@ -447,6 +470,8 @@
case 0: /* 8-bit index */ case 0: /* 8-bit index */
PFR_CHECK( 1 ); PFR_CHECK( 1 );
idx = PFR_NEXT_BYTE( p ); idx = PFR_NEXT_BYTE( p );
if ( idx > y_count )
goto Failure;
cur->y = glyph->y_control[idx]; cur->y = glyph->y_control[idx];
FT_TRACE7(( " cy#%d", idx )); FT_TRACE7(( " cy#%d", idx ));
break; break;
@@ -519,6 +544,7 @@
Exit: Exit:
return error; return error;
Failure:
Too_Short: Too_Short:
error = PFR_Err_Invalid_Table; error = PFR_Err_Invalid_Table;
FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" )); FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" ));
@@ -544,7 +570,8 @@
flags = PFR_NEXT_BYTE( p ); flags = PFR_NEXT_BYTE( p );
/* test for composite glyphs */ /* test for composite glyphs */
FT_ASSERT( ( flags & PFR_GLYPH_IS_COMPOUND ) != 0 ); if ( !( flags & PFR_GLYPH_IS_COMPOUND ) )
goto Failure;
count = flags & 0x3F; count = flags & 0x3F;
@@ -670,6 +697,7 @@
Exit: Exit:
return error; return error;
Failure:
Too_Short: Too_Short:
error = PFR_Err_Invalid_Table; error = PFR_Err_Invalid_Table;
FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" )); FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" ));
@@ -677,9 +705,6 @@
} }
static FT_Error static FT_Error
pfr_glyph_load_rec( PFR_Glyph glyph, pfr_glyph_load_rec( PFR_Glyph glyph,
FT_Stream stream, FT_Stream stream,
+3 -1
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* FreeType PFR data structures (specification only). */ /* FreeType PFR data structures (specification only). */
/* */ /* */
/* Copyright 2002, 2003, 2005 by */ /* Copyright 2002, 2003, 2005, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -335,8 +335,10 @@ FT_BEGIN_HEADER
{ {
FT_Byte format; FT_Byte format;
#if 0
FT_UInt num_x_control; FT_UInt num_x_control;
FT_UInt num_y_control; FT_UInt num_y_control;
#endif
FT_UInt max_xy_control; FT_UInt max_xy_control;
FT_Pos* x_control; FT_Pos* x_control;
FT_Pos* y_control; FT_Pos* y_control;
+2 -7
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* AFM parser (body). */ /* AFM parser (body). */
/* */ /* */
/* Copyright 2006 by */ /* Copyright 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -642,14 +642,12 @@
case AFM_TOKEN_ENDFONTMETRICS: case AFM_TOKEN_ENDFONTMETRICS:
fi->NumTrackKern = n + 1; fi->NumTrackKern = n + 1;
return PSaux_Err_Ok; return PSaux_Err_Ok;
break;
case AFM_TOKEN_UNKNOWN: case AFM_TOKEN_UNKNOWN:
break; break;
default: default:
goto Fail; goto Fail;
break;
} }
} }
@@ -761,7 +759,6 @@
default: default:
goto Fail; goto Fail;
break;
} }
} }
@@ -804,7 +801,6 @@
default: default:
goto Fail; goto Fail;
break;
} }
} }
@@ -921,7 +917,7 @@
case AFM_TOKEN_STARTCHARMETRICS: case AFM_TOKEN_STARTCHARMETRICS:
{ {
FT_Int n; FT_Int n = 0;
if ( afm_parser_read_int( parser, &n ) ) if ( afm_parser_read_int( parser, &n ) )
@@ -942,7 +938,6 @@
case AFM_TOKEN_ENDFONTMETRICS: case AFM_TOKEN_ENDFONTMETRICS:
return PSaux_Err_Ok; return PSaux_Err_Ok;
break;
default: default:
break; break;
+42 -16
View File
@@ -592,7 +592,6 @@
error = PSaux_Err_Invalid_File_Format; error = PSaux_Err_Invalid_File_Format;
} }
FT_ASSERT( parser->error == PSaux_Err_Ok );
parser->error = error; parser->error = error;
parser->cursor = cur; parser->cursor = cur;
} }
@@ -785,8 +784,7 @@
if ( c == '[' ) if ( c == '[' )
ender = ']'; ender = ']';
else if ( c == '{' )
if ( c == '{' )
ender = '}'; ender = '}';
if ( ender ) if ( ender )
@@ -796,6 +794,7 @@
while ( cur < limit ) while ( cur < limit )
{ {
FT_Short dummy; FT_Short dummy;
FT_Byte* old_cur;
/* skip whitespace in front of data */ /* skip whitespace in front of data */
@@ -803,19 +802,28 @@
if ( cur >= limit ) if ( cur >= limit )
goto Exit; goto Exit;
if ( coords != NULL && count >= max_coords )
break;
if ( *cur == ender ) if ( *cur == ender )
{ {
cur++; cur++;
break; break;
} }
old_cur = cur;
if ( coords != NULL && count >= max_coords )
break;
/* call PS_Conv_ToFixed() even if coords == NULL */ /* call PS_Conv_ToFixed() even if coords == NULL */
/* to properly parse number at `cur' */ /* to properly parse number at `cur' */
*( coords != NULL ? &coords[count] : &dummy ) = *( coords != NULL ? &coords[count] : &dummy ) =
(FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 ); (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );
if ( old_cur == cur )
{
count = -1;
goto Exit;
}
else
count++; count++;
if ( !ender ) if ( !ender )
@@ -830,7 +838,7 @@
/* first character must be a delimiter or a part of a number */ /* first character must be a delimiter or a part of a number */
/* NB: `values' can be NULL if we just want to skip the */ /* NB: `values' can be NULL if we just want to skip the */
/* array in this case we ignore `max_values' */ /* array; in this case we ignore `max_values' */
static FT_Int static FT_Int
ps_tofixedarray( FT_Byte* *acur, ps_tofixedarray( FT_Byte* *acur,
@@ -854,8 +862,7 @@
if ( c == '[' ) if ( c == '[' )
ender = ']'; ender = ']';
else if ( c == '{' )
if ( c == '{' )
ender = '}'; ender = '}';
if ( ender ) if ( ender )
@@ -865,6 +872,7 @@
while ( cur < limit ) while ( cur < limit )
{ {
FT_Fixed dummy; FT_Fixed dummy;
FT_Byte* old_cur;
/* skip whitespace in front of data */ /* skip whitespace in front of data */
@@ -872,19 +880,28 @@
if ( cur >= limit ) if ( cur >= limit )
goto Exit; goto Exit;
if ( values != NULL && count >= max_values )
break;
if ( *cur == ender ) if ( *cur == ender )
{ {
cur++; cur++;
break; break;
} }
old_cur = cur;
if ( values != NULL && count >= max_values )
break;
/* call PS_Conv_ToFixed() even if coords == NULL */ /* call PS_Conv_ToFixed() even if coords == NULL */
/* to properly parse number at `cur' */ /* to properly parse number at `cur' */
*( values != NULL ? &values[count] : &dummy ) = *( values != NULL ? &values[count] : &dummy ) =
PS_Conv_ToFixed( &cur, limit, power_ten ); PS_Conv_ToFixed( &cur, limit, power_ten );
if ( old_cur == cur )
{
count = -1;
goto Exit;
}
else
count++; count++;
if ( !ender ) if ( !ender )
@@ -1161,9 +1178,18 @@
{ {
FT_Fixed temp[4]; FT_Fixed temp[4];
FT_BBox* bbox = (FT_BBox*)q; FT_BBox* bbox = (FT_BBox*)q;
FT_Int result;
(void)ps_tofixedarray( &token.start, token.limit, 4, temp, 0 ); result = ps_tofixedarray( &cur, limit, 4, temp, 0 );
if ( result < 0 )
{
FT_ERROR(( "ps_parser_load_field: "
"expected four integers in bounding box\n" ));
error = PSaux_Err_Invalid_File_Format;
goto Exit;
}
bbox->xMin = FT_RoundFix( temp[0] ); bbox->xMin = FT_RoundFix( temp[0] );
bbox->yMin = FT_RoundFix( temp[1] ); bbox->yMin = FT_RoundFix( temp[1] );
@@ -1227,8 +1253,8 @@
error = PSaux_Err_Ignore; error = PSaux_Err_Ignore;
goto Exit; goto Exit;
} }
if ( num_elements > T1_MAX_TABLE_ELEMENTS ) if ( (FT_UInt)num_elements > field->array_max )
num_elements = T1_MAX_TABLE_ELEMENTS; num_elements = field->array_max;
old_cursor = parser->cursor; old_cursor = parser->cursor;
old_limit = parser->limit; old_limit = parser->limit;
@@ -1311,7 +1337,7 @@
{ {
if ( cur < parser->limit && *cur != '>' ) if ( cur < parser->limit && *cur != '>' )
{ {
FT_ERROR(( "ps_tobytes: Missing closing delimiter `>'\n" )); FT_ERROR(( "ps_parser_to_bytes: Missing closing delimiter `>'\n" ));
error = PSaux_Err_Invalid_File_Format; error = PSaux_Err_Invalid_File_Format;
goto Exit; goto Exit;
} }
+4 -3
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* PostScript Type 1 decoding routines (body). */ /* PostScript Type 1 decoding routines (body). */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -951,8 +951,9 @@
default: default:
if ( top - decoder->stack != num_args ) if ( top - decoder->stack != num_args )
FT_TRACE0(( "\nMore operands on the stack than expected " FT_TRACE0(( "t1_decoder_parse_charstrings: "
"(have %d, expected %d)\n", "too much operands on the stack "
"(seen %d, expected %d)\n",
top - decoder->stack, num_args )); top - decoder->stack, num_args ));
break; break;
} }
+4 -3
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* FreeType PostScript hinter module implementation (body). */ /* FreeType PostScript hinter module implementation (body). */
/* */ /* */
/* Copyright 2001, 2002 by */ /* Copyright 2001, 2002, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -51,6 +51,7 @@
ps_hinter_init( PS_Hinter_Module module ) ps_hinter_init( PS_Hinter_Module module )
{ {
FT_Memory memory = module->root.memory; FT_Memory memory = module->root.memory;
void* ph = &module->ps_hints;
ps_hints_init( &module->ps_hints, memory ); ps_hints_init( &module->ps_hints, memory );
@@ -58,10 +59,10 @@
psh_globals_funcs_init( &module->globals_funcs ); psh_globals_funcs_init( &module->globals_funcs );
t1_hints_funcs_init( &module->t1_funcs ); t1_hints_funcs_init( &module->t1_funcs );
module->t1_funcs.hints = (T1_Hints)&module->ps_hints; module->t1_funcs.hints = (T1_Hints)ph;
t2_hints_funcs_init( &module->t2_funcs ); t2_hints_funcs_init( &module->t2_funcs );
module->t2_funcs.hints = (T2_Hints)&module->ps_hints; module->t2_funcs.hints = (T2_Hints)ph;
return 0; return 0;
} }
+3 -3
View File
@@ -309,7 +309,7 @@
/* set a new mask to a given bit range */ /* set a new mask to a given bit range */
static FT_Error static FT_Error
ps_mask_table_set_bits( PS_Mask_Table table, ps_mask_table_set_bits( PS_Mask_Table table,
FT_Byte* source, const FT_Byte* source,
FT_UInt bit_pos, FT_UInt bit_pos,
FT_UInt bit_count, FT_UInt bit_count,
FT_Memory memory ) FT_Memory memory )
@@ -330,7 +330,7 @@
/* now, copy bits */ /* now, copy bits */
{ {
FT_Byte* read = source + ( bit_pos >> 3 ); FT_Byte* read = (FT_Byte*)source + ( bit_pos >> 3 );
FT_Int rmask = 0x80 >> ( bit_pos & 7 ); FT_Int rmask = 0x80 >> ( bit_pos & 7 );
FT_Byte* write = mask->bytes; FT_Byte* write = mask->bytes;
FT_Int wmask = 0x80; FT_Int wmask = 0x80;
@@ -628,7 +628,7 @@
goto Exit; goto Exit;
/* set bits in new mask */ /* set bits in new mask */
error = ps_mask_table_set_bits( &dim->masks, (FT_Byte*)source, error = ps_mask_table_set_bits( &dim->masks, source,
source_pos, source_bits, memory ); source_pos, source_bits, memory );
Exit: Exit:
+4 -4
View File
@@ -32,7 +32,7 @@
#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
#define VARIANT_BIT ( 1L << 31 ) #define VARIANT_BIT 0x80000000UL
#define BASE_GLYPH( code ) ( (code) & ~VARIANT_BIT ) #define BASE_GLYPH( code ) ( (code) & ~VARIANT_BIT )
@@ -92,7 +92,7 @@
if ( *p == '\0' ) if ( *p == '\0' )
return value; return value;
if ( *p == '.' ) if ( *p == '.' )
return value ^ VARIANT_BIT; return value | VARIANT_BIT;
} }
} }
@@ -132,7 +132,7 @@
if ( *p == '\0' ) if ( *p == '\0' )
return value; return value;
if ( *p == '.' ) if ( *p == '.' )
return value ^ VARIANT_BIT; return value | VARIANT_BIT;
} }
} }
@@ -156,7 +156,7 @@
if ( !dot ) if ( !dot )
return ft_get_adobe_glyph_index( glyph_name, p ); return ft_get_adobe_glyph_index( glyph_name, p );
else else
return ft_get_adobe_glyph_index( glyph_name, dot ) ^ VARIANT_BIT; return ft_get_adobe_glyph_index( glyph_name, dot ) | VARIANT_BIT;
} }
} }
+15
View File
@@ -619,7 +619,22 @@
error = SFNT_Err_Ok; error = SFNT_Err_Ok;
} }
else else
{
error = SFNT_Err_Horiz_Header_Missing; error = SFNT_Err_Horiz_Header_Missing;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font and there are */
/* overriding metrics, tolerate a missing `hhea' table. */
if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->
get_glyph_metrics )
{
face->horizontal.number_Of_HMetrics = 0;
error = SFNT_Err_Ok;
}
#endif
}
} }
if ( error ) if ( error )
+9 -1
View File
@@ -155,6 +155,7 @@
FT_Byte* p = cmap->data + 4; FT_Byte* p = cmap->data + 4;
cmap_info->format = 0;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
return SFNT_Err_Ok; return SFNT_Err_Ok;
@@ -527,6 +528,7 @@
FT_Byte* p = cmap->data + 4; FT_Byte* p = cmap->data + 4;
cmap_info->format = 2;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
return SFNT_Err_Ok; return SFNT_Err_Ok;
@@ -1303,6 +1305,7 @@
FT_Byte* p = cmap->data + 4; FT_Byte* p = cmap->data + 4;
cmap_info->format = 4;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
return SFNT_Err_Ok; return SFNT_Err_Ok;
@@ -1462,6 +1465,7 @@
FT_Byte* p = cmap->data + 4; FT_Byte* p = cmap->data + 4;
cmap_info->format = 6;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
return SFNT_Err_Ok; return SFNT_Err_Ok;
@@ -1715,6 +1719,7 @@
FT_Byte* p = cmap->data + 8; FT_Byte* p = cmap->data + 8;
cmap_info->format = 8;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
return SFNT_Err_Ok; return SFNT_Err_Ok;
@@ -1863,6 +1868,7 @@
FT_Byte* p = cmap->data + 8; FT_Byte* p = cmap->data + 8;
cmap_info->format = 10;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
return SFNT_Err_Ok; return SFNT_Err_Ok;
@@ -2179,6 +2185,7 @@
FT_Byte* p = cmap->data + 8; FT_Byte* p = cmap->data + 8;
cmap_info->format = 12;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
return SFNT_Err_Ok; return SFNT_Err_Ok;
@@ -2299,7 +2306,8 @@
valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs; valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs;
if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer ) == 0 ) if ( ft_setjmp(
*((ft_jmp_buf*)&FT_VALIDATOR( &valid )->jump_buffer) ) == 0 )
{ {
/* validate this cmap sub-table */ /* validate this cmap sub-table */
error = clazz->validate( cmap, FT_VALIDATOR( &valid ) ); error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
+2 -2
View File
@@ -84,7 +84,7 @@
for ( nn = 0; nn < num_tables; nn++ ) for ( nn = 0; nn < num_tables; nn++ )
{ {
FT_UInt num_pairs, version, length, coverage; FT_UInt num_pairs, length, coverage;
FT_Byte* p_next; FT_Byte* p_next;
FT_UInt32 mask = 1UL << nn; FT_UInt32 mask = 1UL << nn;
@@ -94,7 +94,7 @@
p_next = p; p_next = p;
version = FT_NEXT_USHORT( p ); p += 2; /* skip version */
length = FT_NEXT_USHORT( p ); length = FT_NEXT_USHORT( p );
coverage = FT_NEXT_USHORT( p ); coverage = FT_NEXT_USHORT( p );
+26 -11
View File
@@ -110,40 +110,48 @@
FT_ULong table_len; FT_ULong table_len;
FT_Long num_shorts, num_longs, num_shorts_checked; FT_Long num_shorts, num_longs, num_shorts_checked;
TT_LongMetrics * longs; TT_LongMetrics* longs;
TT_ShortMetrics** shorts; TT_ShortMetrics** shorts;
FT_Byte* p; FT_Byte* p;
if ( vertical ) if ( vertical )
{ {
void* lm = &face->vertical.long_metrics;
void** sm = &face->vertical.short_metrics;
error = face->goto_table( face, TTAG_vmtx, stream, &table_len ); error = face->goto_table( face, TTAG_vmtx, stream, &table_len );
if ( error ) if ( error )
goto Fail; goto Fail;
num_longs = face->vertical.number_Of_VMetrics; num_longs = face->vertical.number_Of_VMetrics;
if ( (FT_ULong)num_longs > table_len / 4 ) if ( (FT_ULong)num_longs > table_len / 4 )
num_longs = (FT_Long)(table_len / 4); num_longs = (FT_Long)( table_len / 4 );
face->vertical.number_Of_VMetrics = 0; face->vertical.number_Of_VMetrics = 0;
longs = (TT_LongMetrics *)&face->vertical.long_metrics; longs = (TT_LongMetrics*)lm;
shorts = (TT_ShortMetrics**)&face->vertical.short_metrics; shorts = (TT_ShortMetrics**)sm;
} }
else else
{ {
void* lm = &face->horizontal.long_metrics;
void** sm = &face->horizontal.short_metrics;
error = face->goto_table( face, TTAG_hmtx, stream, &table_len ); error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
if ( error ) if ( error )
goto Fail; goto Fail;
num_longs = face->horizontal.number_Of_HMetrics; num_longs = face->horizontal.number_Of_HMetrics;
if ( (FT_ULong)num_longs > table_len / 4 ) if ( (FT_ULong)num_longs > table_len / 4 )
num_longs = (FT_Long)(table_len / 4); num_longs = (FT_Long)( table_len / 4 );
face->horizontal.number_Of_HMetrics = 0; face->horizontal.number_Of_HMetrics = 0;
longs = (TT_LongMetrics *)&face->horizontal.long_metrics; longs = (TT_LongMetrics*)lm;
shorts = (TT_ShortMetrics**)&face->horizontal.short_metrics; shorts = (TT_ShortMetrics**)sm;
} }
/* never trust derived values */ /* never trust derived values */
@@ -279,11 +287,14 @@
if ( vertical ) if ( vertical )
{ {
void *v = &face->vertical;
error = face->goto_table( face, TTAG_vhea, stream, 0 ); error = face->goto_table( face, TTAG_vhea, stream, 0 );
if ( error ) if ( error )
goto Fail; goto Fail;
header = (TT_HoriHeader*)&face->vertical; header = (TT_HoriHeader*)v;
} }
else else
{ {
@@ -348,7 +359,10 @@
if ( vertical ) if ( vertical )
{ {
header = (TT_HoriHeader*)&face->vertical; void* v = &face->vertical;
header = (TT_HoriHeader*)v;
table_pos = face->vert_metrics_offset; table_pos = face->vert_metrics_offset;
table_size = face->vert_metrics_size; table_size = face->vert_metrics_size;
} }
@@ -415,8 +429,9 @@
FT_Short* abearing, FT_Short* abearing,
FT_UShort* aadvance ) FT_UShort* aadvance )
{ {
TT_HoriHeader* header = vertical ? (TT_HoriHeader*)&face->vertical void* v = &face->vertical;
: &face->horizontal; void* h = &face->horizontal;
TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v : h;
TT_LongMetrics longs_m; TT_LongMetrics longs_m;
FT_UShort k = header->number_Of_HMetrics; FT_UShort k = header->number_Of_HMetrics;
+34 -5
View File
@@ -261,14 +261,27 @@
/* now find the strike corresponding to the index */ /* now find the strike corresponding to the index */
{ {
FT_Byte* p = decoder->eblc_base + 8 + 48 * strike_index; FT_Byte* p;
if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
{
error = SFNT_Err_Invalid_File_Format;
goto Exit;
}
p = decoder->eblc_base + 8 + 48 * strike_index;
decoder->strike_index_array = FT_NEXT_ULONG( p ); decoder->strike_index_array = FT_NEXT_ULONG( p );
p += 4; p += 4;
decoder->strike_index_count = FT_NEXT_ULONG( p ); decoder->strike_index_count = FT_NEXT_ULONG( p );
p += 34; p += 34;
decoder->bit_depth = *p; decoder->bit_depth = *p;
if ( decoder->strike_index_array > face->sbit_table_size ||
decoder->strike_index_array + 8 * decoder->strike_index_count >
face->sbit_table_size )
error = SFNT_Err_Invalid_File_Format;
} }
Exit: Exit:
@@ -775,9 +788,6 @@
FT_ULong image_start = 0, image_end = 0, image_offset; FT_ULong image_start = 0, image_end = 0, image_offset;
if ( p + 8 * num_ranges > p_limit )
goto NoBitmap;
for ( ; num_ranges > 0; num_ranges-- ) for ( ; num_ranges > 0; num_ranges-- )
{ {
start = FT_NEXT_USHORT( p ); start = FT_NEXT_USHORT( p );
@@ -792,6 +802,12 @@
FoundRange: FoundRange:
image_offset = FT_NEXT_ULONG( p ); image_offset = FT_NEXT_ULONG( p );
/* overflow check */
if ( decoder->eblc_base + decoder->strike_index_array + image_offset <
decoder->eblc_base )
goto Failure;
p = decoder->eblc_base + decoder->strike_index_array + image_offset; p = decoder->eblc_base + decoder->strike_index_array + image_offset;
if ( p + 8 > p_limit ) if ( p + 8 > p_limit )
goto NoBitmap; goto NoBitmap;
@@ -858,6 +874,11 @@
goto NoBitmap; goto NoBitmap;
num_glyphs = FT_NEXT_ULONG( p ); num_glyphs = FT_NEXT_ULONG( p );
/* overflow check */
if ( p + ( num_glyphs + 1 ) * 4 < p )
goto Failure;
if ( p + ( num_glyphs + 1 ) * 4 > p_limit ) if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
goto NoBitmap; goto NoBitmap;
@@ -895,6 +916,11 @@
goto NoBitmap; goto NoBitmap;
num_glyphs = FT_NEXT_ULONG( p ); num_glyphs = FT_NEXT_ULONG( p );
/* overflow check */
if ( p + 2 * num_glyphs < p )
goto Failure;
if ( p + 2 * num_glyphs > p_limit ) if ( p + 2 * num_glyphs > p_limit )
goto NoBitmap; goto NoBitmap;
@@ -910,7 +936,7 @@
if ( mm >= num_glyphs ) if ( mm >= num_glyphs )
goto NoBitmap; goto NoBitmap;
image_start = image_size*mm; image_start = image_size * mm;
image_end = image_start + image_size; image_end = image_start + image_size;
} }
break; break;
@@ -932,6 +958,9 @@
x_pos, x_pos,
y_pos ); y_pos );
Failure:
return SFNT_Err_Invalid_Table;
NoBitmap: NoBitmap:
return SFNT_Err_Invalid_Argument; return SFNT_Err_Invalid_Argument;
} }
+15 -1
View File
@@ -197,7 +197,7 @@
#define ONE_PIXEL ( 1L << PIXEL_BITS ) #define ONE_PIXEL ( 1L << PIXEL_BITS )
#define PIXEL_MASK ( -1L << PIXEL_BITS ) #define PIXEL_MASK ( -1L << PIXEL_BITS )
#define TRUNC( x ) ( (TCoord)((x) >> PIXEL_BITS) ) #define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) )
#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) #define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS )
#define FLOOR( x ) ( (x) & -ONE_PIXEL ) #define FLOOR( x ) ( (x) & -ONE_PIXEL )
#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) #define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
@@ -398,6 +398,9 @@
int x = ras.ex; int x = ras.ex;
if ( x > ras.max_ex )
x = ras.max_ex;
pcell = &ras.ycells[ras.ey]; pcell = &ras.ycells[ras.ey];
for (;;) for (;;)
{ {
@@ -462,6 +465,10 @@
/* All cells that are on the left of the clipping region go to the */ /* All cells that are on the left of the clipping region go to the */
/* min_ex - 1 horizontal position. */ /* min_ex - 1 horizontal position. */
ey -= ras.min_ey; ey -= ras.min_ey;
if ( ex > ras.max_ex )
ex = ras.max_ex;
ex -= ras.min_ex; ex -= ras.min_ex;
if ( ex < 0 ) if ( ex < 0 )
ex = -1; ex = -1;
@@ -492,6 +499,9 @@
gray_start_cell( RAS_ARG_ TCoord ex, gray_start_cell( RAS_ARG_ TCoord ex,
TCoord ey ) TCoord ey )
{ {
if ( ex > ras.max_ex )
ex = (TCoord)( ras.max_ex );
if ( ex < ras.min_ex ) if ( ex < ras.min_ex )
ex = (TCoord)( ras.min_ex - 1 ); ex = (TCoord)( ras.min_ex - 1 );
@@ -1196,6 +1206,10 @@
y += (TCoord)ras.min_ey; y += (TCoord)ras.min_ey;
x += (TCoord)ras.min_ex; x += (TCoord)ras.min_ex;
/* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */
if ( x >= 32768 )
x = 32767;
if ( coverage ) if ( coverage )
{ {
/* see whether we can add this span to the current list */ /* see whether we can add this span to the current list */
+8
View File
@@ -29,9 +29,11 @@
#endif #endif
#include FT_SERVICE_TRUETYPE_ENGINE_H #include FT_SERVICE_TRUETYPE_ENGINE_H
#include FT_SERVICE_TRUETYPE_GLYF_H
#include "ttdriver.h" #include "ttdriver.h"
#include "ttgload.h" #include "ttgload.h"
#include "ttpload.h"
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include "ttgxvar.h" #include "ttgxvar.h"
@@ -313,6 +315,11 @@
#endif /* TT_USE_BYTECODE_INTERPRETER */ #endif /* TT_USE_BYTECODE_INTERPRETER */
}; };
static const FT_Service_TTGlyfRec tt_service_truetype_glyf =
{
(TT_Glyf_GetLocationFunc)tt_face_get_location
};
static const FT_ServiceDescRec tt_services[] = static const FT_ServiceDescRec tt_services[] =
{ {
{ FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE }, { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE },
@@ -320,6 +327,7 @@
{ FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters }, { FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters },
#endif #endif
{ FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine }, { FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine },
{ FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf },
{ NULL, NULL } { NULL, NULL }
}; };
+57 -30
View File
@@ -244,13 +244,14 @@
FT_Outline* outline; FT_Outline* outline;
TT_Face face = (TT_Face)load->face; TT_Face face = (TT_Face)load->face;
FT_UShort n_ins; FT_UShort n_ins;
FT_Int n, n_points; FT_Int n_points;
FT_Byte *flag, *flag_limit; FT_Byte *flag, *flag_limit;
FT_Byte c, count; FT_Byte c, count;
FT_Vector *vec, *vec_limit; FT_Vector *vec, *vec_limit;
FT_Pos x; FT_Pos x;
FT_Short *cont, *cont_limit; FT_Short *cont, *cont_limit, prev_cont;
FT_Int xy_size = 0;
/* check that we can add the contours to the glyph */ /* check that we can add the contours to the glyph */
@@ -263,15 +264,29 @@
cont_limit = cont + n_contours; cont_limit = cont + n_contours;
/* check space for contours array + instructions count */ /* check space for contours array + instructions count */
if ( n_contours >= 0xFFF || p + (n_contours + 1) * 2 > limit ) if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit )
goto Invalid_Outline; goto Invalid_Outline;
for ( ; cont < cont_limit; cont++ ) cont[0] = prev_cont = FT_NEXT_USHORT( p );
for ( cont++; cont < cont_limit; cont++ )
{
cont[0] = FT_NEXT_USHORT( p ); cont[0] = FT_NEXT_USHORT( p );
if ( cont[0] <= prev_cont )
{
/* unordered contours: this is invalid */
error = FT_Err_Invalid_Table;
goto Fail;
}
prev_cont = cont[0];
}
n_points = 0; n_points = 0;
if ( n_contours > 0 ) if ( n_contours > 0 )
{
n_points = cont[-1] + 1; n_points = cont[-1] + 1;
if ( n_points < 0 )
goto Invalid_Outline;
}
/* note that we will add four phantom points later */ /* note that we will add four phantom points later */
error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 ); error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 );
@@ -298,7 +313,8 @@
if ( n_ins > face->max_profile.maxSizeOfInstructions ) if ( n_ins > face->max_profile.maxSizeOfInstructions )
{ {
FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions!\n" )); FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions (%d)\n",
n_ins ));
error = TT_Err_Too_Many_Hints; error = TT_Err_Too_Many_Hints;
goto Fail; goto Fail;
} }
@@ -357,21 +373,25 @@
flag = (FT_Byte*)outline->tags; flag = (FT_Byte*)outline->tags;
x = 0; x = 0;
if ( p + xy_size > limit )
goto Invalid_Outline;
for ( ; vec < vec_limit; vec++, flag++ ) for ( ; vec < vec_limit; vec++, flag++ )
{ {
FT_Pos y = 0; FT_Pos y = 0;
FT_Byte f = *flag;
if ( *flag & 2 ) if ( f & 2 )
{ {
if ( p + 1 > limit ) if ( p + 1 > limit )
goto Invalid_Outline; goto Invalid_Outline;
y = (FT_Pos)FT_NEXT_BYTE( p ); y = (FT_Pos)FT_NEXT_BYTE( p );
if ( ( *flag & 16 ) == 0 ) if ( ( f & 16 ) == 0 )
y = -y; y = -y;
} }
else if ( ( *flag & 16 ) == 0 ) else if ( ( f & 16 ) == 0 )
{ {
if ( p + 2 > limit ) if ( p + 2 > limit )
goto Invalid_Outline; goto Invalid_Outline;
@@ -381,6 +401,7 @@
x += y; x += y;
vec->x = x; vec->x = x;
*flag = f & ~( 2 | 16 );
} }
/* reading the Y coordinates */ /* reading the Y coordinates */
@@ -393,18 +414,19 @@
for ( ; vec < vec_limit; vec++, flag++ ) for ( ; vec < vec_limit; vec++, flag++ )
{ {
FT_Pos y = 0; FT_Pos y = 0;
FT_Byte f = *flag;
if ( *flag & 4 ) if ( f & 4 )
{ {
if ( p +1 > limit ) if ( p + 1 > limit )
goto Invalid_Outline; goto Invalid_Outline;
y = (FT_Pos)FT_NEXT_BYTE( p ); y = (FT_Pos)FT_NEXT_BYTE( p );
if ( ( *flag & 32 ) == 0 ) if ( ( f & 32 ) == 0 )
y = -y; y = -y;
} }
else if ( ( *flag & 32 ) == 0 ) else if ( ( f & 32 ) == 0 )
{ {
if ( p + 2 > limit ) if ( p + 2 > limit )
goto Invalid_Outline; goto Invalid_Outline;
@@ -414,12 +436,9 @@
x += y; x += y;
vec->y = x; vec->y = x;
*flag = f & FT_CURVE_TAG_ON;
} }
/* clear the touch tags */
for ( n = 0; n < n_points; n++ )
outline->tags[n] &= FT_CURVE_TAG_ON;
outline->n_points = (FT_UShort)n_points; outline->n_points = (FT_UShort)n_points;
outline->n_contours = (FT_Short) n_contours; outline->n_contours = (FT_Short) n_contours;
@@ -573,7 +592,8 @@
FT_UInt start_contour ) FT_UInt start_contour )
{ {
zone->n_points = (FT_UShort)( load->outline.n_points - start_point ); zone->n_points = (FT_UShort)( load->outline.n_points - start_point );
zone->n_contours = (FT_Short) ( load->outline.n_contours - start_contour ); zone->n_contours = (FT_Short) ( load->outline.n_contours -
start_contour );
zone->org = load->extra_points + start_point; zone->org = load->extra_points + start_point;
zone->cur = load->outline.points + start_point; zone->cur = load->outline.points + start_point;
zone->orus = load->extra_points2 + start_point; zone->orus = load->extra_points2 + start_point;
@@ -984,7 +1004,8 @@
/* check it */ /* check it */
if ( n_ins > ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions ) if ( n_ins > ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions )
{ {
FT_TRACE0(( "Too many instructions (%d)\n", n_ins )); FT_TRACE0(( "TT_Process_Composite_Glyph: Too many instructions (%d)\n",
n_ins ));
return TT_Err_Too_Many_Hints; return TT_Err_Too_Many_Hints;
} }
@@ -1316,7 +1337,7 @@
/* this provides additional offsets */ /* this provides additional offsets */
/* for each component's translation */ /* for each component's translation */
if ( (error = TT_Vary_Get_Glyph_Deltas( if ( ( error = TT_Vary_Get_Glyph_Deltas(
face, face,
glyph_index, glyph_index,
&deltas, &deltas,
@@ -1356,7 +1377,6 @@
/* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */ /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
/* `as is' in the glyph slot (the client application will be */ /* `as is' in the glyph slot (the client application will be */
/* responsible for interpreting these data)... */ /* responsible for interpreting these data)... */
/* */
if ( loader->load_flags & FT_LOAD_NO_RECURSE ) if ( loader->load_flags & FT_LOAD_NO_RECURSE )
{ {
FT_GlyphLoader_Add( gloader ); FT_GlyphLoader_Add( gloader );
@@ -1379,6 +1399,11 @@
FT_Stream old_stream = loader->stream; FT_Stream old_stream = loader->stream;
TT_GraphicsState saved_GS;
if ( loader->exec )
saved_GS = loader->exec->GS;
FT_GlyphLoader_Add( gloader ); FT_GlyphLoader_Add( gloader );
@@ -1388,6 +1413,10 @@
FT_Vector pp[4]; FT_Vector pp[4];
/* reinitialize graphics state */
if ( loader->exec )
loader->exec->GS = saved_GS;
/* Each time we call load_truetype_glyph in this loop, the */ /* Each time we call load_truetype_glyph in this loop, the */
/* value of `gloader.base.subglyphs' can change due to table */ /* value of `gloader.base.subglyphs' can change due to table */
/* reallocations. We thus need to recompute the subglyph */ /* reallocations. We thus need to recompute the subglyph */
@@ -1422,10 +1451,10 @@
if ( num_points == num_base_points ) if ( num_points == num_base_points )
continue; continue;
/* gloader->base.outline consists of three part: */ /* gloader->base.outline consists of three parts: */
/* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */ /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */
/* */ /* */
/* (1): exist from the beginning */ /* (1): exists from the beginning */
/* (2): components that have been loaded so far */ /* (2): components that have been loaded so far */
/* (3): the newly loaded component */ /* (3): the newly loaded component */
TT_Process_Composite_Component( loader, subglyph, start_point, TT_Process_Composite_Component( loader, subglyph, start_point,
@@ -1451,7 +1480,7 @@
} }
else else
{ {
/* invalid composite count ( negative but not -1 ) */ /* invalid composite count (negative but not -1) */
error = TT_Err_Invalid_Outline; error = TT_Err_Invalid_Outline;
goto Exit; goto Exit;
} }
@@ -1498,7 +1527,7 @@
else else
bbox = loader->bbox; bbox = loader->bbox;
/* get the device-independent horizontal advance. It is scaled later */ /* get the device-independent horizontal advance; it is scaled later */
/* by the base layer. */ /* by the base layer. */
{ {
FT_Pos advance = loader->linear; FT_Pos advance = loader->linear;
@@ -1759,11 +1788,11 @@
tt_size_run_prep( size ); tt_size_run_prep( size );
} }
/* see if the cvt program has disabled hinting */ /* see whether the cvt program has disabled hinting */
if ( exec->GS.instruct_control & 1 ) if ( exec->GS.instruct_control & 1 )
load_flags |= FT_LOAD_NO_HINTING; load_flags |= FT_LOAD_NO_HINTING;
/* load default graphics state - if needed */ /* load default graphics state -- if needed */
if ( exec->GS.instruct_control & 2 ) if ( exec->GS.instruct_control & 2 )
exec->GS = tt_default_graphics_state; exec->GS = tt_default_graphics_state;
@@ -1774,7 +1803,7 @@
#endif /* TT_USE_BYTECODE_INTERPRETER */ #endif /* TT_USE_BYTECODE_INTERPRETER */
/* seek to the beginning of the glyph table. For Type 42 fonts */ /* seek to the beginning of the glyph table -- for Type 42 fonts */
/* the table might be accessed from a Postscript stream or something */ /* the table might be accessed from a Postscript stream or something */
/* else... */ /* else... */
@@ -1852,13 +1881,11 @@
FT_Int32 load_flags ) FT_Int32 load_flags )
{ {
TT_Face face; TT_Face face;
FT_Stream stream;
FT_Error error; FT_Error error;
TT_LoaderRec loader; TT_LoaderRec loader;
face = (TT_Face)glyph->face; face = (TT_Face)glyph->face;
stream = face->root.stream;
error = TT_Err_Ok; error = TT_Err_Ok;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
@@ -1892,7 +1919,7 @@
glyph->num_subglyphs = 0; glyph->num_subglyphs = 0;
glyph->outline.flags = 0; glyph->outline.flags = 0;
/* Main loading loop */ /* main loading loop */
error = load_truetype_glyph( &loader, glyph_index, 0 ); error = load_truetype_glyph( &loader, glyph_index, 0 );
if ( !error ) if ( !error )
{ {
+22 -10
View File
@@ -621,6 +621,10 @@
exec->pts.n_points = 0; exec->pts.n_points = 0;
exec->pts.n_contours = 0; exec->pts.n_contours = 0;
exec->zp1 = exec->pts;
exec->zp2 = exec->pts;
exec->zp0 = exec->pts;
exec->instruction_trap = FALSE; exec->instruction_trap = FALSE;
return TT_Err_Ok; return TT_Err_Ok;
@@ -1127,17 +1131,8 @@
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
}; };
static
const FT_Vector Null_Vector = {0,0};
#undef PACK #undef PACK
#undef NULL_Vector
#define NULL_Vector (FT_Vector*)&Null_Vector
#if 1 #if 1
static FT_Int32 static FT_Int32
@@ -6157,6 +6152,13 @@
*/ */
twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0; twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0;
if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) )
{
if ( CUR.pedantic_hinting )
CUR.error = TT_Err_Invalid_Reference;
return;
}
if ( twilight ) if ( twilight )
orus_base = &CUR.zp0.org[CUR.GS.rp1]; orus_base = &CUR.zp0.org[CUR.GS.rp1];
else else
@@ -6213,7 +6215,7 @@
? TT_MULDIV( org_dist, cur_range, old_range ) ? TT_MULDIV( org_dist, cur_range, old_range )
: cur_dist; : cur_dist;
CUR_Func_move( &CUR.zp2, point, new_dist - cur_dist ); CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist );
} }
CUR.GS.loop = 1; CUR.GS.loop = 1;
CUR.new_top = CUR.args; CUR.new_top = CUR.args;
@@ -6260,6 +6262,7 @@
FT_Vector* orgs; /* original and current coordinate */ FT_Vector* orgs; /* original and current coordinate */
FT_Vector* curs; /* arrays */ FT_Vector* curs; /* arrays */
FT_Vector* orus; FT_Vector* orus;
FT_UInt max_points;
} IUP_WorkerRec, *IUP_Worker; } IUP_WorkerRec, *IUP_Worker;
@@ -6300,6 +6303,10 @@
if ( p1 > p2 ) if ( p1 > p2 )
return; return;
if ( BOUNDS( ref1, worker->max_points ) ||
BOUNDS( ref2, worker->max_points ) )
return;
orus1 = worker->orus[ref1].x; orus1 = worker->orus[ref1].x;
orus2 = worker->orus[ref2].x; orus2 = worker->orus[ref2].x;
@@ -6399,6 +6406,10 @@
FT_UNUSED_ARG; FT_UNUSED_ARG;
/* ignore empty outlines */
if ( CUR.pts.n_contours == 0 )
return;
if ( CUR.opcode & 1 ) if ( CUR.opcode & 1 )
{ {
mask = FT_CURVE_TAG_TOUCH_X; mask = FT_CURVE_TAG_TOUCH_X;
@@ -6413,6 +6424,7 @@
V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 );
V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 ); V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 );
} }
V.max_points = CUR.pts.n_points;
contour = 0; contour = 0;
point = 0; point = 0;
+3 -10
View File
@@ -693,21 +693,14 @@
size->GS = tt_default_graphics_state; size->GS = tt_default_graphics_state;
error = tt_size_run_prep( size ); error = tt_size_run_prep( size );
if ( !error )
size->cvt_ready = 1;
} }
Exit: Exit:
return error; return error;
} }
#else /* !TT_USE_BYTECODE_INTERPRETER */ #endif /* TT_USE_BYTECODE_INTERPRETER */
FT_LOCAL_DEF( FT_Error )
tt_size_ready_bytecode( TT_Size size )
{
FT_UNUSED( size );
return 0;
}
#endif /* !TT_USE_BYTECODE_INTERPRETER */
/*************************************************************************/ /*************************************************************************/
+3 -3
View File
@@ -423,14 +423,14 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
tt_size_run_prep( TT_Size size ); tt_size_run_prep( TT_Size size );
FT_LOCAL( FT_Error )
tt_size_ready_bytecode( TT_Size size );
#endif /* TT_USE_BYTECODE_INTERPRETER */ #endif /* TT_USE_BYTECODE_INTERPRETER */
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
tt_size_reset( TT_Size size ); tt_size_reset( TT_Size size );
FT_LOCAL( FT_Error )
tt_size_ready_bytecode( TT_Size size );
/*************************************************************************/ /*************************************************************************/
/* */ /* */
+31 -1
View File
@@ -1066,12 +1066,26 @@
FT_Face root = (FT_Face)&face->root; FT_Face root = (FT_Face)&face->root;
FT_Fixed temp[6]; FT_Fixed temp[6];
FT_Fixed temp_scale; FT_Fixed temp_scale;
FT_Int result;
(void)T1_ToFixedArray( parser, 6, temp, 3 ); result = T1_ToFixedArray( parser, 6, temp, 3 );
if ( result < 0 )
{
parser->root.error = T1_Err_Invalid_File_Format;
return;
}
temp_scale = FT_ABS( temp[3] ); temp_scale = FT_ABS( temp[3] );
if ( temp_scale == 0 )
{
FT_ERROR(( "parse_font_matrix: invalid font matrix\n" ));
parser->root.error = T1_Err_Invalid_File_Format;
return;
}
/* Set Units per EM based on FontMatrix values. We set the value to */ /* Set Units per EM based on FontMatrix values. We set the value to */
/* 1000 / temp_scale, because temp_scale was already multiplied by */ /* 1000 / temp_scale, because temp_scale was already multiplied by */
/* 1000 (in t1_tofixed, from psobjs.c). */ /* 1000 (in t1_tofixed, from psobjs.c). */
@@ -1253,7 +1267,11 @@
} }
} }
else else
{
T1_Skip_PS_Token( parser ); T1_Skip_PS_Token( parser );
if ( parser->root.error )
return;
}
T1_Skip_Spaces( parser ); T1_Skip_Spaces( parser );
} }
@@ -1379,6 +1397,12 @@
FT_Byte* temp; FT_Byte* temp;
if ( size <= face->type1.private_dict.lenIV )
{
error = T1_Err_Invalid_File_Format;
goto Fail;
}
/* t1_decrypt() shouldn't write to base -- make temporary copy */ /* t1_decrypt() shouldn't write to base -- make temporary copy */
if ( FT_ALLOC( temp, size ) ) if ( FT_ALLOC( temp, size ) )
goto Fail; goto Fail;
@@ -1554,6 +1578,12 @@
FT_Byte* temp; FT_Byte* temp;
if ( size <= face->type1.private_dict.lenIV )
{
error = T1_Err_Invalid_File_Format;
goto Fail;
}
/* t1_decrypt() shouldn't write to base -- make temporary copy */ /* t1_decrypt() shouldn't write to base -- make temporary copy */
if ( FT_ALLOC( temp, size ) ) if ( FT_ALLOC( temp, size ) )
goto Fail; goto Fail;
+4 -6
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* Type 1 objects manager (body). */ /* Type 1 objects manager (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@@ -191,13 +191,11 @@
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
T1_Face_Done( T1_Face face ) T1_Face_Done( T1_Face face )
{ {
FT_Memory memory;
T1_Font type1 = &face->type1;
if ( face ) if ( face )
{ {
memory = face->root.memory; FT_Memory memory = face->root.memory;
T1_Font type1 = &face->type1;
#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
/* release multiple masters information */ /* release multiple masters information */
+3 -1
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* Type 42 objects manager (body). */ /* Type 42 objects manager (body). */
/* */ /* */
/* Copyright 2002, 2003, 2004, 2005, 2006 by Roberto Alameda. */ /* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by Roberto Alameda. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */ /* modified, and distributed under the terms of the FreeType project */
@@ -55,6 +55,8 @@
error = t42_parse_dict( face, &loader, error = t42_parse_dict( face, &loader,
parser->base_dict, parser->base_len ); parser->base_dict, parser->base_len );
if ( error )
goto Exit;
if ( type1->font_type != 42 ) if ( type1->font_type != 42 )
{ {
+31 -5
View File
@@ -4,7 +4,7 @@
/* */ /* */
/* Type 42 font parser (body). */ /* Type 42 font parser (body). */
/* */ /* */
/* Copyright 2002, 2003, 2004, 2005, 2006 by Roberto Alameda. */ /* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by Roberto Alameda. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */ /* modified, and distributed under the terms of the FreeType project */
@@ -393,7 +393,7 @@
break; break;
} }
/* check whether we've found an entry */ /* check whether we have found an entry */
if ( ft_isdigit( *cur ) || only_immediates ) if ( ft_isdigit( *cur ) || only_immediates )
{ {
FT_Int charcode; FT_Int charcode;
@@ -433,7 +433,11 @@
} }
} }
else else
{
T1_Skip_PS_Token( parser ); T1_Skip_PS_Token( parser );
if ( parser->root.error )
return;
}
T1_Skip_Spaces( parser ); T1_Skip_Spaces( parser );
} }
@@ -490,7 +494,7 @@
FT_Long n, string_size, old_string_size, real_size; FT_Long n, string_size, old_string_size, real_size;
FT_Byte* string_buf = NULL; FT_Byte* string_buf = NULL;
FT_Bool alloc = 0; FT_Bool allocated = 0;
T42_Load_Status status; T42_Load_Status status;
@@ -545,7 +549,7 @@
if ( FT_REALLOC( string_buf, old_string_size, string_size ) ) if ( FT_REALLOC( string_buf, old_string_size, string_size ) )
goto Fail; goto Fail;
alloc = 1; allocated = 1;
parser->root.cursor = cur; parser->root.cursor = cur;
(void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 ); (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 );
@@ -555,6 +559,14 @@
else if ( ft_isdigit( *cur ) ) else if ( ft_isdigit( *cur ) )
{ {
if ( allocated )
{
FT_ERROR(( "t42_parse_sfnts: "
"can't handle mixed binary and hex strings!\n" ));
error = T42_Err_Invalid_File_Format;
goto Fail;
}
string_size = T1_ToInt( parser ); string_size = T1_ToInt( parser );
T1_Skip_PS_Token( parser ); /* `RD' */ T1_Skip_PS_Token( parser ); /* `RD' */
@@ -572,10 +584,24 @@
} }
} }
if ( !string_buf )
{
FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array!\n" ));
error = T42_Err_Invalid_File_Format;
goto Fail;
}
/* A string can have a trailing zero byte for padding. Ignore it. */ /* A string can have a trailing zero byte for padding. Ignore it. */
if ( string_buf[string_size - 1] == 0 && ( string_size % 2 == 1 ) ) if ( string_buf[string_size - 1] == 0 && ( string_size % 2 == 1 ) )
string_size--; string_size--;
if ( !string_size )
{
FT_ERROR(( "t42_parse_sfnts: invalid string!\n" ));
error = T42_Err_Invalid_File_Format;
goto Fail;
}
for ( n = 0; n < string_size; n++ ) for ( n = 0; n < string_size; n++ )
{ {
switch ( status ) switch ( status )
@@ -654,7 +680,7 @@
parser->root.error = error; parser->root.error = error;
Exit: Exit:
if ( alloc ) if ( allocated )
FT_FREE( string_buf ); FT_FREE( string_buf );
} }
+304 -6
View File
@@ -4,8 +4,10 @@
/* */ /* */
/* FreeType font driver for Windows FNT/FON files */ /* FreeType font driver for Windows FNT/FON files */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* Copyright 2003 Huw D M Davies for Codeweavers */
/* Copyright 2007 Dmitry Timoshkov for Codeweavers */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */ /* modified, and distributed under the terms of the FreeType project */
@@ -62,6 +64,80 @@
FT_FRAME_END FT_FRAME_END
}; };
static const FT_Frame_Field winpe32_header_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE WinPE32_HeaderRec
FT_FRAME_START( 248 ),
FT_FRAME_ULONG_LE ( magic ), /* PE00 */
FT_FRAME_USHORT_LE ( machine ), /* 0x014c - i386 */
FT_FRAME_USHORT_LE ( number_of_sections ),
FT_FRAME_SKIP_BYTES( 12 ),
FT_FRAME_USHORT_LE ( size_of_optional_header ),
FT_FRAME_SKIP_BYTES( 2 ),
FT_FRAME_USHORT_LE ( magic32 ), /* 0x10b */
FT_FRAME_SKIP_BYTES( 110 ),
FT_FRAME_ULONG_LE ( rsrc_virtual_address ),
FT_FRAME_ULONG_LE ( rsrc_size ),
FT_FRAME_SKIP_BYTES( 104 ),
FT_FRAME_END
};
static const FT_Frame_Field winpe32_section_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE WinPE32_SectionRec
FT_FRAME_START( 40 ),
FT_FRAME_BYTES ( name, 8 ),
FT_FRAME_SKIP_BYTES( 4 ),
FT_FRAME_ULONG_LE ( virtual_address ),
FT_FRAME_ULONG_LE ( size_of_raw_data ),
FT_FRAME_ULONG_LE ( pointer_to_raw_data ),
FT_FRAME_SKIP_BYTES( 16 ),
FT_FRAME_END
};
static const FT_Frame_Field winpe_rsrc_dir_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE WinPE_RsrcDirRec
FT_FRAME_START( 16 ),
FT_FRAME_ULONG_LE ( characteristics ),
FT_FRAME_ULONG_LE ( time_date_stamp ),
FT_FRAME_USHORT_LE( major_version ),
FT_FRAME_USHORT_LE( minor_version ),
FT_FRAME_USHORT_LE( number_of_named_entries ),
FT_FRAME_USHORT_LE( number_of_id_entries ),
FT_FRAME_END
};
static const FT_Frame_Field winpe_rsrc_dir_entry_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE WinPE_RsrcDirEntryRec
FT_FRAME_START( 8 ),
FT_FRAME_ULONG_LE( name ),
FT_FRAME_ULONG_LE( offset ),
FT_FRAME_END
};
static const FT_Frame_Field winpe_rsrc_data_entry_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE WinPE_RsrcDataEntryRec
FT_FRAME_START( 16 ),
FT_FRAME_ULONG_LE( offset_to_data ),
FT_FRAME_ULONG_LE( size ),
FT_FRAME_ULONG_LE( code_page ),
FT_FRAME_ULONG_LE( reserved ),
FT_FRAME_END
};
static const FT_Frame_Field winfnt_header_fields[] = static const FT_Frame_Field winfnt_header_fields[] =
{ {
#undef FT_STRUCTURE #undef FT_STRUCTURE
@@ -214,6 +290,8 @@
WinNE_HeaderRec ne_header; WinNE_HeaderRec ne_header;
FT_TRACE2(( "MZ signature found\n" ));
if ( FT_STREAM_SEEK( mz_header.lfanew ) || if ( FT_STREAM_SEEK( mz_header.lfanew ) ||
FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) ) FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) )
goto Exit; goto Exit;
@@ -229,6 +307,8 @@
FT_ULong font_offset = 0; FT_ULong font_offset = 0;
FT_TRACE2(( "NE signature found\n" ));
if ( FT_STREAM_SEEK( res_offset ) || if ( FT_STREAM_SEEK( res_offset ) ||
FT_FRAME_ENTER( ne_header.rname_tab_offset - FT_FRAME_ENTER( ne_header.rname_tab_offset -
ne_header.resource_tab_offset ) ) ne_header.resource_tab_offset ) )
@@ -263,7 +343,16 @@
if ( !font_count || !font_offset ) if ( !font_count || !font_offset )
{ {
FT_TRACE2(( "this file doesn't contain any FNT resources!\n" )); FT_TRACE2(( "this file doesn't contain any FNT resources!\n" ));
error = FNT_Err_Unknown_File_Format; error = FNT_Err_Invalid_File_Format;
goto Exit;
}
/* loading `winfnt_header_fields' needs at least 118 bytes; */
/* use this as a rough measure to check the expected font size */
if ( font_count * 118UL > stream->size )
{
FT_TRACE2(( "invalid number of faces\n" ));
error = FNT_Err_Invalid_File_Format;
goto Exit; goto Exit;
} }
@@ -284,7 +373,6 @@
face->font->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift; face->font->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift;
face->font->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift; face->font->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift;
face->font->size_shift = size_shift;
stream->cursor += 8; stream->cursor += 8;
@@ -292,6 +380,193 @@
error = fnt_font_load( face->font, stream ); error = fnt_font_load( face->font, stream );
} }
else if ( ne_header.magic == WINFNT_PE_MAGIC )
{
WinPE32_HeaderRec pe32_header;
WinPE32_SectionRec pe32_section;
WinPE_RsrcDirRec root_dir, name_dir, lang_dir;
WinPE_RsrcDirEntryRec dir_entry1, dir_entry2, dir_entry3;
WinPE_RsrcDataEntryRec data_entry;
FT_Long root_dir_offset, name_dir_offset, lang_dir_offset;
FT_UShort i, j, k;
FT_TRACE2(( "PE signature found\n" ));
if ( FT_STREAM_SEEK( mz_header.lfanew ) ||
FT_STREAM_READ_FIELDS( winpe32_header_fields, &pe32_header ) )
goto Exit;
FT_TRACE2(( "magic %04lx, machine %02x, number_of_sections %u, "
"size_of_optional_header %02x\n"
"magic32 %02x, rsrc_virtual_address %04lx, "
"rsrc_size %04lx\n",
pe32_header.magic, pe32_header.machine,
pe32_header.number_of_sections,
pe32_header.size_of_optional_header,
pe32_header.magic32, pe32_header.rsrc_virtual_address,
pe32_header.rsrc_size ));
if ( pe32_header.magic != WINFNT_PE_MAGIC /* check full signature */ ||
pe32_header.machine != 0x014c /* i386 */ ||
pe32_header.size_of_optional_header != 0xe0 /* FIXME */ ||
pe32_header.magic32 != 0x10b )
{
FT_TRACE2(( "this file has an invalid PE header\n" ));
error = FNT_Err_Invalid_File_Format;
goto Exit;
}
face->root.num_faces = 0;
for ( i = 0; i < pe32_header.number_of_sections; i++ )
{
if ( FT_STREAM_READ_FIELDS( winpe32_section_fields,
&pe32_section ) )
goto Exit;
FT_TRACE2(( "name %.8s, va %04lx, size %04lx, offset %04lx\n",
pe32_section.name, pe32_section.virtual_address,
pe32_section.size_of_raw_data,
pe32_section.pointer_to_raw_data ));
if ( pe32_header.rsrc_virtual_address ==
pe32_section.virtual_address )
goto Found_rsrc_section;
}
FT_TRACE2(( "this file doesn't contain any resources\n" ));
error = FNT_Err_Invalid_File_Format;
goto Exit;
Found_rsrc_section:
FT_TRACE2(( "found resources section %.8s\n", pe32_section.name ));
if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data ) ||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &root_dir ) )
goto Exit;
root_dir_offset = pe32_section.pointer_to_raw_data;
for ( i = 0; i < root_dir.number_of_named_entries +
root_dir.number_of_id_entries; i++ )
{
if ( FT_STREAM_SEEK( root_dir_offset + 16 + i * 8 ) ||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,
&dir_entry1 ) )
goto Exit;
if ( !(dir_entry1.offset & 0x80000000UL ) /* DataIsDirectory */ )
{
error = FNT_Err_Invalid_File_Format;
goto Exit;
}
dir_entry1.offset &= ~0x80000000UL;
name_dir_offset = pe32_section.pointer_to_raw_data +
dir_entry1.offset;
if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data +
dir_entry1.offset ) ||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &name_dir ) )
goto Exit;
for ( j = 0; j < name_dir.number_of_named_entries +
name_dir.number_of_id_entries; j++ )
{
if ( FT_STREAM_SEEK( name_dir_offset + 16 + j * 8 ) ||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,
&dir_entry2 ) )
goto Exit;
if ( !(dir_entry2.offset & 0x80000000UL ) /* DataIsDirectory */ )
{
error = FNT_Err_Invalid_File_Format;
goto Exit;
}
dir_entry2.offset &= ~0x80000000UL;
lang_dir_offset = pe32_section.pointer_to_raw_data +
dir_entry2.offset;
if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data +
dir_entry2.offset ) ||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &lang_dir ) )
goto Exit;
for ( k = 0; k < lang_dir.number_of_named_entries +
lang_dir.number_of_id_entries; k++ )
{
if ( FT_STREAM_SEEK( lang_dir_offset + 16 + k * 8 ) ||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,
&dir_entry3 ) )
goto Exit;
if ( dir_entry2.offset & 0x80000000UL /* DataIsDirectory */ )
{
error = FNT_Err_Invalid_File_Format;
goto Exit;
}
if ( dir_entry1.name == 8 /* RT_FONT */ )
{
if ( FT_STREAM_SEEK( root_dir_offset + dir_entry3.offset ) ||
FT_STREAM_READ_FIELDS( winpe_rsrc_data_entry_fields,
&data_entry ) )
goto Exit;
FT_TRACE2(( "found font #%lu, offset %04lx, "
"size %04lx, cp %lu\n",
dir_entry2.name,
pe32_section.pointer_to_raw_data +
data_entry.offset_to_data -
pe32_section.virtual_address,
data_entry.size, data_entry.code_page ));
if ( face_index == face->root.num_faces )
{
if ( FT_NEW( face->font ) )
goto Exit;
face->font->offset = pe32_section.pointer_to_raw_data +
data_entry.offset_to_data -
pe32_section.virtual_address;
face->font->fnt_size = data_entry.size;
error = fnt_font_load( face->font, stream );
if ( error )
{
FT_TRACE2(( "font #%lu load error %d\n",
dir_entry2.name, error ));
goto Fail;
}
else
FT_TRACE2(( "font #%lu successfully loaded\n",
dir_entry2.name ));
}
face->root.num_faces++;
}
}
}
}
}
if ( !face->root.num_faces )
{
FT_TRACE2(( "this file doesn't contain any RT_FONT resources\n" ));
error = FNT_Err_Invalid_File_Format;
goto Exit;
}
if ( face_index >= face->root.num_faces )
{
error = FNT_Err_Bad_Argument;
goto Exit;
}
} }
Fail: Fail:
@@ -385,6 +660,8 @@
static void static void
FNT_Face_Done( FNT_Face face ) FNT_Face_Done( FNT_Face face )
{
if ( face )
{ {
FT_Memory memory = FT_FACE_MEMORY( face ); FT_Memory memory = FT_FACE_MEMORY( face );
@@ -394,6 +671,7 @@
FT_FREE( face->root.available_sizes ); FT_FREE( face->root.available_sizes );
face->root.num_fixed_sizes = 0; face->root.num_fixed_sizes = 0;
} }
}
static FT_Error static FT_Error
@@ -412,12 +690,18 @@
/* try to load font from a DLL */ /* try to load font from a DLL */
error = fnt_face_get_dll_font( face, face_index ); error = fnt_face_get_dll_font( face, face_index );
if ( error ) if ( error == FNT_Err_Unknown_File_Format )
{ {
/* this didn't work; try to load a single FNT font */ /* this didn't work; try to load a single FNT font */
FNT_Font font; FNT_Font font;
if ( face_index > 0 )
{
error = FNT_Err_Bad_Argument;
goto Exit;
}
if ( FT_NEW( face->font ) ) if ( FT_NEW( face->font ) )
goto Exit; goto Exit;
@@ -428,9 +712,10 @@
font->fnt_size = stream->size; font->fnt_size = stream->size;
error = fnt_font_load( font, stream ); error = fnt_font_load( font, stream );
}
if ( error ) if ( error )
goto Fail; goto Fail;
}
/* we now need to fill the root FT_Face fields */ /* we now need to fill the root FT_Face fields */
/* with relevant information */ /* with relevant information */
@@ -533,11 +818,17 @@
root->num_glyphs = font->header.last_char - root->num_glyphs = font->header.last_char -
font->header.first_char + 1 + 1; font->header.first_char + 1 + 1;
if ( font->header.face_name_offset >= font->header.file_size )
{
FT_TRACE2(( "invalid family name offset!\n" ));
error = FNT_Err_Invalid_File_Format;
goto Fail;
}
family_size = font->header.file_size - font->header.face_name_offset;
/* Some broken fonts don't delimit the face name with a final */ /* Some broken fonts don't delimit the face name with a final */
/* NULL byte -- the frame is erroneously one byte too small. */ /* NULL byte -- the frame is erroneously one byte too small. */
/* We thus allocate one more byte, setting it explicitly to */ /* We thus allocate one more byte, setting it explicitly to */
/* zero. */ /* zero. */
family_size = font->header.file_size - font->header.face_name_offset;
if ( FT_ALLOC( font->family_name, family_size + 1 ) ) if ( FT_ALLOC( font->family_name, family_size + 1 ) )
goto Fail; goto Fail;
@@ -696,6 +987,13 @@
bitmap->rows = font->header.pixel_height; bitmap->rows = font->header.pixel_height;
bitmap->pixel_mode = FT_PIXEL_MODE_MONO; bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
if ( offset + pitch * bitmap->rows >= font->header.file_size )
{
FT_TRACE2(( "invalid bitmap width\n" ));
error = FNT_Err_Invalid_File_Format;
goto Exit;
}
/* note: since glyphs are stored in columns and not in rows we */ /* note: since glyphs are stored in columns and not in rows we */
/* can't use ft_glyphslot_set_bitmap */ /* can't use ft_glyphslot_set_bitmap */
if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) ) if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) )
+62 -2
View File
@@ -4,8 +4,9 @@
/* */ /* */
/* FreeType font driver for Windows FNT/FON files */ /* FreeType font driver for Windows FNT/FON files */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* Copyright 2007 Dmitry Timoshkov for Codeweavers */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */ /* modified, and distributed under the terms of the FreeType project */
@@ -46,6 +47,65 @@ FT_BEGIN_HEADER
} WinNE_HeaderRec; } WinNE_HeaderRec;
typedef struct WinPE32_HeaderRec_
{
FT_ULong magic;
FT_UShort machine;
FT_UShort number_of_sections;
/* skipped content */
FT_UShort size_of_optional_header;
/* skipped content */
FT_UShort magic32;
/* skipped content */
FT_ULong rsrc_virtual_address;
FT_ULong rsrc_size;
/* skipped content */
} WinPE32_HeaderRec;
typedef struct WinPE32_SectionRec_
{
FT_Byte name[8];
/* skipped content */
FT_ULong virtual_address;
FT_ULong size_of_raw_data;
FT_ULong pointer_to_raw_data;
/* skipped content */
} WinPE32_SectionRec;
typedef struct WinPE_RsrcDirRec_
{
FT_ULong characteristics;
FT_ULong time_date_stamp;
FT_UShort major_version;
FT_UShort minor_version;
FT_UShort number_of_named_entries;
FT_UShort number_of_id_entries;
} WinPE_RsrcDirRec;
typedef struct WinPE_RsrcDirEntryRec_
{
FT_ULong name;
FT_ULong offset;
} WinPE_RsrcDirEntryRec;
typedef struct WinPE_RsrcDataEntryRec_
{
FT_ULong offset_to_data;
FT_ULong size;
FT_ULong code_page;
FT_ULong reserved;
} WinPE_RsrcDataEntryRec;
typedef struct WinNameInfoRec_ typedef struct WinNameInfoRec_
{ {
FT_UShort offset; FT_UShort offset;
@@ -68,12 +128,12 @@ FT_BEGIN_HEADER
#define WINFNT_MZ_MAGIC 0x5A4D #define WINFNT_MZ_MAGIC 0x5A4D
#define WINFNT_NE_MAGIC 0x454E #define WINFNT_NE_MAGIC 0x454E
#define WINFNT_PE_MAGIC 0x4550
typedef struct FNT_FontRec_ typedef struct FNT_FontRec_
{ {
FT_ULong offset; FT_ULong offset;
FT_Int size_shift;
FT_WinFNT_HeaderRec header; FT_WinFNT_HeaderRec header;