Sunday, February 14, 2021

Knurden Style: Labels & Etc (Part 6)

In previous postings, I implemented the major portions of Daniel Hasenbro's Knurden map style, the mountains and the forests.  I also previously handled the shoreline and the basic colors.  There remain a few more elements to implement.

One important element is the labeling.  The excerpt above shows examples of the important label types.

The font used for the labels is one of the IM Fell fonts (DW pica).  The city labels are filled in a light reddish brown, and stroked in a dark red brown.  There are two other potential elements to labels.  The first is a mask that blocks out the background around the letters; these labels do not appear to have any masking.  The second is a halo.  This is usually a white blur that surrounds the letters and also helps separate them from the background.  The Knurden city labels have a narrow, somewhat transparent white blur.  Matching the style is then a matter of trying different colors, sizes, blurs and so on until I get something that looks approximately the same.
The colors are still a little bit off because fonts are treated somewhat different in SVG than in Photoshop, but it's a fairly close match.

The labels for woods use an italic version of the IM Fell font.  The letters are outlined in the same dark brown but filled with white, and there does not seem to be a mask or halo.  The forest labels are also fairly small, about 60% or so the size of the town labels.  But here I run into a problem.

The italic version of the IM Fell font has characters that are a little too skinny at the size I need for the forest labels.  In theory, that's not a problem, because you can change the thickness of fonts by using the CSS “font-weight" style.  By setting the font-weight appropriately, I can get a thickness that is readable and roughly matches the Knurden map.  However, I discovered that setting font-weight breaks the font stroke (outline).  You can make the font fatter, or you can have an outline, but you can't have both.

This is probably because font outlining is done using the generic SVG shape stroking capability.  The text is just treated as an SVG shape and then the perimeter of the shape is stroked to create an outline.  Font weight, on the other hand, is a CSS style feature that presumably happens later in the display pipeline.  If the shape is already stroked, it can't then be made fatter.

As it turns out, there is a CSS style to stroke a font as well, called “-webkit-text-stroke"  So you might guess that it would be possible to use this in combination with font-weight to get weighted, stroked text.  Unfortunately you'd be wrong, as -webkit-text-stroke doesn't seem to work on SVG text.

Another possibility for creating an outline effect is to put two copies of the same text on top of each other, and make the back copy thicker using font-weight so that it shows around the edges of the top copy.  Then make the top copy the fill color and the bottom copy the stroke color, and it will appear that you have stroked the outside of the text in a different color.  And while this does work, it turns out that the difference in thickness between the heaviest and the lightest font weights is still pretty minimal, so that the stroke is very thin.  
Just a hair of black peeking out.  So on a practical level, this doesn't work.

Yet another possibility is to make the bottom copy bigger by changing it's size.  The problem with this idea is that when the font changes size, the individual characters don't stay centered on each other.  The space between characters also gets bigger, and this throws everything off.
In theory I suppose you could handle every character separately and line them up correctly, but ... not going to go down that rabbit hole!

After much experimentation, I found yet another way to get the desired effect.  There's a little-known attribute for SVG text called “paint-order" which can be used to modify the order in which the fill, stroke and markers get drawn.  It turns out that when the stroke is drawn first (instead of the fill), “font-weight" starts working!  
I'm not entirely sure of the reasoning here, but I'll take it!

(I later thought of another way to achieve this effect.  Draw the text first with a thick outline, and then draw the text with no outline over the top.   That might work.  It seems there are many ways to skin this particular cat -- I'm glad at least one of them works!)

With this fix in place it's straightforward to get a reasonably close match:
There are only two river labels on the Knurden map, but they use an interesting technique that is used on other labels on the map as well:
For these labels, Daniel gets a kind of “negative" effect by using a transparent light color for the font and surrounding it with a dark halo.  This is fairly straightforward in Dragons Abound, although it takes a lot of tuning to get the colors close (if not exactly the same):
One problem with this style of label is that it can be hard to read on a busy background:
So I may tweak it a bit to address that at some point.

Ocean labels are much as river labels, adjusted for the ocean colors, so I won't go into any big detail on them.  Region labels are like forest labels, but not italic and in all-caps.

With labels done, I want to go back to forests and pick up an interesting little trick from the Knurden map.  Although forests are done as large masses, Daniel also scatters some solitary trees around the map:
As in this example, the trees are normally scattered around the edges of forests and also along rivers.  The solitary trees sometimes appear as clumps of two, or less frequently, three.

Implementing this was a bit more challenging than I expected.  Finding the border around a shape is not very easy or efficient, and in this case often creates a torus shape (a polygon with a hole in it) which is tricky to work with.  Eventually I settled on iterating over all the underlying Voronoi polygons in the land and deciding for each one whether or not it was in the border area, and then whether or not it should contain a tree clump.  At any rate, after that I have isolated trees around the edges of the forest masses:
Now I can do something similar for rivers.  I'll look for locations near rivers that also have above average precipitation.  (As an aside: I don't actually keep the precipitation values by the time I'm generating these trees, but I do have the biomes for each location, so I can use the biomes as a proxy for the level of precipitation.)  That adds a scattering of trees alongside fertile rivers that get a lot of rainfall:
The last thing I want to replicate from Daniel's map are his rhumblines.  Normally rhumblines radiate from spots in the ocean, or from a compass.  Daniel has done something interesting by making them come from the middle of the land.  This makes them useless as navigational aids, but it looks pretty cool.  It looks a little odd to have these radiate from the exact center of my (square) maps, so I'll offset the lines upward a bit.

The last thing I want to replicate is something Daniel does on the larger islands:
He puts a white circle around the island, and fills the circle with transparent white to lighten the background.  I don't think this means anything; it appears to be just a decoration.  Still, it looks neat and I'd like to be able to duplicate it.

Picking the islands to decorate is an interesting problem.  Daniel doesn't decorate all of the islands, generally avoiding those that are in clusters with other large islands or too close to the mainland.  He also doesn't do this decoration on two islands close to each other.  Here's my first attempt to pick out islands:
I have a test to make sure an island is not too close to the mainland, but I've got the polarity of the test reversed, so I'm picking islands that are close instead of far.  Here's a second attempt:
This is better, but the upper island is too close to another big island.  I want these to be somewhat isolated islands (at least from other big islands).  Filtering for that gets me this:
Now I just need to adjust the circle and fill:
That's a pretty reasonable approximation.

There are a few other features of Daniels' map that I won't be reproducing.  His city icons are little works of art:
And while Dragons Abound's city icons are not terrible, they're not nearly as nice as this.  (But that's something I hope to revisit!)

Daniel also does something nice with his country borders by adding a halo effect:
I rather like that, and stylistically it fits in well with his labels.  Dragons Abound does do country borders and I could add this effect fairly easily, but I'm not happy with how Dragons Abound places borders so I don't use that at the moment.

Finally, there's a coast decoration Daniel does with a looping line on the inside of the coast:
That's very nice but I don't have any good ideas on how to easily recreate it, so I'm going to pass on that as well.

Next time, some complete maps!

No comments:

Post a Comment