xref: /trunk/main/svx/source/svdraw/impgrfll.cxx (revision cdf0e10c)
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_svx.hxx"
30 #include <svx/rectenum.hxx>
31 #include <vcl/svapp.hxx>
32 #include <vcl/outdev.hxx>
33 #include <vcl/bitmap.hxx>
34 
35 ///////////////////////////////////////////////////////////////////////////////
36 
37 void ImpCalcBmpFillSizes( Size&			   rStartOffset,
38                           Size&			   rBmpOutputSize,
39                           const Rectangle& rOutputRect,
40                           const MapMode&   rOutputMapMode,
41                           const Bitmap&    rFillBitmap,
42                           const Size&      rBmpSize,
43                           const Size&      rBmpPerCent,
44                           const Size&	   rBmpOffPerCent,
45                           sal_Bool             bBmpLogSize,
46                           sal_Bool             bBmpTile,
47                           sal_Bool             bBmpStretch,
48                           RECT_POINT       eBmpRectPoint )
49 {
50 	sal_Bool	bOriginalSize = sal_False, bScaleSize = sal_False;
51 
52 	// Falls keine Groessen gegeben sind ( z.B. alte Dokumente )
53 	// berechnen wir uns die Groesse selber aus der Bitmap
54 	// ==> altes Verhalten;
55 	// wenn nur eine Groesse gegeben ist, wird die andere
56 	// Groesse angepasst berechnet
57 	if( bBmpLogSize )
58 	{
59 		if( !rBmpSize.Width() && !rBmpSize.Height() )
60 			bOriginalSize = sal_True;
61 		else if( !rBmpSize.Width() || !rBmpSize.Height() )
62 			bScaleSize = sal_True;
63 	}
64 	else
65 	{
66 		if( !rBmpPerCent.Width() && !rBmpPerCent.Height() )
67 			bOriginalSize = sal_True;
68 		else if( !rBmpPerCent.Width() || !rBmpPerCent.Height() )
69 			bScaleSize = sal_True;
70 	}
71 
72 	// entweder Originalgroesse oder angepasste Groesse
73 	if( bOriginalSize || bScaleSize )
74 	{
75 		MapMode aBmpPrefMapMode( rFillBitmap.GetPrefMapMode() );
76 		Size    aBmpPrefSize( rFillBitmap.GetPrefSize() );
77 
78 		// Falls keine gesetzt ist, nehmen wir Pixel
79 		if( !aBmpPrefSize.Width() || !aBmpPrefSize.Height() )
80         {
81 			aBmpPrefSize = rFillBitmap.GetSizePixel();
82             aBmpPrefMapMode = MAP_PIXEL;
83         }
84 
85 		if( bOriginalSize )
86 		{
87 			if( MAP_PIXEL == aBmpPrefMapMode.GetMapUnit() )
88 				rBmpOutputSize = Application::GetDefaultDevice()->PixelToLogic( aBmpPrefSize, rOutputMapMode );
89 			else
90 				rBmpOutputSize = OutputDevice::LogicToLogic( aBmpPrefSize, aBmpPrefMapMode, rOutputMapMode );
91 		}
92 		else
93 		{
94 			if( bBmpLogSize )
95 			{
96 				rBmpOutputSize = rBmpSize;
97 
98 				if( !rBmpSize.Width() )
99 					rBmpOutputSize.Width() = basegfx::fround( (double) rBmpSize.Height() * aBmpPrefSize.Width() / aBmpPrefSize.Height() );
100 				else
101 					rBmpOutputSize.Height() = basegfx::fround( (double) rBmpSize.Width() * aBmpPrefSize.Height() / aBmpPrefSize.Width() );
102 			}
103 			else
104 			{
105 				if( !rBmpPerCent.Width() )
106 				{
107 					rBmpOutputSize.Height() = basegfx::fround( (double) rOutputRect.GetHeight() * rBmpPerCent.Height() / 100. );
108 					rBmpOutputSize.Width() = basegfx::fround( (double) rBmpOutputSize.Height() * aBmpPrefSize.Width() / aBmpPrefSize.Height() );
109 				}
110 				else
111 				{
112 					rBmpOutputSize.Width() = basegfx::fround( (double) rOutputRect.GetWidth() * rBmpPerCent.Width() / 100. );
113 					rBmpOutputSize.Height() = basegfx::fround( (double) rBmpOutputSize.Width() * aBmpPrefSize.Height() / aBmpPrefSize.Width() );
114 				}
115 			}
116 		}
117 	}
118 	// ansonsten koennen wir die Groesse leicht selber berechnen
119 	else
120 	{
121 		if( bBmpLogSize )
122 			rBmpOutputSize = rBmpSize;
123 		else
124 		{
125 			rBmpOutputSize.Width() = basegfx::fround( (double) rOutputRect.GetWidth() * rBmpPerCent.Width() / 100. );
126 			rBmpOutputSize.Height() = basegfx::fround( (double) rOutputRect.GetHeight() * rBmpPerCent.Height() / 100. );
127 		}
128 	}
129 
130 	// nur bei Kachelung die anderen Positionen berechnen
131 	if( bBmpTile )
132 	{
133         Point aStartPoint;
134 
135 		// Grundposition der ersten Kachel berechen;
136 		// Diese Position wird spaeter zur Berechnung der absoluten
137 		// Startposition links oberhalb des Objektes benutzt
138 		switch( eBmpRectPoint )
139 		{
140 			case( RP_MT ):
141 			{
142 				aStartPoint.X() = rOutputRect.Left() + ( ( rOutputRect.GetWidth() - rBmpOutputSize.Width() ) >> 1 );
143 				aStartPoint.Y() = rOutputRect.Top();
144 			}
145 			break;
146 
147 			case( RP_RT ):
148 			{
149 				aStartPoint.X() = rOutputRect.Right() - rBmpOutputSize.Width();
150 				aStartPoint.Y() = rOutputRect.Top();
151 			}
152 			break;
153 
154 			case( RP_LM ):
155 			{
156 				aStartPoint.X() = rOutputRect.Left();
157 				aStartPoint.Y() = rOutputRect.Top() + ( ( rOutputRect.GetHeight() - rBmpOutputSize.Height() ) >> 1  );
158 			}
159 			break;
160 
161 			case( RP_MM ):
162 			{
163 				aStartPoint.X() = rOutputRect.Left() + ( ( rOutputRect.GetWidth() - rBmpOutputSize.Width() ) >> 1 );
164 				aStartPoint.Y() = rOutputRect.Top() + ( ( rOutputRect.GetHeight() - rBmpOutputSize.Height() ) >> 1 );
165 			}
166 			break;
167 
168 			case( RP_RM ):
169 			{
170 				aStartPoint.X() = rOutputRect.Right() - rBmpOutputSize.Width();
171 				aStartPoint.Y() = rOutputRect.Top() + ( ( rOutputRect.GetHeight() - rBmpOutputSize.Height() ) >> 1 );
172 			}
173 			break;
174 
175 			case( RP_LB ):
176 			{
177 				aStartPoint.X() = rOutputRect.Left();
178 				aStartPoint.Y() = rOutputRect.Bottom() - rBmpOutputSize.Height();
179 			}
180 			break;
181 
182 			case( RP_MB ):
183 			{
184 				aStartPoint.X() = rOutputRect.Left() + ( ( rOutputRect.GetWidth() - rBmpOutputSize.Width() ) >> 1 );
185 				aStartPoint.Y() = rOutputRect.Bottom() - rBmpOutputSize.Height();
186 			}
187 			break;
188 
189 			case( RP_RB ):
190 			{
191 				aStartPoint.X() = rOutputRect.Right() - rBmpOutputSize.Width();
192 				aStartPoint.Y() = rOutputRect.Bottom() - rBmpOutputSize.Height();
193 			}
194 			break;
195 
196 			// default linke obere Ecke
197 			default:
198 				aStartPoint = rOutputRect.TopLeft();
199 			break;
200 		}
201 
202 		// X- oder Y-Positionsoffset beruecksichtigen
203 		if( rBmpOffPerCent.Width() )
204 			aStartPoint.X() += ( rBmpOutputSize.Width() * rBmpOffPerCent.Width() / 100 );
205 
206         if( rBmpOffPerCent.Height() )
207 			aStartPoint.Y() += ( rBmpOutputSize.Height() * rBmpOffPerCent.Height() / 100 );
208 
209 		// echten Startpunkt berechnen ( links oben )
210 		if( rBmpOutputSize.Width() && rBmpOutputSize.Height() )
211 		{
212 			const long nDiffX = aStartPoint.X() - rOutputRect.Left();
213 			const long nDiffY = aStartPoint.Y() - rOutputRect.Top();
214 
215 			if ( nDiffX )
216 			{
217 				long nCount = nDiffX / rBmpOutputSize.Width() + 1;
218 
219 				if ( rBmpOffPerCent.Height() && ( nCount & 1L ) )
220 					nCount++;
221 
222 				aStartPoint.X() -= ( nCount * rBmpOutputSize.Width() );
223 			}
224 
225 			if ( nDiffY )
226 			{
227 				long nCount = nDiffY / rBmpOutputSize.Height() + 1;
228 
229 				if ( rBmpOffPerCent.Width() && ( nCount & 1L ) )
230 					nCount++;
231 
232 				aStartPoint.Y() -= ( nCount * rBmpOutputSize.Height() );
233 			}
234 		}
235 
236         rStartOffset = Size( aStartPoint.X() - rOutputRect.Left(),
237                              aStartPoint.Y() - rOutputRect.Top() );
238 	}
239     else
240     {
241         if( bBmpStretch )
242         {
243             rStartOffset = Size(0, 0);
244             rBmpOutputSize = rOutputRect.GetSize();
245         }
246         else
247         {
248             rStartOffset = Size( ( rOutputRect.GetWidth() - rBmpOutputSize.Width() ) >> 1,
249                                  ( rOutputRect.GetHeight() - rBmpOutputSize.Height() ) >> 1 );
250         }
251     }
252 }
253 
254 //////////////////////////////////////////////////////////////////////////////
255 // eof
256