1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
|
/* -*-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
* (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_FONT3D
#define OSGTEXT_FONT3D 1
#include <string>
#include <istream>
#include <osg/Vec2>
#include <osg/Geometry>
#include <osgDB/ReaderWriter>
#include <osgText/Export>
#include <osgText/KerningType>
#include <OpenThreads/Mutex>
namespace osgText {
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:
* - In the current directory
* - All paths defined in OSG_FILE_PATH or OSGFILEPATH environment variable
* - Filename with path stripped: In the current directory
* - Filename with path stripped: All paths defined in OSG_FILE_PATH or OSGFILEPATH
*
* Then the file will be searched in OS specific directories in the following order:
* - Again in the current directory
* - Windows: In C:/winnt/fonts
* - Windows: In C:/windows/fonts
* - Windows: In the fonts directory of the windows install directory
* - 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.
*/
extern OSGTEXT_EXPORT Font3D* readFont3DFile(const std::string& filename, const osgDB::ReaderWriter::Options* userOptions = 0);
/** read a font from specified stream.*/
extern OSGTEXT_EXPORT Font3D* readFont3DStream(std::istream& stream, const osgDB::ReaderWriter::Options* userOptions = 0);
extern OSGTEXT_EXPORT osg::ref_ptr<Font3D> readRefFont3DFile(const std::string& filename, const osgDB::ReaderWriter::Options* userOptions = 0);
extern OSGTEXT_EXPORT osg::ref_ptr<Font3D> readRefFont3DStream(std::istream& stream, const osgDB::ReaderWriter::Options* userOptions = 0);
extern OSGTEXT_EXPORT std::string findFont3DFile(const std::string& str);
/** Pure virtual base class for fonts.
* Concrete implementation are the DefaultFont found in src/osgText/DefaultFont.cpp
* and FreeTypeFont found in src/osgPlugins/freetype/FreeTypeFont.cpp*/
class OSGTEXT_EXPORT Font3D : public osg::Object
{
// declare the interface to a font.
public:
// forward declare nested classes.
class Glyph3D;
class Font3DImplementation;
public:
Font3D(Font3DImplementation* implementation=0);
virtual osg::Object* cloneType() const { return 0; } // cloneType() not appropriate
virtual osg::Object* clone(const osg::CopyOp&) const { return 0; } // clone() not appropriate
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Font3D*>(obj)!=NULL; }
virtual const char* className() const { return "Font3D"; }
virtual const char* libraryName() const { return "osgText"; }
virtual std::string getFileName() const;
unsigned int getFontWidth() const { return _width; }
unsigned int getFontHeight() const { return _height; }
unsigned int getFontDepth() const { return _depth; }
/** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes, w.r.t the current font size hint.*/
virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType);
/** 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;
void setImplementation(Font3DImplementation* implementation);
Font3DImplementation* getImplementation();
const Font3DImplementation* getImplementation() const;
/** 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;
unsigned int _height;
// unsigned int _margin;
// float _marginRatio;
typedef std::map<char, osg::ref_ptr<Glyph3D> > Glyph3DMap;
Glyph3DMap _glyph3DMap;
osg::ref_ptr<Font3DImplementation> _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.*/
virtual Glyph3D* getGlyph(unsigned int charcode) = 0;
/** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes, w.r.t the current font size hint.*/
virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType) = 0;
/** 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);
// }
Font3D* _facade;
};
class OSGTEXT_EXPORT Glyph3D : public osg::Referenced
{
public:
Glyph3D(unsigned int glyphCode):
osg::Referenced(true),
_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; }
void setVerticalBearing(const osg::Vec2& bearing) { _verticalBearing=bearing; }
const osg::Vec2& getVerticalBearing() const { return _verticalBearing; }
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(); }
/** 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;
osg::Vec2 _horizontalBearing;
float _horizontalAdvance;
osg::Vec2 _verticalBearing;
float _verticalAdvance;
osg::BoundingBox _bb;
// osg::Vec2 _advance;
float _width;
float _height;
osg::ref_ptr<osg::Vec3Array> _vertexArray;
osg::ref_ptr<osg::Vec3Array> _normalArray;
osg::Geometry::PrimitiveSetList _frontPrimitiveSetList;
osg::Geometry::PrimitiveSetList _wallPrimitiveSetList;
osg::Geometry::PrimitiveSetList _backPrimitiveSetList;
};
};
}
#endif
|