[evince] Expose images as AtkObject children of the page



commit aea890cbc99aa5c7d340e76a3281f0c170a5add2
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Mon Jun 23 12:59:38 2014 -0400

    Expose images as AtkObject children of the page

 libview/Makefile.am           |    2 +
 libview/ev-image-accessible.c |  208 +++++++++++++++++++++++++++++++++++++++++
 libview/ev-image-accessible.h |   55 +++++++++++
 libview/ev-page-accessible.c  |    9 ++-
 4 files changed, 272 insertions(+), 2 deletions(-)
---
diff --git a/libview/Makefile.am b/libview/Makefile.am
index 8809a70..6d0ab7d 100644
--- a/libview/Makefile.am
+++ b/libview/Makefile.am
@@ -2,6 +2,7 @@ lib_LTLIBRARIES = libevview3.la
 
 NOINST_H_SRC_FILES =                   \
        ev-annotation-window.h          \
+       ev-image-accessible.h           \
        ev-link-accessible.h            \
        ev-page-accessible.h            \
        ev-page-cache.h                 \
@@ -34,6 +35,7 @@ nodist_header_DATA = $(INST_H_BUILT_FILES)
 libevview3_la_SOURCES =                        \
        ev-annotation-window.c          \
        ev-document-model.c             \
+       ev-image-accessible.c           \
        ev-jobs.c                       \
        ev-job-scheduler.c              \
        ev-link-accessible.c            \
diff --git a/libview/ev-image-accessible.c b/libview/ev-image-accessible.c
new file mode 100644
index 0000000..efc37cf
--- /dev/null
+++ b/libview/ev-image-accessible.c
@@ -0,0 +1,208 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/* this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2014 Igalia
+ * Author: Joanmarie Diggs <jdiggs igalia com>
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <config.h>
+
+#include "ev-image-accessible.h"
+#include "ev-view-private.h"
+
+struct _EvImageAccessiblePrivate {
+        EvPageAccessible *page;
+        EvImage          *image;
+        EvRectangle       area;
+};
+
+static void ev_image_accessible_component_iface_init (AtkComponentIface *iface);
+static void ev_image_accessible_image_iface_init     (AtkImageIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (EvImageAccessible, ev_image_accessible, ATK_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, ev_image_accessible_component_iface_init)
+                        G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, ev_image_accessible_image_iface_init))
+
+static void
+ev_image_accessible_get_atk_rect (AtkObject    *atk_object,
+                                 AtkCoordType  coord_type,
+                                 EvRectangle  *atk_rect)
+{
+       EvImageAccessible *image;
+       EvViewAccessible *view_accessible;
+       gint page;
+
+       image = EV_IMAGE_ACCESSIBLE (atk_object);
+       view_accessible = ev_page_accessible_get_view_accessible (image->priv->page);
+       page = ev_page_accessible_get_page (image->priv->page);
+       _transform_doc_rect_to_atk_rect (view_accessible, page, &image->priv->area, atk_rect, coord_type);
+}
+
+static void
+ev_image_accessible_get_extents (AtkComponent *atk_component,
+                                gint         *x,
+                                gint         *y,
+                                gint         *width,
+                                gint         *height,
+                                AtkCoordType  coord_type)
+{
+       EvRectangle atk_rect;
+
+       ev_image_accessible_get_atk_rect (ATK_OBJECT (atk_component), coord_type, &atk_rect);
+       *x = atk_rect.x1;
+       *y = atk_rect.y1;
+       *width = atk_rect.x2 - atk_rect.x1;
+       *height = atk_rect.y2 - atk_rect.y1;
+}
+
+static void
+ev_image_accessible_component_iface_init (AtkComponentIface *iface)
+{
+       iface->get_extents = ev_image_accessible_get_extents;
+}
+
+static const gchar *
+ev_image_accessible_get_image_description (AtkImage *image)
+{
+       /* This will be obtainable for tagged PDFs */
+       return NULL;
+}
+
+static const gchar *
+ev_image_accessible_get_image_locale (AtkImage *atk_image)
+{
+       /* This will be obtainable for tagged PDFs */
+       return NULL;
+}
+
+static void
+ev_image_accessible_get_image_size (AtkImage *atk_image,
+                                   int      *width,
+                                   int      *height)
+{
+       EvRectangle atk_rect;
+
+       ev_image_accessible_get_atk_rect (ATK_OBJECT (atk_image), ATK_XY_WINDOW, &atk_rect);
+       *width = atk_rect.x2 - atk_rect.x1;
+       *height = atk_rect.y2 - atk_rect.y1;
+}
+
+static void
+ev_image_accessible_get_image_position (AtkImage     *atk_image,
+                                       gint         *x,
+                                       gint         *y,
+                                       AtkCoordType  coord_type)
+{
+       EvRectangle atk_rect;
+
+       ev_image_accessible_get_atk_rect (ATK_OBJECT (atk_image), ATK_XY_WINDOW, &atk_rect);
+       *x = atk_rect.x1;
+       *y = atk_rect.y1;
+}
+
+static AtkStateSet *
+ev_image_accessible_ref_state_set (AtkObject *atk_object)
+{
+       AtkStateSet *state_set;
+       AtkStateSet *copy_set;
+       AtkStateSet *page_accessible_state_set;
+       EvImageAccessible *self;
+       EvViewAccessible *view_accessible;
+       gint page;
+
+       self = EV_IMAGE_ACCESSIBLE (atk_object);
+       state_set = ATK_OBJECT_CLASS (ev_image_accessible_parent_class)->ref_state_set (atk_object);
+       atk_state_set_clear_states (state_set);
+
+       page_accessible_state_set = atk_object_ref_state_set (ATK_OBJECT (self->priv->page));
+       copy_set = atk_state_set_or_sets (state_set, page_accessible_state_set);
+       atk_state_set_remove_state (copy_set, ATK_STATE_FOCUSABLE);
+       atk_state_set_remove_state (copy_set, ATK_STATE_FOCUSED);
+
+       view_accessible = ev_page_accessible_get_view_accessible (self->priv->page);
+       page = ev_page_accessible_get_page (self->priv->page);
+       if (!ev_view_accessible_is_doc_rect_showing (view_accessible, page, &self->priv->area))
+               atk_state_set_remove_state (copy_set, ATK_STATE_SHOWING);
+
+       g_object_unref (state_set);
+       g_object_unref (page_accessible_state_set);
+
+       return copy_set;
+}
+
+static AtkObject *
+ev_image_accessible_get_parent (AtkObject *atk_object)
+{
+       EvImageAccessiblePrivate *priv = EV_IMAGE_ACCESSIBLE (atk_object)->priv;
+
+       return ATK_OBJECT (priv->page);
+}
+
+static void
+ev_image_accessible_finalize (GObject *object)
+{
+       EvImageAccessiblePrivate *priv = EV_IMAGE_ACCESSIBLE (object)->priv;
+
+       g_object_unref (priv->image);
+
+       G_OBJECT_CLASS (ev_image_accessible_parent_class)->finalize (object);
+}
+
+static void
+ev_image_accessible_class_init (EvImageAccessibleClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass);
+
+       object_class->finalize = ev_image_accessible_finalize;
+       atk_class->get_parent = ev_image_accessible_get_parent;
+       atk_class->ref_state_set = ev_image_accessible_ref_state_set;
+
+       g_type_class_add_private (klass, sizeof (EvImageAccessiblePrivate));
+}
+
+static void
+ev_image_accessible_init (EvImageAccessible *image)
+{
+       atk_object_set_role (ATK_OBJECT (image), ATK_ROLE_IMAGE);
+
+       image->priv = G_TYPE_INSTANCE_GET_PRIVATE (image, EV_TYPE_IMAGE_ACCESSIBLE, EvImageAccessiblePrivate);
+}
+
+static void
+ev_image_accessible_image_iface_init (AtkImageIface *iface)
+{
+       iface->get_image_description = ev_image_accessible_get_image_description;
+       iface->get_image_locale = ev_image_accessible_get_image_locale;
+       iface->get_image_position = ev_image_accessible_get_image_position;
+       iface->get_image_size = ev_image_accessible_get_image_size;
+}
+
+EvImageAccessible *
+ev_image_accessible_new (EvPageAccessible *page,
+                        EvImage          *image,
+                        EvRectangle      *area)
+{
+       EvImageAccessible *atk_image;
+
+       atk_image = g_object_new (EV_TYPE_IMAGE_ACCESSIBLE, NULL);
+       atk_image->priv->page = page;
+       atk_image->priv->image = g_object_ref (image);
+       atk_image->priv->area = *area;
+
+       return EV_IMAGE_ACCESSIBLE (atk_image);
+}
diff --git a/libview/ev-image-accessible.h b/libview/ev-image-accessible.h
new file mode 100644
index 0000000..5f637a4
--- /dev/null
+++ b/libview/ev-image-accessible.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/* this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2014 Igalia
+ * Author: Joanmarie Diggs <jdiggs igalia com>
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#if !defined (EVINCE_COMPILATION)
+#error "This is a private header."
+#endif
+
+#ifndef __EV_IMAGE_ACCESSIBLE_H__
+#define __EV_IMAGE_ACCESSIBLE_H__
+
+#include <gtk/gtk-a11y.h>
+#include "ev-page-accessible.h"
+#include "ev-image.h"
+
+#define EV_TYPE_IMAGE_ACCESSIBLE      (ev_image_accessible_get_type ())
+#define EV_IMAGE_ACCESSIBLE(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_IMAGE_ACCESSIBLE, 
EvImageAccessible))
+#define EV_IS_IMAGE_ACCESSIBLE(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_IMAGE_ACCESSIBLE))
+
+typedef struct _EvImageAccessible        EvImageAccessible;
+typedef struct _EvImageAccessibleClass   EvImageAccessibleClass;
+typedef struct _EvImageAccessiblePrivate EvImageAccessiblePrivate;
+
+struct _EvImageAccessible {
+        AtkObject parent;
+        EvImageAccessiblePrivate *priv;
+};
+
+struct _EvImageAccessibleClass {
+        AtkObjectClass parent_class;
+};
+
+GType ev_image_accessible_get_type (void);
+EvImageAccessible *ev_image_accessible_new (EvPageAccessible *page,
+                                           EvImage          *image,
+                                           EvRectangle      *area);
+
+#endif  /* __EV_IMAGE_ACCESSIBLE_H__ */
diff --git a/libview/ev-page-accessible.c b/libview/ev-page-accessible.c
index 1bb0aca..6ba0b32 100644
--- a/libview/ev-page-accessible.c
+++ b/libview/ev-page-accessible.c
@@ -24,6 +24,7 @@
 
 #include <glib/gi18n-lib.h>
 #include "ev-page-accessible.h"
+#include "ev-image-accessible.h"
 #include "ev-link-accessible.h"
 #include "ev-view-private.h"
 
@@ -96,6 +97,7 @@ static void
 ev_page_accessible_initialize_children (EvPageAccessible *self)
 {
        EvView *view;
+       EvMappingList *images;
        EvMappingList *links;
        GList *children = NULL;
        GList *list;
@@ -110,10 +112,12 @@ ev_page_accessible_initialize_children (EvPageAccessible *self)
        self->priv->children_initialized = TRUE;
 
        links = ev_page_cache_get_link_mapping (view->page_cache, self->priv->page);
-       if (!links)
+       images = ev_page_cache_get_image_mapping (view->page_cache, self->priv->page);
+       if (!links && !images)
                return;
 
        children = g_list_copy (ev_mapping_list_get_list (links));
+       children = g_list_concat (children, g_list_copy (ev_mapping_list_get_list (images)));
 
        children = g_list_sort (children, (GCompareFunc) compare_mappings);
        self->priv->children = g_ptr_array_new_full (g_list_length (children), (GDestroyNotify) 
g_object_unref);
@@ -127,7 +131,8 @@ ev_page_accessible_initialize_children (EvPageAccessible *self)
                        AtkHyperlink *atk_link = atk_hyperlink_impl_get_hyperlink (ATK_HYPERLINK_IMPL (link));
 
                        child = atk_hyperlink_get_object (atk_link, 0);
-               }
+               } else if (images && ev_mapping_list_find (images, mapping->data))
+                       child = ATK_OBJECT (ev_image_accessible_new (self, EV_IMAGE (mapping->data), 
&mapping->area));
 
                if (child)
                        g_ptr_array_add (self->priv->children, child);


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