mirror of https://github.com/GNOME/gimp.git
added new functions color_region_mask() which works like color_region()
2003-09-27 Michael Natterer <mitch@gimp.org> * app/paint-funcs/paint-funcs.[ch]: added new functions color_region_mask() which works like color_region() but takes an additional maskPR parameters and pattern_region() which fills destPR with a TempBuf of *matching color depth*. * app/paint-funcs/paint-funcs-generic.h: added corresponding color_pixels_mask() and pattern_pixels(). * app/core/gimpimage.[ch] (gimp_image_transform_temp_buf): new function which transforms a TempBuf to a specified drawable's color space. * app/core/gimpdrawable-bucket-fill.c: the functions were factored out here. Removed them and use the new stuff. * app/core/core-enums.[ch]: added enum GimpStrokeStyle which can be one of { SOLID, PATTERN }. * app/core/gimpstrokeoptions.[ch]: added "GimpStrokeStyle style" property, cleanup. * app/core/gimpdrawable-stroke.c: honor the new "style" property and call the new color_region_mask() and pattern_region() functions accordingly, cleanup. * app/widgets/gimpstrokeeditor.c: added a GUI for the stroke style. Ugly but works. * app/gui/stroke-dialog.c: undefine "foreground" and "pattern" and set the user context as parent context so we get these properties from the global settings.
This commit is contained in:
parent
fcb29af719
commit
ab34b3ee94
34
ChangeLog
34
ChangeLog
|
@ -1,3 +1,37 @@
|
|||
2003-09-27 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* app/paint-funcs/paint-funcs.[ch]: added new functions
|
||||
color_region_mask() which works like color_region() but takes an
|
||||
additional maskPR parameters and pattern_region() which fills
|
||||
destPR with a TempBuf of *matching color depth*.
|
||||
|
||||
* app/paint-funcs/paint-funcs-generic.h: added corresponding
|
||||
color_pixels_mask() and pattern_pixels().
|
||||
|
||||
* app/core/gimpimage.[ch] (gimp_image_transform_temp_buf): new
|
||||
function which transforms a TempBuf to a specified drawable's
|
||||
color space.
|
||||
|
||||
* app/core/gimpdrawable-bucket-fill.c: the functions were factored
|
||||
out here. Removed them and use the new stuff.
|
||||
|
||||
* app/core/core-enums.[ch]: added enum GimpStrokeStyle which can
|
||||
be one of { SOLID, PATTERN }.
|
||||
|
||||
* app/core/gimpstrokeoptions.[ch]: added "GimpStrokeStyle style"
|
||||
property, cleanup.
|
||||
|
||||
* app/core/gimpdrawable-stroke.c: honor the new "style" property
|
||||
and call the new color_region_mask() and pattern_region()
|
||||
functions accordingly, cleanup.
|
||||
|
||||
* app/widgets/gimpstrokeeditor.c: added a GUI for the stroke
|
||||
style. Ugly but works.
|
||||
|
||||
* app/gui/stroke-dialog.c: undefine "foreground" and "pattern" and
|
||||
set the user context as parent context so we get these properties
|
||||
from the global settings.
|
||||
|
||||
2003-09-27 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* themes/Default/images/Makefile.am
|
||||
|
|
|
@ -254,6 +254,25 @@ gimp_grid_style_get_type (void)
|
|||
}
|
||||
|
||||
|
||||
static const GEnumValue gimp_stroke_style_enum_values[] =
|
||||
{
|
||||
{ GIMP_STROKE_STYLE_SOLID, N_("Solid"), "solid" },
|
||||
{ GIMP_STROKE_STYLE_PATTERN, N_("Pattern"), "pattern" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
GType
|
||||
gimp_stroke_style_get_type (void)
|
||||
{
|
||||
static GType enum_type = 0;
|
||||
|
||||
if (!enum_type)
|
||||
enum_type = g_enum_register_static ("GimpStrokeStyle", gimp_stroke_style_enum_values);
|
||||
|
||||
return enum_type;
|
||||
}
|
||||
|
||||
|
||||
static const GEnumValue gimp_join_style_enum_values[] =
|
||||
{
|
||||
{ GIMP_JOIN_MITER, N_("Miter"), "miter" },
|
||||
|
|
|
@ -195,6 +195,17 @@ typedef enum /*< pdb-skip >*/
|
|||
} GimpGridStyle;
|
||||
|
||||
|
||||
#define GIMP_TYPE_STROKE_STYLE (gimp_stroke_style_get_type ())
|
||||
|
||||
GType gimp_stroke_style_get_type (void) G_GNUC_CONST;
|
||||
|
||||
typedef enum /*< pdb-skip >*/
|
||||
{
|
||||
GIMP_STROKE_STYLE_SOLID, /*< desc="Solid" >*/
|
||||
GIMP_STROKE_STYLE_PATTERN /*< desc="Pattern" >*/
|
||||
} GimpStrokeStyle;
|
||||
|
||||
|
||||
#define GIMP_TYPE_JOIN_STYLE (gimp_join_style_get_type ())
|
||||
|
||||
GType gimp_join_style_get_type (void) G_GNUC_CONST;
|
||||
|
|
|
@ -44,32 +44,6 @@
|
|||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void gimp_drawable_bucket_fill_region (GimpBucketFillMode fill_mode,
|
||||
PixelRegion *bufPR,
|
||||
PixelRegion *maskPR,
|
||||
guchar *col,
|
||||
TempBuf *pattern,
|
||||
gint off_x,
|
||||
gint off_y,
|
||||
gboolean has_alpha);
|
||||
static void gimp_drawable_bucket_fill_line_color (guchar *buf,
|
||||
guchar *mask,
|
||||
guchar *col,
|
||||
gboolean has_alpha,
|
||||
gint bytes,
|
||||
gint width);
|
||||
static void gimp_drawable_bucket_fill_line_pattern (guchar *buf,
|
||||
guchar *mask,
|
||||
TempBuf *pattern,
|
||||
gboolean has_alpha,
|
||||
gint bytes,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
void
|
||||
|
@ -178,59 +152,8 @@ gimp_drawable_bucket_fill_full (GimpDrawable *drawable,
|
|||
}
|
||||
else if (fill_mode == GIMP_PATTERN_BUCKET_FILL)
|
||||
{
|
||||
/* If the pattern doesn't match the image in terms of color type,
|
||||
* transform it. (ie pattern is RGB, image is indexed)
|
||||
*/
|
||||
if (((pattern->mask->bytes == 3 || pattern->mask->bytes == 4 ) && ! gimp_drawable_is_rgb (drawable)) ||
|
||||
((pattern->mask->bytes == 1 || pattern->mask->bytes == 2 ) && ! gimp_drawable_is_gray (drawable)))
|
||||
{
|
||||
guchar *d1, *d2;
|
||||
gint size, in_bytes, out_bytes;
|
||||
|
||||
if ((pattern->mask->bytes == 2) && gimp_drawable_is_rgb (drawable))
|
||||
pat_buf = temp_buf_new (pattern->mask->width,
|
||||
pattern->mask->height,
|
||||
4, 0, 0, NULL);
|
||||
else if ((pattern->mask->bytes == 1) && gimp_drawable_is_rgb (drawable))
|
||||
pat_buf = temp_buf_new (pattern->mask->width,
|
||||
pattern->mask->height,
|
||||
3, 0, 0, NULL);
|
||||
else if ((pattern->mask->bytes == 4) && gimp_drawable_is_gray (drawable))
|
||||
pat_buf = temp_buf_new (pattern->mask->width,
|
||||
pattern->mask->height,
|
||||
2, 0, 0, NULL);
|
||||
else
|
||||
pat_buf = temp_buf_new (pattern->mask->width,
|
||||
pattern->mask->height,
|
||||
1, 0, 0, NULL);
|
||||
|
||||
d1 = temp_buf_data (pattern->mask);
|
||||
d2 = temp_buf_data (pat_buf);
|
||||
|
||||
size = pattern->mask->width * pattern->mask->height;
|
||||
in_bytes = pattern->mask->bytes;
|
||||
out_bytes = pat_buf->bytes;
|
||||
while (size--)
|
||||
{
|
||||
gimp_image_transform_color (gimage, drawable, d2,
|
||||
(in_bytes == 3 ||
|
||||
in_bytes == 4) ?
|
||||
GIMP_RGB : GIMP_GRAY, d1);
|
||||
/* Handle alpha */
|
||||
if (in_bytes == 4 ||
|
||||
in_bytes == 2 )
|
||||
d2[out_bytes - 1] = d1[in_bytes - 1];
|
||||
|
||||
d1 += in_bytes;
|
||||
d2 += out_bytes;
|
||||
}
|
||||
|
||||
new_buf = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pat_buf = pattern->mask;
|
||||
}
|
||||
pat_buf = gimp_image_transform_temp_buf (gimage, drawable,
|
||||
pattern->mask, &new_buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -244,8 +167,8 @@ gimp_drawable_bucket_fill_full (GimpDrawable *drawable,
|
|||
has_alpha = gimp_drawable_has_alpha (drawable);
|
||||
selection = gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
|
||||
|
||||
/* Do a seed bucket fill...To do this, calculate a new
|
||||
* contiguous region. If there is a selection, calculate the
|
||||
/* Do a seed bucket fill...To do this, calculate a new
|
||||
* contiguous region. If there is a selection, calculate the
|
||||
* intersection of this region with the existing selection.
|
||||
*/
|
||||
if (do_seed_fill)
|
||||
|
@ -289,7 +212,7 @@ gimp_drawable_bucket_fill_full (GimpDrawable *drawable,
|
|||
x2 = CLAMP (x2, off_x, (off_x + gimp_item_width (item)));
|
||||
y2 = CLAMP (y2, off_y, (off_y + gimp_item_height (item)));
|
||||
|
||||
pixel_region_init (&maskPR, gimp_drawable_data (GIMP_DRAWABLE (mask)),
|
||||
pixel_region_init (&maskPR, gimp_drawable_data (GIMP_DRAWABLE (mask)),
|
||||
x1, y1, (x2 - x1), (y2 - y1), TRUE);
|
||||
|
||||
/* translate mask bounds to drawable coords */
|
||||
|
@ -300,7 +223,7 @@ gimp_drawable_bucket_fill_full (GimpDrawable *drawable,
|
|||
}
|
||||
else
|
||||
{
|
||||
pixel_region_init (&maskPR, gimp_drawable_data (GIMP_DRAWABLE (mask)),
|
||||
pixel_region_init (&maskPR, gimp_drawable_data (GIMP_DRAWABLE (mask)),
|
||||
x1, y1, (x2 - x1), (y2 - y1), TRUE);
|
||||
}
|
||||
|
||||
|
@ -317,7 +240,7 @@ gimp_drawable_bucket_fill_full (GimpDrawable *drawable,
|
|||
else if (fill_mode == GIMP_PATTERN_BUCKET_FILL &&
|
||||
(pat_buf->bytes == 2 || pat_buf->bytes == 4))
|
||||
{
|
||||
/* If pattern being applied has an alpha channel,
|
||||
/* If pattern being applied has an alpha channel,
|
||||
* add one to the temp buffer from the image too.
|
||||
*/
|
||||
if (! has_alpha)
|
||||
|
@ -330,18 +253,20 @@ gimp_drawable_bucket_fill_full (GimpDrawable *drawable,
|
|||
buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), bytes);
|
||||
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
|
||||
|
||||
if (mask)
|
||||
gimp_drawable_bucket_fill_region (fill_mode,
|
||||
&bufPR, &maskPR,
|
||||
col, pat_buf,
|
||||
x1, y1,
|
||||
has_alpha);
|
||||
else
|
||||
gimp_drawable_bucket_fill_region (fill_mode,
|
||||
&bufPR, NULL,
|
||||
col, pat_buf,
|
||||
x1, y1,
|
||||
has_alpha);
|
||||
switch (fill_mode)
|
||||
{
|
||||
case GIMP_FG_BUCKET_FILL:
|
||||
case GIMP_BG_BUCKET_FILL:
|
||||
if (mask)
|
||||
color_region_mask (&bufPR, &maskPR, col);
|
||||
else
|
||||
color_region (&bufPR, col);
|
||||
break;
|
||||
|
||||
case GIMP_PATTERN_BUCKET_FILL:
|
||||
pattern_region (&bufPR, mask ? &maskPR : NULL, pat_buf, x1, y1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Apply it to the image */
|
||||
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), FALSE);
|
||||
|
@ -363,146 +288,3 @@ gimp_drawable_bucket_fill_full (GimpDrawable *drawable,
|
|||
|
||||
gimp_unset_busy (gimage->gimp);
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
gimp_drawable_bucket_fill_region (GimpBucketFillMode fill_mode,
|
||||
PixelRegion *bufPR,
|
||||
PixelRegion *maskPR,
|
||||
guchar *col,
|
||||
TempBuf *pattern,
|
||||
gint off_x,
|
||||
gint off_y,
|
||||
gboolean has_alpha)
|
||||
{
|
||||
guchar *s, *m;
|
||||
gint y;
|
||||
void *pr;
|
||||
|
||||
for (pr = pixel_regions_register (2, bufPR, maskPR);
|
||||
pr != NULL;
|
||||
pr = pixel_regions_process (pr))
|
||||
{
|
||||
s = bufPR->data;
|
||||
if (maskPR)
|
||||
m = maskPR->data;
|
||||
else
|
||||
m = NULL;
|
||||
|
||||
for (y = 0; y < bufPR->h; y++)
|
||||
{
|
||||
switch (fill_mode)
|
||||
{
|
||||
case GIMP_FG_BUCKET_FILL:
|
||||
case GIMP_BG_BUCKET_FILL:
|
||||
gimp_drawable_bucket_fill_line_color (s, m,
|
||||
col,
|
||||
has_alpha,
|
||||
bufPR->bytes, bufPR->w);
|
||||
break;
|
||||
case GIMP_PATTERN_BUCKET_FILL:
|
||||
gimp_drawable_bucket_fill_line_pattern (s, m,
|
||||
pattern,
|
||||
has_alpha,
|
||||
bufPR->bytes,
|
||||
off_x + bufPR->x,
|
||||
off_y + y + bufPR->y,
|
||||
bufPR->w);
|
||||
break;
|
||||
}
|
||||
s += bufPR->rowstride;
|
||||
|
||||
if (maskPR)
|
||||
m += maskPR->rowstride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_drawable_bucket_fill_line_color (guchar *buf,
|
||||
guchar *mask,
|
||||
guchar *col,
|
||||
gboolean has_alpha,
|
||||
gint bytes,
|
||||
gint width)
|
||||
{
|
||||
gint alpha, b;
|
||||
|
||||
alpha = (has_alpha) ? bytes - 1 : bytes;
|
||||
while (width--)
|
||||
{
|
||||
for (b = 0; b < alpha; b++)
|
||||
buf[b] = col[b];
|
||||
|
||||
if (has_alpha)
|
||||
{
|
||||
if (mask)
|
||||
buf[alpha] = *mask++;
|
||||
else
|
||||
buf[alpha] = OPAQUE_OPACITY;
|
||||
}
|
||||
|
||||
buf += bytes;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_drawable_bucket_fill_line_pattern (guchar *buf,
|
||||
guchar *mask,
|
||||
TempBuf *pattern,
|
||||
gboolean has_alpha,
|
||||
gint bytes,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width)
|
||||
{
|
||||
guchar *pat, *p;
|
||||
gint alpha, b;
|
||||
gint i;
|
||||
|
||||
/* Get a pointer to the appropriate scanline of the pattern buffer */
|
||||
pat = temp_buf_data (pattern) +
|
||||
(y % pattern->height) * pattern->width * pattern->bytes;
|
||||
|
||||
alpha = (has_alpha) ? bytes - 1 : bytes;
|
||||
/*
|
||||
* image data = pattern data for all but alpha
|
||||
*
|
||||
* If (image has alpha)
|
||||
* if (there's a mask)
|
||||
* image data = mask for alpha;
|
||||
* else
|
||||
* image data = opaque for alpha.
|
||||
*
|
||||
* if (pattern has alpha)
|
||||
* multiply existing alpha channel by pattern alpha
|
||||
* (normalised to (0..1))
|
||||
*/
|
||||
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
p = pat + ((i + x) % pattern->width) * pattern->bytes;
|
||||
|
||||
for (b = 0; b < alpha; b++)
|
||||
buf[b] = p[b];
|
||||
|
||||
if (has_alpha)
|
||||
{
|
||||
if (mask)
|
||||
buf[alpha] = *mask++;
|
||||
else
|
||||
buf[alpha] = OPAQUE_OPACITY;
|
||||
|
||||
if (pattern->bytes == 2 || pattern->bytes == 4)
|
||||
{
|
||||
buf[alpha] =
|
||||
(guchar)(buf[alpha] *
|
||||
(p[alpha]/(gdouble)OPAQUE_OPACITY));
|
||||
}
|
||||
}
|
||||
|
||||
buf += bytes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,20 +31,19 @@
|
|||
#include "base/temp-buf.h"
|
||||
#include "base/tile-manager.h"
|
||||
|
||||
#include "core/gimpitem.h"
|
||||
#include "core/gimpscanconvert.h"
|
||||
#include "core/gimpstrokeoptions.h"
|
||||
#include "core/gimpunit.h"
|
||||
|
||||
#include "vectors/gimpstroke.h"
|
||||
#include "vectors/gimpvectors.h"
|
||||
|
||||
#include "paint-funcs/paint-funcs.h"
|
||||
|
||||
#include "gimp.h"
|
||||
#include "gimpdrawable.h"
|
||||
#include "gimpdrawable-stroke.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimppattern.h"
|
||||
#include "gimpscanconvert.h"
|
||||
#include "gimpstrokeoptions.h"
|
||||
#include "gimpunit.h"
|
||||
|
||||
#include "vectors/gimpstroke.h"
|
||||
#include "vectors/gimpvectors.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
@ -58,8 +57,8 @@ gimp_drawable_stroke_vectors (GimpDrawable *drawable,
|
|||
{
|
||||
/* Stroke options */
|
||||
gdouble opacity;
|
||||
GimpRGB *color;
|
||||
GimpLayerModeEffects paint_mode;
|
||||
GimpStrokeStyle style;
|
||||
gdouble width;
|
||||
GimpJoinStyle join;
|
||||
GimpCapStyle cap;
|
||||
|
@ -69,33 +68,32 @@ gimp_drawable_stroke_vectors (GimpDrawable *drawable,
|
|||
gint num_coords = 0;
|
||||
GimpStroke *stroke;
|
||||
|
||||
GimpImage *gimage;
|
||||
GimpScanConvert *scan_convert;
|
||||
TileManager *base;
|
||||
TileManager *mask;
|
||||
gint x1, x2, y1, y2, bytes, w, h;
|
||||
guchar ucolor[4] = { 0, 0, 0, 255 };
|
||||
guchar bg[1] = { 0, };
|
||||
guchar *src_bytes;
|
||||
PixelRegion maskPR, basePR;
|
||||
|
||||
/* get the options from the GimpStrokeOptions */
|
||||
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
|
||||
g_return_if_fail (GIMP_IS_VECTORS (vectors));
|
||||
g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options));
|
||||
|
||||
g_object_get (options,
|
||||
"opacity", &opacity,
|
||||
"foreground", &color,
|
||||
"paint-mode", &paint_mode,
|
||||
|
||||
"style", &style,
|
||||
"width", &width,
|
||||
"join-style", &join,
|
||||
"cap-style", &cap,
|
||||
"antialias", &antialias,
|
||||
NULL);
|
||||
|
||||
|
||||
|
||||
gimage = gimp_item_get_image (GIMP_ITEM (drawable));
|
||||
|
||||
if (options->width_unit != GIMP_UNIT_PIXEL)
|
||||
{
|
||||
GimpImage *gimage = gimp_item_get_image (GIMP_ITEM (drawable));
|
||||
|
||||
width = (width *
|
||||
_gimp_unit_get_factor (gimage->gimp,
|
||||
options->width_unit) *
|
||||
|
@ -113,7 +111,8 @@ gimp_drawable_stroke_vectors (GimpDrawable *drawable,
|
|||
scan_convert = gimp_scan_convert_new (w, h, antialias);
|
||||
|
||||
/* For each Stroke in the vector, interpolate it, and add it to the
|
||||
* ScanConvert */
|
||||
* ScanConvert
|
||||
*/
|
||||
for (stroke = gimp_vectors_stroke_get_next (vectors, NULL);
|
||||
stroke;
|
||||
stroke = gimp_vectors_stroke_get_next (vectors, stroke))
|
||||
|
@ -124,7 +123,8 @@ gimp_drawable_stroke_vectors (GimpDrawable *drawable,
|
|||
gint i;
|
||||
|
||||
/* Get the interpolated version of this stroke, and add it to our
|
||||
* scanconvert. */
|
||||
* scanconvert.
|
||||
*/
|
||||
coords = gimp_stroke_interpolate (stroke, 1, &closed);
|
||||
|
||||
if (coords && coords->len)
|
||||
|
@ -160,7 +160,8 @@ gimp_drawable_stroke_vectors (GimpDrawable *drawable,
|
|||
0.0, dash_array);
|
||||
|
||||
/* fill a 1-bpp Tilemanager with black, this will describe the shape
|
||||
* of the stroke. */
|
||||
* of the stroke.
|
||||
*/
|
||||
mask = tile_manager_new (w, h, 1);
|
||||
tile_manager_set_offsets (mask, x1+x2, y1+y2);
|
||||
pixel_region_init (&maskPR, mask, 0, 0, w, h, TRUE);
|
||||
|
@ -175,26 +176,53 @@ gimp_drawable_stroke_vectors (GimpDrawable *drawable,
|
|||
if (!gimp_drawable_has_alpha (drawable))
|
||||
bytes++;
|
||||
|
||||
src_bytes = g_malloc0 (bytes);
|
||||
|
||||
/* Fill a TileManager with the stroke color */
|
||||
gimp_rgb_get_uchar (color, ucolor + 0, ucolor + 1, ucolor + 2);
|
||||
|
||||
g_free (color);
|
||||
|
||||
src_bytes[bytes - 1] = OPAQUE_OPACITY;
|
||||
gimp_image_transform_color (GIMP_ITEM (drawable)->gimage, drawable,
|
||||
src_bytes, GIMP_RGB, ucolor);
|
||||
base = tile_manager_new (w, h, bytes);
|
||||
tile_manager_set_offsets (base, x1+x2, y1+y2);
|
||||
pixel_region_init (&basePR, base, 0, 0, w, h, TRUE);
|
||||
color_region (&basePR, src_bytes);
|
||||
g_free (src_bytes);
|
||||
|
||||
/* combine mask and stroke color TileManager */
|
||||
tile_manager_set_offsets (base, x1 + x2, y1 + y2);
|
||||
pixel_region_init (&basePR, base, 0, 0, w, h, TRUE);
|
||||
pixel_region_init (&maskPR, mask, 0, 0, w, h, FALSE);
|
||||
apply_mask_to_region (&basePR, &maskPR, OPAQUE_OPACITY);
|
||||
|
||||
switch (style)
|
||||
{
|
||||
case GIMP_STROKE_STYLE_SOLID:
|
||||
{
|
||||
GimpRGB *color;
|
||||
guchar ucolor[4] = { 0, 0, 0, OPAQUE_OPACITY };
|
||||
guchar *src_bytes;
|
||||
|
||||
g_object_get (options, "foreground", &color, NULL);
|
||||
gimp_rgb_get_uchar (color, ucolor + 0, ucolor + 1, ucolor + 2);
|
||||
g_free (color);
|
||||
|
||||
src_bytes = g_malloc0 (bytes);
|
||||
|
||||
src_bytes[bytes - 1] = OPAQUE_OPACITY;
|
||||
gimp_image_transform_color (GIMP_ITEM (drawable)->gimage, drawable,
|
||||
src_bytes, GIMP_RGB, ucolor);
|
||||
|
||||
color_region_mask (&basePR, &maskPR, src_bytes);
|
||||
|
||||
g_free (src_bytes);
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_STROKE_STYLE_PATTERN:
|
||||
{
|
||||
GimpPattern *pattern;
|
||||
TempBuf *pat_buf;
|
||||
gboolean new_buf;
|
||||
|
||||
g_object_get (options, "pattern", &pattern, NULL);
|
||||
pat_buf = gimp_image_transform_temp_buf (gimage, drawable,
|
||||
pattern->mask, &new_buf);
|
||||
g_object_unref (pattern);
|
||||
|
||||
pattern_region (&basePR, &maskPR, pat_buf, x1, y1);
|
||||
|
||||
if (new_buf)
|
||||
temp_buf_free (pat_buf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Apply to drawable */
|
||||
pixel_region_init (&basePR, base, 0, 0, w, h, FALSE);
|
||||
|
|
|
@ -1762,6 +1762,88 @@ gimp_image_transform_color (const GimpImage *dest_gimage,
|
|||
}
|
||||
}
|
||||
|
||||
TempBuf *
|
||||
gimp_image_transform_temp_buf (const GimpImage *dest_image,
|
||||
const GimpDrawable *dest_drawable,
|
||||
TempBuf *temp_buf,
|
||||
gboolean *new_buf)
|
||||
{
|
||||
TempBuf *ret_buf;
|
||||
|
||||
g_return_val_if_fail (GIMP_IMAGE (dest_image), NULL);
|
||||
g_return_val_if_fail (GIMP_DRAWABLE (dest_drawable), NULL);
|
||||
g_return_val_if_fail (temp_buf != NULL, NULL);
|
||||
g_return_val_if_fail (new_buf != NULL, NULL);
|
||||
|
||||
/* If the pattern doesn't match the image in terms of color type,
|
||||
* transform it. (ie pattern is RGB, image is indexed)
|
||||
*/
|
||||
if (((temp_buf->bytes == 3 || temp_buf->bytes == 4) &&
|
||||
! gimp_drawable_is_rgb (dest_drawable)) ||
|
||||
((temp_buf->bytes == 1 || temp_buf->bytes == 2) &&
|
||||
! gimp_drawable_is_gray (dest_drawable)))
|
||||
{
|
||||
guchar *d1, *d2;
|
||||
gint size, in_bytes, out_bytes;
|
||||
|
||||
if (temp_buf->bytes == 2 && gimp_drawable_is_rgb (dest_drawable))
|
||||
{
|
||||
ret_buf = temp_buf_new (temp_buf->width,
|
||||
temp_buf->height,
|
||||
4, 0, 0, NULL);
|
||||
}
|
||||
else if (temp_buf->bytes == 1 && gimp_drawable_is_rgb (dest_drawable))
|
||||
{
|
||||
ret_buf = temp_buf_new (temp_buf->width,
|
||||
temp_buf->height,
|
||||
3, 0, 0, NULL);
|
||||
}
|
||||
else if (temp_buf->bytes == 4 && gimp_drawable_is_gray (dest_drawable))
|
||||
{
|
||||
ret_buf = temp_buf_new (temp_buf->width,
|
||||
temp_buf->height,
|
||||
2, 0, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_buf = temp_buf_new (temp_buf->width,
|
||||
temp_buf->height,
|
||||
1, 0, 0, NULL);
|
||||
}
|
||||
|
||||
d1 = temp_buf_data (temp_buf);
|
||||
d2 = temp_buf_data (ret_buf);
|
||||
|
||||
size = temp_buf->width * temp_buf->height;
|
||||
|
||||
in_bytes = temp_buf->bytes;
|
||||
out_bytes = ret_buf->bytes;
|
||||
|
||||
while (size--)
|
||||
{
|
||||
gimp_image_transform_color (dest_image, dest_drawable, d2,
|
||||
(in_bytes == 3 || in_bytes == 4) ?
|
||||
GIMP_RGB : GIMP_GRAY, d1);
|
||||
|
||||
/* Handle alpha */
|
||||
if (in_bytes == 4 || in_bytes == 2 )
|
||||
d2[out_bytes - 1] = d1[in_bytes - 1];
|
||||
|
||||
d1 += in_bytes;
|
||||
d2 += out_bytes;
|
||||
}
|
||||
|
||||
*new_buf = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_buf = temp_buf;
|
||||
*new_buf = FALSE;
|
||||
}
|
||||
|
||||
return ret_buf;
|
||||
}
|
||||
|
||||
|
||||
/* shadow tiles */
|
||||
|
||||
|
|
|
@ -331,6 +331,10 @@ void gimp_image_transform_color (const GimpImage *dest_gimag
|
|||
guchar *dest,
|
||||
GimpImageBaseType src_type,
|
||||
const guchar *src);
|
||||
TempBuf * gimp_image_transform_temp_buf (const GimpImage *dest_gimage,
|
||||
const GimpDrawable *dest_drawable,
|
||||
TempBuf *temp_buf,
|
||||
gboolean *new_buf);
|
||||
|
||||
|
||||
/* shadow tiles */
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_STYLE,
|
||||
PROP_WIDTH,
|
||||
PROP_WIDTH_UNIT,
|
||||
PROP_CAP_STYLE,
|
||||
|
@ -46,7 +47,7 @@ enum
|
|||
};
|
||||
|
||||
|
||||
static void gimp_stroke_options_class_init (GimpStrokeOptionsClass *options_class);
|
||||
static void gimp_stroke_options_class_init (GimpStrokeOptionsClass *klass);
|
||||
|
||||
static void gimp_stroke_options_set_property (GObject *object,
|
||||
guint property_id,
|
||||
|
@ -102,6 +103,11 @@ gimp_stroke_options_class_init (GimpStrokeOptionsClass *klass)
|
|||
object_class->set_property = gimp_stroke_options_set_property;
|
||||
object_class->get_property = gimp_stroke_options_get_property;
|
||||
|
||||
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_STYLE,
|
||||
"style", NULL,
|
||||
GIMP_TYPE_STROKE_STYLE,
|
||||
GIMP_STROKE_STYLE_SOLID,
|
||||
0);
|
||||
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_WIDTH,
|
||||
"width", NULL,
|
||||
0.0, 2000.0, 5.0,
|
||||
|
@ -151,16 +157,13 @@ gimp_stroke_options_set_property (GObject *object,
|
|||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpStrokeOptions *options;
|
||||
GValueArray *val_array;
|
||||
GValue *item;
|
||||
gint i;
|
||||
gdouble val;
|
||||
|
||||
options = GIMP_STROKE_OPTIONS (object);
|
||||
GimpStrokeOptions *options = GIMP_STROKE_OPTIONS (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_STYLE:
|
||||
options->style = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_WIDTH:
|
||||
options->width = g_value_get_double (value);
|
||||
break;
|
||||
|
@ -186,32 +189,39 @@ gimp_stroke_options_set_property (GObject *object,
|
|||
options->dash_offset = g_value_get_double (value);
|
||||
break;
|
||||
case PROP_DASH_INFO:
|
||||
if (options->dash_info)
|
||||
g_array_free (options->dash_info, TRUE);
|
||||
{
|
||||
GValueArray *val_array;
|
||||
GValue *item;
|
||||
gint i;
|
||||
gdouble val;
|
||||
|
||||
val_array = g_value_get_boxed (value);
|
||||
if (val_array == NULL || val_array->n_values == 0)
|
||||
{
|
||||
options->dash_info = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
options->dash_info = g_array_sized_new (FALSE, FALSE,
|
||||
sizeof (gdouble),
|
||||
val_array->n_values);
|
||||
if (options->dash_info)
|
||||
g_array_free (options->dash_info, TRUE);
|
||||
|
||||
val_array = g_value_get_boxed (value);
|
||||
if (val_array == NULL || val_array->n_values == 0)
|
||||
{
|
||||
options->dash_info = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
options->dash_info = g_array_sized_new (FALSE, FALSE,
|
||||
sizeof (gdouble),
|
||||
val_array->n_values);
|
||||
|
||||
for (i=0; i < val_array->n_values; i++)
|
||||
{
|
||||
item = g_value_array_get_nth (val_array, i);
|
||||
for (i=0; i < val_array->n_values; i++)
|
||||
{
|
||||
item = g_value_array_get_nth (val_array, i);
|
||||
|
||||
g_return_if_fail (G_VALUE_HOLDS_DOUBLE (item));
|
||||
g_return_if_fail (G_VALUE_HOLDS_DOUBLE (item));
|
||||
|
||||
val = g_value_get_double (item);
|
||||
val = g_value_get_double (item);
|
||||
|
||||
options->dash_info = g_array_append_val (options->dash_info, val);
|
||||
}
|
||||
}
|
||||
options->dash_info = g_array_append_val (options->dash_info,
|
||||
val);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -226,15 +236,13 @@ gimp_stroke_options_get_property (GObject *object,
|
|||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpStrokeOptions *options;
|
||||
GValueArray *val_array;
|
||||
GValue item;
|
||||
gint i;
|
||||
|
||||
options = GIMP_STROKE_OPTIONS (object);
|
||||
GimpStrokeOptions *options = GIMP_STROKE_OPTIONS (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_STYLE:
|
||||
g_value_set_enum (value, options->style);
|
||||
break;
|
||||
case PROP_WIDTH:
|
||||
g_value_set_double (value, options->width);
|
||||
break;
|
||||
|
@ -260,27 +268,34 @@ gimp_stroke_options_get_property (GObject *object,
|
|||
g_value_set_double (value, options->dash_offset);
|
||||
break;
|
||||
case PROP_DASH_INFO:
|
||||
if (options->dash_info)
|
||||
g_array_free (options->dash_info, TRUE);
|
||||
{
|
||||
GValueArray *val_array;
|
||||
GValue item;
|
||||
gint i;
|
||||
|
||||
if (options->dash_info == NULL || options->dash_info->len == 0)
|
||||
{
|
||||
g_value_set_boxed (value, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
val_array = g_value_array_new (options->dash_info->len);
|
||||
if (options->dash_info)
|
||||
g_array_free (options->dash_info, TRUE);
|
||||
|
||||
for (i=0; i < options->dash_info->len; i++)
|
||||
{
|
||||
g_value_set_double (&item, g_array_index (options->dash_info,
|
||||
gdouble,
|
||||
i));
|
||||
if (options->dash_info == NULL || options->dash_info->len == 0)
|
||||
{
|
||||
g_value_set_boxed (value, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
val_array = g_value_array_new (options->dash_info->len);
|
||||
|
||||
g_value_array_append (val_array, &item);
|
||||
}
|
||||
g_value_set_boxed (value, val_array);
|
||||
}
|
||||
for (i=0; i < options->dash_info->len; i++)
|
||||
{
|
||||
g_value_set_double (&item, g_array_index (options->dash_info,
|
||||
gdouble,
|
||||
i));
|
||||
|
||||
g_value_array_append (val_array, &item);
|
||||
}
|
||||
|
||||
g_value_set_boxed (value, val_array);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -288,6 +303,3 @@ gimp_stroke_options_get_property (GObject *object,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -38,21 +38,23 @@ typedef struct _GimpStrokeOptionsClass GimpStrokeOptionsClass;
|
|||
|
||||
struct _GimpStrokeOptions
|
||||
{
|
||||
GimpContext parent_instance;
|
||||
GimpContext parent_instance;
|
||||
|
||||
gdouble width;
|
||||
GimpUnit width_unit;
|
||||
GimpStrokeStyle style;
|
||||
|
||||
GimpCapStyle cap_style;
|
||||
GimpJoinStyle join_style;
|
||||
gdouble width;
|
||||
GimpUnit width_unit;
|
||||
|
||||
gdouble miter;
|
||||
GimpCapStyle cap_style;
|
||||
GimpJoinStyle join_style;
|
||||
|
||||
gboolean antialias;
|
||||
gdouble miter;
|
||||
|
||||
GimpUnit dash_unit;
|
||||
gdouble dash_offset;
|
||||
GArray *dash_info;
|
||||
gboolean antialias;
|
||||
|
||||
GimpUnit dash_unit;
|
||||
gdouble dash_offset;
|
||||
GArray *dash_info;
|
||||
};
|
||||
|
||||
struct _GimpStrokeOptionsClass
|
||||
|
@ -61,6 +63,7 @@ struct _GimpStrokeOptionsClass
|
|||
};
|
||||
|
||||
|
||||
GType gimp_stroke_options_get_type (void) G_GNUC_CONST;
|
||||
GType gimp_stroke_options_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
#endif /* __GIMP_STROKE_OPTIONS_H__ */
|
||||
|
|
|
@ -81,6 +81,13 @@ stroke_dialog_new (GimpItem *item,
|
|||
"gimp", image->gimp,
|
||||
NULL);
|
||||
|
||||
gimp_context_set_parent (GIMP_CONTEXT (options),
|
||||
gimp_get_user_context (image->gimp));
|
||||
gimp_context_define_properties (GIMP_CONTEXT (options),
|
||||
GIMP_CONTEXT_FOREGROUND_MASK |
|
||||
GIMP_CONTEXT_PATTERN_MASK,
|
||||
FALSE);
|
||||
|
||||
/* the dialog */
|
||||
dialog =
|
||||
gimp_viewable_dialog_new (GIMP_VIEWABLE (item),
|
||||
|
|
|
@ -81,6 +81,13 @@ stroke_dialog_new (GimpItem *item,
|
|||
"gimp", image->gimp,
|
||||
NULL);
|
||||
|
||||
gimp_context_set_parent (GIMP_CONTEXT (options),
|
||||
gimp_get_user_context (image->gimp));
|
||||
gimp_context_define_properties (GIMP_CONTEXT (options),
|
||||
GIMP_CONTEXT_FOREGROUND_MASK |
|
||||
GIMP_CONTEXT_PATTERN_MASK,
|
||||
FALSE);
|
||||
|
||||
/* the dialog */
|
||||
dialog =
|
||||
gimp_viewable_dialog_new (GIMP_VIEWABLE (item),
|
||||
|
|
|
@ -164,6 +164,118 @@ color_pixels (guchar *dest,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
color_pixels_mask (guchar *dest,
|
||||
guchar *mask,
|
||||
const guchar *color,
|
||||
guint w,
|
||||
guint bytes)
|
||||
{
|
||||
guchar c0, c1, c2;
|
||||
gint alpha;
|
||||
|
||||
alpha = HAS_ALPHA (bytes) ? bytes - 1 : bytes;
|
||||
|
||||
switch (bytes)
|
||||
{
|
||||
case 1:
|
||||
memset (dest, *color, w);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
c0 = color[0];
|
||||
while (w--)
|
||||
{
|
||||
dest[0] = c0;
|
||||
dest[1] = *mask++;
|
||||
dest += 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
c0 = color[0];
|
||||
c1 = color[1];
|
||||
c2 = color[2];
|
||||
while (w--)
|
||||
{
|
||||
dest[0] = c0;
|
||||
dest[1] = c1;
|
||||
dest[2] = c2;
|
||||
dest += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
c0 = color[0];
|
||||
c1 = color[1];
|
||||
c2 = color[2];
|
||||
while (w--)
|
||||
{
|
||||
dest[0] = c0;
|
||||
dest[1] = c1;
|
||||
dest[2] = c2;
|
||||
dest[3] = *mask++;
|
||||
dest += 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pattern_pixels_mask (guchar *dest,
|
||||
guchar *mask,
|
||||
TempBuf *pattern,
|
||||
guint w,
|
||||
guint bytes,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
guchar *pat, *p;
|
||||
gint alpha, b;
|
||||
gint i;
|
||||
|
||||
/* Get a pointer to the appropriate scanline of the pattern buffer */
|
||||
pat = (temp_buf_data (pattern) +
|
||||
(y % pattern->height) * pattern->width * pattern->bytes);
|
||||
|
||||
alpha = HAS_ALPHA (bytes) ? bytes - 1 : bytes;
|
||||
|
||||
/*
|
||||
* image data = pattern data for all but alpha
|
||||
*
|
||||
* If (image has alpha)
|
||||
* if (there's a mask)
|
||||
* image data = mask for alpha;
|
||||
* else
|
||||
* image data = opaque for alpha.
|
||||
*
|
||||
* if (pattern has alpha)
|
||||
* multiply existing alpha channel by pattern alpha
|
||||
* (normalised to (0..1))
|
||||
*/
|
||||
|
||||
for (i = 0; i < w; i++)
|
||||
{
|
||||
p = pat + ((i + x) % pattern->width) * pattern->bytes;
|
||||
|
||||
for (b = 0; b < alpha; b++)
|
||||
dest[b] = p[b];
|
||||
|
||||
if (HAS_ALPHA (bytes))
|
||||
{
|
||||
if (mask)
|
||||
dest[alpha] = *mask++;
|
||||
else
|
||||
dest[alpha] = OPAQUE_OPACITY;
|
||||
|
||||
if (HAS_ALPHA (pattern->bytes))
|
||||
dest[alpha] = (guchar) (dest[alpha] *
|
||||
p[alpha] / (gdouble) OPAQUE_OPACITY);
|
||||
}
|
||||
|
||||
dest += bytes;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
blend_pixels (const guchar *src1,
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "base/pixel-processor.h"
|
||||
#include "base/pixel-region.h"
|
||||
#include "base/temp-buf.h"
|
||||
#include "base/tile-manager.h"
|
||||
#include "base/tile.h"
|
||||
|
||||
|
@ -2017,24 +2018,97 @@ color_region (PixelRegion *dest,
|
|||
h = dest->h;
|
||||
s = dest->data;
|
||||
|
||||
if (dest->w*dest->bytes == dest->rowstride)
|
||||
if (dest->w * dest->bytes == dest->rowstride)
|
||||
{
|
||||
/* do it all in one function call if we can */
|
||||
/* this hasn't been tested to see if it is a
|
||||
signifigant speed gain yet */
|
||||
color_pixels (s, col, dest->w*h, dest->bytes);
|
||||
/* do it all in one function call if we can
|
||||
* this hasn't been tested to see if it is a
|
||||
* signifigant speed gain yet
|
||||
*/
|
||||
color_pixels (s, col, dest->w * h, dest->bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (h--)
|
||||
{
|
||||
color_pixels (s, col, dest->w, dest->bytes);
|
||||
color_pixels (s, col, dest->w, dest->bytes);
|
||||
s += dest->rowstride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
color_region_mask (PixelRegion *dest,
|
||||
PixelRegion *mask,
|
||||
const guchar *col)
|
||||
{
|
||||
gint h;
|
||||
guchar *d;
|
||||
guchar *m;
|
||||
void *pr;
|
||||
|
||||
for (pr = pixel_regions_register (2, dest, mask);
|
||||
pr != NULL;
|
||||
pr = pixel_regions_process (pr))
|
||||
{
|
||||
h = dest->h;
|
||||
d = dest->data;
|
||||
m = mask->data;
|
||||
|
||||
if (dest->w * dest->bytes == dest->rowstride &&
|
||||
mask->w * mask->bytes == mask->rowstride)
|
||||
{
|
||||
/* do it all in one function call if we can
|
||||
* this hasn't been tested to see if it is a
|
||||
* signifigant speed gain yet
|
||||
*/
|
||||
color_pixels_mask (d, m, col, dest->w * h, dest->bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (h--)
|
||||
{
|
||||
color_pixels_mask (d, m, col, dest->w, dest->bytes);
|
||||
d += dest->rowstride;
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pattern_region (PixelRegion *dest,
|
||||
PixelRegion *mask,
|
||||
TempBuf *pattern,
|
||||
gint off_x,
|
||||
gint off_y)
|
||||
{
|
||||
gint y;
|
||||
guchar *d;
|
||||
guchar *m = NULL;
|
||||
void *pr;
|
||||
|
||||
for (pr = pixel_regions_register (2, dest, mask);
|
||||
pr != NULL;
|
||||
pr = pixel_regions_process (pr))
|
||||
{
|
||||
d = dest->data;
|
||||
|
||||
if (mask)
|
||||
m = mask->data;
|
||||
|
||||
for (y = 0; y < dest->h; y++)
|
||||
{
|
||||
pattern_pixels_mask (d, m, pattern, dest->w, dest->bytes,
|
||||
off_x + dest->x,
|
||||
off_y + dest->y + y);
|
||||
d += dest->rowstride;
|
||||
|
||||
if (mask)
|
||||
m += mask->rowstride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
blend_region (PixelRegion *src1,
|
||||
|
@ -3846,7 +3920,7 @@ border_region (PixelRegion *src,
|
|||
{
|
||||
guchar color[] = "\0\0\0\0";
|
||||
|
||||
color_region(src, color);
|
||||
color_region (src, color);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -268,9 +268,17 @@ void extract_from_indexed_pixels (guchar *src,
|
|||
|
||||
|
||||
/* Region functions */
|
||||
void color_region (PixelRegion *dest,
|
||||
void color_region (PixelRegion *dest,
|
||||
const guchar *color);
|
||||
void color_region_mask (PixelRegion *dest,
|
||||
PixelRegion *mask,
|
||||
const guchar *color);
|
||||
|
||||
void pattern_region (PixelRegion *dest,
|
||||
PixelRegion *mask,
|
||||
TempBuf *pattern,
|
||||
gint off_x,
|
||||
gint off_y);
|
||||
|
||||
void blend_region (PixelRegion *, PixelRegion *,
|
||||
PixelRegion *, int);
|
||||
|
|
|
@ -167,12 +167,20 @@ gimp_stroke_editor_constructor (GType type,
|
|||
|
||||
g_assert (editor->options != NULL);
|
||||
|
||||
table = gtk_table_new (4, 3, FALSE);
|
||||
table = gtk_table_new (5, 3, FALSE);
|
||||
gtk_table_set_col_spacings (GTK_TABLE (table), 2);
|
||||
gtk_table_set_row_spacings (GTK_TABLE (table), 4);
|
||||
gtk_box_pack_start (GTK_BOX (editor), table, FALSE, FALSE, 0);
|
||||
gtk_widget_show (table);
|
||||
|
||||
box = gimp_prop_enum_radio_frame_new (G_OBJECT (editor->options), "style",
|
||||
_("Style"), 0, 0);
|
||||
gtk_table_attach (GTK_TABLE (table), box, 0, 3, row, row + 1,
|
||||
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
|
||||
gtk_widget_show (box);
|
||||
|
||||
row++;
|
||||
|
||||
digits = gimp_unit_get_digits (editor->options->width_unit);
|
||||
spinbutton = gimp_prop_spin_button_new (G_OBJECT (editor->options), "width",
|
||||
1.0, 10.0, digits);
|
||||
|
|
Loading…
Reference in New Issue