mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2024-12-11 15:09:03 +08:00
ac4e0cffa2
git-svn-id: https://tesseract-ocr.googlecode.com/svn/trunk@138 d0cd1f9f-072b-0410-8dd7-cf729c803f20
230 lines
6.6 KiB
C++
230 lines
6.6 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
|
|
ScrollView* fd, //where to paint
|
|
ScrollView::Color fill_colour, //colour for inside
|
|
ScrollView::Color border_colour //colour for border
|
|
) const {
|
|
fd->Brush(fill_colour);
|
|
fd->Pen(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);
|
|
}
|