From 71cb2d3f93bbe00244cca9b2b49609ac5abc48e5 Mon Sep 17 00:00:00 2001 From: chrox Date: Sat, 30 Nov 2013 18:18:16 +0800 Subject: [PATCH] fix looking up wrong word in reflowed page that has a text layer underneath. For multi-column page reflowing usually fits individual column to page width and no finner word boxes are available to map reflowed word box onto native word box. Now the relative position of a reflowed word center is calculated as portion of the width and height of a larger block it belongs. This relative position is also considered in reflow-to-native position transform so that dictionary lookup now works on multi-column pages in reflowing mode. This should fix #376. --- frontend/document/koptinterface.lua | 54 ++++++++++++++++++++++------- koreader-base | 2 +- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/frontend/document/koptinterface.lua b/frontend/document/koptinterface.lua index 50bcf1ede..3ecf8b740 100644 --- a/frontend/document/koptinterface.lua +++ b/frontend/document/koptinterface.lua @@ -665,20 +665,40 @@ function KoptInterface:getWordFromPosition(doc, pos) end end +local function getBoxRelativePosition(s_box, l_box) + local pos_rel = {} + local s_box_center = s_box:center() + pos_rel.x = (s_box_center.x - l_box.x)/l_box.w + pos_rel.y = (s_box_center.y - l_box.y)/l_box.h + return pos_rel +end + --[[ get word and word box from position in reflowed page ]]-- function KoptInterface:getWordFromReflowPosition(doc, boxes, pos) local pageno = pos.page - local reflowed_page_boxes = self:getReflowedTextBoxesFromScratch(doc, pageno) + + local scratch_reflowed_page_boxes = self:getReflowedTextBoxesFromScratch(doc, pageno) + local scratch_reflowed_word_box = self:getWordFromBoxes(scratch_reflowed_page_boxes, pos) + --DEBUG("word box from scratch", scratch_reflowed_word_box) + + local reflowed_page_boxes = self:getReflowedTextBoxes(doc, pageno) local reflowed_word_box = self:getWordFromBoxes(reflowed_page_boxes, pos) - local reflowed_pos = reflowed_word_box.box:center() - local native_pos = self:reflowToNativePosTransform(doc, pageno, reflowed_pos) + --DEBUG("word box from reflow", reflowed_word_box) + + local reflowed_pos_abs = scratch_reflowed_word_box.box:center() + local reflowed_pos_rel = getBoxRelativePosition(scratch_reflowed_word_box.box, reflowed_word_box.box) + --DEBUG("word box absolote center", reflowed_pos_abs) + --DEBUG("word box relative center", reflowed_pos_rel) + + local native_pos = self:reflowToNativePosTransform(doc, pageno, reflowed_pos_abs, reflowed_pos_rel) local native_word_box = self:getWordFromBoxes(boxes, native_pos) + local word_box = { word = native_word_box.word, pbox = native_word_box.box, -- box on page - sbox = reflowed_word_box.box, -- box on screen + sbox = scratch_reflowed_word_box.box, -- box on screen pos = native_pos, } return word_box @@ -716,7 +736,7 @@ end --[[ transform position in reflowed page to native page ]]-- -function KoptInterface:reflowToNativePosTransform(doc, pageno, pos) +function KoptInterface:reflowToNativePosTransform(doc, pageno, abs_pos, rel_pos) local bbox = doc:getPageBBox(pageno) local context_hash = self:getContextHash(doc, pageno, bbox) local kctx_hash = "kctx|"..context_hash @@ -725,7 +745,7 @@ function KoptInterface:reflowToNativePosTransform(doc, pageno, pos) --kc:setDebug() --DEBUG("transform reflowed pos", pos) local npos = {} - npos.x, npos.y = kc:reflowToNativePosTransform(pos.x, pos.y) + npos.x, npos.y = kc:reflowToNativePosTransform(abs_pos.x, abs_pos.y, rel_pos.x, rel_pos.y) --DEBUG("transformed native pos", npos) return npos end @@ -749,14 +769,22 @@ get text and text boxes from screen positions for reflowed page ]]-- function KoptInterface:getTextFromReflowPositions(doc, native_boxes, pos0, pos1) local pageno = pos0.page - local reflowed_page_boxes = self:getReflowedTextBoxesFromScratch(doc, pageno) - local reflowed_box0 = self:getWordFromBoxes(reflowed_page_boxes, pos0) - local reflowed_pos0 = reflowed_box0.box:center() - local native_pos0 = self:reflowToNativePosTransform(doc, pageno, reflowed_pos0) - local reflowed_box1 = self:getWordFromBoxes(reflowed_page_boxes, pos1) - local reflowed_pos1 = reflowed_box1.box:center() - local native_pos1 = self:reflowToNativePosTransform(doc, pageno, reflowed_pos1) + local scratch_reflowed_page_boxes = self:getReflowedTextBoxesFromScratch(doc, pageno) + local reflowed_page_boxes = self:getReflowedTextBoxes(doc, pageno) + + local scratch_reflowed_word_box0 = self:getWordFromBoxes(scratch_reflowed_page_boxes, pos0) + local reflowed_word_box0 = self:getWordFromBoxes(reflowed_page_boxes, pos0) + local scratch_reflowed_word_box1 = self:getWordFromBoxes(scratch_reflowed_page_boxes, pos1) + local reflowed_word_box1 = self:getWordFromBoxes(reflowed_page_boxes, pos1) + + local reflowed_pos_abs0 = scratch_reflowed_word_box0.box:center() + local reflowed_pos_rel0 = getBoxRelativePosition(scratch_reflowed_word_box0.box, reflowed_word_box0.box) + local reflowed_pos_abs1 = scratch_reflowed_word_box1.box:center() + local reflowed_pos_rel1 = getBoxRelativePosition(scratch_reflowed_word_box1.box, reflowed_word_box1.box) + + local native_pos0 = self:reflowToNativePosTransform(doc, pageno, reflowed_pos_abs0, reflowed_pos_rel0) + local native_pos1 = self:reflowToNativePosTransform(doc, pageno, reflowed_pos_abs1, reflowed_pos_rel1) local reflowed_text_boxes = self:getTextFromBoxes(reflowed_page_boxes, pos0, pos1) local native_text_boxes = self:getTextFromBoxes(native_boxes, pos0, pos1) diff --git a/koreader-base b/koreader-base index 2ec1e66a2..730c13093 160000 --- a/koreader-base +++ b/koreader-base @@ -1 +1 @@ -Subproject commit 2ec1e66a21ce6b32435845f9f4f8e5184af2e0a4 +Subproject commit 730c130930e758b3d838687ad03ba9607731d655