From 58e83056bbc0b7b5603fbb97f59f81f2cfafe2b4 Mon Sep 17 00:00:00 2001 From: kimci86 Date: Sat, 15 Jun 2024 19:46:40 +0200 Subject: [PATCH] Some simplifications taking advantage of Rect position and size members --- examples/island/Island.cpp | 3 +- include/SFML/Graphics/Transform.inl | 25 +++++++--------- src/SFML/Graphics/Font.cpp | 46 ++++++++++++----------------- src/SFML/Graphics/Shape.cpp | 13 ++++---- src/SFML/Graphics/Sprite.cpp | 24 ++++++--------- src/SFML/Graphics/Text.cpp | 46 ++++++++++++----------------- src/SFML/Graphics/Texture.cpp | 12 ++++---- 7 files changed, 71 insertions(+), 98 deletions(-) diff --git a/examples/island/Island.cpp b/examples/island/Island.cpp index e834dfee1..401dc749b 100644 --- a/examples/island/Island.cpp +++ b/examples/island/Island.cpp @@ -152,8 +152,7 @@ int main() } // Center the status text - statusText.setPosition({(windowWidth - statusText.getLocalBounds().size.x) / 2.f, - (windowHeight - statusText.getLocalBounds().size.y) / 2.f}); + statusText.setPosition((sf::Vector2f(windowWidth, windowHeight) - statusText.getLocalBounds().size) / 2.f); // Set up an array of pointers to our settings for arrow navigation constexpr std::array settings = { diff --git a/include/SFML/Graphics/Transform.inl b/include/SFML/Graphics/Transform.inl index dfe3c337c..f6bc856ab 100644 --- a/include/SFML/Graphics/Transform.inl +++ b/include/SFML/Graphics/Transform.inl @@ -104,30 +104,27 @@ constexpr Vector2f Transform::transformPoint(const Vector2f& point) const constexpr FloatRect Transform::transformRect(const FloatRect& rectangle) const { // Transform the 4 corners of the rectangle - const std::array points = {transformPoint({rectangle.position.x, rectangle.position.y}), - transformPoint({rectangle.position.x, rectangle.position.y + rectangle.size.y}), - transformPoint({rectangle.position.x + rectangle.size.x, rectangle.position.y}), - transformPoint( - {rectangle.position.x + rectangle.size.x, rectangle.position.y + rectangle.size.y})}; + const std::array points = {transformPoint(rectangle.position), + transformPoint(rectangle.position + Vector2f(0.f, rectangle.size.y)), + transformPoint(rectangle.position + Vector2f(rectangle.size.x, 0.f)), + transformPoint(rectangle.position + rectangle.size)}; // Compute the bounding rectangle of the transformed points - float left = points[0].x; - float top = points[0].y; - float right = points[0].x; - float bottom = points[0].y; + Vector2f pmin = points[0]; + Vector2f pmax = points[0]; for (std::size_t i = 1; i < points.size(); ++i) { // clang-format off - if (points[i].x < left) left = points[i].x; - else if (points[i].x > right) right = points[i].x; + if (points[i].x < pmin.x) pmin.x = points[i].x; + else if (points[i].x > pmax.x) pmax.x = points[i].x; - if (points[i].y < top) top = points[i].y; - else if (points[i].y > bottom) bottom = points[i].y; + if (points[i].y < pmin.y) pmin.y = points[i].y; + else if (points[i].y > pmax.y) pmax.y = points[i].y; // clang-format on } - return {{left, top}, {right - left, bottom - top}}; + return {pmin, pmax - pmin}; } diff --git a/src/SFML/Graphics/Font.cpp b/src/SFML/Graphics/Font.cpp index 0644ec4f7..47c281504 100644 --- a/src/SFML/Graphics/Font.cpp +++ b/src/SFML/Graphics/Font.cpp @@ -546,42 +546,36 @@ Glyph Font::loadGlyph(std::uint32_t codePoint, unsigned int characterSize, bool glyph.lsbDelta = static_cast(face->glyph->lsb_delta); glyph.rsbDelta = static_cast(face->glyph->rsb_delta); - unsigned int width = bitmap.width; - unsigned int height = bitmap.rows; + Vector2u size(bitmap.width, bitmap.rows); - if ((width > 0) && (height > 0)) + if ((size.x > 0) && (size.y > 0)) { // Leave a small padding around characters, so that filtering doesn't // pollute them with pixels from neighbors const unsigned int padding = 2; - width += 2 * padding; - height += 2 * padding; + size += 2u * Vector2u(padding, padding); // Get the glyphs page corresponding to the character size Page& page = loadPage(characterSize); // Find a good position for the new glyph into the texture - glyph.textureRect = findGlyphRect(page, {width, height}); + glyph.textureRect = findGlyphRect(page, size); // Make sure the texture data is positioned in the center // of the allocated texture rectangle - glyph.textureRect.position.x += static_cast(padding); - glyph.textureRect.position.y += static_cast(padding); - glyph.textureRect.size.x -= static_cast(2 * padding); - glyph.textureRect.size.y -= static_cast(2 * padding); + glyph.textureRect.position += Vector2i(padding, padding); + glyph.textureRect.size -= 2 * Vector2i(padding, padding); // Compute the glyph's bounding box - glyph.bounds.position.x = static_cast(bitmapGlyph->left); - glyph.bounds.position.y = static_cast(-bitmapGlyph->top); - glyph.bounds.size.x = static_cast(bitmap.width); - glyph.bounds.size.y = static_cast(bitmap.rows); + glyph.bounds.position = Vector2f(Vector2i(bitmapGlyph->left, -bitmapGlyph->top)); + glyph.bounds.size = Vector2f(Vector2u(bitmap.width, bitmap.rows)); // Resize the pixel buffer to the new size and fill it with transparent white pixels - m_pixelBuffer.resize(static_cast(width) * static_cast(height) * 4); + m_pixelBuffer.resize(static_cast(size.x) * static_cast(size.y) * 4); std::uint8_t* current = m_pixelBuffer.data(); - std::uint8_t* end = current + width * height * 4; + std::uint8_t* end = current + size.x * size.y * 4; while (current != end) { @@ -596,12 +590,12 @@ Glyph Font::loadGlyph(std::uint32_t codePoint, unsigned int characterSize, bool if (bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { // Pixels are 1 bit monochrome values - for (unsigned int y = padding; y < height - padding; ++y) + for (unsigned int y = padding; y < size.y - padding; ++y) { - for (unsigned int x = padding; x < width - padding; ++x) + for (unsigned int x = padding; x < size.x - padding; ++x) { // The color channels remain white, just fill the alpha channel - const std::size_t index = x + y * width; + const std::size_t index = x + y * size.x; m_pixelBuffer[index * 4 + 3] = ((pixels[(x - padding) / 8]) & (1 << (7 - ((x - padding) % 8)))) ? 255 : 0; } pixels += bitmap.pitch; @@ -610,12 +604,12 @@ Glyph Font::loadGlyph(std::uint32_t codePoint, unsigned int characterSize, bool else { // Pixels are 8 bits gray levels - for (unsigned int y = padding; y < height - padding; ++y) + for (unsigned int y = padding; y < size.y - padding; ++y) { - for (unsigned int x = padding; x < width - padding; ++x) + for (unsigned int x = padding; x < size.x - padding; ++x) { // The color channels remain white, just fill the alpha channel - const std::size_t index = x + y * width; + const std::size_t index = x + y * size.x; m_pixelBuffer[index * 4 + 3] = pixels[x - padding]; } pixels += bitmap.pitch; @@ -623,11 +617,9 @@ Glyph Font::loadGlyph(std::uint32_t codePoint, unsigned int characterSize, bool } // Write the pixels to the texture - const unsigned int x = static_cast(glyph.textureRect.position.x) - padding; - const unsigned int y = static_cast(glyph.textureRect.position.y) - padding; - const unsigned int w = static_cast(glyph.textureRect.size.x) + 2 * padding; - const unsigned int h = static_cast(glyph.textureRect.size.y) + 2 * padding; - page.texture.update(m_pixelBuffer.data(), {w, h}, {x, y}); + const auto dest = Vector2u(glyph.textureRect.position) - Vector2u(padding, padding); + const auto updateSize = Vector2u(glyph.textureRect.size) + 2u * Vector2u(padding, padding); + page.texture.update(m_pixelBuffer.data(), updateSize, dest); } // Delete the FT glyph diff --git a/src/SFML/Graphics/Shape.cpp b/src/SFML/Graphics/Shape.cpp index 34176283f..8f51b6356 100644 --- a/src/SFML/Graphics/Shape.cpp +++ b/src/SFML/Graphics/Shape.cpp @@ -265,15 +265,14 @@ void Shape::updateTexCoords() { const FloatRect convertedTextureRect(m_textureRect); + // Make sure not to divide by zero when the points are aligned on a vertical or horizontal line + const Vector2f safeInsideSize(m_insideBounds.size.x > 0 ? m_insideBounds.size.x : 1.f, + m_insideBounds.size.y > 0 ? m_insideBounds.size.y : 1.f); + for (std::size_t i = 0; i < m_vertices.getVertexCount(); ++i) { - const float xratio = m_insideBounds.size.x > 0 - ? (m_vertices[i].position.x - m_insideBounds.position.x) / m_insideBounds.size.x - : 0; - const float yratio = m_insideBounds.size.y > 0 - ? (m_vertices[i].position.y - m_insideBounds.position.y) / m_insideBounds.size.y - : 0; - m_vertices[i].texCoords = convertedTextureRect.position + convertedTextureRect.size.cwiseMul({xratio, yratio}); + const Vector2f ratio = (m_vertices[i].position - m_insideBounds.position).cwiseDiv(safeInsideSize); + m_vertices[i].texCoords = convertedTextureRect.position + convertedTextureRect.size.cwiseMul(ratio); } } diff --git a/src/SFML/Graphics/Sprite.cpp b/src/SFML/Graphics/Sprite.cpp index 6c8a80645..c4eeeb79a 100644 --- a/src/SFML/Graphics/Sprite.cpp +++ b/src/SFML/Graphics/Sprite.cpp @@ -128,28 +128,22 @@ void Sprite::draw(RenderTarget& target, RenderStates states) const //////////////////////////////////////////////////////////// void Sprite::updateVertices() { - const auto left = static_cast(m_textureRect.position.x); - const auto top = static_cast(m_textureRect.position.y); - const auto width = static_cast(m_textureRect.size.x); - const auto height = static_cast(m_textureRect.size.y); - const auto right = float{left + width}; - const auto bottom = float{top + height}; + const auto [position, size] = FloatRect(m_textureRect); // Absolute value is used to support negative texture rect sizes - const auto absWidth = float{std::abs(width)}; - const auto absHeight = float{std::abs(height)}; + const Vector2f absSize(std::abs(size.x), std::abs(size.y)); // Update positions m_vertices[0].position = {0.f, 0.f}; - m_vertices[1].position = {0.f, absHeight}; - m_vertices[2].position = {absWidth, 0.f}; - m_vertices[3].position = {absWidth, absHeight}; + m_vertices[1].position = {0.f, absSize.y}; + m_vertices[2].position = {absSize.x, 0.f}; + m_vertices[3].position = absSize; // Update texture coordinates - m_vertices[0].texCoords = {left, top}; - m_vertices[1].texCoords = {left, bottom}; - m_vertices[2].texCoords = {right, top}; - m_vertices[3].texCoords = {right, bottom}; + m_vertices[0].texCoords = position; + m_vertices[1].texCoords = position + Vector2f(0.f, size.y); + m_vertices[2].texCoords = position + Vector2f(size.x, 0.f); + m_vertices[3].texCoords = position + size; } } // namespace sf diff --git a/src/SFML/Graphics/Text.cpp b/src/SFML/Graphics/Text.cpp index 78f7c7536..c572edbd0 100644 --- a/src/SFML/Graphics/Text.cpp +++ b/src/SFML/Graphics/Text.cpp @@ -63,24 +63,20 @@ void addLine(sf::VertexArray& vertices, // Add a glyph quad to the vertex array void addGlyphQuad(sf::VertexArray& vertices, sf::Vector2f position, const sf::Color& color, const sf::Glyph& glyph, float italicShear) { - const float padding = 1.0; + const sf::Vector2f padding(1.f, 1.f); - const float left = glyph.bounds.position.x - padding; - const float top = glyph.bounds.position.y - padding; - const float right = glyph.bounds.position.x + glyph.bounds.size.x + padding; - const float bottom = glyph.bounds.position.y + glyph.bounds.size.y + padding; + const sf::Vector2f p1 = glyph.bounds.position - padding; + const sf::Vector2f p2 = glyph.bounds.position + glyph.bounds.size + padding; - const float u1 = static_cast(glyph.textureRect.position.x) - padding; - const float v1 = static_cast(glyph.textureRect.position.y) - padding; - const float u2 = static_cast(glyph.textureRect.position.x + glyph.textureRect.size.x) + padding; - const float v2 = static_cast(glyph.textureRect.position.y + glyph.textureRect.size.y) + padding; + const auto uv1 = sf::Vector2f(glyph.textureRect.position) - padding; + const auto uv2 = sf::Vector2f(glyph.textureRect.position + glyph.textureRect.size) + padding; - vertices.append({{position.x + left - italicShear * top, position.y + top}, color, {u1, v1}}); - vertices.append({{position.x + right - italicShear * top, position.y + top}, color, {u2, v1}}); - vertices.append({{position.x + left - italicShear * bottom, position.y + bottom}, color, {u1, v2}}); - vertices.append({{position.x + left - italicShear * bottom, position.y + bottom}, color, {u1, v2}}); - vertices.append({{position.x + right - italicShear * top, position.y + top}, color, {u2, v1}}); - vertices.append({{position.x + right - italicShear * bottom, position.y + bottom}, color, {u2, v2}}); + vertices.append({position + sf::Vector2f(p1.x - italicShear * p1.y, p1.y), color, {uv1.x, uv1.y}}); + vertices.append({position + sf::Vector2f(p2.x - italicShear * p1.y, p1.y), color, {uv2.x, uv1.y}}); + vertices.append({position + sf::Vector2f(p1.x - italicShear * p2.y, p2.y), color, {uv1.x, uv2.y}}); + vertices.append({position + sf::Vector2f(p1.x - italicShear * p2.y, p2.y), color, {uv1.x, uv2.y}}); + vertices.append({position + sf::Vector2f(p2.x - italicShear * p1.y, p1.y), color, {uv2.x, uv1.y}}); + vertices.append({position + sf::Vector2f(p2.x - italicShear * p2.y, p2.y), color, {uv2.x, uv2.y}}); } } // namespace @@ -478,15 +474,13 @@ void Text::ensureGeometryUpdate() const addGlyphQuad(m_vertices, Vector2f(x, y), m_fillColor, glyph, italicShear); // Update the current bounds - const float left = glyph.bounds.position.x; - const float top = glyph.bounds.position.y; - const float right = glyph.bounds.position.x + glyph.bounds.size.x; - const float bottom = glyph.bounds.position.y + glyph.bounds.size.y; + const Vector2f p1 = glyph.bounds.position; + const Vector2f p2 = glyph.bounds.position + glyph.bounds.size; - minX = std::min(minX, x + left - italicShear * bottom); - maxX = std::max(maxX, x + right - italicShear * top); - minY = std::min(minY, y + top); - maxY = std::max(maxY, y + bottom); + minX = std::min(minX, x + p1.x - italicShear * p2.y); + maxX = std::max(maxX, x + p2.x - italicShear * p1.y); + minY = std::min(minY, y + p1.y); + maxY = std::max(maxY, y + p2.y); // Advance to the next character x += glyph.advance + letterSpacing; @@ -521,10 +515,8 @@ void Text::ensureGeometryUpdate() const } // Update the bounding rectangle - m_bounds.position.x = minX; - m_bounds.position.y = minY; - m_bounds.size.x = maxX - minX; - m_bounds.size.y = maxY - minY; + m_bounds.position = Vector2f(minX, minY); + m_bounds.size = Vector2f(maxX, maxY) - Vector2f(minX, minY); } } // namespace sf diff --git a/src/SFML/Graphics/Texture.cpp b/src/SFML/Graphics/Texture.cpp index 1281580bc..76174c2c1 100644 --- a/src/SFML/Graphics/Texture.cpp +++ b/src/SFML/Graphics/Texture.cpp @@ -300,11 +300,11 @@ std::optional Texture::loadFromStream(InputStream& stream, bool sRgb, c std::optional Texture::loadFromImage(const Image& image, bool sRgb, const IntRect& area) { // Retrieve the image size - const auto [width, height] = Vector2i(image.getSize()); + const auto size = Vector2i(image.getSize()); // Load the entire image if the source area is either empty or contains the whole image if (area.size.x == 0 || (area.size.y == 0) || - ((area.position.x <= 0) && (area.position.y <= 0) && (area.size.x >= width) && (area.size.y >= height))) + ((area.position.x <= 0) && (area.position.y <= 0) && (area.size.x >= size.x) && (area.size.y >= size.y))) { // Load the entire image if (auto texture = sf::Texture::create(image.getSize(), sRgb)) @@ -326,8 +326,8 @@ std::optional Texture::loadFromImage(const Image& image, bool sRgb, con IntRect rectangle = area; rectangle.position.x = std::max(rectangle.position.x, 0); rectangle.position.y = std::max(rectangle.position.y, 0); - rectangle.size.x = std::min(rectangle.size.x, width - rectangle.position.x); - rectangle.size.y = std::min(rectangle.size.y, height - rectangle.position.y); + rectangle.size.x = std::min(rectangle.size.x, size.x - rectangle.position.x); + rectangle.size.y = std::min(rectangle.size.y, size.y - rectangle.position.y); // Create the texture and upload the pixels if (auto texture = sf::Texture::create(Vector2u(rectangle.size), sRgb)) @@ -338,12 +338,12 @@ std::optional Texture::loadFromImage(const Image& image, bool sRgb, con const priv::TextureSaver save; // Copy the pixels to the texture, row by row - const std::uint8_t* pixels = image.getPixelsPtr() + 4 * (rectangle.position.x + (width * rectangle.position.y)); + const std::uint8_t* pixels = image.getPixelsPtr() + 4 * (rectangle.position.x + (size.x * rectangle.position.y)); glCheck(glBindTexture(GL_TEXTURE_2D, texture->m_texture)); for (int i = 0; i < rectangle.size.y; ++i) { glCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i, rectangle.size.x, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels)); - pixels += 4 * width; + pixels += 4 * size.x; } glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));