Skip to content

Commit

Permalink
Added correct handling of unicode strings
Browse files Browse the repository at this point in the history
  • Loading branch information
LaurentGomila committed Mar 24, 2013
1 parent d2bbf6a commit 62b7006
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 25 deletions.
Binary file modified extlibs/x64/csfml-audio-2.dll
Binary file not shown.
Binary file modified extlibs/x64/csfml-graphics-2.dll
Binary file not shown.
Binary file modified extlibs/x64/csfml-window-2.dll
Binary file not shown.
Binary file modified extlibs/x86/csfml-audio-2.dll
Binary file not shown.
Binary file modified extlibs/x86/csfml-graphics-2.dll
Binary file not shown.
Binary file modified extlibs/x86/csfml-window-2.dll
Binary file not shown.
31 changes: 28 additions & 3 deletions src/Graphics/RenderWindow.cs
Expand Up @@ -52,10 +52,20 @@ public class RenderWindow : SFML.Window.Window, RenderTarget
/// <param name="settings">Creation parameters</param>
////////////////////////////////////////////////////////////
public RenderWindow(VideoMode mode, string title, Styles style, ContextSettings settings) :
base(sfRenderWindow_create(mode, title, style, ref settings), 0)
base(IntPtr.Zero)

This comment has been minimized.

Copy link
@DavidKarlas

DavidKarlas May 18, 2013

I believe this is bug on linux

{
// Copy the string to a null-terminated UTF-32 byte array
byte[] titleAsUtf32 = System.Text.Encoding.UTF32.GetBytes(title + '\0');

unsafe
{
fixed (byte* titlePtr = titleAsUtf32)
{
SetThis(sfRenderWindow_createUnicode(mode, (IntPtr)titlePtr, style, ref settings));
}
}
Initialize();
}
}

////////////////////////////////////////////////////////////
/// <summary>
Expand Down Expand Up @@ -156,7 +166,16 @@ public override Vector2u Size
////////////////////////////////////////////////////////////
public override void SetTitle(string title)
{
sfRenderWindow_setTitle(CPointer, title);
// Copy the title to a null-terminated UTF-32 byte array
byte[] titleAsUtf32 = System.Text.Encoding.UTF32.GetBytes(title + '\0');

unsafe
{
fixed (byte* titlePtr = titleAsUtf32)
{
sfRenderWindow_setUnicodeTitle(CPointer, (IntPtr)titlePtr);
}
}
}

////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -694,6 +713,9 @@ private void Initialize()
[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfRenderWindow_create(VideoMode Mode, string Title, Styles Style, ref ContextSettings Params);

[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfRenderWindow_createUnicode(VideoMode Mode, IntPtr Title, Styles Style, ref ContextSettings Params);

[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfRenderWindow_createFromHandle(IntPtr Handle, ref ContextSettings Params);

Expand Down Expand Up @@ -736,6 +758,9 @@ private void Initialize()
[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern void sfRenderWindow_setTitle(IntPtr CPointer, string title);

[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern void sfRenderWindow_setUnicodeTitle(IntPtr CPointer, IntPtr title);

[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
unsafe static extern void sfRenderWindow_setIcon(IntPtr CPointer, uint Width, uint Height, byte* Pixels);

Expand Down
47 changes: 28 additions & 19 deletions src/Graphics/Text.cs
Expand Up @@ -110,29 +110,38 @@ public string DisplayedString
{
get
{
// Get the number of characters
// This is probably not the most optimized way; if anyone has a better solution...
int length = Marshal.PtrToStringAnsi(sfText_getString(CPointer)).Length;

// Copy the characters
byte[] characters = new byte[length * 4];
Marshal.Copy(sfText_getUnicodeString(CPointer), characters, 0, characters.Length);

// Convert from UTF-32 to String (UTF-16)
return System.Text.Encoding.UTF32.GetString(characters);
// Get a pointer to the source string (UTF-32)
IntPtr source = sfText_getUnicodeString(CPointer);

// Find its length (find the terminating 0)
uint length = 0;
unsafe
{
for (uint* ptr = (uint*)source.ToPointer(); *ptr != 0; ++ptr)
length++;
}

// Copy it to a byte array
byte[] sourceBytes = new byte[length * 4];
Marshal.Copy(source, sourceBytes, 0, sourceBytes.Length);

// Convert it to a C# string
return System.Text.Encoding.UTF32.GetString(sourceBytes);
}

set
{
// Convert from String (UTF-16) to UTF-32
int[] characters = new int[value.Length];
for (int i = 0; i < value.Length; ++i)
characters[i] = Char.ConvertToUtf32(value, i);

// Transform to raw and pass to the C API
GCHandle handle = GCHandle.Alloc(characters, GCHandleType.Pinned);
sfText_setUnicodeString(CPointer, handle.AddrOfPinnedObject());
handle.Free();
// Copy the string to a null-terminated UTF-32 byte array
byte[] utf32 = System.Text.Encoding.UTF32.GetBytes(value + '\0');

// Pass it to the C API
unsafe
{
fixed (byte* ptr = utf32)
{
sfText_setUnicodeString(CPointer, (IntPtr)ptr);
}
}
}
}

Expand Down
31 changes: 28 additions & 3 deletions src/Window/Window.cs
Expand Up @@ -77,9 +77,19 @@ public class Window : ObjectBase
/// <param name="settings">Creation parameters</param>
////////////////////////////////////////////////////////////
public Window(VideoMode mode, string title, Styles style, ContextSettings settings) :
base(sfWindow_create(mode, title, style, ref settings))
base(IntPtr.Zero)
{
}
// Copy the title to a null-terminated UTF-32 byte array
byte[] titleAsUtf32 = System.Text.Encoding.UTF32.GetBytes(title + '\0');

unsafe
{
fixed (byte* titlePtr = titleAsUtf32)
{
SetThis(sfWindow_createUnicode(mode, (IntPtr)titlePtr, style, ref settings));
}
}
}

////////////////////////////////////////////////////////////
/// <summary>
Expand Down Expand Up @@ -179,7 +189,16 @@ public virtual Vector2u Size
////////////////////////////////////////////////////////////
public virtual void SetTitle(string title)
{
sfWindow_setTitle(CPointer, title);
// Copy the title to a null-terminated UTF-32 byte array
byte[] titleAsUtf32 = System.Text.Encoding.UTF32.GetBytes(title + '\0');

unsafe
{
fixed (byte* titlePtr = titleAsUtf32)
{
sfWindow_setUnicodeTitle(CPointer, (IntPtr)titlePtr);
}
}
}

////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -577,6 +596,9 @@ private void CallEventHandler(Event e)
[DllImport("csfml-window-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfWindow_create(VideoMode Mode, string Title, Styles Style, ref ContextSettings Params);

[DllImport("csfml-window-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfWindow_createUnicode(VideoMode Mode, IntPtr Title, Styles Style, ref ContextSettings Params);

[DllImport("csfml-window-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfWindow_createFromHandle(IntPtr Handle, ref ContextSettings Params);

Expand Down Expand Up @@ -616,6 +638,9 @@ private void CallEventHandler(Event e)
[DllImport("csfml-window-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern void sfWindow_setTitle(IntPtr CPointer, string title);

[DllImport("csfml-window-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern void sfWindow_setUnicodeTitle(IntPtr CPointer, IntPtr title);

[DllImport("csfml-window-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
unsafe static extern void sfWindow_setIcon(IntPtr CPointer, uint Width, uint Height, byte* Pixels);

Expand Down

0 comments on commit 62b7006

Please sign in to comment.