Holmestorm
Holmestorm

Reputation: 103

Is it possible to access the glyph outline coordinates for a plotted string in R?

I am working on a personal project to develop wordcloud type graphics in R. I have some basic code working, but it is limited to detect collisions between words using the smallest rectangle that bounds each individual word.

I am wondering if it is possible to get access to the actual coordinates of the outline of the individual letters (glyphs?), so that I can pack words much closer to one another - and even do things such as plot a word inside the hole in the middle of a character 'o' for example.

All my searches have proved fruitless. This link seems relevant, but for TeX https://tex.stackexchange.com/questions/180510/how-to-get-intersection-points-of-two-glyphs

Upvotes: 1

Views: 264

Answers (1)

Holmestorm
Holmestorm

Reputation: 103

This question got very little traction, but after quite a lot of digging I managed to hack a bit of a solution together that worked for my purposes and am sharing for reference.

I wasn't able to get access to the plotted coordinates of characters, but instead I was able to make my own character glyphs, and plot them.

Seeing this answer https://stackoverflow.com/a/7745776/5825522 to an unrelated question started me on the path of using the grImport package to trace a postscript file. And I was able to hack a solution together (sample below) that eventually worked - although I can't confess to understanding the ins and outs of the postscript code and the XML parsing (as this was my first encounter with both topics!)

Note that during my research I also found this package https://github.com/yixuan/fontr which might be more useful for extracting actual plotted character coordinates, but it was beyond my ability to understand and use.

library(grImport)
library(magrittr)
library(xml2)

# Create postscript file for the letter 'S' in times new roman
cat("%!PS 
    /Times-Roman findfont
    10 scalefont 
    setfont 
    newpath 0 0 moveto (S) show",
    file="example.ps")

# Trace the postscript file to an XML file
grImport::PostScriptTrace("example.ps", "example.xml")

# Read the XML
xml <- xml2::read_xml("example.xml")

# Extract the XML node associated with the letter paths
letter_paths <- xml_find_all(xml, "text/path")

# Extract coordinates
x <- letter_paths %>% xml_find_all("move|line") %>% xml_attr("x") %>% as.numeric()
y <- letter_paths %>% xml_find_all("move|line") %>% xml_attr("y") %>% as.numeric()

# Remove last pair of coordinates as the post script tracing leaves undesired xy coordinates. 
# These corrections are tricky for glyphs that have 'holes' in them like 'O' and 'B'
x <- x[-length(x)]
y <- y[-length(y)]

# plot
plot(x,y, asp=1, type="l")
points(x,y)

The letter 'S'

And after some fiddling I was able to produce a glyph set that worked for me

Glyph set

Upvotes: 2

Related Questions