# Monospaced fonts are not monospaced

I'm using Linux-x86-64 as operating system. Can someone explain this behaviour and maybe give a hint how to resolve it? Here are two lines of exact the same number of letters of a monospaced font:

Style["ZZZZZZZZZZ\n__________", 20, FontFamily -> "Courier"]

As output I get (here with 30 Z and 30 _)

But what I expect from a monospaced font like Courier is to have the same size for every letter (and why is the line dashed anyway?). @Oleksandr was so kind to give me mental support and tried the things on his Windows machine. There the output seems ok:

## More detailed question

What I really want is an image of arbitrary resolution of every letter. I thought when I use a combination of Style and Rasterize I can get equally sized images of them in exact the same form as they appear in text.

But there is (at least here) a clear difference between an assembled image from rasterized letters and a rasterized version of the string

ImageAssemble[
Rasterize[Style[#, 30, FontFamily -> "Courier"], "Image"] & /@
CharacterRange["A", "Z"]]

Rasterize[
Style[StringJoin[CharacterRange["A", "Z"]], 30,
FontFamily -> "Courier"], "Image"]

What I noticed is that the height of the letters is always the same, only the width varies. Looking at how many letters have which width gives here

Sort@Tally@First@
Transpose[
ImageDimensions[
Rasterize[Style[#, 30, FontFamily -> "Courier"], "Image"]] & /@
CharacterRange["A", "z"]]
(*
Out[138]= {{18, 25}, {19, 16}, {20, 8}, {21, 8}, {24, 1}}
*)

-
I see the same issue, but to a much lesser degree (also on Linux-x86-64). The first example is almost not noticeable to the eye and for the last I get: {{18, 53}, {19, 3}, {20, 1}, {21, 1}} which is somewhat better. I have no glue where this comes from, though. –  user21 Sep 19 '12 at 4:52
Well I don't have glue, but no clue either ;-) –  user21 Sep 19 '12 at 5:39
@ruebenko maybe glue is really necessary here to put the letters together. –  halirutan Sep 19 '12 at 16:32
@halirutan I get a similar output to yours, however changing the second line Style["ZZZZZZZZZZ\nAAAAAAAAAA", 20, FontFamily -> "Courier"] or Style["ZZZZZZZZZZ\n0123456789", 20, FontFamily -> "Courier"] seem to be good. Does it make sense ? –  b.gatessucks Sep 19 '12 at 18:55
@b.gatessucks Yes, this makes sense in this scenario. Usually, in Courier all letters should have the same width. In Linux, some letters are wider than others. While the difference between "Z" and "_" is very large, the width of "A" and "Z" seem to be equal. Therefore, your examples look ok. –  halirutan Sep 19 '12 at 21:44

While this is not an answer, I did not want to add it as a comment. The issue is not specific to Linux, happens under Windows as well (Win7 in particular). Also, it is not specific to font: any monospaced font seems to produce overhangs to the default frame of $n$ characters. While rasterized characters have different image dimensions, as pointed out by halirutan, this is not direclty related to the problem, as most of the operator characters comply with the expected dimensions (though they will cause a lot of problems) while those characters that have larger-than-unit dimensions (like A, W, M) might fit in nicely without an overhang. So I think that the different image dimensions and the kerning problem of e.g. "_" are different issues.

## 1. Rasterized characters

For the image assembly, I would suggest using a uniform image dimension applied via ImageCrop:

(* get standard character dimensions - find a suitable char, like "I" *)
unitDim = ImageDimensions@
Rasterize[Style["I", 30, Bold, FontFamily -> "Courier"], "Image"]
{18, 34}
"non cropped individual images"
ImageAssemble[
Rasterize[Style[#, 30, Bold, FontFamily -> "Courier"], "Image"] & /@
CharacterRange["A", "Z"]]

"cropped individual images"
ImageAssemble[
ImageCrop[
Rasterize[Style[#, 30, Bold, FontFamily -> "Courier"], "Image"],
unitDim] & /@ CharacterRange["A", "Z"]]

"rasterize as a whole"
Rasterize[
Style[StringJoin[CharacterRange["A", "Z"]], 30, Bold,
FontFamily -> "Courier"], "Image"]

While cropping individual images is a possible workaround, sadly I have no idea why rasterized characters end up being larger than the monospaced frame. The following test indicates, that this effect depends on FontSize and Magnification but not on ImageResolution:

chars = CharacterRange["A", "Z"]; charPos = Thread[chars -> Range@Length@chars];
resRange = {10, 100, 1000}; sizeRange = {10, 15, 20, 30, 50, 100}; magRange = {.5, 1, 2, 10};

data = Table[
style = {FontSize -> size, Magnification -> mag, FontWeight -> Bold, FontFamily -> "Courier"};
img = Rasterize[Style[#, Sequence @@ style], "Image", ImageResolution -> res] & /@ chars;
imgPos = Thread[img -> Range@Length@chars]; unitDim = ImageDimensions@img[["I" /. charPos]]; imgDim = ImageDimensions /@ img;
Cases[img, x_?((d = ImageDimensions@#) =!= unitDim &) :> chars[[x /. imgPos]]],
{res, resRange}, {size, sizeRange}, {mag, magRange}];

Column[MapThread[Labeled[TableForm[#1, TableHeadings -> {sizeRange, magRange}, TableDepth -> 2], "ImageResolution \[Rule] " <> ToString@#2, Top] &, {data, resRange}], Spacings -> 2]

Figure lists those rasterized characters that do not match the ImageDimension of the standard monospaced dimension (taken from "I"). Horizontal dimension: Magnification; Vertical dimension: FontSize. I would consider this a bug.

## 2. Monospaced characters are not monospaced

Further investigating the first issue of monospaced characters not being monospaced when printed:

n = 30;
font = "Courier"; (* alternatively: "Lucida Console" *)
text = StringJoin[
RandomChoice[{"=", "*", ":"}, n], "\n",
RandomChoice[{"M"}, n], "\n",
RandomChoice[{"@"}, n], "\n",
RandomChoice[{":"}, n], "\n",
RandomChoice[{"M", "A"}, n], "\n",
RandomChoice[{"_"}, n], "\n",
RandomChoice[{"@", "M"}, n], "\n",
RandomChoice[{":", "M"}, n], "\n",
RandomChoice[{":", "A"}, n], "\n",
RandomChoice[{":", "J"}, n]
];

Grid[{{
Style[StringJoin["Normal, 100% magnification, font size 10\n",
text], FontFamily -> font, FontSize -> 10],
Style[StringJoin["Bold, 100% magnification, font size 10\n", text],
FontFamily -> font, FontSize -> 10, Bold]
}, {
Style[StringJoin["Normal, 120% magnification, font size 10\n",
text], FontFamily -> font, FontSize -> 10, Magnification -> 1.2],
Style[StringJoin["Normal, 120% magnification, font size 12\n",
text], FontFamily -> font, FontSize -> 12, Magnification -> 1.2]
}}, Alignment -> {Left, Top}, Frame -> All]

Note the followings:

• Non-bold monospaced font with 100% magnification and 10 points height produces nicely fit lines - any divergence causes overhangs.
• Operators with certain letters (while independently are ok) together form an overhang. This seems to be true for all the operators I've tested.
• "_" is a renegate character as it does not even fit by itself into the frame, not even when not Bold.
• Overhang depends on magnification, font family and font size.

Again, I have no idea what causes these problems, but is definitely operator-character-related. Here, the problem is that no setup that is found on one machine is guaranteed to work on another, as a lot of these parameters depend on the OS.

-
Although we could not resolve the problem properly, you did a great job digging further into this. I'll accept this answer. It's a pity, I was the only one who upvoted your work. –  halirutan Nov 19 '12 at 1:05
@halirutan Thanks for the accept, let's hope this will be cured in v9! –  István Zachar Nov 19 '12 at 8:31
Just to update for v9: no, it is not cured yet, symptoms are the same for both issues. –  István Zachar Oct 14 '13 at 10:03