Mercurial > fife-parpg
comparison ext/guichan-0.8.1/src/imagefont.cpp @ 89:fa33cda75471
* Reverting back to 2543 as requested by sleek
author | mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sat, 19 Jul 2008 11:38:52 +0000 |
parents | 4a0efb7baf70 |
children |
comparison
equal
deleted
inserted
replaced
88:1c2842ebe393 | 89:fa33cda75471 |
---|---|
1 /* _______ __ __ __ ______ __ __ _______ __ __ | |
2 * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\ | |
3 * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / / | |
4 * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / / | |
5 * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / / | |
6 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ / | |
7 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/ | |
8 * | |
9 * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson | |
10 * | |
11 * | |
12 * Per Larsson a.k.a finalman | |
13 * Olof Naessén a.k.a jansem/yakslem | |
14 * | |
15 * Visit: http://guichan.sourceforge.net | |
16 * | |
17 * License: (BSD) | |
18 * Redistribution and use in source and binary forms, with or without | |
19 * modification, are permitted provided that the following conditions | |
20 * are met: | |
21 * 1. Redistributions of source code must retain the above copyright | |
22 * notice, this list of conditions and the following disclaimer. | |
23 * 2. Redistributions in binary form must reproduce the above copyright | |
24 * notice, this list of conditions and the following disclaimer in | |
25 * the documentation and/or other materials provided with the | |
26 * distribution. | |
27 * 3. Neither the name of Guichan nor the names of its contributors may | |
28 * be used to endorse or promote products derived from this software | |
29 * without specific prior written permission. | |
30 * | |
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | |
37 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
38 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
42 */ | |
43 | |
44 /* | |
45 * For comments regarding functions please see the header file. | |
46 */ | |
47 | |
48 #include "guichan/imagefont.hpp" | |
49 | |
50 #include <sstream> | |
51 | |
52 #include "guichan/color.hpp" | |
53 #include "guichan/exception.hpp" | |
54 #include "guichan/graphics.hpp" | |
55 #include "guichan/image.hpp" | |
56 | |
57 namespace gcn | |
58 { | |
59 ImageFont::ImageFont(const std::string& filename, | |
60 const std::string& glyphs) | |
61 { | |
62 mFilename = filename; | |
63 mImage = Image::load(filename, false); | |
64 | |
65 Color separator = mImage->getPixel(0, 0); | |
66 | |
67 int i = 0; | |
68 for (i = 0; | |
69 i < mImage->getWidth() && separator == mImage->getPixel(i, 0); | |
70 ++i) | |
71 { | |
72 } | |
73 | |
74 if (i >= mImage->getWidth()) | |
75 { | |
76 throw GCN_EXCEPTION("Corrupt image."); | |
77 } | |
78 | |
79 int j = 0; | |
80 for (j = 0; j < mImage->getHeight(); ++j) | |
81 { | |
82 if (separator == mImage->getPixel(i, j)) | |
83 { | |
84 break; | |
85 } | |
86 } | |
87 | |
88 mHeight = j; | |
89 int x = 0, y = 0; | |
90 unsigned char k; | |
91 | |
92 for (i = 0; i < (int)glyphs.size(); ++i) | |
93 { | |
94 k = glyphs.at(i); | |
95 mGlyph[k] = scanForGlyph(k, x, y, separator); | |
96 // Update x och y with new coordinates. | |
97 x = mGlyph[k].x + mGlyph[k].width; | |
98 y = mGlyph[k].y; | |
99 } | |
100 | |
101 int w = mImage->getWidth(); | |
102 int h = mImage->getHeight(); | |
103 mImage->convertToDisplayFormat(); | |
104 | |
105 mRowSpacing = 0; | |
106 mGlyphSpacing = 0; | |
107 } | |
108 | |
109 ImageFont::ImageFont(Image* image, | |
110 const std::string& glyphs) | |
111 { | |
112 mFilename = "Image*"; | |
113 if (image == NULL) | |
114 { | |
115 GCN_EXCEPTION("Font image is NULL"); | |
116 } | |
117 mImage = image; | |
118 | |
119 Color separator = mImage->getPixel(0, 0); | |
120 | |
121 int i = 0; | |
122 for (i = 0; | |
123 i < mImage->getWidth() && separator == mImage->getPixel(i, 0); | |
124 ++i) | |
125 { | |
126 } | |
127 | |
128 if (i >= mImage->getWidth()) | |
129 { | |
130 throw GCN_EXCEPTION("Corrupt image."); | |
131 } | |
132 | |
133 int j = 0; | |
134 for (j = 0; j < mImage->getHeight(); ++j) | |
135 { | |
136 if (separator == mImage->getPixel(i, j)) | |
137 { | |
138 break; | |
139 } | |
140 } | |
141 | |
142 mHeight = j; | |
143 int x = 0, y = 0; | |
144 unsigned char k; | |
145 | |
146 for (i = 0; i < (int)glyphs.size(); ++i) | |
147 { | |
148 k = glyphs.at(i); | |
149 mGlyph[k] = scanForGlyph(k, x, y, separator); | |
150 // Update x och y with new coordinates. | |
151 x = mGlyph[k].x + mGlyph[k].width; | |
152 y = mGlyph[k].y; | |
153 } | |
154 | |
155 int w = mImage->getWidth(); | |
156 int h = mImage->getHeight(); | |
157 mImage->convertToDisplayFormat(); | |
158 | |
159 mRowSpacing = 0; | |
160 mGlyphSpacing = 0; | |
161 } | |
162 | |
163 ImageFont::ImageFont(const std::string& filename, | |
164 unsigned char glyphsFrom, | |
165 unsigned char glyphsTo) | |
166 { | |
167 mFilename = filename; | |
168 mImage = Image::load(filename, false); | |
169 | |
170 Color separator = mImage->getPixel(0, 0); | |
171 | |
172 int i = 0; | |
173 for (i=0; separator == mImage->getPixel(i, 0) | |
174 && i < mImage->getWidth(); ++i) | |
175 { | |
176 } | |
177 | |
178 if (i >= mImage->getWidth()) | |
179 { | |
180 throw GCN_EXCEPTION("Corrupt image."); | |
181 } | |
182 | |
183 int j = 0; | |
184 for (j = 0; j < mImage->getHeight(); ++j) | |
185 { | |
186 if (separator == mImage->getPixel(i, j)) | |
187 { | |
188 break; | |
189 } | |
190 } | |
191 | |
192 mHeight = j; | |
193 int x = 0, y = 0; | |
194 | |
195 for (i = glyphsFrom; i < glyphsTo + 1; i++) | |
196 { | |
197 mGlyph[i] = scanForGlyph(i, x, y, separator); | |
198 // Update x och y with new coordinates. | |
199 x = mGlyph[i].x + mGlyph[i].width; | |
200 y = mGlyph[i].y; | |
201 } | |
202 | |
203 int w = mImage->getWidth(); | |
204 int h = mImage->getHeight(); | |
205 mImage->convertToDisplayFormat(); | |
206 | |
207 mRowSpacing = 0; | |
208 mGlyphSpacing = 0; | |
209 } | |
210 | |
211 ImageFont::~ImageFont() | |
212 { | |
213 delete mImage; | |
214 } | |
215 | |
216 int ImageFont::getWidth(unsigned char glyph) const | |
217 { | |
218 if (mGlyph[glyph].width == 0) | |
219 { | |
220 return mGlyph[(int)(' ')].width + mGlyphSpacing; | |
221 } | |
222 | |
223 return mGlyph[glyph].width + mGlyphSpacing; | |
224 } | |
225 | |
226 int ImageFont::getHeight() const | |
227 { | |
228 return mHeight + mRowSpacing; | |
229 } | |
230 | |
231 int ImageFont::drawGlyph(Graphics* graphics, | |
232 unsigned char glyph, | |
233 int x, int y) | |
234 { | |
235 // This is needed for drawing the glyph in the middle | |
236 // if we have spacing. | |
237 int yoffset = getRowSpacing() / 2; | |
238 | |
239 if (mGlyph[glyph].width == 0) | |
240 { | |
241 graphics->drawRectangle(Rectangle(x, | |
242 y + 1 + yoffset, | |
243 mGlyph[(int)(' ')].width - 1, | |
244 mGlyph[(int)(' ')].height - 2)); | |
245 | |
246 return mGlyph[(int)(' ')].width + mGlyphSpacing; | |
247 } | |
248 | |
249 graphics->drawImage(mImage, | |
250 mGlyph[glyph].x, | |
251 mGlyph[glyph].y, | |
252 x, | |
253 y + yoffset, | |
254 mGlyph[glyph].width, | |
255 mGlyph[glyph].height); | |
256 | |
257 return mGlyph[glyph].width + mGlyphSpacing; | |
258 } | |
259 | |
260 void ImageFont::drawString(Graphics* graphics, | |
261 const std::string& text, | |
262 int x, | |
263 int y) | |
264 { | |
265 unsigned int i; | |
266 | |
267 for (i = 0; i < text.size(); ++i) | |
268 { | |
269 drawGlyph(graphics, text.at(i), x, y); | |
270 x += getWidth(text.at(i)); | |
271 } | |
272 } | |
273 | |
274 void ImageFont::setRowSpacing(int spacing) | |
275 { | |
276 mRowSpacing = spacing; | |
277 } | |
278 | |
279 int ImageFont::getRowSpacing() | |
280 { | |
281 return mRowSpacing; | |
282 } | |
283 | |
284 void ImageFont::setGlyphSpacing(int spacing) | |
285 { | |
286 mGlyphSpacing = spacing; | |
287 } | |
288 | |
289 int ImageFont::getGlyphSpacing() | |
290 { | |
291 return mGlyphSpacing; | |
292 } | |
293 | |
294 Rectangle ImageFont::scanForGlyph(unsigned char glyph, | |
295 int x, | |
296 int y, | |
297 const Color& separator) | |
298 { | |
299 Color color; | |
300 do | |
301 { | |
302 ++x; | |
303 | |
304 if (x >= mImage->getWidth()) | |
305 { | |
306 y += mHeight + 1; | |
307 x = 0; | |
308 | |
309 if (y >= mImage->getHeight()) | |
310 { | |
311 std::string str; | |
312 std::ostringstream os(str); | |
313 os << "Image "; | |
314 os << mFilename; | |
315 os << " with font is corrupt near character '"; | |
316 os << glyph; | |
317 os << "'"; | |
318 throw GCN_EXCEPTION(os.str()); | |
319 } | |
320 } | |
321 | |
322 color = mImage->getPixel(x, y); | |
323 | |
324 } while (color == separator); | |
325 | |
326 int width = 0; | |
327 | |
328 do | |
329 { | |
330 ++width; | |
331 | |
332 if (x + width >= mImage->getWidth()) | |
333 { | |
334 std::string str; | |
335 std::ostringstream os(str); | |
336 os << "Image "; | |
337 os << mFilename; | |
338 os << " with font is corrupt near character '"; | |
339 os << glyph; | |
340 os << "'"; | |
341 throw GCN_EXCEPTION(os.str()); | |
342 } | |
343 | |
344 color = mImage->getPixel(x + width, y); | |
345 | |
346 } while (color != separator); | |
347 | |
348 return Rectangle(x, y, width, mHeight); | |
349 } | |
350 | |
351 int ImageFont::getWidth(const std::string& text) const | |
352 { | |
353 unsigned int i; | |
354 int size = 0; | |
355 | |
356 for (i = 0; i < text.size(); ++i) | |
357 { | |
358 size += getWidth(text.at(i)); | |
359 } | |
360 | |
361 return size - mGlyphSpacing; | |
362 } | |
363 | |
364 int ImageFont::getStringIndexAt(const std::string& text, int x) | |
365 { | |
366 unsigned int i; | |
367 int size = 0; | |
368 | |
369 for (i = 0; i < text.size(); ++i) | |
370 { | |
371 size += getWidth(text.at(i)); | |
372 | |
373 if (size > x) | |
374 { | |
375 return i; | |
376 } | |
377 } | |
378 | |
379 return text.size(); | |
380 } | |
381 } |