1 /* 2 * Copyright (C) 1999 Antti Koivisto (koivisto (at) 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 27 FillLayer::FillLayer(EFillLayerType type) 28 : m_image(FillLayer::initialFillImage(type)) 29 , m_xPosition(FillLayer::initialFillXPosition(type)) 30 , m_yPosition(FillLayer::initialFillYPosition(type)) 31 , m_attachment(FillLayer::initialFillAttachment(type)) 32 , m_clip(FillLayer::initialFillClip(type)) 33 , m_origin(FillLayer::initialFillOrigin(type)) 34 , m_repeatX(FillLayer::initialFillRepeatX(type)) 35 , m_repeatY(FillLayer::initialFillRepeatY(type)) 36 , m_composite(FillLayer::initialFillComposite(type)) 37 , m_sizeType(SizeNone) 38 , m_sizeLength(FillLayer::initialFillSizeLength(type)) 39 , m_imageSet(false) 40 , m_attachmentSet(false) 41 , m_clipSet(false) 42 , m_originSet(false) 43 , m_repeatXSet(false) 44 , m_repeatYSet(false) 45 , m_xPosSet(false) 46 , m_yPosSet(false) 47 , m_compositeSet(type == MaskFillLayer) 48 , m_type(type) 49 , m_next(0) 50 { 51 } 52 53 FillLayer::FillLayer(const FillLayer& o) 54 : m_image(o.m_image) 55 , m_xPosition(o.m_xPosition) 56 , m_yPosition(o.m_yPosition) 57 , m_attachment(o.m_attachment) 58 , m_clip(o.m_clip) 59 , m_origin(o.m_origin) 60 , m_repeatX(o.m_repeatX) 61 , m_repeatY(o.m_repeatY) 62 , m_composite(o.m_composite) 63 , m_sizeType(o.m_sizeType) 64 , m_sizeLength(o.m_sizeLength) 65 , m_imageSet(o.m_imageSet) 66 , m_attachmentSet(o.m_attachmentSet) 67 , m_clipSet(o.m_clipSet) 68 , m_originSet(o.m_originSet) 69 , m_repeatXSet(o.m_repeatXSet) 70 , m_repeatYSet(o.m_repeatYSet) 71 , m_xPosSet(o.m_xPosSet) 72 , m_yPosSet(o.m_yPosSet) 73 , m_compositeSet(o.m_compositeSet) 74 , m_type(o.m_type) 75 , m_next(o.m_next ? new FillLayer(*o.m_next) : 0) 76 { 77 } 78 79 FillLayer::~FillLayer() 80 { 81 delete m_next; 82 } 83 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 118 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 129 void FillLayer::fillUnsetProperties() 130 { 131 FillLayer* curr; 132 for (curr = this; curr && curr->isImageSet(); 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_image = pattern->m_image; 137 pattern = pattern->next(); 138 if (pattern == curr || !pattern) 139 pattern = this; 140 } 141 } 142 143 for (curr = this; curr && curr->isXPositionSet(); 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_xPosition = pattern->m_xPosition; 148 pattern = pattern->next(); 149 if (pattern == curr || !pattern) 150 pattern = this; 151 } 152 } 153 154 for (curr = this; curr && curr->isYPositionSet(); 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_yPosition = pattern->m_yPosition; 159 pattern = pattern->next(); 160 if (pattern == curr || !pattern) 161 pattern = this; 162 } 163 } 164 165 for (curr = this; curr && curr->isAttachmentSet(); 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_attachment = pattern->m_attachment; 170 pattern = pattern->next(); 171 if (pattern == curr || !pattern) 172 pattern = this; 173 } 174 } 175 176 for (curr = this; curr && curr->isClipSet(); 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_clip = pattern->m_clip; 181 pattern = pattern->next(); 182 if (pattern == curr || !pattern) 183 pattern = this; 184 } 185 } 186 187 for (curr = this; curr && curr->isCompositeSet(); 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_composite = pattern->m_composite; 192 pattern = pattern->next(); 193 if (pattern == curr || !pattern) 194 pattern = this; 195 } 196 } 197 198 for (curr = this; curr && curr->isOriginSet(); 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_origin = pattern->m_origin; 203 pattern = pattern->next(); 204 if (pattern == curr || !pattern) 205 pattern = this; 206 } 207 } 208 209 for (curr = this; curr && curr->isRepeatXSet(); 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_repeatX = pattern->m_repeatX; 214 pattern = pattern->next(); 215 if (pattern == curr || !pattern) 216 pattern = this; 217 } 218 } 219 220 for (curr = this; curr && curr->isRepeatYSet(); 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_repeatY = pattern->m_repeatY; 225 pattern = pattern->next(); 226 if (pattern == curr || !pattern) 227 pattern = this; 228 } 229 } 230 231 for (curr = this; curr && curr->isSizeSet(); curr = curr->next()) { } 232 if (curr && curr != this) { 233 // We need to fill in the remaining values with the pattern specified. 234 for (FillLayer* pattern = this; curr; curr = curr->next()) { 235 curr->m_sizeType = pattern->m_sizeType; 236 curr->m_sizeLength = pattern->m_sizeLength; 237 pattern = pattern->next(); 238 if (pattern == curr || !pattern) 239 pattern = this; 240 } 241 } 242 } 243 244 void FillLayer::cullEmptyLayers() 245 { 246 FillLayer* next; 247 for (FillLayer* p = this; p; p = next) { 248 next = p->m_next; 249 if (next && !next->isImageSet() && 250 !next->isXPositionSet() && !next->isYPositionSet() && 251 !next->isAttachmentSet() && !next->isClipSet() && 252 !next->isCompositeSet() && !next->isOriginSet() && 253 !next->isRepeatXSet() && !next->isRepeatYSet() 254 && !next->isSizeSet()) { 255 delete next; 256 p->m_next = 0; 257 break; 258 } 259 } 260 } 261 262 bool FillLayer::containsImage(StyleImage* s) const 263 { 264 if (!s) 265 return false; 266 if (m_image && *s == *m_image) 267 return true; 268 if (m_next) 269 return m_next->containsImage(s); 270 return false; 271 } 272 273 bool FillLayer::imagesAreLoaded() const 274 { 275 const FillLayer* curr; 276 for (curr = this; curr; curr = curr->next()) { 277 if (curr->m_image && !curr->m_image->isLoaded()) 278 return false; 279 } 280 281 return true; 282 } 283 284 } // namespace WebCore 285