~ubuntu-branches/ubuntu/maverick/webkit/maverick

« back to all changes in this revision

Viewing changes to WebCore/rendering/RenderStyle.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey
  • Date: 2007-08-19 15:54:12 UTC
  • Revision ID: james.westby@ubuntu.com-20070819155412-uxxg1h9plpghmtbi
Tags: upstream-0~svn25144
ImportĀ upstreamĀ versionĀ 0~svn25144

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
 
3
 * Copyright (C) 2004, 2005, 2006, 2007 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., 59 Temple Place - Suite 330,
 
18
 * Boston, MA 02111-1307, USA.
 
19
 *
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
#include "RenderStyle.h"
 
24
 
 
25
#include "CSSStyleSelector.h"
 
26
#include "RenderArena.h"
 
27
 
 
28
namespace WebCore {
 
29
 
 
30
static RenderStyle* defaultStyle;
 
31
 
 
32
StyleSurroundData::StyleSurroundData()
 
33
    : margin(Fixed), padding(Auto)
 
34
{
 
35
}
 
36
 
 
37
StyleSurroundData::StyleSurroundData(const StyleSurroundData& o)
 
38
    : Shared<StyleSurroundData>()
 
39
    , offset(o.offset)
 
40
    , margin(o.margin)
 
41
    , padding(o.padding)
 
42
    , border(o.border)
 
43
{
 
44
}
 
45
 
 
46
bool StyleSurroundData::operator==(const StyleSurroundData& o) const
 
47
{
 
48
    return offset == o.offset && margin == o.margin && padding == o.padding && border == o.border;
 
49
}
 
50
 
 
51
StyleBoxData::StyleBoxData()
 
52
    : z_index(0), z_auto(true), boxSizing(CONTENT_BOX)
 
53
{
 
54
    // Initialize our min/max widths/heights.
 
55
    min_width = min_height = RenderStyle::initialMinSize();
 
56
    max_width = max_height = RenderStyle::initialMaxSize();
 
57
}
 
58
 
 
59
StyleBoxData::StyleBoxData(const StyleBoxData& o)
 
60
    : Shared<StyleBoxData>()
 
61
    , width(o.width)
 
62
    , height(o.height)
 
63
    , min_width(o.min_width)
 
64
    , max_width(o.max_width)
 
65
    , min_height(o.min_height)
 
66
    , max_height(o.max_height)
 
67
    , z_index(o.z_index)
 
68
    , z_auto(o.z_auto)
 
69
    , boxSizing(o.boxSizing)
 
70
{
 
71
}
 
72
 
 
73
bool StyleBoxData::operator==(const StyleBoxData& o) const
 
74
{
 
75
    return width == o.width &&
 
76
           height == o.height &&
 
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 &&
 
82
           z_auto == o.z_auto &&
 
83
           boxSizing == o.boxSizing;
 
84
}
 
85
 
 
86
StyleVisualData::StyleVisualData()
 
87
    : hasClip(false)
 
88
    , textDecoration(RenderStyle::initialTextDecoration())
 
89
    , counterIncrement(0)
 
90
    , counterReset(0)
 
91
{
 
92
}
 
93
 
 
94
StyleVisualData::~StyleVisualData()
 
95
{
 
96
}
 
97
 
 
98
StyleVisualData::StyleVisualData(const StyleVisualData& o)
 
99
    : Shared<StyleVisualData>()
 
100
    , clip(o.clip)
 
101
    , hasClip(o.hasClip)
 
102
    , textDecoration(o.textDecoration)
 
103
    , counterIncrement(o.counterIncrement)
 
104
    , counterReset(o.counterReset)
 
105
{
 
106
}
 
107
 
 
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())
 
118
    , m_imageSet(false)
 
119
    , m_attachmentSet(false)
 
120
    , m_clipSet(false)
 
121
    , m_originSet(false)
 
122
    , m_repeatSet(false)
 
123
    , m_xPosSet(false)
 
124
    , m_yPosSet(false)
 
125
    , m_compositeSet(false)
 
126
    , m_backgroundSizeSet(false)
 
127
    , m_next(0)
 
128
{
 
129
}
 
130
 
 
131
BackgroundLayer::BackgroundLayer(const BackgroundLayer& o)
 
132
    : m_image(o.m_image)
 
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)
 
151
{
 
152
}
 
153
 
 
154
BackgroundLayer::~BackgroundLayer()
 
155
{
 
156
    delete m_next;
 
157
}
 
158
 
 
159
BackgroundLayer& BackgroundLayer::operator=(const BackgroundLayer& o)
 
160
{
 
161
    if (m_next != o.m_next) {
 
162
        delete m_next;
 
163
        m_next = o.m_next ? new BackgroundLayer(*o.m_next) : 0;
 
164
    }
 
165
 
 
166
    m_image = o.m_image;
 
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;
 
175
 
 
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;
 
185
 
 
186
    return *this;
 
187
}
 
188
 
 
189
bool BackgroundLayer::operator==(const BackgroundLayer& o) const
 
190
{
 
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);
 
198
}
 
199
 
 
200
void BackgroundLayer::fillUnsetProperties()
 
201
{
 
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)
 
210
                pattern = this;
 
211
        }
 
212
    }
 
213
    
 
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)
 
221
                pattern = this;
 
222
        }
 
223
    }
 
224
    
 
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)
 
232
                pattern = this;
 
233
        }
 
234
    }
 
235
    
 
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)
 
243
                pattern = this;
 
244
        }
 
245
    }
 
246
    
 
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)
 
254
                pattern = this;
 
255
        }
 
256
    }
 
257
 
 
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)
 
265
                pattern = this;
 
266
        }
 
267
    }
 
268
 
 
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)
 
276
                pattern = this;
 
277
        }
 
278
    }
 
279
 
 
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)
 
287
                pattern = this;
 
288
        }
 
289
    }
 
290
    
 
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)
 
298
                pattern = this;
 
299
        }
 
300
    }
 
301
}
 
302
 
 
303
void BackgroundLayer::cullEmptyLayers()
 
304
{
 
305
    BackgroundLayer *next;
 
306
    for (BackgroundLayer *p = this; p; p = next) {
 
307
        next = p->m_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()) {
 
313
            delete next;
 
314
            p->m_next = 0;
 
315
            break;
 
316
        }
 
317
    }
 
318
}
 
319
 
 
320
StyleBackgroundData::StyleBackgroundData()
 
321
{
 
322
}
 
323
 
 
324
StyleBackgroundData::StyleBackgroundData(const StyleBackgroundData& o)
 
325
    : Shared<StyleBackgroundData>(), m_background(o.m_background), m_outline(o.m_outline)
 
326
{
 
327
}
 
328
 
 
329
bool StyleBackgroundData::operator==(const StyleBackgroundData& o) const
 
330
{
 
331
    return m_background == o.m_background && m_color == o.m_color && m_outline == o.m_outline;
 
332
}
 
333
 
 
334
StyleMarqueeData::StyleMarqueeData()
 
335
    : increment(RenderStyle::initialMarqueeIncrement())
 
336
    , speed(RenderStyle::initialMarqueeSpeed())
 
337
    , loops(RenderStyle::initialMarqueeLoopCount())
 
338
    , behavior(RenderStyle::initialMarqueeBehavior())
 
339
    , direction(RenderStyle::initialMarqueeDirection())
 
340
{
 
341
}
 
342
 
 
343
StyleMarqueeData::StyleMarqueeData(const StyleMarqueeData& o)
 
344
    : Shared<StyleMarqueeData>()
 
345
    , increment(o.increment)
 
346
    , speed(o.speed)
 
347
    , loops(o.loops)
 
348
    , behavior(o.behavior)
 
349
    , direction(o.direction) 
 
350
{
 
351
}
 
352
 
 
353
bool StyleMarqueeData::operator==(const StyleMarqueeData& o) const
 
354
{
 
355
    return increment == o.increment && speed == o.speed && direction == o.direction &&
 
356
           behavior == o.behavior && loops == o.loops;
 
357
}
 
358
 
 
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())
 
367
{
 
368
}
 
369
 
 
370
StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& o)
 
371
    : Shared<StyleFlexibleBoxData>()
 
372
    , flex(o.flex)
 
373
    , flex_group(o.flex_group)
 
374
    , ordinal_group(o.ordinal_group)
 
375
    , align(o.align)
 
376
    , pack(o.pack)
 
377
    , orient(o.orient)
 
378
    , lines(o.lines)
 
379
{
 
380
}
 
381
 
 
382
bool StyleFlexibleBoxData::operator==(const StyleFlexibleBoxData& o) const
 
383
{
 
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;
 
387
}
 
388
 
 
389
StyleMultiColData::StyleMultiColData()
 
390
    : m_width(0)
 
391
    , m_count(RenderStyle::initialColumnCount())
 
392
    , m_gap(0)
 
393
    , m_autoWidth(true)
 
394
    , m_autoCount(true)
 
395
    , m_normalGap(true)
 
396
    , m_breakBefore(RenderStyle::initialPageBreak())
 
397
    , m_breakAfter(RenderStyle::initialPageBreak())
 
398
    , m_breakInside(RenderStyle::initialPageBreak())
 
399
{}
 
400
 
 
401
StyleMultiColData::StyleMultiColData(const StyleMultiColData& o)
 
402
    : Shared<StyleMultiColData>()
 
403
    , m_width(o.m_width)
 
404
    , m_count(o.m_count)
 
405
    , m_gap(o.m_gap)
 
406
    , m_rule(o.m_rule)
 
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)
 
413
{}
 
414
 
 
415
bool StyleMultiColData::operator==(const StyleMultiColData& o) const
 
416
{
 
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;
 
421
}
 
422
 
 
423
StyleRareNonInheritedData::StyleRareNonInheritedData()
 
424
    : lineClamp(RenderStyle::initialLineClamp())
 
425
    , opacity(RenderStyle::initialOpacity())
 
426
    , m_content(0)
 
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())
 
435
    , m_boxShadow(0)
 
436
#if ENABLE(XBL)
 
437
    , bindingURI(0)
 
438
#endif
 
439
{
 
440
}
 
441
 
 
442
StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInheritedData& o)
 
443
    : Shared<StyleRareNonInheritedData>()
 
444
    , lineClamp(o.lineClamp)
 
445
    , opacity(o.opacity)
 
446
    , flexibleBox(o.flexibleBox)
 
447
    , marquee(o.marquee)
 
448
    , m_multiCol(o.m_multiCol)
 
449
    , m_content(0)
 
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)
 
459
#if ENABLE(XBL)
 
460
    , bindingURI(o.bindingURI ? o.bindingURI->copy() : 0)
 
461
#endif
 
462
{
 
463
}
 
464
 
 
465
StyleRareNonInheritedData::~StyleRareNonInheritedData()
 
466
{
 
467
    delete m_content;
 
468
    delete m_counterDirectives;
 
469
    delete m_boxShadow;
 
470
#if ENABLE(XBL)
 
471
    delete bindingURI;
 
472
#endif
 
473
}
 
474
 
 
475
#if ENABLE(XBL)
 
476
bool StyleRareNonInheritedData::bindingsEquivalent(const StyleRareNonInheritedData& o) const
 
477
{
 
478
    if (this == &o) return true;
 
479
    if (!bindingURI && o.bindingURI || bindingURI && !o.bindingURI)
 
480
        return false;
 
481
    if (bindingURI && o.bindingURI && (*bindingURI != *o.bindingURI))
 
482
        return false;
 
483
    return true;
 
484
}
 
485
#endif
 
486
 
 
487
bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) const
 
488
{
 
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)
 
505
#if ENABLE(XBL)
 
506
        && bindingsEquivalent(o)
 
507
#endif
 
508
        ;
 
509
}
 
510
 
 
511
bool StyleRareNonInheritedData::shadowDataEquivalent(const StyleRareNonInheritedData& o) const
 
512
{
 
513
    if (!m_boxShadow && o.m_boxShadow || m_boxShadow && !o.m_boxShadow)
 
514
        return false;
 
515
    if (m_boxShadow && o.m_boxShadow && (*m_boxShadow != *o.m_boxShadow))
 
516
        return false;
 
517
    return true;
 
518
}
 
519
 
 
520
StyleRareInheritedData::StyleRareInheritedData()
 
521
    : textStrokeWidth(RenderStyle::initialTextStrokeWidth())
 
522
    , textShadow(0)
 
523
    , textSecurity(RenderStyle::initialTextSecurity())
 
524
    , userModify(READ_ONLY)
 
525
    , wordBreak(RenderStyle::initialWordBreak())
 
526
    , wordWrap(RenderStyle::initialWordWrap())
 
527
    , nbspMode(NBNORMAL)
 
528
    , khtmlLineBreak(LBNORMAL)
 
529
    , textSizeAdjust(RenderStyle::initialTextSizeAdjust())
 
530
    , resize(RenderStyle::initialResize())
 
531
    , userSelect(RenderStyle::initialUserSelect())
 
532
{
 
533
}
 
534
 
 
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)
 
549
    , resize(o.resize)
 
550
    , userSelect(o.userSelect)
 
551
{
 
552
}
 
553
 
 
554
StyleRareInheritedData::~StyleRareInheritedData()
 
555
{
 
556
    delete textShadow;
 
557
}
 
558
 
 
559
bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
 
560
{
 
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;
 
574
}
 
575
 
 
576
bool StyleRareInheritedData::shadowDataEquivalent(const StyleRareInheritedData& o) const
 
577
{
 
578
    if (!textShadow && o.textShadow || textShadow && !o.textShadow)
 
579
        return false;
 
580
    if (textShadow && o.textShadow && (*textShadow != *o.textShadow))
 
581
        return false;
 
582
    return true;
 
583
}
 
584
 
 
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())
 
593
{
 
594
}
 
595
 
 
596
StyleInheritedData::~StyleInheritedData()
 
597
{
 
598
}
 
599
 
 
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)
 
608
{
 
609
}
 
610
 
 
611
static bool cursorDataEqvuialent(const CursorList* c1, const CursorList* c2)
 
612
{
 
613
    if (c1 == c2)
 
614
        return true;
 
615
    if (!c1 && c2 || c1 && !c2)
 
616
        return false;
 
617
    return (*c1 == *c2);
 
618
}
 
619
 
 
620
bool StyleInheritedData::operator==(const StyleInheritedData& o) const
 
621
{
 
622
    return
 
623
        indent == o.indent &&
 
624
        line_height == o.line_height &&
 
625
        style_image == o.style_image &&
 
626
        cursorDataEqvuialent(cursorData.get(), o.cursorData.get()) &&
 
627
        font == o.font &&
 
628
        color == o.color &&
 
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;
 
634
}
 
635
 
 
636
bool CursorList::operator==(const CursorList& other) const
 
637
{
 
638
    // If the lists aren't the same size, then they can't be equivalent.
 
639
    if (size() != other.size())
 
640
        return false;
 
641
        
 
642
    for (unsigned i = 0; i < size(); i++) {
 
643
        if (m_vector[i] != other.m_vector[i])
 
644
            return false;
 
645
    }
 
646
    
 
647
    return true;
 
648
}
 
649
 
 
650
 
 
651
static inline bool operator!=(const CounterContent& a, const CounterContent& b)
 
652
{
 
653
    return a.identifier() != b.identifier()
 
654
        || a.listStyle() != b.listStyle()
 
655
        || a.separator() != b.separator();
 
656
}
 
657
 
 
658
// ----------------------------------------------------------
 
659
 
 
660
void* RenderStyle::operator new(size_t sz, RenderArena* renderArena) throw()
 
661
{
 
662
    return renderArena->allocate(sz);
 
663
}
 
664
 
 
665
void RenderStyle::operator delete(void* ptr, size_t sz)
 
666
{
 
667
    // Stash size where destroy can find it.
 
668
    *(size_t *)ptr = sz;
 
669
}
 
670
 
 
671
void RenderStyle::arenaDelete(RenderArena *arena)
 
672
{
 
673
    RenderStyle *ps = pseudoStyle;
 
674
    RenderStyle *prev = 0;
 
675
    
 
676
    while (ps) {
 
677
        prev = ps;
 
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;
 
683
        prev->deref(arena);
 
684
    }
 
685
    delete this;
 
686
    
 
687
    // Recover the size left there for us by operator delete and free the memory.
 
688
    arena->free(*(size_t *)this, this);
 
689
}
 
690
 
 
691
inline RenderStyle *initDefaultStyle()
 
692
{
 
693
    if (!defaultStyle)
 
694
        defaultStyle = ::new RenderStyle(true);
 
695
    return defaultStyle;
 
696
}
 
697
 
 
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)
 
706
    , pseudoStyle(0)
 
707
    , m_pseudoState(PseudoUnknown)
 
708
    , m_affectedByAttributeSelectors(false)
 
709
    , m_unique(false)
 
710
    , m_ref(0)
 
711
#if ENABLE(SVG)
 
712
    , m_svgStyle(defaultStyle->m_svgStyle)
 
713
#endif
 
714
{
 
715
    setBitDefaults(); // Would it be faster to copy this from the default style?
 
716
}
 
717
 
 
718
RenderStyle::RenderStyle(bool)
 
719
    : pseudoStyle(0)
 
720
    , m_pseudoState(PseudoUnknown)
 
721
    , m_affectedByAttributeSelectors(false)
 
722
    , m_unique(false)
 
723
    , m_ref(1)
 
724
{
 
725
    setBitDefaults();
 
726
 
 
727
    box.init();
 
728
    visual.init();
 
729
    background.init();
 
730
    surround.init();
 
731
    rareNonInheritedData.init();
 
732
    rareNonInheritedData.access()->flexibleBox.init();
 
733
    rareNonInheritedData.access()->marquee.init();
 
734
    rareNonInheritedData.access()->m_multiCol.init();
 
735
    rareInheritedData.init();
 
736
    inherited.init();
 
737
    
 
738
#if ENABLE(SVG)
 
739
    m_svgStyle.init();
 
740
#endif
 
741
}
 
742
 
 
743
RenderStyle::RenderStyle(const RenderStyle& o)
 
744
    : inherited_flags(o.inherited_flags)
 
745
    , noninherited_flags(o.noninherited_flags)
 
746
    , box(o.box)
 
747
    , visual(o.visual)
 
748
    , background(o.background)
 
749
    , surround(o.surround)
 
750
    , rareNonInheritedData(o.rareNonInheritedData)
 
751
    , rareInheritedData(o.rareInheritedData)
 
752
    , inherited(o.inherited)
 
753
    , pseudoStyle(0)
 
754
    , m_pseudoState(o.m_pseudoState)
 
755
    , m_affectedByAttributeSelectors(false)
 
756
    , m_unique(false)
 
757
    , m_ref(0)
 
758
#if ENABLE(SVG)
 
759
    , m_svgStyle(o.m_svgStyle)
 
760
#endif
 
761
{
 
762
}
 
763
 
 
764
void RenderStyle::inheritFrom(const RenderStyle* inheritParent)
 
765
{
 
766
    rareInheritedData = inheritParent->rareInheritedData;
 
767
    inherited = inheritParent->inherited;
 
768
    inherited_flags = inheritParent->inherited_flags;
 
769
#if ENABLE(SVG)
 
770
    if (m_svgStyle != inheritParent->m_svgStyle)
 
771
        m_svgStyle.access()->inheritFrom(inheritParent->m_svgStyle.get());
 
772
#endif
 
773
}
 
774
 
 
775
RenderStyle::~RenderStyle()
 
776
{
 
777
}
 
778
 
 
779
bool RenderStyle::operator==(const RenderStyle& o) const
 
780
{
 
781
    // compare everything except the pseudoStyle pointer
 
782
    return inherited_flags == o.inherited_flags &&
 
783
            noninherited_flags == o.noninherited_flags &&
 
784
            box == o.box &&
 
785
            visual == o.visual &&
 
786
            background == o.background &&
 
787
            surround == o.surround &&
 
788
            rareNonInheritedData == o.rareNonInheritedData &&
 
789
            rareInheritedData == o.rareInheritedData &&
 
790
            inherited == o.inherited
 
791
#if ENABLE(SVG)
 
792
            && m_svgStyle == o.m_svgStyle
 
793
#endif
 
794
            ;
 
795
}
 
796
 
 
797
bool RenderStyle::isStyleAvailable() const
 
798
{
 
799
    return this != CSSStyleSelector::styleNotYetAvailable;
 
800
}
 
801
 
 
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 };
 
806
 
 
807
static inline int pseudoBit(RenderStyle::PseudoId pseudo)
 
808
{
 
809
    switch (pseudo) {
 
810
        case RenderStyle::BEFORE:
 
811
            return BEFORE_BIT;
 
812
        case RenderStyle::AFTER:
 
813
            return AFTER_BIT;
 
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;
 
834
        default:
 
835
            return NO_BIT;
 
836
    }
 
837
}
 
838
 
 
839
bool RenderStyle::hasPseudoStyle(PseudoId pseudo) const
 
840
{
 
841
    return pseudoBit(pseudo) & noninherited_flags._pseudoBits;
 
842
}
 
843
 
 
844
void RenderStyle::setHasPseudoStyle(PseudoId pseudo)
 
845
{
 
846
    noninherited_flags._pseudoBits |= pseudoBit(pseudo);
 
847
}
 
848
 
 
849
RenderStyle* RenderStyle::getPseudoStyle(PseudoId pid)
 
850
{
 
851
    if (!pseudoStyle || styleType() != NOPSEUDO)
 
852
        return 0;
 
853
    RenderStyle* ps = pseudoStyle;
 
854
    while (ps && ps->styleType() != pid)
 
855
        ps = ps->pseudoStyle;
 
856
    return ps;
 
857
}
 
858
 
 
859
void RenderStyle::addPseudoStyle(RenderStyle* pseudo)
 
860
{
 
861
    if (!pseudo)
 
862
        return;
 
863
    pseudo->ref();
 
864
    pseudo->pseudoStyle = pseudoStyle;
 
865
    pseudoStyle = pseudo;
 
866
}
 
867
 
 
868
bool RenderStyle::inheritedNotEqual(RenderStyle* other) const
 
869
{
 
870
    return inherited_flags != other->inherited_flags ||
 
871
           inherited != other->inherited ||
 
872
#if ENABLE(SVG)
 
873
           m_svgStyle->inheritedNotEqual(other->m_svgStyle.get()) ||
 
874
#endif
 
875
           rareInheritedData != other->rareInheritedData;
 
876
}
 
877
 
 
878
/*
 
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.
 
881
 
 
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
 
886
       the change.
 
887
 
 
888
  ### TODO:
 
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.
 
892
*/
 
893
RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
 
894
{
 
895
#if ENABLE(SVG)
 
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)
 
900
        return Layout;
 
901
#endif
 
902
 
 
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)
 
909
        return Layout;
 
910
    
 
911
    if (box->vertical_align != other->box->vertical_align || noninherited_flags._vertical_align != other->noninherited_flags._vertical_align)
 
912
        return Layout;
 
913
    
 
914
    if (box->boxSizing != other->box->boxSizing)
 
915
        return Layout;
 
916
    
 
917
    if (surround->margin != other->surround->margin)
 
918
        return Layout;
 
919
        
 
920
    if (surround->padding != other->surround->padding)
 
921
        return Layout;
 
922
    
 
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)
 
929
            return Layout;
 
930
        
 
931
        if (rareNonInheritedData->flexibleBox.get() != other->rareNonInheritedData->flexibleBox.get() &&
 
932
            *rareNonInheritedData->flexibleBox.get() != *other->rareNonInheritedData->flexibleBox.get())
 
933
            return Layout;
 
934
        
 
935
        if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get()))
 
936
            return Layout;
 
937
 
 
938
        if (rareNonInheritedData->m_multiCol.get() != other->rareNonInheritedData->m_multiCol.get() &&
 
939
            *rareNonInheritedData->m_multiCol.get() != *other->rareNonInheritedData->m_multiCol.get())
 
940
            return Layout;
 
941
            
 
942
        // If regions change trigger a relayout to re-calc regions.
 
943
        if (rareNonInheritedData->m_dashboardRegions != other->rareNonInheritedData->m_dashboardRegions)
 
944
            return Layout;
 
945
    }
 
946
 
 
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)
 
955
            return Layout;
 
956
        
 
957
        if (!rareInheritedData->shadowDataEquivalent(*other->rareInheritedData.get()))
 
958
            return Layout;
 
959
            
 
960
        if (textStrokeWidth() != other->textStrokeWidth())
 
961
            return Layout;
 
962
    }
 
963
 
 
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)
 
976
        return Layout;
 
977
 
 
978
   
 
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)
 
984
            return Layout;
 
985
        
 
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))
 
997
            return Layout;
 
998
    }
 
999
 
 
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)
 
1003
            return Layout;
 
1004
    }
 
1005
 
 
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)
 
1011
        return Layout;
 
1012
 
 
1013
    // Overflow returns a layout hint.
 
1014
    if (noninherited_flags._overflowX != other->noninherited_flags._overflowX ||
 
1015
        noninherited_flags._overflowY != other->noninherited_flags._overflowY)
 
1016
        return Layout;
 
1017
 
 
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())
 
1024
        return Layout;
 
1025
 
 
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)))
 
1030
        return Layout;
 
1031
    if (visual->counterIncrement != other->visual->counterIncrement ||
 
1032
        visual->counterReset != other->visual->counterReset)
 
1033
        return Layout;
 
1034
 
 
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;
 
1044
            //else
 
1045
                return Layout;
 
1046
        }
 
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;
 
1050
    }
 
1051
 
 
1052
    if (rareNonInheritedData->opacity != other->rareNonInheritedData->opacity)
 
1053
        return RepaintLayer;
 
1054
 
 
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)
 
1068
        return Repaint;
 
1069
 
 
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.
 
1072
 
 
1073
    return Equal;
 
1074
}
 
1075
 
 
1076
void RenderStyle::adjustBackgroundLayers()
 
1077
{
 
1078
    if (backgroundLayers()->next()) {
 
1079
        // First we cull out layers that have no properties set.
 
1080
        accessBackgroundLayers()->cullEmptyLayers();
 
1081
        
 
1082
        // Next we repeat patterns into layers that don't have some properties set.
 
1083
        accessBackgroundLayers()->fillUnsetProperties();
 
1084
    }
 
1085
}
 
1086
 
 
1087
void RenderStyle::setClip( Length top, Length right, Length bottom, Length left )
 
1088
{
 
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;
 
1094
}
 
1095
 
 
1096
void RenderStyle::addCursor(CachedImage* image, const IntPoint& hotSpot)
 
1097
{
 
1098
    CursorData data;
 
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);
 
1104
}
 
1105
 
 
1106
void RenderStyle::addSVGCursor(const String& fragmentId)
 
1107
{
 
1108
    CursorData data;
 
1109
    data.cursorFragmentId = fragmentId;
 
1110
    if (!inherited.access()->cursorData)
 
1111
        inherited.access()->cursorData = new CursorList;
 
1112
    inherited.access()->cursorData->append(data);
 
1113
}
 
1114
 
 
1115
void RenderStyle::setCursorList(PassRefPtr<CursorList> other)
 
1116
{
 
1117
    inherited.access()->cursorData = other;
 
1118
}
 
1119
 
 
1120
void RenderStyle::clearCursorList()
 
1121
{
 
1122
    inherited.access()->cursorData = new CursorList;
 
1123
}
 
1124
 
 
1125
bool RenderStyle::contentDataEquivalent(const RenderStyle* otherStyle) const
 
1126
{
 
1127
    ContentData* c1 = rareNonInheritedData->m_content;
 
1128
    ContentData* c2 = otherStyle->rareNonInheritedData->m_content;
 
1129
 
 
1130
    while (c1 && c2) {
 
1131
        if (c1->m_type != c2->m_type)
 
1132
            return false;
 
1133
 
 
1134
        switch (c1->m_type) {
 
1135
            case CONTENT_NONE:
 
1136
                break;
 
1137
            case CONTENT_TEXT:
 
1138
                if (!equal(c1->m_content.m_text, c2->m_content.m_text))
 
1139
                    return false;
 
1140
                break;
 
1141
            case CONTENT_OBJECT:
 
1142
                if (c1->m_content.m_object != c2->m_content.m_object)
 
1143
                    return false;
 
1144
                break;
 
1145
            case CONTENT_COUNTER:
 
1146
                if (*c1->m_content.m_counter != *c2->m_content.m_counter)
 
1147
                    return false;
 
1148
                break;
 
1149
        }
 
1150
 
 
1151
        c1 = c1->m_next;
 
1152
        c2 = c2->m_next;
 
1153
    }
 
1154
 
 
1155
    return !c1 && !c2;
 
1156
}
 
1157
 
 
1158
void RenderStyle::clearContent()
 
1159
{
 
1160
    if (rareNonInheritedData->m_content)
 
1161
        rareNonInheritedData->m_content->clear();
 
1162
}
 
1163
 
 
1164
void RenderStyle::setContent(CachedResource* o, bool add)
 
1165
{
 
1166
    if (!o)
 
1167
        return; // The object is null. Nothing to do. Just bail.
 
1168
 
 
1169
    ContentData*& content = rareNonInheritedData.access()->m_content;
 
1170
    ContentData* lastContent = content;
 
1171
    while (lastContent && lastContent->m_next)
 
1172
        lastContent = lastContent->m_next;
 
1173
 
 
1174
    bool reuseContent = !add;
 
1175
    ContentData* newContentData = 0;
 
1176
    if (reuseContent && content) {
 
1177
        content->clear();
 
1178
        newContentData = content;
 
1179
    } else
 
1180
        newContentData = new ContentData;
 
1181
 
 
1182
    if (lastContent && !reuseContent)
 
1183
        lastContent->m_next = newContentData;
 
1184
    else
 
1185
        content = newContentData;
 
1186
 
 
1187
    newContentData->m_content.m_object = o;
 
1188
    newContentData->m_type = CONTENT_OBJECT;
 
1189
}
 
1190
 
 
1191
void RenderStyle::setContent(StringImpl* s, bool add)
 
1192
{
 
1193
    if (!s)
 
1194
        return; // The string is null. Nothing to do. Just bail.
 
1195
    
 
1196
    ContentData*& content = rareNonInheritedData.access()->m_content;
 
1197
    ContentData* lastContent = content;
 
1198
    while (lastContent && lastContent->m_next)
 
1199
        lastContent = lastContent->m_next;
 
1200
 
 
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();
 
1207
            newStr->ref();
 
1208
            oldStr->deref();
 
1209
            newStr->append(s);
 
1210
            lastContent->m_content.m_text = newStr;
 
1211
            return;
 
1212
        }
 
1213
    }
 
1214
 
 
1215
    ContentData* newContentData = 0;
 
1216
    if (reuseContent && content) {
 
1217
        content->clear();
 
1218
        newContentData = content;
 
1219
    } else
 
1220
        newContentData = new ContentData;
 
1221
    
 
1222
    if (lastContent && !reuseContent)
 
1223
        lastContent->m_next = newContentData;
 
1224
    else
 
1225
        content = newContentData;
 
1226
    
 
1227
    newContentData->m_content.m_text = s;
 
1228
    newContentData->m_content.m_text->ref();
 
1229
    newContentData->m_type = CONTENT_TEXT;
 
1230
}
 
1231
 
 
1232
void RenderStyle::setContent(CounterContent* c, bool add)
 
1233
{
 
1234
    if (!c)
 
1235
        return;
 
1236
 
 
1237
    ContentData*& content = rareNonInheritedData.access()->m_content;
 
1238
    ContentData* lastContent = content;
 
1239
    while (lastContent && lastContent->m_next)
 
1240
        lastContent = lastContent->m_next;
 
1241
 
 
1242
    bool reuseContent = !add;
 
1243
    ContentData* newContentData = 0;
 
1244
    if (reuseContent && content) {
 
1245
        content->clear();
 
1246
        newContentData = content;
 
1247
    } else
 
1248
        newContentData = new ContentData;
 
1249
 
 
1250
    if (lastContent && !reuseContent)
 
1251
        lastContent->m_next = newContentData;
 
1252
    else
 
1253
        content = newContentData;
 
1254
 
 
1255
    newContentData->m_content.m_counter = c;
 
1256
    newContentData->m_type = CONTENT_COUNTER;
 
1257
}
 
1258
 
 
1259
void ContentData::clear()
 
1260
{
 
1261
    switch (m_type) {
 
1262
        case CONTENT_NONE:
 
1263
        case CONTENT_OBJECT:
 
1264
            break;
 
1265
        case CONTENT_TEXT:
 
1266
            m_content.m_text->deref();
 
1267
            break;
 
1268
        case CONTENT_COUNTER:
 
1269
            delete m_content.m_counter;
 
1270
            break;
 
1271
    }
 
1272
 
 
1273
    ContentData* n = m_next;
 
1274
    m_type = CONTENT_NONE;
 
1275
    m_next = 0;
 
1276
 
 
1277
    // Reverse the list so we can delete without recursing.
 
1278
    ContentData* last = 0;
 
1279
    ContentData* c;
 
1280
    while ((c = n)) {
 
1281
        n = c->m_next;
 
1282
        c->m_next = last;
 
1283
        last = c;
 
1284
    }
 
1285
    for (c = last; c; c = n) {
 
1286
        n = c->m_next;
 
1287
        c->m_next = 0;
 
1288
        delete c;
 
1289
    }
 
1290
}
 
1291
 
 
1292
#if ENABLE(XBL)
 
1293
BindingURI::BindingURI(StringImpl* uri) 
 
1294
:m_next(0)
 
1295
 
1296
    m_uri = uri;
 
1297
    if (uri) uri->ref();
 
1298
}
 
1299
 
 
1300
BindingURI::~BindingURI()
 
1301
{
 
1302
    if (m_uri)
 
1303
        m_uri->deref();
 
1304
    delete m_next;
 
1305
}
 
1306
 
 
1307
BindingURI* BindingURI::copy()
 
1308
{
 
1309
    BindingURI* newBinding = new BindingURI(m_uri);
 
1310
    if (next()) {
 
1311
        BindingURI* nextCopy = next()->copy();
 
1312
        newBinding->setNext(nextCopy);
 
1313
    }
 
1314
    
 
1315
    return newBinding;
 
1316
}
 
1317
 
 
1318
bool BindingURI::operator==(const BindingURI& o) const
 
1319
{
 
1320
    if ((m_next && !o.m_next) || (!m_next && o.m_next) ||
 
1321
        (m_next && o.m_next && *m_next != *o.m_next))
 
1322
        return false;
 
1323
    
 
1324
    if (m_uri == o.m_uri)
 
1325
        return true;
 
1326
    if (!m_uri || !o.m_uri)
 
1327
        return false;
 
1328
    
 
1329
    return String(m_uri) == String(o.m_uri);
 
1330
}
 
1331
 
 
1332
void RenderStyle::addBindingURI(StringImpl* uri)
 
1333
{
 
1334
    BindingURI* binding = new BindingURI(uri);
 
1335
    if (!bindingURIs())
 
1336
        SET_VAR(rareNonInheritedData, bindingURI, binding)
 
1337
    else 
 
1338
        for (BindingURI* b = bindingURIs(); b; b = b->next()) {
 
1339
            if (!b->next())
 
1340
                b->setNext(binding);
 
1341
        }
 
1342
}
 
1343
#endif
 
1344
 
 
1345
void RenderStyle::setTextShadow(ShadowData* val, bool add)
 
1346
{
 
1347
    StyleRareInheritedData* rareData = rareInheritedData.access(); 
 
1348
    if (!add) {
 
1349
        delete rareData->textShadow;
 
1350
        rareData->textShadow = val;
 
1351
        return;
 
1352
    }
 
1353
 
 
1354
    ShadowData* last = rareData->textShadow;
 
1355
    while (last->next) last = last->next;
 
1356
    last->next = val;
 
1357
}
 
1358
 
 
1359
void RenderStyle::setBoxShadow(ShadowData* val, bool add)
 
1360
{
 
1361
    StyleRareNonInheritedData* rareData = rareNonInheritedData.access(); 
 
1362
    if (!add) {
 
1363
        delete rareData->m_boxShadow;
 
1364
        rareData->m_boxShadow = val;
 
1365
        return;
 
1366
    }
 
1367
 
 
1368
    ShadowData* last = rareData->m_boxShadow;
 
1369
    while (last->next) last = last->next;
 
1370
    last->next = val;
 
1371
}
 
1372
 
 
1373
ShadowData::ShadowData(const ShadowData& o)
 
1374
:x(o.x), y(o.y), blur(o.blur), color(o.color)
 
1375
{
 
1376
    next = o.next ? new ShadowData(*o.next) : 0;
 
1377
}
 
1378
 
 
1379
bool ShadowData::operator==(const ShadowData& o) const
 
1380
{
 
1381
    if ((next && !o.next) || (!next && o.next) ||
 
1382
        (next && o.next && *next != *o.next))
 
1383
        return false;
 
1384
    
 
1385
    return x == o.x && y == o.y && blur == o.blur && color == o.color;
 
1386
}
 
1387
 
 
1388
bool operator==(const CounterDirectives& a, const CounterDirectives& b)
 
1389
{
 
1390
    if (a.m_reset != b.m_reset || a.m_increment != b.m_increment)
 
1391
        return false;
 
1392
    if (a.m_reset && a.m_resetValue != b.m_resetValue)
 
1393
        return false;
 
1394
    if (a.m_increment && a.m_incrementValue != b.m_incrementValue)
 
1395
        return false;
 
1396
    return true;
 
1397
}
 
1398
 
 
1399
const CounterDirectiveMap* RenderStyle::counterDirectives() const
 
1400
{
 
1401
    return rareNonInheritedData->m_counterDirectives;
 
1402
}
 
1403
 
 
1404
CounterDirectiveMap& RenderStyle::accessCounterDirectives()
 
1405
{
 
1406
    CounterDirectiveMap*& map = rareNonInheritedData.access()->m_counterDirectives;
 
1407
    if (!map)
 
1408
        map = new CounterDirectiveMap;
 
1409
    return *map;
 
1410
}
 
1411
 
 
1412
const Vector<StyleDashboardRegion>& RenderStyle::initialDashboardRegions()
 
1413
 
1414
    static Vector<StyleDashboardRegion> emptyList;
 
1415
    return emptyList;
 
1416
}
 
1417
 
 
1418
const Vector<StyleDashboardRegion>& RenderStyle::noneDashboardRegions()
 
1419
 
1420
    static Vector<StyleDashboardRegion> noneList;
 
1421
    static bool noneListInitialized = false;
 
1422
    
 
1423
    if (!noneListInitialized) {
 
1424
        StyleDashboardRegion region;
 
1425
        region.label = "";
 
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;
 
1433
    }
 
1434
    return noneList;
 
1435
}
 
1436
 
 
1437
}