postscript generation sets font sizes without considering tk scaling (workaround)
Brought to you by:
ghowlett
blt::graph widget has a simple way to generate a PostScript (EPS, actually) dump of the graph, but defaults the fonts to low-res display-derived sizes. The display DPI needs to be taken into account!
This could be fixed in the code, but until then a simple workaround is to insert the correct scaling command directly into the generated .eps file:
graph .g ...
.g postscript output file.eps
PatchUpEPS file.eps
proc PatchUpEPS { eps_file } {
set fdpi [tk scaling]
# a workaround for a bug in BLT postscript, imperfect but helps
# from: wiki.tcl-lang.org/page/Canvas+postscript+-+text+rendering+bug
set fp [open $eps_file]
set EPStext [regsub "\/SetFont" [read $fp] "\/scalefont \{$fdpi mul scalefont\} bind def\n\n\/SetFont"]
close $fp
set fp [open $eps_file "w"]; puts $fp $EPStext; close $fp
missing above
Last edit: Edward Sternin 2020-03-10
On 3/10/20 5:20 PM, Edward Sternin wrote:
What is your basic goal when you generate PostScript of a graph?
Is your goal to get a reasonable facsimile of what's on the screen? That
is, display approximately the graph as it is on the screen? The
PostScript could also be scaled to fit on a standard piece of paper, but
it would still look like the screen version. This is what was
implemented in BLT 2.4.
Or is your goal to get (so-called) publication-quality graphics? That
is, a plot that you can immediately embed in your paper. There are
differences between screen and paper. A PostScript printer has much
greater resolution. And many times the plot on the screen is compromised
by available screen size. It really doesn't represent what you want to
see on paper.
At Purdue, the consensus of professors and students was they wanted the
second goal.
Below is a screenshot of a dialog box I created to let users adjust the
settings of the plot displaying the changes in a label (using an
image). When changes are made to the settings in the dialog box, the
corresponding option is set on the cloned graph and the image is snapped
from the graph.
What is your goal?
--gah
dialog.gif
Related
Bugs: #158
I would find it incomprehensible, if the adjustments made on the screen (change the font or its size, or the plotting symbol and its size) did not correspond to the changes made in the postscript output. In general, PNG snapshots in BLT 2.4 and 3.0 work in exactly that way.
The problem with PostScript generation showed up only when I started using high-DPI screens. While I can insist on points (1/72in on screen) being used to define the size of the on-screen buttons and menus in Tk, inside BLT it seems this setting is ignored and the size is interpreted as pixels. Hence a "size 11" font remains an 11-pixel font on the full-page PostScript drawing (actually, I set it to 7i x 5i), which makes it impossibly small. Worse than that, it seems like the font metrics get messed up, so small-size characters are interspersed by large spaces, making for very odd-looking figures. If this was intended to be "publication-quality", it is most definitely not it.
Here's an example of five graphs: a screenshot of what I see in a BLT canvas, then the .png and .eps dumps, then the .eps corrected as described above. This was done on my desktop where
[tk scaling]returns only about 1.33, so the effect is not that impressive. But on my Chromebook, it returns almost 3, and that makes the .eps unusable.EDIT: typos corrected
Last edit: Edward Sternin 2020-03-12
I guess to answer your question explicitly, my goal is to have the relative sizes of the objects be the same, whether they are on the screen or in a PostScript file, at a much higher resolution.
By the way, the plotting symbol and other decorations on the plot must also be scaled by the
[tk scaling]factor when generating PostScript. Some of it could be done in tcl, so the truly critical part about PostScript is the fonts because one cannot correct it within tcl.Perhaps the best way to specify sizes of things on the graph could be not in absolute terms (pixels or points) but, say, % of the graph width. This approach would scale predictably across modes of viewing the same graph (low-res screen, hi-res screen, paper). Controlling the PostScript image size in inches, and specifying object size in points (i.e. fractions of inches) would accomplish the same in two steps. Specifying the symbol size in % of the graph width would allow rescaling adjustments in one step, a true vector graphics approach.
Last edit: Edward Sternin 2020-03-12