summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c7b24ea)
raw | patch | inline | side by side (parent: c7b24ea)
author | johncoswell <johncoswell@users.sourceforge.net> | |
Mon, 21 Apr 2008 00:24:54 +0000 (00:24 +0000) | ||
committer | johncoswell <johncoswell@users.sourceforge.net> | |
Mon, 21 Apr 2008 00:24:54 +0000 (00:24 +0000) |
src/flood-context.cpp | patch | blob | history |
diff --git a/src/flood-context.cpp b/src/flood-context.cpp
index d51c1fde4a36cbdbcf1da57e0ba08bc056790976..083b87fa20ba7dc7c5880e70e62276551b70d272 100644 (file)
--- a/src/flood-context.cpp
+++ b/src/flood-context.cpp
@@ -417,21 +417,23 @@ inline static bool check_if_pixel_is_paintable(guchar *px, unsigned char *trace_
* \param transform The transform to apply to the final SVG path.
* \param union_with_selection If true, merge the final SVG path with the current selection.
*/
-static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *desktop, NR::Matrix transform, bool union_with_selection) {
+static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *desktop, NR::Matrix transform, unsigned int min_x, unsigned int max_x, unsigned int min_y, unsigned int max_y, bool union_with_selection) {
SPDocument *document = sp_desktop_document(desktop);
unsigned char *trace_t;
- GrayMap *gray_map = GrayMapCreate(bci.width, bci.height);
- for (unsigned int y = 0; y < bci.height ; y++) {
- unsigned long *gray_map_t = gray_map->rows[y];
+ GrayMap *gray_map = GrayMapCreate((max_x - min_x + 1), (max_y - min_y + 1));
+ unsigned int gray_map_y = 0;
+ for (unsigned int y = min_y; y <= max_y; y++) {
+ unsigned long *gray_map_t = gray_map->rows[gray_map_y];
- trace_t = get_trace_pixel(trace_px, 0, y, bci.width);
- for (unsigned int x = 0; x < bci.width ; x++) {
+ trace_t = get_trace_pixel(trace_px, min_x, y, bci.width);
+ for (unsigned int x = min_x; x <= max_x; x++) {
*gray_map_t = is_pixel_colored(trace_t) ? GRAYMAP_BLACK : GRAYMAP_WHITE;
gray_map_t++;
trace_t++;
}
+ gray_map_y++;
}
Inkscape::Trace::Potrace::PotraceTracingEngine pte;
@@ -657,7 +659,7 @@ static void shift_point_onto_queue(std::deque<NR::Point> *fill_queue, unsigned i
* \param orig_color The original selected pixel to use as the fill target color.
* \param bci The bitmap_coords_info structure.
*/
-static ScanlineCheckResult perform_bitmap_scanline_check(std::deque<NR::Point> *fill_queue, guchar *px, guchar *trace_px, unsigned char *orig_color, bitmap_coords_info bci) {
+static ScanlineCheckResult perform_bitmap_scanline_check(std::deque<NR::Point> *fill_queue, guchar *px, guchar *trace_px, unsigned char *orig_color, bitmap_coords_info bci, unsigned int *min_x, unsigned int *max_x) {
bool aborted = false;
bool reached_screen_boundary = false;
bool ok;
@@ -687,6 +689,9 @@ static ScanlineCheckResult perform_bitmap_scanline_check(std::deque<NR::Point> *
keep_tracing = (bci.x < bci.width);
}
+ *min_x = MIN(*min_x, bci.x);
+ *max_x = MAX(*max_x, bci.x);
+
if (keep_tracing) {
if (check_if_pixel_is_paintable(px, current_trace_t, bci.x, bci.y, orig_color, bci)) {
paint_directions = paint_pixel(px, trace_px, orig_color, bci, current_trace_t);
@@ -945,6 +950,11 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even
unsigned long sort_size_threshold = 5;
+ unsigned int min_y = height;
+ unsigned int max_y = 0;
+ unsigned int min_x = width;
+ unsigned int max_x = 0;
+
while (!color_queue.empty() && !aborted) {
NR::Point color_point = color_queue.front();
color_queue.pop();
@@ -1033,6 +1043,9 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even
int x = (int)cp[NR::X];
int y = (int)cp[NR::Y];
+ min_y = MIN((unsigned int)y, min_y);
+ max_y = MAX((unsigned int)y, max_y);
+
unsigned char *trace_t = get_trace_pixel(trace_px, x, y, width);
if (!is_pixel_checked(trace_t)) {
mark_pixel_checked(trace_t);
@@ -1057,7 +1070,7 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even
bci.x = x;
bci.y = y;
- ScanlineCheckResult result = perform_bitmap_scanline_check(&fill_queue, px, trace_px, orig_color, bci);
+ ScanlineCheckResult result = perform_bitmap_scanline_check(&fill_queue, px, trace_px, orig_color, bci, &min_x, &max_x);
switch (result) {
case SCANLINE_CHECK_ABORTED:
@@ -1077,7 +1090,7 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even
bci.is_left = false;
bci.x = x + 1;
- result = perform_bitmap_scanline_check(&fill_queue, px, trace_px, orig_color, bci);
+ result = perform_bitmap_scanline_check(&fill_queue, px, trace_px, orig_color, bci, &min_x, &max_x);
switch (result) {
case SCANLINE_CHECK_ABORTED:
@@ -1112,10 +1125,19 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even
if (reached_screen_boundary) {
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."));
}
+
+ unsigned int trace_padding = bci.radius + 1;
+ if (min_y > trace_padding) { min_y -= trace_padding; }
+ if (max_y < (y_limit - trace_padding)) { max_y += trace_padding; }
+ if (min_x > trace_padding) { min_x -= trace_padding; }
+ if (max_x < (width - 1 - trace_padding)) { max_x += trace_padding; }
+
+ NR::Point min_start = NR::Point(min_x, min_y);
+ affine = scale * NR::translate(-origin * scale - min_start);
NR::Matrix inverted_affine = NR::Matrix(affine).inverse();
- do_trace(bci, trace_px, desktop, inverted_affine, union_with_selection);
+ do_trace(bci, trace_px, desktop, inverted_affine, min_x, max_x, min_y, max_y, union_with_selection);
g_free(trace_px);