Skip to content

Commit aa8eb6c

Browse files
committed
Use Leptonica API to access internals of Box
Signed-off-by: Stefan Weil <sw@weilnetz.de>
1 parent 0df584e commit aa8eb6c

File tree

4 files changed

+97
-48
lines changed

4 files changed

+97
-48
lines changed

src/training/pango/boxchar.cpp

+62-28
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ void BoxChar::TranslateBoxes(int xshift, int yshift, std::vector<BoxChar *> *box
8484
for (auto &boxe : *boxes) {
8585
Box *box = boxe->box_;
8686
if (box != nullptr) {
87-
box->x += xshift;
88-
box->y += yshift;
87+
int32_t box_x;
88+
int32_t box_y;
89+
boxGetGeometry(box, &box_x, &box_y, nullptr, nullptr);
90+
boxSetGeometry(box, box_x + xshift, box_y + yshift, -1, -1);
8991
}
9092
}
9193
}
@@ -129,10 +131,18 @@ void BoxChar::InsertNewlines(bool rtl_rules, bool vertical_rules, std::vector<Bo
129131
continue;
130132
}
131133
if (prev_i != SIZE_MAX) {
134+
int32_t box_x;
135+
int32_t box_y;
136+
boxGetGeometry(box, &box_x, &box_y, nullptr, nullptr);
132137
Box *prev_box = (*boxes)[prev_i]->box_;
133-
int shift = box->x - prev_box->x;
138+
int32_t prev_box_x;
139+
int32_t prev_box_y;
140+
int32_t prev_box_w;
141+
int32_t prev_box_h;
142+
boxGetGeometry(prev_box, &prev_box_x, &prev_box_y, &prev_box_w, &prev_box_h);
143+
int shift = box_x - prev_box_x;
134144
if (vertical_rules) {
135-
shift = box->y - prev_box->y;
145+
shift = box_y - prev_box_y;
136146
} else if (rtl_rules) {
137147
shift = -shift;
138148
}
@@ -142,15 +152,15 @@ void BoxChar::InsertNewlines(bool rtl_rules, bool vertical_rules, std::vector<Bo
142152
// a box outside the image by making the width and height 1.
143153
int width = 1;
144154
int height = 1;
145-
int x = prev_box->x + prev_box->w;
146-
int y = prev_box->y;
155+
int x = prev_box_x + prev_box_w;
156+
int y = prev_box_y;
147157
if (vertical_rules) {
148-
x = prev_box->x;
149-
y = prev_box->y + prev_box->h;
158+
x = prev_box_x;
159+
y = prev_box_y + prev_box_h;
150160
} else if (rtl_rules) {
151-
x = prev_box->x - width;
161+
x = prev_box_x - width;
152162
if (x < 0) {
153-
tprintf("prev x = %d, width=%d\n", prev_box->x, width);
163+
tprintf("prev x = %d, width=%d\n", prev_box_x, width);
154164
x = 0;
155165
}
156166
}
@@ -184,36 +194,48 @@ void BoxChar::InsertSpaces(bool rtl_rules, bool vertical_rules, std::vector<BoxC
184194
if (box == nullptr) {
185195
Box *prev = (*boxes)[i - 1]->box_;
186196
Box *next = (*boxes)[i + 1]->box_;
197+
int32_t prev_x;
198+
int32_t prev_y;
199+
int32_t prev_w;
200+
int32_t prev_h;
201+
int32_t next_x;
202+
int32_t next_y;
203+
int32_t next_w;
204+
int32_t next_h;
187205
ASSERT_HOST(prev != nullptr && next != nullptr);
188-
int top = std::min(prev->y, next->y);
189-
int bottom = std::max(prev->y + prev->h, next->y + next->h);
190-
int left = prev->x + prev->w;
191-
int right = next->x;
206+
boxGetGeometry(prev, &prev_x, &prev_y, &prev_w, &prev_h);
207+
boxGetGeometry(next, &next_x, &next_y, &next_w, &next_h);
208+
int top = std::min(prev_y, next_y);
209+
int bottom = std::max(prev_y + prev_h, next_y + next_h);
210+
int left = prev_x + prev_w;
211+
int right = next_x;
192212
if (vertical_rules) {
193-
top = prev->y + prev->h;
194-
bottom = next->y;
195-
left = std::min(prev->x, next->x);
196-
right = std::max(prev->x + prev->w, next->x + next->w);
213+
top = prev_y + prev_h;
214+
bottom = next_y;
215+
left = std::min(prev_x, next_x);
216+
right = std::max(prev_x + prev_w, next_x + next_w);
197217
} else if (rtl_rules) {
198218
// With RTL we have to account for BiDi.
199219
// Right becomes the min left of all prior boxes back to the first
200220
// space or newline.
201-
right = prev->x;
202-
left = next->x + next->w;
221+
right = prev_x;
222+
left = next_x + next_w;
203223
for (int j = i - 2; j >= 0 && (*boxes)[j]->ch_ != " " && (*boxes)[j]->ch_ != "\t"; --j) {
204224
prev = (*boxes)[j]->box_;
205225
ASSERT_HOST(prev != nullptr);
206-
if (prev->x < right) {
207-
right = prev->x;
226+
boxGetGeometry(prev, &prev_x, nullptr, nullptr, nullptr);
227+
if (prev_x < right) {
228+
right = prev_x;
208229
}
209230
}
210231
// Left becomes the max right of all next boxes forward to the first
211232
// space or newline.
212233
for (size_t j = i + 2;
213234
j < boxes->size() && (*boxes)[j]->box_ != nullptr && (*boxes)[j]->ch_ != "\t"; ++j) {
214235
next = (*boxes)[j]->box_;
215-
if (next->x + next->w > left) {
216-
left = next->x + next->w;
236+
boxGetGeometry(next, &next_x, nullptr, &next_w, nullptr);
237+
if (next_x + next_w > left) {
238+
left = next_x + next_w;
217239
}
218240
}
219241
}
@@ -275,8 +297,14 @@ bool BoxChar::MostlyVertical(const std::vector<BoxChar *> &boxes) {
275297
for (size_t i = 1; i < boxes.size(); ++i) {
276298
if (boxes[i - 1]->box_ != nullptr && boxes[i]->box_ != nullptr &&
277299
boxes[i - 1]->page_ == boxes[i]->page_) {
278-
int dx = boxes[i]->box_->x - boxes[i - 1]->box_->x;
279-
int dy = boxes[i]->box_->y - boxes[i - 1]->box_->y;
300+
int32_t x0;
301+
int32_t y0;
302+
boxGetGeometry(boxes[i]->box_, &x0, &y0, nullptr, nullptr);
303+
int32_t x1;
304+
int32_t y1;
305+
boxGetGeometry(boxes[i - 1]->box_, &x1, &y1, nullptr, nullptr);
306+
int dx = x0 - x1;
307+
int dy = y0 - y1;
280308
if (abs(dx) > abs(dy) * kMinNewlineRatio || abs(dy) > abs(dx) * kMinNewlineRatio) {
281309
total_dx += dx * dx;
282310
total_dy += dy * dy;
@@ -337,8 +365,14 @@ std::string BoxChar::GetTesseractBoxStr(int height, const std::vector<BoxChar *>
337365
tprintf("Error: Call PrepareToWrite before WriteTesseractBoxFile!!\n");
338366
return "";
339367
}
340-
int nbytes = snprintf(buffer, kMaxLineLength, "%s %d %d %d %d %d\n", boxe->ch_.c_str(), box->x,
341-
height - box->y - box->h, box->x + box->w, height - box->y, boxe->page_);
368+
int32_t box_x;
369+
int32_t box_y;
370+
int32_t box_w;
371+
int32_t box_h;
372+
boxGetGeometry(const_cast<Box *>(box), &box_x, &box_y, &box_w, &box_h);
373+
int nbytes = snprintf(buffer, kMaxLineLength, "%s %d %d %d %d %d\n",
374+
boxe->ch_.c_str(), box_x, height - box_y - box_h,
375+
box_x + box_w, height - box_y, boxe->page_);
342376
output.append(buffer, nbytes);
343377
}
344378
return output;

src/training/pango/boxchar.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@
2626
#include <vector>
2727

2828
#include <allheaders.h> // for Leptonica API
29-
#if (LIBLEPT_MAJOR_VERSION == 1 && LIBLEPT_MINOR_VERSION >= 83) || LIBLEPT_MAJOR_VERSION > 1
30-
#include <pix_internal.h> // for fast access to Box geometry
31-
#endif
3229
#include <tesseract/export.h>
3330

3431
namespace tesseract {
@@ -79,7 +76,11 @@ class BoxChar {
7976
if (other.box_ == nullptr) {
8077
return false;
8178
}
82-
return box_->x < other.box_->x;
79+
int32_t box_x;
80+
int32_t other_box_x;
81+
boxGetGeometry(box_, &box_x, nullptr, nullptr, nullptr);
82+
boxGetGeometry(box_, &other_box_x, nullptr, nullptr, nullptr);
83+
return box_x < other_box_x;
8384
}
8485
// Increments *num_rtl and *num_ltr according to the directionality of
8586
// characters in the box.

src/training/pango/stringrenderer.cpp

+16-9
Original file line numberDiff line numberDiff line change
@@ -428,15 +428,25 @@ static void MergeBoxCharsToWords(std::vector<BoxChar *> *boxchars) {
428428
BoxChar *last_boxchar = result.back();
429429
// Compute bounding box union
430430
const Box *box = boxchar->box();
431+
int32_t box_x;
432+
int32_t box_y;
433+
int32_t box_w;
434+
int32_t box_h;
435+
boxGetGeometry(const_cast<Box *>(box), &box_x, &box_y, &box_w, &box_h);
431436
Box *last_box = last_boxchar->mutable_box();
432-
int left = std::min(last_box->x, box->x);
433-
int right = std::max(last_box->x + last_box->w, box->x + box->w);
434-
int top = std::min(last_box->y, box->y);
435-
int bottom = std::max(last_box->y + last_box->h, box->y + box->h);
437+
int32_t last_box_x;
438+
int32_t last_box_y;
439+
int32_t last_box_w;
440+
int32_t last_box_h;
441+
boxGetGeometry(last_box, &last_box_x, &last_box_y, &last_box_w, &last_box_h);
442+
int left = std::min(last_box_x, box_x);
443+
int right = std::max(last_box_x + last_box_w, box_x + box_w);
444+
int top = std::min(last_box_y, box_y);
445+
int bottom = std::max(last_box_y + last_box_h, box_y + box_h);
436446
// Conclude that the word was broken to span multiple lines based on the
437447
// size of the merged bounding box in relation to those of the individual
438448
// characters seen so far.
439-
if (right - left > last_box->w + 5 * box->w) {
449+
if (right - left > last_box_w + 5 * box_w) {
440450
tlog(1, "Found line break after '%s'", last_boxchar->ch().c_str());
441451
// Insert a fake interword space and start a new word with the current
442452
// boxchar.
@@ -447,10 +457,7 @@ static void MergeBoxCharsToWords(std::vector<BoxChar *> *boxchars) {
447457
}
448458
// Append to last word
449459
last_boxchar->mutable_ch()->append(boxchar->ch());
450-
last_box->x = left;
451-
last_box->w = right - left;
452-
last_box->y = top;
453-
last_box->h = bottom - top;
460+
boxSetGeometry(last_box, left, top, right - left, bottom - top);
454461
delete boxchar;
455462
boxchar = nullptr;
456463
}

src/training/text2image.cpp

+14-7
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,18 @@ static void ExtractFontProperties(const std::string &utf8_text, StringRenderer *
282282
if (IsWhitespaceBox(boxes[b + 1])) {
283283
continue;
284284
}
285-
int xgap = (boxes[b + 1]->box()->x - (boxes[b]->box()->x + boxes[b]->box()->w));
285+
int32_t box_x;
286+
int32_t box_w;
287+
boxGetGeometry(const_cast<Box *>(boxes[b]->box()), &box_x, nullptr, &box_w, nullptr);
288+
int32_t box1_x;
289+
int32_t box1_w;
290+
boxGetGeometry(const_cast<Box *>(boxes[b + 1]->box()), &box1_x, nullptr, &box1_w, nullptr);
291+
int xgap = (box1_x - (box_x + box_w));
286292
spacing_map_it0 = spacing_map.find(ch0);
287293
int ok_count = 0;
288294
if (spacing_map_it0 == spacing_map.end() &&
289295
render->font().GetSpacingProperties(ch0, &x_bearing, &x_advance)) {
290-
spacing_map[ch0] = SpacingProperties(x_bearing, x_advance - x_bearing - boxes[b]->box()->w);
296+
spacing_map[ch0] = SpacingProperties(x_bearing, x_advance - x_bearing - box_w);
291297
spacing_map_it0 = spacing_map.find(ch0);
292298
++ok_count;
293299
}
@@ -297,7 +303,7 @@ static void ExtractFontProperties(const std::string &utf8_text, StringRenderer *
297303
if (spacing_map_it1 == spacing_map.end() &&
298304
render->font().GetSpacingProperties(ch1, &x_bearing, &x_advance)) {
299305
spacing_map[ch1] =
300-
SpacingProperties(x_bearing, x_advance - x_bearing - boxes[b + 1]->box()->w);
306+
SpacingProperties(x_bearing, x_advance - x_bearing - box1_w);
301307
spacing_map_it1 = spacing_map.find(ch1);
302308
++ok_count;
303309
}
@@ -356,10 +362,11 @@ static bool MakeIndividualGlyphs(Image pix, const std::vector<BoxChar *> &vbox,
356362
if (!b) {
357363
continue;
358364
}
359-
const int x = b->x;
360-
const int y = b->y;
361-
const int w = b->w;
362-
const int h = b->h;
365+
int32_t x;
366+
int32_t y;
367+
int32_t w;
368+
int32_t h;
369+
boxGetGeometry(b, &x, &y, &w, &h);
363370
// Check present tiff page (for multipage tiff)
364371
if (y < y_previous - pixGetHeight(pix) / 10) {
365372
tprintf("ERROR: Wrap-around encountered, at i=%d\n", i);

0 commit comments

Comments
 (0)