src/textord/colpartitionset.cpp
ColumnSpanningType ColPartitionSet::SpanningType(
    int resolution, int left, int right, int height, 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) ||
        (it.at_first() && part->ColumnContains(left + height, 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) ||
          (it.at_last() && part->ColumnContains(right - height, 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) ||
               (it.at_last() && part->ColumnContains(right - height, 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;
}
// 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.
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.
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 height, 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) ||
        (it.at_first() && part->ColumnContains(left + height, y))) {
      *first_col = col_index;
      if (part->ColumnContains(right, y) ||
          (it.at_last() && part->ColumnContains(right - height, y))) {
        *last_col = col_index;
        return CST_FLOWING;
      }
      if (left_margin <= part->LeftAtY(y)) {
        *first_spanned_col = col_index;
        margin_columns = 1;
      }
    } else if (part->ColumnContains(right, y) ||
               (it.at_last() && part->ColumnContains(right - height, y))) {
      if (*first_col < 0) {
        *first_col = col_index - 1;
      }
      if (right_margin >= part->RightAtY(y)) {
        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)) {
      if (*first_col < 0) {
        *first_col = col_index - 1;
      }
      if (margin_columns == 0) {
        *first_spanned_col = col_index;
      }
      *last_col = col_index;
    } else if (right < part->LeftAtY(y)) {
      *last_col = col_index - 1;
      if (*first_col < 0) {
        *first_col = col_index - 1;
      }
      break;
    }
  }
  if (*first_col < 0) {
    *first_col = col_index - 1; 
  }
  if (*last_col < 0) {
    *last_col = col_index - 1; 
  }
  ASSERT_HOST(*first_col >= 0 && *last_col >= 0);
  ASSERT_HOST(*first_col <= *last_col);
  if (*first_col == *last_col && right - left < kMinColumnWidth * resolution) {
    return CST_NOISE;
  } else if (margin_columns <= 1) {
    if (margin_columns == 1 && parts_.singleton()) {
      return CST_HEADING;
    }
    return CST_PULLOUT;
  }
  return CST_HEADING;
}
ColumnSpanningType ColPartitionSet :: SpanningType ( int resolution , int left , int right , int height , 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 ) || ( it . at_first ( ) && part -> ColumnContains ( left + height , y ) ) ) { * first_col = col_index ; if ( part -> ColumnContains ( right , y ) || ( it . at_last ( ) && part -> ColumnContains ( right - height , y ) ) ) { * last_col = col_index ; return CST_FLOWING ; } if ( left_margin <= part -> LeftAtY ( y ) ) { * first_spanned_col = col_index ; margin_columns = 1 ; } } else if ( part -> ColumnContains ( right , y ) || ( it . at_last ( ) && part -> ColumnContains ( right - height , y ) ) ) { if ( * first_col < 0 ) { * first_col = col_index - 1 ; } if ( right_margin >= part -> RightAtY ( y ) ) { 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 ) ) { if ( * first_col < 0 ) { * first_col = col_index - 1 ; } if ( margin_columns == 0 ) { * first_spanned_col = col_index ; } * last_col = col_index ; } else if ( right < part -> LeftAtY ( y ) ) { * last_col = col_index - 1 ; if ( * first_col < 0 ) { * first_col = col_index - 1 ; } break ; } } if ( * first_col < 0 ) { * first_col = col_index - 1 ; } if ( * last_col < 0 ) { * last_col = col_index - 1 ; } ASSERT_HOST ( * first_col >= 0 && * last_col >= 0 ) ; ASSERT_HOST ( * first_col <= * last_col ) ; if ( * first_col == * last_col && right - left < kMinColumnWidth * resolution ) { return CST_NOISE ; } else if ( margin_columns <= 1 ) { if ( margin_columns == 1 && parts_ . singleton ( ) ) { return CST_HEADING ; } return CST_PULLOUT ; } return CST_HEADING ; }
Return the ColumnSpanningType that best explains the columns overlapped
by the given coords(left,right,y), with the given margins.
Return the ColumnSpanningType that best explains the columns overlapped by the given coords ( left right y ) with the given margins .
// 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. // Both within a single column. // It completely spans this column. // It started in-between. // It completely spans this column. // Neither left nor right are contained within, so it spans this // column. // It started in between the previous column and the current column. // We have gone past the end. // It must lie completely between columns =>noise. // The last in-between. // The last in-between. // Neither end was in a column, and it didn't span any, so it lies // entirely between columns, therefore noise. // An exception for headings that stick outside of single-column text. // 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. // Its margins went to the edges of first and last columns => heading.