GEOS SDK TechDocs|
|
8.4 Creating GStrings Dynamically |
8.6 Editing GStrings Dynamically GrDrawGString(), GrDrawGStringAtCP(), GrSetGStringPos(), GrGetGStringBounds(), GrGetGStringBoundsDWord()
There are several ways to use a GString. You've already seen how to use one as the visual moniker for a UI gadget. In that case, the UI is responsible for drawing the moniker. If you are learning about interfacing with printers, you probably know that you pass a GString to a PrintControl object to describe print jobs.
There is also a kernel graphics routine for drawing GStrings directly. The
GrDrawGString()
command draws a GString, or a part thereof. Remember that the GString must be loaded for drawing; you must call
GrLoadGString()
if you have not done so already (or if you have destroyed the GString since you last called
GrLoadGString()
).
Code Display 23-7 GrDrawGString() in Action
@method StaticContentClass, MSG_VIS_DRAW {
word lElem;
static const byte gstringData[] = {
GSSetAreaColorIndex(C_RED), GSFillRect(0, 0, 72, 72),
GSEndString() };
@callsuper();
gstring = GrLoadGString (PtrToSegment(gstringData), GST_PTR,
PtrToOffset(gstringData));
GrDrawGString(gstate, gstring, 0, 0, 0, &lElem); }
@method DynamicContentClass, MSG_VIS_DRAW{
Handle gstring;
VMFileHandle file;
char fileString[] = ".", 0;
VMBlockHandle gstringData;
GStringElement lElem;
@callsuper(); file = VMOpen(fileString, (VMAF_FORCE_READ_WRITE | VMAF_USE_BLOCK_LEVEL_SYNCHRONIZATION), VMO_CREATE_TRUNCATE, 0);
gstring = GrCreateGString(file, GST_VMEM, &gstringData); GrSetAreaColor(gstring, CF_INDEX, C_RED, 0, 0); GrFillRect(gstring, 0, 0, 72, 72); GrEndGString(gstring); GrDestroyGString(gstring, NULL, GSKT_LEAVE_DATA);
gstring = GrLoadGString(file, GST_VMEM, gstringData); GrDrawGString(gstate, gstring, 0, 0, 0, &lElem); GrDestroyGString(gstring, NULL, GSKT_DESTROY_DATA);
FileDelete(fileString);
The
GrDrawGString()
routine has several arguments. A simple usage of the routine is shown in GrDrawGString() in Action. To take advantage of some of the more powerful features of
GrDrawGString()
, you should know what the purpose of the arguments.
GrSaveState()
on the GState before drawing the GString (and call
GrRestoreState()
afterwards). If you will draw anything else to this GState after the GString, you must call
GrDestroyGString()
on the GString, and pass this GState's handle as the gstate argument so that
GrDestroyGString()
can clean up the GState.
GrLoadGString()
).
GSControl
argument which requests that the system stop drawing the GString when it encounters a certain type of GString element. If the GString interpreter encounters one of these elements, it will immediately stop drawing. The GString will remember where it stopped drawing. If you call
GrDrawGString()
with that same GString, it will continue drawing where you left off. Note that any time a GString-traversing function such as
GrDrawGString()
returns, it returns a
GSRetType
value which makes it clear exactly why it stopped traversing the GString.
GStringElement
structure.
GrDrawGString()
will return a value here when it is finished drawing. If the GString has stopped drawing partway through due to a passed
GSControl
, the returned
GStringElement
value will tell you what sort of command was responsible for halting drawing. For instance, if you had instructed
GrDrawGString()
to halt on an `output' element (GrDraw...() or GrFill...() commands), then when
GrDrawGString()
returns, you would check the value returned to see what sort of output element was present.Note that those last two arguments aren't very useful except when used in conjunction with some other GString routines which we will get to later.
The
GrDrawGStringAtCP()
routine functions in much the same way as
GrDrawGString()
, except that the current pen position will be used in the place of passed coordinate arguments.
The
GrSetGStringPos()
routine allows you to skip any number of GString elements, or go back to the beginning or end of the GString. You specify whether you want to skip to the beginning, end, or ahead by a few steps; this is specified by the
GStringSetPosType
argument. This routine is useful both when drawing and editing GStrings. Note that you may also use this routine to jump backwards in a GString, but this only works with VM-based GStrings. The GString must be loaded for drawing or editing, and you will pass in the GString's global handle, as supplied by
GrLoadGString()
or
GrEditGString()
.
Code Display 23-8 GrSetGStringPos() In Action
/* The following routine is used to allow creating an `overlay' effect. Normally, * multi-page GStrings will contain form feed elements that signal the break * between pages. Here we see a section of code which will filter out form feeds by * skipping those elements. The result will be a single page in which all the pages * of the original GString are drawn on top of each other. */
for ( gsr = GrDrawGString(gstate, gstring, 0, 0, GSC_NEW_PAGE, gse);
gsr == GSR_FORM_FEED;
gsr = GrDrawGString(gstate, gstring, 0, 0, GSC_NEW_PAGE, gse) )
{GrSetGStringPos(gstring, GSSPT_SKIP_1, 0); }
Because a GString remembers its place when you stop drawing partway through, if you wish to `reset' the GString position, you should use
GrSetGStringPos()
to set it back to the beginning.
Occasionally you may be curious to know how much space is necessary to draw a GString. The
GrGetGStringBounds()
routine determines this, returning the coordinates describing the GString's bounding rectangle. If the GString may have very large bounds, you should use the
GrGetGStringBoundsDWord()
routine instead.
GEOS SDK TechDocs|
|
8.4 Creating GStrings Dynamically |
8.6 Editing GStrings Dynamically