xref: /trunk/main/sd/source/ui/dlg/vectdlg.cxx (revision 79aad27f)
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 
SdVectorizeDlg(Window * pParent,const Bitmap & rBmp,::sd::DrawDocShell * pDocShell)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 
~SdVectorizeDlg()99 SdVectorizeDlg::~SdVectorizeDlg()
100 {
101 }
102 
103 // -----------------------------------------------------------------------------
104 
GetRect(const Size & rDispSize,const Size & rBmpSize) const105 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 
InitPreviewBmp()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 
GetPreparedBitmap(Bitmap & rBmp,Fraction & rScale)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 
Calculate(Bitmap & rBmp,GDIMetaFile & rMtf)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 
AddTile(BitmapReadAccess * pRAcc,GDIMetaFile & rMtf,long nPosX,long nPosY,long nWidth,long nHeight)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 
IMPL_LINK(SdVectorizeDlg,ProgressHdl,void *,pData)286 IMPL_LINK( SdVectorizeDlg, ProgressHdl, void*, pData )
287 {
288 	aPrgs.SetValue( (sal_uInt16)(sal_uLong) pData );
289 	return 0L;
290 }
291 
292 // -----------------------------------------------------------------------------
293 
IMPL_LINK(SdVectorizeDlg,ClickPreviewHdl,PushButton *,EMPTYARG)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 
IMPL_LINK(SdVectorizeDlg,ClickOKHdl,OKButton *,EMPTYARG)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 
IMPL_LINK(SdVectorizeDlg,ToggleHdl,CheckBox *,pCb)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 
IMPL_LINK(SdVectorizeDlg,ModifyHdl,void *,EMPTYARG)338 IMPL_LINK( SdVectorizeDlg, ModifyHdl, void*, EMPTYARG )
339 {
340 	aBtnPreview.Enable();
341 	return 0L;
342 }
343 
344 // -----------------------------------------------------------------------------
345 
LoadSettings()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 
SaveSettings() const380 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