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 "crakedge.h"
00024 #include "mod128.h"
00025 #include "bits16.h"
00026 #include "rect.h"
00027 #include "blckerr.h"
00028 #include "scrollview.h"
00029
00030 #define INTERSECTING MAX_INT16//no winding number
00031
00032
00033 #define STEP_MASK 3
00034
00035 enum C_OUTLINE_FLAGS
00036 {
00037 COUT_INVERSE
00038 };
00039
00040 class DLLSYM C_OUTLINE;
00041 struct Pix;
00042
00043 ELISTIZEH (C_OUTLINE)
00044 class DLLSYM C_OUTLINE:public ELIST_LINK
00045 {
00046 public:
00047 C_OUTLINE() {
00048 steps = NULL;
00049 }
00050 C_OUTLINE(
00051 CRACKEDGE *startpt,
00052 ICOORD bot_left,
00053 ICOORD top_right,
00054 inT16 length);
00055 C_OUTLINE(ICOORD startpt,
00056 DIR128 *new_steps,
00057 inT16 length);
00058
00059 C_OUTLINE(C_OUTLINE *srcline, FCOORD rotation);
00060
00061
00062 static void FakeOutline(const TBOX& box, C_OUTLINE_LIST* outlines);
00063
00064 ~C_OUTLINE () {
00065 if (steps != NULL)
00066 free_mem(steps);
00067 steps = NULL;
00068 }
00069
00070 BOOL8 flag(
00071 C_OUTLINE_FLAGS mask) const {
00072 return flags.bit (mask);
00073 }
00074 void set_flag(
00075 C_OUTLINE_FLAGS mask,
00076 BOOL8 value) {
00077 flags.set_bit (mask, value);
00078 }
00079
00080 C_OUTLINE_LIST *child() {
00081 return &children;
00082 }
00083
00084
00085 const TBOX &bounding_box() const {
00086 return box;
00087 }
00088 void set_step(
00089 inT16 stepindex,
00090 inT8 stepdir) {
00091 int shift = stepindex%4 * 2;
00092 uinT8 mask = 3 << shift;
00093 steps[stepindex/4] = ((stepdir << shift) & mask) |
00094 (steps[stepindex/4] & ~mask);
00095
00096 }
00097 void set_step(
00098 inT16 stepindex,
00099 DIR128 stepdir) {
00100
00101 inT8 chaindir = stepdir.get_dir() >> (DIRBITS - 2);
00102
00103 set_step(stepindex, chaindir);
00104
00105 }
00106
00107
00108 const ICOORD &start_pos() const {
00109 return start;
00110 }
00111 inT32 pathlength() const {
00112 return stepcount;
00113 }
00114
00115 DIR128 step_dir(inT16 index) const {
00116 return DIR128((inT16)(((steps[index/4] >> (index%4 * 2)) & STEP_MASK) <<
00117 (DIRBITS - 2)));
00118 }
00119
00120 ICOORD step(inT16 index) const {
00121 return step_coords[(steps[index/4] >> (index%4 * 2)) & STEP_MASK];
00122 }
00123
00124 inT32 area();
00125 inT32 perimeter();
00126 inT32 outer_area();
00127 inT32 count_transitions(
00128 inT32 threshold);
00129
00130 BOOL8 operator< (
00131 const C_OUTLINE & other) const;
00132 BOOL8 operator> (
00133 C_OUTLINE & other) const
00134 {
00135 return other < *this;
00136 }
00137 inT16 winding_number(
00138 ICOORD testpt) const;
00139
00140 inT16 turn_direction() const;
00141 void reverse();
00142
00143 void move(
00144 const ICOORD vec);
00145
00146
00147
00148
00149
00150
00151 void RemoveSmallRecursive(int min_size, C_OUTLINE_IT* it);
00152
00153
00154
00155 void render(int left, int top, Pix* pix) const;
00156
00157
00158
00159 void render_outline(int left, int top, Pix* pix) const;
00160
00161 void plot(
00162 ScrollView* window,
00163 ScrollView::Color colour) const;
00164
00165 C_OUTLINE& operator=(const C_OUTLINE& source);
00166
00167 static C_OUTLINE* deep_copy(const C_OUTLINE* src) {
00168 C_OUTLINE* outline = new C_OUTLINE;
00169 *outline = *src;
00170 return outline;
00171 }
00172
00173 static ICOORD chain_step(int chaindir);
00174
00175 private:
00176 int step_mem() const { return (stepcount+3) / 4; }
00177
00178 TBOX box;
00179 ICOORD start;
00180 uinT8 *steps;
00181 inT16 stepcount;
00182 BITS16 flags;
00183 C_OUTLINE_LIST children;
00184 static ICOORD step_coords[4];
00185 };
00186 #endif