source: synfigstudio/trunk/fuentes/src/gui/workarearenderer/renderer_canvas.cpp @ 481

Last change on this file since 481 was 481, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 8.7 KB
Line 
1/* === S Y N F I G ========================================================= */
2/*!     \file renderer_canvas.cpp
3**      \brief Template File
4**
5**      $Id$
6**
7**      \legal
8**      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9**      Copyright (c) 2007, 2008 Chris Moore
10**  Copyright (c) 2011 Nikita Kitaev
11**
12**      This package is free software; you can redistribute it and/or
13**      modify it under the terms of the GNU General Public License as
14**      published by the Free Software Foundation; either version 2 of
15**      the License, or (at your option) any later version.
16**
17**      This package is distributed in the hope that it will be useful,
18**      but WITHOUT ANY WARRANTY; without even the implied warranty of
19**      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20**      General Public License for more details.
21**      \endlegal
22*/
23/* ========================================================================= */
24
25/* === H E A D E R S ======================================================= */
26
27#ifdef USING_PCH
28#       include "pch.h"
29#else
30#ifdef HAVE_CONFIG_H
31#       include <config.h>
32#endif
33
34#include "renderer_canvas.h"
35#include <ETL/misc>
36#include <gdkmm/general.h>
37
38#include "general.h"
39#include "app.h"
40
41#endif
42
43/* === U S I N G =========================================================== */
44
45using namespace std;
46using namespace etl;
47using namespace synfig;
48using namespace studio;
49
50/* === M A C R O S ========================================================= */
51
52/* === G L O B A L S ======================================================= */
53
54/* === P R O C E D U R E S ================================================= */
55
56/* === M E T H O D S ======================================================= */
57
58Renderer_Canvas::~Renderer_Canvas()
59{
60}
61std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >&
62Renderer_Canvas::get_tile_book()
63{
64        return get_work_area()->get_tile_book();
65}
66
67studio::WorkArea::SurfaceBook&
68Renderer_Canvas::get_cairo_book()
69{
70        return get_work_area()->get_cairo_book();
71}
72
73bool
74Renderer_Canvas::get_full_frame()const
75{
76        return get_work_area()->get_full_frame();
77}
78
79int Renderer_Canvas::get_refreshes()const
80{
81        return get_work_area()->get_refreshes();
82}
83
84bool
85Renderer_Canvas::get_canceled()const
86{
87        return get_work_area()->get_canceled();
88}
89
90bool
91Renderer_Canvas::get_queued()const
92{
93        return get_work_area()->get_queued();
94}
95
96bool
97Renderer_Canvas::get_rendering()const
98{
99        return get_work_area()->get_rendering();
100}
101
102void
103Renderer_Canvas::render_vfunc(
104        const Glib::RefPtr<Gdk::Window>& drawable,
105        const Gdk::Rectangle& /*expose_area*/
106)
107{
108        assert(get_work_area());
109        if(!get_work_area())
110                return;
111
112//      const synfig::RendDesc &rend_desc(get_work_area()->get_canvas()->rend_desc());
113
114        const synfig::Vector focus_point(get_work_area()->get_focus_point());
115
116        std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& tile_book(get_tile_book());
117        WorkArea::SurfaceBook& cairo_book(get_cairo_book());
118
119        int drawable_w = drawable->get_width();
120        int drawable_h = drawable->get_height();
121
122        // Calculate the window coordinates of the top-left
123        // corner of the canvas.
124        const synfig::Vector::value_type
125                x(focus_point[0]/get_pw()+drawable_w/2-get_w()/2),
126                y(focus_point[1]/get_ph()+drawable_h/2-get_h()/2);
127
128        /*const synfig::Vector::value_type window_startx(window_tl[0]);
129        const synfig::Vector::value_type window_endx(window_br[0]);
130        const synfig::Vector::value_type window_starty(window_tl[1]);
131        const synfig::Vector::value_type window_endy(window_br[1]);
132        */
133        const int
134                tile_w(get_work_area()->get_tile_w()),
135                tile_h(get_work_area()->get_tile_h());
136
137        const int
138                w(get_w()),
139                h(get_h());
140
141        Cairo::RefPtr<Cairo::Context> cr = drawable->create_cairo_context();
142        if(studio::App::workarea_uses_cairo)
143        {
144                if(!cairo_book.empty())
145                {
146                        if(get_full_frame())
147                        {
148                                        if(cairo_book[0].surface)
149                                        {
150                                                int div;
151                                                cr->save();
152                                                if(get_work_area()->get_low_resolution_flag())
153                                                {
154                                                        div = get_work_area()->get_low_res_pixel_size();
155                                                        cr->scale(div, div);
156                                                }
157                                                else
158                                                        div=1;
159                                                cairo_set_source_surface(cr->cobj(), cairo_book[0].surface, round_to_int(x)/div, round_to_int(y)/div);
160                                                cairo_pattern_set_filter(cairo_get_source(cr->cobj()), CAIRO_FILTER_NEAREST);
161                                                cr->paint();
162                                                cr->restore();
163                                        }
164                       
165                                if(cairo_book[0].refreshes!=get_refreshes() && get_canceled()==false && get_rendering()==false && get_queued()==false)
166                                   get_work_area()->async_update_preview();
167                        }
168                        else // tiled frame
169                        {
170                                int div= get_work_area()->get_low_res_pixel_size();;
171
172                                const int width_in_tiles(w/tile_w+(((get_work_area()->get_low_resolution_flag())?((w/div)%(tile_w/div)):(w%tile_w))?1:0));
173                                const int height_in_tiles(h/tile_h+(h%tile_h?1:0));
174                               
175                                int u(0),v(0),tx,ty;
176                                int u1(0),v1(0),u2(width_in_tiles), v2(height_in_tiles);
177                               
178                                bool needs_refresh(false);
179                               
180                                u1=int(-x/tile_w);
181                                v1=int(-y/tile_h);
182                                u2=int((-x+drawable_w)/tile_w+1);
183                                v2=int((-y+drawable_h)/tile_h+1);
184                                if(u2>width_in_tiles)u2=width_in_tiles;
185                                if(v2>height_in_tiles)v2=height_in_tiles;
186                                if(u1<0)u1=0;
187                                if(v1<0)v1=0;
188                               
189                                for(v=v1;v<v2;v++)
190                                {
191                                        for(u=u1;u<u2;u++)
192                                        {
193                                                int index=v*width_in_tiles+u;
194                                                if(int(cairo_book.size())>index && cairo_book[index].surface)
195                                                {
196                                                        cr->save();
197                                                        if(get_work_area()->get_low_resolution_flag())
198                                                        {
199                                                                div = get_work_area()->get_low_res_pixel_size();
200                                                                cr->scale(div, div);
201                                                        }
202                                                        else
203                                                                div=1;
204
205                                                        tx=u*tile_w;
206                                                        ty=v*tile_w; // not tile_h?
207                                                       
208                                                        cairo_set_source_surface(cr->cobj(), cairo_book[index].surface, (round_to_int(x)+tx)/div, (round_to_int(y)+ty)/div);
209                                                        cairo_pattern_set_filter(cairo_get_source(cr->cobj()), CAIRO_FILTER_NEAREST);
210                                                        cr->paint();
211                                                        cr->restore();
212                                                }
213                                                if(cairo_book[index].refreshes!=get_refreshes())
214                                                        needs_refresh=true;
215                                        }
216                                }
217                                if(needs_refresh==true && get_canceled()==false && get_rendering()==false && get_queued()==false)
218                                {
219                                        get_work_area()->async_update_preview();
220                                }
221                               
222                        }
223                }
224        }
225       
226        else if(!tile_book.empty())
227        {
228                if(get_full_frame())
229                {
230                        if(tile_book[0].first)
231                        {
232                                cr->save();
233                                Gdk::Cairo::set_source_pixbuf(
234                                        cr, //cairo context
235                                        tile_book[0].first, //pixbuf
236                                        round_to_int(x), round_to_int(y) //coordinates to place upper left corner of pixbuf
237                                        );
238                                cr->paint();
239                                cr->restore();
240/*
241                                drawable->draw_pixbuf(
242                                        gc, //GC
243                                        tile_book[0].first, //pixbuf
244                                        0, 0,   // Source X and Y
245                                        round_to_int(x),round_to_int(y),        // Dest X and Y
246                                        -1,-1,  // Width and Height
247                                        Gdk::RGB_DITHER_MAX,            // RgbDither
248                                        2, 2 // Dither offset X and Y
249                                        );
250*/
251                        }
252                        if(tile_book[0].second!=get_refreshes() && get_canceled()==false && get_rendering()==false && get_queued()==false)
253                                get_work_area()->async_update_preview();
254                }
255                else
256                {
257                        int div = get_work_area()->get_low_res_pixel_size();
258                        const int width_in_tiles(w/tile_w+(((get_work_area()->get_low_resolution_flag())?((w/div)%(tile_w/div)):(w%tile_w))?1:0));
259                        const int height_in_tiles(h/tile_h+(h%tile_h?1:0));
260
261                        int u(0),v(0),tx,ty;
262                        int u1(0),v1(0),u2(width_in_tiles), v2(height_in_tiles);
263
264                        bool needs_refresh(false);
265
266                        u1=int(-x/tile_w);
267                        v1=int(-y/tile_h);
268                        u2=int((-x+drawable_w)/tile_w+1);
269                        v2=int((-y+drawable_h)/tile_h+1);
270                        if(u2>width_in_tiles)u2=width_in_tiles;
271                        if(v2>height_in_tiles)v2=height_in_tiles;
272                        if(u1<0)u1=0;
273                        if(v1<0)v1=0;
274
275                        for(v=v1;v<v2;v++)
276                        {
277                                for(u=u1;u<u2;u++)
278                                {
279                                        int index=v*width_in_tiles+u;
280                                        if(int(tile_book.size())>index && tile_book[index].first)
281                                        {
282                                                tx=u*tile_w;
283                                                ty=v*tile_w;
284
285                                                cr->save();
286                                                Gdk::Cairo::set_source_pixbuf(
287                                                        cr, //cairo context
288                                                        tile_book[index].first, //pixbuf
289                                                        round_to_int(x)+tx, round_to_int(y)+ty //coordinates to place upper left corner of pixbuf
290                                                        );
291                                                cr->paint();
292                                                cr->restore();
293/*
294
295                                                drawable->draw_pixbuf(
296                                                        gc, //GC
297                                                        tile_book[index].first, //pixbuf
298                                                        0, 0,   // Source X and Y
299                                                        round_to_int(x)+tx,round_to_int(y)+ty,  // Dest X and Y
300                                                        -1,-1,  // Width and Height
301                                                        Gdk::RGB_DITHER_MAX,            // RgbDither
302                                                        2, 2 // Dither offset X and Y
303                                                        );
304*/
305                                        }
306                                        if(tile_book[index].second!=get_refreshes())
307                                                needs_refresh=true;
308                                }
309                        }
310                        if(needs_refresh==true && get_canceled()==false && get_rendering()==false && get_queued()==false)
311                        {
312                                //queue_render_preview();
313                                get_work_area()->async_update_preview();
314                                //update_preview();
315                                //return true;
316                        }
317
318                }
319        }
320
321        // Draw the border around the rendered region
322        {
323                cr->save();
324
325                cr->set_line_cap(Cairo::LINE_CAP_BUTT);
326                cr->set_line_join(Cairo::LINE_JOIN_MITER);
327                cr->set_antialias(Cairo::ANTIALIAS_NONE);
328
329                cr->set_line_width(1.0);
330                cr->set_source_rgb(0,0,0);
331
332                cr->rectangle(
333                        round_to_int(x), round_to_int(y),
334                        w, h
335                        );
336
337                cr->stroke();
338
339                cr->restore();
340        }
341}
Note: See TracBrowser for help on using the repository browser.