Code

Extensions. Fix Color Markers extension (crashed when a fill or stroke attribute...
[inkscape.git] / src / display / nr-arena.cpp
1 #define __NR_ARENA_C__
3 /*
4  * RGBA display list system for inkscape
5  *
6  * Author:
7  *   Lauris Kaplinski <lauris@kaplinski.com>
8  *
9  * Copyright (C) 2001-2002 Lauris Kaplinski
10  * Copyright (C) 2001 Ximian, Inc.
11  *
12  * Released under GNU GPL, read the file 'COPYING' for more information
13  */
15 #include "nr-arena-item.h"
16 #include "nr-arena.h"
17 #include "nr-filter-gaussian.h"
18 #include "nr-filter-types.h"
19 #include <libnr/nr-blit.h>
20 #include "preferences.h"
21 #include "color.h"
23 static void nr_arena_class_init (NRArenaClass *klass);
24 static void nr_arena_init (NRArena *arena);
25 static void nr_arena_finalize (NRObject *object);
27 static NRActiveObjectClass *parent_class;
29 NRType
30 nr_arena_get_type (void)
31 {
32     static NRType type = 0;
33     if (!type) {
34         type = nr_object_register_type (NR_TYPE_ACTIVE_OBJECT,
35                                         "NRArena",
36                                         sizeof (NRArenaClass),
37                                         sizeof (NRArena),
38                                         (void (*) (NRObjectClass *)) nr_arena_class_init,
39                                         (void (*) (NRObject *)) nr_arena_init);
40     }
41     return type;
42 }
44 static void
45 nr_arena_class_init (NRArenaClass *klass)
46 {
47     NRObjectClass *object_class = (NRObjectClass *) klass;
49     parent_class = (NRActiveObjectClass *) (((NRObjectClass *) klass)->parent);
51     object_class->finalize = nr_arena_finalize;
52     object_class->cpp_ctor = NRObject::invoke_ctor<NRArena>;
53 }
55 static void
56 nr_arena_init (NRArena *arena)
57 {
58     arena->delta = 0; // to be set by desktop from prefs
59     arena->renderoffscreen = false; // use render values from preferences otherwise render exact
60     arena->rendermode = Inkscape::RENDERMODE_NORMAL; // default is normal render
61     arena->blurquality = BLUR_QUALITY_NORMAL;
62     arena->filterquality = Inkscape::Filters::FILTER_QUALITY_NORMAL;
63     arena->outlinecolor = 0xff; // black; to be set by desktop from bg color
64     arena->canvasarena = NULL;
65 }
67 static void
68 nr_arena_finalize (NRObject *object)
69 {
70     ((NRObjectClass *) (parent_class))->finalize (object);
71 }
73 void
74 nr_arena_request_update (NRArena *arena, NRArenaItem *item)
75 {
76     NRActiveObject *aobject = (NRActiveObject *) arena;
78     nr_return_if_fail (arena != NULL);
79     nr_return_if_fail (NR_IS_ARENA (arena));
80     nr_return_if_fail (item != NULL);
81     nr_return_if_fail (NR_IS_ARENA_ITEM (item));
82     // setup render parameter
83     if (arena->renderoffscreen == false) {
84         Inkscape::Preferences *prefs = Inkscape::Preferences::get();
85         arena->blurquality = prefs->getInt("/options/blurquality/value", 0);
86         arena->filterquality = prefs->getInt("/options/filterquality/value", 0);
87     } else {
88         arena->blurquality =  BLUR_QUALITY_BEST;
89         arena->filterquality = Inkscape::Filters::FILTER_QUALITY_BEST;
90         arena->rendermode = Inkscape::RENDERMODE_NORMAL;
91     }
93     if (aobject->callbacks) {
94         for (unsigned int i = 0; i < aobject->callbacks->length; i++) {
95             NRObjectListener *listener = aobject->callbacks->listeners + i;
96             NRArenaEventVector *avector = (NRArenaEventVector *) listener->vector;
97             if ((listener->size >= sizeof (NRArenaEventVector)) && avector->request_update) {
98                 avector->request_update (arena, item, listener->data);
99             }
100         }
101     }
104 void
105 nr_arena_request_render_rect (NRArena *arena, NRRectL *area)
107     NRActiveObject *aobject = (NRActiveObject *) arena;
109     nr_return_if_fail (arena != NULL);
110     nr_return_if_fail (NR_IS_ARENA (arena));
111     nr_return_if_fail (area != NULL);
113     // setup render parameter
114     if (arena->renderoffscreen == false) {
115         Inkscape::Preferences *prefs = Inkscape::Preferences::get();
116         arena->blurquality = prefs->getInt("/options/blurquality/value", 0);
117         arena->filterquality = prefs->getInt("/options/filterquality/value", 0);
118     } else {
119         arena->blurquality =  BLUR_QUALITY_BEST;
120         arena->filterquality = Inkscape::Filters::FILTER_QUALITY_BEST;
121         arena->rendermode = Inkscape::RENDERMODE_NORMAL;
122     }
123     if (aobject->callbacks && area && !nr_rect_l_test_empty_ptr(area)) {
124         for (unsigned int i = 0; i < aobject->callbacks->length; i++) {
125             NRObjectListener *listener = aobject->callbacks->listeners + i;
126             NRArenaEventVector *avector = (NRArenaEventVector *) listener->vector;
127             if ((listener->size >= sizeof (NRArenaEventVector)) && avector->request_render) {
128                 avector->request_render (arena, area, listener->data);
129             }
130         }
131     }
134 void
135 nr_arena_render_paintserver_fill (NRPixBlock *pb, NRRectL *area, SPPainter *painter, float opacity, NRPixBlock *mask)
137     NRPixBlock cb, cb_opa;
138     nr_pixblock_setup_fast (&cb, NR_PIXBLOCK_MODE_R8G8B8A8N, area->x0, area->y0, area->x1, area->y1, TRUE);
139     nr_pixblock_setup_fast (&cb_opa, NR_PIXBLOCK_MODE_R8G8B8A8N, area->x0, area->y0, area->x1, area->y1, TRUE);
141     // if memory allocation failed, abort
142     if ((cb.size != NR_PIXBLOCK_SIZE_TINY && cb.data.px == NULL) || (cb_opa.size != NR_PIXBLOCK_SIZE_TINY && cb_opa.data.px == NULL)) {
143         return;
144     }
146     cb.visible_area = pb->visible_area;
147     cb_opa.visible_area = pb->visible_area;
149     /* Need separate gradient buffer (lauris)*/
150     // do the filling
151     painter->fill (painter, &cb);
152     cb.empty = FALSE;
154     // do the fill-opacity and mask composite
155     if (opacity < 1.0) {
156         nr_blit_pixblock_pixblock_alpha (&cb_opa, &cb, (int) floor (255 * opacity));
157         cb_opa.empty = FALSE;
158         nr_blit_pixblock_pixblock_mask (pb, &cb_opa, mask);
159     } else {
160         nr_blit_pixblock_pixblock_mask (pb, &cb, mask);
161     }
163     pb->empty = FALSE;
165     nr_pixblock_release (&cb);
166     nr_pixblock_release (&cb_opa);
169 /**
170     set arena to offscreen mode
171     rendering will be exact
172     @param arena NRArena object
173 */
174 void
175 nr_arena_set_renderoffscreen (NRArena *arena)
177     nr_return_if_fail (arena != NULL);
178     nr_return_if_fail (NR_IS_ARENA (arena));
180     // the real assignment to the quality indicators is in the update function
181     arena->renderoffscreen = true;
185 #define FLOAT_TO_UINT8(f) (int(f*255))
186 #define RGBA_R(v) ((v) >> 24)
187 #define RGBA_G(v) (((v) >> 16) & 0xff)
188 #define RGBA_B(v) (((v) >> 8) & 0xff)
189 #define RGBA_A(v) ((v) & 0xff)
191 void nr_arena_separate_color_plates(guint32* rgba){
192     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
193     bool render_cyan = prefs->getBool("/options/printcolorspreview/cyan", true);
194     bool render_magenta = prefs->getBool("/options/printcolorspreview/magenta", true);
195     bool render_yellow = prefs->getBool("/options/printcolorspreview/yellow", true);
196     bool render_black = prefs->getBool("/options/printcolorspreview/black", true);
198     float rgb_v[3];
199     float cmyk_v[4];
200     sp_color_rgb_to_cmyk_floatv (cmyk_v, RGBA_R(*rgba)/256.0, RGBA_G(*rgba)/256.0, RGBA_B(*rgba)/256.0); 
201     sp_color_cmyk_to_rgb_floatv (rgb_v, render_cyan ? cmyk_v[0] : 0,
202                                         render_magenta ? cmyk_v[1] : 0,
203                                         render_yellow ? cmyk_v[2] : 0,
204                                         render_black ? cmyk_v[3] : 0);
205     *rgba = (FLOAT_TO_UINT8(rgb_v[0])<<24) + (FLOAT_TO_UINT8(rgb_v[1])<<16) + (FLOAT_TO_UINT8(rgb_v[2])<<8) + 0xff;
208 /*
209   Local Variables:
210   mode:c++
211   c-file-style:"stroustrup"
212   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
213   indent-tabs-mode:nil
214   fill-column:99
215   End:
216 */
217 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :