ref: 29873a0ccd69376125323ded561e271872564077
parent: e140f14232037570e241b42a3483f535a23da6e7
author: David Turner <[email protected]>
date: Mon Oct 23 06:23:17 EDT 2006
* 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 !
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,11 @@
2006-10-23 David Turner <[email protected]>
- * 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 <[email protected]>
* src/base/ftmac.c (FT_New_Face_From_FOND): Initialize variable
@@ -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'.
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -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,26 +1717,8 @@
/* we have to invert the `sids' array for subsetted CID-keyed fonts */
if ( invert )
- {
- FT_UInt i;
- FT_UShort max_cid = 0;
+ error = cff_charset_compute_cids( charset, num_glyphs, memory );
-
- 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;
- }
-
Exit:
/* Clean up if there was an error. */
if ( error )
@@ -1921,33 +1948,30 @@
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] )
- {
- for ( i = 1; i < num_glyphs; i++ )
- /* We matched, so break. */
- if ( charset->sids[i] == encoding->sids[j] )
- break;
+ FT_UInt sid = encoding->sids[j];
+ FT_UInt gid = 0;
- /* 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;
+ if ( sid )
+ gid = charset->cids[sid];
- /* update encoding count */
- if ( encoding->count < j + 1 )
- encoding->count = j + 1;
- }
+ if ( gid != 0 )
+ {
+ encoding->codes[j] = (FT_UShort)gid;
+
+ 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;
--- a/src/sfnt/ttmtx.c
+++ b/src/sfnt/ttmtx.c
@@ -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 */