2c84800d69c20ab57bb9b9e37aa5ab6a28375924
1 /*
2 * Utilities for handling coordinate system transformations in filters
3 *
4 * Author:
5 * Niko Kiirala <niko@kiirala.com>
6 *
7 * Copyright (C) 2007 Niko Kiirala
8 *
9 * Released under GNU GPL, read the file 'COPYING' for more information
10 */
12 #include <glib.h>
14 #include "display/nr-filter-units.h"
15 #include "libnr/nr-matrix.h"
16 #include "libnr/nr-rect.h"
17 #include "libnr/nr-scale.h"
18 #include "sp-filter-units.h"
20 namespace NR {
22 FilterUnits::FilterUnits() :
23 filterUnits(SP_FILTER_UNITS_OBJECTBOUNDINGBOX),
24 primitiveUnits(SP_FILTER_UNITS_USERSPACEONUSE),
25 resolution_x(-1), resolution_y(-1),
26 paraller_axis(false), automatic_resolution(true)
27 {}
29 FilterUnits::FilterUnits(SPFilterUnits const filterUnits, SPFilterUnits const primitiveUnits) :
30 filterUnits(filterUnits), primitiveUnits(primitiveUnits),
31 resolution_x(-1), resolution_y(-1),
32 paraller_axis(false), automatic_resolution(true)
33 {}
35 void FilterUnits::set_ctm(Matrix const &ctm) {
36 this->ctm = ctm;
37 }
39 void FilterUnits::set_resolution(double const x_res, double const y_res) {
40 g_assert(x_res > 0);
41 g_assert(y_res > 0);
43 resolution_x = x_res;
44 resolution_y = y_res;
45 }
47 void FilterUnits::set_item_bbox(Rect const &bbox) {
48 item_bbox = bbox;
49 }
51 void FilterUnits::set_filter_area(Rect const &area) {
52 filter_area = area;
53 }
55 void FilterUnits::set_paraller(bool const paraller) {
56 paraller_axis = paraller;
57 }
59 void FilterUnits::set_automatic_resolution(bool const automatic) {
60 automatic_resolution = automatic;
61 }
63 Matrix FilterUnits::get_matrix_user2pb() const {
64 g_assert(resolution_x > 0);
65 g_assert(resolution_y > 0);
67 Matrix u2pb = ctm;
69 if (paraller_axis || !automatic_resolution) {
70 u2pb[0] = resolution_x / (filter_area.max()[X] - filter_area.min()[X]);
71 u2pb[1] = 0;
72 u2pb[2] = 0;
73 u2pb[3] = resolution_y / (filter_area.max()[Y] - filter_area.min()[Y]);
74 u2pb[4] = 0;
75 u2pb[5] = 0;
76 }
78 return u2pb;
79 }
81 Matrix FilterUnits::get_matrix_units2pb(SPFilterUnits units) const {
82 if (units == SP_FILTER_UNITS_OBJECTBOUNDINGBOX) {
83 Matrix u2pb = get_matrix_user2pb();
84 Point origo(item_bbox.min());
85 origo *= u2pb;
86 Point i_end(item_bbox.max()[X], item_bbox.min()[Y]);
87 i_end *= u2pb;
88 Point j_end(item_bbox.min()[X], item_bbox.max()[Y]);
89 j_end *= u2pb;
91 double len_i = sqrt((origo[X] - i_end[X]) * (origo[X] - i_end[X])
92 + (origo[Y] - i_end[Y]) * (origo[Y] - i_end[Y]));
93 double len_j = sqrt((origo[X] - j_end[X]) * (origo[X] - j_end[X])
94 + (origo[Y] - j_end[Y]) * (origo[Y] - j_end[Y]));
96 /* TODO: make sure that user coordinate system (0,0) is in correct
97 * place in pixblock coordinates */
98 scale scaling(1.0 / len_i, 1.0 / len_j);
99 u2pb *= scaling;
100 return u2pb;
101 } else if (units == SP_FILTER_UNITS_USERSPACEONUSE) {
102 return get_matrix_user2pb();
103 } else {
104 g_warning("Error in NR::FilterUnits::get_matrix_units2pb: unrecognized value of filterUnits");
105 return Matrix();
106 }
107 }
109 Matrix FilterUnits::get_matrix_filterunits2pb() const {
110 return get_matrix_units2pb(filterUnits);
111 }
113 Matrix FilterUnits::get_matrix_primitiveunits2pb() const {
114 return get_matrix_units2pb(primitiveUnits);
115 }
117 Matrix FilterUnits::get_matrix_display2pb() const {
118 Matrix d2pb = ctm.inverse();
119 d2pb *= get_matrix_user2pb();
120 return d2pb;
121 }
123 Matrix FilterUnits::get_matrix_pb2display() const {
124 Matrix pb2d = get_matrix_user2pb().inverse();
125 pb2d *= ctm;
126 return pb2d;
127 }
129 FilterUnits& FilterUnits::operator=(FilterUnits const &other) {
130 filterUnits = other.filterUnits;
131 primitiveUnits = other.primitiveUnits;
132 resolution_x = other.resolution_x;
133 resolution_y = other.resolution_y;
134 paraller_axis = other.paraller_axis;
135 automatic_resolution = other.automatic_resolution;
136 ctm = other.ctm;
137 item_bbox = other.item_bbox;
138 filter_area = other.filter_area;
139 return *this;
140 }
142 } // namespace NR
145 /*
146 Local Variables:
147 mode:c++
148 c-file-style:"stroustrup"
149 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
150 indent-tabs-mode:nil
151 fill-column:99
152 End:
153 */
154 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :