summaryrefslogtreecommitdiff
path: root/src/freetype2/truetype
diff options
context:
space:
mode:
Diffstat (limited to 'src/freetype2/truetype')
-rw-r--r--src/freetype2/truetype/truetype.c1
-rw-r--r--src/freetype2/truetype/ttdriver.c145
-rw-r--r--src/freetype2/truetype/ttdriver.h2
-rw-r--r--src/freetype2/truetype/ttgload.c306
-rw-r--r--src/freetype2/truetype/ttgload.h16
-rw-r--r--src/freetype2/truetype/ttgxvar.c99
-rw-r--r--src/freetype2/truetype/ttgxvar.h2
-rw-r--r--src/freetype2/truetype/ttinterp.c129
-rw-r--r--src/freetype2/truetype/ttobjs.c130
-rw-r--r--src/freetype2/truetype/ttobjs.h42
-rw-r--r--src/freetype2/truetype/ttpic.c79
-rw-r--r--src/freetype2/truetype/ttpic.h59
-rw-r--r--src/freetype2/truetype/ttpload.c81
13 files changed, 732 insertions, 359 deletions
diff --git a/src/freetype2/truetype/truetype.c b/src/freetype2/truetype/truetype.c
index b36473a..4bd1209 100644
--- a/src/freetype2/truetype/truetype.c
+++ b/src/freetype2/truetype/truetype.c
@@ -19,6 +19,7 @@
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include <ft2build.h>
+#include "ttpic.c"
#include "ttdriver.c" /* driver interface */
#include "ttpload.c" /* tables loader */
#include "ttgload.c" /* glyph loader */
diff --git a/src/freetype2/truetype/ttdriver.c b/src/freetype2/truetype/ttdriver.c
index c2cf452..dca009a 100644
--- a/src/freetype2/truetype/ttdriver.c
+++ b/src/freetype2/truetype/ttdriver.c
@@ -4,7 +4,7 @@
/* */
/* TrueType font driver implementation (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -20,7 +20,6 @@
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H
-#include FT_TRUETYPE_IDS_H
#include FT_SERVICE_XFREE86_NAME_H
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
@@ -41,6 +40,7 @@
#include "tterrors.h"
+#include "ttpic.h"
/*************************************************************************/
/* */
@@ -125,6 +125,49 @@
#undef PAIR_TAG
+ static FT_Error
+ tt_get_advances( FT_Face ttface,
+ FT_UInt start,
+ FT_UInt count,
+ FT_Int32 flags,
+ FT_Fixed *advances )
+ {
+ FT_UInt nn;
+ TT_Face face = (TT_Face) ttface;
+ FT_Bool check = FT_BOOL(
+ !( flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) );
+
+
+ /* XXX: TODO: check for sbits */
+
+ if ( flags & FT_LOAD_VERTICAL_LAYOUT )
+ {
+ for ( nn = 0; nn < count; nn++ )
+ {
+ FT_Short tsb;
+ FT_UShort ah;
+
+
+ TT_Get_VMetrics( face, start + nn, check, &tsb, &ah );
+ advances[nn] = ah;
+ }
+ }
+ else
+ {
+ for ( nn = 0; nn < count; nn++ )
+ {
+ FT_Short lsb;
+ FT_UShort aw;
+
+
+ TT_Get_HMetrics( face, start + nn, check, &lsb, &aw );
+ advances[nn] = aw;
+ }
+ }
+
+ return TT_Err_Ok;
+ }
+
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
@@ -229,7 +272,7 @@
/* glyph_index :: The index of the glyph in the font file. */
/* */
/* load_flags :: A flag indicating what to load for this glyph. The */
- /* FTLOAD_??? constants can be used to control the */
+ /* FT_LOAD_XXX constants can be used to control the */
/* glyph loading process (e.g., whether the outline */
/* should be scaled, whether to load bitmaps or not, */
/* whether to hint the outline, etc). */
@@ -258,11 +301,24 @@
if ( !face || glyph_index >= (FT_UInt)face->num_glyphs )
return TT_Err_Invalid_Argument;
+ if ( load_flags & FT_LOAD_NO_HINTING )
+ {
+ /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */
+ /* are necessary to disable hinting for tricky fonts */
+
+ if ( FT_IS_TRICKY( face ) )
+ load_flags &= ~FT_LOAD_NO_HINTING;
+
+ if ( load_flags & FT_LOAD_NO_AUTOHINT )
+ load_flags |= FT_LOAD_NO_HINTING;
+ }
+
if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) )
{
- load_flags |= FT_LOAD_NO_HINTING |
- FT_LOAD_NO_BITMAP |
- FT_LOAD_NO_SCALE;
+ load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE;
+
+ if ( !FT_IS_TRICKY( face ) )
+ load_flags |= FT_LOAD_NO_HINTING;
}
/* now load the glyph outline if necessary */
@@ -288,14 +344,13 @@
/*************************************************************************/
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- static const FT_Service_MultiMastersRec tt_service_gx_multi_masters =
- {
+ FT_DEFINE_SERVICE_MULTIMASTERSREC(tt_service_gx_multi_masters,
(FT_Get_MM_Func) NULL,
(FT_Set_MM_Design_Func) NULL,
(FT_Set_MM_Blend_Func) TT_Set_MM_Blend,
(FT_Get_MM_Var_Func) TT_Get_MM_Var,
(FT_Set_Var_Design_Func)TT_Set_Var_Design
- };
+ )
#endif
static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine =
@@ -315,33 +370,36 @@
#endif /* TT_USE_BYTECODE_INTERPRETER */
};
- static const FT_Service_TTGlyfRec tt_service_truetype_glyf =
- {
+ FT_DEFINE_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 },
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- { FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters },
+ FT_DEFINE_SERVICEDESCREC4(tt_services,
+ FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE,
+ FT_SERVICE_ID_MULTI_MASTERS, &FT_TT_SERVICE_GX_MULTI_MASTERS_GET,
+ FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,
+ FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET
+ )
+#else
+ FT_DEFINE_SERVICEDESCREC3(tt_services,
+ FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE,
+ FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,
+ FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET
+ )
#endif
- { FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine },
- { FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf },
- { NULL, NULL }
- };
-
FT_CALLBACK_DEF( FT_Module_Interface )
tt_get_interface( FT_Module driver, /* TT_Driver */
const char* tt_interface )
{
+ FT_Library library = driver->library;
FT_Module_Interface result;
FT_Module sfntd;
SFNT_Service sfnt;
+ FT_UNUSED(library);
-
- result = ft_service_list_lookup( tt_services, tt_interface );
+ result = ft_service_list_lookup( FT_TT_SERVICES_GET, tt_interface );
if ( result != NULL )
return result;
@@ -360,18 +418,25 @@
/* The FT_DriverInterface structure is defined in ftdriver.h. */
- FT_CALLBACK_TABLE_DEF
- const FT_Driver_ClassRec tt_driver_class =
- {
- {
- FT_MODULE_FONT_DRIVER |
- FT_MODULE_DRIVER_SCALABLE |
#ifdef TT_USE_BYTECODE_INTERPRETER
- FT_MODULE_DRIVER_HAS_HINTER,
+#define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER
+#else
+#define TT_HINTER_FLAG 0
+#endif
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+#define TT_SIZE_SELECT tt_size_select
#else
- 0,
+#define TT_SIZE_SELECT 0
#endif
+ FT_DEFINE_DRIVER(tt_driver_class,
+
+
+ FT_MODULE_FONT_DRIVER |
+ FT_MODULE_DRIVER_SCALABLE |
+ TT_HINTER_FLAG,
+
sizeof ( TT_DriverRec ),
"truetype", /* driver name */
@@ -383,7 +448,6 @@
tt_driver_init,
tt_driver_done,
tt_get_interface,
- },
sizeof ( TT_FaceRec ),
sizeof ( TT_SizeRec ),
@@ -396,23 +460,18 @@
tt_slot_init,
0, /* FT_Slot_DoneFunc */
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
- ft_stub_set_char_sizes,
- ft_stub_set_pixel_sizes,
-#endif
+ ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+ ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+
Load_Glyph,
tt_get_kerning,
0, /* FT_Face_AttachFunc */
- 0, /* FT_Face_GetAdvancesFunc */
+ tt_get_advances,
tt_size_request,
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
- tt_size_select
-#else
- 0 /* FT_Size_SelectFunc */
-#endif
- };
+ TT_SIZE_SELECT
+ )
/* END */
diff --git a/src/freetype2/truetype/ttdriver.h b/src/freetype2/truetype/ttdriver.h
index f6f26e4..aae00f2 100644
--- a/src/freetype2/truetype/ttdriver.h
+++ b/src/freetype2/truetype/ttdriver.h
@@ -27,7 +27,7 @@
FT_BEGIN_HEADER
- FT_EXPORT_VAR( const FT_Driver_ClassRec ) tt_driver_class;
+ FT_DECLARE_DRIVER( tt_driver_class )
FT_END_HEADER
diff --git a/src/freetype2/truetype/ttgload.c b/src/freetype2/truetype/ttgload.c
index ae476a4..28ddb99 100644
--- a/src/freetype2/truetype/ttgload.c
+++ b/src/freetype2/truetype/ttgload.c
@@ -4,7 +4,7 @@
/* */
/* TrueType Glyph Loader (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -69,12 +69,12 @@
/* `check' is true, take care of monospaced fonts by returning the */
/* advance width maximum. */
/* */
- static void
- Get_HMetrics( TT_Face face,
- FT_UInt idx,
- FT_Bool check,
- FT_Short* lsb,
- FT_UShort* aw )
+ FT_LOCAL_DEF(void)
+ TT_Get_HMetrics( TT_Face face,
+ FT_UInt idx,
+ FT_Bool check,
+ FT_Short* lsb,
+ FT_UShort* aw )
{
( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );
@@ -96,12 +96,12 @@
/* The monospace `check' is probably not meaningful here, but we leave */
/* it in for a consistent interface. */
/* */
- static void
- Get_VMetrics( TT_Face face,
- FT_UInt idx,
- FT_Bool check,
- FT_Short* tsb,
- FT_UShort* ah )
+ FT_LOCAL_DEF(void)
+ TT_Get_VMetrics( TT_Face face,
+ FT_UInt idx,
+ FT_Bool check,
+ FT_Short* tsb,
+ FT_UShort* ah )
{
FT_UNUSED( check );
@@ -267,7 +267,11 @@
if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit )
goto Invalid_Outline;
- cont[0] = prev_cont = FT_NEXT_USHORT( p );
+ prev_cont = FT_NEXT_USHORT( p );
+
+ if ( n_contours > 0 )
+ cont[0] = prev_cont;
+
for ( cont++; cont < cont_limit; cont++ )
{
cont[0] = FT_NEXT_USHORT( p );
@@ -313,7 +317,7 @@
if ( n_ins > face->max_profile.maxSizeOfInstructions )
{
- FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions (%d)\n",
+ FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n",
n_ins ));
error = TT_Err_Too_Many_Hints;
goto Fail;
@@ -321,7 +325,7 @@
if ( ( limit - p ) < n_ins )
{
- FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" ));
+ FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
error = TT_Err_Too_Many_Hints;
goto Fail;
}
@@ -378,8 +382,8 @@
for ( ; vec < vec_limit; vec++, flag++ )
{
- FT_Pos y = 0;
- FT_Byte f = *flag;
+ FT_Pos y = 0;
+ FT_Byte f = *flag;
if ( f & 2 )
@@ -401,7 +405,8 @@
x += y;
vec->x = x;
- *flag = f & ~( 2 | 16 );
+ /* the cast is for stupid compilers */
+ *flag = (FT_Byte)( f & ~( 2 | 16 ) );
}
/* reading the Y coordinates */
@@ -413,8 +418,8 @@
for ( ; vec < vec_limit; vec++, flag++ )
{
- FT_Pos y = 0;
- FT_Byte f = *flag;
+ FT_Pos y = 0;
+ FT_Byte f = *flag;
if ( f & 4 )
@@ -436,7 +441,8 @@
x += y;
vec->y = x;
- *flag = f & FT_CURVE_TAG_ON;
+ /* the cast is for stupid compilers */
+ *flag = (FT_Byte)( f & FT_CURVE_TAG_ON );
}
outline->n_points = (FT_UShort)n_points;
@@ -553,10 +559,10 @@
FT_Stream stream = loader->stream;
- /* we must undo the FT_FRAME_ENTER in order to point to the */
- /* composite instructions, if we find some. */
- /* we will process them later... */
- /* */
+ /* we must undo the FT_FRAME_ENTER in order to point */
+ /* to the composite instructions, if we find some. */
+ /* We will process them later. */
+ /* */
loader->ins_pos = (FT_ULong)( FT_STREAM_POS() +
p - limit );
}
@@ -627,7 +633,13 @@
#ifdef TT_USE_BYTECODE_INTERPRETER
- n_ins = loader->glyph->control_len;
+ if ( loader->glyph->control_len > 0xFFFFL )
+ {
+ FT_TRACE1(( "TT_Hint_Glyph: too long instructions " ));
+ FT_TRACE1(( "(0x%lx byte) is truncated\n",
+ loader->glyph->control_len ));
+ }
+ n_ins = (FT_UInt)( loader->glyph->control_len );
#endif
origin = zone->cur[zone->n_points - 4].x;
@@ -639,6 +651,26 @@
/* save original point position in org */
if ( n_ins > 0 )
FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );
+
+ /* Reset graphics state. */
+ loader->exec->GS = ((TT_Size)loader->size)->GS;
+
+ /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */
+ /* completely refer to the (already) hinted subglyphs. */
+ if ( is_composite )
+ {
+ loader->exec->metrics.x_scale = 1 << 16;
+ loader->exec->metrics.y_scale = 1 << 16;
+
+ FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points );
+ }
+ else
+ {
+ loader->exec->metrics.x_scale =
+ ((TT_Size)loader->size)->metrics.x_scale;
+ loader->exec->metrics.y_scale =
+ ((TT_Size)loader->size)->metrics.y_scale;
+ }
#endif
/* round pp2 and pp4 */
@@ -654,6 +686,9 @@
FT_Bool debug;
FT_Error error;
+ FT_GlyphLoader gloader = loader->gloader;
+ FT_Outline current_outline = gloader->current.outline;
+
error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
loader->exec->glyphIns, n_ins );
@@ -669,6 +704,10 @@
error = TT_Run_Context( loader->exec, debug );
if ( error && loader->exec->pedantic_hinting )
return error;
+
+ /* store drop-out mode in bits 5-7; set bit 2 also as a marker */
+ current_outline.tags[0] |=
+ ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
}
#endif
@@ -702,7 +741,7 @@
FT_GlyphLoader gloader = loader->gloader;
FT_Error error = TT_Err_Ok;
FT_Outline* outline;
- FT_UInt n_points;
+ FT_Int n_points;
outline = &gloader->current.outline;
@@ -729,7 +768,7 @@
/* Deltas apply to the unscaled data. */
FT_Vector* deltas;
FT_Memory memory = loader->face->memory;
- FT_UInt i;
+ FT_Int i;
error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face),
@@ -903,15 +942,15 @@
/* This algorithm is a guess and works much better than the above. */
/* */
FT_Fixed mac_xscale = FT_SqrtFixed(
- FT_MulFix( subglyph->transform.xx,
- subglyph->transform.xx ) +
- FT_MulFix( subglyph->transform.xy,
- subglyph->transform.xy ) );
+ (FT_Int32)FT_MulFix( subglyph->transform.xx,
+ subglyph->transform.xx ) +
+ (FT_Int32)FT_MulFix( subglyph->transform.xy,
+ subglyph->transform.xy ) );
FT_Fixed mac_yscale = FT_SqrtFixed(
- FT_MulFix( subglyph->transform.yy,
- subglyph->transform.yy ) +
- FT_MulFix( subglyph->transform.yx,
- subglyph->transform.yx ) );
+ (FT_Int32)FT_MulFix( subglyph->transform.yy,
+ subglyph->transform.yy ) +
+ (FT_Int32)FT_MulFix( subglyph->transform.yx,
+ subglyph->transform.yx ) );
x = FT_MulFix( x, mac_xscale );
@@ -1004,7 +1043,7 @@
/* check it */
if ( n_ins > ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions )
{
- FT_TRACE0(( "TT_Process_Composite_Glyph: Too many instructions (%d)\n",
+ FT_TRACE0(( "TT_Process_Composite_Glyph: too many instructions (%d)\n",
n_ins ));
return TT_Err_Too_Many_Hints;
@@ -1027,8 +1066,7 @@
/* Some points are likely touched during execution of */
/* instructions on components. So let's untouch them. */
for ( i = start_point; i < loader->zone.n_points; i++ )
- loader->zone.tags[i] &= ~( FT_CURVE_TAG_TOUCH_X |
- FT_CURVE_TAG_TOUCH_Y );
+ loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;
loader->zone.n_points += 4;
@@ -1084,7 +1122,10 @@
#endif
- if ( recurse_count > face->max_profile.maxComponentDepth )
+ /* some fonts have an incorrect value of `maxComponentDepth', */
+ /* thus we allow depth 1 to catch the majority of them */
+ if ( recurse_count > 1 &&
+ recurse_count > face->max_profile.maxComponentDepth )
{
error = TT_Err_Invalid_Composite;
goto Exit;
@@ -1116,16 +1157,16 @@
FT_UShort advance_width = 0, advance_height = 0;
- Get_HMetrics( face, glyph_index,
- (FT_Bool)!( loader->load_flags &
- FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
- &left_bearing,
- &advance_width );
- Get_VMetrics( face, glyph_index,
- (FT_Bool)!( loader->load_flags &
- FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
- &top_bearing,
- &advance_height );
+ TT_Get_HMetrics( face, glyph_index,
+ (FT_Bool)!( loader->load_flags &
+ FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
+ &left_bearing,
+ &advance_width );
+ TT_Get_VMetrics( face, glyph_index,
+ (FT_Bool)!( loader->load_flags &
+ FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
+ &top_bearing,
+ &advance_height );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
@@ -1214,10 +1255,31 @@
offset = tt_face_get_location( face, glyph_index,
(FT_UInt*)&loader->byte_len );
- if ( loader->byte_len == 0 )
+ if ( loader->byte_len > 0 )
+ {
+ if ( !loader->glyf_offset )
+ {
+ FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" ));
+ error = TT_Err_Invalid_Table;
+ goto Exit;
+ }
+
+ error = face->access_glyph_frame( loader, glyph_index,
+ loader->glyf_offset + offset,
+ loader->byte_len );
+ if ( error )
+ goto Exit;
+
+ opened_frame = 1;
+
+ /* read first glyph header */
+ error = face->read_glyph_header( loader );
+ if ( error )
+ goto Exit;
+ }
+
+ if ( loader->byte_len == 0 || loader->n_contours == 0 )
{
- /* as described by Frederic Loyer, these are spaces or */
- /* the unknown glyph. */
loader->bbox.xMin = 0;
loader->bbox.xMax = 0;
loader->bbox.yMin = 0;
@@ -1260,19 +1322,6 @@
goto Exit;
}
- error = face->access_glyph_frame( loader, glyph_index,
- loader->glyf_offset + offset,
- loader->byte_len );
- if ( error )
- goto Exit;
-
- opened_frame = 1;
-
- /* read first glyph header */
- error = face->read_glyph_header( loader );
- if ( error )
- goto Exit;
-
TT_LOADER_SET_PP( loader );
/***********************************************************************/
@@ -1281,7 +1330,7 @@
/* if it is a simple glyph, load it */
- if ( loader->n_contours >= 0 )
+ if ( loader->n_contours > 0 )
{
error = face->read_simple_glyph( loader );
if ( error )
@@ -1351,8 +1400,11 @@
{
if ( subglyph->flags & ARGS_ARE_XY_VALUES )
{
- subglyph->arg1 += deltas[i].x;
- subglyph->arg2 += deltas[i].y;
+ /* XXX: overflow check for subglyph->{arg1,arg2}. */
+ /* deltas[i].{x,y} must be within signed 16-bit, */
+ /* but the restriction of summed delta is not clear */
+ subglyph->arg1 += (FT_Int16)deltas[i].x;
+ subglyph->arg2 += (FT_Int16)deltas[i].y;
}
}
@@ -1390,21 +1442,16 @@
/*********************************************************************/
{
- 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 n, num_base_points;
+ FT_SubGlyph subglyph = 0;
- FT_Stream old_stream = loader->stream;
+ FT_UInt num_points = start_point;
+ FT_UInt num_subglyphs = gloader->current.num_subglyphs;
+ FT_UInt num_base_subgs = gloader->base.num_subglyphs;
- TT_GraphicsState saved_GS;
+ FT_Stream old_stream = loader->stream;
- if ( loader->exec )
- saved_GS = loader->exec->GS;
-
FT_GlyphLoader_Add( gloader );
/* read each subglyph independently */
@@ -1413,10 +1460,6 @@
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 */
@@ -1551,17 +1594,35 @@
glyph->metrics.horiBearingY = bbox.yMax;
glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
- /* Now take care of vertical metrics. In the case where there is */
- /* no vertical information within the font (relatively common), make */
- /* up some metrics by `hand'... */
+ /* adjust advance width to the value contained in the hdmx table */
+ if ( !face->postscript.isFixedPitch &&
+ IS_HINTED( loader->load_flags ) )
+ {
+ FT_Byte* widthp;
+
+
+ widthp = tt_face_get_device_metrics( face,
+ size->root.metrics.x_ppem,
+ glyph_index );
+
+ if ( widthp )
+ glyph->metrics.horiAdvance = *widthp << 6;
+ }
+
+ /* set glyph dimensions */
+ glyph->metrics.width = bbox.xMax - bbox.xMin;
+ glyph->metrics.height = bbox.yMax - bbox.yMin;
+ /* Now take care of vertical metrics. In the case where there is */
+ /* no vertical information within the font (relatively common), */
+ /* create some metrics manually */
{
FT_Pos top; /* scaled vertical top side bearing */
FT_Pos advance; /* scaled vertical advance height */
/* Get the unscaled top bearing and advance height. */
- if ( face->vertical_info &&
+ if ( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 )
{
top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
@@ -1643,30 +1704,12 @@
/* XXX: for now, we have no better algorithm for the lsb, but it */
/* should work fine. */
/* */
- glyph->metrics.vertBearingX = ( bbox.xMin - bbox.xMax ) / 2;
+ glyph->metrics.vertBearingX = glyph->metrics.horiBearingX -
+ glyph->metrics.horiAdvance / 2;
glyph->metrics.vertBearingY = top;
glyph->metrics.vertAdvance = advance;
}
- /* adjust advance width to the value contained in the hdmx table */
- if ( !face->postscript.isFixedPitch &&
- IS_HINTED( loader->load_flags ) )
- {
- FT_Byte* widthp;
-
-
- widthp = tt_face_get_device_metrics( face,
- size->root.metrics.x_ppem,
- glyph_index );
-
- if ( widthp )
- glyph->metrics.horiAdvance = *widthp << 6;
- }
-
- /* set glyph dimensions */
- glyph->metrics.width = bbox.xMax - bbox.xMin;
- glyph->metrics.height = bbox.yMax - bbox.yMin;
-
return 0;
}
@@ -1819,12 +1862,15 @@
FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 );
- if ( error )
+ if ( error == TT_Err_Table_Missing )
+ loader->glyf_offset = 0;
+ else if ( error )
{
- FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" ));
+ FT_ERROR(( "tt_loader_init: could not access glyph table\n" ));
return error;
}
- loader->glyf_offset = FT_STREAM_POS();
+ else
+ loader->glyf_offset = FT_STREAM_POS();
}
/* get face's glyph loader */
@@ -1836,7 +1882,7 @@
loader->gloader = gloader;
}
- loader->load_flags = load_flags;
+ loader->load_flags = load_flags;
loader->face = (FT_Face)face;
loader->size = (FT_Size)size;
@@ -1939,6 +1985,40 @@
FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 );
}
+#ifdef TT_USE_BYTECODE_INTERPRETER
+
+ if ( IS_HINTED( load_flags ) )
+ {
+ if ( loader.exec->GS.scan_control )
+ {
+ /* convert scan conversion mode to FT_OUTLINE_XXX flags */
+ switch ( loader.exec->GS.scan_type )
+ {
+ case 0: /* simple drop-outs including stubs */
+ glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS;
+ break;
+ case 1: /* simple drop-outs excluding stubs */
+ /* nothing; it's the default rendering mode */
+ break;
+ case 4: /* smart drop-outs including stubs */
+ glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS |
+ FT_OUTLINE_INCLUDE_STUBS;
+ break;
+ case 5: /* smart drop-outs excluding stubs */
+ glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS;
+ break;
+
+ default: /* no drop-out control */
+ glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
+ break;
+ }
+ }
+ else
+ glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
+ }
+
+#endif /* TT_USE_BYTECODE_INTERPRETER */
+
compute_glyph_metrics( &loader, glyph_index );
}
diff --git a/src/freetype2/truetype/ttgload.h b/src/freetype2/truetype/ttgload.h
index b261e97..958d67d 100644
--- a/src/freetype2/truetype/ttgload.h
+++ b/src/freetype2/truetype/ttgload.h
@@ -4,7 +4,7 @@
/* */
/* TrueType Glyph Loader (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -34,6 +34,20 @@ FT_BEGIN_HEADER
FT_LOCAL( void )
TT_Init_Glyph_Loading( TT_Face face );
+ FT_LOCAL( void )
+ TT_Get_HMetrics( TT_Face face,
+ FT_UInt idx,
+ FT_Bool check,
+ FT_Short* lsb,
+ FT_UShort* aw );
+
+ FT_LOCAL( void )
+ TT_Get_VMetrics( TT_Face face,
+ FT_UInt idx,
+ FT_Bool check,
+ FT_Short* tsb,
+ FT_UShort* ah );
+
FT_LOCAL( FT_Error )
TT_Load_Glyph( TT_Size size,
TT_GlyphSlot glyph,
diff --git a/src/freetype2/truetype/ttgxvar.c b/src/freetype2/truetype/ttgxvar.c
index 0dc2c4f..1456a8c 100644
--- a/src/freetype2/truetype/ttgxvar.c
+++ b/src/freetype2/truetype/ttgxvar.c
@@ -4,7 +4,7 @@
/* */
/* TrueType GX Font Variation loader */
/* */
-/* Copyright 2004, 2005, 2006, 2007 by */
+/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,30 +16,31 @@
/***************************************************************************/
-/***************************************************************************/
-/* */
-/* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */
-/* */
-/* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */
-/* */
-/* The documentation for `fvar' is inconsistent. At one point it says */
-/* that `countSizePairs' should be 3, at another point 2. It should be 2. */
-/* */
-/* The documentation for `gvar' is not intelligible; `cvar' refers you to */
-/* `gvar' and is thus also incomprehensible. */
-/* */
-/* The documentation for `avar' appears correct, but Apple has no fonts */
-/* with an `avar' table, so it is hard to test. */
-/* */
-/* Many thanks to John Jenkins (at Apple) in figuring this out. */
-/* */
-/* */
-/* Apple's `kern' table has some references to tuple indices, but as there */
-/* is no indication where these indices are defined, nor how to */
-/* interpolate the kerning values (different tuples have different */
-/* classes) this issue is ignored. */
-/* */
-/***************************************************************************/
+ /*************************************************************************/
+ /* */
+ /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */
+ /* */
+ /* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */
+ /* */
+ /* The documentation for `fvar' is inconsistent. At one point it says */
+ /* that `countSizePairs' should be 3, at another point 2. It should */
+ /* be 2. */
+ /* */
+ /* The documentation for `gvar' is not intelligible; `cvar' refers you */
+ /* to `gvar' and is thus also incomprehensible. */
+ /* */
+ /* The documentation for `avar' appears correct, but Apple has no fonts */
+ /* with an `avar' table, so it is hard to test. */
+ /* */
+ /* Many thanks to John Jenkins (at Apple) in figuring this out. */
+ /* */
+ /* */
+ /* Apple's `kern' table has some references to tuple indices, but as */
+ /* there is no indication where these indices are defined, nor how to */
+ /* interpolate the kerning values (different tuples have different */
+ /* classes) this issue is ignored. */
+ /* */
+ /*************************************************************************/
#include <ft2build.h>
@@ -47,11 +48,9 @@
#include FT_CONFIG_CONFIG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H
-#include FT_TRUETYPE_IDS_H
#include FT_TRUETYPE_TAGS_H
#include FT_MULTIPLE_MASTERS_H
-#include "ttdriver.h"
#include "ttpload.h"
#include "ttgxvar.h"
@@ -158,6 +157,9 @@
runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK;
first = points[i++] = FT_GET_USHORT();
+ if ( runcnt < 1 )
+ goto Exit;
+
/* first point not included in runcount */
for ( j = 0; j < runcnt; ++j )
points[i++] = (FT_UShort)( first += FT_GET_USHORT() );
@@ -166,11 +168,15 @@
{
first = points[i++] = FT_GET_BYTE();
+ if ( runcnt < 1 )
+ goto Exit;
+
for ( j = 0; j < runcnt; ++j )
points[i++] = (FT_UShort)( first += FT_GET_BYTE() );
}
}
+ Exit:
return points;
}
@@ -205,12 +211,12 @@
/* */
static FT_Short*
ft_var_readpackeddeltas( FT_Stream stream,
- FT_Int delta_cnt )
+ FT_Offset delta_cnt )
{
FT_Short *deltas;
FT_Int runcnt;
- FT_Int i;
- FT_Int j;
+ FT_Offset i;
+ FT_Offset j;
FT_Memory memory = stream->memory;
FT_Error error = TT_Err_Ok;
@@ -337,7 +343,8 @@
}
- typedef struct GX_GVar_Head_ {
+ typedef struct GX_GVar_Head_
+ {
FT_Long version;
FT_UShort axisCount;
FT_UShort globalCoordCount;
@@ -564,7 +571,8 @@
/*************************************************************************/
- typedef struct GX_FVar_Head_ {
+ typedef struct GX_FVar_Head_
+ {
FT_Long version;
FT_UShort offsetToData;
FT_UShort countSizePairs;
@@ -576,7 +584,8 @@
} GX_FVar_Head;
- typedef struct fvar_axis {
+ typedef struct fvar_axis_
+ {
FT_ULong axisTag;
FT_ULong minValue;
FT_ULong defaultValue;
@@ -754,7 +763,7 @@
}
ns = mmvar->namedstyle;
- for ( i = 0; i < fvar_head.instanceCount; ++i )
+ for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns )
{
if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) )
goto Exit;
@@ -902,13 +911,15 @@
}
else
{
- for ( i = 0;
- i < num_coords && blend->normalizedcoords[i] == coords[i];
- ++i );
- if ( i == num_coords )
- manageCvt = mcvt_retain;
- else
+ manageCvt = mcvt_retain;
+ for ( i = 0; i < num_coords; ++i )
+ {
+ if ( blend->normalizedcoords[i] != coords[i] )
+ {
manageCvt = mcvt_load;
+ break;
+ }
+ }
/* If we don't change the blend coords then we don't need to do */
/* anything to the cvt table. It will be correct. Otherwise we */
@@ -1127,7 +1138,7 @@
if ( blend == NULL )
{
- FT_TRACE2(( "no blend specified!\n" ));
+ FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" ));
error = TT_Err_Ok;
goto Exit;
@@ -1135,7 +1146,7 @@
if ( face->cvt == NULL )
{
- FT_TRACE2(( "no `cvt ' table!\n" ));
+ FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" ));
error = TT_Err_Ok;
goto Exit;
@@ -1144,7 +1155,7 @@
error = face->goto_table( face, TTAG_cvar, stream, &table_len );
if ( error )
{
- FT_TRACE2(( "is missing!\n" ));
+ FT_TRACE2(( "is missing\n" ));
error = TT_Err_Ok;
goto Exit;
@@ -1159,7 +1170,7 @@
table_start = FT_Stream_FTell( stream );
if ( FT_GET_LONG() != 0x00010000L )
{
- FT_TRACE2(( "bad table version!\n" ));
+ FT_TRACE2(( "bad table version\n" ));
error = TT_Err_Ok;
goto FExit;
diff --git a/src/freetype2/truetype/ttgxvar.h b/src/freetype2/truetype/ttgxvar.h
index 706cb4d..82dfc44 100644
--- a/src/freetype2/truetype/ttgxvar.h
+++ b/src/freetype2/truetype/ttgxvar.h
@@ -84,7 +84,7 @@ FT_BEGIN_HEADER
FT_Fixed* normalizedcoords;
FT_MM_Var* mmvar;
- FT_Int mmvar_len;
+ FT_Offset mmvar_len;
FT_Bool avar_checked;
GX_AVarSegment avar_segment;
diff --git a/src/freetype2/truetype/ttinterp.c b/src/freetype2/truetype/ttinterp.c
index 85c8529..13aa9a2 100644
--- a/src/freetype2/truetype/ttinterp.c
+++ b/src/freetype2/truetype/ttinterp.c
@@ -4,7 +4,7 @@
/* */
/* TrueType bytecode interpreter (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -693,7 +693,7 @@
/* exec :: A handle to the target execution context. */
/* */
/* <Return> */
- /* TrueTyoe error code. 0 means success. */
+ /* TrueType error code. 0 means success. */
/* */
/* <Note> */
/* Only the glyph loader and debugger should call this function. */
@@ -748,6 +748,13 @@
}
+ /* The default value for `scan_control' is documented as FALSE in the */
+ /* TrueType specification. This is confusing since it implies a */
+ /* Boolean value. However, this is not the case, thus both the */
+ /* default values of our `scan_type' and `scan_control' fields (which */
+ /* the documentation's `scan_control' variable is split into) are */
+ /* zero. */
+
const TT_GraphicsState tt_default_graphics_state =
{
0, 0, 0,
@@ -761,7 +768,7 @@
1, 64, 1,
TRUE, 68, 0, 0, 9, 3,
- 0, FALSE, 2, 1, 1, 1
+ 0, FALSE, 0, 1, 1, 1
};
@@ -784,9 +791,9 @@
/* allocate object */
if ( FT_NEW( exec ) )
- goto Exit;
+ goto Fail;
- /* initialize it */
+ /* initialize it; in case of error this deallocates `exec' too */
error = Init_Context( exec, memory );
if ( error )
goto Fail;
@@ -795,13 +802,10 @@
driver->context = exec;
}
- Exit:
return driver->context;
Fail:
- FT_FREE( exec );
-
- return 0;
+ return NULL;
}
@@ -2190,7 +2194,7 @@
FT_ASSERT( !CUR.face->unpatented_hinting );
#endif
- return TT_DotFix14( dx, dy,
+ return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
CUR.GS.projVector.x,
CUR.GS.projVector.y );
}
@@ -2216,7 +2220,7 @@
Dual_Project( EXEC_OP_ FT_Pos dx,
FT_Pos dy )
{
- return TT_DotFix14( dx, dy,
+ return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
CUR.GS.dualVector.x,
CUR.GS.dualVector.y );
}
@@ -4286,13 +4290,21 @@
CUR.numFDefs++;
}
+ /* Although FDEF takes unsigned 32-bit integer, */
+ /* func # must be within unsigned 16-bit integer */
+ if ( n > 0xFFFFU )
+ {
+ CUR.error = TT_Err_Too_Many_Function_Defs;
+ return;
+ }
+
rec->range = CUR.curRange;
- rec->opc = n;
+ rec->opc = (FT_UInt16)n;
rec->start = CUR.IP + 1;
rec->active = TRUE;
if ( n > CUR.maxFunc )
- CUR.maxFunc = n;
+ CUR.maxFunc = (FT_UInt16)n;
/* Now skip the whole function definition. */
/* We don't allow nested IDEFS & FDEFs. */
@@ -4549,13 +4561,20 @@
CUR.numIDefs++;
}
- def->opc = args[0];
+ /* opcode must be unsigned 8-bit integer */
+ if ( 0 > args[0] || args[0] > 0x00FF )
+ {
+ CUR.error = TT_Err_Too_Many_Instruction_Defs;
+ return;
+ }
+
+ def->opc = (FT_Byte)args[0];
def->start = CUR.IP+1;
def->range = CUR.curRange;
def->active = TRUE;
if ( (FT_ULong)args[0] > CUR.maxIns )
- CUR.maxIns = args[0];
+ CUR.maxIns = (FT_Byte)args[0];
/* Now skip the whole function definition. */
/* We don't allow nested IDEFs & FDEFs. */
@@ -4821,7 +4840,28 @@
if ( CUR.opcode & 1 )
D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K );
else
- D = CUR_Func_dualproj( CUR.zp0.org + L, CUR.zp1.org + K );
+ {
+ FT_Vector* vec1 = CUR.zp0.orus + L;
+ FT_Vector* vec2 = CUR.zp1.orus + K;
+
+
+ if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
+ {
+ /* this should be faster */
+ D = CUR_Func_dualproj( vec1, vec2 );
+ D = TT_MULFIX( D, CUR.metrics.x_scale );
+ }
+ else
+ {
+ FT_Vector vec;
+
+
+ vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale );
+ vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale );
+
+ D = CUR_fast_dualproj( &vec );
+ }
+ }
}
args[0] = D;
@@ -5071,12 +5111,8 @@
return;
}
- A *= 64;
-
-#if 0
- if ( ( args[0] & 0x100 ) != 0 && CUR.metrics.pointSize <= A )
+ if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A )
CUR.GS.scan_control = TRUE;
-#endif
if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated )
CUR.GS.scan_control = TRUE;
@@ -5084,10 +5120,8 @@
if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched )
CUR.GS.scan_control = TRUE;
-#if 0
- if ( ( args[0] & 0x800 ) != 0 && CUR.metrics.pointSize > A )
+ if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A )
CUR.GS.scan_control = FALSE;
-#endif
if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated )
CUR.GS.scan_control = FALSE;
@@ -5106,16 +5140,8 @@
static void
Ins_SCANTYPE( INS_ARG )
{
- /* for compatibility with future enhancements, */
- /* we must ignore new modes */
-
- if ( args[0] >= 0 && args[0] <= 5 )
- {
- if ( args[0] == 3 )
- args[0] = 2;
-
+ if ( args[0] >= 0 )
CUR.GS.scan_type = (FT_Int)args[0];
- }
}
@@ -5428,7 +5454,7 @@
/* XXX: this is probably wrong... at least it prevents memory */
/* corruption when zp2 is the twilight zone */
- if ( last_point > CUR.zp2.n_points )
+ if ( BOUNDS( last_point, CUR.zp2.n_points ) )
{
if ( CUR.zp2.n_points > 0 )
last_point = (FT_UShort)(CUR.zp2.n_points - 1);
@@ -5516,20 +5542,20 @@
{
if ( CUR.GS.both_x_axis )
{
- dx = TT_MulFix14( args[0], 0x4000 );
+ dx = TT_MulFix14( (FT_UInt32)args[0], 0x4000 );
dy = 0;
}
else
{
dx = 0;
- dy = TT_MulFix14( args[0], 0x4000 );
+ dy = TT_MulFix14( (FT_UInt32)args[0], 0x4000 );
}
}
else
#endif
{
- dx = TT_MulFix14( args[0], CUR.GS.freeVector.x );
- dy = TT_MulFix14( args[0], CUR.GS.freeVector.y );
+ dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x );
+ dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y );
}
while ( CUR.GS.loop > 0 )
@@ -5695,8 +5721,8 @@
if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */
{
- CUR.zp0.org[point].x = TT_MulFix14( distance, CUR.GS.freeVector.x );
- CUR.zp0.org[point].y = TT_MulFix14( distance, CUR.GS.freeVector.y ),
+ CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.x );
+ CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.y ),
CUR.zp0.cur[point] = CUR.zp0.org[point];
}
@@ -5883,10 +5909,12 @@
if ( CUR.GS.gep1 == 0 )
{
CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x +
- TT_MulFix14( cvt_dist, CUR.GS.freeVector.x );
+ TT_MulFix14( (FT_UInt32)cvt_dist,
+ CUR.GS.freeVector.x );
CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y +
- TT_MulFix14( cvt_dist, CUR.GS.freeVector.y );
+ TT_MulFix14( (FT_UInt32)cvt_dist,
+ CUR.GS.freeVector.y );
CUR.zp1.cur[point] = CUR.zp0.cur[point];
}
@@ -6211,9 +6239,13 @@
org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base );
cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base );
- new_dist = ( old_range != 0 )
- ? TT_MULDIV( org_dist, cur_range, old_range )
- : cur_dist;
+
+ if ( org_dist )
+ new_dist = ( old_range != 0 )
+ ? TT_MULDIV( org_dist, cur_range, old_range )
+ : cur_dist;
+ else
+ new_dist = 0;
CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist );
}
@@ -6257,7 +6289,7 @@
/* Local variables for Ins_IUP: */
- typedef struct
+ typedef struct IUP_WorkerRec_
{
FT_Vector* orgs; /* original and current coordinate */
FT_Vector* curs; /* arrays */
@@ -6370,7 +6402,7 @@
{
scale_valid = 1;
scale = TT_MULDIV( org2 + delta2 - ( org1 + delta1 ),
- 0x10000, orus2 - orus1 );
+ 0x10000L, orus2 - orus1 );
}
x = ( org1 + delta1 ) +
@@ -6434,6 +6466,9 @@
end_point = CUR.pts.contours[contour] - CUR.pts.first_point;
first_point = point;
+ if ( CUR.pts.n_points <= end_point )
+ end_point = CUR.pts.n_points;
+
while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 )
point++;
diff --git a/src/freetype2/truetype/ttobjs.c b/src/freetype2/truetype/ttobjs.c
index 0294a1b..11d662d 100644
--- a/src/freetype2/truetype/ttobjs.c
+++ b/src/freetype2/truetype/ttobjs.c
@@ -4,7 +4,7 @@
/* */
/* Objects manager (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -18,9 +18,7 @@
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_IDS_H
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_SFNT_H
@@ -144,6 +142,40 @@
#endif /* TT_USE_BYTECODE_INTERPRETER */
+ /* Compare the face with a list of well-known `tricky' fonts. */
+ /* This list shall be expanded as we find more of them. */
+
+ static FT_Bool
+ tt_check_trickyness( FT_String* name )
+ {
+#define TRICK_NAMES_MAX_CHARACTERS 16
+#define TRICK_NAMES_COUNT 7
+ static const char trick_names[TRICK_NAMES_COUNT][TRICK_NAMES_MAX_CHARACTERS+1] =
+ {
+ "DFKaiSho-SB", /* dfkaisb.ttf */
+ "DFKaiShu",
+ "DFKai-SB", /* kaiu.ttf */
+ "HuaTianSongTi?", /* htst3.ttf */
+ "MingLiU", /* mingliu.ttf & mingliu.ttc */
+ "PMingLiU", /* mingliu.ttc */
+ "MingLi43", /* mingli.ttf */
+ };
+ int nn;
+
+
+ if ( !name )
+ return FALSE;
+
+ /* Note that we only check the face name at the moment; it might */
+ /* be worth to do more checks for a few special cases. */
+ for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ )
+ if ( ft_strstr( name, trick_names[nn] ) )
+ return TRUE;
+
+ return FALSE;
+ }
+
+
/*************************************************************************/
/* */
/* <Function> */
@@ -180,7 +212,7 @@
TT_Face face = (TT_Face)ttface;
- library = face->root.driver->root.library;
+ library = ttface->driver->root.library;
sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
if ( !sfnt )
goto Bad_Format;
@@ -206,7 +238,7 @@
}
#ifdef TT_USE_BYTECODE_INTERPRETER
- face->root.face_flags |= FT_FACE_FLAG_HINTER;
+ ttface->face_flags |= FT_FACE_FLAG_HINTER;
#endif
/* If we are performing a simple font format check, exit immediately. */
@@ -218,29 +250,37 @@
if ( error )
goto Exit;
+ if ( tt_check_trickyness( ttface->family_name ) )
+ ttface->face_flags |= FT_FACE_FLAG_TRICKY;
+
error = tt_face_load_hdmx( face, stream );
if ( error )
goto Exit;
- if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE )
+ if ( FT_IS_SCALABLE( ttface ) )
{
#ifdef FT_CONFIG_OPTION_INCREMENTAL
- if ( !face->root.internal->incremental_interface )
+ if ( !ttface->internal->incremental_interface )
error = tt_face_load_loca( face, stream );
if ( !error )
- error = tt_face_load_cvt( face, stream ) ||
- tt_face_load_fpgm( face, stream ) ||
- tt_face_load_prep( face, stream );
+ error = tt_face_load_cvt( face, stream );
+ if ( !error )
+ error = tt_face_load_fpgm( face, stream );
+ if ( !error )
+ error = tt_face_load_prep( face, stream );
#else
if ( !error )
- error = tt_face_load_loca( face, stream ) ||
- tt_face_load_cvt( face, stream ) ||
- tt_face_load_fpgm( face, stream ) ||
- tt_face_load_prep( face, stream );
+ error = tt_face_load_loca( face, stream );
+ if ( !error )
+ error = tt_face_load_cvt( face, stream );
+ if ( !error )
+ error = tt_face_load_fpgm( face, stream );
+ if ( !error )
+ error = tt_face_load_prep( face, stream );
#endif
@@ -262,38 +302,8 @@
if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING )
unpatented_hinting = TRUE;
- /* Compare the face with a list of well-known `tricky' fonts. */
- /* This list shall be expanded as we find more of them. */
if ( !unpatented_hinting )
- {
- static const char* const trick_names[] =
- {
- "DFKaiSho-SB", /* dfkaisb.ttf */
- "DFKai-SB", /* kaiu.ttf */
- "HuaTianSongTi?", /* htst3.ttf */
- "MingLiU", /* mingliu.ttf & mingliu.ttc */
- "PMingLiU", /* mingliu.ttc */
- "MingLi43", /* mingli.ttf */
- NULL
- };
- int nn;
-
-
- /* Note that we only check the face name at the moment; it might */
- /* be worth to do more checks for a few special cases. */
- for ( nn = 0; trick_names[nn] != NULL; nn++ )
- {
- if ( ttface->family_name &&
- ft_strstr( ttface->family_name, trick_names[nn] ) )
- {
- unpatented_hinting = 1;
- break;
- }
- }
- }
-
- ttface->internal->ignore_unpatented_hinter =
- FT_BOOL( !unpatented_hinting );
+ ttface->internal->ignore_unpatented_hinter = TRUE;
}
#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&
@@ -325,12 +335,18 @@
FT_LOCAL_DEF( void )
tt_face_done( FT_Face ttface ) /* TT_Face */
{
- TT_Face face = (TT_Face)ttface;
- FT_Memory memory = face->root.memory;
- FT_Stream stream = face->root.stream;
+ TT_Face face = (TT_Face)ttface;
+ FT_Memory memory;
+ FT_Stream stream;
+ SFNT_Service sfnt;
- SFNT_Service sfnt = (SFNT_Service)face->sfnt;
+ if ( !face )
+ return;
+
+ memory = ttface->memory;
+ stream = ttface->stream;
+ sfnt = (SFNT_Service)face->sfnt;
/* for `extended TrueType formats' (i.e. compressed versions) */
if ( face->extra.finalizer )
@@ -595,18 +611,15 @@
/* Set default metrics */
{
- FT_Size_Metrics* metrics = &size->metrics;
- TT_Size_Metrics* metrics2 = &size->ttmetrics;
+ TT_Size_Metrics* metrics = &size->ttmetrics;
- metrics->x_ppem = 0;
- metrics->y_ppem = 0;
- metrics2->rotated = FALSE;
- metrics2->stretched = FALSE;
+ metrics->rotated = FALSE;
+ metrics->stretched = FALSE;
/* set default compensation (all 0) */
for ( i = 0; i < 4; i++ )
- metrics2->compensations[i] = 0;
+ metrics->compensations[i] = 0;
}
/* allocate function defs, instruction defs, cvt, and storage area */
@@ -669,7 +682,7 @@
if ( !size->cvt_ready )
{
FT_UInt i;
- TT_Face face = (TT_Face) size->root.face;
+ TT_Face face = (TT_Face)size->root.face;
/* Scale the cvt values to the new ppem. */
@@ -694,8 +707,9 @@
error = tt_size_run_prep( size );
if ( !error )
- size->cvt_ready = 1;
+ size->cvt_ready = 1;
}
+
Exit:
return error;
}
diff --git a/src/freetype2/truetype/ttobjs.h b/src/freetype2/truetype/ttobjs.h
index 6971013..30c8669 100644
--- a/src/freetype2/truetype/ttobjs.h
+++ b/src/freetype2/truetype/ttobjs.h
@@ -4,7 +4,7 @@
/* */
/* Objects manager (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -99,6 +99,10 @@ FT_BEGIN_HEADER
FT_Short delta_shift;
FT_Byte instruct_control;
+ /* According to Greg Hitchcock from Microsoft, the `scan_control' */
+ /* variable as documented in the TrueType specification is a 32-bit */
+ /* integer; the high-word part holds the SCANTYPE value, the low-word */
+ /* part the SCANCTRL value. We separate it into two fields. */
FT_Bool scan_control;
FT_Int scan_type;
@@ -192,43 +196,11 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
- /* Subglyph loading record. Used to load composite components. */
- /* */
- typedef struct TT_SubglyphRec_
- {
- FT_Long index; /* subglyph index; initialized with -1 */
- FT_Bool is_scaled; /* is the subglyph scaled? */
- FT_Bool is_hinted; /* should it be hinted? */
- FT_Bool preserve_pps; /* preserve phantom points? */
-
- FT_Long file_offset;
-
- FT_BBox bbox;
- FT_Pos left_bearing;
- FT_Pos advance;
-
- TT_GlyphZoneRec zone;
-
- FT_Long arg1; /* first argument */
- FT_Long arg2; /* second argument */
-
- FT_UShort element_flag; /* current load element flag */
-
- TT_Transform transform; /* transformation matrix */
-
- FT_Vector pp1, pp2; /* phantom points (horizontal) */
- FT_Vector pp3, pp4; /* phantom points (vertical) */
-
- } TT_SubGlyphRec, *TT_SubGlyph_Stack;
-
-
- /*************************************************************************/
- /* */
/* A note regarding non-squared pixels: */
/* */
/* (This text will probably go into some docs at some time; for now, it */
- /* is kept here to explain some definitions in the TIns_Metrics */
- /* record). */
+ /* is kept here to explain some definitions in the TT_Size_Metrics */
+ /* record). */
/* */
/* The CVT is a one-dimensional array containing values that control */
/* certain important characteristics in a font, like the height of all */
diff --git a/src/freetype2/truetype/ttpic.c b/src/freetype2/truetype/ttpic.c
new file mode 100644
index 0000000..27ec4a1
--- /dev/null
+++ b/src/freetype2/truetype/ttpic.c
@@ -0,0 +1,79 @@
+/***************************************************************************/
+/* */
+/* ttpic.c */
+/* */
+/* The FreeType position independent code services for truetype module. */
+/* */
+/* Copyright 2009 by */
+/* Oran Agra and Mickey Gabel. */
+/* */
+/* 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_INTERNAL_OBJECTS_H
+#include "ttpic.h"
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+ /* forward declaration of PIC init functions from ttdriver.c */
+ FT_Error FT_Create_Class_tt_services( FT_Library, FT_ServiceDescRec**);
+ void FT_Destroy_Class_tt_services( FT_Library, FT_ServiceDescRec*);
+ void FT_Init_Class_tt_service_gx_multi_masters(FT_Service_MultiMastersRec*);
+ void FT_Init_Class_tt_service_truetype_glyf(FT_Service_TTGlyfRec*);
+
+ void
+ tt_driver_class_pic_free( FT_Library library )
+ {
+ FT_PIC_Container* pic_container = &library->pic_container;
+ FT_Memory memory = library->memory;
+ if ( pic_container->truetype )
+ {
+ TTModulePIC* container = (TTModulePIC*)pic_container->truetype;
+ if(container->tt_services)
+ FT_Destroy_Class_tt_services(library, container->tt_services);
+ container->tt_services = NULL;
+ FT_FREE( container );
+ pic_container->truetype = NULL;
+ }
+ }
+
+ FT_Error
+ tt_driver_class_pic_init( FT_Library library )
+ {
+ FT_PIC_Container* pic_container = &library->pic_container;
+ FT_Error error = FT_Err_Ok;
+ TTModulePIC* container;
+ FT_Memory memory = library->memory;
+
+ /* allocate pointer, clear and set global container pointer */
+ if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+ return error;
+ FT_MEM_SET( container, 0, sizeof(*container) );
+ pic_container->truetype = container;
+
+ /* initialize pointer table - this is how the module usually expects this data */
+ error = FT_Create_Class_tt_services(library, &container->tt_services);
+ if(error)
+ goto Exit;
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ FT_Init_Class_tt_service_gx_multi_masters(&container->tt_service_gx_multi_masters);
+#endif
+ FT_Init_Class_tt_service_truetype_glyf(&container->tt_service_truetype_glyf);
+Exit:
+ if(error)
+ tt_driver_class_pic_free(library);
+ return error;
+ }
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+
+/* END */
diff --git a/src/freetype2/truetype/ttpic.h b/src/freetype2/truetype/ttpic.h
new file mode 100644
index 0000000..84de0fe
--- /dev/null
+++ b/src/freetype2/truetype/ttpic.h
@@ -0,0 +1,59 @@
+/***************************************************************************/
+/* */
+/* ttpic.h */
+/* */
+/* The FreeType position independent code services for truetype module. */
+/* */
+/* Copyright 2009 by */
+/* Oran Agra and Mickey Gabel. */
+/* */
+/* 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 __TTPIC_H__
+#define __TTPIC_H__
+
+
+FT_BEGIN_HEADER
+
+#ifndef FT_CONFIG_OPTION_PIC
+#define FT_TT_SERVICES_GET tt_services
+#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters
+#define FT_TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+#include FT_MULTIPLE_MASTERS_H
+#include FT_SERVICE_MULTIPLE_MASTERS_H
+#include FT_SERVICE_TRUETYPE_GLYF_H
+
+ typedef struct TTModulePIC_
+ {
+ FT_ServiceDescRec* tt_services;
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ FT_Service_MultiMastersRec tt_service_gx_multi_masters;
+#endif
+ FT_Service_TTGlyfRec tt_service_truetype_glyf;
+ } TTModulePIC;
+
+#define GET_PIC(lib) ((TTModulePIC*)((lib)->pic_container.truetype))
+#define FT_TT_SERVICES_GET (GET_PIC(library)->tt_services)
+#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET (GET_PIC(library)->tt_service_gx_multi_masters)
+#define FT_TT_SERVICE_TRUETYPE_GLYF_GET (GET_PIC(library)->tt_service_truetype_glyf)
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __TTPIC_H__ */
+
+
+/* END */
diff --git a/src/freetype2/truetype/ttpload.c b/src/freetype2/truetype/ttpload.c
index 9d3381b..a311b03 100644
--- a/src/freetype2/truetype/ttpload.c
+++ b/src/freetype2/truetype/ttpload.c
@@ -4,7 +4,7 @@
/* */
/* TrueType-specific tables loader (body). */
/* */
-/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -58,18 +58,23 @@
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
-
FT_LOCAL_DEF( FT_Error )
tt_face_load_loca( TT_Face face,
FT_Stream stream )
{
FT_Error error;
FT_ULong table_len;
+ FT_Int shift;
/* we need the size of the `glyf' table for malformed `loca' tables */
error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len );
- if ( error )
+
+ /* it is possible that a font doesn't have a glyf table at all */
+ /* or its size is zero */
+ if ( error == TT_Err_Table_Missing )
+ face->glyf_len = 0;
+ else if ( error )
goto Exit;
FT_TRACE2(( "Locations " ));
@@ -82,23 +87,65 @@
if ( face->header.Index_To_Loc_Format != 0 )
{
+ shift = 2;
+
if ( table_len >= 0x40000L )
{
- FT_TRACE2(( "table too large!\n" ));
+ FT_TRACE2(( "table too large\n" ));
error = TT_Err_Invalid_Table;
goto Exit;
}
- face->num_locations = (FT_UInt)( table_len >> 2 );
+ face->num_locations = table_len >> shift;
}
else
{
+ shift = 1;
+
if ( table_len >= 0x20000L )
{
- FT_TRACE2(( "table too large!\n" ));
+ FT_TRACE2(( "table too large\n" ));
error = TT_Err_Invalid_Table;
goto Exit;
}
- face->num_locations = (FT_UInt)( table_len >> 1 );
+ face->num_locations = table_len >> shift;
+ }
+
+ if ( face->num_locations != (FT_ULong)face->root.num_glyphs )
+ {
+ FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n",
+ face->num_locations, face->root.num_glyphs ));
+
+ /* we only handle the case where `maxp' gives a larger value */
+ if ( face->num_locations < (FT_ULong)face->root.num_glyphs )
+ {
+ FT_Long new_loca_len = (FT_Long)face->root.num_glyphs << shift;
+
+ TT_Table entry = face->dir_tables;
+ TT_Table limit = entry + face->num_tables;
+
+ FT_Long pos = FT_Stream_Pos( stream );
+ FT_Long dist = 0x7FFFFFFFL;
+
+
+ /* compute the distance to next table in font file */
+ for ( ; entry < limit; entry++ )
+ {
+ FT_Long diff = entry->Offset - pos;
+
+
+ if ( diff > 0 && diff < dist )
+ dist = diff;
+ }
+
+ if ( new_loca_len <= dist )
+ {
+ face->num_locations = face->root.num_glyphs;
+ table_len = new_loca_len;
+
+ FT_TRACE2(( "adjusting num_locations to %d\n",
+ face->num_locations ));
+ }
+ }
}
/*
@@ -156,12 +203,14 @@
}
}
- /* It isn't mentioned explicitly that the `loca' table must be */
- /* ordered, but implicitly it refers to the length of an entry */
- /* as the difference between the current and the next position. */
- /* Anyway, there do exist (malformed) fonts which don't obey */
- /* this rule, so we are only able to provide an upper bound for */
- /* the size. */
+ /* The `loca' table must be ordered; it refers to the length of */
+ /* an entry as the difference between the current and the next */
+ /* position. However, there do exist (malformed) fonts which */
+ /* don't obey this rule, so we are only able to provide an */
+ /* upper bound for the size. */
+ /* */
+ /* We get (intentionally) a wrong, non-zero result in case the */
+ /* `glyf' table is missing. */
if ( pos2 >= pos1 )
*asize = (FT_UInt)( pos2 - pos1 );
else
@@ -216,7 +265,7 @@
error = face->goto_table( face, TTAG_cvt, stream, &table_len );
if ( error )
{
- FT_TRACE2(( "is missing!\n" ));
+ FT_TRACE2(( "is missing\n" ));
face->cvt_size = 0;
face->cvt = NULL;
@@ -301,7 +350,7 @@
face->font_program_size = 0;
error = TT_Err_Ok;
- FT_TRACE2(( "is missing!\n" ));
+ FT_TRACE2(( "is missing\n" ));
}
else
{
@@ -362,7 +411,7 @@
face->cvt_program_size = 0;
error = TT_Err_Ok;
- FT_TRACE2(( "is missing!\n" ));
+ FT_TRACE2(( "is missing\n" ));
}
else
{