/********************************************************************** * C_OUTLINE::C_OUTLINE * * Constructor to build a C_OUTLINE from a C_OUTLINE_FRAG. **********************************************************************/ C_OUTLINE::C_OUTLINE ( //constructor //steps to copy ICOORD startpt, DIR128 * new_steps, inT16 length //length of loop ):start (startpt) { 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 //get memory 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; //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); }
//assignment C_OUTLINE & C_OUTLINE::operator= ( const C_OUTLINE & source //from this ) { 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; }
C_OUTLINE & C_OUTLINE::operator= (const C_OUTLINE & source) { 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; }
C_OUTLINE::C_OUTLINE (CRACKEDGE * startpt, ICOORD bot_left, ICOORD top_right, inT16 length) : 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( //constructor C_OUTLINE *srcline, //outline to FCOORD rotation //rotate ) : 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 ()); }