xref: /AOO41X/main/sd/source/ui/dlg/vectdlg.cxx (revision 79aad27f7f29270c03e208e3d687e8e3850af11d)
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