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