/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #ifndef OSGTEXT_TEXT #define OSGTEXT_TEXT 1 #include #include #include #include namespace osgText { class OSGTEXT_EXPORT Text : public osg::Drawable { public: Text(); Text(const Text& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); virtual osg::Object* cloneType() const { return new Text(); } virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new Text(*this,copyop); } virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } virtual const char* className() const { return "Text"; } virtual const char* libraryName() const { return "osgText"; } /** Set the Font to use to render the text. * setFont(0) sets the use of the default font.*/ void setFont(Font* font=0); /** Set the font, loaded from the specified front file, to use to render the text, * setFont("") sets the use of the default font. * See the osgText::readFontFile function for how the font file will be located. */ void setFont(const std::string& fontfile); /** Get the font. Return 0 if default is being used.*/ const Font* getFont() const { return _font.get(); } /** Set the Font reference width and height resolution in texels. * Note, the size may not be supported by current font, * the closest supported font size will be selected.*/ void setFontResolution(unsigned int width, unsigned int height); unsigned int getFontWidth() const { return _fontWidth; } unsigned int getFontHeight() const { return _fontHeight; } /** Set the text using a osgText::String.*/ void setText(const String& text); /** Set the text using a std::string, * which is converted to an internal TextString.*/ void setText(const std::string& text); /** Set the text using a Unicode encoded std::string, which is converted to an internal TextString. * The encoding parameter specificies which Unicode encodeding is used in the std::string. */ void setText(const std::string& text,String::Encoding encoding); /** Set the text using a wchar_t string, * which is converted to an internal TextString.*/ void setText(const wchar_t* text); /** Get the text string. * Note, if you modify the string you must call Text::update() for * the internal glyph reprentation to be updated.*/ String& getText() { return _text; } /** Get the const text string.*/ const String& getText() const { return _text; } /** update internal glyph respresnetation used for rendering, * and bounding volume.*/ void update() { computeGlyphRepresentation(); } /** Set the rendered character size in object coordinates.*/ void setCharacterSize(float height,float aspectRatio=1.0f); float getCharacterHeight() const { return _characterHeight; } float getCharacterAspectRatio() const { return _characterAspectRatio; } enum CharacterSizeMode { OBJECT_COORDS, /// default SCREEN_COORDS, /// internally scale the characters to be constant screen size. OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT /// text that behavaves like OBJECT_COORDS sized text when a long distance way, but has its screen sized capped automatically when the viewer gets near. }; /** Set how the CharacterSize value relates to the final rendered character.*/ void setCharacterSizeMode(CharacterSizeMode mode) { _characterSizeMode = mode; } /** Get the CharacterSizeMode.*/ CharacterSizeMode getCharacterSizeMode() const { return _characterSizeMode; } /** Set the maximum width of the text box. * With horizontal layouts any characters which do not fit are wrapped around. * 0 or negative values indicate that no maximum width is set, lines can be as long as * they need be to fit thre required text*/ void setMaximumWidth(float maximumWidth); /** Get the maximim width of the text box.*/ float getMaximumWidth() const { return _maximumWidth; } /** Set the maximum height of the text box. * With horizontal layouts any characters which do not fit are wrapped around. * 0 or negative values indicate that no maximum height is set, lines can be as long as * they need be to fit thre required text*/ void setMaximumHeight(float maximumHeight); /** Get the maximum height of the text box.*/ float getMaximumHeight() const { return _maximumHeight; } /** Set the position of text.*/ void setPosition(const osg::Vec3& pos); /** Get the position of text.*/ const osg::Vec3& getPosition() const { return _position; } enum AlignmentType { LEFT_TOP, LEFT_CENTER, LEFT_BOTTOM, CENTER_TOP, CENTER_CENTER, CENTER_BOTTOM, RIGHT_TOP, RIGHT_CENTER, RIGHT_BOTTOM, LEFT_BASE_LINE, CENTER_BASE_LINE, RIGHT_BASE_LINE, LEFT_BOTTOM_BASE_LINE, CENTER_BOTTOM_BASE_LINE, RIGHT_BOTTOM_BASE_LINE, BASE_LINE = LEFT_BASE_LINE /// default. }; void setAlignment(AlignmentType alignment); AlignmentType getAlignment() const { return _alignment; } enum AxisAlignment { XY_PLANE, REVERSED_XY_PLANE, XZ_PLANE, REVERSED_XZ_PLANE, YZ_PLANE, REVERSED_YZ_PLANE, SCREEN }; void setAxisAlignment(AxisAlignment axis); void setRotation(const osg::Quat& quat); const osg::Quat& getRotation() const { return _rotation; } void setAutoRotateToScreen(bool autoRotateToScreen); bool getAutoRotateToScreen() const { return _autoRotateToScreen; } enum Layout { LEFT_TO_RIGHT, /// default RIGHT_TO_LEFT, VERTICAL }; void setLayout(Layout layout); Layout getLayout() const { return _layout; } void setColor(const osg::Vec4& color); const osg::Vec4& getColor() const { return _color; } enum DrawModeMask { TEXT = 1, /// default BOUNDINGBOX = 2, ALIGNMENT = 4 }; void setDrawMode(unsigned int mode); unsigned int getDrawMode() const { return _drawMode; } void setKerningType(KerningType kerningType) { _kerningType = kerningType; } KerningType getKerningType() const { return _kerningType; } /** Get the number of wrapped lines - only valid after computeGlyphRepresentation() has been called, returns 0 otherwise */ unsigned int getLineCount() { return _lineCount; } /** Draw the text.*/ virtual void drawImplementation(osg::State& state) const; /** return false, osgText::Text does not support accept(AttributeFunctor&).*/ virtual bool supports(const osg::Drawable::AttributeFunctor&) const { return false; } /** return true, osgText::Text does support accept(ConstAttributeFunctor&).*/ virtual bool supports(const osg::Drawable::ConstAttributeFunctor&) const { return true; } /** accept an ConstAttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const; /** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/ virtual bool supports(const osg::PrimitiveFunctor&) const { return true; } /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/ virtual void accept(osg::PrimitiveFunctor& pf) const; /** If State is non-zero, this function releases OpenGL objects for * the specified graphics context. Otherwise, releases OpenGL objexts * for all graphics contexts. */ virtual void releaseGLObjects(osg::State* state=0) const; // make Font a friend to allow it set the _font to 0 if the font is // forcefully unloaded. friend class Font; public: // internal structures, variable and methods used for rendering of characters. struct OSGTEXT_EXPORT GlyphQuads { typedef std::vector Glyphs; typedef std::vector LineNumbers; typedef std::vector Coords2; typedef std::vector Coords3; typedef std::vector TexCoords; Glyphs _glyphs; Coords2 _coords; osg::buffered_object _transformedCoords; TexCoords _texcoords; LineNumbers _lineNumbers; Glyphs getGlyphs() { return _glyphs; } const Glyphs getGlyphs() const { return _glyphs; } Coords2& getCoords() { return _coords; } const Coords2& getCoords() const { return _coords; } Coords3& getTransformedCoords(unsigned int contexID) { return _transformedCoords[contexID]; } const Coords3& getTransformedCoords(unsigned int contexID) const { return _transformedCoords[contexID]; } TexCoords& getTexCoords() { return _texcoords; } const TexCoords& getTexCoords() const { return _texcoords; } LineNumbers& getLineNumbers() { return _lineNumbers; } const LineNumbers& getLineNumbers() const { return _lineNumbers; } }; typedef std::map,GlyphQuads> TextureGlyphQuadMap; /** Direct Access to GlyphQuads */ const GlyphQuads* getGlyphQuads(osg::StateSet* stateSet) const { TextureGlyphQuadMap::iterator itGlyphQuad = _textureGlyphQuadMap.find(stateSet); if (itGlyphQuad == _textureGlyphQuadMap.end()) return NULL; return &itGlyphQuad->second; } const TextureGlyphQuadMap& getTextureGlyphQuadMap() const { return _textureGlyphQuadMap; } virtual osg::BoundingBox computeBound() const; protected: virtual ~Text(); Font* getActiveFont(); const Font* getActiveFont() const; String::iterator computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last); // members which have public access. osg::ref_ptr _font; unsigned int _fontWidth; unsigned int _fontHeight; float _characterHeight; float _characterAspectRatio; CharacterSizeMode _characterSizeMode; float _maximumWidth; float _maximumHeight; String _text; osg::Vec3 _position; AlignmentType _alignment; osg::Quat _rotation; bool _autoRotateToScreen; Layout _layout; osg::Vec4 _color; unsigned int _drawMode; KerningType _kerningType; unsigned int _lineCount; // iternal map used for rendering. Set up by the computeGlyphRepresentation() method. mutable TextureGlyphQuadMap _textureGlyphQuadMap; void computeGlyphRepresentation(); // internal caches of the positioning of the text. struct AutoTransformCache { AutoTransformCache(): _traversalNumber(-1), _width(0), _height(0) {} int _traversalNumber; int _width; int _height; osg::Vec3 _transformedPosition; osg::Matrix _modelview; osg::Matrix _projection; osg::Matrix _matrix; }; mutable osg::buffered_object _autoTransformCache; mutable osg::Vec3 _offset; mutable osg::Vec3 _normal; mutable osg::BoundingBox _textBB; void computePositions(); void computePositions(unsigned int contextID) const; }; } #endif