From 715e96ecf43aee96dfaf793e408f0a7f842e1d6c Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Tue, 24 Oct 2006 05:28:45 +0000 Subject: [PATCH] formatting, improving ChangeLog entries --- ChangeLog | 40 ++++++++++++++++++++----- src/base/ftoutln.c | 43 ++++++++++++++++----------- src/cff/cffload.c | 44 ++++++++++++++-------------- src/pshinter/pshalgo.c | 66 +++++++++++++++++++++++++++--------------- src/sfnt/ttmtx.c | 6 ++-- 5 files changed, 126 insertions(+), 73 deletions(-) diff --git a/ChangeLog b/ChangeLog index 24cde4824..1aa0d7cee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,16 +1,40 @@ 2006-10-23 Zhe Su - * src/base/ftoutln.c: re-implementing FT_Outline_Get_Orientation to - better deal with broken Asian fonts with funky glyphs with - self-intersections and other stupid things + * src/base/ftoutln.c (FT_Outline_Get_Orientation): Re-implement to + better deal with broken Asian fonts with strange glyphs, having + self-intersections and other peculiarities. The used algorithm is + based on the nonzero winding rule. 2006-10-23 David Turner - * 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 ! + Speed up the CFF font loader. With some large CFF fonts, + FT_Open_Face is now more than three times faster. - * src/pshinter/pshalgo.c: major speed improvements to the Postscript - hinter, more than 100% speed increase on my machine + * src/cff/cffload.c (cff_get_offset): Removed. + (cff_new_index): Inline functionality of `cff_get_offset'. + (cff_charset_compute_cids, cff_charset_free_cids): New functions. + (cff_charset_done): Call `cff_charset_free_cids'. + (cff_charset_load): Call `cff_charset_compute_cids'. + (cff_encoding_load) : Ditto, to replace inefficient loop. + + * src/sfnt/ttmtx.c (tt_face_load_hmtx): Replace calls to FT_GET_XXX + with FT_NEXT_XXX. + + + Speed up the Postscript hinter, with more than 100% speed increase + on my machine. + + * src/pshinter/pshalgo.c (psh_corner_is_flat, + psh_corner_orientation): New functions. + (psh_glyph_compute_inflections): Merge loops for efficiency. + Use `psh_corner_orientation'. + (psh_glyph_init): Use `psh_corner_is_flat'. + (psh_hint_table_find_strong_point): Renamed to... + (psh_hint_table_find_strong_points): This. + Rewrite, adding argument to handle all points at once. + Update all callers. + (PSH_MAX_STRONG_INTERNAL): New macro. + (psh_glyph_interpolate_normal_points): Rewrite for efficiency. 2006-10-15 suzuki toshiya @@ -124,7 +148,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'. diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c index caee51482..46868d05a 100644 --- a/src/base/ftoutln.c +++ b/src/base/ftoutln.c @@ -947,21 +947,28 @@ FT_Vector* point; int i; - FT_Pos ray_y [3]; - int result [3]; + FT_Pos ray_y[3]; + int result[3]; + if ( !outline || outline->n_points <= 0 ) return FT_ORIENTATION_TRUETYPE; + /* We use the nonzero winding rule to find the orientation. */ + /* Since glyph outlines behave much more `regular' than arbitrary */ + /* cubic or quadratic curves, this test deals with the polygon */ + /* only which is spanned up by the control points. */ + first = outline->points; for ( contour = outline->contours; contour < outline->contours + outline->n_contours; contour++, first = last + 1 ) { - FT_Pos contour_xmin = 32768L; - FT_Pos contour_xmax = -32768L; - FT_Pos contour_ymin = 32768L; - FT_Pos contour_ymax = -32768L; + FT_Pos contour_xmin = 32768L; + FT_Pos contour_xmax = -32768L; + FT_Pos contour_ymin = 32768L; + FT_Pos contour_ymax = -32768L; + last = outline->points + *contour; @@ -999,9 +1006,9 @@ if ( xmin == 32768 ) return FT_ORIENTATION_TRUETYPE; - ray_y[0] = (xmin_ymin*3 + xmin_ymax) >> 2; - ray_y[1] = (xmin_ymin + xmin_ymax) >> 1; - ray_y[2] = (xmin_ymin + xmin_ymax*3) >> 2; + ray_y[0] = ( xmin_ymin * 3 + xmin_ymax ) >> 2; + ray_y[1] = ( xmin_ymin + xmin_ymax ) >> 1; + ray_y[2] = ( xmin_ymin + xmin_ymax * 3 ) >> 2; for ( i = 0; i < 3; i++ ) { @@ -1012,6 +1019,7 @@ FT_Vector* right1; FT_Vector* right2; + RedoRay: left_x = 32768L; right_x = -32768L; @@ -1023,19 +1031,20 @@ { FT_Pos tmp_x; + if ( point->y == ray_y[i] || prev->y == ray_y[i] ) { - ++ ray_y[i]; + ray_y[i]++; goto RedoRay; } - if ( (point->y < ray_y[i] && prev->y < ray_y[i]) || - (point->y > ray_y[i] && prev->y > ray_y[i]) ) - { + if ( ( point->y < ray_y[i] && prev->y < ray_y[i] ) || + ( point->y > ray_y[i] && prev->y > ray_y[i] ) ) continue; - } - tmp_x = FT_MulDiv( point->x - prev->x, ray_y[i] - prev->y, point->y - prev->y ) + prev->x; + tmp_x = FT_MulDiv( point->x - prev->x, + ray_y[i] - prev->y, + point->y - prev->y ) + prev->x; if ( tmp_x < left_x ) { @@ -1063,8 +1072,8 @@ } } - if ( result[0] != FT_ORIENTATION_NONE && - (result[0] == result[1] || result[0] == result[2]) ) + if ( result[0] != FT_ORIENTATION_NONE && + ( result[0] == result[1] || result[0] == result[2] ) ) return result[0]; if ( result[1] != FT_ORIENTATION_NONE && result[1] == result[2] ) diff --git a/src/cff/cffload.c b/src/cff/cffload.c index 6abd9ea5f..2b59481d9 100644 --- a/src/cff/cffload.c +++ b/src/cff/cffload.c @@ -1112,24 +1112,24 @@ switch ( offsize ) { - case 1: - for ( ; p < p_end; p++, poff++ ) - poff[0] = p[0]; - break; + 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 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; + 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); + default: + for ( ; p < p_end; p += 4, poff++ ) + poff[0] = FT_PEEK_ULONG( p ); } FT_FRAME_EXIT(); @@ -1503,10 +1503,11 @@ FT_UInt num_glyphs, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_UInt i; FT_UShort max_cid = 0; + if ( charset->max_cid > 0 ) goto Exit; @@ -1524,7 +1525,7 @@ charset->max_cid = max_cid; Exit: - return error; + return error; } @@ -1543,6 +1544,7 @@ { FT_Memory memory = stream->memory; + cff_charset_free_cids( charset, memory ); FT_FREE( charset->sids ); @@ -1551,7 +1553,6 @@ } - static FT_Error cff_charset_load( CFF_Charset charset, FT_UInt num_glyphs, @@ -1949,7 +1950,7 @@ encoding->count = 0; error = cff_charset_compute_cids( charset, num_glyphs, stream->memory ); - if (error) + if ( error ) goto Exit; for ( j = 0; j < 256; j++ ) @@ -1957,6 +1958,7 @@ FT_UInt sid = encoding->sids[j]; FT_UInt gid = 0; + if ( sid ) gid = charset->cids[sid]; @@ -1964,8 +1966,8 @@ { encoding->codes[j] = (FT_UShort)gid; - if ( encoding->count < j+1 ) - encoding->count = j+1; + if ( encoding->count < j + 1 ) + encoding->count = j + 1; } else { diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c index 3d7d98b6f..8db05dec8 100644 --- a/src/pshinter/pshalgo.c +++ b/src/pshinter/pshalgo.c @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (body). */ /* */ -/* Copyright 2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 2001, 2002, 2003, 2004, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -927,6 +927,7 @@ { FT_Int result; + /* deal with the trivial cases quickly */ if ( in_y == 0 ) { @@ -958,14 +959,15 @@ } else /* general case */ { - long long delta = (long long)in_x*out_y - (long long)in_y*out_x; + long long delta = (long long)in_x * out_y - (long long)in_y * out_x; if ( delta == 0 ) result = 0; else - result = 1 - 2*(delta < 0); + result = 1 - 2 * ( delta < 0 ); } - return result; + + return result; } @@ -1023,9 +1025,9 @@ } while ( orient_prev != 0 ); - first = start; - in_x = out_x; - in_y = out_y; + first = start; + in_x = out_x; + in_y = out_y; /* now, process all segments in the contour */ do @@ -1050,7 +1052,7 @@ } while ( orient_cur == 0 ); - if ( (orient_cur ^ orient_prev) < 0 ) + if ( ( orient_cur ^ orient_prev ) < 0 ) { do { @@ -1294,11 +1296,9 @@ else if ( point->dir_in == point->dir_out ) { - if ( point->dir_out != PSH_DIR_NONE || + if ( point->dir_out != PSH_DIR_NONE || psh_corner_is_flat( dxi, dyi, dxo, dyo ) ) - { point->flags |= PSH_POINT_SMOOTH; - } } } } @@ -1468,10 +1468,12 @@ PSH_Hint* sort = table->sort; FT_UInt num_hints = table->num_hints; + for ( ; count > 0; count--, point++ ) { - FT_Int point_dir = 0; - FT_Pos org_u = point->org_u; + FT_Int point_dir = 0; + FT_Pos org_u = point->org_u; + if ( psh_point_is_strong( point ) ) continue; @@ -1488,11 +1490,13 @@ { FT_UInt nn; + for ( nn = 0; nn < num_hints; nn++ ) { PSH_Hint hint = sort[nn]; FT_Pos d = org_u - hint->org_pos; + if ( d < threshold && -d < threshold ) { psh_point_set_strong( point ); @@ -1506,11 +1510,13 @@ { FT_UInt nn; + for ( nn = 0; nn < num_hints; nn++ ) { PSH_Hint hint = sort[nn]; FT_Pos d = org_u - hint->org_pos - hint->org_len; + if ( d < threshold && -d < threshold ) { psh_point_set_strong( point ); @@ -1547,6 +1553,7 @@ PSH_Hint hint = sort[nn]; FT_Pos d = org_u - hint->org_pos; + if ( d < threshold && -d < threshold ) { point->flags2 |= PSH_POINT_EDGE_MIN; @@ -1563,6 +1570,7 @@ PSH_Hint hint = sort[nn]; FT_Pos d = org_u - hint->org_pos - hint->org_len; + if ( d < threshold && -d < threshold ) { point->flags2 |= PSH_POINT_EDGE_MAX; @@ -1579,6 +1587,7 @@ { PSH_Hint hint = sort[nn]; + if ( org_u >= hint->org_pos && org_u <= hint->org_pos + hint->org_len ) { @@ -1821,13 +1830,14 @@ FT_Memory memory = glyph->memory; PSH_Point* strongs = NULL; - PSH_Point strongs_0[ PSH_MAX_STRONG_INTERNAL ]; + PSH_Point strongs_0[PSH_MAX_STRONG_INTERNAL]; FT_UInt num_strongs = 0; PSH_Point points = glyph->points; PSH_Point points_end = points + glyph->num_points; PSH_Point point; + /* first count the number of strong points */ for ( point = points; point < points_end; point++ ) { @@ -1838,13 +1848,15 @@ if ( num_strongs == 0 ) /* nothing to do here */ return; - /* allocate an array to store a list of points, stored in increasing org_u order */ + /* allocate an array to store a list of points, */ + /* stored in increasing org_u order */ if ( num_strongs <= PSH_MAX_STRONG_INTERNAL ) strongs = strongs_0; else { FT_Error error; + if ( !FT_NEW_ARRAY( strongs, num_strongs ) ) return; } @@ -1852,7 +1864,8 @@ num_strongs = 0; for ( point = points; point < points_end; point++ ) { - PSH_Point* insert; + PSH_Point* insert; + if ( !psh_point_is_strong( point ) ) continue; @@ -1893,6 +1906,7 @@ PSH_Point before, after; FT_UInt nn; + for ( nn = 0; nn < num_strongs; nn++ ) if ( strongs[nn]->org_u > point->org_u ) break; @@ -1902,27 +1916,30 @@ after = strongs[0]; point->cur_u = after->cur_u + - FT_MulFix( point->org_u - after->org_u, scale ); + FT_MulFix( point->org_u - after->org_u, + scale ); } else { - before = strongs[nn-1]; + before = strongs[nn - 1]; for ( nn = num_strongs; nn > 0; nn-- ) - if ( strongs[nn-1]->org_u < point->org_u ) + if ( strongs[nn - 1]->org_u < point->org_u ) break; if ( nn == num_strongs ) /* point is after last strong point */ { - before = strongs[nn-1]; + before = strongs[nn - 1]; point->cur_u = before->cur_u + - FT_MulFix( point->org_u - before->org_u, scale ); + FT_MulFix( point->org_u - before->org_u, + scale ); } else { FT_Pos u; + after = strongs[nn]; /* now interpolate point between before and after */ @@ -1936,9 +1953,9 @@ else point->cur_u = before->cur_u + - FT_MulDiv( u - before->org_u, - after->cur_u - before->cur_u, - after->org_u - before->org_u ); + FT_MulDiv( u - before->org_u, + after->cur_u - before->cur_u, + after->org_u - before->org_u ); } } psh_point_set_fitted( point ); @@ -1947,6 +1964,7 @@ if ( strongs != strongs_0 ) FT_FREE( strongs ); + #endif /* 1 */ } diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c index 2d4f02c1e..180d0cb25 100644 --- a/src/sfnt/ttmtx.c +++ b/src/sfnt/ttmtx.c @@ -185,8 +185,8 @@ for ( ; cur < limit; cur++ ) { - cur->advance = FT_NEXT_USHORT(p); - cur->bearing = FT_NEXT_SHORT(p); + cur->advance = FT_NEXT_USHORT( p ); + cur->bearing = FT_NEXT_SHORT( p ); } } @@ -198,7 +198,7 @@ for ( ; cur < limit; cur++ ) - *cur = FT_NEXT_SHORT(p); + *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 */