X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktextdisplay.c;h=24cc0ec6b4850970c08c3b46f341184232b7b328;hb=8a17cad2e5e3f14e0a8977f069cbe8b8a83eaf48;hp=e9a24bc5f3bf47c4a3c8d434be4ac529d2fd6f17;hpb=c7514e8f0d19a833257497caff413bb4dfae6eb4;p=~andy%2Fgtk diff --git a/gtk/gtktextdisplay.c b/gtk/gtktextdisplay.c index e9a24bc5f..24cc0ec6b 100644 --- a/gtk/gtktextdisplay.c +++ b/gtk/gtktextdisplay.c @@ -21,8 +21,7 @@ * 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 .Free * * Original Tk license: * @@ -108,10 +107,13 @@ struct _GtkTextRenderer GtkWidget *widget; cairo_t *cr; - GdkColor *error_color; /* Error underline color for this widget */ - GList *widgets; /* widgets encountered when drawing */ - - int state; + GdkRGBA *error_color; /* Error underline color for this widget */ + GList *widgets; /* widgets encountered when drawing */ + + GdkRGBA rgba[4]; + guint8 rgba_set[4]; + + guint state : 2; }; struct _GtkTextRendererClass @@ -119,48 +121,27 @@ struct _GtkTextRendererClass PangoRendererClass parent_class; }; -G_DEFINE_TYPE (GtkTextRenderer, _gtk_text_renderer, PANGO_TYPE_RENDERER) - -static void -text_renderer_set_gdk_color (GtkTextRenderer *text_renderer, - PangoRenderPart part, - GdkColor *gdk_color) -{ - PangoRenderer *renderer = PANGO_RENDERER (text_renderer); +GType _gtk_text_renderer_get_type (void); - if (gdk_color) - { - PangoColor color; - - color.red = gdk_color->red; - color.green = gdk_color->green; - color.blue = gdk_color->blue; - - pango_renderer_set_color (renderer, part, &color); - } - else - pango_renderer_set_color (renderer, part, NULL); -} +G_DEFINE_TYPE (GtkTextRenderer, _gtk_text_renderer, PANGO_TYPE_RENDERER) static void text_renderer_set_rgba (GtkTextRenderer *text_renderer, PangoRenderPart part, - GdkRGBA *rgba) + const GdkRGBA *rgba) { PangoRenderer *renderer = PANGO_RENDERER (text_renderer); + PangoColor dummy = { 0, }; if (rgba) { - PangoColor color; - - color.red = CLAMP (rgba->red * 65535. + 0.5, 0, 65535); - color.green = CLAMP (rgba->green * 65535. + 0.5, 0, 65535); - color.blue = CLAMP (rgba->blue * 65535. + 0.5, 0, 65535); - - pango_renderer_set_color (renderer, part, &color); + text_renderer->rgba[part] = *rgba; + pango_renderer_set_color (renderer, part, &dummy); } else pango_renderer_set_color (renderer, part, NULL); + + text_renderer->rgba_set[part] = (rgba != NULL); } static GtkTextAppearance * @@ -188,9 +169,8 @@ gtk_text_renderer_prepare_run (PangoRenderer *renderer, GtkStyleContext *context; GtkStateFlags state; GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer); - GdkColor *bg_color = NULL; + GdkRGBA *bg_rgba = NULL; GdkRGBA *fg_rgba = NULL; - GdkColor *fg_color = NULL; GtkTextAppearance *appearance; PANGO_RENDERER_CLASS (_gtk_text_renderer_parent_class)->prepare_run (renderer, run); @@ -199,23 +179,20 @@ gtk_text_renderer_prepare_run (PangoRenderer *renderer, g_assert (appearance != NULL); context = gtk_widget_get_style_context (text_renderer->widget); - - state = gtk_widget_get_state_flags (text_renderer->widget); + state = gtk_widget_get_state_flags (text_renderer->widget); if (appearance->draw_bg && text_renderer->state == NORMAL) - bg_color = &appearance->bg_color; + bg_rgba = appearance->rgba[0]; else - bg_color = NULL; + bg_rgba = NULL; - text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_BACKGROUND, bg_color); + text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_BACKGROUND, bg_rgba); if (text_renderer->state == SELECTED) { state |= GTK_STATE_FLAG_SELECTED; - gtk_style_context_get (context, state, - "color", &fg_rgba, - NULL); + gtk_style_context_get (context, state, "color", &fg_rgba, NULL); } else if (text_renderer->state == CURSOR && gtk_widget_has_focus (text_renderer->widget)) { @@ -224,56 +201,57 @@ gtk_text_renderer_prepare_run (PangoRenderer *renderer, NULL); } else - fg_color = &appearance->fg_color; + fg_rgba = appearance->rgba[1]; - if (fg_rgba) - { - text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_FOREGROUND, fg_rgba); - text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_STRIKETHROUGH,fg_rgba); - } - else - { - text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_FOREGROUND, fg_color); - text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_STRIKETHROUGH, fg_color); - } + text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_FOREGROUND, fg_rgba); + text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_STRIKETHROUGH, fg_rgba); if (appearance->underline == PANGO_UNDERLINE_ERROR) { if (!text_renderer->error_color) { + GdkColor *color = NULL; + gtk_style_context_get_style (context, - "error-underline-color", &text_renderer->error_color, + "error-underline-color", &color, NULL); - if (!text_renderer->error_color) - { - static const GdkColor red = { 0, 0xffff, 0, 0 }; - text_renderer->error_color = gdk_color_copy (&red); - } + if (color) + { + GdkRGBA rgba; + + rgba.red = color->red / 65535.; + rgba.green = color->green / 65535.; + rgba.blue = color->blue / 65535.; + rgba.alpha = 1; + gdk_color_free (color); + + text_renderer->error_color = gdk_rgba_copy (&rgba); + } + else + { + static const GdkRGBA red = { 1, 0, 0, 1 }; + text_renderer->error_color = gdk_rgba_copy (&red); + } } - text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_UNDERLINE, text_renderer->error_color); + text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_UNDERLINE, text_renderer->error_color); } - else if (fg_rgba) - text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_UNDERLINE, fg_rgba); else - text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_UNDERLINE, fg_color); + text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_UNDERLINE, fg_rgba); + + if (fg_rgba != appearance->rgba[1]) + gdk_rgba_free (fg_rgba); } static void set_color (GtkTextRenderer *text_renderer, PangoRenderPart part) { - PangoColor *color; - cairo_save (text_renderer->cr); - color = pango_renderer_get_color (PANGO_RENDERER (text_renderer), part); - if (color) - cairo_set_source_rgb (text_renderer->cr, - color->red / 65535., - color->green / 65535., - color->blue / 65535.); + if (text_renderer->rgba_set[part]) + gdk_cairo_set_source_rgba (text_renderer->cr, &text_renderer->rgba[part]); } static void @@ -540,7 +518,7 @@ text_renderer_end (GtkTextRenderer *text_renderer) if (text_renderer->error_color) { - gdk_color_free (text_renderer->error_color); + gdk_rgba_free (text_renderer->error_color); text_renderer->error_color = NULL; } @@ -607,10 +585,9 @@ render_para (GtkTextRenderer *text_renderer, screen_width = line_display->total_width; context = gtk_widget_get_style_context (text_renderer->widget); + state = gtk_widget_get_state_flags (text_renderer->widget); - state = GTK_STATE_FLAG_SELECTED; - if (gtk_widget_has_focus (text_renderer->widget)) - state |= GTK_STATE_FLAG_FOCUSED; + state |= GTK_STATE_FLAG_SELECTED; gtk_style_context_get_background_color (context, state, &selection); @@ -672,13 +649,13 @@ render_para (GtkTextRenderer *text_renderer, } else { - if (line_display->pg_bg_color) + if (line_display->pg_bg_rgba) { cairo_t *cr = text_renderer->cr; cairo_save (cr); - - gdk_cairo_set_source_color (cr, line_display->pg_bg_color); + + gdk_cairo_set_source_rgba (text_renderer->cr, line_display->pg_bg_rgba); cairo_rectangle (cr, line_display->left_margin, selection_y, screen_width, selection_height); @@ -844,11 +821,11 @@ gtk_text_layout_draw (GtkTextLayout *layout, cairo_t *cr, GList **widgets) { + GtkStyleContext *context; gint offset_y; - GSList *cursor_list; GtkTextRenderer *text_renderer; GtkTextIter selection_start, selection_end; - gboolean have_selection = FALSE; + gboolean have_selection; GSList *line_list; GSList *tmp_list; GList *tmp_widgets; @@ -862,6 +839,8 @@ gtk_text_layout_draw (GtkTextLayout *layout, if (!gdk_cairo_get_clip_rectangle (cr, &clip)) return; + context = gtk_widget_get_style_context (widget); + line_list = gtk_text_layout_get_lines (layout, clip.y, clip.y + clip.height, &offset_y); if (line_list == NULL) @@ -875,10 +854,9 @@ gtk_text_layout_draw (GtkTextLayout *layout, gtk_text_layout_wrap_loop_start (layout); - if (gtk_text_buffer_get_selection_bounds (layout->buffer, - &selection_start, - &selection_end)) - have_selection = TRUE; + have_selection = gtk_text_buffer_get_selection_bounds (layout->buffer, + &selection_start, + &selection_end); tmp_list = line_list; while (tmp_list != NULL) @@ -886,8 +864,6 @@ gtk_text_layout_draw (GtkTextLayout *layout, GtkTextLineDisplay *line_display; gint selection_start_index = -1; gint selection_end_index = -1; - gboolean have_strong; - gboolean have_weak; GtkTextLine *line = tmp_list->data; @@ -929,50 +905,26 @@ gtk_text_layout_draw (GtkTextLayout *layout, selection_start_index, selection_end_index); /* We paint the cursors last, because they overlap another chunk - and need to appear on top. */ - - have_strong = FALSE; - have_weak = FALSE; - - cursor_list = line_display->cursors; - while (cursor_list) - { - GtkTextCursorDisplay *cursor = cursor_list->data; - if (cursor->is_strong) - have_strong = TRUE; - else - have_weak = TRUE; - - cursor_list = cursor_list->next; - } - - cursor_list = line_display->cursors; - while (cursor_list) + * and need to appear on top. + */ + if (line_display->cursors != NULL) { - GtkTextCursorDisplay *cursor = cursor_list->data; - GtkTextDirection dir; - GdkRectangle cursor_location; - - dir = line_display->direction; - if (have_strong && have_weak) - { - if (!cursor->is_strong) - dir = (dir == GTK_TEXT_DIR_RTL) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; - } - - cursor_location.x = line_display->x_offset + cursor->x; - cursor_location.y = line_display->top_margin + cursor->y; - cursor_location.width = 0; - cursor_location.height = cursor->height; + int i; - gtk_draw_insertion_cursor (widget, cr, &cursor_location, - cursor->is_strong, - dir, have_strong && have_weak); - - cursor_list = cursor_list->next; + for (i = 0; i < line_display->cursors->len; i++) + { + int index; + PangoDirection dir; + + index = g_array_index(line_display->cursors, int, i); + dir = (line_display->direction == GTK_TEXT_DIR_RTL) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR; + gtk_render_insertion_cursor (context, cr, + line_display->x_offset, line_display->top_margin, + line_display->layout, index, dir); + } } } /* line_display->height > 0 */ - + cairo_translate (cr, 0, line_display->height); gtk_text_layout_free_line_display (layout, line_display); @@ -985,10 +937,7 @@ gtk_text_layout_draw (GtkTextLayout *layout, if (widgets) *widgets = tmp_widgets; else - { - g_list_foreach (tmp_widgets, (GFunc)g_object_unref, NULL); - g_list_free (tmp_widgets); - } + g_list_free_full (tmp_widgets, g_object_unref); g_slist_free (line_list); }