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 Apple Inc. All rights
6  * reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24 
25 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_NINE_PIECE_IMAGE_H_
26 #define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_NINE_PIECE_IMAGE_H_
27 
28 #include "third_party/blink/renderer/core/core_export.h"
29 #include "third_party/blink/renderer/core/style/border_image_length_box.h"
30 #include "third_party/blink/renderer/core/style/data_ref.h"
31 #include "third_party/blink/renderer/core/style/style_image.h"
32 #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
33 #include "third_party/blink/renderer/platform/geometry/length_box.h"
34 #include "third_party/blink/renderer/platform/heap/persistent.h"
35 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
36 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
37 
38 namespace blink {
39 
40 enum ENinePieceImageRule {
41   kStretchImageRule,
42   kRoundImageRule,
43   kSpaceImageRule,
44   kRepeatImageRule
45 };
46 
47 class CORE_EXPORT NinePieceImageData
48     : public RefCountedCopyable<NinePieceImageData> {
49  public:
Create()50   static scoped_refptr<NinePieceImageData> Create() {
51     return base::AdoptRef(new NinePieceImageData);
52   }
Copy()53   scoped_refptr<NinePieceImageData> Copy() const {
54     return base::AdoptRef(new NinePieceImageData(*this));
55   }
56 
57   bool operator==(const NinePieceImageData&) const;
58   bool operator!=(const NinePieceImageData& o) const { return !(*this == o); }
59 
60   unsigned fill : 1;
61   unsigned horizontal_rule : 2;  // ENinePieceImageRule
62   unsigned vertical_rule : 2;    // ENinePieceImageRule
63   Persistent<StyleImage> image;
64   LengthBox image_slices;
65   BorderImageLengthBox border_slices;
66   BorderImageLengthBox outset;
67 
68  private:
69   NinePieceImageData();
70   NinePieceImageData(const NinePieceImageData&) = default;
71 };
72 
73 class CORE_EXPORT NinePieceImage {
74   DISALLOW_NEW();
75 
76  public:
77   NinePieceImage();
78   NinePieceImage(StyleImage*,
79                  LengthBox image_slices,
80                  bool fill,
81                  const BorderImageLengthBox& border_slices,
82                  const BorderImageLengthBox& outset,
83                  ENinePieceImageRule horizontal_rule,
84                  ENinePieceImageRule vertical_rule);
85 
MaskDefaults()86   static NinePieceImage MaskDefaults() {
87     NinePieceImage image;
88     image.data_.Access()->image_slices = LengthBox(0);
89     image.data_.Access()->fill = true;
90     image.data_.Access()->border_slices = BorderImageLengthBox(Length::Auto());
91     return image;
92   }
93 
94   bool operator==(const NinePieceImage& other) const {
95     return data_ == other.data_;
96   }
97   bool operator!=(const NinePieceImage& other) const {
98     return data_ != other.data_;
99   }
100 
HasImage()101   bool HasImage() const { return data_->image; }
GetImage()102   StyleImage* GetImage() const { return data_->image.Get(); }
SetImage(StyleImage * image)103   void SetImage(StyleImage* image) { data_.Access()->image = image; }
104 
ImageSlices()105   const LengthBox& ImageSlices() const { return data_->image_slices; }
SetImageSlices(const LengthBox & slices)106   void SetImageSlices(const LengthBox& slices) {
107     data_.Access()->image_slices = slices;
108   }
109 
Fill()110   bool Fill() const { return data_->fill; }
SetFill(bool fill)111   void SetFill(bool fill) { data_.Access()->fill = fill; }
112 
BorderSlices()113   const BorderImageLengthBox& BorderSlices() const {
114     return data_->border_slices;
115   }
SetBorderSlices(const BorderImageLengthBox & slices)116   void SetBorderSlices(const BorderImageLengthBox& slices) {
117     data_.Access()->border_slices = slices;
118   }
119 
Outset()120   const BorderImageLengthBox& Outset() const { return data_->outset; }
SetOutset(const BorderImageLengthBox & outset)121   void SetOutset(const BorderImageLengthBox& outset) {
122     data_.Access()->outset = outset;
123   }
124 
HorizontalRule()125   ENinePieceImageRule HorizontalRule() const {
126     return static_cast<ENinePieceImageRule>(data_->horizontal_rule);
127   }
SetHorizontalRule(ENinePieceImageRule rule)128   void SetHorizontalRule(ENinePieceImageRule rule) {
129     data_.Access()->horizontal_rule = rule;
130   }
131 
VerticalRule()132   ENinePieceImageRule VerticalRule() const {
133     return static_cast<ENinePieceImageRule>(data_->vertical_rule);
134   }
SetVerticalRule(ENinePieceImageRule rule)135   void SetVerticalRule(ENinePieceImageRule rule) {
136     data_.Access()->vertical_rule = rule;
137   }
138 
CopyImageSlicesFrom(const NinePieceImage & other)139   void CopyImageSlicesFrom(const NinePieceImage& other) {
140     data_.Access()->image_slices = other.data_->image_slices;
141     data_.Access()->fill = other.data_->fill;
142   }
143 
CopyBorderSlicesFrom(const NinePieceImage & other)144   void CopyBorderSlicesFrom(const NinePieceImage& other) {
145     data_.Access()->border_slices = other.data_->border_slices;
146   }
147 
CopyOutsetFrom(const NinePieceImage & other)148   void CopyOutsetFrom(const NinePieceImage& other) {
149     data_.Access()->outset = other.data_->outset;
150   }
151 
CopyRepeatFrom(const NinePieceImage & other)152   void CopyRepeatFrom(const NinePieceImage& other) {
153     data_.Access()->horizontal_rule = other.data_->horizontal_rule;
154     data_.Access()->vertical_rule = other.data_->vertical_rule;
155   }
156 
ComputeOutset(const BorderImageLength & outset_side,int border_side)157   static LayoutUnit ComputeOutset(const BorderImageLength& outset_side,
158                                   int border_side) {
159     if (outset_side.IsNumber())
160       return LayoutUnit(outset_side.Number() * border_side);
161     return LayoutUnit(outset_side.length().Value());
162   }
163 
164  private:
165   DataRef<NinePieceImageData> data_;
166 };
167 
168 }  // namespace blink
169 
170 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_NINE_PIECE_IMAGE_H_
171