Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/tesseract/src/textord/blkocc.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 * | |
| 3 * File: blkocc.cpp (Formerly blockocc.c) | |
| 4 * Description: Block Occupancy routines | |
| 5 * Author: Chris Newton | |
| 6 * | |
| 7 * (c) Copyright 1991, Hewlett-Packard Company. | |
| 8 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
| 9 ** you may not use this file except in compliance with the License. | |
| 10 ** You may obtain a copy of the License at | |
| 11 ** http://www.apache.org/licenses/LICENSE-2.0 | |
| 12 ** Unless required by applicable law or agreed to in writing, software | |
| 13 ** distributed under the License is distributed on an "AS IS" BASIS, | |
| 14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 15 ** See the License for the specific language governing permissions and | |
| 16 ** limitations under the License. | |
| 17 * | |
| 18 ******************************************************************************/ | |
| 19 | |
| 20 #include "blkocc.h" | |
| 21 | |
| 22 #include "drawtord.h" | |
| 23 #include "errcode.h" | |
| 24 | |
| 25 #include <cctype> | |
| 26 #include <cmath> | |
| 27 | |
| 28 #include "helpers.h" | |
| 29 | |
| 30 namespace tesseract { | |
| 31 | |
| 32 double_VAR(textord_underline_threshold, 0.5, "Fraction of width occupied"); | |
| 33 | |
| 34 // Forward declarations of static functions | |
| 35 static void horizontal_cblob_projection(C_BLOB *blob, // blob to project | |
| 36 STATS *stats); // output | |
| 37 static void horizontal_coutline_projection(C_OUTLINE *outline, | |
| 38 STATS *stats); // output | |
| 39 | |
| 40 /** | |
| 41 * test_underline | |
| 42 * | |
| 43 * Check to see if the blob is an underline. | |
| 44 * Return true if it is. | |
| 45 */ | |
| 46 | |
| 47 bool test_underline( // look for underlines | |
| 48 bool testing_on, ///< drawing blob | |
| 49 C_BLOB *blob, ///< blob to test | |
| 50 int16_t baseline, ///< coords of baseline | |
| 51 int16_t xheight ///< height of line | |
| 52 ) { | |
| 53 TDimension occ; | |
| 54 STATS projection; | |
| 55 | |
| 56 auto blob_box = blob->bounding_box(); | |
| 57 auto blob_width = blob->bounding_box().width(); | |
| 58 projection.set_range(blob_box.bottom(), blob_box.top()); | |
| 59 if (testing_on) { | |
| 60 // blob->plot(to_win,GOLDENROD,GOLDENROD); | |
| 61 // line_color_index(to_win,GOLDENROD); | |
| 62 // move2d(to_win,blob_box.left(),baseline); | |
| 63 // draw2d(to_win,blob_box.right(),baseline); | |
| 64 // move2d(to_win,blob_box.left(),baseline+xheight); | |
| 65 // draw2d(to_win,blob_box.right(),baseline+xheight); | |
| 66 tprintf("Testing underline on blob at (%d,%d)->(%d,%d), base=%d\nOccs:", | |
| 67 blob->bounding_box().left(), blob->bounding_box().bottom(), | |
| 68 blob->bounding_box().right(), blob->bounding_box().top(), baseline); | |
| 69 } | |
| 70 horizontal_cblob_projection(blob, &projection); | |
| 71 int32_t desc_occ = 0; | |
| 72 for (occ = blob_box.bottom(); occ < baseline; occ++) { | |
| 73 if (occ <= blob_box.top() && projection.pile_count(occ) > desc_occ) { | |
| 74 // max in region | |
| 75 desc_occ = projection.pile_count(occ); | |
| 76 } | |
| 77 } | |
| 78 int32_t x_occ = 0; | |
| 79 for (occ = baseline; occ <= baseline + xheight; occ++) { | |
| 80 if (occ >= blob_box.bottom() && occ <= blob_box.top() && projection.pile_count(occ) > x_occ) { | |
| 81 // max in region | |
| 82 x_occ = projection.pile_count(occ); | |
| 83 } | |
| 84 } | |
| 85 int32_t asc_occ = 0; | |
| 86 for (occ = baseline + xheight + 1; occ <= blob_box.top(); occ++) { | |
| 87 if (occ >= blob_box.bottom() && projection.pile_count(occ) > asc_occ) { | |
| 88 asc_occ = projection.pile_count(occ); | |
| 89 } | |
| 90 } | |
| 91 if (testing_on) { | |
| 92 tprintf("%d %d %d\n", desc_occ, x_occ, asc_occ); | |
| 93 } | |
| 94 if (desc_occ == 0 && x_occ == 0 && asc_occ == 0) { | |
| 95 tprintf("Bottom=%d, top=%d, base=%d, x=%d\n", blob_box.bottom(), blob_box.top(), baseline, | |
| 96 xheight); | |
| 97 projection.print(); | |
| 98 } | |
| 99 if (desc_occ > x_occ + x_occ && desc_occ > blob_width * textord_underline_threshold) { | |
| 100 return true; // real underline | |
| 101 } | |
| 102 return asc_occ > x_occ + x_occ && asc_occ > blob_width * textord_underline_threshold; // overline | |
| 103 // neither | |
| 104 } | |
| 105 | |
| 106 /** | |
| 107 * horizontal_cblob_projection | |
| 108 * | |
| 109 * Compute the horizontal projection of a cblob from its outlines | |
| 110 * and add to the given STATS. | |
| 111 */ | |
| 112 | |
| 113 static void horizontal_cblob_projection( // project outlines | |
| 114 C_BLOB *blob, ///< blob to project | |
| 115 STATS *stats ///< output | |
| 116 ) { | |
| 117 // outlines of blob | |
| 118 C_OUTLINE_IT out_it = blob->out_list(); | |
| 119 | |
| 120 for (out_it.mark_cycle_pt(); !out_it.cycled_list(); out_it.forward()) { | |
| 121 horizontal_coutline_projection(out_it.data(), stats); | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 /** | |
| 126 * horizontal_coutline_projection | |
| 127 * | |
| 128 * Compute the horizontal projection of an outline from its outlines | |
| 129 * and add to the given STATS. | |
| 130 */ | |
| 131 | |
| 132 static void horizontal_coutline_projection( // project outlines | |
| 133 C_OUTLINE *outline, ///< outline to project | |
| 134 STATS *stats ///< output | |
| 135 ) { | |
| 136 ICOORD pos; // current point | |
| 137 ICOORD step; // edge step | |
| 138 int32_t length; // of outline | |
| 139 int16_t stepindex; // current step | |
| 140 C_OUTLINE_IT out_it = outline->child(); | |
| 141 | |
| 142 pos = outline->start_pos(); | |
| 143 length = outline->pathlength(); | |
| 144 for (stepindex = 0; stepindex < length; stepindex++) { | |
| 145 step = outline->step(stepindex); | |
| 146 if (step.y() > 0) { | |
| 147 stats->add(pos.y(), pos.x()); | |
| 148 } else if (step.y() < 0) { | |
| 149 stats->add(pos.y() - 1, -pos.x()); | |
| 150 } | |
| 151 pos += step; | |
| 152 } | |
| 153 | |
| 154 for (out_it.mark_cycle_pt(); !out_it.cycled_list(); out_it.forward()) { | |
| 155 horizontal_coutline_projection(out_it.data(), stats); | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 } // namespace tesseract |
