blob: 668a58f76a3094469e06b33903cdac11a173b2e7 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////
// File: colpartitionset.h
// Description: Class to hold a list of ColPartitions of the page that
// correspond roughly to columns.
// Author: Ray Smith
// Created: Thu Aug 14 10:50: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.
//
///////////////////////////////////////////////////////////////////////
#ifndef TESSERACT_TEXTORD_COLPARTITIONSET_H__
#define TESSERACT_TEXTORD_COLPARTITIONSET_H__
#include "colpartition.h" // For ColPartition_LIST.
#include "genericvector.h" // For GenericVector.
#include "rect.h" // For TBOX.
#include "tabvector.h" // For BLOBNBOX_CLIST.
namespace tesseract {
class WorkingPartSet_LIST;
class ColSegment_LIST;
class ColPartitionSet;
typedef GenericVector<ColPartitionSet*> PartSetVector;
// ColPartitionSet is a class that holds a list of ColPartitions.
// Its main use is in holding a candidate partitioning of the width of the
// image into columns, where each member ColPartition is a single column.
// ColPartitionSets are used in building the column layout of a page.
class ColPartitionSet : public ELIST_LINK {
public:
ColPartitionSet() {
}
explicit ColPartitionSet(ColPartition_LIST* partitions);
explicit ColPartitionSet(ColPartition* partition);
~ColPartitionSet();
// Simple accessors.
const TBOX& bounding_box() const {
return bounding_box_;
}
bool Empty() {
return parts_.empty();
}
int ColumnCount() {
return parts_.length();
}
// Return an element of the parts_ list from its index.
ColPartition* GetColumnByIndex(int index);
// Return the ColPartition that contains the given coords, if any, else NULL.
ColPartition* ColumnContaining(int x, int y);
// Return the bounding boxes of columns at the given y-range
void GetColumnBoxes(int y_bottom, int y_top, ColSegment_LIST *segments);
// Move the parts to the output list, giving up ownership.
void ReturnParts(ColPartition_LIST* 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 MergeOverlaps(ColPartitionSet* other, WidthCallback* cb);
// Attempt to improve this by adding partitions or expanding partitions.
void ImproveColumnCandidate(WidthCallback* cb, PartSetVector* src_sets);
// If this set is good enough to represent a new partitioning into columns,
// add it to the vector of sets, otherwise delete it.
void AddToColumnSetsIfUnique(PartSetVector* column_sets, WidthCallback* cb);
// Return true if the partitions in other are all compatible with the columns
// in this.
bool CompatibleColumns(bool debug, ColPartitionSet* other, WidthCallback* cb);
// Return true if this ColPartitionSet makes a legal column candidate by
// having legal individual partitions and non-overlapping adjacent pairs.
bool LegalColumnCandidate();
// Return a copy of this. If good_only will only copy the Good ColPartitions.
ColPartitionSet* Copy(bool good_only);
// Display the edges of the columns at the given y coords.
void DisplayColumnEdges(int y_bottom, int y_top, ScrollView* win);
// 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 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);
// 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 ChangeWorkColumns(const ICOORD& bleft, const ICOORD& tright,
int resolution, ColPartition_LIST* used_parts,
WorkingPartSet_LIST* working_set);
// Accumulate the widths and gaps into the given variables.
void AccumulateColumnWidthsAndGaps(int* total_width, int* width_samples,
int* total_gap, int* gap_samples);
// Provide debug output for this ColPartitionSet and all the ColPartitions.
void Print();
private:
// Add the given partition to the list in the appropriate place.
void AddPartition(ColPartition* new_part, ColPartition_IT* it);
// Compute the coverage and good column count.
void ComputeCoverage();
// The partitions in this column candidate.
ColPartition_LIST parts_;
// The number of partitions that have a frequent column width.
int good_column_count_;
// Total width of all the ColPartitions.
int total_coverage_;
// Bounding box of all partitions in the set.
TBOX bounding_box_;
};
ELISTIZEH(ColPartitionSet)
} // namespace tesseract.
#endif // TESSERACT_TEXTORD_COLPARTITION_H__