tesseract/ccstruct/blobs.h

291 lines
9.4 KiB
C

/* -*-C-*-
********************************************************************************
*
* File: blobs.h (Formerly blobs.h)
* Description: Blob definition
* Author: Mark Seaman, OCR Technology
* Created: Fri Oct 27 15:39:52 1989
* Modified: Thu Mar 28 15:33:38 1991 (Mark Seaman) marks@hpgrlt
* Language: C
* Package: N/A
* Status: Experimental (Do Not Distribute)
*
* (c) Copyright 1989, Hewlett-Packard Company.
** 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.
*
*********************************************************************************/
#ifndef BLOBS_H
#define BLOBS_H
/*----------------------------------------------------------------------
I n c l u d e s
----------------------------------------------------------------------*/
#include "rect.h"
#include "vecfuncs.h"
class C_BLOB;
class DENORM;
class ROW;
class WERD;
/*----------------------------------------------------------------------
T y p e s
----------------------------------------------------------------------*/
#define EDGEPTFLAGS 4 /*concavity,length etc. */
typedef struct
{ /* Widths of pieces */
int num_chars;
int widths[1];
} WIDTH_RECORD;
struct TPOINT {
void operator+=(const TPOINT& other) {
x += other.x;
y += other.y;
}
void operator/=(int divisor) {
x /= divisor;
y /= divisor;
}
inT16 x; // absolute x coord.
inT16 y; // absolute y coord.
};
typedef TPOINT VECTOR; // structure for coordinates.
struct EDGEPT {
EDGEPT() : next(NULL), prev(NULL) {
memset(flags, 0, EDGEPTFLAGS * sizeof(flags[0]));
}
EDGEPT(const EDGEPT& src) : next(NULL), prev(NULL) {
CopyFrom(src);
}
EDGEPT& operator=(const EDGEPT& src) {
CopyFrom(src);
return *this;
}
// Copies the data elements, but leaves the pointers untouched.
void CopyFrom(const EDGEPT& src) {
pos = src.pos;
vec = src.vec;
memcpy(flags, src.flags, EDGEPTFLAGS * sizeof(flags[0]));
}
// Accessors to hide or reveal a cut edge from feature extractors.
void Hide() {
flags[0] = true;
}
void Reveal() {
flags[0] = false;
}
bool IsHidden() const {
return flags[0] != 0;
}
TPOINT pos; // position
VECTOR vec; // vector to next point
// TODO(rays) Remove flags and replace with
// is_hidden, runlength, dir, and fixed. The only use
// of the flags other than is_hidden is in polyaprx.cpp.
char flags[EDGEPTFLAGS]; // concavity, length etc
EDGEPT* next; // anticlockwise element
EDGEPT* prev; // clockwise element
};
struct TESSLINE {
TESSLINE() : is_hole(false), loop(NULL), next(NULL) {}
TESSLINE(const TESSLINE& src) : loop(NULL), next(NULL) {
CopyFrom(src);
}
~TESSLINE() {
Clear();
}
TESSLINE& operator=(const TESSLINE& src) {
CopyFrom(src);
return *this;
}
// Consume the circular list of EDGEPTs to make a TESSLINE.
static TESSLINE* BuildFromOutlineList(EDGEPT* outline);
// Copies the data and the outline, but leaves next untouched.
void CopyFrom(const TESSLINE& src);
// Deletes owned data.
void Clear();
// Rotates by the given rotation in place.
void Rotate(const FCOORD rotation);
// Moves by the given vec in place.
void Move(const ICOORD vec);
// Scales by the given factor in place.
void Scale(float factor);
// Sets up the start and vec members of the loop from the pos members.
void SetupFromPos();
// Recomputes the bounding box from the points in the loop.
void ComputeBoundingBox();
// Computes the min and max cross product of the outline points with the
// given vec and returns the results in min_xp and max_xp. Geometrically
// this is the left and right edge of the outline perpendicular to the
// given direction, but to get the distance units correct, you would
// have to divide by the modulus of vec.
void MinMaxCrossProduct(const TPOINT vec, int* min_xp, int* max_xp) const;
TBOX bounding_box() const;
// Returns true if the point is contained within the outline box.
bool Contains(const TPOINT& pt) {
return topleft.x <= pt.x && pt.x <= botright.x &&
botright.y <= pt.y && pt.y <= topleft.y;
}
void plot(ScrollView* window, ScrollView::Color color,
ScrollView::Color child_color);
int BBArea() const {
return (botright.x - topleft.x) * (topleft.y - botright.y);
}
TPOINT topleft; // Top left of loop.
TPOINT botright; // Bottom right of loop.
TPOINT start; // Start of loop.
bool is_hole; // True if this is a hole/child outline.
EDGEPT *loop; // Edgeloop.
TESSLINE *next; // Next outline in blob.
}; // Outline structure.
struct TBLOB {
TBLOB() : outlines(NULL), next(NULL) {}
TBLOB(const TBLOB& src) : outlines(NULL), next(NULL) {
CopyFrom(src);
}
~TBLOB() {
Clear();
}
TBLOB& operator=(const TBLOB& src) {
CopyFrom(src);
return *this;
}
// Factory to build a TBLOB from a C_BLOB with polygonal
// approximation along the way.
static TBLOB* PolygonalCopy(C_BLOB* src);
// Copies the data and the outlines, but leaves next untouched.
void CopyFrom(const TBLOB& src);
// Deletes owned data.
void Clear();
// Rotates by the given rotation in place.
void Rotate(const FCOORD rotation);
// Moves by the given vec in place.
void Move(const ICOORD vec);
// Scales by the given factor in place.
void Scale(float factor);
// Recomputes the bounding boxes of the outlines.
void ComputeBoundingBoxes();
// Returns the number of outlines.
int NumOutlines() const;
TBOX bounding_box() const;
void plot(ScrollView* window, ScrollView::Color color,
ScrollView::Color child_color);
int BBArea() const {
int total_area = 0;
for (TESSLINE* outline = outlines; outline != NULL; outline = outline->next)
total_area += outline->BBArea();
return total_area;
}
TESSLINE *outlines; // List of outlines in blob.
TBLOB *next; // Next blob in block.
}; // Blob structure.
int count_blobs(TBLOB *blobs);
struct TWERD {
TWERD() : blobs(NULL), latin_script(false), next(NULL) {}
TWERD(const TWERD& src) : blobs(NULL), next(NULL) {
CopyFrom(src);
}
~TWERD() {
Clear();
}
TWERD& operator=(const TWERD& src) {
CopyFrom(src);
return *this;
}
// Factory to build a TWERD from a (C_BLOB) WERD, with polygonal
// approximation along the way.
static TWERD* PolygonalCopy(WERD* src);
// Normalize in-place and record the normalization in the DENORM.
void Normalize(ROW* row, float x_height, bool numeric_mode, DENORM* denorm);
// Copies the data and the blobs, but leaves next untouched.
void CopyFrom(const TWERD& src);
// Deletes owned data.
void Clear();
// Recomputes the bounding boxes of the blobs.
void ComputeBoundingBoxes();
// Returns the number of blobs in the word.
int NumBlobs() const {
return count_blobs(blobs);
}
TBOX bounding_box() const;
// Merges the blobs from start to end, not including end, and deletes
// the blobs between start and end.
void MergeBlobs(int start, int end);
void plot(ScrollView* window);
TBLOB* blobs; // blobs in word.
bool latin_script; // This word is in a latin-based script.
TWERD* next; // next word.
};
/*----------------------------------------------------------------------
M a c r o s
----------------------------------------------------------------------*/
/**********************************************************************
* free_widths
*
* Free the memory taken up by a width array.
**********************************************************************/
#define free_widths(w) \
if (w) memfree (w)
/*----------------------------------------------------------------------
F u n c t i o n s
----------------------------------------------------------------------*/
// TODO(rays) This will become a member of TBLOB when TBLOB's definition
// moves to blobs.h
TBOX TBLOB_bounding_box(const TBLOB* blob);
void blob_origin(TBLOB *blob, /*blob to compute on */
TPOINT *origin); /*return value */
/*blob to compute on */
void blob_bounding_box(const TBLOB *blob,
TPOINT *topleft, // Bounding box.
TPOINT *botright);
void blobs_bounding_box(TBLOB *blobs, TPOINT *topleft, TPOINT *botright);
void blobs_origin(TBLOB *blobs, /*blob to compute on */
TPOINT *origin); /*return value */
/*blob to compute on */
WIDTH_RECORD *blobs_widths(TBLOB *blobs);
bool divisible_blob(TBLOB *blob, bool italic_blob, TPOINT* location);
void divide_blobs(TBLOB *blob, TBLOB *other_blob, bool italic_blob,
const TPOINT& location);
#endif