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

Revision 9881, 10.5 kB (checked in by robert, 6 years ago)

From David Callu, "Problem:

osgText::Text and osgText::Text3D use the same font file.
The first really load the file and obtain an osgText::Font object,
the second use the cache created during the first load of the
font file, and so obtain an osgText::Font object instead of
osgText::Font3D object. To obtain an osgText::Font3D object,
osgText::Text3D call osgDB::readObjectFile(...) with an option
to specify the plugin we want an osgText::Font3D instead of
osgText::Font.

Generalised Problem:

In osgDB::Registry, loaded file cache is referenced by the name
of this file, so if I load a file with some options, and the cache
already contain object for this filename, I obtain an object
potentially not loaded with my options.

Behaviours:

Cache management is delegate to osgDB::Registry, but cache
coherence (load a file with option then reuse it, deactivate the
cache when load a specific file or don't cached the loaded file)
is user's responsibility.

Text3D solution:

Postfix the font file name by .text3d or something similar and then have the freetype plugin return
osgText::Font3D when it detects this.
This operation is done by osgText::readFont3DFile() which unsure the filename have .text3d as extension.
This is totaly transparent for user, and backward compatible.

BTW, I fix the bug about the Normal of 3D text. Currently, the front and wall face have
the same normal (0,0,1) in the Text3D object coordinate. Now the wall face have its own
normal array computed by the plugin.

BTW 2, I implement
- void Text3D::accept(osg::Drawable::ConstAttributeFunctor?& af) const
- void Text3D::accept(osg::PrimitiveFunctor?& pf) const
so now statistics are well reported.
"

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        /** Set the VertexArray of the glyph. */
233        void setNormalArray(osg::Vec3Array * na) { _normalArray = na; }
234        /** Get the NormalArray for the wall face. */
235        osg::Vec3Array * getNormalArray() { return _normalArray.get(); }
236
237        float getHorizontalWidth() { return (-_horizontalBearing.x() + _horizontalAdvance); }
238        float getHorizontalHeight() { return (-_horizontalBearing.y() + _bb.yMax()); }
239        float getVerticalWidth() { return (-_verticalBearing.x() + _bb.xMax()); }
240        float getVerticalHeight() { return (-_verticalBearing.y() + _verticalAdvance); }
241
242        void setWidth(float width) { _width = width; }
243        float getWidth() { return _width; }
244
245        void setHeight(float height) { _height = height; }
246        float getHeight() { return _height; }
247
248    protected:
249
250        virtual ~Glyph3D() {}
251
252        unsigned int                _glyphCode;
253
254        osg::Vec2                   _horizontalBearing;
255        float                       _horizontalAdvance;
256
257        osg::Vec2                   _verticalBearing;
258        float                       _verticalAdvance;
259
260        osg::BoundingBox            _bb;
261//        osg::Vec2                   _advance;
262
263        float _width;
264        float _height;
265
266
267        osg::ref_ptr<osg::Vec3Array> _vertexArray;
268        osg::ref_ptr<osg::Vec3Array> _normalArray;
269
270        osg::Geometry::PrimitiveSetList _frontPrimitiveSetList;
271        osg::Geometry::PrimitiveSetList _wallPrimitiveSetList;
272        osg::Geometry::PrimitiveSetList _backPrimitiveSetList;
273
274
275    };
276
277
278};
279
280}
281
282
283#endif
Note: See TracBrowser for help on using the browser.