Angel 3.2
A 2D Game Prototyping Engine
TextActor.cpp
1 
2 // Copyright (C) 2008-2013, Shane Liesegang
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of the copyright holder nor the names of any
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "stdafx.h"
31 #include "../Actors/TextActor.h"
32 
33 #include "../Infrastructure/TextRendering.h"
34 #include "../Infrastructure/Camera.h"
35 #include "../Util/StringUtil.h"
36 #include "../Util/MathUtil.h"
37 #include "../Messaging/Switchboard.h"
38 #include "../Util/DrawUtil.h"
39 
40 TextActor::TextActor(const String& fontNickname, const String& displayString, TextAlignment align, int lineSpacing)
41 {
42  SetColor(0.0f, 0.0f, 0.0f); //default text is black
43  _fontNickname = fontNickname;
44  _alignment = align;
45  _lineSpacing = lineSpacing;
46  _screenPosition = Vector2::Zero;
47  _extents.Min = Vector2::Zero;
48  _extents.Max = Vector2::Zero;
49 
50  SetDisplayString(displayString);
51 
52  theSwitchboard.SubscribeTo(this, "CameraChange");
53 }
54 
56 {
57  glColor4f(_color.R, _color.G, _color.B, _color.A);
58  for(unsigned int i=0; i < _displayStrings.size(); i++)
59  {
60  DrawGameText(_displayStrings[i]._string, _fontNickname, (int)_displayStrings[i]._position.X, (int)_displayStrings[i]._position.Y, _rotation + theCamera.GetRotation());
61  }
62 }
63 
64 const String& TextActor::GetFont() const
65 {
66  return _fontNickname;
67 }
68 
69 void TextActor::SetFont(const String& newFont)
70 {
71  _fontNickname = newFont;
72  CalculatePosition();
73 }
74 
75 const String& TextActor::GetDisplayString() const
76 {
77  return _rawString;
78 }
79 
80 void TextActor::SetDisplayString(const String& newString)
81 {
82  _rawString = newString;
83  _displayStrings.clear();
84  StringList strings = SplitString(_rawString, "\n", false);
85  StringList::iterator it = strings.begin();
86  while(it!= strings.end())
87  {
88  TextNugget nugget;
89  nugget._string = *it;
90  _displayStrings.push_back(nugget);
91  it++;
92  }
93 
94  CalculatePosition();
95 }
96 
98 {
99  return _alignment;
100 }
101 
103 {
104  _alignment = newAlignment;
105  CalculatePosition();
106 }
107 
109 {
110  return _lineSpacing;
111 }
112 
113 void TextActor::SetLineSpacing(int newSpacing)
114 {
115  _lineSpacing = newSpacing;
116  CalculatePosition();
117 }
118 
119 void TextActor::SetPosition(float x, float y)
120 {
121  Actor::SetPosition(x, y);
122  CalculatePosition();
123 }
124 
125 void TextActor::SetRotation(float newRotation)
126 {
127  Actor::SetRotation(newRotation);
128  CalculatePosition();
129 }
130 
131 void TextActor::SetPosition(const Vector2& position)
132 {
133  Actor::SetPosition(position);
134  CalculatePosition();
135 }
136 
138 {
139  if (m->GetMessageName() == "CameraChange")
140  {
141  CalculatePosition();
142  }
143 }
144 
146 {
147  return _extents;
148 }
149 
150 void TextActor::CalculatePosition()
151 {
152  Vector2 largest = Vector2::Zero;
153  std::vector<TextNugget>::iterator it = _displayStrings.begin();
154  while(it != _displayStrings.end())
155  {
156  (*it)._extents = GetTextExtents((*it)._string, _fontNickname);
157  if ((*it)._extents.X > largest.X)
158  {
159  largest.X = (*it)._extents.X;
160  }
161  if ((*it)._extents.Y > largest.Y)
162  {
163  largest.Y = (*it)._extents.Y;
164  }
165 
166  it++;
167  }
168 
170  Vector2 currentPoint(startPoint.X, startPoint.Y);
171 
172  it = _displayStrings.begin();
173  while(it != _displayStrings.end())
174  {
175  Vector2 size;
176  switch(_alignment)
177  {
178  case TXT_Left:
179  (*it)._position = currentPoint;
180  break;
181  case TXT_Center:
182  (*it)._position =
183  currentPoint +
184  Vector2::Rotate(Vector2(-(*it)._extents.X * 0.5f, 0.0f), -MathUtil::ToRadians(GetRotation() + theCamera.GetRotation()));
185  break;
186  case TXT_Right:
187  (*it)._position =
188  currentPoint +
189  Vector2::Rotate(Vector2(-(*it)._extents.X, 0.0f), -MathUtil::ToRadians(GetRotation() + theCamera.GetRotation()));
190  break;
191  }
192 
193  Vector2 translation(0.0f, largest.Y + _lineSpacing);
194  currentPoint += Vector2::Rotate(translation, -MathUtil::ToRadians(GetRotation() + theCamera.GetRotation()));
195  it++;
196  }
197 
198  //recalculate extents
199  float minX, minY, maxX, maxY;
200  switch(_alignment)
201  {
202  case TXT_Left:
203  minX = _position.X;
204  minY = _position.Y - (MathUtil::PixelsToWorldUnits(largest.Y + _lineSpacing) * (_displayStrings.size() - 1));
205  maxX = _position.X + MathUtil::PixelsToWorldUnits(largest.X);
206  maxY = _position.Y + MathUtil::PixelsToWorldUnits(largest.Y);
207  _extents.Min = Vector2(minX, minY);
208  _extents.Max = Vector2(maxX, maxY);
209  break;
210  case TXT_Center:
211  minX = _position.X - (MathUtil::PixelsToWorldUnits(largest.X) * 0.5f);
212  minY = _position.Y - (MathUtil::PixelsToWorldUnits(largest.Y + _lineSpacing) * (_displayStrings.size() - 1));
213  maxX = _position.X + (MathUtil::PixelsToWorldUnits(largest.X) * 0.5f);
214  maxY = _position.Y + MathUtil::PixelsToWorldUnits(largest.Y);
215  _extents.Min = Vector2(minX, minY);
216  _extents.Max = Vector2(maxX, maxY);
217  break;
218  case TXT_Right:
219  minX = _position.X - MathUtil::PixelsToWorldUnits(largest.X);
220  minY = _position.Y - (MathUtil::PixelsToWorldUnits(largest.Y + _lineSpacing) * (_displayStrings.size() - 1));
221  maxX = _position.X;
222  maxY = _position.Y + MathUtil::PixelsToWorldUnits(largest.Y);
223  _extents.Min = Vector2(minX, minY);
224  _extents.Max = Vector2(maxX, maxY);
225  break;
226  }
227 }