Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <sot/factory.hxx>
31 : : #include <tools/poly.hxx>
32 : : #include <vcl/bmpacc.hxx>
33 : : #include <vcl/virdev.hxx>
34 : : #include <vcl/wrkwin.hxx>
35 : : #include <svl/solar.hrc>
36 : : #include <sfx2/docfile.hxx>
37 : : #include <sfx2/app.hxx>
38 : : #include "svx/xoutbmp.hxx"
39 : : #include <svtools/FilterConfigItem.hxx>
40 : : #include <svtools/filter.hxx>
41 : :
42 : : // -----------
43 : : // - Defines -
44 : : // -----------
45 : :
46 : : #define FORMAT_BMP String(RTL_CONSTASCII_USTRINGPARAM("bmp"))
47 : : #define FORMAT_GIF String(RTL_CONSTASCII_USTRINGPARAM("gif"))
48 : : #define FORMAT_JPG String(RTL_CONSTASCII_USTRINGPARAM("jpg"))
49 : : #define FORMAT_PNG String(RTL_CONSTASCII_USTRINGPARAM("png"))
50 : :
51 : : // --------------
52 : : // - XOutBitmap -
53 : : // --------------
54 : :
55 : : GraphicFilter* XOutBitmap::pGrfFilter = NULL;
56 : :
57 : : // ------------------------------------------------------------------------
58 : :
59 : 0 : Animation XOutBitmap::MirrorAnimation( const Animation& rAnimation, sal_Bool bHMirr, sal_Bool bVMirr )
60 : : {
61 : 0 : Animation aNewAnim( rAnimation );
62 : :
63 [ # # ][ # # ]: 0 : if( bHMirr || bVMirr )
64 : : {
65 : 0 : const Size& rGlobalSize = aNewAnim.GetDisplaySizePixel();
66 : 0 : sal_uIntPtr nMirrorFlags = 0L;
67 : :
68 [ # # ]: 0 : if( bHMirr )
69 : 0 : nMirrorFlags |= BMP_MIRROR_HORZ;
70 : :
71 [ # # ]: 0 : if( bVMirr )
72 : 0 : nMirrorFlags |= BMP_MIRROR_VERT;
73 : :
74 [ # # ]: 0 : for( sal_uInt16 i = 0, nCount = aNewAnim.Count(); i < nCount; i++ )
75 : : {
76 [ # # ][ # # ]: 0 : AnimationBitmap aAnimBmp( aNewAnim.Get( i ) );
77 : :
78 : : // BitmapEx spiegeln
79 [ # # ]: 0 : aAnimBmp.aBmpEx.Mirror( nMirrorFlags );
80 : :
81 : : // Die Positionen innerhalb der Gesamtbitmap
82 : : // muessen natuerlich auch angepasst werden
83 [ # # ]: 0 : if( bHMirr )
84 : 0 : aAnimBmp.aPosPix.X() = rGlobalSize.Width() - aAnimBmp.aPosPix.X() -
85 : 0 : aAnimBmp.aSizePix.Width();
86 : :
87 [ # # ]: 0 : if( bVMirr )
88 : 0 : aAnimBmp.aPosPix.Y() = rGlobalSize.Height() - aAnimBmp.aPosPix.Y() -
89 : 0 : aAnimBmp.aSizePix.Height();
90 : :
91 [ # # ]: 0 : aNewAnim.Replace( aAnimBmp, i );
92 [ # # ]: 0 : }
93 : : }
94 : :
95 : 0 : return aNewAnim;
96 : : }
97 : :
98 : : // ------------------------------------------------------------------------
99 : :
100 : 0 : Graphic XOutBitmap::MirrorGraphic( const Graphic& rGraphic, const sal_uIntPtr nMirrorFlags )
101 : : {
102 : 0 : Graphic aRetGraphic;
103 : :
104 [ # # ]: 0 : if( nMirrorFlags )
105 : : {
106 [ # # ][ # # ]: 0 : if( rGraphic.IsAnimated() )
107 : : {
108 : : aRetGraphic = MirrorAnimation( rGraphic.GetAnimation(),
109 : : ( nMirrorFlags & BMP_MIRROR_HORZ ) == BMP_MIRROR_HORZ,
110 [ # # ][ # # ]: 0 : ( nMirrorFlags & BMP_MIRROR_VERT ) == BMP_MIRROR_VERT );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
111 : : }
112 : : else
113 : : {
114 [ # # ][ # # ]: 0 : if( rGraphic.IsTransparent() )
115 : : {
116 [ # # ]: 0 : BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
117 : :
118 [ # # ]: 0 : aBmpEx.Mirror( nMirrorFlags );
119 [ # # ][ # # ]: 0 : aRetGraphic = aBmpEx;
[ # # ][ # # ]
120 : : }
121 : : else
122 : : {
123 [ # # ]: 0 : Bitmap aBmp( rGraphic.GetBitmap() );
124 : :
125 [ # # ]: 0 : aBmp.Mirror( nMirrorFlags );
126 [ # # ][ # # ]: 0 : aRetGraphic = aBmp;
[ # # ][ # # ]
127 : : }
128 : : }
129 : : }
130 : : else
131 [ # # ]: 0 : aRetGraphic = rGraphic;
132 : :
133 : 0 : return aRetGraphic;
134 : : }
135 : :
136 : : // ------------------------------------------------------------------------
137 : :
138 : 0 : sal_uInt16 XOutBitmap::WriteGraphic( const Graphic& rGraphic, String& rFileName,
139 : : const String& rFilterName, const sal_uIntPtr nFlags,
140 : : const Size* pMtfSize_100TH_MM )
141 : : {
142 [ # # ]: 0 : if( rGraphic.GetType() != GRAPHIC_NONE )
143 : : {
144 [ # # ][ # # ]: 0 : INetURLObject aURL( rFileName );
145 [ # # ]: 0 : Graphic aGraphic;
146 [ # # ]: 0 : String aExt;
147 [ # # ]: 0 : GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
148 : 0 : sal_uInt16 nErr = GRFILTER_FILTERERROR, nFilter = GRFILTER_FORMAT_NOTFOUND;
149 [ # # ][ # # ]: 0 : sal_Bool bTransparent = rGraphic.IsTransparent(), bAnimated = rGraphic.IsAnimated();
150 : :
151 : : DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "XOutBitmap::WriteGraphic(...): invalid URL" );
152 : :
153 : : // calculate correct file name
154 [ # # ]: 0 : if( !( nFlags & XOUTBMP_DONT_EXPAND_FILENAME ) )
155 : : {
156 [ # # ][ # # ]: 0 : String aName( aURL.getBase() );
157 [ # # ]: 0 : aName += '_';
158 [ # # ][ # # ]: 0 : aName += String(aURL.getExtension());
[ # # ][ # # ]
159 [ # # ]: 0 : aName += '_';
160 [ # # ][ # # ]: 0 : String aStr( String::CreateFromInt32( rGraphic.GetChecksum(), 16 ) );
161 [ # # ]: 0 : if ( aStr.GetChar(0) == '-' )
162 [ # # ]: 0 : aStr.SetChar(0,'m');
163 [ # # ]: 0 : aName += aStr;
164 [ # # ][ # # ]: 0 : aURL.setBase( aName );
[ # # ][ # # ]
165 : : }
166 : :
167 [ # # ][ # # ]: 0 : if( ( nFlags & XOUTBMP_USE_NATIVE_IF_POSSIBLE ) &&
[ # # ][ # # ]
[ # # ][ # # ]
168 : 0 : !( nFlags & XOUTBMP_MIRROR_HORZ ) &&
169 : 0 : !( nFlags & XOUTBMP_MIRROR_VERT ) &&
170 [ # # ][ # # ]: 0 : ( rGraphic.GetType() != GRAPHIC_GDIMETAFILE ) && rGraphic.IsLink() )
171 : : {
172 : : // try to write native link
173 [ # # ]: 0 : const GfxLink aGfxLink( ( (Graphic&) rGraphic ).GetLink() );
174 : :
175 [ # # ]: 0 : switch( aGfxLink.GetType() )
[ # # # # ]
176 : : {
177 [ # # ][ # # ]: 0 : case( GFX_LINK_TYPE_NATIVE_GIF ): aExt = FORMAT_GIF; break;
[ # # ]
178 [ # # ][ # # ]: 0 : case( GFX_LINK_TYPE_NATIVE_JPG ): aExt = FORMAT_JPG; break;
[ # # ]
179 [ # # ][ # # ]: 0 : case( GFX_LINK_TYPE_NATIVE_PNG ): aExt = FORMAT_PNG; break;
[ # # ]
180 : :
181 : : default:
182 : 0 : break;
183 : : }
184 : :
185 [ # # ]: 0 : if( aExt.Len() )
186 : : {
187 [ # # ]: 0 : if( 0 == (nFlags & XOUTBMP_DONT_ADD_EXTENSION))
188 [ # # ][ # # ]: 0 : aURL.setExtension( aExt );
189 [ # # ][ # # ]: 0 : rFileName = aURL.GetMainURL( INetURLObject::NO_DECODE );
190 : :
191 [ # # ][ # # ]: 0 : SfxMedium aMedium( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE | STREAM_SHARE_DENYNONE | STREAM_TRUNC );
[ # # ][ # # ]
192 [ # # ]: 0 : SvStream* pOStm = aMedium.GetOutStream();
193 : :
194 [ # # ][ # # ]: 0 : if( pOStm && aGfxLink.GetDataSize() && aGfxLink.GetData() )
[ # # ][ # # ]
[ # # ][ # # ]
195 : : {
196 [ # # ][ # # ]: 0 : pOStm->Write( aGfxLink.GetData(), aGfxLink.GetDataSize() );
[ # # ]
197 [ # # ]: 0 : aMedium.Commit();
198 : :
199 [ # # ][ # # ]: 0 : if( !aMedium.GetError() )
200 : 0 : nErr = GRFILTER_OK;
201 [ # # ]: 0 : }
202 [ # # ]: 0 : }
203 : : }
204 : :
205 [ # # ]: 0 : if( GRFILTER_OK != nErr )
206 : : {
207 [ # # ]: 0 : String aFilter( rFilterName );
208 [ # # ]: 0 : sal_Bool bWriteTransGrf = ( aFilter.EqualsIgnoreCaseAscii( "transgrf" ) ) ||
209 [ # # ]: 0 : ( aFilter.EqualsIgnoreCaseAscii( "gif" ) ) ||
210 : : ( nFlags & XOUTBMP_USE_GIF_IF_POSSIBLE ) ||
211 [ # # ][ # # ]: 0 : ( ( nFlags & XOUTBMP_USE_GIF_IF_SENSIBLE ) && ( bAnimated || bTransparent ) );
[ # # ][ # # ]
[ # # ][ # # ]
212 : :
213 : : // get filter and extension
214 [ # # ]: 0 : if( bWriteTransGrf )
215 [ # # ][ # # ]: 0 : aFilter = FORMAT_GIF;
[ # # ]
216 : :
217 [ # # ]: 0 : nFilter = rFilter.GetExportFormatNumberForShortName( aFilter );
218 : :
219 [ # # ]: 0 : if( GRFILTER_FORMAT_NOTFOUND == nFilter )
220 : : {
221 [ # # ][ # # ]: 0 : nFilter = rFilter.GetExportFormatNumberForShortName( FORMAT_JPG );
[ # # ]
222 : :
223 [ # # ]: 0 : if( GRFILTER_FORMAT_NOTFOUND == nFilter )
224 [ # # ][ # # ]: 0 : nFilter = rFilter.GetExportFormatNumberForShortName( FORMAT_BMP );
[ # # ]
225 : : }
226 : :
227 [ # # ]: 0 : if( GRFILTER_FORMAT_NOTFOUND != nFilter )
228 : : {
229 [ # # ][ # # ]: 0 : aExt = rFilter.GetExportFormatShortName( nFilter ).ToLowerAscii();
[ # # ][ # # ]
230 : :
231 [ # # ]: 0 : if( bWriteTransGrf )
232 : : {
233 [ # # ]: 0 : if( bAnimated )
234 [ # # ]: 0 : aGraphic = rGraphic;
235 : : else
236 : : {
237 [ # # ][ # # ]: 0 : if( pMtfSize_100TH_MM && ( rGraphic.GetType() != GRAPHIC_BITMAP ) )
[ # # ][ # # ]
238 : : {
239 [ # # ]: 0 : VirtualDevice aVDev;
240 [ # # ][ # # ]: 0 : const Size aSize( aVDev.LogicToPixel( *pMtfSize_100TH_MM, MAP_100TH_MM ) );
[ # # ]
241 : :
242 [ # # ][ # # ]: 0 : if( aVDev.SetOutputSizePixel( aSize ) )
243 : : {
244 [ # # ]: 0 : const Wallpaper aWallpaper( aVDev.GetBackground() );
245 : 0 : const Point aPt;
246 : :
247 [ # # ][ # # ]: 0 : aVDev.SetBackground( Wallpaper( Color( COL_BLACK ) ) );
[ # # ]
248 [ # # ]: 0 : aVDev.Erase();
249 [ # # ]: 0 : rGraphic.Draw( &aVDev, aPt, aSize );
250 : :
251 [ # # ]: 0 : const Bitmap aBitmap( aVDev.GetBitmap( aPt, aSize ) );
252 : :
253 [ # # ]: 0 : aVDev.SetBackground( aWallpaper );
254 [ # # ]: 0 : aVDev.Erase();
255 [ # # ]: 0 : rGraphic.Draw( &aVDev, aPt, aSize );
256 : :
257 [ # # ]: 0 : aVDev.SetRasterOp( ROP_XOR );
258 [ # # ]: 0 : aVDev.DrawBitmap( aPt, aSize, aBitmap );
259 [ # # ][ # # ]: 0 : aGraphic = BitmapEx( aBitmap, aVDev.GetBitmap( aPt, aSize ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
260 : : }
261 : : else
262 [ # # ][ # # ]: 0 : aGraphic = rGraphic.GetBitmapEx();
[ # # ][ # # ]
[ # # ][ # # ]
263 : : }
264 : : else
265 [ # # ][ # # ]: 0 : aGraphic = rGraphic.GetBitmapEx();
[ # # ][ # # ]
[ # # ]
266 : : }
267 : : }
268 : : else
269 : : {
270 [ # # ][ # # ]: 0 : if( pMtfSize_100TH_MM && ( rGraphic.GetType() != GRAPHIC_BITMAP ) )
[ # # ][ # # ]
271 : : {
272 [ # # ]: 0 : VirtualDevice aVDev;
273 [ # # ][ # # ]: 0 : const Size aSize( aVDev.LogicToPixel( *pMtfSize_100TH_MM, MAP_100TH_MM ) );
[ # # ]
274 : :
275 [ # # ][ # # ]: 0 : if( aVDev.SetOutputSizePixel( aSize ) )
276 : : {
277 [ # # ]: 0 : rGraphic.Draw( &aVDev, Point(), aSize );
278 [ # # ][ # # ]: 0 : aGraphic = aVDev.GetBitmap( Point(), aSize );
[ # # ][ # # ]
[ # # ]
279 : : }
280 : : else
281 [ # # ][ # # ]: 0 : aGraphic = rGraphic.GetBitmap();
[ # # ][ # # ]
[ # # ][ # # ]
282 : : }
283 : : else
284 [ # # ][ # # ]: 0 : aGraphic = rGraphic.GetBitmap();
[ # # ][ # # ]
[ # # ]
285 : : }
286 : :
287 : : // mirror?
288 [ # # ][ # # ]: 0 : if( ( nFlags & XOUTBMP_MIRROR_HORZ ) || ( nFlags & XOUTBMP_MIRROR_VERT ) )
289 [ # # ][ # # ]: 0 : aGraphic = MirrorGraphic( aGraphic, nFlags );
[ # # ]
290 : :
291 [ # # ][ # # ]: 0 : if( ( GRFILTER_FORMAT_NOTFOUND != nFilter ) && ( aGraphic.GetType() != GRAPHIC_NONE ) )
[ # # ][ # # ]
292 : : {
293 [ # # ]: 0 : if( 0 == (nFlags & XOUTBMP_DONT_ADD_EXTENSION))
294 [ # # ][ # # ]: 0 : aURL.setExtension( aExt );
295 [ # # ][ # # ]: 0 : rFileName = aURL.GetMainURL( INetURLObject::NO_DECODE );
296 [ # # ]: 0 : nErr = ExportGraphic( aGraphic, aURL, rFilter, nFilter, NULL );
297 : : }
298 [ # # ]: 0 : }
299 : : }
300 : :
301 [ # # ][ # # ]: 0 : return nErr;
[ # # ]
302 : : }
303 : : else
304 : : {
305 : 0 : return GRFILTER_OK;
306 : : }
307 : : }
308 : :
309 : : // ------------------------------------------------------------------------
310 : :
311 : : #ifdef _MSC_VER
312 : : #pragma optimize ( "", off )
313 : : #endif
314 : :
315 : 0 : sal_uInt16 XOutBitmap::ExportGraphic( const Graphic& rGraphic, const INetURLObject& rURL,
316 : : GraphicFilter& rFilter, const sal_uInt16 nFormat,
317 : : const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData )
318 : : {
319 : : DBG_ASSERT( rURL.GetProtocol() != INET_PROT_NOT_VALID, "XOutBitmap::ExportGraphic(...): invalid URL" );
320 : :
321 [ # # ][ # # ]: 0 : SfxMedium aMedium( rURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE | STREAM_SHARE_DENYNONE | STREAM_TRUNC );
[ # # ][ # # ]
322 [ # # ]: 0 : SvStream* pOStm = aMedium.GetOutStream();
323 : 0 : sal_uInt16 nRet = GRFILTER_IOERROR;
324 : :
325 [ # # ]: 0 : if( pOStm )
326 : : {
327 : 0 : pGrfFilter = &rFilter;
328 : :
329 [ # # ][ # # ]: 0 : nRet = rFilter.ExportGraphic( rGraphic, rURL.GetMainURL( INetURLObject::NO_DECODE ), *pOStm, nFormat, pFilterData );
[ # # ][ # # ]
330 : :
331 : 0 : pGrfFilter = NULL;
332 [ # # ]: 0 : aMedium.Commit();
333 : :
334 [ # # ][ # # ]: 0 : if( aMedium.GetError() && ( GRFILTER_OK == nRet ) )
[ # # ][ # # ]
335 : 0 : nRet = GRFILTER_IOERROR;
336 : : }
337 : :
338 [ # # ]: 0 : return nRet;
339 : : }
340 : :
341 : : #ifdef _MSC_VER
342 : : #pragma optimize ( "", on )
343 : : #endif
344 : :
345 : : // ------------------------------------------------------------------------
346 : :
347 : 0 : Bitmap XOutBitmap::DetectEdges( const Bitmap& rBmp, const sal_uInt8 cThreshold )
348 : : {
349 [ # # ]: 0 : const Size aSize( rBmp.GetSizePixel() );
350 [ # # ]: 0 : Bitmap aRetBmp;
351 : 0 : sal_Bool bRet = sal_False;
352 : :
353 [ # # ][ # # ]: 0 : if( ( aSize.Width() > 2L ) && ( aSize.Height() > 2L ) )
[ # # ]
354 : : {
355 [ # # ]: 0 : Bitmap aWorkBmp( rBmp );
356 : :
357 [ # # ][ # # ]: 0 : if( aWorkBmp.Convert( BMP_CONVERSION_8BIT_GREYS ) )
358 : : {
359 [ # # ]: 0 : Bitmap aDstBmp( aSize, 1 );
360 [ # # ]: 0 : BitmapReadAccess* pReadAcc = aWorkBmp.AcquireReadAccess();
361 [ # # ]: 0 : BitmapWriteAccess* pWriteAcc = aDstBmp.AcquireWriteAccess();
362 : :
363 [ # # ][ # # ]: 0 : if( pReadAcc && pWriteAcc )
364 : : {
365 : 0 : const long nWidth = aSize.Width();
366 : 0 : const long nWidth2 = nWidth - 2L;
367 : 0 : const long nHeight = aSize.Height();
368 : 0 : const long nHeight2 = nHeight - 2L;
369 : 0 : const long lThres2 = (long) cThreshold * cThreshold;
370 [ # # ]: 0 : const BitmapColor aWhite = (sal_uInt8) pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) );
371 [ # # ]: 0 : const BitmapColor aBlack = (sal_uInt8) pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) );
372 : : long nSum1;
373 : : long nSum2;
374 : : long lGray;
375 : :
376 : : // Rand mit Weiss init.
377 [ # # ]: 0 : pWriteAcc->SetLineColor( Color( COL_WHITE) );
378 [ # # ]: 0 : pWriteAcc->DrawLine( Point(), Point( nWidth - 1L, 0L ) );
379 [ # # ]: 0 : pWriteAcc->DrawLine( Point( nWidth - 1L, 0L ), Point( nWidth - 1L, nHeight - 1L ) );
380 [ # # ]: 0 : pWriteAcc->DrawLine( Point( nWidth - 1L, nHeight - 1L ), Point( 0L, nHeight - 1L ) );
381 [ # # ]: 0 : pWriteAcc->DrawLine( Point( 0, nHeight - 1L ), Point() );
382 : :
383 [ # # ]: 0 : for( long nY = 0L, nY1 = 1L, nY2 = 2; nY < nHeight2; nY++, nY1++, nY2++ )
384 : : {
385 [ # # ]: 0 : for( long nX = 0L, nXDst = 1L, nXTmp; nX < nWidth2; nX++, nXDst++ )
386 : : {
387 : 0 : nXTmp = nX;
388 : :
389 [ # # ]: 0 : nSum1 = -( nSum2 = lGray = (sal_uInt8) pReadAcc->GetPixel( nY, nXTmp++ ) );
390 [ # # ]: 0 : nSum2 += ( (long) (sal_uInt8) pReadAcc->GetPixel( nY, nXTmp++ ) ) << 1;
391 [ # # ]: 0 : nSum1 += ( lGray = pReadAcc->GetPixel( nY, nXTmp ) );
392 : 0 : nSum2 += lGray;
393 : :
394 [ # # ]: 0 : nSum1 += ( (long) (sal_uInt8) pReadAcc->GetPixel( nY1, nXTmp ) ) << 1;
395 [ # # ]: 0 : nSum1 -= ( (long) (sal_uInt8) pReadAcc->GetPixel( nY1, nXTmp -= 2 ) ) << 1;
396 : :
397 [ # # ]: 0 : nSum1 += ( lGray = -(long) (sal_uInt8) pReadAcc->GetPixel( nY2, nXTmp++ ) );
398 : 0 : nSum2 += lGray;
399 [ # # ]: 0 : nSum2 -= ( (long) (sal_uInt8) pReadAcc->GetPixel( nY2, nXTmp++ ) ) << 1;
400 [ # # ]: 0 : nSum1 += ( lGray = (long) (sal_uInt8) pReadAcc->GetPixel( nY2, nXTmp ) );
401 : 0 : nSum2 -= lGray;
402 : :
403 [ # # ]: 0 : if( ( nSum1 * nSum1 + nSum2 * nSum2 ) < lThres2 )
404 [ # # ]: 0 : pWriteAcc->SetPixel( nY1, nXDst, aWhite );
405 : : else
406 [ # # ]: 0 : pWriteAcc->SetPixel( nY1, nXDst, aBlack );
407 : : }
408 : : }
409 : :
410 : 0 : bRet = sal_True;
411 : : }
412 : :
413 [ # # ]: 0 : aWorkBmp.ReleaseAccess( pReadAcc );
414 [ # # ]: 0 : aDstBmp.ReleaseAccess( pWriteAcc );
415 : :
416 [ # # ]: 0 : if( bRet )
417 [ # # ][ # # ]: 0 : aRetBmp = aDstBmp;
418 [ # # ]: 0 : }
419 : : }
420 : :
421 [ # # ]: 0 : if( !aRetBmp )
422 [ # # ]: 0 : aRetBmp = rBmp;
423 : : else
424 : : {
425 [ # # ]: 0 : aRetBmp.SetPrefMapMode( rBmp.GetPrefMapMode() );
426 : 0 : aRetBmp.SetPrefSize( rBmp.GetPrefSize() );
427 : : }
428 : :
429 : 0 : return aRetBmp;
430 : : };
431 : :
432 : : // ------------------------------------------------------------------------
433 : :
434 : 0 : Polygon XOutBitmap::GetCountour( const Bitmap& rBmp, const sal_uIntPtr nFlags,
435 : : const sal_uInt8 cEdgeDetectThreshold, const Rectangle* pWorkRectPixel )
436 : : {
437 [ # # ]: 0 : Bitmap aWorkBmp;
438 [ # # ]: 0 : Polygon aRetPoly;
439 : 0 : Point aTmpPoint;
440 [ # # ][ # # ]: 0 : Rectangle aWorkRect( aTmpPoint, rBmp.GetSizePixel() );
441 : :
442 [ # # ]: 0 : if( pWorkRectPixel )
443 [ # # ]: 0 : aWorkRect.Intersection( *pWorkRectPixel );
444 : :
445 [ # # ]: 0 : aWorkRect.Justify();
446 : :
447 [ # # ][ # # ]: 0 : if( ( aWorkRect.GetWidth() > 4 ) && ( aWorkRect.GetHeight() > 4 ) )
[ # # ][ # # ]
[ # # ]
448 : : {
449 : : // falls Flag gesetzt, muessen wir Kanten detektieren
450 [ # # ]: 0 : if( nFlags & XOUTBMP_CONTOUR_EDGEDETECT )
451 [ # # ][ # # ]: 0 : aWorkBmp = DetectEdges( rBmp, cEdgeDetectThreshold );
[ # # ]
452 : : else
453 [ # # ]: 0 : aWorkBmp = rBmp;
454 : :
455 [ # # ]: 0 : BitmapReadAccess* pAcc = aWorkBmp.AcquireReadAccess();
456 : :
457 [ # # ]: 0 : if( pAcc )
458 : : {
459 : 0 : const Size& rPrefSize = aWorkBmp.GetPrefSize();
460 : 0 : const long nWidth = pAcc->Width();
461 : 0 : const long nHeight = pAcc->Height();
462 : 0 : const double fFactorX = (double) rPrefSize.Width() / nWidth;
463 : 0 : const double fFactorY = (double) rPrefSize.Height() / nHeight;
464 : 0 : const long nStartX1 = aWorkRect.Left() + 1L;
465 : 0 : const long nEndX1 = aWorkRect.Right();
466 : 0 : const long nStartX2 = nEndX1 - 1L;
467 : : // const long nEndX2 = nStartX1 - 1L;
468 : 0 : const long nStartY1 = aWorkRect.Top() + 1L;
469 : 0 : const long nEndY1 = aWorkRect.Bottom();
470 : 0 : const long nStartY2 = nEndY1 - 1L;
471 : : // const long nEndY2 = nStartY1 - 1L;
472 : 0 : Point* pPoints1 = NULL;
473 : 0 : Point* pPoints2 = NULL;
474 : : long nX, nY;
475 : 0 : sal_uInt16 nPolyPos = 0;
476 [ # # ]: 0 : const BitmapColor aBlack = pAcc->GetBestMatchingColor( Color( COL_BLACK ) );
477 : :
478 [ # # ]: 0 : if( nFlags & XOUTBMP_CONTOUR_VERT )
479 : : {
480 [ # # ][ # # ]: 0 : pPoints1 = new Point[ nWidth ];
481 [ # # ][ # # ]: 0 : pPoints2 = new Point[ nWidth ];
482 : :
483 [ # # ]: 0 : for( nX = nStartX1; nX < nEndX1; nX++ )
484 : : {
485 : 0 : nY = nStartY1;
486 : :
487 : : // zunaechst Zeile von Links nach Rechts durchlaufen
488 [ # # ]: 0 : while( nY < nEndY1 )
489 : : {
490 [ # # ][ # # ]: 0 : if( aBlack == pAcc->GetPixel( nY, nX ) )
491 : : {
492 : 0 : pPoints1[ nPolyPos ] = Point( nX, nY );
493 : 0 : nY = nStartY2;
494 : :
495 : : // diese Schleife wird immer gebreaked da hier ja min. ein Pixel ist
496 : 0 : while( sal_True )
497 : : {
498 [ # # ][ # # ]: 0 : if( aBlack == pAcc->GetPixel( nY, nX ) )
499 : : {
500 : 0 : pPoints2[ nPolyPos ] = Point( nX, nY );
501 : 0 : break;
502 : : }
503 : :
504 : 0 : nY--;
505 : : }
506 : :
507 : 0 : nPolyPos++;
508 : 0 : break;
509 : : }
510 : :
511 : 0 : nY++;
512 : : }
513 : : }
514 : : }
515 : : else
516 : : {
517 [ # # ][ # # ]: 0 : pPoints1 = new Point[ nHeight ];
518 [ # # ][ # # ]: 0 : pPoints2 = new Point[ nHeight ];
519 : :
520 [ # # ]: 0 : for ( nY = nStartY1; nY < nEndY1; nY++ )
521 : : {
522 : 0 : nX = nStartX1;
523 : :
524 : : // zunaechst Zeile von Links nach Rechts durchlaufen
525 [ # # ]: 0 : while( nX < nEndX1 )
526 : : {
527 [ # # ][ # # ]: 0 : if( aBlack == pAcc->GetPixel( nY, nX ) )
528 : : {
529 : 0 : pPoints1[ nPolyPos ] = Point( nX, nY );
530 : 0 : nX = nStartX2;
531 : :
532 : : // diese Schleife wird immer gebreaked da hier ja min. ein Pixel ist
533 : 0 : while( sal_True )
534 : : {
535 [ # # ][ # # ]: 0 : if( aBlack == pAcc->GetPixel( nY, nX ) )
536 : : {
537 : 0 : pPoints2[ nPolyPos ] = Point( nX, nY );
538 : 0 : break;
539 : : }
540 : :
541 : 0 : nX--;
542 : : }
543 : :
544 : 0 : nPolyPos++;
545 : 0 : break;
546 : : }
547 : :
548 : 0 : nX++;
549 : : }
550 : : }
551 : : }
552 : :
553 : 0 : const sal_uInt16 nNewSize1 = nPolyPos << 1;
554 : :
555 [ # # ][ # # ]: 0 : aRetPoly = Polygon( nPolyPos, pPoints1 );
[ # # ]
556 [ # # ]: 0 : aRetPoly.SetSize( nNewSize1 + 1 );
557 [ # # ][ # # ]: 0 : aRetPoly[ nNewSize1 ] = aRetPoly[ 0 ];
558 : :
559 [ # # ]: 0 : for( sal_uInt16 j = nPolyPos; nPolyPos < nNewSize1; )
560 [ # # ]: 0 : aRetPoly[ nPolyPos++ ] = pPoints2[ --j ];
561 : :
562 [ # # ][ # # ]: 0 : if( ( fFactorX != 0. ) && ( fFactorY != 0. ) )
563 [ # # ]: 0 : aRetPoly.Scale( fFactorX, fFactorY );
564 : :
565 [ # # ]: 0 : delete[] pPoints1;
566 [ # # ]: 0 : delete[] pPoints2;
567 : : }
568 : : }
569 : :
570 [ # # ]: 0 : return aRetPoly;
571 : : };
572 : :
573 : : // ----------------
574 : : // - DitherBitmap -
575 : : // ----------------
576 : :
577 : 0 : sal_Bool DitherBitmap( Bitmap& rBitmap )
578 : : {
579 : 0 : sal_Bool bRet = sal_False;
580 : :
581 [ # # ][ # # ]: 0 : if( ( rBitmap.GetBitCount() >= 8 ) && ( Application::GetDefaultDevice()->GetColorCount() < 257 ) )
[ # # ]
582 : 0 : bRet = rBitmap.Dither( BMP_DITHER_FLOYD );
583 : : else
584 : 0 : bRet = sal_False;
585 : :
586 : 0 : return bRet;
587 : : }
588 : :
589 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|