Code

2c84800d69c20ab57bb9b9e37aa5ab6a28375924
[inkscape.git] / src / display / nr-filter-units.cpp
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     }
109 Matrix FilterUnits::get_matrix_filterunits2pb() const {
110     return get_matrix_units2pb(filterUnits);
113 Matrix FilterUnits::get_matrix_primitiveunits2pb() const {
114     return get_matrix_units2pb(primitiveUnits);
117 Matrix FilterUnits::get_matrix_display2pb() const {
118     Matrix d2pb = ctm.inverse();
119     d2pb *= get_matrix_user2pb();
120     return d2pb;
123 Matrix FilterUnits::get_matrix_pb2display() const {
124     Matrix pb2d = get_matrix_user2pb().inverse();
125     pb2d *= ctm;
126     return pb2d;
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;
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 :