diff options
-rw-r--r-- | ChangeLog | 51 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 51 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 51 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 51 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 51 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 51 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 51 | ||||
-rw-r--r-- | gdk/gdkpango.c | 72 | ||||
-rw-r--r-- | gtk/gtkimmodule.c | 2 | ||||
-rw-r--r-- | gtk/gtktextdisplay.c | 177 | ||||
-rw-r--r-- | gtk/gtktextlayout.c | 182 | ||||
-rw-r--r-- | gtk/gtktextlayout.h | 5 | ||||
-rw-r--r-- | gtk/gtktexttag.c | 41 | ||||
-rw-r--r-- | gtk/gtktexttag.h | 8 | ||||
-rw-r--r-- | gtk/gtktextview.c | 319 | ||||
-rw-r--r-- | gtk/gtktextview.h | 60 | ||||
-rw-r--r-- | gtk/testtext.c | 39 | ||||
-rw-r--r-- | tests/testtext.c | 39 |
18 files changed, 996 insertions, 305 deletions
@@ -1,3 +1,54 @@ +2000-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtkimmodule.c (gtk_im_module_init): Free the filename of + the module file. + + * gtk/gtktexttag.c (gtk_text_attributes_copy): fix memory leak of + dest->language + + * gtk/testtext.c: Test pixels above/below/inside paragraphs + settings + + * gtk/gtktextview.c: Implement object args and setters/getters for + all the aspects of the GtkTextAttributes that are not set from + GtkWidget attributes. This is spacing, justification, margins, + etc. + + (gtk_text_view_set_arg) + (gtk_text_view_get_arg): implement get/set for editable, wrap mode + args + (gtk_text_view_class_init): Add args for justify, left_margin, + right_margin, indent, and tabs + + + * gtk/gtktextlayout.c (set_para_values): fix to display indent + attribute properly + + * gtk/gtktexttag.c: Remove left_wrapped_line_margin attribute, + replace with indent attribute + + * gtk/gtktextlayout.c (set_para_values): multiply indent by + PANGO_SCALE + + * gtk/gtktextdisplay.c (render_para): Use PangoLayoutIter, + rearranging code to do that + (gtk_text_layout_draw): Pass in the y for the whole LineDisplay, + i.e. don't subtract the top_margin first, just to keep + all margin-futzing in one place. + + * gdk/gdkpango.c (gdk_draw_layout): Use PangoLayoutIter + + * gtk/gtktextlayout.c (gtk_text_layout_get_iter_location): Remove + special case of last line, Pango now handles this itself. + (gtk_text_layout_get_iter_at_pixel): Fix incorrect clamp of the + Y coordinate + (gtk_text_layout_move_iter_to_x): port to use PangoLayoutIter + (find_display_line_above): wasn't moving the byte index as it + iterated over lines, so always returned byte 0. Also, port to use + PangoLayoutIter. + (find_display_line_below): same problem as + find_display_line_above. Also, port to use PangoLayoutIter. + 2000-11-13 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/*.[ch]: diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 4ea80557cc..e2ce6bdcc3 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,54 @@ +2000-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtkimmodule.c (gtk_im_module_init): Free the filename of + the module file. + + * gtk/gtktexttag.c (gtk_text_attributes_copy): fix memory leak of + dest->language + + * gtk/testtext.c: Test pixels above/below/inside paragraphs + settings + + * gtk/gtktextview.c: Implement object args and setters/getters for + all the aspects of the GtkTextAttributes that are not set from + GtkWidget attributes. This is spacing, justification, margins, + etc. + + (gtk_text_view_set_arg) + (gtk_text_view_get_arg): implement get/set for editable, wrap mode + args + (gtk_text_view_class_init): Add args for justify, left_margin, + right_margin, indent, and tabs + + + * gtk/gtktextlayout.c (set_para_values): fix to display indent + attribute properly + + * gtk/gtktexttag.c: Remove left_wrapped_line_margin attribute, + replace with indent attribute + + * gtk/gtktextlayout.c (set_para_values): multiply indent by + PANGO_SCALE + + * gtk/gtktextdisplay.c (render_para): Use PangoLayoutIter, + rearranging code to do that + (gtk_text_layout_draw): Pass in the y for the whole LineDisplay, + i.e. don't subtract the top_margin first, just to keep + all margin-futzing in one place. + + * gdk/gdkpango.c (gdk_draw_layout): Use PangoLayoutIter + + * gtk/gtktextlayout.c (gtk_text_layout_get_iter_location): Remove + special case of last line, Pango now handles this itself. + (gtk_text_layout_get_iter_at_pixel): Fix incorrect clamp of the + Y coordinate + (gtk_text_layout_move_iter_to_x): port to use PangoLayoutIter + (find_display_line_above): wasn't moving the byte index as it + iterated over lines, so always returned byte 0. Also, port to use + PangoLayoutIter. + (find_display_line_below): same problem as + find_display_line_above. Also, port to use PangoLayoutIter. + 2000-11-13 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/*.[ch]: diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 4ea80557cc..e2ce6bdcc3 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,54 @@ +2000-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtkimmodule.c (gtk_im_module_init): Free the filename of + the module file. + + * gtk/gtktexttag.c (gtk_text_attributes_copy): fix memory leak of + dest->language + + * gtk/testtext.c: Test pixels above/below/inside paragraphs + settings + + * gtk/gtktextview.c: Implement object args and setters/getters for + all the aspects of the GtkTextAttributes that are not set from + GtkWidget attributes. This is spacing, justification, margins, + etc. + + (gtk_text_view_set_arg) + (gtk_text_view_get_arg): implement get/set for editable, wrap mode + args + (gtk_text_view_class_init): Add args for justify, left_margin, + right_margin, indent, and tabs + + + * gtk/gtktextlayout.c (set_para_values): fix to display indent + attribute properly + + * gtk/gtktexttag.c: Remove left_wrapped_line_margin attribute, + replace with indent attribute + + * gtk/gtktextlayout.c (set_para_values): multiply indent by + PANGO_SCALE + + * gtk/gtktextdisplay.c (render_para): Use PangoLayoutIter, + rearranging code to do that + (gtk_text_layout_draw): Pass in the y for the whole LineDisplay, + i.e. don't subtract the top_margin first, just to keep + all margin-futzing in one place. + + * gdk/gdkpango.c (gdk_draw_layout): Use PangoLayoutIter + + * gtk/gtktextlayout.c (gtk_text_layout_get_iter_location): Remove + special case of last line, Pango now handles this itself. + (gtk_text_layout_get_iter_at_pixel): Fix incorrect clamp of the + Y coordinate + (gtk_text_layout_move_iter_to_x): port to use PangoLayoutIter + (find_display_line_above): wasn't moving the byte index as it + iterated over lines, so always returned byte 0. Also, port to use + PangoLayoutIter. + (find_display_line_below): same problem as + find_display_line_above. Also, port to use PangoLayoutIter. + 2000-11-13 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/*.[ch]: diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 4ea80557cc..e2ce6bdcc3 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,54 @@ +2000-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtkimmodule.c (gtk_im_module_init): Free the filename of + the module file. + + * gtk/gtktexttag.c (gtk_text_attributes_copy): fix memory leak of + dest->language + + * gtk/testtext.c: Test pixels above/below/inside paragraphs + settings + + * gtk/gtktextview.c: Implement object args and setters/getters for + all the aspects of the GtkTextAttributes that are not set from + GtkWidget attributes. This is spacing, justification, margins, + etc. + + (gtk_text_view_set_arg) + (gtk_text_view_get_arg): implement get/set for editable, wrap mode + args + (gtk_text_view_class_init): Add args for justify, left_margin, + right_margin, indent, and tabs + + + * gtk/gtktextlayout.c (set_para_values): fix to display indent + attribute properly + + * gtk/gtktexttag.c: Remove left_wrapped_line_margin attribute, + replace with indent attribute + + * gtk/gtktextlayout.c (set_para_values): multiply indent by + PANGO_SCALE + + * gtk/gtktextdisplay.c (render_para): Use PangoLayoutIter, + rearranging code to do that + (gtk_text_layout_draw): Pass in the y for the whole LineDisplay, + i.e. don't subtract the top_margin first, just to keep + all margin-futzing in one place. + + * gdk/gdkpango.c (gdk_draw_layout): Use PangoLayoutIter + + * gtk/gtktextlayout.c (gtk_text_layout_get_iter_location): Remove + special case of last line, Pango now handles this itself. + (gtk_text_layout_get_iter_at_pixel): Fix incorrect clamp of the + Y coordinate + (gtk_text_layout_move_iter_to_x): port to use PangoLayoutIter + (find_display_line_above): wasn't moving the byte index as it + iterated over lines, so always returned byte 0. Also, port to use + PangoLayoutIter. + (find_display_line_below): same problem as + find_display_line_above. Also, port to use PangoLayoutIter. + 2000-11-13 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/*.[ch]: diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 4ea80557cc..e2ce6bdcc3 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,54 @@ +2000-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtkimmodule.c (gtk_im_module_init): Free the filename of + the module file. + + * gtk/gtktexttag.c (gtk_text_attributes_copy): fix memory leak of + dest->language + + * gtk/testtext.c: Test pixels above/below/inside paragraphs + settings + + * gtk/gtktextview.c: Implement object args and setters/getters for + all the aspects of the GtkTextAttributes that are not set from + GtkWidget attributes. This is spacing, justification, margins, + etc. + + (gtk_text_view_set_arg) + (gtk_text_view_get_arg): implement get/set for editable, wrap mode + args + (gtk_text_view_class_init): Add args for justify, left_margin, + right_margin, indent, and tabs + + + * gtk/gtktextlayout.c (set_para_values): fix to display indent + attribute properly + + * gtk/gtktexttag.c: Remove left_wrapped_line_margin attribute, + replace with indent attribute + + * gtk/gtktextlayout.c (set_para_values): multiply indent by + PANGO_SCALE + + * gtk/gtktextdisplay.c (render_para): Use PangoLayoutIter, + rearranging code to do that + (gtk_text_layout_draw): Pass in the y for the whole LineDisplay, + i.e. don't subtract the top_margin first, just to keep + all margin-futzing in one place. + + * gdk/gdkpango.c (gdk_draw_layout): Use PangoLayoutIter + + * gtk/gtktextlayout.c (gtk_text_layout_get_iter_location): Remove + special case of last line, Pango now handles this itself. + (gtk_text_layout_get_iter_at_pixel): Fix incorrect clamp of the + Y coordinate + (gtk_text_layout_move_iter_to_x): port to use PangoLayoutIter + (find_display_line_above): wasn't moving the byte index as it + iterated over lines, so always returned byte 0. Also, port to use + PangoLayoutIter. + (find_display_line_below): same problem as + find_display_line_above. Also, port to use PangoLayoutIter. + 2000-11-13 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/*.[ch]: diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 4ea80557cc..e2ce6bdcc3 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,54 @@ +2000-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtkimmodule.c (gtk_im_module_init): Free the filename of + the module file. + + * gtk/gtktexttag.c (gtk_text_attributes_copy): fix memory leak of + dest->language + + * gtk/testtext.c: Test pixels above/below/inside paragraphs + settings + + * gtk/gtktextview.c: Implement object args and setters/getters for + all the aspects of the GtkTextAttributes that are not set from + GtkWidget attributes. This is spacing, justification, margins, + etc. + + (gtk_text_view_set_arg) + (gtk_text_view_get_arg): implement get/set for editable, wrap mode + args + (gtk_text_view_class_init): Add args for justify, left_margin, + right_margin, indent, and tabs + + + * gtk/gtktextlayout.c (set_para_values): fix to display indent + attribute properly + + * gtk/gtktexttag.c: Remove left_wrapped_line_margin attribute, + replace with indent attribute + + * gtk/gtktextlayout.c (set_para_values): multiply indent by + PANGO_SCALE + + * gtk/gtktextdisplay.c (render_para): Use PangoLayoutIter, + rearranging code to do that + (gtk_text_layout_draw): Pass in the y for the whole LineDisplay, + i.e. don't subtract the top_margin first, just to keep + all margin-futzing in one place. + + * gdk/gdkpango.c (gdk_draw_layout): Use PangoLayoutIter + + * gtk/gtktextlayout.c (gtk_text_layout_get_iter_location): Remove + special case of last line, Pango now handles this itself. + (gtk_text_layout_get_iter_at_pixel): Fix incorrect clamp of the + Y coordinate + (gtk_text_layout_move_iter_to_x): port to use PangoLayoutIter + (find_display_line_above): wasn't moving the byte index as it + iterated over lines, so always returned byte 0. Also, port to use + PangoLayoutIter. + (find_display_line_below): same problem as + find_display_line_above. Also, port to use PangoLayoutIter. + 2000-11-13 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/*.[ch]: diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 4ea80557cc..e2ce6bdcc3 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,54 @@ +2000-11-13 Havoc Pennington <hp@redhat.com> + + * gtk/gtkimmodule.c (gtk_im_module_init): Free the filename of + the module file. + + * gtk/gtktexttag.c (gtk_text_attributes_copy): fix memory leak of + dest->language + + * gtk/testtext.c: Test pixels above/below/inside paragraphs + settings + + * gtk/gtktextview.c: Implement object args and setters/getters for + all the aspects of the GtkTextAttributes that are not set from + GtkWidget attributes. This is spacing, justification, margins, + etc. + + (gtk_text_view_set_arg) + (gtk_text_view_get_arg): implement get/set for editable, wrap mode + args + (gtk_text_view_class_init): Add args for justify, left_margin, + right_margin, indent, and tabs + + + * gtk/gtktextlayout.c (set_para_values): fix to display indent + attribute properly + + * gtk/gtktexttag.c: Remove left_wrapped_line_margin attribute, + replace with indent attribute + + * gtk/gtktextlayout.c (set_para_values): multiply indent by + PANGO_SCALE + + * gtk/gtktextdisplay.c (render_para): Use PangoLayoutIter, + rearranging code to do that + (gtk_text_layout_draw): Pass in the y for the whole LineDisplay, + i.e. don't subtract the top_margin first, just to keep + all margin-futzing in one place. + + * gdk/gdkpango.c (gdk_draw_layout): Use PangoLayoutIter + + * gtk/gtktextlayout.c (gtk_text_layout_get_iter_location): Remove + special case of last line, Pango now handles this itself. + (gtk_text_layout_get_iter_at_pixel): Fix incorrect clamp of the + Y coordinate + (gtk_text_layout_move_iter_to_x): port to use PangoLayoutIter + (find_display_line_above): wasn't moving the byte index as it + iterated over lines, so always returned byte 0. Also, port to use + PangoLayoutIter. + (find_display_line_below): same problem as + find_display_line_above. Also, port to use PangoLayoutIter. + 2000-11-13 Alexander Larsson <alexl@redhat.com> * gdk/linux-fb/*.[ch]: diff --git a/gdk/gdkpango.c b/gdk/gdkpango.c index 2a10fcc8e2..e0e9675ec0 100644 --- a/gdk/gdkpango.c +++ b/gdk/gdkpango.c @@ -272,73 +272,33 @@ gdk_draw_layout (GdkDrawable *drawable, int y, PangoLayout *layout) { - PangoRectangle logical_rect; - GSList *tmp_list; - PangoAlignment align; - gint indent; - gint width; - gint y_offset = 0; - gboolean first = FALSE; + PangoLayoutIter *iter; g_return_if_fail (drawable != NULL); g_return_if_fail (gc != NULL); g_return_if_fail (layout != NULL); - indent = pango_layout_get_indent (layout); - width = pango_layout_get_width (layout); - align = pango_layout_get_alignment (layout); - - if (width == -1 && align != PANGO_ALIGN_LEFT) - { - pango_layout_get_extents (layout, NULL, &logical_rect); - width = logical_rect.width; - } + iter = pango_layout_get_iter (layout); - tmp_list = pango_layout_get_lines (layout); - while (tmp_list) + do { - PangoLayoutLine *line = tmp_list->data; - int x_offset; + PangoRectangle logical_rect; + PangoLayoutLine *line; + int baseline; + + line = pango_layout_iter_get_line (iter); + + pango_layout_iter_get_line_extents (iter, NULL, &logical_rect); + baseline = pango_layout_iter_get_baseline (iter); - pango_layout_line_get_extents (line, NULL, &logical_rect); - - if (width != -1 && align == PANGO_ALIGN_RIGHT) - x_offset = width - logical_rect.width; - else if (width != -1 && align == PANGO_ALIGN_CENTER) - x_offset = (width - logical_rect.width) / 2; - else - x_offset = 0; - - if (first) - { - if (indent > 0) - { - if (align == PANGO_ALIGN_LEFT) - x_offset += indent; - else - x_offset -= indent; - } - - first = FALSE; - } - else - { - if (indent < 0) - { - if (align == PANGO_ALIGN_LEFT) - x_offset -= indent; - else - x_offset += indent; - } - } - gdk_draw_layout_line (drawable, gc, - x + x_offset / PANGO_SCALE, y + (y_offset - logical_rect.y) / PANGO_SCALE, + x + logical_rect.x / PANGO_SCALE, + y + baseline / PANGO_SCALE, line); - - y_offset += logical_rect.height; - tmp_list = tmp_list->next; } + while (pango_layout_iter_next_line (iter)); + + pango_layout_iter_free (iter); } static void diff --git a/gtk/gtkimmodule.c b/gtk/gtkimmodule.c index 353100720b..017f7ecfb0 100644 --- a/gtk/gtkimmodule.c +++ b/gtk/gtkimmodule.c @@ -241,6 +241,7 @@ gtk_im_module_init () { g_warning ("Can not open Input Method module file '%s': %s", filename, g_strerror (errno)); + /* We are leaking all kinds of memory here. */ return; } @@ -338,6 +339,7 @@ gtk_im_module_init () fclose (file); g_string_free (line_buf, TRUE); g_string_free (tmp_buf, TRUE); + g_free (filename); } /** diff --git a/gtk/gtktextdisplay.c b/gtk/gtktextdisplay.c index 10fd95c562..5e42b6439f 100644 --- a/gtk/gtktextdisplay.c +++ b/gtk/gtktextdisplay.c @@ -232,14 +232,14 @@ render_layout_line (GdkDrawable *drawable, if (appearance->draw_bg && !selected) gdk_draw_rectangle (drawable, render_state->bg_gc, TRUE, - x + (x_off + logical_rect.x) / PANGO_SCALE, - y + logical_rect.y / PANGO_SCALE, - logical_rect.width / PANGO_SCALE, - logical_rect.height / PANGO_SCALE); + x + PANGO_PIXELS (x_off) + PANGO_PIXELS (logical_rect.x), + y + PANGO_PIXELS (logical_rect.y), + PANGO_PIXELS (logical_rect.width), + PANGO_PIXELS (logical_rect.height)); gdk_draw_glyphs (drawable, fg_gc, run->item->analysis.font, - x + x_off / PANGO_SCALE, y, run->glyphs); + x + PANGO_PIXELS (x_off), y, run->glyphs); switch (appearance->underline) { @@ -373,85 +373,70 @@ static void render_para (GdkDrawable *drawable, GtkTextRenderState *render_state, GtkTextLineDisplay *line_display, + /* Top-left corner of paragraph including all margins */ int x, int y, int selection_start_index, int selection_end_index) { - PangoRectangle logical_rect; GSList *shaped_pointer = line_display->shaped_objects; - GSList *tmp_list; - PangoAlignment align; PangoLayout *layout = line_display->layout; - int indent; - int total_width; - int y_offset = 0; int byte_offset = 0; - + PangoLayoutIter *iter; + PangoRectangle layout_logical; + int screen_width; + gboolean first = TRUE; - indent = pango_layout_get_indent (layout); - total_width = pango_layout_get_width (layout); - align = pango_layout_get_alignment (layout); + iter = pango_layout_get_iter (layout); - if (total_width < 0) - total_width = line_display->total_width * PANGO_SCALE; + pango_layout_iter_get_layout_extents (iter, NULL, &layout_logical); - tmp_list = pango_layout_get_lines (layout); - while (tmp_list) + /* Adjust for margins */ + + layout_logical.x += line_display->x_offset * PANGO_SCALE; + layout_logical.y += line_display->top_margin * PANGO_SCALE; + + screen_width = line_display->total_width; + if (screen_width < 0) { - PangoLayoutLine *line = tmp_list->data; - int x_offset; + screen_width = pango_layout_get_width (layout); + screen_width = PANGO_PIXELS (screen_width); + } + + do + { + PangoLayoutLine *line = pango_layout_iter_get_line (iter); int selection_y, selection_height; - - pango_layout_line_get_extents (line, NULL, &logical_rect); - - x_offset = line_display->left_margin * PANGO_SCALE; - - switch (align) - { - case PANGO_ALIGN_RIGHT: - x_offset += total_width - logical_rect.width; - break; - case PANGO_ALIGN_CENTER: - x_offset += (total_width - logical_rect.width) / 2; - break; - default: - break; - } - - if (first) - { - if (indent > 0) - { - if (align == PANGO_ALIGN_LEFT) - x_offset += indent; - else - x_offset -= indent; - } - } - else - { - if (indent < 0) - { - if (align == PANGO_ALIGN_LEFT) - x_offset -= indent; - else - x_offset += indent; - } - } - - selection_y = y + y_offset / PANGO_SCALE; - selection_height = logical_rect.height / PANGO_SCALE; + int first_y, last_y; + PangoRectangle line_rect; + int baseline; + + pango_layout_iter_get_line_extents (iter, NULL, &line_rect); + baseline = pango_layout_iter_get_baseline (iter); + pango_layout_iter_get_line_yrange (iter, &first_y, &last_y); + + /* Adjust for margins */ + + line_rect.x += line_display->x_offset * PANGO_SCALE; + line_rect.y += line_display->top_margin * PANGO_SCALE; + baseline += line_display->top_margin * PANGO_SCALE; + + /* Selection is the height of the line, plus top/bottom + * margin if we're the first/last line + */ + selection_y = y + PANGO_PIXELS (first_y) + line_display->top_margin; + selection_height = PANGO_PIXELS (last_y) - PANGO_PIXELS (first_y); if (first) { selection_y -= line_display->top_margin; selection_height += line_display->top_margin; } - if (!tmp_list->next) + + if (pango_layout_iter_at_last_line (iter)) selection_height += line_display->bottom_margin; - + first = FALSE; if (selection_start_index < byte_offset && @@ -460,18 +445,24 @@ render_para (GdkDrawable *drawable, gdk_draw_rectangle (drawable, render_state->widget->style->bg_gc[GTK_STATE_SELECTED], TRUE, - x + line_display->left_margin, selection_y, - total_width / PANGO_SCALE, selection_height); + x + line_display->left_margin, + selection_y, + screen_width, + selection_height); + render_layout_line (drawable, render_state, line, &shaped_pointer, - x + x_offset / PANGO_SCALE, y + (y_offset - logical_rect.y) / PANGO_SCALE, + x + PANGO_PIXELS (line_rect.x), + y + PANGO_PIXELS (baseline), TRUE); } else { GSList *shaped_pointer_tmp = shaped_pointer; - render_layout_line (drawable, render_state, line, &shaped_pointer, - x + x_offset / PANGO_SCALE, y + (y_offset - logical_rect.y) / PANGO_SCALE, + render_layout_line (drawable, render_state, + line, &shaped_pointer, + x + PANGO_PIXELS (line_rect.x), + y + PANGO_PIXELS (baseline), FALSE); if (selection_start_index < byte_offset + line->length && @@ -479,7 +470,8 @@ render_para (GdkDrawable *drawable, { GdkRegion *clip_region = get_selected_clip (render_state, layout, line, x + line_display->x_offset, - selection_y, selection_height, + selection_y, + selection_height, selection_start_index, selection_end_index); gdk_gc_set_clip_region (render_state->widget->style->fg_gc [GTK_STATE_SELECTED], clip_region); @@ -488,12 +480,14 @@ render_para (GdkDrawable *drawable, gdk_draw_rectangle (drawable, render_state->widget->style->bg_gc[GTK_STATE_SELECTED], TRUE, - x + x_offset / PANGO_SCALE, selection_y, - logical_rect.width / PANGO_SCALE, + x + PANGO_PIXELS (line_rect.x), + selection_y, + PANGO_PIXELS (line_rect.width), selection_height); render_layout_line (drawable, render_state, line, &shaped_pointer_tmp, - x + x_offset / PANGO_SCALE, y + (y_offset - logical_rect.y) / PANGO_SCALE, + x + PANGO_PIXELS (line_rect.x), + y + PANGO_PIXELS (baseline), TRUE); gdk_gc_set_clip_region (render_state->widget->style->fg_gc [GTK_STATE_SELECTED], NULL); @@ -502,39 +496,46 @@ render_para (GdkDrawable *drawable, gdk_region_destroy (clip_region); /* Paint in the ends of the line */ - if (x_offset > line_display->left_margin * PANGO_SCALE && + if (line_rect.x > line_display->left_margin * PANGO_SCALE && ((line_display->direction == GTK_TEXT_DIR_LTR && selection_start_index < byte_offset) || (line_display->direction == GTK_TEXT_DIR_RTL && selection_end_index > byte_offset + line->length))) { gdk_draw_rectangle (drawable, render_state->widget->style->bg_gc[GTK_STATE_SELECTED], TRUE, - x + line_display->left_margin, selection_y, - x + x_offset / PANGO_SCALE - line_display->left_margin, + x + line_display->left_margin, + selection_y, + PANGO_PIXELS (line_rect.x) - line_display->left_margin, selection_height); } - if (x_offset + logical_rect.width < line_display->left_margin * PANGO_SCALE + total_width && + if (line_rect.x + line_rect.width < + (screen_width + line_display->left_margin) * PANGO_SCALE && ((line_display->direction == GTK_TEXT_DIR_LTR && selection_end_index > byte_offset + line->length) || (line_display->direction == GTK_TEXT_DIR_RTL && selection_start_index < byte_offset))) { + int nonlayout_width; + nonlayout_width = + line_display->left_margin + screen_width - + PANGO_PIXELS (line_rect.x) - PANGO_PIXELS (line_rect.width); gdk_draw_rectangle (drawable, render_state->widget->style->bg_gc[GTK_STATE_SELECTED], TRUE, - x + (x_offset + logical_rect.width) / PANGO_SCALE, + x + PANGO_PIXELS (line_rect.x) + PANGO_PIXELS (line_rect.width), selection_y, - x + (line_display->left_margin * PANGO_SCALE + total_width - x_offset - logical_rect.width) / PANGO_SCALE, + nonlayout_width, selection_height); } } } byte_offset += line->length; - y_offset += logical_rect.height; - tmp_list = tmp_list->next; } + while (pango_layout_iter_next_line (iter)); + + pango_layout_iter_free (iter); } static GdkRegion * @@ -551,20 +552,18 @@ get_selected_clip (GtkTextRenderState *render_state, gint n_ranges, i; GdkRegion *clip_region = gdk_region_new (); GdkRegion *tmp_region; - PangoRectangle logical_rect; - pango_layout_line_get_extents (line, NULL, &logical_rect); pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges); for (i=0; i < n_ranges; i++) { GdkRectangle rect; - rect.x = x + ranges[2*i] / PANGO_SCALE; + rect.x = x + PANGO_PIXELS (ranges[2*i]); rect.y = y; - rect.width = (ranges[2*i + 1] - ranges[2*i]) / PANGO_SCALE; + rect.width = PANGO_PIXELS (ranges[2*i + 1]) - PANGO_PIXELS (ranges[2*i]); rect.height = height; - + gdk_region_union_with_rect (clip_region, &rect); } @@ -614,13 +613,13 @@ gtk_text_layout_draw (GtkTextLayout *layout, { GdkRectangle clip; gint current_y; - GSList *line_list; - GSList *tmp_list; GSList *cursor_list; GtkTextRenderState *render_state; GtkTextIter selection_start, selection_end; gboolean have_selection = FALSE; - + GSList *line_list; + GSList *tmp_list; + g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout)); g_return_if_fail (layout->default_style != NULL); g_return_if_fail (layout->buffer != NULL); @@ -696,7 +695,7 @@ gtk_text_layout_draw (GtkTextLayout *layout, render_para (drawable, render_state, line_display, - x_offset, - current_y + line_display->top_margin, + current_y, selection_start_index, selection_end_index); diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index 5bf696a593..e7cc89c2fd 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -1105,7 +1105,8 @@ set_para_values (GtkTextLayout *layout, } pango_layout_set_alignment (display->layout, pango_align); - pango_layout_set_spacing (display->layout, style->pixels_inside_wrap * PANGO_SCALE); + pango_layout_set_spacing (display->layout, + style->pixels_inside_wrap * PANGO_SCALE); if (style->tabs) pango_layout_set_tabs (display->layout, style->tabs); @@ -1113,10 +1114,26 @@ set_para_values (GtkTextLayout *layout, display->top_margin = style->pixels_above_lines; display->height = style->pixels_above_lines + style->pixels_below_lines; display->bottom_margin = style->pixels_below_lines; - display->x_offset = display->left_margin = MIN (style->left_margin, style->left_wrapped_line_margin); + display->left_margin = style->left_margin; display->right_margin = style->right_margin; + + if (style->indent < 0) + { + /* This means the margins can be negative. FIXME + * test that things work if they are. + */ + + if (pango_align == PANGO_ALIGN_LEFT) + display->left_margin += style->indent; + else if (pango_align == PANGO_ALIGN_RIGHT) + display->right_margin += style->indent; + } + + display->x_offset = display->left_margin; + - pango_layout_set_indent (display->layout, style->left_margin - style->left_wrapped_line_margin); + pango_layout_set_indent (display->layout, + style->indent * PANGO_SCALE); switch (style->wrap_mode) { @@ -1124,11 +1141,11 @@ set_para_values (GtkTextLayout *layout, /* FIXME: Handle this; for now, fall-through */ case GTK_WRAPMODE_WORD: display->total_width = -1; - layout_width = layout->screen_width - display->x_offset - style->right_margin; + layout_width = layout->screen_width - display->left_margin - display->right_margin; pango_layout_set_width (display->layout, layout_width * PANGO_SCALE); break; case GTK_WRAPMODE_NONE: - display->total_width = MAX (layout->screen_width, layout->width) - display->x_offset - style->right_margin; + display->total_width = MAX (layout->screen_width, layout->width) - display->left_margin - display->right_margin; break; } } @@ -1737,10 +1754,10 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout, pango_layout_get_extents (display->layout, NULL, &extents); if (display->total_width >= 0) - display->x_offset += (display->total_width - extents.width / PANGO_SCALE) * align; + display->x_offset += (display->total_width - PANGO_PIXELS (extents.width)) * align; - display->width = extents.width / PANGO_SCALE + display->left_margin + display->right_margin; - display->height += extents.height / PANGO_SCALE; + display->width = PANGO_PIXELS (extents.width) + display->x_offset + display->right_margin; + display->height += PANGO_PIXELS (extents.height); /* Free this if we aren't in a loop */ if (layout->wrap_loop_count == 0) @@ -1915,7 +1932,7 @@ gtk_text_layout_get_iter_at_pixel (GtkTextLayout *layout, /* 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 */ - y = CLAMP (y, display->top_margin, display->height - display->top_margin - display->bottom_margin - 1); + 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)) @@ -2040,10 +2057,7 @@ gtk_text_layout_get_iter_location (GtkTextLayout *layout, GtkTextBTree *tree; GtkTextLineDisplay *display; gint byte_index; - PangoRectangle whole_para; - gint total_width; gint x_offset; - PangoAlignment align; 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)); @@ -2056,54 +2070,16 @@ gtk_text_layout_get_iter_location (GtkTextLayout *layout, rect->y = gtk_text_btree_find_line_top (tree, line, layout); - pango_layout_get_extents (display->layout, NULL, &whole_para); - - total_width = pango_layout_get_width (display->layout); - align = pango_layout_get_alignment (display->layout); - - if (total_width < 0) - total_width = display->total_width * PANGO_SCALE; + x_offset = display->x_offset * PANGO_SCALE; + + byte_index = gtk_text_iter_get_line_index (iter); - x_offset = display->left_margin * PANGO_SCALE; + pango_layout_index_to_pos (display->layout, byte_index, &pango_rect); - switch (align) - { - case PANGO_ALIGN_RIGHT: - x_offset += total_width - whole_para.width; - break; - case PANGO_ALIGN_CENTER: - x_offset += (total_width - whole_para.width) / 2; - break; - default: - break; - } - - /* pango_layout_index_to_pos () expects the index of a character within the layout, - * so we have to special case the last character. FIXME: This should be moved - * to Pango. - */ - if (gtk_text_iter_ends_line (iter)) - { - PangoLayoutLine *last_line = g_slist_last (pango_layout_get_lines (display->layout))->data; - - pango_layout_line_get_extents (last_line, NULL, &pango_rect); - - rect->x = PANGO_PIXELS (x_offset + pango_rect.x + pango_rect.width); - rect->y += PANGO_PIXELS (whole_para.height - pango_rect.height) + display->top_margin; - rect->width = 0; - rect->height = PANGO_PIXELS (pango_rect.height); - } - else - { - byte_index = line_display_iter_to_index (layout, display, iter); - - pango_layout_index_to_pos (display->layout, byte_index, &pango_rect); - - rect->x = PANGO_PIXELS (x_offset + pango_rect.x); - rect->y += PANGO_PIXELS (pango_rect.y) + display->top_margin; - rect->width = PANGO_PIXELS (pango_rect.width); - rect->height = PANGO_PIXELS (pango_rect.height); - } + rect->x = PANGO_PIXELS (x_offset + pango_rect.x); + rect->y += PANGO_PIXELS (pango_rect.y) + display->top_margin; + rect->width = PANGO_PIXELS (pango_rect.width); + rect->height = PANGO_PIXELS (pango_rect.height); gtk_text_layout_free_line_display (layout, display); } @@ -2141,29 +2117,34 @@ find_display_line_below (GtkTextLayout *layout, { GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, FALSE); gint byte_index = 0; - GSList *tmp_list = pango_layout_get_lines (display->layout); + PangoLayoutIter *layout_iter; + + layout_iter = pango_layout_get_iter (display->layout); line_top += display->top_margin; - while (tmp_list) + do { - PangoRectangle logical_rect; - PangoLayoutLine *layout_line = tmp_list->data; + gint first_y, last_y; + PangoLayoutLine *layout_line = pango_layout_iter_get_line (layout_iter); found_byte = byte_index; - + if (line_top >= y) { found_line = line; break; } - pango_layout_line_get_extents (layout_line, NULL, &logical_rect); - line_top += logical_rect.height / PANGO_SCALE; + pango_layout_iter_get_line_yrange (layout_iter, &first_y, &last_y); + line_top += (last_y - first_y) / PANGO_SCALE; - tmp_list = tmp_list->next; + byte_index += layout_line->length; } + while (pango_layout_iter_next_line (layout_iter)); + pango_layout_iter_free (layout_iter); + line_top += display->bottom_margin; gtk_text_layout_free_line_display (layout, display); @@ -2206,40 +2187,48 @@ find_display_line_above (GtkTextLayout *layout, PangoRectangle logical_rect; gint byte_index = 0; - GSList *tmp_list; + PangoLayoutIter *layout_iter; gint tmp_top; + layout_iter = pango_layout_get_iter (display->layout); + line_top -= display->top_margin + display->bottom_margin; - pango_layout_get_extents (display->layout, NULL, &logical_rect); + pango_layout_iter_get_layout_extents (layout_iter, NULL, &logical_rect); line_top -= logical_rect.height / PANGO_SCALE; tmp_top = line_top + display->top_margin; - tmp_list = pango_layout_get_lines (display->layout); - while (tmp_list) + do { - PangoLayoutLine *layout_line = tmp_list->data; + gint first_y, last_y; + PangoLayoutLine *layout_line = pango_layout_iter_get_line (layout_iter); found_byte = byte_index; - tmp_top += logical_rect.height / PANGO_SCALE; + pango_layout_iter_get_line_yrange (layout_iter, &first_y, &last_y); + + tmp_top -= (last_y - first_y) / PANGO_SCALE; if (tmp_top < y) { found_line = line; found_byte = byte_index; + goto done; } - pango_layout_line_get_extents (layout_line, NULL, &logical_rect); - - tmp_list = tmp_list->next; + byte_index += layout_line->length; } + while (pango_layout_iter_next_line (layout_iter)); + pango_layout_iter_free (layout_iter); + gtk_text_layout_free_line_display (layout, display); line = gtk_text_line_previous (line); } + done: + if (found_line) gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer), iter, found_line, found_byte); @@ -2512,8 +2501,8 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout, GtkTextLineDisplay *display; gint line_byte; gint byte_offset = 0; - GSList *tmp_list; - + PangoLayoutIter *layout_iter; + g_return_if_fail (layout != NULL); g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout)); g_return_if_fail (iter != NULL); @@ -2523,49 +2512,36 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout, display = gtk_text_layout_get_line_display (layout, line, FALSE); line_byte = line_display_iter_to_index (layout, display, iter); - tmp_list = pango_layout_get_lines (display->layout); - while (tmp_list) + layout_iter = pango_layout_get_iter (display->layout); + + do { - PangoLayoutLine *layout_line = tmp_list->data; + PangoLayoutLine *layout_line = pango_layout_iter_get_line (layout_iter); - if (line_byte < byte_offset + layout_line->length || !tmp_list->next) + if (line_byte < byte_offset + layout_line->length || + pango_layout_iter_at_last_line (layout_iter)) { PangoRectangle logical_rect; gint byte_index, trailing; - gint align = pango_layout_get_alignment (display->layout); - gint x_offset = display->left_margin * PANGO_SCALE; - gint width = pango_layout_get_width (display->layout); - - if (width < 0) - width = display->total_width * PANGO_SCALE; + gint x_offset = display->x_offset * PANGO_SCALE; - pango_layout_line_get_extents (layout_line, NULL, &logical_rect); - - switch (align) - { - case PANGO_ALIGN_RIGHT: - x_offset += width - logical_rect.width; - break; - case PANGO_ALIGN_CENTER: - x_offset += (width - logical_rect.width) / 2; - break; - default: - break; - } + pango_layout_iter_get_line_extents (layout_iter, NULL, &logical_rect); pango_layout_line_x_to_index (layout_line, - x * PANGO_SCALE - x_offset, + x * PANGO_SCALE - x_offset - logical_rect.x, &byte_index, &trailing); line_display_index_to_iter (layout, display, iter, byte_index, trailing); - + break; } byte_offset += layout_line->length; - tmp_list = tmp_list->next; } + while (pango_layout_iter_next_line (layout_iter)); + pango_layout_iter_free (layout_iter); + gtk_text_layout_free_line_display (layout, display); } diff --git a/gtk/gtktextlayout.h b/gtk/gtktextlayout.h index dca8e362e5..a24c6f7818 100644 --- a/gtk/gtktextlayout.h +++ b/gtk/gtktextlayout.h @@ -223,7 +223,10 @@ struct _GtkTextLineDisplay gint width; /* Width of layout */ gint total_width; /* width - margins, if no width set on layout, if width set on layout, -1 */ gint height; - gint x_offset; /* Amount layout is shifted from left edge */ + /* Amount layout is shifted from left edge - this is the left margin + * plus any other factors, such as alignment or indentation. + */ + gint x_offset; gint left_margin; gint right_margin; gint top_margin; diff --git a/gtk/gtktexttag.c b/gtk/gtktexttag.c index af9a300879..4f35a80b95 100644 --- a/gtk/gtktexttag.c +++ b/gtk/gtktexttag.c @@ -84,7 +84,7 @@ enum { ARG_JUSTIFY, ARG_DIRECTION, ARG_LEFT_MARGIN, - ARG_LEFT_WRAPPED_LINE_MARGIN, + ARG_INDENT, ARG_STRIKETHROUGH, ARG_RIGHT_MARGIN, ARG_UNDERLINE, @@ -109,7 +109,7 @@ enum { ARG_WRAP_MODE_SET, ARG_JUSTIFY_SET, ARG_LEFT_MARGIN_SET, - ARG_LEFT_WRAPPED_LINE_MARGIN_SET, + ARG_INDENT_SET, ARG_STRIKETHROUGH_SET, ARG_RIGHT_MARGIN_SET, ARG_UNDERLINE_SET, @@ -205,8 +205,8 @@ gtk_text_tag_class_init (GtkTextTagClass *klass) GTK_ARG_READWRITE, ARG_LANGUAGE); gtk_object_add_arg_type ("GtkTextTag::left_margin", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_LEFT_MARGIN); - gtk_object_add_arg_type ("GtkTextTag::left_wrapped_line_margin", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_LEFT_WRAPPED_LINE_MARGIN); + gtk_object_add_arg_type ("GtkTextTag::indent", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_INDENT); gtk_object_add_arg_type ("GtkTextTag::offset", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_OFFSET); gtk_object_add_arg_type ("GtkTextTag::pixels_above_lines", GTK_TYPE_INT, @@ -223,7 +223,7 @@ gtk_text_tag_class_init (GtkTextTagClass *klass) GTK_ARG_READWRITE, ARG_UNDERLINE); gtk_object_add_arg_type ("GtkTextTag::wrap_mode", GTK_TYPE_ENUM, GTK_ARG_READWRITE, ARG_WRAP_MODE); - gtk_object_add_arg_type ("GtkTextTag::tabs", GTK_TYPE_POINTER, + gtk_object_add_arg_type ("GtkTextTag::tabs", GTK_TYPE_POINTER, /* FIXME */ GTK_ARG_READWRITE, ARG_TABS); gtk_object_add_arg_type ("GtkTextTag::invisible", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_INVISIBLE); @@ -253,8 +253,8 @@ gtk_text_tag_class_init (GtkTextTagClass *klass) GTK_ARG_READWRITE, ARG_LANGUAGE_SET); gtk_object_add_arg_type ("GtkTextTag::left_margin_set", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_LEFT_MARGIN_SET); - gtk_object_add_arg_type ("GtkTextTag::left_wrapped_line_margin_set", GTK_TYPE_BOOL, - GTK_ARG_READWRITE, ARG_LEFT_WRAPPED_LINE_MARGIN_SET); + gtk_object_add_arg_type ("GtkTextTag::indent_set", GTK_TYPE_BOOL, + GTK_ARG_READWRITE, ARG_INDENT_SET); gtk_object_add_arg_type ("GtkTextTag::offset_set", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_OFFSET_SET); gtk_object_add_arg_type ("GtkTextTag::pixels_above_lines_set", GTK_TYPE_BOOL, @@ -566,9 +566,9 @@ gtk_text_tag_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) size_changed = TRUE; break; - case ARG_LEFT_WRAPPED_LINE_MARGIN: - text_tag->left_wrapped_line_margin_set = TRUE; - text_tag->values->left_wrapped_line_margin = GTK_VALUE_INT (*arg); + case ARG_INDENT: + text_tag->indent_set = TRUE; + text_tag->values->indent = GTK_VALUE_INT (*arg); size_changed = TRUE; break; @@ -681,8 +681,8 @@ gtk_text_tag_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) size_changed = TRUE; break; - case ARG_LEFT_WRAPPED_LINE_MARGIN_SET: - text_tag->left_wrapped_line_margin_set = GTK_VALUE_BOOL (*arg); + case ARG_INDENT_SET: + text_tag->indent_set = GTK_VALUE_BOOL (*arg); size_changed = TRUE; break; @@ -824,8 +824,8 @@ gtk_text_tag_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) GTK_VALUE_INT (*arg) = tag->values->left_margin; break; - case ARG_LEFT_WRAPPED_LINE_MARGIN: - GTK_VALUE_INT (*arg) = tag->values->left_wrapped_line_margin; + case ARG_INDENT: + GTK_VALUE_INT (*arg) = tag->values->indent; break; case ARG_STRIKETHROUGH: @@ -907,8 +907,8 @@ gtk_text_tag_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) GTK_VALUE_BOOL (*arg) = tag->left_margin_set; break; - case ARG_LEFT_WRAPPED_LINE_MARGIN_SET: - GTK_VALUE_BOOL (*arg) = tag->left_wrapped_line_margin_set; + case ARG_INDENT_SET: + GTK_VALUE_BOOL (*arg) = tag->indent_set; break; case ARG_STRIKETHROUGH_SET: @@ -1184,6 +1184,9 @@ gtk_text_attributes_copy (GtkTextAttributes *src, if (dest->appearance.fg_stipple) gdk_bitmap_unref (dest->appearance.fg_stipple); + if (dest->language) + g_free (dest->language); + /* Copy */ orig_refcount = dest->refcount; @@ -1343,8 +1346,8 @@ gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest, if (tag->left_margin_set) dest->left_margin = vals->left_margin; - if (tag->left_wrapped_line_margin_set) - dest->left_wrapped_line_margin = vals->left_wrapped_line_margin; + if (tag->indent_set) + dest->indent = vals->indent; if (tag->offset_set) dest->offset = vals->offset; @@ -1405,7 +1408,7 @@ gtk_text_tag_affects_size (GtkTextTag *tag) tag->font_set || tag->justify_set || tag->left_margin_set || - tag->left_wrapped_line_margin_set || + tag->indent_set || tag->offset_set || tag->right_margin_set || tag->pixels_above_lines_set || diff --git a/gtk/gtktexttag.h b/gtk/gtktexttag.h index 5527ea7b06..992f31556c 100644 --- a/gtk/gtktexttag.h +++ b/gtk/gtktexttag.h @@ -65,7 +65,7 @@ struct _GtkTextTag guint fg_stipple_set : 1; guint justify_set : 1; guint left_margin_set : 1; - guint left_wrapped_line_margin_set : 1; + guint indent_set : 1; guint offset_set : 1; guint strikethrough_set : 1; guint right_margin_set : 1; @@ -144,12 +144,10 @@ struct _GtkTextAttributes PangoFontDescription *font_desc; - /* lMargin1 */ gint left_margin; - /* lMargin2 */ - gint left_wrapped_line_margin; - + gint indent; + /* super/subscript offset, can be negative */ gint offset; diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index e022a5d0ea..2bfb1eaa28 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -46,7 +46,8 @@ #define SCREEN_WIDTH(widget) text_window_get_width (GTK_TEXT_VIEW (widget)->text_window) #define SCREEN_HEIGHT(widget) text_window_get_height (GTK_TEXT_VIEW (widget)->text_window) -enum { +enum +{ MOVE_CURSOR, SET_ANCHOR, INSERT_AT_CURSOR, @@ -59,7 +60,8 @@ enum { LAST_SIGNAL }; -enum { +enum +{ ARG_0, ARG_HEIGHT_LINES, ARG_WIDTH_COLUMNS, @@ -68,6 +70,11 @@ enum { ARG_PIXELS_INSIDE_WRAP, ARG_EDITABLE, ARG_WRAP_MODE, + ARG_JUSTIFY, + ARG_LEFT_MARGIN, + ARG_RIGHT_MARGIN, + ARG_INDENT, + ARG_TABS, LAST_ARG }; @@ -384,8 +391,17 @@ gtk_text_view_class_init (GtkTextViewClass *klass) GTK_ARG_READWRITE, ARG_EDITABLE); gtk_object_add_arg_type ("GtkTextView::wrap_mode", GTK_TYPE_ENUM, GTK_ARG_READWRITE, ARG_WRAP_MODE); - - + gtk_object_add_arg_type ("GtkTextView::justify", GTK_TYPE_ENUM, + GTK_ARG_READWRITE, ARG_JUSTIFY); + gtk_object_add_arg_type ("GtkTextView::left_margin", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_LEFT_MARGIN); + gtk_object_add_arg_type ("GtkTextView::right_margin", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_RIGHT_MARGIN); + gtk_object_add_arg_type ("GtkTextView::indent", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_INDENT); + gtk_object_add_arg_type ("GtkTextView::tabs", GTK_TYPE_POINTER, /* FIXME */ + GTK_ARG_READWRITE, ARG_TABS); + /* * Signals */ @@ -673,8 +689,18 @@ gtk_text_view_init (GtkTextView *text_view) GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); + /* Set up default style */ text_view->wrap_mode = GTK_WRAPMODE_NONE; - + text_view->pixels_above_lines = 0; + text_view->pixels_below_lines = 0; + text_view->pixels_inside_wrap = 0; + text_view->justify = GTK_JUSTIFY_LEFT; + text_view->left_margin = 0; + text_view->right_margin = 0; + text_view->indent = 0; + text_view->tabs = NULL; + text_view->editable = TRUE; + gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_DROP, target_table, G_N_ELEMENTS (target_table), @@ -694,7 +720,6 @@ gtk_text_view_init (GtkTextView *text_view) gtk_signal_connect (GTK_OBJECT (text_view->im_context), "preedit_changed", GTK_SIGNAL_FUNC (gtk_text_view_preedit_changed_handler), text_view); - text_view->editable = TRUE; text_view->cursor_visible = TRUE; text_view->text_window = text_window_new (GTK_TEXT_WINDOW_TEXT, @@ -1287,6 +1312,220 @@ gtk_text_view_get_editable (GtkTextView *text_view) return text_view->editable; } +void +gtk_text_view_set_pixels_above_lines (GtkTextView *text_view, + gint pixels_above_lines) +{ + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + + if (text_view->pixels_above_lines != pixels_above_lines) + { + text_view->pixels_above_lines = pixels_above_lines; + + if (text_view->layout) + { + text_view->layout->default_style->pixels_above_lines = pixels_above_lines; + gtk_text_layout_default_style_changed (text_view->layout); + } + } +} + +gint +gtk_text_view_get_pixels_above_lines (GtkTextView *text_view) +{ + g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), 0); + + return text_view->pixels_above_lines; +} + +void +gtk_text_view_set_pixels_below_lines (GtkTextView *text_view, + gint pixels_below_lines) +{ + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + + if (text_view->pixels_below_lines != pixels_below_lines) + { + text_view->pixels_below_lines = pixels_below_lines; + + if (text_view->layout) + { + text_view->layout->default_style->pixels_below_lines = pixels_below_lines; + gtk_text_layout_default_style_changed (text_view->layout); + } + } +} + +gint +gtk_text_view_get_pixels_below_lines (GtkTextView *text_view) +{ + g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), 0); + + return text_view->pixels_below_lines; +} + +void +gtk_text_view_set_pixels_inside_wrap (GtkTextView *text_view, + gint pixels_inside_wrap) +{ + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + + if (text_view->pixels_inside_wrap != pixels_inside_wrap) + { + text_view->pixels_inside_wrap = pixels_inside_wrap; + + if (text_view->layout) + { + text_view->layout->default_style->pixels_inside_wrap = pixels_inside_wrap; + gtk_text_layout_default_style_changed (text_view->layout); + } + } +} + +gint +gtk_text_view_get_pixels_inside_wrap (GtkTextView *text_view) +{ + g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), 0); + + return text_view->pixels_inside_wrap; +} + +void +gtk_text_view_set_justification (GtkTextView *text_view, + GtkJustification justify) +{ + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + + if (text_view->justify != justify) + { + text_view->justify = justify; + + if (text_view->layout) + { + text_view->layout->default_style->justify = justify; + gtk_text_layout_default_style_changed (text_view->layout); + } + } +} + +GtkJustification +gtk_text_view_get_justification (GtkTextView *text_view) +{ + g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), GTK_JUSTIFY_LEFT); + + return text_view->justify; +} + +void +gtk_text_view_set_left_margin (GtkTextView *text_view, + gint left_margin) +{ + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + + if (text_view->left_margin != left_margin) + { + text_view->left_margin = left_margin; + + if (text_view->layout) + { + text_view->layout->default_style->left_margin = left_margin; + gtk_text_layout_default_style_changed (text_view->layout); + } + } +} + +gint +gtk_text_view_get_left_margin (GtkTextView *text_view) +{ + g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), 0); + + return text_view->left_margin; +} + +void +gtk_text_view_set_right_margin (GtkTextView *text_view, + gint right_margin) +{ + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + + if (text_view->right_margin != right_margin) + { + text_view->right_margin = right_margin; + + if (text_view->layout) + { + text_view->layout->default_style->right_margin = right_margin; + gtk_text_layout_default_style_changed (text_view->layout); + } + } +} + +gint +gtk_text_view_get_right_margin (GtkTextView *text_view) +{ + g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), 0); + + return text_view->right_margin; +} + +void +gtk_text_view_set_indent (GtkTextView *text_view, + gint indent) +{ + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + + if (text_view->indent != indent) + { + text_view->indent = indent; + + if (text_view->layout) + { + text_view->layout->default_style->indent = indent; + gtk_text_layout_default_style_changed (text_view->layout); + } + } +} + +gint +gtk_text_view_get_indent (GtkTextView *text_view) +{ + g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), 0); + + return text_view->indent; +} + +void +gtk_text_view_set_tabs (GtkTextView *text_view, + PangoTabArray *tabs) +{ + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + + if (text_view->tabs) + pango_tab_array_free (text_view->tabs); + + text_view->tabs = tabs ? pango_tab_array_copy (tabs) : NULL; + + if (text_view->layout) + { + /* some unkosher futzing in internal struct details... */ + if (text_view->layout->default_style->tabs) + pango_tab_array_free (text_view->layout->default_style->tabs); + + text_view->layout->default_style->tabs = + text_view->tabs ? pango_tab_array_copy (text_view->tabs) : NULL; + + gtk_text_layout_default_style_changed (text_view->layout); + } +} + +PangoTabArray* +gtk_text_view_get_tabs (GtkTextView *text_view) +{ + g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), NULL); + + return text_view->tabs ? pango_tab_array_copy (text_view->tabs) : NULL; +} + /** * gtk_text_view_set_cursor_visible: * @text_view: a #GtkTextView @@ -1425,26 +1664,53 @@ gtk_text_view_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) switch (arg_id) { case ARG_HEIGHT_LINES: + g_warning ("FIXME"); break; case ARG_WIDTH_COLUMNS: + g_warning ("FIXME"); break; case ARG_PIXELS_ABOVE_LINES: + gtk_text_view_set_pixels_above_lines (text_view, GTK_VALUE_INT (*arg)); break; case ARG_PIXELS_BELOW_LINES: + gtk_text_view_set_pixels_below_lines (text_view, GTK_VALUE_INT (*arg)); break; case ARG_PIXELS_INSIDE_WRAP: + gtk_text_view_set_pixels_inside_wrap (text_view, GTK_VALUE_INT (*arg)); break; case ARG_EDITABLE: + gtk_text_view_set_editable (text_view, GTK_VALUE_BOOL (*arg)); break; case ARG_WRAP_MODE: + gtk_text_view_set_wrap_mode (text_view, GTK_VALUE_ENUM (*arg)); break; + case ARG_JUSTIFY: + gtk_text_view_set_justification (text_view, GTK_VALUE_ENUM (*arg)); + break; + + case ARG_LEFT_MARGIN: + gtk_text_view_set_left_margin (text_view, GTK_VALUE_INT (*arg)); + break; + + case ARG_RIGHT_MARGIN: + gtk_text_view_set_right_margin (text_view, GTK_VALUE_INT (*arg)); + break; + + case ARG_INDENT: + gtk_text_view_set_indent (text_view, GTK_VALUE_INT (*arg)); + break; + + case ARG_TABS: + gtk_text_view_set_tabs (text_view, GTK_VALUE_POINTER (*arg)); + break; + default: g_assert_not_reached (); break; @@ -1461,26 +1727,53 @@ gtk_text_view_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) switch (arg_id) { case ARG_HEIGHT_LINES: + g_warning ("FIXME"); break; case ARG_WIDTH_COLUMNS: + g_warning ("FIXME"); break; case ARG_PIXELS_ABOVE_LINES: + GTK_VALUE_INT (*arg) = text_view->pixels_above_lines; break; case ARG_PIXELS_BELOW_LINES: + GTK_VALUE_INT (*arg) = text_view->pixels_below_lines; break; case ARG_PIXELS_INSIDE_WRAP: + GTK_VALUE_INT (*arg) = text_view->pixels_inside_wrap; break; case ARG_EDITABLE: + GTK_VALUE_BOOL (*arg) = text_view->editable; break; case ARG_WRAP_MODE: + GTK_VALUE_ENUM (*arg) = text_view->wrap_mode; + break; + + case ARG_JUSTIFY: + GTK_VALUE_ENUM (*arg) = text_view->justify; + break; + + case ARG_LEFT_MARGIN: + GTK_VALUE_INT (*arg) = text_view->left_margin; break; + case ARG_RIGHT_MARGIN: + GTK_VALUE_INT (*arg) = text_view->right_margin; + break; + + case ARG_INDENT: + GTK_VALUE_INT (*arg) = text_view->indent; + break; + + case ARG_TABS: + GTK_VALUE_POINTER (*arg) = gtk_text_view_get_tabs (text_view); + break; + default: arg->type = GTK_TYPE_INVALID; break; @@ -3350,12 +3643,16 @@ gtk_text_view_ensure_layout (GtkTextView *text_view) gtk_text_view_set_attributes_from_style (text_view, style, widget->style); - style->pixels_above_lines = 2; - style->pixels_below_lines = 2; - style->pixels_inside_wrap = 1; - + style->pixels_above_lines = text_view->pixels_above_lines; + style->pixels_below_lines = text_view->pixels_below_lines; + style->pixels_inside_wrap = text_view->pixels_inside_wrap; + style->left_margin = text_view->left_margin; + style->right_margin = text_view->right_margin; + style->indent = text_view->indent; + style->tabs = text_view->tabs ? pango_tab_array_copy (text_view->tabs) : NULL; + style->wrap_mode = text_view->wrap_mode; - style->justify = GTK_JUSTIFY_LEFT; + style->justify = text_view->justify; style->direction = gtk_widget_get_direction (GTK_WIDGET (text_view)); gtk_text_layout_set_default_style (text_view->layout, style); diff --git a/gtk/gtktextview.h b/gtk/gtktextview.h index 5943aceab8..5c72b9e8ba 100644 --- a/gtk/gtktextview.h +++ b/gtk/gtktextview.h @@ -70,9 +70,20 @@ struct _GtkTextView guint selection_drag_scan_timeout; gint scrolling_accel_factor; - GtkWrapMode wrap_mode; /* Default wrap mode */ - - guint editable : 1; /* default editability */ + /* Default style settings */ + gint pixels_above_lines; + gint pixels_below_lines; + gint pixels_inside_wrap; + GtkWrapMode wrap_mode; + GtkJustification justify; + gint left_margin; + gint right_margin; + gint indent; + PangoTabArray *tabs; + guint editable : 1; + + + guint overwrite_mode : 1; guint cursor_visible : 1; guint need_im_reset : 1; /* If we have reset the IM since the last character entered */ @@ -168,14 +179,6 @@ gboolean gtk_text_view_place_cursor_onscreen (GtkTextView *text_view); void gtk_text_view_get_visible_rect (GtkTextView *text_view, GdkRectangle *visible_rect); -void gtk_text_view_set_wrap_mode (GtkTextView *text_view, - GtkWrapMode wrap_mode); -GtkWrapMode gtk_text_view_get_wrap_mode (GtkTextView *text_view); - -void gtk_text_view_set_editable (GtkTextView *text_view, - gboolean setting); -gboolean gtk_text_view_get_editable (GtkTextView *text_view); - void gtk_text_view_set_cursor_visible (GtkTextView *text_view, gboolean setting); gboolean gtk_text_view_get_cursor_visible (GtkTextView *text_view); @@ -241,6 +244,41 @@ void gtk_text_view_move_child (GtkTextView *text_view, gint xpos, gint ypos); +/* Default style settings (fallbacks if no tag affects the property) */ + +void gtk_text_view_set_wrap_mode (GtkTextView *text_view, + GtkWrapMode wrap_mode); +GtkWrapMode gtk_text_view_get_wrap_mode (GtkTextView *text_view); +void gtk_text_view_set_editable (GtkTextView *text_view, + gboolean setting); +gboolean gtk_text_view_get_editable (GtkTextView *text_view); +void gtk_text_view_set_pixels_above_lines (GtkTextView *text_view, + gint pixels_above_lines); +gint gtk_text_view_get_pixels_above_lines (GtkTextView *text_view); +void gtk_text_view_set_pixels_below_lines (GtkTextView *text_view, + gint pixels_below_lines); +gint gtk_text_view_get_pixels_below_lines (GtkTextView *text_view); +void gtk_text_view_set_pixels_inside_wrap (GtkTextView *text_view, + gint pixels_inside_wrap); +gint gtk_text_view_get_pixels_inside_wrap (GtkTextView *text_view); +void gtk_text_view_set_justification (GtkTextView *text_view, + GtkJustification justification); +GtkJustification gtk_text_view_get_justification (GtkTextView *text_view); +void gtk_text_view_set_left_margin (GtkTextView *text_view, + gint left_margin); +gint gtk_text_view_get_left_margin (GtkTextView *text_view); +void gtk_text_view_set_right_margin (GtkTextView *text_view, + gint right_margin); +gint gtk_text_view_get_right_margin (GtkTextView *text_view); +void gtk_text_view_set_indent (GtkTextView *text_view, + gint indent); +gint gtk_text_view_get_indent (GtkTextView *text_view); +void gtk_text_view_set_tabs (GtkTextView *text_view, + PangoTabArray *tabs); +PangoTabArray* gtk_text_view_get_tabs (GtkTextView *text_view); + + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/testtext.c b/gtk/testtext.c index 1f9be694b3..ec964bcf92 100644 --- a/gtk/testtext.c +++ b/gtk/testtext.c @@ -503,12 +503,10 @@ fill_example_buffer (GtkTextBuffer *buffer) gtk_object_set (GTK_OBJECT (tag), "wrap_mode", GTK_WRAPMODE_WORD, "direction", GTK_TEXT_DIR_RTL, - "left_wrapped_line_margin", 20, + "indent", 30, "left_margin", 20, "right_margin", 20, NULL); - - pixbuf = gdk_pixbuf_new_from_xpm_data (book_closed_xpm); @@ -859,6 +857,34 @@ do_direction_changed (gpointer callback_data, gtk_widget_queue_resize (view->text_view); } + +static void +do_spacing_changed (gpointer callback_data, + guint callback_action, + GtkWidget *widget) +{ + View *view = view_from_widget (widget); + + if (callback_action) + { + gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (view->text_view), + 23); + gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (view->text_view), + 21); + gtk_text_view_set_pixels_inside_wrap (GTK_TEXT_VIEW (view->text_view), + 9); + } + else + { + gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (view->text_view), + 0); + gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (view->text_view), + 0); + gtk_text_view_set_pixels_inside_wrap (GTK_TEXT_VIEW (view->text_view), + 0); + } +} + static void do_editable_changed (gpointer callback_data, guint callback_action, @@ -1112,6 +1138,10 @@ static GtkItemFactoryEntry menu_items[] = { "/Settings/Left-to-Right", NULL, do_direction_changed, GTK_TEXT_DIR_LTR, "<RadioItem>" }, { "/Settings/Right-to-Left", NULL, do_direction_changed, GTK_TEXT_DIR_RTL, "/Settings/Left-to-Right" }, + + { "/Settings/sep1", NULL, 0, 0, "<Separator>" }, + { "/Settings/Sane spacing", NULL, do_spacing_changed, FALSE, "<RadioItem>" }, + { "/Settings/Funky spacing", NULL, do_spacing_changed, TRUE, "/Settings/Sane spacing" }, { "/_Attributes", NULL, 0, 0, "<Branch>" }, { "/Attributes/Editable", NULL, do_apply_editable, TRUE, NULL }, { "/Attributes/Not editable", NULL, do_apply_editable, FALSE, NULL }, @@ -1864,8 +1894,7 @@ create_view (Buffer *buffer) view->text_view = gtk_text_view_new_with_buffer (buffer->buffer); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view->text_view), GTK_WRAPMODE_WORD); - - + /* Draw tab stops in the top and bottom windows. */ gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (view->text_view), diff --git a/tests/testtext.c b/tests/testtext.c index 1f9be694b3..ec964bcf92 100644 --- a/tests/testtext.c +++ b/tests/testtext.c @@ -503,12 +503,10 @@ fill_example_buffer (GtkTextBuffer *buffer) gtk_object_set (GTK_OBJECT (tag), "wrap_mode", GTK_WRAPMODE_WORD, "direction", GTK_TEXT_DIR_RTL, - "left_wrapped_line_margin", 20, + "indent", 30, "left_margin", 20, "right_margin", 20, NULL); - - pixbuf = gdk_pixbuf_new_from_xpm_data (book_closed_xpm); @@ -859,6 +857,34 @@ do_direction_changed (gpointer callback_data, gtk_widget_queue_resize (view->text_view); } + +static void +do_spacing_changed (gpointer callback_data, + guint callback_action, + GtkWidget *widget) +{ + View *view = view_from_widget (widget); + + if (callback_action) + { + gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (view->text_view), + 23); + gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (view->text_view), + 21); + gtk_text_view_set_pixels_inside_wrap (GTK_TEXT_VIEW (view->text_view), + 9); + } + else + { + gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (view->text_view), + 0); + gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (view->text_view), + 0); + gtk_text_view_set_pixels_inside_wrap (GTK_TEXT_VIEW (view->text_view), + 0); + } +} + static void do_editable_changed (gpointer callback_data, guint callback_action, @@ -1112,6 +1138,10 @@ static GtkItemFactoryEntry menu_items[] = { "/Settings/Left-to-Right", NULL, do_direction_changed, GTK_TEXT_DIR_LTR, "<RadioItem>" }, { "/Settings/Right-to-Left", NULL, do_direction_changed, GTK_TEXT_DIR_RTL, "/Settings/Left-to-Right" }, + + { "/Settings/sep1", NULL, 0, 0, "<Separator>" }, + { "/Settings/Sane spacing", NULL, do_spacing_changed, FALSE, "<RadioItem>" }, + { "/Settings/Funky spacing", NULL, do_spacing_changed, TRUE, "/Settings/Sane spacing" }, { "/_Attributes", NULL, 0, 0, "<Branch>" }, { "/Attributes/Editable", NULL, do_apply_editable, TRUE, NULL }, { "/Attributes/Not editable", NULL, do_apply_editable, FALSE, NULL }, @@ -1864,8 +1894,7 @@ create_view (Buffer *buffer) view->text_view = gtk_text_view_new_with_buffer (buffer->buffer); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view->text_view), GTK_WRAPMODE_WORD); - - + /* Draw tab stops in the top and bottom windows. */ gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (view->text_view), |