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

View File

@ -302,7 +302,9 @@ FT_BEGIN_HEADER
/* The size in bytes of the render pool used by the scan-line converter */
/* 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
@ -461,12 +463,47 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_UNPATENTED_HINTING (in addition to */
/* TT_CONFIG_OPTION_BYTECODE_INTERPRETER) to compile the unpatented */
/* work-around hinting system. Note that for the moment, the algorithm */
/* is only used when selected at runtime through the parameter tag */
/* FT_PARAM_TAG_UNPATENTED_HINTING; or when the debug hook */
/* FT_DEBUG_HOOK_UNPATENTED_HINTING is globally activated. */
/* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */
/* of the TrueType bytecode interpreter is used that doesn't implement */
/* any of the patented opcodes and algorithms. Note that the */
/* the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you */
/* define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; with other words, */
/* 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
@ -591,6 +628,11 @@ FT_BEGIN_HEADER
/* */
#define AF_CONFIG_OPTION_CJK
/*************************************************************************/
/* */
/* Compile autofit module with Indic script support. */
/* */
#define AF_CONFIG_OPTION_INDIC
/* */

View File

@ -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>
#define ft_memchr memchr

View File

@ -648,8 +648,8 @@ FT_BEGIN_HEADER
{
FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ),
FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ),
FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ),
FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ),
FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ),
FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ),
FT_ENC_TAG( FT_ENCODING_GB2312, 'g', 'b', ' ', ' ' ),
@ -2111,9 +2111,16 @@ FT_BEGIN_HEADER
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* If either the horizontal or vertical resolution is zero, it is set */
/* to a default value of 72dpi. */
/* If either the character width or height is zero, it is set equal */
/* 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_Set_Char_Size( FT_Face face,
FT_F26Dot6 char_width,
@ -2731,8 +2738,7 @@ FT_BEGIN_HEADER
/* */
/* <Description> */
/* Retrieve the ASCII name of a given glyph in a face. This only */
/* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns */
/* TRUE. */
/* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns 1. */
/* */
/* <Input> */
/* face :: A handle to a source face object. */
@ -3323,7 +3329,7 @@ FT_BEGIN_HEADER
*/
#define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 3
#define FREETYPE_PATCH 4
#define FREETYPE_PATCH 5
/*************************************************************************/
@ -3361,6 +3367,62 @@ FT_BEGIN_HEADER
FT_Int *aminor,
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 );
/* */

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -411,14 +411,14 @@ FT_BEGIN_HEADER
/* */
/* height :: The character height. */
/* */
/* pixel :: A Boolean. If TRUE, the `width' and `height' fields */
/* are interpreted as integer pixel character sizes. */
/* pixel :: A Boolean. If 1, the `width' and `height' fields are */
/* interpreted as integer pixel character sizes. */
/* 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. */
/* */
/* 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. */
/* */
/* <Note> */
@ -776,6 +776,60 @@ FT_BEGIN_HEADER
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> */
@ -930,6 +984,62 @@ FT_BEGIN_HEADER
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

View File

@ -4,7 +4,7 @@
/* */
/* FreeType error codes (specification). */
/* */
/* Copyright 2002, 2004, 2006 by */
/* Copyright 2002, 2004, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -230,6 +230,10 @@
"`BBX' field missing" )
FT_ERRORDEF_( Bbx_Too_Big, 0xB7, \
"`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 */

View File

@ -316,7 +316,7 @@ FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* ttengine
* truetype_engine
*
* @title:
* The TrueType Engine

View File

@ -297,8 +297,8 @@ FT_BEGIN_HEADER
* The source outline.
*
* opened ::
* A boolean. If TRUE, the outline is treated as an open path
* instead of a closed one.
* A boolean. If 1, the outline is treated as an open path instead
* of a closed one.
*
* @return:
* FreeType error code. 0 means success.
@ -334,7 +334,7 @@ FT_BEGIN_HEADER
* A pointer to the start vector.
*
* 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:
* FreeType error code. 0 means success.
@ -649,7 +649,7 @@ FT_BEGIN_HEADER
* A stroker handle.
*
* destroy ::
* A Boolean. If TRUE, the source glyph object is destroyed
* A Boolean. If 1, the source glyph object is destroyed
* on success.
*
* @return:
@ -682,11 +682,11 @@ FT_BEGIN_HEADER
* A stroker handle.
*
* inside ::
* A Boolean. If TRUE, return the inside border, otherwise
* A Boolean. If 1, return the inside border, otherwise
* the outside border.
*
* destroy ::
* A Boolean. If TRUE, the source glyph object is destroyed
* A Boolean. If 1, the source glyph object is destroyed
* on success.
*
* @return:

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -94,7 +94,8 @@ FT_BEGIN_HEADER
/* FT_Bool */
/* */
/* <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;
@ -384,7 +385,7 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Struct> */
/* FT_Data */
/* FT_Data */
/* */
/* <Description> */
/* Read-only binary data represented as a pointer and a length. */

View File

@ -89,6 +89,25 @@ FT_BEGIN_HEADER
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 ) )
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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_WINFNT_H <freetype/internal/services/svwinfnt.h>
#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h>
#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h>
/* */

View File

@ -52,6 +52,7 @@ FT_BEGIN_HEADER
typedef struct TT_CMapInfo_
{
FT_ULong language;
FT_Long format;
} TT_CMapInfo;

View File

@ -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 */

View File

@ -595,7 +595,7 @@ FT_BEGIN_HEADER
/* */
/* This function is only useful to access SFNT tables that are loaded */
/* by the sfnt, truetype, and opentype drivers. See @FT_Sfnt_Tag for */
/* a list. */
/* a list. */
/* */
FT_EXPORT( void* )
FT_Get_Sfnt_Table( FT_Face face,
@ -725,6 +725,26 @@ FT_BEGIN_HEADER
FT_EXPORT( FT_ULong )
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 );
/* */

View File

@ -21,7 +21,7 @@ UseFreeTypeHeaders ;
if $(FT2_MULTI)
{
_sources = afangles afglobal afhints aflatin afloader afmodule afdummy afwarp ;
_sources = afangles afglobal afhints aflatin afcjk afindic afloader afmodule afdummy afwarp ;
}
else
{

View File

@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for CJK script (body). */
/* */
/* Copyright 2006 by */
/* Copyright 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* 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 seg;
AF_Direction up_dir;
FT_Fixed scale;
FT_Pos edge_distance_threshold;
@ -342,9 +341,6 @@
scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_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 */
@ -431,7 +427,7 @@
/* insert a new edge in the list and */
/* 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 )
goto Exit;
@ -1365,7 +1361,7 @@
FT_UNUSED( metrics );
error = af_glyph_hints_reload( hints, outline );
error = af_glyph_hints_reload( hints, outline, 0 );
if ( error )
goto Exit;

View File

@ -20,21 +20,29 @@
#include "afdummy.h"
#include "aflatin.h"
#include "afcjk.h"
#include "afindic.h"
#include "aferrors.h"
#ifdef FT_OPTION_AUTOFIT2
#include "aflatin2.h"
#endif
/* populate this list when you add new scripts */
static AF_ScriptClass const af_script_classes[] =
{
&af_dummy_script_class,
#ifdef FT_OPTION_AUTOFIT2
&af_latin2_script_class,
#endif
&af_latin_script_class,
&af_cjk_script_class,
&af_indic_script_class,
NULL /* do not remove */
};
/* index of default script in `af_script_classes' */
#define AF_SCRIPT_LIST_DEFAULT 1
#define AF_SCRIPT_LIST_DEFAULT 2
/* indicates an uncovered glyph */
#define AF_SCRIPT_LIST_NONE 255
@ -217,12 +225,16 @@
FT_LOCAL_DEF( FT_Error )
af_face_globals_get_metrics( AF_FaceGlobals globals,
FT_UInt gindex,
FT_UInt options,
AF_ScriptMetrics *ametrics )
{
AF_ScriptMetrics metrics = NULL;
FT_UInt gidx;
AF_ScriptClass clazz;
FT_Error error = AF_Err_Ok;
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;
if ( gindex >= globals->glyph_count )
@ -231,8 +243,14 @@
goto Exit;
}
gidx = globals->glyph_scripts[gindex];
clazz = af_script_classes[gidx];
gidx = script;
if ( gidx == 0 || gidx + 1 >= script_max )
gidx = globals->glyph_scripts[gindex];
clazz = af_script_classes[gidx];
if ( script == 0 )
script = clazz->script;
metrics = globals->metrics[clazz->script];
if ( metrics == NULL )
{

View File

@ -5,7 +5,7 @@
/* Auto-fitter routines to compute global hinting values */
/* (specification). */
/* */
/* Copyright 2003, 2004, 2005 by */
/* Copyright 2003, 2004, 2005, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -50,6 +50,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
af_face_globals_get_metrics( AF_FaceGlobals globals,
FT_UInt gindex,
FT_UInt options,
AF_ScriptMetrics *ametrics );
FT_LOCAL( void )

View File

@ -54,9 +54,6 @@
}
segment = axis->segments + axis->num_segments++;
#if 0
FT_ZERO( segment );
#endif
Exit:
*asegment = segment;
@ -67,6 +64,7 @@
FT_LOCAL( FT_Error )
af_axis_hints_new_edge( AF_AxisHints axis,
FT_Int fpos,
AF_Direction dir,
FT_Memory memory,
AF_Edge *aedge )
{
@ -101,8 +99,16 @@
edges = axis->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--;
}
@ -111,6 +117,7 @@
FT_ZERO( edge );
edge->fpos = (FT_Short)fpos;
edge->dir = (FT_Char)dir;
Exit:
*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. */
void
af_glyph_hints_dump_segments( AF_GlyphHints hints )
@ -204,19 +239,21 @@
printf ( "Table of %s segments:\n",
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
printf ( " [ index | pos | dir | link | serif |"
" height | extra ]\n" );
printf ( " [ index | pos | dir | link | serif |"
" height | extra | flags ]\n" );
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,
(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_INDEX_NUM( seg->link, segments ),
AF_INDEX_NUM( seg->serif, segments ),
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" );
}
@ -243,21 +280,22 @@
*/
printf ( "Table of %s edges:\n",
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
printf ( " [ index | pos | dir | link |"
" serif | blue | opos | pos ]\n" );
printf ( " [ index | pos | dir | link |"
" serif | blue | opos | pos | flags ]\n" );
for ( edge = edges; edge < limit; edge++ )
{
printf ( " [ %5d | %4d | %5s | %4d |"
" %5d | %c | %5.2f | %5.2f ]\n",
printf ( " [ %5d | %5.2g | %5s | %4d |"
" %5d | %c | %5.2f | %5.2f | %s ]\n",
edge - edges,
(int)edge->fpos,
(int)edge->opos / 64.0,
af_dir_str( (AF_Direction)edge->dir ),
AF_INDEX_NUM( edge->link, edges ),
AF_INDEX_NUM( edge->serif, edges ),
edge->blue_edge ? 'y' : 'n',
edge->opos / 64.0,
edge->pos / 64.0 );
edge->pos / 64.0,
af_edge_flags_to_string( edge->flags ) );
}
printf( "\n" );
}
@ -296,9 +334,6 @@
af_direction_compute( FT_Pos dx,
FT_Pos dy )
{
#if 1
FT_Pos ll, ss; /* long and short arm lengths */
AF_Direction dir; /* candidate direction */
@ -334,45 +369,16 @@
}
}
ss *= 12;
if ( FT_ABS(ll) <= FT_ABS(ss) )
ss *= 14;
if ( FT_ABS( ll ) <= FT_ABS( ss ) )
dir = AF_DIR_NONE;
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 */
#if 1
static void
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 )
af_glyph_hints_init( AF_GlyphHints hints,
@ -656,7 +551,8 @@
FT_LOCAL_DEF( FT_Error )
af_glyph_hints_reload( AF_GlyphHints hints,
FT_Outline* outline )
FT_Outline* outline,
FT_Bool get_inflections )
{
FT_Error error = AF_Err_Ok;
AF_Point points;
@ -739,10 +635,14 @@
AF_Point point_limit = points + hints->num_points;
/* compute coordinates & Bezier flags */
/* compute coordinates & Bezier flags, next and prev */
{
FT_Vector* vec = outline->points;
char* tag = outline->tags;
FT_Vector* vec = outline->points;
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++ )
@ -763,39 +663,17 @@
default:
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;
if ( point < end )
prev->next = point;
prev = point;
if ( point == end )
{
point->next = point + 1;
prev = point;
}
else
{
point->next = first;
contour_index++;
if ( point + 1 < point_limit )
if ( ++contour_index < outline->n_contours )
{
end = points + outline->contours[contour_index];
first = point + 1;
end = points + outline->contours[contour_index];
prev = end;
}
}
@ -819,24 +697,36 @@
/* 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++ )
{
AF_Point prev;
AF_Point next;
FT_Pos in_x, in_y, out_x, out_y;
FT_Pos out_x, out_y;
prev = point->prev;
in_x = point->fx - prev->fx;
in_y = point->fy - prev->fy;
if ( point == first )
{
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;
out_x = next->fx - point->fx;
out_y = next->fy - point->fy;
next = point->next;
out_x = next->fx - point->fx;
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 ) )
{
@ -845,42 +735,26 @@
}
else if ( point->out_dir == point->in_dir )
{
#if 1
if ( point->out_dir != AF_DIR_NONE )
goto Is_Weak_Point;
if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) )
goto Is_Weak_Point;
#else /* old code */
AF_Angle angle_in, angle_out, delta;
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 )
goto Is_Weak_Point;
in_x = out_x;
in_y = out_y;
prev = point;
}
}
}
/* compute inflection points */
af_glyph_hints_compute_inflections( hints );
/* compute inflection points -- */
/* disabled due to no longer perceived benefits */
if ( 0 && get_inflections )
af_glyph_hints_compute_inflections( hints );
Exit:
return error;
@ -923,46 +797,64 @@
af_glyph_hints_align_edge_points( AF_GlyphHints hints,
AF_Dimension dim )
{
AF_AxisHints axis = & hints->axis[dim];
AF_Edge edges = axis->edges;
AF_Edge edge_limit = edges + axis->num_edges;
AF_Edge edge;
AF_AxisHints axis = & hints->axis[dim];
AF_Segment segments = axis->segments;
AF_Segment segment_limit = segments + axis->num_segments;
AF_Segment seg;
for ( edge = edges; edge < edge_limit; edge++ )
if ( dim == AF_DIMENSION_HORZ )
{
/* move the points of each segment */
/* in each edge to the edge's position */
AF_Segment seg = edge->first;
do
for ( seg = segments; seg < segment_limit; seg++ )
{
AF_Point point = seg->first;
AF_Edge edge = seg->edge;
AF_Point point, first, last;
if ( edge == NULL )
continue;
first = seg->first;
last = seg->last;
point = first;
for (;;)
{
if ( dim == AF_DIMENSION_HORZ )
{
point->x = edge->pos;
point->flags |= AF_FLAG_TOUCH_X;
}
else
{
point->y = edge->pos;
point->flags |= AF_FLAG_TOUCH_Y;
}
point->x = edge->pos;
point->flags |= AF_FLAG_TOUCH_X;
if ( point == seg->last )
if ( point == last )
break;
point = point->next;
}
}
}
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->flags |= AF_FLAG_TOUCH_Y;
if ( point == last )
break;
point = point->next;
}
seg = seg->edge_next;
} while ( seg != edge->first );
}
}
}
@ -1056,6 +948,25 @@
min = 0;
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 )
{
mid = ( max + min ) >> 1;
@ -1117,6 +1028,8 @@
AF_Point p;
FT_Pos delta = ref->u - ref->v;
if ( delta == 0 )
return;
for ( p = p1; p < ref; p++ )
p->u = p->v + delta;
@ -1235,53 +1148,76 @@
for ( ; contour < contour_limit; contour++ )
{
AF_Point first_touched, last_touched;
point = *contour;
end_point = point->prev;
first_point = point;
while ( point <= end_point && !( point->flags & touch_flag ) )
point++;
if ( point <= end_point )
/* find first touched point */
for (;;)
{
AF_Point first_touched = point;
AF_Point cur_touched = point;
if ( point > end_point ) /* no touched point in contour */
goto NextContour;
if ( point->flags & touch_flag )
break;
point++;
while ( point <= end_point )
}
first_touched = point;
last_touched = point;
for (;;)
{
FT_ASSERT( point <= end_point &&
( point->flags & touch_flag ) != 0 );
/* skip any touched neighbhours */
while ( point < end_point && ( point[1].flags & touch_flag ) != 0 )
point++;
last_touched = point;
/* find the next touched point, if any */
point ++;
for (;;)
{
if ( point->flags & touch_flag )
{
/* 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;
}
if ( point > end_point )
goto EndContour;
if ( ( point->flags & touch_flag ) != 0 )
break;
point++;
}
if ( cur_touched == first_touched )
{
/* this is a special case: only one point was touched in the */
/* contour; we thus simply shift the whole contour */
af_iup_shift( first_point, end_point, cur_touched );
}
else
{
/* now interpolate after the last touched point to the end */
/* of the contour */
af_iup_interp( cur_touched + 1, end_point,
cur_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 )
af_iup_interp( first_point, first_touched - 1,
cur_touched, first_touched );
}
/* 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 ( first_touched > points )
af_iup_interp( first_point, first_touched - 1,
last_touched, first_touched );
}
NextContour:
;
}
/* now save the interpolated values back to x/y */

View File

@ -21,6 +21,7 @@
#include "aftypes.h"
#define xxAF_SORT_SEGMENTS
FT_BEGIN_HEADER
@ -171,6 +172,9 @@ FT_BEGIN_HEADER
FT_Int num_segments;
FT_Int max_segments;
AF_Segment segments;
#ifdef AF_SORT_SEGMENTS
FT_Int mid_segments;
#endif
FT_Int num_edges;
FT_Int max_edges;
@ -262,6 +266,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error)
af_axis_hints_new_edge( AF_AxisHints axis,
FT_Int fpos,
AF_Direction dir,
FT_Memory memory,
AF_Edge *edge );
@ -281,7 +286,8 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
af_glyph_hints_reload( AF_GlyphHints hints,
FT_Outline* outline );
FT_Outline* outline,
FT_Bool get_inflections );
FT_LOCAL( void )
af_glyph_hints_save( AF_GlyphHints hints,

View File

@ -0,0 +1,134 @@
/***************************************************************************/
/* */
/* afindic.c */
/* */
/* Auto-fitter hinting routines for Indic scripts (body). */
/* */
/* Copyright 2007 by */
/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* 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 */

View File

@ -0,0 +1,41 @@
/***************************************************************************/
/* */
/* afindic.h */
/* */
/* Auto-fitter hinting routines for Indic scripts (specification). */
/* */
/* Copyright 2007 by */
/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* 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 */

View File

@ -74,7 +74,7 @@
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 )
goto Exit;
@ -269,6 +269,7 @@
/* now check whether the point belongs to a straight or round */
/* segment; we first need to find in which contour the extremum */
/* lies, then inspect its previous and next points */
if ( best_point >= 0 )
{
FT_Int prev, next;
FT_Pos dist;
@ -488,12 +489,15 @@
if ( scaled != fitted )
{
#if 0
if ( dim == AF_DIMENSION_HORZ )
{
if ( fitted < scaled )
scale -= scale / 50; /* scale *= 0.98 */
}
else
#endif
if ( dim == AF_DIMENSION_VERT )
{
scale = FT_MulDiv( scale, fitted, scaled );
}
@ -527,7 +531,8 @@
/* an extra-light axis corresponds to a standard width that is */
/* 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 )
{
@ -611,13 +616,6 @@
AF_Point* contour_limit = contour + hints->num_contours;
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 );
seg0.score = 32000;
@ -665,19 +663,6 @@
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 */
continue;
@ -773,14 +758,6 @@
segment->last = point;
segment->contour = contour;
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;
@ -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:
return error;
}
@ -938,11 +844,11 @@
{
/* the fake segments are introduced to hint the metrics -- */
/* we must never link them to anything */
if ( seg1->first == seg1->last )
if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )
continue;
for ( seg2 = seg1 + 1; seg2 < segment_limit; seg2++ )
if ( seg1->dir + seg2->dir == 0 )
for ( seg2 = segments; seg2 < segment_limit; seg2++ )
if ( seg1->dir + seg2->dir == 0 && seg2->pos > seg1->pos )
{
FT_Pos pos1 = seg1->pos;
FT_Pos pos2 = seg2->pos;
@ -1089,7 +995,7 @@
if ( dist < 0 )
dist = -dist;
if ( dist < edge_distance_threshold )
if ( dist < edge_distance_threshold && edge->dir == seg->dir )
{
found = edge;
break;
@ -1103,7 +1009,7 @@
/* insert a new edge in the list and */
/* 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 )
goto Exit;
@ -1113,6 +1019,7 @@
edge->first = seg;
edge->last = seg;
edge->fpos = seg->pos;
edge->dir = seg->dir;
edge->opos = edge->pos = FT_MulFix( seg->pos, scale );
seg->edge_next = seg;
}
@ -1253,6 +1160,7 @@
if ( is_round > 0 && is_round >= is_straight )
edge->flags |= AF_EDGE_ROUND;
#if 0
/* set the edge's main direction */
edge->dir = AF_DIR_NONE;
@ -1264,6 +1172,7 @@
else if ( ups == downs )
edge->dir = 0; /* both up and down! */
#endif
/* gets rid of serifs if link is set */
/* XXX: This gets rid of many unpleasant artefacts! */
@ -2096,16 +2005,24 @@
if ( before >= edges && before < edge &&
after < edge_limit && after > edge )
{
edge->pos = before->pos +
FT_MulDiv( edge->opos - before->opos,
after->pos - before->pos,
after->opos - before->opos );
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
{
edge->pos = anchor->pos +
FT_PIX_ROUND( edge->opos - anchor->opos );
AF_LOG(( "SERIF_LINK: edge %d (opos=%.2f) snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
( ( edge->opos - anchor->opos + 16 ) & ~31 );
AF_LOG(( "SERIF_LINK2: edge %d (opos=%.2f) snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
}
}
edge->flags |= AF_EDGE_DONE;
@ -2131,7 +2048,7 @@
int dim;
error = af_glyph_hints_reload( hints, outline );
error = af_glyph_hints_reload( hints, outline, 1 );
if ( error )
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[] =
{
{ 32, 127 }, /* XXX: TODO: Add new Unicode ranges here! */
{ 160, 255 },
{ 0, 0 }
{ 0x0020, 0x007F }, /* Basic Latin (no control characters) */
{ 0x00A0, 0x00FF }, /* Latin-1 Supplement (no control characters) */
{ 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

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 */

View File

@ -173,7 +173,7 @@
/* width/positioning that occurred during the hinting process */
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;
AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ];
AF_Edge edge1 = axis->edges; /* leftmost edge */
@ -183,7 +183,6 @@
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_lsb = edge1->opos;
new_lsb = edge1->pos;
@ -391,12 +390,12 @@
FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
FT_Vector_Transform( &vvector, &loader->trans_matrix );
}
#if 1
/* we must translate our final outline by -pp1.x and compute */
/* the new metrics */
if ( loader->pp1.x )
FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );
#endif
FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
@ -493,10 +492,17 @@
if ( !error )
{
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,
&metrics );
options, &metrics );
if ( !error )
{
loader->metrics = metrics;

View File

@ -265,6 +265,11 @@ extern void* _af_debug_hints;
AF_SCRIPT_NONE = 0,
AF_SCRIPT_LATIN = 1,
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 */
/* `afglobal.c'. */

View File

@ -4,7 +4,7 @@
/* */
/* Auto-fitter module (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006 by */
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -21,9 +21,15 @@
#include "afangles.c"
#include "afglobal.c"
#include "afhints.c"
#include "afdummy.c"
#include "aflatin.c"
#ifdef FT_OPTION_AUTOFIT2
#include "aflatin2.c"
#endif
#include "afcjk.c"
#include "afindic.c"
#include "afloader.c"
#include "afmodule.c"

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.
#
# 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_DRV_SRC := $(AUTOF_DIR)/afangles.c \
$(AUTOF_DIR)/afcjk.c \
$(AUTOF_DIR)/afdummy.c \
$(AUTOF_DIR)/afglobal.c \
$(AUTOF_DIR)/afhints.c \
$(AUTOF_DIR)/afindic.c \
$(AUTOF_DIR)/aflatin.c \
$(AUTOF_DIR)/afcjk.c \
$(AUTOF_DIR)/afloader.c \
$(AUTOF_DIR)/afmodule.c \
$(AUTOF_DIR)/afwarp.c

View File

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

View File

@ -743,7 +743,6 @@
}
else /* general case */
{
#ifdef FT_LONG64
FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -376,6 +376,8 @@
const FT_Glyph_Class* clazz;
*target = 0;
/* check arguments */
if ( !target || !source || !source->clazz )
{
@ -383,8 +385,6 @@
goto Exit;
}
*target = 0;
clazz = source->clazz;
error = ft_new_glyph( source->library, clazz, &copy );
if ( error )

View File

@ -105,6 +105,10 @@
FSSpec* pathSpec,
FT_Long* face_index )
{
FT_UNUSED( fontName );
FT_UNUSED( pathSpec );
FT_UNUSED( face_index );
return FT_Err_Unimplemented_Feature;
}
@ -118,6 +122,12 @@
FT_ATSFontGetFileReference( ATSFontRef ats_font_id,
FSRef* ats_font_ref )
{
#if __LP64__
FT_UNUSED( ats_font_id );
FT_UNUSED( ats_font_ref );
return fnfErr;
#else
OSStatus err;
FSSpec spec;
@ -127,6 +137,7 @@
err = FSpMakeFSRef( &spec, ats_font_ref );
return err;
#endif
}
@ -204,11 +215,12 @@
FT_Long* face_index )
{
#if __LP64__
FT_UNUSED( fontName );
FT_UNUSED( pathSpec );
FT_UNUSED( face_index );
return FT_Err_Unimplemented_Feature;
#else
FSRef ref;
FT_Error err;
@ -222,7 +234,6 @@
return FT_Err_Unknown_File_Format;
return FT_Err_Ok;
#endif
}
@ -447,10 +458,10 @@
static FT_Error
lookup_lwfn_by_fond( const UInt8* path_fond,
const StringPtr base_lwfn,
UInt8* path_lwfn,
int path_size )
lookup_lwfn_by_fond( const UInt8* path_fond,
ConstStr255Param base_lwfn,
UInt8* path_lwfn,
size_t path_size )
{
FSRef ref, par_ref;
int dirname_len;
@ -472,12 +483,8 @@
if ( ft_strlen( (char *)path_lwfn ) + 1 + base_lwfn[0] > path_size )
return FT_Err_Invalid_Argument;
/* now we have absolute dirname in lookup_path */
if ( path_lwfn[0] == '/' )
ft_strcat( (char *)path_lwfn, "/" );
else
ft_strcat( (char *)path_lwfn, ":" );
/* now we have absolute dirname in path_lwfn */
ft_strcat( (char *)path_lwfn, "/" );
dirname_len = ft_strlen( (char *)path_lwfn );
ft_strcat( (char *)path_lwfn, (char *)base_lwfn + 1 );
path_lwfn[dirname_len + base_lwfn[0]] = '\0';
@ -507,7 +514,6 @@
have_sfnt = have_lwfn = 0;
HLock( fond );
parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );
if ( lwfn_file_name[0] )
@ -523,7 +529,6 @@
else
num_faces = count_faces_scalable( *fond );
HUnlock( fond );
return num_faces;
}
@ -810,9 +815,7 @@
return error;
}
HLock( sfnt );
ft_memcpy( sfnt_data, *sfnt, sfnt_size );
HUnlock( sfnt );
ReleaseResource( sfnt );
is_cff = sfnt_size > 4 && sfnt_data[0] == 'O' &&
@ -894,9 +897,7 @@
if ( ResError() != noErr || fond_type != 'FOND' )
return FT_Err_Invalid_File_Format;
HLock( fond );
parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );
HUnlock( fond );
if ( lwfn_file_name[0] )
{
@ -1073,6 +1074,14 @@
FT_Long face_index,
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;
@ -1080,6 +1089,7 @@
return FT_Err_Invalid_Argument;
else
return FT_New_Face_From_FSRef( library, &ref, face_index, aface );
#endif
}

View File

@ -92,14 +92,14 @@
/* since the cast below also disables the compiler's */
/* type check, we introduce a dummy variable, which */
/* will be optimized away */
volatile jmp_buf* jump_buffer = &valid->jump_buffer;
volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer;
valid->error = error;
/* throw away volatileness; use `jump_buffer' or the */
/* 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;
if ( !face )
return;
for ( n = 0; n < face->num_charmaps; n++ )
{
FT_CMap cmap = FT_CMAP( face->charmaps[n] );
@ -1198,7 +1201,7 @@
{
FT_Open_Args args;
FT_Error error;
FT_Stream stream;
FT_Stream stream = NULL;
FT_Memory memory = library->memory;
@ -2223,16 +2226,14 @@
FT_Request_Metrics( FT_Face face,
FT_Size_Request req )
{
FT_Driver_Class clazz;
FT_Size_Metrics* metrics;
clazz = face->driver->clazz;
metrics = &face->size->metrics;
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 )
@ -2245,16 +2246,16 @@
w = h = face->ascender - face->descender;
break;
case FT_SIZE_REQUEST_TYPE_CELL:
w = face->max_advance_width;
h = face->ascender - face->descender;
break;
case FT_SIZE_REQUEST_TYPE_BBOX:
w = face->bbox.xMax - face->bbox.xMin;
h = face->bbox.yMax - face->bbox.yMin;
break;
case FT_SIZE_REQUEST_TYPE_CELL:
w = face->max_advance_width;
h = face->ascender - face->descender;
break;
case FT_SIZE_REQUEST_TYPE_SCALES:
metrics->x_scale = (FT_Fixed)req->width;
metrics->y_scale = (FT_Fixed)req->height;
@ -2263,11 +2264,8 @@
else if ( !metrics->y_scale )
metrics->y_scale = metrics->x_scale;
goto Calculate_Ppem;
break;
default:
/* this never happens */
return;
case FT_SIZE_REQUEST_TYPE_MAX:
break;
}
@ -2435,11 +2433,14 @@
if ( char_height < 1 * 64 )
char_height = 1 * 64;
if ( !horz_resolution )
horz_resolution = vert_resolution = 72;
req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
req.width = char_width;
req.height = char_height;
req.horiResolution = ( horz_resolution ) ? horz_resolution : 72;
req.vertResolution = ( vert_resolution ) ? vert_resolution : 72;
req.horiResolution = horz_resolution;
req.vertResolution = vert_resolution;
return FT_Request_Size( face, &req );
}
@ -2551,7 +2552,6 @@
{
FT_Service_Kerning service;
FT_Error error = FT_Err_Ok;
FT_Driver driver;
if ( !face )
@ -2560,8 +2560,6 @@
if ( !akerning )
return FT_Err_Invalid_Argument;
driver = face->driver;
FT_FACE_FIND_SERVICE( face, service, KERNING );
if ( !service )
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 */
FT_EXPORT_DEF( FT_Error )
@ -3703,8 +3725,9 @@
/* allocate the render pool */
library->raster_pool_size = FT_RENDER_POOL_SIZE;
if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
goto Fail;
if ( FT_RENDER_POOL_SIZE > 0 )
if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
goto Fail;
/* That's ok now */
*alibrary = library;

View File

@ -83,7 +83,9 @@
FT_Int last; /* index of last point in contour */
last = outline->contours[n];
last = outline->contours[n];
if ( last < 0 )
goto Invalid_Outline;
limit = outline->points + last;
v_start = outline->points[first];

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 */

View File

@ -1537,6 +1537,12 @@
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 ) )
goto Exit;
@ -2117,6 +2123,13 @@
_bdf_list_shift( &p->list, 1 );
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 ) )
goto Exit;
FT_MEM_COPY( p->font->name, s, slen + 1 );
@ -2301,11 +2314,19 @@
{
/* The ENDFONT field was never reached or did not exist. */
if ( !( p->flags & _BDF_GLYPHS ) )
{
/* Error happened while parsing header. */
FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno ));
error = BDF_Err_Corrupted_Font_Header;
goto Exit;
}
else
{
/* Error happened when parsing glyphs. */
FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno ));
error = BDF_Err_Corrupted_Font_Glyphs;
goto Exit;
}
}
}

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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
/* 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
FT_EXPORT( FT_Error )

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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_Manager manager )
{
FTC_MruNode_Prepend( (FTC_MruNode*)&manager->nodes_list,
void *nl = &manager->nodes_list;
FTC_MruNode_Prepend( (FTC_MruNode*)nl,
(FTC_MruNode)node );
manager->num_nodes++;
}
@ -57,7 +60,10 @@
ftc_node_mru_unlink( FTC_Node node,
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 );
manager->num_nodes--;
}

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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; \
void* _nl = &_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 ); \
} \
goto _Ok; \

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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 );
}
break;
default:
return 0;

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -300,11 +300,14 @@ FT_BEGIN_HEADER
#else /* !FTC_INLINE */
#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \
gindex, query, node, error ) \
FT_BEGIN_STMNT \
error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \
FTC_GQUERY( query ), (FTC_Node*)&(node) ); \
#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \
gindex, query, node, error ) \
FT_BEGIN_STMNT \
void* _n = &(node); \
\
\
error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \
FTC_GQUERY( query ), (FTC_Node*)_n ); \
FT_END_STMNT
#endif /* !FTC_INLINE */

View File

@ -372,12 +372,13 @@
/* 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,
FT_UInt glyph_index )
{
CFF_Font cff = (CFF_Font)decoder->builder.face->extra.data;
CFF_SubFont sub = &cff->top_font;
CFF_Font cff = (CFF_Font)decoder->builder.face->extra.data;
CFF_SubFont sub = &cff->top_font;
FT_Error error = CFF_Err_Ok;
/* manage CID fonts */
@ -386,6 +387,13 @@
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];
}
@ -395,6 +403,9 @@
decoder->glyph_width = sub->private_dict.default_width;
decoder->nominal_width = sub->private_dict.nominal_width;
Exit:
return error;
}
@ -2071,7 +2082,7 @@
if ( idx >= decoder->num_locals )
{
FT_ERROR(( "cff_decoder_parse_charstrings:" ));
FT_ERROR(( " invalid local subr index\n" ));
FT_ERROR(( " invalid local subr index\n" ));
goto Syntax_Error;
}
@ -2249,9 +2260,11 @@
&charstring, &charstring_len );
if ( !error )
{
cff_decoder_prepare( &decoder, glyph_index );
error = cff_decoder_parse_charstrings( &decoder,
charstring, charstring_len );
error = cff_decoder_prepare( &decoder, glyph_index );
if ( !error )
error = cff_decoder_parse_charstrings( &decoder,
charstring,
charstring_len );
cff_free_glyph_data( face, &charstring, &charstring_len );
}
@ -2400,36 +2413,40 @@
&charstring, &charstring_len );
if ( !error )
{
cff_decoder_prepare( &decoder, glyph_index );
error = cff_decoder_parse_charstrings( &decoder,
charstring, charstring_len );
error = cff_decoder_prepare( &decoder, glyph_index );
if ( !error )
{
error = cff_decoder_parse_charstrings( &decoder,
charstring,
charstring_len );
cff_free_glyph_data( face, &charstring, charstring_len );
cff_free_glyph_data( face, &charstring, charstring_len );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* Control data and length may not be available for incremental */
/* fonts. */
if ( face->root.internal->incremental_interface )
{
glyph->root.control_data = 0;
glyph->root.control_len = 0;
}
else
/* Control data and length may not be available for incremental */
/* fonts. */
if ( face->root.internal->incremental_interface )
{
glyph->root.control_data = 0;
glyph->root.control_len = 0;
}
else
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
/* We set control_data and control_len if charstrings is loaded. */
/* See how charstring loads at cff_index_access_element() in */
/* cffload.c. */
{
CFF_Index csindex = &cff->charstrings_index;
if ( csindex->offsets )
/* We set control_data and control_len if charstrings is loaded. */
/* See how charstring loads at cff_index_access_element() in */
/* cffload.c. */
{
glyph->root.control_data = csindex->bytes +
csindex->offsets[glyph_index] - 1;
glyph->root.control_len = charstring_len;
CFF_Index csindex = &cff->charstrings_index;
if ( csindex->offsets )
{
glyph->root.control_data = csindex->bytes +
csindex->offsets[glyph_index] - 1;
glyph->root.control_len = charstring_len;
}
}
}
}
@ -2462,25 +2479,27 @@
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
if ( cff->num_subfonts >= 1 )
{
FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index );
font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
}
else
{
font_matrix = cff->top_font.font_dict.font_matrix;
font_offset = cff->top_font.font_dict.font_offset;
}
/* Now, set the metrics -- this is rather simple, as */
/* the left side bearing is the xMin, and the top side */
/* bearing the yMax. */
if ( !error )
{
if ( cff->num_subfonts >= 1 )
{
FT_Byte fd_index = cff_fd_select_get( &cff->fd_select,
glyph_index );
font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
}
else
{
font_matrix = cff->top_font.font_dict.font_matrix;
font_offset = cff->top_font.font_dict.font_offset;
}
/* Now, set the metrics -- this is rather simple, as */
/* the left side bearing is the xMin, and the top side */
/* bearing the yMax. */
/* For composite glyphs, return only left side bearing and */
/* advance width. */
if ( load_flags & FT_LOAD_NO_RECURSE )
@ -2547,11 +2566,16 @@
glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
/* apply the font matrix */
FT_Outline_Transform( &glyph->root.outline, &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_Translate( &glyph->root.outline,
font_offset.x,
font_offset.y );
if ( !( font_offset.x == 0 &&
font_offset.y == 0 ) )
FT_Outline_Translate( &glyph->root.outline,
font_offset.x, font_offset.y );
advance.x = metrics->horiAdvance;
advance.y = 0;

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -175,7 +175,7 @@ FT_BEGIN_HEADER
FT_Bool hinting,
FT_Render_Mode hint_mode );
FT_LOCAL( void )
FT_LOCAL( FT_Error )
cff_decoder_prepare( CFF_Decoder* decoder,
FT_UInt glyph_index );

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -44,12 +44,12 @@
CID_FaceInfo cid = &face->cid;
FT_Byte* p;
FT_UInt fd_select;
FT_Stream stream = face->cid_stream;
FT_Error error = 0;
FT_Byte* charstring = 0;
FT_Memory memory = face->root.memory;
FT_Stream stream = face->cid_stream;
FT_Error error = CID_Err_Ok;
FT_Byte* charstring = 0;
FT_Memory memory = face->root.memory;
FT_ULong glyph_length = 0;
PSAux_Service psaux = (PSAux_Service)face->psaux;
PSAux_Service psaux = (PSAux_Service)face->psaux;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
@ -111,6 +111,11 @@
glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
FT_FRAME_EXIT();
if ( fd_select >= (FT_UInt)cid->num_dicts )
{
error = CID_Err_Invalid_Offset;
goto Exit;
}
if ( glyph_length == 0 )
goto Exit;
if ( FT_ALLOC( charstring, glyph_length ) )
@ -150,7 +155,7 @@
error = decoder->funcs.parse_charstrings(
decoder, charstring + cs_offset,
(FT_Int)glyph_length - cs_offset );
(FT_Int)glyph_length - cs_offset );
}
FT_FREE( charstring );

View File

@ -98,7 +98,11 @@
stream_len = stream->size - FT_STREAM_POS();
if ( stream_len == 0 )
{
FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
error = CID_Err_Unknown_File_Format;
goto Exit;
}
read_len = FT_MIN( read_len, stream_len );
if ( FT_STREAM_READ( p, read_len ) )
@ -165,7 +169,10 @@
while ( cur < limit )
{
if ( parser->root.error )
break;
{
error = parser->root.error;
goto Exit;
}
if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
{

View File

@ -34,12 +34,12 @@ ZEXPORT(uLong) adler32( /* adler, buf, len) */
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
buf += 16;
k -= 16;
}
if (k != 0) do {
s1 += *buf++;
s2 += s1;
s2 += s1;
} while (--k);
s1 %= BASE;
s2 %= BASE;

View File

@ -13,39 +13,39 @@
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define inflateInit2_ z_inflateInit2_
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateReset z_inflateReset
# define compress z_compress
# define compress2 z_compress2
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateReset z_inflateReset
# define compress z_compress
# define compress2 z_compress2
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)

View File

@ -203,7 +203,7 @@ typedef unsigned long ulg;
typedef uLong (*check_func) OF((uLong check, const Bytef *buf,
uInt len));
uInt len));
local voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
local void zcfree OF((voidpf opaque, voidpf ptr));

View File

@ -8,7 +8,7 @@
/* be used to parse compressed PCF fonts, as found with many X11 server */
/* 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, */
/* modified, and distributed under the terms of the FreeType project */
@ -23,55 +23,84 @@
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_DEBUG_H
/* refill input buffer, return 0 on success, or -1 if eof */
static int
ft_lzwstate_refill( FT_LzwState state )
{
int result = -1;
FT_ULong count;
if ( !state->in_eof )
{
FT_ULong count = FT_Stream_TryRead( state->source,
state->in_buff,
sizeof ( state->in_buff ) );
if ( state->in_eof )
return -1;
state->in_cursor = state->in_buff;
state->in_limit = state->in_buff + count;
state->in_eof = FT_BOOL( count < sizeof ( state->in_buff ) );
count = FT_Stream_TryRead( state->source,
state->buf_tab,
state->num_bits ); /* WHY? */
if ( count > 0 )
result = 0;
}
return result;
state->buf_size = (FT_UInt)count;
state->buf_total += count;
state->in_eof = FT_BOOL( count < state->num_bits );
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
ft_lzwstate_get_code( FT_LzwState state,
FT_UInt num_bits )
ft_lzwstate_get_code( FT_LzwState state )
{
FT_Int32 result = -1;
FT_UInt32 pad = state->pad;
FT_UInt pad_bits = state->pad_bits;
FT_UInt num_bits = state->num_bits;
FT_Int offset = state->buf_offset;
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 &&
ft_lzwstate_refill( state ) < 0 )
goto Exit;
if ( state->free_ent >= state->free_bits )
{
state->num_bits = ++num_bits;
state->free_bits = state->num_bits < state->max_bits
? (FT_UInt)( ( 1UL << num_bits ) - 256 )
: state->max_free + 1;
}
pad |= (FT_UInt32)(*state->in_cursor++) << pad_bits;
pad_bits += 8;
if ( state->buf_clear )
{
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;
}
result = (FT_Int32)( pad & LZW_MASK( num_bits ) );
state->pad_bits = pad_bits - num_bits;
state->pad = pad >> num_bits;
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;
}
@ -146,15 +175,14 @@
FT_LOCAL_DEF( void )
ft_lzwstate_reset( FT_LzwState state )
{
state->in_cursor = state->in_buff;
state->in_limit = state->in_buff;
state->in_eof = 0;
state->pad_bits = 0;
state->pad = 0;
state->stack_top = 0;
state->num_bits = LZW_INIT_BITS;
state->phase = FT_LZW_PHASE_START;
state->in_eof = 0;
state->buf_offset = 0;
state->buf_size = 0;
state->buf_clear = 0;
state->buf_total = 0;
state->stack_top = 0;
state->num_bits = LZW_INIT_BITS;
state->phase = FT_LZW_PHASE_START;
}
@ -196,13 +224,13 @@
}
#define FTLZW_STACK_PUSH( c ) \
FT_BEGIN_STMNT \
if ( state->stack_top >= state->stack_size && \
ft_lzwstate_stack_grow( state ) < 0 ) \
goto Eof; \
\
state->stack[ state->stack_top++ ] = (FT_Byte)(c); \
#define FTLZW_STACK_PUSH( c ) \
FT_BEGIN_STMNT \
if ( state->stack_top >= state->stack_size && \
ft_lzwstate_stack_grow( state ) < 0 ) \
goto Eof; \
\
state->stack[state->stack_top++] = (FT_Byte)(c); \
FT_END_STMNT
@ -213,8 +241,6 @@
{
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_code = state->old_code;
FT_UInt in_code = state->in_code;
@ -243,15 +269,16 @@
if ( state->max_bits > LZW_MAX_BITS )
goto Eof;
num_bits = LZW_INIT_BITS;
free_ent = ( state->block_mode ? LZW_FIRST : LZW_CLEAR ) - 256;
state->num_bits = LZW_INIT_BITS;
state->free_ent = ( state->block_mode ? LZW_FIRST
: LZW_CLEAR ) - 256;
in_code = 0;
state->free_bits = num_bits < state->max_bits
? (FT_UInt)( ( 1UL << num_bits ) - 256 )
state->free_bits = state->num_bits < state->max_bits
? (FT_UInt)( ( 1UL << state->num_bits ) - 256 )
: state->max_free + 1;
c = ft_lzwstate_get_code( state, num_bits );
c = ft_lzwstate_get_code( state );
if ( c < 0 )
goto Eof;
@ -274,7 +301,7 @@
NextCode:
c = ft_lzwstate_get_code( state, num_bits );
c = ft_lzwstate_get_code( state );
if ( c < 0 )
goto Eof;
@ -282,14 +309,10 @@
if ( code == LZW_CLEAR && state->block_mode )
{
free_ent = ( LZW_FIRST - 1 ) - 256; /* why not LZW_FIRST-256 ? */
num_bits = LZW_INIT_BITS;
state->free_bits = num_bits < state->max_bits
? (FT_UInt)( ( 1UL << num_bits ) - 256 )
: state->max_free + 1;
c = ft_lzwstate_get_code( state, num_bits );
/* why not LZW_FIRST-256 ? */
state->free_ent = ( LZW_FIRST - 1 ) - 256;
state->buf_clear = 1;
c = ft_lzwstate_get_code( state );
if ( c < 0 )
goto Eof;
@ -301,7 +324,7 @@
if ( code >= 256U )
{
/* special case for KwKwKwK */
if ( code - 256U >= free_ent )
if ( code - 256U >= state->free_ent )
{
FTLZW_STACK_PUSH( old_char );
code = old_code;
@ -335,25 +358,18 @@
}
/* now create new entry */
if ( free_ent < state->max_free )
if ( state->free_ent < state->max_free )
{
if ( free_ent >= state->prefix_size &&
ft_lzwstate_prefix_grow( state ) < 0 )
if ( state->free_ent >= state->prefix_size &&
ft_lzwstate_prefix_grow( state ) < 0 )
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->suffix[free_ent] = (FT_Byte) old_char;
state->prefix[state->free_ent] = (FT_UShort)old_code;
state->suffix[state->free_ent] = (FT_Byte) old_char;
if ( ++free_ent == state->free_bits )
{
num_bits++;
state->free_bits = num_bits < state->max_bits
? (FT_UInt)( ( 1UL << num_bits ) - 256 )
: state->max_free + 1;
}
state->free_ent += 1;
}
old_code = in_code;
@ -367,8 +383,6 @@
}
Exit:
state->num_bits = num_bits;
state->free_ent = free_ent;
state->old_code = old_code;
state->old_char = old_char;
state->in_code = in_code;

View File

@ -8,7 +8,7 @@
/* be used to parse compressed PCF fonts, as found with many X11 server */
/* 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, */
/* modified, and distributed under the terms of the FreeType project */
@ -112,13 +112,13 @@
typedef struct _FT_LzwStateRec
{
FT_LzwPhase phase;
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_Int pad_bits; /* number of meaningful bits in pad value */
FT_Byte buf_tab[16];
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_Int block_mode; /* block mode flag, from file header */
@ -138,8 +138,6 @@
FT_Byte* stack; /* character stack */
FT_UInt stack_top;
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_Stream source; /* source stream */

View File

@ -4,7 +4,7 @@
/* */
/* FreeType PFR cmap handling (body). */
/* */
/* Copyright 2002 by */
/* Copyright 2002, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -24,7 +24,8 @@
FT_CALLBACK_DEF( FT_Error )
pfr_cmap_init( PFR_CMap cmap )
{
PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap );
FT_Error error = PFR_Err_Ok;
PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap );
cmap->num_chars = face->phy_font.num_chars;
@ -39,11 +40,15 @@
for ( n = 1; n < cmap->num_chars; n++ )
{
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;
}

View File

@ -4,7 +4,7 @@
/* */
/* FreeType PFR glyph loader (body). */
/* */
/* Copyright 2002, 2003, 2005 by */
/* Copyright 2002, 2003, 2005, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -59,8 +59,10 @@
glyph->y_control = NULL;
glyph->max_xy_control = 0;
#if 0
glyph->num_x_control = 0;
glyph->num_y_control = 0;
#endif
FT_FREE( glyph->subs );
@ -131,7 +133,12 @@
/* 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 );
if ( !error )
@ -145,6 +152,7 @@
outline->n_points++;
}
Exit:
return error;
}
@ -161,7 +169,12 @@
/* 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 );
if ( !error )
@ -180,6 +193,7 @@
outline->n_points = (FT_Short)( outline->n_points + 3 );
}
Exit:
return error;
}
@ -244,7 +258,8 @@
flags = PFR_NEXT_BYTE( p );
/* test for composite glyphs */
FT_ASSERT( ( flags & PFR_GLYPH_IS_COMPOUND ) == 0 );
if ( flags & PFR_GLYPH_IS_COMPOUND )
goto Failure;
x_count = 0;
y_count = 0;
@ -339,14 +354,15 @@
for (;;)
{
FT_Int format, args_format = 0, args_count, n;
FT_UInt format, format_low, args_format = 0, args_count, n;
/***************************************************************/
/* read instruction */
/* */
PFR_CHECK( 1 );
format = PFR_NEXT_BYTE( p );
format = PFR_NEXT_BYTE( p );
format_low = format & 15;
switch ( format >> 4 )
{
@ -366,30 +382,34 @@
case 5: /* move to outside contour */
FT_TRACE6(( "- move to outside" ));
Line1:
args_format = format & 15;
args_format = format_low;
args_count = 1;
break;
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].x = glyph->x_control[format & 15];
pos[3] = pos[0];
args_count = 0;
break;
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].y = glyph->y_control[format & 15];
pos[3] = pos[0];
pos[0].y = glyph->y_control[format_low];
pos[3] = pos[0];
args_count = 0;
break;
case 6: /* horizontal to vertical curve */
FT_TRACE6(( "- hv curve " ));
args_format = 0xB8E;
args_count = 3;
args_format = 0xB8E;
args_count = 3;
break;
case 7: /* vertical to horizontal curve */
@ -401,7 +421,7 @@
default: /* general curve to */
FT_TRACE6(( "- general curve" ));
args_count = 4;
args_format = format & 15;
args_format = format_low;
}
/***********************************************************/
@ -410,7 +430,8 @@
cur = pos;
for ( n = 0; n < args_count; n++ )
{
FT_Int idx, delta;
FT_UInt idx;
FT_Int delta;
/* read the X argument */
@ -419,6 +440,8 @@
case 0: /* 8-bit index */
PFR_CHECK( 1 );
idx = PFR_NEXT_BYTE( p );
if ( idx > x_count )
goto Failure;
cur->x = glyph->x_control[idx];
FT_TRACE7(( " cx#%d", idx ));
break;
@ -447,6 +470,8 @@
case 0: /* 8-bit index */
PFR_CHECK( 1 );
idx = PFR_NEXT_BYTE( p );
if ( idx > y_count )
goto Failure;
cur->y = glyph->y_control[idx];
FT_TRACE7(( " cy#%d", idx ));
break;
@ -519,6 +544,7 @@
Exit:
return error;
Failure:
Too_Short:
error = PFR_Err_Invalid_Table;
FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" ));
@ -544,7 +570,8 @@
flags = PFR_NEXT_BYTE( p );
/* test for composite glyphs */
FT_ASSERT( ( flags & PFR_GLYPH_IS_COMPOUND ) != 0 );
if ( !( flags & PFR_GLYPH_IS_COMPOUND ) )
goto Failure;
count = flags & 0x3F;
@ -670,6 +697,7 @@
Exit:
return error;
Failure:
Too_Short:
error = PFR_Err_Invalid_Table;
FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" ));
@ -677,9 +705,6 @@
}
static FT_Error
pfr_glyph_load_rec( PFR_Glyph glyph,
FT_Stream stream,

View File

@ -4,7 +4,7 @@
/* */
/* FreeType PFR data structures (specification only). */
/* */
/* Copyright 2002, 2003, 2005 by */
/* Copyright 2002, 2003, 2005, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -335,8 +335,10 @@ FT_BEGIN_HEADER
{
FT_Byte format;
#if 0
FT_UInt num_x_control;
FT_UInt num_y_control;
#endif
FT_UInt max_xy_control;
FT_Pos* x_control;
FT_Pos* y_control;

View File

@ -4,7 +4,7 @@
/* */
/* AFM parser (body). */
/* */
/* Copyright 2006 by */
/* Copyright 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -642,14 +642,12 @@
case AFM_TOKEN_ENDFONTMETRICS:
fi->NumTrackKern = n + 1;
return PSaux_Err_Ok;
break;
case AFM_TOKEN_UNKNOWN:
break;
default:
goto Fail;
break;
}
}
@ -761,7 +759,6 @@
default:
goto Fail;
break;
}
}
@ -804,7 +801,6 @@
default:
goto Fail;
break;
}
}
@ -921,7 +917,7 @@
case AFM_TOKEN_STARTCHARMETRICS:
{
FT_Int n;
FT_Int n = 0;
if ( afm_parser_read_int( parser, &n ) )
@ -942,7 +938,6 @@
case AFM_TOKEN_ENDFONTMETRICS:
return PSaux_Err_Ok;
break;
default:
break;

View File

@ -592,7 +592,6 @@
error = PSaux_Err_Invalid_File_Format;
}
FT_ASSERT( parser->error == PSaux_Err_Ok );
parser->error = error;
parser->cursor = cur;
}
@ -785,8 +784,7 @@
if ( c == '[' )
ender = ']';
if ( c == '{' )
else if ( c == '{' )
ender = '}';
if ( ender )
@ -795,7 +793,8 @@
/* now, read the coordinates */
while ( cur < limit )
{
FT_Short dummy;
FT_Short dummy;
FT_Byte* old_cur;
/* skip whitespace in front of data */
@ -803,20 +802,29 @@
if ( cur >= limit )
goto Exit;
if ( coords != NULL && count >= max_coords )
break;
if ( *cur == ender )
{
cur++;
break;
}
old_cur = cur;
if ( coords != NULL && count >= max_coords )
break;
/* call PS_Conv_ToFixed() even if coords == NULL */
/* to properly parse number at `cur' */
*( coords != NULL ? &coords[count] : &dummy ) =
(FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );
count++;
if ( old_cur == cur )
{
count = -1;
goto Exit;
}
else
count++;
if ( !ender )
break;
@ -830,7 +838,7 @@
/* first character must be a delimiter or a part of a number */
/* NB: `values' can be NULL if we just want to skip the */
/* array in this case we ignore `max_values' */
/* array; in this case we ignore `max_values' */
static FT_Int
ps_tofixedarray( FT_Byte* *acur,
@ -854,8 +862,7 @@
if ( c == '[' )
ender = ']';
if ( c == '{' )
else if ( c == '{' )
ender = '}';
if ( ender )
@ -864,7 +871,8 @@
/* now, read the values */
while ( cur < limit )
{
FT_Fixed dummy;
FT_Fixed dummy;
FT_Byte* old_cur;
/* skip whitespace in front of data */
@ -872,20 +880,29 @@
if ( cur >= limit )
goto Exit;
if ( values != NULL && count >= max_values )
break;
if ( *cur == ender )
{
cur++;
break;
}
old_cur = cur;
if ( values != NULL && count >= max_values )
break;
/* call PS_Conv_ToFixed() even if coords == NULL */
/* to properly parse number at `cur' */
*( values != NULL ? &values[count] : &dummy ) =
PS_Conv_ToFixed( &cur, limit, power_ten );
count++;
if ( old_cur == cur )
{
count = -1;
goto Exit;
}
else
count++;
if ( !ender )
break;
@ -1161,9 +1178,18 @@
{
FT_Fixed temp[4];
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->yMin = FT_RoundFix( temp[1] );
@ -1227,8 +1253,8 @@
error = PSaux_Err_Ignore;
goto Exit;
}
if ( num_elements > T1_MAX_TABLE_ELEMENTS )
num_elements = T1_MAX_TABLE_ELEMENTS;
if ( (FT_UInt)num_elements > field->array_max )
num_elements = field->array_max;
old_cursor = parser->cursor;
old_limit = parser->limit;
@ -1311,7 +1337,7 @@
{
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;
goto Exit;
}

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -951,8 +951,9 @@
default:
if ( top - decoder->stack != num_args )
FT_TRACE0(( "\nMore operands on the stack than expected "
"(have %d, expected %d)\n",
FT_TRACE0(( "t1_decoder_parse_charstrings: "
"too much operands on the stack "
"(seen %d, expected %d)\n",
top - decoder->stack, num_args ));
break;
}

View File

@ -4,7 +4,7 @@
/* */
/* FreeType PostScript hinter module implementation (body). */
/* */
/* Copyright 2001, 2002 by */
/* Copyright 2001, 2002, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -51,6 +51,7 @@
ps_hinter_init( PS_Hinter_Module module )
{
FT_Memory memory = module->root.memory;
void* ph = &module->ps_hints;
ps_hints_init( &module->ps_hints, memory );
@ -58,10 +59,10 @@
psh_globals_funcs_init( &module->globals_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 );
module->t2_funcs.hints = (T2_Hints)&module->ps_hints;
module->t2_funcs.hints = (T2_Hints)ph;
return 0;
}

View File

@ -308,11 +308,11 @@
/* set a new mask to a given bit range */
static FT_Error
ps_mask_table_set_bits( PS_Mask_Table table,
FT_Byte* source,
FT_UInt bit_pos,
FT_UInt bit_count,
FT_Memory memory )
ps_mask_table_set_bits( PS_Mask_Table table,
const FT_Byte* source,
FT_UInt bit_pos,
FT_UInt bit_count,
FT_Memory memory )
{
FT_Error error = 0;
PS_Mask mask;
@ -330,7 +330,7 @@
/* 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_Byte* write = mask->bytes;
FT_Int wmask = 0x80;
@ -628,7 +628,7 @@
goto Exit;
/* 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 );
Exit:

View File

@ -32,7 +32,7 @@
#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
#define VARIANT_BIT ( 1L << 31 )
#define VARIANT_BIT 0x80000000UL
#define BASE_GLYPH( code ) ( (code) & ~VARIANT_BIT )
@ -92,7 +92,7 @@
if ( *p == '\0' )
return value;
if ( *p == '.' )
return value ^ VARIANT_BIT;
return value | VARIANT_BIT;
}
}
@ -132,7 +132,7 @@
if ( *p == '\0' )
return value;
if ( *p == '.' )
return value ^ VARIANT_BIT;
return value | VARIANT_BIT;
}
}
@ -156,7 +156,7 @@
if ( !dot )
return ft_get_adobe_glyph_index( glyph_name, p );
else
return ft_get_adobe_glyph_index( glyph_name, dot ) ^ VARIANT_BIT;
return ft_get_adobe_glyph_index( glyph_name, dot ) | VARIANT_BIT;
}
}

View File

@ -619,7 +619,22 @@
error = SFNT_Err_Ok;
}
else
{
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 )

View File

@ -155,6 +155,7 @@
FT_Byte* p = cmap->data + 4;
cmap_info->format = 0;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
return SFNT_Err_Ok;
@ -527,6 +528,7 @@
FT_Byte* p = cmap->data + 4;
cmap_info->format = 2;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
return SFNT_Err_Ok;
@ -1303,6 +1305,7 @@
FT_Byte* p = cmap->data + 4;
cmap_info->format = 4;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
return SFNT_Err_Ok;
@ -1462,6 +1465,7 @@
FT_Byte* p = cmap->data + 4;
cmap_info->format = 6;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
return SFNT_Err_Ok;
@ -1715,6 +1719,7 @@
FT_Byte* p = cmap->data + 8;
cmap_info->format = 8;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
return SFNT_Err_Ok;
@ -1863,6 +1868,7 @@
FT_Byte* p = cmap->data + 8;
cmap_info->format = 10;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
return SFNT_Err_Ok;
@ -2179,6 +2185,7 @@
FT_Byte* p = cmap->data + 8;
cmap_info->format = 12;
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
return SFNT_Err_Ok;
@ -2299,7 +2306,8 @@
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 */
error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );

View File

@ -84,7 +84,7 @@
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_UInt32 mask = 1UL << nn;
@ -94,7 +94,7 @@
p_next = p;
version = FT_NEXT_USHORT( p );
p += 2; /* skip version */
length = FT_NEXT_USHORT( p );
coverage = FT_NEXT_USHORT( p );

View File

@ -110,40 +110,48 @@
FT_ULong table_len;
FT_Long num_shorts, num_longs, num_shorts_checked;
TT_LongMetrics * longs;
TT_LongMetrics* longs;
TT_ShortMetrics** shorts;
FT_Byte* p;
if ( vertical )
{
void* lm = &face->vertical.long_metrics;
void** sm = &face->vertical.short_metrics;
error = face->goto_table( face, TTAG_vmtx, stream, &table_len );
if ( error )
goto Fail;
num_longs = face->vertical.number_Of_VMetrics;
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;
longs = (TT_LongMetrics *)&face->vertical.long_metrics;
shorts = (TT_ShortMetrics**)&face->vertical.short_metrics;
longs = (TT_LongMetrics*)lm;
shorts = (TT_ShortMetrics**)sm;
}
else
{
void* lm = &face->horizontal.long_metrics;
void** sm = &face->horizontal.short_metrics;
error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
if ( error )
goto Fail;
num_longs = face->horizontal.number_Of_HMetrics;
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;
longs = (TT_LongMetrics *)&face->horizontal.long_metrics;
shorts = (TT_ShortMetrics**)&face->horizontal.short_metrics;
longs = (TT_LongMetrics*)lm;
shorts = (TT_ShortMetrics**)sm;
}
/* never trust derived values */
@ -279,11 +287,14 @@
if ( vertical )
{
void *v = &face->vertical;
error = face->goto_table( face, TTAG_vhea, stream, 0 );
if ( error )
goto Fail;
header = (TT_HoriHeader*)&face->vertical;
header = (TT_HoriHeader*)v;
}
else
{
@ -348,7 +359,10 @@
if ( vertical )
{
header = (TT_HoriHeader*)&face->vertical;
void* v = &face->vertical;
header = (TT_HoriHeader*)v;
table_pos = face->vert_metrics_offset;
table_size = face->vert_metrics_size;
}
@ -415,8 +429,9 @@
FT_Short* abearing,
FT_UShort* aadvance )
{
TT_HoriHeader* header = vertical ? (TT_HoriHeader*)&face->vertical
: &face->horizontal;
void* v = &face->vertical;
void* h = &face->horizontal;
TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v : h;
TT_LongMetrics longs_m;
FT_UShort k = header->number_Of_HMetrics;

View File

@ -235,7 +235,7 @@
TT_SBit_MetricsRec* metrics )
{
FT_Error error;
FT_Stream stream = face->root.stream;
FT_Stream stream = face->root.stream;
FT_ULong ebdt_size;
@ -261,14 +261,27 @@
/* 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 );
p += 4;
decoder->strike_index_count = FT_NEXT_ULONG( p );
p += 34;
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:
@ -642,9 +655,9 @@
for ( nn = 0; nn < num_components; nn++ )
{
FT_UInt gindex = FT_NEXT_USHORT( p );
FT_Byte dx = FT_NEXT_BYTE( p );
FT_Byte dy = FT_NEXT_BYTE( p );
FT_UInt gindex = FT_NEXT_USHORT( p );
FT_Byte dx = FT_NEXT_BYTE( p );
FT_Byte dy = FT_NEXT_BYTE( p );
/* NB: a recursive call */
@ -775,9 +788,6 @@
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-- )
{
start = FT_NEXT_USHORT( p );
@ -792,6 +802,12 @@
FoundRange:
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;
if ( p + 8 > p_limit )
goto NoBitmap;
@ -831,7 +847,7 @@
goto NoBitmap;
image_start = image_size * ( glyph_index - start );
image_end = image_start + image_size;
image_end = image_start + image_size;
}
break;
@ -858,6 +874,11 @@
goto NoBitmap;
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 )
goto NoBitmap;
@ -895,6 +916,11 @@
goto NoBitmap;
num_glyphs = FT_NEXT_ULONG( p );
/* overflow check */
if ( p + 2 * num_glyphs < p )
goto Failure;
if ( p + 2 * num_glyphs > p_limit )
goto NoBitmap;
@ -910,7 +936,7 @@
if ( mm >= num_glyphs )
goto NoBitmap;
image_start = image_size*mm;
image_start = image_size * mm;
image_end = image_start + image_size;
}
break;
@ -932,6 +958,9 @@
x_pos,
y_pos );
Failure:
return SFNT_Err_Invalid_Table;
NoBitmap:
return SFNT_Err_Invalid_Argument;
}

View File

@ -197,7 +197,7 @@
#define ONE_PIXEL ( 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 FLOOR( x ) ( (x) & -ONE_PIXEL )
#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
@ -398,6 +398,9 @@
int x = ras.ex;
if ( x > ras.max_ex )
x = ras.max_ex;
pcell = &ras.ycells[ras.ey];
for (;;)
{
@ -462,6 +465,10 @@
/* All cells that are on the left of the clipping region go to the */
/* min_ex - 1 horizontal position. */
ey -= ras.min_ey;
if ( ex > ras.max_ex )
ex = ras.max_ex;
ex -= ras.min_ex;
if ( ex < 0 )
ex = -1;
@ -492,6 +499,9 @@
gray_start_cell( RAS_ARG_ TCoord ex,
TCoord ey )
{
if ( ex > ras.max_ex )
ex = (TCoord)( ras.max_ex );
if ( ex < ras.min_ex )
ex = (TCoord)( ras.min_ex - 1 );
@ -1196,6 +1206,10 @@
y += (TCoord)ras.min_ey;
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 )
{
/* see whether we can add this span to the current list */

View File

@ -29,9 +29,11 @@
#endif
#include FT_SERVICE_TRUETYPE_ENGINE_H
#include FT_SERVICE_TRUETYPE_GLYF_H
#include "ttdriver.h"
#include "ttgload.h"
#include "ttpload.h"
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include "ttgxvar.h"
@ -313,6 +315,11 @@
#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[] =
{
{ FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE },
@ -320,6 +327,7 @@
{ FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters },
#endif
{ FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine },
{ FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf },
{ NULL, NULL }
};

View File

@ -244,13 +244,14 @@
FT_Outline* outline;
TT_Face face = (TT_Face)load->face;
FT_UShort n_ins;
FT_Int n, n_points;
FT_Int n_points;
FT_Byte *flag, *flag_limit;
FT_Byte c, count;
FT_Vector *vec, *vec_limit;
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 */
@ -263,15 +264,29 @@
cont_limit = cont + n_contours;
/* 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;
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 );
if ( cont[0] <= prev_cont )
{
/* unordered contours: this is invalid */
error = FT_Err_Invalid_Table;
goto Fail;
}
prev_cont = cont[0];
}
n_points = 0;
if ( n_contours > 0 )
{
n_points = cont[-1] + 1;
if ( n_points < 0 )
goto Invalid_Outline;
}
/* note that we will add four phantom points later */
error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 );
@ -298,7 +313,8 @@
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;
goto Fail;
}
@ -357,21 +373,25 @@
flag = (FT_Byte*)outline->tags;
x = 0;
if ( p + xy_size > limit )
goto Invalid_Outline;
for ( ; vec < vec_limit; vec++, flag++ )
{
FT_Pos y = 0;
FT_Byte f = *flag;
if ( *flag & 2 )
if ( f & 2 )
{
if ( p + 1 > limit )
goto Invalid_Outline;
y = (FT_Pos)FT_NEXT_BYTE( p );
if ( ( *flag & 16 ) == 0 )
if ( ( f & 16 ) == 0 )
y = -y;
}
else if ( ( *flag & 16 ) == 0 )
else if ( ( f & 16 ) == 0 )
{
if ( p + 2 > limit )
goto Invalid_Outline;
@ -381,6 +401,7 @@
x += y;
vec->x = x;
*flag = f & ~( 2 | 16 );
}
/* reading the Y coordinates */
@ -393,18 +414,19 @@
for ( ; vec < vec_limit; vec++, flag++ )
{
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;
y = (FT_Pos)FT_NEXT_BYTE( p );
if ( ( *flag & 32 ) == 0 )
if ( ( f & 32 ) == 0 )
y = -y;
}
else if ( ( *flag & 32 ) == 0 )
else if ( ( f & 32 ) == 0 )
{
if ( p + 2 > limit )
goto Invalid_Outline;
@ -414,12 +436,9 @@
x += y;
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_contours = (FT_Short) n_contours;
@ -572,13 +591,14 @@
FT_UInt start_point,
FT_UInt start_contour )
{
zone->n_points = (FT_UShort)( load->outline.n_points - start_point );
zone->n_contours = (FT_Short) ( load->outline.n_contours - start_contour );
zone->org = load->extra_points + start_point;
zone->cur = load->outline.points + start_point;
zone->orus = load->extra_points2 + start_point;
zone->tags = (FT_Byte*)load->outline.tags + start_point;
zone->contours = (FT_UShort*)load->outline.contours + start_contour;
zone->n_points = (FT_UShort)( load->outline.n_points - start_point );
zone->n_contours = (FT_Short) ( load->outline.n_contours -
start_contour );
zone->org = load->extra_points + start_point;
zone->cur = load->outline.points + start_point;
zone->orus = load->extra_points2 + start_point;
zone->tags = (FT_Byte*)load->outline.tags + start_point;
zone->contours = (FT_UShort*)load->outline.contours + start_contour;
zone->first_point = (FT_UShort)start_point;
}
@ -984,7 +1004,8 @@
/* check it */
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;
}
@ -1284,9 +1305,9 @@
/* otherwise, load a composite! */
else if ( loader->n_contours == -1 )
{
FT_UInt start_point;
FT_UInt start_contour;
FT_ULong ins_pos; /* position of composite instructions, if any */
FT_UInt start_point;
FT_UInt start_contour;
FT_ULong ins_pos; /* position of composite instructions, if any */
start_point = gloader->base.outline.n_points;
@ -1316,11 +1337,11 @@
/* this provides additional offsets */
/* for each component's translation */
if ( (error = TT_Vary_Get_Glyph_Deltas(
face,
glyph_index,
&deltas,
gloader->current.num_subglyphs + 4 )) != 0 )
if ( ( error = TT_Vary_Get_Glyph_Deltas(
face,
glyph_index,
&deltas,
gloader->current.num_subglyphs + 4 )) != 0 )
goto Exit;
subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs;
@ -1356,7 +1377,6 @@
/* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
/* `as is' in the glyph slot (the client application will be */
/* responsible for interpreting these data)... */
/* */
if ( loader->load_flags & FT_LOAD_NO_RECURSE )
{
FT_GlyphLoader_Add( gloader );
@ -1370,15 +1390,20 @@
/*********************************************************************/
{
FT_UInt n, num_base_points;
FT_SubGlyph subglyph = 0;
FT_UInt n, num_base_points;
FT_SubGlyph subglyph = 0;
FT_UInt num_points = start_point;
FT_UInt num_subglyphs = gloader->current.num_subglyphs;
FT_UInt num_base_subgs = gloader->base.num_subglyphs;
FT_UInt num_points = start_point;
FT_UInt num_subglyphs = gloader->current.num_subglyphs;
FT_UInt num_base_subgs = gloader->base.num_subglyphs;
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 );
@ -1388,6 +1413,10 @@
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 */
/* value of `gloader.base.subglyphs' can change due to table */
/* reallocations. We thus need to recompute the subglyph */
@ -1422,12 +1451,12 @@
if ( num_points == num_base_points )
continue;
/* gloader->base.outline consists of three part: */
/* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */
/* */
/* (1): exist from the beginning */
/* (2): components that have been loaded so far */
/* (3): the newly loaded component */
/* gloader->base.outline consists of three parts: */
/* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */
/* */
/* (1): exists from the beginning */
/* (2): components that have been loaded so far */
/* (3): the newly loaded component */
TT_Process_Composite_Component( loader, subglyph, start_point,
num_base_points );
}
@ -1451,7 +1480,7 @@
}
else
{
/* invalid composite count ( negative but not -1 ) */
/* invalid composite count (negative but not -1) */
error = TT_Err_Invalid_Outline;
goto Exit;
}
@ -1479,8 +1508,8 @@
static FT_Error
compute_glyph_metrics( TT_Loader loader,
FT_UInt glyph_index )
compute_glyph_metrics( TT_Loader loader,
FT_UInt glyph_index )
{
FT_BBox bbox;
TT_Face face = (TT_Face)loader->face;
@ -1498,8 +1527,8 @@
else
bbox = loader->bbox;
/* get the device-independent horizontal advance. It is scaled later */
/* by the base layer. */
/* get the device-independent horizontal advance; it is scaled later */
/* by the base layer. */
{
FT_Pos advance = loader->linear;
@ -1759,11 +1788,11 @@
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 )
load_flags |= FT_LOAD_NO_HINTING;
/* load default graphics state - if needed */
/* load default graphics state -- if needed */
if ( exec->GS.instruct_control & 2 )
exec->GS = tt_default_graphics_state;
@ -1774,7 +1803,7 @@
#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 */
/* else... */
@ -1852,13 +1881,11 @@
FT_Int32 load_flags )
{
TT_Face face;
FT_Stream stream;
FT_Error error;
TT_LoaderRec loader;
face = (TT_Face)glyph->face;
stream = face->root.stream;
error = TT_Err_Ok;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
@ -1892,7 +1919,7 @@
glyph->num_subglyphs = 0;
glyph->outline.flags = 0;
/* Main loading loop */
/* main loading loop */
error = load_truetype_glyph( &loader, glyph_index, 0 );
if ( !error )
{

View File

@ -621,6 +621,10 @@
exec->pts.n_points = 0;
exec->pts.n_contours = 0;
exec->zp1 = exec->pts;
exec->zp2 = exec->pts;
exec->zp0 = exec->pts;
exec->instruction_trap = FALSE;
return TT_Err_Ok;
@ -1127,17 +1131,8 @@
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 NULL_Vector
#define NULL_Vector (FT_Vector*)&Null_Vector
#if 1
static FT_Int32
@ -6157,6 +6152,13 @@
*/
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 )
orus_base = &CUR.zp0.org[CUR.GS.rp1];
else
@ -6213,7 +6215,7 @@
? TT_MULDIV( org_dist, cur_range, old_range )
: 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.new_top = CUR.args;
@ -6260,6 +6262,7 @@
FT_Vector* orgs; /* original and current coordinate */
FT_Vector* curs; /* arrays */
FT_Vector* orus;
FT_UInt max_points;
} IUP_WorkerRec, *IUP_Worker;
@ -6300,6 +6303,10 @@
if ( p1 > p2 )
return;
if ( BOUNDS( ref1, worker->max_points ) ||
BOUNDS( ref2, worker->max_points ) )
return;
orus1 = worker->orus[ref1].x;
orus2 = worker->orus[ref2].x;
@ -6399,6 +6406,10 @@
FT_UNUSED_ARG;
/* ignore empty outlines */
if ( CUR.pts.n_contours == 0 )
return;
if ( CUR.opcode & 1 )
{
mask = FT_CURVE_TAG_TOUCH_X;
@ -6413,6 +6424,7 @@
V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 );
V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 );
}
V.max_points = CUR.pts.n_points;
contour = 0;
point = 0;

View File

@ -693,21 +693,14 @@
size->GS = tt_default_graphics_state;
error = tt_size_run_prep( size );
if ( !error )
size->cvt_ready = 1;
}
Exit:
return error;
}
#else /* !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 */
#endif /* TT_USE_BYTECODE_INTERPRETER */
/*************************************************************************/

View File

@ -423,14 +423,14 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
tt_size_run_prep( TT_Size size );
FT_LOCAL( FT_Error )
tt_size_ready_bytecode( TT_Size size );
#endif /* TT_USE_BYTECODE_INTERPRETER */
FT_LOCAL( FT_Error )
tt_size_reset( TT_Size size );
FT_LOCAL( FT_Error )
tt_size_ready_bytecode( TT_Size size );
/*************************************************************************/
/* */

View File

@ -1066,12 +1066,26 @@
FT_Face root = (FT_Face)&face->root;
FT_Fixed temp[6];
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] );
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 */
/* 1000 / temp_scale, because temp_scale was already multiplied by */
/* 1000 (in t1_tofixed, from psobjs.c). */
@ -1253,7 +1267,11 @@
}
}
else
{
T1_Skip_PS_Token( parser );
if ( parser->root.error )
return;
}
T1_Skip_Spaces( parser );
}
@ -1379,6 +1397,12 @@
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 */
if ( FT_ALLOC( temp, size ) )
goto Fail;
@ -1548,12 +1572,18 @@
notdef_found = 1;
}
if ( face->type1.private_dict.lenIV >= 0 &&
n < num_glyphs + TABLE_EXTEND )
if ( face->type1.private_dict.lenIV >= 0 &&
n < num_glyphs + TABLE_EXTEND )
{
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 */
if ( FT_ALLOC( temp, size ) )
goto Fail;

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -191,13 +191,11 @@
FT_LOCAL_DEF( void )
T1_Face_Done( T1_Face face )
{
FT_Memory memory;
T1_Font type1 = &face->type1;
if ( face )
{
memory = face->root.memory;
FT_Memory memory = face->root.memory;
T1_Font type1 = &face->type1;
#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
/* release multiple masters information */

View File

@ -4,7 +4,7 @@
/* */
/* 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, */
/* modified, and distributed under the terms of the FreeType project */
@ -55,6 +55,8 @@
error = t42_parse_dict( face, &loader,
parser->base_dict, parser->base_len );
if ( error )
goto Exit;
if ( type1->font_type != 42 )
{

View File

@ -4,7 +4,7 @@
/* */
/* 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, */
/* modified, and distributed under the terms of the FreeType project */
@ -393,7 +393,7 @@
break;
}
/* check whether we've found an entry */
/* check whether we have found an entry */
if ( ft_isdigit( *cur ) || only_immediates )
{
FT_Int charcode;
@ -433,7 +433,11 @@
}
}
else
{
T1_Skip_PS_Token( parser );
if ( parser->root.error )
return;
}
T1_Skip_Spaces( parser );
}
@ -490,7 +494,7 @@
FT_Long n, string_size, old_string_size, real_size;
FT_Byte* string_buf = NULL;
FT_Bool alloc = 0;
FT_Bool allocated = 0;
T42_Load_Status status;
@ -545,7 +549,7 @@
if ( FT_REALLOC( string_buf, old_string_size, string_size ) )
goto Fail;
alloc = 1;
allocated = 1;
parser->root.cursor = cur;
(void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 );
@ -555,6 +559,14 @@
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 );
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. */
if ( string_buf[string_size - 1] == 0 && ( string_size % 2 == 1 ) )
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++ )
{
switch ( status )
@ -654,7 +680,7 @@
parser->root.error = error;
Exit:
if ( alloc )
if ( allocated )
FT_FREE( string_buf );
}

View File

@ -4,8 +4,10 @@
/* */
/* 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. */
/* 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, */
/* modified, and distributed under the terms of the FreeType project */
@ -62,6 +64,80 @@
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[] =
{
#undef FT_STRUCTURE
@ -214,6 +290,8 @@
WinNE_HeaderRec ne_header;
FT_TRACE2(( "MZ signature found\n" ));
if ( FT_STREAM_SEEK( mz_header.lfanew ) ||
FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) )
goto Exit;
@ -229,6 +307,8 @@
FT_ULong font_offset = 0;
FT_TRACE2(( "NE signature found\n" ));
if ( FT_STREAM_SEEK( res_offset ) ||
FT_FRAME_ENTER( ne_header.rname_tab_offset -
ne_header.resource_tab_offset ) )
@ -263,7 +343,16 @@
if ( !font_count || !font_offset )
{
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;
}
@ -282,9 +371,8 @@
FT_FRAME_ENTER( 12 ) )
goto Fail;
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->size_shift = 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;
stream->cursor += 8;
@ -292,6 +380,193 @@
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:
@ -386,13 +661,16 @@
static void
FNT_Face_Done( FNT_Face face )
{
FT_Memory memory = FT_FACE_MEMORY( face );
if ( face )
{
FT_Memory memory = FT_FACE_MEMORY( face );
fnt_font_done( face );
fnt_font_done( face );
FT_FREE( face->root.available_sizes );
face->root.num_fixed_sizes = 0;
FT_FREE( face->root.available_sizes );
face->root.num_fixed_sizes = 0;
}
}
@ -412,12 +690,18 @@
/* try to load font from a DLL */
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 */
FNT_Font font;
if ( face_index > 0 )
{
error = FNT_Err_Bad_Argument;
goto Exit;
}
if ( FT_NEW( face->font ) )
goto Exit;
@ -428,10 +712,11 @@
font->fnt_size = stream->size;
error = fnt_font_load( font, stream );
if ( error )
goto Fail;
}
if ( error )
goto Fail;
/* we now need to fill the root FT_Face fields */
/* with relevant information */
{
@ -533,11 +818,17 @@
root->num_glyphs = font->header.last_char -
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 */
/* NULL byte -- the frame is erroneously one byte too small. */
/* We thus allocate one more byte, setting it explicitly to */
/* zero. */
family_size = font->header.file_size - font->header.face_name_offset;
if ( FT_ALLOC( font->family_name, family_size + 1 ) )
goto Fail;
@ -696,6 +987,13 @@
bitmap->rows = font->header.pixel_height;
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 */
/* can't use ft_glyphslot_set_bitmap */
if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) )

View File

@ -4,8 +4,9 @@
/* */
/* 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. */
/* Copyright 2007 Dmitry Timoshkov for Codeweavers */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
@ -46,6 +47,65 @@ FT_BEGIN_HEADER
} 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_
{
FT_UShort offset;
@ -68,12 +128,12 @@ FT_BEGIN_HEADER
#define WINFNT_MZ_MAGIC 0x5A4D
#define WINFNT_NE_MAGIC 0x454E
#define WINFNT_PE_MAGIC 0x4550
typedef struct FNT_FontRec_
{
FT_ULong offset;
FT_Int size_shift;
FT_WinFNT_HeaderRec header;