koreader / crengine

This is the KOReader CREngine fork. It cross-pollinates with the official CoolReader repository at https://github.com/buggins/coolreader, in case you were looking for that one.
70 stars 45 forks source link

Improved typography for Chinese and Japanese #482

Closed poire-z closed 2 years ago

poire-z commented 2 years ago

Improve CJK typography (mostly Chinese and Japanese, Korean didn't really need and doesn't get anything), as discussed over the last 2 years in https://github.com/koreader/koreader/issues/6162. Should allow closing https://github.com/koreader/koreader/issues/6162 and https://github.com/koreader/koreader/issues/6078.

initTableRendMethods(): fix possible crash

ldomXPointer::getRect(): skip inline pads

Skip them early (not sure if it's really the best thing to do) to avoid a possible crash later when font->measureText() an empty string. Closes #481.

Ruby: keep any last text wrapped in internal table elements

Some publishers include 〘 and 〙 around a <rt> so that, when ruby is not supported, these are displayed inline and wrap the annotation. We'd rather have them not shown by having them wrapped and swallowed/hidden among table-like elements. image image => image

Font: fix HarfBuzz localized glyphs with CJK punctuation

This is a quick simple solution to get Traditional Chinese punctuation back, and should work fine in practice. (A more proper fix would be to gather and remember the detected script of all chars, and so use the script detected from the neighbour chars, but this is a lot more costly as it would need another array like m_text, m_flags: m_script.) See details and discussion starting at https://github.com/koreader/crengine/pull/472#issuecomment-1122647571.

lvtext: store kerning mode as a Formatter property

It's a global setting, so applied to all fonts. No need to pick it from each font. Will allow more tweaking depending on this setting.

CJK: improved typography by tweaking punctuations

Add support in textlang for flagging CJK punctuations, and ensuring width adjustment (forced or allowed reduction) depending on a punctuation context (neighbout, start or end of line), and differently depending if the language is Japanese, Simplified Chinese or Traditional Chinese. This allows, for example, to make consecutive opening or closing punctuations halfwidth in SC, and some punctuations at end of line halfwidth, respecting the recommended typography rules for each language (clreq, jlreq). For reference, some screenshots with copy&paste of the rules I made out at: https://github.com/koreader/koreader/issues/6162#issuecomment-1146572495

In lvtextfm, detect and flag punctuation chars as "flexible" CJK chars, and use the typography rules when breaking lines and making words. When line-breaking, when a CJK char would not fit, and a break would not be allowed (which would cause a hole the size of a glyph at end of line, that text justification would solve by spreading out the glyphs), try to steal some width from any previous "flexible" punctuation that stayed full width. Disable all this when kerning mode is "off", to allow getting the old behaviour.

In lvfntman, when a CJK glyph got its width reduced, try to shift the drawing so this CJK glyph appears in this reduced width as it would naturally (left, right or centered).

CJK: allow scaling CJK glyphs' widths

This may allow "Word Spacing" to have some effect on CJK text (where each glyphs is a word). Scaling glyphs (or letter spacing) is considered bad practice by many typography sites, but it might be helpful with very "solid" CJK fonts and to users learning Chinese. I've seen this requested twice: at https://github.com/koreader/koreader/issues/6162#issuecomment-650469410 and in some comments at https://www.thetype.com/kongque/. See https://github.com/koreader/koreader/pull/6134#issuecomment-1140219185 for some screenshots, and next comments saying anything above 105% is ugly though :)

CSS/lvrend: adds -cr-hint: cjk-tailored

To get paragraphs ("final" blocks) width and text-indent ajusted to an integer multiple of their font size (so text justification of lines made of only squared CJK glyphs get less chance to need to spread the glyphs). See https://github.com/koreader/koreader/issues/6162#issuecomment-1120416923 why this can't really be done automatically, and why it is best left to a style tweak and a user decision.

CJK: expand last line as previous justified line

The last line of a justified paragraph is left aligned and wouldn't get any added spacing, which would make it look more condensed that the justified line above it. So, when both previous to last and last line starts with 2 CJK chars, add to the last line the same spacing added to the above line so CJK chars looks vertically aligned. See https://github.com/koreader/koreader/issues/6162#issuecomment-1120416923. Should allow closing https://github.com/koreader/koreader/issues/8929.

CJK: add 1/4 em of spacing between CJK and western words

At the boundary between a CJK segment and a segment of non-CJK chars, we want to add a bit of spacing, 1/4em as advised by clreq and jlreq. Before: image After, this spacing giving it a nicer touch: image


This change is Reviewable