Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
299 views
in Technique[技术] by (71.8m points)

ghostscript - How to determine string height in PostScript?

I need to determine the height of a string (in given scale and font) in postscript.

/Helvetic-Oblique findfont
10 scalefont
setfont
10 10 1 0 360 arc fill
10 10 moveto (test) dup stringwidth pop 2 div neg 0 rmoveto show

will print test centered horizontally (but not yet vertically) at (10,10). (to see this, I also show a small circle at 10,10). I also need to determine the string height to center the text vertically as well, but I cant find a function for it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Are you familiar with the PostScript code you're using? Or is it just blindly copied and pasted from someplace? If you want to understand it, you should google for "PostScript Language Reference" or "Red Book" or "PLRM". These resources are available as PDFs from Adobe.

Your PostScript snippet uses the following steps:

  1. (test) places the string "test" on the top of the stack.
  2. dup duplicates the topmost item on the stack. (You'll now have the string twice on the stack.)
  3. stringwidth. After this operator is executed, the topmost "test" string will have been consumed, and two values will have been added to the stack instead: the string's height (topmost) and the string's width (second from top). [Update: Actually, "string's height" isn't entirely correct -- it's rather the vertical offset of the current point after finishing to draw the string...]
  4. Next, you use pop. This simply deletes the topmost value on the stack. Now only string's width remains on the top of the stack.
  5. 2 div divides that value by 2 and leaves the result (half the stringwidth).
  6. neg negates the topmost value on the stack. Now that negative value is topmost on the stack.
  7. 0 places the value "0" on top of the stack.
  8. rmoveto then consumes the two topmost values on the stack and moves the current point by that distance (half the string's width) to the left.
  9. show consumes the first "test" string that remained all the time at the bottom of the stack and "shows" it.

So what would work to take into account the string's height? Try as your last line:

200 700 moveto (test) dup true charpath pathbbox 3 -1 roll sub 2 div neg 3 1 roll sub 2 div exch 200 700 moveto rmoveto show"

To understand my changes look up the meaning of charpath, div, exch, pathbbox, roll and sub operators in The Red Book.

This command uses Ghostscript to create a PDF file on Windows from the code (easier to view and check results):

 gswin32c.exe ^
      -o my.pdf ^
      -sDEVICE=pdfwrite ^
      -c "/Helvetic-Oblique findfont 10 scalefont setfont 200 700 1 0 360 arc fill 0 0 moveto (test test) dup true charpath pathbbox 3 -1 roll sub 2 div neg 3 1 roll sub 2 div exch 200 700 moveto rmoveto show"

On Linux use:

 gs 
      -o my.pdf 
      -sDEVICE=pdfwrite 
      -c "/Helvetic-Oblique findfont 10 scalefont setfont 200 700 1 0 360 arc fill 0 0 moveto (test test) dup true charpath pathbbox 3 -1 roll sub 2 div neg 3 1 roll sub 2 div exch 200 700 moveto rmoveto show"

Better readable forms are:

  gswin32c ^
     -o my.pdf ^
     -sDEVICE=pdfwrite ^
     -c "/Helvetic-Oblique findfont 10 scalefont setfont" ^
     -c "200 700 1 0 360 arc fill 0 0 moveto (test test) dup" ^
     -c "true charpath pathbbox 3 -1 roll sub 2 div neg 3 1 roll" ^
     -c "sub 2 div exch 200 700 moveto rmoveto show"

and

  gs 
     -o my.pdf 
     -sDEVICE=pdfwrite 
     -c "/Helvetic-Oblique findfont 10 scalefont setfont" 
     -c "200 700 1 0 360 arc fill 0 0 moveto (test test) dup" 
     -c "true charpath pathbbox 3 -1 roll sub 2 div neg 3 1 roll" 
     -c "sub 2 div exch 200 700 moveto rmoveto show"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...