#include "workingpartset.h"
#include "colpartition.h"
namespace tesseract {
void WorkingPartSet::AddPartition(ColPartition *part) {
ColPartition *partner = part->SingletonPartner(true);
if (partner != nullptr) {
ASSERT_HOST(partner->SingletonPartner(false) == part);
}
if (latest_part_ == nullptr || partner == nullptr) {
part_it_.move_to_last();
} else if (latest_part_->SingletonPartner(false) != part) {
for (part_it_.move_to_first(); !part_it_.at_last() && part_it_.data() != partner;
part_it_.forward()) {
;
}
}
part_it_.add_after_then_move(part);
latest_part_ = part;
}
void WorkingPartSet::ExtractCompletedBlocks(const ICOORD &bleft, const ICOORD &tright,
int resolution, ColPartition_LIST *used_parts,
BLOCK_LIST *blocks, TO_BLOCK_LIST *to_blocks) {
MakeBlocks(bleft, tright, resolution, used_parts);
BLOCK_IT block_it(blocks);
block_it.move_to_last();
block_it.add_list_after(&completed_blocks_);
TO_BLOCK_IT to_block_it(to_blocks);
to_block_it.move_to_last();
to_block_it.add_list_after(&to_blocks_);
}
void WorkingPartSet::InsertCompletedBlocks(BLOCK_LIST *blocks, TO_BLOCK_LIST *to_blocks) {
BLOCK_IT block_it(&completed_blocks_);
block_it.add_list_before(blocks);
TO_BLOCK_IT to_block_it(&to_blocks_);
to_block_it.add_list_before(to_blocks);
}
void WorkingPartSet::MakeBlocks(const ICOORD &bleft, const ICOORD &tright, int resolution,
ColPartition_LIST *used_parts) {
part_it_.move_to_first();
while (!part_it_.empty()) {
ColPartition_LIST block_parts;
ColPartition_IT block_it(&block_parts);
ColPartition *next_part = nullptr;
bool text_block = false;
do {
ColPartition *part = part_it_.extract();
if (part->blob_type() == BRT_UNKNOWN || (part->IsTextType() && part->type() != PT_TABLE)) {
text_block = true;
}
part->set_working_set(nullptr);
part_it_.forward();
block_it.add_after_then_move(part);
next_part = part->SingletonPartner(false);
if (part_it_.empty() || next_part != part_it_.data()) {
next_part = nullptr;
}
if (next_part == nullptr && !part_it_.empty()) {
ColPartition *next_block_part = part_it_.data();
const TBOX &part_box = part->bounding_box();
const TBOX &next_box = next_block_part->bounding_box();
PolyBlockType type = part->type(), next_type = next_block_part->type();
if (ColPartition::TypesSimilar(type, next_type) && !part->IsLineType() &&
!next_block_part->IsLineType() && next_box.bottom() <= part_box.top() &&
(text_block || part_box.bottom() <= next_box.top())) {
next_part = next_block_part;
}
}
} while (!part_it_.empty() && next_part != nullptr);
if (!text_block) {
TO_BLOCK *to_block = ColPartition::MakeBlock(bleft, tright, &block_parts, used_parts);
if (to_block != nullptr) {
TO_BLOCK_IT to_block_it(&to_blocks_);
to_block_it.add_to_end(to_block);
BLOCK_IT block_it(&completed_blocks_);
block_it.add_to_end(to_block->block);
}
} else {
ColPartition::LineSpacingBlocks(bleft, tright, resolution, &block_parts, used_parts,
&completed_blocks_, &to_blocks_);
}
}
part_it_.set_to_list(&part_set_);
latest_part_ = nullptr;
ASSERT_HOST(completed_blocks_.length() == to_blocks_.length());
}
}