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_sd.hxx" 26 27 #ifdef SD_DLLIMPLEMENTATION 28 #undef SD_DLLIMPLEMENTATION 29 #endif 30 #include <vcl/vclenum.hxx> 31 #include <vcl/wrkwin.hxx> 32 33 #include "strings.hrc" 34 #include "sdresid.hxx" 35 #include "DrawDocShell.hxx" 36 #include "sdmod.hxx" 37 #include "sdiocmpt.hxx" 38 #include "DrawDocShell.hxx" 39 #include "vectdlg.hxx" 40 #include "vectdlg.hrc" 41 #include <tools/config.hxx> 42 #include <vcl/bmpacc.hxx> 43 #include <vcl/msgbox.hxx> 44 #include <vcl/metaact.hxx> 45 46 // ----------- 47 // - Defines - 48 // ----------- 49 50 #define VECTORIZE_MAX_EXTENT 512 51 52 // ------------------ 53 // - SdVectorizeDlg - 54 // ------------------ 55 56 SdVectorizeDlg::SdVectorizeDlg( 57 Window* pParent, const Bitmap& rBmp, ::sd::DrawDocShell* pDocShell ) : 58 ModalDialog ( pParent, SdResId( DLG_VECTORIZE ) ), 59 mpDocSh ( pDocShell ), 60 aGrpSettings ( this, SdResId( GRP_SETTINGS ) ), 61 aFtLayers ( this, SdResId( FT_LAYERS ) ), 62 aNmLayers ( this, SdResId( NM_LAYERS ) ), 63 aFtReduce ( this, SdResId( FT_REDUCE ) ), 64 aMtReduce ( this, SdResId( MT_REDUCE ) ), 65 aFtFillHoles ( this, SdResId( FT_FILLHOLES ) ), 66 aMtFillHoles ( this, SdResId( MT_FILLHOLES ) ), 67 aCbFillHoles ( this, SdResId( CB_FILLHOLES ) ), 68 aFtOriginal ( this, SdResId( FT_ORIGINAL ) ), 69 aBmpWin ( this, SdResId( CTL_BMP ) ), 70 aFtVectorized ( this, SdResId( FT_VECTORIZED ) ), 71 aMtfWin ( this, SdResId( CTL_WMF ) ), 72 aGrpPrgs ( this, SdResId( GRP_PRGS ) ), 73 aPrgs ( this, SdResId( WND_PRGS ) ), 74 aBtnOK ( this, SdResId( BTN_OK ) ), 75 aBtnCancel ( this, SdResId( BTN_CANCEL ) ), 76 aBtnHelp ( this, SdResId( BTN_HELP ) ), 77 aBtnPreview ( this, SdResId( BTN_PREVIEW ) ), 78 aBmp ( rBmp ) 79 { 80 FreeResource(); 81 82 aBtnPreview.SetClickHdl( LINK( this, SdVectorizeDlg, ClickPreviewHdl ) ); 83 aBtnOK.SetClickHdl( LINK( this, SdVectorizeDlg, ClickOKHdl ) ); 84 aNmLayers.SetModifyHdl( LINK( this, SdVectorizeDlg, ModifyHdl ) ); 85 aMtReduce.SetModifyHdl( LINK( this, SdVectorizeDlg, ModifyHdl ) ); 86 aMtFillHoles.SetModifyHdl( LINK( this, SdVectorizeDlg, ModifyHdl ) ); 87 aCbFillHoles.SetToggleHdl( LINK( this, SdVectorizeDlg, ToggleHdl ) ); 88 89 // disable 3D border 90 aBmpWin.SetBorderStyle(WINDOW_BORDER_MONO); 91 aMtfWin.SetBorderStyle(WINDOW_BORDER_MONO); 92 93 LoadSettings(); 94 InitPreviewBmp(); 95 } 96 97 // ----------------------------------------------------------------------------- 98 99 SdVectorizeDlg::~SdVectorizeDlg() 100 { 101 } 102 103 // ----------------------------------------------------------------------------- 104 105 Rectangle SdVectorizeDlg::GetRect( const Size& rDispSize, const Size& rBmpSize ) const 106 { 107 Rectangle aRect; 108 109 if( rBmpSize.Width() && rBmpSize.Height() && rDispSize.Width() && rDispSize.Height() ) 110 { 111 Size aBmpSize( rBmpSize ); 112 const double fGrfWH = (double) aBmpSize.Width() / aBmpSize.Height(); 113 const double fWinWH = (double) rDispSize.Width() / rDispSize.Height(); 114 115 if( fGrfWH < fWinWH ) 116 { 117 aBmpSize.Width() = (long) ( rDispSize.Height() * fGrfWH ); 118 aBmpSize.Height()= rDispSize.Height(); 119 } 120 else 121 { 122 aBmpSize.Width() = rDispSize.Width(); 123 aBmpSize.Height()= (long) ( rDispSize.Width() / fGrfWH); 124 } 125 126 const Point aBmpPos( ( rDispSize.Width() - aBmpSize.Width() ) >> 1, 127 ( rDispSize.Height() - aBmpSize.Height() ) >> 1 ); 128 129 aRect = Rectangle( aBmpPos, aBmpSize ); 130 } 131 132 return aRect; 133 } 134 135 // ----------------------------------------------------------------------------- 136 137 void SdVectorizeDlg::InitPreviewBmp() 138 { 139 const Rectangle aRect( GetRect( aBmpWin.GetSizePixel(), aBmp.GetSizePixel() ) ); 140 141 aPreviewBmp = aBmp; 142 aPreviewBmp.Scale( aRect.GetSize() ); 143 aBmpWin.SetGraphic( aPreviewBmp ); 144 } 145 146 // ----------------------------------------------------------------------------- 147 148 Bitmap SdVectorizeDlg::GetPreparedBitmap( Bitmap& rBmp, Fraction& rScale ) 149 { 150 Bitmap aNew( rBmp ); 151 const Size aSizePix( aNew.GetSizePixel() ); 152 153 if( aSizePix.Width() > VECTORIZE_MAX_EXTENT || aSizePix.Height() > VECTORIZE_MAX_EXTENT ) 154 { 155 const Rectangle aRect( GetRect( Size( VECTORIZE_MAX_EXTENT, VECTORIZE_MAX_EXTENT ), aSizePix ) ); 156 rScale = Fraction( aSizePix.Width(), aRect.GetWidth() ); 157 aNew.Scale( aRect.GetSize() ); 158 } 159 else 160 rScale = Fraction( 1, 1 ); 161 162 aNew.ReduceColors( (sal_uInt16) aNmLayers.GetValue(), BMP_REDUCE_SIMPLE ); 163 164 return aNew; 165 } 166 167 // ----------------------------------------------------------------------------- 168 169 void SdVectorizeDlg::Calculate( Bitmap& rBmp, GDIMetaFile& rMtf ) 170 { 171 mpDocSh->SetWaitCursor( sal_True ); 172 aPrgs.SetValue( 0 ); 173 174 Fraction aScale; 175 Bitmap aTmp( GetPreparedBitmap( rBmp, aScale ) ); 176 177 if( !!aTmp ) 178 { 179 const Link aPrgsHdl( LINK( this, SdVectorizeDlg, ProgressHdl ) ); 180 aTmp.Vectorize( rMtf, (sal_uInt8) aMtReduce.GetValue(), BMP_VECTORIZE_OUTER | BMP_VECTORIZE_REDUCE_EDGES, &aPrgsHdl ); 181 182 if( aCbFillHoles.IsChecked() ) 183 { 184 GDIMetaFile aNewMtf; 185 BitmapReadAccess* pRAcc = aTmp.AcquireReadAccess(); 186 187 if( pRAcc ) 188 { 189 const long nWidth = pRAcc->Width(); 190 const long nHeight = pRAcc->Height(); 191 const long nTileX = static_cast<long>(aMtFillHoles.GetValue()); 192 const long nTileY = static_cast<long>(aMtFillHoles.GetValue()); 193 const long nCountX = nWidth / nTileX; 194 const long nCountY = nHeight / nTileY; 195 const long nRestX = nWidth % nTileX; 196 const long nRestY = nHeight % nTileY; 197 198 MapMode aMap( rMtf.GetPrefMapMode() ); 199 aNewMtf.SetPrefSize( rMtf.GetPrefSize() ); 200 aNewMtf.SetPrefMapMode( aMap ); 201 202 for( long nTY = 0; nTY < nCountY; nTY++ ) 203 { 204 const long nY = nTY * nTileY; 205 206 for( long nTX = 0; nTX < nCountX; nTX++ ) 207 AddTile( pRAcc, aNewMtf, nTX * nTileX, nTY * nTileY, nTileX, nTileY ); 208 209 if( nRestX ) 210 AddTile( pRAcc, aNewMtf, nCountX * nTileX, nY, nRestX, nTileY ); 211 } 212 213 if( nRestY ) 214 { 215 const long nY = nCountY * nTileY; 216 217 for( long nTX = 0; nTX < nCountX; nTX++ ) 218 AddTile( pRAcc, aNewMtf, nTX * nTileX, nY, nTileX, nRestY ); 219 220 if( nRestX ) 221 AddTile( pRAcc, aNewMtf, nCountX * nTileX, nCountY * nTileY, nRestX, nRestY ); 222 } 223 224 225 aTmp.ReleaseAccess( pRAcc ); 226 227 for( sal_uLong n = 0UL, nCount = rMtf.GetActionCount(); n < nCount; n++ ) 228 aNewMtf.AddAction( rMtf.GetAction( n )->Clone() ); 229 230 aMap.SetScaleX( aMap.GetScaleX() * aScale ); 231 aMap.SetScaleY( aMap.GetScaleY() * aScale ); 232 aNewMtf.SetPrefMapMode( aMap ); 233 rMtf = aNewMtf; 234 } 235 } 236 } 237 238 aPrgs.SetValue( 0 ); 239 mpDocSh->SetWaitCursor( sal_False ); 240 } 241 242 // ----------------------------------------------------------------------------- 243 244 void SdVectorizeDlg::AddTile( BitmapReadAccess* pRAcc, GDIMetaFile& rMtf, 245 long nPosX, long nPosY, long nWidth, long nHeight ) 246 { 247 sal_uLong nSumR = 0UL, nSumG = 0UL, nSumB = 0UL; 248 const long nRight = nPosX + nWidth - 1L; 249 const long nBottom = nPosY + nHeight - 1L; 250 const double fMult = 1.0 / ( nWidth * nHeight ); 251 252 for( long nY = nPosY; nY <= nBottom; nY++ ) 253 { 254 for( long nX = nPosX; nX <= nRight; nX++ ) 255 { 256 const BitmapColor aPixel( pRAcc->GetColor( nY, nX ) ); 257 258 nSumR += aPixel.GetRed(); 259 nSumG += aPixel.GetGreen(); 260 nSumB += aPixel.GetBlue(); 261 } 262 } 263 264 const Color aColor( (sal_uInt8) FRound( nSumR * fMult ), 265 (sal_uInt8) FRound( nSumG * fMult ), 266 (sal_uInt8) FRound( nSumB * fMult ) ); 267 268 Rectangle aRect( Point( nPosX, nPosY ), Size( nWidth + 1, nHeight + 1 ) ); 269 const Size& rMaxSize = rMtf.GetPrefSize(); 270 271 aRect = PixelToLogic( aRect, rMtf.GetPrefMapMode() ); 272 273 if( aRect.Right() > ( rMaxSize.Width() - 1L ) ) 274 aRect.Right() = rMaxSize.Width() - 1L; 275 276 if( aRect.Bottom() > ( rMaxSize.Height() - 1L ) ) 277 aRect.Bottom() = rMaxSize.Height() - 1L; 278 279 rMtf.AddAction( new MetaLineColorAction( aColor, sal_True ) ); 280 rMtf.AddAction( new MetaFillColorAction( aColor, sal_True ) ); 281 rMtf.AddAction( new MetaRectAction( aRect ) ); 282 } 283 284 // ----------------------------------------------------------------------------- 285 286 IMPL_LINK( SdVectorizeDlg, ProgressHdl, void*, pData ) 287 { 288 aPrgs.SetValue( (sal_uInt16)(sal_uLong) pData ); 289 return 0L; 290 } 291 292 // ----------------------------------------------------------------------------- 293 294 IMPL_LINK( SdVectorizeDlg, ClickPreviewHdl, PushButton*, EMPTYARG ) 295 { 296 Calculate( aBmp, aMtf ); 297 aMtfWin.SetGraphic( aMtf ); 298 aBtnPreview.Disable(); 299 300 return 0L; 301 } 302 303 // ----------------------------------------------------------------------------- 304 305 IMPL_LINK( SdVectorizeDlg, ClickOKHdl, OKButton*, EMPTYARG ) 306 { 307 if( aBtnPreview.IsEnabled() ) 308 Calculate( aBmp, aMtf ); 309 310 SaveSettings(); 311 EndDialog( RET_OK ); 312 313 return 0L; 314 } 315 316 // ----------------------------------------------------------------------------- 317 318 IMPL_LINK( SdVectorizeDlg, ToggleHdl, CheckBox*, pCb ) 319 { 320 if( pCb->IsChecked() ) 321 { 322 aFtFillHoles.Enable(); 323 aMtFillHoles.Enable(); 324 } 325 else 326 { 327 aFtFillHoles.Disable(); 328 aMtFillHoles.Disable(); 329 } 330 331 ModifyHdl( NULL ); 332 333 return 0L; 334 } 335 336 // ----------------------------------------------------------------------------- 337 338 IMPL_LINK( SdVectorizeDlg, ModifyHdl, void*, EMPTYARG ) 339 { 340 aBtnPreview.Enable(); 341 return 0L; 342 } 343 344 // ----------------------------------------------------------------------------- 345 346 void SdVectorizeDlg::LoadSettings() 347 { 348 SvStorageStreamRef xIStm( SD_MOD()->GetOptionStream( 349 UniString::CreateFromAscii( 350 RTL_CONSTASCII_STRINGPARAM( SD_OPTION_VECTORIZE ) ), 351 SD_OPTION_LOAD ) ); 352 sal_uInt16 nLayers; 353 sal_uInt16 nReduce; 354 sal_uInt16 nFillHoles; 355 sal_Bool bFillHoles; 356 357 if( xIStm.Is() ) 358 { 359 SdIOCompat aCompat( *xIStm, STREAM_READ ); 360 *xIStm >> nLayers >> nReduce >> nFillHoles >> bFillHoles; 361 } 362 else 363 { 364 nLayers = 8; 365 nReduce = 0; 366 nFillHoles = 32; 367 bFillHoles = sal_False; 368 } 369 370 aNmLayers.SetValue( nLayers ); 371 aMtReduce.SetValue( nReduce ); 372 aMtFillHoles.SetValue( nFillHoles ); 373 aCbFillHoles.Check( bFillHoles ); 374 375 ToggleHdl( &aCbFillHoles ); 376 } 377 378 // ----------------------------------------------------------------------------- 379 380 void SdVectorizeDlg::SaveSettings() const 381 { 382 SvStorageStreamRef xOStm( SD_MOD()->GetOptionStream( 383 UniString::CreateFromAscii( 384 RTL_CONSTASCII_STRINGPARAM( SD_OPTION_VECTORIZE ) ), 385 SD_OPTION_STORE ) ); 386 387 if( xOStm.Is() ) 388 { 389 SdIOCompat aCompat( *xOStm, STREAM_WRITE, 1 ); 390 *xOStm << (sal_uInt16) aNmLayers.GetValue() << (sal_uInt16) aMtReduce.GetValue(); 391 *xOStm << (sal_uInt16) aMtFillHoles.GetValue() << aCbFillHoles.IsChecked(); 392 } 393 } 394