]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktextlayout.c
Implement gtk_event_box_get/set_input_only()
[~andy/gtk] / gtk / gtktextlayout.c
index ddfcc7fad8cd23fac9391c87c949a56412d37bdf..3fed7624c47c7943f53b085f628233f8d43c4cb1 100644 (file)
@@ -101,6 +101,10 @@ static void gtk_text_layout_invalidate_cursor_line (GtkTextLayout     *layout);
 static void gtk_text_layout_real_free_line_data    (GtkTextLayout     *layout,
                                                    GtkTextLine       *line,
                                                    GtkTextLineData   *line_data);
+static void gtk_text_layout_emit_changed           (GtkTextLayout     *layout,
+                                                   gint               y,
+                                                   gint               old_height,
+                                                   gint               new_height);
 
 static void gtk_text_layout_invalidate_all (GtkTextLayout *layout);
 
@@ -118,6 +122,8 @@ enum {
   LAST_ARG
 };
 
+#define PIXEL_BOUND(d) (((d) + PANGO_SCALE - 1) / PANGO_SCALE)
+
 static void gtk_text_layout_init       (GtkTextLayout      *text_layout);
 static void gtk_text_layout_class_init (GtkTextLayoutClass *klass);
 static void gtk_text_layout_finalize   (GObject            *object);
@@ -430,7 +436,7 @@ gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
                                         gtk_text_buffer_get_mark (layout->buffer, "insert"));
 
       gtk_text_layout_get_line_yrange (layout, &iter, &y, &height);
-      gtk_text_layout_changed (layout, y, height, height);
+      gtk_text_layout_emit_changed (layout, y, height, height);
 
       gtk_text_layout_invalidate_cache (layout, _gtk_text_iter_get_text_line (&iter));
     }
@@ -518,13 +524,36 @@ gtk_text_layout_invalidated (GtkTextLayout *layout)
   g_signal_emit (layout, signals[INVALIDATED], 0);
 }
 
+static void
+gtk_text_layout_emit_changed (GtkTextLayout *layout,
+                             gint           y,
+                             gint           old_height,
+                             gint           new_height)
+{
+  g_signal_emit (layout, signals[CHANGED], 0, y, old_height, new_height);
+}
+
 void
 gtk_text_layout_changed (GtkTextLayout *layout,
                          gint           y,
                          gint           old_height,
                          gint           new_height)
 {
-  g_signal_emit (layout, signals[CHANGED], 0, y, old_height, new_height);
+  /* Check if the range intersects our cached line display,
+   * and invalidate the cached line if so.
+   */
+  if (layout->one_display_cache)
+    {
+      GtkTextLine *line = layout->one_display_cache->line;
+      gint cache_y = _gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
+                                                   line, layout);
+      gint cache_height = layout->one_display_cache->height;
+
+      if (cache_y + cache_height > y && cache_y < y + old_height)
+       gtk_text_layout_invalidate_cache (layout, line);
+    }
+  
+  gtk_text_layout_emit_changed (layout, y, old_height, new_height);
 }
 
 void
@@ -812,6 +841,7 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
   /* Validate backwards from the anchor line to y0
    */
   line = _gtk_text_iter_get_text_line (anchor);
+  line = _gtk_text_line_previous (line);
   seen = 0;
   while (line && seen < -y0)
     {
@@ -827,11 +857,11 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
           delta_height += line_data->height - old_height;
           
           first_line = line;
-          first_line_y = -seen;
+          first_line_y = -seen - line_data->height;
           if (!last_line)
             {
               last_line = line;
-              last_line_y = -seen + line_data->height;
+              last_line_y = -seen;
             }
         }
 
@@ -880,10 +910,10 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
       line_top = _gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
                                                 first_line, layout);
 
-      gtk_text_layout_changed (layout,
-                               line_top,
-                               last_line_y - first_line_y - delta_height,
-                               last_line_y - first_line_y);
+      gtk_text_layout_emit_changed (layout,
+                                   line_top,
+                                   last_line_y - first_line_y - delta_height,
+                                   last_line_y - first_line_y);
     }
 }
 
@@ -912,7 +942,7 @@ gtk_text_layout_validate (GtkTextLayout *layout,
       max_pixels -= new_height;
 
       update_layout_size (layout);
-      gtk_text_layout_changed (layout, y, old_height, new_height);
+      gtk_text_layout_emit_changed (layout, y, old_height, new_height);
     }
 }
 
@@ -1155,6 +1185,12 @@ set_para_values (GtkTextLayout      *layout,
       pango_layout_set_wrap (display->layout, PANGO_WRAP_WORD);
       break;
 
+    case GTK_WRAP_WORD_CHAR:
+      layout_width = layout->screen_width - display->left_margin - display->right_margin;
+      pango_layout_set_width (display->layout, layout_width * PANGO_SCALE);
+      pango_layout_set_wrap (display->layout, PANGO_WRAP_WORD_CHAR);
+      break;
+
     case GTK_WRAP_NONE:
       break;
     }
@@ -1938,7 +1974,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
 
   pango_layout_get_extents (display->layout, NULL, &extents);
 
-  display->width = PANGO_PIXELS (extents.width) + display->left_margin + display->right_margin;
+  display->width = PIXEL_BOUND (extents.width) + display->left_margin + display->right_margin;
   display->height += PANGO_PIXELS (extents.height);
   
   /* Free this if we aren't in a loop */
@@ -2154,6 +2190,7 @@ gtk_text_layout_get_cursor_locations (GtkTextLayout  *layout,
   GtkTextLineDisplay *display;
   gint line_top;
   gint index;
+  GtkTextIter insert_iter;
 
   PangoRectangle pango_strong_pos;
   PangoRectangle pango_weak_pos;
@@ -2168,6 +2205,13 @@ gtk_text_layout_get_cursor_locations (GtkTextLayout  *layout,
   line_top = _gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
                                            line, layout);
   
+  gtk_text_buffer_get_iter_at_mark (layout->buffer, &insert_iter,
+                                    gtk_text_buffer_get_mark (layout->buffer,
+                                                              "insert"));
+
+  if (gtk_text_iter_equal (iter, &insert_iter))
+    index += layout->preedit_cursor - layout->preedit_len;
+  
   pango_layout_get_cursor_pos (display->layout, index,
                                strong_pos ? &pango_strong_pos : NULL,
                                weak_pos ? &pango_weak_pos : NULL);
@@ -2681,6 +2725,9 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
       line = _gtk_text_line_next_excluding_last (line);
     }
 
+  if (!found_after)
+    gtk_text_buffer_get_end_iter (layout->buffer, iter);
+  
   return
     !gtk_text_iter_equal (iter, &orig) &&
     !gtk_text_iter_is_end (iter);