]> Pileus Git - ~andy/gtk/blobdiff - modules/other/gail/gailtextcell.c
Use the correct function to free boxed GdkColors
[~andy/gtk] / modules / other / gail / gailtextcell.c
index eaa774f9083b5f2aa3623de94ee09958597b52e9..f5d7a2afb906317755c56391ae48df06c19d2ab6 100644 (file)
@@ -17,6 +17,8 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include "config.h"
+#include <string.h>
 #include <gtk/gtk.h>
 #include "gailtextcell.h"
 #include "gailcontainercell.h"
@@ -92,14 +94,14 @@ gchar *gail_text_cell_property_list[] = {
   "font_desc",
 
   "attributes",
-  "background_gdk",
+  "background-gdk",
   "editable",
   "family",
-  "foreground_gdk",
+  "foreground-gdk",
   "rise",
   "scale",
   "size",
-  "size_points",
+  "size-points",
   "stretch",
   "strikethrough",
   "style",
@@ -109,19 +111,19 @@ gchar *gail_text_cell_property_list[] = {
   "weight",
 
   /* Also need the sets */
-  "background_set",
-  "editable_set",
-  "family_set",
-  "foreground_set",
-  "rise_set",
-  "scale_set",
-  "size_set",
-  "stretch_set",
-  "strikethrough_set",
-  "style_set",
-  "underline_set",
-  "variant_set",
-  "weight_set",
+  "background-set",
+  "editable-set",
+  "family-set",
+  "foreground-set",
+  "rise-set",
+  "scale-set",
+  "size-set",
+  "stretch-set",
+  "strikethrough-set",
+  "style-set",
+  "underline-set",
+  "variant-set",
+  "weight-set",
   NULL
 };
 
@@ -173,8 +175,7 @@ gail_text_cell_new (void)
   cell = GAIL_RENDERER_CELL(object);
 
   cell->renderer = gtk_cell_renderer_text_new ();
-  g_object_ref (cell->renderer);
-  gtk_object_sink (GTK_OBJECT (cell->renderer));
+  g_object_ref_sink (cell->renderer);
   return atk_object;
 }
 
@@ -221,7 +222,7 @@ gail_text_cell_update_cache (GailRendererCell *cell,
       * value has changed.
       */
       if (new_cache == NULL ||
-          g_strcasecmp (text_cell->cell_text, new_cache))
+          strcmp (text_cell->cell_text, new_cache))
         {
           g_free (text_cell->cell_text);
           temp_length = text_cell->cell_length;
@@ -389,6 +390,7 @@ gail_text_cell_get_run_attributes (AtkText *text,
   PangoLayout *layout;
   AtkObject *parent;
   GtkWidget *widget;
+  gchar *renderer_text;
 
   gail_renderer = GAIL_RENDERER_CELL (text);
   gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
@@ -397,14 +399,16 @@ gail_text_cell_get_run_attributes (AtkText *text,
   if (GAIL_IS_CONTAINER_CELL (parent))
     parent = atk_object_get_parent (parent);
   g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), NULL);
-  widget = GTK_ACCESSIBLE (parent)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
   layout = create_pango_layout (gtk_renderer, widget),
+  g_object_get (gtk_renderer, "text", &renderer_text, NULL);
   attrib_set = gail_misc_layout_get_run_attributes (attrib_set, 
                                                     layout,
-                                                    gtk_renderer->text,
+                                                    renderer_text,
                                                     offset,
                                                     start_offset,
                                                     end_offset);
+  g_free (renderer_text);
   g_object_unref (G_OBJECT (layout));
   
   return attrib_set;
@@ -427,7 +431,7 @@ gail_text_cell_get_default_attributes (AtkText      *text)
   if (GAIL_IS_CONTAINER_CELL (parent))
     parent = atk_object_get_parent (parent);
   g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), NULL);
-  widget = GTK_ACCESSIBLE (parent)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
   layout = create_pango_layout (gtk_renderer, widget),
 
   attrib_set = gail_misc_get_default_attributes (attrib_set, 
@@ -447,71 +451,97 @@ static PangoLayout*
 create_pango_layout(GtkCellRendererText *gtk_renderer,
                     GtkWidget           *widget)
 {
-  PangoAttrList *attr_list;
+  GdkColor *foreground_gdk;
+  PangoAttrList *attr_list, *attributes;
   PangoLayout *layout;
-  PangoUnderline uline;
+  PangoUnderline uline, underline;
   PangoFontMask mask;
-
-  layout = gtk_widget_create_pango_layout (widget, gtk_renderer->text);
-
-  if (gtk_renderer->extra_attrs)
-    attr_list = pango_attr_list_copy (gtk_renderer->extra_attrs);
+  PangoFontDescription *font_desc;
+  gboolean foreground_set, strikethrough_set, strikethrough;
+  gboolean scale_set, underline_set, rise_set;
+  gchar *renderer_text;
+  gdouble scale;
+  gint rise;
+
+  g_object_get (gtk_renderer,
+                "text", &renderer_text,
+                "attributes", &attributes,
+                "foreground-set", &foreground_set,
+                "foreground-gdk", &foreground_gdk,
+                "strikethrough-set", &strikethrough_set,
+                "strikethrough", &strikethrough,
+                "font-desc", &font_desc,
+                "scale-set", &scale_set,
+                "scale", &scale,
+                "underline-set", &underline_set,
+                "underline", &underline,
+                "rise-set", &rise_set,
+                "rise", &rise,
+                NULL);
+
+  layout = gtk_widget_create_pango_layout (widget, renderer_text);
+
+  if (attributes)
+    attr_list = pango_attr_list_copy (attributes);
   else
     attr_list = pango_attr_list_new ();
 
-  if (gtk_renderer->foreground_set)
+  if (foreground_set)
     {
-      PangoColor color;
-      color = gtk_renderer->foreground;
-      add_attr (attr_list, pango_attr_foreground_new (color.red,
-                                                      color.green, color.blue));
+      add_attr (attr_list, pango_attr_foreground_new (foreground_gdk->red,
+                                                      foreground_gdk->green,
+                                                      foreground_gdk->blue));
     }
 
-  if (gtk_renderer->strikethrough_set)
+  if (strikethrough_set)
     add_attr (attr_list,
-              pango_attr_strikethrough_new (gtk_renderer->strikethrough));
+              pango_attr_strikethrough_new (strikethrough));
 
-  mask = pango_font_description_get_set_fields (gtk_renderer->font);
+  mask = pango_font_description_get_set_fields (font_desc);
 
   if (mask & PANGO_FONT_MASK_FAMILY)
     add_attr (attr_list,
-      pango_attr_family_new (pango_font_description_get_family (gtk_renderer->font)));
+      pango_attr_family_new (pango_font_description_get_family (font_desc)));
 
   if (mask & PANGO_FONT_MASK_STYLE)
-    add_attr (attr_list, pango_attr_style_new (pango_font_description_get_style (gtk_renderer->font)));
+    add_attr (attr_list, pango_attr_style_new (pango_font_description_get_style (font_desc)));
 
   if (mask & PANGO_FONT_MASK_VARIANT)
-    add_attr (attr_list, pango_attr_variant_new (pango_font_description_get_variant (gtk_renderer->font)));
+    add_attr (attr_list, pango_attr_variant_new (pango_font_description_get_variant (font_desc)));
 
   if (mask & PANGO_FONT_MASK_WEIGHT)
-    add_attr (attr_list, pango_attr_weight_new (pango_font_description_get_weight (gtk_renderer->font)));
+    add_attr (attr_list, pango_attr_weight_new (pango_font_description_get_weight (font_desc)));
 
   if (mask & PANGO_FONT_MASK_STRETCH)
-    add_attr (attr_list, pango_attr_stretch_new (pango_font_description_get_stretch (gtk_renderer->font)));
+    add_attr (attr_list, pango_attr_stretch_new (pango_font_description_get_stretch (font_desc)));
 
   if (mask & PANGO_FONT_MASK_SIZE)
-    add_attr (attr_list, pango_attr_size_new (pango_font_description_get_size (gtk_renderer->font)));
+    add_attr (attr_list, pango_attr_size_new (pango_font_description_get_size (font_desc)));
 
-  if (gtk_renderer->scale_set &&
-      gtk_renderer->font_scale != 1.0)
-    add_attr (attr_list, pango_attr_scale_new (gtk_renderer->font_scale));
+  if (scale_set && scale != 1.0)
+    add_attr (attr_list, pango_attr_scale_new (scale));
 
-  if (gtk_renderer->underline_set)
-    uline = gtk_renderer->underline_style;
+  if (underline_set)
+    uline = underline;
   else
     uline = PANGO_UNDERLINE_NONE;
 
   if (uline != PANGO_UNDERLINE_NONE)
     add_attr (attr_list,
-      pango_attr_underline_new (gtk_renderer->underline_style));
+              pango_attr_underline_new (underline));
 
-  if (gtk_renderer->rise_set)
-    add_attr (attr_list, pango_attr_rise_new (gtk_renderer->rise));
+  if (rise_set)
+    add_attr (attr_list, pango_attr_rise_new (rise));
 
   pango_layout_set_attributes (layout, attr_list);
   pango_layout_set_width (layout, -1);
   pango_attr_list_unref (attr_list);
 
+  pango_font_description_free (font_desc);
+  pango_attr_list_unref (attributes);
+  g_free (renderer_text);
+  gdk_color_free (foreground_gdk);
+
   return layout;
 }
 
@@ -534,13 +564,17 @@ gail_text_cell_get_character_extents (AtkText          *text,
                                       AtkCoordType     coords)
 {
   GailRendererCell *gail_renderer; 
+  GtkRequisition min_size;
   GtkCellRendererText *gtk_renderer;
   GdkRectangle rendered_rect;
   GtkWidget *widget;
   AtkObject *parent;
   PangoRectangle char_rect;
   PangoLayout *layout;
-  gint x_offset, y_offset, index, cell_height, cell_width;
+  gchar *renderer_text;
+  gfloat xalign, yalign;
+  gint x_offset, y_offset, index;
+  gint xpad, ypad;
 
   if (!GAIL_TEXT_CELL (text)->cell_text)
     {
@@ -557,30 +591,46 @@ gail_text_cell_get_character_extents (AtkText          *text,
   /*
    * Thus would be inconsistent with the cache
    */
-  gail_return_if_fail (gtk_renderer->text);
+  g_object_get (gtk_renderer, "text", &renderer_text, NULL);
+  if (text == NULL)
+    {
+      g_free (renderer_text);
+      return;
+    }
 
   parent = atk_object_get_parent (ATK_OBJECT (text));
   if (GAIL_IS_CONTAINER_CELL (parent))
     parent = atk_object_get_parent (parent);
-  widget = GTK_ACCESSIBLE (parent)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
   g_return_if_fail (GAIL_IS_CELL_PARENT (parent));
   gail_cell_parent_get_cell_area (GAIL_CELL_PARENT (parent), GAIL_CELL (text),
                                   &rendered_rect);
 
-  gtk_cell_renderer_get_size (GTK_CELL_RENDERER (gtk_renderer), widget,
-    &rendered_rect, &x_offset, &y_offset, &cell_width, &cell_height);
+  gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer),
+                                        widget,
+                                        &min_size, NULL);
+
+  gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign);
+  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+    xalign = 1.0 - xalign;
+  x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width));
+  y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height));
+
   layout = create_pango_layout (gtk_renderer, widget);
 
-  index = g_utf8_offset_to_pointer (gtk_renderer->text,
-    offset) - gtk_renderer->text;
-  pango_layout_index_to_pos (layout, index, &char_rect); 
+  index = g_utf8_offset_to_pointer (renderer_text, offset) - renderer_text;
+  pango_layout_index_to_pos (layout, index, &char_rect);
 
+  gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad);
   gail_misc_get_extents_from_pango_rectangle (widget,
       &char_rect,
-      x_offset + rendered_rect.x + gail_renderer->renderer->xpad,
-      y_offset + rendered_rect.y + gail_renderer->renderer->ypad,
+      x_offset + rendered_rect.x + xpad,
+      y_offset + rendered_rect.y + ypad,
       x, y, width, height, coords);
+
+  g_free (renderer_text);
   g_object_unref (layout);
+
   return;
 } 
 
@@ -593,10 +643,14 @@ gail_text_cell_get_offset_at_point (AtkText          *text,
   AtkObject *parent;
   GailRendererCell *gail_renderer; 
   GtkCellRendererText *gtk_renderer;
+  GtkRequisition min_size;
   GtkWidget *widget;
   GdkRectangle rendered_rect;
   PangoLayout *layout;
+  gchar *renderer_text;
+  gfloat xalign, yalign;
   gint x_offset, y_offset, index;
+  gint xpad, ypad;
  
   if (!GAIL_TEXT_CELL (text)->cell_text)
     return -1;
@@ -605,35 +659,65 @@ gail_text_cell_get_offset_at_point (AtkText          *text,
   gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
   parent = atk_object_get_parent (ATK_OBJECT (text));
 
-  g_return_val_if_fail (gtk_renderer->text, -1);
+  g_object_get (gtk_renderer, "text", &renderer_text, NULL);
+  if (text == NULL)
+    {
+      g_free (renderer_text);
+      return -1;
+    }
+
   if (GAIL_IS_CONTAINER_CELL (parent))
     parent = atk_object_get_parent (parent);
 
-  widget = GTK_ACCESSIBLE (parent)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
 
   g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), -1);
   gail_cell_parent_get_cell_area (GAIL_CELL_PARENT (parent), GAIL_CELL (text),
                                   &rendered_rect);
-  gtk_cell_renderer_get_size (GTK_CELL_RENDERER (gtk_renderer), widget,
-     &rendered_rect, &x_offset, &y_offset, NULL, NULL);
+
+  gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer),
+                                        widget,
+                                        &min_size, NULL);
+  gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign);
+  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+    xalign = 1.0 - xalign;
+  x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width));
+  y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height));
 
   layout = create_pango_layout (gtk_renderer, widget);
-   
+
+  gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad);
   index = gail_misc_get_index_at_point_in_layout (widget, layout,
-        x_offset + rendered_rect.x + gail_renderer->renderer->xpad,
-        y_offset + rendered_rect.y + gail_renderer->renderer->ypad,
+        x_offset + rendered_rect.x + xpad,
+        y_offset + rendered_rect.y + ypad,
         x, y, coords);
   g_object_unref (layout);
   if (index == -1)
     {
       if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
-        return g_utf8_strlen (gtk_renderer->text, -1);
-    
+        {
+          glong length;
+
+          length = g_utf8_strlen (renderer_text, -1);
+          g_free (renderer_text);
+
+          return length;
+        }
+
+      g_free (renderer_text);
+
       return index;  
     }
   else
-    return g_utf8_pointer_to_offset (gtk_renderer->text,
-       gtk_renderer->text + index);  
+    {
+      glong offset;
+
+      offset = g_utf8_pointer_to_offset (renderer_text,
+                                         renderer_text + index);
+      g_free (renderer_text);
+
+      return offset;
+    }
 }
 
 static gunichar