diff --git a/frontend/apps/reader/modules/readersearch.lua b/frontend/apps/reader/modules/readersearch.lua index 5ee8ed751..49bb2949d 100644 --- a/frontend/apps/reader/modules/readersearch.lua +++ b/frontend/apps/reader/modules/readersearch.lua @@ -7,6 +7,7 @@ local InputDialog = require("ui/widget/inputdialog") local Menu = require("ui/widget/menu") local Notification = require("ui/widget/notification") local SpinWidget = require("ui/widget/spinwidget") +local TextBoxWidget = require("ui/widget/textboxwidget") local UIManager = require("ui/uimanager") local Utf8Proc = require("ffi/utf8proc") local WidgetContainer = require("ui/widget/container/widgetcontainer") @@ -525,14 +526,17 @@ function ReaderSearch:showFindAllResults(not_cached) if item.matched_word_suffix then word = word .. item.matched_word_suffix end + -- Make this word bolder, using Poor Text Formatting provided by TextBoxWidget + -- (we know this text ends up in a TextBoxWidget). + local text = TextBoxWidget.PTF_BOLD_START .. word .. TextBoxWidget.PTF_BOLD_END -- append context before and after the word - local text = "【" .. word .. "】" if item.prev_text then text = item.prev_text .. text end if item.next_text then text = text .. item.next_text end + text = TextBoxWidget.PTF_HEADER .. text -- enable handling of our bold tags item.text = text item.mandatory = self.ui.bookmark:getBookmarkPageString(item.start) end diff --git a/frontend/document/koptinterface.lua b/frontend/document/koptinterface.lua index b5191a803..9481d0163 100644 --- a/frontend/document/koptinterface.lua +++ b/frontend/document/koptinterface.lua @@ -12,6 +12,7 @@ local FFIUtil = require("ffi/util") local Geom = require("ui/geometry") local KOPTContext = require("ffi/koptcontext") local Persist = require("persist") +local TextBoxWidget = require("ui/widget/textboxwidget") local TileCacheItem = require("document/tilecacheitem") local Utf8Proc = require("ffi/utf8proc") local logger = require("logger") @@ -1510,15 +1511,18 @@ function KoptInterface:findAllText(doc, pattern, case_insensitive, nb_context_wo i_next, j_next = i, j end end - text = "【" .. table.concat(text, " ") .. "】" + -- Make this word bolder, using Poor Text Formatting provided by TextBoxWidget + -- (we know this text ends up in a TextBoxWidget). + text = TextBoxWidget.PTF_BOLD_START .. table.concat(text, " ") .. TextBoxWidget.PTF_BOLD_END local prev_text = get_prev_text(text_boxes, i_prev, j_prev, nb_context_words) if prev_text then - text = prev_text .. text + text = prev_text .. " " .. text end local next_text = get_next_text(text_boxes, i_next, j_next, nb_context_words) if next_text then - text = text .. next_text + text = text .. " " .. next_text end + text = TextBoxWidget.PTF_HEADER .. text -- enable handling of our bold tags res_item.text = text table.insert(res, res_item) if #res == max_hits then diff --git a/frontend/ui/rendertext.lua b/frontend/ui/rendertext.lua index a2801528f..24b1ca688 100644 --- a/frontend/ui/rendertext.lua +++ b/frontend/ui/rendertext.lua @@ -289,17 +289,25 @@ end -- @int glyph index -- @bool[opt=false] bold whether the glyph should be artificially boldened -- @treturn glyph -function RenderText:getGlyphByIndex(face, glyphindex, bold) +function RenderText:getGlyphByIndex(face, glyphindex, bold, bolder) if face.is_real_bold then bold = false -- don't embolden glyphs already bold end - local hash = "xglyph|"..face.hash.."|"..glyphindex.."|"..(bold and 1 or 0) + local hash = "xglyph|"..face.hash.."|"..glyphindex.."|"..(bold and 1 or 0)..(bolder and "x" or "") local glyph = GlyphCache:check(hash) if glyph then -- cache hit return glyph end - local rendered_glyph = face.ftsize:renderGlyphByIndex(glyphindex, bold and face.embolden_half_strength) + local embolden_strength + if bold or bolder then + embolden_strength = face.embolden_half_strength + if bolder then + -- Even if not bold, get it bolder than the strength we'd use for bold + embolden_strength = embolden_strength * 1.5 + end + end + local rendered_glyph = face.ftsize:renderGlyphByIndex(glyphindex, embolden_strength) if not rendered_glyph then logger.warn("error rendering glyph (glyphindex=", glyphindex, ") for face", face) return diff --git a/frontend/ui/widget/textboxwidget.lua b/frontend/ui/widget/textboxwidget.lua index fe60f4c80..d46234276 100644 --- a/frontend/ui/widget/textboxwidget.lua +++ b/frontend/ui/widget/textboxwidget.lua @@ -110,6 +110,17 @@ local TextBoxWidget = InputContainer:extend{ -- for internal use for_measurement_only = nil, -- When the widget is a one-off used to compute text height + + -- Some Poor Text Formatting (PTF, not not to be confused with Richer RTF :)) can be done + -- by embedding some chars in self.text (these codepoints are not part of Unicode, so + -- hopefully not present naturally in any provided self.text). + PTF_HEADER = "\u{FFF1}", -- should be put at start of 'text' to indicate we may find other PTF_ chars + PTF_BOLD_START = "\u{FFF2}", -- start a sequence of bold chars + PTF_BOLD_END = "\u{FFF3}", -- end a sequence of bold chars + _ptf_char_is_bold = nil, + -- This uses fake/synthetic bold, making each glyph bolder without modifying advance. + -- Some other possible formatting we could implement is different alignment (center, + -- right) of some lines in the provided text. } function TextBoxWidget:init() @@ -154,6 +165,41 @@ function TextBoxWidget:init() self.text_height = self.lines_per_page * self.line_height_px end + -- Check for Poor Text Formatting + if not self.charlist and self.text and type(self.text) == "string" + and self.text:sub(1, #TextBoxWidget.PTF_HEADER) == TextBoxWidget.PTF_HEADER then + -- Support for very simple text styling (bold only for now) + self._ptf_char_is_bold = {} + -- Alas, we can't let any of our flag characters be fed to xtext (even with ASCII control + -- chars, it would give them a width, which would result at best in spurious added spacing). + -- So, split text into a table of chars, filter our flags out keeping track of where they + -- start and end bold, and rebuild self.text without them. + local charlist = util.splitToChars(self.text) + table.remove(charlist, 1) + local is_bold = false + local len = #charlist + local i = 1 + while i <= len do + local ch = charlist[i] + if ch == TextBoxWidget.PTF_BOLD_START then + is_bold = true + table.remove(charlist, i) + len = len - 1 + elseif ch == TextBoxWidget.PTF_BOLD_END then + is_bold = false + table.remove(charlist, i) + len = len - 1 + else + if is_bold then + self._ptf_char_is_bold[i] = true + end + i = i + 1 + end + end + self.text = table.concat(charlist, "") + charlist = nil -- luacheck: no unused + end + self:_computeTextDimensions() self:_updateLayout() if self.editable then @@ -822,7 +868,8 @@ function TextBoxWidget:_renderText(start_row_idx, end_row_idx) for _, xglyph in ipairs(line.xglyphs) do if not xglyph.no_drawing then local face = self.face.getFallbackFont(xglyph.font_num) -- callback (not a method) - local glyph = RenderText:getGlyphByIndex(face, xglyph.glyph, self.bold) + local bolder = self._ptf_char_is_bold and self._ptf_char_is_bold[xglyph.text_index] or false + local glyph = RenderText:getGlyphByIndex(face, xglyph.glyph, self.bold, bolder) local color = self.fgcolor if self._alt_color_for_rtl then color = xglyph.is_rtl and Blitbuffer.COLOR_DARK_GRAY or Blitbuffer.COLOR_BLACK