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;
}
Exemple #6
0
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));
	}
}
Exemple #7
0
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));
    }
Exemple #8
0
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);
	}
}
Exemple #10
0
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);
}
Exemple #11
0
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;
	}
Exemple #13
0
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;
}