static void get_renderer_rect (GtkSourceGutter *gutter, Renderer *renderer, GtkTextIter *iter, gint line, GdkRectangle *rectangle, gint start) { gint y; gint ypad; rectangle->x = start; gtk_text_view_get_line_yrange (GTK_TEXT_VIEW (gutter->priv->view), iter, &y, &rectangle->height); rectangle->width = gtk_source_gutter_renderer_get_size (renderer->renderer); gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (gutter->priv->view), gutter->priv->window_type, 0, y, NULL, &rectangle->y); gtk_source_gutter_renderer_get_padding (renderer->renderer, NULL, &ypad); rectangle->y += ypad; rectangle->height -= 2 * ypad; }
/* returns TRUE if window is popped-up lower than the cursor, returns FALSE if window is popped-up higher than the cursor (because cursor is low in the screen) */ static gboolean acwin_position_at_cursor(BluefishTextView * btv) { GtkTextIter it; GdkRectangle rect; GdkScreen *screen; gint x, y, sh; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(btv)); screen = gtk_widget_get_screen(GTK_WIDGET(btv)); gtk_text_buffer_get_iter_at_mark(buffer, &it, gtk_text_buffer_get_insert(buffer)); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(btv), &it, &rect); gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(btv), GTK_TEXT_WINDOW_TEXT, rect.x, rect.y, &rect.x, &rect.y); gdk_window_get_origin(gtk_text_view_get_window(GTK_TEXT_VIEW(btv), GTK_TEXT_WINDOW_TEXT), &x, &y); sh = gdk_screen_get_height(screen); if (rect.y + y + ACWIN(btv->autocomp)->h > sh) { DBG_AUTOCOMP("acwin_position_at_cursor, popup above cursuor, rect.y+y=%d + rect.height(%d)-acw->h(%d)=%d, acw->h=%d, sh=%d\n" , rect.y + y,rect.height,ACWIN(btv->autocomp)->h , rect.y + y + rect.height - ACWIN(btv->autocomp)->h , ACWIN(btv->autocomp)->h, sh); gtk_window_move(GTK_WINDOW(ACWIN(btv->autocomp)->win), rect.x + x, rect.y + y + rect.height - ACWIN(btv->autocomp)->h); return FALSE; } else { DBG_AUTOCOMP("acwin_position_at_cursor, popup below cursuor, rect.y+y=%d, acw->h=%d, sh=%d\n", rect.y + y, ACWIN(btv->autocomp)->h, sh); gtk_window_move(GTK_WINDOW(ACWIN(btv->autocomp)->win), rect.x + x, rect.y + y); return TRUE; } }
static void get_iter_pos (GtkTextView *text_view, GtkTextIter *iter, gint *x, gint *y, gint *height) { GdkWindow *win; GdkRectangle location; gint win_x; gint win_y; gint xx; gint yy; gtk_text_view_get_iter_location (text_view, iter, &location); gtk_text_view_buffer_to_window_coords (text_view, GTK_TEXT_WINDOW_WIDGET, location.x, location.y, &win_x, &win_y); win = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_WIDGET); gdk_window_get_origin (win, &xx, &yy); *x = win_x + xx; *y = win_y + yy + location.height; *height = location.height; }
static VALUE textview_buffer_to_window_coords(VALUE self, VALUE wintype, VALUE buffer_x, VALUE buffer_y) { int window_x, window_y; gtk_text_view_buffer_to_window_coords(_SELF(self), RVAL2GENUM(wintype, GTK_TYPE_TEXT_WINDOW_TYPE), NUM2INT(buffer_x), NUM2INT(buffer_y), &window_x, &window_y); return rb_ary_new3(2, INT2NUM(window_x), INT2NUM(window_y)); }
static int imhtml_expose_cb(GtkWidget *widget, GdkEventExpose *event, PidginConversation *gtkconv) { int y, last_y, offset; GdkRectangle visible_rect; GtkTextIter iter; GdkRectangle buf; int pad; PurpleConversation *conv = gtkconv->active_conv; PurpleConversationType type = purple_conversation_get_type(conv); if ((type == PURPLE_CONV_TYPE_CHAT && !purple_prefs_get_bool(PREF_CHATS)) || (type == PURPLE_CONV_TYPE_IM && !purple_prefs_get_bool(PREF_IMS))) return FALSE; gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(widget), &visible_rect); offset = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "markerline")); if (offset) { gtk_text_buffer_get_iter_at_offset(gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)), &iter, offset); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(widget), &iter, &buf); last_y = buf.y + buf.height; pad = (gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(widget)) + gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(widget))) / 2; last_y += pad; } else last_y = 0; gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT, 0, last_y, 0, &y); if (y >= event->area.y) { GdkColor red = {0, 0xffff, 0, 0}; GdkGC *gc = gdk_gc_new(GDK_DRAWABLE(event->window)); gdk_gc_set_rgb_fg_color(gc, &red); gdk_draw_line(event->window, gc, 0, y, visible_rect.width, y); g_object_unref(G_OBJECT(gc)); } return FALSE; }
static void update_scrubber_position (GtkSourceMap *map) { GtkSourceMapPrivate *priv; GtkTextIter iter; GdkRectangle visible_area; GdkRectangle iter_area; GdkRectangle scrubber_area; GtkAllocation alloc; GtkAllocation view_alloc; gint child_height; gint view_height; gint y; priv = gtk_source_map_get_instance_private (map); if (priv->view == NULL) { return; } gtk_widget_get_allocation (GTK_WIDGET (priv->view), &view_alloc); gtk_widget_get_allocation (GTK_WIDGET (map), &alloc); gtk_widget_get_preferred_height (GTK_WIDGET (priv->view), NULL, &view_height); gtk_widget_get_preferred_height (GTK_WIDGET (priv->child_view), NULL, &child_height); gtk_text_view_get_visible_rect (GTK_TEXT_VIEW (priv->view), &visible_area); gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (priv->view), &iter, visible_area.x, visible_area.y); gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->child_view), &iter, &iter_area); gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (priv->child_view), GTK_TEXT_WINDOW_WIDGET, iter_area.x, iter_area.y, NULL, &y); scrubber_area.x = 0; scrubber_area.width = alloc.width; scrubber_area.y = y; scrubber_area.height = (gdouble)view_alloc.height / (gdouble)view_height * (gdouble)child_height; if (memcmp (&scrubber_area, &priv->scrubber_area, sizeof scrubber_area) != 0) { priv->scrubber_area = scrubber_area; gtk_widget_queue_draw (GTK_WIDGET (map)); } }
void ScrolledFileView::drawLeftMargin(cairo_t *cr) { GtkTextView *textView = getTextView(); DebuggerLocation dbgLoc = mDebugger.getStoppedLocation(); int marginWindowHeight = mLeftMargin.getMarginHeight(textView); std::vector<LineInfo> linesInfo = getLinesInfo(textView, marginWindowHeight); int lineHeight = linesInfo[1].yPos - linesInfo[0].yPos; DebuggerLocation thisFileLoc(getFilename()); int full = lineHeight*.8; int half = full/2; for(auto const & lineInfo : linesInfo) { int yPos; thisFileLoc.setLine(lineInfo.lineNum); gtk_text_view_buffer_to_window_coords (textView, GTK_TEXT_WINDOW_LEFT, 0, lineInfo.yPos, NULL, &yPos); mLeftMargin.drawMarginLineNum(textView, cr, lineInfo.lineNum, yPos); int centerY = yPos + lineHeight/2; if(mDebugger.getBreakpoints().anyLocationsMatch(thisFileLoc)) { cairo_set_source_rgb(cr, 128/255.0, 128/255.0, 0/255.0); cairo_arc(cr, half+1, centerY, half, 0, 2*M_PI); cairo_fill(cr); } if(dbgLoc == thisFileLoc) { cairo_set_source_rgb(cr, 0/255.0, 0/255.0, 255.0/255.0); cairo_move_to(cr, 0, centerY); cairo_line_to(cr, full, centerY); cairo_move_to(cr, full, centerY); cairo_line_to(cr, half, centerY-half); cairo_move_to(cr, full, centerY); cairo_line_to(cr, half, centerY+half); cairo_stroke(cr); } } mLeftMargin.drawMarginLine(textView, cr); cairo_fill(cr); // g_object_unref (G_OBJECT (layout)); }
CAMLprim value ml_gtk_text_view_buffer_to_window_coords (value tv, value tt, value x, value y) { CAMLparam4(tv,tt,x,y); CAMLlocal1(res); int bx,by = 0; gtk_text_view_buffer_to_window_coords(GtkTextView_val(tv), Text_window_type_val(tt), Int_val(x),Int_val(y), &bx,&by); res = alloc_tuple(2); Store_field(res,0,Val_int(bx)); Store_field(res,1,Val_int(by)); CAMLreturn(res); }
static void paint_widget_icons (GcrDisplayView *self, cairo_t *cr) { GHashTableIter hit; GtkTextView *view; GdkRectangle visible; GdkRectangle location; GcrDisplayItem *item; gpointer value; GtkTextIter iter; view = GTK_TEXT_VIEW (self); gtk_text_view_get_visible_rect (view, &visible); g_hash_table_iter_init (&hit, self->pv->items); while (g_hash_table_iter_next (&hit, NULL, &value)) { item = value; if (item->pixbuf == NULL) continue; gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning); gtk_text_view_get_iter_location (view, &iter, &location); location.height = gdk_pixbuf_get_height (item->pixbuf); location.width = gdk_pixbuf_get_width (item->pixbuf); location.x = visible.width - location.width - ICON_MARGIN; if (!gdk_rectangle_intersect (&visible, &location, NULL)) continue; gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_TEXT, location.x, location.y, &location.x, &location.y); cairo_save (cr); gdk_cairo_set_source_pixbuf (cr, item->pixbuf, location.x, location.y); cairo_rectangle (cr, location.x, location.y, location.width, location.height); cairo_fill (cr); cairo_restore (cr); } }
void insert_open_brace(GtkWidget **tip_win, GtkWidget *text_view, GtkTextIter *arg1) { GdkWindow *win; GtkTextIter start; GdkRectangle buf_loc; gint x, y; gint win_x, win_y; gchar *text; gchar *tip_text; start = *arg1; if (!gtk_text_iter_backward_word_start (&start)) return; text = gtk_text_iter_get_text (&start, arg1); g_strstrip (text); tip_text = get_tip(text); if (tip_text == NULL) return; gtk_text_view_get_iter_location (GTK_TEXT_VIEW (text_view), arg1, &buf_loc); g_printf ("Buffer: %d, %d\n", buf_loc.x, buf_loc.y); gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET, buf_loc.x, buf_loc.y, &win_x, &win_y); g_printf ("Window: %d, %d\n", win_x, win_y); win = gtk_text_view_get_window (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET); gdk_window_get_origin (win, &x, &y); if (*tip_win != NULL) gtk_widget_destroy (GTK_WIDGET (*tip_win)); *tip_win = tip_window_new (tip_text); g_free(tip_text); gtk_window_move (GTK_WINDOW (*tip_win), win_x + x, win_y + y + buf_loc.height); gtk_widget_show_all (*tip_win); }
static gint line_numbers_expose (GtkWidget *widget, GdkEventExpose *event) { GtkTextView *text_view; GdkWindow *win; // GtkStyle *style; PangoLayout *layout; PangoAttrList *alist; PangoAttribute *attr; GArray *numbers; GArray *pixels; gint y1, y2; gint count; gint layout_width; gint justify_width = 0; gint i; // gchar *str; gchar str [8]; /* we don't expect more than ten million lines */ GdkGC *gc; gint height; if (line_number_visible){{{{{ // omit calculation text_view = GTK_TEXT_VIEW (widget); /* See if this expose is on the line numbers window */ /* left_win = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_LEFT); right_win = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_RIGHT); if (event->window == left_win) { type = GTK_TEXT_WINDOW_LEFT; target = event->window; } else if (event->window == right_win) { type = GTK_TEXT_WINDOW_RIGHT; target = right_win; } else return FALSE; */ win = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_LEFT); if (event->window != win) return FALSE; // style = gtk_style_copy (widget->style); // style = gtk_style_copy (gtk_widget_get_default_style()); y1 = event->area.y; y2 = y1 + event->area.height; gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y1, NULL, &y1); gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y2, NULL, &y2); numbers = g_array_new (FALSE, FALSE, sizeof (gint)); pixels = g_array_new (FALSE, FALSE, sizeof (gint)); get_lines (text_view, y1, y2, pixels, numbers, &count); /* a zero-lined document should display a "1"; we don't need to worry about scrolling effects of the text widget in this special case */ if (count == 0) { gint y = 0; gint n = 0; count = 1; g_array_append_val (pixels, y); g_array_append_val (numbers, n); } DV({g_print("Painting line numbers %d - %d\n", g_array_index(numbers, gint, 0), g_array_index(numbers, gint, count - 1)); }); layout = gtk_widget_create_pango_layout (widget, ""); // str = g_strdup_printf ("%d", gtk_text_buffer_get_line_count(text_view->buffer)); g_snprintf (str, sizeof (str), "%d", MAX (99, gtk_text_buffer_get_line_count(text_view->buffer))); pango_layout_set_text (layout, str, -1); // g_free (str); pango_layout_get_pixel_size (layout, &layout_width, NULL); min_number_window_width = calculate_min_number_window_width(widget); if (layout_width > min_number_window_width) gtk_text_view_set_border_window_size (text_view, GTK_TEXT_WINDOW_LEFT, layout_width + margin + submargin); else { // if ((gtk_text_view_get_border_window_size (text_view, GTK_TEXT_WINDOW_LEFT) - 5) > layout_width) { gtk_text_view_set_border_window_size (text_view, GTK_TEXT_WINDOW_LEFT, min_number_window_width + margin + submargin); // } justify_width = min_number_window_width - layout_width; } pango_layout_set_width (layout, layout_width); pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); alist = pango_attr_list_new(); attr = pango_attr_foreground_new( widget->style->text_aa->red, widget->style->text_aa->green, widget->style->text_aa->blue); attr->start_index = 0; attr->end_index = G_MAXUINT; pango_attr_list_insert(alist, attr); pango_layout_set_attributes(layout, alist); pango_attr_list_unref(alist); /* Draw fully internationalized numbers! */ i = 0; while (i < count) { gint pos; gtk_text_view_buffer_to_window_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, g_array_index (pixels, gint, i), NULL, &pos); // str = g_strdup_printf ("%d", g_array_index (numbers, gint, i) + 1); g_snprintf (str, sizeof (str), "%d", g_array_index (numbers, gint, i) + 1); pango_layout_set_text (layout, str, -1); gtk_paint_layout (widget->style, win, GTK_WIDGET_STATE (widget), FALSE, NULL, widget, NULL, #if GTK_CHECK_VERSION(2, 6, 0) // Is this solution??? layout_width + justify_width + margin / 2 + 1, #else layout_width + justify_width + margin / 2, #endif pos, layout); // g_free (str); ++i; } g_array_free (pixels, TRUE); g_array_free (numbers, TRUE); g_object_unref (G_OBJECT (layout)); // g_object_ref (G_OBJECT (style)); /* don't stop emission, need to draw children */ }}}}}
/* 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 void dma_sparse_view_paint_margin (DmaSparseView *view, GdkEventExpose *event) { GtkTextView *text_view; GdkWindow *win; PangoLayout *layout; gint y1, y2; gint y, height; gchar str [16]; gint margin_width; gint margin_length; gint text_width; DmaSparseIter buf_iter; GtkTextIter text_iter; guint prev_address = G_MAXUINT; text_view = GTK_TEXT_VIEW (view); if (!view->priv->show_line_numbers && !view->priv->show_line_markers) { gtk_text_view_set_border_window_size (text_view, GTK_TEXT_WINDOW_LEFT, 0); return; } win = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_LEFT); y1 = event->area.y; y2 = y1 + event->area.height; /* get the extents of the line printing */ gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y1, NULL, &y1); gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y2, NULL, &y2); /* set size. */ g_snprintf (str, sizeof (str), "0x%X", G_MAXUINT); margin_length = strlen(str) - 2; layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), str); pango_layout_get_pixel_size (layout, &text_width, NULL); pango_layout_set_width (layout, text_width); pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); /* determine the width of the left margin. */ if (view->priv->show_line_numbers) margin_width = text_width + 4; else margin_width = 0; if (view->priv->show_line_markers) margin_width += GUTTER_PIXMAP; g_return_if_fail (margin_width != 0); gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_LEFT, margin_width); /* Display all addresses */ dma_sparse_iter_copy (&buf_iter, &view->priv->start); gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer (text_view), &text_iter); /* Skip line while position doesn't need to be repaint */ gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); if (y < y1) { do { if (!dma_sparse_iter_forward_lines (&buf_iter, 1)) return; if (!gtk_text_iter_forward_line (&text_iter)) return; gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); } while (y < y1); } /* Display address */ do { gint pos; guint address; gtk_text_view_buffer_to_window_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y, NULL, &pos); address = dma_sparse_iter_get_address (&buf_iter); if (view->priv->show_line_numbers) { g_snprintf (str, sizeof (str),"0x%0*lX", margin_length, (long unsigned int)address); pango_layout_set_markup (layout, str, -1); gtk_paint_layout (gtk_widget_get_style (GTK_WIDGET (view)), win, gtk_widget_get_state (GTK_WIDGET (view)), FALSE, NULL, GTK_WIDGET (view), NULL, text_width + 2, pos, layout); } /* Display marker */ if ((prev_address != address) && (view->priv->show_line_markers)) { gint current_marker = dma_sparse_buffer_get_marks (view->priv->buffer, address); if (current_marker) { gint x; if (view->priv->show_line_numbers) x = text_width + 4; else x = 0; draw_line_markers (view, current_marker, x, pos); prev_address = address; } } if (!dma_sparse_iter_forward_lines (&buf_iter, 1)) return; if (!gtk_text_iter_forward_line (&text_iter)) return; gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); } while (y < y2); g_object_unref (G_OBJECT (layout)); }
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; }