src/textord/imagefind.cpp
static void CutChunkFromParts(const TBOX &box, const TBOX &im_box, const FCOORD &rotation,
                              const FCOORD &rerotation, Image pix, ColPartition_LIST *part_list) {
  ASSERT_HOST(!part_list->empty());
  ColPartition_IT part_it(part_list);
  do {
    ColPartition *part = part_it.data();
    TBOX part_box = part->bounding_box();
    if (part_box.overlap(box)) {
      // This part must be cut and replaced with the remains. There are
      // up to 4 pieces to be made. Start with the first one and use
      // add_before_stay_put. For each piece if it has no black pixels
      // left, just don't make the box.
      // Above box.
      if (box.top() < part_box.top()) {
        TBOX slice(part_box);
        slice.set_bottom(box.top());
        if (ImageFind::CountPixelsInRotatedBox(slice, im_box, rerotation, pix) > 0) {
          AttemptToShrinkBox(rotation, rerotation, im_box, pix, &slice);
          part_it.add_before_stay_put(
              ColPartition::FakePartition(slice, PT_UNKNOWN, BRT_POLYIMAGE, BTFT_NONTEXT));
        }
      }
      // Left of box.
      if (box.left() > part_box.left()) {
        TBOX slice(part_box);
        slice.set_right(box.left());
        if (box.top() < part_box.top()) {
          slice.set_top(box.top());
        }
        if (box.bottom() > part_box.bottom()) {
          slice.set_bottom(box.bottom());
        }
        if (ImageFind::CountPixelsInRotatedBox(slice, im_box, rerotation, pix) > 0) {
          AttemptToShrinkBox(rotation, rerotation, im_box, pix, &slice);
          part_it.add_before_stay_put(
              ColPartition::FakePartition(slice, PT_UNKNOWN, BRT_POLYIMAGE, BTFT_NONTEXT));
        }
      }
      // Right of box.
      if (box.right() < part_box.right()) {
        TBOX slice(part_box);
        slice.set_left(box.right());
        if (box.top() < part_box.top()) {
          slice.set_top(box.top());
        }
        if (box.bottom() > part_box.bottom()) {
          slice.set_bottom(box.bottom());
        }
        if (ImageFind::CountPixelsInRotatedBox(slice, im_box, rerotation, pix) > 0) {
          AttemptToShrinkBox(rotation, rerotation, im_box, pix, &slice);
          part_it.add_before_stay_put(
              ColPartition::FakePartition(slice, PT_UNKNOWN, BRT_POLYIMAGE, BTFT_NONTEXT));
        }
      }
      // Below box.
      if (box.bottom() > part_box.bottom()) {
        TBOX slice(part_box);
        slice.set_top(box.bottom());
        if (ImageFind::CountPixelsInRotatedBox(slice, im_box, rerotation, pix) > 0) {
          AttemptToShrinkBox(rotation, rerotation, im_box, pix, &slice);
          part_it.add_before_stay_put(
              ColPartition::FakePartition(slice, PT_UNKNOWN, BRT_POLYIMAGE, BTFT_NONTEXT));
        }
      }
      part->DeleteBoxes();
      delete part_it.extract();
    }
    part_it.forward();
  } while (!part_it.at_first());
}
// The meat of cutting a polygonal image around text.
// This function covers the general case of cutting a box out of a box
// as shown:
// Input                               Output
// ------------------------------      ------------------------------
// |   Single input partition   |      | 1 Cut up output partitions |
// |                            |      ------------------------------
// |         ----------         |      ---------           ----------
// |         |  box   |         |      |   2   |   box     |    3   |
// |         |        |         |      |       |  is cut   |        |
// |         ----------         |      ---------   out     ----------
// |                            |      ------------------------------
// |                            |      |   4                        |
// ------------------------------      ------------------------------
// In the context that this function is used, at most 3 of the above output
// boxes will be created, as the overlapping box is never contained by the
// input.
// The above cutting operation is executed for each element of part_list that
// is overlapped by the input box. Each modified ColPartition is replaced
// in place in the list by the output of the cutting operation in the order
// shown above, so iff no holes are ever created, the output will be in
// top-to-bottom order, but in extreme cases, hole creation is possible.
// In such cases, the output order may cause strange block polygons.
// rotation, rerotation, pix and im_box are defined in the large comment above.
The meat of cutting a polygonal image around text.
This function covers the general case of cutting a box out of a box
as shown:
Input                               Output



In the context that this function is used, at most 3 of the above output
boxes will be created, as the overlapping box is never contained by the
input.
The above cutting operation is executed for each element of part_list that
is overlapped by the input box. Each modified ColPartition is replaced
in place in the list by the output of the cutting operation in the order
shown above, so iff no holes are ever created, the output will be in
top-to-bottom order, but in extreme cases, hole creation is possible.
In such cases, the output order may cause strange block polygons.
rotation, rerotation, pix and im_box are defined in the large comment above.
The meat of cutting a polygonal image around text . This function covers the general case of cutting a box out of a box as shown : Input Output In the context that this function is used at most 3 of the above output boxes will be created as the overlapping box is never contained by the input . The above cutting operation is executed for each element of part_list that is overlapped by the input box . Each modified ColPartition is replaced in place in the list by the output of the cutting operation in the order shown above so iff no holes are ever created the output will be in top - to - bottom order but in extreme cases hole creation is possible . In such cases the output order may cause strange block polygons . rotation rerotation pix and im_box are defined in the large comment above .
static void CutChunkFromParts(const TBOX &box, const TBOX &im_box, const FCOORD &rotation,
                              const FCOORD &rerotation, Image pix, ColPartition_LIST *part_list) {
  ASSERT_HOST(!part_list->empty());
  ColPartition_IT part_it(part_list);
  do {
    ColPartition *part = part_it.data();
    TBOX part_box = part->bounding_box();
    if (part_box.overlap(box)) {
      if (box.top() < part_box.top()) {
        TBOX slice(part_box);
        slice.set_bottom(box.top());
        if (ImageFind::CountPixelsInRotatedBox(slice, im_box, rerotation, pix) > 0) {
          AttemptToShrinkBox(rotation, rerotation, im_box, pix, &slice);
          part_it.add_before_stay_put(
              ColPartition::FakePartition(slice, PT_UNKNOWN, BRT_POLYIMAGE, BTFT_NONTEXT));
        }
      }
      if (box.left() > part_box.left()) {
        TBOX slice(part_box);
        slice.set_right(box.left());
        if (box.top() < part_box.top()) {
          slice.set_top(box.top());
        }
        if (box.bottom() > part_box.bottom()) {
          slice.set_bottom(box.bottom());
        }
        if (ImageFind::CountPixelsInRotatedBox(slice, im_box, rerotation, pix) > 0) {
          AttemptToShrinkBox(rotation, rerotation, im_box, pix, &slice);
          part_it.add_before_stay_put(
              ColPartition::FakePartition(slice, PT_UNKNOWN, BRT_POLYIMAGE, BTFT_NONTEXT));
        }
      }
      if (box.right() < part_box.right()) {
        TBOX slice(part_box);
        slice.set_left(box.right());
        if (box.top() < part_box.top()) {
          slice.set_top(box.top());
        }
        if (box.bottom() > part_box.bottom()) {
          slice.set_bottom(box.bottom());
        }
        if (ImageFind::CountPixelsInRotatedBox(slice, im_box, rerotation, pix) > 0) {
          AttemptToShrinkBox(rotation, rerotation, im_box, pix, &slice);
          part_it.add_before_stay_put(
              ColPartition::FakePartition(slice, PT_UNKNOWN, BRT_POLYIMAGE, BTFT_NONTEXT));
        }
      }
      if (box.bottom() > part_box.bottom()) {
        TBOX slice(part_box);
        slice.set_top(box.bottom());
        if (ImageFind::CountPixelsInRotatedBox(slice, im_box, rerotation, pix) > 0) {
          AttemptToShrinkBox(rotation, rerotation, im_box, pix, &slice);
          part_it.add_before_stay_put(
              ColPartition::FakePartition(slice, PT_UNKNOWN, BRT_POLYIMAGE, BTFT_NONTEXT));
        }
      }
      part->DeleteBoxes();
      delete part_it.extract();
    }
    part_it.forward();
  } while (!part_it.at_first());
}
static void CutChunkFromParts ( const TBOX & box , const TBOX & im_box , const FCOORD & rotation , const FCOORD & rerotation , Image pix , ColPartition_LIST * part_list ) { ASSERT_HOST ( ! part_list -> empty ( ) ) ; ColPartition_IT part_it ( part_list ) ; do { ColPartition * part = part_it . data ( ) ; TBOX part_box = part -> bounding_box ( ) ; if ( part_box . overlap ( box ) ) { if ( box . top ( ) < part_box . top ( ) ) { TBOX slice ( part_box ) ; slice . set_bottom ( box . top ( ) ) ; if ( ImageFind :: CountPixelsInRotatedBox ( slice , im_box , rerotation , pix ) > 0 ) { AttemptToShrinkBox ( rotation , rerotation , im_box , pix , & slice ) ; part_it . add_before_stay_put ( ColPartition :: FakePartition ( slice , PT_UNKNOWN , BRT_POLYIMAGE , BTFT_NONTEXT ) ) ; } } if ( box . left ( ) > part_box . left ( ) ) { TBOX slice ( part_box ) ; slice . set_right ( box . left ( ) ) ; if ( box . top ( ) < part_box . top ( ) ) { slice . set_top ( box . top ( ) ) ; } if ( box . bottom ( ) > part_box . bottom ( ) ) { slice . set_bottom ( box . bottom ( ) ) ; } if ( ImageFind :: CountPixelsInRotatedBox ( slice , im_box , rerotation , pix ) > 0 ) { AttemptToShrinkBox ( rotation , rerotation , im_box , pix , & slice ) ; part_it . add_before_stay_put ( ColPartition :: FakePartition ( slice , PT_UNKNOWN , BRT_POLYIMAGE , BTFT_NONTEXT ) ) ; } } if ( box . right ( ) < part_box . right ( ) ) { TBOX slice ( part_box ) ; slice . set_left ( box . right ( ) ) ; if ( box . top ( ) < part_box . top ( ) ) { slice . set_top ( box . top ( ) ) ; } if ( box . bottom ( ) > part_box . bottom ( ) ) { slice . set_bottom ( box . bottom ( ) ) ; } if ( ImageFind :: CountPixelsInRotatedBox ( slice , im_box , rerotation , pix ) > 0 ) { AttemptToShrinkBox ( rotation , rerotation , im_box , pix , & slice ) ; part_it . add_before_stay_put ( ColPartition :: FakePartition ( slice , PT_UNKNOWN , BRT_POLYIMAGE , BTFT_NONTEXT ) ) ; } } if ( box . bottom ( ) > part_box . bottom ( ) ) { TBOX slice ( part_box ) ; slice . set_top ( box . bottom ( ) ) ; if ( ImageFind :: CountPixelsInRotatedBox ( slice , im_box , rerotation , pix ) > 0 ) { AttemptToShrinkBox ( rotation , rerotation , im_box , pix , & slice ) ; part_it . add_before_stay_put ( ColPartition :: FakePartition ( slice , PT_UNKNOWN , BRT_POLYIMAGE , BTFT_NONTEXT ) ) ; } } part -> DeleteBoxes ( ) ; delete part_it . extract ( ) ; } part_it . forward ( ) ; } while ( ! part_it . at_first ( ) ) ; }
The meat of cutting a polygonal image around text.
The meat of cutting a polygonal image around text .
// This part must be cut and replaced with the remains. There are // up to 4 pieces to be made. Start with the first one and use // add_before_stay_put. For each piece if it has no black pixels // left, just don't make the box. // Above box. // Left of box. // Right of box. // Below box.