1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/vclenum.hxx>
21 #include <vcl/wrkwin.hxx>
23 #include "strings.hrc"
24 #include "sdresid.hxx"
25 #include "DrawDocShell.hxx"
27 #include "sdiocmpt.hxx"
28 #include "vectdlg.hxx"
29 #include "vectdlg.hrc"
30 #include <vcl/bmpacc.hxx>
31 #include <vcl/msgbox.hxx>
32 #include <vcl/metaact.hxx>
34 #define VECTORIZE_MAX_EXTENT 512
36 SdVectorizeDlg::SdVectorizeDlg(
37 Window
* pParent
, const Bitmap
& rBmp
, ::sd::DrawDocShell
* pDocShell
) :
38 ModalDialog ( pParent
, SdResId( DLG_VECTORIZE
) ),
39 mpDocSh ( pDocShell
),
40 aGrpSettings ( this, SdResId( GRP_SETTINGS
) ),
41 aFtLayers ( this, SdResId( FT_LAYERS
) ),
42 aNmLayers ( this, SdResId( NM_LAYERS
) ),
43 aFtReduce ( this, SdResId( FT_REDUCE
) ),
44 aMtReduce ( this, SdResId( MT_REDUCE
) ),
45 aFtFillHoles ( this, SdResId( FT_FILLHOLES
) ),
46 aMtFillHoles ( this, SdResId( MT_FILLHOLES
) ),
47 aCbFillHoles ( this, SdResId( CB_FILLHOLES
) ),
48 aFtOriginal ( this, SdResId( FT_ORIGINAL
) ),
49 aBmpWin ( this, SdResId( CTL_BMP
) ),
50 aFtVectorized ( this, SdResId( FT_VECTORIZED
) ),
51 aMtfWin ( this, SdResId( CTL_WMF
) ),
52 aGrpPrgs ( this, SdResId( GRP_PRGS
) ),
53 aPrgs ( this, SdResId( WND_PRGS
) ),
54 aBtnOK ( this, SdResId( BTN_OK
) ),
55 aBtnCancel ( this, SdResId( BTN_CANCEL
) ),
56 aBtnHelp ( this, SdResId( BTN_HELP
) ),
57 aBtnPreview ( this, SdResId( BTN_PREVIEW
) ),
62 aBtnPreview
.SetClickHdl( LINK( this, SdVectorizeDlg
, ClickPreviewHdl
) );
63 aBtnOK
.SetClickHdl( LINK( this, SdVectorizeDlg
, ClickOKHdl
) );
64 aNmLayers
.SetModifyHdl( LINK( this, SdVectorizeDlg
, ModifyHdl
) );
65 aMtReduce
.SetModifyHdl( LINK( this, SdVectorizeDlg
, ModifyHdl
) );
66 aMtFillHoles
.SetModifyHdl( LINK( this, SdVectorizeDlg
, ModifyHdl
) );
67 aCbFillHoles
.SetToggleHdl( LINK( this, SdVectorizeDlg
, ToggleHdl
) );
70 aBmpWin
.SetBorderStyle(WINDOW_BORDER_MONO
);
71 aMtfWin
.SetBorderStyle(WINDOW_BORDER_MONO
);
77 SdVectorizeDlg::~SdVectorizeDlg()
81 Rectangle
SdVectorizeDlg::GetRect( const Size
& rDispSize
, const Size
& rBmpSize
) const
85 if( rBmpSize
.Width() && rBmpSize
.Height() && rDispSize
.Width() && rDispSize
.Height() )
87 Size
aBmpSize( rBmpSize
);
88 const double fGrfWH
= (double) aBmpSize
.Width() / aBmpSize
.Height();
89 const double fWinWH
= (double) rDispSize
.Width() / rDispSize
.Height();
93 aBmpSize
.Width() = (long) ( rDispSize
.Height() * fGrfWH
);
94 aBmpSize
.Height()= rDispSize
.Height();
98 aBmpSize
.Width() = rDispSize
.Width();
99 aBmpSize
.Height()= (long) ( rDispSize
.Width() / fGrfWH
);
102 const Point
aBmpPos( ( rDispSize
.Width() - aBmpSize
.Width() ) >> 1,
103 ( rDispSize
.Height() - aBmpSize
.Height() ) >> 1 );
105 aRect
= Rectangle( aBmpPos
, aBmpSize
);
111 void SdVectorizeDlg::InitPreviewBmp()
113 const Rectangle
aRect( GetRect( aBmpWin
.GetSizePixel(), aBmp
.GetSizePixel() ) );
116 aPreviewBmp
.Scale( aRect
.GetSize() );
117 aBmpWin
.SetGraphic( aPreviewBmp
);
120 Bitmap
SdVectorizeDlg::GetPreparedBitmap( Bitmap
& rBmp
, Fraction
& rScale
)
123 const Size
aSizePix( aNew
.GetSizePixel() );
125 if( aSizePix
.Width() > VECTORIZE_MAX_EXTENT
|| aSizePix
.Height() > VECTORIZE_MAX_EXTENT
)
127 const Rectangle
aRect( GetRect( Size( VECTORIZE_MAX_EXTENT
, VECTORIZE_MAX_EXTENT
), aSizePix
) );
128 rScale
= Fraction( aSizePix
.Width(), aRect
.GetWidth() );
129 aNew
.Scale( aRect
.GetSize() );
132 rScale
= Fraction( 1, 1 );
134 aNew
.ReduceColors( (sal_uInt16
) aNmLayers
.GetValue(), BMP_REDUCE_SIMPLE
);
139 void SdVectorizeDlg::Calculate( Bitmap
& rBmp
, GDIMetaFile
& rMtf
)
141 mpDocSh
->SetWaitCursor( sal_True
);
145 Bitmap
aTmp( GetPreparedBitmap( rBmp
, aScale
) );
149 const Link
aPrgsHdl( LINK( this, SdVectorizeDlg
, ProgressHdl
) );
150 aTmp
.Vectorize( rMtf
, (sal_uInt8
) aMtReduce
.GetValue(), BMP_VECTORIZE_OUTER
| BMP_VECTORIZE_REDUCE_EDGES
, &aPrgsHdl
);
152 if( aCbFillHoles
.IsChecked() )
155 BitmapReadAccess
* pRAcc
= aTmp
.AcquireReadAccess();
159 const long nWidth
= pRAcc
->Width();
160 const long nHeight
= pRAcc
->Height();
161 const long nTileX
= static_cast<long>(aMtFillHoles
.GetValue());
162 const long nTileY
= static_cast<long>(aMtFillHoles
.GetValue());
163 const long nCountX
= nWidth
/ nTileX
;
164 const long nCountY
= nHeight
/ nTileY
;
165 const long nRestX
= nWidth
% nTileX
;
166 const long nRestY
= nHeight
% nTileY
;
168 MapMode
aMap( rMtf
.GetPrefMapMode() );
169 aNewMtf
.SetPrefSize( rMtf
.GetPrefSize() );
170 aNewMtf
.SetPrefMapMode( aMap
);
172 for( long nTY
= 0; nTY
< nCountY
; nTY
++ )
174 const long nY
= nTY
* nTileY
;
176 for( long nTX
= 0; nTX
< nCountX
; nTX
++ )
177 AddTile( pRAcc
, aNewMtf
, nTX
* nTileX
, nTY
* nTileY
, nTileX
, nTileY
);
180 AddTile( pRAcc
, aNewMtf
, nCountX
* nTileX
, nY
, nRestX
, nTileY
);
185 const long nY
= nCountY
* nTileY
;
187 for( long nTX
= 0; nTX
< nCountX
; nTX
++ )
188 AddTile( pRAcc
, aNewMtf
, nTX
* nTileX
, nY
, nTileX
, nRestY
);
191 AddTile( pRAcc
, aNewMtf
, nCountX
* nTileX
, nCountY
* nTileY
, nRestX
, nRestY
);
195 aTmp
.ReleaseAccess( pRAcc
);
197 for( size_t n
= 0, nCount
= rMtf
.GetActionSize(); n
< nCount
; n
++ )
198 aNewMtf
.AddAction( rMtf
.GetAction( n
)->Clone() );
200 aMap
.SetScaleX( aMap
.GetScaleX() * aScale
);
201 aMap
.SetScaleY( aMap
.GetScaleY() * aScale
);
202 aNewMtf
.SetPrefMapMode( aMap
);
209 mpDocSh
->SetWaitCursor( sal_False
);
212 void SdVectorizeDlg::AddTile( BitmapReadAccess
* pRAcc
, GDIMetaFile
& rMtf
,
213 long nPosX
, long nPosY
, long nWidth
, long nHeight
)
215 sal_uLong nSumR
= 0UL, nSumG
= 0UL, nSumB
= 0UL;
216 const long nRight
= nPosX
+ nWidth
- 1L;
217 const long nBottom
= nPosY
+ nHeight
- 1L;
218 const double fMult
= 1.0 / ( nWidth
* nHeight
);
220 for( long nY
= nPosY
; nY
<= nBottom
; nY
++ )
222 for( long nX
= nPosX
; nX
<= nRight
; nX
++ )
224 const BitmapColor
aPixel( pRAcc
->GetColor( nY
, nX
) );
226 nSumR
+= aPixel
.GetRed();
227 nSumG
+= aPixel
.GetGreen();
228 nSumB
+= aPixel
.GetBlue();
232 const Color
aColor( (sal_uInt8
) FRound( nSumR
* fMult
),
233 (sal_uInt8
) FRound( nSumG
* fMult
),
234 (sal_uInt8
) FRound( nSumB
* fMult
) );
236 Rectangle
aRect( Point( nPosX
, nPosY
), Size( nWidth
+ 1, nHeight
+ 1 ) );
237 const Size
& rMaxSize
= rMtf
.GetPrefSize();
239 aRect
= PixelToLogic( aRect
, rMtf
.GetPrefMapMode() );
241 if( aRect
.Right() > ( rMaxSize
.Width() - 1L ) )
242 aRect
.Right() = rMaxSize
.Width() - 1L;
244 if( aRect
.Bottom() > ( rMaxSize
.Height() - 1L ) )
245 aRect
.Bottom() = rMaxSize
.Height() - 1L;
247 rMtf
.AddAction( new MetaLineColorAction( aColor
, sal_True
) );
248 rMtf
.AddAction( new MetaFillColorAction( aColor
, sal_True
) );
249 rMtf
.AddAction( new MetaRectAction( aRect
) );
252 IMPL_LINK( SdVectorizeDlg
, ProgressHdl
, void*, pData
)
254 aPrgs
.SetValue( (sal_uInt16
)(sal_uLong
) pData
);
258 IMPL_LINK_NOARG(SdVectorizeDlg
, ClickPreviewHdl
)
260 Calculate( aBmp
, aMtf
);
261 aMtfWin
.SetGraphic( aMtf
);
262 aBtnPreview
.Disable();
267 IMPL_LINK_NOARG(SdVectorizeDlg
, ClickOKHdl
)
269 if( aBtnPreview
.IsEnabled() )
270 Calculate( aBmp
, aMtf
);
278 IMPL_LINK( SdVectorizeDlg
, ToggleHdl
, CheckBox
*, pCb
)
280 if( pCb
->IsChecked() )
282 aFtFillHoles
.Enable();
283 aMtFillHoles
.Enable();
287 aFtFillHoles
.Disable();
288 aMtFillHoles
.Disable();
296 IMPL_LINK_NOARG(SdVectorizeDlg
, ModifyHdl
)
298 aBtnPreview
.Enable();
302 void SdVectorizeDlg::LoadSettings()
304 SvStorageStreamRef
xIStm( SD_MOD()->GetOptionStream(
305 OUString( SD_OPTION_VECTORIZE
) ,
309 sal_uInt16 nFillHoles
;
314 SdIOCompat
aCompat( *xIStm
, STREAM_READ
);
315 *xIStm
>> nLayers
>> nReduce
>> nFillHoles
>> bFillHoles
;
322 bFillHoles
= sal_False
;
325 aNmLayers
.SetValue( nLayers
);
326 aMtReduce
.SetValue( nReduce
);
327 aMtFillHoles
.SetValue( nFillHoles
);
328 aCbFillHoles
.Check( bFillHoles
);
330 ToggleHdl( &aCbFillHoles
);
333 void SdVectorizeDlg::SaveSettings() const
335 SvStorageStreamRef
xOStm( SD_MOD()->GetOptionStream(
336 OUString(SD_OPTION_VECTORIZE
) ,
341 SdIOCompat
aCompat( *xOStm
, STREAM_WRITE
, 1 );
342 *xOStm
<< (sal_uInt16
) aNmLayers
.GetValue() << (sal_uInt16
) aMtReduce
.GetValue();
343 *xOStm
<< (sal_uInt16
) aMtFillHoles
.GetValue() << aCbFillHoles
.IsChecked();
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */