garya@Solbourne.COM (Gary Aitken) (08/04/89)
XDrawImageString has a bug in it for fonts like .../75dpi/courR14.snf which have
pixels at the top of the font for things like umlauts. The font height,
as measured by maxbounds ascent+descent, is 16. A font property, PIXEL_SIZE,
is 14. XDrawImageString does not draw the top two pixels in some cases.
I'm guessing it's using the property somehow to determine a clip region?
Here's a demo:
Fails on X11R3 and the pre release R4 Xlib
================================== cut here ========================================
#include <X11/Xlib.h>
main(argc,argv)
int argc ;
char **argv ;
{
Display *dpy ;
Window rt,win1,win2 ;
int x,y ;
char *fnp ; /* font name */
XFontStruct *fp ; /* ptr to X font structure for new font */
XGCValues tempgc ; /* temporary X graphics context for creating GC's */
GC gc1,gc2 ;
unsigned long mask ;
static char string[] = "H\305" ; /* H, A with a circle over it in courR14.snf */
XEvent event ;
dpy = XOpenDisplay("unix:0.0") ;
XSynchronize(dpy,1) ;
rt = XDefaultRootWindow(dpy) ;
fp = XLoadQueryFont(dpy,"-adobe-courier-medium-r-normal--14-140-75-75-m-90-iso8859-1") ;
tempgc.graphics_exposures = False ;
tempgc.foreground = XBlackPixel(dpy,0) ;
tempgc.background = XWhitePixel(dpy,0) ;
tempgc.font = fp->fid ;
mask = GCForeground | GCBackground | GCGraphicsExposures | GCFont ;
gc1 = XCreateGC(dpy,rt,mask,&tempgc) ;
win1 = XCreateSimpleWindow(dpy,rt,100,100,300,200,4,tempgc.foreground,tempgc.background) ;
win2 = XCreateSimpleWindow(dpy,rt,200,100,300,200,4,tempgc.foreground,tempgc.foreground) ;
XSelectInput(dpy,win1,StructureNotifyMask) ;
XSelectInput(dpy,win2,StructureNotifyMask) ;
XMapWindow(dpy,win1) ;
XMapWindow(dpy,win2) ;
while (!XCheckTypedWindowEvent(dpy,win1,MapNotify,&event))
;
while (!XCheckTypedWindowEvent(dpy,win2,MapNotify,&event))
;
tempgc.foreground = XWhitePixel(dpy,0) ;
tempgc.background = XBlackPixel(dpy,0) ;
gc2 = XCreateGC(dpy,rt,mask,&tempgc) ;
XDrawImageString(dpy,win1,gc1,50,50,string,2) ;
XDrawImageString(dpy,win1,gc2,100,50,string,2) ;
XDrawImageString(dpy,win2,gc1,50,50,string,2) ;
XDrawImageString(dpy,win2,gc2,100,50,string,2) ;
while (1) ;
}
--
Gary Aitken
Solbourne Computer Inc. ARPA: garya@Solbourne.COM
Longmont, CO UUCP: !{boulder,nbires,sun}!stan!garya
rws@EXPO.LCS.MIT.EDU (08/04/89)
Fails on X11R3 and the pre release R4 Xlib Please refrain from reporting suspected problems with pre-release software on public lists. I suspect your company asks the same thing of its customers.
rws@EXPO.LCS.MIT.EDU (08/04/89)
Here's a demo: Fails on X11R3 and the pre release R4 Xlib Your program produces correct output on a Sun R3 server, and on a server in our current development system. Either your server ddx is broken, or you misunderstand what bits should be drawn. The "background" fill is only done based on font-ascent and font-descent, not based on maxbounds. For the font in question, font-ascent is defined as 11, even though some glyphs extend higher than that. If you believe the Courier fonts should be altered to make them more directly useful for image text, you can plead your case to Adobe and Digital, from whence the fonts came.
wdc@ATHENA.MIT.EDU (Bill Cattey) (08/05/89)
I think more clarification is needed with XDrawImageString. I have had the advantage of being able to pick the brains of Ralph Swick who worked with me for a long time before I got the underlying concept of XDrawImageString. I _think_ I have it right now. Ralph, correct me if I still mis-understand. Here goes: Whereas XDrawString and XDrawText are for applications that allow text drawing to be totally unconstrained, XDrawImageString is for those applications where the drawing is "well-behaved". The definition of well-behaved is that all characters drawn have vertical bounds within the bounding box of the font, and no characters have a negative left bearing. This enables simplifying assumptions to be made on redisplay: Since the bounding box constrains the height and descent of characters, line spacing is done by looking at the bounding box of the font, and the application never has to worry about redrawing text above or below the current line. Characters need not be erased, and redrawn, they need only be overwritten. Simple bit blit'ing of rectangular regions move the lines and other characters out of the way. As soon as you permit the more general case, of characters that can bleed into previous characters, and lines above and below the current line, you must write a redisplay that knows what characters it drew, knows to erase and redraw them, and to repair any damage on lines above, below, or to the left of what is drawn. XDrawImageString is, NOT for the general case. When you look at what has to be done for such simple drawing, you understand that the background must be drawn in the constrained rectangle, and that fonts that are not "well-behaved" simply can't be used by applications making the simplifying assumptions. To summarize: you can't write a redisplay algorithm for text that could bleed into nearby bounding boxes without performing erase and redraw operations. A redisply that just pours rectangles of characters and their background onto the screen must be well-behaved. -wdc