/****************************************************************************/ /* */ /* PScript.h */ /* */ /****************************************************************************/ /****************************************************************************/ /* This is a C language header file that defines some graphical routines */ /* for generating an executable PostScript language program. This is a very */ /* reduced version of a much larger program and defines only those routines */ /* sufficient for plotting simple magnetograms. */ /* The unit of length in all routines is mm (millimeter). Font sizes are in */ /* units of points. */ /****************************************************************************/ /****************************************************************************/ /* Lasse Hakkinen */ /* Finnish Meteorological Institute */ /* Department of Geophysics */ /* P.O.Box 503 */ /* FIN-00101, Helsinki, Finland */ /* e-mail: Lasse.Hakkinen@fmi.fi */ /* phone : (+358)-9-19294634 */ /* fax : (+358)-9-19294634 */ /* */ /* version 1.0 13.11.1995 */ /****************************************************************************/ /****************************************************************************/ /* Version history: */ /* */ /* 1.0 13.11.1995 First official release */ /****************************************************************************/ #include #include #include /*--------------------------------------------------------------------------*/ /* Pagewidth defines the width of page. The default value is for A4 paper */ /* size. If you are using US letter then change the value into 216. */ /*--------------------------------------------------------------------------*/ #define PageWidth 210 /*--------------------------------------------------------------------------*/ /* Function prototypes */ /*--------------------------------------------------------------------------*/ void InitializePS(char *TitleStr, char *CreatorStr, char *CreationDateStr, long xLeft, long yBottom, long xRight, long yTop); void NewPagePS(long PageNumber); void ClosePagePS(void); void ClosePS(void); void LandscapePS(void); void TranslatePS(float x, float y); void RotatePS(float angle); void ZoomPS(float ZoomFactor); void FontPS(char *Font,float size); void TextPS(float x,float y,float angle,char mode,char *TextStr); void SetGrayPS(float gray); void SetColorPS(float red,float green,float blue); void MoveToPS(float x,float y); void ClosePathPS(void); void LineWidthPS(float width); static void Dash2(float LengthTot,long LengthVis,long LengthInvis); void LineTypePS(long Linetype,float LengthTot); void LineCapPS(long Param); void LineJoinPS(long Param); void LinePS(float x0,float y0,float x1,float y1); void LineToPS(float x,float y); void RectPS(float x,float y,float dx,float dy,float angle); void FillRectPS(float x,float y,float dx,float dy,float angle, float gray,long Border); void FillColorRectPS(float x,float y,float dx,float dy,float angle, float red,float green,float blue,long Border); void RectClipPS(float x,float y,float dx,float dy); void InitClipPS(); void CirclePS(float x,float y,float rad); void FillCirclePS(float x,float y,float rad,float gray,long Border); void FillColorCirclePS(float x,float y,float rad, float red,float green,float blue,long Border); void CrossPS(float x,float y,float length); void XCrossPS(float x,float y,float length); void FMILogoPS(float x,float y,float size); /*--------------------------------------------------------------------------*/ /* Write header information and several definitions into stdout. This must */ /* be the first PS-command to be called from user's C program. */ /* TitleStr, CreatorStr and CreationDateStr define some useful information */ /* about the postscript file. They are not absolutely necessary but are */ /* usually found in a proper Encapsulated Postscript File (EPS). */ /* The parameters xLeft,yBottom,xRight and yTop define the BoundingBox */ /* i.e. the rectangle which totally encloses the whole picture. BoundingBox */ /* is needed in an EPS-file. */ /*--------------------------------------------------------------------------*/ void InitializePS(char *TitleStr, char *CreatorStr, char *CreationDateStr, long xLeft, long yBottom, long xRight, long yTop) { /* --------- Header --------- */ printf("%%!PS-Adobe-2.0\n"); printf("%%%%Creator: %s\n",CreatorStr); printf("%%%%Title: %s\n",TitleStr); printf("%%%%CreationDate: %s",CreationDateStr); printf("%%%%BoundingBox: %d %d %d %d\n",xLeft,yBottom,xRight,yTop); printf("%%%%EndProlog\n\n"); /* ----- Some PostScript definitions (abbreviations) ----- */ printf("/SW {setlinewidth} def\n"); printf("/M {moveto} def\n"); printf("/RM {rmoveto} def\n"); printf("/L {lineto} def\n"); printf("/RL {rlineto} def\n"); printf("/N {newpath} def\n"); printf("/C {closepath} def\n"); printf("/CP {currentpoint} def\n"); printf("/TR {translate} def\n"); printf("/RO {rotate} def\n"); printf("/GS {gsave} def\n"); printf("/GR {grestore} def\n"); printf("/S {stroke} def\n"); printf("/SG {setgray} def\n"); printf("/LI {newpath moveto lineto stroke} def\n\n"); /* ----- Text handling definitions ----- */ printf("/T1 {GS TR RO} def\n"); printf("/T2 {dup stringwidth pop} def\n"); printf("/T3 {0 M show GR} def\n"); printf("/LE {pop 0} def\n"); printf("/CE {2 div neg} def\n"); printf("/RI {neg} def\n"); printf("/FF {findfont} def\n"); printf("/SS {scalefont setfont} def\n\n"); /* ----- Rectangle drawing definitions ----- */ printf("/REC {GS TR RO N 0 0 M dup neg exch 0 exch RL\n"); printf(" exch 0 RL 0 exch RL C} def\n"); printf("/RE {REC S GR} def\n"); printf("/RF {REC SG fill GR} def\n"); printf("/RB {REC GS SG fill GR S GR} def\n"); printf("/RFC {REC setrgbcolor fill GR} def\n"); printf("/RBC {REC GS setrgbcolor fill GR S GR} def\n"); printf("/RCLIP {N M dup neg exch 0 exch RL\n"); printf("exch 0 RL 0 exch RL C clip} def\n\n"); /* ----- Circle drawing definitions ----- */ printf("/CIR {N 0 360 arc C} def\n"); printf("/CI {CIR S} def\n"); printf("/CF {CIR GS SG fill GR} def\n"); printf("/CB {CIR GS SG fill GR S} def\n"); printf("/CFC {CIR GS setrgbcolor fill GR} def\n"); printf("/CBC {CIR GS setrgbcolor fill GR S} def\n\n"); /* ----- Simple cross and X-cross ----- */ printf("/CRO {N 0 0 N dup 2 div neg dup 0 RM exch dup 0\n"); printf(" RL exch dup RM 0 exch RL S GR} def\n"); printf("/CR {GS TR CRO} def\n"); printf("/CX {GS TR 45 RO CRO} def\n\n"); /* ----- FMI logo routines -----*/ printf("/AR {N arc S} def\n"); printf("/CIRS {-0.326 0 0.451 -80 80 AR\n"); printf("-0.363 0 0.363 -85 85 AR\n"); printf("-0.401 0 0.276 -95 95 AR\n"); printf("-0.422 0 0.174 -110 110 AR\n"); printf("-0.471 0 0.099 -110 110 AR} def\n"); printf("/FMILOGO {GS TR dup scale 0.050 SW 0 0 0.5 0 360 AR\n"); printf("0.044 SW -0.5 0 M 0.5 0 L S CIRS 180 RO CIRS GR} def\n\n"); /* ----- Some final settings ----- */ printf("GS\n"); /* save the graphics state */ printf("%%%% Change units into millimeters\n"); printf("2.835 2.835 scale\n"); /* Scale 1/72 inches to mm:s */ printf("%%%% Set global origin\n"); printf("0 0 TR\n\n"); printf("%%%% ====== End of Header ====== %%%%\n\n"); } /*--------------------------------------------------------------------------*/ /* Define the page handling routines. NewPagePS and ClosePagePS must always */ /* appear as a pair in user's program. All drawing routines must be inside */ /* NewPagePS and ClosePagePS. No PS-commands are allowed between previous */ /* ClosePagePS and next NewPagePS commands. The user must keep track of the */ /* page number defined in NewPagePS. */ /*--------------------------------------------------------------------------*/ void NewPagePS(long PageNumber) { printf("%%%% Page %d\n\n",PageNumber); printf("GS\n"); } void ClosePagePS(void) { printf("showpage\n"); printf("GR\n"); } /*--------------------------------------------------------------------------*/ /* The last PS-command called from user's program must be ClosePS. */ /*--------------------------------------------------------------------------*/ void ClosePS(void) { printf("GR\n"); /* Restore the graphics state */ printf("%%%%Trailer\n"); } /*==========================================================================*/ /* Coordinate system manipulation commands */ /*==========================================================================*/ void LandscapePS(void) /* Turn page into landscape mode */ { printf("%d 0 TR 90 RO\n",PageWidth); } void TranslatePS(float x, float y) /* Change the origo */ { printf("%.3f %.3f TR\n",x,y); } void RotatePS(float angle) /* Rotate the coordinate system */ { printf("%.3f RO\n",angle); } void ZoomPS(float ZoomFactor) /* Change the scale */ { printf("%.3f %.3f scale\n",ZoomFactor,ZoomFactor); } /*==========================================================================*/ /* Text manipulation routines */ /*==========================================================================*/ /*--------------------------------------------------------------------------*/ /* Set the font size. Note that the unit of size parameter here is points. */ /*--------------------------------------------------------------------------*/ void FontPS(char *Font,float size) { printf("/%s FF %.3f SS\n",Font,0.353*size); } /*--------------------------------------------------------------------------*/ /* Write a text string into location (x,y) and rotate it by angle degrees. */ /* Mode defines text alignment: L: left-aligned, C: centered, R:right- */ /* aligned. */ /*--------------------------------------------------------------------------*/ void TextPS(float x,float y,float angle,char mode,char *TextStr) { printf("%.3f %.3f %.3f T1\n",angle,x,y); printf("(%s) T2 ",TextStr); switch (mode) { case 'l' : case 'L' : printf("LE T3\n"); break; /* left aligned */ case 'c' : case 'C' : printf("CE T3\n"); break; /* centered */ case 'r' : case 'R' : printf("RI T3\n"); break; /* right aligned */ } } /*--------------------------------------------------------------------------*/ /* Set the pencil color or grayscale. Here gray = 0 is black and gray = 1 */ /* is white. Values of the colors red, green and blue must be between 0 */ /* and 1. (0,0,0) is black and (1,1,1) is white. */ /*--------------------------------------------------------------------------*/ void SetGrayPS(float gray) { printf("%.3f SG\n",gray); } void SetColorPS(float red,float green,float blue) { printf("%.3f %.3f %.3f setrgbcolor\n",red,green,blue); } /*==========================================================================*/ /* Some pencil operations. MoveToPS moves the pencil into given location */ /* without drawing anything. ClosePathPS causes the current path (= series */ /* of line segments) to be drawn. Every line drawing (e.g. a magnetogram */ /* plot must be started with MoveToPS and ended with ClosePathPS. */ /*==========================================================================*/ void MoveToPS(float x,float y) { printf("N %.3f %.3f M\n",x,y); } void ClosePathPS(void) { printf("S\n"); } /*==========================================================================*/ /* Routines that define how lines are drawn. */ /*==========================================================================*/ /*--------------------------------------------------------------------------*/ /* LineWidthPS defines the drawing size of the pencil. */ /*--------------------------------------------------------------------------*/ void LineWidthPS(float width) { printf("%.3f SW\n",width); } /*--------------------------------------------------------------------------*/ /* LineTypePS routine defines the type of the line (continuous, dashed, */ /* dotted etc.) Here the line consists of two parts (visible and invisible)*/ /* which appear periodically one after another. The parameter scale is the */ /* length of one period. Parameter Linetype may be 0 (continuous line), 1 */ /* (dashed line with equal lengths), 2 (dashed line with relative length */ /* 13 and 7), ... */ /*--------------------------------------------------------------------------*/ static void Dash2(float LengthTot,long LengthVis,long LengthInvis) { float aux; aux = LengthTot/(LengthVis+LengthInvis); printf("%.3f %.3f",LengthVis*aux,LengthInvis*aux); } void LineTypePS(long Linetype,float LengthTot) { printf("["); switch (Linetype) { case 1 : Dash2(LengthTot,1,1); break; case 2 : Dash2(LengthTot,13,7); break; case 3 : Dash2(LengthTot,3,1); break; case 4 : Dash2(LengthTot,1,19); break; case 5 : Dash2(LengthTot,1,4); break; case 6 : Dash2(LengthTot,1,3); break; } printf("] 0 setdash\n"); } /*--------------------------------------------------------------------------*/ /* LineCapPS defines how line ends are handled. Param = 0 means that line */ /* ends exactly at the end point. Param = 1 means that half of the line */ /* width is appended at both ends of the line. Param = 2 means that the */ /* ends are rounded with semicircles with radius = width/2. */ /*--------------------------------------------------------------------------*/ void LineCapPS(long Param) { printf("%d setlinecap\n",Param); } /*--------------------------------------------------------------------------*/ /* LineJoinPS tells how two lines are connected to each other. Param = 0 */ /* implies a miter join (sharp corner). Param = 1 means a round join and */ /* Param = 2 implies a bevel join. */ /*--------------------------------------------------------------------------*/ void LineJoinPS(long Param) { printf("%d setlinejoin\n",Param); } /*--------------------------------------------------------------------------*/ /* LinePS draws a straight line from (x0,y0) to (x1,y1). */ /*--------------------------------------------------------------------------*/ void LinePS(float x0,float y0,float x1,float y1) { /* printf("%.3f %.3f %.3f %.3f LI\n",x1,y1,x0,y0); */ printf("%.3f %.3f ",x1,y1); printf("%.3f %.3f LI\n",x0,y0); } /*--------------------------------------------------------------------------*/ /* LineToPS draws a straight line from current pencil location to (x,y). */ /*--------------------------------------------------------------------------*/ void LineToPS(float x,float y) { printf("%.3f %.3f L\n",x,y); } /*==========================================================================*/ /* Rectangle drawing routines */ /*==========================================================================*/ /*--------------------------------------------------------------------------*/ /* RectPS draws a rectangle with lower left corner at (x,y) and lengths of */ /* the sides as dx and dy, respectively. Parameter angle defines how much */ /* the rectangle is rotated counterclockwise around point (x,y). */ /*--------------------------------------------------------------------------*/ void RectPS(float x,float y,float dx,float dy,float angle) { printf("%.3f %.3f %.3f %.3f %.3f RE\n",dx,dy,angle,x,y); } /*--------------------------------------------------------------------------*/ /* FillRectPS draws a rectangle with lower left corner at (x,y) and side */ /* lengths dx and dy, respectively. Parameter angle defines how much the */ /* rectangle is rotated counter clockwise around point (x,y). Also the */ /* routine fills the rectangle with gray shade defined by the parameter */ /* gray (0 = black, 1 = white). Furthermore the parameter Border tells */ /* whether the border of the rectangle is drawn (1) or not (0). */ /*--------------------------------------------------------------------------*/ void FillRectPS(float x,float y,float dx,float dy,float angle, float gray,long Border) { printf("%.3f %.3f %.3f %.3f %.3f %.3f ",gray,dx,dy,angle,x,y); if (Border) printf("RB\n"); else printf("RF\n"); } /*--------------------------------------------------------------------------*/ /* Same as above but the rectangle is filled with color (red,green,blue) */ /* where red, green and blue are all between 0 and 1. */ /*--------------------------------------------------------------------------*/ void FillColorRectPS(float x,float y,float dx,float dy,float angle, float red,float green,float blue,long Border) { printf("%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f ", red,green,blue,dx,dy,angle,x,y); if (Border) printf("RBC\n"); else printf("RFC\n"); } /*--------------------------------------------------------------------------*/ /* RectClipPS confines all drawing within the given rectangle. Nothing */ /* will be drawn outside the rectangle. To remove the clipping use the */ /* InitClipPS-routine. */ /*--------------------------------------------------------------------------*/ void RectClipPS(float x,float y,float dx,float dy) { printf("%.3f %.3f %.3f %.3f RCLIP\n",dx,dy,x,y); } void InitClipPS() { printf("initclip\n"); } /*==========================================================================*/ /* Circle drawing routines */ /*==========================================================================*/ /*--------------------------------------------------------------------------*/ /* Draw a circle with center point (x,y) and radius rad. */ /*--------------------------------------------------------------------------*/ void CirclePS(float x,float y,float rad) { printf("%.3f %.3f %.3f CI\n",x,y,rad); } /*--------------------------------------------------------------------------*/ /* Draw a circle with center point (x,y) and radius rad. Also fill the */ /* circle with gray shade defined by parameter gray. Parameter Border */ /* defines whether the border is drawn (1) or not (0). */ /*--------------------------------------------------------------------------*/ void FillCirclePS(float x,float y,float rad,float gray,long Border) { printf("%.3f %.3f %.3f %.3f ",gray,x,y,rad); if (Border) printf("CB\n"); else printf("CF\n"); } /*--------------------------------------------------------------------------*/ /* Same as above but the circle is filled with color (red,green,blue) */ /* where red, green and blue are all between 0 and 1. */ /*--------------------------------------------------------------------------*/ void FillColorCirclePS(float x,float y,float rad, float red,float green,float blue,long Border) { printf("%.3f %.3f %.3f %.3f %.3f %.3f ",red,green,blue,x,y,rad); if (Border) printf("CBC\n"); else printf("CFC\n"); } /*==========================================================================*/ /* Plotting various marks */ /*==========================================================================*/ void CrossPS(float x,float y,float length) { printf("%.3f %.3f %.3f CR\n",length,x,y); } void XCrossPS(float x,float y,float length) { printf("%.3f %.3f %.3f CX\n",length,x,y); } void FMILogoPS(float x,float y,float size) { printf("%.3f %.3f %.3f FMILOGO\n",size,x,y); }