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