prawnpdf / prawn

Fast, Nimble PDF Writer for Ruby
https://prawnpdf.org
Other
4.67k stars 688 forks source link

Monospace characters can exceed width of single character #1002

Closed mojavelinux closed 7 years ago

mojavelinux commented 7 years ago

Certain fonts have a glyph width that is wider than the width of a space character (and wider than latin characters in general). This is typically seen in the box drawing glyphs. For example, in the M+ 1mn font, the char width of the space (and "a") is 500. But the char width of the horizontal box line is 1000. As a result, the box drawings don't align correctly.

Here's an example that demonstrates the problem:

require 'prawn'

Prawn::Document.generate 'mono.pdf' do

  font_families['mplus1mn'] = {
    normal: '/usr/share/fonts/mplus/mplus-1mn-regular.ttf'
  }

  font 'mplus1mn', size: 10 do
    text '---'
    warn width_of '---' # prints 15.0
    text '———'
    warn width_of '———' # prints 15.0
    text '───'
    warn width_of '───' # prints 30.0
  end
end

The last line is twice as wide as the first two.

(This behavior is not seen with DejaVu Sans Mono since all the glyphs have the same width)

If I look at the PDF source, I see something like:

BT
36.0 725.6 Td
/F1.1 10 Tf
<212121> Tj
ET

It may be that Prawn can't do anything about this and that it's something the PDF viewer is responsible for handling. I'm not sure.

The only thing I can really see that Prawn could do is adjust the character spacing. The alternative is when Prawn embeds the font in the PDF, it can somehow scale the glyph widths of the monospace font so that they are all the same. But even if I try to force that to happen, I still get overlap. So maybe it is just an issue with this font.

mojavelinux commented 7 years ago

I should add that the browser is able to force the glyphs to be a consistent width, as does the terminal.

mojavelinux commented 7 years ago

I stand corrected. The browser also exhibits this behavior. It's just the terminal that seems to be able to correct it. Now I'm even more convinced that the metrics in the font are incorrect (which I can verify by using fontforge to study the font).

pointlessone commented 7 years ago

Prawn does not treat monospace fonts in any special way. For prawn they just happen to have glyphs of the same widths. Prawn uses whatever glyph metrics are present in the font.

Likewise, all PDF renderers I'm aware of would do exactly the same thing: they will use font metrics as is.

Terminals are a bit of a special case. They assume that text is monospace and is layed out on a grid. iTerm, for instance, implements text grid. It renders individual glyphs in grid cells. It can render "wide" glyphs in double cells. But otherwise it's all about grid.

According to official site, M+ MN Type-1 is a "combination of fixed-fullwidth M+ Type-1 for Japanese and fixed-halfwidth M+ MN Type-1 for alphabets". So it appears logical that box drawing glyphs are fullwidth and twice as wide as regular latin character glyphs.


I will close this issue now as this is not a Prawn bug. Feel free to reopen when you have any additional information.