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_drawinglayer.hxx" 24 25 #include <drawinglayer/primitive2d/graphicprimitive2d.hxx> 26 #include <drawinglayer/primitive2d/cropprimitive2d.hxx> 27 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 28 #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 29 #include <drawinglayer/primitive2d/graphicprimitivehelper2d.hxx> 30 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 31 #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> 32 #include <basegfx/matrix/b2dhommatrixtools.hxx> 33 #include <vcl/svapp.hxx> 34 #include <vcl/outdev.hxx> 35 36 ////////////////////////////////////////////////////////////////////////////// 37 38 namespace drawinglayer 39 { 40 namespace primitive2d 41 { create2DDecomposition(const geometry::ViewInformation2D & rViewInformation) const42 Primitive2DSequence GraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& 43 #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 44 rViewInformation 45 #else 46 /*rViewInformation*/ 47 #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE 48 ) const 49 { 50 Primitive2DSequence aRetval; 51 52 if(255L == getGraphicAttr().GetTransparency()) 53 { 54 // content is invisible, done 55 return aRetval; 56 } 57 58 // do not apply mirroring from GraphicAttr to the Metafile by calling 59 // GetTransformedGraphic, this will try to mirror the Metafile using Scale() 60 // at the Metafile. This again calls Scale at the single MetaFile actions, 61 // but this implementation never worked. I reworked that implementations, 62 // but for security reasons i will try not to use it. 63 basegfx::B2DHomMatrix aTransform(getTransform()); 64 65 if(getGraphicAttr().IsMirrored()) 66 { 67 // content needs mirroring 68 const bool bHMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_HORZ); 69 const bool bVMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_VERT); 70 71 // mirror by applying negative scale to the unit primitive and 72 // applying the object transformation on it. 73 aTransform = basegfx::tools::createScaleB2DHomMatrix( 74 bHMirr ? -1.0 : 1.0, 75 bVMirr ? -1.0 : 1.0); 76 aTransform.translate( 77 bHMirr ? 1.0 : 0.0, 78 bVMirr ? 1.0 : 0.0); 79 aTransform = getTransform() * aTransform; 80 } 81 82 // Get transformed graphic. Suppress rotation and cropping, only filtering is needed 83 // here (and may be replaced later on). Cropping is handled below as mask primitive (if set). 84 // Also need to suppress mirroring, it is part of the transformation now (see above). 85 // Also move transparency handling to embedding to a UnifiedTransparencePrimitive2D; do 86 // that by remembering original transparency and applying that later if needed 87 GraphicAttr aSuppressGraphicAttr(getGraphicAttr()); 88 89 aSuppressGraphicAttr.SetCrop(0, 0, 0, 0); 90 aSuppressGraphicAttr.SetRotation(0); 91 aSuppressGraphicAttr.SetMirrorFlags(0); 92 aSuppressGraphicAttr.SetTransparency(0); 93 94 const GraphicObject& rGraphicObject = getGraphicObject(); 95 Graphic aTransformedGraphic(rGraphicObject.GetGraphic()); 96 const bool isBitmap(GRAPHIC_BITMAP == aTransformedGraphic.GetType() && !aTransformedGraphic.getSvgData().get()); 97 const bool isAdjusted(getGraphicAttr().IsAdjusted()); 98 const bool isDrawMode(GRAPHICDRAWMODE_STANDARD != getGraphicAttr().GetDrawMode()); 99 100 if(isBitmap && (isAdjusted || isDrawMode)) 101 { 102 // the pure primitive solution with the color modifiers works well, too, but when 103 // it is a bitmap graphic the old modification currently is faster; so use it here 104 // instead of creating all as in create2DColorModifierEmbeddingsAsNeeded (see below). 105 // Still, crop, rotation, mirroring and transparency is handled by primitives already 106 // (see above). 107 // This could even be done when vector graphic, but we explicitly want to have the 108 // pure primitive solution for this; this will allow vector graphics to stay vector 109 // geraphics, independent from the color filtering stuff. This will enhance e.g. 110 // SVG and print quality while reducing data size at the same time. 111 // The other way around the old modifications when only used on already bitmap objects 112 // will not loose any quality. 113 aTransformedGraphic = rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr); 114 115 // reset GraphicAttr after use to not apply double 116 aSuppressGraphicAttr = GraphicAttr(); 117 } 118 119 // create sub-content; helper takes care of correct handling of 120 // bitmap, svg or metafile content 121 aRetval = create2DDecompositionOfGraphic( 122 aTransformedGraphic, 123 aTransform); 124 125 if(!aRetval.getLength()) 126 { 127 // content is invisible, done 128 return aRetval; 129 } 130 131 if(isAdjusted || isDrawMode) 132 { 133 // embed to needed ModifiedColorPrimitive2D's if necessary. Do this for 134 // adjustments and draw mode specials 135 aRetval = create2DColorModifierEmbeddingsAsNeeded( 136 aRetval, 137 aSuppressGraphicAttr.GetDrawMode(), 138 basegfx::clamp(aSuppressGraphicAttr.GetLuminance() * 0.01, -1.0, 1.0), 139 basegfx::clamp(aSuppressGraphicAttr.GetContrast() * 0.01, -1.0, 1.0), 140 basegfx::clamp(aSuppressGraphicAttr.GetChannelR() * 0.01, -1.0, 1.0), 141 basegfx::clamp(aSuppressGraphicAttr.GetChannelG() * 0.01, -1.0, 1.0), 142 basegfx::clamp(aSuppressGraphicAttr.GetChannelB() * 0.01, -1.0, 1.0), 143 basegfx::clamp(aSuppressGraphicAttr.GetGamma(), 0.0, 10.0), 144 aSuppressGraphicAttr.IsInvert()); 145 146 if(!aRetval.getLength()) 147 { 148 // content is invisible, done 149 return aRetval; 150 } 151 } 152 153 if(getGraphicAttr().IsTransparent()) 154 { 155 // check for transparency 156 const double fTransparency(basegfx::clamp(getGraphicAttr().GetTransparency() * (1.0 / 255.0), 0.0, 1.0)); 157 158 if(!basegfx::fTools::equalZero(fTransparency)) 159 { 160 const Primitive2DReference aUnifiedTransparence( 161 new UnifiedTransparencePrimitive2D( 162 aRetval, 163 fTransparency)); 164 165 aRetval = Primitive2DSequence(&aUnifiedTransparence, 1); 166 } 167 } 168 169 if(getGraphicAttr().IsCropped()) 170 { 171 // check for cropping 172 // calculate scalings between real image size and logic object size. This 173 // is necessary since the crop values are relative to original bitmap size 174 const basegfx::B2DVector aObjectScale(aTransform * basegfx::B2DVector(1.0, 1.0)); 175 const basegfx::B2DVector aCropScaleFactor( 176 rGraphicObject.calculateCropScaling( 177 aObjectScale.getX(), 178 aObjectScale.getY(), 179 getGraphicAttr().GetLeftCrop(), 180 getGraphicAttr().GetTopCrop(), 181 getGraphicAttr().GetRightCrop(), 182 getGraphicAttr().GetBottomCrop())); 183 184 // embed content in cropPrimitive 185 Primitive2DReference xPrimitive( 186 new CropPrimitive2D( 187 aRetval, 188 aTransform, 189 getGraphicAttr().GetLeftCrop() * aCropScaleFactor.getX(), 190 getGraphicAttr().GetTopCrop() * aCropScaleFactor.getY(), 191 getGraphicAttr().GetRightCrop() * aCropScaleFactor.getX(), 192 getGraphicAttr().GetBottomCrop() * aCropScaleFactor.getY())); 193 194 aRetval = Primitive2DSequence(&xPrimitive, 1); 195 } 196 197 return aRetval; 198 } 199 GraphicPrimitive2D(const basegfx::B2DHomMatrix & rTransform,const GraphicObject & rGraphicObject,const GraphicAttr & rGraphicAttr)200 GraphicPrimitive2D::GraphicPrimitive2D( 201 const basegfx::B2DHomMatrix& rTransform, 202 const GraphicObject& rGraphicObject, 203 const GraphicAttr& rGraphicAttr) 204 : BufferedDecompositionPrimitive2D(), 205 maTransform(rTransform), 206 maGraphicObject(rGraphicObject), 207 maGraphicAttr(rGraphicAttr) 208 { 209 } 210 GraphicPrimitive2D(const basegfx::B2DHomMatrix & rTransform,const GraphicObject & rGraphicObject)211 GraphicPrimitive2D::GraphicPrimitive2D( 212 const basegfx::B2DHomMatrix& rTransform, 213 const GraphicObject& rGraphicObject) 214 : BufferedDecompositionPrimitive2D(), 215 maTransform(rTransform), 216 maGraphicObject(rGraphicObject), 217 maGraphicAttr() 218 { 219 } 220 operator ==(const BasePrimitive2D & rPrimitive) const221 bool GraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 222 { 223 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 224 { 225 const GraphicPrimitive2D& rCompare = (GraphicPrimitive2D&)rPrimitive; 226 227 return (getTransform() == rCompare.getTransform() 228 && getGraphicObject() == rCompare.getGraphicObject() 229 && getGraphicAttr() == rCompare.getGraphicAttr()); 230 } 231 232 return false; 233 } 234 getB2DRange(const geometry::ViewInformation2D &) const235 basegfx::B2DRange GraphicPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const 236 { 237 basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); 238 aRetval.transform(getTransform()); 239 return aRetval; 240 } 241 242 // provide unique ID 243 ImplPrimitrive2DIDBlock(GraphicPrimitive2D, PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D) 244 245 } // end of namespace primitive2d 246 } // end of namespace drawinglayer 247 248 ////////////////////////////////////////////////////////////////////////////// 249 // eof 250