Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/thirdparty/tesseract/src/ccstruct/rect.cpp @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/thirdparty/tesseract/src/ccstruct/rect.cpp Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,277 @@ +/********************************************************************** + * File: rect.cpp (Formerly box.c) + * Description: Bounding box class definition. + * Author: Phil Cheatle + * + * (C) Copyright 1991, Hewlett-Packard Ltd. + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** http://www.apache.org/licenses/LICENSE-2.0 + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + * + **********************************************************************/ + +// Include automatically generated configuration file if running autoconf. +#ifdef HAVE_CONFIG_H +# include "config_auto.h" +#endif + +#include "rect.h" + +#include "serialis.h" // for TFile + +namespace tesseract { + +/********************************************************************** + * TBOX::TBOX() Constructor from 2 ICOORDS + * + **********************************************************************/ + +TBOX::TBOX( // constructor + const ICOORD pt1, // one corner + const ICOORD pt2 // the other corner +) { + if (pt1.x() <= pt2.x()) { + if (pt1.y() <= pt2.y()) { + bot_left = pt1; + top_right = pt2; + } else { + bot_left = ICOORD(pt1.x(), pt2.y()); + top_right = ICOORD(pt2.x(), pt1.y()); + } + } else { + if (pt1.y() <= pt2.y()) { + bot_left = ICOORD(pt2.x(), pt1.y()); + top_right = ICOORD(pt1.x(), pt2.y()); + } else { + bot_left = pt2; + top_right = pt1; + } + } +} + +bool TBOX::DeSerialize(TFile *f) { + return bot_left.DeSerialize(f) && top_right.DeSerialize(f); +} + +bool TBOX::Serialize(TFile *f) const { + return bot_left.Serialize(f) && top_right.Serialize(f); +} + +// rotate_large constructs the containing bounding box of all 4 +// corners after rotating them. It therefore guarantees that all +// original content is contained within, but also slightly enlarges the box. +void TBOX::rotate_large(const FCOORD &vec) { + ICOORD top_left(bot_left.x(), top_right.y()); + ICOORD bottom_right(top_right.x(), bot_left.y()); + top_left.rotate(vec); + bottom_right.rotate(vec); + rotate(vec); + TBOX box2(top_left, bottom_right); + *this += box2; +} + +/********************************************************************** + * TBOX::intersection() Build the largest box contained in both boxes + * + **********************************************************************/ + +TBOX TBOX::intersection( // shared area box + const TBOX &box) const { + TDimension left; + TDimension bottom; + TDimension right; + TDimension top; + if (overlap(box)) { + if (box.bot_left.x() > bot_left.x()) { + left = box.bot_left.x(); + } else { + left = bot_left.x(); + } + + if (box.top_right.x() < top_right.x()) { + right = box.top_right.x(); + } else { + right = top_right.x(); + } + + if (box.bot_left.y() > bot_left.y()) { + bottom = box.bot_left.y(); + } else { + bottom = bot_left.y(); + } + + if (box.top_right.y() < top_right.y()) { + top = box.top_right.y(); + } else { + top = top_right.y(); + } + } else { + left = INT16_MAX; + bottom = INT16_MAX; + top = -INT16_MAX; + right = -INT16_MAX; + } + return TBOX(left, bottom, right, top); +} + +/********************************************************************** + * TBOX::bounding_union() Build the smallest box containing both boxes + * + **********************************************************************/ + +TBOX TBOX::bounding_union( // box enclosing both + const TBOX &box) const { + ICOORD bl; // bottom left + ICOORD tr; // top right + + if (box.bot_left.x() < bot_left.x()) { + bl.set_x(box.bot_left.x()); + } else { + bl.set_x(bot_left.x()); + } + + if (box.top_right.x() > top_right.x()) { + tr.set_x(box.top_right.x()); + } else { + tr.set_x(top_right.x()); + } + + if (box.bot_left.y() < bot_left.y()) { + bl.set_y(box.bot_left.y()); + } else { + bl.set_y(bot_left.y()); + } + + if (box.top_right.y() > top_right.y()) { + tr.set_y(box.top_right.y()); + } else { + tr.set_y(top_right.y()); + } + return TBOX(bl, tr); +} + +/********************************************************************** + * TBOX::plot() Paint a box using specified settings + * + **********************************************************************/ + +#ifndef GRAPHICS_DISABLED +void TBOX::plot( // paint box + ScrollView *fd, // where to paint + ScrollView::Color fill_colour, // colour for inside + ScrollView::Color border_colour // colour for border + ) const { + fd->Brush(fill_colour); + fd->Pen(border_colour); + plot(fd); +} +#endif + +// Appends the bounding box as (%d,%d)->(%d,%d) to a string. +void TBOX::print_to_str(std::string &str) const { + // "(%d,%d)->(%d,%d)", left(), bottom(), right(), top() + str += "(" + std::to_string(left()); + str += "," + std::to_string(bottom()); + str += ")->(" + std::to_string(right()); + str += "," + std::to_string(top()); + str += ')'; +} + +// Writes to the given file. Returns false in case of error. +bool TBOX::Serialize(FILE *fp) const { + if (!bot_left.Serialize(fp)) { + return false; + } + if (!top_right.Serialize(fp)) { + return false; + } + return true; +} +// Reads from the given file. Returns false in case of error. +// If swap is true, assumes a big/little-endian swap is needed. +bool TBOX::DeSerialize(bool swap, FILE *fp) { + if (!bot_left.DeSerialize(swap, fp)) { + return false; + } + if (!top_right.DeSerialize(swap, fp)) { + return false; + } + return true; +} + +/********************************************************************** + * operator+= + * + * Extend one box to include the other (In place union) + **********************************************************************/ + +TBOX &operator+=( // bounding bounding bx + TBOX &op1, // operands + const TBOX &op2) { + if (op2.bot_left.x() < op1.bot_left.x()) { + op1.bot_left.set_x(op2.bot_left.x()); + } + + if (op2.top_right.x() > op1.top_right.x()) { + op1.top_right.set_x(op2.top_right.x()); + } + + if (op2.bot_left.y() < op1.bot_left.y()) { + op1.bot_left.set_y(op2.bot_left.y()); + } + + if (op2.top_right.y() > op1.top_right.y()) { + op1.top_right.set_y(op2.top_right.y()); + } + + return op1; +} + +/********************************************************************** + * operator&= + * + * Reduce one box to intersection with the other (In place intersection) + **********************************************************************/ + +TBOX &operator&=(TBOX &op1, const TBOX &op2) { + if (op1.overlap(op2)) { + if (op2.bot_left.x() > op1.bot_left.x()) { + op1.bot_left.set_x(op2.bot_left.x()); + } + + if (op2.top_right.x() < op1.top_right.x()) { + op1.top_right.set_x(op2.top_right.x()); + } + + if (op2.bot_left.y() > op1.bot_left.y()) { + op1.bot_left.set_y(op2.bot_left.y()); + } + + if (op2.top_right.y() < op1.top_right.y()) { + op1.top_right.set_y(op2.top_right.y()); + } + } else { + op1.bot_left.set_x(INT16_MAX); + op1.bot_left.set_y(INT16_MAX); + op1.top_right.set_x(-INT16_MAX); + op1.top_right.set_y(-INT16_MAX); + } + return op1; +} + +bool TBOX::x_almost_equal(const TBOX &box, int tolerance) const { + return (abs(left() - box.left()) <= tolerance && abs(right() - box.right()) <= tolerance); +} + +bool TBOX::almost_equal(const TBOX &box, int tolerance) const { + return (abs(left() - box.left()) <= tolerance && abs(right() - box.right()) <= tolerance && + abs(top() - box.top()) <= tolerance && abs(bottom() - box.bottom()) <= tolerance); +} + +} // namespace tesseract
