tomt@maui.coral.COM (Tom Tulinsky) (06/13/91)
I hadn't realized that there was a limit to the size of the lists that
the X poly requests like XDrawLines can handle until recently, when I
read Kenton Lee's article 'Behind Curtain X' in June's Unix Review.
Here's some code which will draw lines with an arbitrary length array
of points.
A couple of pointed questions:
- If it's so simple, why can't the Xlib do it for you?
- Xlib should at least tell you the exact number of points you can
give to each request, instead of making you divide by the size of the
array element and subtract the header size...
/* allow for X protocol request header; 3 is supposed to be enough for now,
* but there's no guarantee this will not change...this is pretty sleazy
* anyhow
*/
#define FUDGE 10
int chunksize, ii, reqsize;
chunksize = XMaxRequestSize(gDisplay) - FUDGE;
for (ii=0; ii<numpts; ii+=chunksize-1)
{
/* last chunk is short */
reqsize = min(chunksize, numpts-ii);
XDrawLines (dis, win, gc, Xpts[ii], reqsize, mode);
printf("drawing points %d to %d\n", ii,ii+reqsize-1);
}
rws@expo.lcs.mit.EDU (Bob Scheifler) (06/13/91)
- If it's so simple, why can't the Xlib do it for you? R4 and later Xlib implementations do do it for you.
mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (06/13/91)
> I hadn't realized that there was a limit to the size of the lists > that the X poly requests like XDrawLines can handle until recently, > when I read Kenton Lee's article 'Behind Curtain X' in June's Unix > Review. Here's some code which will draw lines with an arbitrary > length array of points. [code omitted; simply breaks up the list of points, calling XDrawLines multiple times.] > A couple of pointed questions: > - If it's so simple, why can't the Xlib do it for you? Because it's *not* so simple. Read the protocol spec for the PolyLine request. In particular, pay close attention to joins and the semantics of overlapping lines. Your "solution" produces at least the following violations: - Between batches of lines, the line cap is applied twice instead of the line join being applied once. The protocol document says: The lines join correctly at all intermediate points, and if the first and last points coincide, the first and last lines also join correctly. - When wide lines intersect, the overlapping pixesl are drawn either once, if all overlapping pieces fall in the same batch, or multiple times, if not. The protocol document says: For any given line, no pixel is drawn more than once. If thin (zero line-width) lines intersect, the intersecting pixels are drawn multiple times. If wide lines intersect, the intersecting pixels are drawn only once, as though the entire PolyLine were a single filled shape. The Xlib document contains similar language in both cases. > - Xlib should at least tell you the exact number of points you can > give to each request, instead of making you divide by the size of > the array element and subtract the header size... Arguably so, but you'd have to have a separate value for each draw-multiple-things routine. While this is not particularly onerous, because there are only a few things which generate huge requests which can't be split up (lines, rectangles, arcs, and filled polygons are all I can see offhand), it is somewhat ugly. > /* allow for X protocol request header; 3 is supposed to be enough > * for now, but there's no guarantee this will not change... > */ > #define FUDGE 10 It won't change without a pretty major protocol revision; the size of the PolyLine overhead relative to the size of each line is fixed by the encoding. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
rws@expo.lcs.mit.EDU (Bob Scheifler) (06/13/91)
> - If it's so simple, why can't the Xlib do it for you?
Because it's *not* so simple.
Oops, yes, you're quite right, I mistranslated to XDrawSegments,
which Xlib does handle.
klee@wsl.dec.com (Ken Lee) (06/13/91)
In article <9106121938.AA23986@maui.coral.com>, tomt@maui.coral.COM (Tom Tulinsky) writes: |> A couple of pointed questions: |> - If it's so simple, why can't the Xlib do it for you? Most (but not all) current Xlib implementations do break up the easy cases. You're on your own for the hard ones (e.g., XFillPolygon), however. -- Ken Lee DEC Western Software Laboratory, Palo Alto, Calif. Internet: klee@wsl.dec.com uucp: uunet!decwrl!klee
pmartz@undies.dsd.es.com (Paul Martz) (06/13/91)
In article <9106121938.AA23986@maui.coral.com>, tomt@maui.coral.COM (Tom Tulinsky) writes: > I hadn't realized that there was a limit to the size of the lists that > the X poly requests like XDrawLines can handle until recently, when I > read Kenton Lee's article 'Behind Curtain X' in June's Unix Review. There are currently some mumblings in the X community about an extension which will provide access to much larger request sizes, so that neither the application nor the API need break apart large requests. The extension is in the pre-proto-stages of development, from what I've heard so far. -- -paul pmartz@dsd.es.com Evans & Sutherland
tomt@maui.coral.COM (Tom Tulinsky) (06/15/91)
) ) > I hadn't realized that there was a limit to the size of the lists ) > that the X poly requests like XDrawLines can handle until recently, ) > when I read Kenton Lee's article 'Behind Curtain X' in June's Unix ) > Review. Here's some code which will draw lines with an arbitrary ) > length array of points. ) ) [code omitted; simply breaks up the list of points, calling XDrawLines ) multiple times.] ) ) > A couple of pointed questions: ) > - If it's so simple, why can't the Xlib do it for you? ) ) Because it's *not* so simple. Read the protocol spec for the PolyLine ) request. In particular, pay close attention to joins and the semantics ) of overlapping lines. Your "solution" produces at least the following ) violations: ) . . . Good point, correction accepted. I believe that my for loop will satisfy the protocol when the GC function is GXCopy because multiple drawing of pixels does not matter in this common case. Coral * ** Tom Tulinsky 508 460-6010 * ** Coral Network Corporation fax 508 481-6258 * ** 734 Forest St net: tomt@coral.com *** Marlboro, MA 01752 ** U S A ********* NETWORKS
mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (06/15/91)
>>> I hadn't realized that there was a limit to the size of the lists >>> that the X poly requests like XDrawLines can handle until [...] >>> A couple of pointed questions: >>> - If it's so simple, why can't the Xlib do it for you? >> Because it's *not* so simple. Read the protocol spec for the >> PolyLine request. In particular, pay close attention to joins and >> the semantics of overlapping lines. [...] > Good point, correction accepted. I believe that my for loop will > satisfy the protocol when the GC function is GXCopy because multiple > drawing of pixels does not matter in this common case. That's neither sufficient nor, strictly, necessary. It's true that overlap doesn't matter for graphics functions that don't depend on the destination (which means GXclear, GXcopy, GXcopyInverted, and GXset; GXcopy isn't the only one), but you also need to pay attention to the difference between line caps and line joins. Sometimes this doesn't matter; in particular if the cap is CapRound and the join is JoinRound it doesn't. But if, say, the cap is CapButt and the join is JoinMiter, it definitely does. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
pinkas@almond.intel.com (Israel Pinkas) (06/18/91)
In article <9106142040.AA25972@maui.coral.com> tomt@maui.coral.COM (Tom Tulinsky) writes: > ) > I hadn't realized that there was a limit to the size of the lists > ) > that the X poly requests like XDrawLines can handle until recently, > ) > when I read Kenton Lee's article 'Behind Curtain X' in June's Unix > ) > Review. Here's some code which will draw lines with an arbitrary > ) > length array of points. > ) > ) [code omitted; simply breaks up the list of points, calling XDrawLines > ) multiple times.] > ) > ) > A couple of pointed questions: > ) > - If it's so simple, why can't the Xlib do it for you? > ) > ) Because it's *not* so simple. Read the protocol spec for the PolyLine > ) request. In particular, pay close attention to joins and the semantics > ) of overlapping lines. Your "solution" produces at least the following > ) violations: > ) . . . > Good point, correction accepted. I believe that my for loop will > satisfy the protocol when the GC function is GXCopy because multiple > drawing of pixels does not matter in this common case. Nope. Line joins are not the same as the line ends. The only time your code will work is if the line join and the line end are both round (JoinRound and CapRound). There is no way to get the line caps to emulate JoinBevel or JoinMiter. In addition, CapProjecting and CapRound modify pixels that the various joins might not modify. This makes things very painful for wide lines. Try breaking the following up: CapProjecting JoinRound LineWidth=10 50,50 - 100,50 - 100,100 If you know that the lines are wide, you might be able to cheat in the GXCopy case be drawing each segment of the line twice, creating a closed loop. MultiLine requests that form a closed loop are treated as a polygon, which means that there are no caps, only joins. Please note that breaking requests apart will not work if the line is segmented. The segments are supposed to start at the beginning of the line and go to the end. Breaking the request will cause each part to start the pattern over. -Israel Pinkas Intel Corp -- -------------------------------------- Disclaimer: The above are my personal opinions, and in no way represent the opinions of Intel Corporation. In no way should the above be taken to be a statement of Intel. UUCP: {amdcad,decwrl,hplabs,oliveb,pur-ee,qantel}!intelca!mipos3!st860!pinkas ARPA: pinkas%st860.intel.com@relay.cs.net CSNET: pinkas@st860.intel.com