mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
geom: supplement :combine with more generic .boundingBox
It is a bit cleaner to do all of the necessary looping over lists of Geoms within a straight-forward Geom.boundingBox function rather than looping over :combine every time (or reimplementing :combine in some cases). Geom:combine can be trivially reimplemented in terms of Geom.boundingBox as well. Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
This commit is contained in:
committed by
Frans de Jonge
parent
6f1b70e5eb
commit
a29d24f86d
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user