WebCore:
[WebKit-https.git] / WebCore / rendering / RenderStyle.cpp
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 "RenderStyle.h"
24
25 #include "CachedImage.h"
26 #include "CSSStyleSelector.h"
27 #include "RenderArena.h"
28 #include "RenderObject.h"
29
30 namespace WebCore {
31
32 static RenderStyle* defaultStyle;
33
34 static bool imagesEquivalent(StyleImage* image1, StyleImage* image2)
35 {
36     if (image1 != image2) {
37         if (!image1 || !image2)
38             return false;
39         return *image1 == *image2;
40     }
41     return true;
42 }
43
44 bool NinePieceImage::operator==(const NinePieceImage& o) const
45 {
46     return imagesEquivalent(m_image.get(), o.m_image.get()) && m_slices == o.m_slices && m_horizontalRule == o.m_horizontalRule &&
47            m_verticalRule == o.m_verticalRule;
48 }
49
50 StyleSurroundData::StyleSurroundData()
51     : margin(Fixed)
52     , padding(Fixed)
53 {
54 }
55
56 StyleSurroundData::StyleSurroundData(const StyleSurroundData& o)
57     : RefCounted<StyleSurroundData>()
58     , offset(o.offset)
59     , margin(o.margin)
60     , padding(o.padding)
61     , border(o.border)
62 {
63 }
64
65 bool StyleSurroundData::operator==(const StyleSurroundData& o) const
66 {
67     return offset == o.offset && margin == o.margin && padding == o.padding && border == o.border;
68 }
69
70 StyleBoxData::StyleBoxData()
71     : z_index(0)
72     , z_auto(true)
73     , boxSizing(CONTENT_BOX)
74 {
75     // Initialize our min/max widths/heights.
76     min_width = min_height = RenderStyle::initialMinSize();
77     max_width = max_height = RenderStyle::initialMaxSize();
78 }
79
80 StyleBoxData::StyleBoxData(const StyleBoxData& o)
81     : RefCounted<StyleBoxData>()
82     , width(o.width)
83     , height(o.height)
84     , min_width(o.min_width)
85     , max_width(o.max_width)
86     , min_height(o.min_height)
87     , max_height(o.max_height)
88     , z_index(o.z_index)
89     , z_auto(o.z_auto)
90     , boxSizing(o.boxSizing)
91 {
92 }
93
94 bool StyleBoxData::operator==(const StyleBoxData& o) const
95 {
96     return width == o.width &&
97            height == o.height &&
98            min_width == o.min_width &&
99            max_width == o.max_width &&
100            min_height == o.min_height &&
101            max_height == o.max_height &&
102            z_index == o.z_index &&
103            z_auto == o.z_auto &&
104            boxSizing == o.boxSizing;
105 }
106
107 StyleVisualData::StyleVisualData()
108     : hasClip(false)
109     , textDecoration(RenderStyle::initialTextDecoration())
110     , counterIncrement(0)
111     , counterReset(0)
112     , m_zoom(RenderStyle::initialZoom())
113 {
114 }
115
116 StyleVisualData::~StyleVisualData()
117 {
118 }
119
120 StyleVisualData::StyleVisualData(const StyleVisualData& o)
121     : RefCounted<StyleVisualData>()
122     , clip(o.clip)
123     , hasClip(o.hasClip)
124     , textDecoration(o.textDecoration)
125     , counterIncrement(o.counterIncrement)
126     , counterReset(o.counterReset)
127     , m_zoom(RenderStyle::initialZoom())
128 {
129 }
130
131 PassRefPtr<CSSValue> StyleCachedImage::cssValue()
132 {
133     return new CSSPrimitiveValue(m_image->url(), CSSPrimitiveValue::CSS_URI);
134 }
135
136 bool StyleCachedImage::canRender(float multiplier) const
137 {
138     return m_image->canRender(multiplier);
139 }
140
141 bool StyleCachedImage::isLoaded() const
142 {
143     return m_image->isLoaded();
144 }
145
146 bool StyleCachedImage::errorOccurred() const
147 {
148     return m_image->errorOccurred();
149 }
150
151 IntSize StyleCachedImage::imageSize(const RenderObject* /*renderer*/, float multiplier) const
152 {
153     return m_image->imageSize(multiplier);
154 }
155
156 bool StyleCachedImage::imageHasRelativeWidth() const
157 {
158     return m_image->imageHasRelativeWidth();
159 }
160
161 bool StyleCachedImage::imageHasRelativeHeight() const
162 {
163     return m_image->imageHasRelativeHeight();
164 }
165
166 bool StyleCachedImage::usesImageContainerSize() const
167 {
168     return m_image->usesImageContainerSize();
169 }
170
171 void StyleCachedImage::setImageContainerSize(const IntSize& size)
172 {
173     return m_image->setImageContainerSize(size);
174 }
175
176 void StyleCachedImage::addClient(RenderObject* renderer)
177 {
178     return m_image->addClient(renderer);
179 }
180
181 void StyleCachedImage::removeClient(RenderObject* renderer)
182 {
183     return m_image->removeClient(renderer);
184 }
185
186 Image* StyleCachedImage::image(RenderObject* renderer, const IntSize&) const
187 {
188     return m_image->image();
189 }
190
191 PassRefPtr<CSSValue> StyleGeneratedImage::cssValue()
192 {
193     return m_generator;
194 }
195
196 IntSize StyleGeneratedImage::imageSize(const RenderObject* renderer, float /* multiplier */) const
197 {
198     // We can ignore the multiplier, since we always store a raw zoomed size.
199     if (m_fixedSize)
200         return m_generator->fixedSize(renderer);
201     return m_containerSize;
202 }
203
204 void StyleGeneratedImage::setImageContainerSize(const IntSize& size)
205 {
206     m_containerSize = size;
207 }
208
209 void StyleGeneratedImage::addClient(RenderObject* renderer)
210 {
211     m_generator->addClient(renderer, IntSize());
212 }
213
214 void StyleGeneratedImage::removeClient(RenderObject* renderer)
215 {
216     m_generator->removeClient(renderer);
217 }
218
219 Image* StyleGeneratedImage::image(RenderObject* renderer, const IntSize& size) const
220 {
221     return m_generator->image(renderer, size);
222 }
223
224 FillLayer::FillLayer(EFillLayerType type)
225     : m_image(FillLayer::initialFillImage(type))
226     , m_xPosition(FillLayer::initialFillXPosition(type))
227     , m_yPosition(FillLayer::initialFillYPosition(type))
228     , m_attachment(FillLayer::initialFillAttachment(type))
229     , m_clip(FillLayer::initialFillClip(type))
230     , m_origin(FillLayer::initialFillOrigin(type))
231     , m_repeat(FillLayer::initialFillRepeat(type))
232     , m_composite(FillLayer::initialFillComposite(type))
233     , m_size(FillLayer::initialFillSize(type))
234     , m_imageSet(false)
235     , m_attachmentSet(false)
236     , m_clipSet(false)
237     , m_originSet(false)
238     , m_repeatSet(false)
239     , m_xPosSet(false)
240     , m_yPosSet(false)
241     , m_compositeSet(type == MaskFillLayer)
242     , m_sizeSet(false)
243     , m_type(type)
244     , m_next(0)
245 {
246 }
247
248 FillLayer::FillLayer(const FillLayer& o)
249     : m_image(o.m_image)
250     , m_xPosition(o.m_xPosition)
251     , m_yPosition(o.m_yPosition)
252     , m_attachment(o.m_attachment)
253     , m_clip(o.m_clip)
254     , m_origin(o.m_origin)
255     , m_repeat(o.m_repeat)
256     , m_composite(o.m_composite)
257     , m_size(o.m_size)
258     , m_imageSet(o.m_imageSet)
259     , m_attachmentSet(o.m_attachmentSet)
260     , m_clipSet(o.m_clipSet)
261     , m_originSet(o.m_originSet)
262     , m_repeatSet(o.m_repeatSet)
263     , m_xPosSet(o.m_xPosSet)
264     , m_yPosSet(o.m_yPosSet)
265     , m_compositeSet(o.m_compositeSet)
266     , m_sizeSet(o.m_sizeSet)
267     , m_type(o.m_type)
268     , m_next(o.m_next ? new FillLayer(*o.m_next) : 0)
269 {
270 }
271
272 FillLayer::~FillLayer()
273 {
274     delete m_next;
275 }
276
277 FillLayer& FillLayer::operator=(const FillLayer& o)
278 {
279     if (m_next != o.m_next) {
280         delete m_next;
281         m_next = o.m_next ? new FillLayer(*o.m_next) : 0;
282     }
283
284     m_image = o.m_image;
285     m_xPosition = o.m_xPosition;
286     m_yPosition = o.m_yPosition;
287     m_attachment = o.m_attachment;
288     m_clip = o.m_clip;
289     m_composite = o.m_composite;
290     m_origin = o.m_origin;
291     m_repeat = o.m_repeat;
292     m_size = o.m_size;
293
294     m_imageSet = o.m_imageSet;
295     m_attachmentSet = o.m_attachmentSet;
296     m_clipSet = o.m_clipSet;
297     m_compositeSet = o.m_compositeSet;
298     m_originSet = o.m_originSet;
299     m_repeatSet = o.m_repeatSet;
300     m_xPosSet = o.m_xPosSet;
301     m_yPosSet = o.m_yPosSet;
302     m_sizeSet = o.m_sizeSet;
303     
304     m_type = o.m_type;
305
306     return *this;
307 }
308
309 bool FillLayer::operator==(const FillLayer& o) const
310 {
311     // We do not check the "isSet" booleans for each property, since those are only used during initial construction
312     // to propagate patterns into layers.  All layer comparisons happen after values have all been filled in anyway.
313     return imagesEquivalent(m_image.get(), o.m_image.get()) && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition &&
314            m_attachment == o.m_attachment && m_clip == o.m_clip && 
315            m_composite == o.m_composite && m_origin == o.m_origin && m_repeat == o.m_repeat &&
316            m_size.width == o.m_size.width && m_size.height == o.m_size.height && m_type == o.m_type &&
317            ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next);
318 }
319
320 void FillLayer::fillUnsetProperties()
321 {
322     FillLayer* curr;
323     for (curr = this; curr && curr->isImageSet(); curr = curr->next()) { }
324     if (curr && curr != this) {
325         // We need to fill in the remaining values with the pattern specified.
326         for (FillLayer* pattern = this; curr; curr = curr->next()) {
327             curr->m_image = pattern->m_image;
328             pattern = pattern->next();
329             if (pattern == curr || !pattern)
330                 pattern = this;
331         }
332     }
333     
334     for (curr = this; curr && curr->isXPositionSet(); curr = curr->next()) { }
335     if (curr && curr != this) {
336         // We need to fill in the remaining values with the pattern specified.
337         for (FillLayer* pattern = this; curr; curr = curr->next()) {
338             curr->m_xPosition = pattern->m_xPosition;
339             pattern = pattern->next();
340             if (pattern == curr || !pattern)
341                 pattern = this;
342         }
343     }
344     
345     for (curr = this; curr && curr->isYPositionSet(); curr = curr->next()) { }
346     if (curr && curr != this) {
347         // We need to fill in the remaining values with the pattern specified.
348         for (FillLayer* pattern = this; curr; curr = curr->next()) {
349             curr->m_yPosition = pattern->m_yPosition;
350             pattern = pattern->next();
351             if (pattern == curr || !pattern)
352                 pattern = this;
353         }
354     }
355     
356     for (curr = this; curr && curr->isAttachmentSet(); curr = curr->next()) { }
357     if (curr && curr != this) {
358         // We need to fill in the remaining values with the pattern specified.
359         for (FillLayer* pattern = this; curr; curr = curr->next()) {
360             curr->m_attachment = pattern->m_attachment;
361             pattern = pattern->next();
362             if (pattern == curr || !pattern)
363                 pattern = this;
364         }
365     }
366     
367     for (curr = this; curr && curr->isClipSet(); curr = curr->next()) { }
368     if (curr && curr != this) {
369         // We need to fill in the remaining values with the pattern specified.
370         for (FillLayer* pattern = this; curr; curr = curr->next()) {
371             curr->m_clip = pattern->m_clip;
372             pattern = pattern->next();
373             if (pattern == curr || !pattern)
374                 pattern = this;
375         }
376     }
377
378     for (curr = this; curr && curr->isCompositeSet(); curr = curr->next()) { }
379     if (curr && curr != this) {
380         // We need to fill in the remaining values with the pattern specified.
381         for (FillLayer* pattern = this; curr; curr = curr->next()) {
382             curr->m_composite = pattern->m_composite;
383             pattern = pattern->next();
384             if (pattern == curr || !pattern)
385                 pattern = this;
386         }
387     }
388
389     for (curr = this; curr && curr->isOriginSet(); curr = curr->next()) { }
390     if (curr && curr != this) {
391         // We need to fill in the remaining values with the pattern specified.
392         for (FillLayer* pattern = this; curr; curr = curr->next()) {
393             curr->m_origin = pattern->m_origin;
394             pattern = pattern->next();
395             if (pattern == curr || !pattern)
396                 pattern = this;
397         }
398     }
399
400     for (curr = this; curr && curr->isRepeatSet(); curr = curr->next()) { }
401     if (curr && curr != this) {
402         // We need to fill in the remaining values with the pattern specified.
403         for (FillLayer* pattern = this; curr; curr = curr->next()) {
404             curr->m_repeat = pattern->m_repeat;
405             pattern = pattern->next();
406             if (pattern == curr || !pattern)
407                 pattern = this;
408         }
409     }
410     
411     for (curr = this; curr && curr->isSizeSet(); curr = curr->next()) { }
412     if (curr && curr != this) {
413         // We need to fill in the remaining values with the pattern specified.
414         for (FillLayer* pattern = this; curr; curr = curr->next()) {
415             curr->m_size = pattern->m_size;
416             pattern = pattern->next();
417             if (pattern == curr || !pattern)
418                 pattern = this;
419         }
420     }
421 }
422
423 void FillLayer::cullEmptyLayers()
424 {
425     FillLayer *next;
426     for (FillLayer *p = this; p; p = next) {
427         next = p->m_next;
428         if (next && !next->isImageSet() &&
429             !next->isXPositionSet() && !next->isYPositionSet() &&
430             !next->isAttachmentSet() && !next->isClipSet() &&
431             !next->isCompositeSet() && !next->isOriginSet() &&
432             !next->isRepeatSet() && !next->isSizeSet()) {
433             delete next;
434             p->m_next = 0;
435             break;
436         }
437     }
438 }
439
440 StyleBackgroundData::StyleBackgroundData()
441 : m_background(BackgroundFillLayer)
442 {
443 }
444
445 StyleBackgroundData::StyleBackgroundData(const StyleBackgroundData& o)
446     : RefCounted<StyleBackgroundData>()
447     , m_background(o.m_background)
448     , m_color(o.m_color)
449     , m_outline(o.m_outline)
450 {
451 }
452
453 bool StyleBackgroundData::operator==(const StyleBackgroundData& o) const
454 {
455     return m_background == o.m_background && m_color == o.m_color && m_outline == o.m_outline;
456 }
457
458 StyleMarqueeData::StyleMarqueeData()
459     : increment(RenderStyle::initialMarqueeIncrement())
460     , speed(RenderStyle::initialMarqueeSpeed())
461     , loops(RenderStyle::initialMarqueeLoopCount())
462     , behavior(RenderStyle::initialMarqueeBehavior())
463     , direction(RenderStyle::initialMarqueeDirection())
464 {
465 }
466
467 StyleMarqueeData::StyleMarqueeData(const StyleMarqueeData& o)
468     : RefCounted<StyleMarqueeData>()
469     , increment(o.increment)
470     , speed(o.speed)
471     , loops(o.loops)
472     , behavior(o.behavior)
473     , direction(o.direction) 
474 {
475 }
476
477 bool StyleMarqueeData::operator==(const StyleMarqueeData& o) const
478 {
479     return increment == o.increment && speed == o.speed && direction == o.direction &&
480            behavior == o.behavior && loops == o.loops;
481 }
482
483 StyleFlexibleBoxData::StyleFlexibleBoxData()
484     : flex(RenderStyle::initialBoxFlex())
485     , flex_group(RenderStyle::initialBoxFlexGroup())
486     , ordinal_group(RenderStyle::initialBoxOrdinalGroup())
487     , align(RenderStyle::initialBoxAlign())
488     , pack(RenderStyle::initialBoxPack())
489     , orient(RenderStyle::initialBoxOrient())
490     , lines(RenderStyle::initialBoxLines())
491 {
492 }
493
494 StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& o)
495     : RefCounted<StyleFlexibleBoxData>()
496     , flex(o.flex)
497     , flex_group(o.flex_group)
498     , ordinal_group(o.ordinal_group)
499     , align(o.align)
500     , pack(o.pack)
501     , orient(o.orient)
502     , lines(o.lines)
503 {
504 }
505
506 bool StyleFlexibleBoxData::operator==(const StyleFlexibleBoxData& o) const
507 {
508     return flex == o.flex && flex_group == o.flex_group &&
509            ordinal_group == o.ordinal_group && align == o.align &&
510            pack == o.pack && orient == o.orient && lines == o.lines;
511 }
512
513 StyleMultiColData::StyleMultiColData()
514     : m_width(0)
515     , m_count(RenderStyle::initialColumnCount())
516     , m_gap(0)
517     , m_autoWidth(true)
518     , m_autoCount(true)
519     , m_normalGap(true)
520     , m_breakBefore(RenderStyle::initialPageBreak())
521     , m_breakAfter(RenderStyle::initialPageBreak())
522     , m_breakInside(RenderStyle::initialPageBreak())
523 {
524 }
525
526 StyleMultiColData::StyleMultiColData(const StyleMultiColData& o)
527     : RefCounted<StyleMultiColData>()
528     , m_width(o.m_width)
529     , m_count(o.m_count)
530     , m_gap(o.m_gap)
531     , m_rule(o.m_rule)
532     , m_autoWidth(o.m_autoWidth)
533     , m_autoCount(o.m_autoCount)
534     , m_normalGap(o.m_normalGap)
535     , m_breakBefore(o.m_breakBefore)
536     , m_breakAfter(o.m_breakAfter)
537     , m_breakInside(o.m_breakInside)
538 {
539 }
540
541 bool StyleMultiColData::operator==(const StyleMultiColData& o) const
542 {
543     return m_width == o.m_width && m_count == o.m_count && m_gap == o.m_gap &&
544            m_rule == o.m_rule && m_breakBefore == o.m_breakBefore && 
545            m_autoWidth == o.m_autoWidth && m_autoCount == o.m_autoCount && m_normalGap == o.m_normalGap &&
546            m_breakAfter == o.m_breakAfter && m_breakInside == o.m_breakInside;
547 }
548
549 StyleTransformData::StyleTransformData()
550     : m_operations(RenderStyle::initialTransform())
551     , m_x(RenderStyle::initialTransformOriginX())
552     , m_y(RenderStyle::initialTransformOriginY())
553 {
554 }
555
556 StyleTransformData::StyleTransformData(const StyleTransformData& o)
557     : RefCounted<StyleTransformData>()
558     , m_operations(o.m_operations)
559     , m_x(o.m_x)
560     , m_y(o.m_y)
561 {
562 }
563
564 bool StyleTransformData::operator==(const StyleTransformData& o) const
565 {
566     return m_x == o.m_x && m_y == o.m_y && m_operations == o.m_operations;
567 }
568
569 bool TransformOperations::operator==(const TransformOperations& o) const
570 {
571     if (m_operations.size() != o.m_operations.size())
572         return false;
573         
574     unsigned s = m_operations.size();
575     for (unsigned i = 0; i < s; i++) {
576         if (*m_operations[i] != *o.m_operations[i])
577             return false;
578     }
579     
580     return true;
581 }
582
583 TransformOperation* ScaleTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
584 {
585     if (from && !from->isScaleOperation())
586         return this;
587     
588     if (blendToIdentity)
589         return new ScaleTransformOperation(m_x + (1. - m_x) * progress, m_y + (1. - m_y) * progress);
590     
591     const ScaleTransformOperation* fromOp = static_cast<const ScaleTransformOperation*>(from);
592     double fromX = fromOp ? fromOp->m_x : 1.;
593     double fromY = fromOp ? fromOp->m_y : 1.;
594     return new ScaleTransformOperation(fromX + (m_x - fromX) * progress, fromY + (m_y - fromY) * progress);
595 }
596
597 TransformOperation* RotateTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
598 {
599     if (from && !from->isRotateOperation())
600         return this;
601     
602     if (blendToIdentity)
603         return new RotateTransformOperation(m_angle - m_angle * progress);
604     
605     const RotateTransformOperation* fromOp = static_cast<const RotateTransformOperation*>(from);
606     double fromAngle = fromOp ? fromOp->m_angle : 0;
607     return new RotateTransformOperation(fromAngle + (m_angle - fromAngle) * progress);
608 }
609
610 TransformOperation* SkewTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
611 {
612     if (from && !from->isSkewOperation())
613         return this;
614     
615     if (blendToIdentity)
616         return new SkewTransformOperation(m_angleX - m_angleX * progress, m_angleY - m_angleY * progress);
617     
618     const SkewTransformOperation* fromOp = static_cast<const SkewTransformOperation*>(from);
619     double fromAngleX = fromOp ? fromOp->m_angleX : 0;
620     double fromAngleY = fromOp ? fromOp->m_angleY : 0;
621     return new SkewTransformOperation(fromAngleX + (m_angleX - fromAngleX) * progress, fromAngleY + (m_angleY - fromAngleY) * progress);
622 }
623
624 TransformOperation* TranslateTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
625 {
626     if (from && !from->isTranslateOperation())
627         return this;
628     
629     if (blendToIdentity)
630         return new TranslateTransformOperation(Length(0, m_x.type()).blend(m_x, progress), Length(0, m_y.type()).blend(m_y, progress));
631
632     const TranslateTransformOperation* fromOp = static_cast<const TranslateTransformOperation*>(from);
633     Length fromX = fromOp ? fromOp->m_x : Length(0, m_x.type());
634     Length fromY = fromOp ? fromOp->m_y : Length(0, m_y.type());
635     return new TranslateTransformOperation(m_x.blend(fromX, progress), m_y.blend(fromY, progress));
636 }
637
638 TransformOperation* MatrixTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
639 {
640     if (from && !from->isMatrixOperation())
641         return this;
642     
643     if (blendToIdentity)
644         return new MatrixTransformOperation(m_a * (1. - progress) + progress,
645                                             m_b * (1. - progress),
646                                             m_c * (1. - progress),
647                                             m_d * (1. - progress) + progress,
648                                             m_e * (1. - progress),
649                                             m_f * (1. - progress));
650
651     const MatrixTransformOperation* fromOp = static_cast<const MatrixTransformOperation*>(from);
652     double fromA = fromOp ? fromOp->m_a : 1.;
653     double fromB = fromOp ? fromOp->m_b : 0;
654     double fromC = fromOp ? fromOp->m_c : 0;
655     double fromD = fromOp ? fromOp->m_d : 1.;
656     double fromE = fromOp ? fromOp->m_e : 0;
657     double fromF = fromOp ? fromOp->m_f : 0;
658     
659     return new MatrixTransformOperation(fromA + (m_a - fromA) * progress,
660                                         fromB + (m_b - fromB) * progress,
661                                         fromC + (m_c - fromC) * progress,
662                                         fromD + (m_d - fromD) * progress,
663                                         fromE + (m_e - fromE) * progress,
664                                         fromF + (m_f - fromF) * progress);
665 }
666
667 Transition::Transition()
668     : m_duration(RenderStyle::initialTransitionDuration())
669     , m_repeatCount(RenderStyle::initialTransitionRepeatCount())
670     , m_timingFunction(RenderStyle::initialTransitionTimingFunction())
671     , m_property(RenderStyle::initialTransitionProperty())
672     , m_durationSet(false)
673     , m_repeatCountSet(false)
674     , m_timingFunctionSet(false)
675     , m_propertySet(false)
676     , m_next(0)
677 {
678 }
679
680 Transition::Transition(const Transition& o)
681     : m_duration(o.m_duration)
682     , m_repeatCount(o.m_repeatCount)
683     , m_timingFunction(o.m_timingFunction)
684     , m_property(o.m_property)
685     , m_durationSet(o.m_durationSet)
686     , m_repeatCountSet(o.m_repeatCountSet)
687     , m_timingFunctionSet(o.m_timingFunctionSet)
688     , m_propertySet(o.m_propertySet)
689     , m_next(o.m_next ? new Transition(*o.m_next) : 0)
690 {
691 }
692
693 Transition::~Transition()
694 {
695     delete m_next;
696 }
697
698 Transition& Transition::operator=(const Transition& o)
699 {
700     if (m_next != o.m_next) {
701         delete m_next;
702         m_next = o.m_next ? new Transition(*o.m_next) : 0;
703     }
704
705     m_duration = o.m_duration;
706     m_repeatCount = o.m_repeatCount;
707     m_timingFunction = o.m_timingFunction;
708     m_property = o.m_property;
709
710     m_durationSet = o.m_durationSet;
711     m_repeatCountSet = o.m_repeatCountSet;
712     m_timingFunctionSet = o.m_timingFunctionSet;
713     m_propertySet = o.m_propertySet;
714
715     return *this;
716 }
717
718 bool Transition::operator==(const Transition& o) const
719 {
720     return m_duration == o.m_duration && m_repeatCount == o.m_repeatCount && m_timingFunction == o.m_timingFunction &&
721            m_property == o.m_property && m_durationSet == o.m_durationSet && m_repeatCountSet == o.m_repeatCountSet &&
722            m_timingFunctionSet == o.m_timingFunctionSet && m_propertySet == o.m_propertySet &&
723            ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next);
724 }
725
726 void Transition::fillUnsetProperties()
727 {
728     Transition* curr;
729     for (curr = this; curr && curr->isDurationSet(); curr = curr->next()) { }
730     if (curr && curr != this) {
731         // We need to fill in the remaining values with the pattern specified.
732         for (Transition* pattern = this; curr; curr = curr->next()) {
733             curr->m_duration = pattern->m_duration;
734             pattern = pattern->next();
735             if (pattern == curr || !pattern)
736                 pattern = this;
737         }
738     }
739     
740     for (curr = this; curr && curr->isRepeatCountSet(); curr = curr->next()) { }
741     if (curr && curr != this) {
742         // We need to fill in the remaining values with the pattern specified.
743         for (Transition* pattern = this; curr; curr = curr->next()) {
744             curr->m_repeatCount = pattern->m_repeatCount;
745             pattern = pattern->next();
746             if (pattern == curr || !pattern)
747                 pattern = this;
748         }
749     }
750     
751     for (curr = this; curr && curr->isTimingFunctionSet(); curr = curr->next()) { }
752     if (curr && curr != this) {
753         // We need to fill in the remaining values with the pattern specified.
754         for (Transition* pattern = this; curr; curr = curr->next()) {
755             curr->m_timingFunction = pattern->m_timingFunction;
756             pattern = pattern->next();
757             if (pattern == curr || !pattern)
758                 pattern = this;
759         }
760     }
761
762     for (curr = this; curr && curr->isPropertySet(); curr = curr->next()) { }
763     if (curr && curr != this) {
764         // We need to fill in the remaining values with the pattern specified.
765         for (Transition* pattern = this; curr; curr = curr->next()) {
766             curr->m_property = pattern->m_property;
767             pattern = pattern->next();
768             if (pattern == curr || !pattern)
769                 pattern = this;
770         }
771     }
772 }
773
774 StyleRareNonInheritedData::StyleRareNonInheritedData()
775     : lineClamp(RenderStyle::initialLineClamp())
776     , opacity(RenderStyle::initialOpacity())
777     , m_content(0)
778     , m_counterDirectives(0)
779     , userDrag(RenderStyle::initialUserDrag())
780     , textOverflow(RenderStyle::initialTextOverflow())
781     , marginTopCollapse(MCOLLAPSE)
782     , marginBottomCollapse(MCOLLAPSE)
783     , matchNearestMailBlockquoteColor(RenderStyle::initialMatchNearestMailBlockquoteColor())
784     , m_appearance(RenderStyle::initialAppearance())
785     , m_borderFit(RenderStyle::initialBorderFit())
786     , m_boxShadow(0)
787     , m_transition(0)
788     , m_mask(FillLayer(MaskFillLayer))
789 #if ENABLE(XBL)
790     , bindingURI(0)
791 #endif
792 {
793 }
794
795 StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInheritedData& o)
796     : RefCounted<StyleRareNonInheritedData>()
797     , lineClamp(o.lineClamp)
798     , opacity(o.opacity)
799     , flexibleBox(o.flexibleBox)
800     , marquee(o.marquee)
801     , m_multiCol(o.m_multiCol)
802     , m_transform(o.m_transform)
803     , m_content(0)
804     , m_counterDirectives(0)
805     , userDrag(o.userDrag)
806     , textOverflow(o.textOverflow)
807     , marginTopCollapse(o.marginTopCollapse)
808     , marginBottomCollapse(o.marginBottomCollapse)
809     , matchNearestMailBlockquoteColor(o.matchNearestMailBlockquoteColor)
810     , m_appearance(o.m_appearance)
811     , m_borderFit(o.m_borderFit)
812     , m_boxShadow(o.m_boxShadow ? new ShadowData(*o.m_boxShadow) : 0)
813     , m_boxReflect(o.m_boxReflect)
814     , m_transition(o.m_transition ? new Transition(*o.m_transition) : 0)
815     , m_mask(o.m_mask)
816 #if ENABLE(XBL)
817     , bindingURI(o.bindingURI ? o.bindingURI->copy() : 0)
818 #endif
819 {
820 }
821
822 StyleRareNonInheritedData::~StyleRareNonInheritedData()
823 {
824     delete m_content;
825     delete m_counterDirectives;
826     delete m_boxShadow;
827     delete m_transition;
828 #if ENABLE(XBL)
829     delete bindingURI;
830 #endif
831 }
832
833 #if ENABLE(XBL)
834 bool StyleRareNonInheritedData::bindingsEquivalent(const StyleRareNonInheritedData& o) const
835 {
836     if (this == &o) return true;
837     if (!bindingURI && o.bindingURI || bindingURI && !o.bindingURI)
838         return false;
839     if (bindingURI && o.bindingURI && (*bindingURI != *o.bindingURI))
840         return false;
841     return true;
842 }
843 #endif
844
845 bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) const
846 {
847     return lineClamp == o.lineClamp
848         && m_dashboardRegions == o.m_dashboardRegions
849         && opacity == o.opacity
850         && flexibleBox == o.flexibleBox
851         && marquee == o.marquee
852         && m_multiCol == o.m_multiCol
853         && m_transform == o.m_transform
854         && m_content == o.m_content
855         && m_counterDirectives == o.m_counterDirectives
856         && userDrag == o.userDrag
857         && textOverflow == o.textOverflow
858         && marginTopCollapse == o.marginTopCollapse
859         && marginBottomCollapse == o.marginBottomCollapse
860         && matchNearestMailBlockquoteColor == o.matchNearestMailBlockquoteColor
861         && m_appearance == o.m_appearance
862         && m_borderFit == o.m_borderFit
863         && shadowDataEquivalent(o)
864         && reflectionDataEquivalent(o)
865         && transitionDataEquivalent(o)
866         && m_mask == o.m_mask
867 #if ENABLE(XBL)
868         && bindingsEquivalent(o)
869 #endif
870         ;
871 }
872
873 bool StyleRareNonInheritedData::shadowDataEquivalent(const StyleRareNonInheritedData& o) const
874 {
875     if (!m_boxShadow && o.m_boxShadow || m_boxShadow && !o.m_boxShadow)
876         return false;
877     if (m_boxShadow && o.m_boxShadow && (*m_boxShadow != *o.m_boxShadow))
878         return false;
879     return true;
880 }
881
882 bool StyleRareNonInheritedData::reflectionDataEquivalent(const StyleRareNonInheritedData& o) const
883 {
884     if (m_boxReflect != o.m_boxReflect) {
885         if (!m_boxReflect || !o.m_boxReflect)
886             return false;
887         return *m_boxReflect == *o.m_boxReflect;
888     }
889     return true;
890
891 }
892
893 bool StyleRareNonInheritedData::transitionDataEquivalent(const StyleRareNonInheritedData& o) const
894 {
895     if (!m_transition && o.m_transition || m_transition && !o.m_transition)
896         return false;
897     if (m_transition && o.m_transition && (*m_transition != *o.m_transition))
898         return false;
899     return true;
900 }
901
902 StyleRareInheritedData::StyleRareInheritedData()
903     : textStrokeWidth(RenderStyle::initialTextStrokeWidth())
904     , textShadow(0)
905     , textSecurity(RenderStyle::initialTextSecurity())
906     , userModify(READ_ONLY)
907     , wordBreak(RenderStyle::initialWordBreak())
908     , wordWrap(RenderStyle::initialWordWrap())
909     , nbspMode(NBNORMAL)
910     , khtmlLineBreak(LBNORMAL)
911     , textSizeAdjust(RenderStyle::initialTextSizeAdjust())
912     , resize(RenderStyle::initialResize())
913     , userSelect(RenderStyle::initialUserSelect())
914 {
915 }
916
917 StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
918     : RefCounted<StyleRareInheritedData>()
919     , textStrokeColor(o.textStrokeColor)
920     , textStrokeWidth(o.textStrokeWidth)
921     , textFillColor(o.textFillColor)
922     , textShadow(o.textShadow ? new ShadowData(*o.textShadow) : 0)
923     , highlight(o.highlight)
924     , textSecurity(o.textSecurity)
925     , userModify(o.userModify)
926     , wordBreak(o.wordBreak)
927     , wordWrap(o.wordWrap)
928     , nbspMode(o.nbspMode)
929     , khtmlLineBreak(o.khtmlLineBreak)
930     , textSizeAdjust(o.textSizeAdjust)
931     , resize(o.resize)
932     , userSelect(o.userSelect)
933 {
934 }
935
936 StyleRareInheritedData::~StyleRareInheritedData()
937 {
938     delete textShadow;
939 }
940
941 bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
942 {
943     return textStrokeColor == o.textStrokeColor
944         && textStrokeWidth == o.textStrokeWidth
945         && textFillColor == o.textFillColor
946         && shadowDataEquivalent(o)
947         && highlight == o.highlight
948         && textSecurity == o.textSecurity
949         && userModify == o.userModify
950         && wordBreak == o.wordBreak
951         && wordWrap == o.wordWrap
952         && nbspMode == o.nbspMode
953         && khtmlLineBreak == o.khtmlLineBreak
954         && textSizeAdjust == o.textSizeAdjust
955         && userSelect == o.userSelect;
956 }
957
958 bool StyleRareInheritedData::shadowDataEquivalent(const StyleRareInheritedData& o) const
959 {
960     if (!textShadow && o.textShadow || textShadow && !o.textShadow)
961         return false;
962     if (textShadow && o.textShadow && (*textShadow != *o.textShadow))
963         return false;
964     return true;
965 }
966
967 StyleInheritedData::StyleInheritedData()
968     : indent(RenderStyle::initialTextIndent())
969     , line_height(RenderStyle::initialLineHeight())
970     , list_style_image(RenderStyle::initialListStyleImage())
971     , color(RenderStyle::initialColor())
972     , m_effectiveZoom(RenderStyle::initialZoom())
973     , horizontal_border_spacing(RenderStyle::initialHorizontalBorderSpacing())
974     , vertical_border_spacing(RenderStyle::initialVerticalBorderSpacing())
975     , widows(RenderStyle::initialWidows())
976     , orphans(RenderStyle::initialOrphans())
977     , page_break_inside(RenderStyle::initialPageBreak())
978 {
979 }
980
981 StyleInheritedData::~StyleInheritedData()
982 {
983 }
984
985 StyleInheritedData::StyleInheritedData(const StyleInheritedData& o)
986     : RefCounted<StyleInheritedData>()
987     , indent(o.indent)
988     , line_height(o.line_height)
989     , list_style_image(o.list_style_image)
990     , cursorData(o.cursorData)
991     , font(o.font)
992     , color(o.color)
993     , m_effectiveZoom(o.m_effectiveZoom)
994     , horizontal_border_spacing(o.horizontal_border_spacing)
995     , vertical_border_spacing(o.vertical_border_spacing)
996     , widows(o.widows)
997     , orphans(o.orphans)
998     , page_break_inside(o.page_break_inside)
999 {
1000 }
1001
1002 static bool cursorDataEquivalent(const CursorList* c1, const CursorList* c2)
1003 {
1004     if (c1 == c2)
1005         return true;
1006     if (!c1 && c2 || c1 && !c2)
1007         return false;
1008     return (*c1 == *c2);
1009 }
1010
1011 bool StyleInheritedData::operator==(const StyleInheritedData& o) const
1012 {
1013     return
1014         indent == o.indent &&
1015         line_height == o.line_height &&
1016         imagesEquivalent(list_style_image.get(), o.list_style_image.get()) &&
1017         cursorDataEquivalent(cursorData.get(), o.cursorData.get()) &&
1018         font == o.font &&
1019         color == o.color &&
1020         m_effectiveZoom == o.m_effectiveZoom &&
1021         horizontal_border_spacing == o.horizontal_border_spacing &&
1022         vertical_border_spacing == o.vertical_border_spacing &&
1023         widows == o.widows &&
1024         orphans == o.orphans &&
1025         page_break_inside == o.page_break_inside;
1026 }
1027
1028 static inline bool operator!=(const CounterContent& a, const CounterContent& b)
1029 {
1030     return a.identifier() != b.identifier()
1031         || a.listStyle() != b.listStyle()
1032         || a.separator() != b.separator();
1033 }
1034
1035 // ----------------------------------------------------------
1036
1037 void* RenderStyle::operator new(size_t sz, RenderArena* renderArena) throw()
1038 {
1039     return renderArena->allocate(sz);
1040 }
1041
1042 void RenderStyle::operator delete(void* ptr, size_t sz)
1043 {
1044     // Stash size where destroy can find it.
1045     *(size_t *)ptr = sz;
1046 }
1047
1048 void RenderStyle::arenaDelete(RenderArena *arena)
1049 {
1050     RenderStyle *ps = pseudoStyle;
1051     RenderStyle *prev = 0;
1052     
1053     while (ps) {
1054         prev = ps;
1055         ps = ps->pseudoStyle;
1056         // to prevent a double deletion.
1057         // this works only because the styles below aren't really shared
1058         // Dirk said we need another construct as soon as these are shared
1059         prev->pseudoStyle = 0;
1060         prev->deref(arena);
1061     }
1062     delete this;
1063     
1064     // Recover the size left there for us by operator delete and free the memory.
1065     arena->free(*(size_t *)this, this);
1066 }
1067
1068 inline RenderStyle *initDefaultStyle()
1069 {
1070     if (!defaultStyle)
1071         defaultStyle = ::new RenderStyle(true);
1072     return defaultStyle;
1073 }
1074
1075 RenderStyle::RenderStyle()
1076     : box(initDefaultStyle()->box)
1077     , visual(defaultStyle->visual)
1078     , background(defaultStyle->background)
1079     , surround(defaultStyle->surround)
1080     , rareNonInheritedData(defaultStyle->rareNonInheritedData)
1081     , rareInheritedData(defaultStyle->rareInheritedData)
1082     , inherited(defaultStyle->inherited)
1083     , pseudoStyle(0)
1084     , m_pseudoState(PseudoUnknown)
1085     , m_affectedByAttributeSelectors(false)
1086     , m_unique(false)
1087     , m_affectedByEmpty(false)
1088     , m_emptyState(false)
1089     , m_childrenAffectedByFirstChildRules(false)
1090     , m_childrenAffectedByLastChildRules(false)
1091     , m_childrenAffectedByDirectAdjacentRules(false)
1092     , m_childrenAffectedByForwardPositionalRules(false)
1093     , m_childrenAffectedByBackwardPositionalRules(false)
1094     , m_firstChildState(false)
1095     , m_lastChildState(false)
1096     , m_childIndex(0)
1097     , m_ref(0)
1098 #if ENABLE(SVG)
1099     , m_svgStyle(defaultStyle->m_svgStyle)
1100 #endif
1101 {
1102     setBitDefaults(); // Would it be faster to copy this from the default style?
1103 }
1104
1105 RenderStyle::RenderStyle(bool)
1106     : pseudoStyle(0)
1107     , m_pseudoState(PseudoUnknown)
1108     , m_affectedByAttributeSelectors(false)
1109     , m_unique(false)
1110     , m_affectedByEmpty(false)
1111     , m_emptyState(false)
1112     , m_childrenAffectedByFirstChildRules(false)
1113     , m_childrenAffectedByLastChildRules(false)
1114     , m_childrenAffectedByDirectAdjacentRules(false)
1115     , m_childrenAffectedByForwardPositionalRules(false)
1116     , m_childrenAffectedByBackwardPositionalRules(false)
1117     , m_firstChildState(false)
1118     , m_lastChildState(false)
1119     , m_childIndex(0)
1120     , m_ref(1)
1121 {
1122     setBitDefaults();
1123
1124     box.init();
1125     visual.init();
1126     background.init();
1127     surround.init();
1128     rareNonInheritedData.init();
1129     rareNonInheritedData.access()->flexibleBox.init();
1130     rareNonInheritedData.access()->marquee.init();
1131     rareNonInheritedData.access()->m_multiCol.init();
1132     rareNonInheritedData.access()->m_transform.init();
1133     rareInheritedData.init();
1134     inherited.init();
1135     
1136 #if ENABLE(SVG)
1137     m_svgStyle.init();
1138 #endif
1139 }
1140
1141 RenderStyle::RenderStyle(const RenderStyle& o)
1142     : inherited_flags(o.inherited_flags)
1143     , noninherited_flags(o.noninherited_flags)
1144     , box(o.box)
1145     , visual(o.visual)
1146     , background(o.background)
1147     , surround(o.surround)
1148     , rareNonInheritedData(o.rareNonInheritedData)
1149     , rareInheritedData(o.rareInheritedData)
1150     , inherited(o.inherited)
1151     , pseudoStyle(0)
1152     , m_pseudoState(o.m_pseudoState)
1153     , m_affectedByAttributeSelectors(false)
1154     , m_unique(false)
1155     , m_affectedByEmpty(false)
1156     , m_emptyState(false)
1157     , m_childrenAffectedByFirstChildRules(false)
1158     , m_childrenAffectedByLastChildRules(false)
1159     , m_childrenAffectedByDirectAdjacentRules(false)
1160     , m_childrenAffectedByForwardPositionalRules(false)
1161     , m_childrenAffectedByBackwardPositionalRules(false)
1162     , m_firstChildState(false)
1163     , m_lastChildState(false)
1164     , m_childIndex(0)
1165     , m_ref(0)
1166 #if ENABLE(SVG)
1167     , m_svgStyle(o.m_svgStyle)
1168 #endif
1169 {
1170 }
1171
1172 void RenderStyle::inheritFrom(const RenderStyle* inheritParent)
1173 {
1174     rareInheritedData = inheritParent->rareInheritedData;
1175     inherited = inheritParent->inherited;
1176     inherited_flags = inheritParent->inherited_flags;
1177 #if ENABLE(SVG)
1178     if (m_svgStyle != inheritParent->m_svgStyle)
1179         m_svgStyle.access()->inheritFrom(inheritParent->m_svgStyle.get());
1180 #endif
1181 }
1182
1183 RenderStyle::~RenderStyle()
1184 {
1185 }
1186
1187 bool RenderStyle::operator==(const RenderStyle& o) const
1188 {
1189     // compare everything except the pseudoStyle pointer
1190     return inherited_flags == o.inherited_flags &&
1191             noninherited_flags == o.noninherited_flags &&
1192             box == o.box &&
1193             visual == o.visual &&
1194             background == o.background &&
1195             surround == o.surround &&
1196             rareNonInheritedData == o.rareNonInheritedData &&
1197             rareInheritedData == o.rareInheritedData &&
1198             inherited == o.inherited
1199 #if ENABLE(SVG)
1200             && m_svgStyle == o.m_svgStyle
1201 #endif
1202             ;
1203 }
1204
1205 bool RenderStyle::isStyleAvailable() const
1206 {
1207     return this != CSSStyleSelector::styleNotYetAvailable();
1208 }
1209
1210 static inline int pseudoBit(RenderStyle::PseudoId pseudo)
1211 {
1212     return 1 << (pseudo - 1);
1213 }
1214
1215 bool RenderStyle::hasPseudoStyle(PseudoId pseudo) const
1216 {
1217     ASSERT(pseudo > NOPSEUDO);
1218     ASSERT(pseudo < FIRST_INTERNAL_PSEUDOID);
1219     return pseudoBit(pseudo) & noninherited_flags._pseudoBits;
1220 }
1221
1222 void RenderStyle::setHasPseudoStyle(PseudoId pseudo)
1223 {
1224     ASSERT(pseudo > NOPSEUDO);
1225     ASSERT(pseudo < FIRST_INTERNAL_PSEUDOID);
1226     noninherited_flags._pseudoBits |= pseudoBit(pseudo);
1227 }
1228
1229 RenderStyle* RenderStyle::getPseudoStyle(PseudoId pid)
1230 {
1231     if (!pseudoStyle || styleType() != NOPSEUDO)
1232         return 0;
1233     RenderStyle* ps = pseudoStyle;
1234     while (ps && ps->styleType() != pid)
1235         ps = ps->pseudoStyle;
1236     return ps;
1237 }
1238
1239 void RenderStyle::addPseudoStyle(RenderStyle* pseudo)
1240 {
1241     if (!pseudo)
1242         return;
1243     pseudo->ref();
1244     pseudo->pseudoStyle = pseudoStyle;
1245     pseudoStyle = pseudo;
1246 }
1247
1248 bool RenderStyle::inheritedNotEqual(RenderStyle* other) const
1249 {
1250     return inherited_flags != other->inherited_flags ||
1251            inherited != other->inherited ||
1252 #if ENABLE(SVG)
1253            m_svgStyle->inheritedNotEqual(other->m_svgStyle.get()) ||
1254 #endif
1255            rareInheritedData != other->rareInheritedData;
1256 }
1257
1258 bool positionedObjectMoved(const LengthBox& a, const LengthBox& b)
1259 {
1260     // If any unit types are different, then we can't guarantee
1261     // that this was just a movement.
1262     if (a.left.type() != b.left.type() ||
1263         a.right.type() != b.right.type() ||
1264         a.top.type() != b.top.type() ||
1265         a.bottom.type() != b.bottom.type())
1266         return false;
1267         
1268     // Only one unit can be non-auto in the horizontal direction and
1269     // in the vertical direction.  Otherwise the adjustment of values
1270     // is changing the size of the box.
1271     if (!a.left.isIntrinsicOrAuto() && !a.right.isIntrinsicOrAuto())
1272         return false;
1273     if (!a.top.isIntrinsicOrAuto() && !a.bottom.isIntrinsicOrAuto())
1274         return false;
1275         
1276     // One of the units is fixed or percent in both directions and stayed
1277     // that way in the new style.  Therefore all we are doing is moving.
1278     return true;
1279 }
1280
1281 /*
1282   compares two styles. The result gives an idea of the action that
1283   needs to be taken when replacing the old style with a new one.
1284
1285   CbLayout: The containing block of the object needs a relayout.
1286   Layout: the RenderObject needs a relayout after the style change
1287   Visible: The change is visible, but no relayout is needed
1288   NonVisible: The object does need neither repaint nor relayout after
1289        the change.
1290
1291   ### TODO:
1292   A lot can be optimised here based on the display type, lots of
1293   optimisations are unimplemented, and currently result in the
1294   worst case result causing a relayout of the containing block.
1295 */
1296 RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
1297 {
1298 #if ENABLE(SVG)
1299     // This is horribly inefficient.  Eventually we'll have to integrate
1300     // this more directly by calling: Diff svgDiff = svgStyle->diff(other)
1301     // and then checking svgDiff and returning from the appropriate places below.
1302     if (m_svgStyle != other->m_svgStyle)
1303         return Layout;
1304 #endif
1305
1306     if (box->width != other->box->width ||
1307         box->min_width != other->box->min_width ||
1308         box->max_width != other->box->max_width ||
1309         box->height != other->box->height ||
1310         box->min_height != other->box->min_height ||
1311         box->max_height != other->box->max_height)
1312         return Layout;
1313     
1314     if (box->vertical_align != other->box->vertical_align || noninherited_flags._vertical_align != other->noninherited_flags._vertical_align)
1315         return Layout;
1316     
1317     if (box->boxSizing != other->box->boxSizing)
1318         return Layout;
1319     
1320     if (surround->margin != other->surround->margin)
1321         return Layout;
1322         
1323     if (surround->padding != other->surround->padding)
1324         return Layout;
1325     
1326     if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
1327         if (rareNonInheritedData->m_appearance != other->rareNonInheritedData->m_appearance ||
1328             rareNonInheritedData->marginTopCollapse != other->rareNonInheritedData->marginTopCollapse ||
1329             rareNonInheritedData->marginBottomCollapse != other->rareNonInheritedData->marginBottomCollapse ||
1330             rareNonInheritedData->lineClamp != other->rareNonInheritedData->lineClamp ||
1331             rareNonInheritedData->textOverflow != other->rareNonInheritedData->textOverflow)
1332             return Layout;
1333         
1334         if (rareNonInheritedData->flexibleBox.get() != other->rareNonInheritedData->flexibleBox.get() &&
1335             *rareNonInheritedData->flexibleBox.get() != *other->rareNonInheritedData->flexibleBox.get())
1336             return Layout;
1337         
1338         if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get()))
1339             return Layout;
1340
1341         if (!rareNonInheritedData->reflectionDataEquivalent(*other->rareNonInheritedData.get()))
1342             return Layout;
1343     
1344         if (rareNonInheritedData->m_multiCol.get() != other->rareNonInheritedData->m_multiCol.get() &&
1345             *rareNonInheritedData->m_multiCol.get() != *other->rareNonInheritedData->m_multiCol.get())
1346             return Layout;
1347         
1348         if (rareNonInheritedData->m_transform.get() != other->rareNonInheritedData->m_transform.get() &&
1349             *rareNonInheritedData->m_transform.get() != *other->rareNonInheritedData->m_transform.get())
1350             return Layout;
1351
1352         // If regions change, trigger a relayout to re-calc regions.
1353         if (rareNonInheritedData->m_dashboardRegions != other->rareNonInheritedData->m_dashboardRegions)
1354             return Layout;
1355     }
1356
1357     if (rareInheritedData.get() != other->rareInheritedData.get()) {
1358         if (rareInheritedData->highlight != other->rareInheritedData->highlight ||
1359             rareInheritedData->textSizeAdjust != other->rareInheritedData->textSizeAdjust ||
1360             rareInheritedData->wordBreak != other->rareInheritedData->wordBreak ||
1361             rareInheritedData->wordWrap != other->rareInheritedData->wordWrap ||
1362             rareInheritedData->nbspMode != other->rareInheritedData->nbspMode ||
1363             rareInheritedData->khtmlLineBreak != other->rareInheritedData->khtmlLineBreak ||
1364             rareInheritedData->textSecurity != other->rareInheritedData->textSecurity)
1365             return Layout;
1366         
1367         if (!rareInheritedData->shadowDataEquivalent(*other->rareInheritedData.get()))
1368             return Layout;
1369             
1370         if (textStrokeWidth() != other->textStrokeWidth())
1371             return Layout;
1372     }
1373
1374     if (inherited->indent != other->inherited->indent ||
1375         inherited->line_height != other->inherited->line_height ||
1376         inherited->list_style_image != other->inherited->list_style_image ||
1377         inherited->font != other->inherited->font ||
1378         inherited->horizontal_border_spacing != other->inherited->horizontal_border_spacing ||
1379         inherited->vertical_border_spacing != other->inherited->vertical_border_spacing ||
1380         inherited_flags._box_direction != other->inherited_flags._box_direction ||
1381         inherited_flags._visuallyOrdered != other->inherited_flags._visuallyOrdered ||
1382         inherited_flags._htmlHacks != other->inherited_flags._htmlHacks ||
1383         noninherited_flags._position != other->noninherited_flags._position ||
1384         noninherited_flags._floating != other->noninherited_flags._floating ||
1385         noninherited_flags._originalDisplay != other->noninherited_flags._originalDisplay)
1386         return Layout;
1387
1388    
1389     if (((int)noninherited_flags._effectiveDisplay) >= TABLE) {
1390         if (inherited_flags._border_collapse != other->inherited_flags._border_collapse ||
1391             inherited_flags._empty_cells != other->inherited_flags._empty_cells ||
1392             inherited_flags._caption_side != other->inherited_flags._caption_side ||
1393             noninherited_flags._table_layout != other->noninherited_flags._table_layout)
1394             return Layout;
1395         
1396         // In the collapsing border model, 'hidden' suppresses other borders, while 'none'
1397         // does not, so these style differences can be width differences.
1398         if (inherited_flags._border_collapse &&
1399             (borderTopStyle() == BHIDDEN && other->borderTopStyle() == BNONE ||
1400              borderTopStyle() == BNONE && other->borderTopStyle() == BHIDDEN ||
1401              borderBottomStyle() == BHIDDEN && other->borderBottomStyle() == BNONE ||
1402              borderBottomStyle() == BNONE && other->borderBottomStyle() == BHIDDEN ||
1403              borderLeftStyle() == BHIDDEN && other->borderLeftStyle() == BNONE ||
1404              borderLeftStyle() == BNONE && other->borderLeftStyle() == BHIDDEN ||
1405              borderRightStyle() == BHIDDEN && other->borderRightStyle() == BNONE ||
1406              borderRightStyle() == BNONE && other->borderRightStyle() == BHIDDEN))
1407             return Layout;
1408     }
1409
1410     if (noninherited_flags._effectiveDisplay == LIST_ITEM) {
1411         if (inherited_flags._list_style_type != other->inherited_flags._list_style_type ||
1412             inherited_flags._list_style_position != other->inherited_flags._list_style_position)
1413             return Layout;
1414     }
1415
1416     if (inherited_flags._text_align != other->inherited_flags._text_align ||
1417         inherited_flags._text_transform != other->inherited_flags._text_transform ||
1418         inherited_flags._direction != other->inherited_flags._direction ||
1419         inherited_flags._white_space != other->inherited_flags._white_space ||
1420         noninherited_flags._clear != other->noninherited_flags._clear)
1421         return Layout;
1422
1423     // Overflow returns a layout hint.
1424     if (noninherited_flags._overflowX != other->noninherited_flags._overflowX ||
1425         noninherited_flags._overflowY != other->noninherited_flags._overflowY)
1426         return Layout;
1427  
1428     // If our border widths change, then we need to layout.  Other changes to borders
1429     // only necessitate a repaint.
1430     if (borderLeftWidth() != other->borderLeftWidth() ||
1431         borderTopWidth() != other->borderTopWidth() ||
1432         borderBottomWidth() != other->borderBottomWidth() ||
1433         borderRightWidth() != other->borderRightWidth())
1434         return Layout;
1435
1436     // If the counter directives change, trigger a relayout to re-calculate counter values and rebuild the counter node tree.
1437     const CounterDirectiveMap* mapA = rareNonInheritedData->m_counterDirectives;
1438     const CounterDirectiveMap* mapB = other->rareNonInheritedData->m_counterDirectives;
1439     if (!(mapA == mapB || (mapA && mapB && *mapA == *mapB)))
1440         return Layout;
1441     if (visual->counterIncrement != other->visual->counterIncrement ||
1442         visual->counterReset != other->visual->counterReset)
1443         return Layout;
1444
1445     if (inherited->m_effectiveZoom != other->inherited->m_effectiveZoom)
1446         return Layout;
1447
1448     // Make sure these left/top/right/bottom checks stay below all layout checks and above
1449     // all visible checks.
1450     if (position() != StaticPosition) {
1451         if (surround->offset != other->surround->offset) {
1452              // Optimize for the case where a positioned layer is moving but not changing size.
1453             if (position() == AbsolutePosition && positionedObjectMoved(surround->offset, other->surround->offset))
1454                 return LayoutPositionedMovementOnly;
1455
1456             // FIXME: We will need to do a bit of work in RenderObject/Box::setStyle before we
1457             // can stop doing a layout when relative positioned objects move.  In particular, we'll need
1458             // to update scrolling positions and figure out how to do a repaint properly of the updated layer.
1459             //if (other->position() == RelativePosition)
1460             //    return RepaintLayer;
1461             //else
1462                 return Layout;
1463         } else if (box->z_index != other->box->z_index || box->z_auto != other->box->z_auto ||
1464                  visual->clip != other->visual->clip || visual->hasClip != other->visual->hasClip)
1465             return RepaintLayer;
1466     }
1467
1468     if (rareNonInheritedData->opacity != other->rareNonInheritedData->opacity ||
1469         rareNonInheritedData->m_mask != other->rareNonInheritedData->m_mask ||
1470         rareNonInheritedData->m_maskBoxImage != other->rareNonInheritedData->m_maskBoxImage)
1471         return RepaintLayer;
1472
1473     if (inherited->color != other->inherited->color ||
1474         inherited_flags._visibility != other->inherited_flags._visibility ||
1475         inherited_flags._text_decorations != other->inherited_flags._text_decorations ||
1476         inherited_flags._force_backgrounds_to_white != other->inherited_flags._force_backgrounds_to_white ||
1477         surround->border != other->surround->border ||
1478         *background.get() != *other->background.get() ||
1479         visual->textDecoration != other->visual->textDecoration ||
1480         rareInheritedData->userModify != other->rareInheritedData->userModify ||
1481         rareInheritedData->userSelect != other->rareInheritedData->userSelect ||
1482         rareNonInheritedData->userDrag != other->rareNonInheritedData->userDrag ||
1483         rareNonInheritedData->m_borderFit != other->rareNonInheritedData->m_borderFit ||
1484         rareInheritedData->textFillColor != other->rareInheritedData->textFillColor ||
1485         rareInheritedData->textStrokeColor != other->rareInheritedData->textStrokeColor)
1486         return Repaint;
1487
1488     // Cursors are not checked, since they will be set appropriately in response to mouse events,
1489     // so they don't need to cause any repaint or layout.
1490
1491     // Transitions don't need to be checked either.  We always set the new style on the RenderObject, so we will get a chance to fire off
1492     // the resulting transition properly.
1493     return Equal;
1494 }
1495
1496 void RenderStyle::setClip( Length top, Length right, Length bottom, Length left )
1497 {
1498     StyleVisualData *data = visual.access();
1499     data->clip.top = top;
1500     data->clip.right = right;
1501     data->clip.bottom = bottom;
1502     data->clip.left = left;
1503 }
1504
1505 void RenderStyle::addCursor(CachedImage* image, const IntPoint& hotSpot)
1506 {
1507     CursorData data;
1508     data.cursorImage = image;
1509     data.hotSpot = hotSpot;
1510     if (!inherited.access()->cursorData)
1511         inherited.access()->cursorData = new CursorList;
1512     inherited.access()->cursorData->append(data);
1513 }
1514
1515 void RenderStyle::setCursorList(PassRefPtr<CursorList> other)
1516 {
1517     inherited.access()->cursorData = other;
1518 }
1519
1520 void RenderStyle::clearCursorList()
1521 {
1522     inherited.access()->cursorData = new CursorList;
1523 }
1524
1525 bool RenderStyle::contentDataEquivalent(const RenderStyle* otherStyle) const
1526 {
1527     ContentData* c1 = rareNonInheritedData->m_content;
1528     ContentData* c2 = otherStyle->rareNonInheritedData->m_content;
1529
1530     while (c1 && c2) {
1531         if (c1->m_type != c2->m_type)
1532             return false;
1533
1534         switch (c1->m_type) {
1535             case CONTENT_NONE:
1536                 break;
1537             case CONTENT_TEXT:
1538                 if (!equal(c1->m_content.m_text, c2->m_content.m_text))
1539                     return false;
1540                 break;
1541             case CONTENT_OBJECT:
1542                 if (!imagesEquivalent(c1->m_content.m_image, c2->m_content.m_image))
1543                     return false;
1544                 break;
1545             case CONTENT_COUNTER:
1546                 if (*c1->m_content.m_counter != *c2->m_content.m_counter)
1547                     return false;
1548                 break;
1549         }
1550
1551         c1 = c1->m_next;
1552         c2 = c2->m_next;
1553     }
1554
1555     return !c1 && !c2;
1556 }
1557
1558 void RenderStyle::clearContent()
1559 {
1560     if (rareNonInheritedData->m_content)
1561         rareNonInheritedData->m_content->clear();
1562 }
1563
1564 void RenderStyle::setContent(StyleImage* image, bool add)
1565 {
1566     if (!image)
1567         return; // The object is null. Nothing to do. Just bail.
1568
1569     ContentData*& content = rareNonInheritedData.access()->m_content;
1570     ContentData* lastContent = content;
1571     while (lastContent && lastContent->m_next)
1572         lastContent = lastContent->m_next;
1573
1574     bool reuseContent = !add;
1575     ContentData* newContentData = 0;
1576     if (reuseContent && content) {
1577         content->clear();
1578         newContentData = content;
1579     } else
1580         newContentData = new ContentData;
1581
1582     if (lastContent && !reuseContent)
1583         lastContent->m_next = newContentData;
1584     else
1585         content = newContentData;
1586
1587     newContentData->m_content.m_image = image;
1588     newContentData->m_type = CONTENT_OBJECT;
1589     image->ref();
1590 }
1591
1592 void RenderStyle::setContent(StringImpl* s, bool add)
1593 {
1594     if (!s)
1595         return; // The string is null. Nothing to do. Just bail.
1596     
1597     ContentData*& content = rareNonInheritedData.access()->m_content;
1598     ContentData* lastContent = content;
1599     while (lastContent && lastContent->m_next)
1600         lastContent = lastContent->m_next;
1601
1602     bool reuseContent = !add;
1603     if (add && lastContent) {
1604         if (lastContent->m_type == CONTENT_TEXT) {
1605             // We can augment the existing string and share this ContentData node.
1606             StringImpl* oldStr = lastContent->m_content.m_text;
1607             String newStr = oldStr;
1608             newStr.append(s);
1609             newStr.impl()->ref();
1610             oldStr->deref();
1611             lastContent->m_content.m_text = newStr.impl();
1612             return;
1613         }
1614     }
1615
1616     ContentData* newContentData = 0;
1617     if (reuseContent && content) {
1618         content->clear();
1619         newContentData = content;
1620     } else
1621         newContentData = new ContentData;
1622     
1623     if (lastContent && !reuseContent)
1624         lastContent->m_next = newContentData;
1625     else
1626         content = newContentData;
1627     
1628     newContentData->m_content.m_text = s;
1629     newContentData->m_content.m_text->ref();
1630     newContentData->m_type = CONTENT_TEXT;
1631 }
1632
1633 void RenderStyle::setContent(CounterContent* c, bool add)
1634 {
1635     if (!c)
1636         return;
1637
1638     ContentData*& content = rareNonInheritedData.access()->m_content;
1639     ContentData* lastContent = content;
1640     while (lastContent && lastContent->m_next)
1641         lastContent = lastContent->m_next;
1642
1643     bool reuseContent = !add;
1644     ContentData* newContentData = 0;
1645     if (reuseContent && content) {
1646         content->clear();
1647         newContentData = content;
1648     } else
1649         newContentData = new ContentData;
1650
1651     if (lastContent && !reuseContent)
1652         lastContent->m_next = newContentData;
1653     else
1654         content = newContentData;
1655
1656     newContentData->m_content.m_counter = c;
1657     newContentData->m_type = CONTENT_COUNTER;
1658 }
1659
1660 void ContentData::clear()
1661 {
1662     switch (m_type) {
1663         case CONTENT_NONE:
1664             break;
1665         case CONTENT_OBJECT:
1666             m_content.m_image->deref();
1667             break;
1668         case CONTENT_TEXT:
1669             m_content.m_text->deref();
1670             break;
1671         case CONTENT_COUNTER:
1672             delete m_content.m_counter;
1673             break;
1674     }
1675
1676     ContentData* n = m_next;
1677     m_type = CONTENT_NONE;
1678     m_next = 0;
1679
1680     // Reverse the list so we can delete without recursing.
1681     ContentData* last = 0;
1682     ContentData* c;
1683     while ((c = n)) {
1684         n = c->m_next;
1685         c->m_next = last;
1686         last = c;
1687     }
1688     for (c = last; c; c = n) {
1689         n = c->m_next;
1690         c->m_next = 0;
1691         delete c;
1692     }
1693 }
1694
1695 void RenderStyle::applyTransform(AffineTransform& transform, const IntSize& borderBoxSize) const
1696 {
1697     // transform-origin brackets the transform with translate operations.
1698     // Optimize for the case where the only transform is a translation, since the transform-origin is irrelevant
1699     // in that case.
1700     bool applyTransformOrigin = false;
1701     unsigned s = rareNonInheritedData->m_transform->m_operations.size();
1702     unsigned i;
1703     for (i = 0; i < s; i++) {
1704         if (!rareNonInheritedData->m_transform->m_operations[i]->isTranslateOperation()) {
1705             applyTransformOrigin = true;
1706             break;
1707         }
1708     }
1709     
1710     if (applyTransformOrigin)
1711         transform.translate(transformOriginX().calcFloatValue(borderBoxSize.width()), transformOriginY().calcFloatValue(borderBoxSize.height()));
1712     
1713     for (i = 0; i < s; i++)
1714         rareNonInheritedData->m_transform->m_operations[i]->apply(transform, borderBoxSize);
1715         
1716     if (applyTransformOrigin)
1717         transform.translate(-transformOriginX().calcFloatValue(borderBoxSize.width()), -transformOriginY().calcFloatValue(borderBoxSize.height()));
1718 }
1719
1720 #if ENABLE(XBL)
1721 BindingURI::BindingURI(StringImpl* uri) 
1722 :m_next(0)
1723
1724     m_uri = uri;
1725     if (uri) uri->ref();
1726 }
1727
1728 BindingURI::~BindingURI()
1729 {
1730     if (m_uri)
1731         m_uri->deref();
1732     delete m_next;
1733 }
1734
1735 BindingURI* BindingURI::copy()
1736 {
1737     BindingURI* newBinding = new BindingURI(m_uri);
1738     if (next()) {
1739         BindingURI* nextCopy = next()->copy();
1740         newBinding->setNext(nextCopy);
1741     }
1742     
1743     return newBinding;
1744 }
1745
1746 bool BindingURI::operator==(const BindingURI& o) const
1747 {
1748     if ((m_next && !o.m_next) || (!m_next && o.m_next) ||
1749         (m_next && o.m_next && *m_next != *o.m_next))
1750         return false;
1751     
1752     if (m_uri == o.m_uri)
1753         return true;
1754     if (!m_uri || !o.m_uri)
1755         return false;
1756     
1757     return String(m_uri) == String(o.m_uri);
1758 }
1759
1760 void RenderStyle::addBindingURI(StringImpl* uri)
1761 {
1762     BindingURI* binding = new BindingURI(uri);
1763     if (!bindingURIs())
1764         SET_VAR(rareNonInheritedData, bindingURI, binding)
1765     else 
1766         for (BindingURI* b = bindingURIs(); b; b = b->next()) {
1767             if (!b->next())
1768                 b->setNext(binding);
1769         }
1770 }
1771 #endif
1772
1773 void RenderStyle::setTextShadow(ShadowData* val, bool add)
1774 {
1775     StyleRareInheritedData* rareData = rareInheritedData.access(); 
1776     if (!add) {
1777         delete rareData->textShadow;
1778         rareData->textShadow = val;
1779         return;
1780     }
1781
1782     val->next = rareData->textShadow;
1783     rareData->textShadow = val;
1784 }
1785
1786 void RenderStyle::setBoxShadow(ShadowData* val, bool add)
1787 {
1788     StyleRareNonInheritedData* rareData = rareNonInheritedData.access(); 
1789     if (!add) {
1790         delete rareData->m_boxShadow;
1791         rareData->m_boxShadow = val;
1792         return;
1793     }
1794
1795     val->next = rareData->m_boxShadow;
1796     rareData->m_boxShadow = val;
1797 }
1798
1799 ShadowData::ShadowData(const ShadowData& o)
1800 :x(o.x), y(o.y), blur(o.blur), color(o.color)
1801 {
1802     next = o.next ? new ShadowData(*o.next) : 0;
1803 }
1804
1805 bool ShadowData::operator==(const ShadowData& o) const
1806 {
1807     if ((next && !o.next) || (!next && o.next) ||
1808         (next && o.next && *next != *o.next))
1809         return false;
1810     
1811     return x == o.x && y == o.y && blur == o.blur && color == o.color;
1812 }
1813
1814 bool operator==(const CounterDirectives& a, const CounterDirectives& b)
1815 {
1816     if (a.m_reset != b.m_reset || a.m_increment != b.m_increment)
1817         return false;
1818     if (a.m_reset && a.m_resetValue != b.m_resetValue)
1819         return false;
1820     if (a.m_increment && a.m_incrementValue != b.m_incrementValue)
1821         return false;
1822     return true;
1823 }
1824
1825 const CounterDirectiveMap* RenderStyle::counterDirectives() const
1826 {
1827     return rareNonInheritedData->m_counterDirectives;
1828 }
1829
1830 CounterDirectiveMap& RenderStyle::accessCounterDirectives()
1831 {
1832     CounterDirectiveMap*& map = rareNonInheritedData.access()->m_counterDirectives;
1833     if (!map)
1834         map = new CounterDirectiveMap;
1835     return *map;
1836 }
1837
1838 const Vector<StyleDashboardRegion>& RenderStyle::initialDashboardRegions()
1839
1840     static Vector<StyleDashboardRegion> emptyList;
1841     return emptyList;
1842 }
1843
1844 const Vector<StyleDashboardRegion>& RenderStyle::noneDashboardRegions()
1845
1846     static Vector<StyleDashboardRegion> noneList;
1847     static bool noneListInitialized = false;
1848     
1849     if (!noneListInitialized) {
1850         StyleDashboardRegion region;
1851         region.label = "";
1852         region.offset.top  = Length();
1853         region.offset.right = Length();
1854         region.offset.bottom = Length();
1855         region.offset.left = Length();
1856         region.type = StyleDashboardRegion::None;
1857         noneList.append (region);
1858         noneListInitialized = true;
1859     }
1860     return noneList;
1861 }
1862
1863 void RenderStyle::adjustTransitions()
1864 {
1865     if (transitions()) {
1866         if (transitions()->isEmpty()) {
1867             clearTransitions();
1868             return;
1869         }
1870
1871         Transition* next;
1872         for (Transition* p = accessTransitions(); p; p = next) {
1873             next = p->m_next;
1874             if (next && next->isEmpty()) {
1875                 delete next;
1876                 p->m_next = 0;
1877                 break;
1878             }
1879         }
1880     
1881         // Repeat patterns into layers that don't have some properties set.
1882         accessTransitions()->fillUnsetProperties();
1883     }
1884 }
1885
1886 Transition* RenderStyle::accessTransitions()
1887 {
1888     Transition* layer = rareNonInheritedData.access()->m_transition;
1889     if (!layer)
1890         rareNonInheritedData.access()->m_transition = new Transition();
1891     return rareNonInheritedData->m_transition;
1892 }
1893
1894 }