# Layer Drawing

*Article*

Drawing the contents of a layer can be done for different output formats. These include black-and-white vector outlines (TrueType glif), color vector (OpenType COLR), bitmap graphics (PNG), and mixed formats that can hold both vector and bitmap graphics (SVG, PDF).

## Shapes

Shapes are are the building blocks of a layer. For drawing proposes, the shapes are in bottom-to-top order.

Shapes can carry attributes which influence their appearance.

### Path

The simplest shape is a *path*. A path generally has two or more nodes. Paths with one or zero nodes are possible while editing, but they are skipped for display purposes.

A path can be open (it has separate start a end nodes) or closed (there is a start-end node).

Using the hints API, path components (pars pro toto “corner components”) can be attached to a path. These provide reusable path parts like corners, caps, segments, and brushes.

### Component

*Component* shapes reference another glyph. A component has an affine transformation with which the referenced content is displayed. While a component generally references a specific layer of a glyph, it can also reference an interpolation of a glyph.

Components can be seen as a special form of shape groups where the members are referenced instead of contained.

### Shape group

A *shape group* has other shapes as its *direct members*. The *members* of a group are all shapes that the group contains, directly, or more deeply in nested groups. A group can provide attributes that affects the drawing of its members.

### Image

An image may be a vector or bitmap graphic. Vector images are supported in all output formats (image colors are only preserved in color vector output forms). Bitmap images are supported in bitmap or mixed output formats (some vector formats also support embedded bitmap images).

### Text

Text shapes contribute a character string set from a specific font to the outline.

## Pipeline

Drawing is performed on a input shape list. The caller of the drawing code is the *drawing client*.

The client provides a set of supported features which it can interpret itself. Unsupported features are processed on a best-effort basis by the drawing code and thus baked-in. For example, a client that does not support masks gets handed drawings with the masks already applied instead of getting the masks separately to apply it on its own terms.

### 1. HiddenShapes

Hidden shapes do not participate; they are skipped as if they were not part of the input.

### 2. CompoundPaths

Consecutive paths with equal attributes are combined to a *compound path*. The individual paths are then referred to as *subpaths*.

**CompoundPaths.Area**: The area of a compound path is determined using the non-zero winding rule.

### 3. Masks

Shapes with a mark attribute are *masks*. Mask paths are combined into compound mask paths analog to how non-mask paths are combined.

**Masks.Types**: There are two types of masks: *subtraction* and *intersection* masks. A subtraction mask removes its area from the subject. An intersection mask removes the area not shared with the subject.

**Masks.Initial**: Masks without subject do not participate, just like hidden shapes. This is the case for mask shapes that are at the start of the shape list without preceding non-mask shapes.

### 4. ShapeProcessing

A *shape run* is a list of shapes that is processed together. The subpaths of a compound path form a run; all other shape types form a singe-element run.

1. The path components of the shape run are decomposed.
2. The *PrepareLayer* callbacks are applied to a run, resulting in the *processed shapes*.

If the processed shapes are equal to the run, then processing is complete. Otherwise, the processed shapes are input into the pipeline recursively, until and including the ShapeProcessing step.

### 5. ShapeSlices

The input shapes list transformed to *shape slices*. There are different kinds of slices:

- A *pen slice* hold the contents of a compound path as interpreted by a pen.
- There are slices for an individual component, image, or text.
- A *group slice* combines slides into a hierarchy.
- An *error slice* replaces a part of the drawing that cannot be drawn (like an invalid component reference).

Masks are not part of the main slice content. Instead, a slice stores a separate list containing all masks following the slice’s content.

## Key Concepts

### Prepare Layer Callbacks

Prepare layer callbacks modify the shapes. These callbacks can perform arbitrary transformations like expanding a path to a stroke or applying effects such as corner components to a path. Preprocessing can only produce shapes with equal attributes and no hidden or mask shapes. (The attributes do not need to be equal to the attributes of the input to the callback.) This ensures the resulting shapes are still suitable as a shape slice of a composition unit. The callback is responsible for maintaining this invariant.

## API

### Shape API

- Hidden shapes: `BOOL isHidden` (`GSShapeKeyHidden` attribute)
- Mask shapes: `GSMaskType maskType` (`GSShapeKeyMask` attribute)

### Callbacks

- Prepare layer callbacks: `GSPrepareLayerCallbackName`

