3 Revised TextToOutlineShifted a bit
source | link

New Version: Added ReferenceLetter as an option (for easier tinkering)

Options[TextToOutlineShifted] = Join[
   {
    ShiftTo -> "Baseline",
    ReferenceLetter -> "x",
    ShowReferenceLetters -> False,
    AlignLeft -> False
    },
   Options[Style]
   ];

TextToOutlineShifted[text_, opts : OptionsPattern[]] := Module[
   {referenceLetter = 
     TextToOutline[OptionValue[ReferenceLetter], opts],
    content = TextToOutline[text, opts],
    getBoundingBox,
    referenceLetterBoundingBox,
    contentBoundingBox,
    shift,
    leftShift},

   getBoundingBox[textCurve_] := 
    CoordinateBoundingBox[Flatten[textCurve[[2, 1, 1, 2]], 1]];
   referenceLetterBoundingBox = getBoundingBox[referenceLetter];
   contentBoundingBox = getBoundingBox[content];

   shift = -Piecewise[
        {
         {{#[[1, 1]], #[[1, 2]]}, 
          OptionValue[ShiftTo] == "Baseline"},
         {{#[[1, 1]], #[[2, 2]]}, OptionValue[ShiftTo] == "Midline"},
         {{#[[1, 1]], Mean@{#[[1, 2]], #[[2, 2]]}}, 
          OptionValue[ShiftTo] == "Center"}
         }
        ] &@(referenceLetterBoundingBox);

   leftShift = If[
     OptionValue[AlignLeft],
     {-contentBoundingBox[[1, 1]] - 
       referenceLetterBoundingBox[[1, 1]], 0},
     {0, 0}
     ];

   Translate[
    If[OptionValue[ShowReferenceLetters], {referenceLetter, content}, 
     content], shift + leftShift]
   ];

New Version: Added ReferenceLetter as an option (for easier tinkering)

Options[TextToOutlineShifted] = Join[
   {
    ShiftTo -> "Baseline",
    ReferenceLetter -> "x",
    ShowReferenceLetters -> False,
    AlignLeft -> False
    },
   Options[Style]
   ];

TextToOutlineShifted[text_, opts : OptionsPattern[]] := Module[
   {referenceLetter = 
     TextToOutline[OptionValue[ReferenceLetter], opts],
    content = TextToOutline[text, opts],
    getBoundingBox,
    referenceLetterBoundingBox,
    contentBoundingBox,
    shift,
    leftShift},

   getBoundingBox[textCurve_] := 
    CoordinateBoundingBox[Flatten[textCurve[[2, 1, 1, 2]], 1]];
   referenceLetterBoundingBox = getBoundingBox[referenceLetter];
   contentBoundingBox = getBoundingBox[content];

   shift = -Piecewise[
        {
         {{#[[1, 1]], #[[1, 2]]}, 
          OptionValue[ShiftTo] == "Baseline"},
         {{#[[1, 1]], #[[2, 2]]}, OptionValue[ShiftTo] == "Midline"},
         {{#[[1, 1]], Mean@{#[[1, 2]], #[[2, 2]]}}, 
          OptionValue[ShiftTo] == "Center"}
         }
        ] &@(referenceLetterBoundingBox);

   leftShift = If[
     OptionValue[AlignLeft],
     {-contentBoundingBox[[1, 1]] - 
       referenceLetterBoundingBox[[1, 1]], 0},
     {0, 0}
     ];

   Translate[
    If[OptionValue[ShowReferenceLetters], {referenceLetter, content}, 
     content], shift + leftShift]
   ];
    Bounty Ended with 100 reputation awarded by user1747134
2 Formatting
source | link

Different Textstexts

Different Font Sizesfont sizes

Example where this doesn't work

Example where this doesn't work

Different Texts

Different Font Sizes

Example where this doesn't work

Different texts

Different font sizes

Example where this doesn't work

1
source | link

One possible technique is to use a reference letter (e.g., "x") to determine the baseline (and/or midline). I imagine "x" should work for most cases, though definitely not all (see last example below).

This should take care of the "different strings" issues described in the comment of @user6014's answer. I'm not a typography expert by any means, but hopefully I have enough of it right to work for this problem.


Examples

Different Texts

exampleTexts = {"bar", "_bar"};

Show[
 Graphics[
    {EdgeForm[{Black, Opacity[0.6]}],
     TextToOutlineShifted[
      #,
      FontFamily -> "Helvetica",
      FontSize -> 10,
      FontColor -> RandomColor[],
      FontOpacity -> 0.6,
      AlignLeft -> True
      ]
     }
    ] & /@ exampleTexts,
 Axes -> True
 ]

Example with different texts

Different Font Sizes

exampleFontSizes = {1, 2, 4, 8};

Show[
 Graphics[
    {EdgeForm[{Black, Opacity[0.6]}],
     TextToOutlineShifted[
      "Fubar",
      FontFamily -> "Helvetica",
      FontSize -> #,
      FontColor -> RandomColor[],
      FontOpacity -> 0.6,
      AlignLeft -> True
      ]
     }
    ] & /@ exampleFontSizes,
 Axes -> True
 ]

Example with different font sizes

Example where this doesn't work

A quick fix here (depending on the font) would be to try to use a different reference letter.

Show[
 Graphics[
  {EdgeForm[{Black, Opacity[0.6]}],
   TextToOutlineShifted[
    "Fubar",
    FontFamily -> "Zapfino",
    FontSize -> 12,
    FontColor -> RandomColor[],
    FontOpacity -> 0.6,
    AlignLeft -> True,
    ShowReferenceLetters -> True
    ]
   }
  ],
 Axes -> True
 ]

Example where this doesn't work


TextToOutlineShifted

Along with the default options from Style, TextToOutlineShifted also takes:

  • ShiftTo:
    • "Baseline" (default): Aligns the horizontal axis to the bottom of the reference "x"
    • "Midline": Aligns the horizontal axis to the top of the reference "x"
    • "Center": Aligns to the line halfway between the baseline and midline (not sure if this is a thing, or is even useful, but I added it just in case)
  • ShowReferenceLetters: If True, displays the reference "x" used.
  • AlignLeft: If True, aligns the leftmost point of the content text with the vertical axis.

Note here I've defined TextToOutline as follows:

TextToOutline[text_, opts : OptionsPattern[]] := 
  ImportString[
    ExportString[Style[text, FilterRules[{opts}, Options[Style]]], 
     "PDF"], "TextMode" -> "Outlines"][[1, 1]];

...and the code for TextToOutlineShifted:

Options[TextToOutlineShifted] = Join[
   {
    ShiftTo -> "Baseline",
    ShowReferenceLetters -> False,
    AlignLeft -> False
    },
   Options[Style]
   ];

TextToOutlineShifted[text_, opts : OptionsPattern[]] := Module[
   {xref = TextToOutline["x", opts],
    content = TextToOutline[text, opts],
    cbb,
    xrefbb,
    contentbb,
    shift,
    leftshift},

   cbb[letter_] := 
    CoordinateBoundingBox[Flatten[letter[[2, 1, 1, 2]], 1]];
   xrefbb = cbb[xref];
   contentbb = cbb[content];

   shift = -Piecewise[
      {
       {{xrefbb[[1, 1]], xrefbb[[1, 2]]}, 
        OptionValue[ShiftTo] == "Baseline"},
       {{xrefbb[[1, 1]], xrefbb[[2, 2]]}, 
        OptionValue[ShiftTo] == "Midline"},
       {{xrefbb[[1, 1]], Mean@{xrefbb[[1, 2]], xrefbb[[2, 2]]}}, 
        OptionValue[ShiftTo] == "Center"}
       }
      ];

   leftshift = If[
     OptionValue[AlignLeft],
     {-contentbb[[1, 1]] - xrefbb[[1, 1]], 0},
     {0, 0}
     ];

   Translate[
    If[OptionValue[ShowReferenceLetters], {xref, content}, content], 
    shift + leftshift]
   ];

In any case, that's my attempt for the moment. (Feedback is very much welcome, as always.) Hopefully everything is clear, and that it's at least somewhat close to what you have in mind!