Blame modules/other/gail/gailtextcell.c

Packit Service fb6fa5
/* GAIL - The GNOME Accessibility Enabling Library
Packit Service fb6fa5
 * Copyright 2001 Sun Microsystems Inc.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Lesser General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service fb6fa5
 * Lesser General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Lesser General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "config.h"
Packit Service fb6fa5
#include <string.h>
Packit Service fb6fa5
#include <gtk/gtk.h>
Packit Service fb6fa5
#include "gailtextcell.h"
Packit Service fb6fa5
#include "gailcontainercell.h"
Packit Service fb6fa5
#include "gailcellparent.h"
Packit Service fb6fa5
#include <libgail-util/gailmisc.h>
Packit Service fb6fa5
#include "gail-private-macros.h"
Packit Service fb6fa5
Packit Service fb6fa5
static void      gail_text_cell_class_init		(GailTextCellClass *klass);
Packit Service fb6fa5
static void      gail_text_cell_init			(GailTextCell	*text_cell);
Packit Service fb6fa5
static void      gail_text_cell_finalize		(GObject	*object);
Packit Service fb6fa5
Packit Service fb6fa5
static const gchar* gail_text_cell_get_name    (AtkObject      *atk_obj);
Packit Service fb6fa5
Packit Service fb6fa5
static void      atk_text_interface_init		(AtkTextIface	*iface);
Packit Service fb6fa5
Packit Service fb6fa5
/* atktext.h */
Packit Service fb6fa5
Packit Service fb6fa5
static gchar*    gail_text_cell_get_text		(AtkText	*text,
Packit Service fb6fa5
							gint		start_pos,
Packit Service fb6fa5
							gint		end_pos);
Packit Service fb6fa5
static gunichar gail_text_cell_get_character_at_offset	(AtkText	*text,
Packit Service fb6fa5
							 gint		offset);
Packit Service fb6fa5
static gchar*	gail_text_cell_get_text_before_offset	(AtkText	*text,
Packit Service fb6fa5
							 gint		offset,
Packit Service fb6fa5
							 AtkTextBoundary boundary_type,
Packit Service fb6fa5
							 gint		*start_offset,
Packit Service fb6fa5
							 gint		*end_offset);
Packit Service fb6fa5
static gchar*	gail_text_cell_get_text_at_offset	(AtkText	*text,
Packit Service fb6fa5
							 gint		offset,
Packit Service fb6fa5
							 AtkTextBoundary boundary_type,
Packit Service fb6fa5
							 gint		*start_offset,
Packit Service fb6fa5
							 gint		*end_offset);
Packit Service fb6fa5
static gchar*	gail_text_cell_get_text_after_offset	(AtkText	*text,
Packit Service fb6fa5
							 gint		offset,
Packit Service fb6fa5
							 AtkTextBoundary boundary_type,
Packit Service fb6fa5
							 gint		*start_offset,
Packit Service fb6fa5
							 gint		*end_offset);
Packit Service fb6fa5
static gint      gail_text_cell_get_character_count	(AtkText	*text);
Packit Service fb6fa5
static gint      gail_text_cell_get_caret_offset	(AtkText	*text);
Packit Service fb6fa5
static gboolean  gail_text_cell_set_caret_offset	(AtkText	*text,
Packit Service fb6fa5
							 gint		offset);
Packit Service fb6fa5
static void      gail_text_cell_get_character_extents	(AtkText	*text,
Packit Service fb6fa5
							 gint		offset,
Packit Service fb6fa5
							 gint		*x,
Packit Service fb6fa5
							 gint		*y,
Packit Service fb6fa5
							 gint		*width,
Packit Service fb6fa5
							 gint		*height,
Packit Service fb6fa5
							 AtkCoordType	coords);
Packit Service fb6fa5
static gint      gail_text_cell_get_offset_at_point	(AtkText	*text,
Packit Service fb6fa5
							 gint		x,
Packit Service fb6fa5
							 gint		y,
Packit Service fb6fa5
							 AtkCoordType	coords);
Packit Service fb6fa5
static AtkAttributeSet* gail_text_cell_get_run_attributes 
Packit Service fb6fa5
                                                        (AtkText	*text,
Packit Service fb6fa5
							 gint		offset,
Packit Service fb6fa5
							 gint		*start_offset,      
Packit Service fb6fa5
							 gint		*end_offset); 
Packit Service fb6fa5
static AtkAttributeSet* gail_text_cell_get_default_attributes 
Packit Service fb6fa5
                                                        (AtkText        *text);
Packit Service fb6fa5
Packit Service fb6fa5
static PangoLayout*     create_pango_layout             (GtkCellRendererText *gtk_renderer,
Packit Service fb6fa5
                                                         GtkWidget           *widget);
Packit Service fb6fa5
static void             add_attr                        (PangoAttrList  *attr_list,
Packit Service fb6fa5
                                                         PangoAttribute *attr);
Packit Service fb6fa5
Packit Service fb6fa5
/* Misc */
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean gail_text_cell_update_cache		(GailRendererCell *cell,
Packit Service fb6fa5
							 gboolean	emit_change_signal);
Packit Service fb6fa5
Packit Service fb6fa5
gchar *gail_text_cell_property_list[] = {
Packit Service fb6fa5
  /* Set font_desc first since it resets other values if it is NULL */
Packit Service fb6fa5
  "font_desc",
Packit Service fb6fa5
Packit Service fb6fa5
  "attributes",
Packit Service fb6fa5
  "background_gdk",
Packit Service fb6fa5
  "editable",
Packit Service fb6fa5
  "family",
Packit Service fb6fa5
  "foreground_gdk",
Packit Service fb6fa5
  "rise",
Packit Service fb6fa5
  "scale",
Packit Service fb6fa5
  "size",
Packit Service fb6fa5
  "size_points",
Packit Service fb6fa5
  "stretch",
Packit Service fb6fa5
  "strikethrough",
Packit Service fb6fa5
  "style",
Packit Service fb6fa5
  "text",
Packit Service fb6fa5
  "underline",
Packit Service fb6fa5
  "variant",
Packit Service fb6fa5
  "weight",
Packit Service fb6fa5
Packit Service fb6fa5
  /* Also need the sets */
Packit Service fb6fa5
  "background_set",
Packit Service fb6fa5
  "editable_set",
Packit Service fb6fa5
  "family_set",
Packit Service fb6fa5
  "foreground_set",
Packit Service fb6fa5
  "rise_set",
Packit Service fb6fa5
  "scale_set",
Packit Service fb6fa5
  "size_set",
Packit Service fb6fa5
  "stretch_set",
Packit Service fb6fa5
  "strikethrough_set",
Packit Service fb6fa5
  "style_set",
Packit Service fb6fa5
  "underline_set",
Packit Service fb6fa5
  "variant_set",
Packit Service fb6fa5
  "weight_set",
Packit Service fb6fa5
  NULL
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
G_DEFINE_TYPE_WITH_CODE (GailTextCell, gail_text_cell, GAIL_TYPE_RENDERER_CELL,
Packit Service fb6fa5
                         G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
Packit Service fb6fa5
Packit Service fb6fa5
static void 
Packit Service fb6fa5
gail_text_cell_class_init (GailTextCellClass *klass)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
Packit Service fb6fa5
  AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
Packit Service fb6fa5
  GailRendererCellClass *renderer_cell_class = GAIL_RENDERER_CELL_CLASS (klass);
Packit Service fb6fa5
Packit Service fb6fa5
  renderer_cell_class->update_cache = gail_text_cell_update_cache;
Packit Service fb6fa5
  renderer_cell_class->property_list = gail_text_cell_property_list;
Packit Service fb6fa5
Packit Service fb6fa5
  atk_object_class->get_name = gail_text_cell_get_name;
Packit Service fb6fa5
Packit Service fb6fa5
  gobject_class->finalize = gail_text_cell_finalize;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* atktext.h */
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gail_text_cell_init (GailTextCell *text_cell)
Packit Service fb6fa5
{
Packit Service fb6fa5
  text_cell->cell_text = NULL;
Packit Service fb6fa5
  text_cell->caret_pos = 0;
Packit Service fb6fa5
  text_cell->cell_length = 0;
Packit Service fb6fa5
  text_cell->textutil = gail_text_util_new ();
Packit Service fb6fa5
  atk_state_set_add_state (GAIL_CELL (text_cell)->state_set,
Packit Service fb6fa5
                           ATK_STATE_SINGLE_LINE);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
AtkObject* 
Packit Service fb6fa5
gail_text_cell_new (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GObject *object;
Packit Service fb6fa5
  AtkObject *atk_object;
Packit Service fb6fa5
  GailRendererCell *cell;
Packit Service fb6fa5
Packit Service fb6fa5
  object = g_object_new (GAIL_TYPE_TEXT_CELL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (object != NULL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  atk_object = ATK_OBJECT (object);
Packit Service fb6fa5
  atk_object->role = ATK_ROLE_TABLE_CELL;
Packit Service fb6fa5
Packit Service fb6fa5
  cell = GAIL_RENDERER_CELL(object);
Packit Service fb6fa5
Packit Service fb6fa5
  cell->renderer = gtk_cell_renderer_text_new ();
Packit Service fb6fa5
  g_object_ref_sink (cell->renderer);
Packit Service fb6fa5
  return atk_object;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gail_text_cell_finalize (GObject            *object)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GailTextCell *text_cell = GAIL_TEXT_CELL (object);
Packit Service fb6fa5
Packit Service fb6fa5
  g_object_unref (text_cell->textutil);
Packit Service fb6fa5
  g_free (text_cell->cell_text);
Packit Service fb6fa5
Packit Service fb6fa5
  G_OBJECT_CLASS (gail_text_cell_parent_class)->finalize (object);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static const gchar*
Packit Service fb6fa5
gail_text_cell_get_name (AtkObject *atk_obj)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (atk_obj->name)
Packit Service fb6fa5
    return atk_obj->name;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GailTextCell *text_cell = GAIL_TEXT_CELL (atk_obj);
Packit Service fb6fa5
Packit Service fb6fa5
      return text_cell->cell_text;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
gail_text_cell_update_cache (GailRendererCell *cell,
Packit Service fb6fa5
                             gboolean         emit_change_signal)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GailTextCell *text_cell = GAIL_TEXT_CELL (cell);
Packit Service fb6fa5
  AtkObject *obj = ATK_OBJECT (cell);
Packit Service fb6fa5
  gboolean rv = FALSE;
Packit Service fb6fa5
  gint temp_length;
Packit Service fb6fa5
  gchar *new_cache;
Packit Service fb6fa5
Packit Service fb6fa5
  g_object_get (G_OBJECT (cell->renderer), "text", &new_cache, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (text_cell->cell_text)
Packit Service fb6fa5
    {
Packit Service fb6fa5
     /*
Packit Service fb6fa5
      * If the new value is NULL and the old value isn't NULL, then the
Packit Service fb6fa5
      * value has changed.
Packit Service fb6fa5
      */
Packit Service fb6fa5
      if (new_cache == NULL ||
Packit Service fb6fa5
          strcmp (text_cell->cell_text, new_cache))
Packit Service fb6fa5
        {
Packit Service fb6fa5
          g_free (text_cell->cell_text);
Packit Service fb6fa5
          temp_length = text_cell->cell_length;
Packit Service fb6fa5
          text_cell->cell_text = NULL;
Packit Service fb6fa5
          text_cell->cell_length = 0;
Packit Service fb6fa5
          if (emit_change_signal)
Packit Service fb6fa5
            {
Packit Service fb6fa5
              g_signal_emit_by_name (cell, "text_changed::delete", 0, temp_length);
Packit Service fb6fa5
              if (obj->name == NULL)
Packit Service fb6fa5
                g_object_notify (G_OBJECT (obj), "accessible-name");
Packit Service fb6fa5
            }
Packit Service fb6fa5
          if (new_cache)
Packit Service fb6fa5
            rv = TRUE;
Packit Service fb6fa5
        }
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    rv = TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
  if (rv)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (new_cache == NULL)
Packit Service fb6fa5
        {
Packit Service fb6fa5
          text_cell->cell_text = g_strdup ("");
Packit Service fb6fa5
          text_cell->cell_length = 0;
Packit Service fb6fa5
        }
Packit Service fb6fa5
      else
Packit Service fb6fa5
        {
Packit Service fb6fa5
          text_cell->cell_text = g_strdup (new_cache);
Packit Service fb6fa5
          text_cell->cell_length = g_utf8_strlen (new_cache, -1);
Packit Service fb6fa5
        }
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  g_free (new_cache);
Packit Service fb6fa5
  gail_text_util_text_setup (text_cell->textutil, text_cell->cell_text);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (rv)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (emit_change_signal)
Packit Service fb6fa5
        {
Packit Service fb6fa5
          g_signal_emit_by_name (cell, "text_changed::insert",
Packit Service fb6fa5
  			         0, text_cell->cell_length);
Packit Service fb6fa5
Packit Service fb6fa5
          if (obj->name == NULL)
Packit Service fb6fa5
            g_object_notify (G_OBJECT (obj), "accessible-name");
Packit Service fb6fa5
        }
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return rv;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
atk_text_interface_init (AtkTextIface *iface)
Packit Service fb6fa5
{
Packit Service fb6fa5
  iface->get_text = gail_text_cell_get_text;
Packit Service fb6fa5
  iface->get_character_at_offset = gail_text_cell_get_character_at_offset;
Packit Service fb6fa5
  iface->get_text_before_offset = gail_text_cell_get_text_before_offset;
Packit Service fb6fa5
  iface->get_text_at_offset = gail_text_cell_get_text_at_offset;
Packit Service fb6fa5
  iface->get_text_after_offset = gail_text_cell_get_text_after_offset;
Packit Service fb6fa5
  iface->get_character_count = gail_text_cell_get_character_count;
Packit Service fb6fa5
  iface->get_caret_offset = gail_text_cell_get_caret_offset;
Packit Service fb6fa5
  iface->set_caret_offset = gail_text_cell_set_caret_offset;
Packit Service fb6fa5
  iface->get_run_attributes = gail_text_cell_get_run_attributes;
Packit Service fb6fa5
  iface->get_default_attributes = gail_text_cell_get_default_attributes;
Packit Service fb6fa5
  iface->get_character_extents = gail_text_cell_get_character_extents;
Packit Service fb6fa5
  iface->get_offset_at_point = gail_text_cell_get_offset_at_point;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gchar* 
Packit Service fb6fa5
gail_text_cell_get_text (AtkText *text, 
Packit Service fb6fa5
                         gint    start_pos,
Packit Service fb6fa5
                         gint    end_pos)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (GAIL_TEXT_CELL (text)->cell_text)
Packit Service fb6fa5
    return gail_text_util_get_substring (GAIL_TEXT_CELL (text)->textutil,
Packit Service fb6fa5
              start_pos, end_pos);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return g_strdup ("");
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gchar* 
Packit Service fb6fa5
gail_text_cell_get_text_before_offset (AtkText         *text,
Packit Service fb6fa5
                                       gint            offset,
Packit Service fb6fa5
                                       AtkTextBoundary boundary_type,
Packit Service fb6fa5
                                       gint            *start_offset,
Packit Service fb6fa5
                                       gint            *end_offset)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return gail_text_util_get_text (GAIL_TEXT_CELL (text)->textutil,
Packit Service fb6fa5
        NULL, GAIL_BEFORE_OFFSET, boundary_type, offset, start_offset,
Packit Service fb6fa5
        end_offset);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gchar* 
Packit Service fb6fa5
gail_text_cell_get_text_at_offset (AtkText         *text,
Packit Service fb6fa5
                                   gint            offset,
Packit Service fb6fa5
                                   AtkTextBoundary boundary_type,
Packit Service fb6fa5
                                   gint            *start_offset,
Packit Service fb6fa5
                                   gint            *end_offset)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return gail_text_util_get_text (GAIL_TEXT_CELL (text)->textutil,
Packit Service fb6fa5
        NULL, GAIL_AT_OFFSET, boundary_type, offset, start_offset, end_offset);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gchar* 
Packit Service fb6fa5
gail_text_cell_get_text_after_offset (AtkText         *text,
Packit Service fb6fa5
                                      gint            offset,
Packit Service fb6fa5
                                      AtkTextBoundary boundary_type,
Packit Service fb6fa5
                                      gint            *start_offset,
Packit Service fb6fa5
                                      gint            *end_offset)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return gail_text_util_get_text (GAIL_TEXT_CELL (text)->textutil,
Packit Service fb6fa5
        NULL, GAIL_AFTER_OFFSET, boundary_type, offset, start_offset,
Packit Service fb6fa5
        end_offset);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gint 
Packit Service fb6fa5
gail_text_cell_get_character_count (AtkText *text)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (GAIL_TEXT_CELL (text)->cell_text != NULL)
Packit Service fb6fa5
    return GAIL_TEXT_CELL (text)->cell_length;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return 0;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gint 
Packit Service fb6fa5
gail_text_cell_get_caret_offset (AtkText *text)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return GAIL_TEXT_CELL (text)->caret_pos;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean 
Packit Service fb6fa5
gail_text_cell_set_caret_offset (AtkText *text,
Packit Service fb6fa5
                                 gint    offset)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GailTextCell *text_cell = GAIL_TEXT_CELL (text);
Packit Service fb6fa5
Packit Service fb6fa5
  if (text_cell->cell_text == NULL)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
Packit Service fb6fa5
      /* Only set the caret within the bounds and if it is to a new position. */
Packit Service fb6fa5
      if (offset >= 0 && 
Packit Service fb6fa5
          offset <= text_cell->cell_length &&
Packit Service fb6fa5
          offset != text_cell->caret_pos)
Packit Service fb6fa5
        {
Packit Service fb6fa5
          text_cell->caret_pos = offset;
Packit Service fb6fa5
Packit Service fb6fa5
          /* emit the signal */
Packit Service fb6fa5
          g_signal_emit_by_name (text, "text_caret_moved", offset);
Packit Service fb6fa5
          return TRUE;
Packit Service fb6fa5
        }
Packit Service fb6fa5
      else
Packit Service fb6fa5
        return FALSE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static AtkAttributeSet*
Packit Service fb6fa5
gail_text_cell_get_run_attributes (AtkText *text,
Packit Service fb6fa5
                                  gint     offset,
Packit Service fb6fa5
                                  gint     *start_offset,
Packit Service fb6fa5
                                  gint     *end_offset) 
Packit Service fb6fa5
{
Packit Service fb6fa5
  GailRendererCell *gail_renderer; 
Packit Service fb6fa5
  GtkCellRendererText *gtk_renderer;
Packit Service fb6fa5
  AtkAttributeSet *attrib_set = NULL;
Packit Service fb6fa5
  PangoLayout *layout;
Packit Service fb6fa5
  AtkObject *parent;
Packit Service fb6fa5
  GtkWidget *widget;
Packit Service fb6fa5
Packit Service fb6fa5
  gail_renderer = GAIL_RENDERER_CELL (text);
Packit Service fb6fa5
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
Packit Service fb6fa5
Packit Service fb6fa5
  parent = atk_object_get_parent (ATK_OBJECT (text));
Packit Service fb6fa5
  if (GAIL_IS_CONTAINER_CELL (parent))
Packit Service fb6fa5
    parent = atk_object_get_parent (parent);
Packit Service fb6fa5
  g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), NULL);
Packit Service fb6fa5
  widget = GTK_ACCESSIBLE (parent)->widget;
Packit Service fb6fa5
  layout = create_pango_layout (gtk_renderer, widget),
Packit Service fb6fa5
  attrib_set = gail_misc_layout_get_run_attributes (attrib_set, 
Packit Service fb6fa5
                                                    layout,
Packit Service fb6fa5
                                                    gtk_renderer->text,
Packit Service fb6fa5
                                                    offset,
Packit Service fb6fa5
                                                    start_offset,
Packit Service fb6fa5
                                                    end_offset);
Packit Service fb6fa5
  g_object_unref (G_OBJECT (layout));
Packit Service fb6fa5
  
Packit Service fb6fa5
  return attrib_set;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static AtkAttributeSet*
Packit Service fb6fa5
gail_text_cell_get_default_attributes (AtkText	*text)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GailRendererCell *gail_renderer; 
Packit Service fb6fa5
  GtkCellRendererText *gtk_renderer;
Packit Service fb6fa5
  AtkAttributeSet *attrib_set = NULL;
Packit Service fb6fa5
  PangoLayout *layout;
Packit Service fb6fa5
  AtkObject *parent;
Packit Service fb6fa5
  GtkWidget *widget;
Packit Service fb6fa5
Packit Service fb6fa5
  gail_renderer = GAIL_RENDERER_CELL (text);
Packit Service fb6fa5
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
Packit Service fb6fa5
Packit Service fb6fa5
  parent = atk_object_get_parent (ATK_OBJECT (text));
Packit Service fb6fa5
  if (GAIL_IS_CONTAINER_CELL (parent))
Packit Service fb6fa5
    parent = atk_object_get_parent (parent);
Packit Service fb6fa5
  g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), NULL);
Packit Service fb6fa5
  widget = GTK_ACCESSIBLE (parent)->widget;
Packit Service fb6fa5
  layout = create_pango_layout (gtk_renderer, widget),
Packit Service fb6fa5
Packit Service fb6fa5
  attrib_set = gail_misc_get_default_attributes (attrib_set, 
Packit Service fb6fa5
                                                 layout,
Packit Service fb6fa5
                                                 widget);
Packit Service fb6fa5
  g_object_unref (G_OBJECT (layout));
Packit Service fb6fa5
  return attrib_set;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* 
Packit Service fb6fa5
 * This function is used by gail_text_cell_get_offset_at_point()
Packit Service fb6fa5
 * and gail_text_cell_get_character_extents(). There is no 
Packit Service fb6fa5
 * cached PangoLayout for gailtextcell so we must create a temporary
Packit Service fb6fa5
 * one using this function.
Packit Service fb6fa5
 */ 
Packit Service fb6fa5
static PangoLayout*
Packit Service fb6fa5
create_pango_layout(GtkCellRendererText *gtk_renderer,
Packit Service fb6fa5
                    GtkWidget           *widget)
Packit Service fb6fa5
{
Packit Service fb6fa5
  PangoAttrList *attr_list;
Packit Service fb6fa5
  PangoLayout *layout;
Packit Service fb6fa5
  PangoUnderline uline;
Packit Service fb6fa5
  PangoFontMask mask;
Packit Service fb6fa5
Packit Service fb6fa5
  layout = gtk_widget_create_pango_layout (widget, gtk_renderer->text);
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_renderer->extra_attrs)
Packit Service fb6fa5
    attr_list = pango_attr_list_copy (gtk_renderer->extra_attrs);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    attr_list = pango_attr_list_new ();
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_renderer->foreground_set)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      PangoColor color;
Packit Service fb6fa5
      color = gtk_renderer->foreground;
Packit Service fb6fa5
      add_attr (attr_list, pango_attr_foreground_new (color.red,
Packit Service fb6fa5
                                                      color.green, color.blue));
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_renderer->strikethrough_set)
Packit Service fb6fa5
    add_attr (attr_list,
Packit Service fb6fa5
              pango_attr_strikethrough_new (gtk_renderer->strikethrough));
Packit Service fb6fa5
Packit Service fb6fa5
  mask = pango_font_description_get_set_fields (gtk_renderer->font);
Packit Service fb6fa5
Packit Service fb6fa5
  if (mask & PANGO_FONT_MASK_FAMILY)
Packit Service fb6fa5
    add_attr (attr_list,
Packit Service fb6fa5
      pango_attr_family_new (pango_font_description_get_family (gtk_renderer->font)));
Packit Service fb6fa5
Packit Service fb6fa5
  if (mask & PANGO_FONT_MASK_STYLE)
Packit Service fb6fa5
    add_attr (attr_list, pango_attr_style_new (pango_font_description_get_style (gtk_renderer->font)));
Packit Service fb6fa5
Packit Service fb6fa5
  if (mask & PANGO_FONT_MASK_VARIANT)
Packit Service fb6fa5
    add_attr (attr_list, pango_attr_variant_new (pango_font_description_get_variant (gtk_renderer->font)));
Packit Service fb6fa5
Packit Service fb6fa5
  if (mask & PANGO_FONT_MASK_WEIGHT)
Packit Service fb6fa5
    add_attr (attr_list, pango_attr_weight_new (pango_font_description_get_weight (gtk_renderer->font)));
Packit Service fb6fa5
Packit Service fb6fa5
  if (mask & PANGO_FONT_MASK_STRETCH)
Packit Service fb6fa5
    add_attr (attr_list, pango_attr_stretch_new (pango_font_description_get_stretch (gtk_renderer->font)));
Packit Service fb6fa5
Packit Service fb6fa5
  if (mask & PANGO_FONT_MASK_SIZE)
Packit Service fb6fa5
    add_attr (attr_list, pango_attr_size_new (pango_font_description_get_size (gtk_renderer->font)));
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_renderer->scale_set &&
Packit Service fb6fa5
      gtk_renderer->font_scale != 1.0)
Packit Service fb6fa5
    add_attr (attr_list, pango_attr_scale_new (gtk_renderer->font_scale));
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_renderer->underline_set)
Packit Service fb6fa5
    uline = gtk_renderer->underline_style;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    uline = PANGO_UNDERLINE_NONE;
Packit Service fb6fa5
Packit Service fb6fa5
  if (uline != PANGO_UNDERLINE_NONE)
Packit Service fb6fa5
    add_attr (attr_list,
Packit Service fb6fa5
      pango_attr_underline_new (gtk_renderer->underline_style));
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_renderer->rise_set)
Packit Service fb6fa5
    add_attr (attr_list, pango_attr_rise_new (gtk_renderer->rise));
Packit Service fb6fa5
Packit Service fb6fa5
  pango_layout_set_attributes (layout, attr_list);
Packit Service fb6fa5
  pango_layout_set_width (layout, -1);
Packit Service fb6fa5
  pango_attr_list_unref (attr_list);
Packit Service fb6fa5
Packit Service fb6fa5
  return layout;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void 
Packit Service fb6fa5
add_attr (PangoAttrList  *attr_list,
Packit Service fb6fa5
         PangoAttribute *attr)
Packit Service fb6fa5
{
Packit Service fb6fa5
  attr->start_index = 0;
Packit Service fb6fa5
  attr->end_index = G_MAXINT;
Packit Service fb6fa5
  pango_attr_list_insert (attr_list, attr);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void      
Packit Service fb6fa5
gail_text_cell_get_character_extents (AtkText          *text,
Packit Service fb6fa5
                                      gint             offset,
Packit Service fb6fa5
                                      gint             *x,
Packit Service fb6fa5
                                      gint             *y,
Packit Service fb6fa5
                                      gint             *width,
Packit Service fb6fa5
                                      gint             *height,
Packit Service fb6fa5
                                      AtkCoordType     coords)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GailRendererCell *gail_renderer; 
Packit Service fb6fa5
  GtkCellRendererText *gtk_renderer;
Packit Service fb6fa5
  GdkRectangle rendered_rect;
Packit Service fb6fa5
  GtkWidget *widget;
Packit Service fb6fa5
  AtkObject *parent;
Packit Service fb6fa5
  PangoRectangle char_rect;
Packit Service fb6fa5
  PangoLayout *layout;
Packit Service fb6fa5
  gint x_offset, y_offset, index, cell_height, cell_width;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!GAIL_TEXT_CELL (text)->cell_text)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      *x = *y = *height = *width = 0;
Packit Service fb6fa5
      return;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  if (offset < 0 || offset >= GAIL_TEXT_CELL (text)->cell_length)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      *x = *y = *height = *width = 0;
Packit Service fb6fa5
      return;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  gail_renderer = GAIL_RENDERER_CELL (text);
Packit Service fb6fa5
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
Packit Service fb6fa5
  /*
Packit Service fb6fa5
   * Thus would be inconsistent with the cache
Packit Service fb6fa5
   */
Packit Service fb6fa5
  gail_return_if_fail (gtk_renderer->text);
Packit Service fb6fa5
Packit Service fb6fa5
  parent = atk_object_get_parent (ATK_OBJECT (text));
Packit Service fb6fa5
  if (GAIL_IS_CONTAINER_CELL (parent))
Packit Service fb6fa5
    parent = atk_object_get_parent (parent);
Packit Service fb6fa5
  widget = GTK_ACCESSIBLE (parent)->widget;
Packit Service fb6fa5
  g_return_if_fail (GAIL_IS_CELL_PARENT (parent));
Packit Service fb6fa5
  gail_cell_parent_get_cell_area (GAIL_CELL_PARENT (parent), GAIL_CELL (text),
Packit Service fb6fa5
                                  &rendered_rect);
Packit Service fb6fa5
Packit Service fb6fa5
  gtk_cell_renderer_get_size (GTK_CELL_RENDERER (gtk_renderer), widget,
Packit Service fb6fa5
    &rendered_rect, &x_offset, &y_offset, &cell_width, &cell_height);
Packit Service fb6fa5
  layout = create_pango_layout (gtk_renderer, widget);
Packit Service fb6fa5
Packit Service fb6fa5
  index = g_utf8_offset_to_pointer (gtk_renderer->text,
Packit Service fb6fa5
    offset) - gtk_renderer->text;
Packit Service fb6fa5
  pango_layout_index_to_pos (layout, index, &char_rect); 
Packit Service fb6fa5
Packit Service fb6fa5
  gail_misc_get_extents_from_pango_rectangle (widget,
Packit Service fb6fa5
      &char_rect,
Packit Service fb6fa5
      x_offset + rendered_rect.x + gail_renderer->renderer->xpad,
Packit Service fb6fa5
      y_offset + rendered_rect.y + gail_renderer->renderer->ypad,
Packit Service fb6fa5
      x, y, width, height, coords);
Packit Service fb6fa5
  g_object_unref (layout);
Packit Service fb6fa5
  return;
Packit Service fb6fa5
} 
Packit Service fb6fa5
Packit Service fb6fa5
static gint      
Packit Service fb6fa5
gail_text_cell_get_offset_at_point (AtkText          *text,
Packit Service fb6fa5
                                    gint             x,
Packit Service fb6fa5
                                    gint             y,
Packit Service fb6fa5
                                    AtkCoordType     coords)
Packit Service fb6fa5
{
Packit Service fb6fa5
  AtkObject *parent;
Packit Service fb6fa5
  GailRendererCell *gail_renderer; 
Packit Service fb6fa5
  GtkCellRendererText *gtk_renderer;
Packit Service fb6fa5
  GtkWidget *widget;
Packit Service fb6fa5
  GdkRectangle rendered_rect;
Packit Service fb6fa5
  PangoLayout *layout;
Packit Service fb6fa5
  gint x_offset, y_offset, index;
Packit Service fb6fa5
 
Packit Service fb6fa5
  if (!GAIL_TEXT_CELL (text)->cell_text)
Packit Service fb6fa5
    return -1;
Packit Service fb6fa5
Packit Service fb6fa5
  gail_renderer = GAIL_RENDERER_CELL (text);
Packit Service fb6fa5
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
Packit Service fb6fa5
  parent = atk_object_get_parent (ATK_OBJECT (text));
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (gtk_renderer->text, -1);
Packit Service fb6fa5
  if (GAIL_IS_CONTAINER_CELL (parent))
Packit Service fb6fa5
    parent = atk_object_get_parent (parent);
Packit Service fb6fa5
Packit Service fb6fa5
  widget = GTK_ACCESSIBLE (parent)->widget;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), -1);
Packit Service fb6fa5
  gail_cell_parent_get_cell_area (GAIL_CELL_PARENT (parent), GAIL_CELL (text),
Packit Service fb6fa5
                                  &rendered_rect);
Packit Service fb6fa5
  gtk_cell_renderer_get_size (GTK_CELL_RENDERER (gtk_renderer), widget,
Packit Service fb6fa5
     &rendered_rect, &x_offset, &y_offset, NULL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  layout = create_pango_layout (gtk_renderer, widget);
Packit Service fb6fa5
   
Packit Service fb6fa5
  index = gail_misc_get_index_at_point_in_layout (widget, layout,
Packit Service fb6fa5
        x_offset + rendered_rect.x + gail_renderer->renderer->xpad,
Packit Service fb6fa5
        y_offset + rendered_rect.y + gail_renderer->renderer->ypad,
Packit Service fb6fa5
        x, y, coords);
Packit Service fb6fa5
  g_object_unref (layout);
Packit Service fb6fa5
  if (index == -1)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
Packit Service fb6fa5
        return g_utf8_strlen (gtk_renderer->text, -1);
Packit Service fb6fa5
    
Packit Service fb6fa5
      return index;  
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return g_utf8_pointer_to_offset (gtk_renderer->text,
Packit Service fb6fa5
       gtk_renderer->text + index);  
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gunichar 
Packit Service fb6fa5
gail_text_cell_get_character_at_offset (AtkText       *text,
Packit Service fb6fa5
                                        gint          offset)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gchar *index;
Packit Service fb6fa5
  gchar *string;
Packit Service fb6fa5
Packit Service fb6fa5
  string = GAIL_TEXT_CELL(text)->cell_text;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!string)
Packit Service fb6fa5
    return '\0';
Packit Service fb6fa5
Packit Service fb6fa5
  if (offset >= g_utf8_strlen (string, -1))
Packit Service fb6fa5
    return '\0';
Packit Service fb6fa5
Packit Service fb6fa5
  index = g_utf8_offset_to_pointer (string, offset);
Packit Service fb6fa5
Packit Service fb6fa5
  return g_utf8_get_char (index);
Packit Service fb6fa5
}
Packit Service fb6fa5