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_SMALL",
"DCREREADER_CONFIG_WORD_SPACING_MEDIUM", "DCREREADER_CONFIG_WORD_SPACING_MEDIUM",
"DCREREADER_CONFIG_WORD_SPACING_LARGE", "DCREREADER_CONFIG_WORD_SPACING_LARGE",
"DCREREADER_CONFIG_WORD_EXPANSION_NONE",
"DCREREADER_CONFIG_WORD_EXPANSION_SOME",
"DCREREADER_CONFIG_WORD_EXPANSION_MORE",
"DMINIBAR_CONTAINER_HEIGHT", "DMINIBAR_CONTAINER_HEIGHT",
"DGESDETECT_DISABLE_DOUBLE_TAP", "DGESDETECT_DISABLE_DOUBLE_TAP",
"FRONTLIGHT_SENSITIVITY_DECREASE", "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_MEDIUM = {95, 75}
DCREREADER_CONFIG_WORD_SPACING_LARGE = {100, 90} 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) -- crereader progress bar (no longer needed)
-- 0 for top "full" progress bar -- 0 for top "full" progress bar
-- 1 for bottom "mini" 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} or G_reader_settings:readSetting("copt_word_spacing") or {95, 75}
self.ui.document:setWordSpacing(self.word_spacing) 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") self.line_space_percent = config:readSetting("line_space_percent")
or G_reader_settings:readSetting("copt_line_spacing") or G_reader_settings:readSetting("copt_line_spacing")
or DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM or DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM
@ -239,6 +243,13 @@ function ReaderFont:onSetWordSpacing(values)
return true return true
end 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) function ReaderFont:onSetFontGamma(gamma)
self.gamma_index = gamma self.gamma_index = gamma
self.ui.document:setGammaIndex(self.gamma_index) 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_hinting", self.font_hinting)
self.ui.doc_settings:saveSetting("font_kerning", self.font_kerning) 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_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("line_space_percent", self.line_space_percent)
self.ui.doc_settings:saveSetting("gamma_index", self.gamma_index) self.ui.doc_settings:saveSetting("gamma_index", self.gamma_index)
end end

@ -812,6 +812,11 @@ function CreDocument:setWordSpacing(values)
self._document:setIntProperty("crengine.style.space.condensing.percent", values[2]) self._document:setIntProperty("crengine.style.space.condensing.percent", values[2])
end 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 ) function CreDocument:setStyleSheet(new_css_file, appended_css_content )
logger.dbg("CreDocument: set style sheet:", logger.dbg("CreDocument: set style sheet:",
new_css_file and new_css_file or "no file", 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 = "font_fine_tune",
name_text = S.FONTSIZE_FINE_TUNING, name_text = S.FONT_SIZE,
toggle = Device:isTouchDevice() and {S.DECREASE, S.INCREASE} or nil, toggle = Device:isTouchDevice() and {S.DECREASE, S.INCREASE} or nil,
item_text = not Device:isTouchDevice() and {S.DECREASE, S.INCREASE} or nil, item_text = not Device:isTouchDevice() and {S.DECREASE, S.INCREASE} or nil,
more_options = true, more_options = true,
@ -325,7 +325,63 @@ Note that your selected font size is not affected by this setting.]]),
} }
optionsutil.showValues(configurable, opt, prefix) optionsutil.showValues(configurable, opt, prefix)
end, 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.)]]), (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. -- @translators Text alignment. Options given as icons: left, right, center, justify.
S.TEXT_ALIGN = _("Alignment") S.TEXT_ALIGN = _("Alignment")
S.FONTSIZE_FINE_TUNING = _("Fine Tuning") S.FONTSIZE_FINE_TUNING = _("Fine Tuning")
S.FONT_SIZE = _("Font Size")
S.CONTRAST = _("Contrast") S.CONTRAST = _("Contrast")
-- @translators Reflow text. -- @translators Reflow text.
S.REFLOW = _("Reflow") S.REFLOW = _("Reflow")
@ -34,6 +35,7 @@ S.GAMMA = _("Gamma")
S.FONT_HINT = _("Font Hinting") S.FONT_HINT = _("Font Hinting")
S.FONT_KERNING = _("Font Kerning") S.FONT_KERNING = _("Font Kerning")
S.WORD_SPACING = _("Word Spacing") S.WORD_SPACING = _("Word Spacing")
S.WORD_EXPANSION = _("Word Expansion")
S.VIEW_MODE = _("View Mode") S.VIEW_MODE = _("View Mode")
S.EMBEDDED_STYLE = _("Embedded Style") S.EMBEDDED_STYLE = _("Embedded Style")
S.EMBEDDED_FONTS = _("Embedded Fonts") S.EMBEDDED_FONTS = _("Embedded Fonts")
@ -57,6 +59,8 @@ S.NONE = _("none")
S.SMALL = _("small") S.SMALL = _("small")
S.MEDIUM = _("medium") S.MEDIUM = _("medium")
S.LARGE = _("large") S.LARGE = _("large")
S.SOME = _("some")
S.MORE = _("more")
S.DECREASE = _("decrease") S.DECREASE = _("decrease")
S.INCREASE = _("increase") S.INCREASE = _("increase")
S.LIGHTEST = _("lightest") S.LIGHTEST = _("lightest")

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

Loading…
Cancel
Save