From 3a34f81561731f3e981b4e47fc40d5de67c0c734 Mon Sep 17 00:00:00 2001 From: LaurentGom Date: Sun, 13 Dec 2009 15:49:30 +0000 Subject: [PATCH] Complete rewrite of sf::Font to make it more flexible (no more fixed charset and size) FS#125 - Fix tab character not working in sf::String git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1309 4e206d99-4929-0410-ac5d-dfc041789085 --- CSFML/build/VC2008/csfml-graphics.vcproj | 4 + CSFML/include/SFML/Graphics/Font.h | 55 +- CSFML/include/SFML/Graphics/Text.h | 4 +- CSFML/src/SFML/Graphics/Font.cpp | 75 +- CSFML/src/SFML/Graphics/FontStruct.h | 3 + CSFML/src/SFML/Graphics/ImageStruct.h | 4 +- CSFML/src/SFML/Graphics/Text.cpp | 8 +- CSFML/src/SFML/Graphics/csfml-graphics-d.def | 9 +- CSFML/src/SFML/Graphics/csfml-graphics.def | 9 +- build/codeblocks/sfml-graphics.cbp | 2 - build/vc2005/sfml-graphics.vcproj | 8 - build/vc2008/SFML.sln | 3 + build/vc2008/sfml-graphics.vcproj | 8 - dotnet/extlibs/csfml-audio.dll | Bin 49664 -> 52224 bytes dotnet/extlibs/csfml-graphics.dll | Bin 1152512 -> 1150464 bytes dotnet/extlibs/csfml-window.dll | Bin 47104 -> 47104 bytes dotnet/samples/shader/Shader.cs | 4 +- dotnet/src/Graphics/Font.cs | 167 +- dotnet/src/Graphics/Text.cs | 10 +- include/SFML/Graphics/Font.hpp | 307 ++- include/SFML/Graphics/Glyph.hpp | 4 +- include/SFML/Graphics/Image.hpp | 2 +- include/SFML/Graphics/Text.hpp | 22 +- samples/pong/Pong.cpp | 2 +- samples/shader/Shader.cpp | 8 +- src/SFML/Graphics/Font.cpp | 478 ++++- src/SFML/Graphics/FontLoader.cpp | 671 ------ src/SFML/Graphics/FontLoader.hpp | 132 -- src/SFML/Graphics/RenderWindow.cpp | 1 - src/SFML/Graphics/Text.cpp | 221 +- src/SFML/Graphics/stb_truetype/stb_truetype.h | 1807 ----------------- src/SFML/Network/SocketUDP.cpp | 4 - 32 files changed, 1016 insertions(+), 3016 deletions(-) delete mode 100644 src/SFML/Graphics/FontLoader.cpp delete mode 100644 src/SFML/Graphics/FontLoader.hpp delete mode 100644 src/SFML/Graphics/stb_truetype/stb_truetype.h diff --git a/CSFML/build/VC2008/csfml-graphics.vcproj b/CSFML/build/VC2008/csfml-graphics.vcproj index d7d16c7c..09bfd5c0 100644 --- a/CSFML/build/VC2008/csfml-graphics.vcproj +++ b/CSFML/build/VC2008/csfml-graphics.vcproj @@ -232,6 +232,10 @@ RelativePath="..\..\src\SFML\Graphics\FontStruct.h" > + + diff --git a/CSFML/include/SFML/Graphics/Font.h b/CSFML/include/SFML/Graphics/Font.h index 16f76636..685da11f 100644 --- a/CSFML/include/SFML/Graphics/Font.h +++ b/CSFML/include/SFML/Graphics/Font.h @@ -36,26 +36,22 @@ /// Create a new font from a file /// /// \param filename : Path of the font file to load -/// \param charSize : Size of characters in bitmap - the bigger, the higher quality -/// \param charset : Characters set to generate (just pass NULL to get the default charset) /// /// \return A new sfFont object, or NULL if it failed /// //////////////////////////////////////////////////////////// -CSFML_API sfFont* sfFont_CreateFromFile(const char* filename, unsigned int charSize, const sfUint32* charset); +CSFML_API sfFont* sfFont_CreateFromFile(const char* filename); //////////////////////////////////////////////////////////// /// Create a new image font a file in memory /// /// \param data : Pointer to the file data in memory /// \param sizeInBytes : Size of the data to load, in bytes -/// \param charSize : Size of characters in bitmap - the bigger, the higher quality -/// \param charset : Characters set to generate (just pass NULL to get the default charset) /// /// \return A new sfFont object, or NULL if it failed /// //////////////////////////////////////////////////////////// -CSFML_API sfFont* sfFont_CreateFromMemory(const char* data, size_t sizeInBytes, unsigned int charSize, const sfUint32* charset); +CSFML_API sfFont* sfFont_CreateFromMemory(const char* data, size_t sizeInBytes); //////////////////////////////////////////////////////////// /// Destroy an existing font @@ -66,15 +62,52 @@ CSFML_API sfFont* sfFont_CreateFromMemory(const char* data, size_t sizeInBytes, CSFML_API void sfFont_Destroy(sfFont* font); //////////////////////////////////////////////////////////// -/// Get the base size of characters in a font; -/// All glyphs dimensions are based on this value +/// Get a glyph in a font /// -/// \param font : Font object +/// \param font : Source font +/// \param codePoint : Unicode code point of the character to get +/// \param characterSize : Character size, in pixels /// -/// \return Base size of characters +/// \return The corresponding glyph /// //////////////////////////////////////////////////////////// -CSFML_API unsigned int sfFont_GetCharacterSize(const sfFont* font); +CSFML_API sfGlyph sfFont_GetGlyph(sfFont* font, sfUint32 codePoint, unsigned int characterSize); + +//////////////////////////////////////////////////////////// +/// Get the kerning value corresponding to a given pair of characters in a font +/// +/// \param font : Source font +/// \param first : Unicode code point of the first character +/// \param second : Unicode code point of the second character +/// \param characterSize : Character size, in pixels +/// +/// \return Kerning offset, in pixels +/// +//////////////////////////////////////////////////////////// +CSFML_API int sfFont_GetKerning(sfFont* font, sfUint32 first, sfUint32 second, unsigned int characterSize); + +//////////////////////////////////////////////////////////// +/// Get the line spacing value +/// +/// \param font : Source font +/// \param codePoint : Unicode code point of the character to get +/// \param characterSize : Character size, in pixels +/// +/// \return Line spacing, in pixels +/// +//////////////////////////////////////////////////////////// +CSFML_API int sfFont_GetLineSpacing(sfFont* font, unsigned int characterSize); + +//////////////////////////////////////////////////////////// +/// Get the image containing the glyphs of a given size in a font +/// +/// \param font : Source font +/// \param characterSize : Character size, in pixels +/// +/// \return Read-only pointer to the image +/// +//////////////////////////////////////////////////////////// +CSFML_API const sfImage* sfFont_GetImage(sfFont* font, unsigned int characterSize); //////////////////////////////////////////////////////////// /// Get the built-in default font (Arial) diff --git a/CSFML/include/SFML/Graphics/Text.h b/CSFML/include/SFML/Graphics/Text.h index 5c367402..a30fdb0a 100644 --- a/CSFML/include/SFML/Graphics/Text.h +++ b/CSFML/include/SFML/Graphics/Text.h @@ -336,7 +336,7 @@ CSFML_API void sfText_SetFont(sfText* text, const sfFont* font); /// \param size : New size, in pixels /// //////////////////////////////////////////////////////////// -CSFML_API void sfText_SetSize(sfText* text, float size); +CSFML_API void sfText_SetCharacterSize(sfText* text, unsigned int size); //////////////////////////////////////////////////////////// /// Set the style of a text @@ -385,7 +385,7 @@ CSFML_API const sfFont* sfText_GetFont(const sfText* text); /// \return Size of the characters /// //////////////////////////////////////////////////////////// -CSFML_API float sfText_GetSize(const sfText* text); +CSFML_API unsigned int sfText_GetCharacterSize(const sfText* text); //////////////////////////////////////////////////////////// /// Get the style of a text diff --git a/CSFML/src/SFML/Graphics/Font.cpp b/CSFML/src/SFML/Graphics/Font.cpp index 8e2b2207..e66395a1 100644 --- a/CSFML/src/SFML/Graphics/Font.cpp +++ b/CSFML/src/SFML/Graphics/Font.cpp @@ -33,17 +33,10 @@ //////////////////////////////////////////////////////////// /// Create a new font from a file //////////////////////////////////////////////////////////// -sfFont* sfFont_CreateFromFile(const char* filename, unsigned int charSize, const sfUint32* charset) +sfFont* sfFont_CreateFromFile(const char* filename) { sfFont* font = new sfFont; - - bool success = false; - if (charset) - success = font->This.LoadFromFile(filename, charSize, charset); - else - success = font->This.LoadFromFile(filename, charSize); - - if (!success) + if (!font->This.LoadFromFile(filename)) { delete font; font = NULL; @@ -56,17 +49,10 @@ sfFont* sfFont_CreateFromFile(const char* filename, unsigned int charSize, const //////////////////////////////////////////////////////////// /// Create a new font from a file in memory //////////////////////////////////////////////////////////// -sfFont* sfFont_CreateFromMemory(const char* data, size_t sizeInBytes, unsigned int charSize, const sfUint32* charset) +sfFont* sfFont_CreateFromMemory(const char* data, size_t sizeInBytes) { sfFont* font = new sfFont; - - bool success = false; - if (charset) - success = font->This.LoadFromMemory(data, sizeInBytes, charSize, charset); - else - success = font->This.LoadFromMemory(data, sizeInBytes, charSize); - - if (!success) + if (!font->This.LoadFromMemory(data, sizeInBytes)) { delete font; font = NULL; @@ -86,12 +72,57 @@ void sfFont_Destroy(sfFont* font) //////////////////////////////////////////////////////////// -/// Get the base size of characters in a font; -/// All glyphs dimensions are based on this value +/// Get a glyph in a font //////////////////////////////////////////////////////////// -unsigned int sfFont_GetCharacterSize(const sfFont* font) +sfGlyph sfFont_GetGlyph(sfFont* font, sfUint32 codePoint, unsigned int characterSize) { - CSFML_CALL_RETURN(font, GetCharacterSize(), 0); + sfGlyph glyph = {0, {0, 0, 0, 0}, {0, 0, 0, 0}}; + CSFML_CHECK_RETURN(font, glyph); + + sf::Glyph SFMLGlyph = font->This.GetGlyph(codePoint, characterSize); + + glyph.Advance = SFMLGlyph.Advance; + glyph.Rectangle.Left = SFMLGlyph.Rectangle.Left; + glyph.Rectangle.Top = SFMLGlyph.Rectangle.Top; + glyph.Rectangle.Right = SFMLGlyph.Rectangle.Right; + glyph.Rectangle.Bottom = SFMLGlyph.Rectangle.Bottom; + glyph.TexCoords.Left = SFMLGlyph.TexCoords.Left; + glyph.TexCoords.Top = SFMLGlyph.TexCoords.Top; + glyph.TexCoords.Right = SFMLGlyph.TexCoords.Right; + glyph.TexCoords.Bottom = SFMLGlyph.TexCoords.Bottom; + + return glyph; +} + + +//////////////////////////////////////////////////////////// +/// Get the kerning value corresponding to a given pair of characters in a font +//////////////////////////////////////////////////////////// +int sfFont_GetKerning(sfFont* font, sfUint32 first, sfUint32 second, unsigned int characterSize) +{ + CSFML_CALL_RETURN(font, GetKerning(first, second, characterSize), 0); +} + + +//////////////////////////////////////////////////////////// +/// Get the line spacing value +//////////////////////////////////////////////////////////// +int sfFont_GetLineSpacing(sfFont* font, unsigned int characterSize) +{ + CSFML_CALL_RETURN(font, GetLineSpacing(characterSize), 0); +} + + +//////////////////////////////////////////////////////////// +/// Get the image containing the glyphs of a given size in a font +//////////////////////////////////////////////////////////// +const sfImage* sfFont_GetImage(sfFont* font, unsigned int characterSize) +{ + CSFML_CHECK_RETURN(font, NULL); + + *font->Images[characterSize].This = font->This.GetImage(characterSize); + + return &font->Images[characterSize]; } diff --git a/CSFML/src/SFML/Graphics/FontStruct.h b/CSFML/src/SFML/Graphics/FontStruct.h index 08a31f17..019ea773 100644 --- a/CSFML/src/SFML/Graphics/FontStruct.h +++ b/CSFML/src/SFML/Graphics/FontStruct.h @@ -29,6 +29,8 @@ // Headers //////////////////////////////////////////////////////////// #include +#include +#include //////////////////////////////////////////////////////////// @@ -37,6 +39,7 @@ struct sfFont { sf::Font This; + std::map Images; }; diff --git a/CSFML/src/SFML/Graphics/ImageStruct.h b/CSFML/src/SFML/Graphics/ImageStruct.h index 1edc6530..c6289430 100644 --- a/CSFML/src/SFML/Graphics/ImageStruct.h +++ b/CSFML/src/SFML/Graphics/ImageStruct.h @@ -42,9 +42,9 @@ struct sfImage OwnInstance = true; } - sfImage(sf::Image* Image) + sfImage(sf::Image* image) { - This = Image; + This = image; OwnInstance = false; } diff --git a/CSFML/src/SFML/Graphics/Text.cpp b/CSFML/src/SFML/Graphics/Text.cpp index 7f8bb9c7..f3ffb77b 100644 --- a/CSFML/src/SFML/Graphics/Text.cpp +++ b/CSFML/src/SFML/Graphics/Text.cpp @@ -320,9 +320,9 @@ void sfText_SetFont(sfText* text, const sfFont* font) //////////////////////////////////////////////////////////// /// Set the size of a string //////////////////////////////////////////////////////////// -void sfText_SetSize(sfText* text, float size) +void sfText_SetCharacterSize(sfText* text, unsigned int size) { - CSFML_CALL(text, SetSize(size)) + CSFML_CALL(text, SetCharacterSize(size)) } @@ -373,9 +373,9 @@ const sfFont* sfText_GetFont(const sfText* text) //////////////////////////////////////////////////////////// /// Get the size of the characters of a text //////////////////////////////////////////////////////////// -float sfText_GetSize(const sfText* text) +unsigned int sfText_GetCharacterSize(const sfText* text) { - CSFML_CALL_RETURN(text, GetSize(), 0.f) + CSFML_CALL_RETURN(text, GetCharacterSize(), 0.f) } diff --git a/CSFML/src/SFML/Graphics/csfml-graphics-d.def b/CSFML/src/SFML/Graphics/csfml-graphics-d.def index f0643776..84b63511 100644 --- a/CSFML/src/SFML/Graphics/csfml-graphics-d.def +++ b/CSFML/src/SFML/Graphics/csfml-graphics-d.def @@ -127,7 +127,10 @@ EXPORTS sfFont_CreateFromFile sfFont_CreateFromMemory sfFont_Destroy - sfFont_GetCharacterSize + sfFont_GetGlyph + sfFont_GetKerning + sfFont_GetLineSpacing + sfFont_GetImage sfFont_GetDefaultFont sfText_Create sfText_Destroy @@ -158,12 +161,12 @@ EXPORTS sfText_SetString sfText_SetUnicodeString sfText_SetFont - sfText_SetSize + sfText_SetCharacterSize sfText_SetStyle sfText_GetUnicodeString sfText_GetString sfText_GetFont - sfText_GetSize + sfText_GetCharacterSize sfText_GetStyle sfText_GetCharacterPos sfText_GetRect diff --git a/CSFML/src/SFML/Graphics/csfml-graphics.def b/CSFML/src/SFML/Graphics/csfml-graphics.def index 049adbba..cb01bf35 100644 --- a/CSFML/src/SFML/Graphics/csfml-graphics.def +++ b/CSFML/src/SFML/Graphics/csfml-graphics.def @@ -127,7 +127,10 @@ EXPORTS sfFont_CreateFromFile sfFont_CreateFromMemory sfFont_Destroy - sfFont_GetCharacterSize + sfFont_GetGlyph + sfFont_GetKerning + sfFont_GetLineSpacing + sfFont_GetImage sfFont_GetDefaultFont sfText_Create sfText_Destroy @@ -158,12 +161,12 @@ EXPORTS sfText_SetString sfText_SetUnicodeString sfText_SetFont - sfText_SetSize + sfText_SetCharacterSize sfText_SetStyle sfText_GetUnicodeString sfText_GetString sfText_GetFont - sfText_GetSize + sfText_GetCharacterSize sfText_GetStyle sfText_GetCharacterPos sfText_GetRect diff --git a/build/codeblocks/sfml-graphics.cbp b/build/codeblocks/sfml-graphics.cbp index f07b6e71..a9b2275a 100644 --- a/build/codeblocks/sfml-graphics.cbp +++ b/build/codeblocks/sfml-graphics.cbp @@ -140,8 +140,6 @@ - - diff --git a/build/vc2005/sfml-graphics.vcproj b/build/vc2005/sfml-graphics.vcproj index 0e3c9095..d8d041fb 100644 --- a/build/vc2005/sfml-graphics.vcproj +++ b/build/vc2005/sfml-graphics.vcproj @@ -3434,14 +3434,6 @@ RelativePath="..\..\include\SFML\Graphics\Font.hpp" > - - - - diff --git a/build/vc2008/SFML.sln b/build/vc2008/SFML.sln index 8442ed71..fa803a74 100644 --- a/build/vc2008/SFML.sln +++ b/build/vc2008/SFML.sln @@ -14,6 +14,9 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sfml-main", "sfml-main.vcproj", "{2BD26A09-E1B6-42E2-A0D0-63987B76BB97}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sfml-network", "sfml-network.vcproj", "{823DDC98-42D5-4A38-88CF-9DC06C788AE4}" + ProjectSection(ProjectDependencies) = postProject + {C061A27D-7CA0-4179-9869-672FA04A86A8} = {C061A27D-7CA0-4179-9869-672FA04A86A8} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sfml-system", "sfml-system.vcproj", "{C061A27D-7CA0-4179-9869-672FA04A86A8}" EndProject diff --git a/build/vc2008/sfml-graphics.vcproj b/build/vc2008/sfml-graphics.vcproj index feb22c5e..1954e795 100644 --- a/build/vc2008/sfml-graphics.vcproj +++ b/build/vc2008/sfml-graphics.vcproj @@ -3433,14 +3433,6 @@ RelativePath="..\..\include\SFML\Graphics\Font.hpp" > - - - - diff --git a/dotnet/extlibs/csfml-audio.dll b/dotnet/extlibs/csfml-audio.dll index cd78f3c76d0fb210eecddea43a8cb05c9bfe82d5..2e2ffb2c0dcff2e27ab05e914d251ca3dc2bd2ff 100644 GIT binary patch delta 20725 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 EUkB)>=>Px# delta 19226 zcmeHujbBt%{{NkEfKdk-g+T;_5eGy?y)(l+KcON%gfu9E6d@|=NIsx~QksJSt29#B zA+^m4)6`0f(p6C}uo|NE_kVSIWdVGz;@YwZbQ zUT#9dI-cH~FqBVUNr>Xp{Ru<(^v^#1H~4hk%B2o!oAG_@GZ-dQ5X3y_2)zrW7@pk4 z2*(T+3}%=zWaoG#50{Vx!Q=_AhX@!UPmwYV{`d!nC{T=HmftzdjP6oei?0-QX4NO+H67b|{TBu;3rXQb!w$#wnE7Az%< z)FY#$Tj>h1plon1w=aGlP zjk|2Ho!gj0(t_h77vy+7I*-Do9(=f=Fh~R;F{D0tMED3Fn|GL&3Qt}So)W2tsa&W; z@G3*_%;iqaC%*)%ggfSw$sut<$9$3%5+hvlFu6Y@J~xW`m8p<;WR<8Z-V{(?NGt1+ zwNeVA`z|N~J9w$!C3~Z|1w2RlAzmdJ0tHMqm?_B!G51R@=?a-9+&hmb#K~+km1GX{ zk|HW3rftWSBjU6*`Hw4IA^TCsNou3lt(Bvj zsnnc^H#d-ZuIhRe^kZQbB6hqg9AS_{5fUOF8tvqGTXJd(q6klHCj-gOG!gZpGfhl2 z3lw5|=MAr7jv}Iy10@QG^~eJBJ8$H=$`sx$QDbbO!R zw7j~Zs4j2UBkLkJhmHwC%pF@vqGY15U=EolNsqV$y?kEf-KkMb)fsVj`W*72WP)G^ z`I{s~cx^Tr6uL~9Gl!IfsstCw)1k*lbU?+GB|?u%wwDO9J+cdA$*}V9VvyCh5J>~P z+?p`oHToR6I&8eKW-F0}=|(rs#Mt-%JuHIZ6tnP72ZXnG{}e=4hN%Qw$iA@nj0(OY zqROpOCan5C0afDaLKvpTT|P>mt_Uv=b7kE|p+325qIWZ-7<9Mm5V?7dNCe;Rkrfkx zG(m8VD5T>BWh6_w%~ zDo`lAWtI|lc=V7}@Nj;~Adk#Ja)wV4)@n%2@Pv^&>F_9n5j*z=yhfLEwR>bc$Xmlz zf}P}t;mLvu5h_=nRJ%}IlKE1)Nxm{Fo zS42D%UyZOpY}lql+c5}Cn7;^R(i$0y9(y@*3g(yL zBd6ef>d1IJ7vot>wv8N_C?Cs6o6%TIeoHf5QuABX?)(;)CmQr{KmtUQH%BH;ulLr) zyRKkpN#-xeb#>;|Z4e;@ZG!?r7CbOyt}TjGSDwf<=^~jBMdM?SQsY@2HBnGcnxe){ zqET}39W%8rI{Z-j$dIE*3wz@2d3?-V!RXejh-g$Yv?q;9j`GE4QQ>{AmU}Vk{GlX{ zQ3)|Lyl6|bjn{9?pb~y<-9ME)KWg%vi(46K@qXI)_Tt(^nr73*HKTy84r1;zE2c24 zmD#Q=Gn#}BR4T)bz@h{J5eVL;>_aOV9i1e+x|Pg`mWQr@nky@3VwT-CNl(^C>x4f} zA}>Y93lps5T=ckA(at+drGZ4jd9`Hoy`_4ud#f%;Mpal+PDxzqo zy|=g)n<8o_$~W#X?4~)%^D$G@7ke-di3IrVF%h19>5EyP%Cr=5ih_Et98C8M?7Pb)jmQHpBXxqtt}SJPi7ROxLoZ~UVP zWZ±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�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

LuH5b&*mH|9vq6wJxNYa5cT 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 IaJtL?0gc{|Y5)KL delta 191772 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 AW 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 diff --git a/dotnet/extlibs/csfml-window.dll b/dotnet/extlibs/csfml-window.dll index b45310ae2a769800a01315e31ef0671bf23a5a0c..556dbca00d5bca71cb3037dc50c1ab5de85fa3e4 100644 GIT binary patch delta 9605 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 delta 9530 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 diff --git a/dotnet/samples/shader/Shader.cs b/dotnet/samples/shader/Shader.cs index a8a765a2..3ded018b 100644 --- a/dotnet/samples/shader/Shader.cs +++ b/dotnet/samples/shader/Shader.cs @@ -93,7 +93,7 @@ namespace sample_shader Sprite entity = new Sprite(new Image("datas/shader/sprite.png")); // Load the text font - Font font = new Font("datas/shader/arial.ttf", 20); + Font font = new Font("datas/shader/arial.ttf"); // Load the image needed for the wave effect Image waveImage = new Image("datas/shader/wave.jpg"); @@ -135,7 +135,7 @@ namespace sample_shader Text infoText = new Text(); infoText.Font = font; infoText.Size = 20; - infoText.Position = new Vector2(5.0F, 510.0F); + infoText.Position = new Vector2(5.0F, 500.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" + diff --git a/dotnet/src/Graphics/Font.cs b/dotnet/src/Graphics/Font.cs index 273d2d6c..91ffb66c 100644 --- a/dotnet/src/Graphics/Font.cs +++ b/dotnet/src/Graphics/Font.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Security; using System.IO; @@ -7,6 +8,24 @@ namespace SFML { namespace Graphics { + //////////////////////////////////////////////////////////// + ///

+ /// Structure describing a glyph (a visual character) + /// + //////////////////////////////////////////////////////////// + [StructLayout(LayoutKind.Sequential)] + public struct Glyph + { + /// Offset to move horizontically to the next character + public int Advance; + + /// Bounding rectangle of the glyph, in coordinates relative to the baseline + public IntRect Rectangle; + + /// Texture coordinates of the glyph inside the font's image + public FloatRect TexCoords; + } + //////////////////////////////////////////////////////////// /// /// Font is the low-level class for loading and @@ -24,47 +43,8 @@ namespace SFML /// //////////////////////////////////////////////////////////// public Font(string filename) : - this(filename, 30) + base(sfFont_CreateFromFile(filename)) { - } - - //////////////////////////////////////////////////////////// - /// - /// Construct the font from a file, using custom size - /// - /// Font file to load - /// Character size - /// - //////////////////////////////////////////////////////////// - public Font(string filename, uint charSize) : - this(filename, charSize, "") - { - } - - //////////////////////////////////////////////////////////// - /// - /// Construct the font from a file, using custom size and characters set - /// - /// Font file to load - /// Character size - /// Set of characters to generate - /// - //////////////////////////////////////////////////////////// - public Font(string filename, uint charSize, string charset) : - base(IntPtr.Zero) - { - unsafe - { - IntPtr ptr; - int size; - if (Int32.TryParse(charset, out size)) - ptr = new IntPtr(&size); - else - ptr = IntPtr.Zero; - - SetThis(sfFont_CreateFromFile(filename, charSize, ptr)); - } - if (This == IntPtr.Zero) throw new LoadingFailedException("font", filename); } @@ -77,64 +57,73 @@ namespace SFML /// //////////////////////////////////////////////////////////// public Font(Stream stream) : - this(stream, 30) - { - } - - //////////////////////////////////////////////////////////// - /// - /// Construct the font from a file in a stream, using custom size - /// - /// Stream containing the file contents - /// Character size - /// - //////////////////////////////////////////////////////////// - public Font(Stream stream, uint charSize) : - this(stream, charSize, "") - { - } - - //////////////////////////////////////////////////////////// - /// - /// Construct the font from a file in a stream - /// - /// Stream containing the file contents - /// Character size - /// Set of characters to generate - /// - //////////////////////////////////////////////////////////// - public Font(Stream stream, uint charSize, string charset) : base(IntPtr.Zero) { unsafe { - IntPtr ptr; - int size; - if (Int32.TryParse(charset, out size)) - ptr = new IntPtr(&size); - else - ptr = IntPtr.Zero; - stream.Position = 0; byte[] StreamData = new byte[stream.Length]; uint Read = (uint)stream.Read(StreamData, 0, StreamData.Length); fixed (byte* dataPtr = StreamData) { - SetThis(sfFont_CreateFromMemory((char*)dataPtr, Read, charSize, ptr)); + SetThis(sfFont_CreateFromMemory((char*)dataPtr, Read)); } } + if (This == IntPtr.Zero) throw new LoadingFailedException("font"); } //////////////////////////////////////////////////////////// /// - /// Base character size + /// Get a glyph in the font /// + /// Unicode code point of the character to get + /// Character size + /// The glyph corresponding to the character //////////////////////////////////////////////////////////// - public uint CharacterSize + public Glyph GetGlyph(uint codePoint, uint characterSize) { - get { return sfFont_GetCharacterSize(This); } + return sfFont_GetGlyph(This, codePoint, characterSize); + } + + //////////////////////////////////////////////////////////// + /// + /// Get the kerning offset between two glyphs + /// + /// Unicode code point of the first character + /// Unicode code point of the second character + /// Character size + /// Kerning offset, in pixels + //////////////////////////////////////////////////////////// + public int GetKerning(uint first, uint second, uint characterSize) + { + return sfFont_GetKerning(This, first, second, characterSize); + } + + //////////////////////////////////////////////////////////// + /// + /// Get spacing between two consecutive lines + /// + /// Character size + /// Line spacing, in pixels + //////////////////////////////////////////////////////////// + public int GetLineSpacing(uint characterSize) + { + return sfFont_GetLineSpacing(This, characterSize); + } + + //////////////////////////////////////////////////////////// + /// + /// Get the image containing the glyphs of a given size + /// + /// Character size + /// Image storing the glyphs for the given size + //////////////////////////////////////////////////////////// + public Image GetImage(uint characterSize) + { + myImages[characterSize] = new Image(sfFont_GetImage(This, characterSize)); + return myImages[characterSize]; } //////////////////////////////////////////////////////////// @@ -168,6 +157,12 @@ namespace SFML sfFont_Destroy(This); + if (disposing) + { + foreach (Image image in myImages.Values) + image.Dispose(); + } + if (!disposing) Context.Global.SetActive(false); } @@ -184,20 +179,30 @@ namespace SFML { } + private Dictionary myImages = new Dictionary(); private static Font ourDefaultFont = null; #region Imports [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern IntPtr sfFont_CreateFromFile(string Filename, uint CharSize, IntPtr Charset); + static extern IntPtr sfFont_CreateFromFile(string Filename); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - unsafe static extern IntPtr sfFont_CreateFromMemory(char* Data, uint SizeInBytes, uint CharSize, IntPtr Charset); + unsafe static extern IntPtr sfFont_CreateFromMemory(char* Data, uint SizeInBytes); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] static extern void sfFont_Destroy(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern uint sfFont_GetCharacterSize(IntPtr This); + static extern Glyph sfFont_GetGlyph(IntPtr This, uint codePoint, uint characterSize); + + [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] + static extern int sfFont_GetKerning(IntPtr This, uint first, uint second, uint characterSize); + + [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] + static extern int sfFont_GetLineSpacing(IntPtr This, uint characterSize); + + [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] + static extern IntPtr sfFont_GetImage(IntPtr This, uint characterSize); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] static extern IntPtr sfFont_GetDefaultFont(); diff --git a/dotnet/src/Graphics/Text.cs b/dotnet/src/Graphics/Text.cs index e686d394..42ed4b23 100644 --- a/dotnet/src/Graphics/Text.cs +++ b/dotnet/src/Graphics/Text.cs @@ -211,10 +211,10 @@ namespace SFML /// Base size of characters /// //////////////////////////////////////////////////////////// - public float Size + public uint Size { - get {return sfText_GetSize(This);} - set {sfText_SetSize(This, value);} + get {return sfText_GetCharacterSize(This);} + set {sfText_SetCharacterSize(This, value);} } //////////////////////////////////////////////////////////// @@ -376,7 +376,7 @@ namespace SFML static extern void sfText_SetFont(IntPtr This, IntPtr Font); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern void sfText_SetSize(IntPtr This, float Size); + static extern void sfText_SetCharacterSize(IntPtr This, uint Size); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] static extern void sfText_SetStyle(IntPtr This, Styles Style); @@ -385,7 +385,7 @@ namespace SFML static extern string sfText_GetString(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] - static extern float sfText_GetSize(IntPtr This); + static extern uint sfText_GetCharacterSize(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] static extern Styles sfText_GetStyle(IntPtr This); diff --git a/include/SFML/Graphics/Font.hpp b/include/SFML/Graphics/Font.hpp index 318209d4..de3798b8 100644 --- a/include/SFML/Graphics/Font.hpp +++ b/include/SFML/Graphics/Font.hpp @@ -36,109 +36,328 @@ #include #include #include +#include namespace sf { -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::Text +/// \brief Class for loading and manipulating character fonts +/// //////////////////////////////////////////////////////////// class SFML_API Font : public Resource { public : //////////////////////////////////////////////////////////// - /// Default constructor + /// \brief Default constructor + /// + /// This constructor defines an empty font /// //////////////////////////////////////////////////////////// Font(); //////////////////////////////////////////////////////////// - /// Load the font from a file + /// \brief Copy constructor /// - /// \param filename : Font file to load - /// \param charSize : Size of characters in bitmap - the bigger, the higher quality - /// \param charset : Characters set to generate (by default, contains the ISO-8859-1 printable characters) - /// - /// \return True if loading was successful + /// \param copy Instance to copy /// //////////////////////////////////////////////////////////// - bool LoadFromFile(const std::string& filename, unsigned int charSize = 30, String charset = ourDefaultCharset); + Font(const Font& copy); //////////////////////////////////////////////////////////// - /// Load the font from a file in memory + /// \brief Destructor /// - /// \param data : Pointer to the data to load - /// \param sizeInBytes : Size of the data, in bytes - /// \param charSize : Size of characters in bitmap - the bigger, the higher quality - /// \param charset : Characters set to generate (by default, contains the ISO-8859-1 printable characters) - /// - /// \return True if loading was successful + /// Cleans up all the internal resources used by the font /// //////////////////////////////////////////////////////////// - bool LoadFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize = 30, String charset = ourDefaultCharset); + ~Font(); //////////////////////////////////////////////////////////// - /// Get the base size of characters in the font; - /// All glyphs dimensions are based on this value + /// \brief Load the font from a file /// - /// \return Base size of characters + /// The supported font formats are: TrueType, Type 1, CFF, + /// OpenType, SFNT, X11 PCF, Windows FNT, BDF, PFR and Type 42. + /// Note that this function know nothing about the standard + /// fonts installed on the user's system, thus you can't + /// load them directly. + /// + /// \param filename Path of the font file to load + /// + /// \return True if loading succeeded, false if it failed + /// + /// \see LoadFromMemory /// //////////////////////////////////////////////////////////// - unsigned int GetCharacterSize() const; + bool LoadFromFile(const std::string& filename); //////////////////////////////////////////////////////////// - /// Get the description of a glyph (character) - /// given by its unicode value + /// \brief Load the font from a file /// - /// \param codePoint : Unicode value of the character to get + /// The supported font formats are: TrueType, Type 1, CFF, + /// OpenType, SFNT, X11 PCF, Windows FNT, BDF, PFR and Type 42. + /// Note that this function know nothing about the standard + /// fonts installed on the user's system, thus you can't + /// load them directly. /// - /// \return Glyph's visual settings, or an invalid glyph if character not found + /// \param data Pointer to the file data in memory + /// \param sizeInBytes Size of the data to load, in bytes + /// + /// \return True if loading succeeded, false if it failed + /// + /// \see LoadFromFile /// //////////////////////////////////////////////////////////// - const Glyph& GetGlyph(Uint32 codePoint) const; + bool LoadFromMemory(const char* data, std::size_t sizeInBytes); //////////////////////////////////////////////////////////// - /// Get the image containing the rendered characters (glyphs) + /// \brief Retrieve a glyph of the font /// - /// \return Image containing glyphs + /// \param codePoint Unicode code point of the character to get + /// \param characterSize Reference character size + /// + /// \return The glyph corresponding to \a codePoint and \a characterSize /// //////////////////////////////////////////////////////////// - const Image& GetImage() const; + const Glyph& GetGlyph(Uint32 codePoint, unsigned int characterSize) const; //////////////////////////////////////////////////////////// - /// Get the SFML default built-in font (Arial) + /// \brief Get the kerning offset of two glyphs /// - /// \return Instance of the default font + /// The kerning is an extra offset (negative) to apply between two + /// glyphs when rendering them, to make the pair look more "natural". + /// For example, the pair "AV" have a special kerning to make them + /// closer than other characters. Most of the glyphs pairs have a + /// kerning offset of zero, though. + /// + /// \param first Unicode code point of the first character + /// \param second Unicode code point of the second character + /// \param characterSize Reference character size + /// + /// \return Kerning value for \a first and \a second, in pixels + /// + //////////////////////////////////////////////////////////// + int GetKerning(Uint32 first, Uint32 second, unsigned int characterSize) const; + + //////////////////////////////////////////////////////////// + /// \brief Get the line spacing + /// + /// Line spacing is the vertical offset to apply between two + /// consecutive lines of text. + /// + /// \param characterSize Reference character size + /// + /// \return Line spacing, in pixels + /// + //////////////////////////////////////////////////////////// + int GetLineSpacing(unsigned int characterSize) const; + + //////////////////////////////////////////////////////////// + /// \brief Retrieve the image containing the loaded glyphs of a certain size + /// + /// The contents of the returned image changes as more glyphs + /// are requested, thus it is not very relevant. It is mainly + /// used internally by sf::Text. + /// + /// \param characterSize Reference character size + /// + /// \return Image containing the glyphs of the requested size + /// + //////////////////////////////////////////////////////////// + const Image& GetImage(unsigned int characterSize) const; + + //////////////////////////////////////////////////////////// + /// \brief Overload of assignment operator + /// + /// \param right Instance to assign + /// + /// \return Reference to self + /// + //////////////////////////////////////////////////////////// + Font& operator =(const Font& right); + + //////////////////////////////////////////////////////////// + /// \brief Return the default built-in font + /// + /// This font is provided for convenience, it is used by + /// sf::Text instances by default. It is provided so that + /// users don't have to provide and load a font file in order + /// to display text on screen. + /// The font used is Arial. + /// + /// \return Reference to the built-in default font /// //////////////////////////////////////////////////////////// static const Font& GetDefaultFont(); private : - friend class priv::FontLoader; + //////////////////////////////////////////////////////////// + /// \brief Structure storing a glyph together with its + /// rectangle in the texture + /// + //////////////////////////////////////////////////////////// + struct GlyphInfo + { + Glyph GlyphDesc; + IntRect TextureRect; + }; //////////////////////////////////////////////////////////// - // Static member data + /// \brief Structure defining a row of glyphs + /// //////////////////////////////////////////////////////////// - static Uint32 ourDefaultCharset[]; ///< The default charset (all printable ISO-8859-1 characters) + struct Row + { + Row(unsigned int top, unsigned int height) : Width(0), Top(top), Height(height) {} + + unsigned int Width; ///< Current width of the row + unsigned int Top; ///< Y position of the row into the texture + unsigned int Height; ///< Height of the row + }; + + //////////////////////////////////////////////////////////// + // Types + //////////////////////////////////////////////////////////// + typedef std::map GlyphTable; ///< Table mapping a codepoint to its glyph + + //////////////////////////////////////////////////////////// + /// \brief Structure defining a page if glyphs + /// + //////////////////////////////////////////////////////////// + struct Page + { + Page(); + + GlyphTable Glyphs; ///< Table mapping code points to their corresponding glyph + Image Texture; ///< Image containing the pixels of the glyphs + unsigned int NextRow; ///< Y position of the next new row in the image + std::vector Rows; ///< List containing the position of all the existing rows + }; + + //////////////////////////////////////////////////////////// + /// \brief Free all the internal resources + /// + //////////////////////////////////////////////////////////// + void Cleanup(); + + //////////////////////////////////////////////////////////// + /// \brief Load a new glyph and store it in the cache + /// + /// \param codePoint Unicode code point of the character to load + /// \param characterSize Reference character size + /// + /// \return The glyph corresponding to \a codePoint and \a characterSize + /// + //////////////////////////////////////////////////////////// + GlyphInfo LoadGlyph(Uint32 codePoint, unsigned int characterSize) const; + + //////////////////////////////////////////////////////////// + /// \brief Find a suitable rectangle within the texture for a glyph + /// + /// \param page Page of glyphs to search in + /// \param width Width of the rectangle + /// \param height Height of the rectangle + /// + /// \return Found rectangle within the texture + /// + //////////////////////////////////////////////////////////// + IntRect FindGlyphRect(Page& page, unsigned int width, unsigned int height) const; + + //////////////////////////////////////////////////////////// + /// \brief Make sure that the given size is the current one + /// + /// \param characterSize Reference character size + /// + /// \return True on success, false if any error happened + /// + //////////////////////////////////////////////////////////// + bool SetCurrentSize(unsigned int characterSize) const; + + //////////////////////////////////////////////////////////// + // Types + //////////////////////////////////////////////////////////// + typedef std::map PageTable; ///< Table mapping a character size to its page (image) //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - Image myTexture; ///< Texture holding the bitmap font - unsigned int myCharSize; ///< Size of characters in the bitmap font - std::map myGlyphs; ///< Rendering settings of each character (glyph) + void* myLibrary; ///< Pointer to the internal library interface (it is typeless to avoid exposing implementation details) + void* myFace; ///< Pointer to the internal font face (it is typeless to avoid exposing implementation details) + int* myRefCount; ///< Reference counter used by implicit sharing + mutable PageTable myPages; ///< Table containing the glyphs pages by character size + mutable std::vector myPixelBuffer; ///< Pixel buffer holding a glyph's pixels before being written to the texture + mutable unsigned int myCurrentSize; ///< Current character size in use }; } // namespace sf #endif // SFML_FONT_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::Font +/// +/// Fonts can be loaded from a file or from memory, from +/// the most common types of fonts. See the LoadFromFile() +/// function for the complete list of supported formats. +/// +/// Once it is loaded, a sf::Font instance provides three +/// types of informations about the font: +/// \li Global metrics, such as the line spacing +/// \li Per-glyph metrics, such as bounding box or kerning +/// \li Pixel representation of glyphs +/// +/// Fonts alone are not very useful: they hold the font data +/// but cannot make anything useful of it. To do so you need to +/// use the sf::Text class, which is able to properly output text +/// with several options such as character size, style, color, +/// position, rotation, etc. +/// This separation allows more flexibility and better performances: +/// indeed a sf::Font is a heavy resource, and any operation on it +/// is slow (often too slow for real-time applications). On the other +/// side, a sf::Text is a lightweight object which can combine the +/// glyphs data and metrics of a sf::Font to display any text on a +/// render target. +/// Note that it is also possible to bind several sf::Text instances +/// to the same sf::Font. +/// +/// It is important to note that the sf::Text instance doesn't +/// copy the font that it uses, it only keeps a reference to it. +/// Thus, a sf::Font must not be destructed while it is +/// used by a sf::Text (i.e. never write a function that +/// uses a local sf::Font instance for creating a text). +/// +/// Usage example: +/// \code +/// // Declare a new font +/// sf::Font font; +/// +/// // Load it from a file +/// if (!font.LoadFromFile("arial.ttf")) +/// { +/// // error... +/// } +/// +/// // Create a text which uses our font +/// sf::Text text1; +/// text1.SetFont(font); +/// text1.SetCharacterSize(30); +/// text1.SetStyle(sf::Text::Regular); +/// +/// // Create another text using the same font, but with different parameters +/// sf::Text text2; +/// text2.SetFont(font); +/// text2.SetCharacterSize(50); +/// text1.SetStyle(sf::Text::Italic); +/// \endcode +/// +/// Apart from loading font files, and passing them to instances +/// of sf::Text, you should normally not have to deal directly +/// with this class. However, it may be useful to access the +/// font metrics or rasterized glyphs for advanced usage. +/// +/// \see sf::Text +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Graphics/Glyph.hpp b/include/SFML/Graphics/Glyph.hpp index ec1b8869..1b6168a3 100644 --- a/include/SFML/Graphics/Glyph.hpp +++ b/include/SFML/Graphics/Glyph.hpp @@ -51,8 +51,8 @@ public : // Member data //////////////////////////////////////////////////////////// int Advance; ///< Offset to move horizontically to the next character - IntRect Rectangle; ///< Bounding rectangle of the glyph, in relative coordinates - FloatRect TexCoords; ///< Texture coordinates of the glyph inside the bitmap font + IntRect Rectangle; ///< Bounding rectangle of the glyph, in coordinates relative to the baseline + FloatRect TexCoords; ///< Texture coordinates of the glyph inside the font's image }; } // namespace sf diff --git a/include/SFML/Graphics/Image.hpp b/include/SFML/Graphics/Image.hpp index 77f5e15d..907fdf13 100644 --- a/include/SFML/Graphics/Image.hpp +++ b/include/SFML/Graphics/Image.hpp @@ -203,7 +203,7 @@ public : /// Warning: for performances reasons, this function doesn't /// perform any check; thus you're responsible of ensuring that /// \a rectangle does not exceed the image size, and that - /// \a pixels contain enough elements. + /// \a pixels contains enough elements. /// /// \param rectangle : Sub-rectangle of the image to update /// \param pixels : Array of pixels to write to the image diff --git a/include/SFML/Graphics/Text.hpp b/include/SFML/Graphics/Text.hpp index 8a865f94..5524428f 100644 --- a/include/SFML/Graphics/Text.hpp +++ b/include/SFML/Graphics/Text.hpp @@ -65,12 +65,12 @@ public : //////////////////////////////////////////////////////////// /// Construct the string from any kind of text /// - /// \param string : 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 characterSize : Base size of characters, in pixels /// //////////////////////////////////////////////////////////// - explicit Text(const String& string, const Font& font = Font::GetDefaultFont(), float size = 30.f); + explicit Text(const String& string, const Font& font = Font::GetDefaultFont(), unsigned int characterSize = 30); //////////////////////////////////////////////////////////// /// Set the text (from any kind of string) @@ -89,13 +89,13 @@ public : void SetFont(const Font& font); //////////////////////////////////////////////////////////// - /// Set the size of the string + /// Set the base size for the characters. /// The default size is 30 /// /// \param size : New size, in pixels /// //////////////////////////////////////////////////////////// - void SetSize(float size); + void SetCharacterSize(unsigned int size); //////////////////////////////////////////////////////////// /// Set the style of the text @@ -123,12 +123,12 @@ public : const Font& GetFont() const; //////////////////////////////////////////////////////////// - /// Get the size of the characters + /// Get the base size of characters /// - /// \return Size of the characters + /// \return Size of the characters, in pixels /// //////////////////////////////////////////////////////////// - float GetSize() const; + unsigned int GetCharacterSize() const; //////////////////////////////////////////////////////////// /// Get the style of the text @@ -148,7 +148,7 @@ public : /// \return Position of the index-th character (end of string if Index is out of range) /// //////////////////////////////////////////////////////////// - sf::Vector2f GetCharacterPos(std::size_t index) const; + Vector2f GetCharacterPos(std::size_t index) const; //////////////////////////////////////////////////////////// /// Get the string rectangle on screen @@ -179,7 +179,7 @@ private : //////////////////////////////////////////////////////////// String myString; ///< String to display ResourcePtr myFont; ///< Font used to display the string - float mySize; ///< Size of the characters + unsigned int myCharacterSize; ///< Base size of characters, in pixels unsigned long myStyle; ///< Text style (see Style enum) FloatRect myBaseRect; ///< Bounding rectangle of the text in object coordinates bool myNeedRectUpdate; ///< Does the bounding rect need an update ? diff --git a/samples/pong/Pong.cpp b/samples/pong/Pong.cpp index 192a6820..e1db79b1 100644 --- a/samples/pong/Pong.cpp +++ b/samples/pong/Pong.cpp @@ -47,7 +47,7 @@ int main() // Initialize the end text sf::Text end; end.SetFont(font); - end.SetSize(60.f); + end.SetCharacterSize(60); end.Move(150.f, 200.f); end.SetColor(sf::Color(50, 50, 250)); diff --git a/samples/shader/Shader.cpp b/samples/shader/Shader.cpp index 8d102082..45ba013b 100644 --- a/samples/shader/Shader.cpp +++ b/samples/shader/Shader.cpp @@ -108,7 +108,7 @@ int main() // Load the text font sf::Font font; - if (!font.LoadFromFile("datas/shader/arial.ttf", 20)) + if (!font.LoadFromFile("datas/shader/arial.ttf")) return EXIT_FAILURE; // Load the image needed for the wave shader @@ -144,7 +144,7 @@ int main() // Define a string for displaying the description of the current shader sf::Text shaderStr; shaderStr.SetFont(font); - shaderStr.SetSize(20); + shaderStr.SetCharacterSize(20); shaderStr.SetPosition(5.f, 0.f); shaderStr.SetColor(sf::Color(250, 100, 30)); shaderStr.SetString("Background shader: \"" + backgroundShader.GetName() + "\"\n" @@ -154,8 +154,8 @@ int main() // Define a string for displaying help sf::Text infoStr; infoStr.SetFont(font); - infoStr.SetSize(20); - infoStr.SetPosition(5.f, 510.f); + infoStr.SetCharacterSize(20); + infoStr.SetPosition(5.f, 500.f); infoStr.SetColor(sf::Color(250, 100, 30)); infoStr.SetString("Move your mouse to change the shaders' parameters\n" "Press numpad 1/4 to change the background shader\n" diff --git a/src/SFML/Graphics/Font.cpp b/src/SFML/Graphics/Font.cpp index ab6455be..cdf15494 100644 --- a/src/SFML/Graphics/Font.cpp +++ b/src/SFML/Graphics/Font.cpp @@ -26,133 +26,213 @@ // Headers //////////////////////////////////////////////////////////// #include -#include +#include +#include FT_FREETYPE_H +#include FT_GLYPH_H #include namespace sf { //////////////////////////////////////////////////////////// -// Static member data -//////////////////////////////////////////////////////////// -Uint32 Font::ourDefaultCharset[] = -{ - // Printable characters in ASCII range - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, - - // Printable characters in extended ASCII range - 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0x2A, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, - 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, - 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, - 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, - 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, - - // To make it a valid string - 0x00 -}; - - -//////////////////////////////////////////////////////////// -/// Default constructor -//////////////////////////////////////////////////////////// Font::Font() : -myCharSize(0) +myLibrary (NULL), +myFace (NULL), +myRefCount (NULL), +myCurrentSize(0) { } //////////////////////////////////////////////////////////// -/// Load the font from a file -//////////////////////////////////////////////////////////// -bool Font::LoadFromFile(const std::string& filename, unsigned int charSize, String charset) +Font::Font(const Font& copy) : +myLibrary (copy.myLibrary), +myFace (copy.myFace), +myRefCount (copy.myRefCount), +myPages (copy.myPages), +myPixelBuffer(copy.myPixelBuffer), +myCurrentSize(copy.myCurrentSize) { - // Clear the previous character map - myGlyphs.clear(); + // Note: as FreeType doesn't provide functions for copying/cloning, + // we must share all the FreeType pointers - // Always add these special characters - 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, charset, *this); + if (myRefCount) + (*myRefCount)++; } //////////////////////////////////////////////////////////// -/// Load the font from a file in memory -//////////////////////////////////////////////////////////// -bool Font::LoadFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize, String charset) +Font::~Font() { - // Clear the previous character map - myGlyphs.clear(); + Cleanup(); +} - // Check parameters - if (!data || (sizeInBytes == 0)) + +//////////////////////////////////////////////////////////// +bool Font::LoadFromFile(const std::string& filename) +{ + // Cleanup the previous resources + Cleanup(); + + // Initialize FreeType + // Note: we initialize FreeType for every font instance in order to avoid having a single + // global manager that would create a lot of issues regarding creation and destruction order. + FT_Library library; + if (FT_Init_FreeType(&library) != 0) { - std::cerr << "Failed to load font from memory, no data provided" << std::endl; + std::cerr << "Failed to load font \"" << filename << "\" (failed to initialize FreeType)" << std::endl; + return false; + } + myLibrary = library; + + // Load the new font face from the specified file + FT_Face face; + if (FT_New_Face(static_cast(myLibrary), filename.c_str(), 0, &face) != 0) + { + std::cerr << "Failed to load font \"" << filename << "\" (failed to create the font face)" << std::endl; return false; } - // Always add these special characters - 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, charset, *this); -} - - -//////////////////////////////////////////////////////////// -/// Get the base size of characters in the font; -/// All glyphs dimensions are based on this value -//////////////////////////////////////////////////////////// -unsigned int Font::GetCharacterSize() const -{ - return myCharSize; -} - - -//////////////////////////////////////////////////////////// -/// Get the description of a glyph (character) -/// given by its unicode value -//////////////////////////////////////////////////////////// -const Glyph& Font::GetGlyph(Uint32 codePoint) const -{ - std::map::const_iterator it = myGlyphs.find(codePoint); - if (it != myGlyphs.end()) + // Select the unicode character map + if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) != 0) { - // Valid glyph - return it->second; + std::cerr << "Failed to load font \"" << filename << "\" (failed to set the Unicode character set)" << std::endl; + return false; + } + + // Store the loaded font in our ugly void* :) + myFace = face; + + return true; +} + + +//////////////////////////////////////////////////////////// +bool Font::LoadFromMemory(const char* data, std::size_t sizeInBytes) +{ + // Cleanup the previous resources + Cleanup(); + + // Initialize FreeType + // Note: we initialize FreeType for every font instance in order to avoid having a single + // global manager that would create a lot of issues regarding creation and destruction order. + FT_Library library; + if (FT_Init_FreeType(&library) != 0) + { + std::cerr << "Failed to load font from memory (failed to initialize FreeType)" << std::endl; + return false; + } + myLibrary = library; + + // Load the new font face from the specified file + FT_Face face; + if (FT_New_Memory_Face(static_cast(myLibrary), reinterpret_cast(data), static_cast(sizeInBytes), 0, &face) != 0) + { + std::cerr << "Failed to load font from memory (failed to create the font face)" << std::endl; + return false; + } + + // Select the unicode character map + if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) != 0) + { + std::cerr << "Failed to load font from memory (failed to set the Unicode character set)" << std::endl; + return false; + } + + // Store the loaded font in our ugly void* :) + myFace = face; + + return true; +} + + +//////////////////////////////////////////////////////////// +const Glyph& Font::GetGlyph(Uint32 codePoint, unsigned int characterSize) const +{ + // Get the page corresponding to the character size + GlyphTable& glyphs = myPages[characterSize].Glyphs; + + // Search the glyph into the cache + GlyphTable::const_iterator it = glyphs.find(codePoint); + if (it != glyphs.end()) + { + // Found: just return it + return it->second.GlyphDesc; } else { - // Invalid glyph -- return an invalid glyph - static const Glyph invalid; - return invalid; + // Not found: we have to load it + GlyphInfo glyph = LoadGlyph(codePoint, characterSize); + return glyphs.insert(std::make_pair(codePoint, glyph)).first->second.GlyphDesc; } } //////////////////////////////////////////////////////////// -/// Get the image containing the rendered characters (glyphs) -//////////////////////////////////////////////////////////// -const Image& Font::GetImage() const +int Font::GetKerning(Uint32 first, Uint32 second, unsigned int characterSize) const { - return myTexture; + FT_Face face = static_cast(myFace); + + if (face && FT_HAS_KERNING(face) && SetCurrentSize(characterSize)) + { + // Convert the characters to indices + FT_UInt index1 = FT_Get_Char_Index(face, first); + FT_UInt index2 = FT_Get_Char_Index(face, second); + + // Get the kerning vector + FT_Vector kerning; + FT_Get_Kerning(face, index1, index2, FT_KERNING_DEFAULT, &kerning); + + // Return the X advance + return kerning.x >> 6; + } + else + { + // Invalid font, or no kerning + return 0; + } } //////////////////////////////////////////////////////////// -/// Get the SFML default built-in font (Arial) +int Font::GetLineSpacing(unsigned int characterSize) const +{ + FT_Face face = static_cast(myFace); + + if (face && SetCurrentSize(characterSize)) + { + return (face->size->metrics.height >> 6); + } + else + { + return 0; + } +} + + +//////////////////////////////////////////////////////////// +const Image& Font::GetImage(unsigned int characterSize) const +{ + return myPages[characterSize].Texture; +} + + +//////////////////////////////////////////////////////////// +Font& Font::operator =(const Font& right) +{ + Font temp(right); + + std::swap(myLibrary, temp.myLibrary); + std::swap(myFace, temp.myFace); + std::swap(myPages, temp.myPages); + std::swap(myPixelBuffer, temp.myPixelBuffer); + std::swap(myCurrentSize, temp.myCurrentSize); + + return *this; +} + + //////////////////////////////////////////////////////////// const Font& Font::GetDefaultFont() { @@ -167,11 +247,231 @@ const Font& Font::GetDefaultFont() #include }; - font.LoadFromMemory(data, sizeof(data), 30); + font.LoadFromMemory(data, sizeof(data)); loaded = true; } return font; } + +//////////////////////////////////////////////////////////// +void Font::Cleanup() +{ + // Check if we must destroy the FreeType pointers + if (myRefCount) + { + // Decrease the reference counter + (*myRefCount)--; + + // Free the resources only if we are the last owner + if (*myRefCount == 0) + { + // Delete the reference counter + delete myRefCount; + + // Destroy the font face + if (myFace) + FT_Done_Face(static_cast(myFace)); + + // Close the library + if (myLibrary) + FT_Done_FreeType(static_cast(myLibrary)); + } + } + + // Reset members + myLibrary = NULL; + myFace = NULL; + myRefCount = NULL; + myCurrentSize = 0; + myPages.clear(); + myPixelBuffer.clear(); +} + + +//////////////////////////////////////////////////////////// +Font::GlyphInfo Font::LoadGlyph(Uint32 codePoint, unsigned int characterSize) const +{ + // The glyph to return + GlyphInfo glyphInfo; + + // First, transform our ugly void* to a FT_Face + FT_Face face = static_cast(myFace); + if (!face) + return glyphInfo; + + // Set the character size + if (!SetCurrentSize(characterSize)) + return glyphInfo; + + // Load the glyph corresponding to the code point + if (FT_Load_Char(face, codePoint, FT_LOAD_TARGET_NORMAL) != 0) + return glyphInfo; + + // Convert the glyph to a bitmap (i.e. rasterize it) + FT_Glyph glyphDesc; + if (FT_Get_Glyph(face->glyph, &glyphDesc) != 0) + return glyphInfo; + FT_Glyph_To_Bitmap(&glyphDesc, FT_RENDER_MODE_NORMAL, 0, 1); + FT_BitmapGlyph bitmapGlyph = (FT_BitmapGlyph)glyphDesc; + FT_Bitmap& bitmap = bitmapGlyph->bitmap; + + // Compute the glyph's advance offset + glyphInfo.GlyphDesc.Advance = bitmapGlyph->root.advance.x >> 16; + + if ((bitmap.width > 0) && (bitmap.rows > 0)) + { + // Leave a small padding around characters, so that filtering doesn't + // pollute them with pixels from neighbours + const unsigned int padding = 1; + + // Get the glyphs page corresponding to the character size + Page& page = myPages[characterSize]; + + // Find a good position for the new glyph into the texture + glyphInfo.TextureRect = FindGlyphRect(page, bitmap.width + 2 * padding, bitmap.rows + 2 * padding); + + // Compute the glyph's texture coordinates and bounding box + glyphInfo.GlyphDesc.TexCoords = page.Texture.GetTexCoords(glyphInfo.TextureRect); + glyphInfo.GlyphDesc.Rectangle.Left = bitmapGlyph->left - padding; + glyphInfo.GlyphDesc.Rectangle.Top = -bitmapGlyph->top - padding; + glyphInfo.GlyphDesc.Rectangle.Right = bitmapGlyph->left + bitmap.width + padding; + glyphInfo.GlyphDesc.Rectangle.Bottom = -bitmapGlyph->top + bitmap.rows + padding; + + // Extract the glyph's pixels from the bitmap + myPixelBuffer.resize(bitmap.width * bitmap.rows * 4, 255); + const Uint8* pixels = bitmap.buffer; + for (int y = 0; y < bitmap.rows; ++y) + { + for (int x = 0; x < bitmap.width; ++x) + { + // The color channels remain white, just fill the alpha channel + std::size_t index = (x + y * bitmap.width) * 4 + 3; + myPixelBuffer[index] = pixels[x]; + + // Formula for FT_RENDER_MODE_MONO + // myPixelBuffer[index] = ((pixels[x / 8]) & (1 << (7 - (x % 8)))) ? 255 : 0; + } + pixels += bitmap.pitch; + } + + // Write the pixels to the texture + IntRect subrect = glyphInfo.TextureRect; + subrect.Left += padding; + subrect.Top += padding; + subrect.Right -= padding; + subrect.Bottom -= padding; + page.Texture.UpdatePixels(&myPixelBuffer[0], subrect); + } + + // Delete the FT glyph + FT_Done_Glyph(glyphDesc); + + // Done :) + return glyphInfo; +} + + +//////////////////////////////////////////////////////////// +IntRect Font::FindGlyphRect(Page& page, unsigned int width, unsigned int height) const +{ + // Find the line that fits well the glyph + Row* row = NULL; + float bestRatio = 0; + for (std::vector::iterator it = page.Rows.begin(); it != page.Rows.end() && !row; ++it) + { + float ratio = static_cast(height) / it->Height; + + // Ignore rows that are either too small or too high + if ((ratio < 0.7f) || (ratio > 1.f)) + continue; + + // Check if there's enough horizontal space left in the row + if (width > page.Texture.GetWidth() - it->Width) + continue; + + // Make sure that this new row is the best found so far + if (ratio < bestRatio) + continue; + + // The current row passed all the tests: we can select it + row = &*it; + bestRatio = ratio; + } + + // If we didn't find a matching row, create a new one (10% taller than the glyph) + if (!row) + { + int rowHeight = height + height / 10; + if (page.NextRow + rowHeight >= page.Texture.GetHeight()) + { + // Not enough space: resize the texture if possible + unsigned int textureWidth = page.Texture.GetWidth(); + unsigned int textureHeight = page.Texture.GetHeight(); + if ((textureWidth * 2 <= Image::GetMaximumSize()) && (textureHeight * 2 <= Image::GetMaximumSize())) + { + // Make the texture 2 times bigger + std::size_t size = textureWidth * textureHeight * 4; + std::vector pixels(size); + memcpy(&pixels[0], page.Texture.GetPixelsPtr(), size); + page.Texture.Create(textureWidth * 2, textureHeight * 2, sf::Color(255, 255, 255, 0)); + page.Texture.UpdatePixels(&pixels[0], IntRect(0, 0, textureWidth, textureHeight)); + + // Adjust the texture coordinates of all the glyphs that are stored in this page + for (GlyphTable::iterator it = page.Glyphs.begin(); it != page.Glyphs.end(); ++it) + { + it->second.GlyphDesc.TexCoords = page.Texture.GetTexCoords(it->second.TextureRect); + } + } + else + { + // Oops, we've reached the maximum texture size... + std::cerr << "Failed to add a new character to the font: the maximum image size has been reached" << std::endl; + return IntRect(0, 0, 2, 2); + } + } + + // We can now create the new row + page.Rows.push_back(Row(page.NextRow, rowHeight)); + page.NextRow += rowHeight; + row = &page.Rows.back(); + } + + // Find the glyph's rectangle on the selected row + IntRect rect(row->Width, row->Top, row->Width + width, row->Top + height); + + // Update the row informations + row->Width += width; + + return rect; +} + + +//////////////////////////////////////////////////////////// +bool Font::SetCurrentSize(unsigned int characterSize) const +{ + // FT_Set_Pixel_Sizes is an expensive function, so we must call it + // only when necessary to avoid killing performances + + if (myCurrentSize != characterSize) + { + myCurrentSize = characterSize; + return FT_Set_Pixel_Sizes(static_cast(myFace), characterSize, characterSize) == 0; + } + else + { + return true; + } +} + + +//////////////////////////////////////////////////////////// +Font::Page::Page() : +NextRow(0) +{ + // Make sure that the texture is initialized by default + Texture.Create(128, 128, Color(255, 255, 255, 0)); +} + } // namespace sf diff --git a/src/SFML/Graphics/FontLoader.cpp b/src/SFML/Graphics/FontLoader.cpp deleted file mode 100644 index 97802e18..00000000 --- a/src/SFML/Graphics/FontLoader.cpp +++ /dev/null @@ -1,671 +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. -// -//////////////////////////////////////////////////////////// - -//#define SFML_USE_STBTT -#ifndef SFML_USE_STBTT - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include -#include FT_GLYPH_H -#include -#include -#include -#include - - -namespace -{ - //////////////////////////////////////////////////////////// - // Functor to sort glyphs by size - //////////////////////////////////////////////////////////// - struct SizeCompare - { - bool operator ()(FT_BitmapGlyph left, FT_BitmapGlyph right) const - { - return left->bitmap.rows < right->bitmap.rows; - } - }; -} - -namespace sf -{ -namespace priv -{ -//////////////////////////////////////////////////////////// -/// Get the unique instance of the class -//////////////////////////////////////////////////////////// -FontLoader& FontLoader::GetInstance() -{ - static FontLoader instance; - - return instance; -} - - -//////////////////////////////////////////////////////////// -/// Default constructor -//////////////////////////////////////////////////////////// -FontLoader::FontLoader() -{ - // Initialize FreeType library - FT_Error error = FT_Init_FreeType(&myLibrary); - if (error) - { - std::cerr << "Failed to initialize FreeType library (error code : " << error << ")" << std::endl; - return; - } -} - - -//////////////////////////////////////////////////////////// -/// Destructor -//////////////////////////////////////////////////////////// -FontLoader::~FontLoader() -{ - // Shutdown FreeType library - if (myLibrary) - FT_Done_FreeType(myLibrary); -} - - -//////////////////////////////////////////////////////////// -/// Load a font from a file -//////////////////////////////////////////////////////////// -bool FontLoader::LoadFontFromFile(const std::string& filename, unsigned int charSize, const String& charset, Font& font) -{ - // Check if Freetype is correctly initialized - if (!myLibrary) - { - std::cerr << "Failed to load font \"" << filename << "\", FreeType has not been initialized" << std::endl; - return false; - } - - // Create a new font face from the specified file - FT_Face face; - FT_Error error = FT_New_Face(myLibrary, filename.c_str(), 0, &face); - if (error) - { - std::cerr << "Failed to load font \"" << filename << "\" (" << GetErrorDesc(error) << ")" << std::endl; - return false; - } - - // Create the bitmap font - error = CreateBitmapFont(face, charSize, charset, font); - if (error) - std::cerr << "Failed to load font \"" << filename << "\" (" << GetErrorDesc(error) << ")" << std::endl; - - // Delete the font - FT_Done_Face(face); - - return error == 0; -} - - -//////////////////////////////////////////////////////////// -/// Load the font from a file in memory -//////////////////////////////////////////////////////////// -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) - { - std::cerr << "Failed to load font from memory, FreeType has not been initialized" << std::endl; - return false; - } - - // Create a new font face from the specified memory data - FT_Face face; - FT_Error error = FT_New_Memory_Face(myLibrary, reinterpret_cast(data), static_cast(sizeInBytes), 0, &face); - if (error) - { - std::cerr << "Failed to load font from memory (" << GetErrorDesc(error) << ")" << std::endl; - return false; - } - - // Create the bitmap font - error = CreateBitmapFont(face, charSize, charset, font); - if (error) - std::cerr << "Failed to load font from memory (" << GetErrorDesc(error) << ")" << std::endl; - - // Delete the font - FT_Done_Face(face); - - return error == 0; -} - - -//////////////////////////////////////////////////////////// -/// Create a bitmap font from a font face and a characters set -//////////////////////////////////////////////////////////// -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 - unsigned int maxSize = Image::GetMaximumSize(); - 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 >= maxSize) - charSize = maxSize / nbChars; - - // Initialize the dimensions - unsigned int left = 0; - unsigned int top = 0; - unsigned int texWidth = Image::GetValidSize(charSize * nbChars); - unsigned int texHeight = charSize * nbChars; - std::vector tops(texWidth, 0); - - // Create a pixel buffer for rendering every glyph - std::vector glyphsBuffer(texWidth * texHeight * 4); - - // Setup the font size - FT_Error error = FT_Set_Pixel_Sizes(face, charSize, charSize); - if (error) - return error; - - // Select the unicode character map - error = FT_Select_Charmap(face, FT_ENCODING_UNICODE); - if (error) - return error; - - // 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.GetSize(); ++i) - { - // Load the glyph corresponding to the current character - error = FT_Load_Char(face, charset[i], FT_LOAD_TARGET_NORMAL); - if (error) - return error; - - // Convert the glyph to a bitmap (ie. rasterize it) - FT_Glyph glyph; - error = FT_Get_Glyph(face->glyph, &glyph); - if (error) - return error; - FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1); - FT_BitmapGlyph bitmapGlyph = (FT_BitmapGlyph)glyph; - - // Add it to the sorted table of glyphs - glyphs.insert(std::make_pair(bitmapGlyph, charset[i])); - } - - // Leave a small margin around characters, so that filtering doesn't - // pollute them with pixels from neighbours - unsigned int padding = 1; - unsigned int margin = 1; - - // Copy the rendered glyphs into the texture - unsigned int maxHeight = 0; - std::map coords; - for (GlyphTable::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i) - { - // Get the bitmap of the current glyph - Glyph& curGlyph = font.myGlyphs[i->second]; - FT_BitmapGlyph bitmapGlyph = i->first; - FT_Bitmap& bitmap = bitmapGlyph->bitmap; - - // Make sure we don't go over the texture width - if (left + bitmap.width + 2 * padding + margin >= texWidth) - left = 0; - - // Compute the top coordinate - top = tops[left]; - for (unsigned int x = 0; x < bitmap.width + 2 * padding + margin; ++x) - top = std::max(top, tops[left + x]); - - // Make sure we don't go over the texture height -- resize it if we need more space - if (top + bitmap.rows + 2 * padding + margin >= texHeight) - { - texHeight *= 2; - glyphsBuffer.resize(texWidth * texHeight * 4); - } - - // Store the character's position and size - curGlyph.Rectangle.Left = bitmapGlyph->left - padding; - curGlyph.Rectangle.Top = -bitmapGlyph->top - padding; - curGlyph.Rectangle.Right = bitmapGlyph->left + bitmap.width + padding; - curGlyph.Rectangle.Bottom = -bitmapGlyph->top + bitmap.rows + padding; - curGlyph.Advance = bitmapGlyph->root.advance.x >> 16; - - // Texture size may change, so let the texture coordinates be calculated later - coords[i->second] = IntRect(left, top, left + bitmap.width + 2 * padding, top + bitmap.rows + 2 * padding); - - // Draw the glyph into our bitmap font - const Uint8* pixels = bitmap.buffer; - for (int y = 0; y < bitmap.rows; ++y) - { - for (int x = 0; x < bitmap.width; ++x) - { - std::size_t index = x + left + padding + (y + top + padding) * texWidth; - glyphsBuffer[index * 4 + 0] = 255; - glyphsBuffer[index * 4 + 1] = 255; - glyphsBuffer[index * 4 + 2] = 255; - glyphsBuffer[index * 4 + 3] = pixels[x]; - - // Formula for FT_RENDER_MODE_MONO - // glyphsBuffer[index * 4 + 3] = ((pixels[x / 8]) & (1 << (7 - (x % 8)))) ? 255 : 0; - } - pixels += bitmap.pitch; - } - - // Update the rendering coordinates - for (unsigned int x = 0; x < bitmap.width + 2 * padding + margin; ++x) - tops[left + x] = top + bitmap.rows + 2 * padding + margin; - left += bitmap.width + 2 * padding + margin; - if (top + bitmap.rows + 2 * padding > maxHeight) - maxHeight = top + bitmap.rows + 2 * padding; - - // Delete the glyph - FT_Done_Glyph((FT_Glyph)bitmapGlyph); - } - - // Create the font's texture - texHeight = maxHeight; - glyphsBuffer.resize(texWidth * texHeight * 4); - 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.GetSize(); ++i) - { - Uint32 curChar = charset[i]; - font.myGlyphs[curChar].TexCoords = font.myTexture.GetTexCoords(coords[curChar]); - } - - // Update the character size (it may have been changed by the function) - font.myCharSize = charSize; - - return 0; -} - - -//////////////////////////////////////////////////////////// -/// Get a description from a FT error code -//////////////////////////////////////////////////////////// -std::string FontLoader::GetErrorDesc(FT_Error error) -{ - switch (error) - { - // Generic errors - case FT_Err_Cannot_Open_Resource : return "cannot open resource"; - case FT_Err_Unknown_File_Format : return "unknown file format"; - case FT_Err_Invalid_File_Format : return "broken file"; - case FT_Err_Invalid_Version : return "invalid FreeType version"; - case FT_Err_Lower_Module_Version : return "module version is too low"; - case FT_Err_Invalid_Argument : return "invalid argument"; - case FT_Err_Unimplemented_Feature : return "unimplemented feature"; - case FT_Err_Invalid_Table : return "broken table"; - case FT_Err_Invalid_Offset : return "broken offset within table"; - - // Glyph / character errors - case FT_Err_Invalid_Glyph_Index : return "invalid glyph index"; - case FT_Err_Invalid_Character_Code : return "invalid character code"; - case FT_Err_Invalid_Glyph_Format : return "unsupported glyph image format"; - case FT_Err_Cannot_Render_Glyph : return "cannot render this glyph format"; - case FT_Err_Invalid_Outline : return "invalid outline"; - case FT_Err_Invalid_Composite : return "invalid composite glyph"; - case FT_Err_Too_Many_Hints : return "too many hints"; - case FT_Err_Invalid_Pixel_Size : return "invalid pixel size"; - - // Handle errors - case FT_Err_Invalid_Handle : return "invalid object handle"; - case FT_Err_Invalid_Library_Handle : return "invalid library handle"; - case FT_Err_Invalid_Driver_Handle : return "invalid module handle"; - case FT_Err_Invalid_Face_Handle : return "invalid face handle"; - case FT_Err_Invalid_Size_Handle : return "invalid size handle"; - case FT_Err_Invalid_Slot_Handle : return "invalid glyph slot handle"; - case FT_Err_Invalid_CharMap_Handle : return "invalid charmap handle"; - case FT_Err_Invalid_Cache_Handle : return "invalid cache manager handle"; - case FT_Err_Invalid_Stream_Handle : return "invalid stream handle"; - - // Driver errors - case FT_Err_Too_Many_Drivers : return "too many modules"; - case FT_Err_Too_Many_Extensions : return "too many extensions"; - - // Memory errors - case FT_Err_Out_Of_Memory : return "out of memory"; - case FT_Err_Unlisted_Object : return "unlisted object"; - - // Stream errors - case FT_Err_Cannot_Open_Stream : return "cannot open stream"; - case FT_Err_Invalid_Stream_Seek : return "invalid stream seek"; - case FT_Err_Invalid_Stream_Skip : return "invalid stream skip"; - case FT_Err_Invalid_Stream_Read : return "invalid stream read"; - case FT_Err_Invalid_Stream_Operation : return "invalid stream operation"; - case FT_Err_Invalid_Frame_Operation : return "invalid frame operation"; - case FT_Err_Nested_Frame_Access : return "nested frame access"; - case FT_Err_Invalid_Frame_Read : return "invalid frame read"; - - // Raster errors - case FT_Err_Raster_Uninitialized : return "raster uninitialized"; - case FT_Err_Raster_Corrupted : return "raster corrupted"; - case FT_Err_Raster_Overflow : return "raster overflow"; - case FT_Err_Raster_Negative_Height : return "negative height while rastering"; - - // Cache errors - case FT_Err_Too_Many_Caches : return "too many registered caches"; - - // TrueType and SFNT errors - case FT_Err_Invalid_Opcode : return "invalid opcode"; - case FT_Err_Too_Few_Arguments : return "too few arguments"; - case FT_Err_Stack_Overflow : return "stack overflow"; - case FT_Err_Code_Overflow : return "code overflow"; - case FT_Err_Bad_Argument : return "bad argument"; - case FT_Err_Divide_By_Zero : return "division by zero"; - case FT_Err_Invalid_Reference : return "invalid reference"; - case FT_Err_Debug_OpCode : return "found debug opcode"; - case FT_Err_ENDF_In_Exec_Stream : return "found ENDF opcode in execution stream"; - case FT_Err_Nested_DEFS : return "nested DEFS"; - case FT_Err_Invalid_CodeRange : return "invalid code range"; - case FT_Err_Execution_Too_Long : return "execution context too long"; - case FT_Err_Too_Many_Function_Defs : return "too many function definitions"; - case FT_Err_Too_Many_Instruction_Defs : return "too many instruction definitions"; - case FT_Err_Table_Missing : return "SFNT font table missing"; - case FT_Err_Horiz_Header_Missing : return "horizontal header (hhea) table missing"; - case FT_Err_Locations_Missing : return "locations (loca) table missing"; - case FT_Err_Name_Table_Missing : return "name table missing"; - case FT_Err_CMap_Table_Missing : return "character map (cmap) table missing"; - case FT_Err_Hmtx_Table_Missing : return "horizontal metrics (hmtx) table missing"; - case FT_Err_Post_Table_Missing : return "PostScript (post) table missing"; - case FT_Err_Invalid_Horiz_Metrics : return "invalid horizontal metrics"; - case FT_Err_Invalid_CharMap_Format : return "invalid character map (cmap) format"; - case FT_Err_Invalid_PPem : return "invalid ppem value"; - case FT_Err_Invalid_Vert_Metrics : return "invalid vertical metrics"; - case FT_Err_Could_Not_Find_Context : return "could not find context"; - case FT_Err_Invalid_Post_Table_Format : return "invalid PostScript (post) table format"; - case FT_Err_Invalid_Post_Table : return "invalid PostScript (post) table"; - - // CCF, CID and Type 1 errors - case FT_Err_Syntax_Error : return "opcode syntax error"; - case FT_Err_Stack_Underflow : return "argument stack underflow"; - case FT_Err_Ignore : return "ignore"; - - // BDF errors - case FT_Err_Missing_Startfont_Field : return "`STARTFONT' field missing"; - case FT_Err_Missing_Font_Field : return "`FONT' field missing"; - case FT_Err_Missing_Size_Field : return "`SIZE' field missing"; - case FT_Err_Missing_Chars_Field : return "`CHARS' field missing"; - case FT_Err_Missing_Startchar_Field : return "`STARTCHAR' field missing"; - case FT_Err_Missing_Encoding_Field : return "`ENCODING' field missing"; - case FT_Err_Missing_Bbx_Field : return "`BBX' field missing"; - } - - return "unknown error"; -} - -} // namespace priv - -} // namespace sf - -#else - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include -#define STB_TRUETYPE_IMPLEMENTATION -#include -#include -#include -#include -#include -#include - - -namespace -{ - //////////////////////////////////////////////////////////// - // Functor to sort glyphs by size - //////////////////////////////////////////////////////////// - struct SizeCompare - { - bool operator ()(const sf::Glyph& left, const sf::Glyph& right) const - { - return left.Rectangle.GetSize().y < right.Rectangle.GetSize().y; - } - }; -} - -namespace sf -{ -namespace priv -{ -//////////////////////////////////////////////////////////// -/// Get the unique instance of the class -//////////////////////////////////////////////////////////// -FontLoader& FontLoader::GetInstance() -{ - static FontLoader instance; - - return instance; -} - - -//////////////////////////////////////////////////////////// -/// Default constructor -//////////////////////////////////////////////////////////// -FontLoader::FontLoader() -{ -} - - -//////////////////////////////////////////////////////////// -/// Destructor -//////////////////////////////////////////////////////////// -FontLoader::~FontLoader() -{ -} - - -//////////////////////////////////////////////////////////// -/// Load a font from a file -//////////////////////////////////////////////////////////// -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); - if (!file) - return false; - file.seekg(0, std::ios::end); - std::size_t length = file.tellg(); - file.seekg(0, std::ios::beg); - std::vector data(length); - file.read(&data[0], static_cast(length)); - - // Load from memory - return LoadFontFromMemory(&data[0], data.size(), charSize, charset, font); -} - - -//////////////////////////////////////////////////////////// -/// Load the font from a file in memory -//////////////////////////////////////////////////////////// -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 - unsigned int maxSize = Image::GetMaximumSize(); - 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 >= maxSize) - charSize = maxSize / nbChars; - - // Initialize the dimensions - unsigned int left = 0; - unsigned int top = 0; - unsigned int texWidth = Image::GetValidSize(charSize * nbChars); - unsigned int texHeight = charSize * nbChars; - std::vector tops(texWidth, 0); - - // Create a pixel buffer for rendering every glyph - std::vector glyphsBuffer(texWidth * texHeight * 4); - - // Load the font - stbtt_fontinfo info; - int success = stbtt_InitFont(&info, reinterpret_cast(data), 0); - if (!success) - return false; - - // Compute the global scale to apply to match the character size - float scale = stbtt_ScaleForPixelHeight(&info, static_cast(charSize)); - - // 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.GetSize(); ++i) - { - // Load the glyph corresponding to the current character - int index = stbtt_FindGlyphIndex(&info, static_cast(charset[i])); - - // Extract the glyph parameters (bounding box, horizontal advance) - Glyph glyph; - stbtt_GetGlyphHMetrics(&info, index, &glyph.Advance, NULL); - stbtt_GetGlyphBitmapBox(&info, index, scale, scale, &glyph.Rectangle.Left, &glyph.Rectangle.Top, &glyph.Rectangle.Right, &glyph.Rectangle.Bottom); - - // Apply the global scale to the horizontal advance - glyph.Advance = static_cast(glyph.Advance * scale); - - // Add it to the sorted table of glyphs - glyphs.insert(std::make_pair(glyph, charset[i])); - } - - // Leave a small margin around characters, so that filtering doesn't - // pollute them with pixels from neighbours - unsigned int padding = 1; - unsigned int margin = 1; - - // Copy the rendered glyphs into the texture - unsigned int maxHeight = 0; - std::map coords; - for (GlyphTable::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i) - { - // Get the bitmap of the current glyph - Glyph& curGlyph = font.myGlyphs[i->second]; - const Glyph& bitmapGlyph = i->first; - const Vector2i& glyphSize = bitmapGlyph.Rectangle.GetSize(); - - // Make sure we don't go over the texture width - if (left + glyphSize.x + 2 * padding + margin >= texWidth) - left = 0; - - // Compute the top coordinate - top = tops[left]; - for (unsigned int x = 0; x < glyphSize.x + 2 * padding + margin; ++x) - top = std::max(top, tops[left + x]); - - // Make sure we don't go over the texture height -- resize it if we need more space - if (top + glyphSize.x + 2 * padding + margin >= texHeight) - { - texHeight *= 2; - glyphsBuffer.resize(texWidth * texHeight * 4); - } - - // Store the character's position and size - curGlyph.Rectangle.Left = bitmapGlyph.Rectangle.Left - padding; - curGlyph.Rectangle.Top = bitmapGlyph.Rectangle.Top - padding; - curGlyph.Rectangle.Right = bitmapGlyph.Rectangle.Right + padding; - curGlyph.Rectangle.Bottom = bitmapGlyph.Rectangle.Bottom + padding; - curGlyph.Advance = bitmapGlyph.Advance; - - // Texture size may change, so let the texture coordinates be calculated later - coords[i->second] = IntRect(left, top, left + glyphSize.x + 2 * padding, top + glyphSize.y + 2 * padding); - - // Draw the glyph into our bitmap font - int width, height; - unsigned char* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, i->second, &width, &height, NULL, NULL); - unsigned char* pixels = bitmap; - for (int y = 0; y < height; ++y) - { - for (int x = 0; x < width; ++x) - { - std::size_t index = x + left + padding + (y + top + padding) * texWidth; - glyphsBuffer[index * 4 + 0] = 255; - glyphsBuffer[index * 4 + 1] = 255; - glyphsBuffer[index * 4 + 2] = 255; - glyphsBuffer[index * 4 + 3] = pixels[x]; - } - pixels += width; - } - - // Update the rendering coordinates - for (unsigned int x = 0; x < width + 2 * padding + margin; ++x) - tops[left + x] = top + height + 2 * padding + margin; - left += width + 2 * padding + margin; - if (top + height + 2 * padding > maxHeight) - maxHeight = top + height + 2 * padding; - - // Delete the bitmap - stbtt_FreeBitmap(bitmap, NULL); - } - - // Create the font's texture - texHeight = maxHeight; - glyphsBuffer.resize(texWidth * texHeight * 4); - 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.GetSize(); ++i) - { - Uint32 curChar = charset[i]; - font.myGlyphs[curChar].TexCoords = font.myTexture.GetTexCoords(coords[curChar]); - } - - // Update the character size (it may have been changed by the function) - font.myCharSize = charSize; - - return 0; -} - - -//////////////////////////////////////////////////////////// -/// Create a bitmap font from a font face and a characters set -//////////////////////////////////////////////////////////// -FT_Error FontLoader::CreateBitmapFont(FT_Face face, unsigned int charSize, const String& charset, Font& font) -{ - return 0; -} - - -//////////////////////////////////////////////////////////// -/// Get a description from a FT error code -//////////////////////////////////////////////////////////// -std::string FontLoader::GetErrorDesc(FT_Error error) -{ - return ""; -} - -} // namespace priv - -} // namespace sf - -#endif diff --git a/src/SFML/Graphics/FontLoader.hpp b/src/SFML/Graphics/FontLoader.hpp deleted file mode 100644 index f3dad3bf..00000000 --- a/src/SFML/Graphics/FontLoader.hpp +++ /dev/null @@ -1,132 +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_FONTLOADER_HPP -#define SFML_FONTLOADER_HPP - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include -#include FT_FREETYPE_H -#include - - -namespace sf -{ -class Font; - -namespace priv -{ -//////////////////////////////////////////////////////////// -/// FontLoader loads and saves character fonts -//////////////////////////////////////////////////////////// -class FontLoader : NonCopyable -{ -public : - - //////////////////////////////////////////////////////////// - /// Get the unique instance of the class - /// - /// \return Reference to the FontLoader instance - /// - //////////////////////////////////////////////////////////// - static FontLoader& GetInstance(); - - //////////////////////////////////////////////////////////// - /// Load a font from a file - /// - /// \param filename : Path of the font file to load - /// \param charSize : Size of characters in bitmap - the bigger, the higher quality - /// \param charset : Characters set to generate - /// \param font : Font object to fill up - /// - /// \return True if loading was successful - /// - //////////////////////////////////////////////////////////// - bool LoadFontFromFile(const std::string& filename, unsigned int charSize, const String& charset, Font& font); - - //////////////////////////////////////////////////////////// - /// Load the font from a file in memory - /// - /// \param data : Pointer to the data to load - /// \param sizeInBytes : Size of the data, in bytes - /// \param charSize : Size of characters in bitmap - the bigger, the higher quality - /// \param charset : Characters set to generate - /// \param font : Font object to fill up - /// - /// \return True if loading was successful - /// - //////////////////////////////////////////////////////////// - bool LoadFontFromMemory(const char* data, std::size_t sizeInBytes, unsigned int charSize, const String& charset, Font& font); - -private : - - //////////////////////////////////////////////////////////// - /// Default constructor - /// - //////////////////////////////////////////////////////////// - FontLoader(); - - //////////////////////////////////////////////////////////// - /// Destructor - /// - //////////////////////////////////////////////////////////// - ~FontLoader(); - - //////////////////////////////////////////////////////////// - /// Create a bitmap font from a font face and a characters set - /// - /// \param face : Font face containing the loaded font - /// \param charSize : Size of characters in bitmap - /// \param charset : Characters set to generate - /// \param font : Font object to fill up - /// - //////////////////////////////////////////////////////////// - FT_Error CreateBitmapFont(FT_Face face, unsigned int charSize, const String& charset, Font& font); - - //////////////////////////////////////////////////////////// - /// Get a description from a FT error code - /// - /// \param error : FreeType error code - /// - /// \return Error description - /// - //////////////////////////////////////////////////////////// - static std::string GetErrorDesc(FT_Error error); - - //////////////////////////////////////////////////////////// - // Member data - //////////////////////////////////////////////////////////// - FT_Library myLibrary; ///< Handle to the Freetype library -}; - -} // namespace priv - -} // namespace sf - - -#endif // SFML_FONTLOADER_HPP diff --git a/src/SFML/Graphics/RenderWindow.cpp b/src/SFML/Graphics/RenderWindow.cpp index 10e645c6..6e5bd3c0 100644 --- a/src/SFML/Graphics/RenderWindow.cpp +++ b/src/SFML/Graphics/RenderWindow.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include diff --git a/src/SFML/Graphics/Text.cpp b/src/SFML/Graphics/Text.cpp index 567b5bdd..a17626e3 100644 --- a/src/SFML/Graphics/Text.cpp +++ b/src/SFML/Graphics/Text.cpp @@ -37,7 +37,7 @@ namespace sf //////////////////////////////////////////////////////////// Text::Text() : myFont (&Font::GetDefaultFont()), -mySize (30.f), +myCharacterSize (30), myStyle (Regular), myNeedRectUpdate(true) { @@ -48,9 +48,9 @@ myNeedRectUpdate(true) //////////////////////////////////////////////////////////// /// Construct the string from any kind of text //////////////////////////////////////////////////////////// -Text::Text(const String& string, const Font& font, float size) : +Text::Text(const String& string, const Font& font, unsigned int characterSize) : myFont (&font), -mySize (size), +myCharacterSize (characterSize), myStyle (Regular), myNeedRectUpdate(true) { @@ -82,14 +82,14 @@ void Text::SetFont(const Font& font) //////////////////////////////////////////////////////////// -/// Set the size of the string +/// Set the base size for the characters. //////////////////////////////////////////////////////////// -void Text::SetSize(float size) +void Text::SetCharacterSize(unsigned int size) { - if (mySize != size) + if (myCharacterSize != size) { myNeedRectUpdate = true; - mySize = size; + myCharacterSize = size; } } @@ -127,11 +127,11 @@ const Font& Text::GetFont() const //////////////////////////////////////////////////////////// -/// Get the size of the characters +/// Get the base size of characters //////////////////////////////////////////////////////////// -float Text::GetSize() const +unsigned int Text::GetCharacterSize() const { - return mySize; + return myCharacterSize; } @@ -149,36 +149,42 @@ unsigned long Text::GetStyle() const /// in coordinates relative to the string /// (note : translation, center, rotation and scale are not applied) //////////////////////////////////////////////////////////// -sf::Vector2f Text::GetCharacterPos(std::size_t index) const +Vector2f Text::GetCharacterPos(std::size_t index) const { + // Make sure that we have a valid font + if (!myFont) + return Vector2f(0, 0); + // Adjust the index if it's out of range if (index > myString.GetSize()) index = myString.GetSize(); - // The final size is based on the text size - float factor = mySize / myFont->GetCharacterSize(); - float advanceY = mySize; + // We'll need this a lot + float space = static_cast(myFont->GetGlyph(L' ', myCharacterSize).Advance); // Compute the position sf::Vector2f position; + Uint32 prevChar = 0; + float lineSpacing = static_cast(myFont->GetLineSpacing(myCharacterSize)); for (std::size_t i = 0; i < index; ++i) { - // Get the current character and its corresponding glyph - Uint32 curChar = myString[i]; - const Glyph& curGlyph = myFont->GetGlyph(curChar); - float advanceX = curGlyph.Advance * factor; + Uint32 curChar = myString[i]; + // Apply the kerning offset + position.x += static_cast(myFont->GetKerning(prevChar, curChar, myCharacterSize)); + prevChar = curChar; + + // Handle special characters switch (curChar) { - // Handle special characters - case L' ' : position.x += advanceX; break; - case L'\t' : position.x += advanceX * 4; break; - case L'\v' : position.y += advanceY * 4; break; - case L'\n' : position.y += advanceY; position.x = 0; break; - - // Regular character : just add its advance value - default : position.x += advanceX; break; + case L' ' : position.x += space; continue; + case L'\t' : position.x += space * 4; continue; + case L'\v' : position.y += lineSpacing * 4; continue; + case L'\n' : position.y += lineSpacing; position.x = 0; continue; } + + // For regular characters, add the advance offset of the glyph + position.x += static_cast(myFont->GetGlyph(curChar, myCharacterSize).Advance); } return position; @@ -204,24 +210,22 @@ FloatRect Text::GetRect() const //////////////////////////////////////////////////////////// -/// /see sfDrawable::Render +/// /see Drawable::Render //////////////////////////////////////////////////////////// void Text::Render(RenderTarget&, RenderQueue& queue) const { - // No text, no rendering :) - if (myString.IsEmpty()) + // No text or not font: nothing to render + if (!myFont || myString.IsEmpty()) return; - // Set the scaling factor to get the actual size - float charSize = static_cast(myFont->GetCharacterSize()); - float factor = mySize / charSize; - // Bind the font texture - queue.SetTexture(&myFont->GetImage()); + queue.SetTexture(&myFont->GetImage(myCharacterSize)); // Initialize the rendering coordinates + float space = static_cast(myFont->GetGlyph(L' ', myCharacterSize).Advance); + float lineSpacing = static_cast(myFont->GetLineSpacing(myCharacterSize)); float x = 0.f; - float y = charSize; + float y = static_cast(myCharacterSize); // Holds the lines to draw later, for underlined style std::vector underlineCoords; @@ -232,15 +236,15 @@ void Text::Render(RenderTarget&, RenderQueue& queue) const // Draw one quad for each character unsigned int index = 0; + Uint32 prevChar = 0; queue.BeginBatch(); for (std::size_t i = 0; i < myString.GetSize(); ++i) { - // Get the current character and its corresponding glyph - Uint32 curChar = myString[i]; - const Glyph& curGlyph = myFont->GetGlyph(curChar); - int advance = curGlyph.Advance; - const IntRect& rect = curGlyph.Rectangle; - const FloatRect& coord = curGlyph.TexCoords; + Uint32 curChar = myString[i]; + + // Apply the kerning offset + x += static_cast(myFont->GetKerning(prevChar, curChar, myCharacterSize)); + prevChar = curChar; // If we're using the underlined style and there's a new line, // we keep track of the previous line to draw it later @@ -253,17 +257,23 @@ void Text::Render(RenderTarget&, RenderQueue& queue) const // Handle special characters switch (curChar) { - case L' ' : x += advance; continue; - case L'\n' : y += charSize; x = 0; continue; - case L'\t' : x += advance * 4; continue; - case L'\v' : y += charSize * 4; continue; + case L' ' : x += space; continue; + case L'\t' : x += space * 4; continue; + case L'\n' : y += lineSpacing; x = 0; continue; + case L'\v' : y += lineSpacing * 4; continue; } + // Extract the current glyph's description + const Glyph& curGlyph = myFont->GetGlyph(curChar, myCharacterSize); + int advance = curGlyph.Advance; + const IntRect& rect = curGlyph.Rectangle; + const FloatRect& coord = curGlyph.TexCoords; + // Draw a textured quad for the current character - queue.AddVertex(factor * (x + rect.Left - italicCoeff * rect.Top), factor * (y + rect.Top), coord.Left, coord.Top); - queue.AddVertex(factor * (x + rect.Left - italicCoeff * rect.Bottom), factor * (y + rect.Bottom), coord.Left, coord.Bottom); - queue.AddVertex(factor * (x + rect.Right - italicCoeff * rect.Bottom), factor * (y + rect.Bottom), coord.Right, coord.Bottom); - queue.AddVertex(factor * (x + rect.Right - italicCoeff * rect.Top), factor * (y + rect.Top), coord.Right, coord.Top); + queue.AddVertex(x + rect.Left - italicCoeff * rect.Top, y + rect.Top, coord.Left, coord.Top); + queue.AddVertex(x + rect.Left - italicCoeff * rect.Bottom, y + rect.Bottom, coord.Left, coord.Bottom); + queue.AddVertex(x + rect.Right - italicCoeff * rect.Bottom, y + rect.Bottom, coord.Right, coord.Bottom); + queue.AddVertex(x + rect.Right - italicCoeff * rect.Top, y + rect.Top, coord.Right, coord.Top); queue.AddTriangle(index + 0, index + 1, index + 3); queue.AddTriangle(index + 3, index + 1, index + 2); @@ -277,7 +287,7 @@ void Text::Render(RenderTarget&, RenderQueue& queue) const // slightly offseted, to simulate a higher weight if (myStyle & Bold) { - float offset = mySize * 0.02f; + float offset = myCharacterSize * 0.02f; static const float offsetsX[] = {-offset, offset, 0.f, 0.f}; static const float offsetsY[] = {0.f, 0.f, -offset, offset}; @@ -285,32 +295,38 @@ void Text::Render(RenderTarget&, RenderQueue& queue) const { index = 0; x = 0.f; - y = charSize; + y = static_cast(myCharacterSize); + Uint32 prevChar = 0; queue.BeginBatch(); for (std::size_t i = 0; i < myString.GetSize(); ++i) { - // Get the current character and its corresponding glyph - Uint32 curChar = myString[i]; - const Glyph& curGlyph = myFont->GetGlyph(curChar); - int advance = curGlyph.Advance; - const IntRect& rect = curGlyph.Rectangle; - const FloatRect& coord = curGlyph.TexCoords; + Uint32 curChar = myString[i]; + + // Apply the kerning offset + x += static_cast(myFont->GetKerning(prevChar, curChar, myCharacterSize)); + prevChar = curChar; // Handle special characters switch (curChar) { - case L' ' : x += advance; continue; - case L'\n' : y += charSize; x = 0; continue; - case L'\t' : x += advance * 4; continue; - case L'\v' : y += charSize * 4; continue; + case L' ' : x += space; continue; + case L'\t' : x += space * 4; continue; + case L'\n' : y += lineSpacing; x = 0; continue; + case L'\v' : y += lineSpacing * 4; continue; } + // Extract the current glyph's description + const Glyph& curGlyph = myFont->GetGlyph(curChar, myCharacterSize); + int advance = curGlyph.Advance; + const IntRect& rect = curGlyph.Rectangle; + const FloatRect& coord = curGlyph.TexCoords; + // Draw a textured quad for the current character - queue.AddVertex(factor * (x + offsetsX[j] + rect.Left - italicCoeff * rect.Top), factor * (y + offsetsY[j] + rect.Top), coord.Left, coord.Top); - queue.AddVertex(factor * (x + offsetsX[j] + rect.Left - italicCoeff * rect.Bottom), factor * (y + offsetsY[j] + rect.Bottom), coord.Left, coord.Bottom); - queue.AddVertex(factor * (x + offsetsX[j] + rect.Right - italicCoeff * rect.Bottom), factor * (y + offsetsY[j] + rect.Bottom), coord.Right, coord.Bottom); - queue.AddVertex(factor * (x + offsetsX[j] + rect.Right - italicCoeff * rect.Top), factor * (y + offsetsY[j] + rect.Top), coord.Right, coord.Top); + queue.AddVertex(x + offsetsX[j] + rect.Left - italicCoeff * rect.Top, y + offsetsY[j] + rect.Top, coord.Left, coord.Top); + queue.AddVertex(x + offsetsX[j] + rect.Left - italicCoeff * rect.Bottom, y + offsetsY[j] + rect.Bottom, coord.Left, coord.Bottom); + queue.AddVertex(x + offsetsX[j] + rect.Right - italicCoeff * rect.Bottom, y + offsetsY[j] + rect.Bottom, coord.Right, coord.Bottom); + queue.AddVertex(x + offsetsX[j] + rect.Right - italicCoeff * rect.Top, y + offsetsY[j] + rect.Top, coord.Right, coord.Top); queue.AddTriangle(index + 0, index + 1, index + 3); queue.AddTriangle(index + 3, index + 1, index + 2); @@ -338,10 +354,10 @@ void Text::Render(RenderTarget&, RenderQueue& queue) const queue.BeginBatch(); for (std::size_t i = 0; i < underlineCoords.size(); i += 2) { - queue.AddVertex(factor * (0), factor * (underlineCoords[i + 1])); - queue.AddVertex(factor * (0), factor * (underlineCoords[i + 1] + thickness)); - queue.AddVertex(factor * (underlineCoords[i]), factor * (underlineCoords[i + 1] + thickness)); - queue.AddVertex(factor * (underlineCoords[i]), factor * (underlineCoords[i + 1])); + queue.AddVertex(0, underlineCoords[i + 1]); + queue.AddVertex(0, underlineCoords[i + 1] + thickness); + queue.AddVertex(underlineCoords[i], underlineCoords[i + 1] + thickness); + queue.AddVertex(underlineCoords[i], underlineCoords[i + 1]); queue.AddTriangle(index + 0, index + 1, index + 3); queue.AddTriangle(index + 3, index + 1, index + 2); @@ -356,41 +372,51 @@ void Text::Render(RenderTarget&, RenderQueue& queue) const //////////////////////////////////////////////////////////// void Text::RecomputeRect() { - // Reset the "need update" state + // Reset the previous states myNeedRectUpdate = false; + myBaseRect = FloatRect(0, 0, 0, 0); - // No text, empty box :) - if (myString.IsEmpty()) - { - myBaseRect = FloatRect(0, 0, 0, 0); + // No text or not font: empty box + if (!myFont || myString.IsEmpty()) return; - } // Initial values - float curWidth = 0; - float curHeight = 0; - float width = 0; - float height = 0; - float factor = mySize / myFont->GetCharacterSize(); + float charSize = static_cast(myCharacterSize); + float space = static_cast(myFont->GetGlyph(L' ', myCharacterSize).Advance); + float lineSpacing = static_cast(myFont->GetLineSpacing(myCharacterSize)); + float curWidth = 0; + float curHeight = 0; + float width = 0; + float height = 0; + Uint32 prevChar = 0; // Go through each character for (std::size_t i = 0; i < myString.GetSize(); ++i) { - // Get the current character and its corresponding glyph - Uint32 curChar = myString[i]; - const Glyph& curGlyph = myFont->GetGlyph(curChar); - float advance = curGlyph.Advance * factor; - const IntRect& rect = curGlyph.Rectangle; + Uint32 curChar = myString[i]; + + // Apply the kerning offset + curWidth += static_cast(myFont->GetKerning(prevChar, curChar, myCharacterSize)); + prevChar = curChar; // Handle special characters switch (curChar) { - case L' ' : curWidth += advance; continue; - case L'\t' : curWidth += advance * 4; continue; - case L'\v' : height += mySize * 4; curHeight = 0; continue; + case L' ' : + curWidth += space; + continue; + + case L'\t' : + curWidth += space * 4; + continue; + + case L'\v' : + height += lineSpacing * 4; + curHeight = 0; + continue; case L'\n' : - height += mySize; + height += lineSpacing; curHeight = 0; if (curWidth > width) width = curWidth; @@ -398,11 +424,14 @@ void Text::RecomputeRect() continue; } + // Extract the current glyph's description + const Glyph& curGlyph = myFont->GetGlyph(curChar, myCharacterSize); + // Advance to the next character - curWidth += advance; + curWidth += static_cast(curGlyph.Advance); // Update the maximum height - float charHeight = (myFont->GetCharacterSize() + rect.Bottom) * factor; + float charHeight = charSize + curGlyph.Rectangle.Bottom; if (charHeight > curHeight) curHeight = charHeight; } @@ -415,21 +444,21 @@ void Text::RecomputeRect() // Add a slight width / height if we're using the bold style if (myStyle & Bold) { - width += 1 * factor; - height += 1 * factor; + width += 1.f; + height += 1.f; } // Add a slight width if we're using the italic style if (myStyle & Italic) { - width += 0.208f * mySize; + width += 0.208f * charSize; } // Add a slight height if we're using the underlined style if (myStyle & Underlined) { - if (curHeight < mySize + 4 * factor) - height += 4 * factor; + if (curHeight < charSize + 4.f) + height += 4.f; } // Finally update the rectangle diff --git a/src/SFML/Graphics/stb_truetype/stb_truetype.h b/src/SFML/Graphics/stb_truetype/stb_truetype.h deleted file mode 100644 index f9e7fe56..00000000 --- a/src/SFML/Graphics/stb_truetype/stb_truetype.h +++ /dev/null @@ -1,1807 +0,0 @@ -// stb_truetype.h - v0.3 - public domain - 2009 Sean Barrett / RAD Game Tools -// -// This library processes TrueType files: -// parse files -// extract glyph metrics -// extract glyph shapes -// render glyphs to one-channel bitmaps with antialiasing (box filter) -// -// Todo: -// non-MS cmaps -// crashproof on bad data -// hinting -// subpixel positioning when rendering bitmap -// cleartype-style AA -// -// ADDITIONAL CONTRIBUTORS -// -// Mikko Mononen: compound shape support, more cmap formats -// -// VERSIONS -// -// 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM) -// userdata, malloc-from-userdata, non-zero fill (STB) -// 0.2 (2009-03-11) Fix unsigned/signed char warnings -// 0.1 (2009-03-09) First public release -// -// USAGE -// -// Include this file in whatever places neeed to refer to it. In ONE C/C++ -// file, write: -// #define STB_TRUETYPE_IMPLEMENTATION -// before the #include of this file. This expands out the actual -// implementation into that C/C++ file. -// -// Look at the header-file sections below for the API, but here's a quick skim: -// -// Simple 3D API (don't ship this, but it's fine for tools and quick start, -// and you can cut and paste from it to move to more advanced) -// stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture -// stbtt_GetBakedQuad() -- compute quad to draw for a given char -// -// "Load" a font file from a memory buffer (you have to keep the buffer loaded) -// stbtt_InitFont() -// stbtt_GetFontOffsetForIndex() -- use for TTC font collections -// -// Render a unicode codepoint to a bitmap -// stbtt_GetCodepointBitmap() -- allocates and returns a bitmap -// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide -// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be -// -// Character advance/positioning -// stbtt_GetCodepointHMetrics() -// stbtt_GetFontVMetrics() -// -// NOTES -// -// The system uses the raw data found in the .ttf file without changing it -// and without building auxiliary data structures. This is a bit inefficient -// on little-endian systems (the data is big-endian), but assuming you're -// caching the bitmaps or glyph shapes this shouldn't be a big deal. -// -// It appears to be very hard to programmatically determine what font a -// given file is in a general way. I provide an API for this, but I don't -// recommend it. -// -// -// SOURCE STATISTICS (based on v0.3, 1800 LOC) -// -// Documentation & header file 350 LOC \___ 500 LOC documentation -// Sample code 140 LOC / -// Truetype parsing 580 LOC ---- 600 LOC TrueType -// Software rasterization 240 LOC \ . -// Curve tesselation 120 LOC \__ 500 LOC Bitmap creation -// Bitmap management 70 LOC / -// Baked bitmap interface 70 LOC / -// Font name matching & access 150 LOC ---- 150 -// C runtime library abstraction 60 LOC ---- 60 - - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -//// -//// SAMPLE PROGRAMS -//// -// -// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless -// -#if 0 -#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation -#include "stb_truetype.h" - -char ttf_buffer[1<<20]; -unsigned char temp_bitmap[512*512]; - -stbtt_chardata cdata[96]; // ASCII 32..126 is 95 glyphs -GLstbtt_uint ftex; - -void my_stbtt_initfont(void) -{ - fread(ttf_buffer, 1, 1<<20, fopen("c:/windows/fonts/times.ttf", "rb")); - stbtt_BakeFontBitmap(data,0, 32.0, temp_bitmap,512,512, 32,96, cdata); // no guarantee this fits! - // can free ttf_buffer at this point - glGenTextures(1, &ftex); - glBindTexture(GL_TEXTURE_2D, ftex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap); - // can free temp_bitmap at this point - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -} - -void my_stbtt_print(float x, float y, char *text) -{ - // assume orthographic projection with units = screen pixels, origin at top left - glBindTexture(GL_TEXTURE_2D, ftex); - glBegin(GL_QUADS); - while (*text) { - if (*text >= 32 && *text < 128) { - stbtt_aligned_quad q; - stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl,0=old d3d - glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0); - glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0); - glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1); - glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1); - } - ++text; - } - glEnd(); -} -#endif -// -// -////////////////////////////////////////////////////////////////////////////// -// -// Complete program (this compiles): get a single bitmap, print as ASCII art -// -#if 0 -#include -#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation -#include "stb_truetype.h" - -char ttf_buffer[1<<25]; - -int main(int argc, char **argv) -{ - stbtt_fontinfo font; - unsigned char *bitmap; - int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20); - - fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb")); - - stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0)); - bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0); - - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) - putchar(" .:ioVM@"[bitmap[j*w+i]>>5]); - putchar('\n'); - } - return 0; -} -#endif -// -// Output: -// -// .ii. -// @@@@@@. -// V@Mio@@o -// :i. V@V -// :oM@@M -// :@@@MM@M -// @@o o@M -// :@@. M@M -// @@@o@@@@ -// :M@@V:@@. -// -////////////////////////////////////////////////////////////////////////////// -// -// Complete program: print "Hello World!" banner, with bugs -// -#if 0 -int main(int arg, char **argv) -{ - unsigned char screen[20][79]; - int i,j, pos=0; - float scale; - char *text = "Heljo World!"; - - fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb")); - stbtt_InitFont(&font, buffer, 0); - - scale = stbtt_ScaleForPixelHeight(&font, 16); - memset(screen, 0, sizeof(screen)); - - while (*text) { - int advance,lsb,x0,y0,x1,y1, newpos, baseline=13; - stbtt_GetCodepointHMetrics(&font, *text, &advance, &lsb); - stbtt_GetCodepointBitmapBox(&font, *text, scale,scale, &x0,&y0,&x1,&y1); - newpos = pos + (int) (lsb * scale) + x0; - stbtt_MakeCodepointBitmap(&font, &screen[baseline + y0][newpos], x1-x0,y1-y0, 79, scale,scale, *text); - // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong - // because this API is really for baking character bitmaps into textures - pos += (int) (advance * scale); - ++text; - } - - for (j=0; j < 20; ++j) { - for (i=0; i < 79; ++i) - putchar(" .:ioVM@"[screen[j][i]>>5]); - putchar('\n'); - } - - return 0; -} -#endif - - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -//// -//// INTEGRATION WITH RUNTIME LIBRARIES -//// - -#ifdef STB_TRUETYPE_IMPLEMENTATION - // #define your own (u)stbtt_int8/16/32 before including to override this - #ifndef stbtt_uint8 - typedef unsigned char stbtt_uint8; - typedef signed char stbtt_int8; - typedef unsigned short stbtt_uint16; - typedef signed short stbtt_int16; - typedef unsigned int stbtt_uint32; - typedef signed int stbtt_int32; - #endif - - typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1]; - typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1]; - - // #define your own STBTT_sort() to override this to avoid qsort - #ifndef STBTT_sort - #include - #define STBTT_sort(data,num_items,item_size,compare_func) qsort(data,num_items,item_size,compare_func) - #endif - - // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h - #ifndef STBTT_ifloor - #include - #define STBTT_ifloor(x) ((int) floor(x)) - #define STBTT_iceil(x) ((int) ceil(x)) - #endif - - // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h - #ifndef STBTT_malloc - #include - #define STBTT_malloc(x,u) malloc(x) - #define STBTT_free(x,u) free(x) - #endif - - #ifndef STBTT_assert - #include - #define STBTT_assert(x) assert(x) - #endif - - #ifndef STBTT_strlen - #include - #define STBTT_strlen(x) strlen(x) - #endif - - #ifndef STBTT_memcpy - #include - #define STBTT_memcpy memcpy - #define STBTT_memset memset - #endif -#endif - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -//// -//// INTERFACE -//// -//// - -#ifndef __STB_INCLUDE_STB_TRUETYPE_H__ -#define __STB_INCLUDE_STB_TRUETYPE_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// TEXTURE BAKING API -// -// If you use this API, you only have to call two functions ever. -// - -typedef struct -{ - unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap - float xoff,yoff,xadvance; -} stbtt_bakedchar; - -extern int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) - float pixel_height, // height of font in pixels - unsigned char *pixels, int pw, int ph, // bitmap to be filled in - int first_char, int num_chars, // characters to bake - stbtt_bakedchar *chardata); // you allocate this, it's num_chars long -// if return is positive, the first unused row of the bitmap -// if return is negative, returns the negative of the number of characters that fit -// if return is 0, no characters fit and no rows were used -// This uses a very crappy packing. - -typedef struct -{ - float x0,y0,s0,t0; // top-left - float x1,y1,s1,t1; // bottom-right -} stbtt_aligned_quad; - -extern void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above - int char_index, // character to display - float *xpos, float *ypos, // pointers to current position in screen pixel space - stbtt_aligned_quad *q, // output: quad to draw - int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier -// Call GetBakedQuad with char_index = 'character - first_char', and it -// creates the quad you need to draw and advances the current position. -// It's inefficient; you might want to c&p it and optimize it. - - -////////////////////////////////////////////////////////////////////////////// -// -// FONT LOADING -// -// - -extern int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); -// Each .ttf file may have more than one font. Each has a sequential index -// number starting from 0. Call this function to get the font offset for a -// given index; it returns -1 if the index is out of range. A regular .ttf -// file will only define one font and it always be at offset 0, so it will -// return '0' for index 0, and -1 for all other indices. You can just skip -// this step if you know it's that kind of font. - - -// The following structure is defined publically so you can declare one on -// the stack or as a global or etc. -typedef struct -{ - void *userdata; - unsigned char *data; // pointer to .ttf file - int fontstart; // offset of start of font - - int numGlyphs; // number of glyphs, needed for range checking - - int loca,head,glyf,hhea,hmtx; // table locations as offset from start of .ttf - int index_map; // a cmap mapping for our chosen character encoding - int indexToLocFormat; // format needed to map from glyph index to glyph -} stbtt_fontinfo; - -extern int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); -// Given an offset into the file that defines a font, this function builds -// the necessary cached info for the rest of the system. You must allocate -// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't -// need to do anything special to free it, because the contents are a pure -// cache with no additional data structures. Returns 0 on failure. - - -////////////////////////////////////////////////////////////////////////////// -// -// CHARACTER TO GLYPH-INDEX CONVERSIOn - -int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); -// If you're going to perform multiple operations on the same character -// and you want a speed-up, call this function with the character you're -// going to process, then use glyph-based functions instead of the -// codepoint-based functions. - - -////////////////////////////////////////////////////////////////////////////// -// -// CHARACTER PROPERTIES -// - -extern float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); -// computes a scale factor to produce a font whose "height" is 'pixels' tall. -// Height is measured as the distance from the highest ascender to the lowest -// descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics -// and computing: -// scale = pixels / (ascent - descent) -// so if you prefer to measure height by the ascent only, use a similar calculation. - -extern void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); -// ascent is the coordinate above the baseline the font extends; descent -// is the coordinate below the baseline the font extends (i.e. it is typically negative) -// lineGap is the spacing between one row's descent and the next row's ascent... -// so you should advance the vertical position by "*ascent - *descent + *lineGap" -// these are expressed in unscaled coordinates - -extern void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); -// leftSideBearing is the offset from the current horizontal position to the left edge of the character -// advanceWidth is the offset from the current horizontal position to the next horizontal position -// these are expressed in unscaled coordinates - -extern int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); -// an additional amount to add to the 'advance' value between ch1 and ch2 -// @TODO; for now always returns 0! - -extern int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); -// Gets the bounding box of the visible part of the glyph, in unscaled coordinates - -extern void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); -extern int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); -extern int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); -// as above, but takes one or more glyph indices for greater efficiency - - -////////////////////////////////////////////////////////////////////////////// -// -// GLYPH SHAPES (you probably don't need these, but they have to go before -// the bitmaps for C declaration-order reasons) -// - -#ifndef STBTT_vmove // you can predefine these to use different values (but why?) - enum { - STBTT_vmove=1, - STBTT_vline, - STBTT_vcurve - }; -#endif - -#ifndef stbtt_vertex // you can predefine this to use different values - // (we share this with other code at RAD) - #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file - typedef struct - { - stbtt_vertex_type x,y,cx,cy; - unsigned char type,padding; - } stbtt_vertex; -#endif - -extern int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); -extern int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); -// returns # of vertices and fills *vertices with the pointer to them -// these are expressed in "unscaled" coordinates - -extern void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); -// frees the data allocated above - -////////////////////////////////////////////////////////////////////////////// -// -// BITMAP RENDERING -// - -extern void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); -// frees the bitmap allocated below - -extern unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); -// allocates a large-enough single-channel 8bpp bitmap and renders the -// specified character/glyph at the specified scale into it, with -// antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). -// *width & *height are filled out with the width & height of the bitmap, -// which is stored left-to-right, top-to-bottom. -// -// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap - -extern void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); -// the same as above, but you pass in storage for the bitmap in the form -// of 'output', with row spacing of 'out_stride' bytes. the bitmap is -// clipped to out_w/out_h bytes. call the next function to get the -// height and width and positioning info - -extern void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); -// get the bbox of the bitmap centered around the glyph origin; so the -// bitmap width is ix1-ix0, height is iy1-iy0, and location to place -// the bitmap top left is (leftSideBearing*scale,iy0). -// (Note that the bitmap uses y-increases-down, but the shape uses -// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) - -extern unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); -extern void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); -extern void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); - -//extern void stbtt_get_true_bbox(stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); - -// @TODO: don't expose this structure -typedef struct -{ - int w,h,stride; - unsigned char *pixels; -} stbtt__bitmap; - -extern void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, int x_off, int y_off, int invert, void *userdata); - -////////////////////////////////////////////////////////////////////////////// -// -// Finding the right font... -// -// You should really just solve this offline, keep your own tables -// of what font is what, and don't try to get it out of the .ttf file. -// That's because getting it out of the .ttf file is really hard, because -// the names in the file can appear in many possible encodings, in many -// possible languages, and e.g. if you need a case-insensitive comparison, -// the details of that depend on the encoding & language in a complex way -// (actually underspecified in truetype, but also gigantic). -// -// But you can use the provided functions in two possible ways: -// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on -// unicode-encoded names to try to find the font you want; -// you can run this before calling stbtt_InitFont() -// -// stbtt_GetFontNameString() lets you get any of the various strings -// from the file yourself and do your own comparisons on them. -// You have to have called stbtt_InitFont() first. - - -extern int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); -// returns the offset (not index) of the font that matches, or -1 if none -// if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold". -// if you use any other flag, use a font name like "Arial"; this checks -// the 'macStyle' header field; i don't know if fonts set this consistently -#define STBTT_MACSTYLE_DONTCARE 0 -#define STBTT_MACSTYLE_BOLD 1 -#define STBTT_MACSTYLE_ITALIC 2 -#define STBTT_MACSTYLE_UNDERSCORE 4 -#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 - -extern int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); -// returns 1/0 whether the first string interpreted as utf8 is identical to -// the second string interpreted as big-endian utf16... useful for strings from next func - -extern char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); -// returns the string (which may be big-endian double byte, e.g. for unicode) -// and puts the length in bytes in *length. -// -// some of the values for the IDs are below; for more see the truetype spec: -// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html -// http://www.microsoft.com/typography/otspec/name.htm - -enum { // platformID - STBTT_PLATFORM_ID_UNICODE =0, - STBTT_PLATFORM_ID_MAC =1, - STBTT_PLATFORM_ID_ISO =2, - STBTT_PLATFORM_ID_MICROSOFT =3 -}; - -enum { // encodingID for STBTT_PLATFORM_ID_UNICODE - STBTT_UNICODE_EID_UNICODE_1_0 =0, - STBTT_UNICODE_EID_UNICODE_1_1 =1, - STBTT_UNICODE_EID_ISO_10646 =2, - STBTT_UNICODE_EID_UNICODE_2_0_BMP=3, - STBTT_UNICODE_EID_UNICODE_2_0_FULL=4, -}; - -enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT - STBTT_MS_EID_SYMBOL =0, - STBTT_MS_EID_UNICODE_BMP =1, - STBTT_MS_EID_SHIFTJIS =2, - STBTT_MS_EID_UNICODE_FULL =10, -}; - -enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes - STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4, - STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5, - STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6, - STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7, -}; - -enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... - // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs - STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410, - STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411, - STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412, - STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419, - STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409, - STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D, -}; - -enum { // languageID for STBTT_PLATFORM_ID_MAC - STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11, - STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23, - STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32, - STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 , - STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 , - STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33, - STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19, -}; - -#ifdef __cplusplus -} -#endif - -#endif // __STB_INCLUDE_STB_TRUETYPE_H__ - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -//// -//// IMPLEMENTATION -//// -//// - -#ifdef STB_TRUETYPE_IMPLEMENTATION - -////////////////////////////////////////////////////////////////////////// -// -// accessors to parse data from file -// - -// on platforms that don't allow misaligned reads, if we want to allow -// truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE - -#define ttBYTE(p) (* (stbtt_uint8 *) (p)) -#define ttCHAR(p) (* (stbtt_int8 *) (p)) -#define ttFixed(p) ttLONG(p) - -#if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE) - - #define ttUSHORT(p) (* (stbtt_uint16 *) (p)) - #define ttSHORT(p) (* (stbtt_int16 *) (p)) - #define ttULONG(p) (* (stbtt_uint32 *) (p)) - #define ttLONG(p) (* (stbtt_int32 *) (p)) - -#else - - stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } - stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } - stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } - stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } - -#endif - -#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) -#define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3]) - -static int stbtt__isfont(const stbtt_uint8 *font) -{ - // check the version number - if (stbtt_tag(font, "1")) return 1; // TrueType 1 - if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! - if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF - if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0 - return 0; -} - -// @OPTIMIZE: binary search -static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, char *tag) -{ - stbtt_int32 num_tables = ttUSHORT(data+fontstart+4); - stbtt_uint32 tabledir = fontstart + 12; - stbtt_int32 i; - for (i=0; i < num_tables; ++i) { - stbtt_uint32 loc = tabledir + 16*i; - if (stbtt_tag(data+loc+0, tag)) - return ttULONG(data+loc+8); - } - return 0; -} - -int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index) -{ - // if it's just a font, there's only one valid index - if (stbtt__isfont(font_collection)) - return index == 0 ? 0 : -1; - - // check if it's a TTC - if (stbtt_tag(font_collection, "ttcf")) { - // version 1? - if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { - stbtt_int32 n = ttLONG(font_collection+8); - if (index >= n) - return -1; - return ttULONG(font_collection+12+index*14); - } - } - return -1; -} - -int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontstart) -{ - stbtt_uint8 *data = (stbtt_uint8 *) data2; - stbtt_uint32 cmap, t; - stbtt_int32 i,numTables; - - info->data = data; - info->fontstart = fontstart; - - cmap = stbtt__find_table(data, fontstart, "cmap"); - info->loca = stbtt__find_table(data, fontstart, "loca"); - info->head = stbtt__find_table(data, fontstart, "head"); - info->glyf = stbtt__find_table(data, fontstart, "glyf"); - info->hhea = stbtt__find_table(data, fontstart, "hhea"); - info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); - if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx) - return 0; - - t = stbtt__find_table(data, fontstart, "maxp"); - if (t) - info->numGlyphs = ttUSHORT(data+t+4); - else - info->numGlyphs = 0xffff; - - // find a cmap encoding table we understand *now* to avoid searching - // later. (todo: could make this installable) - // the same regardless of glyph. - numTables = ttUSHORT(data + cmap + 2); - info->index_map = 0; - for (i=0; i < numTables; ++i) { - stbtt_uint32 encoding_record = cmap + 4 + 8 * i; - // find an encoding we understand: - switch(ttUSHORT(data+encoding_record)) { - case STBTT_PLATFORM_ID_MICROSOFT: - switch (ttUSHORT(data+encoding_record+2)) { - case STBTT_MS_EID_UNICODE_BMP: - case STBTT_MS_EID_UNICODE_FULL: - // MS/Unicode - info->index_map = cmap + ttULONG(data+encoding_record+4); - break; - } - break; - } - } - if (info->index_map == 0) - return 0; - - info->indexToLocFormat = ttUSHORT(data+info->head + 50); - return 1; -} - -int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint) -{ - stbtt_uint8 *data = info->data; - stbtt_uint32 index_map = info->index_map; - - stbtt_uint16 format = ttUSHORT(data + index_map + 0); - if (format == 0) { // apple byte encoding - stbtt_int32 bytes = ttUSHORT(data + index_map + 2); - if (unicode_codepoint < bytes-6) - return ttBYTE(data + index_map + 6 + unicode_codepoint); - return 0; - } else if (format == 6) { - stbtt_uint32 first = ttUSHORT(data + index_map + 6); - stbtt_uint32 count = ttUSHORT(data + index_map + 8); - if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count) - return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2); - return 0; - } else if (format == 2) { - STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean - return 0; - } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges - stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1; - stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1; - stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10); - stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1; - stbtt_uint16 item, offset, start, end; - - // do a binary search of the segments - stbtt_uint32 endCount = index_map + 14; - stbtt_uint32 search = endCount; - - if (unicode_codepoint > 0xffff) - return 0; - - // they lie from endCount .. endCount + segCount - // but searchRange is the nearest power of two, so... - if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2)) - search += rangeShift*2; - - // now decrement to bias correctly to find smallest - search -= 2; - while (entrySelector) { - stbtt_uint16 start, end; - searchRange >>= 1; - start = ttUSHORT(data + search + 2 + segcount*2 + 2); - end = ttUSHORT(data + search + 2); - start = ttUSHORT(data + search + searchRange*2 + segcount*2 + 2); - end = ttUSHORT(data + search + searchRange*2); - if (unicode_codepoint > end) - search += searchRange*2; - --entrySelector; - } - search += 2; - - item = (stbtt_uint16) ((search - endCount) >> 1); - - STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item)); - start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item); - end = ttUSHORT(data + index_map + 14 + 2 + 2*item); - if (unicode_codepoint < start) - return 0; - - offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item); - if (offset == 0) - return unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item); - - return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item); - } else if (format == 12) { - stbtt_uint16 ngroups = ttUSHORT(data+index_map+6); - stbtt_int32 low,high; - stbtt_uint16 g = 0; - low = 0; high = (stbtt_int32)ngroups; - // Binary search the right group. - while (low <= high) { - stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high - stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12); - stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4); - if ((stbtt_uint32) unicode_codepoint < start_char) - high = mid-1; - else if ((stbtt_uint32) unicode_codepoint > end_char) - low = mid+1; - else { - stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8); - return start_glyph + unicode_codepoint-start_char; - } - } - return 0; // not found - } - // @TODO - STBTT_assert(0); - return 0; -} - -int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices) -{ - return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); -} - -static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int16 x, stbtt_int16 y, stbtt_int16 cx, stbtt_int16 cy) -{ - v->type = type; - v->x = x; - v->y = y; - v->cx = cx; - v->cy = cy; -} - -static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) -{ - int g1,g2; - - if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range - if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format - - if (info->indexToLocFormat == 0) { - g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; - g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; - } else { - g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4); - g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4); - } - - return g1==g2 ? -1 : g1; // if length is 0, return -1 -} - -int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) -{ - int g = stbtt__GetGlyfOffset(info, glyph_index); - if (g < 0) return 0; - - if (x0) *x0 = ttSHORT(info->data + g + 2); - if (y0) *y0 = ttSHORT(info->data + g + 4); - if (x1) *x1 = ttSHORT(info->data + g + 6); - if (y1) *y1 = ttSHORT(info->data + g + 8); - return 1; -} - -int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) -{ - return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1); -} - -int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) -{ - stbtt_int16 numberOfContours; - stbtt_uint8 *endPtsOfContours; - stbtt_uint8 *data = info->data; - stbtt_vertex *vertices=0; - int num_vertices=0; - int g = stbtt__GetGlyfOffset(info, glyph_index); - - *pvertices = NULL; - - if (g < 0) return 0; - - numberOfContours = ttSHORT(data + g); - - if (numberOfContours > 0) { - stbtt_uint8 flags=0,flagcount; - stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off; - stbtt_int16 x,y,cx,cy,sx,sy; - stbtt_uint8 *points; - endPtsOfContours = (data + g + 10); - ins = ttUSHORT(data + g + 10 + numberOfContours * 2); - points = data + g + 10 + numberOfContours * 2 + 2 + ins; - - n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2); - - m = n + numberOfContours; // a loose bound on how many vertices we might need - vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata); - if (vertices == 0) - return 0; - - next_move = 0; - flagcount=0; - - // in first pass, we load uninterpreted data into the allocated array - // above, shifted to the end of the array so we won't overwrite it when - // we create our final data starting from the front - - off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated - - // first load flags - - for (i=0; i < n; ++i) { - if (flagcount == 0) { - flags = *points++; - if (flags & 8) - flagcount = *points++; - } else - --flagcount; - vertices[off+i].type = flags; - } - - // now load x coordinates - x=0; - for (i=0; i < n; ++i) { - flags = vertices[off+i].type; - if (flags & 2) { - stbtt_int16 dx = *points++; - x += (flags & 16) ? dx : -dx; // ??? - } else { - if (!(flags & 16)) { - x = x + (stbtt_int16) (points[0]*256 + points[1]); - points += 2; - } - } - vertices[off+i].x = x; - } - - // now load y coordinates - y=0; - for (i=0; i < n; ++i) { - flags = vertices[off+i].type; - if (flags & 4) { - stbtt_int16 dy = *points++; - y += (flags & 32) ? dy : -dy; // ??? - } else { - if (!(flags & 32)) { - y = y + (stbtt_int16) (points[0]*256 + points[1]); - points += 2; - } - } - vertices[off+i].y = y; - } - - // now convert them to our format - num_vertices=0; - sx = sy = cx = cy = 0; - for (i=0; i < n; ++i) { - flags = vertices[off+i].type; - x = (stbtt_int16) vertices[off+i].x; - y = (stbtt_int16) vertices[off+i].y; - if (next_move == i) { - // when we get to the end, we have to close the shape explicitly - if (i != 0) { - if (was_off) - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy); - else - stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0); - } - - // now start the new one - stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,x,y,0,0); - next_move = 1 + ttUSHORT(endPtsOfContours+j*2); - ++j; - was_off = 0; - sx = x; - sy = y; - } else { - if (!(flags & 1)) { // if it's a curve - if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy); - cx = x; - cy = y; - was_off = 1; - } else { - if (was_off) - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy); - else - stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0); - was_off = 0; - } - } - } - if (i != 0) { - if (was_off) - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy); - else - stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0); - } - } else if (numberOfContours == -1) { - // Compound shapes. - int more = 1; - stbtt_uint8 *comp = data + g + 10; - num_vertices = 0; - vertices = 0; - while (more) { - stbtt_uint16 flags, gidx; - int comp_num_verts = 0, i; - stbtt_vertex *comp_verts = 0, *tmp = 0; - float mtx[6] = {1,0,0,1,0,0}, m, n; - - flags = ttSHORT(comp); comp+=2; - gidx = ttSHORT(comp); comp+=2; - - if (flags & 2) { // XY values - if (flags & 1) { // shorts - mtx[4] = ttSHORT(comp); comp+=2; - mtx[5] = ttSHORT(comp); comp+=2; - } else { - mtx[4] = ttCHAR(comp); comp+=1; - mtx[5] = ttCHAR(comp); comp+=1; - } - } - else { - // @TODO handle matching point - STBTT_assert(0); - } - if (flags & (1<<3)) { // WE_HAVE_A_SCALE - mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = mtx[2] = 0; - } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE - mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = mtx[2] = 0; - mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; - } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO - mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[2] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; - } - - // Find transformation scales. - m = (float) sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); - n = (float) sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); - - // Get indexed glyph. - comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); - if (comp_num_verts > 0) { - // Transform vertices. - for (i = 0; i < comp_num_verts; ++i) { - stbtt_vertex* v = &comp_verts[i]; - stbtt_vertex_type x,y; - x=v->x; y=v->y; - v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); - v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); - x=v->cx; y=v->cy; - v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); - v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); - } - // Append vertices. - tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata); - if (!tmp) { - if (vertices) STBTT_free(vertices, info->userdata); - if (comp_verts) STBTT_free(comp_verts, info->userdata); - return 0; - } - if (num_vertices > 0) memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); - memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); - if (vertices) STBTT_free(vertices, info->userdata); - vertices = tmp; - STBTT_free(comp_verts, info->userdata); - num_vertices += comp_num_verts; - } - // More components ? - more = flags & (1<<5); - } - } else if (numberOfContours < 0) { - // @TODO other compound variations? - STBTT_assert(0); - } else { - // numberOfCounters == 0, do nothing - } - - *pvertices = vertices; - return num_vertices; -} - -void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) -{ - stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34); - if (glyph_index < numOfLongHorMetrics) { - if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index); - if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2); - } else { - if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1)); - if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics)); - } -} - -int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) -{ - return 0; -} - -int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) -{ - return 0; -} - -void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing) -{ - stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing); -} - -void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) -{ - if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4); - if (descent) *descent = ttSHORT(info->data+info->hhea + 6); - if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8); -} - -float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height) -{ - int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6); - return (float) height / fheight; -} - -void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) -{ - STBTT_free(v, info->userdata); -} - -////////////////////////////////////////////////////////////////////////////// -// -// antialiasing software rasterizer -// - -void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) -{ - int x0,y0,x1,y1; - if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) - x0=y0=x1=y1=0; // e.g. space character - // now move to integral bboxes (treating pixels as little squares, what pixels get touched)? - if (ix0) *ix0 = STBTT_ifloor(x0 * scale_x); - if (iy0) *iy0 = -STBTT_iceil (y1 * scale_y); - if (ix1) *ix1 = STBTT_iceil (x1 * scale_x); - if (iy1) *iy1 = -STBTT_ifloor(y0 * scale_y); -} - -void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) -{ - stbtt_GetGlyphBitmapBox(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y, ix0,iy0,ix1,iy1); -} - -typedef struct stbtt__edge { - float x0,y0, x1,y1; - int invert; -} stbtt__edge; - -typedef struct stbtt__active_edge -{ - int x,dx; - float ey; - struct stbtt__active_edge *next; - int valid; -} stbtt__active_edge; - -#define FIXSHIFT 10 -#define FIX (1 << FIXSHIFT) -#define FIXMASK (FIX-1) - -static stbtt__active_edge *new_active(stbtt__edge *e, int off_x, float start_point, void *userdata) -{ - stbtt__active_edge *z = (stbtt__active_edge *) STBTT_malloc(sizeof(*z), userdata); // @TODO: make a pool of these!!! - float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); - STBTT_assert(e->y0 <= start_point); - if (!z) return z; - // round dx down to avoid going too far - if (dxdy < 0) - z->dx = -STBTT_ifloor(FIX * -dxdy); - else - z->dx = STBTT_ifloor(FIX * dxdy); - z->x = STBTT_ifloor(FIX * (e->x0 + dxdy * (start_point - e->y0))); - z->x -= off_x * FIX; - z->ey = e->y1; - z->next = 0; - z->valid = e->invert ? 1 : -1; - return z; -} - -// note: this routine clips fills that extend off the edges... ideally this -// wouldn't happen, but it could happen if the truetype glyph bounding boxes -// are wrong, or if the user supplies a too-small bitmap -static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight) -{ - // non-zero winding fill - int x0=0, w=0; - - while (e) { - if (w == 0) { - // if we're currently at zero, we need to record the edge start point - x0 = e->x; w += e->valid; - } else { - int x1 = e->x; w += e->valid; - // if we went to zero, we need to draw - if (w == 0) { - int i = x0 >> FIXSHIFT; - int j = x1 >> FIXSHIFT; - - if (i < len && j >= 0) { - if (i == j) { - // x0,x1 are the same pixel, so compute combined coverage - scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> FIXSHIFT); - } else { - if (i >= 0) // add antialiasing for x0 - scanline[i] = scanline[i] + (stbtt_uint8) (((FIX - (x0 & FIXMASK)) * max_weight) >> FIXSHIFT); - else - i = -1; // clip - - if (j < len) // add antialiasing for x1 - scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & FIXMASK) * max_weight) >> FIXSHIFT); - else - j = len; // clip - - for (++i; i < j; ++i) // fill pixels between x0 and x1 - scanline[i] = scanline[i] + (stbtt_uint8) max_weight; - } - } - } - } - - e = e->next; - } -} - -static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) -{ - stbtt__active_edge *active = NULL; - int y,j=0; - int max_weight = (255 / vsubsample); // weight per vertical scanline - int s; // vertical subsample index - unsigned char scanline_data[512], *scanline; - - if (result->w > 512) - scanline = (unsigned char *) STBTT_malloc(result->w, userdata); - else - scanline = scanline_data; - - y = off_y * vsubsample; - e[n].y0 = (off_y + result->h) * (float) vsubsample + 1; - - while (j < result->h) { - STBTT_memset(scanline, 0, result->w); - for (s=0; s < vsubsample; ++s) { - // find center of pixel for this scanline - float scan_y = y + 0.5f; - stbtt__active_edge **step = &active; - - // update all active edges; - // remove all active edges that terminate before the center of this scanline - while (*step) { - stbtt__active_edge * z = *step; - if (z->ey <= scan_y) { - *step = z->next; // delete from list - STBTT_assert(z->valid); - z->valid = 0; - STBTT_free(z, userdata); - } else { - z->x += z->dx; // advance to position for current scanline - step = &((*step)->next); // advance through list - } - } - - // resort the list if needed - for(;;) { - int changed=0; - step = &active; - while (*step && (*step)->next) { - if ((*step)->x > (*step)->next->x) { - stbtt__active_edge *t = *step; - stbtt__active_edge *q = t->next; - - t->next = q->next; - q->next = t; - *step = q; - changed = 1; - } - step = &(*step)->next; - } - if (!changed) break; - } - - // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline - while (e->y0 <= scan_y) { - if (e->y1 > scan_y) { - stbtt__active_edge *z = new_active(e, off_x, scan_y, userdata); - // find insertion point - if (active == NULL) - active = z; - else if (z->x < active->x) { - // insert at front - z->next = active; - active = z; - } else { - // find thing to insert AFTER - stbtt__active_edge *p = active; - while (p->next && p->next->x < z->x) - p = p->next; - // at this point, p->next->x is NOT < z->x - z->next = p->next; - p->next = z; - } - } - ++e; - } - - // now process all active edges in XOR fashion - if (active) - stbtt__fill_active_edges(scanline, result->w, active, max_weight); - - ++y; - } - STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w); - ++j; - } - - while (active) { - stbtt__active_edge *z = active; - active = active->next; - STBTT_free(z, userdata); - } - - if (scanline != scanline_data) - STBTT_free(scanline, userdata); -} - -static int stbtt__edge_compare(const void *p, const void *q) -{ - stbtt__edge *a = (stbtt__edge *) p; - stbtt__edge *b = (stbtt__edge *) q; - - if (a->y0 < b->y0) return -1; - if (a->y0 > b->y0) return 1; - return 0; -} - -typedef struct -{ - float x,y; -} stbtt__point; - -static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, int off_x, int off_y, int invert, void *userdata) -{ - float y_scale_inv = invert ? -scale_y : scale_y; - stbtt__edge *e; - int n,i,j,k,m; - int vsubsample = result->h < 8 ? 15 : 5; - // vsubsample should divide 255 evenly; otherwise we won't reach full opacity - - // now we have to blow out the windings into explicit edge lists - n = 0; - for (i=0; i < windings; ++i) - n += wcount[i]; - - e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel - if (e == 0) return; - n = 0; - - m=0; - for (i=0; i < windings; ++i) { - stbtt__point *p = pts + m; - m += wcount[i]; - j = wcount[i]-1; - for (k=0; k < wcount[i]; j=k++) { - int a=k,b=j; - // skip the edge if horizontal - if (p[j].y == p[k].y) - continue; - // add edge from j to k to the list - e[n].invert = 0; - if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) { - e[n].invert = 1; - a=j,b=k; - } - e[n].x0 = p[a].x * scale_x; - e[n].y0 = p[a].y * y_scale_inv * vsubsample; - e[n].x1 = p[b].x * scale_x; - e[n].y1 = p[b].y * y_scale_inv * vsubsample; - ++n; - } - } - - // now sort the edges by their highest point (should snap to integer, and then by x) - STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); - - // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule - stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); - - STBTT_free(e, userdata); -} - -static void stbtt__add_point(stbtt__point *points, int n, float x, float y) -{ - if (!points) return; // during first pass, it's unallocated - points[n].x = x; - points[n].y = y; -} - -// tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching -static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) -{ - // midpoint - float mx = (x0 + 2*x1 + x2)/4; - float my = (y0 + 2*y1 + y2)/4; - // versus directly drawn line - float dx = (x0+x2)/2 - mx; - float dy = (y0+y2)/2 - my; - if (n > 16) // 65536 segments on one curve better be enough! - return 1; - if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA - stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1); - stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1); - } else { - stbtt__add_point(points, *num_points,x2,y2); - *num_points = *num_points+1; - } - return 1; -} - -// returns number of contours -stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) -{ - stbtt__point *points=0; - int num_points=0; - - float objspace_flatness_squared = objspace_flatness * objspace_flatness; - int i,n=0,start=0, pass; - - // count how many "moves" there are to get the contour count - for (i=0; i < num_verts; ++i) - if (vertices[i].type == STBTT_vmove) - ++n; - - *num_contours = n; - if (n == 0) return 0; - - *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata); - - if (*contour_lengths == 0) { - *num_contours = 0; - return 0; - } - - // make two passes through the points so we don't need to realloc - for (pass=0; pass < 2; ++pass) { - float x=0,y=0; - if (pass == 1) { - points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata); - if (points == NULL) goto error; - } - num_points = 0; - n= -1; - for (i=0; i < num_verts; ++i) { - switch (vertices[i].type) { - case STBTT_vmove: - // start the next contour - if (n >= 0) - (*contour_lengths)[n] = num_points - start; - ++n; - start = num_points; - - x = vertices[i].x, y = vertices[i].y; - stbtt__add_point(points, num_points++, x,y); - break; - case STBTT_vline: - x = vertices[i].x, y = vertices[i].y; - stbtt__add_point(points, num_points++, x, y); - break; - case STBTT_vcurve: - stbtt__tesselate_curve(points, &num_points, x,y, - vertices[i].cx, vertices[i].cy, - vertices[i].x, vertices[i].y, - objspace_flatness_squared, 0); - x = vertices[i].x, y = vertices[i].y; - break; - } - } - (*contour_lengths)[n] = num_points - start; - } - - return points; -error: - STBTT_free(points, userdata); - STBTT_free(*contour_lengths, userdata); - *contour_lengths = 0; - *num_contours = 0; - return NULL; -} - -void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, int x_off, int y_off, int invert, void *userdata) -{ - float scale = scale_x > scale_y ? scale_y : scale_x; - int winding_count, *winding_lengths; - stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); - if (windings) { - stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, x_off, y_off, invert, userdata); - STBTT_free(winding_lengths, userdata); - STBTT_free(windings, userdata); - } -} - -void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) -{ - STBTT_free(bitmap, userdata); -} - -unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) -{ - int ix0,iy0,ix1,iy1; - stbtt__bitmap gbm; - stbtt_vertex *vertices; - int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); - - if (scale_x == 0) scale_x = scale_y; - if (scale_y == 0) { - if (scale_x == 0) return NULL; - scale_y = scale_x; - } - - stbtt_GetGlyphBitmapBox(info, glyph, scale_x, scale_y, &ix0,&iy0,&ix1,&iy1); - - // now we get the size - gbm.w = (ix1 - ix0); - gbm.h = (iy1 - iy0); - gbm.pixels = NULL; // in case we error - - if (width ) *width = gbm.w; - if (height) *height = gbm.h; - if (xoff ) *xoff = ix0; - if (yoff ) *yoff = iy0; - - if (gbm.w && gbm.h) { - gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); - if (gbm.pixels) { - gbm.stride = gbm.w; - - stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, ix0, iy0, 1, info->userdata); - } - } - STBTT_free(vertices, info->userdata); - return gbm.pixels; -} - -void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) -{ - int ix0,iy0; - stbtt_vertex *vertices; - int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); - stbtt__bitmap gbm; - - stbtt_GetGlyphBitmapBox(info, glyph, scale_x, scale_y, &ix0,&iy0,0,0); - gbm.pixels = output; - gbm.w = out_w; - gbm.h = out_h; - gbm.stride = out_stride; - - if (gbm.w && gbm.h) - stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, ix0,iy0, 1, info->userdata); - - STBTT_free(vertices, info->userdata); -} - -unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) -{ - return stbtt_GetGlyphBitmap(info, scale_x, scale_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); -} - -void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) -{ - stbtt_MakeGlyphBitmap(info, output, out_w, out_h, out_stride, scale_x, scale_y, stbtt_FindGlyphIndex(info,codepoint)); -} - -////////////////////////////////////////////////////////////////////////////// -// -// bitmap baking -// -// This is SUPER-SHITTY packing to keep source code small - -extern int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) - float pixel_height, // height of font in pixels - unsigned char *pixels, int pw, int ph, // bitmap to be filled in - int first_char, int num_chars, // characters to bake - stbtt_bakedchar *chardata) -{ - float scale; - int x,y,bottom_y, i; - stbtt_fontinfo f; - stbtt_InitFont(&f, data, offset); - STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels - x=y=1; - bottom_y = 1; - - scale = stbtt_ScaleForPixelHeight(&f, pixel_height); - - for (i=0; i < num_chars; ++i) { - int advance, lsb, x0,y0,x1,y1,gw,gh; - int g = stbtt_FindGlyphIndex(&f, first_char + i); - stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); - stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1); - gw = x1-x0; - gh = y1-y0; - if (x + gw + 1 >= pw) - y = bottom_y, x = 1; // advance to next row - if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row - return -i; - STBTT_assert(x+gw < pw); - STBTT_assert(y+gh < ph); - stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g); - chardata[i].x0 = (stbtt_int16) x; - chardata[i].y0 = (stbtt_int16) y; - chardata[i].x1 = (stbtt_int16) (x + gw); - chardata[i].y1 = (stbtt_int16) (y + gh); - chardata[i].xadvance = scale * advance; - chardata[i].xoff = (float) x0; - chardata[i].yoff = (float) y0; - x = x + gw + 2; - if (y+gh+2 > bottom_y) - bottom_y = y+gh+2; - } - return bottom_y; -} - -void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) -{ - float d3d_bias = opengl_fillrule ? 0 : -0.5f; - float ipw = 1.0f / pw, iph = 1.0f / ph; - stbtt_bakedchar *b = chardata + char_index; - int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5); - int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5); - - q->x0 = round_x + d3d_bias; - q->y0 = round_y + d3d_bias; - q->x1 = round_x + b->x1 - b->x0 + d3d_bias; - q->y1 = round_y + b->y1 - b->y0 + d3d_bias; - - q->s0 = b->x0 * ipw; - q->t0 = b->y0 * ipw; - q->s1 = b->x1 * iph; - q->t1 = b->y1 * iph; - - *xpos += b->xadvance; -} - -////////////////////////////////////////////////////////////////////////////// -// -// font name matching -- recommended not to use this -// - -// check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string -static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) -{ - stbtt_int32 i=0; - - // convert utf16 to utf8 and compare the results while converting - while (len2) { - stbtt_uint16 ch = s2[0]*256 + s2[1]; - if (ch < 0x80) { - if (i >= len1) return -1; - if (s1[i++] != ch) return -1; - } else if (ch < 0x800) { - if (i+1 >= len1) return -1; - if (s1[i++] != 0xc0 + (ch >> 6)) return -1; - if (s1[i++] != 0x80 + (ch & 0x3f)) return -1; - } else if (ch >= 0xd800 && ch < 0xdc00) { - stbtt_uint32 c; - stbtt_uint16 ch2 = s2[2]*256 + s2[3]; - if (i+3 >= len1) return -1; - c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000; - if (s1[i++] != 0xf0 + (c >> 18)) return -1; - if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1; - if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1; - if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1; - s2 += 2; // plus another 2 below - len2 -= 2; - } else if (ch >= 0xdc00 && ch < 0xe000) { - return -1; - } else { - if (i+2 >= len1) return -1; - if (s1[i++] != 0xe0 + (ch >> 12)) return -1; - if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1; - if (s1[i++] != 0x80 + ((ch ) & 0x3f)) return -1; - } - s2 += 2; - len2 -= 2; - } - return i; -} - -int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) -{ - return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2); -} - -// returns results in whatever encoding you request... but note that 2-byte encodings -// will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare -char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID) -{ - stbtt_int32 i,count,stringOffset; - stbtt_uint8 *fc = font->data; - stbtt_uint32 offset = font->fontstart; - stbtt_uint32 nm = stbtt__find_table(fc, offset, "name"); - if (!nm) return NULL; - - count = ttUSHORT(fc+nm+2); - stringOffset = nm + ttUSHORT(fc+nm+4); - for (i=0; i < count; ++i) { - stbtt_uint32 loc = nm + 6 + 12 * i; - if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2) - && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) { - *length = ttUSHORT(fc+loc+8); - return (char *) (fc+stringOffset+ttUSHORT(fc+loc+10)); - } - } - return NULL; -} - -static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id) -{ - stbtt_int32 i; - stbtt_int32 count = ttUSHORT(fc+nm+2); - stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4); - - for (i=0; i < count; ++i) { - stbtt_uint32 loc = nm + 6 + 12 * i; - stbtt_int32 id = ttUSHORT(fc+loc+6); - if (id == target_id) { - // find the encoding - stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4); - - // is this a Unicode encoding? - if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { - stbtt_int32 slen = ttUSHORT(fc+loc+8), off = ttUSHORT(fc+loc+10); - - // check if there's a prefix match - stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen); - if (matchlen >= 0) { - // check for target_id+1 immediately following, with same encoding & language - if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) { - stbtt_int32 slen = ttUSHORT(fc+loc+12+8), off = ttUSHORT(fc+loc+12+10); - if (slen == 0) { - if (matchlen == nlen) - return 1; - } else if (matchlen < nlen && name[matchlen] == ' ') { - ++matchlen; - if (stbtt_CompareUTF8toUTF16_bigendian((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen)) - return 1; - } - } else { - // if nothing immediately following - if (matchlen == nlen) - return 1; - } - } - } - - // @TODO handle other encodings - } - } - return 0; -} - -static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags) -{ - stbtt_int32 nlen = STBTT_strlen((char *) name); - stbtt_uint32 nm,hd; - if (!stbtt__isfont(fc+offset)) return 0; - - // check italics/bold/underline flags in macStyle... - if (flags) { - hd = stbtt__find_table(fc, offset, "head"); - if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0; - } - - nm = stbtt__find_table(fc, offset, "name"); - if (!nm) return 0; - - if (flags) { - // if we checked the macStyle flags, then just check the family and ignore the subfamily - if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; - } else { - if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; - } - - return 0; -} - -int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags) -{ - stbtt_int32 i; - for (i=0;;++i) { - stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i); - if (off < 0) return off; - if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags)) - return off; - } -} - -#endif // STB_TRUETYPE_IMPLEMENTATION diff --git a/src/SFML/Network/SocketUDP.cpp b/src/SFML/Network/SocketUDP.cpp index cda58288..ee99ac30 100644 --- a/src/SFML/Network/SocketUDP.cpp +++ b/src/SFML/Network/SocketUDP.cpp @@ -244,10 +244,6 @@ Socket::Status SocketUDP::Send(Packet& packet, const IPAddress& address, unsigne //////////////////////////////////////////////////////////// Socket::Status SocketUDP::Receive(Packet& packet, IPAddress& address, unsigned short& port) { - // This is not safe at all, as data can be lost, duplicated, or arrive in a different order. - // So if a packet is split into more than one chunk, nobody knows what could happen... - // Conclusion : we shouldn't use packets with UDP, unless we build a more complex protocol on top of it. - // We start by getting the size of the incoming packet Uint32 packetSize = 0; std::size_t received = 0;