adobe-fonts / source-han-sans

Source Han Sans | 思源黑体 | 思源黑體 | 思源黑體 香港 | 源ノ角ゴシック | 본고딕
Other
14.55k stars 1.31k forks source link

half width latin characters are not strictly half the width of Chinese characters for every font sizes. #154

Closed nerditation closed 8 years ago

nerditation commented 8 years ago

I downloaded and tried the SHS HW SC fonts. In LibreOffice Writer and web browser, it looks all right. the English letters and Chinese characters are aligned as I expected. but in programs like notepad and emacs, they are aligned only if I set font size to 9, 12, 15 or so, but not aligned in other font size settings. the text in the screenshots are in size 9, 10, 11, 12, 13, respectively.

this is how it looks in LibreOffice: hw-in-office

this is how it looks in emacs: hw-in-emacs

I am really a novice for font technologies, I am not sure whether this was rendering problems of emacs or the Windows OS, or there was something missing in SHS.

I am using Windows 10 Home Simplified Chinese. I have used a DIY hybrid monospaced Chinese font before (ttf instead of otf), which worked well for me in various applications, such as PuTTY, emacs and even vim. I want to use SHS for my frequently used applications, especially emacs. Any kind of help is really appreciated. or should I just not use SHS for this case?

jimmymasaru commented 8 years ago

If you change the font settings to SimSun 宋体, you would have the same issue but if you use NSimSun 新宋体, which is marked as a monospaced font, it will be perfect. And that is the only difference between these two fonts. Because according to the DPI setting, which has the default value of 96dpi, the width of a Chinese character at 10pt will be 10/72*96=13.33≈13px which is an odd number so the width for a latin alphabet would be 7px. This causes 2 latin alphabets use 14px, one more pixel than a Chinese character. The width of 9pt is 12px and it can be divided by two. So all characters are aligned. And I think Windows has some tweaks against monospaced fonts so that the width of Chinese characters of 新宋体 at 10pt are extended to 14px. Some browsers and document editors prefer different rendering engines but code editors usually don't like these bells and whistles.

nerditation commented 8 years ago

Ah, thank you very much for the explanation.

then I wonder if I can build a customized SHS HW otf font which is marked as monospaced? how could I do it if possible? I am not aware of the open type thing. do I need to modify the source postscript font file or I just need to change the feature file and/or the command line option to makeotf command?

I have experimented with the afdko tools for several days and I think I can make a subset with only monospaced glyphs, but I don't know how to mark the final otf as monospaced.

jimmymasaru commented 8 years ago

No guarantee... open /Regular/OTC/cidfontinfo.OTC.HW.SC change isFixedPitch to true open /Regular/OTC/features.OTC.SC change Panose 2 11 5 0 0 0 0 0 0 0; to Panose 2 11 5 9 0 0 0 0 0 0; Do the same changes for Bold. Build.

Reference CompareFamily.py

nerditation commented 8 years ago

thanks for the advice. unfortunately, it doesn't work.

change isFixedPitch to true of the cidfontinfo file doesn't seem to have any effect. btw, how can I check that the installed otf font is marked as monospaced? I can't find such information in the Fonts control panel of the OS.

change Panose to 2 11 5 9 0 0 0 0 0 0 of the feature file simply make the OS treat the half width characters as if they have the same width of the Chinese characters, looks like this: force-monospaced

jimmymasaru commented 8 years ago

😞 Probably there exists other settings we need to tweak. But I have to say Windows handles OTF fonts in a way different than TTF. I think in Fonts folder you can check the details of each font. But I cannot double check that since I'm not using Windows. If you have Visual Studio installed, you can open the settings dialog and go to font settings. Monospaced fonts are marked as bold in the drop-down list.

nerditation commented 8 years ago

OK. thanks for the tip of Visual Studio trick. I checked in Visual Studio and it is not marked monospaced. so changing the cidfontinfo file is not enough to make a monospaced otf.

I think I need to learn more about open type fonts. and thank you for your help. really appreciated.

kenlunde commented 8 years ago

First and foremost, a font should be flagged as fixed-pitch if and only if every glyph in the font shares the same horizontal advance (aka width). Odd behavior may or may not occur if this is done forcibly.

With that written, there seem to be three places in the font that need to be tweaked in order to flag it as being fixed-pitch:

1) The fourth element of the OS/2.panose array, Proportion, should be set to 9. 2) The post.isFixedPitch value should be set to 1. 3) The CFF.isFixedPitch value should be set to 1. (I suspect that this is the setting that you didn't modify, which would be done by adding a new line, /isFixedPitch true def, to the /FontInfo dictionary in the header of the CIDFont resource, cidfont.ps.OTC.HW.SC)

You can use the AFDKO spot tool to confirm these settings. If the settings are correct in the version of the font that you built, then the issue lies outside of the font, perhaps in the app settings, or perhaps an app bug. I suggest that you try a genuine fixed-pitch CFF-based font, Source Code Pro, to see if the same issue occurs. Although it is based on the JP subset, you could also try Source Han Code JP.

nerditation commented 8 years ago

many thanks for the reply.

as jimmymasaru said in an earlier message, Windows handles otf fonts differently than ttf fonts.

previously I used a customized Chinese ttf font. and the width of Chinese characters is 2048 units while the width of English letters and punctuators is 1126 units, which was not equal to half of the Chinese characters. but the English letters were always rendered half the width of the Chinese characters. apparently the OS had scaled the glyphs automatically just because the font was marked as monospaced. (this actually has problem of hinting for certain font sizes, but I can bear with that.)

I thought the OS would do the same for otf fonts. but now I realized this is not case.

actually what I really want to achieve is not to mark the otf as monospaced, but to tell the OS or app to always round up the advance width of Chinese characters to even number of pixels, as what Windows currently does with monospaced ttf fonts, so that the half width characters can be of strictly half width.

is there a way to achieve this -- force the glyphs to be scaled to an even number of pixels -- for otf fonts?

and for now I would simply use 9pt and 12pt as font size in my editor's setting to make the text aligned.

kenlunde commented 8 years ago

@nerditation: Give this a whirl.

nerditation commented 8 years ago

@nerditation: Give this a whirl.

thank you for the link. unfortunately it doesn't work. actually I already tried building an otf as this on by myself.

now I am confused by how Windows handles monospaced Chinese fonts. jimmymasaru stated in previous message:

If you change the font settings to SimSun 宋体, you would have the same issue but if you use NSimSun 新宋体, which is marked as a monospaced font, it will be perfect. And that is the only difference between these two fonts.

I did some experiments today. it seems for ttf fonts, if panose[2] = 9 (no matter what value post.isFixedPitch is) then the font is regarded as monospaced and the Chinese characters always get rendered as even number pixels wide, so everything is aligned. if panose[2] = 0 but post.isFixedPitch = 1 then the font is also recognized as monospaced but for certain font sizes the Chinese character will have width of odd number pixels.

but this behavior doesn't apply to otf fonts. Windows must have different rules to render otf fonts, and I have no clue at all.

anyway, I suppose this is not an problem of the font. it is more related to tweaks of the rendering engine of the OS or applications. I think we can close this issue for good. since I am totally a novice I will definitely dig deeper into this field.

btw I am actually quite happy with 9pt or 12pt font size settings for my text editor using a modified SourceHanSansHWSC font. it looks great.

kenlunde commented 8 years ago

Because there are no bitmaps in the fonts, and because the half-width ASCII glyphs are precisely half the width of the glyphs for ideographs and other CJK characters, it is definitely OS or OS rendering behavior that is different for TrueType- versus CFF-based OpenType.

BTW, I built the OTF for you simply because it wasn't absolutely clear whether you made the appropriate change to the CIDFont resource.

be5invis commented 8 years ago

@nerditation It is a known bug in GDI, when PANOSE's proportion set to monospaced, it will ignore the entire hmtx and force use OS/2.xAvgCharWidth, at least for TTF.