diff options
Diffstat (limited to 'goodies/source/graphic')
-rw-r--r-- | goodies/source/graphic/grfattr.cxx | 148 | ||||
-rw-r--r-- | goodies/source/graphic/grfcache.cxx | 876 | ||||
-rw-r--r-- | goodies/source/graphic/grfcache.hxx | 133 | ||||
-rw-r--r-- | goodies/source/graphic/grfmgr.cxx | 851 | ||||
-rw-r--r-- | goodies/source/graphic/grfmgr2.cxx | 1492 | ||||
-rw-r--r-- | goodies/source/graphic/makefile.mk | 95 |
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 |