diff --git a/src/Microsoft.Maui.Graphics.Gtk/Gtk/GtkImage.cs b/src/Microsoft.Maui.Graphics.Gtk/Gtk/GtkImage.cs index 4a87ae1f..8e970e9b 100644 --- a/src/Microsoft.Maui.Graphics.Gtk/Gtk/GtkImage.cs +++ b/src/Microsoft.Maui.Graphics.Gtk/Gtk/GtkImage.cs @@ -60,6 +60,7 @@ public IImage ToImage(int width, int height, float scale = 1f) return context.Image; } + public IImage ToPlatformImage()=> this; } } diff --git a/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.Context.cs b/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.Context.cs index 46418134..095159d9 100644 --- a/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.Context.cs +++ b/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.Context.cs @@ -4,22 +4,6 @@ namespace Microsoft.Maui.Graphics.Platform.Gtk { public partial class PlatformCanvas { - Cairo.Context? _sharedContext; - - internal Cairo.Context SharedContext - { - get - { - if (_sharedContext == null) - { - using var sf = new Cairo.ImageSurface(Cairo.Format.ARGB32, 1, 1); - _sharedContext = new Cairo.Context(sf); - } - - return _sharedContext; - } - } - private Cairo.Surface CreateSurface(Cairo.Context context, bool imageSurface = false) { var surface = context.GetTarget(); diff --git a/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.Text.cs b/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.Text.cs index 3368d02b..e8b5af1e 100644 --- a/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.Text.cs +++ b/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.Text.cs @@ -49,41 +49,6 @@ public override void DrawText(IAttributedText value, float x, float y, float wid } - private static TextLayout? _textLayout; - - private TextLayout SharedTextLayout => _textLayout ??= new TextLayout(SharedContext) - { - HeightForWidth = true - }; - - public override SizeF GetStringSize(string value, IFont font, float textWidth) - { - if (string.IsNullOrEmpty(value)) - return new SizeF(); - - lock (SharedTextLayout) - { - SharedTextLayout.FontFamily = font?.Name ?? FontExtensions.Default.Family; - - return SharedTextLayout.GetSize(value, textWidth); - } - - } - - public override SizeF GetStringSize(string value, IFont font, float textWidth, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) - { - if (string.IsNullOrEmpty(value)) - return new SizeF(); - - lock (SharedTextLayout) - { - SharedTextLayout.FontFamily = font.Name; - SharedTextLayout.HorizontalAlignment = horizontalAlignment; - SharedTextLayout.VerticalAlignment = verticalAlignment; - - return SharedTextLayout.GetSize(value, textWidth); - } - } } } diff --git a/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.cs b/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.cs index 6b8ae93c..5ec216ca 100644 --- a/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.cs +++ b/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvas.cs @@ -5,10 +5,9 @@ namespace Microsoft.Maui.Graphics.Platform.Gtk public partial class PlatformCanvas : AbstractCanvas { - - public PlatformCanvas() : base(CreateNewState, CreateStateCopy) + public PlatformCanvas() + : base(new PlatformCanvasStateService(), new PlatformStringSizeService ()) { - _context = default; } private Cairo.Context _context; @@ -24,16 +23,6 @@ public Cairo.Context Context } } - private static PlatformCanvasState CreateNewState(object context) - { - return new PlatformCanvasState { }; - } - - private static PlatformCanvasState CreateStateCopy(PlatformCanvasState prototype) - { - return new PlatformCanvasState(prototype); - } - public override void SaveState() { Context?.Save(); diff --git a/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvasStateService.cs b/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvasStateService.cs new file mode 100644 index 00000000..f160e3ab --- /dev/null +++ b/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformCanvasStateService.cs @@ -0,0 +1,9 @@ +using System; + +namespace Microsoft.Maui.Graphics.Platform.Gtk { + public class PlatformCanvasStateService : ICanvasStateService { + public PlatformCanvasState CreateNew (object context) => new() { }; + + public PlatformCanvasState CreateCopy (PlatformCanvasState prototype) => new(prototype); + } +} diff --git a/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformStringSizeService.cs b/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformStringSizeService.cs new file mode 100644 index 00000000..bd1ddc13 --- /dev/null +++ b/src/Microsoft.Maui.Graphics.Gtk/Gtk/PlatformStringSizeService.cs @@ -0,0 +1,48 @@ +namespace Microsoft.Maui.Graphics.Platform.Gtk { + + public class PlatformStringSizeService : IStringSizeService { + Cairo.Context? _sharedContext; + + internal Cairo.Context SharedContext { + get { + if (_sharedContext == null) { + using var sf = new Cairo.ImageSurface (Cairo.Format.ARGB32, 1, 1); + _sharedContext = new Cairo.Context (sf); + } + + return _sharedContext; + } + } + + private static TextLayout? _textLayout; + + private TextLayout SharedTextLayout => _textLayout ??= new TextLayout (SharedContext) { + HeightForWidth = true + }; + + public SizeF GetStringSize (string value, IFont font, float fontSize) { + if (string.IsNullOrEmpty (value)) + return new SizeF (); + + lock (SharedTextLayout) { + SharedTextLayout.SetFontStyle (font, fontSize); + var size = SharedTextLayout.GetPixelSize (value); + return new SizeF (size.width, size.height); + } + } + + public SizeF GetStringSize (string value, IFont font, float aFontSize, HorizontalAlignment aHorizontalAlignment, VerticalAlignment aVerticalAlignment) { + if (string.IsNullOrEmpty (value)) + return new SizeF (); + + lock (SharedTextLayout) { + SharedTextLayout.SetFontStyle (font, aFontSize); + + SharedTextLayout.HorizontalAlignment = aHorizontalAlignment; + SharedTextLayout.VerticalAlignment = aVerticalAlignment; + var size = SharedTextLayout.GetPixelSize (value); + return new SizeF (size.width, size.height); + } + } + } +} diff --git a/src/Microsoft.Maui.Graphics.Gtk/Gtk/TextLayout.cs b/src/Microsoft.Maui.Graphics.Gtk/Gtk/TextLayout.cs index ec22477a..7b05d94b 100644 --- a/src/Microsoft.Maui.Graphics.Gtk/Gtk/TextLayout.cs +++ b/src/Microsoft.Maui.Graphics.Gtk/Gtk/TextLayout.cs @@ -1,6 +1,7 @@ using System; using Microsoft.Maui.Graphics.Extras; using Microsoft.Maui.Graphics.Text; +using Pango; using Context = Cairo.Context; namespace Microsoft.Maui.Graphics.Platform.Gtk { @@ -21,13 +22,60 @@ public TextLayout(Context context) { public Context Context => _context; - public string FontFamily { get; set; } + public string FontFamily { + get { + if (string.IsNullOrEmpty (_fontFamily)) { + _fontFamily = Gdk.PangoHelper.ContextGet ().FontDescription.Family; + } + + return _fontFamily; + } + set { + if (string.Equals (_fontFamily, value)) + return; + _fontFamily = value; + FontDescriptionChanged (); + } + } + + public Pango.Weight Weight { + get => _weight; + set { + if (_weight == value) + return; - public Pango.Weight Weight { get; set; } = Pango.Weight.Normal; + _weight = value; + FontDescriptionChanged (); + } + } - public Pango.Style Style { get; set; } = Pango.Style.Normal; + public Pango.Style Style { + get => _style; + set { + if (_style == value) + return; - public int PangoFontSize { get; set; } = -1; + _style = value; + FontDescriptionChanged (); + } + } + + public int PangoFontSize { + get { + if (_pangoFontSize == -1) { + _pangoFontSize = Gdk.PangoHelper.ContextGet ().FontDescription.Size; + } + + return _pangoFontSize; + } + set { + if (_pangoFontSize == value) + return; + + _pangoFontSize = value; + FontDescriptionChanged (); + } + } private Pango.Layout? _layout; private bool _layoutOwned = false; @@ -56,18 +104,24 @@ public void SetLayout(Pango.Layout value) { } private Pango.FontDescription? _fontDescription; + + void FontDescriptionChanged () { + if (_fontDescriptionOwned && _fontDescription is {}) { + _fontDescription.Family = FontFamily; + _fontDescription.Weight = Weight; + _fontDescription.Style = Style; + _fontDescription.Size = PangoFontSize; + } + } + private bool _fontDescriptionOwned = false; + private string _fontFamily; + private Weight _weight = Pango.Weight.Normal; + private Style _style = Pango.Style.Normal; + private int _pangoFontSize = -1; public Pango.FontDescription FontDescription { get { - if (PangoFontSize == -1) { - PangoFontSize = Gdk.PangoHelper.ContextGet().FontDescription.Size; - } - - if (string.IsNullOrEmpty(FontFamily)) { - FontFamily = Gdk.PangoHelper.ContextGet().FontDescription.Family; - } - if (_fontDescription == null) { _fontDescription = new Pango.FontDescription { Family = FontFamily, @@ -82,6 +136,8 @@ public Pango.FontDescription FontDescription { return _fontDescription; } set { + if (Equals (_fontDescription, value)) + return; _fontDescription = value; _fontDescriptionOwned = false; } diff --git a/src/Microsoft.Maui.Graphics.Gtk/Gtk/TextLayoutExtensions.cs b/src/Microsoft.Maui.Graphics.Gtk/Gtk/TextLayoutExtensions.cs index bd7c4ae4..4614ff10 100644 --- a/src/Microsoft.Maui.Graphics.Gtk/Gtk/TextLayoutExtensions.cs +++ b/src/Microsoft.Maui.Graphics.Gtk/Gtk/TextLayoutExtensions.cs @@ -2,15 +2,16 @@ namespace Microsoft.Maui.Graphics.Platform.Gtk { internal static class TextLayoutExtensions { - public static void SetFontStyle(this TextLayout it, IFont font, double? size = null, int? weight = null, FontStyleType? fontStyleType = null) { + public static void SetFontStyle(this TextLayout it, IFont font, double? fontSize = null, int? weight = null, FontStyleType? fontStyleType = null) { - it.FontFamily = font.Name; + if (font is { }) + it.FontFamily = font.Name; if (weight.HasValue) it.Weight = weight.Value.ToPangoWeight(); - if (size.HasValue) - it.PangoFontSize = size.Value.ScaledToPango(); + if (fontSize.HasValue) + it.PangoFontSize = fontSize.Value.ScaledToPango(); if (fontStyleType.HasValue) it.Style = fontStyleType.Value switch