Formatting.

* src/truetype/ttpload.c (tt_face_load_loca): Fix typo.

* src/sfnt/ttkern.c: Include `ttkern.h'.
(FT_COMPONENT): Updated.

* include/freetype/internal/fttrace.h: Add entry for `ttkern'.

* src/sfnt/ttsbit0.c: s/FT_Err_/SFNT_Err_/.
Decorate constants with `U' and `L' where necessary.

* src/sfnt/ttcmap.c (tt_cmap4_next): Remove unused variable.
This commit is contained in:
Werner Lemberg 2005-03-01 02:13:50 +00:00
parent 7305f62767
commit e793092d0a
28 changed files with 890 additions and 639 deletions

221
ChangeLog
View File

@ -1,45 +1,163 @@
2005-02-28 Werner Lemberg <wl@gnu.org>
* src/truetype/ttpload.c (tt_face_load_loca): Fix typo.
* src/sfnt/ttkern.c: Include `ttkern.h'.
(FT_COMPONENT): Updated.
* include/freetype/internal/fttrace.h: Add entry for `ttkern'.
* src/sfnt/ttsbit0.c: s/FT_Err_/SFNT_Err_/.
Decorate constants with `U' and `L' where necessary.
* src/sfnt/ttcmap.c (tt_cmap4_next): Remove unused variable.
2005-02-28 David Turner <david@freetype.org> 2005-02-28 David Turner <david@freetype.org>
* src/base/ftdbgmem.c (FT_DumpMemory): added sorting of memory sources * src/base/ftdbgmem.c (FT_DumpMemory): Added sorting of memory
according to decreasing maximum cumulative allocations. sources according to decreasing maximum cumulative allocations.
(ft_mem_source_compare): New auxiliary function.
* include/freetype/internal/tttypes.h, src/sfnt/ttsbit.c, src/sfnt/ttsbit0.c,
src/truetype/ttobjs.c, src/cff/cffobjs.c, src/sfnt/sfobjs.c: implementing new * src/sfnt/ttsbit0.c: New file, implementing a heap-optimized
heap-optimized embedded bitmap loader. This one also fixes bug #12107 embedded bitmap loader.
* src/sfnt/sfobjs.c: fixed bug that prevented loading SFNT fonts without * src/sfnt/ttsbit.c: Include `ft2build.h', FT_INTERNAL_DEBUG_H,
a 'kern' table. FT_INTERNAL_STREAM_H, FT_TRUETYPE_TAGS_H.
Load `ttsbit0.c' if FT_OPTIMIZE_MEMORY is set, otherwise use
file contents.
(tt_face_load_sbit_strikes): Set up root fields to indicate the
strikes. This fixes Savannah bug #12107.
Use `static' keyword for `sbit_line_metrics_field',
`strike_start_fields', `strike_end_fields'.
* include/freetype/internal/tttypes.h (TT_FaceRec): Define
`sbit_table', `sbit_table_size', `sbit_num_strikes' if
FT_OPTIMIZE_MEMORY is set.
Don't define `num_sbit_strikes' and `sbit_strikes' if
FT_OPTIMIZE_MEMORY is set.
* src/cff/cffobjs.c (sbit_size_reset): Handle FT_OPTIMIZE_MEMORY.
* src/sfnt/sfobjs.c (sfnt_load_face): Fixed bug that prevented
loading SFNT fonts without a `kern' table.
Properly pass root->face_flags.
Remove code for TT_CONFIG_OPTION_EMBEDDED_BITMAPS.
* src/sfnt/sfdriver.c (sfnt_interface)
[TT_CONFIG_OPTION_EMBEDDED_BITMAPS]: Don't use `tt_find_sbit_image'
and `tt_load_sbit_metrics'.
* src/sfnt/ttcmap.c: Optimize linear charmap scanning for Format 4.
(OPT_CMAP4): New macro.
(TT_CMap4Rec) [OPT_CMAP4]: New structure.
(tt_cmap4_init, tt_cmap4_set_range, tt_cmap4_next, tt_cmap4_reset)
[OPT_CMAP4]: New functions.
(tt_cmap4_char_next) [OPT_CMAP4]: Use `tt_cmap4_next' and
`tt_cmap4_reset'.
(tt_cmap4_class_rec) [OPT_CMAP4]: Use `TT_CMap4Rec' and
`tt_cmap4_init'.
* src/truetype/ttobjs.c (Reset_SBit_Size): Handle
FT_OPTIMIZE_MEMORY.
* src/autofit/afhints.h (AF_PointRec, AF_SegmentRec, AF_EdgeRec):
Optimize member types.
* src/autofit/afloader.c (af_loader_done): Call
`af_glyph_hints_done'.
2005-02-27 David Turner <david@freetype.org> 2005-02-27 David Turner <david@freetype.org>
* src/sfnt/ttkern.c (tt_face_load_kern): fixing a small bug which returned * src/sfnt/ttkern.c (tt_face_load_kern): Fix a small bug which
invalid (random) values for the horizontal kerning caused invalid (random) return values for the horizontal kerning.
2005-02-25 David Turner <david@freetype.org> 2005-02-25 David Turner <david@freetype.org>
* many, many files: several memory optimizations were implemented to Implement several memory optimizations to drastically reduce the
drastically reduce the heap usage of FreeType, especially in the case heap usage of FreeType, especially in the case of memory-mapped
of memory-mapped files. The idea is to avoid loading and decoding tables files. The idea is to avoid loading and decoding tables in the
in the heap, and instead access the raw data whenever possible (i.e. heap, and instead access the raw data whenever possible (i.e., when
when it doesn't compromise performance). it doesn't compromise performance).
This had several impacts: first, opening vera.ttf uses a ridiculous amount This has several benefits: For example, opening vera.ttf now uses
of memory (when the FT_Library footprint is accounted for), until you start just a small amount of memory (even when the FT_Library footprint is
loading glyphs. Even then, you'll save at least 20 Kb compared to the non accounted for), until you start loading glyphs. Even then, you save
optimized case. performance of various operations, including open/close at least 20KB compared to the non-optimized case. Performance of
has also been dramatically improved. various operations, including open and close, has also been
dramatically improved.
More optimisations to come. The auto-hinter eats memory like crazy? This
must be stopped... More optimizations to come, especially for the auto-hinter.
* include/freetype/internal/sfnt.h (TT_Face_GetKerningFunc): New
function type.
(SFNT_Interface): Add it.
* include/freetype/internal/tttypes.h (TT_HdmxEntryRec, TT_HdmxRec,
TT_Kern0_PairRec): Don't define if FT_OPTIMIZE_MEMORY is set.
(TT_FaceRec): Define `horz_metrics', `horz_metrics_size',
`vert_metrics', `vert_metrics_size', `hdmx_table',
`hdmx_table_size', `hdmx_record_count', `hdmx_record_size',
`hdmx_record_sizes', `kern_table', `kern_table_size,
`num_kern_tables', `kern_avail_bits', `kern_order_bits' if
FT_OPTIMIZE_MEMORY is set.
Don't define `hdmx', `num_kern_pairs', `kern_table_index',
`kern_pairs' if FT_OPTIMIZE_MEMORY is set.
* src/base/ftdbgmem.c (ft_mem_table_set): Don't shadow variable.
Fix compiler warning.
* src/cff/cffdrivr.c (Get_Kerning): Renamed to...
(cff_get_kerning): This. Simplify.
(cff_driver_class): Updated.
* src/sfnt/Jamfile (_sources): Add `ttkern'.
* src/sfnt/rules.mk (SFNT_DRV_SRC): Add `ttkern.c'.
* src/sfnt/sfdriver.c (sfnt_interface): Add `tt_face_get_kerning'.
* src/sfnt/sfnt.c: Include `ttkern.c'.
* src/sfnt/sfobjs.c: Include `ttkern.h'.
(sfnt_load_face): Consider the `kern' and `gasp' table as optional.
(sfnt_done_face): Call `tt_face_done_kern'.
Handle horizontal metrics for FT_OPTIMIZE_MEMORY.
* src/sfnt/ttkern.c, src/sfnt/ttkern.h: New files. Code has been
taken from `ttload.c' and `ttload.h'.
Provide special versions of `tt_face_load_kern',
`tt_face_get_kerning', and `tt_face_done_kern' for
FT_OPTIMIZE_MEMORY.
* src/sfnt/ttload.c (tt_face_load_metrics, tt_face_load_hdmx,
tt_face_free_hdmx): Provide version for FT_OPTIMIZE_MEMORY.
(tt_face_load_kern, tt_kern_pair_compare, TT_KERN_INDEX): Moved to
`ttkern.c'.
* src/sfnt/ttload.h: Updated.
* src/sfnt/ttsbit.c (sbit_metrics_field): Add `static' keyword.
* src/truetype/ttdriver.c (Get_Kerning): Renamed to...
(tt_get_kerning): This. Simplify.
(tt_driver_class): Updated.
* src/truetype/ttgload.c (TT_Get_Metrics): Renamed to...
(tt_face_get_metrics): This. Provide version for FT_OPTIMIZE_MEMORY.
Update all callers.
(Get_Advance_Widths): Replaced with...
(Get_Advance_WidthPtr): This. Provide version for
FT_OPTIMIZE_MEMORY.
Update all callers.
* src/truetype/ttgload.h: Updated.
2005-02-22 David Turner <david@freetype.org> 2005-02-22 David Turner <david@freetype.org>
* src/base/ftdbgmem.c: adding the ability to list all allocation sites * src/base/ftdbgmem.c: Partly rewritten. Added the ability to list
in the memory debugger. Also a new function FT_DumpMemory() was added. all allocation sites in the memory debugger. Also a new function
It is only available in builds with FT_DEBUG_MEMORY defined, and you FT_DumpMemory() was added. It is only available in builds with
must declare it in your own code to use it, i.e. with something FT_DEBUG_MEMORY defined, and you must declare it in your own code to
like: use it, i.e., with something like:
extern void FT_DumpMemory( FT_Memory ); extern void FT_DumpMemory( FT_Memory );
@ -47,26 +165,39 @@
FT_DumpMemory( memory ); FT_DumpMemory( memory );
* include/freetype/config/ftoptions.h: disabling TrueType bytecode * include/freetype/config/ftoption.h
interpreter ! (TT_CONFIG_OPTION_BYTECODE_INTERPRETER): Comment out definition --
again.
(FT_OPTIMIZE_MEMORY): New configuration macro to control various
optimizations for reducing the heap footprint of memory-mapped
TrueType files.
* include/freetype/internal/ftmemory.h: adding FT_ARRAY_ZERO, as a * include/freetype/internal/ftmemory.h (FT_ARRAY_ZERO): New
convenience macro. convenience macro.
* include/freetype/config/ftoption.h, include/freetype/internal/ttypes.h, * include/freetype/internal/tttypes.h (TT_FaceRec)
src/truetype/ttpload.c, src/truetype/ttpload.h, src/truetype/ttgload.c: [FT_OPTIMIZE_MEMORY]: Use optimized types for `num_locations' and
added the temporary configuration FT_OPTIMIZE_MEMORY to control various `glyph_locations'.
optimizations used to reduce the heap footprint of memory-mapped TrueType
files.
* src/truetype/ttpload.c (tt_face_load_loca, tt_face_get_location, * src/truetype/ttgload.c (load_truetype_glyph): Call
tt_face_done_loca): when FT_OPTIMIZE_MEMORY is set, the locations table `tt_face_get_location'.
is read directly from memory-mapped streams, instead of being decoded
into the heap.
* src/truetype/ttpload.c: only load the CVT and fpgm tables when the * src/truetype/ttobjs.c (tt_face_init)
bytecode interpreter is compiled in. [FT_CONFIG_OPTION_INCREMENTAL]: Improve error handling.
(tt_face_done): Call `tt_face_done_loca'.
* src/truetype/ttpload.c (tt_face_get_location, tt_face_done_loca):
New functions. If FT_OPTIMIZE_MEMORY is set, the locations table is
read directly from memory-mapped streams, instead of being decoded
into the heap.
(tt_face_load_loca) [FT_OPTIMIZE_MEMORY]: New implementation.
(tt_face_load_cvt, tt_face_load_fpgm): Only load table if the
bytecode interpreter is compiled in.
* src/truetype/ttpload.h: Updated.
* src/autohint/ahglyph.c (ah_outline_load): Improve allocation
logic.
2005-02-20 Werner Lemberg <wl@gnu.org> 2005-02-20 Werner Lemberg <wl@gnu.org>

View File

@ -4,7 +4,7 @@
/* */ /* */
/* User-selectable configuration macros (specification only). */ /* User-selectable configuration macros (specification only). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -568,7 +568,12 @@ FT_BEGIN_HEADER
#endif /* FT_CONFIG_OPTION_CHESTER_HINTS */ #endif /* FT_CONFIG_OPTION_CHESTER_HINTS */
#define FT_OPTIMIZE_MEMORY /*
* This temporary macro is used to control various optimizations for
* reducing the heap footprint of memory-mapped TrueType files.
*
*/
#define FT_OPTIMIZE_MEMORY
FT_END_HEADER FT_END_HEADER

View File

@ -4,7 +4,7 @@
/* */ /* */
/* The FreeType memory management macros (specification). */ /* The FreeType memory management macros (specification). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2004 by */ /* Copyright 1996-2001, 2002, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg */ /* David Turner, Robert Wilhelm, and Werner Lemberg */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -260,14 +260,14 @@ FT_BEGIN_HEADER
#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) #define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) )
#define FT_ARRAY_ZERO( dest, count ) \ #define FT_ARRAY_ZERO( dest, count ) \
FT_MEM_ZERO( dest, (count)*sizeof( *(dest) ) ) FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) )
#define FT_ARRAY_COPY( dest, source, count ) \ #define FT_ARRAY_COPY( dest, source, count ) \
FT_MEM_COPY( dest, source, (count) * sizeof( *(dest) ) ) FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) )
#define FT_ARRAY_MOVE( dest, source, count ) \ #define FT_ARRAY_MOVE( dest, source, count ) \
FT_MEM_MOVE( dest, source, (count) * sizeof( *(dest) ) ) FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) )
/*************************************************************************/ /*************************************************************************/

View File

@ -4,7 +4,7 @@
/* */ /* */
/* Tracing handling (specification only). */ /* Tracing handling (specification only). */
/* */ /* */
/* Copyright 2002, 2004 by */ /* Copyright 2002, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -43,6 +43,7 @@ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */
/* SFNT driver components */ /* SFNT driver components */
FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */
FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */
FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */
FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */
FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */
FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */

View File

@ -4,7 +4,7 @@
/* */ /* */
/* High-level `sfnt' driver interface (specification). */ /* High-level `sfnt' driver interface (specification). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -477,24 +477,27 @@ FT_BEGIN_HEADER
typedef void typedef void
(*TT_Free_Table_Func)( TT_Face face ); (*TT_Free_Table_Func)( TT_Face face );
/**
* @functype: TT_Face_GetKerningFunc /*
* * @functype:
* @description: * TT_Face_GetKerningFunc
* return the horizontal kerning value between two glyphs *
* * @description:
* @input: * Return the horizontal kerning value between two glyphs.
* face :: handle to source face object *
* left_glyph :: left glyph index * @input:
* right_glyph :: right glyph index * face :: A handle to the source face object.
* * left_glyph :: The left glyph index.
* @return: * right_glyph :: The right glyph index.
* kerning value in font units. *
*/ * @return:
* The kerning value in font units.
*/
typedef FT_Int typedef FT_Int
(*TT_Face_GetKerningFunc)( TT_Face face, (*TT_Face_GetKerningFunc)( TT_Face face,
FT_UInt left_glyph, FT_UInt left_glyph,
FT_UInt right_glyph ); FT_UInt right_glyph );
/*************************************************************************/ /*************************************************************************/
/* */ /* */
@ -552,7 +555,7 @@ FT_BEGIN_HEADER
TT_Load_SBit_Image_Func load_sbit_image; TT_Load_SBit_Image_Func load_sbit_image;
TT_Free_Table_Func free_sbits; TT_Free_Table_Func free_sbits;
/* sett `ttkern.h' */ /* see `ttkern.h' */
TT_Face_GetKerningFunc get_kerning; TT_Face_GetKerningFunc get_kerning;
/* see `ttpost.h' */ /* see `ttpost.h' */

View File

@ -5,7 +5,7 @@
/* Basic SFNT/TrueType type definitions and interface (specification */ /* Basic SFNT/TrueType type definitions and interface (specification */
/* only). */ /* only). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2004 by */ /* Copyright 1996-2001, 2002, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -310,7 +310,9 @@ FT_BEGIN_HEADER
} TT_GaspRec; } TT_GaspRec;
#ifndef FT_OPTIMIZE_MEMORY #ifndef FT_OPTIMIZE_MEMORY
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* <Struct> */ /* <Struct> */
@ -360,6 +362,7 @@ FT_BEGIN_HEADER
} TT_HdmxRec, *TT_Hdmx; } TT_HdmxRec, *TT_Hdmx;
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* <Struct> */ /* <Struct> */
@ -385,6 +388,7 @@ FT_BEGIN_HEADER
FT_FWord value; /* kerning value */ FT_FWord value; /* kerning value */
} TT_Kern0_PairRec, *TT_Kern0_Pair; } TT_Kern0_PairRec, *TT_Kern0_Pair;
#endif /* !OPTIMIZE_MEMORY */ #endif /* !OPTIMIZE_MEMORY */
@ -1285,11 +1289,11 @@ FT_BEGIN_HEADER
/* */ /* */
/***********************************************************************/ /***********************************************************************/
/* the glyph locations */
#ifdef FT_OPTIMIZE_MEMORY #ifdef FT_OPTIMIZE_MEMORY
FT_UInt num_locations; FT_UInt num_locations;
FT_Byte* glyph_locations; FT_Byte* glyph_locations;
#else #else
/* the glyph locations */
FT_UShort num_locations; FT_UShort num_locations;
FT_Long* glyph_locations; FT_Long* glyph_locations;
#endif #endif

View File

@ -5,7 +5,7 @@
/* Routines used to load and analyze a given glyph before hinting */ /* Routines used to load and analyze a given glyph before hinting */
/* (body). */ /* (body). */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2004 Catharon Productions Inc. */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005 Catharon Productions Inc. */
/* Author: David Turner */ /* Author: David Turner */
/* */ /* */
/* This file is part of the Catharon Typography Project and shall only */ /* This file is part of the Catharon Typography Project and shall only */
@ -303,11 +303,11 @@
FT_Int max = outline->max_points; FT_Int max = outline->max_points;
if ( FT_RENEW_ARRAY( outline->points, max, news ) || if ( FT_RENEW_ARRAY( outline->points, max, news ) ||
FT_RENEW_ARRAY( outline->horz_edges, max * 2, news * 2 ) ) FT_RENEW_ARRAY( outline->horz_edges, max * 2, news * 2 ) )
goto Exit; goto Exit;
outline->vert_edges = outline->horz_edges + news; outline->vert_edges = outline->horz_edges + news;
if ( FT_RENEW_ARRAY( outline->horz_segments, max * 2, news * 2 ) ) if ( FT_RENEW_ARRAY( outline->horz_segments, max * 2, news * 2 ) )
goto Exit; goto Exit;

View File

@ -4,7 +4,7 @@
/* */ /* */
/* Memory debugger (body). */ /* Memory debugger (body). */
/* */ /* */
/* Copyright 2001, 2002, 2003, 2004 by */ /* Copyright 2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -27,24 +27,28 @@
#ifdef FT_DEBUG_MEMORY #ifdef FT_DEBUG_MEMORY
#define KEEPALIVE /* keep-alive means that free-d blocks aren't released #define KEEPALIVE /* `Keep alive' means that freed blocks aren't released
* to the heap. This is useful to detect double-frees * to the heap. This is useful to detect double-frees
* or weird heap corruption, but it will use gobs of * or weird heap corruption, but it uses large amounts of
* memory however. * memory, however.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
extern void extern void
FT_DumpMemory( FT_Memory memory ); FT_DumpMemory( FT_Memory memory );
typedef struct FT_MemSourceRec_* FT_MemSource; typedef struct FT_MemSourceRec_* FT_MemSource;
typedef struct FT_MemNodeRec_* FT_MemNode; typedef struct FT_MemNodeRec_* FT_MemNode;
typedef struct FT_MemTableRec_* FT_MemTable; typedef struct FT_MemTableRec_* FT_MemTable;
#define FT_MEM_VAL( addr ) ((FT_ULong)(FT_Pointer)( addr )) #define FT_MEM_VAL( addr ) ((FT_ULong)(FT_Pointer)( addr ))
typedef struct FT_MemSourceRec_ typedef struct FT_MemSourceRec_
{ {
const char* file_name; const char* file_name;
@ -65,10 +69,12 @@
} FT_MemSourceRec; } FT_MemSourceRec;
/* we don't need a resizable array for the memory sources, because
* their number is pretty limited within FreeType. /*
* We don't need a resizable array for the memory sources, because
* their number is pretty limited within FreeType.
*/ */
#define FT_MEM_SOURCE_BUCKETS 128 #define FT_MEM_SOURCE_BUCKETS 128
typedef struct FT_MemNodeRec_ typedef struct FT_MemNodeRec_
@ -105,7 +111,7 @@
FT_Bool bound_count; FT_Bool bound_count;
FT_ULong alloc_count_max; FT_ULong alloc_count_max;
FT_MemSource sources[ FT_MEM_SOURCE_BUCKETS ]; FT_MemSource sources[FT_MEM_SOURCE_BUCKETS];
const char* file_name; const char* file_name;
FT_Long line_no; FT_Long line_no;
@ -127,9 +133,9 @@
#define FT_FILENAME( x ) ((x) ? (x) : "unknown file") #define FT_FILENAME( x ) ((x) ? (x) : "unknown file")
/* I hate these prime numbers. I'd better implement L-Hashing /*
* which is 10% faster and doesn't require divisions, but * Prime numbers are ugly to handle. It would be better to implement
* I'm too lazy at the moment. * L-Hashing, which is 10% faster and doesn't require divisions.
*/ */
static const FT_UInt ft_mem_primes[] = static const FT_UInt ft_mem_primes[] =
{ {
@ -186,9 +192,9 @@
} }
extern void extern void
ft_mem_debug_panic( const char* fmt, ... ) ft_mem_debug_panic( const char* fmt,
... )
{ {
va_list ap; va_list ap;
@ -242,13 +248,13 @@
new_size = ft_mem_closest_prime( table->nodes ); new_size = ft_mem_closest_prime( table->nodes );
if ( new_size != table->size ) if ( new_size != table->size )
{ {
FT_MemNode* new_buckets ; FT_MemNode* new_buckets;
FT_ULong i; FT_ULong i;
new_buckets = (FT_MemNode *) new_buckets = (FT_MemNode *)
ft_mem_table_alloc( table, ft_mem_table_alloc( table,
new_size * sizeof ( FT_MemNode ) ); new_size * sizeof ( FT_MemNode ) );
if ( new_buckets == NULL ) if ( new_buckets == NULL )
return; return;
@ -307,8 +313,8 @@
table->free = memory->free; table->free = memory->free;
table->buckets = (FT_MemNode *) table->buckets = (FT_MemNode *)
memory->alloc( memory, memory->alloc( memory,
table->size * sizeof ( FT_MemNode ) ); table->size * sizeof ( FT_MemNode ) );
if ( table->buckets ) if ( table->buckets )
FT_ARRAY_ZERO( table->buckets, table->size ); FT_ARRAY_ZERO( table->buckets, table->size );
else else
@ -327,6 +333,7 @@
{ {
FT_ULong i; FT_ULong i;
FT_DumpMemory( table->memory ); FT_DumpMemory( table->memory );
if ( table ) if ( table )
@ -334,8 +341,7 @@
FT_Long leak_count = 0; FT_Long leak_count = 0;
FT_ULong leaks = 0; FT_ULong leaks = 0;
/* remove all blocks from the table, revealing leaked ones /* remove all blocks from the table, revealing leaked ones */
*/
for ( i = 0; i < table->size; i++ ) for ( i = 0; i < table->size; i++ )
{ {
FT_MemNode *pnode = table->buckets + i, next, node = *pnode; FT_MemNode *pnode = table->buckets + i, next, node = *pnode;
@ -368,18 +374,19 @@
} }
table->buckets[i] = 0; table->buckets[i] = 0;
} }
ft_mem_table_free( table, table->buckets ); ft_mem_table_free( table, table->buckets );
table->buckets = NULL; table->buckets = NULL;
table->size = 0; table->size = 0;
table->nodes = 0; table->nodes = 0;
/* remove all sources /* remove all sources */
*/
for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ ) for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ )
{ {
FT_MemSource source, next; FT_MemSource source, next;
for ( source = table->sources[i]; source != NULL; source = next ) for ( source = table->sources[i]; source != NULL; source = next )
{ {
next = source->link; next = source->link;
@ -438,8 +445,11 @@
FT_UInt32 hash; FT_UInt32 hash;
FT_MemSource node, *pnode; FT_MemSource node, *pnode;
hash = (FT_UInt32)(void*)table->file_name + (FT_UInt32)(5*table->line_no);
pnode = &table->sources[ hash % FT_MEM_SOURCE_BUCKETS ]; hash = (FT_UInt32)(void*)table->file_name +
(FT_UInt32)( 5 * table->line_no );
pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];
for ( ;; ) for ( ;; )
{ {
node = *pnode; node = *pnode;
@ -453,12 +463,11 @@
pnode = &node->link; pnode = &node->link;
} }
node = ft_mem_table_alloc( table, sizeof(*node) ); node = ft_mem_table_alloc( table, sizeof ( *node ) );
if ( node == NULL ) if ( node == NULL )
ft_mem_debug_panic( ft_mem_debug_panic(
"not enough memory to perform memory debugging\n" ); "not enough memory to perform memory debugging\n" );
node->file_name = table->file_name; node->file_name = table->file_name;
node->line_no = table->line_no; node->line_no = table->line_no;
@ -493,21 +502,22 @@
{ {
FT_MemSource source; FT_MemSource source;
pnode = ft_mem_table_get_nodep( table, address ); pnode = ft_mem_table_get_nodep( table, address );
node = *pnode; node = *pnode;
if ( node ) if ( node )
{ {
if ( node->size < 0 ) if ( node->size < 0 )
{ {
/* this block was already freed. This means that our memory is */ /* This block was already freed. Our memory is now completely */
/* now completely corrupted! */ /* corrupted! */
/* this can only happen in keep-alive mode */ /* This can only happen in keep-alive mode. */
ft_mem_debug_panic( ft_mem_debug_panic(
"memory heap corrupted (allocating freed block)" ); "memory heap corrupted (allocating freed block)" );
} }
else else
{ {
/* this block was already allocated. This means that our memory */ /* This block was already allocated. This means that our memory */
/* is also corrupted! */ /* is also corrupted! */
ft_mem_debug_panic( ft_mem_debug_panic(
"memory heap corrupted (re-allocating allocated block at" "memory heap corrupted (re-allocating allocated block at"
@ -577,6 +587,7 @@
{ {
FT_MemSource source; FT_MemSource source;
if ( node->size < 0 ) if ( node->size < 0 )
ft_mem_debug_panic( ft_mem_debug_panic(
"freeing memory block at %p more than once at (%s:%ld)\n" "freeing memory block at %p more than once at (%s:%ld)\n"
@ -586,7 +597,7 @@
FT_FILENAME( node->source->file_name ), node->source->line_no, FT_FILENAME( node->source->file_name ), node->source->line_no,
FT_FILENAME( node->free_file_name ), node->free_line_no ); FT_FILENAME( node->free_file_name ), node->free_line_no );
/* scramble the node's content for additionnals safety */ /* scramble the node's content for additional safety */
FT_MEM_SET( address, 0xF3, node->size ); FT_MEM_SET( address, 0xF3, node->size );
table->alloc_current -= node->size; table->alloc_current -= node->size;
@ -599,13 +610,13 @@
{ {
/* we simply invert the node's size to indicate that the node */ /* we simply invert the node's size to indicate that the node */
/* was freed. */ /* was freed. */
node->size = -node->size; node->size = -node->size;
node->free_file_name = table->file_name; node->free_file_name = table->file_name;
node->free_line_no = table->line_no; node->free_line_no = table->line_no;
} }
else else
{ {
table->nodes --; table->nodes--;
*pnode = node->link; *pnode = node->link;
@ -640,12 +651,12 @@
ft_mem_debug_panic( "negative block size allocation (%ld)", size ); ft_mem_debug_panic( "negative block size allocation (%ld)", size );
/* return NULL if the maximum number of allocations was reached */ /* return NULL if the maximum number of allocations was reached */
if ( table->bound_count && if ( table->bound_count &&
table->alloc_count >= table->alloc_count_max ) table->alloc_count >= table->alloc_count_max )
return NULL; return NULL;
/* return NULL if this allocation would overflow the maximum heap size */ /* return NULL if this allocation would overflow the maximum heap size */
if ( table->bound_total && if ( table->bound_total &&
table->alloc_current + (FT_ULong)size > table->alloc_total_max ) table->alloc_current + (FT_ULong)size > table->alloc_total_max )
return NULL; return NULL;
@ -658,7 +669,7 @@
table->file_name = NULL; table->file_name = NULL;
table->line_no = 0; table->line_no = 0;
return (FT_Pointer) block; return (FT_Pointer)block;
} }
@ -714,7 +725,7 @@
"trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)", "trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)",
block, cur_size, file_name, line_no ); block, cur_size, file_name, line_no );
/* check 'cur_size' value */ /* check `cur_size' value */
pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block ); pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block );
node = *pnode; node = *pnode;
if ( !node ) if ( !node )
@ -761,6 +772,7 @@
{ {
const char* p; const char* p;
memory->user = table; memory->user = table;
memory->alloc = ft_mem_debug_alloc; memory->alloc = ft_mem_debug_alloc;
memory->realloc = ft_mem_debug_realloc; memory->realloc = ft_mem_debug_realloc;
@ -769,31 +781,34 @@
p = getenv( "FT2_ALLOC_TOTAL_MAX" ); p = getenv( "FT2_ALLOC_TOTAL_MAX" );
if ( p != NULL ) if ( p != NULL )
{ {
FT_Long total_max = ft_atol(p); FT_Long total_max = ft_atol( p );
if ( total_max > 0 ) if ( total_max > 0 )
{ {
table->bound_total = 1; table->bound_total = 1;
table->alloc_total_max = (FT_ULong) total_max; table->alloc_total_max = (FT_ULong)total_max;
} }
} }
p = getenv( "FT2_ALLOC_COUNT_MAX" ); p = getenv( "FT2_ALLOC_COUNT_MAX" );
if ( p != NULL ) if ( p != NULL )
{ {
FT_Long total_count = ft_atol(p); FT_Long total_count = ft_atol( p );
if ( total_count > 0 ) if ( total_count > 0 )
{ {
table->bound_count = 1; table->bound_count = 1;
table->alloc_count_max = (FT_ULong) total_count; table->alloc_count_max = (FT_ULong)total_count;
} }
} }
p = getenv( "FT2_KEEP_ALIVE" ); p = getenv( "FT2_KEEP_ALIVE" );
if ( p != NULL ) if ( p != NULL )
{ {
FT_Long keep_alive = ft_atol(p); FT_Long keep_alive = ft_atol( p );
if ( keep_alive > 0 ) if ( keep_alive > 0 )
table->keep_alive = 1; table->keep_alive = 1;
@ -839,6 +854,7 @@
table->file_name = file_name; table->file_name = file_name;
table->line_no = line_no; table->line_no = line_no;
} }
return FT_Alloc( memory, size, P ); return FT_Alloc( memory, size, P );
} }
@ -859,6 +875,7 @@
table->file_name = file_name; table->file_name = file_name;
table->line_no = line_no; table->line_no = line_no;
} }
return FT_Realloc( memory, current, size, P ); return FT_Realloc( memory, current, size, P );
} }
@ -899,6 +916,7 @@
table->file_name = file_name; table->file_name = file_name;
table->line_no = line_no; table->line_no = line_no;
} }
return FT_QRealloc( memory, current, size, P ); return FT_QRealloc( memory, current, size, P );
} }
@ -917,6 +935,7 @@
table->file_name = file_name; table->file_name = file_name;
table->line_no = line_no; table->line_no = line_no;
} }
FT_Free( memory, (void **)block ); FT_Free( memory, (void **)block );
} }
@ -928,6 +947,7 @@
FT_MemSource s1 = *(FT_MemSource*)p1; FT_MemSource s1 = *(FT_MemSource*)p1;
FT_MemSource s2 = *(FT_MemSource*)p2; FT_MemSource s2 = *(FT_MemSource*)p2;
if ( s2->max_size > s1->max_size ) if ( s2->max_size > s1->max_size )
return 1; return 1;
else if ( s2->max_size < s1->max_size ) else if ( s2->max_size < s1->max_size )
@ -945,48 +965,55 @@
if ( table ) if ( table )
{ {
FT_MemSource* bucket = table->sources; FT_MemSource* bucket = table->sources;
FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS; FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS;
FT_MemSource* sources; FT_MemSource* sources;
FT_UInt nn, count; FT_UInt nn, count;
const char* fmt; const char* fmt;
count = 0; count = 0;
for ( ; bucket < limit; bucket++ ) for ( ; bucket < limit; bucket++ )
{ {
FT_MemSource source = *bucket; FT_MemSource source = *bucket;
for ( ; source; source = source->link ) for ( ; source; source = source->link )
count++; count++;
} }
sources = ft_mem_table_alloc( table, sizeof(*sources) * count ); sources = ft_mem_table_alloc( table, sizeof ( *sources ) * count );
count = 0; count = 0;
for ( bucket = table->sources; bucket < limit; bucket++ ) for ( bucket = table->sources; bucket < limit; bucket++ )
{ {
FT_MemSource source = *bucket; FT_MemSource source = *bucket;
for ( ; source; source = source->link ) for ( ; source; source = source->link )
sources[count++] = source; sources[count++] = source;
} }
ft_qsort( sources, count, sizeof(*sources), ft_mem_source_compare ); ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare );
printf( "FreeType Memory Dump: current=%ld max=%ld total=%ld count=%ld\n", printf( "FreeType Memory Dump: "
table->alloc_current, table->alloc_max, table->alloc_total, table->alloc_count ); "current=%ld max=%ld total=%ld count=%ld\n",
table->alloc_current, table->alloc_max,
table->alloc_total, table->alloc_count );
printf( " block block sizes sizes sizes source\n" ); printf( " block block sizes sizes sizes source\n" );
printf( " count high sum highsum max location\n" ); printf( " count high sum highsum max location\n" );
printf( "-------------------------------------------------\n" ); printf( "-------------------------------------------------\n" );
fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n"; fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n";
for ( nn = 0; nn < count; nn++ ) for ( nn = 0; nn < count; nn++ )
{ {
FT_MemSource source = sources[nn]; FT_MemSource source = sources[nn];
printf( fmt, printf( fmt,
source->cur_blocks, source->max_blocks, source->cur_blocks, source->max_blocks,
source->cur_size, source->max_size, source->cur_max, source->cur_size, source->max_size, source->cur_max,
FT_FILENAME( source->file_name ), FT_FILENAME( source->file_name ),
source->line_no ); source->line_no );
} }

View File

@ -4,7 +4,7 @@
/* */ /* */
/* OpenType font driver implementation (body). */ /* OpenType font driver implementation (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -105,13 +105,14 @@
TT_Face face = (TT_Face)ttface; TT_Face face = (TT_Face)ttface;
SFNT_Service sfnt = face->sfnt; SFNT_Service sfnt = face->sfnt;
kerning->x = 0; kerning->x = 0;
kerning->y = 0; kerning->y = 0;
if ( sfnt ) if ( sfnt )
kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
return 0; return CFF_Err_Ok;
} }

View File

@ -4,7 +4,7 @@
/* */ /* */
/* OpenType objects manager (body). */ /* OpenType objects manager (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -81,19 +81,22 @@
if ( !error ) if ( !error )
{ {
/* XXX: TODO: move this code to the SFNT module where it belongs */ /* XXX: TODO: move this code to the SFNT module where it belongs */
#ifdef FT_OPTIMIZE_MEMORY #ifdef FT_OPTIMIZE_MEMORY
FT_Byte* strike = face->sbit_table + 8 + strike_index*48; FT_Byte* strike = face->sbit_table + 8 + strike_index*48;
sbit_metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ sbit_metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */
sbit_metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ sbit_metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */
/* XXX: Is this correct? */ /* XXX: Is this correct? */
sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */
strike[18] + /* max_width */ strike[18] + /* max_width */
(FT_Char)strike[23] /* min_advance_SB */ (FT_Char)strike[23] /* min_advance_SB */
) << 6; ) << 6;
#else /* !OPTIMIZE_MEMORY */ #else /* !OPTIMIZE_MEMORY */
TT_SBit_Strike strike = face->sbit_strikes + strike_index; TT_SBit_Strike strike = face->sbit_strikes + strike_index;
@ -104,6 +107,7 @@
sbit_metrics->max_advance = ( strike->hori.min_origin_SB + sbit_metrics->max_advance = ( strike->hori.min_origin_SB +
strike->hori.max_width + strike->hori.max_width +
strike->hori.min_advance_SB ) << 6; strike->hori.min_advance_SB ) << 6;
#endif /* !OPTIMIZE_MEMORY */ #endif /* !OPTIMIZE_MEMORY */
/* XXX: Is this correct? */ /* XXX: Is this correct? */

View File

@ -1,4 +1,4 @@
# FreeType 2 src/sfnt Jamfile (c) 2001, 2002, 2004 David Turner # FreeType 2 src/sfnt Jamfile (c) 2001, 2002, 2004, 2005 David Turner
# #
SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ; SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ;

View File

@ -3,7 +3,7 @@
# #
# Copyright 1996-2000, 2002, 2003, 2004 by # Copyright 1996-2000, 2002, 2003, 2004, 2005 by
# David Turner, Robert Wilhelm, and Werner Lemberg. # David Turner, Robert Wilhelm, and Werner Lemberg.
# #
# This file is part of the FreeType project, and may only be used, modified, # This file is part of the FreeType project, and may only be used, modified,

View File

@ -4,7 +4,7 @@
/* */ /* */
/* High-level SFNT driver interface (body). */ /* High-level SFNT driver interface (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -366,8 +366,8 @@
/* see `ttsbit.h' and `sfnt.h' */ /* see `ttsbit.h' and `sfnt.h' */
tt_face_set_sbit_strike, tt_face_set_sbit_strike,
tt_face_load_sbit_strikes, tt_face_load_sbit_strikes,
NULL /* tt_find_sbit_image */, 0 /* tt_find_sbit_image */,
NULL /* tt_load_sbit_metrics */, 0 /* tt_load_sbit_metrics */,
tt_face_load_sbit_image, tt_face_load_sbit_image,
tt_face_free_sbit_strikes, tt_face_free_sbit_strikes,

View File

@ -4,7 +4,7 @@
/* */ /* */
/* Single object library component. */ /* Single object library component. */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */

View File

@ -4,7 +4,7 @@
/* */ /* */
/* SFNT object management (base). */ /* SFNT object management (base). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -511,7 +511,7 @@
(void)LOAD_( gasp ); (void)LOAD_( gasp );
(void)LOAD_( kerning ); (void)LOAD_( kerning );
error = 0; error = SFNT_Err_Ok;
face->root.family_name = tt_face_get_name( face, face->root.family_name = tt_face_get_name( face,
TT_NAME_ID_PREFERRED_FAMILY ); TT_NAME_ID_PREFERRED_FAMILY );
@ -560,7 +560,7 @@
#if 0 #if 0
/* kerning available ? */ /* kerning available ? */
if ( TT_FACE_HAS_KERNING(face) ) if ( TT_FACE_HAS_KERNING( face ) )
flags |= FT_FACE_FLAG_KERNING; flags |= FT_FACE_FLAG_KERNING;
#endif #endif
@ -780,6 +780,7 @@
{ {
FT_Stream stream = FT_FACE_STREAM( face ); FT_Stream stream = FT_FACE_STREAM( face );
FT_FRAME_RELEASE( face->horz_metrics ); FT_FRAME_RELEASE( face->horz_metrics );
FT_FRAME_RELEASE( face->vert_metrics ); FT_FRAME_RELEASE( face->vert_metrics );
face->horz_metrics_size = 0; face->horz_metrics_size = 0;

View File

@ -4,7 +4,7 @@
/* */ /* */
/* TrueType character mapping table (cmap) support (body). */ /* TrueType character mapping table (cmap) support (body). */
/* */ /* */
/* Copyright 2002, 2003, 2004 by */ /* Copyright 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -627,18 +627,18 @@
typedef struct TT_CMap4Rec_ typedef struct TT_CMap4Rec_
{ {
TT_CMapRec cmap; TT_CMapRec cmap;
FT_UInt32 old_charcode; /* old charcode */ FT_UInt32 old_charcode; /* old charcode */
FT_UInt32 cur_charcode; /* current charcode */ FT_UInt32 cur_charcode; /* current charcode */
FT_UInt cur_gindex; /* current glyph index */ FT_UInt cur_gindex; /* current glyph index */
FT_UInt table_length; FT_UInt table_length;
FT_UInt num_ranges; FT_UInt num_ranges;
FT_UInt cur_range; FT_UInt cur_range;
FT_UInt cur_start; FT_UInt cur_start;
FT_UInt cur_end; FT_UInt cur_end;
FT_Int cur_delta; FT_Int cur_delta;
FT_Byte* cur_values; FT_Byte* cur_values;
} TT_CMap4Rec, *TT_CMap4; } TT_CMap4Rec, *TT_CMap4;
@ -647,15 +647,16 @@
tt_cmap4_init( TT_CMap4 cmap, tt_cmap4_init( TT_CMap4 cmap,
FT_Byte* table ) FT_Byte* table )
{ {
FT_Byte* p; FT_Byte* p;
cmap->cmap.data = table; cmap->cmap.data = table;
p = table + 2; p = table + 2;
cmap->table_length = FT_PEEK_USHORT(p); cmap->table_length = FT_PEEK_USHORT( p );
p = table + 6; p = table + 6;
cmap->num_ranges = FT_PEEK_USHORT(p) >> 1; cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1;
cmap->cur_range = cmap->num_ranges; cmap->cur_range = cmap->num_ranges;
cmap->old_charcode = 0xFFFFFFFFUL; cmap->old_charcode = 0xFFFFFFFFUL;
cmap->cur_charcode = 0; cmap->cur_charcode = 0;
@ -665,7 +666,6 @@
} }
static FT_Int static FT_Int
tt_cmap4_set_range( TT_CMap4 cmap, tt_cmap4_set_range( TT_CMap4 cmap,
FT_UInt range_index ) FT_UInt range_index )
@ -674,23 +674,25 @@
FT_Byte* p; FT_Byte* p;
FT_UInt num_ranges = cmap->num_ranges; FT_UInt num_ranges = cmap->num_ranges;
while ( range_index < num_ranges ) while ( range_index < num_ranges )
{ {
FT_UInt offset; FT_UInt offset;
p = table + 14 + range_index*2;
cmap->cur_end = FT_PEEK_USHORT(p);
p += 2 + num_ranges*2; p = table + 14 + range_index * 2;
cmap->cur_start = FT_PEEK_USHORT(p); cmap->cur_end = FT_PEEK_USHORT( p );
p += num_ranges*2; p += 2 + num_ranges * 2;
cmap->cur_delta = FT_PEEK_SHORT(p); cmap->cur_start = FT_PEEK_USHORT( p );
p += num_ranges*2; p += num_ranges * 2;
offset = FT_PEEK_SHORT(p); cmap->cur_delta = FT_PEEK_SHORT( p );
if ( offset != 0xFFFF ) p += num_ranges * 2;
offset = FT_PEEK_SHORT( p );
if ( offset != 0xFFFFU )
{ {
cmap->cur_values = offset ? p + offset : NULL; cmap->cur_values = offset ? p + offset : NULL;
cmap->cur_range = range_index; cmap->cur_range = range_index;
@ -712,30 +714,33 @@
static void static void
tt_cmap4_next( TT_CMap4 cmap ) tt_cmap4_next( TT_CMap4 cmap )
{ {
FT_UInt num_ranges = cmap->num_ranges;
FT_UInt charcode = cmap->cur_charcode + 1; FT_UInt charcode = cmap->cur_charcode + 1;
cmap->old_charcode = cmap->cur_charcode; cmap->old_charcode = cmap->cur_charcode;
for ( ;; ) for ( ;; )
{ {
FT_Byte* values = cmap->cur_values; FT_Byte* values = cmap->cur_values;
FT_UInt end = cmap->cur_end; FT_UInt end = cmap->cur_end;
FT_Int delta = cmap->cur_delta; FT_Int delta = cmap->cur_delta;
if ( charcode <= end ) if ( charcode <= end )
{ {
if ( values ) if ( values )
{ {
FT_Byte* p = values + 2*(charcode-cmap->cur_start); FT_Byte* p = values + 2 * ( charcode - cmap->cur_start );
do do
{ {
FT_UInt gindex = FT_NEXT_USHORT(p); FT_UInt gindex = FT_NEXT_USHORT( p );
if ( gindex != 0 ) if ( gindex != 0 )
{ {
gindex = (FT_UInt)((gindex + delta) & 0xFFFF); gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU );
if ( gindex != 0 ) if ( gindex != 0 )
{ {
cmap->cur_charcode = charcode; cmap->cur_charcode = charcode;
@ -743,14 +748,14 @@
return; return;
} }
} }
} } while ( ++charcode <= end );
while ( ++charcode <= end );
} }
else else
{ {
do do
{ {
FT_UInt gindex = (FT_UInt)((charcode + delta) & 0xFFFFU); FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU );
if ( gindex != 0 ) if ( gindex != 0 )
{ {
@ -758,14 +763,12 @@
cmap->cur_gindex = gindex; cmap->cur_gindex = gindex;
return; return;
} }
} } while ( ++charcode <= end );
while ( ++charcode <= end );
} }
} }
/* we need to find another range /* we need to find another range */
*/ if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 )
if ( tt_cmap4_set_range( cmap, cmap->cur_range+1 ) < 0 )
break; break;
charcode = cmap->cur_start; charcode = cmap->cur_start;
@ -1092,6 +1095,7 @@
{ {
TT_CMap4 cmap4 = (TT_CMap4)cmap; TT_CMap4 cmap4 = (TT_CMap4)cmap;
if ( char_code == cmap4->old_charcode ) if ( char_code == cmap4->old_charcode )
{ {
result = cmap4->cur_charcode; result = cmap4->cur_charcode;

View File

@ -1,11 +1,11 @@
/***************************************************************************/ /***************************************************************************/
/* */ /* */
/* ttkern.h */ /* ttkern.c */
/* */ /* */
/* Load the basic TrueType kerning table. This doesn't handle */ /* Load the basic TrueType kerning table. This doesn't handle */
/* kerning data within the GPOS table at the moment. */ /* kerning data within the GPOS table at the moment. */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -21,6 +21,7 @@
#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H #include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H #include FT_TRUETYPE_TAGS_H
#include "ttkern.h"
#include "ttload.h" #include "ttload.h"
#include "sferrors.h" #include "sferrors.h"
@ -33,7 +34,7 @@
/* messages during execution. */ /* messages during execution. */
/* */ /* */
#undef FT_COMPONENT #undef FT_COMPONENT
#define FT_COMPONENT trace_ttload #define FT_COMPONENT trace_ttkern
#undef TT_KERN_INDEX #undef TT_KERN_INDEX
@ -72,15 +73,15 @@
FT_ERROR(( "could not extract kerning table\n" )); FT_ERROR(( "could not extract kerning table\n" ));
goto Exit; goto Exit;
} }
face->kern_table_size = table_size; face->kern_table_size = table_size;
p = face->kern_table; p = face->kern_table;
p_limit = p + table_size; p_limit = p + table_size;
p += 2; /* skip version */ p += 2; /* skip version */
num_tables = FT_NEXT_USHORT(p); num_tables = FT_NEXT_USHORT( p );
if ( num_tables > 32 ) /* we only support up to 32 sub-tables */ if ( num_tables > 32 ) /* we only support up to 32 sub-tables */
num_tables = 32; num_tables = 32;
@ -89,56 +90,61 @@
FT_UInt num_pairs, version, length, coverage; FT_UInt num_pairs, version, length, coverage;
FT_Byte* p_next; FT_Byte* p_next;
FT_UInt32 mask = 1UL << nn; FT_UInt32 mask = 1UL << nn;
if ( p + 6 > p_limit ) if ( p + 6 > p_limit )
break; break;
p_next = p; p_next = p;
version = FT_NEXT_USHORT(p); version = FT_NEXT_USHORT( p );
length = FT_NEXT_USHORT(p); length = FT_NEXT_USHORT( p );
coverage = FT_NEXT_USHORT(p); coverage = FT_NEXT_USHORT( p );
if ( length <= 6 ) if ( length <= 6 )
break; break;
p_next += length; p_next += length;
if ( (coverage & ~8) != 0x0001 || /* only use horizontal kerning tables */ /* only use horizontal kerning tables */
p+8 > p_limit ) if ( ( coverage & ~8 ) != 0x0001 ||
p + 8 > p_limit )
goto NextTable; goto NextTable;
num_pairs = FT_NEXT_USHORT(p); num_pairs = FT_NEXT_USHORT( p );
p += 6; p += 6;
if ( p + 6*num_pairs > p_limit ) if ( p + 6 * num_pairs > p_limit )
goto NextTable; goto NextTable;
avail |= mask; avail |= mask;
/* now, try to see if the pairs in this table are ordered. /*
* when they are, we'll be able to use binary search * Now check whether the pairs in this table are ordered.
*/ * We then can use binary search.
*/
if ( num_pairs > 0 ) if ( num_pairs > 0 )
{ {
FT_UInt count; FT_UInt count;
FT_UInt old_pair; FT_UInt old_pair;
old_pair = FT_NEXT_ULONG(p);
old_pair = FT_NEXT_ULONG( p );
p += 2; p += 2;
for ( count = num_pairs-1; count > 0; count-- ) for ( count = num_pairs - 1; count > 0; count-- )
{ {
FT_UInt32 cur_pair; FT_UInt32 cur_pair;
cur_pair = FT_NEXT_ULONG(p);
cur_pair = FT_NEXT_ULONG( p );
if ( cur_pair <= old_pair ) if ( cur_pair <= old_pair )
break; break;
p += 2; p += 2;
old_pair = cur_pair; old_pair = cur_pair;
} }
if ( count == 0 ) if ( count == 0 )
ordered |= mask; ordered |= mask;
} }
@ -150,7 +156,7 @@
face->num_kern_tables = nn; face->num_kern_tables = nn;
face->kern_avail_bits = avail; face->kern_avail_bits = avail;
face->kern_order_bits = ordered; face->kern_order_bits = ordered;
Exit: Exit:
return error; return error;
} }
@ -160,7 +166,8 @@
tt_face_done_kern( TT_Face face ) tt_face_done_kern( TT_Face face )
{ {
FT_Stream stream = face->root.stream; FT_Stream stream = face->root.stream;
FT_FRAME_RELEASE( face->kern_table ); FT_FRAME_RELEASE( face->kern_table );
face->kern_table_size = 0; face->kern_table_size = 0;
face->num_kern_tables = 0; face->num_kern_tables = 0;
@ -179,6 +186,7 @@
FT_Byte* p = face->kern_table; FT_Byte* p = face->kern_table;
FT_Byte* p_limit = p + face->kern_table_size; FT_Byte* p_limit = p + face->kern_table_size;
p += 4; p += 4;
mask = 0x0001; mask = 0x0001;
@ -186,88 +194,95 @@
{ {
FT_Byte* base = p; FT_Byte* base = p;
FT_Byte* next = base; FT_Byte* next = base;
FT_UInt version = FT_NEXT_USHORT(p); FT_UInt version = FT_NEXT_USHORT( p );
FT_UInt length = FT_NEXT_USHORT(p); FT_UInt length = FT_NEXT_USHORT( p );
FT_UInt coverage = FT_NEXT_USHORT(p); FT_UInt coverage = FT_NEXT_USHORT( p );
FT_Int value = 0; FT_Int value = 0;
next = base + length; next = base + length;
if ( (face->kern_avail_bits & mask) == 0 ) if ( ( face->kern_avail_bits & mask ) == 0 )
goto NextTable; goto NextTable;
if ( p+8 > next ) if ( p + 8 > next )
goto NextTable; goto NextTable;
switch ( coverage >> 8 ) switch ( coverage >> 8 )
{ {
case 0: case 0:
{
FT_UInt num_pairs = FT_NEXT_USHORT( p );
FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph );
p += 6;
if ( face->kern_order_bits & mask ) /* binary search */
{ {
FT_UInt num_pairs = FT_NEXT_USHORT(p); FT_UInt min = 0;
FT_ULong key0 = TT_KERN_INDEX(left_glyph,right_glyph); FT_UInt max = num_pairs;
FT_Byte* q;
p += 6;
if ( face->kern_order_bits & mask ) /* binary search */
{
FT_UInt min = 0;
FT_UInt max = num_pairs;
FT_Byte* q;
while ( min < max )
{
FT_UInt mid = (min+max) >> 1;
FT_Byte* q = p + 6*mid;
FT_ULong key;
key = FT_NEXT_ULONG(q);
if ( key == key0 )
{
value = FT_PEEK_SHORT(q);
goto Found;
}
if ( key < key0 )
min = mid+1;
else
max = mid;
}
}
else /* linear search */
{
FT_UInt count = num_pairs;
for ( ; count > 0; count-- ) while ( min < max )
{
FT_UInt mid = ( min + max ) >> 1;
FT_Byte* q = p + 6 * mid;
FT_ULong key;
key = FT_NEXT_ULONG( q );
if ( key == key0 )
{ {
FT_ULong key = FT_NEXT_ULONG(p); value = FT_PEEK_SHORT( q );
goto Found;
if ( key == key0 )
{
value = FT_PEEK_SHORT(p);
goto Found;
}
p += 2;
} }
if ( key < key0 )
min = mid + 1;
else
max = mid;
} }
} }
break; else /* linear search */
{
FT_UInt count = num_pairs;
/* we don't support format 2 because we've never seen a single font
* using it in real life... for ( ; count > 0; count-- )
*/ {
FT_ULong key = FT_NEXT_ULONG( p );
if ( key == key0 )
{
value = FT_PEEK_SHORT( p );
goto Found;
}
p += 2;
}
}
}
break;
/*
* We don't support format 2 because we've never seen a single font
* using it in real life...
*/
default: default:
; ;
} }
goto NextTable; goto NextTable;
Found: Found:
if ( coverage & 8 ) /* overide or addition */ if ( coverage & 8 ) /* overide or add */
result = value; result = value;
else else
result += value; result += value;
NextTable: NextTable:
p = next; p = next;
} }
@ -276,8 +291,7 @@
return result; return result;
} }
#else /* !OPTIMIZE_MEMORY */
#else /* !OPTMIZE_MEMORY */
FT_CALLBACK_DEF( int ) FT_CALLBACK_DEF( int )
tt_kern_pair_compare( const void* a, tt_kern_pair_compare( const void* a,
@ -365,20 +379,20 @@
{ {
TT_Kern0_Pair pair0 = face->kern_pairs; TT_Kern0_Pair pair0 = face->kern_pairs;
FT_ULong prev = TT_KERN_INDEX( pair0->left, pair0->right ); FT_ULong prev = TT_KERN_INDEX( pair0->left, pair0->right );
for ( pair0++; pair0 < limit; pair0++ ) for ( pair0++; pair0 < limit; pair0++ )
{ {
FT_ULong next = TT_KERN_INDEX( pair0->left, pair0->right ); FT_ULong next = TT_KERN_INDEX( pair0->left, pair0->right );
if ( next < prev ) if ( next < prev )
goto SortIt; goto SortIt;
prev = next; prev = next;
} }
goto Exit; goto Exit;
SortIt: SortIt:
ft_qsort( (void*)face->kern_pairs, (int)num_pairs, ft_qsort( (void*)face->kern_pairs, (int)num_pairs,
sizeof ( TT_Kern0_PairRec ), tt_kern_pair_compare ); sizeof ( TT_Kern0_PairRec ), tt_kern_pair_compare );
@ -400,6 +414,7 @@
return error; return error;
} }
FT_CALLBACK_DEF( int ) FT_CALLBACK_DEF( int )
tt_kern_pair_compare( const void* a, tt_kern_pair_compare( const void* a,
const void* b ) const void* b )
@ -410,9 +425,9 @@
FT_ULong index1 = TT_KERN_INDEX( pair1->left, pair1->right ); FT_ULong index1 = TT_KERN_INDEX( pair1->left, pair1->right );
FT_ULong index2 = TT_KERN_INDEX( pair2->left, pair2->right ); FT_ULong index2 = TT_KERN_INDEX( pair2->left, pair2->right );
return index1 < index2 ? -1
return ( index1 < index2 ? -1 : : ( index1 > index2 ? 1
( index1 > index2 ? 1 : 0 )); : 0 );
} }
@ -420,17 +435,17 @@
tt_face_done_kern( TT_Face face ) tt_face_done_kern( TT_Face face )
{ {
FT_Memory memory = face->root.stream->memory; FT_Memory memory = face->root.stream->memory;
FT_FREE( face->kern_pairs ); FT_FREE( face->kern_pairs );
face->num_kern_pairs = 0; face->num_kern_pairs = 0;
} }
FT_LOCAL_DEF( FT_Int ) FT_LOCAL_DEF( FT_Int )
tt_face_get_kerning( TT_Face face, tt_face_get_kerning( TT_Face face,
FT_UInt left_glyph, FT_UInt left_glyph,
FT_UInt right_glyph ) FT_UInt right_glyph )
{ {
FT_Int result = 0; FT_Int result = 0;
TT_Kern0_Pair pair; TT_Kern0_Pair pair;
@ -477,5 +492,5 @@
#undef TT_KERN_INDEX #undef TT_KERN_INDEX
/* END */ /* END */

View File

@ -2,10 +2,10 @@
/* */ /* */
/* ttkern.h */ /* ttkern.h */
/* */ /* */
/* Load the basic TrueType kerning table. This doesn't handle */ /* Load the basic TrueType kerning table. This doesn't handle */
/* kerning data within the GPOS table at the moment. */ /* kerning data within the GPOS table at the moment. */
/* */ /* */
/* Copyright 1996-2001, 2002 by */ /* Copyright 1996-2001, 2002, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -42,11 +42,12 @@ FT_BEGIN_HEADER
FT_UInt right_glyph ); FT_UInt right_glyph );
#ifdef FT_OPTIMIZE_MEMORY #ifdef FT_OPTIMIZE_MEMORY
# define TT_FACE_HAS_KERNING(face) ((face)->kern_avail_bits != 0) # define TT_FACE_HAS_KERNING( face ) ( (face)->kern_avail_bits != 0 )
#else #else
# define TT_FACE_HAS_KERNING(face) ((face)->kern_pairs != NULL) # define TT_FACE_HAS_KERNING( face ) ( (face)->kern_pairs != NULL )
#endif #endif
FT_END_HEADER FT_END_HEADER
#endif /* __TTKERN_H__ */ #endif /* __TTKERN_H__ */

View File

@ -5,7 +5,7 @@
/* Load the basic TrueType tables, i.e., tables that can be either in */ /* Load the basic TrueType tables, i.e., tables that can be either in */
/* TTF or OTF fonts (body). */ /* TTF or OTF fonts (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -801,6 +801,7 @@
/* FreeType error code. 0 means success. */ /* FreeType error code. 0 means success. */
/* */ /* */
#ifdef FT_OPTIMIZE_MEMORY #ifdef FT_OPTIMIZE_MEMORY
static FT_Error static FT_Error
tt_face_load_metrics( TT_Face face, tt_face_load_metrics( TT_Face face,
FT_Stream stream, FT_Stream stream,
@ -822,7 +823,7 @@
ptable = &face->vert_metrics; ptable = &face->vert_metrics;
ptable_size = &face->vert_metrics_size; ptable_size = &face->vert_metrics_size;
/* The table is optional, quit silently if it wasn't found */ /* The table is optional, quit silently if it wasn't found. */
/* */ /* */
/* XXX: Some fonts have a valid vertical header with a non-null */ /* XXX: Some fonts have a valid vertical header with a non-null */
/* `number_of_VMetrics' fields, but no corresponding `vmtx' */ /* `number_of_VMetrics' fields, but no corresponding `vmtx' */
@ -849,10 +850,10 @@
{ {
#ifdef FT_CONFIG_OPTION_INCREMENTAL #ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font and there are */ /* If this is an incrementally loaded font and there are */
/* overriding metrics tolerate a missing 'hmtx' table. */ /* overriding metrics, tolerate a missing `hmtx' table. */
if ( face->root.internal->incremental_interface && if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs-> face->root.internal->incremental_interface->funcs->
get_glyph_metrics ) get_glyph_metrics )
{ {
face->horizontal.number_Of_HMetrics = 0; face->horizontal.number_Of_HMetrics = 0;
error = SFNT_Err_Ok; error = SFNT_Err_Ok;
@ -876,6 +877,7 @@
} }
#else /* !OPTIMIZE_MEMORY */ #else /* !OPTIMIZE_MEMORY */
static FT_Error static FT_Error
tt_face_load_metrics( TT_Face face, tt_face_load_metrics( TT_Face face,
FT_Stream stream, FT_Stream stream,
@ -897,7 +899,7 @@
if ( vertical ) if ( vertical )
{ {
/* The table is optional, quit silently if it wasn't found */ /* The table is optional, quit silently if it wasn't found. */
/* */ /* */
/* XXX: Some fonts have a valid vertical header with a non-null */ /* XXX: Some fonts have a valid vertical header with a non-null */
/* `number_of_VMetrics' fields, but no corresponding `vmtx' */ /* `number_of_VMetrics' fields, but no corresponding `vmtx' */
@ -927,10 +929,10 @@
#ifdef FT_CONFIG_OPTION_INCREMENTAL #ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font and there are */ /* If this is an incrementally loaded font and there are */
/* overriding metrics tolerate a missing 'hmtx' table. */ /* overriding metrics, tolerate a missing `hmtx' table. */
if ( face->root.internal->incremental_interface && if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs-> face->root.internal->incremental_interface->funcs->
get_glyph_metrics ) get_glyph_metrics )
{ {
face->horizontal.number_Of_HMetrics = 0; face->horizontal.number_Of_HMetrics = 0;
error = SFNT_Err_Ok; error = SFNT_Err_Ok;
@ -993,9 +995,9 @@
for ( ; cur < limit; cur++ ) for ( ; cur < limit; cur++ )
*cur = FT_GET_SHORT(); *cur = FT_GET_SHORT();
/* we fill up the missing left side bearings with the */ /* We fill up the missing left side bearings with the */
/* last valid value. Since this will occur for buggy CJK */ /* last valid value. Since this will occur for buggy CJK */
/* fonts usually only, nothing serious will happen */ /* fonts usually only, nothing serious will happen. */
if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 ) if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 )
{ {
FT_Short val = (*shorts)[num_shorts_checked - 1]; FT_Short val = (*shorts)[num_shorts_checked - 1];
@ -1014,8 +1016,10 @@
Exit: Exit:
return error; return error;
} }
#endif /* !FT_OPTIMIZE_METRICS */ #endif /* !FT_OPTIMIZE_METRICS */
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* <Function> */ /* <Function> */
@ -1704,6 +1708,7 @@
/* FreeType error code. 0 means success. */ /* FreeType error code. 0 means success. */
/* */ /* */
#ifdef FT_OPTIMIZE_MEMORY #ifdef FT_OPTIMIZE_MEMORY
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
tt_face_load_hdmx( TT_Face face, tt_face_load_hdmx( TT_Face face,
FT_Stream stream ) FT_Stream stream )
@ -1715,6 +1720,7 @@
FT_Byte* p; FT_Byte* p;
FT_Byte* limit; FT_Byte* limit;
/* this table is optional */ /* this table is optional */
error = face->goto_table( face, TTAG_hdmx, stream, &table_size ); error = face->goto_table( face, TTAG_hdmx, stream, &table_size );
if ( error || table_size < 8 ) if ( error || table_size < 8 )
@ -1726,9 +1732,9 @@
p = face->hdmx_table; p = face->hdmx_table;
limit = p + table_size; limit = p + table_size;
version = FT_NEXT_USHORT(p); version = FT_NEXT_USHORT( p );
num_records = FT_NEXT_USHORT(p); num_records = FT_NEXT_USHORT( p );
record_size = FT_NEXT_ULONG(p); record_size = FT_NEXT_ULONG( p );
if ( version != 0 || num_records > 255 || record_size > 0x40000 ) if ( version != 0 || num_records > 255 || record_size > 0x40000 )
{ {
@ -1741,7 +1747,7 @@
for ( nn = 0; nn < num_records; nn++ ) for ( nn = 0; nn < num_records; nn++ )
{ {
if ( p+record_size > limit ) if ( p + record_size > limit )
break; break;
face->hdmx_record_sizes[nn] = p[0]; face->hdmx_record_sizes[nn] = p[0];
@ -1767,11 +1773,13 @@
FT_Stream stream = face->root.stream; FT_Stream stream = face->root.stream;
FT_Memory memory = stream->memory; FT_Memory memory = stream->memory;
FT_FREE( face->hdmx_record_sizes ); FT_FREE( face->hdmx_record_sizes );
FT_FRAME_RELEASE( face->hdmx_table ); FT_FRAME_RELEASE( face->hdmx_table );
} }
#else /* !FT_OPTIMIZE_MEMORY */ #else /* !FT_OPTIMIZE_MEMORY */
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
tt_face_load_hdmx( TT_Face face, tt_face_load_hdmx( TT_Face face,
FT_Stream stream ) FT_Stream stream )
@ -1797,9 +1805,9 @@
if ( FT_FRAME_ENTER( 8L ) ) if ( FT_FRAME_ENTER( 8L ) )
goto Exit; goto Exit;
hdmx->version = FT_GET_USHORT(); hdmx->version = FT_GET_USHORT();
num_records = FT_GET_SHORT(); num_records = FT_GET_SHORT();
record_size = FT_GET_LONG(); record_size = FT_GET_LONG();
FT_FRAME_EXIT(); FT_FRAME_EXIT();
@ -1831,7 +1839,7 @@
FT_READ_BYTE( cur->max_width ) ) FT_READ_BYTE( cur->max_width ) )
goto Exit; goto Exit;
if ( FT_QALLOC( cur->widths, num_glyphs ) || if ( FT_QALLOC( cur->widths, num_glyphs ) ||
FT_STREAM_READ( cur->widths, num_glyphs ) ) FT_STREAM_READ( cur->widths, num_glyphs ) )
goto Exit; goto Exit;

View File

@ -5,7 +5,7 @@
/* Load the basic TrueType tables, i.e., tables that can be either in */ /* Load the basic TrueType tables, i.e., tables that can be either in */
/* TTF or OTF fonts (specification). */ /* TTF or OTF fonts (specification). */
/* */ /* */
/* Copyright 1996-2001, 2002 by */ /* Copyright 1996-2001, 2002, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */

View File

@ -4,7 +4,7 @@
/* */ /* */
/* TrueType and OpenType embedded bitmap support (body). */ /* TrueType and OpenType embedded bitmap support (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -584,12 +584,11 @@
} }
} }
/* now set up the root fields to indicate the strikes /* now set up the root fields to indicate the strikes */
*/
if ( face->num_sbit_strikes ) if ( face->num_sbit_strikes )
{ {
FT_ULong n; FT_ULong n;
FT_Face root = FT_FACE(face); FT_Face root = FT_FACE( face );
if ( FT_NEW_ARRAY( root->available_sizes, face->num_sbit_strikes ) ) if ( FT_NEW_ARRAY( root->available_sizes, face->num_sbit_strikes ) )
@ -608,9 +607,9 @@
/* assume 72dpi */ /* assume 72dpi */
bsize->height = bsize->height =
(FT_Short)( ( height * strike->y_ppem + fupem/2 ) / fupem ); (FT_Short)( ( height * strike->y_ppem + fupem / 2 ) / fupem );
bsize->width = bsize->width =
(FT_Short)( ( avg * strike->y_ppem + fupem/2 ) / fupem ); (FT_Short)( ( avg * strike->y_ppem + fupem / 2 ) / fupem );
bsize->size = strike->y_ppem << 6; bsize->size = strike->y_ppem << 6;
bsize->x_ppem = strike->x_ppem << 6; bsize->x_ppem = strike->x_ppem << 6;
bsize->y_ppem = strike->y_ppem << 6; bsize->y_ppem = strike->y_ppem << 6;
@ -1514,6 +1513,7 @@
return error; return error;
} }
#endif /* !OPTIMIZE_MEMORY */
/* END */ /* END */
#endif /* !OPTIMIZE_MEMORY */

View File

@ -1,10 +1,11 @@
/***************************************************************************/ /***************************************************************************/
/* */ /* */
/* ttsbit.c */ /* ttsbit0.c */
/* */ /* */
/* TrueType and OpenType embedded bitmap support (body). */ /* TrueType and OpenType embedded bitmap support (body). */
/* This is a heap-optimized version. */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -84,12 +85,11 @@
}; };
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
tt_face_load_sbit_strikes( TT_Face face, tt_face_load_sbit_strikes( TT_Face face,
FT_Stream stream ) FT_Stream stream )
{ {
FT_Error error = 0; FT_Error error = SFNT_Err_Ok;
FT_Memory memory = stream->memory; FT_Memory memory = stream->memory;
FT_Fixed version; FT_Fixed version;
FT_ULong num_strikes, table_size; FT_ULong num_strikes, table_size;
@ -98,6 +98,7 @@
FT_Byte* p_limit; FT_Byte* p_limit;
FT_UInt nn, count; FT_UInt nn, count;
face->sbit_num_strikes = 0; face->sbit_num_strikes = 0;
/* this table is optional */ /* this table is optional */
@ -109,7 +110,7 @@
if ( table_size < 8 ) if ( table_size < 8 )
{ {
FT_ERROR(( "%s: table too short !\n", "tt_face_load_sbit_strikes" )); FT_ERROR(( "%s: table too short!\n", "tt_face_load_sbit_strikes" ));
error = SFNT_Err_Invalid_File_Format; error = SFNT_Err_Invalid_File_Format;
goto Exit; goto Exit;
} }
@ -122,30 +123,32 @@
p = face->sbit_table; p = face->sbit_table;
p_limit = p + table_size; p_limit = p + table_size;
version = FT_NEXT_ULONG(p); version = FT_NEXT_ULONG( p );
num_strikes = FT_NEXT_ULONG(p); num_strikes = FT_NEXT_ULONG( p );
if ( version != 0x00020000 || num_strikes >= 0x10000UL ) if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
{ {
FT_ERROR(( "%s: invalid table version !\n", "tt_face_load_sbit_strikes" )); FT_ERROR(( "%s: invalid table version!\n",
"tt_face_load_sbit_strikes" ));
error = SFNT_Err_Invalid_File_Format; error = SFNT_Err_Invalid_File_Format;
goto Fail; goto Fail;
} }
/* count the number of strikes available in the table. we're a bit /*
* paranoid there and don't trust the data. * Count the number of strikes available in the table. We are a bit
*/ * paranoid there and don't trust the data.
*/
count = (FT_UInt)num_strikes; count = (FT_UInt)num_strikes;
if ( 8+48UL*count > table_size ) if ( 8 +48UL * count > table_size )
count = (FT_UInt)( (p_limit - p)/48 ); count = (FT_UInt)( ( p_limit - p ) / 48 );
face->sbit_num_strikes = count; face->sbit_num_strikes = count;
/* now allocate the root array of F_Bitmap_Size records, /*
* populate them, and that's all there is to it. Unfortunately, * Now allocate the root array of FT_Bitmap_Size records and
* it's not possible to indicate bit depths in the FT_Bitmap_Size * populate them. Unfortunately, it isn't possible to indicate bit
* record. What were we thinking ? * depths in the FT_Bitmap_Size record. This is a design error.
*/ */
{ {
FT_Memory memory = face->root.stream->memory; FT_Memory memory = face->root.stream->memory;
FT_UInt em_size = (FT_UInt) face->header.Units_Per_EM; FT_UInt em_size = (FT_UInt) face->header.Units_Per_EM;
@ -155,6 +158,7 @@
FT_Short avgwidth = face->os2.xAvgCharWidth; FT_Short avgwidth = face->os2.xAvgCharWidth;
if ( FT_NEW_ARRAY( face->root.available_sizes, count ) ) if ( FT_NEW_ARRAY( face->root.available_sizes, count ) )
goto Fail; goto Fail;
@ -163,14 +167,15 @@
FT_Bitmap_Size* bsize = face->root.available_sizes + nn; FT_Bitmap_Size* bsize = face->root.available_sizes + nn;
FT_UInt x_ppem, y_ppem; FT_UInt x_ppem, y_ppem;
x_ppem = p[44]; x_ppem = p[44];
y_ppem = p[45]; y_ppem = p[45];
bsize->x_ppem = (FT_Pos)(x_ppem << 6); bsize->x_ppem = (FT_Pos)(x_ppem << 6);
bsize->y_ppem = (FT_Pos)(y_ppem << 6); bsize->y_ppem = (FT_Pos)(y_ppem << 6);
bsize->height = (FT_Short)( height*y_ppem + em_size/2 ) / em_size; bsize->height = (FT_Short)( height*y_ppem + em_size / 2 ) / em_size;
bsize->width = (FT_Short)( avgwidth*y_ppem + em_size/2 ) / em_size; bsize->width = (FT_Short)( avgwidth*y_ppem + em_size / 2 ) / em_size;
bsize->size = bsize->y_ppem; bsize->size = bsize->y_ppem;
p += 48; p += 48;
@ -178,7 +183,6 @@
face->root.face_flags |= FT_FACE_FLAG_FIXED_SIZES; face->root.face_flags |= FT_FACE_FLAG_FIXED_SIZES;
face->root.num_fixed_sizes = count; face->root.num_fixed_sizes = count;
} }
Exit: Exit:
@ -196,6 +200,7 @@
{ {
FT_Stream stream = face->root.stream; FT_Stream stream = face->root.stream;
FT_FRAME_RELEASE( face->sbit_table ); FT_FRAME_RELEASE( face->sbit_table );
face->sbit_table_size = 0; face->sbit_table_size = 0;
face->sbit_num_strikes = 0; face->sbit_num_strikes = 0;
@ -212,13 +217,15 @@
FT_Byte* p; FT_Byte* p;
FT_Byte* p_limit; FT_Byte* p_limit;
if ( x_ppem > 255 ||
if ( x_ppem > 255 ||
y_ppem < 1 || y_ppem > 255 ) y_ppem < 1 || y_ppem > 255 )
return SFNT_Err_Invalid_PPem; return SFNT_Err_Invalid_PPem;
p = face->sbit_table + 8; p = face->sbit_table + 8;
p_limit = p + face->sbit_table_size; p_limit = p + face->sbit_table_size;
count = face->sbit_num_strikes; count = face->sbit_num_strikes;
for ( nn = 0; nn < count; nn++ ) for ( nn = 0; nn < count; nn++ )
{ {
if ( x_ppem == (FT_UInt)p[44] && y_ppem == (FT_UInt)p[45] ) if ( x_ppem == (FT_UInt)p[44] && y_ppem == (FT_UInt)p[45] )
@ -233,7 +240,6 @@
} }
typedef struct typedef struct
{ {
TT_Face face; TT_Face face;
@ -265,16 +271,17 @@
FT_Stream stream = face->root.stream; FT_Stream stream = face->root.stream;
FT_ULong ebdt_size; FT_ULong ebdt_size;
error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size ); error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
if ( error ) if ( error )
error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size ); error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
if (error) if ( error )
goto Exit; goto Exit;
decoder->face = face; decoder->face = face;
decoder->stream = stream; decoder->stream = stream;
decoder->bitmap = &face->root.glyph->bitmap; decoder->bitmap = &face->root.glyph->bitmap;
decoder->metrics = metrics; decoder->metrics = metrics;
decoder->metrics_loaded = 0; decoder->metrics_loaded = 0;
decoder->bitmap_allocated = 0; decoder->bitmap_allocated = 0;
@ -285,14 +292,14 @@
decoder->eblc_base = face->sbit_table; decoder->eblc_base = face->sbit_table;
decoder->eblc_limit = face->sbit_table + face->sbit_table_size; decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
/* now find the strike corresponding to the index /* now find the strike corresponding to the index */
*/
{ {
FT_Byte* p = decoder->eblc_base + 8 + 48*strike_index; FT_Byte* p = decoder->eblc_base + 8 + 48 * strike_index;
decoder->strike_index_array = FT_NEXT_ULONG(p);
decoder->strike_index_array = FT_NEXT_ULONG( p );
p += 4; p += 4;
decoder->strike_index_count = FT_NEXT_ULONG(p); decoder->strike_index_count = FT_NEXT_ULONG( p );
p += 34; p += 34;
decoder->bit_depth = *p; decoder->bit_depth = *p;
} }
@ -305,52 +312,52 @@
static void static void
tt_sbit_decoder_done( TT_SBitDecoder decoder ) tt_sbit_decoder_done( TT_SBitDecoder decoder )
{ {
FT_UNUSED(decoder); FT_UNUSED( decoder );
} }
static FT_Error static FT_Error
tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder )
{ {
FT_Error error = 0; FT_Error error = SFNT_Err_Ok;
FT_UInt width, height; FT_UInt width, height;
FT_Bitmap* map = decoder->bitmap; FT_Bitmap* map = decoder->bitmap;
FT_Long size; FT_Long size;
if ( !decoder->metrics_loaded ) if ( !decoder->metrics_loaded )
{ {
error = FT_Err_Invalid_Argument; error = SFNT_Err_Invalid_Argument;
goto Exit; goto Exit;
} }
width = decoder->metrics->width; width = decoder->metrics->width;
height = decoder->metrics->height; height = decoder->metrics->height;
map->width = (int) width; map->width = (int)width;
map->rows = (int) height; map->rows = (int)height;
switch ( decoder->bit_depth ) switch ( decoder->bit_depth )
{ {
case 1: case 1:
map->pixel_mode = FT_PIXEL_MODE_MONO; map->pixel_mode = FT_PIXEL_MODE_MONO;
map->pitch = ( map->width + 7 ) >> 3; map->pitch = ( map->width + 7 ) >> 3;
break; break;
case 2: case 2:
map->pixel_mode = FT_PIXEL_MODE_GRAY2; map->pixel_mode = FT_PIXEL_MODE_GRAY2;
map->pitch = ( map->width + 3 ) >> 2; map->pitch = ( map->width + 3 ) >> 2;
break; break;
case 4: case 4:
map->pixel_mode = FT_PIXEL_MODE_GRAY4; map->pixel_mode = FT_PIXEL_MODE_GRAY4;
map->pitch = ( map->width + 1 ) >> 1; map->pitch = ( map->width + 1 ) >> 1;
break; break;
case 8: case 8:
map->pixel_mode = FT_PIXEL_MODE_GRAY; map->pixel_mode = FT_PIXEL_MODE_GRAY;
map->pitch = map->width; map->pitch = map->width;
break; break;
default: default:
error = SFNT_Err_Invalid_File_Format; error = SFNT_Err_Invalid_File_Format;
@ -364,7 +371,7 @@
goto Exit; /* exit successfully! */ goto Exit; /* exit successfully! */
error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
if (error) if ( error )
goto Exit; goto Exit;
decoder->bitmap_allocated = 1; decoder->bitmap_allocated = 1;
@ -383,28 +390,29 @@
FT_Byte* p = *pp; FT_Byte* p = *pp;
TT_SBit_Metrics metrics = decoder->metrics; TT_SBit_Metrics metrics = decoder->metrics;
if ( p+5 > limit )
if ( p + 5 > limit )
goto Fail; goto Fail;
if ( !decoder->metrics_loaded ) if ( !decoder->metrics_loaded )
{ {
metrics->height = p[0]; metrics->height = p[0];
metrics->width = p[1]; metrics->width = p[1];
metrics->horiBearingX = (FT_Char) p[2]; metrics->horiBearingX = (FT_Char)p[2];
metrics->horiBearingY = (FT_Char) p[3]; metrics->horiBearingY = (FT_Char)p[3];
metrics->horiAdvance = p[4]; metrics->horiAdvance = p[4];
} }
p += 5; p += 5;
if ( big ) if ( big )
{ {
if ( p+3 > limit ) if ( p + 3 > limit )
goto Fail; goto Fail;
if ( !decoder->metrics_loaded ) if ( !decoder->metrics_loaded )
{ {
metrics->vertBearingX = (FT_Char) p[0]; metrics->vertBearingX = (FT_Char)p[0];
metrics->vertBearingY = (FT_Char) p[1]; metrics->vertBearingY = (FT_Char)p[1];
metrics->vertAdvance = p[2]; metrics->vertAdvance = p[2];
} }
@ -416,14 +424,11 @@
return 0; return 0;
Fail: Fail:
return FT_Err_Invalid_Argument; return SFNT_Err_Invalid_Argument;
} }
/* forward declaration */
/* forward declaration */
static FT_Error static FT_Error
tt_sbit_decoder_load_image( TT_SBitDecoder decoder, tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
FT_UInt glyph_index, FT_UInt glyph_index,
@ -437,8 +442,6 @@
FT_Int y_pos ); FT_Int y_pos );
static FT_Error static FT_Error
tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder,
FT_Byte* p, FT_Byte* p,
@ -446,21 +449,21 @@
FT_Int x_pos, FT_Int x_pos,
FT_Int y_pos ) FT_Int y_pos )
{ {
FT_Error error = 0; FT_Error error = SFNT_Err_Ok;
FT_Byte* line; FT_Byte* line;
FT_Int bit_height, bit_width, pitch, width, height, h; FT_Int bit_height, bit_width, pitch, width, height, h;
FT_Bitmap* bitmap; FT_Bitmap* bitmap;
FT_UInt rval; FT_UInt rval;
if ( !decoder->bitmap_allocated ) if ( !decoder->bitmap_allocated )
{ {
error = tt_sbit_decoder_alloc_bitmap( decoder ); error = tt_sbit_decoder_alloc_bitmap( decoder );
if (error) if ( error )
goto Exit; goto Exit;
} }
/* check that we can write the glyph into the bitmap /* check that we can write the glyph into the bitmap */
*/
bitmap = decoder->bitmap; bitmap = decoder->bitmap;
bit_width = bitmap->width; bit_width = bitmap->width;
bit_height = bitmap->rows; bit_height = bitmap->rows;
@ -469,22 +472,21 @@
width = decoder->metrics->width; width = decoder->metrics->width;
height = decoder->metrics->height; height = decoder->metrics->height;
if ( x_pos < 0 || x_pos+width > bit_width || if ( x_pos < 0 || x_pos + width > bit_width ||
y_pos < 0 || y_pos+height > bit_height ) y_pos < 0 || y_pos + height > bit_height )
{ {
error = FT_Err_Invalid_File_Format; error = SFNT_Err_Invalid_File_Format;
goto Exit; goto Exit;
} }
if ( p+((width+7)>>3)*height > limit ) if ( p + ( ( width + 7 ) >> 3 ) * height > limit )
{ {
error = FT_Err_Invalid_File_Format; error = SFNT_Err_Invalid_File_Format;
goto Exit; goto Exit;
} }
/* now do the blit /* now do the blit */
*/ line += y_pos * pitch + ( x_pos >> 3 );
line += y_pos*pitch + (x_pos >> 3);
x_pos &= 7; x_pos &= 7;
if ( x_pos == 0 ) /* the easy one */ if ( x_pos == 0 ) /* the easy one */
@ -494,14 +496,15 @@
FT_Byte* write = line; FT_Byte* write = line;
FT_Int w; FT_Int w;
for ( w = width; w >= 8; w -= 8 ) for ( w = width; w >= 8; w -= 8 )
{ {
write[0] = (FT_Byte)(write[0] | *p++); write[0] = (FT_Byte)( write[0] | *p++ );
write += 1; write += 1;
} }
if ( w > 0 ) if ( w > 0 )
write[0] = (FT_Byte)(write[0] | (*p++ & (0xFF00 >> w))); write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) );
} }
} }
else /* x_pos > 0 */ else /* x_pos > 0 */
@ -512,18 +515,19 @@
FT_Int w; FT_Int w;
FT_UInt wval = 0; FT_UInt wval = 0;
for ( w = width; w >= 8; w -= 8 ) for ( w = width; w >= 8; w -= 8 )
{ {
wval = (FT_UInt)(wval | *p++); wval = (FT_UInt)( wval | *p++ );
write[0] = (FT_Byte)(write[0] | (wval >> x_pos)); write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
write += 1; write += 1;
wval <<= 8; wval <<= 8;
} }
if ( w > 0 ) if ( w > 0 )
wval = (FT_UInt)(wval | (*p++ & (0xFF00 >> w))); wval = (FT_UInt)(wval | ( *p++ & ( 0xFF00U >> w ) ) );
write[0] = (FT_Byte)(write[0] | (wval >> x_pos)); write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
} }
} }
@ -539,21 +543,21 @@
FT_Int x_pos, FT_Int x_pos,
FT_Int y_pos ) FT_Int y_pos )
{ {
FT_Error error = 0; FT_Error error = SFNT_Err_Ok;
FT_Byte* line; FT_Byte* line;
FT_Int bit_height, bit_width, pitch, width, height, h; FT_Int bit_height, bit_width, pitch, width, height, h;
FT_Bitmap* bitmap; FT_Bitmap* bitmap;
FT_UInt32 rval; FT_UInt32 rval;
if ( !decoder->bitmap_allocated ) if ( !decoder->bitmap_allocated )
{ {
error = tt_sbit_decoder_alloc_bitmap( decoder ); error = tt_sbit_decoder_alloc_bitmap( decoder );
if (error) if ( error )
goto Exit; goto Exit;
} }
/* check that we can write the glyph into the bitmap /* check that we can write the glyph into the bitmap */
*/
bitmap = decoder->bitmap; bitmap = decoder->bitmap;
bit_width = bitmap->width; bit_width = bitmap->width;
bit_height = bitmap->rows; bit_height = bitmap->rows;
@ -562,24 +566,23 @@
width = decoder->metrics->width; width = decoder->metrics->width;
height = decoder->metrics->height; height = decoder->metrics->height;
if ( x_pos < 0 || x_pos+width > bit_width || if ( x_pos < 0 || x_pos + width > bit_width ||
y_pos < 0 || y_pos+height > bit_height ) y_pos < 0 || y_pos + height > bit_height )
{ {
error = FT_Err_Invalid_File_Format; error = SFNT_Err_Invalid_File_Format;
goto Exit; goto Exit;
} }
if ( p+((width+7)>>3)*height > limit ) if ( p + ( ( width + 7 ) >> 3 ) * height > limit )
{ {
error = FT_Err_Invalid_File_Format; error = SFNT_Err_Invalid_File_Format;
goto Exit; goto Exit;
} }
/* now do the blit /* now do the blit */
*/ line += y_pos * pitch + ( x_pos >> 3 );
line += y_pos*pitch + (x_pos >> 3);
x_pos &= 7; x_pos &= 7;
rval = 0x10000; rval = 0x10000UL;
for ( h = height; h > 0; h--, line += pitch ) for ( h = height; h > 0; h--, line += pitch )
{ {
@ -587,19 +590,20 @@
FT_UInt32 wval = 0x100 << x_pos; FT_UInt32 wval = 0x100 << x_pos;
FT_Int w; FT_Int w;
for ( w = width; w >= 8; w -= 8 ) for ( w = width; w >= 8; w -= 8 )
{ {
if ( rval & 0x10000 ) if ( rval & 0x10000UL )
rval = 0x100 | *p++; rval = 0x100 | *p++;
wval |= (rval & 0x80); wval |= rval & 0x80;
wval <<= 1; wval <<= 1;
rval <<= 1; rval <<= 1;
if ( wval & 0x10000 ) if ( wval & 0x10000UL )
{ {
write[0] = (FT_Byte)(write[0] | (wval >> 8)); write[0] = (FT_Byte)( write[0] | ( wval >> 8 ) );
write += 1; write += 1;
wval = 0x100; wval = 0x100;
} }
@ -610,7 +614,7 @@
while ( wval > 0x1FF ) while ( wval > 0x1FF )
wval >>= 1; wval >>= 1;
write[0] = (FT_Byte)(write[0] | wval); write[0] = (FT_Byte)( write[0] | wval );
} }
} }
@ -630,21 +634,23 @@
FT_UInt num_components, nn; FT_UInt num_components, nn;
if ( p+2 > limit ) if ( p + 2 > limit )
goto Fail; goto Fail;
num_components = FT_NEXT_USHORT(p); num_components = FT_NEXT_USHORT( p );
if ( p+4*num_components > limit ) if ( p + 4 * num_components > limit )
goto Fail; goto Fail;
for ( nn = 0; nn < num_components; nn++ ) for ( nn = 0; nn < num_components; nn++ )
{ {
FT_UInt gindex = FT_NEXT_USHORT(p); FT_UInt gindex = FT_NEXT_USHORT( p );
FT_Byte dx = FT_NEXT_BYTE(p); FT_Byte dx = FT_NEXT_BYTE( p );
FT_Byte dy = FT_NEXT_BYTE(p); FT_Byte dy = FT_NEXT_BYTE( p );
/* NB: a recursive call */ /* NB: a recursive call */
error = tt_sbit_decoder_load_image( decoder, gindex, x_pos+dx, y_pos+dy ); error = tt_sbit_decoder_load_image( decoder, gindex,
x_pos + dx, y_pos + dy );
if ( error ) if ( error )
break; break;
} }
@ -653,7 +659,7 @@
return error; return error;
Fail: Fail:
error = FT_Err_Invalid_File_Format; error = SFNT_Err_Invalid_File_Format;
goto Exit; goto Exit;
} }
@ -672,35 +678,38 @@
FT_Byte* p_limit; FT_Byte* p_limit;
FT_Byte* data; FT_Byte* data;
/* seek into the EBDT table now
*/ /* seek into the EBDT table now */
if ( glyph_start + glyph_size > decoder->ebdt_size ) if ( glyph_start + glyph_size > decoder->ebdt_size )
{ {
error = FT_Err_Invalid_Argument; error = SFNT_Err_Invalid_Argument;
goto Exit; goto Exit;
} }
if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) || if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
FT_FRAME_EXTRACT( glyph_size, data ) ) FT_FRAME_EXTRACT( glyph_size, data ) )
goto Exit; goto Exit;
p = data; p = data;
p_limit = p + glyph_size; p_limit = p + glyph_size;
/* read the data, depending on the glyph format /* read the data, depending on the glyph format */
*/
switch ( glyph_format ) switch ( glyph_format )
{ {
case 1: case 2: case 8: case 1:
case 2:
case 8:
error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 ); error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
break; break;
case 6: case 7: case 9: case 6:
case 7:
case 9:
error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ); error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
break; break;
default: default:
error = 0; error = SFNT_Err_Ok;
} }
if ( error ) if ( error )
@ -709,29 +718,33 @@
{ {
TT_SBitDecoder_LoadFunc loader; TT_SBitDecoder_LoadFunc loader;
switch ( glyph_format ) switch ( glyph_format )
{ {
case 1: case 6: case 1:
loader = tt_sbit_decoder_load_byte_aligned; case 6:
break; loader = tt_sbit_decoder_load_byte_aligned;
break;
case 2: case 5: case 7: case 2:
loader = tt_sbit_decoder_load_bit_aligned; case 5:
break; case 7:
loader = tt_sbit_decoder_load_bit_aligned;
break;
case 8: case 8:
if ( p+1 > p_limit ) if ( p + 1 > p_limit )
goto Fail; goto Fail;
p += 1; /* skip padding */ p += 1; /* skip padding */
/* fall-through */ /* fall-through */
case 9: case 9:
loader = tt_sbit_decoder_load_compound; loader = tt_sbit_decoder_load_compound;
break; break;
default: default:
goto Fail; goto Fail;
} }
error = loader( decoder, p, p_limit, x_pos, y_pos ); error = loader( decoder, p, p_limit, x_pos, y_pos );
@ -751,22 +764,25 @@
FT_Int x_pos, FT_Int x_pos,
FT_Int y_pos ) FT_Int y_pos )
{ {
/* first, we find the correct strike range that applies to this /*
* glyph index. * First, we find the correct strike range that applies to this
*/ * glyph index.
*/
FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; FT_Byte* p = decoder->eblc_base + decoder->strike_index_array;
FT_Byte* p_limit = decoder->eblc_limit; FT_Byte* p_limit = decoder->eblc_limit;
FT_ULong num_ranges = decoder->strike_index_count; FT_ULong num_ranges = decoder->strike_index_count;
FT_UInt start, end, offset, index_format, image_format; FT_UInt start, end, offset, index_format, image_format;
FT_ULong image_start, image_end, image_offset; FT_ULong image_start, image_end, image_offset;
if ( p+8*num_ranges > p_limit )
if ( p + 8 * num_ranges > p_limit )
goto NoBitmap; goto NoBitmap;
for ( ; num_ranges > 0; num_ranges-- ) for ( ; num_ranges > 0; num_ranges-- )
{ {
start = FT_NEXT_USHORT(p); start = FT_NEXT_USHORT( p );
end = FT_NEXT_USHORT(p); end = FT_NEXT_USHORT( p );
if ( glyph_index >= start && glyph_index <= end ) if ( glyph_index >= start && glyph_index <= end )
goto FoundRange; goto FoundRange;
@ -776,128 +792,131 @@
goto NoBitmap; goto NoBitmap;
FoundRange: FoundRange:
p = decoder->eblc_base + decoder->strike_index_array + FT_NEXT_ULONG(p); p = decoder->eblc_base + decoder->strike_index_array + FT_NEXT_ULONG( p );
if ( p+8 > p_limit ) if ( p + 8 > p_limit )
goto NoBitmap; goto NoBitmap;
/* now, we're going to find the glyph's location and extend within /* now find the glyph's location and extend within the ebdt table */
* the ebdt table index_format = FT_NEXT_USHORT( p );
*/ image_format = FT_NEXT_USHORT( p );
index_format = FT_NEXT_USHORT(p); image_offset = FT_NEXT_ULONG ( p );
image_format = FT_NEXT_USHORT(p);
image_offset = FT_NEXT_ULONG(p);
switch ( index_format ) switch ( index_format )
{ {
case 1: /* 4-byte offsets relative to 'image_offset' */ case 1: /* 4-byte offsets relative to `image_offset' */
{ {
p += 4*(glyph_index-start); p += 4 * ( glyph_index - start );
if ( p+8 > p_limit ) if ( p + 8 > p_limit )
goto NoBitmap; goto NoBitmap;
image_start = FT_NEXT_ULONG(p); image_start = FT_NEXT_ULONG( p );
image_end = FT_NEXT_ULONG(p); image_end = FT_NEXT_ULONG( p );
if ( image_start == image_end ) /* missing glyph */ if ( image_start == image_end ) /* missing glyph */
goto NoBitmap; goto NoBitmap;
} }
break; break;
case 2: /* big metrics, constant image size */ case 2: /* big metrics, constant image size */
{ {
FT_ULong image_size; FT_ULong image_size;
if ( p+12 > p_limit )
goto NoBitmap;
image_size = FT_NEXT_ULONG(p); if ( p + 12 > p_limit )
goto NoBitmap;
if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) image_size = FT_NEXT_ULONG( p );
goto NoBitmap;
image_start = image_offset + image_size*(glyph_index-start); if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
image_end = image_start + image_size; goto NoBitmap;
}
break; image_start = image_offset + image_size * ( glyph_index - start );
image_end = image_start + image_size;
}
break;
case 3: /* 2-byte offsets relative to 'image_offset' */ case 3: /* 2-byte offsets relative to 'image_offset' */
{ {
p += 2*(glyph_index-start); p += 2 * ( glyph_index - start );
if ( p+4 > p_limit ) if ( p + 4 > p_limit )
goto NoBitmap; goto NoBitmap;
image_start = FT_NEXT_USHORT(p); image_start = FT_NEXT_USHORT( p );
image_end = FT_NEXT_USHORT(p); image_end = FT_NEXT_USHORT( p );
if ( image_start == image_end ) /* missing glyph */ if ( image_start == image_end ) /* missing glyph */
goto NoBitmap; goto NoBitmap;
} }
break; break;
case 4: /* sparse glyph array with (glyph,offset) pairs */ case 4: /* sparse glyph array with (glyph,offset) pairs */
{
FT_ULong mm, num_glyphs;
if ( p + 4 > p_limit )
goto NoBitmap;
num_glyphs = FT_NEXT_ULONG( p );
if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
goto NoBitmap;
for ( mm = 0; mm < num_glyphs; mm++ )
{ {
FT_ULong mm, num_glyphs; FT_UInt gindex = FT_NEXT_USHORT( p );
if ( p+4 > p_limit )
goto NoBitmap;
num_glyphs = FT_NEXT_ULONG(p); if ( gindex == glyph_index )
if ( p+(num_glyphs+1)*4 > p_limit )
goto NoBitmap;
for ( mm = 0; mm < num_glyphs; mm++ )
{ {
FT_UInt gindex = FT_NEXT_USHORT(p); image_start = FT_NEXT_USHORT( p );
p += 2;
if ( gindex == glyph_index ) image_end = FT_PEEK_USHORT( p );
{ break;
image_start = FT_NEXT_USHORT(p);
p += 2;
image_end = FT_PEEK_USHORT(p);
break;
}
p += 2;
} }
p += 2;
if ( mm >= num_glyphs )
goto NoBitmap;
} }
break;
if ( mm >= num_glyphs )
goto NoBitmap;
}
break;
case 5: /* constant metrics with sparse glyph codes */ case 5: /* constant metrics with sparse glyph codes */
{
FT_ULong image_size, mm, num_glyphs;
if ( p + 16 > p_limit )
goto NoBitmap;
image_size = FT_NEXT_ULONG( p );
if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
goto NoBitmap;
num_glyphs = FT_NEXT_ULONG( p );
if ( p + 2 * num_glyphs > p_limit )
goto NoBitmap;
for ( mm = 0; mm < num_glyphs; mm++ )
{ {
FT_ULong image_size, mm, num_glyphs; FT_UInt gindex = FT_NEXT_USHORT( p );
if ( p+16 > p_limit )
goto NoBitmap;
image_size = FT_NEXT_ULONG(p); if ( gindex == glyph_index )
break;
if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
goto NoBitmap;
num_glyphs = FT_NEXT_ULONG(p);
if ( p + 2*num_glyphs > p_limit )
goto NoBitmap;
for ( mm = 0; mm < num_glyphs; mm++ )
{
FT_UInt gindex = FT_NEXT_USHORT(p);
if ( gindex == glyph_index )
break;
}
if ( mm >= num_glyphs )
goto NoBitmap;
image_start = image_offset + image_size*mm;
image_end = image_start + image_size;
} }
break;
if ( mm >= num_glyphs )
goto NoBitmap;
image_start = image_offset + image_size*mm;
image_end = image_start + image_size;
}
break;
default: default:
goto NoBitmap; goto NoBitmap;
} }
if ( image_start > image_end ) if ( image_start > image_end )
@ -906,20 +925,18 @@
image_end -= image_start; image_end -= image_start;
image_start = image_offset + image_start; image_start = image_offset + image_start;
return tt_sbit_decoder_load_bitmap( decoder, return tt_sbit_decoder_load_bitmap( decoder,
image_format, image_format,
image_offset + image_start, image_offset + image_start,
image_end, image_end,
x_pos, x_pos,
y_pos ); y_pos );
NoBitmap: NoBitmap:
return FT_Err_Invalid_Argument; return SFNT_Err_Invalid_Argument;
} }
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
tt_face_load_sbit_image( TT_Face face, tt_face_load_sbit_image( TT_Face face,
FT_ULong strike_index, FT_ULong strike_index,
@ -932,6 +949,7 @@
TT_SBitDecoderRec decoder[1]; TT_SBitDecoderRec decoder[1];
FT_Error error; FT_Error error;
error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
if ( !error ) if ( !error )
{ {
@ -941,3 +959,5 @@
return error; return error;
} }
/* EOF */

View File

@ -4,7 +4,7 @@
/* */ /* */
/* TrueType font driver implementation (body). */ /* TrueType font driver implementation (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -100,12 +100,13 @@
/* */ /* */
static FT_Error static FT_Error
tt_get_kerning( FT_Face ttface, /* TT_Face */ tt_get_kerning( FT_Face ttface, /* TT_Face */
FT_UInt left_glyph, FT_UInt left_glyph,
FT_UInt right_glyph, FT_UInt right_glyph,
FT_Vector* kerning ) FT_Vector* kerning )
{ {
TT_Face face = (TT_Face)ttface; TT_Face face = (TT_Face)ttface;
SFNT_Service sfnt = (SFNT_Service) face->sfnt; SFNT_Service sfnt = (SFNT_Service)face->sfnt;
kerning->x = 0; kerning->x = 0;
kerning->y = 0; kerning->y = 0;

View File

@ -4,7 +4,7 @@
/* */ /* */
/* TrueType Glyph Loader (body). */ /* TrueType Glyph Loader (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -97,18 +97,20 @@
/* near future, but I haven't decided which yet. */ /* near future, but I haven't decided which yet. */
/* */ /* */
#ifdef FT_OPTIMIZE_MEMORY #ifdef FT_OPTIMIZE_MEMORY
static void static void
tt_face_get_metrics( TT_Face face, tt_face_get_metrics( TT_Face face,
FT_Bool vertical, FT_Bool vertical,
FT_UInt idx, FT_UInt idx,
FT_Short *abearing, FT_Short *abearing,
FT_UShort *aadvance ) FT_UShort *aadvance )
{ {
TT_HoriHeader* header; TT_HoriHeader* header;
FT_Byte* p; FT_Byte* p;
FT_Byte* limit; FT_Byte* limit;
FT_UShort k; FT_UShort k;
if ( vertical ) if ( vertical )
{ {
header = (TT_HoriHeader*)&face->vertical; header = (TT_HoriHeader*)&face->vertical;
@ -128,25 +130,25 @@
{ {
if ( idx < (FT_UInt)k ) if ( idx < (FT_UInt)k )
{ {
p += 4*idx; p += 4 * idx;
if ( p+4 >= limit ) if ( p + 4 >= limit )
goto NoData; goto NoData;
*aadvance = FT_NEXT_USHORT(p); *aadvance = FT_NEXT_USHORT( p );
*abearing = FT_NEXT_SHORT(p); *abearing = FT_NEXT_SHORT( p );
} }
else else
{ {
p += 4*(k-1); p += 4 * ( k - 1 );
if ( p+4 > limit ) if ( p + 4 > limit )
goto NoData; goto NoData;
*aadvance = FT_NEXT_USHORT(p); *aadvance = FT_NEXT_USHORT( p );
p += 2 + 2*(idx-k); p += 2 + 2 * ( idx - k );
if ( p+2 > limit ) if ( p + 2 > limit )
*abearing = 0; *abearing = 0;
else else
*abearing = FT_PEEK_SHORT(p); *abearing = FT_PEEK_SHORT( p );
} }
} }
else else
@ -156,18 +158,20 @@
*aadvance = 0; *aadvance = 0;
} }
} }
#else
#else /* !FT_OPTIMIZE_MEMORY */
static void static void
tt_face_get_metrics( TT_Face face, tt_face_get_metrics( TT_Face face,
FT_Bool vertical, FT_Bool vertical,
FT_UInt idx, FT_UInt idx,
FT_Short *abearing, FT_Short *abearing,
FT_UShort *aadvance ) FT_UShort *aadvance )
{ {
TT_HoriHeader* header = (vertical ? (TT_HoriHeader*)&face->vertical TT_HoriHeader* header = vertical ? (TT_HoriHeader*)&face->vertical
: &face->horizontal); : &face->horizontal;
TT_LongMetrics longs_m; TT_LongMetrics longs_m;
FT_UShort k = header->number_Of_HMetrics; FT_UShort k = header->number_Of_HMetrics;
if ( k == 0 ) if ( k == 0 )
@ -178,17 +182,18 @@
if ( idx < (FT_UInt)k ) if ( idx < (FT_UInt)k )
{ {
longs_m = (TT_LongMetrics )header->long_metrics + idx; longs_m = (TT_LongMetrics)header->long_metrics + idx;
*abearing = longs_m->bearing; *abearing = longs_m->bearing;
*aadvance = longs_m->advance; *aadvance = longs_m->advance;
} }
else else
{ {
*abearing = ((TT_ShortMetrics*)header->short_metrics)[idx - k]; *abearing = ((TT_ShortMetrics*)header->short_metrics)[idx - k];
*aadvance = ((TT_LongMetrics )header->long_metrics)[k - 1].advance; *aadvance = ((TT_LongMetrics)header->long_metrics)[k - 1].advance;
} }
} }
#endif
#endif /* !FT_OPTIMIZE_MEMORY */
/*************************************************************************/ /*************************************************************************/
@ -222,11 +227,13 @@
FT_UInt gindex ) FT_UInt gindex )
{ {
#ifdef FT_OPTIMIZE_MEMORY #ifdef FT_OPTIMIZE_MEMORY
FT_UInt nn; FT_UInt nn;
FT_Byte* result = NULL; FT_Byte* result = NULL;
FT_ULong record_size = face->hdmx_record_size; FT_ULong record_size = face->hdmx_record_size;
FT_Byte* record = face->hdmx_table + 8; FT_Byte* record = face->hdmx_table + 8;
for ( nn = 0; nn < face->hdmx_record_count; nn++ ) for ( nn = 0; nn < face->hdmx_record_count; nn++ )
if ( face->hdmx_record_sizes[nn] == ppem ) if ( face->hdmx_record_sizes[nn] == ppem )
{ {
@ -237,7 +244,9 @@
} }
return result; return result;
#else #else
FT_UShort n; FT_UShort n;
@ -246,6 +255,7 @@
return &face->hdmx.records[n].widths[gindex]; return &face->hdmx.records[n].widths[gindex];
return NULL; return NULL;
#endif #endif
} }

View File

@ -4,7 +4,7 @@
/* */ /* */
/* TrueType Glyph Loader (specification). */ /* TrueType Glyph Loader (specification). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */

View File

@ -4,7 +4,7 @@
/* */ /* */
/* Objects manager (body). */ /* Objects manager (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -750,19 +750,21 @@
if ( !error ) if ( !error )
{ {
/* XXX: TODO: move this code to the SFNT module where it belongs */ /* XXX: TODO: move this code to the SFNT module where it belongs */
#ifdef FT_OPTIMIZE_MEMORY #ifdef FT_OPTIMIZE_MEMORY
FT_Byte* strike = face->sbit_table + 8 + strike_index*48; FT_Byte* strike = face->sbit_table + 8 + strike_index*48;
sbit_metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ sbit_metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */
sbit_metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ sbit_metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */
/* XXX: Is this correct? */ /* XXX: Is this correct? */
sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */
strike[18] + /* max_width */ strike[18] + /* max_width */
(FT_Char)strike[23] /* min_advance_SB */ (FT_Char)strike[23] /* min_advance_SB */
) << 6; ) << 6;
#else /* !OPTIMIZE_MEMORY */ #else /* !FT_OPTIMIZE_MEMORY */
TT_SBit_Strike strike = face->sbit_strikes + strike_index; TT_SBit_Strike strike = face->sbit_strikes + strike_index;
@ -773,7 +775,8 @@
sbit_metrics->max_advance = ( strike->hori.min_origin_SB + sbit_metrics->max_advance = ( strike->hori.min_origin_SB +
strike->hori.max_width + strike->hori.max_width +
strike->hori.min_advance_SB ) << 6; strike->hori.min_advance_SB ) << 6;
#endif /* !OPTIMIZE_MEMORY */
#endif /* !FT_OPTIMIZE_MEMORY */
/* XXX: Is this correct? */ /* XXX: Is this correct? */
sbit_metrics->height = sbit_metrics->ascender - sbit_metrics->height = sbit_metrics->ascender -

View File

@ -4,7 +4,7 @@
/* */ /* */
/* TrueType glyph data/program tables loader (body). */ /* TrueType glyph data/program tables loader (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2004 by */ /* Copyright 1996-2001, 2002, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -79,29 +79,29 @@
if ( face->header.Index_To_Loc_Format != 0 ) if ( face->header.Index_To_Loc_Format != 0 )
{ {
if ( table_len >= 040000 ) if ( table_len >= 0x40000 )
{ {
FT_TRACE2(( "table too large !!\n" )); FT_TRACE2(( "table too large!\n" ));
error = TT_Err_Invalid_Table; error = TT_Err_Invalid_Table;
goto Exit; goto Exit;
} }
face->num_locations = (FT_UInt)(table_len >> 2); face->num_locations = (FT_UInt)( table_len >> 2 );
} }
else else
{ {
if ( table_len >= 0x20000 ) if ( table_len >= 0x20000 )
{ {
FT_TRACE2(( "table too large !!\n" )); FT_TRACE2(( "table too large!\n" ));
error = TT_Err_Invalid_Table; error = TT_Err_Invalid_Table;
goto Exit; goto Exit;
} }
face->num_locations = (FT_UInt)(table_len >> 1); face->num_locations = (FT_UInt)( table_len >> 1 );
} }
/*
/* extract the frame. We don't need to decompress it since * Extract the frame. We don't need to decompress it since
* we'll be able to parse it directly * we are able to parse it directly.
*/ */
if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) ) if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) )
goto Exit; goto Exit;
@ -113,45 +113,47 @@
FT_LOCAL_DEF( FT_ULong ) FT_LOCAL_DEF( FT_ULong )
tt_face_get_location( TT_Face face, tt_face_get_location( TT_Face face,
FT_UInt gindex, FT_UInt gindex,
FT_UInt *asize ) FT_UInt *asize )
{ {
FT_ULong pos1, pos2; FT_ULong pos1, pos2;
FT_Byte* p; FT_Byte* p;
FT_Byte* p_limit; FT_Byte* p_limit;
pos1 = pos2 = 0; pos1 = pos2 = 0;
if ( gindex < face->num_locations ) if ( gindex < face->num_locations )
{ {
if ( face->header.Index_To_Loc_Format != 0 ) if ( face->header.Index_To_Loc_Format != 0 )
{ {
p = face->glyph_locations + gindex*4; p = face->glyph_locations + gindex * 4;
p_limit = face->glyph_locations + face->num_locations*4; p_limit = face->glyph_locations + face->num_locations * 4;
pos1 = FT_NEXT_ULONG(p); pos1 = FT_NEXT_ULONG( p );
pos2 = pos1; pos2 = pos1;
if ( p+4 <= p_limit ) if ( p + 4 <= p_limit )
pos2 = FT_NEXT_ULONG(p); pos2 = FT_NEXT_ULONG( p );
} }
else else
{ {
p = face->glyph_locations + gindex*2; p = face->glyph_locations + gindex * 2;
p_limit = face->glyph_locations + face->num_locations*2; p_limit = face->glyph_locations + face->num_locations * 2;
pos1 = FT_NEXT_USHORT(p); pos1 = FT_NEXT_USHORT( p );
pos2 = pos1; pos2 = pos1;
if ( p+2 <= p_limit ) if ( p + 2 <= p_limit )
pos2 = FT_NEXT_USHORT(p); pos2 = FT_NEXT_USHORT( p );
pos1 <<= 1; pos1 <<= 1;
pos2 <<= 1; pos2 <<= 1;
} }
} }
*asize = (FT_UInt)(pos2 - pos1); *asize = (FT_UInt)( pos2 - pos1 );
return pos1; return pos1;
} }
@ -160,16 +162,17 @@
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
tt_face_done_loca( TT_Face face ) tt_face_done_loca( TT_Face face )
{ {
FT_Stream stream = face->root.stream; FT_Stream stream = face->root.stream;
FT_FRAME_RELEASE( face->glyph_locations ); FT_FRAME_RELEASE( face->glyph_locations );
face->num_locations = 0; face->num_locations = 0;
} }
#else /* !FT_OPTIMIZE_MEMORY */ #else /* !FT_OPTIMIZE_MEMORY */
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
tt_face_load_loca( TT_Face face, tt_face_load_loca( TT_Face face,
FT_Stream stream ) FT_Stream stream )
@ -224,6 +227,7 @@
if ( FT_FRAME_ENTER( face->num_locations * 2L ) ) if ( FT_FRAME_ENTER( face->num_locations * 2L ) )
goto Exit; goto Exit;
{ {
FT_Long* loc = face->glyph_locations; FT_Long* loc = face->glyph_locations;
FT_Long* limit = loc + face->num_locations; FT_Long* limit = loc + face->num_locations;
@ -232,6 +236,7 @@
for ( ; loc < limit; loc++ ) for ( ; loc < limit; loc++ )
*loc = (FT_Long)( (FT_ULong)FT_GET_USHORT() * 2 ); *loc = (FT_Long)( (FT_ULong)FT_GET_USHORT() * 2 );
} }
FT_FRAME_EXIT(); FT_FRAME_EXIT();
} }
@ -243,13 +248,14 @@
FT_LOCAL_DEF( FT_ULong ) FT_LOCAL_DEF( FT_ULong )
tt_face_get_location( TT_Face face, tt_face_get_location( TT_Face face,
FT_UInt gindex, FT_UInt gindex,
FT_UInt *asize ) FT_UInt *asize )
{ {
FT_ULong offset; FT_ULong offset;
FT_UInt count; FT_UInt count;
offset = face->glyph_locations[gindex]; offset = face->glyph_locations[gindex];
count = 0; count = 0;
@ -264,14 +270,14 @@
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
tt_face_done_loca( TT_Face face ) tt_face_done_loca( TT_Face face )
{ {
FT_Memory memory = face->root.memory; FT_Memory memory = face->root.memory;
FT_FREE( face->glyph_locations ); FT_FREE( face->glyph_locations );
face->num_locations = 0; face->num_locations = 0;
} }
#endif /* !FT_OPTIMIZE_MEMORY */ #endif /* !FT_OPTIMIZE_MEMORY */
@ -345,10 +351,13 @@
Exit: Exit:
return error; return error;
#else /* !BYTECODE_INTERPRETER */ #else /* !FT_CONFIG_OPTION_BYTECODE_INTERPRETER */
FT_UNUSED(face);
FT_UNUSED(stream); FT_UNUSED( face );
FT_UNUSED( stream );
return 0; return 0;
#endif #endif
} }
@ -423,10 +432,13 @@
Exit: Exit:
return error; return error;
#else /* !BYTECODE_INTERPRETER */ #else /* !FT_CONFIG_OPTION_BYTECODE_INTERPRETER */
FT_UNUSED(face);
FT_UNUSED(stream); FT_UNUSED( face );
FT_UNUSED( stream );
return 0; return 0;
#endif #endif
} }

View File

@ -4,7 +4,7 @@
/* */ /* */
/* TrueType glyph data/program tables loader (specification). */ /* TrueType glyph data/program tables loader (specification). */
/* */ /* */
/* Copyright 1996-2001, 2002 by */ /* Copyright 1996-2001, 2002, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -32,9 +32,9 @@ FT_BEGIN_HEADER
FT_Stream stream ); FT_Stream stream );
FT_LOCAL( FT_ULong ) FT_LOCAL( FT_ULong )
tt_face_get_location( TT_Face face, tt_face_get_location( TT_Face face,
FT_UInt gindex, FT_UInt gindex,
FT_UInt *asize ); FT_UInt *asize );
FT_LOCAL( void ) FT_LOCAL( void )
tt_face_done_loca( TT_Face face ); tt_face_done_loca( TT_Face face );