stSortedSetIterator *stSortedSet_getIteratorFrom(stSortedSet *items, void *item) { stSortedSetIterator *iterator = stSortedSet_getIterator(items); if(avl_t_find(&iterator->traverser, items->sortedSet, item) == NULL) { stThrowNew(SORTED_SET_EXCEPTION_ID, "Tried to create an iterator with an item that is not in the list of items"); } stSortedSet_getPrevious(iterator); return iterator; }
/*!When an intersection point is rendered, the segments that it belongs to must be swapped according to the Bentley-Ottmann algorithm. This method performs the swapping in three steps: - first reshaffle the above/below pointers of the input segments and their neighbours. - then find the input segements in the AVL tree and swap them - finally replace the left points of the segments with the crossing point, otherwise the #_tree will be stuffed because of the swapped segments I've tried to have some fun with the above/below pointers, but it almost turn into a nightmare. So if you are not sure what happens, don't mess around*/ void logicop::SweepLine::swap(plysegment*& above, plysegment*& below) { // first fix the pointers of the neighbor segments if (below->below) below->below->above = above; if (above->above) above->above->below = below; // now swap above pointers ... below->above = above->above; above->above = below; // ... and below pointers ... above->below = below->below; below->below = above; // .. and then swap the segments themselfs in the tree ... avl_traverser trava, travb; void* retitem; retitem = avl_t_find(&trava,_tree,above); assert(NULL != retitem); retitem = avl_t_find(&travb,_tree,below); assert(NULL != retitem); below = (plysegment*)avl_t_replace(&trava,below); above = (plysegment*)avl_t_replace(&travb,above); }
Table_iterateur trouver_table( const Table* table, intptr_t cle ) { Table_iterateur it; Table_association* asso = creer_table_association( table, cle, (intptr_t) NULL ); avl_t_find( &it, table->root, (void*) asso ); supprimer_table_association( asso ); return it; }
void tedop::SweepLine::remove(plysegment* seg) { avl_traverser trav; void* retitem = avl_t_find(&trav,_tree,seg); if (NULL == retitem) return; avl_traverser save_trav = trav; plysegment* nx = (plysegment*)avl_t_next(&save_trav); if (NULL != nx) nx->below = seg->below; plysegment* np = (plysegment*)avl_t_prev(&trav); if (NULL != np) np->above = seg->above; avl_delete(_tree,seg); }
/*! This is the only non-virtual method of this class. After a crossing point has been discovered and a CEvent created this method checks whether this event is not already in the event queue. See the description of EventQueue::E_compare(). If the event is not already there it is added, otherwise, it is deleted.\n The other important thing is that if the event is unique, the cross point is added to each of the input segments after what they are linked to each other as well. This data will be used later, outside the Bentley-Ottmann algorithm to form the new polygons.\n I am stil not sure that this class is the best place for this method - just see the number of the input parameters*/ void logicop::Event::checkNupdate(avl_table* EQ, plysegment* above, plysegment* below, CEvent* evt, bool check) { avl_traverser trav; bool insert; if (check) { void* retitem = avl_t_find(&trav, EQ, evt); insert = (NULL == retitem); } else insert = true; if (insert) { void* retitem = avl_t_insert(&trav,EQ,evt); assert(retitem == evt); CPoint* cpsegA = above->insertcrosspoint(evt->cp()); CPoint* cpsegB = below->insertcrosspoint(evt->cp()); cpsegA->linkto(cpsegB); cpsegB->linkto(cpsegA); } else delete evt; }
fm_entry *lookup_fontmap(char *ps_name) { fm_entry *fm, *fm2, tmp; char *a, *b, *c, *d, *e, *s; int i, sl, ex; struct avl_traverser t, t2; if (tfm_tree == NULL) fm_read_info(); /* only to read default map file */ assert(ps_name != NULL); s = ps_name; if (strlen(ps_name) > 7) { /* check for subsetted name tag */ for (i = 0; i < 6; i++, s++) if (*s < 'A' || *s > 'Z') break; if (i == 6 && *s == '+') s++; /* if name tag found, skip behind it */ else s = ps_name; } /* * Scan -Slant_<slant> and -Extend_<extend> font name extensions; * three valid formats: * <fontname>-Slant_<slant> * <fontname>-Slant_<slant>-Extend_<extend> * <fontname>-Extend_<extend> * Slant entry must come _before_ Extend entry */ tmp.slant = 0; tmp.extend = 0; if ((a = strstr(s, "-Slant_")) != NULL) { b = a + strlen("-Slant_"); sl = (int) strtol(b, &e, 10); if ((e != b) && (e == strend(b))) { tmp.slant = sl; *a = '\0'; /* ps_name string ends before "-Slant_" */ } else { if (e != b) { /* only if <slant> is valid number */ if ((c = strstr(e, "-Extend_")) != NULL) { d = c + strlen("-Extend_"); ex = (int) strtol(d, &e, 10); if ((e != d) && (e == strend(d))) { tmp.slant = sl; tmp.extend = ex; *a = '\0'; /* ps_name string ends before "-Slant_" */ } } } } } else { if ((a = strstr(s, "-Extend_")) != NULL) { b = a + strlen("-Extend_"); ex = (int) strtol(b, &e, 10); if ((e != b) && (e == strend(b))) { tmp.extend = ex; *a = '\0'; /* ps_name string ends before "-Extend_" */ } } } tmp.ps_name = s; fm = (fm_entry *) avl_t_find(&t, ps_tree, &tmp); if (fm == NULL) return NULL; /* no entry found */ /* at this point we know there is at least one fm_entry with given ps_name; * we test all such entries and return the first one that is valid for font * replacement */ t2 = t; fm2 = (fm_entry *) avl_t_prev(&t2); /* search forward */ do { if (fm_valid_for_font_replacement(fm)) return fm; fm = (fm_entry *) avl_t_next(&t); } while (fm != NULL && comp_fm_entry_ps(fm, &tmp, NULL) == 0); /* search backward */ while (fm2 != NULL && comp_fm_entry_ps(fm2, &tmp, NULL) == 0) { if (fm_valid_for_font_replacement(fm2)) return fm2; fm2 = (fm_entry *) avl_t_prev(&t2); } return NULL; }