|
From: Allin C. <cot...@wf...> - 2009-02-23 00:44:44
|
Problem: with both the png (libgd) and cairopng terminals, depending on the font selected the gnuplot "key" may overflow the plot data region (even if the key terms are in no way excessive, e.g. n <= 8 characters per term). Example: set term pngcairo font "FreeSans,8" size 680,400 set output 'test.png' set key left top plot x title "PRIME" w lines , \ 2*x title "UNEMP" w lines In the resulting plot, the 'U' of "UNEMP" is vertically bisected by the y axis. The desired result is that all the key text appears within the data area (i.e. to the right of the y axis); and this is achieved if we change the first line of the plot file to (for example) set term pngcairo font "Vera,8" size 680,400 I'd be happy to try to work up a patch for this, but I'm having difficulty figuring out where to start -- i.e., determining where the left limit of the key block is computed, given the selected font. P.S., on further investigation this does not seems to be very terminal-specific: I'm getting the same issue with the pdf, pdfcairo, and 'post eps' terminal types. -- Allin Cottrell Department of Economics Wake Forest University |
|
From: Ethan A M. <merritt@u.washington.edu> - 2009-02-23 01:19:08
|
On Sunday 22 February 2009, Allin Cottrell wrote: > Problem: with both the png (libgd) and cairopng terminals, > depending on the font selected the gnuplot "key" may overflow the > plot data region (even if the key terms are in no way excessive, > e.g. n <= 8 characters per term). Gnuplot does not do any font handling on its own. It leaves this to the individual external devices or libraries. The corresponding drivers are supposed to provide approximate information about the average character width in the fields term->h_char, but the approximation can be pretty terrible depending on what font you pick. And anyhow, at best it contains the estimated width of an "average" character. In your case the titles are in all caps, and these are wider characters than average. So if you think that the png terminals *always* underestimate the font width, then you could multiply term->h_char by some constant everywhere that it is set in the driver. But I find it more likely that some font widths will be underestimated and others will be overestimated, and there is not much we can do about it. In other words, I don't think this is fixable. Not for png, and not for any other terminal unless it is using a monospaced font and correctly reports the corresponding fixed width. This is why there are fudge factors for the key layout, so that you can tweak the layout if the automated estimation is failing. In the example you give, it is sufficient to reserve a little extra width: set key width 2 > Example: > set term pngcairo font "FreeSans,8" size 680,400 > set output 'test.png' > set key left top > plot x title "PRIME" w lines , \ > 2*x title "UNEMP" w lines > > In the resulting plot, the 'U' of "UNEMP" is vertically bisected > by the y axis. The desired result is that all the key text > appears within the data area (i.e. to the right of the y axis); > and this is achieved if we change the first line of the plot file > to (for example) > > set term pngcairo font "Vera,8" size 680,400 > > I'd be happy to try to work up a patch for this, but I'm having > difficulty figuring out where to start -- i.e., determining where > the left limit of the key block is computed, given the selected > font. > > P.S., on further investigation this does not seems to be very > terminal-specific: I'm getting the same issue with the pdf, > pdfcairo, and 'post eps' terminal types. -- Ethan A Merritt |
|
From: <pl...@pi...> - 2009-02-23 08:48:11
|
Ethan A Merritt wrote: > On Sunday 22 February 2009, Allin Cottrell wrote: >> Problem: with both the png (libgd) and cairopng terminals, >> depending on the font selected the gnuplot "key" may overflow the >> plot data region (even if the key terms are in no way excessive, >> e.g. n <= 8 characters per term). > > Gnuplot does not do any font handling on its own. It leaves this > to the individual external devices or libraries. The corresponding > drivers are supposed to provide approximate information about the > average character width in the fields term->h_char, but the > approximation can be pretty terrible depending on what font you pick. > And anyhow, at best it contains the estimated width of an "average" > character. In your case the titles are in all caps, and these are > wider characters than average. > > So if you think that the png terminals *always* underestimate the > font width, then you could multiply term->h_char by some constant > everywhere that it is set in the driver. But I find it more likely > that some font widths will be underestimated and others will be > overestimated, and there is not much we can do about it. > > In other words, I don't think this is fixable. > Not for png, and not for any other terminal unless it is using a > monospaced font and correctly reports the corresponding fixed width. > > This is why there are fudge factors for the key layout, so that you > can tweak the layout if the automated estimation is failing. > In the example you give, it is sufficient to reserve a little extra width: > > set key width 2 > Hi, that gives some kind of manual work around which is helpful but all this seems rather unsatisfactory in this day and age. Are there really none of these terminals that can correctly return the space needed to render a character string? X11 must surely be able to give that. I'd be a little surprised if cairo can't. A little googling came up with this which , on the face of it , seems to be doing just that in order to produce rendered text for http images. http://www.aeracode.org/2007/12/15/django-and-cairo-rendering-pretty-titles/ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1) context = cairo.Context(surface) context.select_font_face(font, style, weight) context.set_font_size(size) width, height = context.text_extents(text)[2:4] While separating out the rendering detail into different terminals has advantages it should not end up reducing things to a lowest common denominator. If some terminals can correctly calculate text extents it would be nice to use that capability. /Peter. > >> Example: >> set term pngcairo font "FreeSans,8" size 680,400 >> set output 'test.png' >> set key left top >> plot x title "PRIME" w lines , \ >> 2*x title "UNEMP" w lines >> >> In the resulting plot, the 'U' of "UNEMP" is vertically bisected >> by the y axis. The desired result is that all the key text >> appears within the data area (i.e. to the right of the y axis); >> and this is achieved if we change the first line of the plot file >> to (for example) >> >> set term pngcairo font "Vera,8" size 680,400 >> >> I'd be happy to try to work up a patch for this, but I'm having >> difficulty figuring out where to start -- i.e., determining where >> the left limit of the key block is computed, given the selected >> font. >> >> P.S., on further investigation this does not seems to be very >> terminal-specific: I'm getting the same issue with the pdf, >> pdfcairo, and 'post eps' terminal types. > |
|
From: Ethan A M. <merritt@u.washington.edu> - 2009-02-23 16:13:43
|
On Monday 23 February 2009, pl...@pi... wrote: > Ethan A Merritt wrote: > > > > Gnuplot does not do any font handling on its own. It leaves this > > to the individual external devices or libraries. The corresponding > > drivers are supposed to provide approximate information about the > > average character width in the fields term->h_char, but the > > approximation can be pretty terrible depending on what font you pick. > > And anyhow, at best it contains the estimated width of an "average" > > character. In your case the titles are in all caps, and these are > > wider characters than average. > > that gives some kind of manual work around which is helpful but all this > seems rather unsatisfactory in this day and age. Are there really none > of these terminals that can correctly return the space needed to render > a character string? X11 must surely be able to give that. I'd be a > little surprised if cairo can't. Sure. You could write a cairo-based graphics program, or a libgd-based graphics program, that queried the libraries for exact character widths. But gnuplot is not such a program. The core gnuplot code is separate from, and independent of, individual terminal drivers. > While separating out the rendering detail into different terminals has > advantages it should not end up reducing things to a lowest common > denominator. If some terminals can correctly calculate text extents it > would be nice to use that capability. So far as I can see, that would require major restructing of the program. If you want to work on it, I suggest that the first step is to block out what such a restructuring would look like. Remember that some of the most capable terminal drivers, e.g. PostScript and svg, cannot know about font metrics at the time gnuplot is running. How would you take that into account? -- Ethan A Merritt |
|
From: <pl...@pi...> - 2009-02-23 18:14:13
|
Ethan A Merritt wrote: > On Monday 23 February 2009, pl...@pi... wrote: >> Ethan A Merritt wrote: >>> Gnuplot does not do any font handling on its own. It leaves this >>> to the individual external devices or libraries. The corresponding >>> drivers are supposed to provide approximate information about the >>> average character width in the fields term->h_char, but the >>> approximation can be pretty terrible depending on what font you pick. >>> And anyhow, at best it contains the estimated width of an "average" >>> character. In your case the titles are in all caps, and these are >>> wider characters than average. >> that gives some kind of manual work around which is helpful but all this >> seems rather unsatisfactory in this day and age. Are there really none >> of these terminals that can correctly return the space needed to render >> a character string? X11 must surely be able to give that. I'd be a >> little surprised if cairo can't. > > Sure. You could write a cairo-based graphics program, or a libgd-based > graphics program, that queried the libraries for exact character widths. > But gnuplot is not such a program. The core gnuplot code is separate > from, and independent of, individual terminal drivers. So the code snippet I posted could go in the cairopng terminal , others would have simliar code where it can be supported. > >> While separating out the rendering detail into different terminals has >> advantages it should not end up reducing things to a lowest common >> denominator. If some terminals can correctly calculate text extents it >> would be nice to use that capability. > > So far as I can see, that would require major restructing of the program. > If you want to work on it, I suggest that the first step is to block out > what such a restructuring would look like. Remember that some of the > most capable terminal drivers, e.g. PostScript and svg, cannot know about > font metrics at the time gnuplot is running. How would you take that into > account? > Well that's what I meant about not going for lowest common demoninator. It does not make sense to limit all output to monochrome because some terminals can't handle colour. Each terminal's capabilities are known. To take advantage of this capability, instead of relying on h_char and v_char, it would need a new function like term_get_text_extent() . Those that can't handle it return a zero or other flag and the main core code calls the existing output. If a valid text extent is returned it gets used. That does not sound like a major rewrite. Probably a couple of lines in core to clean up key formatting plus the extra function added to the terminal interface. Maybe even svg and ps could provide a better estimation in this context. /Peter. |
|
From: Ethan M. <merritt@u.washington.edu> - 2009-02-23 18:39:25
|
On Monday 23 February 2009 10:14:03 pl...@pi... wrote:
> Ethan A Merritt wrote:
> > On Monday 23 February 2009, pl...@pi... wrote:
> >> Ethan A Merritt wrote:
> >>> Gnuplot does not do any font handling on its own. It leaves this
> >>> to the individual external devices or libraries. The corresponding
> >>> drivers are supposed to provide approximate information about the
> >>> average character width in the fields term->h_char, but the
> >>> approximation can be pretty terrible depending on what font you pick.
> >>> And anyhow, at best it contains the estimated width of an "average"
> >>> character. In your case the titles are in all caps, and these are
> >>> wider characters than average.
> >> that gives some kind of manual work around which is helpful but all this
> >> seems rather unsatisfactory in this day and age. Are there really none
> >> of these terminals that can correctly return the space needed to render
> >> a character string? X11 must surely be able to give that. I'd be a
> >> little surprised if cairo can't.
> >
> > Sure. You could write a cairo-based graphics program, or a libgd-based
> > graphics program, that queried the libraries for exact character widths.
> > But gnuplot is not such a program. The core gnuplot code is separate
> > from, and independent of, individual terminal drivers.
>
> So the code snippet I posted could go in the cairopng terminal , others
> would have simliar code where it can be supported.
Huh?
I don't understand at all.
There is already similar code in various terminal drivers, called when
a new font is selected. For example, this bit from gd.trm:
/* Find approximate character width and height of selected TTF font */
if (png_state.ttffont) {
int brect[8];
char *err;
err = gdImageStringFT(NULL, &brect[0], 0,
png_state.ttffont, (double)png_state.ttfsize,
0.0, 0, 0, "f00000000g");
if (!err) {
term->h_char = .11 * (float)(brect[2] - brect[0]) + 0.5;
term->v_char = 1.1 * (float)(brect[1] - brect[7]) + 0.5;
}
But there is no framework in place for the core code to invoke this for
individual strings, nor make use of the result. You would need to design
such a framework.
> >> While separating out the rendering detail into different terminals has
> >> advantages it should not end up reducing things to a lowest common
> >> denominator. If some terminals can correctly calculate text extents it
> >> would be nice to use that capability.
> >
> > So far as I can see, that would require major restructing of the program.
> > If you want to work on it, I suggest that the first step is to block out
> > what such a restructuring would look like. Remember that some of the
> > most capable terminal drivers, e.g. PostScript and svg, cannot know about
> > font metrics at the time gnuplot is running. How would you take that into
> > account?
> >
>
> Well that's what I meant about not going for lowest common demoninator.
> It does not make sense to limit all output to monochrome because some
> terminals can't handle colour.
>
> Each terminal's capabilities are known.
>
> To take advantage of this capability, instead of relying on h_char and
> v_char, it would need a new function like term_get_text_extent() . Those
> that can't handle it return a zero or other flag and the main core code
> calls the existing output. If a valid text extent is returned it gets used.
>
> That does not sound like a major rewrite. Probably a couple of lines in
> core to clean up key formatting plus the extra function added to the
> terminal interface.
>
> Maybe even svg and ps could provide a better estimation in this context.
I look forward to any code you care to prototype.
--
Ethan A Merritt
|
|
From: <pl...@pi...> - 2009-02-23 23:24:13
|
Ethan Merritt wrote:
> On Monday 23 February 2009 10:14:03 pl...@pi... wrote:
>> Ethan A Merritt wrote:
>>> On Monday 23 February 2009, pl...@pi... wrote:
>>>> Ethan A Merritt wrote:
>>>>> Gnuplot does not do any font handling on its own. It leaves this
>>>>> to the individual external devices or libraries. The corresponding
>>>>> drivers are supposed to provide approximate information about the
>>>>> average character width in the fields term->h_char, but the
>>>>> approximation can be pretty terrible depending on what font you pick.
>>>>> And anyhow, at best it contains the estimated width of an "average"
>>>>> character. In your case the titles are in all caps, and these are
>>>>> wider characters than average.
>>>> that gives some kind of manual work around which is helpful but all this
>>>> seems rather unsatisfactory in this day and age. Are there really none
>>>> of these terminals that can correctly return the space needed to render
>>>> a character string? X11 must surely be able to give that. I'd be a
>>>> little surprised if cairo can't.
>>> Sure. You could write a cairo-based graphics program, or a libgd-based
>>> graphics program, that queried the libraries for exact character widths.
>>> But gnuplot is not such a program. The core gnuplot code is separate
>>> from, and independent of, individual terminal drivers.
>> So the code snippet I posted could go in the cairopng terminal , others
>> would have simliar code where it can be supported.
>
> Huh?
> I don't understand at all.
> There is already similar code in various terminal drivers, called when
> a new font is selected. For example, this bit from gd.trm:
>
> /* Find approximate character width and height of selected TTF font */
> if (png_state.ttffont) {
> int brect[8];
> char *err;
> err = gdImageStringFT(NULL, &brect[0], 0,
> png_state.ttffont, (double)png_state.ttfsize,
> 0.0, 0, 0, "f00000000g");
> if (!err) {
> term->h_char = .11 * (float)(brect[2] - brect[0]) + 0.5;
> term->v_char = 1.1 * (float)(brect[1] - brect[7]) + 0.5;
> }
>
> But there is no framework in place for the core code to invoke this for
> individual strings, nor make use of the result. You would need to design
> such a framework.
>
I thought I just did. If you don't understand maybe you missed what I
posted or I did not explain it clearly enough.
>>>> While separating out the rendering detail into different terminals has
>>>> advantages it should not end up reducing things to a lowest common
>>>> denominator. If some terminals can correctly calculate text extents it
>>>> would be nice to use that capability.
>>> So far as I can see, that would require major restructing of the program.
>>> If you want to work on it, I suggest that the first step is to block out
>>> what such a restructuring would look like. Remember that some of the
>>> most capable terminal drivers, e.g. PostScript and svg, cannot know about
>>> font metrics at the time gnuplot is running. How would you take that into
>>> account?
>>>
>> Well that's what I meant about not going for lowest common demoninator.
>> It does not make sense to limit all output to monochrome because some
>> terminals can't handle colour.
>>
>> Each terminal's capabilities are known.
>>
>> To take advantage of this capability, instead of relying on h_char and
>> v_char, it would need a new function like term_get_text_extent() . Those
>> that can't handle it return a zero or other flag and the main core code
>> calls the existing output. If a valid text extent is returned it gets used.
>>
>> That does not sound like a major rewrite. Probably a couple of lines in
>> core to clean up key formatting plus the extra function added to the
>> terminal interface.
>>
>> Maybe even svg and ps could provide a better estimation in this context.
>
> I look forward to any code you care to prototype.
>
>
I don't know what you meant by framework if it was not that: a new
function in the terminal interface that can deliver the true text extent
of a given string as and when needed.
Each terminal capable of delivering a precise text extent will implement
its own low level function, eg. png_text_extent() , those that can't
will return a value indicating they can't.
Now, the key output in the core code can determine the correct text
extent where possible, where not it will fall back to the existing code
based on h_char.
Is that what you mean by a framework? does that approach make sense?
/Peter.
|
|
From: Ethan M. <merritt@u.washington.edu> - 2009-02-23 23:08:13
|
On Monday 23 February 2009 13:37:22 pl...@pi... wrote:
> Ethan Merritt wrote:
> > On Monday 23 February 2009 10:14:03 pl...@pi... wrote:
> >> Ethan A Merritt wrote:
> >>> On Monday 23 February 2009, pl...@pi... wrote:
> >>>> Ethan A Merritt wrote:
> >>>>> Gnuplot does not do any font handling on its own. It leaves this
> >>>>> to the individual external devices or libraries. The corresponding
> >>>>> drivers are supposed to provide approximate information about the
> >>>>> average character width in the fields term->h_char, but the
> >>>>> approximation can be pretty terrible depending on what font you pick.
> >>>>> And anyhow, at best it contains the estimated width of an "average"
> >>>>> character. In your case the titles are in all caps, and these are
> >>>>> wider characters than average.
> >>>> that gives some kind of manual work around which is helpful but all this
> >>>> seems rather unsatisfactory in this day and age. Are there really none
> >>>> of these terminals that can correctly return the space needed to render
> >>>> a character string? X11 must surely be able to give that. I'd be a
> >>>> little surprised if cairo can't.
> >>> Sure. You could write a cairo-based graphics program, or a libgd-based
> >>> graphics program, that queried the libraries for exact character widths.
> >>> But gnuplot is not such a program. The core gnuplot code is separate
> >>> from, and independent of, individual terminal drivers.
> >> So the code snippet I posted could go in the cairopng terminal , others
> >> would have simliar code where it can be supported.
> >
> > Huh?
> > I don't understand at all.
> > There is already similar code in various terminal drivers, called when
> > a new font is selected. For example, this bit from gd.trm:
> >
> > /* Find approximate character width and height of selected TTF font */
> > if (png_state.ttffont) {
> > int brect[8];
> > char *err;
> > err = gdImageStringFT(NULL, &brect[0], 0,
> > png_state.ttffont, (double)png_state.ttfsize,
> > 0.0, 0, 0, "f00000000g");
> > if (!err) {
> > term->h_char = .11 * (float)(brect[2] - brect[0]) + 0.5;
> > term->v_char = 1.1 * (float)(brect[1] - brect[7]) + 0.5;
> > }
> >
> > But there is no framework in place for the core code to invoke this for
> > individual strings, nor make use of the result. You would need to design
> > such a framework.
> >
>
> I thought I just did. If you don't understand maybe you missed what I
> posted or I did not explain it clearly enough.
>
>
> >>>> While separating out the rendering detail into different terminals has
> >>>> advantages it should not end up reducing things to a lowest common
> >>>> denominator. If some terminals can correctly calculate text extents it
> >>>> would be nice to use that capability.
> >>> So far as I can see, that would require major restructing of the program.
> >>> If you want to work on it, I suggest that the first step is to block out
> >>> what such a restructuring would look like. Remember that some of the
> >>> most capable terminal drivers, e.g. PostScript and svg, cannot know about
> >>> font metrics at the time gnuplot is running. How would you take that into
> >>> account?
> >>>
> >> Well that's what I meant about not going for lowest common demoninator.
> >> It does not make sense to limit all output to monochrome because some
> >> terminals can't handle colour.
> >>
> >> Each terminal's capabilities are known.
> >>
> >> To take advantage of this capability, instead of relying on h_char and
> >> v_char, it would need a new function like term_get_text_extent() . Those
> >> that can't handle it return a zero or other flag and the main core code
> >> calls the existing output. If a valid text extent is returned it gets used.
> >>
> >> That does not sound like a major rewrite. Probably a couple of lines in
> >> core to clean up key formatting plus the extra function added to the
> >> terminal interface.
> >>
> >> Maybe even svg and ps could provide a better estimation in this context.
> >
> > I look forward to any code you care to prototype.
> >
> >
>
> I don't know what you meant by framework if it was not that: a new
> function in the terminal interface that can deliver the true text extent
> of a given string as and when needed.
> Each terminal capable of delivering a precise text extent will implement
> its own low level function, eg. png_text_extent() , those that can't
> will return a value indicating they can't.
>
> Now, the key output in the core code can determine the correct text
> extent where possible, where not it will fall back to the existing code
> based on h_char.
>
> Is that what you mean by a framework? does that approach make sense?
I agree that individual terminals could implement such a routine for
single fragments of text. That has been discussed before. But that only
gets you so far.
What I meant by "framework" was a plan for how the core code would make
such a request and then make use of the result. Enhanced text mode is
particularly problematic. You can wave your hands and say you will add
code everywhere that is needed, but where exactly is that?
Ideally you would create some single routine that would mediate calls to
the new terminal function, so it only has to be maintained in one place in
the code. Better yet would be if it could replace some existing single
piece of code. I suppose the starting point would be the routine
estimate_strlen() in term.c. I looked into this once and decided that
it would be too difficult. But maybe you will have a cleverer idea than I did.
Just how many terminals do you think could possibly support this?
Are cairo and gd the only ones? If so, I am not sure it is worth doing,
because my guess is that the people who would care the most are the ones
who are going for publication-quality output. And they are most likely
using one of the terminals based on PostScript or LaTeX, for which I see
no hope of making this work.
--
Ethan A Merritt
|