00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef COUTLN_H
00021 #define COUTLN_H
00022
00023 #include "grphics.h"
00024 #include "crakedge.h"
00025 #include "mod128.h"
00026 #include "bits16.h"
00027 #include "rect.h"
00028 #include "blckerr.h"
00029
00030 #define INTERSECTING MAX_INT16//no winding number
00031
00032
00033 #define STEP_MASK 3
00034
00040 enum C_OUTLINE_FLAGS
00041 {
00042 COUT_INVERSE
00043 };
00044
00045 class DLLSYM C_OUTLINE;
00046
00047 ELISTIZEH_S (C_OUTLINE)
00048
00049
00053 class DLLSYM C_OUTLINE:public ELIST_LINK
00054 {
00055 public:
00056 C_OUTLINE() {
00057 steps = NULL;
00058 }
00059 C_OUTLINE(
00060 CRACKEDGE *startpt,
00061 ICOORD bot_left,
00062 ICOORD top_right,
00063 INT16 length);
00064 C_OUTLINE(ICOORD startpt,
00065 DIR128 *new_steps,
00066 INT16 length);
00067
00068 C_OUTLINE(C_OUTLINE *srcline, FCOORD rotation);
00069 ~C_OUTLINE () {
00070 if (steps != NULL)
00071 free_mem(steps);
00072 steps = NULL;
00073 }
00074
00075 BOOL8 flag(
00076 C_OUTLINE_FLAGS mask) const {
00077 return flags.bit (mask);
00078 }
00079 void set_flag(
00080 C_OUTLINE_FLAGS mask,
00081 BOOL8 value) {
00082 flags.set_bit (mask, value);
00083 }
00084
00085 C_OUTLINE_LIST *child() {
00086 return &children;
00087 }
00088
00089
00090 const BOX &bounding_box() const {
00091 return box;
00092 }
00093 void set_step(
00094 INT16 stepindex,
00095 INT8 stepdir) {
00096 int shift = stepindex%4 * 2;
00097 UINT8 mask = 3 << shift;
00098 steps[stepindex/4] = ((stepdir << shift) & mask) |
00099 (steps[stepindex/4] & ~mask);
00100
00101 }
00102 void set_step(
00103 INT16 stepindex,
00104 DIR128 stepdir) {
00105
00106 INT8 chaindir = stepdir.get_dir() >> (DIRBITS - 2);
00107
00108 set_step(stepindex, chaindir);
00109
00110 }
00111
00112
00113 const ICOORD &start_pos() const {
00114 return start;
00115 }
00116 INT32 pathlength() const {
00117 return stepcount;
00118 }
00119
00120 DIR128 step_dir(INT16 index) const {
00121 return DIR128((INT16)(((steps[index/4] >> (index%4 * 2)) & STEP_MASK) <<
00122 (DIRBITS - 2)));
00123 }
00124
00125 ICOORD step(INT16 index) const {
00126 return step_coords[(steps[index/4] >> (index%4 * 2)) & STEP_MASK];
00127 }
00128
00129 INT32 area();
00130 INT32 outer_area();
00131 INT32 count_transitions(
00132 INT32 threshold);
00133
00134 BOOL8 operator< (
00135 const C_OUTLINE & other) const;
00136 BOOL8 operator> (
00137 C_OUTLINE & other) const
00138 {
00139 return other < *this;
00140 }
00141 INT16 winding_number(
00142 ICOORD testpt) const;
00143
00144 INT16 turn_direction() const;
00145 void reverse();
00146
00147 void move(
00148 const ICOORD vec);
00149
00150 void plot(
00151 WINDOW window,
00152 COLOUR colour) const;
00153
00154 void prep_serialise() {
00155 children.prep_serialise ();
00156 }
00157
00158 void dump(
00159 FILE *f) {
00160
00161 serialise_bytes (f, (void *) steps, step_mem());
00162 children.dump (f);
00163 }
00164
00165 void de_dump(
00166 FILE *f) {
00167 steps = (UINT8 *) de_serialise_bytes (f, step_mem());
00168 children.de_dump (f);
00169 }
00170
00171
00172 make_serialise (C_OUTLINE) C_OUTLINE & operator= (
00173 const C_OUTLINE & source);
00174
00175 private:
00176 int step_mem() const { return (stepcount+3) / 4; }
00177
00179 BOX box;
00181 ICOORD start;
00183 UINT8 *steps;
00185 INT16 stepcount;
00187 BITS16 flags;
00189 C_OUTLINE_LIST children;
00190 static ICOORD step_coords[4];
00191 };
00192 #endif