2019-12-06 21:55:39 +00:00
local BD = require ( " ui/bidi " )
2018-03-22 20:01:38 +00:00
local Device = require ( " device " )
2018-05-26 17:45:37 +00:00
local optionsutil = require ( " ui/data/optionsutil " )
2020-12-10 22:53:33 +00:00
local util = require ( " util " )
2013-10-18 20:38:07 +00:00
local _ = require ( " gettext " )
2020-11-29 09:18:59 +00:00
local C_ = _.pgettext
2018-03-22 20:01:38 +00:00
local Screen = Device.screen
2013-10-18 20:38:07 +00:00
2020-05-07 18:24:12 +00:00
-- The values used for Font Size are not actually font sizes, but kopt zoom levels.
local FONT_SCALE_FACTORS = { 0.2 , 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9 , 1.0 , 1.1 , 1.3 , 1.6 , 2.0 }
-- Font sizes used for the font size widget only
local FONT_SCALE_DISPLAY_SIZE = { 12 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 22 , 25 , 30 , 35 }
-- Get font scale numbers as a table of strings
local tableOfNumbersToTableOfStrings = function ( numbers )
local t = { }
for i , v in ipairs ( numbers ) do
table.insert ( t , string.format ( " %0.1f " , v ) )
end
return t
end
2013-10-18 20:38:07 +00:00
local KoptOptions = {
ReaderZooming: Deal with some more fallout of the new zoom modes (#7728)
* Namely, ensure zoom_mode is consistent with genus & type *both ways*. (I only dealt with the "no zoom_mode" case in my original fixup).
Because documents with settings dating back from before the new zoom modes had "old" zoom_mode settings mixed with "new" genus/type defaults that didn't agree with each other.
It lead to super-confusing ConfigDialog behavior, because ConfigDialog was in fact not reflecting the reality.
(As the source of truth is actually `zoom_mode`).
* There was a snafu in manual mode, because of the extremely weird way prefixes are handled by Configurable/ReaderConfig/DocSettings/ConfigDialog.
So, make sure we only have a *single* zoom_factor, and that it's updated and saved properly under the right name everywhere.
Fixes inconsistencies between first swapping to manual mode, and what the ConfigDialog said/did (because again: possibly a lie), vs., re-opening the same document, which would magically use *different* settings, closer to what was expected (but still broken because of the prefix mismatch and a disagreement on defaults between the two variants).
Fallout from #6885
2021-05-22 01:28:52 +00:00
prefix = " kopt " ,
2014-03-13 13:52:43 +00:00
{
2020-12-19 11:18:30 +00:00
icon = " appbar.rotation " ,
2014-03-13 13:52:43 +00:00
options = {
{
2020-07-01 20:17:41 +00:00
name = " rotation_mode " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Rotation " ) ,
2021-03-29 03:12:22 +00:00
item_icons_func = function ( )
2022-12-21 14:50:39 +00:00
if Screen : getRotationMode ( ) == Screen.DEVICE_ROTATED_UPRIGHT then
2021-03-29 03:12:22 +00:00
-- P, 0UR
return {
" rotation.P.90CCW " ,
" rotation.P.0UR " ,
" rotation.P.90CW " ,
" rotation.P.180UD " ,
}
2022-12-21 14:50:39 +00:00
elseif Screen : getRotationMode ( ) == Screen.DEVICE_ROTATED_UPSIDE_DOWN then
2021-03-29 03:12:22 +00:00
-- P, 180UD
return {
" rotation.P.90CW " ,
" rotation.P.180UD " ,
" rotation.P.90CCW " ,
" rotation.P.0UR " ,
}
2022-12-21 14:50:39 +00:00
elseif Screen : getRotationMode ( ) == Screen.DEVICE_ROTATED_CLOCKWISE then
2021-03-29 03:12:22 +00:00
-- L, 90CW
return {
" rotation.L.90CCW " ,
" rotation.L.0UR " ,
" rotation.L.90CW " ,
" rotation.L.180UD " ,
}
else
-- L, 90CCW
return {
" rotation.L.90CW " ,
" rotation.L.180UD " ,
" rotation.L.90CCW " ,
" rotation.L.0UR " ,
}
end
end ,
2021-03-30 16:47:52 +00:00
-- For Dispatcher & onMakeDefault's sake
2021-03-06 18:27:23 +00:00
labels = { C_ ( " Rotation " , " ⤹ 90° " ) , C_ ( " Rotation " , " ↑ 0° " ) , C_ ( " Rotation " , " ⤸ 90° " ) , C_ ( " Rotation " , " ↓ 180° " ) } ,
2014-03-13 13:52:43 +00:00
alternate = false ,
2022-12-21 14:50:39 +00:00
values = { Screen.DEVICE_ROTATED_COUNTER_CLOCKWISE , Screen.DEVICE_ROTATED_UPRIGHT , Screen.DEVICE_ROTATED_CLOCKWISE , Screen.DEVICE_ROTATED_UPSIDE_DOWN } ,
2023-09-13 04:49:57 +00:00
default_value = Screen.DEVICE_ROTATED_UPRIGHT ,
2022-12-21 14:50:39 +00:00
args = { Screen.DEVICE_ROTATED_COUNTER_CLOCKWISE , Screen.DEVICE_ROTATED_UPRIGHT , Screen.DEVICE_ROTATED_CLOCKWISE , Screen.DEVICE_ROTATED_UPSIDE_DOWN } ,
2020-07-01 20:17:41 +00:00
current_func = function ( ) return Screen : getRotationMode ( ) end ,
event = " SetRotationMode " ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2014-03-13 13:52:43 +00:00
}
}
} ,
{
2020-12-19 11:18:30 +00:00
icon = " appbar.crop " ,
2014-03-13 13:52:43 +00:00
options = {
{
name = " trim_page " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Page Crop " ) ,
2020-05-07 18:24:12 +00:00
-- manual=0, auto=1, semi-auto=2, none=3
-- ordered from least to max cropping done or possible
2021-11-28 21:49:22 +00:00
toggle = { C_ ( " Page crop " , " none " ) , C_ ( " Page crop " , " auto " ) , C_ ( " Page crop " , " semi-auto " ) , C_ ( " Page crop " , " manual " ) } ,
2014-03-13 13:52:43 +00:00
alternate = false ,
2020-05-07 18:24:12 +00:00
values = { 3 , 1 , 2 , 0 } ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_TRIM_PAGE " ) ,
2022-04-14 06:59:36 +00:00
enabled_func = function ( ) return Device : isTouchDevice ( ) or Device : hasDPad ( ) end ,
2014-03-13 13:52:43 +00:00
event = " PageCrop " ,
2020-05-07 18:24:12 +00:00
args = { " none " , " auto " , " semi-auto " , " manual " } ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2020-05-07 18:24:12 +00:00
help_text = _ ( [ [ Allows cropping blank page margins in the original document .
This might be needed on scanned documents , that may have speckles or fingerprints in the margins , to be able to use zoom to fit content width .
- ' none ' does not cut the original document margins .
- ' auto ' finds content area automatically .
- ' semi-auto" finds content area automatically, inside some larger area defined manually.
- ' manual" uses the area defined manually as-is.
In ' semi-auto ' and ' manual ' modes , you may need to define areas once on an odd page number , and once on an even page number ( these areas will then be used for all odd , or even , page numbers ) . ] ] ) ,
} ,
{
name = " page_margin " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Margin " ) ,
2023-03-14 17:29:16 +00:00
buttonprogress = true ,
values = { 0.05 , 0.10 , 0.25 , 0.40 , 0.55 , 0.70 , 0.85 , 1.00 } ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_PAGE_MARGIN " ) ,
2020-05-07 18:24:12 +00:00
event = " MarginUpdate " ,
2023-05-01 08:09:06 +00:00
args = { 0.05 , 0.10 , 0.25 , 0.40 , 0.55 , 0.70 , 0.85 , 1.00 } ,
2020-05-07 18:24:12 +00:00
name_text_hold_callback = optionsutil.showValues ,
help_text = _ ( [[Set margins to be applied after page-crop and zoom modes are applied.]] ) ,
2023-03-14 17:29:16 +00:00
more_options = true ,
more_options_param = {
value_step = 0.01 , value_hold_step = 0.10 ,
value_min = 0 , value_max = 1.50 ,
precision = " %.2f " ,
} ,
2020-05-07 18:24:12 +00:00
} ,
2021-10-03 14:35:46 +00:00
{
name = " auto_straighten " ,
name_text = _ ( " Auto Straighten " ) ,
toggle = { _ ( " 0° " ) , _ ( " 5° " ) , _ ( " 10° " ) , _ ( " 15° " ) , _ ( " 25° " ) } ,
values = { 0 , 5 , 10 , 15 , 25 } ,
event = " DummyEvent " ,
args = { 0 , 5 , 10 , 15 , 25 } ,
more_options = true ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_AUTO_STRAIGHTEN " ) ,
2021-10-03 14:35:46 +00:00
name_text_hold_callback = optionsutil.showValues ,
help_text = _ ( [ [ Attempt to automatically straighten tilted source pages .
Will rotate up to specified value . ] ] ) ,
} ,
2014-03-13 13:52:43 +00:00
}
} ,
2020-11-28 16:18:57 +00:00
{
2020-12-19 11:18:30 +00:00
icon = " appbar.pagefit " ,
2020-11-28 16:18:57 +00:00
options = {
{
name = " zoom_overlap_h " ,
name_text = _ ( " Horizontal overlap " ) ,
2021-03-30 16:47:52 +00:00
enabled_func = function ( configurable , document )
-- NOTE: document.is_reflowable is wonky as hell, don't trust it.
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 0 )
end ,
2020-11-28 16:18:57 +00:00
buttonprogress = true ,
2021-10-01 02:30:18 +00:00
more_options = true ,
2020-11-28 16:18:57 +00:00
values = { 0 , 12 , 24 , 36 , 48 , 60 , 72 , 84 } ,
default_pos = 4 ,
default_value = 36 ,
show_func = function ( config )
return config and config.zoom_mode_genus < 3
end ,
event = " DefineZoom " ,
args = { 0 , 12 , 24 , 36 , 48 , 60 , 72 , 84 } ,
labels = { 0 , 12 , 24 , 36 , 48 , 60 , 72 , 84 } ,
2021-01-11 17:14:19 +00:00
hide_on_apply = true ,
2020-11-28 16:18:57 +00:00
name_text_hold_callback = optionsutil.showValues ,
help_text = _ ( [[Set horizontal zoom overlap (between columns).]] ) ,
} ,
{
name = " zoom_overlap_v " ,
name_text = _ ( " Vertical overlap " ) ,
2021-03-30 16:47:52 +00:00
enabled_func = function ( configurable , document )
-- NOTE: document.is_reflowable is wonky as hell, don't trust it.
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 0 )
end ,
2020-11-28 16:18:57 +00:00
buttonprogress = true ,
2021-10-01 02:30:18 +00:00
more_options = true ,
2020-11-28 16:18:57 +00:00
values = { 0 , 12 , 24 , 36 , 48 , 60 , 72 , 84 } ,
default_pos = 4 ,
default_value = 36 ,
show_func = function ( config )
return config and config.zoom_mode_genus < 3
end ,
event = " DefineZoom " ,
args = { 0 , 12 , 24 , 36 , 48 , 60 , 72 , 84 } ,
labels = { 0 , 12 , 24 , 36 , 48 , 60 , 72 , 84 } ,
2021-01-11 17:14:19 +00:00
hide_on_apply = true ,
2020-11-28 16:18:57 +00:00
name_text_hold_callback = optionsutil.showValues ,
help_text = _ ( [[Set vertical zoom overlap (between lines).]] ) ,
} ,
{
name = " zoom_mode_type " ,
name_text = _ ( " Fit " ) ,
2021-03-30 16:47:52 +00:00
enabled_func = function ( configurable , document )
-- NOTE: document.is_reflowable is wonky as hell, don't trust it.
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 0 )
end ,
2020-11-28 16:18:57 +00:00
toggle = { _ ( " full " ) , _ ( " width " ) , _ ( " height " ) } ,
alternate = false ,
values = { 2 , 1 , 0 } ,
2021-03-30 16:47:52 +00:00
default_value = 1 ,
2020-11-28 16:18:57 +00:00
show_func = function ( config ) return config and config.zoom_mode_genus > 2 end ,
event = " DefineZoom " ,
args = { " full " , " width " , " height " } ,
name_text_hold_callback = optionsutil.showValues ,
2021-03-29 18:32:38 +00:00
help_text = _ ( [[Set how the page should be resized to fit the screen.]] ) ,
2020-11-28 16:18:57 +00:00
} ,
{
name = " zoom_range_number " ,
name_text_func = function ( config )
if config then
if config.zoom_mode_genus == 1 then return _ ( " Rows " )
elseif config.zoom_mode_genus == 2 then return _ ( " Columns " )
end
end
return _ ( " Number " )
end ,
name_text_true_values = true ,
2021-03-30 16:47:52 +00:00
enabled_func = function ( configurable , document )
-- NOTE: document.is_reflowable is wonky as hell, don't trust it.
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 0 )
end ,
2020-11-28 16:18:57 +00:00
show_true_value_func = function ( str )
return string.format ( " %.1f " , str )
end ,
2020-11-30 09:08:03 +00:00
toggle = { " 1 " , " 2 " , " 3 " , " 4 " , " 5 " , " 6 " , " 7 " , " 8 " } ,
2020-11-28 16:18:57 +00:00
more_options = true ,
more_options_param = {
value_step = 0.1 , value_hold_step = 1 ,
value_min = 0.1 , value_max = 1000 ,
precision = " %.1f " ,
} ,
values = { 1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 , 7.0 , 8.0 } ,
default_pos = 2 ,
default_value = 2 ,
show_func = function ( config )
return config and config.zoom_mode_genus < 3 and config.zoom_mode_genus > 0
end ,
event = " DefineZoom " ,
args = { 1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 , 7.0 , 8.0 } ,
2021-01-11 17:14:19 +00:00
hide_on_apply = true ,
2020-11-28 16:18:57 +00:00
name_text_hold_callback = optionsutil.showValues ,
help_text = _ ( [[Set the number of columns or rows into which to split the page.]] ) ,
} ,
{
name = " zoom_factor " ,
name_text = _ ( " Zoom factor " ) ,
name_text_true_values = true ,
2021-03-30 16:47:52 +00:00
enabled_func = function ( configurable , document )
-- NOTE: document.is_reflowable is wonky as hell, don't trust it.
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 0 )
end ,
2020-11-28 16:18:57 +00:00
show_true_value_func = function ( str )
return string.format ( " %.1f " , str )
end ,
2020-11-30 09:08:03 +00:00
toggle = { " 0.7 " , " 1 " , " 1.5 " , " 2 " , " 3 " , " 5 " , " 10 " , " 20 " } ,
2020-11-28 16:18:57 +00:00
more_options = true ,
more_options_param = {
value_step = 0.1 , value_hold_step = 1 ,
value_min = 0.1 , value_max = 1000 ,
precision = " %.1f " ,
} ,
values = { 0.7 , 1.0 , 1.5 , 2.0 , 3.0 , 5.0 , 10.0 , 20.0 } ,
default_pos = 3 ,
default_value = 1.5 ,
show_func = function ( config )
return config and config.zoom_mode_genus < 1
end ,
event = " DefineZoom " ,
args = { 0.7 , 1.0 , 1.5 , 2.0 , 3.0 , 5.0 , 10.0 , 20.0 } ,
2021-01-11 17:14:19 +00:00
hide_on_apply = true ,
2020-11-28 16:18:57 +00:00
name_text_hold_callback = optionsutil.showValues ,
} ,
{
name = " zoom_mode_genus " ,
name_text = _ ( " Zoom to " ) ,
2021-03-30 16:47:52 +00:00
enabled_func = function ( configurable , document )
-- NOTE: document.is_reflowable is wonky as hell, don't trust it.
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 0 )
end ,
2020-11-28 16:18:57 +00:00
-- toggle = {_("page"), _("content"), _("columns"), _("rows"), _("manual")},
item_icons = {
2020-12-19 11:18:30 +00:00
" zoom.page " ,
" zoom.content " ,
" zoom.column " ,
" zoom.row " ,
" zoom.manual " ,
2020-11-28 16:18:57 +00:00
} ,
alternate = false ,
values = { 4 , 3 , 2 , 1 , 0 } ,
2021-03-30 16:47:52 +00:00
labels = { _ ( " page " ) , _ ( " content " ) , _ ( " columns " ) , _ ( " rows " ) , _ ( " manual " ) } ,
2020-11-28 16:18:57 +00:00
default_value = 4 ,
event = " DefineZoom " ,
args = { " page " , " content " , " columns " , " rows " , " manual " } ,
name_text_hold_callback = optionsutil.showValues ,
} ,
{
name = " zoom_direction " ,
name_text = _ ( " Direction " ) ,
enabled_func = function ( config )
2021-03-30 16:47:52 +00:00
return optionsutil.enableIfEquals ( config , " text_wrap " , 0 ) and config.zoom_mode_genus < 3
2020-11-28 16:18:57 +00:00
end ,
item_icons = {
2020-12-19 11:18:30 +00:00
" direction.LRTB " ,
" direction.TBLR " ,
" direction.LRBT " ,
" direction.BTLR " ,
" direction.BTRL " ,
" direction.RLBT " ,
" direction.TBRL " ,
" direction.RLTB " ,
2020-11-28 16:18:57 +00:00
} ,
alternate = false ,
values = { 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 } ,
2021-03-30 16:47:52 +00:00
labels = {
_ ( " Left to Right, Top to Bottom " ) ,
_ ( " Top to Bottom, Left to Right " ) ,
_ ( " Left to Right, Bottom to Top " ) ,
_ ( " Bottom to Top, Left to Right " ) ,
_ ( " Bottom to Top, Right to Left " ) ,
_ ( " Right to Left, Bottom to Top " ) ,
_ ( " Top to Bottom, Right to Left " ) ,
_ ( " Right to Left, Top to Bottom " ) ,
} ,
2020-11-28 16:18:57 +00:00
default_value = 7 ,
event = " DefineZoom " ,
args = { 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 } ,
2021-01-11 17:14:19 +00:00
hide_on_apply = true ,
2020-11-28 16:18:57 +00:00
name_text_hold_callback = optionsutil.showValues ,
help_text = _ ( [ [ Set how paging and swiping forward should move the view on the page :
left to right or reverse , top to bottom or reverse . ] ] ) ,
} ,
}
} ,
2014-03-13 13:52:43 +00:00
{
2020-12-19 11:18:30 +00:00
icon = " appbar.pageview " ,
2014-03-13 13:52:43 +00:00
options = {
{
name = " page_scroll " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " View Mode " ) ,
toggle = { _ ( " page " ) , _ ( " continuous " ) } ,
2020-05-07 18:24:12 +00:00
values = { 0 , 1 } ,
2020-01-07 19:16:59 +00:00
default_value = 1 ,
2016-03-27 22:39:47 +00:00
event = " SetScrollMode " ,
2020-05-07 18:24:12 +00:00
args = { false , true } ,
name_text_hold_callback = optionsutil.showValues ,
help_text = _ ( [ [ - ' page ' mode shows only one page of the document at a time .
- ' continuous ' mode allows you to scroll the pages like you would in a web browser . ] ] ) ,
} ,
{
name = " page_gap_height " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Page Gap " ) ,
2021-11-28 21:49:22 +00:00
toggle = { C_ ( " Page gap " , " none " ) , C_ ( " Page gap " , " small " ) , C_ ( " Page gap " , " medium " ) , C_ ( " Page gap " , " large " ) } ,
2020-05-07 18:24:12 +00:00
values = { 0 , 8 , 16 , 32 } ,
default_value = 8 ,
args = { 0 , 8 , 16 , 32 } ,
event = " PageGapUpdate " ,
enabled_func = function ( configurable )
return optionsutil.enableIfEquals ( configurable , " page_scroll " , 1 )
end ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2020-05-07 18:24:12 +00:00
help_text = _ ( [[In continuous view mode, sets the thickness of the separator between document pages.]] ) ,
2014-03-13 13:52:43 +00:00
} ,
{
name = " full_screen " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Progress Bar " ) ,
toggle = { _ ( " off " ) , _ ( " on " ) } ,
2014-03-13 13:52:43 +00:00
values = { 1 , 0 } ,
2019-12-27 22:03:31 +00:00
default_value = 1 ,
2014-03-13 13:52:43 +00:00
event = " SetFullScreen " ,
args = { true , false } ,
2020-05-07 18:24:12 +00:00
show = false , -- toggling bottom status can be done via tap
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2014-03-13 13:52:43 +00:00
} ,
{
name = " line_spacing " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Line Spacing " ) ,
2021-11-28 21:49:22 +00:00
toggle = { C_ ( " Line spacing " , " small " ) , C_ ( " Line spacing " , " medium " ) , C_ ( " Line spacing " , " large " ) } ,
2014-03-13 13:52:43 +00:00
values = { 1.0 , 1.2 , 1.4 } ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_LINE_SPACING " ) ,
2014-08-05 04:04:17 +00:00
advanced = true ,
2015-03-16 13:49:53 +00:00
enabled_func = function ( configurable )
2020-05-07 18:24:12 +00:00
-- seems to only work in reflow mode
2018-05-26 17:45:37 +00:00
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 1 )
2015-03-16 13:49:53 +00:00
end ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2020-05-07 18:24:12 +00:00
help_text = _ ( [[In reflow mode, sets the spacing between lines.]] ) ,
2014-05-29 12:58:25 +00:00
} ,
{
name = " justification " ,
2020-11-29 09:18:59 +00:00
--- @translators Text alignment. Options given as icons: left, right, center, justify.
name_text = _ ( " Alignment " ) ,
2014-05-29 12:58:25 +00:00
item_icons = {
2020-12-19 11:18:30 +00:00
" align.auto " ,
" align.left " ,
" align.center " ,
" align.right " ,
" align.justify " ,
2014-05-29 12:58:25 +00:00
} ,
values = { - 1 , 0 , 1 , 2 , 3 } ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_JUSTIFICATION " ) ,
2014-08-05 04:04:17 +00:00
advanced = true ,
2015-03-16 13:49:53 +00:00
enabled_func = function ( configurable )
2018-05-26 17:45:37 +00:00
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 1 )
2015-03-16 13:49:53 +00:00
end ,
2020-11-29 09:18:59 +00:00
labels = {
C_ ( " Alignment " , " auto " ) ,
C_ ( " Alignment " , " left " ) ,
C_ ( " Alignment " , " center " ) ,
C_ ( " Alignment " , " right " ) ,
C_ ( " Alignment " , " justify " ) ,
} ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2020-05-07 18:24:12 +00:00
help_text = _ ( [ [ In reflow mode , sets the text alignment .
The first option ( " auto " ) tries to automatically align reflowed text as it is in the original document . ] ] ) ,
2014-05-29 12:58:25 +00:00
} ,
2014-03-13 13:52:43 +00:00
}
} ,
{
2020-12-19 11:18:30 +00:00
icon = " appbar.textsize " ,
2014-03-13 13:52:43 +00:00
options = {
{
name = " font_size " ,
2020-05-07 18:24:12 +00:00
item_text = tableOfNumbersToTableOfStrings ( FONT_SCALE_FACTORS ) ,
2014-03-13 13:52:43 +00:00
item_align_center = 1.0 ,
spacing = 15 ,
2020-05-07 18:24:12 +00:00
item_font_size = FONT_SCALE_DISPLAY_SIZE ,
args = FONT_SCALE_FACTORS ,
values = FONT_SCALE_FACTORS ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_FONT_SIZE " ) ,
2014-03-13 13:52:43 +00:00
event = " FontSizeUpdate " ,
2019-08-30 11:47:51 +00:00
enabled_func = function ( configurable , document )
if document.is_reflowable then return true end
2018-05-26 17:45:37 +00:00
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 1 )
2015-03-16 13:49:53 +00:00
end ,
2014-03-13 13:52:43 +00:00
} ,
{
name = " font_fine_tune " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Font Size " ) ,
toggle = Device : isTouchDevice ( ) and { _ ( " decrease " ) , _ ( " increase " ) } or nil ,
item_text = not Device : isTouchDevice ( ) and { _ ( " decrease " ) , _ ( " increase " ) } or nil ,
2014-03-13 13:52:43 +00:00
values = { - 0.05 , 0.05 } ,
default_value = 0.05 ,
event = " FineTuningFontSize " ,
args = { - 0.05 , 0.05 } ,
alternate = false ,
2019-08-30 11:47:51 +00:00
enabled_func = function ( configurable , document )
if document.is_reflowable then return true end
2018-05-26 17:45:37 +00:00
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 1 )
2015-03-16 13:49:53 +00:00
end ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = function ( configurable , __ , prefix )
local opt = {
name = " font_size " ,
name_text = _ ( " Font Size " ) ,
2020-05-07 18:24:12 +00:00
help_text = _ ( [[In reflow mode, sets a font scaling factor that is applied to the original document font sizes.]] ) ,
2018-05-26 17:45:37 +00:00
}
optionsutil.showValues ( configurable , opt , prefix )
2020-05-07 18:24:12 +00:00
end ,
} ,
2014-03-13 13:52:43 +00:00
{
2020-05-07 18:24:12 +00:00
name = " word_spacing " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Word Gap " ) ,
2021-11-28 21:49:22 +00:00
toggle = { C_ ( " Word gap " , " small " ) , C_ ( " Word gap " , " auto " ) , C_ ( " Word gap " , " large " ) } ,
2022-09-27 23:10:50 +00:00
values = G_defaults : readSetting ( " DKOPTREADER_CONFIG_WORD_SPACINGS " ) ,
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_DEFAULT_WORD_SPACING " ) ,
2020-05-07 18:24:12 +00:00
enabled_func = function ( configurable )
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 1 )
end ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2020-05-07 18:24:12 +00:00
help_text = _ ( [[In reflow mode, sets the spacing between words.]] ) ,
} ,
2014-03-13 13:52:43 +00:00
{
name = " text_wrap " ,
2020-11-29 09:18:59 +00:00
--- @translators Reflow text.
name_text = _ ( " Reflow " ) ,
toggle = { _ ( " off " ) , _ ( " on " ) } ,
2020-05-07 18:24:12 +00:00
values = { 0 , 1 } ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_TEXT_WRAP " ) ,
2021-08-30 15:21:50 +00:00
event = " ReflowUpdated " ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2020-05-07 18:24:12 +00:00
help_text = _ ( [ [ Reflow mode extracts text and images from the original document , possibly discarding some formatting , and reflows it on the screen for easier reading .
Some of the other settings are only available when reflow mode is enabled . ] ] ) ,
} ,
}
} ,
{
2020-12-19 11:18:30 +00:00
icon = " appbar.contrast " ,
2020-05-07 18:24:12 +00:00
options = {
{
name = " contrast " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Contrast " ) ,
2020-05-07 18:24:12 +00:00
buttonprogress = true ,
-- See https://github.com/koreader/koreader/issues/1299#issuecomment-65183895
-- For pdf reflowing mode (kopt_contrast):
2023-09-02 06:41:27 +00:00
values = { 0.8 , 1.0 , 1.5 , 2.0 , 4.0 , 6.0 , 10.0 , 50.0 } ,
2020-05-07 18:24:12 +00:00
default_pos = 2 ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_CONTRAST " ) ,
2020-05-07 18:24:12 +00:00
event = " GammaUpdate " ,
-- For pdf non-reflowing mode (mupdf):
args = { 0.8 , 1.0 , 1.5 , 2.0 , 4.0 , 6.0 , 10.0 , 50.0 } ,
labels = { 0.8 , 1.0 , 1.5 , 2.0 , 4.0 , 6.0 , 10.0 , 50.0 } ,
name_text_hold_callback = optionsutil.showValues ,
2023-09-02 06:41:27 +00:00
more_options = true ,
more_options_param = {
value_step = 0.1 , value_hold_step = 1 ,
value_min = 0.8 , value_max = 50 ,
precision = " %.1f " ,
} ,
2014-03-13 13:52:43 +00:00
} ,
2014-04-06 16:22:47 +00:00
{
name = " page_opt " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Dewatermark " ) ,
toggle = { _ ( " off " ) , _ ( " on " ) } ,
2020-05-07 18:24:12 +00:00
values = { 0 , 1 } ,
2014-04-06 16:22:47 +00:00
default_value = 0 ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2018-07-04 10:08:55 +00:00
help_text = _ ( [ [ Remove watermarks from the rendered document .
This can also be used to remove some gray background or to convert a grayscale or color document to black & white and get more contrast for easier reading . ] ] ) ,
2014-04-06 16:22:47 +00:00
} ,
2014-03-13 13:52:43 +00:00
{
2020-05-07 18:24:12 +00:00
name = " hw_dithering " ,
2022-02-05 19:20:15 +00:00
name_text = _ ( " Dithering " ) ,
2020-11-29 09:18:59 +00:00
toggle = { _ ( " off " ) , _ ( " on " ) } ,
2020-05-07 18:24:12 +00:00
values = { 0 , 1 } ,
2014-03-13 13:52:43 +00:00
default_value = 0 ,
2020-05-07 18:24:12 +00:00
advanced = true ,
2022-02-06 17:01:45 +00:00
event = " HWDitheringUpdate " ,
args = { false , true } ,
2020-05-07 18:24:12 +00:00
show = Device : hasEinkScreen ( ) and Device : canHWDither ( ) ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2022-02-05 18:49:13 +00:00
help_text = _ ( [[Enable hardware dithering.]] ) ,
} ,
{
name = " sw_dithering " ,
2022-02-05 19:20:15 +00:00
name_text = _ ( " Dithering " ) ,
2022-02-05 18:49:13 +00:00
toggle = { _ ( " off " ) , _ ( " on " ) } ,
values = { 0 , 1 } ,
default_value = 0 ,
advanced = true ,
2022-02-06 17:01:45 +00:00
event = " SWDitheringUpdate " ,
args = { false , true } ,
2022-02-05 19:20:15 +00:00
show = Device : hasEinkScreen ( ) and not Device : canHWDither ( ) and Device.screen . fb_bpp == 8 ,
2022-02-05 18:49:13 +00:00
name_text_hold_callback = optionsutil.showValues ,
help_text = _ ( [[Enable software dithering.]] ) ,
2014-03-13 13:52:43 +00:00
} ,
{
name = " quality " ,
2020-11-29 09:18:59 +00:00
name_text = C_ ( " Quality " , " Render Quality " ) ,
toggle = { C_ ( " Quality " , " low " ) , C_ ( " Quality " , " default " ) , C_ ( " Quality " , " high " ) } ,
2014-03-13 13:52:43 +00:00
values = { 0.5 , 1.0 , 1.5 } ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_RENDER_QUALITY " ) ,
2014-08-05 04:04:17 +00:00
advanced = true ,
2015-03-16 13:49:53 +00:00
enabled_func = function ( configurable )
2018-05-26 17:45:37 +00:00
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 1 )
2015-03-16 13:49:53 +00:00
end ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2020-05-07 18:24:12 +00:00
help_text = _ ( [[In reflow mode, sets the quality of the text and image extraction processing and output.]] ) ,
Enable HW dithering in a few key places (#4541)
* Enable HW dithering on supported devices (Clara HD, Forma; Oasis 2, PW4)
* FileManager and co. (where appropriate, i.e., when covers are shown)
* Book Status
* Reader, where appropriate:
* CRe: on pages whith image content (for over 7.5% of the screen area, should hopefully leave stuff like bullet points or small scene breaks alone).
* Other engines: on user-request (in the gear tab of the bottom menu), via the new "Dithering" knob (will only appear on supported devices).
* ScreenSaver
* ImageViewer
* Minimize repaints when flash_ui is enabled (by, almost everywhere, only repainting the flashing element, and not the toplevel window which hosts it).
(The first pass of this involved fixing a few Button instances whose show_parent was wrong, in particular, chevrons in the FM & TopMenu).
* Hunted down a few redundant repaints (unneeded setDirty("all") calls),
either by switching the widget to nil when only a refresh was needed, and not a repaint,
or by passing the appropritate widget to setDirty.
(Note to self: Enable *verbose* debugging to catch broken setDirty calls via its post guard).
There were also a few instances of 'em right behind a widget close.
* Don't repaint the underlying widget when initially showing TopMenu & ConfigDialog.
We unfortunately do need to do it when switching tabs, because of their variable heights.
* On Kobo, disabled the extra and completely useless full refresh before suspend/reboot/poweroff, as well as on resume. No more double refreshes!
* Fix another debug guard in Kobo sysfs_light
* Switch ImageWidget & ImageViewer mostly to "ui" updates, which will be better suited to image content pretty much everywhere, REAGL or not.
PS: (Almost :100: commits! :D)
2019-02-07 00:14:37 +00:00
} ,
2020-05-07 18:24:12 +00:00
}
} ,
{
2020-12-19 11:18:30 +00:00
icon = " appbar.settings " ,
2020-05-07 18:24:12 +00:00
options = {
Enable HW dithering in a few key places (#4541)
* Enable HW dithering on supported devices (Clara HD, Forma; Oasis 2, PW4)
* FileManager and co. (where appropriate, i.e., when covers are shown)
* Book Status
* Reader, where appropriate:
* CRe: on pages whith image content (for over 7.5% of the screen area, should hopefully leave stuff like bullet points or small scene breaks alone).
* Other engines: on user-request (in the gear tab of the bottom menu), via the new "Dithering" knob (will only appear on supported devices).
* ScreenSaver
* ImageViewer
* Minimize repaints when flash_ui is enabled (by, almost everywhere, only repainting the flashing element, and not the toplevel window which hosts it).
(The first pass of this involved fixing a few Button instances whose show_parent was wrong, in particular, chevrons in the FM & TopMenu).
* Hunted down a few redundant repaints (unneeded setDirty("all") calls),
either by switching the widget to nil when only a refresh was needed, and not a repaint,
or by passing the appropritate widget to setDirty.
(Note to self: Enable *verbose* debugging to catch broken setDirty calls via its post guard).
There were also a few instances of 'em right behind a widget close.
* Don't repaint the underlying widget when initially showing TopMenu & ConfigDialog.
We unfortunately do need to do it when switching tabs, because of their variable heights.
* On Kobo, disabled the extra and completely useless full refresh before suspend/reboot/poweroff, as well as on resume. No more double refreshes!
* Fix another debug guard in Kobo sysfs_light
* Switch ImageWidget & ImageViewer mostly to "ui" updates, which will be better suited to image content pretty much everywhere, REAGL or not.
PS: (Almost :100: commits! :D)
2019-02-07 00:14:37 +00:00
{
2021-05-14 22:13:27 +00:00
name = " doc_language " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Document Language " ) ,
2022-09-27 23:10:50 +00:00
toggle = G_defaults : readSetting ( " DKOPTREADER_CONFIG_DOC_LANGS_TEXT " ) ,
values = G_defaults : readSetting ( " DKOPTREADER_CONFIG_DOC_LANGS_CODE " ) ,
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_DOC_DEFAULT_LANG_CODE " ) ,
2020-05-07 18:24:12 +00:00
event = " DocLangUpdate " ,
2022-09-27 23:10:50 +00:00
args = G_defaults : readSetting ( " DKOPTREADER_CONFIG_DOC_LANGS_CODE " ) ,
Enable HW dithering in a few key places (#4541)
* Enable HW dithering on supported devices (Clara HD, Forma; Oasis 2, PW4)
* FileManager and co. (where appropriate, i.e., when covers are shown)
* Book Status
* Reader, where appropriate:
* CRe: on pages whith image content (for over 7.5% of the screen area, should hopefully leave stuff like bullet points or small scene breaks alone).
* Other engines: on user-request (in the gear tab of the bottom menu), via the new "Dithering" knob (will only appear on supported devices).
* ScreenSaver
* ImageViewer
* Minimize repaints when flash_ui is enabled (by, almost everywhere, only repainting the flashing element, and not the toplevel window which hosts it).
(The first pass of this involved fixing a few Button instances whose show_parent was wrong, in particular, chevrons in the FM & TopMenu).
* Hunted down a few redundant repaints (unneeded setDirty("all") calls),
either by switching the widget to nil when only a refresh was needed, and not a repaint,
or by passing the appropritate widget to setDirty.
(Note to self: Enable *verbose* debugging to catch broken setDirty calls via its post guard).
There were also a few instances of 'em right behind a widget close.
* Don't repaint the underlying widget when initially showing TopMenu & ConfigDialog.
We unfortunately do need to do it when switching tabs, because of their variable heights.
* On Kobo, disabled the extra and completely useless full refresh before suspend/reboot/poweroff, as well as on resume. No more double refreshes!
* Fix another debug guard in Kobo sysfs_light
* Switch ImageWidget & ImageViewer mostly to "ui" updates, which will be better suited to image content pretty much everywhere, REAGL or not.
PS: (Almost :100: commits! :D)
2019-02-07 00:14:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2020-05-07 18:24:12 +00:00
help_text = _ ( [[Set the language to be used by the OCR engine.]] ) ,
2014-03-13 13:52:43 +00:00
} ,
2014-07-17 14:32:20 +00:00
{
name = " forced_ocr " ,
2020-11-29 09:18:59 +00:00
--- @translators If OCR is unclear, please see https://en.wikipedia.org/wiki/Optical_character_recognition
name_text = _ ( " Forced OCR " ) ,
toggle = { _ ( " off " ) , _ ( " on " ) } ,
2020-05-07 18:24:12 +00:00
values = { 0 , 1 } ,
2014-07-17 14:32:20 +00:00
default_value = 0 ,
advanced = true ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2020-05-07 18:24:12 +00:00
help_text = _ ( [[Force the use of OCR for text selection, even if the document has a text layer.]] ) ,
} ,
{
name = " writing_direction " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Writing Direction " ) ,
2020-05-07 18:24:12 +00:00
enabled_func = function ( configurable )
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 1 )
end ,
2020-11-29 09:18:59 +00:00
toggle = {
--- @translators LTR is left to right, which is the regular European writing direction.
_ ( " LTR " ) ,
--- @translators RTL is right to left, which is the regular writing direction in languages like Hebrew, Arabic, Persian and Urdu.
_ ( " RTL " ) ,
--- @translators TBRTL is top-to-bottom-right-to-left, which is a traditional Chinese/Japanese writing direction.
_ ( " TBRTL " ) ,
} ,
2020-11-28 16:18:57 +00:00
values = { 0 , 1 , 2 } ,
default_value = 0 ,
2020-05-07 18:24:12 +00:00
name_text_hold_callback = optionsutil.showValues ,
help_text = _ ( [[In reflow mode, sets the original text direction. This needs to be set to RTL to correctly extract and reflow RTL languages like Arabic or Hebrew.]] ) ,
2014-07-17 14:32:20 +00:00
} ,
2014-03-13 13:52:43 +00:00
{
name = " defect_size " ,
2020-11-29 09:18:59 +00:00
--- @translators The maximum size of a dust or ink speckle to be ignored instead of being considered a character.
name_text = _ ( " Reflow Speckle Ignore Size " ) ,
toggle = { _ ( " small " ) , _ ( " medium " ) , _ ( " large " ) } ,
2014-03-13 13:52:43 +00:00
values = { 1.0 , 3.0 , 5.0 } ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_DEFECT_SIZE " ) ,
2014-03-13 13:52:43 +00:00
event = " DefectSizeUpdate " ,
2020-05-07 18:24:12 +00:00
show = false , -- might work somehow, but larger values than 1.0 might easily eat content
2015-03-16 13:49:53 +00:00
enabled_func = function ( configurable )
2018-05-26 17:45:37 +00:00
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 1 )
2015-03-16 13:49:53 +00:00
end ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2014-03-13 13:52:43 +00:00
} ,
{
name = " detect_indent " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Indentation " ) ,
toggle = { _ ( " off " ) , _ ( " on " ) } ,
2020-05-07 18:24:12 +00:00
values = { 0 , 1 } ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_DETECT_INDENT " ) ,
2020-05-07 18:24:12 +00:00
show = false , -- does not work
enabled_func = function ( configurable )
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 1 )
end ,
name_text_hold_callback = optionsutil.showValues ,
} ,
{
name = " max_columns " ,
2020-11-29 09:18:59 +00:00
name_text = _ ( " Document Columns " ) ,
2020-05-07 18:24:12 +00:00
item_icons = {
2020-12-19 11:18:30 +00:00
" column.one " ,
" column.two " ,
" column.three " ,
2020-05-07 18:24:12 +00:00
} ,
2021-03-30 16:47:52 +00:00
values = { 1 , 2 , 3 } ,
2022-09-27 23:10:50 +00:00
default_value = G_defaults : readSetting ( " DKOPTREADER_CONFIG_MAX_COLUMNS " ) ,
2015-03-16 13:49:53 +00:00
enabled_func = function ( configurable )
2018-05-26 17:45:37 +00:00
return optionsutil.enableIfEquals ( configurable , " text_wrap " , 1 )
2015-03-16 13:49:53 +00:00
end ,
2018-05-26 17:45:37 +00:00
name_text_hold_callback = optionsutil.showValues ,
2020-05-07 18:24:12 +00:00
help_text = _ ( [ [ In reflow mode , sets the max number of columns to try to detect in the original document .
You might need to set it to 1 column if , in a full width document , text is incorrectly detected as multiple columns because of unlucky word spacing . ] ] ) ,
2014-03-13 13:52:43 +00:00
} ,
}
} ,
2013-04-08 14:26:54 +00:00
}
2013-10-18 20:38:07 +00:00
2019-12-06 21:55:39 +00:00
if BD.mirroredUILayout ( ) then
-- The justification items {AUTO, LEFT, CENTER, RIGHT, JUSTIFY} will
-- be mirrored - but that's not enough: we need to swap LEFT and RIGHT,
-- so they appear in a more expected and balanced order to RTL users:
-- {JUSTIFY, LEFT, CENTER, RIGHT, AUTO}
2020-12-10 22:53:33 +00:00
local j = KoptOptions [ 4 ] . options [ 5 ]
2019-12-06 21:55:39 +00:00
assert ( j.name == " justification " )
j.item_icons [ 2 ] , j.item_icons [ 4 ] = j.item_icons [ 4 ] , j.item_icons [ 2 ]
j.values [ 2 ] , j.values [ 4 ] = j.values [ 4 ] , j.values [ 2 ]
j.labels [ 2 ] , j.labels [ 4 ] = j.labels [ 4 ] , j.labels [ 2 ]
2020-12-10 22:53:33 +00:00
-- The zoom direction items will be mirrored, but we want them to
-- stay as is, as the RTL diretions are at the end of the arrays.
-- By reverting the mirroring, RTL directions will be on the right,
-- so, at the start of the options for a RTL reader.
j = KoptOptions [ 3 ] . options [ 7 ]
assert ( j.name == " zoom_direction " )
util.arrayReverse ( j.item_icons )
util.arrayReverse ( j.values )
util.arrayReverse ( j.args )
j.default_value = 0
2019-12-06 21:55:39 +00:00
end
2013-10-18 20:38:07 +00:00
return KoptOptions