GPIGuide - Creating and Drawing Retained Graphics: Difference between revisions
(3 intermediate revisions by the same user not shown) | |||
Line 191: | Line 191: | ||
# Root segment 3 | # Root segment 3 | ||
[[Image:img14.png | [[Image:img14.png|Chained and Called Segments]] | ||
Chained and Called Segments | |||
Segment A is called by root segment 1, and segment B is called by both segment A and root segment 2. Segment C calls segment D. Both C and D are unchained segments that are not called from the segment chain, and consequently, are not part of the segment chain. | Segment A is called by root segment 1, and segment B is called by both segment A and root segment 2. Segment C calls segment D. Both C and D are unchained segments that are not called from the segment chain, and consequently, are not part of the segment chain. | ||
Line 221: | Line 219: | ||
# Segment B | # Segment B | ||
[[Image:img15.png | [[Image:img15.png|Chained and called segments reordered using GpiSetSegmentPriority]] | ||
Chained and called segments reordered using | |||
=== Segment Priority === | === Segment Priority === | ||
Line 232: | Line 228: | ||
[[GpiDrawSegment]] accepts as input any segment name. | [[GpiDrawSegment]] accepts as input any segment name. | ||
===GpiDrawFrom === | ===GpiDrawFrom === | ||
Line 270: | Line 265: | ||
[[GpiRestorePS]] retrieves the saved information from the LIFO stack and reapplies it to the presentation space. Input to this function can be either the identifier returned to you from GpiSavePS or a relative value. A relative value of -1, for example, retrieves the information most recently stored on the stack. You do not have to restore the information that was most recently saved. However, any data that you skip over is discarded. | [[GpiRestorePS]] retrieves the saved information from the LIFO stack and reapplies it to the presentation space. Input to this function can be either the identifier returned to you from GpiSavePS or a relative value. A relative value of -1, for example, retrieves the information most recently stored on the stack. You do not have to restore the information that was most recently saved. However, any data that you skip over is discarded. | ||
[[Image:img16.png | [[Image:img16.png|A LIFO Stack with Four Items]] | ||
A LIFO Stack with Four Items | |||
===GpiResetPS=== | ===GpiResetPS=== | ||
Line 355: | Line 348: | ||
*Set the drawing mode to DM_RETAIN. | *Set the drawing mode to DM_RETAIN. | ||
*Check to see whether the chained attribute is one of the initial segment attributes using GpiQueryInitialSegmentAttrs. | *Check to see whether the chained attribute is one of the initial segment attributes using [[GpiQueryInitialSegmentAttrs]]. | ||
*Set the chained attribute, if necessary, with GpiSetInitialSegmentAttrs. | *Set the chained attribute, if necessary, with [[GpiSetInitialSegmentAttrs]]. | ||
*Open the segment using GpiOpenSegment. | *Open the segment using [[GpiOpenSegment]]. | ||
*Perform the necessary drawing operations. | *Perform the necessary drawing operations. | ||
*Close the segment using GpiCloseSegment. | *Close the segment using [[GpiCloseSegment]]. | ||
The following figure shows an example of how to draw a box in a called segment. | The following figure shows an example of how to draw a box in a called segment. | ||
Line 387: | Line 380: | ||
</pre> | </pre> | ||
===Drawing a Segment Chain === | ===Drawing a Segment Chain === | ||
The following figure shows an example of how to draw a segment chain using GpiDrawChain. | The following figure shows an example of how to draw a segment chain using [[GpiDrawChain]]. | ||
<pre> | <pre> | ||
#define INCL_GPICONTROL | #define INCL_GPICONTROL |
Latest revision as of 18:04, 14 May 2025
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation
There are two types of graphics output in the OS/2 operating system:
- Retained graphics, which are stored in segments and can be redrawn or edited when necessary.
- Nonretained graphics, which are drawn immediately but not stored and therefore cannot be used again without repeating the graphics functions needed to re-create the picture.
This chapter describes the advantages of using retained graphics and provides information on creating and drawing retained graphics. The following topics are related to the information in this chapter:
- Presentation spaces and device contexts
- Coordinate spaces and transformations
- Editing retained graphics and graphics segments
About Creating and Drawing Retained Graphics
An application draws by calling graphics functions. Applications store retained graphics in segments, which can be edited. This means that the retained image can be modified without having to re-create the unmodified portion using multiple GPI functions.
When using nonretained graphics, the output appears on the output device (for example, a window) immediately. However, if part of the picture is erased or must be repeated, the application must call the same graphics functions a second, or even a third time.
There are many other advantages to using retained graphics, including:
- Convenience - An application can draw retained graphics with a single function that accesses the storage area containing all the individual functions necessary for the object.
- Flexibility - An application can redraw graphics retained in the segment store to any number of device contexts.
- Editing - An application can modify an object without having to call all the functions necessary to re-create the picture. Individual segments can be moved, scaled, or rotated; then, redrawn.
- Editing the graphics within a segment is described in Editing Retained Graphics and Graphics Segments.
- Power - An application can access the more powerful and useful graphics functions only when graphics are stored in segments.
- Organization - An application can use segments to store the components that will be assembled into the final picture.
Primarily, a graphics segment is a means of grouping and storing graphics primitives and their attributes. Although the graphics within a segment usually are related in some way, they do not have to be. A segment might contain a number of unrelated GPI functions that you want to keep and execute at specific times.
Retained graphics do affect application performance, however, in that a normal presentation space requires 114KB of main memory more than a micro presentation space, and using the drawing mode DM_RETAIN adds an additional 46KB.
Note: Your application can have up to 16KB (16378) segments in the segment store of a single presentation space. The size of an individual segment is limited only by the amount of storage available to you.
Do not confuse a graphics segment with a memory segment.
Drawing Modes
When you create a presentation space, the drawing mode is set to draw. Your application can change this mode using GpiSetDrawingMode. The two additional drawing modes provided by the PM are retain (DM_RETAIN) and draw-and-retain (DM_DRAWANDRETAIN). Your application can determine which drawing mode is set by using GpiQueryDrawingMode.
The drawing mode that you select becomes current for the presentation space, and it can be changed any number of times. Select the appropriate drawing mode before creating a segment. The drawing mode affects the segment type.
Draw Mode
In draw mode, graphics output is provided immediately to the currently associated device and is not retained in a segment store. When the graphics have been drawn, they cannot be used again unless they are re-created. For example, when a window containing draw mode graphics is moved or sized, the graphics have to be re-created by the application.
Draw mode graphics are suitable if an application is creating fairly simple graphics quickly or is maintaining its own graphics database. In the latter case, there is nothing to gain by retaining graphics.
A segment created when the drawing mode is DM_DRAW, is called a nonretained segment. While it might sound contradictory, nonretained segments have certain advantages that are described in Nonretained Graphic Segments.
Retain Mode
In retain mode, graphics are retained in the segment store only. They are not directed to the current device as they are created.
In retain mode, the presentation space does not have to be associated with a device context when graphics are being defined. It is possible to define graphics and store their definitions without sending them to a display screen or printer. The concept of attribute currentness, however, is relevant only when you are drawing graphics to an output device. For example, the color or other attribute that is current when you define a primitive is the color in which the line is drawn. That color or other attribute might not be the color that is current when you actually draw the primitive. This is described in Attribute Currentness.
Many of the GPI queries that return current attribute values are invalid in retain mode because current attribute values have no effect when graphics are not sent to an output device.
Draw-and-Retain Mode
In draw-and-retain mode, graphics are both drawn on the current device as they are created and stored for later use. The GPI queries that return current attribute values are valid in draw-and-retain mode.
Creating a Graphics Segment
Your application signals the start of a graphics segment using GpiOpenSegment, which is valid only in a normal presentation space. The following figure is an example of two segments in a presentation space.
Presentation Space ┌─────────────────────────────────────┐ │ │ │ Graphics Segment 1 │ │ ┌────────────┐ │ │ │ │ │ GpiOpenSegment (hps,1L); │ │ │ │ GpiSet... (hps,...); ──┼───┼────── │ │ GpiLine (hps,...); ──┼───┼── │ │ GpiCloseSegment (hps); │ │ │ Graphics Segment 2│ │ │ │ ┌────────────┐ │ │ │ │ │ │ │ │ └────────────┘ │ │ │ │ │ │ │ GpiOpenSegment (hps,2L); │ │ │ │ GpiSet... (hps,...); ──┼───────────────────┼───── │ │ GpiLine (hps,...); ──┼───────────────────┼── │ │ GpiCloseSegment (hps); │ │ │ │ │ └────────────┘ │ │ │ │ │ └─────────────────────────────────────┘
Graphics Segments in a Presentation Space
GpiOpenSegment accepts, as input, the presentation space handle and a long integer value, which names each segment.
OS/2 applications identify segments with long integer values. If you want to refer to the segment individually in later graphics operations (for example, to edit the segment) the identifier you supply must be greater than 0 and unique within the presentation space.
If you do not want to refer to the segment individually after it is created, you can give the segment an identifier of 0. You might do this when you are creating nonretained segments, for example. Any number of segments can have the 0 identifier. They are referred to throughout this book as zero segments.
To determine which names already have been used in a presentation space, use GpiQuerySegmentNames. This function returns an array of segment names for all retained segments, excluding zero segments, within a specified name range.
Segments do not have to be named in consecutive order (although it is recommended for organizational purposes) because the segment order can be changed using GpiSetSegmentPriority.
Filling a Graphics Segment
After a graphics segment is opened, the GPI functions that follow become a part of a retained segment and are executed every time the segment itself is drawn.
The typical GPI functions that would be called are those that:
- Create graphics primitives - such as lines or markers.
- Assign attributes to those primitives - such as color or line type.
However, there are a few GPI functions that you cannot call while there is an open segment - for example a second GpiOpenSegment. These functions are identified in GPI Function Context.
A presentation space can contain many segments. Each time you open a new segment, many attributes reset themselves to default values. Therefore, the current position and attribute values that apply before you call GpiOpenSegment cannot be guaranteed to be in effect after you call the function. Beginning each segment with a number of attribute-setting requests and, possibly, with GpiSetCurrentPosition, is recommended. Your application also might take advantage of GpiSetDefAttrs, for example, to minimize the number of attributes that must be dealt with upon opening a new segment.
Closing a Graphics Segment
When you have finished creating a graphics segment, close it using GpiCloseSegment. There can be only one open segment at a time in a single graphics presentation space, so you must close one segment before going on to the next.
There is some degree of clean-up processing associated with using GpiCloseSegment, known as close-segment processing, that can make current attribute values unreliable. For more information about the effects of GpiOpenSegment and GpiCloseSegment on current attributes, see Graphics Attributes.
Segment Attributes
Each segment, whether retained or nonretained, has a number of characteristics, called attributes that you can set in accordance with your application's requirements. The attributes of a segment are quite different from those of a graphics primitive in that segment attributes have ON and OFF settings. There are seven segment attributes. However, only two are described in this chapter: chained (ATTR_CHAINED) and fast-chained (ATTR_FASTCHAIN).
When an application creates a segment in a presentation space, the operating system assigns initial attributes to it. By default, five of the attributes will be set ON and two will be set OFF. The chained and fast-chained attributes are set ON. Your application can alter these values using GpiSetInitialSegmentAttrs or retrieve the values of the current initial attributes using GpiQueryInitialSegmentAttrs.
Chained Attribute
When you define a segment with the chained attribute switched ON, that segment becomes a part of the segment chain and is called a chained segment. The segment chain is composed of all chained segments defined in a single presentation space. Segments can be chained together so that they can be drawn as a group. By default, each new segment is chained to the previous segment.
There can be only one segment chain at a time in a single presentation space, and all chained segments are chained to each other in the order in which you created them. Zero segments must have the chained attribute.
Usually, a logical relationship exists between the segments in a segment chain, although this is not a requirement. The whole segment chain can be drawn using GpiDrawChain. Each segment in the chain is called a root segment. Root segments are affected by those GPI functions that act on the segment chain, but they also can be manipulated independently of the chain.
Segments that are defined with the chained attribute switched OFF are called unchained segments. Your application can switch off the chain attribute using GpiSetInitialSegmentAttrs (hps, ATTR_CHAIN, ATTR_OFF). Unchained segments always are retained when they are created, regardless of the current drawing-mode parameter. An unchained segment must have a unique name.
There are a number of reasons for defining a segment as unchained. For example, a particular segment might not belong to the picture that is defined by the segment chain. You also are likely to define as unchained any segment that belongs to the picture but that has no single, fixed place in the segment chain. A car wheel, for example, could be defined once but drawn four times in a picture of a car. It would have no single, fixed place in the segment chain, but would be included four times in the picture by being called from one or more root segments.
A segment is called from another segment by including GpiCallSegmentMatrix in the calling segment. A segment and the segments it calls logically are one object. An important point about called segments is that they assume the primitive attribute settings of the calling segment. Of course, you can change the attribute settings within the called segment if the inherited values are inappropriate.
A closed, unchained segment can be called from any other segment. Chained segments, however, cannot be called from other segments.
Fast-Chained Attribute
The fast-chained attribute applies only to chained segments. It prevents primitive attributes from being reset to their default values at the beginning of the segment, an aid to performance. There is unnecessary overhead in resetting attributes to their defaults if either of the following is true:
- You are going to change the default values of the attributes at the start of the segment.
- You know that attributes have not been altered previously from their default values.
The fast-chained attribute is switched ON by default, and you should leave it on unless you specifically want attributes to be set to their default values. To turn off the fast-chained attribute, call GpiSetInitialSegmentAttrs (hps, ATTR_FASTCHAIN, ATTR_OFF).
Actual Drawing Mode
The drawing mode, as defined by GpiSetDrawingMode, works in conjunction with the segment status to produce the actual drawing mode. It is the actual drawing mode that determines whether graphics are:
- Drawn directly to the output device
- Retained in the segment store
- Both drawn and retained
The actual drawing mode is summarized in the following table.
GpiSetDrawingMode parameter | Chained Segment | Unchained Segment | Outside of any segment |
---|---|---|---|
DM_DRAWANDRETAIN | draw-and-retain | retain | draw |
DM_RETAIN | retain | retain | draw |
DM_DRAW | draw | retain | draw |
As you can see in the preceding table, graphics within chained segments always conform to the current drawing mode parameter. That is, they are drawn in DM_DRAW mode, retained in DM_RETAIN mode, and both drawn and retained in DM_DRAWANDRETAIN mode.
Graphics in unchained segments always are retained, regardless of the current drawing-mode parameter. You cannot retain segments created when the current drawing-mode parameter is DM_DRAW, unless they are unchained segments.
Similarly, graphics outside segments always are drawn without being retained. You cannot retain primitives outside segments, regardless of the current drawing mode.
Note: A micro presentation space has no segment store. Therefore, you cannot create graphics segments in a micro presentation space, nor can you change the drawing mode, which is always DM_DRAW.
Drawing a Retained Graphic
Your application can draw a complete segment chain with GpiDrawChain. The segments are drawn in the order in which they appear in the chain. For example, the segments in the following figure are drawn in the following order:
- Root segment 1
- Unchained segment A
- Unchained segment B
- Root segment 2
- Unchained segment B
- Root segment 3
Segment A is called by root segment 1, and segment B is called by both segment A and root segment 2. Segment C calls segment D. Both C and D are unchained segments that are not called from the segment chain, and consequently, are not part of the segment chain.
GpiSetSegmentPriority changes the position of a root segment (which must not be a zero segment) in the chain. As input to this function, you supply the name of the segment you want to reorder and the name of a reference segment. The reference segment is the segment that either will be immediately before, or immediately after, the reordered segment's new position in the chain.
If the segment you are moving is to come after the reference segment in the chain, it is said to have a higher priority (HIGHER_PRI). If it is to come before the reference segment, it is said to have a lower priority (LOWER_PRI). The nearer a segment is to the end of the chain, the higher its priority.
If you supply the name of an unchained segment as input to GpiSetSegmentPriority, the segment is added to the chain in the position you specify. To learn the position of a segment in the chain, use GpiQuerySegmentPriority.
If your application called the following functions:
GpiSetSegmentPriority (hps, C, 2, LOWER_PRI)
GpiSetSegmentPriority (hps, 3, 0, HIGHER_PRI)
GpiSetSegmentPriority (hps, B, 0, LOWER_PRI)
the segment chain in the previous figure would appear as in the following figure; and GpiDrawChain would draw the segments in the following order:
- Root segment 3
- Root segment 1
- Unchained segment A
- Unchained segment B
- Segment C
- Unchained segment D
- Root segment 2
- Unchained segment B
- Segment B
Segment Priority
The priority of a segment, in conjunction with the current foreground and background mix attributes, affects how the picture is presented to the user. The segment with the highest priority is drawn last, and appears on top of the previously drawn primitives. Picture components in segments with low priorities risk being drawn over and never seen by the user. The mix attributes affect the graphics functions within each segment.
GpiDrawSegment
GpiDrawSegment accepts as input any segment name.
GpiDrawFrom
You can draw a smaller portion of the entire segment chain (but a larger portion than a single segment) using GpiDrawFrom. GpiDrawFrom, as input, a presentation space handle and two nonzero segment names, the first of which must be part of the segment chain. GpiDrawFrom then draws the segments, starting with the first and ending with the last, including all chained and called segments.
Attribute Modes
You can change primitive-attribute settings at any time. The new values you specify replace the existing values. For example, if the current foreground color is green and you change it to red, red replaces green as the foreground color attribute.
When you set primitive attributes within a retained or nonretained segment, you can save the existing attribute values on a last-in-first-out (LIFO) stack, from where they can later be retrieved and made current again. You do this by selecting either of the two attribute modes:
- AM_PRESERVE mode-Also known as push-and-set mode
- AM_NOPRESERVE mode-Also known as set mode.
In AM_NOPRESERVE mode, which is the default setting, existing attribute values are replaced by any new attribute values that you supply. In AM_PRESERVE mode, the existing attribute values are stored on a LIFO stack, and then the new values that you specify take effect. AM_PRESERVE mode also causes the current position to be saved if the position was specified using GpiSetCurrentPosition. If you use GpiMove to set the current position, the position is not saved, regardless of the attribute mode.
To select a current attribute mode, use GpiSetAttrMode. The current attribute mode affects subsequent attribute-setting requests in the presentation space. Attribute modes are not applicable to micro presentation spaces, because graphics segments can be created only in normal presentation spaces.
To retrieve an attribute value from the LIFO stack, use GpiPop, which pulls back the attribute that was stored most recently on the stack. You can retrieve more than one attribute value by supplying a number as an input parameter of this function. For example, if you specify 4, GpiPop retrieves the four attributes that were most recently stored on the stack. If each of the values retrieved applies the same type of attribute to the same primitive (for example, if all four are line-type settings), the last one to be retrieved (and, therefore, the first one on the stack) becomes the current setting.
If you save attribute values from any segment called from another segment, and do not retrieve the values using GpiPop, the values are restored automatically when the end of the segment is reached. If you save attribute values from any segment that is not called from another segment and do not explicitly restore those values using GpiPop, they are lost at the end of the segment.
The AM_PRESERVE mode is useful when you do not want attributes in calling segments to be overwritten by attributes specified in the called segments. This overwriting happens because a calling segment and the segments it calls are logically one object. Attribute changes within a called segment remain current upon return to the calling segment. If you set some attribute values at the start of a called segment, and the current attribute mode is AM_PRESERVE, the attribute values of the calling segment are stored on the LIFO stack. At the end of the called segment, the values on the stack are retrieved automatically so that the calling segment continues with its own attribute values.
Reusing the Presentation Space
A normal presentation space with segments retained in the segment store can be costly in terms of storage. Therefore, delete any presentation space that you no longer need, using GpiDestroyPS. If, for example, your application is using a series of presentation spaces, each with a different format, the creation and deletion activity also can be costly. The PM provides the following functions that let you reuse or redefine an existing presentation space so you can create a presentation space once and use it any number of times.
- GpiSavePS
- GpiRestorePS
- GpiResetPS
- GpiSetPS
GpiSavePS
GpiSavePS saves presentation space information (such as current primitive attributes and the current position) on a dedicated LIFO stack. The presentation space itself is unchanged; that is, it still exists, has the same presentation space handle, and the presentation page dimensions and format are the same.
Output from GpiSavePS is a number that identifies the saved information on the LIFO stack. An output of 3, for example, tells you that this is the third lot of presentation space data on the stack.
GpiRestorePS
GpiRestorePS retrieves the saved information from the LIFO stack and reapplies it to the presentation space. Input to this function can be either the identifier returned to you from GpiSavePS or a relative value. A relative value of -1, for example, retrieves the information most recently stored on the stack. You do not have to restore the information that was most recently saved. However, any data that you skip over is discarded.
GpiResetPS
When a presentation space is first created, it is in a neutral state. Current attributes are set to their initial default values. The current position is (0,0). The segment store contains no segments, and there are no application-defined resources, such as logical color tables.
You can return an existing presentation space to this state using GpiResetPS. GpiResetPS has three levels of reset activity, each more powerful than the last. These are:
- GRES_ATTRS, which is equivalent to the processing done by GpiCloseSegment.
- GRES_SEGMENTS, which is equivalent to creating a new presentation space, but without deleting any logical resources. All retained segments are deleted from the segment store.
- GRES_ALL, which is equivalent to creating a new presentation space.
GpiResetPS does not alter the size or format of the presentation page.
GpiSetPS
GpiSetPS redefines the size and format of the presentation page. The processing performed when you call GpiSetPS is similar to that performed by GpiCreatePS, except that the presentation space already exists. The presentation space is returned to a neutral state (which is the equivalent of requesting GRES_ALL using GpiResetPS), and the presentation page is redefined. For example, you can change a presentation page defined in 0.01mm units to one defined in pels. Essentially, this lets you work with a new presentation space without having to delete one and create another.
You also can use GpiSetPS to change the current mapping mode of a presentation space. To do this, use the PS_NORESET flag, which is the equivalent of requesting GRES_SEGMENTS using GpiResetPS. This feature is particularly useful if you are designing an application that deals with page layout and drafting, or if you want the screen size to correspond to the page size for the printed output.
Nonretained Graphic Segments
It is valid segment construction to create a segment bracket while the drawing mode is DM_DRAW. The GPI functions contained within the bracket are drawn immediately rather than being retained for future use. This type of segment is called a nonretained segment.
Because the usual reason for constructing segments is to take advantage of retained graphics, nonretained segments might appear as a contradiction in terms at first. However, there are four particular advantages in their use:
- If ATTR_FASTCHAIN is set to OFF, the GpiOpenSegment implicitly resets all attributes to their defaults.
- The GpiOpenSegment and GpiCloseSegment initialize and reset the viewing transform matrix, just as they do for retained segments.
- Nonretained segments can be recorded in a metafile, just as a retained segment can.
- A graphic in a nonretained segment, with a unique name, can be converted easily to a retained graphic for future use.
Using Segment Creating and Drawing Functions
You can use retained-drawing and segment functions to:
- Create a chained or called segment
- Draw the picture associated with one or more segments
Creating a Chained Segment
To create a chained segment, you must:
- Set the drawing mode to DM_RETAIN.
- Check to see if the chained attribute is one of the initial segment attributes using GpiQueryInitialSegmentAttrs.
- Set the chained attribute, if necessary, with GpiSetInitialSegmentAttrs.
- Open the segment using GpiOpenSegment.
- Perform the necessary drawing operations.
- Close the segment using GpiCloseSegment.
The following figure is an example of a segment containing a box primitive and calling another segment using GpiCallSegmentMatrix.
#define INCL_GPISEGMENTS#define INCL_GPITRANSFORMS #include <os2.h> void fncSEGS01(void){ POINTL ptl; HPS hps; LONG idSegment = 1; LONG idNonChained = 2; MATRIXLF matlfTransform = { MAKEFIXED(2,0), MAKEFIXED(0,0), 0, MAKEFIXED(0,0), MAKEFIXED(1,0), 0, 0, 0, 1 }; /************************************************************************/ /* Turns chaining on. Adds the new segment to the segment chain. */ /* Segment idNonChained is called, whether chained or not. */ /************************************************************************/ if (ATTR_OFF == GpiQueryInitialSegmentAttrs(hps, ATTR_CHAINED) GpiSetInitialSegmentAttrs(hps, ATTR_CHAINED, ATTR_ON); GpiOpenSegment(hps, idSegment); ptl.x = 150; ptl.y = 150; GpiMove(hps, &ptl); ptl.x = 225; ptl.y = 225; GpiBox(hps, DRO_FILL, &ptl, 0L, 0L); GpiCallSegmentMatrix(hps, idNonChained, 9L, &matlfTransform, TRANSFORM_REPLACE); GpiCloseSegment(hps); } /* fncSEGS01 */
Creating a Called Segment
To create a called segment, you must:
- Set the drawing mode to DM_RETAIN.
- Check to see whether the chained attribute is one of the initial segment attributes using GpiQueryInitialSegmentAttrs.
- Set the chained attribute, if necessary, with GpiSetInitialSegmentAttrs.
- Open the segment using GpiOpenSegment.
- Perform the necessary drawing operations.
- Close the segment using GpiCloseSegment.
The following figure shows an example of how to draw a box in a called segment.
#define INCL_GPISEGMENTS#define INCL_GPICONTROL #include <os2.h> void fncSEGS02(void){ POINTL ptl; HPS hps; LONG idNonChained = 2; GpiSetDrawingMode(hps, DM_RETAIN); /* Creates a non-chained segment. */ if (ATTR_ON == GpiQueryInitialSegmentAttrs(hps, ATTR_CHAINED)) GpiSetInitialSegmentAttrs(hps, ATTR_CHAINED, ATTR_OFF); GpiOpenSegment(hps, idNonChained); ptl.x = 100; ptl.y = 100; GpiMove(hps, &ptl); ptl.x = 200; ptl.y = 200; GpiLine(hps, &ptl); GpiCloseSegment(hps); } /* fncSEGS02 */
Drawing a Segment Chain
The following figure shows an example of how to draw a segment chain using GpiDrawChain.
#define INCL_GPICONTROL #include <os2.h> void fncSEGS03(void){ HPS hps; if (DM_DRAW != GpiQueryDrawingMode(hps)) GpiSetDrawingMode(hps, DM_DRAW); GpiDrawChain(hps); } /* fncSEGS03 */