1
0
mirror of https://github.com/Halofreak1990/XFXFramework synced 2024-12-26 13:49:34 +01:00
XFXFramework/src/libXFX/SpriteFont.cpp

163 lines
5.3 KiB
C++
Raw Normal View History

// Copyright (C) 2010-2012, XFX Team
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the copyright holder nor the names of any
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <Graphics/SpriteBatch.h>
#include <Graphics/SpriteFont.h>
#include <Matrix.h>
#include <System/Array.h>
#include <System/Exception.h>
#include <System/Math.h>
namespace XFX
{
namespace Graphics
{
SpriteFont::SpriteFont(Texture2D texture, List<Rectangle> glyphs, List<Rectangle> cropping, List<char> charMap, int lineSpacing, float spacing, List<Vector3> kerning)
{
textureValue = texture;
glyphData = glyphs;
croppingData = cropping;
characterMap = charMap;
this->lineSpacing = lineSpacing;
this->spacing = spacing;
this->kerning = kerning;
}
void SpriteFont::Draw(char* text, SpriteBatch spriteBatch, Vector2 textblockPosition, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects_t spriteEffects, float depth)
{
Vector2 vector2;
Matrix matrix;
Matrix matrix2;
if (text == null)
throw ArgumentNullException("text");
Matrix::CreateRotationZ(rotation, matrix2);
Matrix::CreateTranslation(-origin.X * scale.X, -origin.Y * scale.Y, 0.0f, matrix);
Matrix::Multiply(matrix, matrix2, matrix2);
int num2 = 1;
float num4 = 0.0f;
bool flag = true;
if ((spriteEffects & SpriteEffects::FlipHorizontally) == SpriteEffects::FlipHorizontally)
{
num4 = MeasureString(text).X * scale.X;
num2 = -1;
}
if ((spriteEffects & SpriteEffects::FlipVertically) == SpriteEffects::FlipVertically)
{
vector2.Y = (MeasureString(text).Y - lineSpacing) * scale.Y;
}
else
{
vector2.Y = 0.0f;
}
vector2.X = num4;
for (int i = 0; i < Array::Length(text); i++)
{
char character = text[i];
switch (character)
{
case '\r':
break;
case '\n':
flag = true;
vector2.X = num4;
if ((spriteEffects & SpriteEffects::FlipVertically) == SpriteEffects::FlipVertically)
{
vector2.Y -= lineSpacing * scale.Y;
}
else
{
vector2.Y += lineSpacing * scale.Y;
}
break;
default:
{
int indexForCharacter = GetIndexForCharacter(character);
Vector3 vector3 = kerning[indexForCharacter];
if (flag)
{
vector3.X = Math::Max(vector3.X, 0.0f);
}
else
{
vector2.X += (spacing * scale.X) * num2;
}
vector2.X += (vector3.X * scale.X) * num2;
Rectangle rectangle = glyphData[indexForCharacter];
Rectangle rectangle2 = croppingData[indexForCharacter];
if ((spriteEffects & SpriteEffects::FlipVertically) == SpriteEffects::FlipVertically)
{
rectangle2.Y = (lineSpacing - rectangle.Height) - rectangle2.Y;
}
if ((spriteEffects & SpriteEffects::FlipHorizontally) == SpriteEffects::FlipHorizontally)
{
rectangle2.X -= rectangle2.Width;
}
Vector2 position = vector2;
position.X += rectangle2.X * scale.X;
position.Y += rectangle2.Y * scale.Y;
Vector2::Transform(position, matrix2, position);
position.X += textblockPosition.X;
position.Y += textblockPosition.Y;
spriteBatch.Draw(textureValue, position, rectangle, color, rotation, Vector2::Zero, scale, spriteEffects, depth);
flag = false;
vector2.X += ((vector3.Y + vector3.Z) * scale.X) * num2;
break;
}
}
}
}
int SpriteFont::GetIndexForCharacter(char character)
{
int num2 = 0;
int num3 = characterMap.Count() - 1;
while (num2 <= num3)
{
int num = num2 + ((num3 - num2) >> 1);
char ch = characterMap[num];
if (ch == character)
{
return num;
}
if (ch < character)
{
num2 = num + 1;
}
else
{
num3 = num - 1;
}
}
throw ArgumentException("character");
}
}
}