|
From: Chris K <gnu...@li...> - 2006-04-04 18:23:53
|
Hi,
In considering whether to add enhanced text to port.trm, I have a question:
The usual enhanced_recursion calls will need feedback about the text layout size
from the terminal driver. If a terminal decided to handle the enhanced text
codes internally in the term->put_text call, without using the
enhanced_rercusion, would it still need to send any information to gnuplot about
the text size?
Also, in looking around to add enhanced text to port.trm, I was reading the
documentation in "gnuplot> help enhanced" and comparing that to the parser in
term.c and I found a contradiction.
In the help text it claims:
> (The '/' character MUST be the first character after the '{'.)
But in term.c (edited to clarity) in the enhanced_recursion routine:
> switch (*p) {
> case '{' :
> {
> while (*++p == ' '); /* Line I will call SKIPPY */
> if (overprint == 2) {
> ovp = (float)strtod(p,&p);
> if (term->flags & TERM_IS_POSTSCRIPT)
> base = ovp*f;
> else
> base += ovp*f;
> }
> --p;
> if (*++p == '/') {
Which clearly skips spaces after each opening brace. So the "MUST" in the help
and the code are in conflict. A related documentation / parser mismatch error is:
> You can change the font for one or
> both strings ('~a{.5 /*.2 o}'---an 'a' with a one-fifth-size 'o' on top---and
> the space between the number and the slash is necessary), but you can't
> change it after the beginning of the string.
Which from reading the code and performing tests is wrong -- you MUST NOT put a
space between the vertical shift and the '/'.
So it looks like the line I call SKIPPY used to be after the (overprint==2)
parsing code and has been cut and pasted to now be before the (overprint==2)
code. This causes both of the differences with the help text documentation.
There are several fixes:
*) Move SKIPPY back to below the (overprint==2) block, keep help text
*) Change the help text to reflect the new behavior
*) Put a copy of SKIPPY below the (overprint==2) block, change help text
*) Delete SKIPPY and change the help text
Also, I am amused that strtod is parsing the numbers for things like the font
size. Thus "{/=-0x.Deap1Rising}" would print "Rising" with a font size of -1.73926
This should be left undocumented. As should "/=INF" and "/=NaN".
Finally, the strtod calls all are prefixed with (float) which means it ought to
be a strtof call, so I assume this was done for portability reasons.
|
|
From: Ethan M. <merritt@u.washington.edu> - 2006-04-04 18:41:26
|
On Tuesday 04 April 2006 11:23 am, Chris K wrote: I'll have a look at the rest of your comments later, but for this one... > The usual enhanced_recursion calls will need feedback about the text layout size > from the terminal driver. I don't think this is true. Could you give a specific example? For instance, the postscript driver itself knows little about text layout. That information is not available until much later, when the output file is run through a postscript interpreter (e.g. a PostScript printer, ghostscript). By then it is far to late to feed any information back to the gnuplot core routines. > If a terminal decided to handle the enhanced text > codes internally in the term->put_text call, without using the > enhanced_recursion, would it still need to send any information to > gnuplot about the text size? I'm still not sure what information you mean. Are you talking about the estimated string length? That estimation is actually done by a special driver that does nothing else - estimate.trm. -- Ethan A Merritt Biomolecular Structure Center University of Washington, Seattle WA |
|
From: Chris K <gnu...@li...> - 2006-04-04 19:24:24
|
Ethan Merritt wrote:
> On Tuesday 04 April 2006 11:23 am, Chris K wrote:
>
> I'll have a look at the rest of your comments later, but for this one...
>
I have an additional comment about term.c's enhanced_recursion. It accepts
character for the name of the new font with this code:
> localfontname = p;
> while ((ch = *p) > ' ' && ch != '=' && ch != '*')
> ++p;
> save = *(savepos=p);
I strongly propose that '}' should also be excluded from the valid font name
characters, and therefore '{' as well. The new code would be:
> localfontname = p;
> while ((ch = *p) > ' ' && ch != '=' && ch != '*'
> && ch != '{' && ch != '}')
> ++p;
> save = *(savepos=p);
This way input like "{/Symbol}" does not parse a local font name of "Symbol}"
>> The usual enhanced_recursion calls will need feedback about the text layout size
>> from the terminal driver.
>
> I don't think this is true. Could you give a specific example?
> For instance, the postscript driver itself knows little about text
> layout. That information is not available until much later, when
> the output file is run through a postscript interpreter
> (e.g. a PostScript printer, ghostscript). By then it is far to late
> to feed any information back to the gnuplot core routines.
>
I think that answers my question. The output terminal code does not need to
measure the size of the text in order to succeed. It should have been obvious,
but other drivers do such measurements, so I was uncertain.
>> If a terminal decided to handle the enhanced text
>> codes internally in the term->put_text call, without using the
>> enhanced_recursion, would it still need to send any information to
>> gnuplot about the text size?
>
> I'm still not sure what information you mean.
> Are you talking about the estimated string length?
> That estimation is actually done by a special driver that
> does nothing else - estimate.trm.
>
I had noticed the estimate.trm file, but I did see where it was being used.
What I am hoping to do is have port.trm just put the enhanced text string (with
all the font commands and special codes) into the output. No calls to
enhanced_recursion|open|writec|flush will be made.
Thus port.trm will never get any measurement of the size of the enhanced text.
Then (perhaps much later), the Haskell code must parse the enhanced text as much
like enhanced_recursion as possible while rendering it. Thus I have been
reading that code very very closely.
I have created a parser in Haskell to comprehend the enhanced text strings.
(Including an amusingly complete emulation of strtod) (And I mimicked the
current code for enhanced_recursion so I will need a bug fix from the menu in my
last message). The next thing to do is to transform this into Render and Pango
instructions for display.
--
Chris
|
|
From: Daniel J S. <dan...@ie...> - 2006-04-04 19:44:02
|
Chris K wrote:
> I strongly propose that '}' should also be excluded from the valid font name
> characters, and therefore '{' as well. The new code would be:
>
>
>> localfontname = p;
>> while ((ch = *p) > ' ' && ch != '=' && ch != '*'
>> && ch != '{' && ch != '}')
>> ++p;
>> save = *(savepos=p);
Couldn't the string functions be utilized? I.e., "strspn()" and "isalnum()"
http://www.cppreference.com/stdstring/index.html
Dan
|
|
From: Chris K <gnu...@li...> - 2006-04-05 08:23:16
|
(moving back onto the list)
Ethan A Merritt wrote:
> On Tuesday 04 April 2006 12:24 pm, you wrote:
>> I strongly propose that '}' should also be excluded from the valid font name
>> characters, and therefore '{' as well. The new code would be:
>>
>>> localfontname = p;
>>> while ((ch = *p) > ' ' && ch != '=' && ch != '*'
>>> && ch != '{' && ch != '}')
>>> ++p;
>>> save = *(savepos=p);
>
> I just tried that, and it doesn't quite work.
> See for example the output of
>
> set title "aaa{/Symbol{bbb}}ccc"
>
> Your intent, I think, was to forgive the missing ' ' and
> proceed to process the next chunk of text. But it seems to
> need additional checks and/or case statements in order to
> avoid spurious error messages about mismatched curly braces.
>
> Anyhow, if you can prepare a patch with a bit more
> error checking and testing, I'll apply it.
>
I see what the problem is now. You need a sacrificial character, a space, after
the font name in order to use the parsing optimization where you overwrite the
space with '\0'. So in the above "aaa{/Symbol{bbb}}ccc\0 "you get
"aaa{/Symbol\0bbb}ccc\0" for localfontname "Symbol\0" and recurse with "bbb}ccc\0".
If the next character is '=' or '*' then it has to recognize this before
overwriting it with '\0'.
The overwritten character is always stored and replaced after the recursion.
If the parser would just copy the localfontname to separate storage, this would
not be an issue, and the parser would not need to mutate input string this way.
So long as the number of font changes in a plot is less than a few thousand, the
performance loss will be negligible.
I will contribute a patch for this.
--
Chris
|
|
From: Bastian M. <bma...@we...> - 2006-04-04 19:25:21
|
Ethan Merritt wrote:
> On Tuesday 04 April 2006 11:23 am, Chris K wrote:
>=20
> I'll have a look at the rest of your comments later, but for this one..=
=2E
>=20
>> The usual enhanced_recursion calls will need feedback about the text l=
ayout size
>> from the terminal driver.
>=20
> I don't think this is true. Could you give a specific example?
> For instance, the postscript driver itself knows little about text
> layout. That information is not available until much later, when
> the output file is run through a postscript interpreter=20
> (e.g. a PostScript printer, ghostscript). By then it is far to late
> to feed any information back to the gnuplot core routines.
I think that this is only true for postscript. win.trm and pm.trm both
need to know where to write the next piece of text and therefore need
to know the width of the text.
A quick look at gd.trm reveals the following piece of code in ENHGD_put_t=
ext():
/* EAM - Software text justification requires two passes */
if (png_state.justify =3D=3D RIGHT || png_state.justify =3D=3D CENTR=
E)
ENHgd_sizeonly =3D TRUE;
But also for left justified text the gdlib routines return the new positi=
on
after put_text and hence return the size of the text output.
So for most terminals you really need a way to get feedback about the tex=
t layout
size. Postscript is special since the decision about the exact positionin=
g
of enhanced text can (and must) be postponed to when the file is actually=
rendered.
Bastian
--=20
Bastian M=E4rkisch
|
|
From: Ethan M. <merritt@u.washington.edu> - 2006-04-04 20:06:33
|
On Tuesday 04 April 2006 12:25 pm, Bastian Maerkisch wrote: > > > >> The usual enhanced_recursion calls will need feedback about the text > >> layout size from the terminal driver. > > > For instance, the postscript driver itself knows little about text > > layout. That information is not available until much later, when > > the output file is run through a postscript interpreter > > (e.g. a PostScript printer, ghostscript). By then it is far to late > > to feed any information back to the gnuplot core routines. > A quick look at gd.trm reveals the following piece of code in ENHGD_put_text(): > > /* EAM - Software text justification requires two passes */ > if (png_state.justify == RIGHT || png_state.justify == CENTRE) > ENHgd_sizeonly = TRUE; > > So for most terminals you really need a way to get feedback about the text layout > size. I'm not sure we're all three of us on the same page here. It may be that I misunderstood the original question. The terminal driver itself may need to track such information internally in order to implement enhanced text. That is certainly true. But I thought Chris's question was whether a driver was obligated to pass such information back to the core code. The answer to that one is 'no'. It would be nice if the core routines *could* ask a driver for specific details, but unfortunately this doesn't work in general. PostScript is a major example, but it is also true for svg and x11. [OK, x11 could be made to work that way but it would probably require a new set of pipes between gnuplot and gnuplot_x11. I did consider doing this at one point, but decided it was too much work for too little gain.] -- Ethan A Merritt Biomolecular Structure Center University of Washington, Seattle WA |
|
From: Bastian M. <bma...@we...> - 2006-04-04 20:29:42
|
Ethan Merritt wrote: >=20 > I'm not sure we're all three of us on the same page here. > It may be that I misunderstood the original question. >=20 > The terminal driver itself may need to track such information > internally in order to implement enhanced text. > That is certainly true. >=20 > But I thought Chris's question was whether a driver was=20 > obligated to pass such information back to the core code. > The answer to that one is 'no'.=20 > > It would be nice if the core routines *could* ask a driver > for specific details, but unfortunately this doesn't work > in general. PostScript is a major example, but it is also > true for svg and x11. =20 >=20 I fully agree. Such a routine would make a nice (optional) addition to the terminal interface though. That way we could provide non terminal specific versions of enh_put_text(), enh_flush() and enh_open(). These could be used for gd.trm, win.trm, pm.trm and probably pdf.trm and bitmap based terminals. --=20 Bastian M=E4rkisch |
|
From:
<br...@ph...> - 2006-04-05 17:36:18
|
Bastian Maerkisch wrote: > Ethan Merritt wrote: >> I don't think this is true. Could you give a specific example? >> For instance, the postscript driver itself knows little about text >> layout. That information is not available until much later, when >> the output file is run through a postscript interpreter (e.g. a >> PostScript printer, ghostscript). By then it is far to late >> to feed any information back to the gnuplot core routines. > I think that this is only true for postscript. win.trm and pm.trm both > need to know where to write the next piece of text and therefore need > to know the width of the text. Some drivers need to know the width. The fact that the drivers exists is proof that they can get at it. Other drivers don't need it. The fact that some drivers exist even though they can't get at this information proves they don't strictly need it. > So for most terminals you really need a way to get feedback about the > text layout size. Counting and arguing about "most terminals" from a sample of just 4 of them makes little sense. > Postscript is special since the decision about the exact positioning > of enhanced text can (and must) be postponed to when the file is actually > rendered. It's not all that special. The fact that GD needs that two-pass try-and-fixup technique to do right and centered horizontal justification is a flaw of GD, not something to base terminal API design on. |
|
From: Bastian M. <bma...@we...> - 2006-04-05 19:49:41
|
Hans-Bernhard Br=F6ker wrote: > Bastian Maerkisch wrote: >> Ethan Merritt wrote: > >>> I don't think this is true. Could you give a specific example? >>> For instance, the postscript driver itself knows little about text >>> layout. That information is not available until much later, when >>> the output file is run through a postscript interpreter (e.g. a >>> PostScript printer, ghostscript). By then it is far to late >>> to feed any information back to the gnuplot core routines. > >> I think that this is only true for postscript. win.trm and pm.trm bot= h >> need to know where to write the next piece of text and therefore need= >> to know the width of the text. > > Some drivers need to know the width. The fact that the drivers exists= > is proof that they can get at it. > > Other drivers don't need it. The fact that some drivers exist even > though they can't get at this information proves they don't strictly > need it. > In another post yesterday Ethan already pointed out that he and I did hav= e a different understanding of Chris's question. I (still) agree that information about the text layout size is not mandatory for every driver,= but a useful and necessary information for some. So you're demonstration wasn't really necessary. --=20 Bastian M=E4rkisch Physikalisches Institut, Universit=E4t Heidelberg |
|
From: Chris K <gnu...@li...> - 2006-04-05 09:25:09
|
Before I can write the patch I want to, this specification bug below needs to be
resolved:
Chris K wrote:
> In the help text it claims:
>
>> (The '/' character MUST be the first character after the '{'.)
>
> But in term.c (edited to clarity) in the enhanced_recursion routine:
>
>> switch (*p) {
>> case '{' :
>> {
>> while (*++p == ' '); /* Line I will call SKIPPY */
>> if (overprint == 2) {
>> ovp = (float)strtod(p,&p);
>> if (term->flags & TERM_IS_POSTSCRIPT)
>> base = ovp*f;
>> else
>> base += ovp*f;
>> }
>> --p;
>> if (*++p == '/') {
>
> Which clearly skips spaces after each opening brace. So the "MUST" in the help
> and the code are in conflict. A related documentation / parser mismatch error is:
>
>> You can change the font for one or
>> both strings ('~a{.5 /*.2 o}'---an 'a' with a one-fifth-size 'o' on top---and
>> the space between the number and the slash is necessary), but you can't
>> change it after the beginning of the string.
>
> Which from reading the code and performing tests is wrong -- you MUST NOT put a
> space between the vertical shift and the '/'.
>
> So it looks like the line I call SKIPPY used to be after the (overprint==2)
> parsing code and has been cut and pasted to now be before the (overprint==2)
> code. This causes both of the differences with the help text documentation.
>
> There are several fixes:
> *) Move SKIPPY back to below the (overprint==2) block, keep help text
> *) Change the help text to reflect the new behavior
> *) Put a copy of SKIPPY below the (overprint==2) block, change help text
> *) Delete SKIPPY and change the help text
>
>
I have checked the 4.0.0 tarball: The above code and bug looks to be the same in
that version. (I did not compile and test).
Consider this command which is currently accepted by the latest code, in
contradiction to help text:
plot x title "aaa{ / Symbol { } { bbb}}ccc"
Which spaces should be required, optional, or forbidden?
The resulting label is "aaa BBBccc" where B means "Beta". Which three spaces
from the command correspond to the three in the label?
These three: "} {"
I don't want to smash backward compatibility and then have to fix it.
How can I check backward compatibility of enhanced text?
I have just downloaded the version 3.7.3 code. Should I take the behavior of
its post.trm ENHPS_recurse routine as canonical?
It appears that this parser agrees with the help text about no space allowed
between "{/", though it lacks the overprint '~' capability.
Or does the development version of gnuplot have a "license to kill" backward
compatibility in corner cases?
--
Chris
|
|
From:
<br...@ph...> - 2006-04-05 14:58:14
|
Chris K wrote: >> So it looks like the line I call SKIPPY used to be after the (overprint==2) >> parsing code and has been cut and pasted to now be before the (overprint==2) >> code. Checking this (via "cvs annotate")... unlikely. That line has been in that place ever since enhanced_recursion() moved to term.c late in 2003. > I don't want to smash backward compatibility and then have to fix it. > How can I check backward compatibility of enhanced text? > I have just downloaded the version 3.7.3 code. Should I take the behavior of > its post.trm ENHPS_recurse routine as canonical? Not really. The latest release (i.e. 4.0) should be the baseline. Any conflicts between source and documentation of that are bugs that need to be discussed here and fixed. In case of doubt, given the lack of will to update documentation along with the changes to the source that is sort of a tradition among developers, the source is to be trusted more than the docs. |
|
From: Ethan A M. <merritt@u.washington.edu> - 2006-04-05 15:23:11
|
On Wednesday 05 April 2006 02:24 am, Chris K wrote:
> >> (The '/' character MUST be the first character after the '{'.)
> >
> > [the code] clearly skips spaces after each opening brace.
> > So the "MUST" in the help and the code are in conflict.
I do not view this as a bug.
The docs state that the supported syntax is '{' followed immediately
by '/'. The code does support this. It also forgives intervening
whitespace, which is undocumented. If you place extra whitespace
in the command, then you have gone outside the documented spec and
should not complain about the results. It happens that the code does
something reasonable anyhow, which is a relatively user-friendly
outcome and hardly deserves the label "bug".
--
Ethan A Merritt
Biomolecular Structure Center
University of Washington, Seattle 98195-7742
|
|
From:
<br...@ph...> - 2006-04-05 16:00:30
|
Ethan A Merritt wrote:
> The docs state that the supported syntax is '{' followed immediately
> by '/'. The code does support this. It also forgives intervening
> whitespace, which is undocumented.
There's a difference between being undocumented and contradicting the
documentation, even more so if the relevant part of the documentation
SHOUTS. Documentation stating wrong facts is a bug in its own right.
|
|
From: Ethan M. <merritt@u.washington.edu> - 2006-04-05 16:22:43
|
On Wednesday 05 April 2006 09:01 am, you wrote:
> Ethan A Merritt wrote:
>
> > The docs state that the supported syntax is '{' followed immediately
> > by '/'. The code does support this. It also forgives intervening
> > whitespace, which is undocumented.
>
> There's a difference between being undocumented and contradicting the
> documentation, even more so if the relevant part of the documentation
> SHOUTS. Documentation stating wrong facts is a bug in its own right.
I don't see how it can ever be a bug for the documentation to say
"the supported syntax requires that blah, blah, blah".
If the docs tell you not to do something, but you do it anyway,
the fact that it happens to work is not a bug. If it works today
but not tomorrow, that also is not a bug.
I do agree that it is odd for the documentation to SHOUT while
stating the supported syntax.
--
Ethan A Merritt
Biomolecular Structure Center
University of Washington, Seattle WA
|
|
From: Chris K <gnu...@li...> - 2006-04-05 16:44:17
|
Ethan A Merritt wrote:
> On Wednesday 05 April 2006 02:24 am, Chris K wrote:
>>>> (The '/' character MUST be the first character after the '{'.)
>>> [the code] clearly skips spaces after each opening brace.
>>> So the "MUST" in the help and the code are in conflict.
>
> I do not view this as a bug.
>
> The docs state that the supported syntax is '{' followed immediately
> by '/'. The code does support this. It also forgives intervening
> whitespace, which is undocumented. If you place extra whitespace
> in the command, then you have gone outside the documented spec and
> should not complain about the results. It happens that the code does
> something reasonable anyhow, which is a relatively user-friendly
> outcome and hardly deserves the label "bug".
>
With only one parsing engine, then you get a consistent and implicitly defined
enhanced text specification. The original Netscape browser made the decision to
be liberal in what it accepted and rendered, and so many people and programs
created nonstandard HTML and every other browser then had to deal with either
breaking backward compatibility with Netscape or copying the informal implicit
specification. And upgrades to Netscape could not abandon the old leniency,
which is exactly what I am asking here: I want to make a clear decision on the
specification, document it, and make the parser match the documentation.
The only unclear clear bit of the enhanced text behavior and documentation has
to do with whitespace handling. There are two goals to making a spec for this:
(1) It should be obvious to people which whitespace is significant so they can
add whitespace where they want it (i.e. principle of least surprise).
(2) It should be obvious to someone writing a GUI front-end how to write a
editor that generates enhanced text.
The secondary unclear bit of the current behavior is that the braces are not
always parsed in pair because of the localfontname parsing.
|