drawing-group.cpp revision 3e0790bc7c644b06f3f02ae3bdbf682ce1b3f9ce
1549N/A/**
1549N/A * @file
1549N/A * @brief Group belonging to an SVG drawing element
1549N/A *//*
1549N/A * Authors:
1549N/A * Krzysztof KosiƄski <tweenk.pl@gmail.com>
1549N/A *
1549N/A * Copyright (C) 2011 Authors
1549N/A * Released under GNU GPL, read the file 'COPYING' for more information
1549N/A */
1549N/A
1549N/A#include "display/cairo-utils.h"
1549N/A#include "display/drawing.h"
1549N/A#include "display/drawing-context.h"
1549N/A#include "display/drawing-item.h"
1549N/A#include "display/drawing-group.h"
1549N/A#include "libnr/nr-values.h"
1549N/A#include "style.h"
1549N/A
1549N/Anamespace Inkscape {
1549N/A
1549N/ADrawingGroup::DrawingGroup(Drawing &drawing)
1549N/A : DrawingItem(drawing)
1549N/A , _style(NULL)
1549N/A , _child_transform(NULL)
1549N/A{}
1549N/A
1549N/ADrawingGroup::~DrawingGroup()
1549N/A{
1549N/A if (_style)
1549N/A sp_style_unref(_style);
1549N/A}
1549N/A
1549N/A/** @brief Set whether the group returns children from pick calls.
1549N/A * Previously this feature was called "transparent groups".
1549N/A */
1549N/Avoid
1549N/ADrawingGroup::setPickChildren(bool p)
1549N/A{
1549N/A _pick_children = p;
1549N/A}
1549N/A
1549N/Avoid
1549N/ADrawingGroup::setStyle(SPStyle *style)
{
_setStyleCommon(_style, style);
}
/** @brief Set additional transform for the group.
* This is applied after the normal transform and mainly useful for
* markers, clipping paths, etc.
*/
void
DrawingGroup::setChildTransform(Geom::Affine const &new_trans)
{
Geom::Affine current;
if (_child_transform) {
current = *_child_transform;
}
if (!Geom::are_near(current, new_trans, NR_EPSILON)) {
// mark the area where the object was for redraw.
_markForRendering();
if (new_trans.isIdentity()) {
delete _child_transform; // delete NULL; is safe
_child_transform = NULL;
} else {
_child_transform = new Geom::Affine(new_trans);
}
_markForUpdate(STATE_ALL, true);
}
}
unsigned
DrawingGroup::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset)
{
unsigned beststate = STATE_ALL;
bool outline = _drawing.outline();
for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) {
UpdateContext child_ctx(ctx);
if (_child_transform) {
child_ctx.ctm = *_child_transform * ctx.ctm;
}
i->update(area, child_ctx, flags, reset);
}
if (beststate & STATE_BBOX) {
_bbox = Geom::OptIntRect();
for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) {
if (i->visible()) {
_bbox.unionWith(outline ? i->geometricBounds() : i->visualBounds());
}
}
}
return beststate;
}
void
DrawingGroup::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags)
{
for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) {
i->render(ct, area, flags);
}
}
void
DrawingGroup::_clipItem(DrawingContext &ct, Geom::IntRect const &area)
{
for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) {
i->clip(ct, area);
}
}
DrawingItem *
DrawingGroup::_pickItem(Geom::Point const &p, double delta, unsigned flags)
{
for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) {
DrawingItem *picked = i->pick(p, delta, flags);
if (picked) {
return _pick_children ? picked : this;
}
}
return NULL;
}
bool
DrawingGroup::_canClip()
{
return true;
}
bool is_drawing_group(DrawingItem *item)
{
return dynamic_cast<DrawingGroup *>(item) != NULL;
}
} // end namespace Inkscape
/*
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 :