|
tesseract
3.03
|
#include <coutln.h>
Public Member Functions | |
| C_OUTLINE () | |
| C_OUTLINE (CRACKEDGE *startpt, ICOORD bot_left, ICOORD top_right, inT16 length) | |
| C_OUTLINE (ICOORD startpt, DIR128 *new_steps, inT16 length) | |
| C_OUTLINE (C_OUTLINE *srcline, FCOORD rotation) | |
| ~C_OUTLINE () | |
| BOOL8 | flag (C_OUTLINE_FLAGS mask) const |
| void | set_flag (C_OUTLINE_FLAGS mask, BOOL8 value) |
| C_OUTLINE_LIST * | child () |
| const TBOX & | bounding_box () const |
| void | set_step (inT16 stepindex, inT8 stepdir) |
| void | set_step (inT16 stepindex, DIR128 stepdir) |
| inT32 | pathlength () const |
| DIR128 | step_dir (int index) const |
| ICOORD | step (int index) const |
| const ICOORD & | start_pos () const |
| ICOORD | position_at_index (int index) const |
| FCOORD | sub_pixel_pos_at_index (const ICOORD &pos, int index) const |
| int | direction_at_index (int index) const |
| int | edge_strength_at_index (int index) const |
| int | chain_code (int index) const |
| inT32 | area () const |
| inT32 | perimeter () const |
| inT32 | outer_area () const |
| inT32 | count_transitions (inT32 threshold) |
| BOOL8 | operator< (const C_OUTLINE &other) const |
| BOOL8 | operator> (C_OUTLINE &other) const |
| inT16 | winding_number (ICOORD testpt) const |
| inT16 | turn_direction () const |
| void | reverse () |
| void | move (const ICOORD vec) |
| bool | IsLegallyNested () const |
| void | RemoveSmallRecursive (int min_size, C_OUTLINE_IT *it) |
| void | ComputeEdgeOffsets (int threshold, Pix *pix) |
| void | ComputeBinaryOffsets () |
| void | render (int left, int top, Pix *pix) const |
| void | render_outline (int left, int top, Pix *pix) const |
| void | plot (ScrollView *window, ScrollView::Color colour) const |
| void | plot_normed (const DENORM &denorm, ScrollView::Color colour, ScrollView *window) const |
| C_OUTLINE & | operator= (const C_OUTLINE &source) |
Static Public Member Functions | |
| static void | FakeOutline (const TBOX &box, C_OUTLINE_LIST *outlines) |
| static C_OUTLINE * | deep_copy (const C_OUTLINE *src) |
| static ICOORD | chain_step (int chaindir) |
Static Public Attributes | |
| static const int | kMaxOutlineLength = 16000 |
| C_OUTLINE::C_OUTLINE | ( | ) | [inline] |
| C_OUTLINE::C_OUTLINE | ( | CRACKEDGE * | startpt, |
| ICOORD | bot_left, | ||
| ICOORD | top_right, | ||
| inT16 | length | ||
| ) |
Definition at line 47 of file coutln.cpp.
:box (bot_left, top_right), start (startpt->pos), offsets(NULL) { inT16 stepindex; //index to step CRACKEDGE *edgept; //current point stepcount = length; //no of steps if (length == 0) { steps = NULL; return; } //get memory steps = (uinT8 *) alloc_mem (step_mem()); memset(steps, 0, step_mem()); edgept = startpt; for (stepindex = 0; stepindex < length; stepindex++) { //set compact step set_step (stepindex, edgept->stepdir); edgept = edgept->next; } }
| C_OUTLINE::C_OUTLINE | ( | ICOORD | startpt, |
| DIR128 * | new_steps, | ||
| inT16 | length | ||
| ) |
Definition at line 79 of file coutln.cpp.
:start (startpt), offsets(NULL) {
inT8 dirdiff; //direction difference
DIR128 prevdir; //previous direction
DIR128 dir; //current direction
DIR128 lastdir; //dir of last step
TBOX new_box; //easy bounding
inT16 stepindex; //index to step
inT16 srcindex; //source steps
ICOORD pos; //current position
pos = startpt;
stepcount = length; // No. of steps.
ASSERT_HOST(length >= 0);
steps = reinterpret_cast<uinT8*>(alloc_mem(step_mem())); // Get memory.
memset(steps, 0, step_mem());
lastdir = new_steps[length - 1];
prevdir = lastdir;
for (stepindex = 0, srcindex = 0; srcindex < length;
stepindex++, srcindex++) {
new_box = TBOX (pos, pos);
box += new_box;
//copy steps
dir = new_steps[srcindex];
set_step(stepindex, dir);
dirdiff = dir - prevdir;
pos += step (stepindex);
if ((dirdiff == 64 || dirdiff == -64) && stepindex > 0) {
stepindex -= 2; //cancel there-and-back
prevdir = stepindex >= 0 ? step_dir (stepindex) : lastdir;
}
else
prevdir = dir;
}
ASSERT_HOST (pos.x () == startpt.x () && pos.y () == startpt.y ());
do {
dirdiff = step_dir (stepindex - 1) - step_dir (0);
if (dirdiff == 64 || dirdiff == -64) {
start += step (0);
stepindex -= 2; //cancel there-and-back
for (int i = 0; i < stepindex; ++i)
set_step(i, step_dir(i + 1));
}
}
while (stepindex > 1 && (dirdiff == 64 || dirdiff == -64));
stepcount = stepindex;
ASSERT_HOST (stepcount >= 4);
}
| C_OUTLINE::C_OUTLINE | ( | C_OUTLINE * | srcline, |
| FCOORD | rotation | ||
| ) |
Definition at line 139 of file coutln.cpp.
: offsets(NULL) {
TBOX new_box; //easy bounding
inT16 stepindex; //index to step
inT16 dirdiff; //direction change
ICOORD pos; //current position
ICOORD prevpos; //previous dest point
ICOORD destpos; //destination point
inT16 destindex; //index to step
DIR128 dir; //coded direction
uinT8 new_step;
stepcount = srcline->stepcount * 2;
if (stepcount == 0) {
steps = NULL;
box = srcline->box;
box.rotate(rotation);
return;
}
//get memory
steps = (uinT8 *) alloc_mem (step_mem());
memset(steps, 0, step_mem());
for (int iteration = 0; iteration < 2; ++iteration) {
DIR128 round1 = iteration == 0 ? 32 : 0;
DIR128 round2 = iteration != 0 ? 32 : 0;
pos = srcline->start;
prevpos = pos;
prevpos.rotate (rotation);
start = prevpos;
box = TBOX (start, start);
destindex = 0;
for (stepindex = 0; stepindex < srcline->stepcount; stepindex++) {
pos += srcline->step (stepindex);
destpos = pos;
destpos.rotate (rotation);
// tprintf("%i %i %i %i ", destpos.x(), destpos.y(), pos.x(), pos.y());
while (destpos.x () != prevpos.x () || destpos.y () != prevpos.y ()) {
dir = DIR128 (FCOORD (destpos - prevpos));
dir += 64; //turn to step style
new_step = dir.get_dir ();
// tprintf(" %i\n", new_step);
if (new_step & 31) {
set_step(destindex++, dir + round1);
prevpos += step(destindex - 1);
if (destindex < 2
|| ((dirdiff =
step_dir (destindex - 1) - step_dir (destindex - 2)) !=
-64 && dirdiff != 64)) {
set_step(destindex++, dir + round2);
prevpos += step(destindex - 1);
} else {
prevpos -= step(destindex - 1);
destindex--;
prevpos -= step(destindex - 1);
set_step(destindex - 1, dir + round2);
prevpos += step(destindex - 1);
}
}
else {
set_step(destindex++, dir);
prevpos += step(destindex - 1);
}
while (destindex >= 2 &&
((dirdiff =
step_dir (destindex - 1) - step_dir (destindex - 2)) == -64 ||
dirdiff == 64)) {
prevpos -= step(destindex - 1);
prevpos -= step(destindex - 2);
destindex -= 2; // Forget u turn
}
//ASSERT_HOST(prevpos.x() == destpos.x() && prevpos.y() == destpos.y());
new_box = TBOX (destpos, destpos);
box += new_box;
}
}
ASSERT_HOST (destpos.x () == start.x () && destpos.y () == start.y ());
dirdiff = step_dir (destindex - 1) - step_dir (0);
while ((dirdiff == 64 || dirdiff == -64) && destindex > 1) {
start += step (0);
destindex -= 2;
for (int i = 0; i < destindex; ++i)
set_step(i, step_dir(i + 1));
dirdiff = step_dir (destindex - 1) - step_dir (0);
}
if (destindex >= 4)
break;
}
ASSERT_HOST(destindex <= stepcount);
stepcount = destindex;
destpos = start;
for (stepindex = 0; stepindex < stepcount; stepindex++) {
destpos += step (stepindex);
}
ASSERT_HOST (destpos.x () == start.x () && destpos.y () == start.y ());
}
| C_OUTLINE::~C_OUTLINE | ( | ) | [inline] |
| inT32 C_OUTLINE::area | ( | ) | const |
Definition at line 256 of file coutln.cpp.
{
int stepindex; //current step
inT32 total_steps; //steps to do
inT32 total; //total area
ICOORD pos; //position of point
ICOORD next_step; //step to next pix
// We aren't going to modify the list, or its contents, but there is
// no const iterator.
C_OUTLINE_IT it(const_cast<C_OUTLINE_LIST*>(&children));
pos = start_pos ();
total_steps = pathlength ();
total = 0;
for (stepindex = 0; stepindex < total_steps; stepindex++) {
//all intersected
next_step = step (stepindex);
if (next_step.x () < 0)
total += pos.y ();
else if (next_step.x () > 0)
total -= pos.y ();
pos += next_step;
}
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
total += it.data ()->area ();//add areas of children
return total;
}
| const TBOX& C_OUTLINE::bounding_box | ( | ) | const [inline] |
| int C_OUTLINE::chain_code | ( | int | index | ) | const [inline] |
| ICOORD C_OUTLINE::chain_step | ( | int | chaindir | ) | [static] |
Definition at line 1040 of file coutln.cpp.
{
return step_coords[chaindir % 4];
}
| C_OUTLINE_LIST* C_OUTLINE::child | ( | ) | [inline] |
| void C_OUTLINE::ComputeBinaryOffsets | ( | ) |
Definition at line 834 of file coutln.cpp.
{
delete [] offsets;
offsets = new EdgeOffset[stepcount];
// Count of the number of steps in each direction in the sliding window.
int dir_counts[4];
// Sum of the positions (y for a horizontal step, x for vertical) in each
// direction in the sliding window.
int pos_totals[4];
memset(dir_counts, 0, sizeof(dir_counts));
memset(pos_totals, 0, sizeof(pos_totals));
ICOORD pos = start;
ICOORD tail_pos = pos;
// tail_pos is the trailing position, with the next point to be lost from
// the window.
tail_pos -= step(stepcount - 1);
tail_pos -= step(stepcount - 2);
// head_pos is the leading position, with the next point to be added to the
// window.
ICOORD head_pos = tail_pos;
// Set up the initial window with 4 points in [-2, 2)
for (int s = -2; s < 2; ++s) {
increment_step(s, 1, &head_pos, dir_counts, pos_totals);
}
for (int s = 0; s < stepcount; pos += step(s++)) {
// At step s, s in in the middle of [s-2, s+2].
increment_step(s + 2, 1, &head_pos, dir_counts, pos_totals);
int dir_index = chain_code(s);
ICOORD step_vec = step(s);
int best_diff = 0;
int offset = 0;
// Use only steps that have a count of >=2 OR the strong U-turn with a
// single d and 2 at d-1 and 2 at d+1 (mod 4).
if (dir_counts[dir_index] >= 2 || (dir_counts[dir_index] == 1 &&
dir_counts[Modulo(dir_index - 1, 4)] == 2 &&
dir_counts[Modulo(dir_index + 1, 4)] == 2)) {
// Valid step direction.
best_diff = dir_counts[dir_index];
int edge_pos = step_vec.x() == 0 ? pos.x() : pos.y();
// The offset proposes that the actual step should be positioned at
// the mean position of the steps in the window of the same direction.
// See ASCII art above.
offset = pos_totals[dir_index] - best_diff * edge_pos;
}
offsets[s].offset_numerator =
static_cast<inT8>(ClipToRange(offset, -MAX_INT8, MAX_INT8));
offsets[s].pixel_diff = static_cast<uinT8>(ClipToRange(best_diff, 0 ,
MAX_UINT8));
// The direction is just the vector from start to end of the window.
FCOORD direction(head_pos.x() - tail_pos.x(), head_pos.y() - tail_pos.y());
offsets[s].direction = direction.to_direction();
increment_step(s - 2, -1, &tail_pos, dir_counts, pos_totals);
}
}
| void C_OUTLINE::ComputeEdgeOffsets | ( | int | threshold, |
| Pix * | pix | ||
| ) |
Definition at line 722 of file coutln.cpp.
{
if (pixGetDepth(pix) != 8) return;
const l_uint32* data = pixGetData(pix);
int wpl = pixGetWpl(pix);
int width = pixGetWidth(pix);
int height = pixGetHeight(pix);
bool negative = flag(COUT_INVERSE);
delete [] offsets;
offsets = new EdgeOffset[stepcount];
ICOORD pos = start;
ICOORD prev_gradient;
ComputeGradient(data, wpl, pos.x(), height - pos.y(), width, height,
&prev_gradient);
for (int s = 0; s < stepcount; ++s) {
ICOORD step_vec = step(s);
TPOINT pt1(pos);
pos += step_vec;
TPOINT pt2(pos);
ICOORD next_gradient;
ComputeGradient(data, wpl, pos.x(), height - pos.y(), width, height,
&next_gradient);
// Use the sum of the prev and next as the working gradient.
ICOORD gradient = prev_gradient + next_gradient;
// best_diff will be manipulated to be always positive.
int best_diff = 0;
// offset will be the extrapolation of the location of the greyscale
// threshold from the edge with the largest difference, relative to the
// location of the binary edge.
int offset = 0;
if (pt1.y == pt2.y && abs(gradient.y()) * 2 >= abs(gradient.x())) {
// Horizontal step. diff_sign == 1 indicates black above.
int diff_sign = (pt1.x > pt2.x) == negative ? 1 : -1;
int x = MIN(pt1.x, pt2.x);
int y = height - pt1.y;
int best_sum = 0;
int best_y = y;
EvaluateVerticalDiff(data, wpl, diff_sign, x, y, height,
&best_diff, &best_sum, &best_y);
// Find the strongest edge.
int test_y = y;
do {
++test_y;
} while (EvaluateVerticalDiff(data, wpl, diff_sign, x, test_y, height,
&best_diff, &best_sum, &best_y));
test_y = y;
do {
--test_y;
} while (EvaluateVerticalDiff(data, wpl, diff_sign, x, test_y, height,
&best_diff, &best_sum, &best_y));
offset = diff_sign * (best_sum / 2 - threshold) +
(y - best_y) * best_diff;
} else if (pt1.x == pt2.x && abs(gradient.x()) * 2 >= abs(gradient.y())) {
// Vertical step. diff_sign == 1 indicates black on the left.
int diff_sign = (pt1.y > pt2.y) == negative ? 1 : -1;
int x = pt1.x;
int y = height - MAX(pt1.y, pt2.y);
const l_uint32* line = pixGetData(pix) + y * wpl;
int best_sum = 0;
int best_x = x;
EvaluateHorizontalDiff(line, diff_sign, x, width,
&best_diff, &best_sum, &best_x);
// Find the strongest edge.
int test_x = x;
do {
++test_x;
} while (EvaluateHorizontalDiff(line, diff_sign, test_x, width,
&best_diff, &best_sum, &best_x));
test_x = x;
do {
--test_x;
} while (EvaluateHorizontalDiff(line, diff_sign, test_x, width,
&best_diff, &best_sum, &best_x));
offset = diff_sign * (threshold - best_sum / 2) +
(best_x - x) * best_diff;
}
offsets[s].offset_numerator =
static_cast<inT8>(ClipToRange(offset, -MAX_INT8, MAX_INT8));
offsets[s].pixel_diff = static_cast<uinT8>(ClipToRange(best_diff, 0 ,
MAX_UINT8));
if (negative) gradient = -gradient;
// Compute gradient angle quantized to 256 directions, rotated by 64 (pi/2)
// to convert from gradient direction to edge direction.
offsets[s].direction =
Modulo(FCOORD::binary_angle_plus_pi(gradient.angle()) + 64, 256);
prev_gradient = next_gradient;
}
}
| inT32 C_OUTLINE::count_transitions | ( | inT32 | threshold | ) |
Definition at line 342 of file coutln.cpp.
{
BOOL8 first_was_max_x; //what was first
BOOL8 first_was_max_y;
BOOL8 looking_for_max_x; //what is next
BOOL8 looking_for_min_x;
BOOL8 looking_for_max_y; //what is next
BOOL8 looking_for_min_y;
int stepindex; //current step
inT32 total_steps; //steps to do
//current limits
inT32 max_x, min_x, max_y, min_y;
inT32 initial_x, initial_y; //initial limits
inT32 total; //total changes
ICOORD pos; //position of point
ICOORD next_step; //step to next pix
pos = start_pos ();
total_steps = pathlength ();
total = 0;
max_x = min_x = pos.x ();
max_y = min_y = pos.y ();
looking_for_max_x = TRUE;
looking_for_min_x = TRUE;
looking_for_max_y = TRUE;
looking_for_min_y = TRUE;
first_was_max_x = FALSE;
first_was_max_y = FALSE;
initial_x = pos.x ();
initial_y = pos.y (); //stop uninit warning
for (stepindex = 0; stepindex < total_steps; stepindex++) {
//all intersected
next_step = step (stepindex);
pos += next_step;
if (next_step.x () < 0) {
if (looking_for_max_x && pos.x () < min_x)
min_x = pos.x ();
if (looking_for_min_x && max_x - pos.x () > threshold) {
if (looking_for_max_x) {
initial_x = max_x;
first_was_max_x = FALSE;
}
total++;
looking_for_max_x = TRUE;
looking_for_min_x = FALSE;
min_x = pos.x (); //reset min
}
}
else if (next_step.x () > 0) {
if (looking_for_min_x && pos.x () > max_x)
max_x = pos.x ();
if (looking_for_max_x && pos.x () - min_x > threshold) {
if (looking_for_min_x) {
initial_x = min_x; //remember first min
first_was_max_x = TRUE;
}
total++;
looking_for_max_x = FALSE;
looking_for_min_x = TRUE;
max_x = pos.x ();
}
}
else if (next_step.y () < 0) {
if (looking_for_max_y && pos.y () < min_y)
min_y = pos.y ();
if (looking_for_min_y && max_y - pos.y () > threshold) {
if (looking_for_max_y) {
initial_y = max_y; //remember first max
first_was_max_y = FALSE;
}
total++;
looking_for_max_y = TRUE;
looking_for_min_y = FALSE;
min_y = pos.y (); //reset min
}
}
else {
if (looking_for_min_y && pos.y () > max_y)
max_y = pos.y ();
if (looking_for_max_y && pos.y () - min_y > threshold) {
if (looking_for_min_y) {
initial_y = min_y; //remember first min
first_was_max_y = TRUE;
}
total++;
looking_for_max_y = FALSE;
looking_for_min_y = TRUE;
max_y = pos.y ();
}
}
}
if (first_was_max_x && looking_for_min_x) {
if (max_x - initial_x > threshold)
total++;
else
total--;
}
else if (!first_was_max_x && looking_for_max_x) {
if (initial_x - min_x > threshold)
total++;
else
total--;
}
if (first_was_max_y && looking_for_min_y) {
if (max_y - initial_y > threshold)
total++;
else
total--;
}
else if (!first_was_max_y && looking_for_max_y) {
if (initial_y - min_y > threshold)
total++;
else
total--;
}
return total;
}
| static C_OUTLINE* C_OUTLINE::deep_copy | ( | const C_OUTLINE * | src | ) | [inline, static] |
| int C_OUTLINE::direction_at_index | ( | int | index | ) | const [inline] |
| int C_OUTLINE::edge_strength_at_index | ( | int | index | ) | const [inline] |
Definition at line 185 of file coutln.h.
{
if (offsets != NULL)
return offsets[index].pixel_diff;
return 1;
}
| void C_OUTLINE::FakeOutline | ( | const TBOX & | box, |
| C_OUTLINE_LIST * | outlines | ||
| ) | [static] |
Definition at line 240 of file coutln.cpp.
{
C_OUTLINE_IT ol_it(outlines);
// Make a C_OUTLINE from the bounds. This is a bit of a hack,
// as there is no outline, just a bounding box, but it works nicely.
CRACKEDGE start;
start.pos = box.topleft();
C_OUTLINE* outline = new C_OUTLINE(&start, box.topleft(), box.botright(), 0);
ol_it.add_to_end(outline);
}
| BOOL8 C_OUTLINE::flag | ( | C_OUTLINE_FLAGS | mask | ) | const [inline] |
| bool C_OUTLINE::IsLegallyNested | ( | ) | const |
Definition at line 615 of file coutln.cpp.
{
if (stepcount == 0) return true;
int parent_area = outer_area();
// We aren't going to modify the list, or its contents, but there is
// no const iterator.
C_OUTLINE_IT child_it(const_cast<C_OUTLINE_LIST*>(&children));
for (child_it.mark_cycle_pt(); !child_it.cycled_list(); child_it.forward()) {
const C_OUTLINE* child = child_it.data();
if (child->outer_area() * parent_area > 0 || !child->IsLegallyNested())
return false;
}
return true;
}
| void C_OUTLINE::move | ( | const ICOORD | vec | ) |
Definition at line 599 of file coutln.cpp.
{
C_OUTLINE_IT it(&children); // iterator
box.move (vec);
start += vec;
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
it.data ()->move (vec); // move child outlines
}
Definition at line 471 of file coutln.cpp.
{
inT16 count = 0; //winding count
ICOORD pos; //position of point
inT32 stepindex; //index to cstep
if (!box.overlap (other.box))
return FALSE; //can't be contained
if (stepcount == 0)
return other.box.contains(this->box);
pos = start;
for (stepindex = 0; stepindex < stepcount
&& (count = other.winding_number (pos)) == INTERSECTING; stepindex++)
pos += step (stepindex); //try all points
if (count == INTERSECTING) {
//all intersected
pos = other.start;
for (stepindex = 0; stepindex < other.stepcount
&& (count = winding_number (pos)) == INTERSECTING; stepindex++)
//try other way round
pos += other.step (stepindex);
return count == INTERSECTING || count == 0;
}
return count != 0;
}
Definition at line 1000 of file coutln.cpp.
{
box = source.box;
start = source.start;
if (steps != NULL)
free_mem(steps);
stepcount = source.stepcount;
steps = (uinT8 *) alloc_mem (step_mem());
memmove (steps, source.steps, step_mem());
if (!children.empty ())
children.clear ();
children.deep_copy(&source.children, &deep_copy);
delete [] offsets;
if (source.offsets != NULL) {
offsets = new EdgeOffset[stepcount];
memcpy(offsets, source.offsets, stepcount * sizeof(*offsets));
} else {
offsets = NULL;
}
return *this;
}
| inT32 C_OUTLINE::outer_area | ( | ) | const |
Definition at line 310 of file coutln.cpp.
{
int stepindex; //current step
inT32 total_steps; //steps to do
inT32 total; //total area
ICOORD pos; //position of point
ICOORD next_step; //step to next pix
pos = start_pos ();
total_steps = pathlength ();
if (total_steps == 0)
return box.area();
total = 0;
for (stepindex = 0; stepindex < total_steps; stepindex++) {
//all intersected
next_step = step (stepindex);
if (next_step.x () < 0)
total += pos.y ();
else if (next_step.x () > 0)
total -= pos.y ();
pos += next_step;
}
return total;
}
| inT32 C_OUTLINE::pathlength | ( | ) | const [inline] |
| inT32 C_OUTLINE::perimeter | ( | ) | const |
Definition at line 290 of file coutln.cpp.
{
inT32 total_steps; // Return value.
// We aren't going to modify the list, or its contents, but there is
// no const iterator.
C_OUTLINE_IT it(const_cast<C_OUTLINE_LIST*>(&children));
total_steps = pathlength();
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward())
total_steps += it.data()->pathlength(); // Add perimeters of children.
return total_steps;
}
| void C_OUTLINE::plot | ( | ScrollView * | window, |
| ScrollView::Color | colour | ||
| ) | const |
Definition at line 931 of file coutln.cpp.
{
inT16 stepindex; // index to cstep
ICOORD pos; // current position
DIR128 stepdir; // direction of step
pos = start; // current position
window->Pen(colour);
if (stepcount == 0) {
window->Rectangle(box.left(), box.top(), box.right(), box.bottom());
return;
}
window->SetCursor(pos.x(), pos.y());
stepindex = 0;
while (stepindex < stepcount) {
pos += step(stepindex); // step to next
stepdir = step_dir(stepindex);
stepindex++; // count steps
// merge straight lines
while (stepindex < stepcount &&
stepdir.get_dir() == step_dir(stepindex).get_dir()) {
pos += step(stepindex);
stepindex++;
}
window->DrawTo(pos.x(), pos.y());
}
}
| void C_OUTLINE::plot_normed | ( | const DENORM & | denorm, |
| ScrollView::Color | colour, | ||
| ScrollView * | window | ||
| ) | const |
Definition at line 963 of file coutln.cpp.
{
window->Pen(colour);
if (stepcount == 0) {
window->Rectangle(box.left(), box.top(), box.right(), box.bottom());
return;
}
const DENORM* root_denorm = denorm.RootDenorm();
ICOORD pos = start; // current position
FCOORD f_pos = sub_pixel_pos_at_index(pos, 0);
FCOORD pos_normed;
denorm.NormTransform(root_denorm, f_pos, &pos_normed);
window->SetCursor(IntCastRounded(pos_normed.x()),
IntCastRounded(pos_normed.y()));
for (int s = 0; s < stepcount; pos += step(s++)) {
int edge_weight = edge_strength_at_index(s);
if (edge_weight == 0) {
// This point has conflicting gradient and step direction, so ignore it.
continue;
}
FCOORD f_pos = sub_pixel_pos_at_index(pos, s);
FCOORD pos_normed;
denorm.NormTransform(root_denorm, f_pos, &pos_normed);
window->DrawTo(IntCastRounded(pos_normed.x()),
IntCastRounded(pos_normed.y()));
}
}
| ICOORD C_OUTLINE::position_at_index | ( | int | index | ) | const [inline] |
| void C_OUTLINE::RemoveSmallRecursive | ( | int | min_size, |
| C_OUTLINE_IT * | it | ||
| ) |
Definition at line 634 of file coutln.cpp.
{
if (box.width() < min_size || box.height() < min_size) {
ASSERT_HOST(this == it->data());
delete it->extract(); // Too small so get rid of it and any children.
} else if (!children.empty()) {
// Search the children of this, deleting any that are too small.
C_OUTLINE_IT child_it(&children);
for (child_it.mark_cycle_pt(); !child_it.cycled_list();
child_it.forward()) {
C_OUTLINE* child = child_it.data();
child->RemoveSmallRecursive(min_size, &child_it);
}
}
}
| void C_OUTLINE::render | ( | int | left, |
| int | top, | ||
| Pix * | pix | ||
| ) | const |
Definition at line 890 of file coutln.cpp.
{
ICOORD pos = start;
for (int stepindex = 0; stepindex < stepcount; ++stepindex) {
ICOORD next_step = step(stepindex);
if (next_step.y() < 0) {
pixRasterop(pix, 0, top - pos.y(), pos.x() - left, 1,
PIX_NOT(PIX_DST), NULL, 0, 0);
} else if (next_step.y() > 0) {
pixRasterop(pix, 0, top - pos.y() - 1, pos.x() - left, 1,
PIX_NOT(PIX_DST), NULL, 0, 0);
}
pos += next_step;
}
}
| void C_OUTLINE::render_outline | ( | int | left, |
| int | top, | ||
| Pix * | pix | ||
| ) | const |
Definition at line 907 of file coutln.cpp.
{
ICOORD pos = start;
for (int stepindex = 0; stepindex < stepcount; ++stepindex) {
ICOORD next_step = step(stepindex);
if (next_step.y() < 0) {
pixSetPixel(pix, pos.x() - left, top - pos.y(), 1);
} else if (next_step.y() > 0) {
pixSetPixel(pix, pos.x() - left - 1, top - pos.y() - 1, 1);
} else if (next_step.x() < 0) {
pixSetPixel(pix, pos.x() - left - 1, top - pos.y(), 1);
} else if (next_step.x() > 0) {
pixSetPixel(pix, pos.x() - left, top - pos.y() - 1, 1);
}
pos += next_step;
}
}
| void C_OUTLINE::reverse | ( | ) |
Definition at line 576 of file coutln.cpp.
{ //reverse drection
DIR128 halfturn = MODULUS / 2; //amount to shift
DIR128 stepdir; //direction of step
inT16 stepindex; //index to cstep
inT16 farindex; //index to other side
inT16 halfsteps; //half of stepcount
halfsteps = (stepcount + 1) / 2;
for (stepindex = 0; stepindex < halfsteps; stepindex++) {
farindex = stepcount - stepindex - 1;
stepdir = step_dir (stepindex);
set_step (stepindex, step_dir (farindex) + halfturn);
set_step (farindex, stepdir + halfturn);
}
}
| void C_OUTLINE::set_flag | ( | C_OUTLINE_FLAGS | mask, |
| BOOL8 | value | ||
| ) | [inline] |
| void C_OUTLINE::set_step | ( | inT16 | stepindex, |
| inT8 | stepdir | ||
| ) | [inline] |
| void C_OUTLINE::set_step | ( | inT16 | stepindex, |
| DIR128 | stepdir | ||
| ) | [inline] |
| const ICOORD& C_OUTLINE::start_pos | ( | ) | const [inline] |
| ICOORD C_OUTLINE::step | ( | int | index | ) | const [inline] |
Definition at line 142 of file coutln.h.
{ // index of step
return step_coords[chain_code(index)];
}
| DIR128 C_OUTLINE::step_dir | ( | int | index | ) | const [inline] |
| FCOORD C_OUTLINE::sub_pixel_pos_at_index | ( | const ICOORD & | pos, |
| int | index | ||
| ) | const [inline] |
Definition at line 161 of file coutln.h.
{
const ICOORD& step_to_next(step(index));
FCOORD f_pos(pos.x() + step_to_next.x() / 2.0f,
pos.y() + step_to_next.y() / 2.0f);
if (offsets != NULL && offsets[index].pixel_diff > 0) {
float offset = offsets[index].offset_numerator;
offset /= offsets[index].pixel_diff;
if (step_to_next.x() != 0)
f_pos.set_y(f_pos.y() + offset);
else
f_pos.set_x(f_pos.x() + offset);
}
return f_pos;
}
| inT16 C_OUTLINE::turn_direction | ( | ) | const |
Definition at line 547 of file coutln.cpp.
{ //winding number
DIR128 prevdir; //previous direction
DIR128 dir; //current direction
inT16 stepindex; //index to cstep
inT8 dirdiff; //direction difference
inT16 count; //winding count
if (stepcount == 0)
return 128;
count = 0;
prevdir = step_dir (stepcount - 1);
for (stepindex = 0; stepindex < stepcount; stepindex++) {
dir = step_dir (stepindex);
dirdiff = dir - prevdir;
ASSERT_HOST (dirdiff == 0 || dirdiff == 32 || dirdiff == -32);
count += dirdiff;
prevdir = dir;
}
ASSERT_HOST (count == 128 || count == -128);
return count; //winding number
}
| inT16 C_OUTLINE::winding_number | ( | ICOORD | testpt | ) | const |
Definition at line 507 of file coutln.cpp.
{
inT16 stepindex; //index to cstep
inT16 count; //winding count
ICOORD vec; //to current point
ICOORD stepvec; //step vector
inT32 cross; //cross product
vec = start - point; //vector to it
count = 0;
for (stepindex = 0; stepindex < stepcount; stepindex++) {
stepvec = step (stepindex); //get the step
//crossing the line
if (vec.y () <= 0 && vec.y () + stepvec.y () > 0) {
cross = vec * stepvec; //cross product
if (cross > 0)
count++; //crossing right half
else if (cross == 0)
return INTERSECTING; //going through point
}
else if (vec.y () > 0 && vec.y () + stepvec.y () <= 0) {
cross = vec * stepvec;
if (cross < 0)
count--; //crossing back
else if (cross == 0)
return INTERSECTING; //illegal
}
vec += stepvec; //sum vectors
}
return count; //winding number
}
const int C_OUTLINE::kMaxOutlineLength = 16000 [static] |