[Tex/LaTex] Outlining (filling) glyph outline with text in TikZ

tikz-pgf

Original question

Is there any automated or semi-automated way of tracing outermost outline or whole path of letters in TikZ?

That I would be able (e.g. by using positioned nodes) to draw a letter using a letters, like shown below in my ascii-art (agreed, not really an art in this case):

   aaaaaaaa
  aaaaaaaaaa
 aa        aa 
            aa
   aaaaaaaa aa
  aaaaaaaaaaaa
 aa        aaa
 aaaaaaaaaaaaa
  aaaaaaaaa  aa

Comment

Martin's note made me certain what I already suspected, that within PGF/TikZ I am unable to trace any glyph from any font. IOW getting outline of glyph in a format supported by TikZ is a separate issue, rather not TeX-related, but worth being mentioned here.

Preliminary

Obtaining glyph outline

Let me summarize already mentioned techniques toward getting it to TikZ:

Obtaining glyph "filling"

It's something I wasn't asking at all, but it's other interesting idea that was brought up in answers:

  • convert for exporting glyph to text form and sed for cleaning it (provided by Jake)

Revised question

Mentioned earlier tracing is now part of preliminary process, as glyph outline (which can be any other path, but I'll stick with this particular example) is assumed to be known, so question should be rephrased.

What are the techniques available in TikZ to outline (fill) glyph outline with text [like one letter]?

Support for diversification of outline/fill style depending on "density" and in-path "neighborhood" (e.g. style changing in case of serifs, bent parts, etc. would be a nice feature.

I'm mostly interested in TikZ, but if you want to share non-TikZ solutions, do it immediately!

Supplementary question

If you know or just came up with not described yet method of obtaining glyph outline (or "filling") and you think it's interesting or simply worth to be mentioned, tell us about it.


Afterword, i.e. paragraph about myself

Maybe I should add that I'm really new to PGF/TikZ. Even though I was using LaTeX for about ~8 years already (with various frequency, so I am far from being an expert), I never really get to TikZ. Back in the old days I did some work with PSTricks, but frankly speaking I forgot all of that since then. I saw TikZ examples a few years ago and was amazed how PGF/TikZ can provide nice abstractions for performing different drawing tasks. Lately I had to touch TikZ and meanwhile I started to think about using it in less common way, i.e. for creating some "artistic" drawings instead of plain diagrams, sketches and whatever it is used usually. PGF/TikZ manual is great, no question, but you must know what to look for and even if you know that, your wording maybe not exactly the same as used in the documentation, which makes finding sometimes hard (it's true especially for non-native English speaker, as in my case). You may say: just browse it! Sure, but ~700 pages is pretty much, so it's rather not something you will read and understand well even within month (correct me if I am wrong). Sorry for too long OT paragraph, but it should clear some things, because it's not like I am unwilling to look to manual myself, just sometimes it's far more productive to ask experts, because they have invaluable things that cannot be found in manual – experience and better intuition!

Best Answer

Update 2012-04-10: There's a preliminary package for this on the TeX-SX Launchpad site. You need to run tex on the file pgflibraryshapes.letters.dtx to produce the TikZ/PGF libraries. To generate the font files themselves, you need x2svg.pe font (uses fontforge) to convert to SVG format and svgtopgf.pl font.svg prefix > <fontname>-<fontshape>-paths.tex to convert the SVG to PDF paths (the prefix should be of the form letter@<fontname>@<fontshape>@). Take a look at letter-shapes-test.tex for a sample. The normal and italic shapes for the STIX fonts are already converted. Due to the licensing, they are called stikz!


Do you want something like this?

traced letters

Here's the source code:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{%
  svg.path,
  decorations.text,
}

\begin{document}

\begin{tikzpicture}[scale=.3]
\draw[decorate,decoration={text along path,text={AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}}] svg "M707 0h-255v19c36 0 43 2 55 9c8 4 14 15 14 24c0 15 -7 42 -19 70l-41 94h-262l-46 -114c-5 -13 -9 -30 -9 -42c0 -31 22 -41 70 -41v-19h-199v19c58 6 67 27 126 167l206 488h20l246 -563c28 -65 42 -86 94 -92v-19zM447 257l-116 275l-115 -275h231z";
\draw[xshift=25cm,decorate,decoration={text along path,text={aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}] svg "M442 66v-28c-30 -38 -56 -48 -90 -48c-37 0 -59 20 -64 73h-1c-53 -60 -102 -73 -145 -73c-62 0 -105 38 -105 104c0 52 31 91 70 117c30 20 67 39 180 81v54c0 62 -33 90 -78 90c-40 0 -70 -22 -70 -49c0 -18 6 -21 6 -42c0 -19 -20 -41 -46 -41c-21 0 -43 19 -43 46
c0 26 16 58 51 80c28 18 70 30 115 30c56 0 94 -16 118 -45s28 -50 28 -111v-191c0 -46 13 -66 31 -66c16 0 26 5 43 19zM287 127v141c-62 -22 -103 -43 -128 -66c-24 -22 -34 -46 -34 -77c0 -53 30 -77 69 -77c20 0 41 5 58 16c29 20 35 34 35 63z";
\end{tikzpicture}
\end{document}

The method of producing this was fairly straightforward. I loaded the font in fontforge and exported it as an SVG font. That then gave me the fonts as SVG paths. Since TikZ can accept SVG format, I could then cut and paste that in to a TikZ document. That lot could be done beforehand so that there was a file with the paths already specified.


Edit (2012-01-29): I had occasion to want to do this with fairly arbitrary letters so semi-automated it. It's not "production" ready, as there's still the odd bit needed to make it truly usable with no extra tweaking, but it's at the usable-if-you-know-what-you're-doing stage.

  1. Convert the font to SVG. You need fontforge installed. Then the following script, made executable, will invoke fontforge and convert the font specified on the command line to SVG format (output saved in the current directory). Eg if it is saved as x2svg.pe (note the extension) then run as x2svg.pe /path/to/font/amazing-font.otf.

    #! /usr/bin/fontforge -script
    
    Open($1)
    Generate($1:t:r + ".svg")
    
  2. Extract the glyph paths from the resulting XML file. The following Perl script does a reasonable job: it should trim excess whitespace at the start and end as well. Also, one could do with a better naming scheme (I tried unicode, but that got confusing).

    perl -MXML::Twig -e '
    $xml = XML::Twig->new(
    twig_handlers => {
    glyph => sub { $n = $_->{att}{"glyph-name"}; $n =~ s/_//g; print  %% "\\svgletter{" . $n  . "}{" . $_->{att}{d} . "}\n";}
    }
    );
    $xml->parsefile("amazing-font.svg");
    ' > amazing-font.letters.tex
    
  3. Then in the TeX file, we just need to input this file and use the paths. Here's an example:

    \documentclass{article}
    \usepackage{tikz}
    \usetikzlibrary{svg.path}
    \newcommand\svgletter[2]{%
      \expandafter\def\csname svgglyph#1\endcsname{svg "#2"}
    }
    
    \input{TeXGyreSchola-Bold.letters}
    
    \def\STOP{stop}
    \def\NOTHING{}
    \def\empty{}
    \newcommand\outline[1]{%
    \outlinelet#1\STOP}
    
    \let\thisis\newpage
    
    \newcommand\vfillornewpage{%
      \ifx\thisis\vfill
      \let\thisis\newpage
      \else
      \let\thisis\vfill
      \fi
      \thisis}
    
    \newcommand\outlinelet[1]{%
      \let\next=\vfillornewpage
      \ifx#1\STOP
      \else
      \tikz[baseline=0pt] \draw[scale=0.09,ultra thick] \csname svgglyph#1\endcsname;
      \let\next=\outlinelet
      \fi
      \next}
    
    
    \begin{document}
    
    \outline{Outline}
    
    \end{document}
    

    With result:

    outlined font in TikZ

    Obviously, one could be more adventurous in the actual use of the path. Also, it would be good to have a more systematic way of getting the right scale factor (perhaps measuring the height of an "x"). Don't expect kerning!