// Display the edges of the columns at the given y coords. void ColPartitionSet::DisplayColumnEdges(int y_bottom, int y_top, ScrollView* win) { #ifndef GRAPHICS_DISABLED ColPartition_IT it(&parts_); for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) { ColPartition* part = it.data(); 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 // GRAPHICS_DISABLED }
// 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); } }
// Return the ColumnSpanningType 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 spanned column. // Column indices are 2n + 1 for real columns (0 based) and even values // represent the gaps in between columns, with 0 being left of the leftmost. // resolution refers to the ppi resolution of the image. ColumnSpanningType ColPartitionSet::SpanningType(int resolution, int left, int right, int y, int left_margin, int right_margin, int* first_col, int* last_col, int* first_spanned_col) { *first_col = -1; *last_col = -1; *first_spanned_col = -1; int margin_columns = 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; return CST_FLOWING; } if (left_margin <= part->LeftAtY(y)) { // It completely spans this column. *first_spanned_col = col_index; margin_columns = 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 (margin_columns == 0) *first_spanned_col = col_index; ++margin_columns; } *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 (*first_col < 0) { // It started in between the previous column and the current column. *first_col = col_index - 1; } if (margin_columns == 0) *first_spanned_col = col_index; *last_col = col_index; } 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 (*first_col == *last_col && right - left < kMinColumnWidth * resolution) { // Neither end was in a column, and it didn't span any, so it lies // entirely between columns, therefore noise. return CST_NOISE; } else if (margin_columns <= 1) { // An exception for headings that stick outside of single-column text. if (margin_columns == 1 && parts_.singleton()) { return CST_HEADING; } // It is a pullout, as left and right were not in the same column, but // it doesn't go to the edge of its start and end. return CST_PULLOUT; } // Its margins went to the edges of first and last columns => heading. return CST_HEADING; }