Changeset - r20543:89cc7ba70ae8
[Not reviewed]
master
0 3 0
frosch - 11 years ago 2013-07-06 18:56:23
frosch@openttd.org
(svn r25569) -Codechange: Cache all Font instances in a static container.
3 files changed with 41 insertions and 16 deletions:
0 comments (0 inline, 0 general)
src/fontcache.cpp
Show inline comments
 
@@ -14,12 +14,13 @@
 
#include "fontdetection.h"
 
#include "blitter/factory.hpp"
 
#include "core/math_func.hpp"
 
#include "core/smallmap_type.hpp"
 
#include "strings_func.h"
 
#include "zoom_type.h"
 
#include "gfx_layout.h"
 

	
 
#include "table/sprites.h"
 
#include "table/control_codes.h"
 
#include "table/unicode.h"
 

	
 
static const int ASCII_LETTERSTART = 32; ///< First printable ASCII letter.
 
@@ -36,19 +37,21 @@ static const int _default_font_ascender[
 
FontCache::FontCache(FontSize fs) : parent(FontCache::Get(fs)), fs(fs), height(_default_font_height[fs]),
 
		ascender(_default_font_ascender[fs]), descender(_default_font_ascender[fs] - _default_font_height[fs]),
 
		units_per_em(1)
 
{
 
	assert(parent == NULL || this->fs == parent->fs);
 
	FontCache::caches[this->fs] = this;
 
	Layouter::ResetFontCache(this->fs);
 
}
 

	
 
/** Clean everything up. */
 
FontCache::~FontCache()
 
{
 
	assert(this->fs == parent->fs);
 
	FontCache::caches[this->fs] = this->parent;
 
	Layouter::ResetFontCache(this->fs);
 
}
 

	
 

	
 
/**
 
 * Get height of a character for a given font size.
 
 * @param size Font size to get height of
src/gfx_layout.cpp
Show inline comments
 
@@ -17,12 +17,17 @@
 
#include "table/control_codes.h"
 

	
 
#ifdef WITH_ICU
 
#include <unicode/ustring.h>
 
#endif /* WITH_ICU */
 

	
 

	
 
/** Cache of Font instances. */
 
Layouter::FontColourMap Layouter::fonts[FS_END];
 

	
 

	
 
/**
 
 * Construct a new font.
 
 * @param size   The font size to use for this font.
 
 * @param colour The colour to draw this font in.
 
 */
 
Font::Font(FontSize size, TextColour colour) :
 
@@ -411,13 +416,13 @@ Layouter::Layouter(const char *str, int 
 
	CharType *buff = this->buffer;
 

	
 
	FontState state(colour, fontsize);
 
	WChar c = 0;
 

	
 
	do {
 
		Font *f = new Font(state.fontsize, state.cur_colour);
 
		Font *f = GetFont(state.fontsize, state.cur_colour);
 
		CharType *buff_begin = buff;
 
		FontMap fontMapping;
 

	
 
		/*
 
		 * Go through the whole string while adding Font instances to the font map
 
		 * whenever the font changes, and convert the wide characters into a format
 
@@ -439,25 +444,21 @@ Layouter::Layouter(const char *str, int 
 
				buff += AppendToBuffer(buff, buffer_last, c);
 
				continue;
 
			}
 

	
 
			if (!fontMapping.Contains(buff - buff_begin)) {
 
				fontMapping.Insert(buff - buff_begin, f);
 
				*this->fonts.Append() = f;
 
			} else {
 
				delete f;
 
			}
 
			f = new Font(state.fontsize, state.cur_colour);
 
			f = GetFont(state.fontsize, state.cur_colour);
 
		}
 

	
 
		/* Better safe than sorry. */
 
		*buff = '\0';
 

	
 
		if (!fontMapping.Contains(buff - buff_begin)) {
 
			fontMapping.Insert(buff - buff_begin, f);
 
			*this->fonts.Append() = f;
 
		}
 
		ParagraphLayout *p = GetParagraphLayout(buff_begin, buff, fontMapping);
 

	
 
		/* Copy all lines into a local cache so we can reuse them later on more easily. */
 
		ParagraphLayout::Line *l;
 
		while ((l = p->nextLine(maxw)) != NULL) {
 
@@ -466,20 +467,12 @@ Layouter::Layouter(const char *str, int 
 

	
 
		delete p;
 

	
 
	} while (c != '\0' && buff < buffer_last);
 
}
 

	
 
/** Free everything we allocated. */
 
Layouter::~Layouter()
 
{
 
	for (Font **iter = this->fonts.Begin(); iter != this->fonts.End(); iter++) {
 
		delete *iter;
 
	}
 
}
 

	
 
/**
 
 * Get the boundaries of this paragraph.
 
 * @return The boundaries.
 
 */
 
Dimension Layouter::GetBounds()
 
{
 
@@ -487,6 +480,31 @@ Dimension Layouter::GetBounds()
 
	for (ParagraphLayout::Line **l = this->Begin(); l != this->End(); l++) {
 
		d.width = max<uint>(d.width, (*l)->getWidth());
 
		d.height += (*l)->getLeading();
 
	}
 
	return d;
 
}
 

	
 
/**
 
 * Get a static font instance.
 
 */
 
Font *Layouter::GetFont(FontSize size, TextColour colour)
 
{
 
	FontColourMap::iterator it = fonts[size].Find(colour);
 
	if (it != fonts[size].End()) return it->second;
 

	
 
	Font *f = new Font(size, colour);
 
	*fonts[size].Append() = FontColourMap::Pair(colour, f);
 
	return f;
 
}
 

	
 
/**
 
 * Reset cached font information.
 
 * @param size Font size to reset.
 
 */
 
void Layouter::ResetFontCache(FontSize size)
 
{
 
	for (FontColourMap::iterator it = fonts[size].Begin(); it != fonts[size].End(); ++it) {
 
		delete it->second;
 
	}
 
	fonts[size].Clear();
 
}
src/gfx_layout.h
Show inline comments
 
@@ -164,15 +164,19 @@ class Layouter : public AutoDeleteSmallV
 
#endif /* WITH_ICU */
 

	
 
	size_t AppendToBuffer(CharType *buff, const CharType *buffer_last, WChar c);
 
	ParagraphLayout *GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping);
 

	
 
	CharType buffer[DRAW_STRING_BUFFER]; ///< Buffer for the text that is going to be drawn.
 
	SmallVector<Font *, 4> fonts;        ///< The fonts needed for drawing.
 

	
 
	typedef SmallMap<TextColour, Font *> FontColourMap;
 
	static FontColourMap fonts[FS_END];
 
	static Font *GetFont(FontSize size, TextColour colour);
 

	
 
public:
 
	Layouter(const char *str, int maxw = INT32_MAX, TextColour colour = TC_FROMSTRING, FontSize fontsize = FS_NORMAL);
 
	~Layouter();
 
	Dimension GetBounds();
 

	
 
	static void ResetFontCache(FontSize size);
 
};
 

	
 
#endif /* GFX_LAYOUT_H */
0 comments (0 inline, 0 general)