1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: _xoutbmp.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <sot/factory.hxx>
35 #include <tools/urlobj.hxx>
36 #include <unotools/ucbstreamhelper.hxx>
37 #include <vcl/bmpacc.hxx>
38 #include <tools/poly.hxx>
39 #include <vcl/virdev.hxx>
40 #include <vcl/wrkwin.hxx>
41 #include <svtools/solar.hrc>
42 #include <sfx2/docfile.hxx>
43 #include <sfx2/app.hxx>
45 #include "xoutbmp.hxx"
46 #include <svtools/FilterConfigItem.hxx>
52 #define FORMAT_BMP String(RTL_CONSTASCII_USTRINGPARAM("bmp"))
53 #define FORMAT_GIF String(RTL_CONSTASCII_USTRINGPARAM("gif"))
54 #define FORMAT_JPG String(RTL_CONSTASCII_USTRINGPARAM("jpg"))
55 #define FORMAT_PNG String(RTL_CONSTASCII_USTRINGPARAM("png"))
61 GraphicFilter
* XOutBitmap::pGrfFilter
= NULL
;
63 // -----------------------------------------------------------------------------
65 BitmapEx
XOutBitmap::CreateQuickDrawBitmapEx( const Graphic
& rGraphic
, const OutputDevice
& rCompDev
,
66 const MapMode
& rMapMode
, const Size
& rLogSize
,
67 const Point
& rPoint
, const Size
& rSize
)
71 if( rGraphic
.IsAlpha() )
72 aRetBmp
= rGraphic
.GetBitmapEx();
75 VirtualDevice
aVDev( rCompDev
);
76 MapMode
aMap( rMapMode
);
78 aMap
.SetOrigin( Point() );
79 aVDev
.SetMapMode( aMap
);
81 Point
aPoint( aVDev
.LogicToPixel( rPoint
) );
82 Size
aOldSize( aVDev
.LogicToPixel( rSize
) );
83 Size
aAbsSize( aOldSize
);
84 Size
aQSizePix( aVDev
.LogicToPixel( rLogSize
) );
86 aVDev
.SetMapMode( MapMode() );
88 if( aOldSize
.Width() < 0 )
89 aAbsSize
.Width() = -aAbsSize
.Width();
91 if( aOldSize
.Height() < 0 )
92 aAbsSize
.Height() = -aAbsSize
.Height();
94 if( aVDev
.SetOutputSizePixel( aAbsSize
) )
96 Point
aNewOrg( -aPoint
.X(), -aPoint
.Y() );
97 const Point aNullPoint
;
99 // horizontale Spiegelung ggf. beruecksichtigen
100 if( aOldSize
.Width() < 0 )
102 aNewOrg
.X() -= aOldSize
.Width();
104 // und jetzt noch einen abziehen
108 // vertikale Spiegelung ggf. beruecksichtigen
109 if( rSize
.Height() < 0 )
111 aNewOrg
.Y() -= aOldSize
.Height();
113 // und jetzt noch einen abziehen
117 if( rGraphic
.GetType() != GRAPHIC_BITMAP
)
119 rGraphic
.Draw( &aVDev
, aNewOrg
, aQSizePix
);
121 const Bitmap
aBmp( aVDev
.GetBitmap( aNullPoint
, aAbsSize
) );
124 Graphic( rGraphic
.GetGDIMetaFile().GetMonochromeMtf( COL_BLACK
) ).Draw( &aVDev
, aNewOrg
, aQSizePix
);
125 aMask
= aVDev
.GetBitmap( aNullPoint
, aAbsSize
);
126 aRetBmp
= BitmapEx( aBmp
, aMask
);
130 Bitmap
aBmp( rGraphic
.GetBitmap() );
132 // UNX has got problems with 1x1 bitmaps which are transparent (KA 02.11.1998)
134 const Size
aBmpSize( aBmp
.GetSizePixel() );
135 BOOL bFullTrans
= FALSE
;
137 if( aBmpSize
.Width() == 1 && aBmpSize
.Height() == 1 && rGraphic
.IsTransparent() )
139 Bitmap
aTrans( rGraphic
.GetBitmapEx().GetMask() );
140 BitmapReadAccess
* pMAcc
= aBmp
.AcquireReadAccess();
144 if( pMAcc
->GetColor( 0, 0 ) == BitmapColor( Color( COL_WHITE
) ) )
147 aTrans
.ReleaseAccess( pMAcc
);
155 DitherBitmap( aBmp
);
156 aVDev
.DrawBitmap( aNewOrg
, aQSizePix
, aBmp
);
157 aBmp
= aVDev
.GetBitmap( aNullPoint
, aAbsSize
);
159 if( !rGraphic
.IsTransparent() )
160 aRetBmp
= BitmapEx( aBmp
);
163 Bitmap
aTrans( rGraphic
.GetBitmapEx().GetMask() );
166 aRetBmp
= BitmapEx( aBmp
, rGraphic
.GetBitmapEx().GetTransparentColor() );
169 aVDev
.DrawBitmap( aNewOrg
, aQSizePix
, aTrans
);
170 aRetBmp
= BitmapEx( aBmp
, aVDev
.GetBitmap( Point(), aAbsSize
) );
181 // ------------------------------------------------------------------------
183 void XOutBitmap::DrawQuickDrawBitmapEx( OutputDevice
* pOutDev
, const Point
& rPt
,
184 const Size
& rSize
, const BitmapEx
& rBmpEx
)
186 const Size
aBmpSizePix( rBmpEx
.GetSizePixel() );
187 const Size
aSizePix( pOutDev
->LogicToPixel( rSize
) );
189 if ( ( aSizePix
.Width() - aBmpSizePix
.Width() ) || ( aSizePix
.Height() - aBmpSizePix
.Height() ) )
190 rBmpEx
.Draw( pOutDev
, rPt
, rSize
);
192 rBmpEx
.Draw( pOutDev
, rPt
);
195 // ------------------------------------------------------------------------
197 void XOutBitmap::DrawTiledBitmapEx( OutputDevice
* pOutDev
,
198 const Point
& rStartPt
, const Size
& rGrfSize
,
199 const Rectangle
& rTileRect
, const BitmapEx
& rBmpEx
)
201 Rectangle
aClipRect( pOutDev
->LogicToPixel( pOutDev
->GetClipRegion().GetBoundRect() ) );
202 Rectangle
aPixRect( pOutDev
->LogicToPixel( rTileRect
) );
203 const Size
aPixSize( pOutDev
->LogicToPixel( rGrfSize
) );
204 const Point
aPixPoint( pOutDev
->LogicToPixel( rStartPt
) );
206 const long nWidth
= aPixSize
.Width();
207 const long nHeight
= aPixSize
.Height();
208 long nXPos
= aPixPoint
.X() + ( ( aPixRect
.Left() - aPixPoint
.X() ) / nWidth
) * nWidth
;
209 long nYPos
= aPixPoint
.Y() + ( ( aPixRect
.Top() - aPixPoint
.Y() ) / nHeight
) * nHeight
;
210 const long nBottom
= aPixRect
.Bottom();
211 const long nRight
= aPixRect
.Right();
212 const long nLeft
= nXPos
;
213 const BOOL bNoSize
= ( aPixSize
== rBmpEx
.GetSizePixel() );
216 pOutDev
->SetMapMode( MapMode() );
218 // ggf. neue ClipRegion berechnen und setzen
219 if ( pOutDev
->IsClipRegion() )
220 aPixRect
.Intersection( aClipRect
);
222 pOutDev
->SetClipRegion( aPixRect
);
224 while( nYPos
<= nBottom
)
226 while( nXPos
<= nRight
)
229 rBmpEx
.Draw( pOutDev
, Point( nXPos
, nYPos
) );
231 rBmpEx
.Draw( pOutDev
, Point( nXPos
, nYPos
), aPixSize
);
243 // ------------------------------------------------------------------------
245 Animation
XOutBitmap::MirrorAnimation( const Animation
& rAnimation
, BOOL bHMirr
, BOOL bVMirr
)
247 Animation
aNewAnim( rAnimation
);
249 if( bHMirr
|| bVMirr
)
251 const Size
& rGlobalSize
= aNewAnim
.GetDisplaySizePixel();
252 ULONG nMirrorFlags
= 0L;
255 nMirrorFlags
|= BMP_MIRROR_HORZ
;
258 nMirrorFlags
|= BMP_MIRROR_VERT
;
260 for( USHORT i
= 0, nCount
= aNewAnim
.Count(); i
< nCount
; i
++ )
262 AnimationBitmap
aAnimBmp( aNewAnim
.Get( i
) );
265 aAnimBmp
.aBmpEx
.Mirror( nMirrorFlags
);
267 // Die Positionen innerhalb der Gesamtbitmap
268 // muessen natuerlich auch angepasst werden
270 aAnimBmp
.aPosPix
.X() = rGlobalSize
.Width() - aAnimBmp
.aPosPix
.X() -
271 aAnimBmp
.aSizePix
.Width();
274 aAnimBmp
.aPosPix
.Y() = rGlobalSize
.Height() - aAnimBmp
.aPosPix
.Y() -
275 aAnimBmp
.aSizePix
.Height();
277 aNewAnim
.Replace( aAnimBmp
, i
);
284 // ------------------------------------------------------------------------
286 Graphic
XOutBitmap::MirrorGraphic( const Graphic
& rGraphic
, const ULONG nMirrorFlags
)
292 if( rGraphic
.IsAnimated() )
294 aRetGraphic
= MirrorAnimation( rGraphic
.GetAnimation(),
295 ( nMirrorFlags
& BMP_MIRROR_HORZ
) == BMP_MIRROR_HORZ
,
296 ( nMirrorFlags
& BMP_MIRROR_VERT
) == BMP_MIRROR_VERT
);
300 if( rGraphic
.IsTransparent() )
302 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
304 aBmpEx
.Mirror( nMirrorFlags
);
305 aRetGraphic
= aBmpEx
;
309 Bitmap
aBmp( rGraphic
.GetBitmap() );
311 aBmp
.Mirror( nMirrorFlags
);
317 aRetGraphic
= rGraphic
;
322 // ------------------------------------------------------------------------
324 USHORT
XOutBitmap::WriteGraphic( const Graphic
& rGraphic
, String
& rFileName
,
325 const String
& rFilterName
, const ULONG nFlags
,
326 const Size
* pMtfSize_100TH_MM
)
328 if( rGraphic
.GetType() != GRAPHIC_NONE
)
330 INetURLObject
aURL( rFileName
);
333 GraphicFilter
* pFilter
= GetGrfFilter();
334 USHORT nErr
= GRFILTER_FILTERERROR
, nFilter
= GRFILTER_FORMAT_NOTFOUND
;
335 BOOL bTransparent
= rGraphic
.IsTransparent(), bAnimated
= rGraphic
.IsAnimated();
337 DBG_ASSERT( aURL
.GetProtocol() != INET_PROT_NOT_VALID
, "XOutBitmap::WriteGraphic(...): invalid URL" );
339 // calculate correct file name
340 if( !( nFlags
& XOUTBMP_DONT_EXPAND_FILENAME
) )
342 String
aName( aURL
.getBase() );
344 aName
+= String(aURL
.getExtension());
346 String
aStr( String::CreateFromInt32( rGraphic
.GetChecksum(), 16 ) );
347 if ( aStr
.GetChar(0) == '-' )
350 aURL
.setBase( aName
);
353 if( ( nFlags
& XOUTBMP_USE_NATIVE_IF_POSSIBLE
) &&
354 !( nFlags
& XOUTBMP_MIRROR_HORZ
) &&
355 !( nFlags
& XOUTBMP_MIRROR_VERT
) &&
356 ( rGraphic
.GetType() != GRAPHIC_GDIMETAFILE
) && rGraphic
.IsLink() )
358 // try to write native link
359 const GfxLink
aGfxLink( ( (Graphic
&) rGraphic
).GetLink() );
361 switch( aGfxLink
.GetType() )
363 case( GFX_LINK_TYPE_NATIVE_GIF
): aExt
= FORMAT_GIF
; break;
364 case( GFX_LINK_TYPE_NATIVE_JPG
): aExt
= FORMAT_JPG
; break;
365 case( GFX_LINK_TYPE_NATIVE_PNG
): aExt
= FORMAT_PNG
; break;
373 aURL
.setExtension( aExt
);
374 rFileName
= aURL
.GetMainURL( INetURLObject::NO_DECODE
);
376 SfxMedium
aMedium( aURL
.GetMainURL( INetURLObject::NO_DECODE
), STREAM_WRITE
| STREAM_SHARE_DENYNONE
| STREAM_TRUNC
, TRUE
);
377 SvStream
* pOStm
= aMedium
.GetOutStream();
379 if( pOStm
&& aGfxLink
.GetDataSize() && aGfxLink
.GetData() )
381 pOStm
->Write( aGfxLink
.GetData(), aGfxLink
.GetDataSize() );
384 if( !aMedium
.GetError() )
390 if( GRFILTER_OK
!= nErr
)
392 String
aFilter( rFilterName
);
393 BOOL bWriteTransGrf
= ( aFilter
.EqualsIgnoreCaseAscii( "transgrf" ) ) ||
394 ( aFilter
.EqualsIgnoreCaseAscii( "gif" ) ) ||
395 ( nFlags
& XOUTBMP_USE_GIF_IF_POSSIBLE
) ||
396 ( ( nFlags
& XOUTBMP_USE_GIF_IF_SENSIBLE
) && ( bAnimated
|| bTransparent
) );
398 // get filter and extension
400 aFilter
= FORMAT_GIF
;
402 nFilter
= pFilter
->GetExportFormatNumberForShortName( aFilter
);
404 if( GRFILTER_FORMAT_NOTFOUND
== nFilter
)
406 nFilter
= pFilter
->GetExportFormatNumberForShortName( FORMAT_JPG
);
408 if( GRFILTER_FORMAT_NOTFOUND
== nFilter
)
409 nFilter
= pFilter
->GetExportFormatNumberForShortName( FORMAT_BMP
);
412 if( GRFILTER_FORMAT_NOTFOUND
!= nFilter
)
414 aExt
= pFilter
->GetExportFormatShortName( nFilter
).ToLowerAscii();
422 if( pMtfSize_100TH_MM
&& ( rGraphic
.GetType() != GRAPHIC_BITMAP
) )
425 const Size
aSize( aVDev
.LogicToPixel( *pMtfSize_100TH_MM
, MAP_100TH_MM
) );
427 if( aVDev
.SetOutputSizePixel( aSize
) )
429 const Wallpaper
aWallpaper( aVDev
.GetBackground() );
432 aVDev
.SetBackground( Wallpaper( Color( COL_BLACK
) ) );
434 rGraphic
.Draw( &aVDev
, aPt
, aSize
);
436 const Bitmap
aBitmap( aVDev
.GetBitmap( aPt
, aSize
) );
438 aVDev
.SetBackground( aWallpaper
);
440 rGraphic
.Draw( &aVDev
, aPt
, aSize
);
442 aVDev
.SetRasterOp( ROP_XOR
);
443 aVDev
.DrawBitmap( aPt
, aSize
, aBitmap
);
444 aGraphic
= BitmapEx( aBitmap
, aVDev
.GetBitmap( aPt
, aSize
) );
447 aGraphic
= rGraphic
.GetBitmapEx();
450 aGraphic
= rGraphic
.GetBitmapEx();
455 if( pMtfSize_100TH_MM
&& ( rGraphic
.GetType() != GRAPHIC_BITMAP
) )
458 const Size
aSize( aVDev
.LogicToPixel( *pMtfSize_100TH_MM
, MAP_100TH_MM
) );
460 if( aVDev
.SetOutputSizePixel( aSize
) )
462 rGraphic
.Draw( &aVDev
, Point(), aSize
);
463 aGraphic
= aVDev
.GetBitmap( Point(), aSize
);
466 aGraphic
= rGraphic
.GetBitmap();
469 aGraphic
= rGraphic
.GetBitmap();
473 if( ( nFlags
& XOUTBMP_MIRROR_HORZ
) || ( nFlags
& XOUTBMP_MIRROR_VERT
) )
474 aGraphic
= MirrorGraphic( aGraphic
, nFlags
);
476 if( ( GRFILTER_FORMAT_NOTFOUND
!= nFilter
) && ( aGraphic
.GetType() != GRAPHIC_NONE
) )
478 aURL
.setExtension( aExt
);
479 rFileName
= aURL
.GetMainURL( INetURLObject::NO_DECODE
);
480 nErr
= ExportGraphic( aGraphic
, aURL
, *pFilter
, nFilter
, NULL
);
493 // ------------------------------------------------------------------------
496 #pragma optimize ( "", off )
499 USHORT
XOutBitmap::ExportGraphic( const Graphic
& rGraphic
, const INetURLObject
& rURL
,
500 GraphicFilter
& rFilter
, const USHORT nFormat
,
501 const com::sun::star::uno::Sequence
< com::sun::star::beans::PropertyValue
>* pFilterData
)
503 DBG_ASSERT( rURL
.GetProtocol() != INET_PROT_NOT_VALID
, "XOutBitmap::ExportGraphic(...): invalid URL" );
505 SfxMedium
aMedium( rURL
.GetMainURL( INetURLObject::NO_DECODE
), STREAM_WRITE
| STREAM_SHARE_DENYNONE
| STREAM_TRUNC
, TRUE
);
506 SvStream
* pOStm
= aMedium
.GetOutStream();
507 USHORT nRet
= GRFILTER_IOERROR
;
511 pGrfFilter
= &rFilter
;
513 nRet
= rFilter
.ExportGraphic( rGraphic
, rURL
.GetMainURL( INetURLObject::NO_DECODE
), *pOStm
, nFormat
, pFilterData
);
518 if( aMedium
.GetError() && ( GRFILTER_OK
== nRet
) )
519 nRet
= GRFILTER_IOERROR
;
526 #pragma optimize ( "", on )
529 // ------------------------------------------------------------------------
531 Bitmap
XOutBitmap::DetectEdges( const Bitmap
& rBmp
, const BYTE cThreshold
)
533 const Size
aSize( rBmp
.GetSizePixel() );
537 if( ( aSize
.Width() > 2L ) && ( aSize
.Height() > 2L ) )
539 Bitmap
aWorkBmp( rBmp
);
541 if( aWorkBmp
.Convert( BMP_CONVERSION_8BIT_GREYS
) )
543 Bitmap
aDstBmp( aSize
, 1 );
544 BitmapReadAccess
* pReadAcc
= aWorkBmp
.AcquireReadAccess();
545 BitmapWriteAccess
* pWriteAcc
= aDstBmp
.AcquireWriteAccess();
547 if( pReadAcc
&& pWriteAcc
)
549 const long nWidth
= aSize
.Width();
550 const long nWidth2
= nWidth
- 2L;
551 const long nHeight
= aSize
.Height();
552 const long nHeight2
= nHeight
- 2L;
553 const long lThres2
= (long) cThreshold
* cThreshold
;
554 const BitmapColor aWhite
= (BYTE
) pWriteAcc
->GetBestMatchingColor( Color( COL_WHITE
) );
555 const BitmapColor aBlack
= (BYTE
) pWriteAcc
->GetBestMatchingColor( Color( COL_BLACK
) );
560 // Rand mit Weiss init.
561 pWriteAcc
->SetLineColor( Color( COL_WHITE
) );
562 pWriteAcc
->DrawLine( Point(), Point( nWidth
- 1L, 0L ) );
563 pWriteAcc
->DrawLine( Point( nWidth
- 1L, 0L ), Point( nWidth
- 1L, nHeight
- 1L ) );
564 pWriteAcc
->DrawLine( Point( nWidth
- 1L, nHeight
- 1L ), Point( 0L, nHeight
- 1L ) );
565 pWriteAcc
->DrawLine( Point( 0, nHeight
- 1L ), Point() );
567 for( long nY
= 0L, nY1
= 1L, nY2
= 2; nY
< nHeight2
; nY
++, nY1
++, nY2
++ )
569 for( long nX
= 0L, nXDst
= 1L, nXTmp
; nX
< nWidth2
; nX
++, nXDst
++ )
573 nSum1
= -( nSum2
= lGray
= (BYTE
) pReadAcc
->GetPixel( nY
, nXTmp
++ ) );
574 nSum2
+= ( (long) (BYTE
) pReadAcc
->GetPixel( nY
, nXTmp
++ ) ) << 1;
575 nSum1
+= ( lGray
= pReadAcc
->GetPixel( nY
, nXTmp
) );
578 nSum1
+= ( (long) (BYTE
) pReadAcc
->GetPixel( nY1
, nXTmp
) ) << 1;
579 nSum1
-= ( (long) (BYTE
) pReadAcc
->GetPixel( nY1
, nXTmp
-= 2 ) ) << 1;
581 nSum1
+= ( lGray
= -(long) (BYTE
) pReadAcc
->GetPixel( nY2
, nXTmp
++ ) );
583 nSum2
-= ( (long) (BYTE
) pReadAcc
->GetPixel( nY2
, nXTmp
++ ) ) << 1;
584 nSum1
+= ( lGray
= (long) (BYTE
) pReadAcc
->GetPixel( nY2
, nXTmp
) );
587 if( ( nSum1
* nSum1
+ nSum2
* nSum2
) < lThres2
)
588 pWriteAcc
->SetPixel( nY1
, nXDst
, aWhite
);
590 pWriteAcc
->SetPixel( nY1
, nXDst
, aBlack
);
597 aWorkBmp
.ReleaseAccess( pReadAcc
);
598 aDstBmp
.ReleaseAccess( pWriteAcc
);
609 aRetBmp
.SetPrefMapMode( rBmp
.GetPrefMapMode() );
610 aRetBmp
.SetPrefSize( rBmp
.GetPrefSize() );
616 // ------------------------------------------------------------------------
618 Polygon
XOutBitmap::GetCountour( const Bitmap
& rBmp
, const ULONG nFlags
,
619 const BYTE cEdgeDetectThreshold
, const Rectangle
* pWorkRectPixel
)
624 Rectangle
aWorkRect( aTmpPoint
, rBmp
.GetSizePixel() );
627 aWorkRect
.Intersection( *pWorkRectPixel
);
631 if( ( aWorkRect
.GetWidth() > 4 ) && ( aWorkRect
.GetHeight() > 4 ) )
633 // falls Flag gesetzt, muessen wir Kanten detektieren
634 if( nFlags
& XOUTBMP_CONTOUR_EDGEDETECT
)
635 aWorkBmp
= DetectEdges( rBmp
, cEdgeDetectThreshold
);
639 BitmapReadAccess
* pAcc
= aWorkBmp
.AcquireReadAccess();
643 const Size
& rPrefSize
= aWorkBmp
.GetPrefSize();
644 const long nWidth
= pAcc
->Width();
645 const long nHeight
= pAcc
->Height();
646 const double fFactorX
= (double) rPrefSize
.Width() / nWidth
;
647 const double fFactorY
= (double) rPrefSize
.Height() / nHeight
;
648 const long nStartX1
= aWorkRect
.Left() + 1L;
649 const long nEndX1
= aWorkRect
.Right();
650 const long nStartX2
= nEndX1
- 1L;
651 // const long nEndX2 = nStartX1 - 1L;
652 const long nStartY1
= aWorkRect
.Top() + 1L;
653 const long nEndY1
= aWorkRect
.Bottom();
654 const long nStartY2
= nEndY1
- 1L;
655 // const long nEndY2 = nStartY1 - 1L;
656 Point
* pPoints1
= NULL
;
657 Point
* pPoints2
= NULL
;
660 const BitmapColor aBlack
= pAcc
->GetBestMatchingColor( Color( COL_BLACK
) );
662 if( nFlags
& XOUTBMP_CONTOUR_VERT
)
664 pPoints1
= new Point
[ nWidth
];
665 pPoints2
= new Point
[ nWidth
];
667 for( nX
= nStartX1
; nX
< nEndX1
; nX
++ )
671 // zunaechst Zeile von Links nach Rechts durchlaufen
674 if( aBlack
== pAcc
->GetPixel( nY
, nX
) )
676 pPoints1
[ nPolyPos
] = Point( nX
, nY
);
679 // diese Schleife wird immer gebreaked da hier ja min. ein Pixel ist
682 if( aBlack
== pAcc
->GetPixel( nY
, nX
) )
684 pPoints2
[ nPolyPos
] = Point( nX
, nY
);
701 pPoints1
= new Point
[ nHeight
];
702 pPoints2
= new Point
[ nHeight
];
704 for ( nY
= nStartY1
; nY
< nEndY1
; nY
++ )
708 // zunaechst Zeile von Links nach Rechts durchlaufen
711 if( aBlack
== pAcc
->GetPixel( nY
, nX
) )
713 pPoints1
[ nPolyPos
] = Point( nX
, nY
);
716 // diese Schleife wird immer gebreaked da hier ja min. ein Pixel ist
719 if( aBlack
== pAcc
->GetPixel( nY
, nX
) )
721 pPoints2
[ nPolyPos
] = Point( nX
, nY
);
737 const USHORT nNewSize1
= nPolyPos
<< 1;
739 aRetPoly
= Polygon( nPolyPos
, pPoints1
);
740 aRetPoly
.SetSize( nNewSize1
+ 1 );
741 aRetPoly
[ nNewSize1
] = aRetPoly
[ 0 ];
743 for( USHORT j
= nPolyPos
; nPolyPos
< nNewSize1
; )
744 aRetPoly
[ nPolyPos
++ ] = pPoints2
[ --j
];
746 if( ( fFactorX
!= 0. ) && ( fFactorY
!= 0. ) )
747 aRetPoly
.Scale( fFactorX
, fFactorY
);
761 BOOL
DitherBitmap( Bitmap
& rBitmap
)
765 if( ( rBitmap
.GetBitCount() >= 8 ) && ( Application::GetDefaultDevice()->GetColorCount() < 257 ) )
766 bRet
= rBitmap
.Dither( BMP_DITHER_FLOYD
);