Jump to content

GPIGuide - Marker Primitives

From EDM2
Revision as of 03:57, 14 May 2025 by Martini (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

GPI Guide and Reference
  1. How to Use the GPI Guide and Reference
  2. Graphics Functions
  3. Data Types
  4. Graphics Orders
  5. Graphics Orders Data Types
  6. Errors
  7. Area and Polygon Primitives
  8. Bit Maps
  9. Creating and Drawing Retained Graphics
  10. Character String Primitives
  11. Clipping and Boundary Determination
  12. Color and Mix Attributes
  13. Correlation
  14. Coordinate Spaces and Transformations
  15. Editing Retained Graphics and Graphics Segments
  16. Fonts
  17. Graphics Attributes
  18. Line and Arc Primitives
  19. Marker Primitives
  20. Matrix Multiplication
  21. Metafiles
  22. Print Job Submission and Manipulation
  23. Presentation Spaces and Device Contexts
  24. Paths
  25. Regions
  26. Notices
  27. Glossary

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 */