Background shapes for cells

Status: Final | Implemented | 2022

typedef enum
{
  IPUZ_STYLE_SHAPE_NONE,
  IPUZ_STYLE_SHAPE_CIRCLE,
} IpuzStyleShapeEnum;

The ipuz spec says,

If an app supports shapebg, the only required shape is “circle”, which is supported by most crossword creation software. Apps can add support for additional shapes provided logical names are used, and no namespacing is required, as with Puzzazz extensions. This allows the set of supported shapes to grow over time as support is added, and Puzzazz is happy to help facilitate the naming of new shapes. The following shapes are known to be supported by one or more apps: circle, arrow-left, arrow-right, arrow-up, arrow-down, triangle-left, triangle-right, triangle-up, triangle-down, diamond, club, heart, spade, star, square, rhombus, /, , X.

Proposal

TL;DR - map shape names to SVG assets; render the cell shapebg from a little SVG.

Shape names

One option is to add enum values to IpuzStyleShapeEnum for all the cases that the spec mentions; this is easy to do and gives a clean, obvious API. These need to be mapped in the crosswords app to SVG asset names - not hard at all to do.

Another option is to replace IpuzStyleShapeEnum for just a string; ipuz_style_get_shapebg() would just return a string with the raw name obtained from the ipuz file. Given a name, the crosswords app can then construct name.svg or whatever. The advantage is that it becomes really easy to support new shapes; the disadvantage is a more stringly-typed API. The / and \ cases may need some special handling, which is not terrible, but still a special case to consider.

Middle-ground option: Keep IpuzStyleShapeEnum, but add an IPUZ_STYLE_SHAPE_UNKNOWN case, and add a const gchar *ipuz_style_get_raw_shapebg_name() that just returns the shapebg’s value as in the previous case.

I guess choosing an option involves knowing how much the ipuz spec tends to change, or how often extensions to shapebg appear out there in the wild. I’m not yet sure about libipuz’s policy for how much to normalize stringly-typed stuff into well-defined values, versus exposing raw values from the .ipuz for callers.

Shape assets

Create a bunch of simple SVGs, with square intrinsic dimensions, and render them at the appropriate size within a cell’s area.

One quirk is that play_cell_draw_shapebg already gets passed get_color(NORMAL) to use for the shape’s color.

The shapes in SVG assets can have a class suitable for tweaking from a stylesheet. Generate a CSS stylesheet on the fly with something like .shapebg-stroke { stroke: #aabbccdd; }; this can be then passed to rsvg_handle_set_stylesheet(). Having this sort of machinery will help later when we generate more things as SVG.

Rendering

If all goes well, a three-liner consisting of rsvg_handle_new_from_*(), rsvg_handle_set_stylesheet(), rsvg_handle_render_document().