app: port GimpDisplayShell grid drawing to cairo
This commit is contained in:
@ -2216,6 +2216,7 @@ static void
|
|||||||
gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
|
gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
|
||||||
GdkEventExpose *eevent)
|
GdkEventExpose *eevent)
|
||||||
{
|
{
|
||||||
|
cairo_t *cr;
|
||||||
GdkRegion *clear_region;
|
GdkRegion *clear_region;
|
||||||
GdkRegion *image_region;
|
GdkRegion *image_region;
|
||||||
GdkRectangle image_rect;
|
GdkRectangle image_rect;
|
||||||
@ -2223,6 +2224,11 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
|
|||||||
gint n_rects;
|
gint n_rects;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
|
cr = gdk_cairo_create (eevent->window);
|
||||||
|
|
||||||
|
gdk_cairo_region (cr, eevent->region);
|
||||||
|
cairo_clip (cr);
|
||||||
|
|
||||||
/* first, clear the exposed part of the region that is outside the
|
/* first, clear the exposed part of the region that is outside the
|
||||||
* image, which is the exposed region minus the image rectangle
|
* image, which is the exposed region minus the image rectangle
|
||||||
*/
|
*/
|
||||||
@ -2286,7 +2292,9 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
|
|||||||
gimp_display_shell_preview_transform (shell);
|
gimp_display_shell_preview_transform (shell);
|
||||||
|
|
||||||
/* draw the grid */
|
/* draw the grid */
|
||||||
gimp_display_shell_draw_grid (shell, eevent->region);
|
cairo_save (cr);
|
||||||
|
gimp_display_shell_draw_grid (shell, cr);
|
||||||
|
cairo_restore (cr);
|
||||||
|
|
||||||
/* draw the guides */
|
/* draw the guides */
|
||||||
gimp_display_shell_draw_guides (shell, eevent->region);
|
gimp_display_shell_draw_guides (shell, eevent->region);
|
||||||
@ -2299,6 +2307,8 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
|
|||||||
|
|
||||||
/* restart (and recalculate) the selection boundaries */
|
/* restart (and recalculate) the selection boundaries */
|
||||||
gimp_display_shell_selection_control (shell, GIMP_SELECTION_ON);
|
gimp_display_shell_selection_control (shell, GIMP_SELECTION_ON);
|
||||||
|
|
||||||
|
cairo_destroy (cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "libgimpbase/gimpbase.h"
|
#include "libgimpbase/gimpbase.h"
|
||||||
|
#include "libgimpcolor/gimpcolor.h"
|
||||||
#include "libgimpmath/gimpmath.h"
|
#include "libgimpmath/gimpmath.h"
|
||||||
#include "libgimpwidgets/gimpwidgets.h"
|
#include "libgimpwidgets/gimpwidgets.h"
|
||||||
|
|
||||||
@ -56,11 +57,12 @@
|
|||||||
|
|
||||||
/* local function prototypes */
|
/* local function prototypes */
|
||||||
|
|
||||||
static GdkGC * gimp_display_shell_get_grid_gc (GimpDisplayShell *shell,
|
static void gimp_display_shell_set_grid_style (GimpDisplayShell *shell,
|
||||||
GimpGrid *grid);
|
GimpGrid *grid,
|
||||||
static GdkGC * gimp_display_shell_get_pen_gc (GimpDisplayShell *shell,
|
cairo_t *cr);
|
||||||
GimpContext *context,
|
static GdkGC * gimp_display_shell_get_pen_gc (GimpDisplayShell *shell,
|
||||||
GimpActiveColor active);
|
GimpContext *context,
|
||||||
|
GimpActiveColor active);
|
||||||
|
|
||||||
|
|
||||||
/* public functions */
|
/* public functions */
|
||||||
@ -226,27 +228,25 @@ gimp_display_shell_draw_guides (GimpDisplayShell *shell,
|
|||||||
|
|
||||||
void
|
void
|
||||||
gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
||||||
const GdkRegion *region)
|
cairo_t *cr)
|
||||||
{
|
{
|
||||||
GimpImage *image;
|
GimpImage *image;
|
||||||
|
|
||||||
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
||||||
g_return_if_fail (region != NULL);
|
g_return_if_fail (cr != NULL);
|
||||||
|
|
||||||
image = gimp_display_get_image (shell->display);
|
image = gimp_display_get_image (shell->display);
|
||||||
|
|
||||||
if (image && gimp_display_shell_get_show_grid (shell))
|
if (image && gimp_display_shell_get_show_grid (shell))
|
||||||
{
|
{
|
||||||
GimpCanvas *canvas = GIMP_CANVAS (shell->canvas);
|
GimpGrid *grid;
|
||||||
GimpGrid *grid;
|
gdouble x, y;
|
||||||
GdkRectangle area;
|
gdouble dx1, dy1, dx2, dy2;
|
||||||
GdkGC *grid_gc;
|
gint x0, x1, x2, x3;
|
||||||
gdouble x, y;
|
gint y0, y1, y2, y3;
|
||||||
gint x0, x1, x2, x3;
|
gint x_real, y_real;
|
||||||
gint y0, y1, y2, y3;
|
gdouble x_offset, y_offset;
|
||||||
gint x_real, y_real;
|
gint width, height;
|
||||||
gdouble x_offset, y_offset;
|
|
||||||
gint width, height;
|
|
||||||
|
|
||||||
#define CROSSHAIR 2
|
#define CROSSHAIR 2
|
||||||
|
|
||||||
@ -256,12 +256,12 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
|||||||
|
|
||||||
g_return_if_fail (grid->xspacing > 0 && grid->yspacing > 0);
|
g_return_if_fail (grid->xspacing > 0 && grid->yspacing > 0);
|
||||||
|
|
||||||
gdk_region_get_clipbox (region, &area);
|
cairo_clip_extents (cr, &dx1, &dy1, &dx2, &dy2);
|
||||||
|
|
||||||
x1 = area.x;
|
x1 = floor (dx1);
|
||||||
y1 = area.y;
|
y1 = floor (dy1);
|
||||||
x2 = area.x + area.width;
|
x2 = ceil (dx2);
|
||||||
y2 = area.y + area.height;
|
y2 = ceil (dy2);
|
||||||
|
|
||||||
width = gimp_image_get_width (image);
|
width = gimp_image_get_width (image);
|
||||||
height = gimp_image_get_height (image);
|
height = gimp_image_get_height (image);
|
||||||
@ -274,10 +274,7 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
|||||||
while (y_offset > 0)
|
while (y_offset > 0)
|
||||||
y_offset -= grid->yspacing;
|
y_offset -= grid->yspacing;
|
||||||
|
|
||||||
grid_gc = gimp_display_shell_get_grid_gc (shell, grid);
|
gimp_display_shell_set_grid_style (shell, grid, cr);
|
||||||
|
|
||||||
gdk_gc_set_clip_region (grid_gc, region);
|
|
||||||
gimp_canvas_set_custom_gc (canvas, grid_gc);
|
|
||||||
|
|
||||||
switch (grid->style)
|
switch (grid->style)
|
||||||
{
|
{
|
||||||
@ -304,9 +301,10 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
|||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
if (y_real >= y1 && y_real < y2)
|
if (y_real >= y1 && y_real < y2)
|
||||||
gimp_canvas_draw_point (GIMP_CANVAS (shell->canvas),
|
{
|
||||||
GIMP_CANVAS_STYLE_CUSTOM,
|
cairo_move_to (cr, x_real, y_real + 0.5);
|
||||||
x_real, y_real);
|
cairo_line_to (cr, x_real + 1, y_real + 0.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -337,21 +335,28 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x_real >= x1 && x_real < x2)
|
if (x_real >= x1 && x_real < x2)
|
||||||
gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_CUSTOM,
|
{
|
||||||
x_real,
|
cairo_move_to (cr,
|
||||||
CLAMP (y_real - CROSSHAIR,
|
x_real + 0.5,
|
||||||
y1, y2 - 1),
|
CLAMP (y_real - CROSSHAIR,
|
||||||
x_real,
|
y1, y2 - 1));
|
||||||
CLAMP (y_real + CROSSHAIR,
|
cairo_line_to (cr,
|
||||||
y1, y2 - 1));
|
x_real + 0.5,
|
||||||
|
CLAMP (y_real + CROSSHAIR,
|
||||||
|
y1, y2 - 1) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (y_real >= y1 && y_real < y2)
|
if (y_real >= y1 && y_real < y2)
|
||||||
gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_CUSTOM,
|
{
|
||||||
CLAMP (x_real - CROSSHAIR,
|
cairo_move_to (cr,
|
||||||
x1, x2 - 1),
|
CLAMP (x_real - CROSSHAIR,
|
||||||
y_real,
|
x1, x2 - 1),
|
||||||
CLAMP (x_real + CROSSHAIR,
|
y_real + 0.5);
|
||||||
x1, x2 - 1),
|
cairo_line_to (cr,
|
||||||
y_real);
|
CLAMP (x_real + CROSSHAIR,
|
||||||
|
x1, x2 - 1) + 1,
|
||||||
|
y_real + 0.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -376,8 +381,10 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
|||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
if (x_real >= x1 && x_real < x2)
|
if (x_real >= x1 && x_real < x2)
|
||||||
gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_CUSTOM,
|
{
|
||||||
x_real, y0, x_real, y3 - 1);
|
cairo_move_to (cr, x_real + 0.5, y0);
|
||||||
|
cairo_line_to (cr, x_real + 0.5, y3 + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = y_offset; y < height; y += grid->yspacing)
|
for (y = y_offset; y < height; y += grid->yspacing)
|
||||||
@ -390,14 +397,15 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
|||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
if (y_real >= y1 && y_real < y2)
|
if (y_real >= y1 && y_real < y2)
|
||||||
gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_CUSTOM,
|
{
|
||||||
x0, y_real, x3 - 1, y_real);
|
cairo_move_to (cr, x0, y_real + 0.5);
|
||||||
|
cairo_line_to (cr, x3 + 1, y_real + 0.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gimp_canvas_set_custom_gc (canvas, NULL);
|
cairo_stroke (cr);
|
||||||
gdk_gc_set_clip_region (grid_gc, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,46 +700,71 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
|
|||||||
|
|
||||||
/* private functions */
|
/* private functions */
|
||||||
|
|
||||||
static GdkGC *
|
static void
|
||||||
gimp_display_shell_get_grid_gc (GimpDisplayShell *shell,
|
gimp_display_shell_set_grid_style (GimpDisplayShell *shell,
|
||||||
GimpGrid *grid)
|
GimpGrid *grid,
|
||||||
|
cairo_t *cr)
|
||||||
{
|
{
|
||||||
GdkGCValues values;
|
cairo_set_line_width (cr, 1.0);
|
||||||
GdkColor fg, bg;
|
|
||||||
|
|
||||||
if (shell->grid_gc)
|
|
||||||
return shell->grid_gc;
|
|
||||||
|
|
||||||
switch (grid->style)
|
switch (grid->style)
|
||||||
{
|
{
|
||||||
case GIMP_GRID_ON_OFF_DASH:
|
case GIMP_GRID_ON_OFF_DASH:
|
||||||
values.line_style = GDK_LINE_ON_OFF_DASH;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GIMP_GRID_DOUBLE_DASH:
|
case GIMP_GRID_DOUBLE_DASH:
|
||||||
values.line_style = GDK_LINE_DOUBLE_DASH;
|
{
|
||||||
|
guchar *data = g_malloc0 (8 * 8 * 4);
|
||||||
|
guchar fg_r, fg_g, fg_b, fg_a;
|
||||||
|
guchar bg_r, bg_g, bg_b, bg_a;
|
||||||
|
gint x, y;
|
||||||
|
guchar *d;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
static cairo_user_data_key_t data_key;
|
||||||
|
|
||||||
|
gimp_rgba_get_uchar (&grid->fgcolor, &fg_r, &fg_g, &fg_b, &fg_a);
|
||||||
|
|
||||||
|
if (grid->style == GIMP_GRID_DOUBLE_DASH)
|
||||||
|
gimp_rgba_get_uchar (&grid->bgcolor, &bg_r, &bg_g, &bg_b, &bg_a);
|
||||||
|
else
|
||||||
|
bg_r = bg_g = bg_b = bg_a = 0;
|
||||||
|
|
||||||
|
d = data;
|
||||||
|
|
||||||
|
for (y = 0; y < 8; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < 8; x++)
|
||||||
|
{
|
||||||
|
if ((y < 4 && x < 4) || (y >= 4 && x >= 4))
|
||||||
|
GIMP_CAIRO_ARGB32_SET_PIXEL (d, fg_r, fg_g, fg_b, fg_a);
|
||||||
|
else
|
||||||
|
GIMP_CAIRO_ARGB32_SET_PIXEL (d, bg_r, bg_g, bg_b, bg_a);
|
||||||
|
|
||||||
|
d += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
surface = cairo_image_surface_create_for_data (data,
|
||||||
|
CAIRO_FORMAT_ARGB32,
|
||||||
|
8, 8, 8 * 4);
|
||||||
|
cairo_surface_set_user_data (surface, &data_key,
|
||||||
|
data, (cairo_destroy_func_t) g_free);
|
||||||
|
|
||||||
|
cairo_set_source_surface (cr, surface, 0, 0);
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
|
||||||
|
cairo_pattern_set_extend (cairo_get_source (cr),
|
||||||
|
CAIRO_EXTEND_REPEAT);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIMP_GRID_DOTS:
|
case GIMP_GRID_DOTS:
|
||||||
case GIMP_GRID_INTERSECTIONS:
|
case GIMP_GRID_INTERSECTIONS:
|
||||||
case GIMP_GRID_SOLID:
|
case GIMP_GRID_SOLID:
|
||||||
values.line_style = GDK_LINE_SOLID;
|
cairo_set_source_rgb (cr,
|
||||||
|
grid->fgcolor.r,
|
||||||
|
grid->fgcolor.g,
|
||||||
|
grid->fgcolor.b);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
values.join_style = GDK_JOIN_MITER;
|
|
||||||
|
|
||||||
shell->grid_gc = gdk_gc_new_with_values (gtk_widget_get_window (shell->canvas),
|
|
||||||
&values, (GDK_GC_LINE_STYLE |
|
|
||||||
GDK_GC_JOIN_STYLE));
|
|
||||||
|
|
||||||
gimp_rgb_get_gdk_color (&grid->fgcolor, &fg);
|
|
||||||
gdk_gc_set_rgb_fg_color (shell->grid_gc, &fg);
|
|
||||||
|
|
||||||
gimp_rgb_get_gdk_color (&grid->bgcolor, &bg);
|
|
||||||
gdk_gc_set_rgb_bg_color (shell->grid_gc, &bg);
|
|
||||||
|
|
||||||
return shell->grid_gc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkGC *
|
static GdkGC *
|
||||||
|
@ -34,7 +34,7 @@ void gimp_display_shell_draw_guide (GimpDisplayShell *shell,
|
|||||||
void gimp_display_shell_draw_guides (GimpDisplayShell *shell,
|
void gimp_display_shell_draw_guides (GimpDisplayShell *shell,
|
||||||
const GdkRegion *region);
|
const GdkRegion *region);
|
||||||
void gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
void gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
||||||
const GdkRegion *region);
|
cairo_t *cr);
|
||||||
void gimp_display_shell_draw_pen (GimpDisplayShell *shell,
|
void gimp_display_shell_draw_pen (GimpDisplayShell *shell,
|
||||||
const GimpVector2 *points,
|
const GimpVector2 *points,
|
||||||
gint num_points,
|
gint num_points,
|
||||||
|
@ -304,12 +304,6 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell)
|
|||||||
|
|
||||||
gimp_display_shell_icon_update_stop (shell);
|
gimp_display_shell_icon_update_stop (shell);
|
||||||
|
|
||||||
if (shell->grid_gc)
|
|
||||||
{
|
|
||||||
g_object_unref (shell->grid_gc);
|
|
||||||
shell->grid_gc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shell->pen_gc)
|
if (shell->pen_gc)
|
||||||
{
|
{
|
||||||
g_object_unref (shell->pen_gc);
|
g_object_unref (shell->pen_gc);
|
||||||
@ -426,12 +420,6 @@ gimp_display_shell_grid_notify_handler (GimpGrid *grid,
|
|||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
GimpDisplayShell *shell)
|
GimpDisplayShell *shell)
|
||||||
{
|
{
|
||||||
if (shell->grid_gc)
|
|
||||||
{
|
|
||||||
g_object_unref (shell->grid_gc);
|
|
||||||
shell->grid_gc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
gimp_display_shell_expose_full (shell);
|
gimp_display_shell_expose_full (shell);
|
||||||
|
|
||||||
/* update item factory */
|
/* update item factory */
|
||||||
|
@ -938,12 +938,6 @@ gimp_display_shell_unrealize (GtkWidget *widget)
|
|||||||
{
|
{
|
||||||
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (widget);
|
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (widget);
|
||||||
|
|
||||||
if (shell->grid_gc)
|
|
||||||
{
|
|
||||||
g_object_unref (shell->grid_gc);
|
|
||||||
shell->grid_gc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shell->pen_gc)
|
if (shell->pen_gc)
|
||||||
{
|
{
|
||||||
g_object_unref (shell->pen_gc);
|
g_object_unref (shell->pen_gc);
|
||||||
|
@ -115,7 +115,6 @@ struct _GimpDisplayShell
|
|||||||
GList *children;
|
GList *children;
|
||||||
|
|
||||||
GtkWidget *canvas; /* GimpCanvas widget */
|
GtkWidget *canvas; /* GimpCanvas widget */
|
||||||
GdkGC *grid_gc; /* GC for grid drawing */
|
|
||||||
GdkGC *pen_gc; /* GC for felt pen drawing */
|
GdkGC *pen_gc; /* GC for felt pen drawing */
|
||||||
|
|
||||||
GtkAdjustment *hsbdata; /* adjustments */
|
GtkAdjustment *hsbdata; /* adjustments */
|
||||||
|
Reference in New Issue
Block a user