NCBI C++ ToolKit
ftglfontmanager.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ftglfontmanager.cpp 42799 2019-04-16 13:34:52Z shkeda $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Bob Falk
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
34 
35 #include <corelib/ncbistr.hpp>
36 #include <corelib/ncbifile.hpp>
37 
38 #ifdef HAVE_LIBFTGL
39 #include <FTGL/ftgl.h>
40 #endif
41 
42 #ifdef USE_METAL
43 #include "MTLTextureFont.h"
44 #endif
45 
46 
48 
50 
52 {
53  static CFtglFontManager tm;
54  return tm;
55 }
56 
58 {
59  // Since this object is a singleton, memory (especially OpenGL) may already
60  // be cleaned up by the system by the time this dtor is called. User should call
61  // 'Clear' to delete fonts.
62  /*
63  Clear();
64  */
65 }
66 
68 {
69  FontIter font;
70  for(font = fonts.begin(); font != fonts.end(); ++font)
71  {
72  delete (*font).second;
73  }
74 
75  fonts.clear();
76  m_BinaryData.clear();
77 }
78 
79 void CFtglFontManager::SetFontPath(const string& p)
80 {
81  m_FontPath = p;
82 
83  // If it is not blank, make sure there is a termination separator, e.g. '/':
84  if (!NStr::IsBlank(m_FontPath)) {
87  }
88  m_FontPath += "fonts";
90  }
91 }
92 
93 FTFont* CFtglFontManager::GetFont(const char *filename,
94  unsigned int size,
95  EFtglFontType ft)
96 {
97 #ifdef HAVE_LIBFTGL
98  static const char* errMsg = " failed to open. To change font directory call "
99  " CFtglFontManager::Instance().SetFontPath(\"..font dir..\") before loading fonts.";
100 
101  char buf[256];
102  sprintf(buf, "%s %i %i", filename, size, ft);
103  string fontKey = string(buf);
104  {{
106  FontIter result = fonts.find(fontKey);
107  if(result != fonts.end())
108  {
109  //_TRACE("Found font " << fontKey << " in list");
110  return result->second;
111  }
112  }}
113 
114  string fullname = m_FontPath + string(filename);
115 
116  // Look for file first in default directory. If not found
117  // try to use filename as the full path name. If neither
118  // work, return null
119  {
120  CDirEntry f1(fullname);
121  if (!f1.Exists()) {
122  CDirEntry f2(filename);
123  if (!f2.Exists()) {
124  ERR_POST(Error << "Font file: " << fullname << errMsg);
125  return nullptr;
126  }
127  else {
128  fullname = filename;
129  }
130  }
131  }
132 
133  unsigned char* buffer = nullptr;
134  size_t bufferSize = 0;
135 
137  {
138  FontIter result = fonts.find(fontKey);
139  if(result != fonts.end())
140  return result->second;
141  }
142 
143  auto it = m_BinaryData.find(fullname);
144  if (it != m_BinaryData.end()) {
145  buffer = std::get<0>(it->second).get();
146  bufferSize = std::get<1>(it->second);
147  }
148  else {
149  unique_ptr<unsigned char[]> data;
150  try {
151  CFileIO file;
152  file.Open(fullname, CFileIO::eOpen, CFileIO::eRead);
153  bufferSize = (size_t)file.GetFileSize();
154  if (bufferSize == 0)
155  NCBI_THROW(CException, eUnknown, "Font file is empty");
156  data.reset(new unsigned char[bufferSize]);
157  if (file.Read(data.get(), bufferSize) != bufferSize)
158  NCBI_THROW(CException, eUnknown, "Failed to read font file");
159  }
160  catch (const CException&) {
161  ERR_POST(Error << "Font file: " << fullname << errMsg);
162  return nullptr;
163  }
164  buffer = data.get();
165 
166  std::get<0>(m_BinaryData[fullname]) = std::move(data);
167  std::get<1>(m_BinaryData[fullname]) = bufferSize;
168  }
169 
170  FTFont* font = nullptr;
171  switch (ft) {
172 #ifdef USE_METAL
173  case eTextureFont:
174  font = new MTLTextureFont(buffer , bufferSize);
175  default:
176  break;
177 #else
178  case eTextureFont:
179  font = new FTTextureFont(buffer , bufferSize);
180  break;
181  case ePixmapFont:
182  font = new FTPixmapFont(buffer, bufferSize);
183  break;
184  case eBitmapFont:
185  font = new FTBitmapFont(buffer, bufferSize);
186  break;
187  case eOutlineFont:
188  font = new FTOutlineFont(buffer, bufferSize);
189  break;
190  case ePolygonFont:
191  font = new FTPolygonFont(buffer, bufferSize);
192  break;
193  case eExtrudedFont:
194  font = new FTExtrudeFont(buffer, bufferSize);
195  break;
196 #endif
197  };
198 
199  //_TRACE("Created font " << fontKey);
200 
201  if(font->Error())
202  {
203  ERR_POST(Error << "Font file: " << fullname <<
204  " failed to open. Default font path: " << m_FontPath );
205  delete font;
206  return NULL;
207  }
208 
209  if(!font->FaceSize(size, m_DeviceResolution))
210  {
211  ERR_POST(Error << "Font " << filename << " failed to set size " << size);
212  delete font;
213  return NULL;
214  }
215  // If we want to actually use device resolution, have to call this twice (or apply fix)
216  // and use a fake device resolution the first time (since it is ignored). But for now we ignore
217  // device resolution because all the non-font rendering ignores it as well and we would want
218  // all our rendering to scale together.
219  // font->FaceSize(size, m_DeviceResolution);
220 
221  font->UseDisplayList(true);
222 
223  fonts[fontKey] = font;
224 
225  return font;
226 #else
227  ERR_POST(Error << "FTGL is unavailable.");
228  return NULL;
229 #endif
230 }
231 
CDirEntry –.
Definition: ncbifile.hpp:262
Class for support low level input/output for files.
Definition: ncbifile.hpp:3475
CRWLock –.
Definition: ncbimtx.hpp:953
FTTextureFont is a specialisation of the FTFont class for handling Texture mapped fonts.
The NCBI C++ standard methods for dealing with std::string.
char data[12]
Definition: iconv.c:80
static CRWLock s_FontMapLock
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
static bool IsPathSeparator(const char c)
Check whether a character "c" is a path separator symbol specific for the current platform.
Definition: ncbifile.cpp:439
virtual bool Exists(void) const
Check the entry existence.
Definition: ncbifile.cpp:2325
static char GetPathSeparator(void)
Get path separator symbol specific for the current platform.
Definition: ncbifile.cpp:433
@ eRead
File can be read.
Definition: ncbifile.hpp:3435
@ eOpen
Open an existing file, or create a new one.
Definition: ncbifile.hpp:3425
string m_FontPath
Directory from which to read font files.
void SetFontPath(const string &p)
This path will be prepended to filename when calling GetFont It should be set to "ToStdString(CSysPat...
unsigned int m_DeviceResolution
target device (screen) resolution in pixels per inch (defaults to 72)
map< string, tuple< unique_ptr< unsigned char[]>, size_t > > m_BinaryData
Loaded to memeory font files.
static CFtglFontManager & Instance()
Get an instance of the manager so you can retrieve fonts.
void Clear()
Delete all current fonts.
EFtglFontType
FTGL can create different types of fonts from files read in using freetype, but the texture fonts are...
FTFont * GetFont(const char *filename, unsigned int size, EFtglFontType ft=eTextureFont)
FontList fonts
All the currently loaded fonts.
FontList::const_iterator FontIter
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static bool IsBlank(const CTempString str, SIZE_TYPE pos=0)
Check if a string is blank (has no text).
Definition: ncbistr.cpp:106
FILE * file
char * buf
const struct ncbi::grid::netcache::search::fields::SIZE size
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
static pcre_uint8 * buffer
Definition: pcretest.c:1051
else result
Definition: token2.c:20
Modified on Tue Apr 23 07:37:17 2024 by modify_doxy.py rev. 669887