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

Revision 13041, 6.2 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • 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 <freetype/ftsnames.h>
21#endif
22
23#include FT_TRUETYPE_IDS_H
24
25FreeTypeLibrary::FreeTypeLibrary()
26{
27    OSG_INFO << "FreeTypeLibrary::FreeTypeLibrary()" << std::endl;
28    FT_Error error = FT_Init_FreeType( &_ftlibrary );
29    if (error)
30    {
31        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    FT_Done_FreeType( _ftlibrary);
53}
54
55FreeTypeLibrary* FreeTypeLibrary::instance()
56{
57    static osg::ref_ptr<FreeTypeLibrary> s_library = new FreeTypeLibrary;
58    return s_library.get();
59}
60
61bool FreeTypeLibrary::getFace(const std::string& fontfile,unsigned int index, FT_Face & face)
62{
63    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(getMutex());
64
65    FT_Error error = FT_New_Face( _ftlibrary, fontfile.c_str(), index, &face );
66    if (error == FT_Err_Unknown_File_Format)
67    {
68        OSG_WARN<<" .... the font file could be opened and read, but it appears"<<std::endl;
69        OSG_WARN<<" .... that its font format is unsupported"<<std::endl;
70        return false;
71    }
72    else if (error)
73    {
74        OSG_WARN<<" .... another error code means that the font file could not"<<std::endl;
75        OSG_WARN<<" .... be opened, read or simply that it is broken.."<<std::endl;
76        return false;
77    }
78
79#ifdef PRINT_OUT_FONT_DETAILS
80
81    OSG_NOTICE<<"Face"<<face<<std::endl;
82    unsigned int count = FT_Get_Sfnt_Name_Count(face);
83    for(unsigned int i=0; i<count; ++i)
84    {
85        FT_SfntName names;
86        FT_Error error = FT_Get_Sfnt_Name(face, i, &names);
87
88        std::string name((char*)names.string, (char*)names.string + names.string_len);
89
90        OSG_NOTICE<<"names "<<name<<std::endl;
91    }
92
93    OSG_NOTICE<<std::endl;
94#endif
95
96    //
97    // GT: Fix to handle symbol fonts in MS Windows
98    //
99    verifyCharacterMap(face);
100
101    return true;
102}
103
104FT_Byte* FreeTypeLibrary::getFace(std::istream& fontstream, unsigned int index, FT_Face & face)
105{
106    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(getMutex());
107
108    FT_Open_Args args;
109
110    std::streampos start = fontstream.tellg();
111    fontstream.seekg(0, std::ios::end);
112    std::streampos end = fontstream.tellg();
113    fontstream.seekg(start, std::ios::beg);
114    std::streampos length = end - start;
115
116    /* empty stream into memory, open that, and keep the pointer in a FreeTypeFont for cleanup */
117    FT_Byte *buffer = new FT_Byte[length];
118    fontstream.read(reinterpret_cast<char*>(buffer), length);
119    if (!fontstream || (static_cast<std::streampos>(fontstream.gcount()) != length))
120    {
121        OSG_WARN<<" .... the font file could not be read from its stream"<<std::endl;
122        if (buffer) delete [] buffer;
123        return 0;
124    }
125    args.flags = FT_OPEN_MEMORY;
126    args.memory_base = buffer;
127    args.memory_size = length;
128
129    FT_Error error = FT_Open_Face( _ftlibrary, &args, index, &face );
130
131    if (error == FT_Err_Unknown_File_Format)
132    {
133        OSG_WARN<<" .... the font file could be opened and read, but it appears"<<std::endl;
134        OSG_WARN<<" .... that its font format is unsupported"<<std::endl;
135        return 0;
136    }
137    else if (error)
138    {
139        OSG_WARN<<" .... another error code means that the font file could not"<<std::endl;
140        OSG_WARN<<" .... be opened, read or simply that it is broken..."<<std::endl;
141        return 0;
142    }
143
144    //
145    // GT: Fix to handle symbol fonts in MS Windows
146    //
147    verifyCharacterMap(face);
148
149    return buffer;
150}
151
152
153osgText::Font* FreeTypeLibrary::getFont(const std::string& fontfile, unsigned int index, unsigned int flags)
154{
155    FT_Face face;
156    if (getFace(fontfile, index, face) == false) return (0);
157
158    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(getMutex());
159
160    FreeTypeFont* fontImp = new FreeTypeFont(fontfile,face,flags);
161    osgText::Font* font = new osgText::Font(fontImp);
162
163    _fontImplementationSet.insert(fontImp);
164
165    return font;
166}
167osgText::Font* FreeTypeLibrary::getFont(std::istream& fontstream, unsigned int index, unsigned int flags)
168{
169    FT_Face face = 0;
170    FT_Byte * buffer = getFace(fontstream, index, face);
171    if (face == 0) return (0);
172
173
174    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(getMutex());
175
176    FreeTypeFont* fontImp = new FreeTypeFont(buffer,face,flags);
177    osgText::Font* font = new osgText::Font(fontImp);
178
179    _fontImplementationSet.insert(fontImp);
180
181    return font;
182}
183
184void FreeTypeLibrary::verifyCharacterMap(FT_Face face)
185{
186    //
187    // GT: Verify the correct character mapping for MS windows
188    // as symbol fonts were being returned incorrectly
189    //
190    FT_CharMap charmap;
191    if (face->charmap == NULL)
192    {
193        for (int n = 0; n < face->num_charmaps; n++)
194        {
195            charmap = face->charmaps[n];
196            if (charmap->platform_id == TT_PLATFORM_MICROSOFT)
197            {
198                FT_Set_Charmap(face, charmap);
199                break;
200            }
201        }
202    }
203}
Note: See TracBrowser for help on using the browser.