/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: overlaymanager.cxx,v $ * $Revision: 1.8 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org 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 version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svx.hxx" #include #include #include #include #include #include #include #include #include #include #include ////////////////////////////////////////////////////////////////////////////// namespace sdr { namespace overlay { void OverlayManager::ImpDrawMembers(const basegfx::B2DRange& rRange, OutputDevice& rDestinationDevice) const { ::sdr::overlay::OverlayObject* pCurrent = mpOverlayObjectStart; if(pCurrent) { const sal_uInt16 nOriginalAA(rDestinationDevice.GetAntialiasing()); // react on AntiAliasing settings if(maDrawinglayerOpt.IsAntiAliasing()) { rDestinationDevice.SetAntialiasing(nOriginalAA | ANTIALIASING_ENABLE_B2DDRAW); } else { rDestinationDevice.SetAntialiasing(nOriginalAA & ~ANTIALIASING_ENABLE_B2DDRAW); } while(pCurrent) { if(pCurrent->isVisible()) { if(rRange.overlaps(pCurrent->getBaseRange())) { pCurrent->drawGeometry(rDestinationDevice); } } pCurrent = pCurrent->mpNext; } // restore AA settings rDestinationDevice.SetAntialiasing(nOriginalAA); } } void OverlayManager::ImpCheckMapModeChange() const { sal_Bool bZoomHasChanged(sal_False); MapMode aOutputDeviceMapMode(getOutputDevice().GetMapMode()); ::sdr::overlay::OverlayObject* pCurrent = mpOverlayObjectStart; if(maMapMode != aOutputDeviceMapMode) { bZoomHasChanged = ( maMapMode.GetScaleX() != aOutputDeviceMapMode.GetScaleX() || maMapMode.GetScaleY() != aOutputDeviceMapMode.GetScaleY()); // remember MapMode ((OverlayManager*)this)->maMapMode = aOutputDeviceMapMode; } if(bZoomHasChanged && pCurrent) { while(pCurrent) { pCurrent->zoomHasChanged(); pCurrent = pCurrent->mpNext; } } } void OverlayManager::ImpStripeDefinitionChanged() { ::sdr::overlay::OverlayObject* pCurrent = mpOverlayObjectStart; while(pCurrent) { pCurrent->stripeDefinitionHasChanged(); pCurrent = pCurrent->mpNext; } } double OverlayManager::getDiscreteOne() const { if(getOutputDevice().GetViewTransformation() != maViewTransformation) { OverlayManager* pThis = const_cast< OverlayManager* >(this); pThis->maViewTransformation = getOutputDevice().GetViewTransformation(); const basegfx::B2DVector aDiscreteInLogic(getOutputDevice().GetInverseViewTransformation() * basegfx::B2DVector(1.0, 0.0)); pThis->mfDiscreteOne = aDiscreteInLogic.getLength(); } return mfDiscreteOne; } OverlayManager::OverlayManager(OutputDevice& rOutputDevice) : Scheduler(), rmOutputDevice(rOutputDevice), mpOverlayObjectStart(0L), mpOverlayObjectEnd(0L), maStripeColorA(Color(COL_BLACK)), maStripeColorB(Color(COL_WHITE)), mnStripeLengthPixel(5L), maDrawinglayerOpt(), maViewTransformation(), mfDiscreteOne(0.0) { } OverlayManager::~OverlayManager() { // the OverlayManager is not the owner of the OverlayObjects // and thus will not delete them, but remove them. while(mpOverlayObjectStart) { remove(*mpOverlayObjectStart); } } void OverlayManager::completeRedraw(const Region& rRegion, OutputDevice* pPreRenderDevice) const { if(!rRegion.IsEmpty() && mpOverlayObjectStart) { // check for changed MapModes. That may influence the // logical size of pixel based OverlayObjects (like BitmapHandles) ImpCheckMapModeChange(); // paint members const Rectangle aRegionBoundRect(rRegion.GetBoundRect()); const basegfx::B2DRange aRegionRange( aRegionBoundRect.Left(), aRegionBoundRect.Top(), aRegionBoundRect.Right(), aRegionBoundRect.Bottom()); OutputDevice& rTarget = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice(); ImpDrawMembers(aRegionRange, rTarget); } } void OverlayManager::flush() { // default has nothing to do } // #i68597# part of content gets copied, react on it void OverlayManager::copyArea(const Point& /*rDestPt*/, const Point& /*rSrcPt*/, const Size& /*rSrcSize*/) { // unbuffered versions do nothing here } void OverlayManager::restoreBackground(const Region& /*rRegion*/) const { // unbuffered versions do nothing here } void OverlayManager::add(OverlayObject& rOverlayObject) { // add to the end of chain to preserve display order in paint DBG_ASSERT(0L == rOverlayObject.mpOverlayManager, "OverlayManager::add: OverlayObject is added to an OverlayManager (!)"); if(mpOverlayObjectEnd) { // new element, add to end rOverlayObject.mpNext = mpOverlayObjectEnd->mpNext; rOverlayObject.mpPrevious = mpOverlayObjectEnd; mpOverlayObjectEnd->mpNext = &rOverlayObject; mpOverlayObjectEnd = &rOverlayObject; } else { // first element rOverlayObject.mpNext = rOverlayObject.mpPrevious = 0L; mpOverlayObjectEnd = mpOverlayObjectStart = &rOverlayObject; } // set manager rOverlayObject.mpOverlayManager = this; // make visible invalidateRange(rOverlayObject.getBaseRange()); // handle evtl. animation if(rOverlayObject.allowsAnimation()) { // Trigger at current time to get alive. This will do the // object-specific next time calculation and hand over adding // again to the scheduler to the animated object, too. This works for // a paused or non-paused animator. rOverlayObject.Trigger(GetTime()); } } void OverlayManager::remove(OverlayObject& rOverlayObject) { // handle evtl. animation if(rOverlayObject.allowsAnimation()) { // remove from event chain RemoveEvent(&rOverlayObject); } // Remove from chain DBG_ASSERT(rOverlayObject.mpOverlayManager == this, "OverlayManager::remove: OverlayObject is removed from wrong OverlayManager (!)"); if(rOverlayObject.mpPrevious) { rOverlayObject.mpPrevious->mpNext = rOverlayObject.mpNext; } if(rOverlayObject.mpNext) { rOverlayObject.mpNext->mpPrevious = rOverlayObject.mpPrevious; } if(&rOverlayObject == mpOverlayObjectStart) { mpOverlayObjectStart = rOverlayObject.mpNext; } if(&rOverlayObject == mpOverlayObjectEnd) { mpOverlayObjectEnd = rOverlayObject.mpPrevious; } // make invisible invalidateRange(rOverlayObject.getBaseRange()); // clear manager rOverlayObject.mpOverlayManager = 0L; } void OverlayManager::invalidateRange(const basegfx::B2DRange& rRange) { if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType()) { if(maDrawinglayerOpt.IsAntiAliasing()) { // assume AA needs one pixel more and invalidate one pixel more const double fDiscreteOne(getDiscreteOne()); const Rectangle aInvalidateRectangle( (sal_Int32)floor(rRange.getMinX() - fDiscreteOne), (sal_Int32)floor(rRange.getMinY() - fDiscreteOne), (sal_Int32)ceil(rRange.getMaxX() + fDiscreteOne), (sal_Int32)ceil(rRange.getMaxY() + fDiscreteOne)); // simply invalidate ((Window&)getOutputDevice()).Invalidate(aInvalidateRectangle, INVALIDATE_NOERASE); } else { // #i77674# transform to rectangle. Use floor/ceil to get all covered // discrete pixels, see #i75163# and OverlayManagerBuffered::invalidateRange const Rectangle aInvalidateRectangle( (sal_Int32)floor(rRange.getMinX()), (sal_Int32)floor(rRange.getMinY()), (sal_Int32)ceil(rRange.getMaxX()), (sal_Int32)ceil(rRange.getMaxY())); // simply invalidate ((Window&)getOutputDevice()).Invalidate(aInvalidateRectangle, INVALIDATE_NOERASE); } } } // stripe support ColA void OverlayManager::setStripeColorA(Color aNew) { if(aNew != maStripeColorA) { maStripeColorA = aNew; ImpStripeDefinitionChanged(); } } // stripe support ColB void OverlayManager::setStripeColorB(Color aNew) { if(aNew != maStripeColorB) { maStripeColorB = aNew; ImpStripeDefinitionChanged(); } } // stripe support StripeLengthPixel void OverlayManager::setStripeLengthPixel(sal_uInt32 nNew) { if(nNew != mnStripeLengthPixel) { mnStripeLengthPixel = nNew; ImpStripeDefinitionChanged(); } } ::boost::shared_ptr OverlayManager::GetOverlayObjects (void) const { ::boost::shared_ptr pObjectList (new OverlayObjectVector()); sdr::overlay::OverlayObject* pObject = mpOverlayObjectStart; while (pObject != NULL) { pObjectList->push_back(pObject); pObject = pObject->mpNext; } return pObjectList; } } // end of namespace overlay } // end of namespace sdr ////////////////////////////////////////////////////////////////////////////// // eof