From: <vo...@us...> - 2009-03-02 20:41:30
|
Revision: 1151 http://opde.svn.sourceforge.net/opde/?rev=1151&view=rev Author: volca Date: 2009-03-02 20:41:26 +0000 (Mon, 02 Mar 2009) Log Message: ----------- * adding segmented text addText method (for coloured labels) * comments Modified Paths: -------------- trunk/src/services/draw/RenderedLabel.cpp trunk/src/services/draw/RenderedLabel.h Modified: trunk/src/services/draw/RenderedLabel.cpp =================================================================== --- trunk/src/services/draw/RenderedLabel.cpp 2009-02-25 06:30:43 UTC (rev 1150) +++ trunk/src/services/draw/RenderedLabel.cpp 2009-03-02 20:41:26 UTC (rev 1151) @@ -34,7 +34,7 @@ /*-------------------- RenderedLabel -----------------*/ /*----------------------------------------------------*/ RenderedLabel::RenderedLabel(DrawService* owner, DrawOperation::ID id, FontDrawSource* fds, const std::string& label) : - DrawOperation(owner, id), mFontSource(fds), mLabel(label) { + DrawOperation(owner, id), mFontSource(fds), mText() { rebuild(); } @@ -46,25 +46,43 @@ //------------------------------------------------------ void RenderedLabel::setLabel(const std::string& label) { - mLabel = label; + clearText(); + addText(label, Ogre::ColourValue::White); + _markDirty(); } //------------------------------------------------------ - void RenderedLabel::_rebuild() { - std::string::iterator it = mLabel.begin(); - std::string::iterator end = mLabel.end(); + void RenderedLabel::addText(const std::string& text, const Ogre::ColourValue& colour) { + TextSegment seg; + seg.colour = colour; + seg.text = text; + + mText.push_back(seg); + _markDirty(); + } + + //------------------------------------------------------ + void RenderedLabel::clearText() { + mText.clear(); + _markDirty(); + } - freeQuadList(); + //------------------------------------------------------ + PixelSize RenderedLabel::calculateTextSize(const std::string& text) { + std::string::const_iterator cit = text.begin(); + std::string::const_iterator cend = text.end(); - int x = 0, y = 0; + size_t x = 0, y = 0; + PixelSize sz(0,0); + + while (cit != cend) { + const unsigned char chr = *cit++; - // TODO: Clipping, reuse of quads if the quad count does not change, etc. - while (it != end) { - const unsigned char chr = *it++; - if (chr == '\n') { y += mFontSource->getHeight(); + if (sz.width < x) + sz.width = x; x = 0; continue; } @@ -78,21 +96,77 @@ if (ds != NULL) { DrawQuad dq; - fillQuad(x, y, chr, ds, dq); + x += ds->getPixelSize().width; - - // if clipping produced some non-empty result - if (mClipRect.clip(dq)) { - // the quad is queued (by making a dynamically allocated copy) - DrawQuad* toStore = new DrawQuad(dq); - mDrawQuadList.push_back(toStore); - } } else { - x += mFontSource->getWidth(); // move the maximal width (maybe 1px would be better?) + // move the maximal width (maybe 1px would be better?) + x += mFontSource->getWidth(); } } + + // not a first char on the line, so some text would be drawn. + // have to include the line's height though + if (x != 0) + sz.height = y + mFontSource->getHeight();; + + return sz; } + + //------------------------------------------------------ + void RenderedLabel::_rebuild() { + SegmentList::iterator it = mText.begin(); + SegmentList::iterator end = mText.end(); + freeQuadList(); + + int x = 0, y = 0; + + // TODO: Reuse of quads if the quad count does not change, etc. + while (it != end) { + // for each segment + TextSegment& ts = *it++; + + std::string::iterator cit = ts.text.begin(); + std::string::iterator cend = ts.text.end(); + + while (cit != cend) { + const unsigned char chr = *cit++; + + if (chr == '\n') { + y += mFontSource->getHeight(); + x = 0; + continue; + } + + // eat DOS line feeds as well... + if (chr == '\r') { + continue; + } + + DrawSource* ds = mFontSource->getGlyph(chr); + + if (ds != NULL) { + DrawQuad dq; + + fillQuad(x, y, chr, ds, dq); + + dq.color = ts.colour; + + x += ds->getPixelSize().width; + + // if clipping produced some non-empty result + if (mClipRect.clip(dq)) { + // the quad is queued (by making a dynamically allocated copy) + DrawQuad* toStore = new DrawQuad(dq); + mDrawQuadList.push_back(toStore); + } + } else { + x += mFontSource->getWidth(); // move the maximal width (maybe 1px would be better?) + } + } + } + } + //------------------------------------------------------ void RenderedLabel::freeQuadList() { DrawQuadList::iterator it = mDrawQuadList.begin(); Modified: trunk/src/services/draw/RenderedLabel.h =================================================================== --- trunk/src/services/draw/RenderedLabel.h 2009-02-25 06:30:43 UTC (rev 1150) +++ trunk/src/services/draw/RenderedLabel.h 2009-03-02 20:41:26 UTC (rev 1151) @@ -32,6 +32,7 @@ namespace Opde { + /** Rendered label. This class represents single font text area, possibly wrapped and coloured. */ class RenderedLabel : public DrawOperation { public: RenderedLabel(DrawService* owner, DrawOperation::ID id, FontDrawSource* fds, const std::string& label); @@ -40,11 +41,30 @@ void visitDrawBuffer(DrawBuffer* db); + /// A shortcut to call clear+addText(label); void setLabel(const std::string& label); + /// Adds a segment of text with a given color + void addText(const std::string& text, const Ogre::ColourValue& colour); + + /// Clears all the text from the label + void clearText(); + + /** Calculates a width and height of the given text string. + * The resulting size is of a unclipped, newline respecting text + */ + PixelSize calculateTextSize(const std::string& text); + DrawSourceBase* getDrawSourceBase(); protected: + struct TextSegment { + Ogre::ColourValue colour; + std::string text; + }; + + typedef std::list< TextSegment > SegmentList; + /// Rebuilds the label - makes new glyph instances void _rebuild(); @@ -59,7 +79,7 @@ FontDrawSource* mFontSource; - std::string mLabel; + SegmentList mText; }; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |