summaryrefslogtreecommitdiff
path: root/vcl/source/gdi/print2.cxx
diff options
context:
space:
mode:
authorVladimir Glazounov <vg@openoffice.org>2008-10-01 13:31:44 +0000
committerVladimir Glazounov <vg@openoffice.org>2008-10-01 13:31:44 +0000
commit46a63a2af38e694327c5308168f499a549fb724e (patch)
tree6e80cfea121ed9231141a56153e9208f553863cb /vcl/source/gdi/print2.cxx
parent248539e2fa8ac0f5271a83f26fe71d0dcc4a5a67 (diff)
CWS-TOOLING: integrate CWS vcl92
Diffstat (limited to 'vcl/source/gdi/print2.cxx')
-rw-r--r--vcl/source/gdi/print2.cxx577
1 files changed, 409 insertions, 168 deletions
diff --git a/vcl/source/gdi/print2.cxx b/vcl/source/gdi/print2.cxx
index e0764595583d..685f68fe7af3 100644
--- a/vcl/source/gdi/print2.cxx
+++ b/vcl/source/gdi/print2.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: print2.cxx,v $
- * $Revision: 1.24 $
+ * $Revision: 1.24.86.3 $
*
* This file is part of OpenOffice.org.
*
@@ -38,6 +38,8 @@
#include <utility>
#include <list>
#include <vector>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
#include <tools/debug.hxx>
#include <vcl/virdev.hxx>
#include <vcl/metaact.hxx>
@@ -49,6 +51,8 @@
#include <vcl/sallayout.hxx>
#include <vcl/bmpacc.hxx>
+#include "pdfwriter_impl.hxx"
+
// -----------
// - Defines -
// -----------
@@ -56,11 +60,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() )
@@ -72,99 +108,181 @@ static bool ImplIsActionSpecial( const MetaAction& rAct )
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;
+ const MetaTransparentAction* pTransAct = static_cast<const MetaTransparentAction*>(&rAct);
+ USHORT nTransparency( pTransAct->GetTransparence() );
- case META_BMPEXSCALE_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 ) );
+
+ // 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) );
+ }
- case META_BMPEXSCALEPART_ACTION:
- aBmpEx = static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx();
- break;
+ o_rMtf.AddAction( new MetaPolyPolygonAction(pTransAct->GetPolyPolygon()) );
- default:
- DBG_ERROR("Printer::GetPreparedMetafile impossible state reached");
- break;
+ if( nTransparency )
+ o_rMtf.AddAction( new MetaPopAction() );
}
+ else
+ {
+ BitmapEx aBmpEx;
- Bitmap aBmp( aBmpEx.GetBitmap() );
- BitmapReadAccess* pRA = aBmp.AcquireReadAccess();
+ switch( rAct.GetType() )
+ {
+ case META_BMPEX_ACTION:
+ aBmpEx = static_cast<const MetaBmpExAction&>(rAct).GetBitmapEx();
+ break;
- if( !pRA )
- return aBmp; // what else should I do?
+ case META_BMPEXSCALE_ACTION:
+ aBmpEx = static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx();
+ break;
- Color aWhite( COL_WHITE );
+ case META_BMPEXSCALEPART_ACTION:
+ aBmpEx = static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx();
+ break;
- if( pRA->HasPalette() )
- aWhite = pRA->GetBestPaletteColor( Color( COL_WHITE ) ).operator Color();
+ case META_TRANSPARENT_ACTION:
- aBmp.ReleaseAccess(pRA);
+ default:
+ DBG_ERROR("Printer::GetPreparedMetafile impossible state reached");
+ break;
+ }
- // did we get true white?
- if( aWhite.GetColorError( Color( COL_WHITE ) ) )
- {
- // no, create truecolor bitmap, then
- aBmp.Convert( BMP_CONVERSION_24BIT );
+ Bitmap aBmp( aBmpEx.GetBitmap() );
+ if( !aBmpEx.IsAlpha() )
+ {
+ // blend with mask
+ BitmapReadAccess* pRA = aBmp.AcquireReadAccess();
- // fill masked out areas white
- aBmp.Replace( aBmpEx.GetMask(), COL_WHITE );
- }
- else
- {
- // fill masked out areas white
- aBmp.Replace( aBmpEx.GetMask(), aWhite );
- }
+ if( !pRA )
+ return; // what else should I do?
- return aBmp;
+ Color aActualColor( aBgColor );
+
+ if( pRA->HasPalette() )
+ aActualColor = pRA->GetBestPaletteColor( aBgColor ).operator Color();
+
+ aBmp.ReleaseAccess(pRA);
+
+ // 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(), 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);
+ }
+
+ // 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() )
@@ -526,46 +644,18 @@ static bool ImplIsActionHandlingTransparency( const MetaAction& rAct )
}
}
-// 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 )
+bool OutputDevice::RemoveTransparenciesFromMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutMtf,
+ long nMaxBmpDPIX, long nMaxBmpDPIY,
+ bool bReduceTransparency, bool bTransparencyAutoMode,
+ bool bDownsampleBitmaps )
{
- const PrinterOptions& rPrinterOptions = GetPrinterOptions();
MetaAction* pCurrAct;
bool bTransparent( false );
rOutMtf.Clear();
- if( !rPrinterOptions.IsReduceTransparency() ||
- ( PRINTER_TRANSPARENCY_AUTO == rPrinterOptions.GetReducedTransparencyMode() ) )
+ if( ! bReduceTransparency || bTransparencyAutoMode )
{
// watch for transparent drawing actions
for( pCurrAct = ( (GDIMetaFile&) rInMtf ).FirstAction();
@@ -581,8 +671,7 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
// 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;
}
@@ -624,8 +713,14 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
// 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;
@@ -633,21 +728,140 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
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,
@@ -661,7 +875,7 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
ConnectedComponents aTotalComponents;
//
- // STAGE 1.1: Search for intersecting cc entries
+ // STAGE 2.1: Search for intersecting cc entries
// =============================================
//
@@ -669,18 +883,33 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
// 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;
@@ -741,7 +970,7 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
}
//
- // STAGE 1.2: Determine special state for cc element
+ // STAGE 2.2: Determine special state for cc element
// =================================================
//
@@ -790,7 +1019,7 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
// 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;
}
@@ -812,14 +1041,15 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
//
- // 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 );
@@ -851,22 +1081,47 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
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
// ====================================================
//
Point aTmpPoint;
- const Rectangle aOutputRect( aTmpPoint, GetOutputSizePixel() );
+ Size aTmpSize( GetOutputSizePixel() );
+ if( mpPDFWriter )
+ {
+ aTmpSize = mpPDFWriter->getCurPageSize();
+ aTmpSize = LogicToPixel( aTmpSize, MapMode( MAP_POINT ) );
+
+ // also add error code to PDFWriter
+ mpPDFWriter->insertError( vcl::PDFWriter::Warning_Transparency_Converted );
+ }
+ const Rectangle aOutputRect( aTmpPoint, aTmpSize );
+ bool bTiling = dynamic_cast<Printer*>(this) != NULL;
// iterate over all aCCList members and generate bitmaps for the special ones
for( aCurr = aCCList.begin(); aCurr != aLast; ++aCurr )
@@ -880,9 +1135,7 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
const double fOutArea( (double) aOutputRect.GetWidth() * aOutputRect.GetHeight() );
// check if output doesn't exceed given size
- if( rPrinterOptions.IsReduceTransparency() &&
- ( PRINTER_TRANSPARENCY_AUTO == rPrinterOptions.GetReducedTransparencyMode() ) &&
- ( fBmpArea > ( 0.25 * fOutArea ) ) )
+ if( bReduceTransparency && bTransparencyAutoMode && ( fBmpArea > ( 0.25 * fOutArea ) ) )
{
// output normally. Therefore, we simply clear the
// special attribute, as everything non-special is
@@ -910,7 +1163,7 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
while( aDstPtPix.Y() <= aBoundRect.Bottom() )
{
aDstPtPix.X() = aBoundRect.Left();
- aDstSzPix = Size( MAX_TILE_WIDTH, MAX_TILE_HEIGHT );
+ aDstSzPix = bTiling ? Size( MAX_TILE_WIDTH, MAX_TILE_HEIGHT ) : aBoundRect.GetSize();
if( ( aDstPtPix.Y() + aDstSzPix.Height() - 1L ) > aBoundRect.Bottom() )
aDstSzPix.Height() = aBoundRect.Bottom() - aDstPtPix.Y() + 1L;
@@ -964,7 +1217,11 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
else if( META_GRADIENT_ACTION == nType )
{
MetaGradientAction* pGradientAction = static_cast<MetaGradientAction*>(pCurrAct);
- DrawGradientEx( &aPaintVDev, pGradientAction->GetRect(), pGradientAction->GetGradient() );
+ Printer* pPrinter = dynamic_cast< Printer* >(this);
+ if( pPrinter )
+ pPrinter->DrawGradientEx( &aPaintVDev, pGradientAction->GetRect(), pGradientAction->GetGradient() );
+ else
+ DrawGradient( pGradientAction->GetRect(), pGradientAction->GetGradient() );
}
else
{
@@ -981,11 +1238,11 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
Bitmap aBandBmp( aPaintVDev.GetBitmap( Point(), aDstSzPix ) );
// scale down bitmap, if requested
- if( rPrinterOptions.IsReduceBitmaps() && rPrinterOptions.IsReducedBitmapIncludesTransparency() )
+ if( bDownsampleBitmaps )
{
- aBandBmp = GetPreparedBitmap( aDstSzPix,
- Point(), aBandBmp.GetSizePixel(),
- aBandBmp, nMaxBmpDPIX, nMaxBmpDPIY );
+ aBandBmp = GetDownsampledBitmap( aDstSzPix,
+ Point(), aBandBmp.GetSizePixel(),
+ aBandBmp, nMaxBmpDPIX, nMaxBmpDPIY );
}
rOutMtf.AddAction( new MetaCommentAction( "PRNSPOOL_TRANSPARENTBITMAP_BEGIN" ) );
@@ -1013,10 +1270,17 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
}
//
- // 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;
@@ -1027,70 +1291,47 @@ void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutM
// 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);
}
}
rOutMtf.SetPrefMapMode( rInMtf.GetPrefMapMode() );
rOutMtf.SetPrefSize( rInMtf.GetPrefSize() );
}
+ return bTransparent;
}
// -----------------------------------------------------------------------------
-Bitmap Printer::GetPreparedBitmap( const Size& rDstSz,
- const Point& rSrcPt, const Size& rSrcSz,
- const Bitmap& rBmp, long nMaxBmpDPIX, long nMaxBmpDPIY )
+Bitmap OutputDevice::GetDownsampledBitmap( const Size& rDstSz,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Bitmap& rBmp, long nMaxBmpDPIX, long nMaxBmpDPIY )
{
Bitmap aBmp( rBmp );
@@ -1157,9 +1398,9 @@ Bitmap Printer::GetPreparedBitmap( const Size& rDstSz,
// -----------------------------------------------------------------------------
-BitmapEx Printer::GetPreparedBitmapEx( const Size& rDstSz,
- const Point& rSrcPt, const Size& rSrcSz,
- const BitmapEx& rBmpEx, long nMaxBmpDPIX, long nMaxBmpDPIY )
+BitmapEx OutputDevice::GetDownsampledBitmapEx( const Size& rDstSz,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const BitmapEx& rBmpEx, long nMaxBmpDPIX, long nMaxBmpDPIY )
{
BitmapEx aBmpEx( rBmpEx );