index 2c84800d69c20ab57bb9b9e37aa5ab6a28375924..6a7de1fedfa0adbef32194323bb225213811f61e 100644 (file)
#include <glib.h>
#include "display/nr-filter-units.h"
-#include "libnr/nr-matrix.h"
-#include "libnr/nr-rect.h"
-#include "libnr/nr-scale.h"
+#include "libnr/nr-rect-l.h"
#include "sp-filter-units.h"
+#include <2geom/transforms.h>
-namespace NR {
+using Geom::X;
+using Geom::Y;
+
+namespace Inkscape {
+namespace Filters {
FilterUnits::FilterUnits() :
filterUnits(SP_FILTER_UNITS_OBJECTBOUNDINGBOX),
paraller_axis(false), automatic_resolution(true)
{}
-void FilterUnits::set_ctm(Matrix const &ctm) {
+void FilterUnits::set_ctm(Geom::Matrix const &ctm) {
this->ctm = ctm;
}
resolution_y = y_res;
}
-void FilterUnits::set_item_bbox(Rect const &bbox) {
+void FilterUnits::set_item_bbox(Geom::OptRect const &bbox) {
item_bbox = bbox;
}
-void FilterUnits::set_filter_area(Rect const &area) {
+void FilterUnits::set_filter_area(Geom::OptRect const &area) {
filter_area = area;
}
automatic_resolution = automatic;
}
-Matrix FilterUnits::get_matrix_user2pb() const {
+Geom::Matrix FilterUnits::get_matrix_user2pb() const {
g_assert(resolution_x > 0);
g_assert(resolution_y > 0);
+ g_assert(filter_area);
- Matrix u2pb = ctm;
+ Geom::Matrix u2pb = ctm;
if (paraller_axis || !automatic_resolution) {
- u2pb[0] = resolution_x / (filter_area.max()[X] - filter_area.min()[X]);
+ u2pb[0] = resolution_x / (filter_area->max()[X] - filter_area->min()[X]);
u2pb[1] = 0;
u2pb[2] = 0;
- u2pb[3] = resolution_y / (filter_area.max()[Y] - filter_area.min()[Y]);
- u2pb[4] = 0;
- u2pb[5] = 0;
+ u2pb[3] = resolution_y / (filter_area->max()[Y] - filter_area->min()[Y]);
+ u2pb[4] = ctm[4];
+ u2pb[5] = ctm[5];
}
return u2pb;
}
-Matrix FilterUnits::get_matrix_units2pb(SPFilterUnits units) const {
- if (units == SP_FILTER_UNITS_OBJECTBOUNDINGBOX) {
- Matrix u2pb = get_matrix_user2pb();
- Point origo(item_bbox.min());
+Geom::Matrix FilterUnits::get_matrix_units2pb(SPFilterUnits units) const {
+ if ( item_bbox && (units == SP_FILTER_UNITS_OBJECTBOUNDINGBOX) ) {
+ Geom::Matrix u2pb = get_matrix_user2pb();
+ Geom::Point origo(item_bbox->min());
origo *= u2pb;
- Point i_end(item_bbox.max()[X], item_bbox.min()[Y]);
+ Geom::Point i_end(item_bbox->max()[X], item_bbox->min()[Y]);
i_end *= u2pb;
- Point j_end(item_bbox.min()[X], item_bbox.max()[Y]);
+ Geom::Point j_end(item_bbox->min()[X], item_bbox->max()[Y]);
j_end *= u2pb;
double len_i = sqrt((origo[X] - i_end[X]) * (origo[X] - i_end[X])
/* TODO: make sure that user coordinate system (0,0) is in correct
* place in pixblock coordinates */
- scale scaling(1.0 / len_i, 1.0 / len_j);
+ Geom::Scale scaling(1.0 / len_i, 1.0 / len_j);
u2pb *= scaling;
return u2pb;
} else if (units == SP_FILTER_UNITS_USERSPACEONUSE) {
return get_matrix_user2pb();
} else {
- g_warning("Error in NR::FilterUnits::get_matrix_units2pb: unrecognized value of filterUnits");
- return Matrix();
+ g_warning("Error in Inkscape::Filters::FilterUnits::get_matrix_units2pb: unrecognized unit type (%d)", units);
+ return Geom::Matrix();
}
}
-Matrix FilterUnits::get_matrix_filterunits2pb() const {
+Geom::Matrix FilterUnits::get_matrix_filterunits2pb() const {
return get_matrix_units2pb(filterUnits);
}
-Matrix FilterUnits::get_matrix_primitiveunits2pb() const {
+Geom::Matrix FilterUnits::get_matrix_primitiveunits2pb() const {
return get_matrix_units2pb(primitiveUnits);
}
-Matrix FilterUnits::get_matrix_display2pb() const {
- Matrix d2pb = ctm.inverse();
+Geom::Matrix FilterUnits::get_matrix_display2pb() const {
+ Geom::Matrix d2pb = ctm.inverse();
d2pb *= get_matrix_user2pb();
return d2pb;
}
-Matrix FilterUnits::get_matrix_pb2display() const {
- Matrix pb2d = get_matrix_user2pb().inverse();
+Geom::Matrix FilterUnits::get_matrix_pb2display() const {
+ Geom::Matrix pb2d = get_matrix_user2pb().inverse();
pb2d *= ctm;
return pb2d;
}
+Geom::Matrix FilterUnits::get_matrix_user2units(SPFilterUnits units) const {
+ if (item_bbox && units == SP_FILTER_UNITS_OBJECTBOUNDINGBOX) {
+ /* No need to worry about rotations: bounding box coordinates
+ * always have base vectors paraller with userspace coordinates */
+ Geom::Point min(item_bbox->min());
+ Geom::Point max(item_bbox->max());
+ double scale_x = 1.0 / (max[X] - min[X]);
+ double scale_y = 1.0 / (max[Y] - min[Y]);
+ //return Geom::Translate(min) * Geom::Scale(scale_x,scale_y); ?
+ return Geom::Matrix(scale_x, 0,
+ 0, scale_y,
+ min[X] * scale_x, min[Y] * scale_y);
+ } else if (units == SP_FILTER_UNITS_USERSPACEONUSE) {
+ return Geom::identity();
+ } else {
+ g_warning("Error in Inkscape::Filters::FilterUnits::get_matrix_user2units: unrecognized unit type (%d)", units);
+ return Geom::Matrix();
+ }
+}
+
+Geom::Matrix FilterUnits::get_matrix_user2filterunits() const {
+ return get_matrix_user2units(filterUnits);
+}
+
+Geom::Matrix FilterUnits::get_matrix_user2primitiveunits() const {
+ return get_matrix_user2units(primitiveUnits);
+}
+
+NR::IRect FilterUnits::get_pixblock_filterarea_paraller() const {
+ g_assert(filter_area);
+
+ int min_x = INT_MAX, min_y = INT_MAX, max_x = INT_MIN, max_y = INT_MIN;
+ Geom::Matrix u2pb = get_matrix_user2pb();
+
+ for (int i = 0 ; i < 4 ; i++) {
+ Geom::Point p = filter_area->corner(i);
+ p *= u2pb;
+ if (p[X] < min_x) min_x = (int)std::floor(p[X]);
+ if (p[X] > max_x) max_x = (int)std::ceil(p[X]);
+ if (p[Y] < min_y) min_y = (int)std::floor(p[Y]);
+ if (p[Y] > max_y) max_y = (int)std::ceil(p[Y]);
+ }
+ NR::IRect ret(NR::IPoint(min_x, min_y), NR::IPoint(max_x, max_y));
+ return ret;
+}
+
FilterUnits& FilterUnits::operator=(FilterUnits const &other) {
filterUnits = other.filterUnits;
primitiveUnits = other.primitiveUnits;
return *this;
}
-} // namespace NR
+} /* namespace Filters */
+} /* namespace Inkscape */
/*