# Print Layout

**Status**: Implemented | 2025

**Author**: Toluwaleke Ogundipe

**Reviewers**: Federico Mena Quintero, Jonathan Blandford

## Goals

- Design a structure to Collect all data required to render a puzzle to a
  print format.
- Ease out the rendering stage of printing puzzles.

## Overall Approach

A **print layout** is a structure contaning all the data (geometry, strings,
grid layout(s), etc) required to render a puzzle to a printable format,
and is independent of the puzzle itself. It is somewhat analogous to a
[grid layout](./grid-layout.md) but encompassing most of the puzzle data,
not just the grid.

The print layout engine takes a layout template and a puzzle, and generates
a concrete layout.

### Geometry Units

All print layout geometry are in millimeters (mm), with the exception of font
sizes which are in points at 72 points-per-inch.

### Generating A Layout

A layout is generated **page-by-page**, flattening each tree of template
elements into an **array of layout elements**. In the process, relevant data
is pulled from the puzzle to construct these elements.

A pre-defined **page margin** is applied and **rectangular extents** are
computed for every element **based on the ratios** from the template and a
pre-defined **element margin** which applies to **non-DIVIDER** elements only.

The layout engine has its own element kinds, slightly different from the
template element kinds. The reason for this is that some template element
kinds diversify at the layout stage, while others simply don't exist.
Also, new unrelated kinds may be added at the layout stage.

In addition to the elements defined by the template, eache page may also
contain a footer element which contains the `Puzzle:url` property, if set.

### Layout Elements

The element kinds and the data they contain are as follows:

> **NOTE:** Aside the kind and the kind-specific data, every element also
> contains its rectangular extents.

- **TEXT**: This contains:

  - A string (possibly containing Pango Markup).
  - A font description.
  - An alignment description.

  Elements whose strings would otherwise be empty are omitted from the layout.

- **GRID**: This contains a `GridLayout` of the puzzle in its initial state.
- **CLUES_SOURCE**: This contains:

  - Its own ID.
  - An array of clue set(s).
  - The ID of the source's first extension.
  - The font description.

- **CLUES_EXTENSION**: This contains:

  - Its own ID.
  - Its source's ID.
  - The ID of the next extension in the flow.
  - The font description, if specified in the template.

- **SOLUTION**: This contains a sub-kind and the data for the effective sub-kind.
  There are a couple of sub-kinds:

  - **NONE**: No data.
  - **GRID**: The data is a `GridLayout` with every cell containing its solution.
  - **FLIPPED_GRID**: Like **GRID**, but to be fliiped (at the rendering stage).
  - **QRCODE**: The data is (preferably encoded) image data. This kind is yet to
    be designed or implemented.

  > **NOTE**: How the sub-kind will be derived is yet to be decided (see the
  > Open Questions section).

- **DIVIDER**: This contains no specific data.

  - Its orientation is opposite to that of the containing box.
  - Its extents are derived from the width/height of the containing box and a
    pre-defined thickness.

Note that the **CLUES** template element kind has been diversified into
**CLUES_SOURCE** and **CLUES_EXTENSION**.

The following template element kinds have been eliminated (for the reasons
stated):

- **SPACER**: It is just blank space.

  It is accounted for in the computation of element extents but there's
  no reason to keep it around.

- **BOX**: Concrete layouts are flat, unlike layout templates.

  The pre-defined divider thickness is subtracted from the width/height
  of the box for every divider in the box, and the other (non-divider)
  sub-elements split up what's left based on their ratios.

The following template element kinds have been transformed into the more
generic **TEXT** element kind:

- **TITLE**: The string contains the `Puzzle:title` property.
- **METADATA**: The string contains the following properties of the puzzle,
  as many as are set:

  - `author`
  - `date`
  - `publisher`
  - `copyright`

- **INTRO**: The string contains the `Puzzle:intro` property.
- **NOTES**: The string contains the `Puzzle:notes` property.

### Laying Out Clues

Clues are stored by _sources_ (**CLUES_SOURCE** elements). The clues stored by
a _source_ feeds that _source_ and all _extensions_ (**CLUES_EXTENSION**
elements) in the same _flow_, if any. Every _source_ contains an array of zero
or more clue sets.

The number of clue sets a source has is determined by the clue direction of the
corresponding **CLUES** template element. If the direction is:

- **ALL**, the _source_ has as many clue sets as the puzzle has.
- **ANY**, and:

  - the puzzle has an available clue set, the _source_ has one clue set.
  - the puzzle has no clue sets left (i.e all claimed up by other _sources_),
    the _source_ has zero clue sets.

- a standard **IPUZ** direction, and:

  - the puzzle has clues in that direction, the _source_ has one clue set.
  - the puzzle has no clues in that direction, the _source_ has zero clue sets.

Each clue set contains the clue set label and an array of clues. Each clue contains:

- the clue number or label, as a string
- the clue text
- the clue's enumeration display string
- a `GridLayout` for the clue's cells only, for acrostic puzzles

## Open Questions

- Concerning **SOLUTION** elements:

  - How do we derive/set the sub-kind? (considering passing it via a config struct)
  - How do we go about printing the solution of a different puzzle?

## Areas For Improvement

- [ ] Tabular layout for acrostics, as in:
      https://s3.us-east-2.amazonaws.com/hedgedoc-gnome-org/uploads/6bc221d6-0ede-4af3-bf29-251ec5254a40.png
