1 /*
2 
3 	Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
4 	and the "Aleph One" developers.
5 
6 	This program is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 3 of the License, or
9 	(at your option) any later version.
10 
11 	This program is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 	GNU General Public License for more details.
15 
16 	This license is contained in the file "COPYING",
17 	which is included with this source code; it is available online at
18 	http://www.gnu.org/licenses/gpl.html
19 
20 */
21 
22 /*
23  *  sdl_fonts.h - SDL font handling
24  *
25  *  Written in 2000 by Christian Bauer
26  */
27 
28 #ifndef SDL_FONTS_H
29 #define SDL_FONTS_H
30 
31 #include "csfonts.h"
32 #include "FileHandler.h"
33 #include <SDL_ttf.h>
34 #include <boost/tuple/tuple.hpp>
35 
36 #include <string>
37 
38 /*
39  *  Definitions
40  */
41 
42 
43 class font_info {
44 	friend void unload_font(font_info *font);
45 public:
46 	virtual uint16 get_ascent(void) const = 0;
47 	virtual uint16 get_height(void) const = 0;
48 	virtual uint16 get_line_height(void) const = 0;
49 	virtual uint16 get_descent(void) const = 0;
50 	virtual int16 get_leading(void) const = 0;
51 
52 	int draw_text(SDL_Surface *s, const char *text, size_t length, int x, int y, uint32 pixel, uint16 style, bool utf8 = false) const;
53 	uint16 text_width(const char *text, size_t length, uint16 style, bool utf8 = false) const;
54 	uint16 text_width(const char *text, uint16 style, bool utf8 = false) const;
55 	int trunc_text(const char *text, int max_width, uint16 style) const;
56 	virtual int8 char_width(uint8 c, uint16 style) const = 0;
57 
58 	int draw_styled_text(SDL_Surface *s, const std::string& text, size_t length, int x, int y, uint32 pixel, uint16 initial_style, bool utf = false) const;
59 	int styled_text_width(const std::string& text, size_t length, uint16 initial_style, bool utf8 = false) const;
60 	int trunc_styled_text(const std::string& text, int max_width, uint16 style) const;
61 	std::string style_at(const std::string& text, std::string::const_iterator pos, uint16 style) const;
62 	virtual ~font_info() = default;
63 protected:
64 	virtual int _draw_text(SDL_Surface *s, const char *text, size_t length, int x, int y, uint32 pixel, uint16 style, bool utf8) const = 0;
65 	virtual uint16 _text_width(const char *text, size_t length, uint16 style, bool utf8) const = 0;
66 	virtual uint16 _text_width(const char *text, uint16 style, bool utf8) const = 0;
67 	virtual int _trunc_text(const char *text, int max_width, uint16 style) const = 0;
68 private:
69 	// wrapped behind unload_font, because we call delete this!
70 	virtual void _unload() = 0;
71 };
72 
73 // Font information structure
74 class sdl_font_info : public font_info {
75 	friend sdl_font_info *load_sdl_font(const TextSpec &spec);
76 	friend void unload_sdl_font(sdl_font_info *font);
77 
78 public:
sdl_font_info()79 	sdl_font_info() : first_character(0), last_character(0),
80 		ascent(0), descent(0), leading(0), pixmap(NULL), ref_count(0) {}
~sdl_font_info()81 	virtual ~sdl_font_info() {if (pixmap) free(pixmap);}
82 
get_ascent(void)83 	uint16 get_ascent(void) const {return ascent;}
get_height(void)84 	uint16 get_height(void) const {return ascent + descent;}
get_line_height(void)85 	uint16 get_line_height(void) const {return ascent + descent + leading;}
get_descent(void)86 	uint16 get_descent(void) const {return descent; }
get_leading(void)87 	int16 get_leading(void) const { return leading;}
88 
89 	uint8 first_character, last_character;
90 	int16 maximum_kerning;
91 	int16 rect_width, rect_height;
92 	uint16 ascent, descent;
93 	int16 leading;
94 
95 	uint8 *pixmap;			// Font image (1 byte/pixel)
96 	int bytes_per_row;		// Bytes per row in pixmap
97 
98 	uint16 *location_table;	// Table of byte-offsets into pixmap (points into resource)
99 	int8 *width_table;		// Table of kerning/width info (points into resource)
100 
101 	int8 char_width(uint8 c, uint16 style) const;
102 
103 protected:
104 	virtual int _draw_text(SDL_Surface *s, const char *text, size_t length, int x, int y, uint32 pixel, uint16 style, bool utf8) const;
105 	virtual uint16 _text_width(const char *text, size_t length, uint16 style, bool utf8) const;
106 	virtual uint16 _text_width(const char *text, uint16 style, bool utf8) const;
107 	virtual int _trunc_text(const char *text, int max_width, uint16 style) const;
108 private:
109 	virtual void _unload();
110 	int ref_count;
111 	LoadedResource rsrc;
112 };
113 
114 typedef boost::tuple<std::string, uint16, int16> ttf_font_key_t;
115 
116 class ttf_font_info : public font_info {
117 public:
get_ascent()118 	uint16 get_ascent() const { return TTF_FontAscent(m_styles[styleNormal]); };
get_height()119 	uint16 get_height() const { return TTF_FontHeight(m_styles[styleNormal]); };
get_line_height()120 	uint16 get_line_height() const { return std::max(TTF_FontLineSkip(m_styles[styleNormal]), TTF_FontHeight(m_styles[styleNormal])) + m_adjust_height; }
get_descent()121 	uint16 get_descent() const { return -TTF_FontDescent(m_styles[styleNormal]); }
get_leading()122 	int16 get_leading() const { return get_line_height() - get_ascent() - get_descent(); }
123 
124 	TTF_Font* m_styles[styleUnderline];
125 	ttf_font_key_t m_keys[styleUnderline];
126 	int m_adjust_height;
127 
128 	int8 char_width(uint8, uint16) const;
129 
ttf_font_info()130 	ttf_font_info() {
131 		for (int i = 0; i < styleUnderline; i++) { m_styles[i] = 0; }
132 	}
133 	virtual ~ttf_font_info() = default;
134 protected:
135 	virtual int _draw_text(SDL_Surface *s, const char *text, size_t length, int x, int y, uint32 pixel, uint16 style, bool utf8) const;
136 	virtual uint16 _text_width(const char *text, size_t length, uint16 style, bool utf8) const;
137 	virtual uint16 _text_width(const char *text, uint16 style, bool utf8) const;
138 	virtual int _trunc_text(const char *text, int max_width, uint16 style) const;
139 private:
140 	char *process_printable(const char *src, int len) const;
141 	uint16 *process_macroman(const char *src, int len) const;
get_ttf(uint16 style)142 	TTF_Font *get_ttf(uint16 style) const { return m_styles[style & (styleBold | styleItalic)]; }
143 	virtual void _unload();
144 };
145 
146 /*
147  *  Functions
148  */
149 
150 // Initialize font management
151 extern void initialize_fonts(bool last_chance);
152 
153 // Load font, return pointer to font info
154 extern font_info *load_font(const TextSpec &spec);
155 
156 // Unload font
157 extern void unload_font(font_info *font);
158 
159 #endif
160