Mercurial > hgrepos > Python2 > PyMuPDF
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /********************************************************************** | |
| 2 * File: rect.cpp (Formerly box.c) | |
| 3 * Description: Bounding box class definition. | |
| 4 * Author: Phil Cheatle | |
| 5 * | |
| 6 * (C) Copyright 1991, Hewlett-Packard Ltd. | |
| 7 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
| 8 ** you may not use this file except in compliance with the License. | |
| 9 ** You may obtain a copy of the License at | |
| 10 ** http://www.apache.org/licenses/LICENSE-2.0 | |
| 11 ** Unless required by applicable law or agreed to in writing, software | |
| 12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 ** See the License for the specific language governing permissions and | |
| 15 ** limitations under the License. | |
| 16 * | |
| 17 **********************************************************************/ | |
| 18 | |
| 19 // Include automatically generated configuration file if running autoconf. | |
| 20 #ifdef HAVE_CONFIG_H | |
| 21 # include "config_auto.h" | |
| 22 #endif | |
| 23 | |
| 24 #include "rect.h" | |
| 25 | |
| 26 #include "serialis.h" // for TFile | |
| 27 | |
| 28 namespace tesseract { | |
| 29 | |
| 30 /********************************************************************** | |
| 31 * TBOX::TBOX() Constructor from 2 ICOORDS | |
| 32 * | |
| 33 **********************************************************************/ | |
| 34 | |
| 35 TBOX::TBOX( // constructor | |
| 36 const ICOORD pt1, // one corner | |
| 37 const ICOORD pt2 // the other corner | |
| 38 ) { | |
| 39 if (pt1.x() <= pt2.x()) { | |
| 40 if (pt1.y() <= pt2.y()) { | |
| 41 bot_left = pt1; | |
| 42 top_right = pt2; | |
| 43 } else { | |
| 44 bot_left = ICOORD(pt1.x(), pt2.y()); | |
| 45 top_right = ICOORD(pt2.x(), pt1.y()); | |
| 46 } | |
| 47 } else { | |
| 48 if (pt1.y() <= pt2.y()) { | |
| 49 bot_left = ICOORD(pt2.x(), pt1.y()); | |
| 50 top_right = ICOORD(pt1.x(), pt2.y()); | |
| 51 } else { | |
| 52 bot_left = pt2; | |
| 53 top_right = pt1; | |
| 54 } | |
| 55 } | |
| 56 } | |
| 57 | |
| 58 bool TBOX::DeSerialize(TFile *f) { | |
| 59 return bot_left.DeSerialize(f) && top_right.DeSerialize(f); | |
| 60 } | |
| 61 | |
| 62 bool TBOX::Serialize(TFile *f) const { | |
| 63 return bot_left.Serialize(f) && top_right.Serialize(f); | |
| 64 } | |
| 65 | |
| 66 // rotate_large constructs the containing bounding box of all 4 | |
| 67 // corners after rotating them. It therefore guarantees that all | |
| 68 // original content is contained within, but also slightly enlarges the box. | |
| 69 void TBOX::rotate_large(const FCOORD &vec) { | |
| 70 ICOORD top_left(bot_left.x(), top_right.y()); | |
| 71 ICOORD bottom_right(top_right.x(), bot_left.y()); | |
| 72 top_left.rotate(vec); | |
| 73 bottom_right.rotate(vec); | |
| 74 rotate(vec); | |
| 75 TBOX box2(top_left, bottom_right); | |
| 76 *this += box2; | |
| 77 } | |
| 78 | |
| 79 /********************************************************************** | |
| 80 * TBOX::intersection() Build the largest box contained in both boxes | |
| 81 * | |
| 82 **********************************************************************/ | |
| 83 | |
| 84 TBOX TBOX::intersection( // shared area box | |
| 85 const TBOX &box) const { | |
| 86 TDimension left; | |
| 87 TDimension bottom; | |
| 88 TDimension right; | |
| 89 TDimension top; | |
| 90 if (overlap(box)) { | |
| 91 if (box.bot_left.x() > bot_left.x()) { | |
| 92 left = box.bot_left.x(); | |
| 93 } else { | |
| 94 left = bot_left.x(); | |
| 95 } | |
| 96 | |
| 97 if (box.top_right.x() < top_right.x()) { | |
| 98 right = box.top_right.x(); | |
| 99 } else { | |
| 100 right = top_right.x(); | |
| 101 } | |
| 102 | |
| 103 if (box.bot_left.y() > bot_left.y()) { | |
| 104 bottom = box.bot_left.y(); | |
| 105 } else { | |
| 106 bottom = bot_left.y(); | |
| 107 } | |
| 108 | |
| 109 if (box.top_right.y() < top_right.y()) { | |
| 110 top = box.top_right.y(); | |
| 111 } else { | |
| 112 top = top_right.y(); | |
| 113 } | |
| 114 } else { | |
| 115 left = INT16_MAX; | |
| 116 bottom = INT16_MAX; | |
| 117 top = -INT16_MAX; | |
| 118 right = -INT16_MAX; | |
| 119 } | |
| 120 return TBOX(left, bottom, right, top); | |
| 121 } | |
| 122 | |
| 123 /********************************************************************** | |
| 124 * TBOX::bounding_union() Build the smallest box containing both boxes | |
| 125 * | |
| 126 **********************************************************************/ | |
| 127 | |
| 128 TBOX TBOX::bounding_union( // box enclosing both | |
| 129 const TBOX &box) const { | |
| 130 ICOORD bl; // bottom left | |
| 131 ICOORD tr; // top right | |
| 132 | |
| 133 if (box.bot_left.x() < bot_left.x()) { | |
| 134 bl.set_x(box.bot_left.x()); | |
| 135 } else { | |
| 136 bl.set_x(bot_left.x()); | |
| 137 } | |
| 138 | |
| 139 if (box.top_right.x() > top_right.x()) { | |
| 140 tr.set_x(box.top_right.x()); | |
| 141 } else { | |
| 142 tr.set_x(top_right.x()); | |
| 143 } | |
| 144 | |
| 145 if (box.bot_left.y() < bot_left.y()) { | |
| 146 bl.set_y(box.bot_left.y()); | |
| 147 } else { | |
| 148 bl.set_y(bot_left.y()); | |
| 149 } | |
| 150 | |
| 151 if (box.top_right.y() > top_right.y()) { | |
| 152 tr.set_y(box.top_right.y()); | |
| 153 } else { | |
| 154 tr.set_y(top_right.y()); | |
| 155 } | |
| 156 return TBOX(bl, tr); | |
| 157 } | |
| 158 | |
| 159 /********************************************************************** | |
| 160 * TBOX::plot() Paint a box using specified settings | |
| 161 * | |
| 162 **********************************************************************/ | |
| 163 | |
| 164 #ifndef GRAPHICS_DISABLED | |
| 165 void TBOX::plot( // paint box | |
| 166 ScrollView *fd, // where to paint | |
| 167 ScrollView::Color fill_colour, // colour for inside | |
| 168 ScrollView::Color border_colour // colour for border | |
| 169 ) const { | |
| 170 fd->Brush(fill_colour); | |
| 171 fd->Pen(border_colour); | |
| 172 plot(fd); | |
| 173 } | |
| 174 #endif | |
| 175 | |
| 176 // Appends the bounding box as (%d,%d)->(%d,%d) to a string. | |
| 177 void TBOX::print_to_str(std::string &str) const { | |
| 178 // "(%d,%d)->(%d,%d)", left(), bottom(), right(), top() | |
| 179 str += "(" + std::to_string(left()); | |
| 180 str += "," + std::to_string(bottom()); | |
| 181 str += ")->(" + std::to_string(right()); | |
| 182 str += "," + std::to_string(top()); | |
| 183 str += ')'; | |
| 184 } | |
| 185 | |
| 186 // Writes to the given file. Returns false in case of error. | |
| 187 bool TBOX::Serialize(FILE *fp) const { | |
| 188 if (!bot_left.Serialize(fp)) { | |
| 189 return false; | |
| 190 } | |
| 191 if (!top_right.Serialize(fp)) { | |
| 192 return false; | |
| 193 } | |
| 194 return true; | |
| 195 } | |
| 196 // Reads from the given file. Returns false in case of error. | |
| 197 // If swap is true, assumes a big/little-endian swap is needed. | |
| 198 bool TBOX::DeSerialize(bool swap, FILE *fp) { | |
| 199 if (!bot_left.DeSerialize(swap, fp)) { | |
| 200 return false; | |
| 201 } | |
| 202 if (!top_right.DeSerialize(swap, fp)) { | |
| 203 return false; | |
| 204 } | |
| 205 return true; | |
| 206 } | |
| 207 | |
| 208 /********************************************************************** | |
| 209 * operator+= | |
| 210 * | |
| 211 * Extend one box to include the other (In place union) | |
| 212 **********************************************************************/ | |
| 213 | |
| 214 TBOX &operator+=( // bounding bounding bx | |
| 215 TBOX &op1, // operands | |
| 216 const TBOX &op2) { | |
| 217 if (op2.bot_left.x() < op1.bot_left.x()) { | |
| 218 op1.bot_left.set_x(op2.bot_left.x()); | |
| 219 } | |
| 220 | |
| 221 if (op2.top_right.x() > op1.top_right.x()) { | |
| 222 op1.top_right.set_x(op2.top_right.x()); | |
| 223 } | |
| 224 | |
| 225 if (op2.bot_left.y() < op1.bot_left.y()) { | |
| 226 op1.bot_left.set_y(op2.bot_left.y()); | |
| 227 } | |
| 228 | |
| 229 if (op2.top_right.y() > op1.top_right.y()) { | |
| 230 op1.top_right.set_y(op2.top_right.y()); | |
| 231 } | |
| 232 | |
| 233 return op1; | |
| 234 } | |
| 235 | |
| 236 /********************************************************************** | |
| 237 * operator&= | |
| 238 * | |
| 239 * Reduce one box to intersection with the other (In place intersection) | |
| 240 **********************************************************************/ | |
| 241 | |
| 242 TBOX &operator&=(TBOX &op1, const TBOX &op2) { | |
| 243 if (op1.overlap(op2)) { | |
| 244 if (op2.bot_left.x() > op1.bot_left.x()) { | |
| 245 op1.bot_left.set_x(op2.bot_left.x()); | |
| 246 } | |
| 247 | |
| 248 if (op2.top_right.x() < op1.top_right.x()) { | |
| 249 op1.top_right.set_x(op2.top_right.x()); | |
| 250 } | |
| 251 | |
| 252 if (op2.bot_left.y() > op1.bot_left.y()) { | |
| 253 op1.bot_left.set_y(op2.bot_left.y()); | |
| 254 } | |
| 255 | |
| 256 if (op2.top_right.y() < op1.top_right.y()) { | |
| 257 op1.top_right.set_y(op2.top_right.y()); | |
| 258 } | |
| 259 } else { | |
| 260 op1.bot_left.set_x(INT16_MAX); | |
| 261 op1.bot_left.set_y(INT16_MAX); | |
| 262 op1.top_right.set_x(-INT16_MAX); | |
| 263 op1.top_right.set_y(-INT16_MAX); | |
| 264 } | |
| 265 return op1; | |
| 266 } | |
| 267 | |
| 268 bool TBOX::x_almost_equal(const TBOX &box, int tolerance) const { | |
| 269 return (abs(left() - box.left()) <= tolerance && abs(right() - box.right()) <= tolerance); | |
| 270 } | |
| 271 | |
| 272 bool TBOX::almost_equal(const TBOX &box, int tolerance) const { | |
| 273 return (abs(left() - box.left()) <= tolerance && abs(right() - box.right()) <= tolerance && | |
| 274 abs(top() - box.top()) <= tolerance && abs(bottom() - box.bottom()) <= tolerance); | |
| 275 } | |
| 276 | |
| 277 } // namespace tesseract |
