diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/core/video/fonts/fontbase.cpp	Sun Jun 29 18:44:17 2008 +0000
@@ -0,0 +1,209 @@
+/***************************************************************************
+ *   Copyright (C) 2005-2008 by the FIFE team                              *
+ *   http://www.fifengine.de                                               *
+ *   This file is part of FIFE.                                            *
+ *                                                                         *
+ *   FIFE 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; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
+ ***************************************************************************/
+
+// Standard C++ library includes
+#include <vector>
+
+// Platform specific includes
+
+// 3rd party library includes
+#include <boost/filesystem/convenience.hpp>
+
+// FIFE includes
+// These includes are split up in two parts, separated by one empty line
+// First block: files included from the FIFE root src directory
+// Second block: files included from the same folder
+#include "util/structures/rect.h"
+#include "util/base/exception.h"
+#include "video/image.h"
+#include "video/renderbackend.h"
+
+#include "fontbase.h"
+
+namespace FIFE {
+
+	FontBase::FontBase():
+			m_pool(),
+			mColor(),
+			mGlyphSpacing(0),
+			mRowSpacing(0),
+			mFilename(""),
+			m_antiAlias(true) {
+	}
+
+	void FontBase::setRowSpacing(int spacing) {
+		mRowSpacing = spacing;
+	}
+
+	int FontBase::getRowSpacing() const {
+		return mRowSpacing;
+	}
+
+	void FontBase::setGlyphSpacing(int spacing) {
+		mGlyphSpacing = spacing;
+	}
+
+	int FontBase::getGlyphSpacing() const {
+		return mGlyphSpacing;
+	}
+
+	void FontBase::setAntiAlias(bool antiAlias) {
+		m_antiAlias = antiAlias;
+	}
+
+	bool FontBase::isAntiAlias() {
+		return m_antiAlias;
+	}
+
+	SDL_Color FontBase::getColor() const {
+		return mColor;
+	}
+
+	int FontBase::getStringIndexAt(const std::string &text, int x) {
+		for (int i = 0; i < static_cast<int>(text.size()); ++i) {
+			if (getWidth(text.substr(0,i)) > x) {
+				return i-1;
+			}
+		}
+		return text.length();
+	}
+
+	Image* FontBase::getAsImage(const std::string& text) {
+		Image* image = m_pool.getRenderedText(this, text);
+		if (!image) {
+			SDL_Surface* textSurface = renderString(text);
+			image = RenderBackend::instance()->createImage(textSurface);
+			m_pool.addRenderedText( this, text, image );
+		}
+		return image;
+	}
+
+	Image* FontBase::getAsImageMultiline(const std::string& text) {
+		Image* image = m_pool.getRenderedText(this, text);
+		if (!image) {
+			std::vector<SDL_Surface*> lines;
+
+			// split text as needed
+			std::string::size_type pos, last_pos = 0;
+			int length = 0;
+			int render_width = 0, render_height = 0;
+			do {
+				pos = text.find("\n", last_pos);
+				if (pos != std::string::npos) {
+					length = pos - last_pos;
+				} else {
+					length = text.size() - last_pos;
+				}
+				std::string sub = text.substr(last_pos, length);
+				SDL_Surface* text_surface = renderString(sub);
+				if (text_surface->w > render_width) {
+					render_width = text_surface->w;
+				}
+				lines.push_back(text_surface);
+				last_pos = pos + 1;
+			} while (pos != std::string::npos);
+			render_height = (getRowSpacing() + getHeight()) * lines.size();
+			SDL_Surface* final_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
+				render_width,render_height,32,
+				RMASK, GMASK, BMASK ,AMASK);
+			if (!final_surface) {
+				std::cerr << "CreateRGBSurface failed: " << SDL_GetError() << "\n";
+				exit(0);
+			}
+			SDL_FillRect(final_surface, 0, 0x00000000);
+			int ypos = 0;
+			for (std::vector<SDL_Surface*>::iterator i = lines.begin(); i != lines.end(); ++i) {
+				SDL_Rect dst_rect = { 0, 0, 0, 0 };
+				dst_rect.y = ypos;
+
+				SDL_SetAlpha(*i,0,SDL_ALPHA_OPAQUE);
+				SDL_BlitSurface(*i,0,final_surface,&dst_rect);
+				ypos += getRowSpacing() + getHeight();
+				SDL_FreeSurface(*i);
+			}
+			image = RenderBackend::instance()->createImage(final_surface);
+			m_pool.addRenderedText(this, text, image);
+		}
+		return image;
+	}
+
+	std::string FontBase::splitTextToWidth (const std::string& text, int render_width) {
+		if (render_width <= 0 || text.empty()) { 
+			return text;
+		}
+		std::string output;
+		std::string line;
+		std::string::size_type pos = 0;
+		std::list<std::pair<size_t,size_t> > break_pos;
+		bool firstLine = true;
+
+		while( pos < text.length() )
+		{
+			break_pos.clear();
+			if( !firstLine ) {
+				line =  "\n";
+			} else {
+				firstLine = false;
+			}
+
+			while( getWidth(line) < render_width && pos < text.length() )
+			{
+				if (text.at(pos) == ' ' && !line.empty())
+					break_pos.push_back( std::make_pair(line.length(),pos) );
+				line.push_back( text.at(pos) );
+				++pos;
+
+				// Special case: Already newlines in string:
+				if( text.at(pos-1) == '\n' ) {
+					if( line[0] == '\n' && line.length() > 1 )
+						line.erase(0);
+					output.append(line);
+					break;
+				}
+			}
+			if( pos >= text.length() )
+				break;
+
+			if( break_pos.empty() ) {
+				// No break position and line length smaller than 2
+				// means the renderwidth is really screwed. Just continue
+				// appending single character lines.
+				if( line.length() <= 1 ) {
+					output.append(line);
+					continue;
+				}
+
+				// We can't do hyphenation here,
+				// so we just retreat one character :-(
+				line.erase(line.length() - 1);
+				--pos;
+			} else {
+				line = line.substr(0,break_pos.back().first);
+				pos = break_pos.back().second + 1;
+			}
+			output.append(line);
+		}
+		if( !line.empty() ) {
+			output.append(line);
+		}
+		return output;
+	}
+}