Allow toggling CRe's new dithering & scaling (#4922)

Smooth scaling toggle is per document, in the gear tab.
Dithering is in the Dev top menu ;).
pull/4940/head
NiLuJe 5 years ago committed by GitHub
parent 6203fbb633
commit 9134594119
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1 +1 @@
Subproject commit ccd44cf38a82ff3e3fb5aaebe683b6cb18296a23 Subproject commit b6b6d74979d7f52b93b1e112afa995815c87a649

@ -289,6 +289,43 @@ function FileManagerMenu:setUpdateItemTable()
end, end,
}) })
end end
if Device:hasEinkScreen() and Device:canHWDither() then
table.insert(self.menu_items.developer_options.sub_item_table, {
text = _("Disable HW dithering"),
checked_func = function()
return not Device.screen.hw_dithering
end,
callback = function()
G_reader_settings:flipNilOrFalse("dev_no_hw_dither")
Device.screen:toggleHWDithering()
-- Make sure SW dithering gets disabled when we enable HW dithering
if Device.screen.hw_dithering and Device.screen.sw_dithering then
Device.screen:toggleSWDithering()
end
UIManager:setDirty("all", "full")
end,
})
end
if Device:hasEinkScreen() then
table.insert(self.menu_items.developer_options.sub_item_table, {
text = _("Disable SW dithering"),
enabled_func = function()
return Device.screen.fb_bpp == 8
end,
checked_func = function()
return not Device.screen.sw_dithering
end,
callback = function()
G_reader_settings:flipNilOrFalse("dev_no_sw_dither")
Device.screen:toggleSWDithering()
-- Make sure HW dithering gets disabled when we enable SW dithering
if Device.screen.hw_dithering and Device.screen.sw_dithering then
Device.screen:toggleHWDithering()
end
UIManager:setDirty("all", "full")
end,
})
end
self.menu_items.cloud_storage = { self.menu_items.cloud_storage = {
text = _("Cloud storage"), text = _("Cloud storage"),
callback = function() callback = function()

@ -75,6 +75,14 @@ function ReaderTypeset:onReadSettings(config)
self.txt_preformatted = config:readSetting("txt_preformatted") or self.txt_preformatted = config:readSetting("txt_preformatted") or
G_reader_settings:readSetting("txt_preformatted") or 1 G_reader_settings:readSetting("txt_preformatted") or 1
self:toggleTxtPreFormatted(self.txt_preformatted) self:toggleTxtPreFormatted(self.txt_preformatted)
-- default to disable smooth scaling for now.
self.smooth_scaling = config:readSetting("smooth_scaling")
if self.smooth_scaling == nil then
local global = G_reader_settings:readSetting("copt_smooth_scaling")
self.smooth_scaling = (global == nil or global == 0) and 0 or 1
end
self:toggleImageScaling(self.smooth_scaling)
end end
function ReaderTypeset:onSaveSettings() function ReaderTypeset:onSaveSettings()
@ -83,6 +91,7 @@ function ReaderTypeset:onSaveSettings()
self.ui.doc_settings:saveSetting("floating_punctuation", self.floating_punctuation) self.ui.doc_settings:saveSetting("floating_punctuation", self.floating_punctuation)
self.ui.doc_settings:saveSetting("embedded_fonts", self.embedded_fonts) self.ui.doc_settings:saveSetting("embedded_fonts", self.embedded_fonts)
self.ui.doc_settings:saveSetting("render_dpi", self.render_dpi) self.ui.doc_settings:saveSetting("render_dpi", self.render_dpi)
self.ui.doc_settings:saveSetting("smooth_scaling", self.smooth_scaling)
end end
function ReaderTypeset:onToggleEmbeddedStyleSheet(toggle) function ReaderTypeset:onToggleEmbeddedStyleSheet(toggle)
@ -95,6 +104,11 @@ function ReaderTypeset:onToggleEmbeddedFonts(toggle)
return true return true
end end
function ReaderTypeset:onToggleImageScaling(toggle)
self:toggleImageScaling(toggle)
return true
end
-- June 2018: epub.css has been cleaned to be more conforming to HTML specs -- June 2018: epub.css has been cleaned to be more conforming to HTML specs
-- and to not include class name based styles (with conditional compatiblity -- and to not include class name based styles (with conditional compatiblity
-- styles for previously opened documents). It should be usable on all -- styles for previously opened documents). It should be usable on all
@ -248,6 +262,17 @@ function ReaderTypeset:toggleEmbeddedFonts(toggle)
self.ui:handleEvent(Event:new("UpdatePos")) self.ui:handleEvent(Event:new("UpdatePos"))
end end
function ReaderTypeset:toggleImageScaling(toggle)
if toggle and (toggle == true or toggle == 1) then
self.smooth_scaling = true
self.ui.document:setImageScaling(true)
else
self.smooth_scaling = false
self.ui.document:setImageScaling(false)
end
self.ui:handleEvent(Event:new("UpdatePos"))
end
function ReaderTypeset:toggleFloatingPunctuation(toggle) function ReaderTypeset:toggleFloatingPunctuation(toggle)
-- for some reason the toggle value read from history files may stay boolean -- for some reason the toggle value read from history files may stay boolean
-- and there seems no more elegant way to convert boolean values to numbers -- and there seems no more elegant way to convert boolean values to numbers

@ -5,6 +5,7 @@ local Document = require("document/document")
local FontList = require("fontlist") local FontList = require("fontlist")
local Geom = require("ui/geometry") local Geom = require("ui/geometry")
local RenderImage = require("ui/renderimage") local RenderImage = require("ui/renderimage")
local Screen = require("device").screen
local ffi = require("ffi") local ffi = require("ffi")
local C = ffi.C local C = ffi.C
local lfs = require("libs/libkoreader-lfs") local lfs = require("libs/libkoreader-lfs")
@ -21,6 +22,7 @@ local CreDocument = Document:new{
_document = false, _document = false,
_loaded = false, _loaded = false,
_view_mode = nil, _view_mode = nil,
_smooth_scaling = false,
line_space_percent = 100, line_space_percent = 100,
default_font = "Noto Serif", default_font = "Noto Serif",
@ -368,14 +370,15 @@ function CreDocument:drawCurrentView(target, x, y, rect, pos)
-- same buffer. And it could only change when some other methods -- same buffer. And it could only change when some other methods
-- from here are called -- from here are called
-- If in night mode, ask crengine to invert all images, so they -- If in night mode, we ask crengine to invert all images, so they
-- get displayed in their original colors when the whole screen -- get displayed in their original colors when the whole screen
-- is inverted by night mode -- is inverted by night mode
local invert_images = G_reader_settings:isTrue("night_mode") -- We also honor the current smooth scaling setting,
-- as well as the global SW dithering setting.
-- local start_clock = os.clock() -- local start_clock = os.clock()
self._drawn_images_count, self._drawn_images_surface_ratio = self._drawn_images_count, self._drawn_images_surface_ratio =
self._document:drawCurrentPage(self.buffer, self.render_color, invert_images) self._document:drawCurrentPage(self.buffer, self.render_color, Screen.night_mode, self._smooth_scaling, Screen.sw_dithering)
-- print(string.format("CreDocument:drawCurrentView: Rendering took %9.3f ms", (os.clock() - start_clock) * 1000)) -- print(string.format("CreDocument:drawCurrentView: Rendering took %9.3f ms", (os.clock() - start_clock) * 1000))
-- start_clock = os.clock() -- start_clock = os.clock()
@ -728,6 +731,11 @@ function CreDocument:setPageMargins(left, top, right, bottom)
self._document:setIntProperty("crengine.page.margin.bottom", bottom) self._document:setIntProperty("crengine.page.margin.bottom", bottom)
end end
function CreDocument:setImageScaling(toggle)
logger.dbg("CreDocument: set smooth scaling", toggle)
self._smooth_scaling = toggle
end
function CreDocument:setFloatingPunctuation(enabled) function CreDocument:setFloatingPunctuation(enabled)
-- FIXME: occasional segmentation fault when toggling floating punctuation -- FIXME: occasional segmentation fault when toggling floating punctuation
logger.dbg("CreDocument: set floating punctuation", enabled) logger.dbg("CreDocument: set floating punctuation", enabled)

@ -322,6 +322,19 @@ Note that your selected font size is not affected by this setting.]]),
help_text = _([[Enable or disable the use of the fonts embedded in the book. help_text = _([[Enable or disable the use of the fonts embedded in the book.
(Disabling the fonts specified in the publisher stylesheets can also be achieved via Style Tweaks in the main menu.)]]), (Disabling the fonts specified in the publisher stylesheets can also be achieved via Style Tweaks in the main menu.)]]),
}, },
{
name = "smooth_scaling",
name_text = S.IMAGE_SCALING,
toggle = {S.FAST, S.BEST},
values = {0, 1},
default_value = 0,
args = {false, true},
default_arg = nil,
event = "ToggleImageScaling",
name_text_hold_callback = optionsutil.showValues,
help_text = _([[- 'fast' uses a fast but inaccurate scaling algorithm when scaling images.
- 'best' switches to a more costly but vastly more pleasing and accurate algorithm.]]),
},
}, },
}, },
} }

@ -35,6 +35,7 @@ S.PROGRESS_BAR = _("Progress Bar")
S.FORCED_OCR = _("Forced OCR") S.FORCED_OCR = _("Forced OCR")
S.HW_DITHERING = _("Dithering") S.HW_DITHERING = _("Dithering")
S.INVERSE_READING_ORDER = _("Inverse Order") S.INVERSE_READING_ORDER = _("Inverse Order")
S.IMAGE_SCALING = _("Image Scaling")
S.ON = _("on") S.ON = _("on")
S.OFF = _("off") S.OFF = _("off")

@ -928,6 +928,12 @@ function UIManager:_repaint()
-- execute refreshes: -- execute refreshes:
for _, refresh in ipairs(self._refresh_stack) do for _, refresh in ipairs(self._refresh_stack) do
-- Honor dithering hints from *anywhere* in the dirty stack
refresh.dither = update_dither(refresh.dither, dithered)
-- If HW dithering is disabled, unconditionally drop the dither flag
if not Screen.hw_dithering then
refresh.dither = nil
end
dbg:v("triggering refresh", refresh) dbg:v("triggering refresh", refresh)
-- NOTE: We overshoot by 1px to account for potential off-by-ones. -- NOTE: We overshoot by 1px to account for potential off-by-ones.
-- This may not strictly be needed anymore, and is blatantly unneeded for full-screen updates, -- This may not strictly be needed anymore, and is blatantly unneeded for full-screen updates,

@ -29,6 +29,7 @@ local Screen = require("device").screen
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local Widget = require("ui/widget/widget") local Widget = require("ui/widget/widget")
local logger = require("logger") local logger = require("logger")
local util = require("util")
-- DPI_SCALE can't change without a restart, so let's compute it now -- DPI_SCALE can't change without a restart, so let's compute it now
local function get_dpi_scale() local function get_dpi_scale()
@ -355,17 +356,31 @@ function ImageWidget:paintTo(bb, x, y)
h = size.h h = size.h
} }
logger.dbg("blitFrom", x, y, self._offset_x, self._offset_y, size.w, size.h) logger.dbg("blitFrom", x, y, self._offset_x, self._offset_y, size.w, size.h)
-- Figure out if we're trying to render one of our own icons...
local is_icon = self.file and util.stringStartsWith(self.file, "resources/")
if self.alpha == true then if self.alpha == true then
-- Only actually try to alpha-blend if the image really has an alpha channel... -- Only actually try to alpha-blend if the image really has an alpha channel...
local bbtype = self._bb:getType() local bbtype = self._bb:getType()
if bbtype == Blitbuffer.TYPE_BB8A or bbtype == Blitbuffer.TYPE_BBRGB32 then if bbtype == Blitbuffer.TYPE_BB8A or bbtype == Blitbuffer.TYPE_BBRGB32 then
-- NOTE: MuPDF feeds us premultiplied alpha (and we don't care w/ GifLib, as alpha is all or nothing). -- NOTE: MuPDF feeds us premultiplied alpha (and we don't care w/ GifLib, as alpha is all or nothing).
bb:pmulalphablitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h) if Screen.sw_dithering and not is_icon then
bb:ditherpmulalphablitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
else
bb:pmulalphablitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
end
else else
bb:blitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h) if Screen.sw_dithering and not is_icon then
bb:ditherblitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
else
bb:blitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
end
end end
else else
bb:blitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h) if Screen.sw_dithering and not is_icon then
bb:ditherblitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
else
bb:blitFrom(self._bb, x, y, self._offset_x, self._offset_y, size.w, size.h)
end
end end
if self.invert then if self.invert then
bb:invertRect(x, y, size.w, size.h) bb:invertRect(x, y, size.w, size.h)
@ -375,9 +390,9 @@ function ImageWidget:paintTo(bb, x, y)
end end
-- If in night mode, invert all rendered images, so the original is -- If in night mode, invert all rendered images, so the original is
-- displayed when the whole screen is inverted by night mode. -- displayed when the whole screen is inverted by night mode.
-- Except for our black & white icon files, that we want inverted -- Except for our black & white icon files, that we do want inverted
-- in night mode. -- in night mode.
if not self.file and G_reader_settings:isTrue("night_mode") then if Screen.night_mode and not is_icon then
bb:invertRect(x, y, size.w, size.h) bb:invertRect(x, y, size.w, size.h)
end end
end end

@ -782,4 +782,20 @@ function util.unpackArchive(archive, extract_to)
return true return true
end end
-- Simple startsWith / endsWith string helpers
-- c.f., http://lua-users.org/wiki/StringRecipes
-- @param str string: source string
-- @param start string: string to match
-- @return boolean: true on success
function util.stringStartsWith(str, start)
return str:sub(1, #start) == start
end
-- @param str string: source string
-- @param ending string: string to match
-- @return boolean: true on success
function util.stringEndsWith(str, ending)
return ending == "" or str:sub(-#ending) == ending
end
return util return util

@ -173,6 +173,16 @@ end
if G_reader_settings:isTrue("night_mode") then if G_reader_settings:isTrue("night_mode") then
Device.screen:toggleNightMode() Device.screen:toggleNightMode()
end end
-- dithering
if Device:hasEinkScreen() then
Device.screen:setupDithering()
if Device.screen.hw_dithering and G_reader_settings:isTrue("dev_no_hw_dither") then
Device.screen:toggleHWDithering()
end
if Device.screen.sw_dithering and G_reader_settings:isTrue("dev_no_sw_dither") then
Device.screen:toggleSWDithering()
end
end
if Device:needsTouchScreenProbe() then if Device:needsTouchScreenProbe() then
Device:touchScreenProbe() Device:touchScreenProbe()

Loading…
Cancel
Save