diff --git a/Cairo/Perspex.Cairo/CairoExtensions.cs b/Cairo/Perspex.Cairo/CairoExtensions.cs
index f6f8502cac..963d2fe980 100644
--- a/Cairo/Perspex.Cairo/CairoExtensions.cs
+++ b/Cairo/Perspex.Cairo/CairoExtensions.cs
@@ -24,5 +24,14 @@ namespace Perspex.Cairo
{
return new Cairo.Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
}
+
+ public static Rect ToPerspex(this Pango.Rectangle rect)
+ {
+ return new Rect(
+ Pango.Units.ToDouble(rect.X),
+ Pango.Units.ToDouble(rect.Y),
+ Pango.Units.ToDouble(rect.Width),
+ Pango.Units.ToDouble(rect.Height));
+ }
}
}
\ No newline at end of file
diff --git a/Cairo/Perspex.Cairo/CairoPlatform.cs b/Cairo/Perspex.Cairo/CairoPlatform.cs
index 2b1016a2e6..cb5e10019e 100644
--- a/Cairo/Perspex.Cairo/CairoPlatform.cs
+++ b/Cairo/Perspex.Cairo/CairoPlatform.cs
@@ -10,6 +10,7 @@ namespace Perspex.Cairo
using global::Cairo;
using Perspex.Cairo.Media;
using Perspex.Cairo.Media.Imaging;
+ using Perspex.Media;
using Perspex.Platform;
using Perspex.Threading;
using Splat;
@@ -30,8 +31,18 @@ namespace Perspex.Cairo
////return new BitmapImpl(imagingFactory, width, height);
}
+ public IFormattedTextImpl CreateFormattedText(
+ string text,
+ string fontFamily,
+ double fontSize,
+ FontStyle fontStyle)
+ {
+ return new FormattedTextImpl(text, fontFamily, fontSize, fontStyle);
+ }
+
public IRenderer CreateRenderer(IPlatformHandle handle, double width, double height)
{
+ Locator.CurrentMutable.RegisterConstant(this.GetPangoContext(handle), typeof(Pango.Context));
return new Renderer(handle, width, height);
}
diff --git a/Cairo/Perspex.Cairo/Media/DrawingContext.cs b/Cairo/Perspex.Cairo/Media/DrawingContext.cs
index 830d2b2f29..5b79613e21 100644
--- a/Cairo/Perspex.Cairo/Media/DrawingContext.cs
+++ b/Cairo/Perspex.Cairo/Media/DrawingContext.cs
@@ -133,14 +133,14 @@ namespace Perspex.Cairo.Media
/// Draws text.
///
/// The foreground brush.
- /// The output rectangle.
+ /// The upper-left corner of the text.
/// The text.
- public void DrawText(Perspex.Media.Brush foreground, Rect rect, FormattedText text)
+ public void DrawText(Brush foreground, Point origin, FormattedText text)
{
- ////var layout = this.textService.CreateLayout(text);
- ////this.SetBrush(foreground);
- ////this.context.MoveTo(rect.X, rect.Y);
- ////Pango.CairoHelper.ShowLayout(this.context, layout);
+ var layout = ((FormattedTextImpl)text.PlatformImpl).Layout;
+ this.SetBrush(foreground);
+ this.context.MoveTo(origin.X, origin.Y);
+ Pango.CairoHelper.ShowLayout(this.context, layout);
}
///
diff --git a/Cairo/Perspex.Cairo/Media/FormattedTextImpl.cs b/Cairo/Perspex.Cairo/Media/FormattedTextImpl.cs
new file mode 100644
index 0000000000..7dc670b37a
--- /dev/null
+++ b/Cairo/Perspex.Cairo/Media/FormattedTextImpl.cs
@@ -0,0 +1,97 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2014 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.Cairo.Media
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using Perspex.Media;
+ using Perspex.Platform;
+ using Splat;
+
+ public class FormattedTextImpl : IFormattedTextImpl
+ {
+ public FormattedTextImpl(
+ string text,
+ string fontFamily,
+ double fontSize,
+ FontStyle fontStyle)
+ {
+ var context = Locator.Current.GetService();
+ this.Layout = new Pango.Layout(context);
+ this.Layout.SetText(text);
+ this.Layout.FontDescription = new Pango.FontDescription
+ {
+ Family = fontFamily,
+ Size = Pango.Units.FromDouble(fontSize),
+ Style = (Pango.Style)fontStyle,
+ };
+ }
+
+ public Size Constraint
+ {
+ get
+ {
+ return new Size(this.Layout.Width, double.PositiveInfinity);
+ }
+
+ set
+ {
+ this.Layout.Width = Pango.Units.FromDouble(value.Width);
+ }
+ }
+
+ public Pango.Layout Layout
+ {
+ get;
+ private set;
+ }
+
+ public void Dispose()
+ {
+ this.Layout.Dispose();
+ }
+
+ public TextHitTestResult HitTestPoint(Point point)
+ {
+ int textPosition;
+ int trailing;
+
+ var isInside = this.Layout.XyToIndex(
+ Pango.Units.FromDouble(point.X),
+ Pango.Units.FromDouble(point.Y),
+ out textPosition,
+ out trailing);
+
+ return new TextHitTestResult
+ {
+ IsInside = isInside,
+ TextPosition = textPosition,
+ IsTrailing = trailing == 0,
+ };
+ }
+
+ public Rect HitTestTextPosition(int index)
+ {
+ return this.Layout.IndexToPos(index).ToPerspex();
+ }
+
+ public IEnumerable HitTestTextRange(int index, int length, Point origin)
+ {
+ // TODO: Implement.
+ return new Rect[0];
+ }
+
+ public Size Measure()
+ {
+ int width;
+ int height;
+ this.Layout.GetPixelSize(out width, out height);
+ return new Size(width, height);
+ }
+ }
+}
diff --git a/Cairo/Perspex.Cairo/Perspex.Cairo.csproj b/Cairo/Perspex.Cairo/Perspex.Cairo.csproj
index a9e2222701..12985d10b8 100644
--- a/Cairo/Perspex.Cairo/Perspex.Cairo.csproj
+++ b/Cairo/Perspex.Cairo/Perspex.Cairo.csproj
@@ -67,6 +67,7 @@
+
diff --git a/Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs b/Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs
index 1ce6cfb357..c01c8b03d0 100644
--- a/Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs
+++ b/Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs
@@ -29,7 +29,11 @@ namespace Perspex.Gtk
public override ModifierKeys Modifiers
{
- get { throw new System.NotImplementedException(); }
+ get
+ {
+ // TODO: Implement.
+ return ModifierKeys.None;
+ }
}
public static Perspex.Input.Key ConvertKey(Gdk.Key key)
diff --git a/Perspex.SceneGraph/Media/TextHitTestResult.cs b/Perspex.SceneGraph/Media/TextHitTestResult.cs
index 64ee08a55d..fee1d1abc4 100644
--- a/Perspex.SceneGraph/Media/TextHitTestResult.cs
+++ b/Perspex.SceneGraph/Media/TextHitTestResult.cs
@@ -8,6 +8,8 @@ namespace Perspex.Media
{
public class TextHitTestResult
{
+ public bool IsInside { get; set; }
+
public int TextPosition { get; set; }
public bool IsTrailing { get; set; }
diff --git a/Windows/Perspex.Direct2D1/Media/FormattedTextImpl.cs b/Windows/Perspex.Direct2D1/Media/FormattedTextImpl.cs
index edf9888a24..fbd166cb7e 100644
--- a/Windows/Perspex.Direct2D1/Media/FormattedTextImpl.cs
+++ b/Windows/Perspex.Direct2D1/Media/FormattedTextImpl.cs
@@ -70,6 +70,7 @@ namespace Perspex.Direct2D1.Media
return new TextHitTestResult
{
+ IsInside = isInside,
TextPosition = result.TextPosition,
IsTrailing = isTrailingHit,
};