21 #include "config_auto.h"
36 ColPartition_IT it(&parts_);
37 it.add_list_after(partitions);
42 ColPartition_IT it(&parts_);
43 it.add_after_then_move(part);
49 int num_good_cols = 0;
51 ColPartition_IT it(const_cast<ColPartition_LIST*>(&parts_));
52 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
53 if (it.data()->good_width()) ++num_good_cols;
60 ColPartition_IT it(&parts_);
62 for (
int i = 0; i < index && !it.cycled_list(); ++i, it.forward());
70 ColPartition_IT it(&parts_);
71 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
81 ColPartition_IT it(&parts_);
91 int set_size = src_sets->
size();
94 for (
int i = 0; i < set_size; ++i) {
96 if (column_set ==
nullptr)
100 ColPartition_IT part_it(&parts_);
102 int prev_right = INT32_MIN;
103 part_it.mark_cycle_pt();
104 ColPartition_IT col_it(&column_set->parts_);
105 for (col_it.mark_cycle_pt(); !col_it.cycled_list(); col_it.forward()) {
109 int col_left = col_part->
left_key();
113 while (!part_it.at_last() && part->
right_key() < col_left) {
116 part = part_it.data();
120 if (part_right < col_left || col_right < part_left) {
126 bool part_width_ok = cb(part->
KeyWidth(part_left, part_right));
127 if (col_left < part_left && col_left > prev_right) {
131 bool tab_width_ok = cb(part->
KeyWidth(col_left, part_right));
132 bool box_width_ok = cb(part->
KeyWidth(col_box_left, part_right));
133 if (tab_width_ok || (!part_width_ok)) {
138 }
else if (col_box_left < part_left &&
139 (box_width_ok || !part_width_ok)) {
147 if (col_right > part_right &&
148 (part_it.at_last() ||
149 part_it.data_relative(1)->left_key() > col_right)) {
152 bool tab_width_ok = cb(part->
KeyWidth(part_left, col_right));
153 bool box_width_ok = cb(part->
KeyWidth(part_left, col_box_right));
154 if (tab_width_ok || (!part_width_ok)) {
159 }
else if (col_box_right > part_right &&
160 (box_width_ok || !part_width_ok)) {
179 tprintf(
"Considering new column candidate:\n");
184 tprintf(
"Not a legal column candidate:\n");
190 for (
int i = 0; i < column_sets->
size(); ++i) {
194 bool better = good_coverage_ > columns->good_coverage_;
195 if (good_coverage_ == columns->good_coverage_) {
196 better = good_column_count_ > columns->good_column_count_;
197 if (good_column_count_ == columns->good_column_count_) {
198 better = bad_coverage_ > columns->bad_coverage_;
205 column_sets->
insert(
this, i);
225 tprintf(
"CompatibleColumns testing compatibility\n");
229 if (other->parts_.empty()) {
231 tprintf(
"CompatibleColumns true due to empty other\n");
234 ColPartition_IT it(&other->parts_);
235 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
239 tprintf(
"CompatibleColumns ignoring image partition\n");
244 int y = part->
MidY();
249 if (right_col ==
nullptr || left_col ==
nullptr) {
251 tprintf(
"CompatibleColumns false due to partition edge outside\n");
256 if (right_col != left_col && cb(right - left)) {
258 tprintf(
"CompatibleColumns false due to good width in multiple cols\n");
264 ColPartition_IT it2= it;
265 while (!it2.at_last()) {
271 if (next_left == right) {
276 if (right_col == next_left_col) {
286 tprintf(
"CompatibleColumns false due to 2 parts of good width\n");
287 tprintf(
"part1 %d-%d, part2 %d-%d\n",
288 left, right, next_left, next_right);
298 tprintf(
"CompatibleColumns true!\n");
307 ColPartition_IT it(&part_set->parts_);
308 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
313 int y = part->
MidY();
314 BLOBNBOX_C_IT box_it(part->
boxes());
315 for (box_it.mark_cycle_pt(); !box_it.cycled_list(); box_it.forward()) {
316 const TBOX& box = it.data()->bounding_box();
322 total_width += box.
width();
331 ColPartition_IT it(&parts_);
334 bool any_text_parts =
false;
335 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
340 any_text_parts =
true;
349 return any_text_parts;
354 ColPartition_LIST copy_parts;
355 ColPartition_IT src_it(&parts_);
356 ColPartition_IT dest_it(©_parts);
357 for (src_it.mark_cycle_pt(); !src_it.cycled_list(); src_it.forward()) {
370 ColSegment_LIST *segments) {
371 ColPartition_IT it(&parts_);
372 ColSegment_IT col_it(segments);
373 col_it.move_to_last();
374 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
379 col_seg->InsertBox(
TBOX(bot_left, top_right));
380 col_it.add_after_then_move(col_seg);
387 #ifndef GRAPHICS_DISABLED
388 ColPartition_IT it(&parts_);
389 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
394 #endif // GRAPHICS_DISABLED
411 int* first_spanned_col) {
414 *first_spanned_col = -1;
415 int margin_columns = 0;
416 ColPartition_IT it(&parts_);
418 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward(), col_index += 2) {
426 *first_col = col_index;
430 *last_col = col_index;
433 if (left_margin <= part->LeftAtY(y)) {
435 *first_spanned_col = col_index;
440 if (*first_col < 0) {
442 *first_col = col_index - 1;
444 if (right_margin >= part->
RightAtY(y)) {
446 if (margin_columns == 0)
447 *first_spanned_col = col_index;
450 *last_col = col_index;
452 }
else if (left < part->LeftAtY(y) && right > part->
RightAtY(y)) {
455 if (*first_col < 0) {
457 *first_col = col_index - 1;
459 if (margin_columns == 0)
460 *first_spanned_col = col_index;
461 *last_col = col_index;
462 }
else if (right < part->LeftAtY(y)) {
464 *last_col = col_index - 1;
465 if (*first_col < 0) {
467 *first_col = col_index - 1;
473 *first_col = col_index - 1;
475 *last_col = col_index - 1;
478 if (*first_col == *last_col && right - left <
kMinColumnWidth * resolution) {
482 }
else if (margin_columns <= 1) {
484 if (margin_columns == 1 && parts_.singleton()) {
502 ColPartition_LIST* used_parts,
503 WorkingPartSet_LIST* working_set_list) {
506 WorkingPartSet_LIST work_src;
507 WorkingPartSet_IT src_it(&work_src);
508 src_it.add_list_after(working_set_list);
509 src_it.move_to_first();
510 WorkingPartSet_IT dest_it(working_set_list);
513 BLOCK_LIST completed_blocks;
514 TO_BLOCK_LIST to_blocks;
517 ColPartition_IT col_it(&parts_);
518 for (col_it.mark_cycle_pt(); !col_it.cycled_list(); col_it.forward()) {
521 while (!src_it.empty() &&
522 ((working_set = src_it.data())->column() ==
nullptr ||
526 used_parts, &completed_blocks,
533 dest_it.add_after_then_move(working_set);
534 if (first_new_set ==
nullptr)
535 first_new_set = working_set;
538 working_set = src_it.empty() ? nullptr : src_it.data();
539 if (working_set !=
nullptr &&
542 dest_it.add_after_then_move(src_it.extract());
545 first_new_set =
nullptr;
549 dest_it.add_after_then_move(working_set);
553 while (!src_it.empty()) {
554 working_set = src_it.extract();
556 used_parts, &completed_blocks,
563 dest_it.add_after_then_move(working_set);
564 if (first_new_set ==
nullptr)
565 first_new_set = working_set;
575 ColPartition_IT it(&parts_);
576 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
583 int part_right = next_part->
left_key();
584 int gap = part->
KeyWidth(part_left, part_right);
593 ColPartition_IT it(&parts_);
594 tprintf(
"Partition set of %d parts, %d good, coverage=%d+%d"
595 " (%d,%d)->(%d,%d)\n",
596 it.length(), good_column_count_, good_coverage_, bad_coverage_,
598 bounding_box_.
right(), bounding_box_.
top());
599 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
608 void ColPartitionSet::AddPartition(
ColPartition* new_part,
609 ColPartition_IT* it) {
610 AddPartitionCoverageAndBox(*new_part);
612 if (it->data()->left_key() >= new_right)
613 it->add_before_stay_put(new_part);
615 it->add_after_stay_put(new_part);
635 void ColPartitionSet::ComputeCoverage() {
637 ColPartition_IT it(&parts_);
638 good_column_count_ = 0;
641 bounding_box_ =
TBOX();
642 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
643 ColPartition* part = it.data();
644 AddPartitionCoverageAndBox(*part);
650 void ColPartitionSet::AddPartitionCoverageAndBox(
const ColPartition& part) {
651 bounding_box_ += part.bounding_box();
652 int coverage = part.ColumnWidth();
653 if (part.good_width()) {
654 good_coverage_ += coverage;
655 good_column_count_ += 2;
659 if (part.good_column())
660 ++good_column_count_;
661 bad_coverage_ += coverage;