Skip to content

Commit

Permalink
Add computed style functions for mask-mode property
Browse files Browse the repository at this point in the history
Implement various functions to support conversion from specified style
to computed style for the newly added mask-mode property. Those values
include alpha, luminance and match-source.

Follow up patch will include usage of the computed value.

Grammar:
<masking-mode>#
<masking-mode> = alpha | luminance | match-source
Spec: https://drafts.fxtf.org/css-masking/#the-mask-mode

Bug: 1490704

Change-Id: Ic549272567a138c0d66c6dbd7e6c2a48bf2312d4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4977877
Reviewed-by: Traian Captan <tcaptan@chromium.org>
Reviewed-by: Philip Rogers <pdr@chromium.org>
Commit-Queue: Philip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1216410}
  • Loading branch information
yotam-hacohen authored and Chromium LUCI CQ committed Oct 27, 2023
1 parent cf93042 commit 279ebb3
Show file tree
Hide file tree
Showing 27 changed files with 168 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -516,11 +516,44 @@ inline EFillRepeat CSSIdentifierValue::ConvertTo() const {
default:
break;
}

NOTREACHED();
return EFillRepeat::kRepeatFill;
}

template <>
inline CSSIdentifierValue::CSSIdentifierValue(EFillMaskMode e)
: CSSValue(kIdentifierClass) {
switch (e) {
case EFillMaskMode::kAlpha:
value_id_ = CSSValueID::kAlpha;
break;
case EFillMaskMode::kLuminance:
value_id_ = CSSValueID::kLuminance;
break;
case EFillMaskMode::kMatchSource:
value_id_ = CSSValueID::kMatchSource;
break;
default:
NOTREACHED();
value_id_ = CSSValueID::kMatchSource;
}
}

template <>
inline EFillMaskMode CSSIdentifierValue::ConvertTo() const {
switch (value_id_) {
case CSSValueID::kAlpha:
return EFillMaskMode::kAlpha;
case CSSValueID::kLuminance:
return EFillMaskMode::kLuminance;
case CSSValueID::kMatchSource:
return EFillMaskMode::kMatchSource;
default:
NOTREACHED();
return EFillMaskMode::kMatchSource;
}
}

template <>
inline CSSIdentifierValue::CSSIdentifierValue(BackgroundEdgeOrigin e)
: CSSValue(kIdentifierClass) {
Expand Down
4 changes: 2 additions & 2 deletions third_party/blink/renderer/core/css/css_properties.json5
Original file line number Diff line number Diff line change
Expand Up @@ -5764,7 +5764,7 @@
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
style_builder_template: "mask_layer",
style_builder_template_args: {
fill_type: "Mode",
fill_type: "MaskMode",
},
runtime_flag: "CSSMaskingInterop",
},
Expand Down Expand Up @@ -7508,7 +7508,7 @@
longhands: [
"mask-image", "-webkit-mask-position-x",
"-webkit-mask-position-y", "mask-size", "mask-repeat", "mask-origin",
"mask-clip", "mask-composite"
"mask-clip", "mask-composite", "mask-mode"
],
property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSMaskingInterop",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ bool FillLayersEqual(const FillLayer& a_layers, const FillLayer& b_layers) {
}
break;
case CSSPropertyID::kMaskMode:
if (a_layer->Mode() != b_layer->Mode()) {
if (a_layer->MaskMode() != b_layer->MaskMode()) {
return false;
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,14 @@ const CSSValue* ComputedStyleUtils::RepeatStyle(const FillLayer* curr_layer) {
return list;
}

const CSSValue* ComputedStyleUtils::MaskMode(const FillLayer* curr_layer) {
CSSValueList* list = CSSValueList::CreateCommaSeparated();
for (; curr_layer; curr_layer = curr_layer->Next()) {
list->Append(*CSSIdentifierValue::Create(curr_layer->MaskMode()));
}
return list;
}

const CSSValueList* ComputedStyleUtils::ValuesForBackgroundShorthand(
const ComputedStyle& style,
const LayoutObject* layout_object,
Expand Down Expand Up @@ -488,7 +496,10 @@ const CSSValueList* ComputedStyleUtils::ValuesForMaskShorthand(
list->Append(*CSSIdentifierValue::Create(layer->CompositingOperator()));
}
// <masking-mode>
// TODO(crbug.com/1490704): Emit mask-mode here.
if (layer->MaskMode() !=
FillLayer::InitialFillMaskMode(EFillLayerType::kMask)) {
list->Append(*CSSIdentifierValue::Create(layer->MaskMode()));
}

if (list->length()) {
result->Append(*list);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class CORE_EXPORT ComputedStyleUtils {
const FillLayer&,
const ComputedStyle&);
static const CSSValue* ValueForFillRepeat(const FillLayer* curr_layer);
static const CSSValue* MaskMode(const FillLayer* curr_layer);
static const CSSValue* RepeatStyle(const FillLayer* curr_layer);
static const CSSValueList* ValuesForBackgroundShorthand(
const ComputedStyle&,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4131,6 +4131,11 @@ CSSValue* ConsumePrefixedMaskComposite(CSSParserTokenRange& range) {
return ConsumeIdentRange(range, CSSValueID::kClear, CSSValueID::kPlusLighter);
}

CSSValue* ConsumeMaskMode(CSSParserTokenRange& range) {
return ConsumeIdent<CSSValueID::kAlpha, CSSValueID::kLuminance,
CSSValueID::kMatchSource>(range);
}

CSSPrimitiveValue* ConsumeLengthOrPercentCountNegative(
CSSParserTokenRange& range,
const CSSParserContext& context,
Expand Down Expand Up @@ -4317,6 +4322,8 @@ CSSValue* ConsumeBackgroundComponent(CSSPropertyID resolved_property,
return ConsumeRepeatStyleValue(range);
case CSSPropertyID::kMaskComposite:
return ConsumeMaskComposite(range);
case CSSPropertyID::kMaskMode:
return ConsumeMaskMode(range);
default:
return nullptr;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ CSSValue* ConsumeBackgroundBox(CSSParserTokenRange&);
CSSValue* ConsumeBackgroundBoxOrText(CSSParserTokenRange&);
CSSValue* ConsumeMaskComposite(CSSParserTokenRange&);
CSSValue* ConsumePrefixedMaskComposite(CSSParserTokenRange&);
CSSValue* ConsumeMaskMode(CSSParserTokenRange&);
bool ConsumeBackgroundPosition(CSSParserTokenRange&,
const CSSParserContext&,
UnitlessQuirk,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9392,19 +9392,14 @@ const CSSValue* MaskMode::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext&,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumeIdent<
CSSValueID::kAlpha, CSSValueID::kLuminance, CSSValueID::kMatchSource>,
range);
css_parsing_utils::ConsumeMaskMode, range);
}

const CSSValue* MaskMode::CSSValueFromComputedStyleInternal(
const ComputedStyle& style,
const LayoutObject*,
bool allow_visited_style) const {
CSSValueList* list = CSSValueList::CreateCommaSeparated();
// TODO(crbug.com/1490704) Implement to support mask mode
list->Append(*CSSIdentifierValue::Create(CSSValueID::kMatchSource));
return list;
bool) const {
return ComputedStyleUtils::MaskMode(&style.MaskLayers());
}

const CSSValue* WebkitMaskOrigin::ParseSingleValue(
Expand Down
18 changes: 14 additions & 4 deletions third_party/blink/renderer/core/css/resolver/css_to_style_map.cc
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,20 @@ void CSSToStyleMap::MapFillRepeat(StyleResolverState&,
}
}

void CSSToStyleMap::MapFillMode(StyleResolverState&,
FillLayer* layer,
const CSSValue& value) {
// TODO(crbug.com/1490704) Implement to support mask mode
void CSSToStyleMap::MapFillMaskMode(StyleResolverState&,
FillLayer* layer,
const CSSValue& value) {
if (value.IsInitialValue()) {
layer->SetMaskMode(FillLayer::InitialFillMaskMode(layer->GetType()));
return;
}

const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
if (!identifier_value) {
return;
}

layer->SetMaskMode(identifier_value->ConvertTo<EFillMaskMode>());
}

void CSSToStyleMap::MapFillSize(StyleResolverState& state,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ class CSSToStyleMap {
static void MapFillOrigin(StyleResolverState&, FillLayer*, const CSSValue&);
static void MapFillImage(StyleResolverState&, FillLayer*, const CSSValue&);
static void MapFillRepeat(StyleResolverState&, FillLayer*, const CSSValue&);
static void MapFillMaskMode(StyleResolverState&, FillLayer*, const CSSValue&);
static void MapFillSize(StyleResolverState&, FillLayer*, const CSSValue&);
static void MapFillMode(StyleResolverState&, FillLayer*, const CSSValue&);
static void MapFillPositionX(StyleResolverState&,
FillLayer*,
const CSSValue&);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1728,6 +1728,13 @@ String StylePropertySerializer::GetLayeredShorthandValue(
omit_value = true;
}
}
} else if (property->IDEquals(CSSPropertyID::kMaskMode)) {
if (auto* ident = DynamicTo<CSSIdentifierValue>(value)) {
if (To<CSSIdentifierValue>(ident)->GetValueID() ==
CSSValueID::kMatchSource) {
omit_value = true;
}
}
}
// TODO(pdr): Omit default values for mask properties.
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ enum class EFillRepeat : unsigned {
kSpaceFill
};

enum class EFillMode : unsigned { kAlpha, kLuminance, kMatchSource };
enum class EFillMaskMode : unsigned { kAlpha, kLuminance, kMatchSource };

enum class EFillLayerType : unsigned { kBackground, kMask };

Expand Down
26 changes: 26 additions & 0 deletions third_party/blink/renderer/core/style/computed_style_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2013,4 +2013,30 @@ TEST_F(ComputedStyleTest, MaskRepeat) {
ASSERT_EQ("repeat-y", computed_value->CssText());
}

TEST_F(ComputedStyleTest, MaskMode) {
std::unique_ptr<DummyPageHolder> dummy_page_holder =
std::make_unique<DummyPageHolder>(gfx::Size(0, 0), nullptr);
Document& document = dummy_page_holder->GetDocument();
const ComputedStyle* initial =
document.GetStyleResolver().InitialStyleForElement();

StyleResolverState state(document, *document.documentElement(),
nullptr /* StyleRecalcContext */,
StyleRequest(initial));

state.SetStyle(*initial);

auto* mode_style_value = CSSIdentifierValue::Create(CSSValueID::kAlpha);

To<Longhand>(GetCSSPropertyMaskMode())
.ApplyValue(state, *mode_style_value, CSSProperty::ValueMode::kNormal);
const ComputedStyle* style = state.TakeStyle();
auto* computed_value = To<Longhand>(GetCSSPropertyMaskMode())
.CSSValueFromComputedStyleInternal(
*style, nullptr /* layout_object */,
false /* allow_visited_style */);
ASSERT_TRUE(computed_value);
ASSERT_EQ("alpha", computed_value->CssText());
}

} // namespace blink
23 changes: 21 additions & 2 deletions third_party/blink/renderer/core/style/fill_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@ FillLayer::FillLayer(EFillLayerType type, bool use_initial_values)
blend_mode_(static_cast<unsigned>(FillLayer::InitialFillBlendMode(type))),
background_x_origin_(static_cast<unsigned>(BackgroundEdgeOrigin::kLeft)),
background_y_origin_(static_cast<unsigned>(BackgroundEdgeOrigin::kTop)),
mask_mode_(static_cast<unsigned>(FillLayer::InitialFillMaskMode(type))),
image_set_(use_initial_values),
attachment_set_(use_initial_values),
clip_set_(use_initial_values),
origin_set_(use_initial_values),
repeat_set_(use_initial_values),
mask_mode_set_(use_initial_values),
pos_x_set_(use_initial_values),
pos_y_set_(use_initial_values),
background_x_origin_set_(false),
Expand Down Expand Up @@ -103,11 +105,13 @@ FillLayer::FillLayer(const FillLayer& o)
blend_mode_(o.blend_mode_),
background_x_origin_(o.background_x_origin_),
background_y_origin_(o.background_y_origin_),
mask_mode_(o.mask_mode_),
image_set_(o.image_set_),
attachment_set_(o.attachment_set_),
clip_set_(o.clip_set_),
origin_set_(o.origin_set_),
repeat_set_(o.repeat_set_),
mask_mode_set_(o.mask_mode_set_),
pos_x_set_(o.pos_x_set_),
pos_y_set_(o.pos_y_set_),
background_x_origin_set_(o.background_x_origin_set_),
Expand Down Expand Up @@ -140,6 +144,7 @@ FillLayer& FillLayer::operator=(const FillLayer& o) {
position_y_ = o.position_y_;
background_x_origin_ = o.background_x_origin_;
background_y_origin_ = o.background_y_origin_;
mask_mode_ = o.mask_mode_;
background_x_origin_set_ = o.background_x_origin_set_;
background_y_origin_set_ = o.background_y_origin_set_;
size_length_ = o.size_length_;
Expand All @@ -158,6 +163,7 @@ FillLayer& FillLayer::operator=(const FillLayer& o) {
blend_mode_set_ = o.blend_mode_set_;
origin_set_ = o.origin_set_;
repeat_set_ = o.repeat_set_;
mask_mode_set_ = o.mask_mode_set_;
pos_x_set_ = o.pos_x_set_;
pos_y_set_ = o.pos_y_set_;

Expand All @@ -173,8 +179,8 @@ bool FillLayer::LayerPropertiesEqual(const FillLayer& o) const {
position_x_ == o.position_x_ && position_y_ == o.position_y_ &&
background_x_origin_ == o.background_x_origin_ &&
background_y_origin_ == o.background_y_origin_ &&
attachment_ == o.attachment_ && clip_ == o.clip_ &&
compositing_operator_ == o.compositing_operator_ &&
mask_mode_ == o.mask_mode_ && attachment_ == o.attachment_ &&
clip_ == o.clip_ && compositing_operator_ == o.compositing_operator_ &&
blend_mode_ == o.blend_mode_ && origin_ == o.origin_ &&
repeat_ == o.repeat_ && size_type_ == o.size_type_ &&
size_length_ == o.size_length_ && type_ == o.type_;
Expand Down Expand Up @@ -331,6 +337,19 @@ void FillLayer::FillUnsetProperties() {
}
}
}

for (curr = this; curr && curr->IsMaskModeSet(); curr = curr->Next()) {
}
if (curr && curr != this) {
// We need to fill in the remaining values with the pattern specified.
for (FillLayer* pattern = this; curr; curr = curr->Next()) {
curr->mask_mode_ = pattern->mask_mode_;
pattern = pattern->Next();
if (pattern == curr || !pattern) {
pattern = this;
}
}
}
}

void FillLayer::CullEmptyLayers() {
Expand Down
25 changes: 13 additions & 12 deletions third_party/blink/renderer/core/style/fill_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ class CORE_EXPORT FillLayer {
EFillBox Clip() const { return static_cast<EFillBox>(clip_); }
EFillBox Origin() const { return static_cast<EFillBox>(origin_); }
const FillRepeat& Repeat() const { return repeat_; }
EFillMode Mode() const { return EFillMode::kAlpha; }
CompositingOperator CompositingOperator() const {
EFillMaskMode MaskMode() const {
return static_cast<EFillMaskMode>(mask_mode_);
}
enum CompositingOperator CompositingOperator() const {
return static_cast<enum CompositingOperator>(compositing_operator_);
}
CompositeOperator Composite() const;
Expand All @@ -113,9 +115,7 @@ class CORE_EXPORT FillLayer {
bool IsClipSet() const { return clip_set_; }
bool IsOriginSet() const { return origin_set_; }
bool IsRepeatSet() const { return repeat_set_; }

// TODO(crbug.com/1490704) Implement to support mask mode
bool IsModeSet() const { return false; }
bool IsMaskModeSet() const { return mask_mode_set_; }
bool IsCompositingOperatorSet() const { return compositing_operator_set_; }

bool IsBlendModeSet() const { return blend_mode_set_; }
Expand Down Expand Up @@ -166,8 +166,9 @@ class CORE_EXPORT FillLayer {
repeat_ = r;
repeat_set_ = true;
}
void SetMode(const EFillMode& m) {
// TODO(crbug.com/1490704) Implement to support mask mode
void SetMaskMode(const EFillMaskMode& m) {
mask_mode_ = static_cast<unsigned>(m);
mask_mode_set_ = true;
}
void SetCompositingOperator(enum CompositingOperator c) {
compositing_operator_ = static_cast<unsigned>(c);
Expand Down Expand Up @@ -201,8 +202,7 @@ class CORE_EXPORT FillLayer {
void ClearClip() { clip_set_ = false; }
void ClearOrigin() { origin_set_ = false; }
void ClearRepeat() { repeat_set_ = false; }
// TODO(crbug.com/1490704) Implement to support mask mode
void ClearMode() {}
void ClearMaskMode() { mask_mode_set_ = false; }
void ClearCompositingOperator() { compositing_operator_set_ = false; }
void ClearBlendMode() { blend_mode_set_ = false; }
void ClearSize() {
Expand Down Expand Up @@ -276,9 +276,8 @@ class CORE_EXPORT FillLayer {
static FillRepeat InitialFillRepeat(EFillLayerType) {
return {EFillRepeat::kRepeatFill, EFillRepeat::kRepeatFill};
}
static EFillMode InitialFillMode(EFillLayerType) {
// TODO(crbug.com/1490704) Implement to support mask mode
return EFillMode::kAlpha;
static EFillMaskMode InitialFillMaskMode(EFillLayerType) {
return EFillMaskMode::kMatchSource;
}
static enum CompositingOperator InitialFillCompositingOperator(
EFillLayerType) {
Expand Down Expand Up @@ -336,11 +335,13 @@ class CORE_EXPORT FillLayer {
unsigned blend_mode_ : 5; // BlendMode
unsigned background_x_origin_ : 2; // BackgroundEdgeOrigin
unsigned background_y_origin_ : 2; // BackgroundEdgeOrigin
unsigned mask_mode_ : 2; // EFillMaskMode
unsigned image_set_ : 1;
unsigned attachment_set_ : 1;
unsigned clip_set_ : 1;
unsigned origin_set_ : 1;
unsigned repeat_set_ : 1;
unsigned mask_mode_set_ : 1;
unsigned pos_x_set_ : 1;
unsigned pos_y_set_ : 1;
unsigned background_x_origin_set_ : 1;
Expand Down

0 comments on commit 279ebb3

Please sign in to comment.