bump crengine: monospace and fallback fonts tweaks (#9343)

Includes:
- Text: fix possible overflow with "white-space: pre"
- Fonts: getFontFileNameAndFaceIndex(): return family type
- Fonts: account for _bias in Font hash
- epub.css, fb2.css: remove hardcoded monospace font names
- Fonts: allow scaling monospace fonts
- Fonts: allow adjusting fallback font sizes to x-height
- HTML parser: trust xml encoding before html charset

In our list of fonts, show a "M" indicator alongside
monospace fonts, and allow long-press to select the one
to be use for "font-family: monospace".
Add 2 options to Font settings, to scale monospace fonts
by a percentage, and to adjust fallback fonts to their
x-height.
reviewable/pr9351/r1
poire-z 2 years ago committed by GitHub
parent 2462ed68ae
commit 5e2ed5ae2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1 +1 @@
Subproject commit 7f0bc2325d85be8f424f8735816a98929e03d0b1
Subproject commit e3e0e3f38bcf1984d5666bb66bf0bced25e7eb85

@ -55,17 +55,23 @@ function ReaderFont:init()
-- Font list
local face_list = cre.getFontFaces()
for k,v in ipairs(face_list) do
local font_filename, font_faceindex = cre.getFontFaceFilenameAndFaceIndex(v)
local font_filename, font_faceindex, is_monospace = cre.getFontFaceFilenameAndFaceIndex(v)
table.insert(self.face_table, {
text_func = function()
-- defaults are hardcoded in credocument.lua
local default_font = G_reader_settings:readSetting("cre_font") or self.ui.document.default_font
local fallback_font = G_reader_settings:readSetting("fallback_font") or self.ui.document.fallback_fonts[1]
local monospace_font = G_reader_settings:readSetting("monospace_font") or self.ui.document.monospace_font
local text = v
if font_filename and font_faceindex then
text = FontList:getLocalizedFontName(font_filename, font_faceindex) or text
end
if v == monospace_font then
text = text .. " \u{1F13C}" -- Squared Latin Capital Letter M
elseif is_monospace then
text = text .. " \u{1D39}" -- Modified Letter Capital M
end
if v == default_font then
text = text .. ""
end
@ -85,7 +91,7 @@ function ReaderFont:init()
self:onSetFont(v)
end,
hold_callback = function(touchmenu_instance)
self:makeDefault(v, touchmenu_instance)
self:makeDefault(v, is_monospace, touchmenu_instance)
end,
checked_func = function()
return v == self.font_face
@ -306,8 +312,31 @@ function ReaderFont:onSetFont(face)
end
end
function ReaderFont:makeDefault(face, touchmenu_instance)
function ReaderFont:makeDefault(face, is_monospace, touchmenu_instance)
if face then
if is_monospace then
-- If the font is monospace, assume it wouldn't be a candidate
-- to be set as a fallback font, and allow it to be set as the
-- default monospace font.
UIManager:show(MultiConfirmBox:new{
text = T(_("Would you like %1 to be used as the default font (★), or the monospace font (\u{1F13C})?"), face),
choice1_text = _("Default"),
choice1_callback = function()
G_reader_settings:saveSetting("cre_font", face)
if touchmenu_instance then touchmenu_instance:updateItems() end
end,
choice2_text = C_("Font", "Monospace"),
choice2_callback = function()
G_reader_settings:saveSetting("monospace_font", face)
-- We need to reset the main font for the biases to be re-set correctly
local current_face = self.font_face
self.font_face = nil
self:onSetFont(current_face)
if touchmenu_instance then touchmenu_instance:updateItems() end
end,
})
return
end
UIManager:show(MultiConfirmBox:new{
text = T(_("Would you like %1 to be used as the default font (★), or the fallback font (<28>)?\n\nCharacters not found in the active font are shown in the fallback font instead."), face),
choice1_text = _("Default"),
@ -404,6 +433,52 @@ These fonts will be used in this order:
You can set a preferred fallback font with a long-press on a font name, and it will be used before these.
If that font happens to be part of this list already, it will be used first.]]),
table.concat(self.ui.document.fallback_fonts, "\n")),
})
table.insert(settings_table, {
text = _("Adjust fallback font sizes"),
checked_func = function()
return G_reader_settings:nilOrTrue("cre_adjusted_fallback_font_sizes")
end,
callback = function()
G_reader_settings:flipNilOrTrue("cre_adjusted_fallback_font_sizes")
self.ui.document:setAdjustedFallbackFontSizes(G_reader_settings:nilOrTrue("cre_adjusted_fallback_font_sizes"))
self.ui:handleEvent(Event:new("UpdatePos"))
end,
help_text = _([[
Adjust the size of each fallback font so they all get the same x-height, and lowercase characters picked in them look similarly sized as those from the defaut font.
This may help with Greek words among Latin text (as Latin fonts often do not have all the Greek characters), but may make Chinese or Indic characters smaller when picked from fallback fonts.]]),
separator = true,
})
table.insert(settings_table, {
text_func = function()
local scale = G_reader_settings:readSetting("cre_monospace_scaling") or 100
return T(_("Monospace fonts scaling: %1 %"), scale)
end,
callback = function()
local SpinWidget = require("ui/widget/spinwidget")
UIManager:show(SpinWidget:new{
value = G_reader_settings:readSetting("cre_monospace_scaling") or 100,
value_min = 30,
value_step = 1,
value_hold_step = 5,
value_max = 150,
unit = "%",
title_text = _("Monospace font scaling"),
-- no info_text: we want this widget to stay small, so we can move it
-- around to see the effect of the scaling
keep_shown_on_apply = true,
callback = function(spin)
local scale = spin.value
G_reader_settings:saveSetting("cre_monospace_scaling", scale)
self.ui.document:setMonospaceFontScaling(scale)
self.ui:handleEvent(Event:new("UpdatePos"))
end
})
end,
help_text = _([[
Monospace fonts may look big when inline with your main font if it has a small x-height.
This setting allows scaling all monospace fonts by this percentage so they can fit your preferred font height, or you can make them be a bit smaller to distinguish them more easily.]]),
separator = true,
})

@ -30,6 +30,7 @@ local CreDocument = Document:new{
line_space_percent = 100,
default_font = "Noto Serif",
monospace_font = "Droid Sans Mono",
header_font = "Noto Sans",
-- Reasons for the fallback font ordering:
@ -132,6 +133,9 @@ function CreDocument:engineInit()
-- and bold text with the font_base_weight setting set to its default value of 0 (=400).
cre.regularizeRegisteredFontsWeights(true) -- true to print what modifications were made
-- Set up bias for some specific fonts
self:setOtherFontBiases()
engine_initialized = true
end
end
@ -237,6 +241,12 @@ function CreDocument:setupDefaultView()
-- or cover image, eg. from History hold menu).
self:setupFallbackFontFaces()
-- Adjust or not fallback font sizes
self:setAdjustedFallbackFontSizes(G_reader_settings:nilOrTrue("cre_adjusted_fallback_font_sizes"))
-- set monospace fonts size scaling
self:setMonospaceFontScaling(G_reader_settings:readSetting("cre_monospace_scaling") or 100)
-- adjust font sizes according to dpi set in canvas context
self._document:adjustFontSizes(CanvasContext:getDPI())
@ -902,8 +912,8 @@ function CreDocument:setFontFace(new_font_face)
-- See: crengine/src/lvfntman.cpp LVFontDef::CalcMatch():
-- it will compute a score for each font, where it adds:
-- + 25600 if standard font family matches (inherit serif sans-serif
-- cursive fantasy monospace) (note that crengine registers all fonts as
-- "sans-serif", except if their name is "Times" or "Times New Roman")
-- cursive fantasy monospace) (note that crengine registers all fonts
-- as "sans-serif", except monospace fonts)
-- + 6400 if they don't and none are monospace (ie:serif vs sans-serif,
-- prefer a sans-serif to a monospace if looking for a serif)
-- +256000 if font names match
@ -914,22 +924,44 @@ function CreDocument:setFontFace(new_font_face)
-- +25601: uses existing real font-family, but use our font even
-- for font-family: monospace
-- +256001: prefer our font to any existing font-family font
self._document:setAsPreferredFontWithBias(new_font_face, 1)
-- +1 +128x5 +256x5: we want our main font, even if it has no italic
-- nor bold variant (eg FreeSerif), to win over all other fonts that
-- have an italic or bold variant:
-- cre.setAsPreferredFontWithBias(new_font_face, 1)
-- Rather +1 +128x5 +256x5: we want our main font, even if it has no italic
-- nor bold variant (eg FreeSerif), to win over all other fonts that have
-- an italic or bold variant:
-- italic_match = 5 * (256 for real italic, or 128 for fake italic
-- weight_match = 5 * (256 - weight_diff * 256 / 800)
-- so give our font a bias enough to win over real italic or bold fonts
-- (all others params (size, family, name), used for computing the match
-- score, have a factor of 100 or 1000 vs the 5 used for italic & weight,
-- so it shouldn't hurt much).
-- Note that this is mostly necessary when forcing a not found name,
-- as we do in the Ignore font-family style tweak.
self._document:setAsPreferredFontWithBias(new_font_face, 1 + 128*5 + 256*5)
-- Note that this is mostly necessary when a font name is given and we
-- don't have the font.
cre.setAsPreferredFontWithBias(new_font_face, 1 + 128*5 + 256*5)
-- The above call has resetted all other biases, so re-set our other ones
self:setOtherFontBiases()
end
end
function CreDocument:setOtherFontBiases()
-- Make sure the user selected (or the default) monospace font is used even
-- if other monospace fonts were registered (same factor as above so its
-- synthetic bold or italic are used, in case some other monospace font
-- has real bold or italic variants)
local monospace_font = G_reader_settings:readSetting("monospace_font") or self.monospace_font
cre.setAsPreferredFontWithBias(monospace_font, 1 + 128*5 + 256*5, false)
end
function CreDocument:setMonospaceFontScaling(value)
logger.dbg("CreDocument: set monospace font scaling", value)
self._document:setIntProperty("font.monospace.size.scale.percent", value or 100)
end
function CreDocument:setAdjustedFallbackFontSizes(toggle)
logger.dbg("CreDocument: set adjusted fallback font sizes", toggle)
self._document:setIntProperty("crengine.font.fallback.sizes.adjusted", toggle and 1 or 0)
end
function CreDocument:setupFallbackFontFaces()
local fallbacks = {}
local seen_fonts = {}

Loading…
Cancel
Save