-/* GTK - The GTK+ Toolkit
+/* GTK - The GIMP Toolkit
* gtktextlayout.c - calculate the layout of the text
*
* Copyright (c) 1992-1994 The Regents of the University of California.
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.Free
*
* Original Tk license:
*
#include "gtktextiterprivate.h"
#include "gtktextutil.h"
#include "gtkintl.h"
-#include "gtkalias.h"
#include <stdlib.h>
#include <string.h>
static void gtk_text_layout_update_cursor_line (GtkTextLayout *layout);
+static void line_display_index_to_iter (GtkTextLayout *layout,
+ GtkTextLineDisplay *display,
+ GtkTextIter *iter,
+ gint index,
+ gint trailing);
+
+static gint line_display_iter_to_index (GtkTextLayout *layout,
+ GtkTextLineDisplay *display,
+ const GtkTextIter *iter);
+
enum {
INVALIDATED,
CHANGED,
#define PIXEL_BOUND(d) (((d) + PANGO_SCALE - 1) / PANGO_SCALE)
-static void gtk_text_layout_finalize (GObject *object);
-
static guint signals[LAST_SIGNAL] = { 0 };
PangoAttrType gtk_text_attr_appearance_type = 0;
G_DEFINE_TYPE (GtkTextLayout, gtk_text_layout, G_TYPE_OBJECT)
+static void
+gtk_text_layout_dispose (GObject *object)
+{
+ GtkTextLayout *layout;
+
+ layout = GTK_TEXT_LAYOUT (object);
+
+ gtk_text_layout_set_buffer (layout, NULL);
+
+ if (layout->default_style != NULL)
+ {
+ gtk_text_attributes_unref (layout->default_style);
+ layout->default_style = NULL;
+ }
+
+ g_clear_object (&layout->ltr_context);
+ g_clear_object (&layout->rtl_context);
+
+ if (layout->one_display_cache)
+ {
+ GtkTextLineDisplay *tmp_display = layout->one_display_cache;
+ layout->one_display_cache = NULL;
+ gtk_text_layout_free_line_display (layout, tmp_display);
+ }
+
+ if (layout->preedit_attrs != NULL)
+ {
+ pango_attr_list_unref (layout->preedit_attrs);
+ layout->preedit_attrs = NULL;
+ }
+
+ G_OBJECT_CLASS (gtk_text_layout_parent_class)->dispose (object);
+}
+
+static void
+gtk_text_layout_finalize (GObject *object)
+{
+ GtkTextLayout *layout;
+
+ layout = GTK_TEXT_LAYOUT (object);
+
+ g_free (layout->preedit_string);
+
+ G_OBJECT_CLASS (gtk_text_layout_parent_class)->finalize (object);
+}
+
static void
gtk_text_layout_class_init (GtkTextLayoutClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = gtk_text_layout_dispose;
object_class->finalize = gtk_text_layout_finalize;
klass->wrap = gtk_text_layout_real_wrap;
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT);
+ g_signal_set_va_marshaller (signals[CHANGED], G_TYPE_FROM_CLASS (klass),
+ _gtk_marshal_VOID__INT_INT_INTv);
signals[ALLOCATE_CHILD] =
- g_signal_new (I_("allocate_child"),
+ g_signal_new (I_("allocate-child"),
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkTextLayoutClass, allocate_child),
_gtk_marshal_VOID__OBJECT_INT_INT,
G_TYPE_NONE,
3,
- GTK_TYPE_OBJECT,
+ G_TYPE_OBJECT,
G_TYPE_INT,
G_TYPE_INT);
}
}
-static void
-gtk_text_layout_finalize (GObject *object)
-{
- GtkTextLayout *layout;
-
- layout = GTK_TEXT_LAYOUT (object);
-
- gtk_text_layout_set_buffer (layout, NULL);
-
- if (layout->default_style)
- gtk_text_attributes_unref (layout->default_style);
- layout->default_style = NULL;
-
- if (layout->ltr_context)
- {
- g_object_unref (layout->ltr_context);
- layout->ltr_context = NULL;
- }
- if (layout->rtl_context)
- {
- g_object_unref (layout->rtl_context);
- layout->rtl_context = NULL;
- }
-
- if (layout->one_display_cache)
- {
- GtkTextLineDisplay *tmp_display = layout->one_display_cache;
- layout->one_display_cache = NULL;
- gtk_text_layout_free_line_display (layout, tmp_display);
- }
-
- if (layout->preedit_string)
- {
- g_free (layout->preedit_string);
- layout->preedit_string = NULL;
- }
-
- if (layout->preedit_attrs)
- {
- pango_attr_list_unref (layout->preedit_attrs);
- layout->preedit_attrs = NULL;
- }
-
-
- (* G_OBJECT_CLASS (gtk_text_layout_parent_class)->finalize) (object);
-}
-
+/**
+ * gtk_text_layout_set_buffer:
+ * @buffer: (allow-none):
+ */
void
gtk_text_layout_set_buffer (GtkTextLayout *layout,
GtkTextBuffer *buffer)
_gtk_text_btree_add_view (_gtk_text_buffer_get_btree (buffer), layout);
/* Bind to all signals that move the insert mark. */
- g_signal_connect_after (layout->buffer, "mark_set",
+ g_signal_connect_after (layout->buffer, "mark-set",
G_CALLBACK (gtk_text_layout_mark_set_handler), layout);
- g_signal_connect_after (layout->buffer, "insert_text",
+ g_signal_connect_after (layout->buffer, "insert-text",
G_CALLBACK (gtk_text_layout_buffer_insert_text), layout);
- g_signal_connect_after (layout->buffer, "delete_range",
+ g_signal_connect_after (layout->buffer, "delete-range",
G_CALLBACK (gtk_text_layout_buffer_delete_range), layout);
gtk_text_layout_update_cursor_line (layout);
* @overwrite: overwrite mode
*
* Sets overwrite mode
- **/
+ */
void
gtk_text_layout_set_overwrite_mode (GtkTextLayout *layout,
gboolean overwrite)
* point at which new text is inserted depends on whether the new
* text is right-to-left or left-to-right, so it may be desired to
* make the drawn position of the cursor depend on the keyboard state.
- **/
+ */
void
gtk_text_layout_set_cursor_direction (GtkTextLayout *layout,
GtkTextDirection direction)
* Sets the keyboard direction; this is used as for the bidirectional
* base direction for the line with the cursor if the line contains
* only neutral characters.
- **/
+ */
void
gtk_text_layout_set_keyboard_direction (GtkTextLayout *layout,
GtkTextDirection keyboard_dir)
* gtk_text_layout_set_buffer().
*
* Return value: the text buffer used by the layout.
- **/
+ */
GtkTextBuffer *
gtk_text_layout_get_buffer (GtkTextLayout *layout)
{
* Sets whether the insertion cursor should be shown. Generally,
* widgets using #GtkTextLayout will hide the cursor when the
* widget does not have the input focus.
- **/
+ */
void
gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
gboolean cursor_visible)
* Returns whether the insertion cursor will be shown.
*
* Return value: if %FALSE, the insertion cursor will not be
- shown, even if the text is editable.
- **/
+ * shown, even if the text is editable.
+ */
gboolean
gtk_text_layout_get_cursor_visible (GtkTextLayout *layout)
{
* Set the preedit string and attributes. The preedit string is a
* string showing text that is currently being edited and not
* yet committed into the buffer.
- **/
+ */
void
gtk_text_layout_set_preedit_string (GtkTextLayout *layout,
const gchar *preedit_string,
GtkTextLine *line,
GtkTextLineData *line_data)
{
- (* GTK_TEXT_LAYOUT_GET_CLASS (layout)->free_line_data)
- (layout, line, line_data);
+ GTK_TEXT_LAYOUT_GET_CLASS (layout)->free_line_data (layout, line, line_data);
}
void
const GtkTextIter *start_index,
const GtkTextIter *end_index)
{
- (* GTK_TEXT_LAYOUT_GET_CLASS (layout)->invalidate)
- (layout, start_index, end_index);
+ GTK_TEXT_LAYOUT_GET_CLASS (layout)->invalidate (layout, start_index, end_index);
}
void
const GtkTextIter *start_index,
const GtkTextIter *end_index)
{
- (* GTK_TEXT_LAYOUT_GET_CLASS (layout)->invalidate_cursors)
- (layout, start_index, end_index);
+ GTK_TEXT_LAYOUT_GET_CLASS (layout)->invalidate_cursors (layout, start_index, end_index);
}
GtkTextLineData*
/* may be NULL */
GtkTextLineData *line_data)
{
- return (* GTK_TEXT_LAYOUT_GET_CLASS (layout)->wrap) (layout, line, line_data);
+ return GTK_TEXT_LAYOUT_GET_CLASS (layout)->wrap (layout, line, line_data);
}
+
+/**
+ * gtk_text_layout_get_lines:
+ *
+ * Return value: (element-type GtkTextLine) (transfer container):
+ */
GSList*
gtk_text_layout_get_lines (GtkTextLayout *layout,
/* [top_y, bottom_y) */
if (cursors_only)
{
- g_slist_foreach (display->cursors, (GFunc)g_free, NULL);
- g_slist_free (display->cursors);
+ if (display->cursors)
+ g_array_free (display->cursors, TRUE);
display->cursors = NULL;
display->cursors_invalid = TRUE;
display->has_block_cursor = FALSE;
GtkTextIter line_start, line_end;
GtkTextLine *line = layout->one_display_cache->line;
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- &line_start, line, 0);
+ gtk_text_layout_get_iter_at_line (layout, &line_start, line, 0);
+
line_end = line_start;
if (!gtk_text_iter_ends_line (&line_end))
gtk_text_iter_forward_to_line_end (&line_end);
* Check if there are any invalid regions in a #GtkTextLayout's buffer
*
* Return value: %TRUE if any invalid regions were found
- **/
+ */
gboolean
gtk_text_layout_is_valid (GtkTextLayout *layout)
{
*
* Ensure that a region of a #GtkTextLayout is valid. The ::changed
* signal will be emitted if any lines are validated.
- **/
+ */
void
gtk_text_layout_validate_yrange (GtkTextLayout *layout,
GtkTextIter *anchor,
* invisible/noninvisible toggle state; this function can use the whole btree
* to get it right.
*/
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter, line, 0);
-
+ gtk_text_layout_get_iter_at_line (layout, iter, line, 0);
if (!_gtk_text_btree_char_is_invisible (iter))
return FALSE;
invalidate_cached_style (layout);
/* Bail out if an elision-unsetting tag begins */
- if (seg->body.toggle.info->tag->invisible_set &&
- !seg->body.toggle.info->tag->values->invisible)
+ if (seg->body.toggle.info->tag->priv->invisible_set &&
+ !seg->body.toggle.info->tag->priv->values->invisible)
break;
}
else if (seg->type == >k_text_toggle_off_type)
invalidate_cached_style (layout);
/* Bail out if an elision-setting tag ends */
- if (seg->body.toggle.info->tag->invisible_set &&
- seg->body.toggle.info->tag->values->invisible)
+ if (seg->body.toggle.info->tag->priv->invisible_set &&
+ seg->body.toggle.info->tag->priv->values->invisible)
break;
}
if (style->pg_bg_color)
display->pg_bg_color = gdk_color_copy (style->pg_bg_color);
else
- display->pg_bg_color = NULL;
+ display->pg_bg_color = NULL;
+
+ if (style->pg_bg_rgba)
+ display->pg_bg_rgba = gdk_rgba_copy (style->pg_bg_rgba);
+ else
+ display->pg_bg_rgba = NULL;
}
static PangoAttribute *
{
GtkTextAttrAppearance *appearance_attr = (GtkTextAttrAppearance *)attr;
- if (appearance_attr->appearance.bg_stipple)
- g_object_unref (appearance_attr->appearance.bg_stipple);
- if (appearance_attr->appearance.fg_stipple)
- g_object_unref (appearance_attr->appearance.fg_stipple);
+ if (appearance_attr->appearance.rgba[0])
+ gdk_rgba_free (appearance_attr->appearance.rgba[0]);
+
+ if (appearance_attr->appearance.rgba[1])
+ gdk_rgba_free (appearance_attr->appearance.rgba[1]);
g_slice_free (GtkTextAttrAppearance, appearance_attr);
}
+static gboolean
+rgba_equal (const GdkRGBA *rgba1, const GdkRGBA *rgba2)
+{
+ if (rgba1 && rgba2)
+ return gdk_rgba_equal (rgba1, rgba2);
+
+ if (rgba1 || rgba2)
+ return FALSE;
+
+ return TRUE;
+}
+
static gboolean
gtk_text_attr_appearance_compare (const PangoAttribute *attr1,
const PangoAttribute *attr2)
const GtkTextAppearance *appearance1 = &((const GtkTextAttrAppearance *)attr1)->appearance;
const GtkTextAppearance *appearance2 = &((const GtkTextAttrAppearance *)attr2)->appearance;
- return (gdk_color_equal (&appearance1->fg_color, &appearance2->fg_color) &&
- gdk_color_equal (&appearance1->bg_color, &appearance2->bg_color) &&
- appearance1->fg_stipple == appearance2->fg_stipple &&
- appearance1->bg_stipple == appearance2->bg_stipple &&
+ return (rgba_equal (appearance1->rgba[0], appearance2->rgba[0]) &&
+ rgba_equal (appearance1->rgba[1], appearance2->rgba[1]) &&
appearance1->underline == appearance2->underline &&
appearance1->strikethrough == appearance2->strikethrough &&
appearance1->draw_bg == appearance2->draw_bg);
}
-/**
+/*
* gtk_text_attr_appearance_new:
* @desc:
*
* and size simultaneously.)
*
* Return value:
- **/
+ */
static PangoAttribute *
gtk_text_attr_appearance_new (const GtkTextAppearance *appearance)
{
result->appearance = *appearance;
- if (appearance->bg_stipple)
- g_object_ref (appearance->bg_stipple);
- if (appearance->fg_stipple)
- g_object_ref (appearance->fg_stipple);
+ if (appearance->rgba[0])
+ result->appearance.rgba[0] = gdk_rgba_copy (appearance->rgba[0]);
+
+ if (appearance->rgba[1])
+ result->appearance.rgba[1] = gdk_rgba_copy (appearance->rgba[1]);
return (PangoAttribute *)result;
}
attr->start_index = start;
attr->end_index = start + seg->byte_count;
pango_attr_list_insert (attrs, attr);
-
- display->shaped_objects =
- g_slist_append (display->shaped_objects, pixbuf->pixbuf);
}
static void
/* Found it */
GtkRequisition req;
- gtk_widget_get_child_requisition (child, &req);
-
+ gtk_widget_get_preferred_size (child, &req, NULL);
+
width = req.width;
height = req.height;
widget = NULL;
}
- display->shaped_objects = g_slist_append (display->shaped_objects, widget);
-
logical_rect.x = 0;
logical_rect.y = -height * PANGO_SCALE;
logical_rect.width = width * PANGO_SCALE;
pango_attr_list_insert (attrs, attr);
}
-/**
+/*
* get_block_cursor:
* @layout: a #GtkTextLayout
* @display: a #GtkTextLineDisplay
* Checks whether layout should display block cursor at given position.
* For this layout must be in overwrite mode and text at @insert_iter
* must be editable.
- **/
+ */
static gboolean
get_block_cursor (GtkTextLayout *layout,
GtkTextLineDisplay *display,
GtkTextLineSegment *seg,
gint start)
{
- PangoRectangle strong_pos, weak_pos;
- GtkTextCursorDisplay *cursor = NULL; /* Quiet GCC */
- gboolean add_weak = FALSE;
- gboolean add_strong = FALSE;
-
/* Hide insertion cursor when we have a selection or the layout
* user has hidden the cursor.
*/
}
}
- pango_layout_get_cursor_pos (display->layout, start, &strong_pos, &weak_pos);
+ if (!display->cursors)
+ display->cursors = g_array_new (FALSE, FALSE, sizeof(int));
- if (layout->cursor_direction == GTK_TEXT_DIR_NONE)
- {
- add_strong = TRUE;
- add_weak = TRUE;
- }
- else if (display->direction == layout->cursor_direction)
- add_strong = TRUE;
- else
- add_weak = TRUE;
-
- if (add_strong)
- {
- cursor = g_new (GtkTextCursorDisplay, 1);
-
- cursor->x = PANGO_PIXELS (strong_pos.x);
- cursor->y = PANGO_PIXELS (strong_pos.y);
- cursor->height = PANGO_PIXELS (strong_pos.height);
- cursor->is_strong = TRUE;
- cursor->is_weak = (layout->cursor_direction == GTK_TEXT_DIR_NONE) ? FALSE : TRUE;
- display->cursors = g_slist_prepend (display->cursors, cursor);
- }
-
- if (add_weak)
- {
- if (weak_pos.x == strong_pos.x && add_strong)
- cursor->is_weak = TRUE;
- else
- {
- cursor = g_new (GtkTextCursorDisplay, 1);
-
- cursor->x = PANGO_PIXELS (weak_pos.x);
- cursor->y = PANGO_PIXELS (weak_pos.y);
- cursor->height = PANGO_PIXELS (weak_pos.height);
- cursor->is_strong = (layout->cursor_direction == GTK_TEXT_DIR_NONE) ? FALSE : TRUE;
- cursor->is_weak = TRUE;
- display->cursors = g_slist_prepend (display->cursors, cursor);
- }
- }
+ display->cursors = g_array_append_val (display->cursors, start);
}
static gboolean
allocate_child_widgets (GtkTextLayout *text_layout,
GtkTextLineDisplay *display)
{
- GSList *shaped = display->shaped_objects;
PangoLayout *layout = display->layout;
- PangoLayoutIter *iter;
-
- iter = pango_layout_get_iter (layout);
-
+ PangoLayoutIter *run_iter;
+
+ run_iter = pango_layout_get_iter (layout);
do
{
- PangoLayoutRun *run = pango_layout_iter_get_run_readonly (iter);
+ PangoLayoutRun *run = pango_layout_iter_get_run_readonly (run_iter);
if (run && is_shape (run))
{
- GObject *shaped_object = shaped->data;
- shaped = shaped->next;
-
- /* shaped_object is NULL for child anchors with no
- * widgets stored at them
+ gint byte_index;
+ GtkTextIter text_iter;
+ GtkTextChildAnchor *anchor = NULL;
+ GList *widgets = NULL;
+ GList *l;
+
+ /* The pango iterator iterates in visual order.
+ * We use the byte index to find the child widget.
*/
- if (GTK_IS_WIDGET (shaped_object))
+ byte_index = pango_layout_iter_get_index (run_iter);
+ line_display_index_to_iter (text_layout, display, &text_iter, byte_index, 0);
+ anchor = gtk_text_iter_get_child_anchor (&text_iter);
+ if (anchor)
+ widgets = gtk_text_child_anchor_get_widgets (anchor);
+
+ for (l = widgets; l; l = l->next)
{
PangoRectangle extents;
+ GtkWidget *child = l->data;
- /* We emit "allocate_child" with the x,y of
- * the widget with respect to the top of the line
- * and the left side of the buffer
- */
-
- pango_layout_iter_get_run_extents (iter,
- NULL,
- &extents);
-
- g_signal_emit (text_layout,
- signals[ALLOCATE_CHILD],
- 0,
- shaped_object,
- PANGO_PIXELS (extents.x) + display->x_offset,
- PANGO_PIXELS (extents.y) + display->top_margin);
+ if (_gtk_anchored_child_get_layout (child) == text_layout)
+ {
+
+ /* We emit "allocate_child" with the x,y of
+ * the widget with respect to the top of the line
+ * and the left side of the buffer
+ */
+ pango_layout_iter_get_run_extents (run_iter,
+ NULL,
+ &extents);
+
+ g_signal_emit (text_layout,
+ signals[ALLOCATE_CHILD],
+ 0,
+ child,
+ PANGO_PIXELS (extents.x) + display->x_offset,
+ PANGO_PIXELS (extents.y) + display->top_margin);
+ }
}
+
+ g_list_free (widgets);
}
}
- while (pango_layout_iter_next_run (iter));
-
- pango_layout_iter_free (iter);
+ while (pango_layout_iter_next_run (run_iter));
+
+ pango_layout_iter_free (run_iter);
}
static void
-convert_color (GdkColor *result,
+convert_color (GdkRGBA *result,
PangoAttrColor *attr)
{
- result->red = attr->color.red;
- result->blue = attr->color.blue;
- result->green = attr->color.green;
+ result->red = attr->color.red / 65535.;
+ result->blue = attr->color.blue / 65535.;
+ result->green = attr->color.green / 65535.;
+ result->alpha = 1;
}
/* This function is used to convert the preedit string attributes, which are
while (tmp_list)
{
PangoAttribute *attr = tmp_list->data;
+ GdkRGBA rgba;
switch (attr->klass->type)
{
case PANGO_ATTR_FOREGROUND:
- convert_color (&appearance.fg_color, (PangoAttrColor *)attr);
+ convert_color (&rgba, (PangoAttrColor *)attr);
+ if (appearance.rgba[1])
+ gdk_rgba_free (appearance.rgba[1]);
+ appearance.rgba[1] = gdk_rgba_copy (&rgba);
break;
case PANGO_ATTR_BACKGROUND:
- convert_color (&appearance.bg_color, (PangoAttrColor *)attr);
+ convert_color (&rgba, (PangoAttrColor *)attr);
+ if (appearance.rgba[0])
+ gdk_rgba_free (appearance.rgba[0]);
+ appearance.rgba[0] = gdk_rgba_copy (&rgba);
appearance.draw_bg = TRUE;
break;
case PANGO_ATTR_UNDERLINE:
display->cursors_invalid = FALSE;
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- &iter, line, 0);
-
/* Special-case optimization for completely
* invisible lines; makes it faster to deal
* with sequences of invisible lines.
seg->type == >k_text_pixbuf_type ||
seg->type == >k_text_child_type)
{
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- &iter, line,
+ gtk_text_layout_get_iter_at_line (layout, &iter, line,
buffer_byte_offset);
- if (!_gtk_text_btree_char_is_invisible (&iter))
+ if (!_gtk_text_btree_char_is_invisible (&iter))
layout_byte_offset += seg->byte_count;
buffer_byte_offset += seg->byte_count;
tags = (GtkTextTag**) array->pdata;
- for (pos = 0; pos < array->len && tags[pos]->priority < tag->priority; pos++) ;
+ for (pos = 0; pos < array->len && tags[pos]->priv->priority < tag->priv->priority; pos++) ;
if (pos < array->len && tags[pos] == tag)
g_ptr_array_remove_index (array, pos);
DV (g_print ("creating one line display cache (%s)\n", G_STRLOC));
- display = g_new0 (GtkTextLineDisplay, 1);
+ display = g_slice_new0 (GtkTextLineDisplay);
display->size_only = size_only;
display->line = line;
display->insert_index = -1;
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- &iter, line, 0);
-
/* Special-case optimization for completely
* invisible lines; makes it faster to deal
* with sequences of invisible lines.
size_only, FALSE);
add_pixbuf_attrs (layout, display, style,
seg, attrs, layout_byte_offset);
- memcpy (text + layout_byte_offset, gtk_text_unknown_char_utf8,
+ memcpy (text + layout_byte_offset, _gtk_text_unknown_char_utf8,
seg->byte_count);
layout_byte_offset += seg->byte_count;
buffer_byte_offset += seg->byte_count;
size_only, FALSE);
add_child_attrs (layout, display, style,
seg, attrs, layout_byte_offset);
- memcpy (text + layout_byte_offset, gtk_text_unknown_char_utf8,
+ memcpy (text + layout_byte_offset, _gtk_text_unknown_char_utf8,
seg->byte_count);
layout_byte_offset += seg->byte_count;
buffer_byte_offset += seg->byte_count;
g_object_unref (display->layout);
if (display->cursors)
- {
- g_slist_foreach (display->cursors, (GFunc)g_free, NULL);
- g_slist_free (display->cursors);
- }
- g_slist_free (display->shaped_objects);
-
+ g_array_free (display->cursors, TRUE);
+
if (display->pg_bg_color)
gdk_color_free (display->pg_bg_color);
- g_free (display);
+ if (display->pg_bg_rgba)
+ gdk_rgba_free (display->pg_bg_rgba);
+
+ g_slice_free (GtkTextLineDisplay, display);
}
}
}
}
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter, display->line, 0);
+ gtk_text_layout_get_iter_at_line (layout, iter, display->line, 0);
gtk_text_iter_set_visible_line_index (iter, index);
/* Clamp to end of line - really this clamping should have been done
* before here, maybe in Pango, this is a broken band-aid I think
*/
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter, display->line, 0);
-
+ gtk_text_layout_get_iter_at_line (layout, iter, display->line, 0);
if (!gtk_text_iter_ends_line (iter))
gtk_text_iter_forward_to_line_end (iter);
}
* @target_iter: the iterator in which the result is stored
* @y: the y positition
* @line_top: location to store the y coordinate of the
- * top of the line. (Can by %NULL.)
+ * top of the line. (Can by %NULL)
*
* Get the iter at the beginning of the line which is displayed
* at the given y.
- **/
+ */
void
gtk_text_layout_get_line_at_y (GtkTextLayout *layout,
GtkTextIter *target_iter,
g_return_if_fail (target_iter != NULL);
get_line_at_y (layout, y, &line, line_top);
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- target_iter, line, 0);
+ gtk_text_layout_get_iter_at_line (layout, target_iter, line, 0);
}
void
if (y > display->height - display->top_margin - display->bottom_margin)
{
byte_index = _gtk_text_line_byte_count (line);
- *trailing = 0;
+ if (trailing)
+ *trailing = 0;
}
else
{
* gtk_text_layout_get_cursor_locations:
* @layout: a #GtkTextLayout
* @iter: a #GtkTextIter
- * @strong_pos: location to store the strong cursor position (may be %NULL)
- * @weak_pos: location to store the weak cursor position (may be %NULL)
+ * @strong_pos: (allow-none): location to store the strong cursor position (may be %NULL)
+ * @weak_pos: (allow-none): location to store the weak cursor position (may be %NULL)
*
* Given an iterator within a text layout, determine the positions of the
* strong and weak cursors if the insertion point is at that
line = next;
}
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter, found_line, found_byte);
+ gtk_text_layout_get_iter_at_line (layout, iter, found_line, found_byte);
}
/* Find the iter for the logical beginning of the last display line whose
}
done:
-
+
if (found_line)
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter, found_line, found_byte);
+ gtk_text_layout_get_iter_at_line (layout, iter, found_line, found_byte);
else
gtk_text_buffer_get_iter_at_offset (layout->buffer, iter, 0);
}
iter, line, byte_offset);
}
-
/**
* gtk_text_layout_move_iter_to_x:
* @layout: a #GtkTextLayout
do
{
line = _gtk_text_line_previous (line);
-
if (!line)
goto done;
-
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- &lineiter, line, 0);
}
while (totally_invisible_line (layout, line, &lineiter));
line = _gtk_text_line_next_excluding_last (line);
if (!line)
goto done;
-
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- &lineiter, line, 0);
}
while (totally_invisible_line (layout, line, &lineiter));
-
+
gtk_text_layout_free_line_display (layout, display);
display = gtk_text_layout_get_line_display (layout, line, FALSE);
new_index = 0;
gtk_text_layout_update_cursor_line (layout);
}
-
-#define __GTK_TEXT_LAYOUT_C__
-#include "gtkaliasdef.c"