FIFE  6e1afdbeda11afe9ac53e6023a4be96ef88f1dc6
fontbase.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2017 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library 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 GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, 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 
29 // FIFE includes
30 // These includes are split up in two parts, separated by one empty line
31 // First block: files included from the FIFE root src directory
32 // Second block: files included from the same folder
33 #include "util/structures/rect.h"
34 #include "util/base/exception.h"
35 #include "util/utf8/utf8.h"
36 #include "video/image.h"
37 #include "video/renderbackend.h"
38 
39 #include "fontbase.h"
40 
41 namespace FIFE {
42 
44  m_pool(),
45  mColor(),
46  mGlyphSpacing(0),
47  mRowSpacing(0),
48  mFilename(""),
49  m_antiAlias(true),
50  m_boldStyle(false),
51  m_italicStyle(false),
52  m_underlineStyle(false),
53  m_strikeStyle(false),
54  m_coloring(false) {
55  }
56 
59  }
60 
61  void FontBase::setRowSpacing(int32_t spacing) {
62  mRowSpacing = spacing;
63  }
64 
65  int32_t FontBase::getRowSpacing() const {
66  return mRowSpacing;
67  }
68 
69  void FontBase::setGlyphSpacing(int32_t spacing) {
70  mGlyphSpacing = spacing;
71  }
72 
73  int32_t FontBase::getGlyphSpacing() const {
74  return mGlyphSpacing;
75  }
76 
77  void FontBase::setAntiAlias(bool antiAlias) {
78  m_antiAlias = antiAlias;
79  }
80 
81  bool FontBase::isAntiAlias() const {
82  return m_antiAlias;
83  }
84 
85  void FontBase::setBoldStyle(bool style) {
86  m_boldStyle = style;
87  }
88 
89  bool FontBase::isBoldStyle() const {
90  return m_boldStyle;
91  }
92 
93  void FontBase::setItalicStyle(bool style) {
94  m_italicStyle = style;
95  }
96 
97  bool FontBase::isItalicStyle() const {
98  return m_italicStyle;
99  }
100 
101  void FontBase::setUnderlineStyle(bool style) {
102  m_underlineStyle = style;
103  }
104 
106  return m_underlineStyle;
107  }
108 
110  m_strikeStyle = style;
111  }
112 
114  return m_strikeStyle;
115  }
116 
117  void FontBase::setDynamicColoring(bool coloring) {
118  m_coloring = coloring;
119  }
120 
122  return m_coloring;
123  }
124 
125  SDL_Color FontBase::getColor() const {
126  return mColor;
127  }
128 
129  int32_t FontBase::getStringIndexAt(const std::string &text, int32_t x) const {
130  assert( utf8::is_valid(text.begin(), text.end()) );
131  std::string::const_iterator cur;
132  if (text.size() == 0) return 0;
133  if (x <= 0) return 0;
134 
135  cur = text.begin();
136 
137  utf8::next(cur, text.end());
138 
139  std::string buff;
140  while(cur != text.end()) {
141  buff = std::string(text.begin(), cur);
142 
143  if (getWidth(buff) > x) {
144  return buff.size();
145  } else {
146  utf8::next(cur, text.end());
147  }
148  }
149 
150  if (x > getWidth(text)) {
151  return text.size();
152  } else {
153  return buff.size();
154  }
155  }
156 
157  Image* FontBase::getAsImage(const std::string& text) {
158  Image* image = m_pool.getRenderedText(this, text);
159  if (!image) {
160  SDL_Surface* textSurface = renderString(text);
161  image = RenderBackend::instance()->createImage(textSurface);
162  m_pool.addRenderedText( this, text, image );
163  }
164  return image;
165  }
166 
167  Image* FontBase::getAsImageMultiline(const std::string& text) {
168  const uint8_t newline_utf8 = '\n';
169  uint32_t newline;
170  utf8::utf8to32(&newline_utf8,&newline_utf8 + 1,&newline);
171  //std::cout << "Text:" << text << std::endl;
172  Image* image = m_pool.getRenderedText(this, text);
173  if (!image) {
174  std::vector<SDL_Surface*> lines;
175  std::string::const_iterator it = text.begin();
176  // split text as needed
177  int32_t render_width = 0, render_height = 0;
178  do {
179  uint32_t codepoint = 0;
180  std::string line;
181  while( codepoint != newline && it != text.end() )
182  {
183  codepoint = utf8::next(it,text.end());
184  if( codepoint != newline )
185  utf8::append(codepoint, back_inserter(line));
186  }
187  //std::cout << "Line:" << line << std::endl;
188  SDL_Surface* text_surface = renderString(line);
189  if (text_surface->w > render_width) {
190  render_width = text_surface->w;
191  }
192  lines.push_back(text_surface);
193  } while (it != text.end());
194 
195  render_height = (getRowSpacing() + getHeight()) * lines.size();
196  SDL_Surface* final_surface = SDL_CreateRGBSurface(0,
197  render_width,render_height,32,
198  RMASK, GMASK, BMASK ,AMASK);
199  if (!final_surface) {
200  throw SDLException(std::string("CreateRGBSurface failed: ") + SDL_GetError());
201  }
202  SDL_FillRect(final_surface, 0, 0x00000000);
203  int32_t ypos = 0;
204  for (std::vector<SDL_Surface*>::iterator i = lines.begin(); i != lines.end(); ++i) {
205  SDL_Rect dst_rect = { 0, 0, 0, 0 };
206  dst_rect.y = ypos;
207 
208  // Disable alpha blending
209  //SDL_SetAlpha(*i,0,SDL_ALPHA_OPAQUE);
210  SDL_SetSurfaceBlendMode(*i, SDL_BLENDMODE_NONE);
211  SDL_BlitSurface(*i, 0, final_surface, &dst_rect);
212  ypos += getRowSpacing() + getHeight();
213  SDL_FreeSurface(*i);
214  }
215  image = RenderBackend::instance()->createImage(final_surface);
216  m_pool.addRenderedText(this, text, image);
217  }
218  return image;
219  }
220 
221  std::string FontBase::splitTextToWidth (const std::string& text, int32_t render_width) {
222  const uint32_t whitespace = ' ';
223  const uint8_t newline_utf8 = '\n';
224  uint32_t newline;
225  utf8::utf8to32(&newline_utf8,&newline_utf8 + 1,&newline);
226  if (render_width <= 0 || text.empty()) {
227  return text;
228  }
229  std::string output;
230  std::string line;
231  std::string::const_iterator pos = text.begin();
232  std::list<std::pair<size_t,std::string::const_iterator> > break_pos;
233  bool firstLine = true;
234 
235  while( pos != text.end())
236  {
237  break_pos.clear();
238  if( !firstLine ) {
239  line = "\n";
240  } else {
241  firstLine = false;
242  }
243 
244  bool haveNewLine = false;
245  while( getWidth(line) < render_width && pos != text.end() )
246  {
247  uint32_t codepoint = utf8::next(pos, text.end());
248  if (codepoint == whitespace && !line.empty())
249  break_pos.push_back( std::make_pair(line.length(),pos) );
250 
251  if( codepoint != newline )
252  utf8::append(codepoint, back_inserter(line) );
253 
254  // Special case: Already newlines in string:
255  if( codepoint == newline ) {
256  output.append(line);
257  line = "";
258  haveNewLine = true;
259  break;
260  }
261  }
262  if( haveNewLine )
263  continue;
264 
265  if( pos == text.end() )
266  break;
267 
268  if( break_pos.empty() ) {
269  // No break position and line length smaller than 2
270  // means the renderwidth is really screwed. Just continue
271  // appending single character lines.
272  if( utf8::distance(line.begin(),line.end()) <= 1 && line != "\n") {
273  output.append(line);
274  continue;
275  }
276 
277  if (line == "\n") {
278  ++pos;
279  }
280 
281  // We can't do hyphenation here,
282  // so we just retreat one character :-(
283  // FIXME
284  //line = line.erase(line.length() - 1);
285  //--pos;
286  } else {
287  line = line.substr(0,break_pos.back().first);
288  pos = break_pos.back().second;
289  }
290  output.append(line);
291  }
292  if( !line.empty() ) {
293  output.append(line);
294  }
295  return output;
296  }
297 }
virtual void setUnderlineStyle(bool style)
Sets the use of underline style.
Definition: fontbase.cpp:101
void invalidate()
Definition: fontbase.cpp:57
int32_t getGlyphSpacing() const
Gets the spacing between letters in pixels.
Definition: fontbase.cpp:73
virtual bool isUnderlineStyle() const
Checks if underline style is used.
Definition: fontbase.cpp:105
virtual bool isBoldStyle() const
Checks if bold style is used.
Definition: fontbase.cpp:89
u32bit_iterator utf8to32(octet_iterator start, octet_iterator end, u32bit_iterator result)
Definition: checked.h:258
Base Class for Images.
Definition: image.h:48
int32_t mGlyphSpacing
Definition: fontbase.h:87
uint32_t next(octet_iterator &it, octet_iterator end)
Definition: checked.h:137
void invalidateCachedText()
Invalidates all cached text images.
bool m_coloring
Definition: fontbase.h:96
Image * getAsImageMultiline(const std::string &text)
Gets given text as Image.
Definition: fontbase.cpp:167
const uint32_t RMASK
Definition: fife_stdint.h:53
virtual void setAntiAlias(bool antiAlias)
Sets the use of anti aliasing.
Definition: fontbase.cpp:77
virtual void setStrikethroughStyle(bool style)
Sets the use of strikethrough style.
Definition: fontbase.cpp:109
SDL_Color mColor
Definition: fontbase.h:86
bool m_italicStyle
Definition: fontbase.h:93
const uint32_t AMASK
Definition: fife_stdint.h:56
virtual void setDynamicColoring(bool coloring)
Definition: fontbase.cpp:117
static RenderBackend * instance()
Definition: singleton.h:84
TextRenderPool m_pool
Definition: fontbase.h:84
Image * getRenderedText(FontBase *fontbase, const std::string &text)
Get a string image.
virtual int32_t getStringIndexAt(const std::string &text, int32_t x) const
Definition: fontbase.cpp:129
unsigned char uint8_t
Definition: core.h:38
const uint32_t GMASK
Definition: fife_stdint.h:54
bool is_valid(octet_iterator start, octet_iterator end)
Definition: core.h:300
void setRowSpacing(int32_t spacing)
Sets the spacing between rows in pixels.
Definition: fontbase.cpp:61
virtual void setItalicStyle(bool style)
Sets the use of italic style.
Definition: fontbase.cpp:93
int32_t mRowSpacing
Definition: fontbase.h:88
virtual void setBoldStyle(bool style)
Sets the use of bold style.
Definition: fontbase.cpp:85
void addRenderedText(FontBase *fontbase, const std::string &text, Image *image)
Add a string image.
virtual bool isStrikethroughStyle() const
Checks if strikethrough style is used.
Definition: fontbase.cpp:113
int32_t getRowSpacing() const
Gets the spacing between rows in pixels.
Definition: fontbase.cpp:65
virtual int32_t getHeight() const =0
gets height of this font
bool m_strikeStyle
Definition: fontbase.h:95
Image * getAsImage(const std::string &text)
Gets given text as Image The rsulting image is pooled, so it&#39;s not that time critical.
Definition: fontbase.cpp:157
virtual bool isItalicStyle() const
Checks if italic style is used.
Definition: fontbase.cpp:97
void setGlyphSpacing(int32_t spacing)
Sets the spacing between letters in pixels.
Definition: fontbase.cpp:69
const uint32_t BMASK
Definition: fife_stdint.h:55
std::iterator_traits< octet_iterator >::difference_type distance(octet_iterator first, octet_iterator last)
Definition: checked.h:198
bool m_antiAlias
Definition: fontbase.h:91
bool m_underlineStyle
Definition: fontbase.h:94
std::string splitTextToWidth(const std::string &text, int32_t render_width)
Definition: fontbase.cpp:221
virtual bool isDynamicColoring() const
Definition: fontbase.cpp:121
virtual Image * createImage(IResourceLoader *loader=0)=0
virtual SDL_Surface * renderString(const std::string &text)=0
SDL_Color getColor() const
Get the color the text was rendered in.
Definition: fontbase.cpp:125
unsigned int uint32_t
Definition: core.h:40
virtual bool isAntiAlias() const
Checks if anti aliasing is used.
Definition: fontbase.cpp:81
bool m_boldStyle
Definition: fontbase.h:92
virtual int32_t getWidth(const std::string &text) const =0
gets width of given text
octet_iterator append(uint32_t cp, octet_iterator result)
The library API - functions intended to be called by the users.
Definition: checked.h:73