flood-context.cpp revision 70a4afb4cd8683415fa1c7fcda611b4dd81c4a56
469N/A#define __SP_FLOOD_CONTEXT_C__
469N/A#include "display/sp-canvas.h"
469N/A#include "document.h"
1068N/A#include "sp-namedview.h"
1068N/A#include "sp-object.h"
1068N/A#include "selection.h"
1068N/A#include "selection-chemistry.h"
1068N/A#include "desktop-handles.h"
1068N/A#include "desktop-style.h"
1068N/A#include "message-stack.h"
1068N/A#include "message-context.h"
1068N/A#include "pixmaps/cursor-paintbucket.xpm"
1068N/A#include "flood-context.h"
1068N/A#include "sp-metrics.h"
1068N/A#include "object-edit.h"
1068N/A#include "xml/node-event-vector.h"
1068N/A#include "prefs-utils.h"
1068N/A#include "context-fns.h"
1068N/A#include "display/nr-arena-item.h"
1068N/A#include "display/nr-arena.h"
1068N/A#include "display/nr-arena-image.h"
469N/A#include "display/canvas-arena.h"
469N/A#include "libnr/nr-pixops.h"
469N/A#include "libnr/nr-matrix-rotate-ops.h"
469N/A#include "libnr/nr-matrix-translate-ops.h"
469N/A#include "libnr/nr-rotate-fns.h"
469N/A#include "libnr/nr-scale-ops.h"
1068N/A#include "libnr/nr-scale-translate-ops.h"
1068N/A#include "libnr/nr-translate-matrix-ops.h"
1068N/A#include "libnr/nr-translate-scale-ops.h"
1068N/A#include "libnr/nr-matrix-ops.h"
469N/A#include "splivarot.h"
469N/A#include "libnr/n-art-bpath.h"
469N/A#include "trace/potrace/inkscape-potrace.h"
469N/Astatic gint sp_flood_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event);
469N/A sizeof(SPFloodContextClass),
469N/A sizeof(SPFloodContext),
469N/A type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPFloodContext", &info, (GTypeFlags) 0);
469N/A if (shape_repr) {
469N/A if (shape_repr) {
469N/Astatic void merge_pixel_with_background(unsigned char *orig, unsigned char *bg, unsigned char *base) {
469N/Aenum PaintBucketChannels {
469N/Astatic bool compare_pixels(unsigned char *check, unsigned char *orig, unsigned char *dtc, int tolerance, PaintBucketChannels method) {
469N/A case FLOOD_CHANNELS_ALPHA:
469N/A case FLOOD_CHANNELS_RGB:
469N/Astatic bool try_add_to_queue(std::queue<NR::Point> *fill_queue, guchar *px, guchar *trace_px, unsigned char *orig, unsigned char *dtc, int x, int y, int width, int tolerance, PaintBucketChannels method, bool fill_switch) {
469N/A if (fill_switch) {
469N/A long totalNodeCount = 0L;
469N/A double offset = prefs_get_double_attribute_limited("tools.paintbucket", "offset", 1.5, 0.0, 2.0);
469N/A delete path_shape;
469N/A delete expanded_path_shape;
469N/A delete expanded_path;
469N/A // (we're dealing with unattached repr, so we write to its attr instead of using sp_item_set_transform)
469N/Astruct bitmap_coords_info {
469N/A bool bottom_fill;
469N/Aenum ScanlineCheckResult {
469N/Astatic ScanlineCheckResult perform_bitmap_scanline_check(std::queue<NR::Point> *fill_queue, guchar *px, guchar *trace_px, unsigned char *orig_color, bitmap_coords_info bci) {
469N/A bool reached_screen_boundary = false;
469N/A bool keep_tracing;
469N/A if (keep_tracing) {
469N/A bci.top_fill = try_add_to_queue(fill_queue, px, trace_px, orig_color, bci.dtc, bci.x, bci.y - 1, bci.width, bci.tolerance, bci.method, bci.top_fill);
469N/A bci.bottom_fill = try_add_to_queue(fill_queue, px, trace_px, orig_color, bci.dtc, bci.x, bci.y + 1, bci.width, bci.tolerance, bci.method, bci.bottom_fill);
469N/A reached_screen_boundary = true;
469N/A return SCANLINE_CHECK_OK;
469N/A desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("<b>Area is not bounded</b>, cannot fill."));
469N/A NRArenaItem *root = sp_item_invoke_show(SP_ITEM(sp_document_root(document)), arena, dkey, SP_ITEM_SHOW_DISPLAY);
469N/A nr_arena_item_invoke_update(root, &final_bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE);
469N/A NRPixBlock B;
469N/A NR::Point pw = NR::Point(event->button.x / zoom_scale, sp_document_height(document) + (event->button.y / zoom_scale)) * affine;
469N/A int tolerance = (255 * prefs_get_int_attribute_limited("tools.paintbucket", "tolerance", 1, 0, 100)) / 100;
469N/A PaintBucketChannels method = (PaintBucketChannels)prefs_get_int_attribute("tools.paintbucket", "channels", 0);
469N/A bool reached_screen_boundary = false;
469N/A bool bottom_fill = true;
469N/A top_fill = try_add_to_queue(&fill_queue, px, trace_px, orig_color, dtc, x, y - 1, width, tolerance, method, top_fill);
469N/A reached_screen_boundary = true;
469N/A bottom_fill = try_add_to_queue(&fill_queue, px, trace_px, orig_color, dtc, x, y + 1, width, tolerance, method, bottom_fill);
469N/A reached_screen_boundary = true;
469N/A ScanlineCheckResult result = perform_bitmap_scanline_check(&fill_queue, px, trace_px, orig_color, bci);
469N/A case SCANLINE_CHECK_ABORTED:
469N/A reached_screen_boundary = true;
469N/A case SCANLINE_CHECK_ABORTED:
469N/A reached_screen_boundary = true;
469N/A desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("<b>Area is not bounded</b>, cannot fill."));
469N/A if (reached_screen_boundary) {
469N/A desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("<b>Only the visible part of the bounded area was filled.</b> If you want to fill all of the area, undo, zoom out, and fill again."));
469N/Astatic gint sp_flood_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event)
469N/A case GDK_BUTTON_PRESS:
469N/A case GDK_BUTTON_PRESS:
469N/A case GDK_KEY_PRESS:
469N/A case GDK_KP_Down:
469N/A if (!MOD__CTRL_ONLY)
469N/A prefs_set_int_attribute("tools.paintbucket", "channels", (gint)gtk_combo_box_get_active(cbox));