惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
月光博客
月光博客
雷峰网
雷峰网
Google DeepMind News
Google DeepMind News
Y
Y Combinator Blog
Microsoft Security Blog
Microsoft Security Blog
M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
MongoDB | Blog
MongoDB | Blog
V
V2EX
博客园 - 【当耐特】
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
I
InfoQ
Martin Fowler
Martin Fowler
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hugging Face - Blog
Hugging Face - Blog
B
Blog
V
Visual Studio Blog
D
DataBreaches.Net
C
Check Point Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
F
Fortinet All Blogs

Red Blob Games: latest blog posts

Red Blob Games: English: a vs an Red Blob Games: Differential heuristics Red Blob Games: Responsive design calculator Red Blob Games: Academic citations Red Blob Games: Highlighting interactive code blocks Red Blob Games: Optimizing page size Red Blob Games: Writing a guide to SDF fonts Red Blob Games: URLs with trailing punctuation Red Blob Games: What I did in 2025 Red Blob Games: Goodbye Sass Goodbye Sass Red Blob Games: RotMG map seeds Red Blob Games: Mapgen4 Mapgen4's use of WebGL2 Red Blob Games: Mapgen4 river shader Red Blob Games: Mapgen4 renderer Red Blob Games: Harnessing ChatGPT hallucinations Red Blob Games: Let Let's write a search engine, part 2 of 2 Red Blob Games: Let Let's write a search engine, part 1 of 2 Red Blob Games: Hexagon conversions Red Blob Games: Mapgen4 trade routes Red Blob Games: De-optimizing mapgen4 Red Blob Games: Hexagon spiral coordinates Red Blob Games: Thoughts on Flash Red Blob Games: What I did in 2024 Red Blob Games: Hexagon page animations Red Blob Games: SDF Halos SDF Halos
Red Blob Games: SDF curved text
2024-10-10 · via Red Blob Games: latest blog posts
Blog post: 9 Oct 2024

Over the last few posts I wrote about things I did to improve font quality, such as antialiasing and combining distance fields to merge outlines and halos. But I want to “pop up the stack” a bit and talk about one of the bigger goals for this project. I want to render text in styles that I’ve seen in maps, both online and offline, both fantasy and real. In particular, I want to apply spacing, rotation, and curvature to the labels.

Sample map
Sample map with labels

These are common in cartography, not only in fantasy maps like Tolkein’s but also in real-world maps. Eduard Imhof’s classic 1975 paper, Positioning Names on Maps[1] has a ton of great advice on how to position labels, and not only recommends curving text, but also sketches out examples:

Imhof paper, figures 40,41 showing label placement on a mountain pass Imhof paper, figure 42 showing label placement along rivers

Clear areal association often requires bending and spreading a name so that it is stretched as much as possible across the horizontal axis of an area.
Figures 40, 41, 42 from Imhof’s paper

I’ve had this paper sitting on my computer desktop since 2011. And I’m sure I was interested in this topic long before then. I will be re-reading it again before writing a label placement algorithm. Both Apple Maps and Google Maps use curved text, as shown in these examples:

curved labels on Apple Maps curved labels on Google Maps

Screenshots: curved labels on Apple and Google maps

Fantasy maps used curved text too. Tolkein’s Lord of the Rings maps used curved text for areas and rivers. Scott Turner’s inspirational blog includes a post Labeling the Coast part two[2] in which he shows how he analyzed the coastline to find a suitable curved arc, and also that he liked curved arcs better than more complex paths. There are also posts on Cartographers Guild[3] about when and how to use curved labels.

So I want to implement curved labels.

To figure out how to make text flow along a curve, I first sketched it out on paper, then made a standalone interactive widget. There are three cases to handle:

  1. Positive curvature: the text should be positioned along the baseline.
  2. Zero curvature: the text is not curved.
  3. Negative curvature: the text should be positioned along the ascender line.
Three curvature cases: >0, =0, <0

If I always curve at the baseline, the tops of the characters are too close together. That’s why I have to curve at the ascender line instead of the baseline when the curvature is negative:

Upwards curvature at baseline makes letters too close together

After calculating the geometry, there are two ways I know of to render the curved text.

  1. “Curving” or “Wrapping”: Position and rotate each letter along a curved path, then render them onto the intermediate combined distance field.
  2. “Shaping” or “Warping”: Draw the letters first onto the intermediate combined distance field, then distort the entire label into a curved shape.

One advantage of warping over wrapping is that it allows for many more effects, such as these:

More shapes to fit the text to

However, whenever stretching the label non-uniformly, the distance field gets distorted. In this example the white halo on the left side (The) is much larger vertically than horizontally. I can find a way to fix this but I decided not to pursue it, since I was primarily interested in curved text and not arbitary warpings:

Trapezoid shows the distance field is non-uniform

Google’s guide[4] says wrapping generally works better than warping, but I ended up trying warping first, and decided I liked it well enough. However, in the last post I had said next time I might choose to not use an intermediate combined distance field. I think without that step, it would be easier to use wrapping than warping.

Using distance fields, I can apply the outline, halo, and antialiasing after the curving step. I’m very happy with the way the curved labels turned out.

Another sample map
Sample map with labels