Wednesday, July 10, 2019

Map Borders (Part 15)

The last item on my map borders TODO list (ignoring bugs and items I've added since I started this) is corner boxes.  Many maps have some sort of decoration on the corners of the borders.  Corner boxes are typically small frames that enclose an ornament or artwork.  Here are some examples from my inspiration maps:

The first example here is a complex box that mimics the actual border, but in most cases the corner box is a fairly simple square (occasionally round) frame that encloses an illustration of some sort.

As the first example above illustrates, the corner box is really just a miniature map border.  So the obvious way to draw one is just to reuse the existing map border code.  Unfortunately, I wasn't thinking that far ahead when I wrote the map border code.  Currently, it decides where to draw the border by finding the edges of the map.  To reuse this code for corner boxes, I'm going to have to break that dependency, by replacing references to the map edges with references to a new parameter that will define where to draw the border.  This is the perfect use case for a refactoring tool, but lacking that I make do with find & replace.

With that in place, I can now experiment with drawing borders in other places.  Here's a test where I just draw a simple line border into the (hardcoded) upper left of the map:
So at least the basic capability is there.  Let me move on to actually using these on a map.

The first step is to figure out where to place the corner boxes  The box above is centered on the corner of the map, which is also the inside corner of the map border.  That's not really the right solution.  If you had a very thick border, the corner box would be increasingly off-center (as it is somewhat in the example above).  Instead, the corner box needs to be centered on the map border.  This is a little tricky to figure out, because the Map Border Description Language lets me place border elements quite flexibly, so (for example) the last element is not necessarily the furthest out from the corner.  Fortunately, I already have to figure this out for other reasons, so after the map border is drawn I know where to center the corner box.

Here's an example showing the corner box correctly centered on the map border:

The second step is to decide how big to make the corner box.  The minimum size should not be smaller than the map border, but for very narrow map borders should still be big enough to be a “box."    The maximum size is a matter of taste, but a range up to (say) 20% bigger than the minimum sizes seems reasonable.  Here are some examples showing box sizes with various thin and thick borders:

In that last example, the black and white scale has actually been placed inside the map area, so it is ignored for purposes of placing and sizing the corner box.

The third step is to to block out the map border behind the corner box.  I can do this by drawing a white rectangle before I draw the corner box. This is a little trickier than you might first think, because I need to block out the area underneath the border of the corner box as well.  That's because the corner box border might have spaces in it:
I can't just block out the interior of the corner box, or the map border will show through between the two lines of the corner box.  However, (just like the map border) I don't know how big the corner box is until after I draw it, which makes it hard to block out before I draw it!

The solution is to draw the corner box first, draw a white box the same size on top of the border, and then pop the corner box drawing back up on top of the white box.  That gets me to here:
So far I've just been using a hard-coded border for the corner box.  I'd like to have some variety in the borders of the corner boxes, although since the corner box is small, the border cannot be too wide.   I took the grammar I'm using for map borders, eliminated most options, and modified the patterns option to create only very tiny patterns.  Most of the corner boxes are single or double lines, but other variants are now possible:
Of course there are combinations that don't look very good:
After some experimenting, I've modified the rules so that thin map borders get thin corner box borders, and to add a chance for the corner box to have the same border as the map.  The latter produced this interesting map:
Here Dragons Abound is trying to fill the corner box sides with the braid, but they're too short to fit more than a single braid.

Corner boxes are a nice embellishment by themselves, but they're usually filled with an illustration to add more interest.  Dragons Abound could add a canned illustration to the corner box, and while I may add that as an option, it's not really procedural generation.  Dragons Abound's ability to create illustrations are somewhat limited, but there are a few options.

One possibility is to draw a Celtic knot within the corner box:
For the moment I'm using a 7x7 braid.  I could make this a random knot, but at this size that doesn't provide a lot of interesting variety.

Another easy option is to repurpose the flower shape that I'm using in pattern borders:
Same thing for stars:

One of my inspirational maps has runes in the corner boxes, so let me implement that.  I have a variety of text-related utilities, so some of this is just finding some good rune fonts and adding them to the list of fonts used in the program.

Finding fonts is a bit tricky than you might expect, though.  It's very hard to tell how big a piece of text is in SVG.  You can certainly get a bounding box for the text, but that turns out to include space for descenders (i.e., the bottom part of a lower-case g, for example) and some space at the top of the text, whether your actual text is using that space or not.  So doing something like centering text in a box is much more difficult than you might expect, because there will be unexpected extra space above and below the characters.  Even worse, if the font doesn't have the proper metadata (and many free fonts you'll find don't) then this measurement is even worse.  Long story short, before I can use a font in the program I have to play with it to see how well it actually works.  So picking out some rune fonts involves finding them, downloading and installing them, trying them out one at a time in the program. It all takes much more time than I would like.

But once I have a few fonts in place, I can draw a random character from the font in the corner box:
Because characters are usually taller than they are wide, two characters often fit into a square box as well as one:

With the flower and star illustrations, it looks best to have the same illustration in each corner.  For runes, it also looks okay to have a different rune in each corner:
That's about it for the easy illustration options.

To wrap up, if you go back to the very first corner box example in this posting:
You'll see that this corner box is actually recursive -- the corner box itself has corner boxes!  So the question you're asking yourself right now, is “Is Scott crazy enough to implement recursive corner boxes in Dragons Abound?!?"

Well... no.  Sorry :-).  So I believe that's about it for corner boxes for now.  Next time will probably be clean-up and bug fixes for borders.