1 /*
2 * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22 #include "config.h"
23 #include "FillLayer.h"
24
25 namespace WebCore {
26
FillLayer(EFillLayerType type)27 FillLayer::FillLayer(EFillLayerType type)
28 : m_next(0)
29 , m_image(FillLayer::initialFillImage(type))
30 , m_xPosition(FillLayer::initialFillXPosition(type))
31 , m_yPosition(FillLayer::initialFillYPosition(type))
32 , m_attachment(FillLayer::initialFillAttachment(type))
33 , m_clip(FillLayer::initialFillClip(type))
34 , m_origin(FillLayer::initialFillOrigin(type))
35 , m_repeatX(FillLayer::initialFillRepeatX(type))
36 , m_repeatY(FillLayer::initialFillRepeatY(type))
37 , m_composite(FillLayer::initialFillComposite(type))
38 , m_sizeType(SizeNone)
39 , m_sizeLength(FillLayer::initialFillSizeLength(type))
40 , m_imageSet(false)
41 , m_attachmentSet(false)
42 , m_clipSet(false)
43 , m_originSet(false)
44 , m_repeatXSet(false)
45 , m_repeatYSet(false)
46 , m_xPosSet(false)
47 , m_yPosSet(false)
48 , m_compositeSet(type == MaskFillLayer)
49 , m_type(type)
50 {
51 }
52
FillLayer(const FillLayer & o)53 FillLayer::FillLayer(const FillLayer& o)
54 : m_next(o.m_next ? new FillLayer(*o.m_next) : 0)
55 , m_image(o.m_image)
56 , m_xPosition(o.m_xPosition)
57 , m_yPosition(o.m_yPosition)
58 , m_attachment(o.m_attachment)
59 , m_clip(o.m_clip)
60 , m_origin(o.m_origin)
61 , m_repeatX(o.m_repeatX)
62 , m_repeatY(o.m_repeatY)
63 , m_composite(o.m_composite)
64 , m_sizeType(o.m_sizeType)
65 , m_sizeLength(o.m_sizeLength)
66 , m_imageSet(o.m_imageSet)
67 , m_attachmentSet(o.m_attachmentSet)
68 , m_clipSet(o.m_clipSet)
69 , m_originSet(o.m_originSet)
70 , m_repeatXSet(o.m_repeatXSet)
71 , m_repeatYSet(o.m_repeatYSet)
72 , m_xPosSet(o.m_xPosSet)
73 , m_yPosSet(o.m_yPosSet)
74 , m_compositeSet(o.m_compositeSet)
75 , m_type(o.m_type)
76 {
77 }
78
~FillLayer()79 FillLayer::~FillLayer()
80 {
81 delete m_next;
82 }
83
operator =(const FillLayer & o)84 FillLayer& FillLayer::operator=(const FillLayer& o)
85 {
86 if (m_next != o.m_next) {
87 delete m_next;
88 m_next = o.m_next ? new FillLayer(*o.m_next) : 0;
89 }
90
91 m_image = o.m_image;
92 m_xPosition = o.m_xPosition;
93 m_yPosition = o.m_yPosition;
94 m_attachment = o.m_attachment;
95 m_clip = o.m_clip;
96 m_composite = o.m_composite;
97 m_origin = o.m_origin;
98 m_repeatX = o.m_repeatX;
99 m_repeatY = o.m_repeatY;
100 m_sizeType = o.m_sizeType;
101 m_sizeLength = o.m_sizeLength;
102
103 m_imageSet = o.m_imageSet;
104 m_attachmentSet = o.m_attachmentSet;
105 m_clipSet = o.m_clipSet;
106 m_compositeSet = o.m_compositeSet;
107 m_originSet = o.m_originSet;
108 m_repeatXSet = o.m_repeatXSet;
109 m_repeatYSet = o.m_repeatYSet;
110 m_xPosSet = o.m_xPosSet;
111 m_yPosSet = o.m_yPosSet;
112
113 m_type = o.m_type;
114
115 return *this;
116 }
117
operator ==(const FillLayer & o) const118 bool FillLayer::operator==(const FillLayer& o) const
119 {
120 // We do not check the "isSet" booleans for each property, since those are only used during initial construction
121 // to propagate patterns into layers. All layer comparisons happen after values have all been filled in anyway.
122 return StyleImage::imagesEquivalent(m_image.get(), o.m_image.get()) && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition &&
123 m_attachment == o.m_attachment && m_clip == o.m_clip &&
124 m_composite == o.m_composite && m_origin == o.m_origin && m_repeatX == o.m_repeatX &&
125 m_repeatY == o.m_repeatY && m_sizeType == o.m_sizeType && m_sizeLength == o.m_sizeLength &&
126 m_type == o.m_type && ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next);
127 }
128
fillUnsetProperties()129 void FillLayer::fillUnsetProperties()
130 {
131 FillLayer* curr;
132 for (curr = this; curr && curr->isXPositionSet(); curr = curr->next()) { }
133 if (curr && curr != this) {
134 // We need to fill in the remaining values with the pattern specified.
135 for (FillLayer* pattern = this; curr; curr = curr->next()) {
136 curr->m_xPosition = pattern->m_xPosition;
137 pattern = pattern->next();
138 if (pattern == curr || !pattern)
139 pattern = this;
140 }
141 }
142
143 for (curr = this; curr && curr->isYPositionSet(); curr = curr->next()) { }
144 if (curr && curr != this) {
145 // We need to fill in the remaining values with the pattern specified.
146 for (FillLayer* pattern = this; curr; curr = curr->next()) {
147 curr->m_yPosition = pattern->m_yPosition;
148 pattern = pattern->next();
149 if (pattern == curr || !pattern)
150 pattern = this;
151 }
152 }
153
154 for (curr = this; curr && curr->isAttachmentSet(); curr = curr->next()) { }
155 if (curr && curr != this) {
156 // We need to fill in the remaining values with the pattern specified.
157 for (FillLayer* pattern = this; curr; curr = curr->next()) {
158 curr->m_attachment = pattern->m_attachment;
159 pattern = pattern->next();
160 if (pattern == curr || !pattern)
161 pattern = this;
162 }
163 }
164
165 for (curr = this; curr && curr->isClipSet(); curr = curr->next()) { }
166 if (curr && curr != this) {
167 // We need to fill in the remaining values with the pattern specified.
168 for (FillLayer* pattern = this; curr; curr = curr->next()) {
169 curr->m_clip = pattern->m_clip;
170 pattern = pattern->next();
171 if (pattern == curr || !pattern)
172 pattern = this;
173 }
174 }
175
176 for (curr = this; curr && curr->isCompositeSet(); curr = curr->next()) { }
177 if (curr && curr != this) {
178 // We need to fill in the remaining values with the pattern specified.
179 for (FillLayer* pattern = this; curr; curr = curr->next()) {
180 curr->m_composite = pattern->m_composite;
181 pattern = pattern->next();
182 if (pattern == curr || !pattern)
183 pattern = this;
184 }
185 }
186
187 for (curr = this; curr && curr->isOriginSet(); curr = curr->next()) { }
188 if (curr && curr != this) {
189 // We need to fill in the remaining values with the pattern specified.
190 for (FillLayer* pattern = this; curr; curr = curr->next()) {
191 curr->m_origin = pattern->m_origin;
192 pattern = pattern->next();
193 if (pattern == curr || !pattern)
194 pattern = this;
195 }
196 }
197
198 for (curr = this; curr && curr->isRepeatXSet(); curr = curr->next()) { }
199 if (curr && curr != this) {
200 // We need to fill in the remaining values with the pattern specified.
201 for (FillLayer* pattern = this; curr; curr = curr->next()) {
202 curr->m_repeatX = pattern->m_repeatX;
203 pattern = pattern->next();
204 if (pattern == curr || !pattern)
205 pattern = this;
206 }
207 }
208
209 for (curr = this; curr && curr->isRepeatYSet(); curr = curr->next()) { }
210 if (curr && curr != this) {
211 // We need to fill in the remaining values with the pattern specified.
212 for (FillLayer* pattern = this; curr; curr = curr->next()) {
213 curr->m_repeatY = pattern->m_repeatY;
214 pattern = pattern->next();
215 if (pattern == curr || !pattern)
216 pattern = this;
217 }
218 }
219
220 for (curr = this; curr && curr->isSizeSet(); curr = curr->next()) { }
221 if (curr && curr != this) {
222 // We need to fill in the remaining values with the pattern specified.
223 for (FillLayer* pattern = this; curr; curr = curr->next()) {
224 curr->m_sizeType = pattern->m_sizeType;
225 curr->m_sizeLength = pattern->m_sizeLength;
226 pattern = pattern->next();
227 if (pattern == curr || !pattern)
228 pattern = this;
229 }
230 }
231 }
232
cullEmptyLayers()233 void FillLayer::cullEmptyLayers()
234 {
235 FillLayer* next;
236 for (FillLayer* p = this; p; p = next) {
237 next = p->m_next;
238 if (next && !next->isImageSet()) {
239 delete next;
240 p->m_next = 0;
241 break;
242 }
243 }
244 }
245
containsImage(StyleImage * s) const246 bool FillLayer::containsImage(StyleImage* s) const
247 {
248 if (!s)
249 return false;
250 if (m_image && *s == *m_image)
251 return true;
252 if (m_next)
253 return m_next->containsImage(s);
254 return false;
255 }
256
imagesAreLoaded() const257 bool FillLayer::imagesAreLoaded() const
258 {
259 const FillLayer* curr;
260 for (curr = this; curr; curr = curr->next()) {
261 if (curr->m_image && !curr->m_image->isLoaded())
262 return false;
263 }
264
265 return true;
266 }
267
268 } // namespace WebCore
269