Adds Word Expansion: use of letter spacing for justification

Bump crengine:
- Text: fix occasional BiDi bad word splitting
- Font: fix HB fallback measurement/drawing mismatches
- Font: do not add letter spacing on diacritics
- Text: tunable use of letter spacing for justification
- Text: dont adjust space after initial quotation mark/dash (rework)
- Text: fix possible bad widths after collapsed spaces

xtext.cpp: pick crengine fix with HB fallback
measurement/drawing mismatches

Adds "Word Expansion" to bottom Font size menu, and moved
"Word Spacing" there too, to balance the panels' heights
to 4 items.
reviewable/pr6127/r1
poire-z 4 years ago
parent 5681ddcd41
commit e074b603e0

@ -106,6 +106,9 @@ read_globals = {
"DCREREADER_CONFIG_WORD_SPACING_SMALL",
"DCREREADER_CONFIG_WORD_SPACING_MEDIUM",
"DCREREADER_CONFIG_WORD_SPACING_LARGE",
"DCREREADER_CONFIG_WORD_EXPANSION_NONE",
"DCREREADER_CONFIG_WORD_EXPANSION_SOME",
"DCREREADER_CONFIG_WORD_EXPANSION_MORE",
"DMINIBAR_CONTAINER_HEIGHT",
"DGESDETECT_DISABLE_DOUBLE_TAP",
"FRONTLIGHT_SENSITIVITY_DECREASE",

@ -1 +1 @@
Subproject commit 57c848f3630e150321cfb8a975cc905070cb316e
Subproject commit 87300d3b026b15f2e6a87505efe8261bf406a1d1

@ -185,6 +185,13 @@ DCREREADER_CONFIG_WORD_SPACING_SMALL = {75, 50}
DCREREADER_CONFIG_WORD_SPACING_MEDIUM = {95, 75}
DCREREADER_CONFIG_WORD_SPACING_LARGE = {100, 90}
-- word expansion, to reduce excessive spacing on justified line
-- by using letter spacing on the words
-- value is the max allowed added letter spacing, as a % of the font size
DCREREADER_CONFIG_WORD_EXPANSION_NONE = 0
DCREREADER_CONFIG_WORD_EXPANSION_SOME = 5
DCREREADER_CONFIG_WORD_EXPANSION_MORE = 15
-- crereader progress bar (no longer needed)
-- 0 for top "full" progress bar
-- 1 for bottom "mini" progress bar

@ -125,6 +125,10 @@ function ReaderFont:onReadSettings(config)
or G_reader_settings:readSetting("copt_word_spacing") or {95, 75}
self.ui.document:setWordSpacing(self.word_spacing)
self.word_expansion = config:readSetting("word_expansion")
or G_reader_settings:readSetting("copt_word_expansion") or 0
self.ui.document:setWordExpansion(self.word_expansion)
self.line_space_percent = config:readSetting("line_space_percent")
or G_reader_settings:readSetting("copt_line_spacing")
or DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM
@ -239,6 +243,13 @@ function ReaderFont:onSetWordSpacing(values)
return true
end
function ReaderFont:onSetWordExpansion(value)
self.word_expansion = value
self.ui.document:setWordExpansion(value)
self.ui:handleEvent(Event:new("UpdatePos"))
return true
end
function ReaderFont:onSetFontGamma(gamma)
self.gamma_index = gamma
self.ui.document:setGammaIndex(self.gamma_index)
@ -259,6 +270,7 @@ function ReaderFont:onSaveSettings()
self.ui.doc_settings:saveSetting("font_hinting", self.font_hinting)
self.ui.doc_settings:saveSetting("font_kerning", self.font_kerning)
self.ui.doc_settings:saveSetting("word_spacing", self.word_spacing)
self.ui.doc_settings:saveSetting("word_expansion", self.word_expansion)
self.ui.doc_settings:saveSetting("line_space_percent", self.line_space_percent)
self.ui.doc_settings:saveSetting("gamma_index", self.gamma_index)
end

@ -812,6 +812,11 @@ function CreDocument:setWordSpacing(values)
self._document:setIntProperty("crengine.style.space.condensing.percent", values[2])
end
function CreDocument:setWordExpansion(value)
logger.dbg("CreDocument: set word expansion", value)
self._document:setIntProperty("crengine.style.max.added.letter.spacing.percent", value or 0)
end
function CreDocument:setStyleSheet(new_css_file, appended_css_content )
logger.dbg("CreDocument: set style sheet:",
new_css_file and new_css_file or "no file",

@ -300,7 +300,7 @@ Note that your selected font size is not affected by this setting.]]),
},
{
name = "font_fine_tune",
name_text = S.FONTSIZE_FINE_TUNING,
name_text = S.FONT_SIZE,
toggle = Device:isTouchDevice() and {S.DECREASE, S.INCREASE} or nil,
item_text = not Device:isTouchDevice() and {S.DECREASE, S.INCREASE} or nil,
more_options = true,
@ -325,7 +325,63 @@ Note that your selected font size is not affected by this setting.]]),
}
optionsutil.showValues(configurable, opt, prefix)
end,
}
},
{
name = "word_spacing",
name_text = S.WORD_SPACING,
toggle = {S.SMALL, S.MEDIUM, S.LARGE},
values = {
DCREREADER_CONFIG_WORD_SPACING_SMALL,
DCREREADER_CONFIG_WORD_SPACING_MEDIUM,
DCREREADER_CONFIG_WORD_SPACING_LARGE,
},
default_value = DCREREADER_CONFIG_WORD_SPACING_MEDIUM,
args = {
DCREREADER_CONFIG_WORD_SPACING_SMALL,
DCREREADER_CONFIG_WORD_SPACING_MEDIUM,
DCREREADER_CONFIG_WORD_SPACING_LARGE,
},
event = "SetWordSpacing",
help_text = _([[Tells the rendering engine how much to scale the width of each 'space' character in the text from its regular width, and how much it can additionally reduce them to make more words fit on a line (100% means no reduction).]]),
name_text_hold_callback = optionsutil.showValues,
name_text_true_values = true,
show_true_value_func = function(val)
return string.format("%d%%, +%d%%", val[1], val[2])
end,
},
{
name = "word_expansion",
name_text = S.WORD_EXPANSION,
more_options = true,
more_options_param = {
value_min = 0,
value_max = 20,
value_step = 1,
value_hold_step = 4,
name = "word_expansion",
name_text = _("Allowed word expansion (%)"),
event = "SetWordExpansion",
},
toggle = {S.NONE, S.SOME, S.MORE},
values = {
DCREREADER_CONFIG_WORD_EXPANSION_NONE,
DCREREADER_CONFIG_WORD_EXPANSION_SOME,
DCREREADER_CONFIG_WORD_EXPANSION_MORE,
},
default_value = DCREREADER_CONFIG_WORD_EXPANSION_NONE,
args = {
DCREREADER_CONFIG_WORD_EXPANSION_NONE,
DCREREADER_CONFIG_WORD_EXPANSION_SOME,
DCREREADER_CONFIG_WORD_EXPANSION_MORE,
},
event = "SetWordExpansion",
help_text = _([[On justified lines having too wide spaces, allow distributing the excessive space into words by expanding them with letter spacing. This sets the max allowed letter spacing as a % of the font size.]]),
name_text_hold_callback = optionsutil.showValues,
name_text_true_values = true,
show_true_value_func = function(val)
return string.format("%d%%", val)
end,
},
}
},
{
@ -400,29 +456,6 @@ Note that your selected font size is not affected by this setting.]]),
(Font Hinting may need to be adjusted for the best result with either kerning implementation.)]]),
},
{
name = "word_spacing",
name_text = S.WORD_SPACING,
toggle = {S.SMALL, S.MEDIUM, S.LARGE},
values = {
DCREREADER_CONFIG_WORD_SPACING_SMALL,
DCREREADER_CONFIG_WORD_SPACING_MEDIUM,
DCREREADER_CONFIG_WORD_SPACING_LARGE,
},
default_value = DCREREADER_CONFIG_WORD_SPACING_MEDIUM,
args = {
DCREREADER_CONFIG_WORD_SPACING_SMALL,
DCREREADER_CONFIG_WORD_SPACING_MEDIUM,
DCREREADER_CONFIG_WORD_SPACING_LARGE,
},
event = "SetWordSpacing",
help_text = _([[Tells the rendering engine how much to scale the width of each 'space' character in the text from its regular width, and how much it can additionally reduce them to make more words fit on a line (100% means no reduction).]]),
name_text_hold_callback = optionsutil.showValues,
name_text_true_values = true,
show_true_value_func = function(val)
return string.format("%d%%, +%d%%", val[1], val[2])
end,
}
}
},
{

@ -17,6 +17,7 @@ S.COLUMNS = _("Columns")
-- @translators Text alignment. Options given as icons: left, right, center, justify.
S.TEXT_ALIGN = _("Alignment")
S.FONTSIZE_FINE_TUNING = _("Fine Tuning")
S.FONT_SIZE = _("Font Size")
S.CONTRAST = _("Contrast")
-- @translators Reflow text.
S.REFLOW = _("Reflow")
@ -34,6 +35,7 @@ S.GAMMA = _("Gamma")
S.FONT_HINT = _("Font Hinting")
S.FONT_KERNING = _("Font Kerning")
S.WORD_SPACING = _("Word Spacing")
S.WORD_EXPANSION = _("Word Expansion")
S.VIEW_MODE = _("View Mode")
S.EMBEDDED_STYLE = _("Embedded Style")
S.EMBEDDED_FONTS = _("Embedded Fonts")
@ -57,6 +59,8 @@ S.NONE = _("none")
S.SMALL = _("small")
S.MEDIUM = _("medium")
S.LARGE = _("large")
S.SOME = _("some")
S.MORE = _("more")
S.DECREASE = _("decrease")
S.INCREASE = _("increase")
S.LIGHTEST = _("lightest")

@ -8,24 +8,27 @@ describe("defaults module", function()
it("should load all defaults from defaults.lua", function()
Defaults:init()
assert.is_same(103, #Defaults.defaults_name)
assert.is_same(106, #Defaults.defaults_name)
end)
it("should save changes to defaults.persistent.lua", function()
local persistent_filename = DataStorage:getDataDir() .. "/defaults.persistent.lua"
os.remove(persistent_filename)
-- To see indices and help updating this when new settings are added:
-- for i=1, 106 do print(i.." ".. Defaults.defaults_name[i]) end
-- not in persistent but checked in defaults
Defaults.changed[20] = true
Defaults.changed[47] = true
Defaults.changed[53] = true
Defaults.changed[82] = true
Defaults.changed[98] = true --SEARCH_LIBRARY_PATH = ""
Defaults.changed[50] = true
Defaults.changed[56] = true
Defaults.changed[85] = true
Defaults.changed[101] = true --SEARCH_LIBRARY_PATH = ""
Defaults:saveSettings()
assert.is_same(103, #Defaults.defaults_name)
assert.is_same("SEARCH_LIBRARY_PATH", Defaults.defaults_name[98])
assert.is_same("DTAP_ZONE_BACKWARD", Defaults.defaults_name[82])
assert.is_same("DCREREADER_CONFIG_WORD_SPACING_LARGE", Defaults.defaults_name[47])
assert.is_same(106, #Defaults.defaults_name)
assert.is_same("SEARCH_LIBRARY_PATH", Defaults.defaults_name[101])
assert.is_same("DTAP_ZONE_BACKWARD", Defaults.defaults_name[85])
assert.is_same("DCREREADER_CONFIG_WORD_SPACING_LARGE", Defaults.defaults_name[50])
assert.is_same("DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE", Defaults.defaults_name[20])
local fd = io.open(persistent_filename, "r")
assert.Equals(
@ -57,15 +60,15 @@ DDOUBLE_TAP_ZONE_PREV_CHAPTER = {
-- in persistent
Defaults:init()
Defaults.changed[53] = true
Defaults.defaults_value[53] = {
Defaults.changed[56] = true
Defaults.defaults_value[56] = {
y = 0,
x = 0,
h = 0.25,
w = 0.75
}
Defaults.changed[82] = true
Defaults.defaults_value[82] = {
Defaults.changed[85] = true
Defaults.defaults_value[85] = {
y = 10,
x = 10.125,
h = 20.25,
@ -119,8 +122,8 @@ DHINTCOUNT = 2
-- in persistent
Defaults:init()
Defaults.changed[54] = true
Defaults.defaults_value[54] = 1
Defaults.changed[57] = true
Defaults.defaults_value[57] = 1
Defaults:saveSettings()
fd = io.open(persistent_filename)
assert.Equals(

Loading…
Cancel
Save