[evince] debug: Add support for drawing different debug borders in EvView
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince] debug: Add support for drawing different debug borders in EvView
- Date: Thu, 11 Jul 2013 13:39:15 +0000 (UTC)
commit f95607dd4b4be7174950f57c6c8f99d67aa0e019
Author: Carlos Garcia Campos <carlosgc gnome org>
Date: Thu Jul 11 15:33:18 2013 +0200
debug: Add support for drawing different debug borders in EvView
When evince is built with debug support, the env variable
EV_DEBUG_SHOW_BORDERS can be used to draw different debug borders in
EvView using different colors. Depending on the value of the env
variable and and the features supported by the current backend, it can
draw bounding boxes of characters, links, images, form fields,
annotations and selection region.
libdocument/ev-debug.c | 54 ++++++++++++++
libdocument/ev-debug.h | 18 ++++-
libview/ev-view.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 255 insertions(+), 2 deletions(-)
---
diff --git a/libdocument/ev-debug.c b/libdocument/ev-debug.c
index 344510f..475f612 100644
--- a/libdocument/ev-debug.c
+++ b/libdocument/ev-debug.c
@@ -37,15 +37,60 @@
#endif
#include <stdio.h>
+#include <string.h>
#include "ev-debug.h"
#ifdef EV_ENABLE_DEBUG
static EvDebugSection ev_debug = EV_NO_DEBUG;
static EvProfileSection ev_profile = EV_NO_PROFILE;
+static EvDebugBorders ev_debug_borders = EV_DEBUG_BORDER_NONE;
static GHashTable *timers = NULL;
+static gboolean
+ev_debug_parse_show_borders (const gchar *show_debug_borders)
+{
+ gchar **items;
+ guint i;
+
+ if (!show_debug_borders)
+ return FALSE;
+
+ items = g_strsplit (show_debug_borders, ",", -1);
+ if (!items)
+ return FALSE;
+
+ for (i = 0; items[i]; i++) {
+ if (g_strcmp0 (items[i], "all") == 0) {
+ ev_debug_borders = EV_DEBUG_BORDER_ALL;
+ break;
+ }
+
+ if (g_strcmp0 (items[i], "none") == 0) {
+ ev_debug_borders = EV_DEBUG_BORDER_NONE;
+ break;
+ }
+
+ if (strcmp (items[i], "chars") == 0)
+ ev_debug_borders |= EV_DEBUG_BORDER_CHARS;
+ if (strcmp (items[i], "links") == 0)
+ ev_debug_borders |= EV_DEBUG_BORDER_LINKS;
+ if (strcmp (items[i], "forms") == 0)
+ ev_debug_borders |= EV_DEBUG_BORDER_FORMS;
+ if (strcmp (items[i], "annots") == 0)
+ ev_debug_borders |= EV_DEBUG_BORDER_ANNOTS;
+ if (strcmp (items[i], "images") == 0)
+ ev_debug_borders |= EV_DEBUG_BORDER_IMAGES;
+ if (strcmp (items[i], "selections") == 0)
+ ev_debug_borders |= EV_DEBUG_BORDER_SELECTIONS;
+ }
+
+ g_strfreev (items);
+
+ return ev_debug_borders != EV_DEBUG_BORDER_NONE;
+}
+
static void
debug_init (void)
{
@@ -57,6 +102,9 @@ debug_init (void)
if (g_getenv ("EV_DEBUG_JOBS") != NULL)
ev_debug |= EV_DEBUG_JOBS;
+
+ if (ev_debug_parse_show_borders (g_getenv ("EV_DEBUG_SHOW_BORDERS")))
+ ev_debug |= EV_DEBUG_SHOW_BORDERS;
}
static void
@@ -174,4 +222,10 @@ ev_profiler_stop (EvProfileSection section,
}
}
+EvDebugBorders
+ev_debug_get_debug_borders (void)
+{
+ return ev_debug_borders;
+}
+
#endif /* EV_ENABLE_DEBUG */
diff --git a/libdocument/ev-debug.h b/libdocument/ev-debug.h
index cf25243..dff1028 100644
--- a/libdocument/ev-debug.h
+++ b/libdocument/ev-debug.h
@@ -71,10 +71,22 @@ G_BEGIN_DECLS
* sections.
*/
typedef enum {
- EV_NO_DEBUG = 0,
- EV_DEBUG_JOBS = 1 << 0
+ EV_NO_DEBUG = 0,
+ EV_DEBUG_JOBS = 1 << 0,
+ EV_DEBUG_SHOW_BORDERS = 1 << 1
} EvDebugSection;
+typedef enum {
+ EV_DEBUG_BORDER_NONE = 0,
+ EV_DEBUG_BORDER_CHARS = 1 << 0,
+ EV_DEBUG_BORDER_LINKS = 1 << 1,
+ EV_DEBUG_BORDER_FORMS = 1 << 2,
+ EV_DEBUG_BORDER_ANNOTS = 1 << 3,
+ EV_DEBUG_BORDER_IMAGES = 1 << 4,
+ EV_DEBUG_BORDER_SELECTIONS = 1 << 5,
+ EV_DEBUG_BORDER_ALL = (1 << 6) - 1
+} EvDebugBorders;
+
#define DEBUG_JOBS EV_DEBUG_JOBS, __FILE__, __LINE__, G_STRFUNC
/*
@@ -100,6 +112,8 @@ void ev_profiler_start (EvProfileSection section,
void ev_profiler_stop (EvProfileSection section,
const gchar *format, ...) G_GNUC_PRINTF(2, 3);
+EvDebugBorders ev_debug_get_debug_borders (void);
+
G_END_DECLS
#endif /* EV_ENABLE_DEBUG */
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 60381f6..6c8d2d9 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -43,6 +43,7 @@
#include "ev-view-accessible.h"
#include "ev-view-private.h"
#include "ev-view-type-builtins.h"
+#include "ev-debug.h"
#define EV_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_VIEW, EvViewClass))
#define EV_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_VIEW))
@@ -3817,6 +3818,186 @@ should_draw_caret_cursor (EvView *view,
!ev_pixbuf_cache_get_selection_region (view->pixbuf_cache, page, view->scale));
}
+#ifdef EV_ENABLE_DEBUG
+static void
+stroke_view_rect (cairo_t *cr,
+ GdkRectangle *clip,
+ GdkRectangle *view_rect)
+{
+ GdkRectangle intersect;
+
+ if (gdk_rectangle_intersect (view_rect, clip, &intersect)) {
+ cairo_rectangle (cr,
+ intersect.x, intersect.y,
+ intersect.width, intersect.height);
+ cairo_stroke (cr);
+ }
+}
+
+static void
+stroke_doc_rect (EvView *view,
+ cairo_t *cr,
+ gint page,
+ GdkRectangle *clip,
+ EvRectangle *doc_rect)
+{
+ GdkRectangle view_rect;
+
+ _ev_view_transform_doc_rect_to_view_rect (view, page, doc_rect, &view_rect);
+ view_rect.x -= view->scroll_x;
+ view_rect.y -= view->scroll_y;
+ stroke_view_rect (cr, clip, &view_rect);
+}
+
+static void
+show_chars_border (EvView *view,
+ cairo_t *cr,
+ gint page,
+ GdkRectangle *clip)
+{
+ EvRectangle *areas = NULL;
+ guint n_areas = 0;
+ guint i;
+
+ ev_page_cache_get_text_layout (view->page_cache, page, &areas, &n_areas);
+ if (!areas)
+ return;
+
+ cairo_set_source_rgb (cr, 1., 0., 0.);
+
+ for (i = 0; i < n_areas; i++) {
+ EvRectangle *doc_rect = areas + i;
+
+ stroke_doc_rect (view, cr, page, clip, doc_rect);
+ }
+}
+
+static void
+show_mapping_list_border (EvView *view,
+ cairo_t *cr,
+ gint page,
+ GdkRectangle *clip,
+ EvMappingList *mapping_list)
+{
+ GList *l;
+
+ for (l = ev_mapping_list_get_list (mapping_list); l; l = g_list_next (l)) {
+ EvMapping *mapping = (EvMapping *)l->data;
+
+ stroke_doc_rect (view, cr, page, clip, &mapping->area);
+ }
+}
+
+static void
+show_links_border (EvView *view,
+ cairo_t *cr,
+ gint page,
+ GdkRectangle *clip)
+{
+ cairo_set_source_rgb (cr, 0., 0., 1.);
+ show_mapping_list_border (view,cr, page, clip,
+ ev_page_cache_get_link_mapping (view->page_cache, page));
+}
+
+static void
+show_forms_border (EvView *view,
+ cairo_t *cr,
+ gint page,
+ GdkRectangle *clip)
+{
+ cairo_set_source_rgb (cr, 0., 1., 0.);
+ show_mapping_list_border (view, cr, page, clip,
+ ev_page_cache_get_form_field_mapping (view->page_cache, page));
+}
+
+static void
+show_annots_border (EvView *view,
+ cairo_t *cr,
+ gint page,
+ GdkRectangle *clip)
+{
+ cairo_set_source_rgb (cr, 0., 1., 1.);
+ show_mapping_list_border (view, cr, page, clip,
+ ev_page_cache_get_annot_mapping (view->page_cache, page));
+}
+
+static void
+show_images_border (EvView *view,
+ cairo_t *cr,
+ gint page,
+ GdkRectangle *clip)
+{
+ cairo_set_source_rgb (cr, 1., 0., 1.);
+ show_mapping_list_border (view, cr, page, clip,
+ ev_page_cache_get_image_mapping (view->page_cache, page));
+}
+
+static void
+show_selections_border (EvView *view,
+ cairo_t *cr,
+ gint page,
+ GdkRectangle *clip)
+{
+ cairo_region_t *region;
+ guint i, n_rects;
+ GdkRectangle page_area;
+ GtkBorder border;
+
+ region = ev_page_cache_get_text_mapping (view->page_cache, page);
+ if (!region)
+ return;
+
+ cairo_set_source_rgb (cr, 0.75, 0.50, 0.25);
+
+ ev_view_get_page_extents (view, page, &page_area, &border);
+
+ region = cairo_region_copy (region);
+ cairo_region_intersect_rectangle (region, clip);
+ n_rects = cairo_region_num_rectangles (region);
+ for (i = 0; i < n_rects; i++) {
+ GdkRectangle view_rect;
+
+ cairo_region_get_rectangle (region, i, &view_rect);
+ view_rect.x = (gint)(view_rect.x * view->scale + 0.5);
+ view_rect.y = (gint)(view_rect.y * view->scale + 0.5);
+ view_rect.width = (gint)(view_rect.width * view->scale + 0.5);
+ view_rect.height = (gint)(view_rect.height * view->scale + 0.5);
+
+ view_rect.x += page_area.x + border.left - view->scroll_x;
+ view_rect.y += page_area.y + border.right - view->scroll_y;
+ stroke_view_rect (cr, clip, &view_rect);
+ }
+ cairo_region_destroy (region);
+}
+
+static void
+draw_debug_borders (EvView *view,
+ cairo_t *cr,
+ gint page,
+ GdkRectangle *clip)
+{
+ EvDebugBorders borders = ev_debug_get_debug_borders();
+
+ cairo_save (cr);
+ cairo_set_line_width (cr, 0.5);
+
+ if (borders & EV_DEBUG_BORDER_CHARS)
+ show_chars_border (view, cr, page, clip);
+ if (borders & EV_DEBUG_BORDER_LINKS)
+ show_links_border (view, cr, page, clip);
+ if (borders & EV_DEBUG_BORDER_FORMS)
+ show_forms_border (view, cr, page, clip);
+ if (borders & EV_DEBUG_BORDER_ANNOTS)
+ show_annots_border (view, cr, page, clip);
+ if (borders & EV_DEBUG_BORDER_IMAGES)
+ show_images_border (view, cr, page, clip);
+ if (borders & EV_DEBUG_BORDER_SELECTIONS)
+ show_selections_border (view, cr, page, clip);
+
+ cairo_restore (cr);
+}
+#endif
+
static gboolean
ev_view_draw (GtkWidget *widget,
cairo_t *cr)
@@ -3860,6 +4041,10 @@ ev_view_draw (GtkWidget *widget,
focus_annotation (view, cr, i, &clip_rect);
if (page_ready && view->synctex_result)
highlight_forward_search_results (view, cr, i);
+#ifdef EV_ENABLE_DEBUG
+ if (page_ready)
+ draw_debug_borders (view, cr, i, &clip_rect);
+#endif
}
if (GTK_WIDGET_CLASS (ev_view_parent_class)->draw)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]