27#define FT_COMPONENT pfr
40 pfr_glyph_init( PFR_Glyph glyph,
41 FT_GlyphLoader loader )
45 glyph->loader = loader;
47 FT_GlyphLoader_Rewind( loader );
52 pfr_glyph_done( PFR_Glyph glyph )
54 FT_Memory memory = glyph->loader->memory;
57 FT_FREE( glyph->x_control );
58 glyph->y_control = NULL;
60 glyph->max_xy_control = 0;
62 glyph->num_x_control = 0;
63 glyph->num_y_control = 0;
66 FT_FREE( glyph->subs );
72 glyph->path_begun = 0;
78 pfr_glyph_close_contour( PFR_Glyph glyph )
80 FT_GlyphLoader loader = glyph->loader;
81 FT_Outline* outline = &loader->current.outline;
85 if ( !glyph->path_begun )
89 last = outline->n_points - 1;
91 if ( outline->n_contours > 0 )
92 first = outline->contours[outline->n_contours - 1];
98 FT_Vector* p1 = outline->points + first;
99 FT_Vector* p2 = outline->points + last;
102 if ( p1->x == p2->x && p1->y == p2->y )
111 outline->contours[outline->n_contours++] = (FT_UShort)last;
113 glyph->path_begun = 0;
119 pfr_glyph_start( PFR_Glyph glyph )
121 glyph->path_begun = 0;
126 pfr_glyph_line_to( PFR_Glyph glyph,
129 FT_GlyphLoader loader = glyph->loader;
130 FT_Outline* outline = &loader->current.outline;
135 if ( !glyph->path_begun )
137 error = FT_THROW( Invalid_Table );
138 FT_ERROR((
"pfr_glyph_line_to: invalid glyph data\n" ));
142 error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 );
145 FT_Int n = outline->n_points;
148 outline->points[n] = *to;
149 outline->tags [n] = FT_CURVE_TAG_ON;
160 pfr_glyph_curve_to( PFR_Glyph glyph,
165 FT_GlyphLoader loader = glyph->loader;
166 FT_Outline* outline = &loader->current.outline;
171 if ( !glyph->path_begun )
173 error = FT_THROW( Invalid_Table );
174 FT_ERROR((
"pfr_glyph_line_to: invalid glyph data\n" ));
178 error = FT_GLYPHLOADER_CHECK_POINTS( loader, 3, 0 );
181 FT_Vector* vec = outline->points + outline->n_points;
182 FT_Byte* tag = outline->tags + outline->n_points;
188 tag[0] = FT_CURVE_TAG_CUBIC;
189 tag[1] = FT_CURVE_TAG_CUBIC;
190 tag[2] = FT_CURVE_TAG_ON;
192 outline->n_points += 3;
201 pfr_glyph_move_to( PFR_Glyph glyph,
204 FT_GlyphLoader loader = glyph->loader;
209 pfr_glyph_close_contour( glyph );
212 glyph->path_begun = 1;
215 error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 1 );
219 error = pfr_glyph_line_to( glyph, to );
227 pfr_glyph_end( PFR_Glyph glyph )
230 pfr_glyph_close_contour( glyph );
233 FT_GlyphLoader_Add( glyph->loader );
248 pfr_glyph_load_simple( PFR_Glyph glyph,
252 FT_Error error = FT_Err_Ok;
253 FT_Memory memory = glyph->loader->memory;
254 FT_UInt flags, x_count, y_count, i, count, mask;
259 flags = PFR_NEXT_BYTE( p );
262 if ( flags & PFR_GLYPH_IS_COMPOUND )
268 if ( flags & PFR_GLYPH_1BYTE_XYCOUNT )
271 count = PFR_NEXT_BYTE( p );
272 x_count = count & 15;
273 y_count = count >> 4;
277 if ( flags & PFR_GLYPH_XCOUNT )
280 x_count = PFR_NEXT_BYTE( p );
283 if ( flags & PFR_GLYPH_YCOUNT )
286 y_count = PFR_NEXT_BYTE( p );
290 count = x_count + y_count;
293 if ( count > glyph->max_xy_control )
295 FT_UInt new_max = FT_PAD_CEIL( count, 8 );
298 if ( FT_RENEW_ARRAY( glyph->x_control,
299 glyph->max_xy_control,
303 glyph->max_xy_control = new_max;
306 glyph->y_control = glyph->x_control + x_count;
311 for ( i = 0; i < count; i++ )
313 if ( ( i & 7 ) == 0 )
316 mask = PFR_NEXT_BYTE( p );
322 x = PFR_NEXT_SHORT( p );
327 x += PFR_NEXT_BYTE( p );
330 glyph->x_control[i] = x;
338 if ( flags & PFR_GLYPH_SINGLE_EXTRA_ITEMS )
340 error = pfr_extra_items_skip( &p, limit );
345 pfr_glyph_start( glyph );
353 pos[0].x = pos[0].y = 0;
358 FT_UInt format, format_low, args_format = 0, args_count, n;
365 format = PFR_NEXT_BYTE( p );
366 format_low = format & 15;
368 switch ( format >> 4 )
371 FT_TRACE6((
"- end glyph" ));
376 FT_TRACE6((
"- general line" ));
380 FT_TRACE6((
"- move to inside" ));
384 FT_TRACE6((
"- move to outside" ));
386 args_format = format_low;
391 FT_TRACE6((
"- horizontal line to cx.%u", format_low ));
392 if ( format_low >= x_count )
394 pos[0].x = glyph->x_control[format_low];
401 FT_TRACE6((
"- vertical line to cy.%u", format_low ));
402 if ( format_low >= y_count )
405 pos[0].y = glyph->y_control[format_low];
411 FT_TRACE6((
"- hv curve" ));
417 FT_TRACE6((
"- vh curve" ));
423 FT_TRACE6((
"- general curve" ));
425 args_format = format_low;
432 for ( n = 0; n < args_count; n++ )
439 switch ( args_format & 3 )
443 idx = PFR_NEXT_BYTE( p );
444 if ( idx >= x_count )
446 cur->x = glyph->x_control[idx];
447 FT_TRACE7((
" cx#%u", idx ));
452 cur->x = PFR_NEXT_SHORT( p );
453 FT_TRACE7((
" x.%ld", cur->x ));
458 delta = PFR_NEXT_INT8( p );
459 cur->x = pos[3].x + delta;
460 FT_TRACE7((
" dx.%d", delta ));
469 switch ( ( args_format >> 2 ) & 3 )
473 idx = PFR_NEXT_BYTE( p );
474 if ( idx >= y_count )
476 cur->y = glyph->y_control[idx];
477 FT_TRACE7((
" cy#%u", idx ));
482 cur->y = PFR_NEXT_SHORT( p );
483 FT_TRACE7((
" y.%ld", cur->y ));
488 delta = PFR_NEXT_INT8( p );
489 cur->y = pos[3].y + delta;
490 FT_TRACE7((
" dy.%d", delta ));
499 if ( n == 0 && args_count == 4 )
502 args_format = PFR_NEXT_BYTE( p );
518 switch ( format >> 4 )
521 pfr_glyph_end( glyph );
527 error = pfr_glyph_line_to( glyph, pos );
532 error = pfr_glyph_move_to( glyph, pos );
536 error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 );
550 error = FT_THROW( Invalid_Table );
551 FT_ERROR((
"pfr_glyph_load_simple: invalid glyph data\n" ));
558 pfr_glyph_load_compound( PFR_Glyph glyph,
562 FT_Error error = FT_Err_Ok;
563 FT_Memory memory = glyph->loader->memory;
564 PFR_SubGlyph subglyph;
565 FT_UInt flags, i, count, org_count;
570 flags = PFR_NEXT_BYTE( p );
573 if ( !( flags & PFR_GLYPH_IS_COMPOUND ) )
576 count = flags & 0x3F;
580 if ( flags & PFR_GLYPH_COMPOUND_EXTRA_ITEMS )
582 error = pfr_extra_items_skip( &p, limit );
595 org_count = glyph->num_subs;
597 if ( org_count + count > glyph->max_subs )
599 FT_UInt new_max = ( org_count + count + 3 ) & (FT_UInt)-4;
606 error = FT_THROW( Invalid_Table );
607 FT_ERROR((
"pfr_glyph_load_compound:"
608 " too many compound glyphs components\n" ));
612 if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) )
615 glyph->max_subs = new_max;
618 subglyph = glyph->subs + org_count;
620 for ( i = 0; i < count; i++, subglyph++ )
629 format = PFR_NEXT_BYTE( p );
632 subglyph->x_scale = 0x10000L;
633 if ( format & PFR_SUBGLYPH_XSCALE )
636 subglyph->x_scale = PFR_NEXT_SHORT( p ) * 16;
639 subglyph->y_scale = 0x10000L;
640 if ( format & PFR_SUBGLYPH_YSCALE )
643 subglyph->y_scale = PFR_NEXT_SHORT( p ) * 16;
647 switch ( format & 3 )
651 x_pos = PFR_NEXT_SHORT( p );
656 x_pos += PFR_NEXT_INT8( p );
663 switch ( ( format >> 2 ) & 3 )
667 y_pos = PFR_NEXT_SHORT( p );
672 y_pos += PFR_NEXT_INT8( p );
679 subglyph->x_delta = x_pos;
680 subglyph->y_delta = y_pos;
683 if ( format & PFR_SUBGLYPH_2BYTE_SIZE )
686 subglyph->gps_size = PFR_NEXT_USHORT( p );
691 subglyph->gps_size = PFR_NEXT_BYTE( p );
694 if ( format & PFR_SUBGLYPH_3BYTE_OFFSET )
697 subglyph->gps_offset = PFR_NEXT_ULONG( p );
702 subglyph->gps_offset = PFR_NEXT_USHORT( p );
713 error = FT_THROW( Invalid_Table );
714 FT_ERROR((
"pfr_glyph_load_compound: invalid glyph data\n" ));
720 pfr_glyph_load_rec( PFR_Glyph glyph,
731 if ( FT_STREAM_SEEK( gps_offset + offset ) ||
732 FT_FRAME_ENTER( size ) )
735 p = (FT_Byte*)stream->cursor;
738 if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND )
740 FT_UInt n, old_count, count;
741 FT_GlyphLoader loader = glyph->loader;
742 FT_Outline* base = &loader->base.outline;
745 old_count = glyph->num_subs;
748 error = pfr_glyph_load_compound( glyph, p, limit );
755 count = glyph->num_subs - old_count;
757 FT_TRACE4((
"compound glyph with %u element%s (offset %lu):\n",
759 count == 1 ?
"" :
"s",
763 for ( n = 0; n < count; n++ )
765 FT_Int i, old_points, num_points;
766 PFR_SubGlyph subglyph;
769 FT_TRACE4((
" subglyph %u:\n", n ));
771 subglyph = glyph->subs + old_count + n;
772 old_points = base->n_points;
774 error = pfr_glyph_load_rec( glyph, stream, gps_offset,
775 subglyph->gps_offset,
776 subglyph->gps_size );
781 subglyph = glyph->subs + old_count + n;
782 num_points = base->n_points - old_points;
785 if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L )
787 FT_Vector* vec = base->points + old_points;
790 for ( i = 0; i < num_points; i++, vec++ )
792 vec->x = FT_MulFix( vec->x, subglyph->x_scale ) +
794 vec->y = FT_MulFix( vec->y, subglyph->y_scale ) +
800 FT_Vector* vec = loader->base.outline.points + old_points;
803 for ( i = 0; i < num_points; i++, vec++ )
805 vec->x += subglyph->x_delta;
806 vec->y += subglyph->y_delta;
813 FT_TRACE4((
"end compound glyph with %u element%s\n",
815 count == 1 ?
"" :
"s" ));
819 FT_TRACE4((
"simple glyph (offset %lu)\n", offset ));
822 error = pfr_glyph_load_simple( glyph, p, limit );
832 FT_LOCAL_DEF( FT_Error )
833 pfr_glyph_load( PFR_Glyph glyph,
840 FT_GlyphLoader_Rewind( glyph->loader );
845 return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size );