From 123ebabedcea2b36fe122ca5dd65a75fd0cefd58 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 3 Dec 2014 00:27:30 +0100 Subject: [PATCH] Finally rendering text on linux! (very ugly and in-the-wrong place text) --- Cairo/Perspex.Cairo/CairoPlatform.cs | 19 +++++++++++ Cairo/Perspex.Cairo/Media/DrawingContext.cs | 6 +++- Cairo/Perspex.Cairo/Media/TextService.cs | 37 +++++++++++++++++++-- Cairo/Perspex.Cairo/Perspex.Cairo.csproj | 15 +++++++-- Perspex-Mono.userprefs | 21 ++++++------ 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/Cairo/Perspex.Cairo/CairoPlatform.cs b/Cairo/Perspex.Cairo/CairoPlatform.cs index e280a5038e..b3ddc347ed 100644 --- a/Cairo/Perspex.Cairo/CairoPlatform.cs +++ b/Cairo/Perspex.Cairo/CairoPlatform.cs @@ -40,6 +40,11 @@ namespace Perspex.Cairo public IRenderer CreateRenderer(IPlatformHandle handle, double width, double height) { + if (textService.Context == null) + { + textService.Context = GetPangoContext(handle); + } + return new Renderer(handle, width, height); } @@ -60,5 +65,19 @@ namespace Perspex.Cairo ImageSurface result = new ImageSurface(fileName); return new BitmapImpl(result); } + + private Pango.Context GetPangoContext(IPlatformHandle handle) + { + switch (handle.HandleDescriptor) + { + case "GtkWindow": + var window = GLib.Object.GetObject(handle.Handle) as Gtk.Window; + return window.PangoContext; + default: + throw new NotSupportedException(string.Format( + "Don't know how to get a Pango Context from a '{0}'.", + handle.HandleDescriptor)); + } + } } } diff --git a/Cairo/Perspex.Cairo/Media/DrawingContext.cs b/Cairo/Perspex.Cairo/Media/DrawingContext.cs index c3519627e6..99c213a72d 100644 --- a/Cairo/Perspex.Cairo/Media/DrawingContext.cs +++ b/Cairo/Perspex.Cairo/Media/DrawingContext.cs @@ -121,7 +121,11 @@ namespace Perspex.Cairo.Media /// The text. public void DrawText(Perspex.Media.Brush foreground, Rect rect, FormattedText text) { - // TODO: Implement + this.SetBrush(foreground); + this.context.MoveTo(rect.X, rect.Bottom); + this.context.SelectFontFace(text.FontFamilyName, (FontSlant)text.FontStyle, FontWeight.Normal); + this.context.SetFontSize(text.FontSize); + this.context.ShowText(text.Text); } /// diff --git a/Cairo/Perspex.Cairo/Media/TextService.cs b/Cairo/Perspex.Cairo/Media/TextService.cs index 9a0be6bf53..901ae2fdb0 100644 --- a/Cairo/Perspex.Cairo/Media/TextService.cs +++ b/Cairo/Perspex.Cairo/Media/TextService.cs @@ -8,13 +8,23 @@ namespace Perspex.Cairo.Media { using System; using System.Linq; + using System.Runtime.InteropServices; using Perspex.Media; using Perspex.Platform; public class TextService : ITextService { - public TextService() + /// + /// Gets the pango context to be used by the service. + /// + /// > + /// There seems to be no way in GtkSharp to create a new Pango Context, so this has to + /// be injected by CairoPlatform the first time a renderer is created. + /// + public Pango.Context Context { + get; + internal set; } public int GetCaretIndex(FormattedText text, Point point, Size constraint) @@ -34,7 +44,30 @@ namespace Perspex.Cairo.Media public Size Measure(FormattedText text, Size constraint) { - return new Size(100, 30); + var layout = this.CreateLayout(text); + + Pango.Rectangle inkRect; + Pango.Rectangle logicalRect; + layout.GetExtents(out inkRect, out logicalRect); + + return new Size(Pango.Units.ToDouble(inkRect.Width), Pango.Units.ToDouble(inkRect.Height)); + } + + private Pango.Layout CreateLayout(FormattedText text) + { + var layout = new Pango.Layout(this.Context) + { + FontDescription = new Pango.FontDescription + { + Family = text.FontFamilyName, + Size = Pango.Units.FromDouble(text.FontSize), + Style = (Pango.Style)text.FontStyle, + } + }; + + layout.SetText(text.Text); + + return layout; } } } diff --git a/Cairo/Perspex.Cairo/Perspex.Cairo.csproj b/Cairo/Perspex.Cairo/Perspex.Cairo.csproj index e851745378..b9d063bd7b 100644 --- a/Cairo/Perspex.Cairo/Perspex.Cairo.csproj +++ b/Cairo/Perspex.Cairo/Perspex.Cairo.csproj @@ -30,9 +30,15 @@ 4 - - - + + gtk-sharp-2.0 + + + glib-sharp-2.0 + + + gtk-sharp-2.0 + gtk-sharp-2.0 @@ -53,6 +59,9 @@ ..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll + + gtk-sharp-2.0 + diff --git a/Perspex-Mono.userprefs b/Perspex-Mono.userprefs index 64d6d04a1c..c6bbcfe9f8 100644 --- a/Perspex-Mono.userprefs +++ b/Perspex-Mono.userprefs @@ -1,29 +1,28 @@  - - - - + - - - + + + + + + + + - - - - +