### 2.3.3 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 [Function]	`

Arguments: array inks

Summary: Returns a pattern ink that has ``` (array-dimension``` ``` array``` ``` 0)``` cells in the vertical direction and ``` (array-dimension``` ``` array``` ``` 1)``` cells in the horizontal direction. array must be a two-dimensional array of non-negative integers less than the length of inks . inks must be a sequence of designs. The design in cell ( i, j ) of the resulting pattern is the n th element of inks , if n is the value of ``` (aref``` ``` array``` ``` i j)``` . For example, array can be a bit-array and inks can be a list of two inks, the ink drawn for 0 and the one drawn for 1.

Each cell of a pattern can be regarded as a hole that allows the ink in it to show through. Each cell might have a different ink in it. The portion of the ink that shows through a hole is the portion on the part of the drawing plane where the hole is located. In other words, incorporating an ink 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 inks 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.

This function captures its mutable inputs; the consequences of modifying those objects are unspecified.

Tiling repeats a rectangular portion of a pattern throughout the drawing plane.

`make-rectangular-tile[Function]	`

Arguments: pattern width height

Summary: Returns a pattern that, when used as an ink, tiles a rectangular portion of the pattern pattern across the entire drawing plane. The resulting pattern repeats with a period of width horizontally and height vertically. width and height must both be integers. The portion of pattern that appears in each tile is a rectangle whose top-left corner is at (0, 0) and whose bottom-right corner is at ( width, height ). The repetition of pattern is accomplished by applying a coordinate transformation to shift pattern into position for each tile, and then extracting a width -by- height portion of that pattern.

Applying a coordinate transformation to a rectangular tile does not change the portion of the argument pattern 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."

`draw-pattern*[Function]	`

Arguments: sheet pattern x y ``` &key``` clipping-region transformation

Summary: Draws the pattern pattern on the sheet sheet at the position ( x, y ). pattern is any pattern created by make-pattern . clipping-region and transformation are as for with-drawing-options or any of the drawing functions.

Note that transformation only affects the position at which the pattern is drawn, not the pattern itself. If you want to affect the pattern, you should explicitly call transform-region on the pattern.

You draw a bitmap by drawing an appropriately aligned and scaled pattern constructed from the bitmap's bits. A 1 in the bitmap corresponds to +foreground- ink+ . 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* (sheet 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`
`                 (sheet`
`                  :clipping-region clipping-region`
`                  :transformation transformation)`
`                 (draw-rectangle* sheet x y`
`                                  (+ x width) (+ y height)`
`                                  :filled t :ink pattern))`
`                (draw-rectangle* sheet x y (+ x width) (+ y height)`
`                                 :filled t :ink pattern))))`

Common Lisp Interface Manager 2.0 User's Guide - 22 Dec 2009