MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
character.cpp
1 //© Copyright 2010 - 2012 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 
41 #ifndef _uicharacter_cpp
42 #define _uicharacter_cpp
43 
44 #include "UI/character.h"
45 #include "UI/textlayer.h"
46 
47 #include "mathtool.h"
48 
49 namespace Mezzanine
50 {
51  namespace UI
52  {
53  ///////////////////////////////////////////////////////////////////////////////
54  // Character Methods
55 
56  Character::Character(const UInt32& GlyphID, const CharacterTraits& Traits, TextLayer* Creator) :
57  CustomSize(-1,-1),
58  Layer(Creator),
59  CharSprite(NULL),
60  LengthOffset(0),
61  Highlighted(false)
62  {
63  // Assign the style
64  this->CharTraits = Traits;
65 
66  if( CharTraits.CharFont == NULL ) {
67  MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"A Font is not defined in CharacterTraits when it is expected to be during Character initialization.");
68  }
69  this->CharGlyph = CharTraits.CharFont->GetGlyph(GlyphID);
70  }
71 
72  Character::Character(Glyph* CharacterGlyph, TextLayer* Creator) :
73  CustomSize(-1,-1),
74  Layer(Creator),
75  CharGlyph(CharacterGlyph),
76  CharSprite(NULL),
77  LengthOffset(0),
78  Highlighted(false)
79  {
80  // Since none was specified, create a default
83  }
84 
85  Character::Character(Glyph* CharacterGlyph, const CharacterTraits& Traits, TextLayer* Creator) :
86  CustomSize(-1,-1),
87  Layer(Creator),
88  CharGlyph(CharacterGlyph),
89  CharSprite(NULL),
90  LengthOffset(0),
91  Highlighted(false)
92  {
93  // Assign the style
94  this->CharTraits = Traits;
95 
96  if( CharTraits.CharFont != CharGlyph->Font ) {
97  MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Font provided in traits does not match the font defined in provided glyph during Character initialization.");
98  }
99  }
100 
101  Character::Character(Sprite* CharacterSprite, TextLayer* Creator) :
102  CustomSize(-1,-1),
103  Layer(Creator),
104  CharGlyph(NULL),
105  CharSprite(CharacterSprite),
106  LengthOffset(0),
107  Highlighted(false)
108  {
109  // Since none was specified, create a default
110  this->CharTraits.CharFont = NULL;
112  }
113 
114  Character::Character(Sprite* CharacterSprite, const CharacterTraits& Traits, TextLayer* Creator) :
115  CustomSize(-1,-1),
116  Layer(Creator),
117  CharGlyph(NULL),
118  CharSprite(CharacterSprite),
119  LengthOffset(0),
120  Highlighted(false)
121  {
122  // Assign the style
123  this->CharTraits = Traits;
124  }
125 
126  ///////////////////////////////////////////////////////////////////////////////
127  // Utility
128 
130  {
131  if( this->IsCustomSizeSet() ) {
132  return MathTools::Floor( this->CustomSize.X );
133  }else{
134  Real Desired = this->Layer->GetDesiredLineHeight();
135  if( Desired > 0 ) {
136  return MathTools::Floor( ( this->GetUnscaledCharacterAdvance(Prev) * ( Desired / this->GetUnscaledLineHeight() ) ) * this->Layer->GetManualTextScale().X );
137  }else{
138  return MathTools::Floor( this->GetUnscaledCharacterAdvance(Prev) * this->Layer->GetManualTextScale().X );
139  }
140  }
141  }
142 
144  {
145  if( this->IsCustomSizeSet() ) {
146  return MathTools::Floor( this->CustomSize.X );
147  }else if( this->IsGlyph() ) {
148  return this->CharGlyph->GlyphAdvance + ( Prev != NULL ? this->CharGlyph->GetKerning(Prev->GlyphID) : 0 );
149  }else if( this->IsSprite() ) {
150  return this->CharSprite->GetWidth();
151  }
152  return 0;
153  }
154 
156  {
157  Real Desired = this->Layer->GetDesiredLineHeight();
158  if( Desired > 0 ) {
159  return MathTools::Floor( Desired * this->Layer->GetManualTextScale().X );
160  }
161  return MathTools::Floor( this->GetUnscaledLineHeight() * this->Layer->GetManualTextScale().X );
162  }
163 
165  {
166  if( this->IsCustomSizeSet() ) {
167  return this->CustomSize.Y;
168  }else if( this->IsGlyph() ) {
169  return this->CharGlyph->Font->GetLineHeight();
170  }else if( this->IsSprite() ) {
171  return this->CharSprite->GetHeight();
172  }
173  return 0;
174  }
175 
177  {
178  Real Desired = this->Layer->GetDesiredLineHeight();
179  if( Desired > 0 ) {
180  return MathTools::Floor( ( this->GetUnscaledVerticalOffset() * ( Desired / this->GetUnscaledLineHeight() ) ) * this->Layer->GetManualTextScale().X );
181  }
183  }
184 
186  {
187  // If this is a glyph, combine the manual vertical offset for low hanging letters as well as the difference between the baseline and lineheight.
188  // In almost all cases the combined offset should be a positive number, elevating the normal letters and thus making everything more centered.
189  /// @todo If we want to change how normal text is aligned on the Y axis, we need to update this.
190  if( this->IsGlyph() ) {
191  return this->CharGlyph->VerticalOffset;// + (this->CharGlyph->Font->GetLineHeight() - this->CharGlyph->Font->GetBaseLine());
192  }
193  return 0;
194  }
195 
197  {
198  if( this->IsGlyph() ) {
199  return this->CharGlyph->Atlas;
200  }else if( this->IsSprite() ) {
201  return this->CharSprite->Atlas;
202  }else{
203  return NULL;
204  }
205  }
206 
208  {
209  if( this->IsGlyph() ) {
210  return this->CharGlyph->GetAtlasName();
211  }else if( this->IsSprite() ) {
212  return this->CharSprite->GetAtlasName();
213  }
214  }
215 
217  {
218  return this->GetAtlas()->GetWhitePixel();
219  }
220 
222  {
223  if( this->IsGlyph() ) return CharGlyph->GetAtlasCoords(Corner);
224  else if( this->IsSprite() ) return CharSprite->GetAtlasCoords(Corner);
225  else return Vector2();
226  }
227 
229  {
230  if( this->IsGlyph() ) return CharGlyph->GetRelativeAtlasCoords(Corner);
231  else if( this->IsSprite() ) return CharSprite->GetRelativeAtlasCoords(Corner);
232  else return Vector2();
233  }
234 
236  {
237  if( this->CharTraits.CharColour != Colour ) {
238  this->CharTraits.CharColour = Colour;
239 
240  if( !Highlighted )
241  this->Layer->_MarkDirty();
242  }
243  }
244 
246  {
247  return this->CharTraits.CharColour;
248  }
249 
250  void Character::SetHighlighted(Boolean Highlight)
251  {
252  this->Highlighted = ( this->IsHighlightable() && Highlight );
253  }
254 
256  {
257  return this->Highlighted;
258  }
259 
261  {
262  if( this->CharTraits != Traits ) {
263  this->CharTraits = Traits;
264  this->Layer->_MarkDirty();
265  }
266  }
267 
269  {
270  return this->CharTraits;
271  }
272 
273  Boolean Character::IsGlyph() const
274  {
275  return (NULL != this->CharGlyph);
276  }
277 
278  Boolean Character::IsSprite() const
279  {
280  return (NULL != this->CharSprite);
281  }
282 
283  Boolean Character::IsRenderable() const
284  {
285  if( this->CharGlyph && this->CharGlyph->IsWhitespace() ) return false;
286  else return true;
287  }
288 
290  {
291  if( this->CharGlyph && this->CharGlyph->IsNewLine() ) return false;
292  else return true;
293  }
294 
295  Boolean Character::IsWhiteSpace() const
296  {
297  if( this->CharGlyph && this->CharGlyph->IsWhitespace() ) return true;
298  else return false;
299  }
300 
301  Boolean Character::IsNewLine() const
302  {
303  if( this->CharGlyph && this->CharGlyph->IsNewLine() ) return true;
304  else return false;
305  }
306 
307  ///////////////////////////////////////////////////////////////////////////////
308  // Transform Related Methods
309 
310  void Character::SetLengthOffset(const Real& Offset)
311  {
312  this->LengthOffset = Offset;
313  }
314 
316  {
317  return this->LengthOffset;
318  }
319 
321  {
322  if( this->CustomSize != Size ) {
323  this->CustomSize = Size;
324  this->Layer->_MarkDirty();
325  }
326  }
327 
329  {
330  const Vector2 Test(-1,-1);
331  return (this->CustomSize != Test);
332  }
333 
335  {
336  Vector2 Ret;
337  if( this->IsCustomSizeSet() ) {
338  Ret = this->CustomSize;
339  }else{
340  Real Desired = this->Layer->GetDesiredLineHeight();
341  if( Desired > 0 ) {
342  Ret = ( ( this->GetUnscaledCharacterSize() * ( Desired / this->GetUnscaledCharacterSize().Y ) ) * this->Layer->GetManualTextScale().X );
343  }else{
344  Ret = ( this->GetUnscaledCharacterSize() * this->Layer->GetManualTextScale().X );
345  }
346  }
347  MathTools::Floor( Ret.X );
348  MathTools::Floor( Ret.Y );
349  return Ret;
350  }
351 
353  {
354  if( this->IsCustomSizeSet() ) {
355  return this->CustomSize;
356  }else if( this->IsGlyph() ) {
357  return this->CharGlyph->GetSize();
358  }else if( this->IsSprite() ) {
359  return this->CharSprite->GetSize();
360  }else{
361  return Vector2();
362  }
363  }
364 
365  ///////////////////////////////////////////////////////////////////////////////
366  // Fetch Methods
367 
369  { return this->CharGlyph; }
370 
372  { return this->CharSprite; }
373  }//UI
374 }//Mezzanine
375 
376 #endif