#include <simgear/canvas/Canvas.hxx>
#include <simgear/canvas/CanvasSystemAdapter.hxx>
#include <simgear/scene/util/parse_color.hxx>
+#include <osg/Version>
#include <osgText/Text>
namespace simgear
TextOSG(canvas::Text* text);
+ void setFontResolution(int res);
void setCharacterAspect(float aspect);
+ void setLineHeight(float factor);
void setFill(const std::string& fill);
void setBackgroundColor(const std::string& fill);
protected:
canvas::Text *_text_element;
+
+ virtual void computePositions(unsigned int contextID) const;
};
//----------------------------------------------------------------------------
Text::TextOSG::TextOSG(canvas::Text* text):
_text_element(text)
{
+ setBackdropImplementation(NO_DEPTH_BUFFER);
+ }
+ //----------------------------------------------------------------------------
+ void Text::TextOSG::setFontResolution(int res)
+ {
+ TextBase::setFontResolution(res, res);
}
//----------------------------------------------------------------------------
setCharacterSize(getCharacterHeight(), aspect);
}
+ //----------------------------------------------------------------------------
+ void Text::TextOSG::setLineHeight(float factor)
+ {
+ setLineSpacing(factor - 1);
+ }
+
//----------------------------------------------------------------------------
void Text::TextOSG::setFill(const std::string& fill)
{
if( !bb.valid() )
return bb;
+#if OSG_VERSION_LESS_THAN(3,1,0)
// TODO bounding box still doesn't seem always right (eg. with center
// horizontal alignment not completely accurate)
bb._min.y() += _offset.y();
bb._max.y() += _offset.y();
+#endif
_text_element->setBoundingBox(bb);
return bb;
}
+ //----------------------------------------------------------------------------
+ void Text::TextOSG::computePositions(unsigned int contextID) const
+ {
+ if( _textureGlyphQuadMap.empty() || _layout == VERTICAL )
+ return osgText::Text::computePositions(contextID);
+
+ // TODO check when it can be larger
+ assert( _textureGlyphQuadMap.size() == 1 );
+
+ const GlyphQuads& quads = _textureGlyphQuadMap.begin()->second;
+ const GlyphQuads::Glyphs& glyphs = quads._glyphs;
+ const GlyphQuads::Coords2& coords = quads._coords;
+ const GlyphQuads::LineNumbers& line_numbers = quads._lineNumbers;
+
+ float wr = _characterHeight / getCharacterAspectRatio();
+
+ size_t cur_line = static_cast<size_t>(-1);
+ for(size_t i = 0; i < glyphs.size(); ++i)
+ {
+ // Check horizontal offsets
+
+ bool first_char = cur_line != line_numbers[i];
+ cur_line = line_numbers[i];
+
+ bool last_char = (i + 1 == glyphs.size())
+ || (cur_line != line_numbers[i + 1]);
+
+ if( first_char || last_char )
+ {
+ // From osg/src/osgText/Text.cpp:
+ //
+ // osg::Vec2 upLeft = local+osg::Vec2(0.0f-fHorizQuadMargin, ...);
+ // osg::Vec2 lowLeft = local+osg::Vec2(0.0f-fHorizQuadMargin, ...);
+ // osg::Vec2 lowRight = local+osg::Vec2(width+fHorizQuadMargin, ...);
+ // osg::Vec2 upRight = local+osg::Vec2(width+fHorizQuadMargin, ...);
+
+ float left = coords[i * 4].x(),
+ right = coords[i * 4 + 2].x(),
+ width = glyphs[i]->getWidth() * wr;
+
+ // (local + width + fHoriz) - (local - fHoriz) = width + 2*fHoriz | -width
+ float margin = 0.5f * (right - left - width),
+ cursor_x = left + margin
+ - glyphs[i]->getHorizontalBearing().x() * wr;
+
+ if( first_char )
+ {
+ if( cur_line == 0 || cursor_x < _textBB._min.x() )
+ _textBB._min.x() = cursor_x;
+ }
+
+ if( last_char )
+ {
+ float cursor_w = cursor_x + glyphs[i]->getHorizontalAdvance() * wr;
+
+ if( cur_line == 0 || cursor_w > _textBB._max.x() )
+ _textBB._max.x() = cursor_w;
+ }
+ }
+ }
+
+ return osgText::Text::computePositions(contextID);
+ }
+
+ //----------------------------------------------------------------------------
+ const std::string Text::TYPE_NAME = "text";
+
+ //----------------------------------------------------------------------------
+ void Text::staticInit()
+ {
+ if( isInit<Text>() )
+ return;
+
+ osg::ref_ptr<TextOSG> Text::*text = &Text::_text;
+
+ addStyle("fill", "color", &TextOSG::setFill, text);
+ addStyle("background", "color", &TextOSG::setBackgroundColor, text);
+ addStyle("character-size",
+ "numeric",
+ static_cast<
+ void (TextOSG::*)(float)
+ > (&TextOSG::setCharacterSize),
+ text);
+ addStyle("character-aspect-ratio",
+ "numeric",
+ &TextOSG::setCharacterAspect, text);
+ addStyle("line-height", "numeric", &TextOSG::setLineHeight, text);
+ addStyle("font-resolution", "numeric", &TextOSG::setFontResolution, text);
+ addStyle("padding", "numeric", &TextOSG::setBoundingBoxMargin, text);
+ // TEXT = 1 default
+ // BOUNDINGBOX = 2
+ // FILLEDBOUNDINGBOX = 4
+ // ALIGNMENT = 8
+ addStyle<int>("draw-mode", "", &TextOSG::setDrawMode, text);
+ addStyle("max-width", "numeric", &TextOSG::setMaximumWidth, text);
+ addStyle("font", "", &Text::setFont);
+ addStyle("alignment", "", &Text::setAlignment);
+ addStyle("text", "", &Text::setText, false);
+ }
+
//----------------------------------------------------------------------------
Text::Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
Element(canvas, node, parent_style, parent),
_text( new Text::TextOSG(this) )
{
+ staticInit();
+
setDrawable(_text);
_text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS);
_text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION);
_text->setRotation(osg::Quat(osg::PI, osg::X_AXIS));
- addStyle("fill", &TextOSG::setFill, _text);
- addStyle("background", &TextOSG::setBackgroundColor, _text);
- addStyle("character-size",
- static_cast<void (TextOSG::*)(float)>(&TextOSG::setCharacterSize),
- _text);
- addStyle("character-aspect-ratio", &TextOSG::setCharacterAspect, _text);
- addStyle("padding", &TextOSG::setBoundingBoxMargin, _text);
- // TEXT = 1 default
- // BOUNDINGBOX = 2
- // FILLEDBOUNDINGBOX = 4
- // ALIGNMENT = 8
- addStyle<int>("draw-mode", &TextOSG::setDrawMode, _text);
- addStyle("max-width", &TextOSG::setMaximumWidth, _text);
- addStyle("font", &Text::setFont, this);
- addStyle("alignment", &Text::setAlignment, this);
- addStyle("text", &Text::setText, this);
-
setupStyle();
}
//----------------------------------------------------------------------------
void Text::setFont(const char* name)
{
- _text->setFont( _canvas.lock()->getSystemAdapter()->getFont(name) );
+ _text->setFont( Canvas::getSystemAdapter()->getFont(name) );
}
//----------------------------------------------------------------------------