summaryrefslogtreecommitdiff
path: root/src/gfx_layout.h
blob: cf4f1f90a6c2645370e7bbaf3eb6c2a7570620f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/* $Id$ */

/*
 * This file is part of OpenTTD.
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file gfx_layout.h Functions related to laying out the texts. */

#ifndef GFX_LAYOUT_H
#define GFX_LAYOUT_H

#include "fontcache.h"
#include "gfx_func.h"
#include "core/smallmap_type.hpp"

/**
 * Container with information about a font.
 */
class Font {
public:
	FontCache *fc;     ///< The font we are using.
	TextColour colour; ///< The colour this font has to be.

	Font(FontSize size, TextColour colour);
};

/** Mapping from index to font. */
typedef SmallMap<int, Font *> FontMap;

/**
 * Class handling the splitting of a paragraph of text into lines and
 * visual runs.
 *
 * One constructs this class with the text that needs to be split into
 * lines. Then nextLine is called with the maximum with until NULL is
 * returned. Each nextLine call creates VisualRuns which contain the
 * length of text that are to be drawn with the same font. In other
 * words, the result of this class is a list of sub strings with their
 * font. The sub strings are then already fully laid out, and only
 * need actual drawing.
 *
 * The positions in a visual run are sequential pairs of X,Y of the
 * begin of each of the glyphs plus an extra pair to mark the end.
 *
 * @note This variant does not handle left-to-right properly. This
 *       is supported in the one ParagraphLayout coming from ICU.
 * @note Does not conform to function naming style as it provides a
 *       fallback for the ICU class.
 */
class ParagraphLayout {
public:
	/** Visual run contains data about the bit of text with the same font. */
	class VisualRun {
		Font *font;       ///< The font used to layout these.
		GlyphID *glyphs;  ///< The glyphs we're drawing.
		float *positions; ///< The positions of the glyphs.
		int glyph_count;  ///< The number of glyphs.

	public:
		VisualRun(Font *font, const WChar *chars, int glyph_count, int x);
		~VisualRun();
		Font *getFont() const;
		int getGlyphCount() const;
		const GlyphID *getGlyphs() const;
		float *getPositions() const;
		int getLeading() const;
	};

	/** A single line worth of VisualRuns. */
	class Line : public AutoDeleteSmallVector<VisualRun *, 4> {
	public:
		int getLeading() const;
		int getWidth() const;
		int countRuns() const;
		VisualRun *getVisualRun(int run) const;
	};

	const WChar *buffer_begin; ///< Begin of the buffer.
	WChar *buffer;             ///< The current location in the buffer.
	FontMap &runs;             ///< The fonts we have to use for this paragraph.

	ParagraphLayout(WChar *buffer, int length, FontMap &runs);
	Line *nextLine(int max_width);
};

/**
 * The layouter performs all the layout work.
 *
 * It also accounts for the memory allocations and frees.
 */
class Layouter : public AutoDeleteSmallVector<ParagraphLayout::Line *, 4> {
	typedef WChar CharType; ///< The type of character used within the layouter.

	size_t AppendToBuffer(CharType *buff, const CharType *buffer_last, WChar c);
	ParagraphLayout *GetParagraphLayout(CharType *buff);

	CharType buffer[DRAW_STRING_BUFFER]; ///< Buffer for the text that is going to be drawn.
	FontMap fonts;                       ///< The fonts needed for drawing.

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

#endif /* GFX_LAYOUT_H */