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 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
GridLayoutof 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
GridLayoutwith 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:titleproperty.METADATA: The string contains the following properties of the puzzle, as many as are set:
authordatepublishercopyright
INTRO: The string contains the
Puzzle:introproperty.NOTES: The string contains the
Puzzle:notesproperty.
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
GridLayoutfor 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