* include/freetype/internal/ftobjs.h, src/base/ftutil.c (ft_highpow2),
src/pfr/pfrload.c, src/pfr/pfrobjs.c, src/pfr/pfrtypes.h: implement FT_OPTIMIZE_MEMORY, the kerning table is not loaded into the heap anymore.
This commit is contained in:
parent
0780817a61
commit
683973b47c
|
@ -80,6 +80,12 @@ FT_BEGIN_HEADER
|
|||
#define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 )
|
||||
|
||||
|
||||
/* returns the highest power of 2 that is <= value, this correspond to
|
||||
* the highest bit in a given 32-bit value
|
||||
*/
|
||||
FT_BASE( FT_UInt32 )
|
||||
ft_highpow2( FT_UInt32 value );
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
|
|
@ -398,4 +398,24 @@
|
|||
}
|
||||
|
||||
|
||||
FT_BASE( FT_UInt32 )
|
||||
ft_highpow2( FT_UInt32 value )
|
||||
{
|
||||
FT_UInt32 value2;
|
||||
|
||||
/* we simply clear the lowest bit in each iteration. when
|
||||
* we reach 0, we now that the previous value was our result
|
||||
*/
|
||||
for ( ;; )
|
||||
{
|
||||
value2 = value & (value-1); /* clear lowest bit */
|
||||
if ( value2 == 0 )
|
||||
break;
|
||||
|
||||
value = value2;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
|
|
|
@ -609,6 +609,7 @@
|
|||
}
|
||||
|
||||
|
||||
#ifndef FT_OPTIMIZE_MEMORY
|
||||
/*
|
||||
* The kerning data embedded in a PFR font are (charcode,charcode)
|
||||
* pairs; we need to translate them to (gindex,gindex) and sort
|
||||
|
@ -747,7 +748,7 @@
|
|||
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif /* !FT_OPTIMIZE_MEMORY */
|
||||
|
||||
static const PFR_ExtraItemRec pfr_phy_font_extra_items[] =
|
||||
{
|
||||
|
@ -826,7 +827,10 @@
|
|||
FT_FREE( phy_font->blue_values );
|
||||
phy_font->num_blue_values = 0;
|
||||
|
||||
#ifndef FT_OPTIMIZE_MEMORY
|
||||
FT_FREE( phy_font->kern_pairs );
|
||||
#endif
|
||||
|
||||
{
|
||||
PFR_KernItem item, next;
|
||||
|
||||
|
@ -1065,8 +1069,10 @@
|
|||
phy_font->bct_offset = FT_STREAM_POS();
|
||||
phy_font->cursor = NULL;
|
||||
|
||||
#ifndef FT_OPTIMIZE_MEMORY
|
||||
/* now sort kerning pairs */
|
||||
error = pfr_sort_kerning_pairs( stream, phy_font );
|
||||
#endif
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
/* we don't want dangling pointers */
|
||||
pfrface->family_name = NULL;
|
||||
pfrface->style_name = NULL;
|
||||
|
||||
|
||||
/* finalize the physical font record */
|
||||
pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) );
|
||||
|
||||
|
@ -174,11 +174,11 @@
|
|||
FT_Bitmap_Size* size;
|
||||
PFR_Strike strike;
|
||||
FT_Memory memory = pfrface->stream->memory;
|
||||
|
||||
|
||||
|
||||
|
||||
if ( FT_NEW_ARRAY( pfrface->available_sizes, count ) )
|
||||
goto Exit;
|
||||
|
||||
|
||||
size = pfrface->available_sizes;
|
||||
strike = phy_font->strikes;
|
||||
for ( n = 0; n < count; n++, size++, strike++ )
|
||||
|
@ -361,6 +361,8 @@
|
|||
metrics->vertBearingX = 0;
|
||||
metrics->vertBearingY = 0;
|
||||
|
||||
#if 0 /* some fonts seem to be broken here !! */
|
||||
|
||||
/* Apply the font matrix, if any. */
|
||||
/* TODO: Test existing fonts with unusual matrix */
|
||||
/* whether we have to adjust Units per EM. */
|
||||
|
@ -375,6 +377,7 @@
|
|||
|
||||
FT_Outline_Transform( outline, &font_matrix );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* scale when needed */
|
||||
if ( scaling )
|
||||
|
@ -419,6 +422,123 @@
|
|||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef FT_OPTIMIZE_MEMORY
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */
|
||||
FT_UInt glyph1,
|
||||
FT_UInt glyph2,
|
||||
FT_Vector* kerning )
|
||||
{
|
||||
PFR_Face face = (PFR_Face)pfrface;
|
||||
FT_Error error = PFR_Err_Ok;
|
||||
PFR_PhyFont phy_font = &face->phy_font;
|
||||
FT_UInt32 code1, code2, pair;
|
||||
|
||||
kerning->x = 0;
|
||||
kerning->y = 0;
|
||||
|
||||
if ( glyph1 > 0 )
|
||||
glyph1--;
|
||||
|
||||
if ( glyph2 > 0 )
|
||||
glyph2--;
|
||||
|
||||
/* convert glyph indices to character codes */
|
||||
if ( glyph1 > phy_font->num_chars ||
|
||||
glyph2 > phy_font->num_chars )
|
||||
goto Exit;
|
||||
|
||||
code1 = phy_font->chars[glyph1].char_code;
|
||||
code2 = phy_font->chars[glyph2].char_code;
|
||||
pair = PFR_KERN_INDEX(code1,code2);
|
||||
|
||||
/* now search the list of kerning items */
|
||||
{
|
||||
PFR_KernItem item = phy_font->kern_items;
|
||||
FT_Stream stream = pfrface->stream;
|
||||
|
||||
for ( ; item; item = item->next )
|
||||
{
|
||||
if ( pair >= item->pair1 && pair <= item->pair2 )
|
||||
goto FoundPair;
|
||||
}
|
||||
goto Exit;
|
||||
|
||||
FoundPair: /* we found an item, now parse it and find the value if any */
|
||||
if ( FT_STREAM_SEEK( item->offset ) ||
|
||||
FT_FRAME_ENTER( item->pair_count*item->pair_size ) )
|
||||
goto Exit;
|
||||
|
||||
{
|
||||
FT_UInt count = item->pair_count;
|
||||
FT_UInt size = item->pair_size;
|
||||
FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count );
|
||||
FT_UInt probe = power*size;
|
||||
FT_UInt extra = count - power;
|
||||
FT_Byte* base = stream->cursor;
|
||||
FT_Bool twobytes = item->flags & 1;
|
||||
FT_Byte* p;
|
||||
FT_UInt32 cpair;
|
||||
|
||||
if ( extra > 0 )
|
||||
{
|
||||
p = base + extra*size;
|
||||
if ( twobytes )
|
||||
cpair = FT_NEXT_ULONG(p);
|
||||
else
|
||||
cpair = PFR_NEXT_KPAIR(p);
|
||||
|
||||
if ( cpair == pair )
|
||||
goto Found;
|
||||
|
||||
if ( cpair < pair )
|
||||
base = p;
|
||||
}
|
||||
|
||||
while ( probe > size )
|
||||
{
|
||||
probe >>= 1;
|
||||
p = base + probe;
|
||||
if ( twobytes )
|
||||
cpair = FT_NEXT_ULONG(p);
|
||||
else
|
||||
cpair = PFR_NEXT_KPAIR(p);
|
||||
|
||||
if ( cpair == pair )
|
||||
goto Found;
|
||||
|
||||
if ( cpair < pair )
|
||||
base += probe;
|
||||
}
|
||||
|
||||
p = base;
|
||||
if ( twobytes )
|
||||
cpair = FT_NEXT_ULONG(p);
|
||||
else
|
||||
cpair = PFR_NEXT_KPAIR(p);
|
||||
|
||||
if ( cpair == pair )
|
||||
{
|
||||
FT_Int value;
|
||||
|
||||
Found:
|
||||
if ( item->flags & 2 )
|
||||
value = FT_PEEK_SHORT(p);
|
||||
else
|
||||
value = p[0];
|
||||
|
||||
kerning->x = item->base_adj + value;
|
||||
}
|
||||
}
|
||||
|
||||
FT_FRAME_EXIT();
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#else /* !FT_OPTIMIZE_MEMORY */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */
|
||||
FT_UInt glyph1,
|
||||
|
@ -438,20 +558,20 @@
|
|||
|
||||
min = 0;
|
||||
max = phy_font->num_kern_pairs;
|
||||
|
||||
|
||||
while ( min < max )
|
||||
{
|
||||
FT_UInt mid = ( min + max ) >> 1;
|
||||
PFR_KernPair pair = pairs + mid;
|
||||
FT_UInt32 pidx = PFR_KERN_PAIR_INDEX( pair );
|
||||
|
||||
|
||||
|
||||
if ( pidx == idx )
|
||||
{
|
||||
kerning->x = pair->kerning;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ( pidx < idx )
|
||||
min = mid + 1;
|
||||
else
|
||||
|
@ -460,6 +580,6 @@
|
|||
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif /* !FT_OPTIMIZE_MEMORY */
|
||||
|
||||
/* END */
|
||||
|
|
|
@ -196,10 +196,10 @@ FT_BEGIN_HEADER
|
|||
typedef struct PFR_KernItemRec_
|
||||
{
|
||||
PFR_KernItem next;
|
||||
FT_UInt pair_count;
|
||||
FT_Byte pair_count;
|
||||
FT_Byte flags;
|
||||
FT_Short base_adj;
|
||||
FT_UInt pair_size;
|
||||
FT_Int base_adj;
|
||||
FT_UInt flags;
|
||||
FT_UInt32 offset;
|
||||
FT_UInt32 pair1;
|
||||
FT_UInt32 pair2;
|
||||
|
@ -212,6 +212,8 @@ FT_BEGIN_HEADER
|
|||
#define PFR_KERN_PAIR_INDEX( pair ) \
|
||||
PFR_KERN_INDEX( (pair)->glyph1, (pair)->glyph2 )
|
||||
|
||||
#define PFR_NEXT_KPAIR(p) ( p+=2, ((FT_UInt32)p[-2] << 16) | p[-1] )
|
||||
|
||||
typedef struct PFR_KernPairRec_
|
||||
{
|
||||
FT_UInt glyph1;
|
||||
|
@ -261,7 +263,9 @@ FT_BEGIN_HEADER
|
|||
FT_UInt num_kern_pairs;
|
||||
PFR_KernItem kern_items;
|
||||
PFR_KernItem* kern_items_tail;
|
||||
#ifndef FT_OPTIMIZE_MEMORY
|
||||
PFR_KernPair kern_pairs;
|
||||
#endif
|
||||
|
||||
/* not part of the spec, but used during load */
|
||||
FT_UInt32 bct_offset;
|
||||
|
|
Loading…
Reference in New Issue