root/OpenSceneGraph/trunk/include/osgText/Font3D @ 7874

Revision 7874, 10.7 kB (checked in by robert, 6 years ago)

Refactored the mutex usage in osgText and freetype plugin to prevent multi-thread crash

Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSGTEXT_FONT3D
15#define OSGTEXT_FONT3D 1
16
17#include <string>
18#include <istream>
19
20#include <osg/Vec2>
21#include <osg/Geometry>
22#include <osgDB/ReaderWriter>
23#include <osgText/Export>
24#include <osgText/KerningType>
25
26#include <OpenThreads/Mutex>
27
28namespace osgText {
29
30class Font3D;
31class Text3D;
32
33/** Read a font from specified file. The filename may contain a path.
34  * It will search for the font file in the following places in this order:
35  * - In the current directory
36  * - All paths defined in OSG_FILE_PATH or OSGFILEPATH environment variable
37  * - Filename with path stripped: In the current directory
38  * - Filename with path stripped: All paths defined in OSG_FILE_PATH or OSGFILEPATH
39  *
40  * Then the file will be searched in OS specific directories in the following order:
41  * - Again in the current directory
42  * - Windows: In C:/winnt/fonts
43  * - Windows: In C:/windows/fonts
44  * - Windows: In the fonts directory of the windows install directory
45  * - Other OS: In /usr/share/fonts/ttf
46  * - Other OS: In /usr/share/fonts/ttf/western
47  * - Other OS: In /usr/share/fonts/ttf/decoratives
48  *
49  * If the given file could not be found, the path part will be stripped and
50  * the file will be searched again in the OS specific directories.
51  */
52extern OSGTEXT_EXPORT Font3D* readFont3DFile(const std::string& filename, const osgDB::ReaderWriter::Options* userOptions = 0);
53
54/** read a font from specified stream.*/
55extern OSGTEXT_EXPORT Font3D* readFont3DStream(std::istream& stream, const osgDB::ReaderWriter::Options* userOptions = 0);
56
57extern OSGTEXT_EXPORT osg::ref_ptr<Font3D> readRefFont3DFile(const std::string& filename, const osgDB::ReaderWriter::Options* userOptions = 0);
58
59extern OSGTEXT_EXPORT osg::ref_ptr<Font3D> readRefFont3DStream(std::istream& stream, const osgDB::ReaderWriter::Options* userOptions = 0);
60
61extern OSGTEXT_EXPORT std::string findFont3DFile(const std::string& str);
62
63/** Pure virtual base class for fonts.
64  * Concrete implementation are the DefaultFont found in src/osgText/DefaultFont.cpp
65  * and FreeTypeFont found in src/osgPlugins/freetype/FreeTypeFont.cpp*/
66class OSGTEXT_EXPORT Font3D : public osg::Object
67{
68// declare the interface to a font.
69public:
70   
71    // forward declare nested classes.
72    class Glyph3D;
73    class Font3DImplementation;
74
75public:
76    Font3D(Font3DImplementation* implementation=0);
77
78    virtual osg::Object* cloneType() const { return 0; } // cloneType() not appropriate
79    virtual osg::Object* clone(const osg::CopyOp&) const { return 0; } // clone() not appropriate
80    virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Font3D*>(obj)!=NULL; }
81    virtual const char* className() const { return "Font3D"; }
82    virtual const char* libraryName() const { return "osgText"; }
83
84    virtual std::string getFileName() const;
85
86    unsigned int getFontWidth() const { return _width; }
87    unsigned int getFontHeight() const { return _height; }
88    unsigned int getFontDepth() const { return _depth; }
89
90    /** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes, w.r.t the current font size hint.*/
91    virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType);
92
93    /** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/
94    virtual Glyph3D* getGlyph(unsigned int charcode);
95   
96    /** Return true if this font provides vertical alignments and spacing or glyphs.*/
97    virtual bool hasVertical() const;
98
99    /** Return the scale to apply on the glyph to have a charactere size equal to 1 */
100    virtual float getScale() const { return _implementation->getScale(); };
101   
102    // make Text a friend to allow it add and remove its entry in the Font's _textList.
103    friend class Font3DImplementation;
104
105    void setImplementation(Font3DImplementation* implementation);
106
107    Font3DImplementation* getImplementation();
108    const Font3DImplementation* getImplementation() const;
109
110    /** Set whether to use a mutex to ensure ref() and unref() */
111    virtual void setThreadSafeRefUnref(bool threadSafe);
112   
113    typedef OpenThreads::Mutex Font3DMutex;
114
115protected:
116
117    virtual ~Font3D();
118   
119//    void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph* glyph);
120    void addGlyph(unsigned int charcode, Glyph3D* glyph);
121   
122    // current active size of font
123    unsigned int                        _depth;
124    unsigned int                        _width;
125    unsigned int                        _height;
126//    unsigned int                    _margin;
127//    float                           _marginRatio;
128
129    typedef std::map<char, osg::ref_ptr<Glyph3D> > Glyph3DMap;
130    Glyph3DMap _glyph3DMap;
131   
132    osg::ref_ptr<Font3DImplementation> _implementation;
133
134   
135// declare the nested classes.
136public:
137
138    class Font3DImplementation : public osg::Referenced
139    {
140    public:
141   
142        Font3DImplementation():
143            osg::Referenced(true),
144            _facade(0) {}
145   
146        virtual std::string getFileName() const = 0;
147
148        /** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/
149        virtual Glyph3D* getGlyph(unsigned int charcode) = 0;
150
151        /** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes, w.r.t the current font size hint.*/
152        virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType) = 0;
153
154        /** Return true if this font provides vertical alignments and spacing or glyphs.*/
155        virtual bool hasVertical() const = 0;
156       
157        virtual float getScale() const = 0;
158 
159        void setFontWidth(unsigned int width) { _facade->_width = width; }
160
161        void setFontHeight(unsigned int height) { _facade->_height = height; }
162       
163        void setFontDepth(unsigned int depth) { _facade->_depth = depth; }
164       
165//        void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph3D* glyph)
166//        {
167//            _facade->addGlyph(width, height, charcode, glyph);
168//        }
169//       
170//        void addGlyph(unsigned int charcode, Glyph3D* glyph)
171//        {
172//            _facade->addGlyph(charcode, glyph);
173//        }
174
175        Font3D* _facade;
176    };
177
178    class OSGTEXT_EXPORT Glyph3D : public osg::Referenced
179    {
180    public:
181
182        Glyph3D(unsigned int glyphCode):
183            osg::Referenced(true),
184            _glyphCode(glyphCode),
185            _horizontalBearing(0,0),
186            _horizontalAdvance(0),
187            _verticalBearing(0,0),
188            _verticalAdvance(0)
189            {}
190       
191
192        /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
193//        virtual int compare(const osg::StateAttribute& rhs) const;
194//       
195//        virtual void apply(osg::State& state) const;
196
197       
198       
199        unsigned int getGlyphCode() const { return _glyphCode; }
200       
201        void setHorizontalBearing(const osg::Vec2& bearing) { _horizontalBearing=bearing; }
202        const osg::Vec2 & getHorizontalBearing() const { return _horizontalBearing; }
203       
204        void setHorizontalAdvance(float advance) { _horizontalAdvance=advance; }
205        float getHorizontalAdvance() const { return _horizontalAdvance; }
206
207        void setVerticalBearing(const osg::Vec2& bearing) {  _verticalBearing=bearing; }
208        const osg::Vec2& getVerticalBearing() const { return _verticalBearing; }
209
210        void setVerticalAdvance(float advance) { _verticalAdvance=advance; }
211        float getVerticalAdvance() const { return _verticalAdvance; }
212               
213        void setBoundingBox(osg::BoundingBox & bb) { _bb=bb; }
214        const osg::BoundingBox & getBoundingBox() const { return _bb; }
215       
216       
217        /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
218        virtual void setThreadSafeRefUnref(bool threadSafe);
219
220       
221        /** Get the PrimitiveSetList for the front face. */
222        osg::Geometry::PrimitiveSetList & getFrontPrimitiveSetList() { return _frontPrimitiveSetList; }
223        /** Get the PrimitiveSetList for the wall face. */
224        osg::Geometry::PrimitiveSetList & getWallPrimitiveSetList() { return _wallPrimitiveSetList; }
225        /** Get et the PrimitiveSetList for the back face. */
226        osg::Geometry::PrimitiveSetList & getBackPrimitiveSetList() { return _backPrimitiveSetList; }
227       
228        /** Set the VertexArray of the glyph. */
229        void setVertexArray(osg::Vec3Array * va) { _vertexArray = va; }
230        /** Get the VertexArray of the glyph. */
231        osg::Vec3Array * getVertexArray() { return _vertexArray.get(); }
232        /** Get the NormalArray for the wall face. */
233        osg::Vec3Array * getNormalArray() { return _normalArray.get(); }
234       
235        float getHorizontalWidth() { return (-_horizontalBearing.x() + _horizontalAdvance); }
236        float getHorizontalHeight() { return (-_horizontalBearing.y() + _bb.yMax()); }
237        float getVerticalWidth() { return (-_verticalBearing.x() + _bb.xMax()); }
238        float getVerticalHeight() { return (-_verticalBearing.y() + _verticalAdvance); }
239       
240        void setWidth(float width) { _width = width; }
241        float getWidth() { return _width; }
242       
243        void setHeight(float height) { _height = height; }
244        float getHeight() { return _height; }
245       
246    protected:
247   
248        virtual ~Glyph3D() {}
249
250        unsigned int                _glyphCode;
251
252        osg::Vec2                   _horizontalBearing;
253        float                       _horizontalAdvance;
254
255        osg::Vec2                   _verticalBearing;
256        float                       _verticalAdvance;
257
258        osg::BoundingBox            _bb;       
259//        osg::Vec2                   _advance;
260       
261        float _width;
262        float _height;
263       
264       
265        osg::ref_ptr<osg::Vec3Array> _vertexArray;
266        osg::ref_ptr<osg::Vec3Array> _normalArray;
267       
268        osg::Geometry::PrimitiveSetList _frontPrimitiveSetList;
269        osg::Geometry::PrimitiveSetList _wallPrimitiveSetList;
270        osg::Geometry::PrimitiveSetList _backPrimitiveSetList;
271       
272       
273    };
274
275
276};
277
278}
279
280
281#endif
Note: See TracBrowser for help on using the browser.