drawing-item.h revision 3fca06bd7c5d09e03990e9cc29696c0435df4c69
2N/A/**
2N/A * @file
2N/A * Canvas item belonging to an SVG drawing element.
2N/A *//*
2N/A * Authors:
2N/A * Krzysztof KosiƄski <tweenk.pl@gmail.com>
2N/A *
2N/A * Copyright (C) 2011 Authors
2N/A * Released under GNU GPL, read the file 'COPYING' for more information
2N/A */
2N/A
2N/A#ifndef SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_H
2N/A#define SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_H
2N/A
2N/A#include <list>
2N/A#include <exception>
2N/A#include <boost/operators.hpp>
2N/A#include <boost/utility.hpp>
2N/A#include <boost/intrusive/list.hpp>
2N/A#include <2geom/rect.h>
2N/A#include <2geom/affine.h>
2N/A
2N/Aclass SPStyle;
2N/A
2N/Anamespace Inkscape {
2N/A
2N/Aclass Drawing;
2N/Aclass DrawingCache;
2N/Aclass DrawingContext;
2N/Aclass DrawingItem;
2N/A
2N/Anamespace Filters {
2N/A
2N/Aclass Filter;
2N/A
2N/A} // namespace Filters
2N/A
2N/A
2N/A
2N/Astruct UpdateContext {
2N/A Geom::Affine ctm;
2N/A};
2N/A
2N/Astruct CacheRecord
2N/A : boost::totally_ordered<CacheRecord>
2N/A{
2N/A bool operator<(CacheRecord const &other) const { return score < other.score; }
2N/A bool operator==(CacheRecord const &other) const { return score == other.score; }
2N/A operator DrawingItem *() const { return item; }
2N/A double score;
2N/A size_t cache_size;
2N/A DrawingItem *item;
2N/A};
2N/Atypedef std::list<CacheRecord> CacheList;
2N/A
2N/Aclass InvalidItemException : public std::exception {
2N/A virtual const char *what() const throw() {
2N/A return "Invalid item in drawing";
2N/A }
2N/A};
2N/A
2N/Aclass DrawingItem
2N/A : boost::noncopyable
2N/A{
2N/Apublic:
2N/A enum RenderFlags {
2N/A RENDER_DEFAULT = 0,
2N/A RENDER_CACHE_ONLY = 1,
2N/A RENDER_BYPASS_CACHE = 2,
2N/A RENDER_FILTER_BACKGROUND = 4
2N/A };
2N/A enum StateFlags {
2N/A STATE_NONE = 0,
2N/A STATE_BBOX = (1<<0), // bounding boxes are up-to-date
2N/A STATE_CACHE = (1<<1), // cache extents and clean area are up-to-date
2N/A STATE_PICK = (1<<2), // can process pick requests
2N/A STATE_RENDER = (1<<3), // can be rendered
2N/A STATE_BACKGROUND = (1<<4), // filter background data is up to date
2N/A STATE_ALL = (1<<5)-1
2N/A };
2N/A enum PickFlags {
2N/A PICK_NORMAL = 0, // normal pick
2N/A PICK_STICKY = (1<<0), // sticky pick - ignore visibility and sensitivity
2N/A PICK_AS_CLIP = (1<<2) // pick with no stroke and opaque fill regardless of item style
2N/A };
2N/A
2N/A DrawingItem(Drawing &drawing);
2N/A virtual ~DrawingItem();
2N/A
2N/A Geom::OptIntRect geometricBounds() const { return _bbox; }
2N/A Geom::OptIntRect visualBounds() const { return _drawbox; }
2N/A Geom::OptRect itemBounds() const { return _item_bbox; }
2N/A Geom::Affine ctm() const { return _ctm; }
2N/A Geom::Affine transform() const { return _transform ? *_transform : Geom::identity(); }
2N/A Drawing &drawing() const { return _drawing; }
2N/A DrawingItem *parent() const;
2N/A bool isAncestorOf(DrawingItem *item) const;
2N/A
2N/A void appendChild(DrawingItem *item);
2N/A void prependChild(DrawingItem *item);
2N/A void clearChildren();
2N/A
2N/A bool visible() const { return _visible; }
2N/A void setVisible(bool v);
2N/A bool sensitive() const { return _sensitive; }
2N/A void setSensitive(bool v);
2N/A bool cached() const { return _cached; }
2N/A void setCached(bool c, bool persistent = false);
2N/A
2N/A void setOpacity(float opacity);
2N/A void setAntialiasing(bool a);
2N/A void setIsolation(unsigned isolation); // CSS Compositing and Blending
2N/A void setBlendMode(unsigned blend_mode);
2N/A void setTransform(Geom::Affine const &trans);
2N/A void setClip(DrawingItem *item);
2N/A void setMask(DrawingItem *item);
2N/A void setZOrder(unsigned z);
2N/A void setItemBounds(Geom::OptRect const &bounds);
2N/A void setFilterBounds(Geom::OptRect const &bounds);
2N/A
2N/A void setKey(unsigned key) { _key = key; }
2N/A unsigned key() const { return _key; }
2N/A void setData(void *data) { _user_data = data; }
2N/A void *data() const { return _user_data; }
2N/A
2N/A void update(Geom::IntRect const &area = Geom::IntRect::infinite(), UpdateContext const &ctx = UpdateContext(), unsigned flags = STATE_ALL, unsigned reset = 0);
2N/A unsigned render(DrawingContext &dc, Geom::IntRect const &area, unsigned flags = 0, DrawingItem *stop_at = NULL);
2N/A void clip(DrawingContext &dc, Geom::IntRect const &area);
2N/A DrawingItem *pick(Geom::Point const &p, double delta, unsigned flags = 0);
2N/A
2N/Aprotected:
2N/A enum ChildType {
2N/A CHILD_ORPHAN = 0, // no parent - implies _parent == NULL
2N/A CHILD_NORMAL = 1, // contained in _children of parent
2N/A CHILD_CLIP = 2, // referenced by _clip member of parent
2N/A CHILD_MASK = 3, // referenced by _mask member of parent
2N/A CHILD_ROOT = 4, // root item of _drawing
2N/A CHILD_FILL_PATTERN = 5, // not yet implemented: referenced by fill pattern of parent
2N/A CHILD_STROKE_PATTERN = 6 // not yet implemented: referenced by stroke pattern of parent
2N/A };
2N/A enum RenderResult {
2N/A RENDER_OK = 0,
2N/A RENDER_STOP = 1
2N/A };
2N/A void _renderOutline(DrawingContext &dc, Geom::IntRect const &area, unsigned flags);
2N/A void _markForUpdate(unsigned state, bool propagate);
2N/A void _markForRendering();
2N/A void _invalidateFilterBackground(Geom::IntRect const &area);
2N/A void _setStyleCommon(SPStyle *&_style, SPStyle *style);
2N/A double _cacheScore();
2N/A Geom::OptIntRect _cacheRect();
2N/A virtual unsigned _updateItem(Geom::IntRect const &/*area*/, UpdateContext const &/*ctx*/,
2N/A unsigned /*flags*/, unsigned /*reset*/) { return 0; }
2N/A virtual unsigned _renderItem(DrawingContext &/*dc*/, Geom::IntRect const &/*area*/, unsigned /*flags*/,
2N/A DrawingItem * /*stop_at*/) { return RENDER_OK; }
2N/A virtual void _clipItem(DrawingContext &/*dc*/, Geom::IntRect const &/*area*/) {}
2N/A virtual DrawingItem *_pickItem(Geom::Point const &/*p*/, double /*delta*/, unsigned /*flags*/) { return NULL; }
2N/A virtual bool _canClip() { return false; }
2N/A
2N/A // member variables start here
Drawing &_drawing;
DrawingItem *_parent;
typedef boost::intrusive::list_member_hook<> ListHook;
ListHook _child_hook;
typedef boost::intrusive::list<
DrawingItem,
boost::intrusive::member_hook<DrawingItem, ListHook, &DrawingItem::_child_hook>
> ChildrenList;
ChildrenList _children;
unsigned _key; ///< Some SPItems can have more than one DrawingItem;
/// this value is a hack used to distinguish between them
float _opacity;
Geom::Affine *_transform; ///< Incremental transform from parent to this item's coords
Geom::Affine _ctm; ///< Total transform from item coords to display coords
Geom::OptIntRect _bbox; ///< Bounding box in display (pixel) coords including stroke
Geom::OptIntRect _drawbox; ///< Full visual bounding box - enlarged by filters, shrunk by clips and masks
Geom::OptRect _item_bbox; ///< Geometric bounding box in item's user space.
/// This is used to compute the filter effect region and render in
/// objectBoundingBox units.
DrawingItem *_clip;
DrawingItem *_mask;
Inkscape::Filters::Filter *_filter;
void *_user_data; ///< Used to associate DrawingItems with SPItems that created them
DrawingCache *_cache;
CacheList::iterator _cache_iterator;
unsigned _state : 8;
unsigned _propagate_state : 8;
unsigned _child_type : 3; // see ChildType enum
unsigned _background_new : 1; ///< Whether enable-background: new is set for this element
unsigned _background_accumulate : 1; ///< Whether this element accumulates background
/// (has any ancestor with enable-background: new)
unsigned _visible : 1;
unsigned _sensitive : 1; ///< Whether this item responds to events
unsigned _cached : 1; ///< Whether the rendering is stored for reuse
unsigned _cached_persistent : 1; ///< If set, will always be cached regardless of score
unsigned _has_cache_iterator : 1; ///< If set, _cache_iterator is valid
unsigned _propagate : 1; ///< Whether to call update for all children on next update
//unsigned _renders_opacity : 1; ///< Whether object needs temporary surface for opacity
unsigned _pick_children : 1; ///< For groups: if true, children are returned from pick(),
/// otherwise the group is returned
unsigned _antialias : 1; ///< Whether to use antialiasing
unsigned _isolation : 1;
unsigned _mix_blend_mode : 4;
friend class Drawing;
};
struct DeleteDisposer {
void operator()(DrawingItem *item) { delete item; }
};
} // end namespace Inkscape
#endif // !SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_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:fileencoding=utf-8:textwidth=99 :