///////////////////////////////////////////////////////////////////////
// File:        colpartitionset.cpp
// Description: Class to hold a list of ColPartitions of the page that
//              correspond roughly to columns.
// Author:      Ray Smith
// Created:     Thu Aug 14 10:54:01 PDT 2008
//
// (C) Copyright 2008, Google Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////

#include "colpartitionset.h"
#include "ndminx.h"
#include "workingpartset.h"
#include "tablefind.h"

namespace tesseract {

ELISTIZE(ColPartitionSet)

ColPartitionSet::ColPartitionSet(ColPartition_LIST* partitions) {
  ColPartition_IT it(&parts_);
  it.add_list_after(partitions);
  ComputeCoverage();
}

ColPartitionSet::ColPartitionSet(ColPartition* part) {
  ColPartition_IT it(&parts_);
  it.add_after_then_move(part);
  ComputeCoverage();
}

ColPartitionSet::~ColPartitionSet() {
}

// Return an element of the parts_ list from its index.
ColPartition* ColPartitionSet::GetColumnByIndex(int index) {
  ColPartition_IT it(&parts_);
  it.mark_cycle_pt();
  for (int i = 0; i < index && !it.cycled_list(); ++i, it.forward());
  if (it.cycled_list())
    return NULL;
  return it.data();
}

// Return the ColPartition that contains the given coords, if any, else NULL.
ColPartition* ColPartitionSet::ColumnContaining(int x, int y) {
  ColPartition_IT it(&parts_);
  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
    ColPartition* part = it.data();
    if (part->ColumnContains(x, y))
      return part;
  }
  return NULL;
}

// Insert the ColPartitions in our list into the given grid.
void ColPartitionSet::ReturnParts(ColPartition_LIST* parts) {
  ColPartition_IT it(parts);
  it.add_list_before(&parts_);
}

// Merge any significantly overlapping partitions within the this and other,
// and unique the boxes so that no two partitions use the same box.
// Return true if any changes were made to either set.
bool ColPartitionSet::MergeOverlaps(ColPartitionSet* other, WidthCallback* cb) {
  bool debug = TabFind::WithinTestRegion(2, bounding_box_.left(),
                                         bounding_box_.bottom()) ||
               TabFind::WithinTestRegion(2, other->bounding_box_.left(),
                                         other->bounding_box_.bottom());
  if (debug) {
    tprintf("Considering merge on:\n");
    Print();
    other->Print();
  }
  ColPartition_IT it1(&parts_);
  ColPartition_IT it2(&other->parts_);
  bool any_merged = false;
  it1.mark_cycle_pt();
  it2.mark_cycle_pt();
  // Iterate the two lists in parallel, using the fact that they are
  // sorted by x-coord to keep the iterators in sync.
  while (!it1.cycled_list() && !it2.cycled_list()) {
    any_merged = false;
    ColPartition* part1 = it1.data();
    ColPartition* part2 = it2.data();
    if (debug) {
      tprintf("Vover=%d, HOver=%d, Hcompatible=%d, typesmatch=%d\n",
              part1->VOverlaps(*part2), part1->HOverlaps(*part2),
              part1->HCompatible(*part2), part1->TypesMatch(*part2));
    }
    if (part1->VOverlaps(*part2) &&
        part1->HCompatible(*part2) && part1->TypesMatch(*part2)) {
      // Partitions seem to be mergeable, so absorb part1 into part2.
      part1->Absorb(it2.extract(), cb);
      any_merged = true;
      it1.forward();
      it2.forward();
    } else if (part1->HOverlaps(*part2) && part1->TypesMatch(*part2) &&
               part1->Unique(part2, cb)) {
      // Unique moved some boxes, so check to see in either partition was
      // left empty. If not, any_merged is not set true.
      if (part1->IsEmpty()) {
        any_merged = true;
        delete it1.extract();
        it1.forward();
        continue;
      }
      if (part2->IsEmpty()) {
        any_merged = true;
        delete it2.extract();
        it2.forward();
        continue;
      }
    }
    if (!any_merged) {
      // Move on the iterator that point to the leftmost partition.
      if (part1->IsLeftOf(*part2)) {
        it1.forward();
      } else {
        it2.forward();
      }
    }
  }
  if (any_merged) {
    ComputeCoverage();
    other->ComputeCoverage();
  }
  return any_merged;
}

// Attempt to improve this by adding partitions or expanding partitions.
void ColPartitionSet::ImproveColumnCandidate(WidthCallback* cb,
                                             PartSetVector* src_sets) {
  int set_size = src_sets->size();
  // Iterate over the provided column sets, as each one may have something
  // to improve this.
  for (int i = 0; i < set_size; ++i) {
    ColPartitionSet* column_set = src_sets->get(i);
    if (column_set == NULL)
      continue;
    // Iterate over the parts in this and column_set, adding bigger or
    // new parts in column_set to this.
    ColPartition_IT part_it(&parts_);
    ASSERT_HOST(!part_it.empty());
    int prev_right = MIN_INT32;
    part_it.mark_cycle_pt();
    ColPartition_IT col_it(&column_set->parts_);
    for (col_it.mark_cycle_pt(); !col_it.cycled_list(); col_it.forward()) {
      ColPartition* col_part = col_it.data();
      if (col_part->blob_type() < BRT_UNKNOWN)
        continue;  // Ignore image partitions.
      int col_left = col_part->left_key();
      int col_right = col_part->right_key();
      // Sync-up part_it (in this) so it matches the col_part in column_set.
      ColPartition* part = part_it.data();
      while (!part_it.at_last() && part->right_key() < col_left) {
        prev_right = part->right_key();
        part_it.forward();
        part = part_it.data();
      }
      int part_left = part->left_key();
      int part_right = part->right_key();
      if (part_right < col_left || col_right < part_left) {
        // There is no overlap so this is a new partition.
        AddPartition(col_part->ShallowCopy(), &part_it);
        continue;
      }
      // Check the edges of col_part to see if they can improve part.
      bool part_width_ok = cb->Run(part->KeyWidth(part_left, part_right));
      if (col_left < part_left && col_left > prev_right) {
        // The left edge of the column is better and it doesn't overlap,
        // so we can potentially expand it.
        int col_box_left = col_part->BoxLeftKey();
        bool tab_width_ok = cb->Run(part->KeyWidth(col_left, part_right));
        bool box_width_ok = cb->Run(part->KeyWidth(col_box_left, part_right));
        if (tab_width_ok || (!part_width_ok )) {
          // The tab is leaving the good column metric at least as good as
          // it was before, so use the tab.
          part->CopyLeftTab(*col_part, false);
          part->SetColumnGoodness(cb);
        } else if (col_box_left < part_left &&
                   (box_width_ok || !part_width_ok)) {
          // The box is leaving the good column metric at least as good as
          // it was before, so use the box.
          part->CopyLeftTab(*col_part, true);
          part->SetColumnGoodness(cb);
        }
        part_left = part->left_key();
      }
      if (col_right > part_right &&
          (part_it.at_last() ||
           part_it.data_relative(1)->left_key() > col_right)) {
        // The right edge is better, so we can possibly expand it.
        int col_box_right = col_part->BoxRightKey();
        bool tab_width_ok = cb->Run(part->KeyWidth(part_left, col_right));
        bool box_width_ok = cb->Run(part->KeyWidth(part_left, col_box_right));
        if (tab_width_ok || (!part_width_ok )) {
          // The tab is leaving the good column metric at least as good as
          // it was before, so use the tab.
          part->CopyRightTab(*col_part, false);
          part->SetColumnGoodness(cb);
        } else if (col_box_right > part_right &&
                   (box_width_ok || !part_width_ok)) {
          // The box is leaving the good column metric at least as good as
          // it was before, so use the box.
          part->CopyRightTab(*col_part, true);
          part->SetColumnGoodness(cb);
        }
      }
    }
  }
  ComputeCoverage();
}

// If this set is good enough to represent a new partitioning into columns,
// add it to the vector of sets, otherwise delete it.
void ColPartitionSet::AddToColumnSetsIfUnique(PartSetVector* column_sets,
                                              WidthCallback* cb) {
  bool debug = TabFind::WithinTestRegion(2, bounding_box_.left(),
                                         bounding_box_.bottom());
  if (debug) {
    tprintf("Considering new column candidate:\n");
    Print();
  }
  if (!LegalColumnCandidate()) {
    if (debug) {
      tprintf("Not a legal column candidate:\n");
      Print();
    }
    delete this;
    return;
  }
  for (int i = 0; i < column_sets->size(); ++i) {
    ColPartitionSet* columns = column_sets->get(i);
    // In ordering the column set candidates, total_coverage_ is king,
    // followed by good_column_count_ and then total column_count.
    bool better = total_coverage_ > columns->total_coverage_;
    if (total_coverage_ == columns->total_coverage_) {
      better = good_column_count_ > columns->good_column_count_;
      if (good_column_count_ == columns->good_column_count_) {
          better = parts_.length() > columns->parts_.length();
      }
    }
    if (better) {
      // The new one is better so add it.
      if (debug)
        tprintf("Good one\n");
      column_sets->insert(this, i);
      return;
    }
    if (columns->CompatibleColumns(false, this, cb)) {
      if (debug)
        tprintf("Duplicate\n");
      delete this;
      return;  // It is not unique.
    }
  }
  if (debug)
    tprintf("Added to end\n");
  column_sets->push_back(this);
}

// Return true if the partitions in other are all compatible with the columns
// in this.
bool ColPartitionSet::CompatibleColumns(bool debug, ColPartitionSet* other,
                                        WidthCallback* cb) {
  if (debug) {
    tprintf("CompatibleColumns testing compability\n");
    Print();
    other->Print();
  }
  if (other->parts_.empty()) {
    if (debug)
      tprintf("CompatibleColumns true due to empty other\n");
    return true;
  }
  ColPartition_IT it(&other->parts_);
  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
    ColPartition* part = it.data();
    if (part->blob_type() < BRT_UNKNOWN) {
      if (debug) {
        tprintf("CompatibleColumns ignoring image partition\n");
        part->Print();
      }
      continue;  // Image partitions are irrelevant to column compability.
    }
    int y = part->MidY();
    int left = part->bounding_box().left();
    int right = part->bounding_box().right();
    ColPartition* left_col = ColumnContaining(left, y);
    ColPartition* right_col = ColumnContaining(right, y);
    if (right_col == NULL || left_col == NULL) {
      if (debug) {
        tprintf("CompatibleColumns false due to partition edge outside\n");
        part->Print();
      }
      return false;  // A partition edge lies outside of all columns
    }
    if (right_col != left_col && cb->Run(right - left)) {
      if (debug) {
        tprintf("CompatibleColumns false due to good width in multiple cols\n");
        part->Print();
      }
      return false;  // Partition with a good width must be in a single column.
    }

    ColPartition_IT it2= it;
    while (!it2.at_last()) {
      it2.forward();
      ColPartition* next_part = it2.data();
      if (next_part->blob_type() <= BRT_UNKNOWN)
        continue;  // Image partitions are irrelevant.
      int next_left = next_part->bounding_box().left();
      if (next_left == right) {
        break;  // They share the same edge, so one must be a pull-out.
      }
      // Search to see if right and next_left fall within a single column.
      ColPartition* next_left_col = ColumnContaining(next_left, y);
      if (right_col == next_left_col) {
        // There is a column break in this column.
        // Check for the difference between different column layout and
        // a pull-out block.
        int part_box_width = part->bounding_box().width();
        int part_margin_width = part->right_margin() - part->left_margin();
        int next_box_width = next_part->bounding_box().width();
        int next_margin_width = next_part->right_margin() -
                                next_part->left_margin();
        int next_right = next_part->bounding_box().right();
        if (part_box_width < next_margin_width &&
            next_box_width < part_margin_width) {
          if (debug) {
            tprintf("CompatibleColumns false due to equal sized columns\n");
            tprintf("part1 %d-%d = %d, part2 %d-%d = %d\n",
                    left, right, part->ColumnWidth(),
                    next_left, next_right, next_part->ColumnWidth());
            right_col->Print();
          }
          return false;  // Must be a new column layout as they are equal size.
        }
        ColPartition* next_right_col = ColumnContaining(next_right, y);
        if (left_col == right_col && next_right_col == next_left_col) {
          // Column completely contains both. Not allowed.
          if (debug) {
            tprintf("CompatibleColumns false due to containing 2 partitions\n");
            tprintf("part1 %d-%d, part2 %d-%d\n",
                    left, right, next_left, next_right);
            right_col->Print();
          }
          return false;
        }
      }
      break;
    }
  }
  if (debug)
    tprintf("CompatibleColumns true!\n");
  return true;
}

// Return true if this ColPartitionSet makes a legal column candidate by
// having legal individual partitions and non-overlapping adjacent pairs.
bool ColPartitionSet::LegalColumnCandidate() {
  ColPartition_IT it(&parts_);
  if (it.empty())
    return false;
  int any_text_parts = false;
  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
    ColPartition* part = it.data();
    if (part->blob_type() > BRT_UNKNOWN) {
      if (!part->IsLegal())
        return false;  // Individual partition is illegal.
      any_text_parts = true;
    }
    if (!it.at_last()) {
      ColPartition* next_part = it.data_relative(1);
      if (next_part->left_key() < part->right_key()) {
        return false;
      }
    }
  }
  return any_text_parts;
}

// Return a copy of this. If good_only will only copy the Good ColPartitions.
ColPartitionSet* ColPartitionSet::Copy(bool good_only) {
  ColPartition_LIST copy_parts;
  ColPartition_IT src_it(&parts_);
  ColPartition_IT dest_it(&copy_parts);
  for (src_it.mark_cycle_pt(); !src_it.cycled_list(); src_it.forward()) {
    ColPartition* part = src_it.data();
    if (part->blob_type() > BRT_UNKNOWN &&
        (!good_only || part->good_width() || part->good_column()))
      dest_it.add_after_then_move(part->ShallowCopy());
  }
  if (dest_it.empty())
    return NULL;
  return new ColPartitionSet(&copy_parts);
}

// Return the bounding boxes of columns at the given y-range
void ColPartitionSet::GetColumnBoxes(int y_bottom, int y_top,
                                     ColSegment_LIST *segments) {
  ColPartition_IT it(&parts_);
  ColSegment_IT col_it(segments);
  col_it.move_to_last();
  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
    ColPartition* part = it.data();
    ICOORD bot_left(part->LeftAtY(y_top), y_bottom);
    ICOORD top_right(part->RightAtY(y_bottom), y_top);
    ColSegment *col_seg = new ColSegment();
    col_seg->InsertBox(TBOX(bot_left, top_right));
    col_it.add_after_then_move(col_seg);
  }
}

// Display the edges of the columns at the given y coords.
void ColPartitionSet::DisplayColumnEdges(int y_bottom, int y_top,
                                         ScrollView* win) {
  ColPartition_IT it(&parts_);
  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
    ColPartition* part = it.data();
#ifndef GRAPHICS_DISABLED
    win->Line(part->LeftAtY(y_top), y_top, part->LeftAtY(y_bottom), y_bottom);
    win->Line(part->RightAtY(y_top), y_top, part->RightAtY(y_bottom), y_bottom);
#endif
  }
}

// Return the PolyBlockType that best explains the columns overlapped
// by the given coords(left,right,y), with the given margins.
// Also return the first and last column index touched by the coords and
// the leftmost and rightmost spanned columns.
// Column indices are 2n + 1 for real colums (0 based) and even values
// represent the gaps in between columns, with 0 being left of the leftmost.
PolyBlockType ColPartitionSet::SpanningType(BlobRegionType type,
                                            int left, int right, int y,
                                            int left_margin, int right_margin,
                                            int* first_col, int* last_col,
                                            int* first_spanned_col,
                                            int* last_spanned_col) {
  *first_col = -1;
  *last_col = -1;
  *first_spanned_col = -1;
  *last_spanned_col = -1;
  int columns_spanned = 0;
  ColPartition_IT it(&parts_);
  int col_index = 1;
  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward(), col_index += 2) {
    ColPartition* part = it.data();
    if (part->ColumnContains(left, y)) {
      // In the default case, first_col is set, but columns_spanned remains
      // zero, so first_col will get reset in the first column genuinely
      // spanned, but we can tell the difference from a noise partition
      // that touches no column.
      *first_col = col_index;
      if (part->ColumnContains(right, y)) {
        // Both within a single column.
        *last_col = col_index;
        if (type == BRT_HLINE)
          return PT_FLOWING_LINE;
        else if (type > BRT_UNKNOWN)
          return type == BRT_VERT_TEXT ? PT_VERTICAL_TEXT : PT_FLOWING_TEXT;
        else
          return PT_FLOWING_IMAGE;
      }
      if (left_margin <= part->LeftAtY(y)) {
        // It completely spans this column.
        *last_col = col_index;
        *first_spanned_col = col_index;
        *last_spanned_col = col_index;
        columns_spanned = 1;
      }
    } else if (part->ColumnContains(right, y)) {
      if (*first_col < 0) {
        // It started in-between.
        *first_col = col_index - 1;
      }
      if (right_margin >= part->RightAtY(y)) {
        // It completely spans this column.
        if (columns_spanned == 0)
          *first_spanned_col = col_index;
        *last_spanned_col = col_index;
        ++columns_spanned;
      }
      *last_col = col_index;
      break;
    } else if (left < part->LeftAtY(y) && right > part->RightAtY(y)) {
      // Neither left nor right are contained within, so it spans this
      // column.
      if (columns_spanned == 0) {
        *first_col = col_index;
        *first_spanned_col = col_index;
      }
      *last_col = col_index;
      *last_spanned_col = col_index;
      ++columns_spanned;
    } else if (right < part->LeftAtY(y)) {
      // We have gone past the end.
      *last_col = col_index - 1;
      if (*first_col < 0) {
        // It must lie completely between columns =>noise.
        *first_col = col_index - 1;
      }
      break;
    }
  }
  if (*first_col < 0)
    *first_col = col_index - 1;  // The last in-between.
  if (*last_col < 0)
    *last_col = col_index - 1;  // The last in-between.
  ASSERT_HOST(*first_col >= 0 && *last_col >= 0);
  ASSERT_HOST(*first_col <= *last_col);
  if (columns_spanned == 0 && *first_col == *last_col) {
    // Neither end was in a column, and it didn't span any, so it lies
    // entirely between columns, therefore noise.
    return PT_NOISE;
  } else if (columns_spanned <= 1) {
    // It is a pullout, as left and right were not in the same column.
    if (type == BRT_HLINE)
      return PT_PULLOUT_LINE;
    else if (type > BRT_UNKNOWN)
      return type == BRT_VERT_TEXT ? PT_VERTICAL_TEXT : PT_PULLOUT_TEXT;
    else
      return PT_PULLOUT_IMAGE;
  }
  // It completely spanned more than one column. Always a heading.
  if (type == BRT_HLINE)
    return PT_HEADING_LINE;
  else if (type > BRT_UNKNOWN)
    return type == BRT_VERT_TEXT ? PT_VERTICAL_TEXT : PT_HEADING_TEXT;
  else
    return PT_HEADING_IMAGE;
}

// The column_set has changed. Close down all in-progress WorkingPartSets in
// columns that do not match and start new ones for the new columns in this.
// As ColPartitions are turned into BLOCKs, the used ones are put in
// used_parts, as they still need to be referenced in the grid.
void ColPartitionSet::ChangeWorkColumns(const ICOORD& bleft,
                                        const ICOORD& tright,
                                        int resolution,
                                        ColPartition_LIST* used_parts,
                                        WorkingPartSet_LIST* working_set_list) {
  // Move the input list to a temporary location so we can delete its elements
  // as we add them to the output working_set.
  WorkingPartSet_LIST work_src;
  WorkingPartSet_IT src_it(&work_src);
  src_it.add_list_after(working_set_list);
  src_it.move_to_first();
  WorkingPartSet_IT dest_it(working_set_list);
  // Completed blocks and to_blocks are accumulated and given to the first new
  // one  whenever we keep a column, or at the end.
  BLOCK_LIST completed_blocks;
  TO_BLOCK_LIST to_blocks;
  WorkingPartSet* first_new_set = NULL;
  WorkingPartSet* working_set = NULL;
  ColPartition_IT col_it(&parts_);
  for (col_it.mark_cycle_pt(); !col_it.cycled_list(); col_it.forward()) {
    ColPartition* column = col_it.data();
    // Any existing column to the left of column is completed.
    while (!src_it.empty() &&
           ((working_set = src_it.data())->column() == NULL ||
            working_set->column()->right_key() <= column->left_key())) {
      src_it.extract();
      working_set->ExtractCompletedBlocks(bleft, tright, resolution,
                                          used_parts, &completed_blocks,
                                          &to_blocks);
      delete working_set;
      src_it.forward();
    }
    // Make a new between-column WorkingSet for before the current column.
    working_set = new WorkingPartSet(NULL);
    dest_it.add_after_then_move(working_set);
    if (first_new_set == NULL)
      first_new_set = working_set;
    // A matching column gets to stay, and first_new_set gets all the
    // completed_sets.
    working_set = src_it.empty() ? NULL : src_it.data();
    if (working_set != NULL &&
        working_set->column()->MatchingColumns(*column)) {
      working_set->set_column(column);
      dest_it.add_after_then_move(src_it.extract());
      src_it.forward();
      first_new_set->InsertCompletedBlocks(&completed_blocks, &to_blocks);
      first_new_set = NULL;
    } else {
      // Just make a new working set for the current column.
      working_set = new WorkingPartSet(column);
      dest_it.add_after_then_move(working_set);
    }
  }
  // Complete any remaining src working sets.
  while (!src_it.empty()) {
    working_set = src_it.extract();
    working_set->ExtractCompletedBlocks(bleft, tright, resolution,
                                        used_parts, &completed_blocks,
                                        &to_blocks);
    delete working_set;
    src_it.forward();
  }
  // Make a new between-column WorkingSet for after the last column.
  working_set = new WorkingPartSet(NULL);
  dest_it.add_after_then_move(working_set);
  if (first_new_set == NULL)
    first_new_set = working_set;
  // The first_new_set now gets any accumulated completed_parts/blocks.
  first_new_set->InsertCompletedBlocks(&completed_blocks, &to_blocks);
}

// Accumulate the widths and gaps into the given variables.
void ColPartitionSet::AccumulateColumnWidthsAndGaps(int* total_width,
                                                    int* width_samples,
                                                    int* total_gap,
                                                    int* gap_samples) {
  ColPartition_IT it(&parts_);
  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
    ColPartition* part = it.data();
    *total_width += part->ColumnWidth();
    ++*width_samples;
    if (!it.at_last()) {
      ColPartition* next_part = it.data_relative(1);
      int gap = part->KeyWidth(part->right_key(), next_part->left_key());
      *total_gap += gap;
      ++*gap_samples;
    }
  }
}

// Provide debug output for this ColPartitionSet and all the ColPartitions.
void ColPartitionSet::Print() {
  ColPartition_IT it(&parts_);
  tprintf("Partition set of %d parts, %d good, coverage=%d (%d,%d)->(%d,%d)\n",
          it.length(), good_column_count_, total_coverage_,
          bounding_box_.left(), bounding_box_.bottom(),
          bounding_box_.right(), bounding_box_.top());
  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
    ColPartition* part = it.data();
    part->Print();
  }
}

// PRIVATE CODE.

// Add the given partition to the list in the appropriate place.
void ColPartitionSet::AddPartition(ColPartition* new_part,
                                   ColPartition_IT* it) {
  bounding_box_ += new_part->bounding_box();
  if (new_part->good_column() || new_part->good_width()) {
    total_coverage_ += new_part->ColumnWidth();
    ++good_column_count_;
    if (new_part->good_width())
      ++good_column_count_;
  }
  int new_right = new_part->right_key();
  if (it->data()->left_key() >= new_right)
    it->add_before_stay_put(new_part);
  else
    it->add_after_stay_put(new_part);
}

// Compute the coverage and good column count.
void ColPartitionSet::ComputeCoverage() {
  // Count the number of good columns and sum their width.
  ColPartition_IT it(&parts_);
  good_column_count_ = 0;
  total_coverage_ = 0;
  bounding_box_ = TBOX();
  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
    ColPartition* part = it.data();
    bounding_box_ += part->bounding_box();
    if (part->good_column() || part->good_width()) {
      total_coverage_ += part->ColumnWidth();
      ++good_column_count_;
      if (part->good_width())
        ++good_column_count_;
    }
  }
}

}  // namespace tesseract.
