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>
* src/base/ftdbgmem.c (FT_DumpMemory): added sorting of memory sources
according to decreasing maximum cumulative allocations.
* 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
heap-optimized embedded bitmap loader. This one also fixes bug #12107
* src/sfnt/sfobjs.c: fixed bug that prevented loading SFNT fonts without
a 'kern' table.
* src/base/ftdbgmem.c (FT_DumpMemory): Added sorting of memory
sources according to decreasing maximum cumulative allocations.
(ft_mem_source_compare): New auxiliary function.
* src/sfnt/ttsbit0.c: New file, implementing a heap-optimized
embedded bitmap loader.
* src/sfnt/ttsbit.c: Include `ft2build.h', FT_INTERNAL_DEBUG_H,
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>
* src/sfnt/ttkern.c (tt_face_load_kern): fixing a small bug which returned
invalid (random) values for the horizontal kerning
* src/sfnt/ttkern.c (tt_face_load_kern): Fix a small bug which
caused invalid (random) return values for the horizontal kerning.
2005-02-25 David Turner <david@freetype.org>
* many, many files: several memory optimizations were implemented to
drastically reduce the heap usage of FreeType, especially in the case
of memory-mapped files. The idea is to avoid loading and decoding tables
in the heap, and instead access the raw data whenever possible (i.e.
when it doesn't compromise performance).
This had several impacts: first, opening vera.ttf uses a ridiculous amount
of memory (when the FT_Library footprint is accounted for), until you start
loading glyphs. Even then, you'll save at least 20 Kb compared to the non
optimized case. performance of various operations, including open/close
has also been dramatically improved.
More optimisations to come. The auto-hinter eats memory like crazy? This
must be stopped...
Implement several memory optimizations to drastically reduce the
heap usage of FreeType, especially in the case of memory-mapped
files. The idea is to avoid loading and decoding tables in the
heap, and instead access the raw data whenever possible (i.e., when
it doesn't compromise performance).
This has several benefits: For example, opening vera.ttf now uses
just a small amount of memory (even when the FT_Library footprint is
accounted for), until you start loading glyphs. Even then, you save
at least 20KB compared to the non-optimized case. Performance of
various operations, including open and close, has also been
dramatically improved.
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>
* src/base/ftdbgmem.c: adding the ability to list all allocation sites
in the memory debugger. Also a new function FT_DumpMemory() was added.
It is only available in builds with FT_DEBUG_MEMORY defined, and you
must declare it in your own code to use it, i.e. with something
like:
* src/base/ftdbgmem.c: Partly rewritten. Added the ability to list
all allocation sites in the memory debugger. Also a new function
FT_DumpMemory() was added. It is only available in builds with
FT_DEBUG_MEMORY defined, and you must declare it in your own code to
use it, i.e., with something like:
extern void FT_DumpMemory( FT_Memory );
@ -47,26 +165,39 @@
FT_DumpMemory( memory );
* include/freetype/config/ftoptions.h: disabling TrueType bytecode
interpreter !
* include/freetype/config/ftoption.h
(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.
* include/freetype/config/ftoption.h, include/freetype/internal/ttypes.h,
src/truetype/ttpload.c, src/truetype/ttpload.h, src/truetype/ttgload.c:
added the temporary configuration FT_OPTIMIZE_MEMORY to control various
optimizations used to reduce the heap footprint of memory-mapped TrueType
files.
* include/freetype/internal/tttypes.h (TT_FaceRec)
[FT_OPTIMIZE_MEMORY]: Use optimized types for `num_locations' and
`glyph_locations'.
* src/truetype/ttpload.c (tt_face_load_loca, tt_face_get_location,
tt_face_done_loca): when FT_OPTIMIZE_MEMORY is set, the locations table
is read directly from memory-mapped streams, instead of being decoded
into the heap.
* src/truetype/ttgload.c (load_truetype_glyph): Call
`tt_face_get_location'.
* src/truetype/ttpload.c: only load the CVT and fpgm tables when the
bytecode interpreter is compiled in.
* src/truetype/ttobjs.c (tt_face_init)
[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>

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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 */
#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

View File

@ -4,7 +4,7 @@
/* */
/* 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 */
/* */
/* 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_ARRAY_ZERO( dest, count ) \
FT_MEM_ZERO( dest, (count)*sizeof( *(dest) ) )
#define FT_ARRAY_ZERO( dest, count ) \
FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) )
#define FT_ARRAY_COPY( dest, source, count ) \
FT_MEM_COPY( dest, source, (count) * sizeof( *(dest) ) )
#define FT_ARRAY_COPY( dest, source, count ) \
FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) )
#define FT_ARRAY_MOVE( dest, source, count ) \
FT_MEM_MOVE( dest, source, (count) * sizeof( *(dest) ) )
#define FT_ARRAY_MOVE( dest, source, count ) \
FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) )
/*************************************************************************/

View File

@ -4,7 +4,7 @@
/* */
/* Tracing handling (specification only). */
/* */
/* Copyright 2002, 2004 by */
/* Copyright 2002, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* 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 */
FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.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( ttpost ) /* PS table processing (ttpost.c) */
FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -477,24 +477,27 @@ FT_BEGIN_HEADER
typedef void
(*TT_Free_Table_Func)( TT_Face face );
/**
* @functype: TT_Face_GetKerningFunc
*
* @description:
* return the horizontal kerning value between two glyphs
*
* @input:
* face :: handle to source face object
* left_glyph :: left glyph index
* right_glyph :: right glyph index
*
* @return:
* kerning value in font units.
*/
/*
* @functype:
* TT_Face_GetKerningFunc
*
* @description:
* Return the horizontal kerning value between two glyphs.
*
* @input:
* face :: A handle to the source face object.
* left_glyph :: The left glyph index.
* right_glyph :: The right glyph index.
*
* @return:
* The kerning value in font units.
*/
typedef FT_Int
(*TT_Face_GetKerningFunc)( TT_Face face,
FT_UInt left_glyph,
FT_UInt right_glyph );
(*TT_Face_GetKerningFunc)( TT_Face face,
FT_UInt left_glyph,
FT_UInt right_glyph );
/*************************************************************************/
/* */
@ -552,7 +555,7 @@ FT_BEGIN_HEADER
TT_Load_SBit_Image_Func load_sbit_image;
TT_Free_Table_Func free_sbits;
/* sett `ttkern.h' */
/* see `ttkern.h' */
TT_Face_GetKerningFunc get_kerning;
/* see `ttpost.h' */

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -105,13 +105,14 @@
TT_Face face = (TT_Face)ttface;
SFNT_Service sfnt = face->sfnt;
kerning->x = 0;
kerning->y = 0;
if ( sfnt )
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). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -81,19 +81,22 @@
if ( !error )
{
/* XXX: TODO: move this code to the SFNT module where it belongs */
#ifdef FT_OPTIMIZE_MEMORY
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 */
/* XXX: Is this correct? */
sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */
strike[18] + /* max_width */
sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */
strike[18] + /* max_width */
(FT_Char)strike[23] /* min_advance_SB */
) << 6;
#else /* !OPTIMIZE_MEMORY */
TT_SBit_Strike strike = face->sbit_strikes + strike_index;
@ -104,6 +107,7 @@
sbit_metrics->max_advance = ( strike->hori.min_origin_SB +
strike->hori.max_width +
strike->hori.min_advance_SB ) << 6;
#endif /* !OPTIMIZE_MEMORY */
/* 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 ;

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.
#
# 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). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -366,8 +366,8 @@
/* see `ttsbit.h' and `sfnt.h' */
tt_face_set_sbit_strike,
tt_face_load_sbit_strikes,
NULL /* tt_find_sbit_image */,
NULL /* tt_load_sbit_metrics */,
0 /* tt_find_sbit_image */,
0 /* tt_load_sbit_metrics */,
tt_face_load_sbit_image,
tt_face_free_sbit_strikes,

View File

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

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -511,7 +511,7 @@
(void)LOAD_( gasp );
(void)LOAD_( kerning );
error = 0;
error = SFNT_Err_Ok;
face->root.family_name = tt_face_get_name( face,
TT_NAME_ID_PREFERRED_FAMILY );
@ -560,7 +560,7 @@
#if 0
/* kerning available ? */
if ( TT_FACE_HAS_KERNING(face) )
if ( TT_FACE_HAS_KERNING( face ) )
flags |= FT_FACE_FLAG_KERNING;
#endif
@ -780,6 +780,7 @@
{
FT_Stream stream = FT_FACE_STREAM( face );
FT_FRAME_RELEASE( face->horz_metrics );
FT_FRAME_RELEASE( face->vert_metrics );
face->horz_metrics_size = 0;

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -627,18 +627,18 @@
typedef struct TT_CMap4Rec_
{
TT_CMapRec cmap;
FT_UInt32 old_charcode; /* old charcode */
FT_UInt32 cur_charcode; /* current charcode */
FT_UInt cur_gindex; /* current glyph index */
TT_CMapRec cmap;
FT_UInt32 old_charcode; /* old charcode */
FT_UInt32 cur_charcode; /* current charcode */
FT_UInt cur_gindex; /* current glyph index */
FT_UInt table_length;
FT_UInt num_ranges;
FT_UInt cur_range;
FT_UInt cur_start;
FT_UInt cur_end;
FT_Int cur_delta;
FT_Byte* cur_values;
FT_UInt table_length;
FT_UInt num_ranges;
FT_UInt cur_range;
FT_UInt cur_start;
FT_UInt cur_end;
FT_Int cur_delta;
FT_Byte* cur_values;
} TT_CMap4Rec, *TT_CMap4;
@ -647,15 +647,16 @@
tt_cmap4_init( TT_CMap4 cmap,
FT_Byte* table )
{
FT_Byte* p;
FT_Byte* p;
cmap->cmap.data = table;
p = table + 2;
cmap->table_length = FT_PEEK_USHORT(p);
cmap->table_length = FT_PEEK_USHORT( p );
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->old_charcode = 0xFFFFFFFFUL;
cmap->cur_charcode = 0;
@ -665,7 +666,6 @@
}
static FT_Int
tt_cmap4_set_range( TT_CMap4 cmap,
FT_UInt range_index )
@ -674,23 +674,25 @@
FT_Byte* p;
FT_UInt num_ranges = cmap->num_ranges;
while ( range_index < num_ranges )
{
FT_UInt offset;
p = table + 14 + range_index*2;
cmap->cur_end = FT_PEEK_USHORT(p);
p += 2 + num_ranges*2;
cmap->cur_start = FT_PEEK_USHORT(p);
p = table + 14 + range_index * 2;
cmap->cur_end = FT_PEEK_USHORT( p );
p += num_ranges*2;
cmap->cur_delta = FT_PEEK_SHORT(p);
p += 2 + num_ranges * 2;
cmap->cur_start = FT_PEEK_USHORT( p );
p += num_ranges*2;
offset = FT_PEEK_SHORT(p);
p += num_ranges * 2;
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_range = range_index;
@ -712,30 +714,33 @@
static void
tt_cmap4_next( TT_CMap4 cmap )
{
FT_UInt num_ranges = cmap->num_ranges;
FT_UInt charcode = cmap->cur_charcode + 1;
cmap->old_charcode = cmap->cur_charcode;
for ( ;; )
{
FT_Byte* values = cmap->cur_values;
FT_UInt end = cmap->cur_end;
FT_Int delta = cmap->cur_delta;
FT_Byte* values = cmap->cur_values;
FT_UInt end = cmap->cur_end;
FT_Int delta = cmap->cur_delta;
if ( charcode <= end )
{
if ( values )
{
FT_Byte* p = values + 2*(charcode-cmap->cur_start);
FT_Byte* p = values + 2 * ( charcode - cmap->cur_start );
do
{
FT_UInt gindex = FT_NEXT_USHORT(p);
FT_UInt gindex = FT_NEXT_USHORT( p );
if ( gindex != 0 )
{
gindex = (FT_UInt)((gindex + delta) & 0xFFFF);
gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU );
if ( gindex != 0 )
{
cmap->cur_charcode = charcode;
@ -743,14 +748,14 @@
return;
}
}
}
while ( ++charcode <= end );
} while ( ++charcode <= end );
}
else
{
do
{
FT_UInt gindex = (FT_UInt)((charcode + delta) & 0xFFFFU);
FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU );
if ( gindex != 0 )
{
@ -758,14 +763,12 @@
cmap->cur_gindex = gindex;
return;
}
}
while ( ++charcode <= end );
} while ( ++charcode <= end );
}
}
/* we need to find another range
*/
if ( tt_cmap4_set_range( cmap, cmap->cur_range+1 ) < 0 )
/* we need to find another range */
if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 )
break;
charcode = cmap->cur_start;
@ -1092,6 +1095,7 @@
{
TT_CMap4 cmap4 = (TT_CMap4)cmap;
if ( char_code == cmap4->old_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. */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* 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_STREAM_H
#include FT_TRUETYPE_TAGS_H
#include "ttkern.h"
#include "ttload.h"
#include "sferrors.h"
@ -33,7 +34,7 @@
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_ttload
#define FT_COMPONENT trace_ttkern
#undef TT_KERN_INDEX
@ -72,15 +73,15 @@
FT_ERROR(( "could not extract kerning table\n" ));
goto Exit;
}
face->kern_table_size = table_size;
p = face->kern_table;
p_limit = p + table_size;
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 */
num_tables = 32;
@ -89,56 +90,61 @@
FT_UInt num_pairs, version, length, coverage;
FT_Byte* p_next;
FT_UInt32 mask = 1UL << nn;
if ( p + 6 > p_limit )
break;
p_next = p;
version = FT_NEXT_USHORT(p);
length = FT_NEXT_USHORT(p);
coverage = FT_NEXT_USHORT(p);
version = FT_NEXT_USHORT( p );
length = FT_NEXT_USHORT( p );
coverage = FT_NEXT_USHORT( p );
if ( length <= 6 )
break;
p_next += length;
if ( (coverage & ~8) != 0x0001 || /* only use horizontal kerning tables */
p+8 > p_limit )
/* only use horizontal kerning tables */
if ( ( coverage & ~8 ) != 0x0001 ||
p + 8 > p_limit )
goto NextTable;
num_pairs = FT_NEXT_USHORT(p);
num_pairs = FT_NEXT_USHORT( p );
p += 6;
if ( p + 6*num_pairs > p_limit )
if ( p + 6 * num_pairs > p_limit )
goto NextTable;
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 )
{
FT_UInt count;
FT_UInt old_pair;
old_pair = FT_NEXT_ULONG(p);
FT_UInt count;
FT_UInt old_pair;
old_pair = FT_NEXT_ULONG( p );
p += 2;
for ( count = num_pairs-1; count > 0; count-- )
for ( count = num_pairs - 1; count > 0; count-- )
{
FT_UInt32 cur_pair;
cur_pair = FT_NEXT_ULONG(p);
cur_pair = FT_NEXT_ULONG( p );
if ( cur_pair <= old_pair )
break;
p += 2;
old_pair = cur_pair;
}
if ( count == 0 )
ordered |= mask;
}
@ -150,7 +156,7 @@
face->num_kern_tables = nn;
face->kern_avail_bits = avail;
face->kern_order_bits = ordered;
Exit:
return error;
}
@ -160,7 +166,8 @@
tt_face_done_kern( TT_Face face )
{
FT_Stream stream = face->root.stream;
FT_FRAME_RELEASE( face->kern_table );
face->kern_table_size = 0;
face->num_kern_tables = 0;
@ -179,6 +186,7 @@
FT_Byte* p = face->kern_table;
FT_Byte* p_limit = p + face->kern_table_size;
p += 4;
mask = 0x0001;
@ -186,88 +194,95 @@
{
FT_Byte* base = p;
FT_Byte* next = base;
FT_UInt version = FT_NEXT_USHORT(p);
FT_UInt length = FT_NEXT_USHORT(p);
FT_UInt coverage = FT_NEXT_USHORT(p);
FT_UInt version = FT_NEXT_USHORT( p );
FT_UInt length = FT_NEXT_USHORT( p );
FT_UInt coverage = FT_NEXT_USHORT( p );
FT_Int value = 0;
next = base + length;
if ( (face->kern_avail_bits & mask) == 0 )
if ( ( face->kern_avail_bits & mask ) == 0 )
goto NextTable;
if ( p+8 > next )
if ( p + 8 > next )
goto NextTable;
switch ( coverage >> 8 )
{
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_ULong key0 = TT_KERN_INDEX(left_glyph,right_glyph);
FT_UInt min = 0;
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);
if ( key == key0 )
{
value = FT_PEEK_SHORT(p);
goto Found;
}
p += 2;
value = FT_PEEK_SHORT( q );
goto Found;
}
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:
;
;
}
goto NextTable;
Found:
if ( coverage & 8 ) /* overide or addition */
if ( coverage & 8 ) /* overide or add */
result = value;
else
result += value;
NextTable:
p = next;
}
@ -276,8 +291,7 @@
return result;
}
#else /* !OPTMIZE_MEMORY */
#else /* !OPTIMIZE_MEMORY */
FT_CALLBACK_DEF( int )
tt_kern_pair_compare( const void* a,
@ -365,20 +379,20 @@
{
TT_Kern0_Pair pair0 = face->kern_pairs;
FT_ULong prev = TT_KERN_INDEX( pair0->left, pair0->right );
for ( pair0++; pair0 < limit; pair0++ )
{
FT_ULong next = TT_KERN_INDEX( pair0->left, pair0->right );
if ( next < prev )
goto SortIt;
prev = next;
}
goto Exit;
SortIt:
ft_qsort( (void*)face->kern_pairs, (int)num_pairs,
sizeof ( TT_Kern0_PairRec ), tt_kern_pair_compare );
@ -400,6 +414,7 @@
return error;
}
FT_CALLBACK_DEF( int )
tt_kern_pair_compare( const void* a,
const void* b )
@ -410,9 +425,9 @@
FT_ULong index1 = TT_KERN_INDEX( pair1->left, pair1->right );
FT_ULong index2 = TT_KERN_INDEX( pair2->left, pair2->right );
return ( index1 < index2 ? -1 :
( index1 > index2 ? 1 : 0 ));
return index1 < index2 ? -1
: ( index1 > index2 ? 1
: 0 );
}
@ -420,17 +435,17 @@
tt_face_done_kern( TT_Face face )
{
FT_Memory memory = face->root.stream->memory;
FT_FREE( face->kern_pairs );
face->num_kern_pairs = 0;
}
FT_LOCAL_DEF( FT_Int )
tt_face_get_kerning( TT_Face face,
FT_UInt left_glyph,
FT_UInt right_glyph )
tt_face_get_kerning( TT_Face face,
FT_UInt left_glyph,
FT_UInt right_glyph )
{
FT_Int result = 0;
TT_Kern0_Pair pair;
@ -477,5 +492,5 @@
#undef TT_KERN_INDEX
/* END */

View File

@ -2,10 +2,10 @@
/* */
/* 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. */
/* */
/* Copyright 1996-2001, 2002 by */
/* Copyright 1996-2001, 2002, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -42,11 +42,12 @@ FT_BEGIN_HEADER
FT_UInt right_glyph );
#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
# define TT_FACE_HAS_KERNING(face) ((face)->kern_pairs != NULL)
# define TT_FACE_HAS_KERNING( face ) ( (face)->kern_pairs != NULL )
#endif
FT_END_HEADER
#endif /* __TTKERN_H__ */

View File

@ -5,7 +5,7 @@
/* Load the basic TrueType tables, i.e., tables that can be either in */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -801,6 +801,7 @@
/* FreeType error code. 0 means success. */
/* */
#ifdef FT_OPTIMIZE_MEMORY
static FT_Error
tt_face_load_metrics( TT_Face face,
FT_Stream stream,
@ -822,7 +823,7 @@
ptable = &face->vert_metrics;
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 */
/* `number_of_VMetrics' fields, but no corresponding `vmtx' */
@ -849,10 +850,10 @@
{
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font and there are */
/* overriding metrics tolerate a missing 'hmtx' table. */
if ( face->root.internal->incremental_interface &&
/* overriding metrics, tolerate a missing `hmtx' table. */
if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->
get_glyph_metrics )
get_glyph_metrics )
{
face->horizontal.number_Of_HMetrics = 0;
error = SFNT_Err_Ok;
@ -876,6 +877,7 @@
}
#else /* !OPTIMIZE_MEMORY */
static FT_Error
tt_face_load_metrics( TT_Face face,
FT_Stream stream,
@ -897,7 +899,7 @@
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 */
/* `number_of_VMetrics' fields, but no corresponding `vmtx' */
@ -927,10 +929,10 @@
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font and there are */
/* overriding metrics tolerate a missing 'hmtx' table. */
if ( face->root.internal->incremental_interface &&
/* overriding metrics, tolerate a missing `hmtx' table. */
if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->
get_glyph_metrics )
get_glyph_metrics )
{
face->horizontal.number_Of_HMetrics = 0;
error = SFNT_Err_Ok;
@ -993,9 +995,9 @@
for ( ; cur < limit; cur++ )
*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 */
/* fonts usually only, nothing serious will happen */
/* fonts usually only, nothing serious will happen. */
if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 )
{
FT_Short val = (*shorts)[num_shorts_checked - 1];
@ -1014,8 +1016,10 @@
Exit:
return error;
}
#endif /* !FT_OPTIMIZE_METRICS */
/*************************************************************************/
/* */
/* <Function> */
@ -1704,6 +1708,7 @@
/* FreeType error code. 0 means success. */
/* */
#ifdef FT_OPTIMIZE_MEMORY
FT_LOCAL_DEF( FT_Error )
tt_face_load_hdmx( TT_Face face,
FT_Stream stream )
@ -1715,6 +1720,7 @@
FT_Byte* p;
FT_Byte* limit;
/* this table is optional */
error = face->goto_table( face, TTAG_hdmx, stream, &table_size );
if ( error || table_size < 8 )
@ -1726,9 +1732,9 @@
p = face->hdmx_table;
limit = p + table_size;
version = FT_NEXT_USHORT(p);
num_records = FT_NEXT_USHORT(p);
record_size = FT_NEXT_ULONG(p);
version = FT_NEXT_USHORT( p );
num_records = FT_NEXT_USHORT( p );
record_size = FT_NEXT_ULONG( p );
if ( version != 0 || num_records > 255 || record_size > 0x40000 )
{
@ -1741,7 +1747,7 @@
for ( nn = 0; nn < num_records; nn++ )
{
if ( p+record_size > limit )
if ( p + record_size > limit )
break;
face->hdmx_record_sizes[nn] = p[0];
@ -1767,11 +1773,13 @@
FT_Stream stream = face->root.stream;
FT_Memory memory = stream->memory;
FT_FREE( face->hdmx_record_sizes );
FT_FRAME_RELEASE( face->hdmx_table );
}
#else /* !FT_OPTIMIZE_MEMORY */
FT_LOCAL_DEF( FT_Error )
tt_face_load_hdmx( TT_Face face,
FT_Stream stream )
@ -1797,9 +1805,9 @@
if ( FT_FRAME_ENTER( 8L ) )
goto Exit;
hdmx->version = FT_GET_USHORT();
num_records = FT_GET_SHORT();
record_size = FT_GET_LONG();
hdmx->version = FT_GET_USHORT();
num_records = FT_GET_SHORT();
record_size = FT_GET_LONG();
FT_FRAME_EXIT();
@ -1831,7 +1839,7 @@
FT_READ_BYTE( cur->max_width ) )
goto Exit;
if ( FT_QALLOC( cur->widths, num_glyphs ) ||
if ( FT_QALLOC( cur->widths, num_glyphs ) ||
FT_STREAM_READ( cur->widths, num_glyphs ) )
goto Exit;

View File

@ -5,7 +5,7 @@
/* Load the basic TrueType tables, i.e., tables that can be either in */
/* TTF or OTF fonts (specification). */
/* */
/* Copyright 1996-2001, 2002 by */
/* Copyright 1996-2001, 2002, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* 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). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* 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 )
{
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 ) )
@ -608,9 +607,9 @@
/* assume 72dpi */
bsize->height =
(FT_Short)( ( height * strike->y_ppem + fupem/2 ) / fupem );
(FT_Short)( ( height * strike->y_ppem + fupem / 2 ) / fupem );
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->x_ppem = strike->x_ppem << 6;
bsize->y_ppem = strike->y_ppem << 6;
@ -1514,6 +1513,7 @@
return error;
}
#endif /* !OPTIMIZE_MEMORY */
/* END */
#endif /* !OPTIMIZE_MEMORY */

View File

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

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -100,12 +100,13 @@
/* */
static FT_Error
tt_get_kerning( FT_Face ttface, /* TT_Face */
FT_UInt left_glyph,
FT_UInt right_glyph,
FT_Vector* kerning )
FT_UInt left_glyph,
FT_UInt right_glyph,
FT_Vector* kerning )
{
TT_Face face = (TT_Face)ttface;
SFNT_Service sfnt = (SFNT_Service) face->sfnt;
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
kerning->x = 0;
kerning->y = 0;

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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. */
/* */
#ifdef FT_OPTIMIZE_MEMORY
static void
tt_face_get_metrics( TT_Face face,
FT_Bool vertical,
FT_UInt idx,
FT_Short *abearing,
FT_UShort *aadvance )
tt_face_get_metrics( TT_Face face,
FT_Bool vertical,
FT_UInt idx,
FT_Short *abearing,
FT_UShort *aadvance )
{
TT_HoriHeader* header;
FT_Byte* p;
FT_Byte* limit;
FT_UShort k;
if ( vertical )
{
header = (TT_HoriHeader*)&face->vertical;
@ -128,25 +130,25 @@
{
if ( idx < (FT_UInt)k )
{
p += 4*idx;
if ( p+4 >= limit )
p += 4 * idx;
if ( p + 4 >= limit )
goto NoData;
*aadvance = FT_NEXT_USHORT(p);
*abearing = FT_NEXT_SHORT(p);
*aadvance = FT_NEXT_USHORT( p );
*abearing = FT_NEXT_SHORT( p );
}
else
{
p += 4*(k-1);
if ( p+4 > limit )
p += 4 * ( k - 1 );
if ( p + 4 > limit )
goto NoData;
*aadvance = FT_NEXT_USHORT(p);
p += 2 + 2*(idx-k);
if ( p+2 > limit )
*aadvance = FT_NEXT_USHORT( p );
p += 2 + 2 * ( idx - k );
if ( p + 2 > limit )
*abearing = 0;
else
*abearing = FT_PEEK_SHORT(p);
*abearing = FT_PEEK_SHORT( p );
}
}
else
@ -156,18 +158,20 @@
*aadvance = 0;
}
}
#else
#else /* !FT_OPTIMIZE_MEMORY */
static void
tt_face_get_metrics( TT_Face face,
FT_Bool vertical,
FT_UInt idx,
FT_Short *abearing,
FT_UShort *aadvance )
tt_face_get_metrics( TT_Face face,
FT_Bool vertical,
FT_UInt idx,
FT_Short *abearing,
FT_UShort *aadvance )
{
TT_HoriHeader* header = (vertical ? (TT_HoriHeader*)&face->vertical
: &face->horizontal);
TT_HoriHeader* header = vertical ? (TT_HoriHeader*)&face->vertical
: &face->horizontal;
TT_LongMetrics longs_m;
FT_UShort k = header->number_Of_HMetrics;
FT_UShort k = header->number_Of_HMetrics;
if ( k == 0 )
@ -178,17 +182,18 @@
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;
*aadvance = longs_m->advance;
}
else
{
*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 )
{
#ifdef FT_OPTIMIZE_MEMORY
FT_UInt nn;
FT_Byte* result = NULL;
FT_Byte* result = NULL;
FT_ULong record_size = face->hdmx_record_size;
FT_Byte* record = face->hdmx_table + 8;
for ( nn = 0; nn < face->hdmx_record_count; nn++ )
if ( face->hdmx_record_sizes[nn] == ppem )
{
@ -237,7 +244,9 @@
}
return result;
#else
FT_UShort n;
@ -246,6 +255,7 @@
return &face->hdmx.records[n].widths[gindex];
return NULL;
#endif
}

View File

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

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -750,19 +750,21 @@
if ( !error )
{
/* XXX: TODO: move this code to the SFNT module where it belongs */
#ifdef FT_OPTIMIZE_MEMORY
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 */
/* XXX: Is this correct? */
sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */
strike[18] + /* max_width */
sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */
strike[18] + /* max_width */
(FT_Char)strike[23] /* min_advance_SB */
) << 6;
#else /* !OPTIMIZE_MEMORY */
#else /* !FT_OPTIMIZE_MEMORY */
TT_SBit_Strike strike = face->sbit_strikes + strike_index;
@ -773,7 +775,8 @@
sbit_metrics->max_advance = ( strike->hori.min_origin_SB +
strike->hori.max_width +
strike->hori.min_advance_SB ) << 6;
#endif /* !OPTIMIZE_MEMORY */
#endif /* !FT_OPTIMIZE_MEMORY */
/* XXX: Is this correct? */
sbit_metrics->height = sbit_metrics->ascender -

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* 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 ( table_len >= 040000 )
if ( table_len >= 0x40000 )
{
FT_TRACE2(( "table too large !!\n" ));
FT_TRACE2(( "table too large!\n" ));
error = TT_Err_Invalid_Table;
goto Exit;
}
face->num_locations = (FT_UInt)(table_len >> 2);
face->num_locations = (FT_UInt)( table_len >> 2 );
}
else
{
if ( table_len >= 0x20000 )
{
FT_TRACE2(( "table too large !!\n" ));
FT_TRACE2(( "table too large!\n" ));
error = TT_Err_Invalid_Table;
goto Exit;
}
face->num_locations = (FT_UInt)(table_len >> 1);
face->num_locations = (FT_UInt)( table_len >> 1 );
}
/* extract the frame. We don't need to decompress it since
* we'll be able to parse it directly
*/
/*
* Extract the frame. We don't need to decompress it since
* we are able to parse it directly.
*/
if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) )
goto Exit;
@ -113,45 +113,47 @@
FT_LOCAL_DEF( FT_ULong )
tt_face_get_location( TT_Face face,
FT_UInt gindex,
FT_UInt *asize )
tt_face_get_location( TT_Face face,
FT_UInt gindex,
FT_UInt *asize )
{
FT_ULong pos1, pos2;
FT_Byte* p;
FT_Byte* p_limit;
pos1 = pos2 = 0;
if ( gindex < face->num_locations )
{
if ( face->header.Index_To_Loc_Format != 0 )
{
p = face->glyph_locations + gindex*4;
p_limit = face->glyph_locations + face->num_locations*4;
p = face->glyph_locations + gindex * 4;
p_limit = face->glyph_locations + face->num_locations * 4;
pos1 = FT_NEXT_ULONG(p);
pos1 = FT_NEXT_ULONG( p );
pos2 = pos1;
if ( p+4 <= p_limit )
pos2 = FT_NEXT_ULONG(p);
if ( p + 4 <= p_limit )
pos2 = FT_NEXT_ULONG( p );
}
else
{
p = face->glyph_locations + gindex*2;
p_limit = face->glyph_locations + face->num_locations*2;
p = face->glyph_locations + gindex * 2;
p_limit = face->glyph_locations + face->num_locations * 2;
pos1 = FT_NEXT_USHORT(p);
pos1 = FT_NEXT_USHORT( p );
pos2 = pos1;
if ( p+2 <= p_limit )
pos2 = FT_NEXT_USHORT(p);
if ( p + 2 <= p_limit )
pos2 = FT_NEXT_USHORT( p );
pos1 <<= 1;
pos2 <<= 1;
}
}
*asize = (FT_UInt)(pos2 - pos1);
*asize = (FT_UInt)( pos2 - pos1 );
return pos1;
}
@ -160,16 +162,17 @@
FT_LOCAL_DEF( void )
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 );
face->num_locations = 0;
}
#else /* !FT_OPTIMIZE_MEMORY */
FT_LOCAL_DEF( FT_Error )
tt_face_load_loca( TT_Face face,
FT_Stream stream )
@ -224,6 +227,7 @@
if ( FT_FRAME_ENTER( face->num_locations * 2L ) )
goto Exit;
{
FT_Long* loc = face->glyph_locations;
FT_Long* limit = loc + face->num_locations;
@ -232,6 +236,7 @@
for ( ; loc < limit; loc++ )
*loc = (FT_Long)( (FT_ULong)FT_GET_USHORT() * 2 );
}
FT_FRAME_EXIT();
}
@ -243,13 +248,14 @@
FT_LOCAL_DEF( FT_ULong )
tt_face_get_location( TT_Face face,
FT_UInt gindex,
FT_UInt *asize )
tt_face_get_location( TT_Face face,
FT_UInt gindex,
FT_UInt *asize )
{
FT_ULong offset;
FT_UInt count;
offset = face->glyph_locations[gindex];
count = 0;
@ -264,14 +270,14 @@
FT_LOCAL_DEF( void )
tt_face_done_loca( TT_Face face )
{
FT_Memory memory = face->root.memory;
FT_Memory memory = face->root.memory;
FT_FREE( face->glyph_locations );
face->num_locations = 0;
}
#endif /* !FT_OPTIMIZE_MEMORY */
@ -345,10 +351,13 @@
Exit:
return error;
#else /* !BYTECODE_INTERPRETER */
FT_UNUSED(face);
FT_UNUSED(stream);
#else /* !FT_CONFIG_OPTION_BYTECODE_INTERPRETER */
FT_UNUSED( face );
FT_UNUSED( stream );
return 0;
#endif
}
@ -423,10 +432,13 @@
Exit:
return error;
#else /* !BYTECODE_INTERPRETER */
FT_UNUSED(face);
FT_UNUSED(stream);
#else /* !FT_CONFIG_OPTION_BYTECODE_INTERPRETER */
FT_UNUSED( face );
FT_UNUSED( stream );
return 0;
#endif
}

View File

@ -4,7 +4,7 @@
/* */
/* 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. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -32,9 +32,9 @@ FT_BEGIN_HEADER
FT_Stream stream );
FT_LOCAL( FT_ULong )
tt_face_get_location( TT_Face face,
FT_UInt gindex,
FT_UInt *asize );
tt_face_get_location( TT_Face face,
FT_UInt gindex,
FT_UInt *asize );
FT_LOCAL( void )
tt_face_done_loca( TT_Face face );