ManaPlus
Public Member Functions | Static Public Attributes | Static Private Member Functions | Private Attributes
Font Class Reference

#include <font.h>

Public Member Functions

 Font (std::string filename, int size, const int style)
 
 ~Font ()
 
void loadFont (std::string filename, const int size, const int style)
 
int getWidth (const std::string &text) const
 
int getHeight () const
 
const TextChunkListgetCache () const A_CONST
 
void drawString (Graphics *const graphics, Color col, const Color &col2, const std::string &text, const int x, const int y)
 
void clear ()
 
void doClean ()
 
void slowLogic (const int rnd)
 
unsigned int getCreateCounter () const
 
unsigned int getDeleteCounter () const
 
int getStringIndexAt (const std::string &text, const int x) const
 
void generate (TextChunk &chunk)
 
void insertChunk (TextChunk *const chunk)
 

Static Public Attributes

static bool mSoftMode
 

Static Private Member Functions

static TTF_Font * openFont (const char *const name, const int size)
 

Private Attributes

TTF_Font * mFont
 
unsigned int mCreateCounter
 
unsigned int mDeleteCounter
 
time_t mCleanTime
 
TextChunkList mCache [CACHES_NUMBER]
 

Detailed Description

A wrapper around SDL_ttf for allowing the use of TrueType fonts.

NOTE: This class initializes SDL_ttf as necessary.

Definition at line 89 of file font.h.

Constructor & Destructor Documentation

◆ Font()

Font::Font ( std::string  filename,
int  size,
const int  style 
)

Definition at line 106 of file font.cpp.

108  :
109  mFont(nullptr),
110  mCreateCounter(0),
111  mDeleteCounter(0),
113 {
114  if (fontCounter == 0)
115  {
117  if (TTF_Init() == -1)
118  {
119  logger->error("Unable to initialize SDL_ttf: " +
120  std::string(SDL_GetError()));
121  }
122  }
123 
124  if (size < 4)
125  {
126  reportAlways("Error: requested load font %s with size %d",
127  filename.c_str(),
128  size)
129  size = 4;
130  }
131 
132  if (fontCounter == 0)
133  {
134  strBuf = new char[65535];
135  memset(strBuf, 0, 65535);
136  }
137 
138  ++fontCounter;
139 
140  fixDirSeparators(filename);
141  logger->log("Attempt to load font: %s",
142  filename.c_str());
143  mFont = openFont(filename.c_str(), size);
144 
145  if (mFont == nullptr)
146  {
147  logger->log("Error normal loading font " + filename);
148 
149  filename = "fonts/dejavusans.ttf";
150  mFont = openFont(fixDirSeparators(filename).c_str(), size);
151  if (mFont == nullptr)
152  {
153 #ifdef UNITTESTS
154  reportAlways("Font load failed %s",
155  filename.c_str())
156 #endif // UNITTESTS
157  logger->error("Font::Font: " +
158  std::string(SDL_GetError()));
159  }
160  else
161  {
162  logger->log("Loaded fallback font %s, %d",
163  filename.c_str(),
164  size);
165  }
166  }
167  else
168  {
169  logger->log("Loaded font %s, %d",
170  filename.c_str(),
171  size);
172  }
173 
174  TTF_SetFontStyle(mFont, style);
175 }
volatile time_t cur_time
Definition: timer.cpp:58
#define reportAlways(...)
Definition: checkutils.h:253
TTF_Font * mFont
Definition: font.h:146
unsigned int mDeleteCounter
Definition: font.h:148
static bool mSoftMode
Definition: font.h:140
unsigned int mCreateCounter
Definition: font.h:147
static TTF_Font * openFont(const char *const name, const int size)
Definition: font.cpp:191
time_t mCleanTime
Definition: font.h:151
virtual RenderType useOpenGL() const
Definition: imagehelper.h:107
void log(const char *const log_text,...)
Definition: logger.cpp:269
void error(const std::string &error_text) __attribute__((noreturn))
Definition: logger.cpp:472
static int fontCounter
Definition: font.cpp:104
char * strBuf
Definition: textchunk.cpp:46
const unsigned int CLEAN_TIME
Definition: font.cpp:98
ImageHelper * imageHelper
Definition: imagehelper.cpp:44
Logger * logger
Definition: logger.cpp:89
int size()
Definition: emotedb.cpp:306
std::string & fixDirSeparators(std::string &str)
Definition: paths.cpp:149
@ RENDER_SOFTWARE
Definition: rendertype.h:27

References Logger::error(), fixDirSeparators(), fontCounter, imageHelper, Logger::log(), logger, mFont, mSoftMode, openFont(), RENDER_SOFTWARE, reportAlways, EmoteDB::size(), strBuf, and ImageHelper::useOpenGL().

◆ ~Font()

Font::~Font ( )

Definition at line 177 of file font.cpp.

178 {
179  TTF_CloseFont(mFont);
180  mFont = nullptr;
181  --fontCounter;
182  clear();
183 
184  if (fontCounter == 0)
185  {
186  TTF_Quit();
187  delete []strBuf;
188  }
189 }
void clear()
Definition: font.cpp:248

References clear(), fontCounter, mFont, and strBuf.

Member Function Documentation

◆ clear()

void Font::clear ( )

Definition at line 248 of file font.cpp.

249 {
250  for (size_t f = 0; f < CACHES_NUMBER; f ++)
251  mCache[f].clear();
252 }
TextChunkList mCache[CACHES_NUMBER]
Definition: font.h:152
const unsigned int CACHES_NUMBER
Definition: font.h:82

References CACHES_NUMBER, and mCache.

Referenced by Gui::clearFonts(), loadFont(), and ~Font().

◆ doClean()

void Font::doClean ( )

Definition at line 367 of file font.cpp.

368 {
369  for (unsigned int f = 0; f < CACHES_NUMBER; f ++)
370  {
371  TextChunkList *const cache = &mCache[f];
372  const size_t size = CAST_SIZE(cache->size);
373 #ifdef DEBUG_FONT_COUNTERS
374  logger->log("ptr: %u, size: %ld", f, size);
375 #endif // DEBUG_FONT_COUNTERS
376 
377  if (size > CACHE_SIZE_SMALL3)
378  {
379 #ifdef DEBUG_FONT_COUNTERS
380  mDeleteCounter += 100;
381 #endif // DEBUG_FONT_COUNTERS
382 
383  cache->removeBack(100);
384 #ifdef DEBUG_FONT_COUNTERS
385  logger->log("delete3");
386 #endif // DEBUG_FONT_COUNTERS
387  }
388  else if (size > CACHE_SIZE_SMALL2)
389  {
390 #ifdef DEBUG_FONT_COUNTERS
391  mDeleteCounter += 20;
392 #endif // DEBUG_FONT_COUNTERS
393 
394  cache->removeBack(20);
395 #ifdef DEBUG_FONT_COUNTERS
396  logger->log("delete2");
397 #endif // DEBUG_FONT_COUNTERS
398  }
399  else if (size > CACHE_SIZE_SMALL1)
400  {
401 #ifdef DEBUG_FONT_COUNTERS
402  mDeleteCounter ++;
403 #endif // DEBUG_FONT_COUNTERS
404 
405  cache->removeBack();
406 #ifdef DEBUG_FONT_COUNTERS
407  logger->log("delete1");
408 #endif // DEBUG_FONT_COUNTERS
409  }
410  }
411 }
#define CAST_SIZE
Definition: cast.h:34
uint32_t size
Definition: textchunklist.h:56
const unsigned int CACHE_SIZE_SMALL1
Definition: font.cpp:95
const unsigned int CACHE_SIZE_SMALL3
Definition: font.cpp:97
const unsigned int CACHE_SIZE_SMALL2
Definition: font.cpp:96

References CACHE_SIZE_SMALL1, CACHE_SIZE_SMALL2, CACHE_SIZE_SMALL3, CACHES_NUMBER, CAST_SIZE, Logger::log(), logger, mCache, mDeleteCounter, TextChunkList::removeBack(), TextChunkList::size, and EmoteDB::size().

Referenced by slowLogic().

◆ drawString()

void Font::drawString ( Graphics *const  graphics,
Color  col,
const Color col2,
const std::string &  text,
const int  x,
const int  y 
)
See also
Font::drawString

Definition at line 254 of file font.cpp.

259 {
260  BLOCK_START("Font::drawString")
261  if (text.empty())
262  {
263  BLOCK_END("Font::drawString")
264  return;
265  }
266 
267 // Color col = graphics->getColor();
268 // const Color &col2 = graphics->getColor2();
269  const float alpha = static_cast<float>(col.a) / 255.0F;
270 
271  /* The alpha value is ignored at string generation so avoid caching the
272  * same text with different alpha values.
273  */
274  col.a = 255;
275 
276  const unsigned char chr = text[0];
277  TextChunkList *const cache = &mCache[chr];
278 
279  std::map<TextChunkSmall, TextChunk*> &search = cache->search;
280  std::map<TextChunkSmall, TextChunk*>::iterator i
281  = search.find(TextChunkSmall(text, col, col2));
282  if (i != search.end())
283  {
284  TextChunk *const chunk2 = (*i).second;
285  cache->moveToFirst(chunk2);
286  Image *const image = chunk2->img;
287  if (image != nullptr)
288  {
289  image->setAlpha(alpha);
290  graphics->drawImage(image, x, y);
291  }
292  }
293  else
294  {
295  if (cache->size >= CACHE_SIZE)
296  {
297 #ifdef DEBUG_FONT_COUNTERS
298  mDeleteCounter ++;
299 #endif // DEBUG_FONT_COUNTERS
300 
301  cache->removeBack();
302  }
303 #ifdef DEBUG_FONT_COUNTERS
304  mCreateCounter ++;
305 #endif // DEBUG_FONT_COUNTERS
306 
307  TextChunk *chunk2 = new TextChunk(text, col, col2, this);
308 
309  chunk2->generate(mFont, alpha);
310  cache->insertFirst(chunk2);
311 
312  const Image *const image = chunk2->img;
313  if (image != nullptr)
314  graphics->drawImage(image, x, y);
315  }
316  BLOCK_END("Font::drawString")
317 }
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
Image * img
Definition: textchunk.h:63
void generate(TTF_Font *const font, const float alpha)
Definition: textchunk.cpp:97
const unsigned int CACHE_SIZE
Definition: font.cpp:94
if(!vert) return
bool find(const std::string &key)
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
std::string empty
Definition: podict.cpp:26

References Color::a, BLOCK_END, BLOCK_START, CACHE_SIZE, Graphics::drawImage(), TextChunk::generate(), TextChunk::img, TextChunkList::insertFirst(), mCache, mCreateCounter, mDeleteCounter, mFont, TextChunkList::moveToFirst(), TextChunkList::removeBack(), TextChunkList::search, TextChunkList::size, x, and y.

Referenced by Game::addWatermark(), Gui::draw(), BrowserBox::draw(), ColorPage::draw(), DropDown::draw(), ExtendedListBox::draw(), ItemContainer::draw(), ItemShortcutContainer::draw(), ListBox::draw(), ServersListBox::draw(), ShopListBox::draw(), SkillListBox::draw(), SkillRectangleListBox::draw(), SpellShortcutContainer::draw(), StaticBrowserBox::draw(), TextBox::draw(), TextPreview::draw(), VirtShortcutContainer::draw(), EquipmentWindow::draw(), FloorItem::draw(), MapItem::draw(), AvatarListBox::draw(), EmoteShortcutContainer::draw(), Viewport::drawPath(), Being::drawPortalSpriteAt(), TouchManager::drawText(), ItemContainer::safeDraw(), ItemShortcutContainer::safeDraw(), SpellShortcutContainer::safeDraw(), VirtShortcutContainer::safeDraw(), EquipmentWindow::safeDraw(), AvatarListBox::safeDraw(), EmoteShortcutContainer::safeDraw(), and TestLauncher::testDraw().

◆ generate()

void Font::generate ( TextChunk chunk)

Definition at line 430 of file font.cpp.

431 {
432  const std::string &text = chunk.text;
433  if (text.empty())
434  return;
435 
436  const unsigned char chr = text[0];
437  TextChunkList *const cache = &mCache[chr];
438  Color &col = chunk.color;
439  Color &col2 = chunk.color2;
440  const int oldAlpha = col.a;
441  col.a = 255;
442 
443  TextChunkSmall key(text, col, col2);
444  std::map<TextChunkSmall, TextChunk*> &search = cache->search;
445  std::map<TextChunkSmall, TextChunk*>::iterator i = search.find(key);
446  if (i != search.end())
447  {
448  TextChunk *const chunk2 = (*i).second;
449  cache->moveToFirst(chunk2);
450 // search.erase(key);
451  cache->remove(chunk2);
452  chunk.img = chunk2->img;
453  chunk2->img = nullptr;
454  delete chunk2;
455 // logger->log("cached image: " + chunk.text);
456  }
457  else
458  {
459  if (cache->size >= CACHE_SIZE)
460  {
461 #ifdef DEBUG_FONT_COUNTERS
462  mDeleteCounter ++;
463 #endif // DEBUG_FONT_COUNTERS
464 
465  cache->removeBack();
466  }
467 #ifdef DEBUG_FONT_COUNTERS
468  mCreateCounter ++;
469 #endif // DEBUG_FONT_COUNTERS
470 
471  const float alpha = static_cast<float>(chunk.color.a) / 255.0F;
472  chunk.generate(mFont, alpha);
473 // logger->log("generate image: " + chunk.text);
474  }
475  col.a = oldAlpha;
476 }
Definition: color.h:76
unsigned int a
Definition: color.h:251
void remove(const TextChunk *const item)
std::map< TextChunkSmall, TextChunk * > search
Definition: textchunklist.h:57
void moveToFirst(TextChunk *const item)
Color color
Definition: textchunk.h:66
Color color2
Definition: textchunk.h:67
std::string text
Definition: textchunk.h:65

References Color::a, CACHE_SIZE, TextChunk::color, TextChunk::color2, TextChunk::generate(), TextChunk::img, mCache, mCreateCounter, mDeleteCounter, mFont, TextChunkList::moveToFirst(), TextChunkList::remove(), TextChunkList::removeBack(), TextChunkList::search, TextChunkList::size, and TextChunk::text.

Referenced by Button::draw(), CheckBox::draw(), Label::draw(), ProgressBar::draw(), RadioButton::draw(), TextField::draw(), Window::draw(), Text::draw(), Button::safeDraw(), ProgressBar::safeDraw(), and Window::safeDraw().

◆ getCache()

const TextChunkList * Font::getCache ( ) const

Definition at line 425 of file font.cpp.

426 {
427  return mCache;
428 }

References mCache.

◆ getCreateCounter()

unsigned int Font::getCreateCounter ( ) const
inline

Definition at line 127 of file font.h.

128  { return mCreateCounter; }

References mCreateCounter.

◆ getDeleteCounter()

unsigned int Font::getDeleteCounter ( ) const
inline

Definition at line 130 of file font.h.

131  { return mDeleteCounter; }

References mDeleteCounter.

◆ getHeight()

int Font::getHeight ( ) const

◆ getStringIndexAt()

int Font::getStringIndexAt ( const std::string &  text,
const int  x 
) const

Definition at line 413 of file font.cpp.

414 {
415  const size_t sz = text.size();
416  for (size_t i = 0; i < sz; ++i)
417  {
418  if (getWidth(text.substr(0, i)) > x)
419  return CAST_S32(i);
420  }
421 
422  return CAST_S32(sz);
423 }
#define CAST_S32
Definition: cast.h:30
int getWidth(const std::string &text) const
Definition: font.cpp:334

References CAST_S32, getWidth(), and x.

Referenced by TextBox::mousePressed(), and TextField::mousePressed().

◆ getWidth()

int Font::getWidth ( const std::string &  text) const

Definition at line 334 of file font.cpp.

335 {
336  if (text.empty())
337  return 0;
338 
339  const unsigned char chr = text[0];
340  TextChunkList *const cache = &mCache[chr];
341 
342  std::map<std::string, TextChunk*> &search = cache->searchWidth;
343  std::map<std::string, TextChunk*>::iterator i = search.find(text);
344  if (i != search.end())
345  {
346  TextChunk *const chunk = (*i).second;
347  cache->moveToFirst(chunk);
348  const Image *const image = chunk->img;
349  if (image != nullptr)
350  return image->getWidth();
351  return 0;
352  }
353 
354  // if string was not drawed
355  int w;
356  int h;
357  getSafeUtf8String(text, strBuf);
358  TTF_SizeUTF8(mFont, strBuf, &w, &h);
359  return w;
360 }
std::map< std::string, TextChunk * > searchWidth
Definition: textchunklist.h:58
const char * getSafeUtf8String(const std::string &text)

References getSafeUtf8String(), TextChunk::img, mCache, mFont, TextChunkList::moveToFirst(), TextChunkList::searchWidth, and strBuf.

Referenced by BrowserBox::addRow(), StaticBrowserBox::addRow(), Button::adjustSize(), Label::adjustSize(), RadioButton::adjustSize(), TextBox::adjustSize(), BrowserBox::calcHeight(), Gui::draw(), Button::draw(), ColorPage::draw(), ExtendedListBox::draw(), ItemContainer::draw(), ItemShortcutContainer::draw(), Label::draw(), ListBox::draw(), ProgressBar::draw(), ServersListBox::draw(), SkillListBox::draw(), SkillRectangleListBox::draw(), TextBox::draw(), TextField::draw(), TextPreview::draw(), VirtShortcutContainer::draw(), Window::draw(), EquipmentWindow::draw(), Viewport::drawPath(), TouchManager::drawText(), TextField::fixScroll(), SliderList::getMaxLabelWidth(), SetupItemSlider2::getMaxWidth(), getStringIndexAt(), InventoryWindow::InventoryWindow(), Label::Label(), ServerDialog::loadServers(), NpcDialog::NpcDialog(), OkDialog::OkDialog(), PincodeDialog::PincodeDialog(), ConfirmDialog::postInit(), Label::resizeTo(), Button::safeDraw(), ItemContainer::safeDraw(), ItemShortcutContainer::safeDraw(), ProgressBar::safeDraw(), VirtShortcutContainer::safeDraw(), Window::safeDraw(), EquipmentWindow::safeDraw(), TextBox::scrollToCaret(), TextBox::setTextWrapped(), Setup_Colors::Setup_Colors(), ServersListModel::setVersionString(), SkillRectangleListBox::SkillRectangleListBox(), TextDialog::TextDialog(), TradeWindow::TradeWindow(), and StaticBrowserBox::updateHeight().

◆ insertChunk()

void Font::insertChunk ( TextChunk *const  chunk)

Definition at line 478 of file font.cpp.

479 {
480  if ((chunk == nullptr) || chunk->text.empty() || (chunk->img == nullptr))
481  return;
482 // logger->log("insert chunk: text=%s, color: %d,%d,%d",
483 // chunk->text.c_str(), chunk->color.r, chunk->color.g, chunk->color.b);
484  const unsigned char chr = chunk->text[0];
485  TextChunkList *const cache = &mCache[chr];
486 
487  std::map<TextChunkSmall, TextChunk*> &search = cache->search;
488  std::map<TextChunkSmall, TextChunk*>::iterator i
489  = search.find(TextChunkSmall(chunk->text,
490  chunk->color, chunk->color2));
491  if (i != search.end())
492  {
493  delete2(chunk->img)
494  return;
495  }
496 
497  TextChunk *const chunk2 = new TextChunk(chunk->text,
498  chunk->color, chunk->color2, chunk->textFont);
499  chunk2->img = chunk->img;
500  cache->insertFirst(chunk2);
501 }
#define new
Definition: debug_new.h:147
#define delete2(var)
Definition: delete2.h:25

References TextChunk::color, TextChunk::color2, delete2, TextChunk::img, TextChunkList::insertFirst(), mCache, TextChunkList::search, TextChunk::text, and TextChunk::textFont.

Referenced by TextChunk::deleteImage().

◆ loadFont()

void Font::loadFont ( std::string  filename,
const int  size,
const int  style 
)

Definition at line 219 of file font.cpp.

222 {
223  if (fontCounter == 0 && TTF_Init() == -1)
224  {
225  logger->log("Unable to initialize SDL_ttf: " +
226  std::string(SDL_GetError()));
227  return;
228  }
229 
230  fixDirSeparators(filename);
231  TTF_Font *const font = openFont(filename.c_str(), size);
232 
233  if (font == nullptr)
234  {
235  logger->log("Font::Font: " +
236  std::string(SDL_GetError()));
237  return;
238  }
239 
240  if (mFont != nullptr)
241  TTF_CloseFont(mFont);
242 
243  mFont = font;
244  TTF_SetFontStyle(mFont, style);
245  clear();
246 }

References clear(), fixDirSeparators(), fontCounter, Logger::log(), logger, mFont, openFont(), and EmoteDB::size().

Referenced by Gui::updateFonts().

◆ openFont()

TTF_Font * Font::openFont ( const char *const  name,
const int  size 
)
staticprivate

Definition at line 191 of file font.cpp.

193 {
194 #ifdef USE_SDL2
195  SDL_RWops *const rw = VirtFs::rwopsOpenRead(name);
196  if (rw)
197  {
198  logger->log("Loading virtfs font file: %s",
199  name);
200  return TTF_OpenFontIndexRW(rw, 1, size, 0);
201  }
202 #endif
203  const std::string path = VirtFs::getPath(name);
204  if (Files::existsLocal(path) == false)
205  {
206 #ifndef UNITTESTS
207  // +++ in future need trigger assert in unit tests here too
208  reportAlways("Font::openFont font not exists: %s",
209  path.c_str())
210 #endif // UNITTESTS
211  return nullptr;
212  }
213  logger->log("Loading physical font file: %s",
214  path.c_str());
215  return TTF_OpenFontIndex(path.c_str(),
216  size, 0);
217 }
bool existsLocal(const std::string &path)
Definition: files.cpp:209
std::string getPath(const std::string &file)
Definition: tools.cpp:97
SDL_RWops * rwopsOpenRead(const std::string &fname)
Definition: rwops.cpp:107

References Files::existsLocal(), VirtFs::getPath(), Logger::log(), logger, reportAlways, VirtFs::rwopsOpenRead(), and EmoteDB::size().

Referenced by Font(), and loadFont().

◆ slowLogic()

void Font::slowLogic ( const int  rnd)

Definition at line 319 of file font.cpp.

320 {
321  BLOCK_START("Font::slowLogic")
322  if (mCleanTime == 0)
323  {
324  mCleanTime = cur_time + CLEAN_TIME + rnd;
325  }
326  else if (mCleanTime < cur_time)
327  {
328  doClean();
329  mCleanTime = cur_time + CLEAN_TIME + rnd;
330  }
331  BLOCK_END("Font::slowLogic")
332 }
void doClean()
Definition: font.cpp:367

References BLOCK_END, BLOCK_START, CLEAN_TIME, cur_time, doClean(), and mCleanTime.

Referenced by Gui::slowLogic().

Field Documentation

◆ mCache

TextChunkList Font::mCache[CACHES_NUMBER]
mutableprivate

Definition at line 152 of file font.h.

Referenced by clear(), doClean(), drawString(), generate(), getCache(), getWidth(), and insertChunk().

◆ mCleanTime

time_t Font::mCleanTime
private

Definition at line 151 of file font.h.

Referenced by slowLogic().

◆ mCreateCounter

unsigned int Font::mCreateCounter
private

Definition at line 147 of file font.h.

Referenced by drawString(), generate(), and getCreateCounter().

◆ mDeleteCounter

unsigned int Font::mDeleteCounter
private

Definition at line 148 of file font.h.

Referenced by doClean(), drawString(), generate(), and getDeleteCounter().

◆ mFont

TTF_Font* Font::mFont
private

Definition at line 146 of file font.h.

Referenced by drawString(), Font(), generate(), getHeight(), getWidth(), loadFont(), and ~Font().

◆ mSoftMode

bool Font::mSoftMode
static

Definition at line 140 of file font.h.

Referenced by Font(), and TextChunkSmall::operator<().


The documentation for this class was generated from the following files: