static gboolean um_crop_area_expose (GtkWidget *widget, GdkEventExpose *event) { cairo_t *cr; GdkRectangle area; GdkRectangle crop; gint width, height; UmCropArea *uarea = UM_CROP_AREA (widget); if (uarea->priv->browse_pixbuf == NULL) return FALSE; update_pixbufs (uarea); width = gdk_pixbuf_get_width (uarea->priv->pixbuf); height = gdk_pixbuf_get_height (uarea->priv->pixbuf); crop_to_widget (uarea, &crop); area.x = 0; area.y = 0; area.width = width; area.height = crop.y; gdk_rectangle_intersect (&area, &event->area, &area); gdk_draw_pixbuf (widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], uarea->priv->color_shifted, area.x, area.y, area.x, area.y, area.width, area.height, GDK_RGB_DITHER_NONE, 0, 0); area.x = 0; area.y = crop.y; area.width = crop.x; area.height = crop.height; gdk_rectangle_intersect (&area, &event->area, &area); gdk_draw_pixbuf (widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], uarea->priv->color_shifted, area.x, area.y, area.x, area.y, area.width, area.height, GDK_RGB_DITHER_NONE, 0, 0); area.x = crop.x; area.y = crop.y; area.width = crop.width; area.height = crop.height; gdk_rectangle_intersect (&area, &event->area, &area); gdk_draw_pixbuf (widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], uarea->priv->pixbuf, area.x, area.y, area.x, area.y, area.width, area.height, GDK_RGB_DITHER_NONE, 0, 0); area.x = crop.x + crop.width; area.y = crop.y; area.width = width - area.x; area.height = crop.height; gdk_rectangle_intersect (&area, &event->area, &area); gdk_draw_pixbuf (widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], uarea->priv->color_shifted, area.x, area.y, area.x, area.y, area.width, area.height, GDK_RGB_DITHER_NONE, 0, 0); area.x = 0; area.y = crop.y + crop.height; area.width = width; area.height = height - area.y; gdk_rectangle_intersect (&area, &event->area, &area); gdk_draw_pixbuf (widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], uarea->priv->color_shifted, area.x, area.y, area.x, area.y, area.width, area.height, GDK_RGB_DITHER_NONE, 0, 0); cr = gdk_cairo_create (widget->window); gdk_cairo_rectangle (cr, &event->area); cairo_clip (cr); if (uarea->priv->active_region != OUTSIDE) { gint x1, x2, y1, y2; gdk_cairo_set_source_color (cr, &widget->style->white); cairo_set_line_width (cr, 1.0); x1 = crop.x + crop.width / 3.0; x2 = crop.x + 2 * crop.width / 3.0; y1 = crop.y + crop.height / 3.0; y2 = crop.y + 2 * crop.height / 3.0; cairo_move_to (cr, x1 + 0.5, crop.y); cairo_line_to (cr, x1 + 0.5, crop.y + crop.height); cairo_move_to (cr, x2 + 0.5, crop.y); cairo_line_to (cr, x2 + 0.5, crop.y + crop.height); cairo_move_to (cr, crop.x, y1 + 0.5); cairo_line_to (cr, crop.x + crop.width, y1 + 0.5); cairo_move_to (cr, crop.x, y2 + 0.5); cairo_line_to (cr, crop.x + crop.width, y2 + 0.5); cairo_stroke (cr); } gdk_cairo_set_source_color (cr, &widget->style->black); cairo_set_line_width (cr, 1.0); cairo_rectangle (cr, crop.x + 0.5, crop.y + 0.5, crop.width - 1.0, crop.height - 1.0); cairo_stroke (cr); gdk_cairo_set_source_color (cr, &widget->style->white); cairo_set_line_width (cr, 2.0); cairo_rectangle (cr, crop.x + 2.0, crop.y + 2.0, crop.width - 4.0, crop.height - 4.0); cairo_stroke (cr); cairo_destroy (cr); return FALSE; }
static void ag_chart_renderer_render(GtkCellRenderer *renderer, cairo_t *cr, GtkWidget *widget, const GdkRectangle *background_area, const GdkRectangle *cell_area, GtkCellRendererState flags) { AgChartRendererPrivate *priv = ag_chart_renderer_get_instance_private( AG_CHART_RENDERER(renderer) ); int margin; GtkStyleContext *context = gtk_widget_get_style_context(widget); GdkPixbuf *pixbuf; gtk_style_context_save(context); gtk_style_context_add_class(context, "ag-chart-renderer"); if (priv->css_class) { gtk_style_context_add_class(context, priv->css_class); } cairo_save(cr); gdk_cairo_rectangle(cr, cell_area); cairo_clip(cr); cairo_translate(cr, cell_area->x, cell_area->y); margin = MAX( AG_CHART_RENDERER_TILE_MARGIN, (int)((cell_area->width - AG_CHART_RENDERER_TILE_SIZE) / 2) ); g_object_get(renderer, "pixbuf", &pixbuf, NULL); if (pixbuf != NULL) { GdkRectangle area = { margin, margin, AG_CHART_RENDERER_TILE_SIZE, AG_CHART_RENDERER_TILE_SIZE }; GTK_CELL_RENDERER_CLASS(ag_chart_renderer_parent_class)->render( renderer, cr, widget, &area, &area, flags ); } else { gtk_render_frame( context, cr, margin, margin, AG_CHART_RENDERER_TILE_SIZE, AG_CHART_RENDERER_TILE_SIZE ); gtk_render_background( context, cr, margin, margin, AG_CHART_RENDERER_TILE_SIZE, AG_CHART_RENDERER_TILE_SIZE ); } gtk_style_context_restore(context); if (priv->toggle_visible) { gint xpad, ypad, x_offset, check_x, check_y; gtk_cell_renderer_get_padding( GTK_CELL_RENDERER(renderer), &xpad, &ypad ); if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) { x_offset = xpad; } else { x_offset = cell_area->width - AG_CHART_RENDERER_CHECK_ICON_SIZE - xpad; } check_x = x_offset; check_y = cell_area->height - AG_CHART_RENDERER_CHECK_ICON_SIZE - ypad; gtk_style_context_save(context); gtk_style_context_add_class(context, GTK_STYLE_CLASS_CHECK); if (priv->checked) { gtk_style_context_set_state(context, GTK_STATE_FLAG_CHECKED); } gtk_render_background( context, cr, check_x, check_y, AG_CHART_RENDERER_CHECK_ICON_SIZE, AG_CHART_RENDERER_CHECK_ICON_SIZE ); gtk_render_frame( context, cr, check_x, check_y, AG_CHART_RENDERER_CHECK_ICON_SIZE, AG_CHART_RENDERER_CHECK_ICON_SIZE ); gtk_render_check( context, cr, check_x, check_y, AG_CHART_RENDERER_CHECK_ICON_SIZE, AG_CHART_RENDERER_CHECK_ICON_SIZE ); gtk_style_context_restore(context); } cairo_restore(cr); }
/*! \brief Actually renders the swatch */ static void ghid_cell_renderer_visibility_render (GtkCellRenderer *cell, GdkWindow *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags) { GHidCellRendererVisibility *pcb_cell; GdkRectangle toggle_rect; GdkRectangle draw_rect; gint xpad, ypad; pcb_cell = GHID_CELL_RENDERER_VISIBILITY (cell); ghid_cell_renderer_visibility_get_size (cell, widget, cell_area, &toggle_rect.x, &toggle_rect.y, &toggle_rect.width, &toggle_rect.height); gtk_cell_renderer_get_padding (cell, &xpad, &ypad); toggle_rect.x += cell_area->x + xpad; toggle_rect.y += cell_area->y + ypad; toggle_rect.width -= xpad * 2; toggle_rect.height -= ypad * 2; if (toggle_rect.width <= 0 || toggle_rect.height <= 0) return; if (gdk_rectangle_intersect (expose_area, cell_area, &draw_rect)) { GdkColor color; cairo_t *cr = gdk_cairo_create (window); cairo_pattern_t *pattern; if (expose_area) { gdk_cairo_rectangle (cr, expose_area); cairo_clip (cr); } cairo_set_line_width (cr, 1); cairo_rectangle (cr, toggle_rect.x + 0.5, toggle_rect.y + 0.5, toggle_rect.width - 1, toggle_rect.height - 1); cairo_set_source_rgb (cr, 1, 1, 1); cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr); gdk_color_parse (pcb_cell->color, &color); if (flags & GTK_CELL_RENDERER_PRELIT) { color.red = (4*color.red + 65535) / 5; color.green = (4*color.green + 65535) / 5; color.blue = (4*color.blue + 65535) / 5; } pattern = cairo_pattern_create_radial ((toggle_rect.width - 1.) * 0.75 + toggle_rect.x + 0.5, (toggle_rect.height - 1.) * 0.75 + toggle_rect.y + 0.5, 0., (toggle_rect.width - 1.) * 0.50 + toggle_rect.x + 0.5, (toggle_rect.height - 1.) * 0.50 + toggle_rect.y + 0.5, (toggle_rect.width - 1.) * 0.71); cairo_pattern_add_color_stop_rgb (pattern, 0.0, (color.red / 65535. * 4. + 1.) / 5., (color.green / 65535. * 4. + 1.) / 5., (color.blue / 65535. * 4. + 1.) / 5.); cairo_pattern_add_color_stop_rgb (pattern, 1.0, (color.red / 65535. * 5. + 0.) / 5., (color.green / 65535. * 5. + 0.) / 5., (color.blue / 65535. * 5. + 0.) / 5.); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); if (pcb_cell->active) cairo_rectangle (cr, toggle_rect.x + 0.5, toggle_rect.y + 0.5, toggle_rect.width - 1, toggle_rect.height - 1); else { cairo_move_to (cr, toggle_rect.x + 1, toggle_rect.y + 1); cairo_rel_line_to (cr, toggle_rect.width / 2, 0); cairo_rel_line_to (cr, -toggle_rect.width / 2, toggle_rect.width / 2); cairo_close_path (cr); } cairo_fill (cr); cairo_destroy (cr); } }
static gint expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data) #endif { MateColorButton *color_button = MATE_COLOR_BUTTON (data); GtkAllocation allocation; cairo_pattern_t *checkered; #if !GTK_CHECK_VERSION (3, 0, 0) cairo_t *cr; cr = gdk_cairo_create (event->window); gtk_widget_get_allocation (widget, &allocation); gdk_cairo_rectangle (cr, &allocation); cairo_clip (cr); #endif if (mate_color_button_has_alpha (color_button)) { cairo_save (cr); cairo_set_source_rgb (cr, CHECK_DARK, CHECK_DARK, CHECK_DARK); cairo_paint (cr); cairo_set_source_rgb (cr, CHECK_LIGHT, CHECK_LIGHT, CHECK_LIGHT); cairo_scale (cr, CHECK_SIZE, CHECK_SIZE); checkered = mate_color_button_get_checkered (); cairo_mask (cr, checkered); cairo_pattern_destroy (checkered); cairo_restore (cr); cairo_set_source_rgba (cr, color_button->priv->color.red / 65535., color_button->priv->color.green / 65535., color_button->priv->color.blue / 65535., color_button->priv->alpha / 65535.); } else { gdk_cairo_set_source_color (cr, &color_button->priv->color); } cairo_paint (cr); if (!gtk_widget_is_sensitive (GTK_WIDGET (color_button))) { gdk_cairo_set_source_color (cr, >k_widget_get_style (GTK_WIDGET(color_button))->bg[GTK_STATE_INSENSITIVE]); checkered = mate_color_button_get_checkered (); cairo_mask (cr, checkered); cairo_pattern_destroy (checkered); } #if !GTK_CHECK_VERSION (3, 0, 0) cairo_destroy (cr); #endif return FALSE; }
/* Call gtk_source_gutter_renderer_begin() on each renderer. */ static void begin_draw (GtkSourceGutter *gutter, GtkTextView *view, GArray *renderer_widths, LinesInfo *info, cairo_t *cr) { GdkRectangle background_area; GdkRectangle cell_area; GList *l; gint renderer_num; background_area.x = 0; background_area.height = info->total_height; gtk_text_view_buffer_to_window_coords (view, gutter->priv->window_type, 0, g_array_index (info->buffer_coords, gint, 0), NULL, &background_area.y); cell_area = background_area; for (l = gutter->priv->renderers, renderer_num = 0; l != NULL; l = l->next, renderer_num++) { Renderer *renderer = l->data; gint width; gint xpad; width = g_array_index (renderer_widths, gint, renderer_num); if (!gtk_source_gutter_renderer_get_visible (renderer->renderer)) { g_assert_cmpint (width, ==, 0); continue; } gtk_source_gutter_renderer_get_padding (renderer->renderer, &xpad, NULL); background_area.width = width; cell_area.width = background_area.width - 2 * xpad; cell_area.x = background_area.x + xpad; cairo_save (cr); gdk_cairo_rectangle (cr, &background_area); cairo_clip (cr); gtk_source_gutter_renderer_begin (renderer->renderer, cr, &background_area, &cell_area, &info->start, &info->end); cairo_restore (cr); background_area.x += background_area.width; }
static gboolean expose(GtkWidget *widget, GdkEventExpose *event, void *t) { #if GTK_CHECK_VERSION(2,14,0) GdkWindow *window = gtk_widget_get_window(widget); #else GdkWindow *window = widget->window; #endif cairo_t *cr = gdk_cairo_create(window); if(!pixmap_terminal) { // Rebuild pixmap gint width; gint height; gdk_drawable_get_size(window,&width,&height); pixmap_terminal = gdk_pixmap_new(window,width,height,-1); g_object_set_data_full(G_OBJECT(pixmap_terminal),"cached_gc",gdk_gc_new(GDK_DRAWABLE(pixmap_terminal)),g_object_unref); update_terminal_contents(); } gdk_cairo_set_source_pixmap(cr, pixmap_terminal, 0, 0); gdk_cairo_rectangle(cr, &event->area); cairo_fill(cr); if((cMode & CURSOR_MODE_ENABLED)) { if(!get_cursor_pixmap()) { pixmap_cursor = gdk_pixmap_new(window,rCursor.width,rCursor.height,-1); update_cursor_pixmap(); } if( (cMode & (CURSOR_MODE_BASE|CURSOR_MODE_SHOW)) == (CURSOR_MODE_BASE|CURSOR_MODE_SHOW) ) { gdk_cairo_set_source_pixmap(cr, get_cursor_pixmap(), rCursor.x, rCursor.y); if(Toggled(INSERT)) cairo_rectangle(cr, rCursor.x, rCursor.y, rCursor.width, rCursor.height); else cairo_rectangle(cr, rCursor.x, rCursor.y+terminal_font_info.ascent, rCursor.width, terminal_font_info.descent); cairo_fill(cr); /* GtkStyle *style = gtk_widget_get_style(widget); gdk_draw_drawable( widget->window, style->fg_gc[GTK_STATE_NORMAL], GDK_DRAWABLE(get_cursor_pixmap()), 0,0, rCursor.x,rCursor.y, rCursor.width,rCursor.height); */ } if(cMode & CURSOR_MODE_CROSS) { // Draw cross-hair cursor int width; int height; gdk_drawable_get_size(window,&width,&height); gdk_cairo_set_source_color(cr,color+TERMINAL_COLOR_CROSS_HAIR); cairo_rectangle(cr, rCursor.x, 0, 1, view.top+2+(terminal_font_info.spacing*view.rows)); cairo_rectangle(cr, 0, rCursor.y+fontAscent, width,1); cairo_fill(cr); } } cairo_destroy(cr); return 0; }
cairo_surface_t * gb_widget_snapshot (GtkWidget *widget, gint width, gint height, gdouble alpha, gboolean draw_border) { cairo_surface_t *surface; GtkAllocation alloc; gdouble x_ratio = 1.0; gdouble y_ratio = 1.0; cairo_t *cr; /* * XXX: This function conflates the drawing of borders and snapshoting. * Totally not ideal, but we can clean that up later. */ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (surface); gtk_widget_get_allocation (widget, &alloc); if ((width != alloc.width) || (height != alloc.height)) { if (alloc.width > alloc.height) { x_ratio = (gdouble) width / (gdouble) alloc.width; y_ratio = (gdouble) width / (gdouble) alloc.width; } else { x_ratio = (gdouble) height / (gdouble) alloc.height; y_ratio = (gdouble) height / (gdouble) alloc.height; } cairo_scale (cr, x_ratio, y_ratio); } gtk_widget_draw (widget, cr); cairo_destroy (cr); { cairo_surface_t *other; GdkRectangle rect = { 3, 3, ceil (alloc.width * x_ratio) - 6, ceil (alloc.height * y_ratio) - 6 }; other = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (other); cairo_save (cr); if (draw_border) { gdk_cairo_rectangle (cr, &rect); cairo_clip (cr); } cairo_set_source_surface (cr, surface, 0, 0); cairo_paint_with_alpha (cr, alpha); cairo_restore (cr); if (draw_border) { GdkRGBA rgba; gb_cairo_rounded_rectangle (cr, &rect, 3, 3); gdk_rgba_parse (&rgba, "#729fcf"); gb_rgba_shade (&rgba, &rgba, 0.8); gdk_cairo_set_source_rgba (cr, &rgba); cairo_set_line_width (cr, 3.0); cairo_stroke (cr); gb_cairo_rounded_rectangle (cr, &rect, 1, 1); gdk_rgba_parse (&rgba, "#729fcf"); gb_rgba_shade (&rgba, &rgba, 1.2); gdk_cairo_set_source_rgba (cr, &rgba); cairo_set_line_width (cr, 1.0); cairo_stroke (cr); } cairo_surface_destroy (surface); surface = other; } return surface; }
static void fm_cell_renderer_text_render(GtkCellRenderer *cell, GdkDrawable *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags) #endif { FmCellRendererText *self = FM_CELL_RENDERER_TEXT(cell); #if GTK_CHECK_VERSION(3, 0, 0) GtkStyleContext* style; GtkStateFlags state; #else GtkStyle* style; GtkStateType state; #endif gchar* text; gint text_width; gint text_height; gint x_offset; gint y_offset; gint x_align_offset; GdkRectangle rect; PangoWrapMode wrap_mode; gint wrap_width; PangoAlignment alignment; gfloat xalign, yalign; gint xpad, ypad; /* FIXME: this is time-consuming since it invokes pango_layout. * if we want to fix this, we must implement the whole cell * renderer ourselves instead of derived from GtkCellRendererText. */ PangoContext* context = gtk_widget_get_pango_context(widget); PangoLayout* layout = pango_layout_new(context); g_object_get(G_OBJECT(cell), "wrap-mode" , &wrap_mode, "wrap-width", &wrap_width, "alignment" , &alignment, "text", &text, NULL); pango_layout_set_alignment(layout, alignment); /* Setup the wrapping. */ if (wrap_width < 0) { pango_layout_set_width(layout, -1); pango_layout_set_wrap(layout, PANGO_WRAP_CHAR); } else { pango_layout_set_width(layout, wrap_width * PANGO_SCALE); pango_layout_set_wrap(layout, wrap_mode); if(self->height > 0) { /* FIXME: add custom ellipsize from object? */ pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); pango_layout_set_height(layout, self->height * PANGO_SCALE); } else pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); } pango_layout_set_text(layout, text, -1); pango_layout_set_auto_dir(layout, TRUE); pango_layout_get_pixel_size(layout, &text_width, &text_height); gtk_cell_renderer_get_alignment(cell, &xalign, &yalign); gtk_cell_renderer_get_padding(cell, &xpad, &ypad); /* Calculate the real x and y offsets. */ x_offset = ((gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) ? (1.0 - xalign) : xalign) * (cell_area->width - text_width - (2 * xpad)); x_offset = MAX(x_offset, 0); y_offset = yalign * (cell_area->height - text_height - (2 * ypad)); y_offset = MAX (y_offset, 0); if(flags & (GTK_CELL_RENDERER_SELECTED|GTK_CELL_RENDERER_FOCUSED)) { rect.x = cell_area->x + x_offset; rect.y = cell_area->y + y_offset; rect.width = text_width + (2 * xpad); rect.height = text_height + (2 * ypad); } #if GTK_CHECK_VERSION(3, 0, 0) style = gtk_widget_get_style_context(widget); #else style = gtk_widget_get_style(widget); #endif if(flags & GTK_CELL_RENDERER_SELECTED) /* item is selected */ { #if GTK_CHECK_VERSION(3, 0, 0) GdkRGBA clr; if(flags & GTK_CELL_RENDERER_INSENSITIVE) /* insensitive */ state = GTK_STATE_FLAG_INSENSITIVE; else state = GTK_STATE_FLAG_SELECTED; gtk_style_context_get_background_color(style, state, &clr); gdk_cairo_rectangle(cr, &rect); gdk_cairo_set_source_rgba(cr, &clr); #else cairo_t *cr = gdk_cairo_create (window); GdkColor clr; if(flags & GTK_CELL_RENDERER_INSENSITIVE) /* insensitive */ state = GTK_STATE_INSENSITIVE; else state = GTK_STATE_SELECTED; clr = style->bg[state]; /* paint the background */ if(expose_area) { gdk_cairo_rectangle(cr, expose_area); cairo_clip(cr); } gdk_cairo_rectangle(cr, &rect); cairo_set_source_rgb(cr, clr.red / 65535., clr.green / 65535., clr.blue / 65535.); #endif cairo_fill (cr); #if !GTK_CHECK_VERSION(3, 0, 0) cairo_destroy (cr); #endif } #if !GTK_CHECK_VERSION(3, 0, 0) else state = GTK_STATE_NORMAL; #endif x_align_offset = (alignment == PANGO_ALIGN_CENTER) ? (wrap_width - text_width) / 2 : 0; #if GTK_CHECK_VERSION(3, 0, 0) gtk_render_layout(style, cr, cell_area->x + x_offset + xpad - x_align_offset, cell_area->y + y_offset + ypad, layout); #else gtk_paint_layout(style, window, state, TRUE, expose_area, widget, "cellrenderertext", cell_area->x + x_offset + xpad - x_align_offset, cell_area->y + y_offset + ypad, layout); #endif g_object_unref(layout); if(G_UNLIKELY( flags & GTK_CELL_RENDERER_FOCUSED) ) /* focused */ { #if GTK_CHECK_VERSION(3, 0, 0) gtk_render_focus(style, cr, rect.x, rect.y, rect.width, rect.height); #else gtk_paint_focus(style, window, state, background_area, widget, "cellrenderertext", rect.x, rect.y, rect.width, rect.height); #endif } if(flags & GTK_CELL_RENDERER_PRELIT) /* hovered */ g_object_set(G_OBJECT(widget), "tooltip-text", text, NULL); else g_object_set(G_OBJECT(widget), "tooltip-text", NULL, NULL); g_free(text); }
static gboolean on_view_draw (GtkSourceView *view, cairo_t *cr, GtkSourceGutter *gutter) { GdkWindow *window; GtkTextView *text_view; GArray *sizes; GdkRectangle clip; gint x, y; gint y1, y2; GArray *numbers; GArray *pixels; GArray *heights; GtkTextIter cur; gint cur_line; gint count; gint i; GList *item; GtkTextIter start; GtkTextIter end; GtkTextBuffer *buffer; GdkRectangle background_area; GdkRectangle cell_area; GtkTextIter selection_start; GtkTextIter selection_end; gboolean has_selection; gint idx; GtkStyleContext *style_context; GdkRGBA fg_color; window = gtk_source_gutter_get_window (gutter); if (window == NULL || !gtk_cairo_should_draw_window (cr, window)) { return FALSE; } gtk_cairo_transform_to_window (cr, GTK_WIDGET (view), window); text_view = GTK_TEXT_VIEW (view); if (!gdk_cairo_get_clip_rectangle (cr, &clip)) { return FALSE; } gutter->priv->is_drawing = TRUE; buffer = gtk_text_view_get_buffer (text_view); gdk_window_get_pointer (window, &x, &y, NULL); y1 = clip.y; y2 = y1 + clip.height; /* get the extents of the line printing */ gtk_text_view_window_to_buffer_coords (text_view, gutter->priv->window_type, 0, y1, NULL, &y1); gtk_text_view_window_to_buffer_coords (text_view, gutter->priv->window_type, 0, y2, NULL, &y2); numbers = g_array_new (FALSE, FALSE, sizeof (gint)); pixels = g_array_new (FALSE, FALSE, sizeof (gint)); heights = g_array_new (FALSE, FALSE, sizeof (gint)); sizes = g_array_new (FALSE, FALSE, sizeof (gint)); calculate_gutter_size (gutter, sizes); i = 0; x = 0; background_area.x = 0; background_area.height = get_lines (text_view, y1, y2, pixels, heights, numbers, &count, &start, &end); cell_area.x = gutter->priv->xpad; cell_area.height = background_area.height; gtk_text_view_buffer_to_window_coords (text_view, gutter->priv->window_type, 0, g_array_index (pixels, gint, 0), NULL, &background_area.y); cell_area.y = background_area.y; item = gutter->priv->renderers; idx = 0; style_context = gtk_widget_get_style_context (GTK_WIDGET (view)); gtk_style_context_get_color (style_context, gtk_widget_get_state (GTK_WIDGET (view)), &fg_color); gdk_cairo_set_source_rgba (cr, &fg_color); while (item) { Renderer *renderer = item->data; gint xpad; gint width; width = g_array_index (sizes, gint, idx++); if (gtk_source_gutter_renderer_get_visible (renderer->renderer)) { gtk_source_gutter_renderer_get_padding (renderer->renderer, &xpad, NULL); background_area.width = width; cell_area.width = width - 2 * xpad; cell_area.x = background_area.x + xpad; cairo_save (cr); gdk_cairo_rectangle (cr, &background_area); cairo_clip (cr); gtk_source_gutter_renderer_begin (renderer->renderer, cr, &background_area, &cell_area, &start, &end); cairo_restore (cr); background_area.x += background_area.width; } item = g_list_next (item); } gtk_text_buffer_get_iter_at_mark (buffer, &cur, gtk_text_buffer_get_insert (buffer)); cur_line = gtk_text_iter_get_line (&cur); gtk_text_buffer_get_selection_bounds (buffer, &selection_start, &selection_end); has_selection = !gtk_text_iter_equal (&selection_start, &selection_end); if (has_selection) { if (!gtk_text_iter_starts_line (&selection_start)) { gtk_text_iter_set_line_offset (&selection_start, 0); } if (!gtk_text_iter_ends_line (&selection_end)) { gtk_text_iter_forward_to_line_end (&selection_end); } } for (i = 0; i < count; ++i) { gint pos; gint line_to_paint; end = start; if (!gtk_text_iter_ends_line (&end)) { gtk_text_iter_forward_to_line_end (&end); } gtk_text_view_buffer_to_window_coords (text_view, gutter->priv->window_type, 0, g_array_index (pixels, gint, i), NULL, &pos); line_to_paint = g_array_index (numbers, gint, i); background_area.y = pos; background_area.height = g_array_index (heights, gint, i); background_area.x = 0; idx = 0; for (item = gutter->priv->renderers; item; item = g_list_next (item)) { Renderer *renderer; gint width; GtkSourceGutterRendererState state; gint xpad; gint ypad; renderer = item->data; width = g_array_index (sizes, gint, idx++); if (!gtk_source_gutter_renderer_get_visible (renderer->renderer)) { continue; } gtk_source_gutter_renderer_get_padding (renderer->renderer, &xpad, &ypad); background_area.width = width; cell_area.y = background_area.y + ypad; cell_area.height = background_area.height - 2 * ypad; cell_area.x = background_area.x + xpad; cell_area.width = background_area.width - 2 * xpad; state = GTK_SOURCE_GUTTER_RENDERER_STATE_NORMAL; if (line_to_paint == cur_line) { state |= GTK_SOURCE_GUTTER_RENDERER_STATE_CURSOR; } if (has_selection && gtk_text_iter_in_range (&start, &selection_start, &selection_end)) { state |= GTK_SOURCE_GUTTER_RENDERER_STATE_SELECTED; } if (renderer->prelit >= 0 && cell_area.y <= renderer->prelit && cell_area.y + cell_area.height >= renderer->prelit) { state |= GTK_SOURCE_GUTTER_RENDERER_STATE_PRELIT; } gtk_source_gutter_renderer_query_data (renderer->renderer, &start, &end, state); cairo_save (cr); gdk_cairo_rectangle (cr, &background_area); cairo_clip (cr); /* Call render with correct area */ gtk_source_gutter_renderer_draw (renderer->renderer, cr, &background_area, &cell_area, &start, &end, state); cairo_restore (cr); background_area.x += background_area.width; } gtk_text_iter_forward_line (&start); } for (item = gutter->priv->renderers; item; item = g_list_next (item)) { Renderer *renderer = item->data; if (gtk_source_gutter_renderer_get_visible (renderer->renderer)) { gtk_source_gutter_renderer_end (renderer->renderer); } } g_array_free (numbers, TRUE); g_array_free (pixels, TRUE); g_array_free (heights, TRUE); g_array_free (sizes, TRUE); gutter->priv->is_drawing = FALSE; return FALSE; }