1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Mats Palmgren <matspal@gmail.com>
24 : * Masayuki Nakano <masayuki@d-toybox.com>
25 : * Rob Arnold <robarnold@mozilla.com>
26 : * Jonathon Jongsma <jonathon.jongsma@collabora.co.uk>, Collabora Ltd.
27 : * L. David Baron <dbaron@dbaron.org>, Mozilla Corporation
28 : *
29 : * Alternatively, the contents of this file may be used under the terms of
30 : * either of the GNU General Public License Version 2 or later (the "GPL"),
31 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
32 : * in which case the provisions of the GPL or the LGPL are applicable instead
33 : * of those above. If you wish to allow use of your version of this file only
34 : * under the terms of either the GPL or the LGPL, and not to allow others to
35 : * use your version of this file under the terms of the MPL, indicate your
36 : * decision by deleting the provisions above and replace them with the notice
37 : * and other provisions required by the GPL or the LGPL. If you do not delete
38 : * the provisions above, a recipient may use your version of this file under
39 : * the terms of any one of the MPL, the GPL or the LGPL.
40 : *
41 : * ***** END LICENSE BLOCK ***** */
42 :
43 : /*
44 : * structs that contain the data provided by nsStyleContext, the
45 : * internal API for computed style data for an element
46 : */
47 :
48 : #ifndef nsStyleStruct_h___
49 : #define nsStyleStruct_h___
50 :
51 : #include "mozilla/Attributes.h"
52 :
53 : #include "nsColor.h"
54 : #include "nsCoord.h"
55 : #include "nsMargin.h"
56 : #include "nsRect.h"
57 : #include "nsFont.h"
58 : #include "nsStyleCoord.h"
59 : #include "nsStyleConsts.h"
60 : #include "nsChangeHint.h"
61 : #include "nsPresContext.h"
62 : #include "nsCOMPtr.h"
63 : #include "nsCOMArray.h"
64 : #include "nsTArray.h"
65 : #include "nsIAtom.h"
66 : #include "nsIURI.h"
67 : #include "nsCSSValue.h"
68 : #include "nsStyleTransformMatrix.h"
69 : #include "nsAlgorithm.h"
70 : #include "imgIRequest.h"
71 : #include "gfxRect.h"
72 :
73 : class nsIFrame;
74 : class imgIRequest;
75 : class imgIContainer;
76 : struct nsCSSValueList;
77 :
78 : // Includes nsStyleStructID.
79 : #include "nsStyleStructFwd.h"
80 :
81 : // Bits for each struct.
82 : // NS_STYLE_INHERIT_BIT defined in nsStyleStructFwd.h
83 : #define NS_STYLE_INHERIT_MASK 0x007fffff
84 :
85 : // Additional bits for nsStyleContext's mBits:
86 : // See nsStyleContext::HasTextDecorationLines
87 : #define NS_STYLE_HAS_TEXT_DECORATION_LINES 0x00800000
88 : // See nsStyleContext::HasPseudoElementData.
89 : #define NS_STYLE_HAS_PSEUDO_ELEMENT_DATA 0x01000000
90 : // See nsStyleContext::RelevantLinkIsVisited
91 : #define NS_STYLE_RELEVANT_LINK_VISITED 0x02000000
92 : // See nsStyleContext::IsStyleIfVisited
93 : #define NS_STYLE_IS_STYLE_IF_VISITED 0x04000000
94 : // See nsStyleContext::GetPseudoEnum
95 : #define NS_STYLE_CONTEXT_TYPE_MASK 0xf8000000
96 : #define NS_STYLE_CONTEXT_TYPE_SHIFT 27
97 :
98 : // Additional bits for nsRuleNode's mDependentBits:
99 : #define NS_RULE_NODE_GC_MARK 0x02000000
100 : #define NS_RULE_NODE_IS_IMPORTANT 0x08000000
101 : #define NS_RULE_NODE_LEVEL_MASK 0xf0000000
102 : #define NS_RULE_NODE_LEVEL_SHIFT 28
103 :
104 : // The lifetime of these objects is managed by the presshell's arena.
105 :
106 : // Each struct must implement a static ForceCompare() function returning a
107 : // boolean. Structs that can return a hint that doesn't guarantee that the
108 : // change will be applied to all descendants must return true from
109 : // ForceCompare(), so that we will make sure to compare those structs in
110 : // nsStyleContext::CalcStyleDifference.
111 :
112 0 : struct nsStyleFont {
113 : nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext);
114 : nsStyleFont(const nsStyleFont& aStyleFont);
115 : nsStyleFont(nsPresContext *aPresContext);
116 : private:
117 : void Init(nsPresContext *aPresContext);
118 : public:
119 0 : ~nsStyleFont(void) {
120 0 : MOZ_COUNT_DTOR(nsStyleFont);
121 0 : }
122 :
123 : nsChangeHint CalcDifference(const nsStyleFont& aOther) const;
124 : #ifdef DEBUG
125 : static nsChangeHint MaxDifference();
126 : #endif
127 0 : static bool ForceCompare() { return false; }
128 : static nsChangeHint CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2);
129 :
130 : static nscoord ZoomText(nsPresContext* aPresContext, nscoord aSize);
131 : static nscoord UnZoomText(nsPresContext* aPresContext, nscoord aSize);
132 :
133 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
134 : void Destroy(nsPresContext* aContext);
135 :
136 : nsFont mFont; // [inherited]
137 : nscoord mSize; // [inherited] Our "computed size". Can be different
138 : // from mFont.size which is our "actual size" and is
139 : // enforced to be >= the user's preferred min-size.
140 : // mFont.size should be used for display purposes
141 : // while mSize is the value to return in
142 : // getComputedStyle() for example.
143 : PRUint8 mGenericID; // [inherited] generic CSS font family, if any;
144 : // value is a kGenericFont_* constant, see nsFont.h.
145 :
146 : // MathML scriptlevel support
147 : PRInt8 mScriptLevel; // [inherited]
148 : // The value mSize would have had if scriptminsize had never been applied
149 : nscoord mScriptUnconstrainedSize;
150 : nscoord mScriptMinSize; // [inherited] length
151 : float mScriptSizeMultiplier; // [inherited]
152 : nsCOMPtr<nsIAtom> mLanguage; // [inherited]
153 : };
154 :
155 0 : struct nsStyleGradientStop {
156 : nsStyleCoord mLocation; // percent, coord, none
157 : nscolor mColor;
158 : };
159 :
160 : class nsStyleGradient {
161 : public:
162 : nsStyleGradient();
163 : PRUint8 mShape; // NS_STYLE_GRADIENT_SHAPE_*
164 : PRUint8 mSize; // NS_STYLE_GRADIENT_SIZE_*;
165 : // not used (must be FARTHEST_CORNER) for linear shape
166 : bool mRepeating;
167 : bool mToCorner;
168 :
169 : nsStyleCoord mBgPosX; // percent, coord, calc, none
170 : nsStyleCoord mBgPosY; // percent, coord, calc, none
171 : nsStyleCoord mAngle; // none, angle
172 :
173 : // stops are in the order specified in the stylesheet
174 : nsTArray<nsStyleGradientStop> mStops;
175 :
176 : bool operator==(const nsStyleGradient& aOther) const;
177 : bool operator!=(const nsStyleGradient& aOther) const {
178 : return !(*this == aOther);
179 : };
180 :
181 : bool IsOpaque();
182 :
183 0 : NS_INLINE_DECL_REFCOUNTING(nsStyleGradient)
184 :
185 : private:
186 0 : ~nsStyleGradient() {}
187 :
188 : nsStyleGradient(const nsStyleGradient& aOther) MOZ_DELETE;
189 : nsStyleGradient& operator=(const nsStyleGradient& aOther) MOZ_DELETE;
190 : };
191 :
192 : enum nsStyleImageType {
193 : eStyleImageType_Null,
194 : eStyleImageType_Image,
195 : eStyleImageType_Gradient,
196 : eStyleImageType_Element
197 : };
198 :
199 : /**
200 : * Represents a paintable image of one of the following types.
201 : * (1) A real image loaded from an external source.
202 : * (2) A CSS linear or radial gradient.
203 : * (3) An element within a document, or an <img>, <video>, or <canvas> element
204 : * not in a document.
205 : * (*) Optionally a crop rect can be set to paint a partial (rectangular)
206 : * region of an image. (Currently, this feature is only supported with an
207 : * image of type (1)).
208 : *
209 : * This struct is currently used only for 'background-image', but it may be
210 : * used by other CSS properties such as 'border-image', 'list-style-image', and
211 : * 'content' in the future (bug 507052).
212 : */
213 : struct nsStyleImage {
214 : nsStyleImage();
215 : ~nsStyleImage();
216 : nsStyleImage(const nsStyleImage& aOther);
217 : nsStyleImage& operator=(const nsStyleImage& aOther);
218 :
219 : void SetNull();
220 : void SetImageData(imgIRequest* aImage);
221 : void TrackImage(nsPresContext* aContext);
222 : void UntrackImage(nsPresContext* aContext);
223 : void SetGradientData(nsStyleGradient* aGradient);
224 : void SetElementId(const PRUnichar* aElementId);
225 : void SetCropRect(nsStyleSides* aCropRect);
226 :
227 0 : nsStyleImageType GetType() const {
228 0 : return mType;
229 : }
230 0 : imgIRequest* GetImageData() const {
231 0 : NS_ABORT_IF_FALSE(mType == eStyleImageType_Image, "Data is not an image!");
232 0 : NS_ABORT_IF_FALSE(mImageTracked,
233 : "Should be tracking any image we're going to use!");
234 0 : return mImage;
235 : }
236 0 : nsStyleGradient* GetGradientData() const {
237 0 : NS_ASSERTION(mType == eStyleImageType_Gradient, "Data is not a gradient!");
238 0 : return mGradient;
239 : }
240 0 : const PRUnichar* GetElementId() const {
241 0 : NS_ASSERTION(mType == eStyleImageType_Element, "Data is not an element!");
242 0 : return mElementId;
243 : }
244 0 : nsStyleSides* GetCropRect() const {
245 0 : NS_ASSERTION(mType == eStyleImageType_Image,
246 : "Only image data can have a crop rect");
247 0 : return mCropRect;
248 : }
249 :
250 : /**
251 : * Compute the actual crop rect in pixels, using the source image bounds.
252 : * The computation involves converting percentage unit to pixel unit and
253 : * clamping each side value to fit in the source image bounds.
254 : * @param aActualCropRect the computed actual crop rect.
255 : * @param aIsEntireImage true iff |aActualCropRect| is identical to the
256 : * source image bounds.
257 : * @return true iff |aActualCropRect| holds a meaningful value.
258 : */
259 : bool ComputeActualCropRect(nsIntRect& aActualCropRect,
260 : bool* aIsEntireImage = nsnull) const;
261 :
262 : /**
263 : * Requests a decode on the image.
264 : */
265 : nsresult RequestDecode() const;
266 : /**
267 : * @return true if the item is definitely opaque --- i.e., paints every
268 : * pixel within its bounds opaquely, and the bounds contains at least a pixel.
269 : */
270 : bool IsOpaque() const;
271 : /**
272 : * @return true if this image is fully loaded, and its size is calculated;
273 : * always returns true if |mType| is |eStyleImageType_Gradient| or
274 : * |eStyleImageType_Element|.
275 : */
276 : bool IsComplete() const;
277 : /**
278 : * @return true if it is 100% confident that this image contains no pixel
279 : * to draw.
280 : */
281 0 : bool IsEmpty() const {
282 : // There are some other cases when the image will be empty, for example
283 : // when the crop rect is empty. However, checking the emptiness of crop
284 : // rect is non-trivial since each side value can be specified with
285 : // percentage unit, which can not be evaluated until the source image size
286 : // is available. Therefore, we currently postpone the evaluation of crop
287 : // rect until the actual rendering time --- alternatively until GetOpaqueRegion()
288 : // is called.
289 0 : return mType == eStyleImageType_Null;
290 : }
291 :
292 : bool operator==(const nsStyleImage& aOther) const;
293 0 : bool operator!=(const nsStyleImage& aOther) const {
294 0 : return !(*this == aOther);
295 : }
296 :
297 : private:
298 : void DoCopy(const nsStyleImage& aOther);
299 :
300 : nsStyleImageType mType;
301 : union {
302 : imgIRequest* mImage;
303 : nsStyleGradient* mGradient;
304 : PRUnichar* mElementId;
305 : };
306 : // This is _currently_ used only in conjunction with eStyleImageType_Image.
307 : nsAutoPtr<nsStyleSides> mCropRect;
308 : #ifdef DEBUG
309 : bool mImageTracked;
310 : #endif
311 : };
312 :
313 : struct nsStyleColor {
314 : nsStyleColor(nsPresContext* aPresContext);
315 : nsStyleColor(const nsStyleColor& aOther);
316 0 : ~nsStyleColor(void) {
317 0 : MOZ_COUNT_DTOR(nsStyleColor);
318 0 : }
319 :
320 : nsChangeHint CalcDifference(const nsStyleColor& aOther) const;
321 : #ifdef DEBUG
322 : static nsChangeHint MaxDifference();
323 : #endif
324 0 : static bool ForceCompare() { return false; }
325 :
326 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
327 0 : return aContext->AllocateFromShell(sz);
328 : }
329 0 : void Destroy(nsPresContext* aContext) {
330 0 : this->~nsStyleColor();
331 0 : aContext->FreeToShell(sizeof(nsStyleColor), this);
332 0 : }
333 :
334 : // Don't add ANY members to this struct! We can achieve caching in the rule
335 : // tree (rather than the style tree) by letting color stay by itself! -dwh
336 : nscolor mColor; // [inherited]
337 : };
338 :
339 : struct nsStyleBackground {
340 : nsStyleBackground();
341 : nsStyleBackground(const nsStyleBackground& aOther);
342 : ~nsStyleBackground();
343 :
344 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
345 0 : return aContext->AllocateFromShell(sz);
346 : }
347 : void Destroy(nsPresContext* aContext);
348 :
349 : nsChangeHint CalcDifference(const nsStyleBackground& aOther) const;
350 : #ifdef DEBUG
351 : static nsChangeHint MaxDifference();
352 : #endif
353 0 : static bool ForceCompare() { return false; }
354 :
355 : struct Position;
356 : friend struct Position;
357 : struct Position {
358 : typedef nsStyleCoord::Calc PositionCoord;
359 : PositionCoord mXPosition, mYPosition;
360 :
361 : // Initialize nothing
362 0 : Position() {}
363 :
364 : // Initialize to initial values
365 : void SetInitialValues();
366 :
367 : // True if the effective background image position described by this depends
368 : // on the size of the corresponding frame.
369 0 : bool DependsOnFrameSize() const {
370 0 : return mXPosition.mPercent != 0.0f || mYPosition.mPercent != 0.0f;
371 : }
372 :
373 0 : bool operator==(const Position& aOther) const {
374 0 : return mXPosition == aOther.mXPosition &&
375 0 : mYPosition == aOther.mYPosition;
376 : }
377 : bool operator!=(const Position& aOther) const {
378 : return !(*this == aOther);
379 : }
380 : };
381 :
382 : struct Size;
383 : friend struct Size;
384 : struct Size {
385 : struct Dimension : public nsStyleCoord::Calc {
386 0 : nscoord ResolveLengthPercentage(nscoord aAvailable) const {
387 0 : double d = double(mPercent) * double(aAvailable) + double(mLength);
388 0 : if (d < 0.0)
389 0 : return 0;
390 0 : return NSToCoordRoundWithClamp(float(d));
391 : }
392 : };
393 : Dimension mWidth, mHeight;
394 :
395 0 : nscoord ResolveWidthLengthPercentage(const nsSize& aBgPositioningArea) const {
396 0 : NS_ABORT_IF_FALSE(mWidthType == eLengthPercentage,
397 : "resolving non-length/percent dimension!");
398 0 : return mWidth.ResolveLengthPercentage(aBgPositioningArea.width);
399 : }
400 :
401 0 : nscoord ResolveHeightLengthPercentage(const nsSize& aBgPositioningArea) const {
402 0 : NS_ABORT_IF_FALSE(mHeightType == eLengthPercentage,
403 : "resolving non-length/percent dimension!");
404 0 : return mHeight.ResolveLengthPercentage(aBgPositioningArea.height);
405 : }
406 :
407 : // Except for eLengthPercentage, Dimension types which might change
408 : // how a layer is painted when the corresponding frame's dimensions
409 : // change *must* precede all dimension types which are agnostic to
410 : // frame size; see DependsOnFrameSize.
411 : enum DimensionType {
412 : // If one of mWidth and mHeight is eContain or eCover, then both are.
413 : // Also, these two values must equal the corresponding values in
414 : // kBackgroundSizeKTable.
415 : eContain, eCover,
416 :
417 : eAuto,
418 : eLengthPercentage,
419 : eDimensionType_COUNT
420 : };
421 : PRUint8 mWidthType, mHeightType;
422 :
423 : // True if the effective image size described by this depends on the size of
424 : // the corresponding frame, when aImage (which must not have null type) is
425 : // the background image.
426 : bool DependsOnFrameSize(const nsStyleImage& aImage) const;
427 :
428 : // Initialize nothing
429 0 : Size() {}
430 :
431 : // Initialize to initial values
432 : void SetInitialValues();
433 :
434 : bool operator==(const Size& aOther) const;
435 : bool operator!=(const Size& aOther) const {
436 : return !(*this == aOther);
437 : }
438 : };
439 :
440 : struct Repeat;
441 : friend struct Repeat;
442 : struct Repeat {
443 : PRUint8 mXRepeat, mYRepeat;
444 :
445 : // Initialize nothing
446 0 : Repeat() {}
447 :
448 : // Initialize to initial values
449 : void SetInitialValues();
450 :
451 0 : bool operator==(const Repeat& aOther) const {
452 : return mXRepeat == aOther.mXRepeat &&
453 0 : mYRepeat == aOther.mYRepeat;
454 : }
455 : bool operator!=(const Repeat& aOther) const {
456 : return !(*this == aOther);
457 : }
458 : };
459 :
460 : struct Layer;
461 : friend struct Layer;
462 0 : struct Layer {
463 : PRUint8 mAttachment; // [reset] See nsStyleConsts.h
464 : PRUint8 mClip; // [reset] See nsStyleConsts.h
465 : PRUint8 mOrigin; // [reset] See nsStyleConsts.h
466 : Repeat mRepeat; // [reset] See nsStyleConsts.h
467 : Position mPosition; // [reset]
468 : nsStyleImage mImage; // [reset]
469 : Size mSize; // [reset]
470 :
471 : // Initializes only mImage
472 : Layer();
473 : ~Layer();
474 :
475 : // Register/unregister images with the document. We do this only
476 : // after the dust has settled in ComputeBackgroundData.
477 0 : void TrackImages(nsPresContext* aContext) {
478 0 : if (mImage.GetType() == eStyleImageType_Image)
479 0 : mImage.TrackImage(aContext);
480 0 : }
481 0 : void UntrackImages(nsPresContext* aContext) {
482 0 : if (mImage.GetType() == eStyleImageType_Image)
483 0 : mImage.UntrackImage(aContext);
484 0 : }
485 :
486 : void SetInitialValues();
487 :
488 : // True if the rendering of this layer might change when the size
489 : // of the corresponding frame changes. This is true for any
490 : // non-solid-color background whose position or size depends on
491 : // the frame size. It's also true for SVG images whose root <svg>
492 : // node has a viewBox.
493 : bool RenderingMightDependOnFrameSize() const;
494 :
495 : // An equality operator that compares the images using URL-equality
496 : // rather than pointer-equality.
497 : bool operator==(const Layer& aOther) const;
498 0 : bool operator!=(const Layer& aOther) const {
499 0 : return !(*this == aOther);
500 : }
501 : };
502 :
503 : // The (positive) number of computed values of each property, since
504 : // the lengths of the lists are independent.
505 : PRUint32 mAttachmentCount,
506 : mClipCount,
507 : mOriginCount,
508 : mRepeatCount,
509 : mPositionCount,
510 : mImageCount,
511 : mSizeCount;
512 : // Layers are stored in an array, matching the top-to-bottom order in
513 : // which they are specified in CSS. The number of layers to be used
514 : // should come from the background-image property. We create
515 : // additional |Layer| objects for *any* property, not just
516 : // background-image. This means that the bottommost layer that
517 : // callers in layout care about (which is also the one whose
518 : // background-clip applies to the background-color) may not be last
519 : // layer. In layers below the bottom layer, properties will be
520 : // uninitialized unless their count, above, indicates that they are
521 : // present.
522 : nsAutoTArray<Layer, 1> mLayers;
523 :
524 0 : const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
525 :
526 : #define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(var_, stylebg_) \
527 : for (PRUint32 var_ = (stylebg_)->mImageCount; var_-- != 0; )
528 :
529 : nscolor mBackgroundColor; // [reset]
530 :
531 : // FIXME: This (now background-break in css3-background) should
532 : // probably move into a different struct so that everything in
533 : // nsStyleBackground is set by the background shorthand.
534 : PRUint8 mBackgroundInlinePolicy; // [reset] See nsStyleConsts.h
535 :
536 : // True if this background is completely transparent.
537 : bool IsTransparent() const;
538 :
539 : // We have to take slower codepaths for fixed background attachment,
540 : // but we don't want to do that when there's no image.
541 : // Not inline because it uses an nsCOMPtr<imgIRequest>
542 : // FIXME: Should be in nsStyleStructInlines.h.
543 : bool HasFixedBackground() const;
544 : };
545 :
546 : // See https://bugzilla.mozilla.org/show_bug.cgi?id=271586#c43 for why
547 : // this is hard to replace with 'currentColor'.
548 : #define BORDER_COLOR_FOREGROUND 0x20
549 : #define OUTLINE_COLOR_INITIAL 0x80
550 : // FOREGROUND | INITIAL(OUTLINE)
551 : #define BORDER_COLOR_SPECIAL 0xA0
552 : #define BORDER_STYLE_MASK 0x1F
553 :
554 : #define NS_SPACING_MARGIN 0
555 : #define NS_SPACING_PADDING 1
556 : #define NS_SPACING_BORDER 2
557 :
558 :
559 : struct nsStyleMargin {
560 : nsStyleMargin(void);
561 : nsStyleMargin(const nsStyleMargin& aMargin);
562 0 : ~nsStyleMargin(void) {
563 0 : MOZ_COUNT_DTOR(nsStyleMargin);
564 0 : }
565 :
566 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
567 : void Destroy(nsPresContext* aContext);
568 :
569 : void RecalcData();
570 : nsChangeHint CalcDifference(const nsStyleMargin& aOther) const;
571 : #ifdef DEBUG
572 : static nsChangeHint MaxDifference();
573 : #endif
574 0 : static bool ForceCompare() { return true; }
575 :
576 : nsStyleSides mMargin; // [reset] coord, percent, calc, auto
577 :
578 : bool IsWidthDependent() const { return !mHasCachedMargin; }
579 0 : bool GetMargin(nsMargin& aMargin) const
580 : {
581 0 : if (mHasCachedMargin) {
582 0 : aMargin = mCachedMargin;
583 0 : return true;
584 : }
585 0 : return false;
586 : }
587 :
588 : protected:
589 : bool mHasCachedMargin;
590 : nsMargin mCachedMargin;
591 : };
592 :
593 :
594 : struct nsStylePadding {
595 : nsStylePadding(void);
596 : nsStylePadding(const nsStylePadding& aPadding);
597 0 : ~nsStylePadding(void) {
598 0 : MOZ_COUNT_DTOR(nsStylePadding);
599 0 : }
600 :
601 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
602 : void Destroy(nsPresContext* aContext);
603 :
604 : void RecalcData();
605 : nsChangeHint CalcDifference(const nsStylePadding& aOther) const;
606 : #ifdef DEBUG
607 : static nsChangeHint MaxDifference();
608 : #endif
609 0 : static bool ForceCompare() { return true; }
610 :
611 : nsStyleSides mPadding; // [reset] coord, percent, calc
612 :
613 0 : bool IsWidthDependent() const { return !mHasCachedPadding; }
614 0 : bool GetPadding(nsMargin& aPadding) const
615 : {
616 0 : if (mHasCachedPadding) {
617 0 : aPadding = mCachedPadding;
618 0 : return true;
619 : }
620 0 : return false;
621 : }
622 :
623 : protected:
624 : bool mHasCachedPadding;
625 : nsMargin mCachedPadding;
626 : };
627 :
628 : struct nsBorderColors {
629 : nsBorderColors* mNext;
630 : nscolor mColor;
631 :
632 : nsBorderColors() : mNext(nsnull), mColor(NS_RGB(0,0,0)) {}
633 0 : nsBorderColors(const nscolor& aColor) : mNext(nsnull), mColor(aColor) {}
634 : ~nsBorderColors();
635 :
636 0 : nsBorderColors* Clone() const { return Clone(true); }
637 :
638 0 : static bool Equal(const nsBorderColors* c1,
639 : const nsBorderColors* c2) {
640 0 : if (c1 == c2)
641 0 : return true;
642 0 : while (c1 && c2) {
643 0 : if (c1->mColor != c2->mColor)
644 0 : return false;
645 0 : c1 = c1->mNext;
646 0 : c2 = c2->mNext;
647 : }
648 : // both should be NULL if these are equal, otherwise one
649 : // has more colors than another
650 0 : return !c1 && !c2;
651 : }
652 :
653 : private:
654 : nsBorderColors* Clone(bool aDeep) const;
655 : };
656 :
657 : struct nsCSSShadowItem {
658 : nscoord mXOffset;
659 : nscoord mYOffset;
660 : nscoord mRadius;
661 : nscoord mSpread;
662 :
663 : nscolor mColor;
664 : bool mHasColor; // Whether mColor should be used
665 : bool mInset;
666 :
667 0 : nsCSSShadowItem() : mHasColor(false) {
668 0 : MOZ_COUNT_CTOR(nsCSSShadowItem);
669 0 : }
670 0 : ~nsCSSShadowItem() {
671 0 : MOZ_COUNT_DTOR(nsCSSShadowItem);
672 0 : }
673 :
674 0 : bool operator==(const nsCSSShadowItem& aOther) {
675 : return (mXOffset == aOther.mXOffset &&
676 : mYOffset == aOther.mYOffset &&
677 : mRadius == aOther.mRadius &&
678 : mHasColor == aOther.mHasColor &&
679 : mSpread == aOther.mSpread &&
680 : mInset == aOther.mInset &&
681 0 : (!mHasColor || mColor == aOther.mColor));
682 : }
683 0 : bool operator!=(const nsCSSShadowItem& aOther) {
684 0 : return !(*this == aOther);
685 : }
686 : };
687 :
688 : class nsCSSShadowArray {
689 : public:
690 0 : void* operator new(size_t aBaseSize, PRUint32 aArrayLen) {
691 : // We can allocate both this nsCSSShadowArray and the
692 : // actual array in one allocation. The amount of memory to
693 : // allocate is equal to the class's size + the number of bytes for all
694 : // but the first array item (because aBaseSize includes one
695 : // item, see the private declarations)
696 : return ::operator new(aBaseSize +
697 0 : (aArrayLen - 1) * sizeof(nsCSSShadowItem));
698 : }
699 :
700 0 : nsCSSShadowArray(PRUint32 aArrayLen) :
701 0 : mLength(aArrayLen)
702 : {
703 0 : MOZ_COUNT_CTOR(nsCSSShadowArray);
704 0 : for (PRUint32 i = 1; i < mLength; ++i) {
705 : // Make sure we call the constructors of each nsCSSShadowItem
706 : // (the first one is called for us because we declared it under private)
707 0 : new (&mArray[i]) nsCSSShadowItem();
708 : }
709 0 : }
710 0 : ~nsCSSShadowArray() {
711 0 : MOZ_COUNT_DTOR(nsCSSShadowArray);
712 0 : for (PRUint32 i = 1; i < mLength; ++i) {
713 0 : mArray[i].~nsCSSShadowItem();
714 : }
715 0 : }
716 :
717 0 : PRUint32 Length() const { return mLength; }
718 0 : nsCSSShadowItem* ShadowAt(PRUint32 i) {
719 0 : NS_ABORT_IF_FALSE(i < mLength, "Accessing too high an index in the text shadow array!");
720 0 : return &mArray[i];
721 : }
722 0 : const nsCSSShadowItem* ShadowAt(PRUint32 i) const {
723 0 : NS_ABORT_IF_FALSE(i < mLength, "Accessing too high an index in the text shadow array!");
724 0 : return &mArray[i];
725 : }
726 :
727 0 : NS_INLINE_DECL_REFCOUNTING(nsCSSShadowArray)
728 :
729 : private:
730 : PRUint32 mLength;
731 : nsCSSShadowItem mArray[1]; // This MUST be the last item
732 : };
733 :
734 : // Border widths are rounded to the nearest-below integer number of pixels,
735 : // but values between zero and one device pixels are always rounded up to
736 : // one device pixel.
737 : #define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \
738 : ((l) == 0) ? 0 : NS_MAX((tpp), (l) / (tpp) * (tpp))
739 : // Outline offset is rounded to the nearest integer number of pixels, but values
740 : // between zero and one device pixels are always rounded up to one device pixel.
741 : // Note that the offset can be negative.
742 : #define NS_ROUND_OFFSET_TO_PIXELS(l,tpp) \
743 : (((l) == 0) ? 0 : \
744 : ((l) > 0) ? NS_MAX( (tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) : \
745 : NS_MIN(-(tpp), ((l) - ((tpp) / 2)) / (tpp) * (tpp)))
746 :
747 : // Returns if the given border style type is visible or not
748 0 : static bool IsVisibleBorderStyle(PRUint8 aStyle)
749 : {
750 : return (aStyle != NS_STYLE_BORDER_STYLE_NONE &&
751 0 : aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
752 : }
753 :
754 : struct nsStyleBorder {
755 : nsStyleBorder(nsPresContext* aContext);
756 : nsStyleBorder(const nsStyleBorder& aBorder);
757 : ~nsStyleBorder();
758 :
759 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
760 : void Destroy(nsPresContext* aContext);
761 :
762 : nsChangeHint CalcDifference(const nsStyleBorder& aOther) const;
763 : #ifdef DEBUG
764 : static nsChangeHint MaxDifference();
765 : #endif
766 0 : static bool ForceCompare() { return false; }
767 : bool ImageBorderDiffers() const;
768 :
769 : nsStyleCorners mBorderRadius; // [reset] coord, percent, calc
770 : nsStyleSides mBorderImageSplit; // [reset] integer, percent
771 : PRUint8 mFloatEdge; // [reset] see nsStyleConsts.h
772 : PRUint8 mBorderImageHFill; // [reset]
773 : PRUint8 mBorderImageVFill; // [reset]
774 : nsBorderColors** mBorderColors; // [reset] multiple levels of color for a border.
775 : nsRefPtr<nsCSSShadowArray> mBoxShadow; // [reset] NULL for 'none'
776 : bool mHaveBorderImageWidth; // [reset]
777 : nsMargin mBorderImageWidth; // [reset]
778 :
779 0 : void EnsureBorderColors() {
780 0 : if (!mBorderColors) {
781 0 : mBorderColors = new nsBorderColors*[4];
782 0 : if (mBorderColors)
783 0 : for (PRInt32 i = 0; i < 4; i++)
784 0 : mBorderColors[i] = nsnull;
785 : }
786 0 : }
787 :
788 0 : void ClearBorderColors(mozilla::css::Side aSide) {
789 0 : if (mBorderColors && mBorderColors[aSide]) {
790 0 : delete mBorderColors[aSide];
791 0 : mBorderColors[aSide] = nsnull;
792 : }
793 0 : }
794 :
795 : // Return whether aStyle is a visible style. Invisible styles cause
796 : // the relevant computed border width to be 0.
797 : // Note that this does *not* consider the effects of 'border-image':
798 : // if border-style is none, but there is a loaded border image,
799 : // HasVisibleStyle will be false even though there *is* a border.
800 0 : bool HasVisibleStyle(mozilla::css::Side aSide)
801 : {
802 0 : return IsVisibleBorderStyle(GetBorderStyle(aSide));
803 : }
804 :
805 : // aBorderWidth is in twips
806 0 : void SetBorderWidth(mozilla::css::Side aSide, nscoord aBorderWidth)
807 : {
808 : nscoord roundedWidth =
809 0 : NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
810 0 : mBorder.Side(aSide) = roundedWidth;
811 0 : if (HasVisibleStyle(aSide))
812 0 : mComputedBorder.Side(aSide) = roundedWidth;
813 0 : }
814 :
815 0 : void SetBorderImageWidthOverride(mozilla::css::Side aSide, nscoord aBorderWidth)
816 : {
817 0 : mBorderImageWidth.Side(aSide) =
818 0 : NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
819 0 : }
820 :
821 : // Get the actual border, in twips. (If there is no border-image
822 : // loaded, this is the same as GetComputedBorder. If there is a
823 : // border-image loaded, it uses the border-image width overrides if
824 : // present, and otherwise mBorder, which is GetComputedBorder without
825 : // considering border-style: none.)
826 : const nsMargin& GetActualBorder() const;
827 :
828 : // Get the computed border (plus rounding). This does consider the
829 : // effects of 'border-style: none', but does not consider
830 : // 'border-image'.
831 0 : const nsMargin& GetComputedBorder() const
832 : {
833 0 : return mComputedBorder;
834 : }
835 :
836 : // Get the actual border width for a particular side, in appunits. Note that
837 : // this is zero if and only if there is no border to be painted for this
838 : // side. That is, this value takes into account the border style and the
839 : // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS.
840 0 : nscoord GetActualBorderWidth(mozilla::css::Side aSide) const
841 : {
842 0 : return GetActualBorder().Side(aSide);
843 : }
844 :
845 0 : PRUint8 GetBorderStyle(mozilla::css::Side aSide) const
846 : {
847 0 : NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
848 0 : return (mBorderStyle[aSide] & BORDER_STYLE_MASK);
849 : }
850 :
851 0 : void SetBorderStyle(mozilla::css::Side aSide, PRUint8 aStyle)
852 : {
853 0 : NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
854 0 : mBorderStyle[aSide] &= ~BORDER_STYLE_MASK;
855 0 : mBorderStyle[aSide] |= (aStyle & BORDER_STYLE_MASK);
856 0 : mComputedBorder.Side(aSide) =
857 0 : (HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0);
858 0 : }
859 :
860 : // Defined in nsStyleStructInlines.h
861 : inline bool IsBorderImageLoaded() const;
862 : inline nsresult RequestDecode();
863 :
864 0 : void GetBorderColor(mozilla::css::Side aSide, nscolor& aColor,
865 : bool& aForeground) const
866 : {
867 0 : aForeground = false;
868 0 : NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
869 0 : if ((mBorderStyle[aSide] & BORDER_COLOR_SPECIAL) == 0)
870 0 : aColor = mBorderColor[aSide];
871 0 : else if (mBorderStyle[aSide] & BORDER_COLOR_FOREGROUND)
872 0 : aForeground = true;
873 : else
874 0 : NS_NOTREACHED("OUTLINE_COLOR_INITIAL should not be set here");
875 0 : }
876 :
877 0 : void SetBorderColor(mozilla::css::Side aSide, nscolor aColor)
878 : {
879 0 : NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
880 0 : mBorderColor[aSide] = aColor;
881 0 : mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
882 0 : }
883 :
884 : // These are defined in nsStyleStructInlines.h
885 : inline void SetBorderImage(imgIRequest* aImage);
886 : inline imgIRequest* GetBorderImage() const;
887 :
888 0 : bool HasBorderImage() {return !!mBorderImage;}
889 :
890 : void TrackImage(nsPresContext* aContext);
891 : void UntrackImage(nsPresContext* aContext);
892 :
893 : // These methods are used for the caller to caches the sub images created during
894 : // a border-image paint operation
895 : inline void SetSubImage(PRUint8 aIndex, imgIContainer* aSubImage) const;
896 : inline imgIContainer* GetSubImage(PRUint8 aIndex) const;
897 :
898 0 : void GetCompositeColors(PRInt32 aIndex, nsBorderColors** aColors) const
899 : {
900 0 : if (!mBorderColors)
901 0 : *aColors = nsnull;
902 : else
903 0 : *aColors = mBorderColors[aIndex];
904 0 : }
905 :
906 0 : void AppendBorderColor(PRInt32 aIndex, nscolor aColor)
907 : {
908 0 : NS_ASSERTION(aIndex >= 0 && aIndex <= 3, "bad side for composite border color");
909 0 : nsBorderColors* colorEntry = new nsBorderColors(aColor);
910 0 : if (!mBorderColors[aIndex])
911 0 : mBorderColors[aIndex] = colorEntry;
912 : else {
913 0 : nsBorderColors* last = mBorderColors[aIndex];
914 0 : while (last->mNext)
915 0 : last = last->mNext;
916 0 : last->mNext = colorEntry;
917 : }
918 0 : mBorderStyle[aIndex] &= ~BORDER_COLOR_SPECIAL;
919 0 : }
920 :
921 0 : void SetBorderToForeground(mozilla::css::Side aSide)
922 : {
923 0 : NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
924 0 : mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
925 0 : mBorderStyle[aSide] |= BORDER_COLOR_FOREGROUND;
926 0 : }
927 :
928 : #ifdef DEBUG
929 : bool mImageTracked;
930 : #endif
931 :
932 : protected:
933 : // mComputedBorder holds the CSS2.1 computed border-width values. In
934 : // particular, these widths take into account the border-style for the
935 : // relevant side and the values are rounded to the nearest device
936 : // pixel. They are also rounded (which is not part of the definition
937 : // of computed values). However, they do *not* take into account the
938 : // presence of border-image. See GetActualBorder above for how to
939 : // really get the actual border.
940 : nsMargin mComputedBorder;
941 :
942 : // mBorder holds the nscoord values for the border widths as they would be if
943 : // all the border-style values were visible (not hidden or none). This
944 : // member exists so that when we create structs using the copy
945 : // constructor during style resolution the new structs will know what the
946 : // specified values of the border were in case they have more specific rules
947 : // setting the border style. Note that this isn't quite the CSS specified
948 : // value, since this has had the enumerated border widths converted to
949 : // lengths, and all lengths converted to twips. But it's not quite the
950 : // computed value either. The values are rounded to the nearest device pixel
951 : // We also use these values when we have a loaded border-image that
952 : // does not have width overrides.
953 : nsMargin mBorder;
954 :
955 : PRUint8 mBorderStyle[4]; // [reset] See nsStyleConsts.h
956 : nscolor mBorderColor[4]; // [reset] the colors to use for a simple border. not used
957 : // if -moz-border-colors is specified
958 : private:
959 : nsCOMPtr<imgIRequest> mBorderImage; // [reset]
960 :
961 : // Cache used by callers for border-image painting
962 : nsCOMArray<imgIContainer> mSubImages;
963 :
964 : nscoord mTwipsPerPixel;
965 :
966 : nsStyleBorder& operator=(const nsStyleBorder& aOther) MOZ_DELETE;
967 : };
968 :
969 :
970 : struct nsStyleOutline {
971 : nsStyleOutline(nsPresContext* aPresContext);
972 : nsStyleOutline(const nsStyleOutline& aOutline);
973 0 : ~nsStyleOutline(void) {
974 0 : MOZ_COUNT_DTOR(nsStyleOutline);
975 0 : }
976 :
977 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
978 0 : return aContext->AllocateFromShell(sz);
979 : }
980 0 : void Destroy(nsPresContext* aContext) {
981 0 : this->~nsStyleOutline();
982 0 : aContext->FreeToShell(sizeof(nsStyleOutline), this);
983 0 : }
984 :
985 : void RecalcData(nsPresContext* aContext);
986 : nsChangeHint CalcDifference(const nsStyleOutline& aOther) const;
987 : #ifdef DEBUG
988 : static nsChangeHint MaxDifference();
989 : #endif
990 0 : static bool ForceCompare() { return false; }
991 :
992 : nsStyleCorners mOutlineRadius; // [reset] coord, percent, calc
993 :
994 : // Note that this is a specified value. You can get the actual values
995 : // with GetOutlineWidth. You cannot get the computed value directly.
996 : nsStyleCoord mOutlineWidth; // [reset] coord, enum (see nsStyleConsts.h)
997 : nscoord mOutlineOffset; // [reset]
998 :
999 0 : bool GetOutlineWidth(nscoord& aWidth) const
1000 : {
1001 0 : if (mHasCachedOutline) {
1002 0 : aWidth = mCachedOutlineWidth;
1003 0 : return true;
1004 : }
1005 0 : return false;
1006 : }
1007 :
1008 0 : PRUint8 GetOutlineStyle(void) const
1009 : {
1010 0 : return (mOutlineStyle & BORDER_STYLE_MASK);
1011 : }
1012 :
1013 0 : void SetOutlineStyle(PRUint8 aStyle)
1014 : {
1015 0 : mOutlineStyle &= ~BORDER_STYLE_MASK;
1016 0 : mOutlineStyle |= (aStyle & BORDER_STYLE_MASK);
1017 0 : }
1018 :
1019 : // false means initial value
1020 0 : bool GetOutlineColor(nscolor& aColor) const
1021 : {
1022 0 : if ((mOutlineStyle & BORDER_COLOR_SPECIAL) == 0) {
1023 0 : aColor = mOutlineColor;
1024 0 : return true;
1025 : }
1026 0 : return false;
1027 : }
1028 :
1029 0 : void SetOutlineColor(nscolor aColor)
1030 : {
1031 0 : mOutlineColor = aColor;
1032 0 : mOutlineStyle &= ~BORDER_COLOR_SPECIAL;
1033 0 : }
1034 :
1035 0 : void SetOutlineInitialColor()
1036 : {
1037 0 : mOutlineStyle |= OUTLINE_COLOR_INITIAL;
1038 0 : }
1039 :
1040 0 : bool GetOutlineInitialColor() const
1041 : {
1042 0 : return !!(mOutlineStyle & OUTLINE_COLOR_INITIAL);
1043 : }
1044 :
1045 : protected:
1046 : // This value is the actual value, so it's rounded to the nearest device
1047 : // pixel.
1048 : nscoord mCachedOutlineWidth;
1049 :
1050 : nscolor mOutlineColor; // [reset]
1051 :
1052 : bool mHasCachedOutline;
1053 : PRUint8 mOutlineStyle; // [reset] See nsStyleConsts.h
1054 :
1055 : nscoord mTwipsPerPixel;
1056 : };
1057 :
1058 :
1059 : struct nsStyleList {
1060 : nsStyleList(void);
1061 : nsStyleList(const nsStyleList& aStyleList);
1062 : ~nsStyleList(void);
1063 :
1064 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
1065 0 : return aContext->AllocateFromShell(sz);
1066 : }
1067 0 : void Destroy(nsPresContext* aContext) {
1068 0 : this->~nsStyleList();
1069 0 : aContext->FreeToShell(sizeof(nsStyleList), this);
1070 0 : }
1071 :
1072 : nsChangeHint CalcDifference(const nsStyleList& aOther) const;
1073 : #ifdef DEBUG
1074 : static nsChangeHint MaxDifference();
1075 : #endif
1076 0 : static bool ForceCompare() { return false; }
1077 :
1078 0 : imgIRequest* GetListStyleImage() const { return mListStyleImage; }
1079 0 : void SetListStyleImage(imgIRequest* aReq)
1080 : {
1081 0 : if (mListStyleImage)
1082 0 : mListStyleImage->UnlockImage();
1083 0 : mListStyleImage = aReq;
1084 0 : if (mListStyleImage)
1085 0 : mListStyleImage->LockImage();
1086 0 : }
1087 :
1088 : PRUint8 mListStyleType; // [inherited] See nsStyleConsts.h
1089 : PRUint8 mListStylePosition; // [inherited]
1090 : private:
1091 : nsCOMPtr<imgIRequest> mListStyleImage; // [inherited]
1092 : nsStyleList& operator=(const nsStyleList& aOther) MOZ_DELETE;
1093 : public:
1094 : nsRect mImageRegion; // [inherited] the rect to use within an image
1095 : };
1096 :
1097 : struct nsStylePosition {
1098 : nsStylePosition(void);
1099 : nsStylePosition(const nsStylePosition& aOther);
1100 : ~nsStylePosition(void);
1101 :
1102 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
1103 0 : return aContext->AllocateFromShell(sz);
1104 : }
1105 0 : void Destroy(nsPresContext* aContext) {
1106 0 : this->~nsStylePosition();
1107 0 : aContext->FreeToShell(sizeof(nsStylePosition), this);
1108 0 : }
1109 :
1110 : nsChangeHint CalcDifference(const nsStylePosition& aOther) const;
1111 : #ifdef DEBUG
1112 : static nsChangeHint MaxDifference();
1113 : #endif
1114 0 : static bool ForceCompare() { return true; }
1115 :
1116 : nsStyleSides mOffset; // [reset] coord, percent, calc, auto
1117 : nsStyleCoord mWidth; // [reset] coord, percent, enum, calc, auto
1118 : nsStyleCoord mMinWidth; // [reset] coord, percent, enum, calc
1119 : nsStyleCoord mMaxWidth; // [reset] coord, percent, enum, calc, none
1120 : nsStyleCoord mHeight; // [reset] coord, percent, calc, auto
1121 : nsStyleCoord mMinHeight; // [reset] coord, percent, calc
1122 : nsStyleCoord mMaxHeight; // [reset] coord, percent, calc, none
1123 : PRUint8 mBoxSizing; // [reset] see nsStyleConsts.h
1124 : nsStyleCoord mZIndex; // [reset] integer, auto
1125 :
1126 0 : bool WidthDependsOnContainer() const
1127 0 : { return WidthCoordDependsOnContainer(mWidth); }
1128 0 : bool MinWidthDependsOnContainer() const
1129 0 : { return WidthCoordDependsOnContainer(mMinWidth); }
1130 0 : bool MaxWidthDependsOnContainer() const
1131 0 : { return WidthCoordDependsOnContainer(mMaxWidth); }
1132 :
1133 : // Note that these functions count 'auto' as depending on the
1134 : // container since that's the case for absolutely positioned elements.
1135 : // However, some callers do not care about this case and should check
1136 : // for it, since it is the most common case.
1137 : // FIXME: We should probably change the assumption to be the other way
1138 : // around.
1139 0 : bool HeightDependsOnContainer() const
1140 0 : { return HeightCoordDependsOnContainer(mHeight); }
1141 0 : bool MinHeightDependsOnContainer() const
1142 0 : { return HeightCoordDependsOnContainer(mMinHeight); }
1143 0 : bool MaxHeightDependsOnContainer() const
1144 0 : { return HeightCoordDependsOnContainer(mMaxHeight); }
1145 :
1146 0 : bool OffsetHasPercent(mozilla::css::Side aSide) const
1147 : {
1148 0 : return mOffset.Get(aSide).HasPercent();
1149 : }
1150 :
1151 : private:
1152 : static bool WidthCoordDependsOnContainer(const nsStyleCoord &aCoord);
1153 0 : static bool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord)
1154 : {
1155 0 : return aCoord.GetUnit() == eStyleUnit_Auto || // CSS 2.1, 10.6.4, item (5)
1156 0 : aCoord.HasPercent();
1157 : }
1158 : };
1159 :
1160 0 : struct nsStyleTextOverflowSide {
1161 0 : nsStyleTextOverflowSide() : mType(NS_STYLE_TEXT_OVERFLOW_CLIP) {}
1162 :
1163 0 : bool operator==(const nsStyleTextOverflowSide& aOther) const {
1164 : return mType == aOther.mType &&
1165 : (mType != NS_STYLE_TEXT_OVERFLOW_STRING ||
1166 0 : mString == aOther.mString);
1167 : }
1168 : bool operator!=(const nsStyleTextOverflowSide& aOther) const {
1169 : return !(*this == aOther);
1170 : }
1171 :
1172 : nsString mString;
1173 : PRUint8 mType;
1174 : };
1175 :
1176 0 : struct nsStyleTextOverflow {
1177 0 : nsStyleTextOverflow() : mLogicalDirections(true) {}
1178 0 : bool operator==(const nsStyleTextOverflow& aOther) const {
1179 0 : return mLeft == aOther.mLeft && mRight == aOther.mRight;
1180 : }
1181 0 : bool operator!=(const nsStyleTextOverflow& aOther) const {
1182 0 : return !(*this == aOther);
1183 : }
1184 :
1185 : // Returns the value to apply on the left side.
1186 0 : const nsStyleTextOverflowSide& GetLeft(PRUint8 aDirection) const {
1187 0 : NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
1188 : aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
1189 0 : return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
1190 0 : mLeft : mRight;
1191 : }
1192 :
1193 : // Returns the value to apply on the right side.
1194 0 : const nsStyleTextOverflowSide& GetRight(PRUint8 aDirection) const {
1195 0 : NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
1196 : aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
1197 0 : return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
1198 0 : mRight : mLeft;
1199 : }
1200 :
1201 : // Returns the first value that was specified.
1202 0 : const nsStyleTextOverflowSide* GetFirstValue() const {
1203 0 : return mLogicalDirections ? &mRight : &mLeft;
1204 : }
1205 :
1206 : // Returns the second value, or null if there was only one value specified.
1207 0 : const nsStyleTextOverflowSide* GetSecondValue() const {
1208 0 : return mLogicalDirections ? nsnull : &mRight;
1209 : }
1210 :
1211 : nsStyleTextOverflowSide mLeft; // start side when mLogicalDirections is true
1212 : nsStyleTextOverflowSide mRight; // end side when mLogicalDirections is true
1213 : bool mLogicalDirections; // true when only one value was specified
1214 : };
1215 :
1216 0 : struct nsStyleTextReset {
1217 : nsStyleTextReset(void);
1218 : nsStyleTextReset(const nsStyleTextReset& aOther);
1219 : ~nsStyleTextReset(void);
1220 :
1221 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
1222 0 : return aContext->AllocateFromShell(sz);
1223 : }
1224 0 : void Destroy(nsPresContext* aContext) {
1225 0 : this->~nsStyleTextReset();
1226 0 : aContext->FreeToShell(sizeof(nsStyleTextReset), this);
1227 0 : }
1228 :
1229 0 : PRUint8 GetDecorationStyle() const
1230 : {
1231 0 : return (mTextDecorationStyle & BORDER_STYLE_MASK);
1232 : }
1233 :
1234 0 : void SetDecorationStyle(PRUint8 aStyle)
1235 : {
1236 0 : NS_ABORT_IF_FALSE((aStyle & BORDER_STYLE_MASK) == aStyle,
1237 : "style doesn't fit");
1238 0 : mTextDecorationStyle &= ~BORDER_STYLE_MASK;
1239 0 : mTextDecorationStyle |= (aStyle & BORDER_STYLE_MASK);
1240 0 : }
1241 :
1242 0 : void GetDecorationColor(nscolor& aColor, bool& aForeground) const
1243 : {
1244 0 : aForeground = false;
1245 0 : if ((mTextDecorationStyle & BORDER_COLOR_SPECIAL) == 0) {
1246 0 : aColor = mTextDecorationColor;
1247 0 : } else if (mTextDecorationStyle & BORDER_COLOR_FOREGROUND) {
1248 0 : aForeground = true;
1249 : } else {
1250 0 : NS_NOTREACHED("OUTLINE_COLOR_INITIAL should not be set here");
1251 : }
1252 0 : }
1253 :
1254 0 : void SetDecorationColor(nscolor aColor)
1255 : {
1256 0 : mTextDecorationColor = aColor;
1257 0 : mTextDecorationStyle &= ~BORDER_COLOR_SPECIAL;
1258 0 : }
1259 :
1260 0 : void SetDecorationColorToForeground()
1261 : {
1262 0 : mTextDecorationStyle &= ~BORDER_COLOR_SPECIAL;
1263 0 : mTextDecorationStyle |= BORDER_COLOR_FOREGROUND;
1264 0 : }
1265 :
1266 : nsChangeHint CalcDifference(const nsStyleTextReset& aOther) const;
1267 : #ifdef DEBUG
1268 : static nsChangeHint MaxDifference();
1269 : #endif
1270 0 : static bool ForceCompare() { return false; }
1271 :
1272 : nsStyleCoord mVerticalAlign; // [reset] coord, percent, calc, enum (see nsStyleConsts.h)
1273 : nsStyleTextOverflow mTextOverflow; // [reset] enum, string
1274 :
1275 : PRUint8 mTextBlink; // [reset] see nsStyleConsts.h
1276 : PRUint8 mTextDecorationLine; // [reset] see nsStyleConsts.h
1277 : PRUint8 mUnicodeBidi; // [reset] see nsStyleConsts.h
1278 : protected:
1279 : PRUint8 mTextDecorationStyle; // [reset] see nsStyleConsts.h
1280 :
1281 : nscolor mTextDecorationColor; // [reset] the colors to use for a decoration lines, not used at currentColor
1282 : };
1283 :
1284 : struct nsStyleText {
1285 : nsStyleText(void);
1286 : nsStyleText(const nsStyleText& aOther);
1287 : ~nsStyleText(void);
1288 :
1289 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
1290 0 : return aContext->AllocateFromShell(sz);
1291 : }
1292 0 : void Destroy(nsPresContext* aContext) {
1293 0 : this->~nsStyleText();
1294 0 : aContext->FreeToShell(sizeof(nsStyleText), this);
1295 0 : }
1296 :
1297 : nsChangeHint CalcDifference(const nsStyleText& aOther) const;
1298 : #ifdef DEBUG
1299 : static nsChangeHint MaxDifference();
1300 : #endif
1301 0 : static bool ForceCompare() { return false; }
1302 :
1303 : PRUint8 mTextAlign; // [inherited] see nsStyleConsts.h
1304 : PRUint8 mTextAlignLast; // [inherited] see nsStyleConsts.h
1305 : PRUint8 mTextTransform; // [inherited] see nsStyleConsts.h
1306 : PRUint8 mWhiteSpace; // [inherited] see nsStyleConsts.h
1307 : PRUint8 mWordWrap; // [inherited] see nsStyleConsts.h
1308 : PRUint8 mHyphens; // [inherited] see nsStyleConsts.h
1309 : PRUint8 mTextSizeAdjust; // [inherited] see nsStyleConsts.h
1310 : PRInt32 mTabSize; // [inherited] see nsStyleConsts.h
1311 :
1312 : nsStyleCoord mLetterSpacing; // [inherited] coord, normal
1313 : nsStyleCoord mLineHeight; // [inherited] coord, factor, normal
1314 : nsStyleCoord mTextIndent; // [inherited] coord, percent, calc
1315 : nscoord mWordSpacing; // [inherited]
1316 :
1317 : nsRefPtr<nsCSSShadowArray> mTextShadow; // [inherited] NULL in case of a zero-length
1318 :
1319 0 : bool WhiteSpaceIsSignificant() const {
1320 : return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
1321 0 : mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP;
1322 : }
1323 :
1324 0 : bool NewlineIsSignificant() const {
1325 : return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
1326 : mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
1327 0 : mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE;
1328 : }
1329 :
1330 0 : bool WhiteSpaceCanWrap() const {
1331 : return mWhiteSpace == NS_STYLE_WHITESPACE_NORMAL ||
1332 : mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
1333 0 : mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE;
1334 : }
1335 :
1336 0 : bool WordCanWrap() const {
1337 0 : return WhiteSpaceCanWrap() && mWordWrap == NS_STYLE_WORDWRAP_BREAK_WORD;
1338 : }
1339 : };
1340 :
1341 : struct nsStyleVisibility {
1342 : nsStyleVisibility(nsPresContext* aPresContext);
1343 : nsStyleVisibility(const nsStyleVisibility& aVisibility);
1344 0 : ~nsStyleVisibility() {
1345 0 : MOZ_COUNT_DTOR(nsStyleVisibility);
1346 0 : }
1347 :
1348 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
1349 0 : return aContext->AllocateFromShell(sz);
1350 : }
1351 0 : void Destroy(nsPresContext* aContext) {
1352 0 : this->~nsStyleVisibility();
1353 0 : aContext->FreeToShell(sizeof(nsStyleVisibility), this);
1354 0 : }
1355 :
1356 : nsChangeHint CalcDifference(const nsStyleVisibility& aOther) const;
1357 : #ifdef DEBUG
1358 : static nsChangeHint MaxDifference();
1359 : #endif
1360 0 : static bool ForceCompare() { return false; }
1361 :
1362 : PRUint8 mDirection; // [inherited] see nsStyleConsts.h NS_STYLE_DIRECTION_*
1363 : PRUint8 mVisible; // [inherited]
1364 : PRUint8 mPointerEvents; // [inherited] see nsStyleConsts.h
1365 :
1366 0 : bool IsVisible() const {
1367 0 : return (mVisible == NS_STYLE_VISIBILITY_VISIBLE);
1368 : }
1369 :
1370 0 : bool IsVisibleOrCollapsed() const {
1371 : return ((mVisible == NS_STYLE_VISIBILITY_VISIBLE) ||
1372 0 : (mVisible == NS_STYLE_VISIBILITY_COLLAPSE));
1373 : }
1374 : };
1375 :
1376 : struct nsTimingFunction {
1377 : enum Type { Function, StepStart, StepEnd };
1378 :
1379 0 : explicit nsTimingFunction(PRInt32 aTimingFunctionType
1380 : = NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE)
1381 : {
1382 0 : AssignFromKeyword(aTimingFunctionType);
1383 0 : }
1384 :
1385 0 : nsTimingFunction(float x1, float y1, float x2, float y2)
1386 0 : : mType(Function)
1387 : {
1388 0 : mFunc.mX1 = x1;
1389 0 : mFunc.mY1 = y1;
1390 0 : mFunc.mX2 = x2;
1391 0 : mFunc.mY2 = y2;
1392 0 : }
1393 :
1394 0 : nsTimingFunction(Type aType, PRUint32 aSteps)
1395 0 : : mType(aType)
1396 : {
1397 0 : NS_ABORT_IF_FALSE(mType == StepStart || mType == StepEnd, "wrong type");
1398 0 : mSteps = aSteps;
1399 0 : }
1400 :
1401 0 : nsTimingFunction(const nsTimingFunction& aOther)
1402 : {
1403 0 : *this = aOther;
1404 0 : }
1405 :
1406 : Type mType;
1407 : union {
1408 : struct {
1409 : float mX1;
1410 : float mY1;
1411 : float mX2;
1412 : float mY2;
1413 : } mFunc;
1414 : PRUint32 mSteps;
1415 : };
1416 :
1417 : nsTimingFunction&
1418 0 : operator=(const nsTimingFunction& aOther)
1419 : {
1420 0 : if (&aOther == this)
1421 0 : return *this;
1422 :
1423 0 : mType = aOther.mType;
1424 :
1425 0 : if (mType == Function) {
1426 0 : mFunc.mX1 = aOther.mFunc.mX1;
1427 0 : mFunc.mY1 = aOther.mFunc.mY1;
1428 0 : mFunc.mX2 = aOther.mFunc.mX2;
1429 0 : mFunc.mY2 = aOther.mFunc.mY2;
1430 : } else {
1431 0 : mSteps = aOther.mSteps;
1432 : }
1433 :
1434 0 : return *this;
1435 : }
1436 :
1437 : bool operator==(const nsTimingFunction& aOther) const
1438 : {
1439 : if (mType != aOther.mType) {
1440 : return false;
1441 : }
1442 : if (mType == Function) {
1443 : return mFunc.mX1 == aOther.mFunc.mX1 && mFunc.mY1 == aOther.mFunc.mY1 &&
1444 : mFunc.mX2 == aOther.mFunc.mX2 && mFunc.mY2 == aOther.mFunc.mY2;
1445 : }
1446 : return mSteps == aOther.mSteps;
1447 : }
1448 :
1449 : bool operator!=(const nsTimingFunction& aOther) const
1450 : {
1451 : return !(*this == aOther);
1452 : }
1453 :
1454 : private:
1455 : void AssignFromKeyword(PRInt32 aTimingFunctionType);
1456 : };
1457 :
1458 0 : struct nsTransition {
1459 0 : nsTransition() { /* leaves uninitialized; see also SetInitialValues */ }
1460 : explicit nsTransition(const nsTransition& aCopy);
1461 :
1462 : void SetInitialValues();
1463 :
1464 : // Delay and Duration are in milliseconds
1465 :
1466 0 : const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
1467 0 : float GetDelay() const { return mDelay; }
1468 0 : float GetDuration() const { return mDuration; }
1469 0 : nsCSSProperty GetProperty() const { return mProperty; }
1470 0 : nsIAtom* GetUnknownProperty() const { return mUnknownProperty; }
1471 :
1472 0 : void SetTimingFunction(const nsTimingFunction& aTimingFunction)
1473 0 : { mTimingFunction = aTimingFunction; }
1474 0 : void SetDelay(float aDelay) { mDelay = aDelay; }
1475 0 : void SetDuration(float aDuration) { mDuration = aDuration; }
1476 0 : void SetProperty(nsCSSProperty aProperty)
1477 : {
1478 0 : NS_ASSERTION(aProperty != eCSSProperty_UNKNOWN, "invalid property");
1479 0 : mProperty = aProperty;
1480 0 : }
1481 : void SetUnknownProperty(const nsAString& aUnknownProperty);
1482 0 : void CopyPropertyFrom(const nsTransition& aOther)
1483 : {
1484 0 : mProperty = aOther.mProperty;
1485 0 : mUnknownProperty = aOther.mUnknownProperty;
1486 0 : }
1487 :
1488 0 : nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
1489 :
1490 : private:
1491 : nsTimingFunction mTimingFunction;
1492 : float mDuration;
1493 : float mDelay;
1494 : nsCSSProperty mProperty;
1495 : nsCOMPtr<nsIAtom> mUnknownProperty; // used when mProperty is
1496 : // eCSSProperty_UNKNOWN
1497 : };
1498 :
1499 0 : struct nsAnimation {
1500 0 : nsAnimation() { /* leaves uninitialized; see also SetInitialValues */ }
1501 : explicit nsAnimation(const nsAnimation& aCopy);
1502 :
1503 : void SetInitialValues();
1504 :
1505 : // Delay and Duration are in milliseconds
1506 :
1507 0 : const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
1508 0 : float GetDelay() const { return mDelay; }
1509 0 : float GetDuration() const { return mDuration; }
1510 0 : const nsString& GetName() const { return mName; }
1511 0 : PRUint8 GetDirection() const { return mDirection; }
1512 0 : PRUint8 GetFillMode() const { return mFillMode; }
1513 0 : PRUint8 GetPlayState() const { return mPlayState; }
1514 0 : float GetIterationCount() const { return mIterationCount; }
1515 :
1516 0 : void SetTimingFunction(const nsTimingFunction& aTimingFunction)
1517 0 : { mTimingFunction = aTimingFunction; }
1518 0 : void SetDelay(float aDelay) { mDelay = aDelay; }
1519 0 : void SetDuration(float aDuration) { mDuration = aDuration; }
1520 0 : void SetName(const nsSubstring& aName) { mName = aName; }
1521 0 : void SetDirection(PRUint8 aDirection) { mDirection = aDirection; }
1522 0 : void SetFillMode(PRUint8 aFillMode) { mFillMode = aFillMode; }
1523 0 : void SetPlayState(PRUint8 aPlayState) { mPlayState = aPlayState; }
1524 0 : void SetIterationCount(float aIterationCount)
1525 0 : { mIterationCount = aIterationCount; }
1526 :
1527 0 : nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
1528 :
1529 : private:
1530 : nsTimingFunction mTimingFunction;
1531 : float mDuration;
1532 : float mDelay;
1533 : nsString mName; // empty string for 'none'
1534 : PRUint8 mDirection;
1535 : PRUint8 mFillMode;
1536 : PRUint8 mPlayState;
1537 : float mIterationCount; // NS_IEEEPositiveInfinity() means infinite
1538 : };
1539 :
1540 : struct nsStyleDisplay {
1541 : nsStyleDisplay();
1542 : nsStyleDisplay(const nsStyleDisplay& aOther);
1543 0 : ~nsStyleDisplay() {
1544 0 : MOZ_COUNT_DTOR(nsStyleDisplay);
1545 0 : }
1546 :
1547 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
1548 0 : return aContext->AllocateFromShell(sz);
1549 : }
1550 0 : void Destroy(nsPresContext* aContext) {
1551 0 : this->~nsStyleDisplay();
1552 0 : aContext->FreeToShell(sizeof(nsStyleDisplay), this);
1553 0 : }
1554 :
1555 : nsChangeHint CalcDifference(const nsStyleDisplay& aOther) const;
1556 : #ifdef DEBUG
1557 : static nsChangeHint MaxDifference();
1558 : #endif
1559 0 : static bool ForceCompare() { return true; }
1560 :
1561 : // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
1562 : // mBinding->mOriginPrincipal.
1563 : nsRefPtr<nsCSSValue::URL> mBinding; // [reset]
1564 : nsRect mClip; // [reset] offsets from upper-left border edge
1565 : float mOpacity; // [reset]
1566 : PRUint8 mDisplay; // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*
1567 : PRUint8 mOriginalDisplay; // [reset] saved mDisplay for position:absolute/fixed
1568 : // and float:left/right; otherwise equal
1569 : // to mDisplay
1570 : PRUint8 mAppearance; // [reset]
1571 : PRUint8 mPosition; // [reset] see nsStyleConsts.h
1572 : PRUint8 mFloats; // [reset] see nsStyleConsts.h NS_STYLE_FLOAT_*
1573 : PRUint8 mOriginalFloats; // [reset] saved mFloats for position:absolute/fixed;
1574 : // otherwise equal to mFloats
1575 : PRUint8 mBreakType; // [reset] see nsStyleConsts.h NS_STYLE_CLEAR_*
1576 : bool mBreakBefore; // [reset]
1577 : bool mBreakAfter; // [reset]
1578 : PRUint8 mOverflowX; // [reset] see nsStyleConsts.h
1579 : PRUint8 mOverflowY; // [reset] see nsStyleConsts.h
1580 : PRUint8 mResize; // [reset] see nsStyleConsts.h
1581 : PRUint8 mClipFlags; // [reset] see nsStyleConsts.h
1582 : PRUint8 mOrient; // [reset] see nsStyleConsts.h
1583 :
1584 : // mSpecifiedTransform is the list of transform functions as
1585 : // specified, or null to indicate there is no transform. (inherit or
1586 : // initial are replaced by an actual list of transform functions, or
1587 : // null, as appropriate.) (owned by the style rule)
1588 : const nsCSSValueList *mSpecifiedTransform; // [reset]
1589 : nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only
1590 : nsStyleCoord mChildPerspective; // [reset] coord
1591 : nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc
1592 : PRUint8 mBackfaceVisibility;
1593 : PRUint8 mTransformStyle;
1594 :
1595 : nsAutoTArray<nsTransition, 1> mTransitions; // [reset]
1596 : // The number of elements in mTransitions that are not from repeating
1597 : // a list due to another property being longer.
1598 : PRUint32 mTransitionTimingFunctionCount,
1599 : mTransitionDurationCount,
1600 : mTransitionDelayCount,
1601 : mTransitionPropertyCount;
1602 :
1603 : nsAutoTArray<nsAnimation, 1> mAnimations; // [reset]
1604 : // The number of elements in mAnimations that are not from repeating
1605 : // a list due to another property being longer.
1606 : PRUint32 mAnimationTimingFunctionCount,
1607 : mAnimationDurationCount,
1608 : mAnimationDelayCount,
1609 : mAnimationNameCount,
1610 : mAnimationDirectionCount,
1611 : mAnimationFillModeCount,
1612 : mAnimationPlayStateCount,
1613 : mAnimationIterationCountCount;
1614 :
1615 0 : bool IsBlockInside() const {
1616 : return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
1617 : NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
1618 0 : NS_STYLE_DISPLAY_INLINE_BLOCK == mDisplay;
1619 : // Should TABLE_CELL and TABLE_CAPTION go here? They have
1620 : // block frames nested inside of them.
1621 : // (But please audit all callers before changing.)
1622 : }
1623 :
1624 0 : bool IsBlockOutside() const {
1625 : return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
1626 : NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
1627 0 : NS_STYLE_DISPLAY_TABLE == mDisplay;
1628 : }
1629 :
1630 0 : static bool IsDisplayTypeInlineOutside(PRUint8 aDisplay) {
1631 : return NS_STYLE_DISPLAY_INLINE == aDisplay ||
1632 : NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay ||
1633 : NS_STYLE_DISPLAY_INLINE_TABLE == aDisplay ||
1634 : NS_STYLE_DISPLAY_INLINE_BOX == aDisplay ||
1635 : NS_STYLE_DISPLAY_INLINE_GRID == aDisplay ||
1636 0 : NS_STYLE_DISPLAY_INLINE_STACK == aDisplay;
1637 : }
1638 :
1639 0 : bool IsInlineOutside() const {
1640 0 : return IsDisplayTypeInlineOutside(mDisplay);
1641 : }
1642 :
1643 0 : bool IsOriginalDisplayInlineOutside() const {
1644 0 : return IsDisplayTypeInlineOutside(mOriginalDisplay);
1645 : }
1646 :
1647 0 : bool IsFloating() const {
1648 0 : return NS_STYLE_FLOAT_NONE != mFloats;
1649 : }
1650 :
1651 0 : bool IsAbsolutelyPositioned() const {return (NS_STYLE_POSITION_ABSOLUTE == mPosition) ||
1652 0 : (NS_STYLE_POSITION_FIXED == mPosition);}
1653 :
1654 : /* Returns true if we're positioned or there's a transform in effect. */
1655 0 : bool IsPositioned() const {
1656 0 : return IsAbsolutelyPositioned() ||
1657 0 : NS_STYLE_POSITION_RELATIVE == mPosition || HasTransform();
1658 : }
1659 :
1660 0 : bool IsScrollableOverflow() const {
1661 : // mOverflowX and mOverflowY always match when one of them is
1662 : // NS_STYLE_OVERFLOW_VISIBLE or NS_STYLE_OVERFLOW_CLIP.
1663 : return mOverflowX != NS_STYLE_OVERFLOW_VISIBLE &&
1664 0 : mOverflowX != NS_STYLE_OVERFLOW_CLIP;
1665 : }
1666 :
1667 : /* Returns whether the element has the -moz-transform property. */
1668 0 : bool HasTransform() const {
1669 : return mSpecifiedTransform != nsnull ||
1670 : mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
1671 0 : mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN;
1672 : }
1673 : };
1674 :
1675 : struct nsStyleTable {
1676 : nsStyleTable(void);
1677 : nsStyleTable(const nsStyleTable& aOther);
1678 : ~nsStyleTable(void);
1679 :
1680 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
1681 0 : return aContext->AllocateFromShell(sz);
1682 : }
1683 0 : void Destroy(nsPresContext* aContext) {
1684 0 : this->~nsStyleTable();
1685 0 : aContext->FreeToShell(sizeof(nsStyleTable), this);
1686 0 : }
1687 :
1688 : nsChangeHint CalcDifference(const nsStyleTable& aOther) const;
1689 : #ifdef DEBUG
1690 : static nsChangeHint MaxDifference();
1691 : #endif
1692 0 : static bool ForceCompare() { return false; }
1693 :
1694 : PRUint8 mLayoutStrategy;// [reset] see nsStyleConsts.h NS_STYLE_TABLE_LAYOUT_*
1695 : PRUint8 mFrame; // [reset] see nsStyleConsts.h NS_STYLE_TABLE_FRAME_*
1696 : PRUint8 mRules; // [reset] see nsStyleConsts.h NS_STYLE_TABLE_RULES_*
1697 : PRInt32 mCols; // [reset] an integer if set, or see nsStyleConsts.h NS_STYLE_TABLE_COLS_*
1698 : PRInt32 mSpan; // [reset] the number of columns spanned by a colgroup or col
1699 : };
1700 :
1701 : struct nsStyleTableBorder {
1702 : nsStyleTableBorder(nsPresContext* aContext);
1703 : nsStyleTableBorder(const nsStyleTableBorder& aOther);
1704 : ~nsStyleTableBorder(void);
1705 :
1706 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
1707 0 : return aContext->AllocateFromShell(sz);
1708 : }
1709 0 : void Destroy(nsPresContext* aContext) {
1710 0 : this->~nsStyleTableBorder();
1711 0 : aContext->FreeToShell(sizeof(nsStyleTableBorder), this);
1712 0 : }
1713 :
1714 : nsChangeHint CalcDifference(const nsStyleTableBorder& aOther) const;
1715 : #ifdef DEBUG
1716 : static nsChangeHint MaxDifference();
1717 : #endif
1718 0 : static bool ForceCompare() { return false; }
1719 :
1720 : nscoord mBorderSpacingX;// [inherited]
1721 : nscoord mBorderSpacingY;// [inherited]
1722 : PRUint8 mBorderCollapse;// [inherited]
1723 : PRUint8 mCaptionSide; // [inherited]
1724 : PRUint8 mEmptyCells; // [inherited]
1725 : };
1726 :
1727 : enum nsStyleContentType {
1728 : eStyleContentType_String = 1,
1729 : eStyleContentType_Image = 10,
1730 : eStyleContentType_Attr = 20,
1731 : eStyleContentType_Counter = 30,
1732 : eStyleContentType_Counters = 31,
1733 : eStyleContentType_OpenQuote = 40,
1734 : eStyleContentType_CloseQuote = 41,
1735 : eStyleContentType_NoOpenQuote = 42,
1736 : eStyleContentType_NoCloseQuote = 43,
1737 : eStyleContentType_AltContent = 50
1738 : };
1739 :
1740 : struct nsStyleContentData {
1741 : nsStyleContentType mType;
1742 : union {
1743 : PRUnichar *mString;
1744 : imgIRequest *mImage;
1745 : nsCSSValue::Array* mCounters;
1746 : } mContent;
1747 : #ifdef DEBUG
1748 : bool mImageTracked;
1749 : #endif
1750 :
1751 0 : nsStyleContentData()
1752 : : mType(nsStyleContentType(0))
1753 : #ifdef DEBUG
1754 0 : , mImageTracked(false)
1755 : #endif
1756 0 : { mContent.mString = nsnull; }
1757 :
1758 : ~nsStyleContentData();
1759 : nsStyleContentData& operator=(const nsStyleContentData& aOther);
1760 : bool operator==(const nsStyleContentData& aOther) const;
1761 :
1762 0 : bool operator!=(const nsStyleContentData& aOther) const {
1763 0 : return !(*this == aOther);
1764 : }
1765 :
1766 : void TrackImage(nsPresContext* aContext);
1767 : void UntrackImage(nsPresContext* aContext);
1768 :
1769 0 : void SetImage(imgIRequest* aRequest)
1770 : {
1771 0 : NS_ABORT_IF_FALSE(!mImageTracked,
1772 : "Setting a new image without untracking the old one!");
1773 0 : NS_ABORT_IF_FALSE(mType == eStyleContentType_Image, "Wrong type!");
1774 0 : NS_IF_ADDREF(mContent.mImage = aRequest);
1775 0 : }
1776 : private:
1777 : nsStyleContentData(const nsStyleContentData&); // not to be implemented
1778 : };
1779 :
1780 0 : struct nsStyleCounterData {
1781 : nsString mCounter;
1782 : PRInt32 mValue;
1783 : };
1784 :
1785 :
1786 : #define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nsnull; }
1787 :
1788 : struct nsStyleQuotes {
1789 : nsStyleQuotes();
1790 : nsStyleQuotes(const nsStyleQuotes& aQuotes);
1791 : ~nsStyleQuotes();
1792 :
1793 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
1794 0 : return aContext->AllocateFromShell(sz);
1795 : }
1796 0 : void Destroy(nsPresContext* aContext) {
1797 0 : this->~nsStyleQuotes();
1798 0 : aContext->FreeToShell(sizeof(nsStyleQuotes), this);
1799 0 : }
1800 :
1801 : void SetInitial();
1802 : void CopyFrom(const nsStyleQuotes& aSource);
1803 :
1804 : nsChangeHint CalcDifference(const nsStyleQuotes& aOther) const;
1805 : #ifdef DEBUG
1806 : static nsChangeHint MaxDifference();
1807 : #endif
1808 0 : static bool ForceCompare() { return false; }
1809 :
1810 0 : PRUint32 QuotesCount(void) const { return mQuotesCount; } // [inherited]
1811 :
1812 0 : const nsString* OpenQuoteAt(PRUint32 aIndex) const
1813 : {
1814 0 : NS_ASSERTION(aIndex < mQuotesCount, "out of range");
1815 0 : return mQuotes + (aIndex * 2);
1816 : }
1817 0 : const nsString* CloseQuoteAt(PRUint32 aIndex) const
1818 : {
1819 0 : NS_ASSERTION(aIndex < mQuotesCount, "out of range");
1820 0 : return mQuotes + (aIndex * 2 + 1);
1821 : }
1822 0 : nsresult GetQuotesAt(PRUint32 aIndex, nsString& aOpen, nsString& aClose) const {
1823 0 : if (aIndex < mQuotesCount) {
1824 0 : aIndex *= 2;
1825 0 : aOpen = mQuotes[aIndex];
1826 0 : aClose = mQuotes[++aIndex];
1827 0 : return NS_OK;
1828 : }
1829 0 : return NS_ERROR_ILLEGAL_VALUE;
1830 : }
1831 :
1832 0 : nsresult AllocateQuotes(PRUint32 aCount) {
1833 0 : if (aCount != mQuotesCount) {
1834 0 : DELETE_ARRAY_IF(mQuotes);
1835 0 : if (aCount) {
1836 0 : mQuotes = new nsString[aCount * 2];
1837 0 : if (! mQuotes) {
1838 0 : mQuotesCount = 0;
1839 0 : return NS_ERROR_OUT_OF_MEMORY;
1840 : }
1841 : }
1842 0 : mQuotesCount = aCount;
1843 : }
1844 0 : return NS_OK;
1845 : }
1846 :
1847 0 : nsresult SetQuotesAt(PRUint32 aIndex, const nsString& aOpen, const nsString& aClose) {
1848 0 : if (aIndex < mQuotesCount) {
1849 0 : aIndex *= 2;
1850 0 : mQuotes[aIndex] = aOpen;
1851 0 : mQuotes[++aIndex] = aClose;
1852 0 : return NS_OK;
1853 : }
1854 0 : return NS_ERROR_ILLEGAL_VALUE;
1855 : }
1856 :
1857 : protected:
1858 : PRUint32 mQuotesCount;
1859 : nsString* mQuotes;
1860 : };
1861 :
1862 : struct nsStyleContent {
1863 : nsStyleContent(void);
1864 : nsStyleContent(const nsStyleContent& aContent);
1865 : ~nsStyleContent(void);
1866 :
1867 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
1868 0 : return aContext->AllocateFromShell(sz);
1869 : }
1870 : void Destroy(nsPresContext* aContext);
1871 :
1872 : nsChangeHint CalcDifference(const nsStyleContent& aOther) const;
1873 : #ifdef DEBUG
1874 : static nsChangeHint MaxDifference();
1875 : #endif
1876 0 : static bool ForceCompare() { return false; }
1877 :
1878 0 : PRUint32 ContentCount(void) const { return mContentCount; } // [reset]
1879 :
1880 0 : const nsStyleContentData& ContentAt(PRUint32 aIndex) const {
1881 0 : NS_ASSERTION(aIndex < mContentCount, "out of range");
1882 0 : return mContents[aIndex];
1883 : }
1884 :
1885 0 : nsStyleContentData& ContentAt(PRUint32 aIndex) {
1886 0 : NS_ASSERTION(aIndex < mContentCount, "out of range");
1887 0 : return mContents[aIndex];
1888 : }
1889 :
1890 : nsresult AllocateContents(PRUint32 aCount);
1891 :
1892 0 : PRUint32 CounterIncrementCount(void) const { return mIncrementCount; } // [reset]
1893 0 : const nsStyleCounterData* GetCounterIncrementAt(PRUint32 aIndex) const {
1894 0 : NS_ASSERTION(aIndex < mIncrementCount, "out of range");
1895 0 : return &mIncrements[aIndex];
1896 : }
1897 :
1898 0 : nsresult AllocateCounterIncrements(PRUint32 aCount) {
1899 0 : if (aCount != mIncrementCount) {
1900 0 : DELETE_ARRAY_IF(mIncrements);
1901 0 : if (aCount) {
1902 0 : mIncrements = new nsStyleCounterData[aCount];
1903 0 : if (! mIncrements) {
1904 0 : mIncrementCount = 0;
1905 0 : return NS_ERROR_OUT_OF_MEMORY;
1906 : }
1907 : }
1908 0 : mIncrementCount = aCount;
1909 : }
1910 0 : return NS_OK;
1911 : }
1912 :
1913 0 : nsresult SetCounterIncrementAt(PRUint32 aIndex, const nsString& aCounter, PRInt32 aIncrement) {
1914 0 : if (aIndex < mIncrementCount) {
1915 0 : mIncrements[aIndex].mCounter = aCounter;
1916 0 : mIncrements[aIndex].mValue = aIncrement;
1917 0 : return NS_OK;
1918 : }
1919 0 : return NS_ERROR_ILLEGAL_VALUE;
1920 : }
1921 :
1922 0 : PRUint32 CounterResetCount(void) const { return mResetCount; } // [reset]
1923 0 : const nsStyleCounterData* GetCounterResetAt(PRUint32 aIndex) const {
1924 0 : NS_ASSERTION(aIndex < mResetCount, "out of range");
1925 0 : return &mResets[aIndex];
1926 : }
1927 :
1928 0 : nsresult AllocateCounterResets(PRUint32 aCount) {
1929 0 : if (aCount != mResetCount) {
1930 0 : DELETE_ARRAY_IF(mResets);
1931 0 : if (aCount) {
1932 0 : mResets = new nsStyleCounterData[aCount];
1933 0 : if (! mResets) {
1934 0 : mResetCount = 0;
1935 0 : return NS_ERROR_OUT_OF_MEMORY;
1936 : }
1937 : }
1938 0 : mResetCount = aCount;
1939 : }
1940 0 : return NS_OK;
1941 : }
1942 :
1943 0 : nsresult SetCounterResetAt(PRUint32 aIndex, const nsString& aCounter, PRInt32 aValue) {
1944 0 : if (aIndex < mResetCount) {
1945 0 : mResets[aIndex].mCounter = aCounter;
1946 0 : mResets[aIndex].mValue = aValue;
1947 0 : return NS_OK;
1948 : }
1949 0 : return NS_ERROR_ILLEGAL_VALUE;
1950 : }
1951 :
1952 : nsStyleCoord mMarkerOffset; // [reset] coord, auto
1953 :
1954 : protected:
1955 : nsStyleContentData* mContents;
1956 : nsStyleCounterData* mIncrements;
1957 : nsStyleCounterData* mResets;
1958 :
1959 : PRUint32 mContentCount;
1960 : PRUint32 mIncrementCount;
1961 : PRUint32 mResetCount;
1962 : };
1963 :
1964 : struct nsStyleUIReset {
1965 : nsStyleUIReset(void);
1966 : nsStyleUIReset(const nsStyleUIReset& aOther);
1967 : ~nsStyleUIReset(void);
1968 :
1969 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
1970 0 : return aContext->AllocateFromShell(sz);
1971 : }
1972 0 : void Destroy(nsPresContext* aContext) {
1973 0 : this->~nsStyleUIReset();
1974 0 : aContext->FreeToShell(sizeof(nsStyleUIReset), this);
1975 0 : }
1976 :
1977 : nsChangeHint CalcDifference(const nsStyleUIReset& aOther) const;
1978 : #ifdef DEBUG
1979 : static nsChangeHint MaxDifference();
1980 : #endif
1981 0 : static bool ForceCompare() { return false; }
1982 :
1983 : PRUint8 mUserSelect; // [reset] (selection-style)
1984 : PRUint8 mForceBrokenImageIcon; // [reset] (0 if not forcing, otherwise forcing)
1985 : PRUint8 mIMEMode; // [reset]
1986 : PRUint8 mWindowShadow; // [reset]
1987 : };
1988 :
1989 : struct nsCursorImage {
1990 : bool mHaveHotspot;
1991 : float mHotspotX, mHotspotY;
1992 :
1993 : nsCursorImage();
1994 : nsCursorImage(const nsCursorImage& aOther);
1995 : ~nsCursorImage();
1996 :
1997 : nsCursorImage& operator=(const nsCursorImage& aOther);
1998 : /*
1999 : * We hide mImage and force access through the getter and setter so that we
2000 : * can lock the images we use. Cursor images are likely to be small, so we
2001 : * don't care about discarding them. See bug 512260.
2002 : * */
2003 0 : void SetImage(imgIRequest *aImage) {
2004 0 : if (mImage)
2005 0 : mImage->UnlockImage();
2006 0 : mImage = aImage;
2007 0 : if (mImage)
2008 0 : mImage->LockImage();
2009 0 : }
2010 0 : imgIRequest* GetImage() const {
2011 0 : return mImage;
2012 : }
2013 :
2014 : private:
2015 : nsCOMPtr<imgIRequest> mImage;
2016 : };
2017 :
2018 : struct nsStyleUserInterface {
2019 : nsStyleUserInterface(void);
2020 : nsStyleUserInterface(const nsStyleUserInterface& aOther);
2021 : ~nsStyleUserInterface(void);
2022 :
2023 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
2024 0 : return aContext->AllocateFromShell(sz);
2025 : }
2026 0 : void Destroy(nsPresContext* aContext) {
2027 0 : this->~nsStyleUserInterface();
2028 0 : aContext->FreeToShell(sizeof(nsStyleUserInterface), this);
2029 0 : }
2030 :
2031 : nsChangeHint CalcDifference(const nsStyleUserInterface& aOther) const;
2032 : #ifdef DEBUG
2033 : static nsChangeHint MaxDifference();
2034 : #endif
2035 0 : static bool ForceCompare() { return false; }
2036 :
2037 : PRUint8 mUserInput; // [inherited]
2038 : PRUint8 mUserModify; // [inherited] (modify-content)
2039 : PRUint8 mUserFocus; // [inherited] (auto-select)
2040 :
2041 : PRUint8 mCursor; // [inherited] See nsStyleConsts.h
2042 :
2043 : PRUint32 mCursorArrayLength;
2044 : nsCursorImage *mCursorArray;// [inherited] The specified URL values
2045 : // and coordinates. Takes precedence over
2046 : // mCursor. Zero-length array is represented
2047 : // by null pointer.
2048 :
2049 : // Does not free mCursorArray; the caller is responsible for calling
2050 : // |delete [] mCursorArray| first if it is needed.
2051 : void CopyCursorArrayFrom(const nsStyleUserInterface& aSource);
2052 : };
2053 :
2054 : struct nsStyleXUL {
2055 : nsStyleXUL();
2056 : nsStyleXUL(const nsStyleXUL& aSource);
2057 : ~nsStyleXUL();
2058 :
2059 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
2060 0 : return aContext->AllocateFromShell(sz);
2061 : }
2062 0 : void Destroy(nsPresContext* aContext) {
2063 0 : this->~nsStyleXUL();
2064 0 : aContext->FreeToShell(sizeof(nsStyleXUL), this);
2065 0 : }
2066 :
2067 : nsChangeHint CalcDifference(const nsStyleXUL& aOther) const;
2068 : #ifdef DEBUG
2069 : static nsChangeHint MaxDifference();
2070 : #endif
2071 0 : static bool ForceCompare() { return false; }
2072 :
2073 : float mBoxFlex; // [reset] see nsStyleConsts.h
2074 : PRUint32 mBoxOrdinal; // [reset] see nsStyleConsts.h
2075 : PRUint8 mBoxAlign; // [reset] see nsStyleConsts.h
2076 : PRUint8 mBoxDirection; // [reset] see nsStyleConsts.h
2077 : PRUint8 mBoxOrient; // [reset] see nsStyleConsts.h
2078 : PRUint8 mBoxPack; // [reset] see nsStyleConsts.h
2079 : bool mStretchStack; // [reset] see nsStyleConsts.h
2080 : };
2081 :
2082 : struct nsStyleColumn {
2083 : nsStyleColumn(nsPresContext* aPresContext);
2084 : nsStyleColumn(const nsStyleColumn& aSource);
2085 : ~nsStyleColumn();
2086 :
2087 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
2088 0 : return aContext->AllocateFromShell(sz);
2089 : }
2090 0 : void Destroy(nsPresContext* aContext) {
2091 0 : this->~nsStyleColumn();
2092 0 : aContext->FreeToShell(sizeof(nsStyleColumn), this);
2093 0 : }
2094 :
2095 : nsChangeHint CalcDifference(const nsStyleColumn& aOther) const;
2096 : #ifdef DEBUG
2097 : static nsChangeHint MaxDifference();
2098 : #endif
2099 0 : static bool ForceCompare() { return false; }
2100 :
2101 : PRUint32 mColumnCount; // [reset] see nsStyleConsts.h
2102 : nsStyleCoord mColumnWidth; // [reset] coord, auto
2103 : nsStyleCoord mColumnGap; // [reset] coord, normal
2104 :
2105 : nscolor mColumnRuleColor; // [reset]
2106 : PRUint8 mColumnRuleStyle; // [reset]
2107 : PRUint8 mColumnFill; // [reset] see nsStyleConsts.h
2108 :
2109 : // See https://bugzilla.mozilla.org/show_bug.cgi?id=271586#c43 for why
2110 : // this is hard to replace with 'currentColor'.
2111 : bool mColumnRuleColorIsForeground;
2112 :
2113 0 : void SetColumnRuleWidth(nscoord aWidth) {
2114 0 : mColumnRuleWidth = NS_ROUND_BORDER_TO_PIXELS(aWidth, mTwipsPerPixel);
2115 0 : }
2116 :
2117 0 : nscoord GetComputedColumnRuleWidth() const {
2118 0 : return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
2119 : }
2120 :
2121 : protected:
2122 : nscoord mColumnRuleWidth; // [reset] coord
2123 : nscoord mTwipsPerPixel;
2124 : };
2125 :
2126 : enum nsStyleSVGPaintType {
2127 : eStyleSVGPaintType_None = 1,
2128 : eStyleSVGPaintType_Color,
2129 : eStyleSVGPaintType_Server
2130 : };
2131 :
2132 : struct nsStyleSVGPaint
2133 : {
2134 : union {
2135 : nscolor mColor;
2136 : nsIURI *mPaintServer;
2137 : } mPaint;
2138 : nsStyleSVGPaintType mType;
2139 : nscolor mFallbackColor;
2140 :
2141 0 : nsStyleSVGPaint() : mType(nsStyleSVGPaintType(0)) { mPaint.mPaintServer = nsnull; }
2142 : ~nsStyleSVGPaint();
2143 : void SetType(nsStyleSVGPaintType aType);
2144 : nsStyleSVGPaint& operator=(const nsStyleSVGPaint& aOther);
2145 : bool operator==(const nsStyleSVGPaint& aOther) const;
2146 :
2147 0 : bool operator!=(const nsStyleSVGPaint& aOther) const {
2148 0 : return !(*this == aOther);
2149 : }
2150 : };
2151 :
2152 : struct nsStyleSVG {
2153 : nsStyleSVG();
2154 : nsStyleSVG(const nsStyleSVG& aSource);
2155 : ~nsStyleSVG();
2156 :
2157 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
2158 0 : return aContext->AllocateFromShell(sz);
2159 : }
2160 0 : void Destroy(nsPresContext* aContext) {
2161 0 : this->~nsStyleSVG();
2162 0 : aContext->FreeToShell(sizeof(nsStyleSVG), this);
2163 0 : }
2164 :
2165 : nsChangeHint CalcDifference(const nsStyleSVG& aOther) const;
2166 : #ifdef DEBUG
2167 : static nsChangeHint MaxDifference();
2168 : #endif
2169 0 : static bool ForceCompare() { return false; }
2170 :
2171 : nsStyleSVGPaint mFill; // [inherited]
2172 : nsStyleSVGPaint mStroke; // [inherited]
2173 : nsCOMPtr<nsIURI> mMarkerEnd; // [inherited]
2174 : nsCOMPtr<nsIURI> mMarkerMid; // [inherited]
2175 : nsCOMPtr<nsIURI> mMarkerStart; // [inherited]
2176 : nsStyleCoord *mStrokeDasharray; // [inherited] coord, percent, factor
2177 :
2178 : nsStyleCoord mStrokeDashoffset; // [inherited] coord, percent, factor
2179 : nsStyleCoord mStrokeWidth; // [inherited] coord, percent, factor
2180 :
2181 : float mFillOpacity; // [inherited]
2182 : float mStrokeMiterlimit; // [inherited]
2183 : float mStrokeOpacity; // [inherited]
2184 :
2185 : PRUint32 mStrokeDasharrayLength;
2186 : PRUint8 mClipRule; // [inherited]
2187 : PRUint8 mColorInterpolation; // [inherited] see nsStyleConsts.h
2188 : PRUint8 mColorInterpolationFilters; // [inherited] see nsStyleConsts.h
2189 : PRUint8 mFillRule; // [inherited] see nsStyleConsts.h
2190 : PRUint8 mImageRendering; // [inherited] see nsStyleConsts.h
2191 : PRUint8 mShapeRendering; // [inherited] see nsStyleConsts.h
2192 : PRUint8 mStrokeLinecap; // [inherited] see nsStyleConsts.h
2193 : PRUint8 mStrokeLinejoin; // [inherited] see nsStyleConsts.h
2194 : PRUint8 mTextAnchor; // [inherited] see nsStyleConsts.h
2195 : PRUint8 mTextRendering; // [inherited] see nsStyleConsts.h
2196 : };
2197 :
2198 : struct nsStyleSVGReset {
2199 : nsStyleSVGReset();
2200 : nsStyleSVGReset(const nsStyleSVGReset& aSource);
2201 : ~nsStyleSVGReset();
2202 :
2203 0 : void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
2204 0 : return aContext->AllocateFromShell(sz);
2205 : }
2206 0 : void Destroy(nsPresContext* aContext) {
2207 0 : this->~nsStyleSVGReset();
2208 0 : aContext->FreeToShell(sizeof(nsStyleSVGReset), this);
2209 0 : }
2210 :
2211 : nsChangeHint CalcDifference(const nsStyleSVGReset& aOther) const;
2212 : #ifdef DEBUG
2213 : static nsChangeHint MaxDifference();
2214 : #endif
2215 0 : static bool ForceCompare() { return false; }
2216 :
2217 : nsCOMPtr<nsIURI> mClipPath; // [reset]
2218 : nsCOMPtr<nsIURI> mFilter; // [reset]
2219 : nsCOMPtr<nsIURI> mMask; // [reset]
2220 : nscolor mStopColor; // [reset]
2221 : nscolor mFloodColor; // [reset]
2222 : nscolor mLightingColor; // [reset]
2223 :
2224 : float mStopOpacity; // [reset]
2225 : float mFloodOpacity; // [reset]
2226 :
2227 : PRUint8 mDominantBaseline; // [reset] see nsStyleConsts.h
2228 : };
2229 :
2230 : #endif /* nsStyleStruct_h___ */
|