[comp.lang.postscript] PostScript utility for font changes, subscripts within string

mrwittma@phoenix.Princeton.EDU (Martin R. Wittmann) (12/19/89)

Does anyone have or know of a set of PostScript procedures which will
print strings which have encoded within them font changes, superscript
and subscripts, etc., and also calculate the lengths of same?

I am writing some PS plotting routines (and modifying those from the S
language) and wish to be able to label the plots with strings containing
Greek symbols, simple super- and subscripts, etc.  It would be easiest
to do this by sending a single string for the label, with the font
changes and super/subscript encoded within it in some fashion.  The
string would be printed with a substitute for the "show" operator which
would properly decode the string.  I also need to be able to calculate
the string width, so that I can center or right justify it.

I have written a simple set of procedures to do all of the above EXCEPT
calculate the string width, but they are by no means elegant, and I was
wondering if anyone has worked this out before.

Thanks.  Please email replies!

Martin Wittmann			mrwittma@phoenix.princeton.edu

batcheldern@hannah.enet.dec.com (Ned Batchelder) (12/21/89)

Rather than limit yourself to the idea that your data representation must be
a string, which is inert and must be decoded, pick a more convenient
representation for your text-with-font-changes. I've done something like
this and it was very easy.

Text is represented as a procedure which when executed shows the text. For 
example:

	/tr /Times-Roman findfont def		% Base font
	/rm tr 10 scalefont def			% font for Roman
	/sc tr [ 8 0 0 8.5 0 0 ] makefont def	% font for small caps

	{ rm setfont (P) show
	  sc setfont (OST) show
	  rm setfont (S) show
	  sc setfont (CRIPT) show }

The procedure at the end is the representation of the caps/small-caps form
of the word "PostScript". Now to show this text, you define "textshow":

	/textshow /exec load def

To compute the width of the text, you have to be a little trickier. Nulldevice
comes in very handy here:

	/textwidth {
		gsave nulldevice
		0 0 moveto
		textshow
		currentpoint
		grestore
	} def

Then you can center text:

	/textcentershow {
		dup textwidth pop
		-2 div 0 rmoveto
		textshow
	} def

Etc.

It isn't a very compact representation, but it sounds like your application 
won't be doing much text anyway, and it can be made compacter by the proper
definition of procedure to use within the text itself.

[I typed this in off the top of my head, so there may be errors, but the ideas
are sound: I've used it and it works.]

Ned Batchelder, Digital Equipment Corp., BatchelderN@Hannah.enet.DEC.com

woody@rpp386.cactus.org (Woodrow Baker) (12/22/89)

The way to accomplish what you asked for (embedded control characters)
in your text string, is to parse the textstring line at a time, looking for
characters.  Don Lancaster has a thing he calls "gonzo justify" that does
exactly that.
Basically, you do a read of the currentfile, and convert the integer to
a string character.  The you test the string character to see if a procedure
by that name is known.  You can then load teh procedure and execute it, else
you image the character.  There was an emulator pshed by adobe at one time
that was a simple diablo emulator.  It worked this way.  Basically, you
had a dctionary called ESC  (defined by     the number 27.  The
dictionary then had procedures, each of which had an integer for the
name, and each  integer had an entry or procedure.  each procedure
in the  escape dictionary was named for a letter, i.e.  for say
<ESC> T   where t was say goto bold, you would have an entry
in the ESC dictionary with a name of  84  (the decimal code for T or so I
think), and a prcdr that did what was needed to go to bold.
Cheers
Woody
p.s. Sorry for the misspellings, I still haven't masterd VI, so I can't
go change them..