Mercurial > fife-parpg
comparison engine/core/video/fonts/fontbase.cpp @ 0:4a0efb7baf70
* Datasets becomes the new trunk and retires after that :-)
author | mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sun, 29 Jun 2008 18:44:17 +0000 |
parents | |
children | 90005975cdbb |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4a0efb7baf70 |
---|---|
1 /*************************************************************************** | |
2 * Copyright (C) 2005-2008 by the FIFE team * | |
3 * http://www.fifengine.de * | |
4 * This file is part of FIFE. * | |
5 * * | |
6 * FIFE 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 2 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 * You should have received a copy of the GNU General Public License * | |
17 * along with this program; if not, write to the * | |
18 * Free Software Foundation, Inc., * | |
19 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * | |
20 ***************************************************************************/ | |
21 | |
22 // Standard C++ library includes | |
23 #include <vector> | |
24 | |
25 // Platform specific includes | |
26 | |
27 // 3rd party library includes | |
28 #include <boost/filesystem/convenience.hpp> | |
29 | |
30 // FIFE includes | |
31 // These includes are split up in two parts, separated by one empty line | |
32 // First block: files included from the FIFE root src directory | |
33 // Second block: files included from the same folder | |
34 #include "util/structures/rect.h" | |
35 #include "util/base/exception.h" | |
36 #include "video/image.h" | |
37 #include "video/renderbackend.h" | |
38 | |
39 #include "fontbase.h" | |
40 | |
41 namespace FIFE { | |
42 | |
43 FontBase::FontBase(): | |
44 m_pool(), | |
45 mColor(), | |
46 mGlyphSpacing(0), | |
47 mRowSpacing(0), | |
48 mFilename(""), | |
49 m_antiAlias(true) { | |
50 } | |
51 | |
52 void FontBase::setRowSpacing(int spacing) { | |
53 mRowSpacing = spacing; | |
54 } | |
55 | |
56 int FontBase::getRowSpacing() const { | |
57 return mRowSpacing; | |
58 } | |
59 | |
60 void FontBase::setGlyphSpacing(int spacing) { | |
61 mGlyphSpacing = spacing; | |
62 } | |
63 | |
64 int FontBase::getGlyphSpacing() const { | |
65 return mGlyphSpacing; | |
66 } | |
67 | |
68 void FontBase::setAntiAlias(bool antiAlias) { | |
69 m_antiAlias = antiAlias; | |
70 } | |
71 | |
72 bool FontBase::isAntiAlias() { | |
73 return m_antiAlias; | |
74 } | |
75 | |
76 SDL_Color FontBase::getColor() const { | |
77 return mColor; | |
78 } | |
79 | |
80 int FontBase::getStringIndexAt(const std::string &text, int x) { | |
81 for (int i = 0; i < static_cast<int>(text.size()); ++i) { | |
82 if (getWidth(text.substr(0,i)) > x) { | |
83 return i-1; | |
84 } | |
85 } | |
86 return text.length(); | |
87 } | |
88 | |
89 Image* FontBase::getAsImage(const std::string& text) { | |
90 Image* image = m_pool.getRenderedText(this, text); | |
91 if (!image) { | |
92 SDL_Surface* textSurface = renderString(text); | |
93 image = RenderBackend::instance()->createImage(textSurface); | |
94 m_pool.addRenderedText( this, text, image ); | |
95 } | |
96 return image; | |
97 } | |
98 | |
99 Image* FontBase::getAsImageMultiline(const std::string& text) { | |
100 Image* image = m_pool.getRenderedText(this, text); | |
101 if (!image) { | |
102 std::vector<SDL_Surface*> lines; | |
103 | |
104 // split text as needed | |
105 std::string::size_type pos, last_pos = 0; | |
106 int length = 0; | |
107 int render_width = 0, render_height = 0; | |
108 do { | |
109 pos = text.find("\n", last_pos); | |
110 if (pos != std::string::npos) { | |
111 length = pos - last_pos; | |
112 } else { | |
113 length = text.size() - last_pos; | |
114 } | |
115 std::string sub = text.substr(last_pos, length); | |
116 SDL_Surface* text_surface = renderString(sub); | |
117 if (text_surface->w > render_width) { | |
118 render_width = text_surface->w; | |
119 } | |
120 lines.push_back(text_surface); | |
121 last_pos = pos + 1; | |
122 } while (pos != std::string::npos); | |
123 render_height = (getRowSpacing() + getHeight()) * lines.size(); | |
124 SDL_Surface* final_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, | |
125 render_width,render_height,32, | |
126 RMASK, GMASK, BMASK ,AMASK); | |
127 if (!final_surface) { | |
128 std::cerr << "CreateRGBSurface failed: " << SDL_GetError() << "\n"; | |
129 exit(0); | |
130 } | |
131 SDL_FillRect(final_surface, 0, 0x00000000); | |
132 int ypos = 0; | |
133 for (std::vector<SDL_Surface*>::iterator i = lines.begin(); i != lines.end(); ++i) { | |
134 SDL_Rect dst_rect = { 0, 0, 0, 0 }; | |
135 dst_rect.y = ypos; | |
136 | |
137 SDL_SetAlpha(*i,0,SDL_ALPHA_OPAQUE); | |
138 SDL_BlitSurface(*i,0,final_surface,&dst_rect); | |
139 ypos += getRowSpacing() + getHeight(); | |
140 SDL_FreeSurface(*i); | |
141 } | |
142 image = RenderBackend::instance()->createImage(final_surface); | |
143 m_pool.addRenderedText(this, text, image); | |
144 } | |
145 return image; | |
146 } | |
147 | |
148 std::string FontBase::splitTextToWidth (const std::string& text, int render_width) { | |
149 if (render_width <= 0 || text.empty()) { | |
150 return text; | |
151 } | |
152 std::string output; | |
153 std::string line; | |
154 std::string::size_type pos = 0; | |
155 std::list<std::pair<size_t,size_t> > break_pos; | |
156 bool firstLine = true; | |
157 | |
158 while( pos < text.length() ) | |
159 { | |
160 break_pos.clear(); | |
161 if( !firstLine ) { | |
162 line = "\n"; | |
163 } else { | |
164 firstLine = false; | |
165 } | |
166 | |
167 while( getWidth(line) < render_width && pos < text.length() ) | |
168 { | |
169 if (text.at(pos) == ' ' && !line.empty()) | |
170 break_pos.push_back( std::make_pair(line.length(),pos) ); | |
171 line.push_back( text.at(pos) ); | |
172 ++pos; | |
173 | |
174 // Special case: Already newlines in string: | |
175 if( text.at(pos-1) == '\n' ) { | |
176 if( line[0] == '\n' && line.length() > 1 ) | |
177 line.erase(0); | |
178 output.append(line); | |
179 break; | |
180 } | |
181 } | |
182 if( pos >= text.length() ) | |
183 break; | |
184 | |
185 if( break_pos.empty() ) { | |
186 // No break position and line length smaller than 2 | |
187 // means the renderwidth is really screwed. Just continue | |
188 // appending single character lines. | |
189 if( line.length() <= 1 ) { | |
190 output.append(line); | |
191 continue; | |
192 } | |
193 | |
194 // We can't do hyphenation here, | |
195 // so we just retreat one character :-( | |
196 line.erase(line.length() - 1); | |
197 --pos; | |
198 } else { | |
199 line = line.substr(0,break_pos.back().first); | |
200 pos = break_pos.back().second + 1; | |
201 } | |
202 output.append(line); | |
203 } | |
204 if( !line.empty() ) { | |
205 output.append(line); | |
206 } | |
207 return output; | |
208 } | |
209 } |