nr-arena-item.cpp revision 4cac4ca7df74906a58898242874f3068e3efb0a2
#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 "display/cairo-utils.h"
#include "display/cairo-templates.h"
#include "display/drawing-context.h"
#include "display/drawing-surface.h"
#include "display/canvas-arena.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 */
// we have up-to-date bbox
}
/* Set up local gc */
}
/* Remember the transformation matrix */
/* Invoke the real method */
// that will update bbox
/* Enlarge the drawbox to contain filter effects */
} else {
}
/* 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) {
}
if (outline) {
} else {
}
}
/* Masking */
if (newstate & NR_ARENA_ITEM_STATE_INVALID) {
}
if (outline) {
} else {
// for masking, we need full drawbox of mask
}
}
// update cache if enabled
if (item->render_cache) {
if (cl) {
// this takes care of invalidation on transform
} else {
// the cache is initially dirty
}
} else {
// disable cache for this item - not visible
}
}
// now that we know drawbox, dirty the corresponding rect on canvas:
// unless filtered, groups do not need to render by themselves, only their members
if (state & ~NR_ARENA_ITEM_STATE_CACHE) {
}
}
}
struct MaskLuminanceToAlpha {
EXTRACT_ARGB32(in, a, r, g, b)
// the operation of unpremul -> luminance-to-alpha -> multiply by alpha
// is equivalent to luminance-to-alpha on premultiplied color values
// original computation in double: r*0.2125 + g*0.7154 + b*0.0721
}
};
unsigned int
nr_arena_item_invoke_render (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area,
unsigned int flags)
{
/* If we are invisible, just return successfully */
if (outline) {
// intersect with bbox rather than drawbox, as we want to render things outside
// of the clipping path as well
if (!carea)
// 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
}
}
// carea is the bounding box for intermediate rendering.
if (!carea)
// render from cache
}
// expand carea to contain the dependent area of filters.
}
using namespace Inkscape;
unsigned state;
unsigned retstate;
// determine whether this shape needs intermediate rendering.
bool needs_intermediate_rendering = false;
bool &nir = needs_intermediate_rendering;
// this item needs an intermediate rendering if:
/* How the rendering is done.
*
* Clipping, masking and opacity are done by rendering them to a surface
* and then compositing the object's rendering onto it with the IN operator.
* The object itself is rendered to a group.
*
* Opacity is done by rendering the clipping path with an alpha
* value corresponding to the opacity. If there is no clipping path,
* the entire intermediate surface is painted with alpha corresponding
* to the opacity value.
*/
// short-circuit the simple case.
if (!needs_intermediate_rendering) {
{ // 1. clear the corresponding part of cache
}
// 2. render to cache
if (state & NR_ARENA_ITEM_STATE_INVALID) {
}
// 3. copy from cache to output
// 4. mark as clean
} else {
if (state & NR_ARENA_ITEM_STATE_INVALID) {
}
}
}
// 1. Render clipping path with alpha = opacity.
// Since clip can be combined with opacity, the result could be incorrect
// for overlapping clip children. To fix this we use the SOURCE operator
// instead of the default OVER.
if (state & NR_ARENA_ITEM_STATE_INVALID) {
goto cleanup;
}
} else {
// if there is no clipping path, fill the entire surface with alpha = opacity.
}
// reset back to default
// 2. Render the mask if present and compose it with the clipping path + opacity.
if (state & NR_ARENA_ITEM_STATE_INVALID) {
goto cleanup;
}
// Convert mask's luminance to alpha
}
// 3. Render object itself.
if (state & NR_ARENA_ITEM_STATE_INVALID) {
goto cleanup;
}
// 4. Apply filter.
// Note that because the object was rendered to a group,
// the internals of the filter need to use cairo_get_group_target()
// instead of cairo_get_target().
}
// 5. Render object inside the composited mask + clip
// 6. Paint the completed rendering onto the base context (or into cache)
}
// the call above is to clear a ref on the intermediate surface held by ct
return retstate;
}
unsigned int
nr_arena_item_invoke_clip (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area)
{
unsigned retstate = 0;
// don't bother if the object does not implement clipping (e.g. NRArenaImage)
return retstate;
// The item used as the clipping path itself has a clipping path.
// Render this item's clipping path onto a temporary surface, then composite it
// with the item using the IN operator
ct.pushAlphaGroup();
}
ct.pushAlphaGroup();
}
// rasterize the clipping path
}
}
return retstate;
}
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;
}
return NULL;
}
void
unsigned int propagate)
{
} else {
}
}
}
void
{
if (!dirty) return;
// dirty the caches of all parents
if (i->render_cache && i->cache) {
}
}
}
/* Public */
{
}
return NULL;
}
void
{
}
void
{
nr_arena_item_set_transform (item, &t);
}
void
{
return;
// mark the area where the object was for redraw.
/* Set to identity affine */
} else {
}
// when update is called, the area where the object was moved
// will be redrawn as well
}
}
void
{
}
void
{
}
void
{
}
void
{
if (clip)
}
}
void
{
if (mask)
}
}
void
{
return;
int pos = 0;
break;
pos += 1;
}
}
}
void
{
}
void
{
if (cache) {
} else {
}
}
/** Returns a background image for use with filter effects. */
{
return NULL;
}
/* 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:fileencoding=utf-8:textwidth=99 :