[hamster-applet/gnome-2-26] use layout to set text instead of the cairo not suggested show_text. fixes bug 585420



commit 47ca98014276fe73314abd10366f1e9b6c835650
Author: Toms Bauģis <toms baugis gmail com>
Date:   Thu Jun 11 13:38:42 2009 +0100

    use layout to set text instead of the cairo not suggested show_text. fixes bug 585420
---
 hamster/charting.py |  111 +++++++++++++++++++++++++++++++--------------------
 1 files changed, 68 insertions(+), 43 deletions(-)

diff --git a/hamster/charting.py b/hamster/charting.py
index 657fad6..49b4608 100644
--- a/hamster/charting.py
+++ b/hamster/charting.py
@@ -53,7 +53,7 @@ Example:
 
 import gtk
 import gobject
-import cairo
+import cairo, pango
 import copy
 import math
 
@@ -139,13 +139,19 @@ class Chart(gtk.DrawingArea):
         self.animation_timeout = 20 #in miliseconds
 
         self.current_frame = self.animation_frames
-        self.freeze_animation = False
+        self.freeze_animation = False        
+        self.layout = None #pango text layout
         
     def _expose(self, widget, event): # expose is when drawing's going on
         context = widget.window.cairo_create()
         context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
         context.clip()
         
+        self.layout = context.create_layout()
+        default_font = pango.FontDescription(gtk.Style().font_desc.to_string())
+        default_font.set_size(8 * pango.SCALE)
+        self.layout.set_font_description(default_font)
+
         if self.orient_vertical:
             # for simple bars figure, when there is way too much data for bars
             # and go to lines (yay!)
@@ -417,21 +423,27 @@ class Chart(gtk.DrawingArea):
 
         # scale labels
         set_color_gdk(context, self.style.fg[gtk.STATE_NORMAL]);
+        self.layout.set_width(-1)
+
         for i in range(records):
-            extent = context.text_extents(data[i]["label"]) #x, y, width, height
-            context.move_to(graph_x + (step * i) + (step - extent[2]) / 2.0,
-                            graph_y + graph_height + 13)
-            context.show_text(data[i]["label"])
+            self.layout.set_text(data[i]["label"])
+            label_w, label_h = self.layout.get_pixel_size()
+            context.move_to(graph_x + (step * i) + (step - label_w) / 2.0,
+                            graph_y + graph_height + 2)
+
+            self.layout.set_text(data[i]["label"])
+
+            context.show_layout(self.layout)
 
         # values for max min and average
         max_label = "%d" % self.max
         if self.there_are_floats:
             max_label = "%.1f" % self.max
 
-        extent = context.text_extents(max_label) #x, y, width, height
-
-        context.move_to(graph_x - extent[2] - 16, rect.y + 10)
-        context.show_text(max_label)
+        self.layout.set_text(max_label)
+        label_w, label_h = self.layout.get_pixel_size()
+        context.move_to(graph_x - label_w - 16, rect.y)
+        context.show_layout(self.layout)
 
 
         #flip the matrix vertically, so we do not have to think upside-down
@@ -474,40 +486,45 @@ class Chart(gtk.DrawingArea):
                     label = "%.1f" % data[i]["value"]
                 else:
                     label = "%d" % data[i]["value"]
-                extent = context.text_extents(label) #x, y, width, height
+                    
+                self.layout.set_text(label)
+                label_w, label_h = self.layout.get_pixel_size()
                 
                 bar_size = graph_height * data[i]["factor"]
-                
                 if self.animate:
                     bar_size = bar_size * 0.8
                 else:
                     bar_size = bar_size * 0.9
                     
-                vertical_offset = (step - extent[2]) / 2.0
+                vertical_offset = (step - label_h) / 2.0
                 
-                if self.animate or bar_size - vertical_offset < extent[3]:
-                    graph_y = -bar_size - 3
+                if self.animate or bar_size - vertical_offset < label_h:
+                   graph_y = -bar_size - label_h
                 else:
-                    graph_y = -bar_size + extent[3] + vertical_offset
+                    graph_y = - bar_size - label_h + vertical_offset + 3
                 
-                context.move_to(graph_x + (step * i) + (step - extent[2]) / 2.0,
+                context.move_to(graph_x + (step * i) + (step - label_w) / 2.0,
                                 graph_y)
-                context.show_text(label)
+                context.show_layout(self.layout)
 
 
     def _ellipsize_text (self, context, text, width):
         """try to constrain text into pixels by ellipsizing end
            TODO - check if cairo maybe has ability to ellipsize automatically
         """
-        extent = context.text_extents(text) #x, y, width, height
-        if extent[2] <= width:
+        self.layout.set_text(text)
+        label_w, label_h = self.layout.get_pixel_size()
+
+        if label_w <= width:
             return text
         
         res = text
         while res:
             res = res[:-1]
-            extent = context.text_extents(res + "â?¦") #x, y, width, height
-            if extent[2] <= width:
+
+            self.layout.set_text(text + "â?¦")
+            label_w, label_h = self.layout.get_pixel_size()
+            if label_w <= width:
                 return res + "â?¦"
         
         return text # if can't fit - return what we have
@@ -523,8 +540,9 @@ class Chart(gtk.DrawingArea):
         else:
             max_extent = 0
             for i in range(records):
-                extent = context.text_extents(data[i]["label"]) #x, y, width, height
-                max_extent = max(max_extent, extent[2] + 8)
+                self.layout.set_text(data[i]["label"])
+                label_w, label_h = self.layout.get_pixel_size()
+                max_extent = max(max_extent, label_w + 8)
         
         
         #push graph to the right, so it doesn't overlap, and add little padding aswell
@@ -551,15 +569,18 @@ class Chart(gtk.DrawingArea):
         ellipsize_label = lambda(text): 3
 
         # now let's put scale labels and align them right
-        set_color_gdk(context, self.style.fg[gtk.STATE_NORMAL]);
+        set_color_gdk(context, self.style.fg[gtk.STATE_NORMAL])
         for i in range(records):
             label = data[i]["label"]
             if self.legend_width:
                 label = self._ellipsize_text(context, label, max_extent - 8)
-            extent = context.text_extents(label) #x, y, width, height
+                
+            self.layout.set_text(label)
+            label_w, label_h = self.layout.get_pixel_size()
             
-            context.move_to(rect.x + max_extent - extent[2] - 8, rect.y + (step * i) + (step + extent[3]) / 2)
-            context.show_text(label)
+            context.move_to(rect.x + max_extent - label_w - 8,
+                            rect.y + (step * i) + (step - label_h) / 2)
+            context.show_layout(self.layout)
         
         context.stroke()        
         
@@ -624,18 +645,21 @@ class Chart(gtk.DrawingArea):
                     label = "%.1f" % data[i]["value"]
                 else:
                     label = "%d" % data[i]["value"]
-                extent = context.text_extents(label) #x, y, width, height
+                    
+                self.layout.set_text(label)
+                label_w, label_h = self.layout.get_pixel_size()
                 
                 bar_size = max_size * data[i]["factor"]
-                horizontal_offset = (step + extent[3]) / 2.0 - extent[3]
+                horizontal_offset = (step - label_h) / 2.0
                 
-                if  bar_size - horizontal_offset < extent[2]:
+                if  bar_size - horizontal_offset < label_w:
                     label_x = graph_x + bar_size + horizontal_offset
                 else:
-                    label_x = graph_x + bar_size - extent[2] - horizontal_offset
+                    label_x = graph_x + bar_size - label_w - horizontal_offset
                 
-                context.move_to(label_x, graph_y + (step * i) + (step + extent[3]) / 2.0)
-                context.show_text(label)
+                context.move_to(label_x,
+                                graph_y + (step * i) + (step - label_h) / 2.0)
+                context.show_layout(self.layout)
 
         else:
             # values for max min and average
@@ -645,7 +669,8 @@ class Chart(gtk.DrawingArea):
             else:
                 max_label = "%d" % self.max
                 
-            context.show_text(max_label)
+            self.layout.set_text(max_label)
+            context.show_layout(self.layout)
         
         
     def _area_chart(self, context):
@@ -717,20 +742,20 @@ class Chart(gtk.DrawingArea):
         set_color_gdk(context, self.style.fg[gtk.STATE_NORMAL]);
         for i in range(records):
             if i % 5 == 0:
-                context.move_to(graph_x + 5 + (step * i), graph_y + graph_height + 13)
-                context.show_text(data[i]["label"])
+                context.move_to(graph_x + 5 + (step * i), graph_y + graph_height + 3)
+                self.layout.set_text(data[i]["label"])
+                context.show_layout(self.layout)
 
         # values for max min and average
         if self.there_are_floats:
             max_label = "%.1f" % self.max
         else:
             max_label = "%d" % self.max
-            
-        extent = context.text_extents(max_label) #x, y, width, height
-
-        context.move_to(graph_x - extent[2] - 16, rect.y + 10)
-        context.show_text(max_label)
-
+        
+        self.layout.set_text(max_label)
+        label_w, label_h = self.layout.get_pixel_size()
+        context.move_to(graph_x - label_w - 16, rect.y)
+        context.show_layout(self.layout)
 
         context.rectangle(graph_x, graph_y, graph_width, graph_height + 1)
         context.clip()



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