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