GPIGuide - Marker Primitives
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation
Marker primitives are graphics objects—such as stars, dots, or crosses—that are used, for example, to indicate plotted points on a line graph.
Related Topics
- Presentation spaces
- Line and arc primitives
- Color and mix attributes
- Fonts
About Marker Primitives
Marker primitives are always drawn centered over a point. In a designated presentation space, GpiMarker draws a single marker primitive of the current marker symbol, with its center at a specified position. This position becomes the new current position when the marker is drawn.
Another marker function, GpiPolyMarker, draws multiple marker primitives in the designated presentation space. Each marker primitive is centered over a position specified in an input array to GpiPolyMarker. All marker primitives drawn by a single call to GpiPolyMarker use the same (current) marker symbol. When a series of marker primitives is drawn, the current position is the center point of the last marker in the series.
An example sequence of diamond-shaped marker primitives can be drawn on a line graph at (1,2), (3,4), (4,3), (7,5), (8,4), (9,8), (10,6), and (11,6). The new current position is at (11,6). This marker sequence could be drawn with a single call to GpiPolyMarker or with eight separate GpiMarker calls.
Attributes of Marker Primitives
Marker primitive attributes are contained in a data structure called MARKERBUNDLE. The attributes are:
- Marker symbol
- Marker box
- Marker set
- Foreground color
- Background color
- Foreground mix attribute
- Background mix attribute
When an application creates a presentation space, the marker attributes are set to the default values shown in the following table.
Marker Attribute Default Values
Attribute | Default Value | Function that Redefines Attribute |
---|---|---|
Marker symbol | Cross | GpiSetMarker |
Marker box | Device dependent; equal to the size of one character | GpiSetMarkerBox |
Marker set | LCID_DEFAULT | GpiSetMarkerSet Note: If this default is changed, the base marker set cannot be reselected with GpiSetMarkerSet. |
Foreground color | Black | GpiSetAttrs (MBB_COLOR) |
Background color | Clear | GpiSetAttrs (MBB_BACK_COLOR) |
Foreground mix | Overpaint | GpiSetAttrs (MBB_MIX_MODE) |
Background mix | Leave alone | GpiSetAttrs (MBB_BACK_MIX_MODE) |
Marker Symbols
The current marker symbol is selected from the current marker set using GpiSetMarker. The marker symbol selected for the specified presentation space is used for all subsequent GpiMarker and GpiPolyMarker calls until a new symbol is selected.
The following table describes the marker symbols provided by the PM in a base marker set. These symbols are not necessarily available from other marker sets.
The Base Marker Set
Symbol | Identifier | Long Value |
---|---|---|
Cross | MARKSYM_CROSS | 1L |
Plus sign | MARKSYM_PLUS | 2L |
Diamond | MARKSYM_DIAMOND | 3L |
Square | MARKSYM_SQUARE | 4L |
Six-point star | MARKSYM_SIXPOINTSTAR | 5L |
Eight-point star | MARKSYM_EIGHTPOINTSTAR | 6L |
Solid diamond | MARKSYM_SOLIDDIAMOND | 7L |
Solid square | MARKSYM_SOLIDSQUARE | 8L |
Dot | MARKSYM_DOT | 9L |
Small circle | MARKSYM_SMALLCIRCLE | 10L |
Blank (invisible marker) | MARKSYM_BLANK | 64L |
The default marker symbol (MARKSYM_DEFAULT) is identical to the MARKSYM_CROSS symbol and has a long value of 0L. The error marker symbol (MARKSYM_ERROR) has a long value of -1L. Your application can determine the marker set with GpiQueryMarkerSet.
Marker Box
The marker box is a rectangular boundary that defines the horizontal and vertical space occupied by the marker symbol. The marker box is used to center the current marker symbol.
If the current marker set contains vector marker primitives (characters outlined by using line and arc functions), changing the size of the marker box changes the size of the marker primitives also. When you change the size of the marker box, a vector marker symbol is scaled up or down automatically to fit the box. Image marker primitives, however, cannot be scaled. If the current marker set contains image characters, the marker box dimensions are fixed, because you cannot alter the size of image markers.
You can use GpiSetMarkerBox to change the size of the marker box for a particular presentation space. Set the value of the appropriate SIZEF structure to the required size. The new size is expressed in world coordinates and should not contain any fractional values.
The default size of the marker box can be determined using DevQueryCaps. The values, CAPS_MARKER_WIDTH and CAPS_MARKER_HEIGHT, depend on the currently associated device and the presentation page. Marker box values set with GpiSetMarkerBox can be determined using GpiQueryMarkerBox.
GpiSetAttrs also can be used to change the size of the marker box. GpiSetDefAttrs can be used to change the default size of the marker box.
Marker Set
When you create a presentation space, the current marker set, along with other marker attributes, is set to default. The current marker symbol (the cross described earlier) is specified from the supplied marker set. The supplied set of marker primitives contains only image, or raster, marker primitives.
The marker primitives in the default marker set are drawn by setting the color of the pels in the marker box. Within the marker box, the color of the set pels defines the foreground color. The default foreground color is neutral—black on the display screen and on printers.
The color of the pels that are not set defines the background color. The default background color is the background color on the device—white on the display screen, and the loaded paper color on printers. The default background mix is LEAVE_ALONE, or transparent, which means the background color is irrelevant.
If the default set is changed using GpiSetDefAttrs, its markers are not accessible. The markers from the default set can be recovered by calling GpiSetDefAttrs and specifying the value LCID_DEFAULT (0).
Customizing Marker Sets
If the current marker set does not contain a symbol that suits your application, you can load a new marker set and select a marker symbol from that set. The only way to see the current marker set is to display it on the screen or view a hardcopy of the symbols. You load a new marker set for a specified presentation space by creating a logical font. Then you select the font as a marker set by specifying the logical font identifier (lcid) as an input parameter to GpiSetMarkerSet. After selecting the marker set, call GpiSetMarker to select a marker from the set. You can set both values simultaneously with GpiSetAttrs.
You can use any font's character set as a marker set and any character within that marker set as a marker. To determine the value that identifies the current marker set, call GpiQueryMarkerSet. To determine the value that identifies the current marker character, call GpiQueryMarker. You can retrieve both values simultaneously with GpiQueryAttrs. You also can create image marker symbols using the Font Editor.
Marker Color and Mix Attributes
The color attribute defines the color used to draw a primitive or an object. The mix attribute determines how the color of a primitive or an object is combined with the color of the drawing surface, or any other objects on the surface.
The marker color defines the color used to draw the output from any of the OS/2 marker functions. When a presentation space is created, the marker color initial default is black. Markers are one of the primitives that have a foreground and background color. For image markers, the colors are determined by the setting of pels. For vector markers, the foreground consists of the arcs and lines that define the marker. The background color appears between the foreground lines. The marker can be solid, or filled, in which case the background color does not appear between the foreground lines.
Marker primitives have both a color and background color attribute. The mix attribute controls the combination of marker color with drawing-surface color, while the background mix attribute controls the combination of the marker box color with the drawing-surface color.
When a presentation space is created, the marker mix attribute initial default is FM_OVERPAINT. The overpaint mix attribute specifies that the marker color is not to be modified by the color of the drawing surface. If the marker mix attribute is changed, the marker color is mixed with colors that are already on the drawing surface.
The marker background color initial default is CLR_BACKGROUND, usually defined by the application to the same color as the drawing surface. The marker background mix attribute initial default is BM_LEAVEALONE. The leave-alone mix background attribute specifies that the marker background color is not drawn. The box that effectively surrounds the marker appears only if the marker background mix attribute is changed.
To specify a new color or mix attribute, call GpiSetAttrs. This function accepts as input the type of primitive (e.g., PRIM_MARKER), a list of attributes to be changed, a list of attributes to be set to their default values, and the values for the attributes to be changed. GpiSetAttrs is useful to specify colors and mix attributes just for a specific data structure (e.g., MARKERBUNDLE) and provides some protection against invalid colors.
To determine the current marker color and mix attribute, call GpiQueryAttrs. This function accepts as input the primitive type and the attributes in question and returns an array of values for the specifically queried attributes.
To reset the default marker color and mix attribute, just as with any other attribute specified in the MARKERBUNDLE data structure, call GpiSetDefAttrs. This function accepts as input the type of primitive (e.g., PRIM_MARKER), the attributes to be changed, and the values that will become the new default values. Changing default values is important when working with segments. Changing the default values during a series of drawing functions is not recommended.
The marker color and mix attribute also can be specified with:
However, these functions specify the foreground and background color or mix attribute for all primitive BUNDLE data structures that have the respective component.
There are four query functions that determine the color and mix attribute as specified by GpiSet functions:
If the marker color, marker background color, mix attribute, or background mix attribute were specified individually, these queries can return a value inconsistent with the current marker attribute.
Using Marker Primitives
You can use marker functions to:
- Draw a single marker or a series of markers
- Set or determine (query) any combination of the marker bundle attributes, including:
- Determining the lcid for the current marker set
- Selecting a character set as the new marker set
- Determining the value that identifies the current marker
- Selecting a character as the new marker
- Setting or changing the size of the marker box
- Setting or changing the color of a marker
Drawing Marker Primitives
You can draw either a single marker or a series of markers using the current marker symbol. To draw a single marker, set the fields in a POINTL structure to correspond to the desired position in world coordinates. Then call GpiMarker, passing it the address of the POINTL structure as the second argument.
To draw a series of markers, set the fields in an array of POINTL structures to correspond to the desired positions in world coordinates. Then call GpiPolyMarker, passing it the number of points in the array as the second argument and the name of the array as the third argument.
The following example shows how to draw a graph with GpiPolyLine and GpiPolyMarker.
#include <os2.h> void fncMARK01(void) { HPS hps; /* Presentation-space handle */ POINTL aptl[6]; /* Array of points */ aptl[0].x = 10; aptl[0].y = 15; /* Assigns points */ aptl[1].x = 150; aptl[1].y = 30; aptl[2].x = 200; aptl[2].y = 32; aptl[3].x = 250; aptl[3].y = 70; aptl[4].x = 360; aptl[4].y = 120; aptl[5].x = 380; aptl[5].y = 98; GpiPolyMarker(hps, sizeof(aptl) / sizeof(POINTL), aptl); /* Plots points */ GpiMove(hps, aptl); /* Sets current position */ GpiPolyLine(hps, sizeof(aptl) / sizeof(POINTL), aptl); /* Draws lines */ } /* fncMARK01 */
Selecting a New Marker
The following example shows how to check whether the default marker primitive from the default marker set is being used currently, and if so, how to replace the cross with the six-pointed star.
#define INCL_GPIPRIMITIVES #include <os2.h> void fncMARK02(void) { HPS hps; if ((GpiQueryMarker(hps) == MARKSYM_DEFAULT) && (GpiQueryMarkerSet(hps) == LCID_DEFAULT)) GpiSetMarker(hps, MARKSYM_SIXPOINTSTAR); }
Selecting a New Marker Set
The following example shows how to load a Helvetica vector font, select it as the new marker set, and select the uppercase A as the new marker primitive.
#define INCL_GPILCIDS #define INCL_GPIPRIMITIVES #include <os2.h> void fncMARK03(void) { LONG cHelvFonts, cFonts, lcid, i, j; HPS hps; FATTRS fattrs; FONTMETRICS afm[80]; MARKERBUNDLE mbnd; cHelvFonts = GpiQueryFonts(hps, QF_PUBLIC, "Helv", &cFonts, sizeof(FONTMETRICS), (PFONTMETRICS) NULL); /* Queries the number of Helvetica fonts. */ GpiQueryFonts(hps, QF_PUBLIC, "Helv", &cHelvFonts, sizeof(FONTMETRICS), afm); /* Loads the array of FONTMETRICS structures. */ for (i = 0; !(afm[i].fsDefn & FM_DEFN_OUTLINE) && i < cHelvFonts; i++); /* Finds outline font */ fattrs.usRecordLength = sizeof(FATTRS); fattrs.fsSelection = 0; fattrs.lMatch = afm[i].lMatch; /* Uses Helvetica outline font */ for (j = 0; j <= sizeof(afm[i].szFacename); j++) fattrs.szFacename[j] = afm[i].szFacename[j]; fattrs.idRegistry = 0; fattrs.usCodePage = 850; /* Uses international code page */ fattrs.lMaxBaselineExt = 0; fattrs.lAveCharWidth = 0; fattrs.fsType = 0; fattrs.fsFontUse = FATTR_FONTUSE_TRANSFORMABLE; GpiCreateLogFont(hps, (PSTR8) NULL, lcid, &fattrs); mbnd.usSet = lcid; /* Uses font as marker set */ mbnd.usSymbol = 'A'; /* Uses capital A as primitive */ GpiSetAttrs(hps, PRIM_MARKER, MBB_SYMBOL | MBB_SET, 0, &mbnd); } /* fncMARK03 */
Changing the Marker Color
The following example shows how to set the marker foreground color to green.
#define INCL_GPIPRIMITIVES #include <os2.h> void fncMARK04(void) { HPS hps; MARKERBUNDLE mbnd; mbnd.lColor = CLR_GREEN; GpiSetAttrs(hps, PRIM_MARKER, MBB_COLOR, 0L, &mbnd); } /* fncMARK04 */