diff options
71 files changed, 220 insertions, 3799 deletions
diff --git a/src/dialogs/clonetiler.cpp b/src/dialogs/clonetiler.cpp index 55884fe4a..00557ad16 100644 --- a/src/dialogs/clonetiler.cpp +++ b/src/dialogs/clonetiler.cpp @@ -46,6 +46,7 @@ #include "../verbs.h" #include "widgets/icon.h" #include "xml/repr.h" +#include "libnr/nr-pixblock.h" #define MIN_ONSCREEN_DISTANCE 50 diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert index 3e8b6ff91..843f5aa8f 100644 --- a/src/display/Makefile_insert +++ b/src/display/Makefile_insert @@ -91,17 +91,13 @@ ink_common_sources += \ display/nr-light.h \ display/nr-light-types.h \ display/nr-plain-stuff.cpp \ + display/nr-plain-stuff.h \ display/nr-plain-stuff-gdk.cpp \ display/nr-plain-stuff-gdk.h \ - display/nr-plain-stuff.h \ display/nr-style.cpp \ display/nr-style.h \ display/nr-svgfonts.cpp \ display/nr-svgfonts.h \ - display/pixblock-scaler.cpp \ - display/pixblock-scaler.h \ - display/pixblock-transform.cpp \ - display/pixblock-transform.h \ display/rendermode.h \ display/snap-indicator.cpp \ display/snap-indicator.h \ diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 25a1e7988..15fceedae 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -457,6 +457,32 @@ ink_cairo_surface_get_height(cairo_surface_t *surface) return cairo_image_surface_get_height(surface); } +cairo_pattern_t * +ink_cairo_pattern_create_checkerboard() +{ + int const w = 8; + int const h = 8; + + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2*w, 2*h); + + cairo_t *ct = cairo_create(s); + cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE); + cairo_set_source_rgb(ct, 0.75, 0.75, 0.75); + cairo_paint(ct); + cairo_set_source_rgb(ct, 0.5, 0.5, 0.5); + cairo_rectangle(ct, 0, 0, w, h); + cairo_rectangle(ct, w, h, w, h); + cairo_fill(ct); + cairo_destroy(ct); + + cairo_pattern_t *p = cairo_pattern_create_for_surface(s); + cairo_pattern_set_extend(p, CAIRO_EXTEND_REPEAT); + cairo_pattern_set_filter(p, CAIRO_FILTER_NEAREST); + + cairo_surface_destroy(s); + return p; +} + /** * @brief Convert pixel data from GdkPixbuf format to ARGB. * This will convert pixel data from GdkPixbuf format to Cairo's native pixel format. diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index 5ac546067..f74ceed14 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -96,6 +96,8 @@ void ink_cairo_surface_blit(cairo_surface_t *src, cairo_surface_t *dest); int ink_cairo_surface_get_width(cairo_surface_t *surface); int ink_cairo_surface_get_height(cairo_surface_t *surface); +cairo_pattern_t *ink_cairo_pattern_create_checkerboard(); + void convert_pixels_pixbuf_to_argb32(guchar *data, int w, int h, int rs); void convert_pixels_argb32_to_pixbuf(guchar *data, int w, int h, int rs); void convert_pixbuf_normal_to_argb32(GdkPixbuf *); diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index db8e1757c..6f85573d1 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -14,7 +14,6 @@ #include <gtk/gtksignal.h> -#include "libnr/nr-blit.h" #include "display/display-forward.h" #include "display/sp-canvas-util.h" #include "helper/sp-marshal.h" @@ -22,6 +21,7 @@ #include "display/nr-arena-group.h" #include "display/canvas-arena.h" #include "display/cairo-utils.h" +#include "libnr/nr-pixblock.h" enum { ARENA_EVENT, diff --git a/src/display/nr-3dutils.cpp b/src/display/nr-3dutils.cpp index 89c21940a..1d92d3ec9 100644 --- a/src/display/nr-3dutils.cpp +++ b/src/display/nr-3dutils.cpp @@ -11,134 +11,15 @@ #include <glib/gmessages.h> -#include "libnr/nr-pixblock.h" #include "display/nr-3dutils.h" #include <cmath> +#include <2geom/point.h> +#include <2geom/matrix.h> namespace NR { -#define BEGIN 0 // TOP or LEFT -#define MIDDLE 1 -#define END 2 // BOTTOM or RIGHT - -#define START(v) ((v)==BEGIN? 1 : 0) -#define FINISH(v) ((v)==END? 1 : 2) - -signed char K_X[3][3][3][3] = { - //K_X[TOP] - { - //K_X[TOP][LEFT] - { - { 0, 0, 0}, - { 0, -2, 2}, - { 0, -1, 1} - }, - { - { 0, 0, 0}, - {-2, 0, 2}, - {-1, 0, 1} - }, - { - { 0, 0, 0}, - {-2, 2, 0}, - {-1, 1, 0} - } - }, - //K_X[MIDDLE] - { - //K_X[MIDDLE][LEFT] - { - { 0, -1, 1}, - { 0, -2, 2}, - { 0, -1, 1} - }, - { - {-1, 0, 1}, - {-2, 0, 2}, - {-1, 0, 1} - }, - { - {-1, 1, 0}, - {-2, 2, 0}, - {-1, 1, 0} - } - }, - //K_X[BOTTOM] - { - //K_X[BOTTOM][LEFT] - { - { 0, -1, 1}, - { 0, -2, 2}, - { 0, 0, 0} - }, - { - {-1, 0, 1}, - {-2, 0, 2}, - { 0, 0, 0} - }, - { - {-1, 1, 0}, - {-2, 2, 0}, - { 0, 0, 0} - } - } -}; - -//K_Y is obtained by transposing K_X globally and each of its components - -gdouble FACTOR_X[3][3] = { - {2./3, 1./3, 2./3}, - {1./2, 1./4, 1./2}, - {2./3, 1./3, 2./3} -}; - -//FACTOR_Y is obtained by transposing FACTOR_X - -inline -int get_carac(int i, int len, int delta) { - if (i < delta) - return BEGIN; - else if (i > len - 1 - delta) - return END; - else - return MIDDLE; -} - -//assumes in is RGBA -//should be made more resistant -void compute_surface_normal(Fvector &N, gdouble ss, NRPixBlock *in, int i, int j, int dx, int dy) { - int w = in->area.x1 - in->area.x0; - int h = in->area.y1 - in->area.y0; - int k, l, alpha_idx, alpha_idx_y; - int x_carac, y_carac; - gdouble alpha; - gdouble accu_x; - gdouble accu_y; - unsigned char *data = NR_PIXBLOCK_PX (in); - g_assert(NR_PIXBLOCK_BPP(in) == 4); - x_carac = get_carac(j, w, dx); //LEFT, MIDDLE or RIGHT - y_carac = get_carac(i, h, dy); //TOP, MIDDLE or BOTTOM - alpha_idx = 4*(i*w + j); - accu_x = 0; - accu_y = 0; - for (k = START(y_carac); k <= FINISH(y_carac); k++) { - alpha_idx_y = alpha_idx + 4*(k-1)*dy*w; - for (l = START(x_carac); l <= FINISH(x_carac); l++) { - alpha = (data + alpha_idx_y + 4*dx*(l-1))[3]; - accu_x += K_X[y_carac][x_carac][k][l] * alpha; - accu_y += K_X[x_carac][y_carac][l][k] * alpha; - } - } - ss /= 255.0; // Correction for scale of pixel values - N[X_3D] = -ss * FACTOR_X[y_carac][x_carac] * accu_x / dx; - N[Y_3D] = -ss * FACTOR_X[x_carac][y_carac] * accu_y / dy; - N[Z_3D] = 1.0; - normalize_vector(N); - //std::cout << "(" << N[X_3D] << ", " << N[Y_3D] << ", " << N[Z_3D] << ")" << std::endl; -} - void convert_coord(gdouble &x, gdouble &y, gdouble &z, Geom::Matrix const &trans) { - Point p = Point(x, y); + Geom::Point p = Geom::Point(x, y); p *= trans; x = p[Geom::X]; y = p[Geom::Y]; diff --git a/src/display/nr-3dutils.h b/src/display/nr-3dutils.h index 42df36c82..9a198a73d 100644 --- a/src/display/nr-3dutils.h +++ b/src/display/nr-3dutils.h @@ -81,22 +81,6 @@ gdouble scalar_product(const Fvector &a, const Fvector &b); void normalized_sum(Fvector &r, const Fvector &a, const Fvector &b); /** - * Computes the unit suface normal vector of surface given by "in" at (i, j) - * and store it into N. "in" is a (NRPixBlock *) in mode RGBA but only the alpha - * channel is considered as a bump map. ss is the altitude when for the alpha - * value 255. dx and dy are the deltas used to compute in our discrete setting - * - * \param N a reference to a Fvector in which we store the unit surface normal - * \param ss the surface scale - * \param in a NRPixBlock * whose alpha channel codes the surface - * \param i the x coordinate of the point at which we compute the normal - * \param j the y coordinate of the point at which we compute the normal - * \param dx the delta used in the x coordinate - * \param dy the delta used in the y coordinate - */ -void compute_surface_normal(Fvector &N, gdouble ss, NRPixBlock *in, int i, int j, int dx, int dy); - -/** * Applies the transformation matrix to (x, y, z). This function assumes that * trans[0] = trans[3]. x and y are transformed according to trans, z is * multiplied by trans[0]. diff --git a/src/display/nr-arena-glyphs.cpp b/src/display/nr-arena-glyphs.cpp index faf10bd38..d35489d70 100644 --- a/src/display/nr-arena-glyphs.cpp +++ b/src/display/nr-arena-glyphs.cpp @@ -16,7 +16,6 @@ #ifdef HAVE_CONFIG_H # include <config.h> #endif -#include "libnr/nr-blit.h" #include "libnr/nr-convert2geom.h" #include <2geom/matrix.h> #include "style.h" diff --git a/src/display/nr-arena-image.cpp b/src/display/nr-arena-image.cpp index 066133dde..5617bb084 100644 --- a/src/display/nr-arena-image.cpp +++ b/src/display/nr-arena-image.cpp @@ -12,9 +12,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <libnr/nr-compose-transform.h> #include <2geom/transforms.h> -#include <libnr/nr-blit.h> #include "../preferences.h" #include "nr-arena-image.h" #include "style.h" diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp index e7cf08722..0bdbd12ae 100644 --- a/src/display/nr-arena-item.cpp +++ b/src/display/nr-arena-item.cpp @@ -19,8 +19,6 @@ #include <string> #include <cairomm/cairomm.h> -#include <libnr/nr-blit.h> -#include <libnr/nr-pixops.h> #include "display/cairo-utils.h" #include "nr-arena.h" #include "nr-arena-item.h" @@ -317,7 +315,7 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); bool filter = (item->arena->rendermode != Inkscape::RENDERMODE_OUTLINE && item->arena->rendermode != Inkscape::RENDERMODE_NO_FILTERS); - bool print_colors = (item->arena->rendermode == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW); + //bool print_colors = (item->arena->rendermode == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW); nr_return_val_if_fail (item != NULL, NR_ARENA_ITEM_STATE_INVALID); nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), @@ -375,193 +373,6 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area return item->state | NR_ARENA_ITEM_STATE_RENDER; } -#if 0 - NRPixBlock *dpb = pb; - - /* Determine, whether we need temporary buffer */ -/* if (item->clip || item->mask - || ((item->opacity != 255) && !item->render_opacity) - || (item->filter && filter) || item->background_new - || (item->parent && item->parent->background_pb))*/ - if (0) { - - /* Setup and render item buffer */ - NRPixBlock ipb; - nr_pixblock_setup_fast (&ipb, NR_PIXBLOCK_MODE_R8G8B8A8P, - carea.x0, carea.y0, carea.x1, carea.y1, - TRUE); - - // if memory allocation failed, abort render - if (ipb.size != NR_PIXBLOCK_SIZE_TINY && ipb.data.px == NULL) { - nr_pixblock_release (&ipb); - return (item->state); - } - - /* If background access is used, save the pixblock address. - * This address is set to NULL at the end of this block */ - if (item->background_new || - (item->parent && item->parent->background_pb)) { - item->background_pb = &ipb; - } - - ipb.visible_area = pb->visible_area; - if (item->filter && filter) { - item->filter->area_enlarge (ipb.visible_area, item); - } - - unsigned int state = NR_ARENA_ITEM_VIRTUAL (item, render) (ct, item, &carea, &ipb, flags); - if (state & NR_ARENA_ITEM_STATE_INVALID) { - /* Clean up and return error */ - nr_pixblock_release (&ipb); - if (dpb != pb) - nr_pixblock_release (dpb); - item->state |= NR_ARENA_ITEM_STATE_INVALID; - return item->state; - } - ipb.empty = FALSE; - - /* Run filtering, if a filter is set for this object */ - if (item->filter && filter) { - item->filter->render (item, &ipb); - } - - if (item->clip || item->mask) { - /* Setup mask pixblock */ - NRPixBlock mpb; - nr_pixblock_setup_fast (&mpb, NR_PIXBLOCK_MODE_A8, carea.x0, - carea.y0, carea.x1, carea.y1, TRUE); - - if (mpb.data.px != NULL) { // if memory allocation was successful - - mpb.visible_area = pb->visible_area; - /* Do clip if needed */ - if (item->clip) { - state = nr_arena_item_invoke_clip (item->clip, &carea, &mpb); - if (state & NR_ARENA_ITEM_STATE_INVALID) { - /* Clean up and return error */ - nr_pixblock_release (&mpb); - nr_pixblock_release (&ipb); - if (dpb != pb) - nr_pixblock_release (dpb); - item->state |= NR_ARENA_ITEM_STATE_INVALID; - return item->state; - } - mpb.empty = FALSE; - } - /* Do mask if needed */ - if (item->mask) { - NRPixBlock tpb; - /* Set up yet another temporary pixblock */ - nr_pixblock_setup_fast (&tpb, NR_PIXBLOCK_MODE_R8G8B8A8N, - carea.x0, carea.y0, carea.x1, - carea.y1, TRUE); - - if (tpb.data.px != NULL) { // if memory allocation was successful - - tpb.visible_area = pb->visible_area; - unsigned int state = NR_ARENA_ITEM_VIRTUAL (item->mask, render) (ct, item->mask, &carea, &tpb, flags); - if (state & NR_ARENA_ITEM_STATE_INVALID) { - /* Clean up and return error */ - nr_pixblock_release (&tpb); - nr_pixblock_release (&mpb); - nr_pixblock_release (&ipb); - if (dpb != pb) - nr_pixblock_release (dpb); - item->state |= NR_ARENA_ITEM_STATE_INVALID; - return item->state; - } - /* Composite with clip */ - if (item->clip) { - int x, y; - for (y = carea.y0; y < carea.y1; y++) { - unsigned char *s, *d; - s = NR_PIXBLOCK_PX (&tpb) + (y - - carea.y0) * tpb.rs; - d = NR_PIXBLOCK_PX (&mpb) + (y - - carea.y0) * mpb.rs; - for (x = carea.x0; x < carea.x1; x++) { - unsigned int m; - m = NR_PREMUL_112 (s[0] + s[1] + s[2], s[3]); - d[0] = - FAST_DIV_ROUND < 3 * 255 * 255 > - (NR_PREMUL_123 (d[0], m)); - s += 4; - d += 1; - } - } - } else { - int x, y; - for (y = carea.y0; y < carea.y1; y++) { - unsigned char *s, *d; - s = NR_PIXBLOCK_PX (&tpb) + (y - - carea.y0) * tpb.rs; - d = NR_PIXBLOCK_PX (&mpb) + (y - - carea.y0) * mpb.rs; - for (x = carea.x0; x < carea.x1; x++) { - unsigned int m; - m = NR_PREMUL_112 (s[0] + s[1] + s[2], s[3]); - d[0] = FAST_DIV_ROUND < 3 * 255 > (m); - s += 4; - d += 1; - } - } - mpb.empty = FALSE; - } - } - nr_pixblock_release (&tpb); - } - /* Multiply with opacity if needed */ - if ((item->opacity != 255) && !item->render_opacity - ) { - int x, y; - unsigned int a; - a = item->opacity; - for (y = carea.y0; y < carea.y1; y++) { - unsigned char *d; - d = NR_PIXBLOCK_PX (&mpb) + (y - carea.y0) * mpb.rs; - for (x = carea.x0; x < carea.x1; x++) { - d[0] = NR_PREMUL_111 (d[0], a); - d += 1; - } - } - } - /* Compose rendering pixblock int destination */ - nr_blit_pixblock_pixblock_mask (dpb, &ipb, &mpb); - } - nr_pixblock_release (&mpb); - } else { - if (item->render_opacity) { // opacity was already rendered in, just copy to dpb here - nr_blit_pixblock_pixblock(dpb, &ipb); - } else { // copy while multiplying by opacity - nr_blit_pixblock_pixblock_alpha (dpb, &ipb, item->opacity); - } - } - nr_pixblock_release (&ipb); - dpb->empty = FALSE; - /* This pointer wouldn't be valid outside this block, so clear it */ - item->background_pb = NULL; - } else { - /* Just render */ - unsigned int state = NR_ARENA_ITEM_VIRTUAL (item, render) (ct, item, const_cast<NRRectL*>(area), dpb, flags); - if (state & NR_ARENA_ITEM_STATE_INVALID) { - /* Clean up and return error */ - if (dpb != pb) - nr_pixblock_release (dpb); - item->state |= NR_ARENA_ITEM_STATE_INVALID; - return item->state; - } - dpb->empty = FALSE; - } - - if (dpb != pb) { - /* Have to blit from cache */ - nr_blit_pixblock_pixblock (pb, dpb); - nr_pixblock_release (dpb); - pb->empty = FALSE; - item->state |= NR_ARENA_ITEM_STATE_IMAGE; - } -#endif - using namespace Inkscape; // clipping and masks @@ -947,27 +758,7 @@ nr_arena_item_set_item_bbox (NRArenaItem *item, Geom::OptRect &bbox) NRPixBlock * nr_arena_item_get_background (NRArenaItem const *item, int depth) { - NRPixBlock *pb; - if (!item->background_pb) - return NULL; - if (item->background_new) { - pb = new NRPixBlock (); - nr_pixblock_setup_fast (pb, item->background_pb->mode, - item->background_pb->area.x0, - item->background_pb->area.y0, - item->background_pb->area.x1, - item->background_pb->area.y1, true); - if (pb->size != NR_PIXBLOCK_SIZE_TINY && pb->data.px == NULL) // allocation failed - return NULL; - } else if (item->parent) { - pb = nr_arena_item_get_background (item->parent, depth + 1); - } else - return NULL; - - if (depth > 0) - nr_blit_pixblock_pixblock (pb, item->background_pb); - - return pb; + return NULL; } /* Helpers */ diff --git a/src/display/nr-arena-item.h b/src/display/nr-arena-item.h index 447307535..752390776 100644 --- a/src/display/nr-arena-item.h +++ b/src/display/nr-arena-item.h @@ -15,9 +15,8 @@ #include <cairo.h> #include <2geom/matrix.h> -#include <libnr/nr-rect-l.h> -#include <libnr/nr-pixblock.h> -#include <libnr/nr-object.h> +#include "libnr/nr-rect-l.h" +#include "libnr/nr-object.h" #include "gc-soft-ptr.h" #include "nr-arena-forward.h" diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp index b51f3a9cf..0f86db041 100644 --- a/src/display/nr-arena-shape.cpp +++ b/src/display/nr-arena-shape.cpp @@ -29,9 +29,7 @@ #include "display/nr-filter.h" #include "helper/geom-curves.h" #include "helper/geom.h" -#include "libnr/nr-blit.h" #include "libnr/nr-convert2geom.h" -#include "libnr/nr-pixops.h" #include "preferences.h" #include "sp-filter.h" #include "sp-filter-reference.h" diff --git a/src/display/nr-arena.cpp b/src/display/nr-arena.cpp index 33870a118..1339786bd 100644 --- a/src/display/nr-arena.cpp +++ b/src/display/nr-arena.cpp @@ -16,7 +16,6 @@ #include "nr-arena.h" #include "nr-filter-gaussian.h" #include "nr-filter-types.h" -#include <libnr/nr-blit.h> #include "preferences.h" #include "color.h" @@ -131,41 +130,6 @@ nr_arena_request_render_rect (NRArena *arena, NRRectL *area) } } -void -nr_arena_render_paintserver_fill (NRPixBlock *pb, NRRectL *area, SPPainter *painter, float opacity, NRPixBlock *mask) -{ - NRPixBlock cb, cb_opa; - nr_pixblock_setup_fast (&cb, NR_PIXBLOCK_MODE_R8G8B8A8N, area->x0, area->y0, area->x1, area->y1, TRUE); - nr_pixblock_setup_fast (&cb_opa, NR_PIXBLOCK_MODE_R8G8B8A8N, area->x0, area->y0, area->x1, area->y1, TRUE); - - // if memory allocation failed, abort - if ((cb.size != NR_PIXBLOCK_SIZE_TINY && cb.data.px == NULL) || (cb_opa.size != NR_PIXBLOCK_SIZE_TINY && cb_opa.data.px == NULL)) { - return; - } - - cb.visible_area = pb->visible_area; - cb_opa.visible_area = pb->visible_area; - - /* Need separate gradient buffer (lauris)*/ - // do the filling - painter->fill (painter, &cb); - cb.empty = FALSE; - - // do the fill-opacity and mask composite - if (opacity < 1.0) { - nr_blit_pixblock_pixblock_alpha (&cb_opa, &cb, (int) floor (255 * opacity)); - cb_opa.empty = FALSE; - nr_blit_pixblock_pixblock_mask (pb, &cb_opa, mask); - } else { - nr_blit_pixblock_pixblock_mask (pb, &cb, mask); - } - - pb->empty = FALSE; - - nr_pixblock_release (&cb); - nr_pixblock_release (&cb_opa); -} - /** set arena to offscreen mode rendering will be exact diff --git a/src/display/nr-arena.h b/src/display/nr-arena.h index d2f9dc246..f4d86a2e6 100644 --- a/src/display/nr-arena.h +++ b/src/display/nr-arena.h @@ -62,8 +62,6 @@ void nr_arena_request_update (NRArena *arena, NRArenaItem *item); void nr_arena_request_render_rect (NRArena *arena, NRRectL *area); void nr_arena_set_renderoffscreen (NRArena *arena); -void nr_arena_render_paintserver_fill (NRPixBlock *pb, NRRectL *area, SPPainter *painter, float opacity, NRPixBlock *mask); - void nr_arena_separate_color_plates(guint32* rgba); #endif diff --git a/src/display/nr-filter-skeleton.cpp b/src/display/nr-filter-skeleton.cpp index bdb993ed9..d5adedad9 100644 --- a/src/display/nr-filter-skeleton.cpp +++ b/src/display/nr-filter-skeleton.cpp @@ -24,7 +24,6 @@ #include "display/nr-filter-skeleton.h" #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" -#include "libnr/nr-pixblock.h" namespace Inkscape { namespace Filters { diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h index 7b32f1210..93c8e2fe2 100644 --- a/src/display/nr-filter-slot.h +++ b/src/display/nr-filter-slot.h @@ -16,7 +16,6 @@ #include <map> #include <cairo.h> -#include "libnr/nr-pixblock.h" #include "display/nr-filter-types.h" #include "display/nr-filter-units.h" @@ -41,7 +40,6 @@ public: * NR_FILTER_FILLPAINT, NR_FILTER_SOURCEPAINT. */ cairo_surface_t *getcairo(int slot); - NRPixBlock *get(int slot) { return NULL; } /** Sets or re-sets the pixblock associated with given slot. * If there was a pixblock already assigned with this slot, @@ -49,8 +47,6 @@ public: */ void set(int slot, cairo_surface_t *s); - void set(int, NRPixBlock*){} - cairo_surface_t *get_result(int slot_nr); /** Returns the number of slots in use. */ diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp index d60c4f617..54b5cf7c6 100644 --- a/src/display/nr-filter-turbulence.cpp +++ b/src/display/nr-filter-turbulence.cpp @@ -24,7 +24,6 @@ #include "display/nr-filter-units.h" #include "display/nr-filter-utils.h" #include "libnr/nr-rect-l.h" -#include "libnr/nr-blit.h" #include <math.h> namespace Inkscape { @@ -301,7 +300,6 @@ FilterTurbulence::FilterTurbulence() , seed(0) , updated(false) , updated_area(NR::IPoint(), NR::IPoint()) - , pix(NULL) , fTileWidth(10) //guessed , fTileHeight(10) //guessed , fTileX(1) //guessed @@ -316,11 +314,6 @@ FilterPrimitive * FilterTurbulence::create() { FilterTurbulence::~FilterTurbulence() { delete gen; - - if (pix) { - nr_pixblock_release(pix); - delete pix; - } } void FilterTurbulence::set_baseFrequency(int axis, double freq){ @@ -352,89 +345,6 @@ void FilterTurbulence::set_type(FilterTurbulenceType t){ void FilterTurbulence::set_updated(bool u){ } -void FilterTurbulence::render_area(NRPixBlock *pix, NR::IRect &full_area, FilterUnits const &units) { -#if 0 - const int bbox_x0 = full_area.min()[NR::X]; - const int bbox_y0 = full_area.min()[NR::Y]; - const int bbox_x1 = full_area.max()[NR::X]; - const int bbox_y1 = full_area.max()[NR::Y]; - - Geom::Matrix unit_trans = units.get_matrix_primitiveunits2pb().inverse(); - - double point[2]; - - unsigned char *pb = NR_PIXBLOCK_PX(pix); - - if (type==TURBULENCE_TURBULENCE){ - for (int y = std::max(bbox_y0, pix->area.y0); y < std::min(bbox_y1, pix->area.y1); y++){ - int out_line = (y - pix->area.y0) * pix->rs; - point[1] = y * unit_trans[3] + unit_trans[5]; - for (int x = std::max(bbox_x0, pix->area.x0); x < std::min(bbox_x1, pix->area.x1); x++){ - int out_pos = out_line + 4 * (x - pix->area.x0); - point[0] = x * unit_trans[0] + unit_trans[4]; - pb[out_pos] = CLAMP_D_TO_U8( turbulence(0,point)*255 ); // CLAMP includes rounding! - pb[out_pos + 1] = CLAMP_D_TO_U8( turbulence(1,point)*255 ); - pb[out_pos + 2] = CLAMP_D_TO_U8( turbulence(2,point)*255 ); - pb[out_pos + 3] = CLAMP_D_TO_U8( turbulence(3,point)*255 ); - } - } - } else { - for (int y = std::max(bbox_y0, pix->area.y0); y < std::min(bbox_y1, pix->area.y1); y++){ - int out_line = (y - pix->area.y0) * pix->rs; - point[1] = y * unit_trans[3] + unit_trans[5]; - for (int x = std::max(bbox_x0, pix->area.x0); x < std::min(bbox_x1, pix->area.x1); x++){ - int out_pos = out_line + 4 * (x - pix->area.x0); - point[0] = x * unit_trans[0] + unit_trans[4]; - pb[out_pos] = CLAMP_D_TO_U8( ((turbulence(0,point)*255) +255)/2 ); - pb[out_pos + 1] = CLAMP_D_TO_U8( ((turbulence(1,point)*255)+255)/2 ); - pb[out_pos + 2] = CLAMP_D_TO_U8( ((turbulence(2,point)*255) +255)/2 ); - pb[out_pos + 3] = CLAMP_D_TO_U8( ((turbulence(3,point)*255) +255)/2 ); - } - } - } - - pix->empty = FALSE; -#endif -} - -void FilterTurbulence::update_pixbuffer(NR::IRect &area, FilterUnits const &units) { - int bbox_x0 = area.min()[NR::X]; - int bbox_y0 = area.min()[NR::Y]; - int bbox_x1 = area.max()[NR::X]; - int bbox_y1 = area.max()[NR::Y]; - - //TurbulenceInit((long)seed); - - if (!pix){ - pix = new NRPixBlock; - nr_pixblock_setup_fast(pix, NR_PIXBLOCK_MODE_R8G8B8A8N, bbox_x0, bbox_y0, bbox_x1, bbox_y1, true); - } - else if (bbox_x0 != pix->area.x0 || bbox_y0 != pix->area.y0 || - bbox_x1 != pix->area.x1 || bbox_y1 != pix->area.y1) - { - /* TODO: release-setup cycle not actually needed, if pixblock - * width and height don't change */ - nr_pixblock_release(pix); - nr_pixblock_setup_fast(pix, NR_PIXBLOCK_MODE_R8G8B8A8N, bbox_x0, bbox_y0, bbox_x1, bbox_y1, true); - } - - /* This limits pre-rendered turbulence to two megapixels. This is - * arbitary limit and could be something other, too. - * If bigger area is needed, visible area is rendered on demand. */ - if (!pix || (pix->size != NR_PIXBLOCK_SIZE_TINY && pix->data.px == NULL) || - ((bbox_x1 - bbox_x0) * (bbox_y1 - bbox_y0) > 2*1024*1024)) { - pix_data = NULL; - return; - } - - render_area(pix, area, units); - - pix_data = NR_PIXBLOCK_PX(pix); - - updated=true; - updated_area = area; -} - struct Turbulence { Turbulence(TurbulenceGenerator const &gen, Geom::Matrix const &trans, int x0, int y0) : _gen(gen) diff --git a/src/display/nr-filter-turbulence.h b/src/display/nr-filter-turbulence.h index b2bc3a185..fca6ebde3 100644 --- a/src/display/nr-filter-turbulence.h +++ b/src/display/nr-filter-turbulence.h @@ -36,9 +36,6 @@ enum FilterTurbulenceType { TURBULENCE_ENDTYPE }; -struct StitchInfo; - -//#define BSize 0x100 class TurbulenceGenerator; class FilterTurbulence : public FilterPrimitive { @@ -48,8 +45,6 @@ public: virtual ~FilterTurbulence(); virtual void render_cairo(FilterSlot &slot); - void update_pixbuffer(NR::IRect &area, FilterUnits const &units); - void render_area(NRPixBlock *pix, NR::IRect &full_area, FilterUnits const &units); void set_baseFrequency(int axis, double freq); void set_numOctaves(int num); @@ -62,13 +57,7 @@ private: TurbulenceGenerator *gen; void turbulenceInit(long seed); -/* - long Turbulence_setup_seed(long lSeed); - long TurbulenceRandom(long lSeed); - void TurbulenceInit(long lSeed); - double TurbulenceNoise2(int nColorChannel, double vec[2], StitchInfo *pStitchInfo); - double turbulence(int nColorChannel, Geom::Point const &point); -*/ + double XbaseFrequency, YbaseFrequency; int numOctaves; double seed; @@ -76,12 +65,8 @@ private: FilterTurbulenceType type; bool updated; NR::IRect updated_area; - NRPixBlock *pix; unsigned char *pix_data; - //int uLatticeSelector[BSize + BSize + 2]; - //double fGradient[4][BSize + BSize + 2][2]; - double fTileWidth; double fTileHeight; diff --git a/src/display/nr-filter-units.h b/src/display/nr-filter-units.h index dcf7e5838..12f0ca2ca 100644 --- a/src/display/nr-filter-units.h +++ b/src/display/nr-filter-units.h @@ -13,8 +13,6 @@ */ #include "sp-filter-units.h" -#include "libnr/nr-matrix.h" -#include "libnr/nr-rect.h" #include "libnr/nr-rect-l.h" #include <2geom/matrix.h> #include <2geom/rect.h> diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 8c638415d..8273cc591 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -42,8 +42,6 @@ #include "display/nr-arena.h" #include "display/nr-arena-item.h" -#include "libnr/nr-pixblock.h" -#include "libnr/nr-blit.h" #include <2geom/matrix.h> #include <2geom/rect.h> #include "svg/svg-length.h" @@ -211,52 +209,6 @@ int Filter::render(NRArenaItem const *item, cairo_t *bgct, NRRectL const *bgarea cairo_set_operator(graphic, CAIRO_OPERATOR_OVER); cairo_surface_destroy(result); - //slot.set_units(units); - - /*cairo_surface_t *in = cairo_surface_create_similar( - cairo_get_target(ct), CAIRO_CONTENT_COLOR_ALPHA, - area->x1 - area->x0, area->y1 - area->y0); - cairo_t *inct = cairo_create(in); - cairo_translate(inct, -area->x0, -area->y0); - cairo_set_source_surface(inct, cairo_get_target(ct), 0, 0); - cairo_paint(inct); - slot.set(NR_FILTER_SOURCEGRAPHIC, in); - cairo_destroy(inct); - cairo_surface_destroy(in);*/ - - /*NRPixBlock *in = new NRPixBlock; - nr_pixblock_setup_fast(in, pb->mode, pb->area.x0, pb->area.y0, - pb->area.x1, pb->area.y1, true); - if (in->size != NR_PIXBLOCK_SIZE_TINY && in->data.px == NULL) { - g_warning("Inkscape::Filters::Filter::render: failed to reserve temporary buffer"); - return 0; - } - nr_blit_pixblock_pixblock(in, pb); - in->empty = FALSE; - slot.set(NR_FILTER_SOURCEGRAPHIC, in);*/ - - // Check that we are rendering a non-empty area - /*in = slot.get(NR_FILTER_SOURCEGRAPHIC); - if (in->area.x1 - in->area.x0 <= 0 || in->area.y1 - in->area.y0 <= 0) { - if (in->area.x1 - in->area.x0 < 0 || in->area.y1 - in->area.y0 < 0) { - g_warning("Inkscape::Filters::Filter::render: negative area! (%d, %d) (%d, %d)", - in->area.x0, in->area.y0, in->area.x1, in->area.y1); - } - return 0; - } - in = NULL; // in is now handled by FilterSlot, we should not touch it - */ - - /*for (int i = 0 ; i < _primitive_count ; i++) { - _primitive[i]->render(slot, units); - }*/ - - //slot.get_final(_output_slot, ct, area); - - // Take note of the amount of used image slots - // -> next time this filter is rendered, we can reserve enough slots - // immediately - //_slot_count = slot.get_slot_count(); return 0; } @@ -327,10 +279,10 @@ void Filter::bbox_enlarge(NRRectL &bbox) { Geom::Rect enlarged = filter_effect_area(tmp_bbox); - bbox.x0 = (NR::ICoord)enlarged.min()[X]; - bbox.y0 = (NR::ICoord)enlarged.min()[Y]; - bbox.x1 = (NR::ICoord)enlarged.max()[X]; - bbox.y1 = (NR::ICoord)enlarged.max()[Y]; + bbox.x0 = (NR::ICoord) floor(enlarged.min()[X]); + bbox.y0 = (NR::ICoord) floor(enlarged.min()[Y]); + bbox.x1 = (NR::ICoord) ceil(enlarged.max()[X]); + bbox.y1 = (NR::ICoord) ceil(enlarged.max()[Y]); } Geom::Rect Filter::filter_effect_area(Geom::Rect const &bbox) diff --git a/src/display/nr-filter.h b/src/display/nr-filter.h index cd805043c..4db1ec988 100644 --- a/src/display/nr-filter.h +++ b/src/display/nr-filter.h @@ -16,8 +16,6 @@ #include <cairo.h> #include "display/nr-filter-primitive.h" #include "display/nr-filter-types.h" -#include "libnr/nr-pixblock.h" -#include "libnr/nr-matrix.h" #include "libnr/nr-rect.h" #include "svg/svg-length.h" #include "sp-filter-units.h" diff --git a/src/display/pixblock-scaler.cpp b/src/display/pixblock-scaler.cpp deleted file mode 100644 index 1f2b1db3f..000000000 --- a/src/display/pixblock-scaler.cpp +++ /dev/null @@ -1,299 +0,0 @@ -#define __NR_PIXBLOCK_SCALER_CPP__ - -/* - * Functions for blitting pixblocks using scaling - * - * Author: - * Niko Kiirala <niko@kiirala.com> - * - * Copyright (C) 2006,2009 Niko Kiirala - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include <glib.h> -#include <cmath> -#if defined (SOLARIS) && (SOLARIS == 8) -#include "round.h" -using Inkscape::round; -#endif -using std::floor; - -#include "display/nr-filter-utils.h" -#include "libnr/nr-pixblock.h" -#include "libnr/nr-blit.h" -#include <2geom/forward.h> - -namespace NR { - -struct RGBA { - double r, g, b, a; -}; - -/** Calculates cubically interpolated value of the four given pixel values. - * The pixel values should be from four adjacent pixels in source image or - * four adjacent interpolated values. len should be the x- or y-coordinate - * (depending on interpolation direction) of the center of the target pixel - * in source image coordinates. - */ -__attribute__ ((const)) -inline static double sample(double const a, double const b, - double const c, double const d, - double const len) -{ - double lena = 1.5 + (len - round(len)); - double lenb = 0.5 + (len - round(len)); - double lenc = 0.5 - (len - round(len)); - double lend = 1.5 - (len - round(len)); - double const f = -0.5; // corresponds to cubic Hermite spline - double sum = 0; - sum += ((((f * lena) - 5.0 * f) * lena + 8.0 * f) * lena - 4 * f) * a; - sum += (((f + 2.0) * lenb - (f + 3.0)) * lenb * lenb + 1.0) * b; - sum += (((f + 2.0) * lenc - (f + 3.0)) * lenc * lenc + 1.0) * c; - sum += ((((f * lend) - 5.0 * f) * lend + 8.0 * f) * lend - 4 * f) * d; - - return sum; -} - -/** - * Sanity check function for indexing pixblocks. - * Catches reading and writing outside the pixblock area. - * When enabled, decreases filter rendering speed massively. - */ -inline static void _check_index(NRPixBlock const * const pb, int const location, int const line) -{ - if(false) { - int max_loc = pb->rs * (pb->area.y1 - pb->area.y0); - if (location < 0 || (location + 4) > max_loc) - g_warning("Location %d out of bounds (0 ... %d) at line %d", location, max_loc, line); - } -} - -static void scale_bicubic_rgba(NRPixBlock *to, NRPixBlock *from, - Geom::Matrix const &trans) -{ - if (NR_PIXBLOCK_BPP(from) != 4 || NR_PIXBLOCK_BPP(to) != 4) { - g_warning("A non-32-bpp image passed to scale_bicubic_rgba: scaling aborted."); - return; - } - - bool free_from_on_exit = false; - if (from->mode != to->mode){ - NRPixBlock *o_from = from; - from = new NRPixBlock; - nr_pixblock_setup_fast(from, to->mode, o_from->area.x0, o_from->area.y0, o_from->area.x1, o_from->area.y1, false); - nr_blit_pixblock_pixblock(from, o_from); - free_from_on_exit = true; - } - - // Precalculate sizes of source and destination pixblocks - int from_width = from->area.x1 - from->area.x0; - int from_height = from->area.y1 - from->area.y0; - int to_width = to->area.x1 - to->area.x0; - int to_height = to->area.y1 - to->area.y0; - - // from_step: when advancing one pixel in destination image, - // how much we should advance in source image - double from_stepx = 1.0 / trans[0]; - double from_stepy = 1.0 / trans[3]; - double from_diffx = from_stepx * (-trans[4]); - double from_diffy = from_stepy * (-trans[5]); - from_diffx = (to->area.x0 * from_stepx + from_diffx) - from->area.x0; - from_diffy = (to->area.y0 * from_stepy + from_diffy) - from->area.y0; - - // Loop through every pixel of destination image, a line at a time - for (int to_y = 0 ; to_y < to_height ; to_y++) { - double from_y = (to_y + 0.5) * from_stepy + from_diffy; - // Pre-calculate beginning of the four horizontal lines, from - // which we should read - int from_line[4]; - for (int i = 0 ; i < 4 ; i++) { - int fy_line = (int)round(from_y) + i - 2; - if (fy_line >= 0) { - if (fy_line < from_height) { - from_line[i] = fy_line * from->rs; - } else { - from_line[i] = (from_height - 1) * from->rs; - } - } else { - from_line[i] = 0; - } - } - // Loop through this horizontal line in destination image - // For every pixel, calculate the color of pixel with - // bicubic interpolation and set the pixel value in destination image - for (int to_x = 0 ; to_x < to_width ; to_x++) { - double from_x = (to_x + 0.5) * from_stepx + from_diffx; - RGBA line[4]; - for (int i = 0 ; i < 4 ; i++) { - int k = (int)round(from_x) + i - 2; - if (k < 0) k = 0; - if (k >= from_width) k = from_width - 1; - k *= 4; - _check_index(from, from_line[0] + k, __LINE__); - _check_index(from, from_line[1] + k, __LINE__); - _check_index(from, from_line[2] + k, __LINE__); - _check_index(from, from_line[3] + k, __LINE__); - line[i].r = sample(NR_PIXBLOCK_PX(from)[from_line[0] + k], - NR_PIXBLOCK_PX(from)[from_line[1] + k], - NR_PIXBLOCK_PX(from)[from_line[2] + k], - NR_PIXBLOCK_PX(from)[from_line[3] + k], - from_y); - line[i].g = sample(NR_PIXBLOCK_PX(from)[from_line[0] + k + 1], - NR_PIXBLOCK_PX(from)[from_line[1] + k + 1], - NR_PIXBLOCK_PX(from)[from_line[2] + k + 1], - NR_PIXBLOCK_PX(from)[from_line[3] + k + 1], - from_y); - line[i].b = sample(NR_PIXBLOCK_PX(from)[from_line[0] + k + 2], - NR_PIXBLOCK_PX(from)[from_line[1] + k + 2], - NR_PIXBLOCK_PX(from)[from_line[2] + k + 2], - NR_PIXBLOCK_PX(from)[from_line[3] + k + 2], - from_y); - line[i].a = sample(NR_PIXBLOCK_PX(from)[from_line[0] + k + 3], - NR_PIXBLOCK_PX(from)[from_line[1] + k + 3], - NR_PIXBLOCK_PX(from)[from_line[2] + k + 3], - NR_PIXBLOCK_PX(from)[from_line[3] + k + 3], - from_y); - } - RGBA result; - result.r = round(sample(line[0].r, line[1].r, line[2].r, line[3].r, - from_x)); - result.g = round(sample(line[0].g, line[1].g, line[2].g, line[3].g, - from_x)); - result.b = round(sample(line[0].b, line[1].b, line[2].b, line[3].b, - from_x)); - result.a = round(sample(line[0].a, line[1].a, line[2].a, line[3].a, - from_x)); - - _check_index(to, to_y * to->rs + to_x * 4, __LINE__); - - using Inkscape::Filters::clamp; - using Inkscape::Filters::clamp_alpha; - if (to->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { - /* Clamp the colour channels to range from 0 to result.a to - * make sure, we don't exceed 100% per colour channel with - * images that have premultiplied alpha */ - - int const alpha = clamp((int)result.a); - - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4] - = clamp_alpha((int)result.r, alpha); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 1] - = clamp_alpha((int)result.g, alpha); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 2] - = clamp_alpha((int)result.b, alpha); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 3] = alpha; - } else { - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4] - = clamp((int)result.r); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 1] - = clamp((int)result.g); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 2] - = clamp((int)result.b); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 3] - = clamp((int)result.a); - } - } - } - if (free_from_on_exit) { - nr_pixblock_release(from); - delete from; - } - -} - -void scale_bicubic_alpha(NRPixBlock *to, NRPixBlock *from, - Geom::Matrix const &trans) -{ - if (NR_PIXBLOCK_BPP(from) != 1 || NR_PIXBLOCK_BPP(to) != 1) { - g_warning("A non-8-bpp image passed to scale_bicubic_alpha: scaling aborted."); - return; - } - - // Precalculate sizes of source and destination pixblocks - int from_width = from->area.x1 - from->area.x0; - int from_height = from->area.y1 - from->area.y0; - int to_width = to->area.x1 - to->area.x0; - int to_height = to->area.y1 - to->area.y0; - - // from_step: when advancing one pixel in destination image, - // how much we should advance in source image - double from_stepx = 1.0 / trans[0]; - double from_stepy = 1.0 / trans[3]; - double from_diffx = from_stepx * (-trans[4]); - double from_diffy = from_stepy * (-trans[5]); - from_diffx = (to->area.x0 * from_stepx + from_diffx) - from->area.x0; - from_diffy = (to->area.y0 * from_stepy + from_diffy) - from->area.y0; - - // Loop through every pixel of destination image, a line at a time - for (int to_y = 0 ; to_y < to_height ; to_y++) { - double from_y = (to_y + 0.5) * from_stepy - from_diffy; - // Pre-calculate beginning of the four horizontal lines, from - // which we should read - int from_line[4]; - for (int i = 0 ; i < 4 ; i++) { - int fy_line = (int)round(from_y) + i - 2; - if (fy_line >= 0) { - if (fy_line < from_height) { - from_line[i] = fy_line * from->rs; - } else { - from_line[i] = (from_height - 1) * from->rs; - } - } else { - from_line[i] = 0; - } - } - // Loop through this horizontal line in destination image - // For every pixel, calculate the color of pixel with - // bicubic interpolation and set the pixel value in destination image - for (int to_x = 0 ; to_x < to_width ; to_x++) { - double from_x = (to_x + 0.5) * from_stepx - from_diffx; - double line[4]; - for (int i = 0 ; i < 4 ; i++) { - int k = (int)round(from_x) + i - 2; - if (k < 0) k = 0; - if (k >= from_width) k = from_width - 1; - _check_index(from, from_line[0] + k, __LINE__); - _check_index(from, from_line[1] + k, __LINE__); - _check_index(from, from_line[2] + k, __LINE__); - _check_index(from, from_line[3] + k, __LINE__); - line[i] = sample(NR_PIXBLOCK_PX(from)[from_line[0] + k], - NR_PIXBLOCK_PX(from)[from_line[1] + k], - NR_PIXBLOCK_PX(from)[from_line[2] + k], - NR_PIXBLOCK_PX(from)[from_line[3] + k], - from_y); - } - int result; - result = (int)round(sample(line[0], line[1], line[2], line[3], - from_x)); - - _check_index(to, to_y * to->rs + to_x, __LINE__); - - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x] - = Inkscape::Filters::clamp(result); - } - } -} - -void scale_bicubic(NRPixBlock *to, NRPixBlock *from, Geom::Matrix const &trans) -{ - if (NR_PIXBLOCK_BPP(to) == 4 && NR_PIXBLOCK_BPP(from) == 4) { - scale_bicubic_rgba(to, from, trans); - } else if (NR_PIXBLOCK_BPP(to) == 1 && NR_PIXBLOCK_BPP(from) == 1) { - scale_bicubic_alpha(to, from, trans); - } else { - g_warning("NR::scale_bicubic: unsupported bitdepths for scaling: to %d, from %d", NR_PIXBLOCK_BPP(to), NR_PIXBLOCK_BPP(from)); - } -} - -} /* namespace NR */ -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/display/pixblock-scaler.h b/src/display/pixblock-scaler.h deleted file mode 100644 index 8e9b1ec62..000000000 --- a/src/display/pixblock-scaler.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __NR_PIXBLOCK_SCALER_H__ -#define __NR_PIXBLOCK_SCALER_H__ - -/* - * Functions for blitting pixblocks using scaling - * - * Author: - * Niko Kiirala <niko@kiirala.com> - * - * Copyright (C) 2006 Niko Kiirala - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include "libnr/nr-pixblock.h" -#include <2geom/forward.h> - -namespace NR { - -/** Blits the second pixblock to the first. - * Image in source pixblock is scaled to the size of destination pixblock - * using bicubic interpolation. - * Source pixblock is not modified in process. - * Only works for 32-bpp images. - */ -void scale_bicubic(NRPixBlock *to, NRPixBlock *from, Geom::Matrix const &trans); - -} /* namespace NR */ - -#endif // __NR_PIXBLOCK_SCALER_H__ -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/display/pixblock-transform.cpp b/src/display/pixblock-transform.cpp deleted file mode 100644 index af05a9b88..000000000 --- a/src/display/pixblock-transform.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#define __NR_PIXBLOCK_SCALER_CPP__ - -/* - * Functions for blitting pixblocks using matrix transformation - * - * Author: - * Niko Kiirala <niko@kiirala.com> - * - * Copyright (C) 2006,2009 Niko Kiirala - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include <glib.h> -#include <cmath> -#if defined (SOLARIS) && (SOLARIS == 8) -#include "round.h" -using Inkscape::round; -#endif -using std::floor; - -#include "display/nr-filter-utils.h" - -#include "libnr/nr-blit.h" -#include "libnr/nr-pixblock.h" -#include <2geom/matrix.h> - -namespace NR { - -struct RGBA { - double r, g, b, a; -}; -struct RGBAi { - int r, g, b, a; -}; - -/** - * Sanity check function for indexing pixblocks. - * Catches reading and writing outside the pixblock area. - * When enabled, decreases filter rendering speed massively. - */ -inline void _check_index(NRPixBlock const * const pb, int const location, int const line) -{ - if(false) { - int max_loc = pb->rs * (pb->area.y1 - pb->area.y0); - if (location < 0 || (location + 4) > max_loc) - g_warning("Location %d out of bounds (0 ... %d) at line %d", location, max_loc, line); - } -} - -void transform_nearest(NRPixBlock *to, NRPixBlock *from, Geom::Matrix const &trans) -{ - if (NR_PIXBLOCK_BPP(from) != 4 || NR_PIXBLOCK_BPP(to) != 4) { - g_warning("A non-32-bpp image passed to transform_nearest: scaling aborted."); - return; - } - - bool free_from_on_exit = false; - if (from->mode != to->mode){ - NRPixBlock *o_from = from; - from = new NRPixBlock; - nr_pixblock_setup_fast(from, to->mode, o_from->area.x0, o_from->area.y0, o_from->area.x1, o_from->area.y1, false); - nr_blit_pixblock_pixblock(from, o_from); - free_from_on_exit = true; - } - - // Precalculate sizes of source and destination pixblocks - int from_width = from->area.x1 - from->area.x0; - int from_height = from->area.y1 - from->area.y0; - int to_width = to->area.x1 - to->area.x0; - int to_height = to->area.y1 - to->area.y0; - - Geom::Matrix itrans = trans.inverse(); - - // Loop through every pixel of destination image, a line at a time - for (int to_y = 0 ; to_y < to_height ; to_y++) { - for (int to_x = 0 ; to_x < to_width ; to_x++) { - RGBAi result = {0,0,0,0}; - - int from_x = (int)floor(itrans[0] * (to_x + 0.5 + to->area.x0) - + itrans[2] * (to_y + 0.5 + to->area.y0) - + itrans[4]); - from_x -= from->area.x0; - int from_y = (int)floor(itrans[1] * (to_x + 0.5 + to->area.x0) - + itrans[3] * (to_y + 0.5 + to->area.y0) - + itrans[5]); - from_y -= from->area.y0; - - if (from_x >= 0 && from_x < from_width - && from_y >= 0 && from_y < from_height) { - _check_index(from, from_y * from->rs + from_x * 4, __LINE__); - result.r = NR_PIXBLOCK_PX(from)[from_y * from->rs + from_x * 4]; - result.g = NR_PIXBLOCK_PX(from)[from_y * from->rs + from_x * 4 + 1]; - result.b = NR_PIXBLOCK_PX(from)[from_y * from->rs + from_x * 4 + 2]; - result.a = NR_PIXBLOCK_PX(from)[from_y * from->rs + from_x * 4 + 3]; - } - - _check_index(to, to_y * to->rs + to_x * 4, __LINE__); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4] = result.r; - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 1] = result.g; - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 2] = result.b; - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 3] = result.a; - } - } - if (free_from_on_exit) { - nr_pixblock_release(from); - delete from; - } -} - -/** Calculates cubically interpolated value of the four given pixel values. - * The pixel values should be from four adjacent pixels in source image or - * four adjacent interpolated values. len should be the x- or y-coordinate - * (depending on interpolation direction) of the center of the target pixel - * in source image coordinates. - */ -__attribute__ ((const)) -inline static double sample(double const a, double const b, - double const c, double const d, - double const len) -{ - double lena = 1.5 + (len - round(len)); - double lenb = 0.5 + (len - round(len)); - double lenc = 0.5 - (len - round(len)); - double lend = 1.5 - (len - round(len)); - double const f = -0.5; // corresponds to cubic Hermite spline - double sum = 0; - sum += ((((f * lena) - 5.0 * f) * lena + 8.0 * f) * lena - 4 * f) * a; - sum += (((f + 2.0) * lenb - (f + 3.0)) * lenb * lenb + 1.0) * b; - sum += (((f + 2.0) * lenc - (f + 3.0)) * lenc * lenc + 1.0) * c; - sum += ((((f * lend) - 5.0 * f) * lend + 8.0 * f) * lend - 4 * f) * d; - - return sum; -} - -void transform_bicubic(NRPixBlock *to, NRPixBlock *from, Geom::Matrix const &trans) -{ - if (NR_PIXBLOCK_BPP(from) != 4 || NR_PIXBLOCK_BPP(to) != 4) { - g_warning("A non-32-bpp image passed to transform_bicubic: scaling aborted."); - return; - } - - bool free_from_on_exit = false; - if (from->mode != to->mode){ - NRPixBlock *o_from = from; - from = new NRPixBlock; - nr_pixblock_setup_fast(from, to->mode, o_from->area.x0, o_from->area.y0, o_from->area.x1, o_from->area.y1, false); - nr_blit_pixblock_pixblock(from, o_from); - free_from_on_exit = true; - } - - if (from->mode != NR_PIXBLOCK_MODE_R8G8B8A8P) { - // TODO: Fix this... (The problem is that for interpolation non-premultiplied colors should be premultiplied...) - g_warning("transform_bicubic does not properly support non-premultiplied images"); - } - - // Precalculate sizes of source and destination pixblocks - int from_width = from->area.x1 - from->area.x0; - int from_height = from->area.y1 - from->area.y0; - int to_width = to->area.x1 - to->area.x0; - int to_height = to->area.y1 - to->area.y0; - - Geom::Matrix itrans = trans.inverse(); - - // Loop through every pixel of destination image, a line at a time - for (int to_y = 0 ; to_y < to_height ; to_y++) { - for (int to_x = 0 ; to_x < to_width ; to_x++) { - double from_x = itrans[0] * (to_x + 0.5 + to->area.x0) - + itrans[2] * (to_y + 0.5 + to->area.y0) - + itrans[4] - from->area.x0; - double from_y = itrans[1] * (to_x + 0.5 + to->area.x0) - + itrans[3] * (to_y + 0.5 + to->area.y0) - + itrans[5] - from->area.y0; - - if (from_x < 0 || from_x >= from_width || - from_y < 0 || from_y >= from_height) { - continue; - } - - RGBA line[4]; - - int from_line[4]; - for (int i = 0 ; i < 4 ; i++) { - int fy_line = (int)round(from_y) + i - 2; - if (fy_line >= 0) { - if (fy_line < from_height) { - from_line[i] = fy_line * from->rs; - } else { - from_line[i] = (from_height - 1) * from->rs; - } - } else { - from_line[i] = 0; - } - } - - for (int i = 0 ; i < 4 ; i++) { - int k = (int)round(from_x) + i - 2; - if (k < 0) k = 0; - if (k >= from_width) k = from_width - 1; - k *= 4; - _check_index(from, from_line[0] + k, __LINE__); - _check_index(from, from_line[1] + k, __LINE__); - _check_index(from, from_line[2] + k, __LINE__); - _check_index(from, from_line[3] + k, __LINE__); - line[i].r = sample(NR_PIXBLOCK_PX(from)[from_line[0] + k], - NR_PIXBLOCK_PX(from)[from_line[1] + k], - NR_PIXBLOCK_PX(from)[from_line[2] + k], - NR_PIXBLOCK_PX(from)[from_line[3] + k], - from_y); - line[i].g = sample(NR_PIXBLOCK_PX(from)[from_line[0] + k + 1], - NR_PIXBLOCK_PX(from)[from_line[1] + k + 1], - NR_PIXBLOCK_PX(from)[from_line[2] + k + 1], - NR_PIXBLOCK_PX(from)[from_line[3] + k + 1], - from_y); - line[i].b = sample(NR_PIXBLOCK_PX(from)[from_line[0] + k + 2], - NR_PIXBLOCK_PX(from)[from_line[1] + k + 2], - NR_PIXBLOCK_PX(from)[from_line[2] + k + 2], - NR_PIXBLOCK_PX(from)[from_line[3] + k + 2], - from_y); - line[i].a = sample(NR_PIXBLOCK_PX(from)[from_line[0] + k + 3], - NR_PIXBLOCK_PX(from)[from_line[1] + k + 3], - NR_PIXBLOCK_PX(from)[from_line[2] + k + 3], - NR_PIXBLOCK_PX(from)[from_line[3] + k + 3], - from_y); - } - RGBA result; - result.r = round(sample(line[0].r, line[1].r, line[2].r, line[3].r, - from_x)); - result.g = round(sample(line[0].g, line[1].g, line[2].g, line[3].g, - from_x)); - result.b = round(sample(line[0].b, line[1].b, line[2].b, line[3].b, - from_x)); - result.a = round(sample(line[0].a, line[1].a, line[2].a, line[3].a, - from_x)); - - using Inkscape::Filters::clamp; - using Inkscape::Filters::clamp_alpha; - _check_index(to, to_y * to->rs + to_x * 4, __LINE__); - if (to->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { - /* Make sure, none of the RGB channels exceeds 100% intensity - * in premultiplied output */ - int const alpha = clamp((int)result.a); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4] = - clamp_alpha((int)result.r, alpha); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 1] = - clamp_alpha((int)result.g, alpha); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 2] = - clamp_alpha((int)result.b, alpha); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 3] = alpha; - } else { - /* Clamp the output to unsigned char range */ - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4] - = clamp((int)result.r); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 1] - = clamp((int)result.g); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 2] - = clamp((int)result.b); - NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 3] - = clamp((int)result.a); - } - } - } - if (free_from_on_exit) { - nr_pixblock_release(from); - delete from; - } -} - -} /* namespace NR */ -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/display/pixblock-transform.h b/src/display/pixblock-transform.h deleted file mode 100644 index 3ba00a08f..000000000 --- a/src/display/pixblock-transform.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __NR_PIXBLOCK_TRANSFORM_H__ -#define __NR_PIXBLOCK_TRANSFORM_H__ - -/* - * Functions for blitting pixblocks using matrix transfomation - * - * Author: - * Niko Kiirala <niko@kiirala.com> - * - * Copyright (C) 2006 Niko Kiirala - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include "libnr/nr-pixblock.h" -#include <2geom/forward.h> - -namespace NR { - -void transform_nearest(NRPixBlock *to, NRPixBlock *from, Geom::Matrix const &trans); -void transform_bicubic(NRPixBlock *to, NRPixBlock *from, Geom::Matrix const &trans); - -} /* namespace NR */ - -#endif // __NR_PIXBLOCK_TRANSFORM_H__ -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 4c74af6d9..8be585a43 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -20,8 +20,6 @@ # include "config.h" #endif -#include <libnr/nr-pixblock.h> - #include <gtk/gtkmain.h> #include <gtk/gtksignal.h> #include <gtk/gtkversion.h> @@ -33,7 +31,6 @@ #include <display/sp-canvas.h> #include "display-forward.h" #include <2geom/matrix.h> -#include <libnr/nr-convex-hull.h> #include "preferences.h" #include "inkscape.h" #include "sodipodi-ctrlrect.h" @@ -41,7 +38,6 @@ #include "color-profile-fns.h" #endif // ENABLE_LCMS #include "display/rendermode.h" -#include "libnr/nr-blit.h" #include "display/cairo-utils.h" #include "debug/gdk-event-latency-tracker.h" #include "desktop.h" @@ -1758,6 +1754,7 @@ sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1, } #endif + // output to X cairo_destroy(buf.ct); @@ -1775,12 +1772,6 @@ sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1, //cairo_destroy (buf.ct); //cairo_surface_finish (cst); //cairo_surface_destroy (cst); - - if (canvas->rendermode != Inkscape::RENDERMODE_OUTLINE) { - nr_pixelstore_256K_free (buf.buf); - } else { - nr_pixelstore_1M_free (buf.buf); - } } struct PaintRectSetup { diff --git a/src/display/testnr.cpp b/src/display/testnr.cpp deleted file mode 100644 index 3a3478d28..000000000 --- a/src/display/testnr.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include <gtk/gtk.h> -#include "sp-arena.h" - -int -main (int argc, char ** argv) -{ - GtkWidget * w, * c; - - gtk_init (&argc, &argv); - - w = gtk_window_new (GTK_WINDOW_TOPLEVEL); - - c = sp_arena_new (); - gtk_widget_show (c); - - gtk_container_add (GTK_CONTAINER (w), c); - - gtk_widget_show (w); - - gtk_main (); - - return 0; -} - diff --git a/src/dropper-context.cpp b/src/dropper-context.cpp index 5415fdc80..85649186d 100644 --- a/src/dropper-context.cpp +++ b/src/dropper-context.cpp @@ -36,6 +36,7 @@ #include "desktop-handles.h" #include "selection.h" #include "document.h" +#include "libnr/nr-pixblock.h" #include "pixmaps/cursor-dropper.xpm" diff --git a/src/dyna-draw-context.cpp b/src/dyna-draw-context.cpp index bb8e69092..de6c151c3 100644 --- a/src/dyna-draw-context.cpp +++ b/src/dyna-draw-context.cpp @@ -62,6 +62,7 @@ #include "display/canvas-bpath.h" #include "display/canvas-arena.h" #include "livarot/Shape.h" +#include "libnr/nr-pixblock.h" #include "dyna-draw-context.h" diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index a1f902457..5ba92ffa0 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -22,6 +22,7 @@ #include <string> #include <2geom/forward.h> +#include <2geom/matrix.h> #include "style.h" diff --git a/src/extension/internal/emf-win32-inout.cpp b/src/extension/internal/emf-win32-inout.cpp index 9d25f3a7f..c88f09733 100644 --- a/src/extension/internal/emf-win32-inout.cpp +++ b/src/extension/internal/emf-win32-inout.cpp @@ -43,10 +43,6 @@ #include "display/nr-arena.h" #include "display/nr-arena-item.h" -//#include "libnr/nr-rect.h" -//#include "libnr/nr-matrix.h" -//#include "libnr/nr-pixblock.h" - //#include <stdio.h> //#include <string.h> diff --git a/src/flood-context.cpp b/src/flood-context.cpp index 612ae1cfc..b67d180ff 100644 --- a/src/flood-context.cpp +++ b/src/flood-context.cpp @@ -53,12 +53,7 @@ #include "display/nr-arena-image.h" #include "display/canvas-arena.h" #include "libnr/nr-pixops.h" -#include "libnr/nr-matrix-translate-ops.h" -#include "libnr/nr-scale-ops.h" -#include "libnr/nr-scale-translate-ops.h" -#include "libnr/nr-translate-matrix-ops.h" -#include "libnr/nr-translate-scale-ops.h" -#include "libnr/nr-matrix-ops.h" +#include "libnr/nr-pixblock.h" #include <2geom/pathvector.h> #include "sp-item.h" #include "sp-root.h" diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp index 3be63aa68..8439115cb 100644 --- a/src/helper/pixbuf-ops.cpp +++ b/src/helper/pixbuf-ops.cpp @@ -15,28 +15,23 @@ # include "config.h" #endif -#include <interface.h> -#include <libnr/nr-pixops.h> #include <glib.h> #include <glib/gmessages.h> #include <png.h> -#include "png-write.h" -#include <display/nr-arena-item.h> -#include <display/nr-arena.h> -#include <document.h> -#include <sp-item.h> -#include <sp-root.h> -#include <sp-use.h> -#include <sp-defs.h> -#include "unit-constants.h" -#include "libnr/nr-matrix-translate-ops.h" -#include "libnr/nr-scale-ops.h" -#include "libnr/nr-scale-translate-ops.h" -#include "libnr/nr-translate-matrix-ops.h" -#include "libnr/nr-translate-scale-ops.h" +#include "interface.h" +#include "helper/png-write.h" +#include "display/cairo-utils.h" +#include "display/nr-arena-item.h" +#include "display/nr-arena.h" +#include "document.h" +#include "sp-item.h" +#include "sp-root.h" +#include "sp-use.h" +#include "sp-defs.h" +#include "unit-constants.h" -#include "pixbuf-ops.h" +#include "helper/pixbuf-ops.h" /** * Hide all items that are not listed in list, recursively, skipping groups and defs. @@ -142,49 +137,32 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, nr_arena_item_invoke_update(root, &final_bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); - guchar *px = NULL; - guint64 size = 4L * (guint64)width * (guint64)height; - if(size < (guint64)G_MAXSIZE) { - // g_try_new is limited to g_size type which is defined as unisgned int. Need to test for very large nubers - px = g_try_new(guchar, size); - } + cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - if(px != NULL) - { + if (cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS) { + cairo_t *ct = cairo_create(surface); + + // clear to background + ink_cairo_set_source_rgba32(ct, bgcolor); + cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE); + cairo_paint(ct); + cairo_set_operator(ct, CAIRO_OPERATOR_OVER); + + // render items + nr_arena_item_invoke_render(ct, root, &final_bbox, NULL, NR_ARENA_ITEM_RENDER_NO_CACHE ); - NRPixBlock B; - //g_warning("sp_generate_internal_bitmap: nr_pixblock_setup_extern."); - nr_pixblock_setup_extern( &B, NR_PIXBLOCK_MODE_R8G8B8A8N, - final_bbox.x0, final_bbox.y0, final_bbox.x1, final_bbox.y1, - px, 4 * width, FALSE, FALSE ); - - unsigned char dtc[4]; - dtc[0] = NR_RGBA32_R(bgcolor); - dtc[1] = NR_RGBA32_G(bgcolor); - dtc[2] = NR_RGBA32_B(bgcolor); - dtc[3] = NR_RGBA32_A(bgcolor); - - for (gsize fy = 0; fy < height; fy++) { - guchar *p = NR_PIXBLOCK_PX(&B) + fy * (gsize)B.rs; - for (unsigned int fx = 0; fx < width; fx++) { - for (int i = 0; i < 4; i++) { - *p++ = dtc[i]; - } - } - } - - - nr_arena_item_invoke_render(NULL, root, &final_bbox, &B, NR_ARENA_ITEM_RENDER_NO_CACHE ); - - pixbuf = gdk_pixbuf_new_from_data(px, GDK_COLORSPACE_RGB, - TRUE, - 8, width, height, width * 4, - (GdkPixbufDestroyNotify)g_free, - NULL); + pixbuf = gdk_pixbuf_new_from_data(cairo_image_surface_get_data(surface), + GDK_COLORSPACE_RGB, TRUE, + 8, width, height, cairo_image_surface_get_stride(surface), + (GdkPixbufDestroyNotify) cairo_surface_destroy, + NULL); + convert_pixbuf_argb32_to_normal(pixbuf); } else { + long long size = (long long) height * (long long) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); g_warning("sp_generate_internal_bitmap: not enough memory to create pixel buffer. Need %lld.", size); + cairo_surface_destroy(surface); } sp_item_invoke_hide (SP_ITEM(sp_document_root(doc)), dkey); nr_object_unref((NRObject *) arena); diff --git a/src/helper/png-write.cpp b/src/helper/png-write.cpp index 908b1fb20..437c39649 100644 --- a/src/helper/png-write.cpp +++ b/src/helper/png-write.cpp @@ -18,7 +18,7 @@ #include "interface.h" #include "libnr/nr-pixops.h" -#include "libnr/nr-translate-scale-ops.h" +#include "libnr/nr-pixblock.h" #include <2geom/rect.h> #include <glib/gmessages.h> #include <png.h> @@ -346,13 +346,8 @@ sp_export_get_rows(guchar const **rows, void **to_free, int row, int num_rows, v cairo_paint(ct); cairo_set_operator(ct, CAIRO_OPERATOR_OVER); - NRPixBlock pb; - nr_pixblock_setup_extern(&pb, NR_PIXBLOCK_MODE_R8G8B8A8N, - bbox.x0, bbox.y0, bbox.x1, bbox.y1, - ebp->px, 4 * ebp->width, FALSE, FALSE); - /* Render */ - nr_arena_item_invoke_render(ct, ebp->root, &bbox, &pb, 0); + nr_arena_item_invoke_render(ct, ebp->root, &bbox, NULL, 0); cairo_destroy(ct); cairo_surface_destroy(s); @@ -367,8 +362,6 @@ sp_export_get_rows(guchar const **rows, void **to_free, int row, int num_rows, v rows[r] = px + r * stride; } - nr_pixblock_release(&pb); - return num_rows; } diff --git a/src/libnr/Makefile_insert b/src/libnr/Makefile_insert index 8dd3c46e3..dc329c351 100644 --- a/src/libnr/Makefile_insert +++ b/src/libnr/Makefile_insert @@ -10,16 +10,11 @@ ink_common_sources += \ libnr/nr-compose.cpp \ libnr/nr-compose.h \ libnr/nr-convert2geom.h \ - libnr/nr-convex-hull.h \ libnr/nr-coord.h \ libnr/nr-dim2.h \ libnr/nr-forward.h \ - libnr/nr-gradient.cpp \ - libnr/nr-gradient.h \ libnr/nr-i-coord.h \ libnr/nr-macros.h \ - libnr/nr-matrix-div.cpp \ - libnr/nr-matrix-div.h \ libnr/nr-matrix-fns.cpp \ libnr/nr-matrix-fns.h \ libnr/nr-matrix-ops.h \ @@ -33,12 +28,8 @@ ink_common_sources += \ libnr/nr-object.cpp \ libnr/nr-object.h \ libnr/nr-path-code.h \ - libnr/nr-pixblock-line.cpp \ - libnr/nr-pixblock-line.h \ libnr/nr-pixblock-pattern.cpp \ libnr/nr-pixblock-pattern.h \ - libnr/nr-pixblock-pixel.cpp \ - libnr/nr-pixblock-pixel.h \ libnr/nr-pixblock.cpp \ libnr/nr-pixblock.h \ libnr/nr-pixops.h \ diff --git a/src/libnr/nr-convex-hull-ops.h b/src/libnr/nr-convex-hull-ops.h deleted file mode 100644 index 2e96bf367..000000000 --- a/src/libnr/nr-convex-hull-ops.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef SEEN_NR_CONVEX_HULL_FNS_H -#define SEEN_NR_CONVEX_HULL_FNS_H - -/* ex:set et ts=4 sw=4: */ - -/* - * A class representing the convex hull of a set of points. - * - * Copyright 2004 MenTaLguY <mental@rydia.net> - * - * This code is licensed under the GNU GPL; see COPYING for more information. - */ - -#include <libnr/nr-matrix-fns.h> -#include <libnr/nr-convex-hull.h> - -namespace NR { - -ConvexHull operator*(const Rect &r, const Matrix &m) { - ConvexHull points(r.corner(0)); - for ( unsigned i = 1 ; i < 4 ; i++ ) { - points.add(r.corner(i)); - } - return points; -} - -} /* namespace NR */ - -#endif diff --git a/src/libnr/nr-convex-hull.h b/src/libnr/nr-convex-hull.h deleted file mode 100644 index dafdd8840..000000000 --- a/src/libnr/nr-convex-hull.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef SEEN_NR_CONVEX_HULL_H -#define SEEN_NR_CONVEX_HULL_H - -/* ex:set et ts=4 sw=4: */ - -/* - * A class representing the convex hull of a set of points. - * - * Copyright 2004 MenTaLguY <mental@rydia.net> - * - * This code is licensed under the GNU GPL; see COPYING for more information. - */ - -#include <libnr/nr-rect.h> - -namespace NR { - -class ConvexHull { -public: - ConvexHull() : _bounds() {} - explicit ConvexHull(Point const &p) : _bounds(Rect(p, p)) {} - - boost::optional<Point> midpoint() const { - if (_bounds) { - return _bounds->midpoint(); - } else { - return boost::optional<Point>(); - } - } - - void add(Point const &p) { - if (_bounds) { - _bounds->expandTo(p); - } else { - _bounds = Rect(p, p); - } - } - void add(Rect const &r) { - // Note that this is a hack. when convexhull actually works - // you will need to add all four points. - _bounds = union_bounds(_bounds, r); - } - void add(ConvexHull const &h) { - if (h._bounds) { - add(*h._bounds); - } - } - - boost::optional<Rect> const &bounds() const { - return _bounds; - } - -private: - boost::optional<Rect> _bounds; -}; - -} /* namespace NR */ - -#endif diff --git a/src/libnr/nr-gradient.cpp b/src/libnr/nr-gradient.cpp deleted file mode 100644 index e6eb9b79c..000000000 --- a/src/libnr/nr-gradient.cpp +++ /dev/null @@ -1,554 +0,0 @@ -#define __NR_GRADIENT_C__ - -/* - * Pixel buffer rendering library - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * MenTaLguY <mental@rydia.net> - *...Jasper van de Gronde <th.v.d.gronde@hccnet.nl> - * - * Copyright (C) 2009 Jasper van de Gronde - * Copyright (C) 2007 MenTaLguY - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -/* - * Derived in part from public domain code by Lauris Kaplinski - */ - -#include <cstring> -#include <libnr/nr-pixops.h> -#include <libnr/nr-pixblock-pixel.h> -#include <libnr/nr-blit.h> -#include <libnr/nr-gradient.h> -#include <libnr/nr-matrix-ops.h> -#include <glib/gtypes.h> -#include <stdio.h> - -/* Common */ - -#define NRG_MASK (NR_GRADIENT_VECTOR_LENGTH - 1) -#define NRG_2MASK ((long long) ((NR_GRADIENT_VECTOR_LENGTH << 1) - 1)) - -namespace { -inline unsigned char const *vector_index(int idx, - unsigned char const *vector) -{ - return vector + 4 * idx; -} - -template <NRGradientSpread spread> struct Spread; - -template <> -struct Spread<NR_GRADIENT_SPREAD_PAD> { -static double index_at(NR::Coord r, double const unity = 1.0) { - return r<0.0?0.0:r>unity?unity:r; -} -static unsigned char const *color_at(NR::Coord r, - unsigned char const *vector) -{ - return vector_index((int)(index_at(r, NR_GRADIENT_VECTOR_LENGTH - 1)+.5), vector); - //return vector_index((int)CLAMP(r, 0, (double)(NR_GRADIENT_VECTOR_LENGTH - 1)), vector); -} -}; - -template <> -struct Spread<NR_GRADIENT_SPREAD_REPEAT> { -static double index_at(NR::Coord r, double const unity = 1.0) { - return r<0.0?(unity+fmod(r,unity)):fmod(r,unity); -} -static unsigned char const *color_at(NR::Coord r, - unsigned char const *vector) -{ - return vector_index((int)(index_at(r, NR_GRADIENT_VECTOR_LENGTH - 1)+.5), vector); - //return vector_index((int)((long long)r & NRG_MASK), vector); -} -}; - -template <> -struct Spread<NR_GRADIENT_SPREAD_REFLECT> { -static double index_at(NR::Coord r, double const unity = 1.0) { - r = r<0.0?(2*unity+fmod(r,2*unity)):fmod(r,2*unity); - if (r>unity) r=2*unity-r; - return r; -} -static unsigned char const *color_at(NR::Coord r, - unsigned char const *vector) -{ - return vector_index((int)(index_at(r, NR_GRADIENT_VECTOR_LENGTH - 1)+.5), vector); - //int idx = (int) ((long long)r & NRG_2MASK); - //if (idx > NRG_MASK) idx = NRG_2MASK - idx; - //return vector_index(idx, vector); -} -}; - -template <NR_PIXBLOCK_MODE mode> struct ModeTraits; - -template <> -struct ModeTraits<NR_PIXBLOCK_MODE_R8G8B8A8N> { -static const unsigned bpp=4; -}; - -template <> -struct ModeTraits<NR_PIXBLOCK_MODE_R8G8B8A8P> { -static const unsigned bpp=4; -}; - -template <> -struct ModeTraits<NR_PIXBLOCK_MODE_R8G8B8> { -static const unsigned bpp=3; -}; - -template <> -struct ModeTraits<NR_PIXBLOCK_MODE_A8> { -static const unsigned bpp=1; -}; - -template <NR_PIXBLOCK_MODE mode, bool empty> -struct Compose { -static const unsigned bpp=ModeTraits<mode>::bpp; -static void compose(NRPixBlock *pb, unsigned char *dest, - NRPixBlock *spb, unsigned char const *src) -{ - nr_compose_pixblock_pixblock_pixel(pb, dest, spb, src); -} -}; - -template <> -struct Compose<NR_PIXBLOCK_MODE_R8G8B8A8N, true> { -static const unsigned bpp=4; -static void compose(NRPixBlock */*pb*/, unsigned char *dest, - NRPixBlock */*spb*/, unsigned char const *src) -{ - std::memcpy(dest, src, 4); -} -}; - -template <> -struct Compose<NR_PIXBLOCK_MODE_R8G8B8A8P, true> { -static const unsigned bpp=4; -static void compose(NRPixBlock */*pb*/, unsigned char *dest, - NRPixBlock */*spb*/, unsigned char const *src) -{ - dest[0] = NR_PREMUL_111(src[0], src[3]); - dest[1] = NR_PREMUL_111(src[1], src[3]); - dest[2] = NR_PREMUL_111(src[2], src[3]); - dest[3] = src[3]; -} -}; - -template <> -struct Compose<NR_PIXBLOCK_MODE_R8G8B8, true> { -static const unsigned bpp=3; -static void compose(NRPixBlock */*pb*/, unsigned char *dest, - NRPixBlock */*spb*/, unsigned char const *src) -{ - dest[0] = NR_COMPOSEN11_1111(src[0], src[3], 255); - dest[1] = NR_COMPOSEN11_1111(src[1], src[3], 255); - dest[2] = NR_COMPOSEN11_1111(src[2], src[3], 255); -} -}; - -template <> -struct Compose<NR_PIXBLOCK_MODE_A8, true> { -static const unsigned bpp=1; -static void compose(NRPixBlock */*pb*/, unsigned char *dest, - NRPixBlock */*spb*/, unsigned char const *src) -{ - dest[0] = src[3]; -} -}; - -template <> -struct Compose<NR_PIXBLOCK_MODE_R8G8B8A8N, false> { -static const unsigned bpp=4; -static void compose(NRPixBlock */*pb*/, unsigned char *dest, - NRPixBlock */*spb*/, unsigned char const *src) -{ - unsigned int ca; - ca = NR_COMPOSEA_112(src[3], dest[3]); - dest[0] = NR_COMPOSENNN_111121(src[0], src[3], dest[0], dest[3], ca); - dest[1] = NR_COMPOSENNN_111121(src[1], src[3], dest[1], dest[3], ca); - dest[2] = NR_COMPOSENNN_111121(src[2], src[3], dest[2], dest[3], ca); - dest[3] = NR_NORMALIZE_21(ca); -} -}; - -template <> -struct Compose<NR_PIXBLOCK_MODE_R8G8B8A8P, false> { -static const unsigned bpp=4; -static void compose(NRPixBlock */*pb*/, unsigned char *dest, - NRPixBlock */*spb*/, unsigned char const *src) -{ - dest[0] = NR_COMPOSENPP_1111(src[0], src[3], dest[0]); - dest[1] = NR_COMPOSENPP_1111(src[1], src[3], dest[1]); - dest[2] = NR_COMPOSENPP_1111(src[2], src[3], dest[2]); - dest[3] = NR_COMPOSEA_111(src[3], dest[3]); -} -}; - -template <> -struct Compose<NR_PIXBLOCK_MODE_R8G8B8, false> { -static const unsigned bpp=3; -static void compose(NRPixBlock */*pb*/, unsigned char *dest, - NRPixBlock */*spb*/, unsigned char const *src) -{ - dest[0] = NR_COMPOSEN11_1111(src[0], src[3], dest[0]); - dest[1] = NR_COMPOSEN11_1111(src[1], src[3], dest[1]); - dest[2] = NR_COMPOSEN11_1111(src[2], src[3], dest[2]); -} -}; - -template <typename Subtype, typename spread> -static void -render_spread(NRGradientRenderer *gr, NRPixBlock *pb) -{ - switch (pb->mode) { - case NR_PIXBLOCK_MODE_R8G8B8A8N: - if (pb->empty) { - typedef Compose<NR_PIXBLOCK_MODE_R8G8B8A8N, true> compose; - Subtype::template render<compose, spread>(gr, pb); - } else { - typedef Compose<NR_PIXBLOCK_MODE_R8G8B8A8N, false> compose; - Subtype::template render<compose, spread>(gr, pb); - } - break; - case NR_PIXBLOCK_MODE_R8G8B8A8P: - if (pb->empty) { - typedef Compose<NR_PIXBLOCK_MODE_R8G8B8A8P, true> compose; - Subtype::template render<compose, spread>(gr, pb); - } else { - typedef Compose<NR_PIXBLOCK_MODE_R8G8B8A8P, false> compose; - Subtype::template render<compose, spread>(gr, pb); - } - break; - case NR_PIXBLOCK_MODE_R8G8B8: - if (pb->empty) { - typedef Compose<NR_PIXBLOCK_MODE_R8G8B8, true> compose; - Subtype::template render<compose, spread>(gr, pb); - } else { - typedef Compose<NR_PIXBLOCK_MODE_R8G8B8, false> compose; - Subtype::template render<compose, spread>(gr, pb); - } - break; - case NR_PIXBLOCK_MODE_A8: - if (pb->empty) { - typedef Compose<NR_PIXBLOCK_MODE_A8, true> compose; - Subtype::template render<compose, spread>(gr, pb); - } else { - typedef Compose<NR_PIXBLOCK_MODE_A8, false> compose; - Subtype::template render<compose, spread>(gr, pb); - } - break; - } -} - -template <typename Subtype> -static void -render(NRRenderer *r, NRPixBlock *pb, NRPixBlock */*m*/) -{ - NRGradientRenderer *gr = static_cast<NRGradientRenderer *>(r); - - switch (gr->spread) { - case NR_GRADIENT_SPREAD_REPEAT: - render_spread<Subtype, Spread<NR_GRADIENT_SPREAD_REPEAT> >(gr, pb); - break; - case NR_GRADIENT_SPREAD_REFLECT: - render_spread<Subtype, Spread<NR_GRADIENT_SPREAD_REFLECT> >(gr, pb); - break; - case NR_GRADIENT_SPREAD_PAD: - default: - render_spread<Subtype, Spread<NR_GRADIENT_SPREAD_PAD> >(gr, pb); - } -} -} - -/* Linear */ - -namespace { - -struct Linear { -template <typename compose, typename spread> -static void render(NRGradientRenderer *gr, NRPixBlock *pb) { - NRLGradientRenderer *lgr = static_cast<NRLGradientRenderer *>(gr); - - int x, y; - unsigned char *d; - double pos; - NRPixBlock spb; - int x0, y0, width, height, rs; - - x0 = pb->area.x0; - y0 = pb->area.y0; - width = pb->area.x1 - pb->area.x0; - height = pb->area.y1 - pb->area.y0; - rs = pb->rs; - - nr_pixblock_setup_extern(&spb, NR_PIXBLOCK_MODE_R8G8B8A8N, - 0, 0, NR_GRADIENT_VECTOR_LENGTH, 1, - (unsigned char *) lgr->vector, - 4 * NR_GRADIENT_VECTOR_LENGTH, 0, 0); - - for (y = 0; y < height; y++) { - d = NR_PIXBLOCK_PX(pb) + y * rs; - pos = (y + y0 - lgr->y0) * lgr->dy + (0 + x0 - lgr->x0) * lgr->dx; - for (x = 0; x < width; x++) { - unsigned char const *s=spread::color_at(pos, lgr->vector); - compose::compose(pb, d, &spb, s); - d += compose::bpp; - pos += lgr->dx; - } - } - - nr_pixblock_release(&spb); -} -}; - -} - -NRRenderer * -nr_lgradient_renderer_setup (NRLGradientRenderer *lgr, - const unsigned char *cv, - unsigned int spread, - const NR::Matrix *gs2px, - float x0, float y0, - float x1, float y1) -{ - NR::Matrix n2gs, n2px, px2n; - - lgr->render = &render<Linear>; - - lgr->vector = cv; - lgr->spread = spread; - - n2gs[0] = x1 - x0; - n2gs[1] = y1 - y0; - n2gs[2] = y1 - y0; - n2gs[3] = x0 - x1; - n2gs[4] = x0; - n2gs[5] = y0; - - n2px = n2gs * (*gs2px); - px2n = n2px.inverse(); - - lgr->x0 = n2px[4] - 0.5; // These -0.5 offsets make sure that the gradient is sampled in the MIDDLE of each pixel. - lgr->y0 = n2px[5] - 0.5; - lgr->dx = px2n[0] * (NR_GRADIENT_VECTOR_LENGTH-1); - lgr->dy = px2n[2] * (NR_GRADIENT_VECTOR_LENGTH-1); - - return (NRRenderer *) lgr; -} - -/* Radial */ - -/* - * The archetype is following - * - * gx gy - pixel coordinates - * Px Py - coordinates, where Fx Fy - gx gy line intersects with circle - * - * (1) (gx - fx) * (Py - fy) = (gy - fy) * (Px - fx) - * (2) (Px - cx) * (Px - cx) + (Py - cy) * (Py - cy) = r * r - * - * (3) Py = (Px - fx) * (gy - fy) / (gx - fx) + fy - * (4) (gy - fy) / (gx - fx) = D - * (5) Py = D * Px - D * fx + fy - * - * (6) D * fx - fy + cy = N - * (7) Px * Px - 2 * Px * cx + cx * cx + (D * Px) * (D * Px) - 2 * (D * Px) * N + N * N = r * r - * (8) (D * D + 1) * (Px * Px) - 2 * (cx + D * N) * Px + cx * cx + N * N = r * r - * - * (9) A = D * D + 1 - * (10) B = -2 * (cx + D * N) - * (11) C = cx * cx + N * N - r * r - * - * (12) Px = (-B +- SQRT(B * B - 4 * A * C)) / 2 * A - */ - -namespace { - -struct SymmetricRadial { -template <typename compose, typename spread> -static void render(NRGradientRenderer *gr, NRPixBlock *pb) -{ - NRRGradientRenderer *rgr = static_cast<NRRGradientRenderer *>(gr); - - NR::Coord const dx = rgr->px2gs[0]; - NR::Coord const dy = rgr->px2gs[1]; - - NRPixBlock spb; - nr_pixblock_setup_extern(&spb, NR_PIXBLOCK_MODE_R8G8B8A8N, - 0, 0, NR_GRADIENT_VECTOR_LENGTH, 1, - (unsigned char *) rgr->vector, - 4 * NR_GRADIENT_VECTOR_LENGTH, - 0, 0); - - for (int y = pb->area.y0; y < pb->area.y1; y++) { - unsigned char *d = NR_PIXBLOCK_PX(pb) + (y - pb->area.y0) * pb->rs; - NR::Coord gx = rgr->px2gs[0] * pb->area.x0 + rgr->px2gs[2] * y + rgr->px2gs[4]; - NR::Coord gy = rgr->px2gs[1] * pb->area.x0 + rgr->px2gs[3] * y + rgr->px2gs[5]; - for (int x = pb->area.x0; x < pb->area.x1; x++) { - NR::Coord const pos = sqrt(((gx*gx) + (gy*gy))); - unsigned char const *s=spread::color_at(pos, rgr->vector); - compose::compose(pb, d, &spb, s); - d += compose::bpp; - gx += dx; - gy += dy; - } - } - - nr_pixblock_release(&spb); -} -}; - -struct Radial { -template <typename compose, typename spread> -static void render(NRGradientRenderer *gr, NRPixBlock *pb) -{ - NRRGradientRenderer *rgr = static_cast<NRRGradientRenderer *>(gr); - int const x0 = pb->area.x0; - int const y0 = pb->area.y0; - int const x1 = pb->area.x1; - int const y1 = pb->area.y1; - int const rs = pb->rs; - - NRPixBlock spb; - nr_pixblock_setup_extern(&spb, NR_PIXBLOCK_MODE_R8G8B8A8N, - 0, 0, NR_GRADIENT_VECTOR_LENGTH, 1, - (unsigned char *) rgr->vector, - 4 * NR_GRADIENT_VECTOR_LENGTH, - 0, 0); - - for (int y = y0; y < y1; y++) { - unsigned char *d = NR_PIXBLOCK_PX(pb) + (y - y0) * rs; - NR::Coord gx = rgr->px2gs[0] * x0 + rgr->px2gs[2] * y + rgr->px2gs[4]; - NR::Coord gy = rgr->px2gs[1] * x0 + rgr->px2gs[3] * y + rgr->px2gs[5]; - NR::Coord const dx = rgr->px2gs[0]; - NR::Coord const dy = rgr->px2gs[1]; - for (int x = x0; x < x1; x++) { - NR::Coord const gx2 = gx * gx; - NR::Coord const gxy2 = gx2 + gy * gy; - NR::Coord const qgx2_4 = gx2 - rgr->C * gxy2; - /* INVARIANT: qgx2_4 >= 0.0 */ - /* qgx2_4 = MAX(qgx2_4, 0.0); */ - NR::Coord const pxgx = gx + sqrt(qgx2_4); - /* We can safely divide by 0 here */ - /* If we are sure pxgx cannot be -0 */ - NR::Coord const pos = gxy2 / pxgx * (NR_GRADIENT_VECTOR_LENGTH-1); - - unsigned char const *s; - if (pos < (1U << 31)) { - s = spread::color_at(pos, rgr->vector); - } else { - s = vector_index(NR_GRADIENT_VECTOR_LENGTH - 1, rgr->vector); - } - - compose::compose(pb, d, &spb, s); - d += compose::bpp; - - gx += dx; - gy += dy; - } - } - - nr_pixblock_release(&spb); -} -}; - -} - -static void nr_rgradient_render_block_end(NRRenderer *r, NRPixBlock *pb, NRPixBlock *m); - -NRRenderer * -nr_rgradient_renderer_setup(NRRGradientRenderer *rgr, - unsigned char const *cv, - unsigned spread, - NR::Matrix const *gs2px, - float cx, float cy, - float fx, float fy, - float r) -{ - rgr->vector = cv; - rgr->spread = spread; - - if (r < NR_EPSILON) { - rgr->render = nr_rgradient_render_block_end; - } else if (NR_DF_TEST_CLOSE(cx, fx, NR_EPSILON) && - NR_DF_TEST_CLOSE(cy, fy, NR_EPSILON)) { - rgr->render = render<SymmetricRadial>; - - rgr->px2gs = gs2px->inverse(); - rgr->px2gs[0] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r; - rgr->px2gs[1] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r; - rgr->px2gs[2] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r; - rgr->px2gs[3] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r; - rgr->px2gs[4] -= cx; - rgr->px2gs[5] -= cy; - rgr->px2gs[4] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r; - rgr->px2gs[5] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r; - rgr->px2gs[4] += 0.5*(rgr->px2gs[0]+rgr->px2gs[2]); // These offsets make sure the gradient is sampled in the MIDDLE of each pixel - rgr->px2gs[5] += 0.5*(rgr->px2gs[1]+rgr->px2gs[3]); - - rgr->cx = 0.0; - rgr->cy = 0.0; - rgr->fx = rgr->cx; - rgr->fy = rgr->cy; - rgr->r = 1.0; - } else { - rgr->render = render<Radial>; - - NR::Coord const df = hypot(fx - cx, fy - cy); - if (df >= r) { - fx = cx + (fx - cx ) * r / (float) df; - fy = cy + (fy - cy ) * r / (float) df; - } - - NR::Matrix n2gs; - n2gs[0] = cx - fx; - n2gs[1] = cy - fy; - n2gs[2] = cy - fy; - n2gs[3] = fx - cx; - n2gs[4] = fx; - n2gs[5] = fy; - - NR::Matrix n2px; - n2px = n2gs * (*gs2px); - rgr->px2gs = n2px.inverse(); - rgr->px2gs[4] += 0.5*(rgr->px2gs[0]+rgr->px2gs[2]); // These offsets make sure the gradient is sampled in the MIDDLE of each pixel - rgr->px2gs[5] += 0.5*(rgr->px2gs[1]+rgr->px2gs[3]); - - rgr->cx = 1.0; - rgr->cy = 0.0; - rgr->fx = 0.0; - rgr->fy = 0.0; - rgr->r = r / (float) hypot(fx - cx, fy - cy); - rgr->C = 1.0F - rgr->r * rgr->r; - /* INVARIANT: C < 0 */ - rgr->C = MIN(rgr->C, -NR_EPSILON); - } - - return (NRRenderer *) rgr; -} - -static void -nr_rgradient_render_block_end(NRRenderer *r, NRPixBlock *pb, NRPixBlock *m) -{ - unsigned char const *c = ((NRRGradientRenderer *) r)->vector + 4 * (NR_GRADIENT_VECTOR_LENGTH - 1); - - nr_blit_pixblock_mask_rgba32(pb, m, (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]); -} - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-gradient.h b/src/libnr/nr-gradient.h deleted file mode 100644 index 1073f36ae..000000000 --- a/src/libnr/nr-gradient.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef __NR_GRADIENT_H__ -#define __NR_GRADIENT_H__ - -/* - * Pixel buffer rendering library - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -/* - * Derived in part from public domain code by Lauris Kaplinski - */ - -#include <libnr/nr-matrix.h> -#include <libnr/nr-render.h> - -#define NR_GRADIENT_VECTOR_BITS 10 -#define NR_GRADIENT_VECTOR_LENGTH (1<<NR_GRADIENT_VECTOR_BITS) - -enum NRGradientSpread { - NR_GRADIENT_SPREAD_PAD, - NR_GRADIENT_SPREAD_REFLECT, - NR_GRADIENT_SPREAD_REPEAT -}; - -struct NRGradientRenderer : public NRRenderer { - const unsigned char *vector; - unsigned int spread; -}; - -/* Linear */ - -struct NRLGradientRenderer : public NRGradientRenderer { - double x0, y0; - double dx, dy; -}; - -NRRenderer *nr_lgradient_renderer_setup (NRLGradientRenderer *lgr, - const unsigned char *cv, - unsigned int spread, - const NR::Matrix *gs2px, - float x0, float y0, - float x1, float y1); - -/* Radial */ - -struct NRRGradientRenderer : public NRGradientRenderer { - NR::Matrix px2gs; - float cx, cy; - float fx, fy; - float r; - float C; -}; - -NRRenderer *nr_rgradient_renderer_setup (NRRGradientRenderer *rgr, - const unsigned char *cv, - unsigned int spread, - const NR::Matrix *gs2px, - float cx, float cy, - float fx, float fy, - float r); - - - -#endif -/* - * Local Variables: - * mode:c++ - * c-file-style:"stroustrup" - * c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - * indent-tabs-mode:nil - * fill-column:99 - * End: - */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-matrix-div.cpp b/src/libnr/nr-matrix-div.cpp deleted file mode 100644 index d6fb598b8..000000000 --- a/src/libnr/nr-matrix-div.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "libnr/nr-matrix-ops.h" -#include "libnr/nr-point-matrix-ops.h" - -NR::Point operator/(NR::Point const &p, NR::Matrix const &m) { - return p * m.inverse(); -} - -NR::Matrix operator/(NR::Matrix const &a, NR::Matrix const &b) { - return a * b.inverse(); -} - - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/libnr/nr-matrix-div.h b/src/libnr/nr-matrix-div.h deleted file mode 100644 index 8669e2ce2..000000000 --- a/src/libnr/nr-matrix-div.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef SEEN_LIBNR_NR_MATRIX_DIV_H -#define SEEN_LIBNR_NR_MATRIX_DIV_H - -#include "libnr/nr-forward.h" - -NR::Point operator/(NR::Point const &, NR::Matrix const &); - -NR::Matrix operator/(NR::Matrix const &, NR::Matrix const &); - -#endif /* !SEEN_LIBNR_NR_MATRIX_DIV_H */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/libnr/nr-pixblock-line.cpp b/src/libnr/nr-pixblock-line.cpp deleted file mode 100644 index eb8b404b4..000000000 --- a/src/libnr/nr-pixblock-line.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#define __NR_PIXBLOCK_LINE_C__ - -/* - * Pixel buffer rendering library - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * This code is in public domain - */ - -#include <libnr/nr-pixops.h> -#include <libnr/nr-pixblock-pixel.h> - -void -nr_pixblock_draw_line_rgba32 (NRPixBlock *d, long x0, long y0, long x1, long y1, short /*first*/, unsigned long rgba) -{ - long deltax, deltay, xinc1, xinc2, yinc1, yinc2; - long den, num, numadd, numpixels; - long x, y, curpixel; - /* Pixblock */ - int dbpp; - NRPixBlock spb; - unsigned char *spx; - - if (x1 >= x0) { - deltax = x1 - x0; - xinc1 = 1; - xinc2 = 1; - } else { - deltax = x0 - x1; - xinc1 = -1; - xinc2 = -1; - } - - if (y1 >= y0) { - deltay = y1 - y0; - yinc1 = 1; - yinc2 = 1; - } else { - deltay = y0 - y1; - yinc1 = -1; - yinc2 = -1; - } - - if (deltax >= deltay) { - xinc1 = 0; - yinc2 = 0; - den = deltax; - num = deltax / 2; - numadd = deltay; - numpixels = deltax; - } else { - xinc2 = 0; - yinc1 = 0; - den = deltay; - num = deltay / 2; - numadd = deltax; - numpixels = deltay; - } - - /* We can be quite sure 1x1 pixblock is TINY */ - nr_pixblock_setup_fast (&spb, NR_PIXBLOCK_MODE_R8G8B8A8N, 0, 0, 1, 1, 0); - spb.empty = 0; - spx = NR_PIXBLOCK_PX (&spb); - spx[0] = NR_RGBA32_R (rgba); - spx[1] = NR_RGBA32_G (rgba); - spx[2] = NR_RGBA32_B (rgba); - spx[3] = NR_RGBA32_A (rgba); - - dbpp = NR_PIXBLOCK_BPP (d); - - x = x0; - y = y0; - - for (curpixel = 0; curpixel <= numpixels; curpixel++) { - if ((x >= d->area.x0) && (y >= d->area.y0) && (x < d->area.x1) && (y < d->area.y1)) { - nr_compose_pixblock_pixblock_pixel (d, NR_PIXBLOCK_PX (d) + (y - d->area.y0) * d->rs + (x - d->area.x0) * dbpp, &spb, spx); - } - num += numadd; - if (num >= den) { - num -= den; - x += xinc1; - y += yinc1; - } - x += xinc2; - y += yinc2; - } - - nr_pixblock_release (&spb); -} - diff --git a/src/libnr/nr-pixblock-line.h b/src/libnr/nr-pixblock-line.h deleted file mode 100644 index 7fd58a0ab..000000000 --- a/src/libnr/nr-pixblock-line.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __NR_PIXBLOCK_LINE_H__ -#define __NR_PIXBLOCK_LINE_H__ - -/* - * Pixel buffer rendering library - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * This code is in public domain - */ - -#include <libnr/nr-pixblock.h> - -void nr_pixblock_draw_line_rgba32 (NRPixBlock *d, long x0, long y0, long x1, long y1, short first, unsigned long rgba); - -#endif - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-pixblock-pixel.cpp b/src/libnr/nr-pixblock-pixel.cpp deleted file mode 100644 index 109ed69dc..000000000 --- a/src/libnr/nr-pixblock-pixel.cpp +++ /dev/null @@ -1,230 +0,0 @@ -#define __NR_PIXBLOCK_PIXEL_C__ - -/* - * Pixel buffer rendering library - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * This code is in public domain - */ - -#include "nr-pixops.h" -#include "nr-pixblock-pixel.h" - -void -nr_compose_pixblock_pixblock_pixel (NRPixBlock *dpb, unsigned char *d, const NRPixBlock *spb, const unsigned char *s) -{ - if (spb->empty) return; - - if (dpb->empty) { - /* Empty destination */ - switch (dpb->mode) { - case NR_PIXBLOCK_MODE_A8: - switch (spb->mode) { - case NR_PIXBLOCK_MODE_A8: - break; - case NR_PIXBLOCK_MODE_R8G8B8: - d[0] = 255; - break; - case NR_PIXBLOCK_MODE_R8G8B8A8N: - d[0] = s[3]; - break; - case NR_PIXBLOCK_MODE_R8G8B8A8P: - d[0] = s[3]; - break; - default: - break; - } - break; - case NR_PIXBLOCK_MODE_R8G8B8: - switch (spb->mode) { - case NR_PIXBLOCK_MODE_A8: - break; - case NR_PIXBLOCK_MODE_R8G8B8: - d[0] = s[0]; - d[1] = s[1]; - d[2] = s[2]; - break; - case NR_PIXBLOCK_MODE_R8G8B8A8N: - d[0] = NR_COMPOSEN11_1111 (s[0], s[3], 255); - d[1] = NR_COMPOSEN11_1111 (s[1], s[3], 255); - d[2] = NR_COMPOSEN11_1111 (s[2], s[3], 255); - break; - case NR_PIXBLOCK_MODE_R8G8B8A8P: - d[0] = NR_COMPOSEP11_1111 (s[0], s[3], 255); - d[1] = NR_COMPOSEP11_1111 (s[1], s[3], 255); - d[2] = NR_COMPOSEP11_1111 (s[2], s[3], 255); - break; - default: - break; - } - break; - case NR_PIXBLOCK_MODE_R8G8B8A8N: - switch (spb->mode) { - case NR_PIXBLOCK_MODE_A8: - break; - case NR_PIXBLOCK_MODE_R8G8B8: - d[0] = s[0]; - d[1] = s[1]; - d[2] = s[2]; - d[3] = 255; - break; - case NR_PIXBLOCK_MODE_R8G8B8A8N: - d[0] = s[0]; - d[1] = s[1]; - d[2] = s[2]; - d[3] = s[3]; - break; - case NR_PIXBLOCK_MODE_R8G8B8A8P: - if (s[3] == 0) { - d[0] = 255; - d[1] = 255; - d[2] = 255; - } else { - d[0] = NR_DEMUL_111(s[0], s[3]); - d[1] = NR_DEMUL_111(s[0], s[3]); - d[2] = NR_DEMUL_111(s[0], s[3]); - } - d[3] = s[3]; - break; - default: - break; - } - break; - case NR_PIXBLOCK_MODE_R8G8B8A8P: - switch (spb->mode) { - case NR_PIXBLOCK_MODE_A8: - break; - case NR_PIXBLOCK_MODE_R8G8B8: - d[0] = s[0]; - d[1] = s[1]; - d[2] = s[2]; - d[3] = 255; - break; - case NR_PIXBLOCK_MODE_R8G8B8A8N: - d[0] = NR_PREMUL_111 (s[0], s[3]); - d[1] = NR_PREMUL_111 (s[1], s[3]); - d[2] = NR_PREMUL_111 (s[2], s[3]); - d[3] = s[3]; - break; - case NR_PIXBLOCK_MODE_R8G8B8A8P: - d[0] = s[0]; - d[1] = s[1]; - d[2] = s[2]; - d[3] = s[3]; - break; - default: - break; - } - break; - default: - break; - } - } else { - /* Image destination */ - switch (dpb->mode) { - case NR_PIXBLOCK_MODE_A8: - switch (spb->mode) { - case NR_PIXBLOCK_MODE_A8: - break; - case NR_PIXBLOCK_MODE_R8G8B8: - d[0] = 255; - break; - case NR_PIXBLOCK_MODE_R8G8B8A8N: - d[0] = NR_COMPOSEA_111(s[3], d[0]); - break; - case NR_PIXBLOCK_MODE_R8G8B8A8P: - d[0] = NR_COMPOSEA_111(s[3], d[0]); - break; - default: - break; - } - break; - case NR_PIXBLOCK_MODE_R8G8B8: - switch (spb->mode) { - case NR_PIXBLOCK_MODE_A8: - break; - case NR_PIXBLOCK_MODE_R8G8B8: - d[0] = s[0]; - d[1] = s[1]; - d[2] = s[2]; - break; - case NR_PIXBLOCK_MODE_R8G8B8A8N: - d[0] = NR_COMPOSEN11_1111 (s[0], s[3], d[0]); - d[1] = NR_COMPOSEN11_1111 (s[1], s[3], d[1]); - d[2] = NR_COMPOSEN11_1111 (s[2], s[3], d[2]); - break; - case NR_PIXBLOCK_MODE_R8G8B8A8P: - d[0] = NR_COMPOSEP11_1111 (s[0], s[3], d[0]); - d[1] = NR_COMPOSEP11_1111 (s[1], s[3], d[1]); - d[2] = NR_COMPOSEP11_1111 (s[2], s[3], d[2]); - break; - default: - break; - } - break; - case NR_PIXBLOCK_MODE_R8G8B8A8N: - switch (spb->mode) { - case NR_PIXBLOCK_MODE_A8: - break; - case NR_PIXBLOCK_MODE_R8G8B8: - d[0] = s[0]; - d[1] = s[1]; - d[2] = s[2]; - break; - case NR_PIXBLOCK_MODE_R8G8B8A8N: - if (s[3] != 0) { - unsigned int ca; - ca = NR_COMPOSEA_112(s[3], d[3]); - d[0] = NR_COMPOSENNN_111121 (s[0], s[3], d[0], d[3], ca); - d[1] = NR_COMPOSENNN_111121 (s[1], s[3], d[1], d[3], ca); - d[2] = NR_COMPOSENNN_111121 (s[2], s[3], d[2], d[3], ca); - d[3] = NR_NORMALIZE_21(ca); - } - break; - case NR_PIXBLOCK_MODE_R8G8B8A8P: - if (s[3] != 0) { - unsigned int ca; - ca = NR_COMPOSEA_112(s[3], d[3]); - d[0] = NR_COMPOSEPNN_111121 (s[0], s[3], d[0], d[3], ca); - d[1] = NR_COMPOSEPNN_111121 (s[1], s[3], d[0], d[3], ca); - d[2] = NR_COMPOSEPNN_111121 (s[2], s[3], d[0], d[3], ca); - d[3] = NR_NORMALIZE_21(ca); - } - break; - default: - break; - } - break; - case NR_PIXBLOCK_MODE_R8G8B8A8P: - switch (spb->mode) { - case NR_PIXBLOCK_MODE_A8: - break; - case NR_PIXBLOCK_MODE_R8G8B8: - d[0] = s[0]; - d[1] = s[1]; - d[2] = s[2]; - break; - case NR_PIXBLOCK_MODE_R8G8B8A8N: - d[0] = NR_COMPOSENPP_1111 (s[0], s[3], d[0]); - d[1] = NR_COMPOSENPP_1111 (s[1], s[3], d[1]); - d[2] = NR_COMPOSENPP_1111 (s[2], s[3], d[2]); - d[3] = NR_COMPOSEA_111(s[3], d[3]); - break; - case NR_PIXBLOCK_MODE_R8G8B8A8P: - d[0] = NR_COMPOSEPPP_1111 (s[0], s[3], d[0]); - d[1] = NR_COMPOSEPPP_1111 (s[1], s[3], d[1]); - d[2] = NR_COMPOSEPPP_1111 (s[2], s[3], d[2]); - d[3] = NR_COMPOSEA_111(s[3], d[3]); - break; - default: - break; - } - break; - default: - break; - } - } -} - diff --git a/src/libnr/nr-pixblock-pixel.h b/src/libnr/nr-pixblock-pixel.h deleted file mode 100644 index d989f53cf..000000000 --- a/src/libnr/nr-pixblock-pixel.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __NR_PIXBLOCK_PIXEL_H__ -#define __NR_PIXBLOCK_PIXEL_H__ - -/* - * Pixel buffer rendering library - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * This code is in public domain - */ - -#include <libnr/nr-pixblock.h> - -void nr_compose_pixblock_pixblock_pixel (NRPixBlock *dpb, unsigned char *d, const NRPixBlock *spb, const unsigned char *s); - -#endif - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/livarot/PathConversion.cpp b/src/livarot/PathConversion.cpp index bf1e9c5c9..57609d1a2 100644 --- a/src/livarot/PathConversion.cpp +++ b/src/livarot/PathConversion.cpp @@ -9,8 +9,6 @@ #include "Path.h" #include "Shape.h" #include "livarot/path-description.h" - -#include <libnr/nr-matrix.h> #include <2geom/transforms.h> /* diff --git a/src/livarot/PathCutting.cpp b/src/livarot/PathCutting.cpp index 4a5aec0f5..91f6f9ec4 100644 --- a/src/livarot/PathCutting.cpp +++ b/src/livarot/PathCutting.cpp @@ -20,7 +20,6 @@ #include "Path.h" #include "style.h" #include "livarot/path-description.h" -#include "libnr/nr-point-matrix-ops.h" #include "libnr/nr-convert2geom.h" #include <2geom/pathvector.h> #include <2geom/point.h> diff --git a/src/livarot/PathSimplify.cpp b/src/livarot/PathSimplify.cpp index 0f440de24..917bcbe7c 100644 --- a/src/livarot/PathSimplify.cpp +++ b/src/livarot/PathSimplify.cpp @@ -7,7 +7,6 @@ */ #include <glib/gmem.h> -#include <libnr/nr-point-matrix-ops.h> #include "livarot/Path.h" #include "livarot/path-description.h" diff --git a/src/livarot/ShapeSweep.cpp b/src/livarot/ShapeSweep.cpp index 00a0dd9a0..9ff633f1d 100644 --- a/src/livarot/ShapeSweep.cpp +++ b/src/livarot/ShapeSweep.cpp @@ -9,14 +9,14 @@ #include <cstdio> #include <cstdlib> #include <cstring> +#include <glib.h> #include <glib/gmem.h> +#include <2geom/matrix.h> #include "Shape.h" #include "livarot/sweep-event-queue.h" #include "livarot/sweep-tree-list.h" #include "livarot/sweep-tree.h" -#include "libnr/nr-matrix.h" - //int doDebug=0; /* diff --git a/src/livarot/path-description.cpp b/src/livarot/path-description.cpp index 9ecfb99d6..fd91cb447 100644 --- a/src/livarot/path-description.cpp +++ b/src/livarot/path-description.cpp @@ -1,5 +1,5 @@ -#include "libnr/nr-point-matrix-ops.h" #include "livarot/path-description.h" +#include <2geom/matrix.h> PathDescr *PathDescrMoveTo::clone() const { diff --git a/src/marker.cpp b/src/marker.cpp index e4c2e0c30..6917c0b71 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -18,12 +18,6 @@ #include <string> #include "config.h" - -#include "libnr/nr-matrix-fns.h" -#include "libnr/nr-matrix-ops.h" -#include "libnr/nr-matrix-translate-ops.h" -#include "libnr/nr-scale-matrix-ops.h" -#include "libnr/nr-translate-matrix-ops.h" #include "libnr/nr-convert2geom.h" #include <2geom/matrix.h> #include "svg/svg.h" diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index cc153aa71..42cfc0a5f 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -52,10 +52,6 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-conn-end.h" #include "dropper-context.h" #include <glibmm/i18n.h> -#include "libnr/nr-matrix-rotate-ops.h" -#include "libnr/nr-matrix-translate-ops.h" -#include "libnr/nr-scale-ops.h" -#include <libnr/nr-matrix-ops.h> #include <2geom/transforms.h> #include "xml/repr.h" #include "xml/rebase-hrefs.h" diff --git a/src/selection.h b/src/selection.h index b5a511e96..a79892eb5 100644 --- a/src/selection.h +++ b/src/selection.h @@ -21,8 +21,6 @@ #include <list> #include <sigc++/sigc++.h> -//#include "libnr/nr-rect.h" -#include "libnr/nr-convex-hull.h" #include "forward.h" #include "gc-managed.h" #include "gc-finalized.h" diff --git a/src/sp-gradient-fns.h b/src/sp-gradient-fns.h index dafa1646f..0fe10a5a1 100644 --- a/src/sp-gradient-fns.h +++ b/src/sp-gradient-fns.h @@ -23,9 +23,6 @@ class SPGradient; /** Forces vector to be built, if not present (i.e. changed) */ void sp_gradient_ensure_vector(SPGradient *gradient); -/** Ensures that color array is populated */ -void sp_gradient_ensure_colors(SPGradient *gradient); - void sp_gradient_set_units(SPGradient *gr, SPGradientUnits units); void sp_gradient_set_spread(SPGradient *gr, SPGradientSpread spread); @@ -35,8 +32,7 @@ SPGradientSpread sp_gradient_get_spread (SPGradient *gradient); void sp_gradient_repr_write_vector(SPGradient *gr); void sp_gradient_repr_clear_vector(SPGradient *gr); -void sp_gradient_render_vector_block_rgba(SPGradient *gr, guchar *px, gint w, gint h, gint rs, gint pos, gint span, bool horizontal); -void sp_gradient_render_vector_block_rgb(SPGradient *gr, guchar *px, gint w, gint h, gint rs, gint pos, gint span, bool horizontal); +cairo_pattern_t *sp_gradient_create_preview_pattern(SPGradient *gradient, double width); /** Transforms to/from gradient position space in given environment */ Geom::Matrix sp_gradient_get_g2d_matrix(SPGradient const *gr, Geom::Matrix const &ctm, diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index ba15f2651..982ce0d0e 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -32,8 +32,6 @@ #include <sigc++/adaptors/bind.h> #include "display/cairo-utils.h" -#include "libnr/nr-gradient.h" -#include "libnr/nr-pixops.h" #include "svg/svg.h" #include "svg/svg-color.h" #include "svg/css-ostringstream.h" @@ -390,8 +388,6 @@ sp_gradient_init(SPGradient *gr) gr->vector.built = false; gr->vector.stops.clear(); - gr->color = NULL; - new (&gr->modified_connection) sigc::connection(); } @@ -447,11 +443,6 @@ sp_gradient_release(SPObject *object) gradient->ref = NULL; } - if (gradient->color) { - g_free(gradient->color); - gradient->color = NULL; - } - gradient->modified_connection.~connection(); if (((SPObjectClass *) gradient_parent_class)->release) @@ -616,7 +607,7 @@ sp_gradient_modified(SPObject *object, guint flags) } if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - sp_gradient_ensure_colors(gr); + sp_gradient_ensure_vector(gr); } if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; @@ -966,12 +957,6 @@ sp_gradient_invalidate_vector(SPGradient *gr) { bool ret = false; - if (gr->color != NULL) { - g_free(gr->color); - gr->color = NULL; - ret = true; - } - if (gr->vector.built) { gr->vector.built = false; gr->vector.stops.clear(); @@ -1084,279 +1069,6 @@ sp_gradient_rebuild_vector(SPGradient *gr) gr->vector.built = true; } -/** - * The gradient's color array is newly created and set up from vector. - */ -void -sp_gradient_ensure_colors(SPGradient *gr) -{ - if (!gr->vector.built) { - sp_gradient_rebuild_vector(gr); - } - g_return_if_fail(!gr->vector.stops.empty()); - - /// \todo Where is the memory freed? - if (!gr->color) { - gr->color = g_new(guchar, 4 * NCOLORS); - } - - // This assumes that gr->vector is a zero-order B-spline (box function) approximation of the "true" gradient. - // This means that the "true" gradient must be prefiltered using a zero order B-spline and then sampled. - // Furthermore, the first element corresponds to offset="0" and the last element to offset="1". - - double remainder[4] = {0,0,0,0}; - double remainder_for_end[4] = {0,0,0,0}; // Used at the end - switch(gr->spread) { - case SP_GRADIENT_SPREAD_PAD: - remainder[0] = 0.5*gr->vector.stops[0].color.v.c[0]; // Half of the first cell uses the color of the first stop - remainder[1] = 0.5*gr->vector.stops[0].color.v.c[1]; - remainder[2] = 0.5*gr->vector.stops[0].color.v.c[2]; - remainder[3] = 0.5*gr->vector.stops[0].opacity; - remainder_for_end[0] = 0.5*gr->vector.stops[gr->vector.stops.size() - 1].color.v.c[0]; // Half of the first cell uses the color of the last stop - remainder_for_end[1] = 0.5*gr->vector.stops[gr->vector.stops.size() - 1].color.v.c[1]; - remainder_for_end[2] = 0.5*gr->vector.stops[gr->vector.stops.size() - 1].color.v.c[2]; - remainder_for_end[3] = 0.5*gr->vector.stops[gr->vector.stops.size() - 1].opacity; - break; - case SP_GRADIENT_SPREAD_REFLECT: - case SP_GRADIENT_SPREAD_REPEAT: - // These two are handled differently, see below. - break; - default: - g_error("Spread type not supported!"); - }; - for (unsigned int i = 0; i < gr->vector.stops.size() - 1; i++) { - double r0 = gr->vector.stops[i].color.v.c[0]; - double g0 = gr->vector.stops[i].color.v.c[1]; - double b0 = gr->vector.stops[i].color.v.c[2]; - double a0 = gr->vector.stops[i].opacity; - double r1 = gr->vector.stops[i+1].color.v.c[0]; - double g1 = gr->vector.stops[i+1].color.v.c[1]; - double b1 = gr->vector.stops[i+1].color.v.c[2]; - double a1 = gr->vector.stops[i+1].opacity; - double o0 = gr->vector.stops[i].offset * (NCOLORS-1); - double o1 = gr->vector.stops[i + 1].offset * (NCOLORS-1); - unsigned int ob = (unsigned int) floor(o0+.5); // These are the first and last element that might be affected by this interval. - unsigned int oe = (unsigned int) floor(o1+.5); // These need to be computed the same to ensure that ob will be covered by the next interval if oe==ob - - if (oe == ob) { - // Simple case, this interval starts and stops within one cell - // The contribution of this interval is: - // (o1-o0)*(c(o0)+c(o1))/2 - // = (o1-o0)*(c0+c1)/2 - double dt = 0.5*(o1-o0); - remainder[0] += dt*(r0 + r1); - remainder[1] += dt*(g0 + g1); - remainder[2] += dt*(b0 + b1); - remainder[3] += dt*(a0 + a1); - } else { - // First compute colors for the cells which are fully covered by the current interval. - // The prefiltered values are equal to the midpoint of each cell here. - // f = (j-o0)/(o1-o0) - // = j*(1/(o1-o0)) - o0/(o1-o0) - double f = (ob-o0) / (o1-o0); - double df = 1. / (o1-o0); - for (unsigned int j = ob+1; j < oe; j++) { - f += df; - gr->color[4 * j + 0] = (unsigned char) floor(255*(r0 + f*(r1-r0)) + .5); - gr->color[4 * j + 1] = (unsigned char) floor(255*(g0 + f*(g1-g0)) + .5); - gr->color[4 * j + 2] = (unsigned char) floor(255*(b0 + f*(b1-b0)) + .5); - gr->color[4 * j + 3] = (unsigned char) floor(255*(a0 + f*(a1-a0)) + .5); - } - - // Now handle the beginning - // The contribution of the last point is already in remainder. - // The contribution of this point is: - // (ob+.5-o0)*(c(o0)+c(ob+.5))/2 - // = (ob+.5-o0)*c((o0+ob+.5)/2) - // = (ob+.5-o0)*(c0+((o0+ob+.5)/2-o0)*df*(c1-c0)) - // = (ob+.5-o0)*(c0+(ob+.5-o0)*df*(c1-c0)/2) - double dt = ob+.5-o0; - f = 0.5*dt*df; - if (ob==0 && gr->spread==SP_GRADIENT_SPREAD_REFLECT) { - // The first half of the first cell is just a mirror image of the second half, so simply multiply it by 2. - gr->color[4 * ob + 0] = (unsigned char) floor(2*255*(remainder[0] + dt*(r0 + f*(r1-r0))) + .5); - gr->color[4 * ob + 1] = (unsigned char) floor(2*255*(remainder[1] + dt*(g0 + f*(g1-g0))) + .5); - gr->color[4 * ob + 2] = (unsigned char) floor(2*255*(remainder[2] + dt*(b0 + f*(b1-b0))) + .5); - gr->color[4 * ob + 3] = (unsigned char) floor(2*255*(remainder[3] + dt*(a0 + f*(a1-a0))) + .5); - } else if (ob==0 && gr->spread==SP_GRADIENT_SPREAD_REPEAT) { - // The first cell is the same as the last cell, so save whatever is in the second half here and deal with the rest later. - remainder_for_end[0] = remainder[0] + dt*(r0 + f*(r1-r0)); - remainder_for_end[1] = remainder[1] + dt*(g0 + f*(g1-g0)); - remainder_for_end[2] = remainder[2] + dt*(b0 + f*(b1-b0)); - remainder_for_end[3] = remainder[3] + dt*(a0 + f*(a1-a0)); - } else { - // The first half of the cell was already in remainder. - gr->color[4 * ob + 0] = (unsigned char) floor(255*(remainder[0] + dt*(r0 + f*(r1-r0))) + .5); - gr->color[4 * ob + 1] = (unsigned char) floor(255*(remainder[1] + dt*(g0 + f*(g1-g0))) + .5); - gr->color[4 * ob + 2] = (unsigned char) floor(255*(remainder[2] + dt*(b0 + f*(b1-b0))) + .5); - gr->color[4 * ob + 3] = (unsigned char) floor(255*(remainder[3] + dt*(a0 + f*(a1-a0))) + .5); - } - - // Now handle the end, which should end up in remainder - // The contribution of this point is: - // (o1-oe+.5)*(c(o1)+c(oe-.5))/2 - // = (o1-oe+.5)*c((o1+oe-.5)/2) - // = (o1-oe+.5)*(c0+((o1+oe-.5)/2-o0)*df*(c1-c0)) - dt = o1-oe+.5; - f = (0.5*(o1+oe-.5)-o0)*df; - remainder[0] = dt*(r0 + f*(r1-r0)); - remainder[1] = dt*(g0 + f*(g1-g0)); - remainder[2] = dt*(b0 + f*(b1-b0)); - remainder[3] = dt*(a0 + f*(a1-a0)); - } - } - switch(gr->spread) { - case SP_GRADIENT_SPREAD_PAD: - gr->color[4 * (NCOLORS-1) + 0] = (unsigned char) floor(255*(remainder[0]+remainder_for_end[0]) + .5); - gr->color[4 * (NCOLORS-1) + 1] = (unsigned char) floor(255*(remainder[1]+remainder_for_end[1]) + .5); - gr->color[4 * (NCOLORS-1) + 2] = (unsigned char) floor(255*(remainder[2]+remainder_for_end[2]) + .5); - gr->color[4 * (NCOLORS-1) + 3] = (unsigned char) floor(255*(remainder[3]+remainder_for_end[3]) + .5); - break; - case SP_GRADIENT_SPREAD_REFLECT: - // The second half is the same as the first half, so multiply by 2. - gr->color[4 * (NCOLORS-1) + 0] = (unsigned char) floor(2*255*remainder[0] + .5); - gr->color[4 * (NCOLORS-1) + 1] = (unsigned char) floor(2*255*remainder[1] + .5); - gr->color[4 * (NCOLORS-1) + 2] = (unsigned char) floor(2*255*remainder[2] + .5); - gr->color[4 * (NCOLORS-1) + 3] = (unsigned char) floor(2*255*remainder[3] + .5); - break; - case SP_GRADIENT_SPREAD_REPEAT: - // The second half is the same as the second half of the first cell (which was saved in remainder_for_end). - gr->color[0] = gr->color[4 * (NCOLORS-1) + 0] = (unsigned char) floor(255*(remainder[0]+remainder_for_end[0]) + .5); - gr->color[1] = gr->color[4 * (NCOLORS-1) + 1] = (unsigned char) floor(255*(remainder[1]+remainder_for_end[1]) + .5); - gr->color[2] = gr->color[4 * (NCOLORS-1) + 2] = (unsigned char) floor(255*(remainder[2]+remainder_for_end[2]) + .5); - gr->color[3] = gr->color[4 * (NCOLORS-1) + 3] = (unsigned char) floor(255*(remainder[3]+remainder_for_end[3]) + .5); - break; - } -} - -/** - * Renders gradient vector to buffer as line. - * - * RGB buffer background should be set up beforehand. - * - * @param len,width,height,rowstride Buffer parameters (1 or 2 dimensional). - * @param span Full integer width of requested gradient. - * @param pos Buffer starting position in span. - */ -static void -sp_gradient_render_vector_line_rgba(SPGradient *const gradient, guchar *buf, - gint const len, gint const pos, gint const span) -{ - g_return_if_fail(gradient != NULL); - g_return_if_fail(SP_IS_GRADIENT(gradient)); - g_return_if_fail(buf != NULL); - g_return_if_fail(len > 0); - g_return_if_fail(pos >= 0); - g_return_if_fail(pos + len <= span); - g_return_if_fail(span > 0); - - if (!gradient->color) { - sp_gradient_ensure_colors(gradient); - } - - gint idx = (pos * 1024 << 8) / span; - gint didx = (1024 << 8) / span; - - for (gint x = 0; x < len; x++) { - /// \todo Can this be done with 4 byte copies? - *buf++ = gradient->color[4 * (idx >> 8)]; - *buf++ = gradient->color[4 * (idx >> 8) + 1]; - *buf++ = gradient->color[4 * (idx >> 8) + 2]; - *buf++ = gradient->color[4 * (idx >> 8) + 3]; - idx += didx; - } -} - -/** - * Render rectangular RGBA area from gradient vector. - */ -void -sp_gradient_render_vector_block_rgba(SPGradient *const gradient, guchar *buf, - gint const width, gint const height, gint const rowstride, - gint const pos, gint const span, bool const horizontal) -{ - g_return_if_fail(gradient != NULL); - g_return_if_fail(SP_IS_GRADIENT(gradient)); - g_return_if_fail(buf != NULL); - g_return_if_fail(width > 0); - g_return_if_fail(height > 0); - g_return_if_fail(pos >= 0); - g_return_if_fail((horizontal && (pos + width <= span)) || (!horizontal && (pos + height <= span))); - g_return_if_fail(span > 0); - - if (horizontal) { - sp_gradient_render_vector_line_rgba(gradient, buf, width, pos, span); - for (gint y = 1; y < height; y++) { - memcpy(buf + y * rowstride, buf, 4 * width); - } - } else { - guchar *tmp = (guchar *)alloca(4 * height); - sp_gradient_render_vector_line_rgba(gradient, tmp, height, pos, span); - for (gint y = 0; y < height; y++) { - guchar *b = buf + y * rowstride; - for (gint x = 0; x < width; x++) { - *b++ = tmp[0]; - *b++ = tmp[1]; - *b++ = tmp[2]; - *b++ = tmp[3]; - } - tmp += 4; - } - } -} - -/** - * Render rectangular RGB area from gradient vector. - */ -void -sp_gradient_render_vector_block_rgb(SPGradient *gradient, guchar *buf, - gint const width, gint const height, gint const /*rowstride*/, - gint const pos, gint const span, bool const horizontal) -{ - g_return_if_fail(gradient != NULL); - g_return_if_fail(SP_IS_GRADIENT(gradient)); - g_return_if_fail(buf != NULL); - g_return_if_fail(width > 0); - g_return_if_fail(height > 0); - g_return_if_fail(pos >= 0); - g_return_if_fail((horizontal && (pos + width <= span)) || (!horizontal && (pos + height <= span))); - g_return_if_fail(span > 0); - - if (horizontal) { - guchar *tmp = (guchar*)alloca(4 * width); - sp_gradient_render_vector_line_rgba(gradient, tmp, width, pos, span); - for (gint y = 0; y < height; y++) { - guchar *t = tmp; - for (gint x = 0; x < width; x++) { - gint a = t[3]; - gint fc = (t[0] - buf[0]) * a; - buf[0] = buf[0] + ((fc + (fc >> 8) + 0x80) >> 8); - fc = (t[1] - buf[1]) * a; - buf[1] = buf[1] + ((fc + (fc >> 8) + 0x80) >> 8); - fc = (t[2] - buf[2]) * a; - buf[2] = buf[2] + ((fc + (fc >> 8) + 0x80) >> 8); - buf += 3; - t += 4; - } - } - } else { - guchar *tmp = (guchar*)alloca(4 * height); - sp_gradient_render_vector_line_rgba(gradient, tmp, height, pos, span); - for (gint y = 0; y < height; y++) { - guchar *t = tmp + 4 * y; - for (gint x = 0; x < width; x++) { - gint a = t[3]; - gint fc = (t[0] - buf[0]) * a; - buf[0] = buf[0] + ((fc + (fc >> 8) + 0x80) >> 8); - fc = (t[1] - buf[1]) * a; - buf[1] = buf[1] + ((fc + (fc >> 8) + 0x80) >> 8); - fc = (t[2] - buf[2]) * a; - buf[2] = buf[2] + ((fc + (fc >> 8) + 0x80) >> 8); - } - } - } -} - Geom::Matrix sp_gradient_get_g2d_matrix(SPGradient const *gr, Geom::Matrix const &ctm, Geom::Rect const &bbox) { @@ -1401,16 +1113,6 @@ sp_gradient_set_gs2d_matrix(SPGradient *gr, Geom::Matrix const &ctm, * Linear Gradient */ -class SPLGPainter; - -/// A context with linear gradient, painter, and gradient renderer. -struct SPLGPainter { - SPPainter painter; - SPLinearGradient *lg; - - NRLGradientRenderer lgr; -}; - static void sp_lineargradient_class_init(SPLinearGradientClass *klass); static void sp_lineargradient_init(SPLinearGradient *lg); @@ -1420,14 +1122,7 @@ static void sp_lineargradient_build(SPObject *object, static void sp_lineargradient_set(SPObject *object, unsigned key, gchar const *value); static Inkscape::XML::Node *sp_lineargradient_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); - -static SPPainter *sp_lineargradient_painter_new(SPPaintServer *ps, - Geom::Matrix const &full_transform, - Geom::Matrix const &parent_transform, - NRRect const *bbox); -static void sp_lineargradient_painter_free(SPPaintServer *ps, SPPainter *painter); static cairo_pattern_t *sp_lineargradient_create_pattern(SPPaintServer *ps, cairo_t *ct, NRRect const *bbox, double opacity); -static void sp_lg_fill(SPPainter *painter, NRPixBlock *pb); static SPGradientClass *lg_parent_class; @@ -1468,8 +1163,6 @@ static void sp_lineargradient_class_init(SPLinearGradientClass *klass) sp_object_class->set = sp_lineargradient_set; sp_object_class->write = sp_lineargradient_write; - ps_class->painter_new = sp_lineargradient_painter_new; - ps_class->painter_free = sp_lineargradient_painter_free; ps_class->pattern_new = sp_lineargradient_create_pattern; } @@ -1560,85 +1253,6 @@ sp_lineargradient_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inks } /** - * Create linear gradient context. - * - * Basically we have to deal with transformations - * - * 1) color2norm - maps point in (0,NCOLORS) vector to (0,1) vector - * 2) norm2pos - maps (0,1) vector to x1,y1 - x2,y2 - * 2) gradientTransform - * 3) bbox2user - * 4) ctm == userspace to pixel grid - * - * See also (*) in sp-pattern about why we may need parent_transform. - * - * \todo (point 1 above) fixme: I do not know how to deal with start > 0 - * and end < 1. - */ -static SPPainter * -sp_lineargradient_painter_new(SPPaintServer *ps, - Geom::Matrix const &full_transform, - Geom::Matrix const &/*parent_transform*/, - NRRect const *bbox) -{ - SPLinearGradient *lg = SP_LINEARGRADIENT(ps); - SPGradient *gr = SP_GRADIENT(ps); - - if (!gr->color) sp_gradient_ensure_colors(gr); - - SPLGPainter *lgp = g_new(SPLGPainter, 1); - - lgp->painter.type = SP_PAINTER_IND; - lgp->painter.fill = sp_lg_fill; - - lgp->lg = lg; - - /** \todo - * Technically speaking, we map NCOLORS on line [start,end] onto line - * [0,1]. I almost think we should fill color array start and end in - * that case. The alternative would be to leave these just empty garbage - * or something similar. Originally I had 1023.9999 here - not sure - * whether we have really to cut out ceil int (Lauris). - */ - Geom::Matrix color2norm(Geom::identity()); - Geom::Matrix color2px; - if (gr->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { - Geom::Matrix norm2pos(Geom::identity()); - - /* BBox to user coordinate system */ - Geom::Matrix bbox2user(bbox->x1 - bbox->x0, 0, 0, bbox->y1 - bbox->y0, bbox->x0, bbox->y0); - - Geom::Matrix color2pos = color2norm * norm2pos; - Geom::Matrix color2tpos = color2pos * gr->gradientTransform; - Geom::Matrix color2user = color2tpos * bbox2user; - color2px = color2user * full_transform; - - } else { - /* Problem: What to do, if we have mixed lengths and percentages? */ - /* Currently we do ignore percentages at all, but that is not good (lauris) */ - - Geom::Matrix norm2pos(Geom::identity()); - Geom::Matrix color2pos = color2norm * norm2pos; - Geom::Matrix color2tpos = color2pos * gr->gradientTransform; - color2px = color2tpos * full_transform; - - } - // TODO: remove color2px_nr after converting to 2geom - NR::Matrix color2px_nr = from_2geom(color2px); - nr_lgradient_renderer_setup(&lgp->lgr, gr->color, sp_gradient_get_spread(gr), &color2px_nr, - lg->x1.computed, lg->y1.computed, - lg->x2.computed, lg->y2.computed); - - return (SPPainter *) lgp; -} - -static void -sp_lineargradient_painter_free(SPPaintServer */*ps*/, SPPainter *painter) -{ - g_free(painter); -} - -/** * Directly set properties of linear gradient and request modified. */ void @@ -1658,35 +1272,10 @@ sp_lineargradient_set_position(SPLinearGradient *lg, SP_OBJECT(lg)->requestModified(SP_OBJECT_MODIFIED_FLAG); } -/** - * Callback when linear gradient object is rendered. - */ -static void -sp_lg_fill(SPPainter *painter, NRPixBlock *pb) -{ - SPLGPainter *lgp = (SPLGPainter *) painter; - - if (lgp->lg->color == NULL) { - sp_gradient_ensure_colors (lgp->lg); - lgp->lgr.vector = lgp->lg->color; - } - - nr_render((NRRenderer *) &lgp->lgr, pb, NULL); -} - /* * Radial Gradient */ -class SPRGPainter; - -/// A context with radial gradient, painter, and gradient renderer. -struct SPRGPainter { - SPPainter painter; - SPRadialGradient *rg; - NRRGradientRenderer rgr; -}; - static void sp_radialgradient_class_init(SPRadialGradientClass *klass); static void sp_radialgradient_init(SPRadialGradient *rg); @@ -1696,16 +1285,8 @@ static void sp_radialgradient_build(SPObject *object, static void sp_radialgradient_set(SPObject *object, unsigned key, gchar const *value); static Inkscape::XML::Node *sp_radialgradient_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); - -static SPPainter *sp_radialgradient_painter_new(SPPaintServer *ps, - Geom::Matrix const &full_transform, - Geom::Matrix const &parent_transform, - NRRect const *bbox); -static void sp_radialgradient_painter_free(SPPaintServer *ps, SPPainter *painter); static cairo_pattern_t *sp_radialgradient_create_pattern(SPPaintServer *ps, cairo_t *ct, NRRect const *bbox, double opacity); -static void sp_rg_fill(SPPainter *painter, NRPixBlock *pb); - static SPGradientClass *rg_parent_class; /** @@ -1745,8 +1326,6 @@ static void sp_radialgradient_class_init(SPRadialGradientClass *klass) sp_object_class->set = sp_radialgradient_set; sp_object_class->write = sp_radialgradient_write; - ps_class->painter_new = sp_radialgradient_painter_new; - ps_class->painter_free = sp_radialgradient_painter_free; ps_class->pattern_new = sp_radialgradient_create_pattern; } @@ -1858,67 +1437,6 @@ sp_radialgradient_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inks } /** - * Create radial gradient context. - */ -static SPPainter * -sp_radialgradient_painter_new(SPPaintServer *ps, - Geom::Matrix const &full_transform, - Geom::Matrix const &/*parent_transform*/, - NRRect const *bbox) -{ - SPRadialGradient *rg = SP_RADIALGRADIENT(ps); - SPGradient *gr = SP_GRADIENT(ps); - - if (!gr->color) sp_gradient_ensure_colors(gr); - - SPRGPainter *rgp = g_new(SPRGPainter, 1); - - rgp->painter.type = SP_PAINTER_IND; - rgp->painter.fill = sp_rg_fill; - - rgp->rg = rg; - - Geom::Matrix gs2px; - - if (gr->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { - /** \todo - * fixme: We may try to normalize here too, look at - * linearGradient (Lauris) - */ - - /* BBox to user coordinate system */ - Geom::Matrix bbox2user(bbox->x1 - bbox->x0, 0, 0, bbox->y1 - bbox->y0, bbox->x0, bbox->y0); - - Geom::Matrix gs2user = gr->gradientTransform * bbox2user; - - gs2px = gs2user * full_transform; - } else { - /** \todo - * Problem: What to do, if we have mixed lengths and percentages? - * Currently we do ignore percentages at all, but that is not - * good (lauris) - */ - - gs2px = gr->gradientTransform * full_transform; - } - // TODO: remove gs2px_nr after converting to 2geom - NR::Matrix gs2px_nr = from_2geom(gs2px); - nr_rgradient_renderer_setup(&rgp->rgr, gr->color, sp_gradient_get_spread(gr), - &gs2px_nr, - rg->cx.computed, rg->cy.computed, - rg->fx.computed, rg->fy.computed, - rg->r.computed); - - return (SPPainter *) rgp; -} - -static void -sp_radialgradient_painter_free(SPPaintServer */*ps*/, SPPainter *painter) -{ - g_free(painter); -} - -/** * Directly set properties of radial gradient and request modified. */ void @@ -1938,22 +1456,6 @@ sp_radialgradient_set_position(SPRadialGradient *rg, SP_OBJECT(rg)->requestModified(SP_OBJECT_MODIFIED_FLAG); } -/** - * Callback when radial gradient object is rendered. - */ -static void -sp_rg_fill(SPPainter *painter, NRPixBlock *pb) -{ - SPRGPainter *rgp = (SPRGPainter *) painter; - - if (rgp->rg->color == NULL) { - sp_gradient_ensure_colors (rgp->rg); - rgp->rgr.vector = rgp->rg->color; - } - - nr_render((NRRenderer *) &rgp->rgr, pb, NULL); -} - /* CAIRO RENDERING STUFF */ static void @@ -2003,7 +1505,7 @@ sp_radialgradient_create_pattern(SPPaintServer *ps, SPRadialGradient *rg = SP_RADIALGRADIENT(ps); SPGradient *gr = SP_GRADIENT(ps); - if (!gr->color) sp_gradient_ensure_colors(gr); + sp_gradient_ensure_vector(gr); cairo_pattern_t *cp = cairo_pattern_create_radial( rg->fx.computed, rg->fy.computed, 0, @@ -2023,7 +1525,7 @@ sp_lineargradient_create_pattern(SPPaintServer *ps, SPLinearGradient *lg = SP_LINEARGRADIENT(ps); SPGradient *gr = SP_GRADIENT(ps); - if (!gr->color) sp_gradient_ensure_colors(gr); + sp_gradient_ensure_vector(gr); cairo_pattern_t *cp = cairo_pattern_create_linear( lg->x1.computed, lg->y1.computed, @@ -2034,6 +1536,23 @@ sp_lineargradient_create_pattern(SPPaintServer *ps, return cp; } +cairo_pattern_t * +sp_gradient_create_preview_pattern(SPGradient *gr, double width) +{ + sp_gradient_ensure_vector(gr); + + cairo_pattern_t *pat = cairo_pattern_create_linear(0, 0, width, 0); + + for (std::vector<SPGradientStop>::iterator i = gr->vector.stops.begin(); + i != gr->vector.stops.end(); ++i) + { + cairo_pattern_add_color_stop_rgba(pat, i->offset, + i->color.v.c[0], i->color.v.c[1], i->color.v.c[2], i->opacity); + } + + return pat; +} + /* Local Variables: mode:c++ diff --git a/src/sp-gradient.h b/src/sp-gradient.h index e7488673d..28099961d 100644 --- a/src/sp-gradient.h +++ b/src/sp-gradient.h @@ -18,7 +18,7 @@ */ #include <gdk/gdktypes.h> -#include "libnr/nr-matrix.h" +#include <2geom/matrix.h> #include "sp-paint-server.h" #include "sp-gradient-spread.h" #include "sp-gradient-units.h" @@ -96,12 +96,8 @@ struct SPGradient : public SPPaintServer { /** Composed vector */ SPGradientVector vector; - /** Rendered color array (4 * 1024 bytes) */ - guchar *color; - sigc::connection modified_connection; - SPStop* getFirstStop(); int getStopCount() const; diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 5a2dfb2f0..10a5fbc59 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -58,11 +58,6 @@ #include "sp-title.h" #include "sp-desc.h" -#include "libnr/nr-matrix-fns.h" -#include "libnr/nr-matrix-scale-ops.h" -#include "libnr/nr-matrix-translate-ops.h" -#include "libnr/nr-scale-translate-ops.h" -#include "libnr/nr-translate-scale-ops.h" #include "libnr/nr-convert2geom.h" #include "util/find-last-if.h" #include "util/reverse-list.h" diff --git a/src/sp-paint-server.cpp b/src/sp-paint-server.cpp index e49e6a378..35a5ff1f1 100644 --- a/src/sp-paint-server.cpp +++ b/src/sp-paint-server.cpp @@ -14,7 +14,6 @@ */ #include <string.h> -#include "libnr/nr-pixblock-pattern.h" #include "sp-paint-server.h" #include "sp-gradient.h" @@ -25,11 +24,9 @@ static void sp_paint_server_init(SPPaintServer *ps); static void sp_paint_server_release(SPObject *object); -static void sp_painter_stale_fill(SPPainter *painter, NRPixBlock *pb); static cairo_pattern_t *sp_paint_server_create_dummy_pattern(SPPaintServer *ps, cairo_t *ct, NRRect const *bbox, double opacity); static SPObjectClass *parent_class; -static GSList *stale_painters = NULL; GType sp_paint_server_get_type (void) { @@ -62,52 +59,15 @@ static void sp_paint_server_class_init(SPPaintServerClass *psc) static void sp_paint_server_init(SPPaintServer *ps) { - ps->painters = NULL; } static void sp_paint_server_release(SPObject *object) { - SPPaintServer *ps = SP_PAINT_SERVER(object); - - while (ps->painters) { - SPPainter *painter = ps->painters; - ps->painters = painter->next; - stale_painters = g_slist_prepend(stale_painters, painter); - painter->next = NULL; - painter->server = NULL; - painter->fill = sp_painter_stale_fill; - } - if (((SPObjectClass *) parent_class)->release) { ((SPObjectClass *) parent_class)->release(object); } } -SPPainter *sp_paint_server_painter_new(SPPaintServer *ps, - Geom::Matrix const &full_transform, - Geom::Matrix const &parent_transform, - const NRRect *bbox) -{ - g_return_val_if_fail(ps != NULL, NULL); - g_return_val_if_fail(SP_IS_PAINT_SERVER(ps), NULL); - g_return_val_if_fail(bbox != NULL, NULL); - - SPPainter *painter = NULL; - SPPaintServerClass *psc = (SPPaintServerClass *) G_OBJECT_GET_CLASS(ps); - if ( psc->painter_new ) { - painter = (*psc->painter_new)(ps, full_transform, parent_transform, bbox); - } - - if (painter) { - painter->next = ps->painters; - painter->server = ps; - painter->type = (SPPainterType) G_OBJECT_TYPE(ps); - ps->painters = painter; - } - - return painter; -} - cairo_pattern_t *sp_paint_server_create_pattern(SPPaintServer *ps, cairo_t *ct, NRRect const *bbox, @@ -138,55 +98,6 @@ sp_paint_server_create_dummy_pattern(SPPaintServer */*ps*/, return cp; } -static void sp_paint_server_painter_free(SPPaintServer *ps, SPPainter *painter) -{ - g_return_if_fail(ps != NULL); - g_return_if_fail(SP_IS_PAINT_SERVER(ps)); - g_return_if_fail(painter != NULL); - - SPPaintServerClass *psc = (SPPaintServerClass *) G_OBJECT_GET_CLASS(ps); - - SPPainter *r = NULL; - for (SPPainter *p = ps->painters; p != NULL; p = p->next) { - if (p == painter) { - if (r) { - r->next = p->next; - } else { - ps->painters = p->next; - } - p->next = NULL; - if (psc->painter_free) { - (*psc->painter_free) (ps, painter); - } - return; - } - r = p; - } - - g_assert_not_reached(); -} - -SPPainter *sp_painter_free(SPPainter *painter) -{ - g_return_val_if_fail(painter != NULL, NULL); - - if (painter->server) { - sp_paint_server_painter_free(painter->server, painter); - } else { - SPPaintServerClass *psc = (SPPaintServerClass *) g_type_class_ref(painter->type); - if (psc->painter_free) - (*psc->painter_free)(NULL, painter); - stale_painters = g_slist_remove(stale_painters, painter); - } - - return NULL; -} - -static void sp_painter_stale_fill(SPPainter */*painter*/, NRPixBlock *pb) -{ - nr_pixblock_render_gray_noise(pb, NULL); -} - bool SPPaintServer::isSwatch() const { bool swatch = false; @@ -217,9 +128,6 @@ bool SPPaintServer::isSolid() const return solid; } - - - /* Local Variables: mode:c++ diff --git a/src/sp-paint-server.h b/src/sp-paint-server.h index d1fc9b7ac..8c9af9f55 100644 --- a/src/sp-paint-server.h +++ b/src/sp-paint-server.h @@ -16,11 +16,11 @@ */ #include <cairo.h> -#include <libnr/nr-pixblock.h> #include "sp-object.h" #include "uri-references.h" -class SPPainter; +struct NRPixBlock; +struct NRRect; #define SP_TYPE_PAINT_SERVER (sp_paint_server_get_type ()) #define SP_PAINT_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_PAINT_SERVER, SPPaintServer)) @@ -28,26 +28,7 @@ class SPPainter; #define SP_IS_PAINT_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_PAINT_SERVER)) #define SP_IS_PAINT_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_PAINT_SERVER)) -typedef enum { - SP_PAINTER_IND, - SP_PAINTER_DEP -} SPPainterType; - -typedef void (* SPPainterFillFunc) (SPPainter *painter, NRPixBlock *pb); - -/* fixme: I do not like that class thingie (Lauris) */ -struct SPPainter { - SPPainter *next; - SPPaintServer *server; - GType server_type; - SPPainterType type; - SPPainterFillFunc fill; -}; - struct SPPaintServer : public SPObject { - /** List of paints */ - SPPainter *painters; - bool isSwatch() const; bool isSolid() const; }; @@ -55,20 +36,13 @@ struct SPPaintServer : public SPObject { struct SPPaintServerClass { SPObjectClass sp_object_class; /** Get SPPaint instance. */ - SPPainter * (* painter_new) (SPPaintServer *ps, Geom::Matrix const &full_transform, Geom::Matrix const &parent_transform, const NRRect *bbox); - /** Free SPPaint instance. */ - void (* painter_free) (SPPaintServer *ps, SPPainter *painter); - cairo_pattern_t *(*pattern_new)(SPPaintServer *ps, cairo_t *ct, const NRRect *bbox, double opacity); }; GType sp_paint_server_get_type (void); -SPPainter *sp_paint_server_painter_new (SPPaintServer *ps, Geom::Matrix const &full_transform, Geom::Matrix const &parent_transform, const NRRect *bbox); cairo_pattern_t *sp_paint_server_create_pattern(SPPaintServer *ps, cairo_t *ct, NRRect const *bbox, double opacity); -SPPainter *sp_painter_free (SPPainter *painter); - class SPPaintServerReference : public Inkscape::URIReference { public: SPPaintServerReference (SPObject *obj) : URIReference(obj) {} diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 074873d5b..b2c718e3b 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -39,44 +39,18 @@ * Pattern */ -class SPPatPainter; - -struct SPPatPainter { - SPPainter painter; - SPPattern *pat; - - Geom::Matrix ps2px; - Geom::Matrix px2ps; - Geom::Matrix pcs2px; - - NRArena *arena; - unsigned int dkey; - NRArenaItem *root; - - bool use_cached_tile; - Geom::Matrix ca2pa; - Geom::Matrix pa2ca; - NRRectL cached_bbox; - NRPixBlock cached_tile; - - std::map<SPObject *, sigc::connection> *_release_connections; -}; - static void sp_pattern_class_init (SPPatternClass *klass); static void sp_pattern_init (SPPattern *gr); static void sp_pattern_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); static void sp_pattern_release (SPObject *object); static void sp_pattern_set (SPObject *object, unsigned int key, const gchar *value); -static void sp_pattern_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); static void sp_pattern_update (SPObject *object, SPCtx *ctx, unsigned int flags); static void sp_pattern_modified (SPObject *object, unsigned int flags); static void pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat); static void pattern_ref_modified (SPObject *ref, guint flags, SPPattern *pattern); -static SPPainter *sp_pattern_painter_new (SPPaintServer *ps, Geom::Matrix const &full_transform, Geom::Matrix const &parent_transform, const NRRect *bbox); -static void sp_pattern_painter_free (SPPaintServer *ps, SPPainter *painter); static cairo_pattern_t *sp_pattern_create_pattern(SPPaintServer *ps, cairo_t *ct, NRRect const *bbox, double opacity); static SPPaintServerClass * pattern_parent_class; @@ -117,14 +91,11 @@ sp_pattern_class_init (SPPatternClass *klass) sp_object_class->build = sp_pattern_build; sp_object_class->release = sp_pattern_release; sp_object_class->set = sp_pattern_set; - sp_object_class->child_added = sp_pattern_child_added; sp_object_class->update = sp_pattern_update; sp_object_class->modified = sp_pattern_modified; // do we need _write? seems to work without it - ps_class->painter_new = sp_pattern_painter_new; - ps_class->painter_free = sp_pattern_painter_free; ps_class->pattern_new = sp_pattern_create_pattern; } @@ -318,34 +289,6 @@ sp_pattern_set (SPObject *object, unsigned int key, const gchar *value) } } -static void -sp_pattern_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) -{ - SPPattern *pat = SP_PATTERN (object); - - if (((SPObjectClass *) (pattern_parent_class))->child_added) - (* ((SPObjectClass *) (pattern_parent_class))->child_added) (object, child, ref); - - SPObject *ochild = sp_object_get_child_by_repr(object, child); - if (SP_IS_ITEM (ochild)) { - - SPPaintServer *ps = SP_PAINT_SERVER (pat); - unsigned position = sp_item_pos_in_parent(SP_ITEM(ochild)); - - for (SPPainter *p = ps->painters; p != NULL; p = p->next) { - - SPPatPainter *pp = (SPPatPainter *) p; - NRArenaItem *ai = sp_item_invoke_show (SP_ITEM (ochild), pp->arena, pp->dkey, SP_ITEM_REFERENCE_FLAGS); - - if (ai) { - nr_arena_item_add_child (pp->root, ai, NULL); - nr_arena_item_set_order (ai, position); - nr_arena_item_unref (ai); - } - } - } -} - /* TODO: do we need a ::remove_child handler? */ /* fixme: We need ::order_changed handler too (Lauris) */ @@ -632,394 +575,6 @@ bool pattern_hasItemChildren (SPPattern *pat) return false; } - - -/* Painter */ - -static void sp_pat_fill (SPPainter *painter, NRPixBlock *pb); - -// item in this pattern is about to be deleted, hide it on our arena and disconnect -void -sp_pattern_painter_release (SPObject *obj, SPPatPainter *painter) -{ - std::map<SPObject *, sigc::connection>::iterator iter = painter->_release_connections->find(obj); - if (iter != painter->_release_connections->end()) { - iter->second.disconnect(); - painter->_release_connections->erase(obj); - } - - sp_item_invoke_hide(SP_ITEM(obj), painter->dkey); -} - -/** -Creates a painter (i.e. the thing that does actual filling at the given zoom). -See (*) below for why the parent_transform may be necessary. -*/ -static SPPainter * -sp_pattern_painter_new (SPPaintServer *ps, Geom::Matrix const &full_transform, Geom::Matrix const &/*parent_transform*/, const NRRect *bbox) -{ - SPPattern *pat = SP_PATTERN (ps); - SPPatPainter *pp = g_new (SPPatPainter, 1); - - pp->painter.type = SP_PAINTER_IND; - pp->painter.fill = sp_pat_fill; - - pp->pat = pat; - - if (pattern_patternUnits (pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { - /* BBox to user coordinate system */ - Geom::Matrix bbox2user (bbox->x1 - bbox->x0, 0.0, 0.0, bbox->y1 - bbox->y0, bbox->x0, bbox->y0); - - // the final patternTransform, taking into account bbox - Geom::Matrix const ps2user(pattern_patternTransform(pat) * bbox2user); - - // see (*) comment below - pp->ps2px = ps2user * full_transform; - } else { - /* Problem: What to do, if we have mixed lengths and percentages? */ - /* Currently we do ignore percentages at all, but that is not good (lauris) */ - - /* fixme: We may try to normalize here too, look at linearGradient (Lauris) */ - - // (*) The spec says, "This additional transformation matrix [patternTransform] is - // post-multiplied to (i.e., inserted to the right of) any previously defined - // transformations, including the implicit transformation necessary to convert from - // object bounding box units to user space." To me, this means that the order should be: - // item_transform * patternTransform * parent_transform - // However both Batik and Adobe plugin use: - // patternTransform * item_transform * parent_transform - // So here I comply with the majority opinion, but leave my interpretation commented out below. - // (To get item_transform, I subtract parent from full.) - - //pp->ps2px = (full_transform / parent_transform) * pattern_patternTransform(pat) * parent_transform; - pp->ps2px = pattern_patternTransform(pat) * full_transform; - } - - pp->px2ps = pp->ps2px.inverse(); - - if (pat->viewBox_set) { - gdouble tmp_x = pattern_width (pat) / (pattern_viewBox(pat)->x1 - pattern_viewBox(pat)->x0); - gdouble tmp_y = pattern_height (pat) / (pattern_viewBox(pat)->y1 - pattern_viewBox(pat)->y0); - - // FIXME: preserveAspectRatio must be taken into account here too! - Geom::Matrix vb2ps (tmp_x, 0.0, 0.0, tmp_y, pattern_x(pat) - pattern_viewBox(pat)->x0 * tmp_x, pattern_y(pat) - pattern_viewBox(pat)->y0 * tmp_y); - - Geom::Matrix vb2us = vb2ps * pattern_patternTransform(pat); - - // see (*) - pp->pcs2px = vb2us * full_transform; - } else { - /* No viewbox, have to parse units */ - if (pattern_patternContentUnits (pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { - /* BBox to user coordinate system */ - Geom::Matrix bbox2user (bbox->x1 - bbox->x0, 0.0, 0.0, bbox->y1 - bbox->y0, bbox->x0, bbox->y0); - - Geom::Matrix pcs2user = pattern_patternTransform(pat) * bbox2user; - - // see (*) - pp->pcs2px = pcs2user * full_transform; - } else { - // see (*) - //pcs2px = (full_transform / parent_transform) * pattern_patternTransform(pat) * parent_transform; - pp->pcs2px = pattern_patternTransform(pat) * full_transform; - } - - pp->pcs2px = Geom::Translate (pattern_x (pat), pattern_y (pat)) * pp->pcs2px; - } - - /* Create arena */ - pp->arena = NRArena::create(); - - pp->dkey = sp_item_display_key_new (1); - - /* Create group */ - pp->root = NRArenaGroup::create(pp->arena); - - /* Show items */ - pp->_release_connections = new std::map<SPObject *, sigc::connection>; - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) { // find the first one with item children - for (SPObject *child = sp_object_first_child(SP_OBJECT(pat_i)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { - if (SP_IS_ITEM (child)) { - // for each item in pattern, - NRArenaItem *cai; - // show it on our arena, - cai = sp_item_invoke_show (SP_ITEM (child), pp->arena, pp->dkey, SP_ITEM_REFERENCE_FLAGS); - // add to the group, - nr_arena_item_append_child (pp->root, cai); - // and connect to the release signal in case the item gets deleted - pp->_release_connections->insert(std::make_pair(child, child->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_pattern_painter_release), pp)))); - } - } - break; // do not go further up the chain if children are found - } - } - - { - NRRect one_tile,tr_tile; - one_tile.x0=pattern_x(pp->pat); - one_tile.y0=pattern_y(pp->pat); - one_tile.x1=one_tile.x0+pattern_width (pp->pat); - one_tile.y1=one_tile.y0+pattern_height (pp->pat); - // TODO: remove ps2px_nr after converting to 2geom - NR::Matrix ps2px_nr = from_2geom(pp->ps2px); - nr_rect_d_matrix_transform (&tr_tile, &one_tile, &ps2px_nr); - int tr_width=(int)ceil(1.3*(tr_tile.x1-tr_tile.x0)); - int tr_height=(int)ceil(1.3*(tr_tile.y1-tr_tile.y0)); -// if ( tr_width < 10000 && tr_height < 10000 && tr_width*tr_height < 1000000 ) { - pp->use_cached_tile=false;//true; - if ( tr_width > 1000 ) tr_width=1000; - if ( tr_height > 1000 ) tr_height=1000; - pp->cached_bbox.x0=0; - pp->cached_bbox.y0=0; - pp->cached_bbox.x1=tr_width; - pp->cached_bbox.y1=tr_height; - - if (pp->use_cached_tile) { - nr_pixblock_setup (&pp->cached_tile,NR_PIXBLOCK_MODE_R8G8B8A8N, pp->cached_bbox.x0, pp->cached_bbox.y0, pp->cached_bbox.x1, pp->cached_bbox.y1,TRUE); - } - - pp->pa2ca[0]=((double)tr_width)/(one_tile.x1-one_tile.x0); - pp->pa2ca[1]=0; - pp->pa2ca[2]=0; - pp->pa2ca[3]=((double)tr_height)/(one_tile.y1-one_tile.y0); - pp->pa2ca[4]=-one_tile.x0*pp->pa2ca[0]; - pp->pa2ca[5]=-one_tile.y0*pp->pa2ca[1]; - pp->ca2pa[0]=(one_tile.x1-one_tile.x0)/((double)tr_width); - pp->ca2pa[1]=0; - pp->ca2pa[2]=0; - pp->ca2pa[3]=(one_tile.y1-one_tile.y0)/((double)tr_height); - pp->ca2pa[4]=one_tile.x0; - pp->ca2pa[5]=one_tile.y0; -// } else { -// pp->use_cached_tile=false; -// } - } - - NRGC gc(NULL); - if ( pp->use_cached_tile ) { - gc.transform=pp->pa2ca; - } else { - gc.transform = pp->pcs2px; - } - nr_arena_item_invoke_update (pp->root, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_ALL); - if ( pp->use_cached_tile ) { - nr_arena_item_invoke_render (NULL, pp->root, &pp->cached_bbox, &pp->cached_tile, 0); - } else { - // nothing to do now - } - - return (SPPainter *) pp; -} - - -static void -sp_pattern_painter_free (SPPaintServer */*ps*/, SPPainter *painter) -{ - SPPatPainter *pp = (SPPatPainter *) painter; - // free our arena - if (pp->arena) { - ((NRObject *) pp->arena)->unreference(); - pp->arena = NULL; - } - - // disconnect all connections - std::map<SPObject *, sigc::connection>::iterator iter; - for (iter = pp->_release_connections->begin() ; iter!=pp->_release_connections->end() ; iter++) { - iter->second.disconnect(); - } - pp->_release_connections->clear(); - delete pp->_release_connections; - - if ( pp->use_cached_tile ) nr_pixblock_release(&pp->cached_tile); - g_free (pp); -} - -void -get_cached_tile_pixel(SPPatPainter* pp,double x,double y,unsigned char &r,unsigned char &g,unsigned char &b,unsigned char &a) -{ - int ca_h=(int)floor(x); - int ca_v=(int)floor(y); - int r_x=(int)floor(16*(x-floor(x))); - int r_y=(int)floor(16*(y-floor(y))); - unsigned int tl_m=(16-r_x)*(16-r_y); - unsigned int bl_m=(16-r_x)*r_y; - unsigned int tr_m=r_x*(16-r_y); - unsigned int br_m=r_x*r_y; - int cb_h=ca_h+1; - int cb_v=ca_v+1; - if ( cb_h >= pp->cached_bbox.x1 ) cb_h=0; - if ( cb_v >= pp->cached_bbox.y1 ) cb_v=0; - - unsigned char* tlx=NR_PIXBLOCK_PX(&pp->cached_tile)+(ca_v*pp->cached_tile.rs)+4*ca_h; - unsigned char* trx=NR_PIXBLOCK_PX(&pp->cached_tile)+(ca_v*pp->cached_tile.rs)+4*cb_h; - unsigned char* blx=NR_PIXBLOCK_PX(&pp->cached_tile)+(cb_v*pp->cached_tile.rs)+4*ca_h; - unsigned char* brx=NR_PIXBLOCK_PX(&pp->cached_tile)+(cb_v*pp->cached_tile.rs)+4*cb_h; - - unsigned int tl_c=tlx[0]; - unsigned int tr_c=trx[0]; - unsigned int bl_c=blx[0]; - unsigned int br_c=brx[0]; - unsigned int f_c=(tl_m*tl_c+tr_m*tr_c+bl_m*bl_c+br_m*br_c)>>8; - r=f_c; - tl_c=tlx[1]; - tr_c=trx[1]; - bl_c=blx[1]; - br_c=brx[1]; - f_c=(tl_m*tl_c+tr_m*tr_c+bl_m*bl_c+br_m*br_c)>>8; - g=f_c; - tl_c=tlx[2]; - tr_c=trx[2]; - bl_c=blx[2]; - br_c=brx[2]; - f_c=(tl_m*tl_c+tr_m*tr_c+bl_m*bl_c+br_m*br_c)>>8; - b=f_c; - tl_c=tlx[3]; - tr_c=trx[3]; - bl_c=blx[3]; - br_c=brx[3]; - f_c=(tl_m*tl_c+tr_m*tr_c+bl_m*bl_c+br_m*br_c)>>8; - a=f_c; -} - -static void -sp_pat_fill (SPPainter *painter, NRPixBlock *pb) -{ - SPPatPainter *pp; - NRRect ba, psa; - NRRectL area; - double x, y; - - pp = (SPPatPainter *) painter; - - if (pattern_width (pp->pat) < NR_EPSILON) return; - if (pattern_height (pp->pat) < NR_EPSILON) return; - - /* Find buffer area in gradient space */ - /* fixme: This is suboptimal (Lauris) */ - - if ( pp->use_cached_tile ) { - double pat_w=pattern_width (pp->pat); - double pat_h=pattern_height (pp->pat); - if ( pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8N || pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8P ) { // same thing because it's filling an empty pixblock - unsigned char* lpx=NR_PIXBLOCK_PX(pb); - double px_y=pb->area.y0; - for (int j=pb->area.y0;j<pb->area.y1;j++) { - unsigned char* cpx=lpx; - double px_x = pb->area.x0; - - double ps_x=pp->px2ps[0]*px_x+pp->px2ps[2]*px_y+pp->px2ps[4]; - double ps_y=pp->px2ps[1]*px_x+pp->px2ps[3]*px_y+pp->px2ps[5]; - for (int i=pb->area.x0;i<pb->area.x1;i++) { - while ( ps_x > pat_w ) ps_x-=pat_w; - while ( ps_x < 0 ) ps_x+=pat_w; - while ( ps_y > pat_h ) ps_y-=pat_h; - while ( ps_y < 0 ) ps_y+=pat_h; - double ca_x=pp->pa2ca[0]*ps_x+pp->pa2ca[2]*ps_y+pp->pa2ca[4]; - double ca_y=pp->pa2ca[1]*ps_x+pp->pa2ca[3]*ps_y+pp->pa2ca[5]; - unsigned char n_a,n_r,n_g,n_b; - get_cached_tile_pixel(pp,ca_x,ca_y,n_r,n_g,n_b,n_a); - cpx[0]=n_r; - cpx[1]=n_g; - cpx[2]=n_b; - cpx[3]=n_a; - - px_x+=1.0; - ps_x+=pp->px2ps[0]; - ps_y+=pp->px2ps[1]; - cpx+=4; - } - px_y+=1.0; - lpx+=pb->rs; - } - } else if ( pb->mode == NR_PIXBLOCK_MODE_R8G8B8 ) { - unsigned char* lpx=NR_PIXBLOCK_PX(pb); - double px_y=pb->area.y0; - for (int j=pb->area.y0;j<pb->area.y1;j++) { - unsigned char* cpx=lpx; - double px_x = pb->area.x0; - - double ps_x=pp->px2ps[0]*px_x+pp->px2ps[2]*px_y+pp->px2ps[4]; - double ps_y=pp->px2ps[1]*px_x+pp->px2ps[3]*px_y+pp->px2ps[5]; - for (int i=pb->area.x0;i<pb->area.x1;i++) { - while ( ps_x > pat_w ) ps_x-=pat_w; - while ( ps_x < 0 ) ps_x+=pat_w; - while ( ps_y > pat_h ) ps_y-=pat_h; - while ( ps_y < 0 ) ps_y+=pat_h; - double ca_x=pp->pa2ca[0]*ps_x+pp->pa2ca[2]*ps_y+pp->pa2ca[4]; - double ca_y=pp->pa2ca[1]*ps_x+pp->pa2ca[3]*ps_y+pp->pa2ca[5]; - unsigned char n_a,n_r,n_g,n_b; - get_cached_tile_pixel(pp,ca_x,ca_y,n_r,n_g,n_b,n_a); - cpx[0]=n_r; - cpx[1]=n_g; - cpx[2]=n_b; - - px_x+=1.0; - ps_x+=pp->px2ps[0]; - ps_y+=pp->px2ps[1]; - cpx+=4; - } - px_y+=1.0; - lpx+=pb->rs; - } - } - } else { - ba.x0 = pb->area.x0; - ba.y0 = pb->area.y0; - ba.x1 = pb->area.x1; - ba.y1 = pb->area.y1; - - // Trying to solve this bug: https://bugs.launchpad.net/inkscape/+bug/167416 - // Bail out if the transformation matrix has extreme values. If we bail out - // however, then something (which was meaningless anyway) won't be rendered, - // which is better than getting stuck in a virtually infinite loop - if (fabs(pp->px2ps[0]) < 1e6 && - fabs(pp->px2ps[3]) < 1e6 && - fabs(pp->px2ps[4]) < 1e6 && - fabs(pp->px2ps[5]) < 1e6) - { - // TODO: remove px2ps_nr after converting to 2geom - NR::Matrix px2ps_nr = from_2geom(pp->px2ps); - nr_rect_d_matrix_transform (&psa, &ba, &px2ps_nr); - - psa.x0 = floor ((psa.x0 - pattern_x (pp->pat)) / pattern_width (pp->pat)) -1; - psa.y0 = floor ((psa.y0 - pattern_y (pp->pat)) / pattern_height (pp->pat)) -1; - psa.x1 = ceil ((psa.x1 - pattern_x (pp->pat)) / pattern_width (pp->pat)) +1; - psa.y1 = ceil ((psa.y1 - pattern_y (pp->pat)) / pattern_height (pp->pat)) +1; - - // If psa is too wide or tall, then something must be wrong! This is due to - // nr_rect_d_matrix_transform (&psa, &ba, &pp->px2ps) using a weird transformation matrix pp->px2ps. - g_assert(std::abs(psa.x1 - psa.x0) < 1e6); - g_assert(std::abs(psa.y1 - psa.y0) < 1e6); - - for (y = psa.y0; y < psa.y1; y++) { - for (x = psa.x0; x < psa.x1; x++) { - NRPixBlock ppb; - double psx, psy; - - psx = x * pattern_width (pp->pat); - psy = y * pattern_height (pp->pat); - - area.x0 = (gint32)(pb->area.x0 - (pp->ps2px[0] * psx + pp->ps2px[2] * psy)); - area.y0 = (gint32)(pb->area.y0 - (pp->ps2px[1] * psx + pp->ps2px[3] * psy)); - area.x1 = area.x0 + pb->area.x1 - pb->area.x0; - area.y1 = area.y0 + pb->area.y1 - pb->area.y0; - - // We do not update here anymore - - // Set up buffer - // fixme: (Lauris) - nr_pixblock_setup_extern (&ppb, pb->mode, area.x0, area.y0, area.x1, area.y1, NR_PIXBLOCK_PX (pb), pb->rs, FALSE, FALSE); - - nr_arena_item_invoke_render (NULL, pp->root, &area, &ppb, 0); - - nr_pixblock_release (&ppb); - } - } - } - } -} - static cairo_pattern_t * sp_pattern_create_pattern(SPPaintServer *ps, cairo_t *base_ct, @@ -1108,7 +663,7 @@ sp_pattern_create_pattern(SPPaintServer *ps, // TODO: make sure there are no leaks. NRGC gc(NULL); - gc.transform = vb2ps;//Geom::identity(); + gc.transform = vb2ps; nr_arena_item_invoke_update (root, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_ALL); nr_arena_item_invoke_render (ct, root, &one_tile, NULL, 0); nr_object_unref(arena); diff --git a/src/sp-pattern.h b/src/sp-pattern.h index f15285e27..8ca97e0a7 100644 --- a/src/sp-pattern.h +++ b/src/sp-pattern.h @@ -27,7 +27,6 @@ GType sp_pattern_get_type (void); class SPPatternClass; #include <libnr/nr-rect.h> -#include <libnr/nr-matrix.h> #include "svg/svg-length.h" #include "sp-paint-server.h" #include "uri-references.h" diff --git a/src/sp-root.cpp b/src/sp-root.cpp index bd935074d..adcad5ebb 100644 --- a/src/sp-root.cpp +++ b/src/sp-root.cpp @@ -27,11 +27,6 @@ #include "document.h" #include "sp-defs.h" #include "sp-root.h" -#include <libnr/nr-matrix-fns.h> -#include <libnr/nr-matrix-ops.h> -#include <libnr/nr-matrix-translate-ops.h> -#include <libnr/nr-scale-ops.h> -#include <libnr/nr-translate-scale-ops.h> #include <xml/repr.h> #include "svg/stringstream.h" #include "inkscape-version.h" diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 3064341b6..30a94302e 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -16,10 +16,6 @@ # include "config.h" #endif -#include <libnr/nr-matrix-fns.h> -#include <libnr/nr-matrix-ops.h> -#include <libnr/nr-matrix-translate-ops.h> -#include <libnr/nr-scale-matrix-ops.h> #include <2geom/rect.h> #include <2geom/transforms.h> #include <2geom/pathvector.h> @@ -270,7 +266,7 @@ sp_shape_update (SPObject *object, SPCtx *ctx, unsigned int flags) style = SP_OBJECT_STYLE (object); if (style->stroke_width.unit == SP_CSS_UNIT_PERCENT) { SPItemCtx *ictx = (SPItemCtx *) ctx; - double const aw = 1.0 / NR::expansion(ictx->i2vp); + double const aw = 1.0 / ictx->i2vp.descrim(); style->stroke_width.computed = style->stroke_width.value * aw; for (SPItemView *v = ((SPItem *) (shape))->display; v != NULL; v = v->next) { nr_arena_shape_set_style ((NRArenaShape *) v->arenaitem, style); diff --git a/src/sp-symbol.h b/src/sp-symbol.h index 61951cf64..eb0b144c6 100644 --- a/src/sp-symbol.h +++ b/src/sp-symbol.h @@ -24,7 +24,6 @@ class SPSymbol; class SPSymbolClass; -#include <libnr/nr-matrix.h> #include <2geom/matrix.h> #include <libnr/nr-rect.h> #include "svg/svg-length.h" diff --git a/src/ui/cache/svg_preview_cache.cpp b/src/ui/cache/svg_preview_cache.cpp index 6e05f6c03..d4c8d0d0c 100644 --- a/src/ui/cache/svg_preview_cache.cpp +++ b/src/ui/cache/svg_preview_cache.cpp @@ -28,6 +28,7 @@ #include "document-private.h" #include "display/nr-arena.h" #include "display/nr-arena-item.h" +#include "libnr/nr-pixblock.h" #include "ui/cache/svg_preview_cache.h" diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index cb6cfbbbe..a71f0789f 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -13,13 +13,14 @@ #include <glibmm/i18n.h> #include <gtkmm/label.h> #include <gtk/gtkdnd.h> +#include <cairo.h> #include "color-item.h" #include "desktop.h" #include "desktop-handles.h" #include "desktop-style.h" -#include "display/nr-plain-stuff.h" +#include "display/cairo-utils.h" #include "document.h" #include "inkscape.h" // for SP_ACTIVE_DESKTOP #include "io/resource.h" @@ -211,17 +212,20 @@ static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpoin } else { GdkPixbuf* pixbuf = 0; if ( item->getGradient() ){ - guchar* px = g_new( guchar, 3 * height * width ); - nr_render_checkerboard_rgb( px, width, height, 3 * width, 0, 0 ); - - sp_gradient_render_vector_block_rgb( item->getGradient(), - px, width, height, 3 * width, - 0, width, TRUE ); - - pixbuf = gdk_pixbuf_new_from_data( px, GDK_COLORSPACE_RGB, FALSE, 8, - width, height, width * 3, - 0, // add delete function - 0 ); + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(item->getGradient(), width); + cairo_t *ct = cairo_create(s); + cairo_set_source(ct, gradient); + cairo_paint(ct); + cairo_destroy(ct); + cairo_pattern_destroy(gradient); + cairo_surface_flush(s); + + pixbuf = gdk_pixbuf_new_from_data(cairo_image_surface_get_data(s), + GDK_COLORSPACE_RGB, TRUE, 8, + width, height, cairo_image_surface_get_stride(s), + (GdkPixbufDestroyNotify) cairo_surface_destroy, NULL); + convert_pixbuf_argb32_to_normal(pixbuf); } else { Glib::RefPtr<Gdk::Pixbuf> thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, width, height ); guint32 fillWith = (0xff000000 & (item->def.getR() << 24)) @@ -251,10 +255,8 @@ static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpoin // } -SwatchPage::SwatchPage() : - _name(), - _prefWidth(0), - _colors() +SwatchPage::SwatchPage() + : _prefWidth(0) { } @@ -264,10 +266,7 @@ SwatchPage::~SwatchPage() ColorItem::ColorItem(ege::PaintDef::ColorType type) : - Previewable(), def(type), - tips(), - _previews(), _isFill(false), _isStroke(false), _isLive(false), @@ -276,18 +275,12 @@ ColorItem::ColorItem(ege::PaintDef::ColorType type) : _linkGray(0), _linkSrc(0), _grad(0), - _pixData(0), - _pixWidth(0), - _pixHeight(0), - _listeners() + _pattern(0) { } ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) : - Previewable(), def( r, g, b, name ), - tips(), - _previews(), _isFill(false), _isStroke(false), _isLive(false), @@ -296,15 +289,15 @@ ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustr _linkGray(0), _linkSrc(0), _grad(0), - _pixData(0), - _pixWidth(0), - _pixHeight(0), - _listeners() + _pattern(0) { } ColorItem::~ColorItem() { + if (_pattern != NULL) { + cairo_pattern_destroy(_pattern); + } } ColorItem::ColorItem(ColorItem const &other) : @@ -360,18 +353,16 @@ void ColorItem::setGradient(SPGradient *grad) } } -void ColorItem::setPixData(guchar* px, int width, int height) +void ColorItem::setPattern(cairo_pattern_t *pattern) { - if (px != _pixData) { - if (_pixData) { - g_free(_pixData); - } - _pixData = px; - _pixWidth = width; - _pixHeight = height; - - _updatePreviews(); + if (pattern) { + cairo_pattern_reference(pattern); + } + if (_pattern) { + cairo_pattern_destroy(_pattern); } + _pattern = pattern; + _updatePreviews(); } void ColorItem::_dragGetColorData( GtkWidget */*widget*/, @@ -519,16 +510,28 @@ void ColorItem::_regenPreview(EekPreview * preview) eek_preview_set_pixbuf( preview, pixbuf ); } - else if ( !_pixData ){ + else if ( !_pattern ){ eek_preview_set_color( preview, (def.getR() << 8) | def.getR(), (def.getG() << 8) | def.getG(), (def.getB() << 8) | def.getB() ); } else { - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( _pixData, GDK_COLORSPACE_RGB, FALSE, 8, - _pixWidth, _pixHeight, _pixWidth * 3, - 0, // add delete function - 0 ); + double w; + cairo_pattern_get_linear_points(_pattern, NULL, NULL, &w, NULL); + int width = ceil(w); + + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, 1); + cairo_t *ct = cairo_create(s); + cairo_set_source(ct, _pattern); + cairo_paint(ct); + cairo_destroy(ct); + cairo_surface_flush(s); + + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( cairo_image_surface_get_data(s), + GDK_COLORSPACE_RGB, TRUE, 8, + width, 1, cairo_image_surface_get_stride(s), + (GdkPixbufDestroyNotify) cairo_surface_destroy, NULL); + convert_pixbuf_argb32_to_normal(pixbuf); eek_preview_set_pixbuf( preview, pixbuf ); } diff --git a/src/ui/dialog/color-item.h b/src/ui/dialog/color-item.h index 4aac86a30..de4618bc0 100644 --- a/src/ui/dialog/color-item.h +++ b/src/ui/dialog/color-item.h @@ -58,8 +58,7 @@ public: void setGradient(SPGradient *grad); SPGradient * getGradient() const { return _grad; } - - void setPixData(guchar* px, int width, int height); + void setPattern(cairo_pattern_t *pattern); void setState( bool fill, bool stroke ); bool isFill() { return _isFill; } @@ -104,9 +103,7 @@ private: int _linkGray; ColorItem* _linkSrc; SPGradient* _grad; - guchar *_pixData; - int _pixWidth; - int _pixHeight; + cairo_pattern_t *_pattern; std::vector<ColorItem*> _listeners; }; diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 6f013f4f3..163b49867 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -46,7 +46,7 @@ #include "ui/previewholder.h" #include "widgets/gradient-vector.h" #include "widgets/eek-preview.h" -#include "display/nr-plain-stuff.h" +#include "display/cairo-utils.h" #include "sp-gradient-reference.h" @@ -714,7 +714,7 @@ void SwatchesPanel::_setDocument( SPDocument *document ) static void recalcSwatchContents(SPDocument* doc, std::vector<ColorItem*> &tmpColors, - std::map<ColorItem*, guchar*> &previewMappings, + std::map<ColorItem*, cairo_pattern_t*> &previewMappings, std::map<ColorItem*, SPGradient*> &gradMappings) { std::vector<SPGradient*> newList; @@ -731,30 +731,28 @@ static void recalcSwatchContents(SPDocument* doc, for ( std::vector<SPGradient*>::iterator it = newList.begin(); it != newList.end(); ++it ) { SPGradient* grad = *it; - sp_gradient_ensure_vector( grad ); - SPGradientStop first = grad->vector.stops[0]; - SPColor color = first.color; - guint32 together = color.toRGBA32(first.opacity); - - SPGradientStop second = (*it)->vector.stops[1]; - SPColor color2 = second.color; + cairo_surface_t *preview = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + PREVIEW_PIXBUF_WIDTH, VBLOCK); + cairo_t *ct = cairo_create(preview); Glib::ustring name( grad->getId() ); - unsigned int r = SP_RGBA32_R_U(together); - unsigned int g = SP_RGBA32_G_U(together); - unsigned int b = SP_RGBA32_B_U(together); - ColorItem* item = new ColorItem( r, g, b, name ); + ColorItem* item = new ColorItem( 0, 0, 0, name ); + + cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); + cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(grad, PREVIEW_PIXBUF_WIDTH); + cairo_set_source(ct, check); + cairo_paint(ct); + cairo_set_source(ct, gradient); + cairo_paint(ct); - gint width = PREVIEW_PIXBUF_WIDTH; - gint height = VBLOCK; - guchar* px = g_new( guchar, 3 * height * width ); - nr_render_checkerboard_rgb( px, width, height, 3 * width, 0, 0 ); + cairo_destroy(ct); + cairo_pattern_destroy(gradient); + cairo_pattern_destroy(check); - sp_gradient_render_vector_block_rgb( grad, - px, width, height, 3 * width, - 0, width, TRUE ); + cairo_pattern_t *prevpat = cairo_pattern_create_for_surface(preview); + cairo_surface_destroy(preview); - previewMappings[item] = px; + previewMappings[item] = prevpat; tmpColors.push_back(item); gradMappings[item] = grad; @@ -767,12 +765,13 @@ void SwatchesPanel::handleGradientsChange(SPDocument *document) SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; if (docPalette) { std::vector<ColorItem*> tmpColors; - std::map<ColorItem*, guchar*> tmpPrevs; + std::map<ColorItem*, cairo_pattern_t*> tmpPrevs; std::map<ColorItem*, SPGradient*> tmpGrads; recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); - for (std::map<ColorItem*, guchar*>::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { - it->first->setPixData(it->second, PREVIEW_PIXBUF_WIDTH, VBLOCK); + for (std::map<ColorItem*, cairo_pattern_t*>::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { + it->first->setPattern(it->second); + cairo_pattern_destroy(it->second); } for (std::map<ColorItem*, SPGradient*>::iterator it = tmpGrads.begin(); it != tmpGrads.end(); ++it) { @@ -784,7 +783,6 @@ void SwatchesPanel::handleGradientsChange(SPDocument *document) delete *it; } - // Figure out which SwatchesPanel instances are affected and update them. for (std::map<SwatchesPanel*, SPDocument*>::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { @@ -805,7 +803,7 @@ void SwatchesPanel::handleDefsModified(SPDocument *document) SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; if (docPalette) { std::vector<ColorItem*> tmpColors; - std::map<ColorItem*, guchar*> tmpPrevs; + std::map<ColorItem*, cairo_pattern_t*> tmpPrevs; std::map<ColorItem*, SPGradient*> tmpGrads; recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); @@ -823,9 +821,16 @@ void SwatchesPanel::handleDefsModified(SPDocument *document) oldColor->setGradient(tmpGrads[newColor]); } if ( tmpPrevs.find(newColor) != tmpPrevs.end() ) { - oldColor->setPixData(tmpPrevs[newColor], PREVIEW_PIXBUF_WIDTH, VBLOCK); + oldColor->setPattern(tmpPrevs[newColor]); } } + + for (std::map<ColorItem*, cairo_pattern_t*>::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { + cairo_pattern_destroy(it->second); + } + for (std::vector<ColorItem*>::iterator it = tmpColors.begin(); it != tmpColors.end(); ++it) { + delete *it; + } } } diff --git a/src/widgets/gradient-image.cpp b/src/widgets/gradient-image.cpp index 11d2d528a..c4b7216c6 100644 --- a/src/widgets/gradient-image.cpp +++ b/src/widgets/gradient-image.cpp @@ -14,8 +14,7 @@ #include <libnr/nr-pixblock-pattern.h> #include "macros.h" -#include "../display/nr-plain-stuff.h" -#include "../display/nr-plain-stuff-gdk.h" +#include "display/cairo-utils.h" #include "gradient-image.h" #include "sp-gradient.h" #include "sp-gradient-fns.h" @@ -29,10 +28,7 @@ static void sp_gradient_image_class_init (SPGradientImageClass *klass); static void sp_gradient_image_init (SPGradientImage *image); static void sp_gradient_image_destroy (GtkObject *object); -static void sp_gradient_image_realize (GtkWidget *widget); -static void sp_gradient_image_unrealize (GtkWidget *widget); static void sp_gradient_image_size_request (GtkWidget *widget, GtkRequisition *requisition); -static void sp_gradient_image_size_allocate (GtkWidget *widget, GtkAllocation *allocation); static gint sp_gradient_image_expose (GtkWidget *widget, GdkEventExpose *event); static void sp_gradient_image_gradient_release (SPObject *, SPGradientImage *im); @@ -76,10 +72,7 @@ sp_gradient_image_class_init (SPGradientImageClass *klass) object_class->destroy = sp_gradient_image_destroy; - widget_class->realize = sp_gradient_image_realize; - widget_class->unrealize = sp_gradient_image_unrealize; widget_class->size_request = sp_gradient_image_size_request; - widget_class->size_allocate = sp_gradient_image_size_allocate; widget_class->expose_event = sp_gradient_image_expose; } @@ -89,7 +82,6 @@ sp_gradient_image_init (SPGradientImage *image) GTK_WIDGET_SET_FLAGS (image, GTK_NO_WINDOW); image->gradient = NULL; - image->px = NULL; new (&image->release_connection) sigc::connection(); new (&image->modified_connection) sigc::connection(); @@ -116,104 +108,39 @@ sp_gradient_image_destroy (GtkObject *object) } static void -sp_gradient_image_realize (GtkWidget *widget) -{ - SPGradientImage *image; - - image = SP_GRADIENT_IMAGE (widget); - - if (((GtkWidgetClass *) parent_class)->realize) - (* ((GtkWidgetClass *) parent_class)->realize) (widget); - - g_assert (!image->px); - image->px = g_new (guchar, 3 * VBLOCK * widget->allocation.width); - sp_gradient_image_update (image); -} - -static void -sp_gradient_image_unrealize (GtkWidget *widget) -{ - SPGradientImage *image; - - image = SP_GRADIENT_IMAGE (widget); - - if (((GtkWidgetClass *) parent_class)->unrealize) - (* ((GtkWidgetClass *) parent_class)->unrealize) (widget); - - g_assert (image->px); - g_free (image->px); - image->px = NULL; -} - -static void sp_gradient_image_size_request (GtkWidget *widget, GtkRequisition *requisition) { - SPGradientImage *slider; - - slider = SP_GRADIENT_IMAGE (widget); - requisition->width = 64; requisition->height = 12; } -static void -sp_gradient_image_size_allocate (GtkWidget *widget, GtkAllocation *allocation) -{ - SPGradientImage *image; - - image = SP_GRADIENT_IMAGE (widget); - - widget->allocation = *allocation; - - if (GTK_WIDGET_REALIZED (widget)) { - g_free (image->px); - image->px = g_new (guchar, 3 * VBLOCK * allocation->width); - } - - sp_gradient_image_update (image); -} - static gint sp_gradient_image_expose (GtkWidget *widget, GdkEventExpose *event) { - SPGradientImage *image; - - image = SP_GRADIENT_IMAGE (widget); - - if (GTK_WIDGET_DRAWABLE (widget)) { - gint x0, y0, x1, y1; - x0 = MAX (event->area.x, widget->allocation.x); - y0 = MAX (event->area.y, widget->allocation.y); - x1 = MIN (event->area.x + event->area.width, widget->allocation.x + widget->allocation.width); - y1 = MIN (event->area.y + event->area.height, widget->allocation.y + widget->allocation.height); - if ((x1 > x0) && (y1 > y0)) { - if (image->px) { - if (image->gradient) { - gint y; - guchar *p; - p = image->px + 3 * (x0 - widget->allocation.x); - for (y = y0; y < y1; y += VBLOCK) { - gdk_draw_rgb_image (widget->window, widget->style->black_gc, - x0, y, - (x1 - x0), MIN (VBLOCK, y1 - y), - GDK_RGB_DITHER_MAX, - p, widget->allocation.width * 3); - } - } else { - nr_gdk_draw_gray_garbage (widget->window, widget->style->black_gc, - x0, y0, - x1 - x0, y1 - y0); - } - } else { - gdk_draw_rectangle (widget->window, widget->style->black_gc, - x0, y0, - (x1 - x0), (y1 - x0), - TRUE); - } - } - } - - return TRUE; + SPGradientImage *image = SP_GRADIENT_IMAGE (widget); + SPGradient *gr = image->gradient; + + cairo_t *ct = gdk_cairo_create(widget->window); + + cairo_rectangle(ct, event->area.x, event->area.y, + event->area.width, event->area.height); + cairo_clip(ct); + cairo_translate(ct, widget->allocation.x, widget->allocation.y); + + cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); + cairo_set_source(ct, check); + cairo_paint(ct); + cairo_pattern_destroy(check); + + if (gr) { + cairo_pattern_t *p = sp_gradient_create_preview_pattern(gr, widget->allocation.width); + cairo_set_source(ct, p); + cairo_paint(ct); + cairo_pattern_destroy(p); + } + cairo_destroy(ct); + + return TRUE; } GtkWidget * @@ -268,26 +195,6 @@ sp_gradient_image_gradient_modified (SPObject *, guint /*flags*/, SPGradientImag static void sp_gradient_image_update (SPGradientImage *image) { - GtkAllocation *allocation; - - if (!image->px) return; - - allocation = &((GtkWidget *) image)->allocation; - - if (image->gradient) { - nr_render_checkerboard_rgb (image->px, allocation->width, VBLOCK, 3 * allocation->width, 0, 0); - sp_gradient_render_vector_block_rgb (image->gradient, - image->px, allocation->width, VBLOCK, 3 * allocation->width, - 0, allocation->width, TRUE); - } else { - NRPixBlock pb; - nr_pixblock_setup_extern (&pb, NR_PIXBLOCK_MODE_R8G8B8, - 0, 0, allocation->width, VBLOCK, - image->px, 3 * allocation->width, TRUE, FALSE); - nr_pixblock_render_gray_noise (&pb, NULL); - nr_pixblock_release (&pb); - } - if (GTK_WIDGET_DRAWABLE (image)) { gtk_widget_queue_draw (GTK_WIDGET (image)); } diff --git a/src/widgets/gradient-image.h b/src/widgets/gradient-image.h index d0864b6e8..3ddd14e35 100644 --- a/src/widgets/gradient-image.h +++ b/src/widgets/gradient-image.h @@ -14,7 +14,6 @@ */ #include <gtk/gtkwidget.h> -#include "../libnr/nr-matrix.h" class SPGradient; #include <glib.h> @@ -30,7 +29,6 @@ class SPGradient; struct SPGradientImage { GtkWidget widget; SPGradient *gradient; - guchar *px; sigc::connection release_connection; sigc::connection modified_connection; diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index 1eb3ef0ab..4ba86b295 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -1024,15 +1024,8 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, CAIRO_FORMAT_ARGB32, psize, psize, stride); cairo_t *ct = cairo_create(s); - NRPixBlock B; - nr_pixblock_setup_extern( &B, NR_PIXBLOCK_MODE_R8G8B8A8N, - ua.x0, ua.y0, ua.x1, ua.y1, - px + stride * (ua.y0 - area.y0) + - 4 * (ua.x0 - area.x0), - stride, FALSE, FALSE ); - nr_arena_item_invoke_render(ct, root, &ua, &B, + nr_arena_item_invoke_render(ct, root, &ua, NULL, NR_ARENA_ITEM_RENDER_NO_CACHE ); - nr_pixblock_release(&B); cairo_destroy(ct); cairo_surface_destroy(s); |
