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] |