/* ============================================================================ * gap_image_delete_immediate * delete image (with workaround to ensure that most of the * allocatd memory is freed) * ============================================================================ * The workaround disables undo and scales the image down to miniumum size * before calling the gimp_image_delete procedure. * this way memory resources for big layers will be freed up immediate. */ void gap_image_delete_immediate (gint32 image_id) { gboolean imageDeleteWorkaroundDefault = TRUE; if(gap_base_get_gimprc_gboolean_value("gap-image-delete-workaround" , imageDeleteWorkaroundDefault)) { if(gap_debug) { printf("gap_image_delete_immediate: SCALED down to 2x2 id = %d (workaround for gimp_image-delete problem)\n" , (int)image_id ); } gimp_image_undo_disable(image_id); //gimp_image_scale_full(image_id, 2, 2, 0 /*INTERPOLATION_NONE*/); gimp_context_push(); gimp_context_set_interpolation(0); gimp_image_scale(image_id, 2, 2); gimp_context_pop(); gimp_image_undo_enable(image_id); /* clear undo stack */ } gimp_image_delete(image_id); } /* end gap_image_delete_immediate */
static PyObject * vectors_to_selection(PyGimpVectors *self, PyObject *args, PyObject *kwargs) { GimpChannelOps operation = GIMP_CHANNEL_OP_REPLACE; gboolean antialias = TRUE, feather = FALSE; double feather_radius_x = 0.0, feather_radius_y = 0.0; static char *kwlist[] = { "operation", "antialias", "feather", "feather_radius_x", "feather_radius_y", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiidd:to_selection", kwlist, &operation, &antialias, &feather, &feather_radius_x, &feather_radius_y)) return NULL; gimp_context_push(); gimp_context_set_antialias(antialias); gimp_context_set_feather(feather); gimp_context_set_feather_radius(feather_radius_x, feather_radius_y); gimp_image_select_item(gimp_item_get_image(self->ID), operation, self->ID); gimp_context_pop(); Py_INCREF(Py_None); return Py_None; }
void render (gint32 image_ID, GimpDrawable *drawable, PlugInVals *vals, PlugInImageVals *image_vals, PlugInDrawableVals *drawable_vals) { double angle = gimp_find_skew(drawable); // in radians DEBUGPRINT("deskew: angle=%.2f\n", 57.295779513082320876798154814105*angle); if (fabs(angle) < deskew_threshold) { // nothing to do; already straightened. return; } gimp_context_push (); gimp_context_set_interpolation (GIMP_INTERPOLATION_CUBIC); gimp_context_set_transform_resize (GIMP_TRANSFORM_RESIZE_ADJUST); drawable->drawable_id = gimp_item_transform_rotate(drawable->drawable_id, angle, TRUE, // auto_center -1, -1 // center_x, center_y ); gimp_context_pop (); }
static void d_paint_rectangle (GfigObject *obj) { DobjPoints *first_pnt; DobjPoints *second_pnt; gdouble dpnts[4]; g_assert (obj != NULL); /* Drawing rectangles is hard . * 1) select rectangle * 2) stroke it */ first_pnt = obj->points; if (!first_pnt) return; /* End-of-line */ second_pnt = first_pnt->next; if (!second_pnt) { g_error ("Internal error - rectangle no second pnt"); } dpnts[0] = (gdouble) MIN (first_pnt->pnt.x, second_pnt->pnt.x); dpnts[1] = (gdouble) MIN (first_pnt->pnt.y, second_pnt->pnt.y); dpnts[2] = (gdouble) MAX (first_pnt->pnt.x, second_pnt->pnt.x); dpnts[3] = (gdouble) MAX (first_pnt->pnt.y, second_pnt->pnt.y); /* Scale before drawing */ if (selvals.scaletoimage) scale_to_original_xy (&dpnts[0], 2); else scale_to_xy (&dpnts[0], 2); gimp_context_push (); gimp_context_set_feather (selopt.feather); gimp_context_set_feather_radius (selopt.feather_radius, selopt.feather_radius); gimp_image_select_rectangle (gfig_context->image_id, selopt.type, dpnts[0], dpnts[1], dpnts[2] - dpnts[0], dpnts[3] - dpnts[1]); gimp_context_pop (); paint_layer_fill (dpnts[0], dpnts[1], dpnts[2], dpnts[3]); if (obj->style.paint_type == PAINT_BRUSH_TYPE) gimp_edit_stroke (gfig_context->drawable_id); }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; gint32 drawable_id; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; gint pwidth, pheight; INIT_I18N (); gfig_context = g_new0 (GFigContext, 1); gfig_context->show_background = TRUE; gfig_context->selected_obj = NULL; drawable_id = param[2].data.d_drawable; run_mode = param[0].data.d_int32; gfig_context->image_id = param[1].data.d_image; gfig_context->drawable_id = drawable_id; *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; gimp_image_undo_group_start (gfig_context->image_id); gimp_context_push (); /* TMP Hack - clear any selections */ if (! gimp_selection_is_empty (gfig_context->image_id)) gimp_selection_none (gfig_context->image_id); gimp_drawable_mask_bounds (drawable_id, &sel_x1, &sel_y1, &sel_x2, &sel_y2); sel_width = sel_x2 - sel_x1; sel_height = sel_y2 - sel_y1; /* Calculate preview size */ if (sel_width > sel_height) { pwidth = MIN (sel_width, PREVIEW_SIZE); pheight = sel_height * pwidth / sel_width; } else { pheight = MIN (sel_height, PREVIEW_SIZE); pwidth = sel_width * pheight / sel_height; } preview_width = MAX (pwidth, 2); /* Min size is 2 */ preview_height = MAX (pheight, 2); org_scale_x_factor = scale_x_factor = (gdouble) sel_width / (gdouble) preview_width; org_scale_y_factor = scale_y_factor = (gdouble) sel_height / (gdouble) preview_height; /* initialize */ gfig_init_object_classes (); switch (run_mode) { case GIMP_RUN_INTERACTIVE: case GIMP_RUN_WITH_LAST_VALS: /*gimp_get_data (PLUG_IN_PROC, &selvals);*/ if (! gfig_dialog ()) { gimp_image_undo_group_end (gfig_context->image_id); return; } break; case GIMP_RUN_NONINTERACTIVE: status = GIMP_PDB_CALLING_ERROR; break; default: break; } gimp_context_pop (); gimp_image_undo_group_end (gfig_context->image_id); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); else #if 0 if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &selvals, sizeof (SelectItVals)); else #endif /* 0 */ { status = GIMP_PDB_EXECUTION_ERROR; } values[0].data.d_status = status; }
static void run ( const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[3]; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; SeparateContext mysc; //enum separate_function func = SEP_NONE; run_mode = param[0].data.d_int32; /* setup for localization */ INIT_I18N (); cmsErrorAction( LCMS_ERROR_IGNORE ); mysc.filename = NULL; if( nparams != ( run_mode == GIMP_RUN_NONINTERACTIVE ? 2 : 1 ) ) status = GIMP_PDB_CALLING_ERROR; else if( run_mode == GIMP_RUN_NONINTERACTIVE ) { if( param[1].type != GIMP_PDB_STRING || strlen( param[1].data.d_string ) == 0 ) status = GIMP_PDB_CALLING_ERROR; else mysc.filename = g_strdup( param[1].data.d_string ); } else { gint size = gimp_get_data_size( "plug-in-separate-import/lastpath" ); if( size ) { mysc.filename = g_malloc( size ); gimp_get_data( "plug-in-separate-import/lastpath", mysc.filename ); } } if( status == GIMP_PDB_SUCCESS && ( run_mode == GIMP_RUN_NONINTERACTIVE || separate_import_dialog( &mysc ) ) ) { gint i, j, x, y; TIFF *in; guint32 width, height, stripSize, stripCount, stripHeight; gint16 bps, spp, step, planerConfig, photometric, inkset, resolutionUnit; float xres, yres; const gchar *layerNames[] = { "C", "M", "Y", "K" }; guchar *buf, *maskbuf[4], *srcbuf, *destbuf[4], *iccProfile; gint32 layers[5], masks[4]; GimpDrawable *drw[4]; GimpPixelRgn rgn[4]; GimpRGB primaries[4] = { { .180, .541, .870, 1.0 }, { .925, .149, .388, 1.0 }, { .929, .862, .129, 1.0 }, { 0, 0, 0, 1.0 } }; gchar *str = NULL; gchar *baseName = g_path_get_basename( gimp_filename_to_utf8( mysc.filename ) ); #ifdef G_OS_WIN32 { gchar *_filename = NULL; // win32 filename encoding(not UTF-8) _filename = g_win32_locale_filename_from_utf8( mysc.filename ); in = TIFFOpen( _filename ? _filename : mysc.filename, "r" ); g_free( _filename ); } #else in = TIFFOpen( mysc.filename, "r" ); #endif if( !in ) { str = g_strdup_printf( _( "Cannot open : \"%s\"" ), baseName ); gimp_message( str ); g_free( str ); status = GIMP_PDB_EXECUTION_ERROR; } else { if( ( TIFFGetField( in, TIFFTAG_BITSPERSAMPLE, &bps ) == FALSE || ( bps != 8 && bps != 16 ) ) || ( TIFFGetField( in, TIFFTAG_SAMPLESPERPIXEL, &spp ) == FALSE || spp != 4 ) || ( TIFFGetField( in, TIFFTAG_PHOTOMETRIC, &photometric ) == FALSE || photometric != PHOTOMETRIC_SEPARATED ) || ( TIFFGetField( in, TIFFTAG_PLANARCONFIG, &planerConfig ) == FALSE || planerConfig != PLANARCONFIG_CONTIG ) || ( TIFFGetField( in, TIFFTAG_INKSET, &inkset ) == TRUE && inkset != INKSET_CMYK ) ) { str = g_strdup_printf( _( "\"%s\" is unsupported." ), baseName ); gimp_message( str ); g_free( str ); status = GIMP_PDB_EXECUTION_ERROR; } else { stripCount = TIFFNumberOfStrips( in ); stripSize = TIFFStripSize( in ); TIFFGetField( in, TIFFTAG_IMAGEWIDTH, &width ); TIFFGetField( in, TIFFTAG_IMAGELENGTH, &height ); TIFFGetField( in, TIFFTAG_ROWSPERSTRIP, &stripHeight ); TIFFGetField( in, TIFFTAG_RESOLUTIONUNIT, &resolutionUnit ); TIFFGetField( in, TIFFTAG_XRESOLUTION, &xres ); TIFFGetField( in, TIFFTAG_YRESOLUTION, &yres ); #if 0 str = g_strdup_printf( "Photometric : %d BPS : %d SPP : %d\nInkset : %d StripCount : %d", photometric, bps, spp, inkset, stripCount ); gimp_message( str ); g_free( str ); #endif step = ( bps == 16 ) ? 2 : 1; buf = g_malloc( stripSize ); values[1].data.d_image = gimp_image_new( width, height, GIMP_RGB ); gimp_image_set_resolution( values[1].data.d_image, xres, yres ); gimp_context_push(); for( i = 0; i < 4; i++ ) { layers[i] = gimp_layer_new( values[1].data.d_image, layerNames[i], width, height, GIMP_RGBA_IMAGE, 100.0, GIMP_DARKEN_ONLY_MODE ); gimp_context_set_foreground( &primaries[i] ); gimp_drawable_fill( layers[i], GIMP_FOREGROUND_FILL ); gimp_image_add_layer( values[1].data.d_image, layers[i], i ); masks[i] = gimp_layer_create_mask( layers[i], GIMP_ADD_BLACK_MASK ); gimp_layer_add_mask( layers[i], masks[i] ); drw[i] = gimp_drawable_get( masks[i] ); maskbuf[i] = g_malloc( width * stripHeight ); } gimp_context_pop(); layers[4] = gimp_layer_new( values[1].data.d_image, _( "Background" ), width, height, GIMP_RGB_IMAGE, 100.0, GIMP_NORMAL_MODE ); gimp_drawable_fill( layers[4], GIMP_WHITE_FILL ); gimp_image_add_layer( values[1].data.d_image, layers[4], 4 ); str = g_strdup_printf( _( "Reading \"%s\"..." ), baseName ); gimp_progress_init( str ); g_free( str ); for( i = 0; i < stripCount; i++ ) { guint32 size = TIFFReadEncodedStrip( in, i, buf, stripSize ); guint32 rowCount = ( size < stripSize ? height % stripHeight : stripHeight ); srcbuf = buf; if( bps == 16 ) srcbuf++; for( j = 0; j < 4; j++ ) { gimp_pixel_rgn_init( &( rgn[j] ), drw[j], 0, stripHeight * i, width, rowCount, FALSE, FALSE ); destbuf[j] = maskbuf[j]; } for( y = 0; y < rowCount; y++ ) { for( x = 0; x < width; x++ ) { *destbuf[0]++ = *srcbuf; srcbuf += step; *destbuf[1]++ = *srcbuf; srcbuf += step; *destbuf[2]++ = *srcbuf; srcbuf += step; *destbuf[3]++ = *srcbuf; srcbuf += step; //srcbuf += spp > 4 ? spp - 4 : 0; } } gimp_pixel_rgn_set_rect( &( rgn[0] ), maskbuf[0], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[1] ), maskbuf[1], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[2] ), maskbuf[2], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[3] ), maskbuf[3], 0, stripHeight * i, width, rowCount ); gimp_progress_update( (gdouble)i / stripCount ); } g_free( buf ); for( i = 0; i < 4; i++ ) { g_free( maskbuf[i] ); gimp_drawable_detach( drw[i] ); } #ifdef ENABLE_COLOR_MANAGEMENT if ( TIFFGetField( in, TIFFTAG_ICCPROFILE, &width, &iccProfile ) ) { GimpParasite *parasite; parasite = gimp_parasite_new( CMYKPROFILE, 0, width, iccProfile ); gimp_image_parasite_attach( values[1].data.d_image, parasite ); gimp_parasite_free( parasite ); //g_free( iccProfile ); // This causes clash on TIFFClose( in ). } #endif } TIFFClose( in ); } g_free( baseName ); } else status = GIMP_PDB_CANCEL; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; if( status == GIMP_PDB_SUCCESS ) { *nreturn_vals = 2; values[1].type = GIMP_PDB_IMAGE; if( run_mode != GIMP_RUN_NONINTERACTIVE ) { gimp_image_undo_enable( values[1].data.d_image ); gimp_display_new( values[1].data.d_image ); gimp_displays_flush(); } gimp_set_data( "plug-in-separate-import/lastpath", mysc.filename, strlen( mysc.filename ) + 1 ); } else *nreturn_vals = 1; g_free( mysc.filename ); }
/* Compose a roll film image from several images */ static gint32 film (void) { gint width, height; guchar *hole; gint film_height, film_width; gint picture_width, picture_height; gint picture_space, picture_x0, picture_y0; gint hole_offset, hole_width, hole_height, hole_space, hole_x; gint number_height, num_images, num_pictures; gint j, k, picture_count; gdouble f; gint num_layers; gint32 *image_ID_src, image_ID_dst, layer_ID_src, layer_ID_dst; gint image_ID_tmp; gint32 *layers; GimpDrawable *drawable_dst; GimpPixelRgn pixel_rgn_dst; gint new_layer; gint floating_sel; /* initialize */ layers = NULL; num_images = filmvals.num_images; image_ID_src = filmvals.image; if (num_images <= 0) return (-1); gimp_context_push (); gimp_context_set_foreground (&filmvals.number_color); gimp_context_set_background (&filmvals.film_color); if (filmvals.keep_height) /* Search maximum picture height */ { picture_height = 0; for (j = 0; j < num_images; j++) { height = gimp_image_height (image_ID_src[j]); if (height > picture_height) picture_height = height; } film_height = (int)(picture_height / filmvals.picture_height + 0.5); filmvals.film_height = film_height; } else { film_height = filmvals.film_height; picture_height = (int)(film_height * filmvals.picture_height + 0.5); } picture_space = (int)(film_height * filmvals.picture_space + 0.5); picture_y0 = (film_height - picture_height)/2; number_height = film_height * filmvals.number_height; /* Calculate total film width */ film_width = 0; num_pictures = 0; for (j = 0; j < num_images; j++) { layers = gimp_image_get_layers (image_ID_src[j], &num_layers); /* Get scaled image size */ width = gimp_image_width (image_ID_src[j]); height = gimp_image_height (image_ID_src[j]); f = ((double)picture_height) / (double)height; picture_width = width * f; for (k = 0; k < num_layers; k++) { if (gimp_layer_is_floating_sel (layers[k])) continue; film_width += (picture_space/2); /* Leading space */ film_width += picture_width; /* Scaled image width */ film_width += (picture_space/2); /* Trailing space */ num_pictures++; } g_free (layers); } #ifdef FILM_DEBUG g_printerr ("film_height = %d, film_width = %d\n", film_height, film_width); g_printerr ("picture_height = %d, picture_space = %d, picture_y0 = %d\n", picture_height, picture_space, picture_y0); g_printerr ("Number of pictures = %d\n", num_pictures); #endif image_ID_dst = create_new_image (_("Untitled"), (guint) film_width, (guint) film_height, GIMP_RGB_IMAGE, &layer_ID_dst, &drawable_dst, &pixel_rgn_dst); /* Fill film background */ gimp_drawable_fill (layer_ID_dst, GIMP_FILL_BACKGROUND); /* Draw all the holes */ hole_offset = film_height * filmvals.hole_offset; hole_width = film_height * filmvals.hole_width; hole_height = film_height * filmvals.hole_height; hole_space = film_height * filmvals.hole_space; hole_x = hole_space / 2; #ifdef FILM_DEBUG g_printerr ("hole_x %d hole_offset %d hole_width %d hole_height %d hole_space %d\n", hole_x, hole_offset, hole_width, hole_height, hole_space ); #endif hole = create_hole_rgb (hole_width, hole_height); if (hole) { while (hole_x < film_width) { draw_hole_rgb (drawable_dst, hole_x, hole_offset, hole_width, hole_height, hole); draw_hole_rgb (drawable_dst, hole_x, film_height-hole_offset-hole_height, hole_width, hole_height, hole); hole_x += hole_width + hole_space; } g_free (hole); } gimp_drawable_detach (drawable_dst); /* Compose all images and layers */ picture_x0 = 0; picture_count = 0; for (j = 0; j < num_images; j++) { image_ID_tmp = gimp_image_duplicate (image_ID_src[j]); width = gimp_image_width (image_ID_tmp); height = gimp_image_height (image_ID_tmp); f = ((gdouble) picture_height) / (gdouble) height; picture_width = width * f; if (gimp_image_base_type (image_ID_tmp) != GIMP_RGB) gimp_image_convert_rgb (image_ID_tmp); gimp_image_scale (image_ID_tmp, picture_width, picture_height); layers = gimp_image_get_layers (image_ID_tmp, &num_layers); for (k = 0; k < num_layers; k++) { if (gimp_layer_is_floating_sel (layers[k])) continue; picture_x0 += picture_space / 2; layer_ID_src = layers[k]; gimp_layer_resize_to_image_size (layer_ID_src); new_layer = gimp_layer_new_from_drawable (layer_ID_src, image_ID_dst); gimp_image_insert_layer (image_ID_dst, new_layer, -1, -1); gimp_layer_set_offsets (new_layer, picture_x0, picture_y0); /* Draw picture numbers */ if ((number_height > 0) && (filmvals.number_pos[0] || filmvals.number_pos[1])) { if (filmvals.number_pos[0]) draw_number (layer_ID_dst, filmvals.number_start + picture_count, picture_x0 + picture_width/2, (hole_offset-number_height)/2, number_height); if (filmvals.number_pos[1]) draw_number (layer_ID_dst, filmvals.number_start + picture_count, picture_x0 + picture_width/2, film_height - (hole_offset + number_height)/2, number_height); } picture_x0 += picture_width + (picture_space/2); gimp_progress_update (((gdouble) (picture_count + 1)) / (gdouble) num_pictures); picture_count++; } g_free (layers); gimp_image_delete (image_ID_tmp); } gimp_progress_update (1.0); gimp_image_flatten (image_ID_dst); /* Drawing text/numbers leaves us with a floating selection. Stop it */ floating_sel = gimp_image_get_floating_sel (image_ID_dst); if (floating_sel != -1) gimp_floating_sel_anchor (floating_sel); gimp_context_pop (); return image_ID_dst; }
/* -------------------------------------------- * gap_fg_from_selection_exec_apply_run * -------------------------------------------- * generate a tri map from the current selection by filling the shrinked * shape with white, the expanded shape with black and the borderline * between shrinked and expanded selection with medium gray. * the trimap is attached as layermask to the input drawable, * and used as input for the foreground selection via alpha matting algorithm, * that creates a resulting layer with trimmed selection. * */ gint gap_fg_from_selection_exec_apply_run (gint32 image_id, gint32 drawable_id , gboolean doProgress, gboolean doFlush , GapFgSelectValues *fsValPtr) { GimpRGB color; gint32 activeSelection; gint32 shrinkedSelection; gint32 trimap; gboolean hadSelection; gint rc; rc = 0; trimap = -1; activeSelection = -1; shrinkedSelection = -1; hadSelection = FALSE; gimp_context_push(); gimp_image_undo_group_start(image_id); if (gimp_selection_is_empty(image_id) == TRUE) { if (gimp_drawable_has_alpha(drawable_id) == FALSE) { /* if the layer has no alpha select all */ gimp_selection_all(image_id); } else { gimp_selection_layer_alpha(drawable_id); } activeSelection = gimp_selection_save(image_id); } else { activeSelection = gimp_selection_save(image_id); hadSelection = TRUE; } trimap = gimp_layer_get_mask(drawable_id); if (trimap < 0) { /* create trimap as new layermask */ trimap = gimp_layer_create_mask(drawable_id, GIMP_ADD_BLACK_MASK); gimp_layer_add_mask(drawable_id, trimap); } else { /* use BLACK color to fill the already existing layermask * (note that gimp_drawable_fill is used to fill the entire mask * regardless to the current selection) */ color.r = 0.0; color.g = 0.0; color.b = 0.0; color.a = 1.0; gimp_context_set_background (&color); gimp_drawable_fill(trimap, GIMP_BACKGROUND_FILL); } gimp_selection_sharpen(image_id); if (fsValPtr->innerRadius > 0) { gimp_selection_shrink(image_id, fsValPtr->innerRadius); } shrinkedSelection = gimp_selection_save(image_id); /* use WHITE color to mark foreground regions */ color.r = 1.0; color.g = 1.0; color.b = 1.0; color.a = 1.0; gimp_context_set_background (&color); gimp_edit_fill(trimap, GIMP_BACKGROUND_FILL); gimp_selection_load(activeSelection); gimp_selection_sharpen(image_id); if (fsValPtr->outerRadius > 0) { gimp_selection_grow(image_id, fsValPtr->outerRadius); } gimp_selection_combine(shrinkedSelection, GIMP_CHANNEL_OP_SUBTRACT); /* use medium GRAY to mark undefined regions */ color.r = 0.5; color.g = 0.5; color.b = 0.5; color.a = 1.0; gimp_context_set_background (&color); gimp_edit_fill(trimap, GIMP_BACKGROUND_FILL); gimp_selection_none(image_id); /* perform the foreground selection (that creates the resulting layer) */ { GapFgExtractValues fgExtractValues; GapFgExtractValues *fgValPtr; fgValPtr = &fgExtractValues; fgValPtr->input_drawable_id = drawable_id; fgValPtr->tri_map_drawable_id = trimap; fgValPtr->create_result = TRUE; fgValPtr->create_layermask = fsValPtr->create_layermask; fgValPtr->lock_color = fsValPtr->lock_color; fgValPtr->colordiff_threshold = fsValPtr->colordiff_threshold; rc = gap_fg_matting_exec_apply_run (image_id, drawable_id , doProgress, doFlush , fgValPtr ); } /* restore original selection */ if (hadSelection == TRUE) { gimp_selection_load(activeSelection); } gimp_image_undo_group_end(image_id); gimp_context_pop(); return (rc); } /* end gap_fg_from_selection_exec_apply_run */
static void d_paint_star (GfigObject *obj) { /* first point center */ /* Next point is radius */ gdouble *line_pnts; gint seg_count = 0; gint i = 0; DobjPoints *center_pnt; DobjPoints *outer_radius_pnt; DobjPoints *inner_radius_pnt; gint16 shift_x; gint16 shift_y; gdouble ang_grid; gdouble ang_loop; gdouble outer_radius; gdouble inner_radius; gdouble offset_angle; gint loop; GdkPoint first_pnt = { 0, 0 }; GdkPoint last_pnt = { 0, 0 }; gboolean first = TRUE; gdouble *min_max; g_assert (obj != NULL); /* count - add one to close polygon */ seg_count = 2 * obj->type_data + 1; center_pnt = obj->points; if (!center_pnt || !seg_count) return; /* no-line */ line_pnts = g_new0 (gdouble, 2 * seg_count + 1); min_max = g_new (gdouble, 4); /* Go around all the points drawing a line from one to the next */ /* Next point defines the radius */ outer_radius_pnt = center_pnt->next; /* this defines the vetices */ if (!outer_radius_pnt) { #ifdef DEBUG g_warning ("Internal error in star - no outer vertice point \n"); #endif /* DEBUG */ g_free (line_pnts); g_free (min_max); return; } inner_radius_pnt = outer_radius_pnt->next; /* this defines the vetices */ if (!inner_radius_pnt) { #ifdef DEBUG g_warning ("Internal error in star - no inner vertice point \n"); #endif /* DEBUG */ g_free (line_pnts); g_free (min_max); return; } shift_x = outer_radius_pnt->pnt.x - center_pnt->pnt.x; shift_y = outer_radius_pnt->pnt.y - center_pnt->pnt.y; outer_radius = sqrt ((shift_x*shift_x) + (shift_y*shift_y)); /* Lines */ ang_grid = 2.0 * G_PI / (2.0 * (gdouble) obj->type_data); offset_angle = atan2 (shift_y, shift_x); shift_x = inner_radius_pnt->pnt.x - center_pnt->pnt.x; shift_y = inner_radius_pnt->pnt.y - center_pnt->pnt.y; inner_radius = sqrt ((shift_x*shift_x) + (shift_y*shift_y)); for (loop = 0 ; loop < 2 * obj->type_data ; loop++) { gdouble lx, ly; GdkPoint calc_pnt; ang_loop = (gdouble)loop * ang_grid + offset_angle; if (loop % 2) { lx = inner_radius * cos (ang_loop); ly = inner_radius * sin (ang_loop); } else { lx = outer_radius * cos (ang_loop); ly = outer_radius * sin (ang_loop); } calc_pnt.x = RINT (lx + center_pnt->pnt.x); calc_pnt.y = RINT (ly + center_pnt->pnt.y); /* Miss out duped pnts */ if (!first) { if (calc_pnt.x == last_pnt.x && calc_pnt.y == last_pnt.y) { continue; } } line_pnts[i++] = calc_pnt.x; line_pnts[i++] = calc_pnt.y; last_pnt = calc_pnt; if (first) { first_pnt = calc_pnt; first = FALSE; min_max[0] = min_max[2] = calc_pnt.x; min_max[1] = min_max[3] = calc_pnt.y; } else { min_max[0] = MIN (min_max[0], calc_pnt.x); min_max[1] = MIN (min_max[1], calc_pnt.y); min_max[2] = MAX (min_max[2], calc_pnt.x); min_max[3] = MAX (min_max[3], calc_pnt.y); } } line_pnts[i++] = first_pnt.x; line_pnts[i++] = first_pnt.y; /* Scale before drawing */ if (selvals.scaletoimage) { scale_to_original_xy (&line_pnts[0], i / 2); scale_to_original_xy (min_max, 2); } else { scale_to_xy (&line_pnts[0], i / 2); scale_to_xy (min_max, 2); } if (gfig_context_get_current_style ()->fill_type != FILL_NONE) { gimp_context_push (); gimp_context_set_antialias (selopt.antia); gimp_context_set_feather (selopt.feather); gimp_context_set_feather_radius (selopt.feather_radius, selopt.feather_radius); gimp_image_select_polygon (gfig_context->image_id, selopt.type, i, line_pnts); gimp_context_pop (); paint_layer_fill (min_max[0], min_max[1], min_max[2], min_max[3]); gimp_selection_none (gfig_context->image_id); } if (obj->style.paint_type == PAINT_BRUSH_TYPE) gfig_paint (selvals.brshtype, gfig_context->drawable_id, i, line_pnts); g_free (line_pnts); g_free (min_max); }
static void d_paint_circle (GfigObject *obj) { DobjPoints *center_pnt; DobjPoints *edge_pnt; gint radius; gdouble dpnts[4]; g_assert (obj != NULL); center_pnt = obj->points; if (!center_pnt) return; /* End-of-line */ edge_pnt = center_pnt->next; if (!edge_pnt) { g_error ("Internal error - circle no edge pnt"); } radius = calc_radius (¢er_pnt->pnt, &edge_pnt->pnt); dpnts[0] = (gdouble) center_pnt->pnt.x - radius; dpnts[1] = (gdouble) center_pnt->pnt.y - radius; dpnts[3] = dpnts[2] = (gdouble) radius * 2; /* Scale before drawing */ if (selvals.scaletoimage) scale_to_original_xy (&dpnts[0], 2); else scale_to_xy (&dpnts[0], 2); if (gfig_context_get_current_style ()->fill_type != FILL_NONE) { gimp_context_push (); gimp_context_set_antialias (selopt.antia); gimp_context_set_feather (selopt.feather); gimp_context_set_feather_radius (selopt.feather_radius, selopt.feather_radius); gimp_image_select_ellipse (gfig_context->image_id, selopt.type, dpnts[0], dpnts[1], dpnts[2], dpnts[3]); gimp_context_pop (); paint_layer_fill (center_pnt->pnt.x - radius, center_pnt->pnt.y - radius, center_pnt->pnt.x + radius, center_pnt->pnt.y + radius); gimp_selection_none (gfig_context->image_id); } /* Drawing a circle may be harder than stroking a circular selection, * but we have to do it or we will not be able to draw outside of the * layer. */ if (obj->style.paint_type == PAINT_BRUSH_TYPE) { const gdouble r = dpnts[2] / 2; const gdouble cx = dpnts[0] + r, cy = dpnts[1] + r; gdouble line_pnts[362]; gdouble angle = 0; gint i = 0; while (i < 362) { static const gdouble step = 2 * G_PI / 180; line_pnts[i++] = cx + r * cos (angle); line_pnts[i++] = cy + r * sin (angle); angle += step; } gfig_paint (selvals.brshtype, gfig_context->drawable_id, i, line_pnts); } }