Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/tesseract/src/ccstruct/points.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: points.cpp (Formerly coords.c) | |
| 3 * Description: Member functions for coordinate classes. | |
| 4 * Author: Ray Smith | |
| 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 #define _USE_MATH_DEFINES // for M_PI | |
| 20 | |
| 21 #include "points.h" | |
| 22 | |
| 23 #include "helpers.h" | |
| 24 #include "serialis.h" | |
| 25 | |
| 26 #include <algorithm> | |
| 27 #include <cmath> // for M_PI | |
| 28 #include <cstdlib> | |
| 29 | |
| 30 namespace tesseract { | |
| 31 | |
| 32 bool FCOORD::normalise() { // Convert to unit vec | |
| 33 float len = length(); | |
| 34 | |
| 35 if (len < 0.0000000001) { | |
| 36 return false; | |
| 37 } | |
| 38 xcoord /= len; | |
| 39 ycoord /= len; | |
| 40 return true; | |
| 41 } | |
| 42 | |
| 43 bool ICOORD::DeSerialize(TFile *f) { | |
| 44 return f->DeSerialize(&xcoord) && f->DeSerialize(&ycoord); | |
| 45 } | |
| 46 | |
| 47 bool ICOORD::Serialize(TFile *f) const { | |
| 48 return f->Serialize(&xcoord) && f->Serialize(&ycoord); | |
| 49 } | |
| 50 | |
| 51 // Set from the given x,y, shrinking the vector to fit if needed. | |
| 52 void ICOORD::set_with_shrink(int x, int y) { | |
| 53 // Fit the vector into an ICOORD, which is 16 bit. | |
| 54 int factor = 1; | |
| 55 int max_extent = std::max(abs(x), abs(y)); | |
| 56 if (max_extent > INT16_MAX) { | |
| 57 factor = max_extent / INT16_MAX + 1; | |
| 58 } | |
| 59 xcoord = x / factor; | |
| 60 ycoord = y / factor; | |
| 61 } | |
| 62 | |
| 63 // The fortran/basic sgn function returns -1, 0, 1 if x < 0, x == 0, x > 0 | |
| 64 // respectively. | |
| 65 static int sign(int x) { | |
| 66 if (x < 0) { | |
| 67 return -1; | |
| 68 } else { | |
| 69 return x > 0 ? 1 : 0; | |
| 70 } | |
| 71 } | |
| 72 | |
| 73 // Writes to the given file. Returns false in case of error. | |
| 74 bool ICOORD::Serialize(FILE *fp) const { | |
| 75 return tesseract::Serialize(fp, &xcoord) && tesseract::Serialize(fp, &ycoord); | |
| 76 } | |
| 77 // Reads from the given file. Returns false in case of error. | |
| 78 // If swap is true, assumes a big/little-endian swap is needed. | |
| 79 bool ICOORD::DeSerialize(bool swap, FILE *fp) { | |
| 80 if (!tesseract::DeSerialize(fp, &xcoord)) { | |
| 81 return false; | |
| 82 } | |
| 83 if (!tesseract::DeSerialize(fp, &ycoord)) { | |
| 84 return false; | |
| 85 } | |
| 86 if (swap) { | |
| 87 ReverseN(&xcoord, sizeof(xcoord)); | |
| 88 ReverseN(&ycoord, sizeof(ycoord)); | |
| 89 } | |
| 90 return true; | |
| 91 } | |
| 92 | |
| 93 // Setup for iterating over the pixels in a vector by the well-known | |
| 94 // Bresenham rendering algorithm. | |
| 95 // Starting with major/2 in the accumulator, on each step add major_step, | |
| 96 // and then add minor to the accumulator. When the accumulator >= major | |
| 97 // subtract major and step a minor step. | |
| 98 | |
| 99 void ICOORD::setup_render(ICOORD *major_step, ICOORD *minor_step, int *major, int *minor) const { | |
| 100 int abs_x = abs(xcoord); | |
| 101 int abs_y = abs(ycoord); | |
| 102 if (abs_x >= abs_y) { | |
| 103 // X-direction is major. | |
| 104 major_step->xcoord = sign(xcoord); | |
| 105 major_step->ycoord = 0; | |
| 106 minor_step->xcoord = 0; | |
| 107 minor_step->ycoord = sign(ycoord); | |
| 108 *major = abs_x; | |
| 109 *minor = abs_y; | |
| 110 } else { | |
| 111 // Y-direction is major. | |
| 112 major_step->xcoord = 0; | |
| 113 major_step->ycoord = sign(ycoord); | |
| 114 minor_step->xcoord = sign(xcoord); | |
| 115 minor_step->ycoord = 0; | |
| 116 *major = abs_y; | |
| 117 *minor = abs_x; | |
| 118 } | |
| 119 } | |
| 120 | |
| 121 // Returns the standard feature direction corresponding to this. | |
| 122 // See binary_angle_plus_pi below for a description of the direction. | |
| 123 uint8_t FCOORD::to_direction() const { | |
| 124 return binary_angle_plus_pi(angle()); | |
| 125 } | |
| 126 // Sets this with a unit vector in the given standard feature direction. | |
| 127 void FCOORD::from_direction(uint8_t direction) { | |
| 128 double radians = angle_from_direction(direction); | |
| 129 xcoord = cos(radians); | |
| 130 ycoord = sin(radians); | |
| 131 } | |
| 132 | |
| 133 // Converts an angle in radians (from ICOORD::angle or FCOORD::angle) to a | |
| 134 // standard feature direction as an unsigned angle in 256ths of a circle | |
| 135 // measured anticlockwise from (-1, 0). | |
| 136 uint8_t FCOORD::binary_angle_plus_pi(double radians) { | |
| 137 return Modulo(IntCastRounded((radians + M_PI) * 128.0 / M_PI), 256); | |
| 138 } | |
| 139 // Inverse of binary_angle_plus_pi returns an angle in radians for the | |
| 140 // given standard feature direction. | |
| 141 double FCOORD::angle_from_direction(uint8_t direction) { | |
| 142 return direction * M_PI / 128.0 - M_PI; | |
| 143 } | |
| 144 | |
| 145 // Returns the point on the given line nearest to this, ie the point such | |
| 146 // that the vector point->this is perpendicular to the line. | |
| 147 // The line is defined as a line_point and a dir_vector for its direction. | |
| 148 FCOORD FCOORD::nearest_pt_on_line(const FCOORD &line_point, const FCOORD &dir_vector) const { | |
| 149 FCOORD point_vector(*this - line_point); | |
| 150 // The dot product (%) is |dir_vector||point_vector|cos theta, so dividing by | |
| 151 // the square of the length of dir_vector gives us the fraction of dir_vector | |
| 152 // to add to line1 to get the appropriate point, so | |
| 153 // result = line1 + lambda dir_vector. | |
| 154 double lambda = point_vector % dir_vector / dir_vector.sqlength(); | |
| 155 return line_point + (dir_vector * lambda); | |
| 156 } | |
| 157 | |
| 158 } // namespace tesseract |
