DocumentServer icon indicating copy to clipboard operation
DocumentServer copied to clipboard

CJK font line spacing not the same as MS word

Open kingkazmam opened this issue 6 years ago • 12 comments

Do you want to request a feature or report a bug? Bug.

What is the current behavior? CJK font line spacing not the same as MS word.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. I only have windows device so I can't test ONLYOFFICE in OSX.

In OSX/iOS and others FreeType users, the single line spacing should be:

((hhea.ascent + abs(hhea.descent) + hhea.lineGap) / head.unitsPerEm) * Fontsize

and in Pages it will be rounding, such as the Chinese font 华文中宋 (STZhongsong),

LineSpacing1(single line spacing) = (1007 + 318 + 0) / 1000 = 1.325

so in Pages 10pt text will be set to 133pt LineSpacing1.

But in windows the situation is very complicated, I can't found the accurate formula by Google or Microsoft. After analysis I found some laws in MS word:

  1. It won't read the hhea info, it use the usWinAscent and usWinDescent info in OS/2 (change the hhea and others info won't change the line spacing);
  2. Line spacing always bigger than (OS/2.usWinAscent + OS/2.usWinDescent), I named this value Extend (by seting 200pt fontsize and zooming in 500% and then measuring);
  3. There is a fixed ratio between line spacing and (OS/2.usWinAscent + OS/2.usWinDescent), it about 1.29 to 1.31 (at least 20 fonts match this);
  4. The Extend will be evenly distributed above and below the font, so I named them ExtendA and ExtendB (by change OS/2.usWinAscent and OS/2.usWinDescent at FontCreater); 1

So:

LineSpacing1 = ((OS/2.usWinAscent + abs(OS/2.usWinDescent)) * 1.3 / head.unitsPerEm) * Fontsize
             = (((OS/2.usWinAscent + abs(OS/2.usWinDescent)) + (OS/2.usWinAscent + abs(OS/2.usWinDescent)) * 0.3) / head.unitsPerEm) * Fontsize
             = (((OS/2.usWinAscent + abs(OS/2.usWinDescent)) + ExtendA + ExtendB) / head.unitsPerEm) * Fontsize
             = (((OS/2.usWinAscent + abs(OS/2.usWinDescent)) + Extend * 2) / head.unitsPerEm) * Fontsize

I tried 21 fonts and then speculate the Extend is about 0.15.

For 仿宋(FangSong), 宋体(SimSun), 幼圆(YouYuan), 新宋体(NSimSun), 方正姚体(FZYaoTi), 方正舒体(FZShuTi), 楷体(KaiTi), 隶书(LiSu), 黑体(SimHei), it's about to 0.14845.

For 华文中宋(STZhongsong), 华文仿宋(STFangsong), 华文宋体(STSong), 华文新魏(STXinwei), 华文楷体(STKaiti), 华文琥珀(STHupo), 华文细黑(STXihei), 华文行楷(STXingkai), 华文隶书(STLiti), 华文彩云(STCaiyun), 微软雅黑(Microsoft YaHei), it's about to 0.15002.

It is worth noting when the Extend = 0.14845, the fonts'unitsPerEm = 256, and when Extend = 0.15002, unitsPerEm = 1000 or 2048. So the difference in this value may come from the measurement error.

So: Extend = (OS/2.usWinAscent + abs(OS/2.usWinDescent)) * 0.15

In windows MS word, Chinese font 华文中宋 (STZhongsong), LineSpacing1(single line spacing) = (912 + 225) * 1.3 / 1000 = 1.4781 The measurement results did not show that MS word use rounding.

What is the expected behavior? Consistent with MS word or just narrowing the gap.

Did this work in previous versions of DocumentServer? Yes.

DocumentServer version: 5.2.7

Operating System: Win 10.

kingkazmam avatar Jan 25 '19 15:01 kingkazmam

Some of the 华文中宋(STZhongsong) font info:

  <head>
    <!-- Most of this table will be recalculated by the compiler -->
    <tableVersion value="1.0"/>
    <fontRevision value="1.0"/>
    <checkSumAdjustment value="0xb611830c"/>
    <magicNumber value="0x5f0f3cf5"/>
    <flags value="00000000 00000011"/>
    <unitsPerEm value="1000"/>
    <created value="Fri Jul 17 10:51:22 1998"/>
    <modified value="Wed Oct 30 08:28:00 2002"/>
    <xMin value="-186"/>
    <yMin value="-318"/>
    <xMax value="1317"/>
    <yMax value="1007"/>
    <macStyle value="00000000 00000000"/>
    <lowestRecPPEM value="14"/>
    <fontDirectionHint value="1"/>
    <indexToLocFormat value="1"/>
    <glyphDataFormat value="0"/>
  </head>

  <hhea>
    <tableVersion value="0x00010000"/>
    <ascent value="1007"/>
    <descent value="-318"/>
    <lineGap value="0"/>
    <advanceWidthMax value="1365"/>
    <minLeftSideBearing value="-186"/>
    <minRightSideBearing value="-186"/>
    <xMaxExtent value="1317"/>
    <caretSlopeRise value="1"/>
    <caretSlopeRun value="0"/>
    <caretOffset value="0"/>
    <reserved0 value="0"/>
    <reserved1 value="0"/>
    <reserved2 value="0"/>
    <reserved3 value="0"/>
    <metricDataFormat value="0"/>
    <numberOfHMetrics value="25185"/>
  </hhea>

  <OS_2>
    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
         will be recalculated by the compiler -->
    <version value="1"/>
    <xAvgCharWidth value="492"/>
    <usWeightClass value="400"/>
    <usWidthClass value="5"/>
    <fsType value="00000000 00001000"/>
    <ySubscriptXSize value="100"/>
    <ySubscriptYSize value="100"/>
    <ySubscriptXOffset value="0"/>
    <ySubscriptYOffset value="150"/>
    <ySuperscriptXSize value="100"/>
    <ySuperscriptYSize value="100"/>
    <ySuperscriptXOffset value="0"/>
    <ySuperscriptYOffset value="650"/>
    <yStrikeoutSize value="100"/>
    <yStrikeoutPosition value="250"/>
    <sFamilyClass value="0"/>
    <panose>
      <bFamilyType value="2"/>
      <bSerifStyle value="1"/>
      <bWeight value="6"/>
      <bProportion value="0"/>
      <bContrast value="4"/>
      <bStrokeVariation value="1"/>
      <bArmStyle value="1"/>
      <bLetterForm value="1"/>
      <bMidline value="1"/>
      <bXHeight value="1"/>
    </panose>
    <ulUnicodeRange1 value="00000000 00000000 00000010 10000111"/>
    <ulUnicodeRange2 value="00001000 00001111 00000000 00000000"/>
    <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
    <achVendID value="SINO"/>
    <fsSelection value="00000000 01000000"/>
    <usFirstCharIndex value="32"/>
    <usLastCharIndex value="65509"/>
    <sTypoAscender value="800"/>
    <sTypoDescender value="-200"/>
    <sTypoLineGap value="144"/>
    <usWinAscent value="912"/>
    <usWinDescent value="225"/>
    <ulCodePageRange1 value="00000000 00000100 00000000 10011111"/>
    <ulCodePageRange2 value="11011111 11010111 00000000 00000000"/>
  </OS_2>

The whole info is too large, so I upload the font you can dump the info use fonttools: STZHONGS.zip

kingkazmam avatar Jan 25 '19 15:01 kingkazmam

@kingkazmam Hi, thank you for detailed bug report. We were aware of this problem and working on it, but currently have no exact date when it will be fixed

ShockwaveNN avatar Jan 30 '19 09:01 ShockwaveNN

@kingkazmam Hi, thank you for detailed bug report. We were aware of this problem and working on it, but currently have no exact date when it will be fixed

Hello, do you have a plan to fix this bug?

huisnotacouncillor avatar Sep 03 '21 07:09 huisnotacouncillor

@huisnotacouncillor Sorry, fix of this problem rather complicated, so currently now news. I'll report as soon as there will be something to say

I forgot to mention in original message, but it's issue 48564 in our private issue tracker

ShockwaveNN avatar Sep 03 '21 10:09 ShockwaveNN

Thank you for your reply. In documents containing Chinese, Japanese, and Korean, this problem will cause the number of pages of the document and the page number calculation is incorrect, which is somewhat different from MS Word.

huisnotacouncillor avatar Sep 03 '21 11:09 huisnotacouncillor

I can confirm this again with 6.4.2.

any progress?

WestFarmer avatar Dec 22 '21 08:12 WestFarmer

@WestFarmer Sorry, no progress, CJK fonts support is very complicated and currently this is not a high priority task You can contact [email protected] to discuss our priorities

ShockwaveNN avatar Dec 22 '21 08:12 ShockwaveNN

@WestFarmer Sorry, no progress, CJK fonts support is very complicated and currently this is not a high priority task You can contact [email protected] to discuss our priorities

ok, that's normal for "open source" soft, maybe you can open the discussion of that 'complicated problem', maybe some community member can help, but I am not a font expert, for me it's confusing that can be more complicated than some simple math.

I am guessing that microsoft word and wps did some tweak for CJK fonts, for line gap to looks not so narrowed.

WestFarmer avatar Dec 22 '21 08:12 WestFarmer

maybe some community member can help

Maybe, but it's up to developers to decide. And I cannot force them, sorry In other words - the problem is rather complicated and we got no time because we solving problems that are more important for us and/or from paying customers

ShockwaveNN avatar Dec 22 '21 09:12 ShockwaveNN

Microsoft tend to keep it secret: https://social.msdn.microsoft.com/Forums/en-US/156d8827-2a4a-4eaa-b518-1cebb71a5e8b/how-can-i-calculate-cjk-font-single-line-spacing?forum=os_binaryfile

WestFarmer avatar Dec 22 '21 09:12 WestFarmer

@kingkazmam I'm happy to announce that the issue is fixed in this commit and is already available in version 8.0.1

TatianaKirillova avatar May 07 '24 13:05 TatianaKirillova

@kingkazmam @huisnotacouncillor Can I ask what was the original issue? Was the line space of CJK font texts were bigger (higher) than MS Word (x1.3 is applied in Word)? @TatianaKirillova How is it currently? so the "x1.3" is now applied?

kim-dongryeong avatar May 28 '24 18:05 kim-dongryeong