Use #pragma once in WebCore
[WebKit-https.git] / Source / WebCore / rendering / style / NinePieceImage.h
1 /*
2  * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3  *           (C) 2000 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2013, 2015 Apple Inc. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  */
23
24 #pragma once
25
26 #include "DataRef.h"
27 #include "LayoutRect.h"
28 #include "LayoutSize.h"
29 #include "LayoutUnit.h"
30 #include "LengthBox.h"
31 #include "StyleImage.h"
32 #include <wtf/Vector.h>
33
34 namespace WebCore {
35
36 enum ENinePieceImageRule {
37     StretchImageRule, RoundImageRule, SpaceImageRule, RepeatImageRule
38 };
39
40 enum ImagePiece {
41     MinPiece = 0,
42     TopLeftPiece = MinPiece,
43     LeftPiece,
44     BottomLeftPiece,
45     TopRightPiece,
46     RightPiece,
47     BottomRightPiece,
48     TopPiece,
49     BottomPiece,
50     MiddlePiece,
51     MaxPiece
52 };
53
54 inline ImagePiece& operator++(ImagePiece& piece)
55 {
56     piece = static_cast<ImagePiece>(static_cast<int>(piece) + 1);
57     return piece;
58 }
59
60 inline bool isCornerPiece(ImagePiece piece)
61 {
62     return piece == TopLeftPiece || piece == TopRightPiece || piece == BottomLeftPiece || piece == BottomRightPiece;
63 }
64
65 inline bool isMiddlePiece(ImagePiece piece)
66 {
67     return piece == MiddlePiece;
68 }
69
70 inline bool isHorizontalPiece(ImagePiece piece)
71 {
72     return piece == TopPiece || piece == BottomPiece || piece == MiddlePiece;
73 }
74
75 inline bool isVerticalPiece(ImagePiece piece)
76 {
77     return piece == LeftPiece || piece == RightPiece || piece == MiddlePiece;
78 }
79
80 inline PhysicalBoxSide imagePieceHorizontalSide(ImagePiece piece)
81 {
82     if (piece == TopLeftPiece || piece == TopPiece || piece == TopRightPiece)
83         return TopSide;
84
85     if (piece == BottomLeftPiece || piece == BottomPiece || piece == BottomRightPiece)
86         return BottomSide;
87
88     return NilSide;
89 }
90
91 inline PhysicalBoxSide imagePieceVerticalSide(ImagePiece piece)
92 {
93     if (piece == TopLeftPiece || piece == LeftPiece || piece == BottomLeftPiece)
94         return LeftSide;
95
96     if (piece == TopRightPiece || piece == RightPiece || piece == BottomRightPiece)
97         return RightSide;
98
99     return NilSide;
100 }
101
102 class RenderStyle;
103
104 class NinePieceImageData : public RefCounted<NinePieceImageData> {
105 public:
106     static Ref<NinePieceImageData> create() { return adoptRef(*new NinePieceImageData); }
107     Ref<NinePieceImageData> copy() const;
108
109     bool operator==(const NinePieceImageData&) const;
110     bool operator!=(const NinePieceImageData& o) const { return !(*this == o); }
111
112     bool fill : 1;
113     unsigned horizontalRule : 2; // ENinePieceImageRule
114     unsigned verticalRule : 2; // ENinePieceImageRule
115     RefPtr<StyleImage> image;
116     LengthBox imageSlices;
117     LengthBox borderSlices;
118     LengthBox outset;
119
120 private:
121     NinePieceImageData();
122     NinePieceImageData(const NinePieceImageData&);
123 };
124
125 class NinePieceImage {
126 public:
127     NinePieceImage();
128     NinePieceImage(PassRefPtr<StyleImage>, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule);
129
130     bool operator==(const NinePieceImage& other) const { return m_data == other.m_data; }
131     bool operator!=(const NinePieceImage& other) const { return m_data != other.m_data; }
132
133     bool hasImage() const { return m_data->image; }
134     StyleImage* image() const { return m_data->image.get(); }
135     void setImage(PassRefPtr<StyleImage> image) { m_data.access()->image = image; }
136     
137     const LengthBox& imageSlices() const { return m_data->imageSlices; }
138     void setImageSlices(LengthBox slices) { m_data.access()->imageSlices = WTFMove(slices); }
139
140     bool fill() const { return m_data->fill; }
141     void setFill(bool fill) { m_data.access()->fill = fill; }
142
143     const LengthBox& borderSlices() const { return m_data->borderSlices; }
144     void setBorderSlices(LengthBox slices) { m_data.access()->borderSlices = WTFMove(slices); }
145
146     const LengthBox& outset() const { return m_data->outset; }
147     void setOutset(LengthBox outset) { m_data.access()->outset = WTFMove(outset); }
148
149     ENinePieceImageRule horizontalRule() const { return static_cast<ENinePieceImageRule>(m_data->horizontalRule); }
150     void setHorizontalRule(ENinePieceImageRule rule) { m_data.access()->horizontalRule = rule; }
151     
152     ENinePieceImageRule verticalRule() const { return static_cast<ENinePieceImageRule>(m_data->verticalRule); }
153     void setVerticalRule(ENinePieceImageRule rule) { m_data.access()->verticalRule = rule; }
154
155     void copyImageSlicesFrom(const NinePieceImage& other)
156     {
157         m_data.access()->imageSlices = other.m_data->imageSlices;
158         m_data.access()->fill = other.m_data->fill;
159     }
160
161     void copyBorderSlicesFrom(const NinePieceImage& other)
162     {
163         m_data.access()->borderSlices = other.m_data->borderSlices;
164     }
165     
166     void copyOutsetFrom(const NinePieceImage& other)
167     {
168         m_data.access()->outset = other.m_data->outset;
169     }
170
171     void copyRepeatFrom(const NinePieceImage& other)
172     {
173         m_data.access()->horizontalRule = other.m_data->horizontalRule;
174         m_data.access()->verticalRule = other.m_data->verticalRule;
175     }
176
177     void setMaskDefaults()
178     {
179         m_data.access()->imageSlices = LengthBox(0);
180         m_data.access()->fill = true;
181         m_data.access()->borderSlices = LengthBox();
182     }
183
184     static LayoutUnit computeOutset(const Length& outsetSide, LayoutUnit borderSide)
185     {
186         if (outsetSide.isRelative())
187             return outsetSide.value() * borderSide;
188         return outsetSide.value();
189     }
190
191     static LayoutUnit computeSlice(Length, LayoutUnit width, LayoutUnit slice, LayoutUnit extent);
192     static LayoutBoxExtent computeSlices(const LayoutSize&, const LengthBox& lengths, int scaleFactor);
193     static LayoutBoxExtent computeSlices(const LayoutSize&, const LengthBox& lengths, const FloatBoxExtent& widths, const LayoutBoxExtent& slices);
194
195     static bool isEmptyPieceRect(ImagePiece, const LayoutBoxExtent& slices);
196     static bool isEmptyPieceRect(ImagePiece, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects);
197
198     static Vector<FloatRect> computeNineRects(const FloatRect& outer, const LayoutBoxExtent& slices, float deviceScaleFactor);
199
200     static void scaleSlicesIfNeeded(const LayoutSize&, LayoutBoxExtent& slices, float deviceScaleFactor);
201
202     static FloatSize computeSideTileScale(ImagePiece, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects);
203     static FloatSize computeMiddleTileScale(const Vector<FloatSize>& scales, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects, ENinePieceImageRule hRule, ENinePieceImageRule vRule);
204     static Vector<FloatSize> computeTileScales(const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects, ENinePieceImageRule hRule, ENinePieceImageRule vRule);
205
206     void paint(GraphicsContext&, RenderElement*, const RenderStyle&, const LayoutRect& destination, const LayoutSize& source, float deviceScaleFactor, CompositeOperator) const;
207
208 private:
209     DataRef<NinePieceImageData> m_data;
210 };
211
212 TextStream& operator<<(TextStream&, const NinePieceImage&);
213
214 } // namespace WebCore