Changed the internal storage of pixels in sf::Image (vector<Color> --> vector<Uint8>)

Changed the Glyph structure to allow using sprites to display glyphs

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1473 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
LaurentGom 2010-03-19 16:06:18 +00:00
parent dcdf39bf74
commit 6b23d15a14
10 changed files with 124 additions and 132 deletions

View File

@ -37,8 +37,8 @@
typedef struct
{
int Advance; ///< Offset to move horizontically to the next character
sfIntRect Rectangle; ///< Bounding rectangle of the glyph, in relative coordinates
sfFloatRect TexCoords; ///< Texture coordinates of the glyph inside the bitmap font
sfIntRect Bounds; ///< Bounding rectangle of the glyph, in coordinates relative to the baseline
sfIntRect SubRect; ///< Texture coordinates of the glyph inside the font's image
} sfGlyph;

View File

@ -93,14 +93,14 @@ sfGlyph sfFont_GetGlyph(sfFont* font, sfUint32 codePoint, unsigned int character
sf::Glyph SFMLGlyph = font->This.GetGlyph(codePoint, characterSize, bold == sfTrue);
glyph.Advance = SFMLGlyph.Advance;
glyph.Rectangle.Left = SFMLGlyph.Rectangle.Left;
glyph.Rectangle.Top = SFMLGlyph.Rectangle.Top;
glyph.Rectangle.Right = SFMLGlyph.Rectangle.Right;
glyph.Rectangle.Bottom = SFMLGlyph.Rectangle.Bottom;
glyph.TexCoords.Left = SFMLGlyph.TexCoords.Left;
glyph.TexCoords.Top = SFMLGlyph.TexCoords.Top;
glyph.TexCoords.Right = SFMLGlyph.TexCoords.Right;
glyph.TexCoords.Bottom = SFMLGlyph.TexCoords.Bottom;
glyph.Bounds.Left = SFMLGlyph.Bounds.Left;
glyph.Bounds.Top = SFMLGlyph.Bounds.Top;
glyph.Bounds.Right = SFMLGlyph.Bounds.Right;
glyph.Bounds.Bottom = SFMLGlyph.Bounds.Bottom;
glyph.SubRect.Left = SFMLGlyph.SubRect.Left;
glyph.SubRect.Top = SFMLGlyph.SubRect.Top;
glyph.SubRect.Right = SFMLGlyph.SubRect.Right;
glyph.SubRect.Bottom = SFMLGlyph.SubRect.Bottom;
return glyph;
}

View File

@ -193,17 +193,6 @@ public :
private :
////////////////////////////////////////////////////////////
/// \brief Structure storing a glyph together with its
/// rectangle in the texture
///
////////////////////////////////////////////////////////////
struct GlyphInfo
{
Glyph GlyphDesc;
IntRect TextureRect;
};
////////////////////////////////////////////////////////////
/// \brief Structure defining a row of glyphs
///
@ -220,7 +209,7 @@ private :
////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////
typedef std::map<Uint32, GlyphInfo> GlyphTable; ///< Table mapping a codepoint to its glyph
typedef std::map<Uint32, Glyph> GlyphTable; ///< Table mapping a codepoint to its glyph
////////////////////////////////////////////////////////////
/// \brief Structure defining a page if glyphs
@ -252,7 +241,7 @@ private :
/// \return The glyph corresponding to \a codePoint and \a characterSize
///
////////////////////////////////////////////////////////////
GlyphInfo LoadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold) const;
Glyph LoadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold) const;
////////////////////////////////////////////////////////////
/// \brief Find a suitable rectangle within the texture for a glyph

View File

@ -51,8 +51,8 @@ public :
// Member data
////////////////////////////////////////////////////////////
int Advance; ///< Offset to move horizontically to the next character
IntRect Rectangle; ///< Bounding rectangle of the glyph, in coordinates relative to the baseline
FloatRect TexCoords; ///< Texture coordinates of the glyph inside the font's image
IntRect Bounds; ///< Bounding rectangle of the glyph, in coordinates relative to the baseline
IntRect SubRect; ///< Texture coordinates of the glyph inside the font's image
};
} // namespace sf

View File

@ -127,11 +127,11 @@ public :
////////////////////////////////////////////////////////////
/// Create transparency mask from a specified colorkey
///
/// \param transparentColor : Color to become transparent
/// \param color : Color to become transparent
/// \param alpha : Alpha value to assign to transparent pixels
///
////////////////////////////////////////////////////////////
void CreateMaskFromColor(const Color& transparentColor, Uint8 alpha = 0);
void CreateMaskFromColor(const Color& color, Uint8 alpha = 0);
////////////////////////////////////////////////////////////
/// Copy pixels from another image onto this one.
@ -178,7 +178,7 @@ public :
/// \return Color of pixel (x, y)
///
////////////////////////////////////////////////////////////
const Color& GetPixel(unsigned int x, unsigned int y) const;
Color GetPixel(unsigned int x, unsigned int y) const;
////////////////////////////////////////////////////////////
/// Get a read-only pointer to the array of pixels (RGBA 8 bits integers components)
@ -338,7 +338,7 @@ private :
////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////
typedef std::vector<Color> ColorArray; ///< Array of colors
typedef std::vector<Uint8> ColorArray; ///< Array of colors
////////////////////////////////////////////////////////////
// Member data

View File

@ -165,13 +165,13 @@ const Glyph& Font::GetGlyph(Uint32 codePoint, unsigned int characterSize, bool b
if (it != glyphs.end())
{
// Found: just return it
return it->second.GlyphDesc;
return it->second;
}
else
{
// Not found: we have to load it
GlyphInfo glyph = LoadGlyph(codePoint, characterSize, bold);
return glyphs.insert(std::make_pair(key, glyph)).first->second.GlyphDesc;
Glyph glyph = LoadGlyph(codePoint, characterSize, bold);
return glyphs.insert(std::make_pair(key, glyph)).first->second;
}
}
@ -303,28 +303,28 @@ void Font::Cleanup()
////////////////////////////////////////////////////////////
Font::GlyphInfo Font::LoadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold) const
Glyph Font::LoadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold) const
{
// The glyph to return
GlyphInfo glyphInfo;
Glyph glyph;
// First, transform our ugly void* to a FT_Face
FT_Face face = static_cast<FT_Face>(myFace);
if (!face)
return glyphInfo;
return glyph;
// Set the character size
if (!SetCurrentSize(characterSize))
return glyphInfo;
return glyph;
// Load the glyph corresponding to the code point
if (FT_Load_Char(face, codePoint, FT_LOAD_TARGET_NORMAL) != 0)
return glyphInfo;
return glyph;
// Retrieve the glyph
FT_Glyph glyphDesc;
if (FT_Get_Glyph(face->glyph, &glyphDesc) != 0)
return glyphInfo;
return glyph;
// Apply bold if necessary -- first technique using outline (highest quality)
FT_Pos weight = 1 << 6;
@ -347,9 +347,9 @@ Font::GlyphInfo Font::LoadGlyph(Uint32 codePoint, unsigned int characterSize, bo
}
// Compute the glyph's advance offset
glyphInfo.GlyphDesc.Advance = glyphDesc->advance.x >> 16;
glyph.Advance = glyphDesc->advance.x >> 16;
if (bold)
glyphInfo.GlyphDesc.Advance += weight >> 6;
glyph.Advance += weight >> 6;
int width = bitmap.width;
int height = bitmap.rows;
@ -363,14 +363,13 @@ Font::GlyphInfo Font::LoadGlyph(Uint32 codePoint, unsigned int characterSize, bo
Page& page = myPages[characterSize];
// Find a good position for the new glyph into the texture
glyphInfo.TextureRect = FindGlyphRect(page, width + 2 * padding, height + 2 * padding);
glyph.SubRect = FindGlyphRect(page, width + 2 * padding, height + 2 * padding);
// Compute the glyph's texture coordinates and bounding box
glyphInfo.GlyphDesc.TexCoords = page.Texture.GetTexCoords(glyphInfo.TextureRect);
glyphInfo.GlyphDesc.Rectangle.Left = bitmapGlyph->left - padding;
glyphInfo.GlyphDesc.Rectangle.Top = -bitmapGlyph->top - padding;
glyphInfo.GlyphDesc.Rectangle.Right = bitmapGlyph->left + width + padding;
glyphInfo.GlyphDesc.Rectangle.Bottom = -bitmapGlyph->top + height + padding;
// Compute the glyph's bounding box
glyph.Bounds.Left = bitmapGlyph->left - padding;
glyph.Bounds.Top = -bitmapGlyph->top - padding;
glyph.Bounds.Right = bitmapGlyph->left + width + padding;
glyph.Bounds.Bottom = -bitmapGlyph->top + height + padding;
// Extract the glyph's pixels from the bitmap
myPixelBuffer.resize(width * height * 4, 255);
@ -390,7 +389,7 @@ Font::GlyphInfo Font::LoadGlyph(Uint32 codePoint, unsigned int characterSize, bo
}
// Write the pixels to the texture
IntRect subrect = glyphInfo.TextureRect;
IntRect subrect = glyph.SubRect;
subrect.Left += padding;
subrect.Top += padding;
subrect.Right -= padding;
@ -402,7 +401,7 @@ Font::GlyphInfo Font::LoadGlyph(Uint32 codePoint, unsigned int characterSize, bo
FT_Done_Glyph(glyphDesc);
// Done :)
return glyphInfo;
return glyph;
}
@ -450,12 +449,6 @@ IntRect Font::FindGlyphRect(Page& page, unsigned int width, unsigned int height)
memcpy(&pixels[0], page.Texture.GetPixelsPtr(), size);
page.Texture.Create(textureWidth * 2, textureHeight * 2, Color(255, 255, 255, 0));
page.Texture.UpdatePixels(&pixels[0], IntRect(0, 0, textureWidth, textureHeight));
// Adjust the texture coordinates of all the glyphs that are stored in this page
for (GlyphTable::iterator it = page.Glyphs.begin(); it != page.Glyphs.end(); ++it)
{
it->second.GlyphDesc.TexCoords = page.Texture.GetTexCoords(it->second.TextureRect);
}
}
else
{

View File

@ -154,8 +154,8 @@ bool Image::LoadFromPixels(unsigned int width, unsigned int height, const Uint8*
myHeight = height;
// Fill the pixel buffer with the specified raw data
const Color* ptr = reinterpret_cast<const Color*>(data);
myPixels.assign(ptr, ptr + width * height);
myPixels.resize(width * height * 4);
memcpy(&myPixels[0], data, myPixels.size());
// We can create the texture
if (CreateTexture())
@ -199,9 +199,19 @@ bool Image::Create(unsigned int width, unsigned int height, const Color& color)
myWidth = width;
myHeight = height;
// Recreate the pixel buffer and fill it with the specified color
myPixels.clear();
myPixels.resize(width * height, color);
// Resize the pixel buffer
myPixels.resize(myWidth * myHeight * 4);
// Fill it with the specified color
Uint8* p = &myPixels[0];
Uint8* end = p + myWidth * myHeight * 4;
while (p < end)
{
*p++ = color.r;
*p++ = color.g;
*p++ = color.b;
*p++ = color.a;
}
// We can create the texture
if (CreateTexture())
@ -220,16 +230,24 @@ bool Image::Create(unsigned int width, unsigned int height, const Color& color)
////////////////////////////////////////////////////////////
/// Create transparency mask from a specified colorkey
////////////////////////////////////////////////////////////
void Image::CreateMaskFromColor(const Color& transparentColor, Uint8 alpha)
void Image::CreateMaskFromColor(const Color& color, Uint8 alpha)
{
// No pixels to replace
if (myPixels.empty())
return;
// Check if the array of pixels needs to be updated
EnsureArrayUpdate();
// Calculate the new color (old color with no alpha)
Color newColor(transparentColor.r, transparentColor.g, transparentColor.b, alpha);
// Replace the old color with the new one
std::replace(myPixels.begin(), myPixels.end(), transparentColor, newColor);
// Replace the alpha of the pixels that match the transparent color
Uint8* p = &myPixels[0];
Uint8* end = p + myWidth * myHeight * 4;
while (p < end)
{
if ((p[0] == color.r) && (p[1] == color.g) && (p[2] == color.b) && (p[3] == color.a))
p[3] = alpha;
p += 4;
}
// The texture will need to be updated
myTextureUpdated = false;
@ -283,8 +301,8 @@ void Image::Copy(const Image& source, unsigned int destX, unsigned int destY, co
int rows = height;
int srcStride = source.myWidth * 4;
int dstStride = myWidth * 4;
const Uint8* srcPixels = source.GetPixelsPtr() + (srcRect.Left + srcRect.Top * source.myWidth) * 4;
Uint8* dstPixels = reinterpret_cast<Uint8*>(&myPixels[0]) + (destX + destY * myWidth) * 4;
const Uint8* srcPixels = &source.myPixels[0] + (srcRect.Left + srcRect.Top * source.myWidth) * 4;
Uint8* dstPixels = &myPixels[0] + (destX + destY * myWidth) * 4;
// Copy the pixels
if (applyAlpha)
@ -386,15 +404,12 @@ void Image::SetPixel(unsigned int x, unsigned int y, const Color& color)
// First check if the array of pixels needs to be updated
EnsureArrayUpdate();
// Check if pixel is whithin the image bounds
/*if ((x >= myWidth) || (y >= myHeight))
{
Err() << "Cannot set pixel (" << x << "," << y << ") for image "
<< "(width = " << myWidth << ", height = " << myHeight << ")" << std::endl;
return;
}*/
myPixels[x + y * myWidth] = color;
// Copy the color components
Uint8* pixel = &myPixels[(x + y * myWidth) * 4];
*pixel++ = color.r;
*pixel++ = color.g;
*pixel++ = color.b;
*pixel++ = color.a;
// The texture will need to be updated
myTextureUpdated = false;
@ -404,20 +419,15 @@ void Image::SetPixel(unsigned int x, unsigned int y, const Color& color)
////////////////////////////////////////////////////////////
/// Get a pixel from the image
////////////////////////////////////////////////////////////
const Color& Image::GetPixel(unsigned int x, unsigned int y) const
Color Image::GetPixel(unsigned int x, unsigned int y) const
{
// First check if the array of pixels needs to be updated
EnsureArrayUpdate();
// Check if pixel is whithin the image bounds
if ((x >= myWidth) || (y >= myHeight))
{
Err() << "Cannot get pixel (" << x << "," << y << ") for image "
<< "(width = " << myWidth << ", height = " << myHeight << ")" << std::endl;
return Color::Black;
}
// Get the color at (x, y)
const Uint8* pixel = &myPixels[(x + y * myWidth) * 4];
return myPixels[x + y * myWidth];
return Color(pixel[0], pixel[1], pixel[2], pixel[3]);
}
@ -433,7 +443,7 @@ const Uint8* Image::GetPixelsPtr() const
if (!myPixels.empty())
{
return reinterpret_cast<const Uint8*>(&myPixels[0]);
return &myPixels[0];
}
else
{
@ -728,7 +738,7 @@ void Image::EnsureArrayUpdate() const
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
// Resize the destination array of pixels
myPixels.resize(myWidth * myHeight);
myPixels.resize(myWidth * myHeight * 4);
if ((myWidth == myTextureWidth) && (myHeight == myTextureHeight) && !myPixelsFlipped)
{
@ -743,27 +753,28 @@ void Image::EnsureArrayUpdate() const
// Texture and array don't have the same size, we have to use a slower algorithm
// All the pixels will first be copied to a temporary array
ColorArray allPixels(myTextureWidth * myTextureHeight);
ColorArray allPixels(myTextureWidth * myTextureHeight * 4);
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
GLCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &allPixels[0]));
// Then we copy the useful pixels from the temporary array to the final one
const Color* src = &allPixels[0];
Color* dst = &myPixels[0];
int srcPitch = myTextureWidth;
const Uint8* src = &allPixels[0];
Uint8* dst = &myPixels[0];
int srcPitch = myTextureWidth * 4;
int dstPitch = myWidth * 4;
// Handle the case where source pixels are flipped vertically
if (myPixelsFlipped)
{
src += myTextureWidth * (myHeight - 1);
src += srcPitch * (myHeight - 1);
srcPitch = -srcPitch;
}
for (unsigned int i = 0; i < myHeight; ++i)
{
std::copy(src, src + myWidth, dst);
memcpy(dst, src, dstPitch);
src += srcPitch;
dst += myWidth;
dst += dstPitch;
}
}

View File

@ -85,7 +85,7 @@ ImageLoader::~ImageLoader()
////////////////////////////////////////////////////////////
/// Load pixels from an image file
////////////////////////////////////////////////////////////
bool ImageLoader::LoadImageFromFile(const std::string& filename, std::vector<Color>& pixels, unsigned int& width, unsigned int& height)
bool ImageLoader::LoadImageFromFile(const std::string& filename, std::vector<Uint8>& pixels, unsigned int& width, unsigned int& height)
{
// Clear the array (just in case)
pixels.clear();
@ -101,8 +101,8 @@ bool ImageLoader::LoadImageFromFile(const std::string& filename, std::vector<Col
height = imgHeight;
// Copy the loaded pixels to the pixel buffer
pixels.resize(width * height);
memcpy(&pixels[0], ptr, width * height * 4);
pixels.resize(width * height * 4);
memcpy(&pixels[0], ptr, pixels.size());
// Free the loaded pixels (they are now in our own pixel buffer)
SOIL_free_image_data(ptr);
@ -122,13 +122,13 @@ bool ImageLoader::LoadImageFromFile(const std::string& filename, std::vector<Col
////////////////////////////////////////////////////////////
/// Load pixels from an image file in memory
////////////////////////////////////////////////////////////
bool ImageLoader::LoadImageFromMemory(const void* data, std::size_t sizeInBytes, std::vector<Color>& pixels, unsigned int& width, unsigned int& height)
bool ImageLoader::LoadImageFromMemory(const void* data, std::size_t sizeInBytes, std::vector<Uint8>& pixels, unsigned int& width, unsigned int& height)
{
// Clear the array (just in case)
pixels.clear();
// Load the image and get a pointer to the pixels in memory
const unsigned char* buffer = reinterpret_cast<const unsigned char*>(data);
const unsigned char* buffer = static_cast<const unsigned char*>(data);
int size = static_cast<int>(sizeInBytes);
int imgWidth, imgHeight, imgChannels;
unsigned char* ptr = SOIL_load_image_from_memory(buffer, size, &imgWidth, &imgHeight, &imgChannels, SOIL_LOAD_RGBA);
@ -140,8 +140,8 @@ bool ImageLoader::LoadImageFromMemory(const void* data, std::size_t sizeInBytes,
height = imgHeight;
// Copy the loaded pixels to the pixel buffer
pixels.resize(width * height);
memcpy(&pixels[0], ptr, width * height * 4);
pixels.resize(width * height * 4);
memcpy(&pixels[0], ptr, pixels.size());
// Free the loaded pixels (they are now in our own pixel buffer)
SOIL_free_image_data(ptr);
@ -161,7 +161,7 @@ bool ImageLoader::LoadImageFromMemory(const void* data, std::size_t sizeInBytes,
////////////////////////////////////////////////////////////
/// Save pixels to an image file
////////////////////////////////////////////////////////////
bool ImageLoader::SaveImageToFile(const std::string& filename, const std::vector<Color>& pixels, unsigned int width, unsigned int height)
bool ImageLoader::SaveImageToFile(const std::string& filename, const std::vector<Uint8>& pixels, unsigned int width, unsigned int height)
{
// Deduce the image type from its extension
int type = -1;
@ -185,8 +185,7 @@ bool ImageLoader::SaveImageToFile(const std::string& filename, const std::vector
}
// Finally save the image
const unsigned char* ptr = reinterpret_cast<const unsigned char*>(&pixels[0]);
if (!SOIL_save_image(filename.c_str(), type, static_cast<int>(width), static_cast<int>(height), 4, ptr))
if (!SOIL_save_image(filename.c_str(), type, static_cast<int>(width), static_cast<int>(height), 4, &pixels[0]))
{
// Error, failed to save the image
Err() << "Failed to save image \"" << filename << "\". Reason: " << SOIL_last_result() << std::endl;
@ -200,7 +199,7 @@ bool ImageLoader::SaveImageToFile(const std::string& filename, const std::vector
////////////////////////////////////////////////////////////
/// Save a JPG image file
////////////////////////////////////////////////////////////
bool ImageLoader::WriteJpg(const std::string& filename, const std::vector<Color>& pixels, unsigned int width, unsigned int height)
bool ImageLoader::WriteJpg(const std::string& filename, const std::vector<Uint8>& pixels, unsigned int width, unsigned int height)
{
// Open the file to write in
FILE* file = fopen(filename.c_str(), "wb");
@ -227,11 +226,11 @@ bool ImageLoader::WriteJpg(const std::string& filename, const std::vector<Color>
// Get rid of the aplha channel
std::vector<Uint8> buffer(width * height * 3);
for (std::size_t i = 0; i < pixels.size(); ++i)
for (std::size_t i = 0; i < width * height; ++i)
{
buffer[i * 3 + 0] = pixels[i].r;
buffer[i * 3 + 1] = pixels[i].g;
buffer[i * 3 + 2] = pixels[i].b;
buffer[i * 3 + 0] = pixels[i * 3 + 0];
buffer[i * 3 + 1] = pixels[i * 3 + 1];
buffer[i * 3 + 2] = pixels[i * 3 + 2];
}
Uint8* ptr = &buffer[0];
@ -259,7 +258,7 @@ bool ImageLoader::WriteJpg(const std::string& filename, const std::vector<Color>
////////////////////////////////////////////////////////////
/// Save a PNG image file
////////////////////////////////////////////////////////////
bool ImageLoader::WritePng(const std::string& filename, const std::vector<Color>& pixels, unsigned int width, unsigned int height)
bool ImageLoader::WritePng(const std::string& filename, const std::vector<Uint8>& pixels, unsigned int width, unsigned int height)
{
// Open the file to write in
FILE* file = fopen(filename.c_str(), "wb");

View File

@ -28,7 +28,6 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/Color.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <string>
#include <vector>
@ -65,7 +64,7 @@ public :
/// \return True if loading was successful
///
////////////////////////////////////////////////////////////
bool LoadImageFromFile(const std::string& filename, std::vector<Color>& pixels, unsigned int& width, unsigned int& height);
bool LoadImageFromFile(const std::string& filename, std::vector<Uint8>& pixels, unsigned int& width, unsigned int& height);
////////////////////////////////////////////////////////////
/// Load pixels from an image file in memory
@ -79,7 +78,7 @@ public :
/// \return True if loading was successful
///
////////////////////////////////////////////////////////////
bool LoadImageFromMemory(const void* data, std::size_t sizeInBytes, std::vector<Color>& pixels, unsigned int& width, unsigned int& height);
bool LoadImageFromMemory(const void* data, std::size_t sizeInBytes, std::vector<Uint8>& pixels, unsigned int& width, unsigned int& height);
////////////////////////////////////////////////////////////
/// Save pixels to an image file
@ -92,7 +91,7 @@ public :
/// \return True if saving was successful
///
////////////////////////////////////////////////////////////
bool SaveImageToFile(const std::string& filename, const std::vector<Color>& pixels, unsigned int width, unsigned int height);
bool SaveImageToFile(const std::string& filename, const std::vector<Uint8>& pixels, unsigned int width, unsigned int height);
private :
@ -119,7 +118,7 @@ private :
/// \return True if saving was successful
///
////////////////////////////////////////////////////////////
bool WriteJpg(const std::string& filename, const std::vector<Color>& pixels, unsigned int width, unsigned int height);
bool WriteJpg(const std::string& filename, const std::vector<Uint8>& pixels, unsigned int width, unsigned int height);
////////////////////////////////////////////////////////////
/// Save a PNG image file
@ -132,7 +131,7 @@ private :
/// \return True if saving was successful
///
////////////////////////////////////////////////////////////
bool WritePng(const std::string& filename, const std::vector<Color>& pixels, unsigned int width, unsigned int height);
bool WritePng(const std::string& filename, const std::vector<Uint8>& pixels, unsigned int width, unsigned int height);
};
} // namespace priv

View File

@ -219,7 +219,8 @@ void Text::Render(RenderTarget&, Renderer& renderer) const
return;
// Bind the font texture
renderer.SetTexture(&myFont->GetImage(myCharacterSize));
const Image& texture = myFont->GetImage(myCharacterSize);
renderer.SetTexture(&texture);
// Computes values related to the text style
bool bold = (myStyle & Bold) != 0;
@ -227,7 +228,7 @@ void Text::Render(RenderTarget&, Renderer& renderer) const
float italicCoeff = (myStyle & Italic) ? 0.208f : 0.f; // 12 degrees
float underlineOffset = myCharacterSize * 0.1f;
float underlineThickness = myCharacterSize * (bold ? 0.1f : 0.07f);
FloatRect underlineCoords = myFont->GetImage(myCharacterSize).GetTexCoords(IntRect(1, 1, 1, 1));
FloatRect underlineCoords = texture.GetTexCoords(IntRect(1, 1, 1, 1));
// Initialize the rendering coordinates
float space = static_cast<float>(myFont->GetGlyph(L' ', myCharacterSize, bold).Advance);
@ -273,17 +274,17 @@ void Text::Render(RenderTarget&, Renderer& renderer) const
}
// Extract the current glyph's description
const Glyph& curGlyph = myFont->GetGlyph(curChar, myCharacterSize, bold);
int advance = curGlyph.Advance;
const IntRect& rect = curGlyph.Rectangle;
const FloatRect& coord = curGlyph.TexCoords;
const Glyph& glyph = myFont->GetGlyph(curChar, myCharacterSize, bold);
int advance = glyph.Advance;
const IntRect& bounds = glyph.Bounds;
const FloatRect& coords = texture.GetTexCoords(glyph.SubRect);
// Draw a textured quad for the current character
renderer.Begin(Renderer::QuadList);
renderer.AddVertex(x + rect.Left - italicCoeff * rect.Top, y + rect.Top, coord.Left, coord.Top);
renderer.AddVertex(x + rect.Right - italicCoeff * rect.Top, y + rect.Top, coord.Right, coord.Top);
renderer.AddVertex(x + rect.Right - italicCoeff * rect.Bottom, y + rect.Bottom, coord.Right, coord.Bottom);
renderer.AddVertex(x + rect.Left - italicCoeff * rect.Bottom, y + rect.Bottom, coord.Left, coord.Bottom);
renderer.AddVertex(x + bounds.Left - italicCoeff * bounds.Top, y + bounds.Top, coords.Left, coords.Top);
renderer.AddVertex(x + bounds.Right - italicCoeff * bounds.Top, y + bounds.Top, coords.Right, coords.Top);
renderer.AddVertex(x + bounds.Right - italicCoeff * bounds.Bottom, y + bounds.Bottom, coords.Right, coords.Bottom);
renderer.AddVertex(x + bounds.Left - italicCoeff * bounds.Bottom, y + bounds.Bottom, coords.Left, coords.Bottom);
renderer.End();
// Advance to the next character
@ -374,7 +375,7 @@ void Text::UpdateRect() const
curWidth += static_cast<float>(curGlyph.Advance);
// Update the maximum height
float charHeight = charSize + curGlyph.Rectangle.Bottom;
float charHeight = charSize + curGlyph.Bounds.Bottom;
if (charHeight > curHeight)
curHeight = charHeight;
}