Overlays on the grid
Status: Implemented | 2023
Motivation: Now that libipuz can read styles like barred
,
dashed
, etc., we need a way to display those decorations.
The drawing code currently assumes that the puzzle’s shape can be
represented by a grid of border items (corners and horizontal or
vertical edges), or cells — see grid-layout.md
.
One shortcoming of that scheme is that border items cannot easily draw outside of their allocation. For example, drawing a border that is thicker than the others is impossible. Similarly, a “dashed” border should have a hyphen struck through the border line; the dash overlaps the adjacent cells, but hopefully does not intrude their text.
If we allow for having decorations overlaid on the normal grid, we can solve these problems.
Overlaid decorations
When the GridLayout
is computed, we can also compute a list of
decorations that are to be overlaid on the grid. Each decoration has
a kind (barred, dotted, dashed, etc.) and a grid position.
For the sake of example, consider this 2x1 puzzle with a barred border in the middle:
┌───┬───┐
│ ┃ │
└───┴───┘
The grid coordinates of that barred border are (2, 1). So, the overlay struct would look like:
Overlay {
kind: barred,
x: 2,
y: 1,
}
The drawing code is then expected to translate that into actual coordinates for its drawing primitives, or to get as exotic as it wants by first creating a mask against which to clip the borders.
Holes in the border
Consider a dashed
style like this:
┌───┬───┐
│ - │
└───┴───┘
The vertical border needs a “hole” to allow the dash overlay to fit without being visually joined to the border.
The GridLayout
code can easily have a boolean has_hole
flag in
LayoutBorderHorizontal
and LayoutBorderVertical
. Then,
PlayBorder
draw such a border in two pieces, or however it needs.
Borders as SVG
At GUADEC we briefly talked about leaving the cells as PlayCell
widgets, but leaving all the border-drawing to an SVG overlay.
If we do that, the SVG can be generated with holes in the borders as appropriate, either with two little rectangles for each border-with-a-hole, or with masking or a clipping path.
Moving all border drawing to SVG seems like an easy way to do printing, at the expense of more complicated event handling for things like the editor, where the user will want to tweak border pieces individually. Maybe using widgets or SVG for borders are not exclusive, and we can take advantage of both?