Various tiny semantic changes in here. The big fix is that we consider every cell as visible and as showing if the treeview is mapped. This was also fixed in the tree dump test.
		
			
				
	
	
		
			817 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			817 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* GAIL - The GNOME Accessibility Enabling Library
 | 
						|
 * Copyright 2001 Sun Microsystems Inc.
 | 
						|
 *
 | 
						|
 * This library is free software; you can redistribute it and/or
 | 
						|
 * modify it under the terms of the GNU Lesser General Public
 | 
						|
 * License as published by the Free Software Foundation; either
 | 
						|
 * version 2 of the License, or (at your option) any later version.
 | 
						|
 *
 | 
						|
 * This library is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
 * Lesser General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU Lesser General Public
 | 
						|
 * License along with this library; if not, write to the
 | 
						|
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
						|
 * Boston, MA 02111-1307, USA.
 | 
						|
 */
 | 
						|
 | 
						|
#include "config.h"
 | 
						|
 | 
						|
#include <gtk/gtk.h>
 | 
						|
#include "../gtkpango.h"
 | 
						|
#include "gtktextcellaccessible.h"
 | 
						|
#include "gtkcontainercellaccessible.h"
 | 
						|
#include "gtkcellaccessibleparent.h"
 | 
						|
 | 
						|
static const gchar* gtk_text_cell_accessible_get_name    (AtkObject      *atk_obj);
 | 
						|
 | 
						|
 | 
						|
/* atktext.h */
 | 
						|
 | 
						|
static gchar*    gtk_text_cell_accessible_get_text                (AtkText        *text,
 | 
						|
                                                        gint            start_pos,
 | 
						|
                                                        gint            end_pos);
 | 
						|
static gunichar gtk_text_cell_accessible_get_character_at_offset  (AtkText        *text,
 | 
						|
                                                         gint           offset);
 | 
						|
static gchar*   gtk_text_cell_accessible_get_text_before_offset   (AtkText        *text,
 | 
						|
                                                         gint           offset,
 | 
						|
                                                         AtkTextBoundary boundary_type,
 | 
						|
                                                         gint           *start_offset,
 | 
						|
                                                         gint           *end_offset);
 | 
						|
static gchar*   gtk_text_cell_accessible_get_text_at_offset       (AtkText        *text,
 | 
						|
                                                         gint           offset,
 | 
						|
                                                         AtkTextBoundary boundary_type,
 | 
						|
                                                         gint           *start_offset,
 | 
						|
                                                         gint           *end_offset);
 | 
						|
static gchar*   gtk_text_cell_accessible_get_text_after_offset    (AtkText        *text,
 | 
						|
                                                         gint           offset,
 | 
						|
                                                         AtkTextBoundary boundary_type,
 | 
						|
                                                         gint           *start_offset,
 | 
						|
                                                         gint           *end_offset);
 | 
						|
static gint      gtk_text_cell_accessible_get_character_count     (AtkText        *text);
 | 
						|
static gint      gtk_text_cell_accessible_get_caret_offset        (AtkText        *text);
 | 
						|
static gboolean  gtk_text_cell_accessible_set_caret_offset        (AtkText        *text,
 | 
						|
                                                         gint           offset);
 | 
						|
static void      gtk_text_cell_accessible_get_character_extents   (AtkText        *text,
 | 
						|
                                                         gint           offset,
 | 
						|
                                                         gint           *x,
 | 
						|
                                                         gint           *y,
 | 
						|
                                                         gint           *width,
 | 
						|
                                                         gint           *height,
 | 
						|
                                                         AtkCoordType   coords);
 | 
						|
static gint      gtk_text_cell_accessible_get_offset_at_point     (AtkText        *text,
 | 
						|
                                                         gint           x,
 | 
						|
                                                         gint           y,
 | 
						|
                                                         AtkCoordType   coords);
 | 
						|
static AtkAttributeSet* gtk_text_cell_accessible_get_run_attributes 
 | 
						|
                                                        (AtkText        *text,
 | 
						|
                                                         gint           offset,
 | 
						|
                                                         gint           *start_offset,      
 | 
						|
                                                         gint           *end_offset); 
 | 
						|
static AtkAttributeSet* gtk_text_cell_accessible_get_default_attributes 
 | 
						|
                                                        (AtkText        *text);
 | 
						|
 | 
						|
static GtkWidget*       get_widget                      (GtkTextCellAccessible *cell);
 | 
						|
static PangoLayout*     create_pango_layout             (GtkTextCellAccessible *cell);
 | 
						|
static void             add_attr                        (PangoAttrList  *attr_list,
 | 
						|
                                                         PangoAttribute *attr);
 | 
						|
 | 
						|
/* Misc */
 | 
						|
 | 
						|
static gboolean gtk_text_cell_accessible_update_cache             (GtkRendererCellAccessible *cell,
 | 
						|
                                                         gboolean       emit_change_signal);
 | 
						|
 | 
						|
static gchar *property_list[] = {
 | 
						|
  /* Set font_desc first since it resets other values if it is NULL */
 | 
						|
  "font-desc",
 | 
						|
  "attributes",
 | 
						|
  "background-gdk",
 | 
						|
  "editable",
 | 
						|
  "family",
 | 
						|
  "foreground-gdk",
 | 
						|
  "rise",
 | 
						|
  "scale",
 | 
						|
  "size",
 | 
						|
  "size-points",
 | 
						|
  "stretch",
 | 
						|
  "strikethrough",
 | 
						|
  "style",
 | 
						|
  "text",
 | 
						|
  "underline",
 | 
						|
  "variant",
 | 
						|
  "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",
 | 
						|
  NULL
 | 
						|
};
 | 
						|
 | 
						|
static void atk_text_interface_init (AtkTextIface *iface);
 | 
						|
 | 
						|
G_DEFINE_TYPE_WITH_CODE (GtkTextCellAccessible, _gtk_text_cell_accessible, GTK_TYPE_RENDERER_CELL_ACCESSIBLE,
 | 
						|
                         G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
 | 
						|
 | 
						|
static AtkStateSet *
 | 
						|
gtk_text_cell_accessible_ref_state_set (AtkObject *accessible)
 | 
						|
{
 | 
						|
  AtkStateSet *state_set;
 | 
						|
 | 
						|
  state_set = ATK_OBJECT_CLASS (_gtk_text_cell_accessible_parent_class)->ref_state_set (accessible);
 | 
						|
 | 
						|
  atk_state_set_add_state (state_set, ATK_STATE_SINGLE_LINE);
 | 
						|
 | 
						|
  return state_set;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
gtk_text_cell_accessible_finalize (GObject *object)
 | 
						|
{
 | 
						|
  GtkTextCellAccessible *text_cell = GTK_TEXT_CELL_ACCESSIBLE (object);
 | 
						|
 | 
						|
  g_free (text_cell->cell_text);
 | 
						|
 | 
						|
  G_OBJECT_CLASS (_gtk_text_cell_accessible_parent_class)->finalize (object);
 | 
						|
}
 | 
						|
 | 
						|
static const gchar *
 | 
						|
gtk_text_cell_accessible_get_name (AtkObject *atk_obj)
 | 
						|
{
 | 
						|
  GtkTextCellAccessible *text_cell = GTK_TEXT_CELL_ACCESSIBLE (atk_obj);
 | 
						|
 | 
						|
  if (atk_obj->name)
 | 
						|
    return atk_obj->name;
 | 
						|
 | 
						|
  return text_cell->cell_text;
 | 
						|
}
 | 
						|
 | 
						|
static gboolean
 | 
						|
gtk_text_cell_accessible_update_cache (GtkRendererCellAccessible *cell,
 | 
						|
                                       gboolean                   emit_change_signal)
 | 
						|
{
 | 
						|
  GtkTextCellAccessible *text_cell = GTK_TEXT_CELL_ACCESSIBLE (cell);
 | 
						|
  AtkObject *obj = ATK_OBJECT (cell);
 | 
						|
  gboolean rv = FALSE;
 | 
						|
  gint temp_length;
 | 
						|
  gchar *text;
 | 
						|
 | 
						|
  g_object_get (G_OBJECT (cell->renderer), "text", &text, NULL);
 | 
						|
 | 
						|
  if (text_cell->cell_text)
 | 
						|
    {
 | 
						|
      if (text == NULL || g_strcmp0 (text_cell->cell_text, text) != 0)
 | 
						|
        {
 | 
						|
          g_free (text_cell->cell_text);
 | 
						|
          temp_length = text_cell->cell_length;
 | 
						|
          text_cell->cell_text = NULL;
 | 
						|
          text_cell->cell_length = 0;
 | 
						|
          if (emit_change_signal)
 | 
						|
            {
 | 
						|
              g_signal_emit_by_name (cell, "text-changed::delete", 0, temp_length);
 | 
						|
              if (obj->name == NULL)
 | 
						|
                g_object_notify (G_OBJECT (obj), "accessible-name");
 | 
						|
            }
 | 
						|
          if (text)
 | 
						|
            rv = TRUE;
 | 
						|
        }
 | 
						|
    }
 | 
						|
  else
 | 
						|
    rv = TRUE;
 | 
						|
 | 
						|
  if (rv)
 | 
						|
    {
 | 
						|
      if (text == NULL)
 | 
						|
        {
 | 
						|
          text_cell->cell_text = g_strdup ("");
 | 
						|
          text_cell->cell_length = 0;
 | 
						|
        }
 | 
						|
      else
 | 
						|
        {
 | 
						|
          text_cell->cell_text = g_strdup (text);
 | 
						|
          text_cell->cell_length = g_utf8_strlen (text, -1);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
  g_free (text);
 | 
						|
 | 
						|
  if (rv)
 | 
						|
    {
 | 
						|
      if (emit_change_signal)
 | 
						|
        {
 | 
						|
          g_signal_emit_by_name (cell, "text-changed::insert",
 | 
						|
                                 0, text_cell->cell_length);
 | 
						|
 | 
						|
          if (obj->name == NULL)
 | 
						|
            g_object_notify (G_OBJECT (obj), "accessible-name");
 | 
						|
        }
 | 
						|
    }
 | 
						|
  return rv;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
_gtk_text_cell_accessible_class_init (GtkTextCellAccessibleClass *klass)
 | 
						|
{
 | 
						|
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
						|
  AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
 | 
						|
  GtkRendererCellAccessibleClass *renderer_cell_class = GTK_RENDERER_CELL_ACCESSIBLE_CLASS (klass);
 | 
						|
 | 
						|
  renderer_cell_class->update_cache = gtk_text_cell_accessible_update_cache;
 | 
						|
  renderer_cell_class->property_list = property_list;
 | 
						|
 | 
						|
  atk_object_class->get_name = gtk_text_cell_accessible_get_name;
 | 
						|
  atk_object_class->ref_state_set = gtk_text_cell_accessible_ref_state_set;
 | 
						|
 | 
						|
  gobject_class->finalize = gtk_text_cell_accessible_finalize;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
_gtk_text_cell_accessible_init (GtkTextCellAccessible *text_cell)
 | 
						|
{
 | 
						|
  text_cell->cell_text = NULL;
 | 
						|
  text_cell->caret_pos = 0;
 | 
						|
  text_cell->cell_length = 0;
 | 
						|
}
 | 
						|
 | 
						|
AtkObject *
 | 
						|
_gtk_text_cell_accessible_new (void)
 | 
						|
{
 | 
						|
  GObject *object;
 | 
						|
  AtkObject *atk_object;
 | 
						|
  GtkRendererCellAccessible *cell;
 | 
						|
 | 
						|
  object = g_object_new (GTK_TYPE_TEXT_CELL_ACCESSIBLE, NULL);
 | 
						|
 | 
						|
  g_return_val_if_fail (object != NULL, NULL);
 | 
						|
 | 
						|
  atk_object = ATK_OBJECT (object);
 | 
						|
  atk_object->role = ATK_ROLE_TABLE_CELL;
 | 
						|
 | 
						|
  cell = GTK_RENDERER_CELL_ACCESSIBLE(object);
 | 
						|
 | 
						|
  cell->renderer = gtk_cell_renderer_text_new ();
 | 
						|
  g_object_ref_sink (cell->renderer);
 | 
						|
 | 
						|
  return atk_object;
 | 
						|
}
 | 
						|
 | 
						|
static gchar *
 | 
						|
gtk_text_cell_accessible_get_text (AtkText *atk_text,
 | 
						|
                                   gint     start_pos,
 | 
						|
                                   gint     end_pos)
 | 
						|
{
 | 
						|
  gchar *text;
 | 
						|
 | 
						|
  text = GTK_TEXT_CELL_ACCESSIBLE (atk_text)->cell_text;
 | 
						|
  if (text)
 | 
						|
    return g_utf8_substring (text, start_pos, end_pos > -1 ? end_pos : g_utf8_strlen (text, -1));
 | 
						|
  else
 | 
						|
    return g_strdup ("");
 | 
						|
}
 | 
						|
 | 
						|
static gchar *
 | 
						|
gtk_text_cell_accessible_get_text_before_offset (AtkText         *atk_text,
 | 
						|
                                                 gint             offset,
 | 
						|
                                                 AtkTextBoundary  boundary_type,
 | 
						|
                                                 gint            *start_offset,
 | 
						|
                                                 gint            *end_offset)
 | 
						|
{
 | 
						|
  PangoLayout *layout;
 | 
						|
  gchar *text;
 | 
						|
 | 
						|
  layout = create_pango_layout (GTK_TEXT_CELL_ACCESSIBLE (atk_text));
 | 
						|
  text = _gtk_pango_get_text_before (layout, boundary_type, offset, start_offset, end_offset);
 | 
						|
  g_object_unref (layout);
 | 
						|
 | 
						|
  return text;
 | 
						|
}
 | 
						|
 | 
						|
static gchar *
 | 
						|
gtk_text_cell_accessible_get_text_at_offset (AtkText         *atk_text,
 | 
						|
                                             gint             offset,
 | 
						|
                                             AtkTextBoundary  boundary_type,
 | 
						|
                                             gint            *start_offset,
 | 
						|
                                             gint            *end_offset)
 | 
						|
{
 | 
						|
  PangoLayout *layout;
 | 
						|
  gchar *text;
 | 
						|
 | 
						|
  layout = create_pango_layout (GTK_TEXT_CELL_ACCESSIBLE (atk_text));
 | 
						|
  text = _gtk_pango_get_text_at (layout, boundary_type, offset, start_offset, end_offset);
 | 
						|
  g_object_unref (layout);
 | 
						|
 | 
						|
  return text;
 | 
						|
}
 | 
						|
 | 
						|
static gchar *
 | 
						|
gtk_text_cell_accessible_get_text_after_offset (AtkText         *atk_text,
 | 
						|
                                                gint             offset,
 | 
						|
                                                AtkTextBoundary  boundary_type,
 | 
						|
                                                gint            *start_offset,
 | 
						|
                                                gint            *end_offset)
 | 
						|
{
 | 
						|
  PangoLayout *layout;
 | 
						|
  gchar *text;
 | 
						|
 | 
						|
  layout = create_pango_layout (GTK_TEXT_CELL_ACCESSIBLE (atk_text));
 | 
						|
  text = _gtk_pango_get_text_after (layout, boundary_type, offset, start_offset, end_offset);
 | 
						|
  g_object_unref (layout);
 | 
						|
 | 
						|
  return text;
 | 
						|
}
 | 
						|
 | 
						|
static gint
 | 
						|
gtk_text_cell_accessible_get_character_count (AtkText *text)
 | 
						|
{
 | 
						|
  if (GTK_TEXT_CELL_ACCESSIBLE (text)->cell_text != NULL)
 | 
						|
    return GTK_TEXT_CELL_ACCESSIBLE (text)->cell_length;
 | 
						|
  else
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static gint
 | 
						|
gtk_text_cell_accessible_get_caret_offset (AtkText *text)
 | 
						|
{
 | 
						|
  return GTK_TEXT_CELL_ACCESSIBLE (text)->caret_pos;
 | 
						|
}
 | 
						|
 | 
						|
static gboolean
 | 
						|
gtk_text_cell_accessible_set_caret_offset (AtkText *text,
 | 
						|
                                           gint     offset)
 | 
						|
{
 | 
						|
  GtkTextCellAccessible *text_cell = GTK_TEXT_CELL_ACCESSIBLE (text);
 | 
						|
 | 
						|
  if (text_cell->cell_text == NULL)
 | 
						|
    return FALSE;
 | 
						|
  else
 | 
						|
    {
 | 
						|
      /* Only set the caret within the bounds and if it is to a new position. */
 | 
						|
      if (offset >= 0 &&
 | 
						|
          offset <= text_cell->cell_length &&
 | 
						|
          offset != text_cell->caret_pos)
 | 
						|
        {
 | 
						|
          text_cell->caret_pos = offset;
 | 
						|
 | 
						|
          /* emit the signal */
 | 
						|
          g_signal_emit_by_name (text, "text-caret-moved", offset);
 | 
						|
          return TRUE;
 | 
						|
        }
 | 
						|
      else
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static AtkAttributeSet *
 | 
						|
gtk_text_cell_accessible_get_run_attributes (AtkText *text,
 | 
						|
                                             gint     offset,
 | 
						|
                                             gint    *start_offset,
 | 
						|
                                             gint    *end_offset)
 | 
						|
{
 | 
						|
  AtkAttributeSet *attrib_set = NULL;
 | 
						|
  PangoLayout *layout;
 | 
						|
 | 
						|
  layout = create_pango_layout (GTK_TEXT_CELL_ACCESSIBLE (text));
 | 
						|
  attrib_set = _gtk_pango_get_run_attributes  (NULL, layout, offset, start_offset, end_offset);
 | 
						|
  g_object_unref (G_OBJECT (layout));
 | 
						|
 | 
						|
  return attrib_set;
 | 
						|
}
 | 
						|
 | 
						|
static AtkAttributeSet *
 | 
						|
add_attribute (AtkAttributeSet  *attributes,
 | 
						|
               AtkTextAttribute  attr,
 | 
						|
               const gchar      *value)
 | 
						|
{
 | 
						|
  AtkAttribute *at;
 | 
						|
 | 
						|
  at = g_new (AtkAttribute, 1);
 | 
						|
  at->name = g_strdup (atk_text_attribute_get_name (attr));
 | 
						|
  at->value = g_strdup (value);
 | 
						|
 | 
						|
  return g_slist_prepend (attributes, at);
 | 
						|
}
 | 
						|
 | 
						|
static AtkAttributeSet *
 | 
						|
gtk_text_cell_accessible_get_default_attributes (AtkText *text)
 | 
						|
{
 | 
						|
  AtkAttributeSet *attrib_set = NULL;
 | 
						|
  PangoLayout *layout;
 | 
						|
  GtkWidget *widget;
 | 
						|
 | 
						|
  layout = create_pango_layout (GTK_TEXT_CELL_ACCESSIBLE (text));
 | 
						|
  widget = get_widget (GTK_TEXT_CELL_ACCESSIBLE (text));
 | 
						|
 | 
						|
  attrib_set = add_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION,
 | 
						|
                   atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION,
 | 
						|
                                                 gtk_widget_get_direction (widget)));
 | 
						|
  attrib_set = _gtk_pango_get_default_attributes (NULL, layout);
 | 
						|
 | 
						|
  attrib_set = _gtk_style_context_get_attributes (attrib_set,
 | 
						|
                                                  gtk_widget_get_style_context (widget),
 | 
						|
                                                  gtk_widget_get_state_flags (widget));
 | 
						|
 | 
						|
  g_object_unref (G_OBJECT (layout));
 | 
						|
 | 
						|
  return attrib_set;
 | 
						|
}
 | 
						|
 | 
						|
GtkWidget *
 | 
						|
get_widget (GtkTextCellAccessible *text)
 | 
						|
{
 | 
						|
  AtkObject *parent;
 | 
						|
 | 
						|
  parent = atk_object_get_parent (ATK_OBJECT (text));
 | 
						|
  if (GTK_IS_CONTAINER_CELL_ACCESSIBLE (parent))
 | 
						|
    parent = atk_object_get_parent (parent);
 | 
						|
 | 
						|
  return gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
 | 
						|
}
 | 
						|
 | 
						|
/* This function is used by gtk_text_cell_accessible_get_offset_at_point()
 | 
						|
 * and gtk_text_cell_accessible_get_character_extents(). There is no
 | 
						|
 * cached PangoLayout so we must create a temporary one using this function.
 | 
						|
 */
 | 
						|
static PangoLayout *
 | 
						|
create_pango_layout (GtkTextCellAccessible *text)
 | 
						|
{
 | 
						|
  GdkRGBA *foreground_rgba;
 | 
						|
  PangoAttrList *attr_list, *attributes;
 | 
						|
  PangoLayout *layout;
 | 
						|
  PangoUnderline uline, underline;
 | 
						|
  PangoFontMask mask;
 | 
						|
  PangoFontDescription *font_desc;
 | 
						|
  gboolean foreground_set, strikethrough_set, strikethrough;
 | 
						|
  gboolean scale_set, underline_set, rise_set;
 | 
						|
  gchar *renderer_text;
 | 
						|
  gdouble scale;
 | 
						|
  gint rise;
 | 
						|
  GtkRendererCellAccessible *gail_renderer;
 | 
						|
  GtkCellRendererText *gtk_renderer;
 | 
						|
 | 
						|
  gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text);
 | 
						|
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
 | 
						|
 | 
						|
  g_object_get (gtk_renderer,
 | 
						|
                "text", &renderer_text,
 | 
						|
                "attributes", &attributes,
 | 
						|
                "foreground-set", &foreground_set,
 | 
						|
                "foreground-rgba", &foreground_rgba,
 | 
						|
                "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 (get_widget (text), renderer_text);
 | 
						|
 | 
						|
  if (attributes)
 | 
						|
    attr_list = pango_attr_list_copy (attributes);
 | 
						|
  else
 | 
						|
    attr_list = pango_attr_list_new ();
 | 
						|
 | 
						|
  if (foreground_set)
 | 
						|
    {
 | 
						|
      add_attr (attr_list, pango_attr_foreground_new (foreground_rgba->red * 65535,
 | 
						|
                                                      foreground_rgba->green * 65535,
 | 
						|
                                                      foreground_rgba->blue * 65535));
 | 
						|
    }
 | 
						|
 | 
						|
  if (strikethrough_set)
 | 
						|
    add_attr (attr_list,
 | 
						|
              pango_attr_strikethrough_new (strikethrough));
 | 
						|
 | 
						|
  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 (font_desc)));
 | 
						|
 | 
						|
  if (mask & PANGO_FONT_MASK_STYLE)
 | 
						|
    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 (font_desc)));
 | 
						|
 | 
						|
  if (mask & PANGO_FONT_MASK_WEIGHT)
 | 
						|
    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 (font_desc)));
 | 
						|
 | 
						|
  if (mask & PANGO_FONT_MASK_SIZE)
 | 
						|
    add_attr (attr_list, pango_attr_size_new (pango_font_description_get_size (font_desc)));
 | 
						|
 | 
						|
  if (scale_set && scale != 1.0)
 | 
						|
    add_attr (attr_list, pango_attr_scale_new (scale));
 | 
						|
 | 
						|
  if (underline_set)
 | 
						|
    uline = underline;
 | 
						|
  else
 | 
						|
    uline = PANGO_UNDERLINE_NONE;
 | 
						|
 | 
						|
  if (uline != PANGO_UNDERLINE_NONE)
 | 
						|
    add_attr (attr_list,
 | 
						|
              pango_attr_underline_new (underline));
 | 
						|
 | 
						|
  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_rgba_free (foreground_rgba);
 | 
						|
 | 
						|
  return layout;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
add_attr (PangoAttrList *attr_list,
 | 
						|
         PangoAttribute *attr)
 | 
						|
{
 | 
						|
  attr->start_index = 0;
 | 
						|
  attr->end_index = G_MAXINT;
 | 
						|
  pango_attr_list_insert (attr_list, attr);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void
 | 
						|
get_origins (GtkWidget *widget,
 | 
						|
             gint      *x_window,
 | 
						|
             gint      *y_window,
 | 
						|
             gint      *x_toplevel,
 | 
						|
             gint      *y_toplevel)
 | 
						|
{
 | 
						|
  GdkWindow *window;
 | 
						|
 | 
						|
  if (GTK_IS_TREE_VIEW (widget))
 | 
						|
    window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget));
 | 
						|
  else
 | 
						|
    window = gtk_widget_get_window (widget);
 | 
						|
 | 
						|
  gdk_window_get_origin (window, x_window, y_window);
 | 
						|
  window = gdk_window_get_toplevel (gtk_widget_get_window (widget));
 | 
						|
  gdk_window_get_origin (window, x_toplevel, y_toplevel);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
gtk_text_cell_accessible_get_character_extents (AtkText      *text,
 | 
						|
                                                gint          offset,
 | 
						|
                                                gint         *x,
 | 
						|
                                                gint         *y,
 | 
						|
                                                gint         *width,
 | 
						|
                                                gint         *height,
 | 
						|
                                                AtkCoordType  coords)
 | 
						|
{
 | 
						|
  GtkRendererCellAccessible *gail_renderer;
 | 
						|
  GtkRequisition min_size;
 | 
						|
  GtkCellRendererText *gtk_renderer;
 | 
						|
  GdkRectangle rendered_rect;
 | 
						|
  GtkWidget *widget;
 | 
						|
  AtkObject *parent;
 | 
						|
  PangoRectangle char_rect;
 | 
						|
  PangoLayout *layout;
 | 
						|
  gchar *renderer_text;
 | 
						|
  gfloat xalign, yalign;
 | 
						|
  gint x_offset, y_offset, index;
 | 
						|
  gint xpad, ypad;
 | 
						|
  gint x_window, y_window, x_toplevel, y_toplevel;
 | 
						|
 | 
						|
  if (!GTK_TEXT_CELL_ACCESSIBLE (text)->cell_text)
 | 
						|
    {
 | 
						|
      *x = *y = *height = *width = 0;
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  if (offset < 0 || offset >= GTK_TEXT_CELL_ACCESSIBLE (text)->cell_length)
 | 
						|
    {
 | 
						|
      *x = *y = *height = *width = 0;
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text);
 | 
						|
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
 | 
						|
 | 
						|
  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 (GTK_IS_CONTAINER_CELL_ACCESSIBLE (parent))
 | 
						|
    parent = atk_object_get_parent (parent);
 | 
						|
  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
 | 
						|
  g_return_if_fail (GTK_IS_CELL_ACCESSIBLE_PARENT (parent));
 | 
						|
  _gtk_cell_accessible_parent_get_cell_area (GTK_CELL_ACCESSIBLE_PARENT (parent),
 | 
						|
                                             GTK_CELL_ACCESSIBLE (text),
 | 
						|
                                             &rendered_rect);
 | 
						|
 | 
						|
  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_TEXT_CELL_ACCESSIBLE (text));
 | 
						|
 | 
						|
  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);
 | 
						|
 | 
						|
  get_origins (widget, &x_window, &y_window, &x_toplevel, &y_toplevel);
 | 
						|
 | 
						|
  *x = (char_rect.x / PANGO_SCALE) + x_offset + rendered_rect.x + xpad + x_window;
 | 
						|
  *y = (char_rect.y / PANGO_SCALE) + y_offset + rendered_rect.y + ypad + y_window;
 | 
						|
  *height = char_rect.height / PANGO_SCALE;
 | 
						|
  *width = char_rect.width / PANGO_SCALE;
 | 
						|
 | 
						|
  if (coords == ATK_XY_WINDOW)
 | 
						|
    {
 | 
						|
      *x -= x_toplevel;
 | 
						|
      *y -= y_toplevel;
 | 
						|
    }
 | 
						|
  else if (coords != ATK_XY_SCREEN)
 | 
						|
    {
 | 
						|
      *x = 0;
 | 
						|
      *y = 0;
 | 
						|
      *height = 0;
 | 
						|
      *width = 0;
 | 
						|
    }
 | 
						|
 | 
						|
  g_free (renderer_text);
 | 
						|
  g_object_unref (layout);
 | 
						|
}
 | 
						|
 | 
						|
static gint
 | 
						|
gtk_text_cell_accessible_get_offset_at_point (AtkText      *text,
 | 
						|
                                              gint          x,
 | 
						|
                                              gint          y,
 | 
						|
                                              AtkCoordType  coords)
 | 
						|
{
 | 
						|
  AtkObject *parent;
 | 
						|
  GtkRendererCellAccessible *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;
 | 
						|
  gint x_window, y_window, x_toplevel, y_toplevel;
 | 
						|
  gint x_temp, y_temp;
 | 
						|
  gboolean ret;
 | 
						|
 | 
						|
  if (!GTK_TEXT_CELL_ACCESSIBLE (text)->cell_text)
 | 
						|
    return -1;
 | 
						|
 | 
						|
  gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text);
 | 
						|
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
 | 
						|
  parent = atk_object_get_parent (ATK_OBJECT (text));
 | 
						|
 | 
						|
  g_object_get (gtk_renderer, "text", &renderer_text, NULL);
 | 
						|
  if (text == NULL)
 | 
						|
    {
 | 
						|
      g_free (renderer_text);
 | 
						|
      return -1;
 | 
						|
    }
 | 
						|
 | 
						|
  if (GTK_IS_CONTAINER_CELL_ACCESSIBLE (parent))
 | 
						|
    parent = atk_object_get_parent (parent);
 | 
						|
 | 
						|
  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
 | 
						|
 | 
						|
  g_return_val_if_fail (GTK_IS_CELL_ACCESSIBLE_PARENT (parent), -1);
 | 
						|
  _gtk_cell_accessible_parent_get_cell_area (GTK_CELL_ACCESSIBLE_PARENT (parent),
 | 
						|
                                             GTK_CELL_ACCESSIBLE (text),
 | 
						|
                                             &rendered_rect);
 | 
						|
 | 
						|
  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_TEXT_CELL_ACCESSIBLE (text));
 | 
						|
 | 
						|
  gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad);
 | 
						|
 | 
						|
  get_origins (widget, &x_window, &y_window, &x_toplevel, &y_toplevel);
 | 
						|
 | 
						|
  x_temp =  x - (x_offset + rendered_rect.x + xpad) - x_window;
 | 
						|
  y_temp =  y - (y_offset + rendered_rect.y + ypad) - y_window;
 | 
						|
  if (coords == ATK_XY_WINDOW)
 | 
						|
    {
 | 
						|
      x_temp += x_toplevel;
 | 
						|
      y_temp += y_toplevel;
 | 
						|
    }
 | 
						|
  else if (coords != ATK_XY_SCREEN)
 | 
						|
    index = -1;
 | 
						|
 | 
						|
  ret = pango_layout_xy_to_index (layout,
 | 
						|
                                  x_temp * PANGO_SCALE,
 | 
						|
                                  y_temp * PANGO_SCALE,
 | 
						|
                                  &index, NULL);
 | 
						|
  if (!ret)
 | 
						|
    {
 | 
						|
      if (x_temp < 0 || y_temp < 0)
 | 
						|
        index = 0;
 | 
						|
      else
 | 
						|
        index = -1;
 | 
						|
    }
 | 
						|
 | 
						|
  g_object_unref (layout);
 | 
						|
  if (index == -1)
 | 
						|
    {
 | 
						|
      if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
 | 
						|
        {
 | 
						|
          glong length;
 | 
						|
 | 
						|
          length = g_utf8_strlen (renderer_text, -1);
 | 
						|
          g_free (renderer_text);
 | 
						|
 | 
						|
          return length;
 | 
						|
        }
 | 
						|
 | 
						|
      g_free (renderer_text);
 | 
						|
 | 
						|
      return index;
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      glong offset;
 | 
						|
 | 
						|
      offset = g_utf8_pointer_to_offset (renderer_text,
 | 
						|
                                         renderer_text + index);
 | 
						|
      g_free (renderer_text);
 | 
						|
 | 
						|
      return offset;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static gunichar
 | 
						|
gtk_text_cell_accessible_get_character_at_offset (AtkText *text,
 | 
						|
                                                  gint     offset)
 | 
						|
{
 | 
						|
  gchar *index;
 | 
						|
  gchar *string;
 | 
						|
 | 
						|
  string = GTK_TEXT_CELL_ACCESSIBLE(text)->cell_text;
 | 
						|
 | 
						|
  if (!string)
 | 
						|
    return '\0';
 | 
						|
 | 
						|
  if (offset >= g_utf8_strlen (string, -1))
 | 
						|
    return '\0';
 | 
						|
 | 
						|
  index = g_utf8_offset_to_pointer (string, offset);
 | 
						|
 | 
						|
  return g_utf8_get_char (index);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
atk_text_interface_init (AtkTextIface *iface)
 | 
						|
{
 | 
						|
  iface->get_text = gtk_text_cell_accessible_get_text;
 | 
						|
  iface->get_character_at_offset = gtk_text_cell_accessible_get_character_at_offset;
 | 
						|
  iface->get_text_before_offset = gtk_text_cell_accessible_get_text_before_offset;
 | 
						|
  iface->get_text_at_offset = gtk_text_cell_accessible_get_text_at_offset;
 | 
						|
  iface->get_text_after_offset = gtk_text_cell_accessible_get_text_after_offset;
 | 
						|
  iface->get_character_count = gtk_text_cell_accessible_get_character_count;
 | 
						|
  iface->get_caret_offset = gtk_text_cell_accessible_get_caret_offset;
 | 
						|
  iface->set_caret_offset = gtk_text_cell_accessible_set_caret_offset;
 | 
						|
  iface->get_run_attributes = gtk_text_cell_accessible_get_run_attributes;
 | 
						|
  iface->get_default_attributes = gtk_text_cell_accessible_get_default_attributes;
 | 
						|
  iface->get_character_extents = gtk_text_cell_accessible_get_character_extents;
 | 
						|
  iface->get_offset_at_point = gtk_text_cell_accessible_get_offset_at_point;
 | 
						|
}
 |