mirror of https://github.com/GNOME/gimp.git
app: port GimpDisplayShell image drawing to cairo
This commit is contained in:
parent
90655d8744
commit
f0c40d3717
|
@ -258,11 +258,6 @@ gimp_canvas_gc_new (GimpCanvas *canvas,
|
|||
|
||||
switch (style)
|
||||
{
|
||||
case GIMP_CANVAS_STYLE_RENDER:
|
||||
mask |= GDK_GC_EXPOSURES;
|
||||
values.graphics_exposures = TRUE;
|
||||
break;
|
||||
|
||||
case GIMP_CANVAS_STYLE_XOR_DOTTED:
|
||||
case GIMP_CANVAS_STYLE_XOR_DASHED:
|
||||
mask |= GDK_GC_LINE_STYLE;
|
||||
|
@ -556,43 +551,6 @@ gimp_canvas_get_layout (GimpCanvas *canvas,
|
|||
return canvas->layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_get_window (GTK_WIDGET (canvas)),
|
||||
canvas->gc[style],
|
||||
x, y, width, height,
|
||||
GDK_RGB_DITHER_MAX,
|
||||
rgb_buf, rowstride, xdith, ydith);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_canvas_draw_drop_zone (GimpCanvas *canvas,
|
||||
cairo_t *cr)
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
typedef enum
|
||||
{
|
||||
GIMP_CANVAS_STYLE_RENDER,
|
||||
GIMP_CANVAS_STYLE_XOR,
|
||||
GIMP_CANVAS_STYLE_XOR_DASHED,
|
||||
GIMP_CANVAS_STYLE_XOR_DOTTED,
|
||||
|
@ -116,16 +115,6 @@ void gimp_canvas_draw_segments (GimpCanvas *canvas,
|
|||
PangoLayout *gimp_canvas_get_layout (GimpCanvas *canvas,
|
||||
const gchar *format,
|
||||
...) G_GNUC_PRINTF (2, 3);
|
||||
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);
|
||||
void gimp_canvas_draw_drop_zone (GimpCanvas *canvas,
|
||||
cairo_t *cr);
|
||||
|
||||
|
|
|
@ -2273,13 +2273,17 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
|
|||
{
|
||||
gdk_region_get_rectangles (image_region, &rects, &n_rects);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
for (i = 0; i < n_rects; i++)
|
||||
gimp_display_shell_draw_area (shell,
|
||||
gimp_display_shell_draw_area (shell, cr,
|
||||
rects[i].x,
|
||||
rects[i].y,
|
||||
rects[i].width,
|
||||
rects[i].height);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
g_free (rects);
|
||||
}
|
||||
|
||||
|
|
|
@ -692,6 +692,7 @@ gimp_display_shell_draw_cursor (GimpDisplayShell *shell,
|
|||
|
||||
void
|
||||
gimp_display_shell_draw_area (GimpDisplayShell *shell,
|
||||
cairo_t *cr,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
|
@ -703,6 +704,7 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
|
|||
|
||||
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
||||
g_return_if_fail (gimp_display_get_image (shell->display));
|
||||
g_return_if_fail (cr != NULL);
|
||||
|
||||
x2 = x + w;
|
||||
y2 = y + h;
|
||||
|
@ -732,7 +734,7 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
|
|||
&disp_xoffset,
|
||||
&disp_yoffset);
|
||||
|
||||
gimp_display_shell_render (shell,
|
||||
gimp_display_shell_render (shell, cr,
|
||||
j - disp_xoffset,
|
||||
i - disp_yoffset,
|
||||
dx, dy,
|
||||
|
|
|
@ -67,6 +67,7 @@ void gimp_display_shell_draw_vectors (GimpDisplayShell *shell)
|
|||
void gimp_display_shell_draw_cursor (GimpDisplayShell *shell,
|
||||
cairo_t *cr);
|
||||
void gimp_display_shell_draw_area (GimpDisplayShell *shell,
|
||||
cairo_t *cr,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
|
|
|
@ -76,7 +76,6 @@ struct _RenderInfo
|
|||
gint src_y;
|
||||
gint dest_bpp;
|
||||
gint dest_bpl;
|
||||
gint dest_width;
|
||||
|
||||
gint zoom_quality;
|
||||
|
||||
|
@ -195,6 +194,7 @@ static const guchar * render_image_tile_fault (RenderInfo *info);
|
|||
|
||||
|
||||
static void gimp_display_shell_render_highlight (GimpDisplayShell *shell,
|
||||
RenderInfo *info,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
|
@ -213,6 +213,7 @@ static void gimp_display_shell_render_mask (GimpDisplayShell *shell,
|
|||
|
||||
void
|
||||
gimp_display_shell_render (GimpDisplayShell *shell,
|
||||
cairo_t *cr,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
|
@ -227,6 +228,7 @@ gimp_display_shell_render (GimpDisplayShell *shell,
|
|||
gint offset_y;
|
||||
|
||||
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
||||
g_return_if_fail (cr != NULL);
|
||||
g_return_if_fail (w > 0 && h > 0);
|
||||
|
||||
image = gimp_display_get_image (shell->display);
|
||||
|
@ -239,16 +241,15 @@ gimp_display_shell_render (GimpDisplayShell *shell,
|
|||
/* Initialize RenderInfo with values that don't change during the
|
||||
* call of this function.
|
||||
*/
|
||||
info.shell = shell;
|
||||
info.shell = shell;
|
||||
|
||||
info.x = x + offset_x;
|
||||
info.y = y + offset_y;
|
||||
info.w = w;
|
||||
info.h = h;
|
||||
info.x = x + offset_x;
|
||||
info.y = y + offset_y;
|
||||
info.w = w;
|
||||
info.h = h;
|
||||
|
||||
info.dest_bpp = 3;
|
||||
info.dest_bpl = info.dest_bpp * GIMP_DISPLAY_RENDER_BUF_WIDTH;
|
||||
info.dest_width = info.dest_bpp * info.w;
|
||||
info.dest_bpp = 4;
|
||||
info.dest_bpl = cairo_image_surface_get_stride (shell->render_surface);
|
||||
|
||||
switch (shell->display->config->zoom_quality)
|
||||
{
|
||||
|
@ -293,17 +294,19 @@ gimp_display_shell_render (GimpDisplayShell *shell,
|
|||
}
|
||||
|
||||
/* apply filters to the rendered projection */
|
||||
#if 0
|
||||
if (shell->filter_stack)
|
||||
gimp_color_display_stack_convert (shell->filter_stack,
|
||||
shell->render_buf,
|
||||
w, h,
|
||||
3,
|
||||
3 * GIMP_DISPLAY_RENDER_BUF_WIDTH);
|
||||
#endif
|
||||
|
||||
/* dim pixels outside the highlighted rectangle */
|
||||
if (highlight)
|
||||
{
|
||||
gimp_display_shell_render_highlight (shell, x, y, w, h, highlight);
|
||||
gimp_display_shell_render_highlight (shell, &info, x, y, w, h, highlight);
|
||||
}
|
||||
else if (shell->mask)
|
||||
{
|
||||
|
@ -315,6 +318,8 @@ gimp_display_shell_render (GimpDisplayShell *shell,
|
|||
gimp_display_shell_render_mask (shell, &info);
|
||||
}
|
||||
|
||||
cairo_surface_mark_dirty (shell->render_surface);
|
||||
|
||||
/* put it to the screen */
|
||||
{
|
||||
gint disp_xoffset, disp_yoffset;
|
||||
|
@ -322,35 +327,43 @@ gimp_display_shell_render (GimpDisplayShell *shell,
|
|||
gimp_display_shell_scroll_get_disp_offset (shell,
|
||||
&disp_xoffset, &disp_yoffset);
|
||||
|
||||
gimp_canvas_draw_rgb (GIMP_CANVAS (shell->canvas),
|
||||
GIMP_CANVAS_STYLE_RENDER,
|
||||
x + disp_xoffset, y + disp_yoffset,
|
||||
w, h,
|
||||
shell->render_buf,
|
||||
3 * GIMP_DISPLAY_RENDER_BUF_WIDTH,
|
||||
offset_x, offset_y);
|
||||
cairo_set_source_surface (cr, shell->render_surface,
|
||||
x + disp_xoffset, y + disp_yoffset);
|
||||
cairo_rectangle (cr, x + disp_xoffset, y + disp_yoffset, w, h);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
#define CAIRO_RGB24_RED_PIXEL 2
|
||||
#define CAIRO_RGB24_GREEN_PIXEL 1
|
||||
#define CAIRO_RGB24_BLUE_PIXEL 0
|
||||
#else
|
||||
#define CAIRO_RGB24_RED_PIXEL 1
|
||||
#define CAIRO_RGB24_GREEN_PIXEL 2
|
||||
#define CAIRO_RGB24_BLUE_PIXEL 3
|
||||
#endif
|
||||
|
||||
#define GIMP_DISPLAY_SHELL_DIM_PIXEL(buf,x) \
|
||||
{ \
|
||||
buf[3 * (x) + 0] >>= 1; \
|
||||
buf[3 * (x) + 1] >>= 1; \
|
||||
buf[3 * (x) + 2] >>= 1; \
|
||||
buf[4 * (x) + CAIRO_RGB24_RED_PIXEL] >>= 1; \
|
||||
buf[4 * (x) + CAIRO_RGB24_GREEN_PIXEL] >>= 1; \
|
||||
buf[4 * (x) + CAIRO_RGB24_BLUE_PIXEL] >>= 1; \
|
||||
}
|
||||
|
||||
/* This function highlights the given area by dimming all pixels outside. */
|
||||
|
||||
static void
|
||||
gimp_display_shell_render_highlight (GimpDisplayShell *shell,
|
||||
RenderInfo *info,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h,
|
||||
const GdkRectangle *highlight)
|
||||
{
|
||||
guchar *buf = shell->render_buf;
|
||||
guchar *buf = cairo_image_surface_get_data (shell->render_surface);
|
||||
GdkRectangle rect;
|
||||
gint offset_x;
|
||||
gint offset_y;
|
||||
|
@ -373,7 +386,7 @@ gimp_display_shell_render_highlight (GimpDisplayShell *shell,
|
|||
for (x = 0; x < w; x++)
|
||||
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
|
||||
|
||||
buf += 3 * GIMP_DISPLAY_RENDER_BUF_WIDTH;
|
||||
buf += info->dest_bpl;
|
||||
}
|
||||
|
||||
for ( ; y < rect.y + rect.height; y++)
|
||||
|
@ -384,7 +397,7 @@ gimp_display_shell_render_highlight (GimpDisplayShell *shell,
|
|||
for (x += rect.width; x < w; x++)
|
||||
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
|
||||
|
||||
buf += 3 * GIMP_DISPLAY_RENDER_BUF_WIDTH;
|
||||
buf += info->dest_bpl;
|
||||
}
|
||||
|
||||
for ( ; y < h; y++)
|
||||
|
@ -392,7 +405,7 @@ gimp_display_shell_render_highlight (GimpDisplayShell *shell,
|
|||
for (x = 0; x < w; x++)
|
||||
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
|
||||
|
||||
buf += 3 * GIMP_DISPLAY_RENDER_BUF_WIDTH;
|
||||
buf += info->dest_bpl;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -402,7 +415,7 @@ gimp_display_shell_render_highlight (GimpDisplayShell *shell,
|
|||
for (x = 0; x < w; x++)
|
||||
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
|
||||
|
||||
buf += 3 * GIMP_DISPLAY_RENDER_BUF_WIDTH;
|
||||
buf += info->dest_bpl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -429,35 +442,35 @@ gimp_display_shell_render_mask (GimpDisplayShell *shell,
|
|||
switch (shell->mask_color)
|
||||
{
|
||||
case GIMP_RED_CHANNEL:
|
||||
for (x = info->x; x < xe; x++, src++, dest += 3)
|
||||
for (x = info->x; x < xe; x++, src++, dest += info->dest_bpp)
|
||||
{
|
||||
if (*src & 0x80)
|
||||
continue;
|
||||
|
||||
dest[1] = dest[1] >> 2;
|
||||
dest[2] = dest[2] >> 2;
|
||||
dest[CAIRO_RGB24_GREEN_PIXEL] >>= 2;
|
||||
dest[CAIRO_RGB24_BLUE_PIXEL] >>= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_GREEN_CHANNEL:
|
||||
for (x = info->x; x < xe; x++, src++, dest += 3)
|
||||
for (x = info->x; x < xe; x++, src++, dest += info->dest_bpp)
|
||||
{
|
||||
if (*src & 0x80)
|
||||
continue;
|
||||
|
||||
dest[0] = dest[0] >> 2;
|
||||
dest[2] = dest[2] >> 2;
|
||||
dest[CAIRO_RGB24_RED_PIXEL] >>= 2;
|
||||
dest[CAIRO_RGB24_BLUE_PIXEL] >>= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_BLUE_CHANNEL:
|
||||
for (x = info->x; x < xe; x++, src++, dest += 3)
|
||||
for (x = info->x; x < xe; x++, src++, dest += info->dest_bpp)
|
||||
{
|
||||
if (*src & 0x80)
|
||||
continue;
|
||||
|
||||
dest[0] = dest[0] >> 2;
|
||||
dest[1] = dest[1] >> 2;
|
||||
dest[CAIRO_RGB24_RED_PIXEL] >>= 2;
|
||||
dest[CAIRO_RGB24_GREEN_PIXEL] >>= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -504,7 +517,7 @@ render_image_gray_a (RenderInfo *info)
|
|||
|
||||
dark_light = (y >> check_shift) + (info->x >> check_shift);
|
||||
|
||||
for (x = info->x; x < xe; x++, src += 2, dest += 3)
|
||||
for (x = info->x; x < xe; x++, src += 2, dest += info->dest_bpp)
|
||||
{
|
||||
guint v;
|
||||
|
||||
|
@ -513,7 +526,7 @@ render_image_gray_a (RenderInfo *info)
|
|||
else
|
||||
v = ((src[0] << 8) + check_light * (256 - src[1])) >> 8;
|
||||
|
||||
dest[0] = dest[1] = dest[2] = v;
|
||||
GIMP_CAIRO_RGB24_SET_PIXEL (dest, v, v, v);
|
||||
|
||||
if (((x + 1) & check_mod) == 0)
|
||||
dark_light += 1;
|
||||
|
@ -553,7 +566,7 @@ render_image_rgb_a (RenderInfo *info)
|
|||
|
||||
dark_light = (y >> check_shift) + (info->x >> check_shift);
|
||||
|
||||
for (x = info->x; x < xe; x++, src += 4, dest += 3)
|
||||
for (x = info->x; x < xe; x++, src += 4, dest += info->dest_bpp)
|
||||
{
|
||||
guint r, g, b;
|
||||
|
||||
|
@ -570,9 +583,7 @@ render_image_rgb_a (RenderInfo *info)
|
|||
b = ((src[2] << 8) + check_light * (256 - src[3])) >> 8;
|
||||
}
|
||||
|
||||
dest[0] = r;
|
||||
dest[1] = g;
|
||||
dest[2] = b;
|
||||
GIMP_CAIRO_RGB24_SET_PIXEL (dest, r, g, b);
|
||||
|
||||
if (((x + 1) & check_mod) == 0)
|
||||
dark_light += 1;
|
||||
|
@ -605,7 +616,7 @@ gimp_display_shell_render_info_scale (RenderInfo *info,
|
|||
/* We must reset info->dest because this member is modified in render
|
||||
* functions.
|
||||
*/
|
||||
info->dest = shell->render_buf;
|
||||
info->dest = cairo_image_surface_get_data (shell->render_surface);
|
||||
|
||||
info->scalex = shell->scale_x * (1 << level);
|
||||
info->scaley = shell->scale_y * (1 << level);
|
||||
|
|
|
@ -27,6 +27,7 @@ void gimp_display_shell_render_init (Gimp *gimp);
|
|||
void gimp_display_shell_render_exit (Gimp *gimp);
|
||||
|
||||
void gimp_display_shell_render (GimpDisplayShell *shell,
|
||||
cairo_t *cr,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
|
|
|
@ -289,9 +289,9 @@ gimp_display_shell_init (GimpDisplayShell *shell)
|
|||
shell->x_src_dec = 1;
|
||||
shell->y_src_dec = 1;
|
||||
|
||||
shell->render_buf = g_new (guchar,
|
||||
GIMP_DISPLAY_RENDER_BUF_WIDTH *
|
||||
GIMP_DISPLAY_RENDER_BUF_HEIGHT * 3);
|
||||
shell->render_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
|
||||
GIMP_DISPLAY_RENDER_BUF_WIDTH,
|
||||
GIMP_DISPLAY_RENDER_BUF_HEIGHT);
|
||||
|
||||
shell->icon_size = 32;
|
||||
|
||||
|
@ -868,10 +868,10 @@ gimp_display_shell_destroy (GtkObject *object)
|
|||
shell->filter_idle_id = 0;
|
||||
}
|
||||
|
||||
if (shell->render_buf)
|
||||
if (shell->render_surface)
|
||||
{
|
||||
g_free (shell->render_buf);
|
||||
shell->render_buf = NULL;
|
||||
cairo_surface_destroy (shell->render_surface);
|
||||
shell->render_surface = NULL;
|
||||
}
|
||||
|
||||
if (shell->highlight)
|
||||
|
|
|
@ -131,7 +131,7 @@ struct _GimpDisplayShell
|
|||
|
||||
GtkWidget *statusbar; /* statusbar */
|
||||
|
||||
guchar *render_buf; /* buffer for rendering the image */
|
||||
cairo_surface_t *render_surface; /* buffer for rendering the image */
|
||||
|
||||
guint title_idle_id; /* title update idle ID */
|
||||
gchar *title; /* current title */
|
||||
|
|
Loading…
Reference in New Issue