~ubuntu-branches/ubuntu/trusty/python-enable/trusty

« back to all changes in this revision

Viewing changes to enthought/kiva/agg/src/kiva_gradient.h

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2010-02-28 14:56:36 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100228145636-9ghfhe3uy37tt3q6
Tags: 3.3.0-1
* New upstream release
* Bump Standards-Version to 3.8.4
* Switch to source format 3.0
* Update patches/freetype2.diff

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
#include "agg_span_interpolator_linear.h"
16
16
#include "agg_renderer_mclip.h"
17
17
 
 
18
#include "kiva_affine_helpers.h"
18
19
#include "kiva_constants.h"
19
20
 
20
21
namespace kiva
41
42
        std::vector<gradient_stop> stops;
42
43
        gradient_type_e gradient_type;
43
44
        gradient_spread_e spread_method;
44
 
 
 
45
        gradient_units_e units;
 
46
 
 
47
        private:
 
48
        agg::trans_affine affine_mtx;
 
49
 
 
50
        public:
45
51
        gradient(gradient_type_e gradient_type);
46
52
        gradient(gradient_type_e gradient_type,
47
53
                std::vector<point> points,
48
54
                std::vector<gradient_stop> stops,
49
 
                const char* spread_method);
 
55
                const char* spread_method,
 
56
                const char* units="userSpaceOnUse");
50
57
        ~gradient();
51
58
 
52
59
        template <typename pixfmt_type>
59
66
                if (this->points[0].first == this->points[1].first)
60
67
                {
61
68
                    agg::gradient_y grad_func;
62
 
                    this->_apply(pixfmt, ras, rbase, grad_func);
 
69
 
 
70
                    // apply the proper fill adapter based on the spread method
 
71
 
 
72
                    if (this->spread_method == kiva::reflect)
 
73
                    {
 
74
                        agg::gradient_reflect_adaptor<agg::gradient_y> adaptor(grad_func);
 
75
                        this->_apply(pixfmt, ras, rbase, adaptor);
 
76
                    }
 
77
                    else if (this->spread_method == kiva::repeat)
 
78
                    {
 
79
                        agg::gradient_repeat_adaptor<agg::gradient_y> adaptor(grad_func);
 
80
                        this->_apply(pixfmt, ras, rbase, adaptor);
 
81
                    }
 
82
                    else
 
83
                    {
 
84
                        this->_apply(pixfmt, ras, rbase, grad_func);
 
85
                    }
63
86
                }
64
87
                else if (this->points[0].second == this->points[1].second)
65
88
                {
66
89
                    agg::gradient_x grad_func;
67
 
                    this->_apply(pixfmt, ras, rbase, grad_func);
 
90
 
 
91
                    // apply the proper fill adapter based on the spread method
 
92
 
 
93
                    if (this->spread_method == kiva::reflect)
 
94
                    {
 
95
                        agg::gradient_reflect_adaptor<agg::gradient_x> adaptor(grad_func);
 
96
                        this->_apply(pixfmt, ras, rbase, adaptor);
 
97
                    }
 
98
                    else if (this->spread_method == kiva::repeat)
 
99
                    {
 
100
                        agg::gradient_repeat_adaptor<agg::gradient_x> adaptor(grad_func);
 
101
                        this->_apply(pixfmt, ras, rbase, adaptor);
 
102
                    }
 
103
                    else
 
104
                    {
 
105
                        this->_apply(pixfmt, ras, rbase, grad_func);
 
106
                    }
68
107
                }
69
108
                else
70
109
                {
71
110
                    agg::gradient_x grad_func;
72
 
                    this->_apply(pixfmt, ras, rbase, grad_func);
 
111
 
 
112
                    // apply the proper fill adapter based on the spread method
 
113
 
 
114
                    if (this->spread_method == kiva::reflect)
 
115
                    {
 
116
                        agg::gradient_reflect_adaptor<agg::gradient_x> adaptor(grad_func);
 
117
                        this->_apply(pixfmt, ras, rbase, adaptor);
 
118
                    }
 
119
                    else if (this->spread_method == kiva::repeat)
 
120
                    {
 
121
                        agg::gradient_repeat_adaptor<agg::gradient_x> adaptor(grad_func);
 
122
                        this->_apply(pixfmt, ras, rbase, adaptor);
 
123
                    }
 
124
                    else
 
125
                    {
 
126
                        this->_apply(pixfmt, ras, rbase, grad_func);
 
127
                    }
73
128
                }
74
129
            }
75
130
            else
77
132
                agg::gradient_radial_focus grad_func(points[1].first,
78
133
                                                                                points[2].first - points[0].first,
79
134
                                                                                points[2].second - points[0].second);
80
 
                this->_apply(pixfmt, ras, rbase, grad_func);
 
135
 
 
136
                if (this->spread_method == kiva::reflect)
 
137
                {
 
138
                        agg::gradient_reflect_adaptor<agg::gradient_radial_focus> adaptor(grad_func);
 
139
                    this->_apply(pixfmt, ras, rbase, adaptor);
 
140
                }
 
141
                else if (this->spread_method == kiva::repeat)
 
142
                {
 
143
                        agg::gradient_repeat_adaptor<agg::gradient_radial_focus> adaptor(grad_func);
 
144
                    this->_apply(pixfmt, ras, rbase, adaptor);
 
145
                }
 
146
                else
 
147
                {
 
148
                        this->_apply(pixfmt, ras, rbase, grad_func);
 
149
                }
81
150
            }
82
151
        }
83
152
 
 
153
        void set_ctm(const agg::trans_affine& mtx)
 
154
        {
 
155
                this->affine_mtx = mtx;
 
156
        }
 
157
 
84
158
        protected:
85
159
 
86
160
        template <class pixfmt_type, class gradient_func_type>
116
190
            double d1 = 0;
117
191
            double d2 = sqrt(dx * dx + dy * dy);
118
192
 
 
193
            if (this->units == kiva::user_space)
 
194
            {
 
195
                gradient_mtx *= this->affine_mtx;
 
196
 
 
197
                // scale the translation part of the transform, otherwise Agg
 
198
                // will draw the gradient at the wrong location
 
199
 
 
200
                double x, y, scale_x, scale_y;
 
201
                kiva::get_translation(this->affine_mtx, &x, &y);
 
202
                kiva::get_scale(this->affine_mtx, &scale_x, &scale_y);
 
203
                double scaled_trans_x = x*scale_x;
 
204
                double scaled_trans_y = -y*scale_y;
 
205
 
 
206
//              std::cout << "translations: " << x << ", " << y << std::endl;
 
207
//              std::cout << "scaled: " << scale_x << ", " << scale_y << std::endl;
 
208
//              std::cout << "scaled translations: " << scaled_trans_x << ", " << scaled_trans_y << std::endl;
 
209
 
 
210
                double temp[6];
 
211
                gradient_mtx.store_to(temp);
 
212
                temp[4] = scaled_trans_x;
 
213
                temp[5] = scaled_trans_y;
 
214
                gradient_mtx.load_from(temp);
 
215
            }
 
216
 
 
217
//            std::cout << "starting with affine matrix " << gradient_mtx.m0
 
218
//                                        << ", " << gradient_mtx.m1
 
219
//                                        << ", " << gradient_mtx.m2
 
220
//                                        << ", " << gradient_mtx.m3
 
221
//                                        << ", " << gradient_mtx.m4
 
222
//                                        << ", " << gradient_mtx.m5 << std::endl;
 
223
 
 
224
            gradient_mtx *= agg::trans_affine_translation(-points[0].first, -points[0].second);
 
225
 
119
226
            if ((this->gradient_type == kiva::grad_radial) && (this->points.size() >2))
120
227
            {
121
228
                d2 = points[1].first;
122
 
                gradient_mtx *= agg::trans_affine_translation(-points[0].first, -points[0].second);
123
229
                                // TOOD: apply scaling transform here, determined by dx and dy of the bounding box,
124
230
                // if appropriate
125
231
            }
127
233
            {
128
234
                if (points[0].first == points[1].first)
129
235
                {
130
 
                    gradient_mtx *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / (d2-d1));
131
 
                    gradient_mtx *= agg::trans_affine_rotation(atan2(dx, dy));
132
 
                    gradient_mtx *= agg::trans_affine_translation(-points[0].first, -points[0].second);
 
236
                        gradient_mtx *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / (d2-d1));
 
237
                        gradient_mtx *= agg::trans_affine_rotation(atan2(dx, dy));
133
238
                }
134
239
                else if (points[0].second == points[1].second)
135
240
                {
136
241
                        // No need to rotate
137
 
                    gradient_mtx *= agg::trans_affine_translation(-points[0].first, -points[0].second);
138
242
                }
139
243
                else
140
244
                {
141
245
                        // general case: scale, rotate and translate
142
246
                    gradient_mtx *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / (d2-d1));
143
247
                    gradient_mtx *= agg::trans_affine_rotation(atan2(-dy, dx));
144
 
                    gradient_mtx *= agg::trans_affine_translation(-points[0].first, -points[0].second);
145
248
                }
146
249
            }
147
250
 
 
251
//            std::cout << "drawing with affine matrix " << gradient_mtx.m0
 
252
//                                        << ", " << gradient_mtx.m1
 
253
//                                        << ", " << gradient_mtx.m2
 
254
//                                        << ", " << gradient_mtx.m3
 
255
//                                        << ", " << gradient_mtx.m4
 
256
//                                        << ", " << gradient_mtx.m5 << std::endl;
 
257
 
148
258
            span_gradient_type span_gradient(span_interpolator,
149
259
                                            gradient_func,
150
260
                                            color_array,
187
297
                    offset = i/double(array.size());
188
298
                }
189
299
            }
190
 
 
191
 
            if (this->spread_method == kiva::pad)
192
 
            {
193
 
                for (; i < array.size(); i++)
194
 
                {
195
 
                    array[i] = this->stops.back().color;
196
 
                }
197
 
            }
198
 
            else if (this->spread_method == kiva::reflect)
199
 
            {
200
 
                // TODO: handle 'reflect' spread method
201
 
            }
202
 
            else
203
 
            {
204
 
                // TODO: handle 'repeat' spread method
205
 
            }
206
300
        }
207
301
    };
208
302
}