//----------------------------------------------------------------------------// void BasicRenderedStringParser::appendRenderedText(RenderedString& rs, const String& text) const { size_t cpos = 0; // split the given string into lines based upon the newline character while (text.length() > cpos) { // find next newline const size_t nlpos = text.find('\n', cpos); // calculate length of this substring const size_t len = ((nlpos != String::npos) ? nlpos : text.length()) - cpos; // construct new text component and append it. RenderedStringTextComponent rtc(text.substr(cpos, len), d_fontName); rtc.setPadding(d_padding); rtc.setColours(d_colours); rtc.setVerticalFormatting(d_vertAlignment); rtc.setAspectLock(d_aspectLock); rs.appendComponent(rtc); // break line if needed if (nlpos != String::npos) rs.appendLineBreak(); // advance current position. +1 to skip the \n char cpos += len + 1; } }
//----------------------------------------------------------------------------// RenderedString DefaultRenderedStringParser::parse( const String& input_string, const Font* initial_font, const ColourRect* initial_colours) { RenderedString rs; size_t epos, spos = 0; while ((epos = input_string.find('\n', spos)) != String::npos) { appendSubstring(rs, input_string.substr(spos, epos - spos), initial_font, initial_colours); rs.appendLineBreak(); // set new start position (skipping the previous \n we found) spos = epos + 1; } if (spos < input_string.length()) appendSubstring(rs, input_string.substr(spos), initial_font, initial_colours); return rs; }
//----------------------------------------------------------------------------// void RenderedString::split(const size_t line, float split_point, RenderedString& left) { // FIXME: This function is big and nasty; it breaks all the rules for a // 'good' function and desperately needs some refactoring work done to it. // On the plus side, it does seem to work though ;) if (line >= getLineCount()) CEGUI_THROW(InvalidRequestException("RenderedString::split: " "line number specified is invalid.")); left.clearComponents(); if (d_components.empty()) return; // move all components in lines prior to the line being split to the left if (line > 0) { // calculate size of range const size_t sz = d_lines[line - 1].first + d_lines[line - 1].second; // range start ComponentList::iterator cb = d_components.begin(); // range end (exclusive) ComponentList::iterator ce = cb + sz; // copy components to left side left.d_components.assign(cb, ce); // erase components from this side. d_components.erase(cb, ce); LineList::iterator lb = d_lines.begin(); LineList::iterator le = lb + line; // copy lines to left side left.d_lines.assign(lb, le); // erase lines from this side d_lines.erase(lb, le); } // find the component where the requested split point lies. float partial_extent = 0; size_t idx = 0; const size_t last_component = d_lines[0].second; for (; idx < last_component; ++idx) { partial_extent += d_components[idx]->getPixelSize().d_width; if (split_point <= partial_extent) break; } // case where split point is past the end if (idx >= last_component) { // transfer this line's components to the 'left' string. // // calculate size of range const size_t sz = d_lines[0].second; // range start ComponentList::iterator cb = d_components.begin(); // range end (exclusive) ComponentList::iterator ce = cb + sz; // copy components to left side left.d_components.insert(left.d_components.end(), cb, ce); // erase components from this side. d_components.erase(cb, ce); // copy line info to left side left.d_lines.push_back(d_lines[0]); // erase line from this side d_lines.erase(d_lines.begin()); // fix up lines in this object for (size_t comp = 0, i = 0; i < d_lines.size(); ++i) { d_lines[i].first = comp; comp += d_lines[i].second; } return; } left.appendLineBreak(); const size_t left_line = left.getLineCount() - 1; // Everything up to 'idx' is xfered to 'left' for (size_t i = 0; i < idx; ++i) { left.d_components.push_back(d_components[0]); d_components.erase(d_components.begin()); ++left.d_lines[left_line].second; --d_lines[0].second; } // now to split item 'idx' putting half in left and leaving half in this. RenderedStringComponent* c = d_components[0]; if (c->canSplit()) { RenderedStringComponent* lc = c->split(split_point - (partial_extent - c->getPixelSize().d_width), idx == 0); if (lc) { left.d_components.push_back(lc); ++left.d_lines[left_line].second; } } // can't split, if component width is >= split_point xfer the whole // component to it's own line in the left part (FIX #306) else if (c->getPixelSize().d_width >= split_point) { left.appendLineBreak(); left.d_components.push_back(d_components[0]); d_components.erase(d_components.begin()); ++left.d_lines[left_line + 1].second; --d_lines[0].second; } // fix up lines in this object for (size_t comp = 0, i = 0; i < d_lines.size(); ++i) { d_lines[i].first = comp; comp += d_lines[i].second; } }