Regions Content::LayoutForPointInRegion(Point p, const Region& rgn) const { Region layoutRgn = Region(rgn.Origin() + p, frame.Dimensions()); Regions rgns; rgns.push_back(layoutRgn); return rgns; }
Regions ContentContainer::LayoutForPointInRegion(Point p, const Region&) const { Region layoutRgn(p, ContentFrame()); parentOffset = p; Regions rgns; rgns.push_back(layoutRgn); return rgns; }
Regions RegionFileLoader::ReadRegions(std::ifstream& f) { Regions regions; std::vector<Double_t> vec; Char_t next_char; std::stringstream ss; Double_t sa; std::string aline; while (1) { f >> std::ws; next_char = f.peek(); // check to see if the next is a number, // if so, this function is done break if ( ! IsNumber(next_char) ) { break; } std::getline(f,aline); ss.clear(); ss.str(""); vec.clear(); ss << aline; ss >> sa; while(!ss.fail()) { vec.push_back(sa); ss >> sa; } // std::cout << vec.size() << std::endl; if (vec.size() == 8) { Region region; region.grid_xlow = vec[0]; region.cntr_xlow = vec[1]; region.grid_xhigh = vec[2]; region.cntr_xhigh = vec[3]; region.grid_ylow = vec[4]; region.cntr_ylow = vec[5]; region.grid_yhigh = vec[6]; region.cntr_yhigh = vec[7]; // std::cout << "filling current region" << std::endl; regions.push_back(region); } } return regions; }
Regions TextSpan::LayoutForPointInRegion(Point layoutPoint, const Region& rgn) const { Regions layoutRegions; const Point& drawOrigin = rgn.Origin(); const Font* layoutFont = LayoutFont(); assert(layoutFont); if (frame.Dimensions().IsZero()) { // this means we get to wrap :) // calculate each line and print line by line int lineheight = layoutFont->LineHeight; Regions lineExclusions; Region lineRgn(layoutPoint + drawOrigin, Size(rgn.w, lineheight)); lineRgn.y -= lineheight; Region lineSegment; #define LINE_REMAINDER lineRgn.w - lineSegment.x; const Region* excluded = NULL; size_t numPrinted = 0; bool newline = true; do { if (newline || lineSegment.x + lineSegment.w >= lineRgn.x + lineRgn.w) { // start next line newline = false; lineRgn.x = drawOrigin.x; lineRgn.y += lineheight; lineRgn.w = rgn.w; layoutPoint = lineRgn.Origin(); lineSegment = lineRgn; } do { // process all overlaping exclusion zones until we trim down to the leftmost non conflicting region. // check for intersections with other content excluded = parent->ContentRegionForRect(lineSegment); if (!excluded) { // now check if we already used this region ourselves std::vector<Region>::const_iterator it; for (it = lineExclusions.begin(); it != lineExclusions.end(); ++it) { if (lineSegment.IntersectsRegion(*it)) { excluded = &*it; break; } } } // no else! if (excluded) { Region intersect = excluded->Intersect(lineSegment); if (intersect.x > lineSegment.x) { // to the right, simply shrink the width lineSegment.w = intersect.x - lineSegment.x; } else { // overlaps our start point, jump to the right of intersect int x = lineSegment.x; lineSegment.x = intersect.x + intersect.w; // must shrink to compensate for moving x lineSegment.w -= lineSegment.x - x; } // its possible that the resulting segment is 0 in width if (lineSegment.w <= 0) { lineSegment.x = intersect.x + intersect.w; lineSegment.w = LINE_REMAINDER; lineExclusions.push_back(lineSegment); newline = true; goto newline; } } } while (excluded); { // protected scope for goto assert(lineSegment.h == lineheight); size_t numOnLine = 0; // must limit our operation to this single line. size_t nextLine = text.find_first_of(L'\n', numPrinted); if (nextLine == numPrinted) { // this is a new line, we dont have to actually size that // simply occupy the entire area and advance. lineSegment.w = LINE_REMAINDER; numOnLine = 1; newline = true; } else { size_t subLen = nextLine; if (nextLine != String::npos) { subLen = nextLine - numPrinted + 1; // +1 for the \n } const String& substr = text.substr(numPrinted, subLen); Font::StringSizeMetrics metrics = {lineSegment.Dimensions(), 0, lineSegment.w == lineRgn.w}; Size printSize = layoutFont->StringSize(substr, &metrics); numOnLine = metrics.numChars; assert(numOnLine || !metrics.forceBreak); bool noFit = !metrics.forceBreak && numOnLine == 0; bool lineFilled = lineSegment.x + lineSegment.w == lineRgn.w; bool moreChars = numPrinted + numOnLine < text.length(); if (subLen != String::npos || noFit || (lineFilled && moreChars)) { // optimization for when the segment is the entire line (and we have more text) // saves looping again for the known to be useless segment newline = true; lineSegment.w = LINE_REMAINDER; } else { assert(printSize.w); lineSegment.w = printSize.w; } } numPrinted += numOnLine; } assert(!lineSegment.Dimensions().IsEmpty()); lineExclusions.push_back(lineSegment); newline: if (newline || numPrinted == text.length()) { // must claim the lineExclusions as part of the layout // just because we didnt fit doesnt mean somethng else wont... Region lineLayout = Region::RegionEnclosingRegions(lineExclusions); assert(lineLayout.h % lineheight == 0); layoutRegions.push_back(lineLayout); lineExclusions.clear(); } // FIXME: infinite loop possibility. } while (numPrinted < text.length()); #undef LINE_REMAINDER assert(numPrinted == text.length()); } else { // we are limited to drawing within our frame :( // FIXME: we ought to be able to set an alignment for "blocks" of text // probably the way to do this is have alignment on the container // then maybe another Draw method that takes an alignment argument? Region drawRegion = LayoutInFrameAtPoint(layoutPoint, rgn); assert(drawRegion.h && drawRegion.w); layoutRegions.push_back(drawRegion); } return layoutRegions; }