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