/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * structs that contain the data provided by ComputedStyle, the * internal API for computed style data for an element */ #ifndef nsStyleStruct_h___ #define nsStyleStruct_h___ #include "mozilla/Attributes.h" #include "mozilla/Maybe.h" #include "mozilla/SheetType.h" #include "mozilla/StaticPtr.h" #include "mozilla/StyleComplexColor.h" #include "mozilla/UniquePtr.h" #include "nsColor.h" #include "nsCoord.h" #include "nsMargin.h" #include "nsFont.h" #include "nsStyleAutoArray.h" #include "nsStyleCoord.h" #include "nsStyleConsts.h" #include "nsChangeHint.h" #include "nsTimingFunction.h" #include "nsCOMPtr.h" #include "nsCOMArray.h" #include "nsTArray.h" #include "nsCSSValue.h" #include "imgRequestProxy.h" #include "Orientation.h" #include "CounterStyleManager.h" #include // offsetof() #include #include "X11UndefineNone.h" class nsIFrame; class nsIURI; class nsTextFrame; class imgIContainer; class nsPresContext; struct nsStyleDisplay; struct nsStyleVisibility; namespace mozilla { class ComputedStyle; namespace dom { class ImageTracker; } // namespace dom } // namespace mozilla namespace mozilla { struct Position { using Coord = nsStyleCoord::CalcValue; Coord mXPosition, mYPosition; // Initialize nothing Position() {} // Sets both mXPosition and mYPosition to the given percent value for the // initial property-value (e.g. 0.0f for "0% 0%", or 0.5f for "50% 50%") void SetInitialPercentValues(float aPercentVal); // Sets both mXPosition and mYPosition to 0 (app units) for the // initial property-value as a length with no percentage component. void SetInitialZeroValues(); // True if the effective background image position described by this depends // on the size of the corresponding frame. bool DependsOnPositioningAreaSize() const { return mXPosition.mPercent != 0.0f || mYPosition.mPercent != 0.0f; } bool operator==(const Position& aOther) const { return mXPosition == aOther.mXPosition && mYPosition == aOther.mYPosition; } bool operator!=(const Position& aOther) const { return !(*this == aOther); } }; } // namespace mozilla struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont { nsStyleFont(const nsStyleFont& aStyleFont); explicit nsStyleFont(const nsPresContext* aContext); ~nsStyleFont() { MOZ_COUNT_DTOR(nsStyleFont); } void FinishStyle(nsPresContext*, const nsStyleFont*) {} const static bool kHasFinishStyle = false; nsChangeHint CalcDifference(const nsStyleFont& aNewData) const; /** * Return aSize multiplied by the current text zoom factor (in aPresContext). * aSize is allowed to be negative, but the caller is expected to deal with * negative results. The result is clamped to nscoord_MIN .. nscoord_MAX. */ static nscoord ZoomText(const nsPresContext* aPresContext, nscoord aSize); static already_AddRefed GetLanguage(const nsPresContext* aPresContext); nsFont mFont; nscoord mSize; // Our "computed size". Can be different // from mFont.size which is our "actual size" and is // enforced to be >= the user's preferred min-size. // mFont.size should be used for display purposes // while mSize is the value to return in // getComputedStyle() for example. // In stylo these three track whether the size is keyword-derived // and if so if it has been modified by a factor/offset float mFontSizeFactor; nscoord mFontSizeOffset; uint8_t mFontSizeKeyword; // NS_STYLE_FONT_SIZE_*, is NS_STYLE_FONT_SIZE_NO_KEYWORD // when not keyword-derived uint8_t mGenericID; // generic CSS font family, if any; // value is a kGenericFont_* constant, see nsFont.h. // MathML scriptlevel support int8_t mScriptLevel; // MathML mathvariant support uint8_t mMathVariant; // MathML displaystyle support uint8_t mMathDisplay; // allow different min font-size for certain cases uint8_t mMinFontSizeRatio; // percent * 100 // was mLanguage set based on a lang attribute in the document? bool mExplicitLanguage; // should calls to ZoomText() and UnZoomText() be made to the font // size on this nsStyleFont? bool mAllowZoom; // The value mSize would have had if scriptminsize had never been applied nscoord mScriptUnconstrainedSize; nscoord mScriptMinSize; // length float mScriptSizeMultiplier; RefPtr mLanguage; }; struct nsStyleGradientStop { nsStyleCoord mLocation; // percent, coord, calc, none mozilla::StyleComplexColor mColor; bool mIsInterpolationHint; // Use ==/!= on nsStyleGradient instead of on the gradient stop. bool operator==(const nsStyleGradientStop&) const = delete; bool operator!=(const nsStyleGradientStop&) const = delete; }; class nsStyleGradient final { public: nsStyleGradient(); uint8_t mShape; // NS_STYLE_GRADIENT_SHAPE_* uint8_t mSize; // NS_STYLE_GRADIENT_SIZE_*; // not used (must be FARTHEST_CORNER) for linear shape bool mRepeating; bool mLegacySyntax; // If true, serialization should use a vendor prefix. // XXXdholbert This will hopefully be going away soon, if bug 1337655 sticks: bool mMozLegacySyntax; // (Only makes sense when mLegacySyntax is true.) // If true, serialization should use -moz prefix. // Else, serialization should use -webkit prefix. nsStyleCoord mBgPosX; // percent, coord, calc, none nsStyleCoord mBgPosY; // percent, coord, calc, none nsStyleCoord mAngle; // none, angle nsStyleCoord mRadiusX; // percent, coord, calc, none nsStyleCoord mRadiusY; // percent, coord, calc, none // stops are in the order specified in the stylesheet nsTArray mStops; bool operator==(const nsStyleGradient& aOther) const; bool operator!=(const nsStyleGradient& aOther) const { return !(*this == aOther); } bool IsOpaque(); bool HasCalc(); uint32_t Hash(PLDHashNumber aHash); NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleGradient) private: // Private destructor, to discourage deletion outside of Release(): ~nsStyleGradient() {} nsStyleGradient(const nsStyleGradient& aOther) = delete; nsStyleGradient& operator=(const nsStyleGradient& aOther) = delete; }; /** * A wrapper for an imgRequestProxy that supports off-main-thread creation * and equality comparison. * * An nsStyleImageRequest can be created using the constructor that takes the * URL, base URI, referrer and principal that can be used to initiate an image * load and produce an imgRequestProxy later. * * This can be called from any thread. The nsStyleImageRequest is not * considered "resolved" at this point, and the Resolve() method must be called * later to initiate the image load and make calls to get() valid. * * Calls to TrackImage(), UntrackImage(), LockImage(), UnlockImage() and * RequestDiscard() are made to the imgRequestProxy and ImageTracker as * appropriate, according to the mode flags passed in to the constructor. * * The constructor receives a css::URLValue to represent the url() * information, which is held on to for the comparisons done in * DefinitelyEquals(). */ class nsStyleImageRequest { public: // Flags describing whether the imgRequestProxy must be tracked in the // ImageTracker, whether LockImage/UnlockImage calls will be made // when obtaining and releasing the imgRequestProxy, and whether // RequestDiscard will be called on release. enum class Mode : uint8_t { // The imgRequestProxy will be added to the ImageTracker when resolved // Without this flag, the nsStyleImageRequest itself will call LockImage/ // UnlockImage on the imgRequestProxy, rather than leaving locking to the // ImageTracker to manage. // // This flag is currently used by all nsStyleImageRequests except // those for list-style-image and cursor. Track = 0x1, // The imgRequestProxy will have its RequestDiscard method called when // the nsStyleImageRequest is going away. // // This is currently used only for cursor images. Discard = 0x2, }; // Can be called from any thread, but Resolve() must be called later // on the main thread before get() can be used. nsStyleImageRequest(Mode aModeFlags, mozilla::css::URLValue* aImageValue); bool Resolve(nsPresContext*, const nsStyleImageRequest* aOldImageRequest); bool IsResolved() const { return mResolved; } imgRequestProxy* get() { MOZ_ASSERT(IsResolved(), "Resolve() must be called first"); MOZ_ASSERT(NS_IsMainThread()); return mRequestProxy.get(); } const imgRequestProxy* get() const { return const_cast(this)->get(); } // Returns whether the URLValue objects in the two nsStyleImageRequests // return true from URLValue::DefinitelyEqualURIs. bool DefinitelyEquals(const nsStyleImageRequest& aOther) const; mozilla::css::URLValue* GetImageValue() const { return mImageValue; } already_AddRefed GetImageURI() const; NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleImageRequest); private: ~nsStyleImageRequest(); nsStyleImageRequest& operator=(const nsStyleImageRequest& aOther) = delete; void MaybeTrackAndLock(); RefPtr mRequestProxy; RefPtr mImageValue; RefPtr mImageTracker; // Cache DocGroup for dispatching events in the destructor. RefPtr mDocGroup; Mode mModeFlags; bool mResolved; }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsStyleImageRequest::Mode) enum nsStyleImageType { eStyleImageType_Null, eStyleImageType_Image, eStyleImageType_Gradient, eStyleImageType_Element, eStyleImageType_URL }; struct CachedBorderImageData { ~CachedBorderImageData() { PurgeCachedImages(); } // Caller are expected to ensure that the value of aSVGViewportSize is // different from the cached one since the method won't do the check. void SetCachedSVGViewportSize(const mozilla::Maybe& aSVGViewportSize); const mozilla::Maybe& GetCachedSVGViewportSize(); void PurgeCachedImages(); void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage); imgIContainer* GetSubImage(uint8_t aIndex); private: // If this is a SVG border-image, we save the size of the SVG viewport that // we used when rasterizing any cached border-image subimages. (The viewport // size matters for percent-valued sizes & positions in inner SVG doc). mozilla::Maybe mCachedSVGViewportSize; nsCOMArray mSubImages; }; /** * Represents a paintable image of one of the following types. * (1) A real image loaded from an external source. * (2) A CSS linear or radial gradient. * (3) An element within a document, or an ,