Changeset View
Changeset View
Standalone View
Standalone View
libs/flake/KoClipMask.cpp
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | * Copyright (c) 2016 Dmitry Kazakov <dimula73@gmail.com> | ||||
3 | * | ||||
4 | * This program is free software; you can redistribute it and/or modify | ||||
5 | * it under the terms of the GNU General Public License as published by | ||||
6 | * the Free Software Foundation; either version 2 of the License, or | ||||
7 | * (at your option) any later version. | ||||
8 | * | ||||
9 | * This program is distributed in the hope that it will be useful, | ||||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
12 | * GNU General Public License for more details. | ||||
13 | * | ||||
14 | * You should have received a copy of the GNU General Public License | ||||
15 | * along with this program; if not, write to the Free Software | ||||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
17 | */ | ||||
18 | | ||||
19 | #include "KoClipMask.h" | ||||
20 | | ||||
21 | #include <QRectF> | ||||
22 | #include <QTransform> | ||||
23 | #include <QPainter> | ||||
24 | #include <KoShape.h> | ||||
25 | #include "kis_algebra_2d.h" | ||||
26 | | ||||
27 | #include <KoViewConverter.h> | ||||
28 | #include <KoShapePainter.h> | ||||
29 | | ||||
30 | struct Q_DECL_HIDDEN KoClipMask::Private { | ||||
31 | Private() {} | ||||
32 | Private(const Private &rhs) | ||||
33 | : coordinates(rhs.coordinates), | ||||
34 | contentCoordinates(rhs.contentCoordinates), | ||||
35 | maskRect(rhs.maskRect), | ||||
36 | extraShapeTransform(rhs.extraShapeTransform) | ||||
37 | { | ||||
38 | Q_FOREACH (KoShape *shape, rhs.shapes) { | ||||
39 | KoShape *clonedShape = shape->cloneShape(); | ||||
40 | KIS_ASSERT_RECOVER(clonedShape) { continue; } | ||||
41 | | ||||
42 | shapes << clonedShape; | ||||
43 | } | ||||
44 | } | ||||
45 | | ||||
46 | ~Private() { | ||||
47 | qDeleteAll(shapes); | ||||
48 | shapes.clear(); | ||||
49 | } | ||||
50 | | ||||
51 | | ||||
52 | KoFlake::CoordinateSystem coordinates = KoFlake::ObjectBoundingBox; | ||||
53 | KoFlake::CoordinateSystem contentCoordinates = KoFlake::UserSpaceOnUse; | ||||
54 | | ||||
55 | QRectF maskRect = QRectF(-0.1, -0.1, 1.2, 1.2); | ||||
56 | | ||||
57 | QList<KoShape*> shapes; | ||||
58 | QTransform extraShapeTransform; // TODO: not used anymore, use direct shape transform instead | ||||
59 | | ||||
60 | }; | ||||
61 | | ||||
62 | KoClipMask::KoClipMask() | ||||
63 | : m_d(new Private) | ||||
64 | { | ||||
65 | } | ||||
66 | | ||||
67 | KoClipMask::~KoClipMask() | ||||
68 | { | ||||
69 | } | ||||
70 | | ||||
71 | KoClipMask::KoClipMask(const KoClipMask &rhs) | ||||
72 | : m_d(new Private(*rhs.m_d)) | ||||
73 | { | ||||
74 | } | ||||
75 | | ||||
76 | KoClipMask *KoClipMask::clone() const | ||||
77 | { | ||||
78 | return new KoClipMask(*this); | ||||
79 | } | ||||
80 | | ||||
81 | KoFlake::CoordinateSystem KoClipMask::coordinates() const | ||||
82 | { | ||||
83 | return m_d->coordinates; | ||||
84 | } | ||||
85 | | ||||
86 | void KoClipMask::setCoordinates(KoFlake::CoordinateSystem value) | ||||
87 | { | ||||
88 | m_d->coordinates = value; | ||||
89 | } | ||||
90 | | ||||
91 | KoFlake::CoordinateSystem KoClipMask::contentCoordinates() const | ||||
92 | { | ||||
93 | return m_d->contentCoordinates; | ||||
94 | } | ||||
95 | | ||||
96 | void KoClipMask::setContentCoordinates(KoFlake::CoordinateSystem value) | ||||
97 | { | ||||
98 | m_d->contentCoordinates = value; | ||||
99 | } | ||||
100 | | ||||
101 | QRectF KoClipMask::maskRect() const | ||||
102 | { | ||||
103 | return m_d->maskRect; | ||||
104 | } | ||||
105 | | ||||
106 | void KoClipMask::setMaskRect(const QRectF &value) | ||||
107 | { | ||||
108 | m_d->maskRect = value; | ||||
109 | } | ||||
110 | | ||||
111 | QList<KoShape *> KoClipMask::shapes() const | ||||
112 | { | ||||
113 | return m_d->shapes; | ||||
114 | } | ||||
115 | | ||||
116 | void KoClipMask::setShapes(const QList<KoShape *> &value) | ||||
117 | { | ||||
118 | m_d->shapes = value; | ||||
119 | } | ||||
120 | | ||||
121 | bool KoClipMask::isEmpty() const | ||||
122 | { | ||||
123 | return m_d->shapes.isEmpty(); | ||||
124 | } | ||||
125 | | ||||
126 | void KoClipMask::setExtraShapeOffset(const QPointF &value) | ||||
127 | { | ||||
128 | /** | ||||
129 | * TODO: when we implement source shapes sharing, please wrap the shapes | ||||
130 | * into a group and apply this transform to the group instead | ||||
131 | */ | ||||
132 | | ||||
133 | if (m_d->contentCoordinates == KoFlake::UserSpaceOnUse) { | ||||
134 | const QTransform t = QTransform::fromTranslate(value.x(), value.y()); | ||||
135 | | ||||
136 | Q_FOREACH (KoShape *shape, m_d->shapes) { | ||||
137 | shape->applyAbsoluteTransformation(t); | ||||
138 | } | ||||
139 | } | ||||
140 | | ||||
141 | if (m_d->coordinates == KoFlake::UserSpaceOnUse) { | ||||
142 | m_d->maskRect.translate(value); | ||||
143 | } | ||||
144 | } | ||||
145 | | ||||
146 | void KoClipMask::drawMask(QPainter *painter, KoShape *shape) | ||||
147 | { | ||||
148 | painter->save(); | ||||
149 | | ||||
150 | QPainterPath clipPathInShapeSpace; | ||||
151 | | ||||
152 | if (m_d->coordinates == KoFlake::ObjectBoundingBox) { | ||||
153 | QTransform relativeToShape = KisAlgebra2D::mapToRect(shape->outlineRect()); | ||||
154 | clipPathInShapeSpace.addPolygon(relativeToShape.map(m_d->maskRect)); | ||||
155 | } else { | ||||
156 | clipPathInShapeSpace.addRect(m_d->maskRect); | ||||
157 | clipPathInShapeSpace = m_d->extraShapeTransform.map(clipPathInShapeSpace); | ||||
158 | } | ||||
159 | | ||||
160 | painter->setClipPath(clipPathInShapeSpace, Qt::IntersectClip); | ||||
161 | | ||||
162 | if (m_d->contentCoordinates == KoFlake::ObjectBoundingBox) { | ||||
163 | QTransform relativeToShape = KisAlgebra2D::mapToRect(shape->outlineRect()); | ||||
164 | | ||||
165 | painter->setTransform(relativeToShape, true); | ||||
166 | } else { | ||||
167 | painter->setTransform(m_d->extraShapeTransform, true); | ||||
168 | } | ||||
169 | | ||||
170 | KoViewConverter converter; | ||||
171 | KoShapePainter p; | ||||
172 | p.setShapes(m_d->shapes); | ||||
173 | p.paint(*painter, converter); | ||||
174 | | ||||
175 | painter->restore(); | ||||
176 | } |