From f31fe557ae875c1e5ea95d88f710bde0618da80c Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 3 Dec 2014 00:59:32 +0100 Subject: [PATCH] Use Pango to draw text in Cairo engine. Makes text look a lot better, and is aligned correctly! Yay! --- Cairo/Perspex.Cairo/Media/DrawingContext.cs | 32 ++++++++++-------- Cairo/Perspex.Cairo/Media/TextService.cs | 36 ++++++++++----------- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/Cairo/Perspex.Cairo/Media/DrawingContext.cs b/Cairo/Perspex.Cairo/Media/DrawingContext.cs index 99c213a72d..af96caa20b 100644 --- a/Cairo/Perspex.Cairo/Media/DrawingContext.cs +++ b/Cairo/Perspex.Cairo/Media/DrawingContext.cs @@ -8,11 +8,11 @@ namespace Perspex.Cairo.Media { using System; using System.Reactive.Disposables; - using global::Cairo; using Perspex.Media; + using Perspex.Platform; + using Splat; + using Cairo = global::Cairo; using IBitmap = Perspex.Media.Imaging.IBitmap; - using Matrix = Perspex.Matrix; - using CairoMatrix = global::Cairo.Matrix; /// /// Draws using Direct2D1. @@ -22,21 +22,27 @@ namespace Perspex.Cairo.Media /// /// The cairo context. /// - private Context context; + private Cairo.Context context; /// /// The cairo surface. /// - private Surface surface; + private Cairo.Surface surface; + + /// + /// The text service. + /// + private TextService textService; /// /// Initializes a new instance of the class. /// /// The target surface. - public DrawingContext(Surface surface) + public DrawingContext(Cairo.Surface surface) { this.surface = surface; - this.context = new Context(surface); + this.context = new Cairo.Context(surface); + this.textService = Locator.Current.GetService() as TextService; } /// @@ -47,6 +53,7 @@ namespace Perspex.Cairo.Media { this.Drawable = drawable; this.context = Gdk.CairoHelper.Create(drawable); + this.textService = Locator.Current.GetService() as TextService; } public Matrix CurrentTransform @@ -121,11 +128,10 @@ namespace Perspex.Cairo.Media /// The text. public void DrawText(Perspex.Media.Brush foreground, Rect rect, FormattedText text) { + var layout = this.textService.CreateLayout(text); 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); + this.context.MoveTo(rect.X, rect.Y); + Pango.CairoHelper.ShowLayout(this.context, layout); } /// @@ -167,9 +173,9 @@ namespace Perspex.Cairo.Media }); } - private static CairoMatrix Convert(Matrix m) + private static Cairo.Matrix Convert(Matrix m) { - return new CairoMatrix(m.M11, m.M12, m.M21, m.M22, m.OffsetX, m.OffsetY); + return new Cairo.Matrix(m.M11, m.M12, m.M21, m.M22, m.OffsetX, m.OffsetY); } private void SetBrush(Brush brush) diff --git a/Cairo/Perspex.Cairo/Media/TextService.cs b/Cairo/Perspex.Cairo/Media/TextService.cs index 901ae2fdb0..ff6c6a5b0d 100644 --- a/Cairo/Perspex.Cairo/Media/TextService.cs +++ b/Cairo/Perspex.Cairo/Media/TextService.cs @@ -27,6 +27,23 @@ namespace Perspex.Cairo.Media internal set; } + public 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; + } + public int GetCaretIndex(FormattedText text, Point point, Size constraint) { throw new NotImplementedException(); @@ -50,24 +67,7 @@ namespace Perspex.Cairo.Media 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; + return new Size(Pango.Units.ToDouble(logicalRect.Width), Pango.Units.ToDouble(logicalRect.Height)); } } }