Renditions
This section defines renditions and explains how they
are implemented on the display. It further explains the use of various
attributes associated with renditions.
The content of the HT_Rendition object consists of the following:
HT_Net_Data HT_Transform_Data depth_buffering hard_clip viewport camera modelling_matrix viewing_matrix projection_matrix screen_matrix object_to_device world_to_device HT_Line_Data line_weight line_pattern line_cap line_join HT_Color_Data color matched_color color_index contrast_color matched_contrast_color contrast_color_index background_color matched_background_color background_color_index shader add_light light HT_Face_Data face_pattern face_displacement HT_Marker_Data marker_symbol marker_size HT_Misc_Data mixing_mode pattern_mode perspective_correction interpolation_level
HT_Rendition *hr
Incarnations
Every rendition has a set of incarnations that are identifiers
unique to the particular set of attribute values contained in the rendition.
An incarnation is a number that can be checked quickly to determine whether
all attribute values have remained the same. A net incarnation provides
a unique identifier for all attributes in the rendition. Your driver should
maintain, in its local state data, the most recent incarnations of its
relevant rendition types that it uses. Then, each action function can check
the incarnations of its relevant renditions against the previous values.
If the current incarnation value is unchanged from the previous call, then
the action does not need to update the attribute state.
Checking incarnations can be important on devices for which attribute changes are expensive. If the application retains a high level of attribute coherence when it is performing its database traversal, then the incarnation values may help limit the number of attribute changes significantly.
This section describes particular rendition types with the actions that use them. Many drawing actions require you to adhere to the attributes in the rendition. For example, the draw_dc_polyline action needs to look up the attributes line_cap, line_pattern, and line_join that are specified in the line rendition. The driver may query these through the access member functions of the HT_Rendition class. Specifically, these rendition attributes can be queried like this:
HT_Rendition *hr; HT_Line_Cap my_line_cap = hr->line_cap(); HT_Line_Pattern my_line_pattern = hr->line_pattern(); HT_Line_Join my_line_join = hr->line_join();
The color system defines whether the color or color index is used when rendering primitives. Both the color and color index are always valid. Contrast colors are used to fill the 0 (off) bits in face and line patterns. Background colors are used as a reference for clearing the drawing buffer and drawing in the XOR mixing mode.
Matched color needs more explanation. It is provided automatically by Heidi when the original RGB color that the application requested is not available in the current driver palette. In this case, matched color is the closest RGB value that approximates the original color. The best matched color index number is then stored in the color index.
Usually, matched colors are the same as the color set provided by the application. Only when the application requests a true color on a mapped RGB (8-bit) display does the matched color differ from the original color. In this case, Heidi is trying to match the original color to the available RGB color entry. Since matched color is what the physical device uses, Heidi driver developers should always use the matched color as the current RGB drawing color.
Miscellaneous Attributes
The rendition contains two miscellaneous attributes.
The first attribute, mixing_mode,
defines the logical operation used when drawing filled primitives, such
as faces and text, are drawn. The logical operation is an enumeration value
defined in the class HT_Mixing_Mode.
Currently, two values are supported, Exclusive_Or
and Copy.
The Exclusive_Or mode specifies that the destination pixel should
be the XOR of the source pixel and the destination pixel. The Copy
mode specifies that destination pixel should be replaced by the source
pixel.
The second attribute, pattern_mode, defines the drawing mode to use when filled primitives, such as faces and text, are drawn. The drawing mode is an enumeration value defined in the class HT_Pattern_Mode. For more information see HT_Rendition::pattern_mode in appendix A, "Heidi Class Reference."
Line Primitive Attributes
The rendition contains a set of line
attributes that the driver must adhere to when displaying line primitives.
Line primitives are all generally subject to the line_weight and line_pattern attributes. The polyline primitives are also subject to the line_cap and line_join attributes. In addition, line primitives are generally subject to the color attributes color and color_index. The exception is the colorized and Gouraud primitives, which are not subject to the line color attributes in the rendition. Instead, the colorized routines have their line color passed through a data structure in an additional parameter and the Gouraud routines are passed colors to be interpolated. They are also subject to the miscellaneous attributes mixing_mode and pattern_mode.
Notes: A line_weight of "0"
or "1" represents a single pixel line.
Heidi now draws the last
pixel of a polyline in order to facilitate the display of weighted lines
rasterized as polytriangles. In the past, this pixel was drawn by applications¾for
example, AutoCAD through its DisplayList, adding it as an extra point to
the geometry.
Solid, Dashed, Dotted, Dash_Dot, Short_Dash, Medium_Dash, Long_Dash, Short_Dash_X2, Medium_Dash_X2, Long_Dash_X2, Medium_Long_Dash, Medium_Dash_Short_Dash_Short_Dash, Long_Dash_Short_Dash, Long_Dash_Dot_Dot, Long_Dash_Dot, Medium_Dash_Dot_Short_Dash_Dot, Sparse_Dot, User_Defined,
short const * line_pattern_lengths (HT_Line_Pattern pattern) const
The first element in the array is a scaling factor for adaptive patterns. It is the total of the lengths of dashes, spaces, dots and so forth in the pattern¾for example, the actual length or a percentage length that will display a line type pattern span within the varying segments of a polyline. This equals 50 in the example following. The second element in the array is a count of spans. This is followed by the set of numbers terminated by -1. The driver should alternate drawing styles for the percentage of pixels given by each successive span number. For the first number in the pair, draw the face color. For the next number in the pair, draw nothing if the pattern mode is Hollow or draw the contrast color if the pattern mode is Filled. Then, alternate with another pair. When the end of the span array has been reached, you should start again at the beginning of the array.
This is best illustrated with an example. The internal code span array for dash_dot looks like this:
dash_dot[] = {50, 4, 26, 12, 0, 12, -1}
pattern_scale = dc->requirements().m_pattern_scale;
where dc is a pointer to a HT_Renderer or HT_Device.
m_pattern_scale, a method of HT_Device_Requirements, stores the pattern_scale factor and represents 100% of a normal line pattern for video displays. This defaults to 50 pixels. For hardcopy devices, it is recommended that the pattern_scale device requirements be set to a number of pixels corresponding to 1/2 inch. (It is the responsibility of the hardcopy driver writer to set the pattern_scale to a value that correctly represents their particular device.)
The span value is again multiplied by another line scale parameter, line_pattern_scale, which is set at the rendition. Thus the plotted line pattern is affected by 2 scale factors¾at the renderer level, pattern_scale, and at the rendition level, line_pattern_scale.
You may also override these definitions if your hardware has specific built-in lengths. By overriding, you can make standard routines match the output from your hardware, which generally accelerates line drawing. The hardware line patterns, however, do not always match the Heidi definitions. We recommend adding a driver specific option, for example "Use Hardware Line Pattern" and let the application decide whether it wants the faster but less accurate hardware line patterns or the more precise but slower software patterns.
Custom line patterns can be developed from HT_Dash_Pattern. If set_line_pattern is called with an HT_Dash_Pattern, then the line pattern type is automatically set to User_Defined.
Line Caps and Joins
The line cap and line join attributes define the appearance
of the line and dash start and endpoints, and inner vertices as follows:
line_end_cap_solid controls the drawing of solid end caps for nonclosed polylines.
dash_cap specifies the start and end caps for dash lines if the caps are the same. If the start and end caps are different, then it is undefined and dash_start_cap and dash_end_cap would be used. dash_cap can be applied to dashes within the dash line.
dash_start_cap and dash_end_cap specify the start and end caps for dashed lines, if the start and end caps are different. These methods can also be applied to dashes within the dashed line.
There are four enumeration values defined in class HT_Line_Cap:
Round ¾ Line end formed by a semicircle centered at the endpoint of the line. See figure 11.
Square ¾ Line end formed by a square centered at the endpoint of the line. See figure 10.
Diamond ¾
Line end formed by a triangle centered at the endpoint of the line. See
figure
11.
line_joins_solid controls the drawing of solid joins.
There are four enumeration values for these line join
methods defined in class HT_Line_Join:
Bevel ¾ A line is drawn between the corners of the two nominal segments exterior to the angle of the join, and the polyline image is filled out to this line. Thus, the bevel case involves adding an equilateral triangular area to the line at each joint, as shown in figure 10.
Round ¾ An arc of a circle is drawn tangent to the two edges of the nominal segments exterior to the angle of the join, and the polyline image is filled out to this arc, as shown in figure 11.
Diamond ¾
Two lines are drawn from the corners of the two nominal segments
exterior to the angle of the join. These lines extend to a point, and the
polyline image is filled out to them. The "vertex" point of these lines
is 1/2 line width from the intersection of the midpoints of the ends of
the nominal segments, as shown in
figure 11.
line_weight() > 1
The top illustration, figure 9, shows a three-point (two-segment) wide polyline with its two nominal segment rectangles drawn in outline and its three vertices shown as heavy dots. The area inside either (or both) of the nominal segment rectangles is covered by the polyline, including the kite-shaped region just above the join vertex. However, there is a notch below the join vertex that is not in either nominal segment rectangle. This notch must be filled in to make a smooth wide polyline.
Figure 9. Two segment polyline
Figure 10. Butt & square caps with miter & bevel joins
Figure 11. Round & diamond caps with round & diamond joins
The face primitives are subject
to the face attributes face_pattern
and face_displacement
of class HT_Rendition.
In addition, face primitives are generally subject to the color attributes
color,
color_index,
contrast_color,
contrast_color_index,
and material,
as well as the miscellaneous attributes mixing_mode
and pattern_mode.
Stipple00-Stipple64 Solid Checkerboard Crosshatch Diamonds Horizontal_Bars Slant_Left Slant_Right Square_Dots Vertical_Bars User Defined
To access the face pattern definitions, you must use member functions of the HT_Renderer class by calling the following function:
HT_Byte const * face_pattern_bits (HT_Face_Pattern pattern) const
The format for the bit patterns is an 8 x 8 monochromatic bitmap stored in 8 sequential bytes. The bytes store the bits of the pattern in row-major order, top row first, with the most significant bit of each byte representing the left-most pixel. The bitmap should be tiled across the face you are drawing.
User Defined Face
Patterns
You may override the pattern definitions if your hardware
has specific built-in patterns. By overriding, you can make standard routines
match the output from your hardware.
In addition to the built-in face patterns, you can specify a user defined face pattern from HT_Fill_Pattern. These user defined equivalents to face pattern definitions can have an arbitrary size and on, off patterning.
The fill_pattern method of class HT_Rendition queries for the user specified bit map of a fill pattern defined by HT_Fill_Pattern, which is called by set_face_pattern, and is automatically set to User_Defined. The pattern is applied to area fill primitives in the face contrast color over whatever fill color is determined by the color attribute or the lighting and shading computation in effect. Solid means "no pattern", that is, the color covers the filled area completely and the contrast color is not used. The pattern is applied as a "decal" in screen space, and is not subject to the transformations of the pipeline.
Using the set_fill_pattern_offset method of class HT_Rendition, a Heidi application developer can supply an offset to control fill patterns ¾ a fill pattern anchor. Fill patterns are normally offset from the origin of the view ¾ usually 0,0 for AutoCAD. In this case, the fill pattern does not follow any subsequent relocation of the geometry and appears to change within the polygon. The ability to specify a fill pattern offset allows the pattern to remain fixed with subsequent polygon offsets so that the user can drag a patterned polygon on the screen and the pattern moves with the polygon.
Note: For all Heidi drivers that fill in the draw_dc_polygon, but not the draw_2d_polygon, core Heidi hands over clipped polygons instead of triangles.
The built-in face patterns are
8 bits however using HT_Fill_Pattern,
you could establish an 18 by 10 honeycomb pattern as shown in the following
example. In this honeycomb fill pattern example
read the rows from the bottom up, low bits first with each row padded out
to a full byte.
// _,_,_,1,1,1,1,1, 1,1,_,_,_,_,_,_, _,_, // _,_,1,_,_,_,_,_, _,_,1,_,_,_,_,_, _,_, // _,_,1,_,_,_,_,_, _,_,1,_,_,_,_,_, _,_, // _,1,_,_,_,_,_,_, _,_,_,1,_,_,_,_, _,_, // _,1,_,_,_,_,_,_, _,_,_,1,_,_,_,_, _,_, // 1,_,_,_,_,_,_,_, _,_,_,_,1,1,1,1, 1,1, // _,1,_,_,_,_,_,_, _,_,_,1,_,_,_,_, _,_, // _,1,_,_,_,_,_,_, _,_,_,1,_,_,_,_, _,_, // _,_,1,_,_,_,_,_, _,_,1,_,_,_,_,_, _,_, // _,_,1,_,_,_,_,_, _,_,1,_,_,_,_,_, _,_,The array of values (bytes) for this honeycomb fill pattern is shown following:
HT_Byte honeycomb[] = {
0x04, 0x04, 0x00,
0x04, 0x04, 0x00,
0x02, 0x08, 0x00,
0x02, 0x08, 0x00,
0x01, 0xF0, 0x03,
0x02, 0x08, 0x00,
0x02, 0x08, 0x00,
0x04, 0x04, 0x00,
0x04, 0x04, 0x00,
0xF8, 0x03, 0x00,
};
The face pattern definition for the honeycomb would be as
follows:
m_Rendition.set_face_pattern(HT_Fill_Pattern(18, 10, honeycomb));
User Defined Hatch
Patterns
Hatch patterns are set from the rendition using a method
similar to that of user defined face patterns explained in the preceding
section. These are vector based fill patterns similar in look to the basic
AutoCAD hatch patterns.
The hatch_pattern
method of class HT_Rendition queries for the user specified line
set defined by HT_Hatch_Pattern,
which is called by set_face_pattern.
The pattern consists of some number of parallel line sets defined within
a unit square. These are sets of parallel line patterns which cross at
various angles and can be skewed (offset) to a specified distance. For
more information, an example and illustration, see HT_Hatch_Pattern
and
HT_Parallel_Line_Set.
Dot Plus X Star Circle Circle_With_Dot Circle_With_Plus Circle_With_X Circle_With_Circle Circle_Filled Box Box_With_Dot Box_With_X Box_Filled Diamond Diamond_With_Dot Diamond_With_Plus Diamond_Filled Triangle_Up Triangle_Up_With_Dot Triangle_Up_Filled Triangle_Up_Vertex Triangle_Up_Vertex_Filled Triangle_Down Triangle_Down_With_Dot Triangle_Down_Filled Triangle_Down_Vertex Triangle_Down_Vertex_Filled Triangle_Left Triangle_Left_With_Dot Triangle_Left_Filled Triangle_Left_Vertex Triangle_Left_Vertex_Filled Triangle_Right Triangle_Right_With_Dot Triangle_Right_Filled Triangle_Right_Vertex Triangle_Right_Vertex_Filled
Font Engine
For a complete description and overview of the Font engine
and its implementation, see chapter 5, "The
Font Engine."