diff --git a/include/osgText/Font3D b/include/osgText/Font3D index 2ded85516..fdbbf1576 100644 --- a/include/osgText/Font3D +++ b/include/osgText/Font3D @@ -1,13 +1,13 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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 + * 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ @@ -31,7 +31,7 @@ class Font3D; class Text3D; /** Read a font from specified file. The filename may contain a path. - * It will search for the font file in the following places in this order: + * It will search for the font file in the following places in this order: * - In the current directory * - All paths defined in OSG_FILE_PATH or OSGFILEPATH environment variable * - Filename with path stripped: In the current directory @@ -45,7 +45,7 @@ class Text3D; * - Other OS: In /usr/share/fonts/ttf * - Other OS: In /usr/share/fonts/ttf/western * - Other OS: In /usr/share/fonts/ttf/decoratives - * + * * If the given file could not be found, the path part will be stripped and * the file will be searched again in the OS specific directories. */ @@ -67,7 +67,7 @@ class OSGTEXT_EXPORT Font3D : public osg::Object { // declare the interface to a font. public: - + // forward declare nested classes. class Glyph3D; class Font3DImplementation; @@ -92,13 +92,13 @@ public: /** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/ virtual Glyph3D* getGlyph(unsigned int charcode); - + /** Return true if this font provides vertical alignments and spacing or glyphs.*/ virtual bool hasVertical() const; /** Return the scale to apply on the glyph to have a charactere size equal to 1 */ virtual float getScale() const { return _implementation->getScale(); }; - + // make Text a friend to allow it add and remove its entry in the Font's _textList. friend class Font3DImplementation; @@ -109,16 +109,16 @@ public: /** Set whether to use a mutex to ensure ref() and unref() */ virtual void setThreadSafeRefUnref(bool threadSafe); - + typedef OpenThreads::Mutex Font3DMutex; protected: virtual ~Font3D(); - + // void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph* glyph); void addGlyph(unsigned int charcode, Glyph3D* glyph); - + // current active size of font unsigned int _depth; unsigned int _width; @@ -127,22 +127,22 @@ protected: // float _marginRatio; typedef std::map > Glyph3DMap; - Glyph3DMap _glyph3DMap; - + Glyph3DMap _glyph3DMap; + osg::ref_ptr _implementation; - + // declare the nested classes. public: class Font3DImplementation : public osg::Referenced { public: - + Font3DImplementation(): osg::Referenced(true), _facade(0) {} - + virtual std::string getFileName() const = 0; /** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/ @@ -153,20 +153,20 @@ public: /** Return true if this font provides vertical alignments and spacing or glyphs.*/ virtual bool hasVertical() const = 0; - + virtual float getScale() const = 0; - + void setFontWidth(unsigned int width) { _facade->_width = width; } void setFontHeight(unsigned int height) { _facade->_height = height; } - + void setFontDepth(unsigned int depth) { _facade->_depth = depth; } - + // void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph3D* glyph) // { // _facade->addGlyph(width, height, charcode, glyph); // } -// +// // void addGlyph(unsigned int charcode, Glyph3D* glyph) // { // _facade->addGlyph(charcode, glyph); @@ -181,26 +181,26 @@ public: Glyph3D(unsigned int glyphCode): osg::Referenced(true), - _glyphCode(glyphCode), + _glyphCode(glyphCode), _horizontalBearing(0,0), _horizontalAdvance(0), _verticalBearing(0,0), _verticalAdvance(0) {} - + /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ // virtual int compare(const osg::StateAttribute& rhs) const; -// +// // virtual void apply(osg::State& state) const; - - + + unsigned int getGlyphCode() const { return _glyphCode; } - + void setHorizontalBearing(const osg::Vec2& bearing) { _horizontalBearing=bearing; } const osg::Vec2 & getHorizontalBearing() const { return _horizontalBearing; } - + void setHorizontalAdvance(float advance) { _horizontalAdvance=advance; } float getHorizontalAdvance() const { return _horizontalAdvance; } @@ -209,42 +209,44 @@ public: void setVerticalAdvance(float advance) { _verticalAdvance=advance; } float getVerticalAdvance() const { return _verticalAdvance; } - + void setBoundingBox(osg::BoundingBox & bb) { _bb=bb; } const osg::BoundingBox & getBoundingBox() const { return _bb; } - - + + /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ virtual void setThreadSafeRefUnref(bool threadSafe); - + /** Get the PrimitiveSetList for the front face. */ osg::Geometry::PrimitiveSetList & getFrontPrimitiveSetList() { return _frontPrimitiveSetList; } /** Get the PrimitiveSetList for the wall face. */ osg::Geometry::PrimitiveSetList & getWallPrimitiveSetList() { return _wallPrimitiveSetList; } /** Get et the PrimitiveSetList for the back face. */ osg::Geometry::PrimitiveSetList & getBackPrimitiveSetList() { return _backPrimitiveSetList; } - + /** Set the VertexArray of the glyph. */ void setVertexArray(osg::Vec3Array * va) { _vertexArray = va; } /** Get the VertexArray of the glyph. */ osg::Vec3Array * getVertexArray() { return _vertexArray.get(); } + /** Set the VertexArray of the glyph. */ + void setNormalArray(osg::Vec3Array * na) { _normalArray = na; } /** Get the NormalArray for the wall face. */ osg::Vec3Array * getNormalArray() { return _normalArray.get(); } - + float getHorizontalWidth() { return (-_horizontalBearing.x() + _horizontalAdvance); } float getHorizontalHeight() { return (-_horizontalBearing.y() + _bb.yMax()); } float getVerticalWidth() { return (-_verticalBearing.x() + _bb.xMax()); } float getVerticalHeight() { return (-_verticalBearing.y() + _verticalAdvance); } - + void setWidth(float width) { _width = width; } float getWidth() { return _width; } - + void setHeight(float height) { _height = height; } float getHeight() { return _height; } - + protected: - + virtual ~Glyph3D() {} unsigned int _glyphCode; @@ -255,21 +257,21 @@ public: osg::Vec2 _verticalBearing; float _verticalAdvance; - osg::BoundingBox _bb; + osg::BoundingBox _bb; // osg::Vec2 _advance; - + float _width; float _height; - - + + osg::ref_ptr _vertexArray; osg::ref_ptr _normalArray; - + osg::Geometry::PrimitiveSetList _frontPrimitiveSetList; osg::Geometry::PrimitiveSetList _wallPrimitiveSetList; osg::Geometry::PrimitiveSetList _backPrimitiveSetList; - - + + }; diff --git a/include/osgText/Text3D b/include/osgText/Text3D index ee43b8e62..cc9212f1d 100644 --- a/include/osgText/Text3D +++ b/include/osgText/Text3D @@ -1,13 +1,13 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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 + * 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ @@ -30,7 +30,7 @@ public: * PER_FACE : render all front face with the default StateSet * all wall face with the wall StateSet * all back face with the back StateSet (back face of the character, no the OpenGL back face) - * + * * PER_GLYPH : render all Charactere with the default StateSet */ enum RenderMode @@ -38,7 +38,7 @@ public: PER_FACE, PER_GLYPH }; - + Text3D(); Text3D(const Text3D& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); @@ -48,7 +48,7 @@ public: float getCharacterDepth() const { return _characterDepth; } /** Set the Charactere Depth of text. */ void setCharacterDepth(float characterDepth) { _characterDepth = characterDepth; computeGlyphRepresentation(); } - + /** Get the render mode used to render the text. */ RenderMode getRenderMode() const { return _renderMode; } /** Set the render mode used to render the text. */ @@ -57,10 +57,10 @@ public: // /** Get the wall StateSet */ // osg::StateSet * getWallStateSet() { return _wallStateSet.get(); } // /** Get or create the wall StateSet */ -// osg::StateSet * getOrCreateWallStateSet() -// { -// if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet; -// return _wallStateSet.get(); +// osg::StateSet * getOrCreateWallStateSet() +// { +// if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet; +// return _wallStateSet.get(); // } // /** Set the wall StateSet */ // void setWallStateSet(osg::StateSet * wallStateSet) { _wallStateSet = wallStateSet; } @@ -71,9 +71,9 @@ public: // osg::StateSet * getOrCreateBackStateSet() { if (_backStateSet.valid() == false) _backStateSet = new osg::StateSet; return _backStateSet.get(); } // /** Set the back StateSet */ // void setBackStateSet(osg::StateSet * backStateSet) { _backStateSet = backStateSet; } -// - - /** Set the Font to use to render the text. +// + + /** Set the Font to use to render the text. * setFont(0) sets the use of the default font.*/ inline void setFont(Font3D* font=0) { setFont(osg::ref_ptr(font)); }; @@ -86,12 +86,12 @@ public: * 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.*/ + /** Get the font. Return 0 if default is being used.*/ const Font3D* getFont() const { return _font.get(); } - - - + + + /** Draw the text.*/ virtual void drawImplementation(osg::RenderInfo& renderInfo) const; @@ -102,13 +102,13 @@ public: virtual bool supports(const osg::Drawable::ConstAttributeFunctor&) const { return false; } /** 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; + virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const; /** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/ virtual bool supports(const osg::PrimitiveFunctor&) const { return false; } /** 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; + virtual void accept(osg::PrimitiveFunctor& pf) const; /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ @@ -122,7 +122,7 @@ public: * 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 +// // make Font a friend to allow it set the _font to 0 if the font is // // forcefully unloaded. friend class Font3D; @@ -131,8 +131,8 @@ public: protected: - virtual ~Text3D() {} - + virtual ~Text3D() {} + void renderPerGlyph(osg::State & state) const; void renderPerFace(osg::State & state) const; @@ -140,28 +140,28 @@ protected: void computeGlyphRepresentation(); void computePositions(unsigned int contextID) const; - + // ** glyph and other information to render the glyph struct GlyphRenderInfo { GlyphRenderInfo(Font3D::Glyph3D * glyph, osg::Vec3 & pos) : _glyph(glyph), _position(pos) {} - + osg::ref_ptr _glyph; osg::Vec3 _position; }; - + typedef std::vector LineRenderInfo; - typedef std::vector TextRenderInfo; - + typedef std::vector TextRenderInfo; + TextRenderInfo _textRenderInfo; osg::ref_ptr _font; float _characterDepth; - + RenderMode _renderMode; - + osg::ref_ptr _wallStateSet; osg::ref_ptr _backStateSet; }; diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index a009b138f..8376e58ca 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -318,8 +318,9 @@ Registry::Registry() addFileExtensionAlias("cff", "freetype"); // OpenType addFileExtensionAlias("cef", "freetype"); // OpenType addFileExtensionAlias("fon", "freetype"); // Windows bitmap fonts - addFileExtensionAlias("fnt", "freetype"); // Windows bitmap fonts - + addFileExtensionAlias("fnt", "freetype"); // Windows bitmap fonts + addFileExtensionAlias("text3d", "freetype"); // use 3D Font instead of 2D Font + // wont't add type1 and type2 until resolve extension collision with Performer binary and ascii files. // addFileExtensionAlias("pfb", "freetype"); // type1 binary // addFileExtensionAlias("pfa", "freetype"); // type2 ascii diff --git a/src/osgPlugins/freetype/FreeTypeFont3D.cpp b/src/osgPlugins/freetype/FreeTypeFont3D.cpp index 6cba789ea..04414bc82 100644 --- a/src/osgPlugins/freetype/FreeTypeFont3D.cpp +++ b/src/osgPlugins/freetype/FreeTypeFont3D.cpp @@ -1,13 +1,13 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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 + * 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ @@ -20,13 +20,13 @@ #include -#include +#include #include #include #include -#include +#include #include FT_FREETYPE_H #include @@ -173,7 +173,7 @@ int conicTo( const FT_Vector* control,const FT_Vector* to, void* user ) int cubicTo( const FT_Vector* control1,const FT_Vector* control2,const FT_Vector* to, void* user ) { Char3DInfo* char3d = (Char3DInfo*)user; - char3d->cubicTo( + char3d->cubicTo( osg::Vec2(FT_NUM(control1->x),FT_NUM(control1->y)), osg::Vec2(FT_NUM(control2->x),FT_NUM(control2->y)), osg::Vec2(FT_NUM(to->x),FT_NUM(to->y)) ); @@ -220,7 +220,7 @@ void FreeTypeFont3D::init() return; } - FT_Set_Char_Size( _face, 64*64, 64*64, 600, 600); + FT_Set_Char_Size( _face, 64*64, 64*64, 600, 600); int glyphIndex = FT_Get_Char_Index( _face, 'M' ); _error = FT_Load_Glyph( _face, glyphIndex, FT_LOAD_DEFAULT ); @@ -290,7 +290,7 @@ FreeTypeFont3D::~FreeTypeFont3D() // remove myself from the local registry to ensure that // not dangling pointers remain freeTypeLibrary->removeFont3DImplmentation(this); - + // free the freetype font face itself FT_Done_Face(_face); _face = 0; @@ -308,12 +308,12 @@ FreeTypeFont3D::~FreeTypeFont3D() osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode) { - - + + // - // GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being - // returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct - // values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect. + // GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being + // returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct + // values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect. // Microsoft uses a private field for its symbol fonts // unsigned int charindex = charcode; @@ -336,7 +336,7 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode) osg::notify(osg::WARN) << "FreeTypeFont3D::getGlyph : not a vector font" << std::endl; return 0; } - + // ** init FreeType to describe the glyph Char3DInfo char3d; @@ -348,7 +348,7 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode) funcs.move_to = (FT_Outline_MoveToFunc)&moveTo; funcs.shift = 0; funcs.delta = 0; - + // ** record description FT_Error _error = FT_Outline_Decompose(&outline, &funcs, &char3d); if (_error) @@ -356,74 +356,74 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode) osg::notify(osg::WARN) << "FreeTypeFont3D::getGlyph : - outline decompose failed ..." << std::endl; return 0; } - + // ** create geometry for each part of the glyph osg::ref_ptr frontGeo(new osg::Geometry); frontGeo->setVertexArray(char3d.get()->getVertexArray()); frontGeo->setPrimitiveSetList(char3d.get()->getPrimitiveSetList()); - + osg::ref_ptr wallGeo(new osg::Geometry); wallGeo->setVertexArray(frontGeo->getVertexArray()); - + osg::ref_ptr backGeo(new osg::Geometry); backGeo->setVertexArray(frontGeo->getVertexArray()); - - - - // ** for conveniance. + + + + // ** for convenience. osg::Vec3Array * vertices = char3d._verts.get(); - - - - // ** duplicate the vertex for the back face + + + + // ** duplicate the vertex for the back face // ** with a depth equal to the font depth std::size_t len = vertices->size(); std::size_t dlen = len * 2; - + vertices->reserve(dlen); - + osg::Vec3Array::iterator begin = vertices->begin(); osg::Vec3Array::iterator it = vertices->begin(); - + for (std::size_t i = 0; i != len; ++i, ++it) vertices->push_back(*it); // std::copy(begin, begin + len, begin + len + 1); TOCHECK - - + + // ** and decal new vertices unsigned int depth = _facade->getFontDepth(); for (std::size_t i = len; i != dlen; ++i) { (*vertices)[i].z() -= depth; } - + osg::Vec3Array::iterator end; - + // ** create wall and back face from the front polygon - // ** then accumulate them in the apropriate geometry wallGeo and backGeo + // ** then accumulate them in the appropriate geometry wallGeo and backGeo for (std::size_t i=0; i < frontGeo->getNumPrimitiveSets(); ++i) { // ** get the front polygon osg::ref_ptr daFront(dynamic_cast(frontGeo->getPrimitiveSet(i))); unsigned int idx = daFront->getFirst(); unsigned int cnt = daFront->getCount(); - + // ** reverse vertices to draw the front face in the CCW std::reverse(begin + idx, begin + idx + cnt); - + // ** create the back polygon osg::ref_ptr daBack(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, idx + len, cnt)); backGeo->addPrimitiveSet(daBack.get()); - - + + // ** create the wall triangle strip - osg::ref_ptr deWall(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP)); + osg::ref_ptr deWall(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP)); wallGeo->addPrimitiveSet(deWall.get()); - + // ** link triangle strip deWall->push_back(idx + len); for (unsigned int j = 1; j < cnt; ++j) - { + { deWall->push_back(idx + cnt - j); deWall->push_back(idx + len + j); } @@ -439,7 +439,7 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode) ts.setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY); ts.retessellatePolygons(*frontGeo); } - + { osgUtil::Tessellator ts; ts.setWindingType(osgUtil::Tessellator::TESS_WINDING_POSITIVE); @@ -454,17 +454,18 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode) geode->addDrawable(wallGeo.get()); geode->accept(sm); } - - // ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list + + // ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list osgText::Font3D::Glyph3D * glyph3D = new osgText::Font3D::Glyph3D(charcode); glyph3D->setVertexArray(dynamic_cast(frontGeo->getVertexArray())); - + glyph3D->setNormalArray(dynamic_cast(wallGeo->getNormalArray())); + glyph3D->getFrontPrimitiveSetList() = frontGeo->getPrimitiveSetList(); glyph3D->getWallPrimitiveSetList() = wallGeo->getPrimitiveSetList(); glyph3D->getBackPrimitiveSetList() = backGeo->getPrimitiveSetList(); - + FT_Glyph_Metrics* metrics = &(_face->glyph->metrics); glyph3D->setHorizontalBearing(osg::Vec2((float)metrics->horiBearingX/64.0f,(float)(metrics->horiBearingY-metrics->height)/64.0f)); // bottom left. @@ -475,7 +476,7 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode) glyph3D->setWidth((float)metrics->width / 64.0f); glyph3D->setHeight((float)metrics->height / 64.0f); - + FT_BBox ftbb; FT_Outline_Get_BBox(&outline, &ftbb); @@ -483,11 +484,11 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode) long xmax = ft_ceiling( ftbb.xMax ); long ymin = ft_floor( ftbb.yMin ); long ymax = ft_ceiling( ftbb.yMax ); - + osg::BoundingBox bb(xmin / 64.0f, ymin / 64.0f, 0.0f, xmax / 64.0f, ymax / 64.0f, 0.0f); - + glyph3D->setBoundingBox(bb); - + return glyph3D; } @@ -500,8 +501,8 @@ osg::Vec2 FreeTypeFont3D::getKerning(unsigned int leftcharcode,unsigned int righ // convert character code to glyph index FT_UInt left = FT_Get_Char_Index( _face, leftcharcode ); FT_UInt right = FT_Get_Char_Index( _face, rightcharcode ); - - // get the kerning distances. + + // get the kerning distances. FT_Vector kerning; FT_Error error = FT_Get_Kerning( _face, // handle to face object @@ -524,7 +525,7 @@ bool FreeTypeFont3D::hasVertical() const return FT_HAS_VERTICAL(_face)!=0; } -float FreeTypeFont3D::getScale() const -{ - return _scale; +float FreeTypeFont3D::getScale() const +{ + return _scale; } diff --git a/src/osgPlugins/freetype/ReaderWriterFreeType.cpp b/src/osgPlugins/freetype/ReaderWriterFreeType.cpp index f64a1e7f6..6579c407f 100644 --- a/src/osgPlugins/freetype/ReaderWriterFreeType.cpp +++ b/src/osgPlugins/freetype/ReaderWriterFreeType.cpp @@ -17,14 +17,15 @@ class ReaderWriterFreeType : public osgDB::ReaderWriter supportsExtension("cid","Postscript CID-Fonts format"); supportsExtension("cff","OpenType format"); supportsExtension("cef","OpenType format"); - supportsExtension("fon","Windows bitmap fonts format"); + supportsExtension("fon","Windows bitmap fonts format"); supportsExtension("fnt","Windows bitmap fonts format"); + supportsExtension("text3d","use 3D Font instead of 2D Font"); supportsOption("monochrome","Select monochrome font."); } - + virtual const char* className() const { return "FreeType Font Reader/Writer"; } - + static unsigned int getFlags(const osgDB::ReaderWriter::Options* options) { unsigned int flags = 0; @@ -32,26 +33,40 @@ class ReaderWriterFreeType : public osgDB::ReaderWriter { flags |= FT_LOAD_MONOCHROME; } - + return flags; } virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const { - std::string ext = osgDB::getLowerCaseFileExtension(file); + std::string tmpFile = file; + bool needFont3D = false; + + std::string ext = osgDB::getLowerCaseFileExtension(tmpFile); + if (ext == "text3d") + { + needFont3D = true; + tmpFile.erase(tmpFile.size()-7, 7); + ext = osgDB::getLowerCaseFileExtension(tmpFile); + } + else if ((options != NULL) && (options->getPluginData("3D"))) + { + needFont3D = true; + } + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; - std::string fileName = osgDB::findDataFile( file, options ); + std::string fileName = osgDB::findDataFile( tmpFile, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; - + FreeTypeLibrary* freeTypeLibrary = FreeTypeLibrary::instance(); - if (!freeTypeLibrary) + if (!freeTypeLibrary) { osg::notify(osg::WARN)<<"Warning:: cannot create freetype font after freetype library has been deleted."<getPluginData("3D")) ) + if (needFont3D) return freeTypeLibrary->getFont3D(fileName,0,getFlags(options)); else return freeTypeLibrary->getFont(fileName,0,getFlags(options)); @@ -60,7 +75,7 @@ class ReaderWriterFreeType : public osgDB::ReaderWriter virtual ReadResult readObject(std::istream& stream, const osgDB::ReaderWriter::Options* options) const { FreeTypeLibrary* freeTypeLibrary = FreeTypeLibrary::instance(); - if (!freeTypeLibrary) + if (!freeTypeLibrary) { osg::notify(osg::WARN)<<"Warning:: cannot create freetype font after freetype library has been deleted."< lock(s_Font3DFileMutex); osg::ref_ptr localOptions; @@ -104,16 +117,10 @@ osgText::Font3D* readFont3DFile(const std::string& filename, const osgDB::Reader { localOptions = new osgDB::ReaderWriter::Options; localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS); - // ** HACK to load Font3D instead of Font - localOptions->setPluginData("3D", (void*) 1); - } - else - { - userOptions->setPluginData("3D", (void*) 1); } osg::Object* object = osgDB::readObjectFile(foundFile, userOptions ? userOptions : localOptions.get()); - + // if the object is a font then return it. osgText::Font3D* font3D = dynamic_cast(object); if (font3D) return font3D; @@ -142,7 +149,7 @@ osgText::Font3D* readFont3DStream(std::istream& stream, const osgDB::ReaderWrite // there should be a better way to get the FreeType ReaderWriter by name... osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension("ttf"); if (reader == 0) return 0; - + osgDB::ReaderWriter::ReadResult rr = reader->readObject(stream, userOptions ? userOptions : localOptions.get()); if (rr.error()) { @@ -150,7 +157,7 @@ osgText::Font3D* readFont3DStream(std::istream& stream, const osgDB::ReaderWrite return 0; } if (!rr.validObject()) return 0; - + osg::Object *object = rr.takeObject(); // if the object is a font then return it. @@ -166,9 +173,19 @@ osg::ref_ptr readRefFont3DFile(const std::string& filename, const osgDB: { if (filename=="") return 0; - std::string foundFile = findFont3DFile(filename); + std::string tmpFilename; + std::string text3dExt = ".text3d"; + std::string ext = osgDB::getFileExtensionIncludingDot(filename); + if (ext == text3dExt) + tmpFilename = filename.substr(0, filename.size() - ext.size()); + else + tmpFilename = filename; + + std::string foundFile = findFont3DFile(tmpFilename); if (foundFile.empty()) return 0; - + + foundFile += text3dExt; + OpenThreads::ScopedLock lock(s_Font3DFileMutex); osg::ref_ptr localOptions; @@ -176,16 +193,10 @@ osg::ref_ptr readRefFont3DFile(const std::string& filename, const osgDB: { localOptions = new osgDB::ReaderWriter::Options; localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS); - // ** HACK to load Font3D instead of Font - localOptions->setPluginData("3D", (void*) 1); - } - else - { - userOptions->setPluginData("3D", (void*) 1); } osg::ref_ptr object = osgDB::readRefObjectFile(foundFile, userOptions ? userOptions : localOptions.get()); - + // if the object is a font then return it. osgText::Font3D* font3D = dynamic_cast(object.get()); if (font3D) return osg::ref_ptr(font3D); @@ -212,7 +223,7 @@ osg::ref_ptr readRefFont3DStream(std::istream& stream, const osgDB::Read // there should be a better way to get the FreeType ReaderWriter by name... osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension("ttf"); if (reader == 0) return 0; - + osgDB::ReaderWriter::ReadResult rr = reader->readObject(stream, userOptions ? userOptions : localOptions.get()); if (rr.error()) { @@ -267,24 +278,24 @@ std::string Font3D::getFileName() const Font3D::Glyph3D* Font3D::getGlyph(unsigned int charcode) { - Glyph3D * glyph3D = NULL; - + Glyph3D * glyph3D = NULL; + Glyph3DMap::iterator itr = _glyph3DMap.find(charcode); if (itr!=_glyph3DMap.end()) glyph3D = itr->second.get(); - + else if (_implementation.valid()) { glyph3D = _implementation->getGlyph(charcode); if (glyph3D) _glyph3DMap[charcode] = glyph3D; } - + return glyph3D; } void Font3D::setThreadSafeRefUnref(bool threadSafe) { Glyph3DMap::iterator it,end = _glyph3DMap.end(); - + for (it=_glyph3DMap.begin(); it!=end; ++it) it->second->setThreadSafeRefUnref(threadSafe); } diff --git a/src/osgText/Text3D.cpp b/src/osgText/Text3D.cpp index 521d82d2a..fc126ec0e 100644 --- a/src/osgText/Text3D.cpp +++ b/src/osgText/Text3D.cpp @@ -1,19 +1,19 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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 + * 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include #include -namespace osgText +namespace osgText { Text3D::Text3D(): @@ -32,25 +32,66 @@ Text3D::Text3D(const Text3D & text3D, const osg::CopyOp & copyop): computeGlyphRepresentation(); } -//void Text3D::accept(osg::Drawable::ConstAttributeFunctor& af) const -//{ -// TODO -//} +void Text3D::accept(osg::Drawable::ConstAttributeFunctor& af) const +{ + // ** for each line, do ... + TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); + for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) + { + // ** for each glyph in the line, do ... + LineRenderInfo::const_iterator it, end = itLine->end(); + for (it = itLine->begin(); it!=end; ++it) + { + // ** apply the vertex array + af.apply(osg::Drawable::VERTICES, it->_glyph->getVertexArray()->size(), &(it->_glyph->getVertexArray()->front())); + } + } +} +void Text3D::accept(osg::PrimitiveFunctor& pf) const +{ + // ** for each line, do ... + TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); + for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) + { + // ** for each glyph in the line, do ... + LineRenderInfo::const_iterator it, end = itLine->end(); + for (it = itLine->begin(); it!=end; ++it) + { + pf.setVertexArray(it->_glyph->getVertexArray()->size(),&(it->_glyph->getVertexArray()->front())); -//void Text3D::accept(osg::PrimitiveFunctor& /*pf*/) const -//{ -// TODO -//} + // ** render the front face of the glyph + osg::Geometry::PrimitiveSetList & pslFront = it->_glyph->getFrontPrimitiveSetList(); + for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr) + { + (*itr)->accept(pf); + } + + // ** render the wall face of the glyph + osg::Geometry::PrimitiveSetList & pslWall = it->_glyph->getWallPrimitiveSetList(); + for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslWall.begin(), end=pslWall.end(); itr!=end; ++itr) + { + (*itr)->accept(pf); + } + + // ** render the back face of the glyph + osg::Geometry::PrimitiveSetList & pslBack = it->_glyph->getBackPrimitiveSetList(); + for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr) + { + (*itr)->accept(pf); + } + } + } +} void Text3D::setFont(osg::ref_ptr font) -{ +{ _font = font; - + computeGlyphRepresentation(); } void Text3D::setFont(const std::string & fontfile) -{ +{ setFont(readRefFont3DFile(fontfile)); } @@ -75,11 +116,11 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i float maximumHeight = _maximumHeight / _font->getScale(); float maximumWidth = _maximumWidth / _font->getScale(); - + for(bool outOfSpace=false;lastChar!=last;++lastChar) { unsigned int charcode = *lastChar; - + if (charcode=='\n') { return lastChar; @@ -89,16 +130,16 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i if (glyph) { const osg::BoundingBox & bb = glyph->getBoundingBox(); - + // adjust cursor position w.r.t any kerning. if (previous_charcode) { - + if (_layout == RIGHT_TO_LEFT) { cursor.x() -= glyph->getHorizontalAdvance(); } - + if (kerning) { switch (_layout) @@ -119,7 +160,7 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i } } else - { + { switch (_layout) { case LEFT_TO_RIGHT: @@ -135,10 +176,10 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i case VERTICAL: break; } - + } - - + + switch(_layout) { @@ -158,7 +199,7 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i if (maximumHeight>0.0f && cursor.y()<-maximumHeight) outOfSpace=true; break; } - + // => word boundary detection & wrapping if (outOfSpace) break; @@ -175,17 +216,17 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i } } - + // word boundary detection & wrapping if (lastChar!=last) { - if (deliminatorSet.count(*lastChar)==0) + if (deliminatorSet.count(*lastChar)==0) { String::iterator lastValidChar = lastChar; while (lastValidChar!=first && deliminatorSet.count(*lastValidChar)==0) { --lastValidChar; - + //Substract off glyphs from the cursor position (to correctly center text) Font3D::Glyph3D* glyph = _font->getGlyph(*lastValidChar); if (glyph) @@ -198,7 +239,7 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i } } } - + if (first!=lastValidChar) { ++lastValidChar; @@ -213,17 +254,17 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i void Text3D::computeGlyphRepresentation() { if (_font.valid() == false) return; - + _textRenderInfo.clear(); _lineCount = 0; - - if (_text.empty()) + + if (_text.empty()) { _textBB.set(0,0,0, 0,0,0);//no size text TextBase::computePositions(); //to reset the origin return; } - + // initialize bounding box, it will be expanded during glyph position calculation _textBB.init(); @@ -231,31 +272,31 @@ void Text3D::computeGlyphRepresentation() osg::Vec2 cursor(startOfLine_coords); osg::Vec2 local(0.0f,0.0f); osg::Vec2 startOffset(0.0f,0.0f); - + unsigned int previous_charcode = 0; unsigned int linelength = 0; bool kerning = true; - + unsigned int lineNumber = 0; - + for(String::iterator itr=_text.begin(); itr!=_text.end(); ) { _textRenderInfo.resize(lineNumber + 1); LineRenderInfo & currentLineRenderInfo = _textRenderInfo.back(); - + // record the start of the current line String::iterator startOfLine_itr = itr; // find the end of the current line. osg::Vec2 endOfLine_coords(cursor); String::iterator endOfLine_itr = computeLastCharacterOnLine(endOfLine_coords, itr,_text.end()); - - // ** position the cursor function to the Layout and the alignement + + // ** position the cursor function to the Layout and the alignement TextBase::positionCursor(endOfLine_coords, cursor, (unsigned int) (endOfLine_itr - startOfLine_itr)); - + if (itr!=endOfLine_itr) { for(;itr!=endOfLine_itr;++itr) @@ -266,7 +307,7 @@ void Text3D::computeGlyphRepresentation() if (glyph) { const osg::BoundingBox & bb = glyph->getBoundingBox(); - + // adjust cursor position w.r.t any kerning. if (previous_charcode) { @@ -274,7 +315,7 @@ void Text3D::computeGlyphRepresentation() { cursor.x() -= glyph->getHorizontalAdvance(); } - + if (kerning) { switch (_layout) @@ -295,7 +336,7 @@ void Text3D::computeGlyphRepresentation() } } else - { + { switch (_layout) { case LEFT_TO_RIGHT: @@ -314,19 +355,19 @@ void Text3D::computeGlyphRepresentation() break; } } - + } local = cursor; - + if (_layout==VERTICAL) { local.x() += -glyph->getVerticalBearing().x(); local.y() += -glyph->getVerticalBearing().y(); } - - - + + + // move the cursor onto the next character. // also expand bounding box switch (_layout) @@ -344,14 +385,14 @@ void Text3D::computeGlyphRepresentation() case RIGHT_TO_LEFT: _textBB.expandBy(osg::Vec3(cursor.x()+bb.xMax(), cursor.y() + bb.yMax(), 0.0f)); //upper right corner _textBB.expandBy(osg::Vec3(cursor.x()+bb.xMin(), cursor.y()+bb.yMin(), 0.0f)); //lower left corner - + break; } - + osg::Vec3 pos = osg::Vec3(local.x(), local.y(), 0.0f); currentLineRenderInfo.push_back(Text3D::GlyphRenderInfo(glyph, pos)); - + previous_charcode = charcode; } } @@ -360,13 +401,13 @@ void Text3D::computeGlyphRepresentation() { ++itr; } - + if (itr!=_text.end()) { // skip over return. if (*itr=='\n') ++itr; } - + // move to new line. switch(_layout) { @@ -394,12 +435,10 @@ void Text3D::computeGlyphRepresentation() ++lineNumber; } _textBB.expandBy(0.0f,0.0f,-1); - + TextBase::computePositions(); } - - osg::BoundingBox Text3D::computeBound() const { osg::BoundingBox bbox; @@ -410,25 +449,17 @@ osg::BoundingBox Text3D::computeBound() const { osg::Matrix& matrix = _autoTransformCache[i]._matrix; bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*matrix); -// bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*matrix); bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMax())*matrix); -// bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*matrix); } } - + return bbox; } - - - - - - void Text3D::computePositions(unsigned int contextID) const { if (_font.valid() == false) return; - + switch(_alignment) { case LEFT_TOP: _offset.set(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()); break; @@ -446,16 +477,16 @@ void Text3D::computePositions(unsigned int contextID) const case LEFT_BASE_LINE: _offset.set(0.0f,0.0f,0.0f); break; case CENTER_BASE_LINE: _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,0.0f,0.0f); break; case RIGHT_BASE_LINE: _offset.set(_textBB.xMax(),0.0f,0.0f); break; - + case LEFT_BOTTOM_BASE_LINE: _offset.set(0.0f,-_characterHeight*(_lineCount-1),0.0f); break; case CENTER_BOTTOM_BASE_LINE: _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,-_characterHeight*(_lineCount-1),0.0f); break; case RIGHT_BOTTOM_BASE_LINE: _offset.set(_textBB.xMax(),-_characterHeight*(_lineCount-1),0.0f); break; } - + AutoTransformCache& atc = _autoTransformCache[contextID]; osg::Matrix& matrix = atc._matrix; - + float scale = _font->getScale(); osg::Vec3 scaleVec(scale * _characterHeight, scale * _characterHeight / _characterAspectRatio, _characterDepth); matrix.makeTranslate(-_offset); @@ -463,19 +494,19 @@ void Text3D::computePositions(unsigned int contextID) const matrix.postMultRotate(_rotation); matrix.postMultTranslate(_position); - + _normal = osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix); _normal.normalize(); - const_cast(this)->dirtyBound(); + const_cast(this)->dirtyBound(); } void Text3D::drawImplementation(osg::RenderInfo& renderInfo) const { osg::State & state = *renderInfo.getState(); unsigned int contextID = state.getContextID(); - - + + // ** save the previous modelview matrix osg::ref_ptr previous(new osg::RefMatrix(state.getModelViewMatrix())); @@ -484,25 +515,25 @@ void Text3D::drawImplementation(osg::RenderInfo& renderInfo) const // ** mult previous by the modelview for this context modelview->postMult(*previous.get()); - + // ** apply this new modelview matrix state.applyModelViewMatrix(modelview.get()); - - + + if (_drawMode & TEXT) { renderInfo.getState()->disableAllVertexArrays(); - + glPushAttrib(GL_TRANSFORM_BIT); glEnable(GL_RESCALE_NORMAL); - + switch(_renderMode) { case PER_FACE: renderPerFace(*renderInfo.getState()); break; case PER_GLYPH: default: renderPerGlyph(*renderInfo.getState()); break; } - + glPopAttrib(); } @@ -514,41 +545,41 @@ void Text3D::drawImplementation(osg::RenderInfo& renderInfo) const osg::Vec3 c100(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMax())); osg::Vec3 c110(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMax())); osg::Vec3 c010(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMax())); - + osg::Vec3 c001(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())); osg::Vec3 c101(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())); osg::Vec3 c111(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())); osg::Vec3 c011(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())); - + glBegin(GL_LINE_LOOP); glVertex3fv(c000.ptr()); glVertex3fv(c100.ptr()); glVertex3fv(c110.ptr()); glVertex3fv(c010.ptr()); glEnd(); - + glBegin(GL_LINE_LOOP); glVertex3fv(c001.ptr()); glVertex3fv(c011.ptr()); glVertex3fv(c111.ptr()); glVertex3fv(c101.ptr()); glEnd(); - + glBegin(GL_LINES); glVertex3fv(c000.ptr()); glVertex3fv(c001.ptr()); - + glVertex3fv(c100.ptr()); glVertex3fv(c101.ptr()); - + glVertex3fv(c110.ptr()); glVertex3fv(c111.ptr()); - + glVertex3fv(c010.ptr()); glVertex3fv(c011.ptr()); glEnd(); } - } + } if (_drawMode & ALIGNMENT) { @@ -565,17 +596,15 @@ void Text3D::drawImplementation(osg::RenderInfo& renderInfo) const glVertex3fv(vt.ptr()); glVertex3fv(vb.ptr()); glEnd(); - + } // restore the previous modelview matrix state.applyModelViewMatrix(previous.get()); } - - void Text3D::renderPerGlyph(osg::State & state) const -{ +{ // ** for each line, do ... TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) @@ -584,24 +613,23 @@ void Text3D::renderPerGlyph(osg::State & state) const LineRenderInfo::const_iterator it, end = itLine->end(); for (it = itLine->begin(); it!=end; ++it) { - + glPushMatrix(); glTranslatef(it->_position.x(), it->_position.y(), it->_position.z()); - + // ** apply the vertex array state.setVertexPointer(it->_glyph->getVertexArray()); - + // ** render the front face of the glyph glNormal3f(0.0f,0.0f,1.0f); - + osg::Geometry::PrimitiveSetList & pslFront = it->_glyph->getFrontPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr) { - (*itr)->draw(state, false); } - + // ** render the wall face of the glyph state.setNormalPointer(it->_glyph->getNormalArray()); osg::Geometry::PrimitiveSetList & pslWall = it->_glyph->getWallPrimitiveSetList(); @@ -609,16 +637,17 @@ void Text3D::renderPerGlyph(osg::State & state) const { (*itr)->draw(state, false); } - + state.disableNormalPointer(); + // ** render the back face of the glyph glNormal3f(0.0f,0.0f,-1.0f); - + osg::Geometry::PrimitiveSetList & pslBack = it->_glyph->getBackPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr) { (*itr)->draw(state, false); } - + glPopMatrix(); } } @@ -628,18 +657,18 @@ void Text3D::renderPerFace(osg::State & state) const { // ** render all front faces glNormal3f(0.0f,0.0f,1.0f); - + TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) { // ** for each glyph in the line, do ... LineRenderInfo::const_iterator it, end = itLine->end(); - for (it = itLine->begin(); it!=end; ++it) + for (it = itLine->begin(); it!=end; ++it) { glPushMatrix(); glTranslatef(it->_position.x(), it->_position.y(), it->_position.z()); state.setVertexPointer(it->_glyph->getVertexArray()); - + // ** render the front face of the glyph osg::Geometry::PrimitiveSetList & psl = it->_glyph->getFrontPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr) @@ -649,7 +678,7 @@ void Text3D::renderPerFace(osg::State & state) const glPopMatrix(); } } - + // ** render all wall face of the text for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) @@ -662,7 +691,7 @@ void Text3D::renderPerFace(osg::State & state) const glTranslatef(it->_position.x(), it->_position.y(), it->_position.z()); state.setVertexPointer(it->_glyph->getVertexArray()); state.setNormalPointer(it->_glyph->getNormalArray()); - + osg::Geometry::PrimitiveSetList & psl = it->_glyph->getWallPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr) { @@ -672,10 +701,10 @@ void Text3D::renderPerFace(osg::State & state) const } } - + // ** render all back face of the text glNormal3f(0.0f,0.0f,-1.0f); - + for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) { // ** for each glyph in the line, do ... @@ -685,7 +714,7 @@ void Text3D::renderPerFace(osg::State & state) const glPushMatrix(); glTranslatef(it->_position.x(), it->_position.y(), it->_position.z()); state.setVertexPointer(it->_glyph->getVertexArray()); - + // ** render the back face of the glyph osg::Geometry::PrimitiveSetList & psl = it->_glyph->getBackPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr) @@ -709,14 +738,14 @@ void Text3D::setThreadSafeRefUnref(bool threadSafe) void Text3D::resizeGLObjectBuffers(unsigned int maxSize) { TextBase::resizeGLObjectBuffers(maxSize); - + if (_font.valid()) _font->resizeGLObjectBuffers(maxSize); } void Text3D::releaseGLObjects(osg::State* state) const { TextBase::releaseGLObjects(state); - + if (_font.valid()) _font->releaseGLObjects(state); }