The outage for Sunday 24th November has been cancelled.
Bioplib
Protein Structure C Library
 All Data Structures Files Functions Variables Typedefs Macros Pages
ps.c
Go to the documentation of this file.
1 /************************************************************************/
2 /**
3 
4  \file ps.c
5 
6  \version V1.5
7  \date 07.07.14
8  \brief PostScript plotting routines
9 
10  \copyright (c) UCL / Dr. Andrew C. R. Martin 1993-2014
11  \author Dr. Andrew C. R. Martin
12  \par
13  Institute of Structural & Molecular Biology,
14  University College London,
15  Gower Street,
16  London.
17  WC1E 6BT.
18  \par
19  andrew@bioinf.org.uk
20  andrew.martin@ucl.ac.uk
21 
22 **************************************************************************
23 
24  This code is NOT IN THE PUBLIC DOMAIN, but it may be copied
25  according to the conditions laid out in the accompanying file
26  COPYING.DOC.
27 
28  The code may be modified as required, but any modifications must be
29  documented so that the person responsible can be identified.
30 
31  The code may not be sold commercially or included as part of a
32  commercial product except as described in the file COPYING.DOC.
33 
34 **************************************************************************
35 
36  Description:
37  ============
38 
39  These routines supply rudimentry PostScript support with
40  simple commands from C.
41 
42  This version does not support EPSF.
43 
44 **************************************************************************
45 
46  Usage:
47  ======
48  You should #include "ps.h" in your program and assign
49  values to the global variables PSxpicsize,PSypicsize,PSxoffset
50  and PSyoffset. All these values are in inches. Your plot should
51  then run between 0.0 and 1.0 (you need to look after scaling
52  to fit within these boundaries yourself).
53 
54  Start with a call to PSInit which will set up the scaling and other
55  routines within the PostScript program.
56 
57 **************************************************************************
58 
59  Revision History:
60  =================
61 - V1.0 22.11.90 Original
62 - V1.1 06.07.93 Modified for book
63 - V1.2 27.07.93 Changed I/O precision to double
64 - V1.4 22.06.94 The file pointer is now global rather than static
65 - V1.5 07.07.14 Use bl prefix for functions By: CTP
66 
67 *************************************************************************/
68 /* Defines and macros
69 */
70 #define MAXBUFF 160
71 #define _PS_MAIN
72 
73 /************************************************************************/
74 /* Doxygen
75  -------
76  #GROUP Graphics
77  #SUBGROUP Postscript
78  #FUNCTION blPSInit()
79  Initialises the file writing the Prologue. The filename and creator
80  are written into the Prologue and EPSFxoff and EPSFyoff are used to
81  calculate the bounding box size for EPSF plots.
82 
83  #FUNCTION blPSThick()
84  Set the line thickness
85 
86  #FUNCTION blPSMove()
87  Move to X,Y
88 
89  #FUNCTION blPSDraw()
90  Draw to X,Y
91 
92  #FUNCTION blPSSetDash()
93  Set a line dash pattern which must be supplied as a string
94 
95  #FUNCTION blPSClearDash()
96  Clear the dash pattern to a full line
97 
98  #FUNCTION blPSStroke()
99  Actually draw what you've just done onto the paper
100 
101  #FUNCTION blPSFont()
102  Set the font and size
103 
104  #FUNCTION blPSLText()
105  Left justify text
106 
107  #FUNCTION blPSCBText()
108  Centers a piece of text with X,Y being the Coords of the BOTTOM centre
109  point
110 
111  #FUNCTION blPSROffText()
112  Right justify text with offset in device coordinates (points).
113 
114  #FUNCTION blPSLCText()
115  Left justify text, centred on Y
116 
117  #FUNCTION blPSCTText()
118  Centers a piece of text with X,Y being the Coords of the TOP centre
119  point
120 
121  #FUNCTION blPSVText()
122  Write vertical text centred on x,y offset back along x by the size of
123  label and by xoff in pts. Used, for example, to title the y-axis of
124  a graph. The `label' specification is used to calculate an amount by
125  which to move the text back. Typically this would be the longest data
126  label on the graph's Y-axis.
127 
128  #FUNCTION blPSShowText()
129  Displays text, processing it first if any control codes are found. Used
130  by the various text positioning routines.
131 
132  #FUNCTION blPSEnd()
133  End of page
134 
135  #FUNCTION blPSCorrectCase()
136  Goes through a fontname and fixes case to match the required standard.
137 */
138 /************************************************************************/
139 /* Includes
140 */
141 #include <stdio.h>
142 #include <string.h>
143 #include <math.h>
144 #include <time.h>
145 #include <ctype.h>
146 
147 #include "MathType.h"
148 #include "SysDefs.h"
149 
150 #include "plotting.h"
151 #include "general.h"
152 #include "ps.h"
153 
154 /************************************************************************/
155 /* Globals
156 */
157 static char sPSBuff[200];
158 static REAL sTextHeight = 10.0;
159 
160 /************************************************************************/
161 /* Prototypes
162 */
163 
164 /************************************************************************/
165 /*>BOOL blPSInit(char *FName, char *creator, char *AltFont)
166  --------------------------------------------------------
167 *//**
168 
169  \param[in] *FName PostScript filename
170  \param[in] *creator Creator string
171  \param[in] *AltFont Alternate font (normall greek style)
172  \return Success?
173 
174  Initialises the file writing the Prologue. The filename and creator
175  are written into the Prologue and EPSFxoff and EPSFyoff are used to
176  calculate the bounding box size for EPSF plots.
177 
178 - 08.05.92 Added definitions of raise, lower and greek. New parameter
179  to specify name of alternate font.
180 - 23.06.92 Padded BoundingBox with spaces and setting of PSXMin, etc.
181 - 26.07.92 Correctly divide EPSFxoff and EPSFyoff by 72 when writing
182  offsets in prologue.
183 - 15.09.92 Added support for Amiga reencoding. Starting dimensions
184  for BoundingBox set to dimensions set by Paper.
185 - 06.07.93 Opens the file
186 - 27.07.93 Floating point precision -> double
187 - 07.07.14 Use bl prefix for functions By: CTP
188 */
189 BOOL blPSInit(char *FName,
190  char *creator,
191  char *AltFont)
192 {
193  struct tm *time_struc;
194  time_t time_value;
195 
196  if((gPSFile = fopen(FName,"w")) == NULL) return(FALSE);
197 
198  /* Header information */
199  fputs("%!PS-Adobe-2.0\n",gPSFile);
200  fputs("%%Creator: ",gPSFile);
201  fputs(creator,gPSFile);
202  fputs("\n",gPSFile);
203  fputs("%%For: (Andrew Martin Support Library)\n",gPSFile);
204  sprintf(sPSBuff,"%%%%Title: (%s)\n",FName);
205  fputs(sPSBuff,gPSFile);
206  time(&time_value);
207  time_struc = localtime(&time_value);
208  sprintf(sPSBuff,"%%%%CreationDate: %s",asctime(time_struc));
209  fputs(sPSBuff,gPSFile);
210  fputs("%%Pages: 1\n",gPSFile);
211  fputs("%%DocumentFonts: atend\n",gPSFile);
212 
213  fputs("%%EndComments\n",gPSFile);
214 
215  fputs("%%---------------Prologue-----------------\n",gPSFile);
216 
217  sprintf(sPSBuff,"/xpicsize %7.4f def\n",PSxpicsize);
218  fputs(sPSBuff,gPSFile);
219  sprintf(sPSBuff,"/ypicsize %7.4f def\n",PSypicsize);
220  fputs(sPSBuff,gPSFile);
221 
222  sprintf(sPSBuff,"/xoffset %7.4f def\n",PSxoffset);
223  fputs(sPSBuff,gPSFile);
224  sprintf(sPSBuff,"/yoffset %7.4f def\n",PSyoffset);
225  fputs(sPSBuff,gPSFile);
226 
227  fputs("/xscale { xpicsize 72 mul mul } def\n",gPSFile);
228  fputs("/yscale { ypicsize 72 mul mul } def\n",gPSFile);
229  fputs("/xunits { xscale xoffset 72 mul add } def\n",gPSFile);
230  fputs("/yunits { yscale yoffset 72 mul add } def\n\n",gPSFile);
231 
232  /* A routine to set the font */
233  fputs("/font\n",gPSFile);
234  fputs("{\n",gPSFile);
235  fputs(" findfont exch scalefont setfont\n",gPSFile);
236  fputs("}def\n",gPSFile);
237 
238  /* The RJust procedure */
239  fputs("/rightJustifyText\n",gPSFile);
240  fputs("{ /RightColumn exch def\n",gPSFile);
241  fputs(" dup\n",gPSFile);
242  fputs(" stringwidth pop\n",gPSFile);
243  fputs(" RightColumn exch sub\n",gPSFile);
244  fputs(" Line moveto\n",gPSFile);
245  fputs(" show\n",gPSFile);
246  fputs("} def\n",gPSFile);
247 
248  /* The circle procedure */
249  fputs("/circle\n",gPSFile);
250  fputs("{ 0 360 arc\n",gPSFile);
251  fputs("} def\n",gPSFile);
252 
253  /* The raise procedure */
254  fputs("/raise\n",gPSFile);
255  fputs("{ sTextHeight 1.5 div FontName font\n",gPSFile);
256  fputs(" 0 sTextHeight 2 div rmoveto\n",gPSFile);
257  fputs(" show\n",gPSFile);
258  fputs(" 0 sTextHeight 2 div neg rmoveto\n",gPSFile);
259  fputs(" sTextHeight FontName font\n",gPSFile);
260  fputs("} def\n",gPSFile);
261 
262  /* The lower procedure */
263  fputs("/lower\n",gPSFile);
264  fputs("{ sTextHeight 1.5 div FontName font\n",gPSFile);
265  fputs(" 0 sTextHeight 4 div neg rmoveto\n",gPSFile);
266  fputs(" show\n",gPSFile);
267  fputs(" 0 sTextHeight 4 div rmoveto\n",gPSFile);
268  fputs(" sTextHeight FontName font\n",gPSFile);
269  fputs("} def\n",gPSFile);
270 
271  /* The greek procedure */
272  fputs("/greek\n",gPSFile);
273  fputs("{ AltFontName findfont sTextHeight scalefont setfont\n",
274  gPSFile);
275  fputs(" show\n",gPSFile);
276  fputs(" sTextHeight FontName font\n",gPSFile);
277  fputs("} def\n",gPSFile);
278 
279  /* Define the alternate font for Greek */
280  sprintf(sPSBuff,"/AltFontName /%s def\n",AltFont);
281  fputs(sPSBuff,gPSFile);
282 
283  /* The max procedure */
284  fputs("/max\n",gPSFile);
285  fputs("{ 2 copy\n",gPSFile);
286  fputs(" lt {exch} if\n",gPSFile);
287  fputs(" pop\n",gPSFile);
288  fputs("} def\n",gPSFile);
289 
290  fputs("%%EndProlog\n",gPSFile);
291  fputs("%%Page 1 1\n",gPSFile);
292  fputs("%%---------------Script-----------------\n",gPSFile);
293 
294  return(TRUE);
295 }
296 
297 /************************************************************************/
298 /*>void blPSThick(REAL thickness)
299  ------------------------------
300 *//**
301 
302  \param[in] thickness Line thickness
303 
304  Set the line thickness
305 
306 - 27.07.93 Floating point precision -> double
307 - 07.07.14 Use bl prefix for functions By: CTP
308 */
309 void blPSThick(REAL thickness)
310 {
311  sprintf(sPSBuff,"%f setlinewidth\n",thickness);
312  fputs(sPSBuff,gPSFile);
313 }
314 
315 /************************************************************************/
316 /*>void blPSMove(REAL X, REAL Y)
317  -----------------------------
318 *//**
319 
320  \param[in] X X coordinate
321  \param[in] Y Y coordinate
322 
323  Move to X,Y
324 
325 - 27.07.93 Floating point precision -> double
326 - 07.07.14 Use bl prefix for functions By: CTP
327 */
328 void blPSMove(REAL X,
329  REAL Y)
330 {
331  sprintf(sPSBuff,"%7.4f xunits %7.4f yunits moveto\n",X,Y);
332  fputs(sPSBuff,gPSFile);
333 }
334 
335 /************************************************************************/
336 /*>void blPSDraw(REAL X, REAL Y)
337  -----------------------------
338 *//**
339 
340  \param[in] X X coordinate
341  \param[in] Y Y coordinate
342 
343  Draw to X,Y
344 
345 - 27.07.93 Floating point precision -> double
346 - 07.07.14 Use bl prefix for functions By: CTP
347 */
348 void blPSDraw(REAL X,
349  REAL Y)
350 {
351  sprintf(sPSBuff,"%7.4f xunits %7.4f yunits lineto\n",X,Y);
352  fputs(sPSBuff,gPSFile);
353 }
354 
355 /************************************************************************/
356 /*>void blPSSetDash(char *linepatt)
357  --------------------------------
358 *//**
359 
360  \param[in] *linepatt Line pattern (a string of numbers)
361 
362  Set a line dash pattern which must be supplied as a string
363 
364 - 07.07.14 Use bl prefix for functions By: CTP
365 */
366 void blPSSetDash(char *linepatt)
367 {
368  sprintf(sPSBuff,"[%s] 0 setdash\n",linepatt);
369  fputs(sPSBuff,gPSFile);
370 }
371 
372 /************************************************************************/
373 /*>void blPSClearDash(void)
374  ------------------------
375 *//**
376 
377  Clear the dash pattern to a full line
378 
379 - 30.06.92 Removed redundant sprintf()'s
380 - 07.07.14 Use bl prefix for functions By: CTP
381 */
382 void blPSClearDash(void)
383 {
384  fputs("[] 0 setdash\n",gPSFile);
385 }
386 
387 /************************************************************************/
388 /*>void blPSStroke(void)
389  ---------------------
390 *//**
391 
392  Actually draw what you've just done onto the paper
393 
394 - 30.06.92 Removed redundant sprintf()'s
395 - 07.07.14 Use bl prefix for functions By: CTP
396 */
397 void blPSStroke(void)
398 {
399  fputs("stroke\n",gPSFile);
400 }
401 
402 /************************************************************************/
403 /*>void blPSFont(char *fontname, REAL size)
404  ----------------------------------------
405 *//**
406 
407  \param[in] *fontname Font to set
408  \param[in] size Point size of font
409 
410  Set the font and size
411 - 08.05.92 Changed to support raise and lower
412 - 23.06.92 Set sTextHeight
413 - 15.09.92 Changed to support Amiga reencoding
414 - 06.07.93 Removed Amiga reecncoding for general distribution
415 - 27.07.93 Floating point precision -> double
416 - 07.07.14 Use bl prefix for functions By: CTP
417 */
418 void blPSFont(char *fontname,
419  REAL size)
420 {
421  char font[80];
422 
423  blStringToUpper(fontname,font);
424 
425  if(!strncmp(font,"TIMES",5))
426  {
427  if(font[5] != '-')
428  strcpy(fontname+5,"-Roman\0");
429  }
430 
431  sprintf(sPSBuff,"/FontName /%s def\n",blPSCorrectCase(fontname));
432  fputs(sPSBuff,gPSFile);
433  sprintf(sPSBuff,"/sTextHeight %f def\n",size);
434  fputs(sPSBuff,gPSFile);
435 
436  fputs("sTextHeight FontName font\n",gPSFile);
437 
438  sTextHeight = size;
439 }
440 
441 /************************************************************************/
442 /*>void blPSLText(REAL X, REAL Y, char *label)
443  -------------------------------------------
444 *//**
445 
446  \param[in] X X coordinate
447  \param[in] Y Y coordinate
448  \param[in] *label Text to be printed
449 
450  Left justify text
451 
452 - 30.06.92 Removed redundant sprintf()'s
453 - 15.09.92 Multiply string width by 0.65
454 - 27.07.93 Floating point precision -> double
455 - 07.07.14 Use bl prefix for functions By: CTP
456 */
458  REAL Y,
459  char *label)
460 {
461  /* Define the current line and position */
462  sprintf(sPSBuff,"%7.4f xunits\n",X);
463  fputs(sPSBuff,gPSFile);
464  sprintf(sPSBuff,"/Line %7.4f yunits def\n",Y);
465  fputs(sPSBuff,gPSFile);
466  fputs("Line moveto\n",gPSFile);
467  /* Put the text into the file and display */
468  blPSShowText(label);
469 }
470 
471 /************************************************************************/
472 /*>void blPSCBText(REAL X, REAL Y, REAL Offset, char *label)
473  ---------------------------------------------------------
474 *//**
475 
476  \param[in] X X coordinate
477  \param[in] Y Y coordinate
478  \param[in] Offset Y offset - multiple of font height. Moves up
479  by this quantity
480  \param[in] *label Text to be printed
481 
482  Centers a piece of text with X,Y being the Coords of the BOTTOM centre
483  point
484 
485 - 30.06.92 Removed redundant sprintf()'s
486 - 15.09.92 Multiply string width by 0.65
487 - 27.07.93 Floating point precision -> double
488 - 07.07.14 Use bl prefix for functions By: CTP
489 */
491  REAL Y,
492  REAL Offset,
493  char *label)
494 {
495  char *buffer;
496 
497  buffer = label;
498  while(*buffer == ' ') buffer++;
499 
500  /* Put the string on the stack */
501  sprintf(sPSBuff,"(%s)\n",blSimplifyText(buffer));
502  fputs(sPSBuff,gPSFile);
503  /* Define the current line */
504  sprintf(sPSBuff,
505  "%7.4f yunits 2 sub /Line exch def\n",Y);
506  fputs(sPSBuff,gPSFile);
507  /* We are now left with label on the stack.
508  Find half its width */
509  fputs("dup stringwidth pop 2 div\n",gPSFile);
510  /* Put the X position on the stack, subtract width/2 */
511  sprintf(sPSBuff,"%7.4f xunits exch sub\n",X);
512  fputs(sPSBuff,gPSFile);
513  /* We are left with the label and correct X on the stack
514  Put Y on, move there and show the text */
515  if (Offset == 0.0)
516  {
517  fputs("Line moveto pop\n",gPSFile);
518  }
519  else
520  {
521  sprintf(sPSBuff,"Line sTextHeight %7.4f mul sub moveto pop\n",
522  Offset);
523  fputs(sPSBuff,gPSFile);
524  }
525  blPSShowText(buffer);
526 }
527 
528 /************************************************************************/
529 /*>void blPSROffText(REAL X, REAL Y, REAL offset, char *label)
530  -----------------------------------------------------------
531 *//**
532 
533  \param[in] X X coordinate
534  \param[in] Y Y coordinate
535  \param[in] offset X offset in points; text moved to the left by
536  this amount
537  \param[in] *label Text to be printed
538 
539  Right justify text with offset in device coordinates (points).
540 
541 - 07.05.92 Original
542 - 30.06.92 Removed use of PSShowText(). This can't be used with the
543  current rightJustifyText
544 - 15.09.92 Multiply string width by 0.65
545 - 27.07.93 Floating point precision -> double
546 - 07.07.14 Use bl prefix for functions By: CTP
547 */
549  REAL Y,
550  REAL offset,
551  char *label)
552 {
553  /* Define the current line */
554  sprintf(sPSBuff,"/Line %7.4f yunits sTextHeight 2 div sub 2 \
555 add def\n",Y);
556  fputs(sPSBuff,gPSFile);
557  /* Put the text into the file */
558  sprintf(sPSBuff,"(%s)\n",label);
559  fputs(sPSBuff,gPSFile);
560  /* Ask to Right Justify */
561  sprintf(sPSBuff,"%7.4f xunits 4 sub %f add rightJustifyText\n",
562  X,offset);
563  fputs(sPSBuff,gPSFile);
564 }
565 
566 /************************************************************************/
567 /*>void blPSLCText(REAL X, REAL Y, char *label)
568  --------------------------------------------
569 *//**
570 
571  \param[in] X X coordinate
572  \param[in] Y Y coordinate
573  \param[in] *label Text to be printed
574 
575  Left justify text, centred on Y
576 
577 - 08.05.92 Original
578 - 30.06.92 Removed redundant sprintf()'s
579 - 15.09.92 Multiply string width by 0.65
580 - 27.07.93 Floating point precision -> double
581 - 07.07.14 Use bl prefix for functions By: CTP
582 */
584  REAL Y,
585  char *label)
586 {
587  /* Define the current line and position */
588  sprintf(sPSBuff,"%7.4f xunits\n",X);
589  fputs(sPSBuff,gPSFile);
590  sprintf(sPSBuff,"/Line %7.4f yunits sTextHeight 2 div sub 2 \
591 add def\n",Y);
592  fputs(sPSBuff,gPSFile);
593  fputs("Line moveto\n",gPSFile);
594  /* Put the text into the file and display */
595  blPSShowText(label);
596 }
597 
598 /************************************************************************/
599 /*>void blPSCTText(REAL X, REAL Y, REAL Offset, char *label)
600  ---------------------------------------------------------
601 *//**
602 
603  \param[in] X X coordinate
604  \param[in] Y Y coordinate
605  \param[in] Offset Y offset in points. Moves down by this quantity
606  \param[in] *label Text to be printed
607 
608  Centers a piece of text with X,Y being the Coords of the TOP centre
609  point
610 
611 - 26.06.92 Changed strlen() to use SimplifyText()
612 - 30.06.92 Removed redundant sprintf()'s
613 - 01.07.92 Changed Offset to be in pts rather than a multiplier of
614  font size.
615 - 27.07.92 Changed update limits to account better for descenders.
616 - 15.09.92 Multiply string width by 0.65
617 - 27.07.93 Floating point precision -> double
618 - 07.07.14 Use bl prefix for functions By: CTP
619 */
621  REAL Y,
622  REAL Offset,
623  char *label)
624 {
625  char *buffer;
626 
627  buffer = label;
628  while(*buffer == ' ') buffer++;
629 
630  /* Put the string on the stack */
631  sprintf(sPSBuff,"(%s)\n",blSimplifyText(buffer));
632  fputs(sPSBuff,gPSFile);
633  /* Define the current line */
634  sprintf(sPSBuff,
635  "sTextHeight %7.4f yunits exch sub /Line exch def\n",Y);
636  fputs(sPSBuff,gPSFile);
637  /* We are now left with label on the stack.
638  Find half its width */
639  sprintf(sPSBuff,"dup stringwidth pop 2 div\n");
640  fputs(sPSBuff,gPSFile);
641  /* Put the X position on the stack, subtract width/2 */
642  sprintf(sPSBuff,"%7.4f xunits exch sub\n",X);
643  fputs(sPSBuff,gPSFile);
644  /* We are left with the label and correct X on the stack
645  Put Y on, move there and show the text */
646  if (Offset == 0.0)
647  {
648  fputs("Line moveto pop\n",gPSFile);
649  }
650  else
651  {
652  sprintf(sPSBuff,"Line %7.4f add moveto pop\n",Offset);
653  fputs(sPSBuff,gPSFile);
654  }
655  blPSShowText(buffer);
656 }
657 
658 
659 /************************************************************************/
660 /*>void blPSVText(REAL x, REAL y, REAL xoff,
661  char *text, char *font, REAL size,
662  char *label, char *lfont, REAL lsize)
663  -------------------------------------------------------
664 *//**
665 
666  \param[in] x X coordinate (in data units)
667  \param[in] y Y coordinate (in data units)
668  \param[in] xoff X-offset in pts
669  \param[in] *text Text to be written
670  \param[in] *font Font in which to write it
671  \param[in] size Size of font
672  \param[in] *label Label to be used to calc x offset
673  \param[in] *lfont Font of this label
674  \param[in] lsize Size of this label
675 
676  Write vertical text centred on x,y offset back along x by the size of
677  label and by xoff in pts. Used, for example, to title the y-axis of
678  a graph. The `label' specification is used to calculate an amount by
679  which to move the text back. Typically this would be the longest data
680  label on the graph's Y-axis.
681 
682 - 08.05.92 Original
683 - 30.06.92 Removed redundant sprintf()'s
684 - 15.09.92 Multiply string width by 0.65
685 - 27.07.93 Floating point precision -> double
686 - 07.07.14 Use bl prefix for functions By: CTP
687 */
688 void blPSVText(REAL x, /* Data coord position (to be offset) */
689  REAL y, /* Data coord position */
690  REAL xoff, /* X-offset in pts */
691  char *text, /* Text to be written */
692  char *font, /* Font in which to write it */
693  REAL size, /* Size of font */
694  char *label, /* Label to be used to calc x offset */
695  char *lfont, /* Font of this label */
696  REAL lsize) /* Size of this label */
697 {
698  /* Put the text on the stack */
699  sprintf(sPSBuff,"(%s) dup\n",blSimplifyText(text));
700  fputs(sPSBuff,gPSFile);
701 
702  /* Find the length of the string/2 */
703  fputs("stringwidth pop 2 div\n",gPSFile);
704 
705  /* Do specified y-pos minus strlen/2 */
706  sprintf(sPSBuff,"%7.4g yunits exch sub\n",y);
707  fputs(sPSBuff,gPSFile);
708 
709  /* Set font to the offset label font */
710  blPSFont(lfont, lsize);
711 
712  /* Calculate the x-offset */
713  sprintf(sPSBuff,"%7.4g xunits (%s) stringwidth pop sub 5 sub %f \
714 add exch moveto\n",x,label,xoff);
715  fputs(sPSBuff,gPSFile);
716 
717  /* Set font back */
718  blPSFont(font, size);
719 
720  /* Display the actual text */
721  fputs("pop 90 rotate ",gPSFile);
722  blPSShowText(text);
723  fputs(" -90 rotate\n",gPSFile);
724 }
725 
726 /************************************************************************/
727 /*>void blPSShowText(char *text)
728  -----------------------------
729 *//**
730 
731  \param[in] *text Text to be written
732 
733  Displays text, processing it first if any control codes are found. Used
734  by the various text positioning routines.
735 
736 - 08.05.92 Original
737 - 07.07.14 Use bl prefix for functions By: CTP
738 */
739 void blPSShowText(char *text)
740 {
741  char buffer[MAXBUFF];
742  int i, j;
743 
744  /* Walk along the string */
745  for(i=0, j=0; i<strlen(text) && j<MAXBUFF-1; i++)
746  {
747  switch(text[i])
748  {
749  case '\\': /* Should interpret next character as Greek */
750  /* Finish the current string */
751  if(j)
752  {
753  buffer[j] = '\0';
754  sprintf(sPSBuff,"(%s) show ",buffer);
755  fputs(sPSBuff,gPSFile);
756  j = 0;
757  }
758  /* Output the next character as Greek */
759  sprintf(sPSBuff,"(%c) greek ",text[++i]);
760  fputs(sPSBuff,gPSFile);
761  break;
762  case '^': /* Should raise next character */
763  /* Finish the current string */
764  if(j)
765  {
766  buffer[j] = '\0';
767  sprintf(sPSBuff,"(%s) show ",buffer);
768  fputs(sPSBuff,gPSFile);
769  j = 0;
770  }
771  /* If necessary build string */
772  if(text[++i] == '{')
773  while(text[++i] != '}' && text[i] != '\0' && j<MAXBUFF-1)
774  buffer[j++] = text[i];
775  else
776  buffer[j++] = text[i];
777  /* Output raised string */
778  if(j)
779  {
780  buffer[j] = '\0';
781  sprintf(sPSBuff,"(%s) raise ",buffer);
782  fputs(sPSBuff,gPSFile);
783  j = 0;
784  }
785  break;
786  case '_': /* Should lower next character */
787  /* Finish the current string */
788  if(j)
789  {
790  buffer[j] = '\0';
791  sprintf(sPSBuff,"(%s) show ",buffer);
792  fputs(sPSBuff,gPSFile);
793  j = 0;
794  }
795  /* If necessary build string */
796  if(text[++i] == '{')
797  while(text[++i] != '}' && text[i] != '\0' && j<MAXBUFF-1)
798  buffer[j++] = text[i];
799  else
800  buffer[j++] = text[i];
801  /* Output lowered string */
802  if(j)
803  {
804  buffer[j] = '\0';
805  sprintf(sPSBuff,"(%s) lower ",buffer);
806  fputs(sPSBuff,gPSFile);
807  j = 0;
808  }
809  break;
810  case '(': /* Need to insert a \, before falling through */
811  case ')':
812  buffer[j++] = '\\';
813  default: /* An ordinary character */
814  buffer[j++] = text[i];
815  break;
816  }
817  }
818 
819  if(j)
820  {
821  buffer[j] = '\0';
822  sprintf(sPSBuff,"(%s) show ",buffer);
823  fputs(sPSBuff,gPSFile);
824  j = 0;
825  }
826 
827  if(strlen(text)) fputs("\n",gPSFile);
828 }
829 
830 /************************************************************************/
831 /*>void blPSEnd(void)
832  ------------------
833 *//**
834 
835  End of page
836 
837 - 08.05.92 Original
838 - 07.07.14 Use bl prefix for functions By: CTP
839 */
840 void blPSEnd(void)
841 {
842  fputs("showpage\n",gPSFile);
843  fputs("%%Trailer\n",gPSFile);
844 
845  fclose(gPSFile);
846 }
847 
848 /************************************************************************/
849 /*>char *blPSCorrectCase(char *font)
850  ---------------------------------
851 *//**
852 
853  \param[in] *font Input fontname
854  \return Case-fixed fontname
855 
856  Goes through a fontname and fixes case to match the required standard.
857 
858 - 08.05.92 Original
859 - 07.07.14 Use bl prefix for functions By: CTP
860 */
861 char *blPSCorrectCase(char *font)
862 {
863  int i;
864  /* Set the first character to UC */
865  font[0] = toupper(font[0]);
866  /* Set everything else to lower */
867  for(i=1;i<strlen(font);i++)
868  font[i] = tolower(font[i]);
869  /* Now step through and upper the bits which need to be */
870  for(i=1;i<strlen(font);i++)
871  {
872  /* Anything after a - */
873  if(font[i]=='-')
874  font[i+1] = toupper(font[i+1]);
875  /* Start of the word oblique */
876  if(!strncmp(font+i,"oblique",7))
877  font[i] = toupper(font[i]);
878  /* Start of the word italic */
879  if(!strncmp(font+i,"italic",6))
880  font[i] = toupper(font[i]);
881  /* Start of the word roman */
882  if(!strncmp(font+i,"roman",5))
883  font[i] = toupper(font[i]);
884  /* Start of the word bold */
885  if(!strncmp(font+i,"bold",4))
886  font[i] = toupper(font[i]);
887  }
888 
889  return(font);
890 }
891 
void blPSClearDash(void)
Definition: ps.c:382
FILE * gPSFile
void blPSLCText(REAL X, REAL Y, char *label)
Definition: ps.c:583
void blPSEnd(void)
Definition: ps.c:840
REAL PSyoffset
short BOOL
Definition: SysDefs.h:64
Include file for PostScript routine.
void blPSSetDash(char *linepatt)
Definition: ps.c:366
#define NULL
Definition: array2.c:99
char * blPSCorrectCase(char *font)
Definition: ps.c:861
void blStringToUpper(char *string1, char *string2)
void blPSThick(REAL thickness)
Definition: ps.c:309
void blPSFont(char *fontname, REAL size)
Definition: ps.c:418
char * blSimplifyText(char *string)
Definition: plotting.c:915
#define FALSE
Definition: macros.h:223
void blPSLText(REAL X, REAL Y, char *label)
Definition: ps.c:457
void blPSVText(REAL x, REAL y, REAL xoff, char *text, char *font, REAL size, char *label, char *lfont, REAL lsize)
Definition: ps.c:688
Include file for using plotting routines.
void blPSCBText(REAL X, REAL Y, REAL Offset, char *label)
Definition: ps.c:490
double REAL
Definition: MathType.h:67
REAL PSypicsize
#define MAXBUFF
Definition: ps.c:70
void blPSShowText(char *text)
Definition: ps.c:739
REAL PSxoffset
#define TRUE
Definition: macros.h:219
void blPSROffText(REAL X, REAL Y, REAL offset, char *label)
Definition: ps.c:548
void blPSDraw(REAL X, REAL Y)
Definition: ps.c:348
Header file for general purpose routines.
void blPSStroke(void)
Definition: ps.c:397
System-type variable type definitions.
void blPSMove(REAL X, REAL Y)
Definition: ps.c:328
REAL PSxpicsize
BOOL blPSInit(char *FName, char *creator, char *AltFont)
Definition: ps.c:189
void blPSCTText(REAL X, REAL Y, REAL Offset, char *label)
Definition: ps.c:620
Type definitions for maths.