commit 9f66f1d773d3c2eb557bbd3f6afe62157a4997ee Author: Cristian Pallarés Date: Thu Jul 26 13:04:54 2012 +0200 First commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ebd21a --- /dev/null +++ b/.gitignore @@ -0,0 +1,163 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.vspscc +.builds +*.dotCover + +## TODO: If you have NuGet Package Restore enabled, uncomment this +#packages/ + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp + +# ReSharper is a .NET coding add-in +_ReSharper* + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Others +[Bb]in +[Oo]bj +sql +TestResults +*.Cache +ClientBin +stylecop.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML + + + +############ +## Windows +############ + +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +# Mac crap +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..dc0642e --- /dev/null +++ b/README.md @@ -0,0 +1,59 @@ +RichText +======== + +Rich text class for [SFML2](https://github.com/LaurentGomila/SFML/). Allows the +user to draw lines of text with different styles and colors. + +Author +------ + +* [Cristian Pallarés](https://github.com/Skyrpex) - Original code +* [Lukas Dürrenberger](https://github.com/eXpl0it3r/) - Conversion to the new SFML2 API + +How to use +---------- + +1. Include the header and the source to your project. +2. Link to SFML2 (obviously :P!). + +Repository +---------- + +You can get the current development version from the [git repository](https://github.com/Skyrpex/RichText). + +Example +------- + + #include "RichText.hpp" + #include + + int main() + { + sf::RichText text; + text << sf::Text::Bold << sf::Color::Cyan << "This" + << sf::Text::Italic << sf::Color::White << " is cool " + << sf::Text::Regular << sf::Color::Green << "mate" + << sf::Color::White << ". " + << sf::Text::Underlined << "I wish I could lick it!"; + + text.setCharacterSize(25); + text.setPosition(400, 300); + text.setOrigin(text.getWidth()/2.f, text.getHeight()/2.f); + + sf::RenderWindow window; + window.create(sf::VideoMode(800, 600), "Rich text"); + + while(window.isOpen()) + { + sf::Event event; + while(window.pollEvent(event)) + { + if(event.type == sf::Event::Closed) + window.close(); + } + + window.clear(); + window.draw(text); + window.display(); + } + } \ No newline at end of file diff --git a/RichText.cpp b/RichText.cpp new file mode 100644 index 0000000..e93eff2 --- /dev/null +++ b/RichText.cpp @@ -0,0 +1,239 @@ +//////////////////////////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////////////////////////// +#include "RichText.hpp" +#include +#include + +namespace sfe +{ +RichText::RichText() + : myCurrentColor(sf::Color::White), + myCurrentStyle(sf::Text::Regular), + mySizeUpdated(false), + myPositionUpdated(false) +{ + +} + +//////////////////////////////////////////////////////////////////////////////// +// Operator << sf::Color +//////////////////////////////////////////////////////////////////////////////// +RichText & RichText::operator << (const sf::Color &color) +{ + myCurrentColor = color; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////// +// Operator << sf::Text::Style +//////////////////////////////////////////////////////////////////////////////// +RichText & RichText::operator << (sf::Text::Style style) +{ + myCurrentStyle = style; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////// +// Operator << sf::String +//////////////////////////////////////////////////////////////////////////////// +/* + ** Must parse the strings to look for '\n' characters. If found, we break + ** the string into two pieces. + */ +RichText & RichText::operator << (const sf::String &string) +{ + // It is not updated + mySizeUpdated = false; + myPositionUpdated = false; + + // Find \n characters (assert) + //assert(string.Find('\n') == std::string::npos); + if(string.find('\n') != std::string::npos) + std::cerr << "sfe::RichtText: Oops, character \n found." + "You will get visual errors." << std::endl; + + // Add string + myTexts.resize(myTexts.size()+1); + + // Setup string + sf::Text &text = *(--myTexts.end()); + text.setColor(myCurrentColor); + text.setStyle(myCurrentStyle); + text.setString(string); + + // Return + return *this; +} + +//////////////////////////////////////////////////////////////////////////////// +// Set size +//////////////////////////////////////////////////////////////////////////////// +void RichText::setCharacterSize(unsigned int size) +{ + // Set character size + for(std::list::iterator it = myTexts.begin(); + it != myTexts.end(); ++it) + { + it->setCharacterSize(size); + } + + // It is not updated + mySizeUpdated = false; + myPositionUpdated = false; +} + +//////////////////////////////////////////////////////////////////////////////// +// Set font +//////////////////////////////////////////////////////////////////////////////// +void RichText::setFont(const sf::Font &font) +{ + // Set character size + for(std::list::iterator it = myTexts.begin(); + it != myTexts.end(); ++it) + { + it->setFont(font); + } + + // It is not updated + mySizeUpdated = false; + myPositionUpdated = false; +} + +//////////////////////////////////////////////////////////////////////////////// +// Clear +//////////////////////////////////////////////////////////////////////////////// +void RichText::clear() +{ + // Clear text list + myTexts.clear(); + + // Reset size + mySize = sf::Vector2f(0.f, 0.f); + + // It is updated + mySizeUpdated = true; + myPositionUpdated = true; +} + +//////////////////////////////////////////////////////////////////////////////// +// Get text list +//////////////////////////////////////////////////////////////////////////////// +const std::list & RichText::getTextList() const +{ + return myTexts; +} + +//////////////////////////////////////////////////////////////////////////////// +// Get character size +//////////////////////////////////////////////////////////////////////////////// +unsigned int RichText::getCharacterSize() const +{ + if(myTexts.size()) return myTexts.begin()->getCharacterSize(); + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// Get font +//////////////////////////////////////////////////////////////////////////////// +const sf::Font & RichText::getFont() const +{ + if(myTexts.size()) return myTexts.begin()->getFont(); + return sf::Font::getDefaultFont(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Get width +//////////////////////////////////////////////////////////////////////////////// +float RichText::getWidth() const +{ + updateSize(); + return mySize.x; +} + +//////////////////////////////////////////////////////////////////////////////// +// Get height +//////////////////////////////////////////////////////////////////////////////// +float RichText::getHeight() const +{ + updateSize(); + return mySize.y; +} + +//////////////////////////////////////////////////////////////////////////////// +// Render +//////////////////////////////////////////////////////////////////////////////// +void RichText::draw(sf::RenderTarget& target, sf::RenderStates states) const +{ + // Update position + updatePosition(); + + states.transform *= getTransform(); + + // Draw + for(std::list::const_iterator it = myTexts.begin(); + it != myTexts.end(); ++it) + { + // Add transformation + //it->setT + + // Draw text + target.draw(*it, states); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Update size +//////////////////////////////////////////////////////////////////////////////// +void RichText::updateSize() const +{ + // Return if updated + if(mySizeUpdated) return; + + // Return if empty + if(myTexts.begin() == myTexts.end()) return; + + // It is updated + mySizeUpdated = true; + + // Sum all sizes (height not implemented) + mySize.x = 0.f; + mySize.y = myTexts.begin()->getGlobalBounds().height; + for(std::list::const_iterator it = myTexts.begin(); + it != myTexts.end(); ++it) + { + // Update width + mySize.x += it->getGlobalBounds().width; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Update position +//////////////////////////////////////////////////////////////////////////////// +void RichText::updatePosition() const +{ + // Return if updated + if(myPositionUpdated) return; + + // Return if empty + if(myTexts.begin() == myTexts.end()) return; + + // It is updated + myPositionUpdated = true; + + // Get starting position + sf::Vector2f offset; + + // Draw + for(std::list::iterator it = myTexts.begin(); + it != myTexts.end(); ++it) + { + // Set all the origins to the first one + it->setOrigin(it->getPosition() - myTexts.begin()->getPosition() - offset); + + // Set offset + const sf::FloatRect rect = it->getGlobalBounds(); + offset.x += rect.width; + } +} +} diff --git a/RichText.hpp b/RichText.hpp new file mode 100644 index 0000000..fc3fd2f --- /dev/null +++ b/RichText.hpp @@ -0,0 +1,101 @@ +#ifndef RICHTEXT_HPP +#define RICHTEXT_HPP + +////////////////////////////////////////////////////////////////////////// +// Headers +////////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include + +namespace sf +{ + +class RichText : public sf::Drawable, public sf::Transformable +{ +public: + ////////////////////////////////////////////////////////////////////////// + // Constructor + ////////////////////////////////////////////////////////////////////////// + RichText(); + + ////////////////////////////////////////////////////////////////////////// + // Operators + ////////////////////////////////////////////////////////////////////////// + RichText & operator << (const sf::Color &color); + RichText & operator << (sf::Text::Style style); + RichText & operator << (const sf::String &string); + + ////////////////////////////////////////////////////////////////////////// + // Set character size + ////////////////////////////////////////////////////////////////////////// + void setCharacterSize(unsigned int size); + + ////////////////////////////////////////////////////////////////////////// + // Set font + ////////////////////////////////////////////////////////////////////////// + void setFont(const sf::Font &font); + + ////////////////////////////////////////////////////////////////////////// + // Clear + ////////////////////////////////////////////////////////////////////////// + void clear(); + + ////////////////////////////////////////////////////////////////////////// + // Get text list + ////////////////////////////////////////////////////////////////////////// + const std::list &getTextList() const; + + ////////////////////////////////////////////////////////////////////////// + // Get character size + ////////////////////////////////////////////////////////////////////////// + unsigned int getCharacterSize() const; + + ////////////////////////////////////////////////////////////////////////// + // Get font + ////////////////////////////////////////////////////////////////////////// + const sf::Font & getFont() const; + + ////////////////////////////////////////////////////////////////////////// + // Get width + ////////////////////////////////////////////////////////////////////////// + float getWidth() const; + + ////////////////////////////////////////////////////////////////////////// + // Get height + ////////////////////////////////////////////////////////////////////////// + float getHeight() const; + +private: + ////////////////////////////////////////////////////////////////////////// + // Update size + ////////////////////////////////////////////////////////////////////////// + void updateSize() const; + + ////////////////////////////////////////////////////////////////////////// + // Update position + ////////////////////////////////////////////////////////////////////////// + void updatePosition() const; + + ////////////////////////////////////////////////////////////////////////// + // Render + ////////////////////////////////////////////////////////////////////////// + void draw(sf::RenderTarget& target, sf::RenderStates states) const; + + ////////////////////////////////////////////////////////////////////////// + // Member data + ////////////////////////////////////////////////////////////////////////// + mutable std::list myTexts; ///< List of texts + sf::Color myCurrentColor; ///< Last used color + sf::Text::Style myCurrentStyle; ///< Last style used + mutable sf::Vector2f mySize; ///< Size of the text + mutable bool mySizeUpdated; ///< Do we need to recompute the size? + mutable bool myPositionUpdated; ///< Do we need to recompute the + ///< position? +}; + +} + +#endif // RICHTEXT_HPP