1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
24 #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
25 #include <drawinglayer/attribute/fillgraphicattribute.hxx>
27 #include <vcl/graph.hxx>
30 namespace drawinglayer::attribute
32 class ImpSdrFillGraphicAttribute
36 Graphic maFillGraphic
;
37 basegfx::B2DVector maGraphicLogicSize
;
38 basegfx::B2DVector maSize
;
39 basegfx::B2DVector maOffset
;
40 basegfx::B2DVector maOffsetPosition
;
41 basegfx::B2DVector maRectPoint
;
47 ImpSdrFillGraphicAttribute(
49 const basegfx::B2DVector
& rGraphicLogicSize
,
50 const basegfx::B2DVector
& rSize
,
51 const basegfx::B2DVector
& rOffset
,
52 const basegfx::B2DVector
& rOffsetPosition
,
53 const basegfx::B2DVector
& rRectPoint
,
57 : maFillGraphic(std::move(aFillGraphic
)),
58 maGraphicLogicSize(rGraphicLogicSize
),
61 maOffsetPosition(rOffsetPosition
),
62 maRectPoint(rRectPoint
),
69 ImpSdrFillGraphicAttribute()
77 const Graphic
& getFillGraphic() const { return maFillGraphic
; }
78 const basegfx::B2DVector
& getGraphicLogicSize() const { return maGraphicLogicSize
; }
79 const basegfx::B2DVector
& getSize() const { return maSize
; }
80 const basegfx::B2DVector
& getOffset() const { return maOffset
; }
81 const basegfx::B2DVector
& getOffsetPosition() const { return maOffsetPosition
; }
82 const basegfx::B2DVector
& getRectPoint() const { return maRectPoint
; }
83 bool getTiling() const { return mbTiling
; }
84 bool getStretch() const { return mbStretch
; }
86 bool operator==(const ImpSdrFillGraphicAttribute
& rCandidate
) const
88 return (getFillGraphic() == rCandidate
.getFillGraphic()
89 && getGraphicLogicSize() == rCandidate
.getGraphicLogicSize()
90 && getSize() == rCandidate
.getSize()
91 && getOffset() == rCandidate
.getOffset()
92 && getOffsetPosition() == rCandidate
.getOffsetPosition()
93 && getRectPoint() == rCandidate
.getRectPoint()
94 && getTiling() == rCandidate
.getTiling()
95 && getStretch() == rCandidate
.getStretch()
96 && mbLogSize
== rCandidate
.mbLogSize
);
102 SdrFillGraphicAttribute::ImplType
& theGlobalDefault()
104 static SdrFillGraphicAttribute::ImplType SINGLETON
;
109 SdrFillGraphicAttribute::SdrFillGraphicAttribute(
110 const Graphic
& rFillGraphic
,
111 const basegfx::B2DVector
& rGraphicLogicSize
,
112 const basegfx::B2DVector
& rSize
,
113 const basegfx::B2DVector
& rOffset
,
114 const basegfx::B2DVector
& rOffsetPosition
,
115 const basegfx::B2DVector
& rRectPoint
,
119 : mpSdrFillGraphicAttribute(
120 ImpSdrFillGraphicAttribute(
133 SdrFillGraphicAttribute::SdrFillGraphicAttribute()
134 : mpSdrFillGraphicAttribute(theGlobalDefault())
138 SdrFillGraphicAttribute::SdrFillGraphicAttribute(const SdrFillGraphicAttribute
&) = default;
140 SdrFillGraphicAttribute::SdrFillGraphicAttribute(SdrFillGraphicAttribute
&&) = default;
142 SdrFillGraphicAttribute::~SdrFillGraphicAttribute() = default;
144 bool SdrFillGraphicAttribute::isDefault() const
146 return mpSdrFillGraphicAttribute
.same_object(theGlobalDefault());
149 SdrFillGraphicAttribute
& SdrFillGraphicAttribute::operator=(const SdrFillGraphicAttribute
&) = default;
151 SdrFillGraphicAttribute
& SdrFillGraphicAttribute::operator=(SdrFillGraphicAttribute
&&) = default;
153 bool SdrFillGraphicAttribute::operator==(const SdrFillGraphicAttribute
& rCandidate
) const
155 // tdf#87509 default attr is always != non-default attr, even with same values
156 if(rCandidate
.isDefault() != isDefault())
159 return rCandidate
.mpSdrFillGraphicAttribute
== mpSdrFillGraphicAttribute
;
162 const Graphic
& SdrFillGraphicAttribute::getFillGraphic() const
164 return mpSdrFillGraphicAttribute
->getFillGraphic();
167 const basegfx::B2DVector
& SdrFillGraphicAttribute::getGraphicLogicSize() const
169 return mpSdrFillGraphicAttribute
->getGraphicLogicSize();
172 const basegfx::B2DVector
& SdrFillGraphicAttribute::getSize() const
174 return mpSdrFillGraphicAttribute
->getSize();
177 const basegfx::B2DVector
& SdrFillGraphicAttribute::getOffset() const
179 return mpSdrFillGraphicAttribute
->getOffset();
182 const basegfx::B2DVector
& SdrFillGraphicAttribute::getOffsetPosition() const
184 return mpSdrFillGraphicAttribute
->getOffsetPosition();
187 const basegfx::B2DVector
& SdrFillGraphicAttribute::getRectPoint() const
189 return mpSdrFillGraphicAttribute
->getRectPoint();
192 bool SdrFillGraphicAttribute::getTiling() const
194 return mpSdrFillGraphicAttribute
->getTiling();
197 FillGraphicAttribute
SdrFillGraphicAttribute::createFillGraphicAttribute(const basegfx::B2DRange
& rRange
) const
199 // get logical size of bitmap (before possibly expanding it)
200 Graphic
aGraphic(getFillGraphic());
202 // init values with defaults for stretched
203 basegfx::B2DPoint
aBitmapSize(1.0, 1.0);
204 basegfx::B2DVector
aBitmapTopLeft(0.0, 0.0);
206 // are changes needed? When stretched we are already done, all other values will have no influence
207 if(getTiling() || !mpSdrFillGraphicAttribute
->getStretch())
209 // init values with range sizes
210 const double fRangeWidth(0.0 != rRange
.getWidth() ? rRange
.getWidth() : 1.0);
211 const double fRangeHeight(0.0 != rRange
.getHeight() ? rRange
.getHeight() : 1.0);
212 aBitmapSize
= basegfx::B2DPoint(fRangeWidth
, fRangeHeight
);
215 if(0.0 != getSize().getX())
217 if(getSize().getX() < 0.0)
219 aBitmapSize
.setX(aBitmapSize
.getX() * (getSize().getX() * -0.01));
223 aBitmapSize
.setX(getSize().getX());
228 // #i124002# use GraphicLogicSize directly, do not try to use GetPrefSize
229 // of the graphic, that may not be adapted to the MapMode of the target
230 aBitmapSize
.setX(getGraphicLogicSize().getX());
233 if(0.0 != getSize().getY())
235 if(getSize().getY() < 0.0)
237 aBitmapSize
.setY(aBitmapSize
.getY() * (getSize().getY() * -0.01));
241 aBitmapSize
.setY(getSize().getY());
246 // #i124002# use GraphicLogicSize directly, do not try to use GetPrefSize
247 // of the graphic, that may not be adapted to the MapMode of the target
248 aBitmapSize
.setY(getGraphicLogicSize().getY());
251 // position changes X
252 if(0.0 == getRectPoint().getX())
254 aBitmapTopLeft
.setX((fRangeWidth
- aBitmapSize
.getX()) * 0.5);
256 else if(1.0 == getRectPoint().getX())
258 aBitmapTopLeft
.setX(fRangeWidth
- aBitmapSize
.getX());
261 // offset positions are only meaningful when tiled
262 if(getTiling() && 0.0 != getOffsetPosition().getX())
264 aBitmapTopLeft
.setX(aBitmapTopLeft
.getX() + (aBitmapSize
.getX() * (getOffsetPosition().getX() * 0.01)));
267 // position changes Y
268 if(0.0 == getRectPoint().getY())
270 aBitmapTopLeft
.setY((fRangeHeight
- aBitmapSize
.getY()) * 0.5);
272 else if(1.0 == getRectPoint().getY())
274 aBitmapTopLeft
.setY(fRangeHeight
- aBitmapSize
.getY());
277 // offset positions are only meaningful when tiled
278 if(getTiling() && 0.0 != getOffsetPosition().getY())
280 aBitmapTopLeft
.setY(aBitmapTopLeft
.getY() + (aBitmapSize
.getY() * (getOffsetPosition().getY() * 0.01)));
283 // apply bitmap size scaling to unit rectangle
284 aBitmapTopLeft
.setX(aBitmapTopLeft
.getX() / fRangeWidth
);
285 aBitmapTopLeft
.setY(aBitmapTopLeft
.getY() / fRangeHeight
);
286 aBitmapSize
.setX(aBitmapSize
.getX() / fRangeWidth
);
287 aBitmapSize
.setY(aBitmapSize
.getY() / fRangeHeight
);
290 // get offset in percent
291 const double fOffsetX(std::clamp(getOffset().getX() * 0.01, 0.0, 1.0));
292 const double fOffsetY(std::clamp(getOffset().getY() * 0.01, 0.0, 1.0));
294 // create FillGraphicAttribute
295 return FillGraphicAttribute(
297 basegfx::B2DRange(aBitmapTopLeft
, aBitmapTopLeft
+ aBitmapSize
),
303 } // end of namespace
305 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */