OLD | NEW |
| (Empty) |
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 "core/layout/style/FillLayer.h" | |
24 | |
25 #include "core/layout/style/DataEquivalency.h" | |
26 | |
27 namespace blink { | |
28 | |
29 struct SameSizeAsFillLayer { | |
30 FillLayer* m_next; | |
31 | |
32 RefPtr<StyleImage> m_image; | |
33 | |
34 Length m_xPosition; | |
35 Length m_yPosition; | |
36 | |
37 LengthSize m_sizeLength; | |
38 | |
39 unsigned m_bitfields1; | |
40 unsigned m_bitfields2; | |
41 }; | |
42 | |
43 static_assert(sizeof(FillLayer) == sizeof(SameSizeAsFillLayer), "FillLayer shoul
d stay small"); | |
44 | |
45 FillLayer::FillLayer(EFillLayerType type, bool useInitialValues) | |
46 : m_next(0) | |
47 , m_image(FillLayer::initialFillImage(type)) | |
48 , m_xPosition(FillLayer::initialFillXPosition(type)) | |
49 , m_yPosition(FillLayer::initialFillYPosition(type)) | |
50 , m_sizeLength(FillLayer::initialFillSizeLength(type)) | |
51 , m_attachment(FillLayer::initialFillAttachment(type)) | |
52 , m_clip(FillLayer::initialFillClip(type)) | |
53 , m_origin(FillLayer::initialFillOrigin(type)) | |
54 , m_repeatX(FillLayer::initialFillRepeatX(type)) | |
55 , m_repeatY(FillLayer::initialFillRepeatY(type)) | |
56 , m_composite(FillLayer::initialFillComposite(type)) | |
57 , m_sizeType(useInitialValues ? FillLayer::initialFillSizeType(type) : SizeN
one) | |
58 , m_blendMode(FillLayer::initialFillBlendMode(type)) | |
59 , m_maskSourceType(FillLayer::initialFillMaskSourceType(type)) | |
60 , m_backgroundXOrigin(LeftEdge) | |
61 , m_backgroundYOrigin(TopEdge) | |
62 , m_imageSet(useInitialValues) | |
63 , m_attachmentSet(useInitialValues) | |
64 , m_clipSet(useInitialValues) | |
65 , m_originSet(useInitialValues) | |
66 , m_repeatXSet(useInitialValues) | |
67 , m_repeatYSet(useInitialValues) | |
68 , m_xPosSet(useInitialValues) | |
69 , m_yPosSet(useInitialValues) | |
70 , m_backgroundXOriginSet(false) | |
71 , m_backgroundYOriginSet(false) | |
72 , m_compositeSet(useInitialValues || type == MaskFillLayer) | |
73 , m_blendModeSet(useInitialValues) | |
74 , m_maskSourceTypeSet(useInitialValues) | |
75 , m_type(type) | |
76 { | |
77 } | |
78 | |
79 FillLayer::FillLayer(const FillLayer& o) | |
80 : m_next(o.m_next ? new FillLayer(*o.m_next) : 0) | |
81 , m_image(o.m_image) | |
82 , m_xPosition(o.m_xPosition) | |
83 , m_yPosition(o.m_yPosition) | |
84 , m_sizeLength(o.m_sizeLength) | |
85 , m_attachment(o.m_attachment) | |
86 , m_clip(o.m_clip) | |
87 , m_origin(o.m_origin) | |
88 , m_repeatX(o.m_repeatX) | |
89 , m_repeatY(o.m_repeatY) | |
90 , m_composite(o.m_composite) | |
91 , m_sizeType(o.m_sizeType) | |
92 , m_blendMode(o.m_blendMode) | |
93 , m_maskSourceType(o.m_maskSourceType) | |
94 , m_backgroundXOrigin(o.m_backgroundXOrigin) | |
95 , m_backgroundYOrigin(o.m_backgroundYOrigin) | |
96 , m_imageSet(o.m_imageSet) | |
97 , m_attachmentSet(o.m_attachmentSet) | |
98 , m_clipSet(o.m_clipSet) | |
99 , m_originSet(o.m_originSet) | |
100 , m_repeatXSet(o.m_repeatXSet) | |
101 , m_repeatYSet(o.m_repeatYSet) | |
102 , m_xPosSet(o.m_xPosSet) | |
103 , m_yPosSet(o.m_yPosSet) | |
104 , m_backgroundXOriginSet(o.m_backgroundXOriginSet) | |
105 , m_backgroundYOriginSet(o.m_backgroundYOriginSet) | |
106 , m_compositeSet(o.m_compositeSet) | |
107 , m_blendModeSet(o.m_blendModeSet) | |
108 , m_maskSourceTypeSet(o.m_maskSourceTypeSet) | |
109 , m_type(o.m_type) | |
110 { | |
111 } | |
112 | |
113 FillLayer::~FillLayer() | |
114 { | |
115 delete m_next; | |
116 } | |
117 | |
118 FillLayer& FillLayer::operator=(const FillLayer& o) | |
119 { | |
120 if (m_next != o.m_next) { | |
121 delete m_next; | |
122 m_next = o.m_next ? new FillLayer(*o.m_next) : 0; | |
123 } | |
124 | |
125 m_image = o.m_image; | |
126 m_xPosition = o.m_xPosition; | |
127 m_yPosition = o.m_yPosition; | |
128 m_backgroundXOrigin = o.m_backgroundXOrigin; | |
129 m_backgroundYOrigin = o.m_backgroundYOrigin; | |
130 m_backgroundXOriginSet = o.m_backgroundXOriginSet; | |
131 m_backgroundYOriginSet = o.m_backgroundYOriginSet; | |
132 m_sizeLength = o.m_sizeLength; | |
133 m_attachment = o.m_attachment; | |
134 m_clip = o.m_clip; | |
135 m_composite = o.m_composite; | |
136 m_blendMode = o.m_blendMode; | |
137 m_origin = o.m_origin; | |
138 m_repeatX = o.m_repeatX; | |
139 m_repeatY = o.m_repeatY; | |
140 m_sizeType = o.m_sizeType; | |
141 m_maskSourceType = o.m_maskSourceType; | |
142 | |
143 m_imageSet = o.m_imageSet; | |
144 m_attachmentSet = o.m_attachmentSet; | |
145 m_clipSet = o.m_clipSet; | |
146 m_compositeSet = o.m_compositeSet; | |
147 m_blendModeSet = o.m_blendModeSet; | |
148 m_originSet = o.m_originSet; | |
149 m_repeatXSet = o.m_repeatXSet; | |
150 m_repeatYSet = o.m_repeatYSet; | |
151 m_xPosSet = o.m_xPosSet; | |
152 m_yPosSet = o.m_yPosSet; | |
153 m_maskSourceTypeSet = o.m_maskSourceTypeSet; | |
154 | |
155 m_type = o.m_type; | |
156 | |
157 return *this; | |
158 } | |
159 | |
160 bool FillLayer::operator==(const FillLayer& o) const | |
161 { | |
162 // We do not check the "isSet" booleans for each property, since those are o
nly used during initial construction | |
163 // to propagate patterns into layers. All layer comparisons happen after va
lues have all been filled in anyway. | |
164 return dataEquivalent(m_image, o.m_image) && m_xPosition == o.m_xPosition &&
m_yPosition == o.m_yPosition | |
165 && m_backgroundXOrigin == o.m_backgroundXOrigin && m_backgroundYOrigin =
= o.m_backgroundYOrigin | |
166 && m_attachment == o.m_attachment && m_clip == o.m_clip && m_composite =
= o.m_composite | |
167 && m_blendMode == o.m_blendMode && m_origin == o.m_origin && m_repeatX =
= o.m_repeatX | |
168 && m_repeatY == o.m_repeatY && m_sizeType == o.m_sizeType && m_maskSourc
eType == o.m_maskSourceType | |
169 && m_sizeLength == o.m_sizeLength && m_type == o.m_type | |
170 && ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next); | |
171 } | |
172 | |
173 void FillLayer::fillUnsetProperties() | |
174 { | |
175 FillLayer* curr; | |
176 for (curr = this; curr && curr->isXPositionSet(); 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_xPosition = pattern->m_xPosition; | |
181 if (pattern->isBackgroundXOriginSet()) | |
182 curr->m_backgroundXOrigin = pattern->m_backgroundXOrigin; | |
183 if (pattern->isBackgroundYOriginSet()) | |
184 curr->m_backgroundYOrigin = pattern->m_backgroundYOrigin; | |
185 pattern = pattern->next(); | |
186 if (pattern == curr || !pattern) | |
187 pattern = this; | |
188 } | |
189 } | |
190 | |
191 for (curr = this; curr && curr->isYPositionSet(); curr = curr->next()) { } | |
192 if (curr && curr != this) { | |
193 // We need to fill in the remaining values with the pattern specified. | |
194 for (FillLayer* pattern = this; curr; curr = curr->next()) { | |
195 curr->m_yPosition = pattern->m_yPosition; | |
196 if (pattern->isBackgroundXOriginSet()) | |
197 curr->m_backgroundXOrigin = pattern->m_backgroundXOrigin; | |
198 if (pattern->isBackgroundYOriginSet()) | |
199 curr->m_backgroundYOrigin = pattern->m_backgroundYOrigin; | |
200 pattern = pattern->next(); | |
201 if (pattern == curr || !pattern) | |
202 pattern = this; | |
203 } | |
204 } | |
205 | |
206 for (curr = this; curr && curr->isAttachmentSet(); curr = curr->next()) { } | |
207 if (curr && curr != this) { | |
208 // We need to fill in the remaining values with the pattern specified. | |
209 for (FillLayer* pattern = this; curr; curr = curr->next()) { | |
210 curr->m_attachment = pattern->m_attachment; | |
211 pattern = pattern->next(); | |
212 if (pattern == curr || !pattern) | |
213 pattern = this; | |
214 } | |
215 } | |
216 | |
217 for (curr = this; curr && curr->isClipSet(); curr = curr->next()) { } | |
218 if (curr && curr != this) { | |
219 // We need to fill in the remaining values with the pattern specified. | |
220 for (FillLayer* pattern = this; curr; curr = curr->next()) { | |
221 curr->m_clip = pattern->m_clip; | |
222 pattern = pattern->next(); | |
223 if (pattern == curr || !pattern) | |
224 pattern = this; | |
225 } | |
226 } | |
227 | |
228 for (curr = this; curr && curr->isCompositeSet(); curr = curr->next()) { } | |
229 if (curr && curr != this) { | |
230 // We need to fill in the remaining values with the pattern specified. | |
231 for (FillLayer* pattern = this; curr; curr = curr->next()) { | |
232 curr->m_composite = pattern->m_composite; | |
233 pattern = pattern->next(); | |
234 if (pattern == curr || !pattern) | |
235 pattern = this; | |
236 } | |
237 } | |
238 | |
239 for (curr = this; curr && curr->isBlendModeSet(); curr = curr->next()) { } | |
240 if (curr && curr != this) { | |
241 // We need to fill in the remaining values with the pattern specified. | |
242 for (FillLayer* pattern = this; curr; curr = curr->next()) { | |
243 curr->m_blendMode = pattern->m_blendMode; | |
244 pattern = pattern->next(); | |
245 if (pattern == curr || !pattern) | |
246 pattern = this; | |
247 } | |
248 } | |
249 | |
250 for (curr = this; curr && curr->isOriginSet(); curr = curr->next()) { } | |
251 if (curr && curr != this) { | |
252 // We need to fill in the remaining values with the pattern specified. | |
253 for (FillLayer* pattern = this; curr; curr = curr->next()) { | |
254 curr->m_origin = pattern->m_origin; | |
255 pattern = pattern->next(); | |
256 if (pattern == curr || !pattern) | |
257 pattern = this; | |
258 } | |
259 } | |
260 | |
261 for (curr = this; curr && curr->isRepeatXSet(); curr = curr->next()) { } | |
262 if (curr && curr != this) { | |
263 // We need to fill in the remaining values with the pattern specified. | |
264 for (FillLayer* pattern = this; curr; curr = curr->next()) { | |
265 curr->m_repeatX = pattern->m_repeatX; | |
266 pattern = pattern->next(); | |
267 if (pattern == curr || !pattern) | |
268 pattern = this; | |
269 } | |
270 } | |
271 | |
272 for (curr = this; curr && curr->isRepeatYSet(); curr = curr->next()) { } | |
273 if (curr && curr != this) { | |
274 // We need to fill in the remaining values with the pattern specified. | |
275 for (FillLayer* pattern = this; curr; curr = curr->next()) { | |
276 curr->m_repeatY = pattern->m_repeatY; | |
277 pattern = pattern->next(); | |
278 if (pattern == curr || !pattern) | |
279 pattern = this; | |
280 } | |
281 } | |
282 | |
283 for (curr = this; curr && curr->isSizeSet(); curr = curr->next()) { } | |
284 if (curr && curr != this) { | |
285 // We need to fill in the remaining values with the pattern specified. | |
286 for (FillLayer* pattern = this; curr; curr = curr->next()) { | |
287 curr->m_sizeType = pattern->m_sizeType; | |
288 curr->m_sizeLength = pattern->m_sizeLength; | |
289 pattern = pattern->next(); | |
290 if (pattern == curr || !pattern) | |
291 pattern = this; | |
292 } | |
293 } | |
294 } | |
295 | |
296 void FillLayer::cullEmptyLayers() | |
297 { | |
298 FillLayer* next; | |
299 for (FillLayer* p = this; p; p = next) { | |
300 next = p->m_next; | |
301 if (next && !next->isImageSet()) { | |
302 delete next; | |
303 p->m_next = 0; | |
304 break; | |
305 } | |
306 } | |
307 } | |
308 | |
309 static EFillBox clipMax(EFillBox clipA, EFillBox clipB) | |
310 { | |
311 if (clipA == BorderFillBox || clipB == BorderFillBox) | |
312 return BorderFillBox; | |
313 if (clipA == PaddingFillBox || clipB == PaddingFillBox) | |
314 return PaddingFillBox; | |
315 if (clipA == ContentFillBox || clipB == ContentFillBox) | |
316 return ContentFillBox; | |
317 return TextFillBox; | |
318 } | |
319 | |
320 void FillLayer::computeClipMax() const | |
321 { | |
322 if (m_next) { | |
323 m_next->computeClipMax(); | |
324 m_clipMax = clipMax(clip(), m_next->clip()); | |
325 } else { | |
326 m_clipMax = m_clip; | |
327 } | |
328 } | |
329 | |
330 bool FillLayer::clipOccludesNextLayers(bool firstLayer) const | |
331 { | |
332 if (firstLayer) | |
333 computeClipMax(); | |
334 return m_clip == m_clipMax; | |
335 } | |
336 | |
337 bool FillLayer::containsImage(StyleImage* s) const | |
338 { | |
339 if (!s) | |
340 return false; | |
341 if (m_image && *s == *m_image) | |
342 return true; | |
343 if (m_next) | |
344 return m_next->containsImage(s); | |
345 return false; | |
346 } | |
347 | |
348 bool FillLayer::imagesAreLoaded() const | |
349 { | |
350 const FillLayer* curr; | |
351 for (curr = this; curr; curr = curr->next()) { | |
352 if (curr->m_image && !curr->m_image->isLoaded()) | |
353 return false; | |
354 } | |
355 | |
356 return true; | |
357 } | |
358 | |
359 bool FillLayer::hasOpaqueImage(const LayoutObject* layoutObject) const | |
360 { | |
361 if (!m_image) | |
362 return false; | |
363 | |
364 if (m_composite == CompositeClear || m_composite == CompositeCopy) | |
365 return true; | |
366 | |
367 if (m_blendMode != WebBlendModeNormal) | |
368 return false; | |
369 | |
370 if (m_composite == CompositeSourceOver) | |
371 return m_image->knownToBeOpaque(layoutObject); | |
372 | |
373 return false; | |
374 } | |
375 | |
376 bool FillLayer::hasRepeatXY() const | |
377 { | |
378 return m_repeatX == RepeatFill && m_repeatY == RepeatFill; | |
379 } | |
380 | |
381 } // namespace blink | |
OLD | NEW |