comparison mupdf-source/thirdparty/tesseract/src/ccstruct/points.h @ 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.h (Formerly coords.h)
3 * Description: Coordinate class definitions.
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 #ifndef POINTS_H
20 #define POINTS_H
21
22 #include "elst.h"
23 #include "errcode.h" // for ASSERT_HOST
24 #include "tesstypes.h" // for TDimension
25
26 #include <tesseract/export.h> // for DLLSYM
27
28 #include <cmath> // for sqrt, atan2
29 #include <cstdio>
30
31 namespace tesseract {
32
33 class FCOORD;
34
35 /// integer coordinate
36 class ICOORD {
37 friend class FCOORD;
38
39 public:
40 /// empty constructor
41 ICOORD() {
42 xcoord = ycoord = 0; // default zero
43 }
44 /// constructor
45 ///@param xin x value
46 ///@param yin y value
47 ICOORD(TDimension xin, TDimension yin) {
48 xcoord = xin;
49 ycoord = yin;
50 }
51 /// destructor
52 ~ICOORD() = default;
53
54 bool DeSerialize(TFile *f);
55 bool Serialize(TFile *f) const;
56
57 /// access function
58 TDimension x() const {
59 return xcoord;
60 }
61 /// access_function
62 TDimension y() const {
63 return ycoord;
64 }
65
66 /// rewrite function
67 void set_x(TDimension xin) {
68 xcoord = xin; // write new value
69 }
70 /// rewrite function
71 void set_y(TDimension yin) { // value to set
72 ycoord = yin;
73 }
74
75 /// Set from the given x,y, shrinking the vector to fit if needed.
76 void set_with_shrink(int x, int y);
77
78 /// find sq length
79 float sqlength() const {
80 return static_cast<float>(xcoord * xcoord + ycoord * ycoord);
81 }
82
83 /// find length
84 float length() const {
85 return std::sqrt(sqlength());
86 }
87
88 /// sq dist between pts
89 float pt_to_pt_sqdist(const ICOORD &pt) const {
90 ICOORD gap;
91
92 gap.xcoord = xcoord - pt.xcoord;
93 gap.ycoord = ycoord - pt.ycoord;
94 return gap.sqlength();
95 }
96
97 /// Distance between pts
98 float pt_to_pt_dist(const ICOORD &pt) const {
99 return std::sqrt(pt_to_pt_sqdist(pt));
100 }
101
102 /// find angle
103 float angle() const {
104 return std::atan2(static_cast<float>(ycoord), static_cast<float>(xcoord));
105 }
106
107 /// test equality
108 bool operator==(const ICOORD &other) const {
109 return xcoord == other.xcoord && ycoord == other.ycoord;
110 }
111 /// test inequality
112 bool operator!=(const ICOORD &other) const {
113 return xcoord != other.xcoord || ycoord != other.ycoord;
114 }
115 /// rotate 90 deg anti
116 friend ICOORD operator!(const ICOORD &);
117 /// unary minus
118 friend ICOORD operator-(const ICOORD &);
119 /// add
120 friend ICOORD operator+(const ICOORD &, const ICOORD &);
121 /// add
122 friend ICOORD &operator+=(ICOORD &, const ICOORD &);
123 /// subtract
124 friend ICOORD operator-(const ICOORD &, const ICOORD &);
125 /// subtract
126 friend ICOORD &operator-=(ICOORD &, const ICOORD &);
127 /// scalar product
128 friend int32_t operator%(const ICOORD &, const ICOORD &);
129 /// cross product
130 friend int32_t operator*(const ICOORD &, const ICOORD &);
131 /// multiply
132 friend ICOORD operator*(const ICOORD &, TDimension);
133 /// multiply
134 friend ICOORD operator*(TDimension, const ICOORD &);
135 /// multiply
136 friend ICOORD &operator*=(ICOORD &, TDimension);
137 /// divide
138 friend ICOORD operator/(const ICOORD &, TDimension);
139 /// divide
140 friend ICOORD &operator/=(ICOORD &, TDimension);
141 /// rotate
142 ///@param vec by vector
143 void rotate(const FCOORD &vec);
144
145 /// Setup for iterating over the pixels in a vector by the well-known
146 /// Bresenham rendering algorithm.
147 /// Starting with major/2 in the accumulator, on each step move by
148 /// major_step, and then add minor to the accumulator. When
149 /// accumulator >= major subtract major and also move by minor_step.
150 void setup_render(ICOORD *major_step, ICOORD *minor_step, int *major, int *minor) const;
151
152 // Writes to the given file. Returns false in case of error.
153 bool Serialize(FILE *fp) const;
154 // Reads from the given file. Returns false in case of error.
155 // If swap is true, assumes a big/little-endian swap is needed.
156 bool DeSerialize(bool swap, FILE *fp);
157
158 protected:
159 TDimension xcoord; ///< x value
160 TDimension ycoord; ///< y value
161 };
162
163 class ICOORDELT : public ELIST_LINK,
164 public ICOORD
165 // embedded coord list
166 {
167 public:
168 /// empty constructor
169 ICOORDELT() = default;
170 /// constructor from ICOORD
171 ICOORDELT(ICOORD icoord) : ICOORD(icoord) {}
172 /// constructor
173 ///@param xin x value
174 ///@param yin y value
175 ICOORDELT(TDimension xin, TDimension yin) {
176 xcoord = xin;
177 ycoord = yin;
178 }
179
180 static ICOORDELT *deep_copy(const ICOORDELT *src) {
181 auto *elt = new ICOORDELT;
182 *elt = *src;
183 return elt;
184 }
185 };
186
187 ELISTIZEH(ICOORDELT)
188
189 class TESS_API FCOORD {
190 public:
191 /// empty constructor
192 FCOORD() = default;
193 /// constructor
194 ///@param xvalue x value
195 ///@param yvalue y value
196 FCOORD(float xvalue, float yvalue) {
197 xcoord = xvalue; // set coords
198 ycoord = yvalue;
199 }
200 FCOORD( // make from ICOORD
201 ICOORD icoord) { // coords to set
202 xcoord = icoord.xcoord;
203 ycoord = icoord.ycoord;
204 }
205
206 float x() const { // get coords
207 return xcoord;
208 }
209 float y() const {
210 return ycoord;
211 }
212 /// rewrite function
213 void set_x(float xin) {
214 xcoord = xin; // write new value
215 }
216 /// rewrite function
217 void set_y(float yin) { // value to set
218 ycoord = yin;
219 }
220
221 /// find sq length
222 float sqlength() const {
223 return xcoord * xcoord + ycoord * ycoord;
224 }
225
226 /// find length
227 float length() const {
228 return std::sqrt(sqlength());
229 }
230
231 /// sq dist between pts
232 float pt_to_pt_sqdist(const FCOORD &pt) const {
233 FCOORD gap;
234
235 gap.xcoord = xcoord - pt.xcoord;
236 gap.ycoord = ycoord - pt.ycoord;
237 return gap.sqlength();
238 }
239
240 /// Distance between pts
241 float pt_to_pt_dist(const FCOORD &pt) const {
242 return std::sqrt(pt_to_pt_sqdist(pt));
243 }
244
245 /// find angle
246 float angle() const {
247 return std::atan2(ycoord, xcoord);
248 }
249 // Returns the standard feature direction corresponding to this.
250 // See binary_angle_plus_pi below for a description of the direction.
251 uint8_t to_direction() const;
252 // Sets this with a unit vector in the given standard feature direction.
253 void from_direction(uint8_t direction);
254
255 // Converts an angle in radians (from ICOORD::angle or FCOORD::angle) to a
256 // standard feature direction as an unsigned angle in 256ths of a circle
257 // measured anticlockwise from (-1, 0).
258 static uint8_t binary_angle_plus_pi(double angle);
259 // Inverse of binary_angle_plus_pi returns an angle in radians for the
260 // given standard feature direction.
261 static double angle_from_direction(uint8_t direction);
262 // Returns the point on the given line nearest to this, ie the point such
263 // that the vector point->this is perpendicular to the line.
264 // The line is defined as a line_point and a dir_vector for its direction.
265 // dir_vector need not be a unit vector.
266 FCOORD nearest_pt_on_line(const FCOORD &line_point, const FCOORD &dir_vector) const;
267
268 /// Convert to unit vec
269 bool normalise();
270
271 /// test equality
272 bool operator==(const FCOORD &other) const {
273 return xcoord == other.xcoord && ycoord == other.ycoord;
274 }
275 /// test inequality
276 bool operator!=(const FCOORD &other) const {
277 return xcoord != other.xcoord || ycoord != other.ycoord;
278 }
279 /// rotate 90 deg anti
280 friend FCOORD operator!(const FCOORD &);
281 /// unary minus
282 friend FCOORD operator-(const FCOORD &);
283 /// add
284 friend FCOORD operator+(const FCOORD &, const FCOORD &);
285 /// add
286 friend FCOORD &operator+=(FCOORD &, const FCOORD &);
287 /// subtract
288 friend FCOORD operator-(const FCOORD &, const FCOORD &);
289 /// subtract
290 friend FCOORD &operator-=(FCOORD &, const FCOORD &);
291 /// scalar product
292 friend float operator%(const FCOORD &, const FCOORD &);
293 /// cross product
294 friend float operator*(const FCOORD &, const FCOORD &);
295 /// multiply
296 friend FCOORD operator*(const FCOORD &, float);
297 /// multiply
298 friend FCOORD operator*(float, const FCOORD &);
299
300 /// multiply
301 friend FCOORD &operator*=(FCOORD &, float);
302 /// divide
303 friend FCOORD operator/(const FCOORD &, float);
304 /// rotate
305 ///@param vec by vector
306 void rotate(const FCOORD vec);
307 // unrotate - undo a rotate(vec)
308 // @param vec by vector
309 void unrotate(const FCOORD &vec);
310 /// divide
311 friend FCOORD &operator/=(FCOORD &, float);
312
313 private:
314 float xcoord; // 2 floating coords
315 float ycoord;
316 };
317
318 /**********************************************************************
319 * operator!
320 *
321 * Rotate an ICOORD 90 degrees anticlockwise.
322 **********************************************************************/
323
324 inline ICOORD operator!( // rotate 90 deg anti
325 const ICOORD &src // thing to rotate
326 ) {
327 ICOORD result; // output
328
329 result.xcoord = -src.ycoord;
330 result.ycoord = src.xcoord;
331 return result;
332 }
333
334 /**********************************************************************
335 * operator-
336 *
337 * Unary minus of an ICOORD.
338 **********************************************************************/
339
340 inline ICOORD operator-( // unary minus
341 const ICOORD &src // thing to minus
342 ) {
343 ICOORD result; // output
344
345 result.xcoord = -src.xcoord;
346 result.ycoord = -src.ycoord;
347 return result;
348 }
349
350 /**********************************************************************
351 * operator+
352 *
353 * Add 2 ICOORDS.
354 **********************************************************************/
355
356 inline ICOORD operator+( // sum vectors
357 const ICOORD &op1, // operands
358 const ICOORD &op2) {
359 ICOORD sum; // result
360
361 sum.xcoord = op1.xcoord + op2.xcoord;
362 sum.ycoord = op1.ycoord + op2.ycoord;
363 return sum;
364 }
365
366 /**********************************************************************
367 * operator+=
368 *
369 * Add 2 ICOORDS.
370 **********************************************************************/
371
372 inline ICOORD &operator+=( // sum vectors
373 ICOORD &op1, // operands
374 const ICOORD &op2) {
375 op1.xcoord += op2.xcoord;
376 op1.ycoord += op2.ycoord;
377 return op1;
378 }
379
380 /**********************************************************************
381 * operator-
382 *
383 * Subtract 2 ICOORDS.
384 **********************************************************************/
385
386 inline ICOORD operator-( // subtract vectors
387 const ICOORD &op1, // operands
388 const ICOORD &op2) {
389 ICOORD sum; // result
390
391 sum.xcoord = op1.xcoord - op2.xcoord;
392 sum.ycoord = op1.ycoord - op2.ycoord;
393 return sum;
394 }
395
396 /**********************************************************************
397 * operator-=
398 *
399 * Subtract 2 ICOORDS.
400 **********************************************************************/
401
402 inline ICOORD &operator-=( // subtract vectors
403 ICOORD &op1, // operands
404 const ICOORD &op2) {
405 op1.xcoord -= op2.xcoord;
406 op1.ycoord -= op2.ycoord;
407 return op1;
408 }
409
410 /**********************************************************************
411 * operator%
412 *
413 * Scalar product of 2 ICOORDS.
414 **********************************************************************/
415
416 inline int32_t operator%( // scalar product
417 const ICOORD &op1, // operands
418 const ICOORD &op2) {
419 return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord;
420 }
421
422 /**********************************************************************
423 * operator*
424 *
425 * Cross product of 2 ICOORDS.
426 **********************************************************************/
427
428 inline int32_t operator*( // cross product
429 const ICOORD &op1, // operands
430 const ICOORD &op2) {
431 return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord;
432 }
433
434 /**********************************************************************
435 * operator*
436 *
437 * Scalar multiply of an ICOORD.
438 **********************************************************************/
439
440 inline ICOORD operator*( // scalar multiply
441 const ICOORD &op1, // operands
442 TDimension scale) {
443 ICOORD result; // output
444
445 result.xcoord = op1.xcoord * scale;
446 result.ycoord = op1.ycoord * scale;
447 return result;
448 }
449
450 inline ICOORD operator*( // scalar multiply
451 TDimension scale,
452 const ICOORD &op1 // operands
453 ) {
454 ICOORD result; // output
455
456 result.xcoord = op1.xcoord * scale;
457 result.ycoord = op1.ycoord * scale;
458 return result;
459 }
460
461 /**********************************************************************
462 * operator*=
463 *
464 * Scalar multiply of an ICOORD.
465 **********************************************************************/
466
467 inline ICOORD &operator*=( // scalar multiply
468 ICOORD &op1, // operands
469 TDimension scale) {
470 op1.xcoord *= scale;
471 op1.ycoord *= scale;
472 return op1;
473 }
474
475 /**********************************************************************
476 * operator/
477 *
478 * Scalar divide of an ICOORD.
479 **********************************************************************/
480
481 inline ICOORD operator/( // scalar divide
482 const ICOORD &op1, // operands
483 TDimension scale) {
484 ICOORD result; // output
485
486 result.xcoord = op1.xcoord / scale;
487 result.ycoord = op1.ycoord / scale;
488 return result;
489 }
490
491 /**********************************************************************
492 * operator/=
493 *
494 * Scalar divide of an ICOORD.
495 **********************************************************************/
496
497 inline ICOORD &operator/=( // scalar divide
498 ICOORD &op1, // operands
499 TDimension scale) {
500 op1.xcoord /= scale;
501 op1.ycoord /= scale;
502 return op1;
503 }
504
505 /**********************************************************************
506 * ICOORD::rotate
507 *
508 * Rotate an ICOORD by the given (normalized) (cos,sin) vector.
509 **********************************************************************/
510
511 inline void ICOORD::rotate( // rotate by vector
512 const FCOORD &vec) {
513 auto tmp = static_cast<TDimension>(std::floor(xcoord * vec.x() - ycoord * vec.y() + 0.5f));
514 ycoord = static_cast<TDimension>(std::floor(ycoord * vec.x() + xcoord * vec.y() + 0.5f));
515 xcoord = tmp;
516 }
517
518 /**********************************************************************
519 * operator!
520 *
521 * Rotate an FCOORD 90 degrees anticlockwise.
522 **********************************************************************/
523
524 inline FCOORD operator!( // rotate 90 deg anti
525 const FCOORD &src // thing to rotate
526 ) {
527 FCOORD result; // output
528
529 result.xcoord = -src.ycoord;
530 result.ycoord = src.xcoord;
531 return result;
532 }
533
534 /**********************************************************************
535 * operator-
536 *
537 * Unary minus of an FCOORD.
538 **********************************************************************/
539
540 inline FCOORD operator-( // unary minus
541 const FCOORD &src // thing to minus
542 ) {
543 FCOORD result; // output
544
545 result.xcoord = -src.xcoord;
546 result.ycoord = -src.ycoord;
547 return result;
548 }
549
550 /**********************************************************************
551 * operator+
552 *
553 * Add 2 FCOORDS.
554 **********************************************************************/
555
556 inline FCOORD operator+( // sum vectors
557 const FCOORD &op1, // operands
558 const FCOORD &op2) {
559 FCOORD sum; // result
560
561 sum.xcoord = op1.xcoord + op2.xcoord;
562 sum.ycoord = op1.ycoord + op2.ycoord;
563 return sum;
564 }
565
566 /**********************************************************************
567 * operator+=
568 *
569 * Add 2 FCOORDS.
570 **********************************************************************/
571
572 inline FCOORD &operator+=( // sum vectors
573 FCOORD &op1, // operands
574 const FCOORD &op2) {
575 op1.xcoord += op2.xcoord;
576 op1.ycoord += op2.ycoord;
577 return op1;
578 }
579
580 /**********************************************************************
581 * operator-
582 *
583 * Subtract 2 FCOORDS.
584 **********************************************************************/
585
586 inline FCOORD operator-( // subtract vectors
587 const FCOORD &op1, // operands
588 const FCOORD &op2) {
589 FCOORD sum; // result
590
591 sum.xcoord = op1.xcoord - op2.xcoord;
592 sum.ycoord = op1.ycoord - op2.ycoord;
593 return sum;
594 }
595
596 /**********************************************************************
597 * operator-=
598 *
599 * Subtract 2 FCOORDS.
600 **********************************************************************/
601
602 inline FCOORD &operator-=( // subtract vectors
603 FCOORD &op1, // operands
604 const FCOORD &op2) {
605 op1.xcoord -= op2.xcoord;
606 op1.ycoord -= op2.ycoord;
607 return op1;
608 }
609
610 /**********************************************************************
611 * operator%
612 *
613 * Scalar product of 2 FCOORDS.
614 **********************************************************************/
615
616 inline float operator%( // scalar product
617 const FCOORD &op1, // operands
618 const FCOORD &op2) {
619 return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord;
620 }
621
622 /**********************************************************************
623 * operator*
624 *
625 * Cross product of 2 FCOORDS.
626 **********************************************************************/
627
628 inline float operator*( // cross product
629 const FCOORD &op1, // operands
630 const FCOORD &op2) {
631 return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord;
632 }
633
634 /**********************************************************************
635 * operator*
636 *
637 * Scalar multiply of an FCOORD.
638 **********************************************************************/
639
640 inline FCOORD operator*( // scalar multiply
641 const FCOORD &op1, // operands
642 float scale) {
643 FCOORD result; // output
644
645 result.xcoord = op1.xcoord * scale;
646 result.ycoord = op1.ycoord * scale;
647 return result;
648 }
649
650 inline FCOORD operator*( // scalar multiply
651 float scale,
652 const FCOORD &op1 // operands
653 ) {
654 FCOORD result; // output
655
656 result.xcoord = op1.xcoord * scale;
657 result.ycoord = op1.ycoord * scale;
658 return result;
659 }
660
661 /**********************************************************************
662 * operator*=
663 *
664 * Scalar multiply of an FCOORD.
665 **********************************************************************/
666
667 inline FCOORD &operator*=( // scalar multiply
668 FCOORD &op1, // operands
669 float scale) {
670 op1.xcoord *= scale;
671 op1.ycoord *= scale;
672 return op1;
673 }
674
675 /**********************************************************************
676 * operator/
677 *
678 * Scalar divide of an FCOORD.
679 **********************************************************************/
680
681 inline FCOORD operator/( // scalar divide
682 const FCOORD &op1, // operands
683 float scale) {
684 FCOORD result; // output
685 ASSERT_HOST(scale != 0.0f);
686 result.xcoord = op1.xcoord / scale;
687 result.ycoord = op1.ycoord / scale;
688 return result;
689 }
690
691 /**********************************************************************
692 * operator/=
693 *
694 * Scalar divide of an FCOORD.
695 **********************************************************************/
696
697 inline FCOORD &operator/=( // scalar divide
698 FCOORD &op1, // operands
699 float scale) {
700 ASSERT_HOST(scale != 0.0f);
701 op1.xcoord /= scale;
702 op1.ycoord /= scale;
703 return op1;
704 }
705
706 /**********************************************************************
707 * rotate
708 *
709 * Rotate an FCOORD by the given (normalized) (cos,sin) vector.
710 **********************************************************************/
711
712 inline void FCOORD::rotate( // rotate by vector
713 const FCOORD vec) {
714 float tmp;
715
716 tmp = xcoord * vec.x() - ycoord * vec.y();
717 ycoord = ycoord * vec.x() + xcoord * vec.y();
718 xcoord = tmp;
719 }
720
721 inline void FCOORD::unrotate(const FCOORD &vec) {
722 rotate(FCOORD(vec.x(), -vec.y()));
723 }
724
725 } // namespace tesseract
726
727 #endif