[hyena] [Hyena.Gui] TextBlock use CanvasHost's PangoLayout



commit 9d62569120d3e907d901583b86c21c824d562ee7
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Wed Nov 24 11:58:14 2010 -0600

    [Hyena.Gui] TextBlock use CanvasHost's PangoLayout
    
    Instead of each TextBlock instance creating its own.  There are
    rendering issues introduced with this commit due to out-of-order
    Measure/Arrange/Render calls, I imagine.

 Hyena.Gui/Hyena.Data.Gui/CellContext.cs            |    1 +
 Hyena.Gui/Hyena.Data.Gui/ListView/ListViewBase.cs  |    1 +
 .../Hyena.Data.Gui/ListView/ListView_Rendering.cs  |    7 +++-
 Hyena.Gui/Hyena.Gui.Canvas/CanvasHost.cs           |   20 ++++++++++
 Hyena.Gui/Hyena.Gui.Canvas/CanvasManager.cs        |    7 ++--
 Hyena.Gui/Hyena.Gui.Canvas/ICanvasHost.cs          |    2 +
 Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs            |   38 +++++++-------------
 7 files changed, 46 insertions(+), 30 deletions(-)
---
diff --git a/Hyena.Gui/Hyena.Data.Gui/CellContext.cs b/Hyena.Gui/Hyena.Data.Gui/CellContext.cs
index 3bdb05e..e300c20 100644
--- a/Hyena.Gui/Hyena.Data.Gui/CellContext.cs
+++ b/Hyena.Gui/Hyena.Data.Gui/CellContext.cs
@@ -41,6 +41,7 @@ namespace Hyena.Data.Gui
 
         public Cairo.Context Context { get; set; }
         public Pango.Layout Layout { get; set; }
+        public Pango.FontDescription FontDescription { get; set; }
         public Gtk.Widget Widget { get; set; }
         public Gtk.StateType State { get; set; }
         public Gdk.Drawable Drawable { get; set; }
diff --git a/Hyena.Gui/Hyena.Data.Gui/ListView/ListViewBase.cs b/Hyena.Gui/Hyena.Data.Gui/ListView/ListViewBase.cs
index 60af960..0628520 100644
--- a/Hyena.Gui/Hyena.Data.Gui/ListView/ListViewBase.cs
+++ b/Hyena.Gui/Hyena.Data.Gui/ListView/ListViewBase.cs
@@ -70,5 +70,6 @@ namespace Hyena.Data.Gui
         }
 
         public abstract Pango.Layout PangoLayout { get; }
+        public abstract Pango.FontDescription FontDescription { get; }
     }
 }
diff --git a/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs b/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs
index 8918e43..233ab1d 100644
--- a/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs
+++ b/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs
@@ -51,6 +51,10 @@ namespace Hyena.Data.Gui
             get { return cell_context.Layout; }
         }
 
+        public override Pango.FontDescription FontDescription {
+            get { return cell_context.FontDescription; }
+        }
+
         private List<int> selected_rows = new List<int> ();
 
         private Theme theme;
@@ -90,7 +94,7 @@ namespace Hyena.Data.Gui
             Gdk.Drawable drawable = cell_context != null ? cell_context.Drawable : null;
 
             if (pango_layout != null) {
-                pango_layout.FontDescription.Dispose ();
+                cell_context.FontDescription.Dispose ();
                 pango_layout.Dispose ();
                 pango_layout = null;
             }
@@ -133,6 +137,7 @@ namespace Hyena.Data.Gui
 
             cell_context.Context = cairo_context;
             cell_context.Layout = pango_layout;
+            cell_context.FontDescription = pango_layout.FontDescription;
 
             // FIXME: legacy list foo
             if (ViewLayout == null) {
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/CanvasHost.cs b/Hyena.Gui/Hyena.Gui.Canvas/CanvasHost.cs
index 6eb7e1e..1c6c22f 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/CanvasHost.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/CanvasHost.cs
@@ -304,6 +304,26 @@ namespace Hyena.Gui.Canvas
             }
         }
 
+        Pango.Layout layout;
+        public Pango.Layout PangoLayout {
+            get {
+                if (layout == null) {
+                    if (GdkWindow == null || !IsRealized) {
+                        return null;
+                    }
+
+                    using (var cr = Gdk.CairoHelper.Create (GdkWindow)) {
+                        layout = CairoExtensions.CreateLayout (this, cr);
+                        FontDescription = layout.FontDescription;
+                    }
+                }
+
+                return layout;
+            }
+        }
+
+        public Pango.FontDescription FontDescription { get; private set; }
+
         public bool Debug {
             get { return debug; }
             set { debug = value; }
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/CanvasManager.cs b/Hyena.Gui/Hyena.Gui.Canvas/CanvasManager.cs
index eac25e5..db6d68f 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/CanvasManager.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/CanvasManager.cs
@@ -30,9 +30,9 @@ namespace Hyena.Gui.Canvas
 {
     public class CanvasManager
     {
-        private object host;
+        private ICanvasHost host;
 
-        public CanvasManager (object host)
+        public CanvasManager (ICanvasHost host)
         {
             this.host = host;
         }
@@ -49,7 +49,6 @@ namespace Hyena.Gui.Canvas
 
         public void QueueRender (CanvasItem item, Rect rect)
         {
-            ICanvasHost host = Host as ICanvasHost;
             if (host == null) {
                 return;
             }
@@ -57,7 +56,7 @@ namespace Hyena.Gui.Canvas
             host.QueueRender (item, rect);
         }
 
-        public object Host {
+        public ICanvasHost Host {
             get { return host; }
         }
     }
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/ICanvasHost.cs b/Hyena.Gui/Hyena.Gui.Canvas/ICanvasHost.cs
index 9abc395..25a76bb 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/ICanvasHost.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/ICanvasHost.cs
@@ -35,5 +35,7 @@ namespace Hyena.Gui.Canvas
     public interface ICanvasHost
     {
         void QueueRender (CanvasItem item, Rect rect);
+        Pango.Layout PangoLayout { get; }
+        Pango.FontDescription FontDescription { get; }
     }
 }
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs b/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs
index af1a0c6..2631d6f 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs
@@ -49,20 +49,8 @@ namespace Hyena.Gui.Canvas
 
         private bool EnsureLayout ()
         {
-            if (layout != null) {
-                return true;
-            }
-
-            Gtk.Widget widget = Manager == null ? null : Manager.Host as Gtk.Widget;
-            if (widget == null || widget.GdkWindow == null || !widget.IsRealized) {
-                return false;
-            }
-
-            using (var cr = Gdk.CairoHelper.Create (widget.GdkWindow)) {
-                layout = CairoExtensions.CreateLayout (widget, cr);
-                font_desc = layout.FontDescription;
-            }
-
+            layout = Manager.Host.PangoLayout;
+            font_desc = Manager.Host.FontDescription;
             return layout != null;
         }
 
@@ -76,15 +64,8 @@ namespace Hyena.Gui.Canvas
 
             int text_w, text_h;
 
-            TextWrap wrap = TextWrap;
-            layout.Width = wrap == TextWrap.None ? -1 : (int)(Pango.Scale.PangoScale * (available.Width - Margin.X));
-            layout.Wrap = GetPangoWrapMode (wrap);
-            font_desc.Weight = GetPangoFontWeight (FontWeight);
-            layout.SingleParagraphMode = wrap == TextWrap.None;
-            layout.Ellipsize = EllipsizeMode;
-            
             // Update layout
-            UpdateLayoutText (GetText ());
+            UpdateLayout (GetText (), available.Width);
 
             layout.GetPixelSize (out text_w, out text_h);
 
@@ -107,7 +88,7 @@ namespace Hyena.Gui.Canvas
             return size;
         }
 
-        private void UpdateLayoutText (string text)
+        private void UpdateLayout (string text, double width)
         {
             if (text == last_text) {
                 return;
@@ -120,6 +101,13 @@ namespace Hyena.Gui.Canvas
                 last_formatted_text = last_formatted_text.Replace ("\r\n", "\x20").Replace ('\n', '\x20').Replace ('\r', '\x20');
             }
 
+            TextWrap wrap = TextWrap;
+            layout.Width = wrap == TextWrap.None ? -1 : (int)(Pango.Scale.PangoScale * (width - Margin.X));
+            layout.Wrap = GetPangoWrapMode (wrap);
+            font_desc.Weight = GetPangoFontWeight (FontWeight);
+            layout.SingleParagraphMode = wrap == TextWrap.None;
+            layout.Ellipsize = EllipsizeMode;
+
             if (UseMarkup) {
                 layout.SetMarkup (last_formatted_text);
             } else {
@@ -196,11 +184,11 @@ namespace Hyena.Gui.Canvas
 
         protected override void ClippedRender (Hyena.Data.Gui.CellContext context)
         {
-            var cr = context.Context;
             if (!EnsureLayout ()) {
                 return;
             }
 
+            var cr = context.Context;
             Foreground = new Brush (context.Theme.Colors.GetWidgetColor (
                 context.TextAsForeground ? GtkColorClass.Foreground : GtkColorClass.Text, context.State));
 
@@ -220,7 +208,7 @@ namespace Hyena.Gui.Canvas
 
             cr.MoveTo (text_alloc.X, text_alloc.Y);
             Foreground.Apply (cr);
-            UpdateLayoutText (GetText ());
+            UpdateLayout (GetText (), RenderSize.Width);
             Pango.CairoHelper.ShowLayout (cr, layout);
             cr.Fill ();
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]