| Drawing in Color | Contents | Index | Extended Stream Output |
14 General Designs
This chapter discusses more general designs than Chapter Drawing in Color and reveals
that regions are also designs. This chapter generalizes to those designs that
do not have the same color and opacity at every point in the drawing plane.
These include:
Note: A design is a unification of both a shape and a color and opacity. As such, a design can serve multiple roles. For example, the same design can play the role of an ink that colors the drawing plane, a shape that specifies where to draw another design, a stencil that controls the compositing of two designs, the background of a window, or a region that defines clipping. It is important not to get confused between type , which is inherent in an object, and role , which is determined by how an object is used in a particular function call.
14.1 The Compositing Protocol
Compositing creates a design whose appearance at each point is a
composite of the appearances of two other designs at that point. Three
varieties of compositing are provided: composing over ,
composing in , and composing out .
The methods for compose-over , compose-in , and compose-out will typically specialize both of the design arguments.
In Release 2, compositing might only be supported for uniform designs.
| compose-over | design1 design2 | [Generic function] |
If both arguments are regions, compose-over is the same as region-union .
This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. The result returned by compose-over might be freshly constructed or might be an existing object.
| compose-in | ink mask | [Generic function] |
More precisely, at each point in the drawing plane the resulting design specifies a color and an opacity as follows: the color is the same color that ink specifies. The opacity is the opacity that ink specifies, multiplied by the stencil opacity of mask .
The stencil opacity of a design at a point is defined as the opacity that would result from drawing the design onto a fictitious medium whose drawing plane is initially completely transparent black (opacity and all color components are zero), and whose foreground and background are both opaque black. With this definition, the stencil opacity of a member of class opacity is simply its value.
If mask is a solid design, the effect of compose-in is to clip ink to mask . If mask is translucent, the effect is a soft matte.
If both arguments are regions, compose-in is the same as region-intersection .
This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. The result returned by compose-in might be freshly constructed or might be an existing object.
| compose-out | ink mask | [Generic function] |
More precisely, at each point in the drawing plane the resulting design specifies a color and an opacity as follows: the color is the same color that ink specifies. The opacity is the opacity that ink specifies, multiplied by 1 minus the stencil opacity of mask .
If mask is a solid design, the effect of compose-out is to clip ink to the complement of mask . If mask is translucent, the effect is a soft matte.
If both arguments are regions, compose-out is the same as region-difference of mask and ink .
This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. The result returned by compose-out might be freshly constructed or might be an existing object.
14.2 Patterns and Stencils
Patterning creates a bounded rectangular arrangement of designs, like
a checkerboard. Drawing a pattern draws a different design in each rectangular
cell of the pattern. To create an infinite pattern, apply
make-rectangular-tile to a pattern.
A stencil is a special kind of pattern that contains only opacities.
| make-pattern | array designs | [Function] |
Each cell of a pattern can be regarded as a hole that allows the design in it to show through. Each cell might have a different design in it. The portion of the design that shows through a hole is the portion on the part of the drawing plane where the hole is located. In other words, incorporating a design into a pattern does not change its alignment to the drawing plane, and does not apply a coordinate transformation to the design. Drawing a pattern collects the pieces of designs that show through all the holes and draws the pieces where the holes lie on the drawing plane. The pattern is completely transparent outside the area defined by the array.
Each cell of a pattern occupies a 1 by 1 square. You can use transform-region to scale the pattern to a different cell size and shape, or to rotate the pattern so that the rectangular cells become diamond-shaped. Applying a coordinate transformation to a pattern does not affect the designs that make up the pattern. It only changes the position, size, and shape of the cells' holes, allowing different portions of the designs in the cells to show through. Consequently, applying make-rectangular-tile to a pattern of nonuniform designs can produce a different appearance in each tile. The pattern cells' holes are tiled, but the designs in the cells are not tiled and a different portion of each of those designs shows through in each tile.
This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified.
| pattern-width | pattern | [Generic function] |
| pattern-height | pattern | [Generic function] |
| make-stencil | array | [Function] |
This function is permitted to capture its mutable inputs; the
consequences of modifying those objects are unspecified. 14.3 Tiling
Tiling repeats a rectangular portion of a design throughout the
drawing plane. This is most commonly used with patterns.
| make-rectangular-tile | design width height | [Function] |
Applying a coordinate transformation to a rectangular tile does not change the portion of the argument design that appears in each tile. However, it can change the period, phase, and orientation of the repeated pattern of tiles. This is so that adjacent figures drawn using the same tile have their inks ``line up''.
14.4 Regions as Designs
Any member of the class region is a solid, colorless design. The design is
opaque at points in the region and transparent elsewhere.
Figure 14.1 shows how the design and region classes relate to
each other.

Transforming a uniform design simply returns the argument. Transforming a composite, flipping, or indirect design applies the transformation to the component design(s). Transforming a pattern, tile, or output record design is described in the sections on those designs.
| draw-design | medium design &key ink clipping-region transformation line-style line-thickness line-unit line-dashes line-joint-shape line-cap-shape text-style text-family text-face text-size | [Generic function] |
If design is an area, draw-design paints the specified region of the drawing plane with medium's current ink. If design is a path, draw-design strokes the path with medium's current ink under control of the line-style. If design is a point, draw-design is the same as draw-point .
If design is a color or an opacity, draw-design paints the entire drawing plane (subject to the clipping region of the medium).
If design is +nowhere+ , draw-design has no effect.
If design is a non-uniform design (see Chapter General Designs ), draw-design paints the design, positioned at coordinates (0,0).
CLIM implementations are required to support draw-design for the following cases:
| draw-pattern* | medium pattern x y &key clipping-region transformation | [Function] |
Note that transformation only affects the position at which the pattern is drawn, not the pattern itself. If a programmer wishes to affect the pattern, he should explicity call transform-region on the pattern.
Drawing a bitmap consists of drawing an appropriately aligned and scaled pattern constructed from the bitmap's bits. A 1 in the bitmap corresponds to +foreground-ink+ , while a 0 corresponds to +background-ink+ if an opaque drawing operation is desired, or to +nowhere+ if a transparent drawing operation is desired.
Drawing a (colored) raster image consists of drawing an appropriately aligned and scaled pattern constructed from the raster array and raster color map.
draw-pattern* could be implemented as follows, assuming that the functions pattern-width and pattern-height return the width and height of the pattern.
(defun draw-pattern* (medium pattern x y &key clipping-region transformation)
(check-type pattern pattern)
(let ((width (pattern-width pattern))
(height (pattern-height pattern)))
(if (or clipping-region transformation)
(with-drawing-options (medium :clipping-region clipping-region
:transformation transformation)
(draw-rectangle* medium x y (+ x width) (+ y height)
:filled t :ink pattern))
(draw-rectangle* medium x y (+ x width) (+ y height)
:filled t :ink pattern))))
Painting a gray or colored wash over a display.
Specify a translucent design as the ink, such as :ink (compose-in +black+
(make-opacity 0.25)) , :ink (compose-in +red+ (make-opacity 0.1)) , or
:ink (compose-in +foreground-ink+ (make-opacity 0.75)) . The last example
can be abbreviated as :ink (make-opacity 0.75) . On a non-color,
non-grayscale display this will usually turn into a stipple.
Drawing a faded but opaque version of the foreground color.
Specify :ink (compose-over (compose-in +foreground-ink+ (make-opacity 0.25))
+background-ink+) to draw at 25% of the normal contrast. On a non-color,
non-grayscale display this will probably turn into a stipple.
Drawing a tiled pattern.
Specify :ink (make-rectangular-tile (make-pattern array colors )) .
Drawing a ``bitmap''.
Use (draw-design medium (make-pattern bit-array (list
+background-ink+ +foreground-ink+)) :transformation
(make-translation-transformation x y )) .
| Drawing in Color | Contents | Index | Extended Stream Output |