Browse Source

[Cairo] Fixed wrong index calculation of text in case text contains Unicode chars

pull/194/head
David Karlaš 11 years ago
parent
commit
2b55af700f
  1. 23
      src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs

23
src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Perspex.Media;
using Perspex.Platform;
using Splat;
@ -13,6 +14,7 @@ namespace Perspex.Cairo.Media
public class FormattedTextImpl : IFormattedTextImpl
{
private Size _size;
private string _text;
public FormattedTextImpl(
Pango.Context context,
@ -26,6 +28,7 @@ namespace Perspex.Cairo.Media
Contract.Requires<NullReferenceException>(context != null);
Layout = new Pango.Layout(context);
_text = text;
Layout.SetText(text);
Layout.FontDescription = new Pango.FontDescription
{
@ -49,7 +52,7 @@ namespace Perspex.Cairo.Media
set
{
_size = value;
Layout.Width = double.IsPositiveInfinity(value.Width) ?
Layout.Width = double.IsPositiveInfinity(value.Width) ?
-1 : Pango.Units.FromDouble(value.Width);
}
}
@ -80,6 +83,8 @@ namespace Perspex.Cairo.Media
out textPosition,
out trailing);
textPosition = PangoIndexToTextIndex(textPosition);
return new TextHitTestResult
{
IsInside = isInside,
@ -88,9 +93,19 @@ namespace Perspex.Cairo.Media
};
}
int PangoIndexToTextIndex(int pangoIndex)
{
return Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(_text), 0, Math.Min(pangoIndex, _text.Length)).Length;
}
public Rect HitTestTextPosition(int index)
{
return Layout.IndexToPos(index).ToPerspex();
return Layout.IndexToPos(TextIndexToPangoIndex(index)).ToPerspex();
}
int TextIndexToPangoIndex(int textIndex)
{
return Encoding.UTF8.GetByteCount(textIndex < _text.Length ? _text.Remove(textIndex) : _text);
}
public IEnumerable<Rect> HitTestTextRange(int index, int length)
@ -124,8 +139,8 @@ namespace Perspex.Cairo.Media
color.Parse(string.Format("#{0}", scb.Color.ToString().Substring(3)));
var brushAttr = new Pango.AttrForeground(color);
brushAttr.StartIndex = (uint)startIndex;
brushAttr.EndIndex = (uint)(startIndex + count);
brushAttr.StartIndex = (uint)TextIndexToPangoIndex(startIndex);
brushAttr.EndIndex = (uint)TextIndexToPangoIndex(startIndex + count);
Layout.Attributes.Insert(brushAttr);
}

Loading…
Cancel
Save