void OUTLINE::scale( // scale OUTLINE const FCOORD vector //by fcoord ) { //child outline itertr OUTLINE_IT child_it(&children); POLYPT_IT poly_it(&outline); //outline point itertr POLYPT *pt; box.scale (vector); start.set_x ((inT16) floor (start.x () * vector.x () + 0.5)); // ?? Why ICOORD? start.set_y ((inT16) floor (start.y () * vector.y () + 0.5)); // ?? Why ICOORD? for (poly_it.mark_cycle_pt (); !poly_it.cycled_list (); poly_it.forward ()) { pt = poly_it.data (); pt->pos = FCOORD (pt->pos.x () * vector.x (), pt->pos.y () * vector.y ()); pt->vec = FCOORD (pt->vec.x () * vector.x (), pt->vec.y () * vector.y ()); } for (child_it.mark_cycle_pt (); !child_it.cycled_list (); child_it.forward ()) //scale child outlines child_it.data ()->scale (vector); }
void OUTLINE::scale( // scale OUTLINE const float f // by multiplier ) { //child outline itertr OUTLINE_IT child_it(&children); POLYPT_IT poly_it(&outline); //outline point itertr POLYPT *pt; box.scale (f); // ?? Why ICOORD? start.set_x ((inT16) floor (start.x () * f + 0.5)); // ?? Why ICOORD? start.set_y ((inT16) floor (start.y () * f + 0.5)); for (poly_it.mark_cycle_pt (); !poly_it.cycled_list (); poly_it.forward ()) { pt = poly_it.data (); pt->pos *= f; pt->vec *= f; } for (child_it.mark_cycle_pt (); !child_it.cycled_list (); child_it.forward ()) child_it.data ()->scale (f); //scale child outlines }
float OUTLINE::area() { //constructor FCOORD origin; //startpt FCOORD prev_vec; //previous value of vec FCOORD vec; //from start to current float total; //total area POLYPT_IT poly_it = polypts ();//iterator //child outline itertr OUTLINE_IT child_it(&children); origin = poly_it.data ()->pos; poly_it.forward (); vec = poly_it.data ()->pos - origin; poly_it.forward (); total = 0.0f; while (!poly_it.at_first ()) { prev_vec = vec; vec = poly_it.data ()->pos - origin; total += prev_vec * vec; poly_it.forward (); } total /= 2; for (child_it.mark_cycle_pt (); !child_it.cycled_list (); child_it.forward ()) { //add ares of childrein total += child_it.data ()->area (); } return total; }
const std::string SiblingsFirstTraverse ::next(Stack* itStack, bool* isFinished) { // pointer mustn't point to NULL and iteration mustn't be finished poco_check_ptr(isFinished); poco_assert(!(*isFinished)); // add dirs to queue (if depth limit allows) bool isDepthLimitReached = isFiniteDepth() && _depthDeterminer(*itStack) >= _maxDepth; if (!isDepthLimitReached && itStack->top()->isDirectory()) { const std::string& p = itStack->top()->path(); _dirsStack.top().push(p); } ++(itStack->top()); poco_assert(!itStack->empty()); // return up until there isn't right sibling while (itStack->top() == _itEnd) { // try to find first not empty directory and go deeper while (!_dirsStack.top().empty()) { std::string dir = _dirsStack.top().front(); _dirsStack.top().pop(); Poco::DirectoryIterator child_it(dir); // check if directory is empty if (child_it != _itEnd) { itStack->push(child_it); _dirsStack.push(std::queue<std::string>()); return child_it->path(); } } // if fail go upper itStack->pop(); _dirsStack.pop(); // detect end of traversal if (itStack->empty()) { *isFinished = true; return _itEnd->path(); } } return itStack->top()->path(); }
// Returns true if *this and its children are legally nested. // The outer area of a child should have the opposite sign to the // parent. If not, it means we have discarded an outline in between // (probably due to excessive length). bool C_OUTLINE::IsLegallyNested() const { if (stepcount == 0) return true; int parent_area = outer_area(); // We aren't going to modify the list, or its contents, but there is // no const iterator. C_OUTLINE_IT child_it(const_cast<C_OUTLINE_LIST*>(&children)); for (child_it.mark_cycle_pt(); !child_it.cycled_list(); child_it.forward()) { const C_OUTLINE* child = child_it.data(); if (child->outer_area() * parent_area > 0 || !child->IsLegallyNested()) return false; } return true; }
// If this outline is smaller than the given min_size, delete this and // remove from its list, via *it, after checking that *it points to this. // Otherwise, if any children of this are too small, delete them. // On entry, *it must be an iterator pointing to this. If this gets deleted // then this is extracted from *it, so an iteration can continue. void C_OUTLINE::RemoveSmallRecursive(int min_size, C_OUTLINE_IT* it) { if (box.width() < min_size || box.height() < min_size) { ASSERT_HOST(this == it->data()); delete it->extract(); // Too small so get rid of it and any children. } else if (!children.empty()) { // Search the children of this, deleting any that are too small. C_OUTLINE_IT child_it(&children); for (child_it.mark_cycle_pt(); !child_it.cycled_list(); child_it.forward()) { C_OUTLINE* child = child_it.data(); child->RemoveSmallRecursive(min_size, &child_it); } } }
const std::string ChildrenFirstTraverse ::next(Stack* itStack, bool* isFinished) { // pointer mustn't point to NULL and iteration mustn't be finished poco_check_ptr(isFinished); poco_assert(!(*isFinished)); std::stack<Poco::DirectoryIterator> it; //_depthDeterminer(it); // go deeper into not empty directory // (if depth limit allows) bool isDepthLimitReached = isFiniteDepth() && _depthDeterminer(*itStack) >= _maxDepth; if (!isDepthLimitReached && itStack->top()->isDirectory()) { Poco::DirectoryIterator child_it(itStack->top().path()); // check if directory is empty if (child_it != _itEnd) { itStack->push(child_it); return child_it->path(); } } ++(itStack->top()); poco_assert(!itStack->empty()); // return up until there isn't right sibling while (itStack->top() == _itEnd) { itStack->pop(); // detect end of traversal if (itStack->empty()) { *isFinished = true; return _itEnd->path(); } else { ++(itStack->top()); } } return itStack->top()->path(); }
// Static helper for C_BLOB::rotate to allow recursion of child outlines. void RotateOutlineList(const FCOORD& rotation, C_OUTLINE_LIST* outlines) { C_OUTLINE_LIST new_outlines; C_OUTLINE_IT src_it(outlines); C_OUTLINE_IT dest_it(&new_outlines); while (!src_it.empty()) { C_OUTLINE* old_outline = src_it.extract(); src_it.forward(); C_OUTLINE* new_outline = new C_OUTLINE(old_outline, rotation); if (!old_outline->child()->empty()) { RotateOutlineList(rotation, old_outline->child()); C_OUTLINE_IT child_it(new_outline->child()); child_it.add_list_after(old_outline->child()); } delete old_outline; dest_it.add_to_end(new_outline); } src_it.add_list_after(&new_outlines); }
void OUTLINE::move( // reposition OUTLINE const FCOORD vec // by vector ) { //child outline itertr OUTLINE_IT child_it(&children); POLYPT_IT poly_it(&outline); //outline point itertr box.move (vec); start.set_x ((inT16) floor (start.x () + vec.x () + 0.5)); // ?? Why ICOORD? start.set_y ((inT16) floor (start.y () + vec.y () + 0.5)); // ?? Why ICOORD? for (poly_it.mark_cycle_pt (); !poly_it.cycled_list (); poly_it.forward ()) poly_it.data ()->pos += vec; for (child_it.mark_cycle_pt (); !child_it.cycled_list (); child_it.forward ()) child_it.data ()->move (vec); // move child outlines }
void OUTLINE::rotate( const FCOORD vector //by fcoord ) { //child outline itertr OUTLINE_IT child_it(&children); POLYPT_IT poly_it(&outline); //outline point itertr POLYPT *pt; box.rotate(vector); start.rotate(vector); for (poly_it.mark_cycle_pt (); !poly_it.cycled_list (); poly_it.forward ()) { pt = poly_it.data (); pt->pos.rotate(vector); pt->vec.rotate(vector); } for (child_it.mark_cycle_pt (); !child_it.cycled_list (); child_it.forward ()) //scale child outlines child_it.data ()->rotate(vector); }