From 78247bd386a8ddfa396cb8b0eb754ce2365b3226 Mon Sep 17 00:00:00 2001 From: LaurentGom Date: Thu, 26 Nov 2009 08:07:38 +0000 Subject: [PATCH] FS#90 - Improve Unicode string classes Added the sf::String class to replace (and enhance) sf::Unicode::Text FS#138 - Rename sf::String to sf::Text git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1286 4e206d99-4929-0410-ac5d-dfc041789085 --- CSFML/build/VC2005/csfml-graphics.vcproj | 6 +- CSFML/build/VC2008/csfml-graphics.vcproj | 6 +- CSFML/build/codeblocks/csfml-graphics.cbp | 11 +- CSFML/include/SFML/Graphics/RenderImage.h | 14 +- CSFML/include/SFML/Graphics/RenderWindow.h | 14 +- .../SFML/Graphics/{String.h => Text.h} | 286 ++++---- CSFML/include/SFML/Graphics/Types.h | 2 +- CSFML/src/SFML/Graphics/RenderImage.cpp | 14 +- CSFML/src/SFML/Graphics/RenderWindow.cpp | 14 +- .../SFML/Graphics/{String.cpp => Text.cpp} | 266 +++---- .../Graphics/{StringStruct.h => TextStruct.h} | 16 +- CSFML/src/SFML/Graphics/csfml-graphics-d.def | 84 +-- CSFML/src/SFML/Graphics/csfml-graphics.def | 84 +-- build/codeblocks/sfml-graphics.cbp | 4 +- build/codeblocks/sfml-system.cbp | 8 +- build/vc2005/sfml-graphics.vcproj | 4 +- build/vc2005/sfml-system.vcproj | 14 +- build/vc2008/sfml-graphics.vcproj | 4 +- build/vc2008/sfml-system.vcproj | 14 +- dotnet/extlibs/csfml-audio.dll | Bin 49664 -> 49664 bytes dotnet/extlibs/csfml-graphics.dll | Bin 1159680 -> 1152512 bytes dotnet/extlibs/csfml-window.dll | Bin 47104 -> 47104 bytes dotnet/samples/opengl/OpenGL.cs | 2 +- dotnet/samples/shader/Shader.cs | 56 +- dotnet/src/Graphics/{String2D.cs => Text.cs} | 168 ++--- dotnet/src/Graphics/sfml-graphics.csproj | 2 +- include/SFML/Graphics.hpp | 2 +- include/SFML/Graphics/Font.hpp | 11 +- .../SFML/Graphics/{String.hpp => Text.hpp} | 30 +- include/SFML/System.hpp | 3 +- include/SFML/System/String.hpp | 530 ++++++++++++++ include/SFML/System/Unicode.hpp | 290 -------- include/SFML/System/Unicode.inl | 474 ------------ include/SFML/System/Utf.hpp | 672 ++++++++++++++++++ include/SFML/System/Utf.inl | 665 +++++++++++++++++ samples/opengl/OpenGL.cpp | 3 +- samples/pong/Pong.cpp | 6 +- samples/shader/Shader.cpp | 26 +- src/SFML/Graphics/Font.cpp | 47 +- src/SFML/Graphics/FontLoader.cpp | 24 +- src/SFML/Graphics/FontLoader.hpp | 8 +- src/SFML/Graphics/{String.cpp => Text.cpp} | 69 +- src/SFML/System/String.cpp | 387 ++++++++++ src/SFML/System/Unicode.cpp | 300 -------- src/SFML/System/Utf.cpp | 79 ++ src/SFML/Window/Linux/WindowImplX11.cpp | 9 +- 46 files changed, 3003 insertions(+), 1725 deletions(-) rename CSFML/include/SFML/Graphics/{String.h => Text.h} (55%) rename CSFML/src/SFML/Graphics/{String.cpp => Text.cpp} (51%) rename CSFML/src/SFML/Graphics/{StringStruct.h => TextStruct.h} (85%) rename dotnet/src/Graphics/{String2D.cs => Text.cs} (66%) rename include/SFML/Graphics/{String.hpp => Text.hpp} (88%) create mode 100644 include/SFML/System/String.hpp delete mode 100644 include/SFML/System/Unicode.hpp delete mode 100644 include/SFML/System/Unicode.inl create mode 100644 include/SFML/System/Utf.hpp create mode 100644 include/SFML/System/Utf.inl rename src/SFML/Graphics/{String.cpp => Text.cpp} (87%) create mode 100644 src/SFML/System/String.cpp delete mode 100644 src/SFML/System/Unicode.cpp create mode 100644 src/SFML/System/Utf.cpp diff --git a/CSFML/build/VC2005/csfml-graphics.vcproj b/CSFML/build/VC2005/csfml-graphics.vcproj index a374f5e6..1ad0eba8 100644 --- a/CSFML/build/VC2005/csfml-graphics.vcproj +++ b/CSFML/build/VC2005/csfml-graphics.vcproj @@ -318,15 +318,15 @@ > - + - + @@ -72,19 +72,20 @@ - - + + - + + diff --git a/CSFML/include/SFML/Graphics/RenderImage.h b/CSFML/include/SFML/Graphics/RenderImage.h index a55471e9..82e89e77 100644 --- a/CSFML/include/SFML/Graphics/RenderImage.h +++ b/CSFML/include/SFML/Graphics/RenderImage.h @@ -112,25 +112,25 @@ CSFML_API void sfRenderImage_Display(sfRenderImage* renderImage); //////////////////////////////////////////////////////////// /// Draw something on a renderimage /// -/// \param renderImage : Renderimage to draw in -/// \param sprite / string / shape : Object to draw +/// \param renderImage : Renderimage to draw in +/// \param sprite / text / shape : Object to draw /// //////////////////////////////////////////////////////////// CSFML_API void sfRenderImage_DrawSprite(sfRenderImage* renderImage, sfSprite* sprite); CSFML_API void sfRenderImage_DrawShape (sfRenderImage* renderImage, sfShape* shape); -CSFML_API void sfRenderImage_DrawString(sfRenderImage* renderImage, sfString* string); +CSFML_API void sfRenderImage_DrawText (sfRenderImage* renderImage, sfText* text); //////////////////////////////////////////////////////////// /// Draw something on a renderimage with a shader /// -/// \param renderImage : Renderimage to draw in -/// \param sprite / string / shape : Object to draw -/// \param shader : Shader to use +/// \param renderImage : Renderimage to draw in +/// \param sprite / text / shape : Object to draw +/// \param shader : Shader to use /// //////////////////////////////////////////////////////////// CSFML_API void sfRenderImage_DrawSpriteWithShader(sfRenderImage* renderImage, sfSprite* sprite, sfShader* shader); CSFML_API void sfRenderImage_DrawShapeWithShader (sfRenderImage* renderImage, sfShape* shape, sfShader* shader); -CSFML_API void sfRenderImage_DrawStringWithShader(sfRenderImage* renderImage, sfString* string, sfShader* shader); +CSFML_API void sfRenderImage_DrawTextWithShader (sfRenderImage* renderImage, sfText* text, sfShader* shader); //////////////////////////////////////////////////////////// /// Clear the renderimage with the given color diff --git a/CSFML/include/SFML/Graphics/RenderWindow.h b/CSFML/include/SFML/Graphics/RenderWindow.h index 45087923..39f4e18c 100644 --- a/CSFML/include/SFML/Graphics/RenderWindow.h +++ b/CSFML/include/SFML/Graphics/RenderWindow.h @@ -292,25 +292,25 @@ CSFML_API void sfRenderWindow_SetJoystickThreshold(sfRenderWindow* renderWindow, //////////////////////////////////////////////////////////// /// Draw something on a renderwindow /// -/// \param renderWindow : Renderwindow to draw in -/// \param sprite / string / shape : Object to draw +/// \param renderWindow : Renderwindow to draw in +/// \param sprite / text / shape : Object to draw /// //////////////////////////////////////////////////////////// CSFML_API void sfRenderWindow_DrawSprite(sfRenderWindow* renderWindow, sfSprite* sprite); CSFML_API void sfRenderWindow_DrawShape (sfRenderWindow* renderWindow, sfShape* shape); -CSFML_API void sfRenderWindow_DrawString(sfRenderWindow* renderWindow, sfString* string); +CSFML_API void sfRenderWindow_DrawText (sfRenderWindow* renderWindow, sfText* text); //////////////////////////////////////////////////////////// /// Draw something on a renderwindow with a shader /// -/// \param renderWindow : Renderwindow to draw in -/// \param sprite / string / shape : Object to draw -/// \param shader : Shader to use +/// \param renderWindow : Renderwindow to draw in +/// \param sprite / text / shape : Object to draw +/// \param shader : Shader to use /// //////////////////////////////////////////////////////////// CSFML_API void sfRenderWindow_DrawSpriteWithShader(sfRenderWindow* renderWindow, sfSprite* sprite, sfShader* shader); CSFML_API void sfRenderWindow_DrawShapeWithShader (sfRenderWindow* renderWindow, sfShape* shape, sfShader* shader); -CSFML_API void sfRenderWindow_DrawStringWithShader(sfRenderWindow* renderWindow, sfString* string, sfShader* shader); +CSFML_API void sfRenderWindow_DrawTextWithShader (sfRenderWindow* renderWindow, sfText* text, sfShader* shader); //////////////////////////////////////////////////////////// /// Clear the screen with the given color diff --git a/CSFML/include/SFML/Graphics/String.h b/CSFML/include/SFML/Graphics/Text.h similarity index 55% rename from CSFML/include/SFML/Graphics/String.h rename to CSFML/include/SFML/Graphics/Text.h index 3909aa76..3a9243c5 100644 --- a/CSFML/include/SFML/Graphics/String.h +++ b/CSFML/include/SFML/Graphics/Text.h @@ -22,8 +22,8 @@ // //////////////////////////////////////////////////////////// -#ifndef SFML_STRING_H -#define SFML_STRING_H +#ifndef SFML_TEXT_H +#define SFML_TEXT_H //////////////////////////////////////////////////////////// // Headers @@ -36,389 +36,389 @@ //////////////////////////////////////////////////////////// -/// sfString styles +/// sfText styles //////////////////////////////////////////////////////////// typedef enum { - sfStringRegular = 0, ///< Regular characters, no style - sfStringBold = 1 << 0, ///< Characters are bold - sfStringItalic = 1 << 1, ///< Characters are in italic - sfStringUnderlined = 1 << 2 ///< Characters are underlined -} sfStringStyle; + sfTextRegular = 0, ///< Regular characters, no style + sfTextBold = 1 << 0, ///< Characters are bold + sfTextItalic = 1 << 1, ///< Characters are in italic + sfTextUnderlined = 1 << 2 ///< Characters are underlined +} sfTextStyle; //////////////////////////////////////////////////////////// -/// Create a new string +/// Create a new text /// -/// \return A new sfString object, or NULL if it failed +/// \return A new sfText object, or NULL if it failed /// //////////////////////////////////////////////////////////// -CSFML_API sfString* sfString_Create(); +CSFML_API sfText* sfText_Create(); //////////////////////////////////////////////////////////// -/// Destroy an existing string +/// Destroy an existing text /// -/// \param string : String to delete +/// \param text : Text to delete /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_Destroy(sfString* string); +CSFML_API void sfText_Destroy(sfText* text); //////////////////////////////////////////////////////////// -/// Set the X position of a string +/// Set the X position of a text /// -/// \param string : String to modify -/// \param x : New X coordinate +/// \param text : String to modify +/// \param x : New X coordinate /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetX(sfString* string, float x); +CSFML_API void sfText_SetX(sfText* text, float x); //////////////////////////////////////////////////////////// -/// Set the Y position of a string +/// Set the Y position of a text /// -/// \param string : String to modify -/// \param y : New Y coordinate +/// \param text : String to modify +/// \param y : New Y coordinate /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetY(sfString* string, float y); +CSFML_API void sfText_SetY(sfText* text, float y); //////////////////////////////////////////////////////////// -/// Set the position of a string +/// Set the position of a text /// -/// \param string : String to modify -/// \param x : New X coordinate -/// \param y : New Y coordinate +/// \param text : String to modify +/// \param x : New X coordinate +/// \param y : New Y coordinate /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetPosition(sfString* string, float x, float y); +CSFML_API void sfText_SetPosition(sfText* text, float x, float y); //////////////////////////////////////////////////////////// -/// Set the horizontal scale of a string +/// Set the horizontal scale of a text /// -/// \param string : String to modify -/// \param scale : New scale (must be strictly positive) +/// \param text : String to modify +/// \param scale : New scale (must be strictly positive) /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetScaleX(sfString* string, float scale); +CSFML_API void sfText_SetScaleX(sfText* text, float scale); //////////////////////////////////////////////////////////// -/// Set the vertical scale of a string +/// Set the vertical scale of a text /// -/// \param string : String to modify -/// \param scale : New scale (must be strictly positive) +/// \param text : String to modify +/// \param scale : New scale (must be strictly positive) /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetScaleY(sfString* string, float scale); +CSFML_API void sfText_SetScaleY(sfText* text, float scale); //////////////////////////////////////////////////////////// -/// Set the scale of a string +/// Set the scale of a text /// -/// \param string : String to modify +/// \param text : String to modify /// \param scaleX : New horizontal scale (must be strictly positive) /// \param scaleY : New vertical scale (must be strictly positive) /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetScale(sfString* string, float scaleX, float scaleY); +CSFML_API void sfText_SetScale(sfText* text, float scaleX, float scaleY); //////////////////////////////////////////////////////////// -/// Set the orientation of a string +/// Set the orientation of a text /// -/// \param string : String to modify +/// \param text : String to modify /// \param rotation : Angle of rotation, in degrees /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetRotation(sfString* string, float rotation); +CSFML_API void sfText_SetRotation(sfText* text, float rotation); //////////////////////////////////////////////////////////// -/// Set the local origin of a string, in coordinates +/// Set the local origin of a text, in coordinates /// relative to its left-top corner /// -/// \param string : String to modify -/// \param x : X coordinate of the origin -/// \param y : Y coordinate of the origin +/// \param text : String to modify +/// \param x : X coordinate of the origin +/// \param y : Y coordinate of the origin /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetOrigin(sfString* string, float x, float y); +CSFML_API void sfText_SetOrigin(sfText* text, float x, float y); //////////////////////////////////////////////////////////// -/// Set the color of a string +/// Set the color of a text /// -/// \param string : String to modify -/// \param color : New color +/// \param text : String to modify +/// \param color : New color /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetColor(sfString* string, sfColor color); +CSFML_API void sfText_SetColor(sfText* text, sfColor color); //////////////////////////////////////////////////////////// -/// Set the blending mode for a string +/// Set the blending mode for a text /// -/// \param string : String to modify -/// \param mode : New blending mode +/// \param text : String to modify +/// \param mode : New blending mode /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetBlendMode(sfString* string, sfBlendMode mode); +CSFML_API void sfText_SetBlendMode(sfText* text, sfBlendMode mode); //////////////////////////////////////////////////////////// -/// Get the X position of a string +/// Get the X position of a text /// -/// \param string : String to read +/// \param text : String to read /// /// \return Current X position /// //////////////////////////////////////////////////////////// -CSFML_API float sfString_GetX(sfString* string); +CSFML_API float sfText_GetX(sfText* text); //////////////////////////////////////////////////////////// -/// Get the top Y of a string +/// Get the top Y of a text /// -/// \param string : String to read +/// \param text : String to read /// /// \return Current Y position /// //////////////////////////////////////////////////////////// -CSFML_API float sfString_GetY(sfString* string); +CSFML_API float sfText_GetY(sfText* text); //////////////////////////////////////////////////////////// -/// Get the horizontal scale of a string +/// Get the horizontal scale of a text /// -/// \param string : String to read +/// \param text : String to read /// /// \return Current X scale factor (always positive) /// //////////////////////////////////////////////////////////// -CSFML_API float sfString_GetScaleX(sfString* string); +CSFML_API float sfText_GetScaleX(sfText* text); //////////////////////////////////////////////////////////// -/// Get the vertical scale of a string +/// Get the vertical scale of a text /// -/// \param string : String to read +/// \param text : String to read /// /// \return Current Y scale factor (always positive) /// //////////////////////////////////////////////////////////// -CSFML_API float sfString_GetScaleY(sfString* string); +CSFML_API float sfText_GetScaleY(sfText* text); //////////////////////////////////////////////////////////// -/// Get the orientation of a string +/// Get the orientation of a text /// -/// \param string : String to read +/// \param text : String to read /// /// \return Current rotation, in degrees /// //////////////////////////////////////////////////////////// -CSFML_API float sfString_GetRotation(sfString* string); +CSFML_API float sfText_GetRotation(sfText* text); //////////////////////////////////////////////////////////// -/// Get the X position of the origin a string +/// Get the X position of the origin a text /// -/// \param string : String to read +/// \param text : String to read /// /// \return Current X origin position /// //////////////////////////////////////////////////////////// -CSFML_API float sfString_GetOriginX(sfString* string); +CSFML_API float sfText_GetOriginX(sfText* text); //////////////////////////////////////////////////////////// -/// Get the top Y of the origin of a string +/// Get the top Y of the origin of a text /// -/// \param string : String to read +/// \param text : String to read /// /// \return Current Y origin position /// //////////////////////////////////////////////////////////// -CSFML_API float sfString_GetOriginY(sfString* string); +CSFML_API float sfText_GetOriginY(sfText* text); //////////////////////////////////////////////////////////// -/// Get the color of a string +/// Get the color of a text /// -/// \param string : String to read +/// \param text : String to read /// /// \return Current color /// //////////////////////////////////////////////////////////// -CSFML_API sfColor sfString_GetColor(sfString* string); +CSFML_API sfColor sfText_GetColor(sfText* text); //////////////////////////////////////////////////////////// -/// Get the current blending mode of a string +/// Get the current blending mode of a text /// -/// \param string : String to read +/// \param text : String to read /// /// \return Current blending mode /// //////////////////////////////////////////////////////////// -CSFML_API sfBlendMode sfString_GetBlendMode(sfString* string); +CSFML_API sfBlendMode sfText_GetBlendMode(sfText* text); //////////////////////////////////////////////////////////// -/// Move a string +/// Move a text /// -/// \param string : String to modify +/// \param text : String to modify /// \param offsetX : Offset on the X axis /// \param offsetY : Offset on the Y axis /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_Move(sfString* string, float offsetX, float offsetY); +CSFML_API void sfText_Move(sfText* text, float offsetX, float offsetY); //////////////////////////////////////////////////////////// -/// Scale a string +/// Scale a text /// -/// \param string : String to modify +/// \param text : String to modify /// \param factorX : Horizontal scaling factor (must be strictly positive) /// \param factorY : Vertical scaling factor (must be strictly positive) /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_Scale(sfString* string, float factorX, float factorY); +CSFML_API void sfText_Scale(sfText* text, float factorX, float factorY); //////////////////////////////////////////////////////////// -/// Rotate a string +/// Rotate a text /// -/// \param string : String to modify -/// \param angle : Angle of rotation, in degrees +/// \param text : String to modify +/// \param angle : Angle of rotation, in degrees /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_Rotate(sfString* string, float angle); +CSFML_API void sfText_Rotate(sfText* text, float angle); //////////////////////////////////////////////////////////// /// Transform a point from global coordinates into the string's local coordinates /// (ie it applies the inverse of object's origin, translation, rotation and scale to the point) /// -/// \param string : String object +/// \param text : String object /// \param pointX : X coordinate of the point to transform /// \param pointY : Y coordinate of the point to transform /// \param x : Value to fill with the X coordinate of the converted point /// \param y : Value to fill with the y coordinate of the converted point /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_TransformToLocal(sfString* string, float pointX, float pointY, float* x, float* y); +CSFML_API void sfText_TransformToLocal(sfText* text, float pointX, float pointY, float* x, float* y); //////////////////////////////////////////////////////////// /// Transform a point from the string's local coordinates into global coordinates /// (ie it applies the object's origin, translation, rotation and scale to the point) /// -/// \param string : String object +/// \param text : String object /// \param pointX : X coordinate of the point to transform /// \param pointY : Y coordinate of the point to transform /// \param x : Value to fill with the X coordinate of the converted point /// \param y : Value to fill with the y coordinate of the converted point /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_TransformToGlobal(sfString* string, float pointX, float pointY, float* X, float* y); +CSFML_API void sfText_TransformToGlobal(sfText* text, float pointX, float pointY, float* X, float* y); //////////////////////////////////////////////////////////// -/// Set the text of a string (from a multibyte string) +/// Set the string of a text (from a multibyte string) /// -/// \param string : String to modify -/// \param text : New text +/// \param text : Text to modify +/// \param string : New string /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetText(sfString* string, const char* text); +CSFML_API void sfText_SetString(sfText* text, const char* string); //////////////////////////////////////////////////////////// -/// Set the text of a string (from a unicode string) +/// Set the string of a text (from a unicode string) /// -/// \param string : String to modify -/// \param text : New text +/// \param text : Text to modify +/// \param string : New string /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetUnicodeText(sfString* string, const sfUint32* text); +CSFML_API void sfText_SetUnicodeString(sfText* text, const sfUint32* string); //////////////////////////////////////////////////////////// -/// Set the font of a string +/// Set the font of a text /// -/// \param string : String to modify -/// \param font : Font to use +/// \param text : String to modify +/// \param font : Font to use /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetFont(sfString* string, sfFont* font); +CSFML_API void sfText_SetFont(sfText* text, sfFont* font); //////////////////////////////////////////////////////////// -/// Set the size of a string +/// Set the size of a text /// -/// \param string : String to modify -/// \param size : New size, in pixels +/// \param text : String to modify +/// \param size : New size, in pixels /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetSize(sfString* string, float size); +CSFML_API void sfText_SetSize(sfText* text, float size); //////////////////////////////////////////////////////////// -/// Set the style of a string +/// Set the style of a text /// -/// \param string : String to modify -/// \param style : New style (see sfStringStyle enum) +/// \param text : String to modify +/// \param style : New style (see sfTextStyle enum) /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_SetStyle(sfString* string, unsigned long style); +CSFML_API void sfText_SetStyle(sfText* text, unsigned long style); //////////////////////////////////////////////////////////// -/// Get the text of a string (returns a unicode string) +/// Get the string of a text (returns a unicode string) /// -/// \param string : String to read +/// \param text : String to read /// -/// \return Text as UTF-32 +/// \return String as UTF-32 /// //////////////////////////////////////////////////////////// -CSFML_API const sfUint32* sfString_GetUnicodeText(sfString* string); +CSFML_API const sfUint32* sfText_GetUnicodeString(sfText* text); //////////////////////////////////////////////////////////// -/// Get the text of a string (returns an ANSI string) +/// Get the text of a text (returns an ANSI string) /// -/// \param string : String to read +/// \param text : String to read /// -/// \return Text an a locale-dependant ANSI string +/// \return String an a locale-dependant ANSI string /// //////////////////////////////////////////////////////////// -CSFML_API const char* sfString_GetText(sfString* string); +CSFML_API const char* sfText_GetString(sfText* text); //////////////////////////////////////////////////////////// -/// Get the font used by a string +/// Get the font used by a text /// -/// \param string : String to read +/// \param text : String to read /// /// \return Pointer to the font /// //////////////////////////////////////////////////////////// -CSFML_API sfFont* sfString_GetFont(sfString* string); +CSFML_API sfFont* sfText_GetFont(sfText* text); //////////////////////////////////////////////////////////// -/// Get the size of the characters of a string +/// Get the size of the characters of a text /// -/// \param string : String to read +/// \param text : String to read /// /// \return Size of the characters /// //////////////////////////////////////////////////////////// -CSFML_API float sfString_GetSize(sfString* string); +CSFML_API float sfText_GetSize(sfText* text); //////////////////////////////////////////////////////////// -/// Get the style of a string +/// Get the style of a text /// -/// \param string : String to read +/// \param text : String to read /// -/// \return Current string style (see sfStringStyle enum) +/// \return Current string style (see sfTextStyle enum) /// //////////////////////////////////////////////////////////// -CSFML_API unsigned long sfString_GetStyle(sfString* string); +CSFML_API unsigned long sfText_GetStyle(sfText* text); //////////////////////////////////////////////////////////// -/// Return the visual position of the Index-th character of the string, +/// Return the visual position of the Index-th character of the text, /// in coordinates relative to the string /// (note : translation, origin, rotation and scale are not applied) /// -/// \param string : String to read -/// \param index : Index of the character -/// \param x : Value to fill with the X coordinate of the position -/// \param y : Value to fill with the y coordinate of the position +/// \param text : String to read +/// \param index : Index of the character +/// \param x : Value to fill with the X coordinate of the position +/// \param y : Value to fill with the y coordinate of the position /// //////////////////////////////////////////////////////////// -CSFML_API void sfString_GetCharacterPos(sfString* string, size_t index, float* x, float* y); +CSFML_API void sfText_GetCharacterPos(sfText* text, size_t index, float* x, float* y); //////////////////////////////////////////////////////////// -/// Get the bounding rectangle of a string on screen +/// Get the bounding rectangle of a text on screen /// -/// \param string : String to read +/// \param text : String to read /// /// \return Rectangle contaning the string in screen coordinates /// //////////////////////////////////////////////////////////// -CSFML_API sfFloatRect sfString_GetRect(sfString* string); +CSFML_API sfFloatRect sfText_GetRect(sfText* text); -#endif // SFML_STRING_H +#endif // SFML_TEXT_H diff --git a/CSFML/include/SFML/Graphics/Types.h b/CSFML/include/SFML/Graphics/Types.h index 55783eaf..a490128c 100644 --- a/CSFML/include/SFML/Graphics/Types.h +++ b/CSFML/include/SFML/Graphics/Types.h @@ -33,7 +33,7 @@ typedef struct sfRenderImage sfRenderImage; typedef struct sfRenderWindow sfRenderWindow; typedef struct sfShape sfShape; typedef struct sfSprite sfSprite; -typedef struct sfString sfString; +typedef struct sfText sfText; typedef struct sfView sfView; diff --git a/CSFML/src/SFML/Graphics/RenderImage.cpp b/CSFML/src/SFML/Graphics/RenderImage.cpp index 5a582b78..a8b8d55c 100644 --- a/CSFML/src/SFML/Graphics/RenderImage.cpp +++ b/CSFML/src/SFML/Graphics/RenderImage.cpp @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include @@ -128,10 +128,10 @@ void sfRenderImage_DrawShape(sfRenderImage* renderImage, sfShape* shape) CSFML_CHECK(shape); CSFML_CALL(renderImage, Draw(shape->This)); } -void sfRenderImage_DrawString(sfRenderImage* renderImage, sfString* string) +void sfRenderImage_DrawText(sfRenderImage* renderImage, sfText* text) { - CSFML_CHECK(string); - CSFML_CALL(renderImage, Draw(string->This)); + CSFML_CHECK(text); + CSFML_CALL(renderImage, Draw(text->This)); } @@ -150,11 +150,11 @@ void sfRenderImage_DrawShapeWithShader(sfRenderImage* renderImage, sfShape* shap CSFML_CHECK(shader); CSFML_CALL(renderImage, Draw(shape->This, shader->This)); } -void sfRenderImage_DrawStringWithShader(sfRenderImage* renderImage, sfString* string, sfShader* shader) +void sfRenderImage_DrawTextWithShader(sfRenderImage* renderImage, sfText* text, sfShader* shader) { - CSFML_CHECK(string); + CSFML_CHECK(text); CSFML_CHECK(shader); - CSFML_CALL(renderImage, Draw(string->This, shader->This)); + CSFML_CALL(renderImage, Draw(text->This, shader->This)); } diff --git a/CSFML/src/SFML/Graphics/RenderWindow.cpp b/CSFML/src/SFML/Graphics/RenderWindow.cpp index 5d3427f0..f10798bd 100644 --- a/CSFML/src/SFML/Graphics/RenderWindow.cpp +++ b/CSFML/src/SFML/Graphics/RenderWindow.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include @@ -366,10 +366,10 @@ void sfRenderWindow_DrawShape(sfRenderWindow* renderWindow, sfShape* shape) CSFML_CHECK(shape); CSFML_CALL(renderWindow, Draw(shape->This)); } -void sfRenderWindow_DrawString(sfRenderWindow* renderWindow, sfString* string) +void sfRenderWindow_DrawText(sfRenderWindow* renderWindow, sfText* text) { - CSFML_CHECK(string); - CSFML_CALL(renderWindow, Draw(string->This)); + CSFML_CHECK(text); + CSFML_CALL(renderWindow, Draw(text->This)); } @@ -388,11 +388,11 @@ void sfRenderWindow_DrawShapeWithShader(sfRenderWindow* renderWindow, sfShape* s CSFML_CHECK(shader); CSFML_CALL(renderWindow, Draw(shape->This, shader->This)); } -void sfRenderWindow_DrawStringWithShader(sfRenderWindow* renderWindow, sfString* string, sfShader* shader) +void sfRenderWindow_DrawTextWithShader(sfRenderWindow* renderWindow, sfText* text, sfShader* shader) { - CSFML_CHECK(string); + CSFML_CHECK(text); CSFML_CHECK(shader); - CSFML_CALL(renderWindow, Draw(string->This, shader->This)); + CSFML_CALL(renderWindow, Draw(text->This, shader->This)); } diff --git a/CSFML/src/SFML/Graphics/String.cpp b/CSFML/src/SFML/Graphics/Text.cpp similarity index 51% rename from CSFML/src/SFML/Graphics/String.cpp rename to CSFML/src/SFML/Graphics/Text.cpp index b176ce1b..7d338ca5 100644 --- a/CSFML/src/SFML/Graphics/String.cpp +++ b/CSFML/src/SFML/Graphics/Text.cpp @@ -25,397 +25,397 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include -#include +#include +#include #include #include #include //////////////////////////////////////////////////////////// -/// Create a new string +/// Create a new text //////////////////////////////////////////////////////////// -sfString* sfString_Create() +sfText* sfText_Create() { - sfString* string = new sfString; - string->Font = sfFont_GetDefaultFont(); + sfText* text = new sfText; + text->Font = sfFont_GetDefaultFont(); - return string; + return text; } //////////////////////////////////////////////////////////// -/// Destroy an existing string +/// Destroy an existing text //////////////////////////////////////////////////////////// -void sfString_Destroy(sfString* string) +void sfText_Destroy(sfText* text) { - delete string; + delete text; } //////////////////////////////////////////////////////////// -/// Set the X position of a string +/// Set the X position of a text //////////////////////////////////////////////////////////// -void sfString_SetX(sfString* string, float x) +void sfText_SetX(sfText* text, float x) { - CSFML_CALL(string, SetX(x)) + CSFML_CALL(text, SetX(x)) } //////////////////////////////////////////////////////////// -/// Set the Y position of a string +/// Set the Y position of a text //////////////////////////////////////////////////////////// -void sfString_SetY(sfString* string, float y) +void sfText_SetY(sfText* text, float y) { - CSFML_CALL(string, SetY(y)) + CSFML_CALL(text, SetY(y)) } //////////////////////////////////////////////////////////// -/// Set the position of a string +/// Set the position of a text //////////////////////////////////////////////////////////// -void sfString_SetPosition(sfString* string, float x, float y) +void sfText_SetPosition(sfText* text, float x, float y) { - CSFML_CALL(string, SetPosition(sf::Vector2f(x, y))) + CSFML_CALL(text, SetPosition(sf::Vector2f(x, y))) } //////////////////////////////////////////////////////////// -/// Set the horizontal scale of a string +/// Set the horizontal scale of a text //////////////////////////////////////////////////////////// -void sfString_SetScaleX(sfString* string, float scale) +void sfText_SetScaleX(sfText* text, float scale) { - CSFML_CALL(string, SetScaleX(scale)) + CSFML_CALL(text, SetScaleX(scale)) } //////////////////////////////////////////////////////////// -/// Set the vertical scale of a string +/// Set the vertical scale of a text //////////////////////////////////////////////////////////// -void sfString_SetScaleY(sfString* string, float scale) +void sfText_SetScaleY(sfText* text, float scale) { - CSFML_CALL(string, SetScaleY(scale)) + CSFML_CALL(text, SetScaleY(scale)) } //////////////////////////////////////////////////////////// -/// Set the scale of a string +/// Set the scale of a text //////////////////////////////////////////////////////////// -void sfString_SetScale(sfString* string, float scaleX, float scaleY) +void sfText_SetScale(sfText* text, float scaleX, float scaleY) { - CSFML_CALL(string, SetScale(sf::Vector2f(scaleX, scaleY))) + CSFML_CALL(text, SetScale(sf::Vector2f(scaleX, scaleY))) } //////////////////////////////////////////////////////////// -/// Set the orientation of a string +/// Set the orientation of a text //////////////////////////////////////////////////////////// -void sfString_SetRotation(sfString* string, float rotation) +void sfText_SetRotation(sfText* text, float rotation) { - CSFML_CALL(string, SetRotation(rotation)) + CSFML_CALL(text, SetRotation(rotation)) } //////////////////////////////////////////////////////////// -/// Set the local origin of a string, in coordinates +/// Set the local origin of a text, in coordinates /// relative to its left-top corner //////////////////////////////////////////////////////////// -void sfString_SetOrigin(sfString* string, float x, float y) +void sfText_SetOrigin(sfText* text, float x, float y) { - CSFML_CALL(string, SetOrigin(sf::Vector2f(x, y))) + CSFML_CALL(text, SetOrigin(sf::Vector2f(x, y))) } //////////////////////////////////////////////////////////// -/// Set the color of a string +/// Set the color of a text //////////////////////////////////////////////////////////// -void sfString_SetColor(sfString* string, sfColor color) +void sfText_SetColor(sfText* text, sfColor color) { - CSFML_CALL(string, SetColor(sf::Color(color.r, color.g, color.b, color.a))) + CSFML_CALL(text, SetColor(sf::Color(color.r, color.g, color.b, color.a))) } //////////////////////////////////////////////////////////// -/// Set the blending mode for a string +/// Set the blending mode for a text //////////////////////////////////////////////////////////// -void sfString_SetBlendMode(sfString* string, sfBlendMode mode) +void sfText_SetBlendMode(sfText* text, sfBlendMode mode) { - CSFML_CALL(string, SetBlendMode(static_cast(mode))) + CSFML_CALL(text, SetBlendMode(static_cast(mode))) } //////////////////////////////////////////////////////////// -/// Get the X position of a string +/// Get the X position of a text //////////////////////////////////////////////////////////// -float sfString_GetX(sfString* string) +float sfText_GetX(sfText* text) { - CSFML_CALL_RETURN(string, GetPosition().x, 0.f) + CSFML_CALL_RETURN(text, GetPosition().x, 0.f) } //////////////////////////////////////////////////////////// -/// Get the Y position of a string +/// Get the Y position of a text //////////////////////////////////////////////////////////// -float sfString_GetY(sfString* string) +float sfText_GetY(sfText* text) { - CSFML_CALL_RETURN(string, GetPosition().y, 0.f) + CSFML_CALL_RETURN(text, GetPosition().y, 0.f) } //////////////////////////////////////////////////////////// -/// Get the horizontal scale of a string +/// Get the horizontal scale of a text //////////////////////////////////////////////////////////// -float sfString_GetScaleX(sfString* string) +float sfText_GetScaleX(sfText* text) { - CSFML_CALL_RETURN(string, GetScale().x, 0.f) + CSFML_CALL_RETURN(text, GetScale().x, 0.f) } //////////////////////////////////////////////////////////// -/// Get the vertical scale of a string +/// Get the vertical scale of a text //////////////////////////////////////////////////////////// -float sfString_GetScaleY(sfString* string) +float sfText_GetScaleY(sfText* text) { - CSFML_CALL_RETURN(string, GetScale().y, 0.f) + CSFML_CALL_RETURN(text, GetScale().y, 0.f) } //////////////////////////////////////////////////////////// -/// Get the orientation of a string +/// Get the orientation of a text //////////////////////////////////////////////////////////// -float sfString_GetRotation(sfString* string) +float sfText_GetRotation(sfText* text) { - CSFML_CALL_RETURN(string, GetRotation(), 0.f) + CSFML_CALL_RETURN(text, GetRotation(), 0.f) } //////////////////////////////////////////////////////////// -/// Get the X position of the origin a string +/// Get the X position of the origin a text //////////////////////////////////////////////////////////// -float sfString_GetOriginX(sfString* string) +float sfText_GetOriginX(sfText* text) { - CSFML_CALL_RETURN(string, GetOrigin().x, 0.f) + CSFML_CALL_RETURN(text, GetOrigin().x, 0.f) } //////////////////////////////////////////////////////////// -/// Get the top Y of the origin of a string +/// Get the top Y of the origin of a text //////////////////////////////////////////////////////////// -float sfString_GetOriginY(sfString* string) +float sfText_GetOriginY(sfText* text) { - CSFML_CALL_RETURN(string, GetOrigin().y, 0.f) + CSFML_CALL_RETURN(text, GetOrigin().y, 0.f) } //////////////////////////////////////////////////////////// -/// Get the color of a string +/// Get the color of a text //////////////////////////////////////////////////////////// -sfColor sfString_GetColor(sfString* string) +sfColor sfText_GetColor(sfText* text) { sfColor color = {0, 0, 0, 0}; - CSFML_CHECK_RETURN(string, color) + CSFML_CHECK_RETURN(text, color) - sf::Color SFMLColor = string->This.GetColor(); + sf::Color SFMLColor = text->This.GetColor(); return sfColor_FromRGBA(SFMLColor.r, SFMLColor.g, SFMLColor.b, SFMLColor.a); } //////////////////////////////////////////////////////////// -/// Get the current blending mode of a string +/// Get the current blending mode of a text //////////////////////////////////////////////////////////// -sfBlendMode sfString_GetBlendMode(sfString* string) +sfBlendMode sfText_GetBlendMode(sfText* text) { - CSFML_CHECK_RETURN(string, sfBlendNone) + CSFML_CHECK_RETURN(text, sfBlendNone) - return static_cast(string->This.GetBlendMode()); + return static_cast(text->This.GetBlendMode()); } //////////////////////////////////////////////////////////// -/// Move a string +/// Move a text //////////////////////////////////////////////////////////// -void sfString_Move(sfString* string, float offsetX, float offsetY) +void sfText_Move(sfText* text, float offsetX, float offsetY) { - CSFML_CALL(string, Move(sf::Vector2f(offsetX, offsetY))) + CSFML_CALL(text, Move(sf::Vector2f(offsetX, offsetY))) } //////////////////////////////////////////////////////////// -/// Scale a string +/// Scale a text //////////////////////////////////////////////////////////// -void sfString_Scale(sfString* string, float factorX, float factorY) +void sfText_Scale(sfText* text, float factorX, float factorY) { - CSFML_CALL(string, Scale(sf::Vector2f(factorX, factorY))) + CSFML_CALL(text, Scale(sf::Vector2f(factorX, factorY))) } //////////////////////////////////////////////////////////// -/// Rotate a string +/// Rotate a text //////////////////////////////////////////////////////////// -void sfString_Rotate(sfString* string, float angle) +void sfText_Rotate(sfText* text, float angle) { - CSFML_CALL(string, Rotate(angle)) + CSFML_CALL(text, Rotate(angle)) } //////////////////////////////////////////////////////////// -/// Transform a point from global coordinates into the string's local coordinates +/// Transform a point from global coordinates into the text's local coordinates /// (ie it applies the inverse of object's origin, translation, rotation and scale to the point) //////////////////////////////////////////////////////////// -void sfString_TransformToLocal(sfString* string, float pointX, float pointY, float* x, float* y) +void sfText_TransformToLocal(sfText* text, float pointX, float pointY, float* x, float* y) { - CSFML_CHECK(string) + CSFML_CHECK(text) - sf::Vector2f point = string->This.TransformToLocal(sf::Vector2f(pointX, pointY)); + sf::Vector2f point = text->This.TransformToLocal(sf::Vector2f(pointX, pointY)); if (x) *x = point.x; if (y) *y = point.y; } //////////////////////////////////////////////////////////// -/// Transform a point from the string's local coordinates into global coordinates +/// Transform a point from the text's local coordinates into global coordinates /// (ie it applies the object's origin, translation, rotation and scale to the point) //////////////////////////////////////////////////////////// -void sfString_TransformToGlobal(sfString* string, float pointX, float pointY, float* x, float* y) +void sfText_TransformToGlobal(sfText* text, float pointX, float pointY, float* x, float* y) { - CSFML_CHECK(string) + CSFML_CHECK(text) - sf::Vector2f point = string->This.TransformToGlobal(sf::Vector2f(pointX, pointY)); + sf::Vector2f point = text->This.TransformToGlobal(sf::Vector2f(pointX, pointY)); if (x) *x = point.x; if (y) *y = point.y; } //////////////////////////////////////////////////////////// -/// Set the text of a string (from a multibyte string) +/// Set the string of a text (from a multibyte string) //////////////////////////////////////////////////////////// -void sfString_SetText(sfString* string, const char* text) +void sfText_SetString(sfText* text, const char* string) { - CSFML_CALL(string, SetText(text)) + CSFML_CALL(text, SetString(string)) } //////////////////////////////////////////////////////////// -/// Set the text of a string (from a unicode string) +/// Set the string of a text (from a unicode string) //////////////////////////////////////////////////////////// -void sfString_SetUnicodeText(sfString* string, const sfUint32* text) +void sfText_SetUnicodeString(sfText* text, const sfUint32* string) { - sf::Unicode::UTF32String UTF32Text = text; - CSFML_CALL(string, SetText(UTF32Text)) + sf::String UTF32Text = string; + CSFML_CALL(text, SetString(UTF32Text)) } //////////////////////////////////////////////////////////// /// Set the font of a string //////////////////////////////////////////////////////////// -void sfString_SetFont(sfString* string, sfFont* font) +void sfText_SetFont(sfText* text, sfFont* font) { CSFML_CHECK(font); - CSFML_CALL(string, SetFont(font->This)) - string->Font = font; + CSFML_CALL(text, SetFont(font->This)) + text->Font = font; } //////////////////////////////////////////////////////////// /// Set the size of a string //////////////////////////////////////////////////////////// -void sfString_SetSize(sfString* string, float size) +void sfText_SetSize(sfText* text, float size) { - CSFML_CALL(string, SetSize(size)) + CSFML_CALL(text, SetSize(size)) } //////////////////////////////////////////////////////////// /// Set the style of a string //////////////////////////////////////////////////////////// -void sfString_SetStyle(sfString* string, unsigned long style) +void sfText_SetStyle(sfText* text, unsigned long style) { - CSFML_CALL(string, SetStyle(style)) + CSFML_CALL(text, SetStyle(style)) } //////////////////////////////////////////////////////////// -/// Get the text of a string (returns a unicode string) +/// Get the string of a text (returns a unicode string) //////////////////////////////////////////////////////////// -const sfUint32* sfString_GetUnicodeText(sfString* string) +const sfUint32* sfText_GetUnicodeString(sfText* text) { - CSFML_CHECK_RETURN(string, NULL) + CSFML_CHECK_RETURN(text, NULL) - return static_cast(string->This.GetText()).c_str(); + return text->This.GetString().GetData(); } //////////////////////////////////////////////////////////// -/// Get the text of a string (returns an ANSI string) +/// Get the string of a text (returns an ANSI string) //////////////////////////////////////////////////////////// -const char* sfString_GetText(sfString* string) +const char* sfText_GetString(sfText* text) { - CSFML_CHECK_RETURN(string, NULL) + CSFML_CHECK_RETURN(text, NULL) - string->Text = string->This.GetText(); + text->String = text->This.GetString().ToAnsiString(); - return string->Text.c_str(); + return text->String.c_str(); } //////////////////////////////////////////////////////////// -/// Get the font used by a string +/// Get the font used by a text //////////////////////////////////////////////////////////// -sfFont* sfString_GetFont(sfString* string) +sfFont* sfText_GetFont(sfText* text) { - CSFML_CHECK_RETURN(string, NULL) + CSFML_CHECK_RETURN(text, NULL) - return string->Font; + return text->Font; } //////////////////////////////////////////////////////////// -/// Get the size of the characters of a string +/// Get the size of the characters of a text //////////////////////////////////////////////////////////// -float sfString_GetSize(sfString* string) +float sfText_GetSize(sfText* text) { - CSFML_CALL_RETURN(string, GetSize(), 0.f) + CSFML_CALL_RETURN(text, GetSize(), 0.f) } //////////////////////////////////////////////////////////// -/// Get the style of a string +/// Get the style of a text //////////////////////////////////////////////////////////// -unsigned long sfString_GetStyle(sfString* string) +unsigned long sfText_GetStyle(sfText* text) { - CSFML_CALL_RETURN(string, GetStyle(), 0) + CSFML_CALL_RETURN(text, GetStyle(), 0) } //////////////////////////////////////////////////////////// -/// Return the visual position of the Index-th character of the string, -/// in coordinates relative to the string +/// Return the visual position of the Index-th character of the text, +/// in coordinates relative to the text /// (note : translation, origin, rotation and scale are not applied) //////////////////////////////////////////////////////////// -void sfString_GetCharacterPos(sfString* string, size_t index, float* x, float* y) +void sfText_GetCharacterPos(sfText* text, size_t index, float* x, float* y) { - CSFML_CHECK(string); + CSFML_CHECK(text); - sf::Vector2f pos = string->This.GetCharacterPos(index); + sf::Vector2f pos = text->This.GetCharacterPos(index); if (x) *x = pos.x; if (y) *y = pos.y; } //////////////////////////////////////////////////////////// -/// Get the bounding rectangle of a string on screen +/// Get the bounding rectangle of a text on screen //////////////////////////////////////////////////////////// -sfFloatRect sfString_GetRect(sfString* string) +sfFloatRect sfText_GetRect(sfText* text) { sfFloatRect rect = {0.f, 0.f, 0.f, 0.f}; - CSFML_CHECK_RETURN(string, rect) + CSFML_CHECK_RETURN(text, rect) - sf::FloatRect SFMLRect = string->This.GetRect(); - string->Rect.Left = SFMLRect.Left; - string->Rect.Top = SFMLRect.Top; - string->Rect.Right = SFMLRect.Right; - string->Rect.Bottom = SFMLRect.Bottom; + sf::FloatRect SFMLRect = text->This.GetRect(); + text->Rect.Left = SFMLRect.Left; + text->Rect.Top = SFMLRect.Top; + text->Rect.Right = SFMLRect.Right; + text->Rect.Bottom = SFMLRect.Bottom; - return string->Rect; + return text->Rect; } diff --git a/CSFML/src/SFML/Graphics/StringStruct.h b/CSFML/src/SFML/Graphics/TextStruct.h similarity index 85% rename from CSFML/src/SFML/Graphics/StringStruct.h rename to CSFML/src/SFML/Graphics/TextStruct.h index c27b230d..9d00bad0 100644 --- a/CSFML/src/SFML/Graphics/StringStruct.h +++ b/CSFML/src/SFML/Graphics/TextStruct.h @@ -22,28 +22,28 @@ // //////////////////////////////////////////////////////////// -#ifndef SFML_STRINGSTRUCT_H -#define SFML_STRINGSTRUCT_H +#ifndef SFML_TEXTSTRUCT_H +#define SFML_TEXTSTRUCT_H //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include +#include #include #include #include //////////////////////////////////////////////////////////// -// Internal structure of sfMusic +// Internal structure of sfText //////////////////////////////////////////////////////////// -struct sfString +struct sfText { - sf::String This; - std::string Text; + sf::Text This; + std::string String; sfFont* Font; sfFloatRect Rect; }; -#endif // SFML_STRINGSTRUCT_H +#endif // SFML_TEXTSTRUCT_H diff --git a/CSFML/src/SFML/Graphics/csfml-graphics-d.def b/CSFML/src/SFML/Graphics/csfml-graphics-d.def index 71dde90a..29c77510 100644 --- a/CSFML/src/SFML/Graphics/csfml-graphics-d.def +++ b/CSFML/src/SFML/Graphics/csfml-graphics-d.def @@ -130,44 +130,44 @@ EXPORTS sfFont_Destroy sfFont_GetCharacterSize sfFont_GetDefaultFont - sfString_Create - sfString_Destroy - sfString_SetX - sfString_SetY - sfString_SetPosition - sfString_SetScaleX - sfString_SetScaleY - sfString_SetScale - sfString_SetRotation - sfString_SetOrigin - sfString_SetColor - sfString_SetBlendMode - sfString_GetX - sfString_GetY - sfString_GetScaleX - sfString_GetScaleY - sfString_GetRotation - sfString_GetOriginX - sfString_GetOriginY - sfString_GetColor - sfString_GetBlendMode - sfString_Move - sfString_Scale - sfString_Rotate - sfString_TransformToLocal - sfString_TransformToGlobal - sfString_SetText - sfString_SetUnicodeText - sfString_SetFont - sfString_SetSize - sfString_SetStyle - sfString_GetUnicodeText - sfString_GetText - sfString_GetFont - sfString_GetSize - sfString_GetStyle - sfString_GetCharacterPos - sfString_GetRect + sfText_Create + sfText_Destroy + sfText_SetX + sfText_SetY + sfText_SetPosition + sfText_SetScaleX + sfText_SetScaleY + sfText_SetScale + sfText_SetRotation + sfText_SetOrigin + sfText_SetColor + sfText_SetBlendMode + sfText_GetX + sfText_GetY + sfText_GetScaleX + sfText_GetScaleY + sfText_GetRotation + sfText_GetOriginX + sfText_GetOriginY + sfText_GetColor + sfText_GetBlendMode + sfText_Move + sfText_Scale + sfText_Rotate + sfText_TransformToLocal + sfText_TransformToGlobal + sfText_SetString + sfText_SetUnicodeString + sfText_SetFont + sfText_SetSize + sfText_SetStyle + sfText_GetUnicodeString + sfText_GetString + sfText_GetFont + sfText_GetSize + sfText_GetStyle + sfText_GetCharacterPos + sfText_GetRect sfRenderImage_Create sfRenderImage_Destroy sfRenderImage_GetWidth @@ -177,10 +177,10 @@ EXPORTS sfRenderImage_Display sfRenderImage_DrawSprite sfRenderImage_DrawShape - sfRenderImage_DrawString + sfRenderImage_DrawText sfRenderImage_DrawSpriteWithShader sfRenderImage_DrawShapeWithShader - sfRenderImage_DrawStringWithShader + sfRenderImage_DrawTextWithShader sfRenderImage_Clear sfRenderImage_SetView sfRenderImage_GetView @@ -213,10 +213,10 @@ EXPORTS sfRenderWindow_GetFrameTime sfRenderWindow_SetJoystickThreshold sfRenderWindow_DrawSprite - sfRenderWindow_DrawString + sfRenderWindow_DrawText sfRenderWindow_DrawShape sfRenderWindow_DrawSpriteWithShader - sfRenderWindow_DrawStringWithShader + sfRenderWindow_DrawTextWithShader sfRenderWindow_DrawShapeWithShader sfRenderWindow_Clear sfRenderWindow_SetView diff --git a/CSFML/src/SFML/Graphics/csfml-graphics.def b/CSFML/src/SFML/Graphics/csfml-graphics.def index c8c9ef4f..a7399110 100644 --- a/CSFML/src/SFML/Graphics/csfml-graphics.def +++ b/CSFML/src/SFML/Graphics/csfml-graphics.def @@ -130,44 +130,44 @@ EXPORTS sfFont_Destroy sfFont_GetCharacterSize sfFont_GetDefaultFont - sfString_Create - sfString_Destroy - sfString_SetX - sfString_SetY - sfString_SetPosition - sfString_SetScaleX - sfString_SetScaleY - sfString_SetScale - sfString_SetRotation - sfString_SetOrigin - sfString_SetColor - sfString_SetBlendMode - sfString_GetX - sfString_GetY - sfString_GetScaleX - sfString_GetScaleY - sfString_GetRotation - sfString_GetOriginX - sfString_GetOriginY - sfString_GetColor - sfString_GetBlendMode - sfString_Move - sfString_Scale - sfString_Rotate - sfString_TransformToLocal - sfString_TransformToGlobal - sfString_SetText - sfString_SetUnicodeText - sfString_SetFont - sfString_SetSize - sfString_SetStyle - sfString_GetUnicodeText - sfString_GetText - sfString_GetFont - sfString_GetSize - sfString_GetStyle - sfString_GetCharacterPos - sfString_GetRect + sfText_Create + sfText_Destroy + sfText_SetX + sfText_SetY + sfText_SetPosition + sfText_SetScaleX + sfText_SetScaleY + sfText_SetScale + sfText_SetRotation + sfText_SetOrigin + sfText_SetColor + sfText_SetBlendMode + sfText_GetX + sfText_GetY + sfText_GetScaleX + sfText_GetScaleY + sfText_GetRotation + sfText_GetOriginX + sfText_GetOriginY + sfText_GetColor + sfText_GetBlendMode + sfText_Move + sfText_Scale + sfText_Rotate + sfText_TransformToLocal + sfText_TransformToGlobal + sfText_SetString + sfText_SetUnicodeString + sfText_SetFont + sfText_SetSize + sfText_SetStyle + sfText_GetUnicodeString + sfText_GetString + sfText_GetFont + sfText_GetSize + sfText_GetStyle + sfText_GetCharacterPos + sfText_GetRect sfRenderImage_Create sfRenderImage_Destroy sfRenderImage_GetWidth @@ -177,10 +177,10 @@ EXPORTS sfRenderImage_Display sfRenderImage_DrawSprite sfRenderImage_DrawShape - sfRenderImage_DrawString + sfRenderImage_DrawText sfRenderImage_DrawSpriteWithShader sfRenderImage_DrawShapeWithShader - sfRenderImage_DrawStringWithShader + sfRenderImage_DrawTextWithShader sfRenderImage_Clear sfRenderImage_SetView sfRenderImage_GetView @@ -215,10 +215,10 @@ EXPORTS sfRenderWindow_GetFrameTime sfRenderWindow_SetJoystickThreshold sfRenderWindow_DrawSprite - sfRenderWindow_DrawString + sfRenderWindow_DrawText sfRenderWindow_DrawShape sfRenderWindow_DrawSpriteWithShader - sfRenderWindow_DrawStringWithShader + sfRenderWindow_DrawTextWithShader sfRenderWindow_DrawShapeWithShader sfRenderWindow_Clear sfRenderWindow_SetView diff --git a/build/codeblocks/sfml-graphics.cbp b/build/codeblocks/sfml-graphics.cbp index 1978f961..f07b6e71 100644 --- a/build/codeblocks/sfml-graphics.cbp +++ b/build/codeblocks/sfml-graphics.cbp @@ -133,7 +133,7 @@ - + @@ -189,7 +189,7 @@ - + diff --git a/build/codeblocks/sfml-system.cbp b/build/codeblocks/sfml-system.cbp index 4a1bd373..e7a65c29 100644 --- a/build/codeblocks/sfml-system.cbp +++ b/build/codeblocks/sfml-system.cbp @@ -98,12 +98,13 @@ + - - + + @@ -114,9 +115,10 @@ + - + diff --git a/build/vc2005/sfml-graphics.vcproj b/build/vc2005/sfml-graphics.vcproj index cf08d988..0e3c9095 100644 --- a/build/vc2005/sfml-graphics.vcproj +++ b/build/vc2005/sfml-graphics.vcproj @@ -3314,11 +3314,11 @@ > diff --git a/build/vc2005/sfml-system.vcproj b/build/vc2005/sfml-system.vcproj index 52490548..e64c2463 100644 --- a/build/vc2005/sfml-system.vcproj +++ b/build/vc2005/sfml-system.vcproj @@ -470,6 +470,14 @@ RelativePath="..\..\include\SFML\System\Sleep.hpp" > + + + + @@ -495,15 +503,15 @@ > diff --git a/build/vc2008/sfml-system.vcproj b/build/vc2008/sfml-system.vcproj index f1936ef5..cb0d42ec 100644 --- a/build/vc2008/sfml-system.vcproj +++ b/build/vc2008/sfml-system.vcproj @@ -431,6 +431,14 @@ RelativePath="..\..\include\SFML\System\Sleep.hpp" > + + + + @@ -456,15 +464,15 @@ > QZNAd5K^`LCv7kZ`0DKS|cK`qY delta 66 zcmZo@VQy$)p74W3*!6?g#6Lbv`b#!@G2W^G^EYc$&0!PZ;NjZCx?9@2r$OAf!NO$k P<|_>w6ZLEWV1`QN- zDXFZ;VT;{mi;{|pY*0$tSYr#OYuGDIrq+;qqX1fKi_&W-1EMl zbDrPNeeQGbU`c;+Nn>(#g31TCd*rmv!_*$pKN&AX)wf|wi)VBn={$aWO{h+RBQfZLw5#%c8kIJ@Z4F`q;{Jj z5f$2hkW%NEhv&|mvaH~Sq5_~-zo6!!NuFRj|Kepgf{EFY;HMdWLjFrM7!sG|USDuM zu&hP!5d+!6>^tRb)0~SS6PQUuH2eJeRX`CKoN+(Npe|?1>?6UPvpvr%@=P2t?%9Jqhe3zeP2}+xU9ZnS7gR$L>|N}J#Iao+ z4-MTR2nv=~a;%~cyC-%WBk4ay%D13v-jI7i_>B~4yGcBYrd__3@)w$JlarMSXV zUysb3Yy*Eg{#MSPU@%l|iQM#hB2j35gF)$uG8iB^htZc@Q2K7s7O57_`fJc(Hk@xk zS6>QLM8!nZ%dPV!UbNXa0L5|WSxHUPYV93Q)!HGdw2B)BeT9}?X62n7a_YEzaG#Rtx1J*3#R(Z&}0Y2AEoM+s6_=bsNjZm6fCf#n=E3I_Ep0=5K!IzU_ zmqJG3&lIfO_f6qaEG1aCISR+oA=DLQ#CaTZXiy>z7Wta+`NnJIyTX@2*hAr~)Eaw7Zmqp~uy+w|@xv8u`*WOQNB_NrN;H%s2)tINvJsQR_=` znYVa+Unz(GF*`}9vZ<`@kgw0%mRsBCFATjBHWL2S~aE|Y!(lSQ=C~Vgn2OF;s1^R%E#x%8swX4Dy##b{LE0)TxWdTt65l z@0ogd%=`ZglVj~M%ggavlWc*ivOloJR_?KtXWM*;is{YYj*gZdX$QIa&T!xUCOGgYk0#6BdCN@O z3!(2Un4~)jufNQ5O%sz0rX%{81wOYZ!)s;de3x9esCvQ{%u|N%GPp23F!zF0Z=Qjg z>fN3#ra-ZR_}`PD)Bw3qmae6F(Bykc4or)Tqfw=PLZ68b9p3hk;q6d|w}|p)lKlSS z%S_!*$rF~WcN~L$x-rIgSriSG<#suQq?)*+I15814qGuY9$(KgYpOOWG*_Rsq$?E8RfB5;hp0Qc& z^6k+#c{6-_BKM7kmvumd(mgIic-av+Ql7ajm`vehiaso&AHVZE-*B2Q+ocqrE9nuE zV<73->|5%B{KHk(?vYkt89s#E+T(}A?>9jL@jc=9e+PN?#_x$L92=h4#~VM4 zj#li6s>qHm-4kO7-}gQ!;3DZrm2NJ<2rvcMHtjM(n~G)HXoRRMXkp)MtSk>z)(5_g z(Y`HFy9|;Mu6&YZhQYAQkh)3Agctxtg+@5BmM^O{9+iK!bb&VzmmC}ZXke^iA@nTC z0P82U-dDUAw-L^??QO$TsghAY1;ugrAVZXD#g>@S54LUH{%*3z*ksHuZMPotO|)Vc zjKI}Ss&o+QKTWEI&kQLCJ~t^7r$UvtTYMd(mqpk?<55PYXha2Pbl?C5#9tl|v9;gW z)8zfjRxQBdY*9PSCau#XyO$&haZFy4mxE@UlG`2eHk&nl~5m7Eyt?LU!HqD z!ab4UFYa-H)~38SAHrEut8R-@o%K+B*a^wm}ELf+*pp!#C41cjB zEfwoc8HH>@3#n}bH4ahX0=EP%*uL2?2j#7BL3$6bcyw0ZrLD0EGy;7|8o+TTDcG%i zqK`@4qKma!f?bRT-mlLFPZ01Z536S`=onSUWXaju+jRgP_8)QU)x1_gE=7m`zvYmo z2+F5qhwN`sK7#d+ItVC-@0<;q33!xWpMB~9pE&wy~Vad{%F;OQCO$RN!iDI z5m<-M;waoCMPdCZ(V;H#(o3fsUp&0_QnS%`rMy1=Qe%_oG3TG69#gvF@CWgGjmD0{ zn=e~sG(8wAS6?3Kh0EW(!@)&CZp8wa%?+gkN!pUu99+^mVMb5Ev+9!8?83Pw8dj|y zoa`gdUC~CS!pU@8MYzO@_FpTs6>abeZ0wYqF1MRv+vImIk2HOGp{!i~Q)|_mR>+I4 zm}i_Tr(BT-%fZ*Lm}PuH{_u*6OmS_pC2^i9rcI7cj01K<;=D;%Yh{5#i*M3sM0A_{ zXyP19x+L1A$aH{Kg--c7@3$?%Yl+WTz zHT#lGQJ}(w3f|CExuI?#=#(`H7|ye1{v9a4QHyy;<-7fAz@Ln$2N+~Bt zSq^NkH_mo0q_nl=m}phnqlkP_&P-lqx%WS#qnUDptV=b|{{|}Mi*<3v`{jl13ntHjOM!2Ly|g_tH4XFsqMYrX z=^PTJVAa!0ne191*SMEYI=Dcuo`Z|zZues2ZStr)()7i5^4zN&#&6}%YG=r4SIwIL z1BA+`fNEQ7P4g&`m>k@wY_?Zzu%(Xa+T>BHzCG~xpmC1ebd~vv7tb9s7N{ba&I?=? z_$M>+doc9{ULHg5O-fXflfS;6;Crc8~h+^~+4si}Hf2S6=+cN04LOG8ml) z*Y9bYjwg%t*YRZ9Z#s<>qQZowH81pzV{+Ge`}%X@LOSEpHfP{YTqIWZCD4l@JGUL54G^PU^Gewz$IN$7Z#Q&#YO4XAP+G{AiJhC9H^j&lOe+q}7s-wiNm$Dm` z!=?WnDVVhHlLB-6oC0+>D*kSB;d#3vMYz2txb=klZd|vdC|9D34bz16u82|rJxOUC zg*s5v46nKh(wm^Cm*Ry>x9}eKzZ0AwM3XVWbXOFW<^znZ7SaKQj3k_JPJ-v@3BoM^ z74R`s4VQX1fMmAmT)KfoLj=qAI>h}cs)T}n}|>gDZ#VS!xaEk>3E^K2oi+V zUJ~@@#LZCDlue#gWnhO`4voz-8cK^@Ipzm??wknyK4p{QIG;LfiYo?s)&s}3s*`4E zd-PG4w#SW|-0Od&kGZyFRCr-Z@a@G;R&_@a^fRrK#VL-XKhnvdZ>@qJ7+y9VcCg?m zF}!Rd9O0Z{!`k;KtFbc9?s*>NSKsS(G_hLmbKb(C&Cp+>u~E{MvFHplFbr+c_a>-) z&oug>-tW?tNzhk7AB`28u5@8&wN;!V4)nVyWmQOuR^I7ccJh4e`!KKC%g;#(J6yW* z3urVbTQrs}UAYNEs%3LRhjS6`8qv!(wW{6)l?lC^bviqhZy^R?CG!T0h8-?lS&0b- zi}oLkd~VTlel$VW>C_Uwib|Fsq_<7)a2~JHj&+_64>(d>?oDvuhUV~ipbxrXuTt5a zBf8#0w}`HnOI;7zIaN6{OLRTxbKA4Q*A?t}F-M~eY@L`X)`_iOz}AeoiG{m0c!*LA z9r@0Q^T0JFRoOzpz=*~hRu)Sx-#F*eSMV;W7;fyc9lncKd=dXW%t=3Ja}rFi_V}+0 zqT;_VjHEsD6{GQYs~hO@pEu6DuKx1Lw!+JMzZ^dnk9s3&;Im?Bi8!tm$7SO9pg1na zM5Q}WwJN8!m$@Y-7UC;7-Gr*{ozIt8ls zUA;v1W8mgJXEdgMGuC~@WSg;YS?NS^@Ol#@1p%$to0Lpg?@9S@!7l4>W{7IXGq?yW zxvT+nhQgTA0jICCBG=`VY%%co<~X$KMZ3xWCW$R<;5lN@pF(s2j3 zPqHa1W%squtbFD7qoZO`wzsVro?o60+Eshe4(>p8DznOPBcRZ#EH9Cr*R4Ch<=k3= z^kH#hJ`M@Ud#{T(cFAvDx6s}5qe5kQsfc%la+OycT+H?mh9Qfo%H^Mj^h$Zj*45se z5Ak-ta24yqO(6CtAO0;w40lJ{wnAUUdeo~B?la;3{-ko(UEi+~1$O+pnwc{SXArWuD%y8ci(UhV6@&nrzn;OdHSGV10g5ARN zvuEduO+;9C^k%uNN;f>O^$qrp>rHZ5`rhjun*)*ij`sdm`NVE9^eQl}?Y)7X8?6;# zps<4Cy`FaEZ9JE3`Rx6Qb>`mR_8e1Q0MK)zxniB=v-du0Q=YNQ&txxE)5Bk1WG{?f zB*BA~BTZ1A?T|It0CSw)vd^eq2ulZSu%`O9>TWYE0H3)}zGC}~m~QAJzK763xd(EI z>qjFXXu}gq1D=Cjq%9fB#MMxO6UzSkIb0*@DgPbv?iT0EOLsjO6EXTXzbs7-K~if709Jl0)C--*#bz~<8wpd0pU z6w)94!*(c=ZT8XNO$!XH(g6o0(O z#1B3VS0=LVqTUKauW`I|_F5Fje1^EA*!G0H`ueFGqHrA!r9B>20_}KwTpoPlDq0@| z`k01@asMOY_m5*lV~708^|5Y@LopTi0k|eX5)f96ise4)z=nj7ng1i?ts>;=IJ|X& z8wYGZyt9N&0H=}is-`inHkd|8*0E|KgX)V0S@Xe~bUAq^g z(YAMW)&90J=&Pdb?6IpA?*W4JL7R7S}?_K<4 zWxV?FIXUtZ;yIE}+?cmzd92<|XKCGZiq=iXtKGElQg-=`x_**PQlK}aDu3yv#FSn- zpd{q{n<88R=u>I%+D!}mmM-$aQuUY}^Yy{zu=!7sC+f#QL z)5r$gjB)4}Ea$D8q`lw{yf5hy$+5W`&Qe|Avt!35UmI-#d!$a0L33!naL@DW9+6|M zE+CM|DE)$M4?K`>mFAlIlH_X1;S~vptGW5zYo7^TKIDT3tg)+{epYeGnSgztE-ui*0$}^xpx%IU7AD_N~lm zlPh;!yk-Q>mL88%@5-bBNCi|5Z0ER5qaWgakniNXWv+g3H^ICJvk{z+DL?2sg(*a& zw8`dMmM{4T=4*`pKo4j!ZE;Fy&(4i}{Vma!M7)JPp%lrF-ZIyev{r7pAOQ0+G!0J3@DdPoRlEs~&khmWlmWOS$4n@9Z8jR#RjnJ1U+cQ_ ziR}{llB;j68J?`bygYuFnB^h#HmJ^HzHw*vPlxTN7sW&x{D2GHJ8+@PTQmn-tZE~^ z{bAEewh^}q=^~de|1QsUH9m*B#Q+!ccB2xu6xL+t+}4Q@;2-v~e8X)QU9fNx_^*TAG!a963XNNbrB~o9 zcXnez7<3Si{MKy?O*3AW|90D}CQFG6lzi%Ae0bKt> z*n!XAHePxjy{ZTa%{wgrH-DC-zEi?q`$?xRs=m%d%8yv~*jyHIIcd_5W9mj@3AZHmDo@44d!Q^iL4Z+FZyKMHFc`Mf(DOuZZASMI#f z*)sx*qGZbh8|~$8dwI6q=Yfsr-<4lyS03E($XyY}=jCa4C7WV4$k}&Iv$;WBzTFOe z2L}A=|AxtBcWqnnU6=u$2$t-LF!+8b_zS$Tqrakw6$=$G`M+TY76y!$!X7=ofEe?# zY$>?HTnJNue09M!bN>SCZn33*2KHFA=IjiutTzj0dhO7opiJ;8q56&#-m`mHWtp+E zVxT_Kv9es}K2dUEWo2SzMTsX$H{hmDx+~YW&H-^BYh z<927foL+dJY4>`$r_gCC|5pB{Fxq(C;rY97!S@3nx_hP3A-{9?PS}lKHQlm7-d%KE zxZ7w*%b-if3FYK}o#ZRH*js{de2ln0AHg)E);`9tuT zz2_SEd_jEvAU-#Gkv#1!$6LCnl2sA6!2LKjEdCFrjPngEnIFo#OJHmqK2@>-s_yWz z`>ryMfuSW2mQI%+F8u=p$Sqq0Cmt-@XN31K?fX|4b7c4ai;cOm7e05&ukOEi>Q1=L zgS&FL)q7v5*B9R_w@rN3z~>J6{rfLo0J2?UR3Gp4YJf2i z;7%}3r$IX_O18YPd{GW$2bR;LuuV0rZBxbPxnjf19)h~qH(GeFx=|H~muz>cd+UIu zAIF=|!SajcGaZm9_*`)A$v>B`hZ09uTnV4~6^rL@gBj~KYy55cdm5L+lLQw$-HCz# z4h$f_RWT1L?o>s@#Xp(%%b|eq4$!_S@cZ0Empm|Q61c)ePAig}{=fxiqlyRSpN-yl z!0Fg7igL@jQNIkHj6e6}Jl`#ovSA3UGkG#LLotYhokL4M!TWtG@GR`Qgee)1Nxze^$;m1v=zORj-&{ zdRcy_YNshD=kVeOUpJb%Uq1Y|hkh`c{sWWu!&^N5$?FSc`T6f4-96V;K+aa5u`g(j9=-~y=kGmgvdZwvkhwOa1E)1D6T_b;b z`lIQqp;b1*OF$=;iEE(qZEcGn>o|xQe?rDYxyDn|_gPiHD#kl;K2q+H>=aN%E@a7Q$!Fb5Zcx zLB(?mXI&W_s3(-)Lk7f19|IokYvkWPch$VtUl<+j{nCTCt}uU!XF^WgzG)jC9bFMP zKCW+vyz=>6*Vp%n3|$6!AEv|Qo8fo>j(sP6JuALYet)0**7Fyc&c8<H;$pV`7C6B!W(S%bmix@#+#F^&aOn)oEYrQC z2Qp?@qVe~>8J5#<8M}R^Wu-X^-Vr^}Fw>HG5!|#Y?t;xlbx(&GR>AJh?(@Ld00!)$M*1G=fU`<= z9lRO{m&8xtXJ3F`V6@nJ-tI(Kc$&T96WEiq_uh{-9NBum?A>hW-DX||FNW>jU6t#C zr&$kSI*J_vi=gn3XmE>?{EN}iPYhMb|LK9d%hKWLcV8C%YDs%DzRtd{34ZlV?8lL` z)^O&6PkV4*L<44serB4=)}qz><(V-c?A>O#G9Hq>^Fero^3FE#U;&n~qc=jdeeiP! z{5%RjrbnCQA6m}$mJUQg9cIuZ1-C8xvAzt-+NZ({yZ;h^ zjirRgVX#1n>V;Rt;B0iogFQei9>e>X?G^h^!7tcei#q0e5GxSW7WlDkh7a7nwJHC8 zTGXi13sve2snR2&N>8r%0#r_=>0lV_Nr&&h5Uver>iyQ{DjLZBaLyM;@iUaq{m{*O zK7rjNtjb8J%JBPf(<%Jb@|4%GI;-N~R}a)6CV#pKPKm1Y>g*|CP@(%V2WmA#bA#Lt z%?Y;wr;9@c`Y9|D6hgGl@Beh_(_WYZ3nyUyF{v|GK}`I;8WUHmL)5@iqoZT4^xB|b zxu6nUA(a3HfM^byPsjdj9HxH8^l1;3e68~2lVOH5@>INbK_@IZBKlrN!B|-Doczsn?_=E0Do^4JV*ySOu9KBtV9bpECHw@g=YL0 zIcj9hOBo1BYP&@lMq6}sJ*{qJEUlMSa$MwaJA88hZ$n`AzVWd9&I?x={c`w=)0X@Z zGC<7>_W;q555w_sLwEuF0lGQd8$=tcj)P3&Cm* z%WGeEn@%3WXtVzaX=)?-tau|&%12*cXzqs>nB;-iXRfAJOznM4)Y-{iF@hn%7!$Q6 zO$bJ1QXLF882)TmJ_;5d@@p?%Vmkj;dGN&<-W3oPA17GPy3-n!o;&BcU+F+1+}V6p z^#aa|zTd$;d!(`g_UOw3;rmuv0Ew9+EkjxMxR@$pV35S#Smo+Iq(3!loFkA7b$SD*^Hlt6UD} zaFQ(z{0FZQ9+=b$j)_Sv2Yx}xa1w*kt;Q?Q>0HPfJ`$=jKML8w%b2LT({SI1vw$-= zx6xF%3h*aaTHrxe@0AXD^2@QNy|MDRm#;7-#>(qnUOWEV6-GSoOOb0{Ug$MKN(J!f z4BpW3o&4+{pS=f*9px2}RBbb*ZLZopic7Lrpw6n+8a9^>$IQH^7q)cqjk9FJKE`#V1rb#_+OVK|Md)4o|SP`N^=;JIU5yEL_+dDD5!z zp7M*6vzt*8(Sn~}_C~bg@7V$PY%mqhM5QUHY!v63;1j3Q6<<`V&72$T9rwbeCM0K_ zGBvp!vVwQqaMgw}kV*>WB%IY-I#wBd0(##dv{a0560{Yxbu_kDO8BeQb)vlaUP(uS7VL%{}|D=z5E2?O|Fj*ZsffUb#sAqIoXG zb2xrH){cwh#8({NdQ7MdlENz!t^*SBkt#H%`4gk>_`B=J2vIXd`iH8#{tScwDa-NiY(UAe&L~AIQ^Qy%=sr@)gPlwVQH`&}&`<-!g)d$3XqT6Gf~`2$Y8d>icE#9j{@O z2VRTBH?UEU-KrPfU=}X&k=Lfps$B-*p%ic?$@lvuU2Wf);{SCgyci5O-v4|p65MSq z3+7z{s;VnZ9<2>$eQHJ*}|DoH^y)BL>@H`1u%qHUid(Yo)wLi38i8H+F3PAzowuDjDRVDC(M5(Rtkv7oPK)gG(%p8saP zg|X!Owo$lY+-5JdU$6J$3#-;Max0V|>$cb;wo&Rg-M``#%E=p4CXvX*7S~eAX!NtBWVTZ*IoB6c6Vm*Sp zD;FNQ2|f=TSsFE*8*(G`XLvOqHqPi()Xq-mT2@HK+%pmG*awa*nShs>p5?t`%{vdz zeS4fyy9K}QML8xAiTB`}0&mbg_}wpPXl2{$rrSP}2itytEem<@=oK@2zpO~L_Fii% z-&+sWRlfHZ@Cg+H*MIq{V_%spI}azc|I)M`-|%SNImtHq(Y}Dx00;gKm{7uNj*Wig z?}Q`V-Yfg0z;xIs)e4!vi_>zV-B-waKc6FSJRau7kkvP-A&cO^-xCbk$DMP8%zuhg zH_?7hV~8r8+KCS6)Qfo?z7f;+59%0cAJHLB+ldZy+DLSS(;A|NL{>A!M9qSFgB6xb z*uupgqE=25h}t-fB5LQf3jzqrMpq{MFz>6G;tst`jnUEvJ=44{};Uw2sq! zqV+lzqdu2#gN||3rxR`DG?8c%r_n^4Idu?i;nYmDRZxA@58f=gS%8cCh_-XuL9~O@ zW}=;())DREw32A|S);y)a1R&f67A#EL-Z7<2}JujjUuXWYP*?6{Q$=!lBkJ6PWy=t zaoR<6n9~-bBb?R|HLMPqgkjWI6E=rpqf|oF!f8HHE2lX`ZJc_D+Br=m>QJdR>SG8y zxj2$&B&Rl_E=~s&Oar-;U^o}3Xn>bnTXa&drY9H&i06F99Snz$Oq_bfT_ zB#rNpTh#GA00;ggaG~+-=FWXW=1<|Ylc&EqtYXuhEO_>LxAz{L)tMVwlQ7IQj66GsWBgG9?X?I&73o#Sr8mDoPh z<-sm$pN>1#_Gy9xe>J$M^DlR<6*7MRj#G(fy-r2@WD;)BF}9DJXd|a_ zM4LEu5^d(xO0g;UEN>io;`Kt9dCoc0hM;wq~YFNYP-&(@v zP;8XSiCQ=cMib8A*g-UxQwvdv)1li$#piK)ifBHkokR2gv7q%ti#e?( zTEb~D(K1dYqUD^X6Rkw*)$fxN30HG*G|?JP9Ykw6H4{C^>ENxRe(E^wBkHZ^xPx#5 zr_DqgIjtkw#AzkbW=@NUws4wzEA0QmZC@+L9ufyQO(5FNX%x{8PVGcHIW-XN3ZY)O z&Omv4}pglx;IBh4|$7vJMQ=A?o+Rte@QH7{i+a)O=Jix^{LIBDr%Pg>-S+K{Sff7NXIdHV}=`>3m#k z)DVuKrM&cYDR<1|1tpVJ1S1)NqBEz+r26&4XL)-kq84$%@$ zlZcja8cnpEQybArPDgf&VpI#NuL>2yHC)_Dw3gE*q6ayxBU;C48PR%9C87;pjy;4M zIgKUS#HoX5Gp81!Eu0Qu%fsx;X;&ew3IiOslenGJMxq^@))4LFw3uiYr};#?L+J*i zluNiL6dNTE(LPQSiJsy#nrJ_bp~}z3izzLoNbS|JaNt+Kg?jY>ca9V?{~)JUqC=bx zQ->PHgkUn2P^3+!Bl>u%y;n`S7!LgS5&pPCK}0UD^VAx^+cmMtt1*Ps6L(w2*+@77SUKvlZeJ~8cj5T zQ#;W_PDkz$g-h~s+)voeX(!PXPMe8(I6X)-ozpU+nVja`L*prn<8%_|aGF3gms1x} ziBl`lJWhwGkLHKco$w5Ua6u?GO6^38IBg_a%xMkL5>AVWmL+KyKXL7dDOUTs6At|4 z;6i=9k~>?4%wNsv2zAsNPWy@0a@tAspiag0yp?dBjeus3Ew71~*9LH* zyf*S8<%p#!tc6nGz~2;YJpdpMPd_6e#FUk~9^TpUNVpHml6g;N{R0ZvDLF3LQ}sX}zmdDLKMG06*9**5H)jJOBBBj8lo-#ISpSc$3-NzaVinDbDBvMzw8+j*iF>Q zX&lkWPzsyWQG{Kg*eE%O;&(Pf0$Yeib2?08ErwHtXe_5)MB`MtNqsccLO6ko>xd?D zT22(d0~?aHe4_5PFalj-ridz0X9_DE_)|bmqtC+~2WhCJbJ|5TlhY=mS)5iA&C%&Z z96$wxb48A5;jZPV7;_|no^q6@d!l2GkoogDO(I%=;q=Ga?!9UuW8uJG6bxC+on1oa zFX7Zqw2V_T(Q;0QDEUgAUW0k|h2oCb(C>+}XJK?C6y9V4wK+RAAO(Ez9UMB6#dBHDqa z)wjuQljPxCaQ26 zMRb5u8__{dNA`;h4{_Q@bXZXR3eZk?go_)A8j{&)uOVvYw2Y{QQ;DdR(-fjMFUK*2 z?VQ?)IyfELCran!w3}!or_DrNoYw54D?k*-B_xjKG>>Qur|CpvIZY%Q$7vMNgiv~k zQL+|g_Ar!ax+6fnjV4#geOE|3|TE=NH(Q;06iB@u& zLbRG_aEmXNa19qn60PObLi8Y~Lo|`raoR_;p3`=9(oOcVG1)}8k&A1IHgQ@)w3$XN+a+ZFPIT6%;o1spcvy&+ z!GXUk=-kbn^M%ac!)X@LK2F_4PjMPcv|p#<-XfB)qGOzftwaZs<*$Bc_YU%t{Zx=4 zPP>Q>bJ|LDgwqD1hIOnlYlxaTEh(QZhK7aXJQ7>iL2b^kNsX9cZJWZj4)=UT+YE|= zK=pRRf!_`>sBIiPT7b&y#Au>z#M&wS0kv)7;J_albarv)NFnn_acUtNjUn~5Q=?A} zSpx_Dm|)0Q?p!Qn{y0u^h$e9ACYs18yyK16?IfLwtFD8vTgTYk@TWCUoWf~8mB7Pk zC((3Hn~7#}T1PZX(5T=mfz^a_xHz9^E>@TrTw;H^Ph<@mupJKk61Y$U=Alfi-Gt0i zsn+Wd%JPG<0xpZyWKKBn7X@X-L77+y=2ofEQsBT}5|ov}QONo~R>=J2oH~hCa%v`8 z&FO&1kH1EzqLn%c*XkHssgdYGPHTzQaauyOo>Pfv1E(IMje^Si;8hoRfmMv2R*`9_ z{8~8hH-UgEznKRpqO!GMCF(QVNVQst3LN-bgU$i&+$CiGc1~M~c5qrxw3E|nqFp+b z*LRLD7(X&li6PF+M3Ikgf^a!0d@AEpuD z=HgRCQ{YdMe?H4AIUk0K(XLS*kcQW=M_19I=hM$U?+!hmdG7g~(DPYmpO@$KjuTU5 zCCYHcQ2+=29HGM(-E%RU`i$DF$?8xh1!Z|bnV2e_vKq|*2mbt^tN@Nerpo?DM5id? zw1a3dr;S8QIISjHrc*Ih<`XX0F%EVQ(MnEZiB@xJCtAblkSM;tmeW3>2L+uHyr8uc zt`iN7kAX!+r)X6ZhgDM#J~Vqa1Zz+{!wG1zMwB%MWlcQk8X@yHb6QNah0|Q3tvo*i zg5p{T4*Y>&Lii{1Kc5{VnQKD&XNNe=`lloGe5X73Ts}y3t4Og)apF`Blshg;U(-@*wP8~#Tg6dlq2EukOR;a=poOTg)a@tHZlG9qEE>6pd zMj5Z7K9Yn@pv_^?pgn62%L+Xoa~1Xx(R4AjYSTI3z#l6dangz7$&DNkO_#uFKhZ=^ zJBTK6+CbE;Q))WGDLTfc%O~pLG@WQVrwK$eIdu`u;?zboN6=ltX`)~BUw#5i)-hrY2UgViK>{oGa0}Iq2LXGKKHQ2w9gVYeiXWP!<)(P;m-9GvX9d;qNg~`CECwv5>bWd z__9w5_Z_Z-%3gbw<08`7N9_618$#L)6A;F;Tlt#XdfH>VJFu9w^X zV)sV!lTJG6;?ztuiqip63;t+MyNSkd+DbH*)A}b@U=8`>IIbjd0;l;z6W3!`vg04P zkgQLIv`^Cd;0{U(a=g07!GYfmaj0EWctn?w`8^nMx=qRnjg~H=iDvB9q6IKoW-wY7 zkJd=hayYFen#*Z9QHj%hqIpEM-U|PSCvvSD=Ia@2cv>xH4IKCjz>SJo#KV>enZKCR zJfbC>W)dyqG>K@rPFG=1iXmL7W26qE)ts7%)`->%&iCnu)Dk4Xfxi}9s00VObEJ^@ z>o~O%t><*`Sq$lK;IxZqqfW&owuNw$j~6R9_uM z67Jw)3(-za2kJ!Wx;X77+RbST(H>4~iS~IpE+%}6(=4L>oF)-fIE^Mcz^R?+Ag3eG z&;y+zj{Bbxr5on7ljsPiEkq4hv$?d6sF~AhqLxq!kMv6jTSGA{u!!0?%^_;%G=->x z(*&YUPNRuNs#N>lgOjj}i>*YXI31xu6wT=X(HKtqh{kf-Ni^>2$q}KKpjN^OSHnyw zZl}c}q(&Q^B{(`0Arg(wBpx%5#-SUXVH#~hQ=6?)t`07z^ZeMjFe$s?!0!o0OXty| zgv_7GsfB13rwXNIE^J*%&C)T38y1ev@)HFi}xwQ{acsX(i$8)P>w+QcgS8|!0?IX6J{bA* z+RSMb(H2YyUgoSvQ|nHxdUq;&Ud>=W9QXsll-qf0tfcI#CB z?jPrQdvqHcX81YGj=zu7exj#1?IPOGX)95M(*~jgoYp+&70C^9Ttea@PVld#t=1!Q2EzqCU`9&0P4U(GApM;)Sfm@PZ70q+DX*GX$w&&Q5?`?vzG_9 z9+Rs-pMYNq5aTtoLG2F-aNv&wEsX&ej}<9o{wPi@M58$!q?V82w1;S{PQ_v6{i3&D5!Q5lbSR zg}I_v!}5Qr)~N>${5hbf9OdesSjbo*^GlrCiRN)SOo`-k+C#K}Xy}wJ+P1$@%||yJ z_=`YA`6%X5I)uz$!f6Z9GEN(amUCK5v{I*HnOH`+TE|%IJfbz6W)iLCG?C~*PNRv| zacU=8FQ~puG!Sm!V&&IjB535ahiDV09YmWsZ6eyjX)V!KV~V``Uv_VRpDm)Z?VL(P zJ2=fG+R3S#Xcwn(M7ueS`ZdjVJsdko+{dYf=qXNzeck7ZRRwNXbY!K zqOCd=6>T6K&@ooD(u}$Cw{zM}w1d-DqMe-95$)o%oM^Y8`eh}ba1R$}67A#EP4pC} zaYXw$jU=jYY9Tt{<#_P0DDxnvJw%5%Z6!L)X&uoKPRocIHnNdZaF})<%pB*C*urTF zQ7fl$L~We9h}t=|5p{%8*nJpzS(MosilOz1MsnIs)WvClXcVW7M58&aB^skrZTF#! za4Z++6OH3Ei)aF;ZlZ~t#u829G?J)$Bmb)lR>CP&Kir`|}yMI2j*7IQk-Bx<6B(;lK_oCb)N zbJ{?(GDzvKE>sh)4r1|F7mA41aGFE3mQy#;gPg_?t>e@|v>vHk_W88n_qm(IJP5OT zEgbk8;5^OhjT_ljwnvk-qpT??Yv!^MO{So%B`9mb2S*{7_AU|4e~Qxd(R(2}f~pHPL8J z3y8*Wnn^U4(*&Y%*FblllP;cY8D0-*rv#9n)lRn1^NHu4cZHr$x(3@(>=c$E$6lWY z2Y$D3#CA;KIZ78YzlYNVqUj=^Q{egAK?GWF$`q-HZti|VO(hx*{8_r^b{n+X?ObKrWHF)}sPWy?LbJ|I?lG7%l)jAbhyfuVtbd1Rr5v|2qhPT9%Fq2y559*m8&@$hRnXiKw zl=*rdtyReU4V=~!ZRE6)XcMOeM4NRg>NtyV3ucpci^|&6>db=!e=F!IM*-av%abG@q!A z(X%FqS2ugmeX#+F`*c~wM#UXQ!~*x zPWxL$h7&jq5KZK?foPISCH4Ecm4w|~oJ%x?(*&X(PF+OPIkgbY^w6Ae5Ql{}CuDgJ z1Qr=%jYkjsdy#P;{JM9safkPM2v9zIhxptnK6AzA4e)vTGx(FzCEu;Qb3ys+96^6v z{q9&)8%m1D8Dk3<{*?CJu^8D9B3@B=f%jbXyJImQpgUW>yl`o#`rWaZYta3a{H{gs zj>Qav(l9l{eR5Wxy&C>K9Tf;Lr9 zJ`vBLLgWY(_Gd_OR8vIY8B~a}K_cG296Bo%Jc9~Rr3E(Sj(Rnf@`;F~`j6qCCc!^k zF4e%%p&NlIOY!fRuf)F!1%Cis%kE7W$PE9Ekdyvu6kN^WFGh(K0v79Nc?2lDHYpzi z4#2^M_@_m*$h)-2;flFY&Hf>TQVhnb6Kb=jzC}~plr5^d zt$ZR<$?>rl^mkxl223mupt1wa{$4O|MKcY}PBd>rGf4!uX~Ay?CJJd&-cW->!H`PL z;G;yKcMW>yqxU%B9ju}|Jn)q};U2EE21{}WdKaO05Bxi^@Q2*B#O~A+`#~=WQYjbZ zzXZAD#>DQz#GVk|!NdwQZzuhsCv1-#{QE)B#nc8ti4=pOwqqzKhAPBR9v*797HSs# zO(+bNt49hPLV;w)K+`Z#e-8w@8v})**@r*FF4dfE%4gu5jV%v(MJ#oJlX5e<2hhC? z-LFHl0nL4AUX5lYn)}gAKruaA3*aInie#DX#O6}!H>YKMDr+`J!n>;c^J(WG#^B>9?e=bA42m{G>g%!#xbVs zM>`kohw=2?V8Xvqrgf}GfT_dq(^s?!1)<~t7v(CU4)!ZqQ`?j|uaX*S5UCW4@|j#- zldbDdsd|_rYEbV){TcYDlR~=TqnbQidFeGRGYBO!s^8-3$2uCHw7QW{^q>$`>)Y_t3Mt{&rOl zt&CLaLj8CDW@SC3$-|WrRUSBmP-;eXC#a2%XG!8)W9XXc)qMkpP$4Cu>v$|c3>M&JV9Iy!49}Tu4QmF-e zl$}Bzteh529X2Y>`TC)c=e}e@l})=_^{; z1nSqb)HM+*q-b=#g1a8kTwxJZ1M5i9{W|sL3mig)CR7efzx;)g?YdCaF^R+2O?*!WwsZ@jdF`;_Hp>|CkuJpc3@_>L+ z5vo5NgbtkxM~B`4q4F-6AtUEq&Dkl5Z?1ggg^a3STTxduD3MYylu!5ud-rkOSA44l z%UG|M5o#6{QY^Z9Fc(hDMF%itHP6L+TBLBryY9GF2BeZ1y{DqL(gohXMQ=0reqZy3 z%dhGT^@~*M1|Q|af3i-{smpIs<&agRQcD+XY$(rxUaG^?eg{xFfMz+GC(tYx(So;7 zC$(tdN_H^k2&Fts`#N+^N9QhdzFIg3?<9V&Iop(nRp+IUb;ME(x;xR`f$o1m_ley7 z1J8l3OJT|K0qPB?|LjXv)NU>QEc#{(w$PB?LV-glkd%|)Sr494Hyj=M5L0?o1PW&K zBQ20kd0($$q*Ciiy!E@0C;UfU->26xQt2S3b_u3dj;ZwkQ=-t6(CkHX2AU~oevIY> zG-J{H1kL}#Kl2%K@#+iS`pu%RhhQO-;MMWqGN})|q)6~r+Q3z^Vx&(o(#s-Ju#let zQz!SHj^K=kR2n$}-lgcRz|o;Up?87i?G-x?hfZnka1nY+oyF4id_W&Vh17weR$-_H z4E1LWwHVE6H2;F;EHn$y{41JPG;`4GNAvpuFx_bW4b3kHykJM8{W;oy!qav%|BhxC znuEUsQ$e#0%^oyQqly2ps?>_+KhX4}S&!x!G;6>tZI98e2m`=G{e&xv)%pn>0tj0V zW#FUSDCEKE;R{Xfr0=s}yX5Qj0sR~ml7y~HFyVAe_)ARKiDn|2|3q`52pk-8gIZwN zQ^0&2`0O&{I4@Eu3WI%ih7E$RG&yW?yr<1A2qhb;o4ER4ni^KUoxx6kR2u38`Ccyn zT9bR7^d3BxG6i0-)%OBWB6Xv0GWbfZaCB%0m~x2-73_Zh)htci>6aM8tt?9n?957x1GsU+UE)m212KCXX{|@y} zqiIF+zi2*$=HUBaj-Xk>qkRud9Vm~fIfdShRO$mCB^ABf(fbGVUV~->n%+^gSBPlA z<}{=RyVdyLY3+khs>EPpg*w=)jG7uIQ&kN;38_?o@{dll#y9Emtlz=KU0sVHmagqPNtsv0L@V4je*(wR4;&quiu%vc z44`R8^CXxd+nW)<)Cp^4x7M=|O7$4)S#+*M=V|Eth;R-L$LX50P4PCU-q6z!OGW6u zQ|N=W=+O1At8%Dyq*4ybW4U~WCJ$GB8_XL*DGAl%Le;P)oT_DTr@YLnT6&&G_OE23C;Ov#-JI6rVGuvV1{fTEdZuA*iCA-1BVu*!oHJa1s~<> zzk&DAaqwP<-u+;PtYt6Iylu)Z)f*ZNsniEP$}8yIj^0t|{T!P0Xf8tY0GgF(E=IE) z%_20HVEW2EXiI2ETkS7`9>(G1@O(&XL(cF)w0nIEl??!X*D45&Ol+f%$GaJoo(d7*z=>;9k$3Z z;ONjUjD8Z$W;Aa>GXQ4DM3@Im9Wvr20?c<7titvC6I5icfN$4j`;Kj;f2Brhfrq%k z_YLwv5H3&cog!W+bA3WniDZETe*vBo{{(dr9EH4*GJp|2@)vX3O|&ExUwp$C$`Ub} z_F_X>D!#TRUg$5%E&ODn~tYkwXK@coLf)F$$2#rf!cOy4-OIxjNN~tDFU4pp9ifUa(Ra;6` zTP;PK_|+v5b#F_nZ4@mn?X$mVOY7Da`+mvRTAyXVe=236kH+ESE@u`^^bf)i+sH*lcc*Ocq3c! zW#jFt$anmcKiLbj5zK&tBAV|SQ@vJdx2wIdg9I~G!OZxkbMfsGw$b8GU9M3>Nu=)w za6&J5tTW)t#)vABk^Yg@9|^WG%Aa~dqgwr`yEJOFKXtuEjrCFGQMvgVInGC>qjC<7 z+S#8vSfeKRQ#)(aB!6n8Mospo-q!LUMN+*#)+w`gjyE41ln(;{&`MyizktCKw$bKK zjn$}WRavW55UZ?#$=GKrj4C2}UgWCfE4X^lU5G+!myoGRFSe;pN?j>Z1eJsNeXKXr>n zUG7g^sZm#IRPT9l5jUJQjNS#Jp)kd2&a1njL;~df>(S-zla+PcVastm$>t8*l`5tT zXLIub5C4-?0+ouWMHA7u^FU8OP7V zkKfJlzk4@Pn#mgG6WlR}jfaEod_nVmM4BA(RAM`WXV=Bmn{R zdXiq()9Xz-%e9MMH_+>^@+?=?ApfmY%(tsD+oJyMv+6BUum%y;T{2FURU5&miW2GZ zHk8i^pF_YxLOEtq^gRFQoAlAUIU4@&-cTza!aE!!r~#RhMW(zBnp#WBts1;;*2~4& zJf9`RaU_$3?{JVyx8?Ybf0S;X%th*n^P%Az**nL!+fN>NJuqr9(=5-d;BXl_Le z$4QE@P#+`5@YYs+6qtkaLY|sT97hSo8Lp3Gc_7VRxkB#vY)6tnhb4>H{dvN&(We-(4JXq?p`PAz9)V%A7jL!2AQ z8t}($;?_vkGT#W4Iw(grb672}wf+fAR$L*S42Gh?)(Cr1nl&_aw}C*dbf9qry3!G# z6l;VH$WZ(4JJ$hXI?$5@It-9=f;FPxZb0z7zsUNTR!hlsU}f3@bcy?T6l-c$y_~B~ zx0dD`qhR?{HW5CWwXAo6l*BykOYV4^7&e-PcQ`1u>lhBHJj?Rj4w*y9SVC6i!2SS2t|VlV z4*85t^c=&&6Xp}6u8uK*L{xOpE8Cq*px?&(QZ&&fiV(ZUIAWCR7|&AdLW-ScjYvf* zLTy@7(+K&h4mrstE<(ik6k<%$F(#9UE+oQdLp`z~j*xwI$ma-I+h18-LPip@kq$Y< zCdQ6s;oU97xb~FKkmpH6aeJ*ijKT9-2TI4V>^A`!f7AI{%-y2bAkrYpR>4z08_Sx7 zU;it}QV8c!XXymx+QeOG=y3^5b-0d^M;aPHgRbz*l*rSBY@;kkf7AOHwwU7;|-u7fD2ae`PgD z#7shF>X0)C+1OuM5FsZJvYie&(Q5(v3Khnz#mLH^1tlwK<#N9vGsZKCPpP!>vzjylFX5^*cW zPnk5?NXQyGWC0;RC#0_;gp#r=e*$^_37=*2ZQ^w(>v4$~J9Uf&Bw~6s%1#rqP={P- z6W1ucdx$Ys$5=!nT9OE#KghbYg^*oz$i;;Gx2>OLGILfEvbGLcXcLp3AkQJj#m9Yy zEFlr^kcj(~O(tZq4(TN1EPrJ(bFv6oq(d&XiQk~CM+z~X&@qZgL>qr)btr#36SA8Q zxy&Ydk3)JRi4m-0yhI|tY2#N!5hTJu$jguUEL%><_X+8uaJmLe`V6sj}UUa4!MGm?fjL=%-K%J9y;Voo9OW*GG{$8>ggD(NW__FKg(q1 zEGMKZ+h-ZhJHHGO3G<1uU&jz6VgW=@M}xGTEW5CuAKRa+6I=ba>0}=g~gP-X;<6k_ew=zWTRY zhumxvWe}0Dlw`l8W4uEm(n&;B%dPeCIXci5o3K31!ZRmR>|`C|U5Xv(Z-XqIY(m!8 zA>Sk9Ict@lT&?Z#ldP*j;?3zSQmlQNHOn82c+xqxjPjZJKE-_&adl?aq?(^hT4w8z zTM3y$NM9R4tbSOHa?YhyzPcssZ-iqV}=#bk8d7O|w z&9XGjggiUaXU%q-crypCbNdf4KGHEhA`vh6E0dY25^|9axr2~H{FO;RtsvxR9dak? z)iZFNBgBZ;G3dm#>+j}%mdUPW7a?ovkRPL7LB#m2#Q5=1pCO-+h_^{ZRTl1->0L+2 zk9EjmLeB747Dm}PpO8)+vIO;tluaYXV>$*My>_+sS0>Xtj*t)OkaX(Wb+?(HWioTp z2w6vm{1o+S0y1X+F@7H5vy6^byWS-cKFef_(V39Db;!M_R}e8iiWo2H7<5kBl};jj z{vdrel#oyAkoyT4Q;jkMArp1TQk&>C5z4Oo4n~NML1&*`-$nT;lg@XVkiTa6EIUBR z4+!bAOpew|3AtB?EVqfhP}XA?F;?gpbjaB?!e5yj&a5Zo(>mm5HWBhHX6q}7(M!jm zbIh&)65(sNr02{hWS9;~$Ch1ZoBCNMTew_8R%ZGvqr=Ruj|f?1+3s-!I`ohZMF*K( zO9^$K<}`w?(;<)9#1EACWMWLwG3Ye2E5T3Ee%U6-f%O0#@&qA+{FTYRAev-0(IG!4 zpujovU9(z2u4C4(;>gaRkcZQ7dZxBuVb7f5l{JRlM|Hd zzd^)Q9r6?*ll+x6GN9sC5OS~%`ISwypN#C1!}#Vp#@8f5ZR}^7EbAjA;&!^vGCBe6 z+DFJL%XXI#=xZJ58v?ybAYTE>+P#I4@7B>lzqN@|NYeN<#L3q&z9SiZ{S@t&)nyJL z({)HX676bKjkd{zjL{*_V6ovjD9a)S(=q7WwCixB-m3kwElDBdcWFNR=}5Kfbwc_~ zlO-ER$PaYLb2jlgl=X-rMuCoTo+sIz#O`PROeA+AoLhm#zSLcDTgE;UHmosrcr%$ zNIFRFs_m~?YZ*yqBYQiaIdq8JbrH@=vli2oC*+LfcIAUJmQ{JIaZeQtIVk6((=q74x$6uX zCS6X-mU9asUBi57xrqrRL?o;v#(o{+7KvB@5uVvuH|9y?QXuc2o!yv<*%^(6v=#aZ>6^Zb9mTZjW zQo-9gB%ObEJ>#!Tj$Kkn<_sP3u1&b1Oi8K?65AGFF+6b^3m+K=m^3X!2c={2uJ14y z)v1@697RHZ9pbaVO~?;`q`btc@qBNAM?ec^FfGK%X{`RECa;!Ry0`{xez_j@)3W>a zf1w~t2Vw+j;!$9nk}bXIDo|QME!U>`>C;)`b{9aErd%8BOCYEC#b^R#0;i0X@hko- z6W1;Lh&PH;7e%p)Kc*w2N`XQ~Sw*`SS%dIhUT9+-)Myu@UxW{A0#p5KkWVcgw0G@B zi>UJf+2_dRjH5bapj~_f5eX|v#G5)s4HEGrL{Q36ml_3n+;lmR{%#r}B4(f_&G9C& zolcC&E{4oN5+{&+MaQT~@{ht-bV-y$wroP48R#>nmR)Rsi2O8SY|}C5%)Tp+MEKk^ z03M(%>MzhC&4e7}uS_<8DI{~G4oQdjUCjtt)wAsGOrWk0=}gqeF(<#Xcy@mkZ3V=ok?sBFkSHQjev665-Gx8xXR+zcQH#D+$?C zhot)fE+Zj*{v$^bb7Xdf>Y#Kt!1X-_BRX4Uk2jfw{ZL(2KA>?WulCBlFM)@m~85>K;2|8p`y9mms>>@@V9V3cFnEaK=?7BirbP+ma zGeZ7==2d5zY;27r^Y?x}%bF8%7a@J62n~ka*Yj0C59*+FnZdP$pjEc+zC@rmbs#H& zp7hr&3rg-%<>`=g@xhhouUQt9JpV^nlR(8>04zgb^{WjCdpo)?+0xHtHC3N5b{AzcQIs^9ea!hm5fcHW#h^ zOx3gG*3ikCHVD`~89>>a)YgGx?P3zZnd3;x#S~wX>6V4-9kggVel?Tt; zj!ii!$XJb_F!5voMpUJ*?UwFvQUTY zVi(sSV*C+ejMXvd{)nq3iKwa&x&?|ZIwV~mas7+J(D?1LMiPl=o~WtYgrP6W2E;q}NyBP}vQ;Clm5=vd=QQjN*D9Na<+7^HR{= z%d&R-DxEDUKO0eGy_u$qmQ2xlk^*0b$TZqW!B8EN?yI;$3F+%W<)|cukX9YC4WaYgtmlcpI68LdMOAmr~D@99j#oYt`W(l0>X>*=$M zuDrMo64IBk($gyP33^%wr7JG3wFIrQRW@?!HXVrWytwlGHA_!8LgE(akb?<1$X~No zO$a%%r*5&FuFANY`D>PysjE)jPy*e7JLzneozW(eXVxKyVMMnW8N8AhKlSishK)pQ zArVy;?uRECcFX3vM2Dn%GOpSF%8))}Fs)uJ(;?{!jVq0iz6_Qba#}8QjMG8sdX1~C zzj`TjDJ8VK4w;4#T_OB&8Zj(723?+UeT&T*oiP7D2(WqpxwH28H`dLgKqn{7Lo{`Hsn7BM1)+e zL()Yc*C-%8y>2m3vfa9J+1Kqi%Rh&Bvhj-6#id(AuHU&|LS?-@Nm}l8_a!u&kOv9r zD-=0Q+C#|GIwV~sa;*hY-(m0KNQ}3~4(nmsy~&%LXLV8OLXoSpCn`3Vo8hZ8WgXC- ze)|#6_IKZ<=xeJMSnhW7CG`orn6(t$$x=$$*E+^H68|ceM07UD$<7=?zN_{M({)I?e&lN8uS`0YjgT=qq{A+T6=4`NfEY~2pnFHI z!zfNq$?o!&Y%-Ad4`af_$3?8!lW}0lVlGPX=17h8bXln~LziUPyho9~r*ts7#8lZq zmpQVz4JBAF9c+SKBranqe4<^fkluxI|T|a1zorMk`M%uN-_5nAM=&oJ7Sx{>|oey{I(i%Gposo;Q?e0vV5FLmP zf4g4NnmG#{c#KTdjii3<>=Q>v!d*|c^4E<1&#*g|gznWrUrQBxUxqtI5@UsqL8rc5 zA^zHAgJL4&(>mnqsUqYRETr6~!A zg0-l3lA?9jMca@nl2@RS-a`zFjzLGtUCXp4?!m(QrIRm>bb8!1j*w|qzrriif#_to zs~3R=TfK(JswwyB#6vnL9T<0o`D^wS-b5X8bE>Gbl7)|wh4-+IK}W(}Wyk`bw%uFF z!X`Qp9rt#v14zrUBwCF{bH0BQfblnDZtG7u?pe)hi8oiWCiRw*nD;vR%zrmkoJ1nV z&nLzl9fJ;ZyY6XijMrpo$4o+I=#X@f+jW|dDOPV@%SK=VA!BvOt*K(@D)dOBh{1IX zI;8EIqZg_ICA*|Eu=I*q7p9pk*zd`)94kwYCuFIl6Opb?`~YsuQM32Adud*R68 zHpg}_onN@awh*Se;`mncc>$UdsYo zP!eXFo$V86Tc!rO!yNP;I6OU*N+cR3qPBcjv{}nq^HC#2>RJ{X^+Pdo*kH>9>*x3J zb*Lp~sJZNKzToH!GQN0YEen4<{B)opQ|( z4zgrAtoTe-gWl4NcZYckQT=y=CqMqwzG(R&!e3(@{@=;J{Em3~HP(dZWr@PqSWNzw zPmpFyDkcAe_wco!C8nRb>^5IeswE%h4>7>$ItOp7HAft;`T9?B?GE>!)&!S0i;5%*? zc1E#w&gp5isWDmNuXU_Lhwmq#-AuElq^hMkXr&kcgL59WshzT6(Ba^1hl;o5SqtmPbX#8!V>R zzf|t?ttKP~7v>Y8Y|7VAADgOP%#;myoK5YIZ|Ux^WXhcsYb~H>PZpNF{(x_NsFA!?tW)XOF(aLqM!2;IK!y8WJ81sm+DYaRGKzh<;ynpv9~Cav9RxL zMCznPvJ?%ulVh-}d2`5NbkWVJjuKyV+VpihHRy+5Qhhez7IdSc^xLULeec-Ru82Mw zL|uxVL#{j1@7Pn-k?SFPR;aTteEBv=IWPwQ19ME7Hn1a?fZg{tgxl=uOB3-j#Ec)i z$uX!?Uc2YcEE-bbtWay%#Q62B4a)ZA^(-o%N^{61XZmetUudwYuL+7q!sBmdWI$*w zGRG_Q^GPU5Z%S?X1ifze6lmW|_;tI)LsXnwkIHt+nO>1vn0Ki#Pc6*5q6&>Tb_|*f ztt8OYiMS1{Ca<|mByM2QtvtO(LFrv;r6PR&MvryqJ>YS;ulP@pDBQprH$d5?y1zq4 z;f~sZAb1^OSRBj2-oJr`<%4anVxKd}s(_x^(Q+p5s-5Set%(Fw^*rGctr zrcOX!FBy57E^=Ny88P=C79`T%VuO*(8{T3Gy^+fWcinlZI=@JDq#$C3BbK78eC-1s z{Ku=3>)N%E)g|gjfM~`TVJBTi5_OU<%{fQ;-KPR)PV-5uxMwE*s zn^;=S4_Cp{hNr7t#jl%KH(~jPHLE!YwBecRrB$N)H>{r(111#%CT;ZO8#b9ToY!)U zg}GL};%ccAs--6L*>ilY{6RM?VRZC5&mKyD$=KGg32JY3A{#Ca&7WKzg zR7*WrEp>af)b(!sqAd+({RJVYN+{UhqW5A*WONpCH~ZWPX*iJPxeq3S4*8xEp=42)B)8}6RN2B`dS`cMb=Xzs-+sMrCz;TUH+V_ zmb#0m`45!-mTJK(tEEn>mYP*9wR5%9{K#s_*Y8wk$LVURrPWf`RZGpipPDb5*R=b| zlA2I0HMCl)p<3#tf2%X&gpQi;YvVWR$Uf@)YN?Z}rKVL&9b7FnPNU}ESN9{T1skfR zs_2v-Y&}j?OWj^Ab=^Pt)rp|x1wX+N+nJ?3LJGp82$K;OBCJE$fp7%j2ZZYgwLW5& zD1@#EgApD_n1-+nVH3iC5Kbcef^g@fd}gV;gIS^xdLpDDvp$&3m;OqTR6$VW-qS z0o)o4Uv26JAAuGk;Io*-S1ls7-vx}E`g>NA<_8?16@ZpC<#YEzywETVqtk8%bt+~N zj`g%CQ28Hiux+-M5Tt6M!t7Zgz;NqXh}QIo*SE2z6U(7|owWjzoX6FAYXWHk8F3b2 zLFuf(a{<$k{4@WYt1}r-b=ST?gL9AdG=Z;T);7WUMew#S6OT+Wzk2JQ^LC-e3f^`r z1Bs(mW`i2?0vT?^fH}gcri!TTtbYDPtHBVw?S^twxtW0xrSj?tmpIUYuGor25 zllY#QnT{nNQpVJr&7=~O#058VX-zLS-ko@urWe2N)+|o3M%fByTH_EpBP6I_fB|3@ zlxxVn9^~MB>i|0-SqP&Lveiu<&LNi#%d3tjo_;njU7ap9#?zWo;;r0~q*IeK)q_s6 zMx`RUPvhwOH4gS5Q>+6hZC-`>*=l^1#vifIiae-C3t{1@_%`iOinWnJopBiJ7RO=# z5!lb;Z>l+~0}TsGgBLEsyVISSfzo;bBwM-~_cEp#dEEWAbE#EM-1=K=1!dEa&M5UR z?nRKVQoQ#l-q(qZB)|nBdlq#h{*~waAUe$Id8`@-J6f7AU3USwoex%Gt`A zMVnA9pwEpIWyMgc@QWN+b1O22CzegomfeCrW&Mp$oFLR2RJMWF$LM2?5W1C z@9&^w23KV}Qy)11U!pp5Q=5|iu}iBn(t~s1!MUh2xu`SWf&rkcGjj6&*)GxX6BgcX zt0%@`R~F3m6MnYLU-;Zzf|X#Y-*LaJ%qpz|QlTviVH85P+Otade=&7;2D)0o0B2X1 zogN0)=(~8NS+j$;p(K^Batz8>R8OMS<+#X$)W*fYw5lw}N)&;e`CFyKfS+JbE%+?T z=KNgUK7;C1yjy+fWvWY4Ctx2l6Rtl1uaJn}K+(zyt`e!1Uq>tF3@RJ|_c0cfh8Eh4&Y`Bl0VZdDhS_<%&}Qzh9$y}4NW48oIJLIS zBcrf)E(lwwz?WK=(*tY6sniPCQjv^JprG22&l}Y<*yr$oZED?}C?hSM@i*;-yR6%R z!Gr3ndSeHbtO;PTxtIm#d!)_xNefUP-vdLmrF5J6DI&n%a!C-S0uSk}8;OopL~8w{ zC%hsh8_OYle_&Olkw)^YihT4R7Ak%!VNLS~{X!K4KPVVHpKPM_ zBeP9?`-RnhY(spsoIQ)x$ za=&1#I9Y;Zt>29rapMLY8T&xFF9K-Iu&dWAwG_z(!c=X%pzU|~5@e$Up;{Q!U*;h} zJ&b4*WeRAy%chUcLW&@YTUE*}05>zc6n!IB8XDpFU!)m4>B zK~2z$7Rc;26L(yqd=ACPXBy=(l5_IE|1*ydQYj)aSu%GI&wZdYcWESD+KqtYsHm2g zq%vHL`4r=a1R5hyMm~Xzj6y~}tVGVJ4{ zsDfy4F`9@Me|^dtuQ)j=EQ|(j{qTEEiT#aZ@iz*Wl#MxHG>BSz*pH&-Ue+6p{Gh#T zKOVLBv6t|8O?$-bXHVm8)qXapc2%WlzEeC?${LODd{8d4nYD!l@)V>ejWW$0mWy>b znb9D3K15c57oCK0raNo^65}Y**65<`V2(0?8Jk86b)7%N#zuy-A`|f@6ppguZ*z#> zO4(EVkvk&2j5X&0cf|BE_8zZ!N3=Y^Iy5@+4|2GlY01#2#RH-ikBM^Hup;;Q;zy&@ zePYr9R-cQ1#G(VNFVFs0e1Z4i1VmUomO5RGZ9}$*zYefu-fWBLQqFqvi|>fMayEn4 zeMkIR&K||z)g5w>MRKzEAbyiC^l|T2A}ys*ks{$XKZ}ht%7}weX=JfgXL0N=GP|r~ zaTZw|J%B9k@*di+H0wBL{|Ie6Y(kD9)s|sX-y4Wpq=Nh@c?269nJA2(v3dNdfnxDz zNYt8vV)JJ#mgfuWFil-h8h1~61hd3J;dH;o5iBTtTCTly|3A`OW#y0bI*Tr+k*+69Np5x38 zYS0O`fqgEvpJ300%y{@74b?&^6D{hHKis0z=j>B}e*c_p;IpoZm%m_>LteWo2Xr3P z#NXVa?w4#4P;0+r;~|)zWE1c<=_H#`ALSJP8wxu#v2O%zk>}N-A<*hm%mKvHr&xMx zAZR$|83`5j$NnHT2P08GoLws~(~2?XB93k1@+sDH!jG7CIP0e#?kDFAhx=hNP93#I#=NE7cixm2X2>zO_H_jS=&nc=$By&fXNWPqT;yt53S!Y_`QYl|)9MSC2}Kxdr$8L2NtC!h2=lXuw9iOdT?$e+mILH+4y!CjKLO{jYhNRy>kr1Gi})FTn?PAu%FQ#wnqDg!xLK% zh&E?fheznAvSG8VrH(F9n0mRxBn^HGyFwEW=RK5oJTKlIwuy4*_5ycqBWL6F_)fci zn8jq6Q!{bk;(*w22Gc6qaZDZVSc9f8({WV^#@`~qhg}kE+7ROsQP<$ZranDR>x|WG z?F)6m+A77c`w2b0&@MiXcHF|MBP5V(dX8AYfw5ygMwm%=&cSj6~TisCiQVSp(feFKPr*(&;2Sz#O( zmR9j>;CWz4_?lzr@eP={&8w1%A2Ze;hnQ>>?sKdYKeenl{ycky@fvx>hksxV7>~^p zKmEvZd3LtQy1-(1+mFS93#>O!a*87tSktgZPBaM%E3haAf6>-zOipo!SideIR;iwK zdWnd;$eQw=t8ta^Y48EPP`-K8yD4!lyc~P@MjWwGSVNvS4$;@IvyQdmG)ruN<|KDf-*^QO;=VZX4h zEI=&$h1nXlG6UM*64T%8eB%yqIJc8n;aUH<_6v*Sqq0SdU)hFG75Stc?QyMoJ>JDaF{H{_l;@;i%RXTQ+U=ec- zqxnfci(%JTD?V$6c;On$Zglx43`U;yAB^0vTO)}jr8u&fvJJ$hSs zT;pS+<8|g81~npNb;F=qNA3ytH>|#JUT58)`m^gS4i6eS{m(d$9`?jZyunrg{N)Xn z)Z)}5Os-HONQxnUayg3H5nyn|HqUsIGbm-XJD|WhIC?v%CiOkaxcL!5`<$T$HtfHBY2~4 zmC?bZ&4#Lf?v|ZVE2>^kY@pPZpAeb1*!1AY7Xu9$g*^+OH7_26zv?Z1yv0&Oj*n;h zk)mrxai804A!FBzkN(YUj6EzG{)@`cv3TjftRrWWiuc`R3ve_t7|s81wJxewMyBIr zpcw9EYrNDPjB7J9i2ARaCGZB>tGaM8I(af0?)q5U9(!nB2+i1#a>u0_!Iq+aS+
    %nvrN3qf#?Ut`g2jvGtcN^smCpclg-KUVOfqxp)Hikiw<>~oPo{(rVRI~40Ymg@(vRXX`;~Tn0bqk zCc$W#sf8;jO@_qC1LCBaf76Hv2cyT7&*}br-Z6C3=7Q1)TSh9*$sQ1;b$CL1TPUeC zZkG?!Wce^(l@H7MFeG4rqj10kEOH)Bo*WS=S_SbYNPgcS-mLjkPcXxN1EyB!au>{S z&{+F$^-J-4 z5VtmHJ3~7B&3-1HTQ~TVj0UMi{Zeeh)t^L6FwbVa#nNCthV2lQ!F*JB-jh;PW$2vQ z4V1hfhXd-;Rks*p;X~O~@qvYhH;9-oF%XyxfyEi2&VDmfv14*loVUP+X5x;8r?7LP zcL?v$C2|6RBLJS0TR-@de$$*obDbHJu_~LcW-lO~Wj}T43uc>g;X+A}(_o=^JA_BG zvEqvm-ab&K;9tS(@;2{kLyh41*uXMmsHOsu5yqQF{5p@I#xdni$+y->GUh&;fvhM3mu(jx zgz<0`%~ z7tEe)psC+E@lk!=y!IJf$U+J;Gt^$TvZ>dMQxx0!O<{FV3qZYPeb!s#M2RzN zux#;L1nORMh+ElE z@g^QEz$w^A^~jKyUX;}6d<9%13{H}nQMi!Es_9knOCz2b0$}{n1!seoy$$U7fbC61 zr%1l5e&8Br$f*S|Wu1CkFz`y6iaU|Kh&3%<(wO&Wt)hZ0m9+})nP!DJ%=n(E;+GM~ z3qi`O=ePjLnQ9HExYdNW4Fo?!{Z_PY%11MYSkRQW&Q zo30RFHbaxPOSEauw=|sbiYz6p*e$dodf~z-e5T{H=sZ!`9F5fDqIL`3Ha~MG!Hn4U z42AEU(YAGNmPb*mGf3mzEKkm@ce6kGkvc{FQ;@I2cSzAU%Z-EzkZ;CY7tT)3D4ab( zeOq>Drnxh%lcSJyaM$R#i{^{(tUQhqL4$=+nU3h@a3d@s$uz{fZCE0iP&hjU4n^CY z8R~J!(|ir(w$u{EYmES7>L9g#O5HgFFTGzoDq$<0*Lsnu%~gT?@jQ;}s_g7g~r=rWO+6XvOiug`pZ@+9QGap!{&GaA5=}Ka{EC0Vx=2 z!qhzygfZpkD;$%N!t>|s=g*x#BmY;Z&1ENO0{6VeJ!=Q&`|}m&E7ZU$o+qY`_g~ou zQoJ)&QuEJNMLkgsn^b;}P@#VKKe?oKxsQAPoF@DXC5rx6s8g!A-#e1XoC-Urqlh{T zYv<+XJ>>809%X&1BAh)>|0{IST2=ARX?ddYpsqr#HCJ4Z=F3pF1#S3Cc+_jlH=8t# zYLX~x%R>Y4mZ~-vXWR0&GA*b96{mi@aQ@8AgT3?WJ1$6crh0C+Y`F1;2IEXdG#Yq( zuQ+;6x{7+fujn1a8<4b2^>vXQ!#gyU-yMjD7$q3X=T~BGG|S?+BN@ZQhcUcyU3@p;n`I?v;Y_I~ zaoaf5!WT@5Z#wXt8syj|xzA|axtO!K^ItH{h1a|D!CfP{L%iJCZg*2q9g_N;Xw{Cl zjFI2X8Ulwuq8FT<8C>u$%dJ)LZ$NH9!M}mCgB)=Z^sAWKj>o3Tq0>D7453Bt}ASYE53@BI*}p%vc$-#*5-s2cE!&h`2cP$~%(9 zs5ov7l)M+j!Z^MoY!@|21|0s$G1v+hQMFe$B#R*(c{tzFOFY$)zr$LJpiX?`K*Tyf z%9@0J<9xtL?IrGfz!B{mysuRI7KNrt`xXI@)V^8H2W-*4na&5SZz*IL z;fV`=L)Ju4mx(^0Z9H!s6+^7s#B%2~K|36po}vDVTIEn7B|}{*o{Q)8_~IU7VLV@1 z_i?Sh6+WB*)5Fs<)n+2LGjC`*loV*dn_CR+%p37~bHy{A`6@P3U?(t=|B)z~cHvfj zG*R^J!g~Zly^W??UHFFj<)|Tr{RR&&T!g^^7RUypkiP6LdUfU54bFonQ;jVk3sN5H z$d)PZD@wZZra@i0qihOJqZn+NszY4v${%J2MVp6s)B2lckyMj2)9f5(D*MTZy)boq zH!Es&b7{w<6NyhZTk1d@uCK{~7!F-vq!;GMgnk8;+4 zAJFD{AmU@t<5`KO?Ka082uM{YJ|}&xvZ*uJnJKR%J(EzpF@X7t|uPv!h=VeZLWH+pp{Mo3)kg9l|(AZ~3)pHwzfoU4ff1&N|=AN~ycQq1ndTkt_0#Kt~6nb({mF8ASS`DD-Z zfB^+ZE+jjb(d5YHFt?$hEEXM5@(YPna4-t8R|3bL_rGghMDi)6yBiA%}G==Mh_chwMrw{ z)H|^>ME0JbJ#k_~blYH@Ey~yz-B#4@i<$g;BEByc0X`C=`tnRRqIg$dzL%NbKWj8( z791L!F_`zg@HS zwV*&l@cs;r4KY;PRMfQ}B?a4_sK;iUqyyNy zE}FpKWBe>Hj(?UnHZ_Lj&N`*^8Fmn#g@GH6&||34S?5IC;)zrFAzpLMJdR6QMU&@= zr0IO1vhY?wap80x&RPY{<(6>>xd;mp)*zH1oI&^%p$kItJaOnn-e39gW`Miv?7;$AG|HTv&Y{?BMnIBX9{UYAo z$S3zGuD_JyrrhKB0THZ!m6yQfsORZS2NvQ_r~`ixUl;MRuxUR97&fd!Y&cGIq4A-o zoORa6hlycpj-R*qr@ik@Jhr7cW}DFY^}F z=j-rv{5npAH+NrJ%_qay)vxj_m^|WD-V2XcU*-MqxbP|;%VLU?*YfcUmWy{^ze-pKK9q-b8`zkE_Vcu~;dq$P6m+w}~YWa+g+902?+1fL1 zz4q*Ec&qrgbvz>=U(wfA>B4t#y+ zSt72z#oJjAvvVkKU%PS>Rgqx_`EVf7X*#$4s7Tq!&(Kt=V75u|?9=^(9j82_`@70P z+Ws7>Re{QKQZ- z*~i=(>MHy>(aIXyd4un?;|~F9zTvaGIEWR6yfHgNoT+9T9L?tb3jDES5G_FcanD`1 zJX_&wM>m|rDF>f%CpOZ1yl&!vm> zSe`9+_6x=3XLZt1k^c^VoX#MTx8Y0}hE~nd-o{~7oc20EMI&%HfHLMvj4*BC18QE~ zLCw~xJv)j=Y~k6wFO>`?!Wxv0E|o7Iw4Ga?L0E?HDMAIpU4%zJ!V)Gz8-$+`8bMS# z!t5R5-g`V5#`Johhtr7@DXmKHQ}6Q;^+sg}Sft zvjD@HfIHxxJ1Y4BAMmr#aPb3vgWo(LDn8_W_>Kc2avN_PNV#K(6}`6cFjiKazKy@Y zSQqj6cC>$8MAS$8xEFElBOU=#tsOj;uih^bcJMg7p4iEoip4vy6wpOHy%WoplGKWI z6@TsIah|xvZFceO0El0*o0l2ec0Njlupkl-Etd?j!Su@#_yd~-2M3f_6`Cbh?n3(^+{_)A{W6Xm>5l$K9ett_Rx z`sLWW9v*)dzhw{xZ@YtH6IT!LF!6mk4{b%zIWWlsRhwXEwy?i3u{2M+O`C}(yU z+Z2R`*LOM0qr7&EJS-LFALf%hq~hy``78xdrX1(zAYj-DKDvAMN$iYuEpYR^nuq&c zolI}h1%LCr$O1RE3P36)QkWNzeF|?iK(>4(emTKot>nX4AT(l6Hwv4WQR!-e+-5gc zrT9urao5lJ1}0OnC03mO0*ll2H;UU|@L?uch%8MyAclR(+aqbSzvK~o>RV#XmwZgU z`fml`jB6&YC!OqyyF>18-(K|PxR)* zyC?ary0Pm6Fs;P&)Zqp`U5#8{yyF!AQA?E}wpe`aP2!$d(eoSLk~XVR_Go76cuEn5 zO#OyG%Yr(ESmt6FgP}*{>zHQz`7NKwOb=mWIC6pGAu+y!ua&AHsKyz7jdd;l`wSn+ z`LtCc;~a0{<>jB_s`vZE^OzmjR){ywbBC8^{(;Bl-$uczFRchL{d>%GxPA13-RQ)6zzzl|1p4W-ur{KH<@#?z3vv4TF%(Z>b)xI`Z+ zeO#fBtN75m0a5$||GeX0csJw)sQB3uw;W9u^^0;)%53WSYjmapy-RLdPE^q{Bi33S zr&GnpKk}A*PnJ0MBcBRS8-9WR7VnjE2}i*+DY%T_5fg=js+yQ75VI72@j;XG{6*e| z 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 diff --git a/dotnet/extlibs/csfml-window.dll b/dotnet/extlibs/csfml-window.dll index 0570f35389453b2a65e4ae45ad07c5a4f1050a2f..b45310ae2a769800a01315e31ef0671bf23a5a0c 100644 GIT binary patch delta 3839 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 Z-ww2Bwdho&%zQc+U{gB;Gj`(cO3qh=PIvL>#$N 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 b=naw~#W373$uQHf&`=}K+*ajZqf`GEt8L%+ diff --git a/dotnet/samples/opengl/OpenGL.cs b/dotnet/samples/opengl/OpenGL.cs index 8e27fc0b..f84ce438 100644 --- a/dotnet/samples/opengl/OpenGL.cs +++ b/dotnet/samples/opengl/OpenGL.cs @@ -26,7 +26,7 @@ namespace sample_opengl Sprite background = new Sprite(backgroundImage); // Create a text to display - String2D text = new String2D("SFML / OpenGL demo"); + Text text = new Text("SFML / OpenGL demo"); text.Position = new Vector2(250.0F, 450.0F); text.Color = new Color(255, 255, 255, 170); diff --git a/dotnet/samples/shader/Shader.cs b/dotnet/samples/shader/Shader.cs index 74205bf3..a8a765a2 100644 --- a/dotnet/samples/shader/Shader.cs +++ b/dotnet/samples/shader/Shader.cs @@ -61,7 +61,7 @@ namespace sample_shader private static ShaderSelector backgroundShader; private static ShaderSelector entityShader; private static ShaderSelector globalShader; - private static String2D shaderStr; + private static Text shaderText; /// /// The main entry point for the application. @@ -122,25 +122,25 @@ namespace sample_shader shaders["pixelate"].SetTexture("texture", Shader.CurrentTexture); // Define a string for displaying current effect description - shaderStr = new String2D(); - shaderStr.Font = font; - shaderStr.Size = 20; - shaderStr.Position = new Vector2(5.0F, 0.0F); - shaderStr.Color = new Color(250, 100, 30); - shaderStr.Text = "Background shader: \"" + backgroundShader.Name + "\"\n" + - "Flower shader: \"" + entityShader.Name + "\"\n" + - "Global shader: \"" + globalShader.Name + "\"\n"; + shaderText = new Text(); + shaderText.Font = font; + shaderText.Size = 20; + shaderText.Position = new Vector2(5.0F, 0.0F); + shaderText.Color = new Color(250, 100, 30); + shaderText.DisplayedString = "Background shader: \"" + backgroundShader.Name + "\"\n" + + "Flower shader: \"" + entityShader.Name + "\"\n" + + "Global shader: \"" + globalShader.Name + "\"\n"; // Define a string for displaying help - String2D infoStr = new String2D(); - infoStr.Font = font; - infoStr.Size = 20; - infoStr.Position = new Vector2(5.0F, 510.0F); - infoStr.Color = new Color(250, 100, 30); - infoStr.Text = "Move your mouse to change the shaders' parameters\n" + - "Press numpad 1 to change the background shader\n" + - "Press numpad 2 to change the flower shader\n" + - "Press numpad 3 to change the global shader"; + Text infoText = new Text(); + infoText.Font = font; + infoText.Size = 20; + infoText.Position = new Vector2(5.0F, 510.0F); + infoText.Color = new Color(250, 100, 30); + infoText.DisplayedString = "Move your mouse to change the shaders' parameters\n" + + "Press numpad 1 to change the background shader\n" + + "Press numpad 2 to change the flower shader\n" + + "Press numpad 3 to change the global shader"; // Start the game loop float time = 0.0F; @@ -176,9 +176,9 @@ namespace sample_shader // Draw the contents of the render image to the window window.Draw(new Sprite(image.Image), globalShader.Shader); - // Draw interface strings - window.Draw(shaderStr); - window.Draw(infoStr); + // Draw interface texts + window.Draw(shaderText); + window.Draw(infoText); // Finally, display the rendered frame on screen window.Display(); @@ -192,9 +192,9 @@ namespace sample_shader private static void DisplayError(RenderWindow window) { // Define a string for displaying the error message - String2D errorStr = new String2D("Sorry, your system doesn't support shaders"); - errorStr.Position = new Vector2(100.0F, 250.0F); - errorStr.Color = new Color(200, 100, 150); + Text error = new Text("Sorry, your system doesn't support shaders"); + error.Position = new Vector2(100.0F, 250.0F); + error.Color = new Color(200, 100, 150); // Start the game loop while (window.IsOpened()) @@ -206,7 +206,7 @@ namespace sample_shader window.Clear(); // Draw the error message - window.Draw(errorStr); + window.Draw(error); // Finally, display the rendered frame on screen window.Display(); @@ -242,9 +242,9 @@ namespace sample_shader } // Update the text - shaderStr.Text = "Background shader: \"" + backgroundShader.Name + "\"\n" + - "Flower shader: \"" + entityShader.Name + "\"\n" + - "Global shader: \"" + globalShader.Name + "\"\n"; + shaderText.DisplayedString = "Background shader: \"" + backgroundShader.Name + "\"\n" + + "Flower shader: \"" + entityShader.Name + "\"\n" + + "Global shader: \"" + globalShader.Name + "\"\n"; } } } diff --git a/dotnet/src/Graphics/String2D.cs b/dotnet/src/Graphics/Text.cs similarity index 66% rename from dotnet/src/Graphics/String2D.cs rename to dotnet/src/Graphics/Text.cs index 50b81f7a..61447d30 100644 --- a/dotnet/src/Graphics/String2D.cs +++ b/dotnet/src/Graphics/Text.cs @@ -11,7 +11,7 @@ namespace SFML /// This class defines a graphical 2D text, that can be drawn on screen /// //////////////////////////////////////////////////////////// - public class String2D : Drawable + public class Text : Drawable { //////////////////////////////////////////////////////////// /// @@ -39,46 +39,46 @@ namespace SFML /// Default constructor /// //////////////////////////////////////////////////////////// - public String2D() : + public Text() : this("") { } //////////////////////////////////////////////////////////// /// - /// Construct the string from a text + /// Construct the text from a string /// - /// Text to display + /// String to display //////////////////////////////////////////////////////////// - public String2D(string text) : - this(text, Font.DefaultFont) + public Text(string str) : + this(str, Font.DefaultFont) { } //////////////////////////////////////////////////////////// /// - /// Construct the string from a text and a font + /// Construct the text from a string and a font /// - /// Text to display + /// String to display /// Font to use //////////////////////////////////////////////////////////// - public String2D(string text, Font font) : - this(text, font, 30) + public Text(string str, Font font) : + this(str, font, 30) { } //////////////////////////////////////////////////////////// /// - /// Construct the string from a text, font and size + /// Construct the text from a string, font and size /// - /// Text to display + /// String to display /// Font to use /// Base characters size //////////////////////////////////////////////////////////// - public String2D(string text, Font font, uint size) : - base(sfString_Create()) + public Text(string str, Font font, uint size) : + base(sfText_Create()) { - Text = text; + DisplayedString = str; Font = font; Size = size; } @@ -90,8 +90,8 @@ namespace SFML //////////////////////////////////////////////////////////// public override Vector2 Position { - get { return new Vector2(sfString_GetX(This), sfString_GetY(This)); } - set { sfString_SetPosition(This, value.X, value.Y); } + get { return new Vector2(sfText_GetX(This), sfText_GetY(This)); } + set { sfText_SetPosition(This, value.X, value.Y); } } //////////////////////////////////////////////////////////// @@ -101,8 +101,8 @@ namespace SFML //////////////////////////////////////////////////////////// public override float Rotation { - get { return sfString_GetRotation(This); } - set { sfString_SetRotation(This, value); } + get { return sfText_GetRotation(This); } + set { sfText_SetRotation(This, value); } } //////////////////////////////////////////////////////////// @@ -112,8 +112,8 @@ namespace SFML //////////////////////////////////////////////////////////// public override Vector2 Scale { - get { return new Vector2(sfString_GetScaleX(This), sfString_GetScaleY(This)); } - set { sfString_SetScale(This, value.X, value.Y); } + get { return new Vector2(sfText_GetScaleX(This), sfText_GetScaleY(This)); } + set { sfText_SetScale(This, value.X, value.Y); } } //////////////////////////////////////////////////////////// @@ -124,8 +124,8 @@ namespace SFML //////////////////////////////////////////////////////////// public override Vector2 Origin { - get { return new Vector2(sfString_GetOriginX(This), sfString_GetOriginY(This)); } - set { sfString_SetOrigin(This, value.X, value.Y); } + get { return new Vector2(sfText_GetOriginX(This), sfText_GetOriginY(This)); } + set { sfText_SetOrigin(This, value.X, value.Y); } } //////////////////////////////////////////////////////////// @@ -135,8 +135,8 @@ namespace SFML //////////////////////////////////////////////////////////// public override Color Color { - get { return sfString_GetColor(This); } - set { sfString_SetColor(This, value); } + get { return sfText_GetColor(This); } + set { sfText_SetColor(This, value); } } //////////////////////////////////////////////////////////// @@ -146,8 +146,8 @@ namespace SFML //////////////////////////////////////////////////////////// public override BlendMode BlendMode { - get { return sfString_GetBlendMode(This); } - set { sfString_SetBlendMode(This, value); } + get { return sfText_GetBlendMode(This); } + set { sfText_SetBlendMode(This, value); } } //////////////////////////////////////////////////////////// @@ -161,7 +161,7 @@ namespace SFML public override Vector2 TransformToLocal(Vector2 point) { Vector2 Transformed; - sfString_TransformToLocal(This, point.X, point.Y, out Transformed.X, out Transformed.Y); + sfText_TransformToLocal(This, point.X, point.Y, out Transformed.X, out Transformed.Y); return Transformed; } @@ -177,22 +177,22 @@ namespace SFML public override Vector2 TransformToGlobal(Vector2 point) { Vector2 Transformed; - sfString_TransformToGlobal(This, point.X, point.Y, out Transformed.X, out Transformed.Y); + sfText_TransformToGlobal(This, point.X, point.Y, out Transformed.X, out Transformed.Y); return Transformed; } //////////////////////////////////////////////////////////// /// - /// Text displayed + /// String which is displayed /// //////////////////////////////////////////////////////////// - public string Text + public string DisplayedString { // TODO : use unicode functions // (convert from UTF-16 to UTF-32, and find how to marshal System.String as sfUint32*...) - get {return sfString_GetText(This);} - set {sfString_SetText(This, value);} + get {return sfText_GetString(This);} + set {sfText_SetString(This, value);} } //////////////////////////////////////////////////////////// @@ -203,7 +203,7 @@ namespace SFML public Font Font { get {return myFont;} - set {myFont = value; sfString_SetFont(This, value != null ? value.This : IntPtr.Zero);} + set {myFont = value; sfText_SetFont(This, value != null ? value.This : IntPtr.Zero);} } //////////////////////////////////////////////////////////// @@ -213,8 +213,8 @@ namespace SFML //////////////////////////////////////////////////////////// public float Size { - get {return sfString_GetSize(This);} - set {sfString_SetSize(This, value);} + get {return sfText_GetSize(This);} + set {sfText_SetSize(This, value);} } //////////////////////////////////////////////////////////// @@ -224,34 +224,34 @@ namespace SFML //////////////////////////////////////////////////////////// public Styles Style { - get {return sfString_GetStyle(This);} - set {sfString_SetStyle(This, value);} + get {return sfText_GetStyle(This);} + set {sfText_SetStyle(This, value);} } //////////////////////////////////////////////////////////// /// - /// Get the string rectangle on screen + /// Get the text rectangle on screen /// - /// String rectangle in global coordinates (doesn't include rotation) + /// Text rectangle in global coordinates (doesn't include rotation) //////////////////////////////////////////////////////////// public FloatRect GetRect() { - return sfString_GetRect(This); + return sfText_GetRect(This); } //////////////////////////////////////////////////////////// /// - /// Return the visual position of the Index-th character of the string, - /// in coordinates relative to the string + /// Return the visual position of the Index-th character of the text, + /// in coordinates relative to the text /// (note : translation, origin, rotation and scale are not applied) /// /// Index of the character - /// Position of the Index-th character (end of string if Index is out of range) + /// Position of the Index-th character (end of text if Index is out of range) //////////////////////////////////////////////////////////// public Vector2 GetCharacterPos(uint index) { Vector2 Pos; - sfString_GetCharacterPos(This, index, out Pos.X, out Pos.Y); + sfText_GetCharacterPos(This, index, out Pos.X, out Pos.Y); return Pos; } @@ -266,9 +266,9 @@ namespace SFML internal override void Render(RenderWindow target, Shader shader) { if (shader == null) - sfRenderWindow_DrawString(target.This, This); + sfRenderWindow_DrawText(target.This, This); else - sfRenderWindow_DrawStringWithShader(target.This, This, shader.This); + sfRenderWindow_DrawTextWithShader(target.This, This, shader.This); } //////////////////////////////////////////////////////////// @@ -281,9 +281,9 @@ namespace SFML internal override void Render(RenderImage target, Shader shader) { if (shader == null) - sfRenderImage_DrawString(target.This, This); + sfRenderImage_DrawText(target.This, This); else - sfRenderImage_DrawStringWithShader(target.This, This, shader.This); + sfRenderImage_DrawTextWithShader(target.This, This, shader.This); } //////////////////////////////////////////////////////////// @@ -294,113 +294,113 @@ namespace SFML //////////////////////////////////////////////////////////// protected override void Destroy(bool disposing) { - sfString_Destroy(This); + sfText_Destroy(This); } private Font myFont = Font.DefaultFont; #region Imports [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern IntPtr sfString_Create(); + static extern IntPtr sfText_Create(); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfString_Destroy(IntPtr This); + static extern void sfText_Destroy(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfString_SetPosition(IntPtr This, float X, float Y); + static extern void sfText_SetPosition(IntPtr This, float X, float Y); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern float sfString_GetX(IntPtr This); + static extern float sfText_GetX(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern float sfString_GetY(IntPtr This); + static extern float sfText_GetY(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfString_SetRotation(IntPtr This, float Rotation); + static extern void sfText_SetRotation(IntPtr This, float Rotation); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern float sfString_GetRotation(IntPtr This); + static extern float sfText_GetRotation(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfString_SetScale(IntPtr This, float X, float Y); + static extern void sfText_SetScale(IntPtr This, float X, float Y); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern float sfString_GetScaleX(IntPtr This); + static extern float sfText_GetScaleX(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern float sfString_GetScaleY(IntPtr This); + static extern float sfText_GetScaleY(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfString_SetOrigin(IntPtr This, float X, float Y); + static extern void sfText_SetOrigin(IntPtr This, float X, float Y); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern float sfString_GetOriginX(IntPtr This); + static extern float sfText_GetOriginX(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern float sfString_GetOriginY(IntPtr This); + static extern float sfText_GetOriginY(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfString_SetColor(IntPtr This, Color Color); + static extern void sfText_SetColor(IntPtr This, Color Color); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern Color sfString_GetColor(IntPtr This); + static extern Color sfText_GetColor(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfString_SetBlendMode(IntPtr This, BlendMode Mode); + static extern void sfText_SetBlendMode(IntPtr This, BlendMode Mode); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern BlendMode sfString_GetBlendMode(IntPtr This); + static extern BlendMode sfText_GetBlendMode(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern Vector2 sfString_TransformToLocal(IntPtr This, float PointX, float PointY, out float X, out float Y); + static extern Vector2 sfText_TransformToLocal(IntPtr This, float PointX, float PointY, out float X, out float Y); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern Vector2 sfString_TransformToGlobal(IntPtr This, float PointX, float PointY, out float X, out float Y); + static extern Vector2 sfText_TransformToGlobal(IntPtr This, float PointX, float PointY, out float X, out float Y); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfRenderWindow_DrawString(IntPtr This, IntPtr String); + static extern void sfRenderWindow_DrawText(IntPtr This, IntPtr String); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfRenderWindow_DrawStringWithShader(IntPtr This, IntPtr String, IntPtr Shader); + static extern void sfRenderWindow_DrawTextWithShader(IntPtr This, IntPtr String, IntPtr Shader); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfRenderImage_DrawString(IntPtr This, IntPtr String); + static extern void sfRenderImage_DrawText(IntPtr This, IntPtr String); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfRenderImage_DrawStringWithShader(IntPtr This, IntPtr String, IntPtr Shader); + static extern void sfRenderImage_DrawTextWithShader(IntPtr This, IntPtr String, IntPtr Shader); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern float sfString_GetWidth(IntPtr This); + static extern float sfText_GetWidth(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern float sfString_GetHeight(IntPtr This); + static extern float sfText_GetHeight(IntPtr This); [DllImport("csfml-graphics", CharSet = CharSet.Ansi), SuppressUnmanagedCodeSecurity] - static extern void sfString_SetText(IntPtr This, string Text); + static extern void sfText_SetString(IntPtr This, string Text); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfString_SetFont(IntPtr This, IntPtr Font); + static extern void sfText_SetFont(IntPtr This, IntPtr Font); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfString_SetSize(IntPtr This, float Size); + static extern void sfText_SetSize(IntPtr This, float Size); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfString_SetStyle(IntPtr This, Styles Style); + static extern void sfText_SetStyle(IntPtr This, Styles Style); [DllImport("csfml-graphics", CharSet = CharSet.Ansi), SuppressUnmanagedCodeSecurity] - static extern string sfString_GetText(IntPtr This); + static extern string sfText_GetString(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern float sfString_GetSize(IntPtr This); + static extern float sfText_GetSize(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern Styles sfString_GetStyle(IntPtr This); + static extern Styles sfText_GetStyle(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern FloatRect sfString_GetRect(IntPtr This); + static extern FloatRect sfText_GetRect(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfString_GetCharacterPos(IntPtr This, uint Index, out float X, out float Y); + static extern void sfText_GetCharacterPos(IntPtr This, uint Index, out float X, out float Y); #endregion } diff --git a/dotnet/src/Graphics/sfml-graphics.csproj b/dotnet/src/Graphics/sfml-graphics.csproj index 04c7e40a..1c6850be 100644 --- a/dotnet/src/Graphics/sfml-graphics.csproj +++ b/dotnet/src/Graphics/sfml-graphics.csproj @@ -60,7 +60,7 @@ - + diff --git a/include/SFML/Graphics.hpp b/include/SFML/Graphics.hpp index 14b251bf..986fa7ac 100644 --- a/include/SFML/Graphics.hpp +++ b/include/SFML/Graphics.hpp @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include diff --git a/include/SFML/Graphics/Font.hpp b/include/SFML/Graphics/Font.hpp index b9465e65..318209d4 100644 --- a/include/SFML/Graphics/Font.hpp +++ b/include/SFML/Graphics/Font.hpp @@ -30,7 +30,7 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include #include #include #include @@ -40,16 +40,15 @@ namespace sf { -class String; - namespace priv { class FontLoader; } + //////////////////////////////////////////////////////////// /// Font is the low-level class for loading and /// manipulating character fonts. This class is meant to -/// be used by sf::String +/// be used by sf::Text //////////////////////////////////////////////////////////// class SFML_API Font : public Resource { @@ -71,7 +70,7 @@ public : /// \return True if loading was successful /// //////////////////////////////////////////////////////////// - bool LoadFromFile(const std::string& filename, unsigned int charSize = 30, const Unicode::Text& charset = ourDefaultCharset); + bool LoadFromFile(const std::string& filename, unsigned int charSize = 30, String charset = ourDefaultCharset); //////////////////////////////////////////////////////////// /// Load the font from a file in memory @@ -84,7 +83,7 @@ public : /// \return True if loading was successful /// //////////////////////////////////////////////////////////// - bool LoadFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize = 30, const Unicode::Text& charset = ourDefaultCharset); + bool LoadFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize = 30, String charset = ourDefaultCharset); //////////////////////////////////////////////////////////// /// Get the base size of characters in the font; diff --git a/include/SFML/Graphics/String.hpp b/include/SFML/Graphics/Text.hpp similarity index 88% rename from include/SFML/Graphics/String.hpp rename to include/SFML/Graphics/Text.hpp index 67625f2b..8a865f94 100644 --- a/include/SFML/Graphics/String.hpp +++ b/include/SFML/Graphics/Text.hpp @@ -22,14 +22,14 @@ // //////////////////////////////////////////////////////////// -#ifndef SFML_STRING_HPP -#define SFML_STRING_HPP +#ifndef SFML_TEXT_HPP +#define SFML_TEXT_HPP //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// #include -#include +#include #include #include #include @@ -39,9 +39,9 @@ namespace sf { //////////////////////////////////////////////////////////// -/// String defines a graphical 2D text, that can be drawn on screen +/// Text defines a graphical 2D text, that can be drawn on screen //////////////////////////////////////////////////////////// -class SFML_API String : public Drawable +class SFML_API Text : public Drawable { public : @@ -60,25 +60,25 @@ public : /// Default constructor /// //////////////////////////////////////////////////////////// - String(); + Text(); //////////////////////////////////////////////////////////// /// Construct the string from any kind of text /// - /// \param text : Text assigned to the string - /// \param font : Font used to draw the string - /// \param size : Characters size + /// \param string : Text assigned to the string + /// \param font : Font used to draw the string + /// \param size : Characters size /// //////////////////////////////////////////////////////////// - explicit String(const Unicode::Text& text, const Font& font = Font::GetDefaultFont(), float size = 30.f); + explicit Text(const String& string, const Font& font = Font::GetDefaultFont(), float size = 30.f); //////////////////////////////////////////////////////////// /// Set the text (from any kind of string) /// - /// \param text : New text + /// \param string : New text /// //////////////////////////////////////////////////////////// - void SetText(const Unicode::Text& text); + void SetString(const String& string); //////////////////////////////////////////////////////////// /// Set the font of the string @@ -112,7 +112,7 @@ public : /// \return String's text /// //////////////////////////////////////////////////////////// - const Unicode::Text& GetText() const; + const String& GetString() const; //////////////////////////////////////////////////////////// /// Get the font used by the string @@ -177,7 +177,7 @@ private : //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - Unicode::Text myText; ///< Text to display + String myString; ///< String to display ResourcePtr myFont; ///< Font used to display the string float mySize; ///< Size of the characters unsigned long myStyle; ///< Text style (see Style enum) @@ -188,4 +188,4 @@ private : } // namespace sf -#endif // SFML_STRING_HPP +#endif // SFML_TEXT_HPP diff --git a/include/SFML/System.hpp b/include/SFML/System.hpp index 4ca40f10..59837354 100644 --- a/include/SFML/System.hpp +++ b/include/SFML/System.hpp @@ -35,10 +35,11 @@ #include #include #include +#include #include #include #include -#include +#include #include #include diff --git a/include/SFML/System/String.hpp b/include/SFML/System/String.hpp new file mode 100644 index 00000000..b9192c5b --- /dev/null +++ b/include/SFML/System/String.hpp @@ -0,0 +1,530 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_STRING_HPP +#define SFML_STRING_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// \brief Utility string class that automatically handles +/// conversions between types and encodings +/// +//////////////////////////////////////////////////////////// +class SFML_API String +{ +public : + + //////////////////////////////////////////////////////////// + // Types + //////////////////////////////////////////////////////////// + typedef std::basic_string::iterator Iterator; ///< Iterator type + typedef std::basic_string::const_iterator ConstIterator; ///< Constant iterator type + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// This constructor creates an empty string. + /// + //////////////////////////////////////////////////////////// + String(); + + //////////////////////////////////////////////////////////// + /// \brief Construct from a null-terminated C-style ANSI string + /// + /// The source string is converted to UTF-32 according + /// to the current locale. See the other constructor for + /// explicitely passing the locale to use. + /// + /// \param ansiString ANSI string to convert + /// + //////////////////////////////////////////////////////////// + String(const char* ansiString); + + //////////////////////////////////////////////////////////// + /// \brief Construct from an ANSI string + /// + /// The source string is converted to UTF-32 according + /// to the current global locale. See the other constructor for + /// explicitely passing the locale to use. + /// + /// \param ansiString ANSI string to convert + /// + //////////////////////////////////////////////////////////// + String(const std::string& ansiString); + + //////////////////////////////////////////////////////////// + /// \brief Construct from a null-terminated C-style ANSI string and a locale + /// + /// The source string is converted to UTF-32 according + /// to the given locale. If you want to use the current global + /// locale, rather use the other constructor. + /// + /// \param ansiString ANSI string to convert + /// \param locale Locale to use for conversion + /// + //////////////////////////////////////////////////////////// + String(const char* ansiString, const std::locale& locale); + + //////////////////////////////////////////////////////////// + /// \brief Construct from an ANSI string and a locale + /// + /// The source string is converted to UTF-32 according + /// to the given locale. If you want to use the current global + /// locale, rather use the other constructor. + /// + /// \param ansiString ANSI string to convert + /// \param locale Locale to use for conversion + /// + //////////////////////////////////////////////////////////// + String(const std::string& ansiString, const std::locale& locale); + + //////////////////////////////////////////////////////////// + /// \brief Construct from null-terminated C-style wide string + /// + /// \param wideString Wide string to convert + /// + //////////////////////////////////////////////////////////// + String(const wchar_t* wideString); + + //////////////////////////////////////////////////////////// + /// \brief Construct from a wide string + /// + /// \param wideString Wide string to convert + /// + //////////////////////////////////////////////////////////// + String(const std::wstring& wideString); + + //////////////////////////////////////////////////////////// + /// \brief Construct from a null-terminated C-style UTF-32 string + /// + /// \param utf32String UTF-32 string to assign + /// + //////////////////////////////////////////////////////////// + String(const Uint32* utf32String); + + //////////////////////////////////////////////////////////// + /// \brief Construct from an UTF-32 string + /// + /// \param utf32String UTF-32 string to assign + /// + //////////////////////////////////////////////////////////// + String(const std::basic_string& utf32String); + + //////////////////////////////////////////////////////////// + /// \brief Copy constructor + /// + /// \param other Instance to copy + /// + //////////////////////////////////////////////////////////// + String(const String& copy); + + //////////////////////////////////////////////////////////// + /// \brief Implicit cast operator to std::string (ANSI string) + /// + /// The current global locale is used for conversion. If you + /// want to explicitely specify a locale, see ToAnsiString. + /// Characters that do not fit in the target encoding are + /// discarded from the returned string. + /// This operator is defined for convenience, and is equivalent + /// to calling ToAnsiString(). + /// + /// \return Converted ANSI string + /// + //////////////////////////////////////////////////////////// + operator std::string() const; + + //////////////////////////////////////////////////////////// + /// \brief Implicit cast operator to std::wstring (wide string) + /// + /// Characters that do not fit in the target encoding are + /// discarded from the returned string. + /// This operator is defined for convenience, and is equivalent + /// to calling ToWideString(). + /// + /// \return Converted wide string + /// + //////////////////////////////////////////////////////////// + operator std::wstring() const; + + //////////////////////////////////////////////////////////// + /// \brief Convert the unicode string to an ANSI string + /// + /// The current global locale is used for conversion. If you + /// want to explicitely specify a locale, see the other overload + /// of ToAnsiString. + /// Characters that do not fit in the target encoding are + /// discarded from the returned string. + /// + /// \return Converted ANSI string + /// + //////////////////////////////////////////////////////////// + std::string ToAnsiString() const; + + //////////////////////////////////////////////////////////// + /// \brief Convert the unicode string to an ANSI string + /// + /// The UTF-32 string is converted to an ANSI string in + /// the encoding defined by \a locale. If you want to use + /// the current global locale, see the other overload + /// of ToAnsiString. + /// Characters that do not fit in the target encoding are + /// discarded from the returned string. + /// + /// \param locale Locale to use for conversion + /// + /// \return Converted ANSI string + /// + //////////////////////////////////////////////////////////// + std::string ToAnsiString(const std::locale& locale) const; + + //////////////////////////////////////////////////////////// + /// \brief Convert the unicode string to a wide string + /// + /// Characters that do not fit in the target encoding are + /// discarded from the returned string. + /// + /// \return Converted wide string + /// + //////////////////////////////////////////////////////////// + std::wstring ToWideString() const; + + //////////////////////////////////////////////////////////// + /// \brief Overload of assignment operator + /// + /// \param right Instance to assign + /// + /// \return Reference to self + /// + //////////////////////////////////////////////////////////// + String& operator =(const String& right); + + //////////////////////////////////////////////////////////// + /// \brief Overload of += operator to append an ANSI character + /// + /// \param right Character to append + /// + /// \return Reference to self + /// + //////////////////////////////////////////////////////////// + String& operator +=(char right); + + //////////////////////////////////////////////////////////// + /// \brief Overload of += operator to append a wide character + /// + /// \param right Character to append + /// + /// \return Reference to self + /// + //////////////////////////////////////////////////////////// + String& operator +=(wchar_t right); + + //////////////////////////////////////////////////////////// + /// \brief Overload of += operator to append an UTF-32 character + /// + /// \param right Character to append + /// + /// \return Reference to self + /// + //////////////////////////////////////////////////////////// + String& operator +=(Uint32 right); + + //////////////////////////////////////////////////////////// + /// \brief Overload of += operator to append an UTF-32 string + /// + /// \param right String to append + /// + /// \return Reference to self + /// + //////////////////////////////////////////////////////////// + String& operator +=(const String& right); + + //////////////////////////////////////////////////////////// + /// \brief Overload of [] operator to access a character by its position + /// + /// This function provides read-only access to characters. + /// Note: this function doesn't throw if \a index is out of range. + /// + /// \param index Index of the character to get + /// + /// \return Character at position \a index + /// + //////////////////////////////////////////////////////////// + Uint32 operator [](std::size_t index) const; + + //////////////////////////////////////////////////////////// + /// \brief Overload of [] operator to access a character by its position + /// + /// This function provides read and write access to characters. + /// Note: this function doesn't throw if \a index is out of range. + /// + /// \param index Index of the character to get + /// + /// \return Reference to the character at position \a index + /// + //////////////////////////////////////////////////////////// + Uint32& operator [](std::size_t index); + + //////////////////////////////////////////////////////////// + /// \brief Clear the string + /// + /// This function removes all the characters from the string. + /// + /// \see IsEmpty, Erase + /// + //////////////////////////////////////////////////////////// + void Clear(); + + //////////////////////////////////////////////////////////// + /// \brief Get the size of the string + /// + /// \return Number of characters in the string + /// + /// \see IsEmpty + /// + //////////////////////////////////////////////////////////// + std::size_t GetSize() const; + + //////////////////////////////////////////////////////////// + /// \brief Check whether the string is empty or not + /// + /// \return True if the string is empty (i.e. contains no character) + /// + /// \see Clear, GetSize + /// + //////////////////////////////////////////////////////////// + bool IsEmpty() const; + + //////////////////////////////////////////////////////////// + /// \brief Erase one or more characters from the string + /// + /// This function removes a sequence of \a count characters + /// starting from \a position. + /// + /// \param position Position of the first character to erase + /// \param count Number of characters to erase + /// + //////////////////////////////////////////////////////////// + void Erase(std::size_t position, std::size_t count = 1); + + //////////////////////////////////////////////////////////// + /// \brief Get a pointer to the C-style array of characters + /// + /// This functions provides a read-only access to a + /// null-terminated C-style representation of the string. + /// The returned pointer is temporary and is meant only for + /// immediate use, thus it is not recommended to store it. + /// + /// \return Read-only pointer to the array of characters + /// + //////////////////////////////////////////////////////////// + const Uint32* GetData() const; + + //////////////////////////////////////////////////////////// + /// \brief Return an iterator to the beginning of the string + /// + /// \return Read-write iterator to the beginning of the string characters + /// + /// \see End + /// + //////////////////////////////////////////////////////////// + Iterator Begin(); + + //////////////////////////////////////////////////////////// + /// \brief Return an iterator to the beginning of the string + /// + /// \return Read-only iterator to the beginning of the string characters + /// + /// \see End + /// + //////////////////////////////////////////////////////////// + ConstIterator Begin() const; + + //////////////////////////////////////////////////////////// + /// \brief Return an iterator to the beginning of the string + /// + /// The end iterator refers to 1 position past the last character; + /// thus it represents an invalid character and should never be + /// accessed. + /// + /// \return Read-write iterator to the end of the string characters + /// + /// \see Begin + /// + //////////////////////////////////////////////////////////// + Iterator End(); + + //////////////////////////////////////////////////////////// + /// \brief Return an iterator to the beginning of the string + /// + /// The end iterator refers to 1 position past the last character; + /// thus it represents an invalid character and should never be + /// accessed. + /// + /// \return Read-only iterator to the end of the string characters + /// + /// \see Begin + /// + //////////////////////////////////////////////////////////// + ConstIterator End() const; + +private : + + friend SFML_API bool operator ==(const String& left, const String& right); + friend SFML_API bool operator <(const String& left, const String& right); + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + std::basic_string myString; ///< Internal string of UTF-32 characters +}; + +//////////////////////////////////////////////////////////// +/// \brief Overload of == operator to compare two UTF-32 strings +/// +/// \param left Left operand (a string) +/// \param right Right operand (a string) +/// +/// \return True if both strings are equal +/// +//////////////////////////////////////////////////////////// +SFML_API bool operator ==(const String& left, const String& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of != operator to compare two UTF-32 strings +/// +/// \param left Left operand (a string) +/// \param right Right operand (a string) +/// +/// \return True if both strings are different +/// +//////////////////////////////////////////////////////////// +SFML_API bool operator !=(const String& left, const String& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of < operator to compare two UTF-32 strings +/// +/// \param left Left operand (a string) +/// \param right Right operand (a string) +/// +/// \return True if \a left is alphabetically lesser than \a right +/// +//////////////////////////////////////////////////////////// +SFML_API bool operator <(const String& left, const String& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of > operator to compare two UTF-32 strings +/// +/// \param left Left operand (a string) +/// \param right Right operand (a string) +/// +/// \return True if \a left is alphabetically greater than \a right +/// +//////////////////////////////////////////////////////////// +SFML_API bool operator >(const String& left, const String& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of <= operator to compare two UTF-32 strings +/// +/// \param left Left operand (a string) +/// \param right Right operand (a string) +/// +/// \return True if \a left is alphabetically lesser or equal than \a right +/// +//////////////////////////////////////////////////////////// +SFML_API bool operator <=(const String& left, const String& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of >= operator to compare two UTF-32 strings +/// +/// \param left Left operand (a string) +/// \param right Right operand (a string) +/// +/// \return True if \a left is alphabetically greater or equal than \a right +/// +//////////////////////////////////////////////////////////// +SFML_API bool operator >=(const String& left, const String& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of binary + operator to concatenate a string and an ANSI character +/// +/// \param left Source string +/// \param right Character to concatenate +/// +/// \return Concatenated string +/// +//////////////////////////////////////////////////////////// +SFML_API String operator +(const String& left, char right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of binary + operator to concatenate a string and a wide character +/// +/// \param left Source string +/// \param right Character to concatenate +/// +/// \return Concatenated string +/// +//////////////////////////////////////////////////////////// +SFML_API String operator +(const String& left, wchar_t right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of binary + operator to concatenate a string and a UTF-32 character +/// +/// \param left Source string +/// \param right Character to concatenate +/// +/// \return Concatenated string +/// +//////////////////////////////////////////////////////////// +SFML_API String operator +(const String& left, Uint32 right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of binary + operator to concatenate two strings +/// +/// \param left Left operand (a string) +/// \param right Right operand (a string) +/// +/// \return Concatenated string +/// +//////////////////////////////////////////////////////////// +SFML_API String operator +(const String& left, const String& right); + +} // namespace sf + + +#endif // SFML_STRING_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::String +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/System/Unicode.hpp b/include/SFML/System/Unicode.hpp deleted file mode 100644 index 85973e36..00000000 --- a/include/SFML/System/Unicode.hpp +++ /dev/null @@ -1,290 +0,0 @@ -//////////////////////////////////////////////////////////// -// -// SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it freely, -// subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; -// you must not claim that you wrote the original software. -// If you use this software in a product, an acknowledgment -// in the product documentation would be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, -// and must not be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// -//////////////////////////////////////////////////////////// - -#ifndef SFML_UNICODE_HPP -#define SFML_UNICODE_HPP - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include - - -namespace sf -{ -//////////////////////////////////////////////////////////// -/// Provides utility functions to convert from and to -/// any unicode and ASCII encoding -//////////////////////////////////////////////////////////// -class SFML_API Unicode -{ -public : - - //////////////////////////////////////////////////////////// - /// Define a string type for each encoding - /// Warning : in UTF8 and UTF16 strings, one element doesn't - /// necessarily maps to one character ; only an UTF32 element - /// is wide enough to hold all possible unicode values - //////////////////////////////////////////////////////////// - typedef std::basic_string UTF8String; - typedef std::basic_string UTF16String; - typedef std::basic_string UTF32String; - - //////////////////////////////////////////////////////////// - /// This class is an abstract definition of a unicode text, - /// it can be converted from and to any kind of string - /// and encoding - //////////////////////////////////////////////////////////// - class SFML_API Text - { - public : - - //////////////////////////////////////////////////////////// - /// Default constructor (empty text) - /// - //////////////////////////////////////////////////////////// - Text(); - - //////////////////////////////////////////////////////////// - /// Construct the unicode text from any type of string - /// - /// \param str : String to convert - /// - //////////////////////////////////////////////////////////// - Text(const char* str); - Text(const wchar_t* str); - Text(const Uint8* str); - Text(const Uint16* str); - Text(const Uint32* str); - Text(const std::string& str); - Text(const std::wstring& str); - Text(const Unicode::UTF8String& str); - Text(const Unicode::UTF16String& str); - Text(const Unicode::UTF32String& str); - - //////////////////////////////////////////////////////////// - /// Operator to cast the text to any type of string - /// - /// \return Converted string - /// - //////////////////////////////////////////////////////////// - operator std::string () const; - operator std::wstring () const; - operator Unicode::UTF8String () const; - operator Unicode::UTF16String () const; - operator const Unicode::UTF32String&() const; - - private : - - //////////////////////////////////////////////////////////// - // Data member - //////////////////////////////////////////////////////////// - sf::Unicode::UTF32String myUTF32String; ///< UTF-32 unicode text - }; - - //////////////////////////////////////////////////////////// - /// Generic function to convert an UTF-32 characters range - /// to an ANSI characters range, using the given locale - /// - /// \param begin : Iterator pointing to the beginning of the input sequence - /// \param end : Iterator pointing to the end of the input sequence - /// \param output : Iterator pointing to the beginning of the output sequence - /// \param replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character) - /// \param locale : Locale to use for conversion - /// - /// \return Iterator to the end of the output sequence which has been written - /// - //////////////////////////////////////////////////////////// - template - static Out UTF32ToANSI(In begin, In end, Out output, char replacement = '?', const std::locale& locale = GetDefaultLocale()); - - //////////////////////////////////////////////////////////// - /// Generic function to convert an ANSI characters range - /// to an UTF-32 characters range, using the given locale - /// - /// \param begin : Iterator pointing to the beginning of the input sequence - /// \param end : Iterator pointing to the end of the input sequence - /// \param output : Iterator pointing to the beginning of the output sequence - /// \param locale : Locale to use for conversion - /// - /// \return Iterator to the end of the output sequence which has been written - /// - //////////////////////////////////////////////////////////// - template - static Out ANSIToUTF32(In begin, In end, Out output, const std::locale& locale = GetDefaultLocale()); - - //////////////////////////////////////////////////////////// - /// Generic function to convert an UTF-8 characters range - /// to an UTF-16 characters range, using the given locale - /// - /// \param begin : Iterator pointing to the beginning of the input sequence - /// \param end : Iterator pointing to the end of the input sequence - /// \param output : Iterator pointing to the beginning of the output sequence - /// \param replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character) - /// - /// \return Iterator to the end of the output sequence which has been written - /// - //////////////////////////////////////////////////////////// - template - static Out UTF8ToUTF16(In begin, In end, Out output, Uint16 replacement = '?'); - - //////////////////////////////////////////////////////////// - /// Generic function to convert an UTF-8 characters range - /// to an UTF-32 characters range, using the given locale - /// - /// \param begin : Iterator pointing to the beginning of the input sequence - /// \param end : Iterator pointing to the end of the input sequence - /// \param output : Iterator pointing to the beginning of the output sequence - /// \param replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character) - /// - /// \return Iterator to the end of the output sequence which has been written - /// - //////////////////////////////////////////////////////////// - template - static Out UTF8ToUTF32(In begin, In end, Out output, Uint32 replacement = '?'); - - //////////////////////////////////////////////////////////// - /// Generic function to convert an UTF-16 characters range - /// to an UTF-8 characters range, using the given locale - /// - /// \param begin : Iterator pointing to the beginning of the input sequence - /// \param end : Iterator pointing to the end of the input sequence - /// \param output : Iterator pointing to the beginning of the output sequence - /// \param replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character) - /// - /// \return Iterator to the end of the output sequence which has been written - /// - //////////////////////////////////////////////////////////// - template - static Out UTF16ToUTF8(In begin, In end, Out output, Uint8 replacement = '?'); - - //////////////////////////////////////////////////////////// - /// Generic function to convert an UTF-16 characters range - /// to an UTF-32 characters range, using the given locale - /// - /// \param begin : Iterator pointing to the beginning of the input sequence - /// \param end : Iterator pointing to the end of the input sequence - /// \param output : Iterator pointing to the beginning of the output sequence - /// \param replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character) - /// - /// \return Iterator to the end of the output sequence which has been written - /// - //////////////////////////////////////////////////////////// - template - static Out UTF16ToUTF32(In begin, In end, Out output, Uint32 replacement = '?'); - - //////////////////////////////////////////////////////////// - /// Generic function to convert an UTF-32 characters range - /// to an UTF-8 characters range, using the given locale - /// - /// \param begin : Iterator pointing to the beginning of the input sequence - /// \param end : Iterator pointing to the end of the input sequence - /// \param output : Iterator pointing to the beginning of the output sequence - /// \param replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character) - /// - /// \return Iterator to the end of the output sequence which has been written - /// - //////////////////////////////////////////////////////////// - template - static Out UTF32ToUTF8(In begin, In end, Out output, Uint8 replacement = '?'); - - //////////////////////////////////////////////////////////// - /// Generic function to convert an UTF-32 characters range - /// to an UTF-16 characters range, using the given locale - /// - /// \param begin : Iterator pointing to the beginning of the input sequence - /// \param end : Iterator pointing to the end of the input sequence - /// \param output : Iterator pointing to the beginning of the output sequence - /// \param replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character) - /// - /// \return Iterator to the end of the output sequence which has been written - /// - //////////////////////////////////////////////////////////// - template - static Out UTF32ToUTF16(In begin, In end, Out output, Uint16 replacement = '?'); - - //////////////////////////////////////////////////////////// - /// Get the number of characters composing an UTF-8 string - /// - /// \param begin : Iterator pointing to the beginning of the input sequence - /// \param end : Iterator pointing to the end of the input sequence - /// - /// \return Count of the characters in the string - /// - //////////////////////////////////////////////////////////// - template - static std::size_t GetUTF8Length(In begin, In end); - - //////////////////////////////////////////////////////////// - /// Get the number of characters composing an UTF-16 string - /// - /// \param begin : Iterator pointing to the beginning of the input sequence - /// \param end : Iterator pointing to the end of the input sequence - /// - /// \return Count of the characters in the string - /// - //////////////////////////////////////////////////////////// - template - static std::size_t GetUTF16Length(In begin, In end); - - //////////////////////////////////////////////////////////// - /// Get the number of characters composing an UTF-32 string - /// - /// \param begin : Iterator pointing to the beginning of the input sequence - /// \param end : Iterator pointing to the end of the input sequence - /// - /// \return Count of the characters in the string - /// - //////////////////////////////////////////////////////////// - template - static std::size_t GetUTF32Length(In begin, In end); - -private : - - //////////////////////////////////////////////////////////// - /// Get the default system locale - /// - /// \return Reference to the default system locale - /// - //////////////////////////////////////////////////////////// - static const std::locale& GetDefaultLocale(); - - //////////////////////////////////////////////////////////// - // Static member data - //////////////////////////////////////////////////////////// - static const int UTF8TrailingBytes[256]; ///< Lookup table to find the length of an UTF-8 sequence - static const Uint32 UTF8Offsets[6]; ///< Magic values to subtract during UTF-8 conversions - static const Uint8 UTF8FirstBytes[7]; ///< First bytes for UTF-8 sequences -}; - -#include - -} // namespace sf - - -#endif // SFML_UNICODE_HPP diff --git a/include/SFML/System/Unicode.inl b/include/SFML/System/Unicode.inl deleted file mode 100644 index 779d244a..00000000 --- a/include/SFML/System/Unicode.inl +++ /dev/null @@ -1,474 +0,0 @@ -//////////////////////////////////////////////////////////// -// -// SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it freely, -// subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; -// you must not claim that you wrote the original software. -// If you use this software in a product, an acknowledgment -// in the product documentation would be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, -// and must not be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// -//////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////// -/// Generic function to convert an UTF-32 characters range -/// to an ANSI characters range, using the given locale -//////////////////////////////////////////////////////////// -template -inline Out Unicode::UTF32ToANSI(In begin, In end, Out output, char replacement, const std::locale& locale) -{ - #ifdef __MINGW32__ - - // MinGW has a almost no support for unicode stuff - // As a consequence, the MinGW version of this function can only use the default locale - // and ignores the one passed as parameter - while (begin < end) - { - char character = 0; - if (wctomb(&character, static_cast(*begin++)) >= 0) - *output++ = character; - else if (replacement) - *output++ = replacement; - } - - #else - - // Get the facet of the locale which deals with character conversion - const std::ctype& facet = std::use_facet< std::ctype >(locale); - - // Use the facet to convert each character of the input string - while (begin < end) - *output++ = facet.narrow(static_cast(*begin++), replacement); - - #endif - - return output; -} - - -//////////////////////////////////////////////////////////// -/// Generic function to convert an ANSI characters range -/// to an UTF-32 characters range, using the given locale -//////////////////////////////////////////////////////////// -template -inline Out Unicode::ANSIToUTF32(In begin, In end, Out output, const std::locale& locale) -{ - #ifdef __MINGW32__ - - // MinGW has a almost no support for unicode stuff - // As a consequence, the MinGW version of this function can only use the default locale - // and ignores the one passed as parameter - while (begin < end) - { - wchar_t character = 0; - mbtowc(&character, &*begin, 1); - begin++; - *output++ = static_cast(character); - } - - #else - - // Get the facet of the locale which deals with character conversion - const std::ctype& facet = std::use_facet< std::ctype >(locale); - - // Use the facet to convert each character of the input string - while (begin < end) - *output++ = static_cast(facet.widen(*begin++)); - - #endif - - return output; -} - - -//////////////////////////////////////////////////////////// -/// Generic function to convert an UTF-8 characters range -/// to an UTF-16 characters range, using the given locale -//////////////////////////////////////////////////////////// -template -inline Out Unicode::UTF8ToUTF16(In begin, In end, Out output, Uint16 replacement) -{ - while (begin < end) - { - Uint32 character = 0; - int trailingBytes = UTF8TrailingBytes[static_cast(*begin)]; - if (begin + trailingBytes < end) - { - // First decode the UTF-8 character - switch (trailingBytes) - { - case 5 : character += *begin++; character <<= 6; - case 4 : character += *begin++; character <<= 6; - case 3 : character += *begin++; character <<= 6; - case 2 : character += *begin++; character <<= 6; - case 1 : character += *begin++; character <<= 6; - case 0 : character += *begin++; - } - character -= UTF8Offsets[trailingBytes]; - - // Then encode it in UTF-16 - if (character < 0xFFFF) - { - // Character can be converted directly to 16 bits, just need to check it's in the valid range - if ((character >= 0xD800) && (character <= 0xDFFF)) - { - // Invalid character (this range is reserved) - if (replacement) - *output++ = replacement; - } - else - { - // Valid character directly convertible to 16 bits - *output++ = static_cast(character); - } - } - else if (character > 0x0010FFFF) - { - // Invalid character (greater than the maximum unicode value) - if (replacement) - *output++ = replacement; - } - else - { - // Character will be converted to 2 UTF-16 elements - character -= 0x0010000; - *output++ = static_cast((character >> 10) + 0xD800); - *output++ = static_cast((character & 0x3FFUL) + 0xDC00); - } - } - } - - return output; -} - - -//////////////////////////////////////////////////////////// -/// Generic function to convert an UTF-8 characters range -/// to an UTF-32 characters range, using the given locale -//////////////////////////////////////////////////////////// -template -inline Out Unicode::UTF8ToUTF32(In begin, In end, Out output, Uint32 replacement) -{ - while (begin < end) - { - Uint32 character = 0; - int trailingBytes = UTF8TrailingBytes[static_cast(*begin)]; - if (begin + trailingBytes < end) - { - // First decode the UTF-8 character - switch (trailingBytes) - { - case 5 : character += *begin++; character <<= 6; - case 4 : character += *begin++; character <<= 6; - case 3 : character += *begin++; character <<= 6; - case 2 : character += *begin++; character <<= 6; - case 1 : character += *begin++; character <<= 6; - case 0 : character += *begin++; - } - character -= UTF8Offsets[trailingBytes]; - - // Then write it if valid - if ((character < 0xD800) || (character > 0xDFFF)) - { - // Valid UTF-32 character - *output++ = character; - } - else - { - // Invalid UTF-32 character - if (replacement) - *output++ = replacement; - } - } - } - - return output; -} - - -//////////////////////////////////////////////////////////// -/// Generic function to convert an UTF-16 characters range -/// to an UTF-8 characters range, using the given locale -//////////////////////////////////////////////////////////// -template -inline Out Unicode::UTF16ToUTF8(In begin, In end, Out output, Uint8 replacement) -{ - while (begin < end) - { - Uint32 character = *begin++; - - // If it's a surrogate pair, first convert to a single UTF-32 character - if ((character >= 0xD800) && (character <= 0xDBFF)) - { - if (begin < end) - { - // The second element is valid : convert the two elements to a UTF-32 character - Uint32 d = *begin++; - if ((d >= 0xDC00) && (d <= 0xDFFF)) - character = static_cast(((character - 0xD800) << 10) + (d - 0xDC00) + 0x0010000); - } - else - { - // Invalid second element - if (replacement) - *output++ = replacement; - } - } - - // Then convert to UTF-8 - if (character > 0x0010FFFF) - { - // Invalid character (greater than the maximum unicode value) - if (replacement) - *output++ = replacement; - } - else - { - // Valid character - - // Get number of bytes to write - int bytesToWrite = 1; - if (character < 0x80) bytesToWrite = 1; - else if (character < 0x800) bytesToWrite = 2; - else if (character < 0x10000) bytesToWrite = 3; - else if (character <= 0x0010FFFF) bytesToWrite = 4; - - // Extract bytes to write - Uint8 bytes[4]; - switch (bytesToWrite) - { - case 4 : bytes[3] = static_cast((character | 0x80) & 0xBF); character >>= 6; - case 3 : bytes[2] = static_cast((character | 0x80) & 0xBF); character >>= 6; - case 2 : bytes[1] = static_cast((character | 0x80) & 0xBF); character >>= 6; - case 1 : bytes[0] = static_cast (character | UTF8FirstBytes[bytesToWrite]); - } - - // Add them to the output - const Uint8* currentByte = bytes; - switch (bytesToWrite) - { - case 4 : *output++ = *currentByte++; - case 3 : *output++ = *currentByte++; - case 2 : *output++ = *currentByte++; - case 1 : *output++ = *currentByte++; - } - } - } - - return output; -} - - -//////////////////////////////////////////////////////////// -/// Generic function to convert an UTF-16 characters range -/// to an UTF-32 characters range, using the given locale -//////////////////////////////////////////////////////////// -template -inline Out Unicode::UTF16ToUTF32(In begin, In end, Out output, Uint32 replacement) -{ - while (begin < end) - { - Uint16 character = *begin++; - if ((character >= 0xD800) && (character <= 0xDBFF)) - { - // We have a surrogate pair, ie. a character composed of two elements - if (begin < end) - { - Uint16 d = *begin++; - if ((d >= 0xDC00) && (d <= 0xDFFF)) - { - // The second element is valid : convert the two elements to a UTF-32 character - *output++ = static_cast(((character - 0xD800) << 10) + (d - 0xDC00) + 0x0010000); - } - else - { - // Invalid second element - if (replacement) - *output++ = replacement; - } - } - } - else if ((character >= 0xDC00) && (character <= 0xDFFF)) - { - // Invalid character - if (replacement) - *output++ = replacement; - } - else - { - // Valid character directly convertible to UTF-32 - *output++ = static_cast(character); - } - } - - return output; -} - - -//////////////////////////////////////////////////////////// -/// Generic function to convert an UTF-32 characters range -/// to an UTF-8 characters range, using the given locale -//////////////////////////////////////////////////////////// -template -inline Out Unicode::UTF32ToUTF8(In begin, In end, Out output, Uint8 replacement) -{ - while (begin < end) - { - Uint32 character = *begin++; - if (character > 0x0010FFFF) - { - // Invalid character (greater than the maximum unicode value) - if (replacement) - *output++ = replacement; - } - else - { - // Valid character - - // Get number of bytes to write - int bytesToWrite = 1; - if (character < 0x80) bytesToWrite = 1; - else if (character < 0x800) bytesToWrite = 2; - else if (character < 0x10000) bytesToWrite = 3; - else if (character <= 0x0010FFFF) bytesToWrite = 4; - - // Extract bytes to write - Uint8 bytes[4]; - switch (bytesToWrite) - { - case 4 : bytes[3] = static_cast((character | 0x80) & 0xBF); character >>= 6; - case 3 : bytes[2] = static_cast((character | 0x80) & 0xBF); character >>= 6; - case 2 : bytes[1] = static_cast((character | 0x80) & 0xBF); character >>= 6; - case 1 : bytes[0] = static_cast (character | UTF8FirstBytes[bytesToWrite]); - } - - // Add them to the output - const Uint8* currentByte = bytes; - switch (bytesToWrite) - { - case 4 : *output++ = *currentByte++; - case 3 : *output++ = *currentByte++; - case 2 : *output++ = *currentByte++; - case 1 : *output++ = *currentByte++; - } - } - } - - return output; -} - - -//////////////////////////////////////////////////////////// -/// Generic function to convert an UTF-32 characters range -/// to an UTF-16 characters range, using the given locale -//////////////////////////////////////////////////////////// -template -inline Out Unicode::UTF32ToUTF16(In begin, In end, Out output, Uint16 replacement) -{ - while (begin < end) - { - Uint32 character = *begin++; - if (character < 0xFFFF) - { - // Character can be converted directly to 16 bits, just need to check it's in the valid range - if ((character >= 0xD800) && (character <= 0xDFFF)) - { - // Invalid character (this range is reserved) - if (replacement) - *output++ = replacement; - } - else - { - // Valid character directly convertible to 16 bits - *output++ = static_cast(character); - } - } - else if (character > 0x0010FFFF) - { - // Invalid character (greater than the maximum unicode value) - if (replacement) - *output++ = replacement; - } - else - { - // Character will be converted to 2 UTF-16 elements - character -= 0x0010000; - *output++ = static_cast((character >> 10) + 0xD800); - *output++ = static_cast((character & 0x3FFUL) + 0xDC00); - } - } - - return output; -} - - -//////////////////////////////////////////////////////////// -/// Get the number of characters composing an UTF-8 string -//////////////////////////////////////////////////////////// -template -inline std::size_t Unicode::GetUTF8Length(In begin, In end) -{ - std::size_t length = 0; - while (begin < end) - { - int nbBytes = UTF8TrailingBytes[static_cast(*begin)]; - if (begin + nbBytes < end) - ++length; - - begin += nbBytes + 1; - } - - return length; -} - - -//////////////////////////////////////////////////////////// -/// Get the number of characters composing an UTF-16 string -//////////////////////////////////////////////////////////// -template -inline std::size_t Unicode::GetUTF16Length(In begin, In end) -{ - std::size_t length = 0; - while (begin < end) - { - if ((*begin >= 0xD800) && (*begin <= 0xDBFF)) - { - ++begin; - if ((begin < end) && ((*begin >= 0xDC00) && (*begin <= 0xDFFF))) - { - ++length; - } - } - else - { - ++length; - } - - ++begin; - } - - return length; -} - - -//////////////////////////////////////////////////////////// -/// Get the number of characters composing an UTF-32 string -//////////////////////////////////////////////////////////// -template -inline std::size_t Unicode::GetUTF32Length(In begin, In end) -{ - return end - begin; -} diff --git a/include/SFML/System/Utf.hpp b/include/SFML/System/Utf.hpp new file mode 100644 index 00000000..0a191e68 --- /dev/null +++ b/include/SFML/System/Utf.hpp @@ -0,0 +1,672 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_UTF_HPP +#define SFML_UTF_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Get the default system locale +/// +/// \return Reference to the default system locale +/// +//////////////////////////////////////////////////////////// +SFML_API const std::locale& GetDefaultLocale(); + +//////////////////////////////////////////////////////////// +/// \brief Utility class providing generic functions for UTF conversions +/// +//////////////////////////////////////////////////////////// +template +class Utf; + +//////////////////////////////////////////////////////////// +/// \brief Specialization of the Utf template for UTF-8 +/// +//////////////////////////////////////////////////////////// +template <> +class Utf<8> +{ +public : + + //////////////////////////////////////////////////////////// + /// \brief Decode a single UTF-8 character + /// + /// Decoding a character means finding its unique 32-bits + /// code (called the codepoint) in the Unicode standard. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Codepoint of the decoded UTF-8 character + /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid + /// + /// \return Iterator pointing to one past the last read element of the input sequence + /// + //////////////////////////////////////////////////////////// + template + static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0); + + //////////////////////////////////////////////////////////// + /// \brief Encode a single UTF-8 character + /// + /// Encoding a character means converting a unique 32-bits + /// code (called the codepoint) in the target encoding, UTF-8. + /// + /// \param input Codepoint to encode as UTF-8 + /// \param output Iterator pointing to the beginning of the output sequence + /// \param replacement Replacement for characters not convertible to UTF-8 (use 0 to skip them) + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out Encode(Uint32 input, Out output, Uint8 replacement = 0); + + //////////////////////////////////////////////////////////// + /// \brief Advance to the next UTF-8 character + /// + /// This function is necessary for multi-elements encodings, as + /// a single character may use more than 1 storage element. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// + /// \return Iterator pointing to one past the last read element of the input sequence + /// + //////////////////////////////////////////////////////////// + template + static In Next(In begin, In end); + + //////////////////////////////////////////////////////////// + /// \brief Count the number of characters of a UTF-8 sequence + /// + /// This function is necessary for multi-elements encodings, as + /// a single character may use more than 1 storage element, thus the + /// total size can be different from (begin - end). + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// + /// \return Iterator pointing to one past the last read element of the input sequence + /// + //////////////////////////////////////////////////////////// + template + static std::size_t Count(In begin, In end); + + //////////////////////////////////////////////////////////// + /// \brief Convert an ANSI characters range to UTF-8 + /// + /// The current global locale will be used by default, unless you + /// pass a custom one in the \a locale parameter. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// \param locale Locale to use for conversion + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = GetDefaultLocale()); + + //////////////////////////////////////////////////////////// + /// \brief Convert a wide characters range to UTF-8 + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out FromWide(In begin, In end, Out output); + + //////////////////////////////////////////////////////////// + /// \brief Convert an UTF-8 characters range to ANSI characters + /// + /// The current global locale will be used by default, unless you + /// pass a custom one in the \a locale parameter. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them) + /// \param locale Locale to use for conversion + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = GetDefaultLocale()); + + //////////////////////////////////////////////////////////// + /// \brief Convert an UTF-8 characters range to wide characters + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them) + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0); + + //////////////////////////////////////////////////////////// + /// \brief Convert a UTF-8 characters range to UTF-8 + /// + /// This functions does nothing more than a direct copy; + /// it is defined only to provide the same interface as other + /// specializations of the sf::Utf<> template, and allow + /// generic code to be written on top of it. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToUtf8(In begin, In end, Out output); + + //////////////////////////////////////////////////////////// + /// \brief Convert a UTF-8 characters range to UTF-16 + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToUtf16(In begin, In end, Out output); + + //////////////////////////////////////////////////////////// + /// \brief Convert a UTF-8 characters range to UTF-32 + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToUtf32(In begin, In end, Out output); +}; + +//////////////////////////////////////////////////////////// +/// \brief Specialization of the Utf template for UTF-16 +/// +//////////////////////////////////////////////////////////// +template <> +class Utf<16> +{ +public : + + //////////////////////////////////////////////////////////// + /// \brief Decode a single UTF-16 character + /// + /// Decoding a character means finding its unique 32-bits + /// code (called the codepoint) in the Unicode standard. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Codepoint of the decoded UTF-16 character + /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid + /// + /// \return Iterator pointing to one past the last read element of the input sequence + /// + //////////////////////////////////////////////////////////// + template + static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0); + + //////////////////////////////////////////////////////////// + /// \brief Encode a single UTF-16 character + /// + /// Encoding a character means converting a unique 32-bits + /// code (called the codepoint) in the target encoding, UTF-16. + /// + /// \param input Codepoint to encode as UTF-16 + /// \param output Iterator pointing to the beginning of the output sequence + /// \param replacement Replacement for characters not convertible to UTF-16 (use 0 to skip them) + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out Encode(Uint32 input, Out output, Uint16 replacement = 0); + + //////////////////////////////////////////////////////////// + /// \brief Advance to the next UTF-16 character + /// + /// This function is necessary for multi-elements encodings, as + /// a single character may use more than 1 storage element. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// + /// \return Iterator pointing to one past the last read element of the input sequence + /// + //////////////////////////////////////////////////////////// + template + static In Next(In begin, In end); + + //////////////////////////////////////////////////////////// + /// \brief Count the number of characters of a UTF-16 sequence + /// + /// This function is necessary for multi-elements encodings, as + /// a single character may use more than 1 storage element, thus the + /// total size can be different from (begin - end). + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// + /// \return Iterator pointing to one past the last read element of the input sequence + /// + //////////////////////////////////////////////////////////// + template + static std::size_t Count(In begin, In end); + + //////////////////////////////////////////////////////////// + /// \brief Convert an ANSI characters range to UTF-16 + /// + /// The current global locale will be used by default, unless you + /// pass a custom one in the \a locale parameter. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// \param locale Locale to use for conversion + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = GetDefaultLocale()); + + //////////////////////////////////////////////////////////// + /// \brief Convert a wide characters range to UTF-16 + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out FromWide(In begin, In end, Out output); + + //////////////////////////////////////////////////////////// + /// \brief Convert an UTF-16 characters range to ANSI characters + /// + /// The current global locale will be used by default, unless you + /// pass a custom one in the \a locale parameter. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them) + /// \param locale Locale to use for conversion + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = GetDefaultLocale()); + + //////////////////////////////////////////////////////////// + /// \brief Convert an UTF-16 characters range to wide characters + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them) + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0); + + //////////////////////////////////////////////////////////// + /// \brief Convert a UTF-16 characters range to UTF-8 + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToUtf8(In begin, In end, Out output); + + //////////////////////////////////////////////////////////// + /// \brief Convert a UTF-16 characters range to UTF-16 + /// + /// This functions does nothing more than a direct copy; + /// it is defined only to provide the same interface as other + /// specializations of the sf::Utf<> template, and allow + /// generic code to be written on top of it. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToUtf16(In begin, In end, Out output); + + //////////////////////////////////////////////////////////// + /// \brief Convert a UTF-16 characters range to UTF-32 + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToUtf32(In begin, In end, Out output); +}; + +//////////////////////////////////////////////////////////// +/// \brief Specialization of the Utf template for UTF-16 +/// +//////////////////////////////////////////////////////////// +template <> +class Utf<32> +{ +public : + + //////////////////////////////////////////////////////////// + /// \brief Decode a single UTF-32 character + /// + /// Decoding a character means finding its unique 32-bits + /// code (called the codepoint) in the Unicode standard. + /// For UTF-32, the character value is the same as the codepoint. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Codepoint of the decoded UTF-32 character + /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid + /// + /// \return Iterator pointing to one past the last read element of the input sequence + /// + //////////////////////////////////////////////////////////// + template + static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0); + + //////////////////////////////////////////////////////////// + /// \brief Encode a single UTF-32 character + /// + /// Encoding a character means converting a unique 32-bits + /// code (called the codepoint) in the target encoding, UTF-32. + /// For UTF-32, the codepoint is the same as the character value. + /// + /// \param input Codepoint to encode as UTF-32 + /// \param output Iterator pointing to the beginning of the output sequence + /// \param replacement Replacement for characters not convertible to UTF-32 (use 0 to skip them) + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out Encode(Uint32 input, Out output, Uint32 replacement = 0); + + //////////////////////////////////////////////////////////// + /// \brief Advance to the next UTF-32 character + /// + /// This function is trivial for UTF-32, which can store + /// every character in a single storage element. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// + /// \return Iterator pointing to one past the last read element of the input sequence + /// + //////////////////////////////////////////////////////////// + template + static In Next(In begin, In end); + + //////////////////////////////////////////////////////////// + /// \brief Count the number of characters of a UTF-32 sequence + /// + /// This function is trivial for UTF-32, which can store + /// every character in a single storage element. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// + /// \return Iterator pointing to one past the last read element of the input sequence + /// + //////////////////////////////////////////////////////////// + template + static std::size_t Count(In begin, In end); + + //////////////////////////////////////////////////////////// + /// \brief Convert an ANSI characters range to UTF-32 + /// + /// The current global locale will be used by default, unless you + /// pass a custom one in the \a locale parameter. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// \param locale Locale to use for conversion + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = GetDefaultLocale()); + + //////////////////////////////////////////////////////////// + /// \brief Convert a wide characters range to UTF-32 + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out FromWide(In begin, In end, Out output); + + //////////////////////////////////////////////////////////// + /// \brief Convert an UTF-32 characters range to ANSI characters + /// + /// The current global locale will be used by default, unless you + /// pass a custom one in the \a locale parameter. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them) + /// \param locale Locale to use for conversion + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = GetDefaultLocale()); + + //////////////////////////////////////////////////////////// + /// \brief Convert an UTF-32 characters range to wide characters + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them) + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0); + + //////////////////////////////////////////////////////////// + /// \brief Convert a UTF-32 characters range to UTF-8 + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToUtf8(In begin, In end, Out output); + + //////////////////////////////////////////////////////////// + /// \brief Convert a UTF-32 characters range to UTF-16 + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToUtf16(In begin, In end, Out output); + + //////////////////////////////////////////////////////////// + /// \brief Convert a UTF-32 characters range to UTF-32 + /// + /// This functions does nothing more than a direct copy; + /// it is defined only to provide the same interface as other + /// specializations of the sf::Utf<> template, and allow + /// generic code to be written on top of it. + /// + /// \param begin Iterator pointing to the beginning of the input sequence + /// \param end Iterator pointing to the end of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out ToUtf32(In begin, In end, Out output); + + //////////////////////////////////////////////////////////// + /// \brief Decode a single ANSI character to UTF-32 + /// + /// This function does not exist in other specializations + /// of sf::Utf<>, it is defined for convenience (it is used by + /// several other conversion functions). + /// + /// \param input Input ANSI character + /// \param locale Locale to use for conversion + /// + /// \return Converted character + /// + //////////////////////////////////////////////////////////// + template + static Uint32 DecodeAnsi(In input, const std::locale& locale = GetDefaultLocale()); + + //////////////////////////////////////////////////////////// + /// \brief Decode a single wide character to UTF-32 + /// + /// This function does not exist in other specializations + /// of sf::Utf<>, it is defined for convenience (it is used by + /// several other conversion functions). + /// + /// \param input Input wide character + /// + /// \return Converted character + /// + //////////////////////////////////////////////////////////// + template + static Uint32 DecodeWide(In input); + + //////////////////////////////////////////////////////////// + /// \brief Encode a single UTF-32 character to ANSI + /// + /// This function does not exist in other specializations + /// of sf::Utf<>, it is defined for convenience (it is used by + /// several other conversion functions). + /// + /// \param codepoint Iterator pointing to the beginning of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// \param replacement Replacement if the input character is not convertible to ANSI (use 0 to skip it) + /// \param locale Locale to use for conversion + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out EncodeAnsi(Uint32 codepoint, Out output, char replacement = 0, const std::locale& locale = GetDefaultLocale()); + + //////////////////////////////////////////////////////////// + /// \brief Encode a single UTF-32 character to wide + /// + /// This function does not exist in other specializations + /// of sf::Utf<>, it is defined for convenience (it is used by + /// several other conversion functions). + /// + /// \param codepoint Iterator pointing to the beginning of the input sequence + /// \param output Iterator pointing to the beginning of the output sequence + /// \param replacement Replacement if the input character is not convertible to wide (use 0 to skip it) + /// + /// \return Iterator to the end of the output sequence which has been written + /// + //////////////////////////////////////////////////////////// + template + static Out EncodeWide(Uint32 codepoint, Out output, wchar_t replacement = 0); +}; + +#include + +// Make typedefs to get rid of the template syntax +typedef Utf<8> Utf8; +typedef Utf<16> Utf16; +typedef Utf<32> Utf32; + +} // namespace sf + + +#endif // SFML_UTF_HPP diff --git a/include/SFML/System/Utf.inl b/include/SFML/System/Utf.inl new file mode 100644 index 00000000..552c6177 --- /dev/null +++ b/include/SFML/System/Utf.inl @@ -0,0 +1,665 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////// +template +In Utf<8>::Decode(In begin, In end, Uint32& output, Uint32 replacement) +{ + // Some useful precomputed data + static const int trailing[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 + }; + static const Uint32 offsets[6] = + { + 0x00000000, 0x00003080, 0x000E2080, 0x03C82080, 0xFA082080, 0x82082080 + }; + + // Decode the character + int trailingBytes = trailing[static_cast(*begin)]; + if (begin + trailingBytes < end) + { + output = 0; + switch (trailingBytes) + { + case 5 : output += *begin++; output <<= 6; + case 4 : output += *begin++; output <<= 6; + case 3 : output += *begin++; output <<= 6; + case 2 : output += *begin++; output <<= 6; + case 1 : output += *begin++; output <<= 6; + case 0 : output += *begin++; + } + output -= offsets[trailingBytes]; + } + else + { + // Incomplete character + begin = end; + output = replacement; + } + + return begin; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<8>::Encode(Uint32 input, Out output, Uint8 replacement) +{ + // Some useful precomputed data + static const Uint8 firstBytes[7] = + { + 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC + }; + + // Encode the character + if ((input > 0x0010FFFF) || ((input >= 0xD800) && (input <= 0xDBFF))) + { + // Invalid character + if (replacement) + *output++ = replacement; + } + else + { + // Valid character + + // Get the number of bytes to write + int bytesToWrite = 1; + if (input < 0x80) bytesToWrite = 1; + else if (input < 0x800) bytesToWrite = 2; + else if (input < 0x10000) bytesToWrite = 3; + else if (input <= 0x0010FFFF) bytesToWrite = 4; + + // Extract the bytes to write + Uint8 bytes[4]; + switch (bytesToWrite) + { + case 4 : bytes[3] = static_cast((input | 0x80) & 0xBF); input >>= 6; + case 3 : bytes[2] = static_cast((input | 0x80) & 0xBF); input >>= 6; + case 2 : bytes[1] = static_cast((input | 0x80) & 0xBF); input >>= 6; + case 1 : bytes[0] = static_cast (input | firstBytes[bytesToWrite]); + } + + // Add them to the output + const Uint8* currentByte = bytes; + switch (bytesToWrite) + { + case 4 : *output++ = *currentByte++; + case 3 : *output++ = *currentByte++; + case 2 : *output++ = *currentByte++; + case 1 : *output++ = *currentByte++; + } + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +In Utf<8>::Next(In begin, In end) +{ + Uint32 codepoint; + return Decode(begin, end, codepoint); +} + + +//////////////////////////////////////////////////////////// +template +std::size_t Utf<8>::Count(In begin, In end) +{ + std::size_t length = 0; + while (begin < end) + { + begin = Next(begin, end); + ++length; + } + + return length; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<8>::FromAnsi(In begin, In end, Out output, const std::locale& locale) +{ + while (begin < end) + { + Uint32 codepoint = Utf<32>::DecodeAnsi(*begin++, locale); + output = Encode(codepoint, output); + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<8>::FromWide(In begin, In end, Out output) +{ + while (begin < end) + { + Uint32 codepoint = Utf<32>::DecodeWide(*begin++); + output = Encode(codepoint, output); + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<8>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale) +{ + while (begin < end) + { + Uint32 codepoint; + begin = Decode(begin, end, codepoint); + output = Utf<32>::EncodeAnsi(codepoint, output, replacement, locale); + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<8>::ToWide(In begin, In end, Out output, wchar_t replacement) +{ + while (begin < end) + { + Uint32 codepoint; + begin = Decode(begin, end, codepoint); + output = Utf<32>::EncodeWide(codepoint, output, replacement); + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<8>::ToUtf8(In begin, In end, Out output) +{ + while (begin < end) + *output++ = *begin++; + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<8>::ToUtf16(In begin, In end, Out output) +{ + while (begin < end) + { + Uint32 codepoint; + begin = Decode(begin, end, codepoint); + output = Utf<16>::Encode(codepoint, output); + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<8>::ToUtf32(In begin, In end, Out output) +{ + while (begin < end) + { + Uint32 codepoint; + begin = Decode(begin, end, codepoint); + *output++ = codepoint; + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +In Utf<16>::Decode(In begin, In end, Uint32& output, Uint32 replacement) +{ + Uint16 first = *begin++; + + // If it's a surrogate pair, first convert to a single UTF-32 character + if ((first >= 0xD800) && (first <= 0xDBFF)) + { + if (begin < end) + { + Uint32 second = *begin++; + if ((second >= 0xDC00) && (second <= 0xDFFF)) + { + // The second element is valid: convert the two elements to a UTF-32 character + output = static_cast(((first - 0xD800) << 10) + (second - 0xDC00) + 0x0010000); + } + else + { + // Invalid character + output = replacement; + } + } + else + { + // Invalid character + begin = end; + output = replacement; + } + } + else + { + // We can make a direct copy + output = first; + } + + return begin; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<16>::Encode(Uint32 input, Out output, Uint16 replacement) +{ + if (input < 0xFFFF) + { + // The character can be copied directly, we just need to check if it's in the valid range + if ((input >= 0xD800) && (input <= 0xDFFF)) + { + // Invalid character (this range is reserved) + if (replacement) + *output++ = replacement; + } + else + { + // Valid character directly convertible to a single UTF-16 character + *output++ = static_cast(input); + } + } + else if (input > 0x0010FFFF) + { + // Invalid character (greater than the maximum unicode value) + if (replacement) + *output++ = replacement; + } + else + { + // The input character will be converted to two UTF-16 elements + input -= 0x0010000; + *output++ = static_cast((input >> 10) + 0xD800); + *output++ = static_cast((input & 0x3FFUL) + 0xDC00); + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +In Utf<16>::Next(In begin, In end) +{ + Uint32 codepoint; + return Decode(begin, end, codepoint); +} + + +//////////////////////////////////////////////////////////// +template +std::size_t Utf<16>::Count(In begin, In end) +{ + std::size_t length = 0; + while (begin < end) + { + begin = Next(begin, end); + ++length; + } + + return length; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<16>::FromAnsi(In begin, In end, Out output, const std::locale& locale) +{ + while (begin < end) + { + Uint32 codepoint = Utf<32>::DecodeAnsi(*begin++, locale); + output = Encode(codepoint, output); + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<16>::FromWide(In begin, In end, Out output) +{ + while (begin < end) + { + Uint32 codepoint = Utf<32>::DecodeWide(*begin++); + output = Encode(codepoint, output); + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<16>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale) +{ + while (begin < end) + { + Uint32 codepoint; + begin = Decode(begin, end, codepoint); + output = Utf<32>::EncodeAnsi(codepoint, output, replacement, locale); + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<16>::ToWide(In begin, In end, Out output, wchar_t replacement) +{ + while (begin < end) + { + Uint32 codepoint; + begin = Decode(begin, end, codepoint); + output = Utf<32>::EncodeWide(codepoint, output, replacement); + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<16>::ToUtf8(In begin, In end, Out output) +{ + while (begin < end) + { + Uint32 codepoint; + begin = Decode(begin, end, codepoint); + output = Utf<8>::Encode(codepoint, output); + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<16>::ToUtf16(In begin, In end, Out output) +{ + while (begin < end) + *output++ = *begin++; + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<16>::ToUtf32(In begin, In end, Out output) +{ + while (begin < end) + { + Uint32 codepoint; + begin = Decode(begin, end, codepoint); + *output++ = codepoint; + } + + return output; +} + + +//////////////////////////////////////////////////////////// +template +In Utf<32>::Decode(In begin, In end, Uint32& output, Uint32) +{ + output = *begin++; + return begin; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<32>::Encode(Uint32 input, Out output, Uint32 replacement) +{ + *output++ = input; + return output; +} + + +//////////////////////////////////////////////////////////// +template +In Utf<32>::Next(In begin, In end) +{ + return ++begin; +} + + +//////////////////////////////////////////////////////////// +template +std::size_t Utf<32>::Count(In begin, In end) +{ + return begin - end; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<32>::FromAnsi(In begin, In end, Out output, const std::locale& locale) +{ + while (begin < end) + *output++ = DecodeAnsi(*begin++, locale); + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<32>::FromWide(In begin, In end, Out output) +{ + while (begin < end) + *output++ = DecodeWide(*begin++); + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<32>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale) +{ + while (begin < end) + output = EncodeAnsi(*begin++, output, replacement, locale); + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<32>::ToWide(In begin, In end, Out output, wchar_t replacement) +{ + while (begin < end) + output = EncodeWide(*begin++, output, replacement); + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<32>::ToUtf8(In begin, In end, Out output) +{ + while (begin < end) + output = Utf<8>::Encode(*begin++, output); + + return output; +} + +//////////////////////////////////////////////////////////// +template +Out Utf<32>::ToUtf16(In begin, In end, Out output) +{ + while (begin < end) + output = Utf<16>::Encode(*begin++, output); + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<32>::ToUtf32(In begin, In end, Out output) +{ + while (begin < end) + *output++ = *begin++; + + return output; +} + + +//////////////////////////////////////////////////////////// +template +Uint32 Utf<32>::DecodeAnsi(In input, const std::locale& locale) +{ + #ifdef __MINGW32__ + + // MinGW has almost no support for unicode stuff + // As a consequence, the MinGW version of this function can only use the default locale + // and ignores the one passed as parameter + + wchar_t character = 0; + mbtowc(&character, &input, 1); + return static_cast(character); + + #else + + // Get the facet of the locale which deals with character conversion + const std::ctype& facet = std::use_facet< std::ctype >(locale); + + // Use the facet to convert each character of the input string + return static_cast(facet.widen(input)); + + #endif +} + + +//////////////////////////////////////////////////////////// +template +Uint32 Utf<32>::DecodeWide(In input) +{ + // The encoding of wide characters is not well defined and is left to the system; + // however we can safely assume that it is UCS-2 on Windows and + // UCS-4 on Unix systems. + // In both cases, a simple copy is enough (UCS-2 is a subset of UCS-4, + // and UCS-4 *is* UTF-32). + + return input; +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<32>::EncodeAnsi(Uint32 codepoint, Out output, char replacement, const std::locale& locale) +{ + #ifdef __MINGW32__ + + // MinGW has almost no support for unicode stuff + // As a consequence, the MinGW version of this function can only use the default locale + // and ignores the one passed as parameter + + char character = 0; + if (wctomb(&character, static_cast(codepoint)) >= 0) + *output++ = character; + else if (replacement) + *output++ = replacement; + + return output; + + #else + + // Get the facet of the locale which deals with character conversion + const std::ctype& facet = std::use_facet< std::ctype >(locale); + + // Use the facet to convert each character of the input string + *output++ = facet.narrow(static_cast(codepoint), replacement); + + return output; + + #endif +} + + +//////////////////////////////////////////////////////////// +template +Out Utf<32>::EncodeWide(Uint32 codepoint, Out output, wchar_t replacement) +{ + // The encoding of wide characters is not well defined and is left to the system; + // however we can safely assume that it is UCS-2 on Windows and + // UCS-4 on Unix systems. + // For UCS-2 we need to check if the source characters fits in (UCS-2 is a subset of UCS-4). + // For UCS-4 we can do a direct copy (UCS-4 *is* UTF-32). + + switch (sizeof(wchar_t)) + { + case 4: + { + *output++ = static_cast(codepoint); + break; + } + + default: + { + if ((codepoint <= 0xFFFF) && ((codepoint < 0xD800) || (codepoint > 0xDFFF))) + { + *output++ = static_cast(codepoint); + } + else if (replacement) + { + *output++ = replacement; + } + break; + } + } + + return output; +} diff --git a/samples/opengl/OpenGL.cpp b/samples/opengl/OpenGL.cpp index 35e982e2..4fdf74e8 100644 --- a/samples/opengl/OpenGL.cpp +++ b/samples/opengl/OpenGL.cpp @@ -141,10 +141,11 @@ int main() glEnd(); // Draw some text on top of our OpenGL object - sf::String text("SFML / OpenGL demo"); + sf::Text text("SFML / OpenGL demo"); text.SetPosition(250.f, 450.f); text.SetColor(sf::Color(255, 255, 255, 170)); window.Draw(text); + std::wstring s = text.GetString(); // Finally, display the rendered frame on screen window.Display(); diff --git a/samples/pong/Pong.cpp b/samples/pong/Pong.cpp index eb16e094..192a6820 100644 --- a/samples/pong/Pong.cpp +++ b/samples/pong/Pong.cpp @@ -45,7 +45,7 @@ int main() return EXIT_FAILURE; // Initialize the end text - sf::String end; + sf::Text end; end.SetFont(font); end.SetSize(60.f); end.Move(150.f, 200.f); @@ -125,12 +125,12 @@ int main() if (ball.GetPosition().x < 0.f) { isPlaying = false; - end.SetText("You lost !\n(press escape to exit)"); + end.SetString("You lost !\n(press escape to exit)"); } if (ball.GetPosition().x + ball.GetSize().x > window.GetView().GetSize().x) { isPlaying = false; - end.SetText("You won !\n(press escape to exit)"); + end.SetString("You won !\n(press escape to exit)"); } if (ball.GetPosition().y < 0.f) { diff --git a/samples/shader/Shader.cpp b/samples/shader/Shader.cpp index 02ed0fd7..8d102082 100644 --- a/samples/shader/Shader.cpp +++ b/samples/shader/Shader.cpp @@ -142,25 +142,25 @@ int main() shaders["pixelate"].SetTexture("texture", sf::Shader::CurrentTexture); // Define a string for displaying the description of the current shader - sf::String shaderStr; + sf::Text shaderStr; shaderStr.SetFont(font); shaderStr.SetSize(20); shaderStr.SetPosition(5.f, 0.f); shaderStr.SetColor(sf::Color(250, 100, 30)); - shaderStr.SetText("Background shader: \"" + backgroundShader.GetName() + "\"\n" - "Flower shader: \"" + entityShader.GetName() + "\"\n" - "Global shader: \"" + globalShader.GetName() + "\"\n"); + shaderStr.SetString("Background shader: \"" + backgroundShader.GetName() + "\"\n" + "Flower shader: \"" + entityShader.GetName() + "\"\n" + "Global shader: \"" + globalShader.GetName() + "\"\n"); // Define a string for displaying help - sf::String infoStr; + sf::Text infoStr; infoStr.SetFont(font); infoStr.SetSize(20); infoStr.SetPosition(5.f, 510.f); infoStr.SetColor(sf::Color(250, 100, 30)); - infoStr.SetText("Move your mouse to change the shaders' parameters\n" - "Press numpad 1/4 to change the background shader\n" - "Press numpad 2/5 to change the flower shader\n" - "Press numpad 3/6 to change the global shader"); + infoStr.SetString("Move your mouse to change the shaders' parameters\n" + "Press numpad 1/4 to change the background shader\n" + "Press numpad 2/5 to change the flower shader\n" + "Press numpad 3/6 to change the global shader"); // Create a clock to measure the total time elapsed sf::Clock clock; @@ -195,9 +195,9 @@ int main() } // Update the text - shaderStr.SetText("Background shader: \"" + backgroundShader.GetName() + "\"\n" - "Entity shader: \"" + entityShader.GetName() + "\"\n" - "Global shader: \"" + globalShader.GetName() + "\"\n"); + shaderStr.SetString("Background shader: \"" + backgroundShader.GetName() + "\"\n" + "Entity shader: \"" + entityShader.GetName() + "\"\n" + "Global shader: \"" + globalShader.GetName() + "\"\n"); } } @@ -249,7 +249,7 @@ void DisplayError() sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Shader"); // Define a string for displaying the error message - sf::String error("Sorry, your system doesn't support shaders"); + sf::Text error("Sorry, your system doesn't support shaders"); error.SetPosition(100.f, 250.f); error.SetColor(sf::Color(200, 100, 150)); diff --git a/src/SFML/Graphics/Font.cpp b/src/SFML/Graphics/Font.cpp index 84bcb6b0..ab6455be 100644 --- a/src/SFML/Graphics/Font.cpp +++ b/src/SFML/Graphics/Font.cpp @@ -71,26 +71,25 @@ myCharSize(0) //////////////////////////////////////////////////////////// /// Load the font from a file //////////////////////////////////////////////////////////// -bool Font::LoadFromFile(const std::string& filename, unsigned int charSize, const Unicode::Text& charset) +bool Font::LoadFromFile(const std::string& filename, unsigned int charSize, String charset) { // Clear the previous character map myGlyphs.clear(); // Always add these special characters - Unicode::UTF32String UTFCharset = charset; - if (UTFCharset.find(L' ') != Unicode::UTF32String::npos) UTFCharset += L' '; - if (UTFCharset.find(L'\n') != Unicode::UTF32String::npos) UTFCharset += L'\n'; - if (UTFCharset.find(L'\v') != Unicode::UTF32String::npos) UTFCharset += L'\v'; - if (UTFCharset.find(L'\t') != Unicode::UTF32String::npos) UTFCharset += L'\t'; + if (std::find(charset.Begin(), charset.End(), L' ') == charset.End()) charset += L' '; + if (std::find(charset.Begin(), charset.End(), L'\n') == charset.End()) charset += L'\n'; + if (std::find(charset.Begin(), charset.End(), L'\v') == charset.End()) charset += L'\v'; + if (std::find(charset.Begin(), charset.End(), L'\t') == charset.End()) charset += L'\t'; - return priv::FontLoader::GetInstance().LoadFontFromFile(filename, charSize, UTFCharset, *this); + return priv::FontLoader::GetInstance().LoadFontFromFile(filename, charSize, charset, *this); } //////////////////////////////////////////////////////////// /// Load the font from a file in memory //////////////////////////////////////////////////////////// -bool Font::LoadFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize, const Unicode::Text& charset) +bool Font::LoadFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize, String charset) { // Clear the previous character map myGlyphs.clear(); @@ -103,13 +102,12 @@ bool Font::LoadFromMemory(const char* data, std::size_t sizeInBytes, unsigned in } // Always add these special characters - Unicode::UTF32String UTFCharset = charset; - if (UTFCharset.find(L' ') != Unicode::UTF32String::npos) UTFCharset += L' '; - if (UTFCharset.find(L'\n') != Unicode::UTF32String::npos) UTFCharset += L'\n'; - if (UTFCharset.find(L'\v') != Unicode::UTF32String::npos) UTFCharset += L'\v'; - if (UTFCharset.find(L'\t') != Unicode::UTF32String::npos) UTFCharset += L'\t'; + if (std::find(charset.Begin(), charset.End(), L' ') == charset.End()) charset += L' '; + if (std::find(charset.Begin(), charset.End(), L'\n') == charset.End()) charset += L'\n'; + if (std::find(charset.Begin(), charset.End(), L'\v') == charset.End()) charset += L'\v'; + if (std::find(charset.Begin(), charset.End(), L'\t') == charset.End()) charset += L'\t'; - return priv::FontLoader::GetInstance().LoadFontFromMemory(data, sizeInBytes, charSize, UTFCharset, *this); + return priv::FontLoader::GetInstance().LoadFontFromMemory(data, sizeInBytes, charSize, charset, *this); } @@ -158,21 +156,22 @@ const Image& Font::GetImage() const //////////////////////////////////////////////////////////// const Font& Font::GetDefaultFont() { - static Font defaultFont; - static bool defaultFontLoaded = false; - static const char defaultFontData[] = - { - #include - }; + static Font font; + static bool loaded = false; // Load the default font on first call - if (!defaultFontLoaded) + if (!loaded) { - defaultFont.LoadFromMemory(defaultFontData, sizeof(defaultFontData), 30); - defaultFontLoaded = true; + static const char data[] = + { + #include + }; + + font.LoadFromMemory(data, sizeof(data), 30); + loaded = true; } - return defaultFont; + return font; } } // namespace sf diff --git a/src/SFML/Graphics/FontLoader.cpp b/src/SFML/Graphics/FontLoader.cpp index f8828e79..9a6244d2 100644 --- a/src/SFML/Graphics/FontLoader.cpp +++ b/src/SFML/Graphics/FontLoader.cpp @@ -98,7 +98,7 @@ FontLoader::~FontLoader() //////////////////////////////////////////////////////////// /// Load a font from a file //////////////////////////////////////////////////////////// -bool FontLoader::LoadFontFromFile(const std::string& filename, unsigned int charSize, const Unicode::UTF32String& charset, Font& font) +bool FontLoader::LoadFontFromFile(const std::string& filename, unsigned int charSize, const String& charset, Font& font) { // Check if Freetype is correctly initialized if (!myLibrary) @@ -131,7 +131,7 @@ bool FontLoader::LoadFontFromFile(const std::string& filename, unsigned int char //////////////////////////////////////////////////////////// /// Load the font from a file in memory //////////////////////////////////////////////////////////// -bool FontLoader::LoadFontFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize, const Unicode::UTF32String& charset, Font& font) +bool FontLoader::LoadFontFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize, const String& charset, Font& font) { // Check if Freetype is correctly initialized if (!myLibrary) @@ -164,12 +164,12 @@ bool FontLoader::LoadFontFromMemory(const char* data, std::size_t sizeInBytes, u //////////////////////////////////////////////////////////// /// Create a bitmap font from a font face and a characters set //////////////////////////////////////////////////////////// -FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const Unicode::UTF32String& charset, Font& font) +FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const String& charset, Font& font) { // Let's find how many characters to put in each row to make them fit into a squared texture GLint maxSize; GLCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize)); - int nbChars = static_cast(sqrt(static_cast(charset.length())) * 0.75); + int nbChars = static_cast(sqrt(static_cast(charset.GetSize())) * 0.75); // Clamp the character size to make sure we won't create a texture too big if (nbChars * charSize >= static_cast(maxSize)) @@ -198,7 +198,7 @@ FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const // Render all glyphs and sort them by size to optimize texture space typedef std::multimap GlyphTable; GlyphTable glyphs; - for (std::size_t i = 0; i < charset.length(); ++i) + for (std::size_t i = 0; i < charset.GetSize(); ++i) { // Load the glyph corresponding to the current character error = FT_Load_Char(face, charset[i], FT_LOAD_TARGET_NORMAL); @@ -293,7 +293,7 @@ FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const font.myTexture.LoadFromPixels(texWidth, texHeight, &glyphsBuffer[0]); // Now that the texture is created, we can precompute texture coordinates - for (std::size_t i = 0; i < charset.size(); ++i) + for (std::size_t i = 0; i < charset.GetSize(); ++i) { Uint32 curChar = charset[i]; font.myGlyphs[curChar].TexCoords = font.myTexture.GetTexCoords(coords[curChar]); @@ -491,7 +491,7 @@ FontLoader::~FontLoader() //////////////////////////////////////////////////////////// /// Load a font from a file //////////////////////////////////////////////////////////// -bool FontLoader::LoadFontFromFile(const std::string& filename, unsigned int charSize, const Unicode::UTF32String& charset, Font& font) +bool FontLoader::LoadFontFromFile(const std::string& filename, unsigned int charSize, const String& charset, Font& font) { // Get the contents of the font file std::ifstream file(filename.c_str(), std::ios_base::binary); @@ -511,12 +511,12 @@ bool FontLoader::LoadFontFromFile(const std::string& filename, unsigned int char //////////////////////////////////////////////////////////// /// Load the font from a file in memory //////////////////////////////////////////////////////////// -bool FontLoader::LoadFontFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize, const Unicode::UTF32String& charset, Font& font) +bool FontLoader::LoadFontFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize, const String& charset, Font& font) { // Let's find how many characters to put in each row to make them fit into a squared texture GLint maxSize; GLCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize)); - int nbChars = static_cast(sqrt(static_cast(charset.length())) * 0.75); + int nbChars = static_cast(sqrt(static_cast(charset.GetSize())) * 0.75); // Clamp the character size to make sure we won't create a texture too big if (nbChars * charSize >= static_cast(maxSize)) @@ -544,7 +544,7 @@ bool FontLoader::LoadFontFromMemory(const char* data, std::size_t sizeInBytes, u // Render all glyphs and sort them by size to optimize texture space typedef std::multimap GlyphTable; GlyphTable glyphs; - for (std::size_t i = 0; i < charset.length(); ++i) + for (std::size_t i = 0; i < charset.GetSize(); ++i) { // Load the glyph corresponding to the current character int index = stbtt_FindGlyphIndex(&info, static_cast(charset[i])); @@ -636,7 +636,7 @@ bool FontLoader::LoadFontFromMemory(const char* data, std::size_t sizeInBytes, u font.myTexture.LoadFromPixels(texWidth, texHeight, &glyphsBuffer[0]); // Now that the texture is created, we can precompute texture coordinates - for (std::size_t i = 0; i < charset.size(); ++i) + for (std::size_t i = 0; i < charset.GetSize(); ++i) { Uint32 curChar = charset[i]; font.myGlyphs[curChar].TexCoords = font.myTexture.GetTexCoords(coords[curChar]); @@ -652,7 +652,7 @@ bool FontLoader::LoadFontFromMemory(const char* data, std::size_t sizeInBytes, u //////////////////////////////////////////////////////////// /// Create a bitmap font from a font face and a characters set //////////////////////////////////////////////////////////// -FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const Unicode::UTF32String& charset, Font& font) +FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const String& charset, Font& font) { return 0; } diff --git a/src/SFML/Graphics/FontLoader.hpp b/src/SFML/Graphics/FontLoader.hpp index 28704b54..f3dad3bf 100644 --- a/src/SFML/Graphics/FontLoader.hpp +++ b/src/SFML/Graphics/FontLoader.hpp @@ -29,7 +29,7 @@ // Headers //////////////////////////////////////////////////////////// #include -#include +#include #include #include FT_FREETYPE_H #include @@ -67,7 +67,7 @@ public : /// \return True if loading was successful /// //////////////////////////////////////////////////////////// - bool LoadFontFromFile(const std::string& filename, unsigned int charSize, const Unicode::UTF32String& charset, Font& font); + bool LoadFontFromFile(const std::string& filename, unsigned int charSize, const String& charset, Font& font); //////////////////////////////////////////////////////////// /// Load the font from a file in memory @@ -81,7 +81,7 @@ public : /// \return True if loading was successful /// //////////////////////////////////////////////////////////// - bool LoadFontFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize, const Unicode::UTF32String& charset, Font& font); + bool LoadFontFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize, const String& charset, Font& font); private : @@ -106,7 +106,7 @@ private : /// \param font : Font object to fill up /// //////////////////////////////////////////////////////////// - FT_Error CreateBitmapFont(FT_Face face, unsigned int charSize, const Unicode::UTF32String& charset, Font& font); + FT_Error CreateBitmapFont(FT_Face face, unsigned int charSize, const String& charset, Font& font); //////////////////////////////////////////////////////////// /// Get a description from a FT error code diff --git a/src/SFML/Graphics/String.cpp b/src/SFML/Graphics/Text.cpp similarity index 87% rename from src/SFML/Graphics/String.cpp rename to src/SFML/Graphics/Text.cpp index 60b3f23d..6dd0fa17 100644 --- a/src/SFML/Graphics/String.cpp +++ b/src/SFML/Graphics/Text.cpp @@ -25,7 +25,7 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include +#include #include #include @@ -35,7 +35,7 @@ namespace sf //////////////////////////////////////////////////////////// /// Default constructor //////////////////////////////////////////////////////////// -String::String() : +Text::Text() : myFont (&Font::GetDefaultFont()), mySize (30.f), myStyle (Regular), @@ -48,30 +48,30 @@ myNeedRectUpdate(true) //////////////////////////////////////////////////////////// /// Construct the string from any kind of text //////////////////////////////////////////////////////////// -String::String(const Unicode::Text& text, const Font& font, float size) : +Text::Text(const String& string, const Font& font, float size) : myFont (&font), mySize (size), myStyle (Regular), myNeedRectUpdate(true) { - SetText(text); + SetString(string); } //////////////////////////////////////////////////////////// /// Set the text (from any kind of string) //////////////////////////////////////////////////////////// -void String::SetText(const Unicode::Text& text) +void Text::SetString(const String& string) { myNeedRectUpdate = true; - myText = text; + myString = string; } //////////////////////////////////////////////////////////// /// Set the font of the string //////////////////////////////////////////////////////////// -void String::SetFont(const Font& font) +void Text::SetFont(const Font& font) { if (myFont != &font) { @@ -84,7 +84,7 @@ void String::SetFont(const Font& font) //////////////////////////////////////////////////////////// /// Set the size of the string //////////////////////////////////////////////////////////// -void String::SetSize(float size) +void Text::SetSize(float size) { if (mySize != size) { @@ -98,7 +98,7 @@ void String::SetSize(float size) /// Set the style of the text /// The default style is Regular //////////////////////////////////////////////////////////// -void String::SetStyle(unsigned long style) +void Text::SetStyle(unsigned long style) { if (myStyle != style) { @@ -111,16 +111,16 @@ void String::SetStyle(unsigned long style) //////////////////////////////////////////////////////////// /// Get the text (the returned text can be converted implicitely to any kind of string) //////////////////////////////////////////////////////////// -const Unicode::Text& String::GetText() const +const String& Text::GetString() const { - return myText; + return myString; } //////////////////////////////////////////////////////////// /// Get the font used by the string //////////////////////////////////////////////////////////// -const Font& String::GetFont() const +const Font& Text::GetFont() const { return *myFont; } @@ -129,7 +129,7 @@ const Font& String::GetFont() const //////////////////////////////////////////////////////////// /// Get the size of the characters //////////////////////////////////////////////////////////// -float String::GetSize() const +float Text::GetSize() const { return mySize; } @@ -138,7 +138,7 @@ float String::GetSize() const //////////////////////////////////////////////////////////// /// Get the style of the text //////////////////////////////////////////////////////////// -unsigned long String::GetStyle() const +unsigned long Text::GetStyle() const { return myStyle; } @@ -149,14 +149,11 @@ unsigned long String::GetStyle() const /// in coordinates relative to the string /// (note : translation, center, rotation and scale are not applied) //////////////////////////////////////////////////////////// -sf::Vector2f String::GetCharacterPos(std::size_t index) const +sf::Vector2f Text::GetCharacterPos(std::size_t index) const { - // First get the UTF32 representation of the text - const Unicode::UTF32String& text = myText; - // Adjust the index if it's out of range - if (index > text.length()) - index = text.length(); + if (index > myString.GetSize()) + index = myString.GetSize(); // The final size is based on the text size float factor = mySize / myFont->GetCharacterSize(); @@ -167,7 +164,7 @@ sf::Vector2f String::GetCharacterPos(std::size_t index) const for (std::size_t i = 0; i < index; ++i) { // Get the current character and its corresponding glyph - Uint32 curChar = text[i]; + Uint32 curChar = myString[i]; const Glyph& curGlyph = myFont->GetGlyph(curChar); float advanceX = curGlyph.Advance * factor; @@ -191,10 +188,10 @@ sf::Vector2f String::GetCharacterPos(std::size_t index) const //////////////////////////////////////////////////////////// /// Get the string rectangle on screen //////////////////////////////////////////////////////////// -FloatRect String::GetRect() const +FloatRect Text::GetRect() const { if (myNeedRectUpdate) - const_cast(this)->RecomputeRect(); + const_cast(this)->RecomputeRect(); FloatRect rect; rect.Left = (myBaseRect.Left - GetOrigin().x) * GetScale().x + GetPosition().x; @@ -209,13 +206,10 @@ FloatRect String::GetRect() const //////////////////////////////////////////////////////////// /// /see sfDrawable::Render //////////////////////////////////////////////////////////// -void String::Render(RenderTarget&, RenderQueue& queue) const +void Text::Render(RenderTarget&, RenderQueue& queue) const { - // First get the internal UTF-32 string of the text - const Unicode::UTF32String& text = myText; - // No text, no rendering :) - if (text.empty()) + if (myString.IsEmpty()) return; // Set the scaling factor to get the actual size @@ -239,10 +233,10 @@ void String::Render(RenderTarget&, RenderQueue& queue) const // Draw one quad for each character unsigned int index = 0; queue.BeginBatch(); - for (std::size_t i = 0; i < text.size(); ++i) + for (std::size_t i = 0; i < myString.GetSize(); ++i) { // Get the current character and its corresponding glyph - Uint32 curChar = text[i]; + Uint32 curChar = myString[i]; const Glyph& curGlyph = myFont->GetGlyph(curChar); int advance = curGlyph.Advance; const IntRect& rect = curGlyph.Rectangle; @@ -294,10 +288,10 @@ void String::Render(RenderTarget&, RenderQueue& queue) const y = charSize; queue.BeginBatch(); - for (std::size_t i = 0; i < text.size(); ++i) + for (std::size_t i = 0; i < myString.GetSize(); ++i) { // Get the current character and its corresponding glyph - Uint32 curChar = text[i]; + Uint32 curChar = myString[i]; const Glyph& curGlyph = myFont->GetGlyph(curChar); int advance = curGlyph.Advance; const IntRect& rect = curGlyph.Rectangle; @@ -360,16 +354,13 @@ void String::Render(RenderTarget&, RenderQueue& queue) const //////////////////////////////////////////////////////////// /// Recompute the bounding rectangle of the text //////////////////////////////////////////////////////////// -void String::RecomputeRect() +void Text::RecomputeRect() { - // First get the internal UTF-32 string of the text - const Unicode::UTF32String& text = myText; - // Reset the "need update" state myNeedRectUpdate = false; // No text, empty box :) - if (text.empty()) + if (myString.IsEmpty()) { myBaseRect = FloatRect(0, 0, 0, 0); return; @@ -383,10 +374,10 @@ void String::RecomputeRect() float factor = mySize / myFont->GetCharacterSize(); // Go through each character - for (std::size_t i = 0; i < text.size(); ++i) + for (std::size_t i = 0; i < myString.GetSize(); ++i) { // Get the current character and its corresponding glyph - Uint32 curChar = text[i]; + Uint32 curChar = myString[i]; const Glyph& curGlyph = myFont->GetGlyph(curChar); float advance = curGlyph.Advance * factor; const IntRect& rect = curGlyph.Rectangle; diff --git a/src/SFML/System/String.cpp b/src/SFML/System/String.cpp new file mode 100644 index 00000000..6c478dc7 --- /dev/null +++ b/src/SFML/System/String.cpp @@ -0,0 +1,387 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +String::String() +{ +} + + +//////////////////////////////////////////////////////////// +String::String(const char* ansiString) +{ + if (ansiString) + { + std::size_t length = strlen(ansiString); + if (length > 0) + { + myString.reserve(length + 1); + Utf32::FromAnsi(ansiString, ansiString + length, std::back_inserter(myString)); + } + } +} + + +//////////////////////////////////////////////////////////// +String::String(const std::string& ansiString) +{ + myString.reserve(ansiString.length() + 1); + Utf32::FromAnsi(ansiString.begin(), ansiString.end(), std::back_inserter(myString)); +} + + +//////////////////////////////////////////////////////////// +String::String(const char* ansiString, const std::locale& locale) +{ + if (ansiString) + { + std::size_t length = strlen(ansiString); + if (length > 0) + { + myString.reserve(length + 1); + Utf32::FromAnsi(ansiString, ansiString + length, std::back_inserter(myString), locale); + } + } +} + + +//////////////////////////////////////////////////////////// +String::String(const std::string& ansiString, const std::locale& locale) +{ + myString.reserve(ansiString.length() + 1); + Utf32::FromAnsi(ansiString.begin(), ansiString.end(), std::back_inserter(myString), locale); +} + + +//////////////////////////////////////////////////////////// +String::String(const wchar_t* wideString) +{ + if (wideString) + { + std::size_t length = wcslen(wideString); + if (length > 0) + { + myString.reserve(length + 1); + Utf32::FromWide(wideString, wideString + length, std::back_inserter(myString)); + } + } +} + + +//////////////////////////////////////////////////////////// +String::String(const std::wstring& wideString) +{ + myString.reserve(wideString.length() + 1); + Utf32::FromWide(wideString.begin(), wideString.end(), std::back_inserter(myString)); +} + + +//////////////////////////////////////////////////////////// +String::String(const Uint32* utf32String) +{ + if (utf32String) + myString = utf32String; +} + + +//////////////////////////////////////////////////////////// +String::String(const std::basic_string& utf32String) : +myString(utf32String) +{ +} + + +//////////////////////////////////////////////////////////// +String::String(const String& copy) : +myString(copy.myString) +{ +} + + +//////////////////////////////////////////////////////////// +String::operator std::string() const +{ + return ToAnsiString(); +} + + +//////////////////////////////////////////////////////////// +String::operator std::wstring() const +{ + return ToWideString(); +} + + +//////////////////////////////////////////////////////////// +std::string String::ToAnsiString() const +{ + // Prepare the output string + std::string output; + output.reserve(myString.length() + 1); + + // Convert + Utf32::ToAnsi(myString.begin(), myString.end(), std::back_inserter(output), 0); + + return output; +} + + +//////////////////////////////////////////////////////////// +std::string String::ToAnsiString(const std::locale& locale) const +{ + // Prepare the output string + std::string output; + output.reserve(myString.length() + 1); + + // Convert + Utf32::ToAnsi(myString.begin(), myString.end(), std::back_inserter(output), 0, locale); + + return output; +} + + +//////////////////////////////////////////////////////////// +std::wstring String::ToWideString() const +{ + // Prepare the output string + std::wstring output; + output.reserve(myString.length() + 1); + + // Convert + Utf32::ToWide(myString.begin(), myString.end(), std::back_inserter(output), 0); + + return output; +} + + +//////////////////////////////////////////////////////////// +String& String::operator =(const String& right) +{ + myString = right.myString; + return *this; +} + + +//////////////////////////////////////////////////////////// +String& String::operator +=(char right) +{ + myString += Utf32::DecodeAnsi(right); + return *this; +} + + +//////////////////////////////////////////////////////////// +String& String::operator +=(wchar_t right) +{ + myString += Utf32::DecodeWide(right); + return *this; +} + + +//////////////////////////////////////////////////////////// +String& String::operator +=(Uint32 right) +{ + myString += right; + return *this; +} + + +//////////////////////////////////////////////////////////// +String& String::operator +=(const String& right) +{ + myString += right.myString; + return *this; +} + + +//////////////////////////////////////////////////////////// +Uint32 String::operator [](std::size_t index) const +{ + return myString[index]; +} + + +//////////////////////////////////////////////////////////// +Uint32& String::operator [](std::size_t index) +{ + return myString[index]; +} + + +//////////////////////////////////////////////////////////// +void String::Clear() +{ + myString.clear(); +} + + +//////////////////////////////////////////////////////////// +std::size_t String::GetSize() const +{ + return myString.size(); +} + + +//////////////////////////////////////////////////////////// +bool String::IsEmpty() const +{ + return myString.empty(); +} + + +//////////////////////////////////////////////////////////// +void String::Erase(std::size_t position, std::size_t count) +{ + myString.erase(position, count); +} + + +//////////////////////////////////////////////////////////// +const Uint32* String::GetData() const +{ + return myString.c_str(); +} + + +//////////////////////////////////////////////////////////// +String::Iterator String::Begin() +{ + return myString.begin(); +} + + +//////////////////////////////////////////////////////////// +String::ConstIterator String::Begin() const +{ + return myString.begin(); +} + + +//////////////////////////////////////////////////////////// +String::Iterator String::End() +{ + return myString.end(); +} + + +//////////////////////////////////////////////////////////// +String::ConstIterator String::End() const +{ + return myString.end(); +} + + +//////////////////////////////////////////////////////////// +bool operator ==(const String& left, const String& right) +{ + return left.myString == right.myString; +} + + +//////////////////////////////////////////////////////////// +bool operator !=(const String& left, const String& right) +{ + return !(left == right); +} + + +//////////////////////////////////////////////////////////// +bool operator <(const String& left, const String& right) +{ + return left.myString < right.myString; +} + + +//////////////////////////////////////////////////////////// +bool operator >(const String& left, const String& right) +{ + return right < left; +} + + +//////////////////////////////////////////////////////////// +bool operator <=(const String& left, const String& right) +{ + return !(right < left); +} + + +//////////////////////////////////////////////////////////// +bool operator >=(const String& left, const String& right) +{ + return !(left < right); +} + + +//////////////////////////////////////////////////////////// +String operator +(const String& left, char right) +{ + String string = left; + string += right; + + return string; +} + + +//////////////////////////////////////////////////////////// +String operator +(const String& left, wchar_t right) +{ + String string = left; + string += right; + + return string; +} + + +//////////////////////////////////////////////////////////// +String operator +(const String& left, Uint32 right) +{ + String string = left; + string += right; + + return string; +} + + +//////////////////////////////////////////////////////////// +String operator +(const String& left, const String& right) +{ + String string = left; + string += right; + + return string; +} + +} // namespace sf diff --git a/src/SFML/System/Unicode.cpp b/src/SFML/System/Unicode.cpp deleted file mode 100644 index 1e46ec04..00000000 --- a/src/SFML/System/Unicode.cpp +++ /dev/null @@ -1,300 +0,0 @@ -//////////////////////////////////////////////////////////// -// -// SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it freely, -// subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; -// you must not claim that you wrote the original software. -// If you use this software in a product, an acknowledgment -// in the product documentation would be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, -// and must not be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// -//////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include - - -//////////////////////////////////////////////////////////// -// References : -// -// http://www.unicode.org/ -// http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c -// http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.h -// http://people.w3.org/rishida/scripts/uniview/conversion -// -//////////////////////////////////////////////////////////// - -namespace -{ - //////////////////////////////////////////////////////////// - // Generic utility function to compute the number - // of characters in a null-terminated string of any type - //////////////////////////////////////////////////////////// - template - std::size_t StrLen(const T* Str) - { - std::size_t Length = 0; - while (*Str++) Length++; - return Length; - } - - //////////////////////////////////////////////////////////// - // Get the current system locale - //////////////////////////////////////////////////////////// - std::locale GetCurrentLocale() - { - try - { - return std::locale(""); - } - catch (std::runtime_error&) - { - // It seems some implementations don't know the "" locale - // (Mac OS, MinGW) - - return std::locale(); - } - } -} - -namespace sf -{ -//////////////////////////////////////////////////////////// -// Static member data -//////////////////////////////////////////////////////////// -const int Unicode::UTF8TrailingBytes[256] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 -}; -const Uint32 Unicode::UTF8Offsets[6] = -{ - 0x00000000, 0x00003080, 0x000E2080, 0x03C82080, 0xFA082080, 0x82082080 -}; -const Uint8 Unicode::UTF8FirstBytes[7] = -{ - 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC -}; - - -//////////////////////////////////////////////////////////// -/// Default constructor (empty text) -//////////////////////////////////////////////////////////// -Unicode::Text::Text() -{ - // Nothing to do -} - - -//////////////////////////////////////////////////////////// -/// Construct the unicode text from any type of string -//////////////////////////////////////////////////////////// -Unicode::Text::Text(const char* Str) -{ - if (Str) - { - std::size_t Length = StrLen(Str); - if (Length > 0) - { - myUTF32String.reserve(Length + 1); - Unicode::ANSIToUTF32(Str, Str + Length, std::back_inserter(myUTF32String)); - } - } -} -Unicode::Text::Text(const wchar_t* Str) -{ - if (Str) - { - std::size_t Length = StrLen(Str); - if (Length > 0) - { - // See comments below, in Unicode::Text::Text(const std::wstring&) - myUTF32String.reserve(Length + 1); - switch (sizeof(wchar_t)) - { - case 2 : Unicode::UTF16ToUTF32(Str, Str + Length, std::back_inserter(myUTF32String), 0); break; - case 4 : std::copy(Str, Str + Length, std::back_inserter(myUTF32String)); break; - default : break; - } - } - } -} -Unicode::Text::Text(const Uint8* Str) -{ - if (Str) - { - std::size_t Length = StrLen(Str); - if (Length > 0) - { - myUTF32String.reserve(Length + 1); - Unicode::UTF8ToUTF32(Str, Str + Length, std::back_inserter(myUTF32String), 0); - } - } -} -Unicode::Text::Text(const Uint16* Str) -{ - if (Str) - { - std::size_t Length = StrLen(Str); - if (Length > 0) - { - myUTF32String.reserve(Length+ 1); - Unicode::UTF16ToUTF32(Str, Str + Length, std::back_inserter(myUTF32String), 0); - } - } -} -Unicode::Text::Text(const Uint32* Str) -{ - if (Str) - myUTF32String = Str; -} -Unicode::Text::Text(const std::string& Str) -{ - myUTF32String.reserve(Str.length() + 1); - Unicode::ANSIToUTF32(Str.begin(), Str.end(), std::back_inserter(myUTF32String)); -} -Unicode::Text::Text(const std::wstring& Str) -{ - // This function assumes that 2-byte large wchar_t are encoded in UTF-16 (Windows), and - // 4-byte large wchar_t are encoded using UTF-32 (Unix) - // Is that always true ? (some platforms may use JIS Japanese encoding) - // The macro __STDC_ISO_10646__ should help identifying UTF-32 compliant implementations - - myUTF32String.reserve(Str.length() + 1); - - // Select the proper function according to the (supposed) wchar_t system encoding - switch (sizeof(wchar_t)) - { - // wchar_t uses UTF-16 -- need a conversion - case 2 : - { - Unicode::UTF16ToUTF32(Str.begin(), Str.end(), std::back_inserter(myUTF32String), 0); - break; - } - - // wchar_t uses UTF-32 -- direct copy - case 4 : - { - std::copy(Str.begin(), Str.end(), std::back_inserter(myUTF32String)); - break; - } - - // This should never happen - default : break; - } -} -Unicode::Text::Text(const Unicode::UTF8String& Str) -{ - myUTF32String.reserve(Str.length() + 1); - Unicode::UTF8ToUTF32(Str.begin(), Str.end(), std::back_inserter(myUTF32String), 0); -} -Unicode::Text::Text(const Unicode::UTF16String& Str) -{ - myUTF32String.reserve(Str.length() + 1); - Unicode::UTF16ToUTF32(Str.begin(), Str.end(), std::back_inserter(myUTF32String), 0); -} -Unicode::Text::Text(const Unicode::UTF32String& Str) -{ - myUTF32String = Str; -} - - -//////////////////////////////////////////////////////////// -/// Operator to cast the text to any type of string -//////////////////////////////////////////////////////////// -Unicode::Text::operator std::string() const -{ - std::string Output; - Output.reserve(myUTF32String.length() + 1); - Unicode::UTF32ToANSI(myUTF32String.begin(), myUTF32String.end(), std::back_inserter(Output), 0, Unicode::GetDefaultLocale()); - return Output; -} -Unicode::Text::operator std::wstring() const -{ - // This function assumes that 2-byte large wchar_t are encoded in UTF-16 (Windows), and - // 4-byte large wchar_t are encoded using UTF-32 (Unix) - // Is that always true ? (some platforms may use JIS Japanese encoding) - // The macro __STDC_ISO_10646__ should help identifying UTF-32 compliant implementations - - std::wstring Output; - Output.reserve(myUTF32String.length() + 1); - - // Select the proper function according to the (supposed) wchar_t system encoding - switch (sizeof(wchar_t)) - { - // wchar_t uses UTF-16 -- need a conversion - case 2 : - { - UTF32ToUTF16(myUTF32String.begin(), myUTF32String.end(), std::back_inserter(Output), 0); - break; - } - - // wchar_t uses UTF-32 -- direct copy - case 4 : - { - std::copy(myUTF32String.begin(), myUTF32String.end(), std::back_inserter(Output)); - break; - } - - // This should never happen - default : break; - } - return Output; -} -Unicode::Text::operator sf::Unicode::UTF8String() const -{ - Unicode::UTF8String Output; - Output.reserve(myUTF32String.length() * 4 + 1); - Unicode::UTF32ToUTF8(myUTF32String.begin(), myUTF32String.end(), std::back_inserter(Output), 0); - return Output; -} -Unicode::Text::operator sf::Unicode::UTF16String() const -{ - Unicode::UTF16String Output; - Output.reserve(myUTF32String.length() * 2 + 1); - Unicode::UTF32ToUTF16(myUTF32String.begin(), myUTF32String.end(), std::back_inserter(Output), 0); - return Output; -} -Unicode::Text::operator const sf::Unicode::UTF32String&() const -{ - return myUTF32String; -} - - -//////////////////////////////////////////////////////////// -/// Get the default system locale -//////////////////////////////////////////////////////////// -const std::locale& Unicode::GetDefaultLocale() -{ - // It seems getting the default locale is a very expensive operation, - // so we only do it once and then store the locale for reuse. - // Warning : this code won't be aware of any change of the default locale during runtime - - static std::locale DefaultLocale = GetCurrentLocale(); - - return DefaultLocale; -} - -} // namespace sf diff --git a/src/SFML/System/Utf.cpp b/src/SFML/System/Utf.cpp new file mode 100644 index 00000000..798c7a51 --- /dev/null +++ b/src/SFML/System/Utf.cpp @@ -0,0 +1,79 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + + +//////////////////////////////////////////////////////////// +// References : +// +// http://www.unicode.org/ +// http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c +// http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.h +// http://people.w3.org/rishida/scripts/uniview/conversion +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Private data +//////////////////////////////////////////////////////////// +namespace +{ + // Get the current global locale + std::locale GetCurrentLocale() + { + try + { + return std::locale(""); + } + catch (std::exception&) + { + // It seems that some implementations don't know the "" locale (Mac OS X, MinGW) + return std::locale(); + } + } +} + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Get the default system locale +//////////////////////////////////////////////////////////// +const std::locale& GetDefaultLocale() +{ + // It seems that getting the default locale is a very expensive operation, + // so we only do it once and then store the locale for reuse. + // Warning: this code won't be aware of any change of the default locale during runtime. + + static std::locale locale = GetCurrentLocale(); + + return locale; +} + +} // namespace sf diff --git a/src/SFML/Window/Linux/WindowImplX11.cpp b/src/SFML/Window/Linux/WindowImplX11.cpp index 2be374a7..c9f0d823 100644 --- a/src/SFML/Window/Linux/WindowImplX11.cpp +++ b/src/SFML/Window/Linux/WindowImplX11.cpp @@ -698,14 +698,13 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent) int length = Xutf8LookupString(myInputContext, &windowEvent.xkey, reinterpret_cast(keyBuffer), sizeof(keyBuffer), NULL, &status); if (length > 0) { - Uint32 unicode[2]; // just in case, but 1 character should be enough - const Uint32* end = Unicode::UTF8ToUTF32(keyBuffer, keyBuffer + length, unicode); - - if (end > unicode) + Uint32 unicode = 0; + Utf8::Decode(keyBuffer, keyBuffer + length, unicode, 0); + if (unicode != 0) { Event textEvent; textEvent.Type = Event::TextEntered; - textEvent.Text.Unicode = unicode[0]; + textEvent.Text.Unicode = unicode; SendEvent(textEvent); } }