Is there a way to outline text?

Import text as a FilledCurve in graphics, using PDF as an intermediate format. Below are modified examples from Documentation Center:

text = First[First[ImportString[ExportString[Style["Hi", Italic, FontSize -> 24, 
FontFamily -> "Times"], "PDF"], "PDF", "TextMode" -> "Outlines"]]];

Outline fonts using different edge and face forms:

Graphics[{EdgeForm[Directive[White, Thick]], Red, text},
Background -> Black, PlotRange -> {{-5, 25}, {-0, 20}}]

enter image description here

3D text effect:

Graphics[{EdgeForm[Opacity[0.5]], Table[{ColorData["TemperatureMap"][t], 
    Translate[text, 4 {-t, t}]}, {t, 0, 1, 1/10}]}, ImageSize -> Medium]

enter image description here


An important issue in the question seems to be that of speed. So as Sjoerd suggested, I wrote a solution that pre-outlines all the characters in a reasonable range of ASCII characters, and then does the replacements on an arbitrary string. The characters are stored in a table ascii, and their graphic replacements in asciiGraphics. I then define the replacement rule (rule) which is part of the function makeText:

ascii = CharacterRange[" ", "z"]

(*
==> {" ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", \
"+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", \
"9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", \
"G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", \
"U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", \
"b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", \
"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}
*)


asciiGraphics = 
  First@ImportString[
      ExportString[Style[#, FontFamily -> "Times", FontSize -> 44], 
       "PDF"], "TextOutlines" -> True] & /@ ascii;

rule = Dispatch[Thread[ascii -> asciiGraphics]];


Clear[makeText];
Options[makeText] = {"OutlineThickness" -> 1, "OutlineColor" -> White,
   "Color" -> Red}; 
makeText[string_, OptionsPattern[]] := 
 DisplayForm[
  Row[Characters[string] /. rule] /. 
   FilledCurve[
     x__] :> {EdgeForm[{AbsoluteThickness[
        OptionValue["OutlineThickness"]], 
       OptionValue["OutlineColor"]}],
     OptionValue["Color"],
     FilledCurve[x]
     }
  ]

The argument to makeText is the string to be rendered as outlined text. The thickness of the outlines is specified by the option "OutlineThickness". The other two options are "OutlineColor" and "Color" (of the filled areas).

The following is a demo - you win the game by sliding the slider to the right...

Manipulate[
 Style[Pane[
   makeText["Player 1 has " <> ToString[Floor[p]] <> " points", 
    "OutlineThickness" -> .7], ImageSize -> 360], 
   Background -> Black,
   Magnification -> 3
 ], {p, 0, 1000}]

manipulate

Edit

In response to the question in the comment:

By using Dispatch you can eke out a faster timing, and my focus was on getting fast execution. It won't matter much if you're dealing only with a short string. But if you're trying to translate a long text into outlined characters, the replacement is sped up when you first apply Dispatch to the rule.


In version 10, we can bypass exporting to PDF and re-importing and can outline text directly using region discretization functions. This is shown in the documentation of BoundaryDiscretizeGraphics.

reg = BoundaryDiscretizeGraphics[Text[Style["R", FontFamily -> "Cambria"]], _Text]

Mathematica graphics

The region can then be converted back to graphics, and the FilledCurve extracted.

WARNING: I just realized that the following line will often crash the kernel with 10.1.0 on OS X! Proceed with caution!

Cases[Normal@Show[reg], _FilledCurve, Infinity]

Normal is for getting rid of GraphicsComplex inside the resulting Graphics object.

If there is a direct way to go from a BoundaryMeshRegion to a FilledCurve, without having to use Show, please let me know!