Graphic, FullGraphic - structured graphic abstract base class and
subclass that stores a complete set of graphics state attributes
#include <Unidraw/Graphic/graphic.h>
Graphic is an abstract base class for structured graphics
objects. Graphic objects maintain graphics state and geometric information,
which lets them draw themselves on demand and support hit detection.
Graphic subclasses can implement graphical objects such as lines,
rectangles, ellipses, and polygons. Subclasses can also support hierarchical
composition of Graphic instances, thus providing an object-oriented
rendition of traditional structured graphics functionality.
- virtual void
Draw(Canvas*)
- virtual void
Draw(Canvas*, Coord, Coord, Coord, Coord)
- virtual void
DrawClipped(Canvas*, Coord, Coord, Coord, Coord)
- virtual void
Erase(Canvas*)
- virtual void
Erase(Canvas*, Coord, Coord, Coord, Coord)
- virtual void
EraseClipped(Canvas*, Coord, Coord, Coord, Coord)
- Draw or erase the graphic on the given canvas. The one-parameter Draw and
Erase operations draw and erase the graphic in its entirety. The
five-parameter forms take four coordinates defining a rectangular area
with which to cull drawing. Composite graphics in particular can use this
information to avoid drawing children falling entirely outside the given
area. DrawClipped and EraseClipped draw the graphic strictly within a
rectangular area. All Coord parameters are in canvas coordinates.
- virtual void
FillBg(boolean)
- virtual void
SetBrush(PSBrush*)
- virtual void
SetColors(PSColor* fg, PSColor* bg)
- virtual void
SetFont(PSFont*)
- virtual void
SetPattern(PSPattern*)
- virtual int
BgFilled()
- virtual
PSBrush* GetBrush()
- virtual
PSColor* GetFgColor()
- virtual
PSColor* GetBgColor()
- virtual PSFont*
GetFont()
- virtual
PSPattern* GetPattern()
- Set and get the graphic's graphic state attributes analogous to those
defined for Painters. The base class implements the operations for setting
and getting the fill mode and colors; the other operations should be
redefined in subclasses that need them.
- void Translate(float dx,
float dy)
- void Scale(float x,
float y, float cx = 0.0, float cy = 0.0)
- void Rotate(float
angle, float cx = 0.0, float cy = 0.0)
- void
SetTransformer(Transformer*)
- Transformer*
GetTransformer()
- void
TotalTransformation(Transformer& t)
- Coordinates passed to drawing operations are transformed according to the
current translation, rotation, and scale factor. Optionally, scaling and
rotation can be performed relative to a point (cx, cy). The
base class stores a transformer _t that can be directly set and
accessed with SetTransformer and GetTransformer. The default transformer
is nil, meaning no transformations are performed. TotalTransformation uses
concatTransformer (described below) to concatenate t (usually the
identity transformation) and the transformers of the graphic's parents to
obtain the graphic's total transformation, which it then stores in
t.
Unless otherwise noted, input and output coordinates are
affected by the concatenation of this's transformer, its parent's
transformer, its parent's parent's, and so on up to the root of the
graphic instance hierarchy. Prior to transformation, coordinates reflect
the graphic's coordinate system. Following transformation, the
coordinates reflect the canvas coordinate system (i.e., they are canvas
coordinates). The coordinates that Graphic subclass constructors require
are normally in graphic coordinates, while operations for returning a
graphic's bounding box (see below) are in canvas coordinates.
- void Align(Alignment,
Graphic*, Alignment)
- Position the given graphic relative to this, which stays fixed,
while the graphic supplied as the argument is translated appropriately.
The first Alignment parameter specifies the alignment with respect to
this, while the second specifies the alignment with respect to the
given graphic.
- virtual void
GetBounds(
- float&
left, float& bottom, float& right, float& top
- )
-
Return the exact coordinates of the smallest box circumscribing the graphic.
The return values are in canvas coordinates.
- void GetBox(Coord&
left, Coord& bottom, Coord& right, Coord& top)
- void
GetBox(BoxObj&)
- Return the smallest bounding box circumscribing the graphic. The return
values are in canvas coordinates. The BoxObj represents a rectangle
defined by lower left and upper right coordinates (see geomobjs(3U) for
details).
- virtual void
GetCenter(float& x, float& y)
- Return the center point of the graphic in canvas coordinates.
- virtual boolean
Contains(PointObj&)
- virtual boolean
Intersects(BoxObj&)
- Return whether or not the graphic contains the given point or intersects
the given rectangular area specified in canvas coordinates.
PointObj describes a point (see geomobjs(3U)). These operations are
used most often for fine-grained hit detection.
- void
SetTag(void*)
- void*
GetTag()
- Set or return a tag associated with the graphic.
- Graphic*
Parent()
- Return the graphic's parent, if any.
- virtual void
First(Iterator&)
- virtual void
Last(Iterator&)
- virtual void
Next(Iterator&)
- virtual void
Prev(Iterator&)
- virtual boolean
Done(Iterator)
- Operations for iterating over the graphic's children, if any. These
operations do nothing by default. Graphics that compose other graphics
should redefine these operations to permit traversal of their children.
First and Last initialize an iterator to point to the beginning and end of
the list of children, respectively. Next increments the iterator to point
to the following child, while Prev decrements the iterator to point to the
preceding child. Done returns whether or not the iterator points beyond
the first or last child in the list.
- Graphic*
GetGraphic(Iterator)
- void
SetGraphic(Graphic*, Iterator&)
- These operations do nothing by default. Subclasses that contain children
should redefine them as follows: GetGraphic should return the graphic to
which an iterator points. SetGraphic should initialize the iterator to
point to a particular graphic in the list of children; it should
initialize the iterator to point to a nil instance if the given graphic is
not a child.
- virtual void
Bequeath()
- Bequeath does nothing by default. Composite graphic subclasses should
redefine it so that it propagates to the children all the graphics state
in this that can affect them. This will prevent a change in a
child's appearance should it be removed from this. Following the
call to Bequeath, this should no longer define any graphics state
attributes.
- virtual
Graphic* FirstGraphicContaining(PointObj&)
- virtual
Graphic* LastGraphicContaining(PointObj&)
- virtual
Graphic* FirstGraphicIntersecting(BoxObj&)
- virtual
Graphic* LastGraphicIntersecting(BoxObj&)
- virtual
Graphic* FirstGraphicWithin(BoxObj&)
- virtual
Graphic* LastGraphicWithin(BoxObj&)
- These operation do nothing by default. Composite graphic subclasses should
redefine them so that they return the first or last child that contains a
point, intersects a rectangular area, or does not extend beyond the given
rectangular area, respectively.
- virtual
Graphic& operator = (Graphic&)
- Assign the given graphic's graphics state attributes to this.
- virtual
Graphic* Copy()
- Return a copy of the graphic. Subclasses should redefine this operation to
return an instance of their type.
- Graphic(Graphic*
gr = nil)
- Initialize the graphics, optionally supplying a graphic from which to
obtain an initial set of graphics state attributes. Graphic is an abstract
base class. Therefore its constructor is protected to prevent
instantiation.
- virtual void
draw(Canvas*, Graphic* gs)
- virtual void
drawClipped(
- Canvas*, Coord,
Coord, Coord, Coord, Graphic*
- )
- virtual void
erase(Canvas*, Graphic*)
- virtual void
eraseClipped(
- Canvas*,
Coord, Coord, Coord, Coord, Graphic*
- )
-
Graphic subclasses redefine these stateless drawing operations to
render themselves. These operations are called by the corresponding
capitalized operations, which supply them with the extra trailing Graphic
parameter gs. This parameter defines the graphics state with which
to draw the graphic. The graphic state is normally computed using the
concat functions described below. Subclasses normally use the
graphics state passed to them without ignoring or modifying it, though
they may safely do so if they must override one or more attributes.
- void update(Graphic*
gs)
- Graphics ultimately use a Painter to draw themselves. The Graphic class
maintains a protected static painter _p that subclasses can use to
draw themselves. The update operation sets _p's graphics state
attributes to match those of the given graphic to ensure that the painter
will generate graphics with the proper color, font, etc. Subclasses should
call update in their stateless drawing operations (normally supplying the
graphic they were passed) before they call any drawing operations on
_p. The graphics that _p generates, therefore, will reflect
the graphics state that was passed to the stateless drawing
operation.
- virtual void
getExtent(
- float&
left, float& bottom, float& cx, float& cy,
- float&
tol, Graphic* gs
- )
- void
GetExtent(Extent&)
- A graphic's extent defines its physical boundaries. Subclasses
redefine getExtent to return this boundary information based on the
graphics state supplied in gs. The left, bottom,
cx, and cy parameters define the graphic's lower left corner
and center, respectively, in canvas coordinates. The tol parameter
specifies a fixed amount of space around the boundary to account for parts
of the graphic's appearance that do not scale linearly (e.g., brush
width). The relationship between getExtent and GetExtent is the same as
that between draw and Draw: getExtent is the stateless version of
GetExtent, which concatenates the parent's graphics state and calls
getExtent with the result.
- void
getBounds(
- float&
left, float& bottom, float& right, float& top,
- Graphic*
gs
- )
- void
getBox(
- Coord&
left, Coord& bottom, Coord& right, Coord& top,
-
Graphic*
- )
- void
getBox(BoxObj&, Graphic*)
- Stateless versions of the corresponding capitalized bounding box
operations, which call the stateless versions with the cumulative graphics
state of this's ancestors. These operations are defined in terms of
getExtent and therefore should not be reimplemented by subclasses.
- virtual boolean
contains(PointObj&, Graphic* gs)
- virtual boolean
intersects(BoxObj&, Graphic*)
- Stateless versions of the corresponding capitalized operations for
fine-grained hit detection. By default, these operations return true if
the argument is contained in or intersects this's bounding box.
Subclasses can redefine these operations to make a more discerning
decision.
- Graphic*
getRoot()
- void
totalGS(Graphic& g)
- void
parentXform(Transformer& t)
- Helper functions for parent-related operations. getRoot returns the root
graphic in this's hierarchy. totalGS uses concat (described below)
to concatenate the graphics state of this and all its ancestors,
returning the result in g. Any graphics state that g stored
initially will be lost. The parentXform operation uses concatTransform
(described below) to concatenate the transformations of all ancestors of
this, returning the result in t. Any transformations that
t stored initially will be lost.
- void
setParent(Graphic* g, Graphic* parent)
- void
unsetParent(Graphic* g)
- Operations for setting and getting the value of another graphic's
(g's) parent as stored in the _parent protected member
variable. Normally only composite graphics change this attribute of
another graphic, usually a newly-acquired child.
- void
cachingOn()
- void
cachingOff()
- virtual boolean
extentCached()
- virtual void
uncacheExtent()
- virtual void
uncacheParents()
- virtual void
uncacheChildren()
- virtual void
invalidateCaches()
- Operations that support extent caching. Some Graphic subclasses may cache
extent information when it is computed for the first time, thereby
improving performance. For example, it may be expensive to compute the
extent for composite graphics that have many children; thus caching the
extent will improve performance if the extent does not change often.
cachingOn and cachingOff change the value of _caching,
a protected static boolean member of Graphic that indicates whether
caching is active on a global basis. Extent-caching subclasses should
check this member to avoid caching when it is false. Caching
subclasses should redefine extentCached to return whether or not they
have cached their extent (in whatever form they store it). They should
redefine uncacheExtent to discard any extent information they've cached.
By default, uncacheParents simply calls uncacheExtent on each ancestor
of this, while uncacheChildren does nothing by default.
Subclasses should redefine uncacheChildren to make any children uncache
their extents.
- virtual void
concatGS(Graphic* a, Graphic* b, Graphic* dest)
- virtual void
concatTransformer(
-
Transformer* a, Transformer* b, Transformer* dest
- )
- virtual void
concat(Graphic* a, Graphic* b, Graphic* dest)
- Operations for concatenting graphics state. concatGS concatenates
a's graphics state (brush, font, pattern, etc., but not
transformation matrix) with b's and assigns the result to
dest. According to the default concatenation semantics, dest
will receive graphics state attributes defined by b; dest
will receive only those attributes from a that b does not
define (i.e., those for which b returns nil). By default,
concatTransformer does a matrix multiply of a and b and
assigns the result to dest. The concat operation concatenates both
the graphics state and transformation of its arguments, assigning the
results to dest.
- void
transform(Coord&, Coord&, Graphic*)
- void transform(Coord,
Coord, Coord&, Coord&, Graphic*)
- void transform(float,
float, float&, float&, Graphic*)
- void
transformList(
- Coord[], Coord[],
int, Coord[], Coord[], Graphic*
- )
- void
transformRect(
- float, float, float,
float,
- float&,
float&, float&, float&, Graphic*
- )
- void
invTransform(Coord&, Coord&, Graphic*)
- void
invTransform(Coord, Coord, Coord&, Coord&, Graphic*)
- void
invTransform(float, float, float&, float&, Graphic*)
- void
invTransformList(
- Coord[],
Coord[], int, Coord[], Coord[], Graphic*
- )
- void
invTransformRect(
- float, float,
float, float,
-
float&, float&, float&, float&, Graphic*
- )
-
Convenience functions analogous to the Transformer operations of the same
name. These operations simply check if _t is nil before calling the
corresponding Transformer operation on it.
- virtual void
drawGraphic(Graphic* g, Canvas*, Graphic* gs)
- virtual void
drawClippedGraphic(
- Graphic* g,
Canvas*, Coord, Coord, Coord, Coord, Graphic*
- )
- virtual void
eraseGraphic(Graphic* g, Canvas*, Graphic*)
- virtual void
eraseClippedGraphic(
- Graphic* g,
Canvas*, Coord, Coord, Coord, Coord, Graphic*
- )
- virtual void
getExtentGraphic(
- Graphic* g,
float& left, float& bottom, float& cx, float&
cy,
- float&
tol, Graphic* gs
- )
- virtual boolean
containsGraphic(
- Graphic* g,
PointObj&, Graphic* gs
- )
- virtual boolean
intersectsGraphic(Graphic* g, BoxObj&, Graphic*)
- virtual boolean
extentCachedGraphic(Graphic* g)
- virtual void
uncacheExtentGraphic(Graphic* g)
- virtual void
uncacheParentsGraphic(Graphic* g)
- virtual void
uncacheChildrenGraphic(Graphic* g)
- virtual void
invalidateCachesGraphic(Graphic* g)
- virtual void
concatGSGraphic(
- Graphic* g,
Graphic* a, Graphic* b, Graphic* dest
- )
- virtual void
concatTransformerGraphic(
- Graphic* g,
Transformer* a, Transformer* b,
-
Transformer* dest
- )
- virtual void
concatGraphic(
- Graphic* g,
Graphic* a, Graphic* b, Graphic* dest
- )
-
Helper functions that let graphic subclasses call the protected member
functions on instances of other subclasses that redefine them. All these
helper functions take the affected instance as their first parameter. All
are semantically identical to the corresponding functions described above
(which omit the "Graphic" suffix and the leading g
parameter). Composite graphics are the most likely users of such helper
functions, calling them on their children.
- FullGraphic(Graphic*
= nil)
- Construct a full graphic, optionally supplying another graphic from which
to copy an initial set of graphics state attributes. FullGraphic objects
store a full complement of graphics state attributes; consequently,
FullGraphic redefines all the operations for setting and getting these
attributes. The FullGraphic class can be used as a base class from which
to derive graphics that require a complete set of graphics state and store
such state. It is also useful to instantiate FullGraphics and use them as
graphics state repositories.
Canvas(3I), Iterator(3U), Painter(3I) Transformer(3I),
geomobjs(3U), pspaint(3U)
"Applying Object-Oriented Design to Structured
Graphics," John M. Vlissides and Mark A. Linton, in Proceedings of
the 1988 USENIX C++ Conference, Denver, CO, October 1988, pp.
81-94.