* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#define GTK_TEXT_USE_INTERNAL_UNSUPPORTED_API
#include "gtksignal.h"
+#include "gtkmarshalers.h"
#include "gtktextlayout.h"
#include "gtktextbtree.h"
#include "gtktextiterprivate.h"
#include <stdlib.h>
#include <string.h>
-static GtkTextLineData *gtk_text_line_data_new (GtkTextLayout *layout,
- GtkTextLine *line);
-
static GtkTextLineData *gtk_text_layout_real_wrap (GtkTextLayout *layout,
GtkTextLine *line,
/* may be NULL */
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkTextLayoutClass, invalidated),
NULL, NULL,
- gtk_marshal_VOID__VOID,
+ _gtk_marshal_VOID__VOID,
GTK_TYPE_NONE,
0);
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkTextLayoutClass, changed),
NULL, NULL,
- gtk_marshal_VOID__INT_INT_INT,
+ _gtk_marshal_VOID__INT_INT_INT,
GTK_TYPE_NONE,
3,
GTK_TYPE_INT,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkTextLayoutClass, allocate_child),
NULL, NULL,
- gtk_marshal_VOID__OBJECT_INT_INT,
+ _gtk_marshal_VOID__OBJECT_INT_INT,
GTK_TYPE_NONE,
3,
GTK_TYPE_OBJECT,
GTK_TYPE_INT);
}
-void
+static void
gtk_text_layout_init (GtkTextLayout *text_layout)
{
text_layout->cursor_visible = TRUE;
{
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
+ DV (g_print ("invalidating all due to default style change (%s)\n", G_STRLOC));
gtk_text_layout_invalidate_all (layout);
}
layout->rtl_context = rtl_context;
g_object_ref (G_OBJECT (rtl_context));
+ DV (g_print ("invalidating all due to new pango contexts (%s)\n", G_STRLOC));
gtk_text_layout_invalidate_all (layout);
}
layout->screen_width = width;
+ DV (g_print ("invalidating all due to new screen width (%s)\n", G_STRLOC));
gtk_text_layout_invalidate_all (layout);
}
*
* Check if there are any invalid regions in a #GtkTextLayout's buffer
*
- * Return value: #TRUE if any invalid regions were found
+ * Return value: %TRUE if any invalid regions were found
**/
gboolean
gtk_text_layout_is_valid (GtkTextLayout *layout)
GtkTextLineDisplay *display;
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), NULL);
-
+ g_return_val_if_fail (line != NULL, NULL);
+
if (line_data == NULL)
{
- line_data = gtk_text_line_data_new (layout, line);
+ line_data = _gtk_text_line_data_new (layout, line);
_gtk_text_line_add_data (line, line_data);
}
cursor->y = PANGO_PIXELS (strong_pos.y);
cursor->height = PANGO_PIXELS (strong_pos.height);
cursor->is_strong = TRUE;
- cursor->is_weak = FALSE;
+ cursor->is_weak = (layout->cursor_direction == GTK_TEXT_DIR_NONE) ? FALSE : TRUE;
display->cursors = g_slist_prepend (display->cursors, cursor);
}
cursor->x = PANGO_PIXELS (weak_pos.x);
cursor->y = PANGO_PIXELS (weak_pos.y);
cursor->height = PANGO_PIXELS (weak_pos.height);
- cursor->is_strong = FALSE;
+ cursor->is_strong = (layout->cursor_direction == GTK_TEXT_DIR_NONE) ? FALSE : TRUE;
cursor->is_weak = TRUE;
display->cursors = g_slist_prepend (display->cursors, cursor);
}
gtk_text_iter_forward_chars (iter, trailing);
}
-/* FIXME: This really doesn't belong in this file ... */
-static GtkTextLineData*
-gtk_text_line_data_new (GtkTextLayout *layout,
- GtkTextLine *line)
-{
- GtkTextLineData *line_data;
-
- line_data = g_new (GtkTextLineData, 1);
-
- line_data->view_id = layout;
- line_data->next = NULL;
- line_data->width = 0;
- line_data->height = 0;
- line_data->valid = FALSE;
-
- return line_data;
-}
-
static void
get_line_at_y (GtkTextLayout *layout,
gint y,
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
g_return_if_fail (target_iter != NULL);
- /* Adjust pixels to be on-screen. This gives nice
- behavior if the user is dragging with a pointer grab.
- */
- if (x < 0)
- x = 0;
- if (x > layout->width)
- x = layout->width;
-
get_line_at_y (layout, y, &line, &line_top);
display = gtk_text_layout_get_line_display (layout, line, FALSE);
x -= display->x_offset;
y -= line_top + display->top_margin;
- /* We clamp y to the area of the actual layout so that the layouts
- * hit testing works OK on the space above and below the layout
+ /* If we are below the layout, position the cursor at the last character
+ * of the line.
*/
- y = CLAMP (y, 0, display->height - display->top_margin - display->bottom_margin - 1);
-
- if (!pango_layout_xy_to_index (display->layout, x * PANGO_SCALE, y * PANGO_SCALE,
- &byte_index, &trailing))
+ if (y > display->height - display->top_margin - display->bottom_margin)
{
byte_index = _gtk_text_line_byte_count (line);
trailing = 0;
}
+ else
+ {
+ /* Ignore the "outside" return value from pango. Pango is doing
+ * the right thing even if we are outside the layout in the
+ * x-direction.
+ */
+ pango_layout_xy_to_index (display->layout, x * PANGO_SCALE, y * PANGO_SCALE,
+ &byte_index, &trailing);
+ }
line_display_index_to_iter (layout, display, target_iter, byte_index, trailing);
}
}
+/**
+ * _gtk_text_layout_get_line_xrange:
+ * @layout: a #GtkTextLayout
+ * @iter: a #GtkTextIter
+ * @x: location to store the top of the paragraph in pixels,
+ * or %NULL.
+ * @width location to store the height of the paragraph in pixels,
+ * or %NULL.
+ *
+ * Find the range of X coordinates for the paragraph containing
+ * the given iter. Private for 2.0 due to API freeze, could
+ * be made public for 2.2.
+ **/
+void
+_gtk_text_layout_get_line_xrange (GtkTextLayout *layout,
+ const GtkTextIter *iter,
+ gint *x,
+ gint *width)
+{
+ GtkTextLine *line;
+
+ g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
+ g_return_if_fail (_gtk_text_iter_get_btree (iter) == _gtk_text_buffer_get_btree (layout->buffer));
+
+ line = _gtk_text_iter_get_text_line (iter);
+
+ if (x)
+ *x = 0; /* FIXME This is wrong; should represent the first available cursor position */
+
+ if (width)
+ {
+ GtkTextLineData *line_data = _gtk_text_line_get_data (line, layout);
+ if (line_data)
+ *width = line_data->width;
+ else
+ *width = 0;
+ }
+}
+
void
gtk_text_layout_get_iter_location (GtkTextLayout *layout,
const GtkTextIter *iter,
if (tmp_top < y)
{
found_line = line;
+ pango_layout_iter_free (layout_iter);
goto done;
}
}