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/wallpaperprimitive2d.hxx>
28 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
29 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
30 #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
31 #include <basegfx/polygon/b2dpolygontools.hxx>
32 #include <basegfx/polygon/b2dpolygon.hxx>
33 #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
34 #include <basegfx/matrix/b2dhommatrixtools.hxx>
35 #include <vcl/graph.hxx>
36 
37 //////////////////////////////////////////////////////////////////////////////
38 
39 namespace drawinglayer
40 {
41 	namespace primitive2d
42 	{
create2DDecomposition(const geometry::ViewInformation2D &) const43 		Primitive2DSequence WallpaperBitmapPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
44 		{
45 			Primitive2DSequence aRetval;
46 
47 			if(!getLocalObjectRange().isEmpty() && !getBitmapEx().IsEmpty())
48 			{
49 				// get bitmap PIXEL size
50 			    const Size& rPixelSize = getBitmapEx().GetSizePixel();
51 
52 				if(rPixelSize.Width() > 0 && rPixelSize.Height() > 0)
53 				{
54 					if(WALLPAPER_SCALE == getWallpaperStyle())
55 					{
56 						// shortcut for scale; use simple BitmapPrimitive2D
57 						basegfx::B2DHomMatrix aObjectTransform;
58 
59 						aObjectTransform.set(0, 0, getLocalObjectRange().getWidth());
60 						aObjectTransform.set(1, 1, getLocalObjectRange().getHeight());
61 						aObjectTransform.set(0, 2, getLocalObjectRange().getMinX());
62 						aObjectTransform.set(1, 2, getLocalObjectRange().getMinY());
63 
64 						Primitive2DReference xReference(
65 							new BitmapPrimitive2D(
66 								getBitmapEx(),
67 								aObjectTransform));
68 
69 						aRetval = Primitive2DSequence(&xReference, 1);
70 					}
71 					else
72 					{
73 						// transform to logic size
74 						basegfx::B2DHomMatrix aInverseViewTransformation(getViewTransformation());
75 						aInverseViewTransformation.invert();
76 						basegfx::B2DVector aLogicSize(rPixelSize.Width(), rPixelSize.Height());
77 						aLogicSize = aInverseViewTransformation * aLogicSize;
78 
79 						// apply laout
80 						basegfx::B2DPoint aTargetTopLeft(getLocalObjectRange().getMinimum());
81 						bool bUseTargetTopLeft(true);
82 						bool bNeedsClipping(false);
83 
84 						switch(getWallpaperStyle())
85 						{
86 							default: //case WALLPAPER_TILE :, also WALLPAPER_NULL and WALLPAPER_APPLICATIONGRADIENT
87 							{
88 								bUseTargetTopLeft = false;
89 								break;
90 							}
91 							case WALLPAPER_SCALE :
92 							{
93 								// handled by shortcut above
94 								break;
95 							}
96 							case WALLPAPER_TOPLEFT :
97 							{
98 								// nothing to do
99 								break;
100 							}
101 							case WALLPAPER_TOP :
102 							{
103 								const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter());
104 								aTargetTopLeft.setX(aCenter.getX() - (aLogicSize.getX() * 0.5));
105 								break;
106 							}
107 							case WALLPAPER_TOPRIGHT :
108 							{
109 								aTargetTopLeft.setX(getLocalObjectRange().getMaxX() - aLogicSize.getX());
110 								break;
111 							}
112 							case WALLPAPER_LEFT :
113 							{
114 								const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter());
115 								aTargetTopLeft.setY(aCenter.getY() - (aLogicSize.getY() * 0.5));
116 								break;
117 							}
118 							case WALLPAPER_CENTER :
119 							{
120 								const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter());
121 								aTargetTopLeft = aCenter - (aLogicSize * 0.5);
122 								break;
123 							}
124 							case WALLPAPER_RIGHT :
125 							{
126 								const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter());
127 								aTargetTopLeft.setX(getLocalObjectRange().getMaxX() - aLogicSize.getX());
128 								aTargetTopLeft.setY(aCenter.getY() - (aLogicSize.getY() * 0.5));
129 								break;
130 							}
131 							case WALLPAPER_BOTTOMLEFT :
132 							{
133 								aTargetTopLeft.setY(getLocalObjectRange().getMaxY() - aLogicSize.getY());
134 								break;
135 							}
136 							case WALLPAPER_BOTTOM :
137 							{
138 								const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter());
139 								aTargetTopLeft.setX(aCenter.getX() - (aLogicSize.getX() * 0.5));
140 								aTargetTopLeft.setY(getLocalObjectRange().getMaxY() - aLogicSize.getY());
141 								break;
142 							}
143 							case WALLPAPER_BOTTOMRIGHT :
144 							{
145 								aTargetTopLeft = getLocalObjectRange().getMaximum() - aLogicSize;
146 								break;
147 							}
148 						}
149 
150 						if(bUseTargetTopLeft)
151 						{
152 							// fill target range
153 							const basegfx::B2DRange aTargetRange(aTargetTopLeft, aTargetTopLeft + aLogicSize);
154 
155 							// create aligned, single BitmapPrimitive2D
156 							basegfx::B2DHomMatrix aObjectTransform;
157 
158 							aObjectTransform.set(0, 0, aTargetRange.getWidth());
159 							aObjectTransform.set(1, 1, aTargetRange.getHeight());
160 							aObjectTransform.set(0, 2, aTargetRange.getMinX());
161 							aObjectTransform.set(1, 2, aTargetRange.getMinY());
162 
163 							Primitive2DReference xReference(
164 								new BitmapPrimitive2D(
165 									getBitmapEx(),
166 									aObjectTransform));
167 							aRetval = Primitive2DSequence(&xReference, 1);
168 
169 							// clip when not completely inside object range
170 							bNeedsClipping = !getLocalObjectRange().isInside(aTargetRange);
171 						}
172 						else
173 						{
174 							// WALLPAPER_TILE, WALLPAPER_NULL, WALLPAPER_APPLICATIONGRADIENT
175 							// convert to relative positions
176 							const basegfx::B2DVector aRelativeSize(
177 								aLogicSize.getX() / (getLocalObjectRange().getWidth() ? getLocalObjectRange().getWidth() : 1.0),
178 								aLogicSize.getY() / (getLocalObjectRange().getHeight() ? getLocalObjectRange().getHeight() : 1.0));
179 							basegfx::B2DPoint aRelativeTopLeft(0.0, 0.0);
180 
181 							if(WALLPAPER_TILE != getWallpaperStyle())
182 							{
183 								aRelativeTopLeft.setX(0.5 - aRelativeSize.getX());
184 								aRelativeTopLeft.setY(0.5 - aRelativeSize.getY());
185 							}
186 
187 							// prepare FillGraphicAttribute
188 							const attribute::FillGraphicAttribute aFillGraphicAttribute(
189 								Graphic(getBitmapEx()),
190 								basegfx::B2DRange(aRelativeTopLeft, aRelativeTopLeft+ aRelativeSize),
191 								true);
192 
193 							// create ObjectTransform
194 							const basegfx::B2DHomMatrix aObjectTransform(
195                                 basegfx::tools::createScaleTranslateB2DHomMatrix(
196                                     getLocalObjectRange().getRange(),
197                                     getLocalObjectRange().getMinimum()));
198 
199 							// create FillBitmapPrimitive
200 							const drawinglayer::primitive2d::Primitive2DReference xFillBitmap(
201 								new drawinglayer::primitive2d::FillGraphicPrimitive2D(
202 									aObjectTransform,
203 									aFillGraphicAttribute));
204 							aRetval = Primitive2DSequence(&xFillBitmap, 1);
205 
206 							// always embed tiled fill to clipping
207 							bNeedsClipping = true;
208 						}
209 
210 						if(bNeedsClipping)
211 						{
212 							// embed to clipping; this is necessary for tiled fills
213 							const basegfx::B2DPolyPolygon aPolyPolygon(
214                                 basegfx::tools::createPolygonFromRect(getLocalObjectRange()));
215 							const drawinglayer::primitive2d::Primitive2DReference xClippedFill(
216 								new drawinglayer::primitive2d::MaskPrimitive2D(
217 									aPolyPolygon,
218 									aRetval));
219 							aRetval = Primitive2DSequence(&xClippedFill, 1);
220 						}
221 					}
222 				}
223 			}
224 
225 			return aRetval;
226 		}
227 
WallpaperBitmapPrimitive2D(const basegfx::B2DRange & rObjectRange,const BitmapEx & rBitmapEx,WallpaperStyle eWallpaperStyle)228 		WallpaperBitmapPrimitive2D::WallpaperBitmapPrimitive2D(
229 			const basegfx::B2DRange& rObjectRange,
230 			const BitmapEx& rBitmapEx,
231 			WallpaperStyle eWallpaperStyle)
232 		:	ViewTransformationDependentPrimitive2D(),
233 			maObjectRange(rObjectRange),
234 			maBitmapEx(rBitmapEx),
235 			meWallpaperStyle(eWallpaperStyle)
236 		{
237 		}
238 
operator ==(const BasePrimitive2D & rPrimitive) const239 		bool WallpaperBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
240 		{
241 			if(ViewTransformationDependentPrimitive2D::operator==(rPrimitive))
242 			{
243 				const WallpaperBitmapPrimitive2D& rCompare = (WallpaperBitmapPrimitive2D&)rPrimitive;
244 
245 				return (getLocalObjectRange() == rCompare.getLocalObjectRange()
246 					&& getBitmapEx() == rCompare.getBitmapEx()
247 					&& getWallpaperStyle() == rCompare.getWallpaperStyle());
248 			}
249 
250 			return false;
251 		}
252 
getB2DRange(const geometry::ViewInformation2D &) const253 		basegfx::B2DRange WallpaperBitmapPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
254 		{
255 			return getLocalObjectRange();
256 		}
257 
258 		// provide unique ID
259 		ImplPrimitrive2DIDBlock(WallpaperBitmapPrimitive2D, PRIMITIVE2D_ID_WALLPAPERBITMAPPRIMITIVE2D)
260 	} // end of namespace primitive2d
261 } // end of namespace drawinglayer
262 
263 //////////////////////////////////////////////////////////////////////////////
264 // eof
265