Reviewed by eseidel.
[WebKit-https.git] / WebCore / rendering / RenderStyle.cpp
1 /*
2  * This file is part of the DOM implementation for KDE.
3  *
4  * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
5  * Copyright (C) 2004, 2005 Apple Computer, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  */
23
24 #include "config.h"
25 #include "RenderStyle.h"
26
27 #include "cssstyleselector.h"
28 #include "RenderArena.h"
29
30 namespace WebCore {
31
32 static RenderStyle* defaultStyle;
33
34 StyleSurroundData::StyleSurroundData()
35     : margin(Fixed), padding(Auto)
36 {
37 }
38
39 StyleSurroundData::StyleSurroundData(const StyleSurroundData& o)
40     : Shared<StyleSurroundData>()
41     , offset(o.offset)
42     , margin(o.margin)
43     , padding(o.padding)
44     , border(o.border)
45 {
46 }
47
48 bool StyleSurroundData::operator==(const StyleSurroundData& o) const
49 {
50     return offset == o.offset && margin == o.margin && padding == o.padding && border == o.border;
51 }
52
53 StyleBoxData::StyleBoxData()
54     : z_index(0), z_auto(true), boxSizing(CONTENT_BOX)
55 {
56     // Initialize our min/max widths/heights.
57     min_width = min_height = RenderStyle::initialMinSize();
58     max_width = max_height = RenderStyle::initialMaxSize();
59 }
60
61 StyleBoxData::StyleBoxData(const StyleBoxData& o )
62     : Shared<StyleBoxData>()
63     , width(o.width)
64     , height(o.height)
65     , min_width(o.min_width)
66     , max_width(o.max_width)
67     , min_height(o.min_height)
68     , max_height(o.max_height)
69     , z_index(o.z_index)
70     , z_auto(o.z_auto)
71     , boxSizing(o.boxSizing)
72 {
73 }
74
75 bool StyleBoxData::operator==(const StyleBoxData& o) const
76 {
77     return width == o.width &&
78            height == o.height &&
79            min_width == o.min_width &&
80            max_width == o.max_width &&
81            min_height == o.min_height &&
82            max_height == o.max_height &&
83            z_index == o.z_index &&
84            z_auto == o.z_auto &&
85            boxSizing == o.boxSizing;
86 }
87
88
89 StyleVisualData::StyleVisualData()
90     : hasClip(false)
91     , textDecoration(RenderStyle::initialTextDecoration())
92     , colspan(1)
93     , counter_increment(0)
94     , counter_reset(0)
95 {
96 }
97
98 StyleVisualData::~StyleVisualData()
99 {
100 }
101
102 StyleVisualData::StyleVisualData(const StyleVisualData& o)
103     : Shared<StyleVisualData>()
104     , clip(o.clip)
105     , hasClip(o.hasClip)
106     , textDecoration(o.textDecoration)
107     , colspan(o.colspan)
108     , counter_increment(o.counter_increment)
109     , counter_reset(o.counter_reset)
110 {
111 }
112
113 BackgroundLayer::BackgroundLayer()
114     : m_image(RenderStyle::initialBackgroundImage())
115     , m_bgAttachment(RenderStyle::initialBackgroundAttachment())
116     , m_bgClip(RenderStyle::initialBackgroundClip())
117     , m_bgOrigin(RenderStyle::initialBackgroundOrigin())
118     , m_bgRepeat(RenderStyle::initialBackgroundRepeat())
119     , m_bgComposite(RenderStyle::initialBackgroundComposite())
120     , m_backgroundSize(RenderStyle::initialBackgroundSize())
121     , m_imageSet(false)
122     , m_attachmentSet(false)
123     , m_clipSet(false)
124     , m_originSet(false)
125     , m_repeatSet(false)
126     , m_xPosSet(false)
127     , m_yPosSet(false)
128     , m_compositeSet(false)
129     , m_backgroundSizeSet(false)
130     , m_next(0)
131 {
132 }
133
134 BackgroundLayer::BackgroundLayer(const BackgroundLayer& o)
135     : m_image(o.m_image)
136     , m_xPosition(o.m_xPosition)
137     , m_yPosition(o.m_yPosition)
138     , m_bgAttachment(o.m_bgAttachment)
139     , m_bgClip(o.m_bgClip)
140     , m_bgOrigin(o.m_bgOrigin)
141     , m_bgRepeat(o.m_bgRepeat)
142     , m_bgComposite(o.m_bgComposite)
143     , m_backgroundSize(o.m_backgroundSize)
144     , m_imageSet(o.m_imageSet)
145     , m_attachmentSet(o.m_attachmentSet)
146     , m_clipSet(o.m_clipSet)
147     , m_originSet(o.m_originSet)
148     , m_repeatSet(o.m_repeatSet)
149     , m_xPosSet(o.m_xPosSet)
150     , m_yPosSet(o.m_yPosSet)
151     , m_compositeSet(o.m_compositeSet)
152     , m_backgroundSizeSet(o.m_backgroundSizeSet)
153     , m_next(o.m_next ? new BackgroundLayer(*o.m_next) : 0)
154 {
155 }
156
157 BackgroundLayer::~BackgroundLayer()
158 {
159     delete m_next;
160 }
161
162 BackgroundLayer& BackgroundLayer::operator=(const BackgroundLayer& o)
163 {
164     if (m_next != o.m_next) {
165         delete m_next;
166         m_next = o.m_next ? new BackgroundLayer(*o.m_next) : 0;
167     }
168
169     m_image = o.m_image;
170     m_xPosition = o.m_xPosition;
171     m_yPosition = o.m_yPosition;
172     m_bgAttachment = o.m_bgAttachment;
173     m_bgClip = o.m_bgClip;
174     m_bgComposite = o.m_bgComposite;
175     m_bgOrigin = o.m_bgOrigin;
176     m_bgRepeat = o.m_bgRepeat;
177     m_backgroundSize = o.m_backgroundSize;
178
179     m_imageSet = o.m_imageSet;
180     m_attachmentSet = o.m_attachmentSet;
181     m_clipSet = o.m_clipSet;
182     m_compositeSet = o.m_compositeSet;
183     m_originSet = o.m_originSet;
184     m_repeatSet = o.m_repeatSet;
185     m_xPosSet = o.m_xPosSet;
186     m_yPosSet = o.m_yPosSet;
187     m_backgroundSizeSet = o.m_backgroundSizeSet;
188
189     return *this;
190 }
191
192 bool BackgroundLayer::operator==(const BackgroundLayer& o) const
193 {
194     return m_image == o.m_image && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition &&
195            m_bgAttachment == o.m_bgAttachment && m_bgClip == o.m_bgClip && 
196            m_bgComposite == o.m_bgComposite && m_bgOrigin == o.m_bgOrigin && m_bgRepeat == o.m_bgRepeat &&
197            m_backgroundSize.width == o.m_backgroundSize.width && m_backgroundSize.height == o.m_backgroundSize.height && 
198            m_imageSet == o.m_imageSet && m_attachmentSet == o.m_attachmentSet && m_compositeSet == o.m_compositeSet && 
199            m_repeatSet == o.m_repeatSet && m_xPosSet == o.m_xPosSet && m_yPosSet == o.m_yPosSet && 
200            m_backgroundSizeSet == o.m_backgroundSizeSet && 
201            ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next);
202 }
203
204 void BackgroundLayer::fillUnsetProperties()
205 {
206     BackgroundLayer* curr;
207     for (curr = this; curr && curr->isBackgroundImageSet(); curr = curr->next());
208     if (curr && curr != this) {
209         // We need to fill in the remaining values with the pattern specified.
210         for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
211             curr->m_image = pattern->m_image;
212             pattern = pattern->next();
213             if (pattern == curr || !pattern)
214                 pattern = this;
215         }
216     }
217     
218     for (curr = this; curr && curr->isBackgroundXPositionSet(); curr = curr->next());
219     if (curr && curr != this) {
220         // We need to fill in the remaining values with the pattern specified.
221         for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
222             curr->m_xPosition = pattern->m_xPosition;
223             pattern = pattern->next();
224             if (pattern == curr || !pattern)
225                 pattern = this;
226         }
227     }
228     
229     for (curr = this; curr && curr->isBackgroundYPositionSet(); curr = curr->next());
230     if (curr && curr != this) {
231         // We need to fill in the remaining values with the pattern specified.
232         for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
233             curr->m_yPosition = pattern->m_yPosition;
234             pattern = pattern->next();
235             if (pattern == curr || !pattern)
236                 pattern = this;
237         }
238     }
239     
240     for (curr = this; curr && curr->isBackgroundAttachmentSet(); curr = curr->next());
241     if (curr && curr != this) {
242         // We need to fill in the remaining values with the pattern specified.
243         for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
244             curr->m_bgAttachment = pattern->m_bgAttachment;
245             pattern = pattern->next();
246             if (pattern == curr || !pattern)
247                 pattern = this;
248         }
249     }
250     
251     for (curr = this; curr && curr->isBackgroundClipSet(); curr = curr->next());
252     if (curr && curr != this) {
253         // We need to fill in the remaining values with the pattern specified.
254         for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
255             curr->m_bgClip = pattern->m_bgClip;
256             pattern = pattern->next();
257             if (pattern == curr || !pattern)
258                 pattern = this;
259         }
260     }
261
262     for (curr = this; curr && curr->isBackgroundCompositeSet(); curr = curr->next());
263     if (curr && curr != this) {
264         // We need to fill in the remaining values with the pattern specified.
265         for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
266             curr->m_bgComposite = pattern->m_bgComposite;
267             pattern = pattern->next();
268             if (pattern == curr || !pattern)
269                 pattern = this;
270         }
271     }
272
273     for (curr = this; curr && curr->isBackgroundOriginSet(); curr = curr->next());
274     if (curr && curr != this) {
275         // We need to fill in the remaining values with the pattern specified.
276         for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
277             curr->m_bgOrigin = pattern->m_bgOrigin;
278             pattern = pattern->next();
279             if (pattern == curr || !pattern)
280                 pattern = this;
281         }
282     }
283
284     for (curr = this; curr && curr->isBackgroundRepeatSet(); curr = curr->next());
285     if (curr && curr != this) {
286         // We need to fill in the remaining values with the pattern specified.
287         for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
288             curr->m_bgRepeat = pattern->m_bgRepeat;
289             pattern = pattern->next();
290             if (pattern == curr || !pattern)
291                 pattern = this;
292         }
293     }
294     
295     for (curr = this; curr && curr->isBackgroundSizeSet(); curr = curr->next());
296     if (curr && curr != this) {
297         // We need to fill in the remaining values with the pattern specified.
298         for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
299             curr->m_backgroundSize = pattern->m_backgroundSize;
300             pattern = pattern->next();
301             if (pattern == curr || !pattern)
302                 pattern = this;
303         }
304     }
305 }
306
307 void BackgroundLayer::cullEmptyLayers()
308 {
309     BackgroundLayer *next;
310     for (BackgroundLayer *p = this; p; p = next) {
311         next = p->m_next;
312         if (next && !next->isBackgroundImageSet() &&
313             !next->isBackgroundXPositionSet() && !next->isBackgroundYPositionSet() &&
314             !next->isBackgroundAttachmentSet() && !next->isBackgroundClipSet() &&
315             !next->isBackgroundCompositeSet() && !next->isBackgroundOriginSet() &&
316             !next->isBackgroundRepeatSet() && !next->isBackgroundSizeSet()) {
317             delete next;
318             p->m_next = 0;
319             break;
320         }
321     }
322 }
323
324 StyleBackgroundData::StyleBackgroundData()
325 {
326 }
327
328 StyleBackgroundData::StyleBackgroundData(const StyleBackgroundData& o)
329     : Shared<StyleBackgroundData>(), m_background(o.m_background), m_outline(o.m_outline)
330 {
331 }
332
333 bool StyleBackgroundData::operator==(const StyleBackgroundData& o) const
334 {
335     return m_background == o.m_background && m_color == o.m_color && m_outline == o.m_outline;
336 }
337
338 StyleMarqueeData::StyleMarqueeData()
339     : increment(RenderStyle::initialMarqueeIncrement())
340     , speed(RenderStyle::initialMarqueeSpeed())
341     , loops(RenderStyle::initialMarqueeLoopCount())
342     , behavior(RenderStyle::initialMarqueeBehavior())
343     , direction(RenderStyle::initialMarqueeDirection())
344 {
345 }
346
347 StyleMarqueeData::StyleMarqueeData(const StyleMarqueeData& o)
348     : Shared<StyleMarqueeData>()
349     , increment(o.increment)
350     , speed(o.speed)
351     , loops(o.loops)
352     , behavior(o.behavior)
353     , direction(o.direction) 
354 {
355 }
356
357 bool StyleMarqueeData::operator==(const StyleMarqueeData& o) const
358 {
359     return increment == o.increment && speed == o.speed && direction == o.direction &&
360            behavior == o.behavior && loops == o.loops;
361 }
362
363 StyleFlexibleBoxData::StyleFlexibleBoxData()
364     : flex(RenderStyle::initialBoxFlex())
365     , flex_group(RenderStyle::initialBoxFlexGroup())
366     , ordinal_group(RenderStyle::initialBoxOrdinalGroup())
367     , align(RenderStyle::initialBoxAlign())
368     , pack(RenderStyle::initialBoxPack())
369     , orient(RenderStyle::initialBoxOrient())
370     , lines(RenderStyle::initialBoxLines())
371 {
372 }
373
374 StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& o)
375     : Shared<StyleFlexibleBoxData>()
376     , flex(o.flex)
377     , flex_group(o.flex_group)
378     , ordinal_group(o.ordinal_group)
379     , align(o.align)
380     , pack(o.pack)
381     , orient(o.orient)
382     , lines(o.lines)
383 {
384 }
385
386 bool StyleFlexibleBoxData::operator==(const StyleFlexibleBoxData& o) const
387 {
388     return flex == o.flex && flex_group == o.flex_group &&
389            ordinal_group == o.ordinal_group && align == o.align &&
390            pack == o.pack && orient == o.orient && lines == o.lines;
391 }
392
393 StyleCSS3NonInheritedData::StyleCSS3NonInheritedData()
394     : lineClamp(RenderStyle::initialLineClamp())
395     , opacity(RenderStyle::initialOpacity())
396     , userDrag(RenderStyle::initialUserDrag())
397     , userSelect(RenderStyle::initialUserSelect())
398     , textOverflow(RenderStyle::initialTextOverflow())
399     , marginTopCollapse(MCOLLAPSE)
400     , marginBottomCollapse(MCOLLAPSE)
401     , m_appearance(RenderStyle::initialAppearance())
402 #ifdef XBL_SUPPORT
403     , bindingURI(0)
404 #endif
405 {
406 }
407
408 StyleCSS3NonInheritedData::StyleCSS3NonInheritedData(const StyleCSS3NonInheritedData& o)
409     : Shared<StyleCSS3NonInheritedData>()
410     , lineClamp(o.lineClamp)
411     , opacity(o.opacity)
412     , flexibleBox(o.flexibleBox)
413     , marquee(o.marquee)
414     , userDrag(o.userDrag)
415     , userSelect(o.userSelect)
416     , textOverflow(o.textOverflow)
417     , marginTopCollapse(o.marginTopCollapse)
418     , marginBottomCollapse(o.marginBottomCollapse)
419     , m_appearance(o.m_appearance)
420 #ifdef XBL_SUPPORT
421     , bindingURI(o.bindingURI ? o.bindingURI->copy() : 0)
422 #endif
423 {
424 }
425
426 StyleCSS3NonInheritedData::~StyleCSS3NonInheritedData()
427 {
428 #ifdef XBL_SUPPORT
429     delete bindingURI;
430 #endif
431 }
432
433 #ifdef XBL_SUPPORT
434 bool StyleCSS3NonInheritedData::bindingsEquivalent(const StyleCSS3NonInheritedData& o) const
435 {
436     if (this == &o) return true;
437     if (!bindingURI && o.bindingURI || bindingURI && !o.bindingURI)
438         return false;
439     if (bindingURI && o.bindingURI && (*bindingURI != *o.bindingURI))
440         return false;
441     return true;
442 }
443 #endif
444
445 bool StyleCSS3NonInheritedData::operator==(const StyleCSS3NonInheritedData& o) const
446 {
447     return opacity == o.opacity && flexibleBox == o.flexibleBox && marquee == o.marquee &&
448            userDrag == o.userDrag && userSelect == o.userSelect && textOverflow == o.textOverflow &&
449            marginTopCollapse == o.marginTopCollapse && marginBottomCollapse == o.marginBottomCollapse &&
450            m_appearance == o.m_appearance
451 #ifdef XBL_SUPPORT
452            && bindingsEquivalent(o)
453 #endif
454            && lineClamp == o.lineClamp && m_dashboardRegions == o.m_dashboardRegions
455     ;
456 }
457
458 StyleCSS3InheritedData::StyleCSS3InheritedData()
459     : textShadow(0)
460     , textSecurity(RenderStyle::initialTextSecurity())
461     , userModify(READ_ONLY)
462     , wordWrap(WBNORMAL)
463     , nbspMode(NBNORMAL)
464     , khtmlLineBreak(LBNORMAL)
465     , textSizeAdjust(RenderStyle::initialTextSizeAdjust())
466     , resize(RenderStyle::initialResize())
467 {
468
469 }
470
471 StyleCSS3InheritedData::StyleCSS3InheritedData(const StyleCSS3InheritedData& o)
472     : Shared<StyleCSS3InheritedData>()
473     , textShadow(o.textShadow ? new ShadowData(*o.textShadow) : 0)
474     , highlight(o.highlight)
475     , textSecurity(o.textSecurity)
476     , userModify(o.userModify)
477     , wordWrap(o.wordWrap)
478     , nbspMode(o.nbspMode)
479     , khtmlLineBreak(o.khtmlLineBreak)
480     , textSizeAdjust(o.textSizeAdjust)
481     , resize(o.resize)
482 {
483 }
484
485 StyleCSS3InheritedData::~StyleCSS3InheritedData()
486 {
487     delete textShadow;
488 }
489
490 bool StyleCSS3InheritedData::operator==(const StyleCSS3InheritedData& o) const
491 {
492     return userModify == o.userModify
493         && shadowDataEquivalent(o)
494         && highlight == o.highlight
495         && wordWrap == o.wordWrap
496         && nbspMode == o.nbspMode
497         && khtmlLineBreak == o.khtmlLineBreak
498         && textSizeAdjust == o.textSizeAdjust;
499 }
500
501 bool StyleCSS3InheritedData::shadowDataEquivalent(const StyleCSS3InheritedData& o) const
502 {
503     if (!textShadow && o.textShadow || textShadow && !o.textShadow)
504         return false;
505     if (textShadow && o.textShadow && (*textShadow != *o.textShadow))
506         return false;
507     return true;
508 }
509
510 StyleInheritedData::StyleInheritedData()
511     : indent(RenderStyle::initialTextIndent()), line_height(RenderStyle::initialLineHeight()), 
512       style_image(RenderStyle::initialListStyleImage()),
513       color(RenderStyle::initialColor()), 
514       horizontal_border_spacing(RenderStyle::initialHorizontalBorderSpacing()), 
515       vertical_border_spacing(RenderStyle::initialVerticalBorderSpacing()),
516       widows(RenderStyle::initialWidows()), orphans(RenderStyle::initialOrphans()),
517       page_break_inside(RenderStyle::initialPageBreak())
518 {
519 }
520
521 StyleInheritedData::~StyleInheritedData()
522 {
523 }
524
525 StyleInheritedData::StyleInheritedData(const StyleInheritedData& o )
526     : Shared<StyleInheritedData>(),
527       indent( o.indent ), line_height( o.line_height ), style_image( o.style_image ),
528       cursorData(o.cursorData),
529       font( o.font ), color( o.color ),
530       horizontal_border_spacing( o.horizontal_border_spacing ),
531       vertical_border_spacing( o.vertical_border_spacing ),
532       widows(o.widows), orphans(o.orphans), page_break_inside(o.page_break_inside)
533 {
534 }
535
536 bool StyleInheritedData::operator==(const StyleInheritedData& o) const
537 {
538     return
539         indent == o.indent &&
540         line_height == o.line_height &&
541         style_image == o.style_image &&
542         cursorData  == o.cursorData &&
543         font == o.font &&
544         color == o.color &&
545         horizontal_border_spacing == o.horizontal_border_spacing &&
546         vertical_border_spacing == o.vertical_border_spacing &&
547         widows == o.widows &&
548         orphans == o.orphans &&
549         page_break_inside == o.page_break_inside;
550 }
551
552 // ----------------------------------------------------------
553
554 void* RenderStyle::operator new(size_t sz, RenderArena* renderArena) throw()
555 {
556     return renderArena->allocate(sz);
557 }
558
559 void RenderStyle::operator delete(void* ptr, size_t sz)
560 {
561     // Stash size where destroy can find it.
562     *(size_t *)ptr = sz;
563 }
564
565 void RenderStyle::arenaDelete(RenderArena *arena)
566 {
567     RenderStyle *ps = pseudoStyle;
568     RenderStyle *prev = 0;
569     
570     while (ps) {
571         prev = ps;
572         ps = ps->pseudoStyle;
573         // to prevent a double deletion.
574         // this works only because the styles below aren't really shared
575         // Dirk said we need another construct as soon as these are shared
576         prev->pseudoStyle = 0;
577         prev->deref(arena);
578     }
579     delete content;
580     
581     delete this;
582     
583     // Recover the size left there for us by operator delete and free the memory.
584     arena->free(*(size_t *)this, this);
585 }
586
587 inline RenderStyle *initDefaultStyle()
588 {
589     if (!defaultStyle)
590         defaultStyle = ::new RenderStyle(true);
591     return defaultStyle;
592 }
593
594 RenderStyle::RenderStyle()
595     : box(initDefaultStyle()->box)
596     , visual(defaultStyle->visual)
597     , background(defaultStyle->background)
598     , surround(defaultStyle->surround)
599     , css3NonInheritedData(defaultStyle->css3NonInheritedData)
600     , css3InheritedData(defaultStyle->css3InheritedData)
601     , inherited(defaultStyle->inherited)
602     , pseudoStyle(0)
603     , content(0)
604     , m_pseudoState(PseudoUnknown)
605     , m_affectedByAttributeSelectors(false)
606     , m_unique(false)
607     , m_ref(0)
608 #ifdef SVG_SUPPORT
609     , m_svgStyle(defaultStyle->m_svgStyle)
610 #endif
611 {
612     setBitDefaults(); // Would it be faster to copy this from the default style?
613 }
614
615 RenderStyle::RenderStyle(bool)
616     : pseudoStyle(0)
617     , content(0)
618     , m_pseudoState(PseudoUnknown)
619     , m_affectedByAttributeSelectors(false)
620     , m_unique(false)
621     , m_ref(1)
622 {
623     setBitDefaults();
624
625     box.init();
626     visual.init();
627     background.init();
628     surround.init();
629     css3NonInheritedData.init();
630     css3NonInheritedData.access()->flexibleBox.init();
631     css3NonInheritedData.access()->marquee.init();
632     css3InheritedData.init();
633     inherited.init();
634     
635 #ifdef SVG_SUPPORT
636     m_svgStyle.init();
637 #endif
638 }
639
640 RenderStyle::RenderStyle(const RenderStyle& o)
641     : inherited_flags(o.inherited_flags)
642     , noninherited_flags(o.noninherited_flags)
643     , box(o.box)
644     , visual(o.visual )
645     , background(o.background)
646     , surround(o.surround)
647     , css3NonInheritedData(o.css3NonInheritedData)
648     , css3InheritedData(o.css3InheritedData)
649     , inherited(o.inherited)
650     , pseudoStyle(0)
651     , content(o.content)
652     , m_pseudoState(o.m_pseudoState)
653     , m_affectedByAttributeSelectors(false)
654     , m_unique(false)
655     , m_ref(0)
656 #ifdef SVG_SUPPORT
657     , m_svgStyle(o.m_svgStyle)
658 #endif
659 {
660 }
661
662 void RenderStyle::inheritFrom(const RenderStyle* inheritParent)
663 {
664     css3InheritedData = inheritParent->css3InheritedData;
665     inherited = inheritParent->inherited;
666     inherited_flags = inheritParent->inherited_flags;
667 #ifdef SVG_SUPPORT
668     if (m_svgStyle != inheritParent->m_svgStyle)
669         m_svgStyle.access()->inheritFrom(inheritParent->m_svgStyle.get());
670 #endif
671 }
672
673 RenderStyle::~RenderStyle()
674 {
675 }
676
677 bool RenderStyle::operator==(const RenderStyle& o) const
678 {
679     // compare everything except the pseudoStyle pointer
680     return inherited_flags == o.inherited_flags &&
681             noninherited_flags == o.noninherited_flags &&
682             box == o.box &&
683             visual == o.visual &&
684             background == o.background &&
685             surround == o.surround &&
686             css3NonInheritedData == o.css3NonInheritedData &&
687             css3InheritedData == o.css3InheritedData &&
688             inherited == o.inherited
689 #ifdef SVG_SUPPORT
690             && m_svgStyle == o.m_svgStyle
691 #endif
692             ;
693 }
694
695 bool RenderStyle::isStyleAvailable() const
696 {
697     return this != CSSStyleSelector::styleNotYetAvailable;
698 }
699
700 enum EPseudoBit { NO_BIT = 0x0, BEFORE_BIT = 0x1, AFTER_BIT = 0x2, FIRST_LINE_BIT = 0x4,
701                   FIRST_LETTER_BIT = 0x8, SELECTION_BIT = 0x10, FIRST_LINE_INHERITED_BIT = 0x20,
702                   FILE_UPLOAD_BUTTON_BIT = 0x40 };
703
704 static inline int pseudoBit(RenderStyle::PseudoId pseudo)
705 {
706     switch (pseudo) {
707         case RenderStyle::BEFORE:
708             return BEFORE_BIT;
709         case RenderStyle::AFTER:
710             return AFTER_BIT;
711         case RenderStyle::FIRST_LINE:
712             return FIRST_LINE_BIT;
713         case RenderStyle::FIRST_LETTER:
714             return FIRST_LETTER_BIT;
715         case RenderStyle::SELECTION:
716             return SELECTION_BIT;
717         case RenderStyle::FIRST_LINE_INHERITED:
718             return FIRST_LINE_INHERITED_BIT;
719         case RenderStyle::FILE_UPLOAD_BUTTON:
720             return FILE_UPLOAD_BUTTON_BIT;
721         default:
722             return NO_BIT;
723     }
724 }
725
726 bool RenderStyle::hasPseudoStyle(PseudoId pseudo) const
727 {
728     return pseudoBit(pseudo) & noninherited_flags._pseudoBits;
729 }
730
731 void RenderStyle::setHasPseudoStyle(PseudoId pseudo)
732 {
733     noninherited_flags._pseudoBits |= pseudoBit(pseudo);
734 }
735
736 RenderStyle* RenderStyle::getPseudoStyle(PseudoId pid)
737 {
738     if (!pseudoStyle || styleType() != NOPSEUDO)
739         return 0;
740     RenderStyle* ps = pseudoStyle;
741     while (ps && ps->styleType() != pid)
742         ps = ps->pseudoStyle;
743     return ps;
744 }
745
746 void RenderStyle::addPseudoStyle(RenderStyle* pseudo)
747 {
748     if (!pseudo)
749         return;
750     pseudo->ref();
751     pseudo->pseudoStyle = pseudoStyle;
752     pseudoStyle = pseudo;
753 }
754
755 bool RenderStyle::inheritedNotEqual( RenderStyle *other ) const
756 {
757     return inherited_flags != other->inherited_flags ||
758            inherited != other->inherited ||
759 #ifdef SVG_SUPPORT
760            m_svgStyle->inheritedNotEqual(other->m_svgStyle.get()) ||
761 #endif
762            css3InheritedData != other->css3InheritedData;
763 }
764
765 /*
766   compares two styles. The result gives an idea of the action that
767   needs to be taken when replacing the old style with a new one.
768
769   CbLayout: The containing block of the object needs a relayout.
770   Layout: the RenderObject needs a relayout after the style change
771   Visible: The change is visible, but no relayout is needed
772   NonVisible: The object does need neither repaint nor relayout after
773        the change.
774
775   ### TODO:
776   A lot can be optimised here based on the display type, lots of
777   optimisations are unimplemented, and currently result in the
778   worst case result causing a relayout of the containing block.
779 */
780 RenderStyle::Diff RenderStyle::diff( const RenderStyle *other ) const
781 {
782 #ifdef SVG_SUPPORT
783     // This is horribly inefficient.  Eventually we'll have to integrate
784     // this more directly by calling: Diff svgDiff = svgStyle->diff(other)
785     // and then checking svgDiff and returning from the appropriate places below.
786     if (m_svgStyle != other->m_svgStyle)
787         return Layout;
788 #endif
789
790     // we anyway assume they are the same
791 //      EDisplay _effectiveDisplay : 5;
792
793     // NonVisible:
794 //      ECursor _cursor_style : 4;
795
796 // ### this needs work to know more exactly if we need a relayout
797 //     or just a repaint
798
799 // non-inherited attributes
800 //     DataRef<StyleBoxData> box;
801 //     DataRef<StyleVisualData> visual;
802 //     DataRef<StyleSurroundData> surround;
803
804 // inherited attributes
805 //     DataRef<StyleInheritedData> inherited;
806
807     if ( box->width != other->box->width ||
808          box->min_width != other->box->min_width ||
809          box->max_width != other->box->max_width ||
810          box->height != other->box->height ||
811          box->min_height != other->box->min_height ||
812          box->max_height != other->box->max_height ||
813          box->vertical_align != other->box->vertical_align ||
814          box->boxSizing != other->box->boxSizing ||
815          !(surround->margin == other->surround->margin) ||
816          !(surround->padding == other->surround->padding) ||
817          css3NonInheritedData->m_appearance != other->css3NonInheritedData->m_appearance ||
818          css3NonInheritedData->marginTopCollapse != other->css3NonInheritedData->marginTopCollapse ||
819          css3NonInheritedData->marginBottomCollapse != other->css3NonInheritedData->marginBottomCollapse ||
820          *css3NonInheritedData->flexibleBox.get() != *other->css3NonInheritedData->flexibleBox.get() ||
821          (css3NonInheritedData->lineClamp != other->css3NonInheritedData->lineClamp) ||
822          (css3InheritedData->highlight != other->css3InheritedData->highlight) ||
823          (css3InheritedData->textSizeAdjust != other->css3InheritedData->textSizeAdjust) ||
824          (css3InheritedData->wordWrap != other->css3InheritedData->wordWrap) ||
825          (css3InheritedData->nbspMode != other->css3InheritedData->nbspMode) ||
826          (css3InheritedData->khtmlLineBreak != other->css3InheritedData->khtmlLineBreak) ||
827         !(inherited->indent == other->inherited->indent) ||
828         !(inherited->line_height == other->inherited->line_height) ||
829         !(inherited->style_image == other->inherited->style_image) ||
830         !(inherited->cursorData  == other->inherited->cursorData) ||
831         !(inherited->font == other->inherited->font) ||
832         !(inherited->horizontal_border_spacing == other->inherited->horizontal_border_spacing) ||
833         !(inherited->vertical_border_spacing == other->inherited->vertical_border_spacing) ||
834         !(inherited_flags._box_direction == other->inherited_flags._box_direction) ||
835         !(inherited_flags._visuallyOrdered == other->inherited_flags._visuallyOrdered) ||
836         !(inherited_flags._htmlHacks == other->inherited_flags._htmlHacks) ||
837         !(noninherited_flags._position == other->noninherited_flags._position) ||
838         !(noninherited_flags._floating == other->noninherited_flags._floating) ||
839         !(noninherited_flags._originalDisplay == other->noninherited_flags._originalDisplay) ||
840          visual->colspan != other->visual->colspan ||
841          visual->counter_increment != other->visual->counter_increment ||
842          visual->counter_reset != other->visual->counter_reset ||
843          css3NonInheritedData->textOverflow != other->css3NonInheritedData->textOverflow ||
844          (css3InheritedData->textSecurity != other->css3InheritedData->textSecurity))
845         return Layout;
846    
847     // changes causing Layout changes:
848
849 // only for tables:
850 //     _border_collapse
851 //     EEmptyCell _empty_cells : 2 ;
852 //     ECaptionSide _caption_side : 2;
853 //     ETableLayout _table_layout : 1;
854 //     EPosition _position : 2;
855 //     EFloat _floating : 2;
856     if ( ((int)noninherited_flags._effectiveDisplay) >= TABLE ) {
857         // Stupid gcc gives a compile error on
858         // a != other->b if a and b are bitflags. Using
859         // !(a== other->b) instead.
860         if ( !(inherited_flags._border_collapse == other->inherited_flags._border_collapse) ||
861              !(inherited_flags._empty_cells == other->inherited_flags._empty_cells) ||
862              !(inherited_flags._caption_side == other->inherited_flags._caption_side) ||
863              !(noninherited_flags._table_layout == other->noninherited_flags._table_layout))
864             return Layout;
865         
866         // In the collapsing border model, 'hidden' suppresses other borders, while 'none'
867         // does not, so these style differences can be width differences.
868         if (inherited_flags._border_collapse &&
869             (borderTopStyle() == BHIDDEN && other->borderTopStyle() == BNONE ||
870              borderTopStyle() == BNONE && other->borderTopStyle() == BHIDDEN ||
871              borderBottomStyle() == BHIDDEN && other->borderBottomStyle() == BNONE ||
872              borderBottomStyle() == BNONE && other->borderBottomStyle() == BHIDDEN ||
873              borderLeftStyle() == BHIDDEN && other->borderLeftStyle() == BNONE ||
874              borderLeftStyle() == BNONE && other->borderLeftStyle() == BHIDDEN ||
875              borderRightStyle() == BHIDDEN && other->borderRightStyle() == BNONE ||
876              borderRightStyle() == BNONE && other->borderRightStyle() == BHIDDEN))
877             return Layout;
878     }
879
880 // only for lists:
881 //      EListStyleType _list_style_type : 5 ;
882 //      EListStylePosition _list_style_position :1;
883     if (noninherited_flags._effectiveDisplay == LIST_ITEM ) {
884         if ( !(inherited_flags._list_style_type == other->inherited_flags._list_style_type) ||
885              !(inherited_flags._list_style_position == other->inherited_flags._list_style_position) )
886             return Layout;
887     }
888
889 // ### These could be better optimised
890 //      ETextAlign _text_align : 3;
891 //      ETextTransform _text_transform : 4;
892 //      EDirection _direction : 1;
893 //      EWhiteSpace _white_space : 2;
894 //      EFontVariant _font_variant : 1;
895 //     EClear _clear : 2;
896     if ( !(inherited_flags._text_align == other->inherited_flags._text_align) ||
897          !(inherited_flags._text_transform == other->inherited_flags._text_transform) ||
898          !(inherited_flags._direction == other->inherited_flags._direction) ||
899          !(inherited_flags._white_space == other->inherited_flags._white_space) ||
900          !(noninherited_flags._clear == other->noninherited_flags._clear) ||
901          !css3InheritedData->shadowDataEquivalent(*other->css3InheritedData.get())
902         )
903         return Layout;
904
905     // Overflow returns a layout hint.
906     if (noninherited_flags._overflowX != other->noninherited_flags._overflowX ||
907         noninherited_flags._overflowY != other->noninherited_flags._overflowY)
908         return Layout;
909         
910 // only for inline:
911 //     EVerticalAlign _vertical_align : 4;
912
913     if ( !(noninherited_flags._effectiveDisplay == INLINE) &&
914          !(noninherited_flags._vertical_align == other->noninherited_flags._vertical_align))
915         return Layout;
916
917     // If our border widths change, then we need to layout.  Other changes to borders
918     // only necessitate a repaint.
919     if (borderLeftWidth() != other->borderLeftWidth() ||
920         borderTopWidth() != other->borderTopWidth() ||
921         borderBottomWidth() != other->borderBottomWidth() ||
922         borderRightWidth() != other->borderRightWidth())
923         return Layout;
924
925     // If regions change trigger a relayout to re-calc regions.
926     if (!(css3NonInheritedData->m_dashboardRegions == other->css3NonInheritedData->m_dashboardRegions))
927         return Layout;
928
929     // Make sure these left/top/right/bottom checks stay below all layout checks and above
930     // all visible checks.
931     if (other->position() != StaticPosition) {
932         if (!(surround->offset == other->surround->offset)) {
933             // FIXME: We will need to do a bit of work in RenderObject/Box::setStyle before we
934             // can stop doing a layout when relative positioned objects move.  In particular, we'll need
935             // to update scrolling positions and figure out how to do a repaint properly of the updated layer.
936             //if (other->position() == RelativePosition)
937             //    return RepaintLayer;
938             //else
939                 return Layout;
940         }
941         else if (box->z_index != other->box->z_index || box->z_auto != other->box->z_auto ||
942                  !(visual->clip == other->visual->clip) || visual->hasClip != other->visual->hasClip)
943             return RepaintLayer;
944     }
945
946     if (css3NonInheritedData->opacity != other->css3NonInheritedData->opacity)
947         return RepaintLayer;
948
949     // Repaint:
950 //      EVisibility _visibility : 2;
951 //      int _text_decoration : 4;
952 //     DataRef<StyleBackgroundData> background;
953     if (inherited->color != other->inherited->color ||
954         inherited_flags._visibility != other->inherited_flags._visibility ||
955         !(inherited_flags._text_decorations == other->inherited_flags._text_decorations) ||
956         !(inherited_flags._force_backgrounds_to_white == other->inherited_flags._force_backgrounds_to_white) ||
957         !(surround->border == other->surround->border) ||
958         *background.get() != *other->background.get() ||
959         visual->textDecoration != other->visual->textDecoration ||
960         css3InheritedData->userModify != other->css3InheritedData->userModify ||
961         css3NonInheritedData->userSelect != other->css3NonInheritedData->userSelect ||
962         css3NonInheritedData->userDrag != other->css3NonInheritedData->userDrag
963         )
964         return Repaint;
965
966     return Equal;
967 }
968
969 void RenderStyle::adjustBackgroundLayers()
970 {
971     if (backgroundLayers()->next()) {
972         // First we cull out layers that have no properties set.
973         accessBackgroundLayers()->cullEmptyLayers();
974         
975         // Next we repeat patterns into layers that don't have some properties set.
976         accessBackgroundLayers()->fillUnsetProperties();
977     }
978 }
979
980 void RenderStyle::setClip( Length top, Length right, Length bottom, Length left )
981 {
982     StyleVisualData *data = visual.access();
983     data->clip.top = top;
984     data->clip.right = right;
985     data->clip.bottom = bottom;
986     data->clip.left = left;
987 }
988
989 void RenderStyle::addCursor(CachedImage* image, const IntPoint& hotSpot)
990 {
991     CursorData data;
992     data.cursorImage = image;
993     data.hotSpot = hotSpot;
994     if (!inherited.access()->cursorData)
995         inherited.access()->cursorData = new CursorList;
996     inherited.access()->cursorData->append(data);
997 }
998
999 void RenderStyle::addSVGCursor(const String& fragmentId)
1000 {
1001     CursorData data;
1002     data.cursorFragmentId = fragmentId;
1003     if (!inherited.access()->cursorData)
1004         inherited.access()->cursorData = new CursorList;
1005     inherited.access()->cursorData->append(data);
1006 }
1007
1008 void RenderStyle::setCursorList(PassRefPtr<CursorList> other)
1009 {
1010     inherited.access()->cursorData = other;
1011 }
1012
1013 void RenderStyle::clearCursorList()
1014 {
1015     inherited.access()->cursorData = new CursorList;
1016 }
1017
1018 bool RenderStyle::contentDataEquivalent(const RenderStyle* otherStyle) const
1019 {
1020     ContentData* c1 = content;
1021     ContentData* c2 = otherStyle->content;
1022
1023     while (c1 && c2) {
1024         if (c1->_contentType != c2->_contentType)
1025             return false;
1026         if (c1->_contentType == CONTENT_TEXT) {
1027             String c1Str(c1->_content.text);
1028             String c2Str(c2->_content.text);
1029             if (c1Str != c2Str)
1030                 return false;
1031         }
1032         else if (c1->_contentType == CONTENT_OBJECT) {
1033             if (c1->_content.object != c2->_content.object)
1034                 return false;
1035         }
1036
1037         c1 = c1->_nextContent;
1038         c2 = c2->_nextContent;
1039     }
1040
1041     return !c1 && !c2;
1042 }
1043
1044 void RenderStyle::setContent(CachedResource* o, bool add)
1045 {
1046     if (!o)
1047         return; // The object is null. Nothing to do. Just bail.
1048
1049     ContentData* lastContent = content;
1050     while (lastContent && lastContent->_nextContent)
1051         lastContent = lastContent->_nextContent;
1052
1053     bool reuseContent = !add;
1054     ContentData* newContentData = 0;
1055     if (reuseContent && content) {
1056         content->clearContent();
1057         newContentData = content;
1058     }
1059     else
1060         newContentData = new ContentData;
1061
1062     if (lastContent && !reuseContent)
1063         lastContent->_nextContent = newContentData;
1064     else
1065         content = newContentData;
1066
1067     newContentData->_content.object = o;
1068     newContentData->_contentType = CONTENT_OBJECT;
1069 }
1070
1071 void RenderStyle::setContent(StringImpl* s, bool add)
1072 {
1073     if (!s)
1074         return; // The string is null. Nothing to do. Just bail.
1075     
1076     ContentData* lastContent = content;
1077     while (lastContent && lastContent->_nextContent)
1078         lastContent = lastContent->_nextContent;
1079
1080     bool reuseContent = !add;
1081     if (add && lastContent) {
1082         if (lastContent->_contentType == CONTENT_TEXT) {
1083             // We can augment the existing string and share this ContentData node.
1084             StringImpl* oldStr = lastContent->_content.text;
1085             StringImpl* newStr = oldStr->copy();
1086             newStr->ref();
1087             oldStr->deref();
1088             newStr->append(s);
1089             lastContent->_content.text = newStr;
1090             return;
1091         }
1092     }
1093
1094     ContentData* newContentData = 0;
1095     if (reuseContent && content) {
1096         content->clearContent();
1097         newContentData = content;
1098     }
1099     else
1100         newContentData = new ContentData;
1101     
1102     if (lastContent && !reuseContent)
1103         lastContent->_nextContent = newContentData;
1104     else
1105         content = newContentData;
1106     
1107     newContentData->_content.text = s;
1108     newContentData->_content.text->ref();
1109     newContentData->_contentType = CONTENT_TEXT;
1110 }
1111
1112 ContentData::~ContentData()
1113 {
1114     clearContent();
1115 }
1116
1117 void ContentData::clearContent()
1118 {
1119     delete _nextContent;
1120     _nextContent = 0;
1121     
1122     switch (_contentType)
1123     {
1124         case CONTENT_OBJECT:
1125             _content.object = 0;
1126             break;
1127         case CONTENT_TEXT:
1128             _content.text->deref();
1129             _content.text = 0;
1130         default:
1131             ;
1132     }
1133 }
1134
1135 #ifdef XBL_SUPPORT
1136 BindingURI::BindingURI(StringImpl* uri) 
1137 :m_next(0)
1138
1139     m_uri = uri;
1140     if (uri) uri->ref();
1141 }
1142
1143 BindingURI::~BindingURI()
1144 {
1145     if (m_uri)
1146         m_uri->deref();
1147     delete m_next;
1148 }
1149
1150 BindingURI* BindingURI::copy()
1151 {
1152     BindingURI* newBinding = new BindingURI(m_uri);
1153     if (next()) {
1154         BindingURI* nextCopy = next()->copy();
1155         newBinding->setNext(nextCopy);
1156     }
1157     
1158     return newBinding;
1159 }
1160
1161 bool BindingURI::operator==(const BindingURI& o) const
1162 {
1163     if ((m_next && !o.m_next) || (!m_next && o.m_next) ||
1164         (m_next && o.m_next && *m_next != *o.m_next))
1165         return false;
1166     
1167     if (m_uri == o.m_uri)
1168         return true;
1169     if (!m_uri || !o.m_uri)
1170         return false;
1171     
1172     return String(m_uri) == String(o.m_uri);
1173 }
1174
1175 void RenderStyle::addBindingURI(StringImpl* uri)
1176 {
1177     BindingURI* binding = new BindingURI(uri);
1178     if (!bindingURIs())
1179         SET_VAR(css3NonInheritedData, bindingURI, binding)
1180     else 
1181         for (BindingURI* b = bindingURIs(); b; b = b->next()) {
1182             if (!b->next())
1183                 b->setNext(binding);
1184         }
1185 }
1186 #endif
1187
1188 void RenderStyle::setTextShadow(ShadowData* val, bool add)
1189 {
1190     StyleCSS3InheritedData* css3Data = css3InheritedData.access(); 
1191     if (!add) {
1192         delete css3Data->textShadow;
1193         css3Data->textShadow = val;
1194         return;
1195     }
1196
1197     ShadowData* last = css3Data->textShadow;
1198     while (last->next) last = last->next;
1199     last->next = val;
1200 }
1201
1202 ShadowData::ShadowData(const ShadowData& o)
1203 :x(o.x), y(o.y), blur(o.blur), color(o.color)
1204 {
1205     next = o.next ? new ShadowData(*o.next) : 0;
1206 }
1207
1208 bool ShadowData::operator==(const ShadowData& o) const
1209 {
1210     if ((next && !o.next) || (!next && o.next) ||
1211         (next && o.next && *next != *o.next))
1212         return false;
1213     
1214     return x == o.x && y == o.y && blur == o.blur && color == o.color;
1215 }
1216
1217 const Vector<StyleDashboardRegion>& RenderStyle::initialDashboardRegions()
1218
1219     static Vector<StyleDashboardRegion> emptyList;
1220     return emptyList;
1221 }
1222
1223 const Vector<StyleDashboardRegion>& RenderStyle::noneDashboardRegions()
1224
1225     static Vector<StyleDashboardRegion> noneList;
1226     static bool noneListInitialized = false;
1227     
1228     if (!noneListInitialized) {
1229         StyleDashboardRegion region;
1230         region.label = "";
1231         region.offset.top  = Length();
1232         region.offset.right = Length();
1233         region.offset.bottom = Length();
1234         region.offset.left = Length();
1235         region.type = StyleDashboardRegion::None;
1236         noneList.append (region);
1237         noneListInitialized = true;
1238     }
1239     return noneList;
1240 }
1241
1242 }