GEOS SDK TechDocs|
|
8.6 Editing GStrings Dynamically |
9 Graphics Paths GrGetGStringElement(), GrParseGString()
For complicated GString operations, you may find the following advanced routines helpful.
GrGetGStringElement()
returns the raw data associated with the current GString element. To understand this stream of bytes, you must know what sorts of data are associated with each kind of GString element. For example
GrGetGStringElement ()
might return GR_DRAW_RECT with the following buffer of bytes:
GR_DRAW_RECT, 0x00, 0x48, 0x00, 0x24, 0x00, 0x90, 0x00, 0x84
You must know enough about GString element structures to know that this will draw a rectangle with bounds {72, 36, 144, 108}. To find out this sort of information, examine the GS...() macros, or search
gstring.h
for macros containing the appropriate
GStringElement
value.
Code Display 23-9 GrGetGStringElement() In Action
/* Our application allows for a second kind of spline, a B-spline. This spline * looks similar to a regular Bézier spline, but is somewhat different and uses * a different mathematical formula. When this app creates a GString, it will * output Bézier splines in the normal way.
* When outputting a B-spline to a GString, it outputs the GString element for a * regular spline. That way, other applications will be able to draw the GString * mostly correctly. However, all B-spline elements will be preceded by a * GString comment 'B''s''p''l'.:
* GSComment(4), 'B','s','p','l', * GSDrawSpline(...), ...
* The following snippet of code will be used when this application draws a * GString. It will look for the significant comments. When it finds them, it will * know that the following GR_DRAW_SPLINE element should actually be treated * differently. */
for ( gsr = GrDrawGString(gstate, gstring, 0, 0, GSC_MISC, gse);
gsr == GSRT_MISC;
gsr = GrDrawGString(gstate, gstring, 0, 0, GSC_MISC, gse) )
{byte canonicalBuffer[] = {GR_COMMENT,'B','s','p','l'};
byte buffer[20];
int eSize;
GrGetGStringElement(gstate, gstring, sizeof(buffer),&buffer, &eSize);
/* First check to see if this is the
* comment we're looking for: */
if (strncmp(buffer, canonicalBuffer, 5)) {
/* Skip ahead to the GrDrawSpline element */
GrSetGStringPos(gstring, GSSPT_SKIP_1, 0);
GrGetGStringElement(gstate, gstring,
sizeof(buffer), &buffer, &eSize);
/* Draw spline using our routine */
MyDrawBSpline(gstate, buffer+3,
(eSize-3)/sizeof(Point))
/* Advance GString so kernel won't draw a
* Bézier spline over our B-spline. */
GrSetGStringPos(gstring, GSSPT_SKIP_1, 0) }
}
The
GrParseGString()
command calls a callback routine on all elements of a GString which match some criterion. The routine may save information about the elements, draw to a GState, or something completely different.
GrParseGString()
takes the following arguments:
GrParseGString()
itself will do nothing with this handle, and passing a NULL handle is permitted. However, this GState will be passed to the callback routine. If your callback routine will draw, it is thus convenient to pass a properly initialized GState to
GrParseGString()
which the callback routine may then draw to.
GSControl
. This will determine which elements will be passed on to the callback routine. If you set GSC_OUTPUT, the callback routine will be called only for those GString elements which draw something. If you set GSC_ONE, the callback routine will be called upon all of the GString elements.
The callback routine is passed a pointer to the GString element and the handle of the GState that was passed to
GrParseGString()
.
GEOS SDK TechDocs|
|
8.6 Editing GStrings Dynamically |
9 Graphics Paths