diff --git a/frontend/document/credocument.lua b/frontend/document/credocument.lua index 0fdf8196b..24d39315e 100644 --- a/frontend/document/credocument.lua +++ b/frontend/document/credocument.lua @@ -561,25 +561,14 @@ function CreDocument:getWordFromPosition(pos) if text_range.pos0 and text_range.pos1 then -- get segments from these pos, to build the overall box local word_boxes = self._document:getWordBoxesFromPositions(text_range.pos0, text_range.pos1, true) - if #word_boxes > 0 then - local overall_box - for i = 1, #word_boxes do - local line_box = word_boxes[i] - if not overall_box then - overall_box = line_box - else - if line_box.x0 < overall_box.x0 then overall_box.x0 = line_box.x0 end - if line_box.y0 < overall_box.y0 then overall_box.y0 = line_box.y0 end - if line_box.x1 > overall_box.x1 then overall_box.x1 = line_box.x1 end - if line_box.y1 > overall_box.y1 then overall_box.y1 = line_box.y1 end - end - end - wordbox.sbox = Geom:new{ - x = overall_box.x0, - y = overall_box.y0, - w = overall_box.x1 - overall_box.x0, - h = overall_box.y1 - overall_box.y0, - } + -- convert to Geom so we can use Geom.boundingBox + for i=1, #word_boxes do + local v = word_boxes[i] + word_boxes[i] = { x = v.x0, y = v.y0, + w = v.x1 - v.x0, h = v.y1 - v.y0 } + end + wordbox.sbox = Geom.boundingBox(word_boxes) + if wordbox.sbox then box_found = true end end diff --git a/frontend/document/koptinterface.lua b/frontend/document/koptinterface.lua index c3a3b64bd..c178d05eb 100644 --- a/frontend/document/koptinterface.lua +++ b/frontend/document/koptinterface.lua @@ -789,14 +789,7 @@ function KoptInterface:getClipPageContext(doc, pos0, pos1, pboxes, drawer) assert(pos0.zoom == pos1.zoom) local rect if pboxes and #pboxes > 0 then - local box = pboxes[1] - rect = Geom:new{ - x = box.x, y = box.y, - w = box.w, h = box.h, - } - for _, _box in ipairs(pboxes) do - rect = rect:combine(Geom:new(_box)) - end + rect = Geom.boundingBox(pboxes) else local zoom = pos0.zoom or 1 rect = { @@ -1241,14 +1234,9 @@ function KoptInterface:nativeToPageRectTransform(doc, pageno, rect) y = rect.y + rect.h - 5 } local boxes = self:getPageBoxesFromPositions(doc, pageno, pos0, pos1) - local res_rect = nil - if #boxes > 0 then - res_rect = boxes[1] - for _, box in pairs(boxes) do - res_rect = res_rect:combine(box) - end + if boxes then + return Geom.boundingBox(boxes) end - return res_rect else return rect end diff --git a/frontend/ui/geometry.lua b/frontend/ui/geometry.lua index d6e929c26..94c4dbf4f 100644 --- a/frontend/ui/geometry.lua +++ b/frontend/ui/geometry.lua @@ -144,27 +144,7 @@ Works for rectangles, dimensions and points @treturn Geom ]] function Geom:combine(rect_b) - -- We'll want to return a *new* object, so, start with a copy of self - local combined = self:copy() - if not rect_b or rect_b:area() == 0 then return combined end - - if combined.x > rect_b.x then - combined.x = rect_b.x - end - if combined.y > rect_b.y then - combined.y = rect_b.y - end - if self.x + self.w > rect_b.x + rect_b.w then - combined.w = self.x + self.w - combined.x - else - combined.w = rect_b.x + rect_b.w - combined.x - end - if self.y + self.h > rect_b.y + rect_b.h then - combined.h = self.y + self.h - combined.y - else - combined.h = rect_b.y + rect_b.h - combined.y - end - return combined + return Geom.boundingBox({self, rect_b}) end --[[-- @@ -439,4 +419,34 @@ function Geom:isEmpty() return false end +--[[-- +Returns a bounding box which encompasses all passed rectangles. +@tparam Geom rectangles to encompass +@treturn Geom bounding box or nil if no rectangles passed +]] +function Geom.boundingBox(boxes) + local bounding_box + for _, geom in ipairs(boxes) do + -- Easier to work with (x0,x0)+(x1,y1) pairs. + local box = { x0 = geom.x, y0 = geom.y, + x1 = geom.x + geom.w, y1 = geom.y + geom.h } + if not bounding_box then + bounding_box = box + else + if box.x0 < bounding_box.x0 then bounding_box.x0 = box.x0 end + if box.y0 < bounding_box.y0 then bounding_box.y0 = box.y0 end + if box.x1 > bounding_box.x1 then bounding_box.x1 = box.x1 end + if box.y1 > bounding_box.y1 then bounding_box.y1 = box.y1 end + end + end + if bounding_box then + return Geom:new{ + x = bounding_box.x0, + y = bounding_box.y0, + w = bounding_box.x1 - bounding_box.x0, + h = bounding_box.y1 - bounding_box.y0, + } + end +end + return Geom