root/OpenSceneGraph/trunk/src/osgPlugins/freetype/FreeTypeLibrary.cpp @ 10964

Revision 10964, 7.8 kB (checked in by robert, 4 years ago)

Restructure the includes of freetype

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
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#include "FreeTypeLibrary.h"
15#include <osg/Notify>
16//#include <ft2build.h>
17
18//#define PRINT_OUT_FONT_DETAILS
19#ifdef PRINT_OUT_FONT_DETAILS
20    #include <ftsnames.h>
21#endif
22
23#include FT_TRUETYPE_IDS_H
24
25FreeTypeLibrary::FreeTypeLibrary()
26{
27    osg::notify(osg::INFO) << "FreeTypeLibrary::FreeTypeLibrary()" << std::endl;
28    FT_Error error = FT_Init_FreeType( &_ftlibrary );
29    if (error)
30    {
31        osg::notify(osg::WARN)<<"Warning: an error occurred during FT_Init_FreeType(..) initialisation, error code = "<<std::hex<<error<<std::dec<<std::endl;
32    }
33
34}
35
36FreeTypeLibrary::~FreeTypeLibrary()
37{
38    // need to remove the implementations from the Fonts here
39    // just in case the Fonts continue to have external references
40    // to them, otherwise they will try to point to an object thats
41    // definition has been unloaded along with the unload of the FreeType
42    // plugin.
43    while(!_fontImplementationSet.empty())
44    {
45        FreeTypeFont* fontImplementation = *_fontImplementationSet.begin();
46        _fontImplementationSet.erase(_fontImplementationSet.begin());
47        osgText::Font* font = fontImplementation->_facade;
48        if (font) font->setImplementation(0);
49        else fontImplementation->_facade = 0;
50    }
51   
52    while(!_font3DImplementationSet.empty())
53    {
54        FreeTypeFont3D* font3DImplementation = *_font3DImplementationSet.begin();
55        _font3DImplementationSet.erase(_font3DImplementationSet.begin());
56        osgText::Font3D* font3D = font3DImplementation->_facade;
57        if (font3D) font3D->setImplementation(0);
58        else font3DImplementation->_facade = 0;
59    }
60   
61    FT_Done_FreeType( _ftlibrary);
62}
63
64FreeTypeLibrary* FreeTypeLibrary::instance()
65{
66    static osg::ref_ptr<FreeTypeLibrary> s_library = new FreeTypeLibrary;
67    return s_library.get();
68}
69
70bool FreeTypeLibrary::getFace(const std::string& fontfile,unsigned int index, FT_Face & face)
71{
72    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(getMutex());
73
74    FT_Error error = FT_New_Face( _ftlibrary, fontfile.c_str(), index, &face );
75    if (error == FT_Err_Unknown_File_Format)
76    {
77        osg::notify(osg::WARN)<<" .... the font file could be opened and read, but it appears"<<std::endl;
78        osg::notify(osg::WARN)<<" .... that its font format is unsupported"<<std::endl;
79        return false;
80    }
81    else if (error)
82    {
83        osg::notify(osg::WARN)<<" .... another error code means that the font file could not"<<std::endl;
84        osg::notify(osg::WARN)<<" .... be opened, read or simply that it is broken.."<<std::endl;
85        return false;
86    }
87   
88#ifdef PRINT_OUT_FONT_DETAILS
89
90    osg::notify(osg::NOTICE)<<"Face"<<face<<std::endl;
91    unsigned int count = FT_Get_Sfnt_Name_Count(face);
92    for(unsigned int i=0; i<count; ++i)
93    {
94        FT_SfntName names;
95        FT_Error error = FT_Get_Sfnt_Name(face, i, &names);
96       
97        std::string name((char*)names.string, (char*)names.string + names.string_len);
98       
99        osg::notify(osg::NOTICE)<<"names "<<name<<std::endl;
100    }
101
102    osg::notify(osg::NOTICE)<<std::endl;
103#endif
104
105    //
106    // GT: Fix to handle symbol fonts in MS Windows
107    //
108    verifyCharacterMap(face);
109   
110    return true;
111}
112
113FT_Byte* FreeTypeLibrary::getFace(std::istream& fontstream, unsigned int index, FT_Face & face)
114{
115    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(getMutex());
116
117    FT_Open_Args args;
118
119    std::streampos start = fontstream.tellg();
120    fontstream.seekg(0, std::ios::end);
121    std::streampos end = fontstream.tellg();
122    fontstream.seekg(start, std::ios::beg);
123    std::streampos length = end - start;
124
125    /* empty stream into memory, open that, and keep the pointer in a FreeTypeFont for cleanup */
126    FT_Byte *buffer = new FT_Byte[length];
127    fontstream.read(reinterpret_cast<char*>(buffer), length);
128    if (!fontstream || (static_cast<std::streampos>(fontstream.gcount()) != length))
129    {
130        osg::notify(osg::WARN)<<" .... the font file could not be read from its stream"<<std::endl;
131        return 0;
132    }
133    args.flags = FT_OPEN_MEMORY;
134    args.memory_base = buffer;
135    args.memory_size = length;
136
137    FT_Error error = FT_Open_Face( _ftlibrary, &args, index, &face );
138
139    if (error == FT_Err_Unknown_File_Format)
140    {
141        osg::notify(osg::WARN)<<" .... the font file could be opened and read, but it appears"<<std::endl;
142        osg::notify(osg::WARN)<<" .... that its font format is unsupported"<<std::endl;
143        return 0;
144    }
145    else if (error)
146    {
147        osg::notify(osg::WARN)<<" .... another error code means that the font file could not"<<std::endl;
148        osg::notify(osg::WARN)<<" .... be opened, read or simply that it is broken..."<<std::endl;
149        return 0;
150    }
151
152    //
153    // GT: Fix to handle symbol fonts in MS Windows
154    //
155    verifyCharacterMap(face);
156   
157    return buffer;
158}
159
160
161osgText::Font* FreeTypeLibrary::getFont(const std::string& fontfile, unsigned int index, unsigned int flags)
162{
163    FT_Face face;
164    if (getFace(fontfile, index, face) == false) return (0);
165
166    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(getMutex());
167   
168    FreeTypeFont* fontImp = new FreeTypeFont(fontfile,face,flags);
169    osgText::Font* font = new osgText::Font(fontImp);
170
171    _fontImplementationSet.insert(fontImp);
172   
173    return font;
174}
175osgText::Font* FreeTypeLibrary::getFont(std::istream& fontstream, unsigned int index, unsigned int flags)
176{
177    FT_Face face = 0;
178    FT_Byte * buffer = getFace(fontstream, index, face);
179    if (face == 0) return (0);
180
181   
182    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(getMutex());
183
184    FreeTypeFont* fontImp = new FreeTypeFont(buffer,face,flags);
185    osgText::Font* font = new osgText::Font(fontImp);
186   
187    _fontImplementationSet.insert(fontImp);
188
189    return font;
190}
191
192osgText::Font3D* FreeTypeLibrary::getFont3D(const std::string& fontfile, unsigned int index, unsigned int flags)
193{
194    FT_Face face;
195    if (getFace(fontfile, index, face) == false) return (0);
196
197    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(getMutex());
198   
199    FreeTypeFont3D* font3DImp = new FreeTypeFont3D(fontfile,face,flags);
200    osgText::Font3D* font3D = new osgText::Font3D(font3DImp);
201
202    _font3DImplementationSet.insert(font3DImp);
203   
204    return font3D;
205}
206osgText::Font3D* FreeTypeLibrary::getFont3D(std::istream& fontstream, unsigned int index, unsigned int flags)
207{
208
209    FT_Face face = 0;
210    FT_Byte * buffer = getFace(fontstream, index, face);
211    if (face == 0) return (0);
212   
213    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(getMutex());
214
215    FreeTypeFont3D* font3DImp = new FreeTypeFont3D(buffer,face,flags);
216    osgText::Font3D* font3D = new osgText::Font3D(font3DImp);
217   
218    _font3DImplementationSet.insert(font3DImp);
219
220    return font3D;
221}
222
223void FreeTypeLibrary::verifyCharacterMap(FT_Face face)
224{
225    //
226    // GT: Verify the correct character mapping for MS windows
227    // as symbol fonts were being returned incorrectly
228    //
229    FT_CharMap charmap;
230    if (face->charmap == NULL)
231    {
232        for (int n = 0; n < face->num_charmaps; n++)
233        {
234            charmap = face->charmaps[n];
235            if (charmap->platform_id == TT_PLATFORM_MICROSOFT)
236            {
237                FT_Set_Charmap(face, charmap);
238                break;
239            }
240        }
241    }
242}
Note: See TracBrowser for help on using the browser.