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/. */
7 #include "mozilla/StyleColorInlines.h"
9 #include "mozilla/ComputedStyle.h"
10 #include "mozilla/ComputedStyleInlines.h"
12 #include "nsStyleStruct.h"
16 // Blend one RGBA color with another based on a given ratios.
17 // It is a linear combination of each channel with alpha premultipled.
18 static nscolor
LinearBlendColors(const StyleRGBA
& aBg
, float aBgRatio
,
19 const StyleRGBA
& aFg
, float aFgRatio
) {
20 constexpr float kFactor
= 1.0f
/ 255.0f
;
23 float a1
= kFactor
* aBg
.alpha
;
24 float r1
= a1
* aBg
.red
;
25 float g1
= a1
* aBg
.green
;
26 float b1
= a1
* aBg
.blue
;
29 float a2
= kFactor
* aFg
.alpha
;
30 float r2
= a2
* aFg
.red
;
31 float g2
= a2
* aFg
.green
;
32 float b2
= a2
* aFg
.blue
;
34 float a
= p1
* a1
+ p2
* a2
;
36 return NS_RGBA(0, 0, 0, 0);
43 auto r
= ClampColor((p1
* r1
+ p2
* r2
) / a
);
44 auto g
= ClampColor((p1
* g1
+ p2
* g2
) / a
);
45 auto b
= ClampColor((p1
* b1
+ p2
* b2
) / a
);
46 return NS_RGBA(r
, g
, b
, NSToIntRound(a
* 255));
50 bool StyleColor::MaybeTransparent() const {
51 // We know that the color is opaque when it's a numeric color with
53 return ratios
!= StyleComplexColorRatios::NUMERIC
|| color
.alpha
!= 255;
57 nscolor
StyleColor::CalcColor(nscolor aColor
) const {
58 return CalcColor(StyleRGBA::FromColor(aColor
));
62 nscolor
StyleColor::CalcColor(const StyleRGBA
& aForegroundColor
) const {
63 if (ratios
== StyleComplexColorRatios::NUMERIC
) {
64 return color
.ToColor();
66 if (ratios
== StyleComplexColorRatios::CURRENT_COLOR
) {
67 return aForegroundColor
.ToColor();
69 return LinearBlendColors(color
, ratios
.bg
, aForegroundColor
, ratios
.fg
);
73 nscolor
StyleColor::CalcColor(const ComputedStyle
& aStyle
) const {
74 // Common case that is numeric color, which is pure background, we
75 // can skip resolving StyleText().
76 if (ratios
== StyleComplexColorRatios::NUMERIC
) {
77 return color
.ToColor();
79 return CalcColor(aStyle
.StyleText()->mColor
);
83 nscolor
StyleColor::CalcColor(const nsIFrame
* aFrame
) const {
84 if (ratios
== StyleComplexColorRatios::NUMERIC
) {
85 return color
.ToColor();
87 return CalcColor(aFrame
->StyleText()->mColor
);
90 } // namespace mozilla