tesseract/ccstruct/rect.cpp
2007-03-07 20:03:40 +00:00

233 lines
6.8 KiB
C++

/**********************************************************************
* File: rect.c (Formerly box.c)
* Description: Bounding box class definition.
* Author: Phil Cheatle
* Created: Wed Oct 16 15:18:45 BST 1991
*
* (C) Copyright 1991, Hewlett-Packard Ltd.
** 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 "mfcpch.h" //precompiled headers
#include "rect.h"
/**********************************************************************
* BOX::BOX() Constructor from 2 ICOORDS
*
**********************************************************************/
BOX::BOX( //construtor
const ICOORD pt1, //one corner
const ICOORD pt2 //the other corner
) {
if (pt1.x () <= pt2.x ()) {
if (pt1.y () <= pt2.y ()) {
bot_left = pt1;
top_right = pt2;
}
else {
bot_left = ICOORD (pt1.x (), pt2.y ());
top_right = ICOORD (pt2.x (), pt1.y ());
}
}
else {
if (pt1.y () <= pt2.y ()) {
bot_left = ICOORD (pt2.x (), pt1.y ());
top_right = ICOORD (pt1.x (), pt2.y ());
}
else {
bot_left = pt2;
top_right = pt1;
}
}
}
/**********************************************************************
* BOX::intersection() Build the largest box contained in both boxes
*
**********************************************************************/
BOX BOX::intersection( //shared area box
const BOX &box) const {
ICOORD bl; //bottom left
ICOORD tr; //top right
if (overlap (box)) {
if (box.bot_left.x () > bot_left.x ())
bl.set_x (box.bot_left.x ());
else
bl.set_x (bot_left.x ());
if (box.top_right.x () < top_right.x ())
tr.set_x (box.top_right.x ());
else
tr.set_x (top_right.x ());
if (box.bot_left.y () > bot_left.y ())
bl.set_y (box.bot_left.y ());
else
bl.set_y (bot_left.y ());
if (box.top_right.y () < top_right.y ())
tr.set_y (box.top_right.y ());
else
tr.set_y (top_right.y ());
}
else {
bl.set_x (MAX_INT16);
bl.set_y (MAX_INT16);
tr.set_x (-MAX_INT16);
tr.set_y (-MAX_INT16);
}
return BOX (bl, tr);
}
/**********************************************************************
* BOX::bounding_union() Build the smallest box containing both boxes
*
**********************************************************************/
BOX BOX::bounding_union( //box enclosing both
const BOX &box) const {
ICOORD bl; //bottom left
ICOORD tr; //top right
if (box.bot_left.x () < bot_left.x ())
bl.set_x (box.bot_left.x ());
else
bl.set_x (bot_left.x ());
if (box.top_right.x () > top_right.x ())
tr.set_x (box.top_right.x ());
else
tr.set_x (top_right.x ());
if (box.bot_left.y () < bot_left.y ())
bl.set_y (box.bot_left.y ());
else
bl.set_y (bot_left.y ());
if (box.top_right.y () > top_right.y ())
tr.set_y (box.top_right.y ());
else
tr.set_y (top_right.y ());
return BOX (bl, tr);
}
/**********************************************************************
* BOX::plot() Paint a box using specified settings
*
**********************************************************************/
#ifndef GRAPHICS_DISABLED
void BOX::plot( //paint box
WINDOW fd, //where to paint
INT16 style, //display style
INT16 edged, //show border?
COLOUR fill_colour, //colour for inside
COLOUR border_colour //colour for border
) const {
interior_style(fd, style, edged);
fill_color_index(fd, fill_colour);
perimeter_color_index(fd, border_colour);
plot(fd);
}
#endif
/**********************************************************************
* operator+=
*
* Extend one box to include the other (In place union)
**********************************************************************/
DLLSYM BOX &
operator+= ( //bounding bounding bx
BOX & op1, //operands
const BOX & op2) {
if (op2.bot_left.x () < op1.bot_left.x ())
op1.bot_left.set_x (op2.bot_left.x ());
if (op2.top_right.x () > op1.top_right.x ())
op1.top_right.set_x (op2.top_right.x ());
if (op2.bot_left.y () < op1.bot_left.y ())
op1.bot_left.set_y (op2.bot_left.y ());
if (op2.top_right.y () > op1.top_right.y ())
op1.top_right.set_y (op2.top_right.y ());
return op1;
}
/**********************************************************************
* operator-=
*
* Reduce one box to intersection with the other (In place intersection)
**********************************************************************/
DLLSYM BOX &
operator-= ( //inplace intersection
BOX & op1, //operands
const BOX & op2) {
if (op1.overlap (op2)) {
if (op2.bot_left.x () > op1.bot_left.x ())
op1.bot_left.set_x (op2.bot_left.x ());
if (op2.top_right.x () < op1.top_right.x ())
op1.top_right.set_x (op2.top_right.x ());
if (op2.bot_left.y () > op1.bot_left.y ())
op1.bot_left.set_y (op2.bot_left.y ());
if (op2.top_right.y () < op1.top_right.y ())
op1.top_right.set_y (op2.top_right.y ());
}
else {
op1.bot_left.set_x (MAX_INT16);
op1.bot_left.set_y (MAX_INT16);
op1.top_right.set_x (-MAX_INT16);
op1.top_right.set_y (-MAX_INT16);
}
return op1;
}
/**********************************************************************
* BOX::serialise_asc() Convert to ascii file.
*
**********************************************************************/
void BOX::serialise_asc( //convert to ascii
FILE *f //file to use
) {
bot_left.serialise_asc (f);
top_right.serialise_asc (f);
}
/**********************************************************************
* BOX::de_serialise_asc() Convert from ascii file.
*
**********************************************************************/
void BOX::de_serialise_asc( //convert from ascii
FILE *f //file to use
) {
bot_left.de_serialise_asc (f);
top_right.de_serialise_asc (f);
}