|
From: Benjamin L. <bj...@gm...> - 2011-02-11 09:51:51
|
On Fri, Feb 11, 2011 at 2:14 AM, Ethan Merritt <merritt@u.washington.edu> wrote: >> The problem of the enhanced text positioning is fixed with the patch >> suggested at >> http://article.gmane.org/gmane.comp.graphics.gnuplot.devel/9905 >> which still applies for the 2011-01-25 CVS snapshot. >> >> benjamin >> > > I woul d be happy to apply this patch if it indeed fixes a problem for > Windows users. > > I must say, however, that I do not understand the logic behind the patch. > The existing code in win.trm looks correct to me, as it is > parallel to code that is demonstrably correct in other terminal drivers. > Maybe I am misunderstanding what is returned by the routine > GraphGetTextLength(). I would have thought that it would return > the bounding rectangle for the text in absolute units (~pixels) with > 0,0 at the lower left and (xmax,ymax) at the upper right. > (That's what the analagous routine does in libgd). But in that case > modifying the code to scale the bounding rectangle by the terminal > width and height makes no sense. Does it not have the effect of expanding > every text fragment to fill the whole screen? > > If the coordinates returned by GraphGetTextLength() are non-uniform, > then I could understand needing to correct the extent along y by the > aspect ratio: > width = cos(WIN_angle) * len; > height = sin(WIN_ANGLE) * len; > height *= graphwin.xmax/graphwin.ymax; > > But that is different from what the patch does. > Am I reading this wrong? Thanks for the criticism, I started to re-think from scratch, and realized that by trying to fix this problem as proposed, I introduced another bug elswhere (damn!) I'm sorry for causing all this confusion, I'll try to explain how I understand the problem here. First, remember that the windows terminal introduces an additional intermediate layer between what gnuplot tells the terminal driver and what the windows graph windows displays, so you can't compare to non-interactive terminals like the gd terminals. The terminal driver generates a virtual coordinate system that extends from (0,0) to (graphwin.xmax, graphwin.ymax). The graph window, however has a different coordinate system, extending from (0,0) to (rect.width, rect.height). So you have to translate between them. And the terminal's width and height merely define the resolution of the positioning within the graw window coordinate system. Your proposal above does not work, because xmax/ymax is not the same as width/height - there are two different scaling factors for x and y coordinates. Now, the old behaviour was like follows: GraphGetTextLength() determined the extent of the text along the horizontal axes (i.e. its width) in physical points, and then translated the text width but only considering the width of the terminal canvas and the width of graph window (the only-the-width part is the mistake here) - so it does not return the text extent in absolute pixels. When actually displaying the text, the coordinates are again transformed into real-world screen pixels. But the ratio of window width to canvas width is not the same as window height to canvas height (the canvas extent is hardwired and has no relation to the graph window's actual width&height) - so scaling both x and y part of coordinates considering only the ratio of window width to canvas width will yield a wrong placement in y. The proposed behaviour is: GraphGetTextLength() returns the width in points (which are interpreted as pixels). The coordinate transformation happens afterwards, now (correctly) separately for x and y axis. (BTW this transformation is the inverse of the transformation that is done in drawgraph() in wgraph.c - the graph window's actual drawing function) The actual drawing on the graph window is done in drawgraph() in wgraph.c. And here all coordinates are transformed back to pixels-on-the-screen, with x -> x*width/xmax, y -> y*height/ymax. And these ratios need not be the same, that's why the inverse transformation in WIN_enhanced_flush() must take both into account. This now is fixed (for me with 2011-01-25 CVS snapshot on WinXP SP3) with diff --git a/src/win/wgraph.c b/src/win/wgraph.c --- a/src/win/wgraph.c +++ b/src/win/wgraph.c @@ -2681,7 +2681,7 @@ GetTextExtentPoint(hdc, text, strlen(text), &size); SelectObject(hdc, hprevfont); - size.cx = MulDiv(size.cx + GetTextCharacterExtra(hdc), lpgw->xmax, rect.right-rect.left-1); + size.cx += GetTextCharacterExtra(hdc); /* shige: restore original font */ GraphChangeFont(lpgw, lpgw->deffontname, lpgw->deffontsize, hdc, rect); return size.cx; diff --git a/term/win.trm b/term/win.trm --- a/term/win.trm +++ b/term/win.trm @@ -850,8 +850,11 @@ /* calculate length of string first */ len = GraphGetTextLength(&graphwin, enhanced_text, WIN_font, WIN_fontsize); - width = cos(WIN_angle) * len; - height = sin(WIN_angle) * len; + RECT rect; + GetPlotRect(&graphwin, &rect); + + width = round(cos(WIN_angle) * len * graphwin.xmax / (rect.right-rect.left-1)); + height = round(sin(WIN_angle) * len * graphwin.ymax / (rect.bottom-rect.top-1)); if (ENHwin_show && !ENHwin_sizeonly) { /* display string */ which simply moves the translation from GraphGetTextLength() to WIN_enhanced_flush and uses correct scaling factors in x and y. the other two hunks in the original patch caused problems with coordinate positioning for all other plotted objects (aside enhanced rotated text with sub/superscript) - so I have to drop them. Apoplogies again for introducing them in the first place. The problem is rather complex on second thoughts... benjamin |