diff options
Diffstat (limited to 'Build/source/libs/t1lib/t1outline.c')
-rw-r--r-- | Build/source/libs/t1lib/t1outline.c | 766 |
1 files changed, 766 insertions, 0 deletions
diff --git a/Build/source/libs/t1lib/t1outline.c b/Build/source/libs/t1lib/t1outline.c new file mode 100644 index 00000000000..23942780dd3 --- /dev/null +++ b/Build/source/libs/t1lib/t1outline.c @@ -0,0 +1,766 @@ +/*-------------------------------------------------------------------------- + ----- File: t1outline.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-12-02 + ----- Description: This file is part of the t1-library. It contains + functions for getting glyph outline descriptions of + strings and characters. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1OUTLINE_C + + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include <setjmp.h> + +#include "../type1/ffilest.h" +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" +#include "../type1/paths.h" + + +#include "t1types.h" +#include "t1extern.h" +#include "t1set.h" +#include "t1load.h" +#include "t1finfo.h" +#include "t1misc.h" +#include "t1base.h" +#include "t1outline.h" + + +/* As a fall back */ +#ifndef T1_AA_TYPE16 +#define T1_AA_TYPE16 short +#endif +#ifndef T1_AA_TYPE32 +#define T1_AA_TYPE32 int +#endif + + +extern char *t1_get_abort_message( int number); +extern struct segment *Type1Line(psfont *env, struct XYspace *S, + float line_position, + float line_thickness, + float line_length); +extern struct segment *t1_Join( struct segment *path1, + struct segment *path2); +extern struct segment *CopyPath( struct segment *p); +extern void KillPath( struct segment *p); + + + + +/* T1_SetChar(...): Generate the bitmap for a character */ +T1_OUTLINE *T1_GetCharOutline( int FontID, char charcode, float size, + T1_TMATRIX *transform) +{ + int i; + int mode; + T1_PATHSEGMENT *charpath; + struct XYspace *Current_S; + unsigned char ucharcode; + + + FONTSIZEDEPS *font_ptr; + FONTPRIVATE *fontarrayP; + + /* We don't implement underlining for characters, but the rasterer + implements it. Thus, we use a modflag of constant 0 */ + int modflag=0; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_GetCharOutline()", err_warn_msg_buf, + T1LOG_ERROR); + return( NULL); + } + + ucharcode=(unsigned char)charcode; + + + /* First, check for a correct ID */ + i=T1_CheckForFontID(FontID); + if (i==-1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + /* if necessary load font into memory */ + if (i==0) + if (T1_LoadFont(FontID)) + return(NULL); + + /* Check for valid size */ + if (size<=0.0){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + fontarrayP=&(pFontBase->pFontArray[FontID]); + + /* font is now loaded into memory => + Check for size: */ + if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ + font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS); + if (font_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + } + + /* Setup an appropriate charspace matrix. Note that the rasterizer + assumes vertical values with inverted sign! Transformation should + create a copy of the local charspace matrix which then still has + to be made permanent. */ + if (transform!=NULL) { + Current_S=(struct XYspace *) + Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, + transform->cxx, - transform->cxy, + transform->cyx, - transform->cyy), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + else{ + Current_S=(struct XYspace *) + Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, + 1.0, 0.0, 0.0, -1.0), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + + + /* fnt_ptr now points to the correct FontSizeDeps-struct => + lets now raster the character */ + mode=0; + charpath=(T1_PATHSEGMENT *)fontfcnB( FontID, modflag, Current_S, + fontarrayP->pFontEnc, + ucharcode, &mode, + fontarrayP->pType1Data, + DO_NOT_RASTER,0.0f); + KillSpace (Current_S); + + return((T1_OUTLINE *)charpath); +} + + + +/* T1_GetStringOutline(...): Generate the outline for a string of + characters */ +T1_OUTLINE *T1_GetStringOutline( int FontID, char *string, int len, + long spaceoff, int modflag, float size, + T1_TMATRIX *transform) +{ + int i; + int mode; + /* initialize this to NULL just to be on the safe side */ + T1_PATHSEGMENT *charpath = NULL; + struct XYspace *Current_S; + int *kern_pairs; /* use for accessing the kern pairs if kerning is + requested */ + int no_chars=0; /* The number of characters in the string */ + static int lastno_chars=0; + long spacewidth; /* This is given to fontfcnb_string() */ + + + FONTSIZEDEPS *font_ptr; + FONTPRIVATE *fontarrayP; + + static int *pixel_h_anchor_corr=NULL; + static int *flags=NULL; + + unsigned char *ustring; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_GetStringOutline()", err_warn_msg_buf, + T1LOG_ERROR); + return( NULL); + } + + /* force string elements into unsigned */ + ustring=(unsigned char*)string; + + /* First, check for a correct ID */ + i=T1_CheckForFontID(FontID); + if (i==-1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + /* if necessary load font into memory */ + if (i==0) + if (T1_LoadFont(FontID)) + return(NULL); + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return(NULL); + } + + /* Check for valid size */ + if (size<=0.0){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + fontarrayP=&(pFontBase->pFontArray[FontID]); + + /* font is now loaded into memory => + Check for size: */ + if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ + font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS); + if (font_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + } + + /* Now comes string specific stuff: Get length of string and create an + array of integers where to store the bitmap positioning dimens: */ + if (len<0){ /* invalid length */ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + if (len==0) /* should be computed assuming "normal" 0-terminated string */ + no_chars=strlen(string); + else /* use value given on command line */ + no_chars=len; + + /* If necessary, allocate memory */ + if (no_chars>lastno_chars){ + if (pixel_h_anchor_corr!=NULL){ + free(pixel_h_anchor_corr); + } + if (flags!=NULL){ + free(flags); + } + + pixel_h_anchor_corr=(int *)calloc(no_chars, sizeof(int)); + flags=(int *)calloc(no_chars, sizeof(int)); + lastno_chars=no_chars; + } + else{ + /* Reset flags and position array */ + for (i=0; i<no_chars; i++){ + flags[i]=0; + pixel_h_anchor_corr[i]=0; + } + } + + /* Setup an appropriate charspace matrix. Note that the rasterizer + assumes vertical values with inverted sign! Transformation should + create a copy of the local charspace matrix which then still has + to be made permanent. */ + if (transform!=NULL){ + Current_S=(struct XYspace *) + Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, + transform->cxx, - transform->cxy, + transform->cyx, - transform->cyy), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + else{ + Current_S=(struct XYspace *) + Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, + 1.0, 0.0, 0.0, -1.0), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + + /* Compute the correct spacewidth value (in charspace units). The + value supplied by the user is interpreted as an offset in + char space units: + */ + spacewidth=T1_GetCharWidth(FontID,fontarrayP->space_position)+spaceoff; + + mode=0; + kern_pairs=(int *)calloc(no_chars, sizeof(int)); + if ((modflag & T1_KERNING)) + for (i=0; i<no_chars -1; i++) + kern_pairs[i]=T1_GetKerning( FontID, ustring[i], ustring[i+1]); + charpath=(T1_PATHSEGMENT *) fontfcnB_string( FontID, modflag, Current_S, + fontarrayP->pFontEnc, + (unsigned char *)string, + no_chars, &mode, + fontarrayP->pType1Data, + kern_pairs, spacewidth, + DO_NOT_RASTER,0.0f); + KillSpace (Current_S); + + /* In all cases, free memory for kerning pairs */ + free(kern_pairs); + + /* fill the string_glyph-structure */ + if (mode != 0) { + sprintf( err_warn_msg_buf, "fontfcnB_string() set mode=%d", mode); + T1_PrintLog( "T1_GetStringOutline()", err_warn_msg_buf, T1LOG_WARNING); + T1_errno=mode; + /* make sure to get rid of path if it's there */ + if (charpath){ + KillRegion (charpath); + } + return(NULL); + } + if (charpath == NULL){ + T1_PrintLog( "T1_GetStringOutline()", "path=NULL returned by fontfcnB_string()", T1LOG_WARNING); + T1_errno=mode; + return(NULL); + } + + return( (T1_OUTLINE *)charpath); +} + + +/* T1_GetMoveOutline(...): Generate the "outline" for a movement + */ +T1_OUTLINE *T1_GetMoveOutline( int FontID, int deltax, int deltay, int modflag, + float size, T1_TMATRIX *transform) +{ + int i; + FONTSIZEDEPS *font_ptr; + struct segment *path, *tmppath; + struct XYspace *Current_S; + psfont *FontP; + float length; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_GetMoveOutline()", err_warn_msg_buf, + T1LOG_ERROR); + return( NULL); + } + + + /* First, check for a correct ID */ + i=T1_CheckForFontID(FontID); + if (i==-1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + /* if necessary load font into memory */ + if (i==0) + if (T1_LoadFont(FontID)) + return(NULL); + + /* Check for valid size */ + if (size<=0.0){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + FontP=pFontBase->pFontArray[i].pType1Data; + + /* font is now loaded into memory => + Check for size: */ + if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ + font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS); + if (font_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + } + + /* Setup an appropriate charspace matrix. Note that the rasterizer + assumes vertical values with inverted sign! Transformation should + create a copy of the local charspace matrix which then still has + to be made permanent. */ + if (transform!=NULL){ + Current_S=(struct XYspace *) + Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, + transform->cxx, - transform->cxy, + transform->cyx, - transform->cyy), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + else{ + Current_S=(struct XYspace *) + Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, + 1.0, 0.0, 0.0, -1.0), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + + + path=(struct segment *)ILoc( Current_S, deltax, deltay); + + /* Take care for underlining and such */ + length=(float) deltax; + if (modflag & T1_UNDERLINE){ + tmppath=(struct segment *)Type1Line(FontP,Current_S, + pFontBase->pFontArray[FontID].UndrLnPos, + pFontBase->pFontArray[FontID].UndrLnThick, + length); + path=(struct segment *)Join(path,tmppath); + } + if (modflag & T1_OVERLINE){ + tmppath=(struct segment *)Type1Line(FontP,Current_S, + pFontBase->pFontArray[FontID].OvrLnPos, + pFontBase->pFontArray[FontID].OvrLnThick, + length); + path=(struct segment *)Join(path,tmppath); + } + if (modflag & T1_OVERSTRIKE){ + tmppath=(struct segment *)Type1Line(FontP,Current_S, + pFontBase->pFontArray[FontID].OvrStrkPos, + pFontBase->pFontArray[FontID].OvrStrkThick, + length); + path=(struct segment *)Join(path,tmppath); + } + + KillSpace( Current_S); + + return( (T1_OUTLINE *)path); + +} + + +/* T1_ConcatOutlines(): Concatenate two outline to one path */ +T1_OUTLINE *T1_ConcatOutlines( T1_OUTLINE *path1, T1_OUTLINE *path2) +{ + + return( (T1_OUTLINE *) t1_Join( (struct segment *) path1, + (struct segment *) path2)); + +} + + +/* T1_ScaleOutline(): Scale an outline */ +T1_OUTLINE *T1_ScaleOutline( T1_OUTLINE *path, float scale) +{ + struct segment *ipath; + + /* Step through the path list */ + ipath=(struct segment *)path; + + do { + if (ipath->type==LINETYPE){ + ipath->dest.x = (fractpel) (ipath->dest.x * scale); + ipath->dest.y = (fractpel) (ipath->dest.y * scale); + } + if (ipath->type==CONICTYPE){ + ((struct conicsegment *)ipath)->dest.x = + (fractpel) ((struct conicsegment *)ipath)->dest.x * scale; + ((struct conicsegment *)ipath)->dest.y = + (fractpel) ((struct conicsegment *)ipath)->dest.y * scale; + ((struct conicsegment *)ipath)->M.x = + (fractpel) ((struct conicsegment *)ipath)->M.x * scale; + ((struct conicsegment *)ipath)->M.y = + (fractpel) ((struct conicsegment *)ipath)->M.y * scale; + } + if (ipath->type==MOVETYPE){ + ipath->dest.x = (fractpel) (ipath->dest.x * scale); + ipath->dest.y = (fractpel) (ipath->dest.y * scale); + } + if (ipath->type==BEZIERTYPE){ + ((struct beziersegment *)ipath)->B.x = + (fractpel) (((struct beziersegment *)ipath)->B.x * scale); + ((struct beziersegment *)ipath)->B.y = + (fractpel) (((struct beziersegment *)ipath)->B.y * scale); + ((struct beziersegment *)ipath)->C.x = + (fractpel) (((struct beziersegment *)ipath)->C.x * scale); + ((struct beziersegment *)ipath)->C.y = + (fractpel) (((struct beziersegment *)ipath)->C.y * scale); + ((struct beziersegment *)ipath)->dest.x = + (fractpel) (((struct beziersegment *)ipath)->dest.x * scale); + ((struct beziersegment *)ipath)->dest.y = + (fractpel) (((struct beziersegment *)ipath)->dest.y * scale); + } + if (ipath->type==HINTTYPE){ + ((struct hintsegment *)ipath)->dest.x = + (fractpel) (((struct hintsegment *)ipath)->dest.x * scale); + ((struct hintsegment *)ipath)->dest.y = + (fractpel) (((struct hintsegment *)ipath)->dest.y * scale); + ((struct hintsegment *)ipath)->ref.x = + (fractpel) (((struct hintsegment *)ipath)->ref.x * scale); + ((struct hintsegment *)ipath)->ref.y = + (fractpel) (((struct hintsegment *)ipath)->ref.y * scale); + ((struct hintsegment *)ipath)->width.x = + (fractpel) (((struct hintsegment *)ipath)->width.x * scale); + ((struct hintsegment *)ipath)->width.y = + (fractpel) (((struct hintsegment *)ipath)->width.y * scale); + } + if (ipath->type==TEXTTYPE) + ; + ipath=ipath->link; + + } while (ipath!=NULL); + + return( path); + +} + + +/* dump a description of path elements to stdout */ +void T1_DumpPath( T1_OUTLINE *path) +{ + + struct segment *ipath; + + /* Step through the path list */ + ipath=(struct segment *)path; + + do { + if (ipath->type==LINETYPE){ + printf("Line-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); + } + if (ipath->type==MOVETYPE){ + printf("Move-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); + } + if (ipath->type==BEZIERTYPE){ + printf("Bezier-Segment: ... (%f,%f) ... (%f,%f) -> (%f,%f)\n", + (((struct beziersegment *)ipath)->B.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->B.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->C.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->C.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->dest.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->dest.y)/(double)(0xFFFF)); + } + ipath=ipath->link; + } while (ipath!=NULL); + +} + + +/* convert a relative path to an absolute path */ +void T1_AbsolutePath( T1_OUTLINE *rpath) +{ + + struct segment *ipath; + fractpel xcurr=0, ycurr=0; + + /* Step through the path list */ + ipath=(struct segment *)rpath; + + do { + if (ipath->type==LINETYPE){ + ipath->dest.x +=xcurr; + ipath->dest.y +=ycurr; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Line-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); +#endif + xcurr=ipath->dest.x; + ycurr=ipath->dest.y; + } + if (ipath->type==MOVETYPE){ + ipath->dest.x +=xcurr; + ipath->dest.y +=ycurr; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Move-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); +#endif + xcurr=ipath->dest.x; + ycurr=ipath->dest.y; + } + if (ipath->type==BEZIERTYPE){ + ((struct beziersegment *)ipath)->B.x +=xcurr; + ((struct beziersegment *)ipath)->B.y +=ycurr; + ((struct beziersegment *)ipath)->C.x +=xcurr; + ((struct beziersegment *)ipath)->C.y +=ycurr; + ipath->dest.x +=xcurr; + ipath->dest.y +=ycurr; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Bezier-Segment: ... (%f,%f) ... (%f,%f) -> (%f,%f)\n", + (((struct beziersegment *)ipath)->B.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->B.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->C.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->C.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->dest.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->dest.y)/(double)(0xFFFF)); +#endif + xcurr=ipath->dest.x; + ycurr=ipath->dest.y; + } + ipath=ipath->link; + } while (ipath!=NULL); + +} + + + +/* convert path into a relative path as needed by the rasterizer */ +void T1_RelativePath( T1_OUTLINE *apath) +{ + + struct segment *ipath; + fractpel xcurr=0, ycurr=0; + + + /* Step through the path list */ + ipath=(struct segment *)apath; + + do { + if (ipath->type==LINETYPE){ + ipath->dest.x -=xcurr; + ipath->dest.y -=ycurr; + xcurr +=ipath->dest.x; + ycurr +=ipath->dest.y; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Line-Segment: -> (%f,%f), curr=(%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF), + xcurr/(double)(0xFFFF), -ycurr/(double)(0xFFFF)); +#endif + } + if (ipath->type==MOVETYPE){ + ipath->dest.x -=xcurr; + ipath->dest.y -=ycurr; + xcurr +=ipath->dest.x; + ycurr +=ipath->dest.y; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Move-Segment: -> (%f,%f), curr=(%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF), + xcurr/(double)(0xFFFF), -ycurr/(double)(0xFFFF)); +#endif + } + if (ipath->type==BEZIERTYPE){ + ipath->dest.x -=xcurr; + ipath->dest.y -=ycurr; + ((struct beziersegment *)ipath)->C.x -=xcurr; + ((struct beziersegment *)ipath)->C.y -=ycurr; + ((struct beziersegment *)ipath)->B.x -=xcurr; + ((struct beziersegment *)ipath)->B.y -=ycurr; + xcurr +=ipath->dest.x; + ycurr +=ipath->dest.y; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Bezier-Segment: ... (%f,%f) ... (%f,%f) -> (%f,%f)\n", + (((struct beziersegment *)ipath)->B.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->B.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->C.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->C.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->dest.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->dest.y)/(double)(0xFFFF)); +#endif + } + ipath=ipath->link; + } while (ipath!=NULL); + +} + + +/* maniuplate the coordinata points of a path */ +void T1_ManipulatePath( T1_OUTLINE *path, + void (*manipulate)(fractpel *x,fractpel *y,int type)) +{ + + struct segment *ipath; + + + /* Step through the path list */ + ipath=(struct segment *)path; + + do { + if (ipath->type==LINETYPE){ + manipulate( &(ipath->dest.x), &ipath->dest.y, LINETYPE); +#ifdef PRINT_PATHS_TO_STDOUT + printf("Line-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); +#endif + } + if (ipath->type==MOVETYPE){ + manipulate( &(ipath->dest.x), &ipath->dest.y, MOVETYPE); +#ifdef PRINT_PATHS_TO_STDOUT + printf("Move-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); +#endif + } + if (ipath->type==BEZIERTYPE){ + manipulate( &((struct beziersegment *)ipath)->B.x, + &((struct beziersegment *)ipath)->B.y, + BEZIERTYPE); + manipulate( &((struct beziersegment *)ipath)->C.x, + &((struct beziersegment *)ipath)->C.y, + BEZIERTYPE); + manipulate( &((struct beziersegment *)ipath)->dest.x, + &((struct beziersegment *)ipath)->dest.y, + BEZIERTYPE); +#ifdef PRINT_PATHS_TO_STDOUT + printf("Bezier-Segment: ... (%f,%f) ... (%f,%f) -> (%f,%f)\n", + (((struct beziersegment *)ipath)->B.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->B.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->C.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->C.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->dest.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->dest.y)/(double)(0xFFFF)); +#endif + } + ipath=ipath->link; + } while (ipath!=NULL); + +} + + + +/* T1_CopyOutline(): Copy an outline physically. + Returns a pointer to the path or NULL */ +T1_OUTLINE *T1_CopyOutline( T1_OUTLINE *path) +{ + + return( (T1_OUTLINE *) CopyPath( (struct segment *)path)); + +} + + + +/* T1_FreeOutline(): Free an outline. */ +void T1_FreeOutline( T1_OUTLINE *path) +{ + + KillPath( (struct segment *)path); + return; + +} + |