1464702f4SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3464702f4SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4464702f4SAndrew Rist * or more contributor license agreements. See the NOTICE file 5464702f4SAndrew Rist * distributed with this work for additional information 6464702f4SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7464702f4SAndrew Rist * to you under the Apache License, Version 2.0 (the 8464702f4SAndrew Rist * "License"); you may not use this file except in compliance 9464702f4SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11464702f4SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13464702f4SAndrew Rist * Unless required by applicable law or agreed to in writing, 14464702f4SAndrew Rist * software distributed under the License is distributed on an 15464702f4SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16464702f4SAndrew Rist * KIND, either express or implied. See the License for the 17464702f4SAndrew Rist * specific language governing permissions and limitations 18464702f4SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20464702f4SAndrew Rist *************************************************************/ 21464702f4SAndrew Rist 22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 23cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx" 24cdf0e10cSrcweir 25cdf0e10cSrcweir #include <drawinglayer/primitive2d/graphicprimitive2d.hxx> 26ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/cropprimitive2d.hxx> 27cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 28ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 29035a2f44SArmin Le Grand #include <drawinglayer/primitive2d/graphicprimitivehelper2d.hxx> 30*49c58f9bSArmin Le Grand #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 31*49c58f9bSArmin Le Grand #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> 32035a2f44SArmin Le Grand #include <basegfx/matrix/b2dhommatrixtools.hxx> 33cdf0e10cSrcweir #include <vcl/svapp.hxx> 34035a2f44SArmin Le Grand #include <vcl/outdev.hxx> 35cdf0e10cSrcweir 36cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 37cdf0e10cSrcweir 38cdf0e10cSrcweir namespace drawinglayer 39cdf0e10cSrcweir { 40cdf0e10cSrcweir namespace primitive2d 41cdf0e10cSrcweir { create2DDecomposition(const geometry::ViewInformation2D & rViewInformation) const42cdf0e10cSrcweir Primitive2DSequence GraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& 43cdf0e10cSrcweir #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 44cdf0e10cSrcweir rViewInformation 45cdf0e10cSrcweir #else 46cdf0e10cSrcweir /*rViewInformation*/ 47cdf0e10cSrcweir #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 48cdf0e10cSrcweir ) const 49cdf0e10cSrcweir { 50cdf0e10cSrcweir Primitive2DSequence aRetval; 51cdf0e10cSrcweir 52*49c58f9bSArmin Le Grand if(255L == getGraphicAttr().GetTransparency()) 53cdf0e10cSrcweir { 54*49c58f9bSArmin Le Grand // content is invisible, done 55*49c58f9bSArmin Le Grand return aRetval; 56*49c58f9bSArmin Le Grand } 57*49c58f9bSArmin Le Grand 58cdf0e10cSrcweir // do not apply mirroring from GraphicAttr to the Metafile by calling 59cdf0e10cSrcweir // GetTransformedGraphic, this will try to mirror the Metafile using Scale() 60cdf0e10cSrcweir // at the Metafile. This again calls Scale at the single MetaFile actions, 61cdf0e10cSrcweir // but this implementation never worked. I reworked that implementations, 62cdf0e10cSrcweir // but for security reasons i will try not to use it. 63cdf0e10cSrcweir basegfx::B2DHomMatrix aTransform(getTransform()); 64cdf0e10cSrcweir 65cdf0e10cSrcweir if(getGraphicAttr().IsMirrored()) 66cdf0e10cSrcweir { 67cdf0e10cSrcweir // content needs mirroring 68cdf0e10cSrcweir const bool bHMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_HORZ); 69cdf0e10cSrcweir const bool bVMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_VERT); 70cdf0e10cSrcweir 71cdf0e10cSrcweir // mirror by applying negative scale to the unit primitive and 72cdf0e10cSrcweir // applying the object transformation on it. 73cdf0e10cSrcweir aTransform = basegfx::tools::createScaleB2DHomMatrix( 74cdf0e10cSrcweir bHMirr ? -1.0 : 1.0, 75cdf0e10cSrcweir bVMirr ? -1.0 : 1.0); 76cdf0e10cSrcweir aTransform.translate( 77cdf0e10cSrcweir bHMirr ? 1.0 : 0.0, 78cdf0e10cSrcweir bVMirr ? 1.0 : 0.0); 79cdf0e10cSrcweir aTransform = getTransform() * aTransform; 80cdf0e10cSrcweir } 81cdf0e10cSrcweir 82cdf0e10cSrcweir // Get transformed graphic. Suppress rotation and cropping, only filtering is needed 83cdf0e10cSrcweir // here (and may be replaced later on). Cropping is handled below as mask primitive (if set). 84cdf0e10cSrcweir // Also need to suppress mirroring, it is part of the transformation now (see above). 85*49c58f9bSArmin Le Grand // Also move transparency handling to embedding to a UnifiedTransparencePrimitive2D; do 86*49c58f9bSArmin Le Grand // that by remembering original transparency and applying that later if needed 87cdf0e10cSrcweir GraphicAttr aSuppressGraphicAttr(getGraphicAttr()); 88*49c58f9bSArmin Le Grand 89cdf0e10cSrcweir aSuppressGraphicAttr.SetCrop(0, 0, 0, 0); 90cdf0e10cSrcweir aSuppressGraphicAttr.SetRotation(0); 91cdf0e10cSrcweir aSuppressGraphicAttr.SetMirrorFlags(0); 92*49c58f9bSArmin Le Grand aSuppressGraphicAttr.SetTransparency(0); 93cdf0e10cSrcweir 94cdf0e10cSrcweir const GraphicObject& rGraphicObject = getGraphicObject(); 95*49c58f9bSArmin Le Grand Graphic aTransformedGraphic(rGraphicObject.GetGraphic()); 96*49c58f9bSArmin Le Grand const bool isBitmap(GRAPHIC_BITMAP == aTransformedGraphic.GetType() && !aTransformedGraphic.getSvgData().get()); 97*49c58f9bSArmin Le Grand const bool isAdjusted(getGraphicAttr().IsAdjusted()); 98*49c58f9bSArmin Le Grand const bool isDrawMode(GRAPHICDRAWMODE_STANDARD != getGraphicAttr().GetDrawMode()); 99cdf0e10cSrcweir 100*49c58f9bSArmin Le Grand if(isBitmap && (isAdjusted || isDrawMode)) 101*49c58f9bSArmin Le Grand { 102*49c58f9bSArmin Le Grand // the pure primitive solution with the color modifiers works well, too, but when 103*49c58f9bSArmin Le Grand // it is a bitmap graphic the old modification currently is faster; so use it here 104*49c58f9bSArmin Le Grand // instead of creating all as in create2DColorModifierEmbeddingsAsNeeded (see below). 105*49c58f9bSArmin Le Grand // Still, crop, rotation, mirroring and transparency is handled by primitives already 106*49c58f9bSArmin Le Grand // (see above). 107*49c58f9bSArmin Le Grand // This could even be done when vector graphic, but we explicitely want to have the 108*49c58f9bSArmin Le Grand // pure primitive solution for this; this will allow vector graphics to stay vector 109*49c58f9bSArmin Le Grand // geraphics, independent from the color filtering stuff. This will enhance e.g. 110*49c58f9bSArmin Le Grand // SVG and print quality while reducing data size at the same time. 111*49c58f9bSArmin Le Grand // The other way around the old modifications when only used on already bitmap objects 112*49c58f9bSArmin Le Grand // will not loose any quality. 113*49c58f9bSArmin Le Grand aTransformedGraphic = rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr); 114*49c58f9bSArmin Le Grand 115*49c58f9bSArmin Le Grand // reset GraphicAttr after use to not apply double 116*49c58f9bSArmin Le Grand aSuppressGraphicAttr = GraphicAttr(); 117*49c58f9bSArmin Le Grand } 118*49c58f9bSArmin Le Grand 119*49c58f9bSArmin Le Grand // create sub-content; helper takes care of correct handling of 120*49c58f9bSArmin Le Grand // bitmap, svg or metafile content 121035a2f44SArmin Le Grand aRetval = create2DDecompositionOfGraphic( 122035a2f44SArmin Le Grand aTransformedGraphic, 123035a2f44SArmin Le Grand aTransform); 124cdf0e10cSrcweir 125*49c58f9bSArmin Le Grand if(!aRetval.getLength()) 126cdf0e10cSrcweir { 127*49c58f9bSArmin Le Grand // content is invisible, done 128*49c58f9bSArmin Le Grand return aRetval; 129*49c58f9bSArmin Le Grand } 130*49c58f9bSArmin Le Grand 131*49c58f9bSArmin Le Grand if(isAdjusted || isDrawMode) 132*49c58f9bSArmin Le Grand { 133*49c58f9bSArmin Le Grand // embed to needed ModifiedColorPrimitive2D's if necessary. Do this for 134*49c58f9bSArmin Le Grand // adjustments and draw mode specials 135*49c58f9bSArmin Le Grand aRetval = create2DColorModifierEmbeddingsAsNeeded( 136*49c58f9bSArmin Le Grand aRetval, 137*49c58f9bSArmin Le Grand aSuppressGraphicAttr.GetDrawMode(), 138*49c58f9bSArmin Le Grand basegfx::clamp(aSuppressGraphicAttr.GetLuminance() * 0.01, -1.0, 1.0), 139*49c58f9bSArmin Le Grand basegfx::clamp(aSuppressGraphicAttr.GetContrast() * 0.01, -1.0, 1.0), 140*49c58f9bSArmin Le Grand basegfx::clamp(aSuppressGraphicAttr.GetChannelR() * 0.01, -1.0, 1.0), 141*49c58f9bSArmin Le Grand basegfx::clamp(aSuppressGraphicAttr.GetChannelG() * 0.01, -1.0, 1.0), 142*49c58f9bSArmin Le Grand basegfx::clamp(aSuppressGraphicAttr.GetChannelB() * 0.01, -1.0, 1.0), 143*49c58f9bSArmin Le Grand basegfx::clamp(aSuppressGraphicAttr.GetGamma(), 0.0, 10.0), 144*49c58f9bSArmin Le Grand aSuppressGraphicAttr.IsInvert()); 145*49c58f9bSArmin Le Grand 146*49c58f9bSArmin Le Grand if(!aRetval.getLength()) 147*49c58f9bSArmin Le Grand { 148*49c58f9bSArmin Le Grand // content is invisible, done 149*49c58f9bSArmin Le Grand return aRetval; 150*49c58f9bSArmin Le Grand } 151*49c58f9bSArmin Le Grand } 152*49c58f9bSArmin Le Grand 153*49c58f9bSArmin Le Grand if(getGraphicAttr().IsTransparent()) 154*49c58f9bSArmin Le Grand { 155*49c58f9bSArmin Le Grand // check for transparency 156*49c58f9bSArmin Le Grand const double fTransparency(basegfx::clamp(getGraphicAttr().GetTransparency() * (1.0 / 255.0), 0.0, 1.0)); 157*49c58f9bSArmin Le Grand 158*49c58f9bSArmin Le Grand if(!basegfx::fTools::equalZero(fTransparency)) 159*49c58f9bSArmin Le Grand { 160*49c58f9bSArmin Le Grand const Primitive2DReference aUnifiedTransparence( 161*49c58f9bSArmin Le Grand new UnifiedTransparencePrimitive2D( 162*49c58f9bSArmin Le Grand aRetval, 163*49c58f9bSArmin Le Grand fTransparency)); 164*49c58f9bSArmin Le Grand 165*49c58f9bSArmin Le Grand aRetval = Primitive2DSequence(&aUnifiedTransparence, 1); 166*49c58f9bSArmin Le Grand } 167*49c58f9bSArmin Le Grand } 168*49c58f9bSArmin Le Grand 169cdf0e10cSrcweir if(getGraphicAttr().IsCropped()) 170cdf0e10cSrcweir { 171*49c58f9bSArmin Le Grand // check for cropping 172cdf0e10cSrcweir // calculate scalings between real image size and logic object size. This 173cdf0e10cSrcweir // is necessary since the crop values are relative to original bitmap size 1742376739dSArmin Le Grand const basegfx::B2DVector aObjectScale(aTransform * basegfx::B2DVector(1.0, 1.0)); 1752376739dSArmin Le Grand const basegfx::B2DVector aCropScaleFactor( 1762376739dSArmin Le Grand rGraphicObject.calculateCropScaling( 1772376739dSArmin Le Grand aObjectScale.getX(), 1782376739dSArmin Le Grand aObjectScale.getY(), 1792376739dSArmin Le Grand getGraphicAttr().GetLeftCrop(), 1802376739dSArmin Le Grand getGraphicAttr().GetTopCrop(), 1812376739dSArmin Le Grand getGraphicAttr().GetRightCrop(), 1822376739dSArmin Le Grand getGraphicAttr().GetBottomCrop())); 183cdf0e10cSrcweir 184ddde725dSArmin Le Grand // embed content in cropPrimitive 185035a2f44SArmin Le Grand Primitive2DReference xPrimitive( 186035a2f44SArmin Le Grand new CropPrimitive2D( 187035a2f44SArmin Le Grand aRetval, 188ddde725dSArmin Le Grand aTransform, 1892376739dSArmin Le Grand getGraphicAttr().GetLeftCrop() * aCropScaleFactor.getX(), 1902376739dSArmin Le Grand getGraphicAttr().GetTopCrop() * aCropScaleFactor.getY(), 1912376739dSArmin Le Grand getGraphicAttr().GetRightCrop() * aCropScaleFactor.getX(), 1922376739dSArmin Le Grand getGraphicAttr().GetBottomCrop() * aCropScaleFactor.getY())); 193cdf0e10cSrcweir 194035a2f44SArmin Le Grand aRetval = Primitive2DSequence(&xPrimitive, 1); 195035a2f44SArmin Le Grand } 196cdf0e10cSrcweir 197cdf0e10cSrcweir return aRetval; 198cdf0e10cSrcweir } 199cdf0e10cSrcweir GraphicPrimitive2D(const basegfx::B2DHomMatrix & rTransform,const GraphicObject & rGraphicObject,const GraphicAttr & rGraphicAttr)200cdf0e10cSrcweir GraphicPrimitive2D::GraphicPrimitive2D( 201cdf0e10cSrcweir const basegfx::B2DHomMatrix& rTransform, 202cdf0e10cSrcweir const GraphicObject& rGraphicObject, 203cdf0e10cSrcweir const GraphicAttr& rGraphicAttr) 204cdf0e10cSrcweir : BufferedDecompositionPrimitive2D(), 205cdf0e10cSrcweir maTransform(rTransform), 206cdf0e10cSrcweir maGraphicObject(rGraphicObject), 207cdf0e10cSrcweir maGraphicAttr(rGraphicAttr) 208cdf0e10cSrcweir { 209cdf0e10cSrcweir } 210cdf0e10cSrcweir GraphicPrimitive2D(const basegfx::B2DHomMatrix & rTransform,const GraphicObject & rGraphicObject)211cdf0e10cSrcweir GraphicPrimitive2D::GraphicPrimitive2D( 212cdf0e10cSrcweir const basegfx::B2DHomMatrix& rTransform, 213cdf0e10cSrcweir const GraphicObject& rGraphicObject) 214cdf0e10cSrcweir : BufferedDecompositionPrimitive2D(), 215cdf0e10cSrcweir maTransform(rTransform), 216cdf0e10cSrcweir maGraphicObject(rGraphicObject), 217cdf0e10cSrcweir maGraphicAttr() 218cdf0e10cSrcweir { 219cdf0e10cSrcweir } 220cdf0e10cSrcweir operator ==(const BasePrimitive2D & rPrimitive) const221cdf0e10cSrcweir bool GraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 222cdf0e10cSrcweir { 223cdf0e10cSrcweir if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 224cdf0e10cSrcweir { 225cdf0e10cSrcweir const GraphicPrimitive2D& rCompare = (GraphicPrimitive2D&)rPrimitive; 226cdf0e10cSrcweir 227cdf0e10cSrcweir return (getTransform() == rCompare.getTransform() 228cdf0e10cSrcweir && getGraphicObject() == rCompare.getGraphicObject() 229cdf0e10cSrcweir && getGraphicAttr() == rCompare.getGraphicAttr()); 230cdf0e10cSrcweir } 231cdf0e10cSrcweir 232cdf0e10cSrcweir return false; 233cdf0e10cSrcweir } 234cdf0e10cSrcweir getB2DRange(const geometry::ViewInformation2D &) const235cdf0e10cSrcweir basegfx::B2DRange GraphicPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const 236cdf0e10cSrcweir { 237cdf0e10cSrcweir basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); 238cdf0e10cSrcweir aRetval.transform(getTransform()); 239cdf0e10cSrcweir return aRetval; 240cdf0e10cSrcweir } 241cdf0e10cSrcweir 242cdf0e10cSrcweir // provide unique ID 243cdf0e10cSrcweir ImplPrimitrive2DIDBlock(GraphicPrimitive2D, PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D) 244cdf0e10cSrcweir 245cdf0e10cSrcweir } // end of namespace primitive2d 246cdf0e10cSrcweir } // end of namespace drawinglayer 247cdf0e10cSrcweir 248cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 249cdf0e10cSrcweir // eof 250