From 5f3b6cb57af35dd356b80ac391d78ec66df82a26 Mon Sep 17 00:00:00 2001 From: Foaly Date: Fri, 18 Jul 2014 13:57:23 +0200 Subject: [PATCH] Added a strikethrough text style to sf::Text. Fixes issue #243. --- include/SFML/Graphics/Text.hpp | 13 +++++----- src/SFML/Graphics/Text.cpp | 43 ++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/include/SFML/Graphics/Text.hpp b/include/SFML/Graphics/Text.hpp index 302d9d21..457ca679 100644 --- a/include/SFML/Graphics/Text.hpp +++ b/include/SFML/Graphics/Text.hpp @@ -55,10 +55,11 @@ public : //////////////////////////////////////////////////////////// enum Style { - Regular = 0, ///< Regular characters, no style - Bold = 1 << 0, ///< Bold characters - Italic = 1 << 1, ///< Italic characters - Underlined = 1 << 2 ///< Underlined characters + Regular = 0, ///< Regular characters, no style + Bold = 1 << 0, ///< Bold characters + Italic = 1 << 1, ///< Italic characters + Underlined = 1 << 2, ///< Underlined characters + StrikeThrough = 1 << 3 ///< Strike through characters }; //////////////////////////////////////////////////////////// @@ -326,8 +327,8 @@ private : /// It inherits all the functions from sf::Transformable: /// position, rotation, scale, origin. It also adds text-specific /// properties such as the font to use, the character size, -/// the font style (bold, italic, underlined), the global color -/// and the text to display of course. +/// the font style (bold, italic, underlined, strike through), the +/// global color and the text to display of course. /// It also provides convenience functions to calculate the /// graphical size of the text, or to get the global position /// of a given character. diff --git a/src/SFML/Graphics/Text.cpp b/src/SFML/Graphics/Text.cpp index 90208cf6..a28c404a 100644 --- a/src/SFML/Graphics/Text.cpp +++ b/src/SFML/Graphics/Text.cpp @@ -34,7 +34,7 @@ namespace sf { //////////////////////////////////////////////////////////// -Text::Text() : +Text::Text() : m_string (), m_font (NULL), m_characterSize (30), @@ -42,14 +42,14 @@ m_style (Regular), m_color (255, 255, 255), m_vertices (Triangles), m_bounds (), -m_geometryNeedUpdate(false) +m_geometryNeedUpdate(false) { } //////////////////////////////////////////////////////////// -Text::Text(const String& string, const Font& font, unsigned int characterSize) : +Text::Text(const String& string, const Font& font, unsigned int characterSize) : m_string (string), m_font (&font), m_characterSize (characterSize), @@ -57,7 +57,7 @@ m_style (Regular), m_color (255, 255, 255), m_vertices (Triangles), m_bounds (), -m_geometryNeedUpdate(true) +m_geometryNeedUpdate(true) { } @@ -261,10 +261,17 @@ void Text::ensureGeometryUpdate() const // Compute values related to the text style bool bold = (m_style & Bold) != 0; bool underlined = (m_style & Underlined) != 0; + bool strikeThrough = (m_style & StrikeThrough) != 0; float italic = (m_style & Italic) ? 0.208f : 0.f; // 12 degrees float underlineOffset = static_cast(m_font->getUnderlinePosition(m_characterSize)); float underlineThickness = static_cast(m_font->getUnderlineThickness(m_characterSize)); + // Compute the location of the strike through dynamically + // We use the center point of the lowercase 'x' glyph as the reference + // We reuse the underline thickness as the thickness of the strike through as well + IntRect xBounds = m_font->getGlyph(L'x', m_characterSize, bold).bounds; + float strikeThroughOffset = static_cast(xBounds.top) + static_cast(xBounds.height) / 2.f; + // Precompute the variables needed by the algorithm float hspace = static_cast(m_font->getGlyph(L' ', m_characterSize, bold).advance); float vspace = static_cast(m_font->getLineSpacing(m_characterSize)); @@ -299,6 +306,20 @@ void Text::ensureGeometryUpdate() const m_vertices.append(Vertex(Vector2f(x, bottom), m_color, Vector2f(1, 1))); } + // If we're using the strike through style and there's a new line, draw a line across all characters + if (strikeThrough && (curChar == L'\n')) + { + float top = y + strikeThroughOffset; + float bottom = top + underlineThickness; + + m_vertices.append(Vertex(Vector2f(0, top), m_color, Vector2f(1, 1))); + m_vertices.append(Vertex(Vector2f(x, top), m_color, Vector2f(1, 1))); + m_vertices.append(Vertex(Vector2f(0, bottom), m_color, Vector2f(1, 1))); + m_vertices.append(Vertex(Vector2f(0, bottom), m_color, Vector2f(1, 1))); + m_vertices.append(Vertex(Vector2f(x, top), m_color, Vector2f(1, 1))); + m_vertices.append(Vertex(Vector2f(x, bottom), m_color, Vector2f(1, 1))); + } + // Handle special characters if ((curChar == ' ') || (curChar == '\t') || (curChar == '\n')) { @@ -366,6 +387,20 @@ void Text::ensureGeometryUpdate() const m_vertices.append(Vertex(Vector2f(x, bottom), m_color, Vector2f(1, 1))); } + // If we're using the strike through style, add the last line across all characters + if (strikeThrough) + { + float top = y + strikeThroughOffset; + float bottom = top + underlineThickness; + + m_vertices.append(Vertex(Vector2f(0, top), m_color, Vector2f(1, 1))); + m_vertices.append(Vertex(Vector2f(x, top), m_color, Vector2f(1, 1))); + m_vertices.append(Vertex(Vector2f(0, bottom), m_color, Vector2f(1, 1))); + m_vertices.append(Vertex(Vector2f(0, bottom), m_color, Vector2f(1, 1))); + m_vertices.append(Vertex(Vector2f(x, top), m_color, Vector2f(1, 1))); + m_vertices.append(Vertex(Vector2f(x, bottom), m_color, Vector2f(1, 1))); + } + // Update the bounding rectangle m_bounds.left = minX; m_bounds.top = minY;