Index: xc/extras/freetype2/src/autofit/afhints.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/autofit/afhints.c,v retrieving revision 1.2 diff -u -r1.2 afhints.c --- a/xc/extras/freetype2/src/autofit/afhints.c 23 Apr 2004 18:42:46 -0000 1.2 +++ b/xc/extras/freetype2/src/autofit/afhints.c 28 Apr 2004 10:25:18 -0000 @@ -4,107 +4,130 @@ #include - void - af_outline_hints_dump_edges( AF_OutlineHints hints ) + static const char* af_dir_str( AF_Direction dir ) { - AF_Edge edges; - AF_Edge edge_limit; - AF_Segment segments; - FT_Int dimension; - - - edges = hints->horz_edges; - edge_limit = edges + hints->num_hedges; - segments = hints->horz_segments; + const char* result; - for ( dimension = 1; dimension >= 0; dimension-- ) + switch (dir) { - AF_Edge edge; - + case AF_DIR_UP: result = "up"; break; + case AF_DIR_DOWN: result = "down"; break; + case AF_DIR_LEFT: result = "left"; break; + case AF_DIR_RIGHT: result = "right"; break; + default: result = "none"; + } + return result; + } - printf ( "Table of %s edges:\n", - !dimension ? "vertical" : "horizontal" ); - printf ( " [ index | pos | dir | link |" - " serif | blue | opos | pos ]\n" ); +#define AF_INDEX_NUM(ptr,base) ( (ptr) ? ((ptr)-(base)) : -1 ) - for ( edge = edges; edge < edge_limit; edge++ ) - { - printf ( " [ %5d | %4d | %5s | %4d | %5d | %c | %5.2f | %5.2f ]\n", - edge - edges, - (int)edge->fpos, - edge->dir == AF_DIR_UP - ? "up" - : ( edge->dir == AF_DIR_DOWN - ? "down" - : ( edge->dir == AF_DIR_LEFT - ? "left" - : ( edge->dir == AF_DIR_RIGHT - ? "right" - : "none" ) ) ), - edge->link ? ( edge->link - edges ) : -1, - edge->serif ? ( edge->serif - edges ) : -1, - edge->blue_edge ? 'y' : 'n', - edge->opos / 64.0, - edge->pos / 64.0 ); - } - - edges = hints->vert_edges; - edge_limit = edges + hints->num_vedges; - segments = hints->vert_segments; + void + af_glyph_hints_dump_points( AF_GlyphHints hints ) + { + AF_Point points = hints->points; + AF_Point limit = points + hints->num_points; + AF_Point point; + + printf( "Table of points:\n" ); + printf( " [ index | xorg | yorg | xscale | yscale | xfit | yfit | flags ]\n" ); + for ( point = points; point < limit; point++ ) + { + printf( " [ %5d | %5d | %5d | %-5.2f | %-5.2f | %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n", + point - points, + point->fx, + point->fy, + point->ox/64.0, + point->oy/64.0, + point->x/64.0, + point->y/64.0, + (point->flags & AF_FLAG_WEAK_INTERPOLATION) ? 'w' : ' ', + (point->flags & AF_FLAG_INFLECTION) ? 'i' : ' ', + (point->flags & AF_FLAG_EXTREMA_X) ? '<' : ' ', + (point->flags & AF_FLAG_EXTREMA_Y) ? 'v' : ' ', + (point->flags & AF_FLAG_ROUND_X) ? '(' : ' ', + (point->flags & AF_FLAG_ROUND_Y) ? 'u' : ' ' + ); } + printf( "\n" ); } /* A function used to dump the array of linked segments */ void - af_outline_hints_dump_segments( AF_OutlineHints hints ) + af_glyph_hints_dump_segments( AF_GlyphHints hints ) { - AF_Segment segments; - AF_Segment segment_limit; - AF_Point points; + AF_Point points = hints->points; FT_Int dimension; - - points = hints->points; - segments = hints->horz_segments; - segment_limit = segments + hints->num_hsegments; - for ( dimension = 1; dimension >= 0; dimension-- ) { - AF_Segment seg; + AF_AxisHints axis = &hints->axis[dimension]; + AF_Segment segments = axis->segments; + AF_Segment limit = segments + axis->num_segments; + AF_Segment seg; printf ( "Table of %s segments:\n", - !dimension ? "vertical" : "horizontal" ); + dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); printf ( " [ index | pos | dir | link | serif |" " numl | first | start ]\n" ); - for ( seg = segments; seg < segment_limit; seg++ ) + for ( seg = segments; seg < limit; seg++ ) { printf ( " [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n", seg - segments, (int)seg->pos, - seg->dir == AF_DIR_UP - ? "up" - : ( seg->dir == AF_DIR_DOWN - ? "down" - : ( seg->dir == AF_DIR_LEFT - ? "left" - : ( seg->dir == AF_DIR_RIGHT - ? "right" - : "none" ) ) ), - seg->link ? ( seg->link - segments ) : -1, - seg->serif ? ( seg->serif - segments ) : -1, + af_dir_str( seg->dir ), + AF_INDEX_NUM( seg->link, segments ), + AF_INDEX_NUM( seg->serif, segments ), (int)seg->num_linked, seg->first - points, seg->last - points ); } + printf( "\n" ); + } + } + + + void + af_glyph_hints_dump_edges( AF_GlyphHints hints ) + { + FT_Int dimension; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AF_AxisHints axis = &hints->axis[ dimension ]; + AF_Edge edges = axis->edges; + AF_Edge limit = edges + axis->num_edges; + AF_Edge edge; + + /* note: AF_DIMENSION_HORZ corresponds to _vertical_ edges + * since they have constant X coordinate + */ + printf ( "Table of %s edges:\n", + dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); + printf ( " [ index | pos | dir | link |" + " serif | blue | opos | pos ]\n" ); + + for ( edge = edges; edge < limit; edge++ ) + { + printf ( " [ %5d | %4d | %5s | %4d | %5d | %c | %5.2f | %5.2f ]\n", + edge - edges, + (int)edge->fpos, + af_dir_str( edge->dir ), + AF_INDEX_NUM( edge->link, edges ), + AF_INDEX_NUM( edge->serif, edges ), + edge->blue_edge ? 'y' : 'n', + edge->opos / 64.0, + edge->pos / 64.0 ); + } - segments = hints->vert_segments; - segment_limit = segments + hints->num_vsegments; + printf( "\n" ); } } + + #endif /* AF_DEBUG */ @@ -114,8 +137,8 @@ FT_Pos dy ) { AF_Direction dir; - FT_Pos ax = ABS( dx ); - FT_Pos ay = ABS( dy ); + FT_Pos ax = FT_ABS( dx ); + FT_Pos ay = FT_ABS( dy ); dir = AF_DIR_NONE; @@ -139,15 +162,12 @@ /* compute all inflex points in a given glyph */ static void - af_outline_hints_compute_inflections( AF_OutlineHints hints ) + af_glyph_hints_compute_inflections( AF_GlyphHints hints ) { AF_Point* contour = hints->contours; AF_Point* contour_limit = contour + hints->num_contours; - /* load original coordinates in (u,v) */ - af_outline_hints_setup_uv( hints, outline, AF_UV_FXY ); - /* do each contour separately */ for ( ; contour < contour_limit; contour++ ) { @@ -172,10 +192,10 @@ if ( end == first ) goto Skip; - } while ( end->u == first->u && end->v == first->v ); + } while ( end->fx == first->fx && end->fy == first->fy ); - angle_seg = af_angle( end->u - start->u, - end->v - start->v ); + angle_seg = af_angle_atan( end->fx - start->fx, + end->fy - start->fy ); /* extend the segment start whenever possible */ before = start; @@ -188,10 +208,10 @@ if ( before == first ) goto Skip; - } while ( before->u == start->u && before->v == start->v ); + } while ( before->fx == start->fx && before->fy == start->fy ); - angle_in = af_angle( start->u - before->u, - start->v - before->v ); + angle_in = af_angle_atan( start->fx - before->fx, + start->fy - before->fy ); } while ( angle_in == angle_seg ); @@ -212,12 +232,10 @@ if ( after == first ) finished = 1; - } while ( end->u == after->u && end->v == after->v ); + } while ( end->fx == after->fx && end->fy == after->fy ); - vec.x = after->u - end->u; - vec.y = after->v - end->v; - angle_out = af_angle( after->u - end->u, - after->v - end->v ); + angle_out = af_angle_atan( after->fx - end->fx, + after->fy - end->fy ); } while ( angle_out == angle_seg ); @@ -252,17 +270,17 @@ FT_LOCAL_DEF( void ) - af_outline_hints_init( AF_OutlineHints hints, - FT_Memory memory ) + af_glyph_hints_init( AF_GlyphHints hints, + FT_Memory memory ) { FT_ZERO( hints ); hints->memory = memory; - } + } FT_LOCAL_DEF( void ) - af_outline_hints_done( AF_OutlineHints hints ) + af_glyph_hints_done( AF_GlyphHints hints ) { if ( hints && hints->memory ) { @@ -275,7 +293,7 @@ for ( dim = 0; dim < 2; dim++ ) { AF_AxisHints axis = &hints->axis[ dim ]; - + axis->num_segments = 0; axis->num_edges = 0; axis->segments = NULL; @@ -285,11 +303,11 @@ FT_FREE( hints->contours ); hints->max_contours = 0; hints->num_contours = 0; - + FT_FREE( hints->points ); hints->num_points = 0; hints->max_points = 0; - + hints->memory = NULL; } } @@ -297,23 +315,33 @@ FT_LOCAL_DEF( FT_Error ) - af_outline_hints_reset( AF_OutlineHints hints, - FT_Outline* outline, - FT_Fixed x_scale, - FT_Fixed y_scale ) + af_glyph_hints_reset( AF_GlyphHints hints, + AF_Scaler scaler, + AF_ScriptMetrics metrics, + FT_Outline* outline ) { - FT_Error error = AF_Err_Ok; - + FT_Error error = FT_Err_Ok; + AF_Point points; FT_UInt old_max, new_max; + FT_Fixed x_scale = scaler->x_scale; + FT_Fixed y_scale = scaler->y_scale; + FT_Pos x_delta = scaler->x_delta; + FT_Pos y_delta = scaler->y_delta; + FT_Memory memory = hints->memory; + + hints->metrics = metrics; + + hints->scaler_flags = scaler->flags; + hints->other_flags = 0; hints->num_points = 0; hints->num_contours = 0; - + hints->axis[0].num_segments = 0; hints->axis[0].num_edges = 0; hints->axis[1].num_segments = 0; hints->axis[1].num_edges = 0; - + /* first of all, reallocate the contours array when necessary */ new_max = (FT_UInt) outline->n_contours; @@ -321,40 +349,44 @@ if ( new_max > old_max ) { new_max = (new_max + 3) & ~3; - + if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) goto Exit; - + hints->max_contours = new_max; } - /* then, reallocate the points, segments & edges arrays if needed -- - * note that we reserved two additional point positions, used to - * hint metrics appropriately - */ + /* then, reallocate the points, segments & edges arrays if needed -- + * note that we reserved two additional point positions, used to + * hint metrics appropriately + */ new_max = (FT_UInt)( outline->n_points + 2 ); old_max = hints->max_points; if ( new_max > old_max ) { FT_Byte* items; FT_ULong off1, off2, off3; - + /* we store in a single buffer the following arrays: * * - an array of N AF_PointRec items * - an array of 2*N AF_SegmentRec items - * - an array of 2*N AF_EdgeRec items + * - an array of 2*N AF_EdgeRec items * */ - + new_max = ( new_max + 2 + 7 ) & ~7; - + +#define OFF_PAD2(x,y) (((x)+(y)-1) & ~((y)-1)) +#define OFF_PADX(x,y) ((((x)+(y)-1)/(y))*(y)) +#define OFF_PAD(x,y) ( ((y) & ((y)-1)) ? OFF_PADX(x,y) : OFF_PAD2(x,y) ) + #undef OFF_INCREMENT #define OFF_INCREMENT( _off, _type, _count ) \ - ((((_off) + sizeof(_type)) & ~(sizeof(_type)) + ((_count)*sizeof(_type))) + ( OFF_PAD( _off, sizeof(_type) ) + (_count)*sizeof(_type)) off1 = OFF_INCREMENT( 0, AF_PointRec, new_max ); - off2 = OFF_INCREMENT( off1, AF_SegmentRec, new_max ); + off2 = OFF_INCREMENT( off1, AF_SegmentRec, new_max*2 ); off3 = OFF_INCREMENT( off2, AF_EdgeRec, new_max*2 ); FT_FREE( hints->points ); @@ -368,15 +400,15 @@ hints->axis[1].edges = NULL; goto Exit; } - + /* readjust some pointers */ hints->max_points = new_max; hints->points = (AF_Point) items; - + hints->axis[0].segments = (AF_Segment)( items + off1 ); hints->axis[1].segments = hints->axis[0].segments + new_max; - + hints->axis[0].edges = (AF_Edge) ( items + off2 ); hints->axis[1].edges = hints->axis[0].edges + new_max; } @@ -400,14 +432,14 @@ hints->x_scale = x_scale; hints->y_scale = y_scale; + hints->x_delta = x_delta; + hints->y_delta = y_delta; points = hints->points; if ( hints->num_points == 0 ) goto Exit; { - /* do one thing at a time -- it is easier to understand, and */ - /* the code is clearer */ AF_Point point; AF_Point point_limit = points + hints->num_points; @@ -422,8 +454,8 @@ { point->fx = vec->x; point->fy = vec->y; - point->ox = point->x = FT_MulFix( vec->x, x_scale ); - point->oy = point->y = FT_MulFix( vec->y, y_scale ); + point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; + point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; switch ( FT_CURVE_TAG( *tag ) ) { @@ -468,7 +500,7 @@ contour_index++; if ( point + 1 < point_limit ) { - end = points + source->contours[contour_index]; + end = points + outline->contours[contour_index]; first = point + 1; prev = end; } @@ -503,14 +535,14 @@ prev = point->prev; in_x = point->fx - prev->fx; in_y = point->fy - prev->fy; - - point->in_dir = af_compute_direction( in_x, in_y ); + + point->in_dir = af_direction_compute( in_x, in_y ); next = point->next; out_x = next->fx - point->fx; out_y = next->fy - point->fy; - point->out_dir = af_compute_direction( out_x, out_y ); + point->out_dir = af_direction_compute( out_x, out_y ); if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) ) { @@ -525,8 +557,8 @@ if ( point->out_dir != AF_DIR_NONE ) goto Is_Weak_Point; - angle_in = af_angle( in_x, in_y ); - angle_out = af_angle( out_x, out_y ); + angle_in = af_angle_atan( in_x, in_y ); + angle_out = af_angle_atan( out_x, out_y ); delta = af_angle_diff( angle_in, angle_out ); if ( delta < 2 && delta > -2 ) @@ -539,8 +571,8 @@ } /* compute inflection points - */ - af_outline_hints_compute_inflections( hints ); + */ + af_glyph_hints_compute_inflections( hints ); Exit: return error; @@ -548,79 +580,407 @@ FT_LOCAL_DEF( void ) - af_outline_hints_setup_uv( AF_OutlineHints hints, - AF_UV source ) + af_glyph_hints_save( AF_GlyphHints hints, + FT_Outline* outline ) { - AF_Point point = hints->points; - AF_Point point_limit = point + hints->num_points; + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + FT_Vector* vec = outline->points; + char* tag = outline->tags; + + for ( ; point < limit; point++, vec++, tag++ ) + { + vec->x = (FT_Pos) point->x; + vec->y = (FT_Pos) point->y; + + if ( point->flags & AF_FLAG_CONIC ) + tag[0] = FT_CURVE_TAG_CONIC; + else if ( point->flags & AF_FLAG_CUBIC ) + tag[0] = FT_CURVE_TAG_CUBIC; + else + tag[0] = FT_CURVE_TAG_ON; + } + } - switch ( source ) - { - case AF_UV_FXY: - for ( ; point < point_limit; point++ ) + /* + * + * E D G E P O I N T G R I D - F I T T I N G + * + */ + + + FT_LOCAL_DEF( void ) + af_glyph_hints_align_edge_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = & hints->axis[ dim ]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + + for ( edge = edges; edge < edge_limit; edge++ ) + { + /* move the points of each segment */ + /* in each edge to the edge's position */ + AF_Segment seg = edge->first; + + + do { - point->u = point->fx; - point->v = point->fy; - } - break; + AF_Point point = seg->first; + + + for (;;) + { + if ( dim == AF_DIMENSION_HORZ ) + { + point->x = edge->pos; + point->flags |= AF_FLAG_TOUCH_X; + } + else + { + point->y = edge->pos; + point->flags |= AF_FLAG_TOUCH_Y; + } + + if ( point == seg->last ) + break; + + point = point->next; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + } + + + /* + * + * S T R O N G P O I N T I N T E R P O L A T I O N + * + */ + + + /* hint the strong points -- this is equivalent to the TrueType `IP' */ + /* hinting instruction */ + FT_LOCAL_DEF( void ) + af_glyph_hints_align_strong_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_Point points = hints->points; + AF_Point point_limit = points + hints->num_points; + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Flags touch_flag; + + + if ( dim == AF_DIMENSION_HORZ ) + touch_flag = AF_FLAG_TOUCH_X; + else + touch_flag = AF_FLAG_TOUCH_Y; + + if ( edges < edge_limit ) + { + AF_Point point; + AF_Edge edge; - case AF_UV_FYX: - for ( ; point < point_limit; point++ ) + for ( point = points; point < point_limit; point++ ) { - point->u = point->fy; - point->v = point->fx; + FT_Pos u, ou, fu; /* point position */ + FT_Pos delta; + + + if ( point->flags & touch_flag ) + continue; + + /* if this point is candidate to weak interpolation, we will */ + /* interpolate it after all strong points have been processed */ + if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) && + !( point->flags & AF_FLAG_INFLECTION ) ) + continue; + + if ( dim == AF_DIMENSION_VERT ) + { + u = point->fy; + ou = point->oy; + } + else + { + u = point->fx; + ou = point->ox; + } + + fu = u; + + /* is the point before the first edge? */ + edge = edges; + delta = edge->fpos - u; + if ( delta >= 0 ) + { + u = edge->pos - ( edge->opos - ou ); + goto Store_Point; + } + + /* is the point after the last edge? */ + edge = edge_limit - 1; + delta = u - edge->fpos; + if ( delta >= 0 ) + { + u = edge->pos + ( ou - edge->opos ); + goto Store_Point; + } + + { + FT_UInt min, max, mid; + FT_Pos fpos; + + + /* find enclosing edges */ + min = 0; + max = edge_limit - edges; + + while ( min < max ) + { + mid = ( max + min ) >> 1; + edge = edges + mid; + fpos = edge->fpos; + + if ( u < fpos ) + max = mid; + else if ( u > fpos ) + min = mid + 1; + else + { + /* we are on the edge */ + u = edge->pos; + goto Store_Point; + } + } + + { + AF_Edge before = edges + min - 1; + AF_Edge after = edges + min + 0; + + + /* assert( before && after && before != after ) */ + if ( before->scale == 0 ) + before->scale = FT_DivFix( after->pos - before->pos, + after->fpos - before->fpos ); + + u = before->pos + FT_MulFix( fu - before->fpos, + before->scale ); + } + } + + + Store_Point: + + /* save the point position */ + if ( dim == AF_DIMENSION_HORZ ) + point->x = u; + else + point->y = u; + + point->flags |= touch_flag; } - break; + } + } + + + /* + * + * W E A K P O I N T I N T E R P O L A T I O N + * + */ + + static void + af_iup_shift( AF_Point p1, + AF_Point p2, + AF_Point ref ) + { + AF_Point p; + FT_Pos delta = ref->u - ref->v; + + + for ( p = p1; p < ref; p++ ) + p->u = p->v + delta; + + for ( p = ref + 1; p <= p2; p++ ) + p->u = p->v + delta; + } + + + static void + af_iup_interp( AF_Point p1, + AF_Point p2, + AF_Point ref1, + AF_Point ref2 ) + { + AF_Point p; + FT_Pos u; + FT_Pos v1 = ref1->v; + FT_Pos v2 = ref2->v; + FT_Pos d1 = ref1->u - v1; + FT_Pos d2 = ref2->u - v2; + - case AF_UV_OXY: - for ( ; point < point_limit; point++ ) + if ( p1 > p2 ) + return; + + if ( v1 == v2 ) + { + for ( p = p1; p <= p2; p++ ) { - point->u = point->ox; - point->v = point->oy; + u = p->v; + + if ( u <= v1 ) + u += d1; + else + u += d2; + + p->u = u; } - break; + return; + } - case AF_UV_OYX: - for ( ; point < point_limit; point++ ) + if ( v1 < v2 ) + { + for ( p = p1; p <= p2; p++ ) { - point->u = point->oy; - point->v = point->ox; - } - break; + u = p->v; - case AF_UV_YX: - for ( ; point < point_limit; point++ ) + if ( u <= v1 ) + u += d1; + else if ( u >= v2 ) + u += d2; + else + u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + + p->u = u; + } + } + else + { + for ( p = p1; p <= p2; p++ ) { - point->u = point->y; - point->v = point->x; + u = p->v; + + if ( u <= v2 ) + u += d2; + else if ( u >= v1 ) + u += d1; + else + u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + + p->u = u; } - break; + } + } - case AF_UV_OX: - for ( ; point < point_limit; point++ ) + + FT_LOCAL_DEF( void ) + af_glyph_hints_align_weak_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_Point points = hints->points; + AF_Point point_limit = points + hints->num_points; + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + AF_Flags touch_flag; + AF_Point point; + AF_Point end_point; + AF_Point first_point; + + + /* PASS 1: Move segment points to edge positions */ + + if ( dim == AF_DIMENSION_HORZ ) + { + touch_flag = AF_FLAG_TOUCH_X; + + for ( point = points; point < point_limit; point++ ) { point->u = point->x; point->v = point->ox; } - break; + } + else + { + touch_flag = AF_FLAG_TOUCH_Y; - case AF_UV_OY: - for ( ; point < point_limit; point++ ) + for ( point = points; point < point_limit; point++ ) { point->u = point->y; point->v = point->oy; } - break; + } + + point = points; + + for ( ; contour < contour_limit; contour++ ) + { + point = *contour; + end_point = point->prev; + first_point = point; + + while ( point <= end_point && !( point->flags & touch_flag ) ) + point++; - default: - for ( ; point < point_limit; point++ ) + if ( point <= end_point ) { - point->u = point->x; - point->v = point->y; - } - } - } + AF_Point first_touched = point; + AF_Point cur_touched = point; + point++; + while ( point <= end_point ) + { + if ( point->flags & touch_flag ) + { + /* we found two successive touched points; we interpolate */ + /* all contour points between them */ + af_iup_interp( cur_touched + 1, point - 1, + cur_touched, point ); + cur_touched = point; + } + point++; + } + if ( cur_touched == first_touched ) + { + /* this is a special case: only one point was touched in the */ + /* contour; we thus simply shift the whole contour */ + af_iup_shift( first_point, end_point, cur_touched ); + } + else + { + /* now interpolate after the last touched point to the end */ + /* of the contour */ + af_iup_interp( cur_touched + 1, end_point, + cur_touched, first_touched ); + + /* if the first contour point isn't touched, interpolate */ + /* from the contour start to the first touched point */ + if ( first_touched > points ) + af_iup_interp( first_point, first_touched - 1, + cur_touched, first_touched ); + } + } + } + + /* now save the interpolated values back to x/y */ + if ( dim == AF_DIMENSION_HORZ ) + { + for ( point = points; point < point_limit; point++ ) + point->x = point->u; + } + else + { + for ( point = points; point < point_limit; point++ ) + point->y = point->u; + } + } Index: xc/extras/freetype2/src/autofit/afhints.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/autofit/afhints.h,v retrieving revision 1.2 diff -u -r1.2 afhints.h --- a/xc/extras/freetype2/src/autofit/afhints.h 23 Apr 2004 18:42:46 -0000 1.2 +++ b/xc/extras/freetype2/src/autofit/afhints.h 28 Apr 2004 10:25:18 -0000 @@ -6,8 +6,8 @@ FT_BEGIN_HEADER /* - * The definition of outline hints. These are shared by all - * script analysis routines + * The definition of outline glyph hints. These are shared by all + * script analysis routines (until now) * */ @@ -17,7 +17,7 @@ AF_DIMENSION_VERT = 1, /* y coordinates, i.e. horizontal segments & edges */ AF_DIMENSION_MAX /* do not remove */ - + } AF_Dimension; @@ -30,7 +30,7 @@ AF_DIR_LEFT = -1, AF_DIR_UP = 2, AF_DIR_DOWN = -2 - + } AF_Direction; @@ -38,32 +38,32 @@ typedef enum { AF_FLAG_NONE = 0, - + /* point type flags */ AF_FLAG_CONIC = (1 << 0), AF_FLAG_CUBIC = (1 << 1), AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC, - + /* point extremum flags */ AF_FLAG_EXTREMA_X = (1 << 2), AF_FLAG_EXTREMA_Y = (1 << 3), - + /* point roundness flags */ AF_FLAG_ROUND_X = (1 << 4), AF_FLAG_ROUND_Y = (1 << 5), - + /* point touch flags */ AF_FLAG_TOUCH_X = (1 << 6), AF_FLAG_TOUCH_Y = (1 << 7), - + /* candidates for weak interpolation have this flag set */ AF_FLAG_WEAK_INTERPOLATION = (1 << 8), - + /* all inflection points in the outline have this flag set */ AF_FLAG_INFLECTION = (1 << 9) - + } AF_Flags; - + /* edge hint flags */ typedef enum @@ -72,7 +72,7 @@ AF_EDGE_ROUND = (1 << 0), AF_EDGE_SERIF = (1 << 1), AF_EDGE_DONE = (1 << 2) - + } AF_Edge_Flags; @@ -110,10 +110,10 @@ AF_Edge edge; /* the segment's parent edge */ AF_Segment edge_next; /* link to next segment in parent edge */ - AF_Segment link; /* link segment */ + AF_Segment link; /* (stem) link segment */ AF_Segment serif; /* primary segment for serifs */ FT_Pos num_linked; /* number of linked segments */ - FT_Pos score; + FT_Pos score; /* used during stem matching */ AF_Point first; /* first point in edge segment */ AF_Point last; /* last point in edge segment */ @@ -131,7 +131,7 @@ AF_Edge_Flags flags; /* edge flags */ AF_Direction dir; /* edge direction */ FT_Fixed scale; /* used to speed up interpolation between edges */ - FT_Pos* blue_edge; /* non-NULL if this is a blue edge */ + AF_Width blue_edge; /* non-NULL if this is a blue edge */ AF_Edge link; AF_Edge serif; @@ -142,7 +142,6 @@ AF_Segment first; AF_Segment last; - } AF_EdgeRec; @@ -150,7 +149,7 @@ { FT_Int num_segments; AF_Segment segments; - + FT_Int num_edges; AF_Edge edges; @@ -158,13 +157,17 @@ } AF_AxisHintsRec, *AF_AxisHints; - - typedef struct AF_OutlineHintsRec_ + + typedef struct AF_GlyphHintsRec_ { FT_Memory memory; FT_Fixed x_scale; + FT_Pos x_delta; + FT_Fixed y_scale; + FT_Pos y_delta; + FT_Pos edge_distance_threshold; FT_Int max_points; @@ -176,10 +179,25 @@ AF_Point* contours; AF_AxisHintsRec axis[ AF_DIMENSION_MAX ]; + + FT_UInt32 scaler_flags; /* copy of scaler flags */ + FT_UInt32 other_flags; /* free for script-specific implementations */ + AF_ScriptMetrics metrics; - } AF_OutlineHintsRec; + } AF_GlyphHintsRec; +#define AF_HINTS_TEST_SCALER(h,f) ( (h)->scaler_flags & (f) ) +#define AF_HINTS_TEST_OTHER(h,f) ( (h)->other_flags & (f) ) + +#define AF_HINTS_DO_HORIZONTAL(h) \ + !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_HORIZONTAL) + +#define AF_HINTS_DO_VERTICAL(h) \ + !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_VERTICAL) + +#define AF_HINTS_DO_ADVANCE(h) \ + !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_ADVANCE) FT_LOCAL( AF_Direction ) @@ -188,43 +206,38 @@ FT_LOCAL( void ) - af_outline_hints_init( AF_OutlineHints hints ); + af_glyph_hints_init( AF_GlyphHints hints, + FT_Memory memory ); - /* used to set the (u,v) fields of each AF_Point in a AF_OutlineHints - * object. - */ - typedef enum AH_UV_ - { - AH_UV_FXY, /* (u,v) = (fx,fy) */ - AH_UV_FYX, /* (u,v) = (fy,fx) */ - AH_UV_OXY, /* (u,v) = (ox,oy) */ - AH_UV_OYX, /* (u,v) = (oy,ox) */ - AH_UV_OX, /* (u,v) = (ox,x) */ - AH_UV_OY, /* (u,v) = (oy,y) */ - AH_UV_YX, /* (u,v) = (y,x) */ - AH_UV_XY /* (u,v) = (x,y) * should always be last! */ - } AH_UV; - - FT_LOCAL_DEF( void ) - af_outline_hints_setup_uv( AF_OutlineHints hints, - AF_UV source ); - - - /* recomputes all AF_Point in a AF_OutlineHints from the definitions + /* recomputes all AF_Point in a AF_GlyphHints from the definitions * in a source outline */ FT_LOCAL( FT_Error ) - af_outline_hints_reset( AF_OutlineHints hints, - FT_Outline* outline, - FT_Fixed x_scale, - FT_Fixed y_scale ); + af_glyph_hints_reset( AF_GlyphHints hints, + AF_Scaler scaler, + AF_ScriptMetrics metrics, + FT_Outline* outline ); FT_LOCAL( void ) - af_outline_hints_done( AF_OutlineHints hints ); + af_glyph_hints_save( AF_GlyphHints hints, + FT_Outline* outline ); + FT_LOCAL( void ) + af_glyph_hints_align_edge_points( AF_GlyphHints hints, + AF_Dimension dim ); + FT_LOCAL( void ) + af_glyph_hints_align_strong_points( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( void ) + af_glyph_hints_align_weak_points( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( void ) + af_glyph_hints_done( AF_GlyphHints hints ); /* */ Index: xc/extras/freetype2/src/autofit/aflatin.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/autofit/aflatin.c,v retrieving revision 1.2 diff -u -r1.2 aflatin.c --- a/xc/extras/freetype2/src/autofit/aflatin.c 23 Apr 2004 18:42:46 -0000 1.2 +++ b/xc/extras/freetype2/src/autofit/aflatin.c 28 Apr 2004 10:25:19 -0000 @@ -1,8 +1,458 @@ #include "aflatin.h" + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + + static void + af_latin_metrics_init_widths( AF_LatinMetrics metrics, + FT_Face face ) + { + /* scan the array of segments in each direction */ + AF_GlyphHintsRec hints[1]; + + af_glyph_hints_init( hints, face->memory ); + + metrics->axis[ AF_DIMENSION_HORZ ].width_count = 0; + metrics->axis[ AF_DIMENSION_VERT ].width_count = 0; + + /* For now, compute the standard width and height from the `o' */ + { + FT_Error error; + FT_UInt glyph_index; + AF_Dimension dim; + AF_ScalerRec scaler[1]; + + + glyph_index = FT_Get_Char_Index( face, 'o' ); + if ( glyph_index == 0 ) + goto Exit; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || face->glyph->outline.n_points <= 0 ) + goto Exit; + + scaler->x_scale = scaler->y_scale = 0x10000L; + scaler->x_delta = scaler->y_delta = 0; + scaler->face = face; + scaler->render_mode = 0; + scaler->flags = 0; + + error = af_glyph_hints_reset( hints, scaler, + (AF_ScriptMetrics) metrics, + &face->glyph->outline ); + if ( error ) + goto Exit; + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_LatinAxis axis = & metrics->axis[ dim ]; + AF_AxisHints axhints = & hints->axis[ dim ]; + AF_Segment seg, limit, link; + FT_UInt num_widths = 0; + FT_Pos edge_distance_threshold = 32000; + + af_latin_hints_compute_segments( hints, dim ); + af_latin_hints_link_segments ( hints, dim ); + + seg = axhints->segments; + limit = seg + axhints->num_segments; + + for ( ; seg < limit; seg++ ) + { + link = seg->link; + /* we only consider stem segments there! */ + if ( link && link->link == seg && link > seg ) + { + FT_Pos dist; + + + dist = seg->pos - link->pos; + if ( dist < 0 ) + dist = -dist; + + if ( num_widths < AF_LATIN_MAX_WIDTHS ) + axis->widths[ num_widths++ ].org = dist; + } + } + + af_sort_widths( num_widths, axis->widths ); + axis->width_count = num_widths; + + /* we will now try to find the smallest width */ + if ( num_widths > 0 && axis->widths[0].org < edge_distance_threshold ) + edge_distance_threshold = axis->widths[0].org; + + /* Now, compute the edge distance threshold as a fraction of the */ + /* smallest width in the font. Set it in `hinter->glyph' too! */ + if ( edge_distance_threshold == 32000 ) + edge_distance_threshold = 50; + + /* let's try 20% */ + axis->edge_distance_threshold = edge_distance_threshold / 5; + } + } + + Exit: + af_glyph_hints_done( hints ); + } + + + +#define AF_LATIN_MAX_TEST_CHARACTERS 12 + + + static const char* const af_latin_blue_chars[ AF_LATIN_MAX_BLUES ] = + { + "THEZOCQS", + "HEZLOCUS", + "fijkdbh", + "xzroesc", + "xzroesc", + "pqgjy" + }; + + + static void + af_latin_metrics_init_blues( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_Pos flats [ AF_LATIN_MAX_TEST_CHARACTERS ]; + FT_Pos rounds[ AF_LATIN_MAX_TEST_CHARACTERS ]; + FT_Int num_flats; + FT_Int num_rounds; + FT_Int bb; + AF_LatinBlue blue; + FT_Error error; + AF_LatinAxis axis = &metrics->axis[ AF_DIMENSION_VERT ]; + FT_GlyphSlot glyph = face->glyph; + + /* we compute the blues simply by loading each character from the */ + /* 'af_latin_blue_chars[blues]' string, then compute its top-most or */ + /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ + + AF_LOG(( "blue zones computation\n" )); + AF_LOG(( "------------------------------------------------\n" )); + + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + { + const char* p = af_latin_blue_chars[bb]; + const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; + FT_Pos* blue_ref; + FT_Pos* blue_shoot; + + AF_LOG(( "blue %3d: ", bb )); + + num_flats = 0; + num_rounds = 0; + + for ( ; p < limit && *p; p++ ) + { + FT_UInt glyph_index; + FT_Vector* extremum; + FT_Vector* points; + FT_Vector* point_limit; + FT_Vector* point; + FT_Bool round; + + + AF_LOG(( "'%c'", *p )); + + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); + if ( glyph_index == 0 ) + continue; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || glyph->outline.n_points <= 0 ) + continue; + + /* now compute min or max point indices and coordinates */ + points = glyph->outline.points; + point_limit = points + glyph->outline.n_points; + point = points; + extremum = point; + point++; + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + { + for ( ; point < point_limit; point++ ) + if ( point->y > extremum->y ) + extremum = point; + } + else + { + for ( ; point < point_limit; point++ ) + if ( point->y < extremum->y ) + extremum = point; + } + + AF_LOG(( "%5d", (int)extremum->y )); + + /* now, check whether the point belongs to a straight or round */ + /* segment; we first need to find in which contour the extremum */ + /* lies, then see its previous and next points */ + { + FT_Int idx = (FT_Int)( extremum - points ); + FT_Int n; + FT_Int first, last, prev, next, end; + FT_Pos dist; + + + last = -1; + first = 0; + + for ( n = 0; n < glyph->outline.n_contours; n++ ) + { + end = glyph->outline.contours[n]; + if ( end >= idx ) + { + last = end; + break; + } + first = end + 1; + } + + /* XXX: should never happen! */ + if ( last < 0 ) + continue; + + /* now look for the previous and next points that are not on the */ + /* same Y coordinate. Threshold the `closeness'... */ + + prev = idx; + next = prev; + + do + { + if ( prev > first ) + prev--; + else + prev = last; + + dist = points[prev].y - extremum->y; + if ( dist < -5 || dist > 5 ) + break; + + } while ( prev != idx ); + + do + { + if ( next < last ) + next++; + else + next = first; + + dist = points[next].y - extremum->y; + if ( dist < -5 || dist > 5 ) + break; + + } while ( next != idx ); + + /* now, set the `round' flag depending on the segment's kind */ + round = FT_BOOL( + FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_CURVE_TAG_ON || + FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_CURVE_TAG_ON ); + + AF_LOG(( "%c ", round ? 'r' : 'f' )); + } + + if ( round ) + rounds[num_rounds++] = extremum->y; + else + flats[num_flats++] = extremum->y; + } + + AF_LOG(( "\n" )); + + if ( num_flats == 0 && num_rounds == 0 ) + { + /* we couldn't find a single glyph to compute this blue zone, + * we will simply ignore it then + */ + AF_LOG(( "empty !!\n" )); + continue; + } + + /* we have computed the contents of the `rounds' and `flats' tables, */ + /* now determine the reference and overshoot position of the blue -- */ + /* we simply take the median value after a simple sort */ + af_sort_pos( num_rounds, rounds ); + af_sort_pos( num_flats, flats ); + + blue = & axis->blues[ axis->blue_count ]; + blue_ref = & blue->ref.org; + blue_shoot = & blue->shoot.org; + + axis->blue_count ++; + + if ( num_flats == 0 ) + { + *blue_ref = + *blue_shoot = rounds[num_rounds / 2]; + } + else if ( num_rounds == 0 ) + { + *blue_ref = + *blue_shoot = flats[num_flats / 2]; + } + else + { + *blue_ref = flats[num_flats / 2]; + *blue_shoot = rounds[num_rounds / 2]; + } + + /* there are sometimes problems: if the overshoot position of top */ + /* zones is under its reference position, or the opposite for bottom */ + /* zones. We must thus check everything there and correct the errors */ + if ( *blue_shoot != *blue_ref ) + { + FT_Pos ref = *blue_ref; + FT_Pos shoot = *blue_shoot; + FT_Bool over_ref = FT_BOOL( shoot > ref ); + + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) + *blue_shoot = *blue_ref = ( shoot + ref ) / 2; + } + + blue->flags = 0; + if ( AF_LATIN_IS_TOP_BLUE(bb) ) + blue->flags |= AF_LATIN_BLUE_TOP; + + AF_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); + } + + return; + } + + + FT_LOCAL_DEF( FT_Error ) + af_latin_metrics_init( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_Error error; + FT_CharMap oldmap = face->charmap; + + /* do we have a Unicode charmap in there? */ + error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); + if ( error ) goto Exit; + + metrics->units_per_em = face->units_per_EM; + + af_latin_metrics_init_widths( metrics, face ); + af_latin_metrics_init_blues( metrics, face ); + + Exit: + FT_Set_Charmap( face, oldmap ); + return error; + } + + + static void + af_latin_metrics_scale_dim( AF_LatinMetrics metrics, + AF_Scaler scaler, + AF_Dimension dim ) + { + FT_Fixed scale; + FT_Pos delta; + AF_LatinAxis axis; + FT_UInt nn; + + if ( dim == AF_DIMENSION_HORZ ) + { + scale = scaler->x_scale; + delta = scaler->x_delta; + } + else + { + scale = scaler->y_scale; + delta = scaler->y_delta; + } + + axis = & metrics->axis[ dim ]; + + if ( axis->org_scale == scale && axis->org_delta == delta ) + return; + + axis->org_scale = scale; + axis->org_delta = delta; + + /* XXX: TODO: Correct Y and X scale according to Chester rules + */ + axis->scale = scale; + axis->delta = delta; + + if ( dim == AF_DIMENSION_HORZ ) + { + metrics->root.scaler.x_scale = scale; + metrics->root.scaler.x_delta = delta; + } + else + { + metrics->root.scaler.y_scale = scale; + metrics->root.scaler.y_delta = delta; + } + + /* scale the standard widths + */ + for ( nn = 0; nn < axis->width_count; nn++ ) + { + AF_Width width = axis->widths + nn; + + width->cur = FT_MulFix( width->org, scale ); + width->fit = width->cur; + } + + if ( dim == AF_DIMENSION_VERT ) + { + /* scale the blue zones + */ + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = & axis->blues[nn]; + FT_Pos dist; + + blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; + blue->ref.fit = blue->ref.cur; + + blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; + blue->shoot.fit = blue->shoot.cur; + + /* a blue zone is only active when it is less than 3/4 pixels tall + */ + dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); + if ( dist >= 48 || dist <= -48 ) + blue->flags |= ~AF_LATIN_BLUE_ACTIVE; + } + } + } + + + FT_LOCAL_DEF( void ) + af_latin_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ) + { + af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); + af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); + } + + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + FT_LOCAL_DEF( void ) - af_latin_hints_compute_segments( AF_OutlineHints hints, - AF_Dimension dim ) + af_latin_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ) { AF_AxisHints axis = &hints->axis[dim]; AF_Segment segments = axis->segments; @@ -10,7 +460,7 @@ FT_Int num_segments = 0; AF_Point* contour = hints->contours; AF_Point* contour_limit = contour + hints->num_contours; - AF_Direction major_dir; + AF_Direction major_dir, segment_dir; #ifdef AF_HINT_METRICS AF_Point min_point = 0; @@ -19,13 +469,32 @@ FT_Pos max_coord = -32000; #endif - major_dir = ABS( axis->major_dir ); + major_dir = FT_ABS( axis->major_dir ); segment_dir = major_dir; /* set up (u,v) in each point */ - af_setup_uv( outline, (dim == AF_DIMENSION_HORZ) - ? AF_UV_FXY, - : AF_UV_FYX ); + if ( dim == AF_DIMENSION_HORZ ) + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + for ( ; point < limit; point++ ) + { + point->u = point->fx; + point->v = point->fy; + } + } + else + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + for ( ; point < limit; point++ ) + { + point->u = point->fy; + point->v = point->fx; + } + } /* do each contour separately */ @@ -55,8 +524,8 @@ if ( point == last ) /* skip singletons -- just in case */ continue; - if ( ABS( last->out_dir ) == major_dir && - ABS( point->out_dir ) == major_dir ) + if ( FT_ABS( last->out_dir ) == major_dir && + FT_ABS( point->out_dir ) == major_dir ) { /* we are already on an edge, try to locate its start */ last = point; @@ -64,7 +533,7 @@ for (;;) { point = point->prev; - if ( ABS( point->out_dir ) != major_dir ) + if ( FT_ABS( point->out_dir ) != major_dir ) { point = point->next; break; @@ -129,7 +598,7 @@ passed = 1; } - if ( !on_edge && ABS( point->out_dir ) == major_dir ) + if ( !on_edge && FT_ABS( point->out_dir ) == major_dir ) { /* this is the start of a new segment! */ segment_dir = point->out_dir; @@ -238,8 +707,8 @@ FT_LOCAL_DEF( void ) - af_latin_hints_link_segments( AF_OutlineHints hints, - AF_Dimension dim ) + af_latin_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ) { AF_AxisHints axis = &hints->axis[dim]; AF_Segment segments = axis->segments; @@ -318,17 +787,17 @@ FT_LOCAL_DEF( void ) - af_latin_hints_compute_edges( AF_OutlineHints hints, - AF_Dimension dim ) + af_latin_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ) { AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge, edge_limit; - + AF_Segment segments = axis->segments; AF_Segment segment_limit = segments + axis->num_segments; AF_Segment seg; - + AF_Direction up_dir; FT_Fixed scale; FT_Pos edge_distance_threshold; @@ -356,7 +825,7 @@ /* */ /*********************************************************************/ - edge_distance_threshold = FT_MulFix( outline->edge_distance_threshold, + edge_distance_threshold = FT_MulFix( hints->edge_distance_threshold, scale ); if ( edge_distance_threshold > 64 / 4 ) edge_distance_threshold = 64 / 4; @@ -399,7 +868,7 @@ edge_limit++; /* clear all edge fields */ - FT_MEM_ZERO( edge, sizeof ( *edge ) ); + FT_ZERO( edge ); /* add the segment to the new edge's list */ edge->first = seg; @@ -417,7 +886,7 @@ edge->last = seg; } } - *p_num_edges = (FT_Int)( edge_limit - edges ); + axis->num_edges = (FT_Int)( edge_limit - edges ); /*********************************************************************/ @@ -519,7 +988,6 @@ else edge2 = seg2->edge; -#ifdef FT_CONFIG_CHESTER_SERIF if ( is_serif ) { edge->serif = edge2; @@ -527,12 +995,6 @@ } else edge->link = edge2; -#else /* !FT_CONFIG_CHESTER_SERIF */ - if ( is_serif ) - edge->serif = edge2; - else - edge->link = edge2; -#endif /* !FT_CONFIG_CHESTER_SERIF */ } seg = seg->edge_next; @@ -567,110 +1029,60 @@ } - /*************************************************************************/ - /* */ - /* */ - /* af_outline_detect_features */ - /* */ - /* */ - /* Performs feature detection on a given AF_OutlineRec object. */ - /* */ FT_LOCAL_DEF( void ) - af_latin_hints_detect_features( AF_OutlineHints hints, - AF_Dimension dim ) + af_latin_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ) { af_latin_hints_compute_segments( hints, dim ); af_latin_hints_link_segments ( hints, dim ); - af_latin_hints_compute_edges ( hints dim ); + af_latin_hints_compute_edges ( hints, dim ); } - /*************************************************************************/ - /* */ - /* */ - /* af_outline_compute_blue_edges */ - /* */ - /* */ - /* Computes the `blue edges' in a given outline (i.e. those that must */ - /* be snapped to a blue zone edge (top or bottom). */ - /* */ FT_LOCAL_DEF( void ) - af_latin_hints_compute_blue_edges( AF_OutlineHints outline, - AF_Face_Globals face_globals ) + af_latin_hints_compute_blue_edges( AF_GlyphHints hints, + AF_LatinMetrics metrics ) { - AF_Edge edge = outline->horz_edges; - AF_Edge edge_limit = edge + outline->num_hedges; - AF_Globals globals = &face_globals->design; - FT_Fixed y_scale = outline->y_scale; - - FT_Bool blue_active[AF_BLUE_MAX]; + AF_AxisHints axis = &hints->axis[ AF_DIMENSION_VERT ]; + AF_Edge edge = axis->edges; + AF_Edge edge_limit = edge + axis->num_edges; + AF_LatinAxis latin = &metrics->axis[ AF_DIMENSION_VERT ]; + FT_Fixed scale = latin->scale; /* compute which blue zones are active, i.e. have their scaled */ /* size < 3/4 pixels */ - { - AF_Blue blue; - FT_Bool check = 0; - - - for ( blue = AF_BLUE_CAPITAL_TOP; blue < AF_BLUE_MAX; blue++ ) - { - FT_Pos ref, shoot, dist; - - ref = globals->blue_refs[blue]; - shoot = globals->blue_shoots[blue]; - dist = ref - shoot; - if ( dist < 0 ) - dist = -dist; - - blue_active[blue] = 0; - - if ( FT_MulFix( dist, y_scale ) < 48 ) - { - blue_active[blue] = 1; - check = 1; - } - } - - /* return immediately if no blue zone is active */ - if ( !check ) - return; - } - - /* for each horizontal edge search the blue zone which is closest */ + /* for each horizontal edge search the blue zone which is closest */ for ( ; edge < edge_limit; edge++ ) { - AF_Blue blue; - FT_Pos* best_blue = 0; - FT_Pos best_dist; /* initial threshold */ + FT_Int bb; + AF_Width best_blue = NULL; + FT_Pos best_dist; /* initial threshold */ /* compute the initial threshold as a fraction of the EM size */ - best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale ); + best_dist = FT_MulFix( metrics->units_per_em / 40, scale ); -#ifdef FT_CONFIG_CHESTER_SMALL_F if ( best_dist > 64 / 2 ) best_dist = 64 / 2; -#else - if ( best_dist > 64 / 4 ) - best_dist = 64 / 4; -#endif - for ( blue = AF_BLUE_CAPITAL_TOP; blue < AF_BLUE_MAX; blue++ ) + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) { + AF_LatinBlue blue = latin->blues + bb; + FT_Bool is_top_blue, is_major_dir; + + /* skip inactive blue zones (i.e. those that are too small + */ + if ( !(blue->flags & AF_LATIN_BLUE_ACTIVE) ) + continue; + /* if it is a top zone, check for right edges -- if it is a bottom */ /* zone, check for left edges */ /* */ - /* of course, that's for TrueType XXX */ - FT_Bool is_top_blue = - FT_BOOL( AF_IS_TOP_BLUE( blue ) ); - FT_Bool is_major_dir = - FT_BOOL( edge->dir == outline->horz_major_dir ); - - - if ( !blue_active[blue] ) - continue; + /* of course, that's for TrueType */ + is_top_blue = (blue->flags & AF_LATIN_BLUE_TOP) != 0; + is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); /* if it is a top zone, the edge must be against the major */ /* direction; if it is a bottom zone, it must be in the major */ @@ -678,19 +1090,18 @@ if ( is_top_blue ^ is_major_dir ) { FT_Pos dist; - FT_Pos* blue_pos = globals->blue_refs + blue; /* first of all, compare it to the reference position */ - dist = edge->fpos - *blue_pos; + dist = edge->fpos - blue->ref.org; if ( dist < 0 ) dist = -dist; - dist = FT_MulFix( dist, y_scale ); + dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { best_dist = dist; - best_blue = blue_pos; + best_blue = & blue->ref; } /* now, compare it to the overshoot position if the edge is */ @@ -698,21 +1109,21 @@ /* top zone, or under the reference position of a bottom zone */ if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) { - FT_Bool is_under_ref = FT_BOOL( edge->fpos < *blue_pos ); + FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); if ( is_top_blue ^ is_under_ref ) { - blue_pos = globals->blue_shoots + blue; - dist = edge->fpos - *blue_pos; + blue = latin->blues + bb; + dist = edge->fpos - blue->shoot.org; if ( dist < 0 ) dist = -dist; - dist = FT_MulFix( dist, y_scale ); + dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { best_dist = dist; - best_blue = blue_pos; + best_blue = & blue->shoot; } } } @@ -725,31 +1136,654 @@ } + static FT_Error + af_latin_hints_init( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ) + { + FT_Error error; + FT_Render_Mode mode; + + error = af_glyph_hints_reset( hints, &metrics->root.scaler, + (AF_ScriptMetrics) metrics, + outline ); + if (error) + goto Exit; + + + /* compute flags depending on render mode, etc... + */ + + mode = metrics->root.scaler.render_mode; + + /* we snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) + hints->other_flags |= AF_LATIN_HINTS_HORZ_SNAP; + + /* we snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) + hints->other_flags |= AF_LATIN_HINTS_VERT_SNAP; + + /* XXX + */ + if ( mode != FT_RENDER_MODE_LIGHT ) + hints->other_flags |= AF_LATIN_HINTS_STEM_ADJUST; + + if ( mode == FT_RENDER_MODE_MONO ) + hints->other_flags |= AF_LATIN_HINTS_MONO; + + /* analyze glyph outline + */ + if ( AF_HINTS_DO_HORIZONTAL(hints) ) + af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ ); + + if ( AF_HINTS_DO_VERTICAL(hints) ) + { + af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); + af_latin_hints_compute_blue_edges( hints, metrics ); + } + + Exit: + return error; + } + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + + /* snap a given width in scaled coordinates to one of the */ + /* current standard widths */ + static FT_Pos + af_latin_snap_width( AF_Width widths, + FT_Int count, + FT_Pos width ) + { + int n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; + + + for ( n = 0; n < count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = widths[n].cur; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + scaled = FT_PIX_ROUND( reference ); + + if ( width >= reference ) + { + if ( width < scaled + 48 ) + width = reference; + } + else + { + if ( width > scaled - 48 ) + width = reference; + } + + return width; + } + + + /* compute the snapped width of a given stem */ + + static FT_Pos + af_latin_compute_stem_width( AF_GlyphHints hints, + AF_Dimension dim, + FT_Pos width, + AF_Edge_Flags base_flags, + AF_Edge_Flags stem_flags ) + { + AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; + AF_LatinAxis axis = & metrics->axis[ dim ]; + FT_Pos dist = width; + FT_Int sign = 0; + FT_Int vertical = AF_HINTS_DO_VERTICAL( hints ); + + + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) + return width; + + if ( dist < 0 ) + { + dist = -width; + sign = 1; + } + + if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) + { + /* smooth hinting process: very lightly quantize the stem width */ + /* */ + + /* leave the widths of serifs alone */ + + if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) ) + goto Done_Width; + + else if ( ( base_flags & AF_EDGE_ROUND ) ) + { + if ( dist < 80 ) + dist = 64; + } + else if ( dist < 56 ) + dist = 56; + + if ( axis->width_count > 0 ) + { + FT_Pos delta; + + /* compare to standard width + */ + if ( axis->width_count > 0 ) + { + delta = dist - axis->widths[0].cur; + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + dist = axis->widths[ 0 ].cur; + if ( dist < 48 ) + dist = 48; + + goto Done_Width; + } + } + + if ( dist < 3 * 64 ) + { + delta = dist & 63; + dist &= -64; + + if ( delta < 10 ) + dist += delta; + + else if ( delta < 32 ) + dist += 10; + + else if ( delta < 54 ) + dist += 54; + + else + dist += delta; + } + else + dist = ( dist + 32 ) & ~63; + } + } + else + { + /* strong hinting process: snap the stem width to integer pixels */ + /* */ + dist = af_latin_snap_width( axis->widths, axis->width_count, dist ); + + if ( vertical ) + { + /* in the case of vertical hinting, always round */ + /* the stem heights to integer pixels */ + if ( dist >= 64 ) + dist = ( dist + 16 ) & ~63; + else + dist = 64; + } + else + { + if ( AF_LATIN_HINTS_DO_MONO( hints ) ) + { + /* monochrome horizontal hinting: snap widths to integer pixels */ + /* with a different threshold */ + if ( dist < 64 ) + dist = 64; + else + dist = ( dist + 32 ) & ~63; + } + else + { + /* for horizontal anti-aliased hinting, we adopt a more subtle */ + /* approach: we strengthen small stems, round stems whose size */ + /* is between 1 and 2 pixels to an integer, otherwise nothing */ + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + + else if ( dist < 128 ) + dist = ( dist + 22 ) & ~63; + else + /* round otherwise to prevent color fringes in LCD mode */ + dist = ( dist + 32 ) & ~63; + } + } + } + + Done_Width: + if ( sign ) + dist = -dist; + + return dist; + } + + + + /* align one stem edge relative to the previous stem edge */ + static void + af_latin_align_linked_edge( AF_GlyphHints hints, + AF_Dimension dim, + AF_Edge base_edge, + AF_Edge stem_edge ) + { + FT_Pos dist = stem_edge->opos - base_edge->opos; + + FT_Pos fitted_width = af_latin_compute_stem_width( hints, + dim, + dist, + base_edge->flags, + stem_edge->flags ); + + stem_edge->pos = base_edge->pos + fitted_width; + } + + + static void + af_latin_align_serif_edge( AF_GlyphHints hints, + AF_Edge base, + AF_Edge serif ) + { + FT_UNUSED( hints ); + + serif->pos = base->pos + (serif->opos - base->opos); + } + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** E D G E H I N T I N G ****/ + /**** ****/ + /*************************************************************************/ /*************************************************************************/ - /* */ - /* */ - /* af_outline_scale_blue_edges */ - /* */ - /* */ - /* This function must be called before hinting in order to re-adjust */ - /* the contents of the detected edges (basically change the `blue */ - /* edge' pointer from `design units' to `scaled ones'). */ - /* */ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) - af_outline_hints_scale_blue_edges( AF_OutlineHints hints ) outline, + af_latin_hint_edges( AF_GlyphHints hints, + AF_Dimension dim ) { - AF_AxisHints axis = &hints->axis[ AF_DIMENSION_VERT ]; - AF_Edge edge = axis->edges; - AF_Edge edge_limit = edge + axis->num_edges; - FT_Pos delta; + AF_AxisHints axis = & hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + FT_Int n_edges; + AF_Edge edge; + AF_Edge anchor = 0; + FT_Int has_serifs = 0; - delta = globals->scaled.blue_refs - globals->design.blue_refs; + /* we begin by aligning all stems relative to the blue zone */ + /* if needed -- that's only for horizontal edges */ + if ( dim == AF_DIMENSION_VERT ) + { + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Width blue; + AF_Edge edge1, edge2; - for ( ; edge < edge_limit; edge++ ) + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + blue = edge->blue_edge; + edge1 = NULL; + edge2 = edge->link; + + if ( blue ) + { + edge1 = edge; + } + else if ( edge2 && edge2->blue_edge ) + { + blue = edge2->blue_edge; + edge1 = edge2; + edge2 = edge; + } + + if ( !edge1 ) + continue; + + edge1->pos = blue->fit; + edge1->flags |= AF_EDGE_DONE; + + if ( edge2 && !edge2->blue_edge ) + { + af_latin_align_linked_edge( hints, dim, edge1, edge2 ); + edge2->flags |= AF_EDGE_DONE; + } + + if ( !anchor ) + anchor = edge; + } + } + + /* now we will align all stem edges, trying to maintain the */ + /* relative order of stems in the glyph */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Edge edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + /* skip all non-stem edges */ + edge2 = edge->link; + if ( !edge2 ) + { + has_serifs++; + continue; + } + + /* now align the stem */ + + /* this should not happen, but it's better to be safe */ + if ( edge2->blue_edge || edge2 < edge ) + { + af_latin_align_linked_edge( hints, dim, edge2, edge ); + edge->flags |= AF_EDGE_DONE; + continue; + } + + if ( !anchor ) + { + FT_Pos org_len, org_center, cur_len; + FT_Pos cur_pos1, error1, error2, u_off, d_off; + + + org_len = edge2->opos - edge->opos; + cur_len = af_latin_compute_stem_width( hints, dim, org_len, + edge->flags, edge2->flags ); + if ( cur_len <= 64 ) + u_off = d_off = 32; + else + { + u_off = 38; + d_off = 26; + } + + if ( cur_len < 96 ) + { + org_center = edge->opos + ( org_len >> 1 ); + + cur_pos1 = FT_PIX_ROUND( org_center ); + + error1 = org_center - ( cur_pos1 - u_off ); + if ( error1 < 0 ) + error1 = -error1; + + error2 = org_center - ( cur_pos1 + d_off ); + if ( error2 < 0 ) + error2 = -error2; + + if ( error1 < error2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = cur_pos1 + cur_len / 2; + + } + else + edge->pos = FT_PIX_ROUND( edge->opos ); + + anchor = edge; + + edge->flags |= AF_EDGE_DONE; + + af_latin_align_linked_edge( hints, dim, edge, edge2 ); + } + else + { + FT_Pos org_pos, org_len, org_center, cur_len; + FT_Pos cur_pos1, cur_pos2, delta1, delta2; + + + org_pos = anchor->pos + ( edge->opos - anchor->opos ); + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + + cur_len = af_latin_compute_stem_width( hints, dim, org_len, + edge->flags, edge2->flags ); + + if ( cur_len < 96 ) + { + FT_Pos u_off, d_off; + + + cur_pos1 = FT_PIX_ROUND( org_center ); + + if (cur_len <= 64 ) + u_off = d_off = 32; + else + { + u_off = 38; + d_off = 26; + } + + delta1 = org_center - ( cur_pos1 - u_off ); + if ( delta1 < 0 ) + delta1 = -delta1; + + delta2 = org_center - ( cur_pos1 + d_off ); + if ( delta2 < 0 ) + delta2 = -delta2; + + if ( delta1 < delta2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = cur_pos1 + cur_len / 2; + } + else + { + org_pos = anchor->pos + ( edge->opos - anchor->opos ); + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + + cur_len = af_latin_compute_stem_width( hints, dim, org_len, + edge->flags, edge2->flags ); + + cur_pos1 = FT_PIX_ROUND( org_pos ); + delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center ); + if ( delta1 < 0 ) + delta1 = -delta1; + + cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len; + delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center ); + if ( delta2 < 0 ) + delta2 = -delta2; + + edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2; + edge2->pos = edge->pos + cur_len; + } + + edge->flags |= AF_EDGE_DONE; + edge2->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + edge->pos = edge[-1].pos; + } + } + + /* make sure that lowercase m's maintain their symmetry */ + + /* In general, lowercase m's have six vertical edges if they are sans */ + /* serif, or twelve if they are avec serif. This implementation is */ + /* based on that assumption, and seems to work very well with most */ + /* faces. However, if for a certain face this assumption is not */ + /* true, the m is just rendered like before. In addition, any stem */ + /* correction will only be applied to symmetrical glyphs (even if the */ + /* glyph is not an m), so the potential for unwanted distortion is */ + /* relatively low. */ + + /* We don't handle horizontal edges since we can't easily assure that */ + /* the third (lowest) stem aligns with the base line; it might end up */ + /* one pixel higher or lower. */ + + n_edges = edge_limit - edges; + if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) + { + AF_Edge edge1, edge2, edge3; + FT_Pos dist1, dist2, span, delta; + + + if ( n_edges == 6 ) + { + edge1 = edges; + edge2 = edges + 2; + edge3 = edges + 4; + } + else + { + edge1 = edges + 1; + edge2 = edges + 5; + edge3 = edges + 9; + } + + dist1 = edge2->opos - edge1->opos; + dist2 = edge3->opos - edge2->opos; + + span = dist1 - dist2; + if ( span < 0 ) + span = -span; + + if ( span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; + if ( edge3->link ) + edge3->link->pos -= delta; + + /* move the serifs along with the stem */ + if ( n_edges == 12 ) + { + ( edges + 8 )->pos -= delta; + ( edges + 11 )->pos -= delta; + } + + edge3->flags |= AF_EDGE_DONE; + if ( edge3->link ) + edge3->link->flags |= AF_EDGE_DONE; + } + } + + if ( has_serifs || !anchor ) + { + /* now hint the remaining edges (serifs and single) in order + * to complete our processing + */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + if ( edge->flags & AF_EDGE_DONE ) + continue; + + if ( edge->serif ) + af_latin_align_serif_edge( hints, edge->serif, edge ); + else if ( !anchor ) + { + edge->pos = FT_PIX_ROUND( edge->opos ); + anchor = edge; + } + else + edge->pos = anchor->pos + + FT_PIX_ROUND( edge->opos - anchor->opos ); + + edge->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + edge->pos = edge[-1].pos; + + if ( edge + 1 < edge_limit && + edge[1].flags & AF_EDGE_DONE && + edge->pos > edge[1].pos ) + edge->pos = edge[1].pos; + } + } + } + + + static FT_Error + af_latin_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ) + { + AF_Dimension dim; + + FT_UNUSED( metrics ); + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { - if ( edge->blue_edge ) - edge->blue_edge += delta; + if ( (dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL(hints)) || + (dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL(hints)) ) + { + af_latin_hint_edges( hints, dim ); + af_glyph_hints_align_edge_points( hints, dim ); + af_glyph_hints_align_strong_points( hints, dim ); + af_glyph_hints_align_weak_points( hints, dim ); + } } + af_glyph_hints_save( hints, outline ); + + return 0; } + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N S C R I P T C L A S S *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + + static const AF_Script_UniRangeRec af_latin_uniranges[] = + { + { 32, 127 }, /* XXX: TODO: Add new Unicode ranges here !! */ + { 160, 255 }, + { 0, 0 } + }; + + FT_LOCAL_DEF( const AF_ScriptClassRec ) af_latin_script_class = + { + AF_SCRIPT_LATIN, + af_latin_uniranges, + + sizeof( AF_LatinMetricsRec ), + (AF_Script_InitMetricsFunc) af_latin_metrics_init, + (AF_Script_ScaleMetricsFunc) af_latin_metrics_scale, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_latin_hints_init, + (AF_Script_ApplyHintsFunc) af_latin_hints_apply + }; + Index: xc/extras/freetype2/src/autofit/aflatin.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/autofit/aflatin.h,v retrieving revision 1.2 diff -u -r1.2 aflatin.h --- a/xc/extras/freetype2/src/autofit/aflatin.h 23 Apr 2004 18:42:46 -0000 1.2 +++ b/xc/extras/freetype2/src/autofit/aflatin.h 28 Apr 2004 10:25:19 -0000 @@ -4,12 +4,20 @@ #include "afhints.h" FT_BEGIN_HEADER - - /* + + /* * the latin-specific script class * */ - FT_LOCAL( const FT_ScriptClassRec ) af_latin_script_class; + FT_LOCAL( const AF_ScriptClassRec ) af_latin_script_class; + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ /* * the following declarations could be embedded in the file "aflatin.c" @@ -21,34 +29,74 @@ * Latin (global) metrics management * */ - + + enum + { + AF_LATIN_BLUE_CAPITAL_TOP, + AF_LATIN_BLUE_CAPITAL_BOTTOM, + AF_LATIN_BLUE_SMALL_F_TOP, + AF_LATIN_BLUE_SMALL_TOP, + AF_LATIN_BLUE_SMALL_BOTTOM, + AF_LATIN_BLUE_SMALL_MINOR, + + AF_LATIN_BLUE_MAX + }; + +#define AF_LATIN_IS_TOP_BLUE( b ) ( (b) == AF_LATIN_BLUE_CAPITAL_TOP || \ + (b) == AF_LATIN_BLUE_SMALL_F_TOP || \ + (b) == AF_LATIN_BLUE_SMALL_TOP ) + #define AF_LATIN_MAX_WIDTHS 16 -#define AF_LATIN_MAX_BLUES 32 +#define AF_LATIN_MAX_BLUES AF_LATIN_BLUE_MAX + + enum + { + AF_LATIN_BLUE_ACTIVE = (1 << 0), + AF_LATIN_BLUE_TOP = (1 << 1), + + AF_LATIN_BLUE_FLAG_MAX + }; + + + typedef struct AF_LatinBlueRec_ + { + AF_WidthRec ref; + AF_WidthRec shoot; + FT_UInt flags; + + } AF_LatinBlueRec, *AF_LatinBlue; + typedef struct AF_LatinAxisRec_ { - FT_Fixed scale; - FT_Pos delta; - - FT_UInt width_count; - AF_WidthRec widths[ AF_LATIN_MAX_WIDTHS ]; - + FT_Fixed scale; + FT_Pos delta; + + FT_UInt width_count; + AF_WidthRec widths[ AF_LATIN_MAX_WIDTHS ]; + FT_Pos edge_distance_threshold; + /* ignored for horizontal metrics */ - FT_Bool control_overshoot; - FT_UInt blue_count; - AF_WidthRec blue_refs [ AF_MAX_BLUES ]; - AF_WidthRec blue_shoots[ AF_MAX_BLUES ]; - + FT_Bool control_overshoot; + FT_UInt blue_count; + AF_LatinBlueRec blues[ AF_LATIN_BLUE_MAX ]; + + FT_Fixed org_scale; + FT_Pos org_delta; + } AF_LatinAxisRec, *AF_LatinAxis; - + + typedef struct AF_LatinMetricsRec_ { - AF_OutlineMetricsRec root; + AF_ScriptMetricsRec root; + FT_UInt units_per_em; AF_LatinAxisRec axis[ AF_DIMENSION_MAX ]; - + } AF_LatinMetricsRec, *AF_LatinMetrics; + FT_LOCAL( FT_Error ) af_latin_metrics_init( AF_LatinMetrics metrics, FT_Face face ); @@ -58,29 +106,60 @@ AF_Scaler scaler ); - /* - * Latin (glyph) hints management - * - */ - FT_LOCAL( + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ - FT_LOCAL( void ) - af_latin_hints_compute_segments( AF_OutlineHints hints, - AF_Dimension dim ); + enum + { + AF_LATIN_HINTS_HORZ_SNAP = (1 << 0), /* enable stem width snapping */ + AF_LATIN_HINTS_VERT_SNAP = (1 << 1), /* enable stem height snapping */ + AF_LATIN_HINTS_STEM_ADJUST = (1 << 2), /* enable stem width/height adjustment */ + AF_LATIN_HINTS_MONO = (1 << 3) /* indicate monochrome rendering */ + }; + +#define AF_LATIN_HINTS_DO_HORZ_SNAP(h) \ + AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_HORZ_SNAP) +#define AF_LATIN_HINTS_DO_VERT_SNAP(h) \ + AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_VERT_SNAP) + +#define AF_LATIN_HINTS_DO_STEM_ADJUST(h) \ + AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_STEM_ADJUST) + +#define AF_LATIN_HINTS_DO_MONO(h) \ + AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_MONO) + + + /* this shouldn't normally be exported. However, other scripts might + * like to use this function as-is + */ FT_LOCAL( void ) - af_latin_hints_link_segments( AF_OutlineHints hints, - AF_Dimension dim ); + af_latin_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ); + /* this shouldn't normally be exported. However, other scripts might + * want to use this function as-is + */ FT_LOCAL( void ) - af_latin_hints_compute_edges( AF_OutlineHints hints, - AF_Dimension dim ); + af_latin_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ); + /* this shouldn't normally be exported. However, other scripts might + * want to use this function as-is + */ FT_LOCAL( void ) - af_latin_hints_init( AF_OutlineHints hints, - AF_Dimension dim ); + af_latin_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ); + FT_LOCAL( void ) + af_latin_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ); /* */ Index: xc/extras/freetype2/src/autofit/afloader.c =================================================================== RCS file: xc/extras/freetype2/src/autofit/afloader.c diff -N xc/extras/freetype2/src/autofit/afloader.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/autofit/afloader.c 28 Apr 2004 10:25:20 -0000 @@ -0,0 +1,441 @@ +#include "afloader.h" +#include "afhints.h" +#include "afglobal.h" +#include "aflatin.h" + + FT_LOCAL_DEF( FT_Error ) + af_loader_init( AF_Loader loader, + FT_Memory memory ) + { + FT_Error error; + + FT_ZERO( loader ); + + af_glyph_hints_init( &loader->hints, memory ); + + error = FT_GlyphLoader_New( memory, &loader->gloader ); + if ( !error ) + { + error = FT_GlyphLoader_CreateExtra( loader->gloader ); + if ( error ) + { + FT_GlyphLoader_Done( loader->gloader ); + loader->gloader = NULL; + } + } + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + af_loader_reset( AF_Loader loader, + FT_Face face ) + { + FT_Error error = 0; + + loader->face = face; + loader->globals = (AF_FaceGlobals) face->autohint.data; + + FT_GlyphLoader_Rewind( loader->gloader ); + + if ( loader->globals == NULL ) + { + error = af_face_globals_new( face, &loader->globals ); + if ( !error ) + { + face->autohint.data = (FT_Pointer) loader->globals; + face->autohint.finalizer = (FT_Generic_Finalizer) af_face_globals_free; + } + } + return error; + } + + + FT_LOCAL_DEF( void ) + af_loader_done( AF_Loader loader ) + { + loader->face = NULL; + loader->globals = NULL; + + FT_GlyphLoader_Done( loader->gloader ); + loader->gloader = NULL; + } + + + static FT_Error + af_loader_load_g( AF_Loader loader, + AF_Scaler scaler, + FT_UInt glyph_index, + FT_Int32 load_flags, + FT_UInt depth ) + { + FT_Error error = 0; + FT_Face face = loader->face; + FT_GlyphLoader gloader = loader->gloader; + AF_ScriptMetrics metrics = loader->metrics; + AF_GlyphHints hints = &loader->hints; + FT_GlyphSlot slot = face->glyph; + FT_Slot_Internal internal = slot->internal; + + error = FT_Load_Glyph( face, glyph_index, load_flags ); + if ( error ) + goto Exit; + + loader->transformed = internal->glyph_transformed; + if ( loader->transformed ) + { + FT_Matrix inverse; + + loader->trans_matrix = internal->glyph_matrix; + loader->trans_delta = internal->glyph_delta; + + inverse = loader->trans_matrix; + FT_Matrix_Invert( &inverse ); + FT_Vector_Transform( &loader->trans_delta, &inverse ); + } + + /* set linear metrics */ + slot->linearHoriAdvance = slot->metrics.horiAdvance; + slot->linearVertAdvance = slot->metrics.vertAdvance; + + switch ( slot->format ) + { + case FT_GLYPH_FORMAT_OUTLINE: + /* translate the loaded glyph when an internal transform + * is needed + */ + if ( loader->transformed ) + { + FT_Vector* point = slot->outline.points; + FT_Vector* limit = point + slot->outline.n_points; + + for ( ; point < limit; point++ ) + { + point->x += loader->trans_delta.x; + point->y += loader->trans_delta.y; + } + } + + /* copy the outline points in the loader's current */ + /* extra points which is used to keep original glyph coordinates */ + error = FT_GlyphLoader_CheckPoints( gloader, + slot->outline.n_points + 4, + slot->outline.n_contours ); + if ( error ) + goto Exit; + + FT_ARRAY_COPY( gloader->current.outline.points, + slot->outline.points, + slot->outline.n_points ); + + FT_ARRAY_COPY( gloader->current.extra_points, + slot->outline.points, + slot->outline.n_points ); + + FT_ARRAY_COPY( gloader->current.outline.contours, + slot->outline.contours, + slot->outline.n_contours ); + + FT_ARRAY_COPY( gloader->current.outline.tags, + slot->outline.tags, + slot->outline.n_points ); + + gloader->current.outline.n_points = slot->outline.n_points; + gloader->current.outline.n_contours = slot->outline.n_contours; + + /* compute original horizontal phantom points (and ignore */ + /* vertical ones) */ + loader->pp1.x = hints->x_delta; + loader->pp1.y = hints->y_delta; + loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, + hints->x_scale ) + hints->x_delta; + loader->pp2.y = hints->y_delta; + + /* be sure to check for spacing glyphs */ + if ( slot->outline.n_points == 0 ) + goto Hint_Metrics; + + /* now load the slot image into the auto-outline and run the */ + /* automatic hinting process */ + error = metrics->clazz->script_hints_init( hints, + &gloader->current.outline, + metrics ); + if ( error ) + goto Exit; + + /* apply the hints */ + metrics->clazz->script_hints_apply( hints, + &gloader->current.outline, + metrics ); + /* we now need to hint the metrics according to the change in */ + /* width/positioning that occured during the hinting process */ + { + FT_Pos old_advance, old_rsb, old_lsb, new_lsb; + AF_AxisHints axis = &hints->axis[ AF_DIMENSION_HORZ ]; + AF_Edge edge1 = axis->edges; /* leftmost edge */ + AF_Edge edge2 = edge1 + axis->num_edges - 1; /* rightmost edge */ + + + old_advance = loader->pp2.x; + old_rsb = old_advance - edge2->opos; + old_lsb = edge1->opos; + new_lsb = edge1->pos; + + loader->pp1.x = FT_PIX_ROUND( new_lsb - old_lsb ); + loader->pp2.x = FT_PIX_ROUND( edge2->pos + old_rsb ); + +#if 0 + /* try to fix certain bad advance computations */ + if ( loader->pp2.x + loader->pp1.x == edge2->pos && old_rsb > 4 ) + loader->pp2.x += 64; +#endif + } + + /* good, we simply add the glyph to our loader's base */ + FT_GlyphLoader_Add( gloader ); + break; + + case FT_GLYPH_FORMAT_COMPOSITE: + { + FT_UInt nn, num_subglyphs = slot->num_subglyphs; + FT_UInt num_base_subgs, start_point; + FT_SubGlyph subglyph; + + + start_point = gloader->base.outline.n_points; + + /* first of all, copy the subglyph descriptors in the glyph loader */ + error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs ); + if ( error ) + goto Exit; + + FT_ARRAY_COPY( gloader->current.subglyphs, + slot->subglyphs, + num_subglyphs ); + + gloader->current.num_subglyphs = num_subglyphs; + num_base_subgs = gloader->base.num_subglyphs; + + /* now, read each subglyph independently */ + for ( nn = 0; nn < num_subglyphs; nn++ ) + { + FT_Vector pp1, pp2; + FT_Pos x, y; + FT_UInt num_points, num_new_points, num_base_points; + + + /* gloader.current.subglyphs can change during glyph loading due */ + /* to re-allocation -- we must recompute the current subglyph on */ + /* each iteration */ + subglyph = gloader->base.subglyphs + num_base_subgs + nn; + + pp1 = loader->pp1; + pp2 = loader->pp2; + + num_base_points = gloader->base.outline.n_points; + + error = af_loader_load_g( loader, scaler, subglyph->index, + load_flags, depth + 1 ); + if ( error ) + goto Exit; + + /* recompute subglyph pointer */ + subglyph = gloader->base.subglyphs + num_base_subgs + nn; + + if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) + { + pp1 = loader->pp1; + pp2 = loader->pp2; + } + else + { + loader->pp1 = pp1; + loader->pp2 = pp2; + } + + num_points = gloader->base.outline.n_points; + num_new_points = num_points - num_base_points; + + /* now perform the transform required for this subglyph */ + + if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE | + FT_SUBGLYPH_FLAG_XY_SCALE | + FT_SUBGLYPH_FLAG_2X2 ) ) + { + FT_Vector* cur = gloader->base.outline.points + + num_base_points; + FT_Vector* org = gloader->base.extra_points + + num_base_points; + FT_Vector* limit = cur + num_new_points; + + + for ( ; cur < limit; cur++, org++ ) + { + FT_Vector_Transform( cur, &subglyph->transform ); + FT_Vector_Transform( org, &subglyph->transform ); + } + } + + /* apply offset */ + + if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) ) + { + FT_Int k = subglyph->arg1; + FT_UInt l = subglyph->arg2; + FT_Vector* p1; + FT_Vector* p2; + + + if ( start_point + k >= num_base_points || + l >= (FT_UInt)num_new_points ) + { + error = FT_Err_Invalid_Composite; + goto Exit; + } + + l += num_base_points; + + /* for now, only use the current point coordinates; */ + /* we may consider another approach in the near future */ + p1 = gloader->base.outline.points + start_point + k; + p2 = gloader->base.outline.points + start_point + l; + + x = p1->x - p2->x; + y = p1->y - p2->y; + } + else + { + x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta; + y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta; + + x = FT_PIX_ROUND(x); + y = FT_PIX_ROUND(y); + } + + { + FT_Outline dummy = gloader->base.outline; + + + dummy.points += num_base_points; + dummy.n_points = (short)num_new_points; + + FT_Outline_Translate( &dummy, x, y ); + } + } + } + break; + + default: + /* we don't support other formats (yet?) */ + error = FT_Err_Unimplemented_Feature; + } + + Hint_Metrics: + if ( depth == 0 ) + { + FT_BBox bbox; + + + /* transform the hinted outline if needed */ + if ( loader->transformed ) + FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); + + /* we must translate our final outline by -pp1.x and compute */ + /* the new metrics */ + if ( loader->pp1.x ) + FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); + + FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); + + bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); + bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); + bbox.xMax = FT_PIX_CEIL( bbox.xMax ); + bbox.yMax = FT_PIX_CEIL( bbox.yMax ); + + slot->metrics.width = bbox.xMax - bbox.xMin; + slot->metrics.height = bbox.yMax - bbox.yMin; + slot->metrics.horiBearingX = bbox.xMin; + slot->metrics.horiBearingY = bbox.yMax; + + /* for mono-width fonts (like Andale, Courier, etc.) we need */ + /* to keep the original rounded advance width */ +#if 0 + if ( !FT_IS_FIXED_WIDTH( slot->face ) ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + else + slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, + x_scale ); +#else + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; +#endif + + slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); + + /* now copy outline into glyph slot */ + FT_GlyphLoader_Rewind( internal->loader ); + error = FT_GlyphLoader_CopyPoints( internal->loader, gloader ); + if ( error ) + goto Exit; + + slot->outline = internal->loader->base.outline; + slot->format = FT_GLYPH_FORMAT_OUTLINE; + } + +#ifdef DEBUG_HINTER + af_debug_hinter = hinter; +#endif + + Exit: + return error; + } + + + + + FT_LOCAL_DEF( FT_Error ) + af_loader_load_glyph( AF_Loader loader, + FT_Face face, + FT_UInt gindex, + FT_UInt32 load_flags ) + { + FT_Error error; + FT_Size size = face->size; + AF_ScalerRec scaler; + + if ( !size ) + return FT_Err_Invalid_Argument; + + FT_ZERO( &scaler ); + + scaler.face = face; + scaler.x_scale = size->metrics.x_scale; + scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ + scaler.y_scale = size->metrics.y_scale; + scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ + + scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); + scaler.flags = 0; /* XXX: fix this */ + + error = af_loader_reset( loader, face ); + if ( !error ) + { + AF_ScriptMetrics metrics; + + error = af_face_globals_get_metrics( loader->globals, gindex, &metrics ); + if ( !error ) + { + loader->metrics = metrics; + + metrics->scaler = scaler; + + if ( metrics->clazz->script_metrics_scale ) + metrics->clazz->script_metrics_scale( metrics, &scaler ); + + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; + load_flags &= ~FT_LOAD_RENDER; + + error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); + } + } + return error; + } Index: xc/extras/freetype2/src/autofit/afloader.h =================================================================== RCS file: xc/extras/freetype2/src/autofit/afloader.h diff -N xc/extras/freetype2/src/autofit/afloader.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/autofit/afloader.h 28 Apr 2004 10:25:20 -0000 @@ -0,0 +1,50 @@ +#ifndef __AF_LOADER_H__ +#define __AF_LOADER_H__ + +#include "afhints.h" +#include "afglobal.h" + +FT_BEGIN_HEADER + + typedef struct AF_LoaderRec_ + { + FT_Face face; /* current face */ + AF_FaceGlobals globals; /* current face globals */ + FT_GlyphLoader gloader; /* glyph loader */ + AF_GlyphHintsRec hints; + AF_ScriptMetrics metrics; + FT_Bool transformed; + FT_Matrix trans_matrix; + FT_Vector trans_delta; + FT_Vector pp1; + FT_Vector pp2; + /* we don't handle vertical phantom points */ + + } AF_LoaderRec, *AF_Loader; + + + FT_LOCAL( FT_Error ) + af_loader_init( AF_Loader loader, + FT_Memory memory ); + + + FT_LOCAL( FT_Error ) + af_loader_reset( AF_Loader loader, + FT_Face face ); + + + FT_LOCAL( void ) + af_loader_done( AF_Loader loader ); + + + FT_LOCAL( FT_Error ) + af_loader_load_glyph( AF_Loader loader, + FT_Face face, + FT_UInt gindex, + FT_UInt32 load_flags ); + +/* */ + +FT_END_HEADER + +#endif /* __AF_LOADER_H__ */ Index: xc/extras/freetype2/src/autofit/afmodule.c =================================================================== RCS file: xc/extras/freetype2/src/autofit/afmodule.c diff -N xc/extras/freetype2/src/autofit/afmodule.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/autofit/afmodule.c 28 Apr 2004 10:25:20 -0000 @@ -0,0 +1,70 @@ +#include "afmodule.h" +#include "afloader.h" +#include FT_INTERNAL_OBJECTS_H + + typedef struct FT_AutofitterRec_ + { + FT_ModuleRec root; + AF_LoaderRec loader[1]; + + } FT_AutofitterRec, *FT_Autofitter; + + + FT_CALLBACK_DEF( FT_Error ) + af_autofitter_init( FT_Autofitter module ) + { + return af_loader_init( module->loader, module->root.library->memory ); + } + + + FT_CALLBACK_DEF( void ) + af_autofitter_done( FT_Autofitter module ) + { + af_loader_done( module->loader ); + } + + + FT_CALLBACK_DEF( FT_Error ) + af_autofitter_load_glyph( FT_Autofitter module, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_UNUSED(size); + + return af_loader_load_glyph( module->loader, slot->face, + glyph_index, load_flags ); + } + + + + FT_CALLBACK_TABLE_DEF + const FT_AutoHinter_ServiceRec af_autofitter_service = + { + NULL, + NULL, + NULL, + (FT_AutoHinter_GlyphLoadFunc) af_autofitter_load_glyph + }; + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class autofit_module_class = + { + FT_MODULE_HINTER, + sizeof ( FT_AutofitterRec ), + + "autofitter", + 0x10000L, /* version 1.0 of the autofitter */ + 0x20000L, /* requires FreeType 2.0 or above */ + + (const void*) &af_autofitter_service, + + (FT_Module_Constructor) af_autofitter_init, + (FT_Module_Destructor) af_autofitter_done, + (FT_Module_Requester) 0 + }; + + +/* END */ Index: xc/extras/freetype2/src/autofit/afmodule.h =================================================================== RCS file: xc/extras/freetype2/src/autofit/afmodule.h diff -N xc/extras/freetype2/src/autofit/afmodule.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/autofit/afmodule.h 28 Apr 2004 10:25:20 -0000 @@ -0,0 +1,16 @@ +#ifndef __AFMODULE_H__ +#define __AFMODULE_H__ + +#include +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + FT_CALLBACK_TABLE + const FT_Module_Class autofit_module_class; + + +FT_END_HEADER + +#endif /* __AFMODULE_H__ */ Index: xc/extras/freetype2/src/autofit/aftypes.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/autofit/aftypes.h,v retrieving revision 1.2 diff -u -r1.2 aftypes.h --- a/xc/extras/freetype2/src/autofit/aftypes.h 23 Apr 2004 18:42:46 -0000 1.2 +++ b/xc/extras/freetype2/src/autofit/aftypes.h 28 Apr 2004 10:25:20 -0000 @@ -1,6 +1,12 @@ #ifndef __AFTYPES_H__ #define __AFTYPES_H__ +#include +#include FT_FREETYPE_H +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + FT_BEGIN_HEADER /**************************************************************************/ @@ -16,7 +22,7 @@ #ifdef AF_DEBUG # include -# define AF_LOG( x ) printf ## x +# define AF_LOG( x ) printf x #else @@ -27,15 +33,41 @@ /**************************************************************************/ /**************************************************************************/ /***** *****/ + /***** U T I L I T Y *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + typedef struct AF_WidthRec_ + { + FT_Pos org; /* original position/width in font units */ + FT_Pos cur; /* current/scaled position/width in device sub-pixels */ + FT_Pos fit; /* current/fitted position/width in device sub-pixels */ + + } AF_WidthRec, *AF_Width; + + + FT_LOCAL( void ) + af_sort_pos( FT_UInt count, + FT_Pos* table ); + + FT_LOCAL( void ) + af_sort_widths( FT_UInt count, + AF_Width widths ); + + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ /***** A N G L E T Y P E S *****/ /***** *****/ /**************************************************************************/ /**************************************************************************/ - + /* * Angle type. The auto-fitter doesn't need a very high angular accuracy, * and this allows us to speed up some computations considerably with a - * light Cordic algorithm (see afangle.c) + * light Cordic algorithm (see afangles.c) * */ @@ -51,8 +83,8 @@ * */ FT_LOCAL( AF_Angle ) - af_angle( FT_Pos dx, - FT_Pos dy ); + af_angle_atan( FT_Pos dx, + FT_Pos dy ); /* @@ -73,66 +105,27 @@ /**************************************************************************/ /**************************************************************************/ - typedef struct AF_OutlineHintsRec_* AF_OutlineHints; - - typedef struct AF_GlobalHintsRec_* AF_GlobalHints; + /* opaque handle to glyph-specific hints. see "afhints.h" for more + * details + */ + typedef struct AF_GlyphHintsRec_* AF_GlyphHints; + /* this structure is used to model an input glyph outline to + * the auto-hinter. The latter will set the "hints" field + * depending on the glyph's script + */ typedef struct AF_OutlineRec_ { - FT_Memory memory; FT_Face face; - FT_OutlineRec outline; + FT_Outline outline; FT_UInt outline_resolution; - + FT_Int advance; FT_UInt metrics_resolution; - - AF_OutlineHints hints; - - } AF_OutlineRec; - - /**************************************************************************/ - /**************************************************************************/ - /***** *****/ - /***** G L O B A L M E T R I C S *****/ - /***** *****/ - /**************************************************************************/ - /**************************************************************************/ - /* - * the following define global metrics in a _single_ dimension - * - * the "blue_refs" and "blue_shoots" arrays are ignored in - * the horizontal dimension - */ + AF_GlyphHints hints; - typedef struct AF_WidthRec_ - { - FT_Pos org; /* original position/width in font units */ - FT_Pos cur; /* current/scaled position/width in device sub-pixels */ - FT_Pos fit; /* current/fitted position/width in device sub-pixels */ - - } AF_WidthRec, *AF_Width; - - -#define AF_MAX_WIDTHS 16 -#define AF_MAX_BLUES 32 - - typedef struct AF_GlobalMetricsRec_ - { - FT_Int num_widths; - AF_WidthRec widths[ AF_MAX_WIDTHS ]; - - FT_Fixed scale; /* used to scale from org to cur with: */ - FT_Pos delta; /* x_cur = x_org * scale + delta */ - - /* ignored for horizontal metrics */ - AF_WidthRec blue_refs [ AF_MAX_BLUES ]; - AF_WidthRec blue_shoots[ AF_MAX_BLUES ]; - - FT_Bool control_overshoot; - - } AF_GlobalMetricsRec, *AF_GlobalMetrics; + } AF_OutlineRec; /**************************************************************************/ @@ -148,7 +141,7 @@ * auto-hinted glyph image * */ - + typedef enum { AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */ @@ -167,7 +160,7 @@ FT_Pos y_delta; /* in 1/64th device pixels */ FT_Render_Mode render_mode; /* monochrome, anti-aliased, LCD, etc.. */ FT_UInt32 flags; /* additionnal control flags, see above */ - + } AF_ScalerRec, *AF_Scaler; @@ -184,104 +177,90 @@ * the list of know scripts. Each different script correspond to the * following information: * - * - a set of Unicode ranges to test wether the face supports the + * - a set of Unicode ranges to test weither the face supports the * script * * - a specific global analyzer that will compute global metrics * specific to the script. * - * - a specific hinting routine + * - a specific glyph analyzer that will compute segments and + * edges for each glyph covered by the script * - * all scripts should share the same analysis routine though + * - a specific grid-fitting algorithm that will distort the + * scaled glyph outline according to the results of the glyph + * analyzer + * + * note that a given analyzer and/or grid-fitting algorithm can be + * used by more than one script */ typedef enum { - AF_SCRIPT_LATIN = 0, - /* add new scripts here */ - + AF_SCRIPT_NONE = 0, + AF_SCRIPT_LATIN = 1, + /* add new scripts here. don't forget to update the list in "afglobal.c" */ + AF_SCRIPT_MAX /* do not remove */ - + } AF_Script; + typedef struct AF_ScriptClassRec_ const* AF_ScriptClass; - /* - * root class for script-specific metrics - */ typedef struct AF_ScriptMetricsRec_ { - AF_ScriptClass script_class; - AF_GlobalMetricsRec horz_metrics; - AF_GlobalMetricsRec vert_metrics; + AF_ScriptClass clazz; + AF_ScalerRec scaler; } AF_ScriptMetricsRec, *AF_ScriptMetrics; /* this function parses a FT_Face to compute global metrics for * a specific script - */ - typedef FT_Error (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics, - FT_Face face ); + */ + typedef FT_Error (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics, + FT_Face face ); typedef void (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics, AF_Scaler scaler ); - typedef void (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics ); + typedef void (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics ); - typedef FT_Error (*AF_Script_InitHintsFunc)( AF_OutlineHints hints, - AF_Scaler scaler, + typedef FT_Error (*AF_Script_InitHintsFunc)( AF_GlyphHints hints, + FT_Outline* outline, AF_ScriptMetrics metrics ); - typedef void (*AF_Script_ApplyHintsFunc)( AF_OutlineHints hints ); - + typedef void (*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints, + FT_Outline* outline, + AF_ScriptMetrics metrics ); + typedef struct AF_Script_UniRangeRec_ { FT_UInt32 first; FT_UInt32 last; - - } AF_Script_UniRangeRec, *AF_Script_UniRange; - + + } AF_Script_UniRangeRec; + + typedef const AF_Script_UniRangeRec * AF_Script_UniRange; typedef struct AF_ScriptClassRec_ { AF_Script script; - AF_Scipt_UniRange script_uni_ranges; /* last must be { 0, 0 } */ + AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */ FT_UInt script_metrics_size; AF_Script_InitMetricsFunc script_metrics_init; AF_Script_ScaleMetricsFunc script_metrics_scale; AF_Script_DoneMetricsFunc script_metrics_done; - } AF_ScriptClassRec; + AF_Script_InitHintsFunc script_hints_init; + AF_Script_ApplyHintsFunc script_hints_apply; + } AF_ScriptClassRec; - /**************************************************************************/ - /**************************************************************************/ - /***** *****/ - /***** F A C E G L O B A L S *****/ - /***** *****/ - /**************************************************************************/ - /**************************************************************************/ - - /* - * models the global hints data for a given face, decomposed into - * script-specific items.. - * - */ - typedef struct AF_FaceGlobalsRec_ - { - FT_Face face; - FT_UInt glyph_count; /* same as face->num_glyphs */ - FT_Byte* glyph_scripts; /* maps each gindex to a script */ - - FT_ScriptMetrics metrics[ AF_SCRIPT_MAX ]; - - } AF_FaceGlobalsRec, *AF_FaceGlobals; - /* */ FT_END_HEADER Index: xc/extras/freetype2/src/autofit/autofit.c =================================================================== RCS file: xc/extras/freetype2/src/autofit/autofit.c diff -N xc/extras/freetype2/src/autofit/autofit.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/autofit/autofit.c 28 Apr 2004 10:25:20 -0000 @@ -0,0 +1,9 @@ +#define FT_MAKE_OPTION_SINGLE_OBJECT +#include +#include "afangles.c" +#include "afglobal.c" +#include "afhints.c" +#include "afdummy.c" +#include "aflatin.c" +#include "afloader.c" +#include "afmodule.c" Index: xc/extras/freetype2/src/autohint/ahglobal.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/ahglobal.c,v retrieving revision 1.2 diff -u -r1.2 ahglobal.c --- a/xc/extras/freetype2/src/autohint/ahglobal.c 23 Apr 2004 18:42:46 -0000 1.2 +++ b/xc/extras/freetype2/src/autohint/ahglobal.c 28 Apr 2004 10:25:21 -0000 @@ -4,7 +4,7 @@ /* */ /* Routines used to compute global metrics automatically (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003 Catharon Productions Inc. */ +/* Copyright 2000-2001, 2002, 2003, 2004 Catharon Productions Inc. */ /* Author: David Turner */ /* */ /* This file is part of the Catharon Typography Project and shall only */ @@ -95,7 +95,7 @@ goto Exit; /* we compute the blues simply by loading each character from the */ - /* 'blue_chars[blues]' string, then compute its top-most or */ + /* `blue_chars[blues]' string, then compute its top-most or */ /* bottom-most points (depending on `AH_IS_TOP_BLUE') */ AH_LOG(( "blue zones computation\n" )); Index: xc/extras/freetype2/src/autohint/ahglyph.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/ahglyph.c,v retrieving revision 1.2 diff -u -r1.2 ahglyph.c --- a/xc/extras/freetype2/src/autohint/ahglyph.c 23 Apr 2004 18:42:46 -0000 1.2 +++ b/xc/extras/freetype2/src/autohint/ahglyph.c 28 Apr 2004 10:25:22 -0000 @@ -5,7 +5,7 @@ /* Routines used to load and analyze a given glyph before hinting */ /* (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003 Catharon Productions Inc. */ +/* Copyright 2000-2001, 2002, 2003, 2004 Catharon Productions Inc. */ /* Author: David Turner */ /* */ /* This file is part of the Catharon Typography Project and shall only */ @@ -141,8 +141,8 @@ FT_Pos dy ) { AH_Direction dir; - FT_Pos ax = ABS( dx ); - FT_Pos ay = ABS( dy ); + FT_Pos ax = FT_ABS( dx ); + FT_Pos ay = FT_ABS( dy ); dir = AH_DIR_NONE; @@ -418,7 +418,7 @@ /* first of all, reallocate the contours array if necessary */ if ( num_contours > outline->max_contours ) { - FT_Int new_contours = ( num_contours + 3 ) & -4; + FT_Int new_contours = FT_PAD_CEIL( num_contours, 4 ); if ( FT_RENEW_ARRAY( outline->contours, @@ -435,7 +435,7 @@ /* */ if ( num_points + 2 > outline->max_points ) { - FT_Int news = ( num_points + 2 + 7 ) & -8; + FT_Int news = FT_PAD_CEIL( num_points + 2, 8 ); FT_Int max = outline->max_points; @@ -884,8 +884,8 @@ if ( point == last ) /* skip singletons -- just in case */ continue; - if ( ABS( last->out_dir ) == major_dir && - ABS( point->out_dir ) == major_dir ) + if ( FT_ABS( last->out_dir ) == major_dir && + FT_ABS( point->out_dir ) == major_dir ) { /* we are already on an edge, try to locate its start */ last = point; @@ -893,7 +893,7 @@ for (;;) { point = point->prev; - if ( ABS( point->out_dir ) != major_dir ) + if ( FT_ABS( point->out_dir ) != major_dir ) { point = point->next; break; @@ -958,7 +958,7 @@ passed = 1; } - if ( !on_edge && ABS( point->out_dir ) == major_dir ) + if ( !on_edge && FT_ABS( point->out_dir ) == major_dir ) { /* this is the start of a new segment! */ segment_dir = point->out_dir; Index: xc/extras/freetype2/src/autohint/ahhint.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/ahhint.c,v retrieving revision 1.2 diff -u -r1.2 ahhint.c --- a/xc/extras/freetype2/src/autohint/ahhint.c 23 Apr 2004 18:42:46 -0000 1.2 +++ b/xc/extras/freetype2/src/autohint/ahhint.c 28 Apr 2004 10:25:24 -0000 @@ -4,7 +4,7 @@ /* */ /* Glyph hinter (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003 Catharon Productions Inc. */ +/* Copyright 2000-2001, 2002, 2003, 2004 Catharon Productions Inc. */ /* Author: David Turner */ /* */ /* This file is part of the Catharon Typography Project and shall only */ @@ -71,7 +71,7 @@ } } - scaled = ( reference + 32 ) & -64; + scaled = FT_PIX_ROUND( reference ); if ( width >= reference ) { @@ -167,7 +167,7 @@ dist += delta; } else - dist = ( dist + 32 ) & -64; + dist = ( dist + 32 ) & ~63; } } else @@ -181,7 +181,7 @@ /* in the case of vertical hinting, always round */ /* the stem heights to integer pixels */ if ( dist >= 64 ) - dist = ( dist + 16 ) & -64; + dist = ( dist + 16 ) & ~63; else dist = 64; } @@ -196,7 +196,7 @@ if ( dist < 64 ) dist = 64; else - dist = ( dist + 32 ) & -64; + dist = ( dist + 32 ) & ~63; } else { @@ -207,10 +207,10 @@ dist = ( dist + 64 ) >> 1; else if ( dist < 128 ) - dist = ( dist + 22 ) & -64; + dist = ( dist + 22 ) & ~63; else /* XXX: round otherwise to prevent color fringes in LCD mode */ - dist = ( dist + 32 ) & -64; + dist = ( dist + 32 ) & ~63; } } } @@ -284,7 +284,7 @@ dist += delta; } else - dist = ( dist + 32 ) & -64; + dist = ( dist + 32 ) & ~63; } } else @@ -298,7 +298,7 @@ /* in the case of vertical hinting, always round */ /* the stem heights to integer pixels */ if ( dist >= 64 ) - dist = ( dist + 16 ) & -64; + dist = ( dist + 16 ) & ~63; else dist = 64; } @@ -313,7 +313,7 @@ if ( dist < 64 ) dist = 64; else - dist = ( dist + 32 ) & -64; + dist = ( dist + 32 ) & ~63; } else { @@ -324,10 +324,10 @@ dist = ( dist + 64 ) >> 1; else if ( dist < 128 ) - dist = ( dist + 22 ) & -64; + dist = ( dist + 22 ) & ~63; else /* XXX: round otherwise to prevent color fringes in LCD mode */ - dist = ( dist + 32 ) & -64; + dist = ( dist + 32 ) & ~63; } } } @@ -396,7 +396,7 @@ if ( base->flags & AH_EDGE_DONE ) { if ( dist >= 64 ) - dist = ( dist + 8 ) & -64; + dist = ( dist + 8 ) & ~63; else if ( dist <= 32 && !vertical ) dist = ( dist + 33 ) >> 1; @@ -545,7 +545,7 @@ { org_center = edge->opos + ( org_len >> 1 ); - cur_pos1 = ( org_center + 32 ) & -64; + cur_pos1 = FT_PIX_ROUND( org_center ); error1 = org_center - ( cur_pos1 - u_off ); if ( error1 < 0 ) @@ -565,7 +565,7 @@ } else - edge->pos = ( edge->opos + 32 ) & -64; + edge->pos = FT_PIX_ROUND( edge->opos ); anchor = edge; @@ -575,7 +575,7 @@ #else /* !FT_CONFIG_CHESTER_STEM */ - edge->pos = ( edge->opos + 32 ) & -64; + edge->pos = FT_PIX_ROUND( edge->opos ); anchor = edge; edge->flags |= AH_EDGE_DONE; @@ -614,7 +614,7 @@ FT_Pos u_off, d_off; - cur_pos1 = ( org_center + 32 ) & -64; + cur_pos1 = FT_PIX_ROUND( org_center ); if (cur_len <= 64 ) u_off = d_off = 32; @@ -649,12 +649,12 @@ cur_len = ah_compute_stem_width( hinter, dimension, org_len, edge->flags, edge2->flags ); - cur_pos1 = ( org_pos + 32 ) & -64; + cur_pos1 = FT_PIX_ROUND( org_pos ); delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center ); if ( delta1 < 0 ) delta1 = -delta1; - cur_pos2 = ( ( org_pos + org_len + 32 ) & -64 ) - cur_len; + cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len; delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center ); if ( delta2 < 0 ) delta2 = -delta2; @@ -665,12 +665,12 @@ #else /* !FT_CONFIG_CHESTER_STEM */ - cur_pos1 = ( org_pos + 32 ) & -64; + cur_pos1 = FT_PIX_ROUND( org_pos ); delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center ); if ( delta1 < 0 ) delta1 = -delta1; - cur_pos2 = ( ( org_pos + org_len + 32 ) & -64 ) - cur_len; + cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len; delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center ); if ( delta2 < 0 ) delta2 = -delta2; @@ -703,7 +703,7 @@ /* the third (lowest) stem aligns with the base line; it might end up */ /* one pixel higher or lower. */ - n_edges = edge_limit - edges; + n_edges = (FT_Int)( edge_limit - edges ); if ( !dimension && ( n_edges == 6 || n_edges == 12 ) ) { AH_EdgeRec *edge1, *edge2, *edge3; @@ -764,12 +764,12 @@ ah_align_serif_edge( hinter, edge->serif, edge, dimension ); else if ( !anchor ) { - edge->pos = ( edge->opos + 32 ) & -64; + edge->pos = FT_PIX_ROUND( edge->opos ); anchor = edge; } else edge->pos = anchor->pos + - ( ( edge->opos-anchor->opos + 32 ) & -64 ); + FT_PIX_ROUND( edge->opos - anchor->opos ); edge->flags |= AH_EDGE_DONE; @@ -943,7 +943,7 @@ /* find enclosing edges */ min = 0; - max = edge_limit - edges; + max = (FT_UInt)( edge_limit - edges ); while ( min < max ) { @@ -1299,15 +1299,16 @@ if ( delta2 < 32 ) delta2 = 0; else if ( delta2 < 64 ) - delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & -32 ); + delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); else - delta2 = ( delta2 + 32 ) & -64; + delta2 = FT_PIX_ROUND( delta2 ); if ( delta < 0 ) delta2 = -delta2; scaled->blue_refs[n] = - ( FT_MulFix( design->blue_refs[n], y_scale ) + 32 ) & -64; + FT_PIX_ROUND( FT_MulFix( design->blue_refs[n], y_scale ) ); + scaled->blue_shoots[n] = scaled->blue_refs[n] + delta2; } @@ -1488,24 +1489,24 @@ /* copy the outline points in the loader's current */ /* extra points which is used to keep original glyph coordinates */ - error = ah_loader_check_points( gloader, slot->outline.n_points + 2, + error = ah_loader_check_points( gloader, slot->outline.n_points + 4, slot->outline.n_contours ); if ( error ) goto Exit; - FT_MEM_COPY( gloader->current.extra_points, slot->outline.points, - slot->outline.n_points * sizeof ( FT_Vector ) ); + FT_ARRAY_COPY( gloader->current.extra_points, slot->outline.points, + slot->outline.n_points ); - FT_MEM_COPY( gloader->current.outline.contours, slot->outline.contours, - slot->outline.n_contours * sizeof ( short ) ); + FT_ARRAY_COPY( gloader->current.outline.contours, slot->outline.contours, + slot->outline.n_contours ); - FT_MEM_COPY( gloader->current.outline.tags, slot->outline.tags, - slot->outline.n_points * sizeof ( char ) ); + FT_ARRAY_COPY( gloader->current.outline.tags, slot->outline.tags, + slot->outline.n_points ); gloader->current.outline.n_points = slot->outline.n_points; gloader->current.outline.n_contours = slot->outline.n_contours; - /* compute original phantom points */ + /* compute original horizontal phantom points, ignoring vertical ones */ hinter->pp1.x = 0; hinter->pp1.y = 0; hinter->pp2.x = FT_MulFix( slot->metrics.horiAdvance, x_scale ); @@ -1539,6 +1540,7 @@ /* we now need to hint the metrics according to the change in */ /* width/positioning that occured during the hinting process */ + if ( outline->num_vedges > 0 ) { FT_Pos old_advance, old_rsb, old_lsb, new_lsb; AH_Edge edge1 = outline->vert_edges; /* leftmost edge */ @@ -1551,8 +1553,8 @@ old_lsb = edge1->opos; new_lsb = edge1->pos; - hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64; - hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64; + hinter->pp1.x = FT_PIX_ROUND( new_lsb - old_lsb ); + hinter->pp2.x = FT_PIX_ROUND( edge2->pos + old_rsb ); #if 0 /* try to fix certain bad advance computations */ @@ -1561,6 +1563,12 @@ #endif } + else + { + hinter->pp1.x = ( hinter->pp1.x + 32 ) & -64; + hinter->pp2.x = ( hinter->pp2.x + 32 ) & -64; + } + /* good, we simply add the glyph to our loader's base */ ah_loader_add( gloader ); break; @@ -1579,8 +1587,8 @@ if ( error ) goto Exit; - FT_MEM_COPY( gloader->current.subglyphs, slot->subglyphs, - num_subglyphs * sizeof ( FT_SubGlyph ) ); + FT_ARRAY_COPY( gloader->current.subglyphs, slot->subglyphs, + num_subglyphs ); gloader->current.num_subglyphs = num_subglyphs; num_base_subgs = gloader->base.num_subglyphs; @@ -1677,8 +1685,8 @@ x = FT_MulFix( subglyph->arg1, x_scale ); y = FT_MulFix( subglyph->arg2, y_scale ); - x = ( x + 32 ) & -64; - y = ( y + 32 ) & -64; + x = FT_PIX_ROUND(x); + y = FT_PIX_ROUND(y); } { @@ -1715,10 +1723,10 @@ FT_Outline_Translate( &gloader->base.outline, -hinter->pp1.x, 0 ); FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); - bbox.xMin &= -64; - bbox.yMin &= -64; - bbox.xMax = ( bbox.xMax + 63 ) & -64; - bbox.yMax = ( bbox.yMax + 63 ) & -64; + bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); + bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); + bbox.xMax = FT_PIX_CEIL( bbox.xMax ); + bbox.yMax = FT_PIX_CEIL( bbox.yMax ); slot->metrics.width = bbox.xMax - bbox.xMin; slot->metrics.height = bbox.yMax - bbox.yMin; @@ -1733,7 +1741,7 @@ slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, x_scale ); - slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + 32 ) & -64; + slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); /* now copy outline into glyph slot */ ah_loader_rewind( slot->internal->loader ); @@ -1802,7 +1810,7 @@ if ( shoot > 0 ) { FT_Pos scaled = FT_MulFix( shoot, y_scale ); - FT_Pos fitted = ( scaled + 32 ) & -64; + FT_Pos fitted = FT_PIX_ROUND( scaled ); if ( scaled != fitted ) Index: xc/extras/freetype2/src/autohint/ahtypes.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/ahtypes.h,v retrieving revision 1.2 diff -u -r1.2 ahtypes.h --- a/xc/extras/freetype2/src/autohint/ahtypes.h 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/autohint/ahtypes.h 28 Apr 2004 10:25:25 -0000 @@ -5,7 +5,7 @@ /* General types and definitions for the auto-hint module */ /* (specification only). */ /* */ -/* Copyright 2000-2001, 2002, 2003 Catharon Productions Inc. */ +/* Copyright 2000-2001, 2002, 2003, 2004 Catharon Productions Inc. */ /* Author: David Turner */ /* */ /* This file is part of the Catharon Typography Project and shall only */ @@ -492,8 +492,9 @@ AH_Outline glyph; AH_Loader loader; - FT_Vector pp1; + FT_Vector pp1; /* horizontal phantom points */ FT_Vector pp2; + /* we ignore vertical phantom points */ FT_Bool transformed; FT_Vector trans_delta; Index: xc/extras/freetype2/src/base/Jamfile =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/Jamfile,v retrieving revision 1.2 diff -u -r1.2 Jamfile --- a/xc/extras/freetype2/src/base/Jamfile 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/Jamfile 28 Apr 2004 10:25:25 -0000 @@ -1,4 +1,4 @@ -# FreeType 2 src/base Jamfile (c) 2001, 2002, 2003 David Turner +# FreeType 2 src/base Jamfile (c) 2001, 2002, 2003, 2004 David Turner # SubDir FT2_TOP $(FT2_SRC_DIR) base ; @@ -10,7 +10,7 @@ if $(FT2_MULTI) { _sources = ftutil ftdbgmem ftstream ftcalc fttrigon ftgloadr ftoutln - ftobjs ftnames ; + ftobjs ftnames ftrfork ; } else { @@ -24,8 +24,7 @@ # Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c ftbdf.c ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c - ftstroke.c ftwinfnt.c - ; + ftstroke.c ftwinfnt.c ; # Add Macintosh-specific file to the library when necessary. # Index: xc/extras/freetype2/src/base/descrip.mms =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/descrip.mms,v retrieving revision 1.2 diff -u -r1.2 descrip.mms --- a/xc/extras/freetype2/src/base/descrip.mms 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/descrip.mms 28 Apr 2004 10:25:25 -0000 @@ -3,7 +3,7 @@ # -# Copyright 2001, 2003 by +# Copyright 2001, 2003, 2004 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,7 +15,7 @@ CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.builds.vms],[--.include],[--.src.base]) -OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj,ftstroke.obj,ftwinfnt.obj +OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj,ftstroke.obj,ftwinfnt.obj,ftbbox.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) Index: xc/extras/freetype2/src/base/ftbase.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftbase.c,v retrieving revision 1.2 diff -u -r1.2 ftbase.c --- a/xc/extras/freetype2/src/base/ftbase.c 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/ftbase.c 28 Apr 2004 10:25:25 -0000 @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,6 +29,7 @@ #include "ftgloadr.c" #include "ftobjs.c" #include "ftnames.c" +#include "ftrfork.c" #if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON ) #include "ftmac.c" Index: xc/extras/freetype2/src/base/ftcalc.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftcalc.c,v retrieving revision 1.2 diff -u -r1.2 ftcalc.c --- a/xc/extras/freetype2/src/base/ftcalc.c 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/ftcalc.c 28 Apr 2004 10:25:26 -0000 @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -74,8 +74,8 @@ FT_EXPORT_DEF( FT_Fixed ) FT_RoundFix( FT_Fixed a ) { - return ( a >= 0 ) ? ( a + 0x8000L ) & -0x10000L - : -((-a + 0x8000L ) & -0x10000L ); + return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL + : -((-a + 0x8000L ) & ~0xFFFFL ); } @@ -84,8 +84,8 @@ FT_EXPORT_DEF( FT_Fixed ) FT_CeilFix( FT_Fixed a ) { - return ( a >= 0 ) ? ( a + 0xFFFFL ) & -0x10000L - : -((-a + 0xFFFFL ) & -0x10000L ); + return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL + : -((-a + 0xFFFFL ) & ~0xFFFFL ); } @@ -94,8 +94,8 @@ FT_EXPORT_DEF( FT_Fixed ) FT_FloorFix( FT_Fixed a ) { - return ( a >= 0 ) ? a & -0x10000L - : -((-a) & -0x10000L ); + return ( a >= 0 ) ? a & ~0xFFFFL + : -((-a) & ~0xFFFFL ); } @@ -155,6 +155,33 @@ } +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ) + { + FT_Int s; + FT_Long d; + + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + if ( c < 0 ) { c = -c; s = -s; } + + d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c + : 0x7FFFFFFFL ); + + return ( s > 0 ) ? d : -d; + } + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) @@ -298,14 +325,13 @@ if ( a == 0 || b == c ) return a; - s = a; a = ABS( a ); - s ^= b; b = ABS( b ); - s ^= c; c = ABS( c ); + s = a; a = FT_ABS( a ); + s ^= b; b = FT_ABS( b ); + s ^= c; c = FT_ABS( c ); if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) - { a = ( a * b + ( c >> 1 ) ) / c; - } + else if ( c > 0 ) { FT_Int64 temp, temp2; @@ -325,6 +351,43 @@ } +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + FT_BASE_DEF( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ) + { + long s; + + + if ( a == 0 || b == c ) + return a; + + s = a; a = FT_ABS( a ); + s ^= b; b = FT_ABS( b ); + s ^= c; c = FT_ABS( c ); + + if ( a <= 46340L && b <= 46340L && c > 0 ) + a = a * b / c; + + else if ( c > 0 ) + { + FT_Int64 temp; + + + ft_multo64( a, b, &temp ); + a = ft_div64by32( temp.hi, temp.lo, c ); + } + else + a = 0x7FFFFFFFL; + + return ( s < 0 ? -a : a ); + } + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) @@ -338,8 +401,8 @@ if ( a == 0 || b == 0x10000L ) return a; - s = a; a = ABS(a); - s ^= b; b = ABS(b); + s = a; a = FT_ABS(a); + s ^= b; b = FT_ABS(b); ua = (FT_ULong)a; ub = (FT_ULong)b; @@ -371,8 +434,8 @@ FT_UInt32 q; - s = a; a = ABS(a); - s ^= b; b = ABS(b); + s = a; a = FT_ABS(a); + s ^= b; b = FT_ABS(b); if ( b == 0 ) { @@ -411,8 +474,8 @@ FT_Int32 s; - s = x; x = ABS( x ); - s ^= y; y = ABS( y ); + s = x; x = FT_ABS( x ); + s ^= y; y = FT_ABS( y ); ft_multo64( x, y, z ); @@ -445,7 +508,7 @@ x->lo = (FT_UInt32)-(FT_Int32)x->lo; x->hi = ~x->hi + !x->lo; } - s ^= y; y = ABS( y ); + s ^= y; y = FT_ABS( y ); /* Shortcut */ if ( x->hi == 0 ) @@ -499,7 +562,7 @@ x->lo = (FT_UInt32)-(FT_Int32)x->lo; x->hi = ~x->hi + !x->lo; } - s ^= y; y = ABS( y ); + s ^= y; y = FT_ABS( y ); /* Shortcut */ if ( x->hi == 0 ) Index: xc/extras/freetype2/src/base/ftdbgmem.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftdbgmem.c,v retrieving revision 1.2 diff -u -r1.2 ftdbgmem.c --- a/xc/extras/freetype2/src/base/ftdbgmem.c 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/ftdbgmem.c 28 Apr 2004 10:25:26 -0000 @@ -4,7 +4,7 @@ /* */ /* Memory debugger (body). */ /* */ -/* Copyright 2001, 2002, 2003 by */ +/* Copyright 2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -604,7 +604,7 @@ p = getenv( "FT2_ALLOC_TOTAL_MAX" ); if ( p != NULL ) { - FT_Long total_max = atol(p); + FT_Long total_max = ft_atol(p); if ( total_max > 0 ) { @@ -616,7 +616,7 @@ p = getenv( "FT2_ALLOC_COUNT_MAX" ); if ( p != NULL ) { - FT_Long total_count = atol(p); + FT_Long total_count = ft_atol(p); if ( total_count > 0 ) { Index: xc/extras/freetype2/src/base/ftdebug.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftdebug.c,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 ftdebug.c --- a/xc/extras/freetype2/src/base/ftdebug.c 25 Nov 2003 19:27:19 -0000 1.1.1.2 +++ b/xc/extras/freetype2/src/base/ftdebug.c 28 Apr 2004 10:25:26 -0000 @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (body). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2002, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -82,8 +82,9 @@ /* array of trace levels, initialized to 0 */ int ft_trace_levels[trace_count]; + /* define array of trace toggle names */ -#define FT_TRACE_DEF(x) #x , +#define FT_TRACE_DEF( x ) #x , static const char* ft_trace_toggles[trace_count + 1] = { @@ -94,19 +95,43 @@ #undef FT_TRACE_DEF + /* documentation is in ftdebug.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Trace_Get_Count( void ) + { + return trace_count; + } + + + /* documentation is in ftdebug.h */ + + FT_EXPORT_DEF( const char * ) + FT_Trace_Get_Name( FT_Int idx ) + { + int max = FT_Trace_Get_Count(); + + + if ( idx < max ) + return ft_trace_toggles[idx]; + else + return NULL; + } + + /*************************************************************************/ /* */ /* Initialize the tracing sub-system. This is done by retrieving the */ - /* value of the "FT2_DEBUG" environment variable. It must be a list of */ - /* toggles, separated by spaces, `;' or `,'. Example: */ + /* value of the `FT2_DEBUG' environment variable. It must be a list of */ + /* toggles, separated by spaces, `;', or `,'. Example: */ /* */ - /* "any:3 memory:6 stream:5" */ + /* export FT2_DEBUG="any:3 memory:6 stream:5" */ /* */ - /* This will request that all levels be set to 3, except the trace level */ - /* for the memory and stream components which are set to 6 and 5, */ + /* This requests that all levels be set to 3, except the trace level for */ + /* the memory and stream components which are set to 6 and 5, */ /* respectively. */ /* */ - /* See the file for details of the */ + /* See the file for details of the */ /* available toggle names. */ /* */ /* The level must be between 0 and 6; 0 means quiet (except for serious */ @@ -117,6 +142,7 @@ { const char* ft2_debug = getenv( "FT2_DEBUG" ); + if ( ft2_debug ) { const char* p = ft2_debug; @@ -133,10 +159,10 @@ q = p; while ( *p && *p != ':' ) p++; - + if ( *p == ':' && p > q ) { - FT_Int n, i, len = (FT_Int)(p - q); + FT_Int n, i, len = (FT_Int)( p - q ); FT_Int level = -1, found = -1; @@ -171,7 +197,7 @@ { if ( found == trace_any ) { - /* special case for "any" */ + /* special case for `any' */ for ( n = 0; n < trace_count; n++ ) ft_trace_levels[n] = level; } @@ -183,14 +209,33 @@ } } + #else /* !FT_DEBUG_LEVEL_TRACE */ + FT_BASE_DEF( void ) ft_debug_init( void ) { /* nothing */ } + + FT_EXPORT_DEF( FT_Int ) + FT_Trace_Get_Count( void ) + { + return 0; + } + + + FT_EXPORT_DEF( const char * ) + FT_Trace_Get_Name( FT_Int idx ) + { + FT_UNUSED( idx ); + + return NULL; + } + + #endif /* !FT_DEBUG_LEVEL_TRACE */ Index: xc/extras/freetype2/src/base/ftgloadr.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftgloadr.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 ftgloadr.c --- a/xc/extras/freetype2/src/base/ftgloadr.c 14 Nov 2003 16:48:24 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/base/ftgloadr.c 28 Apr 2004 10:25:26 -0000 @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +19,7 @@ #include #include FT_INTERNAL_GLYPH_LOADER_H #include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_OBJECTS_H #undef FT_COMPONENT #define FT_COMPONENT trace_gloader @@ -205,7 +206,7 @@ if ( new_max > old_max ) { - new_max = ( new_max + 7 ) & -8; + new_max = FT_PAD_CEIL( new_max, 8 ); if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || FT_RENEW_ARRAY( base->tags, old_max, new_max ) ) @@ -225,7 +226,7 @@ n_contours; if ( new_max > old_max ) { - new_max = ( new_max + 3 ) & -4; + new_max = FT_PAD_CEIL( new_max, 4 ); if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) goto Exit; @@ -261,7 +262,7 @@ old_max = loader->max_subglyphs; if ( new_max > old_max ) { - new_max = ( new_max + 1 ) & -2; + new_max = FT_PAD_CEIL( new_max, 2 ); if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) ) goto Exit; @@ -336,17 +337,17 @@ FT_Outline* in = &source->base.outline; - FT_MEM_COPY( out->points, in->points, - num_points * sizeof ( FT_Vector ) ); - FT_MEM_COPY( out->tags, in->tags, - num_points * sizeof ( char ) ); - FT_MEM_COPY( out->contours, in->contours, - num_contours * sizeof ( short ) ); + FT_ARRAY_COPY( out->points, in->points, + num_points ); + FT_ARRAY_COPY( out->tags, in->tags, + num_points ); + FT_ARRAY_COPY( out->contours, in->contours, + num_contours ); /* do we need to copy the extra points? */ if ( target->use_extra && source->use_extra ) - FT_MEM_COPY( target->base.extra_points, source->base.extra_points, - num_points * sizeof ( FT_Vector ) ); + FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points, + num_points ); out->n_points = (short)num_points; out->n_contours = (short)num_contours; Index: xc/extras/freetype2/src/base/ftglyph.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftglyph.c,v retrieving revision 1.2 diff -u -r1.2 ftglyph.c --- a/xc/extras/freetype2/src/base/ftglyph.c 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/ftglyph.c 28 Apr 2004 10:25:27 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -206,6 +206,7 @@ } + FT_CALLBACK_TABLE_DEF const FT_Glyph_Class ft_bitmap_glyph_class = { sizeof( FT_BitmapGlyphRec ), @@ -253,14 +254,11 @@ goto Exit; /* copy it */ - FT_MEM_COPY( target->points, source->points, - source->n_points * sizeof ( FT_Vector ) ); + FT_ARRAY_COPY( target->points, source->points, source->n_points ); - FT_MEM_COPY( target->tags, source->tags, - source->n_points * sizeof ( FT_Byte ) ); + FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); - FT_MEM_COPY( target->contours, source->contours, - source->n_contours * sizeof ( FT_Short ) ); + FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); /* copy all flags, except the `FT_OUTLINE_OWNER' one */ target->flags = source->flags | FT_OUTLINE_OWNER; @@ -327,6 +325,7 @@ } + FT_CALLBACK_TABLE_DEF const FT_Glyph_Class ft_outline_glyph_class = { sizeof( FT_OutlineGlyphRec ), @@ -546,10 +545,10 @@ if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || bbox_mode == FT_GLYPH_BBOX_PIXELS ) { - acbox->xMin &= -64; - acbox->yMin &= -64; - acbox->xMax = ( acbox->xMax + 63 ) & -64; - acbox->yMax = ( acbox->yMax + 63 ) & -64; + acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); + acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); + acbox->xMax = FT_PIX_CEIL( acbox->xMax ); + acbox->yMax = FT_PIX_CEIL( acbox->yMax ); } /* convert to integer pixels if needed */ Index: xc/extras/freetype2/src/base/ftmac.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftmac.c,v retrieving revision 1.2 diff -u -r1.2 ftmac.c --- a/xc/extras/freetype2/src/base/ftmac.c 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/ftmac.c 28 Apr 2004 10:25:29 -0000 @@ -4,7 +4,7 @@ /* */ /* Mac FOND support. Written by just@letterror.com. */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,6 +15,7 @@ /* */ /***************************************************************************/ + /* Notes @@ -65,6 +66,10 @@ #ifdef __GNUC__ #include "../truetype/ttobjs.h" #include "../type1/t1objs.h" + /* This is for Mac OS X. Without redefinition, OS_INLINE */ + /* expands to `static inline' which doesn't survive the */ + /* -ansi compilation flag of GCC. */ +#define OS_INLINE static __inline__ #include #else #include "truetype/ttobjs.h" @@ -76,6 +81,10 @@ #include #endif +#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO +#include +#endif + #include FT_MAC_H @@ -86,12 +95,50 @@ #define PREFER_LWFN 1 #endif + +#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO + +#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) + + + FT_CALLBACK_DEF( void ) + ft_FSp_stream_close( FT_Stream stream ) + { + fclose( STREAM_FILE( stream ) ); + + stream->descriptor.pointer = NULL; + stream->size = 0; + stream->base = 0; + } + + + FT_CALLBACK_DEF( unsigned long ) + ft_FSp_stream_io( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ) + { + FILE* file; + + + file = STREAM_FILE( stream ); + + fseek( file, offset, SEEK_SET ); + + return (unsigned long)fread( buffer, 1, count, file ); + } + +#endif /* __MWERKS__ && !TARGET_RT_MAC_MACHO */ + + /* Given a pathname, fill in a file spec. */ static int file_spec_from_path( const char* pathname, FSSpec* spec ) { -#if defined( TARGET_API_MAC_CARBON ) && !defined( __MWERKS__ ) + +#if !TARGET_API_MAC_OS8 && \ + !( defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO ) OSErr e; FSRef ref; @@ -122,12 +169,13 @@ return 0; #endif + } /* Return the file type of the file specified by spec. */ static OSType - get_file_type( FSSpec* spec ) + get_file_type( const FSSpec* spec ) { FInfo finfo; @@ -139,22 +187,6 @@ } -#ifdef TARGET_API_MAC_CARBON - - /* is this a Mac OS X .dfont file */ - static Boolean - is_dfont( FSSpec* spec ) - { - int nameLen = spec->name[0]; - - - return nameLen >= 6 && - !ft_memcmp( spec->name + nameLen - 5, ".dfont", 6 ); - } - -#endif - - /* Given a PostScript font name, create the Macintosh LWFN file name. */ static void create_lwfn_name( char* ps_name, @@ -216,9 +248,9 @@ /* Make a file spec for an LWFN file from a FOND resource and a file name. */ static FT_Error - make_lwfn_spec( Handle fond, - unsigned char* file_name, - FSSpec* spec ) + make_lwfn_spec( Handle fond, + const unsigned char* file_name, + FSSpec* spec ) { FT_Error error; short ref_num, v_ref_num; @@ -239,12 +271,24 @@ } + static short + count_faces_sfnt( char *fond_data ) + { + /* The count is 1 greater than the value in the FOND. */ + /* Isn't that cute? :-) */ + + return 1 + *( (short *)( fond_data + sizeof ( FamRec ) ) ); + } + + /* Look inside the FOND data, answer whether there should be an SFNT resource, and answer the name of a possible LWFN Type 1 file. Thanks to Paul Miller (paulm@profoundeffects.com) for the fix to load a face OTHER than the first one in the FOND! */ + + static void parse_fond( char* fond_data, short* have_sfnt, @@ -264,19 +308,24 @@ fond = (FamRec*)fond_data; assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); base_assoc = assoc; - assoc += face_index; /* add on the face_index! */ - /* if the face at this index is not scalable, - fall back to the first one (old behavior) */ - if ( assoc->fontSize == 0 ) + /* Let's do a little range checking before we get too excited here */ + if ( face_index < count_faces_sfnt( fond_data ) ) { - *have_sfnt = 1; - *sfnt_id = assoc->fontID; - } - else if ( base_assoc->fontSize == 0 ) - { - *have_sfnt = 1; - *sfnt_id = base_assoc->fontID; + assoc += face_index; /* add on the face_index! */ + + /* if the face at this index is not scalable, + fall back to the first one (old behavior) */ + if ( assoc->fontSize == 0 ) + { + *have_sfnt = 1; + *sfnt_id = assoc->fontID; + } + else if ( base_assoc->fontSize == 0 ) + { + *have_sfnt = 1; + *sfnt_id = base_assoc->fontID; + } } if ( fond->ffStylOff ) @@ -343,6 +392,33 @@ } + static short + count_faces( Handle fond ) + { + short sfnt_id, have_sfnt, have_lwfn = 0; + Str255 lwfn_file_name; + FSSpec lwfn_spec; + + + HLock( fond ); + parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 ); + HUnlock( fond ); + + if ( lwfn_file_name[0] ) + { + if ( make_lwfn_spec( fond, lwfn_file_name, &lwfn_spec ) == FT_Err_Ok ) + have_lwfn = 1; /* yeah, we got one! */ + else + have_lwfn = 0; /* no LWFN file found */ + } + + if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) + return 1; + else + return count_faces_sfnt( *fond ); + } + + /* Read Type 1 data from the POST resources inside the LWFN file, return a PFB buffer. This is somewhat convoluted because the FT2 PFB parser wants the ASCII header as one chunk, and the LWFN @@ -350,12 +426,12 @@ of the same type together. */ static FT_Error read_lwfn( FT_Memory memory, - FSSpec* lwfn_spec, + short res_ref, FT_Byte** pfb_data, FT_ULong* size ) { FT_Error error = FT_Err_Ok; - short res_ref, res_id; + short res_id; unsigned char *buffer, *p, *size_p = NULL; FT_ULong total_size = 0; FT_ULong post_size, pfb_chunk_size; @@ -363,13 +439,10 @@ char code, last_code; - res_ref = FSpOpenResFile( lwfn_spec, fsRdPerm ); - if ( ResError() ) - return FT_Err_Out_Of_Memory; UseResFile( res_ref ); - /* First pass: load all POST resources, and determine the size of - the output buffer. */ + /* First pass: load all POST resources, and determine the size of */ + /* the output buffer. */ res_id = 501; last_code = -1; @@ -396,8 +469,8 @@ if ( FT_ALLOC( buffer, (FT_Long)total_size ) ) goto Error; - /* Second pass: append all POST data to the buffer, add PFB fields. - Glue all consecutive chunks of the same type together. */ + /* Second pass: append all POST data to the buffer, add PFB fields. */ + /* Glue all consecutive chunks of the same type together. */ p = buffer; res_id = 501; last_code = -1; @@ -542,6 +615,14 @@ args.driver = FT_Get_Module( library, driver_name ); } + /* At this point, face_index has served its purpose; */ + /* whoever calls this function has already used it to */ + /* locate the correct font data. We should not propagate */ + /* this index to FT_Open_Face() (unless it is negative). */ + + if ( face_index > 0 ) + face_index = 0; + error = FT_Open_Face( library, &args, face_index, aface ); if ( error == FT_Err_Ok ) (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; @@ -550,19 +631,59 @@ } + static FT_Error + OpenFileAsResource( const FSSpec* spec, + short *p_res_ref ) + { + FT_Error error; + +#if !TARGET_API_MAC_OS8 + + FSRef hostContainerRef; + + + error = FSpMakeFSRef( spec, &hostContainerRef ); + if ( error == noErr ) + error = FSOpenResourceFile( &hostContainerRef, + 0, NULL, fsRdPerm, p_res_ref ); + + /* If the above fails, then it is probably not a resource file */ + /* However, it has been reported that FSOpenResourceFile() sometimes */ + /* fails on some old resource-fork files, which FSpOpenResFile() can */ + /* open. So, just try again with FSpOpenResFile() and see what */ + /* happens :-) */ + + if ( error != noErr ) + +#endif /* !TARGET_API_MAC_OS8 */ + + { + *p_res_ref = FSpOpenResFile( spec, fsRdPerm ); + error = ResError(); + } + + return error ? FT_Err_Cannot_Open_Resource : FT_Err_Ok; + } + + /* Create a new FT_Face from a file spec to an LWFN file. */ static FT_Error - FT_New_Face_From_LWFN( FT_Library library, - FSSpec* spec, - FT_Long face_index, - FT_Face *aface ) + FT_New_Face_From_LWFN( FT_Library library, + const FSSpec* lwfn_spec, + FT_Long face_index, + FT_Face *aface ) { FT_Byte* pfb_data; FT_ULong pfb_size; FT_Error error; + short res_ref; - error = read_lwfn( library->memory, spec, &pfb_data, &pfb_size ); + error = OpenFileAsResource( lwfn_spec, &res_ref ); + if ( error ) + return error; + + error = read_lwfn( library->memory, res_ref, &pfb_data, &pfb_size ); if ( error ) return error; @@ -623,83 +744,34 @@ /* Create a new FT_Face from a file spec to a suitcase file. */ static FT_Error FT_New_Face_From_Suitcase( FT_Library library, - FSSpec* spec, + short res_ref, FT_Long face_index, FT_Face *aface ) { FT_Error error = FT_Err_Ok; - short res_ref, res_index; + short res_index; Handle fond; + short num_faces; - res_ref = FSpOpenResFile( spec, fsRdPerm ); - if ( ResError() ) - return FT_Err_Cannot_Open_Resource; UseResFile( res_ref ); - /* face_index may be -1, in which case we - just need to do a sanity check */ - if ( face_index < 0 ) - res_index = 1; - else - { - res_index = (short)( face_index + 1 ); - face_index = 0; - } - fond = Get1IndResource( 'FOND', res_index ); - if ( ResError() ) + for ( res_index = 1; ; ++res_index ) { - error = FT_Err_Cannot_Open_Resource; - goto Error; - } - - error = FT_New_Face_From_FOND( library, fond, face_index, aface ); - - Error: - CloseResFile( res_ref ); - return error; - } - - -#ifdef TARGET_API_MAC_CARBON - - /* Create a new FT_Face from a file spec to a suitcase file. */ - static FT_Error - FT_New_Face_From_dfont( FT_Library library, - FSSpec* spec, - FT_Long face_index, - FT_Face* aface ) - { - FT_Error error = FT_Err_Ok; - short res_ref, res_index; - Handle fond; - FSRef hostContainerRef; - - - error = FSpMakeFSRef( spec, &hostContainerRef ); - if ( error == noErr ) - error = FSOpenResourceFile( &hostContainerRef, - 0, NULL, fsRdPerm, &res_ref ); - - if ( error != noErr ) - return FT_Err_Cannot_Open_Resource; + fond = Get1IndResource( 'FOND', res_index ); + if ( ResError() ) + { + error = FT_Err_Cannot_Open_Resource; + goto Error; + } + if ( face_index < 0 ) + break; - UseResFile( res_ref ); + num_faces = count_faces( fond ); + if ( face_index < num_faces ) + break; - /* face_index may be -1, in which case we - just need to do a sanity check */ - if ( face_index < 0 ) - res_index = 1; - else - { - res_index = (short)( face_index + 1 ); - face_index = 0; - } - fond = Get1IndResource( 'FOND', res_index ); - if ( ResError() ) - { - error = FT_Err_Cannot_Open_Resource; - goto Error; + face_index -= num_faces; } error = FT_New_Face_From_FOND( library, fond, face_index, aface ); @@ -709,8 +781,6 @@ return error; } -#endif - /* documentation is in ftmac.h */ @@ -762,9 +832,9 @@ /* documentation is in ftmac.h */ FT_EXPORT_DEF( FT_Error ) - FT_GetFile_From_Mac_Name( char* fontName, - FSSpec* pathSpec, - FT_Long* face_index ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) { OptionBits options = kFMUseGlobalScopeOption; @@ -825,7 +895,7 @@ the_font = font; } else - ++(*face_index); + ++(*face_index); } } @@ -844,23 +914,46 @@ return FT_Err_Unknown_File_Format; } + /* Common function to load a new FT_Face from a resource file. */ - static long - ResourceForkSize(FSSpec* spec) + static FT_Error + FT_New_Face_From_Resource( FT_Library library, + const FSSpec *spec, + FT_Long face_index, + FT_Face *aface ) { - long len; - short refNum; - OSErr e; + OSType file_type; + short res_ref; + FT_Error error; - e = FSpOpenRF( spec, fsRdPerm, &refNum ); /* I.M. Files 2-155 */ - if ( e == noErr ) + if ( OpenFileAsResource( spec, &res_ref ) == FT_Err_Ok ) { - e = GetEOF( refNum, &len ); - FSClose( refNum ); + /* LWFN is a (very) specific file format, check for it explicitly */ + + file_type = get_file_type( spec ); + if ( file_type == 'LWFN' ) + return FT_New_Face_From_LWFN( library, spec, face_index, aface ); + + /* Otherwise the file type doesn't matter (there are more than */ + /* `FFIL' and `tfil'). Just try opening it as a font suitcase; */ + /* if it works, fine. */ + + error = FT_New_Face_From_Suitcase( library, res_ref, + face_index, aface ); + if ( error == 0 ) + return error; + + /* else forget about the resource fork and fall through to */ + /* data fork formats */ + + CloseResFile( res_ref ); } - return ( e == noErr ) ? len : 0; + /* let it fall through to normal loader (.ttf, .otf, etc.); */ + /* we signal this by returning no error and no FT_Face */ + *aface = NULL; + return 0; } @@ -883,7 +976,7 @@ { FT_Open_Args args; FSSpec spec; - OSType file_type; + FT_Error error; /* test for valid `library' and `aface' delayed to FT_Open_Face() */ @@ -893,31 +986,106 @@ if ( file_spec_from_path( pathname, &spec ) ) return FT_Err_Invalid_Argument; - /* Regardless of type, don't try to use the resource fork if it is */ - /* empty. Some TTF fonts have type `FFIL', for example, but they */ - /* only have data forks. */ - - if ( ResourceForkSize( &spec ) != 0 ) - { - file_type = get_file_type( &spec ); - if ( file_type == 'FFIL' || file_type == 'tfil' ) - return FT_New_Face_From_Suitcase( library, &spec, face_index, aface ); + error = FT_New_Face_From_Resource( library, &spec, face_index, aface ); + if ( error != 0 || *aface != NULL ) + return error; - if ( file_type == 'LWFN' ) - return FT_New_Face_From_LWFN( library, &spec, face_index, aface ); - } + /* let it fall through to normal loader (.ttf, .otf, etc.) */ + args.flags = FT_OPEN_PATHNAME; + args.pathname = (char*)pathname; + return FT_Open_Face( library, &args, face_index, aface ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* FT_New_Face_From_FSSpec */ + /* */ + /* */ + /* FT_New_Face_From_FSSpec is identical to FT_New_Face except it */ + /* accepts an FSSpec instead of a path. */ + /* */ + FT_EXPORT_DEF( FT_Error ) + FT_New_Face_From_FSSpec( FT_Library library, + const FSSpec *spec, + FT_Long face_index, + FT_Face *aface ) + { + FT_Open_Args args; + FT_Error error; + FT_Stream stream; + FILE* file; + FT_Memory memory; -#ifdef TARGET_API_MAC_CARBON - if ( is_dfont( &spec ) ) - return FT_New_Face_From_dfont( library, &spec, face_index, aface ); + /* test for valid `library' and `aface' delayed to FT_Open_Face() */ + if ( !spec ) + return FT_Err_Invalid_Argument; -#endif + error = FT_New_Face_From_Resource( library, spec, face_index, aface ); + if ( error != 0 || *aface != NULL ) + return error; /* let it fall through to normal loader (.ttf, .otf, etc.) */ - args.flags = FT_OPEN_PATHNAME; - args.pathname = (char*)pathname; - return FT_Open_Face( library, &args, face_index, aface ); + +#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO + + /* Codewarrior's C library can open a FILE from a FSSpec */ + /* but we must compile with FSp_fopen.c in addition to */ + /* runtime libraries. */ + + memory = library->memory; + + if ( FT_NEW( stream ) ) + return error; + stream->memory = memory; + + file = FSp_fopen( spec, "rb" ); + if ( !file ) + return FT_Err_Cannot_Open_Resource; + + fseek( file, 0, SEEK_END ); + stream->size = ftell( file ); + fseek( file, 0, SEEK_SET ); + + stream->descriptor.pointer = file; + stream->pathname.pointer = NULL; + stream->pos = 0; + + stream->read = ft_FSp_stream_io; + stream->close = ft_FSp_stream_close; + + args.flags = FT_OPEN_STREAM; + args.stream = stream; + + error = FT_Open_Face( library, &args, face_index, aface ); + if ( error == FT_Err_Ok ) + (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; + +#else /* !(__MWERKS__ && !TARGET_RT_MAC_MACHO) */ + + { + FSRef ref; + UInt8 path[256]; + OSErr err; + + + err = FSpMakeFSRef(spec, &ref); + if ( !err ) + { + err = FSRefMakePath( &ref, path, sizeof ( path ) ); + if ( !err ) + error = FT_New_Face( library, (const char*)path, + face_index, aface ); + } + if ( err ) + error = FT_Err_Cannot_Open_Resource; + } + +#endif /* !(__MWERKS__ && !TARGET_RT_MAC_MACHO) */ + + return error; } Index: xc/extras/freetype2/src/base/ftobjs.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftobjs.c,v retrieving revision 1.2 diff -u -r1.2 ftobjs.c --- a/xc/extras/freetype2/src/base/ftobjs.c 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/ftobjs.c 28 Apr 2004 10:25:32 -0000 @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 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_OUTLINE_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_RFORK_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ #include FT_TRUETYPE_TABLES_H @@ -30,6 +31,7 @@ #include FT_SERVICE_SFNT_H #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_TT_CMAP_H FT_BASE_DEF( FT_Pointer ) @@ -102,12 +104,12 @@ /*************************************************************************/ - /* create a new input stream from a FT_Open_Args structure */ - /* */ - static FT_Error - ft_input_stream_new( FT_Library library, - const FT_Open_Args* args, - FT_Stream* astream ) + /* create a new input stream from an FT_Open_Args structure */ + /* */ + FT_BASE_DEF( FT_Error ) + FT_Stream_New( FT_Library library, + const FT_Open_Args* args, + FT_Stream *astream ) { FT_Error error; FT_Memory memory; @@ -165,9 +167,9 @@ } - static void - ft_input_stream_free( FT_Stream stream, - FT_Int external ) + FT_BASE_DEF( void ) + FT_Stream_Free( FT_Stream stream, + FT_Int external ) { if ( stream ) { @@ -515,7 +517,10 @@ autohint = 0; } - if ( autohint ) + /* don't apply autohinting if glyph is vertically distorted or */ + /* mirrored */ + if ( autohint && !( face->internal->transform_matrix.yy <= 0 || + face->internal->transform_matrix.yx != 0 ) ) { FT_AutoHinter_Service hinting; @@ -575,15 +580,14 @@ if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && ( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) { - FT_UInt EM = face->units_per_EM; FT_Size_Metrics* metrics = &face->size->metrics; slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, - (FT_Long)metrics->x_ppem << 16, EM ); + metrics->x_scale, 64 ); slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance, - (FT_Long)metrics->y_ppem << 16, EM ); + metrics->y_scale, 64 ); } if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 ) @@ -669,6 +673,28 @@ } + static void + destroy_charmaps( FT_Face face, + FT_Memory memory ) + { + FT_Int n; + + + for ( n = 0; n < face->num_charmaps; n++ ) + { + FT_CMap cmap = FT_CMAP( face->charmaps[n] ); + + + FT_CMap_Done( cmap ); + + face->charmaps[n] = NULL; + } + + FT_FREE( face->charmaps ); + face->num_charmaps = 0; + } + + /* destructor for faces list */ static void destroy_face( FT_Memory memory, @@ -699,31 +725,14 @@ face->generic.finalizer( face ); /* discard charmaps */ - { - FT_Int n; - - - for ( n = 0; n < face->num_charmaps; n++ ) - { - FT_CMap cmap = FT_CMAP( face->charmaps[n] ); - - - FT_CMap_Done( cmap ); - - face->charmaps[n] = NULL; - } - - FT_FREE( face->charmaps ); - face->num_charmaps = 0; - } - + destroy_charmaps( face, memory ); /* finalize format-specific stuff */ if ( clazz->done_face ) clazz->done_face( face ); /* close the stream for this face if needed */ - ft_input_stream_free( + FT_Stream_Free( face->stream, ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); @@ -924,6 +933,7 @@ Fail: if ( error ) { + destroy_charmaps( face, memory ); clazz->done_face( face ); FT_FREE( internal ); FT_FREE( face ); @@ -1127,19 +1137,18 @@ static FT_Error Mac_Read_POST_Resource( FT_Library library, FT_Stream stream, - FT_Long resource_listoffset, + FT_Long *offsets, FT_Long resource_cnt, - FT_Long resource_data, FT_Long face_index, FT_Face *aface ) { FT_Error error = FT_Err_Cannot_Open_Resource; FT_Memory memory = library->memory; FT_Byte* pfb_data; - int i, type, flags, len; + int i, type, flags; + FT_Long len; FT_Long pfb_len, pfb_pos, pfb_lenpos; - FT_Long rlen, junk, temp; - FT_Long *offsets; + FT_Long rlen, temp; if ( face_index == -1 ) @@ -1147,24 +1156,6 @@ if ( face_index != 0 ) return error; - if ( FT_ALLOC( offsets, (FT_Long)resource_cnt * sizeof ( FT_Long ) ) ) - return error; - - error = FT_Stream_Seek( stream, resource_listoffset ); - if ( error ) - goto Exit; - - /* Find all the POST resource offsets */ - for ( i = 0; i < resource_cnt; ++i ) - { - (void)FT_READ_USHORT( junk ); /* resource id */ - (void)FT_READ_USHORT( junk ); /* rsource name */ - if ( FT_READ_LONG( temp ) ) - goto Exit; - offsets[i] = resource_data + ( temp & 0xFFFFFFL ); - (void)FT_READ_LONG( junk ); /* mbz */ - } - /* Find the length of all the POST resources, concatenated. Assume */ /* worst case (each resource in its own section). */ pfb_len = 0; @@ -1250,7 +1241,6 @@ FT_FREE( pfb_data ); Exit: - FT_FREE( offsets ); return error; } @@ -1263,18 +1253,16 @@ static FT_Error Mac_Read_sfnt_Resource( FT_Library library, FT_Stream stream, - FT_Long resource_listoffset, + FT_Long *offsets, FT_Long resource_cnt, - FT_Long resource_data, FT_Long face_index, FT_Face *aface ) { FT_Memory memory = library->memory; FT_Byte* sfnt_data; FT_Error error; - int i; - FT_Long flag_offset= 0xFFFFFFL; - FT_Long rlen, junk; + FT_Long flag_offset; + FT_Long rlen; int is_cff; @@ -1283,26 +1271,11 @@ if ( face_index >= resource_cnt ) return FT_Err_Cannot_Open_Resource; - error = FT_Stream_Seek( stream, resource_listoffset ); + flag_offset = offsets[face_index]; + error = FT_Stream_Seek( stream, flag_offset ); if ( error ) goto Exit; - for ( i = 0; i <= face_index; ++i ) - { - (void)FT_READ_USHORT( junk ); /* resource id */ - (void)FT_READ_USHORT( junk ); /* rsource name */ - if ( FT_READ_LONG( flag_offset ) ) - goto Exit; - flag_offset &= 0xFFFFFFL; - (void)FT_READ_LONG( junk ); /* mbz */ - } - - if ( flag_offset == 0xFFFFFFL ) - return FT_Err_Cannot_Open_Resource; - - error = FT_Stream_Seek( stream, flag_offset + resource_data ); - if ( error ) - goto Exit; if ( FT_READ_LONG( rlen ) ) goto Exit; if ( rlen == -1 ) @@ -1343,113 +1316,41 @@ FT_Long face_index, FT_Face *aface ) { - FT_Error error; - unsigned char head[16], head2[16]; - FT_Long rdata_pos, map_pos, rdata_len, map_len; - int allzeros, allmatch, i, cnt, subcnt; - FT_Long type_list, rpos, junk; - FT_ULong tag; - - - error = FT_Stream_Seek( stream, resource_offset ); - if ( error ) - goto Exit; - error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); - if ( error ) - goto Exit; - - rdata_pos = resource_offset + ( ( head[0] << 24 ) | - ( head[1] << 16 ) | - ( head[2] << 8 ) | - head[3] ); - map_pos = resource_offset + ( ( head[4] << 24 ) | - ( head[5] << 16 ) | - ( head[6] << 8 ) | - head[7] ); - rdata_len = ( head[ 8] << 24 ) | - ( head[ 9] << 16 ) | - ( head[10] << 8 ) | - head[11]; - map_len = ( head[12] << 24 ) | - ( head[13] << 16 ) | - ( head[14] << 8 ) | - head[15]; - - if ( rdata_pos + rdata_len != map_pos || map_pos == resource_offset ) - return FT_Err_Unknown_File_Format; - - error = FT_Stream_Seek( stream, map_pos ); - if ( error ) - goto Exit; + FT_Memory memory = library->memory; + FT_Error error; + FT_Long map_offset, rdara_pos; + FT_Long *data_offsets; + FT_Long count; - head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */ - error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 ); + error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset, + &map_offset, &rdara_pos ); if ( error ) - goto Exit; + return error; - allzeros = 1; - allmatch = 1; - for ( i = 0; i < 16; ++i ) - { - if ( head2[i] != 0 ) - allzeros = 0; - if ( head2[i] != head[i] ) - allmatch = 0; + error = FT_Raccess_Get_DataOffsets( library, stream, + map_offset, rdara_pos, + FT_MAKE_TAG( 'P', 'O', 'S', 'T' ), + &data_offsets, &count ); + if ( !error ) + { + error = Mac_Read_POST_Resource( library, stream, data_offsets, count, + face_index, aface ); + FT_FREE( data_offsets ); + return error; } - if ( !allzeros && !allmatch ) - return FT_Err_Unknown_File_Format; - - /* If we've gotten this far then it's probably a mac resource file. */ - /* Now, does it contain any interesting resources? */ - (void)FT_READ_LONG( junk ); /* skip handle to next resource map */ - (void)FT_READ_USHORT( junk ); /* skip file resource number */ - (void)FT_READ_USHORT( junk ); /* skip attributes */ - - if ( FT_READ_USHORT( type_list ) ) - goto Exit; - if ( type_list == -1 ) - return FT_Err_Unknown_File_Format; - - error = FT_Stream_Seek( stream, map_pos + type_list ); - if ( error ) - goto Exit; - - if ( FT_READ_USHORT( cnt ) ) - goto Exit; - - ++cnt; - for ( i = 0; i < cnt; ++i ) + error = FT_Raccess_Get_DataOffsets( library, stream, + map_offset, rdara_pos, + FT_MAKE_TAG( 's', 'f', 'n', 't' ), + &data_offsets, &count ); + if ( !error ) { - if ( FT_READ_LONG( tag ) || - FT_READ_USHORT( subcnt ) || - FT_READ_USHORT( rpos ) ) - goto Exit; - - ++subcnt; - rpos += map_pos + type_list; - if ( tag == FT_MAKE_TAG( 'P', 'O', 'S', 'T' ) ) - return Mac_Read_POST_Resource( library, - stream, - rpos, - subcnt, - rdata_pos, - face_index, - aface ); - else if ( tag == FT_MAKE_TAG( 's', 'f', 'n', 't' ) ) - return Mac_Read_sfnt_Resource( library, - stream, - rpos, - subcnt, - rdata_pos, - face_index, - aface ); + error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count, + face_index, aface ); + FT_FREE( data_offsets ); } - error = FT_Err_Cannot_Open_Resource; /* this file contains no - interesting resources */ - Exit: return error; } @@ -1504,11 +1405,87 @@ } - /* Check for some macintosh formats */ + static FT_Error + load_face_in_embedded_rfork( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Face *aface, + const FT_Open_Args *args ) + { + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + FT_Memory memory = library->memory; + FT_Error error = FT_Err_Unknown_File_Format; + int i; + + char * file_names[FT_RACCESS_N_RULES]; + FT_Long offsets[FT_RACCESS_N_RULES]; + FT_Error errors[FT_RACCESS_N_RULES]; + + FT_Open_Args args2; + FT_Stream stream2; + + + FT_Raccess_Guess( library, stream, + args->pathname, file_names, offsets, errors ); + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + if ( errors[i] ) + { + FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i )); + continue; + } + + args2.flags = FT_OPEN_PATHNAME; + args2.pathname = file_names[i] ? file_names[i] : args->pathname; + + FT_TRACE3(( "Try rule %d: %s (offset=%d) ...", + i, args2.pathname, offsets[i] )); + + error = FT_Stream_New( library, &args2, &stream2 ); + if ( error ) + { + FT_TRACE3(( "failed\n" )); + continue; + } + + error = IsMacResource( library, stream2, offsets[i], + face_index, aface ); + FT_Stream_Close( stream2 ); + + FT_TRACE3(( "%s\n", error ? "failed": "successful" )); + + if ( !error ) + break; + } + + for (i = 0; i < FT_RACCESS_N_RULES; i++) + { + if ( file_names[i] ) + FT_FREE( file_names[i] ); + } + + /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */ + if ( error ) + error = FT_Err_Unknown_File_Format; + + return error; + +#undef FT_COMPONENT +#define FT_COMPONENT trace_objs + + } + + + /* Check for some macintosh formats. */ /* Is this a macbinary file? If so look at the resource fork. */ /* Is this a mac dfont file? */ /* Is this an old style resource fork? (in data) */ - /* Else if we're on Mac OS/X, open the resource fork explicitly. */ + /* Else call load_face_in_embedded_rfork to try extra rules */ + /* (defined in `ftrfork.c'). */ /* */ static FT_Error load_mac_face( FT_Library library, @@ -1523,46 +1500,27 @@ error = IsMacBinary( library, stream, face_index, aface ); if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format ) - error = IsMacResource( library, stream, 0, face_index, aface ); + { -#ifdef FT_MACINTOSH - /* - I know this section is within code which is normally turned off - for the Mac. It provides an alternative approach to reading the - mac resource forks on OS/X in the event that a user does not wish - to compile ftmac.c. - */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess - if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format || - FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) && - ( args->flags & FT_OPEN_PATHNAME ) ) - { - FT_Open_Args args2; - char* newpath; - FT_Memory memory; - FT_Stream stream2; + FT_TRACE3(( "Try as dfont: %s ...", args->pathname )); + error = IsMacResource( library, stream, 0, face_index, aface ); - memory = library->memory; + FT_TRACE3(( "%s\n", error ? "failed" : "successful" )); - FT_ALLOC( newpath, - ft_strlen( args->pathname ) + ft_strlen( "/rsrc" ) + 1 ); - ft_strcpy( newpath, args->pathname ); - ft_strcat( newpath, "/rsrc" ); +#undef FT_COMPONENT +#define FT_COMPONENT trace_objs - args2.flags = FT_OPEN_PATHNAME; - args2.pathname = (char*)newpath; - error = ft_input_stream_new( library, &args2, &stream2 ); - if ( !error ) - { - error = IsMacResource( library, stream2, 0, face_index, aface ); - FT_Stream_Close( stream2 ); - } - FT_FREE( newpath ); } -#endif /* FT_MACINTOSH */ - + if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format || + FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) && + ( args->flags & FT_OPEN_PATHNAME ) ) + error = load_face_in_embedded_rfork( library, stream, + face_index, aface, args ); return error; } @@ -1587,7 +1545,7 @@ /* test for valid `library' delayed to */ - /* ft_input_stream_new() */ + /* FT_Stream_New() */ if ( !aface || !args ) return FT_Err_Invalid_Argument; @@ -1598,7 +1556,7 @@ args->stream ); /* create input stream */ - error = ft_input_stream_new( library, args, &stream ); + error = FT_Stream_New( library, args, &stream ); if ( error ) goto Exit; @@ -1631,7 +1589,7 @@ else error = FT_Err_Invalid_Handle; - ft_input_stream_free( stream, external_stream ); + FT_Stream_Free( stream, external_stream ); goto Fail; } else @@ -1676,7 +1634,7 @@ FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation ) goto Fail2; -#ifndef FT_MACINTOSH +#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) error = load_mac_face( library, stream, face_index, aface, args ); if ( !error ) { @@ -1685,19 +1643,19 @@ /* stream (we opened a different stream which extracted the */ /* interesting information out of this stream here. That stream */ /* will still be open and the face will point to it). */ - ft_input_stream_free( stream, external_stream ); + FT_Stream_Free( stream, external_stream ); return error; } if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) goto Fail2; -#endif /* !FT_MACINTOSH */ +#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ /* no driver is able to handle this format */ error = FT_Err_Unknown_File_Format; Fail2: - ft_input_stream_free( stream, external_stream ); + FT_Stream_Free( stream, external_stream ); goto Fail; } @@ -1806,7 +1764,7 @@ FT_Driver_Class clazz; - /* test for valid `parameters' delayed to ft_input_stream_new() */ + /* test for valid `parameters' delayed to FT_Stream_New() */ if ( !face ) return FT_Err_Invalid_Face_Handle; @@ -1815,7 +1773,7 @@ if ( !driver ) return FT_Err_Invalid_Driver_Handle; - error = ft_input_stream_new( driver->root.library, parameters, &stream ); + error = FT_Stream_New( driver->root.library, parameters, &stream ); if ( error ) goto Exit; @@ -1828,7 +1786,7 @@ error = clazz->attach_file( face, stream ); /* close the attached stream */ - ft_input_stream_free( stream, + FT_Stream_Free( stream, (FT_Bool)( parameters->stream && ( parameters->flags & FT_OPEN_STREAM ) ) ); @@ -1986,17 +1944,17 @@ { /* Compute root ascender, descender, test height, and max_advance */ - metrics->ascender = ( FT_MulFix( face->ascender, - metrics->y_scale ) + 63 ) & -64; + metrics->ascender = FT_PIX_CEIL( FT_MulFix( face->ascender, + metrics->y_scale ) ); - metrics->descender = ( FT_MulFix( face->descender, - metrics->y_scale ) + 0 ) & -64; + metrics->descender = FT_PIX_FLOOR( FT_MulFix( face->descender, + metrics->y_scale ) ); - metrics->height = ( FT_MulFix( face->height, - metrics->y_scale ) + 32 ) & -64; + metrics->height = FT_PIX_ROUND( FT_MulFix( face->height, + metrics->y_scale ) ); - metrics->max_advance = ( FT_MulFix( face->max_advance_width, - metrics->x_scale ) + 32 ) & -64; + metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width, + metrics->x_scale ) ); } @@ -2042,11 +2000,20 @@ char_height = 1 * 64; /* Compute pixel sizes in 26.6 units with rounding */ - dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & -64; - dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64; + dim_x = ( char_width * horz_resolution + 36 ) / 72; + dim_y = ( char_height * vert_resolution + 36 ) / 72; + + { + FT_UShort x_ppem = (FT_UShort)( ( dim_x + 32 ) >> 6 ); + FT_UShort y_ppem = (FT_UShort)( ( dim_y + 32 ) >> 6 ); - metrics->x_ppem = (FT_UShort)( dim_x >> 6 ); - metrics->y_ppem = (FT_UShort)( dim_y >> 6 ); + + if ( x_ppem == metrics->x_ppem && y_ppem == metrics->y_ppem ) + return FT_Err_Ok; + + metrics->x_ppem = x_ppem; + metrics->y_ppem = y_ppem; + } metrics->x_scale = 0x10000L; metrics->y_scale = 0x10000L; @@ -2089,7 +2056,6 @@ metrics = &face->size->metrics; clazz = driver->clazz; - /* default processing -- this can be overridden by the driver */ if ( pixel_width == 0 ) pixel_width = pixel_height; @@ -2101,6 +2067,12 @@ if ( pixel_height < 1 ) pixel_height = 1; + /* use `>=' to avoid potention compiler warning on 16bit platforms */ + if ( pixel_width >= 0xFFFFU ) + pixel_width = 0xFFFFU; + if ( pixel_height >= 0xFFFFU ) + pixel_height = 0xFFFFU; + metrics->x_ppem = (FT_UShort)pixel_width; metrics->y_ppem = (FT_UShort)pixel_height; @@ -2162,8 +2134,8 @@ if ( kern_mode != FT_KERNING_UNFITTED ) { - akerning->x = ( akerning->x + 32 ) & -64; - akerning->y = ( akerning->y + 32 ) & -64; + akerning->x = FT_PIX_ROUND( akerning->x ); + akerning->y = FT_PIX_ROUND( akerning->y ); } } } @@ -2518,6 +2490,28 @@ } + FT_EXPORT_DEF( FT_ULong ) + FT_Get_CMap_Language_ID( FT_CharMap charmap ) + { + FT_Service_TTCMaps service; + FT_Face face; + TT_CMapInfo cmap_info; + + + if ( !charmap || !charmap->face ) + return 0; + + face = charmap->face; + FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); + if ( service == NULL ) + return 0; + if ( service->get_cmap_info( charmap, &cmap_info )) + return 0; + + return cmap_info.language; + } + + FT_EXPORT_DEF( FT_Error ) FT_Activate_Size( FT_Size size ) { Index: xc/extras/freetype2/src/base/ftoutln.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftoutln.c,v retrieving revision 1.2 diff -u -r1.2 ftoutln.c --- a/xc/extras/freetype2/src/base/ftoutln.c 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/ftoutln.c 28 Apr 2004 10:25:32 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -358,14 +358,11 @@ source->n_contours != target->n_contours ) return FT_Err_Invalid_Argument; - FT_MEM_COPY( target->points, source->points, - source->n_points * sizeof ( FT_Vector ) ); + FT_ARRAY_COPY( target->points, source->points, source->n_points ); - FT_MEM_COPY( target->tags, source->tags, - source->n_points * sizeof ( FT_Byte ) ); + FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); - FT_MEM_COPY( target->contours, source->contours, - source->n_contours * sizeof ( FT_Short ) ); + FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); /* copy all flags, except the `FT_OUTLINE_OWNER' one */ is_owner = target->flags & FT_OUTLINE_OWNER; @@ -658,14 +655,14 @@ typedef struct FT_OrientationExtremumRec_ { - FT_Int index; - FT_Int pos; - FT_Int first; - FT_Int last; - + FT_Int index; + FT_Long pos; + FT_Int first; + FT_Int last; + } FT_OrientationExtremumRec; - + static FT_Orientation ft_orientation_extremum_compute( FT_OrientationExtremumRec* extremum, FT_Outline* outline ) @@ -673,36 +670,37 @@ FT_Vector *point, *first, *last, *prev, *next; FT_Vector* points = outline->points; FT_Angle angle_in, angle_out; - + /* compute the previous and next points in the same contour */ point = points + extremum->index; first = points + extremum->first; last = points + extremum->last; - + + prev = point; + next = point; + do { - prev = ( point == first ) ? last : point - 1; - + prev = ( prev == first ) ? last : prev - 1; if ( prev == point ) return FT_ORIENTATION_TRUETYPE; /* degenerate case */ - + } while ( prev->x != point->x || prev->y != point->y ); - + do { - next = ( point == last ) ? first : point + 1; - + next = ( next == last ) ? first : next + 1; if ( next == point ) return FT_ORIENTATION_TRUETYPE; /* shouldn't happen */ - + } while ( next->x != point->x || next->y != point->y ); - + /* now compute the orientation of the `out' vector relative */ /* to the `in' vector. */ angle_in = FT_Atan2( point->x - prev->x, point->y - prev->y ); angle_out = FT_Atan2( next->x - point->x, next->y - point->y ); - + return ( FT_Angle_Diff( angle_in, angle_out ) >= 0 ) ? FT_ORIENTATION_TRUETYPE : FT_ORIENTATION_POSTSCRIPT; @@ -713,7 +711,7 @@ FT_Outline_Get_Orientation( FT_Outline* outline ) { FT_Orientation result = FT_ORIENTATION_TRUETYPE; - + if ( outline && outline->n_points > 0 ) { @@ -721,11 +719,11 @@ FT_Int n; FT_Int first, last; FT_Vector* points = outline->points; - + xmin.pos = ymin.pos = +32768L; xmax.pos = ymax.pos = -32768L; - + xmin.index = ymin.index = xmax.index = ymax.index = -1; first = 0; @@ -737,13 +735,13 @@ if ( last > first + 1 ) { FT_Int i; - + for ( i = first; i < last; i++ ) { FT_Pos x = points[i].x; FT_Pos y = points[i].y; - + if ( x < xmin.pos ) { @@ -775,21 +773,21 @@ } } } - + if ( xmin.index >= 0 ) result = ft_orientation_extremum_compute( &xmin, outline ); - + else if ( xmax.index >= 0 ) result = ft_orientation_extremum_compute( &xmax, outline ); - + else if ( ymin.index >= 0 ) result = ft_orientation_extremum_compute( &ymin, outline ); - + else if ( ymax.index >= 0 ) result = ft_orientation_extremum_compute( &ymax, outline ); } } - + return result; } Index: xc/extras/freetype2/src/base/ftrfork.c =================================================================== RCS file: xc/extras/freetype2/src/base/ftrfork.c diff -N xc/extras/freetype2/src/base/ftrfork.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/base/ftrfork.c 28 Apr 2004 10:25:33 -0000 @@ -0,0 +1,717 @@ +/***************************************************************************/ +/* */ +/* ftrfork.c */ +/* */ +/* Embedded resource forks accessor (body). */ +/* */ +/* Copyright 2004 by */ +/* Masatake YAMATO and Redhat K.K. */ +/* */ +/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ +/* derived from ftobjs.c. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* Development of the code in this file is support of */ +/* Information-technology Promotion Agency, Japan. */ +/***************************************************************************/ + + +#include +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_RFORK_H + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** Resource fork directory access ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + FT_BASE_DEF( FT_Error ) + FT_Raccess_Get_HeaderInfo( FT_Library library, + FT_Stream stream, + FT_Long rfork_offset, + FT_Long *map_offset, + FT_Long *rdata_pos ) + { + FT_Error error; + unsigned char head[16], head2[16]; + FT_Long map_pos, rdata_len; + int allzeros, allmatch, i; + FT_Long type_list; + + FT_UNUSED( library ); + + + error = FT_Stream_Seek( stream, rfork_offset ); + if ( error ) + return error; + + error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); + if ( error ) + return error; + + *rdata_pos = rfork_offset + ( ( head[0] << 24 ) | + ( head[1] << 16 ) | + ( head[2] << 8 ) | + head[3] ); + map_pos = rfork_offset + ( ( head[4] << 24 ) | + ( head[5] << 16 ) | + ( head[6] << 8 ) | + head[7] ); + rdata_len = ( head[ 8] << 24 ) | + ( head[ 9] << 16 ) | + ( head[10] << 8 ) | + head[11]; + + /* map_len = head[12] .. head[15] */ + + if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset ) + return FT_Err_Unknown_File_Format; + + error = FT_Stream_Seek( stream, map_pos ); + if ( error ) + return error; + + head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */ + + error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 ); + if ( error ) + return error; + + allzeros = 1; + allmatch = 1; + for ( i = 0; i < 16; ++i ) + { + if ( head2[i] != 0 ) + allzeros = 0; + if ( head2[i] != head[i] ) + allmatch = 0; + } + if ( !allzeros && !allmatch ) + return FT_Err_Unknown_File_Format; + + /* If we have reached this point then it is probably a mac resource */ + /* file. Now, does it contain any interesting resources? */ + /* Skip handle to next resource map, the file resource number, and */ + /* attributes. */ + (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ + + 2 /* skip file resource number */ + + 2 ); /* skip attributes */ + + if ( FT_READ_USHORT( type_list ) ) + return error; + if ( type_list == -1 ) + return FT_Err_Unknown_File_Format; + + error = FT_Stream_Seek( stream, map_pos + type_list ); + if ( error ) + return error; + + *map_offset = map_pos + type_list; + return FT_Err_Ok; + } + + + FT_BASE_DEF( FT_Error ) + FT_Raccess_Get_DataOffsets( FT_Library library, + FT_Stream stream, + FT_Long map_offset, + FT_Long rdata_pos, + FT_Long tag, + FT_Long **offsets, + FT_Long *count ) + { + FT_Error error; + int i, j, cnt, subcnt; + FT_Long tag_internal, rpos; + FT_Memory memory = library->memory; + FT_Long temp; + FT_Long *offsets_internal; + + + error = FT_Stream_Seek( stream, map_offset ); + if ( error ) + return error; + + if ( FT_READ_USHORT( cnt ) ) + return error; + cnt++; + + for ( i = 0; i < cnt; ++i ) + { + if ( FT_READ_LONG( tag_internal ) || + FT_READ_USHORT( subcnt ) || + FT_READ_USHORT( rpos ) ) + return error; + + FT_TRACE2(( "Resource tags: %c%c%c%c\n", + (char)( 0xff & ( tag_internal >> 24 ) ), + (char)( 0xff & ( tag_internal >> 16 ) ), + (char)( 0xff & ( tag_internal >> 8 ) ), + (char)( 0xff & ( tag_internal >> 0 ) ) )); + + if ( tag_internal == tag ) + { + *count = subcnt + 1; + rpos += map_offset; + + error = FT_Stream_Seek( stream, rpos ); + if ( error ) + return error; + + if ( FT_ALLOC( offsets_internal, *count * sizeof( FT_Long ) ) ) + return error; + + for ( j = 0; j < *count; ++j ) + { + (void)FT_STREAM_SKIP( 2 ); /* resource id */ + (void)FT_STREAM_SKIP( 2 ); /* rsource name */ + + if ( FT_READ_LONG( temp ) ) + { + FT_FREE( offsets_internal ); + return error; + } + + offsets_internal[j] = rdata_pos + ( temp & 0xFFFFFFL ); + + (void)FT_STREAM_SKIP( 4 ); /* mbz */ + } + + *offsets = offsets_internal; + + return FT_Err_Ok; + } + } + + return FT_Err_Cannot_Open_Resource; + } + + +#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** Guessing functions ****/ + /**** ****/ + /**** When you add a new guessing function, ****/ + /**** update FT_RACCESS_N_RULES in ftrfork.h. ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + typedef FT_Error + (*raccess_guess_func)( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + + static FT_Error + raccess_guess_apple_double( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_apple_single( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_darwin_ufs_export( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_darwin_hfsplus( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_vfat( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_cap( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_double( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_netatalk( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + + /*************************************************************************/ + /**** ****/ + /**** Helper functions ****/ + /**** ****/ + /*************************************************************************/ + + static FT_Error + raccess_guess_apple_generic( FT_Library library, + FT_Stream stream, + char * base_file_name, + FT_Int32 magic, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_double_from_file_name( FT_Library library, + char * file_name, + FT_Long *result_offset ); + + static char * + raccess_make_file_name( FT_Memory memory, + const char *original_name, + const char *insertion ); + + + FT_BASE_DEF( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char* base_name, + char **new_names, + FT_Long *offsets, + FT_Error *errors ) + { + FT_Long i; + + + raccess_guess_func funcs[FT_RACCESS_N_RULES] = + { + raccess_guess_apple_double, + raccess_guess_apple_single, + raccess_guess_darwin_ufs_export, + raccess_guess_darwin_hfsplus, + raccess_guess_vfat, + raccess_guess_linux_cap, + raccess_guess_linux_double, + raccess_guess_linux_netatalk, + }; + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + new_names[i] = NULL; + errors[i] = FT_Stream_Seek( stream, 0 ); + if ( errors[i] ) + continue ; + + errors[i] = (funcs[i])( library, stream, base_name, + &(new_names[i]), &(offsets[i]) ); + } + + return; + } + + + static FT_Error + raccess_guess_apple_double( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + FT_Int32 magic = ( 0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x07 ); + + + *result_file_name = NULL; + return raccess_guess_apple_generic( library, stream, base_file_name, + magic, result_offset ); + } + + + static FT_Error + raccess_guess_apple_single( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + FT_Int32 magic = (0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x00); + + + *result_file_name = NULL; + return raccess_guess_apple_generic( library, stream, base_file_name, + magic, result_offset ); + } + + + static FT_Error + raccess_guess_darwin_ufs_export( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + newpath = raccess_make_file_name( memory, base_file_name, "._" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_darwin_hfsplus( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + /* + Only meaningful on systems with hfs+ drivers (or Macs). + */ + FT_Error error; + char* newpath; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + if ( FT_ALLOC( newpath, + ft_strlen( base_file_name ) + ft_strlen( "/rsrc" ) + 1 ) ) + return error; + + ft_strcpy( newpath, base_file_name ); + ft_strcat( newpath, "/rsrc" ); + *result_file_name = newpath; + *result_offset = 0; + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_vfat( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, + "resource.frk/" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_linux_cap( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, ".resource/" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_linux_double( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, "%" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_linux_netatalk( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, + ".AppleDouble/" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_apple_generic( FT_Library library, + FT_Stream stream, + char * base_file_name, + FT_Int32 magic, + FT_Long *result_offset ) + { + FT_Int32 magic_from_stream; + FT_Error error; + FT_Int32 version_number; + FT_UShort n_of_entries; + + int i; + FT_UInt32 entry_id, entry_offset, entry_length; + + const FT_UInt32 resource_fork_entry_id = 0x2; + + FT_UNUSED( library ); + FT_UNUSED( base_file_name ); + + + if ( FT_READ_LONG ( magic_from_stream ) ) + return error; + if ( magic_from_stream != magic ) + return FT_Err_Unknown_File_Format; + + if ( FT_READ_LONG( version_number ) ) + return error; + + /* filler */ + error = FT_Stream_Skip( stream, 16 ); + if ( error ) + return error; + + if ( FT_READ_USHORT( n_of_entries ) ) + return error; + if ( n_of_entries == 0 ) + return FT_Err_Unknown_File_Format; + + for ( i = 0; i < n_of_entries; i++ ) + { + if ( FT_READ_LONG( entry_id ) ) + return error; + if ( entry_id == resource_fork_entry_id ) + { + if ( FT_READ_LONG( entry_offset ) || + FT_READ_LONG( entry_length ) ) + continue; + *result_offset = entry_offset; + + return FT_Err_Ok; + } + else + FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ + } + + return FT_Err_Unknown_File_Format; + } + + + static FT_Error + raccess_guess_linux_double_from_file_name( FT_Library library, + char * file_name, + FT_Long *result_offset ) + { + FT_Memory memory; + FT_Open_Args args2; + FT_Stream stream2; + char * nouse = NULL; + FT_Error error; + + + memory = library->memory; + + args2.flags = FT_OPEN_PATHNAME; + args2.pathname = file_name; + error = FT_Stream_New( library, &args2, &stream2 ); + if ( error ) + return error; + + error = raccess_guess_apple_double( library, stream2, file_name, + &nouse, result_offset ); + + FT_Stream_Close( stream2 ); + + return error; + } + + + static char* + raccess_make_file_name( FT_Memory memory, + const char *original_name, + const char *insertion ) + { + char* new_name; + char* tmp; + const char* slash; + unsigned new_length; + FT_ULong error; + + new_length = ft_strlen( original_name ) + ft_strlen( insertion ); + if ( FT_ALLOC( new_name, new_length + 1 ) ) + return NULL; + + tmp = ft_strrchr( original_name, '/' ); + if ( tmp ) + { + ft_strncpy( new_name, original_name, tmp - original_name + 1 ); + new_name[tmp - original_name + 1] = '\0'; + slash = tmp + 1; + } + else + { + slash = original_name; + new_name[0] = '\0'; + } + + ft_strcat( new_name, insertion ); + ft_strcat( new_name, slash ); + + return new_name; + } + + +#else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ + + + /*************************************************************************/ + /* Dummy function; just sets errors */ + /*************************************************************************/ + + FT_BASE_DEF( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char* base_name, + char **new_names, + FT_Long *offsets, + FT_Error *errors ) + { + int i; + + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + new_names[i] = NULL; + offsets[i] = 0; + errors[i] = FT_Err_Unimplemented_Feature; + } + } + + +#endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ + + +/* END */ Index: xc/extras/freetype2/src/base/ftstream.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftstream.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 ftstream.c --- a/xc/extras/freetype2/src/base/ftstream.c 14 Nov 2003 16:48:24 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/base/ftstream.c 28 Apr 2004 10:25:33 -0000 @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -770,15 +770,15 @@ p = (FT_Byte*)structure + fields->offset; switch ( fields->size ) { - case 1: + case (8 / FT_CHAR_BIT): *(FT_Byte*)p = (FT_Byte)value; break; - case 2: + case (16 / FT_CHAR_BIT): *(FT_UShort*)p = (FT_UShort)value; break; - case 4: + case (32 / FT_CHAR_BIT): *(FT_UInt32*)p = (FT_UInt32)value; break; Index: xc/extras/freetype2/src/base/ftstroke.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftstroke.c,v retrieving revision 1.2 diff -u -r1.2 ftstroke.c --- a/xc/extras/freetype2/src/base/ftstroke.c 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/ftstroke.c 28 Apr 2004 10:25:34 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (body). */ /* */ -/* Copyright 2002, 2003 by */ +/* Copyright 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,8 +19,31 @@ #include #include FT_STROKER_H #include FT_TRIGONOMETRY_H +#include FT_OUTLINE_H #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H + + FT_EXPORT_DEF( FT_StrokerBorder ) + FT_Outline_GetInsideBorder( FT_Outline* outline ) + { + FT_Orientation o = FT_Outline_Get_Orientation( outline ); + + + return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_RIGHT + : FT_STROKER_BORDER_LEFT ; + } + + + FT_EXPORT_DEF( FT_StrokerBorder ) + FT_Outline_GetOutsideBorder( FT_Outline* outline ) + { + FT_Orientation o = FT_Outline_Get_Orientation( outline ); + + + return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_LEFT + : FT_STROKER_BORDER_RIGHT ; + } /***************************************************************************/ @@ -221,6 +244,7 @@ FT_Bool movable; FT_Int start; /* index of current sub-path start point */ FT_Memory memory; + FT_Bool valid; } FT_StrokeBorderRec, *FT_StrokeBorder; @@ -468,6 +492,7 @@ border->num_points = 0; border->max_points = 0; border->start = -1; + border->valid = 0; } @@ -476,6 +501,7 @@ { border->num_points = 0; border->start = -1; + border->valid = 0; } @@ -491,6 +517,7 @@ border->num_points = 0; border->max_points = 0; border->start = -1; + border->valid = 0; } @@ -520,7 +547,7 @@ } else if ( in_contour == 0 ) goto Fail; - + if ( tags[0] & FT_STROKE_TAG_END ) { if ( in_contour == 0 ) @@ -534,6 +561,8 @@ if ( in_contour != 0 ) goto Fail; + border->valid = 1; + Exit: *anum_points = num_points; *anum_contours = num_contours; @@ -551,9 +580,9 @@ FT_Outline* outline ) { /* copy point locations */ - FT_MEM_COPY( outline->points + outline->n_points, - border->points, - border->num_points * sizeof ( FT_Vector ) ); + FT_ARRAY_COPY( outline->points + outline->n_points, + border->points, + border->num_points ); /* copy tags */ { @@ -661,10 +690,18 @@ stroker->line_join = line_join; stroker->miter_limit = miter_limit; - stroker->valid = 0; + FT_Stroker_Rewind( stroker ); + } - ft_stroke_border_reset( &stroker->borders[0] ); - ft_stroke_border_reset( &stroker->borders[1] ); + + FT_EXPORT_DEF( void ) + FT_Stroker_Rewind( FT_Stroker stroker ) + { + if ( stroker ) + { + ft_stroke_border_reset( &stroker->borders[0] ); + ft_stroke_border_reset( &stroker->borders[1] ); + } } @@ -1347,7 +1384,6 @@ { FT_Error error = 0; - if ( stroker->subpath_open ) { FT_StrokeBorder right = stroker->borders; @@ -1380,6 +1416,14 @@ FT_Angle turn; FT_Int inside_side; + /* close the path if needed */ + if ( stroker->center.x != stroker->subpath_start.x || + stroker->center.y != stroker->subpath_start.y ) + { + error = FT_Stroker_LineTo( stroker, &stroker->subpath_start ); + if ( error ) + goto Exit; + } /* process the corner */ stroker->angle_out = stroker->subpath_angle; @@ -1408,17 +1452,41 @@ goto Exit; } - /* we will first end our two subpaths */ + /* then end our two subpaths */ ft_stroke_border_close( stroker->borders + 0 ); ft_stroke_border_close( stroker->borders + 1 ); + } - /* now, add the reversed left subpath to "right" */ - error = ft_stroker_add_reverse_left( stroker, 0 ); - if ( error ) - goto Exit; + Exit: + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_GetBorderCounts( FT_Stroker stroker, + FT_StrokerBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_UInt num_points = 0, num_contours = 0; + FT_Error error; + + + if ( !stroker || border > 1 ) + { + error = FT_Err_Invalid_Argument; + goto Exit; } + error = ft_stroke_border_get_counts( stroker->borders + border, + &num_points, &num_contours ); Exit: + if ( anum_points ) + *anum_points = num_points; + + if ( anum_contours ) + *anum_contours = num_contours; + return error; } @@ -1446,8 +1514,6 @@ num_points = count1 + count3; num_contours = count2 + count4; - stroker->valid = 1; - Exit: *anum_points = num_points; *anum_contours = num_contours; @@ -1456,17 +1522,31 @@ FT_EXPORT_DEF( void ) - FT_Stroker_Export( FT_Stroker stroker, - FT_Outline* outline ) + FT_Stroker_ExportBorder( FT_Stroker stroker, + FT_StrokerBorder border, + FT_Outline* outline ) { - if ( stroker->valid ) + if ( border == FT_STROKER_BORDER_LEFT || + border == FT_STROKER_BORDER_RIGHT ) { - ft_stroke_border_export( stroker->borders + 0, outline ); - ft_stroke_border_export( stroker->borders + 1, outline ); + FT_StrokeBorder sborder = & stroker->borders[border]; + + + if ( sborder->valid ) + ft_stroke_border_export( sborder, outline ); } } + FT_EXPORT_DEF( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ) + { + FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_LEFT, outline ); + FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_RIGHT, outline ); + } + + /* * The following is very similar to FT_Outline_Decompose, except * that we do support opened paths, and do not scale the outline. @@ -1494,6 +1574,8 @@ if ( !outline || !stroker ) return FT_Err_Invalid_Argument; + FT_Stroker_Rewind( stroker ); + first = 0; for ( n = 0; n < outline->n_contours; n++ ) @@ -1664,4 +1746,161 @@ } + extern const FT_Glyph_Class ft_outline_glyph_class; + + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_Stroke( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool destroy ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_Glyph glyph = NULL; + + + if ( pglyph == NULL ) + goto Exit; + + glyph = *pglyph; + if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) + goto Exit; + + { + FT_Glyph copy; + + + error = FT_Glyph_Copy( glyph, © ); + if ( error ) + goto Exit; + + glyph = copy; + } + + { + FT_OutlineGlyph oglyph = (FT_OutlineGlyph) glyph; + FT_Outline* outline = &oglyph->outline; + FT_UInt num_points, num_contours; + + + error = FT_Stroker_ParseOutline( stroker, outline, 0 ); + if ( error ) + goto Fail; + + (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); + + FT_Outline_Done( glyph->library, outline ); + + error = FT_Outline_New( glyph->library, + num_points, num_contours, outline ); + if ( error ) + goto Fail; + + outline->n_points = 0; + outline->n_contours = 0; + + FT_Stroker_Export( stroker, outline ); + } + + if ( destroy ) + FT_Done_Glyph( *pglyph ); + + *pglyph = glyph; + goto Exit; + + Fail: + FT_Done_Glyph( glyph ); + glyph = NULL; + + if ( !destroy ) + *pglyph = NULL; + + Exit: + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_StrokeBorder( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool inside, + FT_Bool destroy ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_Glyph glyph = NULL; + + + if ( pglyph == NULL ) + goto Exit; + + glyph = *pglyph; + if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) + goto Exit; + + { + FT_Glyph copy; + + + error = FT_Glyph_Copy( glyph, © ); + if ( error ) + goto Exit; + + glyph = copy; + } + + { + FT_OutlineGlyph oglyph = (FT_OutlineGlyph) glyph; + FT_StrokerBorder border; + FT_Outline* outline = &oglyph->outline; + FT_UInt num_points, num_contours; + + + border = FT_Outline_GetOutsideBorder( outline ); + if ( inside ) + { + if ( border == FT_STROKER_BORDER_LEFT ) + border = FT_STROKER_BORDER_RIGHT; + else + border = FT_STROKER_BORDER_LEFT; + } + + error = FT_Stroker_ParseOutline( stroker, outline, 0 ); + if ( error ) + goto Fail; + + (void)FT_Stroker_GetBorderCounts( stroker, border, + &num_points, &num_contours ); + + FT_Outline_Done( glyph->library, outline ); + + error = FT_Outline_New( glyph->library, + num_points, + num_contours, + outline ); + if ( error ) + goto Fail; + + outline->n_points = 0; + outline->n_contours = 0; + + FT_Stroker_ExportBorder( stroker, border, outline ); + } + + if ( destroy ) + FT_Done_Glyph( *pglyph ); + + *pglyph = glyph; + goto Exit; + + Fail: + FT_Done_Glyph( glyph ); + glyph = NULL; + + if ( !destroy ) + *pglyph = NULL; + + Exit: + return error; + } + + /* END */ Index: xc/extras/freetype2/src/base/ftsynth.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/ftsynth.c,v retrieving revision 1.2 diff -u -r1.2 ftsynth.c --- a/xc/extras/freetype2/src/base/ftsynth.c 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/ftsynth.c 28 Apr 2004 10:25:34 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType synthesizing code for emboldening and slanting (body). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -279,7 +279,8 @@ first = last + 1; } - slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + distance*4 ) & -64; + slot->metrics.horiAdvance = + ( slot->metrics.horiAdvance + distance*4 ) & ~63; } Index: xc/extras/freetype2/src/base/fttrigon.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/fttrigon.c,v retrieving revision 1.2 diff -u -r1.2 fttrigon.c --- a/xc/extras/freetype2/src/base/fttrigon.c 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/fttrigon.c 28 Apr 2004 10:25:35 -0000 @@ -17,6 +17,7 @@ #include +#include FT_INTERNAL_OBJECTS_H #include FT_TRIGONOMETRY_H @@ -271,9 +272,9 @@ /* round theta */ if ( theta >= 0 ) - theta = ( theta + 16 ) & -32; + theta = FT_PAD_ROUND( theta, 32 ); else - theta = - (( -theta + 16 ) & -32); + theta = - FT_PAD_ROUND( -theta, 32 ); vec->x = x; vec->y = theta; Index: xc/extras/freetype2/src/base/rules.mk =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/base/rules.mk,v retrieving revision 1.2 diff -u -r1.2 rules.mk --- a/xc/extras/freetype2/src/base/rules.mk 23 Apr 2004 18:42:47 -0000 1.2 +++ b/xc/extras/freetype2/src/base/rules.mk 28 Apr 2004 10:25:35 -0000 @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002, 2003 by +# Copyright 1996-2000, 2002, 2003, 2004 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -32,16 +32,17 @@ # # ftsystem, ftinit, and ftdebug are handled by freetype.mk # -BASE_SRC := $(BASE_DIR)/ftcalc.c \ - $(BASE_DIR)/fttrigon.c \ - $(BASE_DIR)/ftutil.c \ - $(BASE_DIR)/ftstream.c \ +BASE_SRC := $(BASE_DIR)/ftapi.c \ + $(BASE_DIR)/ftcalc.c \ + $(BASE_DIR)/ftdbgmem.c \ $(BASE_DIR)/ftgloadr.c \ - $(BASE_DIR)/ftoutln.c \ - $(BASE_DIR)/ftobjs.c \ - $(BASE_DIR)/ftapi.c \ $(BASE_DIR)/ftnames.c \ - $(BASE_DIR)/ftdbgmem.c + $(BASE_DIR)/ftobjs.c \ + $(BASE_DIR)/ftoutln.c \ + $(BASE_DIR)/ftrfork.c \ + $(BASE_DIR)/ftstream.c \ + $(BASE_DIR)/fttrigon.c \ + $(BASE_DIR)/ftutil.c # Base layer `extensions' sources # @@ -49,15 +50,15 @@ # object. It will then be linked to the final executable only if one of its # symbols is used by the application. # -BASE_EXT_SRC := $(BASE_DIR)/ftglyph.c \ - $(BASE_DIR)/ftmm.c \ +BASE_EXT_SRC := $(BASE_DIR)/ftbbox.c \ $(BASE_DIR)/ftbdf.c \ - $(BASE_DIR)/fttype1.c \ - $(BASE_DIR)/ftxf86.c \ + $(BASE_DIR)/ftglyph.c \ + $(BASE_DIR)/ftmm.c \ $(BASE_DIR)/ftpfr.c \ $(BASE_DIR)/ftstroke.c \ + $(BASE_DIR)/fttype1.c \ $(BASE_DIR)/ftwinfnt.c \ - $(BASE_DIR)/ftbbox.c + $(BASE_DIR)/ftxf86.c # Default extensions objects # Index: xc/extras/freetype2/src/bdf/bdfdrivr.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/bdf/bdfdrivr.c,v retrieving revision 1.2 diff -u -r1.2 bdfdrivr.c --- a/xc/extras/freetype2/src/bdf/bdfdrivr.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/bdf/bdfdrivr.c 28 Apr 2004 10:25:36 -0000 @@ -2,7 +2,7 @@ FreeType font driver for bdf files - Copyright (C) 2001, 2002, 2003 by + Copyright (C) 2001, 2002, 2003, 2004 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -172,6 +172,118 @@ }; + static FT_Error + bdf_interpret_style( BDF_Face bdf ) + { + FT_Error error = BDF_Err_Ok; + FT_Face face = FT_FACE( bdf ); + FT_Memory memory = face->memory; + bdf_font_t* font = bdf->bdffont; + bdf_property_t* prop; + + char *istr = NULL, *bstr = NULL; + char *sstr = NULL, *astr = NULL; + + int parts = 0, len = 0; + + + face->style_flags = 0; + + prop = bdf_get_font_property( font, (char *)"SLANT" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || + *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) + { + face->style_flags |= FT_STYLE_FLAG_ITALIC; + istr = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) + ? (char *)"Oblique" + : (char *)"Italic"; + len += ft_strlen( istr ); + parts++; + } + + prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) + { + face->style_flags |= FT_STYLE_FLAG_BOLD; + bstr = (char *)"Bold"; + len += ft_strlen( bstr ); + parts++; + } + + prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + { + sstr = (char *)(prop->value.atom); + len += ft_strlen( sstr ); + parts++; + } + + prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + { + astr = (char *)(prop->value.atom); + len += ft_strlen( astr ); + parts++; + } + + if ( !parts || !len ) + face->style_name = (char *)"Regular"; + else + { + char *style, *s; + unsigned int i; + + + if ( FT_ALLOC( style, len + parts ) ) + return error; + + s = style; + + if ( astr ) + { + ft_strcpy( s, astr ); + for ( i = 0; i < ft_strlen( astr ); i++, s++ ) + if ( *s == ' ' ) + *s = '-'; /* replace spaces with dashes */ + *(s++) = ' '; + } + if ( bstr ) + { + ft_strcpy( s, bstr ); + s += ft_strlen( bstr ); + *(s++) = ' '; + } + if ( istr ) + { + ft_strcpy( s, istr ); + s += ft_strlen( istr ); + *(s++) = ' '; + } + if ( sstr ) + { + ft_strcpy( s, sstr ); + for ( i = 0; i < ft_strlen( sstr ); i++, s++ ) + if ( *s == ' ' ) + *s = '-'; /* replace spaces with dashes */ + *(s++) = ' '; + } + *(--s) = '\0'; /* overwrite last ' ', terminate the string */ + + face->style_name = style; /* allocated string */ + } + + return error; + } + + FT_CALLBACK_DEF( FT_Error ) BDF_Face_Done( BDF_Face face ) { @@ -252,39 +364,17 @@ FT_FACE_FLAG_FAST_GLYPHS; prop = bdf_get_font_property( font, "SPACING" ); - if ( prop != NULL ) - if ( prop->format == BDF_ATOM ) - if ( prop->value.atom != NULL ) - if ( ( *(prop->value.atom) == 'M' ) || - ( *(prop->value.atom) == 'm' ) || - ( *(prop->value.atom) == 'C' ) || - ( *(prop->value.atom) == 'c' ) ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' || + *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */ /* FZ XXX: I need a font to implement this */ - root->style_flags = 0; - prop = bdf_get_font_property( font, "SLANT" ); - if ( prop != NULL ) - if ( prop->format == BDF_ATOM ) - if ( prop->value.atom != NULL ) - if ( ( *(prop->value.atom) == 'O' ) || - ( *(prop->value.atom) == 'o' ) || - ( *(prop->value.atom) == 'I' ) || - ( *(prop->value.atom) == 'i' ) ) - root->style_flags |= FT_STYLE_FLAG_ITALIC; - - prop = bdf_get_font_property( font, "WEIGHT_NAME" ); - if ( prop != NULL ) - if ( prop->format == BDF_ATOM ) - if ( prop->value.atom != NULL ) - if ( ( *(prop->value.atom) == 'B' ) || - ( *(prop->value.atom) == 'b' ) ) - root->style_flags |= FT_STYLE_FLAG_BOLD; - prop = bdf_get_font_property( font, "FAMILY_NAME" ); - if ( ( prop != NULL ) && ( prop->value.atom != NULL ) ) + if ( prop && prop->value.atom ) { int l = ft_strlen( prop->value.atom ) + 1; @@ -296,16 +386,8 @@ else root->family_name = 0; - root->style_name = (char *)"Regular"; - if ( root->style_flags & FT_STYLE_FLAG_BOLD ) - { - if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = (char *)"Bold Italic"; - else - root->style_name = (char *)"Bold"; - } - else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = (char *)"Italic"; + if ( ( error = bdf_interpret_style( face ) ) != 0 ) + goto Exit; root->num_glyphs = font->glyphs_size; /* unencoded included */ @@ -315,43 +397,47 @@ { FT_Bitmap_Size* bsize = root->available_sizes; + FT_Short resolution_x = 0, resolution_y = 0; FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); - prop = bdf_get_font_property( font, "PIXEL_SIZE" ); - if ( prop != NULL ) - bsize->height = (FT_Short)prop->value.int32; + bsize->height = font->font_ascent + font->font_descent; prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); - if ( prop != NULL ) + if ( prop ) bsize->width = (FT_Short)( ( prop->value.int32 + 5 ) / 10 ); + else + bsize->width = bsize->height * 2/3; prop = bdf_get_font_property( font, "POINT_SIZE" ); - if ( prop != NULL ) + if ( prop ) /* convert from 722.7 decipoints to 72 points per inch */ bsize->size = (FT_Pos)( ( prop->value.int32 * 64 * 7200 + 36135L ) / 72270L ); + prop = bdf_get_font_property( font, "PIXEL_SIZE" ); + if ( prop ) + bsize->y_ppem = (FT_Short)prop->value.int32 << 6; + prop = bdf_get_font_property( font, "RESOLUTION_X" ); - if ( prop != NULL ) - bsize->x_ppem = - (FT_Pos)( ( prop->value.int32 * bsize->size + 36 ) / 72 ); + if ( prop ) + resolution_x = (FT_Short)prop->value.int32; prop = bdf_get_font_property( font, "RESOLUTION_Y" ); - if ( prop != NULL ) - bsize->y_ppem = - (FT_Pos)( ( prop->value.int32 * bsize->size + 36 ) / 72 ); + if ( prop ) + resolution_y = (FT_Short)prop->value.int32; - if ( bsize->height == 0 ) - bsize->height = (FT_Short)( ( bsize->y_ppem + 32 ) / 64 ); - - if ( bsize->height == 0 ) + if ( bsize->y_ppem == 0 ) { - /* some fonts have a broken SIZE declaration (jiskan24.bdf) */ - FT_ERROR(( "BDF_Face_Init: reading size\n" )); - bsize->height = (FT_Short)font->point_size; + bsize->y_ppem = bsize->size; + if ( resolution_y ) + bsize->y_ppem = bsize->y_ppem * resolution_y / 72; } + if ( resolution_x && resolution_y ) + bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + else + bsize->x_ppem = bsize->y_ppem; } /* encoding table */ @@ -381,21 +467,21 @@ bdf_get_font_property( font, "CHARSET_REGISTRY" ); charset_encoding = bdf_get_font_property( font, "CHARSET_ENCODING" ); - if ( ( charset_registry != NULL ) && ( charset_encoding != NULL ) ) + if ( charset_registry && charset_encoding ) { - if ( ( charset_registry->format == BDF_ATOM ) && - ( charset_encoding->format == BDF_ATOM ) && - ( charset_registry->value.atom != NULL ) && - ( charset_encoding->value.atom != NULL ) ) + if ( charset_registry->format == BDF_ATOM && + charset_encoding->format == BDF_ATOM && + charset_registry->value.atom && + charset_encoding->value.atom ) { const char* s; if ( FT_NEW_ARRAY( face->charset_encoding, - strlen( charset_encoding->value.atom ) + 1 ) ) + ft_strlen( charset_encoding->value.atom ) + 1 ) ) goto Exit; if ( FT_NEW_ARRAY( face->charset_registry, - strlen( charset_registry->value.atom ) + 1 ) ) + ft_strlen( charset_registry->value.atom ) + 1 ) ) goto Exit; ft_strcpy( face->charset_registry, charset_registry->value.atom ); @@ -481,13 +567,14 @@ FT_TRACE4(( "rec %d - pres %d\n", - size->metrics.y_ppem, root->available_sizes->height )); + size->metrics.y_ppem, root->available_sizes->y_ppem )); - if ( size->metrics.y_ppem == root->available_sizes->height ) + if ( size->metrics.y_ppem == root->available_sizes->y_ppem >> 6 ) { - size->metrics.ascender = face->bdffont->bbx.ascent << 6; - size->metrics.descender = face->bdffont->bbx.descent * ( -64 ); - size->metrics.height = face->bdffont->bbx.height << 6; + size->metrics.ascender = face->bdffont->font_ascent << 6; + size->metrics.descender = -face->bdffont->font_descent << 6; + size->metrics.height = ( face->bdffont->font_ascent + + face->bdffont->font_descent ) << 6; size->metrics.max_advance = face->bdffont->bbx.width << 6; return BDF_Err_Ok; @@ -633,14 +720,13 @@ } } - slot->bitmap_left = 0; + slot->bitmap_left = glyph.bbx.x_offset; slot->bitmap_top = glyph.bbx.ascent; /* FZ XXX: TODO: vertical metrics */ slot->metrics.horiAdvance = glyph.dwidth << 6; slot->metrics.horiBearingX = glyph.bbx.x_offset << 6; - slot->metrics.horiBearingY = ( glyph.bbx.y_offset + - glyph.bbx.height ) << 6; + slot->metrics.horiBearingY = glyph.bbx.ascent << 6; slot->metrics.width = bitmap->width << 6; slot->metrics.height = bitmap->rows << 6; @@ -657,7 +743,7 @@ * BDF SERVICE * */ - + static FT_Error bdf_get_bdf_property( BDF_Face face, const char* prop_name, @@ -669,7 +755,7 @@ FT_ASSERT( face && face->bdffont ); prop = bdf_get_font_property( face->bdffont, prop_name ); - if ( prop != NULL ) + if ( prop ) { switch ( prop->format ) { @@ -705,9 +791,9 @@ { *acharset_encoding = face->charset_encoding; *acharset_registry = face->charset_registry; - + return 0; - } + } static const FT_Service_BDFRec bdf_service_bdf = @@ -722,7 +808,7 @@ * SERVICES LIST * */ - + static const FT_ServiceDescRec bdf_services[] = { { FT_SERVICE_ID_BDF, &bdf_service_bdf }, Index: xc/extras/freetype2/src/bdf/bdfdrivr.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/bdf/bdfdrivr.h,v retrieving revision 1.2 diff -u -r1.2 bdfdrivr.h --- a/xc/extras/freetype2/src/bdf/bdfdrivr.h 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/bdf/bdfdrivr.h 28 Apr 2004 10:25:36 -0000 @@ -2,7 +2,7 @@ FreeType font driver for bdf fonts - Copyright (C) 2001, 2002 by + Copyright (C) 2001, 2002, 2003 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy Index: xc/extras/freetype2/src/bdf/bdflib.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/bdf/bdflib.c,v retrieving revision 1.2 diff -u -r1.2 bdflib.c --- a/xc/extras/freetype2/src/bdf/bdflib.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/bdf/bdflib.c 28 Apr 2004 10:25:38 -0000 @@ -1,6 +1,6 @@ /* * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001, 2002, 2003 Francesco Zappa Nardelli + * Copyright 2001, 2002, 2003, 2004 Francesco Zappa Nardelli * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -1770,14 +1770,14 @@ /* Determine the overall font bounding box as the characters are */ /* loaded so corrections can be done later if indicated. */ - p->maxas = (short)MAX( glyph->bbx.ascent, p->maxas ); - p->maxds = (short)MAX( glyph->bbx.descent, p->maxds ); + p->maxas = (short)FT_MAX( glyph->bbx.ascent, p->maxas ); + p->maxds = (short)FT_MAX( glyph->bbx.descent, p->maxds ); p->rbearing = (short)( glyph->bbx.width + glyph->bbx.x_offset ); - p->maxrb = (short)MAX( p->rbearing, p->maxrb ); - p->minlb = (short)MIN( glyph->bbx.x_offset, p->minlb ); - p->maxlb = (short)MAX( glyph->bbx.x_offset, p->maxlb ); + p->maxrb = (short)FT_MAX( p->rbearing, p->maxrb ); + p->minlb = (short)FT_MIN( glyph->bbx.x_offset, p->minlb ); + p->maxlb = (short)FT_MAX( glyph->bbx.x_offset, p->maxlb ); if ( !( p->flags & _BDF_DWIDTH ) ) { Index: xc/extras/freetype2/src/cache/Jamfile =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cache/Jamfile,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 Jamfile --- a/xc/extras/freetype2/src/cache/Jamfile 25 Nov 2003 19:27:19 -0000 1.1.1.2 +++ b/xc/extras/freetype2/src/cache/Jamfile 28 Apr 2004 10:25:38 -0000 @@ -1,4 +1,4 @@ -# FreeType 2 src/cache Jamfile (c) 2001 David Turner +# FreeType 2 src/cache Jamfile (c) 2001, 2003, 2004 David Turner # SubDir FT2_TOP $(FT2_SRC_DIR) cache ; @@ -14,7 +14,15 @@ if $(FT2_MULTI) { - _sources = ftlru ftcmanag ftccache ftcglyph ftcsbits ftcimage ftccmap ; + _sources = ftcmru + ftcmanag + ftccache + ftcglyph + ftcsbits + ftcimage + ftcbasic + ftccmap + ; } else { Index: xc/extras/freetype2/src/cache/descrip.mms =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cache/descrip.mms,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 descrip.mms --- a/xc/extras/freetype2/src/cache/descrip.mms 14 Nov 2003 16:48:24 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/cache/descrip.mms 28 Apr 2004 10:25:38 -0000 @@ -3,7 +3,7 @@ # -# Copyright 2001, 2002 by +# Copyright 2001, 2002, 2003, 2004 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,6 @@ all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -ftcache.obj : ftcache.c ftlru.c ftcmanag.c ftccache.c ftcglyph.c ftcimage.c \ - ftcsbits.c ftccmap.c +ftcache.obj : ftcache.c # EOF Index: xc/extras/freetype2/src/cache/ftcache.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cache/ftcache.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 ftcache.c --- a/xc/extras/freetype2/src/cache/ftcache.c 14 Nov 2003 16:48:24 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/cache/ftcache.c 28 Apr 2004 10:25:38 -0000 @@ -4,7 +4,7 @@ /* */ /* The FreeType Caching sub-system (body only). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,13 +19,13 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include -#include "ftlru.c" +#include "ftcmru.c" #include "ftcmanag.c" #include "ftccache.c" +#include "ftccmap.c" #include "ftcglyph.c" #include "ftcimage.c" #include "ftcsbits.c" -#include "ftccmap.c" - +#include "ftcbasic.c" /* END */ Index: xc/extras/freetype2/src/cache/ftcbasic.c =================================================================== RCS file: xc/extras/freetype2/src/cache/ftcbasic.c diff -N xc/extras/freetype2/src/cache/ftcbasic.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/cache/ftcbasic.c 28 Apr 2004 10:25:38 -0000 @@ -0,0 +1,425 @@ +/***************************************************************************/ +/* */ +/* ftcbasic.c */ +/* */ +/* The FreeType basic cache interface (body). */ +/* */ +/* Copyright 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include +#include FT_CACHE_H +#include FT_CACHE_INTERNAL_GLYPH_H +#include FT_CACHE_INTERNAL_IMAGE_H +#include FT_CACHE_INTERNAL_SBITS_H +#include FT_INTERNAL_MEMORY_H + +#include "ftccback.h" +#include "ftcerror.h" + + + /* + * Basic Families + * + */ + typedef struct FTC_BasicAttrRec_ + { + FTC_ScalerRec scaler; + FT_UInt load_flags; + + } FTC_BasicAttrRec, *FTC_BasicAttrs; + +#define FTC_BASIC_ATTR_COMPARE( a, b ) \ + ( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \ + (a)->load_flags == (b)->load_flags ) + +#define FTC_BASIC_ATTR_HASH( a ) \ + ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags ) + + + typedef struct FTC_BasicQueryRec_ + { + FTC_GQueryRec gquery; + FTC_BasicAttrRec attrs; + + } FTC_BasicQueryRec, *FTC_BasicQuery; + + + typedef struct FTC_BasicFamilyRec_ + { + FTC_FamilyRec family; + FTC_BasicAttrRec attrs; + + } FTC_BasicFamilyRec, *FTC_BasicFamily; + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_basic_family_compare( FTC_BasicFamily family, + FTC_BasicQuery query ) + { + return FT_BOOL( FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs ) ); + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_init( FTC_BasicFamily family, + FTC_BasicQuery query, + FTC_Cache cache ) + { + FTC_Family_Init( FTC_FAMILY( family ), cache ); + family->attrs = query->attrs; + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + ftc_basic_family_get_count( FTC_BasicFamily family, + FTC_Manager manager ) + { + FT_Error error; + FT_Face face; + FT_UInt result = 0; + + + error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id, + &face ); + if ( !error ) + result = face->num_glyphs; + + return result; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_load_bitmap( FTC_BasicFamily family, + FT_UInt gindex, + FTC_Manager manager, + FT_Face *aface ) + { + FT_Error error; + FT_Size size; + + + error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size ); + if ( !error ) + { + FT_Face face = size->face; + + + error = FT_Load_Glyph( face, gindex, + family->attrs.load_flags | FT_LOAD_RENDER ); + if ( !error ) + *aface = face; + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_load_glyph( FTC_BasicFamily family, + FT_UInt gindex, + FTC_Cache cache, + FT_Glyph *aglyph ) + { + FT_Error error; + FTC_Scaler scaler = &family->attrs.scaler; + FT_Face face; + FT_Size size; + + + /* we will now load the glyph image */ + error = FTC_Manager_LookupSize( cache->manager, + scaler, + &size ); + if ( !error ) + { + face = size->face; + + error = FT_Load_Glyph( face, gindex, family->attrs.load_flags ); + if ( !error ) + { + if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || + face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* ok, copy it */ + FT_Glyph glyph; + + + error = FT_Get_Glyph( face->glyph, &glyph ); + if ( !error ) + { + *aglyph = glyph; + goto Exit; + } + } + else + error = FTC_Err_Invalid_Argument; + } + } + + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_basic_gnode_compare_faceid( FTC_GNode gnode, + FTC_FaceID face_id, + FTC_Cache cache ) + { + FTC_BasicFamily family = (FTC_BasicFamily)gnode->family; + FT_Bool result; + + + result = FT_BOOL( family->attrs.scaler.face_id == face_id ); + if ( result ) + { + /* we must call this function to avoid this node from appearing + * in later lookups with the same face_id! + */ + FTC_GNode_UnselectFamily( gnode, cache ); + } + return result; + } + + + /* + * + * basic image cache + * + */ + + FT_CALLBACK_TABLE_DEF + const FTC_IFamilyClassRec ftc_basic_image_family_class = + { + { + sizeof( FTC_BasicFamilyRec ), + (FTC_MruNode_CompareFunc)ftc_basic_family_compare, + (FTC_MruNode_InitFunc) ftc_basic_family_init, + (FTC_MruNode_ResetFunc) NULL, + (FTC_MruNode_DoneFunc) NULL + }, + (FTC_IFamily_LoadGlyphFunc)ftc_basic_family_load_glyph + }; + + + FT_CALLBACK_TABLE_DEF + const FTC_GCacheClassRec ftc_basic_image_cache_class = + { + { + (FTC_Node_NewFunc) ftc_inode_new, + (FTC_Node_WeightFunc) ftc_inode_weight, + (FTC_Node_CompareFunc)ftc_gnode_compare, + (FTC_Node_CompareFunc)ftc_basic_gnode_compare_faceid, + (FTC_Node_FreeFunc) ftc_inode_free, + + sizeof( FTC_GCacheRec ), + (FTC_Cache_InitFunc) ftc_gcache_init, + (FTC_Cache_DoneFunc) ftc_gcache_done + }, + (FTC_MruListClass)&ftc_basic_image_family_class + }; + + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ) + { + return FTC_GCache_New( manager, &ftc_basic_image_cache_class, + (FTC_GCache*)acache ); + } + + + /* documentation is in ftcimage.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ) + { + FTC_BasicQueryRec query; + FTC_INode node; + FT_Error error; + FT_UInt32 hash; + + + /* some argument checks are delayed to FTC_Cache_Lookup */ + if ( !aglyph ) + { + error = FTC_Err_Invalid_Argument; + goto Exit; + } + + *aglyph = NULL; + if ( anode ) + *anode = NULL; + + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.scaler.pixel = 1; + query.attrs.load_flags = type->flags; + + query.attrs.scaler.x_res = 0; /* make compilers happy */ + query.attrs.scaler.y_res = 0; + + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; + +#if 1 /* inlining is about 50% faster! */ + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_GNode_Compare, + hash, gindex, + &query, + node, + error ); +#else + error = FTC_GCache_Lookup( FTC_GCACHE( cache ), + hash, gindex, + FTC_GQUERY( &query ), + (FTC_Node*) &node ); +#endif + if ( !error ) + { + *aglyph = FTC_INODE( node )->glyph; + + if ( anode ) + { + *anode = FTC_NODE( node ); + FTC_NODE( node )->ref_count++; + } + } + + Exit: + return error; + } + + + /* + * + * basic small bitmap cache + * + */ + + + FT_CALLBACK_TABLE_DEF + const FTC_SFamilyClassRec ftc_basic_sbit_family_class = + { + { + sizeof( FTC_BasicFamilyRec ), + (FTC_MruNode_CompareFunc)ftc_basic_family_compare, + (FTC_MruNode_InitFunc) ftc_basic_family_init, + (FTC_MruNode_ResetFunc) NULL, + (FTC_MruNode_DoneFunc) NULL + }, + (FTC_SFamily_GetCountFunc) ftc_basic_family_get_count, + (FTC_SFamily_LoadGlyphFunc)ftc_basic_family_load_bitmap + }; + + + FT_CALLBACK_TABLE_DEF + const FTC_GCacheClassRec ftc_basic_sbit_cache_class = + { + { + (FTC_Node_NewFunc) ftc_snode_new, + (FTC_Node_WeightFunc) ftc_snode_weight, + (FTC_Node_CompareFunc)ftc_snode_compare, + (FTC_Node_CompareFunc)ftc_basic_gnode_compare_faceid, + (FTC_Node_FreeFunc) ftc_snode_free, + + sizeof( FTC_GCacheRec ), + (FTC_Cache_InitFunc) ftc_gcache_init, + (FTC_Cache_DoneFunc) ftc_gcache_done + }, + (FTC_MruListClass)&ftc_basic_sbit_family_class + }; + + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ) + { + return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class, + (FTC_GCache*)acache ); + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *ansbit, + FTC_Node *anode ) + { + FT_Error error; + FTC_BasicQueryRec query; + FTC_SNode node; + FT_UInt32 hash; + + + if ( anode ) + *anode = NULL; + + /* other argument checks delayed to FTC_Cache_Lookup */ + if ( !ansbit ) + return FTC_Err_Invalid_Argument; + + *ansbit = NULL; + + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.scaler.pixel = 1; + query.attrs.load_flags = type->flags; + + query.attrs.scaler.x_res = 0; /* make compilers happy */ + query.attrs.scaler.y_res = 0; + + /* beware, the hash must be the same for all glyph ranges! */ + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + + gindex / FTC_SBIT_ITEMS_PER_NODE; + +#if 1 /* inlining is about 50% faster! */ + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_SNode_Compare, + hash, gindex, + &query, + node, + error ); +#else + error = FTC_GCache_Lookup( FTC_GCACHE( cache ), + hash, + gindex, + FTC_GQUERY( &query ), + (FTC_Node*)&node ); +#endif + if ( error ) + goto Exit; + + *ansbit = node->sbits + ( gindex - FTC_GNODE( node )->gindex ); + + if ( anode ) + { + *anode = FTC_NODE( node ); + FTC_NODE( node )->ref_count++; + } + + Exit: + return error; + } + + +/* END */ Index: xc/extras/freetype2/src/cache/ftccache.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cache/ftccache.c,v retrieving revision 1.2 diff -u -r1.2 ftccache.c --- a/xc/extras/freetype2/src/cache/ftccache.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cache/ftccache.c 28 Apr 2004 10:25:39 -0000 @@ -4,7 +4,7 @@ /* */ /* The FreeType internal cache interface (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,10 +17,11 @@ #include -#include FT_CACHE_MANAGER_H +#include FT_CACHE_INTERNAL_MANAGER_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include "ftccback.h" #include "ftcerror.h" @@ -40,208 +41,194 @@ /*************************************************************************/ /*************************************************************************/ - FT_EXPORT_DEF( void ) - ftc_node_done( FTC_Node node, - FTC_Cache cache ) + /* add a new node to the head of the manager's circular MRU list */ + static void + ftc_node_mru_link( FTC_Node node, + FTC_Manager manager ) { - FTC_Family family; - FTC_FamilyEntry entry; - + FTC_MruNode_Prepend( (FTC_MruNode*)&manager->nodes_list, + (FTC_MruNode)node ); + manager->num_nodes++; + } - entry = cache->manager->families.entries + node->fam_index; - family = entry->family; - /* remove from parent set table - eventually destroy the set */ - if ( --family->num_nodes == 0 ) - FT_LruList_Remove( cache->families, (FT_LruNode) family ); + /* remove a node from the manager's MRU list */ + static void + ftc_node_mru_unlink( FTC_Node node, + FTC_Manager manager ) + { + FTC_MruNode_Remove( (FTC_MruNode*)&manager->nodes_list, + (FTC_MruNode)node ); + manager->num_nodes--; } - /* add a new node to the head of the manager's circular MRU list */ + /* move a node to the head of the manager's MRU list */ static void - ftc_node_mru_link( FTC_Node node, - FTC_Manager manager ) + ftc_node_mru_up( FTC_Node node, + FTC_Manager manager ) { - FTC_Node first = manager->nodes_list; + FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list, + (FTC_MruNode)node ); + } - if ( first ) + /* Note that this function cannot fail. If we cannot re-size the + * buckets array appropriately, we simply degrade the hash table's + * performance! + */ + static void + ftc_cache_resize( FTC_Cache cache ) + { + for (;;) { - FTC_Node last = first->mru_prev; + FTC_Node node, *pnode; + FT_UInt p = cache->p; + FT_UInt mask = cache->mask; + FT_UInt count = mask + p + 1; /* number of buckets */ - FT_ASSERT( last->mru_next == first ); + /* do we need to shrink the buckets array? */ + if ( cache->slack < 0 ) + { + FTC_Node new_list = NULL; - node->mru_prev = last; - node->mru_next = first; - last->mru_next = node; - first->mru_prev = node; - } - else - { - FT_ASSERT( manager->num_nodes == 0 ); + /* try to expand the buckets array _before_ splitting + * the bucket lists + */ + if ( p >= mask ) + { + FT_Memory memory = cache->memory; - node->mru_next = node; - node->mru_prev = node; - } - manager->nodes_list = node; - manager->num_nodes++; - } + /* if we can't expand the array, leave immediately */ + if ( FT_MEM_RENEW_ARRAY( cache->buckets, (mask+1)*2, (mask+1)*4 ) ) + break; + } + /* split a single bucket */ + pnode = cache->buckets + p; - /* remove a node from the manager's MRU list */ - static void - ftc_node_mru_unlink( FTC_Node node, - FTC_Manager manager ) - { - FTC_Node first = manager->nodes_list; - FTC_Node prev = node->mru_prev; - FTC_Node next = node->mru_next; + for (;;) + { + node = *pnode; + if ( node == NULL ) + break; + if ( node->hash & ( mask + 1 ) ) + { + *pnode = node->link; + node->link = new_list; + new_list = node; + } + else + pnode = &node->link; + } - FT_ASSERT( first != NULL && manager->num_nodes > 0 ); - FT_ASSERT( next->mru_prev == node ); - FT_ASSERT( prev->mru_next == node ); + cache->buckets[p + mask + 1] = new_list; - next->mru_prev = prev; - prev->mru_next = next; + cache->slack += FTC_HASH_MAX_LOAD; - if ( node == first ) - { - /* this is the last node in the list; update its head pointer */ - if ( node == next ) - manager->nodes_list = NULL; - else - manager->nodes_list = next; - } + if ( p >= mask ) + { + cache->mask = 2 * mask + 1; + cache->p = 0; + } + else + cache->p = p + 1; + } - node->mru_next = NULL; - node->mru_prev = NULL; - manager->num_nodes--; - } + /* do we need to expand the buckets array? */ + else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD ) + { + FT_UInt old_index = p + mask; + FTC_Node* pold; - /* move a node to the head of the manager's MRU list */ - static void - ftc_node_mru_up( FTC_Node node, - FTC_Manager manager ) - { - FTC_Node first = manager->nodes_list; + if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE ) + break; + if ( p == 0 ) + { + FT_Memory memory = cache->memory; - if ( node != first ) - { - FTC_Node prev = node->mru_prev; - FTC_Node next = node->mru_next; - FTC_Node last; + /* if we can't shrink the array, leave immediately */ + if ( FT_MEM_RENEW_ARRAY( cache->buckets, + ( mask + 1 ) * 2, mask + 1 ) ) + break; - prev->mru_next = next; - next->mru_prev = prev; + cache->mask >>= 1; + p = cache->mask; + } + else + p--; - last = first->mru_prev; - node->mru_next = first; - node->mru_prev = last; - first->mru_prev = node; - last->mru_next = node; + pnode = cache->buckets + p; + while ( *pnode ) + pnode = &(*pnode)->link; + + pold = cache->buckets + old_index; + *pnode = *pold; + *pold = NULL; - manager->nodes_list = node; + cache->slack -= FTC_HASH_MAX_LOAD; + cache->p = p; + } + else /* the hash table is balanced */ + break; } } /* remove a node from its cache's hash table */ - static FT_Error - ftc_node_hash_unlink( FTC_Node node, + static void + ftc_node_hash_unlink( FTC_Node node0, FTC_Cache cache ) { - FT_Error error = 0; FTC_Node *pnode; - FT_UInt idx, num_buckets; + FT_UInt idx; - idx = (FT_UInt)( node->hash & cache->mask ); + idx = (FT_UInt)( node0->hash & cache->mask ); if ( idx < cache->p ) - idx = (FT_UInt)( node->hash & ( 2 * cache->mask + 1 ) ); + idx = (FT_UInt)( node0->hash & ( 2 * cache->mask + 1 ) ); pnode = cache->buckets + idx; for (;;) { - if ( *pnode == NULL ) + FTC_Node node = *pnode; + + + if ( node == NULL ) { FT_ERROR(( "ftc_node_hash_unlink: unknown node!\n" )); - return FTC_Err_Ok; + return; } - if ( *pnode == node ) - { - *pnode = node->link; - node->link = NULL; + if ( node == node0 ) break; - } pnode = &(*pnode)->link; } - num_buckets = ( cache->p + cache->mask + 1 ); - - if ( ++cache->slack > (FT_Long)num_buckets * FTC_HASH_SUB_LOAD ) - { - FT_UInt p = cache->p; - FT_UInt mask = cache->mask; - FT_UInt old_index = p + mask; - FTC_Node* pold; - - - if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE ) - goto Exit; - - if ( p == 0 ) - { - FT_Memory memory = cache->memory; - - - cache->mask >>= 1; - p = cache->mask; - - if ( FT_RENEW_ARRAY( cache->buckets, ( mask + 1 ) * 2, (mask+1) ) ) - { - FT_ERROR(( "ftc_node_hash_unlink: couldn't shunk buckets!\n" )); - goto Exit; - } - } - else - p--; - - pnode = cache->buckets + p; - while ( *pnode ) - pnode = &(*pnode)->link; - - pold = cache->buckets + old_index; - *pnode = *pold; - *pold = NULL; - - cache->slack -= FTC_HASH_MAX_LOAD; - cache->p = p; - } + *pnode = node0->link; + node0->link = NULL; - Exit: - return error; + cache->slack++; + ftc_cache_resize( cache ); } - - /* add a node to the "top" of its cache's hash table */ - static FT_Error + /* add a node to the `top' of its cache's hash table */ + static void ftc_node_hash_link( FTC_Node node, FTC_Cache cache ) { FTC_Node *pnode; FT_UInt idx; - FT_Error error = 0; idx = (FT_UInt)( node->hash & cache->mask ); @@ -253,85 +240,29 @@ node->link = *pnode; *pnode = node; - if ( --cache->slack < 0 ) - { - FT_UInt p = cache->p; - FT_UInt mask = cache->mask; - FTC_Node new_list; - - - /* split a single bucket */ - new_list = NULL; - pnode = cache->buckets + p; - - for (;;) - { - node = *pnode; - if ( node == NULL ) - break; - - if ( node->hash & ( mask + 1 ) ) - { - *pnode = node->link; - node->link = new_list; - new_list = node; - } - else - pnode = &node->link; - } - - cache->buckets[p + mask + 1] = new_list; - - cache->slack += FTC_HASH_MAX_LOAD; - - if ( p >= mask ) - { - FT_Memory memory = cache->memory; - - - if ( FT_RENEW_ARRAY( cache->buckets, - ( mask + 1 ) * 2, ( mask + 1 ) * 4 ) ) - { - FT_ERROR(( "ftc_node_hash_link: couldn't expand buckets!\n" )); - goto Exit; - } - - cache->mask = 2 * mask + 1; - cache->p = 0; - } - else - cache->p = p + 1; - } - - Exit: - return error; + cache->slack--; + ftc_cache_resize( cache ); } - - /* remove a node from the cache manager */ FT_EXPORT_DEF( void ) ftc_node_destroy( FTC_Node node, FTC_Manager manager ) { - FT_Memory memory = manager->library->memory; - FTC_Cache cache; - FTC_FamilyEntry entry; - FTC_Cache_Class clazz; + FTC_Cache cache; #ifdef FT_DEBUG_ERROR /* find node's cache */ - if ( node->fam_index >= manager->families.count ) + if ( node->cache_index >= manager->num_caches ) { FT_ERROR(( "ftc_node_destroy: invalid node handle\n" )); return; } #endif - entry = manager->families.entries + node->fam_index; - cache = entry->cache; + cache = manager->caches[node->cache_index]; #ifdef FT_DEBUG_ERROR if ( cache == NULL ) @@ -341,9 +272,7 @@ } #endif - clazz = cache->clazz; - - manager->cur_weight -= clazz->node_weight( node, cache ); + manager->cur_weight -= cache->clazz.node_weight( node, cache ); /* remove node from mru list */ ftc_node_mru_unlink( node, manager ); @@ -352,10 +281,7 @@ ftc_node_hash_unlink( node, cache ); /* now finalize it */ - if ( clazz->node_done ) - clazz->node_done( node, cache ); - - FT_FREE( node ); + cache->clazz.node_free( node, cache ); #if 0 /* check, just in case of general corruption :-) */ @@ -369,120 +295,42 @@ /*************************************************************************/ /*************************************************************************/ /***** *****/ - /***** CACHE FAMILY DEFINITIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_EXPORT_DEF( FT_Error ) - ftc_family_init( FTC_Family family, - FTC_Query query, - FTC_Cache cache ) - { - FT_Error error; - FTC_Manager manager = cache->manager; - FT_Memory memory = manager->library->memory; - FTC_FamilyEntry entry; - - - family->cache = cache; - family->num_nodes = 0; - - /* now add to manager's family table */ - error = ftc_family_table_alloc( &manager->families, memory, &entry ); - if ( !error ) - { - entry->cache = cache; - entry->family = family; - family->fam_index = entry->index; - - query->family = family; /* save family in query */ - } - - return error; - } - - - FT_EXPORT_DEF( void ) - ftc_family_done( FTC_Family family ) - { - if ( family && family->cache ) - { - FTC_Manager manager = family->cache->manager; - - - /* remove from manager's family table */ - ftc_family_table_free( &manager->families, family->fam_index ); - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ /***** ABSTRACT CACHE CLASS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ - FT_EXPORT_DEF( FT_Error ) - ftc_cache_init( FTC_Cache cache ) + FTC_Cache_Init( FTC_Cache cache ) { - FT_Memory memory = cache->memory; - FTC_Cache_Class clazz = cache->clazz; - FT_Error error; + FT_Memory memory = cache->memory; cache->p = 0; cache->mask = FTC_HASH_INITIAL_SIZE - 1; cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD; - if ( FT_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ) ) - goto Exit; - - /* now, initialize the lru list of families for this cache */ - if ( clazz->family_size > 0 ) - { - FT_LruList_ClassRec* lru_class = &cache->family_class; - + return ( FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ) ); + } - lru_class->list_size = sizeof( FT_LruListRec ); - lru_class->list_init = NULL; - lru_class->list_done = NULL; - - lru_class->node_size = clazz->family_size; - lru_class->node_init = (FT_LruNode_InitFunc) clazz->family_init; - lru_class->node_done = (FT_LruNode_DoneFunc) clazz->family_done; - lru_class->node_flush = (FT_LruNode_FlushFunc) NULL; - lru_class->node_compare = (FT_LruNode_CompareFunc)clazz->family_compare; - - error = FT_LruList_New( (FT_LruList_Class) lru_class, - 0, /* max items == 0 => unbounded list */ - cache, - memory, - &cache->families ); - if ( error ) - FT_FREE( cache->buckets ); - } - Exit: - return error; + FT_LOCAL_DEF( FT_Error ) + ftc_cache_init( FTC_Cache cache ) + { + return FTC_Cache_Init( cache ); } FT_EXPORT_DEF( void ) - ftc_cache_clear( FTC_Cache cache ) + FTC_Cache_Clear( FTC_Cache cache ) { if ( cache ) { - FT_Memory memory = cache->memory; - FTC_Cache_Class clazz = cache->clazz; - FTC_Manager manager = cache->manager; - FT_UFast i; - FT_UInt count; + FTC_Manager manager = cache->manager; + FT_UFast i; + FT_UInt count; + count = cache->p + cache->mask + 1; @@ -500,309 +348,256 @@ ftc_node_mru_unlink( node, manager ); /* now finalize it */ - manager->cur_weight -= clazz->node_weight( node, cache ); - - if ( clazz->node_done ) - clazz->node_done( node, cache ); + manager->cur_weight -= cache->clazz.node_weight( node, cache ); - FT_FREE( node ); + cache->clazz.node_free( node, cache ); node = next; } cache->buckets[i] = NULL; } - - cache->p = 0; - - /* destroy the families */ - if ( cache->families ) - FT_LruList_Reset( cache->families ); + ftc_cache_resize( cache ); } } FT_EXPORT_DEF( void ) - ftc_cache_done( FTC_Cache cache ) + FTC_Cache_Done( FTC_Cache cache ) { - if ( cache ) + if ( cache->memory ) { FT_Memory memory = cache->memory; - ftc_cache_clear( cache ); + FTC_Cache_Clear( cache ); FT_FREE( cache->buckets ); cache->mask = 0; + cache->p = 0; cache->slack = 0; - if ( cache->families ) - { - FT_LruList_Destroy( cache->families ); - cache->families = NULL; - } + cache->memory = NULL; } } - /* Look up a node in "top" of its cache's hash table. */ - /* If not found, create a new node. */ - /* */ - FT_EXPORT_DEF( FT_Error ) - ftc_cache_lookup( FTC_Cache cache, - FTC_Query query, - FTC_Node *anode ) + FT_LOCAL_DEF( void ) + ftc_cache_done( FTC_Cache cache ) { - FT_Error error = FTC_Err_Ok; - FTC_Manager manager; - FT_LruNode lru; - FT_UInt free_count = 0; - - - if ( !cache || !query || !anode ) - return FTC_Err_Invalid_Argument; - - *anode = NULL; - - query->hash = 0; - query->family = NULL; - - manager = cache->manager; - - /* here's a small note explaining what's happening in the code below. - * - * We need to deal intelligently with out-of-memory (OOM) conditions - * when trying to create a new family or cache node during the lookup. - * - * When an OOM is detected, we try to free one or more "old" nodes - * from the cache, then try again. It may be necessary to do that - * several times, so a loop is needed. - * - * The local variable "free_count" holds the number of "old" nodes to - * discard on each attempt. It starts at 1 and doubles on each - * iteration. The loop stops when: - * - * - a non-OOM error is detected - * - a succesful lookup is performed - * - there are no more unused nodes in the cache - * - * For the record, remember that all used nodes appear _before_ - * unused ones in the manager's MRU node list. - */ + FTC_Cache_Done( cache ); + } - for (;;) - { - { - /* first of all, find the relevant family */ - FT_LruList list = cache->families; - FT_LruNode fam, *pfam; - FT_LruNode_CompareFunc compare = list->clazz->node_compare; - pfam = &list->nodes; - for (;;) - { - fam = *pfam; - if ( fam == NULL ) - { - error = FT_LruList_Lookup( list, query, &lru ); - if ( error ) - goto Fail; + static void + ftc_cache_add( FTC_Cache cache, + FT_UInt32 hash, + FTC_Node node ) + { + node->hash = hash; + node->cache_index = (FT_UInt16) cache->index; + node->ref_count = 0; - goto Skip; - } + ftc_node_hash_link( node, cache ); + ftc_node_mru_link( node, cache->manager ); - if ( compare( fam, query, list->data ) ) - break; + { + FTC_Manager manager = cache->manager; - pfam = &fam->next; - } - FT_ASSERT( fam != NULL ); + manager->cur_weight += cache->clazz.node_weight( node, cache ); - /* move to top of list when needed */ - if ( fam != list->nodes ) - { - *pfam = fam->next; - fam->next = list->nodes; - list->nodes = fam; - } + if ( manager->cur_weight >= manager->max_weight ) + { + node->ref_count++; + FTC_Manager_Compress( manager ); + node->ref_count--; + } + } + } - lru = fam; - Skip: - ; - } + FT_EXPORT_DEF( FT_Error ) + FTC_Cache_NewNode( FTC_Cache cache, + FT_UInt32 hash, + FT_Pointer query, + FTC_Node *anode ) + { + FT_Error error; + FTC_Node node; + + /* + * Try to allocate a new cache node. Note that in case of + * out-of-memory error (OOM), we'll flush the cache a bit, + * then try again. + * + * On each try, the `tries' variable gives the number + * of old nodes we want to flush from the manager's global list + * before the next allocation attempt. It barely doubles on + * each iteration. + * + */ + error = cache->clazz.node_new( &node, query, cache ); + if ( error ) + goto FlushCache; + + AddNode: + /* don't assume that the cache has the same number of buckets, since + * our allocation request might have triggered global cache flushing + */ + ftc_cache_add( cache, hash, node ); - { - FTC_Family family = (FTC_Family) lru; - FT_UFast hash = query->hash; - FTC_Node* bucket; - FT_UInt idx; + Exit: + *anode = node; + return error; + FlushCache: + node = NULL; + if ( error != FT_Err_Out_Of_Memory ) + goto Exit; - idx = hash & cache->mask; - if ( idx < cache->p ) - idx = hash & ( cache->mask * 2 + 1 ); + { + FTC_Manager manager = cache->manager; + FT_UInt count, tries = 1; - bucket = cache->buckets + idx; + for (;;) + { + error = cache->clazz.node_new( &node, query, cache ); + if ( !error ) + break; - if ( query->family != family || - family->fam_index >= manager->families.size ) - { - FT_ERROR(( - "ftc_cache_lookup: invalid query (bad 'family' field)\n" )); - error = FTC_Err_Invalid_Argument; + node = NULL; + if ( error != FT_Err_Out_Of_Memory ) goto Exit; - } - - if ( *bucket ) - { - FTC_Node* pnode = bucket; - FTC_Node_CompareFunc compare = cache->clazz->node_compare; + count = FTC_Manager_FlushN( manager, tries ); + if ( count == 0 ) + goto Exit; - for ( ;; ) - { - FTC_Node node; + if ( count == tries ) + { + count = tries * 2; + if ( count < tries || count > manager->num_nodes ) + count = manager->num_nodes; + } + tries = count; + } + } + goto AddNode; + } - node = *pnode; - if ( node == NULL ) - break; - - if ( node->hash == hash && - (FT_UInt)node->fam_index == family->fam_index && - compare( node, query, cache ) ) - { - /* move to head of bucket list */ - if ( pnode != bucket ) - { - *pnode = node->link; - node->link = *bucket; - *bucket = node; - } - - /* move to head of MRU list */ - if ( node != manager->nodes_list ) - ftc_node_mru_up( node, manager ); - - *anode = node; - goto Exit; - } + FT_EXPORT_DEF( FT_Error ) + FTC_Cache_Lookup( FTC_Cache cache, + FT_UInt32 hash, + FT_Pointer query, + FTC_Node *anode ) + { + FT_UFast idx; + FTC_Node* bucket; + FTC_Node* pnode; + FTC_Node node; + FT_Error error = 0; - pnode = &node->link; - } - } + FTC_Node_CompareFunc compare = cache->clazz.node_compare; - /* didn't find a node, create a new one */ - { - FTC_Cache_Class clazz = cache->clazz; - FT_Memory memory = cache->memory; - FTC_Node node; + if ( cache == NULL || anode == NULL ) + return FT_Err_Invalid_Argument; - if ( FT_ALLOC( node, clazz->node_size ) ) - goto Fail; + idx = hash & cache->mask; + if ( idx < cache->p ) + idx = hash & ( cache->mask * 2 + 1 ); - node->fam_index = (FT_UShort) family->fam_index; - node->hash = query->hash; - node->ref_count = 0; + bucket = cache->buckets + idx; + pnode = bucket; + for (;;) + { + node = *pnode; + if ( node == NULL ) + goto NewNode; - error = clazz->node_init( node, query, cache ); - if ( error ) - { - FT_FREE( node ); - goto Fail; - } + if ( node->hash == hash && compare( node, query, cache ) ) + break; - error = ftc_node_hash_link( node, cache ); - if ( error ) - { - clazz->node_done( node, cache ); - FT_FREE( node ); - goto Fail; - } + pnode = &node->link; + } - ftc_node_mru_link( node, cache->manager ); + if ( node != *bucket ) + { + *pnode = node->link; + node->link = *bucket; + *bucket = node; + } - cache->manager->cur_weight += clazz->node_weight( node, cache ); + /* move to head of MRU list */ + { + FTC_Manager manager = cache->manager; - /* now try to compress the node pool when necessary */ - if ( manager->cur_weight >= manager->max_weight ) - { - node->ref_count++; - FTC_Manager_Compress( manager ); - node->ref_count--; - } - *anode = node; - } + if ( node != manager->nodes_list ) + ftc_node_mru_up( node, manager ); + } + *anode = node; + return error; - /* all is well, exit now - */ - goto Exit; - } + NewNode: + return FTC_Cache_NewNode( cache, hash, query, anode ); + } - Fail: - if ( error != FTC_Err_Out_Of_Memory ) - goto Exit; - - /* There is not enough memory; try to release some unused nodes - * from the cache to make room for a new one. - */ - { - FT_UInt new_count; + FT_EXPORT_DEF( void ) + FTC_Cache_RemoveFaceID( FTC_Cache cache, + FTC_FaceID face_id ) + { + FT_UFast i, count; + FTC_Manager manager = cache->manager; + FTC_Node frees = NULL; - new_count = 1 + free_count * 2; - /* check overflow and bounds */ - if ( new_count < free_count || free_count > manager->num_nodes ) - goto Exit; + count = cache->p + cache->mask; + for ( i = 0; i < count; i++ ) + { + FTC_Node* bucket = cache->buckets + i; + FTC_Node* pnode = bucket; - free_count = new_count; - /* try to remove "new_count" nodes from the list */ - { - FTC_Node first = manager->nodes_list; - FTC_Node node; + for ( ;; ) + { + FTC_Node node = *pnode; - if ( first == NULL ) /* empty list! */ - goto Exit; + if ( node == NULL ) + break; - /* go to last node - it's a circular list */ - node = first->mru_prev; - for ( ; node && new_count > 0; new_count-- ) - { - FTC_Node prev = node->mru_prev; + if ( cache->clazz.node_remove_faceid( node, face_id, cache ) ) + { + *pnode = node->link; + node->link = frees; + frees = node; + } + else + pnode = &node->link; + } + } + /* remove all nodes in the free list */ + while ( frees ) + { + FTC_Node node; - /* Used nodes always appear before unused one in the MRU - * list. If we find one here, we'd better stop right now - * our iteration. - */ - if ( node->ref_count > 0 ) - { - /* if there are no unused nodes in the list, we'd better exit */ - if ( new_count == free_count ) - goto Exit; - break; - } + node = frees; + frees = node->link; - ftc_node_destroy( node, manager ); + manager->cur_weight -= cache->clazz.node_weight( node, cache ); + ftc_node_mru_unlink( node, manager ); - if ( node == first ) - break; + cache->clazz.node_free( node, cache ); - node = prev; - } - } - } + cache->slack++; } - Exit: - return error; + ftc_cache_resize( cache ); } Index: xc/extras/freetype2/src/cache/ftccache.i =================================================================== RCS file: xc/extras/freetype2/src/cache/ftccache.i diff -N xc/extras/freetype2/src/cache/ftccache.i --- a/xc/extras/freetype2/src/cache/ftccache.i 25 Nov 2003 19:27:19 -0000 1.1.1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,157 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftccache.i */ -/* */ -/* FreeType template for generic cache. */ -/* */ -/* Copyright 2002 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef GEN_CACHE_FAMILY_COMPARE -#error "GEN_CACHE_FAMILY_COMPARE not defined in template instantiation" -#endif - -#ifndef GEN_CACHE_NODE_COMPARE -#error "GEN_CACHE_NODE_COMPARE not defined in template instantiation" -#endif - - - static FT_Error - GEN_CACHE_LOOKUP( FTC_Cache cache, - FTC_Query query, - FTC_Node *anode ) - { - FT_LruNode lru; - FTC_Family family; - FT_UFast hash; - - - query->hash = 0; - query->family = NULL; - - /* XXX: we break encapsulation for the sake of speed! */ - { - /* first of all, find the relevant family */ - FT_LruList list = cache->families; - FT_LruNode fam, *pfam; - - - pfam = &list->nodes; - for (;;) - { - fam = *pfam; - if ( fam == NULL ) - goto Normal; - - if ( GEN_CACHE_FAMILY_COMPARE( fam, query, list->data ) ) - break; - - pfam = &fam->next; - } - - FT_ASSERT( fam != NULL ); - - /* move to top of list when needed */ - if ( fam != list->nodes ) - { - *pfam = fam->next; - fam->next = list->nodes; - list->nodes = fam; - } - - lru = fam; - } - - { - FTC_Node node, *pnode, *bucket; - - - family = (FTC_Family)lru; - hash = query->hash; - - { - FT_UInt idx; - - - idx = hash & cache->mask; - if ( idx < cache->p ) - idx = hash & ( cache->mask * 2 + 1 ); - - bucket = cache->buckets + idx; - } - - pnode = bucket; - - for ( ;; ) - { - node = *pnode; - if ( node == NULL ) - goto Normal; - - if ( node->hash == hash && - (FT_UInt)node->fam_index == family->fam_index && - GEN_CACHE_NODE_COMPARE( node, query, cache ) ) - { - /* we place the following out of the loop to make it */ - /* as small as possible... */ - goto Found; - } - - pnode = &node->link; - } - - Normal: - return ftc_cache_lookup( cache, query, anode ); - - Found: - /* move to head of bucket list */ - if ( pnode != bucket ) - { - *pnode = node->link; - node->link = *bucket; - *bucket = node; - } - - /* move to head of MRU list */ - if ( node != cache->manager->nodes_list ) - { - /* XXX: again, this is an inlined version of ftc_node_mru_up */ - FTC_Manager manager = cache->manager; - FTC_Node first = manager->nodes_list; - FTC_Node prev = node->mru_prev; - FTC_Node next = node->mru_next; - FTC_Node last; - - - prev->mru_next = next; - next->mru_prev = prev; - - last = first->mru_prev; - node->mru_next = first; - node->mru_prev = last; - first->mru_prev = node; - last->mru_next = node; - - manager->nodes_list = node; - } - - *anode = node; - return 0; - } - } - -#undef GEN_CACHE_NODE_COMPARE -#undef GEN_CACHE_FAMILY_COMPARE -#undef GEN_CACHE_LOOKUP - - -/* END */ Index: xc/extras/freetype2/src/cache/ftccback.h =================================================================== RCS file: xc/extras/freetype2/src/cache/ftccback.h diff -N xc/extras/freetype2/src/cache/ftccback.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/cache/ftccback.h 28 Apr 2004 10:25:39 -0000 @@ -0,0 +1,82 @@ +/***************************************************************************/ +/* */ +/* ftccback.h */ +/* */ +/* Callback functions of the caching sub-system (specification only). */ +/* */ +/* Copyright 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#ifndef __FTCCBACK_H__ +#define __FTCCBACK_H__ + +#include +#include FT_CACHE_H +#include FT_CACHE_INTERNAL_MRU_H +#include FT_CACHE_INTERNAL_IMAGE_H +#include FT_CACHE_INTERNAL_MANAGER_H +#include FT_CACHE_INTERNAL_GLYPH_H +#include FT_CACHE_INTERNAL_SBITS_H + + + FT_LOCAL( void ) + ftc_inode_free( FTC_INode inode, + FTC_Cache cache ); + + FT_LOCAL( FT_Error ) + ftc_inode_new( FTC_INode *pinode, + FTC_GQuery gquery, + FTC_Cache cache ); + + FT_LOCAL( FT_ULong ) + ftc_inode_weight( FTC_INode inode ); + + + FT_LOCAL( void ) + ftc_snode_free( FTC_SNode snode, + FTC_Cache cache ); + + FT_LOCAL( FT_Error ) + ftc_snode_new( FTC_SNode *psnode, + FTC_GQuery gquery, + FTC_Cache cache ); + + FT_LOCAL( FT_ULong ) + ftc_snode_weight( FTC_SNode snode ); + + FT_LOCAL( FT_Bool ) + ftc_snode_compare( FTC_SNode snode, + FTC_GQuery gquery, + FTC_Cache cache ); + + + FT_LOCAL( FT_Bool ) + ftc_gnode_compare( FTC_GNode gnode, + FTC_GQuery gquery ); + + + FT_LOCAL( FT_Error ) + ftc_gcache_init( FTC_GCache cache ); + + FT_LOCAL( void ) + ftc_gcache_done( FTC_GCache cache ); + + + FT_LOCAL( FT_Error ) + ftc_cache_init( FTC_Cache cache ); + + FT_LOCAL( void ) + ftc_cache_done( FTC_Cache cache ); + + +#endif /* __FTCCBACK_H__ */ + +/* END */ Index: xc/extras/freetype2/src/cache/ftccmap.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cache/ftccmap.c,v retrieving revision 1.2 diff -u -r1.2 ftccmap.c --- a/xc/extras/freetype2/src/cache/ftccmap.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cache/ftccmap.c 28 Apr 2004 10:25:39 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType CharMap cache (body) */ /* */ -/* Copyright 2000-2001, 2002, 2003 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,17 +19,18 @@ #include #include FT_FREETYPE_H #include FT_CACHE_H -#include FT_CACHE_CHARMAP_H -#include FT_CACHE_MANAGER_H +#include FT_CACHE_INTERNAL_MANAGER_H #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_DEBUG_H #include FT_TRUETYPE_IDS_H +#include "ftccback.h" #include "ftcerror.h" #undef FT_COMPONENT #define FT_COMPONENT trace_cache + /*************************************************************************/ /* */ /* Each FTC_CMapNode contains a simple array to map a range of character */ @@ -47,56 +48,44 @@ /* number of glyph indices / character code per node */ #define FTC_CMAP_INDICES_MAX 128 + /* compute a query/node hash */ +#define FTC_CMAP_HASH( faceid, index, charcode ) \ + ( FTC_FACE_ID_HASH( faceid ) + 211 * ( index ) + \ + ( (char_code) / FTC_CMAP_INDICES_MAX ) ) + + /* the charmap query */ + typedef struct FTC_CMapQueryRec_ + { + FTC_FaceID face_id; + FT_UInt cmap_index; + FT_UInt32 char_code; + + } FTC_CMapQueryRec, *FTC_CMapQuery; +#define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x)) +#define FTC_CMAP_QUERY_HASH( x ) \ + FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code ) + + /* the cmap cache node */ typedef struct FTC_CMapNodeRec_ { FTC_NodeRec node; + FTC_FaceID face_id; + FT_UInt cmap_index; FT_UInt32 first; /* first character in node */ FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */ } FTC_CMapNodeRec, *FTC_CMapNode; - #define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) - - - /* compute node hash value from cmap family and "requested" glyph index */ -#define FTC_CMAP_HASH( cfam, cquery ) \ - ( (cfam)->hash + ( (cquery)->char_code / FTC_CMAP_INDICES_MAX ) ) +#define FTC_CMAP_NODE_HASH( x ) \ + FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first ) /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ #define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 ) - /* the charmap query */ - typedef struct FTC_CMapQueryRec_ - { - FTC_QueryRec query; - FTC_CMapDesc desc; - FT_UInt32 char_code; - - } FTC_CMapQueryRec, *FTC_CMapQuery; - - -#define FTC_CMAP_QUERY( x ) ( (FTC_CMapQuery)( x ) ) - - - /* the charmap family */ - typedef struct FTC_CMapFamilyRec_ - { - FTC_FamilyRec family; - FT_UInt32 hash; - FTC_CMapDescRec desc; - FT_UInt index; - - } FTC_CMapFamilyRec, *FTC_CMapFamily; - - -#define FTC_CMAP_FAMILY( x ) ( (FTC_CMapFamily)( x ) ) -#define FTC_CMAP_FAMILY_MEMORY( x ) FTC_FAMILY( x )->memory - - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -106,27 +95,44 @@ /*************************************************************************/ - /* no need for specific finalizer; we use "ftc_node_done" directly */ + /* no need for specific finalizer; we use `ftc_node_done' directly */ + + FT_CALLBACK_DEF( void ) + ftc_cmap_node_free( FTC_CMapNode node, + FTC_Cache cache ) + { + FT_Memory memory = cache->memory; + + + FT_FREE( node ); + } + /* initialize a new cmap node */ FT_CALLBACK_DEF( FT_Error ) - ftc_cmap_node_init( FTC_CMapNode cnode, - FTC_CMapQuery cquery, - FTC_Cache cache ) + ftc_cmap_node_new( FTC_CMapNode *anode, + FTC_CMapQuery query, + FTC_Cache cache ) { - FT_UInt32 first; - FT_UInt n; - FT_UNUSED( cache ); + FT_Error error; + FT_Memory memory = cache->memory; + FTC_CMapNode node; + FT_UInt nn; - first = ( cquery->char_code / FTC_CMAP_INDICES_MAX ) * - FTC_CMAP_INDICES_MAX; + if ( !FT_NEW( node ) ) + { + node->face_id = query->face_id; + node->cmap_index = query->cmap_index; + node->first = (query->char_code / FTC_CMAP_INDICES_MAX) * + FTC_CMAP_INDICES_MAX; - cnode->first = first; - for ( n = 0; n < FTC_CMAP_INDICES_MAX; n++ ) - cnode->indices[n] = FTC_CMAP_UNKNOWN; + for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ ) + node->indices[nn] = FTC_CMAP_UNKNOWN; + } - return 0; + *anode = node; + return error; } @@ -142,185 +148,27 @@ /* compare a cmap node to a given query */ FT_CALLBACK_DEF( FT_Bool ) - ftc_cmap_node_compare( FTC_CMapNode cnode, - FTC_CMapQuery cquery ) - { - FT_UInt32 offset = (FT_UInt32)( cquery->char_code - cnode->first ); - - - return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CHARMAP FAMILY *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_DEF( FT_Error ) - ftc_cmap_family_init( FTC_CMapFamily cfam, - FTC_CMapQuery cquery, - FTC_Cache cache ) + ftc_cmap_node_compare( FTC_CMapNode node, + FTC_CMapQuery query ) { - FTC_Manager manager = cache->manager; - FTC_CMapDesc desc = cquery->desc; - FT_UInt32 hash = 0; - FT_Error error; - FT_Face face; - - - /* setup charmap descriptor */ - cfam->desc = *desc; - - /* let's see whether the rest is correct too */ - error = FTC_Manager_Lookup_Face( manager, desc->face_id, &face ); - if ( !error ) + if ( node->face_id == query->face_id && + node->cmap_index == query->cmap_index ) { - FT_UInt count = face->num_charmaps; - FT_UInt idx = count; - FT_CharMap* cur = face->charmaps; - - - switch ( desc->type ) - { - case FTC_CMAP_BY_INDEX: - idx = desc->u.index; - hash = idx * 33; - break; - - case FTC_CMAP_BY_ENCODING: - if ( desc->u.encoding == FT_ENCODING_UNICODE ) - { - /* Since the `interesting' table, pid/eid (3,10), is normally the - * last one, we loop backwards. This looses with type1 fonts with - * non-BMP characters (<.0001%), this wins with .ttf with non-BMP - * chars (.01% ?), and this is the same about 99.99% of the time! - */ - - FT_UInt unicmap_idx = count; /* some UCS-2 map, if we found it */ - - - cur += count - 1; - - for ( idx = 0; idx < count; idx++, cur-- ) - { - if ( cur[0]->encoding == FT_ENCODING_UNICODE ) - { - unicmap_idx = idx; /* record we found a Unicode charmap */ - - /* XXX If some new encodings to represent UCS-4 are added, - * they should be added here. - */ - if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && - cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || - ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && - cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) - - /* Hurray! We found a UCS-4 charmap. We can stop the scan! */ - { - idx = count - 1 - idx; - goto Found_idx_for_FTC_CMAP_BY_ENCODING; - } - } - } - - /* We do not have any UCS-4 charmap. Sigh. - * Let's see if we have some other kind of Unicode charmap, though. - */ - if ( unicmap_idx < count ) - idx = count - 1 - unicmap_idx; - } - else - { - for ( idx = 0; idx < count; idx++, cur++ ) - if ( cur[0]->encoding == desc->u.encoding ) - break; - } - - Found_idx_for_FTC_CMAP_BY_ENCODING: - hash = idx * 67; - break; - - case FTC_CMAP_BY_ID: - for ( idx = 0; idx < count; idx++, cur++ ) - { - if ( (FT_UInt)cur[0]->platform_id == desc->u.id.platform && - (FT_UInt)cur[0]->encoding_id == desc->u.id.encoding ) - { - hash = ( ( desc->u.id.platform << 8 ) | desc->u.id.encoding ) * 7; - break; - } - } - break; - - default: - ; - } - - if ( idx >= count ) - goto Bad_Descriptor; + FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first ); - /* compute hash value, both in family and query */ - cfam->index = idx; - cfam->hash = hash ^ FTC_FACE_ID_HASH( desc->face_id ); - FTC_QUERY( cquery )->hash = FTC_CMAP_HASH( cfam, cquery ); - error = ftc_family_init( FTC_FAMILY( cfam ), - FTC_QUERY( cquery ), cache ); + return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); } - return error; - - Bad_Descriptor: - FT_TRACE1(( "ftp_cmap_family_init: invalid charmap descriptor\n" )); - return FTC_Err_Invalid_Argument; + return 0; } FT_CALLBACK_DEF( FT_Bool ) - ftc_cmap_family_compare( FTC_CMapFamily cfam, - FTC_CMapQuery cquery ) + ftc_cmap_node_remove_faceid( FTC_CMapNode node, + FTC_FaceID face_id ) { - FT_Int result = 0; - - - /* first, compare face id and type */ - if ( cfam->desc.face_id != cquery->desc->face_id || - cfam->desc.type != cquery->desc->type ) - goto Exit; - - switch ( cfam->desc.type ) - { - case FTC_CMAP_BY_INDEX: - result = ( cfam->desc.u.index == cquery->desc->u.index ); - break; - - case FTC_CMAP_BY_ENCODING: - result = ( cfam->desc.u.encoding == cquery->desc->u.encoding ); - break; - - case FTC_CMAP_BY_ID: - result = ( cfam->desc.u.id.platform == cquery->desc->u.id.platform && - cfam->desc.u.id.encoding == cquery->desc->u.id.encoding ); - break; - - default: - ; - } - - if ( result ) - { - /* when found, update the 'family' and 'hash' field of the query */ - FTC_QUERY( cquery )->family = FTC_FAMILY( cfam ); - FTC_QUERY( cquery )->hash = FTC_CMAP_HASH( cfam, cquery ); - } - - Exit: - return FT_BOOL( result ); + return FT_BOOL( node->face_id == face_id ); } @@ -334,23 +182,17 @@ FT_CALLBACK_TABLE_DEF - const FTC_Cache_ClassRec ftc_cmap_cache_class = + const FTC_CacheClassRec ftc_cmap_cache_class = { - sizeof ( FTC_CacheRec ), - (FTC_Cache_InitFunc) ftc_cache_init, - (FTC_Cache_ClearFunc)ftc_cache_clear, - (FTC_Cache_DoneFunc) ftc_cache_done, - - sizeof ( FTC_CMapFamilyRec ), - (FTC_Family_InitFunc) ftc_cmap_family_init, - (FTC_Family_CompareFunc)ftc_cmap_family_compare, - (FTC_Family_DoneFunc) ftc_family_done, - - sizeof ( FTC_CMapNodeRec ), - (FTC_Node_InitFunc) ftc_cmap_node_init, + (FTC_Node_NewFunc) ftc_cmap_node_new, (FTC_Node_WeightFunc) ftc_cmap_node_weight, (FTC_Node_CompareFunc)ftc_cmap_node_compare, - (FTC_Node_DoneFunc) ftc_node_done + (FTC_Node_CompareFunc)ftc_cmap_node_remove_faceid, + (FTC_Node_FreeFunc) ftc_cmap_node_free, + + sizeof ( FTC_CacheRec ), + (FTC_Cache_InitFunc) ftc_cache_init, + (FTC_Cache_DoneFunc) ftc_cache_done, }; @@ -360,99 +202,84 @@ FTC_CMapCache_New( FTC_Manager manager, FTC_CMapCache *acache ) { - return FTC_Manager_Register_Cache( - manager, - (FTC_Cache_Class)&ftc_cmap_cache_class, - FTC_CACHE_P( acache ) ); + return FTC_Manager_RegisterCache( manager, + &ftc_cmap_cache_class, + FTC_CACHE_P( acache ) ); } -#ifdef FTC_CACHE_USE_INLINE - -#define GEN_CACHE_FAMILY_COMPARE( f, q, c ) \ - ftc_cmap_family_compare( (FTC_CMapFamily)(f), (FTC_CMapQuery)(q) ) - -#define GEN_CACHE_NODE_COMPARE( n, q, c ) \ - ftc_cmap_node_compare( (FTC_CMapNode)(n), (FTC_CMapQuery)(q) ) - -#define GEN_CACHE_LOOKUP ftc_cmap_cache_lookup - -#include "ftccache.i" - -#else /* !FTC_CACHE_USE_INLINE */ - -#define ftc_cmap_cache_lookup ftc_cache_lookup - -#endif /* !FTC_CACHE_USE_INLINE */ - - /* documentation is in ftccmap.h */ FT_EXPORT_DEF( FT_UInt ) - FTC_CMapCache_Lookup( FTC_CMapCache cache, - FTC_CMapDesc desc, + FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, + FTC_FaceID face_id, + FT_Int cmap_index, FT_UInt32 char_code ) { - FTC_CMapQueryRec cquery; + FTC_Cache cache = FTC_CACHE( cmap_cache ); + FTC_CMapQueryRec query; FTC_CMapNode node; FT_Error error; FT_UInt gindex = 0; + FT_UInt32 hash; - if ( !cache || !desc ) + if ( !cache ) { FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" )); return 0; } - cquery.desc = desc; - cquery.char_code = char_code; - - error = ftc_cmap_cache_lookup( FTC_CACHE( cache ), - FTC_QUERY( &cquery ), - (FTC_Node*)&node ); - if ( !error ) - { - FT_UInt offset = (FT_UInt)( char_code - node->first ); + query.face_id = face_id; + query.cmap_index = (FT_UInt)cmap_index; + query.char_code = char_code; + + hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); + +#if 1 + FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, + node, error ); +#else + error = FTC_Cache_Lookup( cache, hash, &query, (FTC_Node*) &node ); +#endif + if ( error ) + goto Exit; + FT_ASSERT( (FT_UInt)( char_code - node->first ) < FTC_CMAP_INDICES_MAX ); - FT_ASSERT( offset < FTC_CMAP_INDICES_MAX ); + gindex = node->indices[char_code - node->first]; + if ( gindex == FTC_CMAP_UNKNOWN ) + { + FT_Face face; - gindex = node->indices[offset]; - if ( gindex == FTC_CMAP_UNKNOWN ) - { - FT_Face face; + gindex = 0; - /* we need to use FT_Get_Char_Index */ - gindex = 0; + error = FTC_Manager_LookupFace( cache->manager, node->face_id, &face ); + if ( error ) + goto Exit; - error = FTC_Manager_Lookup_Face( FTC_CACHE(cache)->manager, - desc->face_id, - &face ); - if ( !error ) - { - FT_CharMap old, cmap = NULL; - FT_UInt cmap_index; + if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) + { + FT_CharMap old, cmap = NULL; - /* save old charmap, select new one */ - old = face->charmap; - cmap_index = FTC_CMAP_FAMILY( FTC_QUERY( &cquery )->family )->index; - cmap = face->charmaps[cmap_index]; + old = face->charmap; + cmap = face->charmaps[cmap_index]; + if ( old != cmap ) FT_Set_Charmap( face, cmap ); - /* perform lookup */ - gindex = FT_Get_Char_Index( face, char_code ); - node->indices[offset] = (FT_UInt16)gindex; + gindex = FT_Get_Char_Index( face, char_code ); - /* restore old charmap */ + if ( old != cmap ) FT_Set_Charmap( face, old ); - } } + + node->indices[char_code - node->first] = gindex; } + Exit: return gindex; } Index: xc/extras/freetype2/src/cache/ftcglyph.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cache/ftcglyph.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 ftcglyph.c --- a/xc/extras/freetype2/src/cache/ftcglyph.c 14 Nov 2003 16:48:24 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/cache/ftcglyph.c 28 Apr 2004 10:25:39 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType Glyph Image (FT_Glyph) cache (body). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,54 +20,64 @@ #include FT_CACHE_H #include FT_CACHE_INTERNAL_GLYPH_H #include FT_ERRORS_H -#include FT_LIST_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include "ftccback.h" #include "ftcerror.h" /* create a new chunk node, setting its cache index and ref count */ FT_EXPORT_DEF( void ) - ftc_glyph_node_init( FTC_GlyphNode gnode, - FT_UInt gindex, - FTC_GlyphFamily gfam ) + FTC_GNode_Init( FTC_GNode gnode, + FT_UInt gindex, + FTC_Family family ) { - FT_UInt len; - FT_UInt start = FTC_GLYPH_FAMILY_START( gfam, gindex ); + gnode->family = family; + gnode->gindex = gindex; + family->num_nodes++; + } - gnode->item_start = (FT_UShort)start; + FT_EXPORT_DEF( void ) + FTC_GNode_UnselectFamily( FTC_GNode gnode, + FTC_Cache cache ) + { + FTC_Family family = gnode->family; - len = gfam->item_total - start; - if ( len > gfam->item_count ) - len = gfam->item_count; - gnode->item_count = (FT_UShort)len; - gfam->family.num_nodes++; + gnode->family = NULL; + if ( family && --family->num_nodes <= 0 ) + FTC_MruList_Remove( &FTC_GCACHE( cache )->families, + (FTC_MruNode)family ); } FT_EXPORT_DEF( void ) - ftc_glyph_node_done( FTC_GlyphNode gnode, - FTC_Cache cache ) + FTC_GNode_Done( FTC_GNode gnode, + FTC_Cache cache ) { /* finalize the node */ - gnode->item_count = 0; - gnode->item_start = 0; + gnode->gindex = 0; - ftc_node_done( FTC_NODE( gnode ), cache ); + FTC_GNode_UnselectFamily( gnode, cache ); } FT_EXPORT_DEF( FT_Bool ) - ftc_glyph_node_compare( FTC_GlyphNode gnode, - FTC_GlyphQuery gquery ) + FTC_GNode_Compare( FTC_GNode gnode, + FTC_GQuery gquery ) { - FT_UInt start = (FT_UInt)gnode->item_start; - FT_UInt count = (FT_UInt)gnode->item_count; + return FT_BOOL( gnode->family == gquery->family && + gnode->gindex == gquery->gindex ); + } + - return FT_BOOL( (FT_UInt)( gquery->gindex - start ) < count ); + FT_LOCAL_DEF( FT_Bool ) + ftc_gnode_compare( FTC_GNode gnode, + FTC_GQuery gquery ) + { + return FTC_GNode_Compare( gnode, gquery ); } @@ -79,36 +89,89 @@ /*************************************************************************/ /*************************************************************************/ + FT_EXPORT_DEF( void ) + FTC_Family_Init( FTC_Family family, + FTC_Cache cache ) + { + FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS( cache ); + + + family->clazz = clazz->family_class; + family->num_nodes = 0; + family->cache = cache; + } + FT_EXPORT_DEF( FT_Error ) - ftc_glyph_family_init( FTC_GlyphFamily gfam, - FT_UInt32 hash, - FT_UInt item_count, - FT_UInt item_total, - FTC_GlyphQuery gquery, - FTC_Cache cache ) + FTC_GCache_Init( FTC_GCache cache ) { - FT_Error error; + FT_Error error; - - error = ftc_family_init( FTC_FAMILY( gfam ), FTC_QUERY( gquery ), cache ); + error = FTC_Cache_Init( FTC_CACHE( cache ) ); if ( !error ) { - gfam->hash = hash; - gfam->item_total = item_total; - gfam->item_count = item_count; - - FTC_GLYPH_FAMILY_FOUND( gfam, gquery ); + FTC_GCacheClass clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class; + + FTC_MruList_Init( &cache->families, + clazz->family_class, + 0, /* no maximum here! */ + cache, + FTC_CACHE( cache )->memory ); } return error; } + FT_LOCAL_DEF( FT_Error ) + ftc_gcache_init( FTC_GCache cache ) + { + return FTC_GCache_Init( cache ); + } + + FT_EXPORT_DEF( void ) - ftc_glyph_family_done( FTC_GlyphFamily gfam ) + FTC_GCache_Done( FTC_GCache cache ) + { + FTC_Cache_Done( (FTC_Cache)cache ); + FTC_MruList_Done( &cache->families ); + } + + + FT_LOCAL_DEF( void ) + ftc_gcache_done( FTC_GCache cache ) + { + FTC_GCache_Done( cache ); + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_GCache_New( FTC_Manager manager, + FTC_GCacheClass clazz, + FTC_GCache *acache ) + { + return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz, + (FTC_Cache*)acache ); + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_GCache_Lookup( FTC_GCache cache, + FT_UInt32 hash, + FT_UInt gindex, + FTC_GQuery query, + FTC_Node *anode ) { - ftc_family_done( FTC_FAMILY( gfam ) ); + FT_Error error; + + + query->gindex = gindex; + + FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); + if ( !error ) + error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode ); + + return error; } Index: xc/extras/freetype2/src/cache/ftcimage.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cache/ftcimage.c,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 ftcimage.c --- a/xc/extras/freetype2/src/cache/ftcimage.c 25 Nov 2003 19:27:19 -0000 1.1.1.2 +++ b/xc/extras/freetype2/src/cache/ftcimage.c 28 Apr 2004 10:25:39 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType Image cache (body). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,133 +18,83 @@ #include #include FT_CACHE_H -#include FT_CACHE_IMAGE_H -#include FT_CACHE_INTERNAL_GLYPH_H +#include FT_CACHE_INTERNAL_IMAGE_H #include FT_INTERNAL_MEMORY_H +#include "ftccback.h" #include "ftcerror.h" - /* the FT_Glyph image node type */ - typedef struct FTC_ImageNodeRec_ + /* finalize a given glyph image node */ + FT_EXPORT_DEF( void ) + FTC_INode_Free( FTC_INode inode, + FTC_Cache cache ) { - FTC_GlyphNodeRec gnode; - FT_Glyph glyph; + FT_Memory memory = cache->memory; - } FTC_ImageNodeRec, *FTC_ImageNode; + if ( inode->glyph ) + { + FT_Done_Glyph( inode->glyph ); + inode->glyph = NULL; + } -#define FTC_IMAGE_NODE( x ) ( (FTC_ImageNode)( x ) ) -#define FTC_IMAGE_NODE_GINDEX( x ) FTC_GLYPH_NODE_GINDEX( x ) + FTC_GNode_Done( FTC_GNODE( inode ), cache ); + FT_FREE( inode ); + } - /* the glyph image query */ - typedef struct FTC_ImageQueryRec_ + FT_LOCAL_DEF( void ) + ftc_inode_free( FTC_INode inode, + FTC_Cache cache ) { - FTC_GlyphQueryRec gquery; - FTC_ImageTypeRec type; - - } FTC_ImageQueryRec, *FTC_ImageQuery; - - -#define FTC_IMAGE_QUERY( x ) ( (FTC_ImageQuery)( x ) ) + FTC_INode_Free( inode, cache ); + } - /* the glyph image set type */ - typedef struct FTC_ImageFamilyRec_ + /* initialize a new glyph image node */ + FT_EXPORT_DEF( FT_Error ) + FTC_INode_New( FTC_INode *pinode, + FTC_GQuery gquery, + FTC_Cache cache ) { - FTC_GlyphFamilyRec gfam; - FTC_ImageTypeRec type; - - } FTC_ImageFamilyRec, *FTC_ImageFamily; + FT_Memory memory = cache->memory; + FT_Error error; + FTC_INode inode; -#define FTC_IMAGE_FAMILY( x ) ( (FTC_ImageFamily)( x ) ) -#define FTC_IMAGE_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &(x)->gfam ) - + if ( !FT_NEW( inode ) ) + { + FTC_GNode gnode = FTC_GNODE( inode ); + FTC_Family family = gquery->family; + FT_UInt gindex = gquery->gindex; + FTC_IFamilyClass clazz = FTC_CACHE__IFAMILY_CLASS( cache ); - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLYPH IMAGE NODES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ + /* initialize its inner fields */ + FTC_GNode_Init( gnode, gindex, family ); - /* finalize a given glyph image node */ - FT_CALLBACK_DEF( void ) - ftc_image_node_done( FTC_ImageNode inode, - FTC_Cache cache ) - { - if ( inode->glyph ) - { - FT_Done_Glyph( inode->glyph ); - inode->glyph = NULL; + /* we will now load the glyph image */ + error = clazz->family_load_glyph( family, gindex, cache, + &inode->glyph ); } - ftc_glyph_node_done( FTC_GLYPH_NODE( inode ), cache ); + *pinode = inode; + return error; } - /* initialize a new glyph image node */ - FT_CALLBACK_DEF( FT_Error ) - ftc_image_node_init( FTC_ImageNode inode, - FTC_GlyphQuery gquery, - FTC_Cache cache ) + FT_LOCAL_DEF( FT_Error ) + ftc_inode_new( FTC_INode *pinode, + FTC_GQuery gquery, + FTC_Cache cache ) { - FTC_ImageFamily ifam = FTC_IMAGE_FAMILY( gquery->query.family ); - FT_Error error; - FT_Face face; - FT_Size size; - - - /* initialize its inner fields */ - ftc_glyph_node_init( FTC_GLYPH_NODE( inode ), - gquery->gindex, - FTC_GLYPH_FAMILY( ifam ) ); - - /* we will now load the glyph image */ - error = FTC_Manager_Lookup_Size( FTC_FAMILY( ifam )->cache->manager, - &ifam->type.font, - &face, &size ); - if ( !error ) - { - FT_UInt gindex = FTC_GLYPH_NODE_GINDEX( inode ); - - - error = FT_Load_Glyph( face, gindex, ifam->type.flags ); - if ( !error ) - { - if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || - face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) - { - /* ok, copy it */ - FT_Glyph glyph; - - - error = FT_Get_Glyph( face->glyph, &glyph ); - if ( !error ) - { - inode->glyph = glyph; - goto Exit; - } - } - else - error = FTC_Err_Invalid_Argument; - } - } - - /* in case of error */ - ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache ); - - Exit: - return error; + return FTC_INode_New( pinode, gquery, cache ); } - FT_CALLBACK_DEF( FT_ULong ) - ftc_image_node_weight( FTC_ImageNode inode ) + FT_EXPORT_DEF( FT_ULong ) + FTC_INode_Weight( FTC_INode inode ) { FT_ULong size = 0; FT_Glyph glyph = inode->glyph; @@ -185,214 +135,10 @@ } - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLYPH IMAGE SETS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_DEF( FT_Error ) - ftc_image_family_init( FTC_ImageFamily ifam, - FTC_ImageQuery iquery, - FTC_Cache cache ) - { - FTC_Manager manager = cache->manager; - FT_Error error; - FT_Face face; - - - ifam->type = iquery->type; - - /* we need to compute "iquery.item_total" now */ - error = FTC_Manager_Lookup_Face( manager, - iquery->type.font.face_id, - &face ); - if ( !error ) - { - error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( ifam ), - FTC_IMAGE_TYPE_HASH( &ifam->type ), - 1, - face->num_glyphs, - FTC_GLYPH_QUERY( iquery ), - cache ); - } - - return error; - } - - - FT_CALLBACK_DEF( FT_Bool ) - ftc_image_family_compare( FTC_ImageFamily ifam, - FTC_ImageQuery iquery ) - { - FT_Bool result; - - - result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &ifam->type, &iquery->type ) ); - if ( result ) - FTC_GLYPH_FAMILY_FOUND( ifam, iquery ); - - return result; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLYPH IMAGE CACHE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - - FT_CALLBACK_TABLE_DEF - const FTC_Cache_ClassRec ftc_image_cache_class = + FT_LOCAL_DEF( FT_ULong ) + ftc_inode_weight( FTC_INode inode ) { - sizeof ( FTC_CacheRec ), - (FTC_Cache_InitFunc) ftc_cache_init, - (FTC_Cache_ClearFunc)ftc_cache_clear, - (FTC_Cache_DoneFunc) ftc_cache_done, - - sizeof ( FTC_ImageFamilyRec ), - (FTC_Family_InitFunc) ftc_image_family_init, - (FTC_Family_CompareFunc)ftc_image_family_compare, - (FTC_Family_DoneFunc) ftc_glyph_family_done, - - sizeof ( FTC_ImageNodeRec ), - (FTC_Node_InitFunc) ftc_image_node_init, - (FTC_Node_WeightFunc) ftc_image_node_weight, - (FTC_Node_CompareFunc)ftc_glyph_node_compare, - (FTC_Node_DoneFunc) ftc_image_node_done - }; - - - /* documentation is in ftcimage.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_ImageCache_New( FTC_Manager manager, - FTC_ImageCache *acache ) - { - return FTC_Manager_Register_Cache( - manager, - (FTC_Cache_Class)&ftc_image_cache_class, - FTC_CACHE_P( acache ) ); - } - - - /* documentation is in ftcimage.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_ImageCache_Lookup( FTC_ImageCache cache, - FTC_ImageType type, - FT_UInt gindex, - FT_Glyph *aglyph, - FTC_Node *anode ) - { - FTC_ImageQueryRec iquery; - FTC_ImageNode node; - FT_Error error; - - - /* some argument checks are delayed to ftc_cache_lookup */ - if ( !aglyph ) - return FTC_Err_Invalid_Argument; - - if ( anode ) - *anode = NULL; - - iquery.gquery.gindex = gindex; - iquery.type = *type; - - error = ftc_cache_lookup( FTC_CACHE( cache ), - FTC_QUERY( &iquery ), - (FTC_Node*)&node ); - if ( !error ) - { - *aglyph = node->glyph; - - if ( anode ) - { - *anode = (FTC_Node)node; - FTC_NODE( node )->ref_count++; - } - } - - return error; - } - - - /* backwards-compatibility functions */ - - FT_EXPORT_DEF( FT_Error ) - FTC_Image_Cache_New( FTC_Manager manager, - FTC_Image_Cache *acache ) - { - return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache ); - } - - - FT_EXPORT_DEF( FT_Error ) - FTC_Image_Cache_Lookup( FTC_Image_Cache icache, - FTC_Image_Desc* desc, - FT_UInt gindex, - FT_Glyph *aglyph ) - { - FTC_ImageTypeRec type0; - - - if ( !desc ) - return FTC_Err_Invalid_Argument; - - type0.font = desc->font; - - /* convert image type flags to load flags */ - { - FT_UInt load_flags = FT_LOAD_DEFAULT; - FT_UInt type = desc->image_type; - - - /* determine load flags, depending on the font description's */ - /* image type */ - - if ( ftc_image_format( type ) == ftc_image_format_bitmap ) - { - if ( type & ftc_image_flag_monochrome ) - load_flags |= FT_LOAD_MONOCHROME; - - /* disable embedded bitmaps loading if necessary */ - if ( type & ftc_image_flag_no_sbits ) - load_flags |= FT_LOAD_NO_BITMAP; - } - else - { - /* we want an outline, don't load embedded bitmaps */ - load_flags |= FT_LOAD_NO_BITMAP; - - if ( type & ftc_image_flag_unscaled ) - load_flags |= FT_LOAD_NO_SCALE; - } - - /* always render glyphs to bitmaps */ - load_flags |= FT_LOAD_RENDER; - - if ( type & ftc_image_flag_unhinted ) - load_flags |= FT_LOAD_NO_HINTING; - - if ( type & ftc_image_flag_autohinted ) - load_flags |= FT_LOAD_FORCE_AUTOHINT; - - type0.flags = load_flags; - } - - return FTC_ImageCache_Lookup( (FTC_ImageCache)icache, - &type0, - gindex, - aglyph, - NULL ); + return FTC_INode_Weight( inode ); } Index: xc/extras/freetype2/src/cache/ftcmanag.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cache/ftcmanag.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 ftcmanag.c --- a/xc/extras/freetype2/src/cache/ftcmanag.c 14 Nov 2003 16:48:24 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/cache/ftcmanag.c 28 Apr 2004 10:25:39 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (body). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,8 +18,7 @@ #include #include FT_CACHE_H -#include FT_CACHE_MANAGER_H -#include FT_CACHE_INTERNAL_LRU_H +#include FT_CACHE_INTERNAL_MANAGER_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include FT_SIZES_H @@ -33,124 +32,151 @@ #define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data ) - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FACE LRU IMPLEMENTATION *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ + static FT_Error + ftc_scaler_lookup_size( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ) + { + FT_Face face; + FT_Size size = NULL; + FT_Error error; - typedef struct FTC_FaceNodeRec_* FTC_FaceNode; - typedef struct FTC_SizeNodeRec_* FTC_SizeNode; + error = FTC_Manager_LookupFace( manager, scaler->face_id, &face ); + if ( error ) + goto Exit; - typedef struct FTC_FaceNodeRec_ - { - FT_LruNodeRec lru; - FT_Face face; + error = FT_New_Size( face, &size ); + if ( error ) + goto Exit; - } FTC_FaceNodeRec; + FT_Activate_Size( size ); + + if ( scaler->pixel ) + error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height ); + else + error = FT_Set_Char_Size( face, scaler->width, scaler->height, + scaler->x_res, scaler->y_res ); + if ( error ) + { + FT_Done_Size( size ); + size = NULL; + } + + Exit: + *asize = size; + return error; + } typedef struct FTC_SizeNodeRec_ { - FT_LruNodeRec lru; - FT_Size size; + FTC_MruNodeRec node; + FT_Size size; + FTC_ScalerRec scaler; - } FTC_SizeNodeRec; + } FTC_SizeNodeRec, *FTC_SizeNode; - FT_CALLBACK_DEF( FT_Error ) - ftc_face_node_init( FTC_FaceNode node, - FTC_FaceID face_id, - FTC_Manager manager ) + FT_CALLBACK_DEF( void ) + ftc_size_node_done( FTC_SizeNode node ) { - FT_Error error; - + FT_Size size = node->size; - error = manager->request_face( face_id, - manager->library, - manager->request_data, - &node->face ); - if ( !error ) - { - /* destroy initial size object; it will be re-created later */ - if ( node->face->size ) - FT_Done_Size( node->face->size ); - } - return error; + if ( size ) + FT_Done_Size( size ); } - /* helper function for ftc_face_node_done() */ FT_CALLBACK_DEF( FT_Bool ) - ftc_size_node_select( FTC_SizeNode node, - FT_Face face ) + ftc_size_node_compare( FTC_SizeNode node, + FTC_Scaler scaler ) { - return FT_BOOL( node->size->face == face ); + FTC_Scaler scaler0 = &node->scaler; + + + if ( FTC_SCALER_COMPARE( scaler0, scaler ) ) + { + FT_Activate_Size( node->size ); + return 1; + } + return 0; } - FT_CALLBACK_DEF( void ) - ftc_face_node_done( FTC_FaceNode node, + FT_CALLBACK_DEF( FT_Error ) + ftc_size_node_init( FTC_SizeNode node, + FTC_Scaler scaler, FTC_Manager manager ) { - FT_Face face = node->face; + node->scaler = scaler[0]; + return ftc_scaler_lookup_size( manager, scaler, &node->size ); + } - /* we must begin by removing all sizes for the target face */ - /* from the manager's list */ - FT_LruList_Remove_Selection( manager->sizes_list, - (FT_LruNode_SelectFunc)ftc_size_node_select, - face ); - /* all right, we can discard the face now */ - FT_Done_Face( face ); - node->face = NULL; + FT_CALLBACK_DEF( FT_Error ) + ftc_size_node_reset( FTC_SizeNode node, + FTC_Scaler scaler, + FTC_Manager manager ) + { + FT_Done_Size( node->size ); + + node->scaler = scaler[0]; + + return ftc_scaler_lookup_size( manager, scaler, &node->size ); } FT_CALLBACK_TABLE_DEF - const FT_LruList_ClassRec ftc_face_list_class = + const FTC_MruListClassRec ftc_size_list_class = { - sizeof ( FT_LruListRec ), - (FT_LruList_InitFunc)0, - (FT_LruList_DoneFunc)0, - - sizeof ( FTC_FaceNodeRec ), - (FT_LruNode_InitFunc) ftc_face_node_init, - (FT_LruNode_DoneFunc) ftc_face_node_done, - (FT_LruNode_FlushFunc) 0, /* no flushing needed */ - (FT_LruNode_CompareFunc)0, /* direct comparison of FTC_FaceID handles */ + sizeof( FTC_SizeNodeRec ), + (FTC_MruNode_CompareFunc)ftc_size_node_compare, + (FTC_MruNode_InitFunc) ftc_size_node_init, + (FTC_MruNode_ResetFunc) ftc_size_node_reset, + (FTC_MruNode_DoneFunc) ftc_size_node_done }; - /* documentation is in ftcache.h */ + /* helper function used by ftc_face_node_done */ + static FT_Bool + ftc_size_node_compare_faceid( FTC_SizeNode node, + FTC_FaceID face_id ) + { + return FT_BOOL( node->scaler.face_id == face_id ); + } + FT_EXPORT_DEF( FT_Error ) - FTC_Manager_Lookup_Face( FTC_Manager manager, - FTC_FaceID face_id, - FT_Face *aface ) + FTC_Manager_LookupSize( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ) { FT_Error error; - FTC_FaceNode node; + FTC_SizeNode node; - if ( aface == NULL ) + if ( asize == NULL ) return FTC_Err_Bad_Argument; - *aface = NULL; + *asize = NULL; if ( !manager ) return FTC_Err_Invalid_Cache_Handle; - error = FT_LruList_Lookup( manager->faces_list, - (FT_LruKey)face_id, - (FT_LruNode*)&node ); +#ifdef FTC_INLINE + + FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare, + node, error ); + +#else + error = FTC_MruList_Lookup( &manager->sizes, scaler, (FTC_MruNode*)&node ); +#endif + if ( !error ) - *aface = node->face; + *asize = node->size; return error; } @@ -159,280 +185,119 @@ /*************************************************************************/ /*************************************************************************/ /***** *****/ - /***** SIZES LRU IMPLEMENTATION *****/ + /***** FACE MRU IMPLEMENTATION *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ - - typedef struct FTC_SizeQueryRec_ + typedef struct FTC_FaceNodeRec_ { - FT_Face face; - FT_UInt width; - FT_UInt height; + FTC_MruNodeRec node; + FTC_FaceID face_id; + FT_Face face; - } FTC_SizeQueryRec, *FTC_SizeQuery; + } FTC_FaceNodeRec, *FTC_FaceNode; FT_CALLBACK_DEF( FT_Error ) - ftc_size_node_init( FTC_SizeNode node, - FTC_SizeQuery query ) + ftc_face_node_init( FTC_FaceNode node, + FTC_FaceID face_id, + FTC_Manager manager ) { - FT_Face face = query->face; - FT_Size size; FT_Error error; - node->size = NULL; - error = FT_New_Size( face, &size ); + node->face_id = face_id; + + error = manager->request_face( face_id, + manager->library, + manager->request_data, + &node->face ); if ( !error ) { - FT_Activate_Size( size ); - error = FT_Set_Pixel_Sizes( query->face, - query->width, - query->height ); - if ( error ) - FT_Done_Size( size ); - else - node->size = size; + /* destroy initial size object; it will be re-created later */ + if ( node->face->size ) + FT_Done_Size( node->face->size ); } + return error; } FT_CALLBACK_DEF( void ) - ftc_size_node_done( FTC_SizeNode node ) - { - if ( node->size ) - { - FT_Done_Size( node->size ); - node->size = NULL; - } - } - - - FT_CALLBACK_DEF( FT_Error ) - ftc_size_node_flush( FTC_SizeNode node, - FTC_SizeQuery query ) + ftc_face_node_done( FTC_FaceNode node, + FTC_Manager manager ) { - FT_Size size = node->size; - FT_Error error; + /* we must begin by removing all scalers for the target face */ + /* from the manager's list */ + FTC_MruList_RemoveSelection( + & manager->sizes, + (FTC_MruNode_CompareFunc)ftc_size_node_compare_faceid, + node->face_id ); - - if ( size->face == query->face ) - { - FT_Activate_Size( size ); - error = FT_Set_Pixel_Sizes( query->face, query->width, query->height ); - if ( error ) - { - FT_Done_Size( size ); - node->size = NULL; - } - } - else - { - FT_Done_Size( size ); - node->size = NULL; - - error = ftc_size_node_init( node, query ); - } - return error; + /* all right, we can discard the face now */ + FT_Done_Face( node->face ); + node->face = NULL; + node->face_id = NULL; } FT_CALLBACK_DEF( FT_Bool ) - ftc_size_node_compare( FTC_SizeNode node, - FTC_SizeQuery query ) + ftc_face_node_compare( FTC_FaceNode node, + FTC_FaceID face_id ) { - FT_Size size = node->size; - - - return FT_BOOL( size->face == query->face && - (FT_UInt)size->metrics.x_ppem == query->width && - (FT_UInt)size->metrics.y_ppem == query->height ); + return FT_BOOL( node->face_id == face_id ); } FT_CALLBACK_TABLE_DEF - const FT_LruList_ClassRec ftc_size_list_class = + const FTC_MruListClassRec ftc_face_list_class = { - sizeof ( FT_LruListRec ), - (FT_LruList_InitFunc)0, - (FT_LruList_DoneFunc)0, - - sizeof ( FTC_SizeNodeRec ), - (FT_LruNode_InitFunc) ftc_size_node_init, - (FT_LruNode_DoneFunc) ftc_size_node_done, - (FT_LruNode_FlushFunc) ftc_size_node_flush, - (FT_LruNode_CompareFunc)ftc_size_node_compare + sizeof( FTC_FaceNodeRec), + + (FTC_MruNode_CompareFunc)ftc_face_node_compare, + (FTC_MruNode_InitFunc) ftc_face_node_init, + (FTC_MruNode_ResetFunc) NULL, + (FTC_MruNode_DoneFunc) ftc_face_node_done }; /* documentation is in ftcache.h */ FT_EXPORT_DEF( FT_Error ) - FTC_Manager_Lookup_Size( FTC_Manager manager, - FTC_Font font, - FT_Face *aface, - FT_Size *asize ) - { - FT_Error error; - - - /* check for valid `manager' delayed to FTC_Manager_Lookup_Face() */ - if ( aface ) - *aface = 0; - - if ( asize ) - *asize = 0; - - error = FTC_Manager_Lookup_Face( manager, font->face_id, aface ); - if ( !error ) - { - FTC_SizeQueryRec query; - FTC_SizeNode node; - - - query.face = *aface; - query.width = font->pix_width; - query.height = font->pix_height; - - error = FT_LruList_Lookup( manager->sizes_list, - (FT_LruKey)&query, - (FT_LruNode*)&node ); - if ( !error ) - { - /* select the size as the current one for this face */ - FT_Activate_Size( node->size ); - - if ( asize ) - *asize = node->size; - } - } - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SET TABLE MANAGEMENT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - ftc_family_table_init( FTC_FamilyTable table ) - { - table->count = 0; - table->size = 0; - table->entries = NULL; - table->free = FTC_FAMILY_ENTRY_NONE; - } - - - static void - ftc_family_table_done( FTC_FamilyTable table, - FT_Memory memory ) - { - FT_FREE( table->entries ); - table->free = 0; - table->count = 0; - table->size = 0; - } - - - FT_EXPORT_DEF( FT_Error ) - ftc_family_table_alloc( FTC_FamilyTable table, - FT_Memory memory, - FTC_FamilyEntry *aentry ) + FTC_Manager_LookupFace( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ) { - FTC_FamilyEntry entry; - FT_Error error = 0; - - - /* re-allocate table size when needed */ - if ( table->free == FTC_FAMILY_ENTRY_NONE && table->count >= table->size ) - { - FT_UInt old_size = table->size; - FT_UInt new_size, idx; - - - if ( old_size == 0 ) - new_size = 8; - else - { - new_size = old_size * 2; + FT_Error error; + FTC_FaceNode node; - /* check for (unlikely) overflow */ - if ( new_size < old_size ) - new_size = 65534; - } - if ( FT_RENEW_ARRAY( table->entries, old_size, new_size ) ) - return error; + if ( aface == NULL ) + return FTC_Err_Bad_Argument; - table->size = new_size; + *aface = NULL; - entry = table->entries + old_size; - table->free = old_size; + if ( !manager ) + return FTC_Err_Invalid_Cache_Handle; - for ( idx = old_size; idx + 1 < new_size; idx++, entry++ ) - { - entry->link = idx + 1; - entry->index = idx; - } + /* we break encapsulation for the sake of speed */ +#ifdef FTC_INLINE - entry->link = FTC_FAMILY_ENTRY_NONE; - entry->index = idx; - } + FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare, + node, error ); - if ( table->free != FTC_FAMILY_ENTRY_NONE ) - { - entry = table->entries + table->free; - table->free = entry->link; - } - else if ( table->count < table->size ) - { - entry = table->entries + table->count++; - } - else - { - FT_ERROR(( "ftc_family_table_alloc: internal bug!" )); - return FTC_Err_Invalid_Argument; - } +#else + error = FTC_MruList_Lookup( &manager->faces, face_id, (FTC_MruNode*)&node ); +#endif - entry->link = FTC_FAMILY_ENTRY_NONE; - table->count++; + if ( !error ) + *aface = node->face; - *aentry = entry; return error; } - FT_EXPORT_DEF( void ) - ftc_family_table_free( FTC_FamilyTable table, - FT_UInt idx ) - { - /* simply add it to the linked list of free entries */ - if ( idx < table->count ) - { - FTC_FamilyEntry entry = table->entries + idx; - - - if ( entry->link != FTC_FAMILY_ENTRY_NONE ) - FT_ERROR(( "ftc_family_table_free: internal bug!\n" )); - else - { - entry->link = table->free; - table->free = entry->index; - table->count--; - } - } - } - - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -475,41 +340,28 @@ if ( max_bytes == 0 ) max_bytes = FTC_MAX_BYTES_DEFAULT; - error = FT_LruList_New( &ftc_face_list_class, - max_faces, - manager, - memory, - &manager->faces_list ); - if ( error ) - goto Exit; - - error = FT_LruList_New( &ftc_size_list_class, - max_sizes, - manager, - memory, - &manager->sizes_list ); - if ( error ) - goto Exit; - manager->library = library; + manager->memory = memory; manager->max_weight = max_bytes; - manager->cur_weight = 0; manager->request_face = requester; manager->request_data = req_data; - ftc_family_table_init( &manager->families ); + FTC_MruList_Init( &manager->faces, + &ftc_face_list_class, + max_faces, + manager, + memory ); + + FTC_MruList_Init( &manager->sizes, + &ftc_size_list_class, + max_sizes, + manager, + memory ); *amanager = manager; Exit: - if ( error && manager ) - { - FT_LruList_Destroy( manager->faces_list ); - FT_LruList_Destroy( manager->sizes_list ); - FT_FREE( manager ); - } - return error; } @@ -526,31 +378,29 @@ if ( !manager || !manager->library ) return; - memory = manager->library->memory; + memory = manager->memory; /* now discard all caches */ - for (idx = 0; idx < FTC_MAX_CACHES; idx++ ) + for (idx = manager->num_caches; idx-- > 0; ) { FTC_Cache cache = manager->caches[idx]; if ( cache ) { - cache->clazz->cache_done( cache ); + cache->clazz.cache_done( cache ); FT_FREE( cache ); - manager->caches[idx] = 0; + manager->caches[idx] = NULL; } } - - /* discard families table */ - ftc_family_table_done( &manager->families, memory ); + manager->num_caches = 0; /* discard faces and sizes */ - FT_LruList_Destroy( manager->faces_list ); - manager->faces_list = 0; + FTC_MruList_Done( &manager->sizes ); + FTC_MruList_Done( &manager->faces ); - FT_LruList_Destroy( manager->sizes_list ); - manager->sizes_list = 0; + manager->library = NULL; + manager->memory = NULL; FT_FREE( manager ); } @@ -563,8 +413,8 @@ { if ( manager ) { - FT_LruList_Reset( manager->sizes_list ); - FT_LruList_Reset( manager->faces_list ); + FTC_MruList_Reset( &manager->sizes ); + FTC_MruList_Reset( &manager->faces ); } /* XXX: FIXME: flush the caches? */ } @@ -576,7 +426,7 @@ FTC_Manager_Check( FTC_Manager manager ) { FTC_Node node, first; - + first = manager->nodes_list; @@ -584,26 +434,22 @@ if ( first ) { FT_ULong weight = 0; - + node = first; do { - FTC_FamilyEntry entry = manager->families.entries + node->fam_index; - FTC_Cache cache; + FTC_Cache cache = manager->caches[node->cache_index]; - if ( (FT_UInt)node->fam_index >= manager->families.count || - entry->link != FTC_FAMILY_ENTRY_NONE ) - FT_ERROR(( "FTC_Manager_Check: invalid node (family index = %ld\n", - node->fam_index )); + + if ( (FT_UInt)node->cache_index >= manager->num_caches ) + FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n", + node->cache_index )); else - { - cache = entry->cache; - weight += cache->clazz->node_weight( node, cache ); - } + weight += cache->clazz.node_weight( node, cache ); - node = node->mru_next; + node = FTC_NODE__NEXT( node ); } while ( node != first ); @@ -622,7 +468,7 @@ do { count++; - node = node->mru_next; + node = FTC_NODE__NEXT( node ); } while ( node != first ); @@ -664,14 +510,14 @@ if ( manager->cur_weight < manager->max_weight || first == NULL ) return; - /* go to last node - it's a circular list */ - node = first->mru_prev; + /* go to last node -- it's a circular list */ + node = FTC_NODE__PREV( first ); do { - FTC_Node prev = node->mru_prev; + FTC_Node prev; - prev = ( node == first ) ? NULL : node->mru_prev; + prev = ( node == first ) ? NULL : FTC_NODE__PREV( node ); if ( node->ref_count <= 0 ) ftc_node_destroy( node, manager ); @@ -685,9 +531,9 @@ /* documentation is in ftcmanag.h */ FT_EXPORT_DEF( FT_Error ) - FTC_Manager_Register_Cache( FTC_Manager manager, - FTC_Cache_Class clazz, - FTC_Cache *acache ) + FTC_Manager_RegisterCache( FTC_Manager manager, + FTC_CacheClass clazz, + FTC_Cache *acache ) { FT_Error error = FTC_Err_Invalid_Argument; FTC_Cache cache = NULL; @@ -695,50 +541,37 @@ if ( manager && clazz && acache ) { - FT_Memory memory = manager->library->memory; - FT_UInt idx = 0; - + FT_Memory memory = manager->memory; - /* check for an empty cache slot in the manager's table */ - for ( idx = 0; idx < FTC_MAX_CACHES; idx++ ) - { - if ( manager->caches[idx] == 0 ) - break; - } - /* return an error if there are too many registered caches */ - if ( idx >= FTC_MAX_CACHES ) + if ( manager->num_caches >= FTC_MAX_CACHES ) { error = FTC_Err_Too_Many_Caches; - FT_ERROR(( "FTC_Manager_Register_Cache:" )); - FT_ERROR(( " too many registered caches\n" )); + FT_ERROR(( "%s: too many registered caches\n", + "FTC_Manager_Register_Cache" )); goto Exit; } if ( !FT_ALLOC( cache, clazz->cache_size ) ) { - cache->manager = manager; - cache->memory = memory; - cache->clazz = clazz; + cache->manager = manager; + cache->memory = memory; + cache->clazz = clazz[0]; + cache->org_class = clazz; /* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */ /* IF IT IS NOT SET CORRECTLY */ - cache->cache_index = idx; + cache->index = manager->num_caches; - if ( clazz->cache_init ) + error = clazz->cache_init( cache ); + if ( error ) { - error = clazz->cache_init( cache ); - if ( error ) - { - if ( clazz->cache_done ) - clazz->cache_done( cache ); - - FT_FREE( cache ); - goto Exit; - } + clazz->cache_done( cache ); + FT_FREE( cache ); + goto Exit; } - manager->caches[idx] = cache; + manager->caches[manager->num_caches++] = cache; } } @@ -748,17 +581,66 @@ } + FT_EXPORT_DEF( FT_UInt ) + FTC_Manager_FlushN( FTC_Manager manager, + FT_UInt count ) + { + FTC_Node first = manager->nodes_list; + FTC_Node node; + FT_UInt result; + + + /* try to remove `count' nodes from the list */ + if ( first == NULL ) /* empty list! */ + return 0; + + /* go to last node - it's a circular list */ + node = FTC_NODE__PREV(first); + for ( result = 0; result < count; ) + { + FTC_Node prev = FTC_NODE__PREV( node ); + + + /* don't touch locked nodes */ + if ( node->ref_count <= 0 ) + { + ftc_node_destroy( node, manager ); + result++; + } + + if ( prev == manager->nodes_list ) + break; + + node = prev; + } + return result; + } + + + FT_EXPORT_DEF( void ) + FTC_Manager_RemoveFaceID( FTC_Manager manager, + FTC_FaceID face_id ) + { + FT_UInt nn; + + /* this will remove all FTC_SizeNode that correspond to + * the face_id as well + */ + FTC_MruList_RemoveSelection( &manager->faces, NULL, face_id ); + + for ( nn = 0; nn < manager->num_caches; nn++ ) + FTC_Cache_RemoveFaceID( manager->caches[nn], face_id ); + } + + /* documentation is in ftcmanag.h */ FT_EXPORT_DEF( void ) FTC_Node_Unref( FTC_Node node, FTC_Manager manager ) { - if ( node && (FT_UInt)node->fam_index < manager->families.count && - manager->families.entries[node->fam_index].cache ) - { + if ( node && (FT_UInt)node->cache_index < manager->num_caches ) node->ref_count--; - } } Index: xc/extras/freetype2/src/cache/ftcmru.c =================================================================== RCS file: xc/extras/freetype2/src/cache/ftcmru.c diff -N xc/extras/freetype2/src/cache/ftcmru.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/cache/ftcmru.c 28 Apr 2004 10:25:39 -0000 @@ -0,0 +1,355 @@ +/***************************************************************************/ +/* */ +/* ftcmru.c */ +/* */ +/* FreeType MRU support (body). */ +/* */ +/* Copyright 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include +#include FT_CACHE_H +#include FT_CACHE_INTERNAL_MRU_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +#include "ftcerror.h" + + + FT_EXPORT_DEF( void ) + FTC_MruNode_Prepend( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + + + if ( first ) + { + FTC_MruNode last = first->prev; + + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + + + do + { + if ( cnode == node ) + { + fprintf( stderr, "FTC_MruNode_Prepend: invalid action!\n" ); + exit( 2 ); + } + cnode = cnode->next; + + } while ( cnode != first ); + } +#endif + + first->prev = node; + last->next = node; + node->next = first; + node->prev = last; + } + else + { + node->next = node; + node->prev = node; + } + *plist = node; + } + + + FT_EXPORT_DEF( void ) + FTC_MruNode_Up( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + + + FT_ASSERT( first != NULL ); + + if ( first != node ) + { + FTC_MruNode prev, next, last; + + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + do + { + if ( cnode == node ) + goto Ok; + cnode = cnode->next; + + } while ( cnode != first ); + + fprintf( stderr, "FTC_MruNode_Up: invalid action!\n" ); + exit( 2 ); + Ok: + } +#endif + prev = node->prev; + next = node->next; + + prev->next = next; + next->prev = prev; + + last = first->prev; + + last->next = node; + first->prev = node; + + node->next = first; + node->prev = last; + + *plist = node; + } + } + + + FT_EXPORT_DEF( void ) + FTC_MruNode_Remove( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + FTC_MruNode prev, next; + + + FT_ASSERT( first != NULL ); + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + + + do + { + if ( cnode == node ) + goto Ok; + cnode = cnode->next; + + } while ( cnode != first ); + + fprintf( stderr, "FTC_MruNode_Remove: invalid action!\n" ); + exit( 2 ); + Ok: + } +#endif + + prev = node->prev; + next = node->next; + + prev->next = next; + next->prev = prev; + + if ( node == next ) + { + FT_ASSERT( first == node ); + FT_ASSERT( prev == node ); + + *plist = NULL; + } + else if ( node == first ) + *plist = next; + } + + + FT_EXPORT_DEF( void ) + FTC_MruList_Init( FTC_MruList list, + FTC_MruListClass clazz, + FT_UInt max_nodes, + FT_Pointer data, + FT_Memory memory ) + { + list->num_nodes = 0; + list->max_nodes = max_nodes; + list->nodes = NULL; + list->clazz = *clazz; + list->data = data; + list->memory = memory; + } + + + FT_EXPORT( void ) + FTC_MruList_Reset( FTC_MruList list ) + { + while ( list->nodes ) + FTC_MruList_Remove( list, list->nodes ); + + FT_ASSERT( list->num_nodes == 0 ); + } + + + FT_EXPORT( void ) + FTC_MruList_Done( FTC_MruList list ) + { + FTC_MruList_Reset( list ); + } + + + FT_EXPORT_DEF( FTC_MruNode ) + FTC_MruList_Find( FTC_MruList list, + FT_Pointer key ) + { + FTC_MruNode_CompareFunc compare = list->clazz.node_compare; + FTC_MruNode first, node; + + + first = list->nodes; + node = NULL; + + if ( first ) + { + node = first; + do + { + if ( compare( node, key ) ) + { + if ( node != first ) + FTC_MruNode_Up( &list->nodes, node ); + + return node; + } + + node = node->next; + + } while ( node != first); + } + + return NULL; + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_MruList_New( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *anode ) + { + FT_Error error; + FTC_MruNode node; + FT_Memory memory = list->memory; + + + if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 ) + { + node = list->nodes->prev; + + FT_ASSERT( node ); + + if ( list->clazz.node_reset ) + { + FTC_MruNode_Up( &list->nodes, node ); + + error = list->clazz.node_reset( node, key, list->data ); + if ( !error ) + goto Exit; + } + + FTC_MruNode_Remove( &list->nodes, node ); + list->num_nodes--; + + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + } + else if ( FT_ALLOC( node, list->clazz.node_size ) ) + goto Exit; + + error = list->clazz.node_init( node, key, list->data ); + if ( error ) + goto Fail; + + FTC_MruNode_Prepend( &list->nodes, node ); + list->num_nodes++; + + Exit: + *anode = node; + return error; + + Fail: + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + + FT_FREE( node ); + goto Exit; + } + + + FT_EXPORT( FT_Error ) + FTC_MruList_Lookup( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *anode ) + { + FTC_MruNode node; + + + node = FTC_MruList_Find( list, key ); + if ( node == NULL ) + return FTC_MruList_New( list, key, anode ); + + *anode = node; + return 0; + } + + + FT_EXPORT_DEF( void ) + FTC_MruList_Remove( FTC_MruList list, + FTC_MruNode node ) + { + FTC_MruNode_Remove( &list->nodes, node ); + list->num_nodes--; + + { + FT_Memory memory = list->memory; + + + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + + FT_FREE( node ); + } + } + + + FT_EXPORT_DEF( void ) + FTC_MruList_RemoveSelection( FTC_MruList list, + FTC_MruNode_CompareFunc selection, + FT_Pointer key ) + { + FTC_MruNode first, node, next; + + + first = list->nodes; + while ( first && ( selection == NULL || selection( first, key ) ) ) + { + FTC_MruList_Remove( list, first ); + first = list->nodes; + } + + if ( first ) + { + node = first->next; + while ( node != first ) + { + next = node->next; + + if ( selection( node, key ) ) + FTC_MruList_Remove( list, node ); + + node = next; + } + } + } + + +/* END */ Index: xc/extras/freetype2/src/cache/ftcsbits.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cache/ftcsbits.c,v retrieving revision 1.2 diff -u -r1.2 ftcsbits.c --- a/xc/extras/freetype2/src/cache/ftcsbits.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cache/ftcsbits.c 28 Apr 2004 10:25:40 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType sbits manager (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,57 +18,15 @@ #include #include FT_CACHE_H -#include FT_CACHE_SMALL_BITMAPS_H -#include FT_CACHE_INTERNAL_GLYPH_H +#include FT_CACHE_INTERNAL_SBITS_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include FT_ERRORS_H +#include "ftccback.h" #include "ftcerror.h" -#define FTC_SBIT_ITEMS_PER_NODE 16 - - - typedef struct FTC_SBitNodeRec_* FTC_SBitNode; - - typedef struct FTC_SBitNodeRec_ - { - FTC_GlyphNodeRec gnode; - FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE]; - - } FTC_SBitNodeRec; - - -#define FTC_SBIT_NODE( x ) ( (FTC_SBitNode)( x ) ) - - - typedef struct FTC_SBitQueryRec_ - { - FTC_GlyphQueryRec gquery; - FTC_ImageTypeRec type; - - } FTC_SBitQueryRec, *FTC_SBitQuery; - - -#define FTC_SBIT_QUERY( x ) ( (FTC_SBitQuery)( x ) ) - - - typedef struct FTC_SBitFamilyRec_* FTC_SBitFamily; - - /* sbit family structure */ - typedef struct FTC_SBitFamilyRec_ - { - FTC_GlyphFamilyRec gfam; - FTC_ImageTypeRec type; - - } FTC_SBitFamilyRec; - - -#define FTC_SBIT_FAMILY( x ) ( (FTC_SBitFamily)( x ) ) -#define FTC_SBIT_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &( x )->cset ) - - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -100,454 +58,275 @@ } - FT_CALLBACK_DEF( void ) - ftc_sbit_node_done( FTC_SBitNode snode, - FTC_Cache cache ) + FT_EXPORT_DEF( void ) + FTC_SNode_Free( FTC_SNode snode, + FTC_Cache cache ) { FTC_SBit sbit = snode->sbits; - FT_UInt count = FTC_GLYPH_NODE( snode )->item_count; + FT_UInt count = snode->count; FT_Memory memory = cache->memory; for ( ; count > 0; sbit++, count-- ) FT_FREE( sbit->buffer ); - ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache ); + FTC_GNode_Done( FTC_GNODE( snode ), cache ); + + FT_FREE( snode ); + } + + + FT_LOCAL_DEF( void ) + ftc_snode_free( FTC_SNode snode, + FTC_Cache cache ) + { + FTC_SNode_Free( snode, cache ); } static FT_Error - ftc_sbit_node_load( FTC_SBitNode snode, - FTC_Manager manager, - FTC_SBitFamily sfam, - FT_UInt gindex, - FT_ULong *asize ) + ftc_snode_load( FTC_SNode snode, + FTC_Manager manager, + FT_UInt gindex, + FT_ULong *asize ) { - FT_Error error; - FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); - FT_Memory memory; - FT_Face face; - FT_Size size; - FTC_SBit sbit; + FT_Error error; + FTC_GNode gnode = FTC_GNODE( snode ); + FTC_Family family = gnode->family; + FT_Memory memory = manager->memory; + FT_Face face; + FTC_SBit sbit; + FTC_SFamilyClass clazz; - if ( gindex < (FT_UInt)gnode->item_start || - gindex >= (FT_UInt)gnode->item_start + gnode->item_count ) + if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count ) { - FT_ERROR(( "ftc_sbit_node_load: invalid glyph index" )); + FT_ERROR(( "ftc_snode_load: invalid glyph index" )); return FTC_Err_Invalid_Argument; } - memory = manager->library->memory; + sbit = snode->sbits + ( gindex - gnode->gindex ); + clazz = (FTC_SFamilyClass)family->clazz; + + sbit->buffer = 0; - sbit = snode->sbits + ( gindex - gnode->item_start ); + error = clazz->family_load_glyph( family, gindex, manager, &face ); + if ( error ) + goto BadGlyph; - error = FTC_Manager_Lookup_Size( manager, &sfam->type.font, - &face, &size ); - if ( !error ) { - /* by default, indicates a `missing' glyph */ - sbit->buffer = 0; + FT_Int temp; + FT_GlyphSlot slot = face->glyph; + FT_Bitmap* bitmap = &slot->bitmap; + FT_Int xadvance, yadvance; - error = FT_Load_Glyph( face, gindex, sfam->type.flags | FT_LOAD_RENDER ); - if ( !error ) - { - FT_Int temp; - FT_GlyphSlot slot = face->glyph; - FT_Bitmap* bitmap = &slot->bitmap; - FT_Int xadvance, yadvance; + if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) + { + FT_ERROR(( "%s: glyph loaded didn't return a bitmap!\n", + "ftc_snode_load" )); + goto BadGlyph; + } - /* check that our values fit into 8-bit containers! */ - /* If this is not the case, our bitmap is too large */ - /* and we will leave it as `missing' with sbit.buffer = 0 */ + /* Check that our values fit into 8-bit containers! */ + /* If this is not the case, our bitmap is too large */ + /* and we will leave it as `missing' with sbit.buffer = 0 */ #define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d ) #define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d ) - /* XXX: FIXME: add support for vertical layouts maybe */ - - /* horizontal advance in pixels */ - xadvance = ( slot->metrics.horiAdvance + 32 ) >> 6; - yadvance = ( slot->metrics.vertAdvance + 32 ) >> 6; - - if ( CHECK_BYTE( bitmap->rows ) && - CHECK_BYTE( bitmap->width ) && - CHECK_CHAR( bitmap->pitch ) && - CHECK_CHAR( slot->bitmap_left ) && - CHECK_CHAR( slot->bitmap_top ) && - CHECK_CHAR( xadvance ) && - CHECK_CHAR( yadvance ) ) - { - sbit->width = (FT_Byte)bitmap->width; - sbit->height = (FT_Byte)bitmap->rows; - sbit->pitch = (FT_Char)bitmap->pitch; - sbit->left = (FT_Char)slot->bitmap_left; - sbit->top = (FT_Char)slot->bitmap_top; - sbit->xadvance = (FT_Char)xadvance; - sbit->yadvance = (FT_Char)yadvance; - sbit->format = (FT_Byte)bitmap->pixel_mode; - sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); - -#if 0 /* this doesn't work well with embedded bitmaps */ - - /* grab the bitmap when possible - this is a hack! */ - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) - { - slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; - sbit->buffer = bitmap->buffer; - } - else -#endif - { - /* copy the bitmap into a new buffer -- ignore error */ - error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); - } - - /* now, compute size */ - if ( asize ) - *asize = ABS( sbit->pitch ) * sbit->height; - - } /* glyph dimensions ok */ - - } /* glyph loading successful */ - - /* ignore the errors that might have occurred -- */ - /* we mark unloaded glyphs with `sbit.buffer == 0' */ - /* and 'width == 255', 'height == 0' */ - /* */ - if ( error && error != FTC_Err_Out_Of_Memory ) - { - sbit->width = 255; - error = 0; - /* sbit->buffer == NULL too! */ - } + /* horizontal advance in pixels */ + xadvance = ( slot->metrics.horiAdvance + 32 ) >> 6; + yadvance = ( slot->metrics.vertAdvance + 32 ) >> 6; + + if ( !CHECK_BYTE( bitmap->rows ) || + !CHECK_BYTE( bitmap->width ) || + !CHECK_CHAR( bitmap->pitch ) || + !CHECK_CHAR( slot->bitmap_left ) || + !CHECK_CHAR( slot->bitmap_top ) || + !CHECK_CHAR( xadvance ) || + !CHECK_CHAR( yadvance ) ) + goto BadGlyph; + + sbit->width = (FT_Byte)bitmap->width; + sbit->height = (FT_Byte)bitmap->rows; + sbit->pitch = (FT_Char)bitmap->pitch; + sbit->left = (FT_Char)slot->bitmap_left; + sbit->top = (FT_Char)slot->bitmap_top; + sbit->xadvance = (FT_Char)xadvance; + sbit->yadvance = (FT_Char)yadvance; + sbit->format = (FT_Byte)bitmap->pixel_mode; + sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); + + /* copy the bitmap into a new buffer -- ignore error */ + error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); + + /* now, compute size */ + if ( asize ) + *asize = FT_ABS( sbit->pitch ) * sbit->height; + + } /* glyph loading successful */ + + /* ignore the errors that might have occurred -- */ + /* we mark unloaded glyphs with `sbit.buffer == 0' */ + /* and `width == 255', `height == 0' */ + /* */ + if ( error && error != FTC_Err_Out_Of_Memory ) + { + BadGlyph: + sbit->width = 255; + sbit->height = 0; + sbit->buffer = NULL; + error = 0; + if ( asize ) + *asize = 0; } return error; } - FT_CALLBACK_DEF( FT_Error ) - ftc_sbit_node_init( FTC_SBitNode snode, - FTC_GlyphQuery gquery, - FTC_Cache cache ) - { - FT_Error error; - - - ftc_glyph_node_init( FTC_GLYPH_NODE( snode ), - gquery->gindex, - FTC_GLYPH_FAMILY( gquery->query.family ) ); - - error = ftc_sbit_node_load( snode, - cache->manager, - FTC_SBIT_FAMILY( FTC_QUERY( gquery )->family ), - gquery->gindex, - NULL ); - if ( error ) - ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache ); - - return error; - } - - - FT_CALLBACK_DEF( FT_ULong ) - ftc_sbit_node_weight( FTC_SBitNode snode ) - { - FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); - FT_UInt count = gnode->item_count; - FTC_SBit sbit = snode->sbits; - FT_Int pitch; - FT_ULong size; - + FT_EXPORT_DEF( FT_Error ) + FTC_SNode_New( FTC_SNode *psnode, + FTC_GQuery gquery, + FTC_Cache cache ) + { + FT_Memory memory = cache->memory; + FT_Error error; + FTC_SNode snode = NULL; + FT_UInt gindex = gquery->gindex; + FTC_Family family = gquery->family; - /* the node itself */ - size = sizeof ( *snode ); + FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache ); + FT_UInt total; - /* the sbit records */ - size += FTC_GLYPH_NODE( snode )->item_count * sizeof ( FTC_SBitRec ); - for ( ; count > 0; count--, sbit++ ) + total = clazz->family_get_count( family, cache->manager ); + if ( total == 0 || gindex >= total ) { - if ( sbit->buffer ) - { - pitch = sbit->pitch; - if ( pitch < 0 ) - pitch = -pitch; - - /* add the size of a given glyph image */ - size += pitch * sbit->height; - } + error = FT_Err_Invalid_Argument; + goto Exit; } - return size; - } - + if ( !FT_NEW( snode ) ) + { + FT_UInt count, start; - FT_CALLBACK_DEF( FT_Bool ) - ftc_sbit_node_compare( FTC_SBitNode snode, - FTC_SBitQuery squery, - FTC_Cache cache ) - { - FTC_GlyphQuery gquery = FTC_GLYPH_QUERY( squery ); - FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); - FT_Bool result; + start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE ); + count = total - start; + if ( count > FTC_SBIT_ITEMS_PER_NODE ) + count = FTC_SBIT_ITEMS_PER_NODE; - result = ftc_glyph_node_compare( gnode, gquery ); - if ( result ) - { - /* check if we need to load the glyph bitmap now */ - FT_UInt gindex = gquery->gindex; - FTC_SBit sbit = snode->sbits + ( gindex - gnode->item_start ); + FTC_GNode_Init( FTC_GNODE( snode ), start, family ); + snode->count = count; - if ( sbit->buffer == NULL && sbit->width != 255 ) + error = ftc_snode_load( snode, + cache->manager, + gindex, + NULL ); + if ( error ) { - FT_ULong size; - - - if ( !ftc_sbit_node_load( - snode, cache->manager, - FTC_SBIT_FAMILY( FTC_QUERY( squery )->family ), - gindex, &size ) ) - cache->manager->cur_weight += size; + FTC_SNode_Free( snode, cache ); + snode = NULL; } } - return result; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SBITS FAMILIES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_DEF( FT_Error ) - ftc_sbit_family_init( FTC_SBitFamily sfam, - FTC_SBitQuery squery, - FTC_Cache cache ) - { - FTC_Manager manager = cache->manager; - FT_Error error; - FT_Face face; - - - sfam->type = squery->type; - - /* we need to compute "cquery.item_total" now */ - error = FTC_Manager_Lookup_Face( manager, - squery->type.font.face_id, - &face ); - if ( !error ) - { - error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( sfam ), - FTC_IMAGE_TYPE_HASH( &sfam->type ), - FTC_SBIT_ITEMS_PER_NODE, - face->num_glyphs, - FTC_GLYPH_QUERY( squery ), - cache ); - } - + Exit: + *psnode = snode; return error; } - FT_CALLBACK_DEF( FT_Bool ) - ftc_sbit_family_compare( FTC_SBitFamily sfam, - FTC_SBitQuery squery ) + FT_LOCAL_DEF( FT_Error ) + ftc_snode_new( FTC_SNode *psnode, + FTC_GQuery gquery, + FTC_Cache cache ) { - FT_Bool result; - - - /* we need to set the "cquery.cset" field or our query for */ - /* faster glyph comparisons in ftc_sbit_node_compare */ - /* */ - result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &sfam->type, &squery->type ) ); - if ( result ) - FTC_GLYPH_FAMILY_FOUND( sfam, squery ); - - return result; + return FTC_SNode_New( psnode, gquery, cache ); } - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SBITS CACHE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_TABLE_DEF - const FTC_Cache_ClassRec ftc_sbit_cache_class = - { - sizeof ( FTC_CacheRec ), - (FTC_Cache_InitFunc) ftc_cache_init, - (FTC_Cache_ClearFunc)ftc_cache_clear, - (FTC_Cache_DoneFunc) ftc_cache_done, - - sizeof ( FTC_SBitFamilyRec ), - (FTC_Family_InitFunc) ftc_sbit_family_init, - (FTC_Family_CompareFunc)ftc_sbit_family_compare, - (FTC_Family_DoneFunc) ftc_glyph_family_done, - - sizeof ( FTC_SBitNodeRec ), - (FTC_Node_InitFunc) ftc_sbit_node_init, - (FTC_Node_WeightFunc) ftc_sbit_node_weight, - (FTC_Node_CompareFunc)ftc_sbit_node_compare, - (FTC_Node_DoneFunc) ftc_sbit_node_done - }; - - - /* documentation is in ftcsbits.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_SBitCache_New( FTC_Manager manager, - FTC_SBitCache *acache ) - { - return FTC_Manager_Register_Cache( manager, - &ftc_sbit_cache_class, - (FTC_Cache*)acache ); - } - - - /* documentation is in ftcsbits.h */ - -#ifdef FTC_CACHE_USE_INLINE - -#define GEN_CACHE_FAMILY_COMPARE( f, q, c ) \ - ftc_sbit_family_compare( (FTC_SBitFamily)(f), (FTC_SBitQuery)(q) ) - -#define GEN_CACHE_NODE_COMPARE( n, q, c ) \ - ftc_sbit_node_compare( (FTC_SBitNode)(n), (FTC_SBitQuery)(q), c ) - -#define GEN_CACHE_LOOKUP ftc_sbit_cache_lookup -#include "ftccache.i" - -#else /* !FTC_CACHE_USE_INLINE */ - -#define ftc_sbit_cache_lookup ftc_cache_lookup - -#endif /* !FTC_CACHE_USE_INLINE */ - - FT_EXPORT_DEF( FT_Error ) - FTC_SBitCache_Lookup( FTC_SBitCache cache, - FTC_ImageType type, - FT_UInt gindex, - FTC_SBit *ansbit, - FTC_Node *anode ) + FT_EXPORT_DEF( FT_ULong ) + FTC_SNode_Weight( FTC_SNode snode ) { - FT_Error error; - FTC_SBitQueryRec squery; - FTC_SBitNode node; - + FT_UInt count = snode->count; + FTC_SBit sbit = snode->sbits; + FT_Int pitch; + FT_ULong size; - /* other argument checks delayed to ftc_cache_lookup */ - if ( !ansbit ) - return FTC_Err_Invalid_Argument; - - *ansbit = NULL; - if ( anode ) - *anode = NULL; + FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE ); - squery.gquery.gindex = gindex; - squery.type = *type; + /* the node itself */ + size = sizeof ( *snode ); - error = ftc_sbit_cache_lookup( FTC_CACHE( cache ), - FTC_QUERY( &squery ), - (FTC_Node*)&node ); - if ( !error ) + for ( ; count > 0; count--, sbit++ ) { - *ansbit = node->sbits + ( gindex - FTC_GLYPH_NODE( node )->item_start ); - - if ( anode ) + if ( sbit->buffer ) { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; + pitch = sbit->pitch; + if ( pitch < 0 ) + pitch = -pitch; + + /* add the size of a given glyph image */ + size += pitch * sbit->height; } } - return error; - } + return size; + } - /* backwards-compatibility functions */ - FT_EXPORT_DEF( FT_Error ) - FTC_SBit_Cache_New( FTC_Manager manager, - FTC_SBit_Cache *acache ) + FT_LOCAL_DEF( FT_ULong ) + ftc_snode_weight( FTC_SNode snode ) { - return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache ); + return FTC_SNode_Weight( snode ); } - FT_EXPORT_DEF( FT_Error ) - FTC_SBit_Cache_Lookup( FTC_SBit_Cache cache, - FTC_Image_Desc* desc, - FT_UInt gindex, - FTC_SBit *ansbit ) + FT_EXPORT_DEF( FT_Bool ) + FTC_SNode_Compare( FTC_SNode snode, + FTC_GQuery gquery, + FTC_Cache cache ) { - FTC_ImageTypeRec type0; - + FTC_GNode gnode = FTC_GNODE( snode ); + FT_UInt gindex = gquery->gindex; + FT_Bool result; - if ( !desc ) - return FTC_Err_Invalid_Argument; - type0.font = desc->font; - type0.flags = 0; - - /* convert image type flags to load flags */ + result = FT_BOOL( gnode->family == gquery->family && + (FT_UInt)( gindex - gnode->gindex ) < snode->count ); + if ( result ) { - FT_UInt load_flags = FT_LOAD_DEFAULT; - FT_UInt type = desc->image_type; - + /* check if we need to load the glyph bitmap now */ + FTC_SBit sbit = snode->sbits + ( gindex - gnode->gindex ); - /* determine load flags, depending on the font description's */ - /* image type */ - if ( ftc_image_format( type ) == ftc_image_format_bitmap ) + if ( sbit->buffer == NULL && sbit->width != 255 ) { - if ( type & ftc_image_flag_monochrome ) - load_flags |= FT_LOAD_MONOCHROME; + FT_ULong size; - /* disable embedded bitmaps loading if necessary */ - if ( type & ftc_image_flag_no_sbits ) - load_flags |= FT_LOAD_NO_BITMAP; - } - else - { - /* we want an outline, don't load embedded bitmaps */ - load_flags |= FT_LOAD_NO_BITMAP; - if ( type & ftc_image_flag_unscaled ) - load_flags |= FT_LOAD_NO_SCALE; + if ( !ftc_snode_load( snode, cache->manager, + gindex, &size ) ) + { + cache->manager->cur_weight += size; + } } + } - /* always render glyphs to bitmaps */ - load_flags |= FT_LOAD_RENDER; - - if ( type & ftc_image_flag_unhinted ) - load_flags |= FT_LOAD_NO_HINTING; - - if ( type & ftc_image_flag_autohinted ) - load_flags |= FT_LOAD_FORCE_AUTOHINT; + return result; + } - type0.flags = load_flags; - } - return FTC_SBitCache_Lookup( (FTC_SBitCache)cache, - &type0, - gindex, - ansbit, - NULL ); + FT_LOCAL_DEF( FT_Bool ) + ftc_snode_compare( FTC_SNode snode, + FTC_GQuery gquery, + FTC_Cache cache ) + { + return FTC_SNode_Compare( snode, gquery, cache ); } Index: xc/extras/freetype2/src/cache/ftlru.c =================================================================== RCS file: xc/extras/freetype2/src/cache/ftlru.c diff -N xc/extras/freetype2/src/cache/ftlru.c --- a/xc/extras/freetype2/src/cache/ftlru.c 23 Apr 2004 18:42:49 -0000 1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,390 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftlru.c */ -/* */ -/* Simple LRU list-cache (body). */ -/* */ -/* Copyright 2000-2001, 2002, 2003 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include -#include FT_CACHE_H -#include FT_CACHE_INTERNAL_LRU_H -#include FT_LIST_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H - -#include "ftcerror.h" - - - FT_EXPORT_DEF( FT_Error ) - FT_LruList_New( FT_LruList_Class clazz, - FT_UInt max_nodes, - FT_Pointer user_data, - FT_Memory memory, - FT_LruList *alist ) - { - FT_Error error; - FT_LruList list; - - - if ( !alist || !clazz ) - return FTC_Err_Invalid_Argument; - - *alist = NULL; - if ( !FT_ALLOC( list, clazz->list_size ) ) - { - /* initialize common fields */ - list->clazz = clazz; - list->memory = memory; - list->max_nodes = max_nodes; - list->data = user_data; - - if ( clazz->list_init ) - { - error = clazz->list_init( list ); - if ( error ) - { - if ( clazz->list_done ) - clazz->list_done( list ); - - FT_FREE( list ); - } - } - - *alist = list; - } - - return error; - } - - - FT_EXPORT_DEF( void ) - FT_LruList_Destroy( FT_LruList list ) - { - FT_Memory memory; - FT_LruList_Class clazz; - - - if ( !list ) - return; - - memory = list->memory; - clazz = list->clazz; - - FT_LruList_Reset( list ); - - if ( clazz->list_done ) - clazz->list_done( list ); - - FT_FREE( list ); - } - - - FT_EXPORT_DEF( void ) - FT_LruList_Reset( FT_LruList list ) - { - FT_LruNode node; - FT_LruList_Class clazz; - FT_Memory memory; - - - if ( !list ) - return; - - node = list->nodes; - clazz = list->clazz; - memory = list->memory; - - while ( node ) - { - FT_LruNode next = node->next; - - - if ( clazz->node_done ) - clazz->node_done( node, list->data ); - - FT_FREE( node ); - node = next; - } - - list->nodes = NULL; - list->num_nodes = 0; - } - - - FT_EXPORT_DEF( FT_Error ) - FT_LruList_Lookup( FT_LruList list, - FT_LruKey key, - FT_LruNode *anode ) - { - FT_Error error = 0; - FT_LruNode node, *pnode; - FT_LruList_Class clazz; - FT_LruNode result = NULL; - FT_Memory memory; - - - if ( !list || !key || !anode ) - return FTC_Err_Invalid_Argument; - - pnode = &list->nodes; - node = NULL; - clazz = list->clazz; - memory = list->memory; - - if ( clazz->node_compare ) - { - for (;;) - { - node = *pnode; - if ( node == NULL ) - break; - - if ( clazz->node_compare( node, key, list->data ) ) - break; - - pnode = &(*pnode)->next; - } - } - else - { - for (;;) - { - node = *pnode; - if ( node == NULL ) - break; - - if ( node->key == key ) - break; - - pnode = &(*pnode)->next; - } - } - - if ( node ) - { - /* move element to top of list */ - if ( list->nodes != node ) - { - *pnode = node->next; - node->next = list->nodes; - list->nodes = node; - } - result = node; - goto Exit; - } - - /* Since we haven't found the relevant element in our LRU list, - * we're going to "create" a new one. - * - * The following code is a bit special, because it tries to handle - * out-of-memory conditions (OOM) in an intelligent way. - * - * More precisely, if not enough memory is available to create a - * new node or "flush" an old one, we need to remove the oldest - * elements from our list, and try again. Since several tries may - * be necessary, a loop is needed. - * - * This loop will only exit when: - * - * - a new node was successfully created, or an old node flushed - * - an error other than FTC_Err_Out_Of_Memory is detected - * - the list of nodes is empty, and it isn't possible to create - * new nodes - * - * On each unsuccessful attempt, one node will be removed from the list. - * - */ - - { - FT_Int drop_last = ( list->max_nodes > 0 && - list->num_nodes >= list->max_nodes ); - - for (;;) - { - node = NULL; - - /* If "drop_last" is true, we should free the last node in - * the list to make room for a new one. Note that we reuse - * its memory block to save allocation calls. - */ - if ( drop_last ) - { - /* find the last node in the list - */ - pnode = &list->nodes; - node = *pnode; - - if ( node == NULL ) - { - FT_ASSERT( list->num_nodes == 0 ); - error = FTC_Err_Out_Of_Memory; - goto Exit; - } - - FT_ASSERT( list->num_nodes > 0 ); - - while ( node->next ) - { - pnode = &node->next; - node = *pnode; - } - - /* Remove it from the list, and try to "flush" it. Doing this will - * save a significant number of dynamic allocations compared to - * a classic destroy/create cycle. - */ - *pnode = NULL; - list->num_nodes--; - - if ( clazz->node_flush ) - { - error = clazz->node_flush( node, key, list->data ); - if ( !error ) - goto Success; - - /* Note that if an error occured during the flush, we need to - * finalize it since it is potentially in incomplete state. - */ - } - - /* We finalize, but do not destroy the last node, we - * simply reuse its memory block! - */ - if ( clazz->node_done ) - clazz->node_done( node, list->data ); - - FT_MEM_ZERO( node, clazz->node_size ); - } - else - { - /* Try to allocate a new node when "drop_last" is not TRUE. - * This usually happens on the first pass, when the LRU list - * is not already full. - */ - if ( FT_ALLOC( node, clazz->node_size ) ) - goto Fail; - } - - FT_ASSERT( node != NULL ); - - node->key = key; - error = clazz->node_init( node, key, list->data ); - if ( error ) - { - if ( clazz->node_done ) - clazz->node_done( node, list->data ); - - FT_FREE( node ); - goto Fail; - } - - Success: - result = node; - - node->next = list->nodes; - list->nodes = node; - list->num_nodes++; - goto Exit; - - Fail: - if ( error != FTC_Err_Out_Of_Memory ) - goto Exit; - - drop_last = 1; - continue; - } - } - - Exit: - *anode = result; - return error; - } - - - FT_EXPORT_DEF( void ) - FT_LruList_Remove( FT_LruList list, - FT_LruNode node ) - { - FT_LruNode *pnode; - - - if ( !list || !node ) - return; - - pnode = &list->nodes; - for (;;) - { - if ( *pnode == node ) - { - FT_Memory memory = list->memory; - FT_LruList_Class clazz = list->clazz; - - - *pnode = node->next; - node->next = NULL; - - if ( clazz->node_done ) - clazz->node_done( node, list->data ); - - FT_FREE( node ); - list->num_nodes--; - break; - } - - pnode = &(*pnode)->next; - } - } - - - FT_EXPORT_DEF( void ) - FT_LruList_Remove_Selection( FT_LruList list, - FT_LruNode_SelectFunc select_func, - FT_Pointer select_data ) - { - FT_LruNode *pnode, node; - FT_LruList_Class clazz; - FT_Memory memory; - - - if ( !list || !select_func ) - return; - - memory = list->memory; - clazz = list->clazz; - pnode = &list->nodes; - - for (;;) - { - node = *pnode; - if ( node == NULL ) - break; - - if ( select_func( node, select_data, list->data ) ) - { - *pnode = node->next; - node->next = NULL; - - if ( clazz->node_done ) - clazz->node_done( node, list ); - - FT_FREE( node ); - list->num_nodes--; - } - else - pnode = &(*pnode)->next; - } - } - - -/* END */ Index: xc/extras/freetype2/src/cache/rules.mk =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cache/rules.mk,v retrieving revision 1.2 diff -u -r1.2 rules.mk --- a/xc/extras/freetype2/src/cache/rules.mk 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cache/rules.mk 28 Apr 2004 10:25:40 -0000 @@ -3,7 +3,7 @@ # -# Copyright 2000, 2001, 2003 by +# Copyright 2000, 2001, 2003, 2004 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -25,8 +25,9 @@ # Cache driver sources (i.e., C files) # -CACHE_DRV_SRC := $(CACHE_DIR)/ftlru.c \ +CACHE_DRV_SRC := $(CACHE_DIR)/ftcmru.c \ $(CACHE_DIR)/ftcmanag.c \ + $(CACHE_DIR)/ftcbasic.c \ $(CACHE_DIR)/ftccache.c \ $(CACHE_DIR)/ftcglyph.c \ $(CACHE_DIR)/ftcsbits.c \ @@ -35,11 +36,13 @@ # Cache driver headers # -CACHE_DRV_H := $(CACHE_H_DIR)/ftlru.h \ +CACHE_DRV_H := $(CACHE_H_DIR)/ftcmru.h \ $(CACHE_H_DIR)/ftcmanag.h \ $(CACHE_H_DIR)/ftcglyph.h \ $(CACHE_H_DIR)/ftcimage.h \ - $(CACHE_DIR)/ftcerror.h + $(CACHE_H_DIR)/ftccmap.h \ + $(CACHE_DIR)/ftcerror.h \ + $(CACHE_DIR)/ftccback.h # Cache driver object(s) Index: xc/extras/freetype2/src/cff/Jamfile =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/Jamfile,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 Jamfile --- a/xc/extras/freetype2/src/cff/Jamfile 25 Nov 2003 19:27:19 -0000 1.1.1.2 +++ b/xc/extras/freetype2/src/cff/Jamfile 28 Apr 2004 10:25:40 -0000 @@ -1,4 +1,4 @@ -# FreeType 2 src/cff Jamfile (c) 2001 David Turner +# FreeType 2 src/cff Jamfile (c) 2001, 2002 David Turner # SubDir FT2_TOP $(FT2_SRC_DIR) cff ; Index: xc/extras/freetype2/src/cff/cff.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cff.c,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 cff.c --- a/xc/extras/freetype2/src/cff/cff.c 25 Nov 2003 19:27:19 -0000 1.1.1.2 +++ b/xc/extras/freetype2/src/cff/cff.c 28 Apr 2004 10:25:40 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType OpenType driver component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2002 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ Index: xc/extras/freetype2/src/cff/cffcmap.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cffcmap.c,v retrieving revision 1.2 diff -u -r1.2 cffcmap.c --- a/xc/extras/freetype2/src/cff/cffcmap.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/cffcmap.c 28 Apr 2004 10:25:40 -0000 @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002, 2003 by */ +/* Copyright 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -152,7 +152,7 @@ cmap->num_pairs = 0; cmap->pairs = NULL; - count = (FT_UInt)face->root.num_glyphs; + count = cff->num_glyphs; if ( !FT_NEW_ARRAY( cmap->pairs, count ) ) { @@ -200,7 +200,7 @@ if ( new_count != count && new_count < count / 2 ) { (void)FT_RENEW_ARRAY( cmap->pairs, count, new_count ); - error = 0; + error = CFF_Err_Ok; } /* sort the pairs table to allow efficient binary searches */ Index: xc/extras/freetype2/src/cff/cffdrivr.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cffdrivr.c,v retrieving revision 1.2 diff -u -r1.2 cffdrivr.c --- a/xc/extras/freetype2/src/cff/cffdrivr.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/cffdrivr.c 28 Apr 2004 10:25:41 -0000 @@ -4,7 +4,7 @@ /* */ /* OpenType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,10 +24,12 @@ #include FT_TRUETYPE_IDS_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_TT_CMAP_H #include "cffdrivr.h" #include "cffgload.h" #include "cffload.h" +#include "cffcmap.h" #include "cfferrs.h" @@ -199,7 +201,7 @@ if ( size ) { /* these two object must have the same parent */ - if ( size->face != slot->root.face ) + if ( size->root.face != slot->root.face ) return CFF_Err_Invalid_Face_Handle; } @@ -236,7 +238,7 @@ if ( !psnames ) { FT_ERROR(( "cff_get_glyph_name:" )); - FT_ERROR(( " cannot open CFF & CEF fonts\n" )); + FT_ERROR(( " cannot get glyph name from CFF & CEF fonts\n" )); FT_ERROR(( " " )); FT_ERROR(( " without the `PSNames' module\n" )); error = CFF_Err_Unknown_File_Format; @@ -287,6 +289,9 @@ charset = &cff->charset; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + if ( !psnames ) + return 0; + for ( i = 0; i < cff->num_glyphs; i++ ) { sid = charset->sids[i]; @@ -324,8 +329,7 @@ static FT_Int cff_ps_has_glyph_names( FT_Face face ) { - FT_UNUSED( face ); - return 1; + return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0; } @@ -336,6 +340,51 @@ }; + /* + * TT CMAP INFO + * + * If the charmap is a synthetic Unicode encoding cmap or + * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO + * service defined in SFNT module. + * + * Otherwise call the service function in the sfnt module. + * + */ + static FT_Error + cff_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ) + { + FT_CMap cmap = FT_CMAP( charmap ); + FT_Error error = CFF_Err_Ok; + + + cmap_info->language = 0; + + if ( cmap->clazz != &cff_cmap_encoding_class_rec && + cmap->clazz != &cff_cmap_unicode_class_rec ) + { + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Module sfnt = FT_Get_Module( library, "sfnt" ); + FT_Service_TTCMaps service = + (FT_Service_TTCMaps)ft_module_get_service( sfnt, + FT_SERVICE_ID_TT_CMAP ); + + + if ( service && service->get_cmap_info ) + error = service->get_cmap_info( charmap, cmap_info ); + } + + return error; + } + + + static const FT_Service_TTCMapsRec cff_service_get_cmap_info = + { + (TT_CMap_Info_GetFunc)cff_get_cmap_info + }; + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -355,6 +404,7 @@ #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict }, #endif + { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info }, { NULL, NULL } }; @@ -403,7 +453,7 @@ /* now the specific driver fields */ sizeof( TT_FaceRec ), - sizeof( FT_SizeRec ), + sizeof( CFF_SizeRec ), sizeof( CFF_GlyphSlotRec ), (FT_Face_InitFunc) cff_face_init, Index: xc/extras/freetype2/src/cff/cffgload.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cffgload.c,v retrieving revision 1.2 diff -u -r1.2 cffgload.c --- a/xc/extras/freetype2/src/cff/cffgload.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/cffgload.c 28 Apr 2004 10:25:42 -0000 @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,7 +16,6 @@ /***************************************************************************/ - #include #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_CALC_H @@ -252,15 +251,15 @@ if ( hinting && size ) { - builder->hints_globals = size->internal; + builder->hints_globals = size->root.internal; builder->hints_funcs = glyph->root.internal->glyph_hints; } } if ( size ) { - builder->scale_x = size->metrics.x_scale; - builder->scale_y = size->metrics.y_scale; + builder->scale_x = size->root.metrics.x_scale; + builder->scale_y = size->root.metrics.y_scale; } builder->pos_x = 0; @@ -367,7 +366,7 @@ decoder->num_globals = cff->num_global_subrs; decoder->globals = cff->global_subrs; decoder->globals_bias = cff_compute_bias( decoder->num_globals ); - + decoder->hint_mode = hint_mode; } @@ -399,7 +398,7 @@ } - /* check that there is enough room for `count' more points */ + /* check that there is enough space for `count' more points */ static FT_Error check_points( CFF_Builder* builder, FT_Int count ) @@ -452,7 +451,7 @@ } - /* check room for a new contour, then add it */ + /* check space for a new contour, then add it */ static FT_Error cff_builder_add_contour( CFF_Builder* builder ) { @@ -486,7 +485,7 @@ FT_Pos x, FT_Pos y ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; /* test whether we are building a new contour */ @@ -546,6 +545,10 @@ FT_UShort glyph_sid; + /* CID-keyed fonts don't have glyph names */ + if ( !cff->charset.sids ) + return -1; + /* check range of standard char code */ if ( charcode < 0 || charcode > 255 ) return -1; @@ -641,13 +644,13 @@ FT_Int bchar, FT_Int achar ) { - FT_Error error; - FT_Int bchar_index, achar_index, n_base_points; - FT_Outline* base = decoder->builder.base; - TT_Face face = decoder->builder.face; - FT_Vector left_bearing, advance; - FT_Byte* charstring; - FT_ULong charstring_len; + FT_Error error; + CFF_Builder* builder = &decoder->builder; + FT_Int bchar_index, achar_index; + TT_Face face = decoder->builder.face; + FT_Vector left_bearing, advance; + FT_Byte* charstring; + FT_ULong charstring_len; #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -677,9 +680,9 @@ /* If we are trying to load a composite glyph, do not load the */ /* accent character and return the array of subglyphs. */ - if ( decoder->builder.no_recurse ) + if ( builder->no_recurse ) { - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph; FT_GlyphLoader loader = glyph->internal->loader; FT_SubGlyph subg; @@ -702,8 +705,8 @@ /* subglyph 1 = accent character */ subg->index = achar_index; subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = (FT_Int)adx; - subg->arg2 = (FT_Int)ady; + subg->arg1 = (FT_Int)( adx >> 16 ); + subg->arg2 = (FT_Int)( ady >> 16 ); /* set up remaining glyph fields */ glyph->num_subglyphs = 2; @@ -713,6 +716,8 @@ loader->current.num_subglyphs = 2; } + FT_GlyphLoader_Prepare( builder->loader ); + /* First load `bchar' in builder */ error = cff_get_glyph_data( face, bchar_index, &charstring, &charstring_len ); @@ -727,16 +732,17 @@ cff_free_glyph_data( face, &charstring, charstring_len ); } - n_base_points = base->n_points; - /* Save the left bearing and width of the base character */ /* as they will be erased by the next load. */ - left_bearing = decoder->builder.left_bearing; - advance = decoder->builder.advance; + left_bearing = builder->left_bearing; + advance = builder->advance; + + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; - decoder->builder.left_bearing.x = 0; - decoder->builder.left_bearing.y = 0; + builder->pos_x = adx; + builder->pos_y = ady; /* Now load `achar' on top of the base outline. */ error = cff_get_glyph_data( face, achar_index, @@ -754,20 +760,11 @@ /* Restore the left side bearing and advance width */ /* of the base character. */ - decoder->builder.left_bearing = left_bearing; - decoder->builder.advance = advance; - - /* Finally, move the accent. */ - if ( decoder->builder.load_points ) - { - FT_Outline dummy; + builder->left_bearing = left_bearing; + builder->advance = advance; - - dummy.n_points = (short)( base->n_points - n_base_points ); - dummy.points = base->points + n_base_points; - - FT_Outline_Translate( &dummy, adx, ady ); - } + builder->pos_x = 0; + builder->pos_y = 0; Exit: return error; @@ -904,7 +901,7 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( !( val & 0xFFFFL ) ) - FT_TRACE4(( " %d", (FT_Int32)( val >> 16 ) )); + FT_TRACE4(( " %ld", (FT_Int32)( val >> 16 ) )); else FT_TRACE4(( " %.2f", val / 65536.0 )); #endif @@ -1111,7 +1108,7 @@ /* `glyph_width' to `nominal_width' plus number on the stack */ /* -- for either case. */ - FT_Int set_width_ok; + FT_Int set_width_ok; switch ( op ) @@ -1126,6 +1123,8 @@ case cff_op_hstemhm: case cff_op_vstemhm: case cff_op_rmoveto: + case cff_op_hintmask: + case cff_op_cntrmask: set_width_ok = num_args & 1; break; @@ -1224,7 +1223,7 @@ for ( maskbyte = 0; maskbyte < (FT_UInt)(( decoder->num_hints + 7 ) >> 3); maskbyte++, ip++ ) - FT_TRACE4(( "%02X", *ip )); + FT_TRACE4(( "0x%02X", *ip )); } #else ip += ( decoder->num_hints + 7 ) >> 3; @@ -1650,11 +1649,11 @@ case cff_op_flex1: { - FT_Pos start_x, start_y; /* record start x, y values for alter */ - /* use */ - FT_Int dx = 0, dy = 0; /* used in horizontal/vertical */ - /* algorithm below */ - FT_Int horizontal, count; + FT_Pos start_x, start_y; /* record start x, y values for */ + /* alter use */ + FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ + /* algorithm below */ + FT_Int horizontal, count; FT_TRACE4(( " flex1" )); @@ -1676,8 +1675,8 @@ /* grab up to the last argument */ for ( count = 5; count > 0; count-- ) { - dx += (FT_Int)args[0]; - dy += (FT_Int)args[1]; + dx += args[0]; + dy += args[1]; args += 2; } @@ -1733,7 +1732,7 @@ x += args[0]; y += args[1]; cff_builder_add_point( builder, x, y, - (FT_Bool)( count == 3 || count == 0 ) ); + (FT_Bool)( count == 4 || count == 1 ) ); args += 2; } @@ -1747,35 +1746,43 @@ /* We are going to emulate the seac operator. */ if ( num_args == 4 ) { + /* Save glyph width so that the subglyphs don't overwrite it. */ + FT_Pos glyph_width = decoder->glyph_width; + + error = cff_operator_seac( decoder, - args[0] >> 16, - args[1] >> 16, + args[0], + args[1], (FT_Int)( args[2] >> 16 ), (FT_Int)( args[3] >> 16 ) ); args += 4; + + decoder->glyph_width = glyph_width; } + else + { + if ( !error ) + error = CFF_Err_Ok; - if ( !error ) - error = CFF_Err_Ok; + cff_builder_close_contour( builder ); - cff_builder_close_contour( builder ); + /* close hints recording session */ + if ( hinter ) + { + if (hinter->close( hinter->hints, builder->current->n_points ) ) + goto Syntax_Error; - /* close hints recording session */ - if ( hinter ) - { - if (hinter->close( hinter->hints, builder->current->n_points ) ) - goto Syntax_Error; + /* apply hints to the loaded glyph outline now */ + hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + decoder->hint_mode ); + } - /* apply hints to the loaded glyph outline now */ - hinter->apply( hinter->hints, - builder->current, - (PSH_Globals)builder->hints_globals, - decoder->hint_mode ); + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); } - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - /* return now! */ FT_TRACE4(( "\n\n" )); return error; @@ -2212,7 +2219,7 @@ cff_compute_max_advance( TT_Face face, FT_Int* max_advance ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; CFF_Decoder decoder; FT_Int glyph_index; CFF_Font cff = (CFF_Font)face->other; @@ -2248,7 +2255,7 @@ } /* ignore the error if one has occurred -- skip to next glyph */ - error = 0; + error = CFF_Err_Ok; } *max_advance = decoder.builder.advance.x; @@ -2282,14 +2289,14 @@ FT_Int glyph_index, FT_Int32 load_flags ) { - FT_Error error; - CFF_Decoder decoder; - TT_Face face = (TT_Face)glyph->root.face; - FT_Bool hinting; - CFF_Font cff = (CFF_Font)face->extra.data; + FT_Error error; + CFF_Decoder decoder; + TT_Face face = (TT_Face)glyph->root.face; + FT_Bool hinting; + CFF_Font cff = (CFF_Font)face->extra.data; - FT_Matrix font_matrix; - FT_Vector font_offset; + FT_Matrix font_matrix; + FT_Vector font_offset; if ( load_flags & FT_LOAD_NO_RECURSE ) @@ -2299,10 +2306,77 @@ glyph->y_scale = 0x10000L; if ( size ) { - glyph->x_scale = size->metrics.x_scale; - glyph->y_scale = size->metrics.y_scale; + glyph->x_scale = size->root.metrics.x_scale; + glyph->y_scale = size->root.metrics.y_scale; + } + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* try to load embedded bitmap if any */ + /* */ + /* XXX: The convention should be emphasized in */ + /* the documents because it can be confusing. */ + if ( size ) + { + CFF_Face cff_face = (CFF_Face)size->root.face; + SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt; + FT_Stream stream = cff_face->root.stream; + + + if ( size->strike_index != 0xFFFFU && + sfnt->load_sbits && + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + { + TT_SBit_MetricsRec metrics; + + + error = sfnt->load_sbit_image( face, + (FT_ULong)size->strike_index, + (FT_UInt)glyph_index, + (FT_Int)load_flags, + stream, + &glyph->root.bitmap, + &metrics ); + + if ( !error ) + { + glyph->root.outline.n_points = 0; + glyph->root.outline.n_contours = 0; + + glyph->root.metrics.width = (FT_Pos)metrics.width << 6; + glyph->root.metrics.height = (FT_Pos)metrics.height << 6; + + glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; + glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; + glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; + + glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; + glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; + glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; + + glyph->root.format = FT_GLYPH_FORMAT_BITMAP; + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + glyph->root.bitmap_left = metrics.vertBearingX; + glyph->root.bitmap_top = metrics.vertBearingY; + } + else + { + glyph->root.bitmap_left = metrics.horiBearingX; + glyph->root.bitmap_top = metrics.horiBearingY; + } + return error; + } + } } +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* return immediately if we only want the embedded bitmaps */ + if ( load_flags & FT_LOAD_SBITS_ONLY ) + return CFF_Err_Invalid_Argument; + glyph->root.outline.n_points = 0; glyph->root.outline.n_contours = 0; @@ -2316,8 +2390,15 @@ FT_ULong charstring_len; + /* in a CID-keyed font, consider `glyph_index' as a CID and map */ + /* it immediately to the real glyph_index -- if it isn't a */ + /* subsetted font, glyph_indices and CIDs are identical, though */ + if ( cff->top_font.font_dict.cid_registry != 0xFFFFU && + cff->charset.cids ) + glyph_index = cff->charset.cids[glyph_index]; + cff_decoder_init( &decoder, face, size, glyph, hinting, - FT_LOAD_TARGET_MODE(load_flags) ); + FT_LOAD_TARGET_MODE( load_flags ) ); decoder.builder.no_recurse = (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); @@ -2363,7 +2444,7 @@ cff_builder_done( &decoder.builder ); } - #ifdef FT_CONFIG_OPTION_INCREMENTAL +#ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ if ( !error && @@ -2430,7 +2511,7 @@ glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; glyph->root.outline.flags = 0; - if ( size && size->metrics.y_ppem < 24 ) + if ( size && size->root.metrics.y_ppem < 24 ) glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; @@ -2480,11 +2561,11 @@ if ( hinting ) { - metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64; - metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64; + metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); + metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); - metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64; - metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64; + metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX ); + metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY ); } } Index: xc/extras/freetype2/src/cff/cffload.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cffload.c,v retrieving revision 1.2 diff -u -r1.2 cffload.c --- a/xc/extras/freetype2/src/cff/cffload.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/cffload.c 28 Apr 2004 10:25:43 -0000 @@ -4,7 +4,7 @@ /* */ /* OpenType and CFF data/program tables loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -1172,12 +1172,12 @@ } - /* allocate a table containing pointers to an index's elements */ + /* allocate a table containing pointers to an index's elements */ static FT_Error cff_index_get_pointers( CFF_Index idx, FT_Byte*** table ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; FT_Memory memory = idx->stream->memory; FT_ULong n, offset, old_offset; FT_Byte** t; @@ -1211,7 +1211,7 @@ FT_Byte** pbytes, FT_ULong* pbyte_len ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; if ( idx && idx->count > element ) @@ -1316,10 +1316,18 @@ FT_UInt sid, FT_Service_PsCMaps psnames ) { + /* value 0xFFFFU indicates a missing dictionary entry */ + if ( sid == 0xFFFFU ) + return 0; + /* if it is not a standard string, return it */ if ( sid > 390 ) return cff_index_get_name( idx, sid - 391 ); + /* CID-keyed CFF fonts don't have glyph names */ + if ( !psnames ) + return 0; + /* that's a standard string, fetch a copy from the PSName module */ { FT_String* name = 0; @@ -1493,6 +1501,7 @@ FT_FREE( charset->sids ); + FT_FREE( charset->cids ); charset->format = 0; charset->offset = 0; } @@ -1503,10 +1512,11 @@ FT_UInt num_glyphs, FT_Stream stream, FT_ULong base_offset, - FT_ULong offset ) + FT_ULong offset, + FT_Bool invert ) { FT_Memory memory = stream->memory; - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; FT_UShort glyph_sid; @@ -1603,8 +1613,8 @@ case 0: if ( num_glyphs > 229 ) { - FT_ERROR(("cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe ISO-Latin)!\n" )); + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" + "predefined charset (Adobe ISO-Latin)!\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -1614,8 +1624,7 @@ goto Exit; /* Copy the predefined charset into the allocated memory. */ - FT_MEM_COPY( charset->sids, cff_isoadobe_charset, - num_glyphs * sizeof ( FT_UShort ) ); + FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs ); break; @@ -1633,8 +1642,7 @@ goto Exit; /* Copy the predefined charset into the allocated memory. */ - FT_MEM_COPY( charset->sids, cff_expert_charset, - num_glyphs * sizeof ( FT_UShort ) ); + FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs ); break; @@ -1652,8 +1660,7 @@ goto Exit; /* Copy the predefined charset into the allocated memory. */ - FT_MEM_COPY( charset->sids, cff_expertsubset_charset, - num_glyphs * sizeof ( FT_UShort ) ); + FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs ); break; @@ -1663,17 +1670,36 @@ } } - Exit: + /* 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]] = i; + } + Exit: /* Clean up if there was an error. */ if ( error ) - if ( charset->sids ) - { - FT_FREE( charset->sids ); - charset->format = 0; - charset->offset = 0; - charset->sids = 0; - } + { + FT_FREE( charset->sids ); + FT_FREE( charset->cids ); + charset->format = 0; + charset->offset = 0; + charset->sids = 0; + } return error; } @@ -1696,7 +1722,7 @@ FT_ULong base_offset, FT_ULong offset ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; FT_UInt count; FT_UInt j; FT_UShort glyph_sid; @@ -1880,15 +1906,12 @@ { case 0: /* First, copy the code to SID mapping. */ - FT_MEM_COPY( encoding->sids, cff_standard_encoding, - 256 * sizeof ( FT_UShort ) ); - + FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 ); goto Populate; case 1: /* First, copy the code to SID mapping. */ - FT_MEM_COPY( encoding->sids, cff_expert_encoding, - 256 * sizeof ( FT_UShort ) ); + FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 ); Populate: /* Construct code to GID mapping from code to SID mapping */ @@ -1949,7 +1972,7 @@ { FT_Error error; CFF_ParserRec parser; - FT_Byte* dict; + FT_Byte* dict = NULL; FT_ULong dict_len; CFF_FontRecDict top = &font->font_dict; CFF_Private priv = &font->private_dict; @@ -1967,6 +1990,20 @@ top->font_matrix.yy = 0x10000L; top->cid_count = 8720; + /* we use the implementation specific SID value 0xFFFF to indicate */ + /* missing entries */ + top->version = 0xFFFFU; + top->notice = 0xFFFFU; + top->copyright = 0xFFFFU; + top->full_name = 0xFFFFU; + top->family_name = 0xFFFFU; + top->weight = 0xFFFFU; + top->embedded_postscript = 0xFFFFU; + + top->cid_registry = 0xFFFFU; + top->cid_ordering = 0xFFFFU; + top->cid_font_name = 0xFFFFU; + error = cff_index_access_element( idx, font_index, &dict, &dict_len ) || cff_parser_run( &parser, dict, dict + dict_len ); @@ -1976,7 +2013,7 @@ goto Exit; /* if it is a CID font, we stop there */ - if ( top->cid_registry ) + if ( top->cid_registry != 0xFFFFU ) goto Exit; /* parse the private dictionary, if any */ @@ -2117,8 +2154,15 @@ if ( error ) goto Exit; + if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) + goto Exit; + + error = cff_new_index( &font->charstrings_index, stream, 0 ); + if ( error ) + goto Exit; + /* now, check for a CID font */ - if ( dict->cid_registry ) + if ( dict->cid_registry != 0xFFFFU ) { CFF_IndexRec fd_index; CFF_SubFont sub; @@ -2161,7 +2205,7 @@ /* now load the FD Select array */ error = CFF_Load_FD_Select( &font->fd_select, - (FT_UInt)dict->cid_count, + font->charstrings_index.count, stream, base_offset + dict->cid_fd_select_offset ); @@ -2182,13 +2226,6 @@ goto Exit; } - if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) - goto Exit; - - error = cff_new_index( &font->charstrings_index, stream, 0 ); - if ( error ) - goto Exit; - /* explicit the global subrs */ font->num_global_subrs = font->global_subrs_index.count; font->num_glyphs = font->charstrings_index.count; @@ -2199,25 +2236,38 @@ if ( error ) goto Exit; - /* read the Charset and Encoding tables when available */ + /* read the Charset and Encoding tables if available */ if ( font->num_glyphs > 0 ) { + FT_Bool invert; + + + invert = dict->cid_registry != 0xFFFFU && + font->charstrings_index.count != dict->cid_count; error = cff_charset_load( &font->charset, font->num_glyphs, stream, - base_offset, dict->charset_offset ); + base_offset, dict->charset_offset, invert ); if ( error ) goto Exit; - error = cff_encoding_load( &font->encoding, - &font->charset, - font->num_glyphs, - stream, - base_offset, - dict->encoding_offset ); - if ( error ) - goto Exit; + /* CID-keyed CFFs don't have an encoding */ + if ( dict->cid_registry == 0xFFFFU ) + { + error = cff_encoding_load( &font->encoding, + &font->charset, + font->num_glyphs, + stream, + base_offset, + dict->encoding_offset ); + if ( error ) + goto Exit; + } + else + /* CID-keyed fonts only need CIDs */ + FT_FREE( font->charset.sids ); } - /* get the font name */ + /* get the font name (/CIDFontName for CID-keyed fonts, */ + /* /FontName otherwise) */ font->font_name = cff_index_get_name( &font->name_index, face_index ); Exit: Index: xc/extras/freetype2/src/cff/cffload.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cffload.h,v retrieving revision 1.2 diff -u -r1.2 cffload.h --- a/xc/extras/freetype2/src/cff/cffload.h 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/cffload.h 28 Apr 2004 10:25:43 -0000 @@ -62,7 +62,7 @@ FT_LOCAL( FT_Byte ) - cff_fd_select_get( CFF_FDSelect select, + cff_fd_select_get( CFF_FDSelect fdselect, FT_UInt glyph_index ); Index: xc/extras/freetype2/src/cff/cffobjs.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cffobjs.c,v retrieving revision 1.2 diff -u -r1.2 cffobjs.c --- a/xc/extras/freetype2/src/cff/cffobjs.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/cffobjs.c 28 Apr 2004 10:25:45 -0000 @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,16 +52,81 @@ /*************************************************************************/ +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + static FT_Error + sbit_size_reset( CFF_Size size ) + { + CFF_Face face; + FT_Error error = CFF_Err_Ok; + + FT_ULong strike_index; + FT_Size_Metrics* metrics; + FT_Size_Metrics* sbit_metrics; + SFNT_Service sfnt; + + + metrics = &size->root.metrics; + + face = (CFF_Face)size->root.face; + sfnt = (SFNT_Service)face->sfnt; + + sbit_metrics = &size->strike_metrics; + + error = sfnt->set_sbit_strike( face, + metrics->x_ppem, metrics->y_ppem, + &strike_index ); + + if ( !error ) + { + TT_SBit_Strike strike = face->sbit_strikes + strike_index; + + + sbit_metrics->x_ppem = metrics->x_ppem; + sbit_metrics->y_ppem = metrics->y_ppem; + + sbit_metrics->ascender = strike->hori.ascender << 6; + sbit_metrics->descender = strike->hori.descender << 6; + + /* XXX: Is this correct? */ + sbit_metrics->height = sbit_metrics->ascender - + sbit_metrics->descender; + + /* XXX: Is this correct? */ + sbit_metrics->max_advance = ( strike->hori.min_origin_SB + + strike->hori.max_width + + strike->hori.min_advance_SB ) << 6; + + size->strike_index = (FT_UInt)strike_index; + } + else + { + size->strike_index = 0xFFFFU; + + sbit_metrics->x_ppem = 0; + sbit_metrics->y_ppem = 0; + sbit_metrics->ascender = 0; + sbit_metrics->descender = 0; + sbit_metrics->height = 0; + sbit_metrics->max_advance = 0; + } + + return error; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + static PSH_Globals_Funcs cff_size_get_globals_funcs( CFF_Size size ) { - CFF_Face face = (CFF_Face)size->face; + CFF_Face face = (CFF_Face)size->root.face; CFF_Font font = (CFF_FontRec *)face->extra.data; PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; FT_Module module; - module = FT_Get_Module( size->face->driver->root.library, + module = FT_Get_Module( size->root.face->driver->root.library, "pshinter" ); return ( module && pshinter && pshinter->get_globals_funcs ) ? pshinter->get_globals_funcs( module ) @@ -72,16 +137,16 @@ FT_LOCAL_DEF( void ) cff_size_done( CFF_Size size ) { - if ( size->internal ) + if ( size->root.internal ) { PSH_Globals_Funcs funcs; funcs = cff_size_get_globals_funcs( size ); if ( funcs ) - funcs->destroy( (PSH_Globals)size->internal ); + funcs->destroy( (PSH_Globals)size->root.internal ); - size->internal = 0; + size->root.internal = 0; } } @@ -89,14 +154,14 @@ FT_LOCAL_DEF( FT_Error ) cff_size_init( CFF_Size size ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); if ( funcs ) { PSH_Globals globals; - CFF_Face face = (CFF_Face)size->face; + CFF_Face face = (CFF_Face)size->root.face; CFF_Font font = (CFF_FontRec *)face->extra.data; CFF_SubFont subfont = &font->top_font; @@ -150,9 +215,9 @@ priv.lenIV = cpriv->lenIV; } - error = funcs->create( size->face->memory, &priv, &globals ); + error = funcs->create( size->root.face->memory, &priv, &globals ); if ( !error ) - size->internal = (FT_Size_Internal)(void*)globals; + size->root.internal = (FT_Size_Internal)(void*)globals; } return error; @@ -163,15 +228,32 @@ cff_size_reset( CFF_Size size ) { PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; + FT_Face face = size->root.face; if ( funcs ) - error = funcs->set_scale( (PSH_Globals)size->internal, - size->metrics.x_scale, - size->metrics.y_scale, + error = funcs->set_scale( (PSH_Globals)size->root.internal, + size->root.metrics.x_scale, + size->root.metrics.y_scale, 0, 0 ); - return error; + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + { + error = sbit_size_reset( size ); + + if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) + size->root.metrics = size->strike_metrics; + } + +#endif + + if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + return CFF_Err_Ok; + else + return error; } @@ -244,8 +326,6 @@ } - - FT_LOCAL_DEF( FT_Error ) cff_face_init( FT_Stream stream, CFF_Face face, @@ -283,7 +363,7 @@ if ( FT_STREAM_SEEK( 0 ) ) goto Exit; - /* check that we have a valid OpenType file */ + /* check whether we have a valid OpenType file */ error = sfnt->init_face( stream, face, face_index, num_params, params ); if ( !error ) { @@ -300,7 +380,7 @@ sfnt_format = 1; /* now, the font can be either an OpenType/CFF font, or an SVG CEF */ - /* font; in the later case it doesn't have a `head' table */ + /* font; in the latter case it doesn't have a `head' table */ error = face->goto_table( face, TTAG_head, stream, 0 ); if ( !error ) { @@ -314,7 +394,7 @@ } else { - /* load the `cmap' table by hand */ + /* load the `cmap' table explicitly */ error = sfnt->load_charmaps( face, stream ); if ( error ) goto Exit; @@ -324,7 +404,7 @@ /* FreeType 2 */ } - /* now, load the CFF part of the file */ + /* now load the CFF part of the file */ error = face->goto_table( face, TTAG_CFF, stream, 0 ); if ( error ) goto Exit; @@ -339,10 +419,11 @@ /* now load and parse the CFF table in the file */ { - CFF_Font cff; - FT_Memory memory = face->root.memory; - FT_Face root; - FT_Int32 flags; + CFF_Font cff; + CFF_FontRecDict dict; + FT_Memory memory = face->root.memory; + FT_Face root; + FT_Int32 flags; if ( FT_NEW( cff ) ) @@ -362,26 +443,29 @@ root = &face->root; root->num_glyphs = cff->num_glyphs; - if ( pure_cff ) + dict = &cff->top_font.font_dict; + + /* we need the `PSNames' module for CFF and CEF formats */ + /* which aren't CID-keyed */ + if ( dict->cid_registry == 0xFFFFU && !psnames ) { - CFF_FontRecDict dict = &cff->top_font.font_dict; + FT_ERROR(( "cff_face_init:" )); + FT_ERROR(( " cannot open CFF & CEF fonts\n" )); + FT_ERROR(( " " )); + FT_ERROR(( " without the `PSNames' module\n" )); + goto Bad_Format; + } + if ( pure_cff ) + { + char* style_name = NULL; - /* we need the `PSNames' module for pure-CFF and CEF formats */ - if ( !psnames ) - { - FT_ERROR(( "cff_face_init:" )); - FT_ERROR(( " cannot open CFF & CEF fonts\n" )); - FT_ERROR(( " " )); - FT_ERROR(( " without the `PSNames' module\n" )); - goto Bad_Format; - } /* Set up num_faces. */ root->num_faces = cff->num_faces; /* compute number of glyphs */ - if ( dict->cid_registry ) + if ( dict->cid_registry != 0xFFFFU ) root->num_glyphs = dict->cid_count; else root->num_glyphs = cff->charstrings_index.count; @@ -392,7 +476,6 @@ root->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16; root->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16; - root->ascender = (FT_Short)( root->bbox.yMax ); root->descender = (FT_Short)( root->bbox.yMin ); root->height = (FT_Short)( @@ -409,13 +492,81 @@ (FT_Short)( dict->underline_thickness >> 16 ); /* retrieve font family & style name */ - root->family_name = cff_index_get_name( &cff->name_index, face_index ); - if ( dict->cid_registry ) - root->style_name = cff_strcpy( memory, "Regular" ); /* XXXX */ + root->family_name = cff_index_get_name( &cff->name_index, + face_index ); + + if ( root->family_name ) + { + char* full = cff_index_get_sid_string( &cff->string_index, + dict->full_name, + psnames ); + char* fullp = full; + char* family = root->family_name; + + /* we're going to try to extract the style name from the + * full name. We need to ignore spaces and dashes during + * the search. + */ + if ( full ) + { + while ( *fullp ) + { + /* skip common characters at the start of both strings + */ + if ( *fullp == *family ) + { + family++; + fullp++; + continue; + } + + /* ignore spaces or dashes in full name during comparison + */ + if ( *fullp == ' ' || *fullp == '-' ) + { + fullp++; + continue; + } + /* ignore spaces and dashes in family name during comparison + */ + if ( *family == ' ' || *family == '-' ) + { + family++; + continue; + } + + if ( !*family && *fullp ) + { + /* the full name begins with the same characters than the + * family name, with spaces and dashes removed. In this + * case, the remaining string in "fullp" will be used + * as the style name + */ + style_name = cff_strcpy( memory, fullp ); + } + break; + } + FT_FREE( full ); + } + } else - root->style_name = cff_index_get_sid_string( &cff->string_index, - dict->weight, - psnames ); + { + char *cid_font_name = + cff_index_get_sid_string( &cff->string_index, + dict->cid_font_name, + psnames ); + + + /* do we have a `/FontName' for a CID-keyed font? */ + if ( cid_font_name ) + root->family_name = cid_font_name; + } + + if ( style_name ) + root->style_name = style_name; + else + /* assume "Regular" style if we don't know better */ + root->style_name = cff_strcpy( memory, (char *)"Regular" ); /*******************************************************************/ /* */ @@ -438,10 +589,6 @@ flags |= FT_FACE_FLAG_KERNING; #endif -#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES - flags |= FT_FACE_FLAG_GLYPH_NAMES; -#endif - root->face_flags = flags; /*******************************************************************/ @@ -453,13 +600,29 @@ if ( dict->italic_angle ) flags |= FT_STYLE_FLAG_ITALIC; - /* XXX: may not be correct */ - if ( cff->top_font.private_dict.force_bold ) - flags |= FT_STYLE_FLAG_BOLD; + { + char *weight = cff_index_get_sid_string( &cff->string_index, + dict->weight, + psnames ); + + + if ( weight ) + if ( !ft_strcmp( weight, "Bold" ) || + !ft_strcmp( weight, "Black" ) ) + flags |= FT_STYLE_FLAG_BOLD; + FT_FREE( weight ); + } root->style_flags = flags; } +#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES + /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ + /* has unset this flag because of the 3.0 `post' table */ + if ( dict->cid_registry == 0xFFFFU ) + root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; +#endif + /*******************************************************************/ /* */ /* Compute char maps. */ @@ -488,7 +651,12 @@ goto Skip_Unicode; /* Standard Unicode (deprecated) */ } - /* we didn't find a Unicode charmap, synthetize one */ + /* since CID-keyed fonts don't contain glyph names, we can't */ + /* construct a cmap */ + if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) + goto Exit; + + /* we didn't find a Unicode charmap -- synthetize one */ cmaprec.face = root; cmaprec.platform_id = 3; cmaprec.encoding_id = 1; Index: xc/extras/freetype2/src/cff/cffobjs.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cffobjs.h,v retrieving revision 1.2 diff -u -r1.2 cffobjs.h --- a/xc/extras/freetype2/src/cff/cffobjs.h 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/cffobjs.h 28 Apr 2004 10:25:45 -0000 @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -51,7 +51,18 @@ /* */ /* A handle to an OpenType size object. */ /* */ - typedef FT_Size CFF_Size; + typedef struct CFF_SizeRec_ + { + FT_SizeRec root; + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_UInt strike_index; /* 0xFFFF to indicate invalid */ + FT_Size_Metrics strike_metrics; /* current strike's metrics */ + +#endif + + } CFF_SizeRec, *CFF_Size; /*************************************************************************/ @@ -89,15 +100,6 @@ } CFF_Transform; - /* this is only used in the case of a pure CFF font with no charmap */ - typedef struct CFF_CharMapRec_ - { - TT_CharMapRec root; - PS_Unicodes unicodes; - - } CFF_CharMapRec, *CFF_CharMap; - - /***********************************************************************/ /* */ /* TrueType driver class. */ Index: xc/extras/freetype2/src/cff/cffparse.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cffparse.c,v retrieving revision 1.2 diff -u -r1.2 cffparse.c --- a/xc/extras/freetype2/src/cff/cffparse.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/cffparse.c 28 Apr 2004 10:25:45 -0000 @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (body) */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -334,7 +334,7 @@ offset->x = cff_parse_fixed_thousand( data++ ); offset->y = cff_parse_fixed_thousand( data ); - temp = ABS( matrix->yy ); + temp = FT_ABS( matrix->yy ); *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) ); Index: xc/extras/freetype2/src/cff/cffparse.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cffparse.h,v retrieving revision 1.2 diff -u -r1.2 cffparse.h --- a/xc/extras/freetype2/src/cff/cffparse.h 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/cffparse.h 28 Apr 2004 10:25:45 -0000 @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (specification) */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ Index: xc/extras/freetype2/src/cff/cfftoken.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cfftoken.h,v retrieving revision 1.2 diff -u -r1.2 cfftoken.h --- a/xc/extras/freetype2/src/cff/cfftoken.h 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/cfftoken.h 28 Apr 2004 10:25:45 -0000 @@ -43,10 +43,10 @@ CFF_FIELD_NUM ( 17, charstrings_offset ) CFF_FIELD_CALLBACK( 18, private_dict ) CFF_FIELD_NUM ( 0x114, synthetic_base ) - CFF_FIELD_STRING ( 0x115, postscript ) - CFF_FIELD_STRING ( 0x116, base_font_name ) + CFF_FIELD_STRING ( 0x115, embedded_postscript ) #if 0 + CFF_FIELD_STRING ( 0x116, base_font_name ) CFF_FIELD_DELTA ( 0x117, base_font_blend, 16 ) CFF_FIELD_CALLBACK( 0x118, multiple_master ) CFF_FIELD_CALLBACK( 0x119, blend_axit_types ) Index: xc/extras/freetype2/src/cff/cfftypes.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/cfftypes.h,v retrieving revision 1.2 diff -u -r1.2 cfftypes.h --- a/xc/extras/freetype2/src/cff/cfftypes.h 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/cfftypes.h 28 Apr 2004 10:25:45 -0000 @@ -82,7 +82,8 @@ FT_ULong offset; FT_UShort* sids; - + FT_UShort* cids; /* the inverse mapping of `sids'; only needed */ + /* for CID-keyed fonts */ } CFF_CharsetRec, *CFF_Charset; @@ -113,8 +114,6 @@ FT_ULong private_size; FT_Long synthetic_base; FT_UInt embedded_postscript; - FT_UInt base_font_name; - FT_UInt postscript; /* these should only be used for the top-level font dictionary */ FT_UInt cid_registry; @@ -124,7 +123,7 @@ FT_Long cid_font_version; FT_Long cid_font_revision; FT_Long cid_font_type; - FT_Long cid_count; + FT_ULong cid_count; FT_ULong cid_uid_base; FT_ULong cid_fd_array_offset; FT_ULong cid_fd_select_offset; @@ -200,7 +199,7 @@ /* maximum number of sub-fonts in a CID-keyed file */ -#define CFF_MAX_CID_FONTS 16 +#define CFF_MAX_CID_FONTS 32 typedef struct CFF_FontRec_ Index: xc/extras/freetype2/src/cff/rules.mk =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cff/rules.mk,v retrieving revision 1.2 diff -u -r1.2 rules.mk --- a/xc/extras/freetype2/src/cff/rules.mk 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cff/rules.mk 28 Apr 2004 10:25:45 -0000 @@ -34,6 +34,7 @@ # CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \ $(CFF_DIR)/cfftoken.h \ + $(CFF_DIR)/cfftypes.h \ $(CFF_DIR)/cfferrs.h Index: xc/extras/freetype2/src/cid/cidgload.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cid/cidgload.c,v retrieving revision 1.2 diff -u -r1.2 cidgload.c --- a/xc/extras/freetype2/src/cid/cidgload.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cid/cidgload.c 28 Apr 2004 10:25:45 -0000 @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -44,7 +44,7 @@ CID_FaceInfo cid = &face->cid; FT_Byte* p; FT_UInt fd_select; - FT_Stream stream = face->root.stream; + FT_Stream stream = face->cid_stream; FT_Error error = 0; FT_Byte* charstring = 0; FT_Memory memory = face->root.memory; @@ -306,7 +306,7 @@ 0, /* glyph names -- XXX */ 0, /* blend == 0 */ hinting, - FT_LOAD_TARGET_MODE(load_flags), + FT_LOAD_TARGET_MODE( load_flags ), cid_load_glyph ); /* set up the decoder */ @@ -412,11 +412,11 @@ if ( hinting ) { - metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64; - metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64; + metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); + metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); - metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64; - metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64; + metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX ); + metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY ); } } @@ -426,10 +426,10 @@ /* grid fit the bounding box if necessary */ if ( hinting ) { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); } metrics->width = cbox.xMax - cbox.xMin; Index: xc/extras/freetype2/src/cid/cidload.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cid/cidload.c,v retrieving revision 1.2 diff -u -r1.2 cidload.c --- a/xc/extras/freetype2/src/cid/cidload.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cid/cidload.c 28 Apr 2004 10:25:45 -0000 @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -162,7 +162,7 @@ (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); - temp_scale = ABS( temp[3] ); + temp_scale = FT_ABS( temp[3] ); /* Set units per EM based on FontMatrix values. We set the value to */ /* `1000/temp_scale', because temp_scale was already multiplied by */ @@ -363,7 +363,7 @@ { CID_FaceInfo cid = &face->cid; FT_Memory memory = face->root.memory; - FT_Stream stream = face->root.stream; + FT_Stream stream = face->cid_stream; FT_Error error; FT_Int n; CID_Subrs subr; @@ -388,7 +388,7 @@ /* reallocate offsets array if needed */ if ( num_subrs + 1 > max_offsets ) { - FT_UInt new_max = ( num_subrs + 1 + 3 ) & -4; + FT_UInt new_max = FT_PAD_CEIL( num_subrs + 1, 4 ); if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) ) @@ -399,7 +399,7 @@ /* read the subrmap's offsets */ if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || - FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) + FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) goto Fail; p = (FT_Byte*)stream->cursor; @@ -487,11 +487,111 @@ } + static FT_Error + cid_hex_to_binary( FT_Byte* data, + FT_Long data_len, + FT_ULong offset, + CID_Face face ) + { + FT_Stream stream = face->root.stream; + FT_Error error; + + FT_Byte buffer[256]; + FT_Byte *p, *plimit; + FT_Byte *d, *dlimit; + FT_Byte val; + + FT_Bool upper_nibble, done; + + + if ( FT_STREAM_SEEK( offset ) ) + goto Exit; + + d = data; + dlimit = d + data_len; + p = buffer; + plimit = p; + + upper_nibble = 1; + done = 0; + + while ( d < dlimit ) + { + if ( p >= plimit ) + { + FT_ULong oldpos = FT_STREAM_POS(); + FT_ULong size = stream->size - oldpos; + + + if ( size == 0 ) + { + error = CID_Err_Syntax_Error; + goto Exit; + } + + if ( FT_STREAM_READ( buffer, 256 > size ? size : 256 ) ) + goto Exit; + p = buffer; + plimit = p + FT_STREAM_POS() - oldpos; + } + + if ( ft_isdigit( *p ) ) + val = *p - '0'; + else if ( *p >= 'a' && *p <= 'f' ) + val = *p - 'a'; + else if ( *p >= 'A' && *p <= 'F' ) + val = *p - 'A' + 10; + else if ( *p == ' ' || + *p == '\t' || + *p == '\r' || + *p == '\n' || + *p == '\f' || + *p == '\0' ) + { + p++; + continue; + } + else if ( *p == '>' ) + { + val = 0; + done = 1; + } + else + { + error = CID_Err_Syntax_Error; + goto Exit; + } + + if ( upper_nibble ) + *d = val << 4; + else + { + *d += val; + d++; + } + + upper_nibble = 1 - upper_nibble; + + if ( done ) + break; + + p++; + } + + error = CID_Err_Ok; + + Exit: + return error; + } + + FT_LOCAL_DEF( FT_Error ) - cid_face_open( CID_Face face ) + cid_face_open( CID_Face face, + FT_Int face_index ) { CID_Loader loader; CID_Parser* parser; + FT_Memory memory = face->root.memory; FT_Error error; @@ -509,7 +609,30 @@ if ( error ) goto Exit; - face->cid.data_offset = loader.parser.data_offset; + if ( face_index < 0 ) + goto Exit; + + if ( FT_NEW( face->cid_stream ) ) + goto Exit; + + if ( parser->binary_length ) + { + /* we must convert the data section from hexadecimal to binary */ + if ( FT_ALLOC( face->binary_data, parser->binary_length ) || + cid_hex_to_binary( face->binary_data, parser->binary_length, + parser->data_offset, face ) ) + goto Exit; + + FT_Stream_OpenMemory( face->cid_stream, + face->binary_data, parser->binary_length ); + face->cid.data_offset = 0; + } + else + { + *face->cid_stream = *face->root.stream; + face->cid.data_offset = loader.parser.data_offset; + } + error = cid_read_subrs( face ); Exit: Index: xc/extras/freetype2/src/cid/cidload.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cid/cidload.h,v retrieving revision 1.2 diff -u -r1.2 cidload.h --- a/xc/extras/freetype2/src/cid/cidload.h 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cid/cidload.h 28 Apr 2004 10:25:45 -0000 @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,7 +41,8 @@ FT_Byte offsize ); FT_LOCAL( FT_Error ) - cid_face_open( CID_Face face ); + cid_face_open( CID_Face face, + FT_Int face_index ); FT_END_HEADER Index: xc/extras/freetype2/src/cid/cidobjs.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cid/cidobjs.c,v retrieving revision 1.2 diff -u -r1.2 cidobjs.c --- a/xc/extras/freetype2/src/cid/cidobjs.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cid/cidobjs.c 28 Apr 2004 10:25:45 -0000 @@ -4,7 +4,7 @@ /* */ /* CID objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -234,6 +234,9 @@ face->root.family_name = 0; face->root.style_name = 0; + + FT_FREE( face->binary_data ); + FT_FREE( face->cid_stream ); } } @@ -275,7 +278,6 @@ FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_UNUSED( stream ); @@ -305,7 +307,7 @@ if ( FT_STREAM_SEEK( 0 ) ) goto Exit; - error = cid_face_open( face ); + error = cid_face_open( face, face_index ); if ( error ) goto Exit; @@ -416,10 +418,8 @@ root->height = (FT_Short)( ( ( root->ascender - root->descender ) * 12 ) / 10 ); - root->underline_position = - (FT_Short)( info->underline_position >> 16 ); - root->underline_thickness = - (FT_Short)( info->underline_thickness >> 16 ); + root->underline_position = (FT_Short)info->underline_position; + root->underline_thickness = (FT_Short)info->underline_thickness; root->internal->max_points = 0; root->internal->max_contours = 0; Index: xc/extras/freetype2/src/cid/cidparse.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cid/cidparse.c,v retrieving revision 1.2 diff -u -r1.2 cidparse.c --- a/xc/extras/freetype2/src/cid/cidparse.c 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cid/cidparse.c 28 Apr 2004 10:25:45 -0000 @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -59,6 +59,7 @@ FT_Byte buffer[256 + 10]; FT_Int buff_len; FT_Byte *cur, *limit; + FT_Byte *arg1, *arg2; FT_MEM_ZERO( parser, sizeof ( *parser ) ); @@ -135,8 +136,16 @@ parser->root.limit = parser->root.cursor + ps_len; parser->num_dict = -1; - /* finally we check whether `StartData' was real -- it could be */ - /* in a comment or string */ + /* Finally, we check whether `StartData' was real -- it could be */ + /* in a comment or string. We also get its arguments to find out */ + /* whether the data is represented in binary or hex format. */ + + arg1 = parser->root.cursor; + cid_parser_skip_PS_token( parser ); + cid_parser_skip_spaces ( parser ); + arg2 = parser->root.cursor; + cid_parser_skip_PS_token( parser ); + cid_parser_skip_spaces ( parser ); limit = parser->root.limit; cur = parser->root.cursor; @@ -145,6 +154,9 @@ { if ( *cur == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) { + if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) + parser->binary_length = ft_atol( (const char *)arg2 ); + limit = parser->root.limit; cur = parser->root.cursor; goto Exit; @@ -152,7 +164,9 @@ cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); - cur = parser->root.cursor; + arg1 = arg2; + arg2 = cur; + cur = parser->root.cursor; } /* we haven't found the correct `StartData'; go back and continue */ Index: xc/extras/freetype2/src/cid/cidparse.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/cid/cidparse.h,v retrieving revision 1.2 diff -u -r1.2 cidparse.h --- a/xc/extras/freetype2/src/cid/cidparse.h 23 Apr 2004 18:42:49 -0000 1.2 +++ b/xc/extras/freetype2/src/cid/cidparse.h 28 Apr 2004 10:25:45 -0000 @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,6 +50,9 @@ /* data_offset :: The start position of the binary data (i.e., the */ /* end of the data to be parsed. */ /* */ + /* binary_length :: The length of the data after the `StartData' */ + /* command if the data format is hexadecimal. */ + /* */ /* cid :: A structure which holds the information about */ /* the current font. */ /* */ @@ -65,6 +68,8 @@ FT_ULong data_offset; + FT_Long binary_length; + CID_FaceInfo cid; FT_Int num_dict; Index: xc/extras/freetype2/src/gzip/ftgzip.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/gzip/ftgzip.c,v retrieving revision 1.2 diff -u -r1.2 ftgzip.c --- a/xc/extras/freetype2/src/gzip/ftgzip.c 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/gzip/ftgzip.c 28 Apr 2004 10:25:46 -0000 @@ -4,11 +4,11 @@ /* */ /* FreeType support for .gz compressed files. */ /* */ -/* this optional component relies on zlib. It should mainly be used to */ +/* This optional component relies on zlib. It should mainly be used to */ /* parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2002, 2003 by */ +/* Copyright 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +19,7 @@ /* */ /***************************************************************************/ + #include #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_STREAM_H @@ -143,7 +144,7 @@ /***************************************************************************/ /***************************************************************************/ -#define FT_GZIP_BUFFER_SIZE 4096 +#define FT_GZIP_BUFFER_SIZE 4096 typedef struct FT_GZipFileRec_ { @@ -153,7 +154,7 @@ z_stream zstream; /* zlib input stream */ FT_ULong start; /* starting position, after .gz header */ - FT_Byte input[FT_GZIP_BUFFER_SIZE]; /* input read buffer */ + FT_Byte input[FT_GZIP_BUFFER_SIZE]; /* input read buffer */ FT_Byte buffer[FT_GZIP_BUFFER_SIZE]; /* output buffer */ FT_ULong pos; /* position in output */ @@ -172,7 +173,7 @@ #define FT_GZIP_RESERVED 0xE0 /* bits 5..7: reserved */ - /* check and skip .gz header - we don't support "transparent" compression */ + /* check and skip .gz header - we don't support `transparent' compression */ static FT_Error ft_gzip_check_header( FT_Stream stream ) { @@ -253,7 +254,7 @@ FT_Stream source ) { z_stream* zstream = &zip->zstream; - FT_Error error = 0; + FT_Error error = Gzip_Err_Ok; zip->stream = stream; @@ -275,9 +276,9 @@ zip->start = FT_STREAM_POS(); } - /* initialize zlib - there is no zlib header in the compressed stream */ - zstream->zalloc = (alloc_func) ft_gzip_alloc; - zstream->zfree = (free_func) ft_gzip_free; + /* initialize zlib -- there is no zlib header in the compressed stream */ + zstream->zalloc = (alloc_func)ft_gzip_alloc; + zstream->zfree = (free_func) ft_gzip_free; zstream->opaque = stream->memory; zstream->avail_in = 0; @@ -285,10 +286,7 @@ if ( inflateInit2( zstream, -MAX_WBITS ) != Z_OK || zstream->next_in == NULL ) - { error = Gzip_Err_Invalid_File_Format; - goto Exit; - } Exit: return error; @@ -300,6 +298,7 @@ { z_stream* zstream = &zip->zstream; + inflateEnd( zstream ); /* clear the rest */ @@ -340,7 +339,8 @@ zip->cursor = zip->limit; zip->pos = 0; } - return error; + + return error; } @@ -375,7 +375,7 @@ zstream->next_in = zip->input; zstream->avail_in = size; - return 0; + return Gzip_Err_Ok; } @@ -417,6 +417,7 @@ break; } } + return error; } @@ -426,8 +427,8 @@ ft_gzip_file_skip_output( FT_GZipFile zip, FT_ULong count ) { - FT_Error error = 0; - FT_ULong delta; + FT_Error error = Gzip_Err_Ok; + FT_ULong delta; for (;;) Index: xc/extras/freetype2/src/gzip/zutil.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/gzip/zutil.h,v retrieving revision 1.2 diff -u -r1.2 zutil.h --- a/xc/extras/freetype2/src/gzip/zutil.h 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/gzip/zutil.h 28 Apr 2004 10:25:49 -0000 @@ -8,8 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id$ */ - +/* @(#) $Id: zutil.h,v 1.4 2003/05/21 07:39:42 werner Exp $ */ #ifndef _Z_UTIL_H #define _Z_UTIL_H Index: xc/extras/freetype2/src/lzw/Jamfile =================================================================== RCS file: xc/extras/freetype2/src/lzw/Jamfile diff -N xc/extras/freetype2/src/lzw/Jamfile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/lzw/Jamfile 28 Apr 2004 10:25:49 -0000 @@ -0,0 +1,9 @@ +# FreeType 2 src/lzw Jamfile (C) 2004 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) lzw ; + +Library $(FT2_LIB) : ftlzw.c ; + +# end of src/lzw Jamfile + Index: xc/extras/freetype2/src/lzw/ftlzw.c =================================================================== RCS file: xc/extras/freetype2/src/lzw/ftlzw.c diff -N xc/extras/freetype2/src/lzw/ftlzw.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/lzw/ftlzw.c 28 Apr 2004 10:25:49 -0000 @@ -0,0 +1,463 @@ +/***************************************************************************/ +/* */ +/* ftlzw.c */ +/* */ +/* FreeType support for .Z compressed files. */ +/* */ +/* This optional component relies on NetBSD's zopen(). It should mainly */ +/* be used to parse compressed PCF fonts, as found with many X11 server */ +/* distributions. */ +/* */ +/* Copyright 2004 by */ +/* Albert Chin-A-Young. */ +/* */ +/* Based on code in src/gzip/ftgzip.c, Copyright 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H +#include +#include + + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX LZW_Err_ +#define FT_ERR_BASE FT_Mod_Err_LZW + +#include FT_ERRORS_H + + +#ifdef FT_CONFIG_OPTION_USE_LZW + +#include "zopen.h" + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** M E M O R Y M A N A G E M E N T *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** F I L E D E S C R I P T O R *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + +#define FT_LZW_BUFFER_SIZE 4096 + + typedef struct FT_LZWFileRec_ + { + FT_Stream source; /* parent/source stream */ + FT_Stream stream; /* embedding stream */ + FT_Memory memory; /* memory allocator */ + s_zstate_t zstream; /* lzw input stream */ + + FT_ULong start; /* starting position, after .Z header */ + FT_Byte input[FT_LZW_BUFFER_SIZE]; /* input buffer */ + + FT_Byte buffer[FT_LZW_BUFFER_SIZE]; /* output buffer */ + FT_ULong pos; /* position in output */ + FT_Byte* cursor; + FT_Byte* limit; + + } FT_LZWFileRec, *FT_LZWFile; + + + /* check and skip .Z header */ + static FT_Error + ft_lzw_check_header( FT_Stream stream ) + { + FT_Error error; + FT_Byte head[2]; + + + if ( FT_STREAM_SEEK( 0 ) || + FT_STREAM_READ( head, 2 ) ) + goto Exit; + + /* head[0] && head[1] are the magic numbers */ + if ( head[0] != 0x1f || + head[1] != 0x9d ) + error = LZW_Err_Invalid_File_Format; + + Exit: + return error; + } + + + static FT_Error + ft_lzw_file_init( FT_LZWFile zip, + FT_Stream stream, + FT_Stream source ) + { + s_zstate_t* zstream = &zip->zstream; + FT_Error error = LZW_Err_Ok; + + + zip->stream = stream; + zip->source = source; + zip->memory = stream->memory; + + zip->limit = zip->buffer + FT_LZW_BUFFER_SIZE; + zip->cursor = zip->limit; + zip->pos = 0; + + /* check and skip .Z header */ + { + stream = source; + + error = ft_lzw_check_header( source ); + if ( error ) + goto Exit; + + zip->start = FT_STREAM_POS(); + } + + /* initialize internal lzw variable */ + zinit( zstream ); + + zstream->avail_in = 0; + zstream->next_in = zip->buffer; + zstream->zs_in_count = source->size - 2; + + if ( zstream->next_in == NULL ) + error = LZW_Err_Invalid_File_Format; + + Exit: + return error; + } + + + static void + ft_lzw_file_done( FT_LZWFile zip ) + { + s_zstate_t* zstream = &zip->zstream; + + + /* clear the rest */ + zstream->next_in = NULL; + zstream->next_out = NULL; + zstream->avail_in = 0; + zstream->avail_out = 0; + zstream->total_in = 0; + zstream->total_out = 0; + + zip->memory = NULL; + zip->source = NULL; + zip->stream = NULL; + } + + + static FT_Error + ft_lzw_file_reset( FT_LZWFile zip ) + { + FT_Stream stream = zip->source; + FT_Error error; + + + if ( !FT_STREAM_SEEK( zip->start ) ) + { + s_zstate_t* zstream = &zip->zstream; + + + zinit( zstream ); + + zstream->avail_in = 0; + zstream->next_in = zip->input; + zstream->total_in = 0; + zstream->avail_out = 0; + zstream->next_out = zip->buffer; + zstream->total_out = 0; + zstream->zs_in_count = zip->source->size - 2; + + zip->limit = zip->buffer + FT_LZW_BUFFER_SIZE; + zip->cursor = zip->limit; + zip->pos = 0; + } + + return error; + } + + + static FT_Error + ft_lzw_file_fill_input( FT_LZWFile zip ) + { + s_zstate_t* zstream = &zip->zstream; + FT_Stream stream = zip->source; + FT_ULong size; + + + if ( stream->read ) + { + size = stream->read( stream, stream->pos, zip->input, + FT_LZW_BUFFER_SIZE ); + if ( size == 0 ) + return LZW_Err_Invalid_Stream_Operation; + } + else + { + size = stream->size - stream->pos; + if ( size > FT_LZW_BUFFER_SIZE ) + size = FT_LZW_BUFFER_SIZE; + + if ( size == 0 ) + return LZW_Err_Invalid_Stream_Operation; + + FT_MEM_COPY( zip->input, stream->base + stream->pos, size ); + } + stream->pos += size; + + zstream->next_in = zip->input; + zstream->avail_in = size; + + return LZW_Err_Ok; + } + + + + static FT_Error + ft_lzw_file_fill_output( FT_LZWFile zip ) + { + s_zstate_t* zstream = &zip->zstream; + FT_Error error = 0; + + + zip->cursor = zip->buffer; + zstream->next_out = zip->cursor; + zstream->avail_out = FT_LZW_BUFFER_SIZE; + + while ( zstream->avail_out > 0 ) + { + int num_read = 0; + + + if ( zstream->avail_in == 0 ) + { + error = ft_lzw_file_fill_input( zip ); + if ( error ) + break; + } + + num_read = zread( zstream ); + + if ( num_read == -1 && zstream->zs_in_count == 0 ) + { + zip->limit = zstream->next_out; + if ( zip->limit == zip->cursor ) + error = LZW_Err_Invalid_Stream_Operation; + break; + } + else if ( num_read == -1 ) + break; + else + zstream->avail_out -= num_read; + } + + return error; + } + + + /* fill output buffer; `count' must be <= FT_LZW_BUFFER_SIZE */ + static FT_Error + ft_lzw_file_skip_output( FT_LZWFile zip, + FT_ULong count ) + { + FT_Error error = LZW_Err_Ok; + FT_ULong delta; + + + for (;;) + { + delta = (FT_ULong)( zip->limit - zip->cursor ); + if ( delta >= count ) + delta = count; + + zip->cursor += delta; + zip->pos += delta; + + count -= delta; + if ( count == 0 ) + break; + + error = ft_lzw_file_fill_output( zip ); + if ( error ) + break; + } + + return error; + } + + + static FT_ULong + ft_lzw_file_io( FT_LZWFile zip, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_ULong result = 0; + FT_Error error; + + + /* Teset inflate stream if we're seeking backwards. */ + /* Yes, that is not too efficient, but it saves memory :-) */ + if ( pos < zip->pos ) + { + error = ft_lzw_file_reset( zip ); + if ( error ) + goto Exit; + } + + /* skip unwanted bytes */ + if ( pos > zip->pos ) + { + error = ft_lzw_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) ); + if ( error ) + goto Exit; + } + + if ( count == 0 ) + goto Exit; + + /* now read the data */ + for (;;) + { + FT_ULong delta; + + + delta = (FT_ULong)( zip->limit - zip->cursor ); + if ( delta >= count ) + delta = count; + + FT_MEM_COPY( buffer, zip->cursor, delta ); + buffer += delta; + result += delta; + zip->cursor += delta; + zip->pos += delta; + + count -= delta; + if ( count == 0 ) + break; + + error = ft_lzw_file_fill_output( zip ); + if ( error ) + break; + } + + Exit: + return result; + } + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** L Z W E M B E D D I N G S T R E A M *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + + static void + ft_lzw_stream_close( FT_Stream stream ) + { + FT_LZWFile zip = (FT_LZWFile)stream->descriptor.pointer; + FT_Memory memory = stream->memory; + + + if ( zip ) + { + /* finalize lzw file descriptor */ + ft_lzw_file_done( zip ); + + FT_FREE( zip ); + + stream->descriptor.pointer = NULL; + } + } + + + static FT_ULong + ft_lzw_stream_io( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_LZWFile zip = (FT_LZWFile)stream->descriptor.pointer; + + + return ft_lzw_file_io( zip, pos, buffer, count ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ) + { + FT_Error error; + FT_Memory memory = source->memory; + FT_LZWFile zip; + + + FT_ZERO( stream ); + stream->memory = memory; + + if ( !FT_NEW( zip ) ) + { + error = ft_lzw_file_init( zip, stream, source ); + if ( error ) + { + FT_FREE( zip ); + goto Exit; + } + + stream->descriptor.pointer = zip; + } + + stream->size = 0x7FFFFFFFL; /* don't know the real size! */ + stream->pos = 0; + stream->base = 0; + stream->read = ft_lzw_stream_io; + stream->close = ft_lzw_stream_close; + + Exit: + return error; + } + +#include "zopen.c" + + +#else /* !FT_CONFIG_OPTION_USE_LZW */ + + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ) + { + FT_UNUSED( stream ); + FT_UNUSED( source ); + + return LZW_Err_Unimplemented_Feature; + } + + +#endif /* !FT_CONFIG_OPTION_USE_LZW */ + + +/* END */ Index: xc/extras/freetype2/src/lzw/rules.mk =================================================================== RCS file: xc/extras/freetype2/src/lzw/rules.mk diff -N xc/extras/freetype2/src/lzw/rules.mk --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/lzw/rules.mk 28 Apr 2004 10:25:49 -0000 @@ -0,0 +1,70 @@ +# +# FreeType 2 LZW support configuration rules +# + + +# Copyright 2004 by +# Albert Chin-A-Young. +# +# Based on src/lzw/rules.mk, Copyright 2002 by +# David Turner, Robert Wilhelm, and Werner Lemberg. +# +# This file is part of the FreeType project, and may only be used, modified, +# and distributed under the terms of the FreeType project license, +# LICENSE.TXT. By continuing to use, modify, or distribute this file you +# indicate that you have read the license and understand and accept it +# fully. + + +# LZW driver directory +# +LZW_DIR := $(SRC_DIR)/lzw + + +# compilation flags for the driver +# +LZW_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(LZW_DIR)) + + +# LZW support sources (i.e., C files) +# +LZW_DRV_SRC := $(LZW_DIR)/ftlzw.c \ + $(LZW_DIR)/zopen.c + +# LZW support headers +# +LZW_DRV_H := $(LZW_DIR)/zopen.h + + +# LZW driver object(s) +# +# LZW_DRV_OBJ_M is used during `multi' builds +# LZW_DRV_OBJ_S is used during `single' builds +# +LZW_DRV_OBJ_M := $(OBJ_DIR)/ftlzw.$O +LZW_DRV_OBJ_S := $(OBJ_DIR)/ftlzw.$O + +# LZW support source file for single build +# +LZW_DRV_SRC_S := $(LZW_DIR)/ftlzw.c + + +# LZW support - single object +# +$(LZW_DRV_OBJ_S): $(LZW_DRV_SRC_S) $(LZW_DRV_SRC) $(FREETYPE_H) $(LZW_DRV_H) + $(LZW_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(LZW_DRV_SRC_S)) + + +# LZW support - multiple objects +# +$(OBJ_DIR)/%.$O: $(LZW_DIR)/%.c $(FREETYPE_H) $(LZW_DRV_H) + $(LZW_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(LZW_DRV_OBJ_S) +DRV_OBJS_M += $(LZW_DRV_OBJ_M) + + +# EOF Index: xc/extras/freetype2/src/lzw/zopen.c =================================================================== RCS file: xc/extras/freetype2/src/lzw/zopen.c diff -N xc/extras/freetype2/src/lzw/zopen.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/lzw/zopen.c 28 Apr 2004 10:25:50 -0000 @@ -0,0 +1,396 @@ +/* $NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $ */ + +/*- + * Copyright (c) 1985, 1986, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Diomidis Spinellis and James A. Woods, derived from original + * work by Spencer Thomas and Joseph Orost. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*- + * + * Copyright (c) 2004 + * Albert Chin-A-Young. + * + * Modified to work with FreeType's PCF driver. + * + */ + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93"; +#else +static char rcsid[] = "$NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +/*- + * fcompress.c - File compression ala IEEE Computer, June 1984. + * + * Compress authors: + * Spencer W. Thomas (decvax!utah-cs!thomas) + * Jim McKie (decvax!mcvax!jim) + * Steve Davies (decvax!vax135!petsd!peora!srd) + * Ken Turkowski (decvax!decwrl!turtlevax!ken) + * James A. Woods (decvax!ihnp4!ames!jaw) + * Joe Orost (decvax!vax135!petsd!joe) + * + * Cleaned up and converted to library returning I/O streams by + * Diomidis Spinellis . + */ + +#include +#include +#include +#include +#include + +#if 0 +static char_type magic_header[] = + { 0x1f, 0x9d }; /* 1F 9D */ +#endif + +#define BIT_MASK 0x1f /* Defines for third byte of header. */ +#define BLOCK_MASK 0x80 + +/* + * Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is + * a fourth header byte (for expansion). + */ +#define INIT_BITS 9 /* Initial number of bits/code. */ + +#define MAXCODE(n_bits) ((1 << (n_bits)) - 1) + +/* Definitions to retain old variable names */ +#define fp zs->zs_fp +#define state zs->zs_state +#define n_bits zs->zs_n_bits +#define maxbits zs->zs_maxbits +#define maxcode zs->zs_maxcode +#define maxmaxcode zs->zs_maxmaxcode +#define htab zs->zs_htab +#define codetab zs->zs_codetab +#define hsize zs->zs_hsize +#define free_ent zs->zs_free_ent +#define block_compress zs->zs_block_compress +#define clear_flg zs->zs_clear_flg +#define offset zs->zs_offset +#define in_count zs->zs_in_count +#define buf_len zs->zs_buf_len +#define buf zs->zs_buf +#define stackp zs->u.r.zs_stackp +#define finchar zs->u.r.zs_finchar +#define code zs->u.r.zs_code +#define oldcode zs->u.r.zs_oldcode +#define incode zs->u.r.zs_incode +#define roffset zs->u.r.zs_roffset +#define size zs->u.r.zs_size +#define gbuf zs->u.r.zs_gbuf + +/* + * To save much memory, we overlay the table used by compress() with those + * used by decompress(). The tab_prefix table is the same size and type as + * the codetab. The tab_suffix table needs 2**BITS characters. We get this + * from the beginning of htab. The output stack uses the rest of htab, and + * contains characters. There is plenty of room for any possible stack + * (stack used to be 8000 characters). + */ + +#define htabof(i) htab[i] +#define codetabof(i) codetab[i] + +#define tab_prefixof(i) codetabof(i) +#define tab_suffixof(i) ((char_type *)(htab))[i] +#define de_stack ((char_type *)&tab_suffixof(1 << BITS)) + +#define CHECK_GAP 10000 /* Ratio check interval. */ + +/* + * the next two codes should not be changed lightly, as they must not + * lie within the contiguous general code space. + */ +#define FIRST 257 /* First free entry. */ +#define CLEAR 256 /* Table clear output code. */ + +/*- + * Algorithm from "A Technique for High Performance Data Compression", + * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19. + * + * Algorithm: + * Modified Lempel-Ziv method (LZW). Basically finds common + * substrings and replaces them with a variable size code. This is + * deterministic, and can be done on the fly. Thus, the decompression + * procedure needs no input table, but tracks the way the table was built. + */ + +#if 0 +static int +zclose(s_zstate_t *zs) +{ + free(zs); + return (0); +} +#endif + +/*- + * Output the given code. + * Inputs: + * code: A n_bits-bit integer. If == -1, then EOF. This assumes + * that n_bits =< (long)wordsize - 1. + * Outputs: + * Outputs code to the file. + * Assumptions: + * Chars are 8 bits long. + * Algorithm: + * Maintain a BITS character long buffer (so that 8 codes will + * fit in it exactly). Use the VAX insv instruction to insert each + * code in turn. When the buffer fills up empty it and start over. + */ + +static const char_type rmask[9] = + {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; + +/* + * Decompress read. This routine adapts to the codes in the file building + * the "string" table on-the-fly; requiring no table to be stored in the + * compressed file. The tables used herein are shared with those of the + * compress() routine. See the definitions above. + */ +static int +zread(s_zstate_t *zs) +{ + unsigned int count; + + if (in_count == 0) + return -1; + if (zs->avail_out == 0) + return 0; + + count = zs->avail_out; + switch (state) { + case S_START: + state = S_MIDDLE; + break; + case S_MIDDLE: + goto middle; + case S_EOF: + goto eof; + } + + maxbits = *(zs->next_in); /* Set -b from file. */ + zs->avail_in--; + zs->next_in++; + zs->total_in++; + in_count--; + block_compress = maxbits & BLOCK_MASK; + maxbits &= BIT_MASK; + maxmaxcode = 1L << maxbits; + if (maxbits > BITS) { + return -1; + } + /* As above, initialize the first 256 entries in the table. */ + maxcode = MAXCODE(n_bits = INIT_BITS); + for (code = 255; code >= 0; code--) { + tab_prefixof(code) = 0; + tab_suffixof(code) = (char_type) code; + } + free_ent = block_compress ? FIRST : 256; + + finchar = oldcode = getcode(zs); + if (oldcode == -1) /* EOF already? */ + return 0; /* Get out of here */ + + /* First code must be 8 bits = char. */ + *(zs->next_out)++ = (unsigned char)finchar; + zs->total_out++; + count--; + stackp = de_stack; + + while ((code = getcode(zs)) > -1) { + if ((code == CLEAR) && block_compress) { + for (code = 255; code >= 0; code--) + tab_prefixof(code) = 0; + clear_flg = 1; + free_ent = FIRST - 1; + if ((code = getcode(zs)) == -1) + /* O, untimely death! */ + break; + } + incode = code; + + /* Special case for KwKwK string. */ + if (code >= free_ent) { + *stackp++ = finchar; + code = oldcode; + } + + /* Generate output characters in reverse order. */ + while (code >= 256) { + *stackp++ = tab_suffixof(code); + code = tab_prefixof(code); + } + *stackp++ = finchar = tab_suffixof(code); + + /* And put them out in forward order. */ +middle: + if (stackp == de_stack) + continue; + + do { + if (count-- == 0) { + return zs->avail_out; + } + *(zs->next_out)++ = *--stackp; + zs->total_out++; + } while (stackp > de_stack); + + /* Generate the new entry. */ + if ((code = free_ent) < maxmaxcode) { + tab_prefixof(code) = (unsigned short) oldcode; + tab_suffixof(code) = finchar; + free_ent = code + 1; + } + + /* Remember previous code. */ + oldcode = incode; + } + /* state = S_EOF; */ +eof: return (zs->avail_out - count); +} + +/*- + * Read one code from the standard input. If EOF, return -1. + * Inputs: + * stdin + * Outputs: + * code or -1 is returned. + */ +static code_int +getcode(s_zstate_t *zs) +{ + code_int gcode; + int r_off, bits; + char_type *bp; + + bp = gbuf; + if (clear_flg > 0 || roffset >= size || free_ent > maxcode) { + /* + * If the next entry will be too big for the current gcode + * size, then we must increase the size. This implies reading + * a new buffer full, too. + */ + if (free_ent > maxcode) { + n_bits++; + if (n_bits == maxbits) /* Won't get any bigger now. */ + maxcode = maxmaxcode; + else + maxcode = MAXCODE(n_bits); + } + if (clear_flg > 0) { + maxcode = MAXCODE(n_bits = INIT_BITS); + clear_flg = 0; + } + if ( zs->avail_in < (unsigned int)n_bits && in_count > (long)n_bits ) { + memcpy (buf, zs->next_in, zs->avail_in); + buf_len = zs->avail_in; + zs->avail_in = 0; + return -1; + } + if (buf_len) { + memcpy (gbuf, buf, buf_len); + memcpy (gbuf + buf_len, zs->next_in, + n_bits - buf_len); + zs->next_in += n_bits - buf_len; + zs->avail_in -= n_bits - buf_len; + buf_len = 0; + zs->total_in += n_bits; + size = n_bits; + in_count -= n_bits; + } else { + if (in_count > n_bits) { + memcpy (gbuf, zs->next_in, n_bits); + zs->next_in += n_bits; + zs->avail_in -= n_bits; + zs->total_in += n_bits; + size = n_bits; + in_count -= n_bits; + } else { + memcpy (gbuf, zs->next_in, in_count); + zs->next_in += in_count; + zs->avail_in -= in_count; + zs->total_in += in_count; + size = in_count; + in_count = 0; + } + } + roffset = 0; + /* Round size down to integral number of codes. */ + size = (size << 3) - (n_bits - 1); + } + r_off = roffset; + bits = n_bits; + + /* Get to the first byte. */ + bp += (r_off >> 3); + r_off &= 7; + + /* Get first part (low order bits). */ + gcode = (*bp++ >> r_off); + bits -= (8 - r_off); + r_off = 8 - r_off; /* Now, roffset into gcode word. */ + + /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ + if (bits >= 8) { + gcode |= *bp++ << r_off; + r_off += 8; + bits -= 8; + } + + /* High order bits. */ + gcode |= (*bp & rmask[bits]) << r_off; + roffset += n_bits; + + return (gcode); +} + +static void +zinit(s_zstate_t *zs) +{ + memset(zs, 0, sizeof (s_zstate_t)); + + maxbits = BITS; /* User settable max # bits/code. */ + maxmaxcode = 1 << maxbits; /* Should NEVER generate this code. */ + hsize = HSIZE; /* For dynamic table sizing. */ + free_ent = 0; /* First unused entry. */ + block_compress = BLOCK_MASK; + clear_flg = 0; + state = S_START; + roffset = 0; + size = 0; +} Index: xc/extras/freetype2/src/lzw/zopen.h =================================================================== RCS file: xc/extras/freetype2/src/lzw/zopen.h diff -N xc/extras/freetype2/src/lzw/zopen.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/lzw/zopen.h 28 Apr 2004 10:25:50 -0000 @@ -0,0 +1,114 @@ +/* $NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $ */ + +/*- + * Copyright (c) 1985, 1986, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Diomidis Spinellis and James A. Woods, derived from original + * work by Spencer Thomas and Joseph Orost. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*- + * + * Copyright (c) 2004 + * Albert Chin-A-Young. + * + * Modified to work with FreeType's PCF driver. + * + */ + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93"; +#else +static char rcsid[] = "$NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include + +#define BITS 16 /* Default bits. */ +#define HSIZE 69001 /* 95% occupancy */ + +/* A code_int must be able to hold 2**BITS values of type int, and also -1. */ +typedef long code_int; +typedef long count_int; + +typedef unsigned char char_type; + +typedef enum { + S_START, S_MIDDLE, S_EOF +} zs_enum; + +typedef struct { + unsigned char *next_in; + unsigned int avail_in; + unsigned long total_in; + + unsigned char *next_out; + unsigned int avail_out; + unsigned long total_out; + + zs_enum zs_state; /* State of computation */ + int zs_n_bits; /* Number of bits/code. */ + int zs_maxbits; /* User settable max # bits/code. */ + code_int zs_maxcode; /* Maximum code, given n_bits. */ + code_int zs_maxmaxcode; /* Should NEVER generate this code. */ + count_int zs_htab [HSIZE]; + unsigned short zs_codetab [HSIZE]; + code_int zs_hsize; /* For dynamic table sizing. */ + code_int zs_free_ent; /* First unused entry. */ + /* + * Block compression parameters -- after all codes are used up, + * and compression rate changes, start over. + */ + int zs_block_compress; + int zs_clear_flg; + int zs_offset; + long zs_in_count; /* Remaining uncompressed bytes. */ + char_type zs_buf_len; + char_type zs_buf[BITS]; /* Temporary buffer if we need + to read more to accumulate + n_bits. */ + union { + struct { + char_type *zs_stackp; + int zs_finchar; + code_int zs_code, zs_oldcode, zs_incode; + int zs_roffset, zs_size; + char_type zs_gbuf[BITS]; + } r; /* Read parameters */ + } u; +} s_zstate_t; + +static code_int getcode(s_zstate_t *); +#if 0 +static int zclose(s_zstate_t *); +#endif +static void zinit(s_zstate_t *); +static int zread(s_zstate_t *); Index: xc/extras/freetype2/src/pcf/pcfdrivr.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pcf/pcfdrivr.c,v retrieving revision 1.2 diff -u -r1.2 pcfdrivr.c --- a/xc/extras/freetype2/src/pcf/pcfdrivr.c 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/pcf/pcfdrivr.c 28 Apr 2004 10:25:52 -0000 @@ -2,7 +2,7 @@ FreeType font driver for pcf files - Copyright (C) 2000, 2001, 2002, 2003 by + Copyright (C) 2000, 2001, 2002, 2003, 2004 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -31,12 +31,12 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_OBJECTS_H #include FT_GZIP_H +#include FT_LZW_H #include FT_ERRORS_H #include FT_BDF_H #include "pcf.h" #include "pcfdrivr.h" -#include "pcfutil.h" #include "pcfread.h" #include "pcferror.h" @@ -214,7 +214,7 @@ FT_TRACE4(( "PCF_Face_Done: done face\n" )); - /* close gzip stream if any */ + /* close gzip/LZW stream if any */ if ( face->root.stream == &face->gzip_stream ) { FT_Stream_Close( &face->gzip_stream ); @@ -247,21 +247,44 @@ /* this didn't work, try gzip support! */ error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); - if ( error2 == PCF_Err_Unimplemented_Feature ) + if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature ) goto Fail; error = error2; if ( error ) - goto Fail; + { + FT_Error error3; - face->gzip_source = stream; - face->root.stream = &face->gzip_stream; - stream = face->root.stream; + /* this didn't work, try LZW support! */ + error3 = FT_Stream_OpenLZW( &face->gzip_stream, stream ); + if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature ) + goto Fail; - error = pcf_load_font( stream, face ); - if ( error ) - goto Fail; + error = error3; + if ( error ) + goto Fail; + + face->gzip_source = stream; + face->root.stream = &face->gzip_stream; + + stream = face->root.stream; + + error = pcf_load_font( stream, face ); + if ( error ) + goto Fail; + } + else + { + face->gzip_source = stream; + face->root.stream = &face->gzip_stream; + + stream = face->root.stream; + + error = pcf_load_font( stream, face ); + if ( error ) + goto Fail; + } } /* set-up charmap */ @@ -336,9 +359,9 @@ FT_TRACE4(( "rec %d - pres %d\n", size->metrics.y_ppem, - face->root.available_sizes->height )); + face->root.available_sizes->y_ppem >> 6 )); - if ( size->metrics.y_ppem == face->root.available_sizes->height ) + if ( size->metrics.y_ppem == face->root.available_sizes->y_ppem >> 6 ) { size->metrics.ascender = face->accel.fontAscent << 6; size->metrics.descender = face->accel.fontDescent * (-64); @@ -478,7 +501,7 @@ * BDF SERVICE * */ - + static FT_Error pcf_get_bdf_property( PCF_Face face, const char* prop_name, @@ -511,9 +534,21 @@ } - static FT_Service_BDFRec pcf_service_bdf = + static FT_Error + pcf_get_charset_id( PCF_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) { - (FT_BDF_GetCharsetIdFunc)NULL, /* unimplemented ? */ + *acharset_encoding = face->charset_encoding; + *acharset_registry = face->charset_registry; + + return 0; + } + + + static const FT_Service_BDFRec pcf_service_bdf = + { + (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, (FT_BDF_GetPropertyFunc) pcf_get_bdf_property }; @@ -524,14 +559,14 @@ * */ - static FT_ServiceDescRec pcf_services[] = + static const FT_ServiceDescRec pcf_services[] = { { FT_SERVICE_ID_BDF, &pcf_service_bdf }, { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF }, { NULL, NULL } }; - - + + static FT_Module_Interface pcf_driver_requester( FT_Module module, const char* name ) Index: xc/extras/freetype2/src/pcf/pcfread.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pcf/pcfread.c,v retrieving revision 1.2 diff -u -r1.2 pcfread.c --- a/xc/extras/freetype2/src/pcf/pcfread.c 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/pcf/pcfread.c 28 Apr 2004 10:25:52 -0000 @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000, 2001, 2002, 2003 by + Copyright 2000, 2001, 2002, 2003, 2004 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -24,6 +24,7 @@ THE SOFTWARE. */ + #include #include FT_INTERNAL_DEBUG_H @@ -48,7 +49,7 @@ #if defined( FT_DEBUG_LEVEL_TRACE ) - static const char* tableNames[] = + static const char* const tableNames[] = { "prop", "accl", "mtrcs", "bmps", "imtrcs", "enc", "swidth", "names", "accel" @@ -861,6 +862,116 @@ } + static FT_Error + pcf_interpret_style( PCF_Face pcf ) + { + FT_Error error = PCF_Err_Ok; + FT_Face face = FT_FACE( pcf ); + FT_Memory memory = face->memory; + + PCF_Property prop; + + char *istr = NULL, *bstr = NULL; + char *sstr = NULL, *astr = NULL; + + int parts = 0, len = 0; + + + face->style_flags = 0; + + prop = pcf_find_property( pcf, "SLANT" ); + if ( prop && prop->isString && + ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || + *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) + { + face->style_flags |= FT_STYLE_FLAG_ITALIC; + istr = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) + ? (char *)"Oblique" + : (char *)"Italic"; + len += ft_strlen( istr ); + parts++; + } + + prop = pcf_find_property( pcf, "WEIGHT_NAME" ); + if ( prop && prop->isString && + ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) + { + face->style_flags |= FT_STYLE_FLAG_BOLD; + bstr = (char *)"Bold"; + len += ft_strlen( bstr ); + parts++; + } + + prop = pcf_find_property( pcf, "SETWIDTH_NAME" ); + if ( prop && prop->isString && + *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + { + sstr = (char *)(prop->value.atom); + len += ft_strlen( sstr ); + parts++; + } + + prop = pcf_find_property( pcf, "ADD_STYLE_NAME" ); + if ( prop && prop->isString && + *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + { + astr = (char *)(prop->value.atom); + len += ft_strlen( astr ); + parts++; + } + + if ( !parts || !len ) + face->style_name = (char *)"Regular"; + else + { + char *style, *s; + unsigned int i; + + + if ( FT_ALLOC( style, len + parts ) ) + return error; + + s = style; + + if ( astr ) + { + ft_strcpy( s, astr ); + for ( i = 0; i < ft_strlen( astr ); i++, s++ ) + if ( *s == ' ' ) + *s = '-'; /* replace spaces with dashes */ + *(s++) = ' '; + } + if ( bstr ) + { + ft_strcpy( s, bstr ); + s += ft_strlen( bstr ); + *(s++) = ' '; + } + if ( istr ) + { + ft_strcpy( s, istr ); + s += ft_strlen( istr ); + *(s++) = ' '; + } + if ( sstr ) + { + ft_strcpy( s, sstr ); + for ( i = 0; i < ft_strlen( sstr ); i++, s++ ) + if ( *s == ' ' ) + *s = '-'; /* replace spaces with dashes */ + *(s++) = ' '; + } + *(--s) = '\0'; /* overwrite last ' ', terminate the string */ + + face->style_name = style; /* allocated string */ + } + + return error; + } + + FT_LOCAL_DEF( FT_Error ) pcf_load_font( FT_Stream stream, PCF_Face face ) @@ -929,49 +1040,21 @@ if ( face->accel.constantWidth ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - root->style_flags = 0; - prop = pcf_find_property( face, "SLANT" ); - if ( prop != NULL ) - if ( prop->isString ) - if ( ( *(prop->value.atom) == 'O' ) || - ( *(prop->value.atom) == 'o' ) || - ( *(prop->value.atom) == 'I' ) || - ( *(prop->value.atom) == 'i' ) ) - root->style_flags |= FT_STYLE_FLAG_ITALIC; - - prop = pcf_find_property( face, "WEIGHT_NAME" ); - if ( prop != NULL ) - if ( prop->isString ) - if ( ( *(prop->value.atom) == 'B' ) || - ( *(prop->value.atom) == 'b' ) ) - root->style_flags |= FT_STYLE_FLAG_BOLD; - - root->style_name = (char *)"Regular"; - - if ( root->style_flags & FT_STYLE_FLAG_BOLD ) { - if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = (char *)"Bold Italic"; - else - root->style_name = (char *)"Bold"; - } - else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = (char *)"Italic"; + if ( ( error = pcf_interpret_style( face ) ) != 0 ) + goto Exit; prop = pcf_find_property( face, "FAMILY_NAME" ); - if ( prop != NULL ) + if ( prop && prop->isString ) { - if ( prop->isString ) - { - int l = ft_strlen( prop->value.atom ) + 1; + int l = ft_strlen( prop->value.atom ) + 1; - if ( FT_NEW_ARRAY( root->family_name, l ) ) - goto Exit; - ft_strcpy( root->family_name, prop->value.atom ); - } + if ( FT_NEW_ARRAY( root->family_name, l ) ) + goto Exit; + ft_strcpy( root->family_name, prop->value.atom ); } else - root->family_name = 0; + root->family_name = NULL; /* Note: We shift all glyph indices by +1 since we must * respect the convention that glyph 0 always corresponds @@ -987,39 +1070,47 @@ { FT_Bitmap_Size* bsize = root->available_sizes; + FT_Short resolution_x = 0, resolution_y = 0; FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); - prop = pcf_find_property( face, "PIXEL_SIZE" ); - if ( prop != NULL ) - bsize->height = (FT_Short)prop->value.integer; + bsize->height = face->accel.fontAscent + face->accel.fontDescent; prop = pcf_find_property( face, "AVERAGE_WIDTH" ); - if ( prop != NULL ) + if ( prop ) bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 ); + else + bsize->width = bsize->height * 2/3; prop = pcf_find_property( face, "POINT_SIZE" ); - if ( prop != NULL ) - /* convert from 722,7 decipoints to 72 points per inch */ + if ( prop ) + /* convert from 722.7 decipoints to 72 points per inch */ bsize->size = (FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L ); + prop = pcf_find_property( face, "PIXEL_SIZE" ); + if ( prop ) + bsize->y_ppem = (FT_Short)prop->value.integer << 6; + prop = pcf_find_property( face, "RESOLUTION_X" ); - if ( prop != NULL ) - bsize->x_ppem = - (FT_Pos)( ( prop->value.integer * bsize->size + 36 ) / 72 ); + if ( prop ) + resolution_x = (FT_Short)prop->value.integer; prop = pcf_find_property( face, "RESOLUTION_Y" ); - if ( prop != NULL ) - bsize->y_ppem = - (FT_Pos)( ( prop->value.integer * bsize->size + 36 ) / 72 ); - - if ( bsize->height == 0 ) - bsize->height = (FT_Short)( ( bsize->y_ppem + 32 ) / 64 ); + if ( prop ) + resolution_y = (FT_Short)prop->value.integer; - if ( bsize->height == 0 ) - bsize->height = 12; + if ( bsize->y_ppem == 0 ) + { + bsize->y_ppem = bsize->size; + if ( resolution_y ) + bsize->y_ppem = bsize->y_ppem * resolution_y / 72; + } + if ( resolution_x && resolution_y ) + bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + else + bsize->x_ppem = bsize->y_ppem; } /* set up charset */ @@ -1030,23 +1121,19 @@ charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" ); - if ( ( charset_registry != NULL ) && - ( charset_encoding != NULL ) ) + if ( charset_registry && charset_registry->isString && + charset_encoding && charset_encoding->isString ) { - if ( ( charset_registry->isString ) && - ( charset_encoding->isString ) ) - { - if ( FT_NEW_ARRAY( face->charset_encoding, - ft_strlen( charset_encoding->value.atom ) + 1 ) ) - goto Exit; - - if ( FT_NEW_ARRAY( face->charset_registry, - ft_strlen( charset_registry->value.atom ) + 1 ) ) - goto Exit; - - ft_strcpy( face->charset_registry, charset_registry->value.atom ); - ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); - } + if ( FT_NEW_ARRAY( face->charset_encoding, + ft_strlen( charset_encoding->value.atom ) + 1 ) ) + goto Exit; + + if ( FT_NEW_ARRAY( face->charset_registry, + ft_strlen( charset_registry->value.atom ) + 1 ) ) + goto Exit; + + ft_strcpy( face->charset_registry, charset_registry->value.atom ); + ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); } } } Index: xc/extras/freetype2/src/pcf/pcfutil.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pcf/pcfutil.c,v retrieving revision 1.2 diff -u -r1.2 pcfutil.c --- a/xc/extras/freetype2/src/pcf/pcfutil.c 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/pcf/pcfutil.c 28 Apr 2004 10:25:52 -0000 @@ -25,6 +25,8 @@ * Author: Keith Packard, MIT X Consortium */ +/* Modified for use with FreeType */ + #include #include "pcfutil.h" @@ -72,7 +74,7 @@ * Invert bit order within each BYTE of an array. */ - void + static void BitOrderInvert( unsigned char* buf, int nbytes ) { @@ -88,7 +90,7 @@ * Invert byte order within each 16-bits of an array. */ - void + static void TwoByteSwap( unsigned char* buf, int nbytes ) { @@ -107,7 +109,7 @@ * Invert byte order within each 32-bits of an array. */ - void + static void FourByteSwap( unsigned char* buf, int nbytes ) { @@ -127,89 +129,4 @@ } - /* - * Repad a bitmap. - */ - - int - RepadBitmap( char* pSrc, - char* pDst, - unsigned int srcPad, - unsigned int dstPad, - int width, - int height ) - { - int srcWidthBytes, dstWidthBytes; - int row, col; - char *pTmpSrc, *pTmpDst; - - - switch ( srcPad ) - { - case 1: - srcWidthBytes = ( width + 7 ) >> 3; - break; - - case 2: - srcWidthBytes = ( ( width + 15 ) >> 4 ) << 1; - break; - - case 4: - srcWidthBytes = ( ( width + 31 ) >> 5 ) << 2; - break; - - case 8: - srcWidthBytes = ( ( width + 63 ) >> 6 ) << 3; - break; - - default: - return 0; - } - - switch ( dstPad ) - { - case 1: - dstWidthBytes = ( width + 7 ) >> 3; - break; - - case 2: - dstWidthBytes = ( ( width + 15 ) >> 4 ) << 1; - break; - - case 4: - dstWidthBytes = ( ( width + 31 ) >> 5 ) << 2; - break; - - case 8: - dstWidthBytes = ( ( width + 63 ) >> 6 ) << 3; - break; - - default: - return 0; - } - - width = srcWidthBytes; - if ( width > dstWidthBytes ) - width = dstWidthBytes; - - pTmpSrc= pSrc; - pTmpDst= pDst; - - for ( row = 0; row < height; row++ ) - { - for ( col = 0; col < width; col++ ) - *pTmpDst++ = *pTmpSrc++; - - while ( col < dstWidthBytes ) - { - *pTmpDst++ = '\0'; - col++; - } - pTmpSrc += srcWidthBytes - width; - } - - return dstWidthBytes * height; - } - - /* END */ Index: xc/extras/freetype2/src/pcf/pcfutil.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pcf/pcfutil.h,v retrieving revision 1.2 diff -u -r1.2 pcfutil.h --- a/xc/extras/freetype2/src/pcf/pcfutil.h 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/pcf/pcfutil.h 28 Apr 2004 10:25:52 -0000 @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000-2001 by + Copyright 2000, 2001, 2004 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -24,6 +24,7 @@ THE SOFTWARE. */ + #ifndef __PCFUTIL_H__ #define __PCFUTIL_H__ @@ -31,25 +32,18 @@ #include - void + static void BitOrderInvert( unsigned char* buf, int nbytes); - void + static void TwoByteSwap( unsigned char* buf, int nbytes); - void + static void FourByteSwap( unsigned char* buf, int nbytes); - int - RepadBitmap( char* pSrc, - char* pDst, - unsigned int srcPad, - unsigned int dstPad, - int width, - int height); #endif /* __PCFUTIL_H__ */ Index: xc/extras/freetype2/src/pfr/pfrdrivr.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pfr/pfrdrivr.c,v retrieving revision 1.2 diff -u -r1.2 pfrdrivr.c --- a/xc/extras/freetype2/src/pfr/pfrdrivr.c 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/pfr/pfrdrivr.c 28 Apr 2004 10:25:53 -0000 @@ -26,6 +26,7 @@ #include "pfrerror.h" + static FT_Error pfr_get_kerning( PFR_Face face, FT_UInt left, @@ -52,28 +53,29 @@ return PFR_Err_Ok; } + /* * PFR METRICS SERVICE * */ static FT_Error - pfr_get_advance( PFR_Face face, - FT_UInt gindex, - FT_Pos *aadvance ) + pfr_get_advance( PFR_Face face, + FT_UInt gindex, + FT_Pos *anadvance ) { FT_Error error = PFR_Err_Bad_Argument; - *aadvance = 0; + *anadvance = 0; if ( face ) { - PFR_PhyFont phys = &face->phy_font; + PFR_PhyFont phys = &face->phy_font; if ( gindex < phys->num_chars ) { - *aadvance = phys->chars[ gindex ].advance; + *anadvance = phys->chars[gindex].advance; error = 0; } } @@ -84,18 +86,18 @@ static FT_Error pfr_get_metrics( PFR_Face face, - FT_UInt *aoutline_resolution, + FT_UInt *anoutline_resolution, FT_UInt *ametrics_resolution, FT_Fixed *ametrics_x_scale, FT_Fixed *ametrics_y_scale ) { - PFR_PhyFont phys = &face->phy_font; + PFR_PhyFont phys = &face->phy_font; FT_Fixed x_scale, y_scale; FT_Size size = face->root.size; - if ( aoutline_resolution ) - *aoutline_resolution = phys->outline_resolution; + if ( anoutline_resolution ) + *anoutline_resolution = phys->outline_resolution; if ( ametrics_resolution ) *ametrics_resolution = phys->metrics_resolution; @@ -118,7 +120,7 @@ if ( ametrics_y_scale ) *ametrics_y_scale = y_scale; - return 0; + return PFR_Err_Ok; } @@ -130,6 +132,7 @@ (FT_PFR_GetAdvanceFunc)pfr_get_advance }; + /* * SERVICE LIST * @@ -137,7 +140,7 @@ static const FT_ServiceDescRec pfr_services[] = { - { FT_SERVICE_ID_PFR_METRICS, & pfr_metrics_service_rec }, + { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PFR }, { NULL, NULL } }; @@ -177,20 +180,20 @@ sizeof( PFR_SizeRec ), sizeof( PFR_SlotRec ), - (FT_Face_InitFunc) pfr_face_init, - (FT_Face_DoneFunc) pfr_face_done, - (FT_Size_InitFunc) NULL, - (FT_Size_DoneFunc) NULL, - (FT_Slot_InitFunc) pfr_slot_init, - (FT_Slot_DoneFunc) pfr_slot_done, - - (FT_Size_ResetPointsFunc) NULL, - (FT_Size_ResetPixelsFunc) NULL, - (FT_Slot_LoadFunc) pfr_slot_load, - - (FT_Face_GetKerningFunc) pfr_get_kerning, - (FT_Face_AttachFunc) 0, - (FT_Face_GetAdvancesFunc) 0 + (FT_Face_InitFunc) pfr_face_init, + (FT_Face_DoneFunc) pfr_face_done, + (FT_Size_InitFunc) NULL, + (FT_Size_DoneFunc) NULL, + (FT_Slot_InitFunc) pfr_slot_init, + (FT_Slot_DoneFunc) pfr_slot_done, + + (FT_Size_ResetPointsFunc)NULL, + (FT_Size_ResetPixelsFunc)NULL, + (FT_Slot_LoadFunc) pfr_slot_load, + + (FT_Face_GetKerningFunc) pfr_get_kerning, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc)0 }; Index: xc/extras/freetype2/src/pfr/pfrgload.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pfr/pfrgload.c,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 pfrgload.c --- a/xc/extras/freetype2/src/pfr/pfrgload.c 25 Nov 2003 19:27:22 -0000 1.1.1.2 +++ b/xc/extras/freetype2/src/pfr/pfrgload.c 28 Apr 2004 10:25:53 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType PFR glyph loader (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -198,7 +198,7 @@ /* indicate that a new contour has started */ glyph->path_begun = 1; - /* check that there is room for a new contour and a new point */ + /* check that there is space for a new contour and a new point */ error = FT_GlyphLoader_CheckPoints( loader, 1, 1 ); if ( !error ) /* add new start point */ @@ -276,7 +276,7 @@ /* re-allocate array when necessary */ if ( count > glyph->max_xy_control ) { - FT_UInt new_max = ( count + 7 ) & -8; + FT_UInt new_max = FT_PAD_CEIL( count, 8 ); if ( FT_RENEW_ARRAY( glyph->x_control, Index: xc/extras/freetype2/src/pfr/pfrload.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pfr/pfrload.c,v retrieving revision 1.2 diff -u -r1.2 pfrload.c --- a/xc/extras/freetype2/src/pfr/pfrload.c 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/pfr/pfrload.c 28 Apr 2004 10:25:54 -0000 @@ -365,7 +365,7 @@ /* re-allocate when needed */ if ( phy_font->num_strikes + count > phy_font->max_strikes ) { - FT_UInt new_max = ( phy_font->num_strikes + count + 3 ) & -4; + FT_UInt new_max = FT_PAD_CEIL( phy_font->num_strikes + count, 4 ); if ( FT_RENEW_ARRAY( phy_font->strikes, Index: xc/extras/freetype2/src/pfr/pfrobjs.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pfr/pfrobjs.c,v retrieving revision 1.2 diff -u -r1.2 pfrobjs.c --- a/xc/extras/freetype2/src/pfr/pfrobjs.c 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/pfr/pfrobjs.c 28 Apr 2004 10:25:54 -0000 @@ -15,6 +15,7 @@ /* */ /***************************************************************************/ + #include "pfrobjs.h" #include "pfrload.h" #include "pfrgload.h" Index: xc/extras/freetype2/src/pfr/pfrsbit.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pfr/pfrsbit.c,v retrieving revision 1.2 diff -u -r1.2 pfrsbit.c --- a/xc/extras/freetype2/src/pfr/pfrsbit.c 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/pfr/pfrsbit.c 28 Apr 2004 10:25:55 -0000 @@ -635,7 +635,7 @@ glyph->root.metrics.height = (FT_Long)ysize << 6; glyph->root.metrics.horiBearingX = xpos << 6; glyph->root.metrics.horiBearingY = ypos << 6; - glyph->root.metrics.horiAdvance = ( ( advance >> 2 ) + 32 ) & -64; + glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) ); glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1; glyph->root.metrics.vertBearingY = 0; glyph->root.metrics.vertAdvance = size->root.metrics.height; Index: xc/extras/freetype2/src/psaux/psobjs.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/psaux/psobjs.c,v retrieving revision 1.2 diff -u -r1.2 psobjs.c --- a/xc/extras/freetype2/src/psaux/psobjs.c 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/psaux/psobjs.c 28 Apr 2004 10:25:56 -0000 @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -142,7 +142,7 @@ /* table :: The target table. */ /* */ /* */ - /* idx :: The index of the object in the table. */ + /* idx :: The index of the object in the table. */ /* */ /* object :: The address of the object to copy in memory. */ /* */ @@ -181,7 +181,7 @@ /* increase size by 25% and round up to the nearest multiple of 1024 */ new_size += ( new_size >> 2 ) + 1; - new_size = ( new_size + 1023 ) & -1024; + new_size = FT_PAD_CEIL( new_size, 1024 ); } error = reallocate_t1_table( table, new_size ); @@ -285,7 +285,7 @@ #if 'A' == 65 /* ASCII */ - char ft_char_table[128] = + static const char ft_char_table[128] = { /* 0x00 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -306,7 +306,7 @@ #if 'A' == 193 /* EBCDIC */ - char ft_char_table[128] = + static const char ft_char_table[128] = { /* 0x80 */ -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, @@ -688,9 +688,9 @@ /* first character must be already part of the number */ static FT_Long - T1Radix( FT_Long radixBase, - FT_Byte* *acur, - FT_Byte* limit ) + ps_radix( FT_Long radixBase, + FT_Byte* *acur, + FT_Byte* limit ) { FT_Long result = 0; FT_Byte* cur = *acur; @@ -716,6 +716,8 @@ cur++; } + *acur = cur; + return result; } @@ -746,7 +748,7 @@ if ( *cur == '#' ) { cur++; - result = T1Radix( result, &cur, limit ); + result = ps_radix( result, &cur, limit ); break; } @@ -1280,10 +1282,6 @@ if ( cur >= limit ) break; - /* with synthetic fonts, it is possible to find a field twice */ - if ( *(FT_String**)q ) - break; - if ( field->type == T1_FIELD_TYPE_KEY ) { /* don't include leading `/' */ @@ -1359,7 +1357,7 @@ T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS]; T1_Token token; FT_Int num_elements; - FT_Error error = 0; + FT_Error error = PSaux_Err_Ok; FT_Byte* old_cursor; FT_Byte* old_limit; T1_FieldRec fieldrec = *(T1_Field)field; @@ -1374,8 +1372,10 @@ ps_parser_to_token_array( parser, elements, T1_MAX_TABLE_ELEMENTS, &num_elements ); if ( num_elements < 0 ) - goto Fail; - + { + error = PSaux_Err_Ignore; + goto Exit; + } if ( num_elements > T1_MAX_TABLE_ELEMENTS ) num_elements = T1_MAX_TABLE_ELEMENTS; @@ -1408,10 +1408,6 @@ Exit: return error; - - Fail: - error = PSaux_Err_Invalid_File_Format; - goto Exit; } @@ -1670,7 +1666,7 @@ } - /* check room for a new contour, then add it */ + /* check space for a new contour, then add it */ FT_LOCAL_DEF( FT_Error ) t1_builder_add_contour( T1_Builder builder ) { Index: xc/extras/freetype2/src/psaux/t1decode.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/psaux/t1decode.c,v retrieving revision 1.2 diff -u -r1.2 t1decode.c --- a/xc/extras/freetype2/src/psaux/t1decode.c 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/psaux/t1decode.c 28 Apr 2004 10:25:57 -0000 @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -262,10 +262,6 @@ if ( error ) goto Exit; -#if 0 - n_base_points = base->n_points; -#endif - /* save the left bearing and width of the base character */ /* as they will be erased by the next load. */ @@ -290,23 +286,8 @@ decoder->builder.left_bearing = left_bearing; decoder->builder.advance = advance; - /* XXX: old code doesn't work with PostScript hinter */ -#if 0 - /* Finally, move the accent */ - if ( decoder->builder.load_points ) - { - FT_Outline dummy; - - - dummy.n_points = (short)( base->n_points - n_base_points ); - dummy.points = base->points + n_base_points; - - FT_Outline_Translate( &dummy, adx - asb, ady ); - } -#else decoder->builder.pos_x = 0; decoder->builder.pos_y = 0; -#endif Exit: return error; Index: xc/extras/freetype2/src/pshinter/Jamfile =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pshinter/Jamfile,v retrieving revision 1.2 diff -u -r1.2 Jamfile --- a/xc/extras/freetype2/src/pshinter/Jamfile 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/pshinter/Jamfile 28 Apr 2004 10:25:57 -0000 @@ -1,4 +1,4 @@ -# FreeType 2 src/pshinter Jamfile (c) 2001 David Turner +# FreeType 2 src/pshinter Jamfile (c) 2001, 2003 David Turner # SubDir FT2_TOP $(FT2_SRC_DIR) pshinter ; Index: xc/extras/freetype2/src/pshinter/pshalgo.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pshinter/pshalgo.c,v retrieving revision 1.2 diff -u -r1.2 pshalgo.c --- a/xc/extras/freetype2/src/pshinter/pshalgo.c 23 Apr 2004 18:42:50 -0000 1.2 +++ b/xc/extras/freetype2/src/pshinter/pshalgo.c 28 Apr 2004 10:25:58 -0000 @@ -2,9 +2,9 @@ /* */ /* pshalgo.c */ /* */ -/* PostScript hinting algorithm 3 (body). */ +/* PostScript hinting algorithm (body). */ /* */ -/* Copyright 2001, 2002, 2003 by */ +/* Copyright 2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -35,8 +35,11 @@ #endif -#define COMPUTE_INFLEXS /* compute inflection points to optimize "S" and others */ -#define STRONGER /* slightly increase the contrast of smooth hinting */ +#define COMPUTE_INFLEXS /* compute inflection points to optimize `S' */ + /* and similar glyphs */ +#define STRONGER /* slightly increase the contrast of smooth */ + /* hinting */ + /*************************************************************************/ /*************************************************************************/ @@ -46,13 +49,13 @@ /*************************************************************************/ /*************************************************************************/ - /* return true iff two stem hints overlap */ + /* return true if two stem hints overlap */ static FT_Int psh_hint_overlap( PSH_Hint hint1, PSH_Hint hint2 ) { - return ( hint1->org_pos + hint1->org_len >= hint2->org_pos && - hint2->org_pos + hint2->org_len >= hint1->org_pos ); + return hint1->org_pos + hint1->org_len >= hint2->org_pos && + hint2->org_pos + hint2->org_len >= hint1->org_pos; } @@ -89,7 +92,7 @@ } - /* internal function used to record a new hint */ + /* internal function to record a new hint */ static void psh_hint_table_record( PSH_Hint_Table table, FT_UInt idx ) @@ -109,8 +112,8 @@ psh_hint_activate( hint ); - /* now scan the current active hint set in order to determine */ - /* if we are overlapping with another segment */ + /* now scan the current active hint set to check */ + /* whether `hint' overlaps with another hint */ { PSH_Hint* sorted = table->sort_global; FT_UInt count = table->num_hints; @@ -172,12 +175,14 @@ PS_Mask_Table counter_masks, FT_Memory memory ) { - FT_UInt count = hints->num_hints; + FT_UInt count; FT_Error error; FT_UNUSED( counter_masks ); + count = hints->num_hints; + /* allocate our tables */ if ( FT_NEW_ARRAY( table->sort, 2 * count ) || FT_NEW_ARRAY( table->hints, count ) || @@ -190,7 +195,7 @@ table->num_zones = 0; table->zone = 0; - /* now, initialize the "hints" array */ + /* initialize the `table->hints' array */ { PSH_Hint write = table->hints; PS_Hint read = hints->hints; @@ -204,30 +209,31 @@ } } - /* we now need to determine the initial "parent" stems; first */ + /* we now need to determine the initial `parent' stems; first */ /* activate the hints that are given by the initial hint masks */ if ( hint_masks ) { - FT_UInt Count = hint_masks->num_masks; - PS_Mask Mask = hint_masks->masks; + PS_Mask mask = hint_masks->masks; + count = hint_masks->num_masks; table->hint_masks = hint_masks; - for ( ; Count > 0; Count--, Mask++ ) - psh_hint_table_record_mask( table, Mask ); + for ( ; count > 0; count--, mask++ ) + psh_hint_table_record_mask( table, mask ); } - /* now, do a linear parse in case some hints were left alone */ + /* finally, do a linear parse in case some hints were left alone */ if ( table->num_hints != table->max_hints ) { - FT_UInt Index, Count; + FT_UInt idx; FT_ERROR(( "psh_hint_table_init: missing/incorrect hint masks!\n" )); - Count = table->max_hints; - for ( Index = 0; Index < Count; Index++ ) - psh_hint_table_record( table, Index ); + + count = table->max_hints; + for ( idx = 0; idx < count; idx++ ) + psh_hint_table_record( table, idx ); } Exit: @@ -375,11 +381,11 @@ len += delta; } else - len = ( len + 32 ) & -64; + len = FT_PIX_ROUND( len ); } if ( do_snapping ) - len = ( len + 32 ) & -64; + len = FT_PIX_ROUND( len ); return len; } @@ -417,11 +423,11 @@ psh_hint_snap_stem_side_delta( FT_Fixed pos, FT_Fixed len ) { - FT_Fixed delta1 = ( ( pos + 32 ) & -64 ) - pos; - FT_Fixed delta2 = ( ( pos + len + 32 ) & -64 ) - pos - len; + FT_Fixed delta1 = FT_PIX_ROUND( pos ) - pos; + FT_Fixed delta2 = FT_PIX_ROUND( pos + len ) - pos - len; - if ( ABS( delta1 ) <= ABS( delta2 ) ) + if ( FT_ABS( delta1 ) <= FT_ABS( delta2 ) ) return delta1; else return delta2; @@ -511,6 +517,9 @@ if ( !psh_hint_is_fitted( parent ) ) psh_hint_align( parent, globals, dimension, glyph ); + /* keep original relation between hints, this is, use the */ + /* scaled distance between the centers of the hints to */ + /* compute the new position */ par_org_center = parent->org_pos + ( parent->org_len >> 1 ); par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 ); cur_org_center = hint->org_pos + ( hint->org_len >> 1 ); @@ -534,10 +543,10 @@ * around the nearest pixel center */ #if 1 - pos = ( pos + ( len >> 1 ) ) & -64; + pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ); #else /* this seems to be a bug! */ - pos = ( pos + ( ( len >> 1 ) & -64 ) ); + pos = pos + FT_PIX_FLOOR( len >> 1 ); #endif len = 64; } @@ -562,7 +571,7 @@ if ( len < 64 ) len = 64; else - len = ( len + 32 ) & -64; + len = FT_PIX_ROUND( len ); switch ( align.align ) { @@ -583,9 +592,9 @@ default: hint->cur_len = len; if ( len & 64 ) - pos = ( ( pos + ( len >> 1 ) ) & -64 ) + 32; + pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ) + 32; else - pos = ( pos + ( len >> 1 ) + 32 ) & -64; + pos = FT_PIX_ROUND( pos + ( len >> 1 ) ); hint->cur_pos = pos - ( len >> 1 ); hint->cur_len = len; @@ -739,13 +748,13 @@ if ( ( len / 64 ) & 1 ) { - delta_a = ( center & -64 ) + 32 - center; - delta_b = ( ( center + 32 ) & - 64 ) - center; + delta_a = FT_PIX_FLOOR( center ) + 32 - center; + delta_b = FT_PIX_ROUND( center ) - center; } else { - delta_a = ( ( center + 32 ) & - 64 ) - center; - delta_b = ( center & -64 ) + 32 - center; + delta_a = FT_PIX_ROUND( center ) - center; + delta_b = FT_PIX_FLOOR( center ) + 32 - center; } /* We choose between B) and C) above based on the amount @@ -762,8 +771,7 @@ FT_Fixed side_delta = psh_hint_snap_stem_side_delta ( pos, len ); - - if ( ABS( side_delta ) < ABS( delta_b ) ) + if ( FT_ABS( side_delta ) < FT_ABS( delta_b ) ) pos += side_delta; else pos += delta_b; @@ -1111,7 +1119,7 @@ /* clear all fields */ FT_MEM_ZERO( glyph, sizeof ( *glyph ) ); - memory = globals->memory; + memory = glyph->memory = globals->memory; /* allocate and setup points + contours arrays */ if ( FT_NEW_ARRAY( glyph->points, outline->n_points ) || @@ -1218,7 +1226,6 @@ } } - glyph->memory = memory; glyph->outline = outline; glyph->globals = globals; @@ -1323,8 +1330,8 @@ ; } - /* for each extrema, determine its direction along the */ - /* orthogonal axis */ + /* for each extremum, determine its direction along the */ + /* orthogonal axis */ for ( n = 0; n < glyph->num_points; n++ ) { PSH_Point point, before, after; @@ -1370,9 +1377,6 @@ } -#define PSH_STRONG_THRESHOLD 30 - - /* major_dir is the direction for points on the bottom/left of the stem; */ /* Points on the top/right of the stem will have a direction of */ /* -major_dir. */ @@ -1380,6 +1384,7 @@ static void psh_hint_table_find_strong_point( PSH_Hint_Table table, PSH_Point point, + FT_Int threshold, FT_Int major_dir ) { PSH_Hint* sort = table->sort; @@ -1409,7 +1414,7 @@ flag = PSH_POINT_EDGE_MIN; d = point->org_u - hint->org_pos; - if ( ABS( d ) < PSH_STRONG_THRESHOLD ) + if ( FT_ABS( d ) < threshold ) { Is_Strong: psh_point_set_strong( point ); @@ -1423,7 +1428,7 @@ flag = PSH_POINT_EDGE_MAX; d = point->org_u - hint->org_pos - hint->org_len; - if ( ABS( d ) < PSH_STRONG_THRESHOLD ) + if ( FT_ABS( d ) < threshold ) goto Is_Strong; } } @@ -1459,7 +1464,7 @@ flag = PSH_POINT_EDGE_MIN; d = point->org_u - hint->org_pos; - if ( ABS( d ) < PSH_STRONG_THRESHOLD ) + if ( FT_ABS( d ) < threshold ) { Is_Strong2: point->flags2 |= flag; @@ -1473,7 +1478,7 @@ flag = PSH_POINT_EDGE_MAX; d = point->org_u - hint->org_pos - hint->org_len; - if ( ABS( d ) < PSH_STRONG_THRESHOLD ) + if ( FT_ABS( d ) < threshold ) goto Is_Strong2; } @@ -1489,74 +1494,165 @@ } + /* the accepted shift for strong points in fractional pixels */ +#define PSH_STRONG_THRESHOLD 32 + + /* the maximum shift value in font units */ +#define PSH_STRONG_THRESHOLD_MAXIMUM 30 + + /* find strong points in a glyph */ static void psh_glyph_find_strong_points( PSH_Glyph glyph, FT_Int dimension ) { - /* a point is strong if it is located on a stem */ - /* edge and has an "in" or "out" tangent to the hint's direction */ - { - PSH_Hint_Table table = &glyph->hint_tables[dimension]; - PS_Mask mask = table->hint_masks->masks; - FT_UInt num_masks = table->hint_masks->num_masks; - FT_UInt first = 0; - FT_Int major_dir = dimension == 0 ? PSH_DIR_VERTICAL - : PSH_DIR_HORIZONTAL; + /* a point is `strong' if it is located on a stem edge and */ + /* has an `in' or `out' tangent parallel to the hint's direction */ + PSH_Hint_Table table = &glyph->hint_tables[dimension]; + PS_Mask mask = table->hint_masks->masks; + FT_UInt num_masks = table->hint_masks->num_masks; + FT_UInt first = 0; + FT_Int major_dir = dimension == 0 ? PSH_DIR_VERTICAL + : PSH_DIR_HORIZONTAL; + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Int threshold; - /* process secondary hints to "selected" points */ - if ( num_masks > 1 && glyph->num_points > 0 ) + + threshold = (FT_Int)FT_DivFix( PSH_STRONG_THRESHOLD, scale ); + if ( threshold > PSH_STRONG_THRESHOLD_MAXIMUM ) + threshold = PSH_STRONG_THRESHOLD_MAXIMUM; + + /* process secondary hints to `selected' points */ + if ( num_masks > 1 && glyph->num_points > 0 ) + { + first = mask->end_point; + mask++; + for ( ; num_masks > 1; num_masks--, mask++ ) { - first = mask->end_point; - mask++; - for ( ; num_masks > 1; num_masks--, mask++ ) - { - FT_UInt next; - FT_Int count; + FT_UInt next; + FT_Int count; - next = mask->end_point; - count = next - first; - if ( count > 0 ) - { - PSH_Point point = glyph->points + first; + next = mask->end_point; + count = next - first; + if ( count > 0 ) + { + PSH_Point point = glyph->points + first; - psh_hint_table_activate_mask( table, mask ); + psh_hint_table_activate_mask( table, mask ); - for ( ; count > 0; count--, point++ ) - psh_hint_table_find_strong_point( table, point, major_dir ); - } - first = next; + for ( ; count > 0; count--, point++ ) + psh_hint_table_find_strong_point( table, point, + threshold, major_dir ); } + first = next; } + } - /* process primary hints for all points */ - if ( num_masks == 1 ) + /* process primary hints for all points */ + if ( num_masks == 1 ) + { + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; + + + psh_hint_table_activate_mask( table, table->hint_masks->masks ); + for ( ; count > 0; count--, point++ ) { - FT_UInt count = glyph->num_points; - PSH_Point point = glyph->points; + if ( !psh_point_is_strong( point ) ) + psh_hint_table_find_strong_point( table, point, + threshold, major_dir ); + } + } + /* now, certain points may have been attached to a hint and */ + /* not marked as strong; update their flags then */ + { + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; - psh_hint_table_activate_mask( table, table->hint_masks->masks ); - for ( ; count > 0; count--, point++ ) - { - if ( !psh_point_is_strong( point ) ) - psh_hint_table_find_strong_point( table, point, major_dir ); - } + + for ( ; count > 0; count--, point++ ) + if ( point->hint && !psh_point_is_strong( point ) ) + psh_point_set_strong( point ); + } + } + + + /* find points in a glyph which are in a blue zone and have `in' or */ + /* `out' tangents parallel to the horizontal axis */ + static void + psh_glyph_find_blue_points( PSH_Blues blues, + PSH_Glyph glyph ) + { + PSH_Blue_Table table; + PSH_Blue_Zone zone; + FT_UInt glyph_count = glyph->num_points; + FT_UInt blue_count; + PSH_Point point = glyph->points; + + + for ( ; glyph_count > 0; glyph_count--, point++ ) + { + FT_Pos y; + + + /* check tangents */ + if ( !PSH_DIR_COMPARE( point->dir_in, PSH_DIR_HORIZONTAL ) && + !PSH_DIR_COMPARE( point->dir_out, PSH_DIR_HORIZONTAL ) ) + continue; + + /* skip strong points */ + if ( psh_point_is_strong( point ) ) + continue; + + y = point->org_u; + + /* look up top zones */ + table = &blues->normal_top; + blue_count = table->count; + zone = table->zones; + + for ( ; blue_count > 0; blue_count--, zone++ ) + { + FT_Pos delta = y - zone->org_bottom; + + + if ( delta < -blues->blue_fuzz ) + break; + + if ( y <= zone->org_top + blues->blue_fuzz ) + if ( blues->no_overshoots || delta <= blues->blue_threshold ) + { + point->cur_u = zone->cur_bottom; + psh_point_set_strong( point ); + psh_point_set_fitted( point ); + } } - /* now, certain points may have been attached to hint and */ - /* not marked as strong; update their flags then */ + /* look up bottom zones */ + table = &blues->normal_bottom; + blue_count = table->count; + zone = table->zones + blue_count - 1; + + for ( ; blue_count > 0; blue_count--, zone-- ) { - FT_UInt count = glyph->num_points; - PSH_Point point = glyph->points; + FT_Pos delta = zone->org_top - y; - for ( ; count > 0; count--, point++ ) - if ( point->hint && !psh_point_is_strong( point ) ) + if ( delta < -blues->blue_fuzz ) + break; + + if ( y >= zone->org_bottom - blues->blue_fuzz ) + if ( blues->no_overshoots || delta < blues->blue_threshold ) + { + point->cur_u = zone->cur_top; psh_point_set_strong( point ); + psh_point_set_fitted( point ); + } } } } @@ -1570,50 +1666,45 @@ PSH_Dimension dim = &glyph->globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; + + for ( ; count > 0; count--, point++ ) { - FT_UInt count = glyph->num_points; - PSH_Point point = glyph->points; + PSH_Hint hint = point->hint; - for ( ; count > 0; count--, point++ ) + if ( hint ) { - PSH_Hint hint = point->hint; + FT_Pos delta; - if ( hint ) - { - FT_Pos delta; + if ( psh_point_is_edge_min( point ) ) + point->cur_u = hint->cur_pos; + else if ( psh_point_is_edge_max( point ) ) + point->cur_u = hint->cur_pos + hint->cur_len; - if ( psh_point_is_edge_min( point ) ) - { - point->cur_u = hint->cur_pos; - } - else if ( psh_point_is_edge_max( point ) ) - { - point->cur_u = hint->cur_pos + hint->cur_len; - } - else - { - delta = point->org_u - hint->org_pos; + else + { + delta = point->org_u - hint->org_pos; - if ( delta <= 0 ) - point->cur_u = hint->cur_pos + FT_MulFix( delta, scale ); + if ( delta <= 0 ) + point->cur_u = hint->cur_pos + FT_MulFix( delta, scale ); - else if ( delta >= hint->org_len ) - point->cur_u = hint->cur_pos + hint->cur_len + - FT_MulFix( delta - hint->org_len, scale ); - - else if ( hint->org_len > 0 ) - point->cur_u = hint->cur_pos + - FT_MulDiv( delta, hint->cur_len, - hint->org_len ); - else - point->cur_u = hint->cur_pos; - } - psh_point_set_fitted( point ); + else if ( delta >= hint->org_len ) + point->cur_u = hint->cur_pos + hint->cur_len + + FT_MulFix( delta - hint->org_len, scale ); + + else if ( hint->org_len > 0 ) + point->cur_u = hint->cur_pos + + FT_MulDiv( delta, hint->cur_len, + hint->org_len ); + else + point->cur_u = hint->cur_pos; } + psh_point_set_fitted( point ); } } } @@ -1625,109 +1716,107 @@ { #if 1 + /* first technique: a point is strong if it is a local extremum */ PSH_Dimension dim = &glyph->globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; - /* first technique: a point is strong if it is a local extrema */ - { - FT_UInt count = glyph->num_points; - PSH_Point point = glyph->points; + for ( ; count > 0; count--, point++ ) + { + if ( psh_point_is_strong( point ) ) + continue; - for ( ; count > 0; count--, point++ ) + /* sometimes, some local extrema are smooth points */ + if ( psh_point_is_smooth( point ) ) { - if ( psh_point_is_strong( point ) ) + if ( point->dir_in == PSH_DIR_NONE || + point->dir_in != point->dir_out ) continue; - /* sometimes, some local extremas are smooth points */ - if ( psh_point_is_smooth( point ) ) - { - if ( point->dir_in == PSH_DIR_NONE || - point->dir_in != point->dir_out ) - continue; - - if ( !psh_point_is_extremum( point ) && - !psh_point_is_inflex( point ) ) - continue; + if ( !psh_point_is_extremum( point ) && + !psh_point_is_inflex( point ) ) + continue; - point->flags &= ~PSH_POINT_SMOOTH; - } + point->flags &= ~PSH_POINT_SMOOTH; + } - /* find best enclosing point coordinates */ - { - PSH_Point before = 0; - PSH_Point after = 0; + /* find best enclosing point coordinates */ + { + PSH_Point before = 0; + PSH_Point after = 0; - FT_Pos diff_before = -32000; - FT_Pos diff_after = 32000; - FT_Pos u = point->org_u; + FT_Pos diff_before = -32000; + FT_Pos diff_after = 32000; + FT_Pos u = point->org_u; - FT_Int count2 = glyph->num_points; - PSH_Point cur = glyph->points; + FT_Int count2 = glyph->num_points; + PSH_Point cur = glyph->points; - for ( ; count2 > 0; count2--, cur++ ) + for ( ; count2 > 0; count2--, cur++ ) + { + if ( psh_point_is_strong( cur ) ) { - if ( psh_point_is_strong( cur ) ) - { - FT_Pos diff = cur->org_u - u;; + FT_Pos diff = cur->org_u - u; - if ( diff <= 0 ) + if ( diff <= 0 ) + { + if ( diff > diff_before ) { - if ( diff > diff_before ) - { - diff_before = diff; - before = cur; - } + diff_before = diff; + before = cur; } - else if ( diff >= 0 ) + } + + else if ( diff >= 0 ) + { + if ( diff < diff_after ) { - if ( diff < diff_after ) - { - diff_after = diff; - after = cur; - } + diff_after = diff; + after = cur; } } } + } - if ( !before ) - { - if ( !after ) - continue; + if ( !before ) + { + if ( !after ) + continue; - /* we are before the first strong point coordinate; */ - /* simply translate the point */ - point->cur_u = after->cur_u + + /* we are before the first strong point coordinate; */ + /* simply translate the point */ + point->cur_u = after->cur_u + FT_MulFix( point->org_u - after->org_u, scale ); - } - else if ( !after ) - { - /* we are after the last strong point coordinate; */ - /* simply translate the point */ - point->cur_u = before->cur_u + + } + else if ( !after ) + { + /* we are after the last strong point coordinate; */ + /* simply translate the point */ + point->cur_u = before->cur_u + FT_MulFix( point->org_u - before->org_u, scale ); - } - else - { - if ( diff_before == 0 ) - point->cur_u = before->cur_u; + } + else + { + if ( diff_before == 0 ) + point->cur_u = before->cur_u; - else if ( diff_after == 0 ) - point->cur_u = after->cur_u; + else if ( diff_after == 0 ) + point->cur_u = after->cur_u; - else - point->cur_u = before->cur_u + + 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 ); - } - - psh_point_set_fitted( point ); } + + psh_point_set_fitted( point ); } } @@ -1940,7 +2029,7 @@ scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale ); - fitted = ( scaled + 32 ) & -64; + fitted = FT_PIX_ROUND( scaled ); if (scaled != fitted ) { y_scale = FT_MulDiv( y_scale, fitted, scaled ); @@ -1979,6 +2068,8 @@ /* find strong points, align them, then interpolate others */ psh_glyph_find_strong_points( glyph, dimension ); + if ( dimension == 1 ) + psh_glyph_find_blue_points( &globals->blues, glyph ); psh_glyph_interpolate_strong_points( glyph, dimension ); psh_glyph_interpolate_normal_points( glyph, dimension ); psh_glyph_interpolate_other_points( glyph, dimension ); Index: xc/extras/freetype2/src/pshinter/pshglob.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pshinter/pshglob.c,v retrieving revision 1.2 diff -u -r1.2 pshglob.c --- a/xc/extras/freetype2/src/pshinter/pshglob.c 23 Apr 2004 18:42:51 -0000 1.2 +++ b/xc/extras/freetype2/src/pshinter/pshglob.c 28 Apr 2004 10:25:59 -0000 @@ -5,7 +5,7 @@ /* PostScript hinter global hinting management (body). */ /* Inspired by the new auto-hinter module. */ /* */ -/* Copyright 2001, 2002, 2003 by */ +/* Copyright 2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -52,7 +52,7 @@ if ( count > 0 ) { width->cur = FT_MulFix( width->org, scale ); - width->fit = FT_RoundFix( width->cur ); + width->fit = FT_PIX_ROUND( width->cur ); width++; count--; @@ -72,7 +72,7 @@ w = stand->cur; width->cur = w; - width->fit = FT_RoundFix( w ); + width->fit = FT_PIX_ROUND( w ); } } } @@ -377,7 +377,7 @@ /* parameter to the raw bluescale value. Here is why: */ /* */ /* We need to suppress overshoots for all pointsizes. */ - /* At 300dpi that satisfy: */ + /* At 300dpi that satisfies: */ /* */ /* pointsize < 240*bluescale + 0.49 */ /* */ @@ -396,7 +396,16 @@ /* */ /* "scale < bluescale" */ /* */ - blues->no_overshoots = FT_BOOL( scale < blues->blue_scale ); + /* Note that `blue_scale' is stored 1000 times its real */ + /* value, and that `scale' converts from font units to */ + /* fractional pixels. */ + /* */ + + /* 1000 / 64 = 125 / 8 */ + if ( scale >= 0x20C49BAL ) + blues->no_overshoots = FT_BOOL( scale < blues->blue_scale * 8 / 125 ); + else + blues->no_overshoots = FT_BOOL( scale * 125 < blues->blue_scale * 8 ); /* */ /* The blue threshold is the font units distance under */ @@ -412,7 +421,7 @@ while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 ) - threshold --; + threshold--; blues->blue_threshold = threshold; } @@ -448,7 +457,7 @@ zone->cur_delta = FT_MulFix( zone->org_delta, scale ); /* round scaled reference position */ - zone->cur_ref = ( zone->cur_ref + 32 ) & -64; + zone->cur_ref = FT_PIX_ROUND( zone->cur_ref ); #if 0 if ( zone->cur_ref > zone->cur_top ) @@ -530,7 +539,7 @@ no_shoots = blues->no_overshoots; - /* lookup stem top in top zones table */ + /* look up stem top in top zones table */ table = &blues->normal_top; count = table->count; zone = table->zones; @@ -565,7 +574,7 @@ if ( stem_bot >= zone->org_bottom - blues->blue_fuzz ) { - if ( no_shoots || delta < blues->blue_shift ) + if ( no_shoots || delta < blues->blue_threshold ) { alignment->align |= PSH_BLUE_ALIGN_BOT; alignment->align_bot = zone->cur_ref; @@ -644,7 +653,7 @@ read++; } - dim->stdw.count = priv->num_snap_widths; + dim->stdw.count = priv->num_snap_widths + 1; } /* copy standard heights */ @@ -654,7 +663,7 @@ write->org = priv->standard_height[0]; - write++; + write++; read = priv->snap_heights; for ( count = priv->num_snap_heights; count > 0; count-- ) { @@ -663,7 +672,7 @@ read++; } - dim->stdw.count = priv->num_snap_heights; + dim->stdw.count = priv->num_snap_heights + 1; } /* copy blue zones */ @@ -675,15 +684,9 @@ priv->family_blues, priv->num_family_other_blues, priv->family_other_blues, priv->blue_fuzz, 1 ); - globals->blues.blue_scale = priv->blue_scale - ? priv->blue_scale - : 0x27A000L; /* 0.039625 * 0x10000 * 1000 */ - - globals->blues.blue_shift = priv->blue_shift - ? priv->blue_shift - : 7; - - globals->blues.blue_fuzz = priv->blue_fuzz; + globals->blues.blue_scale = priv->blue_scale; + globals->blues.blue_shift = priv->blue_shift; + globals->blues.blue_fuzz = priv->blue_fuzz; globals->dimension[0].scale_mult = 0; globals->dimension[0].scale_delta = 0; Index: xc/extras/freetype2/src/pshinter/pshrec.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pshinter/pshrec.c,v retrieving revision 1.2 diff -u -r1.2 pshrec.c --- a/xc/extras/freetype2/src/pshinter/pshrec.c 23 Apr 2004 18:42:51 -0000 1.2 +++ b/xc/extras/freetype2/src/pshinter/pshrec.c 28 Apr 2004 10:26:00 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hints recorder (body). */ /* */ -/* Copyright 2001, 2002, 2003 by */ +/* Copyright 2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -68,7 +68,7 @@ if ( new_max > old_max ) { /* try to grow the table */ - new_max = ( new_max + 7 ) & -8; + new_max = FT_PAD_CEIL( new_max, 8 ); if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) ) table->max_hints = new_max; } @@ -142,7 +142,7 @@ if ( new_max > old_max ) { - new_max = ( new_max + 7 ) & -8; + new_max = FT_PAD_CEIL( new_max, 8 ); if ( !FT_RENEW_ARRAY( mask->bytes, old_max, new_max ) ) mask->max_bits = new_max * 8; } @@ -239,7 +239,7 @@ if ( new_max > old_max ) { - new_max = ( new_max + 7 ) & -8; + new_max = FT_PAD_CEIL( new_max, 8 ); if ( !FT_RENEW_ARRAY( table->masks, old_max, new_max ) ) table->max_masks = new_max; } @@ -318,8 +318,7 @@ PS_Mask mask; - /* allocate new mask, and grow it to "bit_count" bits */ - error = ps_mask_table_alloc( table, memory, &mask ); + error = ps_mask_table_last( table, memory, &mask ); if ( error ) goto Exit; @@ -1012,18 +1011,18 @@ FT_ERROR(( "ps_hints_t2mask: " "called with invalid bitcount %d (instead of %d)\n", bit_count, count1 + count2 )); - + /* simply ignore the operator */ return; } /* set-up new horizontal and vertical hint mask now */ - error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1, + error = ps_dimension_set_mask_bits( &dim[0], bytes, count2, count1, end_point, memory ); if ( error ) goto Fail; - error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2, + error = ps_dimension_set_mask_bits( &dim[1], bytes, 0, count2, end_point, memory ); if ( error ) goto Fail; @@ -1057,7 +1056,7 @@ FT_ERROR(( "ps_hints_t2counter: " "called with invalid bitcount %d (instead of %d)\n", bit_count, count1 + count2 )); - + /* simply ignore the operator */ return; } Index: xc/extras/freetype2/src/pshinter/pshrec.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/pshinter/pshrec.h,v retrieving revision 1.2 diff -u -r1.2 pshrec.h --- a/xc/extras/freetype2/src/pshinter/pshrec.h 23 Apr 2004 18:42:51 -0000 1.2 +++ b/xc/extras/freetype2/src/pshinter/pshrec.h 28 Apr 2004 10:26:00 -0000 @@ -4,7 +4,7 @@ /* */ /* Postscript (Type1/Type2) hints recorder (specification). */ /* */ -/* Copyright 2001, 2002 by */ +/* Copyright 2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ Index: xc/extras/freetype2/src/raster/ftrend1.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/raster/ftrend1.c,v retrieving revision 1.2 diff -u -r1.2 ftrend1.c --- a/xc/extras/freetype2/src/raster/ftrend1.c 23 Apr 2004 18:42:51 -0000 1.2 +++ b/xc/extras/freetype2/src/raster/ftrend1.c 28 Apr 2004 10:26:05 -0000 @@ -140,10 +140,10 @@ /* compute the control box, and grid fit it */ FT_Outline_Get_CBox( outline, &cbox ); - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); @@ -161,7 +161,7 @@ if ( !( mode & FT_RENDER_MODE_MONO ) ) { /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ - pitch = ( width + 3 ) & -4; + pitch = FT_PAD_CEIL( width, 4 ); bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; bitmap->num_grays = 256; } @@ -193,9 +193,9 @@ /* render outline into the bitmap */ error = render->raster_render( render->raster, ¶ms ); - + FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); - + if ( error ) goto Exit; Index: xc/extras/freetype2/src/sfnt/Jamfile =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/sfnt/Jamfile,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 Jamfile --- a/xc/extras/freetype2/src/sfnt/Jamfile 25 Nov 2003 19:27:23 -0000 1.1.1.2 +++ b/xc/extras/freetype2/src/sfnt/Jamfile 28 Apr 2004 10:26:05 -0000 @@ -1,4 +1,4 @@ -# FreeType 2 src/sfnt Jamfile (c) 2001, 2002 David Turner +# FreeType 2 src/sfnt Jamfile (c) 2001, 2002, 2004 David Turner # SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ; @@ -8,7 +8,7 @@ if $(FT2_MULTI) { - _sources = sfobjs sfdriver ttcmap ttcmap0 ttpost ttload ttsbit ; + _sources = sfobjs sfdriver ttcmap0 ttpost ttload ttsbit ; } else { Index: xc/extras/freetype2/src/sfnt/rules.mk =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/sfnt/rules.mk,v retrieving revision 1.2 diff -u -r1.2 rules.mk --- a/xc/extras/freetype2/src/sfnt/rules.mk 23 Apr 2004 18:42:51 -0000 1.2 +++ b/xc/extras/freetype2/src/sfnt/rules.mk 28 Apr 2004 10:26:05 -0000 @@ -26,7 +26,6 @@ # SFNT driver sources (i.e., C files) # SFNT_DRV_SRC := $(SFNT_DIR)/ttload.c \ - $(SFNT_DIR)/ttcmap.c \ $(SFNT_DIR)/ttcmap0.c \ $(SFNT_DIR)/ttsbit.c \ $(SFNT_DIR)/ttpost.c \ Index: xc/extras/freetype2/src/sfnt/sfdriver.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/sfnt/sfdriver.c,v retrieving revision 1.2 diff -u -r1.2 sfdriver.c --- a/xc/extras/freetype2/src/sfnt/sfdriver.c 23 Apr 2004 18:42:51 -0000 1.2 +++ b/xc/extras/freetype2/src/sfnt/sfdriver.c 28 Apr 2004 10:26:05 -0000 @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,13 +15,13 @@ /* */ /***************************************************************************/ + #include #include FT_INTERNAL_SFNT_H #include FT_INTERNAL_OBJECTS_H #include "sfdriver.h" #include "ttload.h" -#include "ttcmap.h" #include "sfobjs.h" #include "sferrors.h" @@ -34,9 +34,12 @@ #include "ttpost.h" #endif +#include "ttcmap0.h" + #include FT_SERVICE_GLYPH_DICT_H #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_SFNT_H +#include FT_SERVICE_TT_CMAP_H /* @@ -260,6 +263,15 @@ }; + /* + * TT CMAP INFO + * + */ + static const FT_Service_TTCMapsRec tt_service_get_cmap_info = + { + (TT_CMap_Info_GetFunc)tt_get_cmap_info + }; + /* * SERVICE LIST @@ -273,6 +285,7 @@ #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES { FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict }, #endif + { FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info }, { NULL, NULL } }; @@ -330,9 +343,11 @@ /* see `ttload.h' */ tt_face_load_bitmap_header, - /* see `ttsbit.h' */ + /* see `ttsbit.h' and `sfnt.h' */ tt_face_set_sbit_strike, tt_face_load_sbit_strikes, + tt_find_sbit_image, + tt_load_sbit_metrics, tt_face_load_sbit_image, tt_face_free_sbit_strikes, @@ -341,6 +356,8 @@ 0, 0, 0, + 0, + 0, 0, 0, @@ -359,9 +376,6 @@ #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - /* see `ttcmap.h' */ - tt_face_load_charmap, - tt_face_free_charmap, }; Index: xc/extras/freetype2/src/sfnt/sfnt.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/sfnt/sfnt.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 sfnt.c --- a/xc/extras/freetype2/src/sfnt/sfnt.c 14 Nov 2003 16:48:24 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/sfnt/sfnt.c 28 Apr 2004 10:26:05 -0000 @@ -4,7 +4,7 @@ /* */ /* Single object library component. */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,6 @@ #include #include "ttload.c" -#include "ttcmap.c" #include "ttcmap0.c" #include "sfobjs.c" #include "sfdriver.c" Index: xc/extras/freetype2/src/sfnt/sfobjs.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/sfnt/sfobjs.c,v retrieving revision 1.2 diff -u -r1.2 sfobjs.c --- a/xc/extras/freetype2/src/sfnt/sfobjs.c 23 Apr 2004 18:42:51 -0000 1.2 +++ b/xc/extras/freetype2/src/sfnt/sfobjs.c 28 Apr 2004 10:26:05 -0000 @@ -15,6 +15,7 @@ /* */ /***************************************************************************/ + #include #include "sfobjs.h" #include "ttload.h" @@ -399,7 +400,7 @@ FT_Int num_params, FT_Parameter* params ) { - FT_Error error; + FT_Error error, psnames_error; FT_Bool has_outline; FT_Bool is_apple_sbit; @@ -461,7 +462,7 @@ /* the following tables are optional in PCL fonts -- */ /* don't check for errors */ (void)LOAD_( names ); - (void)LOAD_( psnames ); + psnames_error = LOAD_( psnames ); /* do not load the metrics headers and tables if this is an Apple */ /* sbit font file */ @@ -528,9 +529,9 @@ FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - /* might need more polish to detect the presence of a Postscript */ - /* name table in the font */ - flags |= FT_FACE_FLAG_GLYPH_NAMES; + if ( psnames_error == SFNT_Err_Ok && + face->postscript.FormatType != 0x00030000L ) + flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif /* fixed width font? */ Index: xc/extras/freetype2/src/sfnt/ttcmap.c =================================================================== RCS file: xc/extras/freetype2/src/sfnt/ttcmap.c diff -N xc/extras/freetype2/src/sfnt/ttcmap.c --- a/xc/extras/freetype2/src/sfnt/ttcmap.c 25 Nov 2003 19:27:23 -0000 1.1.1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1110 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttcmap.c */ -/* */ -/* TrueType character mapping table (cmap) support (body). */ -/* */ -/* Copyright 1996-2001, 2002 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include -#include FT_INTERNAL_DEBUG_H -#include "ttload.h" -#include "ttcmap.h" - -#include "sferrors.h" - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttcmap - - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index0( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next0( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index2( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next2( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index4( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next4( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index6( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next6( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index8_12( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next8_12( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index10( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next10( TT_CMapTable charmap, - FT_ULong char_code ); - - - /*************************************************************************/ - /* */ - /* */ - /* tt_face_load_charmap */ - /* */ - /* */ - /* Loads a given TrueType character map into memory. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* stream :: A handle to the current stream object. */ - /* */ - /* */ - /* table :: A pointer to a cmap object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The function assumes that the stream is already in use (i.e., */ - /* opened). In case of error, all partially allocated tables are */ - /* released. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_charmap( TT_Face face, - TT_CMapTable cmap, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory; - FT_UShort num_SH, num_Seg, i; - FT_ULong j, n; - - FT_UShort u, l; - - TT_CMap0 cmap0; - TT_CMap2 cmap2; - TT_CMap4 cmap4; - TT_CMap6 cmap6; - TT_CMap8_12 cmap8_12; - TT_CMap10 cmap10; - - TT_CMap2SubHeader cmap2sub; - TT_CMap4Segment segments; - TT_CMapGroup groups; - - - if ( cmap->loaded ) - return SFNT_Err_Ok; - - memory = stream->memory; - - if ( FT_STREAM_SEEK( cmap->offset ) ) - return error; - - switch ( cmap->format ) - { - case 0: - cmap0 = &cmap->c.cmap0; - - if ( FT_READ_USHORT( cmap0->language ) || - FT_ALLOC( cmap0->glyphIdArray, 256L ) || - FT_STREAM_READ( cmap0->glyphIdArray, 256L ) ) - goto Fail; - - cmap->get_index = code_to_index0; - cmap->get_next_char = code_to_next0; - break; - - case 2: - num_SH = 0; - cmap2 = &cmap->c.cmap2; - - /* allocate subheader keys */ - - if ( FT_NEW_ARRAY( cmap2->subHeaderKeys, 256 ) || - FT_FRAME_ENTER( 2L + 512L ) ) - goto Fail; - - cmap2->language = FT_GET_USHORT(); - - for ( i = 0; i < 256; i++ ) - { - u = (FT_UShort)( FT_GET_USHORT() / 8 ); - cmap2->subHeaderKeys[i] = u; - - if ( num_SH < u ) - num_SH = u; - } - - FT_FRAME_EXIT(); - - /* load subheaders */ - - cmap2->numGlyphId = l = (FT_UShort)( - ( ( cmap->length - 2L * ( 256 + 3 ) - num_SH * 8L ) & 0xFFFFU ) / 2 ); - - if ( FT_NEW_ARRAY( cmap2->subHeaders, num_SH + 1 ) || - FT_FRAME_ENTER( ( num_SH + 1 ) * 8L ) ) - { - FT_FREE( cmap2->subHeaderKeys ); - goto Fail; - } - - cmap2sub = cmap2->subHeaders; - - for ( i = 0; i <= num_SH; i++ ) - { - cmap2sub->firstCode = FT_GET_USHORT(); - cmap2sub->entryCount = FT_GET_USHORT(); - cmap2sub->idDelta = FT_GET_SHORT(); - /* we apply the location offset immediately */ - cmap2sub->idRangeOffset = (FT_UShort)( - FT_GET_USHORT() - ( num_SH - i ) * 8 - 2 ); - - cmap2sub++; - } - - FT_FRAME_EXIT(); - - /* load glyph IDs */ - - if ( FT_NEW_ARRAY( cmap2->glyphIdArray, l ) || - FT_FRAME_ENTER( l * 2L ) ) - { - FT_FREE( cmap2->subHeaders ); - FT_FREE( cmap2->subHeaderKeys ); - goto Fail; - } - - for ( i = 0; i < l; i++ ) - cmap2->glyphIdArray[i] = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - - cmap->get_index = code_to_index2; - cmap->get_next_char = code_to_next2; - break; - - case 4: - cmap4 = &cmap->c.cmap4; - - /* load header */ - - if ( FT_FRAME_ENTER( 10L ) ) - goto Fail; - - cmap4->language = FT_GET_USHORT(); - cmap4->segCountX2 = FT_GET_USHORT(); - cmap4->searchRange = FT_GET_USHORT(); - cmap4->entrySelector = FT_GET_USHORT(); - cmap4->rangeShift = FT_GET_USHORT(); - - num_Seg = (FT_UShort)( cmap4->segCountX2 / 2 ); - - FT_FRAME_EXIT(); - - /* load segments */ - - if ( FT_NEW_ARRAY( cmap4->segments, num_Seg ) || - FT_FRAME_ENTER( ( num_Seg * 4 + 1 ) * 2L ) ) - goto Fail; - - segments = cmap4->segments; - - for ( i = 0; i < num_Seg; i++ ) - segments[i].endCount = FT_GET_USHORT(); - - (void)FT_GET_USHORT(); - - for ( i = 0; i < num_Seg; i++ ) - segments[i].startCount = FT_GET_USHORT(); - - for ( i = 0; i < num_Seg; i++ ) - segments[i].idDelta = FT_GET_SHORT(); - - for ( i = 0; i < num_Seg; i++ ) - segments[i].idRangeOffset = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - - cmap4->numGlyphId = l = (FT_UShort)( - ( ( cmap->length - ( 16L + 8L * num_Seg ) ) & 0xFFFFU ) / 2 ); - - /* load IDs */ - - if ( FT_NEW_ARRAY( cmap4->glyphIdArray, l ) || - FT_FRAME_ENTER( l * 2L ) ) - { - FT_FREE( cmap4->segments ); - goto Fail; - } - - for ( i = 0; i < l; i++ ) - cmap4->glyphIdArray[i] = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - - cmap4->last_segment = cmap4->segments; - - cmap->get_index = code_to_index4; - cmap->get_next_char = code_to_next4; - break; - - case 6: - cmap6 = &cmap->c.cmap6; - - if ( FT_FRAME_ENTER( 6L ) ) - goto Fail; - - cmap6->language = FT_GET_USHORT(); - cmap6->firstCode = FT_GET_USHORT(); - cmap6->entryCount = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - - l = cmap6->entryCount; - - if ( FT_NEW_ARRAY( cmap6->glyphIdArray, l ) || - FT_FRAME_ENTER( l * 2L ) ) - goto Fail; - - for ( i = 0; i < l; i++ ) - cmap6->glyphIdArray[i] = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - cmap->get_index = code_to_index6; - cmap->get_next_char = code_to_next6; - break; - - case 8: - case 12: - cmap8_12 = &cmap->c.cmap8_12; - - if ( FT_FRAME_ENTER( 8L ) ) - goto Fail; - - cmap->length = FT_GET_ULONG(); - cmap8_12->language = FT_GET_ULONG(); - - FT_FRAME_EXIT(); - - if ( cmap->format == 8 ) - if ( FT_STREAM_SKIP( 8192L ) ) - goto Fail; - - if ( FT_READ_ULONG( cmap8_12->nGroups ) ) - goto Fail; - - n = cmap8_12->nGroups; - - if ( FT_NEW_ARRAY( cmap8_12->groups, n ) || - FT_FRAME_ENTER( n * 3 * 4L ) ) - goto Fail; - - groups = cmap8_12->groups; - - for ( j = 0; j < n; j++ ) - { - groups[j].startCharCode = FT_GET_ULONG(); - groups[j].endCharCode = FT_GET_ULONG(); - groups[j].startGlyphID = FT_GET_ULONG(); - } - - FT_FRAME_EXIT(); - - cmap8_12->last_group = cmap8_12->groups; - - cmap->get_index = code_to_index8_12; - cmap->get_next_char = code_to_next8_12; - break; - - case 10: - cmap10 = &cmap->c.cmap10; - - if ( FT_FRAME_ENTER( 16L ) ) - goto Fail; - - cmap->length = FT_GET_ULONG(); - cmap10->language = FT_GET_ULONG(); - cmap10->startCharCode = FT_GET_ULONG(); - cmap10->numChars = FT_GET_ULONG(); - - FT_FRAME_EXIT(); - - n = cmap10->numChars; - - if ( FT_NEW_ARRAY( cmap10->glyphs, n ) || - FT_FRAME_ENTER( n * 2L ) ) - goto Fail; - - for ( j = 0; j < n; j++ ) - cmap10->glyphs[j] = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - cmap->get_index = code_to_index10; - cmap->get_next_char = code_to_next10; - break; - - default: /* corrupt character mapping table */ - return SFNT_Err_Invalid_CharMap_Format; - - } - - return SFNT_Err_Ok; - - Fail: - tt_face_free_charmap( face, cmap ); - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* tt_face_free_charmap */ - /* */ - /* */ - /* Destroys a character mapping table. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* cmap :: A handle to a cmap object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_free_charmap( TT_Face face, - TT_CMapTable cmap ) - { - FT_Memory memory; - - - if ( !cmap ) - return SFNT_Err_Ok; - - memory = face->root.driver->root.memory; - - switch ( cmap->format ) - { - case 0: - FT_FREE( cmap->c.cmap0.glyphIdArray ); - break; - - case 2: - FT_FREE( cmap->c.cmap2.subHeaderKeys ); - FT_FREE( cmap->c.cmap2.subHeaders ); - FT_FREE( cmap->c.cmap2.glyphIdArray ); - break; - - case 4: - FT_FREE( cmap->c.cmap4.segments ); - FT_FREE( cmap->c.cmap4.glyphIdArray ); - cmap->c.cmap4.segCountX2 = 0; - break; - - case 6: - FT_FREE( cmap->c.cmap6.glyphIdArray ); - cmap->c.cmap6.entryCount = 0; - break; - - case 8: - case 12: - FT_FREE( cmap->c.cmap8_12.groups ); - cmap->c.cmap8_12.nGroups = 0; - break; - - case 10: - FT_FREE( cmap->c.cmap10.glyphs ); - cmap->c.cmap10.numChars = 0; - break; - - default: - /* invalid table format, do nothing */ - ; - } - - cmap->loaded = FALSE; - return SFNT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index0 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 0. */ - /* `charCode' must be in the range 0x00-0xFF (otherwise 0 is */ - /* returned). */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap0 :: A pointer to a cmap table in format 0. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index0( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap0 cmap0 = &cmap->c.cmap0; - - - return ( charCode <= 0xFF ? cmap0->glyphIdArray[charCode] : 0 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_next0 */ - /* */ - /* */ - /* Finds the next encoded character after the given one. Uses */ - /* format 0. `charCode' must be in the range 0x00-0xFF (otherwise 0 */ - /* is returned). */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap0 :: A pointer to a cmap table in format 0. */ - /* */ - /* */ - /* Next char code. 0 if no higher one is encoded. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next0( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap0 cmap0 = &cmap->c.cmap0; - - - while ( ++charCode <= 0xFF ) - if ( cmap0->glyphIdArray[charCode] ) - return ( charCode ); - return ( 0 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index2 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 2. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap2 :: A pointer to a cmap table in format 2. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index2( TT_CMapTable cmap, - FT_ULong charCode ) - { - FT_UInt result, index1, offset; - FT_UInt char_lo; - FT_ULong char_hi; - TT_CMap2SubHeader sh2; - TT_CMap2 cmap2; - - - cmap2 = &cmap->c.cmap2; - result = 0; - char_lo = (FT_UInt)( charCode & 0xFF ); - char_hi = charCode >> 8; - - if ( char_hi == 0 ) - { - /* an 8-bit character code -- we use the subHeader 0 in this case */ - /* to test whether the character code is in the charmap */ - index1 = cmap2->subHeaderKeys[char_lo]; - if ( index1 != 0 ) - return 0; - } - else - { - /* a 16-bit character code */ - index1 = cmap2->subHeaderKeys[char_hi & 0xFF]; - if ( index1 == 0 ) - return 0; - } - - sh2 = cmap2->subHeaders + index1; - char_lo -= sh2->firstCode; - - if ( char_lo < (FT_UInt)sh2->entryCount ) - { - offset = sh2->idRangeOffset / 2 + char_lo; - if ( offset < (FT_UInt)cmap2->numGlyphId ) - { - result = cmap2->glyphIdArray[offset]; - if ( result ) - result = ( result + sh2->idDelta ) & 0xFFFFU; - } - } - - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_next2 */ - /* */ - /* */ - /* Find the next encoded character. Uses format 2. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap2 :: A pointer to a cmap table in format 2. */ - /* */ - /* */ - /* Next encoded character. 0 if none exists. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next2( TT_CMapTable cmap, - FT_ULong charCode ) - { - FT_UInt index1, offset; - FT_UInt char_lo; - FT_ULong char_hi; - TT_CMap2SubHeader sh2; - TT_CMap2 cmap2; - - - cmap2 = &cmap->c.cmap2; - charCode++; - - /* - * This is relatively simplistic -- look for a subHeader containing - * glyphs and then walk to the first glyph in that subHeader. - */ - while ( charCode < 0x10000L ) - { - char_lo = (FT_UInt)( charCode & 0xFF ); - char_hi = charCode >> 8; - - if ( char_hi == 0 ) - { - /* an 8-bit character code -- we use the subHeader 0 in this case */ - /* to test whether the character code is in the charmap */ - index1 = cmap2->subHeaderKeys[char_lo]; - if ( index1 != 0 ) - { - charCode++; - continue; - } - } - else - { - /* a 16-bit character code */ - index1 = cmap2->subHeaderKeys[char_hi & 0xFF]; - if ( index1 == 0 ) - { - charCode = ( char_hi + 1 ) << 8; - continue; - } - } - - sh2 = cmap2->subHeaders + index1; - char_lo -= sh2->firstCode; - - if ( char_lo > (FT_UInt)sh2->entryCount ) - { - charCode = ( char_hi + 1 ) << 8; - continue; - } - - offset = sh2->idRangeOffset / 2 + char_lo; - if ( offset >= (FT_UInt)cmap2->numGlyphId || - cmap2->glyphIdArray[offset] == 0 ) - { - charCode++; - continue; - } - - return charCode; - } - return 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index4 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 4. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap4 :: A pointer to a cmap table in format 4. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index4( TT_CMapTable cmap, - FT_ULong charCode ) - { - FT_UInt result, index1, segCount; - TT_CMap4 cmap4; - TT_CMap4SegmentRec *seg4, *limit; - - - cmap4 = &cmap->c.cmap4; - result = 0; - segCount = cmap4->segCountX2 / 2; - limit = cmap4->segments + segCount; - - /* first, check against the last used segment */ - - seg4 = cmap4->last_segment; - - /* the following is equivalent to performing two tests, as in */ - /* */ - /* if ( charCode >= seg4->startCount && charCode <= seg4->endCount ) */ - /* */ - /* This is a bit strange, but it is faster, and the idea behind the */ - /* cache is to significantly speed up charcode to glyph index */ - /* conversion. */ - - if ( (FT_ULong)( charCode - seg4->startCount ) < - (FT_ULong)( seg4->endCount - seg4->startCount ) ) - goto Found1; - - for ( seg4 = cmap4->segments; seg4 < limit; seg4++ ) - { - /* the ranges are sorted in increasing order. If we are out of */ - /* the range here, the char code isn't in the charmap, so exit. */ - - if ( charCode > (FT_UInt)seg4->endCount ) - continue; - - if ( charCode >= (FT_UInt)seg4->startCount ) - goto Found; - } - return 0; - - Found: - cmap4->last_segment = seg4; - - Found1: - /* if the idRangeOffset is 0, we can compute the glyph index */ - /* directly */ - - if ( seg4->idRangeOffset == 0 ) - result = (FT_UInt)( charCode + seg4->idDelta ) & 0xFFFFU; - else - { - /* otherwise, we must use the glyphIdArray to do it */ - index1 = (FT_UInt)( seg4->idRangeOffset / 2 - + ( charCode - seg4->startCount ) - + ( seg4 - cmap4->segments ) - - segCount ); - - if ( index1 < (FT_UInt)cmap4->numGlyphId && - cmap4->glyphIdArray[index1] != 0 ) - result = ( cmap4->glyphIdArray[index1] + seg4->idDelta ) & 0xFFFFU; - } - - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_next4 */ - /* */ - /* */ - /* Find the next encoded character. Uses format 4. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap :: A pointer to a cmap table in format 4. */ - /* */ - /* */ - /* Next encoded character. 0 if none exists. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next4( TT_CMapTable cmap, - FT_ULong charCode ) - { - FT_UInt index1, segCount; - TT_CMap4 cmap4; - TT_CMap4SegmentRec *seg4, *limit; - - - cmap4 = &cmap->c.cmap4; - segCount = cmap4->segCountX2 / 2; - limit = cmap4->segments + segCount; - - charCode++; - - for ( seg4 = cmap4->segments; seg4 < limit; seg4++ ) - { - /* The ranges are sorted in increasing order. If we are out of */ - /* the range here, the char code isn't in the charmap, so exit. */ - - if ( charCode <= (FT_UInt)seg4->endCount ) - goto Found; - } - return 0; - - Found: - if ( charCode < (FT_ULong) seg4->startCount ) - charCode = seg4->startCount; - - /* if the idRangeOffset is 0, all chars in the map exist */ - - if ( seg4->idRangeOffset == 0 ) - return ( charCode ); - - while ( charCode <= (FT_UInt) seg4->endCount ) - { - /* otherwise, we must use the glyphIdArray to do it */ - index1 = (FT_UInt)( seg4->idRangeOffset / 2 - + ( charCode - seg4->startCount ) - + ( seg4 - cmap4->segments ) - - segCount ); - - if ( index1 < (FT_UInt)cmap4->numGlyphId && - cmap4->glyphIdArray[index1] != 0 ) - return ( charCode ); - charCode++; - } - - return 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index6 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 6. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap6 :: A pointer to a cmap table in format 6. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index6( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap6 cmap6; - FT_UInt result = 0; - - - cmap6 = &cmap->c.cmap6; - charCode -= cmap6->firstCode; - - if ( charCode < (FT_UInt)cmap6->entryCount ) - result = cmap6->glyphIdArray[charCode]; - - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_next6 */ - /* */ - /* */ - /* Find the next encoded character. Uses format 6. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap :: A pointer to a cmap table in format 6. */ - /* */ - /* */ - /* Next encoded character. 0 if none exists. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next6( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap6 cmap6; - - - charCode++; - - cmap6 = &cmap->c.cmap6; - - if ( charCode < (FT_ULong) cmap6->firstCode ) - charCode = cmap6->firstCode; - - charCode -= cmap6->firstCode; - - while ( charCode < (FT_UInt)cmap6->entryCount ) - { - if ( cmap6->glyphIdArray[charCode] != 0 ) - return charCode + cmap6->firstCode; - charCode++; - } - - return 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index8_12 */ - /* */ - /* */ - /* Converts the (possibly 32bit) character code into a glyph index. */ - /* Uses format 8 or 12. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap8_12 :: A pointer to a cmap table in format 8 or 12. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index8_12( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap8_12 cmap8_12; - TT_CMapGroupRec *group, *limit; - - - cmap8_12 = &cmap->c.cmap8_12; - limit = cmap8_12->groups + cmap8_12->nGroups; - - /* first, check against the last used group */ - - group = cmap8_12->last_group; - - /* the following is equivalent to performing two tests, as in */ - /* */ - /* if ( charCode >= group->startCharCode && */ - /* charCode <= group->endCharCode ) */ - /* */ - /* This is a bit strange, but it is faster, and the idea behind the */ - /* cache is to significantly speed up charcode to glyph index */ - /* conversion. */ - - if ( (FT_ULong)( charCode - group->startCharCode ) < - (FT_ULong)( group->endCharCode - group->startCharCode ) ) - goto Found1; - - for ( group = cmap8_12->groups; group < limit; group++ ) - { - /* the ranges are sorted in increasing order. If we are out of */ - /* the range here, the char code isn't in the charmap, so exit. */ - - if ( charCode > group->endCharCode ) - continue; - - if ( charCode >= group->startCharCode ) - goto Found; - } - return 0; - - Found: - cmap8_12->last_group = group; - - Found1: - return (FT_UInt)( group->startGlyphID + - ( charCode - group->startCharCode ) ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_next8_12 */ - /* */ - /* */ - /* Find the next encoded character. Uses format 8 or 12. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap :: A pointer to a cmap table in format 8 or 12. */ - /* */ - /* */ - /* Next encoded character. 0 if none exists. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next8_12( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap8_12 cmap8_12; - TT_CMapGroupRec *group, *limit; - - - charCode++; - cmap8_12 = &cmap->c.cmap8_12; - limit = cmap8_12->groups + cmap8_12->nGroups; - - for ( group = cmap8_12->groups; group < limit; group++ ) - { - /* the ranges are sorted in increasing order. If we are out of */ - /* the range here, the char code isn't in the charmap, so exit. */ - - if ( charCode <= group->endCharCode ) - goto Found; - } - return 0; - - Found: - if ( charCode < group->startCharCode ) - charCode = group->startCharCode; - - return charCode; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index10 */ - /* */ - /* */ - /* Converts the (possibly 32bit) character code into a glyph index. */ - /* Uses format 10. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap10 :: A pointer to a cmap table in format 10. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index10( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap10 cmap10; - FT_UInt result = 0; - - - cmap10 = &cmap->c.cmap10; - charCode -= cmap10->startCharCode; - - /* the overflow trick for comparison works here also since the number */ - /* of glyphs (even if numChars is specified as ULong in the specs) in */ - /* an OpenType font is limited to 64k */ - - if ( charCode < cmap10->numChars ) - result = cmap10->glyphs[charCode]; - - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_next10 */ - /* */ - /* */ - /* Find the next encoded character. Uses format 10. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap :: A pointer to a cmap table in format 10. */ - /* */ - /* */ - /* Next encoded character. 0 if none exists. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next10( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap10 cmap10; - - - charCode++; - cmap10 = &cmap->c.cmap10; - - if ( charCode < cmap10->startCharCode ) - charCode = cmap10->startCharCode; - - charCode -= cmap10->startCharCode; - - /* the overflow trick for comparison works here also since the number */ - /* of glyphs (even if numChars is specified as ULong in the specs) in */ - /* an OpenType font is limited to 64k */ - - while ( charCode < cmap10->numChars ) - { - if ( cmap10->glyphs[charCode] ) - return ( charCode + cmap10->startCharCode ); - charCode++; - } - - return 0; - } - - -/* END */ Index: xc/extras/freetype2/src/sfnt/ttcmap.h =================================================================== RCS file: xc/extras/freetype2/src/sfnt/ttcmap.h diff -N xc/extras/freetype2/src/sfnt/ttcmap.h --- a/xc/extras/freetype2/src/sfnt/ttcmap.h 25 Nov 2003 19:27:23 -0000 1.1.1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,45 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttcmap.h */ -/* */ -/* TrueType character mapping table (cmap) support (specification). */ -/* */ -/* Copyright 1996-2001, 2002 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __TTCMAP_H__ -#define __TTCMAP_H__ - - -#include -#include FT_INTERNAL_TRUETYPE_TYPES_H - - -FT_BEGIN_HEADER - - - FT_LOCAL( FT_Error ) - tt_face_load_charmap( TT_Face face, - TT_CMapTable cmap, - FT_Stream input ); - - FT_LOCAL( FT_Error ) - tt_face_free_charmap( TT_Face face, - TT_CMapTable cmap ); - - -FT_END_HEADER - -#endif /* __TTCMAP_H__ */ - - -/* END */ Index: xc/extras/freetype2/src/sfnt/ttcmap0.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/sfnt/ttcmap0.c,v retrieving revision 1.2 diff -u -r1.2 ttcmap0.c --- a/xc/extras/freetype2/src/sfnt/ttcmap0.c 23 Apr 2004 18:42:51 -0000 1.2 +++ b/xc/extras/freetype2/src/sfnt/ttcmap0.c 28 Apr 2004 10:26:06 -0000 @@ -15,6 +15,7 @@ /* */ /***************************************************************************/ + #include #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H @@ -143,6 +144,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap0_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap0_class_rec = { @@ -155,7 +169,8 @@ (FT_CMap_CharNextFunc) tt_cmap0_char_next }, 0, - (TT_CMap_ValidateFunc) tt_cmap0_validate + (TT_CMap_ValidateFunc) tt_cmap0_validate, + (TT_CMap_Info_GetFunc) tt_cmap0_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_0 */ @@ -377,10 +392,13 @@ else { /* a 16-bit character code */ - p += char_hi * 2; /* jump to key entry */ - sub = subs + ( TT_PEEK_USHORT( p ) & -8 ); /* jump to sub-header */ - /* check that the hi byte isn't a valid one-byte value */ + /* jump to key entry */ + p += char_hi * 2; + /* jump to sub-header */ + sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) ); + + /* check that the high byte isn't a valid one-byte value */ if ( sub == subs ) goto Exit; } @@ -466,7 +484,7 @@ pos = (FT_UInt)( char_lo - start ); p += offset + pos * 2; - charcode = ( charcode & -256 ) + char_lo; + charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo; for ( ; pos < count; pos++, charcode++ ) { @@ -486,7 +504,7 @@ /* jump to next sub-header, i.e. higher byte value */ Next_SubHeader: - charcode = ( charcode & -256 ) + 256; + charcode = FT_PAD_FLOOR( charcode, 256 ) + 256; } Exit: @@ -496,6 +514,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap2_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap2_class_rec = { @@ -508,7 +539,8 @@ (FT_CMap_CharNextFunc) tt_cmap2_char_next }, 2, - (TT_CMap_ValidateFunc) tt_cmap2_validate + (TT_CMap_ValidateFunc) tt_cmap2_validate, + (TT_CMap_Info_GetFunc) tt_cmap2_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_2 */ @@ -766,7 +798,7 @@ p = table + 6; - num_segs2 = TT_PEEK_USHORT( p ) & -2; /* be paranoid! */ + num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); /* be paranoid! */ #if 1 /* Some fonts have more than 170 segments in their charmaps! */ @@ -889,7 +921,7 @@ code = (FT_UInt)char_code + 1; p = table + 6; - num_segs2 = TT_PEEK_USHORT(p) & -2; /* ensure even-ness */ + num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT(p), 2 ); /* ensure even-ness */ #if 1 @@ -1057,6 +1089,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap4_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap4_class_rec = { @@ -1069,7 +1114,8 @@ (FT_CMap_CharNextFunc) tt_cmap4_char_next }, 4, - (TT_CMap_ValidateFunc) tt_cmap4_validate + (TT_CMap_ValidateFunc) tt_cmap4_validate, + (TT_CMap_Info_GetFunc) tt_cmap4_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_4 */ @@ -1201,6 +1247,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap6_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap6_class_rec = { @@ -1213,7 +1272,8 @@ (FT_CMap_CharNextFunc) tt_cmap6_char_next }, 6, - (TT_CMap_ValidateFunc) tt_cmap6_validate + (TT_CMap_ValidateFunc) tt_cmap6_validate, + (TT_CMap_Info_GetFunc) tt_cmap6_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_6 */ @@ -1438,6 +1498,18 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap8_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap8_class_rec = { @@ -1450,7 +1522,8 @@ (FT_CMap_CharNextFunc) tt_cmap8_char_next }, 8, - (TT_CMap_ValidateFunc) tt_cmap8_validate + (TT_CMap_ValidateFunc) tt_cmap8_validate, + (TT_CMap_Info_GetFunc) tt_cmap8_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_8 */ @@ -1570,6 +1643,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap10_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap10_class_rec = { @@ -1582,7 +1668,8 @@ (FT_CMap_CharNextFunc) tt_cmap10_char_next }, 10, - (TT_CMap_ValidateFunc) tt_cmap10_validate + (TT_CMap_ValidateFunc) tt_cmap10_validate, + (TT_CMap_Info_GetFunc) tt_cmap10_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_10 */ @@ -1740,6 +1827,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap12_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap12_class_rec = { @@ -1752,7 +1852,8 @@ (FT_CMap_CharNextFunc) tt_cmap12_char_next }, 12, - (TT_CMap_ValidateFunc) tt_cmap12_validate + (TT_CMap_ValidateFunc) tt_cmap12_validate, + (TT_CMap_Info_GetFunc) tt_cmap12_get_info }; @@ -1865,6 +1966,7 @@ FT_ERROR(( "tt_face_build_cmaps:" )); FT_ERROR(( " broken cmap sub-table ignored!\n" )); } + break; } } } @@ -1874,4 +1976,16 @@ } + FT_LOCAL( FT_Error ) + tt_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ) + { + FT_CMap cmap = (FT_CMap)charmap; + TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; + + + return clazz->get_cmap_info( charmap, cmap_info ); + } + + /* END */ Index: xc/extras/freetype2/src/sfnt/ttcmap0.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/sfnt/ttcmap0.h,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 ttcmap0.h --- a/xc/extras/freetype2/src/sfnt/ttcmap0.h 25 Nov 2003 19:27:23 -0000 1.1.1.2 +++ b/xc/extras/freetype2/src/sfnt/ttcmap0.h 28 Apr 2004 10:26:06 -0000 @@ -4,7 +4,7 @@ /* */ /* TrueType new character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,7 +23,7 @@ #include #include FT_INTERNAL_TRUETYPE_TYPES_H #include FT_INTERNAL_OBJECTS_H - +#include FT_SERVICE_TT_CMAP_H FT_BEGIN_HEADER @@ -46,6 +46,7 @@ FT_CMap_ClassRec clazz; FT_UInt format; TT_CMap_ValidateFunc validate; + TT_CMap_Info_GetFunc get_cmap_info; } TT_CMap_ClassRec; @@ -65,6 +66,11 @@ FT_LOCAL( FT_Error ) tt_face_build_cmaps( TT_Face face ); + /* used in tt-cmaps service */ + FT_LOCAL( FT_Error ) + tt_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ); + FT_END_HEADER Index: xc/extras/freetype2/src/sfnt/ttload.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/sfnt/ttload.c,v retrieving revision 1.2 diff -u -r1.2 ttload.c --- a/xc/extras/freetype2/src/sfnt/ttload.c 23 Apr 2004 18:42:51 -0000 1.2 +++ b/xc/extras/freetype2/src/sfnt/ttload.c 28 Apr 2004 10:26:07 -0000 @@ -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 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,12 +16,12 @@ /* */ /***************************************************************************/ + #include #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include "ttload.h" -#include "ttcmap.h" #include "sferrors.h" @@ -253,7 +253,7 @@ /* stream :: The input stream. */ /* */ /* face_index :: If the font is a collection, the number of the font */ - /* in the collection, ignored otherwise. */ + /* in the collection. Must be zero otherwise. */ /* */ /* */ /* sfnt :: The SFNT header. */ @@ -276,7 +276,7 @@ SFNT_Header sfnt ) { FT_Error error; - FT_ULong format_tag, offset; + FT_ULong font_format_tag, format_tag, offset; FT_Memory memory = stream->memory; static const FT_Frame_Field sfnt_header_fields[] = @@ -313,16 +313,17 @@ face->num_tables = 0; - /* first of all, read the first 4 bytes. If it is `ttcf', then the */ - /* file is a TrueType collection, otherwise it can be any other */ - /* kind of font. */ - /* */ + /* First of all, read the first 4 bytes. If it is `ttcf', then the */ + /* file is a TrueType collection, otherwise it is a single-face font. */ + /* */ offset = FT_STREAM_POS(); - if ( FT_READ_ULONG( format_tag ) ) + if ( FT_READ_ULONG( font_format_tag ) ) goto Exit; - if ( format_tag == TTAG_ttcf ) + format_tag = font_format_tag; + + if ( font_format_tag == TTAG_ttcf ) { FT_Int n; @@ -354,8 +355,8 @@ /* seek to the appropriate TrueType file, then read tag */ offset = face->ttc_header.offsets[face_index]; - if ( FT_STREAM_SEEK( offset ) || - FT_READ_LONG( format_tag ) ) + if ( FT_STREAM_SEEK( offset ) || + FT_READ_LONG( format_tag ) ) goto Exit; } @@ -372,8 +373,13 @@ { FT_TRACE2(( "tt_face_load_sfnt_header: file is not SFNT!\n" )); error = SFNT_Err_Unknown_File_Format; + goto Exit; } + /* disallow face index values > 0 for non-TTC files */ + if ( font_format_tag != TTAG_ttcf && face_index > 0 ) + error = SFNT_Err_Bad_Argument; + Exit: return error; } @@ -740,12 +746,12 @@ face->root.num_glyphs = maxProfile->numGlyphs; face->root.internal->max_points = - (FT_UShort)MAX( maxProfile->maxCompositePoints, - maxProfile->maxPoints ); + (FT_UShort)FT_MAX( maxProfile->maxCompositePoints, + maxProfile->maxPoints ); face->root.internal->max_contours = - (FT_Short)MAX( maxProfile->maxCompositeContours, - maxProfile->maxContours ); + (FT_Short)FT_MAX( maxProfile->maxCompositeContours, + maxProfile->maxContours ); face->max_components = (FT_ULong)maxProfile->maxComponentElements + maxProfile->maxComponentDepth; @@ -896,7 +902,8 @@ /* do we have an inconsistent number of metric values? */ { TT_ShortMetrics* cur = *shorts; - TT_ShortMetrics* limit = cur + MIN( num_shorts, num_shorts_checked ); + TT_ShortMetrics* limit = cur + + FT_MIN( num_shorts, num_shorts_checked ); for ( ; cur < limit; cur++ ) Index: xc/extras/freetype2/src/sfnt/ttsbit.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/sfnt/ttsbit.c,v retrieving revision 1.2 diff -u -r1.2 ttsbit.c --- a/xc/extras/freetype2/src/sfnt/ttsbit.c 23 Apr 2004 18:42:51 -0000 1.2 +++ b/xc/extras/freetype2/src/sfnt/ttsbit.c 28 Apr 2004 10:26:09 -0000 @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -622,22 +622,22 @@ FT_LOCAL_DEF( FT_Error ) tt_face_set_sbit_strike( TT_Face face, - FT_Int x_ppem, - FT_Int y_ppem, + FT_UInt x_ppem, + FT_UInt y_ppem, FT_ULong *astrike_index ) { FT_ULong i; - if ( x_ppem < 0 || x_ppem > 255 || + if ( x_ppem > 255 || y_ppem < 1 || y_ppem > 255 ) return SFNT_Err_Invalid_PPem; for ( i = 0; i < face->num_sbit_strikes; i++ ) { - if ( ( face->sbit_strikes[i].y_ppem == y_ppem ) && - ( ( x_ppem == 0 ) || - ( face->sbit_strikes[i].x_ppem == x_ppem ) ) ) + if ( ( (FT_UInt)face->sbit_strikes[i].y_ppem == y_ppem ) && + ( ( x_ppem == 0 ) || + ( (FT_UInt)face->sbit_strikes[i].x_ppem == x_ppem ) ) ) { *astrike_index = i; return SFNT_Err_Ok; @@ -754,7 +754,7 @@ /*************************************************************************/ /* */ /* */ - /* find_sbit_image */ + /* tt_find_sbit_image */ /* */ /* */ /* Checks whether an embedded bitmap (an `sbit') exists for a given */ @@ -779,13 +779,13 @@ /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */ /* glyph. */ /* */ - static FT_Error - find_sbit_image( TT_Face face, - FT_UInt glyph_index, - FT_ULong strike_index, - TT_SBit_Range *arange, - TT_SBit_Strike *astrike, - FT_ULong *aglyph_offset ) + FT_LOCAL( FT_Error ) + tt_find_sbit_image( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ) { FT_Error error; TT_SBit_Strike strike; @@ -819,7 +819,7 @@ /*************************************************************************/ /* */ /* */ - /* load_sbit_metrics */ + /* tt_load_sbit_metrics */ /* */ /* */ /* Gets the big metrics for a given SBit. */ @@ -843,10 +843,10 @@ /* positioned just after the metrics header in the `EBDT' table on */ /* function exit. */ /* */ - static FT_Error - load_sbit_metrics( FT_Stream stream, - TT_SBit_Range range, - TT_SBit_Metrics metrics ) + FT_LOCAL( FT_Error ) + tt_load_sbit_metrics( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ) { FT_Error error = SFNT_Err_Ok; @@ -1228,7 +1228,7 @@ if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) ) goto Exit; - error = load_sbit_metrics( stream, range, metrics ); + error = tt_load_sbit_metrics( stream, range, metrics ); if ( error ) goto Exit; @@ -1419,8 +1419,8 @@ /* Check whether there is a glyph sbit for the current index */ - error = find_sbit_image( face, glyph_index, strike_index, - &range, &strike, &glyph_offset ); + error = tt_find_sbit_image( face, glyph_index, strike_index, + &range, &strike, &glyph_offset ); if ( error ) goto Exit; Index: xc/extras/freetype2/src/sfnt/ttsbit.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/sfnt/ttsbit.h,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 ttsbit.h --- a/xc/extras/freetype2/src/sfnt/ttsbit.h 25 Nov 2003 19:27:23 -0000 1.1.1.2 +++ b/xc/extras/freetype2/src/sfnt/ttsbit.h 28 Apr 2004 10:26:09 -0000 @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -37,11 +37,24 @@ FT_LOCAL( FT_Error ) tt_face_set_sbit_strike( TT_Face face, - FT_Int x_ppem, - FT_Int y_ppem, + FT_UInt x_ppem, + FT_UInt y_ppem, FT_ULong *astrike_index ); FT_LOCAL( FT_Error ) + tt_find_sbit_image( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ); + + FT_LOCAL( FT_Error ) + tt_load_sbit_metrics( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ); + + FT_LOCAL( FT_Error ) tt_face_load_sbit_image( TT_Face face, FT_ULong strike_index, FT_UInt glyph_index, Index: xc/extras/freetype2/src/smooth/ftsmooth.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/smooth/ftsmooth.c,v retrieving revision 1.2 diff -u -r1.2 ftsmooth.c --- a/xc/extras/freetype2/src/smooth/ftsmooth.c 23 Apr 2004 18:42:52 -0000 1.2 +++ b/xc/extras/freetype2/src/smooth/ftsmooth.c 28 Apr 2004 10:26:10 -0000 @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -132,10 +132,10 @@ /* compute the control box, and grid fit it */ FT_Outline_Get_CBox( outline, &cbox ); - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); @@ -154,7 +154,7 @@ if ( hmul ) { width = width * hmul; - pitch = ( width + 3 ) & -4; + pitch = FT_PAD_CEIL( width, 4 ); } if ( vmul ) @@ -236,6 +236,9 @@ FT_Render_Mode mode, FT_Vector* origin ) { + if ( mode == FT_RENDER_MODE_LIGHT ) + mode = FT_RENDER_MODE_NORMAL; + return ft_smooth_render_generic( render, slot, mode, origin, FT_RENDER_MODE_NORMAL, 0, 0 ); Index: xc/extras/freetype2/src/tools/docmaker/content.py =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/tools/docmaker/content.py,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 content.py --- a/xc/extras/freetype2/src/tools/docmaker/content.py 25 Nov 2003 19:27:23 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/tools/docmaker/content.py 28 Apr 2004 10:26:13 -0000 @@ -56,8 +56,16 @@ self.lines.append( l ) def dump( self, prefix = "", width=60 ): - for l in self.lines: + lines = self.dump_lines( 0, width ) + for l in lines: print prefix + l + + def dump_lines( self, margin=0, width=60 ): + result = [] + for l in self.lines: + result.append( " "*margin + l ) + return result + ############################################################################# @@ -76,8 +84,14 @@ self.words.extend( string.split( l ) ) def dump( self, prefix = "", width = 60 ): - cur = "" # current line - col = 0 # current width + lines = self.dump_lines( 0, width ) + for l in lines: + print prefix + l + + def dump_lines( self, margin=0, width = 60 ): + cur = "" # current line + col = 0 # current width + result = [] for word in self.words: ln = len(word) @@ -85,7 +99,7 @@ ln = ln+1 if col + ln > width: - print prefix + cur + result.append( " "*margin + cur ) cur = word col = len(word) else: @@ -95,8 +109,11 @@ col = col + ln if col > 0: - print prefix + cur + result.append( " "*margin + cur ) + + return result + ############################################################################# @@ -187,6 +204,17 @@ p.dump( prefix ) first = 0 + def dump_lines( self, margin=0, width=60 ): + result = [] + nl = None + for p in self.items: + if nl: + result.append( "" ) + + result.extend( p.dump_lines( margin, width ) ) + nl = 1 + + return result # this regular expression is used to detect field definitions # @@ -233,6 +261,16 @@ except: return None + + def get_start( self ): + try: + result = "" + for word in self.fields[0].items[0].words: + result = result + " " + word + return result[1:] + + except: + return "ERROR" def dump( self, margin ): print " "*margin + "<" + self.tag + ">" @@ -544,4 +582,4 @@ m = self.get_markup( tag_name ) return m.fields[0].items except: - return None \ No newline at end of file + return None Index: xc/extras/freetype2/src/tools/docmaker/docbeauty.py =================================================================== RCS file: xc/extras/freetype2/src/tools/docmaker/docbeauty.py diff -N xc/extras/freetype2/src/tools/docmaker/docbeauty.py --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/extras/freetype2/src/tools/docmaker/docbeauty.py 28 Apr 2004 10:26:13 -0000 @@ -0,0 +1,109 @@ +#!/usr/bin/env python +# +# DocBeauty (c) 2003, 2004 David Turner +# +# This program is used to beautify the documentation comments used +# in the FreeType 2 public headers. +# + +from sources import * +from content import * +from utils import * + +import utils + +import sys, os, time, string, getopt + +content_processor = ContentProcessor() + + +def beautify_block( block ): + if block.content: + content_processor.reset() + + markups = content_processor.process_content( block.content ) + text = [] + first = 1 + + for markup in markups: + text.extend( markup.beautify( first ) ) + first = 0 + + # now beautify the documentation "borders" themselves + lines = [ " /*************************************************************************" ] + for l in text: + lines.append( " *" + l ) + lines.append( " */" ) + + block.lines = lines + + +def usage(): + print "\nDocBeauty 0.1 Usage information\n" + print " docbeauty [options] file1 [ file2 ... ]\n" + print "using the following options:\n" + print " -h : print this page" + print " -b : backup original files with the 'orig' extension" + print "" + print " --backup : same as -b" + + +def main( argv ): + """main program loop""" + + global output_dir + + try: + opts, args = getopt.getopt( sys.argv[1:], + "hb", + [ "help", "backup" ] ) + + except getopt.GetoptError: + usage() + sys.exit( 2 ) + + if args == []: + usage() + sys.exit( 1 ) + + # process options + # + output_dir = None + do_backup = None + + for opt in opts: + if opt[0] in ( "-h", "--help" ): + usage() + sys.exit( 0 ) + + if opt[0] in ( "-b", "--backup" ): + do_backup = 1 + + # create context and processor + source_processor = SourceProcessor() + + # retrieve the list of files to process + file_list = make_file_list( args ) + for filename in file_list: + source_processor.parse_file( filename ) + for block in source_processor.blocks: + beautify_block( block ) + new_name = filename + ".new" + ok = None + try: + file = open( new_name, "wt" ) + for block in source_processor.blocks: + for line in block.lines: + file.write( line ) + file.write( "\n" ) + file.close() + except: + ok = 0 + +# if called from the command line +# +if __name__ == '__main__': + main( sys.argv ) + + +# eof Index: xc/extras/freetype2/src/tools/docmaker/docmaker.py =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/tools/docmaker/docmaker.py,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 docmaker.py --- a/xc/extras/freetype2/src/tools/docmaker/docmaker.py 25 Nov 2003 19:27:23 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/tools/docmaker/docmaker.py 28 Apr 2004 10:26:14 -0000 @@ -1,16 +1,16 @@ #!/usr/bin/env python # -# DocMaker 0.2 (c) 2002 David Turner +# DocMaker (c) 2002, 2004 David Turner # # This program is a re-write of the original DocMaker took used # to generate the API Reference of the FreeType font engine -# by converting in-source comments into structured HTML +# by converting in-source comments into structured HTML. # # This new version is capable of outputting XML data, as well -# as accepts more liberal formatting options +# as accepts more liberal formatting options. # # It also uses regular expression matching and substitution -# to speed things significantly +# to speed things significantly. # from sources import * @@ -24,50 +24,8 @@ import sys, os, time, string, glob, getopt -def file_exists( pathname ): - """checks that a given file exists""" - result = 1 - try: - file = open( pathname, "r" ) - file.close() - except: - result = None - sys.stderr.write( pathname + " couldn't be accessed\n" ) - - return result - - -def make_file_list( args = None ): - """builds a list of input files from command-line arguments""" - - file_list = [] - # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' ) - - if not args: - args = sys.argv[1 :] - - for pathname in args: - if string.find( pathname, '*' ) >= 0: - newpath = glob.glob( pathname ) - newpath.sort() # sort files -- this is important because - # of the order of files - else: - newpath = [pathname] - - file_list.extend( newpath ) - - if len( file_list ) == 0: - file_list = None - else: - # now filter the file list to remove non-existing ones - file_list = filter( file_exists, file_list ) - - return file_list - - - def usage(): - print "\nDocMaker 0.2 Usage information\n" + print "\nDocMaker Usage information\n" print " docmaker [options] file1 [ file2 ... ]\n" print "using the following options:\n" print " -h : print this page" Index: xc/extras/freetype2/src/tools/docmaker/formatter.py =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/tools/docmaker/formatter.py,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 formatter.py --- a/xc/extras/freetype2/src/tools/docmaker/formatter.py 25 Nov 2003 19:27:23 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/tools/docmaker/formatter.py 28 Apr 2004 10:26:14 -0000 @@ -2,6 +2,15 @@ from content import * from utils import * +# This is the base Formatter class. its purpose is to convert +# a content processor's data into specific documents (i.e. table of +# contents, global index, and individual API reference indices). +# +# You'll need to sub-class it to output anything sensible. For example, +# the file tohtml.py contains the definition of the HtmlFormatter sub-class +# used to output, you guessed it, HTML. +# + class Formatter: def __init__( self, processor ): Index: xc/extras/freetype2/src/tools/docmaker/sources.py =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/tools/docmaker/sources.py,v retrieving revision 1.2 diff -u -r1.2 sources.py --- a/xc/extras/freetype2/src/tools/docmaker/sources.py 23 Apr 2004 18:42:53 -0000 1.2 +++ b/xc/extras/freetype2/src/tools/docmaker/sources.py 28 Apr 2004 10:26:14 -0000 @@ -200,7 +200,7 @@ self.processor = processor self.filename = filename self.lineno = lineno - self.lines = lines + self.lines = lines[:] self.format = processor.format self.content = [] @@ -212,7 +212,7 @@ # extract comment lines lines = [] - for line0 in self.lines[1:]: + for line0 in self.lines: m = self.format.column.match( line0 ) if m: lines.append( m.group(1) ) @@ -304,7 +304,7 @@ if self.format.end.match( line ): # that's a normal block end, add it to lines and # create a new block - # self.lines.append( line ) + self.lines.append( line ) self.add_block_lines() elif self.format.column.match( line ): Index: xc/extras/freetype2/src/tools/docmaker/utils.py =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/tools/docmaker/utils.py,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 utils.py --- a/xc/extras/freetype2/src/tools/docmaker/utils.py 25 Nov 2003 19:27:23 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/tools/docmaker/utils.py 28 Apr 2004 10:26:14 -0000 @@ -1,4 +1,4 @@ -import string, sys, os +import string, sys, os, glob # current output directory # @@ -85,3 +85,44 @@ sys.exit( 2 ) else: output_dir = None + +def file_exists( pathname ): + """checks that a given file exists""" + result = 1 + try: + file = open( pathname, "r" ) + file.close() + except: + result = None + sys.stderr.write( pathname + " couldn't be accessed\n" ) + + return result + + +def make_file_list( args = None ): + """builds a list of input files from command-line arguments""" + + file_list = [] + # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' ) + + if not args: + args = sys.argv[1 :] + + for pathname in args: + if string.find( pathname, '*' ) >= 0: + newpath = glob.glob( pathname ) + newpath.sort() # sort files -- this is important because + # of the order of files + else: + newpath = [pathname] + + file_list.extend( newpath ) + + if len( file_list ) == 0: + file_list = None + else: + # now filter the file list to remove non-existing ones + file_list = filter( file_exists, file_list ) + + return file_list + Index: xc/extras/freetype2/src/truetype/ttdriver.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/truetype/ttdriver.c,v retrieving revision 1.2 diff -u -r1.2 ttdriver.c --- a/xc/extras/freetype2/src/truetype/ttdriver.c 23 Apr 2004 18:42:53 -0000 1.2 +++ b/xc/extras/freetype2/src/truetype/ttdriver.c 28 Apr 2004 10:26:15 -0000 @@ -4,7 +4,7 @@ /* */ /* TrueType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -208,8 +208,8 @@ /* we need to use rounding in the following computations. Otherwise, * the resulting hinted outlines will be very slightly distorted */ - dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & -64; - dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64; + dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & ~63; + dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & ~63; } else { @@ -293,7 +293,7 @@ static FT_Error Load_Glyph( TT_GlyphSlot slot, TT_Size size, - FT_UShort glyph_index, + FT_UInt glyph_index, FT_Int32 load_flags ) { FT_Error error; Index: xc/extras/freetype2/src/truetype/ttgload.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/truetype/ttgload.c,v retrieving revision 1.2 diff -u -r1.2 ttgload.c --- a/xc/extras/freetype2/src/truetype/ttgload.c 23 Apr 2004 18:42:53 -0000 1.2 +++ b/xc/extras/freetype2/src/truetype/ttgload.c 28 Apr 2004 10:26:16 -0000 @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -162,11 +162,62 @@ } + /*************************************************************************/ + /* */ + /* Returns the vertical metrics in font units for a given glyph. */ + /* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */ + /* table, typoAscender/Descender from the `OS/2' table would be used */ + /* instead, and if there were no `OS/2' table, use ascender/descender */ + /* from the `hhea' table. But that is not what Microsoft's rasterizer */ + /* apparently does: It uses the ppem value as the advance height, and */ + /* sets the top side bearing to be zero. */ + /* */ + /* The monospace `check' is probably not meaningful here, but we leave */ + /* it in for a consistent interface. */ + /* */ + static void + Get_VMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* tsb, + FT_UShort* ah ) + { + FT_UNUSED( check ); + + if ( face->vertical_info ) + TT_Get_Metrics( (TT_HoriHeader *)&face->vertical, idx, tsb, ah ); + +#if 1 /* Emperically determined, at variance with what MS said */ + + else + { + *tsb = 0; + *ah = face->root.units_per_EM; + } + +#else /* This is what MS said to do. It isn't what they do, however. */ + + else if ( face->os2.version != 0xFFFFU ) + { + *tsb = face->os2.sTypoAscender; + *ah = face->os2.sTypoAscender - face->os2.sTypoDescender; + } + else + { + *tsb = face->horizontal.Ascender; + *ah = face->horizontal.Ascender - face->horizontal.Descender; + } + +#endif + + } + + #define cur_to_org( n, zone ) \ - FT_MEM_COPY( (zone)->org, (zone)->cur, (n) * sizeof ( FT_Vector ) ) + FT_ARRAY_COPY( (zone)->org, (zone)->cur, (n) ) #define org_to_cur( n, zone ) \ - FT_MEM_COPY( (zone)->cur, (zone)->org, (n) * sizeof ( FT_Vector ) ) + FT_ARRAY_COPY( (zone)->cur, (zone)->org, (n) ) /*************************************************************************/ @@ -317,7 +368,7 @@ if ( n_contours > 0 ) n_points = cont[-1] + 1; - error = FT_GlyphLoader_CheckPoints( gloader, n_points + 2, 0 ); + error = FT_GlyphLoader_CheckPoints( gloader, n_points + 4, 0 ); if ( error ) goto Fail; @@ -635,12 +686,16 @@ /* add shadow points */ - /* Now add the two shadow points at n and n + 1. */ + /* Add two horizontal shadow points at n and n+1. */ /* We need the left side bearing and advance width. */ + /* Add two vertical shadow points at n+2 and n+3. */ + /* We need the top side bearing and advance height. */ { FT_Vector* pp1; FT_Vector* pp2; + FT_Vector* pp3; + FT_Vector* pp4; /* pp1 = xMin - lsb */ @@ -653,14 +708,26 @@ pp2->x = pp1->x + load->advance; pp2->y = 0; + /* pp3 = top side bearing */ + pp3 = pp1 + 2; + pp3->x = 0; + pp3->y = load->top_bearing + load->bbox.yMax; + + /* pp4 = pp3 - ah */ + pp4 = pp1 + 3; + pp4->x = 0; + pp4->y = pp3->y - load->vadvance; + outline->tags[n_points ] = 0; outline->tags[n_points + 1] = 0; + outline->tags[n_points + 2] = 0; + outline->tags[n_points + 3] = 0; } /* Note that we return two more points that are not */ /* part of the glyph outline. */ - n_points += 2; + n_points += 4; /* set up zone for hinting */ tt_prepare_zone( zone, &gloader->current, 0, 0 ); @@ -687,15 +754,18 @@ /* eventually hint the glyph */ if ( IS_HINTED( load->load_flags ) ) { - FT_Pos x = zone->org[n_points-2].x; + FT_Pos x = zone->org[n_points-4].x; + FT_Pos y = zone->org[n_points-2].y; - x = ( ( x + 32 ) & -64 ) - x; - translate_array( n_points, zone->org, x, 0 ); + x = FT_PIX_ROUND( x ) - x; + y = FT_PIX_ROUND( y ) - y; + translate_array( n_points, zone->org, x, y ); org_to_cur( n_points, zone ); - zone->cur[n_points - 1].x = ( zone->cur[n_points - 1].x + 32 ) & -64; + zone->cur[n_points - 3].x = FT_PIX_ROUND( zone->cur[n_points - 3].x ); + zone->cur[n_points - 1].y = FT_PIX_ROUND( zone->cur[n_points - 1].y ); #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER @@ -711,7 +781,7 @@ load->exec->pedantic_hinting = (FT_Bool)( load->load_flags & FT_LOAD_PEDANTIC ); load->exec->pts = *zone; - load->exec->pts.n_points += 2; + load->exec->pts.n_points += 4; error = TT_Run_Context( load->exec, debug ); if ( error && load->exec->pedantic_hinting ) @@ -727,8 +797,10 @@ /* save glyph phantom points */ if ( !load->preserve_pps ) { - load->pp1 = zone->cur[n_points - 2]; - load->pp2 = zone->cur[n_points - 1]; + load->pp1 = zone->cur[n_points - 4]; + load->pp2 = zone->cur[n_points - 3]; + load->pp3 = zone->cur[n_points - 2]; + load->pp4 = zone->cur[n_points - 1]; } #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER @@ -797,16 +869,22 @@ y_scale = loader->size->metrics.y_scale; } - /* get horizontal metrics */ + /* get metrics, horizontal and vertical */ { - FT_Short left_bearing = 0; - FT_UShort advance_width = 0; + FT_Short left_bearing = 0, top_bearing = 0; + FT_UShort advance_width = 0, advance_height = 0; + Get_HMetrics( face, glyph_index, (FT_Bool)!( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), &left_bearing, &advance_width ); + Get_VMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &top_bearing, + &advance_height ); #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -830,10 +908,33 @@ advance_width = (FT_UShort)metrics.advance; } +# if 0 + /* GWW: Do I do the same for vertical metrics ??? */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + + metrics.bearing_x = 0; + metrics.bearing_y = top_bearing; + metrics.advance = advance_height; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, TRUE, &metrics ); + if ( error ) + goto Exit; + top_bearing = (FT_Short)metrics.bearing_y; + advance_height = (FT_UShort)metrics.advance; + } +# endif + #endif /* FT_CONFIG_OPTION_INCREMENTAL */ loader->left_bearing = left_bearing; loader->advance = advance_width; + loader->top_bearing = top_bearing; + loader->vadvance = advance_height; if ( !loader->linear_def ) { @@ -893,9 +994,14 @@ loader->pp1.x = 0; loader->pp2.x = loader->advance; + loader->pp3.y = 0; + loader->pp4.y = loader->pp3.y-loader->vadvance; if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); + } #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER @@ -933,10 +1039,17 @@ loader->pp2.x = loader->pp1.x + loader->advance; loader->pp2.y = 0; + loader->pp3.x = 0; + loader->pp3.y = loader->top_bearing + loader->bbox.yMax; + loader->pp4.x = 0; + loader->pp4.y = loader->pp3.y - loader->vadvance; + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); + loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); } /***********************************************************************/ @@ -1045,7 +1158,7 @@ for ( n = 0; n < (FT_Int)num_subglyphs; n++ ) { - FT_Vector pp1, pp2; + FT_Vector pp1, pp2, pp3, pp4; FT_Pos x, y; @@ -1057,6 +1170,8 @@ pp1 = loader->pp1; pp2 = loader->pp2; + pp3 = loader->pp3; + pp4 = loader->pp4; num_base_points = gloader->base.outline.n_points; @@ -1072,11 +1187,15 @@ { pp1 = loader->pp1; pp2 = loader->pp2; + pp3 = loader->pp3; + pp4 = loader->pp4; } else { loader->pp1 = pp1; loader->pp2 = pp2; + loader->pp3 = pp3; + loader->pp4 = pp4; } num_points = gloader->base.outline.n_points; @@ -1202,8 +1321,8 @@ if ( subglyph->flags & ROUND_XY_TO_GRID ) { - x = ( x + 32 ) & -64; - y = ( y + 32 ) & -64; + x = FT_PIX_ROUND( x ); + y = FT_PIX_ROUND( y ); } } } @@ -1273,7 +1392,7 @@ if ( error ) goto Fail; - error = FT_GlyphLoader_CheckPoints( gloader, num_points + 2, 0 ); + error = FT_GlyphLoader_CheckPoints( gloader, num_points + 4, 0 ); if ( error ) goto Fail; @@ -1282,22 +1401,28 @@ start_point, start_contour ); pts = &exec->pts; - pts->n_points = (short)(num_points + 2); + pts->n_points = (short)( num_points + 4 ); pts->n_contours = gloader->base.outline.n_contours; /* add phantom points */ pp1 = pts->cur + num_points; pp1[0] = loader->pp1; pp1[1] = loader->pp2; + pp1[2] = loader->pp3; + pp1[3] = loader->pp4; pts->tags[num_points ] = 0; pts->tags[num_points + 1] = 0; + pts->tags[num_points + 2] = 0; + pts->tags[num_points + 3] = 0; /* if hinting, round the phantom points */ if ( IS_HINTED( loader->load_flags ) ) { - pp1[0].x = ( ( loader->pp1.x + 32 ) & -64 ); - pp1[1].x = ( ( loader->pp2.x + 32 ) & -64 ); + pp1[0].x = FT_PIX_ROUND( loader->pp1.x ); + pp1[1].x = FT_PIX_ROUND( loader->pp2.x ); + pp1[2].y = FT_PIX_ROUND( loader->pp3.y ); + pp1[3].y = FT_PIX_ROUND( loader->pp4.y ); } { @@ -1308,7 +1433,7 @@ pts->tags[k] &= FT_CURVE_TAG_ON; } - cur_to_org( num_points + 2, pts ); + cur_to_org( num_points + 4, pts ); /* now consider hinting */ if ( IS_HINTED( loader->load_flags ) && n_ins > 0 ) @@ -1324,6 +1449,8 @@ /* save glyph origin and advance points */ loader->pp1 = pp1[0]; loader->pp2 = pp1[1]; + loader->pp3 = pp1[2]; + loader->pp4 = pp1[3]; } #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ @@ -1390,10 +1517,10 @@ if ( IS_HINTED( loader->load_flags ) ) { /* grid-fit the bounding box */ - bbox.xMin &= -64; - bbox.yMin &= -64; - bbox.xMax = ( bbox.xMax + 63 ) & -64; - bbox.yMax = ( bbox.yMax + 63 ) & -64; + bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); + bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); + bbox.xMax = FT_PIX_CEIL( bbox.xMax ); + bbox.yMax = FT_PIX_CEIL( bbox.yMax ); } } else @@ -1425,7 +1552,7 @@ /* don't forget to hint the advance when we need to */ if ( IS_HINTED( loader->load_flags ) ) - glyph->metrics.horiAdvance = ( glyph->metrics.horiAdvance + 32 ) & -64; + glyph->metrics.horiAdvance = FT_PIX_ROUND( glyph->metrics.horiAdvance ); /* Now take care of vertical metrics. In the case where there is */ /* no vertical information within the font (relatively common), make */ @@ -1443,13 +1570,9 @@ if ( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ) { - /* Don't assume that both the vertical header and vertical */ - /* metrics are present in the same font :-) */ + advance_height = loader->pp4.y - loader->pp3.y; + top_bearing = loader->pp3.y - bbox.yMax; - TT_Get_Metrics( (TT_HoriHeader*)&face->vertical, - glyph_index, - &top_bearing, - &advance_height ); } else { @@ -1465,6 +1588,12 @@ /* here with: */ /* ascender - descender + linegap */ /* */ + /* NOTE3: This is different from what MS's rasterizer */ + /* appears to do when getting default values */ + /* for the vertical phantom points. We leave */ + /* the old code untouched, but relying on */ + /* phantom points alone might be reasonable */ + /* (i.e., removing the `if' above). */ if ( face->os2.version != 0xFFFFU ) { top_bearing = (FT_Short)( face->os2.sTypoLineGap / 2 ); @@ -1507,6 +1636,8 @@ advance_height = (FT_UShort)metrics.advance; } + /* GWW: Do vertical metrics get loaded incrementally too? */ + #endif /* FT_CONFIG_OPTION_INCREMENTAL */ /* We must adjust the top_bearing value from the bounding box given */ @@ -1538,9 +1669,9 @@ /* grid-fit them if necessary */ if ( IS_HINTED( loader->load_flags ) ) { - left &= -64; - top = ( top + 63 ) & -64; - advance = ( advance + 32 ) & -64; + left = FT_PIX_FLOOR( left ); + top = FT_PIX_CEIL( top ); + advance = FT_PIX_ROUND( advance ); } glyph->metrics.vertBearingX = left; @@ -1598,7 +1729,7 @@ FT_LOCAL_DEF( FT_Error ) TT_Load_Glyph( TT_Size size, TT_GlyphSlot glyph, - FT_UShort glyph_index, + FT_UInt glyph_index, FT_Int32 load_flags ) { SFNT_Service sfnt; @@ -1641,7 +1772,7 @@ error = sfnt->load_sbit_image( face, (FT_ULong)size->strike_index, - (FT_UInt)glyph_index, + glyph_index, (FT_Int)load_flags, stream, &glyph->bitmap, Index: xc/extras/freetype2/src/truetype/ttgload.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/truetype/ttgload.h,v retrieving revision 1.2 diff -u -r1.2 ttgload.h --- a/xc/extras/freetype2/src/truetype/ttgload.h 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/truetype/ttgload.h 28 Apr 2004 10:26:16 -0000 @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -43,7 +43,7 @@ FT_LOCAL( FT_Error ) TT_Load_Glyph( TT_Size size, TT_GlyphSlot glyph, - FT_UShort glyph_index, + FT_UInt glyph_index, FT_Int32 load_flags ); Index: xc/extras/freetype2/src/truetype/ttinterp.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/truetype/ttinterp.c,v retrieving revision 1.2 diff -u -r1.2 ttinterp.c --- a/xc/extras/freetype2/src/truetype/ttinterp.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/truetype/ttinterp.c 28 Apr 2004 10:26:19 -0000 @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,9 +30,10 @@ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#define TT_MULFIX FT_MulFix -#define TT_MULDIV FT_MulDiv -#define TT_INT64 FT_Int64 +#define TT_MULFIX FT_MulFix +#define TT_MULDIV FT_MulDiv +#define TT_MULDIV_NO_ROUND FT_MulDiv_No_Round + /*************************************************************************/ /* */ @@ -162,6 +163,9 @@ #define CUR_Func_move( z, p, d ) \ CUR.func_move( EXEC_ARG_ z, p, d ) +#define CUR_Func_move_orig( z, p, d ) \ + CUR.func_move_orig( EXEC_ARG_ z, p, d ) + #define CUR_Func_dualproj( x, y ) \ CUR.func_dualproj( EXEC_ARG_ x, y ) @@ -515,8 +519,7 @@ if ( *size < new_max ) { - FT_FREE( *buff ); - if ( FT_ALLOC( *buff, new_max * multiplier ) ) + if ( FT_REALLOC( *buff, *size, new_max * multiplier ) ) return error; *size = new_max; } @@ -1566,7 +1569,6 @@ if ( v != 0 ) { - zone->cur[point].x += TT_MULDIV( distance, v * 0x10000L, CUR.F_dot_P ); @@ -1578,7 +1580,6 @@ if ( v != 0 ) { - zone->cur[point].y += TT_MULDIV( distance, v * 0x10000L, CUR.F_dot_P ); @@ -1590,6 +1591,51 @@ /*************************************************************************/ /* */ + /* */ + /* Direct_Move_Orig */ + /* */ + /* */ + /* Moves the *original* position of a point by a given distance along */ + /* the freedom vector. Obviously, the point will not be `touched'. */ + /* */ + /* */ + /* point :: The index of the point to move. */ + /* */ + /* distance :: The distance to apply. */ + /* */ + /* */ + /* zone :: The affected glyph zone. */ + /* */ + static void + Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_F26Dot6 v; + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_ASSERT( !CUR.face->unpatented_hinting ); +#endif + + v = CUR.GS.freeVector.x; + + if ( v != 0 ) + zone->org[point].x += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + + v = CUR.GS.freeVector.y; + + if ( v != 0 ) + zone->org[point].y += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + } + + + /*************************************************************************/ + /* */ /* Special versions of Direct_Move() */ /* */ /* The following versions are used whenever both vectors are both */ @@ -1624,6 +1670,38 @@ /*************************************************************************/ /* */ + /* Special versions of Direct_Move_Orig() */ + /* */ + /* The following versions are used whenever both vectors are both */ + /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* */ + /*************************************************************************/ + + + static void + Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->org[point].x += distance; + } + + + static void + Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->org[point].y += distance; + } + + + /*************************************************************************/ + /* */ /* */ /* Round_None */ /* */ @@ -1656,7 +1734,7 @@ if ( distance >= 0 ) { val = distance + compensation; - if ( val < 0 ) + if ( distance && val < 0 ) val = 0; } else { @@ -1696,14 +1774,14 @@ if ( distance >= 0 ) { val = distance + compensation + 32; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~63; else val = 0; } else { - val = -( ( compensation - distance + 32 ) & -64 ); + val = -FT_PIX_ROUND( compensation - distance ); if ( val > 0 ) val = 0; } @@ -1739,13 +1817,13 @@ if ( distance >= 0 ) { - val = ( ( distance + compensation ) & -64 ) + 32; - if ( val < 0 ) + val = FT_PIX_FLOOR( distance + compensation ) + 32; + if ( distance && val < 0 ) val = 0; } else { - val = -( ( (compensation - distance) & -64 ) + 32 ); + val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); if ( val > 0 ) val = 0; } @@ -1782,7 +1860,7 @@ if ( distance >= 0 ) { val = distance + compensation; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~63; else val = 0; @@ -1826,14 +1904,14 @@ if ( distance >= 0 ) { val = distance + compensation + 63; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~63; else val = 0; } else { - val = -( ( compensation - distance + 63 ) & -64 ); + val = - FT_PIX_CEIL( compensation - distance ); if ( val > 0 ) val = 0; } @@ -1870,14 +1948,14 @@ if ( distance >= 0 ) { val = distance + compensation + 16; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~31; else val = 0; } else { - val = -( ( compensation - distance + 16 ) & -32 ); + val = -FT_PAD_ROUND( compensation - distance, 32 ); if ( val > 0 ) val = 0; } @@ -1919,7 +1997,7 @@ { val = ( distance - CUR.phase + CUR.threshold + compensation ) & -CUR.period; - if ( val < 0 ) + if ( distance && val < 0 ) val = 0; val += CUR.phase; } @@ -1967,7 +2045,7 @@ { val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / CUR.period ) * CUR.period; - if ( val < 0 ) + if ( distance && val < 0 ) val = 0; val += CUR.phase; } @@ -2243,13 +2321,15 @@ if ( CUR.GS.both_x_axis ) { - CUR.func_project = Project_x; - CUR.func_move = Direct_Move_X; + CUR.func_project = Project_x; + CUR.func_move = Direct_Move_X; + CUR.func_move_orig = Direct_Move_Orig_X; } else { - CUR.func_project = Project_y; - CUR.func_move = Direct_Move_Y; + CUR.func_project = Project_y; + CUR.func_move = Direct_Move_Y; + CUR.func_move_orig = Direct_Move_Orig_Y; } if ( CUR.GS.dualVector.x == 0x4000 ) @@ -2300,23 +2380,30 @@ CUR.func_dualproj = (TT_Project_Func)Dual_Project; } - CUR.func_move = (TT_Move_Func)Direct_Move; + CUR.func_move = (TT_Move_Func)Direct_Move; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig; if ( CUR.F_dot_P == 0x40000000L ) { if ( CUR.GS.freeVector.x == 0x4000 ) - CUR.func_move = (TT_Move_Func)Direct_Move_X; + { + CUR.func_move = (TT_Move_Func)Direct_Move_X; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; + } else { if ( CUR.GS.freeVector.y == 0x4000 ) - CUR.func_move = (TT_Move_Func)Direct_Move_Y; + { + CUR.func_move = (TT_Move_Func)Direct_Move_Y; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; + } } } /* at small sizes, F_dot_P can become too small, resulting */ /* in overflows and `spikes' in a number of glyphs like `w'. */ - if ( ABS( CUR.F_dot_P ) < 0x4000000L ) + if ( FT_ABS( CUR.F_dot_P ) < 0x4000000L ) CUR.F_dot_P = 0x40000000L; /* Disable cached aspect ratio */ @@ -2359,7 +2446,7 @@ FT_UNUSED_EXEC; - if ( ABS( Vx ) < 0x10000L && ABS( Vy ) < 0x10000L ) + if ( FT_ABS( Vx ) < 0x10000L && FT_ABS( Vy ) < 0x10000L ) { Vx *= 0x100; Vy *= 0x100; @@ -2887,19 +2974,19 @@ args[0] -= args[1]; -#define DO_DIV \ - if ( args[1] == 0 ) \ - CUR.error = TT_Err_Divide_By_Zero; \ - else \ - args[0] = TT_MULDIV( args[0], 64L, args[1] ); +#define DO_DIV \ + if ( args[1] == 0 ) \ + CUR.error = TT_Err_Divide_By_Zero; \ + else \ + args[0] = TT_MULDIV_NO_ROUND( args[0], 64L, args[1] ); #define DO_MUL \ args[0] = TT_MULDIV( args[0], args[1], 64L ); -#define DO_ABS \ - args[0] = ABS( args[0] ); +#define DO_ABS \ + args[0] = FT_ABS( args[0] ); #define DO_NEG \ @@ -2907,11 +2994,11 @@ #define DO_FLOOR \ - args[0] &= -64; + args[0] = FT_PIX_FLOOR( args[0] ); #define DO_CEILING \ - args[0] = ( args[0] + 63 ) & -64; + args[0] = FT_PIX_CEIL( args[0] ); #define DO_RS \ @@ -4019,9 +4106,9 @@ K = CUR.stack[CUR.args - L]; - FT_MEM_MOVE( &CUR.stack[CUR.args - L ], - &CUR.stack[CUR.args - L + 1], - ( L - 1 ) * sizeof ( FT_Long ) ); + FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ], + &CUR.stack[CUR.args - L + 1], + ( L - 1 ) ); CUR.stack[CUR.args - 1] = K; } @@ -5201,7 +5288,7 @@ { *x = 0; *y = d; - } + } } else #endif @@ -5359,11 +5446,11 @@ last_point = 0; } - /* XXX: UNDOCUMENTED! SHC doesn't touch the points */ + /* XXX: UNDOCUMENTED! SHC does touch the points */ for ( i = first_point; i <= last_point; i++ ) { if ( zp.cur != CUR.zp2.cur || refp != i ) - MOVE_Zp2_Point( i, dx, dy, FALSE ); + MOVE_Zp2_Point( i, dx, dy, TRUE ); } } @@ -5498,9 +5585,11 @@ } /* XXX: UNDOCUMENTED! behaviour */ - if ( CUR.GS.gep0 == 0 ) /* if in twilight zone */ + if ( CUR.GS.gep1 == 0 ) /* if the point that is to be moved */ + /* is in twilight zone */ { CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; + CUR_Func_move_orig( &CUR.zp1, point, args[1] ); CUR.zp1.cur[point] = CUR.zp1.org[point]; } @@ -5619,7 +5708,7 @@ if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cutin flag */ { - if ( ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) + if ( FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) distance = org_dist; distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] ); @@ -5663,7 +5752,7 @@ /* single width cutin test */ - if ( ABS( org_dist - CUR.GS.single_width_value ) < + if ( FT_ABS( org_dist - CUR.GS.single_width_value ) < CUR.GS.single_width_cutin ) { if ( org_dist >= 0 ) @@ -5753,7 +5842,7 @@ /* single width test */ - if ( ABS( cvt_dist - CUR.GS.single_width_value ) < + if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) < CUR.GS.single_width_cutin ) { if ( cvt_dist >= 0 ) @@ -5797,7 +5886,7 @@ /* refer to the same zone. */ if ( CUR.GS.gep0 == CUR.GS.gep1 ) - if ( ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin ) + if ( FT_ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin ) cvt_dist = org_dist; distance = CUR_Func_round( @@ -5947,7 +6036,7 @@ discriminant = TT_MULDIV( dax, -dby, 0x40 ) + TT_MULDIV( day, dbx, 0x40 ); - if ( ABS( discriminant ) >= 0x40 ) + if ( FT_ABS( discriminant ) >= 0x40 ) { val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 ); Index: xc/extras/freetype2/src/truetype/ttinterp.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/truetype/ttinterp.h,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 ttinterp.h --- a/xc/extras/freetype2/src/truetype/ttinterp.h 14 Nov 2003 16:48:24 -0000 1.1.1.1 +++ b/xc/extras/freetype2/src/truetype/ttinterp.h 28 Apr 2004 10:26:20 -0000 @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -210,6 +210,7 @@ func_freeProj; /* current freedom proj. func */ TT_Move_Func func_move; /* current point move function */ + TT_Move_Func func_move_orig; /* move original position function */ TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ Index: xc/extras/freetype2/src/truetype/ttobjs.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/truetype/ttobjs.c,v retrieving revision 1.2 diff -u -r1.2 ttobjs.c --- a/xc/extras/freetype2/src/truetype/ttobjs.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/truetype/ttobjs.c 28 Apr 2004 10:26:20 -0000 @@ -590,14 +590,15 @@ } /* Compute root ascender, descender, text height, and max_advance */ - metrics->ascender = ( FT_MulFix( face->root.ascender, - metrics->y_scale ) + 32 ) & -64; - metrics->descender = ( FT_MulFix( face->root.descender, - metrics->y_scale ) + 32 ) & -64; - metrics->height = ( FT_MulFix( face->root.height, - metrics->y_scale ) + 32 ) & -64; - metrics->max_advance = ( FT_MulFix( face->root.max_advance_width, - metrics->x_scale ) + 32 ) & -64; + metrics->ascender = + FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) ); + metrics->descender = + FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) ); + metrics->height = + FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) ); + metrics->max_advance = + FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width, + metrics->x_scale ) ); #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS @@ -748,7 +749,8 @@ sbit_metrics->descender = strike->hori.descender << 6; /* XXX: Is this correct? */ - sbit_metrics->height = sbit_metrics->ascender - sbit_metrics->descender; + sbit_metrics->height = sbit_metrics->ascender - + sbit_metrics->descender; /* XXX: Is this correct? */ sbit_metrics->max_advance = ( strike->hori.min_origin_SB + Index: xc/extras/freetype2/src/truetype/ttobjs.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/truetype/ttobjs.h,v retrieving revision 1.2 diff -u -r1.2 ttobjs.h --- a/xc/extras/freetype2/src/truetype/ttobjs.h 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/truetype/ttobjs.h 28 Apr 2004 10:26:21 -0000 @@ -4,7 +4,7 @@ /* */ /* Objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -216,7 +216,8 @@ TT_Transform transform; /* transformation matrix */ - FT_Vector pp1, pp2; /* phantom points */ + FT_Vector pp1, pp2; /* phantom points (horizontal) */ + FT_Vector pp3, pp4; /* phantom points (vertical) */ } TT_SubGlyphRec, *TT_SubGlyph_Stack; Index: xc/extras/freetype2/src/type1/t1driver.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/type1/t1driver.c,v retrieving revision 1.2 diff -u -r1.2 t1driver.c --- a/xc/extras/freetype2/src/type1/t1driver.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/type1/t1driver.c 28 Apr 2004 10:26:21 -0000 @@ -189,7 +189,6 @@ const FT_String* t1_interface ) { FT_UNUSED( driver ); - FT_UNUSED( t1_interface ); return ft_service_list_lookup( t1_services, t1_interface ); } Index: xc/extras/freetype2/src/type1/t1gload.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/type1/t1gload.c,v retrieving revision 1.2 diff -u -r1.2 t1gload.c --- a/xc/extras/freetype2/src/type1/t1gload.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/type1/t1gload.c 28 Apr 2004 10:26:21 -0000 @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,6 +15,7 @@ /* */ /***************************************************************************/ + #include #include "t1gload.h" #include FT_INTERNAL_DEBUG_H @@ -80,7 +81,7 @@ /* For ordinary fonts get the character data stored in the face record. */ { char_string->pointer = type1->charstrings[glyph_index]; - char_string->length = type1->charstrings_len[glyph_index]; + char_string->length = (FT_Int)type1->charstrings_len[glyph_index]; } if ( !error ) @@ -96,6 +97,7 @@ { FT_Incremental_MetricsRec metrics; + metrics.bearing_x = decoder->builder.left_bearing.x; metrics.bearing_y = decoder->builder.left_bearing.y; metrics.advance = decoder->builder.advance.x; @@ -110,7 +112,7 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ - return error; + return error; } @@ -119,11 +121,12 @@ FT_UInt glyph_index ) { FT_Data glyph_data; - FT_Error error = T1_Parse_Glyph_And_Get_Char_String( + FT_Error error = T1_Parse_Glyph_And_Get_Char_String( decoder, glyph_index, &glyph_data ); #ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( !error ) { T1_Face face = (T1_Face)decoder->builder.face; @@ -134,6 +137,7 @@ face->root.internal->incremental_interface->object, &glyph_data ); } + #endif /* FT_CONFIG_OPTION_INCREMENTAL */ return error; @@ -183,7 +187,7 @@ error = T1_Parse_Glyph( &decoder, glyph_index ); if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) *max_advance = decoder.builder.advance.x; - + /* ignore the error if one occurred - skip to next glyph */ } @@ -251,7 +255,7 @@ (FT_Byte**)type1->glyph_names, face->blend, FT_BOOL( hinting ), - FT_LOAD_TARGET_MODE(load_flags), + FT_LOAD_TARGET_MODE( load_flags ), T1_Parse_Glyph ); if ( error ) goto Exit; @@ -370,11 +374,11 @@ if ( hinting ) { - metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64; - metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64; + metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); + metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); - metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64; - metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64; + metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX ); + metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY ); } } @@ -384,10 +388,10 @@ /* grid fit the bounding box if necessary */ if ( hinting ) { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax+63 ) & -64; - cbox.yMax = ( cbox.yMax+63 ) & -64; + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); } metrics->width = cbox.xMax - cbox.xMin; Index: xc/extras/freetype2/src/type1/t1load.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/type1/t1load.c,v retrieving revision 1.2 diff -u -r1.2 t1load.c --- a/xc/extras/freetype2/src/type1/t1load.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/type1/t1load.c 28 Apr 2004 10:26:22 -0000 @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -397,7 +397,12 @@ /* take an array of objects */ T1_ToTokenArray( &loader->parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) + if ( num_axis < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) { FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n", num_axis )); @@ -459,8 +464,14 @@ /* get the array of design tokens -- compute number of designs */ - T1_ToTokenArray( parser, design_tokens, T1_MAX_MM_DESIGNS, &num_designs ); - if ( num_designs <= 0 || num_designs > T1_MAX_MM_DESIGNS ) + T1_ToTokenArray( parser, design_tokens, + T1_MAX_MM_DESIGNS, &num_designs ); + if ( num_designs < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) { FT_ERROR(( "parse_blend_design_positions:" )); FT_ERROR(( " incorrect number of designs: %d\n", @@ -472,13 +483,13 @@ { FT_Byte* old_cursor = parser->root.cursor; FT_Byte* old_limit = parser->root.limit; - FT_UInt n; + FT_Int n; blend = face->blend; num_axis = 0; /* make compiler happy */ - for ( n = 0; n < (FT_UInt)num_designs; n++ ) + for ( n = 0; n < num_designs; n++ ) { T1_TokenRec axis_tokens[T1_MAX_MM_DESIGNS]; T1_Token token; @@ -541,8 +552,14 @@ FT_Memory memory = face->root.memory; - T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) + T1_ToTokenArray( parser, axis_tokens, + T1_MAX_MM_AXIS, &num_axis ); + if ( num_axis < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) { FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n", num_axis )); @@ -615,26 +632,46 @@ parse_weight_vector( T1_Face face, T1_Loader loader ) { + T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; + FT_Int num_designs; FT_Error error = T1_Err_Ok; T1_Parser parser = &loader->parser; PS_Blend blend = face->blend; - T1_TokenRec master; - FT_UInt n; + T1_Token token; + FT_Int n; FT_Byte* old_cursor; FT_Byte* old_limit; - if ( !blend || blend->num_designs == 0 ) + T1_ToTokenArray( parser, design_tokens, + T1_MAX_MM_DESIGNS, &num_designs ); + if ( num_designs < 0 ) { - FT_ERROR(( "parse_weight_vector: too early!\n" )); + error = T1_Err_Ignore; + goto Exit; + } + if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) + { + FT_ERROR(( "parse_weight_vector:" )); + FT_ERROR(( " incorrect number of designs: %d\n", + num_designs )); error = T1_Err_Invalid_File_Format; goto Exit; } - T1_ToToken( parser, &master ); - if ( master.type != T1_TOKEN_TYPE_ARRAY ) + if ( !blend || !blend->num_designs ) + { + error = t1_allocate_blend( face, num_designs, 0 ); + if ( error ) + goto Exit; + blend = face->blend; + } + else if ( blend->num_designs != (FT_UInt)num_designs ) { - FT_ERROR(( "parse_weight_vector: incorrect format!\n" )); + FT_ERROR(( "parse_weight_vector:" + " /BlendDesignPosition and /WeightVector have\n" )); + FT_ERROR(( " " + " different number of elements!\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } @@ -642,12 +679,12 @@ old_cursor = parser->root.cursor; old_limit = parser->root.limit; - /* don't include the delimiting brackets */ - parser->root.cursor = master.start + 1; - parser->root.limit = master.limit - 1; - - for ( n = 0; n < blend->num_designs; n++ ) + for ( n = 0; n < num_designs; n++ ) { + token = design_tokens + n; + parser->root.cursor = token->start; + parser->root.limit = token->limit; + blend->default_weight_vector[n] = blend->weight_vector[n] = T1_ToFixed( parser, 0 ); } @@ -660,23 +697,6 @@ } - /* the keyword `/shareddict' appears in some multiple master fonts */ - /* with a lot of Postscript garbage behind it (that's completely out */ - /* of spec!); we detect it and terminate the parsing */ - /* */ - static void - parse_shared_dict( T1_Face face, - T1_Loader loader ) - { - T1_Parser parser = &loader->parser; - - FT_UNUSED( face ); - - - parser->root.cursor = parser->root.limit; - parser->root.error = 0; - } - #endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ @@ -787,10 +807,11 @@ FT_Byte* limit = parser->root.limit; - /* the binary data has the following format */ - /* */ - /* `size' [white*] RD white ....... ND */ - /* */ + /* the binary data has one of the following formats */ + /* */ + /* `size' [white*] RD white ....... ND */ + /* `size' [white*] -| white ....... |- */ + /* */ T1_Skip_Spaces( parser ); @@ -833,7 +854,7 @@ (void)T1_ToFixedArray( parser, 6, temp, 3 ); - temp_scale = ABS( temp[3] ); + temp_scale = FT_ABS( temp[3] ); /* Set Units per EM based on FontMatrix values. We set the value to */ /* 1000 / temp_scale, because temp_scale was already multiplied by */ @@ -1006,9 +1027,9 @@ parser->root.error = T1_Add_Table( char_table, charcode, cur, len + 1 ); - char_table->elements[charcode][len] = '\0'; if ( parser->root.error ) return; + char_table->elements[charcode][len] = '\0'; n++; } @@ -1040,10 +1061,7 @@ face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; else - { - FT_ERROR(( "parse_encoding: invalid token!\n" )); - parser->root.error = T1_Err_Invalid_File_Format; - } + parser->root.error = T1_Err_Ignore; } } @@ -1116,7 +1134,7 @@ /* (bound to `noaccess put') or by two separate tokens: */ /* `noaccess' & `put'. We position the parser right */ /* before the next `dup', if any. */ - T1_Skip_PS_Token( parser ); /* `NP' or `I' or `noaccess' */ + T1_Skip_PS_Token( parser ); /* `NP' or `|' or `noaccess' */ T1_Skip_Spaces ( parser ); if ( ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 ) @@ -1155,7 +1173,8 @@ goto Fail; } - loader->num_subrs = num_subrs; + if ( !loader->num_subrs ) + loader->num_subrs = num_subrs; return; @@ -1182,35 +1201,43 @@ FT_Byte* cur; FT_Byte* limit = parser->root.limit; - FT_Int n; + FT_Int n, num_glyphs; FT_UInt notdef_index = 0; FT_Byte notdef_found = 0; - loader->num_glyphs = (FT_Int)T1_ToInt( parser ); - if ( parser->root.error ) + num_glyphs = (FT_Int)T1_ToInt( parser ); + /* some fonts like Optima-Oblique not only define the /CharStrings */ + /* array but access it also */ + if ( num_glyphs == 0 || parser->root.error ) return; - /* initialize tables, leaving room for addition of .notdef, */ - /* if necessary, and a few other glyphs to handle buggy */ - /* fonts which have more glyphs than specified. */ - - error = psaux->ps_table_funcs->init( - code_table, loader->num_glyphs + 1 + TABLE_EXTEND, memory ); - if ( error ) - goto Fail; + /* initialize tables, leaving space for addition of .notdef, */ + /* if necessary, and a few other glyphs to handle buggy */ + /* fonts which have more glyphs than specified. */ + + /* for some non-standard fonts like `Optima' which provides */ + /* different outlines depending on the resolution it is */ + /* possible to get here twice */ + if ( !loader->num_glyphs ) + { + error = psaux->ps_table_funcs->init( + code_table, num_glyphs + 1 + TABLE_EXTEND, memory ); + if ( error ) + goto Fail; - error = psaux->ps_table_funcs->init( - name_table, loader->num_glyphs + 1 + TABLE_EXTEND, memory ); - if ( error ) - goto Fail; + error = psaux->ps_table_funcs->init( + name_table, num_glyphs + 1 + TABLE_EXTEND, memory ); + if ( error ) + goto Fail; - /* Initialize table for swapping index notdef_index and */ - /* index 0 names and codes (if necessary). */ + /* Initialize table for swapping index notdef_index and */ + /* index 0 names and codes (if necessary). */ - error = psaux->ps_table_funcs->init( swap_table, 4, memory ); - if ( error ) - goto Fail; + error = psaux->ps_table_funcs->init( swap_table, 4, memory ); + if ( error ) + goto Fail; + } n = 0; @@ -1220,8 +1247,8 @@ FT_Byte* base; - /* the format is simple: */ - /* `/glyphname' + binary data */ + /* the format is simple: */ + /* `/glyphname' + binary data */ T1_Skip_Spaces( parser ); @@ -1259,6 +1286,15 @@ cur++; /* skip `/' */ len = parser->root.cursor - cur; + if ( !read_binary_data( parser, &size, &base ) ) + return; + + /* for some non-standard fonts like `Optima' which provides */ + /* different outlines depending on the resolution it is */ + /* possible to get here twice */ + if ( loader->num_glyphs ) + continue; + error = T1_Add_Table( name_table, n, cur, len + 1 ); if ( error ) goto Fail; @@ -1275,11 +1311,8 @@ notdef_found = 1; } - if ( !read_binary_data( parser, &size, &base ) ) - return; - if ( face->type1.private_dict.lenIV >= 0 && - n < loader->num_glyphs + TABLE_EXTEND ) + n < num_glyphs + TABLE_EXTEND ) { FT_Byte* temp; @@ -1303,7 +1336,10 @@ } } - loader->num_glyphs = n; + if ( loader->num_glyphs ) + return; + else + loader->num_glyphs = n; /* if /.notdef is found but does not occupy index 0, do our magic. */ if ( ft_strcmp( (const char*)".notdef", @@ -1376,7 +1412,7 @@ /* We take index 0 and add it to the end of the table(s) */ /* and add our own /.notdef glyph to index 0. */ - /* 0 333 hsbw endchar */ + /* 0 333 hsbw endchar */ FT_Byte notdef_glyph[] = {0x8B, 0xF7, 0xE1, 0x0D, 0x0E}; char* notdef_name = (char *)".notdef"; @@ -1450,7 +1486,6 @@ T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map ) T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ) T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector ) - T1_FIELD_CALLBACK( "shareddict", parse_shared_dict ) #endif { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } @@ -1469,7 +1504,8 @@ FT_Byte* keyword_flags ) { T1_Parser parser = &loader->parser; - FT_Byte* limit; + FT_Byte *limit, *start_binary = NULL; + FT_Bool have_integer = 0; parser->root.cursor = base; @@ -1525,13 +1561,56 @@ cur2 = parser->root.cursor; } parser->root.cursor = cur2; + have_integer = 0; } + /* look for `eexec' */ + else if ( *cur == 'e' && cur + 5 < limit && + ft_strncmp( (char*)cur, "eexec", 5 ) == 0 ) + break; + /* look for `closefile' which ends the eexec section */ else if ( *cur == 'c' && cur + 9 < limit && ft_strncmp( (char*)cur, "closefile", 9 ) == 0 ) break; + /* check whether we have an integer */ + else if ( ft_isdigit( *cur ) ) + { + start_binary = cur; + T1_Skip_PS_Token( parser ); + have_integer = 1; + } + + /* in valid Type 1 fonts we don't see `RD' or `-|' directly */ + /* since those tokens are handled by parse_subrs and */ + /* parse_charstrings */ + else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' && + have_integer ) + { + FT_Long s; + FT_Byte* b; + + + parser->root.cursor = start_binary; + if ( !read_binary_data( parser, &s, &b ) ) + return T1_Err_Invalid_File_Format; + have_integer = 0; + } + + else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' && + have_integer ) + { + FT_Long s; + FT_Byte* b; + + + parser->root.cursor = start_binary; + if ( !read_binary_data( parser, &s, &b ) ) + return T1_Err_Invalid_File_Format; + have_integer = 0; + } + /* look for immediates */ else if ( *cur == '/' && cur + 2 < limit ) { @@ -1559,10 +1638,7 @@ name = (FT_Byte*)keyword->ident; if ( !name ) - { - T1_Skip_PS_Token( parser ); break; - } if ( cur[0] == name[0] && len == ft_strlen( (const char *)name ) && @@ -1571,17 +1647,25 @@ /* We found it -- run the parsing callback! */ /* We only record the first instance of any */ /* field to deal adequately with synthetic */ - /* fonts; /Subrs is handled specially. */ - if ( keyword_flag[0] == 0 || - ft_strcmp( (const char*)name, "Subrs" ) == 0 ) + /* fonts; /Subrs and /CharStrings are */ + /* handled specially. */ + if ( keyword_flag[0] == 0 || + ft_strcmp( (const char*)name, "Subrs" ) == 0 || + ft_strcmp( (const char*)name, "CharStrings") == 0 ) { parser->root.error = t1_load_keyword( face, loader, keyword ); - if ( parser->root.error ) - return parser->root.error; + if ( parser->root.error == T1_Err_Ok ) + keyword_flag[0] = 1; + else + { + if ( FT_ERROR_BASE( parser->root.error ) == FT_Err_Ignore ) + parser->root.error = T1_Err_Ok; + else + return parser->root.error; + } } - keyword_flag[0] = 1; break; } @@ -1589,13 +1673,21 @@ keyword_flag++; } } + + have_integer = 0; } else + { T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + have_integer = 0; + } T1_Skip_Spaces( parser ); } + Exit: return parser->root.error; } @@ -1644,6 +1736,7 @@ T1_LoaderRec loader; T1_Parser parser; T1_Font type1 = &face->type1; + PS_Private priv = &type1->private_dict; FT_Error error; FT_Byte keyword_flags[T1_FIELD_COUNT]; @@ -1652,11 +1745,12 @@ t1_init_loader( &loader, face ); - /* default lenIV */ - type1->private_dict.lenIV = 4; - - /* default blue fuzz, we put it there since 0 is a valid value */ - type1->private_dict.blue_fuzz = 1; + /* default values */ + priv->blue_shift = 7; + priv->blue_fuzz = 1; + priv->lenIV = 4; + priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); + priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); parser = &loader.parser; error = T1_New_Parser( parser, @@ -1689,6 +1783,30 @@ if ( error ) goto Exit; +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + + /* the following can happen for MM instances; we then treat the */ + /* font as a normal PS font */ + if ( face->blend && + ( !face->blend->num_designs || !face->blend->num_axis ) ) + T1_Done_Blend( face ); + + /* another safety check */ + if ( face->blend ) + { + FT_UInt i; + + + for ( i = 0; i < face->blend->num_axis; i++ ) + if ( !face->blend->design_map[i].num_points ) + { + T1_Done_Blend( face ); + break; + } + } + +#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ + /* now, propagate the subrs, charstrings, and glyphnames tables */ /* to the Type1 data */ type1->num_glyphs = loader.num_glyphs; @@ -1707,7 +1825,7 @@ #endif if ( !loader.charstrings.init ) { - FT_ERROR(( "T1_Open_Face: no charstrings array in face!\n" )); + FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face!\n" )); error = T1_Err_Invalid_File_Format; } Index: xc/extras/freetype2/src/type1/t1objs.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/type1/t1objs.c,v retrieving revision 1.2 diff -u -r1.2 t1objs.c --- a/xc/extras/freetype2/src/type1/t1objs.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/type1/t1objs.c 28 Apr 2004 10:26:23 -0000 @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,9 +15,11 @@ /* */ /***************************************************************************/ + #include #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_IDS_H #include "t1gload.h" #include "t1load.h" @@ -429,10 +431,8 @@ root->max_advance_height = root->height; - root->underline_position = - (FT_Short)( info->underline_position >> 16 ); - root->underline_thickness = - (FT_Short)( info->underline_thickness >> 16 ); + root->underline_position = (FT_Short)info->underline_position; + root->underline_thickness = (FT_Short)info->underline_thickness; root->internal->max_points = 0; root->internal->max_contours = 0; @@ -466,25 +466,25 @@ { case T1_ENCODING_TYPE_STANDARD: charmap.encoding = FT_ENCODING_ADOBE_STANDARD; - charmap.encoding_id = 0; + charmap.encoding_id = TT_ADOBE_ID_STANDARD; clazz = cmap_classes->standard; break; case T1_ENCODING_TYPE_EXPERT: charmap.encoding = FT_ENCODING_ADOBE_EXPERT; - charmap.encoding_id = 1; + charmap.encoding_id = TT_ADOBE_ID_EXPERT; clazz = cmap_classes->expert; break; case T1_ENCODING_TYPE_ARRAY: charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; - charmap.encoding_id = 2; + charmap.encoding_id = TT_ADOBE_ID_CUSTOM; clazz = cmap_classes->custom; break; case T1_ENCODING_TYPE_ISOLATIN1: charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; - charmap.encoding_id = 3; + charmap.encoding_id = TT_ADOBE_ID_LATIN_1; clazz = cmap_classes->unicode; break; Index: xc/extras/freetype2/src/type1/t1parse.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/type1/t1parse.c,v retrieving revision 1.2 diff -u -r1.2 t1parse.c --- a/xc/extras/freetype2/src/type1/t1parse.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/type1/t1parse.c 28 Apr 2004 10:26:23 -0000 @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -356,8 +356,22 @@ parser->root.limit = parser->base_dict + parser->base_len; T1_Skip_PS_Token( parser ); - T1_Skip_Spaces ( parser ); cur = parser->root.cursor; + if ( *cur == '\r' ) + { + cur++; + if ( *cur == '\n' ) + cur++; + } + else if ( *cur == '\n' ) + cur++; + else + { + FT_ERROR(( "T1_Get_Private_Dict:" )); + FT_ERROR(( " `eexec' not properly terminated\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } size = (FT_Long)( parser->base_len - ( cur - parser->base_dict ) ); @@ -404,7 +418,7 @@ } else /* binary encoding -- copy the private dict */ - FT_MEM_COPY( parser->private_dict, cur, size ); + FT_MEM_MOVE( parser->private_dict, cur, size ); } /* we now decrypt the encoded binary private dictionary */ Index: xc/extras/freetype2/src/type1/t1tokens.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/type1/t1tokens.h,v retrieving revision 1.2 diff -u -r1.2 t1tokens.h --- a/xc/extras/freetype2/src/type1/t1tokens.h 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/type1/t1tokens.h 28 Apr 2004 10:26:23 -0000 @@ -4,7 +4,7 @@ /* */ /* Type 1 tokenizer (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -60,6 +60,8 @@ T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) + T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor ) + #undef FT_STRUCTURE #define FT_STRUCTURE T1_FontRec Index: xc/extras/freetype2/src/type42/t42drivr.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/type42/t42drivr.c,v retrieving revision 1.2 diff -u -r1.2 t42drivr.c --- a/xc/extras/freetype2/src/type42/t42drivr.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/type42/t42drivr.c 28 Apr 2004 10:26:24 -0000 @@ -4,7 +4,7 @@ /* */ /* High-level Type 42 driver interface (body). */ /* */ -/* Copyright 2002, 2003 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -95,14 +95,14 @@ gname = face->type1.glyph_names[i]; if ( !ft_strcmp( glyph_name, gname ) ) - return ft_atoi( (const char *)face->type1.charstrings[i] ); + return (FT_UInt)ft_atol( (const char *)face->type1.charstrings[i] ); } return 0; } - static FT_Service_GlyphDictRec t42_service_glyph_dict = + static const FT_Service_GlyphDictRec t42_service_glyph_dict = { (FT_GlyphDict_GetNameFunc) t42_get_glyph_name, (FT_GlyphDict_NameIndexFunc)t42_get_name_index @@ -122,7 +122,7 @@ } - static FT_Service_PsFontNameRec t42_service_ps_font_name = + static const FT_Service_PsFontNameRec t42_service_ps_font_name = { (FT_PsName_GetFunc)t42_get_ps_font_name }; Index: xc/extras/freetype2/src/type42/t42objs.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/type42/t42objs.c,v retrieving revision 1.2 diff -u -r1.2 t42objs.c --- a/xc/extras/freetype2/src/type42/t42objs.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/type42/t42objs.c 28 Apr 2004 10:26:24 -0000 @@ -4,7 +4,7 @@ /* */ /* Type 42 objects manager (body). */ /* */ -/* Copyright 2002, 2003 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -281,8 +281,8 @@ root->max_advance_width = face->ttf_face->max_advance_width; root->max_advance_height = face->ttf_face->max_advance_height; - root->underline_position = (FT_Short)( info->underline_position >> 16 ); - root->underline_thickness = (FT_Short)( info->underline_thickness >> 16 ); + root->underline_position = (FT_Short)info->underline_position; + root->underline_thickness = (FT_Short)info->underline_thickness; root->internal->max_points = 0; root->internal->max_contours = 0; Index: xc/extras/freetype2/src/type42/t42parse.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/type42/t42parse.c,v retrieving revision 1.2 diff -u -r1.2 t42parse.c --- a/xc/extras/freetype2/src/type42/t42parse.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/type42/t42parse.c 28 Apr 2004 10:26:25 -0000 @@ -4,7 +4,7 @@ /* */ /* Type 42 font parser (body). */ /* */ -/* Copyright 2002, 2003 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -245,7 +245,7 @@ (void)T1_ToFixedArray( parser, 6, temp, 3 ); - temp_scale = ABS( temp[3] ); + temp_scale = FT_ABS( temp[3] ); /* Set Units per EM based on FontMatrix values. We set the value to */ /* 1000 / temp_scale, because temp_scale was already multiplied by */ @@ -964,8 +964,8 @@ { T42_Parser parser = &loader->parser; FT_Byte* limit; - int n_keywords = sizeof ( t42_keywords ) / - sizeof ( t42_keywords[0] ); + FT_Int n_keywords = (FT_Int)( sizeof ( t42_keywords ) / + sizeof ( t42_keywords[0] ) ); parser->root.cursor = base; Index: xc/extras/freetype2/src/type42/t42types.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/type42/t42types.h,v retrieving revision 1.2 diff -u -r1.2 t42types.h --- a/xc/extras/freetype2/src/type42/t42types.h 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/type42/t42types.h 28 Apr 2004 10:26:25 -0000 @@ -4,7 +4,7 @@ /* */ /* Type 42 font data types (specification only). */ /* */ -/* Copyright 2002 by Roberto Alameda. */ +/* Copyright 2002, 2003 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ Index: xc/extras/freetype2/src/winfonts/winfnt.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/winfonts/winfnt.c,v retrieving revision 1.2 diff -u -r1.2 winfnt.c --- a/xc/extras/freetype2/src/winfonts/winfnt.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/winfonts/winfnt.c 28 Apr 2004 10:26:25 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -121,6 +121,7 @@ if ( font->fnt_frame ) FT_FRAME_RELEASE( font->fnt_frame ); + FT_FREE( font->family_name ); FT_FREE( font ); face->font = 0; @@ -434,8 +435,9 @@ /* we now need to fill the root FT_Face fields */ /* with relevant information */ { - FT_Face root = FT_FACE( face ); - FNT_Font font = face->font; + FT_Face root = FT_FACE( face ); + FNT_Font font = face->font; + FT_PtrDist family_size; root->face_flags = FT_FACE_FLAG_FIXED_SIZES | @@ -476,11 +478,18 @@ FT_CharMapRec charmap; - charmap.encoding = FT_ENCODING_UNICODE; - charmap.platform_id = 3; - charmap.encoding_id = 1; + charmap.encoding = FT_ENCODING_NONE; + charmap.platform_id = 0; + charmap.encoding_id = 0; charmap.face = root; + if ( font->header.charset == FT_WinFNT_ID_MAC ) + { + charmap.encoding = FT_ENCODING_APPLE_ROMAN; + charmap.platform_id = 1; +/* charmap.encoding_id = 0; */ + } + error = FT_CMap_New( fnt_cmap_class, NULL, &charmap, @@ -499,8 +508,22 @@ root->num_glyphs = font->header.last_char - font->header.first_char + 1 + 1; - root->family_name = (FT_String*)font->fnt_frame + - font->header.face_name_offset; + /* Some broken fonts don't delimit the face name with a final */ + /* NULL byte -- the frame is erroneously one byte too small. */ + /* We thus allocate one more byte, setting it explicitly to */ + /* zero. */ + family_size = font->header.file_size - font->header.face_name_offset; + if ( FT_ALLOC( font->family_name, family_size + 1 ) ) + goto Fail; + FT_MEM_COPY( font->family_name, + font->fnt_frame + font->header.face_name_offset, + family_size ); + font->family_name[family_size] = '\0'; + if ( FT_REALLOC( font->family_name, + family_size, + ft_strlen( font->family_name ) + 1 ) ) + goto Fail; + root->family_name = font->family_name; root->style_name = (char *)"Regular"; if ( root->style_flags & FT_STYLE_FLAG_BOLD ) @@ -513,10 +536,10 @@ else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) root->style_name = (char *)"Italic"; } + goto Exit; Fail: - if ( error ) - FNT_Face_Done( face ); + FNT_Face_Done( face ); Exit: return error; @@ -536,8 +559,8 @@ size->metrics.ascender = font->header.ascent * 64; - size->metrics.descender = ( font->header.pixel_height - - font->header.ascent ) * 64; + size->metrics.descender = -( font->header.pixel_height - + font->header.ascent ) * 64; size->metrics.height = font->header.pixel_height * 64; size->metrics.max_advance = font->header.max_width * 64; Index: xc/extras/freetype2/src/winfonts/winfnt.h =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/src/winfonts/winfnt.h,v retrieving revision 1.2 diff -u -r1.2 winfnt.h --- a/xc/extras/freetype2/src/winfonts/winfnt.h 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/src/winfonts/winfnt.h 28 Apr 2004 10:26:25 -0000 @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -79,6 +79,7 @@ FT_Byte* fnt_frame; FT_ULong fnt_size; + FT_String* family_name; } FNT_FontRec, *FNT_Font; Index: xc/extras/freetype2/tests/gview.c =================================================================== RCS file: /cvs/xorg/xc/extras/freetype2/tests/gview.c,v retrieving revision 1.2 diff -u -r1.2 gview.c --- a/xc/extras/freetype2/tests/gview.c 23 Apr 2004 18:42:54 -0000 1.2 +++ b/xc/extras/freetype2/tests/gview.c 28 Apr 2004 10:26:26 -0000 @@ -745,7 +745,7 @@ x = (NV_Pos)( v1.x + 0.5 ); nv_pixmap_fill_rect( target, x - 1, y2, 3, - ABS( y1 - y2 ) + 1, SEGMENT_COLOR ); + FT_ABS( y1 - y2 ) + 1, SEGMENT_COLOR ); } } @@ -787,7 +787,7 @@ x = (NV_Pos)( v1.y + 0.5 ); nv_pixmap_fill_rect( target, y1, x - 1, - ABS( y1 - y2 ) + 1, 3, SEGMENT_COLOR ); + FT_ABS( y1 - y2 ) + 1, 3, SEGMENT_COLOR ); } } Index: xc/lib/font/FreeType/ftconfig.h =================================================================== RCS file: /cvs/xorg/xc/lib/font/FreeType/ftconfig.h,v retrieving revision 1.2 diff -u -r1.2 ftconfig.h --- a/xc/lib/font/FreeType/ftconfig.h 23 Apr 2004 18:44:07 -0000 1.2 +++ b/xc/lib/font/FreeType/ftconfig.h 28 Apr 2004 10:26:30 -0000 @@ -4,11 +4,9 @@ /* */ /* ANSI-specific configuration file (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ -/* Modified for XFree86. */ -/* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ @@ -16,7 +14,6 @@ /* understand and accept it fully. */ /* */ /***************************************************************************/ -/* $XFree86$ */ /*************************************************************************/ @@ -61,44 +58,44 @@ /*************************************************************************/ -#ifdef XFREE86_FT2 - -# include "X11/Xmd.h" - - /* The number of bytes in an `int' type. */ -# define FT_SIZEOF_INT 4 - - /* The number of bytes in a `long' type. */ -# ifdef LONG64 -# define FT_SIZEOF_LONG 8 -# else -# define FT_SIZEOF_LONG 4 -# endif - -#else - - /* The number of bytes in an `int' type. */ -# if FT_UINT_MAX == 0xFFFFFFFFUL -# define FT_SIZEOF_INT 4 -# elif FT_UINT_MAX == 0xFFFFU -# define FT_SIZEOF_INT 2 -# elif FT_UINT_MAX > 0xFFFFFFFFU && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFU -# define FT_SIZEOF_INT 8 + /* There are systems (like the Texas Instruments 'C54x) where a `char' */ + /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ + /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ + /* is probably unexpected. */ + /* */ + /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ + /* `char' type. */ + +#ifndef FT_CHAR_BIT +# ifdef CHAR_BIT +# define FT_CHAR_BIT 8 # else -# error "Unsupported number of bytes in `int' type!" +# define FT_CHAR_BIT 8 # endif +#endif - /* The number of bytes in a `long' type. */ -# if FT_ULONG_MAX == 0xFFFFFFFFUL -# define FT_SIZEOF_LONG 4 -# elif FT_ULONG_MAX > 0xFFFFFFFFU && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFU -# define FT_SIZEOF_LONG 8 -# else -# error "Unsupported number of bytes in `long' type!" -# endif + /* The size of an `int' type. */ +#if FT_UINT_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_INT (32 / FT_CHAR_BIT) +#elif FT_UINT_MAX == 0xFFFFU +#define FT_SIZEOF_INT (16 / FT_CHAR_BIT) +#elif FT_UINT_MAX > 0xFFFFFFFFU && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFU +#define FT_SIZEOF_INT (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `int' type!" +#endif + + /* The size of a `long' type. */ +#if FT_ULONG_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFU && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFU +#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `long' type!" #endif + /* Preferred alignment of data */ #define FT_ALIGNMENT 8 @@ -143,12 +140,12 @@ typedef signed short FT_Int16; typedef unsigned short FT_UInt16; -#if FT_SIZEOF_INT == 4 +#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) typedef signed int FT_Int32; typedef unsigned int FT_UInt32; -#elif FT_SIZEOF_LONG == 4 +#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT) typedef signed long FT_Int32; typedef unsigned long FT_UInt32; @@ -158,12 +155,12 @@ #endif /* look up an integer type that is at least 32 bits */ -#if FT_SIZEOF_INT >= 4 +#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) typedef int FT_Fast; typedef unsigned int FT_UFast; -#elif FT_SIZEOF_LONG >= 4 +#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT) typedef long FT_Fast; typedef unsigned long FT_UFast; @@ -173,7 +170,7 @@ /* determine whether we have a 64-bit int type for platforms without */ /* Autoconf */ -#if FT_SIZEOF_LONG == 8 +#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) /* FT_LONG64 must be defined if a 64-bit type is available */ #define FT_LONG64 @@ -209,7 +206,7 @@ #define FT_LONG64 #define FT_INT64 long long int -#endif /* FT_SIZEOF_LONG == 8 */ +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ #define FT_BEGIN_STMNT do { Index: xc/lib/font/FreeType/module/ftheader.h =================================================================== RCS file: /cvs/xorg/xc/lib/font/FreeType/module/ftheader.h,v retrieving revision 1.2 diff -u -r1.2 ftheader.h --- a/xc/lib/font/FreeType/module/ftheader.h 23 Apr 2004 18:44:08 -0000 1.2 +++ b/xc/lib/font/FreeType/module/ftheader.h 28 Apr 2004 10:26:31 -0000 @@ -377,6 +377,18 @@ /*************************************************************************/ /* */ /* @macro: */ + /* FT_LZW_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the definitions of an API to support for LZW-compressed files. */ + /* */ +#define FT_LZW_H + + + /*************************************************************************/ + /* */ + /* @macro: */ /* FT_WINFONTS_H */ /* */ /* @description: */ Index: xc/lib/font/FreeType/module/ftoption.h =================================================================== RCS file: /cvs/xorg/xc/lib/font/FreeType/module/ftoption.h,v retrieving revision 1.2 diff -u -r1.2 ftoption.h --- a/xc/lib/font/FreeType/module/ftoption.h 23 Apr 2004 18:44:08 -0000 1.2 +++ b/xc/lib/font/FreeType/module/ftoption.h 28 Apr 2004 10:26:31 -0000 @@ -1,15 +1,12 @@ -/* $XFree86: xc/lib/font/FreeType/ftoption.h,v 1.7 2003/06/10 15:48:45 dawes Exp $ */ /***************************************************************************/ /* */ /* ftoption.h */ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ -/* Modified for XFree86. */ -/* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ @@ -100,16 +97,30 @@ /*************************************************************************/ /* */ + /* LZW-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* 'compress' program. This is mostly used to parse many of the PCF */ + /* files that come with various X11 distributions. The implementation */ + /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ + /* (see src/lzw/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +#define FT_CONFIG_OPTION_USE_LZW + + + /*************************************************************************/ + /* */ /* Gzip-compressed file support. */ /* */ /* FreeType now handles font files that have been compressed with the */ /* 'gzip' program. This is mostly used to parse many of the PCF files */ /* that come with XFree86. The implementation uses `zlib' to */ - /* partially uncompress the file on the fly (see src/base/ftgzip.c). */ + /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ /* */ - /* Define this macro if you want to enable this "feature". Note that */ - /* this will however force you to link the zlib to any program that */ - /* also uses FreeType. */ + /* Define this macro if you want to enable this `feature'. See also */ + /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ /* */ #define FT_CONFIG_OPTION_USE_ZLIB @@ -119,7 +130,7 @@ /* ZLib library selection */ /* */ /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ - /* It allows FreeType's "ftgzip" component to link to the system's */ + /* It allows FreeType's `ftgzip' component to link to the system's */ /* installation of the ZLib library. This is useful on systems like */ /* Unix or VMS where it generally is already available. */ /* */ @@ -235,6 +246,29 @@ /*************************************************************************/ /* */ + /* Guessing methods to access embedded resource forks */ + /* */ + /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ + /* GNU/Linux). */ + /* */ + /* Resource forks which include fonts data are stored sometimes in */ + /* locations which users or developers don't expected. In some cases, */ + /* resource forks start with some offset from the head of a file. In */ + /* other cases, the actual resource fork is stored in file different */ + /* from what the user specifies. If this option is activated, */ + /* FreeType tries to guess whether such offsets or different file */ + /* names must be used. */ + /* */ + /* Note that normal, direct access of resource forks is controlled via */ + /* the FT_CONFIG_OPTION_MAC_FONTS option. */ + /* */ +#ifdef FT_CONFIG_OPTION_MAC_FONTS +#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#endif + + + /*************************************************************************/ + /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ /* contain no glyph data, but supply it via a callback function. */ /* This allows FreeType to be used with the PostScript language, using */ @@ -492,7 +526,7 @@ /* files into an existing face. Note that if set, the T1 driver will be */ /* unable to produce kerning distances. */ /* */ -#define T1_CONFIG_OPTION_NO_AFM +#undef T1_CONFIG_OPTION_NO_AFM /*************************************************************************/ @@ -501,7 +535,7 @@ /* compilation of the Multiple Masters font support in the Type 1 */ /* driver. */ /* */ -#define T1_CONFIG_OPTION_NO_MM_SUPPORT +#undef T1_CONFIG_OPTION_NO_MM_SUPPORT /* */ Index: xc/lib/freetype2/Imakefile =================================================================== RCS file: /cvs/xorg/xc/lib/freetype2/Imakefile,v retrieving revision 1.2 diff -u -r1.2 Imakefile --- a/xc/lib/freetype2/Imakefile 23 Apr 2004 18:44:24 -0000 1.2 +++ b/xc/lib/freetype2/Imakefile 28 Apr 2004 10:26:32 -0000 @@ -38,11 +38,13 @@ INCLUDES = -I.\ -I$(FREETYPESRC)\ -I$(FREETYPESRC)/base\ + -I$(FREETYPESRC)/autofit \ -I$(FREETYPESRC)/autohint\ -I$(FREETYPESRC)/bdf\ -I$(FREETYPESRC)/cff\ -I$(FREETYPESRC)/cid\ -I$(FREETYPESRC)/gzip\ + -I$(FREETYPESRC)/lzw \ -I$(FREETYPESRC)/pcf\ -I$(FREETYPESRC)/pfr\ -I$(FREETYPESRC)/psaux\ @@ -94,6 +96,9 @@ ftwinfnt.o \ ftxf86.o +SRCS_AUTOFIT = autofit.c +OBJS_AUTOFIT = autofit.o + SRCS_AUTOHINT = autohint.c OBJS_AUTOHINT = autohint.o @@ -109,6 +114,9 @@ SRCS_GZIP = ftgzip.c OBJS_GZIP = ftgzip.o +SRCS_LZW = ftlzw.c +OBJS_LZW = ftlzw.o + SRCS_PCF = pcf.c OBJS_PCF = pcf.o @@ -146,11 +154,13 @@ OBJS_WINFONTS = winfnt.o SRCS = $(SRCS_BASE)\ + $(SRCS_AUTOFIT) \ $(SRCS_AUTOHINT)\ $(SRCS_BDF)\ $(SRCS_CFF)\ $(SRCS_CID)\ $(SRCS_GZIP)\ + $(SRCS_LZW)\ $(SRCS_PCF)\ $(SRCS_PFR)\ $(SRCS_PSAUX)\ @@ -165,11 +175,13 @@ $(SRCS_WINFONTS) OBJS = $(OBJS_BASE)\ + $(OBJS_AUTOFIT) \ $(OBJS_AUTOHINT)\ $(OBJS_BDF)\ $(OBJS_CFF)\ $(OBJS_CID)\ $(OBJS_GZIP)\ + $(OBJS_LZW)\ $(OBJS_PCF)\ $(OBJS_PFR)\ $(OBJS_PSAUX)\ @@ -226,10 +238,12 @@ LinkSourceFile(ftmac.c,$(FREETYPESRC)/base) #endif +LinkSourceFile(autofit.c,$(FREETYPESRC)/autofit) LinkSourceFile(autohint.c,$(FREETYPESRC)/autohint) LinkSourceFile(bdf.c,$(FREETYPESRC)/bdf) LinkSourceFile(cff.c,$(FREETYPESRC)/cff) LinkSourceFile(ftgzip.c,$(FREETYPESRC)/gzip) +LinkSourceFile(ftlzw.c,$(FREETYPESRC)/lzw) LinkSourceFile(type1cid.c,$(FREETYPESRC)/cid) LinkSourceFile(pcf.c,$(FREETYPESRC)/pcf) LinkSourceFile(pfr.c,$(FREETYPESRC)/pfr) Index: xc/lib/freetype2/freetype/Imakefile =================================================================== RCS file: /cvs/xorg/xc/lib/freetype2/freetype/Imakefile,v retrieving revision 1.2 diff -u -r1.2 Imakefile --- a/xc/lib/freetype2/freetype/Imakefile 23 Apr 2004 18:44:24 -0000 1.2 +++ b/xc/lib/freetype2/freetype/Imakefile 28 Apr 2004 10:26:32 -0000 @@ -41,6 +41,7 @@ ftwinfnt.h \ ftxf86.h \ t1tables.h \ + ftlzw.h \ ttnameid.h \ tttables.h \ tttags.h \ @@ -80,6 +81,7 @@ LinkSourceFile(ftwinfnt.h,$(FREETYPEINC)) LinkSourceFile(ftxf86.h,$(FREETYPEINC)) LinkSourceFile(t1tables.h,$(FREETYPEINC)) +LinkSourceFile(ftlzw.h,$(FREETYPEINC)) LinkSourceFile(ttnameid.h,$(FREETYPEINC)) LinkSourceFile(tttables.h,$(FREETYPEINC)) LinkSourceFile(tttags.h,$(FREETYPEINC)) Index: xc/lib/freetype2/freetype/cache/Imakefile =================================================================== RCS file: /cvs/xorg/xc/lib/freetype2/freetype/cache/Imakefile,v retrieving revision 1.2 diff -u -r1.2 Imakefile --- a/xc/lib/freetype2/freetype/cache/Imakefile 23 Apr 2004 18:44:24 -0000 1.2 +++ b/xc/lib/freetype2/freetype/cache/Imakefile 28 Apr 2004 10:26:32 -0000 @@ -11,7 +11,7 @@ ftcimage.h \ ftcmanag.h \ ftcsbits.h \ - ftlru.h + ftcmru.h BuildIncludes($(HEADERS),freetype2/freetype/cache,../../..) InstallMultipleFlags($(HEADERS),$(INCDIR)/freetype2/freetype/cache,$(INSTINCFLAGS)) @@ -22,4 +22,4 @@ LinkSourceFile(ftcimage.h,$(FREETYPEINC)/cache) LinkSourceFile(ftcmanag.h,$(FREETYPEINC)/cache) LinkSourceFile(ftcsbits.h,$(FREETYPEINC)/cache) -LinkSourceFile(ftlru.h,$(FREETYPEINC)/cache) +LinkSourceFile(ftcmru.h,$(FREETYPEINC)/cache) Index: xc/lib/freetype2/freetype/internal/Imakefile =================================================================== RCS file: /cvs/xorg/xc/lib/freetype2/freetype/internal/Imakefile,v retrieving revision 1.2 diff -u -r1.2 Imakefile --- a/xc/lib/freetype2/freetype/internal/Imakefile 23 Apr 2004 18:44:24 -0000 1.2 +++ b/xc/lib/freetype2/freetype/internal/Imakefile 28 Apr 2004 10:26:32 -0000 @@ -17,6 +17,7 @@ ftgloadr.h \ ftmemory.h \ ftobjs.h \ + ftrfork.h \ ftserv.h \ ftstream.h \ fttrace.h \ @@ -38,6 +39,7 @@ LinkSourceFile(ftgloadr.h,$(FREETYPEINC)/internal) LinkSourceFile(ftmemory.h,$(FREETYPEINC)/internal) LinkSourceFile(ftobjs.h,$(FREETYPEINC)/internal) +LinkSourceFile(ftrfork.h,$(FREETYPEINC)/internal) LinkSourceFile(ftstream.h,$(FREETYPEINC)/internal) LinkSourceFile(ftserv.h,$(FREETYPEINC)/internal) LinkSourceFile(fttrace.h,$(FREETYPEINC)/internal) Index: xc/lib/freetype2/freetype/internal/services/Imakefile =================================================================== RCS file: /cvs/xorg/xc/lib/freetype2/freetype/internal/services/Imakefile,v retrieving revision 1.2 diff -u -r1.2 Imakefile --- a/xc/lib/freetype2/freetype/internal/services/Imakefile 23 Apr 2004 18:44:25 -0000 1.2 +++ b/xc/lib/freetype2/freetype/internal/services/Imakefile 28 Apr 2004 10:26:32 -0000 @@ -3,16 +3,17 @@ FREETYPEINC = $(FREETYPETOP)/include/freetype HEADERS= \ - svbdf.h \ - svmm.h \ - svpostnm.h \ - svpsinfo.h \ - svwinfnt.h \ - svgldict.h \ - svpfr.h \ - svpscmap.h \ - svsfnt.h \ - svxf86nm.h + svbdf.h \ + svmm.h \ + svpostnm.h \ + svpsinfo.h \ + svwinfnt.h \ + svgldict.h \ + svpfr.h \ + svpscmap.h \ + svsfnt.h \ + svttcmap.h \ + svxf86nm.h BuildIncludes($(HEADERS),freetype2/freetype/internal/services,../../../..) InstallMultipleFlags($(HEADERS),$(INCDIR)/freetype2/freetype/internal/services,$(INSTINCFLAGS)) @@ -26,4 +27,5 @@ LinkSourceFile(svpfr.h,$(FREETYPEINC)/internal/services) LinkSourceFile(svpscmap.h,$(FREETYPEINC)/internal/services) LinkSourceFile(svsfnt.h,$(FREETYPEINC)/internal/services) +LinkSourceFile(svttcmap.h,$(FREETYPEINC)/internal/services) LinkSourceFile(svxf86nm.h,$(FREETYPEINC)/internal/services)