ooo-build r12026 - in trunk: . patches/dev300 patches/src680



Author: thorstenb
Date: Thu Mar 27 21:52:41 2008
New Revision: 12026
URL: http://svn.gnome.org/viewvc/ooo-build?rev=12026&view=rev

Log:
	* patches/src680/vcl-transparent-printing.diff: fixing a bunch of
	issues and inefficiencies regarding printout of transparent
	content (needs some testing, fragile area)
	* patches/src680/apply: activating the fix for SUSE-11
	* patches/dev300/apply: activating the fix for 3.0 code line



Added:
   trunk/patches/src680/vcl-transparent-printing.diff
Modified:
   trunk/ChangeLog
   trunk/patches/dev300/apply
   trunk/patches/src680/apply

Modified: trunk/patches/dev300/apply
==============================================================================
--- trunk/patches/dev300/apply	(original)
+++ trunk/patches/dev300/apply	Thu Mar 27 21:52:41 2008
@@ -418,6 +418,9 @@
 # screws things up
 userform-scrollleftandtop.diff, i#87007, noelpwer
 
+# adds fixes for printing transparent content
+vcl-transparent-printing.diff, thorsten
+
 [ SELinux ]
 # make OOo work under SELinux
 ooo80816.selinux.bridges.diff, i#80816

Modified: trunk/patches/src680/apply
==============================================================================
--- trunk/patches/src680/apply	(original)
+++ trunk/patches/src680/apply	Thu Mar 27 21:52:41 2008
@@ -48,7 +48,7 @@
 SUSE-10.1 : NovellBase, BerkeleyDB43
 SUSE-10.2 : NovellBase, BerkeleyDB43, EMFPlus
 SUSE-10.3 : NovellBase, BerkeleyDB43, EMFPlus
-SUSE      : NovellBase, BerkeleyDB43, Gcc43, EMFPlus
+SUSE      : NovellBase, BerkeleyDB43, Gcc43, EMFPlus, TransparentPrinting
 SUSE-reduced:NovellBase,BerkeleyDB43, ReducedDefaults
 # Debian
 DebianBase : LinuxCommon, DebianBaseOnly, Lockdown, GCCSTL, CalcSolver, BerkeleyDB43, Split, PostgreSQL
@@ -2080,6 +2080,10 @@
 vcl-grey-alpha-unix-sal-bitmap.diff, rodo
 cairocanvas-alpha-pixmap-rewrite.diff, rodo
 
+[ TransparentPrinting ]
+# adds fixes for printing transparent content
+vcl-transparent-printing.diff, thorsten
+
 [ IntegrateExtensions ]
 scp2_build_extensions.diff
 scp2_makefile_extensions.diff

Added: trunk/patches/src680/vcl-transparent-printing.diff
==============================================================================
--- (empty file)
+++ trunk/patches/src680/vcl-transparent-printing.diff	Thu Mar 27 21:52:41 2008
@@ -0,0 +1,742 @@
+? unxlngx6
+--- vcl/source/gdi/impprn.cxx	14 Jan 2008 16:22:11 -0000	1.16
++++ vcl/source/gdi/impprn.cxx	27 Mar 2008 21:32:18 -0000
+@@ -172,6 +172,16 @@ void ImplQPrinter::ImplPrintMtf( GDIMeta
+                     // execute action here to avoid DPI processing of bitmap;
+                     pAct->Execute( this );
+ 
++#ifdef VERBOSE_DEBUG
++                    Push();
++                    SetLineColor(COL_RED);
++                    SetFillColor();
++                    DrawRect( Rectangle(
++                                  static_cast<MetaBmpScaleAction*>(pAct)->GetPoint(),
++                                  static_cast<MetaBmpScaleAction*>(pAct)->GetSize()) );
++                    Pop();
++#endif
++
+ 					// seek to end of this comment
+ 					do
+ 					{
+--- vcl/source/gdi/print2.cxx	27 Jun 2007 20:22:34 -0000	1.23
++++ vcl/source/gdi/print2.cxx	27 Mar 2008 21:32:18 -0000
+@@ -43,6 +43,8 @@
+ #include <utility>
+ #include <list>
+ #include <vector>
++#include <basegfx/polygon/b2dpolygon.hxx>
++#include <basegfx/polygon/b2dpolygontools.hxx>
+ 
+ #ifndef _DEBUG_HXX
+ #include <tools/debug.hxx>
+@@ -82,11 +84,43 @@
+ #define MAX_TILE_WIDTH  1024
+ #define MAX_TILE_HEIGHT 1024
+ 
++// ---------
++// - Types -
++// ---------
++
++typedef ::std::pair< MetaAction*, int > Component; // MetaAction plus index in metafile
++
++typedef ::std::list< Component > ComponentList;
++
++// List of (intersecting) actions, plus overall bounds
++struct ConnectedComponents
++{
++    ConnectedComponents() : 
++        aComponentList(),
++        aBounds(),
++        aBgColor(COL_WHITE),
++        bIsSpecial(false),
++        bIsFullyTransparent(false)
++    {}
++
++    ComponentList	aComponentList;
++    Rectangle		aBounds;
++    Color           aBgColor;
++    bool			bIsSpecial;
++    bool			bIsFullyTransparent;
++};
++
++typedef ::std::list< ConnectedComponents > ConnectedComponentsList;	
++
++
+ // -----------
+ // - Printer -
+ // -----------
+ 
+-// #i10613# Extracted from Printer::GetPreparedMetaFile
++/** #i10613# Extracted from Printer::GetPreparedMetaFile. Returns true
++    if given action requires special handling (usually because of
++    transparency)
++*/
+ static bool ImplIsActionSpecial( const MetaAction& rAct )
+ {
+     switch( rAct.GetType() )
+@@ -98,99 +132,181 @@ static bool ImplIsActionSpecial( const M
+             return true;
+ 
+         case META_BMPEX_ACTION:
+-            return static_cast<const MetaBmpExAction&>(rAct).GetBitmapEx().IsAlpha() != 0;
++            return static_cast<const MetaBmpExAction&>(rAct).GetBitmapEx().IsTransparent();
+ 
+         case META_BMPEXSCALE_ACTION:
+-            return static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx().IsAlpha() != 0;
++            return static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx().IsTransparent();
+ 
+         case META_BMPEXSCALEPART_ACTION:
+-            return static_cast<const MetaBmpExScalePartAction&>(rAct).GetBitmapEx().IsAlpha() != 0;
++            return static_cast<const MetaBmpExScalePartAction&>(rAct).GetBitmapEx().IsTransparent();
+ 
+         default:
+             return false;
+     }
+ }
+ 
+-// #107169# Check whether given metaaction is a masked bitmap
+-static bool ImplIsActionMaskedBitmap( const MetaAction& rAct )
++/** Check whether rCurrRect rectangle fully covers io_rPrevRect - if
++    yes, return true and update o_rBgColor
++ */
++static bool checkRect( Rectangle&       io_rPrevRect,
++                       Color&           o_rBgColor,
++                       const Rectangle& rCurrRect,
++                       OutputDevice&    rMapModeVDev )
+ {
+-    switch( rAct.GetType() )
+-    {
+-        case META_BMPEX_ACTION:
+-            return static_cast<const MetaBmpExAction&>(rAct).GetBitmapEx().IsAlpha() == 0;
+-            
+-        case META_BMPEXSCALE_ACTION:
+-            return static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx().IsAlpha() == 0;
++    // shape needs to fully cover previous content, and have uniform
++    // color
++    const bool bRet( 
++        rMapModeVDev.LogicToPixel(rCurrRect).IsInside(io_rPrevRect) &&
++        rMapModeVDev.IsFillColor() );
+ 
+-        case META_BMPEXSCALEPART_ACTION:
+-            return static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx().IsAlpha() == 0;
+-
+-        default:
+-            return false;
++    if( bRet )
++    {
++        io_rPrevRect = rCurrRect;
++        o_rBgColor = rMapModeVDev.GetFillColor();
+     }
++    
++    return bRet;
+ }
+ 
+-// #107169# Convert BitmapEx with mask to Bitmap with white background at masked-out places
+-static Bitmap ImplConvertBmpEx2Bmp( const MetaAction& rAct )
++/** #107169# Convert BitmapEx to Bitmap with appropriately blended
++    color. Convert MetaTransparentAction to plain polygon,
++    appropriately colored
++
++    @param o_rMtf
++    Add converted actions to this metafile
++*/
++static void ImplConvertTransparentAction( GDIMetaFile&        o_rMtf,
++                                          const MetaAction&   rAct,
++                                          const OutputDevice& rStateOutDev,
++                                          Color               aBgColor )
+ {
+-    BitmapEx aBmpEx;
+-
+-    switch( rAct.GetType() )
++    if( rAct.GetType() == META_TRANSPARENT_ACTION )
+     {
+-        case META_BMPEX_ACTION:
+-            aBmpEx = static_cast<const MetaBmpExAction&>(rAct).GetBitmapEx();
+-            break;
+-            
+-        case META_BMPEXSCALE_ACTION:
+-            aBmpEx = static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx();
+-            break;
++        const MetaTransparentAction* pTransAct = static_cast<const MetaTransparentAction*>(&rAct);
++        USHORT				         nTransparency( pTransAct->GetTransparence() );
+ 
+-        case META_BMPEXSCALEPART_ACTION:
+-            aBmpEx = static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx();
+-            break;
++        // #i10613# Respect transparency for draw color
++        if( nTransparency )
++        {
++            o_rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR|PUSH_FILLCOLOR ) );
+ 
+-        default:
+-            DBG_ERROR("Printer::GetPreparedMetafile impossible state reached");
+-            break;
++            // assume white background for alpha blending
++            Color aLineColor( rStateOutDev.GetLineColor() );
++            aLineColor.SetRed( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aLineColor.GetRed()) / 100L ) );
++            aLineColor.SetGreen( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aLineColor.GetGreen()) / 100L ) );
++            aLineColor.SetBlue( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aLineColor.GetBlue()) / 100L ) );
++            o_rMtf.AddAction( new MetaLineColorAction(aLineColor, TRUE) );
++
++            Color aFillColor( rStateOutDev.GetFillColor() );
++            aFillColor.SetRed( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aFillColor.GetRed()) / 100L ) );
++            aFillColor.SetGreen( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aFillColor.GetGreen()) / 100L ) );
++            aFillColor.SetBlue( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aFillColor.GetBlue()) / 100L ) );
++            o_rMtf.AddAction( new MetaFillColorAction(aFillColor, TRUE) );
++        }
++
++        o_rMtf.AddAction( new MetaPolyPolygonAction(pTransAct->GetPolyPolygon()) );
++
++        if( nTransparency )
++            o_rMtf.AddAction( new MetaPopAction() );
+     }
++    else
++    {
++        BitmapEx aBmpEx;
++
++        switch( rAct.GetType() )
++        {
++            case META_BMPEX_ACTION:
++                aBmpEx = static_cast<const MetaBmpExAction&>(rAct).GetBitmapEx();
++                break;
++            
++            case META_BMPEXSCALE_ACTION:
++                aBmpEx = static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx();
++                break;
++
++            case META_BMPEXSCALEPART_ACTION:
++                aBmpEx = static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx();
++                break;
++
++            case META_TRANSPARENT_ACTION:
++
++            default:
++                DBG_ERROR("Printer::GetPreparedMetafile impossible state reached");
++                break;
++        }
+ 
+-    Bitmap			  aBmp( aBmpEx.GetBitmap() );
+-    BitmapReadAccess* pRA = aBmp.AcquireReadAccess();
++        Bitmap aBmp( aBmpEx.GetBitmap() );
++        if( !aBmpEx.IsAlpha() )
++        {
++            // blend with mask
++            BitmapReadAccess* pRA = aBmp.AcquireReadAccess();
+ 
+-    if( !pRA )
+-        return aBmp; // what else should I do?
++            if( !pRA )
++                return; // what else should I do?
+ 
+-    Color aWhite( COL_WHITE );
++            Color aActualColor( aBgColor );
+ 
+-    if( pRA->HasPalette() )
+-        aWhite = pRA->GetBestPaletteColor( Color( COL_WHITE ) ).operator Color();
++            if( pRA->HasPalette() )
++                aActualColor = pRA->GetBestPaletteColor( aBgColor ).operator Color();
+     
+-    aBmp.ReleaseAccess(pRA);
++            aBmp.ReleaseAccess(pRA);
+ 
+-    // did we get true white?
+-    if( aWhite.GetColorError( Color( COL_WHITE ) ) )
+-    {
+-        // no, create truecolor bitmap, then
+-        aBmp.Convert( BMP_CONVERSION_24BIT );
++            // did we get true white?
++            if( aActualColor.GetColorError( aBgColor ) )
++            {
++                // no, create truecolor bitmap, then
++                aBmp.Convert( BMP_CONVERSION_24BIT );
+ 
+-        // fill masked out areas white
+-        aBmp.Replace( aBmpEx.GetMask(), COL_WHITE );
+-    }
+-    else
+-    {
+-        // fill masked out areas white
+-        aBmp.Replace( aBmpEx.GetMask(), aWhite );
+-    }
++                // fill masked out areas white
++                aBmp.Replace( aBmpEx.GetMask(), aBgColor );
++            }
++            else
++            {
++                // fill masked out areas white
++                aBmp.Replace( aBmpEx.GetMask(), aActualColor );
++            }
++        }
++        else
++        {
++            // blend with alpha channel
++            aBmp.Convert( BMP_CONVERSION_24BIT );
++            aBmp.Blend(aBmpEx.GetAlpha(),aBgColor);
++        }
+ 
+-    return aBmp;
++        // add corresponding action
++        switch( rAct.GetType() )
++        {
++            case META_BMPEX_ACTION:
++                o_rMtf.AddAction( new MetaBmpAction( 
++                                       static_cast<const MetaBmpExAction&>(rAct).GetPoint(), 
++                                       aBmp ));
++                break;
++            case META_BMPEXSCALE_ACTION:
++                o_rMtf.AddAction( new MetaBmpScaleAction( 
++                                       static_cast<const MetaBmpExScaleAction&>(rAct).GetPoint(), 
++                                       static_cast<const MetaBmpExScaleAction&>(rAct).GetSize(), 
++                                       aBmp ));
++                break;
++            case META_BMPEXSCALEPART_ACTION:
++                o_rMtf.AddAction( new MetaBmpScalePartAction( 
++                                       static_cast<const MetaBmpExScalePartAction&>(rAct).GetDestPoint(), 
++                                       static_cast<const MetaBmpExScalePartAction&>(rAct).GetDestSize(), 
++                                       static_cast<const MetaBmpExScalePartAction&>(rAct).GetSrcPoint(), 
++                                       static_cast<const MetaBmpExScalePartAction&>(rAct).GetSrcSize(), 
++                                       aBmp ));
++                break;
++            default:
++                DBG_ERROR("Unexpected case");
++                break;
++        }
++    }
+ }
+ 
+ // #i10613# Extracted from ImplCheckRect::ImplCreate
+ // Returns true, if given action creates visible (i.e. non-transparent) output
+ static bool ImplIsNotTransparent( const MetaAction& rAct, const OutputDevice& rOut )
+ {
+-    const bool	bLineTransparency( rOut.GetLineColor().GetTransparency() == 255 );
+-    const bool 	bFillTransparency( rOut.GetFillColor().GetTransparency() == 255 );
++    const bool	bLineTransparency( rOut.IsLineColor() ? rOut.GetLineColor().GetTransparency() == 255 : true );
++    const bool 	bFillTransparency( rOut.IsFillColor() ? rOut.GetFillColor().GetTransparency() == 255 : true );
+     bool		bRet( false );
+ 
+ 	switch( rAct.GetType() )
+@@ -552,35 +668,7 @@ static bool ImplIsActionHandlingTranspar
+     }
+ }
+ 
+-// predicate functor for checking whether given element is fully transparent
+-class Impl_IsTransparent : public ::std::unary_function< ::std::pair< const MetaAction*, int >, bool >
+-{
+-public:
+-    Impl_IsTransparent( const OutputDevice& rOut ) : mrOut(rOut) {}
+-    bool operator()( ::std::pair< const MetaAction*, int > rElem ) 
+-    {
+-        return !ImplIsNotTransparent( *rElem.first, mrOut );
+-    }
+-
+-private:
+-    const OutputDevice& mrOut;
+-};
+-
+-typedef ::std::pair< const MetaAction*, int > Component; // MetaAction plus index in metafile
+-
+-// List of (intersecting) actions, plus overall bounds
+-struct ConnectedComponents
+-{
+-    ::std::list< Component >	aComponentList;
+-    Rectangle					aBounds;
+-    bool						bIsSpecial;
+-    bool						bIsFullyTransparent;
+-};
+-
+-typedef ::std::list< ConnectedComponents > ConnectedComponentsList;	
+-
+ // remove comment to enable highlighting of generated output
+-
+ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutMtf, 
+                                    long nMaxBmpDPIX, long nMaxBmpDPIY )
+ {
+@@ -607,8 +695,7 @@ void Printer::GetPreparedMetaFile( const
+             // of uniform opacity): if a masked bitmap is printed over
+             // empty background, we convert to a plain bitmap with
+             // white background.
+-            if( ImplIsActionMaskedBitmap( *pCurrAct ) ||
+-                ImplIsActionSpecial( *pCurrAct ) )
++            if( ImplIsActionSpecial( *pCurrAct ) )
+             {
+                 bTransparent = true;
+             }
+@@ -650,8 +737,14 @@ void Printer::GetPreparedMetaFile( const
+         // algorithm was designed by AF.
+         //
+ 
+-        ConnectedComponentsList	aCCList; 	  	// list containing distinct sets of connected components as elements. 
+-        int						nActionNum;		
++        //
++        //  STAGE 1: Detect background
++        //  ==========================
++        //
++
++        // Receives uniform background content, and is _not_ merged
++        // nor checked for intersection against other aCCList elements
++        ConnectedComponents aBackgroundComponent;
+ 
+         // create an OutputDevice to record mapmode changes and the like
+ 		VirtualDevice aMapModeVDev;
+@@ -659,21 +752,140 @@ void Printer::GetPreparedMetaFile( const
+ 		aMapModeVDev.mnDPIY = mnDPIY;
+ 		aMapModeVDev.EnableOutput(FALSE);
+ 
++        int nLastBgAction, nActionNum;
++
++        // weed out page-filling background objects (if they are
++        // uniformly coloured). Keeping them outside the other
++        // connected components often prevents whole-page bitmap
++        // generation.
++        bool bStillBackground=true; // true until first non-bg action
++        nActionNum=0; nLastBgAction=-1;
++		pCurrAct=const_cast<GDIMetaFile&>(rInMtf).FirstAction();
++		while( pCurrAct && bStillBackground )
++		{
++            switch( pCurrAct->GetType() )
++            {
++                case META_RECT_ACTION:
++                {
++                    if( !checkRect(
++                            aBackgroundComponent.aBounds,
++                            aBackgroundComponent.aBgColor,
++                            static_cast<const MetaRectAction*>(pCurrAct)->GetRect(),
++                            aMapModeVDev) )
++                        bStillBackground=false; // incomplete occlusion of background
++                    else
++                        nLastBgAction=nActionNum; // this _is_ background
++                    break;
++                }
++                case META_POLYGON_ACTION:
++                {
++                    const Polygon aPoly(
++                        static_cast<const MetaPolygonAction*>(pCurrAct)->GetPolygon());
++                    if( !basegfx::tools::isRectangle(
++                            aPoly.getB2DPolygon()) ||
++                        !checkRect(
++                            aBackgroundComponent.aBounds,
++                            aBackgroundComponent.aBgColor,
++                            aPoly.GetBoundRect(),
++                            aMapModeVDev) )
++                        bStillBackground=false; // incomplete occlusion of background
++                    else
++                        nLastBgAction=nActionNum; // this _is_ background
++                    break;
++                }
++                case META_POLYPOLYGON_ACTION:
++                {
++                    const PolyPolygon aPoly(
++                        static_cast<const MetaPolyPolygonAction*>(pCurrAct)->GetPolyPolygon());
++                    if( aPoly.Count() != 1 ||
++                        !basegfx::tools::isRectangle(
++                            aPoly[0].getB2DPolygon()) ||
++                        !checkRect(
++                            aBackgroundComponent.aBounds,
++                            aBackgroundComponent.aBgColor,
++                            aPoly.GetBoundRect(),
++                            aMapModeVDev) )
++                        bStillBackground=false; // incomplete occlusion of background
++                    else
++                        nLastBgAction=nActionNum; // this _is_ background
++                    break;
++                }
++                case META_WALLPAPER_ACTION:
++                {
++                    if( !checkRect(
++                            aBackgroundComponent.aBounds,
++                            aBackgroundComponent.aBgColor,
++                            static_cast<const MetaWallpaperAction*>(pCurrAct)->GetRect(),
++                            aMapModeVDev) )
++                        bStillBackground=false; // incomplete occlusion of background
++                    else
++                        nLastBgAction=nActionNum; // this _is_ background
++                    break;
++                }
++                default:
++                {
++                    if( ImplIsNotTransparent( *pCurrAct,
++                                              aMapModeVDev ) )
++                        bStillBackground=false; // non-transparent action, possibly
++                                                // not uniform
++                    else
++                        // extend current bounds (next uniform action
++                        // needs to fully cover this area)
++                        aBackgroundComponent.aBounds.Union(
++                            ImplCalcActionBounds(*pCurrAct, aMapModeVDev) );
++                    break;
++                }
++            }
++
++            // execute action to get correct MapModes etc.
++            pCurrAct->Execute( &aMapModeVDev );
++            
++            pCurrAct=const_cast<GDIMetaFile&>(rInMtf).NextAction();
++            ++nActionNum;
++        }
++
++        ConnectedComponentsList	aCCList; // list containing distinct sets of connected components as elements. 
++
++        // create an OutputDevice to record mapmode changes and the like
++		VirtualDevice aMapModeVDev2;
++		aMapModeVDev2.mnDPIX = mnDPIX;
++		aMapModeVDev2.mnDPIY = mnDPIY;
++		aMapModeVDev2.EnableOutput(FALSE);
++
++        // fast-forward until one after the last background action
++        // (need to reconstruct map mode vdev state)
++        nActionNum=0;
++		pCurrAct=const_cast<GDIMetaFile&>(rInMtf).FirstAction();
++		while( pCurrAct && nActionNum<=nLastBgAction )
++		{
++            // up to and including last ink-generating background
++            // action go to background component
++            aBackgroundComponent.aComponentList.push_back( 
++                ::std::make_pair(
++                    pCurrAct, nActionNum) );
++
++			// execute action to get correct MapModes etc.
++			pCurrAct->Execute( &aMapModeVDev2 );
++            pCurrAct=const_cast<GDIMetaFile&>(rInMtf).NextAction();
++            ++nActionNum;
++        }
++
+         //
+-        //  STAGE 1: Generate connected components list
++        //  STAGE 2: Generate connected components list
+         //  ===========================================
+         //
+ 
+-        // iterate over all actions
+-		for( pCurrAct=const_cast<GDIMetaFile&>(rInMtf).FirstAction(), nActionNum=0; 
++        // iterate over all actions (start where background action
++        // search left off)
++		for( ; 
+              pCurrAct; 
+              pCurrAct=const_cast<GDIMetaFile&>(rInMtf).NextAction(), ++nActionNum )
+ 		{
+ 			// execute action to get correct MapModes etc.
+-			pCurrAct->Execute( &aMapModeVDev );
++			pCurrAct->Execute( &aMapModeVDev2 );
+ 
+             // cache bounds of current action 
+-            const Rectangle aBBCurrAct( ImplCalcActionBounds(*pCurrAct, aMapModeVDev) );
++            const Rectangle aBBCurrAct( ImplCalcActionBounds(*pCurrAct, aMapModeVDev2) );
+ 
+             // accumulate collected bounds here, initialize with current action
+             Rectangle								aTotalBounds( aBBCurrAct ); // thus,
+@@ -687,7 +899,7 @@ void Printer::GetPreparedMetaFile( const
+             ConnectedComponents						aTotalComponents;
+ 
+             //
+-            //  STAGE 1.1: Search for intersecting cc entries
++            //  STAGE 2.1: Search for intersecting cc entries
+             //  =============================================
+             //
+ 
+@@ -695,18 +907,33 @@ void Printer::GetPreparedMetaFile( const
+             // aCCList member. Thus, we can safe us the check.
+             // Furthermore, this ensures that non-output-generating
+             // actions get their own aCCList entry, which is necessary
+-            // when copying them to the output metafile (see stage 3
++            // when copying them to the output metafile (see stage 4
+             // below).
+ 
+             // #107169# Wholly transparent objects need
+             // not be considered for connected components,
+             // too. Just put each of them into a separate
+             // component.
+-            aTotalComponents.bIsFullyTransparent = !ImplIsNotTransparent(*pCurrAct, aMapModeVDev);
++            aTotalComponents.bIsFullyTransparent = !ImplIsNotTransparent(*pCurrAct, aMapModeVDev2);
+ 
+             if( !aBBCurrAct.IsEmpty() &&        
+                 !aTotalComponents.bIsFullyTransparent )
+             {
++                if( !aBackgroundComponent.aComponentList.empty() &&
++                    !aBackgroundComponent.aBounds.IsInside(aTotalBounds) )
++                {
++                    // it seems the background is not large enough. to
++                    // be on the safe side, combine with this component.
++                    aTotalBounds.Union( aBackgroundComponent.aBounds );
++                        
++                    // extract all aCurr actions to aTotalComponents
++                    aTotalComponents.aComponentList.splice( aTotalComponents.aComponentList.end(), 
++                                                            aBackgroundComponent.aComponentList );
++                        
++                    if( aBackgroundComponent.bIsSpecial )
++                        bTreatSpecial = true;
++                }
++
+                 ConnectedComponentsList::iterator 		aCurrCC;
+                 const ConnectedComponentsList::iterator aLastCC( aCCList.end() );
+                 bool									bSomeComponentsChanged;
+@@ -767,7 +994,7 @@ void Printer::GetPreparedMetaFile( const
+             }
+ 
+             //
+-            //  STAGE 1.2: Determine special state for cc element
++            //  STAGE 2.2: Determine special state for cc element
+             //  =================================================
+             //
+ 
+@@ -816,7 +1043,7 @@ void Printer::GetPreparedMetaFile( const
+                     // check whether we're on white background
+                     if( aTotalComponents.aComponentList.empty() )
+                     {
+-                        // nothing between pCurrAct and empty page
++                        // nothing between pCurrAct and page
+                         // background -> don't be special
+                         aTotalComponents.bIsSpecial = false;
+                     }
+@@ -838,14 +1065,15 @@ void Printer::GetPreparedMetaFile( const
+ 
+ 
+             //
+-            //  STAGE 1.3: Add newly generated CC list element
++            //  STAGE 2.3: Add newly generated CC list element
+             //  ==============================================
+             //
+ 
+             // set new bounds and add action to list
+             aTotalComponents.aBounds = aTotalBounds;
+-            aTotalComponents.aComponentList.push_back( ::std::make_pair(
+-                        const_cast<const MetaAction*>(pCurrAct), nActionNum) );
++            aTotalComponents.aComponentList.push_back( 
++                ::std::make_pair(
++                    pCurrAct, nActionNum) );
+ 
+             // add aTotalComponents as a new entry to aCCList
+             aCCList.push_back( aTotalComponents );
+@@ -871,23 +1099,38 @@ void Printer::GetPreparedMetaFile( const
+ 
+         // maps mtf actions to CC list entries
+         ::std::vector< const ConnectedComponents* > aCCList_MemberMap( rInMtf.GetActionCount() );
+-        
++
+         // iterate over all aCCList members and their contained metaactions
+         ConnectedComponentsList::iterator 		aCurr( aCCList.begin() );
+         const ConnectedComponentsList::iterator aLast( aCCList.end() );
+         for( ; aCurr != aLast; ++aCurr )
+         {
+-            ::std::list< Component >::iterator			aCurrAct( aCurr->aComponentList.begin() );
+-            const ::std::list< Component >::iterator	aLastAct( aCurr->aComponentList.end() );
+-            for( ; aCurrAct != aLastAct; ++aCurrAct )
++            ComponentList::iterator		  aCurrentAction( aCurr->aComponentList.begin() );
++            const ComponentList::iterator aLastAction( aCurr->aComponentList.end() );
++            for( ; aCurrentAction != aLastAction; ++aCurrentAction )
+             {
+                 // set pointer to aCCList element for corresponding index
+-                aCCList_MemberMap[ aCurrAct->second ] = &(*aCurr);
++                aCCList_MemberMap[ aCurrentAction->second ] = &(*aCurr);
+             }
+         }
+ 
+         //
+-        //  STAGE 2: Generate banded bitmaps for special regions
++        //  STAGE 3.1: Output background mtf actions (if there are any)
++        //  ===========================================================
++        //
++
++        ComponentList::iterator		  aCurrAct( aBackgroundComponent.aComponentList.begin() );
++        const ComponentList::iterator aLastAct( aBackgroundComponent.aComponentList.end() );
++        for( ; aCurrAct != aLastAct; ++aCurrAct )
++        {
++            // simply add this action (above, we inserted the actions
++            // starting at index 0 up to and including nLastBgAction)
++            rOutMtf.AddAction( ( aCurrAct->first->Duplicate(), aCurrAct->first ) );
++        }
++
++
++        //
++        //  STAGE 3.2: Generate banded bitmaps for special regions
+         //  ====================================================
+         //
+ 
+@@ -1039,10 +1282,17 @@ void Printer::GetPreparedMetaFile( const
+         }
+ 
+         //
+-        //  STAGE 3: Copy actions to output metafile
++        //  STAGE 4: Copy actions to output metafile
+         //  ========================================
+         //
+ 
++        // create an OutputDevice to record color settings, mapmode
++        // changes and the like
++		VirtualDevice aMapModeVDev3;
++		aMapModeVDev3.mnDPIX = mnDPIX;
++		aMapModeVDev3.mnDPIY = mnDPIY;
++		aMapModeVDev3.EnableOutput(FALSE);
++
+         // iterate over all actions and duplicate the ones not in a
+         // special aCCList member into rOutMtf
+         for( pCurrAct=const_cast<GDIMetaFile&>(rInMtf).FirstAction(), nActionNum=0; 
+@@ -1053,57 +1303,33 @@ void Printer::GetPreparedMetaFile( const
+ 
+             // NOTE: This relies on the fact that map-mode or draw
+             // mode changing actions are solitary aCCList elements and
+-            // have empty bounding boxes, see comment on stage 1.1
++            // have empty bounding boxes, see comment on stage 2.1
+             // above
+             if( pCurrAssociatedComponent &&
+                 (pCurrAssociatedComponent->aBounds.IsEmpty() ||
+                  !pCurrAssociatedComponent->bIsSpecial) )
+             {
+-                // #107169# Treat masked bitmaps special, if they are
+-                // the first (or sole) action in their bounds
++                // #107169# Treat transparent bitmaps special, if they
++                // are the first (or sole) action in their bounds
+                 // list. Note that we previously ensured that no
+                 // fully-transparent objects are before us here.
+-                if( ImplIsActionMaskedBitmap( *pCurrAct ) &&
++                if( ImplIsActionHandlingTransparency( *pCurrAct ) &&
+                     pCurrAssociatedComponent->aComponentList.begin()->first == pCurrAct )
+                 {
+-                    // convert to plain Bitmap, where masked-out parts are white
+-                    Bitmap aBmp( ImplConvertBmpEx2Bmp(*pCurrAct) );
+-
+-                    // add corresponding action
+-                    switch( pCurrAct->GetType() )
+-                    {
+-                        case META_BMPEX_ACTION:
+-                            rOutMtf.AddAction( new MetaBmpExAction( 
+-                                                   static_cast<const MetaBmpExAction*>(pCurrAct)->GetPoint(), 
+-                                                   aBmp ) );
+-                            break;
+-            
+-                        case META_BMPEXSCALE_ACTION:
+-                            rOutMtf.AddAction( new MetaBmpExScaleAction( 
+-                                                   static_cast<const MetaBmpExScaleAction*>(pCurrAct)->GetPoint(), 
+-                                                   static_cast<const MetaBmpExScaleAction*>(pCurrAct)->GetSize(), 
+-                                                   aBmp ) );
+-                            break;
+-
+-                        case META_BMPEXSCALEPART_ACTION:
+-                            rOutMtf.AddAction( new MetaBmpExScalePartAction( 
+-                                                   static_cast<const MetaBmpExScalePartAction*>(pCurrAct)->GetDestPoint(), 
+-                                                   static_cast<const MetaBmpExScalePartAction*>(pCurrAct)->GetDestSize(), 
+-                                                   static_cast<const MetaBmpExScalePartAction*>(pCurrAct)->GetSrcPoint(), 
+-                                                   static_cast<const MetaBmpExScalePartAction*>(pCurrAct)->GetSrcSize(), 
+-                                                   aBmp ) );
+-                            break;
+-
+-                        default:
+-                            DBG_ERROR("Printer::GetPreparedMetafile impossible state reached");
+-                            break;
+-                    }
++                    // convert actions, where masked-out parts are of
++                    // given background color
++                    ImplConvertTransparentAction(rOutMtf,
++                                                 *pCurrAct,
++                                                 aMapModeVDev3,
++                                                 aBackgroundComponent.aBgColor);
+                 }
+                 else
+                 {
+                     // simply add this action
+                     rOutMtf.AddAction( ( pCurrAct->Duplicate(), pCurrAct ) );
+                 }
++
++                pCurrAct->Execute(&aMapModeVDev3);
+             }
+         }
+ 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]