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 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_drawinglayer.hxx"
26 
27 #include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
28 #include <drawinglayer/primitive2d/cropprimitive2d.hxx>
29 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
30 #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
31 #include <drawinglayer/primitive2d/graphicprimitivehelper2d.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 	{
42 		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                 // do not apply mirroring from GraphicAttr to the Metafile by calling
55                 // GetTransformedGraphic, this will try to mirror the Metafile using Scale()
56                 // at the Metafile. This again calls Scale at the single MetaFile actions,
57                 // but this implementation never worked. I reworked that implementations,
58                 // but for security reasons i will try not to use it.
59                 basegfx::B2DHomMatrix aTransform(getTransform());
60 
61                 if(getGraphicAttr().IsMirrored())
62                 {
63                     // content needs mirroring
64                     const bool bHMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_HORZ);
65                     const bool bVMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_VERT);
66 
67                     // mirror by applying negative scale to the unit primitive and
68                     // applying the object transformation on it.
69                     aTransform = basegfx::tools::createScaleB2DHomMatrix(
70                         bHMirr ? -1.0 : 1.0,
71                         bVMirr ? -1.0 : 1.0);
72                     aTransform.translate(
73                         bHMirr ? 1.0 : 0.0,
74                         bVMirr ? 1.0 : 0.0);
75                     aTransform = getTransform() * aTransform;
76                 }
77 
78 		        // Get transformed graphic. Suppress rotation and cropping, only filtering is needed
79 		        // here (and may be replaced later on). Cropping is handled below as mask primitive (if set).
80                 // Also need to suppress mirroring, it is part of the transformation now (see above).
81 		        GraphicAttr aSuppressGraphicAttr(getGraphicAttr());
82 		        aSuppressGraphicAttr.SetCrop(0, 0, 0, 0);
83 		        aSuppressGraphicAttr.SetRotation(0);
84 		        aSuppressGraphicAttr.SetMirrorFlags(0);
85 
86                 const GraphicObject& rGraphicObject = getGraphicObject();
87                 const Graphic aTransformedGraphic(rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr));
88 
89                 aRetval = create2DDecompositionOfGraphic(
90                     aTransformedGraphic,
91                     aTransform);
92 
93                 if(aRetval.getLength())
94                 {
95                     // check for cropping
96                     if(getGraphicAttr().IsCropped())
97                     {
98                         // calculate scalings between real image size and logic object size. This
99                         // is necessary since the crop values are relative to original bitmap size
100                         double fFactorX(1.0);
101                         double fFactorY(1.0);
102 
103                         {
104                             const MapMode aMapMode100thmm(MAP_100TH_MM);
105                             Size aBitmapSize(rGraphicObject.GetPrefSize());
106 
107                             // #i95968# better support PrefMapMode; special for MAP_PIXEL was missing
108                             if(MAP_PIXEL == rGraphicObject.GetPrefMapMode().GetMapUnit())
109                             {
110                                 aBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aBitmapSize, aMapMode100thmm);
111                             }
112                             else
113                             {
114                                 aBitmapSize = Application::GetDefaultDevice()->LogicToLogic(aBitmapSize, rGraphicObject.GetPrefMapMode(), aMapMode100thmm);
115                             }
116 
117                             const double fDivX(aBitmapSize.Width() - getGraphicAttr().GetLeftCrop() - getGraphicAttr().GetRightCrop());
118                             const double fDivY(aBitmapSize.Height() - getGraphicAttr().GetTopCrop() - getGraphicAttr().GetBottomCrop());
119                             const basegfx::B2DVector aScale(aTransform * basegfx::B2DVector(1.0, 1.0));
120 
121                             if(!basegfx::fTools::equalZero(fDivX))
122                             {
123                                 fFactorX = fabs(aScale.getX()) / fDivX;
124                             }
125 
126                             if(!basegfx::fTools::equalZero(fDivY))
127                             {
128                                 fFactorY = fabs(aScale.getY()) / fDivY;
129                             }
130                         }
131 
132                         // embed content in cropPrimitive
133                         Primitive2DReference xPrimitive(
134                             new CropPrimitive2D(
135                                 aRetval,
136                                 aTransform,
137                                 getGraphicAttr().GetLeftCrop() * fFactorX,
138                                 getGraphicAttr().GetTopCrop() * fFactorY,
139                                 getGraphicAttr().GetRightCrop() * fFactorX,
140                                 getGraphicAttr().GetBottomCrop() * fFactorY));
141 
142                         aRetval = Primitive2DSequence(&xPrimitive, 1);
143                     }
144                 }
145 			}
146 
147 			return aRetval;
148 		}
149 
150 		GraphicPrimitive2D::GraphicPrimitive2D(
151 			const basegfx::B2DHomMatrix& rTransform,
152 			const GraphicObject& rGraphicObject,
153 			const GraphicAttr& rGraphicAttr)
154 		:	BufferedDecompositionPrimitive2D(),
155 			maTransform(rTransform),
156 			maGraphicObject(rGraphicObject),
157 			maGraphicAttr(rGraphicAttr)
158 		{
159 		}
160 
161 		GraphicPrimitive2D::GraphicPrimitive2D(
162 			const basegfx::B2DHomMatrix& rTransform,
163 			const GraphicObject& rGraphicObject)
164 		:	BufferedDecompositionPrimitive2D(),
165 			maTransform(rTransform),
166 			maGraphicObject(rGraphicObject),
167 			maGraphicAttr()
168 		{
169 		}
170 
171 		bool GraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
172 		{
173 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
174 			{
175 				const GraphicPrimitive2D& rCompare = (GraphicPrimitive2D&)rPrimitive;
176 
177 				return (getTransform() == rCompare.getTransform()
178 					&& getGraphicObject() == rCompare.getGraphicObject()
179 					&& getGraphicAttr() == rCompare.getGraphicAttr());
180 			}
181 
182 			return false;
183 		}
184 
185 		basegfx::B2DRange GraphicPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
186 		{
187 			basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
188 			aRetval.transform(getTransform());
189 			return aRetval;
190 		}
191 
192 		// provide unique ID
193 		ImplPrimitrive2DIDBlock(GraphicPrimitive2D, PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D)
194 
195 	} // end of namespace primitive2d
196 } // end of namespace drawinglayer
197 
198 //////////////////////////////////////////////////////////////////////////////
199 // eof
200