Jump to content

GPIGuide - Area and Polygon Primitives

From EDM2
Revision as of 00:42, 24 April 2025 by Martini (talk | contribs)

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

An area is one or more closed figures that can be drawn filled, outlined, or filled and outlined. If an area includes more than one figure, those figures can be separate or intersecting.

A polygon , too, is one or more closed figures that can be drawn filled, outlined, or filled and outlined. Polygons, unlike areas, are limited to figures with straight edges. Polygons also can be separate or intersecting.

The following topics are related to information in this chapter:

  • Presentation spaces
  • Line and arc primitives
  • Color and mix attributes
  • Fonts
  • Bit maps
  • Paths

About Area Primitives

Applications can create, outline, and fill areas and can create custom-fill patterns from bit maps or font symbols. Some graphics functions are not valid within an area definition. For example, you cannot include marker, image, or character-string primitives in an area definition.

The following figure is an example of an area.

File:1030 L2 AboutAreaPrimitives 0.png

An Area

This area comprises two hexagons, one completely enclosed by the other. The area is filled with the current area-fill pattern.

Attributes of Area Primitives

The attributes of the area primitive are contained in a data structure called AREABUNDLE. These attributes are:

  • Pattern symbol
  • Pattern reference point
  • Pattern set
  • Foreground color
  • Background color
  • Foreground mix attribute
  • Background mix mode

When an application creates a presentation space, the area attributes are set to the default values shown in the following table.

Area Attribute Default Values
Attribute Default Value Function that Redefines Attribute
Pattern symbol solid GpiSetPattern
Pattern reference point (0,0) GpiSetPatternRefPoint
Pattern set LCID_DEFAULT GpiSetPatternSet
Foreground color Black GpiSetAttrs (ABB_COLOR)
Background color Clear GpiSetAttrs (ABB_BACK_COLOR)
Foreground mix Overpaint GpiSetAttrs (ABB_MIX_MODE)
Background mix Leave alone GpiSetAttrs (ABB_BACK_MIX_MODE)

Note: If the default (LCID_DEFAULT) for pattern set is changed, the base pattern set cannot be reselected with GpiSetPatternSet.

Pattern Symbol Attribute

The current pattern symbol, also called the symbol point code, is selected from the current pattern set with GpiSetPattern. The pattern symbol selected for the specified presentation space is used as the subsequent fill pattern until a new symbol is selected. Applications must not call GpiSetPattern while in an area or a path. If the current pattern set specifies a bit map, this attribute is ignored.

The following table describes the pattern symbols provided by the PM programming interface in a base pattern set. These symbols are not necessarily available from other pattern sets.

The Base Pattern Set
Symbol Identifier Long Value
Solid shading decreasing in dots per inch through PATSYM_DENSE8 PATSYM_DENSE1 through PATSYM_DENSE8 1L - 8L
Vertical lines PATSYM_VERT 9L
Horizontal lines PATSYM_HORIZ 10L
Lines bottom left to top right PATSYM_DIAG1 11L
Lines bottom left to middle right PATSYM_DIAG2 12L
Lines top left to bottom right PATSYM_DIAG3 13L
Lines top left to middle right PATSYM_DIAG4 14L
No shading PATSYM_NOSHADE 15L
Solid shading PATSYM_SOLID 16L
Alternate pels PATSYM_HALFTONE 17L
Cartesian grid PATSYM_HATCH 18L
Diagonal crosshatch PATSYM_DIAGHATCH 19L
Blank (often called the clear pattern) PATSYM_BLANK 64L

The default pattern symbol (PATSYM_DEFAULT) is identical to the PATSYM_SOLID symbol, and has a long value of 0L. The error pattern symbol (PATSYM_ERROR) has a long value of -1L.

The following figure shows the patterns from the base pattern symbol set. Applications can determine the current pattern set by calling GpiQueryPattern.

The Base Pattern Symbol Set

Pattern Reference Point Attribute

The pattern reference point is the point from which the area's fill-pattern spreads horizontally and vertically. The lower-left corner of the pattern is aligned on this point. The pattern reference point has a default value of (0,0), and is expressed in world coordinates. Applications can determine the pattern reference point with GpiQueryPatternRefPoint. Applications can specify the pattern reference point with GpiSetPatternRefPoint; however, this should not be done inside an area. The pattern reference point does not have to be within the boundary of the area. The following figure shows an area that was filled using the default pattern reference point.

The Pattern Reference Point

The pattern of diagonal lines is aligned with the pattern reference point (0,0). When the picture is displayed or printed, only the hexagon will be filled.

Use of the default reference point causes the diagonal lines of the pattern to intersect the area boundary at specific points. If you change the reference point to (0,4), for example, the pattern shifts upward, and the points of intersection with the area boundary are different. Although the reference point is outside the area, when an application displays or prints the picture, only the area is filled.

Pattern Set Attribute

When you create a presentation space, the current pattern set and other area attributes are set to the default. The current pattern-a black solid, as described earlier- is specified from the supplied pattern set. (The supplied set of pattern symbols contains image or raster patterns only.) An area primitive is filled by repeating this pattern vertically and horizontally within the area boundary.

Default Pattern Set

The standard pattern set contains patterns of solid shading with decreasing intensity, and patterns of vertical, horizontal, and diagonal lines. If the default pattern set is changed with GpiSetDefAttrs, its patterns are not accessible. The patterns from the default set can be recovered by specifying GpiSetDefAttrs with the value LCID_DEFAULT, (0).

Customizing Pattern Sets

An application can create custom patterns by using bit maps or characters and symbols from an image font. When designing custom patterns, consider that the operating system uses only the first eight bits in the first eight rows, starting with the lower-left corner of the bit map. The cell size of an image font used as a fill pattern might be too large to include the complete character or symbol.

An application can change the appearance of a fill pattern by changing its alignment in an area primitive with GpiSetPatternRefPoint. When the default reference point is set, the operating system aligns the lower-left corner of the fill pattern with the point (0,0) in the application's world space and begins filling the area. If an application adjusts the pattern reference point to (3,2), The operating system aligns the lower-left corner of the fill pattern with the point (3,2) in the application's world space and begins filling the area. By moving the reference point from (0,0) to (3,2), the fill pattern appears shifted up two pels and to the right three pels.

Custom Fill Patterns from a Bit Map

To create a custom pattern from a hard-coded bit map, an application must use the following steps: 1. Create or load a bit map to obtain a bit-map handle; for example, use GpiLoadBitmap. 2. Call GpiSetBitmapId (ID) to tag the bit map with a local identifier (lcid) from 1 to 254. 3. Call GpiSetPatternSet (ID) or GpiSetAttrs (ABB_SET) to set the current fill pattern.

The application can now draw the area.

Custom Fill Patterns from a Font Symbol

To create a custom pattern from a character or a symbol in a font: 1. Create a logical image font and assign it an ID; for example use GpiCreateLogFont. 2. Call GpiSetPatternSet (ID) or GpiSetAttrs (ABB_SET), passing it the local identifier for the font. 3. Call GpiSetPattern, passing the value of the code point for a character or symbol in the font.

The application can now draw the area.

Area Colors 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. Both attributes also are described in Color and Mix Attributes.

The area color defines the color used to fill the output from any of the IBM OS/2 area functions, when necessary. The area primitive is the only primitive in which the color can be changed during the drawing of the area. Therefore, this attribute, more than the other area attributes, depends on the current value as described in Attribute Currentness.

When a presentation space is created, the area color initial default is black. The pattern symbol initial default, explained previously, is solid. Areas are one of the primitives that have a foreground and background color.

Area Primitives

Area primitives have both a color and background color attribute. The background color does not appear if the pattern symbol is solid, and the background color is undefined if the pattern symbol is a customized, multi-colored bit map.

When a presentation space is created, the area mix attribute initial default is FM_OVERPAINT. The overpaint mix attribute specifies that the area color is not to be modified by the color of the drawing surface. If the area mix attribute is changed, the area color is mixed with colors that are already on the drawing surface.

When the pattern symbol is solid, the color that fills the area, if necessary, is the current area foreground color. If the pattern symbol is changed to be a pattern of vertical lines, for example, the color of those lines is the current area foreground color. Inside of the area bracket, there can be other colors if these colors are the current color for primitives such as lines or arcs, that are drawn within the area bracket. These colors are not specifically defined or influenced by the area foreground color.

The area background color initial default is CLR_BACKGROUND. Usually this is defined by the application to the same color as the drawing surface. If the pattern symbol is solid, the area background color does not appear. If the pattern symbol is changed to be a pattern of vertical lines, for example, the color in between those lines is the current area background color.

The area background mix attribute initial default is BM_LEAVEALONE. The leave-alone background mix attribute specifies that the area background color is not drawn. This means that for a nonsolid pattern symbol, the drawing-surface color or the color of an object, not created by the area bracket, but on the drawing surface, shows through the nonsolid pattern. The area background color, for nonsolid pattern symbols, appears only if the background mix attribute is changed to overpaint, BM_OVERPAINT.

If you have customized the pattern symbol with a bit map, the color definitions of the area primitive change. The foreground color corresponds to the color of the pels that are specified ON in the fill-pattern bit map. The background color corresponds to the color of the pels that are specified OFF in the fill-pattern bit map. The foreground and background mix attribute do not change.

Note: Background color and mix attribute only apply to monochrome (2-color) fill patterns. The bit set to 0 is defined as the background and the bit set to 1 is defined as the foreground. A multi-colored bit map is unaffected by the background color and mix attributes.

To specify a new color or mix attribute call GpiSetAttrs. This function accepts as input the type of primitive, for example PRIM_AREA, a list of attributes that are to be changed, a list of attributes that are to be set to their default values, and the values for the attributes that are to be changed. GpiSetAttrs is useful to specify colors and mix attributes just for a specific data structure -for example the AREABUNDLE structure. GpiSetAttrs also provides some protection against invalid colors.

To determine the current area color and mix attribute, call GpiQueryAttrs. This function accepts as input the primitive type and the attributes in question. It returns as output an array of values for the specifically queried attributes.

To reset the default area color and mix attribute, just as with any other attribute specified in the AREABUNDLE. data structure, call GpiSetDefAttrs. This function accepts as input the type of primitive, for example PRIM_AREA, the attributes to be changed, and the values that will become the new default values. The changing of default values is important when working with segments. Changing the default values during a series of drawing functions is not recommended.

The area color and mix attribute also can be specified with:

However, these functions have the disadvantage of specifying the foreground and background color or mix attribute for all primitive BUNDLE data structures that have the respective component.

There are four queries that determine the color and mix attribute as specified by GpiSet... functions:

If the area color, area background color, mix attribute, or background mix attribute were specified individually, the aforementioned queries can return a value inconsistent with the current area attribute.

Area Brackets

Areas also are referred to as area brackets, because the functions that create and define the area always are "bracketed" by the two functions, GpiBeginArea and GpiEndArea. Only one area is defined between these two functions. However, within the area, there can be any number of adjacent, intersecting, or completely separate area primitives.

GpiBeginArea signals the start of a group of primitives that define the boundary of the area. The current position is not changed by GpiBeginArea, although it is updated by any drawing instructions that follow.

If you call GpiSetCurrentPosition or GpiMove within an area definition, the current figure is closed automatically, and a new figure is started at the current position by the next line or curve. A figure in the area, whose start and end points are not the same, is closed by drawing a straight line from the current position to the start position of the figure.

GpiEndArea signals the end of an area definition and tells the operating system to draw the area. If an application does not close a figure before calling GpiEndArea, the figure is closed automatically by drawing a straight line from the end point of the last line or curve to the start point of the current figure. The current position is always updated to the end point of the last line drawn.

The functional sequence to draw an area could be:

#include <os2.h>
void fncAREA01(void){

#if 0
GpiBeginArea              /* Starts the area bracket */
GpiSetCurrentPosition     /* Set the start point of the outer hexagon. */
GpiPolyLine               /* Draw the outer hexagon. */
GpiSetCurrentPosition     /* Set the start point of the inner hexagon. */
GpiPolyLine               /* Draw the inner hexagon. */
GpiEndArea                /* End the area definition. */
#endif
}

An area bracket contains the functions that define an area. Only one area can be defined between "bracket" functions. Following the beginning of an area bracket, an application can define the shape and location of the area in world space by using the following line and arc functions:

If an application calls either GpiBox or GpiFullArc inside an area, it must use the DRO_OUTLINE option. In addition to the drawing functions, an application also can use the following specification functions inside an area bracket:

An application also can use the following query functions inside an area bracket:

Area Bracket Attributes

In addition to the attributes controlled by the AREABUNDLE data structure, there are two attributes that can be specified for each individual area bracket:

  • Area boundary
  • Area construction

These bracket attributes affect how the area primitives inside the bracket are drawn. The concept of attribute currentness is especially important to areas and paths that contain multiple figures.

Area Boundaries

An application specifies the area boundary when it calls GpiBeginArea. There are two options:

  • BA_BOUNDARY (the default)
  • BA_NOBOUNDARY.

The BA_BOUNDARY value tells the programming interface to draw all outlines of the area primitives within the area bracket, using a line that conforms to the current LINEBUNDLE attributes. If the line attributes have not been changed, the default outline color is black on most displays and printers, and the default line style is solid. An application can change the line color and line styles within the area bracket. The interior of the area primitive is filled with the current pattern.

To prevent the interface from outlining an area, an application can use the BA_NOBOUNDARY flag when calling GpiBeginArea. Only the interior fill pattern is visible. This value most often is used when an area contains many overlapping figures, and the interior lines are not desired.

You could think of this option in terms similar to the outline and fill options discussed with boxes and full arcs. The BA_BOUNDARY value corresponds to DRO_OUTLINEFILL, and BA_NOBOUNDARY, to DRO_FILL. There is no distinct boundary value that corresponds to DRO_OUTLINE, the simple outline. To simulate this effect, OR the BA_NOBOUNDARY value with the appropriate area construction value when calling GpiBeginArea.

Area Construction

An application specifies the area construction when it calls GpiBeginArea. There are two options:

  • BA_ALTERNATE (the default)
  • BA_WINDING.

Construction modes also are called area-fill modes. They provide different ways of determining whether a given point is included in the filled area. Normally, the construction mode you use is a matter of personal preference.

Alternate Mode

In alternate mode, the following occurs:

A point is included in the filled area if you have to cross an odd number of lines in the area when drawing a line from that point to infinity.

A point is not included in the filled area if you have to cross an even number of lines in the area when drawing a line from that point to infinity.

In the example in the following figure, the inner hexagon is not shaded, because to draw a line from any point in the hexagon to infinity, you must cross two boundary lines. The remainder of the area is shaded, because to move outside the area, you need to cross only one boundary line.

Winding Mode

In winding mode, the direction in which the boundary lines in the area are drawn determines whether a given point is included in the filled area. The direction of a line depends on both the graphics functions used to draw it and the world coordinates that define it. For example, if the current position of a presentation space is (c,c), and GpiBox is called with the diagonally-opposite corner of the box specified as (d,d), GpiBox always draws the box in the following order:

1. (xc.,yc.) to 2. (xd.,yc.) to 3. (xd.,yd.) to 4. (xc.,yd.) and returning to 5. (xc.,yc.).

As illustrated in the following figure, in some cases the box is drawn in a counterclockwise direction. When either xd. is less than xc., or yd. is less than yc., but not both, a box is drawn clockwise.

[[Image:]]

The Box

The current position is (3,2) and the specified corner is at (8,6). The box is drawn from (3,2) to (8,2) to (8,6) to (3,8) to (3,2).

For the polyline primitive, the direction in which a line is drawn depends on the relative values of the end points of each line, so you can choose whether to draw in a clockwise or counterclockwise direction.

To determine if a given point is included in the filled area, count the number of lines to be crossed to move from that point to infinity. For each boundary line drawn in one direction, add one to the tally. For each line drawn in the opposite direction, subtract one from the tally. A point is within the area if the result is nonzero.

If two figures -for example, the hexagons in the following figure- are drawn in different directions, the tally for the inner hexagon is 0 and the area will look exactly as it does in alternate mode.

Area Constructed in Different Directions in Winding Mode

If the two hexagons are drawn in the same direction, the result is 2, and the inner hexagon is shaded as shown in the following figure.

Area Constructed in the Same Direction in Winding Mode

The boundary lines of the area in the previous figure have been drawn and are visible through the area-fill pattern. The boundary lines of an area primitive do not have to be drawn; but if they are, they are drawn according to the current line attributes.

To vary the appearance of different parts of the boundary line, you can change the current line attributes during area definition.

The boundary lines of an area are considered a part of the area's interior. Therefore, when you draw an area without boundary lines (BA_NOBOUNDARY), the area-fill pattern extends to include the boundaries of the area, and the area is the same size it would be if the boundary lines had been drawn.

[[Image:]]

Calculating Filled Areas Constructed in Alternate Mode.

Attribute Currentness

Graphics functions that change attributes are valid within the area bracket. There are misconceptions, however, about which attributes are used when the figures are displayed in a window or drawn to the printer.

Review the following functional sequence:

Function Effect
GpiSetColor Sets color to red.
GpiBeginArea Opens area bracket
GpiLine Draws a straight line
GpiSetColor Sets color to green.
GpiPolyLine Draws two additional lines to form a triangle.
GpiEndArea Ends the area bracket and displays a picture.

If you are displaying on a color monitor, the image appears as follows:

The triangle has one red line, drawn with GpiLine and two green lines, drawn with GpiPolyLine. The interior of the triangle, if drawn, is red. Red is the color that was current when the area was defined and, therefore, is the current color for the area interior. In terms of the interior area, green is only the color that was current when the function that initiates drawing was called.

If the application immediately opened a new area bracket, the interior of that bracket, if drawn, would be green. The color attribute for the second AREABUNDLE, is not "inherited" from the last AREABUNDLE drawn.

About Polygon Primitives

Using Area and Polygon Primitives