From 1d1ff1fedde7e2420f3ae27bcde7f1880eb3767d Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Thu, 12 Aug 2010 13:13:15 +0200 Subject: [PATCH] app: port GimpDisplayShell sample point drawing to cairo Same disclaimer about tool uglyness applies here. Will be fixed. --- app/display/gimpcanvas.c | 42 +++------ app/display/gimpcanvas.h | 9 +- app/display/gimpdisplayshell-callbacks.c | 4 +- app/display/gimpdisplayshell-draw.c | 112 +++++++++++------------ app/display/gimpdisplayshell-draw.h | 4 +- app/display/gimpdisplayshell-style.c | 33 ++++++- app/display/gimpdisplayshell-style.h | 15 +-- app/tools/gimpcolortool.c | 42 ++++++--- 8 files changed, 138 insertions(+), 123 deletions(-) diff --git a/app/display/gimpcanvas.c b/app/display/gimpcanvas.c index 46d96623a9..500395d782 100644 --- a/app/display/gimpcanvas.c +++ b/app/display/gimpcanvas.c @@ -371,8 +371,6 @@ gimp_canvas_gc_new (GimpCanvas *canvas, { case GIMP_CANVAS_STYLE_BLACK: case GIMP_CANVAS_STYLE_WHITE: - case GIMP_CANVAS_STYLE_SAMPLE_POINT_NORMAL: - case GIMP_CANVAS_STYLE_SAMPLE_POINT_ACTIVE: break; case GIMP_CANVAS_STYLE_RENDER: @@ -489,18 +487,6 @@ gimp_canvas_gc_new (GimpCanvas *canvas, bg.green = 0xffff; bg.blue = 0x0; break; - - case GIMP_CANVAS_STYLE_SAMPLE_POINT_NORMAL: - fg.red = 0x0; - fg.green = 0x7f7f; - fg.blue = 0xffff; - break; - - case GIMP_CANVAS_STYLE_SAMPLE_POINT_ACTIVE: - fg.red = 0xffff; - fg.green = 0x0; - fg.blue = 0x0; - break; } gdk_gc_set_rgb_fg_color (gc, &fg); @@ -805,28 +791,24 @@ gimp_canvas_draw_segments (GimpCanvas *canvas, /** * gimp_canvas_draw_text: * @canvas: a #GimpCanvas widget - * @style: one of the enumerated #GimpCanvasStyle's. - * @x: X coordinate of the left of the layout. - * @y: Y coordinate of the top of the layout. * @format: a standard printf() format string. * @Varargs: the parameters to insert into the format string. * - * Draws a layout, in the specified style. + * Returns a layout which can be used for + * pango_cairo_show_layout(). The layout belongs to the canvas and + * should not be freed, not should a pointer to it be kept around + * after drawing. + * + * Returns: a #PangoLayout owned by the canvas. **/ -void -gimp_canvas_draw_text (GimpCanvas *canvas, - GimpCanvasStyle style, - gint x, - gint y, - const gchar *format, - ...) +PangoLayout * +gimp_canvas_get_layout (GimpCanvas *canvas, + const gchar *format, + ...) { va_list args; gchar *text; - if (! gimp_canvas_ensure_style (canvas, style)) - return; - if (! canvas->layout) canvas->layout = gtk_widget_create_pango_layout (GTK_WIDGET (canvas), NULL); @@ -838,9 +820,7 @@ gimp_canvas_draw_text (GimpCanvas *canvas, pango_layout_set_text (canvas->layout, text, -1); g_free (text); - gdk_draw_layout (gtk_widget_get_window (GTK_WIDGET (canvas)), - canvas->gc[style], - x, y, canvas->layout); + return canvas->layout; } /** diff --git a/app/display/gimpcanvas.h b/app/display/gimpcanvas.h index 1bb1bda4d6..81a09c232d 100644 --- a/app/display/gimpcanvas.h +++ b/app/display/gimpcanvas.h @@ -34,8 +34,6 @@ typedef enum GIMP_CANVAS_STYLE_SELECTION_OUT, GIMP_CANVAS_STYLE_LAYER_BOUNDARY, GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY, - GIMP_CANVAS_STYLE_SAMPLE_POINT_NORMAL, - GIMP_CANVAS_STYLE_SAMPLE_POINT_ACTIVE, GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE, GIMP_CANVAS_STYLE_CUSTOM, GIMP_CANVAS_NUM_STYLES @@ -134,12 +132,9 @@ void gimp_canvas_draw_segments (GimpCanvas *canvas, GimpCanvasStyle style, GdkSegment *segments, gint num_segments); -void gimp_canvas_draw_text (GimpCanvas *canvas, - GimpCanvasStyle style, - gint x, - gint y, +PangoLayout *gimp_canvas_get_layout (GimpCanvas *canvas, const gchar *format, - ...) G_GNUC_PRINTF (5, 6); + ...) G_GNUC_PRINTF (2, 3); void gimp_canvas_draw_rgb (GimpCanvas *canvas, GimpCanvasStyle style, gint x, diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c index 17386402fd..db5e4b651a 100644 --- a/app/display/gimpdisplayshell-callbacks.c +++ b/app/display/gimpdisplayshell-callbacks.c @@ -2302,7 +2302,9 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell, cairo_restore (cr); /* draw the sample points */ - gimp_display_shell_draw_sample_points (shell, eevent->region); + cairo_save (cr); + gimp_display_shell_draw_sample_points (shell, cr); + cairo_restore (cr); /* and the cursor (if we have a software cursor) */ gimp_display_shell_draw_cursor (shell); diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c index 7bef3107b5..a0bc9de524 100644 --- a/app/display/gimpdisplayshell-draw.c +++ b/app/display/gimpdisplayshell-draw.c @@ -438,18 +438,19 @@ gimp_display_shell_draw_pen (GimpDisplayShell *shell, void gimp_display_shell_draw_sample_point (GimpDisplayShell *shell, + cairo_t *cr, GimpSamplePoint *sample_point, - const GdkRectangle *area, gboolean active) { - GimpImage *image; - GimpCanvasStyle style; - gdouble x, y; - gint x1, x2; - gint y1, y2; - gint w, h; + GimpImage *image; + gdouble dx1, dy1, dx2, dy2; + gint x1, x2, y1, y2; + gint sx1, sx2, sy1, sy2; + gdouble x, y; + PangoLayout *layout; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + g_return_if_fail (cr != NULL); g_return_if_fail (sample_point != NULL); if (sample_point->x < 0) @@ -457,93 +458,82 @@ gimp_display_shell_draw_sample_point (GimpDisplayShell *shell, image = gimp_display_get_image (shell->display); + cairo_clip_extents (cr, &dx1, &dy1, &dx2, &dy2); + + x1 = floor (dx1); + y1 = floor (dy1); + x2 = ceil (dx2); + y2 = ceil (dy2); + gimp_display_shell_transform_xy_f (shell, sample_point->x + 0.5, sample_point->y + 0.5, &x, &y, FALSE); - x1 = floor (x - GIMP_SAMPLE_POINT_DRAW_SIZE); - x2 = ceil (x + GIMP_SAMPLE_POINT_DRAW_SIZE); - y1 = floor (y - GIMP_SAMPLE_POINT_DRAW_SIZE); - y2 = ceil (y + GIMP_SAMPLE_POINT_DRAW_SIZE); + sx1 = floor (x - GIMP_SAMPLE_POINT_DRAW_SIZE); + sx2 = ceil (x + GIMP_SAMPLE_POINT_DRAW_SIZE); + sy1 = floor (y - GIMP_SAMPLE_POINT_DRAW_SIZE); + sy2 = ceil (y + GIMP_SAMPLE_POINT_DRAW_SIZE); - gdk_drawable_get_size (gtk_widget_get_window (shell->canvas), &w, &h); - - if (x < - GIMP_SAMPLE_POINT_DRAW_SIZE || - y < - GIMP_SAMPLE_POINT_DRAW_SIZE || - x > w + GIMP_SAMPLE_POINT_DRAW_SIZE || - y > h + GIMP_SAMPLE_POINT_DRAW_SIZE) + if (sx1 > x2 || + sx2 < x1 || + sy1 > y2 || + sy2 < y1) return; - if (area && (x + GIMP_SAMPLE_POINT_DRAW_SIZE < area->x || - y + GIMP_SAMPLE_POINT_DRAW_SIZE < area->y || - x - GIMP_SAMPLE_POINT_DRAW_SIZE >= area->x + area->width || - y - GIMP_SAMPLE_POINT_DRAW_SIZE >= area->y + area->height)) - return; - - if (active) - style = GIMP_CANVAS_STYLE_SAMPLE_POINT_ACTIVE; - else - style = GIMP_CANVAS_STYLE_SAMPLE_POINT_NORMAL; + gimp_display_shell_set_sample_point_style (shell, cr, active); #define HALF_SIZE (GIMP_SAMPLE_POINT_DRAW_SIZE / 2) - gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), style, - x, y1, x, y1 + HALF_SIZE); - gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), style, - x, y2 - HALF_SIZE, x, y2); + cairo_move_to (cr, x + 0.5, sy1); + cairo_line_to (cr, x + 0.5, sy1 + HALF_SIZE); - gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), style, - x1, y, x1 + HALF_SIZE, y); - gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), style, - x2 - HALF_SIZE, y, x2, y); + cairo_move_to (cr, x + 0.5, sy2); + cairo_line_to (cr, x + 0.5, sy2 - HALF_SIZE); - gimp_canvas_draw_arc (GIMP_CANVAS (shell->canvas), style, - FALSE, - x - HALF_SIZE, y - HALF_SIZE, - GIMP_SAMPLE_POINT_DRAW_SIZE, - GIMP_SAMPLE_POINT_DRAW_SIZE, - 0, 64 * 270); + cairo_move_to (cr, sx1, y + 0.5); + cairo_line_to (cr, sx1 + HALF_SIZE, y + 0.5); - gimp_canvas_draw_text (GIMP_CANVAS (shell->canvas), style, - x + 2, y + 2, - "%d", - g_list_index (gimp_image_get_sample_points (image), - sample_point) + 1); + cairo_move_to (cr, sx2, y + 0.5); + cairo_line_to (cr, sx2 - HALF_SIZE, y + 0.5); + + cairo_arc_negative (cr, x + 0.5, y + 0.5, HALF_SIZE, 0.0, 0.5 * G_PI); + + cairo_stroke (cr); + + layout = + gimp_canvas_get_layout (GIMP_CANVAS (shell->canvas), + "%d", + g_list_index (gimp_image_get_sample_points (image), + sample_point) + 1); + + cairo_move_to (cr, x + 2, y + 2); + pango_cairo_show_layout (cr, layout); + + cairo_fill (cr); } void gimp_display_shell_draw_sample_points (GimpDisplayShell *shell, - const GdkRegion *region) + cairo_t *cr) { GimpImage *image; 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); if (image && gimp_display_shell_get_show_sample_points (shell)) { - GdkRectangle area; - GList *list; - - gimp_canvas_set_clip_region (GIMP_CANVAS (shell->canvas), - GIMP_CANVAS_STYLE_SAMPLE_POINT_NORMAL, - region); - gdk_region_get_clipbox (region, &area); + GList *list; for (list = gimp_image_get_sample_points (image); list; list = g_list_next (list)) { - gimp_display_shell_draw_sample_point (shell, list->data, - &area, FALSE); + gimp_display_shell_draw_sample_point (shell, cr, list->data, FALSE); } - - gimp_canvas_set_clip_region (GIMP_CANVAS (shell->canvas), - GIMP_CANVAS_STYLE_SAMPLE_POINT_NORMAL, - NULL); } } diff --git a/app/display/gimpdisplayshell-draw.h b/app/display/gimpdisplayshell-draw.h index 7473e02c2d..fe11b68960 100644 --- a/app/display/gimpdisplayshell-draw.h +++ b/app/display/gimpdisplayshell-draw.h @@ -42,11 +42,11 @@ void gimp_display_shell_draw_pen (GimpDisplayShell *shell, GimpActiveColor color, gint width); void gimp_display_shell_draw_sample_point (GimpDisplayShell *shell, + cairo_t *cr, GimpSamplePoint *sample_point, - const GdkRectangle *area, gboolean active); void gimp_display_shell_draw_sample_points (GimpDisplayShell *shell, - const GdkRegion *region); + cairo_t *cr); void gimp_display_shell_draw_vector (GimpDisplayShell *shell, GimpVectors *vectors); void gimp_display_shell_draw_vectors (GimpDisplayShell *shell); diff --git a/app/display/gimpdisplayshell-style.c b/app/display/gimpdisplayshell-style.c index 52d1f82756..97e7eb6448 100644 --- a/app/display/gimpdisplayshell-style.c +++ b/app/display/gimpdisplayshell-style.c @@ -34,10 +34,13 @@ #include "gimpdisplayshell-style.h" -static const GimpRGB guide_normal_fg = { 0.0, 0.0, 0.0, 1.0 }; -static const GimpRGB guide_normal_bg = { 0.0, 0.5, 1.0, 1.0 }; -static const GimpRGB guide_active_fg = { 0.0, 0.0, 0.0, 1.0 }; -static const GimpRGB guide_active_bg = { 1.0, 0.0, 0.0, 1.0 }; +static const GimpRGB guide_normal_fg = { 0.0, 0.0, 0.0, 1.0 }; +static const GimpRGB guide_normal_bg = { 0.0, 0.5, 1.0, 1.0 }; +static const GimpRGB guide_active_fg = { 0.0, 0.0, 0.0, 1.0 }; +static const GimpRGB guide_active_bg = { 1.0, 0.0, 0.0, 1.0 }; + +static const GimpRGB sample_point_normal = { 0.0, 0.5, 1.0, 1.0 }; +static const GimpRGB sample_point_active = { 1.0, 0.0, 0.0, 1.0 }; /* local function prototypes */ @@ -69,6 +72,28 @@ gimp_display_shell_set_guide_style (GimpDisplayShell *shell, &guide_normal_bg); } +void +gimp_display_shell_set_sample_point_style (GimpDisplayShell *shell, + cairo_t *cr, + gboolean active) +{ + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + g_return_if_fail (cr != NULL); + + cairo_set_line_width (cr, 1.0); + + if (active) + cairo_set_source_rgb (cr, + sample_point_active.r, + sample_point_active.g, + sample_point_active.b); + else + cairo_set_source_rgb (cr, + sample_point_normal.r, + sample_point_normal.g, + sample_point_normal.b); +} + void gimp_display_shell_set_grid_style (GimpDisplayShell *shell, cairo_t *cr, diff --git a/app/display/gimpdisplayshell-style.h b/app/display/gimpdisplayshell-style.h index 41bb7597aa..55959e9925 100644 --- a/app/display/gimpdisplayshell-style.h +++ b/app/display/gimpdisplayshell-style.h @@ -22,12 +22,15 @@ #define __GIMP_DISPLAY_SHELL_STYLE_H__ -void gimp_display_shell_set_guide_style (GimpDisplayShell *shell, - cairo_t *cr, - gboolean active); -void gimp_display_shell_set_grid_style (GimpDisplayShell *shell, - cairo_t *cr, - GimpGrid *grid); +void gimp_display_shell_set_guide_style (GimpDisplayShell *shell, + cairo_t *cr, + gboolean active); +void gimp_display_shell_set_sample_point_style (GimpDisplayShell *shell, + cairo_t *cr, + gboolean active); +void gimp_display_shell_set_grid_style (GimpDisplayShell *shell, + cairo_t *cr, + GimpGrid *grid); #endif /* __GIMP_DISPLAY_SHELL_STYLE_H__ */ diff --git a/app/tools/gimpcolortool.c b/app/tools/gimpcolortool.c index 1c9e88b9b5..376d2e10e5 100644 --- a/app/tools/gimpcolortool.c +++ b/app/tools/gimpcolortool.c @@ -210,15 +210,23 @@ gimp_color_tool_control (GimpTool *tool, case GIMP_TOOL_ACTION_RESUME: if (color_tool->sample_point && gimp_display_shell_get_show_sample_points (shell)) - gimp_display_shell_draw_sample_point (shell, color_tool->sample_point, - NULL, TRUE); + { + cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas)); + gimp_display_shell_draw_sample_point (shell, cr, + color_tool->sample_point, TRUE); + cairo_destroy (cr); + } break; case GIMP_TOOL_ACTION_HALT: if (color_tool->sample_point && gimp_display_shell_get_show_sample_points (shell)) - gimp_display_shell_draw_sample_point (shell, color_tool->sample_point, - NULL, FALSE); + { + cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas)); + gimp_display_shell_draw_sample_point (shell, cr, + color_tool->sample_point, FALSE); + cairo_destroy (cr); + } break; } @@ -356,8 +364,12 @@ gimp_color_tool_button_release (GimpTool *tool, gimp_image_flush (image); if (color_tool->sample_point) - gimp_display_shell_draw_sample_point (shell, color_tool->sample_point, - NULL, TRUE); + { + cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas)); + gimp_display_shell_draw_sample_point (shell, cr, + color_tool->sample_point, TRUE); + cairo_destroy (cr); + } color_tool->moving_sample_point = FALSE; color_tool->sample_point_x = -1; @@ -496,8 +508,12 @@ gimp_color_tool_oper_update (GimpTool *tool, color_tool->sample_point = sample_point; if (color_tool->sample_point) - gimp_display_shell_draw_sample_point (shell, color_tool->sample_point, - NULL, TRUE); + { + cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas)); + gimp_display_shell_draw_sample_point (shell, cr, + color_tool->sample_point, TRUE); + cairo_destroy (cr); + } } static void @@ -823,9 +839,13 @@ gimp_color_tool_start_sample_point (GimpTool *tool, gimp_tool_control_set_scroll_lock (tool->control, TRUE); if (color_tool->sample_point) - gimp_display_shell_draw_sample_point (gimp_display_get_shell (display), - color_tool->sample_point, - NULL, FALSE); + { + GimpDisplayShell *shell = gimp_display_get_shell (display); + cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas)); + gimp_display_shell_draw_sample_point (shell, cr, + color_tool->sample_point, FALSE); + cairo_destroy (cr); + } color_tool->sample_point = NULL; color_tool->moving_sample_point = TRUE;