app: port GimpDisplayShell layer boundary drawing to cairo

The boundary is temporarily kept around as both BoundSeg and
GdkSegment arrays now, but this uglyness will go away once porting to
cairo is complete.
This commit is contained in:
Michael Natterer
2010-08-24 18:07:31 +02:00
parent b5e49426df
commit 4e0925a67c
7 changed files with 147 additions and 57 deletions

View File

@ -398,9 +398,6 @@ gimp_canvas_gc_new (GimpCanvas *canvas,
case GIMP_CANVAS_STYLE_SELECTION_IN: case GIMP_CANVAS_STYLE_SELECTION_IN:
case GIMP_CANVAS_STYLE_SELECTION_OUT: case GIMP_CANVAS_STYLE_SELECTION_OUT:
case GIMP_CANVAS_STYLE_LAYER_BOUNDARY:
case GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY:
case GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE:
mask |= GDK_GC_CAP_STYLE | GDK_GC_FILL | GDK_GC_STIPPLE; mask |= GDK_GC_CAP_STYLE | GDK_GC_FILL | GDK_GC_STIPPLE;
values.cap_style = GDK_CAP_NOT_LAST; values.cap_style = GDK_CAP_NOT_LAST;
values.fill = GDK_OPAQUE_STIPPLED; values.fill = GDK_OPAQUE_STIPPLED;
@ -456,36 +453,6 @@ gimp_canvas_gc_new (GimpCanvas *canvas,
bg.green = 0x7f7f; bg.green = 0x7f7f;
bg.blue = 0x7f7f; bg.blue = 0x7f7f;
break; break;
case GIMP_CANVAS_STYLE_LAYER_BOUNDARY:
fg.red = 0x0;
fg.green = 0x0;
fg.blue = 0x0;
bg.red = 0xffff;
bg.green = 0xffff;
bg.blue = 0x0;
break;
case GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY:
fg.red = 0x0;
fg.green = 0x0;
fg.blue = 0x0;
bg.red = 0x0;
bg.green = 0xffff;
bg.blue = 0xffff;
break;
case GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE:
fg.red = 0x0;
fg.green = 0x0;
fg.blue = 0x0;
bg.red = 0x0;
bg.green = 0xffff;
bg.blue = 0x0;
break;
} }
gdk_gc_set_rgb_fg_color (gc, &fg); gdk_gc_set_rgb_fg_color (gc, &fg);

View File

@ -32,9 +32,6 @@ typedef enum
GIMP_CANVAS_STYLE_XOR_DOTTED, GIMP_CANVAS_STYLE_XOR_DOTTED,
GIMP_CANVAS_STYLE_SELECTION_IN, GIMP_CANVAS_STYLE_SELECTION_IN,
GIMP_CANVAS_STYLE_SELECTION_OUT, GIMP_CANVAS_STYLE_SELECTION_OUT,
GIMP_CANVAS_STYLE_LAYER_BOUNDARY,
GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY,
GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE,
GIMP_CANVAS_NUM_STYLES GIMP_CANVAS_NUM_STYLES
} GimpCanvasStyle; } GimpCanvasStyle;

View File

@ -26,9 +26,11 @@
#include "display-types.h" #include "display-types.h"
#include "base/boundary.h"
#include "base/tile-manager.h" #include "base/tile-manager.h"
#include "core/gimpcontext.h" #include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpgrid.h" #include "core/gimpgrid.h"
#include "core/gimpguide.h" #include "core/gimpguide.h"
#include "core/gimpimage.h" #include "core/gimpimage.h"
@ -529,6 +531,71 @@ gimp_display_shell_draw_sample_points (GimpDisplayShell *shell,
} }
} }
void
gimp_display_shell_draw_layer_boundary (GimpDisplayShell *shell,
cairo_t *cr,
GimpDrawable *drawable,
BoundSeg *segs,
gint n_segs)
{
gint i;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (cr != NULL);
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (segs != NULL && n_segs == 4);
gimp_display_shell_set_layer_style (shell, cr, drawable);
for (i = 0; i < n_segs; i++)
{
gint xclamp = shell->disp_width + 1;
gint yclamp = shell->disp_height + 1;
gint x1, y1;
gint x2, y2;
gimp_display_shell_transform_xy (shell,
segs[i].x1, segs[i].y1,
&x1, &y1,
FALSE);
gimp_display_shell_transform_xy (shell,
segs[i].x2, segs[i].y2,
&x2, &y2,
FALSE);
x1 = CLAMP (x1, -1, xclamp);
y1 = CLAMP (y1, -1, yclamp);
x2 = CLAMP (x2, -1, xclamp);
y2 = CLAMP (y2, -1, yclamp);
if (x1 == x2)
{
if (! segs[i].open)
{
x1 -= 1;
x2 -= 1;
}
cairo_move_to (cr, x1 + 0.5, y1);
cairo_line_to (cr, x2 + 0.5, y2);
}
else
{
if (! segs[i].open)
{
y1 -= 1;
y2 -= 1;
}
cairo_move_to (cr, x1, y1 + 0.5);
cairo_line_to (cr, x2, y2 + 0.5);
}
}
cairo_stroke (cr);
}
void void
gimp_display_shell_draw_vector (GimpDisplayShell *shell, gimp_display_shell_draw_vector (GimpDisplayShell *shell,
GimpVectors *vectors) GimpVectors *vectors)

View File

@ -48,6 +48,11 @@ void gimp_display_shell_draw_sample_point (GimpDisplayShell *shell,
gboolean active); gboolean active);
void gimp_display_shell_draw_sample_points (GimpDisplayShell *shell, void gimp_display_shell_draw_sample_points (GimpDisplayShell *shell,
cairo_t *cr); cairo_t *cr);
void gimp_display_shell_draw_layer_boundary (GimpDisplayShell *shell,
cairo_t *cr,
GimpDrawable *drawable,
BoundSeg *segs,
gint n_segs);
void gimp_display_shell_draw_vector (GimpDisplayShell *shell, void gimp_display_shell_draw_vector (GimpDisplayShell *shell,
GimpVectors *vectors); GimpVectors *vectors);
void gimp_display_shell_draw_vectors (GimpDisplayShell *shell); void gimp_display_shell_draw_vectors (GimpDisplayShell *shell);

View File

@ -35,6 +35,7 @@
#include "gimpdisplay.h" #include "gimpdisplay.h"
#include "gimpdisplayshell.h" #include "gimpdisplayshell.h"
#include "gimpdisplayshell-appearance.h" #include "gimpdisplayshell-appearance.h"
#include "gimpdisplayshell-draw.h"
#include "gimpdisplayshell-expose.h" #include "gimpdisplayshell-expose.h"
#include "gimpdisplayshell-selection.h" #include "gimpdisplayshell-selection.h"
#include "gimpdisplayshell-transform.h" #include "gimpdisplayshell-transform.h"
@ -56,6 +57,9 @@ struct _Selection
GdkSegment *segs_out; /* gdk segments of area boundary */ GdkSegment *segs_out; /* gdk segments of area boundary */
gint n_segs_out; /* number of segments in segs2 */ gint n_segs_out; /* number of segments in segs2 */
BoundSeg *bound_segs_layer;
gint n_bound_segs_layer;
GdkSegment *segs_layer; /* gdk segments of layer boundary */ GdkSegment *segs_layer; /* gdk segments of layer boundary */
gint n_segs_layer; /* number of segments in segs3 */ gint n_segs_layer; /* number of segments in segs3 */
@ -384,21 +388,20 @@ selection_layer_draw (Selection *selection)
{ {
if (selection->segs_layer) if (selection->segs_layer)
{ {
GimpCanvas *canvas = GIMP_CANVAS (selection->shell->canvas); GimpImage *image;
GimpImage *image = gimp_display_get_image (selection->shell->display); GimpDrawable *drawable;
GimpDrawable *drawable = gimp_image_get_active_drawable (image); cairo_t *cr;
GimpCanvasStyle style;
if (GIMP_IS_LAYER_MASK (drawable)) image = gimp_display_get_image (selection->shell->display);
style = GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE; drawable = gimp_image_get_active_drawable (image);
else if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
style = GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY;
else
style = GIMP_CANVAS_STYLE_LAYER_BOUNDARY;
gimp_canvas_draw_segments (canvas, style, cr = gdk_cairo_create (gtk_widget_get_window (selection->shell->canvas));
selection->segs_layer,
selection->n_segs_layer); gimp_display_shell_draw_layer_boundary (selection->shell, cr, drawable,
selection->bound_segs_layer,
selection->n_bound_segs_layer);
cairo_destroy (cr);
} }
} }
@ -659,19 +662,19 @@ selection_generate_segs (Selection *selection)
if (layer) if (layer)
{ {
BoundSeg *segs; selection->bound_segs_layer =
gimp_layer_boundary (layer, &selection->n_bound_segs_layer);
segs = gimp_layer_boundary (layer, &selection->n_segs_layer); if (selection->n_bound_segs_layer)
if (selection->n_segs_layer)
{ {
selection->segs_layer = g_new (GdkSegment, selection->n_segs_layer); selection->segs_layer = g_new (GdkSegment,
selection->n_bound_segs_layer);
selection->n_segs_layer = selection->n_bound_segs_layer;
selection_transform_segs (selection, segs, selection_transform_segs (selection,
selection->bound_segs_layer,
selection->segs_layer, selection->segs_layer,
selection->n_segs_layer); selection->n_segs_layer);
g_free (segs);
} }
} }
} }
@ -695,6 +698,13 @@ selection_free_segs (Selection *selection)
selection->n_segs_out = 0; selection->n_segs_out = 0;
} }
if (selection->bound_segs_layer)
{
g_free (selection->bound_segs_layer);
selection->bound_segs_layer = NULL;
selection->n_bound_segs_layer = 0;
}
if (selection->segs_layer) if (selection->segs_layer)
{ {
g_free (selection->segs_layer); g_free (selection->segs_layer);

View File

@ -30,6 +30,7 @@
#include "core/gimpcontext.h" #include "core/gimpcontext.h"
#include "core/gimpgrid.h" #include "core/gimpgrid.h"
#include "core/gimplayermask.h"
#include "gimpdisplayshell.h" #include "gimpdisplayshell.h"
#include "gimpdisplayshell-style.h" #include "gimpdisplayshell-style.h"
@ -43,6 +44,15 @@ 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_normal = { 0.0, 0.5, 1.0, 1.0 };
static const GimpRGB sample_point_active = { 1.0, 0.0, 0.0, 1.0 }; static const GimpRGB sample_point_active = { 1.0, 0.0, 0.0, 1.0 };
static const GimpRGB layer_fg = { 0.0, 0.0, 0.0, 1.0 };
static const GimpRGB layer_bg = { 1.0, 1.0, 0.0, 1.0 };
static const GimpRGB layer_group_fg = { 0.0, 0.0, 0.0, 1.0 };
static const GimpRGB layer_group_bg = { 0.0, 1.0, 1.0, 1.0 };
static const GimpRGB layer_mask_fg = { 0.0, 0.0, 0.0, 1.0 };
static const GimpRGB layer_mask_bg = { 0.0, 1.0, 0.0, 1.0 };
/* local function prototypes */ /* local function prototypes */
@ -182,6 +192,37 @@ gimp_display_shell_set_pen_style (GimpDisplayShell *shell,
cairo_set_source_rgb (cr, rgb.r, rgb.g, rgb.b); cairo_set_source_rgb (cr, rgb.r, rgb.g, rgb.b);
} }
void
gimp_display_shell_set_layer_style (GimpDisplayShell *shell,
cairo_t *cr,
GimpDrawable *drawable)
{
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (cr != NULL);
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
cairo_set_line_width (cr, 1.0);
if (GIMP_IS_LAYER_MASK (drawable))
{
gimp_display_shell_set_stipple_style (cr,
&layer_mask_fg,
&layer_mask_bg);
}
else if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
{
gimp_display_shell_set_stipple_style (cr,
&layer_group_fg,
&layer_group_bg);
}
else
{
gimp_display_shell_set_stipple_style (cr,
&layer_fg,
&layer_bg);
}
}
/* private functions */ /* private functions */

View File

@ -38,6 +38,9 @@ void gimp_display_shell_set_pen_style (GimpDisplayShell *shell,
GimpContext *context, GimpContext *context,
GimpActiveColor active, GimpActiveColor active,
gint width); gint width);
void gimp_display_shell_set_layer_style (GimpDisplayShell *shell,
cairo_t *cr,
GimpDrawable *drawable);
#endif /* __GIMP_DISPLAY_SHELL_STYLE_H__ */ #endif /* __GIMP_DISPLAY_SHELL_STYLE_H__ */