/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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. */ #include "TextNode.h" #include "../../src/osgText/GlyphGeometry.h" #include #include #include #include using namespace osgText; ///////////////////////////////////////////////////////////////////////////////////////// // // Layout // Layout::Layout() { } Layout::Layout(const Layout& layout, const osg::CopyOp& copyop): osg::Object(layout,copyop) { } osg::ref_ptr& Layout::getDefaultLayout() { static OpenThreads::Mutex s_DefaultLayoutMutex; OpenThreads::ScopedLock lock(s_DefaultLayoutMutex); static osg::ref_ptr s_defaultLayout = new Layout; return s_defaultLayout; } void Layout::layout(TextNode& text) const { OSG_NOTICE<<"Layout::layout"<(static_cast(resolution.first)*style->getSampleDensity()); resolution.second = static_cast(static_cast(resolution.second)*style->getSampleDensity()); } float characterWidthScale = 1.0f; bool textIs3D = (style && style->getThicknessRatio()!=0.0); if (!textIs3D) { characterWidthScale = 1.0f/static_cast(resolution.first); } osgText::KerningType kerningType = osgText::KERNING_DEFAULT; technique->start(); unsigned int previousCharcode = 0; for(unsigned int i=0; igetGlyph(resolution, charcode); if (glyph) { technique->addCharacter(pos, size, glyph, style); pos += osg::Vec3(size.x()*(glyph->getHorizontalAdvance()*characterWidthScale), 0.0f ,0.0f); } } else { osgText::Glyph3D* glyph = font->getGlyph3D(charcode); OSG_NOTICE<<"pos = "< transform = new osg::PositionAttitudeTransform; transform->setPosition(position); transform->setAttitude(osg::Quat(osg::inDegrees(90.0),osg::Vec3d(1.0,0.0,0.0))); transform->setScale(size); osg::ref_ptr geode = new osg::Geode; const Bevel* bevel = style ? style->getBevel() : 0; bool outline = style ? style->getOutlineRatio()>0.0f : false; float width = style->getThicknessRatio(); float creaseAngle = 30.0f; bool smooth = true; if (bevel) { osg::ref_ptr glyphGeometry = osgText::computeGlyphGeometry(glyph, *bevel, width); osg::ref_ptr textGeometry = osgText::computeTextGeometry(glyphGeometry.get(), *bevel, width); osg::ref_ptr shellGeometry = outline ? osgText::computeShellGeometry(glyphGeometry.get(), *bevel, width) : 0; if (textGeometry.valid()) geode->addDrawable(textGeometry.get()); if (shellGeometry.valid()) geode->addDrawable(shellGeometry.get()); // create the normals if (smooth && textGeometry.valid()) { osgUtil::SmoothingVisitor::smooth(*textGeometry, osg::DegreesToRadians(creaseAngle)); } } else { osg::ref_ptr textGeometry = osgText::computeTextGeometry(glyph, width); if (textGeometry.valid()) geode->addDrawable(textGeometry.get()); // create the normals if (smooth && textGeometry.valid()) { osgUtil::SmoothingVisitor::smooth(*textGeometry, osg::DegreesToRadians(creaseAngle)); } } transform->addChild(geode.get()); _textNode->addChild(transform.get()); transform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); } void TextTechnique::finish() { OSG_NOTICE<<"TextTechnique::finish()"<osg::Group::traverse(nv); } ///////////////////////////////////////////////////////////////////////////////////////// // // TextNode // TextNode::TextNode(): _characterSize(1.0f) { } TextNode::TextNode(const TextNode& text, const osg::CopyOp& copyop): osg::Group(text, copyop) { } TextNode::~TextNode() { setTextTechnique(0); } void TextNode::traverse(osg::NodeVisitor& nv) { if (_technique.valid()) { _technique->traverse(nv); } else { Group::traverse(nv); } } void TextNode::setTextTechnique(TextTechnique* technique) { if (_technique==technique) return; if (_technique.valid()) _technique->setTextNode(0); if (TextTechnique::getDefaultTextTechinque()==technique) { OSG_NOTICE<<"Warning: Attempt to assign DefaultTextTechnique() prototype to TextNode::setTextTechnique(..), assigning a clone() of it instead."<setTextNode(this); } void TextNode::update() { getActiveLayout()->layout(*this); } void TextNode::setText(const std::string& str) { _string.set(str); }