diff --git a/include/osg/ShapeDrawable b/include/osg/ShapeDrawable index 2a960df27..26ae13a50 100644 --- a/include/osg/ShapeDrawable +++ b/include/osg/ShapeDrawable @@ -135,7 +135,7 @@ class SG_EXPORT ShapeDrawable : public Drawable */ virtual void drawImplementation(State& state) const; - /** return false, osg::ProceduralGeoemtry does not support accept(AttributeFunctor&).*/ + /** return false, osg::ShapeDrawable does not support accept(AttributeFunctor&).*/ virtual bool supports(AttributeFunctor&) const { return false; } /** return true, osg::ShapeDrawable does support accept(ConstAttributeFunctor&).*/ diff --git a/include/osgDB/Input b/include/osgDB/Input index 6c67b2fbd..74f4b05b9 100644 --- a/include/osgDB/Input +++ b/include/osgDB/Input @@ -51,7 +51,7 @@ class OSGDB_EXPORT Input : public FieldReaderIterator private: - typedef std::map UniqueIDToObjectMapping; + typedef std::map< std::string, osg::ref_ptr > UniqueIDToObjectMapping; UniqueIDToObjectMapping _uniqueIDToObjectMap; }; diff --git a/include/osgText/Text b/include/osgText/Text index 6a02e988c..67e052f45 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -183,6 +183,22 @@ public: /** Draw the text.*/ virtual void drawImplementation(osg::State& state) const; + /** return false, osgText::Text does not support accept(AttributeFunctor&).*/ + virtual bool supports(osg::Drawable::AttributeFunctor&) const { return false; } + + /** return true, osgText::Text does support accept(ConstAttributeFunctor&).*/ + virtual bool supports(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(osg::Drawable::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::Drawable::PrimitiveFunctor& pf) const; + + // make Font a friend to allow it set the _font to 0 if the font is // forcefully unloaded. friend class Font; diff --git a/src/osgDB/Input.cpp b/src/osgDB/Input.cpp index f37dcf78f..56e56c35e 100644 --- a/src/osgDB/Input.cpp +++ b/src/osgDB/Input.cpp @@ -31,7 +31,7 @@ Input::~Input() osg::Object* Input::getObjectForUniqueID(const std::string& uniqueID) { UniqueIDToObjectMapping::iterator fitr = _uniqueIDToObjectMap.find(uniqueID); - if (fitr != _uniqueIDToObjectMap.end()) return (*fitr).second; + if (fitr != _uniqueIDToObjectMap.end()) return (*fitr).second.get(); else return NULL; } diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 622aeb578..6023a0df9 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -569,7 +569,7 @@ osg::Object* Registry::readObjectOfType(const osg::Object& compObj,Input& fr) if (fr[1].isString()) { Object* obj = fr.getObjectForUniqueID(fr[1].getStr()); - if (compObj.isSameKindAs(obj)) + if (obj && compObj.isSameKindAs(obj)) { fr+=2; return obj; diff --git a/src/osgPlugins/freetype/Makefile b/src/osgPlugins/freetype/Makefile index 14221c582..8d00b60b7 100644 --- a/src/osgPlugins/freetype/Makefile +++ b/src/osgPlugins/freetype/Makefile @@ -6,7 +6,7 @@ CXXFILES =\ FreeTypeFont.cpp\ ReaderWriterFreeType.cpp\ -LIBS += $(OSG_LIBS) $(FREETYPE_LIB) $(OTHER_LIBS) +LIBS += -losgText $(OSG_LIBS) $(FREETYPE_LIB) $(OTHER_LIBS) ifneq ($(OS),HP-UX) INC += -I$(OSGHOME)/include \ diff --git a/src/osgPlugins/osgText/IO_Text.cpp b/src/osgPlugins/osgText/IO_Text.cpp index 060522714..057863783 100644 --- a/src/osgPlugins/osgText/IO_Text.cpp +++ b/src/osgPlugins/osgText/IO_Text.cpp @@ -10,6 +10,7 @@ #include #include #include +#include bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr); bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw); @@ -28,10 +29,118 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr) osgText::Text &text = static_cast(obj); bool itAdvanced = false; + + if (fr.matchSequence("font %w")) + { + text.setFont(fr[1].getStr()); + fr += 2; + itAdvanced = true; + + } + + if (fr[0].matchWord("fontSize")) + { + unsigned int width; + unsigned int height; + if (fr[1].getUInt(width) && fr[2].getUInt(height)) + { + text.setFontSize(width,height); + fr += 3; + itAdvanced = true; + } + } + + if (fr[0].matchWord("characterSize")) + { + float height; + float aspectRatio; + if (fr[1].getFloat(height) && fr[2].getFloat(aspectRatio)) + { + text.setCharacterSize(height,aspectRatio); + fr += 3; + itAdvanced = true; + } + } + + // maximum dimentsions of text box. + if (fr[0].matchWord("maximumWidth")) + { + float width; + if (fr[1].getFloat(width)) + { + text.setMaximumWidth(width); + fr += 2; + itAdvanced = true; + } + } + + if (fr[0].matchWord("maximumHeight")) + { + float height; + if (fr[1].getFloat(height)) + { + text.setMaximumWidth(height); + fr += 2; + itAdvanced = true; + } + } + + if (fr.matchSequence("alignment %w")) + { + std::string str = fr[1].getStr(); + if (str=="LEFT_TOP") text.setAlignment(osgText::Text::LEFT_TOP); + else if (str=="LEFT_CENTER") text.setAlignment(osgText::Text::LEFT_CENTER); + else if (str=="LEFT_BOTTOM") text.setAlignment(osgText::Text::LEFT_BOTTOM); + else if (str=="CENTER_TOP") text.setAlignment(osgText::Text::CENTER_TOP); + else if (str=="CENTER_CENTER") text.setAlignment(osgText::Text::CENTER_CENTER); + else if (str=="CENTER_BOTTOM") text.setAlignment(osgText::Text::CENTER_BOTTOM); + else if (str=="RIGHT_TOP") text.setAlignment(osgText::Text::RIGHT_TOP); + else if (str=="RIGHT_CENTER") text.setAlignment(osgText::Text::RIGHT_CENTER); + else if (str=="RIGHT_BOTTOM") text.setAlignment(osgText::Text::RIGHT_BOTTOM); + else if (str=="BASE_LINE") text.setAlignment(osgText::Text::BASE_LINE); + fr += 2; + itAdvanced = true; + } + + if (fr.matchSequence("axisAlignment %w")) + { + std::string str = fr[1].getStr(); + if (str=="XY_PLANE") text.setAxisAlignment(osgText::Text::XY_PLANE); + else if (str=="XZ_PLANE") text.setAxisAlignment(osgText::Text::XZ_PLANE); + else if (str=="YZ_PLANE") text.setAxisAlignment(osgText::Text::YZ_PLANE); + else if (str=="SCREEN") text.setAxisAlignment(osgText::Text::SCREEN); + fr += 2; + itAdvanced = true; + } + + if (fr.matchSequence("rotation")) + { + osg::Vec4 rotation; + if (fr[1].getFloat(rotation.x()) && fr[2].getFloat(rotation.y()) && fr[3].getFloat(rotation.z()) && fr[4].getFloat(rotation.w())) + { + text.setRotation(rotation); + fr += 4; + itAdvanced = true; + } + } + + if (fr.matchSequence("layout %w")) + { + std::string str = fr[1].getStr(); + if (str=="LEFT_TO_RIGHT") text.setLayout(osgText::Text::LEFT_TO_RIGHT); + else if (str=="RIGHT_TO_LEFT") text.setLayout(osgText::Text::RIGHT_TO_LEFT); + else if (str=="VERTICAL") text.setLayout(osgText::Text::VERTICAL); + fr += 2; + itAdvanced = true; + } + + // position - if (fr[0].matchWord("position")) { + if (fr[0].matchWord("position")) + { osg::Vec3 p; - if (fr[1].getFloat(p.x()) && fr[2].getFloat(p.y()) && fr[3].getFloat(p.z())) { + if (fr[1].getFloat(p.x()) && fr[2].getFloat(p.y()) && fr[3].getFloat(p.z())) + { text.setPosition(p); fr += 4; itAdvanced = true; @@ -39,9 +148,11 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr) } // color - if (fr[0].matchWord("color")) { + if (fr[0].matchWord("color")) + { osg::Vec4 c; - if (fr[1].getFloat(c.x()) && fr[2].getFloat(c.y()) && fr[3].getFloat(c.z()) && fr[4].getFloat(c.w())) { + if (fr[1].getFloat(c.x()) && fr[2].getFloat(c.y()) && fr[3].getFloat(c.z()) && fr[4].getFloat(c.w())) + { text.setColor(c); fr += 4; itAdvanced = true; @@ -49,7 +160,8 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr) } // draw mode - if (fr[0].matchWord("drawMode")) { + if (fr[0].matchWord("drawMode")) + { int i; if (fr[1].getInt(i)) { text.setDrawMode(i); @@ -58,16 +170,6 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr) } } - // alignment - if (fr[0].matchWord("alignment")) { - int i; - if (fr[1].getInt(i)) { - text.setAlignment((osgText::Text::AlignmentType)i); - fr += 2; - itAdvanced = true; - } - } - // text if (fr.matchSequence("text %s")) { text.setText(std::string(fr[1].getStr())); @@ -75,6 +177,39 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr) itAdvanced = true; } + if (fr.matchSequence("text %i {")) + { + // pre 0.9.3 releases.. + int entry = fr[0].getNoNestedBrackets(); + + int capacity; + fr[1].getInt(capacity); + + osgText::String str; + str.reserve(capacity); + + fr += 3; + + while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) + { + unsigned int c; + if (fr[0].getUInt(c)) + { + ++fr; + str.push_back(c); + } + else + { + ++fr; + } + } + + text.setText(str); + + itAdvanced = true; + ++fr; + } + return itAdvanced; } @@ -87,8 +222,69 @@ bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw) fw.indent() << "font " << text.getFont()->getFileName() << std::endl; } + // font resolution fw.indent() << "fontSize " << text.getFontWidth() << " " << text.getFontHeight() << std::endl; + // charater size. + fw.indent() << "characterSize " << text.getCharacterHeight() << " " << text.getCharacterAspectRatio() << std::endl; + + // maximum dimension of text box. + if (text.getMaximumWidth()>0.0f) + { + fw.indent() << "maximumWidth " << text.getMaximumWidth() << std::endl; + } + + if (text.getMaximumHeight()>0.0f) + { + fw.indent() << "maximumHeight " << text.getMaximumHeight() << std::endl; + } + + // alignment + fw.indent() << "alignment "; + switch(text.getAlignment()) + { + case osgText::Text::LEFT_TOP: fw << "LEFT_TOP" << std::endl; break; + case osgText::Text::LEFT_CENTER : fw << "LEFT_CENTER" << std::endl; break; + case osgText::Text::LEFT_BOTTOM : fw << "LEFT_BOTTOM" << std::endl; break; + + case osgText::Text::CENTER_TOP: fw << "CENTER_TOP" << std::endl; break; + case osgText::Text::CENTER_CENTER: fw << "CENTER_CENTER" << std::endl; break; + case osgText::Text::CENTER_BOTTOM: fw << "CENTER_BOTTOM" << std::endl; break; + + case osgText::Text::RIGHT_TOP: fw << "RIGHT_TOP" << std::endl; break; + case osgText::Text::RIGHT_CENTER: fw << "RIGHT_CENTER" << std::endl; break; + case osgText::Text::RIGHT_BOTTOM: fw << "RIGHT_BOTTOM" << std::endl; break; + + case osgText::Text::BASE_LINE: fw << "BASE_LINE" << std::endl; break; + }; + + + // axis alignment + fw.indent() << "axisAlignment "; + switch(text.getAxisAlignment()) + { + case osgText::Text::XY_PLANE: fw << "XY_PLANE" << std::endl; break; + case osgText::Text::XZ_PLANE: fw << "XZ_PLANE" << std::endl; break; + case osgText::Text::YZ_PLANE: fw << "YZ_PLANE" << std::endl; break; + case osgText::Text::SCREEN: fw << "SCREEN" << std::endl; break; + }; + + if (!text.getRotation().zeroRotation()) + { + fw.indent() << "rotation " << text.getRotation() << std::endl; + } + + + // layout + fw.indent() << "layout "; + switch(text.getLayout()) + { + case osgText::Text::LEFT_TO_RIGHT: fw << "LEFT_TO_RIGHT" << std::endl; break; + case osgText::Text::RIGHT_TO_LEFT: fw << "RIGHT_TO_LEFT" << std::endl; break; + case osgText::Text::VERTICAL: fw << "VERTICAL" << std::endl; break; + }; + + // position osg::Vec3 p = text.getPosition(); fw.indent() << "position " << p.x() << " " << p.y() << " " << p.z() << std::endl; @@ -100,8 +296,6 @@ bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw) // draw mode fw.indent() << "drawMode " << text.getDrawMode() << std::endl; - // alignment - fw.indent() << "alignment " << text.getAlignment() << std::endl; // text const osgText::String& textstring = text.getText(); @@ -120,10 +314,10 @@ bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw) } else { - // do it the hardway... + // do it the hardway...output each character as an int + fw.indent() << "text "<setGlyphImageMargin(_margin); diff --git a/src/osgText/Makefile b/src/osgText/Makefile index 7f5cbef9e..57769bf5d 100644 --- a/src/osgText/Makefile +++ b/src/osgText/Makefile @@ -11,7 +11,7 @@ CXXFILES = \ DEF += -DOSGTEXT_LIBRARY -LIBS += -losgDB -losgUtil -losg $(GL_LIBS) $(OTHER_LIBS) +LIBS += -losgDB -losg $(GL_LIBS) $(OTHER_LIBS) TARGET_BASENAME = osgText LIB = $(LIB_PREFIX)$(TARGET_BASENAME).$(LIB_EXT) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 25dc3e6b5..422f34d2c 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -240,8 +240,8 @@ void Text::computeGlyphRepresentation() if (charcode=='\n') { - if (horizontal) startOfLine.y() -= _fontHeight; - else startOfLine.x() += _fontWidth; + if (horizontal) startOfLine.y() -= _characterHeight; + else startOfLine.x() += _characterHeight; cursor = startOfLine; previous_charcode = 0; continue; @@ -300,7 +300,7 @@ void Text::computeGlyphRepresentation() { if (local.x()+width>_maximumWidth) { - startOfLine.y() -= _fontHeight; + startOfLine.y() -= _characterHeight; cursor = startOfLine; previous_charcode = 0; @@ -317,7 +317,7 @@ void Text::computeGlyphRepresentation() { if (local.x()<-_maximumWidth) { - startOfLine.y() -= _fontHeight; + startOfLine.y() -= _characterHeight; cursor = startOfLine; previous_charcode = 0; @@ -333,7 +333,7 @@ void Text::computeGlyphRepresentation() { if (local.y()<-_maximumHeight) { - startOfLine.x() += _fontWidth; + startOfLine.x() += _characterHeight/_characterAspectRatio; cursor = startOfLine; previous_charcode = 0; @@ -470,8 +470,6 @@ void Text::drawImplementation(osg::State& state) const if (_drawMode & TEXT) { - bool first = false; - state.disableAllVertexArrays(); for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin(); @@ -479,11 +477,7 @@ void Text::drawImplementation(osg::State& state) const ++titr) { // need to set the texture here... - - if (!first) - { - state.apply(titr->first.get()); - } + state.apply(titr->first.get()); const GlyphQuads& glyphquad = titr->second; @@ -492,8 +486,6 @@ void Text::drawImplementation(osg::State& state) const glDrawArrays(GL_QUADS,0,glyphquad._coords.size()); - first = false; - } } @@ -536,3 +528,36 @@ void Text::drawImplementation(osg::State& state) const glPopMatrix(); } +void Text::accept(osg::Drawable::ConstAttributeFunctor& af) const +{ + for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin(); + titr!=_textureGlyphQuadMap.end(); + ++titr) + { + const GlyphQuads& glyphquad = titr->second; + af.apply(osg::Drawable::VERTICES,glyphquad._coords.size(),&(glyphquad._coords.front())); + af.apply(osg::Drawable::TEXTURE_COORDS_0,glyphquad._texcoords.size(),&(glyphquad._texcoords.front())); + } +} + +void Text::accept(osg::Drawable::PrimitiveFunctor& pf) const +{ + for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin(); + titr!=_textureGlyphQuadMap.end(); + ++titr) + { + const GlyphQuads& glyphquad = titr->second; + + pf.begin(GL_QUADS); + for(GlyphQuads::Coords::const_iterator itr = glyphquad._coords.begin(); + itr!=glyphquad._coords.end(); + ++itr) + { + + osg::Vec3 pos(itr->x(),itr->y(),0.0f); + pf.vertex(pos*_matrix); + } + pf.end(); + } + +}