tesseract  3.04.00
C_OUTLINE Class Reference

#include <coutln.h>

Inheritance diagram for C_OUTLINE:
ELIST_LINK

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 TBOXbounding_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 ICOORDstart_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_OUTLINEoperator= (const C_OUTLINE &source)
 
- Public Member Functions inherited from ELIST_LINK
 ELIST_LINK ()
 
 ELIST_LINK (const ELIST_LINK &)
 
void operator= (const ELIST_LINK &)
 

Static Public Member Functions

static void FakeOutline (const TBOX &box, C_OUTLINE_LIST *outlines)
 
static C_OUTLINEdeep_copy (const C_OUTLINE *src)
 
static ICOORD chain_step (int chaindir)
 

Static Public Attributes

static const int kMaxOutlineLength = 16000
 

Detailed Description

Definition at line 69 of file coutln.h.

Constructor & Destructor Documentation

C_OUTLINE::C_OUTLINE ( )
inline

Definition at line 71 of file coutln.h.

71  { //empty constructor
72  steps = NULL;
73  offsets = NULL;
74  }
#define NULL
Definition: host.h:144
C_OUTLINE::C_OUTLINE ( CRACKEDGE startpt,
ICOORD  bot_left,
ICOORD  top_right,
inT16  length 
)

Definition at line 47 of file coutln.cpp.

52  :box (bot_left, top_right), start (startpt->pos), offsets(NULL) {
53  inT16 stepindex; //index to step
54  CRACKEDGE *edgept; //current point
55 
56  stepcount = length; //no of steps
57  if (length == 0) {
58  steps = NULL;
59  return;
60  }
61  //get memory
62  steps = (uinT8 *) alloc_mem (step_mem());
63  memset(steps, 0, step_mem());
64  edgept = startpt;
65 
66  for (stepindex = 0; stepindex < length; stepindex++) {
67  //set compact step
68  set_step (stepindex, edgept->stepdir);
69  edgept = edgept->next;
70  }
71 }
CRACKEDGE * next
Definition: crakedge.h:35
#define NULL
Definition: host.h:144
ICOORD pos
Definition: crakedge.h:30
void * alloc_mem(inT32 count)
Definition: memry.cpp:47
short inT16
Definition: host.h:100
void set_step(inT16 stepindex, inT8 stepdir)
Definition: coutln.h:114
inT8 stepdir
Definition: crakedge.h:33
unsigned char uinT8
Definition: host.h:99
C_OUTLINE::C_OUTLINE ( ICOORD  startpt,
DIR128 new_steps,
inT16  length 
)

Definition at line 79 of file coutln.cpp.

84  :start (startpt), offsets(NULL) {
85  inT8 dirdiff; //direction difference
86  DIR128 prevdir; //previous direction
87  DIR128 dir; //current direction
88  DIR128 lastdir; //dir of last step
89  TBOX new_box; //easy bounding
90  inT16 stepindex; //index to step
91  inT16 srcindex; //source steps
92  ICOORD pos; //current position
93 
94  pos = startpt;
95  stepcount = length; // No. of steps.
96  ASSERT_HOST(length >= 0);
97  steps = reinterpret_cast<uinT8*>(alloc_mem(step_mem())); // Get memory.
98  memset(steps, 0, step_mem());
99 
100  lastdir = new_steps[length - 1];
101  prevdir = lastdir;
102  for (stepindex = 0, srcindex = 0; srcindex < length;
103  stepindex++, srcindex++) {
104  new_box = TBOX (pos, pos);
105  box += new_box;
106  //copy steps
107  dir = new_steps[srcindex];
108  set_step(stepindex, dir);
109  dirdiff = dir - prevdir;
110  pos += step (stepindex);
111  if ((dirdiff == 64 || dirdiff == -64) && stepindex > 0) {
112  stepindex -= 2; //cancel there-and-back
113  prevdir = stepindex >= 0 ? step_dir (stepindex) : lastdir;
114  }
115  else
116  prevdir = dir;
117  }
118  ASSERT_HOST (pos.x () == startpt.x () && pos.y () == startpt.y ());
119  do {
120  dirdiff = step_dir (stepindex - 1) - step_dir (0);
121  if (dirdiff == 64 || dirdiff == -64) {
122  start += step (0);
123  stepindex -= 2; //cancel there-and-back
124  for (int i = 0; i < stepindex; ++i)
125  set_step(i, step_dir(i + 1));
126  }
127  }
128  while (stepindex > 1 && (dirdiff == 64 || dirdiff == -64));
129  stepcount = stepindex;
130  ASSERT_HOST (stepcount >= 4);
131 }
SIGNED char inT8
Definition: host.h:98
Definition: mod128.h:29
#define NULL
Definition: host.h:144
DIR128 step_dir(int index) const
Definition: coutln.h:137
ICOORD step(int index) const
Definition: coutln.h:142
Definition: rect.h:30
integer coordinate
Definition: points.h:30
void * alloc_mem(inT32 count)
Definition: memry.cpp:47
inT16 x() const
access function
Definition: points.h:52
short inT16
Definition: host.h:100
void set_step(inT16 stepindex, inT8 stepdir)
Definition: coutln.h:114
unsigned char uinT8
Definition: host.h:99
inT16 y() const
access_function
Definition: points.h:56
#define ASSERT_HOST(x)
Definition: errcode.h:84
C_OUTLINE::C_OUTLINE ( C_OUTLINE srcline,
FCOORD  rotation 
)

Definition at line 139 of file coutln.cpp.

142  : offsets(NULL) {
143  TBOX new_box; //easy bounding
144  inT16 stepindex; //index to step
145  inT16 dirdiff; //direction change
146  ICOORD pos; //current position
147  ICOORD prevpos; //previous dest point
148 
149  ICOORD destpos; //destination point
150  inT16 destindex; //index to step
151  DIR128 dir; //coded direction
152  uinT8 new_step;
153 
154  stepcount = srcline->stepcount * 2;
155  if (stepcount == 0) {
156  steps = NULL;
157  box = srcline->box;
158  box.rotate(rotation);
159  return;
160  }
161  //get memory
162  steps = (uinT8 *) alloc_mem (step_mem());
163  memset(steps, 0, step_mem());
164 
165  for (int iteration = 0; iteration < 2; ++iteration) {
166  DIR128 round1 = iteration == 0 ? 32 : 0;
167  DIR128 round2 = iteration != 0 ? 32 : 0;
168  pos = srcline->start;
169  prevpos = pos;
170  prevpos.rotate (rotation);
171  start = prevpos;
172  box = TBOX (start, start);
173  destindex = 0;
174  for (stepindex = 0; stepindex < srcline->stepcount; stepindex++) {
175  pos += srcline->step (stepindex);
176  destpos = pos;
177  destpos.rotate (rotation);
178  // tprintf("%i %i %i %i ", destpos.x(), destpos.y(), pos.x(), pos.y());
179  while (destpos.x () != prevpos.x () || destpos.y () != prevpos.y ()) {
180  dir = DIR128 (FCOORD (destpos - prevpos));
181  dir += 64; //turn to step style
182  new_step = dir.get_dir ();
183  // tprintf(" %i\n", new_step);
184  if (new_step & 31) {
185  set_step(destindex++, dir + round1);
186  prevpos += step(destindex - 1);
187  if (destindex < 2
188  || ((dirdiff =
189  step_dir (destindex - 1) - step_dir (destindex - 2)) !=
190  -64 && dirdiff != 64)) {
191  set_step(destindex++, dir + round2);
192  prevpos += step(destindex - 1);
193  } else {
194  prevpos -= step(destindex - 1);
195  destindex--;
196  prevpos -= step(destindex - 1);
197  set_step(destindex - 1, dir + round2);
198  prevpos += step(destindex - 1);
199  }
200  }
201  else {
202  set_step(destindex++, dir);
203  prevpos += step(destindex - 1);
204  }
205  while (destindex >= 2 &&
206  ((dirdiff =
207  step_dir (destindex - 1) - step_dir (destindex - 2)) == -64 ||
208  dirdiff == 64)) {
209  prevpos -= step(destindex - 1);
210  prevpos -= step(destindex - 2);
211  destindex -= 2; // Forget u turn
212  }
213  //ASSERT_HOST(prevpos.x() == destpos.x() && prevpos.y() == destpos.y());
214  new_box = TBOX (destpos, destpos);
215  box += new_box;
216  }
217  }
218  ASSERT_HOST (destpos.x () == start.x () && destpos.y () == start.y ());
219  dirdiff = step_dir (destindex - 1) - step_dir (0);
220  while ((dirdiff == 64 || dirdiff == -64) && destindex > 1) {
221  start += step (0);
222  destindex -= 2;
223  for (int i = 0; i < destindex; ++i)
224  set_step(i, step_dir(i + 1));
225  dirdiff = step_dir (destindex - 1) - step_dir (0);
226  }
227  if (destindex >= 4)
228  break;
229  }
230  ASSERT_HOST(destindex <= stepcount);
231  stepcount = destindex;
232  destpos = start;
233  for (stepindex = 0; stepindex < stepcount; stepindex++) {
234  destpos += step (stepindex);
235  }
236  ASSERT_HOST (destpos.x () == start.x () && destpos.y () == start.y ());
237 }
void rotate(const FCOORD &vec)
Definition: ipoints.h:241
Definition: mod128.h:29
#define NULL
Definition: host.h:144
DIR128 step_dir(int index) const
Definition: coutln.h:137
ICOORD step(int index) const
Definition: coutln.h:142
Definition: rect.h:30
integer coordinate
Definition: points.h:30
void * alloc_mem(inT32 count)
Definition: memry.cpp:47
inT16 x() const
access function
Definition: points.h:52
short inT16
Definition: host.h:100
void set_step(inT16 stepindex, inT8 stepdir)
Definition: coutln.h:114
Definition: points.h:189
inT8 get_dir() const
Definition: mod128.h:77
unsigned char uinT8
Definition: host.h:99
inT16 y() const
access_function
Definition: points.h:56
#define ASSERT_HOST(x)
Definition: errcode.h:84
void rotate(const FCOORD &vec)
Definition: rect.h:189
C_OUTLINE::~C_OUTLINE ( )
inline

Definition at line 89 of file coutln.h.

89  { //destructor
90  if (steps != NULL)
91  free_mem(steps);
92  steps = NULL;
93  delete [] offsets;
94  }
#define NULL
Definition: host.h:144
void free_mem(void *oldchunk)
Definition: memry.cpp:55

Member Function Documentation

inT32 C_OUTLINE::area ( ) const

Definition at line 256 of file coutln.cpp.

256  {
257  int stepindex; //current step
258  inT32 total_steps; //steps to do
259  inT32 total; //total area
260  ICOORD pos; //position of point
261  ICOORD next_step; //step to next pix
262  // We aren't going to modify the list, or its contents, but there is
263  // no const iterator.
264  C_OUTLINE_IT it(const_cast<C_OUTLINE_LIST*>(&children));
265 
266  pos = start_pos ();
267  total_steps = pathlength ();
268  total = 0;
269  for (stepindex = 0; stepindex < total_steps; stepindex++) {
270  //all intersected
271  next_step = step (stepindex);
272  if (next_step.x () < 0)
273  total += pos.y ();
274  else if (next_step.x () > 0)
275  total -= pos.y ();
276  pos += next_step;
277  }
278  for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
279  total += it.data ()->area ();//add areas of children
280 
281  return total;
282 }
int inT32
Definition: host.h:102
inT32 pathlength() const
Definition: coutln.h:133
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
inT16 x() const
access function
Definition: points.h:52
const ICOORD & start_pos() const
Definition: coutln.h:146
inT16 y() const
access_function
Definition: points.h:56
const TBOX& C_OUTLINE::bounding_box ( ) const
inline

Definition at line 111 of file coutln.h.

111  {
112  return box;
113  }
int C_OUTLINE::chain_code ( int  index) const
inline

Definition at line 193 of file coutln.h.

193  { // index of step
194  return (steps[index / 4] >> (index % 4 * 2)) & STEP_MASK;
195  }
#define STEP_MASK
Definition: coutln.h:35
ICOORD C_OUTLINE::chain_step ( int  chaindir)
static

Definition at line 1040 of file coutln.cpp.

1040  {
1041  return step_coords[chaindir % 4];
1042 }
C_OUTLINE_LIST* C_OUTLINE::child ( )
inline

Definition at line 106 of file coutln.h.

106  { //get child list
107  return &children;
108  }
void C_OUTLINE::ComputeBinaryOffsets ( )

Definition at line 834 of file coutln.cpp.

834  {
835  delete [] offsets;
836  offsets = new EdgeOffset[stepcount];
837  // Count of the number of steps in each direction in the sliding window.
838  int dir_counts[4];
839  // Sum of the positions (y for a horizontal step, x for vertical) in each
840  // direction in the sliding window.
841  int pos_totals[4];
842  memset(dir_counts, 0, sizeof(dir_counts));
843  memset(pos_totals, 0, sizeof(pos_totals));
844  ICOORD pos = start;
845  ICOORD tail_pos = pos;
846  // tail_pos is the trailing position, with the next point to be lost from
847  // the window.
848  tail_pos -= step(stepcount - 1);
849  tail_pos -= step(stepcount - 2);
850  // head_pos is the leading position, with the next point to be added to the
851  // window.
852  ICOORD head_pos = tail_pos;
853  // Set up the initial window with 4 points in [-2, 2)
854  for (int s = -2; s < 2; ++s) {
855  increment_step(s, 1, &head_pos, dir_counts, pos_totals);
856  }
857  for (int s = 0; s < stepcount; pos += step(s++)) {
858  // At step s, s in in the middle of [s-2, s+2].
859  increment_step(s + 2, 1, &head_pos, dir_counts, pos_totals);
860  int dir_index = chain_code(s);
861  ICOORD step_vec = step(s);
862  int best_diff = 0;
863  int offset = 0;
864  // Use only steps that have a count of >=2 OR the strong U-turn with a
865  // single d and 2 at d-1 and 2 at d+1 (mod 4).
866  if (dir_counts[dir_index] >= 2 || (dir_counts[dir_index] == 1 &&
867  dir_counts[Modulo(dir_index - 1, 4)] == 2 &&
868  dir_counts[Modulo(dir_index + 1, 4)] == 2)) {
869  // Valid step direction.
870  best_diff = dir_counts[dir_index];
871  int edge_pos = step_vec.x() == 0 ? pos.x() : pos.y();
872  // The offset proposes that the actual step should be positioned at
873  // the mean position of the steps in the window of the same direction.
874  // See ASCII art above.
875  offset = pos_totals[dir_index] - best_diff * edge_pos;
876  }
877  offsets[s].offset_numerator =
878  static_cast<inT8>(ClipToRange(offset, -MAX_INT8, MAX_INT8));
879  offsets[s].pixel_diff = static_cast<uinT8>(ClipToRange(best_diff, 0 ,
880  MAX_UINT8));
881  // The direction is just the vector from start to end of the window.
882  FCOORD direction(head_pos.x() - tail_pos.x(), head_pos.y() - tail_pos.y());
883  offsets[s].direction = direction.to_direction();
884  increment_step(s - 2, -1, &tail_pos, dir_counts, pos_totals);
885  }
886 }
uinT8 direction
Definition: coutln.h:62
SIGNED char inT8
Definition: host.h:98
uinT8 pixel_diff
Definition: coutln.h:61
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
int direction(EDGEPT *point)
Definition: vecfuncs.cpp:43
inT16 x() const
access function
Definition: points.h:52
#define MAX_INT8
Definition: host.h:118
Definition: points.h:189
inT8 offset_numerator
Definition: coutln.h:60
int Modulo(int a, int b)
Definition: helpers.h:157
#define MAX_UINT8
Definition: host.h:121
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:115
unsigned char uinT8
Definition: host.h:99
inT16 y() const
access_function
Definition: points.h:56
int chain_code(int index) const
Definition: coutln.h:193
void C_OUTLINE::ComputeEdgeOffsets ( int  threshold,
Pix *  pix 
)

Definition at line 722 of file coutln.cpp.

722  {
723  if (pixGetDepth(pix) != 8) return;
724  const l_uint32* data = pixGetData(pix);
725  int wpl = pixGetWpl(pix);
726  int width = pixGetWidth(pix);
727  int height = pixGetHeight(pix);
728  bool negative = flag(COUT_INVERSE);
729  delete [] offsets;
730  offsets = new EdgeOffset[stepcount];
731  ICOORD pos = start;
732  ICOORD prev_gradient;
733  ComputeGradient(data, wpl, pos.x(), height - pos.y(), width, height,
734  &prev_gradient);
735  for (int s = 0; s < stepcount; ++s) {
736  ICOORD step_vec = step(s);
737  TPOINT pt1(pos);
738  pos += step_vec;
739  TPOINT pt2(pos);
740  ICOORD next_gradient;
741  ComputeGradient(data, wpl, pos.x(), height - pos.y(), width, height,
742  &next_gradient);
743  // Use the sum of the prev and next as the working gradient.
744  ICOORD gradient = prev_gradient + next_gradient;
745  // best_diff will be manipulated to be always positive.
746  int best_diff = 0;
747  // offset will be the extrapolation of the location of the greyscale
748  // threshold from the edge with the largest difference, relative to the
749  // location of the binary edge.
750  int offset = 0;
751  if (pt1.y == pt2.y && abs(gradient.y()) * 2 >= abs(gradient.x())) {
752  // Horizontal step. diff_sign == 1 indicates black above.
753  int diff_sign = (pt1.x > pt2.x) == negative ? 1 : -1;
754  int x = MIN(pt1.x, pt2.x);
755  int y = height - pt1.y;
756  int best_sum = 0;
757  int best_y = y;
758  EvaluateVerticalDiff(data, wpl, diff_sign, x, y, height,
759  &best_diff, &best_sum, &best_y);
760  // Find the strongest edge.
761  int test_y = y;
762  do {
763  ++test_y;
764  } while (EvaluateVerticalDiff(data, wpl, diff_sign, x, test_y, height,
765  &best_diff, &best_sum, &best_y));
766  test_y = y;
767  do {
768  --test_y;
769  } while (EvaluateVerticalDiff(data, wpl, diff_sign, x, test_y, height,
770  &best_diff, &best_sum, &best_y));
771  offset = diff_sign * (best_sum / 2 - threshold) +
772  (y - best_y) * best_diff;
773  } else if (pt1.x == pt2.x && abs(gradient.x()) * 2 >= abs(gradient.y())) {
774  // Vertical step. diff_sign == 1 indicates black on the left.
775  int diff_sign = (pt1.y > pt2.y) == negative ? 1 : -1;
776  int x = pt1.x;
777  int y = height - MAX(pt1.y, pt2.y);
778  const l_uint32* line = pixGetData(pix) + y * wpl;
779  int best_sum = 0;
780  int best_x = x;
781  EvaluateHorizontalDiff(line, diff_sign, x, width,
782  &best_diff, &best_sum, &best_x);
783  // Find the strongest edge.
784  int test_x = x;
785  do {
786  ++test_x;
787  } while (EvaluateHorizontalDiff(line, diff_sign, test_x, width,
788  &best_diff, &best_sum, &best_x));
789  test_x = x;
790  do {
791  --test_x;
792  } while (EvaluateHorizontalDiff(line, diff_sign, test_x, width,
793  &best_diff, &best_sum, &best_x));
794  offset = diff_sign * (threshold - best_sum / 2) +
795  (best_x - x) * best_diff;
796  }
797  offsets[s].offset_numerator =
798  static_cast<inT8>(ClipToRange(offset, -MAX_INT8, MAX_INT8));
799  offsets[s].pixel_diff = static_cast<uinT8>(ClipToRange(best_diff, 0 ,
800  MAX_UINT8));
801  if (negative) gradient = -gradient;
802  // Compute gradient angle quantized to 256 directions, rotated by 64 (pi/2)
803  // to convert from gradient direction to edge direction.
804  offsets[s].direction =
805  Modulo(FCOORD::binary_angle_plus_pi(gradient.angle()) + 64, 256);
806  prev_gradient = next_gradient;
807  }
808 }
#define MIN(x, y)
Definition: ndminx.h:28
uinT8 direction
Definition: coutln.h:62
SIGNED char inT8
Definition: host.h:98
Definition: blobs.h:50
#define MAX(x, y)
Definition: ndminx.h:24
uinT8 pixel_diff
Definition: coutln.h:61
BOOL8 flag(C_OUTLINE_FLAGS mask) const
Definition: coutln.h:96
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
static uinT8 binary_angle_plus_pi(double angle)
Definition: points.cpp:124
inT16 x() const
access function
Definition: points.h:52
#define MAX_INT8
Definition: host.h:118
inT8 offset_numerator
Definition: coutln.h:60
int Modulo(int a, int b)
Definition: helpers.h:157
#define MAX_UINT8
Definition: host.h:121
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:115
unsigned char uinT8
Definition: host.h:99
inT16 y() const
access_function
Definition: points.h:56
inT32 C_OUTLINE::count_transitions ( inT32  threshold)

Definition at line 342 of file coutln.cpp.

344  {
345  BOOL8 first_was_max_x; //what was first
346  BOOL8 first_was_max_y;
347  BOOL8 looking_for_max_x; //what is next
348  BOOL8 looking_for_min_x;
349  BOOL8 looking_for_max_y; //what is next
350  BOOL8 looking_for_min_y;
351  int stepindex; //current step
352  inT32 total_steps; //steps to do
353  //current limits
354  inT32 max_x, min_x, max_y, min_y;
355  inT32 initial_x, initial_y; //initial limits
356  inT32 total; //total changes
357  ICOORD pos; //position of point
358  ICOORD next_step; //step to next pix
359 
360  pos = start_pos ();
361  total_steps = pathlength ();
362  total = 0;
363  max_x = min_x = pos.x ();
364  max_y = min_y = pos.y ();
365  looking_for_max_x = TRUE;
366  looking_for_min_x = TRUE;
367  looking_for_max_y = TRUE;
368  looking_for_min_y = TRUE;
369  first_was_max_x = FALSE;
370  first_was_max_y = FALSE;
371  initial_x = pos.x ();
372  initial_y = pos.y (); //stop uninit warning
373  for (stepindex = 0; stepindex < total_steps; stepindex++) {
374  //all intersected
375  next_step = step (stepindex);
376  pos += next_step;
377  if (next_step.x () < 0) {
378  if (looking_for_max_x && pos.x () < min_x)
379  min_x = pos.x ();
380  if (looking_for_min_x && max_x - pos.x () > threshold) {
381  if (looking_for_max_x) {
382  initial_x = max_x;
383  first_was_max_x = FALSE;
384  }
385  total++;
386  looking_for_max_x = TRUE;
387  looking_for_min_x = FALSE;
388  min_x = pos.x (); //reset min
389  }
390  }
391  else if (next_step.x () > 0) {
392  if (looking_for_min_x && pos.x () > max_x)
393  max_x = pos.x ();
394  if (looking_for_max_x && pos.x () - min_x > threshold) {
395  if (looking_for_min_x) {
396  initial_x = min_x; //remember first min
397  first_was_max_x = TRUE;
398  }
399  total++;
400  looking_for_max_x = FALSE;
401  looking_for_min_x = TRUE;
402  max_x = pos.x ();
403  }
404  }
405  else if (next_step.y () < 0) {
406  if (looking_for_max_y && pos.y () < min_y)
407  min_y = pos.y ();
408  if (looking_for_min_y && max_y - pos.y () > threshold) {
409  if (looking_for_max_y) {
410  initial_y = max_y; //remember first max
411  first_was_max_y = FALSE;
412  }
413  total++;
414  looking_for_max_y = TRUE;
415  looking_for_min_y = FALSE;
416  min_y = pos.y (); //reset min
417  }
418  }
419  else {
420  if (looking_for_min_y && pos.y () > max_y)
421  max_y = pos.y ();
422  if (looking_for_max_y && pos.y () - min_y > threshold) {
423  if (looking_for_min_y) {
424  initial_y = min_y; //remember first min
425  first_was_max_y = TRUE;
426  }
427  total++;
428  looking_for_max_y = FALSE;
429  looking_for_min_y = TRUE;
430  max_y = pos.y ();
431  }
432  }
433 
434  }
435  if (first_was_max_x && looking_for_min_x) {
436  if (max_x - initial_x > threshold)
437  total++;
438  else
439  total--;
440  }
441  else if (!first_was_max_x && looking_for_max_x) {
442  if (initial_x - min_x > threshold)
443  total++;
444  else
445  total--;
446  }
447  if (first_was_max_y && looking_for_min_y) {
448  if (max_y - initial_y > threshold)
449  total++;
450  else
451  total--;
452  }
453  else if (!first_was_max_y && looking_for_max_y) {
454  if (initial_y - min_y > threshold)
455  total++;
456  else
457  total--;
458  }
459 
460  return total;
461 }
int inT32
Definition: host.h:102
inT32 pathlength() const
Definition: coutln.h:133
#define FALSE
Definition: capi.h:29
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
inT16 x() const
access function
Definition: points.h:52
const ICOORD & start_pos() const
Definition: coutln.h:146
unsigned char BOOL8
Definition: host.h:113
#define TRUE
Definition: capi.h:28
inT16 y() const
access_function
Definition: points.h:56
static C_OUTLINE* C_OUTLINE::deep_copy ( const C_OUTLINE src)
inlinestatic

Definition at line 259 of file coutln.h.

259  {
260  C_OUTLINE* outline = new C_OUTLINE;
261  *outline = *src;
262  return outline;
263  }
C_OUTLINE()
Definition: coutln.h:71
int C_OUTLINE::direction_at_index ( int  index) const
inline

Definition at line 176 of file coutln.h.

176  {
177  if (offsets != NULL && offsets[index].pixel_diff > 0)
178  return offsets[index].direction;
179  return -1;
180  }
uinT8 direction
Definition: coutln.h:62
#define NULL
Definition: host.h:144
int C_OUTLINE::edge_strength_at_index ( int  index) const
inline

Definition at line 185 of file coutln.h.

185  {
186  if (offsets != NULL)
187  return offsets[index].pixel_diff;
188  return 1;
189  }
uinT8 pixel_diff
Definition: coutln.h:61
#define NULL
Definition: host.h:144
void C_OUTLINE::FakeOutline ( const TBOX box,
C_OUTLINE_LIST *  outlines 
)
static

Definition at line 240 of file coutln.cpp.

240  {
241  C_OUTLINE_IT ol_it(outlines);
242  // Make a C_OUTLINE from the bounds. This is a bit of a hack,
243  // as there is no outline, just a bounding box, but it works nicely.
244  CRACKEDGE start;
245  start.pos = box.topleft();
246  C_OUTLINE* outline = new C_OUTLINE(&start, box.topleft(), box.botright(), 0);
247  ol_it.add_to_end(outline);
248 }
ICOORD topleft() const
Definition: rect.h:96
ICOORD pos
Definition: crakedge.h:30
ICOORD botright() const
Definition: rect.h:92
C_OUTLINE()
Definition: coutln.h:71
BOOL8 C_OUTLINE::flag ( C_OUTLINE_FLAGS  mask) const
inline

Definition at line 96 of file coutln.h.

97  { //flag to test
98  return flags.bit (mask);
99  }
BOOL8 bit(uinT8 bit_num) const
Definition: bits16.h:56
bool C_OUTLINE::IsLegallyNested ( ) const

Definition at line 615 of file coutln.cpp.

615  {
616  if (stepcount == 0) return true;
617  int parent_area = outer_area();
618  // We aren't going to modify the list, or its contents, but there is
619  // no const iterator.
620  C_OUTLINE_IT child_it(const_cast<C_OUTLINE_LIST*>(&children));
621  for (child_it.mark_cycle_pt(); !child_it.cycled_list(); child_it.forward()) {
622  const C_OUTLINE* child = child_it.data();
623  if (child->outer_area() * parent_area > 0 || !child->IsLegallyNested())
624  return false;
625  }
626  return true;
627 }
C_OUTLINE_LIST * child()
Definition: coutln.h:106
inT32 outer_area() const
Definition: coutln.cpp:310
bool IsLegallyNested() const
Definition: coutln.cpp:615
void C_OUTLINE::move ( const ICOORD  vec)

Definition at line 599 of file coutln.cpp.

601  {
602  C_OUTLINE_IT it(&children); // iterator
603 
604  box.move (vec);
605  start += vec;
606 
607  for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
608  it.data ()->move (vec); // move child outlines
609 }
void move(const ICOORD vec)
Definition: rect.h:153
BOOL8 C_OUTLINE::operator< ( const C_OUTLINE other) const

Definition at line 471 of file coutln.cpp.

474 {
475  inT16 count = 0; //winding count
476  ICOORD pos; //position of point
477  inT32 stepindex; //index to cstep
478 
479  if (!box.overlap (other.box))
480  return FALSE; //can't be contained
481  if (stepcount == 0)
482  return other.box.contains(this->box);
483 
484  pos = start;
485  for (stepindex = 0; stepindex < stepcount
486  && (count = other.winding_number (pos)) == INTERSECTING; stepindex++)
487  pos += step (stepindex); //try all points
488  if (count == INTERSECTING) {
489  //all intersected
490  pos = other.start;
491  for (stepindex = 0; stepindex < other.stepcount
492  && (count = winding_number (pos)) == INTERSECTING; stepindex++)
493  //try other way round
494  pos += other.step (stepindex);
495  return count == INTERSECTING || count == 0;
496  }
497  return count != 0;
498 }
int inT32
Definition: host.h:102
bool overlap(const TBOX &box) const
Definition: rect.h:345
#define FALSE
Definition: capi.h:29
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
short inT16
Definition: host.h:100
#define INTERSECTING
Definition: coutln.h:32
bool contains(const FCOORD pt) const
Definition: rect.h:323
int count(LIST var_list)
Definition: oldlist.cpp:108
inT16 winding_number(ICOORD testpt) const
Definition: coutln.cpp:507
C_OUTLINE & C_OUTLINE::operator= ( const C_OUTLINE source)

Definition at line 1000 of file coutln.cpp.

1002  {
1003  box = source.box;
1004  start = source.start;
1005  if (steps != NULL)
1006  free_mem(steps);
1007  stepcount = source.stepcount;
1008  steps = (uinT8 *) alloc_mem (step_mem());
1009  memmove (steps, source.steps, step_mem());
1010  if (!children.empty ())
1011  children.clear ();
1012  children.deep_copy(&source.children, &deep_copy);
1013  delete [] offsets;
1014  if (source.offsets != NULL) {
1015  offsets = new EdgeOffset[stepcount];
1016  memcpy(offsets, source.offsets, stepcount * sizeof(*offsets));
1017  } else {
1018  offsets = NULL;
1019  }
1020  return *this;
1021 }
static C_OUTLINE * deep_copy(const C_OUTLINE *src)
Definition: coutln.h:259
#define NULL
Definition: host.h:144
void * alloc_mem(inT32 count)
Definition: memry.cpp:47
unsigned char uinT8
Definition: host.h:99
void free_mem(void *oldchunk)
Definition: memry.cpp:55
BOOL8 C_OUTLINE::operator> ( C_OUTLINE other) const
inline

Definition at line 205 of file coutln.h.

207  {
208  return other < *this; //use the < to do it
209  }
inT32 C_OUTLINE::outer_area ( ) const

Definition at line 310 of file coutln.cpp.

310  {
311  int stepindex; //current step
312  inT32 total_steps; //steps to do
313  inT32 total; //total area
314  ICOORD pos; //position of point
315  ICOORD next_step; //step to next pix
316 
317  pos = start_pos ();
318  total_steps = pathlength ();
319  if (total_steps == 0)
320  return box.area();
321  total = 0;
322  for (stepindex = 0; stepindex < total_steps; stepindex++) {
323  //all intersected
324  next_step = step (stepindex);
325  if (next_step.x () < 0)
326  total += pos.y ();
327  else if (next_step.x () > 0)
328  total -= pos.y ();
329  pos += next_step;
330  }
331 
332  return total;
333 }
int inT32
Definition: host.h:102
inT32 pathlength() const
Definition: coutln.h:133
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
inT16 x() const
access function
Definition: points.h:52
const ICOORD & start_pos() const
Definition: coutln.h:146
inT32 area() const
Definition: rect.h:118
inT16 y() const
access_function
Definition: points.h:56
inT32 C_OUTLINE::pathlength ( ) const
inline

Definition at line 133 of file coutln.h.

133  { //get path length
134  return stepcount;
135  }
inT32 C_OUTLINE::perimeter ( ) const

Definition at line 290 of file coutln.cpp.

290  {
291  inT32 total_steps; // Return value.
292  // We aren't going to modify the list, or its contents, but there is
293  // no const iterator.
294  C_OUTLINE_IT it(const_cast<C_OUTLINE_LIST*>(&children));
295 
296  total_steps = pathlength();
297  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward())
298  total_steps += it.data()->pathlength(); // Add perimeters of children.
299 
300  return total_steps;
301 }
int inT32
Definition: host.h:102
inT32 pathlength() const
Definition: coutln.h:133
void C_OUTLINE::plot ( ScrollView window,
ScrollView::Color  colour 
) const

Definition at line 931 of file coutln.cpp.

934  {
935  inT16 stepindex; // index to cstep
936  ICOORD pos; // current position
937  DIR128 stepdir; // direction of step
938 
939  pos = start; // current position
940  window->Pen(colour);
941  if (stepcount == 0) {
942  window->Rectangle(box.left(), box.top(), box.right(), box.bottom());
943  return;
944  }
945  window->SetCursor(pos.x(), pos.y());
946 
947  stepindex = 0;
948  while (stepindex < stepcount) {
949  pos += step(stepindex); // step to next
950  stepdir = step_dir(stepindex);
951  stepindex++; // count steps
952  // merge straight lines
953  while (stepindex < stepcount &&
954  stepdir.get_dir() == step_dir(stepindex).get_dir()) {
955  pos += step(stepindex);
956  stepindex++;
957  }
958  window->DrawTo(pos.x(), pos.y());
959  }
960 }
void SetCursor(int x, int y)
Definition: scrollview.cpp:525
Definition: mod128.h:29
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:606
inT16 left() const
Definition: rect.h:68
inT16 right() const
Definition: rect.h:75
DIR128 step_dir(int index) const
Definition: coutln.h:137
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
inT16 x() const
access function
Definition: points.h:52
short inT16
Definition: host.h:100
void DrawTo(int x, int y)
Definition: scrollview.cpp:531
void Pen(Color color)
Definition: scrollview.cpp:726
inT16 bottom() const
Definition: rect.h:61
inT8 get_dir() const
Definition: mod128.h:77
inT16 y() const
access_function
Definition: points.h:56
inT16 top() const
Definition: rect.h:54
void C_OUTLINE::plot_normed ( const DENORM denorm,
ScrollView::Color  colour,
ScrollView window 
) const

Definition at line 963 of file coutln.cpp.

964  {
965  window->Pen(colour);
966  if (stepcount == 0) {
967  window->Rectangle(box.left(), box.top(), box.right(), box.bottom());
968  return;
969  }
970  const DENORM* root_denorm = denorm.RootDenorm();
971  ICOORD pos = start; // current position
972  FCOORD f_pos = sub_pixel_pos_at_index(pos, 0);
973  FCOORD pos_normed;
974  denorm.NormTransform(root_denorm, f_pos, &pos_normed);
975  window->SetCursor(IntCastRounded(pos_normed.x()),
976  IntCastRounded(pos_normed.y()));
977  for (int s = 0; s < stepcount; pos += step(s++)) {
978  int edge_weight = edge_strength_at_index(s);
979  if (edge_weight == 0) {
980  // This point has conflicting gradient and step direction, so ignore it.
981  continue;
982  }
983  FCOORD f_pos = sub_pixel_pos_at_index(pos, s);
984  FCOORD pos_normed;
985  denorm.NormTransform(root_denorm, f_pos, &pos_normed);
986  window->DrawTo(IntCastRounded(pos_normed.x()),
987  IntCastRounded(pos_normed.y()));
988  }
989 }
float y() const
Definition: points.h:212
int IntCastRounded(double x)
Definition: helpers.h:172
void SetCursor(int x, int y)
Definition: scrollview.cpp:525
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:606
inT16 left() const
Definition: rect.h:68
inT16 right() const
Definition: rect.h:75
float x() const
Definition: points.h:209
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
void NormTransform(const DENORM *first_norm, const TPOINT &pt, TPOINT *transformed) const
Definition: normalis.cpp:334
void DrawTo(int x, int y)
Definition: scrollview.cpp:531
void Pen(Color color)
Definition: scrollview.cpp:726
const DENORM * RootDenorm() const
Definition: normalis.h:260
inT16 bottom() const
Definition: rect.h:61
Definition: points.h:189
FCOORD sub_pixel_pos_at_index(const ICOORD &pos, int index) const
Definition: coutln.h:161
inT16 top() const
Definition: rect.h:54
int edge_strength_at_index(int index) const
Definition: coutln.h:185
ICOORD C_OUTLINE::position_at_index ( int  index) const
inline

Definition at line 151 of file coutln.h.

151  {
152  ICOORD pos = start;
153  for (int i = 0; i < index; ++i)
154  pos += step(i);
155  return pos;
156  }
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
void C_OUTLINE::RemoveSmallRecursive ( int  min_size,
C_OUTLINE_IT *  it 
)

Definition at line 634 of file coutln.cpp.

634  {
635  if (box.width() < min_size || box.height() < min_size) {
636  ASSERT_HOST(this == it->data());
637  delete it->extract(); // Too small so get rid of it and any children.
638  } else if (!children.empty()) {
639  // Search the children of this, deleting any that are too small.
640  C_OUTLINE_IT child_it(&children);
641  for (child_it.mark_cycle_pt(); !child_it.cycled_list();
642  child_it.forward()) {
643  C_OUTLINE* child = child_it.data();
644  child->RemoveSmallRecursive(min_size, &child_it);
645  }
646  }
647 }
C_OUTLINE_LIST * child()
Definition: coutln.h:106
inT16 height() const
Definition: rect.h:104
void RemoveSmallRecursive(int min_size, C_OUTLINE_IT *it)
Definition: coutln.cpp:634
inT16 width() const
Definition: rect.h:111
#define ASSERT_HOST(x)
Definition: errcode.h:84
void C_OUTLINE::render ( int  left,
int  top,
Pix *  pix 
) const

Definition at line 890 of file coutln.cpp.

890  {
891  ICOORD pos = start;
892  for (int stepindex = 0; stepindex < stepcount; ++stepindex) {
893  ICOORD next_step = step(stepindex);
894  if (next_step.y() < 0) {
895  pixRasterop(pix, 0, top - pos.y(), pos.x() - left, 1,
896  PIX_NOT(PIX_DST), NULL, 0, 0);
897  } else if (next_step.y() > 0) {
898  pixRasterop(pix, 0, top - pos.y() - 1, pos.x() - left, 1,
899  PIX_NOT(PIX_DST), NULL, 0, 0);
900  }
901  pos += next_step;
902  }
903 }
#define NULL
Definition: host.h:144
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
inT16 x() const
access function
Definition: points.h:52
inT16 y() const
access_function
Definition: points.h:56
void C_OUTLINE::render_outline ( int  left,
int  top,
Pix *  pix 
) const

Definition at line 907 of file coutln.cpp.

907  {
908  ICOORD pos = start;
909  for (int stepindex = 0; stepindex < stepcount; ++stepindex) {
910  ICOORD next_step = step(stepindex);
911  if (next_step.y() < 0) {
912  pixSetPixel(pix, pos.x() - left, top - pos.y(), 1);
913  } else if (next_step.y() > 0) {
914  pixSetPixel(pix, pos.x() - left - 1, top - pos.y() - 1, 1);
915  } else if (next_step.x() < 0) {
916  pixSetPixel(pix, pos.x() - left - 1, top - pos.y(), 1);
917  } else if (next_step.x() > 0) {
918  pixSetPixel(pix, pos.x() - left, top - pos.y() - 1, 1);
919  }
920  pos += next_step;
921  }
922 }
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
inT16 x() const
access function
Definition: points.h:52
inT16 y() const
access_function
Definition: points.h:56
void C_OUTLINE::reverse ( )

Definition at line 576 of file coutln.cpp.

576  { //reverse drection
577  DIR128 halfturn = MODULUS / 2; //amount to shift
578  DIR128 stepdir; //direction of step
579  inT16 stepindex; //index to cstep
580  inT16 farindex; //index to other side
581  inT16 halfsteps; //half of stepcount
582 
583  halfsteps = (stepcount + 1) / 2;
584  for (stepindex = 0; stepindex < halfsteps; stepindex++) {
585  farindex = stepcount - stepindex - 1;
586  stepdir = step_dir (stepindex);
587  set_step (stepindex, step_dir (farindex) + halfturn);
588  set_step (farindex, stepdir + halfturn);
589  }
590 }
Definition: mod128.h:29
#define MODULUS
Definition: mod128.h:25
DIR128 step_dir(int index) const
Definition: coutln.h:137
short inT16
Definition: host.h:100
void set_step(inT16 stepindex, inT8 stepdir)
Definition: coutln.h:114
void C_OUTLINE::set_flag ( C_OUTLINE_FLAGS  mask,
BOOL8  value 
)
inline

Definition at line 100 of file coutln.h.

102  { //value to set
103  flags.set_bit (mask, value);
104  }
void set_bit(uinT8 bit_num, BOOL8 value)
Definition: bits16.h:47
void C_OUTLINE::set_step ( inT16  stepindex,
inT8  stepdir 
)
inline

Definition at line 114 of file coutln.h.

116  { //chain code
117  int shift = stepindex%4 * 2;
118  uinT8 mask = 3 << shift;
119  steps[stepindex/4] = ((stepdir << shift) & mask) |
120  (steps[stepindex/4] & ~mask);
121  //squeeze 4 into byte
122  }
unsigned char uinT8
Definition: host.h:99
void C_OUTLINE::set_step ( inT16  stepindex,
DIR128  stepdir 
)
inline

Definition at line 123 of file coutln.h.

125  { //direction
126  //clean it
127  inT8 chaindir = stepdir.get_dir() >> (DIRBITS - 2);
128  //difference
129  set_step(stepindex, chaindir);
130  //squeeze 4 into byte
131  }
SIGNED char inT8
Definition: host.h:98
void set_step(inT16 stepindex, inT8 stepdir)
Definition: coutln.h:114
inT8 get_dir() const
Definition: mod128.h:77
#define DIRBITS
Definition: mod128.h:26
const ICOORD& C_OUTLINE::start_pos ( ) const
inline

Definition at line 146 of file coutln.h.

146  {
147  return start;
148  }
ICOORD C_OUTLINE::step ( int  index) const
inline

Definition at line 142 of file coutln.h.

142  { // index of step
143  return step_coords[chain_code(index)];
144  }
int chain_code(int index) const
Definition: coutln.h:193
DIR128 C_OUTLINE::step_dir ( int  index) const
inline

Definition at line 137 of file coutln.h.

137  {
138  return DIR128((inT16)(((steps[index/4] >> (index%4 * 2)) & STEP_MASK) <<
139  (DIRBITS - 2)));
140  }
#define STEP_MASK
Definition: coutln.h:35
Definition: mod128.h:29
short inT16
Definition: host.h:100
#define DIRBITS
Definition: mod128.h:26
FCOORD C_OUTLINE::sub_pixel_pos_at_index ( const ICOORD pos,
int  index 
) const
inline

Definition at line 161 of file coutln.h.

161  {
162  const ICOORD& step_to_next(step(index));
163  FCOORD f_pos(pos.x() + step_to_next.x() / 2.0f,
164  pos.y() + step_to_next.y() / 2.0f);
165  if (offsets != NULL && offsets[index].pixel_diff > 0) {
166  float offset = offsets[index].offset_numerator;
167  offset /= offsets[index].pixel_diff;
168  if (step_to_next.x() != 0)
169  f_pos.set_y(f_pos.y() + offset);
170  else
171  f_pos.set_x(f_pos.x() + offset);
172  }
173  return f_pos;
174  }
uinT8 pixel_diff
Definition: coutln.h:61
#define NULL
Definition: host.h:144
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
inT16 x() const
access function
Definition: points.h:52
Definition: points.h:189
inT8 offset_numerator
Definition: coutln.h:60
inT16 y() const
access_function
Definition: points.h:56
inT16 C_OUTLINE::turn_direction ( ) const

Definition at line 547 of file coutln.cpp.

547  { //winding number
548  DIR128 prevdir; //previous direction
549  DIR128 dir; //current direction
550  inT16 stepindex; //index to cstep
551  inT8 dirdiff; //direction difference
552  inT16 count; //winding count
553 
554  if (stepcount == 0)
555  return 128;
556  count = 0;
557  prevdir = step_dir (stepcount - 1);
558  for (stepindex = 0; stepindex < stepcount; stepindex++) {
559  dir = step_dir (stepindex);
560  dirdiff = dir - prevdir;
561  ASSERT_HOST (dirdiff == 0 || dirdiff == 32 || dirdiff == -32);
562  count += dirdiff;
563  prevdir = dir;
564  }
565  ASSERT_HOST (count == 128 || count == -128);
566  return count; //winding number
567 }
SIGNED char inT8
Definition: host.h:98
Definition: mod128.h:29
DIR128 step_dir(int index) const
Definition: coutln.h:137
short inT16
Definition: host.h:100
int count(LIST var_list)
Definition: oldlist.cpp:108
#define ASSERT_HOST(x)
Definition: errcode.h:84
inT16 C_OUTLINE::winding_number ( ICOORD  testpt) const

Definition at line 507 of file coutln.cpp.

509  {
510  inT16 stepindex; //index to cstep
511  inT16 count; //winding count
512  ICOORD vec; //to current point
513  ICOORD stepvec; //step vector
514  inT32 cross; //cross product
515 
516  vec = start - point; //vector to it
517  count = 0;
518  for (stepindex = 0; stepindex < stepcount; stepindex++) {
519  stepvec = step (stepindex); //get the step
520  //crossing the line
521  if (vec.y () <= 0 && vec.y () + stepvec.y () > 0) {
522  cross = vec * stepvec; //cross product
523  if (cross > 0)
524  count++; //crossing right half
525  else if (cross == 0)
526  return INTERSECTING; //going through point
527  }
528  else if (vec.y () > 0 && vec.y () + stepvec.y () <= 0) {
529  cross = vec * stepvec;
530  if (cross < 0)
531  count--; //crossing back
532  else if (cross == 0)
533  return INTERSECTING; //illegal
534  }
535  vec += stepvec; //sum vectors
536  }
537  return count; //winding number
538 }
int inT32
Definition: host.h:102
ICOORD step(int index) const
Definition: coutln.h:142
integer coordinate
Definition: points.h:30
short inT16
Definition: host.h:100
#define INTERSECTING
Definition: coutln.h:32
inT16 y() const
access_function
Definition: points.h:56
int count(LIST var_list)
Definition: oldlist.cpp:108

Member Data Documentation

const int C_OUTLINE::kMaxOutlineLength = 16000
static

Definition at line 271 of file coutln.h.


The documentation for this class was generated from the following files: