📄 fpchop.cpp
字号:
test_index = tail_index; //stop warnings do { *tail_pos += srcline->step (tail_index); prev_step = srcline->step (tail_index); tail_index++; if (tail_index >= length) tail_index = 0; if (test_valid && tail_pos->x () == chop_coord && prev_step.x () < 0) { if (tail_pos->y () <= chop_starty) { chop_starty = MAX_INT16; test_valid = FALSE; } else { *tail_pos = test_pos; tail_index = test_index; break; //must chop there } } if (tail_pos->x () == chop_coord && srcline->step (tail_index).x () > 0 && tail_pos->y () < chop_starty) { chop_starty = tail_pos->y (); test_index = tail_index; test_pos = *tail_pos; test_valid = TRUE; } else if (tail_pos->x () == chop_coord && srcline->step (tail_index).y () > 0 && prev_step.x () > 0 && tail_pos->y () < chop_starty) break; //must chop here } while (tail_index != startindex && tail_pos->x () < chop_coord + pitch_error); return tail_index;}/********************************************************************** * next_clock_right_seg * * Search the outline for a suitable point at which it crosses the * chop_coord from right to left. **********************************************************************/INT16 next_clock_right_seg( //chop the outline C_OUTLINE *srcline, //source outline INT16 tail_index, //of tailpos INT16 startindex, //end of search INT32 length, //of outline INT16 chop_coord, //place to chop float pitch_error, //allowed deviation ICOORD *tail_pos //current position ) { BOOL8 test_valid; //test pt valid INT16 chop_starty; //test chop pt INT16 test_index; //possible chop pt ICOORD test_pos; //possible chop pt ICOORD prev_step; //in x to tail pos test_valid = FALSE; chop_starty = MAX_INT16; test_index = tail_index; //stop warnings do { //move forward *tail_pos += srcline->step (tail_index); prev_step = srcline->step (tail_index); tail_index++; if (tail_index >= length) tail_index = 0; if (test_valid && tail_pos->x () == chop_coord && prev_step.x () > 0) { if (tail_pos->y () >= chop_starty) { chop_starty = MAX_INT16; test_valid = FALSE; } else { *tail_pos = test_pos; tail_index = test_index; break; //must chop there } } if (tail_pos->x () == chop_coord && srcline->step (tail_index).x () < 0 && tail_pos->y () > chop_starty) { chop_starty = tail_pos->y (); test_index = tail_index; test_pos = *tail_pos; test_valid = TRUE; //save possible chop pt } else if (tail_pos->x () == chop_coord && srcline->step (tail_index).y () < 0 && prev_step.x () < 0 && tail_pos->y () > chop_starty) break; //must chop here } while (tail_index != startindex && tail_pos->x () > chop_coord - pitch_error); return tail_index;}/********************************************************************** * save_chop_cfragment * * Store the given fragment in the given fragment list. **********************************************************************/void save_chop_cfragment( //chop the outline INT16 head_index, //head of fragment ICOORD head_pos, //head of fragment INT16 tail_index, //tail of fragment ICOORD tail_pos, //tail of fragment C_OUTLINE *srcline, //source of edgesteps C_OUTLINE_FRAG_LIST *frags //fragment list ) { INT16 jump; //gap across end INT16 stepcount; //total steps C_OUTLINE_FRAG *head; //head of fragment C_OUTLINE_FRAG *tail; //tail of fragment INT16 tail_y; //ycoord of tail ASSERT_HOST (tail_pos.x () == head_pos.x ()); ASSERT_HOST (tail_index != head_index); stepcount = tail_index - head_index; if (stepcount < 0) stepcount += srcline->pathlength (); jump = tail_pos.y () - head_pos.y (); if (jump < 0) jump = -jump; if (jump == stepcount) return; //its a nop tail_y = tail_pos.y (); head = new C_OUTLINE_FRAG (head_pos, tail_pos, srcline, head_index, tail_index); tail = new C_OUTLINE_FRAG (head, tail_y); head->other_end = tail; add_frag_to_list(head, frags); add_frag_to_list(tail, frags); }/********************************************************************** * C_OUTLINE_FRAG::C_OUTLINE_FRAG * * Constructors for C_OUTLINE_FRAG. **********************************************************************/C_OUTLINE_FRAG::C_OUTLINE_FRAG( //record fragment ICOORD start_pt, //start coord ICOORD end_pt, //end coord C_OUTLINE *outline, //source of steps INT16 start_index, INT16 end_index) { start = start_pt; end = end_pt; ycoord = start_pt.y (); stepcount = end_index - start_index; if (stepcount < 0) stepcount += outline->pathlength (); ASSERT_HOST (stepcount > 0); steps = new DIR128[stepcount]; if (end_index > start_index) {
for (int i = start_index; i < end_index; ++i)
steps[i - start_index] = outline->step_dir(i);
} else {
int len = outline->pathlength();
int i = start_index;
for (; i < len; ++i)
steps[i - start_index] = outline->step_dir(i); if (end_index > 0)
for (; i < end_index + len; ++i)
steps[i - start_index] = outline->step_dir(i - len); } other_end = NULL; delete close(); }C_OUTLINE_FRAG::C_OUTLINE_FRAG( //record fragment C_OUTLINE_FRAG *head, //other end INT16 tail_y) { ycoord = tail_y; other_end = head; start = head->start; end = head->end; steps = NULL; stepcount = 0;}/********************************************************************** * add_frag_to_list * * Insert the fragment in the list at the appropriate place to keep * them in ascending ycoord order. **********************************************************************/void add_frag_to_list( //ordered add C_OUTLINE_FRAG *frag, //fragment to add C_OUTLINE_FRAG_LIST *frags //fragment list ) { //output list C_OUTLINE_FRAG_IT frag_it = frags; if (!frags->empty ()) { for (frag_it.mark_cycle_pt (); !frag_it.cycled_list (); frag_it.forward ()) { if (frag_it.data ()->ycoord > frag->ycoord || frag_it.data ()->ycoord == frag->ycoord && frag->other_end->ycoord < frag->ycoord) { frag_it.add_before_then_move (frag); return; } } } frag_it.add_to_end (frag);}/********************************************************************** * close_chopped_cfragments * * Clear the given list of fragments joining them up into outlines. * Each outline made soaks up any of the child outlines which it encloses. **********************************************************************/void close_chopped_cfragments( //chop the outline C_OUTLINE_FRAG_LIST *frags, //list to clear C_OUTLINE_LIST *children, //potential children float pitch_error, //allowed shrinkage C_OUTLINE_IT *dest_it //output list ) { //iterator C_OUTLINE_FRAG_IT frag_it = frags; C_OUTLINE_FRAG *bottom_frag; //bottom of cut C_OUTLINE_FRAG *top_frag; //top of cut C_OUTLINE *outline; //new outline C_OUTLINE *child; //current child C_OUTLINE_IT child_it = children; C_OUTLINE_IT olchild_it; //children of outline while (!frag_it.empty ()) { frag_it.move_to_first (); //get bottom one bottom_frag = frag_it.extract (); frag_it.forward (); top_frag = frag_it.data (); //look at next if (bottom_frag->steps == 0 && top_frag->steps == 0 || bottom_frag->steps != 0 && top_frag->steps != 0) { if (frag_it.data_relative (1)->ycoord == top_frag->ycoord) frag_it.forward (); } top_frag = frag_it.extract (); if (top_frag->other_end != bottom_frag) { outline = join_chopped_fragments (bottom_frag, top_frag); ASSERT_HOST (outline == NULL); } else { outline = join_chopped_fragments (bottom_frag, top_frag); ASSERT_HOST (outline != NULL); olchild_it.set_to_list (outline->child ()); for (child_it.mark_cycle_pt (); !child_it.cycled_list (); child_it.forward ()) { child = child_it.data (); if (*child < *outline) olchild_it.add_to_end (child_it.extract ()); } if (outline->bounding_box ().width () > pitch_error) dest_it->add_after_then_move (outline); else delete outline; //make it disappear } } while (!child_it.empty ()) { dest_it->add_after_then_move (child_it.extract ()); child_it.forward (); }}/********************************************************************** * join_chopped_fragments * * Join the two lists of POLYPTs such that neither OUTLINE_FRAG * operand keeps responsibility for the fragment. **********************************************************************/C_OUTLINE *join_chopped_fragments( //join pieces C_OUTLINE_FRAG *bottom, //bottom of cut C_OUTLINE_FRAG *top //top of cut ) { C_OUTLINE *outline; //closed loop if (bottom->other_end == top) { if (bottom->steps == 0) outline = top->close (); //turn to outline else outline = bottom->close (); delete top; delete bottom; return outline; } if (bottom->steps == 0) { ASSERT_HOST (top->steps != 0); join_segments (bottom->other_end, top); } else { ASSERT_HOST (top->steps == 0); join_segments (top->other_end, bottom); } top->other_end->other_end = bottom->other_end; bottom->other_end->other_end = top->other_end; delete bottom; delete top; return NULL;}/********************************************************************** * join_segments * * Join the two edgestep fragments such that the second comes after * the first and the gap beween them is closed. **********************************************************************/void join_segments( //join pieces C_OUTLINE_FRAG *bottom, //bottom of cut C_OUTLINE_FRAG *top //top of cut ) { DIR128 *steps; //new steps INT32 stepcount; //no of steps INT16 fake_count; //fake steps DIR128 fake_step; //step entry ASSERT_HOST (bottom->end.x () == top->start.x ()); fake_count = top->start.y () - bottom->end.y (); if (fake_count < 0) { fake_count = -fake_count; fake_step = 32; } else fake_step = 96; stepcount = bottom->stepcount + fake_count + top->stepcount; steps = new DIR128[stepcount]; memmove (steps, bottom->steps, bottom->stepcount); memset (steps + bottom->stepcount, fake_step.get_dir(), fake_count); memmove (steps + bottom->stepcount + fake_count, top->steps, top->stepcount); delete [] bottom->steps; bottom->steps = steps; bottom->stepcount = stepcount; bottom->end = top->end; bottom->other_end->end = top->end;}/********************************************************************** * C_OUTLINE_FRAG::close * * Join the ends of this fragment and turn it into an outline. **********************************************************************/C_OUTLINE *C_OUTLINE_FRAG::close() { //join pieces DIR128 *new_steps; //new steps INT32 new_stepcount; //no of steps INT16 fake_count; //fake steps DIR128 fake_step; //step entry ASSERT_HOST (start.x () == end.x ()); fake_count = start.y () - end.y (); if (fake_count < 0) { fake_count = -fake_count; fake_step = 32; } else fake_step = 96; new_stepcount = stepcount + fake_count; new_steps = new DIR128[new_stepcount]; memmove(new_steps, steps, stepcount); memset (new_steps + stepcount, fake_step.get_dir(), fake_count);
C_OUTLINE* result = new C_OUTLINE (start, new_steps, new_stepcount);
delete [] new_steps;
return result;}/********************************************************************** * C_OUTLINE_FRAG::operator= * * Copy this fragment. **********************************************************************/ //join piecesC_OUTLINE_FRAG & C_OUTLINE_FRAG::operator= (const C_OUTLINE_FRAG & src //fragment to copy) { if (steps != NULL) delete [] steps; stepcount = src.stepcount; steps = new DIR128[stepcount]; memmove (steps, src.steps, stepcount); start = src.start; end = src.end; ycoord = src.ycoord; return *this;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -