File: RectEdges.h

package info (click to toggle)
webkit2gtk 2.42.2-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 362,432 kB
  • sloc: cpp: 2,881,947; javascript: 282,447; ansic: 134,088; python: 43,789; ruby: 18,308; perl: 15,872; asm: 14,389; xml: 4,395; yacc: 2,350; sh: 2,074; java: 1,734; lex: 1,323; makefile: 296; pascal: 60
file content (127 lines) | stat: -rw-r--r-- 5,884 bytes parent folder | download | duplicates (2)
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
/*
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "WritingMode.h"
#include <array>
#include <wtf/OptionSet.h>
#include <wtf/text/TextStream.h>

namespace WebCore {

enum class BoxSideFlag : uint8_t {
    Top     = 1 << static_cast<unsigned>(BoxSide::Top),
    Right   = 1 << static_cast<unsigned>(BoxSide::Right),
    Bottom  = 1 << static_cast<unsigned>(BoxSide::Bottom),
    Left    = 1 << static_cast<unsigned>(BoxSide::Left)
};

using BoxSideSet = OptionSet<BoxSideFlag>;

template<typename T> class RectEdges {
public:
    RectEdges() = default;

    RectEdges(const RectEdges&) = default;
    RectEdges& operator=(const RectEdges&) = default;

    template<typename U>
    RectEdges(U&& top, U&& right, U&& bottom, U&& left)
        : m_sides({ { std::forward<T>(top), std::forward<T>(right), std::forward<T>(bottom), std::forward<T>(left) } })
    { }

    T& at(BoxSide side) { return m_sides[static_cast<size_t>(side)]; }
    T& operator[](BoxSide side) { return m_sides[static_cast<size_t>(side)]; }
    T& top() { return at(BoxSide::Top); }
    T& right() { return at(BoxSide::Right); }
    T& bottom() { return at(BoxSide::Bottom); }
    T& left() { return at(BoxSide::Left); }

    const T& at(BoxSide side) const { return m_sides[static_cast<size_t>(side)]; }
    const T& operator[](BoxSide side) const { return m_sides[static_cast<size_t>(side)]; }
    const T& top() const { return at(BoxSide::Top); }
    const T& right() const { return at(BoxSide::Right); }
    const T& bottom() const { return at(BoxSide::Bottom); }
    const T& left() const { return at(BoxSide::Left); }

    void setAt(BoxSide side, const T& v) { at(side) = v; }
    void setTop(const T& top) { setAt(BoxSide::Top, top); }
    void setRight(const T& right) { setAt(BoxSide::Right, right); }
    void setBottom(const T& bottom) { setAt(BoxSide::Bottom, bottom); }
    void setLeft(const T& left) { setAt(BoxSide::Left, left); }

    T& before(WritingMode writingMode) { return at(mapLogicalSideToPhysicalSide(writingMode, LogicalBoxSide::BlockStart)); }
    T& after(WritingMode writingMode) { return at(mapLogicalSideToPhysicalSide(writingMode, LogicalBoxSide::BlockEnd)); }
    T& start(WritingMode writingMode, TextDirection direction = TextDirection::LTR) { return at(mapLogicalSideToPhysicalSide(makeTextFlow(writingMode, direction), LogicalBoxSide::InlineStart)); }
    T& end(WritingMode writingMode, TextDirection direction = TextDirection::LTR) { return at(mapLogicalSideToPhysicalSide(makeTextFlow(writingMode, direction), LogicalBoxSide::InlineEnd)); }

    const T& before(WritingMode writingMode) const { return at(mapLogicalSideToPhysicalSide(writingMode, LogicalBoxSide::BlockStart)); }
    const T& after(WritingMode writingMode) const { return at(mapLogicalSideToPhysicalSide(writingMode, LogicalBoxSide::BlockEnd)); }
    const T& start(WritingMode writingMode, TextDirection direction = TextDirection::LTR) const { return at(mapLogicalSideToPhysicalSide(makeTextFlow(writingMode, direction), LogicalBoxSide::InlineStart)); }
    const T& end(WritingMode writingMode, TextDirection direction = TextDirection::LTR) const { return at(mapLogicalSideToPhysicalSide(makeTextFlow(writingMode, direction), LogicalBoxSide::InlineEnd)); }

    void setBefore(const T& before, WritingMode writingMode) { this->before(writingMode) = before; }
    void setAfter(const T& after, WritingMode writingMode) { this->after(writingMode) = after; }
    void setStart(const T& start, WritingMode writingMode, TextDirection direction = TextDirection::LTR) { this->start(writingMode, direction) = start; }
    void setEnd(const T& end, WritingMode writingMode, TextDirection direction = TextDirection::LTR) { this->end(writingMode, direction) = end; }

    bool operator==(const RectEdges& other) const { return m_sides == other.m_sides; }

    bool isZero() const
    {
        return !top() && !right() && !bottom() && !left();
    }

private:
    std::array<T, 4> m_sides { };
};

template<typename T>
constexpr RectEdges<T> operator+(const RectEdges<T>& a, const RectEdges<T>& b)
{
    return {
        a.top() + b.top(),
        a.right() + b.right(),
        a.bottom() + b.bottom(),
        a.left() + b.left()
    };
}

template<typename T>
inline RectEdges<T>& operator+=(RectEdges<T>& a, const RectEdges<T>& b)
{
    a = a + b;
    return a;
}

template<typename T>
TextStream& operator<<(TextStream& ts, const RectEdges<T>& edges)
{
    ts << "[top " << edges.top() << " right " << edges.right() << " bottom " << edges.bottom() << " left " << edges.left() << "]";
    return ts;
}

}