Code

Modified filter rendering area handling to better accommodate upcoming feOffset
[inkscape.git] / src / dialogs / tiledialog.cpp
index 12c94ed815cda3e7f1abb34f9f5f9dfc809c5bcf..75311ddd03dc3fa3b837a9ea02ffe0fce9817240 100644 (file)
@@ -49,18 +49,23 @@ sp_compare_x_position(SPItem *first, SPItem *second)
     using NR::X;
     using NR::Y;
 
-    NR::Rect const a = first->invokeBbox(sp_item_i2doc_affine(first));
-    double const a_height = a.dimensions()[Y];
+    NR::Maybe<NR::Rect> a = first->getBounds(sp_item_i2doc_affine(first));
+    NR::Maybe<NR::Rect> b = second->getBounds(sp_item_i2doc_affine(second));
 
-    NR::Rect const b = second->invokeBbox(sp_item_i2doc_affine(second));
-    double const b_height = b.dimensions()[Y];
+    if ( !a || !b ) {
+        // FIXME?
+        return 0;
+    }
+
+    double const a_height = a->dimensions()[Y];
+    double const b_height = b->dimensions()[Y];
     
     bool a_in_b_vert = false;
-    if ((a.min()[Y] < b.min()[Y] + 0.1) && (a.min()[Y] > b.min()[Y] - b_height)) {
+    if ((a->min()[Y] < b->min()[Y] + 0.1) && (a->min()[Y] > b->min()[Y] - b_height)) {
         a_in_b_vert = true;
-    } else if ((b.min()[Y] < a.min()[Y] + 0.1) && (b.min()[Y] > a.min()[Y] - a_height)) {
+    } else if ((b->min()[Y] < a->min()[Y] + 0.1) && (b->min()[Y] > a->min()[Y] - a_height)) {
         a_in_b_vert = true;
-    } else if (b.min()[Y] == a.min()[Y]) {
+    } else if (b->min()[Y] == a->min()[Y]) {
         a_in_b_vert = true;
     } else {
         a_in_b_vert = false;
@@ -69,10 +74,10 @@ sp_compare_x_position(SPItem *first, SPItem *second)
     if (!a_in_b_vert) {
         return -1;
     }
-    if (a_in_b_vert && a.min()[X] > b.min()[X]) {
+    if (a_in_b_vert && a->min()[X] > b->min()[X]) {
         return 1;
     }
-    if (a_in_b_vert && a.min()[X] < b.min()[X]) {
+    if (a_in_b_vert && a->min()[X] < b->min()[X]) {
         return -1;
     }
     return 0;
@@ -84,13 +89,18 @@ sp_compare_x_position(SPItem *first, SPItem *second)
 int
 sp_compare_y_position(SPItem *first, SPItem *second)
 {
-    NR::Rect const a = first->invokeBbox(sp_item_i2doc_affine(first));
-    NR::Rect const b = second->invokeBbox(sp_item_i2doc_affine(second));
+    NR::Maybe<NR::Rect> a = first->getBounds(sp_item_i2doc_affine(first));
+    NR::Maybe<NR::Rect> b = second->getBounds(sp_item_i2doc_affine(second));
+
+    if ( !a || !b ) {
+        // FIXME?
+        return 0;
+    }
 
-    if (a.min()[NR::Y] > b.min()[NR::Y]) {
+    if (a->min()[NR::Y] > b->min()[NR::Y]) {
         return 1;
     }
-    if (a.min()[NR::Y] < b.min()[NR::Y]) {
+    if (a->min()[NR::Y] < b->min()[NR::Y]) {
         return -1;
     }
     
@@ -123,6 +133,9 @@ void TileDialog::Grid_Arrange ()
     total_col_width=0;
     total_row_height=0;
 
+    // check for correct numbers in the row- and col-spinners
+    on_col_spinbutton_changed();
+    on_row_spinbutton_changed();
 
     // set padding to manual values
     paddingx = XPadSpinner.get_value();
@@ -149,24 +162,29 @@ void TileDialog::Grid_Arrange ()
     grid_top = 99999;
 
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-    sp_document_ensure_up_to_date(SP_DT_DOCUMENT(desktop));
+    sp_document_ensure_up_to_date(sp_desktop_document(desktop));
 
-    Inkscape::Selection *selection = SP_DT_SELECTION (desktop);
+    Inkscape::Selection *selection = sp_desktop_selection (desktop);
     const GSList *items = selection->itemList();
     cnt=0;
     for (; items != NULL; items = items->next) {
         SPItem *item = SP_ITEM(items->data);
-        NR::Rect const b = item->invokeBbox(sp_item_i2doc_affine(item));
-        width = b.dimensions()[NR::X];
-        height = b.dimensions()[NR::Y];
-        cx = b.midpoint()[NR::X];
-        cy = b.midpoint()[NR::Y];
-
-        if (b.min()[NR::X] < grid_left) {
-            grid_left = b.min()[NR::X];
+        NR::Maybe<NR::Rect> b = item->getBounds(sp_item_i2doc_affine(item));
+        if (!b) {
+            continue;
+        }
+
+        width = b->dimensions()[NR::X];
+        height = b->dimensions()[NR::Y];
+
+        cx = b->midpoint()[NR::X];
+        cy = b->midpoint()[NR::Y];
+
+        if (b->min()[NR::X] < grid_left) {
+            grid_left = b->min()[NR::X];
         }
-        if (b.min()[NR::Y] < grid_top) {
-            grid_top = b.min()[NR::Y];
+        if (b->min()[NR::Y] < grid_top) {
+            grid_top = b->min()[NR::Y];
         }
         if (width > col_width) {
             col_width = width;
@@ -193,15 +211,18 @@ void TileDialog::Grid_Arrange ()
         const GSList *sizes = sorted;
         for (; sizes != NULL; sizes = sizes->next) {
             SPItem *item = SP_ITEM(sizes->data);
-            NR::Rect const b = item->invokeBbox(sp_item_i2doc_affine(item));
-            width = b.dimensions()[NR::X];
-            height = b.dimensions()[NR::Y];
-            if (width > col_widths[(cnt % NoOfCols)]) {
-                col_widths[(cnt % NoOfCols)] = width;
-            }
-            if (height > row_heights[(cnt / NoOfCols)]) {
-                row_heights[(cnt / NoOfCols)] = height;
+            NR::Maybe<NR::Rect> b = item->getBounds(sp_item_i2doc_affine(item));
+            if (b) {
+                width = b->dimensions()[NR::X];
+                height = b->dimensions()[NR::Y];
+                if (width > col_widths[(cnt % NoOfCols)]) {
+                    col_widths[(cnt % NoOfCols)] = width;
+                }
+                if (height > row_heights[(cnt / NoOfCols)]) {
+                    row_heights[(cnt / NoOfCols)] = height;
+                }
             }
+
             cnt++;
         }
 
@@ -247,14 +268,14 @@ void TileDialog::Grid_Arrange ()
     }
 
 
+    NR::Maybe<NR::Rect> sel_bbox = selection->bounds();
     // Fit to bbox, calculate padding between rows accordingly.
-    if (!SpaceManualRadioButton.get_active()){
-        NR::Rect b = selection->bounds();
+    if ( sel_bbox && !SpaceManualRadioButton.get_active() ){
 #ifdef DEBUG_GRID_ARRANGE
 g_print("\n row = %f     col = %f selection x= %f selection y = %f", total_row_height,total_col_width, b.extent(NR::X), b.extent(NR::Y));
 #endif
-        paddingx = (b.extent(NR::X) - total_col_width) / (NoOfCols -1);
-        paddingy = (b.extent(NR::Y) - total_row_height) / (NoOfRows -1);
+        paddingx = (sel_bbox->extent(NR::X) - total_col_width) / (NoOfCols -1);
+        paddingy = (sel_bbox->extent(NR::Y) - total_row_height) / (NoOfRows -1);
     }
 
 /*
@@ -297,20 +318,25 @@ g_print("\n row = %f     col = %f selection x= %f selection y = %f", total_row_h
              for (; current_row != NULL; current_row = current_row->next) {
                  SPItem *item=SP_ITEM(current_row->data);
                  Inkscape::XML::Node *repr = SP_OBJECT_REPR(item);
-                 NR::Rect const b = item->invokeBbox(sp_item_i2doc_affine(item));
-                 width = b.dimensions()[NR::X];
-                 height = b.dimensions()[NR::Y];
+                 NR::Maybe<NR::Rect> b = item->getBounds(sp_item_i2doc_affine(item));
+                 NR::Point min;
+                 if (b) {
+                     width = b->dimensions()[NR::X];
+                     height = b->dimensions()[NR::Y];
+                     min = b->min();
+                 } else {
+                     width = height = 0;
+                     min = NR::Point(0, 0);
+                 }
+
                  row = cnt / NoOfCols;
                  col = cnt % NoOfCols;
 
-                // original before I started fecking about with it.
-                // new_x = grid_left + (((col_width - width)/2)*HorizAlign) + (( col_width + paddingx ) * (cnt % NoOfCols));
-                // new_y = grid_top + (((row_height - height)/2)*VertAlign) +(( row_height + paddingy ) * (cnt / NoOfCols));
-
                  new_x = grid_left + (((col_widths[col] - width)/2)*HorizAlign) + col_xs[col];
                  new_y = grid_top + (((row_heights[row] - height)/2)*VertAlign) + row_ys[row];
 
-                 NR::Point move = NR::Point(new_x - b.min()[NR::X], b.min()[NR::Y] - new_y); // why are the two args the opposite ways round???
+                 // signs are inverted between x and y due to y inversion
+                 NR::Point move = NR::Point(new_x - min[NR::X], min[NR::Y] - new_y);
                  NR::Matrix const &affine = NR::Matrix(NR::translate(move));
                  sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * affine);
                  sp_item_write_transform(item, repr, item->transform,  NULL);
@@ -323,7 +349,8 @@ g_print("\n row = %f     col = %f selection x= %f selection y = %f", total_row_h
     NRRect b;
             selection->bounds(&b);
 
-    sp_document_done (SP_DT_DOCUMENT (desktop));
+            sp_document_done (sp_desktop_document (desktop), SP_VERB_SELECTION_GRIDTILE, 
+                              _("Arrange in a grid"));
 
 }
 
@@ -353,7 +380,7 @@ void TileDialog::on_row_spinbutton_changed()
     updating = true;
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
 
-    Inkscape::Selection *selection = SP_DT_SELECTION (desktop);
+    Inkscape::Selection *selection = sp_desktop_selection (desktop);
 
     GSList const *items = selection->itemList();
     int selcount = g_slist_length((GSList *)items);
@@ -377,7 +404,7 @@ void TileDialog::on_col_spinbutton_changed()
     // in turn, prevent listener from responding
     updating = true;
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-    Inkscape::Selection *selection = SP_DT_SELECTION (desktop);
+    Inkscape::Selection *selection = sp_desktop_selection (desktop);
 
     GSList const *items = selection->itemList();
     int selcount = g_slist_length((GSList *)items);
@@ -539,7 +566,7 @@ void TileDialog::updateSelection()
     // in turn, prevent listener from responding
     updating = true;
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-    Inkscape::Selection *selection = SP_DT_SELECTION (desktop);
+    Inkscape::Selection *selection = sp_desktop_selection (desktop);
     const GSList *items = selection->itemList();
     int selcount = g_slist_length((GSList *)items);
 
@@ -609,7 +636,7 @@ TileDialog::TileDialog()
 
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
 
-    Inkscape::Selection *selection = SP_DT_SELECTION (desktop);
+    Inkscape::Selection *selection = sp_desktop_selection (desktop);
     int selcount = 1;
     if (!selection->isEmpty()) {
         GSList const *items = selection->itemList();
@@ -780,7 +807,7 @@ TileDialog::TileDialog()
     {
         /*#### Y Padding ####*/
 
-        GtkWidget *i = sp_icon_new (GTK_ICON_SIZE_MENU, "clonetiler_per_row");
+        GtkWidget *i = sp_icon_new (Inkscape::ICON_SIZE_MENU, "clonetiler_per_row");
         YPadBox.pack_start (*(Glib::wrap(i)), false, false, MARGIN);
 
         YPadSpinner.set_digits(1);
@@ -805,7 +832,7 @@ TileDialog::TileDialog()
     {
         /*#### X padding ####*/
 
-        GtkWidget *i = sp_icon_new (GTK_ICON_SIZE_MENU, "clonetiler_per_column");
+        GtkWidget *i = sp_icon_new (Inkscape::ICON_SIZE_MENU, "clonetiler_per_column");
         XPadBox.pack_start (*(Glib::wrap(i)), false, false, MARGIN);
 
         XPadSpinner.set_digits(1);