Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : /* represent a color combines a numeric color and currentcolor */
8 :
9 : #ifndef mozilla_StyleComplexColor_h_
10 : #define mozilla_StyleComplexColor_h_
11 :
12 : #include "nsColor.h"
13 :
14 : class nsIFrame;
15 :
16 : namespace mozilla {
17 :
18 : class ComputedStyle;
19 :
20 : /**
21 : * This struct represents a combined color from a numeric color and
22 : * the current foreground color (currentcolor keyword).
23 : * Conceptually, the formula is "color * q + currentcolor * p"
24 : * where p is mFgRatio and q is mBgRatio.
25 : *
26 : * It can also represent an "auto" value, which is valid for some
27 : * properties. See comment of `Tag::eAuto`.
28 : */
29 : class StyleComplexColor final
30 : {
31 : public:
32 140 : static StyleComplexColor FromColor(nscolor aColor) {
33 140 : return {aColor, 0, eNumeric};
34 : }
35 350 : static StyleComplexColor CurrentColor() {
36 350 : return {NS_RGBA(0, 0, 0, 0), 1, eForeground};
37 : }
38 105 : static StyleComplexColor Auto() {
39 105 : return {NS_RGBA(0, 0, 0, 0), 1, eAuto};
40 : }
41 :
42 : bool IsAuto() const { return mTag == eAuto; }
43 : bool IsCurrentColor() const { return mTag == eForeground; }
44 :
45 0 : bool operator==(const StyleComplexColor& aOther) const {
46 175 : if (mTag != aOther.mTag) {
47 : return false;
48 : }
49 :
50 175 : switch (mTag) {
51 : case eAuto:
52 : case eForeground:
53 : return true;
54 : case eNumeric:
55 0 : return mColor == aOther.mColor;
56 : case eComplex:
57 0 : return (mBgRatio == aOther.mBgRatio &&
58 0 : mFgRatio == aOther.mFgRatio &&
59 0 : mColor == aOther.mColor);
60 : default:
61 : MOZ_ASSERT_UNREACHABLE("Unexpected StyleComplexColor type.");
62 : return false;
63 : }
64 : }
65 :
66 : bool operator!=(const StyleComplexColor& aOther) const {
67 : return !(*this == aOther);
68 : }
69 :
70 : /**
71 : * Is it possible that this StyleComplexColor is transparent?
72 : */
73 : bool MaybeTransparent() const;
74 :
75 : /**
76 : * Compute the color for this StyleComplexColor, taking into account
77 : * the foreground color from aStyle.
78 : */
79 : nscolor CalcColor(mozilla::ComputedStyle* aStyle) const;
80 :
81 : /**
82 : * Compute the color for this StyleComplexColor, taking into account
83 : * the foreground color from aFrame's ComputedStyle.
84 : */
85 : nscolor CalcColor(const nsIFrame* aFrame) const;
86 :
87 : private:
88 : enum Tag : uint8_t {
89 : // This represents a computed-value time auto value. This
90 : // indicates that this value should not be interpolatable with
91 : // other colors. Other fields represent a currentcolor and
92 : // properties can decide whether that should be used.
93 : eAuto,
94 : // This represents a numeric color; no currentcolor component.
95 : eNumeric,
96 : // This represents the current foreground color, currentcolor; no
97 : // numeric color component.
98 : eForeground,
99 : // This represents a linear combination of numeric color and the
100 : // foreground color: "mColor * mBgRatio + currentcolor *
101 : // mFgRatio".
102 : eComplex,
103 : };
104 :
105 : StyleComplexColor(nscolor aColor,
106 : float aFgRatio,
107 : Tag aTag)
108 : : mColor(aColor)
109 : , mBgRatio(1.f - aFgRatio)
110 : , mFgRatio(aFgRatio)
111 : , mTag(aTag)
112 : {
113 : MOZ_ASSERT(mTag != eNumeric || aFgRatio == 0.);
114 : MOZ_ASSERT(!(mTag == eAuto || mTag == eForeground) || aFgRatio == 1.);
115 : }
116 :
117 : nscolor mColor;
118 : float mBgRatio;
119 : float mFgRatio;
120 : Tag mTag;
121 : };
122 :
123 : } // namespace mozilla
124 :
125 : #endif // mozilla_StyleComplexColor_h_
|