* src/sfnt/ttmtx.c, src/cff/cffload.c: speeding up the CFF font

loader, with some large CFF fonts, FT_Open_Face is now 350% faster !
This commit is contained in:
David Turner 2006-10-23 10:23:17 +00:00
parent e140f14232
commit 29873a0ccd
3 changed files with 108 additions and 77 deletions

View File

@ -1,7 +1,10 @@
2006-10-23 David Turner <david@freetype.org>
* src/pshinter/pshalgo.c: major speed improvements to the Postscript
hinter, more than 100% speed increase on my machine
* src/sfnt/ttmtx.c, src/cff/cffload.c: speeding up the CFF font
loader, with some large CFF fonts, FT_Open_Face is now 350% faster !
* src/pshinter/pshalgo.c: major speed improvements to the Postscript
hinter, more than 100% speed increase on my machine
2006-10-15 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
@ -115,6 +118,7 @@
* src/smooth/ftsmooth.c (ft_smooth_render_generic): Remove arguments
`hmul' and `vmul'.
5A
Handle subpixel rendering.
Simplify function.
(ft_smooth_render_lcd): Use `FT_RENDER_MODE_LCD'.

View File

@ -1063,24 +1063,6 @@
#define FT_COMPONENT trace_cffload
/* read a CFF offset from memory */
static FT_ULong
cff_get_offset( FT_Byte* p,
FT_Byte off_size )
{
FT_ULong result;
for ( result = 0; off_size > 0; off_size-- )
{
result <<= 8;
result |= *p++;
}
return result;
}
static FT_Error
cff_new_index( CFF_Index idx,
FT_Stream stream,
@ -1101,6 +1083,7 @@
FT_Byte offsize;
FT_ULong data_size;
FT_ULong* poff;
FT_Byte* p_end;
/* there is at least one element; read the offset size, */
@ -1108,6 +1091,12 @@
if ( FT_READ_BYTE( offsize ) )
goto Exit;
if ( offsize < 1 || offsize > 4 )
{
error = FT_Err_Invalid_Table;
goto Exit;
}
idx->stream = stream;
idx->count = count;
idx->off_size = offsize;
@ -1117,14 +1106,30 @@
FT_FRAME_ENTER( data_size ) )
goto Exit;
poff = idx->offsets;
p = (FT_Byte*)stream->cursor;
poff = idx->offsets;
p = (FT_Byte*)stream->cursor;
p_end = p + data_size;
for ( ; (FT_Short)count >= 0; count-- )
switch ( offsize )
{
poff[0] = cff_get_offset( p, offsize );
poff++;
p += offsize;
case 1:
for ( ; p < p_end; p++, poff++ )
poff[0] = p[0];
break;
case 2:
for ( ; p < p_end; p += 2, poff++ )
poff[0] = FT_PEEK_USHORT(p);
break;
case 3:
for ( ; p < p_end; p += 3, poff++ )
poff[0] = FT_PEEK_OFF3(p);
break;
default:
for ( ; p < p_end; p += 4, poff++ )
poff[0] = FT_PEEK_ULONG(p);
}
FT_FRAME_EXIT();
@ -1493,20 +1498,60 @@
/*************************************************************************/
/*************************************************************************/
static FT_Error
cff_charset_compute_cids( CFF_Charset charset,
FT_UInt num_glyphs,
FT_Memory memory )
{
FT_Error error = 0;
FT_UInt i;
FT_UShort max_cid = 0;
if ( charset->max_cid > 0 )
goto Exit;
for ( i = 0; i < num_glyphs; i++ )
if ( charset->sids[i] > max_cid )
max_cid = charset->sids[i];
max_cid++;
if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
goto Exit;
for ( i = 0; i < num_glyphs; i++ )
charset->cids[charset->sids[i]] = (FT_UShort)i;
charset->max_cid = max_cid;
Exit:
return error;
}
static void
cff_charset_free_cids( CFF_Charset charset,
FT_Memory memory )
{
FT_FREE( charset->cids );
charset->max_cid = 0;
}
static void
cff_charset_done( CFF_Charset charset,
FT_Stream stream )
{
FT_Memory memory = stream->memory;
cff_charset_free_cids( charset, memory );
FT_FREE( charset->sids );
FT_FREE( charset->cids );
charset->format = 0;
charset->offset = 0;
}
static FT_Error
cff_charset_load( CFF_Charset charset,
FT_UInt num_glyphs,
@ -1672,25 +1717,7 @@
/* we have to invert the `sids' array for subsetted CID-keyed fonts */
if ( invert )
{
FT_UInt i;
FT_UShort max_cid = 0;
for ( i = 0; i < num_glyphs; i++ )
if ( charset->sids[i] > max_cid )
max_cid = charset->sids[i];
max_cid++;
if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
goto Exit;
FT_MEM_ZERO( charset->cids, sizeof ( FT_UShort ) * max_cid );
for ( i = 0; i < num_glyphs; i++ )
charset->cids[charset->sids[i]] = (FT_UShort)i;
charset->max_cid = max_cid;
}
error = cff_charset_compute_cids( charset, num_glyphs, memory );
Exit:
/* Clean up if there was an error. */
@ -1921,32 +1948,29 @@
encoding->count = 0;
error = cff_charset_compute_cids( charset, num_glyphs, stream->memory );
if (error)
goto Exit;
for ( j = 0; j < 256; j++ )
{
/* If j is encoded, find the GID for it. */
if ( encoding->sids[j] )
FT_UInt sid = encoding->sids[j];
FT_UInt gid = 0;
if ( sid )
gid = charset->cids[sid];
if ( gid != 0 )
{
for ( i = 1; i < num_glyphs; i++ )
/* We matched, so break. */
if ( charset->sids[i] == encoding->sids[j] )
break;
encoding->codes[j] = (FT_UShort)gid;
/* i will be equal to num_glyphs if we exited the above */
/* loop without a match. In this case, we also have to */
/* fix the code to SID mapping. */
if ( i == num_glyphs )
{
encoding->codes[j] = 0;
encoding->sids [j] = 0;
}
else
{
encoding->codes[j] = (FT_UShort)i;
/* update encoding count */
if ( encoding->count < j + 1 )
encoding->count = j + 1;
}
if ( encoding->count < j+1 )
encoding->count = j+1;
}
else
{
encoding->codes[j] = 0;
encoding->sids [j] = 0;
}
}
break;
@ -2013,7 +2037,7 @@
if ( error )
goto Exit;
/* if it is a CID font, we stop there */
if ( top->cid_registry != 0xFFFFU )
goto Exit;

View File

@ -71,8 +71,8 @@
FT_ULong table_size;
FT_Byte** ptable;
FT_ULong* ptable_size;
if ( vertical )
{
error = face->goto_table( face, TTAG_vmtx, stream, &table_size );
@ -91,10 +91,10 @@
ptable = &face->horz_metrics;
ptable_size = &face->horz_metrics_size;
}
if ( FT_FRAME_EXTRACT( table_size, *ptable ) )
goto Fail;
*ptable_size = table_size;
Fail:
@ -116,6 +116,7 @@
TT_LongMetrics * longs;
TT_ShortMetrics** shorts;
FT_Byte* p;
if ( vertical )
@ -175,6 +176,8 @@
if ( FT_FRAME_ENTER( table_len ) )
goto Fail;
p = stream->cursor;
{
TT_LongMetrics cur = *longs;
TT_LongMetrics limit = cur + num_longs;
@ -182,8 +185,8 @@
for ( ; cur < limit; cur++ )
{
cur->advance = FT_GET_USHORT();
cur->bearing = FT_GET_SHORT();
cur->advance = FT_NEXT_USHORT(p);
cur->bearing = FT_NEXT_SHORT(p);
}
}
@ -195,7 +198,7 @@
for ( ; cur < limit; cur++ )
*cur = FT_GET_SHORT();
*cur = FT_NEXT_SHORT(p);
/* We fill up the missing left side bearings with the */
/* last valid value. Since this will occur for buggy CJK */
@ -313,7 +316,7 @@
/*************************************************************************/
/* */
/* <Function> */
/* tt_face_get_metrics */
/* tt_face_get_metrics */
/* */
/* <Description> */
/* Returns the horizontal or vertical metrics in font units for a */