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