void insertSegment (SegmentTree * st, int n, Coord Y1, Coord Y2) { Coord discriminant; if (st->nodes[n].left >= Y1 && st->nodes[n].right <= Y2) { st->nodes[n].covered++; } else { assert (n < st->size / 2); discriminant = st->nodes[n * 2 + 1 /*right */ ].left; if (Y1 < discriminant) { insertSegment (st, n * 2, Y1, Y2); } if (discriminant < Y2) { insertSegment (st, n * 2 + 1, Y1, Y2); } } /* fixup area */ st->nodes[n].area = (st->nodes[n].covered > 0) ? (st->nodes[n].right - st->nodes[n].left) : (n >= st->size / 2) ? 0 : st->nodes[n * 2].area + st->nodes[n * 2 + 1].area; }
void Model::addSortedSegment(SegmentModel* m) { insertSegment(m); // Add points if necessary // If there is an existing previous segment, its end point also exists auto createStartPoint = [&]() { auto pt = new PointModel{getStrongId(m_points), this}; pt->setFollowing(m->id()); pt->setPos(m->start()); addPoint(pt); return pt; }; auto createEndPoint = [&]() { auto pt = new PointModel{getStrongId(m_points), this}; pt->setPrevious(m->id()); pt->setPos(m->end()); addPoint(pt); return pt; }; if (!m->previous()) { createStartPoint(); } else { // The previous segment has already been inserted, // hence the previous point is present. m_points.back()->setFollowing(m->id()); } createEndPoint(); }
void LLChatMsgBox::addText( const LLStringExplicit& text , const LLStyle::Params& input_params ) { S32 length = getLength(); // if there is existing text, add a separator if (length > 0) { // chat separator exists right before the null terminator insertSegment(new ChatSeparator(length - 1, length - 1)); } // prepend newline only if there is some existing text appendText(text, length > 0, input_params); }
//NOTE: obliterates existing styles (including hyperlinks) void LLExpandableTextBox::LLTextBoxEx::hideExpandText() { if (mExpanderVisible) { // this will overwrite the expander segment and all text styling with a single style LLStyleConstSP sp(new LLStyle(getDefaultStyleParams())); LLNormalTextSegment* segmentp = new LLNormalTextSegment(sp, 0, getLength() + 1, *this); insertSegment(segmentp); mExpanderVisible = false; } }
void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end) { LLWString text = getWText(); // Start with i just after the first embedded item for(S32 idx = start; idx < end; idx++ ) { llwchar embedded_char = text[idx]; if( embedded_char >= FIRST_EMBEDDED_CHAR && embedded_char <= LAST_EMBEDDED_CHAR && mEmbeddedItemList->hasEmbeddedItem(embedded_char) ) { LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItemPtr(embedded_char); LLUIImagePtr image = mEmbeddedItemList->getItemImage(embedded_char); insertSegment(new LLEmbeddedItemSegment(idx, image, itemp, *this)); } } }
void LLExpandableTextBox::LLTextBoxEx::showExpandText() { if (!mExpanderVisible) { // make sure we're scrolled to top when collapsing if (mScroller) { mScroller->goToTop(); } // get fully visible lines std::pair<S32, S32> visible_lines = getVisibleLines(true); S32 last_line = visible_lines.second - 1; LLStyle::Params expander_style(getDefaultStyleParams()); expander_style.font.style = "UNDERLINE"; expander_style.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); LLExpanderSegment* expanderp = new LLExpanderSegment(new LLStyle(expander_style), getLineStart(last_line), getLength() + 1, mExpanderLabel, *this); insertSegment(expanderp); mExpanderVisible = true; } }
// Walk through a string, applying the rules specified by the keyword token list and // create a list of color segments. void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor) { std::for_each(seg_list->begin(), seg_list->end(), DeletePointer()); seg_list->clear(); if( wtext.empty() ) { return; } S32 text_len = wtext.size(); seg_list->push_back( new LLTextSegment( LLColor3(defaultColor), 0, text_len ) ); const llwchar* base = wtext.c_str(); const llwchar* cur = base; const llwchar* line = NULL; while( *cur ) { if( *cur == '\n' || cur == base ) { if( *cur == '\n' ) { cur++; if( !*cur || *cur == '\n' ) { continue; } } // Start of a new line line = cur; // Skip white space while( *cur && isspace(*cur) && (*cur != '\n') ) { cur++; } if( !*cur || *cur == '\n' ) { continue; } // cur is now at the first non-whitespace character of a new line // Line start tokens { BOOL line_done = FALSE; for (token_list_t::iterator iter = mLineTokenList.begin(); iter != mLineTokenList.end(); ++iter) { LLKeywordToken* cur_token = *iter; if( cur_token->isHead( cur ) ) { S32 seg_start = cur - base; while( *cur && *cur != '\n' ) { // skip the rest of the line cur++; } S32 seg_end = cur - base; LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end ); text_segment->setToken( cur_token ); insertSegment( seg_list, text_segment, text_len, defaultColor); line_done = TRUE; // to break out of second loop. break; } } if( line_done ) { continue; } } } // Skip white space while( *cur && isspace(*cur) && (*cur != '\n') ) { cur++; } while( *cur && *cur != '\n' ) { // Check against delimiters { S32 seg_start = 0; LLKeywordToken* cur_delimiter = NULL; for (token_list_t::iterator iter = mDelimiterTokenList.begin(); iter != mDelimiterTokenList.end(); ++iter) { LLKeywordToken* delimiter = *iter; if( delimiter->isHead( cur ) ) { cur_delimiter = delimiter; break; } } if( cur_delimiter ) { S32 between_delimiters = 0; S32 seg_end = 0; seg_start = cur - base; cur += cur_delimiter->getLength(); if( cur_delimiter->getType() == LLKeywordToken::TWO_SIDED_DELIMITER ) { while( *cur && !cur_delimiter->isHead(cur)) { // Check for an escape sequence. if (*cur == '\\') { // Count the number of backslashes. S32 num_backslashes = 0; while (*cur == '\\') { num_backslashes++; between_delimiters++; cur++; } // Is the next character the end delimiter? if (cur_delimiter->isHead(cur)) { // Is there was an odd number of backslashes, then this delimiter // does not end the sequence. if (num_backslashes % 2 == 1) { between_delimiters++; cur++; } else { // This is an end delimiter. break; } } } else { between_delimiters++; cur++; } } if( *cur ) { cur += cur_delimiter->getLength(); seg_end = seg_start + between_delimiters + 2 * cur_delimiter->getLength(); } else { // eof seg_end = seg_start + between_delimiters + cur_delimiter->getLength(); } } else { llassert( cur_delimiter->getType() == LLKeywordToken::ONE_SIDED_DELIMITER ); // Left side is the delimiter. Right side is eol or eof. while( *cur && ('\n' != *cur) ) { between_delimiters++; cur++; } seg_end = seg_start + between_delimiters + cur_delimiter->getLength(); } LLTextSegment* text_segment = new LLTextSegment( cur_delimiter->getColor(), seg_start, seg_end ); text_segment->setToken( cur_delimiter ); insertSegment( seg_list, text_segment, text_len, defaultColor); // Note: we don't increment cur, since the end of one delimited seg may be immediately // followed by the start of another one. continue; } } // check against words llwchar prev = cur > base ? *(cur-1) : 0; if( !isalnum( prev ) && (prev != '_') ) { const llwchar* p = cur; while( isalnum( *p ) || (*p == '_') ) { p++; } S32 seg_len = p - cur; if( seg_len > 0 ) { LLWString word( cur, 0, seg_len ); word_token_map_t::iterator map_iter = mWordTokenMap.find(word); if( map_iter != mWordTokenMap.end() ) { LLKeywordToken* cur_token = map_iter->second; S32 seg_start = cur - base; S32 seg_end = seg_start + seg_len; // llinfos << "Seg: [" << word.c_str() << "]" << llendl; LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end ); text_segment->setToken( cur_token ); insertSegment( seg_list, text_segment, text_len, defaultColor); } cur += seg_len; continue; } } if( *cur && *cur != '\n' ) { cur++; } } } }
void Segment::insertNewSegment(const SegmentPoint& p, SegmentType type) { insertSegment(duplicate(p, type)); }
void Model::addSegment(SegmentModel* m) { insertSegment(m); // Add points if necessary // If there is an existing previous segment, its end point also exists auto createStartPoint = [&]() { auto pt = new PointModel{getStrongId(m_points), this}; pt->setFollowing(m->id()); pt->setPos(m->start()); addPoint(pt); return pt; }; auto createEndPoint = [&]() { auto pt = new PointModel{getStrongId(m_points), this}; pt->setPrevious(m->id()); pt->setPos(m->end()); addPoint(pt); return pt; }; if (m->previous()) { auto previousSegment = std::find_if( m_segments.begin(), m_segments.end(), [&](const auto& seg) { return seg.following() == m->id(); }); if (previousSegment != m_segments.end()) { auto thePt = std::find_if( m_points.begin(), m_points.end(), [&](PointModel* pt) { return pt->previous() == (*previousSegment).id(); }); if (thePt != m_points.end()) { // The previous segments and points both exist (*thePt)->setFollowing(m->id()); } else { // The previous segment exists but not the end point. auto pt = createStartPoint(); pt->setPrevious((*previousSegment).id()); } } else // The previous segment has not yet been added. { createStartPoint(); } } else if (std::none_of(m_points.begin(), m_points.end(), [&](PointModel* pt) { return pt->following() == m->id(); })) { createStartPoint(); } if (m->following()) { auto followingSegment = std::find_if( m_segments.begin(), m_segments.end(), [&](const auto& seg) { return seg.previous() == m->id(); }); if (followingSegment != m_segments.end()) { auto thePt = std::find_if( m_points.begin(), m_points.end(), [&](PointModel* pt) { return pt->following() == (*followingSegment).id(); }); if (thePt != m_points.end()) { (*thePt)->setPrevious(m->id()); } else { auto pt = createEndPoint(); pt->setFollowing((*followingSegment).id()); } } else { createEndPoint(); } } else if (std::none_of(m_points.begin(), m_points.end(), [&](PointModel* pt) { return pt->previous() == m->id(); })) { // Note : if one day a buggy case happens here, check that set // following/previous // are correctly set after cloning the segment. createEndPoint(); } }
uint32 All_RoadSegment::AnalysisSegment() { uint32 firstSegId = 0; //open XML TiXmlDocument XMLdoc("./config/DE_Airport_ParamConfig.xml"); if(!XMLdoc.LoadFile()) { cout<<"fail to load config file"<<endl; return 0; } TiXmlElement* root = XMLdoc.RootElement(); TiXmlElement* segment; //segnumber segment = root->FirstChildElement(); segmentnum = stringToNum<uint32>(segment->GetText()); segment = segment->NextSiblingElement(); int index = -1; int insert_idex; while(NULL != segment) { RoadSegment *p_seg_t = new RoadSegment; //segID TiXmlElement* nextElement = segment->FirstChildElement(); p_seg_t->segId = stringToNum<uint16>(nextElement->GetText()); if(-1 == index)//first segment {firstSegId = p_seg_t->segId;} //segType nextElement = nextElement->NextSiblingElement(); p_seg_t->segType = stringToNum<uint32>(nextElement->GetText()); //lanenum nextElement = nextElement->NextSiblingElement(); p_seg_t->laneNum = stringToNum<uint32>(nextElement->GetText()); //lineNum nextElement = nextElement->NextSiblingElement(); p_seg_t->lineNum = stringToNum<uint32>(nextElement->GetText()); //gpspoint number nextElement = nextElement->NextSiblingElement(); p_seg_t->pointNum = stringToNum<uint32>(nextElement->GetText()); //point element index = p_seg_t->pointNum; while(index) { Segmentpoint *p_point_t = new Segmentpoint; index--; nextElement = nextElement->NextSiblingElement(); TiXmlElement* pointElement = nextElement->FirstChildElement(); //point ID p_point_t->pointId = stringToNum<uint32>(pointElement->GetText()); pointElement = pointElement->NextSiblingElement(); //point type p_point_t->point_type = stringToNum<uint32>(pointElement->GetText()); pointElement = pointElement->NextSiblingElement(); //connect segmentID p_point_t->conn_segId = stringToNum<uint32>(pointElement->GetText()); pointElement = pointElement->NextSiblingElement(); //gps p_point_t->point.lat = stringToNum<double>(pointElement->GetText()); pointElement = pointElement->NextSiblingElement(); p_point_t->point.lon = stringToNum<double>(pointElement->GetText()); pointElement = pointElement->NextSiblingElement(); //inert lane and sort insert_idex = p_seg_t->insertPoint(p_point_t); p_seg_t->_segpoint.insert(p_seg_t->_segpoint.begin()+insert_idex , *p_point_t); } //check gps point if(!p_seg_t->CheckPointId()) return false; //lane element index = p_seg_t->laneNum; while(index) { Segmentlane *p_lane_t = new Segmentlane; index--; nextElement = nextElement->NextSiblingElement(); TiXmlElement* laneElement = nextElement->FirstChildElement(); //laneID p_lane_t->laneId = stringToNum<uint32>(laneElement->GetText()); laneElement = laneElement->NextSiblingElement(); //start position p_lane_t->start_pos.lat = stringToNum<double>(laneElement->GetText()); laneElement = laneElement->NextSiblingElement(); p_lane_t->start_pos.lon = stringToNum<double>(laneElement->GetText()); laneElement = laneElement->NextSiblingElement(); //stop position p_lane_t->end_pos.lat = stringToNum<double>(laneElement->GetText()); laneElement = laneElement->NextSiblingElement(); p_lane_t->end_pos.lon = stringToNum<double>(laneElement->GetText()); laneElement = laneElement->NextSiblingElement(); //direction p_lane_t->derection = stringToNum<uint32>(laneElement->GetText()); laneElement = laneElement->NextSiblingElement(); //merge left p_lane_t->merge_left = stringToNum<uint32>(laneElement->GetText()); laneElement = laneElement->NextSiblingElement(); //merge right p_lane_t->merge_right = stringToNum<uint32>(laneElement->GetText()); laneElement = laneElement->NextSiblingElement(); //left line p_lane_t->leftlineID = stringToNum<uint32>(laneElement->GetText()); laneElement = laneElement->NextSiblingElement(); //right line p_lane_t->rightlineID = stringToNum<uint32>(laneElement->GetText()); laneElement = laneElement->NextSiblingElement(); //inert lane and sort insert_idex = p_seg_t->insertLane(p_lane_t); p_seg_t->_seglane.insert(p_seg_t->_seglane.begin()+insert_idex , *p_lane_t); } //check lane if(!p_seg_t->CheckLaneId()) return false; //line element index = p_seg_t->lineNum; while(index) { Segmentline *p_line_t = new Segmentline; index--; nextElement = nextElement->NextSiblingElement(); TiXmlElement* lineElement = nextElement->FirstChildElement(); //line ID p_line_t->lineId = stringToNum<uint32>(lineElement->GetText()); lineElement = lineElement->NextSiblingElement(); //line type p_line_t->linetype = stringToNum<uint32>(lineElement->GetText()); lineElement = lineElement->NextSiblingElement(); //connection segID p_line_t->connSegID = stringToNum<uint32>(lineElement->GetText()); lineElement = lineElement->NextSiblingElement(); //connection lineID p_line_t->connLineID = stringToNum<uint32>(lineElement->GetText()); lineElement = lineElement->NextSiblingElement(); //insert line and sort insert_idex = p_seg_t->insertLine(p_line_t); p_seg_t->_segline.insert(p_seg_t->_segline.begin()+insert_idex , *p_line_t); } //check line if(!p_seg_t->CheckLineId()) return false; //insert segment and sort insert_idex = insertSegment(p_seg_t); _roadsegment.insert(_roadsegment.begin()+insert_idex , *p_seg_t); //point to next segmen segment = segment->NextSiblingElement(); } //check segment if(!CheckSegmentID()) return false; return firstSegId; }
void fill(const TRaster32P &ras, const TRaster32P &ref, const FillParameters ¶ms, TTileSaverFullColor *saver) { TPixel32 *pix, *limit, *pix0, *oldpix; int oldy, xa, xb, xc, xd, dy; int oldxc, oldxd; int matte, oldMatte; int x = params.m_p.x, y = params.m_p.y; TRaster32P workRas = ref ? ref : ras; TRect bbbox = workRas->getBounds(); if (!bbbox.contains(params.m_p)) return; TPaletteP plt = params.m_palette; TPixel32 color = plt->getStyle(params.m_styleId)->getMainColor(); int fillDepth = params.m_shiftFill ? params.m_maxFillDepth : params.m_minFillDepth; assert(fillDepth >= 0 && fillDepth < 16); fillDepth = ((15 - fillDepth) << 4) | (15 - fillDepth); // looking for any pure transparent pixel along the border; if after filling // that pixel will be changed, // it means that I filled the bg and the savebox needs to be recomputed! TPixel32 borderIndex; TPixel32 *borderPix = 0; pix = workRas->pixels(0); int i; for (i = 0; i < workRas->getLx(); i++, pix++) // border down if (pix->m == 0) { borderIndex = *pix; borderPix = pix; break; } if (borderPix == 0) // not found in border down...try border up (avoid left // and right borders...so unlikely) { pix = workRas->pixels(workRas->getLy() - 1); for (i = 0; i < workRas->getLx(); i++, pix++) // border up if (pix->m == 0) { borderIndex = *pix; borderPix = pix; break; } } std::stack<FillSeed> seeds; std::map<int, std::vector<std::pair<int, int>>> segments; // fillRow(r, params.m_p, xa, xb, color ,saver); findSegment(workRas, params.m_p, xa, xb, color); segments[y].push_back(std::pair<int, int>(xa, xb)); seeds.push(FillSeed(xa, xb, y, 1)); seeds.push(FillSeed(xa, xb, y, -1)); while (!seeds.empty()) { FillSeed fs = seeds.top(); seeds.pop(); xa = fs.m_xa; xb = fs.m_xb; oldy = fs.m_y; dy = fs.m_dy; y = oldy + dy; if (y > bbbox.y1 || y < bbbox.y0) continue; pix = pix0 = workRas->pixels(y) + xa; limit = workRas->pixels(y) + xb; oldpix = workRas->pixels(oldy) + xa; x = xa; oldxd = (std::numeric_limits<int>::min)(); oldxc = (std::numeric_limits<int>::max)(); while (pix <= limit) { oldMatte = threshMatte(oldpix->m, fillDepth); matte = threshMatte(pix->m, fillDepth); bool test = false; if (segments.find(y) != segments.end()) test = isPixelInSegment(segments[y], x); if (*pix != color && !test && matte >= oldMatte && matte != 255) { findSegment(workRas, TPoint(x, y), xc, xd, color); // segments[y].push_back(std::pair<int,int>(xc, xd)); insertSegment(segments[y], std::pair<int, int>(xc, xd)); if (xc < xa) seeds.push(FillSeed(xc, xa - 1, y, -dy)); if (xd > xb) seeds.push(FillSeed(xb + 1, xd, y, -dy)); if (oldxd >= xc - 1) oldxd = xd; else { if (oldxd >= 0) seeds.push(FillSeed(oldxc, oldxd, y, dy)); oldxc = xc; oldxd = xd; } pix += xd - x + 1; oldpix += xd - x + 1; x += xd - x + 1; } else { pix++; oldpix++, x++; } } if (oldxd > 0) seeds.push(FillSeed(oldxc, oldxd, y, dy)); } std::map<int, std::vector<std::pair<int, int>>>::iterator it; for (it = segments.begin(); it != segments.end(); it++) { TPixel32 *line = ras->pixels(it->first); TPixel32 *refLine = 0; TPixel32 *refPix; if (ref) refLine = ref->pixels(it->first); std::vector<std::pair<int, int>> segmentVector = it->second; for (int i = 0; i < (int)segmentVector.size(); i++) { std::pair<int, int> segment = segmentVector[i]; if (segment.second >= segment.first) { pix = line + segment.first; if (ref) refPix = refLine + segment.first; int n; for (n = 0; n < segment.second - segment.first + 1; n++, pix++) { if (ref) { *pix = *refPix; refPix++; } else *pix = pix->m == 0 ? color : overPix(color, *pix); } } } } }
/* --------------------------------------------------------------------------- * Compute the area of the union of the given rectangles. * O(N ln N) time. */ double ComputeUnionArea (BoxListType *boxlist) { BoxType **rectLeft, **rectRight; Cardinal i, j; LocationList yCoords; SegmentTree segtree; Coord lastX; double area = 0.0; if (boxlist->BoxN == 0) return 0.0; /* create sorted list of Y coordinates */ yCoords = createSortedYList (boxlist); /* now create empty segment tree */ segtree = createSegmentTree (yCoords.p, yCoords.size); free (yCoords.p); /* create sorted list of left and right X coordinates of rectangles */ rectLeft = (BoxType **)calloc (boxlist->BoxN, sizeof (*rectLeft)); rectRight = (BoxType **)calloc (boxlist->BoxN, sizeof (*rectRight)); for (i = 0; i < boxlist->BoxN; i++) { assert (boxlist->Box[i].X1 <= boxlist->Box[i].X2); assert (boxlist->Box[i].Y1 <= boxlist->Box[i].Y2); rectLeft[i] = rectRight[i] = &boxlist->Box[i]; } qsort (rectLeft, boxlist->BoxN, sizeof (*rectLeft), compareleft); qsort (rectRight, boxlist->BoxN, sizeof (*rectRight), compareright); /* sweep through x segments from left to right */ i = j = 0; lastX = rectLeft[0]->X1; while (j < boxlist->BoxN) { assert (i <= boxlist->BoxN); /* i will step through rectLeft, j will through rectRight */ if (i == boxlist->BoxN || rectRight[j]->X2 < rectLeft[i]->X1) { /* right edge of rectangle */ BoxType *b = rectRight[j++]; /* check lastX */ if (b->X2 != lastX) { assert (lastX < b->X2); area += (double) (b->X2 - lastX) * segtree.nodes[1].area; lastX = b->X2; } /* remove a segment from the segment tree. */ deleteSegment (&segtree, 1, b->Y1, b->Y2); } else { /* left edge of rectangle */ BoxType *b = rectLeft[i++]; /* check lastX */ if (b->X1 != lastX) { assert (lastX < b->X1); area += (double) (b->X1 - lastX) * segtree.nodes[1].area; lastX = b->X1; } /* add a segment from the segment tree. */ insertSegment (&segtree, 1, b->Y1, b->Y2); } } free (rectLeft); free (rectRight); free (segtree.nodes); return area * 0.0001; }