File: StyleMaskLayer.h

package info (click to toggle)
webkit2gtk 2.51.2-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 457,708 kB
  • sloc: cpp: 3,884,629; javascript: 198,661; ansic: 165,298; python: 49,171; asm: 21,849; ruby: 18,095; perl: 16,914; xml: 4,623; sh: 2,397; yacc: 2,356; java: 2,019; lex: 1,330; pascal: 372; makefile: 197
file content (180 lines) | stat: -rw-r--r-- 7,836 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
 *           (C) 2000 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved.
 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
 * Copyright (C) 2025 Samuel Weinig <sam@webkit.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#pragma once

#include <WebCore/CSSPropertyNames.h>
#include <WebCore/GraphicsTypes.h>
#include <WebCore/RenderStyleConstants.h>
#include <WebCore/StyleBackgroundSize.h>
#include <WebCore/StyleCoordinatedValueListValue.h>
#include <WebCore/StyleImageOrNone.h>
#include <WebCore/StylePosition.h>
#include <WebCore/StyleRepeatStyle.h>
#include <wtf/RefPtr.h>
#include <wtf/TZoneMalloc.h>

namespace WebCore {

class RenderElement;

namespace Style {

// macro(ownerType, property, type, lowercaseName, uppercaseName)

#define FOR_EACH_MASK_LAYER_REFERENCE(macro) \
    macro(MaskLayer, MaskImage, ImageOrNone, image, Image) \
    macro(MaskLayer, WebkitMaskPositionX, PositionX, positionX, PositionX) \
    macro(MaskLayer, WebkitMaskPositionY, PositionY, positionY, PositionY) \
    macro(MaskLayer, MaskSize, BackgroundSize, size, Size) \
    macro(MaskLayer, MaskRepeat, RepeatStyle, repeat, Repeat) \
\

#define FOR_EACH_MASK_LAYER_ENUM(macro) \
    macro(MaskLayer, MaskClip, FillBox, clip, Clip) \
    macro(MaskLayer, MaskOrigin, FillBox, origin, Origin) \
    macro(MaskLayer, MaskComposite, CompositeOperator, composite, Composite) \
    macro(MaskLayer, MaskMode, MaskMode, maskMode, MaskMode) \
\

#define FOR_EACH_MASK_LAYER_SHORTHAND(macro) \
    macro(MaskLayer, MaskPosition, Position, position, Position) \
\

#define FOR_EACH_MASK_LAYER_PROPERTY(macro) \
    FOR_EACH_MASK_LAYER_REFERENCE(macro) \
    FOR_EACH_MASK_LAYER_ENUM(macro) \
\

struct MaskLayer {
    MaskLayer();
    MaskLayer(CSS::Keyword::None);
    MaskLayer(ImageOrNone&&);
    MaskLayer(RefPtr<StyleImage>&&);

    const ImageOrNone& image() const { return m_image; }
    const PositionX& positionX() const { return m_positionX; }
    const PositionY& positionY() const { return m_positionY; }
    const BackgroundSize& size() const { return m_size; }
    FillBox clip() const { return static_cast<FillBox>(m_clip); }
    FillBox origin() const { return static_cast<FillBox>(m_origin); }
    const RepeatStyle& repeat() const { return m_repeat; }
    CompositeOperator composite() const { return static_cast<CompositeOperator>(m_composite); }
    MaskMode maskMode() const { return static_cast<MaskMode>(m_maskMode); }

    static constexpr FillAttachment attachment() { return FillAttachment::ScrollBackground; }
    static constexpr BlendMode blendMode() { return BlendMode::Normal; }

    // https://drafts.fxtf.org/css-masking/#the-mask-composite
    // If there is no further mask layer, the compositing operator must be ignored.
    CompositeOperator compositeForPainting(bool isLastLayer) const
    {
        if (isLastLayer)
            return CompositeOperator::SourceOver;
        return composite();
    }

    static ImageOrNone initialImage() { return CSS::Keyword::None { }; }
    static PositionX initialPositionX() { using namespace CSS::Literals; return 0_css_percentage; }
    static PositionY initialPositionY() { using namespace CSS::Literals; return 0_css_percentage; }
    static BackgroundSize initialSize() { return CSS::Keyword::Auto { }; }
    static constexpr RepeatStyle initialRepeat() { return { .values { FillRepeat::Repeat, FillRepeat::Repeat } }; }
    static constexpr FillBox initialClip() { return FillBox::BorderBox; }
    static constexpr FillBox initialOrigin() { return FillBox::BorderBox; }
    static constexpr CompositeOperator initialComposite() { return CompositeOperator::SourceOver; }
    static constexpr MaskMode initialMaskMode() { return MaskMode::MatchSource; }

    bool hasImage() const { return m_image.isImage(); }
    bool hasOpaqueImage(const RenderElement&) const;
    bool hasRepeatXY() const { return repeat() == FillRepeat::Repeat; }

    bool clipOccludesNextLayers() const { return m_clip == m_clipMax; }
    void setClipMax(FillBox clipMax) const { m_clipMax = static_cast<unsigned>(clipMax); }

    bool operator==(const MaskLayer&) const;

    FOR_EACH_MASK_LAYER_REFERENCE(DECLARE_COORDINATED_VALUE_LIST_GETTER_AND_SETTERS_REFERENCE)
    FOR_EACH_MASK_LAYER_ENUM(DECLARE_COORDINATED_VALUE_LIST_GETTER_AND_SETTERS_ENUM)

    // Support for the `mask-position` shorthand.
    static Position initialPosition() { return { initialPositionX(), initialPositionY() }; }
    Position position() const { return { m_positionX, m_positionY }; }
    void setPosition(Position&& position) { setPositionX(WTFMove(position.x)); setPositionY(WTFMove(position.y)); }
    void fillPosition(Position&& position) { fillPositionX(WTFMove(position.x)); fillPositionY(WTFMove(position.y)); }
    void clearPosition() { clearPositionX(); clearPositionY(); }
    bool isPositionUnset() const { return isPositionXUnset() && isPositionYUnset(); }
    bool isPositionSet() const { return isPositionXSet() || isPositionYSet(); }
    bool isPositionFilled() const { return isPositionXFilled() || isPositionYFilled(); }

    // CoordinatedValueList interface.

    static constexpr auto computedValueUsesUsedValues = true;
    static constexpr auto baseProperty = PropertyNameConstant<CSSPropertyMaskImage> { };
    static constexpr auto properties =  std::tuple { FOR_EACH_MASK_LAYER_PROPERTY(DECLARE_COORDINATED_VALUE_LIST_PROPERTY) };
    static MaskLayer clone(const MaskLayer& other) { return other; }
    bool isInitial() const { return m_image.isNone(); }

private:
    ImageOrNone m_image;
    PositionX m_positionX;
    PositionY m_positionY;
    BackgroundSize m_size;
    RepeatStyle m_repeat;

    PREFERRED_TYPE(FillBox) unsigned m_clip : FillBoxBitWidth;
    PREFERRED_TYPE(FillBox) unsigned m_origin : FillBoxBitWidth;
    PREFERRED_TYPE(CompositeOperator) unsigned m_composite : 4;
    PREFERRED_TYPE(MaskMode) unsigned m_maskMode : 2;

    PREFERRED_TYPE(FillBox) mutable unsigned m_clipMax : FillBoxBitWidth; // maximum m_clip value from this to bottom layer

    FOR_EACH_MASK_LAYER_PROPERTY(DECLARE_COORDINATED_VALUE_LIST_IS_SET_AND_IS_FILLED_MEMBERS)

    // Needed by macros to access members.
    MaskLayer& data() { return *this; }
    const MaskLayer& data() const { return *this; }
};

FOR_EACH_MASK_LAYER_REFERENCE(DECLARE_COORDINATED_VALUE_LIST_PROPERTY_ACCESSOR_REFERENCE)
FOR_EACH_MASK_LAYER_ENUM(DECLARE_COORDINATED_VALUE_LIST_PROPERTY_ACCESSOR_ENUM)
FOR_EACH_MASK_LAYER_SHORTHAND(DECLARE_COORDINATED_VALUE_LIST_PROPERTY_ACCESSOR_SHORTHAND)

// MARK: - Blending

template<> struct Blending<MaskLayer> {
    auto canBlend(const MaskLayer&, const MaskLayer&) -> bool;
};

// MARK: - Logging

WTF::TextStream& operator<<(WTF::TextStream&, const MaskLayer&);

#undef FOR_EACH_MASK_LAYER_REFERENCE
#undef FOR_EACH_MASK_LAYER_ENUM
#undef FOR_EACH_MASK_LAYER_SHORTHAND
#undef FOR_EACH_MASK_LAYER_PROPERTY

} // namespace Style
} // namespace WebCore