argv%eureka@Sun.COM (Dan Heller) (05/18/89)
Now that I'm talking about fonts, inspection of the code *appears*
to be just shy of giving XDrawString the ability to render rotated
text. The following changes would need to happen: there needs to
be a height field in the XCharStruct data structure, and there needs
to be an ability to communicate this new information about the font
changes to the server. The application is responsible for rotating
the glyphs of the characters, of course.
typedef struct {
short lbearing; /* origin to left edge of raster */
short rbearing; /* origin to right edge of raster */
short width; /* advance to next char's origin */
/+ short height; /* advance to next y coord */ +/
short ascent; /* baseline to top edge of raster */
short descent; /* baseline to bottom edge of raster */
unsigned short attributes; /* per char flags (not predefined) */
} XCharStruct;
Here, the "width" is currently used to move the position of the
next x coord for rendering the next character. However, the y
coord stays the same. I don't see a requirement that this has
to be this way -- with the "height" parameter, the next char's
origin can be moved up or down as well. If the application
chooses to not rotate the glyphs, the the characters rendered
may have a stepping stone effect. With negative values in the
height and width fields, the text may be rendered from right
to left.
Affected called would include all the routines which would get
the geometry of a string including the bounding boxes, text width
and height, etc...
Feedback?
dan <island!argv@sun.com>
dan <argv@sun.com>
clive@ixi.UUCP (Clive Feather) (05/19/89)
In article <105466@sun.Eng.Sun.COM> argv@sun (Dan Heller) writes: >Now that I'm talking about fonts, inspection of the code *appears* >to be just shy of giving XDrawString the ability to render rotated >text. The following changes would need to happen: there needs to >be a height field in the XCharStruct data structure, and there needs >to be an ability to communicate this new information about the font >changes to the server. The application is responsible for rotating >the glyphs of the characters, of course. Firstly, changing the XCharStruct data structure means changing the protocol, and there's no way that the real world out there is going to let you (yes, I know that there have been changes from R1 to R2 to R3, but they were subtle and upwards compatible - this would be *totally* incompatible). Next, isn't the "width" and "height" of the character going to change as you change the angle ? Far more important - how is the application going to rotate the glyphs ? They're not in the XFontStruct or anything that hangs off it. This means that to get hold of them, you need to do something on the lines of: create a pixmap just big enough to hold the largest character in the font, and depth 1; create a GC for working on this pixmap; for (each character c in the font) { XSetForeground (GC, 0); XFillRectangle (the whole pixmap); XSetForeground (GC, 1); XDrawString (pixmap, an appropriate position, a string of length 1 holding c); glyph [c] = XGetImage (the pixmap); } BTW, please describe an algorithm for rotating the characters *neatly*. Finally, there is no way to turn these rotated glyphs back into a font ! The nearest that you can do is something like: Rotate the glyphs. Write them out in BDF (Bitmap Distribution Format), wrapped up to form a font. Run bdftosnf on the font. Install the font in an appropriate directory. Run mkfontdir on that directory. Reboot your server (or possibly, mess around with XSetFontPath). If you just want to write the characters at an angle, without rotating the glyphs, then the following might be of use to you: WARNING: Untested (and uncompiled) code follows. =============================== 8< ================================== /* DISCLAIMER: I am not interested in bug fixes or any other comments on this code. This has been written just to make a point. This is not supported code of IXI Limited. COPYRIGHT: This code is in the public domain (or whatever the equivalent is in English law). DESCRIPTION: XDrawAngledString (display, d, gc, fs, x, y, angle, string, length) Arguments as XDrawString, except "fs", which is the XFontStruct for the font, and "angle", which is a double. This function draws a string, placing the glyphs along a line at an angle to the horizontal, spaced at the correct distance along that line but not rotating the glyphs. */ XDrawAngledString (display, d, gc, fs, x, y, angle, string, length) Display *display; Drawable d; GC gc; XFontStruct *fs; int x, y; double angle; char *string; int length; { int i; int xx = x; int xx = y; double si = sin (angle); double co = cos (angle); char *c; for (i = 0, c = string; i < length; i++, c++) { int w; XDrawString (display, d, gc, xx, yy, c, 1); w = XTextWidth (fs, c, 1); xx += si * w; yy += co * w; } } =============================== 8< ================================== -- Clive D.W. Feather clive@ixi.uucp IXI Limited ...!mcvax!ukc!ixi!clive (riskier) +44 223 462 131
ondrejko@paul.rutgers.edu (Michael Ondrejko) (05/19/89)
We are about to start design of an application that could use rotated text within a graphics window. From what I have noticed Xlib (& Xtoolkit) only provide for horizontal text. I would appreciate any information that could be provided. Thanks, Michael Ondrejko (ondrejko@paul.rutgers.edu)
dheller@cory.Berkeley.EDU (Dan Heller) (05/21/89)
> In article <105466@sun.Eng.Sun.COM> argv@sun (Dan Heller) writes: > >Now that I'm talking about fonts, inspection of the code *appears* > >to be just shy of giving XDrawString the ability to render rotated > >text. The following changes would need to happen: there needs to > >be a height field in the XCharStruct data structure, and there needs > >to be an ability to communicate this new information about the font > >changes to the server. The application is responsible for rotating > >the glyphs of the characters, of course. In article <169@ixi.UUCP> clive@ixi.uucp (Clive Feather) writes: > Firstly, changing the XCharStruct data structure means changing the > protocol, and there's no way that the real world out there is going > to let you This is the biggest problem, of course and for that reason, it's all a moot point. However, this need not be in there were an -additional- font type which has different calling functions from the currently existing font types. Since for rotated text, calls such as XTextWidth doesn't make a lot of sense (since there is another dimension involved). A new set of functions could be introduced to support this stuff. I or anyone else isn't going to go to the effort to do so if X is definitively going to stay out of the page description aspect of graphics. > Next, isn't the "width" and "height" of the character going to change > as you change the angle ? Yes -- and that's why I'd like to have the ability to send a request to the server to modify this information. This wouldn't apply to any arbitrary font, it would apply only to fonts which have been "uploaded" by the application (uploaded fonts could be flaged as read/write).. If the application decides to rotate text, then it could send a request to the server to change the width/height attributes of a font. This doesn't necessarily require the glyphs to rotate of course. You can have chars which appear as steps. Similarly, you can rotate glyphs without affecting the way their orientation appears. These are all concepts in the printing industry that are not unusual. Since great efforts were made to make X suitable for creating a "Draw" package by supporting all sorts of geometric shapes, line styles, end caps, and so on, why not extend the protocol to do reasonable page description support. > Far more important - how is the application going to rotate the > glyphs ? They're not in the XFontStruct or anything that hangs off > it. This means that to get hold of them, you need to do something on > the lines of: The X server stores the glyphs somewhere (admittedly, I don't know the internals to this that well). However they are stored, it would be nice to be able to tell the server to change the glyph of a particular character. XSetFontGlyph(fid, c, glyph) XID fid; /* font id */ int c; /* index into the font table */ Pixmap glyph; /* change image to use this glyph */ > BTW, please describe an algorithm for rotating the characters *neatly*. There are many ways to store font information. So as not to threat anyone's technology, let's consider the most simple case -- fonts stored as bitmaps. Here, a simple bitmap rotation method is all you need. Again, this does not necessarily represent characters, even tho it's likely. The actual rotation of glyphs can be simple or complex depending on the needs (intelligence?) of the application. > Finally, there is no way to turn these rotated glyphs back into a font ! A font is nothing more than a set of glyphs and information about them. If I take an 'A' and use some magic to rotate it (again, use the bitmap rotation analogy), then the glyph, in my font book, still represents an A. It is still a font. A well designed application will obviously save its "initial" information about a font so numerous transformations don't degenerate the image into a set of random pixels. > The nearest that you can do is something like: > > Rotate the glyphs. > Write them out in BDF (Bitmap Distribution Format), wrapped > up to form a font. > Run bdftosnf on the font. > Install the font in an appropriate directory. > Run mkfontdir on that directory. This is *precisely* what I want to avoid. I want to be able to load a font directly into the server from an application -- and, I want to modify that font from the application. Clearly, there are restrictions on this special font that don't apply to the other fonts -- e.g. you don't get the font listed from xlsfonts; the font is read/write; the font is only available to the client using the font; the font is destroyed and all information about it is freed in case the application dies or sends a XFreeFont type of request. These are just issues from the top of my head -- I haven't gone into a design phase of this. > Reboot your server (or possibly, mess around with XSetFontPath). If XSetFontPath exists, then there are clearly the internal functions available to actually load a new font or change font info at runtime. Next, you provide a sample routine which demonstrates my point that the need for rotated font information should exist. first, a quick review of your routine: > for (i = 0, c = string; i < length; i++, c++) > { > int w; > > XDrawString (display, d, gc, xx, yy, c, 1); > w = XTextWidth (fs, c, 1); > xx += si * w; > yy += co * w; > } I should point out that this is just about what I *am* doing now in order to display rotated fonts because there is no other method available. The routine involves two expensive operations: XDrawString and XTextWidth. For one thing, both of these routines involve communication with the server -- in the case of XTextWidth, the glyph is gotten from the server for inspection. Both of these routines, when compounded by the length of the string, will generate lots of network traffic as well as poor performance. If the height and width information I described before were stored in the font or character somehow, then the string can be rendered with the single call to XDrawString and the server can handle the placement of the next character internally. It already does it for the width --the only change necessary would be for its height. Dan Heller <island!argv@sun.com>
brown@ftms.UUCP (Vidiot) (03/20/91)
We are looking for pointers, hints or code that will allow us to put up text in a window that isn't horizontal. The idea is to label (for instance) a graph's left (Y) axis with text that is rotated 90 degrees clockwise. Does anyone have ways of doing this? If so, please send me some e-mail. It will be appreciated. -- harvard\ ucbvax!uwvax!astroatc!ftms!brown rutgers/ INTERNET: spool.cs.wisc.edu!astroatc!ftms!brown
mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (03/22/91)
> We are looking for pointers, hints or code that will allow us to put > up text in a window that isn't horizontal. [It's the text that's to be non-horizontal, not the window.] From the FAQ: ---------------------------------------------------------------------- Subject: 110) How do I render rotated text? Xlib intentionally does not provide such sophisticated graphics capabilities, leaving them up to server-extensions or clients-side graphics libraries. Your only choice, if you want to stay within the core X protocol, is to render the text into a pixmap, read it back via XGetImage(), rotate it "by hand" with whatever matrices you want, and put it back to the server via XPutImage(); more specifically: 1) create a bitmap B and write your text to it. 2) create an XYBitmap image I from B (via XGetImage). 3) create an XYBitmap Image I2 big enough to handle the transformation. 4) for each x,y in I2, I2(x,y) = I(a,b) where a = x * cos(theta) - y * sin(theta) b = x * sin(theta) + y * cos(theta) 5) render I2 Note that you should be careful how you implement this not to lose bits; an algorithm based on shear transformations may in fact be better. The high-level server-extensions and graphics packages available for X also permit rendering of rotated text: Display PostScript, PEX, PHIGS, and GKS, although most are not capable of arbitrary rotation and probably do not use the same fonts that would be found on a printer. In addition, if you have enough access to the server to install a font on it, you can create a font which consists of letters rotated at some predefined angle. Your application can then itself figure out placement of each glyph. [courtesy der Mouse (mouse@larry.mcrcim.mcgill.edu), Eric Taylor (etaylor@wilkins.bmc.tmc.edu), and Ken Lee (klee@wsl.dec.com), 11/90; Liam Quin (lee@sq.com), 12/90] ---------------------------------------------------------------------- der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
brsmith@cs.umn.edu (Brian R. Smith) (03/23/91)
In <9103220518.AA05516@lightning.McRCIM.McGill.EDU> mouse@lightning.mcrcim.mcgill.EDU (der Mouse) writes: >> We are looking for pointers, hints or code that will allow us to put >> up text in a window that isn't horizontal. >[It's the text that's to be non-horizontal, not the window.] >From the FAQ: >---------------------------------------------------------------------- >Subject: 110) How do I render rotated text? > > Xlib intentionally does not provide such sophisticated >graphics capabilities, leaving them up to server-extensions or >clients-side graphics libraries. Your only choice, if you want >to stay within the core X protocol, is to render the text into a >pixmap, read it back via XGetImage(), rotate it "by hand" with >whatever matrices you want, and put it back to the server via >XPutImage(); more specifically: On a related note: InterViews (C++ UI toolkit, in the X contrib software) has support for rendering rotated fonts in X. It could be one source of example code. (With the caveat that it is a somewhat large and complex piece of software to go dredging through for that one specific piece of information.) -- Brian