summaryrefslogtreecommitdiffstats
path: root/src/sp-pattern.h
blob: 3fe0f53d81c227f49a59103579de5ba291fbfdad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/** @file
 * SVG <pattern> implementation
 *//*
 * Author:
 *   Lauris Kaplinski <lauris@kaplinski.com>
 *   Abhishek Sharma
 *
 * Copyright (C) 2002 Lauris Kaplinski
 *
 * Released under GNU GPL, read the file 'COPYING' for more information
 */

#ifndef SEEN_SP_PATTERN_H
#define SEEN_SP_PATTERN_H

#include <list>
#include <stddef.h>
#include <glibmm/ustring.h>
#include <sigc++/connection.h>

#include "svg/svg-length.h"
#include "sp-paint-server.h"
#include "uri-references.h"
#include "viewbox.h"

class SPPatternReference;
class SPItem;

namespace Inkscape {
namespace XML {

class Node;

}
}

#define SP_PATTERN(obj) (dynamic_cast<SPPattern*>((SPObject*)obj))
#define SP_IS_PATTERN(obj) (dynamic_cast<const SPPattern*>((SPObject*)obj) != NULL)

class SPPattern : public SPPaintServer, public SPViewBox {
public:
    enum PatternUnits {
        UNITS_USERSPACEONUSE,
        UNITS_OBJECTBOUNDINGBOX
    };

	SPPattern();
	virtual ~SPPattern();

    /* Reference (href) */
	Glib::ustring href;
    SPPatternReference *ref;

    gdouble get_x() const;
    gdouble get_y() const;
    gdouble get_width() const;
    gdouble get_height() const;
    Geom::OptRect get_viewbox() const;
    SPPattern::PatternUnits get_pattern_units() const;
    SPPattern::PatternUnits get_pattern_content_units() const;
    Geom::Affine const &get_transform() const;
    SPPattern *get_root(); //TODO: const

    SPPattern *clone_if_necessary(SPItem *item, const gchar *property);
    void transform_multiply(Geom::Affine postmul, bool set);

    /**
     * @brief create a new pattern in XML tree
     * @return created pattern id
     */
    static const gchar *produce(const std::list<Inkscape::XML::Node*> &reprs,
    		Geom::Rect bounds, SPDocument *document, Geom::Affine transform, Geom::Affine move);

    bool isValid() const;
	virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity);

protected:
	virtual void build(SPDocument* doc, Inkscape::XML::Node* repr);
	virtual void release();
	virtual void set(unsigned int key, const gchar* value);
	virtual void update(SPCtx* ctx, unsigned int flags);
	virtual void modified(unsigned int flags);

private:
	bool _has_item_children() const;
	void _get_children(std::list<SPObject*>& l);
	SPPattern *_chain() const;

	/**
	Count how many times pattern is used by the styles of o and its descendants
	*/
	guint _count_hrefs(SPObject* o) const;

	/**
	Gets called when the pattern is reattached to another <pattern>
	*/
	void _on_ref_changed(SPObject *old_ref, SPObject *ref);

	/**
	Gets called when the referenced <pattern> is changed
	*/
	void _on_ref_modified(SPObject *ref, guint flags);

    /* patternUnits and patternContentUnits attribute */
    PatternUnits patternUnits : 1;
    bool patternUnits_set : 1;
    PatternUnits patternContentUnits : 1;
    bool patternContentUnits_set : 1;
    /* patternTransform attribute */
    Geom::Affine patternTransform;
    bool patternTransform_set : 1;
    /* Tile rectangle */
    SVGLength x;
    SVGLength y;
    SVGLength width;
    SVGLength height;

    sigc::connection modified_connection;
};


class SPPatternReference : public Inkscape::URIReference {
public:
    SPPatternReference (SPObject *obj) : URIReference(obj) {}
    SPPattern *getObject() const {
        return reinterpret_cast<SPPattern *>(URIReference::getObject());
    }

protected:
    virtual bool _acceptObject(SPObject *obj) const {
        return SP_IS_PATTERN (obj);
    }
};

#endif // SEEN_SP_PATTERN_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 :