2
* Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
3
* Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
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.
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.
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., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA.
23
#include "RenderStyle.h"
25
#include "CSSStyleSelector.h"
26
#include "RenderArena.h"
30
static RenderStyle* defaultStyle;
32
StyleSurroundData::StyleSurroundData()
33
: margin(Fixed), padding(Auto)
37
StyleSurroundData::StyleSurroundData(const StyleSurroundData& o)
38
: Shared<StyleSurroundData>()
46
bool StyleSurroundData::operator==(const StyleSurroundData& o) const
48
return offset == o.offset && margin == o.margin && padding == o.padding && border == o.border;
51
StyleBoxData::StyleBoxData()
52
: z_index(0), z_auto(true), boxSizing(CONTENT_BOX)
54
// Initialize our min/max widths/heights.
55
min_width = min_height = RenderStyle::initialMinSize();
56
max_width = max_height = RenderStyle::initialMaxSize();
59
StyleBoxData::StyleBoxData(const StyleBoxData& o)
60
: Shared<StyleBoxData>()
63
, min_width(o.min_width)
64
, max_width(o.max_width)
65
, min_height(o.min_height)
66
, max_height(o.max_height)
69
, boxSizing(o.boxSizing)
73
bool StyleBoxData::operator==(const StyleBoxData& o) const
75
return width == o.width &&
77
min_width == o.min_width &&
78
max_width == o.max_width &&
79
min_height == o.min_height &&
80
max_height == o.max_height &&
81
z_index == o.z_index &&
83
boxSizing == o.boxSizing;
86
StyleVisualData::StyleVisualData()
88
, textDecoration(RenderStyle::initialTextDecoration())
94
StyleVisualData::~StyleVisualData()
98
StyleVisualData::StyleVisualData(const StyleVisualData& o)
99
: Shared<StyleVisualData>()
102
, textDecoration(o.textDecoration)
103
, counterIncrement(o.counterIncrement)
104
, counterReset(o.counterReset)
108
BackgroundLayer::BackgroundLayer()
109
: m_image(RenderStyle::initialBackgroundImage())
110
, m_xPosition(RenderStyle::initialBackgroundXPosition())
111
, m_yPosition(RenderStyle::initialBackgroundYPosition())
112
, m_bgAttachment(RenderStyle::initialBackgroundAttachment())
113
, m_bgClip(RenderStyle::initialBackgroundClip())
114
, m_bgOrigin(RenderStyle::initialBackgroundOrigin())
115
, m_bgRepeat(RenderStyle::initialBackgroundRepeat())
116
, m_bgComposite(RenderStyle::initialBackgroundComposite())
117
, m_backgroundSize(RenderStyle::initialBackgroundSize())
119
, m_attachmentSet(false)
125
, m_compositeSet(false)
126
, m_backgroundSizeSet(false)
131
BackgroundLayer::BackgroundLayer(const BackgroundLayer& o)
133
, m_xPosition(o.m_xPosition)
134
, m_yPosition(o.m_yPosition)
135
, m_bgAttachment(o.m_bgAttachment)
136
, m_bgClip(o.m_bgClip)
137
, m_bgOrigin(o.m_bgOrigin)
138
, m_bgRepeat(o.m_bgRepeat)
139
, m_bgComposite(o.m_bgComposite)
140
, m_backgroundSize(o.m_backgroundSize)
141
, m_imageSet(o.m_imageSet)
142
, m_attachmentSet(o.m_attachmentSet)
143
, m_clipSet(o.m_clipSet)
144
, m_originSet(o.m_originSet)
145
, m_repeatSet(o.m_repeatSet)
146
, m_xPosSet(o.m_xPosSet)
147
, m_yPosSet(o.m_yPosSet)
148
, m_compositeSet(o.m_compositeSet)
149
, m_backgroundSizeSet(o.m_backgroundSizeSet)
150
, m_next(o.m_next ? new BackgroundLayer(*o.m_next) : 0)
154
BackgroundLayer::~BackgroundLayer()
159
BackgroundLayer& BackgroundLayer::operator=(const BackgroundLayer& o)
161
if (m_next != o.m_next) {
163
m_next = o.m_next ? new BackgroundLayer(*o.m_next) : 0;
167
m_xPosition = o.m_xPosition;
168
m_yPosition = o.m_yPosition;
169
m_bgAttachment = o.m_bgAttachment;
170
m_bgClip = o.m_bgClip;
171
m_bgComposite = o.m_bgComposite;
172
m_bgOrigin = o.m_bgOrigin;
173
m_bgRepeat = o.m_bgRepeat;
174
m_backgroundSize = o.m_backgroundSize;
176
m_imageSet = o.m_imageSet;
177
m_attachmentSet = o.m_attachmentSet;
178
m_clipSet = o.m_clipSet;
179
m_compositeSet = o.m_compositeSet;
180
m_originSet = o.m_originSet;
181
m_repeatSet = o.m_repeatSet;
182
m_xPosSet = o.m_xPosSet;
183
m_yPosSet = o.m_yPosSet;
184
m_backgroundSizeSet = o.m_backgroundSizeSet;
189
bool BackgroundLayer::operator==(const BackgroundLayer& o) const
191
// We do not check the "isSet" booleans for each property, since those are only used during initial construction
192
// to propagate patterns into layers. All layer comparisons happen after values have all been filled in anyway.
193
return m_image == o.m_image && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition &&
194
m_bgAttachment == o.m_bgAttachment && m_bgClip == o.m_bgClip &&
195
m_bgComposite == o.m_bgComposite && m_bgOrigin == o.m_bgOrigin && m_bgRepeat == o.m_bgRepeat &&
196
m_backgroundSize.width == o.m_backgroundSize.width && m_backgroundSize.height == o.m_backgroundSize.height &&
197
((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next);
200
void BackgroundLayer::fillUnsetProperties()
202
BackgroundLayer* curr;
203
for (curr = this; curr && curr->isBackgroundImageSet(); curr = curr->next());
204
if (curr && curr != this) {
205
// We need to fill in the remaining values with the pattern specified.
206
for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
207
curr->m_image = pattern->m_image;
208
pattern = pattern->next();
209
if (pattern == curr || !pattern)
214
for (curr = this; curr && curr->isBackgroundXPositionSet(); curr = curr->next());
215
if (curr && curr != this) {
216
// We need to fill in the remaining values with the pattern specified.
217
for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
218
curr->m_xPosition = pattern->m_xPosition;
219
pattern = pattern->next();
220
if (pattern == curr || !pattern)
225
for (curr = this; curr && curr->isBackgroundYPositionSet(); curr = curr->next());
226
if (curr && curr != this) {
227
// We need to fill in the remaining values with the pattern specified.
228
for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
229
curr->m_yPosition = pattern->m_yPosition;
230
pattern = pattern->next();
231
if (pattern == curr || !pattern)
236
for (curr = this; curr && curr->isBackgroundAttachmentSet(); curr = curr->next());
237
if (curr && curr != this) {
238
// We need to fill in the remaining values with the pattern specified.
239
for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
240
curr->m_bgAttachment = pattern->m_bgAttachment;
241
pattern = pattern->next();
242
if (pattern == curr || !pattern)
247
for (curr = this; curr && curr->isBackgroundClipSet(); curr = curr->next());
248
if (curr && curr != this) {
249
// We need to fill in the remaining values with the pattern specified.
250
for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
251
curr->m_bgClip = pattern->m_bgClip;
252
pattern = pattern->next();
253
if (pattern == curr || !pattern)
258
for (curr = this; curr && curr->isBackgroundCompositeSet(); curr = curr->next());
259
if (curr && curr != this) {
260
// We need to fill in the remaining values with the pattern specified.
261
for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
262
curr->m_bgComposite = pattern->m_bgComposite;
263
pattern = pattern->next();
264
if (pattern == curr || !pattern)
269
for (curr = this; curr && curr->isBackgroundOriginSet(); curr = curr->next());
270
if (curr && curr != this) {
271
// We need to fill in the remaining values with the pattern specified.
272
for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
273
curr->m_bgOrigin = pattern->m_bgOrigin;
274
pattern = pattern->next();
275
if (pattern == curr || !pattern)
280
for (curr = this; curr && curr->isBackgroundRepeatSet(); curr = curr->next());
281
if (curr && curr != this) {
282
// We need to fill in the remaining values with the pattern specified.
283
for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
284
curr->m_bgRepeat = pattern->m_bgRepeat;
285
pattern = pattern->next();
286
if (pattern == curr || !pattern)
291
for (curr = this; curr && curr->isBackgroundSizeSet(); curr = curr->next());
292
if (curr && curr != this) {
293
// We need to fill in the remaining values with the pattern specified.
294
for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
295
curr->m_backgroundSize = pattern->m_backgroundSize;
296
pattern = pattern->next();
297
if (pattern == curr || !pattern)
303
void BackgroundLayer::cullEmptyLayers()
305
BackgroundLayer *next;
306
for (BackgroundLayer *p = this; p; p = next) {
308
if (next && !next->isBackgroundImageSet() &&
309
!next->isBackgroundXPositionSet() && !next->isBackgroundYPositionSet() &&
310
!next->isBackgroundAttachmentSet() && !next->isBackgroundClipSet() &&
311
!next->isBackgroundCompositeSet() && !next->isBackgroundOriginSet() &&
312
!next->isBackgroundRepeatSet() && !next->isBackgroundSizeSet()) {
320
StyleBackgroundData::StyleBackgroundData()
324
StyleBackgroundData::StyleBackgroundData(const StyleBackgroundData& o)
325
: Shared<StyleBackgroundData>(), m_background(o.m_background), m_outline(o.m_outline)
329
bool StyleBackgroundData::operator==(const StyleBackgroundData& o) const
331
return m_background == o.m_background && m_color == o.m_color && m_outline == o.m_outline;
334
StyleMarqueeData::StyleMarqueeData()
335
: increment(RenderStyle::initialMarqueeIncrement())
336
, speed(RenderStyle::initialMarqueeSpeed())
337
, loops(RenderStyle::initialMarqueeLoopCount())
338
, behavior(RenderStyle::initialMarqueeBehavior())
339
, direction(RenderStyle::initialMarqueeDirection())
343
StyleMarqueeData::StyleMarqueeData(const StyleMarqueeData& o)
344
: Shared<StyleMarqueeData>()
345
, increment(o.increment)
348
, behavior(o.behavior)
349
, direction(o.direction)
353
bool StyleMarqueeData::operator==(const StyleMarqueeData& o) const
355
return increment == o.increment && speed == o.speed && direction == o.direction &&
356
behavior == o.behavior && loops == o.loops;
359
StyleFlexibleBoxData::StyleFlexibleBoxData()
360
: flex(RenderStyle::initialBoxFlex())
361
, flex_group(RenderStyle::initialBoxFlexGroup())
362
, ordinal_group(RenderStyle::initialBoxOrdinalGroup())
363
, align(RenderStyle::initialBoxAlign())
364
, pack(RenderStyle::initialBoxPack())
365
, orient(RenderStyle::initialBoxOrient())
366
, lines(RenderStyle::initialBoxLines())
370
StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& o)
371
: Shared<StyleFlexibleBoxData>()
373
, flex_group(o.flex_group)
374
, ordinal_group(o.ordinal_group)
382
bool StyleFlexibleBoxData::operator==(const StyleFlexibleBoxData& o) const
384
return flex == o.flex && flex_group == o.flex_group &&
385
ordinal_group == o.ordinal_group && align == o.align &&
386
pack == o.pack && orient == o.orient && lines == o.lines;
389
StyleMultiColData::StyleMultiColData()
391
, m_count(RenderStyle::initialColumnCount())
396
, m_breakBefore(RenderStyle::initialPageBreak())
397
, m_breakAfter(RenderStyle::initialPageBreak())
398
, m_breakInside(RenderStyle::initialPageBreak())
401
StyleMultiColData::StyleMultiColData(const StyleMultiColData& o)
402
: Shared<StyleMultiColData>()
407
, m_autoWidth(o.m_autoWidth)
408
, m_autoCount(o.m_autoCount)
409
, m_normalGap(o.m_normalGap)
410
, m_breakBefore(o.m_breakBefore)
411
, m_breakAfter(o.m_breakAfter)
412
, m_breakInside(o.m_breakInside)
415
bool StyleMultiColData::operator==(const StyleMultiColData& o) const
417
return m_width == o.m_width && m_count == o.m_count && m_gap == o.m_gap &&
418
m_rule == o.m_rule && m_breakBefore == o.m_breakBefore &&
419
m_autoWidth == o.m_autoWidth && m_autoCount == o.m_autoCount && m_normalGap == o.m_normalGap &&
420
m_breakAfter == o.m_breakAfter && m_breakInside == o.m_breakInside;
423
StyleRareNonInheritedData::StyleRareNonInheritedData()
424
: lineClamp(RenderStyle::initialLineClamp())
425
, opacity(RenderStyle::initialOpacity())
427
, m_counterDirectives(0)
428
, userDrag(RenderStyle::initialUserDrag())
429
, textOverflow(RenderStyle::initialTextOverflow())
430
, marginTopCollapse(MCOLLAPSE)
431
, marginBottomCollapse(MCOLLAPSE)
432
, matchNearestMailBlockquoteColor(RenderStyle::initialMatchNearestMailBlockquoteColor())
433
, m_appearance(RenderStyle::initialAppearance())
434
, m_borderFit(RenderStyle::initialBorderFit())
442
StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInheritedData& o)
443
: Shared<StyleRareNonInheritedData>()
444
, lineClamp(o.lineClamp)
446
, flexibleBox(o.flexibleBox)
448
, m_multiCol(o.m_multiCol)
450
, m_counterDirectives(0)
451
, userDrag(o.userDrag)
452
, textOverflow(o.textOverflow)
453
, marginTopCollapse(o.marginTopCollapse)
454
, marginBottomCollapse(o.marginBottomCollapse)
455
, matchNearestMailBlockquoteColor(o.matchNearestMailBlockquoteColor)
456
, m_appearance(o.m_appearance)
457
, m_borderFit(o.m_borderFit)
458
, m_boxShadow(o.m_boxShadow ? new ShadowData(*o.m_boxShadow) : 0)
460
, bindingURI(o.bindingURI ? o.bindingURI->copy() : 0)
465
StyleRareNonInheritedData::~StyleRareNonInheritedData()
468
delete m_counterDirectives;
476
bool StyleRareNonInheritedData::bindingsEquivalent(const StyleRareNonInheritedData& o) const
478
if (this == &o) return true;
479
if (!bindingURI && o.bindingURI || bindingURI && !o.bindingURI)
481
if (bindingURI && o.bindingURI && (*bindingURI != *o.bindingURI))
487
bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) const
489
return lineClamp == o.lineClamp
490
&& m_dashboardRegions == o.m_dashboardRegions
491
&& opacity == o.opacity
492
&& flexibleBox == o.flexibleBox
493
&& marquee == o.marquee
494
&& m_multiCol == o.m_multiCol
495
&& m_content == o.m_content
496
&& m_counterDirectives == o.m_counterDirectives
497
&& userDrag == o.userDrag
498
&& textOverflow == o.textOverflow
499
&& marginTopCollapse == o.marginTopCollapse
500
&& marginBottomCollapse == o.marginBottomCollapse
501
&& matchNearestMailBlockquoteColor == o.matchNearestMailBlockquoteColor
502
&& m_appearance == o.m_appearance
503
&& m_borderFit == o.m_borderFit
504
&& shadowDataEquivalent(o)
506
&& bindingsEquivalent(o)
511
bool StyleRareNonInheritedData::shadowDataEquivalent(const StyleRareNonInheritedData& o) const
513
if (!m_boxShadow && o.m_boxShadow || m_boxShadow && !o.m_boxShadow)
515
if (m_boxShadow && o.m_boxShadow && (*m_boxShadow != *o.m_boxShadow))
520
StyleRareInheritedData::StyleRareInheritedData()
521
: textStrokeWidth(RenderStyle::initialTextStrokeWidth())
523
, textSecurity(RenderStyle::initialTextSecurity())
524
, userModify(READ_ONLY)
525
, wordBreak(RenderStyle::initialWordBreak())
526
, wordWrap(RenderStyle::initialWordWrap())
528
, khtmlLineBreak(LBNORMAL)
529
, textSizeAdjust(RenderStyle::initialTextSizeAdjust())
530
, resize(RenderStyle::initialResize())
531
, userSelect(RenderStyle::initialUserSelect())
535
StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
536
: Shared<StyleRareInheritedData>()
537
, textStrokeColor(o.textStrokeColor)
538
, textStrokeWidth(o.textStrokeWidth)
539
, textFillColor(o.textFillColor)
540
, textShadow(o.textShadow ? new ShadowData(*o.textShadow) : 0)
541
, highlight(o.highlight)
542
, textSecurity(o.textSecurity)
543
, userModify(o.userModify)
544
, wordBreak(o.wordBreak)
545
, wordWrap(o.wordWrap)
546
, nbspMode(o.nbspMode)
547
, khtmlLineBreak(o.khtmlLineBreak)
548
, textSizeAdjust(o.textSizeAdjust)
550
, userSelect(o.userSelect)
554
StyleRareInheritedData::~StyleRareInheritedData()
559
bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
561
return textStrokeColor == o.textStrokeColor
562
&& textStrokeWidth == o.textStrokeWidth
563
&& textFillColor == o.textFillColor
564
&& shadowDataEquivalent(o)
565
&& highlight == o.highlight
566
&& textSecurity == o.textSecurity
567
&& userModify == o.userModify
568
&& wordBreak == o.wordBreak
569
&& wordWrap == o.wordWrap
570
&& nbspMode == o.nbspMode
571
&& khtmlLineBreak == o.khtmlLineBreak
572
&& textSizeAdjust == o.textSizeAdjust
573
&& userSelect == o.userSelect;
576
bool StyleRareInheritedData::shadowDataEquivalent(const StyleRareInheritedData& o) const
578
if (!textShadow && o.textShadow || textShadow && !o.textShadow)
580
if (textShadow && o.textShadow && (*textShadow != *o.textShadow))
585
StyleInheritedData::StyleInheritedData()
586
: indent(RenderStyle::initialTextIndent()), line_height(RenderStyle::initialLineHeight()),
587
style_image(RenderStyle::initialListStyleImage()),
588
color(RenderStyle::initialColor()),
589
horizontal_border_spacing(RenderStyle::initialHorizontalBorderSpacing()),
590
vertical_border_spacing(RenderStyle::initialVerticalBorderSpacing()),
591
widows(RenderStyle::initialWidows()), orphans(RenderStyle::initialOrphans()),
592
page_break_inside(RenderStyle::initialPageBreak())
596
StyleInheritedData::~StyleInheritedData()
600
StyleInheritedData::StyleInheritedData(const StyleInheritedData& o)
601
: Shared<StyleInheritedData>(),
602
indent( o.indent ), line_height( o.line_height ), style_image( o.style_image ),
603
cursorData(o.cursorData),
604
font( o.font ), color( o.color ),
605
horizontal_border_spacing( o.horizontal_border_spacing ),
606
vertical_border_spacing( o.vertical_border_spacing ),
607
widows(o.widows), orphans(o.orphans), page_break_inside(o.page_break_inside)
611
static bool cursorDataEqvuialent(const CursorList* c1, const CursorList* c2)
615
if (!c1 && c2 || c1 && !c2)
620
bool StyleInheritedData::operator==(const StyleInheritedData& o) const
623
indent == o.indent &&
624
line_height == o.line_height &&
625
style_image == o.style_image &&
626
cursorDataEqvuialent(cursorData.get(), o.cursorData.get()) &&
629
horizontal_border_spacing == o.horizontal_border_spacing &&
630
vertical_border_spacing == o.vertical_border_spacing &&
631
widows == o.widows &&
632
orphans == o.orphans &&
633
page_break_inside == o.page_break_inside;
636
bool CursorList::operator==(const CursorList& other) const
638
// If the lists aren't the same size, then they can't be equivalent.
639
if (size() != other.size())
642
for (unsigned i = 0; i < size(); i++) {
643
if (m_vector[i] != other.m_vector[i])
651
static inline bool operator!=(const CounterContent& a, const CounterContent& b)
653
return a.identifier() != b.identifier()
654
|| a.listStyle() != b.listStyle()
655
|| a.separator() != b.separator();
658
// ----------------------------------------------------------
660
void* RenderStyle::operator new(size_t sz, RenderArena* renderArena) throw()
662
return renderArena->allocate(sz);
665
void RenderStyle::operator delete(void* ptr, size_t sz)
667
// Stash size where destroy can find it.
671
void RenderStyle::arenaDelete(RenderArena *arena)
673
RenderStyle *ps = pseudoStyle;
674
RenderStyle *prev = 0;
678
ps = ps->pseudoStyle;
679
// to prevent a double deletion.
680
// this works only because the styles below aren't really shared
681
// Dirk said we need another construct as soon as these are shared
682
prev->pseudoStyle = 0;
687
// Recover the size left there for us by operator delete and free the memory.
688
arena->free(*(size_t *)this, this);
691
inline RenderStyle *initDefaultStyle()
694
defaultStyle = ::new RenderStyle(true);
698
RenderStyle::RenderStyle()
699
: box(initDefaultStyle()->box)
700
, visual(defaultStyle->visual)
701
, background(defaultStyle->background)
702
, surround(defaultStyle->surround)
703
, rareNonInheritedData(defaultStyle->rareNonInheritedData)
704
, rareInheritedData(defaultStyle->rareInheritedData)
705
, inherited(defaultStyle->inherited)
707
, m_pseudoState(PseudoUnknown)
708
, m_affectedByAttributeSelectors(false)
712
, m_svgStyle(defaultStyle->m_svgStyle)
715
setBitDefaults(); // Would it be faster to copy this from the default style?
718
RenderStyle::RenderStyle(bool)
720
, m_pseudoState(PseudoUnknown)
721
, m_affectedByAttributeSelectors(false)
731
rareNonInheritedData.init();
732
rareNonInheritedData.access()->flexibleBox.init();
733
rareNonInheritedData.access()->marquee.init();
734
rareNonInheritedData.access()->m_multiCol.init();
735
rareInheritedData.init();
743
RenderStyle::RenderStyle(const RenderStyle& o)
744
: inherited_flags(o.inherited_flags)
745
, noninherited_flags(o.noninherited_flags)
748
, background(o.background)
749
, surround(o.surround)
750
, rareNonInheritedData(o.rareNonInheritedData)
751
, rareInheritedData(o.rareInheritedData)
752
, inherited(o.inherited)
754
, m_pseudoState(o.m_pseudoState)
755
, m_affectedByAttributeSelectors(false)
759
, m_svgStyle(o.m_svgStyle)
764
void RenderStyle::inheritFrom(const RenderStyle* inheritParent)
766
rareInheritedData = inheritParent->rareInheritedData;
767
inherited = inheritParent->inherited;
768
inherited_flags = inheritParent->inherited_flags;
770
if (m_svgStyle != inheritParent->m_svgStyle)
771
m_svgStyle.access()->inheritFrom(inheritParent->m_svgStyle.get());
775
RenderStyle::~RenderStyle()
779
bool RenderStyle::operator==(const RenderStyle& o) const
781
// compare everything except the pseudoStyle pointer
782
return inherited_flags == o.inherited_flags &&
783
noninherited_flags == o.noninherited_flags &&
785
visual == o.visual &&
786
background == o.background &&
787
surround == o.surround &&
788
rareNonInheritedData == o.rareNonInheritedData &&
789
rareInheritedData == o.rareInheritedData &&
790
inherited == o.inherited
792
&& m_svgStyle == o.m_svgStyle
797
bool RenderStyle::isStyleAvailable() const
799
return this != CSSStyleSelector::styleNotYetAvailable;
802
enum EPseudoBit { NO_BIT = 0x0, BEFORE_BIT = 0x1, AFTER_BIT = 0x2, FIRST_LINE_BIT = 0x4,
803
FIRST_LETTER_BIT = 0x8, SELECTION_BIT = 0x10, FIRST_LINE_INHERITED_BIT = 0x20,
804
FILE_UPLOAD_BUTTON_BIT = 0x40, SLIDER_THUMB_BIT = 0x80, SEARCH_CANCEL_BUTTON_BIT = 0x100, SEARCH_DECORATION_BIT = 0x200,
805
SEARCH_RESULTS_DECORATION_BIT = 0x400, SEARCH_RESULTS_BUTTON_BIT = 0x800 };
807
static inline int pseudoBit(RenderStyle::PseudoId pseudo)
810
case RenderStyle::BEFORE:
812
case RenderStyle::AFTER:
814
case RenderStyle::FIRST_LINE:
815
return FIRST_LINE_BIT;
816
case RenderStyle::FIRST_LETTER:
817
return FIRST_LETTER_BIT;
818
case RenderStyle::SELECTION:
819
return SELECTION_BIT;
820
case RenderStyle::FIRST_LINE_INHERITED:
821
return FIRST_LINE_INHERITED_BIT;
822
case RenderStyle::FILE_UPLOAD_BUTTON:
823
return FILE_UPLOAD_BUTTON_BIT;
824
case RenderStyle::SLIDER_THUMB:
825
return SLIDER_THUMB_BIT;
826
case RenderStyle::SEARCH_CANCEL_BUTTON:
827
return SEARCH_CANCEL_BUTTON_BIT;
828
case RenderStyle::SEARCH_DECORATION:
829
return SEARCH_DECORATION_BIT;
830
case RenderStyle::SEARCH_RESULTS_DECORATION:
831
return SEARCH_RESULTS_DECORATION_BIT;
832
case RenderStyle::SEARCH_RESULTS_BUTTON:
833
return SEARCH_RESULTS_BUTTON_BIT;
839
bool RenderStyle::hasPseudoStyle(PseudoId pseudo) const
841
return pseudoBit(pseudo) & noninherited_flags._pseudoBits;
844
void RenderStyle::setHasPseudoStyle(PseudoId pseudo)
846
noninherited_flags._pseudoBits |= pseudoBit(pseudo);
849
RenderStyle* RenderStyle::getPseudoStyle(PseudoId pid)
851
if (!pseudoStyle || styleType() != NOPSEUDO)
853
RenderStyle* ps = pseudoStyle;
854
while (ps && ps->styleType() != pid)
855
ps = ps->pseudoStyle;
859
void RenderStyle::addPseudoStyle(RenderStyle* pseudo)
864
pseudo->pseudoStyle = pseudoStyle;
865
pseudoStyle = pseudo;
868
bool RenderStyle::inheritedNotEqual(RenderStyle* other) const
870
return inherited_flags != other->inherited_flags ||
871
inherited != other->inherited ||
873
m_svgStyle->inheritedNotEqual(other->m_svgStyle.get()) ||
875
rareInheritedData != other->rareInheritedData;
879
compares two styles. The result gives an idea of the action that
880
needs to be taken when replacing the old style with a new one.
882
CbLayout: The containing block of the object needs a relayout.
883
Layout: the RenderObject needs a relayout after the style change
884
Visible: The change is visible, but no relayout is needed
885
NonVisible: The object does need neither repaint nor relayout after
889
A lot can be optimised here based on the display type, lots of
890
optimisations are unimplemented, and currently result in the
891
worst case result causing a relayout of the containing block.
893
RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
896
// This is horribly inefficient. Eventually we'll have to integrate
897
// this more directly by calling: Diff svgDiff = svgStyle->diff(other)
898
// and then checking svgDiff and returning from the appropriate places below.
899
if (m_svgStyle != other->m_svgStyle)
903
if (box->width != other->box->width ||
904
box->min_width != other->box->min_width ||
905
box->max_width != other->box->max_width ||
906
box->height != other->box->height ||
907
box->min_height != other->box->min_height ||
908
box->max_height != other->box->max_height)
911
if (box->vertical_align != other->box->vertical_align || noninherited_flags._vertical_align != other->noninherited_flags._vertical_align)
914
if (box->boxSizing != other->box->boxSizing)
917
if (surround->margin != other->surround->margin)
920
if (surround->padding != other->surround->padding)
923
if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
924
if (rareNonInheritedData->m_appearance != other->rareNonInheritedData->m_appearance ||
925
rareNonInheritedData->marginTopCollapse != other->rareNonInheritedData->marginTopCollapse ||
926
rareNonInheritedData->marginBottomCollapse != other->rareNonInheritedData->marginBottomCollapse ||
927
rareNonInheritedData->lineClamp != other->rareNonInheritedData->lineClamp ||
928
rareNonInheritedData->textOverflow != other->rareNonInheritedData->textOverflow)
931
if (rareNonInheritedData->flexibleBox.get() != other->rareNonInheritedData->flexibleBox.get() &&
932
*rareNonInheritedData->flexibleBox.get() != *other->rareNonInheritedData->flexibleBox.get())
935
if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get()))
938
if (rareNonInheritedData->m_multiCol.get() != other->rareNonInheritedData->m_multiCol.get() &&
939
*rareNonInheritedData->m_multiCol.get() != *other->rareNonInheritedData->m_multiCol.get())
942
// If regions change trigger a relayout to re-calc regions.
943
if (rareNonInheritedData->m_dashboardRegions != other->rareNonInheritedData->m_dashboardRegions)
947
if (rareInheritedData.get() != other->rareInheritedData.get()) {
948
if (rareInheritedData->highlight != other->rareInheritedData->highlight ||
949
rareInheritedData->textSizeAdjust != other->rareInheritedData->textSizeAdjust ||
950
rareInheritedData->wordBreak != other->rareInheritedData->wordBreak ||
951
rareInheritedData->wordWrap != other->rareInheritedData->wordWrap ||
952
rareInheritedData->nbspMode != other->rareInheritedData->nbspMode ||
953
rareInheritedData->khtmlLineBreak != other->rareInheritedData->khtmlLineBreak ||
954
rareInheritedData->textSecurity != other->rareInheritedData->textSecurity)
957
if (!rareInheritedData->shadowDataEquivalent(*other->rareInheritedData.get()))
960
if (textStrokeWidth() != other->textStrokeWidth())
964
if (inherited->indent != other->inherited->indent ||
965
inherited->line_height != other->inherited->line_height ||
966
inherited->style_image != other->inherited->style_image ||
967
inherited->font != other->inherited->font ||
968
inherited->horizontal_border_spacing != other->inherited->horizontal_border_spacing ||
969
inherited->vertical_border_spacing != other->inherited->vertical_border_spacing ||
970
inherited_flags._box_direction != other->inherited_flags._box_direction ||
971
inherited_flags._visuallyOrdered != other->inherited_flags._visuallyOrdered ||
972
inherited_flags._htmlHacks != other->inherited_flags._htmlHacks ||
973
noninherited_flags._position != other->noninherited_flags._position ||
974
noninherited_flags._floating != other->noninherited_flags._floating ||
975
noninherited_flags._originalDisplay != other->noninherited_flags._originalDisplay)
979
if (((int)noninherited_flags._effectiveDisplay) >= TABLE) {
980
if (inherited_flags._border_collapse != other->inherited_flags._border_collapse ||
981
inherited_flags._empty_cells != other->inherited_flags._empty_cells ||
982
inherited_flags._caption_side != other->inherited_flags._caption_side ||
983
noninherited_flags._table_layout != other->noninherited_flags._table_layout)
986
// In the collapsing border model, 'hidden' suppresses other borders, while 'none'
987
// does not, so these style differences can be width differences.
988
if (inherited_flags._border_collapse &&
989
(borderTopStyle() == BHIDDEN && other->borderTopStyle() == BNONE ||
990
borderTopStyle() == BNONE && other->borderTopStyle() == BHIDDEN ||
991
borderBottomStyle() == BHIDDEN && other->borderBottomStyle() == BNONE ||
992
borderBottomStyle() == BNONE && other->borderBottomStyle() == BHIDDEN ||
993
borderLeftStyle() == BHIDDEN && other->borderLeftStyle() == BNONE ||
994
borderLeftStyle() == BNONE && other->borderLeftStyle() == BHIDDEN ||
995
borderRightStyle() == BHIDDEN && other->borderRightStyle() == BNONE ||
996
borderRightStyle() == BNONE && other->borderRightStyle() == BHIDDEN))
1000
if (noninherited_flags._effectiveDisplay == LIST_ITEM) {
1001
if (inherited_flags._list_style_type != other->inherited_flags._list_style_type ||
1002
inherited_flags._list_style_position != other->inherited_flags._list_style_position)
1006
if (inherited_flags._text_align != other->inherited_flags._text_align ||
1007
inherited_flags._text_transform != other->inherited_flags._text_transform ||
1008
inherited_flags._direction != other->inherited_flags._direction ||
1009
inherited_flags._white_space != other->inherited_flags._white_space ||
1010
noninherited_flags._clear != other->noninherited_flags._clear)
1013
// Overflow returns a layout hint.
1014
if (noninherited_flags._overflowX != other->noninherited_flags._overflowX ||
1015
noninherited_flags._overflowY != other->noninherited_flags._overflowY)
1018
// If our border widths change, then we need to layout. Other changes to borders
1019
// only necessitate a repaint.
1020
if (borderLeftWidth() != other->borderLeftWidth() ||
1021
borderTopWidth() != other->borderTopWidth() ||
1022
borderBottomWidth() != other->borderBottomWidth() ||
1023
borderRightWidth() != other->borderRightWidth())
1026
// If the counter directives change, trigger a relayout to re-calculate counter values and rebuild the counter node tree.
1027
const CounterDirectiveMap* mapA = rareNonInheritedData->m_counterDirectives;
1028
const CounterDirectiveMap* mapB = other->rareNonInheritedData->m_counterDirectives;
1029
if (!(mapA == mapB || (mapA && mapB && *mapA == *mapB)))
1031
if (visual->counterIncrement != other->visual->counterIncrement ||
1032
visual->counterReset != other->visual->counterReset)
1035
// Make sure these left/top/right/bottom checks stay below all layout checks and above
1036
// all visible checks.
1037
if (other->position() != StaticPosition) {
1038
if (surround->offset != other->surround->offset) {
1039
// FIXME: We will need to do a bit of work in RenderObject/Box::setStyle before we
1040
// can stop doing a layout when relative positioned objects move. In particular, we'll need
1041
// to update scrolling positions and figure out how to do a repaint properly of the updated layer.
1042
//if (other->position() == RelativePosition)
1043
// return RepaintLayer;
1047
else if (box->z_index != other->box->z_index || box->z_auto != other->box->z_auto ||
1048
visual->clip != other->visual->clip || visual->hasClip != other->visual->hasClip)
1049
return RepaintLayer;
1052
if (rareNonInheritedData->opacity != other->rareNonInheritedData->opacity)
1053
return RepaintLayer;
1055
if (inherited->color != other->inherited->color ||
1056
inherited_flags._visibility != other->inherited_flags._visibility ||
1057
inherited_flags._text_decorations != other->inherited_flags._text_decorations ||
1058
inherited_flags._force_backgrounds_to_white != other->inherited_flags._force_backgrounds_to_white ||
1059
surround->border != other->surround->border ||
1060
*background.get() != *other->background.get() ||
1061
visual->textDecoration != other->visual->textDecoration ||
1062
rareInheritedData->userModify != other->rareInheritedData->userModify ||
1063
rareInheritedData->userSelect != other->rareInheritedData->userSelect ||
1064
rareNonInheritedData->userDrag != other->rareNonInheritedData->userDrag ||
1065
rareNonInheritedData->m_borderFit != other->rareNonInheritedData->m_borderFit ||
1066
rareInheritedData->textFillColor != other->rareInheritedData->textFillColor ||
1067
rareInheritedData->textStrokeColor != other->rareInheritedData->textStrokeColor)
1070
// Cursors are not checked, since they will be set appropriately in response to mouse events,
1071
// so they don't need to cause any repaint or layout.
1076
void RenderStyle::adjustBackgroundLayers()
1078
if (backgroundLayers()->next()) {
1079
// First we cull out layers that have no properties set.
1080
accessBackgroundLayers()->cullEmptyLayers();
1082
// Next we repeat patterns into layers that don't have some properties set.
1083
accessBackgroundLayers()->fillUnsetProperties();
1087
void RenderStyle::setClip( Length top, Length right, Length bottom, Length left )
1089
StyleVisualData *data = visual.access();
1090
data->clip.top = top;
1091
data->clip.right = right;
1092
data->clip.bottom = bottom;
1093
data->clip.left = left;
1096
void RenderStyle::addCursor(CachedImage* image, const IntPoint& hotSpot)
1099
data.cursorImage = image;
1100
data.hotSpot = hotSpot;
1101
if (!inherited.access()->cursorData)
1102
inherited.access()->cursorData = new CursorList;
1103
inherited.access()->cursorData->append(data);
1106
void RenderStyle::addSVGCursor(const String& fragmentId)
1109
data.cursorFragmentId = fragmentId;
1110
if (!inherited.access()->cursorData)
1111
inherited.access()->cursorData = new CursorList;
1112
inherited.access()->cursorData->append(data);
1115
void RenderStyle::setCursorList(PassRefPtr<CursorList> other)
1117
inherited.access()->cursorData = other;
1120
void RenderStyle::clearCursorList()
1122
inherited.access()->cursorData = new CursorList;
1125
bool RenderStyle::contentDataEquivalent(const RenderStyle* otherStyle) const
1127
ContentData* c1 = rareNonInheritedData->m_content;
1128
ContentData* c2 = otherStyle->rareNonInheritedData->m_content;
1131
if (c1->m_type != c2->m_type)
1134
switch (c1->m_type) {
1138
if (!equal(c1->m_content.m_text, c2->m_content.m_text))
1141
case CONTENT_OBJECT:
1142
if (c1->m_content.m_object != c2->m_content.m_object)
1145
case CONTENT_COUNTER:
1146
if (*c1->m_content.m_counter != *c2->m_content.m_counter)
1158
void RenderStyle::clearContent()
1160
if (rareNonInheritedData->m_content)
1161
rareNonInheritedData->m_content->clear();
1164
void RenderStyle::setContent(CachedResource* o, bool add)
1167
return; // The object is null. Nothing to do. Just bail.
1169
ContentData*& content = rareNonInheritedData.access()->m_content;
1170
ContentData* lastContent = content;
1171
while (lastContent && lastContent->m_next)
1172
lastContent = lastContent->m_next;
1174
bool reuseContent = !add;
1175
ContentData* newContentData = 0;
1176
if (reuseContent && content) {
1178
newContentData = content;
1180
newContentData = new ContentData;
1182
if (lastContent && !reuseContent)
1183
lastContent->m_next = newContentData;
1185
content = newContentData;
1187
newContentData->m_content.m_object = o;
1188
newContentData->m_type = CONTENT_OBJECT;
1191
void RenderStyle::setContent(StringImpl* s, bool add)
1194
return; // The string is null. Nothing to do. Just bail.
1196
ContentData*& content = rareNonInheritedData.access()->m_content;
1197
ContentData* lastContent = content;
1198
while (lastContent && lastContent->m_next)
1199
lastContent = lastContent->m_next;
1201
bool reuseContent = !add;
1202
if (add && lastContent) {
1203
if (lastContent->m_type == CONTENT_TEXT) {
1204
// We can augment the existing string and share this ContentData node.
1205
StringImpl* oldStr = lastContent->m_content.m_text;
1206
StringImpl* newStr = oldStr->copy();
1210
lastContent->m_content.m_text = newStr;
1215
ContentData* newContentData = 0;
1216
if (reuseContent && content) {
1218
newContentData = content;
1220
newContentData = new ContentData;
1222
if (lastContent && !reuseContent)
1223
lastContent->m_next = newContentData;
1225
content = newContentData;
1227
newContentData->m_content.m_text = s;
1228
newContentData->m_content.m_text->ref();
1229
newContentData->m_type = CONTENT_TEXT;
1232
void RenderStyle::setContent(CounterContent* c, bool add)
1237
ContentData*& content = rareNonInheritedData.access()->m_content;
1238
ContentData* lastContent = content;
1239
while (lastContent && lastContent->m_next)
1240
lastContent = lastContent->m_next;
1242
bool reuseContent = !add;
1243
ContentData* newContentData = 0;
1244
if (reuseContent && content) {
1246
newContentData = content;
1248
newContentData = new ContentData;
1250
if (lastContent && !reuseContent)
1251
lastContent->m_next = newContentData;
1253
content = newContentData;
1255
newContentData->m_content.m_counter = c;
1256
newContentData->m_type = CONTENT_COUNTER;
1259
void ContentData::clear()
1263
case CONTENT_OBJECT:
1266
m_content.m_text->deref();
1268
case CONTENT_COUNTER:
1269
delete m_content.m_counter;
1273
ContentData* n = m_next;
1274
m_type = CONTENT_NONE;
1277
// Reverse the list so we can delete without recursing.
1278
ContentData* last = 0;
1285
for (c = last; c; c = n) {
1293
BindingURI::BindingURI(StringImpl* uri)
1297
if (uri) uri->ref();
1300
BindingURI::~BindingURI()
1307
BindingURI* BindingURI::copy()
1309
BindingURI* newBinding = new BindingURI(m_uri);
1311
BindingURI* nextCopy = next()->copy();
1312
newBinding->setNext(nextCopy);
1318
bool BindingURI::operator==(const BindingURI& o) const
1320
if ((m_next && !o.m_next) || (!m_next && o.m_next) ||
1321
(m_next && o.m_next && *m_next != *o.m_next))
1324
if (m_uri == o.m_uri)
1326
if (!m_uri || !o.m_uri)
1329
return String(m_uri) == String(o.m_uri);
1332
void RenderStyle::addBindingURI(StringImpl* uri)
1334
BindingURI* binding = new BindingURI(uri);
1336
SET_VAR(rareNonInheritedData, bindingURI, binding)
1338
for (BindingURI* b = bindingURIs(); b; b = b->next()) {
1340
b->setNext(binding);
1345
void RenderStyle::setTextShadow(ShadowData* val, bool add)
1347
StyleRareInheritedData* rareData = rareInheritedData.access();
1349
delete rareData->textShadow;
1350
rareData->textShadow = val;
1354
ShadowData* last = rareData->textShadow;
1355
while (last->next) last = last->next;
1359
void RenderStyle::setBoxShadow(ShadowData* val, bool add)
1361
StyleRareNonInheritedData* rareData = rareNonInheritedData.access();
1363
delete rareData->m_boxShadow;
1364
rareData->m_boxShadow = val;
1368
ShadowData* last = rareData->m_boxShadow;
1369
while (last->next) last = last->next;
1373
ShadowData::ShadowData(const ShadowData& o)
1374
:x(o.x), y(o.y), blur(o.blur), color(o.color)
1376
next = o.next ? new ShadowData(*o.next) : 0;
1379
bool ShadowData::operator==(const ShadowData& o) const
1381
if ((next && !o.next) || (!next && o.next) ||
1382
(next && o.next && *next != *o.next))
1385
return x == o.x && y == o.y && blur == o.blur && color == o.color;
1388
bool operator==(const CounterDirectives& a, const CounterDirectives& b)
1390
if (a.m_reset != b.m_reset || a.m_increment != b.m_increment)
1392
if (a.m_reset && a.m_resetValue != b.m_resetValue)
1394
if (a.m_increment && a.m_incrementValue != b.m_incrementValue)
1399
const CounterDirectiveMap* RenderStyle::counterDirectives() const
1401
return rareNonInheritedData->m_counterDirectives;
1404
CounterDirectiveMap& RenderStyle::accessCounterDirectives()
1406
CounterDirectiveMap*& map = rareNonInheritedData.access()->m_counterDirectives;
1408
map = new CounterDirectiveMap;
1412
const Vector<StyleDashboardRegion>& RenderStyle::initialDashboardRegions()
1414
static Vector<StyleDashboardRegion> emptyList;
1418
const Vector<StyleDashboardRegion>& RenderStyle::noneDashboardRegions()
1420
static Vector<StyleDashboardRegion> noneList;
1421
static bool noneListInitialized = false;
1423
if (!noneListInitialized) {
1424
StyleDashboardRegion region;
1426
region.offset.top = Length();
1427
region.offset.right = Length();
1428
region.offset.bottom = Length();
1429
region.offset.left = Length();
1430
region.type = StyleDashboardRegion::None;
1431
noneList.append (region);
1432
noneListInitialized = true;