summaryrefslogtreecommitdiff
path: root/goodies/source/graphic
diff options
context:
space:
mode:
Diffstat (limited to 'goodies/source/graphic')
-rw-r--r--goodies/source/graphic/grfattr.cxx148
-rw-r--r--goodies/source/graphic/grfcache.cxx876
-rw-r--r--goodies/source/graphic/grfcache.hxx133
-rw-r--r--goodies/source/graphic/grfmgr.cxx851
-rw-r--r--goodies/source/graphic/grfmgr2.cxx1492
-rw-r--r--goodies/source/graphic/makefile.mk95
6 files changed, 3595 insertions, 0 deletions
diff --git a/goodies/source/graphic/grfattr.cxx b/goodies/source/graphic/grfattr.cxx
new file mode 100644
index 000000000000..498498f78d40
--- /dev/null
+++ b/goodies/source/graphic/grfattr.cxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * $RCSfile: grfattr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:30:16 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <tools/vcompat.hxx>
+#include "grfmgr.hxx"
+
+// ---------------
+// - GraphicAttr -
+// ---------------
+
+GraphicAttr::GraphicAttr() :
+ mfGamma ( 1.0 ),
+ mnMirrFlags ( 0 ),
+ mnLeftCrop ( 0 ),
+ mnTopCrop ( 0 ),
+ mnRightCrop ( 0 ),
+ mnBottomCrop ( 0 ),
+ mnRotate10 ( 0 ),
+ mnContPercent ( 0 ),
+ mnLumPercent ( 0 ),
+ mnRPercent ( 0 ),
+ mnGPercent ( 0 ),
+ mnBPercent ( 0 ),
+ mbInvert ( FALSE ),
+ mcTransparency ( 0 ),
+ meDrawMode ( GRAPHICDRAWMODE_STANDARD )
+{
+}
+
+// ------------------------------------------------------------------------
+
+GraphicAttr::~GraphicAttr()
+{
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GraphicAttr::operator==( const GraphicAttr& rAttr ) const
+{
+ return( ( maLogSize == rAttr.maLogSize ) &&
+ ( mfGamma == rAttr.mfGamma ) &&
+ ( mnMirrFlags == rAttr.mnMirrFlags ) &&
+ ( mnLeftCrop == rAttr.mnLeftCrop ) &&
+ ( mnTopCrop == rAttr.mnTopCrop ) &&
+ ( mnRightCrop == rAttr.mnRightCrop ) &&
+ ( mnBottomCrop == rAttr.mnBottomCrop ) &&
+ ( mnRotate10 == rAttr.mnRotate10 ) &&
+ ( mnContPercent == rAttr.mnContPercent ) &&
+ ( mnLumPercent == rAttr.mnLumPercent ) &&
+ ( mnRPercent == rAttr.mnRPercent ) &&
+ ( mnGPercent == rAttr.mnGPercent ) &&
+ ( mnBPercent == rAttr.mnBPercent ) &&
+ ( mbInvert == rAttr.mbInvert ) &&
+ ( mcTransparency == rAttr.mcTransparency ) &&
+ ( meDrawMode == rAttr.meDrawMode ) );
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, GraphicAttr& rAttr )
+{
+ VersionCompat aCompat( rIStm, STREAM_READ );
+ UINT16 nTmp16;
+
+ rIStm >> rAttr.maLogSize >> rAttr.mfGamma >> rAttr.mnMirrFlags >> rAttr.mnRotate10;
+ rIStm >> rAttr.mnContPercent >> rAttr.mnLumPercent >> rAttr.mnRPercent >> rAttr.mnGPercent >> rAttr.mnBPercent;
+ rIStm >> rAttr.mbInvert >> rAttr.mcTransparency >> nTmp16;
+ rAttr.meDrawMode = (GraphicDrawMode) nTmp16;
+
+ if( aCompat.GetVersion() >= 2 )
+ {
+ rIStm >> rAttr.mnLeftCrop >> rAttr.mnTopCrop >> rAttr.mnRightCrop >> rAttr.mnBottomCrop;
+ }
+
+ return rIStm;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const GraphicAttr& rAttr )
+{
+ VersionCompat aCompat( rOStm, STREAM_WRITE, 2 );
+
+ rOStm << rAttr.maLogSize << rAttr.mfGamma << rAttr.mnMirrFlags << rAttr.mnRotate10;
+ rOStm << rAttr.mnContPercent << rAttr.mnLumPercent << rAttr.mnRPercent << rAttr.mnGPercent << rAttr.mnBPercent;
+ rOStm << rAttr.mbInvert << rAttr.mcTransparency << (UINT16) rAttr.meDrawMode;
+ rOStm << rAttr.mnLeftCrop << rAttr.mnTopCrop << rAttr.mnRightCrop << rAttr.mnBottomCrop;
+
+ return rOStm;
+}
diff --git a/goodies/source/graphic/grfcache.cxx b/goodies/source/graphic/grfcache.cxx
new file mode 100644
index 000000000000..0e31ff8a671b
--- /dev/null
+++ b/goodies/source/graphic/grfcache.cxx
@@ -0,0 +1,876 @@
+/*************************************************************************
+ *
+ * $RCSfile: grfcache.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:30:16 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <tools/debug.hxx>
+#include <vcl/outdev.hxx>
+#include "grfcache.hxx"
+
+// -----------
+// - statics -
+// -----------
+
+static const char aHexData[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+// -------------
+// - GraphicID -
+// -------------
+
+class GraphicID
+{
+private:
+
+ sal_uInt32 mnID1;
+ sal_uInt32 mnID2;
+ sal_uInt32 mnID3;
+ sal_uInt32 mnID4;
+
+ GraphicID();
+
+public:
+
+
+ GraphicID( const GraphicObject& rObj );
+ ~GraphicID() {}
+
+ BOOL operator==( const GraphicID& rID ) const
+ {
+ return( rID.mnID1 == mnID1 && rID.mnID2 == mnID2 &&
+ rID.mnID3 == mnID3 && rID.mnID4 == mnID4 );
+ }
+
+ ByteString GetIDString() const;
+};
+
+// -----------------------------------------------------------------------------
+
+GraphicID::GraphicID( const GraphicObject& rObj )
+{
+ const Graphic& rGraphic = rObj.GetGraphic();
+
+ mnID1 = ( (ULONG) rGraphic.GetType() ) << 28;
+
+ switch( rGraphic.GetType() )
+ {
+ case( GRAPHIC_BITMAP ):
+ {
+ if( rGraphic.IsAnimated() )
+ {
+ const Animation aAnimation( rGraphic.GetAnimation() );
+
+ mnID1 |= ( aAnimation.Count() & 0x0fffffff );
+ mnID2 = aAnimation.GetDisplaySizePixel().Width();
+ mnID3 = aAnimation.GetDisplaySizePixel().Height();
+ mnID4 = rGraphic.GetChecksum();
+ }
+ else
+ {
+ const BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ mnID1 |= ( ( ( (ULONG) aBmpEx.GetTransparentType() << 8 ) | ( aBmpEx.IsAlpha() ? 1 : 0 ) ) & 0x0fffffff );
+ mnID2 = aBmpEx.GetSizePixel().Width();
+ mnID3 = aBmpEx.GetSizePixel().Height();
+ mnID4 = rGraphic.GetChecksum();
+ }
+ }
+ break;
+
+ case( GRAPHIC_GDIMETAFILE ):
+ {
+ const GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
+
+ mnID1 |= ( aMtf.GetActionCount() & 0x0fffffff );
+ mnID2 = aMtf.GetPrefSize().Width();
+ mnID3 = aMtf.GetPrefSize().Height();
+ mnID4 = rGraphic.GetChecksum();
+ }
+ break;
+
+ default:
+ mnID2 = mnID3 = mnID4 = 0;
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+ByteString GraphicID::GetIDString() const
+{
+ ByteString aHexStr;
+ sal_Char* pStr = aHexStr.AllocBuffer( 32 );
+ sal_Int32 nShift;
+
+ for( nShift = 28; nShift >= 0; nShift -= 4 )
+ *pStr++ = aHexData[ ( mnID1 >> (sal_uInt32) nShift ) & 0xf ];
+
+ for( nShift = 28; nShift >= 0; nShift -= 4 )
+ *pStr++ = aHexData[ ( mnID2 >> (sal_uInt32) nShift ) & 0xf ];
+
+ for( nShift = 28; nShift >= 0; nShift -= 4 )
+ *pStr++ = aHexData[ ( mnID3 >> (sal_uInt32) nShift ) & 0xf ];
+
+ for( nShift = 28; nShift >= 0; nShift -= 4 )
+ *pStr++ = aHexData[ ( mnID4 >> (sal_uInt32) nShift ) & 0xf ];
+
+ return aHexStr;
+}
+
+// ---------------------
+// - GraphicCacheEntry -
+// ---------------------
+
+class GraphicCacheEntry
+{
+private:
+
+ List maGraphicObjectList;
+ GraphicID maID;
+ GfxLink maGfxLink;
+ BitmapEx* mpBmpEx;
+ GDIMetaFile* mpMtf;
+ Animation* mpAnimation;
+ BOOL mbSwappedAll : 1;
+ BOOL mbInitialized : 1;
+
+ BOOL ImplInit( const GraphicObject& rObj );
+ BOOL ImplMatches( const GraphicObject& rObj ) const { return( GraphicID( rObj ) == maID ); }
+ void ImplFillSubstitute( Graphic& rSubstitute );
+
+public:
+
+ GraphicCacheEntry( const GraphicObject& rObj );
+ ~GraphicCacheEntry();
+
+ const GraphicID& GetID() const { return maID; }
+
+ BOOL AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute );
+ BOOL ReleaseGraphicObjectReference( const GraphicObject& rObj );
+ ULONG GetGraphicObjectReferenceCount() { return maGraphicObjectList.Count(); }
+ BOOL HasGraphicObjectReference( const GraphicObject& rObj );
+
+ void GraphicObjectWasSwappedOut( const GraphicObject& rObj );
+ BOOL FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute );
+ void GraphicObjectWasSwappedIn( const GraphicObject& rObj );
+
+ BOOL IsInitialized() const { return mbInitialized; }
+};
+
+// -----------------------------------------------------------------------------
+
+GraphicCacheEntry::GraphicCacheEntry( const GraphicObject& rObj ) :
+ maID ( rObj ),
+ mpBmpEx ( NULL ),
+ mpMtf ( NULL ),
+ mpAnimation ( NULL ),
+ mbInitialized ( ImplInit( rObj ) )
+{
+ mbSwappedAll = !mbInitialized;
+ maGraphicObjectList.Insert( (void*) &rObj, LIST_APPEND );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicCacheEntry::~GraphicCacheEntry()
+{
+ DBG_ASSERT( !maGraphicObjectList.Count(), "GraphicCacheEntry::~GraphicCacheEntry(): Not all GraphicObjects are removed from this entry" );
+
+ delete mpBmpEx;
+ delete mpMtf;
+ delete mpAnimation;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCacheEntry::ImplInit( const GraphicObject& rObj )
+{
+ BOOL bRet;
+
+ if( !rObj.IsSwappedOut() )
+ {
+ const Graphic& rGraphic = rObj.GetGraphic();
+
+ if( mpBmpEx )
+ delete mpBmpEx, mpBmpEx = NULL;
+
+ if( mpMtf )
+ delete mpMtf, mpMtf = NULL;
+
+ if( mpAnimation )
+ delete mpAnimation, mpAnimation = NULL;
+
+ switch( rGraphic.GetType() )
+ {
+ case( GRAPHIC_BITMAP ):
+ {
+ if( rGraphic.IsAnimated() )
+ mpAnimation = new Animation( rGraphic.GetAnimation() );
+ else
+ mpBmpEx = new BitmapEx( rGraphic.GetBitmapEx() );
+ }
+ break;
+
+ case( GRAPHIC_GDIMETAFILE ):
+ {
+ mpMtf = new GDIMetaFile( rGraphic.GetGDIMetaFile() );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if( rGraphic.IsLink() )
+ maGfxLink = ( (Graphic&) rGraphic ).GetLink();
+ else
+ maGfxLink = GfxLink();
+
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCacheEntry::ImplFillSubstitute( Graphic& rSubstitute )
+{
+ // create substitute for graphic;
+ const Size aPrefSize( rSubstitute.GetPrefSize() );
+ const MapMode aPrefMapMode( rSubstitute.GetPrefMapMode() );
+ const Link aAnimationNotifyHdl( rSubstitute.GetAnimationNotifyHdl() );
+ const String aDocFileName( rSubstitute.GetDocFileName() );
+ const ULONG nDocFilePos = rSubstitute.GetDocFilePos();
+ const GraphicType eOldType = rSubstitute.GetType();
+ const BOOL bDefaultType = ( rSubstitute.GetType() == GRAPHIC_DEFAULT );
+
+ if( rSubstitute.IsLink() && ( GFX_LINK_TYPE_NONE == maGfxLink.GetType() ) )
+ maGfxLink = rSubstitute.GetLink();
+
+ if( mpBmpEx )
+ rSubstitute = *mpBmpEx;
+ else if( mpAnimation )
+ rSubstitute = *mpAnimation;
+ else if( mpMtf )
+ rSubstitute = *mpMtf;
+ else
+ rSubstitute.Clear();
+
+ if( eOldType != GRAPHIC_NONE )
+ {
+ rSubstitute.SetPrefSize( aPrefSize );
+ rSubstitute.SetPrefMapMode( aPrefMapMode );
+ rSubstitute.SetAnimationNotifyHdl( aAnimationNotifyHdl );
+ rSubstitute.SetDocFileName( aDocFileName, nDocFilePos );
+ }
+
+ if( GFX_LINK_TYPE_NONE != maGfxLink.GetType() )
+ rSubstitute.SetLink( maGfxLink );
+
+ if( bDefaultType )
+ rSubstitute.SetDefaultType();
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCacheEntry::AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute )
+{
+ BOOL bRet;
+
+ if( !rObj.IsSwappedOut() )
+ {
+ // append object pointer to list
+ maGraphicObjectList.Insert( (void*) &rObj, LIST_APPEND );
+
+ if( mbSwappedAll )
+ {
+ ImplInit( rObj );
+ mbSwappedAll = FALSE;
+ }
+
+ ImplFillSubstitute( rSubstitute );
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCacheEntry::ReleaseGraphicObjectReference( const GraphicObject& rObj )
+{
+ BOOL bRet = FALSE;
+
+ for( void* pObj = maGraphicObjectList.First(); !bRet && pObj; pObj = maGraphicObjectList.Next() )
+ {
+ if( &rObj == (GraphicObject*) pObj )
+ {
+ maGraphicObjectList.Remove( pObj );
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCacheEntry::HasGraphicObjectReference( const GraphicObject& rObj )
+{
+ BOOL bRet = FALSE;
+
+ for( void* pObj = maGraphicObjectList.First(); !bRet && pObj; pObj = maGraphicObjectList.Next() )
+ if( &rObj == (GraphicObject*) pObj )
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCacheEntry::GraphicObjectWasSwappedOut( const GraphicObject& rObj )
+{
+ mbSwappedAll = TRUE;
+
+ for( void* pObj = maGraphicObjectList.First(); mbSwappedAll && pObj; pObj = maGraphicObjectList.Next() )
+ if( !( (GraphicObject*) pObj )->IsSwappedOut() )
+ mbSwappedAll = FALSE;
+
+ if( mbSwappedAll )
+ {
+ delete mpBmpEx, mpBmpEx = NULL;
+ delete mpMtf, mpMtf = NULL;
+ delete mpAnimation, mpAnimation = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCacheEntry::FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
+{
+ BOOL bRet;
+
+ if( !mbSwappedAll && rObj.IsSwappedOut() )
+ {
+ ImplFillSubstitute( rSubstitute );
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCacheEntry::GraphicObjectWasSwappedIn( const GraphicObject& rObj )
+{
+ if( mbSwappedAll )
+ mbSwappedAll = !ImplInit( rObj );
+}
+
+// ----------------------------
+// - GraphicDisplayCacheEntry -
+// ----------------------------
+
+class GraphicDisplayCacheEntry
+{
+private:
+
+ const GraphicCacheEntry* mpRefCacheEntry;
+ GDIMetaFile* mpMtf;
+ BitmapEx* mpBmpEx;
+ GraphicAttr maAttr;
+ Size maOutSizePix;
+ ULONG mnCacheSize;
+
+public:
+
+ static ULONG GetNeededSize( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr );
+
+public:
+
+ GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry,
+ OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const BitmapEx& rBmpEx ) :
+ mpRefCacheEntry( pRefCacheEntry ),
+ mpMtf( NULL ), mpBmpEx( new BitmapEx( rBmpEx ) ),
+ maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ),
+ mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ) {}
+
+ GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry,
+ OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const GDIMetaFile& rMtf ) :
+ mpRefCacheEntry( pRefCacheEntry ),
+ mpMtf( new GDIMetaFile( rMtf ) ), mpBmpEx( NULL ),
+ maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ),
+ mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ) {}
+
+ ~GraphicDisplayCacheEntry();
+
+ const GraphicAttr& GetAttr() const { return maAttr; }
+ const Size& GetOutputSizePixel() const { return maOutSizePix; }
+ const long GetCacheSize() const { return mnCacheSize; }
+ const GraphicCacheEntry* GetReferencedCacheEntry() const { return mpRefCacheEntry; }
+
+ BOOL Matches( OutputDevice* pOut, const Point& rPtPixel, const Size& rSzPixel,
+ const GraphicCacheEntry* pCacheEntry, const GraphicAttr& rAttr ) const
+ {
+ return( ( pCacheEntry == mpRefCacheEntry ) &&
+ ( maAttr == rAttr ) &&
+ ( ( maOutSizePix == rSzPixel ) || ( !maOutSizePix.Width() && !maOutSizePix.Height() ) ) );
+ }
+
+ void Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const;
+};
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicDisplayCacheEntry::GetNeededSize( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr )
+{
+ const GraphicType eType = rObj.GetGraphic().GetType();
+ ULONG nNeededSize;
+
+ if( GRAPHIC_BITMAP == eType )
+ {
+ const Size aOutSizePix( pOut->LogicToPixel( rSz ) );
+ const long nBitCount = pOut->GetBitCount();
+
+ if( nBitCount )
+ {
+ nNeededSize = aOutSizePix.Width() * aOutSizePix.Height() * nBitCount / 8;
+
+ if( rObj.IsTransparent() || ( rAttr.GetRotation() % 3600 ) )
+ nNeededSize += nNeededSize / nBitCount;
+ }
+ else
+ {
+ DBG_ERROR( "GraphicDisplayCacheEntry::GetNeededSize(): pOut->GetBitCount() == 0" );
+ nNeededSize = 256000;
+ }
+ }
+ else if( GRAPHIC_GDIMETAFILE == eType )
+ nNeededSize = 65535;
+ else
+ nNeededSize = 0;
+
+ return nNeededSize;
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicDisplayCacheEntry::~GraphicDisplayCacheEntry()
+{
+ if( mpMtf )
+ delete mpMtf;
+
+ if( mpBmpEx )
+ delete mpBmpEx;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicDisplayCacheEntry::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const
+{
+ if( mpMtf )
+ GraphicManager::ImplDraw( pOut, rPt, rSz, *mpMtf, maAttr );
+ else if( mpBmpEx )
+ GraphicManager::ImplDraw( pOut, rPt, rSz, *mpBmpEx, maAttr );
+}
+
+// -----------------------
+// - GraphicCache -
+// -----------------------
+
+GraphicCache::GraphicCache( GraphicManager& rMgr, ULONG nDisplayCacheSize, ULONG nMaxObjDisplayCacheSize ) :
+ mrMgr ( rMgr ),
+ mnMaxDisplaySize ( nDisplayCacheSize ),
+ mnMaxObjDisplaySize ( nMaxObjDisplayCacheSize ),
+ mnUsedDisplaySize ( 0UL )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicCache::~GraphicCache()
+{
+ DBG_ASSERT( !maGraphicCache.Count(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in cache" );
+ DBG_ASSERT( !maDisplayCache.Count(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in display cache" );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::AddGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute, const ByteString* pID )
+{
+ BOOL bInserted = FALSE;
+
+ if( !rObj.IsSwappedOut() )
+ {
+ GraphicCacheEntry* pEntry = (GraphicCacheEntry*) maGraphicCache.First();
+ const GraphicID aID( rObj );
+
+ while( !bInserted && pEntry )
+ {
+ const GraphicID& rID = pEntry->GetID();
+
+ if( pID )
+ {
+ if( rID.GetIDString() == *pID )
+ bInserted = pEntry->AddGraphicObjectReference( rObj, rSubstitute );
+ }
+ else
+ {
+ if( pEntry->GetID() == aID )
+ bInserted = pEntry->AddGraphicObjectReference( rObj, rSubstitute );
+ }
+
+ pEntry = (GraphicCacheEntry*) maGraphicCache.Next();
+ }
+ }
+
+ if( !bInserted )
+ maGraphicCache.Insert( new GraphicCacheEntry( rObj ), LIST_APPEND );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::ReleaseGraphicObject( const GraphicObject& rObj )
+{
+ // Release cached object
+ GraphicCacheEntry* pEntry = (GraphicCacheEntry*) maGraphicCache.First();
+ BOOL bRemoved = FALSE;
+
+ while( !bRemoved && pEntry )
+ {
+ bRemoved = pEntry->ReleaseGraphicObjectReference( rObj );
+
+ if( bRemoved )
+ {
+ if( 0 == pEntry->GetGraphicObjectReferenceCount() )
+ {
+ // if graphic cache entry has no more references,
+ // the corresponding display cache object can be removed
+ GraphicDisplayCacheEntry* pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First();
+
+ while( pDisplayEntry )
+ {
+ if( pDisplayEntry->GetReferencedCacheEntry() == pEntry )
+ {
+ mnUsedDisplaySize -= pDisplayEntry->GetCacheSize();
+ maDisplayCache.Remove( pDisplayEntry );
+ delete pDisplayEntry;
+ pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.GetCurObject();
+ }
+ else
+ pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
+ }
+
+ // delete graphic cache entry
+ maGraphicCache.Remove( (void*) pEntry );
+ delete pEntry;
+ }
+ }
+ else
+ pEntry = (GraphicCacheEntry*) maGraphicCache.Next();
+ }
+
+ DBG_ASSERT( bRemoved, "GraphicCache::ReleaseGraphicObject(...): GraphicObject not found in cache" );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::GraphicObjectWasSwappedOut( const GraphicObject& rObj )
+{
+ ImplGetCacheEntry( rObj )->GraphicObjectWasSwappedOut( rObj );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
+{
+ return( ImplGetCacheEntry( rObj )->FillSwappedGraphicObject( rObj, rSubstitute ) );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::GraphicObjectWasSwappedIn( const GraphicObject& rObj )
+{
+ GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );
+
+ if( !pEntry->IsInitialized() )
+ {
+ ReleaseGraphicObject( rObj );
+ AddGraphicObject( rObj, (Graphic&) rObj.GetGraphic(), NULL );
+ }
+ else
+ pEntry->GraphicObjectWasSwappedIn( rObj );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::SetMaxDisplayCacheSize( ULONG nNewCacheSize )
+{
+ mnMaxDisplaySize = nNewCacheSize;
+
+ if( GetMaxDisplayCacheSize() < GetUsedDisplayCacheSize() )
+ ImplFreeDisplayCacheSpace( GetUsedDisplayCacheSize() - GetMaxDisplayCacheSize() );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::SetMaxObjDisplayCacheSize( ULONG nNewMaxObjSize, BOOL bDestroyGreaterCached )
+{
+ const BOOL bDestroy = ( bDestroyGreaterCached && ( nNewMaxObjSize < mnMaxObjDisplaySize ) );
+
+ mnMaxObjDisplaySize = Min( nNewMaxObjSize, mnMaxDisplaySize );
+
+ if( bDestroy )
+ {
+ GraphicDisplayCacheEntry* pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.First();
+
+ while( pCacheObj )
+ {
+ if( pCacheObj->GetCacheSize() > mnMaxObjDisplaySize )
+ {
+ mnUsedDisplaySize -= pCacheObj->GetCacheSize();
+ maDisplayCache.Remove( pCacheObj );
+ delete pCacheObj;
+ pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.GetCurObject();
+ }
+ else
+ pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicCache::ClearDisplayCache()
+{
+ for( void* pObj = maDisplayCache.First(); pObj; pObj = maDisplayCache.Next() )
+ delete (GraphicDisplayCacheEntry*) pObj;
+
+ maDisplayCache.Clear();
+ mnUsedDisplaySize = 0UL;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::IsDisplayCacheable( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr ) const
+{
+ return( GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) <=
+ GetMaxObjDisplayCacheSize() );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::IsInDisplayCache( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr ) const
+{
+ const Point aPtPixel( pOut->LogicToPixel( rPt ) );
+ const Size aSzPixel( pOut->LogicToPixel( rSz ) );
+ const GraphicCacheEntry* pCacheEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj );
+ GraphicDisplayCacheEntry* pDisplayEntry = (GraphicDisplayCacheEntry*) ( (GraphicCache*) this )->maDisplayCache.First();
+ BOOL bFound = FALSE;
+
+ for( long i = 0, nCount = maDisplayCache.Count(); !bFound && ( i < nCount ); i++ )
+ if( ( (GraphicDisplayCacheEntry*) maDisplayCache.GetObject( i ) )->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) )
+ bFound = TRUE;
+
+ return bFound;
+}
+
+// -----------------------------------------------------------------------------
+
+ByteString GraphicCache::GetUniqueID( const GraphicObject& rObj ) const
+{
+ return( ( (GraphicCache*) this )->ImplGetCacheEntry( rObj )->GetID().GetIDString() );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const BitmapEx& rBmpEx )
+{
+ const ULONG nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr );
+ BOOL bRet = FALSE;
+
+ if( nNeededSize <= GetMaxObjDisplayCacheSize() )
+ {
+ if( nNeededSize > GetFreeDisplayCacheSize() )
+ ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() );
+
+ GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ),
+ pOut, rPt, rSz, rObj, rAttr, rBmpEx );
+
+
+ maDisplayCache.Insert( pNewEntry, (ULONG) 0 );
+ mnUsedDisplaySize += pNewEntry->GetCacheSize();
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const GDIMetaFile& rMtf )
+{
+ const ULONG nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr );
+ BOOL bRet = FALSE;
+
+ if( nNeededSize <= GetMaxObjDisplayCacheSize() )
+ {
+ if( nNeededSize > GetFreeDisplayCacheSize() )
+ ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() );
+
+ GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ),
+ pOut, rPt, rSz, rObj, rAttr, rMtf );
+
+
+ maDisplayCache.Insert( pNewEntry, (ULONG) 0 );
+ mnUsedDisplaySize += pNewEntry->GetCacheSize();
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::DrawDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr )
+{
+ const Point aPtPixel( pOut->LogicToPixel( rPt ) );
+ const Size aSzPixel( pOut->LogicToPixel( rSz ) );
+ const GraphicCacheEntry* pCacheEntry = ImplGetCacheEntry( rObj );
+ GraphicDisplayCacheEntry* pDisplayCacheEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First();
+ BOOL bRet = FALSE;
+
+ while( !bRet && pDisplayCacheEntry )
+ {
+ if( pDisplayCacheEntry->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) )
+ {
+ // put found object at last used position
+ maDisplayCache.Insert( maDisplayCache.Remove( pDisplayCacheEntry ), LIST_APPEND );
+ bRet = TRUE;
+ }
+ else
+ pDisplayCacheEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
+ }
+
+ if( bRet )
+ pDisplayCacheEntry->Draw( pOut, rPt, rSz );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicCache::ImplFreeDisplayCacheSpace( ULONG nSizeToFree )
+{
+ ULONG nFreedSize = 0UL;
+
+ if( nSizeToFree && ( nSizeToFree <= mnMaxDisplaySize ) )
+ {
+ void* pObj = maDisplayCache.First();
+
+ while( pObj )
+ {
+ GraphicDisplayCacheEntry* pCacheObj = (GraphicDisplayCacheEntry*) pObj;
+
+ nFreedSize += pCacheObj->GetCacheSize();
+ mnUsedDisplaySize -= pCacheObj->GetCacheSize();
+ maDisplayCache.Remove( pObj );
+ delete pCacheObj;
+
+ if( nFreedSize >= nSizeToFree )
+ break;
+ else
+ pObj = maDisplayCache.GetCurObject();
+ }
+ }
+
+ return( nFreedSize >= nSizeToFree );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicCacheEntry* GraphicCache::ImplGetCacheEntry( const GraphicObject& rObj )
+{
+ GraphicCacheEntry* pRet = NULL;
+
+ for( void* pObj = maGraphicCache.First(); !pRet && pObj; pObj = maGraphicCache.Next() )
+ if( ( (GraphicCacheEntry*) pObj )->HasGraphicObjectReference( rObj ) )
+ pRet = (GraphicCacheEntry*) pObj;
+
+ return pRet;
+}
diff --git a/goodies/source/graphic/grfcache.hxx b/goodies/source/graphic/grfcache.hxx
new file mode 100644
index 000000000000..508ec2e15206
--- /dev/null
+++ b/goodies/source/graphic/grfcache.hxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * $RCSfile: grfcache.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:30:16 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _GRFCACHE_HXX
+#define _GRFCACHE_HXX
+
+#include <tools/list.hxx>
+#include <vcl/graph.hxx>
+#include "grfmgr.hxx"
+
+// -----------------------
+// - GraphicManagerCache -
+// -----------------------
+
+class GraphicCacheEntry;
+
+class GraphicCache
+{
+private:
+
+ GraphicManager& mrMgr;
+ List maGraphicCache;
+ List maDisplayCache;
+ ULONG mnMaxDisplaySize;
+ ULONG mnMaxObjDisplaySize;
+ ULONG mnUsedDisplaySize;
+
+ BOOL ImplFreeDisplayCacheSpace( ULONG nSizeToFree );
+ GraphicCacheEntry* ImplGetCacheEntry( const GraphicObject& rObj );
+
+public:
+
+ GraphicCache( GraphicManager& rMgr,
+ ULONG nDisplayCacheSize = 10000000UL,
+ ULONG nMaxObjDisplayCacheSize = 2400000UL );
+ ~GraphicCache();
+
+public:
+
+ void AddGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute, const ByteString* pID );
+ void ReleaseGraphicObject( const GraphicObject& rObj );
+
+ void GraphicObjectWasSwappedOut( const GraphicObject& rObj );
+ BOOL FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute );
+ void GraphicObjectWasSwappedIn( const GraphicObject& rObj );
+
+ ByteString GetUniqueID( const GraphicObject& rObj ) const;
+
+public:
+
+ void SetMaxDisplayCacheSize( ULONG nNewCacheSize );
+ ULONG GetMaxDisplayCacheSize() const { return mnMaxDisplaySize; };
+
+ void SetMaxObjDisplayCacheSize( ULONG nNewMaxObjSize, BOOL bDestroyGreaterCached = FALSE );
+ ULONG GetMaxObjDisplayCacheSize() const { return mnMaxObjDisplaySize; }
+
+ ULONG GetUsedDisplayCacheSize() const { return mnUsedDisplaySize; }
+ ULONG GetFreeDisplayCacheSize() const { return( mnMaxDisplaySize - mnUsedDisplaySize ); }
+
+ void ClearDisplayCache();
+ BOOL IsDisplayCacheable( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr ) const;
+ BOOL IsInDisplayCache( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr ) const;
+ BOOL CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const BitmapEx& rBmpEx );
+ BOOL CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr,
+ const GDIMetaFile& rMtf );
+ BOOL DrawDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicObject& rObj, const GraphicAttr& rAttr );
+};
+
+#endif // _GRFCACHE_HXX
diff --git a/goodies/source/graphic/grfmgr.cxx b/goodies/source/graphic/grfmgr.cxx
new file mode 100644
index 000000000000..9b8d255ab946
--- /dev/null
+++ b/goodies/source/graphic/grfmgr.cxx
@@ -0,0 +1,851 @@
+/*************************************************************************
+ *
+ * $RCSfile: grfmgr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:30:16 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define ENABLE_BYTESTRING_STREAM_OPERATORS
+
+#include <tools/vcompat.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/virdev.hxx>
+#include "grfmgr.hxx"
+
+// -----------
+// - Defines -
+// -----------
+
+#define GRFMGR_CACHESIZE_STANDARD 10000000UL
+#define GRFMGR_OBJCACHESIZE_STANDARD 2500000UL
+#define GRFMGR_CACHESIZE_APPSERVER 10000000UL
+#define GRFMGR_OBJCACHESIZE_APPSERVER 2500000UL
+#define WATERMARK_LUM_OFFSET 50
+#define WATERMARK_CON_OFFSET -70
+
+// -----------
+// - statics -
+// -----------
+
+GraphicManager* GraphicObject::mpGlobalMgr = NULL;
+
+// ---------------------
+// - GrfDirectCacheObj -
+// ---------------------
+
+struct GrfSimpleCacheObj
+{
+ Graphic maGraphic;
+ GraphicAttr maAttr;
+
+ GrfSimpleCacheObj( const Graphic& rGraphic, const GraphicAttr& rAttr ) :
+ maGraphic( rGraphic ), maAttr( rAttr ) {}
+};
+
+// -----------------
+// - GraphicObject -
+// -----------------
+
+TYPEINIT1_AUTOFACTORY( GraphicObject, SvDataCopyStream );
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::GraphicObject( const GraphicManager* pMgr ) :
+ mpLink ( NULL )
+{
+ ImplConstruct();
+ ImplAssignGraphicData();
+ ImplSetGraphicManager( pMgr );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::GraphicObject( const Graphic& rGraphic, const GraphicManager* pMgr ) :
+ maGraphic ( rGraphic ),
+ mpLink ( NULL )
+{
+ ImplConstruct();
+ ImplAssignGraphicData();
+ ImplSetGraphicManager( pMgr );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::GraphicObject( const Graphic& rGraphic, const String& rLink, const GraphicManager* pMgr ) :
+ maGraphic ( rGraphic ),
+ mpLink ( rLink.Len() ? ( new String( rLink ) ) : NULL )
+{
+ ImplConstruct();
+ ImplAssignGraphicData();
+ ImplSetGraphicManager( pMgr );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::GraphicObject( const GraphicObject& rGraphicObj, const GraphicManager* pMgr ) :
+ maGraphic ( rGraphicObj.GetGraphic() ),
+ mpLink ( rGraphicObj.mpLink ? ( new String( *rGraphicObj.mpLink ) ) : NULL ),
+ maAttr ( rGraphicObj.maAttr )
+{
+ ImplConstruct();
+ ImplAssignGraphicData();
+ ImplSetGraphicManager( pMgr );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::GraphicObject( const ByteString& rUniqueID, const GraphicManager* pMgr ) :
+ mpLink ( NULL )
+{
+ ImplConstruct();
+ ImplSetGraphicManager( pMgr, &rUniqueID );
+ ImplAssignGraphicData();
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject::~GraphicObject()
+{
+ if( mpMgr )
+ {
+ mpMgr->ImplUnregisterObj( *this );
+
+ if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() )
+ delete mpGlobalMgr, mpGlobalMgr = NULL;
+ }
+
+ delete mpSwapOutTimer;
+ delete mpSwapStreamHdl;
+ delete mpLink;
+ delete mpSimpleCache;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ImplConstruct()
+{
+ mpMgr = NULL;
+ mpSwapStreamHdl = NULL;
+ mpSwapOutTimer = NULL;
+ mpSimpleCache = NULL;
+ mbAutoSwapped = FALSE;
+ mbIsInSwapIn = FALSE;
+ mbIsInSwapOut = FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ImplAssignGraphicData()
+{
+ maPrefSize = maGraphic.GetPrefSize();
+ maPrefMapMode = maGraphic.GetPrefMapMode();
+ mnSizeBytes = maGraphic.GetSizeBytes();
+ meType = maGraphic.GetType();
+ mbTransparent = maGraphic.IsTransparent();
+ mbAnimated = maGraphic.IsAnimated();
+
+ if( maGraphic.GetType() == GRAPHIC_GDIMETAFILE )
+ {
+ const GDIMetaFile& rMtf = GetGraphic().GetGDIMetaFile();
+ mbEPS = ( rMtf.GetActionCount() == 1 ) && ( META_EPS_ACTION == rMtf.GetAction( 0 )->GetType() );
+ }
+ else
+ mbEPS = FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ImplSetGraphicManager( const GraphicManager* pMgr, const ByteString* pID )
+{
+ if( !mpMgr || ( pMgr != mpMgr ) )
+ {
+ if( !pMgr && mpMgr && ( mpMgr == mpGlobalMgr ) )
+ return;
+ else
+ {
+ if( mpMgr )
+ {
+ mpMgr->ImplUnregisterObj( *this );
+
+ if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() )
+ delete mpGlobalMgr, mpGlobalMgr = NULL;
+ }
+
+ if( !pMgr )
+ {
+ if( !mpGlobalMgr )
+ {
+ if( Application::IsRemoteServer() )
+ mpGlobalMgr = new GraphicManager( GRFMGR_CACHESIZE_APPSERVER, GRFMGR_OBJCACHESIZE_APPSERVER );
+ else
+ mpGlobalMgr = new GraphicManager( GRFMGR_CACHESIZE_STANDARD, GRFMGR_OBJCACHESIZE_STANDARD );
+ }
+
+ mpMgr = mpGlobalMgr;
+ }
+ else
+ mpMgr = (GraphicManager*) pMgr;
+
+ mpMgr->ImplRegisterObj( *this, maGraphic, pID );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ImplAutoSwapIn( BOOL bIgnoreSwapState )
+{
+ if( bIgnoreSwapState || IsSwappedOut() )
+ {
+ if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
+ mbAutoSwapped = FALSE;
+ else
+ {
+ mbIsInSwapIn = TRUE;
+
+ SvStream* pStream = GetSwapStream();
+
+ if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
+ {
+ if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
+ {
+ if( HasLink() )
+ {
+ SvFileStream aIStm( GetLink(), STREAM_READ );
+ mbAutoSwapped = !maGraphic.SwapIn( &aIStm );
+ }
+ }
+ else if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
+ mbAutoSwapped = !maGraphic.SwapIn();
+ else if( GRFMGR_AUTOSWAPSTREAM_LOADED == pStream )
+ mbAutoSwapped = maGraphic.IsSwapOut();
+ else
+ {
+ mbAutoSwapped = !maGraphic.SwapIn( pStream );
+ delete pStream;
+ }
+ }
+
+ mbIsInSwapIn = FALSE;
+
+ if( !mbAutoSwapped && mpMgr )
+ mpMgr->ImplGraphicObjectWasSwappedIn( *this );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicObject& GraphicObject::operator=( const GraphicObject& rGraphicObj )
+{
+ if( &rGraphicObj != this )
+ {
+ mpMgr->ImplUnregisterObj( *this );
+
+ delete mpSwapStreamHdl, mpSwapStreamHdl = NULL;
+ delete mpSimpleCache, mpSimpleCache = NULL;
+ delete mpLink;
+
+ maGraphic = rGraphicObj.GetGraphic();
+ maAttr = rGraphicObj.maAttr;
+ mpLink = rGraphicObj.mpLink ? new String( *rGraphicObj.mpLink ) : NULL;
+ ImplAssignGraphicData();
+ mbAutoSwapped = FALSE;
+ mpMgr = rGraphicObj.mpMgr;
+
+ mpMgr->ImplRegisterObj( *this, maGraphic, NULL );
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::operator==( const GraphicObject& rGraphicObj ) const
+{
+ return( ( rGraphicObj.maGraphic == maGraphic ) &&
+ ( rGraphicObj.maAttr == maAttr ) &&
+ ( rGraphicObj.GetLink() == GetLink() ) );
+}
+
+// ------------------------------------------------------------------------
+
+void GraphicObject::Load( SvStream& rIStm )
+{
+ rIStm >> *this;
+}
+
+// ------------------------------------------------------------------------
+
+void GraphicObject::Save( SvStream& rOStm )
+{
+ rOStm << *this;
+}
+
+// ------------------------------------------------------------------------
+
+void GraphicObject::Assign( const SvDataCopyStream& rCopyStream )
+{
+ *this = (const GraphicObject& ) rCopyStream;
+}
+
+// -----------------------------------------------------------------------------
+
+ByteString GraphicObject::GetUniqueID() const
+{
+ ByteString aRet;
+
+ if( mpMgr )
+ aRet = mpMgr->ImplGetUniqueID( *this );
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicObject::GetChecksum() const
+{
+ return( ( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() ) ? maGraphic.GetChecksum() : 0 );
+}
+
+// -----------------------------------------------------------------------------
+
+SvStream* GraphicObject::GetSwapStream() const
+{
+ return( HasSwapStreamHdl() ? (SvStream*) mpSwapStreamHdl->Call( (void*) this ) : GRFMGR_AUTOSWAPSTREAM_NONE );
+}
+
+// -----------------------------------------------------------------------------
+
+// !!! to be removed
+ULONG GraphicObject::GetReleaseFromCache() const
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetAttr( const GraphicAttr& rAttr )
+{
+ maAttr = rAttr;
+
+ if( mpSimpleCache && ( mpSimpleCache->maAttr != rAttr ) )
+ delete mpSimpleCache, mpSimpleCache = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetLink()
+{
+ if( mpLink )
+ delete mpLink, mpLink = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetLink( const String& rLink )
+{
+ delete mpLink, mpLink = new String( rLink );
+}
+
+// -----------------------------------------------------------------------------
+
+String GraphicObject::GetLink() const
+{
+ if( mpLink )
+ return *mpLink;
+ else
+ return String();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetSwapStreamHdl()
+{
+ if( mpSwapStreamHdl )
+ {
+ delete mpSwapOutTimer, mpSwapOutTimer = NULL;
+ delete mpSwapStreamHdl, mpSwapStreamHdl = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetSwapStreamHdl( const Link& rHdl, const ULONG nSwapOutTimeout )
+{
+ delete mpSwapStreamHdl, mpSwapStreamHdl = new Link( rHdl );
+
+ if( nSwapOutTimeout )
+ {
+ if( !mpSwapOutTimer )
+ {
+ mpSwapOutTimer = new Timer;
+ mpSwapOutTimer->SetTimeoutHdl( LINK( this, GraphicObject, ImplAutoSwapOutHdl ) );
+ }
+
+ mpSwapOutTimer->SetTimeout( nSwapOutTimeout );
+ mpSwapOutTimer->Start();
+ }
+ else
+ delete mpSwapOutTimer, mpSwapOutTimer = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+Link GraphicObject::GetSwapStreamHdl() const
+{
+ if( mpSwapStreamHdl )
+ return *mpSwapStreamHdl;
+ else
+ return Link();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::FireSwapInRequest()
+{
+ ImplAutoSwapIn( TRUE );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::FireSwapOutRequest()
+{
+ ImplAutoSwapOutHdl( NULL );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::GraphicManagerDestroyed()
+{
+ // we're alive, but our manager doesn't live anymore ==> connect to default manager
+ mpMgr = NULL;
+ ImplSetGraphicManager( NULL );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetGraphicManager( const GraphicManager& rMgr )
+{
+ ImplSetGraphicManager( &rMgr );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::IsCached( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicAttr* pAttr, ULONG nFlags ) const
+{
+ BOOL bRet;
+
+ if( nFlags & GRFMGR_DRAW_CACHED )
+ bRet = mpMgr->IsInCache( pOut, rPt, rSz, *this, ( pAttr ? *pAttr : GetAttr() ) );
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ReleaseFromCache()
+{
+
+ mpMgr->ReleaseFromCache( *this );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetAnimationNotifyHdl( const Link& rLink )
+{
+ maGraphic.SetAnimationNotifyHdl( rLink );
+}
+
+// -----------------------------------------------------------------------------
+
+List* GraphicObject::GetAnimationInfoList() const
+{
+ return maGraphic.GetAnimationInfoList();
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GraphicAttr* pAttr, ULONG nFlags )
+{
+ const GraphicAttr& rActAttr = ( pAttr ? *pAttr : GetAttr() );
+ BOOL bCached = FALSE;
+ BOOL bRet;
+
+ if( IsAnimated() || !( nFlags & GRFMGR_DRAW_CACHED ) )
+ {
+ GetGraphic();
+
+ if( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() )
+ {
+ Graphic aGraphic( GetTransformedGraphic( &rActAttr ) );
+
+ if( aGraphic.IsSupportedGraphic() )
+ {
+ aGraphic.Draw( pOut, rPt, rSz );
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+ }
+ else
+ bRet = FALSE;
+ }
+ else
+ bRet = mpMgr->DrawObj( pOut, rPt, rSz, *this, rActAttr, nFlags, bCached );
+
+ if( bCached )
+ {
+ if( mpSwapOutTimer )
+ mpSwapOutTimer->Start();
+ else
+ FireSwapOutRequest();
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::StartAnimation( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ long nExtraData, const GraphicAttr* pAttr, ULONG nFlags,
+ OutputDevice* pFirstFrameOutDev )
+{
+ const GraphicAttr& rActAttr = ( pAttr ? *pAttr : GetAttr() );
+ BOOL bRet = FALSE;
+
+ GetGraphic();
+
+ if( !IsSwappedOut() )
+ {
+ if( mbAnimated )
+ {
+ if( !mpSimpleCache || ( mpSimpleCache->maAttr != rActAttr ) || pFirstFrameOutDev )
+ {
+ if( mpSimpleCache )
+ delete mpSimpleCache;
+
+ mpSimpleCache = new GrfSimpleCacheObj( GetTransformedGraphic( &rActAttr ), rActAttr );
+ mpSimpleCache->maGraphic.SetAnimationNotifyHdl( GetAnimationNotifyHdl() );
+ }
+
+ mpSimpleCache->maGraphic.StartAnimation( pOut, rPt, rSz, nExtraData, pFirstFrameOutDev );
+ bRet = TRUE;
+ }
+ else
+ bRet = Draw( pOut, rPt, rSz, &rActAttr, GRFMGR_DRAW_STANDARD );
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::StopAnimation( OutputDevice* pOut, long nExtraData )
+{
+ if( mpSimpleCache )
+ mpSimpleCache->maGraphic.StopAnimation( pOut, nExtraData );
+}
+
+// -----------------------------------------------------------------------------
+
+const Graphic& GraphicObject::GetGraphic() const
+{
+ if( mbAutoSwapped )
+ ( (GraphicObject*) this )->ImplAutoSwapIn( FALSE );
+
+ return maGraphic;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetGraphic( const Graphic& rGraphic )
+{
+ mpMgr->ImplUnregisterObj( *this );
+
+ if( mpSwapOutTimer )
+ mpSwapOutTimer->Stop();
+
+ maGraphic = rGraphic;
+ mbAutoSwapped = FALSE;
+ ImplAssignGraphicData();
+ delete mpLink, mpLink = NULL;
+ delete mpSimpleCache, mpSimpleCache = NULL;
+
+ mpMgr->ImplRegisterObj( *this, maGraphic, NULL );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::SetGraphic( const Graphic& rGraphic, const String& rLink )
+{
+ SetGraphic( rGraphic );
+ mpLink = new String( rLink );
+}
+
+// -----------------------------------------------------------------------------
+
+Graphic GraphicObject::GetTransformedGraphic( const GraphicAttr* pAttr ) const
+{
+ Graphic aGraphic;
+ GraphicAttr aActAttr;
+
+ GetGraphic();
+ aActAttr = ( pAttr ? *pAttr : GetAttr() );
+
+ if( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() )
+ {
+ if( aActAttr.IsSpecialDrawMode() || aActAttr.IsAdjusted() ||
+ aActAttr.IsMirrored() || aActAttr.IsRotated() || aActAttr.IsTransparent() )
+ {
+ if( GetType() == GRAPHIC_BITMAP )
+ {
+ if( IsAnimated() )
+ {
+ Animation aAnimation( maGraphic.GetAnimation() );
+ GraphicManager::ImplAdjust( aAnimation, aActAttr, ADJUSTMENT_ALL );
+ aGraphic = aAnimation;
+ }
+ else
+ {
+ BitmapEx aBmpEx( maGraphic.GetBitmapEx() );
+ GraphicManager::ImplAdjust( aBmpEx, aActAttr, ADJUSTMENT_ALL );
+ aGraphic = aBmpEx;
+ }
+ }
+ else
+ {
+ GDIMetaFile aMtf( maGraphic.GetGDIMetaFile() );
+ GraphicManager::ImplAdjust( aMtf, aActAttr, ADJUSTMENT_ALL );
+ aGraphic = aMtf;
+ }
+ }
+ else
+ aGraphic = maGraphic;
+ }
+
+ return aGraphic;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicObject::ResetAnimationLoopCount()
+{
+ if( IsAnimated() && !IsSwappedOut() )
+ {
+ maGraphic.ResetAnimationLoopCount();
+
+ if( mpSimpleCache )
+ mpSimpleCache->maGraphic.ResetAnimationLoopCount();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::SwapOut()
+{
+ BOOL bRet = ( !mbAutoSwapped ? maGraphic.SwapOut() : FALSE );
+
+ if( bRet && mpMgr )
+ mpMgr->ImplGraphicObjectWasSwappedOut( *this );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::SwapOut( SvStream* pOStm )
+{
+ BOOL bRet = ( !mbAutoSwapped ? maGraphic.SwapOut( pOStm ) : FALSE );
+
+ if( bRet && mpMgr )
+ mpMgr->ImplGraphicObjectWasSwappedOut( *this );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::SwapIn()
+{
+ BOOL bRet;
+
+ if( mbAutoSwapped )
+ {
+ ImplAutoSwapIn( FALSE );
+ bRet = TRUE;
+ }
+ else if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
+ bRet = TRUE;
+ else
+ {
+ bRet = maGraphic.SwapIn();
+
+ if( bRet && mpMgr )
+ mpMgr->ImplGraphicObjectWasSwappedIn( *this );
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicObject::SwapIn( SvStream* pIStm )
+{
+ BOOL bRet;
+
+ if( mbAutoSwapped )
+ {
+ ImplAutoSwapIn( FALSE );
+ bRet = TRUE;
+ }
+ else if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
+ bRet = TRUE;
+ else
+ {
+ bRet = maGraphic.SwapIn( pIStm );
+
+ if( bRet && mpMgr )
+ mpMgr->ImplGraphicObjectWasSwappedIn( *this );
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+IMPL_LINK( GraphicObject, ImplAutoSwapOutHdl, void*, p )
+{
+ if( !mbAutoSwapped && !IsSwappedOut() )
+ {
+ mbIsInSwapOut = TRUE;
+
+ SvStream* pStream = GetSwapStream();
+
+ if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
+ {
+ if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
+ mbAutoSwapped = SwapOut( NULL );
+ else
+ {
+ if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
+ mbAutoSwapped = SwapOut();
+ else
+ {
+ mbAutoSwapped = SwapOut( pStream );
+ delete pStream;
+ }
+ }
+ }
+
+ mbIsInSwapOut = FALSE;
+ }
+
+ if( mpSwapOutTimer )
+ mpSwapOutTimer->Start();
+
+ return 0L;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, GraphicObject& rGraphicObj )
+{
+ VersionCompat aCompat( rIStm, STREAM_READ );
+ Graphic aGraphic;
+ GraphicAttr aAttr;
+ ByteString aLink;
+ BOOL bLink;
+
+ rIStm >> aGraphic >> aAttr >> bLink;
+
+ rGraphicObj.SetGraphic( aGraphic );
+ rGraphicObj.SetAttr( aAttr );
+
+ if( bLink )
+ {
+ rIStm >> aLink;
+ rGraphicObj.SetLink( UniString( aLink, RTL_TEXTENCODING_UTF8 ) );
+ }
+ else
+ rGraphicObj.SetLink();
+
+ rGraphicObj.SetSwapStreamHdl();
+
+ return rIStm;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const GraphicObject& rGraphicObj )
+{
+ VersionCompat aCompat( rOStm, STREAM_WRITE, 1 );
+ const BOOL bLink = rGraphicObj.HasLink();
+
+ rOStm << rGraphicObj.GetGraphic() << rGraphicObj.GetAttr() << bLink;
+
+ if( bLink )
+ rOStm << ByteString( rGraphicObj.GetLink(), RTL_TEXTENCODING_UTF8 );
+
+ return rOStm;
+}
diff --git a/goodies/source/graphic/grfmgr2.cxx b/goodies/source/graphic/grfmgr2.cxx
new file mode 100644
index 000000000000..8d8de217bbc0
--- /dev/null
+++ b/goodies/source/graphic/grfmgr2.cxx
@@ -0,0 +1,1492 @@
+/*************************************************************************
+ *
+ * $RCSfile: grfmgr2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:30:16 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <vos/macros.hxx>
+#include <vcl/bmpacc.hxx>
+#include <vcl/poly.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/window.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/animate.hxx>
+#include <vcl/alpha.hxx>
+#include "grfcache.hxx"
+#include "grfmgr.hxx"
+
+// -----------
+// - defines -
+// -----------
+
+#define MAX_PRINTER_EXT 1024
+#define MAP( cVal0, cVal1, nFrac ) ((BYTE)((((long)(cVal0)<<20L)+nFrac*((long)(cVal1)-(cVal0)))>>20L))
+#define WATERMARK_LUM_OFFSET 50
+#define WATERMARK_CON_OFFSET -70
+
+// ------------------
+// - GraphicManager -
+// ------------------
+
+GraphicManager::GraphicManager( ULONG nCacheSize, ULONG nMaxObjCacheSize ) :
+ mpCache( new GraphicCache( *this, nCacheSize, nMaxObjCacheSize ) )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicManager::~GraphicManager()
+{
+ for( void* pObj = maObjList.First(); pObj; pObj = maObjList.Next() )
+ ( (GraphicObject*) pObj )->GraphicManagerDestroyed();
+
+ delete mpCache;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::SetMaxCacheSize( ULONG nNewCacheSize )
+{
+ mpCache->SetMaxDisplayCacheSize( nNewCacheSize );
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicManager::GetMaxCacheSize() const
+{
+ return mpCache->GetMaxDisplayCacheSize();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::SetMaxObjCacheSize( ULONG nNewMaxObjSize, BOOL bDestroyGreaterCached )
+{
+ mpCache->SetMaxObjDisplayCacheSize( nNewMaxObjSize, bDestroyGreaterCached );
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicManager::GetMaxObjCacheSize() const
+{
+ return mpCache->GetMaxObjDisplayCacheSize();
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicManager::GetUsedCacheSize() const
+{
+ return mpCache->GetUsedDisplayCacheSize();
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG GraphicManager::GetFreeCacheSize() const
+{
+ return mpCache->GetFreeDisplayCacheSize();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ClearCache()
+{
+ mpCache->ClearDisplayCache();
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ReleaseFromCache( const GraphicObject& rObj )
+{
+ // !!!
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::IsInCache( OutputDevice* pOut, const Point& rPt,
+ const Size& rSz, const GraphicObject& rObj,
+ const GraphicAttr& rAttr ) const
+{
+ return mpCache->IsInDisplayCache( pOut, rPt, rSz, rObj, rAttr );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::DrawObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ GraphicObject& rObj, const GraphicAttr& rAttr,
+ const ULONG nFlags, BOOL& rCached )
+{
+ GraphicAttr aAttr( rAttr );
+ Point aPt( rPt );
+ Size aSz( rSz );
+ BOOL bRet = FALSE;
+
+ rCached = FALSE;
+
+ if( aSz.Width() < 0L )
+ {
+ aPt.X() += aSz.Width() + 1;
+ aSz.Width() = -aSz.Width();
+ aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_HORZ );
+ }
+
+ if( aSz.Height() < 0L )
+ {
+ aPt.Y() += aSz.Height() + 1;
+ aSz.Height() = -aSz.Height();
+ aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_VERT );
+ }
+
+ if( ( rObj.GetType() == GRAPHIC_BITMAP ) || ( rObj.GetType() == GRAPHIC_GDIMETAFILE ) )
+ {
+ const Size aOutSize( pOut->GetOutputSizePixel() );
+
+ // metafile recording?
+ if( ( pOut->GetOutDevType() == OUTDEV_PRINTER ) ||
+ ( pOut->GetConnectMetaFile() && !pOut->IsOutputEnabled() &&
+ ( aOutSize.Width() == 1 ) && ( aOutSize.Height() == 1 ) ) )
+ {
+ const Graphic aGraphic( rObj.GetTransformedGraphic( &aAttr ) );
+
+ if( aGraphic.IsSupportedGraphic() )
+ aGraphic.Draw( pOut, aPt, aSz );
+
+ bRet = TRUE;
+ }
+
+ // cached/direct drawing
+ if( !bRet )
+ {
+ if( !mpCache->DrawDisplayCacheObj( pOut, aPt, aSz, rObj, aAttr ) )
+ bRet = ImplDraw( pOut, aPt, aSz, rObj, aAttr, rCached );
+ else
+ bRet = rCached = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplRegisterObj( const GraphicObject& rObj, Graphic& rSubstitute, const ByteString* pID )
+{
+ maObjList.Insert( (void*) &rObj, LIST_APPEND );
+ mpCache->AddGraphicObject( rObj, rSubstitute, pID );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplUnregisterObj( const GraphicObject& rObj )
+{
+ mpCache->ReleaseGraphicObject( rObj );
+ maObjList.Remove( (void*) &rObj );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplGraphicObjectWasSwappedOut( const GraphicObject& rObj )
+{
+ mpCache->GraphicObjectWasSwappedOut( rObj );
+}
+
+// -----------------------------------------------------------------------------
+
+ByteString GraphicManager::ImplGetUniqueID( const GraphicObject& rObj ) const
+{
+ return mpCache->GetUniqueID( rObj );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplFillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
+{
+ return( mpCache->FillSwappedGraphicObject( rObj, rSubstitute ) );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplGraphicObjectWasSwappedIn( const GraphicObject& rObj )
+{
+ mpCache->GraphicObjectWasSwappedIn( rObj );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt,
+ const Size& rSz, GraphicObject& rObj,
+ const GraphicAttr& rAttr, BOOL& rCached )
+{
+ const Graphic& rGraphic = rObj.GetGraphic();
+ BOOL bRet = FALSE;
+
+ if( rGraphic.IsSupportedGraphic() && !rGraphic.IsSwapOut() )
+ {
+ if( GRAPHIC_BITMAP == rGraphic.GetType() )
+ {
+ const BitmapEx aSrcBmpEx( rGraphic.GetBitmapEx() );
+
+ if( mpCache->IsDisplayCacheable( pOut, rPt, rSz, rObj, rAttr ) )
+ {
+ BitmapEx aDstBmpEx;
+
+ if( ImplCreateOutput( pOut, rPt, rSz, aSrcBmpEx, rAttr, &aDstBmpEx ) )
+ {
+ rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstBmpEx );
+ bRet = TRUE;
+ }
+ }
+
+ if( !bRet )
+ bRet = ImplCreateOutput( pOut, rPt, rSz, aSrcBmpEx, rAttr );
+ }
+ else
+ {
+ const GDIMetaFile& rSrcMtf = rGraphic.GetGDIMetaFile();
+
+ if( mpCache->IsDisplayCacheable( pOut, rPt, rSz, rObj, rAttr ) )
+ {
+ GDIMetaFile aDstMtf;
+
+ if( ImplCreateOutput( pOut, rPt, rSz, rSrcMtf, rAttr, &aDstMtf ) )
+ {
+ rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstMtf );
+ bRet = TRUE;
+ }
+ }
+
+ if( !bRet )
+ {
+ const Graphic aGraphic( rObj.GetTransformedGraphic( &rAttr ) );
+
+ if( aGraphic.IsSupportedGraphic() )
+ {
+ aGraphic.Draw( pOut, rPt, rSz );
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplCreateOutput( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const BitmapEx& rBmpEx, const GraphicAttr& rAttr,
+ BitmapEx* pBmpEx )
+{
+ const USHORT nRot10 = rAttr.GetRotation() % 3600;
+ const Point aOutPtPix( pOut->LogicToPixel( rPt ) );
+ const Size aOutSzPix( pOut->LogicToPixel( rSz ) );
+ const Size aUntSzPix( nRot10 ? pOut->LogicToPixel( rAttr.GetUntransformedSize() ) : aOutSzPix );
+ BOOL bRet = FALSE;
+
+ if( aUntSzPix.Width() && aUntSzPix.Height() )
+ {
+ BitmapEx aBmpEx( rBmpEx );
+ BitmapEx aOutBmpEx;
+ Point aOutPt;
+ Size aOutSz;
+ const Size& rBmpSzPix = rBmpEx.GetSizePixel();
+ const long nW = rBmpSzPix.Width();
+ const long nH = rBmpSzPix.Height();
+ const long nNewW = aUntSzPix.Width();
+ const long nNewH = aUntSzPix.Height();
+ const double fRevScaleX = ( nNewW > 1L ) ? ( (double) ( nW - 1L ) / ( nNewW - 1L ) ) : 0.0;
+ const double fRevScaleY = ( nNewH > 1L ) ? ( (double) ( nH - 1L ) / ( nNewH - 1L ) ) : 0.0;
+ double fTmp;
+ long* pMapIX = new long[ nNewW ];
+ long* pMapFX = new long[ nNewW ];
+ long* pMapIY = new long[ nNewH ];
+ long* pMapFY = new long[ nNewH ];
+ long nStartX, nStartY, nEndX, nEndY;
+ long nX, nY, nTmp, nTmpX, nTmpY;
+ BOOL bHMirr = ( rAttr.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
+ BOOL bVMirr = ( rAttr.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;
+
+ // create horizontal mapping table
+ for( nX = 0L, nTmpX = nW - 1L, nTmp = nW - 2L; nX < nNewW; nX++ )
+ {
+ fTmp = nX * fRevScaleX;
+
+ if( bHMirr )
+ fTmp = nTmpX - fTmp;
+
+ pMapFX[ nX ] = (long) ( ( fTmp - ( pMapIX[ nX ] = MinMax( (long) fTmp, 0, nTmp ) ) ) * 1048576. );
+ }
+
+ // create vertical mapping table
+ for( nY = 0L, nTmpY = nH - 1L, nTmp = nH - 2L; nY < nNewH; nY++ )
+ {
+ fTmp = nY * fRevScaleY;
+
+ if( bVMirr )
+ fTmp = nTmpY - fTmp;
+
+ pMapFY[ nY ] = (long) ( ( fTmp - ( pMapIY[ nY ] = MinMax( (long) fTmp, 0, nTmp ) ) ) * 1048576. );
+ }
+
+ // calculate output sizes
+ if( !pBmpEx )
+ {
+ Point aPt;
+ Rectangle aOutRect( aPt, pOut->GetOutputSizePixel() );
+ Rectangle aBmpRect( aOutPtPix, aOutSzPix );
+
+ if( pOut->GetOutDevType() == OUTDEV_WINDOW )
+ {
+ const Region aPaintRgn( ( (Window*) pOut )->GetPaintRegion() );
+ if( !aPaintRgn.IsNull() )
+ aOutRect.Intersection( pOut->LogicToPixel( aPaintRgn.GetBoundRect() ) );
+ }
+
+ aOutRect.Intersection( aBmpRect );
+
+ if( !aOutRect.IsEmpty() )
+ {
+ aOutPt = pOut->PixelToLogic( aOutRect.TopLeft() );
+ aOutSz = pOut->PixelToLogic( aOutRect.GetSize() );
+ nStartX = aOutRect.Left() - aBmpRect.Left();
+ nStartY = aOutRect.Top() - aBmpRect.Top();
+ nEndX = aOutRect.Right() - aBmpRect.Left();
+ nEndY = aOutRect.Bottom() - aBmpRect.Top();
+ }
+ else
+ nStartX = -1L; // invalid
+ }
+ else
+ {
+ aOutPt = rPt;
+ aOutSz = rSz;
+ nStartX = nStartY = 0;
+ nEndX = aOutSzPix.Width() - 1L;
+ nEndY = aOutSzPix.Height() - 1L;
+ }
+
+ // do transformation
+ if( nStartX >= 0L )
+ {
+ const BOOL bSimple = ( 1 == nW || 1 == nH );
+
+ if( nRot10 )
+ {
+ if( bSimple )
+ {
+ bRet = ( aOutBmpEx = aBmpEx ).Scale( aUntSzPix );
+
+ if( bRet )
+ aOutBmpEx.Rotate( nRot10, COL_TRANSPARENT );
+ }
+ else
+ {
+ bRet = ImplCreateRotatedScaled( aBmpEx,
+ nRot10, aOutSzPix, aUntSzPix,
+ pMapIX, pMapFX, pMapIY, pMapFY, nStartX, nEndX, nStartY, nEndY,
+ aOutBmpEx );
+ }
+ }
+ else
+ {
+ if( bSimple )
+ bRet = ( aOutBmpEx = aBmpEx ).Scale( Size( nEndX - nStartX + 1, nEndY - nStartY + 1 ) );
+ else
+ {
+ bRet = ImplCreateScaled( aBmpEx,
+ pMapIX, pMapFX, pMapIY, pMapFY,
+ nStartX, nEndX, nStartY, nEndY,
+ aOutBmpEx );
+ }
+ }
+
+ if( bRet )
+ {
+ // attribute adjustment if neccessary
+ if( rAttr.IsSpecialDrawMode() || rAttr.IsAdjusted() || rAttr.IsTransparent() )
+ ImplAdjust( aOutBmpEx, rAttr, ADJUSTMENT_DRAWMODE | ADJUSTMENT_COLORS | ADJUSTMENT_TRANSPARENCY );
+
+ // OutDev adjustment if neccessary
+ if( pOut->GetOutDevType() != OUTDEV_PRINTER && pOut->GetBitCount() <= 8 && aOutBmpEx.GetBitCount() >= 8 )
+ aOutBmpEx.Dither( BMP_DITHER_MATRIX );
+ }
+ }
+
+ // delete lookup tables
+ delete[] pMapIX;
+ delete[] pMapFX;
+ delete[] pMapIY;
+ delete[] pMapFY;
+
+ // create output
+ if( bRet )
+ {
+ if( !pBmpEx )
+ ImplDraw( pOut, aOutPt, aOutSz, aOutBmpEx, rAttr );
+ else
+ {
+ if( !rAttr.IsTransparent() && !aOutBmpEx.IsAlpha() )
+ aOutBmpEx = BitmapEx( aOutBmpEx.GetBitmap().CreateDisplayBitmap( pOut ), aOutBmpEx.GetMask() );
+
+ ImplDraw( pOut, aOutPt, aOutSz, *pBmpEx = aOutBmpEx, rAttr );
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplCreateOutput( OutputDevice* pOut,
+ const Point& rPt, const Size& rSz,
+ const GDIMetaFile& rMtf,
+ const GraphicAttr& rAttr,
+ GDIMetaFile* pMtf )
+{
+ if( !pMtf )
+ {
+ DBG_ERROR( "Missing..." );
+ }
+ else
+ {
+ *pMtf = rMtf;
+
+ if( rAttr.IsSpecialDrawMode() || rAttr.IsAdjusted() || rAttr.IsRotated() || rAttr.IsTransparent() )
+ ImplAdjust( *pMtf, rAttr, ADJUSTMENT_DRAWMODE | ADJUSTMENT_COLORS | ADJUSTMENT_ROTATE | ADJUSTMENT_TRANSPARENCY );
+
+ ImplDraw( pOut, rPt, rSz, *pMtf, rAttr );
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplCreateScaled( const BitmapEx& rBmpEx,
+ long* pMapIX, long* pMapFX, long* pMapIY, long* pMapFY,
+ long nStartX, long nEndX, long nStartY, long nEndY,
+ BitmapEx& rOutBmpEx )
+{
+ Bitmap aBmp( rBmpEx.GetBitmap() );
+ Bitmap aOutBmp;
+ BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
+ BitmapWriteAccess* pWAcc;
+ BitmapColor aCol0, aCol1, aColRes;
+ const long nDstW = nEndX - nStartX + 1L;
+ const long nDstH = nEndY - nStartY + 1L;
+ long nX, nY, nTmpX, nTmpY, nTmpFX, nTmpFY;
+ long nXDst, nYDst;
+ BYTE cR0, cG0, cB0, cR1, cG1, cB1;
+ BOOL bRet = FALSE;
+
+ if( pAcc )
+ {
+ aOutBmp = Bitmap( Size( nDstW, nDstH ), 24 );
+ pWAcc = aOutBmp.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ if( pAcc->HasPalette() )
+ {
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ Scanline pLine0, pLine1;
+
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
+ pLine0 = pAcc->GetScanline( nTmpY );
+ pLine1 = pAcc->GetScanline( ++nTmpY );
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];
+
+ const BitmapColor& rCol0 = pAcc->GetPaletteColor( pLine0[ nTmpX ] );
+ const BitmapColor& rCol2 = pAcc->GetPaletteColor( pLine1[ nTmpX ] );
+ const BitmapColor& rCol1 = pAcc->GetPaletteColor( pLine0[ ++nTmpX ] );
+ const BitmapColor& rCol3 = pAcc->GetPaletteColor( pLine1[ nTmpX ] );
+
+ cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTmpFX );
+ cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTmpFX );
+
+ cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTmpFX );
+ cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTmpFX );
+ cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aColRes );
+ }
+ }
+ }
+ else
+ {
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ], nTmpFY = pMapFY[ nY ];
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];
+
+ aCol0 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, nTmpX ) );
+ aCol1 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, ++nTmpX ) );
+ cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aCol1 = pAcc->GetPaletteColor( pAcc->GetPixel( ++nTmpY, nTmpX ) );
+ aCol0 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY--, --nTmpX ) );
+ cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aColRes );
+ }
+ }
+ }
+ }
+ else
+ {
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
+ {
+ Scanline pLine0, pLine1, pTmp0, pTmp1;
+ long nOff;
+
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
+ pLine0 = pAcc->GetScanline( nTmpY );
+ pLine1 = pAcc->GetScanline( ++nTmpY );
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nOff = 3L * ( nTmpX = pMapIX[ nX ] );
+ nTmpFX = pMapFX[ nX ];
+
+ pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L;
+ cB0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cG0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cR0 = MAP( *pTmp0, *pTmp1, nTmpFX );
+
+ pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L;
+ cB1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cG1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cR1 = MAP( *pTmp0, *pTmp1, nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aColRes );
+ }
+ }
+ }
+ else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB )
+ {
+ Scanline pLine0, pLine1, pTmp0, pTmp1;
+ long nOff;
+
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
+ pLine0 = pAcc->GetScanline( nTmpY );
+ pLine1 = pAcc->GetScanline( ++nTmpY );
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nOff = 3L * ( nTmpX = pMapIX[ nX ] );
+ nTmpFX = pMapFX[ nX ];
+
+ pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L;
+ cR0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cG0 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cB0 = MAP( *pTmp0, *pTmp1, nTmpFX );
+
+ pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L;
+ cR1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cG1 = MAP( *pTmp0, *pTmp1, nTmpFX ); pTmp0++; pTmp1++;
+ cB1 = MAP( *pTmp0, *pTmp1, nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aColRes );
+ }
+ }
+ }
+ else
+ {
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];
+
+ aCol0 = pAcc->GetPixel( nTmpY, nTmpX );
+ aCol1 = pAcc->GetPixel( nTmpY, ++nTmpX );
+ cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aCol1 = pAcc->GetPixel( ++nTmpY, nTmpX );
+ aCol0 = pAcc->GetPixel( nTmpY--, --nTmpX );
+ cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aColRes );
+ }
+ }
+ }
+ }
+
+ aOutBmp.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ aBmp.ReleaseAccess( pAcc );
+ }
+
+ if( bRet && rBmpEx.IsTransparent() )
+ {
+ bRet = FALSE;
+
+ if( rBmpEx.IsAlpha() )
+ {
+ AlphaMask aAlpha( rBmpEx.GetAlpha() );
+ AlphaMask aOutAlpha;
+
+ pAcc = aAlpha.AcquireReadAccess();
+
+ if( pAcc )
+ {
+ aOutAlpha = AlphaMask( Size( nDstW, nDstH ) );
+ pWAcc = aOutAlpha.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL &&
+ pWAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ Scanline pLine0, pLine1, pLineW;
+
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ]; nTmpFY = pMapFY[ nY ];
+ pLine0 = pAcc->GetScanline( nTmpY );
+ pLine1 = pAcc->GetScanline( ++nTmpY );
+ pLineW = pWAcc->GetScanline( nYDst );
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++, nXDst++ )
+ {
+ nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];
+
+ const long nAlpha0 = pLine0[ nTmpX ];
+ const long nAlpha2 = pLine1[ nTmpX ];
+ const long nAlpha1 = pLine0[ ++nTmpX ];
+ const long nAlpha3 = pLine1[ nTmpX ];
+ const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
+ const long n1 = MAP( nAlpha2, nAlpha3, nTmpFX );
+
+ *pLineW++ = MAP( n0, n1, nTmpFY );
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aAlphaValue( 0 );
+
+ for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
+ {
+ nTmpY = pMapIY[ nY ], nTmpFY = pMapFY[ nY ];
+
+ for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
+ {
+ nTmpX = pMapIX[ nX ]; nTmpFX = pMapFX[ nX ];
+
+ long nAlpha0 = pAcc->GetPixel( nTmpY, nTmpX ).GetIndex();
+ long nAlpha1 = pAcc->GetPixel( nTmpY, ++nTmpX ).GetIndex();
+ const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
+
+ nAlpha1 = pAcc->GetPixel( ++nTmpY, nTmpX ).GetIndex();
+ nAlpha0 = pAcc->GetPixel( nTmpY--, --nTmpX ).GetIndex();
+ const long n1 = MAP( nAlpha0, nAlpha1, nTmpFX );
+
+ aAlphaValue.SetIndex( MAP( n0, n1, nTmpFY ) );
+ pWAcc->SetPixel( nYDst, nXDst++, aAlphaValue );
+ }
+ }
+ }
+
+ aOutAlpha.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ aAlpha.ReleaseAccess( pAcc );
+
+ if( bRet )
+ rOutBmpEx = BitmapEx( aOutBmp, aOutAlpha );
+ }
+ }
+ else
+ {
+ Bitmap aMsk( rBmpEx.GetMask() );
+ Bitmap aOutMsk;
+
+ pAcc = aMsk.AcquireReadAccess();
+
+ if( pAcc )
+ {
+ aOutMsk = Bitmap( Size( nDstW, nDstH ), 1 );
+ pWAcc = aOutMsk.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ long* pMapLX = new long[ nDstW ];
+ long* pMapLY = new long[ nDstH ];
+
+ // create new horizontal mapping table
+ for( nX = 0UL, nTmpX = nStartX; nX < nDstW; nTmpX++ )
+ pMapLX[ nX++ ] = FRound( (double) pMapIX[ nTmpX ] + pMapFX[ nTmpX ] / 1048576. );
+
+ // create new vertical mapping table
+ for( nY = 0UL, nTmpY = nStartY; nY < nDstH; nTmpY++ )
+ pMapLY[ nY++ ] = FRound( (double) pMapIY[ nTmpY ] + pMapFY[ nTmpY ] / 1048576. );
+
+ // do normal scaling
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
+ pWAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL )
+ {
+ // optimized
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ Scanline pSrc = pAcc->GetScanline( pMapLY[ nY ] );
+ Scanline pDst = pWAcc->GetScanline( nY );
+
+ for( nX = 0L; nX < nDstW; nX++ )
+ {
+ const long nSrcX = pMapLX[ nX ];
+
+ if( pSrc[ nSrcX >> 3 ] & ( 1 << ( 7 - ( nSrcX & 7 ) ) ) )
+ pDst[ nX >> 3 ] |= 1 << ( 7 - ( nX & 7 ) );
+ else
+ pDst[ nX >> 3 ] &= ~( 1 << ( 7 - ( nX & 7 ) ) );
+ }
+ }
+ }
+ else
+ {
+ const BitmapColor aB( pAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const BitmapColor aWB( pWAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const BitmapColor aWW( pWAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+
+ if( pAcc->HasPalette() )
+ {
+ for( nY = 0L; nY < nDstH; nY++ )
+ {
+ for( nX = 0L; nX < nDstW; nX++ )
+ {
+ if( pAcc->GetPaletteColor( (BYTE) pAcc->GetPixel( pMapLY[ nY ], pMapLX[ nX ] ) ) == aB )
+ pWAcc->SetPixel( nY, nX, aWB );
+ else
+ pWAcc->SetPixel( nY, nX, aWW );
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0L; nY < nDstH; nY++ )
+ {
+ for( nX = 0L; nX < nDstW; nX++ )
+ {
+ if( pAcc->GetPixel( pMapLY[ nY ], pMapLX[ nX ] ) == aB )
+ pWAcc->SetPixel( nY, nX, aWB );
+ else
+ pWAcc->SetPixel( nY, nX, aWW );
+ }
+ }
+ }
+ }
+
+ delete[] pMapLX;
+ delete[] pMapLY;
+ aOutMsk.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ aMsk.ReleaseAccess( pAcc );
+
+ if( bRet )
+ rOutBmpEx = BitmapEx( aOutBmp, aOutMsk );
+ }
+ }
+
+ if( !bRet )
+ rOutBmpEx = aOutBmp;
+ }
+ else
+ rOutBmpEx = aOutBmp;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL GraphicManager::ImplCreateRotatedScaled( const BitmapEx& rBmpEx,
+ USHORT nRot10, const Size& rOutSzPix, const Size& rUntSzPix,
+ long* pMapIX, long* pMapFX, long* pMapIY, long* pMapFY,
+ long nStartX, long nEndX, long nStartY, long nEndY,
+ BitmapEx& rOutBmpEx )
+{
+ Point aPt;
+ Bitmap aBmp( rBmpEx.GetBitmap() );
+ Bitmap aOutBmp;
+ BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
+ BitmapWriteAccess* pWAcc;
+ Polygon aPoly( Rectangle( aPt, rUntSzPix ) ); aPoly.Rotate( Point(), nRot10 );
+ Rectangle aNewBound( aPoly.GetBoundRect() );
+ const double fCosAngle = cos( nRot10 * F_PI1800 ), fSinAngle = sin( nRot10 * F_PI1800 );
+ double fTmp;
+ const long nDstW = nEndX - nStartX + 1L;
+ const long nDstH = nEndY - nStartY + 1L;
+ const long nUnRotW = rUntSzPix.Width();
+ const long nUnRotH = rUntSzPix.Height();
+ long* pCosX = new long[ nDstW ];
+ long* pSinX = new long[ nDstW ];
+ long* pCosY = new long[ nDstH ];
+ long* pSinY = new long[ nDstH ];
+ long nX, nY, nTmpX, nTmpY, nTmpFX, nTmpFY, nUnRotX, nUnRotY, nSinY, nCosY;
+ BYTE cR0, cG0, cB0, cR1, cG1, cB1;
+ BOOL bRet = FALSE;
+
+ // create horizontal mapping table
+ for( nX = 0L, nTmpX = aNewBound.Left() + nStartX; nX < nDstW; nX++ )
+ {
+ pCosX[ nX ] = FRound( fCosAngle * ( fTmp = nTmpX++ << 8 ) );
+ pSinX[ nX ] = FRound( fSinAngle * fTmp );
+ }
+
+ // create vertical mapping table
+ for( nY = 0L, nTmpY = aNewBound.Top() + nStartY; nY < nDstH; nY++ )
+ {
+ pCosY[ nY ] = FRound( fCosAngle * ( fTmp = nTmpY++ << 8 ) );
+ pSinY[ nY ] = FRound( fSinAngle * fTmp );
+ }
+
+ if( pAcc )
+ {
+ aOutBmp = Bitmap( Size( nDstW, nDstH ), 24 );
+ pWAcc = aOutBmp.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ BitmapColor aColRes;
+
+ if( pAcc->HasPalette() )
+ {
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ nSinY = pSinY[ nY ];
+ nCosY = pCosY[ nY ];
+
+ for( nX = 0; nX < nDstW; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ const BitmapColor& rCol0 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, nTmpX ) );
+ const BitmapColor& rCol1 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, ++nTmpX ) );
+ cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTmpFX );
+ cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTmpFX );
+
+ const BitmapColor& rCol3 = pAcc->GetPaletteColor( pAcc->GetPixel( ++nTmpY, nTmpX ) );
+ const BitmapColor& rCol2 = pAcc->GetPaletteColor( pAcc->GetPixel( nTmpY, --nTmpX ) );
+ cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTmpFX );
+ cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTmpFX );
+ cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nY, nX, aColRes );
+ }
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aCol0, aCol1;
+
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ nSinY = pSinY[ nY ];
+ nCosY = pCosY[ nY ];
+
+ for( nX = 0; nX < nDstW; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ aCol0 = pAcc->GetPixel( nTmpY, nTmpX );
+ aCol1 = pAcc->GetPixel( nTmpY, ++nTmpX );
+ cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aCol1 = pAcc->GetPixel( ++nTmpY, nTmpX );
+ aCol0 = pAcc->GetPixel( nTmpY, --nTmpX );
+ cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
+ cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
+ cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
+
+ aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
+ aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
+ aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
+ pWAcc->SetPixel( nY, nX, aColRes );
+ }
+ }
+ }
+ }
+
+ aOutBmp.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ aBmp.ReleaseAccess( pAcc );
+ }
+
+ // mask processing
+ if( bRet && ( rBmpEx.IsTransparent() || ( nRot10 != 900 && nRot10 != 1800 && nRot10 != 2700 ) ) )
+ {
+ bRet = FALSE;
+
+ if( rBmpEx.IsAlpha() )
+ {
+ AlphaMask aAlpha( rBmpEx.GetAlpha() );
+ AlphaMask aOutAlpha;
+
+ pAcc = aAlpha.AcquireReadAccess();
+
+ if( pAcc )
+ {
+ aOutAlpha = AlphaMask( Size( nDstW, nDstH ) );
+ pWAcc = aOutAlpha.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL &&
+ pWAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ Scanline pLine0, pLine1, pLineW;
+
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ nSinY = pSinY[ nY ], nCosY = pCosY[ nY ];
+ pLineW = pWAcc->GetScanline( nY );
+
+ for( nX = 0; nX < nDstW; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ], nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ pLine0 = pAcc->GetScanline( nTmpY++ );
+ pLine1 = pAcc->GetScanline( nTmpY );
+
+ const long nAlpha0 = pLine0[ nTmpX ];
+ const long nAlpha2 = pLine1[ nTmpX++ ];
+ const long nAlpha1 = pLine0[ nTmpX ];
+ const long nAlpha3 = pLine1[ nTmpX ];
+ const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
+ const long n1 = MAP( nAlpha2, nAlpha3, nTmpFX );
+
+ *pLineW++ = MAP( n0, n1, nTmpFY );
+ }
+ else
+ *pLineW++ = 255;
+ }
+ }
+ }
+ else
+ {
+ const BitmapColor aTrans( pWAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ BitmapColor aAlphaVal( 0 );
+
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ nSinY = pSinY[ nY ], nCosY = pCosY[ nY ];
+
+ for( nX = 0; nX < nDstW; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
+ {
+ nTmpX = pMapIX[ nUnRotX ]; nTmpFX = pMapFX[ nUnRotX ];
+ nTmpY = pMapIY[ nUnRotY ], nTmpFY = pMapFY[ nUnRotY ];
+
+ const long nAlpha0 = pAcc->GetPixel( nTmpY, nTmpX ).GetIndex();
+ const long nAlpha1 = pAcc->GetPixel( nTmpY, ++nTmpX ).GetIndex();
+ const long nAlpha3 = pAcc->GetPixel( ++nTmpY, nTmpX ).GetIndex();
+ const long nAlpha2 = pAcc->GetPixel( nTmpY, --nTmpX ).GetIndex();
+ const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
+ const long n1 = MAP( nAlpha2, nAlpha3, nTmpFX );
+
+ aAlphaVal.SetIndex( MAP( n0, n1, nTmpFY ) );
+ pWAcc->SetPixel( nY, nX, aAlphaVal );
+ }
+ else
+ pWAcc->SetPixel( nY, nX, aTrans );
+ }
+ }
+ }
+
+ aOutAlpha.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ aAlpha.ReleaseAccess( pAcc );
+ }
+
+ if( bRet )
+ rOutBmpEx = BitmapEx( aOutBmp, aOutAlpha );
+ }
+ else
+ {
+ Bitmap aOutMsk( Size( nDstW, nDstH ), 1 );
+ pWAcc = aOutMsk.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ Bitmap aMsk( rBmpEx.GetMask() );
+ const BitmapColor aB( pWAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const BitmapColor aW( pWAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ BitmapReadAccess* pMAcc = NULL;
+
+ if( !aMsk || ( ( pMAcc = aMsk.AcquireReadAccess() ) != NULL ) )
+ {
+ long* pMapLX = new long[ nUnRotW ];
+ long* pMapLY = new long[ nUnRotH ];
+ BitmapColor aTestB;
+
+ if( pMAcc )
+ aTestB = pMAcc->GetBestMatchingColor( Color( COL_BLACK ) );
+
+ // create new horizontal mapping table
+ for( nX = 0UL; nX < nUnRotW; nX++ )
+ pMapLX[ nX ] = FRound( (double) pMapIX[ nX ] + pMapFX[ nX ] / 1048576. );
+
+ // create new vertical mapping table
+ for( nY = 0UL; nY < nUnRotH; nY++ )
+ pMapLY[ nY ] = FRound( (double) pMapIY[ nY ] + pMapFY[ nY ] / 1048576. );
+
+ // do mask rotation
+ for( nY = 0; nY < nDstH; nY++ )
+ {
+ nSinY = pSinY[ nY ];
+ nCosY = pCosY[ nY ];
+
+ for( nX = 0; nX < nDstW; nX++ )
+ {
+ nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
+ nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
+
+ if( ( nUnRotX >= 0L ) && ( nUnRotX < nUnRotW ) &&
+ ( nUnRotY >= 0L ) && ( nUnRotY < nUnRotH ) )
+ {
+ if( pMAcc )
+ {
+ if( pMAcc->GetPixel( pMapLY[ nUnRotY ], pMapLX[ nUnRotX ] ) == aTestB )
+ pWAcc->SetPixel( nY, nX, aB );
+ else
+ pWAcc->SetPixel( nY, nX, aW );
+ }
+ else
+ pWAcc->SetPixel( nY, nX, aB );
+ }
+ else
+ pWAcc->SetPixel( nY, nX, aW );
+ }
+ }
+
+ delete[] pMapLX;
+ delete[] pMapLY;
+
+ if( pMAcc )
+ aMsk.ReleaseAccess( pMAcc );
+
+ bRet = TRUE;
+ }
+
+ aOutMsk.ReleaseAccess( pWAcc );
+ }
+
+ if( bRet )
+ rOutBmpEx = BitmapEx( aOutBmp, aOutMsk );
+ }
+
+ if( !bRet )
+ rOutBmpEx = aOutBmp;
+ }
+ else
+ rOutBmpEx = aOutBmp;
+
+ delete[] pSinX;
+ delete[] pCosX;
+ delete[] pSinY;
+ delete[] pCosY;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplAdjust( BitmapEx& rBmpEx, const GraphicAttr& rAttr, ULONG nAdjustmentFlags )
+{
+ GraphicAttr aAttr( rAttr );
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
+ {
+ switch( aAttr.GetDrawMode() )
+ {
+ case( GRAPHICDRAWMODE_MONO ):
+ rBmpEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
+ break;
+
+ case( GRAPHICDRAWMODE_GREYS ):
+ rBmpEx.Convert( BMP_CONVERSION_8BIT_GREYS );
+ break;
+
+ case( GRAPHICDRAWMODE_WATERMARK ):
+ {
+ aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
+ aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
+ {
+ rBmpEx.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
+ aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
+ aAttr.GetGamma(), aAttr.IsInvert() );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
+ {
+ rBmpEx.Mirror( aAttr.GetMirrorFlags() );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
+ {
+ rBmpEx.Rotate( aAttr.GetRotation(), Color( COL_TRANSPARENT ) );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
+ {
+ AlphaMask aAlpha;
+ BYTE cTrans = aAttr.GetTransparency();
+
+ if( !rBmpEx.IsTransparent() )
+ aAlpha = AlphaMask( rBmpEx.GetSizePixel(), &cTrans );
+ else if( !rBmpEx.IsAlpha() )
+ {
+ aAlpha = rBmpEx.GetMask();
+ aAlpha.Replace( 0, cTrans );
+ }
+ else
+ {
+ aAlpha = rBmpEx.GetAlpha();
+ BitmapWriteAccess* pA = aAlpha.AcquireWriteAccess();
+
+ if( pA )
+ {
+ ULONG nTrans = cTrans, nNewTrans;
+ const long nWidth = pA->Width(), nHeight = pA->Height();
+
+ if( pA->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ for( long nY = 0; nY < nHeight; nY++ )
+ {
+ Scanline pAScan = pA->GetScanline( nY );
+
+ for( long nX = 0; nX < nWidth; nX++ )
+ {
+ nNewTrans = nTrans + *pAScan;
+ *pAScan++ = (BYTE) ( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans );
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aAlphaValue( 0 );
+
+ for( long nY = 0; nY < nHeight; nY++ )
+ {
+ for( long nX = 0; nX < nWidth; nX++ )
+ {
+ nNewTrans = nTrans + pA->GetPixel( nY, nX ).GetIndex();
+ aAlphaValue.SetIndex( (BYTE) ( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans ) );
+ pA->SetPixel( nY, nX, aAlphaValue );
+ }
+ }
+ }
+
+ aAlpha.ReleaseAccess( pA );
+ }
+ }
+
+ rBmpEx = BitmapEx( rBmpEx.GetBitmap(), aAlpha );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplAdjust( GDIMetaFile& rMtf, const GraphicAttr& rAttr, ULONG nAdjustmentFlags )
+{
+ GraphicAttr aAttr( rAttr );
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
+ {
+ switch( aAttr.GetDrawMode() )
+ {
+ case( GRAPHICDRAWMODE_MONO ):
+ rMtf.Convert( MTF_CONVERSION_1BIT_THRESHOLD );
+ break;
+
+ case( GRAPHICDRAWMODE_GREYS ):
+ rMtf.Convert( MTF_CONVERSION_8BIT_GREYS );
+ break;
+
+ case( GRAPHICDRAWMODE_WATERMARK ):
+ {
+ aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
+ aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
+ {
+ rMtf.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
+ aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
+ aAttr.GetGamma(), aAttr.IsInvert() );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
+ {
+ Size aPrefSize( rMtf.GetPrefSize() );
+ long nMoveX, nMoveY;
+ double fScaleX, fScaleY;
+
+ if( aAttr.GetMirrorFlags() & BMP_MIRROR_HORZ )
+ nMoveX = VOS_ABS( aPrefSize.Width() ) - 1, fScaleX = -1.0;
+ else
+ nMoveX = 0, fScaleX = 1.0;
+
+ if( aAttr.GetMirrorFlags() & BMP_MIRROR_VERT )
+ nMoveY = VOS_ABS( aPrefSize.Height() ) - 1, fScaleY = -1.0;
+ else
+ nMoveY = 0, fScaleY = 1.0;
+
+ rMtf.Scale( fScaleX, fScaleY );
+ rMtf.Move( nMoveX, nMoveY );
+ rMtf.SetPrefSize( aPrefSize );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
+ {
+ DBG_ERROR( "Missing implementation: Mtf-Rotation" );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
+ {
+ DBG_ERROR( "Missing implementation: Mtf-Transparency" );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplAdjust( Animation& rAnimation, const GraphicAttr& rAttr, ULONG nAdjustmentFlags )
+{
+ GraphicAttr aAttr( rAttr );
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_DRAWMODE ) && aAttr.IsSpecialDrawMode() )
+ {
+ switch( aAttr.GetDrawMode() )
+ {
+ case( GRAPHICDRAWMODE_MONO ):
+ rAnimation.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
+ break;
+
+ case( GRAPHICDRAWMODE_GREYS ):
+ rAnimation.Convert( BMP_CONVERSION_8BIT_GREYS );
+ break;
+
+ case( GRAPHICDRAWMODE_WATERMARK ):
+ {
+ aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
+ aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_COLORS ) && aAttr.IsAdjusted() )
+ {
+ rAnimation.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
+ aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
+ aAttr.GetGamma(), aAttr.IsInvert() );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_MIRROR ) && aAttr.IsMirrored() )
+ rAnimation.Mirror( aAttr.GetMirrorFlags() );
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_ROTATE ) && aAttr.IsRotated() )
+ {
+ DBG_ERROR( "Missing implementation: Animation-Rotation" );
+ }
+
+ if( ( nAdjustmentFlags & ADJUSTMENT_TRANSPARENCY ) && aAttr.IsTransparent() )
+ {
+ DBG_ERROR( "Missing implementation: Animation-Transparency" );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const BitmapEx& rBmpEx, const GraphicAttr& rAttr )
+{
+ pOut->DrawBitmapEx( rPt, rSz, rBmpEx );
+}
+
+// -----------------------------------------------------------------------------
+
+void GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ const GDIMetaFile& rMtf, const GraphicAttr& rAttr )
+{
+ Point aPt( rPt );
+ Size aSz( rSz );
+
+ if( rAttr.IsMirrored() )
+ {
+ if( rAttr.GetMirrorFlags() & BMP_MIRROR_HORZ )
+ {
+ aPt.X() += aSz.Width() - 1;
+ aSz.Width() = -aSz.Width();
+ }
+
+ if( rAttr.GetMirrorFlags() & BMP_MIRROR_VERT )
+ {
+ aPt.Y() += aSz.Height() - 1;
+ aSz.Height() = -aSz.Height();
+ }
+ }
+
+ pOut->Push( PUSH_CLIPREGION );
+ pOut->IntersectClipRegion( Rectangle( aPt, aSz ) );
+
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ ( (GDIMetaFile&) rMtf ).Play( pOut, aPt, aSz );
+ ( (GDIMetaFile&) rMtf ).WindStart();
+
+ pOut->Pop();
+}
+
diff --git a/goodies/source/graphic/makefile.mk b/goodies/source/graphic/makefile.mk
new file mode 100644
index 000000000000..f4c64d5efa7b
--- /dev/null
+++ b/goodies/source/graphic/makefile.mk
@@ -0,0 +1,95 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 16:30:16 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=goodies
+TARGET=graphic
+VERSION=$(UPD)
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+.IF "$(GUI)"=="WIN"
+LINKFLAGS=$(LINKFLAGS) /PACKC:32768
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= \
+ grfattr.cxx \
+ grfmgr.cxx \
+ grfmgr2.cxx \
+ grfcache.cxx
+
+SLOFILES= \
+ $(SLO)$/grfattr.obj \
+ $(SLO)$/grfmgr.obj \
+ $(SLO)$/grfmgr2.obj \
+ $(SLO)$/grfcache.obj
+
+# --- Target -------------------------------------------------------
+
+.INCLUDE : target.mk