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