16
$\begingroup$

I'm trying to find an explanation for the different sizes I'm seeing for fonts added to graphics in different ways, and haven't yet located an easy to understand explanation. Here's a minimal example:

Graphics[
 {LightGray,
  Rectangle[{0, 0}, {72, 72}],
  Red,
  Style[
   Text["Hig", {0, 0}, {-1, -1}], 72,
   FontFamily -> "Times New Roman"],
  Black,
  First[
   First[
    ImportString[
     ExportString[
      Style["Hig", 
       FontFamily -> "Times New Roman", 
       FontSize -> 72], "PDF"],If[$VersionNumber>=13,{"PDF","PageGraphics"},"PDF"],
     "TextMode" -> "Outlines"]]]
  },
 PlotRange -> {{0, 100}, {0, 100}}, 
 Axes -> True, 
 Ticks -> {Table[x, {x, 0, 100, 10}], Table[x, {x, 0, 100, 10}]},
 Epilog -> {Text["72", {200, 75}], Line[{{0, 72}, {200, 72}}]}]

fonts

The red text doesn't change size when you resize the graphic, although everything else changes. The black text resizes along with everything else. But neither text seems to be the result of specifying 72.

Update

After changing the screen resolution to Automatic following @Sjoerd's suggestion, I can see how the red text is basically displaying at a fixed size that's independent of Mathematica. In this picture, the left image shows 72 dpi, the red font is using 70ish pixels of vertical space. The right image is at 'Automatic' (so presumably 133.51 for my machine, according to this site, and similarly uses up 70ish pixels.

resolutions

I'm still puzzled by the size of the black font, which doesn't seem to be related to the specified font size or to the screen resolution. Perhaps the PDF translation introduces another scaling factor.

$\endgroup$
1

3 Answers 3

8
$\begingroup$

The FontSize refers to printers points, which by convention are 1/72 of an inch. So the red 'Hig' is fixed to an external font size and will not scale with the graphic. However, you are right to say that this font size doesn't seem to be strictly 72 points... If you try:

Export["hig.pdf", Style["Hig", FontFamily -> "Times New Roman", FontSize -> 72]]

a quick comparison with 72pt text generated in Illustrator shows that the fontsize is ~51 pts or ~30% too small (the Mathematica 72pt text is on the right):

illustrator 72pt vs mma 72pt

I have no clue as to why Mathematica text is too small....

Your second block of text is converted to a scalable graphic by the ImportString[ ExportString[Style[...], "PDF"],"TextMode" -> "Outlines"]]] transform. Enclosing this routine in FullForm demonstrates that the text has been converted into a FilledCurvecomprised of nested lists (i.e. is no longer treated as text but rather as a scalable graphic element). As a result, it is scaled with the units of the graphic.

FullForm[ImportString[
  ExportString[
   Style["Hig", FontFamily -> "Times New Roman", FontSize -> 72], 
   "PDF"], "TextMode" -> "Outlines"]]

List[Graphics[ List[Thickness[0.0128601], Style[List[ FilledCurve[ List[List[List[0, 2, 0], List[0, 1, 0], List[1, 3, 3], List[1, 3, 3], List[1, 3, 3], List[0, 1, 0], List[0, 1, 0], List[0, 1, 0], List[0, 1, 0], List[0, 1, 0], List[1, 3, 3], List[1, 3, 3], List[1, 3, 3],<<.......>>List[59.7569, 11.0567]]]]], Thickness[0.0128601]]], Rule[ImageSize, List[78., 56.]], Rule[PlotRange, List[List[0., 77.76], List[0., 56.]]], Rule[AspectRatio, Automatic]]]

with,

FullForm[Style["Hig", FontFamily -> "Times New Roman", FontSize -> 72]]

Style["Hig", Rule[FontFamily, "Times New Roman"], Rule[FontSize, 72]]

Interestingly, even when scaled, the size disparity persists, as can be seen if you resize your graphic such that the red and black text overlap, then the grey square is approximately one inch wide...

$\endgroup$
4
  • $\begingroup$ The black text could also be seen as being about 51 'units' high too. Kind of consistent, in a funny way. $\endgroup$
    – cormullion
    Apr 17, 2013 at 14:57
  • $\begingroup$ @cormullion, yes, I think that is right. By the way, why are you using the First[first[ImportString[ExportString[..construct? where does it come from? $\endgroup$
    – geordie
    Apr 17, 2013 at 15:10
  • $\begingroup$ @geordie It's from the FilledCurve documentation page. $\endgroup$ Apr 17, 2013 at 15:11
  • $\begingroup$ @SjoerdC.deVries, Thanks, it looks like a handy hack! :] $\endgroup$
    – geordie
    Apr 17, 2013 at 15:19
8
$\begingroup$

As it is pointed out in my old answer here, graphics and text are displayed inside of the FrontEnd in the style environment defined by the ScreenStyleEvironment option while are Exported into "PDF" in the style environment defined by the PrintingStyleEnvironment option:

Options[$FrontEnd, {ScreenStyleEnvironment, 
  PrintingStyleEnvironment}]    
{PrintingStyleEnvironment -> "Printout", 
 ScreenStyleEnvironment -> "Working"}

The "Working" and "Printout" style environments are defined in the default Core.nb stylesheet and differ in the value of Magnification option which is set to 1 in the "Working" and to 0.8 in the "Printout" style environment correspondingly:

screenshot of the Core.nb stylesheet

It is possible to override the value of this option by setting it explicitly via Style:

text = Style["Hig", 72, FontFamily -> "Times New Roman", 
  Magnification -> 1]
textOutlines = 
 First[ImportString[ExportString[text, "PDF"], 
   "TextMode" -> "Outlines"]];
Style[textOutlines, Magnification -> 1]

screenshot

We can check that the outlines and the text have identical sizes:

Style[Show[textOutlines, 
  Prolog -> {Red, Text[text, {0, 0}, {-1, -1}]}], Magnification -> 1]

screenshot2

A step-by-step explanation HOW it works:

  1. As Sjoerd correctly points out in his answer, the glyphs are displayed on the screen with FontProperties -> "ScreenResolution" -> 72 by default. In practice it means that each displayed pixel on the screen corresponds to 1/72 of inch (when Magnification is set to 1) and so a glyph of height 72 printer's points will have height 72 pixels on the screen (even if on the level of operating system is set other resolution for rendering of fonts).
  2. The internal coordinate system of PDF file is defined in printer's points (one printer's point = 1/72 of inch). It means that if we Export a glyph of height 72 printer's points to PDF with Magnification -> 1 then the glyph will have height 72 units in the internal coordinate system of the PDF file. So when we convert the glyphs to outlines and Import the outlines we get a plot which internal coordinate system is defined in printer's points.
  3. The Graphics object created from the Imported PDF figure has AspectRatio -> Automatic and ImageSize set to the size of the imported figure in printer's points without any extra paddings:

    textOutlines // Options
    
    {ImageSize -> {108., 81.}, 
     PlotRange -> {{0., 108.}, {0., 81.}}, AspectRatio -> Automatic}
    

The combination of these factors gives us the situation when each unit on the plot corresponds to one pixel on the screen and is equal to one printer's point of displayed glyph (when Magnification is set to 1). So we get identical sizes of the glyphs and outlines. But when we turn on the Frame we add extra paddings and the coordinates no longer correspond to printer's points:

Style[Show[textOutlines, 
  Prolog -> {Red, Text[text, {0, 0}, {-1, -1}]}, Frame -> True], 
 Magnification -> 1]

screenshot3

For obtaining correct coordinate scalings we need to carefully define PlotRange, ImagePadding and ImageSize:

plotSize = {120, 100};(* in arbitrary units *)
imagePadding = 20;(* in printer's points *)
imageSize = plotSize + 2*imagePadding;(* in printer's points; now the internal 
   coordinate system of the plot will be in printer's points *)
plot = Style[
  Show[textOutlines, Frame -> True, 
   FrameTicks -> {{Automatic, {72}}, {Automatic, None}}, 
   GridLines -> {None, {72}}, ImagePadding -> imagePadding, 
   PlotRange -> {{0, plotSize[[1]]}, {0, plotSize[[2]]}}, 
   ImageSize -> imageSize, 
   Prolog -> {Red, Text[text, {0, 0}, {-1, -1}]}], Magnification -> 1]

screenshot4

$\endgroup$
5
$\begingroup$

I will not duplicate geordie's explanation of the scaling-with-graphics-resize part of the question.

The reason the displayed font looks too small is the setting of the "ScreenResolution" option (part of FontProperties) to 72, which used to be the default for decades, but is incorrect for most screens nowadays.

If you set it to Automatic (or perhaps the value you know is correct for your display)

SetOptions[$FrontEnd, FontProperties -> {"ScreenResolution" -> Automatic}]

you'll get a better match. Compare the default setting

enter image description here

with the Automatic one on my display

enter image description here

$\endgroup$
3
  • $\begingroup$ hmmm, how does it compare when exported to say Illustrator or Acrobat etc.? Does the size issue persist? $\endgroup$
    – geordie
    Apr 17, 2013 at 15:13
  • $\begingroup$ Your black text looks correct in both examples. I'll investigate that option now... $\endgroup$
    – cormullion
    Apr 17, 2013 at 15:30
  • $\begingroup$ @cormullion Actually, the option should have impact on the red letters. $\endgroup$ Apr 17, 2013 at 20:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.