示例#1
0
static void
select_area_expose (GtkWidget      *widget,
                    GdkEventExpose *event)
{
  GtkStyle *style  = gtk_widget_get_style (widget);
  gdouble   width  = widget->allocation.width;
  gdouble   height = widget->allocation.height;
  gdouble   dx     = 1.0 / width;
  gdouble   dy     = 1.0 / height;
  guchar   *buf    = g_alloca (3 * event->area.width * event->area.height);
  guchar   *dest   = buf;
  gdouble   y;
  gint      i, j;

  for (j = 0, y = event->area.y / height; j < event->area.height; j++, y += dy)
    {
      guchar  *d  = dest;

      gdouble  r  = calc (0, y, 0);
      gdouble  g  = calc (0, y, 120);
      gdouble  b  = calc (0, y, 240);

      gdouble  dr = calc (dx, y, 0)   - r;
      gdouble  dg = calc (dx, y, 120) - g;
      gdouble  db = calc (dx, y, 240) - b;

      r += event->area.x * dr;
      g += event->area.x * dg;
      b += event->area.x * db;

      for (i = 0; i < event->area.width; i++)
        {
          d[0] = CLAMP ((gint) r, 0, 255);
          d[1] = CLAMP ((gint) g, 0, 255);
          d[2] = CLAMP ((gint) b, 0, 255);

          r += dr;
          g += dg;
          b += db;

          d += 3;
        }

      dest += event->area.width * 3;
    }

  gdk_draw_rgb_image_dithalign (widget->window,
                                style->fg_gc[widget->state],
                                event->area.x, event->area.y,
                                event->area.width, event->area.height,
                                GDK_RGB_DITHER_MAX,
                                buf, 3 * event->area.width,
                                -event->area.x, -event->area.y);
}
示例#2
0
/**
 * gimp_canvas_draw_rgb:
 * @canvas:    a #GimpCanvas widget
 * @style:     one of the enumerated #GimpCanvasStyle's.
 * @x:         X coordinate of the upper left corner.
 * @y:         Y coordinate of the upper left corner.
 * @width:     width of the rectangle to be drawn.
 * @height:    height of the rectangle to be drawn.
 * @rgb_buf:   pixel data for the image to be drawn.
 * @rowstride: the rowstride in @rgb_buf.
 * @xdith:     x offset for dither alignment.
 * @ydith:     y offset for dither alignment.
 *
 * Draws an RGB image on the canvas in the specified style.
 **/
void
gimp_canvas_draw_rgb (GimpCanvas      *canvas,
                      GimpCanvasStyle  style,
                      gint             x,
                      gint             y,
                      gint             width,
                      gint             height,
                      guchar          *rgb_buf,
                      gint             rowstride,
                      gint             xdith,
                      gint             ydith)
{
  if (! gimp_canvas_ensure_style (canvas, style))
    return;

  gdk_draw_rgb_image_dithalign (GTK_WIDGET (canvas)->window, canvas->gc[style],
                                x, y, width, height,
                                GDK_RGB_DITHER_MAX,
                                rgb_buf, rowstride, xdith, ydith);
}
示例#3
0
/* Expose callback for the drawing area */
static gint
expose_cb (GtkWidget      *widget,
           GdkEventExpose *event,
           gpointer        data)
{
  guchar *pixels;
  int rowstride;

  rowstride = gdk_pixbuf_get_rowstride (frame);

  pixels = gdk_pixbuf_get_pixels (frame) + rowstride * event->area.y + event->area.x * 3;

  gdk_draw_rgb_image_dithalign (widget->window,
                                widget->style->black_gc,
                                event->area.x, event->area.y,
                                event->area.width, event->area.height,
                                GDK_RGB_DITHER_NORMAL,
                                pixels, rowstride,
                                event->area.x, event->area.y);

  return TRUE;
}
示例#4
0
static gboolean
gimp_color_area_expose (GtkWidget      *widget,
                        GdkEventExpose *event)
{
  GimpColorArea *area = GIMP_COLOR_AREA (widget);
  guchar        *buf;

  if (! area->buf || ! GTK_WIDGET_DRAWABLE (widget))
    return FALSE;

  if (area->needs_render)
    gimp_color_area_render (area);

  buf = area->buf + event->area.y * area->rowstride + event->area.x * 3;

  gdk_draw_rgb_image_dithalign (widget->window,
                                widget->style->black_gc,
                                event->area.x,
                                event->area.y,
                                event->area.width,
                                event->area.height,
                                GDK_RGB_DITHER_MAX,
                                buf,
                                area->rowstride,
                                event->area.x,
                                event->area.y);

  if (area->draw_border)
    gdk_draw_rectangle (widget->window,
                        widget->style->fg_gc[widget->state],
                        FALSE,
                        0, 0,
                        area->width - 1, area->height - 1);

  return FALSE;
}
示例#5
0
/* Paints a rectangle of the dirty region */
static void
paint_rectangle (ImageView *view, ArtIRect *rect, GdkInterpType interp_type)
{
	ImageViewPrivate *priv;
	int scaled_width, scaled_height;
	int width, height;
	int xofs, yofs;
	ArtIRect r, d;
	GdkPixbuf *tmp;
	int check_size;
	guint32 check_1, check_2;

	priv = view->priv;

	compute_scaled_size (view, priv->zoomx, priv->zoomy, &scaled_width, &scaled_height);

	width = GTK_WIDGET (view)->allocation.width;
	height = GTK_WIDGET (view)->allocation.height;

	/* Compute image offsets with respect to the window */

	if (scaled_width < width)
		xofs = (width - scaled_width) / 2;
	else
		xofs = -priv->xofs;

	if (scaled_height < height)
		yofs = (height - scaled_height) / 2;
	else
		yofs = -priv->yofs;

	/* Draw background if necessary, in four steps */

	/* Top */
	if (yofs > 0) {
		r.x0 = 0;
		r.y0 = 0;
		r.x1 = width;
		r.y1 = yofs;
		paint_background (view, &r, rect);
	}

	/* Left */
	if (xofs > 0) {
		r.x0 = 0;
		r.y0 = yofs;
		r.x1 = xofs;
		r.y1 = yofs + scaled_height;
		paint_background (view, &r, rect);
	}

	/* Right */
	if (xofs >= 0) {
		r.x0 = xofs + scaled_width;
		r.y0 = yofs;
		r.x1 = width;
		r.y1 = yofs + scaled_height;
		if (r.x0 < r.x1)
			paint_background (view, &r, rect);
	}

	/* Bottom */
	if (yofs >= 0) {
		r.x0 = 0;
		r.y0 = yofs + scaled_height;
		r.x1 = width;
		r.y1 = height;
		if (r.y0 < r.y1)
			paint_background (view, &r, rect);
	}

	/* Draw the scaled image
	 *
	 * FIXME: this is not using the color correction tables!
	 */

	if (!priv->pixbuf)
		return;

	r.x0 = xofs;
	r.y0 = yofs;
	r.x1 = xofs + scaled_width;
	r.y1 = yofs + scaled_height;

	art_irect_intersect (&d, &r, rect);
	if (art_irect_empty (&d))
		return;

	/* Short-circuit the fast case to avoid a memcpy() */

	if (unity_zoom (priv)
	    && gdk_pixbuf_get_colorspace (priv->pixbuf) == GDK_COLORSPACE_RGB
	    && !gdk_pixbuf_get_has_alpha (priv->pixbuf)
	    && gdk_pixbuf_get_bits_per_sample (priv->pixbuf) == 8) {
		guchar *pixels;
		int rowstride;

		rowstride = gdk_pixbuf_get_rowstride (priv->pixbuf);

		pixels = (gdk_pixbuf_get_pixels (priv->pixbuf)
			  + (d.y0 - yofs) * rowstride
			  + 3 * (d.x0 - xofs));

		gdk_draw_rgb_image_dithalign (GTK_WIDGET (view)->window,
					      GTK_WIDGET (view)->style->black_gc,
					      d.x0, d.y0,
					      d.x1 - d.x0, d.y1 - d.y0,
					      priv->dither,
					      pixels,
					      rowstride,
					      d.x0 - xofs, d.y0 - yofs);
		return;
	}

	/* For all other cases, create a temporary pixbuf */

#ifdef PACK_RGBA
	tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, d.x1 - d.x0, d.y1 - d.y0);
#else
	tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, d.x1 - d.x0, d.y1 - d.y0);
#endif

	if (!tmp) {
		g_message ("paint_rectangle(): Could not allocate temporary pixbuf of "
			   "size (%d, %d); skipping", d.x1 - d.x0, d.y1 - d.y0);
		return;
	}

	/* Compute check parameters */

	switch (priv->check_type) {
	case CHECK_TYPE_DARK:
		check_1 = CHECK_BLACK;
		check_2 = CHECK_DARK;
		break;

	case CHECK_TYPE_MIDTONE:
		check_1 = CHECK_DARK;
		check_2 = CHECK_LIGHT;
		break;

	case CHECK_TYPE_LIGHT:
		check_1 = CHECK_LIGHT;
		check_2 = CHECK_WHITE;
		break;

	case CHECK_TYPE_BLACK:
		check_1 = check_2 = CHECK_BLACK;
		break;

	case CHECK_TYPE_GRAY:
		check_1 = check_2 = CHECK_GRAY;
		break;

	case CHECK_TYPE_WHITE:
		check_1 = check_2 = CHECK_WHITE;
		break;

	default:
		g_assert_not_reached ();
		return;
	}

	switch (priv->check_size) {
	case CHECK_SIZE_SMALL:
		check_size = CHECK_SMALL;
		break;

	case CHECK_SIZE_MEDIUM:
		check_size = CHECK_MEDIUM;
		break;

	case CHECK_SIZE_LARGE:
		check_size = CHECK_LARGE;
		break;

	default:
		g_assert_not_reached ();
		return;
	}

	/* Draw! */

	gdk_pixbuf_composite_color (priv->pixbuf,
				    tmp,
				    0, 0,
				    d.x1 - d.x0, d.y1 - d.y0,
				    -(d.x0 - xofs), -(d.y0 - yofs),
				    priv->zoomx, priv->zoomy,
				    unity_zoom (priv) ? GDK_INTERP_NEAREST : interp_type,
				    255,
				    d.x0 - xofs, d.y0 - yofs,
				    check_size,
				    check_1, check_2);

#ifdef PACK_RGBA
	pack_pixbuf (tmp);
#endif

	gdk_draw_rgb_image_dithalign (GTK_WIDGET (view)->window,
				      GTK_WIDGET (view)->style->black_gc,
				      d.x0, d.y0,
				      d.x1 - d.x0, d.y1 - d.y0,
				      priv->dither,
				      gdk_pixbuf_get_pixels (tmp),
				      gdk_pixbuf_get_rowstride (tmp),
				      d.x0 - xofs, d.y0 - yofs);

	g_object_unref (tmp);

#if 0
	gdk_draw_line (GTK_WIDGET (view)->window,
		       GTK_WIDGET (view)->style->black_gc,
		       d.x0, d.y0,
		       d.x1 - 1, d.y1 - 1);
	gdk_draw_line (GTK_WIDGET (view)->window,
		       GTK_WIDGET (view)->style->black_gc,
		       d.x1 - 1, d.y0,
		       d.x0, d.y1 - 1);
#endif
}