xref: /trunk/main/drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_drawinglayer.hxx"
30 
31 #include <drawinglayer/primitive2d/wallpaperprimitive2d.hxx>
32 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
33 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
34 #include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
35 #include <basegfx/polygon/b2dpolygontools.hxx>
36 #include <basegfx/polygon/b2dpolygon.hxx>
37 #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
38 
39 //////////////////////////////////////////////////////////////////////////////
40 
41 namespace drawinglayer
42 {
43     namespace primitive2d
44     {
45         Primitive2DSequence WallpaperBitmapPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
46         {
47             Primitive2DSequence aRetval;
48 
49             if(!getLocalObjectRange().isEmpty() && !getBitmapEx().IsEmpty())
50             {
51                 // get bitmap PIXEL size
52                 const Size& rPixelSize = getBitmapEx().GetSizePixel();
53 
54                 if(rPixelSize.Width() > 0 && rPixelSize.Height() > 0)
55                 {
56                     if(WALLPAPER_SCALE == getWallpaperStyle())
57                     {
58                         // shortcut for scale; use simple BitmapPrimitive2D
59                         basegfx::B2DHomMatrix aObjectTransform;
60 
61                         aObjectTransform.set(0, 0, getLocalObjectRange().getWidth());
62                         aObjectTransform.set(1, 1, getLocalObjectRange().getHeight());
63                         aObjectTransform.set(0, 2, getLocalObjectRange().getMinX());
64                         aObjectTransform.set(1, 2, getLocalObjectRange().getMinY());
65 
66                         Primitive2DReference xReference(
67                             new BitmapPrimitive2D(
68                                 getBitmapEx(),
69                                 aObjectTransform));
70 
71                         aRetval = Primitive2DSequence(&xReference, 1);
72                     }
73                     else
74                     {
75                         // transform to logic size
76                         basegfx::B2DHomMatrix aInverseViewTransformation(getViewTransformation());
77                         aInverseViewTransformation.invert();
78                         basegfx::B2DVector aLogicSize(rPixelSize.Width(), rPixelSize.Height());
79                         aLogicSize = aInverseViewTransformation * aLogicSize;
80 
81                         // apply laout
82                         basegfx::B2DPoint aTargetTopLeft(getLocalObjectRange().getMinimum());
83                         bool bUseTargetTopLeft(true);
84                         bool bNeedsClipping(false);
85 
86                         switch(getWallpaperStyle())
87                         {
88                             default: //case WALLPAPER_TILE :, also WALLPAPER_NULL and WALLPAPER_APPLICATIONGRADIENT
89                             {
90                                 bUseTargetTopLeft = false;
91                                 break;
92                             }
93                             case WALLPAPER_SCALE :
94                             {
95                                 // handled by shortcut above
96                                 break;
97                             }
98                             case WALLPAPER_TOPLEFT :
99                             {
100                                 // nothing to do
101                                 break;
102                             }
103                             case WALLPAPER_TOP :
104                             {
105                                 const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter());
106                                 aTargetTopLeft.setX(aCenter.getX() - (aLogicSize.getX() * 0.5));
107                                 break;
108                             }
109                             case WALLPAPER_TOPRIGHT :
110                             {
111                                 aTargetTopLeft.setX(getLocalObjectRange().getMaxX() - aLogicSize.getX());
112                                 break;
113                             }
114                             case WALLPAPER_LEFT :
115                             {
116                                 const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter());
117                                 aTargetTopLeft.setY(aCenter.getY() - (aLogicSize.getY() * 0.5));
118                                 break;
119                             }
120                             case WALLPAPER_CENTER :
121                             {
122                                 const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter());
123                                 aTargetTopLeft = aCenter - (aLogicSize * 0.5);
124                                 break;
125                             }
126                             case WALLPAPER_RIGHT :
127                             {
128                                 const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter());
129                                 aTargetTopLeft.setX(getLocalObjectRange().getMaxX() - aLogicSize.getX());
130                                 aTargetTopLeft.setY(aCenter.getY() - (aLogicSize.getY() * 0.5));
131                                 break;
132                             }
133                             case WALLPAPER_BOTTOMLEFT :
134                             {
135                                 aTargetTopLeft.setY(getLocalObjectRange().getMaxY() - aLogicSize.getY());
136                                 break;
137                             }
138                             case WALLPAPER_BOTTOM :
139                             {
140                                 const basegfx::B2DPoint aCenter(getLocalObjectRange().getCenter());
141                                 aTargetTopLeft.setX(aCenter.getX() - (aLogicSize.getX() * 0.5));
142                                 aTargetTopLeft.setY(getLocalObjectRange().getMaxY() - aLogicSize.getY());
143                                 break;
144                             }
145                             case WALLPAPER_BOTTOMRIGHT :
146                             {
147                                 aTargetTopLeft = getLocalObjectRange().getMaximum() - aLogicSize;
148                                 break;
149                             }
150                         }
151 
152                         if(bUseTargetTopLeft)
153                         {
154                             // fill target range
155                             const basegfx::B2DRange aTargetRange(aTargetTopLeft, aTargetTopLeft + aLogicSize);
156 
157                             // create aligned, single BitmapPrimitive2D
158                             basegfx::B2DHomMatrix aObjectTransform;
159 
160                             aObjectTransform.set(0, 0, aTargetRange.getWidth());
161                             aObjectTransform.set(1, 1, aTargetRange.getHeight());
162                             aObjectTransform.set(0, 2, aTargetRange.getMinX());
163                             aObjectTransform.set(1, 2, aTargetRange.getMinY());
164 
165                             Primitive2DReference xReference(
166                                 new BitmapPrimitive2D(
167                                     getBitmapEx(),
168                                     aObjectTransform));
169                             aRetval = Primitive2DSequence(&xReference, 1);
170 
171                             // clip when not completely inside object range
172                             bNeedsClipping = !getLocalObjectRange().isInside(aTargetRange);
173                         }
174                         else
175                         {
176                             // WALLPAPER_TILE, WALLPAPER_NULL, WALLPAPER_APPLICATIONGRADIENT
177                             // convert to relative positions
178                             const basegfx::B2DVector aRelativeSize(
179                                 aLogicSize.getX() / (getLocalObjectRange().getWidth() ? getLocalObjectRange().getWidth() : 1.0),
180                                 aLogicSize.getY() / (getLocalObjectRange().getHeight() ? getLocalObjectRange().getHeight() : 1.0));
181                             basegfx::B2DPoint aRelativeTopLeft(0.0, 0.0);
182 
183                             if(WALLPAPER_TILE != getWallpaperStyle())
184                             {
185                                 aRelativeTopLeft.setX(0.5 - aRelativeSize.getX());
186                                 aRelativeTopLeft.setY(0.5 - aRelativeSize.getY());
187                             }
188 
189                             // prepare FillBitmapAttribute
190                             const attribute::FillBitmapAttribute aFillBitmapAttribute(
191                                 getBitmapEx(),
192                                 aRelativeTopLeft,
193                                 aRelativeSize,
194                                 true);
195 
196                             // create ObjectTransform
197                             basegfx::B2DHomMatrix aObjectTransform;
198 
199                             aObjectTransform.set(0, 0, getLocalObjectRange().getWidth());
200                             aObjectTransform.set(1, 1, getLocalObjectRange().getHeight());
201                             aObjectTransform.set(0, 2, getLocalObjectRange().getMinX());
202                             aObjectTransform.set(1, 2, getLocalObjectRange().getMinY());
203 
204                             // create FillBitmapPrimitive
205                             const drawinglayer::primitive2d::Primitive2DReference xFillBitmap(
206                                 new drawinglayer::primitive2d::FillBitmapPrimitive2D(
207                                     aObjectTransform,
208                                     aFillBitmapAttribute));
209                             aRetval = Primitive2DSequence(&xFillBitmap, 1);
210 
211                             // always embed tiled fill to clipping
212                             bNeedsClipping = true;
213                         }
214 
215                         if(bNeedsClipping)
216                         {
217                             // embed to clipping; this is necessary for tiled fills
218                             const basegfx::B2DPolyPolygon aPolyPolygon(
219                                 basegfx::tools::createPolygonFromRect(getLocalObjectRange()));
220                             const drawinglayer::primitive2d::Primitive2DReference xClippedFill(
221                                 new drawinglayer::primitive2d::MaskPrimitive2D(
222                                     aPolyPolygon,
223                                     aRetval));
224                             aRetval = Primitive2DSequence(&xClippedFill, 1);
225                         }
226                     }
227                 }
228             }
229 
230             return aRetval;
231         }
232 
233         WallpaperBitmapPrimitive2D::WallpaperBitmapPrimitive2D(
234             const basegfx::B2DRange& rObjectRange,
235             const BitmapEx& rBitmapEx,
236             WallpaperStyle eWallpaperStyle)
237         :   ViewTransformationDependentPrimitive2D(),
238             maObjectRange(rObjectRange),
239             maBitmapEx(rBitmapEx),
240             meWallpaperStyle(eWallpaperStyle)
241         {
242         }
243 
244         bool WallpaperBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
245         {
246             if(ViewTransformationDependentPrimitive2D::operator==(rPrimitive))
247             {
248                 const WallpaperBitmapPrimitive2D& rCompare = (WallpaperBitmapPrimitive2D&)rPrimitive;
249 
250                 return (getLocalObjectRange() == rCompare.getLocalObjectRange()
251                     && getBitmapEx() == rCompare.getBitmapEx()
252                     && getWallpaperStyle() == rCompare.getWallpaperStyle());
253             }
254 
255             return false;
256         }
257 
258         basegfx::B2DRange WallpaperBitmapPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
259         {
260             return getLocalObjectRange();
261         }
262 
263         // provide unique ID
264         ImplPrimitrive2DIDBlock(WallpaperBitmapPrimitive2D, PRIMITIVE2D_ID_WALLPAPERBITMAPPRIMITIVE2D)
265     } // end of namespace primitive2d
266 } // end of namespace drawinglayer
267 
268 //////////////////////////////////////////////////////////////////////////////
269 // eof
270