xref: /trunk/main/svx/source/sdr/attribute/sdrallfillattributeshelper.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1*56b35d86SArmin Le Grand /**************************************************************
2*56b35d86SArmin Le Grand  *
3*56b35d86SArmin Le Grand  * Licensed to the Apache Software Foundation (ASF) under one
4*56b35d86SArmin Le Grand  * or more contributor license agreements.  See the NOTICE file
5*56b35d86SArmin Le Grand  * distributed with this work for additional information
6*56b35d86SArmin Le Grand  * regarding copyright ownership.  The ASF licenses this file
7*56b35d86SArmin Le Grand  * to you under the Apache License, Version 2.0 (the
8*56b35d86SArmin Le Grand  * "License"); you may not use this file except in compliance
9*56b35d86SArmin Le Grand  * with the License.  You may obtain a copy of the License at
10*56b35d86SArmin Le Grand  *
11*56b35d86SArmin Le Grand  *   http://www.apache.org/licenses/LICENSE-2.0
12*56b35d86SArmin Le Grand  *
13*56b35d86SArmin Le Grand  * Unless required by applicable law or agreed to in writing,
14*56b35d86SArmin Le Grand  * software distributed under the License is distributed on an
15*56b35d86SArmin Le Grand  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*56b35d86SArmin Le Grand  * KIND, either express or implied.  See the License for the
17*56b35d86SArmin Le Grand  * specific language governing permissions and limitations
18*56b35d86SArmin Le Grand  * under the License.
19*56b35d86SArmin Le Grand  *
20*56b35d86SArmin Le Grand  *************************************************************/
21*56b35d86SArmin Le Grand 
22*56b35d86SArmin Le Grand // MARKER(update_precomp.py): autogen include statement, do not remove
23*56b35d86SArmin Le Grand #include "precompiled_svx.hxx"
24*56b35d86SArmin Le Grand 
25*56b35d86SArmin Le Grand #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
26*56b35d86SArmin Le Grand #include <svx/sdr/primitive2d/sdrattributecreator.hxx>
27*56b35d86SArmin Le Grand #include <svx/sdr/primitive2d/sdrdecompositiontools.hxx>
28*56b35d86SArmin Le Grand #include <basegfx/polygon/b2dpolygontools.hxx>
29*56b35d86SArmin Le Grand #include <basegfx/matrix/b2dhommatrix.hxx>
30*56b35d86SArmin Le Grand #include <basegfx/polygon/b2dpolygon.hxx>
31*56b35d86SArmin Le Grand #include <drawinglayer/attribute/fillhatchattribute.hxx>
32*56b35d86SArmin Le Grand #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
33*56b35d86SArmin Le Grand #include <svx/xfillit0.hxx>
34*56b35d86SArmin Le Grand #include <vcl/graph.hxx>
35*56b35d86SArmin Le Grand 
36*56b35d86SArmin Le Grand //////////////////////////////////////////////////////////////////////////////
37*56b35d86SArmin Le Grand 
38*56b35d86SArmin Le Grand namespace drawinglayer
39*56b35d86SArmin Le Grand {
40*56b35d86SArmin Le Grand     namespace attribute
41*56b35d86SArmin Le Grand     {
createPrimitive2DSequence(const basegfx::B2DRange & rPaintRange,const basegfx::B2DRange & rDefineRange)42*56b35d86SArmin Le Grand         void SdrAllFillAttributesHelper::createPrimitive2DSequence(
43*56b35d86SArmin Le Grand             const basegfx::B2DRange& rPaintRange,
44*56b35d86SArmin Le Grand             const basegfx::B2DRange& rDefineRange)
45*56b35d86SArmin Le Grand         {
46*56b35d86SArmin Le Grand             // reset and remember new target range for object geometry
47*56b35d86SArmin Le Grand             maLastPaintRange = rPaintRange;
48*56b35d86SArmin Le Grand             maLastDefineRange = rDefineRange;
49*56b35d86SArmin Le Grand 
50*56b35d86SArmin Le Grand             if(isUsed())
51*56b35d86SArmin Le Grand             {
52*56b35d86SArmin Le Grand                 maPrimitives.realloc(1);
53*56b35d86SArmin Le Grand                 maPrimitives[0] = drawinglayer::primitive2d::createPolyPolygonFillPrimitive(
54*56b35d86SArmin Le Grand                     basegfx::B2DPolyPolygon(
55*56b35d86SArmin Le Grand                         basegfx::tools::createPolygonFromRect(
56*56b35d86SArmin Le Grand                             maLastPaintRange)),
57*56b35d86SArmin Le Grand                         maLastDefineRange,
58*56b35d86SArmin Le Grand                     maFillAttribute.get() ? *maFillAttribute.get() : drawinglayer::attribute::SdrFillAttribute(),
59*56b35d86SArmin Le Grand                     maFillGradientAttribute.get() ? *maFillGradientAttribute.get() : drawinglayer::attribute::FillGradientAttribute());
60*56b35d86SArmin Le Grand             }
61*56b35d86SArmin Le Grand         }
62*56b35d86SArmin Le Grand 
SdrAllFillAttributesHelper()63*56b35d86SArmin Le Grand         SdrAllFillAttributesHelper::SdrAllFillAttributesHelper()
64*56b35d86SArmin Le Grand         :   maLastPaintRange(),
65*56b35d86SArmin Le Grand             maLastDefineRange(),
66*56b35d86SArmin Le Grand             maFillAttribute(),
67*56b35d86SArmin Le Grand             maFillGradientAttribute(),
68*56b35d86SArmin Le Grand             maPrimitives()
69*56b35d86SArmin Le Grand         {
70*56b35d86SArmin Le Grand         }
71*56b35d86SArmin Le Grand 
SdrAllFillAttributesHelper(const Color & rColor)72*56b35d86SArmin Le Grand         SdrAllFillAttributesHelper::SdrAllFillAttributesHelper(const Color& rColor)
73*56b35d86SArmin Le Grand         :   maLastPaintRange(),
74*56b35d86SArmin Le Grand             maLastDefineRange(),
75*56b35d86SArmin Le Grand             maFillAttribute(),
76*56b35d86SArmin Le Grand             maFillGradientAttribute(),
77*56b35d86SArmin Le Grand             maPrimitives()
78*56b35d86SArmin Le Grand         {
79*56b35d86SArmin Le Grand             maFillAttribute.reset(
80*56b35d86SArmin Le Grand                 new drawinglayer::attribute::SdrFillAttribute(
81*56b35d86SArmin Le Grand                     0.0,
82*56b35d86SArmin Le Grand                     Color(rColor.GetRGBColor()).getBColor(),
83*56b35d86SArmin Le Grand                     drawinglayer::attribute::FillGradientAttribute(),
84*56b35d86SArmin Le Grand                     drawinglayer::attribute::FillHatchAttribute(),
85*56b35d86SArmin Le Grand                     drawinglayer::attribute::SdrFillGraphicAttribute()));
86*56b35d86SArmin Le Grand         }
87*56b35d86SArmin Le Grand 
SdrAllFillAttributesHelper(const SfxItemSet & rSet)88*56b35d86SArmin Le Grand         SdrAllFillAttributesHelper::SdrAllFillAttributesHelper(const SfxItemSet& rSet)
89*56b35d86SArmin Le Grand         :   maLastPaintRange(),
90*56b35d86SArmin Le Grand             maLastDefineRange(),
91*56b35d86SArmin Le Grand             maFillAttribute(
92*56b35d86SArmin Le Grand                 new drawinglayer::attribute::SdrFillAttribute(
93*56b35d86SArmin Le Grand                     drawinglayer::primitive2d::createNewSdrFillAttribute(rSet))),
94*56b35d86SArmin Le Grand             maFillGradientAttribute(
95*56b35d86SArmin Le Grand                 new drawinglayer::attribute::FillGradientAttribute(
96*56b35d86SArmin Le Grand                     drawinglayer::primitive2d::createNewTransparenceGradientAttribute(rSet))),
97*56b35d86SArmin Le Grand             maPrimitives()
98*56b35d86SArmin Le Grand         {
99*56b35d86SArmin Le Grand         }
100*56b35d86SArmin Le Grand 
~SdrAllFillAttributesHelper()101*56b35d86SArmin Le Grand         SdrAllFillAttributesHelper::~SdrAllFillAttributesHelper()
102*56b35d86SArmin Le Grand         {
103*56b35d86SArmin Le Grand         }
104*56b35d86SArmin Le Grand 
isUsed() const105*56b35d86SArmin Le Grand         bool SdrAllFillAttributesHelper::isUsed() const
106*56b35d86SArmin Le Grand         {
107*56b35d86SArmin Le Grand             // only depends on fill, FillGradientAttribute alone defines no fill
108*56b35d86SArmin Le Grand             return maFillAttribute.get() && !maFillAttribute->isDefault();
109*56b35d86SArmin Le Grand         }
110*56b35d86SArmin Le Grand 
isTransparent() const111*56b35d86SArmin Le Grand         bool SdrAllFillAttributesHelper::isTransparent() const
112*56b35d86SArmin Le Grand         {
113*56b35d86SArmin Le Grand             if(hasSdrFillAttribute() && 0.0 != maFillAttribute->getTransparence())
114*56b35d86SArmin Le Grand             {
115*56b35d86SArmin Le Grand                 return true;
116*56b35d86SArmin Le Grand             }
117*56b35d86SArmin Le Grand 
118*56b35d86SArmin Le Grand             if(hasFillGradientAttribute() && !maFillGradientAttribute->isDefault())
119*56b35d86SArmin Le Grand             {
120*56b35d86SArmin Le Grand                 return true;
121*56b35d86SArmin Le Grand             }
122*56b35d86SArmin Le Grand 
123*56b35d86SArmin Le Grand             if(hasSdrFillAttribute())
124*56b35d86SArmin Le Grand             {
125*56b35d86SArmin Le Grand                 const Graphic& rGraphic = getFillAttribute().getFillGraphic().getFillGraphic();
126*56b35d86SArmin Le Grand 
127*56b35d86SArmin Le Grand                 return rGraphic.IsSupportedGraphic() && rGraphic.IsTransparent();
128*56b35d86SArmin Le Grand             }
129*56b35d86SArmin Le Grand 
130*56b35d86SArmin Le Grand             return false;
131*56b35d86SArmin Le Grand         }
132*56b35d86SArmin Le Grand 
getFillAttribute() const133*56b35d86SArmin Le Grand         const drawinglayer::attribute::SdrFillAttribute& SdrAllFillAttributesHelper::getFillAttribute() const
134*56b35d86SArmin Le Grand         {
135*56b35d86SArmin Le Grand             if(!maFillAttribute.get())
136*56b35d86SArmin Le Grand             {
137*56b35d86SArmin Le Grand                 const_cast< SdrAllFillAttributesHelper* >(this)->maFillAttribute.reset(new drawinglayer::attribute::SdrFillAttribute());
138*56b35d86SArmin Le Grand             }
139*56b35d86SArmin Le Grand 
140*56b35d86SArmin Le Grand             return *maFillAttribute.get();
141*56b35d86SArmin Le Grand         }
142*56b35d86SArmin Le Grand 
getFillGradientAttribute() const143*56b35d86SArmin Le Grand         const drawinglayer::attribute::FillGradientAttribute& SdrAllFillAttributesHelper::getFillGradientAttribute() const
144*56b35d86SArmin Le Grand         {
145*56b35d86SArmin Le Grand             if(!maFillGradientAttribute.get())
146*56b35d86SArmin Le Grand             {
147*56b35d86SArmin Le Grand                 const_cast< SdrAllFillAttributesHelper* >(this)->maFillGradientAttribute.reset(new drawinglayer::attribute::FillGradientAttribute());
148*56b35d86SArmin Le Grand             }
149*56b35d86SArmin Le Grand 
150*56b35d86SArmin Le Grand             return *maFillGradientAttribute.get();
151*56b35d86SArmin Le Grand         }
152*56b35d86SArmin Le Grand 
getPrimitive2DSequence(const basegfx::B2DRange & rPaintRange,const basegfx::B2DRange & rDefineRange) const153*56b35d86SArmin Le Grand         const drawinglayer::primitive2d::Primitive2DSequence& SdrAllFillAttributesHelper::getPrimitive2DSequence(
154*56b35d86SArmin Le Grand             const basegfx::B2DRange& rPaintRange,
155*56b35d86SArmin Le Grand             const basegfx::B2DRange& rDefineRange) const
156*56b35d86SArmin Le Grand         {
157*56b35d86SArmin Le Grand             if(maPrimitives.getLength() && (maLastPaintRange != rPaintRange || maLastDefineRange != rDefineRange))
158*56b35d86SArmin Le Grand             {
159*56b35d86SArmin Le Grand                 const_cast< SdrAllFillAttributesHelper* >(this)->maPrimitives.realloc(0);
160*56b35d86SArmin Le Grand             }
161*56b35d86SArmin Le Grand 
162*56b35d86SArmin Le Grand             if(!maPrimitives.getLength())
163*56b35d86SArmin Le Grand             {
164*56b35d86SArmin Le Grand                 const_cast< SdrAllFillAttributesHelper* >(this)->createPrimitive2DSequence(rPaintRange, rDefineRange);
165*56b35d86SArmin Le Grand             }
166*56b35d86SArmin Le Grand 
167*56b35d86SArmin Le Grand             return maPrimitives;
168*56b35d86SArmin Le Grand         }
169*56b35d86SArmin Le Grand 
getAverageColor(const basegfx::BColor & rFallback) const170*56b35d86SArmin Le Grand         basegfx::BColor SdrAllFillAttributesHelper::getAverageColor(const basegfx::BColor& rFallback) const
171*56b35d86SArmin Le Grand         {
172*56b35d86SArmin Le Grand             basegfx::BColor aRetval(rFallback);
173*56b35d86SArmin Le Grand 
174*56b35d86SArmin Le Grand             if(maFillAttribute.get() && !maFillAttribute->isDefault())
175*56b35d86SArmin Le Grand             {
176*56b35d86SArmin Le Grand                 const drawinglayer::attribute::FillGradientAttribute& rFillGradientAttribute = maFillAttribute->getGradient();
177*56b35d86SArmin Le Grand                 const drawinglayer::attribute::FillHatchAttribute& rFillHatchAttribute = maFillAttribute->getHatch();
178*56b35d86SArmin Le Grand                 const drawinglayer::attribute::SdrFillGraphicAttribute& rSdrFillGraphicAttribute = maFillAttribute->getFillGraphic();
179*56b35d86SArmin Le Grand                 const drawinglayer::attribute::FillGradientAttribute& rFillTransparenceGradientAttribute = getFillGradientAttribute();
180*56b35d86SArmin Le Grand                 double fTransparence(maFillAttribute->getTransparence());
181*56b35d86SArmin Le Grand 
182*56b35d86SArmin Le Grand                 if(!rFillTransparenceGradientAttribute.isDefault())
183*56b35d86SArmin Le Grand                 {
184*56b35d86SArmin Le Grand                     const double fTransA = rFillTransparenceGradientAttribute.getStartColor().luminance();
185*56b35d86SArmin Le Grand                     const double fTransB = rFillTransparenceGradientAttribute.getEndColor().luminance();
186*56b35d86SArmin Le Grand 
187*56b35d86SArmin Le Grand                     fTransparence = (fTransA + fTransB) * 0.5;
188*56b35d86SArmin Le Grand                 }
189*56b35d86SArmin Le Grand 
190*56b35d86SArmin Le Grand                 if(!rFillGradientAttribute.isDefault())
191*56b35d86SArmin Le Grand                 {
192*56b35d86SArmin Le Grand                     // gradient fill
193*56b35d86SArmin Le Grand                     const basegfx::BColor& rStart = rFillGradientAttribute.getStartColor();
194*56b35d86SArmin Le Grand                     const basegfx::BColor& rEnd = rFillGradientAttribute.getEndColor();
195*56b35d86SArmin Le Grand 
196*56b35d86SArmin Le Grand                     aRetval = basegfx::interpolate(rStart, rEnd, 0.5);
197*56b35d86SArmin Le Grand                 }
198*56b35d86SArmin Le Grand                 else if(!rFillHatchAttribute.isDefault())
199*56b35d86SArmin Le Grand                 {
200*56b35d86SArmin Le Grand                     // hatch fill
201*56b35d86SArmin Le Grand                     const basegfx::BColor& rColor = rFillHatchAttribute.getColor();
202*56b35d86SArmin Le Grand 
203*56b35d86SArmin Le Grand                     if(rFillHatchAttribute.isFillBackground())
204*56b35d86SArmin Le Grand                     {
205*56b35d86SArmin Le Grand                         const basegfx::BColor& rBackgroundColor = maFillAttribute->getColor();
206*56b35d86SArmin Le Grand 
207*56b35d86SArmin Le Grand                         // mix colors 50%/50%
208*56b35d86SArmin Le Grand                         aRetval = basegfx::interpolate(rColor, rBackgroundColor, 0.5);
209*56b35d86SArmin Le Grand                     }
210*56b35d86SArmin Le Grand                     else
211*56b35d86SArmin Le Grand                     {
212*56b35d86SArmin Le Grand                         // mix color with fallback color
213*56b35d86SArmin Le Grand                         aRetval = basegfx::interpolate(rColor, rFallback, 0.5);
214*56b35d86SArmin Le Grand                     }
215*56b35d86SArmin Le Grand                 }
216*56b35d86SArmin Le Grand                 else if(!rSdrFillGraphicAttribute.isDefault())
217*56b35d86SArmin Le Grand                 {
218*56b35d86SArmin Le Grand                     // graphic fill
219*56b35d86SArmin Le Grand 
220*56b35d86SArmin Le Grand                     // not used yet by purpose (see SwPageFrm::GetDrawBackgrdColor()),
221*56b35d86SArmin Le Grand                     // use fallback (already set)
222*56b35d86SArmin Le Grand                 }
223*56b35d86SArmin Le Grand                 else
224*56b35d86SArmin Le Grand                 {
225*56b35d86SArmin Le Grand                     // color fill
226*56b35d86SArmin Le Grand                     aRetval = maFillAttribute->getColor();
227*56b35d86SArmin Le Grand                 }
228*56b35d86SArmin Le Grand 
229*56b35d86SArmin Le Grand                 if(!basegfx::fTools::equalZero(fTransparence))
230*56b35d86SArmin Le Grand                 {
231*56b35d86SArmin Le Grand                     // blend into transparency
232*56b35d86SArmin Le Grand                     aRetval = basegfx::interpolate(aRetval, rFallback, fTransparence);
233*56b35d86SArmin Le Grand                 }
234*56b35d86SArmin Le Grand             }
235*56b35d86SArmin Le Grand 
236*56b35d86SArmin Le Grand             return aRetval.clamp();
237*56b35d86SArmin Le Grand         }
238*56b35d86SArmin Le Grand 
needCompleteRepaint() const239*56b35d86SArmin Le Grand         bool SdrAllFillAttributesHelper::needCompleteRepaint() const
240*56b35d86SArmin Le Grand         {
241*56b35d86SArmin Le Grand             if(!isUsed() || !hasSdrFillAttribute())
242*56b35d86SArmin Le Grand             {
243*56b35d86SArmin Le Grand                 // not used or no fill
244*56b35d86SArmin Le Grand                 return false;
245*56b35d86SArmin Le Grand             }
246*56b35d86SArmin Le Grand 
247*56b35d86SArmin Le Grand             const drawinglayer::attribute::SdrFillAttribute& rSdrFillAttribute = getFillAttribute();
248*56b35d86SArmin Le Grand 
249*56b35d86SArmin Le Grand             if(!rSdrFillAttribute.getHatch().isDefault())
250*56b35d86SArmin Le Grand             {
251*56b35d86SArmin Le Grand                 // hatch is always top-left aligned, needs no full refreshes
252*56b35d86SArmin Le Grand                 return false;
253*56b35d86SArmin Le Grand             }
254*56b35d86SArmin Le Grand 
255*56b35d86SArmin Le Grand             if(!rSdrFillAttribute.getGradient().isDefault())
256*56b35d86SArmin Le Grand             {
257*56b35d86SArmin Le Grand                 // gradients always scale with the object
258*56b35d86SArmin Le Grand                 return true;
259*56b35d86SArmin Le Grand             }
260*56b35d86SArmin Le Grand 
261*56b35d86SArmin Le Grand             if(!rSdrFillAttribute.getFillGraphic().isDefault())
262*56b35d86SArmin Le Grand             {
263*56b35d86SArmin Le Grand                 // some graphic constellations may not need this, but since most do
264*56b35d86SArmin Le Grand                 // (stretch to fill, all but top-left aligned, ...) claim to do by default
265*56b35d86SArmin Le Grand                 return true;
266*56b35d86SArmin Le Grand             }
267*56b35d86SArmin Le Grand 
268*56b35d86SArmin Le Grand             // color fill
269*56b35d86SArmin Le Grand             return false;
270*56b35d86SArmin Le Grand         }
271*56b35d86SArmin Le Grand     } // end of namespace attribute
272*56b35d86SArmin Le Grand } // end of namespace drawinglayer
273*56b35d86SArmin Le Grand 
274*56b35d86SArmin Le Grand //////////////////////////////////////////////////////////////////////////////
275*56b35d86SArmin Le Grand // eof
276