#include <coutln.h>
List of all members.
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) |
const ICOORD & | start_pos () const |
inT32 | pathlength () const |
DIR128 | step_dir (inT16 index) const |
ICOORD | step (inT16 index) const |
inT32 | area () |
inT32 | perimeter () |
inT32 | outer_area () |
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) |
void | RemoveSmallRecursive (int min_size, C_OUTLINE_IT *it) |
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 |
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) |
Detailed Description
Definition at line 44 of file coutln.h.
Constructor & Destructor Documentation
C_OUTLINE::C_OUTLINE |
( |
| ) |
[inline] |
Definition at line 44 of file coutln.cpp.
:box (bot_left, top_right), start (startpt->pos) {
inT16 stepindex;
CRACKEDGE *edgept;
stepcount = length;
if (length == 0) {
steps = NULL;
return;
}
steps = (uinT8 *) alloc_mem (step_mem());
memset(steps, 0, step_mem());
edgept = startpt;
for (stepindex = 0; stepindex < length; stepindex++) {
set_step (stepindex, edgept->stepdir);
edgept = edgept->next;
}
}
Definition at line 76 of file coutln.cpp.
:start (startpt) {
inT8 dirdiff;
DIR128 prevdir;
DIR128 dir;
DIR128 lastdir;
TBOX new_box;
inT16 stepindex;
inT16 srcindex;
ICOORD pos;
pos = startpt;
stepcount = length;
steps = (uinT8 *) alloc_mem (step_mem());
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;
dir = new_steps[srcindex];
set_step(stepindex, dir);
dirdiff = dir - prevdir;
pos += step (stepindex);
if ((dirdiff == 64 || dirdiff == -64) && stepindex > 0) {
stepindex -= 2;
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;
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);
}
Definition at line 136 of file coutln.cpp.
{
TBOX new_box;
inT16 stepindex;
inT16 dirdiff;
ICOORD pos;
ICOORD prevpos;
ICOORD destpos;
inT16 destindex;
DIR128 dir;
uinT8 new_step;
stepcount = srcline->stepcount * 2;
if (stepcount == 0) {
steps = NULL;
box = srcline->box;
box.rotate(rotation);
return;
}
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);
while (destpos.x () != prevpos.x () || destpos.y () != prevpos.y ()) {
dir = DIR128 (FCOORD (destpos - prevpos));
dir += 64;
new_step = dir.get_dir ();
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;
}
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] |
Member Function Documentation
inT32 C_OUTLINE::area |
( |
| ) |
|
Definition at line 253 of file coutln.cpp.
{
int stepindex;
inT32 total_steps;
inT32 total;
ICOORD pos;
ICOORD next_step;
C_OUTLINE_IT it = child ();
pos = start_pos ();
total_steps = pathlength ();
total = 0;
for (stepindex = 0; stepindex < total_steps; stepindex++) {
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 ();
return total;
}
const TBOX& C_OUTLINE::bounding_box |
( |
| ) |
const [inline] |
ICOORD C_OUTLINE::chain_step |
( |
int |
chaindir | ) |
[static] |
Definition at line 723 of file coutln.cpp.
{
return step_coords[chaindir % 4];
}
C_OUTLINE_LIST* C_OUTLINE::child |
( |
| ) |
[inline] |
inT32 C_OUTLINE::count_transitions |
( |
inT32 |
threshold | ) |
|
Definition at line 335 of file coutln.cpp.
{
BOOL8 first_was_max_x;
BOOL8 first_was_max_y;
BOOL8 looking_for_max_x;
BOOL8 looking_for_min_x;
BOOL8 looking_for_max_y;
BOOL8 looking_for_min_y;
int stepindex;
inT32 total_steps;
inT32 max_x, min_x, max_y, min_y;
inT32 initial_x, initial_y;
inT32 total;
ICOORD pos;
ICOORD next_step;
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 ();
for (stepindex = 0; stepindex < total_steps; stepindex++) {
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 ();
}
}
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;
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;
first_was_max_y = FALSE;
}
total++;
looking_for_max_y = TRUE;
looking_for_min_y = FALSE;
min_y = pos.y ();
}
}
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;
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;
}
void C_OUTLINE::FakeOutline |
( |
const TBOX & |
box, |
|
|
C_OUTLINE_LIST * |
outlines |
|
) |
| [static] |
Definition at line 70 of file coutln.h.
{
return flags.bit (mask);
}
void C_OUTLINE::move |
( |
const ICOORD |
vec | ) |
|
Definition at line 592 of file coutln.cpp.
{
C_OUTLINE_IT it(&children);
box.move (vec);
start += vec;
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
it.data ()->move (vec);
}
Definition at line 707 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);
return *this;
}
Definition at line 132 of file coutln.h.
{
return other < *this;
}
inT32 C_OUTLINE::outer_area |
( |
| ) |
|
Definition at line 303 of file coutln.cpp.
{
int stepindex;
inT32 total_steps;
inT32 total;
ICOORD pos;
ICOORD next_step;
pos = start_pos ();
total_steps = pathlength ();
if (total_steps == 0)
return box.area();
total = 0;
for (stepindex = 0; stepindex < total_steps; stepindex++) {
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 |
( |
| ) |
|
Definition at line 285 of file coutln.cpp.
{
inT32 total_steps;
C_OUTLINE_IT it = child();
total_steps = pathlength();
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward())
total_steps += it.data()->pathlength();
return total_steps;
}
void C_OUTLINE::RemoveSmallRecursive |
( |
int |
min_size, |
|
|
C_OUTLINE_IT * |
it |
|
) |
| |
Definition at line 609 of file coutln.cpp.
{
if (box.width() < min_size || box.height() < min_size) {
ASSERT_HOST(this == it->data());
delete it->extract();
} else if (!children.empty()) {
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 626 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 643 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 569 of file coutln.cpp.
{
DIR128 halfturn = MODULUS / 2;
DIR128 stepdir;
inT16 stepindex;
inT16 farindex;
inT16 halfsteps;
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_step |
( |
inT16 |
stepindex, |
|
|
inT8 |
stepdir |
|
) |
| [inline] |
Definition at line 88 of file coutln.h.
{
int shift = stepindex%4 * 2;
uinT8 mask = 3 << shift;
steps[stepindex/4] = ((stepdir << shift) & mask) |
(steps[stepindex/4] & ~mask);
}
void C_OUTLINE::set_step |
( |
inT16 |
stepindex, |
|
|
DIR128 |
stepdir |
|
) |
| [inline] |
const ICOORD& C_OUTLINE::start_pos |
( |
| ) |
const [inline] |
Definition at line 120 of file coutln.h.
{
return step_coords[(steps[index/4] >> (index%4 * 2)) & STEP_MASK];
}
DIR128 C_OUTLINE::step_dir |
( |
inT16 |
index | ) |
const [inline] |
inT16 C_OUTLINE::turn_direction |
( |
| ) |
const |
Definition at line 540 of file coutln.cpp.
{
DIR128 prevdir;
DIR128 dir;
inT16 stepindex;
inT8 dirdiff;
inT16 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;
}
Definition at line 500 of file coutln.cpp.
{
inT16 stepindex;
inT16 count;
ICOORD vec;
ICOORD stepvec;
inT32 cross;
vec = start - point;
count = 0;
for (stepindex = 0; stepindex < stepcount; stepindex++) {
stepvec = step (stepindex);
if (vec.y () <= 0 && vec.y () + stepvec.y () > 0) {
cross = vec * stepvec;
if (cross > 0)
count++;
else if (cross == 0)
return INTERSECTING;
}
else if (vec.y () > 0 && vec.y () + stepvec.y () <= 0) {
cross = vec * stepvec;
if (cross < 0)
count--;
else if (cross == 0)
return INTERSECTING;
}
vec += stepvec;
}
return count;
}
The documentation for this class was generated from the following files: