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:
parent
dcdf39bf74
commit
6b23d15a14
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user