nr-arena-item.cpp revision 28318b9cff1b85a7041eb33789e3ae7b4d8d933e
#define __NR_ARENA_ITEM_C__
/*
* RGBA display list system for inkscape
*
* Author:
* Lauris Kaplinski <lauris@kaplinski.com>
*
* Copyright (C) 2001-2002 Lauris Kaplinski
* Copyright (C) 2001 Ximian, Inc.
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#define noNR_ARENA_ITEM_VERBOSE
#define noNR_ARENA_ITEM_DEBUG_CASCADE
#include <cstring>
#include <string>
#include <libnr/nr-pixops.h>
#include "display/cairo-utils.h"
#include "nr-arena.h"
#include "nr-arena-item.h"
#include "gc-core.h"
#include "nr-filter.h"
#include "nr-arena-group.h"
#include "preferences.h"
static NRObjectClass *parent_class;
nr_arena_item_get_type (void)
{
if (!type) {
"NRArenaItem",
sizeof (NRArenaItemClass),
sizeof (NRArenaItem),
(void (*)(NRObjectClass *))
(void (*)(NRObject *))
}
return type;
}
static void
{
}
static void
{
item->background_new = false;
}
static void
{
}
{
return NULL;
}
{
} else {
if (ref)
return ref;
}
}
void
{
}
void
{
}
void
{
}
{
return item;
}
{
return NULL;
}
unsigned int
{
#ifdef NR_ARENA_ITEM_DEBUG_CASCADE
printf ("Update %s:%p %x %x %x\n",
#endif
/* return if in error */
/* Set reset flags according to propagation status */
}
/* Reset our state */
/* Return if NOP */
/* Test whether to return immediately */
}
/* Reset image cache, if not to be kept */
}
/* Set up local gc */
}
/* Remember the transformation matrix */
/* Invoke the real method */
// that will update bbox
// get a copy of bbox
/* Enlarge the drawbox to contain filter effects */
}
// fixme: to fix the display glitches, in outline mode bbox must be a combination of
// full item bbox and its clip and mask (after we have the API to get these)
/* Clipping */
// FIXME: since here we only need bbox, consider passing
// ((state & !(NR_ARENA_ITEM_STATE_RENDER)) | NR_ARENA_ITEM_STATE_BBOX)
// instead of state, so it does not have to create rendering structures in nr_arena_shape_update
if (newstate & NR_ARENA_ITEM_STATE_INVALID) {
}
// for clipping, we need geometric bbox
}
/* Masking */
if (newstate & NR_ARENA_ITEM_STATE_INVALID) {
}
// for masking, we need full drawbox of mask
}
// now that we know drawbox, dirty the corresponding rect on canvas:
// unless filtered, groups do not need to render by themselves, only their members
}
}
/**
* Render item to pixblock.
*
* \return Has NR_ARENA_ITEM_STATE_RENDER set on success.
*/
unsigned int
{
#ifdef NR_ARENA_ITEM_VERBOSE
#endif
/* If we are invisible, just return successfully */
// carea is the bounding box for intermediate rendering.
if (nr_rect_l_test_empty(carea))
}
if (outline) {
// No caching in outline mode for now; investigate if it really gives any advantage with cairo.
// Also no attempts to clip anything; just render everything: item, clip, mask
// First, render the object itself
if (state & NR_ARENA_ITEM_STATE_INVALID) {
/* Clean up and return error */
}
// render clip and mask, if any
// render clippath as an object, using a different color
item->arena->outlinecolor = prefs->getInt("/options/wireframecolors/clips", 0x00ff00ff); // green clips
}
// render mask as an object, using a different color
item->arena->outlinecolor = prefs->getInt("/options/wireframecolors/masks", 0x0000ffff); // blue masks
}
}
#if 0
/* 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 */
TRUE);
// if memory allocation failed, abort render
}
/* 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 ||
}
}
if (state & NR_ARENA_ITEM_STATE_INVALID) {
/* Clean up and return error */
}
/* Run filtering, if a filter is set for this object */
}
/* Setup mask pixblock */
/* Do clip if needed */
if (state & NR_ARENA_ITEM_STATE_INVALID) {
/* Clean up and return error */
}
}
/* Do mask if needed */
/* Set up yet another temporary pixblock */
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 */
}
/* Composite with clip */
int x, y;
unsigned char *s, *d;
s = NR_PIXBLOCK_PX (&tpb) + (y -
d = NR_PIXBLOCK_PX (&mpb) + (y -
unsigned int m;
d[0] =
(NR_PREMUL_123 (d[0], m));
s += 4;
d += 1;
}
}
} else {
int x, y;
unsigned char *s, *d;
s = NR_PIXBLOCK_PX (&tpb) + (y -
d = NR_PIXBLOCK_PX (&mpb) + (y -
unsigned int m;
s += 4;
d += 1;
}
}
}
}
}
/* Multiply with opacity if needed */
) {
int x, y;
unsigned int a;
unsigned char *d;
d[0] = NR_PREMUL_111 (d[0], a);
d += 1;
}
}
}
/* Compose rendering pixblock int destination */
}
} else {
} else { // copy while multiplying by opacity
}
}
/* This pointer wouldn't be valid outside this block, so clear it */
} 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 */
}
}
/* Have to blit from cache */
}
#endif
using namespace Inkscape;
// clipping and masks
unsigned int state;
bool needs_intermediate_rendering = false;
bool &nir = needs_intermediate_rendering;
// this item needs an intermediate rendering if:
if (needs_intermediate_rendering) {
}
if (state & NR_ARENA_ITEM_STATE_INVALID) {
}
}
// handle opacity of a masked object by composing it with the mask
// this uses 1/4 the memory of composing it with full rendering
if (needs_opacity) {
}
if (state & NR_ARENA_ITEM_STATE_INVALID) {
}
if (needs_opacity) {
}
}
/*if (mask) {
drawgroup.push();
}*/
if (state & NR_ARENA_ITEM_STATE_INVALID) {
/* Clean up and return error */
}
if (needs_intermediate_rendering) {
if (mask) {
// bring mask into the coordinate system of ct
// opacity of masked objects is handled by premultiplying the mask
} else {
// opacity of non-masked objects must be rendered explicitly
if (needs_opacity) {
} else {
}
}
cairo_set_source_rgba(ct,0,0,0,0);
}
}
unsigned int
{
/* we originally short-circuited if the object state included
* NR_ARENA_ITEM_STATE_CLIP (and showed a warning on the console);
* anyone know why we stopped doing so?
*/
/*nr_return_val_if_fail ((pb->area.x1 - pb->area.x0) >=
(area->x1 - area->x0),
NR_ARENA_ITEM_STATE_INVALID);
nr_return_val_if_fail ((pb->area.y1 - pb->area.y0) >=
(area->y1 - area->y0),
NR_ARENA_ITEM_STATE_INVALID);*/
#ifdef NR_ARENA_ITEM_VERBOSE
printf ("Invoke clip by %p: %d %d - %d %d, item bbox %d %d - %d %d\n",
#endif
/* Need render that item */
}
}
}
unsigned int sticky)
{
// Sometimes there's no BBOX in item->state, reason unknown (bug 992817); I made this not an assert to remove the warning
return NULL;
return NULL;
// TODO: rewrite using Geom::Rect
const double x = p[Geom::X];
const double y = p[Geom::Y];
}
return NULL;
}
void
unsigned int propagate)
{
} else {
}
}
}
void
{
}
/* Public */
{
}
return NULL;
}
void
{
}
void
{
nr_arena_item_set_transform (item, &t);
}
void
{
return;
/* Set to identity affine */
} else {
}
}
}
void
{
}
void
{
}
void
{
}
void
{
if (clip)
}
}
void
{
if (mask)
}
}
void
{
return;
int pos = 0;
break;
pos += 1;
}
}
}
void
{
}
/** Returns a background image for use with filter effects. */
{
NRPixBlock *pb;
if (!item->background_pb)
return NULL;
if (item->background_new) {
pb = new NRPixBlock ();
return NULL;
} else
return NULL;
if (depth > 0)
return pb;
}
/* Helpers */
{
if (prev)
if (next)
return child;
}
{
if (prev)
if (next)
return next;
}
/*
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 :