[gedit/wip/spell-checking] auto-spell: check only visible region
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gedit/wip/spell-checking] auto-spell: check only visible region
- Date: Tue, 21 Jul 2015 10:44:11 +0000 (UTC)
commit fed02f5a80e4eebbb9dd70226fbc4cb828629c18
Author: Sébastien Wilmet <swilmet gnome org>
Date: Tue Jul 21 12:25:16 2015 +0200
auto-spell: check only visible region
plugins/spell/gedit-automatic-spell-checker.c | 150 ++++++++++++++++++++++---
1 files changed, 135 insertions(+), 15 deletions(-)
---
diff --git a/plugins/spell/gedit-automatic-spell-checker.c b/plugins/spell/gedit-automatic-spell-checker.c
index abdf688..3ef0a8c 100644
--- a/plugins/spell/gedit-automatic-spell-checker.c
+++ b/plugins/spell/gedit-automatic-spell-checker.c
@@ -177,38 +177,158 @@ check_subregion (GeditAutomaticSpellChecker *spell,
}
static void
-check_region (GeditAutomaticSpellChecker *spell)
+check_region (GeditAutomaticSpellChecker *spell,
+ GtkTextRegion *region)
{
GtkTextRegionIterator region_iter;
-#if ENABLE_DEBUG
- GTimer *timer;
-#endif
- if (spell->scan_region == NULL)
+ if (region == NULL)
{
return;
}
-#if ENABLE_DEBUG
- timer = g_timer_new ();
-#endif
-
- gtk_text_region_get_iterator (spell->scan_region, ®ion_iter, 0);
+ gtk_text_region_get_iterator (region, ®ion_iter, 0);
while (!gtk_text_region_iterator_is_end (®ion_iter))
{
GtkTextIter start;
GtkTextIter end;
- gtk_text_region_iterator_get_subregion (®ion_iter, &start, &end);
+ if (!gtk_text_region_iterator_get_subregion (®ion_iter, &start, &end))
+ {
+ return;
+ }
check_subregion (spell, &start, &end);
gtk_text_region_iterator_next (®ion_iter);
}
+}
+
+static void
+get_visible_region (GtkTextView *view,
+ GtkTextIter *start,
+ GtkTextIter *end)
+{
+ GdkRectangle visible_rect;
+
+ gtk_text_view_get_visible_rect (view, &visible_rect);
+
+ gtk_text_view_get_line_at_y (view,
+ start,
+ visible_rect.y,
+ NULL);
+
+ gtk_text_view_get_line_at_y (view,
+ end,
+ visible_rect.y + visible_rect.height,
+ NULL);
+
+ gtk_text_iter_backward_line (start);
+ gtk_text_iter_forward_line (end);
+}
+
+/* A TextRegion can contain empty subregions. So checking the number of
+ * subregions is not sufficient.
+ * When calling gtk_text_region_add() with equal iters, the subregion is not
+ * added. But when a subregion becomes empty, due to text deletion, the
+ * subregion is not removed from the TextRegion.
+ */
+static gboolean
+is_text_region_empty (GtkTextRegion *region)
+{
+ GtkTextRegionIterator region_iter;
+
+ if (region == NULL)
+ {
+ return TRUE;
+ }
+
+ gtk_text_region_get_iterator (region, ®ion_iter, 0);
+
+ while (!gtk_text_region_iterator_is_end (®ion_iter))
+ {
+ GtkTextIter region_start;
+ GtkTextIter region_end;
+
+ if (!gtk_text_region_iterator_get_subregion (®ion_iter,
+ ®ion_start,
+ ®ion_end))
+ {
+ return TRUE;
+ }
+
+ if (!gtk_text_iter_equal (®ion_start, ®ion_end))
+ {
+ return FALSE;
+ }
+
+ gtk_text_region_iterator_next (®ion_iter);
+ }
+
+ return TRUE;
+}
+
+static void
+check_visible_region_in_view (GeditAutomaticSpellChecker *spell,
+ GtkTextView *view)
+{
+ GtkTextIter visible_start;
+ GtkTextIter visible_end;
+ GtkTextRegion *intersect;
+
+ if (spell->scan_region == NULL)
+ {
+ return;
+ }
+
+ get_visible_region (view, &visible_start, &visible_end);
- gtk_text_region_destroy (spell->scan_region);
- spell->scan_region = NULL;
+ intersect = gtk_text_region_intersect (spell->scan_region,
+ &visible_start,
+ &visible_end);
+
+ if (intersect == NULL)
+ {
+ return;
+ }
+
+ check_region (spell, intersect);
+ gtk_text_region_destroy (intersect);
+
+ gtk_text_region_subtract (spell->scan_region,
+ &visible_start,
+ &visible_end);
+
+ if (is_text_region_empty (spell->scan_region))
+ {
+ gtk_text_region_destroy (spell->scan_region);
+ spell->scan_region = NULL;
+ }
+}
+
+static void
+check_visible_region (GeditAutomaticSpellChecker *spell)
+{
+ GSList *l;
+#if ENABLE_DEBUG
+ GTimer *timer;
+#endif
+
+ if (spell->scan_region == NULL)
+ {
+ return;
+ }
+
+#if ENABLE_DEBUG
+ timer = g_timer_new ();
+#endif
+
+ for (l = spell->views; l != NULL; l = l->next)
+ {
+ GtkTextView *view = l->data;
+ check_visible_region_in_view (spell, view);
+ }
#if ENABLE_DEBUG
g_print ("%s() executed in %lf seconds\n",
@@ -222,7 +342,7 @@ check_region (GeditAutomaticSpellChecker *spell)
static gboolean
timeout_cb (GeditAutomaticSpellChecker *spell)
{
- check_region (spell);
+ check_visible_region (spell);
spell->timeout_id = 0;
return G_SOURCE_REMOVE;
@@ -998,7 +1118,7 @@ gedit_automatic_spell_checker_recheck_all (GeditAutomaticSpellChecker *spell)
gtk_text_buffer_get_bounds (spell->buffer, &start, &end);
add_subregion_to_scan (spell, &start, &end);
- check_region (spell);
+ check_visible_region (spell);
}
/* ex:set ts=8 noet: */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]