diff options
Diffstat (limited to 'svx/source/sdr/overlay')
18 files changed, 3346 insertions, 0 deletions
diff --git a/svx/source/sdr/overlay/makefile.mk b/svx/source/sdr/overlay/makefile.mk new file mode 100644 index 000000000000..155053826f0d --- /dev/null +++ b/svx/source/sdr/overlay/makefile.mk @@ -0,0 +1,59 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=svx +TARGET=overlay +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/overlayanimatedbitmapex.obj \ + $(SLO)$/overlaybitmapex.obj \ + $(SLO)$/overlaycrosshair.obj \ + $(SLO)$/overlayhatchrect.obj \ + $(SLO)$/overlayhelpline.obj \ + $(SLO)$/overlayline.obj \ + $(SLO)$/overlaymanager.obj \ + $(SLO)$/overlaymanagerbuffered.obj \ + $(SLO)$/overlayobject.obj \ + $(SLO)$/overlayobjectcell.obj \ + $(SLO)$/overlayobjectlist.obj \ + $(SLO)$/overlaypolypolygon.obj \ + $(SLO)$/overlayprimitive2dsequenceobject.obj \ + $(SLO)$/overlayrollingrectangle.obj \ + $(SLO)$/overlayselection.obj \ + $(SLO)$/overlaytools.obj \ + $(SLO)$/overlaytriangle.obj + +.INCLUDE : target.mk diff --git a/svx/source/sdr/overlay/overlayanimatedbitmapex.cxx b/svx/source/sdr/overlay/overlayanimatedbitmapex.cxx new file mode 100644 index 000000000000..6fbd294a6559 --- /dev/null +++ b/svx/source/sdr/overlay/overlayanimatedbitmapex.cxx @@ -0,0 +1,217 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlayanimatedbitmapex.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + // #i53216# check blink time value range + void OverlayAnimatedBitmapEx::impCheckBlinkTimeValueRange() + { + if(mnBlinkTime < 25) + { + mnBlinkTime = 25; + } + else if(mnBlinkTime > 10000) + { + mnBlinkTime = 10000; + } + } + + drawinglayer::primitive2d::Primitive2DSequence OverlayAnimatedBitmapEx::createOverlayObjectPrimitive2DSequence() + { + if(mbOverlayState) + { + const drawinglayer::primitive2d::Primitive2DReference aPrimitive( + new drawinglayer::primitive2d::OverlayBitmapExPrimitive( + getBitmapEx1(), + getBasePosition(), + getCenterX1(), + getCenterY1())); + + return drawinglayer::primitive2d::Primitive2DSequence(&aPrimitive, 1); + } + else + { + const drawinglayer::primitive2d::Primitive2DReference aPrimitive( + new drawinglayer::primitive2d::OverlayBitmapExPrimitive( + getBitmapEx2(), + getBasePosition(), + getCenterX2(), + getCenterY2())); + + return drawinglayer::primitive2d::Primitive2DSequence(&aPrimitive, 1); + } + } + + OverlayAnimatedBitmapEx::OverlayAnimatedBitmapEx( + const basegfx::B2DPoint& rBasePos, + const BitmapEx& rBitmapEx1, + const BitmapEx& rBitmapEx2, + sal_uInt32 nBlinkTime, + sal_uInt16 nCenX1, + sal_uInt16 nCenY1, + sal_uInt16 nCenX2, + sal_uInt16 nCenY2) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_WHITE)), + maBitmapEx1(rBitmapEx1), + maBitmapEx2(rBitmapEx2), + mnCenterX1(nCenX1), mnCenterY1(nCenY1), + mnCenterX2(nCenX2), mnCenterY2(nCenY2), + mnBlinkTime(nBlinkTime), + mbOverlayState(false) + { + // set AllowsAnimation flag to mark this object as animation capable + mbAllowsAnimation = true; + + // #i53216# check blink time value range + impCheckBlinkTimeValueRange(); + } + + OverlayAnimatedBitmapEx::~OverlayAnimatedBitmapEx() + { + } + + void OverlayAnimatedBitmapEx::setBitmapEx1(const BitmapEx& rNew) + { + if(rNew != maBitmapEx1) + { + // remember new Bitmap + maBitmapEx1 = rNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayAnimatedBitmapEx::setBitmapEx2(const BitmapEx& rNew) + { + if(rNew != maBitmapEx2) + { + // remember new Bitmap + maBitmapEx2 = rNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayAnimatedBitmapEx::setCenterXY1(sal_uInt16 nNewX, sal_uInt16 nNewY) + { + if(nNewX != mnCenterX1 || nNewY != mnCenterY1) + { + // remember new values + if(nNewX != mnCenterX1) + { + mnCenterX1 = nNewX; + } + + if(nNewY != mnCenterY1) + { + mnCenterY1 = nNewY; + } + + // register change (after change) + objectChange(); + } + } + + void OverlayAnimatedBitmapEx::setCenterXY2(sal_uInt16 nNewX, sal_uInt16 nNewY) + { + if(nNewX != mnCenterX2 || nNewY != mnCenterY2) + { + // remember new values + if(nNewX != mnCenterX2) + { + mnCenterX2 = nNewX; + } + + if(nNewY != mnCenterY2) + { + mnCenterY2 = nNewY; + } + + // register change (after change) + objectChange(); + } + } + + void OverlayAnimatedBitmapEx::setBlinkTime(sal_uInt32 nNew) + { + if(mnBlinkTime != nNew) + { + // remember new value + mnBlinkTime = nNew; + + // #i53216# check blink time value range + impCheckBlinkTimeValueRange(); + + // register change (after change) + objectChange(); + } + } + + void OverlayAnimatedBitmapEx::Trigger(sal_uInt32 nTime) + { + if(getOverlayManager()) + { + // #i53216# produce event after nTime + x + SetTime(nTime + mnBlinkTime); + + // switch state + if(mbOverlayState) + { + mbOverlayState = false; + } + else + { + mbOverlayState = true; + } + + // re-insert me as event + getOverlayManager()->InsertEvent(this); + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaybitmapex.cxx b/svx/source/sdr/overlay/overlaybitmapex.cxx new file mode 100644 index 000000000000..ac1e5aa4ef1c --- /dev/null +++ b/svx/source/sdr/overlay/overlaybitmapex.cxx @@ -0,0 +1,104 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlaybitmapex.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayBitmapEx::createOverlayObjectPrimitive2DSequence() + { + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::OverlayBitmapExPrimitive( + getBitmapEx(), + getBasePosition(), + getCenterX(), + getCenterY())); + + return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + OverlayBitmapEx::OverlayBitmapEx( + const basegfx::B2DPoint& rBasePos, + const BitmapEx& rBitmapEx, + sal_uInt16 nCenX, sal_uInt16 nCenY) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_WHITE)), + maBitmapEx(rBitmapEx), + mnCenterX(nCenX), + mnCenterY(nCenY) + { + } + + OverlayBitmapEx::~OverlayBitmapEx() + { + } + + void OverlayBitmapEx::setBitmapEx(const BitmapEx& rNew) + { + if(rNew != maBitmapEx) + { + // remember new Bitmap + maBitmapEx = rNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayBitmapEx::setCenterXY(sal_uInt16 nNewX, sal_uInt16 nNewY) + { + if(nNewX != mnCenterX || nNewY != mnCenterY) + { + // remember new values + if(nNewX != mnCenterX) + { + mnCenterX = nNewX; + } + + if(nNewY != mnCenterY) + { + mnCenterY = nNewY; + } + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaycrosshair.cxx b/svx/source/sdr/overlay/overlaycrosshair.cxx new file mode 100644 index 000000000000..cf1c4c4a3c88 --- /dev/null +++ b/svx/source/sdr/overlay/overlaycrosshair.cxx @@ -0,0 +1,84 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlaycrosshair.hxx> +#include <tools/gen.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayCrosshairStriped::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + + if(getOverlayManager()) + { + const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); + const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); + const double fStripeLengthPixel(getOverlayManager()->getStripeLengthPixel()); + + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::OverlayCrosshairPrimitive( + getBasePosition(), + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + return aRetval; + } + + void OverlayCrosshairStriped::stripeDefinitionHasChanged() + { + // react on OverlayManager's stripe definition change + objectChange(); + } + + OverlayCrosshairStriped::OverlayCrosshairStriped(const basegfx::B2DPoint& rBasePos) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_BLACK)) + { + } + + OverlayCrosshairStriped::~OverlayCrosshairStriped() + { + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayhatchrect.cxx b/svx/source/sdr/overlay/overlayhatchrect.cxx new file mode 100644 index 000000000000..64bd9e11b31f --- /dev/null +++ b/svx/source/sdr/overlay/overlayhatchrect.cxx @@ -0,0 +1,94 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/overlay/overlayhatchrect.hxx> +#include <vcl/hatch.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayHatchRect::createOverlayObjectPrimitive2DSequence() + { + const basegfx::B2DRange aHatchRange(getBasePosition(), getSecondPosition()); + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::OverlayHatchRectanglePrimitive( + aHatchRange, + 3.0, + getHatchRotation(), + getBaseColor().getBColor(), + getDiscreteGrow(), + getDiscreteShrink(), + getRotation())); + + return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + OverlayHatchRect::OverlayHatchRect( + const basegfx::B2DPoint& rBasePosition, + const basegfx::B2DPoint& rSecondPosition, + const Color& rHatchColor, + double fDiscreteGrow, + double fDiscreteShrink, + double fHatchRotation, + double fRotation) + : OverlayObjectWithBasePosition(rBasePosition, rHatchColor), + maSecondPosition(rSecondPosition), + mfDiscreteGrow(fDiscreteGrow), + mfDiscreteShrink(fDiscreteShrink), + mfHatchRotation(fHatchRotation), + mfRotation(fRotation) + { + } + + void OverlayHatchRect::setSecondPosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maSecondPosition) + { + // remember new value + maSecondPosition = rNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayhelpline.cxx b/svx/source/sdr/overlay/overlayhelpline.cxx new file mode 100644 index 000000000000..3417cc4a651f --- /dev/null +++ b/svx/source/sdr/overlay/overlayhelpline.cxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlayhelpline.hxx> +#include <tools/gen.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/vector/b2dvector.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayHelplineStriped::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + + if(getOverlayManager()) + { + const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); + const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); + const double fStripeLengthPixel(getOverlayManager()->getStripeLengthPixel()); + const drawinglayer::primitive2d::HelplineStyle aStyle( + SDRHELPLINE_POINT == getKind() ? drawinglayer::primitive2d::HELPLINESTYLE_POINT : + SDRHELPLINE_VERTICAL == getKind() ? drawinglayer::primitive2d::HELPLINESTYLE_VERTICAL : + drawinglayer::primitive2d::HELPLINESTYLE_HORIZONTAL); + + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::OverlayHelplineStripedPrimitive( + getBasePosition(), + aStyle, + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + return aRetval; + } + + void OverlayHelplineStriped::stripeDefinitionHasChanged() + { + // react on OverlayManager's stripe definition change + objectChange(); + } + + OverlayHelplineStriped::OverlayHelplineStriped( + const basegfx::B2DPoint& rBasePos, + SdrHelpLineKind eNewKind) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_BLACK)), + meKind(eNewKind) + { + } + + OverlayHelplineStriped::~OverlayHelplineStriped() + { + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayline.cxx b/svx/source/sdr/overlay/overlayline.cxx new file mode 100644 index 000000000000..4d53ac480241 --- /dev/null +++ b/svx/source/sdr/overlay/overlayline.cxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlayline.hxx> +#include <tools/gen.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/vector/b2dvector.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayLineStriped::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + + if(getOverlayManager()) + { + const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); + const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); + const double fStripeLengthPixel(getOverlayManager()->getStripeLengthPixel()); + basegfx::B2DPolygon aLine; + + aLine.append(getBasePosition()); + aLine.append(getSecondPosition()); + + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::PolygonMarkerPrimitive2D( + aLine, + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + return aRetval; + } + + void OverlayLineStriped::stripeDefinitionHasChanged() + { + // react on OverlayManager's stripe definition change + objectChange(); + } + + OverlayLineStriped::OverlayLineStriped( + const basegfx::B2DPoint& rBasePos, + const basegfx::B2DPoint& rSecondPos) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_BLACK)), + maSecondPosition(rSecondPos) + { + } + + OverlayLineStriped::~OverlayLineStriped() + { + } + + void OverlayLineStriped::setSecondPosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maSecondPosition) + { + // remember new value + maSecondPosition = rNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaymanager.cxx b/svx/source/sdr/overlay/overlaymanager.cxx new file mode 100644 index 000000000000..f52205d88e45 --- /dev/null +++ b/svx/source/sdr/overlay/overlaymanager.cxx @@ -0,0 +1,393 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/range/b2drange.hxx> +#include <tools/gen.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <vcl/window.hxx> +#include <svx/sdr/overlay/overlayobject.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/processor2d/baseprocessor2d.hxx> +#include <svx/sdr/contact/objectcontacttools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + void OverlayManager::ImpDrawMembers(const basegfx::B2DRange& rRange, OutputDevice& rDestinationDevice) const + { + const sal_uInt32 nSize(maOverlayObjects.size()); + + if(nSize) + { + const sal_uInt16 nOriginalAA(rDestinationDevice.GetAntialiasing()); + const bool bIsAntiAliasing(getDrawinglayerOpt().IsAntiAliasing()); + + // create processor + drawinglayer::processor2d::BaseProcessor2D* pProcessor = ::sdr::contact::createBaseProcessor2DFromOutputDevice( + rDestinationDevice, + getCurrentViewInformation2D()); + + if(pProcessor) + { + for(OverlayObjectVector::const_iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); aIter++) + { + OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)"); + const OverlayObject& rCandidate = **aIter; + + if(rCandidate.isVisible()) + { + const drawinglayer::primitive2d::Primitive2DSequence& rSequence = rCandidate.getOverlayObjectPrimitive2DSequence(); + + if(rSequence.hasElements()) + { + if(rRange.overlaps(rCandidate.getBaseRange())) + { + if(bIsAntiAliasing && rCandidate.allowsAntiAliase()) + { + rDestinationDevice.SetAntialiasing(nOriginalAA | ANTIALIASING_ENABLE_B2DDRAW); + } + else + { + rDestinationDevice.SetAntialiasing(nOriginalAA & ~ANTIALIASING_ENABLE_B2DDRAW); + } + + pProcessor->process(rSequence); + } + } + } + } + + delete pProcessor; + } + + // restore AA settings + rDestinationDevice.SetAntialiasing(nOriginalAA); + } + } + + void OverlayManager::ImpStripeDefinitionChanged() + { + const sal_uInt32 nSize(maOverlayObjects.size()); + + if(nSize) + { + for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); aIter++) + { + OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)"); + OverlayObject& rCandidate = **aIter; + rCandidate.stripeDefinitionHasChanged(); + } + } + } + + double OverlayManager::getDiscreteOne() const + { + if(basegfx::fTools::equalZero(mfDiscreteOne)) + { + const basegfx::B2DVector aDiscreteInLogic(getOutputDevice().GetInverseViewTransformation() * basegfx::B2DVector(1.0, 0.0)); + const_cast< OverlayManager* >(this)->mfDiscreteOne = aDiscreteInLogic.getLength(); + } + + return mfDiscreteOne; + } + + OverlayManager::OverlayManager( + OutputDevice& rOutputDevice, + OverlayManager* pOldOverlayManager) + : Scheduler(), + rmOutputDevice(rOutputDevice), + maOverlayObjects(), + maStripeColorA(Color(COL_BLACK)), + maStripeColorB(Color(COL_WHITE)), + mnStripeLengthPixel(5), + maDrawinglayerOpt(), + maViewTransformation(), + maViewInformation2D(0), + mfDiscreteOne(0.0) + { + // set Property 'ReducedDisplayQuality' to true to allow simpler interaction + // visualisations + static bool bUseReducedDisplayQualityForDrag(true); + + if(bUseReducedDisplayQualityForDrag) + { + uno::Sequence< beans::PropertyValue > xProperties(1); + xProperties[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedDisplayQuality")); + xProperties[0].Value <<= true; + maViewInformation2D = drawinglayer::geometry::ViewInformation2D(xProperties); + } + + if(pOldOverlayManager) + { + // take over OverlayObjects from given OverlayManager. Copy + // the vector of pointers + maOverlayObjects = pOldOverlayManager->maOverlayObjects; + const sal_uInt32 nSize(maOverlayObjects.size()); + + if(nSize) + { + for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); aIter++) + { + OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)"); + OverlayObject& rCandidate = **aIter; + + // remove from old and add to new OverlayManager + pOldOverlayManager->impApplyRemoveActions(rCandidate); + impApplyAddActions(rCandidate); + } + + pOldOverlayManager->maOverlayObjects.clear(); + } + } + } + + const drawinglayer::geometry::ViewInformation2D OverlayManager::getCurrentViewInformation2D() const + { + if(getOutputDevice().GetViewTransformation() != maViewTransformation) + { + basegfx::B2DRange aViewRange(maViewInformation2D.getViewport()); + + if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType()) + { + const Size aOutputSizePixel(getOutputDevice().GetOutputSizePixel()); + aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight()); + aViewRange.transform(getOutputDevice().GetInverseViewTransformation()); + } + + OverlayManager* pThis = const_cast< OverlayManager* >(this); + + pThis->maViewTransformation = getOutputDevice().GetViewTransformation(); + pThis->maViewInformation2D = drawinglayer::geometry::ViewInformation2D( + maViewInformation2D.getObjectTransformation(), + maViewTransformation, + aViewRange, + maViewInformation2D.getVisualizedPage(), + maViewInformation2D.getViewTime(), + maViewInformation2D.getExtendedInformationSequence()); + pThis->mfDiscreteOne = 0.0; + } + + return maViewInformation2D; + } + + void OverlayManager::impApplyRemoveActions(OverlayObject& rTarget) + { + // handle evtl. animation + if(rTarget.allowsAnimation()) + { + // remove from event chain + RemoveEvent(&rTarget); + } + + // make invisible + invalidateRange(rTarget.getBaseRange()); + + // clear manager + rTarget.mpOverlayManager = 0; + } + + void OverlayManager::impApplyAddActions(OverlayObject& rTarget) + { + // set manager + rTarget.mpOverlayManager = this; + + // make visible + invalidateRange(rTarget.getBaseRange()); + + // handle evtl. animation + if(rTarget.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. + rTarget.Trigger(GetTime()); + } + } + + OverlayManager::~OverlayManager() + { + // The OverlayManager is not the owner of the OverlayObjects + // and thus will not delete them, but remove them. Profit here + // from knowing that all will be removed + const sal_uInt32 nSize(maOverlayObjects.size()); + + if(nSize) + { + for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); aIter++) + { + OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)"); + OverlayObject& rCandidate = **aIter; + impApplyRemoveActions(rCandidate); + } + + // erase vector + maOverlayObjects.clear(); + } + } + + void OverlayManager::completeRedraw(const Region& rRegion, OutputDevice* pPreRenderDevice) const + { + if(!rRegion.IsEmpty() && maOverlayObjects.size()) + { + // 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) + { + OSL_ENSURE(0 == rOverlayObject.mpOverlayManager, "OverlayObject is added twice to an OverlayManager (!)"); + + // add to the end of chain to preserve display order in paint + maOverlayObjects.push_back(&rOverlayObject); + + // execute add actions + impApplyAddActions(rOverlayObject); + } + + void OverlayManager::remove(OverlayObject& rOverlayObject) + { + OSL_ENSURE(rOverlayObject.mpOverlayManager == this, "OverlayObject is removed from wrong OverlayManager (!)"); + + // execute remove actions + impApplyRemoveActions(rOverlayObject); + + // remove from vector + const OverlayObjectVector::iterator aFindResult = ::std::find(maOverlayObjects.begin(), maOverlayObjects.end(), &rOverlayObject); + const bool bFound(aFindResult != maOverlayObjects.end()); + OSL_ENSURE(bFound, "OverlayObject NOT found at OverlayManager (!)"); + + if(bFound) + { + maOverlayObjects.erase(aFindResult); + } + } + + void OverlayManager::invalidateRange(const basegfx::B2DRange& rRange) + { + if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType()) + { + if(getDrawinglayerOpt().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(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx new file mode 100644 index 000000000000..dcbf12991d30 --- /dev/null +++ b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx @@ -0,0 +1,538 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlaymanagerbuffered.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/range/b2drange.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/window.hxx> +#include <vcl/bitmap.hxx> +#include <tools/stream.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <vcl/cursor.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + void OverlayManagerBuffered::ImpPrepareBufferDevice() + { + // compare size of maBufferDevice with size of visible area + if(maBufferDevice.GetOutputSizePixel() != getOutputDevice().GetOutputSizePixel()) + { + // set new buffer size, copy as much content as possible (use bool parameter for vcl). + // Newly uncovered regions will be repainted. + maBufferDevice.SetOutputSizePixel(getOutputDevice().GetOutputSizePixel(), false); + } + + // compare the MapModes for zoom/scroll changes + if(maBufferDevice.GetMapMode() != getOutputDevice().GetMapMode()) + { + const bool bZoomed( + maBufferDevice.GetMapMode().GetScaleX() != getOutputDevice().GetMapMode().GetScaleX() + || maBufferDevice.GetMapMode().GetScaleY() != getOutputDevice().GetMapMode().GetScaleY()); + + if(!bZoomed) + { + const Point& rOriginOld = maBufferDevice.GetMapMode().GetOrigin(); + const Point& rOriginNew = getOutputDevice().GetMapMode().GetOrigin(); + const bool bScrolled(rOriginOld != rOriginNew); + + if(bScrolled) + { + // get pixel bounds + const Point aOriginOldPixel(maBufferDevice.LogicToPixel(rOriginOld)); + const Point aOriginNewPixel(maBufferDevice.LogicToPixel(rOriginNew)); + const Size aOutputSizePixel(maBufferDevice.GetOutputSizePixel()); + + // remember and switch off MapMode + const bool bMapModeWasEnabled(maBufferDevice.IsMapModeEnabled()); + maBufferDevice.EnableMapMode(false); + + // scroll internally buffered stuff + const Point aDestinationOffsetPixel(aOriginNewPixel - aOriginOldPixel); + maBufferDevice.DrawOutDev( + aDestinationOffsetPixel, aOutputSizePixel, // destination + Point(), aOutputSizePixel); // source + + // restore MapMode + maBufferDevice.EnableMapMode(bMapModeWasEnabled); + + // scroll remembered region, too. + if(!maBufferRememberedRangePixel.isEmpty()) + { + const basegfx::B2IPoint aIPointDestinationOffsetPixel(aDestinationOffsetPixel.X(), aDestinationOffsetPixel.Y()); + const basegfx::B2IPoint aNewMinimum(maBufferRememberedRangePixel.getMinimum() + aIPointDestinationOffsetPixel); + const basegfx::B2IPoint aNewMaximum(maBufferRememberedRangePixel.getMaximum() + aIPointDestinationOffsetPixel); + maBufferRememberedRangePixel = basegfx::B2IRange(aNewMinimum, aNewMaximum); + } + } + } + + // copy new MapMode + maBufferDevice.SetMapMode(getOutputDevice().GetMapMode()); + } + + // #i29186# + maBufferDevice.SetDrawMode(getOutputDevice().GetDrawMode()); + maBufferDevice.SetSettings(getOutputDevice().GetSettings()); + maBufferDevice.SetAntialiasing(getOutputDevice().GetAntialiasing()); + } + + void OverlayManagerBuffered::ImpRestoreBackground() const + { + const Rectangle aRegionRectanglePixel( + maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), + maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); + const Region aRegionPixel(aRegionRectanglePixel); + + ImpRestoreBackground(aRegionPixel); + } + + void OverlayManagerBuffered::ImpRestoreBackground(const Region& rRegionPixel) const + { + // local region + Region aRegionPixel(rRegionPixel); + RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects()); + Rectangle aRegionRectanglePixel; + + // MapModes off + const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled()); + const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled()); + getOutputDevice().EnableMapMode(false); + ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(false); + + while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel)) + { +#ifdef DBG_UTIL + // #i72754# possible graphical region test only with non-pro + static bool bDoPaintForVisualControl(false); + if(bDoPaintForVisualControl) + { + getOutputDevice().SetLineColor(COL_LIGHTGREEN); + getOutputDevice().SetFillColor(); + getOutputDevice().DrawRect(aRegionRectanglePixel); + } +#endif + + // restore the area + const Point aTopLeft(aRegionRectanglePixel.TopLeft()); + const Size aSize(aRegionRectanglePixel.GetSize()); + + getOutputDevice().DrawOutDev( + aTopLeft, aSize, // destination + aTopLeft, aSize, // source + maBufferDevice); + } + + aRegionPixel.EndEnumRects(aRegionHandle); + + // restore MapModes + getOutputDevice().EnableMapMode(bMapModeWasEnabledDest); + ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(bMapModeWasEnabledSource); + } + + void OverlayManagerBuffered::ImpSaveBackground(const Region& rRegion, OutputDevice* pPreRenderDevice) + { + // prepare source + OutputDevice& rSource = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice(); + + // Ensure buffer is valid + ImpPrepareBufferDevice(); + + // build region which needs to be copied + Region aRegion(rSource.LogicToPixel(rRegion)); + + // limit to PaintRegion if it's a window. This will be evtl. the expanded one, + // but always the exact redraw area + if(OUTDEV_WINDOW == rSource.GetOutDevType()) + { + Window& rWindow = (Window&)rSource; + Region aPaintRegionPixel = rWindow.LogicToPixel(rWindow.GetPaintRegion()); + aRegion.Intersect(aPaintRegionPixel); + + // #i72754# Make sure content is completetly rendered, the window + // will be used as source of a DrawOutDev soon + rWindow.Flush(); + } + + // also limit to buffer size + const Rectangle aBufferDeviceRectanglePixel = Rectangle(Point(), maBufferDevice.GetOutputSizePixel()); + aRegion.Intersect(aBufferDeviceRectanglePixel); + + // prepare to iterate over the rectangles from the region in pixels + RegionHandle aRegionHandle(aRegion.BeginEnumRects()); + Rectangle aRegionRectanglePixel; + + // MapModes off + const bool bMapModeWasEnabledDest(rSource.IsMapModeEnabled()); + const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled()); + rSource.EnableMapMode(false); + maBufferDevice.EnableMapMode(false); + + while(aRegion.GetEnumRects(aRegionHandle, aRegionRectanglePixel)) + { + // for each rectangle, save the area + Point aTopLeft(aRegionRectanglePixel.TopLeft()); + Size aSize(aRegionRectanglePixel.GetSize()); + + maBufferDevice.DrawOutDev( + aTopLeft, aSize, // destination + aTopLeft, aSize, // source + rSource); + +#ifdef DBG_UTIL + // #i72754# possible graphical region test only with non-pro + static bool bDoPaintForVisualControl(false); + if(bDoPaintForVisualControl) + { + const bool bMapModeWasEnabledTest(getOutputDevice().IsMapModeEnabled()); + getOutputDevice().EnableMapMode(false); + getOutputDevice().SetLineColor(COL_LIGHTRED); + getOutputDevice().SetFillColor(); + getOutputDevice().DrawRect(aRegionRectanglePixel); + getOutputDevice().EnableMapMode(bMapModeWasEnabledTest); + } + + static bool bDoSaveForVisualControl(false); + if(bDoSaveForVisualControl) + { + const Bitmap aBitmap(maBufferDevice.GetBitmap(aTopLeft, aSize)); + SvFileStream aNew((const String&)String(ByteString( "c:\\test.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC); + aNew << aBitmap; + } +#endif + } + + aRegion.EndEnumRects(aRegionHandle); + + // restore MapModes + rSource.EnableMapMode(bMapModeWasEnabledDest); + maBufferDevice.EnableMapMode(bMapModeWasEnabledSource); + } + + IMPL_LINK(OverlayManagerBuffered, ImpBufferTimerHandler, AutoTimer*, /*pTimer*/) + { + // stop timer + maBufferTimer.Stop(); + + if(!maBufferRememberedRangePixel.isEmpty()) + { + // logic size for impDrawMember call + basegfx::B2DRange aBufferRememberedRangeLogic( + maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), + maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); + aBufferRememberedRangeLogic.transform(getOutputDevice().GetInverseViewTransformation()); + + // prepare cursor handling + const bool bTargetIsWindow(OUTDEV_WINDOW == rmOutputDevice.GetOutDevType()); + bool bCursorWasEnabled(false); + + // #i80730# switch off VCL cursor during overlay refresh + if(bTargetIsWindow) + { + Window& rWindow = static_cast< Window& >(rmOutputDevice); + Cursor* pCursor = rWindow.GetCursor(); + + if(pCursor && pCursor->IsVisible()) + { + pCursor->Hide(); + bCursorWasEnabled = true; + } + } + + if(DoRefreshWithPreRendering()) + { + // #i73602# ensure valid and sized maOutputBufferDevice + const Size aDestinationSizePixel(maBufferDevice.GetOutputSizePixel()); + const Size aOutputBufferSizePixel(maOutputBufferDevice.GetOutputSizePixel()); + + if(aDestinationSizePixel != aOutputBufferSizePixel) + { + maOutputBufferDevice.SetOutputSizePixel(aDestinationSizePixel); + } + + maOutputBufferDevice.SetMapMode(getOutputDevice().GetMapMode()); + maOutputBufferDevice.EnableMapMode(false); + maOutputBufferDevice.SetDrawMode(maBufferDevice.GetDrawMode()); + maOutputBufferDevice.SetSettings(maBufferDevice.GetSettings()); + maOutputBufferDevice.SetAntialiasing(maBufferDevice.GetAntialiasing()); + + // calculate sizes + Rectangle aRegionRectanglePixel( + maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), + maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); + + // truncate aRegionRectanglePixel to destination pixel size, more does + // not need to be prepared since destination is a buffer for a window. So, + // maximum size indirectly shall be limited to getOutputDevice().GetOutputSizePixel() + if(aRegionRectanglePixel.Left() < 0L) + { + aRegionRectanglePixel.Left() = 0L; + } + + if(aRegionRectanglePixel.Top() < 0L) + { + aRegionRectanglePixel.Top() = 0L; + } + + if(aRegionRectanglePixel.Right() > aDestinationSizePixel.getWidth()) + { + aRegionRectanglePixel.Right() = aDestinationSizePixel.getWidth(); + } + + if(aRegionRectanglePixel.Bottom() > aDestinationSizePixel.getHeight()) + { + aRegionRectanglePixel.Bottom() = aDestinationSizePixel.getHeight(); + } + + // get sizes + const Point aTopLeft(aRegionRectanglePixel.TopLeft()); + const Size aSize(aRegionRectanglePixel.GetSize()); + + { + const bool bMapModeWasEnabledDest(maBufferDevice.IsMapModeEnabled()); + maBufferDevice.EnableMapMode(false); + + maOutputBufferDevice.DrawOutDev( + aTopLeft, aSize, // destination + aTopLeft, aSize, // source + maBufferDevice); + + // restore MapModes + maBufferDevice.EnableMapMode(bMapModeWasEnabledDest); + } + + // paint overlay content for remembered region, use + // method from base class directly + maOutputBufferDevice.EnableMapMode(true); + OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, maOutputBufferDevice); + maOutputBufferDevice.EnableMapMode(false); + + // copy to output + { + const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled()); + getOutputDevice().EnableMapMode(false); + + getOutputDevice().DrawOutDev( + aTopLeft, aSize, // destination + aTopLeft, aSize, // source + maOutputBufferDevice); + + // debug + /*getOutputDevice().SetLineColor(COL_RED); + getOutputDevice().SetFillColor(); + getOutputDevice().DrawRect(Rectangle(aTopLeft, aSize));*/ + + // restore MapModes + getOutputDevice().EnableMapMode(bMapModeWasEnabledDest); + } + } + else + { + // Restore all rectangles for remembered region from buffer + ImpRestoreBackground(); + + // paint overlay content for remembered region, use + // method from base class directly + OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, getOutputDevice()); + } + + // VCL hack for transparent child windows + // Problem is e.g. a radiobuttion form control in life mode. The used window + // is a transparence vcl childwindow. This flag only allows the parent window to + // paint into the child windows area, but there is no mechanism which takes + // care for a repaint of the child window. A transparent child window is NOT + // a window which always keeps it's content consistent over the parent, but it's + // more like just a paint flag for the parent. + // To get the update, the windows in question are updated manulally here. + if(bTargetIsWindow) + { + Window& rWindow = static_cast< Window& >(rmOutputDevice); + + if(rWindow.IsChildTransparentModeEnabled() && rWindow.GetChildCount()) + { + const Rectangle aRegionRectanglePixel( + maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), + maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); + + for(sal_uInt16 a(0); a < rWindow.GetChildCount(); a++) + { + Window* pCandidate = rWindow.GetChild(a); + + if(pCandidate && pCandidate->IsPaintTransparent()) + { + const Rectangle aCandidatePosSizePixel(pCandidate->GetPosPixel(), pCandidate->GetSizePixel()); + + if(aCandidatePosSizePixel.IsOver(aRegionRectanglePixel)) + { + pCandidate->Invalidate(INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN); + pCandidate->Update(); + } + } + } + } + } + + // #i80730# restore visibility of VCL cursor + if(bCursorWasEnabled) + { + Window& rWindow = static_cast< Window& >(rmOutputDevice); + Cursor* pCursor = rWindow.GetCursor(); + + if(pCursor) + { + // check if cursor still exists. It may have been deleted from someone + pCursor->Show(); + } + } + + // forget remembered Region + maBufferRememberedRangePixel.reset(); + } + + return 0; + } + + OverlayManagerBuffered::OverlayManagerBuffered( + OutputDevice& rOutputDevice, + OverlayManager* pOldOverlayManager, + bool bRefreshWithPreRendering) + : OverlayManager(rOutputDevice, pOldOverlayManager), + mbRefreshWithPreRendering(bRefreshWithPreRendering) + { + // Init timer + maBufferTimer.SetTimeout(1); + maBufferTimer.SetTimeoutHdl(LINK(this, OverlayManagerBuffered, ImpBufferTimerHandler)); + } + + OverlayManagerBuffered::~OverlayManagerBuffered() + { + // Clear timer + maBufferTimer.Stop(); + + if(!maBufferRememberedRangePixel.isEmpty()) + { + // Restore all rectangles for remembered region from buffer + ImpRestoreBackground(); + } + } + + void OverlayManagerBuffered::completeRedraw(const Region& rRegion, OutputDevice* pPreRenderDevice) const + { + if(!rRegion.IsEmpty()) + { + // save new background + ((OverlayManagerBuffered*)this)->ImpSaveBackground(rRegion, pPreRenderDevice); + } + + // call parent + OverlayManager::completeRedraw(rRegion, pPreRenderDevice); + } + + void OverlayManagerBuffered::flush() + { + // call timer handler direct + ImpBufferTimerHandler(0); + } + + // #i68597# part of content gets copied, react on it + void OverlayManagerBuffered::copyArea(const Point& rDestPt, const Point& rSrcPt, const Size& rSrcSize) + { + // scroll local buffered area + maBufferDevice.CopyArea(rDestPt, rSrcPt, rSrcSize); + } + + void OverlayManagerBuffered::restoreBackground(const Region& rRegion) const + { + // restore + const Region aRegionPixel(getOutputDevice().LogicToPixel(rRegion)); + ImpRestoreBackground(aRegionPixel); + + // call parent + OverlayManager::restoreBackground(rRegion); + } + + void OverlayManagerBuffered::invalidateRange(const basegfx::B2DRange& rRange) + { + if(!rRange.isEmpty()) + { + // buffered output, do not invalidate but use the timer + // to trigger a timer event for refresh + maBufferTimer.Start(); + + // add the discrete range to the remembered region + // #i75163# use double precision and floor/ceil rounding to get overlapped pixel region, even + // when the given logic region has a width/height of 0.0. This does NOT work with LogicToPixel + // since it just transforms the top left and bottom right points equally without taking + // discrete pixel coverage into account. An empty B2DRange and thus empty logic Rectangle translated + // to an also empty discrete pixel rectangle - what is wrong. + basegfx::B2DRange aDiscreteRange(rRange); + aDiscreteRange.transform(getOutputDevice().GetViewTransformation()); + + if(maDrawinglayerOpt.IsAntiAliasing()) + { + // assume AA needs one pixel more and invalidate one pixel more + const double fDiscreteOne(getDiscreteOne()); + const basegfx::B2IPoint aTopLeft( + (sal_Int32)floor(aDiscreteRange.getMinX() - fDiscreteOne), + (sal_Int32)floor(aDiscreteRange.getMinY() - fDiscreteOne)); + const basegfx::B2IPoint aBottomRight( + (sal_Int32)ceil(aDiscreteRange.getMaxX() + fDiscreteOne), + (sal_Int32)ceil(aDiscreteRange.getMaxY() + fDiscreteOne)); + + maBufferRememberedRangePixel.expand(aTopLeft); + maBufferRememberedRangePixel.expand(aBottomRight); + } + else + { + const basegfx::B2IPoint aTopLeft((sal_Int32)floor(aDiscreteRange.getMinX()), (sal_Int32)floor(aDiscreteRange.getMinY())); + const basegfx::B2IPoint aBottomRight((sal_Int32)ceil(aDiscreteRange.getMaxX()), (sal_Int32)ceil(aDiscreteRange.getMaxY())); + + maBufferRememberedRangePixel.expand(aTopLeft); + maBufferRememberedRangePixel.expand(aBottomRight); + } + } + } + + void OverlayManagerBuffered::SetRefreshWithPreRendering(bool bNew) + { + if((bool)mbRefreshWithPreRendering != bNew) + { + mbRefreshWithPreRendering = bNew; + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayobject.cxx b/svx/source/sdr/overlay/overlayobject.cxx new file mode 100644 index 000000000000..049dfe2ecc4c --- /dev/null +++ b/svx/source/sdr/overlay/overlayobject.cxx @@ -0,0 +1,216 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlayobject.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <tools/debug.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/vector/b2dvector.hxx> +#include <vcl/outdev.hxx> +#include <vcl/salbtype.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <svx/sdr/contact/objectcontacttools.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + void OverlayObject::objectChange() + { + const basegfx::B2DRange aPreviousRange(maBaseRange); + maBaseRange.reset(); + setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DSequence()); + + if(getOverlayManager() && !aPreviousRange.isEmpty()) + { + getOverlayManager()->invalidateRange(aPreviousRange); + } + + const basegfx::B2DRange& rCurrentRange = getBaseRange(); + + if(getOverlayManager() && rCurrentRange != aPreviousRange && !rCurrentRange.isEmpty()) + { + getOverlayManager()->invalidateRange(rCurrentRange); + } + } + + // OverlayObject implementations. + drawinglayer::primitive2d::Primitive2DSequence OverlayObject::createOverlayObjectPrimitive2DSequence() + { + // Default implementation has to assert a missing implementation. It cannot + // be useful to have overlay object derivations which have no visualisation + // at all + OSL_ENSURE(false, "OverlayObject derivation without visualisation definition (missing createOverlayObjectPrimitive2DSequence implementation) (!)"); + return drawinglayer::primitive2d::Primitive2DSequence(); + } + + void OverlayObject::allowAntiAliase(bool bNew) + { + if(bNew != (bool)mbAllowsAntiAliase) + { + // remember new value + mbAllowsAntiAliase = bNew; + + // register change (after change) + objectChange(); + } + } + + OverlayObject::OverlayObject(Color aBaseColor) + : Event(0), + mpOverlayManager(0), + maBaseColor(aBaseColor), + mbIsVisible(true), + mbIsHittable(true), + mbAllowsAnimation(false), + mbAllowsAntiAliase(true) + { + } + + OverlayObject::~OverlayObject() + { + OSL_ENSURE(0 == getOverlayManager(), "OverlayObject is destructed which is still registered at OverlayManager (!)"); + } + + drawinglayer::primitive2d::Primitive2DSequence OverlayObject::getOverlayObjectPrimitive2DSequence() const + { + if(!getPrimitive2DSequence().hasElements()) + { + // no existing sequence; create one + const_cast< OverlayObject* >(this)->setPrimitive2DSequence( + const_cast< OverlayObject* >(this)->createOverlayObjectPrimitive2DSequence()); + } + + return getPrimitive2DSequence(); + } + + const basegfx::B2DRange& OverlayObject::getBaseRange() const + { + if(getOverlayManager() && maBaseRange.isEmpty()) + { + const drawinglayer::primitive2d::Primitive2DSequence& rSequence = getOverlayObjectPrimitive2DSequence(); + + if(rSequence.hasElements()) + { + const drawinglayer::geometry::ViewInformation2D aViewInformation2D(getOverlayManager()->getCurrentViewInformation2D()); + + const_cast< sdr::overlay::OverlayObject* >(this)->maBaseRange = + drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(rSequence, aViewInformation2D); + } + } + + return maBaseRange; + } + + void OverlayObject::setVisible(bool bNew) + { + if(bNew != (bool)mbIsVisible) + { + // remember new value + mbIsVisible = bNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayObject::setHittable(bool bNew) + { + if(bNew != (bool)mbIsHittable) + { + // remember new value + mbIsHittable = bNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayObject::setBaseColor(Color aNew) + { + if(aNew != maBaseColor) + { + // remember new value + maBaseColor = aNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayObject::Trigger(sal_uInt32 /*nTime*/) + { + // default does not register again + } + + void OverlayObject::stripeDefinitionHasChanged() + { + // default does not need to do anything + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + OverlayObjectWithBasePosition::OverlayObjectWithBasePosition(const basegfx::B2DPoint& rBasePos, Color aBaseColor) + : OverlayObject(aBaseColor), + maBasePosition(rBasePos) + { + } + + OverlayObjectWithBasePosition::~OverlayObjectWithBasePosition() + { + } + + void OverlayObjectWithBasePosition::setBasePosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maBasePosition) + { + // remember new value + maBasePosition = rNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayobjectcell.cxx b/svx/source/sdr/overlay/overlayobjectcell.cxx new file mode 100644 index 000000000000..dbf38a8cd0f1 --- /dev/null +++ b/svx/source/sdr/overlay/overlayobjectcell.cxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <basegfx/numeric/ftools.hxx> +#include <vcl/outdev.hxx> +#include <vcl/hatch.hxx> +#include <svx/sdr/overlay/overlayobjectcell.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> +#include <drawinglayer/primitive2d/invertprimitive2d.hxx> + +using namespace ::basegfx; + +// #114409# +namespace sdr +{ + namespace overlay + { + OverlayObjectCell::OverlayObjectCell( CellOverlayType eType, const Color& rColor, const RangeVector& rRects ) + : OverlayObject( rColor ), + mePaintType( eType ), + maRectangles( rRects ) + { + // no AA for selection overlays + allowAntiAliase(false); + } + + OverlayObjectCell::~OverlayObjectCell() + { + } + + drawinglayer::primitive2d::Primitive2DSequence OverlayObjectCell::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + const sal_uInt32 nCount(maRectangles.size()); + + if(nCount) + { + const basegfx::BColor aRGBColor(getBaseColor().getBColor()); + aRetval.realloc(nCount); + + // create primitives for all ranges + for(sal_uInt32 a(0); a < nCount; a++) + { + const basegfx::B2DRange& rRange(maRectangles[a]); + const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(rRange)); + + aRetval[a] = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aPolygon), + aRGBColor)); + } + + + if(mePaintType == CELL_OVERLAY_TRANSPARENT) + { + // embed in 50% transparent paint + const drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparence( + new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( + aRetval, + 0.5)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparence, 1); + } + else // CELL_OVERLAY_INVERT + { + // embed in invert primitive + const drawinglayer::primitive2d::Primitive2DReference aInvert( + new drawinglayer::primitive2d::InvertPrimitive2D( + aRetval)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aInvert, 1); + } + } + + return aRetval; + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayobjectlist.cxx b/svx/source/sdr/overlay/overlayobjectlist.cxx new file mode 100644 index 000000000000..e9464bdee09b --- /dev/null +++ b/svx/source/sdr/overlay/overlayobjectlist.cxx @@ -0,0 +1,184 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlayobjectlist.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <tools/debug.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> + +// for SOLARIS compiler include of algorithm part of _STL is necesary to +// get access to basic algos like ::std::find +#include <algorithm> + +#include <drawinglayer/processor2d/hittestprocessor2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + OverlayObjectList::~OverlayObjectList() + { + clear(); + } + + void OverlayObjectList::clear() + { + OverlayObjectVector::iterator aStart(maVector.begin()); + + for(; aStart != maVector.end(); aStart++) + { + ::sdr::overlay::OverlayObject* pCandidate = *aStart; + + if(pCandidate->getOverlayManager()) + { + pCandidate->getOverlayManager()->remove(*pCandidate); + } + + delete pCandidate; + } + + maVector.clear(); + } + + void OverlayObjectList::remove(OverlayObject& rOverlayObject) + { + const OverlayObjectVector::iterator aFindResult = ::std::find(maVector.begin(), maVector.end(), &rOverlayObject); + const bool bFound(aFindResult != maVector.end()); + OSL_ENSURE(bFound, "Could not find given object in list (!)"); + + if(bFound) + { + maVector.erase(aFindResult); + } + } + + bool OverlayObjectList::isHitLogic(const basegfx::B2DPoint& rLogicPosition, double fLogicTolerance) const + { + if(maVector.size()) + { + OverlayObjectVector::const_iterator aStart(maVector.begin()); + sdr::overlay::OverlayObject* pFirst = *aStart; + OSL_ENSURE(pFirst, "Corrupt OverlayObjectList (!)"); + OverlayManager* pManager = pFirst->getOverlayManager(); + + if(pManager) + { + if(0.0 == fLogicTolerance) + { + const Size aSizeLogic(pManager->getOutputDevice().PixelToLogic( + Size(DEFAULT_VALUE_FOR_HITTEST_PIXEL, DEFAULT_VALUE_FOR_HITTEST_PIXEL))); + fLogicTolerance = aSizeLogic.Width(); + } + + const drawinglayer::geometry::ViewInformation2D aViewInformation2D(pManager->getCurrentViewInformation2D()); + drawinglayer::processor2d::HitTestProcessor2D aHitTestProcessor2D( + aViewInformation2D, + rLogicPosition, + fLogicTolerance, + false); + + for(; aStart != maVector.end(); aStart++) + { + sdr::overlay::OverlayObject* pCandidate = *aStart; + OSL_ENSURE(pCandidate, "Corrupt OverlayObjectList (!)"); + + if(pCandidate->isHittable()) + { + const drawinglayer::primitive2d::Primitive2DSequence& rSequence = pCandidate->getOverlayObjectPrimitive2DSequence(); + + if(rSequence.hasElements()) + { + aHitTestProcessor2D.process(rSequence); + + if(aHitTestProcessor2D.getHit()) + { + return true; + } + } + } + } + } + } + + return false; + } + + bool OverlayObjectList::isHitPixel(const Point& rDiscretePosition, sal_uInt32 nDiscreteTolerance) const + { + if(maVector.size()) + { + OverlayObjectVector::const_iterator aStart(maVector.begin()); + sdr::overlay::OverlayObject* pCandidate = *aStart; + OverlayManager* pManager = pCandidate->getOverlayManager(); + + if(pManager) + { + const Point aPosLogic(pManager->getOutputDevice().PixelToLogic(rDiscretePosition)); + const basegfx::B2DPoint aPosition(aPosLogic.X(), aPosLogic.Y()); + + if(nDiscreteTolerance) + { + const Size aSizeLogic(pManager->getOutputDevice().PixelToLogic(Size(nDiscreteTolerance, nDiscreteTolerance))); + return isHitLogic(aPosition, (double)aSizeLogic.Width()); + } + else + { + return isHitLogic(aPosition); + } + } + } + + return false; + } + + basegfx::B2DRange OverlayObjectList::getBaseRange() const + { + basegfx::B2DRange aRetval; + + if(maVector.size()) + { + OverlayObjectVector::const_iterator aStart(maVector.begin()); + + for(; aStart != maVector.end(); aStart++) + { + ::sdr::overlay::OverlayObject* pCandidate = *aStart; + aRetval.expand(pCandidate->getBaseRange()); + } + } + + return aRetval; + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaypolypolygon.cxx b/svx/source/sdr/overlay/overlaypolypolygon.cxx new file mode 100644 index 000000000000..a8476854ae13 --- /dev/null +++ b/svx/source/sdr/overlay/overlaypolypolygon.cxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlaypolypolygon.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayPolyPolygonStriped::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + + if(getOverlayManager()) + { + const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); + const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); + const double fStripeLengthPixel(getOverlayManager()->getStripeLengthPixel()); + + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D( + getPolyPolygon(), + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + return aRetval; + } + + void OverlayPolyPolygonStriped::stripeDefinitionHasChanged() + { + // react on OverlayManager's stripe definition change + objectChange(); + } + + OverlayPolyPolygonStriped::OverlayPolyPolygonStriped( + const basegfx::B2DPolyPolygon& rPolyPolygon) + : OverlayObject(Color(COL_BLACK)), + maPolyPolygon(rPolyPolygon) + { + } + + OverlayPolyPolygonStriped::~OverlayPolyPolygonStriped() + { + } + + void OverlayPolyPolygonStriped::setPolyPolygon(const basegfx::B2DPolyPolygon& rNew) + { + if(rNew != maPolyPolygon) + { + // remember new value + maPolyPolygon = rNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayprimitive2dsequenceobject.cxx b/svx/source/sdr/overlay/overlayprimitive2dsequenceobject.cxx new file mode 100644 index 000000000000..52f43084c664 --- /dev/null +++ b/svx/source/sdr/overlay/overlayprimitive2dsequenceobject.cxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx> +#include <drawinglayer/geometry/viewinformation2d.hxx> +#include <drawinglayer/processor2d/vclpixelprocessor2d.hxx> +#include <svx/sdr/contact/objectcontacttools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayPrimitive2DSequenceObject::createOverlayObjectPrimitive2DSequence() + { + return getSequence(); + } + + OverlayPrimitive2DSequenceObject::OverlayPrimitive2DSequenceObject(const drawinglayer::primitive2d::Primitive2DSequence& rSequence) + : OverlayObjectWithBasePosition(basegfx::B2DPoint(), Color(COL_BLACK)), + maSequence(rSequence) + { + } + + OverlayPrimitive2DSequenceObject::~OverlayPrimitive2DSequenceObject() + { + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayrollingrectangle.cxx b/svx/source/sdr/overlay/overlayrollingrectangle.cxx new file mode 100644 index 000000000000..1b09df2ca60e --- /dev/null +++ b/svx/source/sdr/overlay/overlayrollingrectangle.cxx @@ -0,0 +1,150 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlayrollingrectangle.hxx> +#include <tools/gen.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayRollingRectangleStriped::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + + if(getOverlayManager() && (getShowBounds() || getExtendedLines())) + { + const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); + const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); + const double fStripeLengthPixel(getOverlayManager()->getStripeLengthPixel()); + const basegfx::B2DRange aRollingRectangle(getBasePosition(), getSecondPosition()); + + if(getShowBounds()) + { + // view-independent part, create directly + const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(aRollingRectangle)); + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::PolygonMarkerPrimitive2D( + aPolygon, + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aReference); + } + + if(getExtendedLines()) + { + // view-dependent part, use helper primitive + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::OverlayRollingRectanglePrimitive( + aRollingRectangle, + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aReference); + } + } + + return aRetval; + } + + void OverlayRollingRectangleStriped::stripeDefinitionHasChanged() + { + // react on OverlayManager's stripe definition change + objectChange(); + } + + OverlayRollingRectangleStriped::OverlayRollingRectangleStriped( + const basegfx::B2DPoint& rBasePos, + const basegfx::B2DPoint& rSecondPos, + bool bExtendedLines, + bool bShowBounds) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_BLACK)), + maSecondPosition(rSecondPos), + mbExtendedLines(bExtendedLines), + mbShowBounds(bShowBounds) + { + } + + OverlayRollingRectangleStriped::~OverlayRollingRectangleStriped() + { + } + + void OverlayRollingRectangleStriped::setSecondPosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maSecondPosition) + { + // remember new value + maSecondPosition = rNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayRollingRectangleStriped::setExtendedLines(bool bNew) + { + if(bNew != (bool)mbExtendedLines) + { + // remember new value + mbExtendedLines = bNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayRollingRectangleStriped::setShowBounds(bool bNew) + { + if(bNew != (bool)mbShowBounds) + { + // remember new value + mbShowBounds = bNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayselection.cxx b/svx/source/sdr/overlay/overlayselection.cxx new file mode 100644 index 000000000000..2115d3c63120 --- /dev/null +++ b/svx/source/sdr/overlay/overlayselection.cxx @@ -0,0 +1,237 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlayselection.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <svtools/optionsdrawinglayer.hxx> +#include <vcl/svapp.hxx> +#include <vcl/outdev.hxx> +#include <drawinglayer/primitive2d/invertprimitive2d.hxx> +#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> +#include <basegfx/polygon/b2dpolypolygoncutter.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + // combine rages geometrically to a single, ORed polygon + basegfx::B2DPolyPolygon impCombineRangesToPolyPolygon(const std::vector< basegfx::B2DRange >& rRanges) + { + const sal_uInt32 nCount(rRanges.size()); + basegfx::B2DPolyPolygon aRetval; + + for(sal_uInt32 a(0); a < nCount; a++) + { + const basegfx::B2DPolygon aDiscretePolygon(basegfx::tools::createPolygonFromRect(rRanges[a])); + + if(0 == a) + { + aRetval.append(aDiscretePolygon); + } + else + { + aRetval = basegfx::tools::solvePolygonOperationOr(aRetval, basegfx::B2DPolyPolygon(aDiscretePolygon)); + } + } + + return aRetval; + } + + // check if wanted type OVERLAY_TRANSPARENT or OVERLAY_SOLID + // is possible. If not, fallback to invert mode (classic mode) + OverlayType impCheckPossibleOverlayType(OverlayType aOverlayType) + { + if(OVERLAY_INVERT != aOverlayType) + { + const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; + + if(!aSvtOptionsDrawinglayer.IsTransparentSelection()) + { + // not possible when switched off by user + return OVERLAY_INVERT; + } + else + { + const OutputDevice *pOut = Application::GetDefaultDevice(); + + if(pOut->GetSettings().GetStyleSettings().GetHighContrastMode()) + { + // not possible when in high contrast mode + return OVERLAY_INVERT; + } + + if(!pOut->supportsOperation(OutDevSupport_TransparentRect)) + { + // not possible when no fast transparence paint is supported on the system + return OVERLAY_INVERT; + } + } + } + + return aOverlayType; + } + + drawinglayer::primitive2d::Primitive2DSequence OverlaySelection::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + const sal_uInt32 nCount(getRanges().size()); + + if(nCount) + { + // create range primitives + const bool bInvert(OVERLAY_INVERT == maLastOverlayType); + basegfx::BColor aRGBColor(getBaseColor().getBColor()); + aRetval.realloc(nCount); + + if(bInvert) + { + // force color to white for invert to get a full invert + aRGBColor = basegfx::BColor(1.0, 1.0, 1.0); + } + + for(sal_uInt32 a(0);a < nCount; a++) + { + const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(maRanges[a])); + aRetval[a] = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aPolygon), + aRGBColor)); + } + + if(bInvert) + { + // embed all in invert primitive + const drawinglayer::primitive2d::Primitive2DReference aInvert( + new drawinglayer::primitive2d::InvertPrimitive2D( + aRetval)); + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aInvert, 1); + } + else if(OVERLAY_TRANSPARENT == maLastOverlayType) + { + // embed all rectangles in transparent paint + const double fTransparence(mnLastTransparence / 100.0); + const drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparence( + new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( + aRetval, + fTransparence)); + + if(getBorder()) + { + const basegfx::B2DPolyPolygon aPolyPolygon(impCombineRangesToPolyPolygon(getRanges())); + const drawinglayer::primitive2d::Primitive2DReference aSelectionOutline( + new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D( + aPolyPolygon, + aRGBColor)); + + // add both to result + aRetval.realloc(2); + aRetval[0] = aUnifiedTransparence; + aRetval[1] = aSelectionOutline; + } + else + { + // just add transparent part + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparence, 1); + } + } + } + + return aRetval; + } + + OverlaySelection::OverlaySelection( + OverlayType eType, + const Color& rColor, + const std::vector< basegfx::B2DRange >& rRanges, + bool bBorder) + : OverlayObject(rColor), + meOverlayType(eType), + maRanges(rRanges), + maLastOverlayType(eType), + mnLastTransparence(0), + mbBorder(bBorder) + { + // no AA for selection overlays + allowAntiAliase(false); + } + + OverlaySelection::~OverlaySelection() + { + if(getOverlayManager()) + { + getOverlayManager()->remove(*this); + } + } + + drawinglayer::primitive2d::Primitive2DSequence OverlaySelection::getOverlayObjectPrimitive2DSequence() const + { + // get current values + const OverlayType aNewOverlayType(impCheckPossibleOverlayType(meOverlayType)); + const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; + const sal_uInt16 nNewTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent()); + + if(getPrimitive2DSequence().hasElements()) + { + if(aNewOverlayType != maLastOverlayType + || nNewTransparence != mnLastTransparence) + { + // conditions of last local decomposition have changed, delete + const_cast< OverlaySelection* >(this)->setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DSequence()); + } + } + + if(!getPrimitive2DSequence().hasElements()) + { + // remember new values + const_cast< OverlaySelection* >(this)->maLastOverlayType = aNewOverlayType; + const_cast< OverlaySelection* >(this)->mnLastTransparence = nNewTransparence; + } + + // call base implementation + return OverlayObject::getOverlayObjectPrimitive2DSequence(); + } + + void OverlaySelection::setRanges(const std::vector< basegfx::B2DRange >& rNew) + { + if(rNew != maRanges) + { + maRanges = rNew; + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaytools.cxx b/svx/source/sdr/overlay/overlaytools.cxx new file mode 100644 index 000000000000..215b8484d5bf --- /dev/null +++ b/svx/source/sdr/overlay/overlaytools.cxx @@ -0,0 +1,493 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/overlay/overlaytools.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/geometry/viewinformation2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + OverlayBitmapExPrimitive::OverlayBitmapExPrimitive( + const BitmapEx& rBitmapEx, + const basegfx::B2DPoint& rBasePosition, + sal_uInt16 nCenterX, + sal_uInt16 nCenterY) + : DiscreteMetricDependentPrimitive2D(), + maBitmapEx(rBitmapEx), + maBasePosition(rBasePosition), + mnCenterX(nCenterX), + mnCenterY(nCenterY) + {} + + Primitive2DSequence OverlayBitmapExPrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DSequence aRetval; + const Size aBitmapSize(getBitmapEx().GetSizePixel()); + + if(aBitmapSize.Width() && aBitmapSize.Height() && basegfx::fTools::more(getDiscreteUnit(), 0.0)) + { + // calculate back from internal bitmap's extreme coordinates (the edges) + // to logical coordinates. Only use a unified scaling value (getDiscreteUnit(), + // the prepared one which expresses how many logic units form a discrete unit) + // for this step. This primitive is to be displayed always unscaled (in it's pixel size) + // and unrotated, more like a marker + const double fLeft(((0.0 - getCenterX()) * getDiscreteUnit()) + getBasePosition().getX()); + const double fTop(((0.0 - getCenterY()) * getDiscreteUnit()) + getBasePosition().getY()); + const double fRight((((aBitmapSize.getWidth() - 1.0) - getCenterX()) * getDiscreteUnit()) + getBasePosition().getX()); + const double fBottom((((aBitmapSize.getHeight() - 1.0) - getCenterY()) * getDiscreteUnit()) + getBasePosition().getY()); + + // create a BitmapPrimitive2D using those positions + basegfx::B2DHomMatrix aTransform; + + aTransform.set(0, 0, fRight - fLeft); + aTransform.set(1, 1, fBottom - fTop); + aTransform.set(0, 2, fLeft); + aTransform.set(1, 2, fTop); + + const Primitive2DReference aPrimitive(new BitmapPrimitive2D(getBitmapEx(), aTransform)); + aRetval = Primitive2DSequence(&aPrimitive, 1); + } + + return aRetval; + } + + bool OverlayBitmapExPrimitive::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) + { + const OverlayBitmapExPrimitive& rCompare = static_cast< const OverlayBitmapExPrimitive& >(rPrimitive); + + return (getBitmapEx() == rCompare.getBitmapEx() + && getBasePosition() == rCompare.getBasePosition() + && getCenterX() == rCompare.getCenterX() + && getCenterY() == rCompare.getCenterY()); + } + + return false; + } + + ImplPrimitrive2DIDBlock(OverlayBitmapExPrimitive, PRIMITIVE2D_ID_OVERLAYBITMAPEXPRIMITIVE) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + OverlayCrosshairPrimitive::OverlayCrosshairPrimitive( + const basegfx::B2DPoint& rBasePosition, + const basegfx::BColor& rRGBColorA, + const basegfx::BColor& rRGBColorB, + double fDiscreteDashLength) + : ViewportDependentPrimitive2D(), + maBasePosition(rBasePosition), + maRGBColorA(rRGBColorA), + maRGBColorB(rRGBColorB), + mfDiscreteDashLength(fDiscreteDashLength) + {} + + Primitive2DSequence OverlayCrosshairPrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + // use the prepared Viewport information accessible using getViewport() + Primitive2DSequence aRetval; + + if(!getViewport().isEmpty()) + { + aRetval.realloc(2); + basegfx::B2DPolygon aPolygon; + + aPolygon.append(basegfx::B2DPoint(getViewport().getMinX(), getBasePosition().getY())); + aPolygon.append(basegfx::B2DPoint(getViewport().getMaxX(), getBasePosition().getY())); + + aRetval[0] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aPolygon, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + + aPolygon.clear(); + aPolygon.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMinY())); + aPolygon.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMaxY())); + + aRetval[1] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aPolygon, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + } + + return aRetval; + } + + bool OverlayCrosshairPrimitive::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(ViewportDependentPrimitive2D::operator==(rPrimitive)) + { + const OverlayCrosshairPrimitive& rCompare = static_cast< const OverlayCrosshairPrimitive& >(rPrimitive); + + return (getBasePosition() == rCompare.getBasePosition() + && getRGBColorA() == rCompare.getRGBColorA() + && getRGBColorB() == rCompare.getRGBColorB() + && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); + } + + return false; + } + + ImplPrimitrive2DIDBlock(OverlayCrosshairPrimitive, PRIMITIVE2D_ID_OVERLAYCROSSHAIRPRIMITIVE) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + OverlayHatchRectanglePrimitive::OverlayHatchRectanglePrimitive( + const basegfx::B2DRange& rObjectRange, + double fDiscreteHatchDistance, + double fHatchRotation, + const basegfx::BColor& rHatchColor, + double fDiscreteGrow, + double fDiscreteShrink, + double fRotation) + : DiscreteMetricDependentPrimitive2D(), + maObjectRange(rObjectRange), + mfDiscreteHatchDistance(fDiscreteHatchDistance), + mfHatchRotation(fHatchRotation), + maHatchColor(rHatchColor), + mfDiscreteGrow(fDiscreteGrow), + mfDiscreteShrink(fDiscreteShrink), + mfRotation(fRotation) + {} + + Primitive2DSequence OverlayHatchRectanglePrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DSequence aRetval; + + if(basegfx::fTools::more(getDiscreteUnit(), 0.0)) + { + basegfx::B2DRange aInnerRange(getObjectRange()); + basegfx::B2DRange aOuterRange(getObjectRange()); + basegfx::B2DPolyPolygon aHatchPolyPolygon; + + aOuterRange.grow(getDiscreteUnit() * getDiscreteGrow()); + aInnerRange.grow(getDiscreteUnit() * -getDiscreteShrink()); + + aHatchPolyPolygon.append(basegfx::tools::createPolygonFromRect(aOuterRange)); + + if(!aInnerRange.isEmpty()) + { + aHatchPolyPolygon.append(basegfx::tools::createPolygonFromRect(aInnerRange)); + } + + if(!basegfx::fTools::equalZero(getRotation())) + { + const basegfx::B2DHomMatrix aTransform(basegfx::tools::createRotateAroundPoint( + getObjectRange().getMinX(), getObjectRange().getMinY(), getRotation())); + + aHatchPolyPolygon.transform(aTransform); + } + + const basegfx::BColor aEmptyColor(0.0, 0.0, 0.0); + const drawinglayer::attribute::FillHatchAttribute aFillHatchAttribute( + drawinglayer::attribute::HATCHSTYLE_SINGLE, + getDiscreteHatchDistance() * getDiscreteUnit(), + getHatchRotation() - getRotation(), + getHatchColor(), + false); + const Primitive2DReference aPrimitive( + new PolyPolygonHatchPrimitive2D( + aHatchPolyPolygon, + aEmptyColor, + aFillHatchAttribute)); + + aRetval = Primitive2DSequence(&aPrimitive, 1); + } + + return aRetval; + } + + bool OverlayHatchRectanglePrimitive::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) + { + const OverlayHatchRectanglePrimitive& rCompare = static_cast< const OverlayHatchRectanglePrimitive& >(rPrimitive); + + return (getObjectRange() == rCompare.getObjectRange() + && getDiscreteHatchDistance() == rCompare.getDiscreteHatchDistance() + && getHatchRotation() == rCompare.getHatchRotation() + && getHatchColor() == rCompare.getHatchColor() + && getDiscreteGrow() == rCompare.getDiscreteGrow() + && getDiscreteShrink() == rCompare.getDiscreteShrink() + && getRotation() == rCompare.getRotation()); + } + + return false; + } + + ImplPrimitrive2DIDBlock(OverlayHatchRectanglePrimitive, PRIMITIVE2D_ID_OVERLAYHATCHRECTANGLEPRIMITIVE) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + OverlayHelplineStripedPrimitive::OverlayHelplineStripedPrimitive( + const basegfx::B2DPoint& rBasePosition, + HelplineStyle eStyle, + const basegfx::BColor& rRGBColorA, + const basegfx::BColor& rRGBColorB, + double fDiscreteDashLength) + : ViewportDependentPrimitive2D(), + maBasePosition(rBasePosition), + meStyle(eStyle), + maRGBColorA(rRGBColorA), + maRGBColorB(rRGBColorB), + mfDiscreteDashLength(fDiscreteDashLength) + {} + + Primitive2DSequence OverlayHelplineStripedPrimitive::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const + { + // use the prepared Viewport information accessible using getViewport() + Primitive2DSequence aRetval; + + if(!getViewport().isEmpty()) + { + switch(getStyle()) + { + case HELPLINESTYLE_VERTICAL : + { + aRetval.realloc(1); + basegfx::B2DPolygon aLine; + + aLine.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMinY())); + aLine.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMaxY())); + + aRetval[0] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aLine, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + break; + } + + case HELPLINESTYLE_HORIZONTAL : + { + aRetval.realloc(1); + basegfx::B2DPolygon aLine; + + aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getBasePosition().getY())); + aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getBasePosition().getY())); + + aRetval[0] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aLine, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + break; + } + + default: // case HELPLINESTYLE_POINT : + { + const double fDiscreteUnit((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength()); + aRetval.realloc(2); + basegfx::B2DPolygon aLineA, aLineB; + + aLineA.append(basegfx::B2DPoint(getBasePosition().getX(), getBasePosition().getY() - fDiscreteUnit)); + aLineA.append(basegfx::B2DPoint(getBasePosition().getX(), getBasePosition().getY() + fDiscreteUnit)); + + aRetval[0] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aLineA, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + + aLineB.append(basegfx::B2DPoint(getBasePosition().getX() - fDiscreteUnit, getBasePosition().getY())); + aLineB.append(basegfx::B2DPoint(getBasePosition().getX() + fDiscreteUnit, getBasePosition().getY())); + + aRetval[1] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aLineB, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + + break; + } + } + } + + return aRetval; + } + + bool OverlayHelplineStripedPrimitive::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(ViewportDependentPrimitive2D::operator==(rPrimitive)) + { + const OverlayHelplineStripedPrimitive& rCompare = static_cast< const OverlayHelplineStripedPrimitive& >(rPrimitive); + + return (getBasePosition() == rCompare.getBasePosition() + && getStyle() == rCompare.getStyle() + && getRGBColorA() == rCompare.getRGBColorA() + && getRGBColorB() == rCompare.getRGBColorB() + && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); + } + + return false; + } + + ImplPrimitrive2DIDBlock(OverlayHelplineStripedPrimitive, PRIMITIVE2D_ID_OVERLAYHELPLINESTRIPEDPRIMITIVE) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + OverlayRollingRectanglePrimitive::OverlayRollingRectanglePrimitive( + const basegfx::B2DRange& aRollingRectangle, + const basegfx::BColor& rRGBColorA, + const basegfx::BColor& rRGBColorB, + double fDiscreteDashLength) + : ViewportDependentPrimitive2D(), + maRollingRectangle(aRollingRectangle), + maRGBColorA(rRGBColorA), + maRGBColorB(rRGBColorB), + mfDiscreteDashLength(fDiscreteDashLength) + {} + + Primitive2DSequence OverlayRollingRectanglePrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + // use the prepared Viewport information accessible using getViewport() + Primitive2DSequence aRetval; + + if(!getViewport().isEmpty()) + { + basegfx::B2DPolygon aLine; + aRetval.realloc(8); + + // Left lines + aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getRollingRectangle().getMinY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMinY())); + aRetval[0] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + aLine.clear(); + aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getRollingRectangle().getMaxY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMaxY())); + aRetval[1] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + // Right lines + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMinY())); + aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getRollingRectangle().getMinY())); + aRetval[2] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMaxY())); + aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getRollingRectangle().getMaxY())); + aRetval[3] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + // Top lines + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getViewport().getMinY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMinY())); + aRetval[4] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getViewport().getMinY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMinY())); + aRetval[5] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + // Bottom lines + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMaxY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getViewport().getMaxY())); + aRetval[6] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMaxY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getViewport().getMaxY())); + aRetval[7] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + } + + return aRetval; + } + + bool OverlayRollingRectanglePrimitive::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(ViewportDependentPrimitive2D::operator==(rPrimitive)) + { + const OverlayRollingRectanglePrimitive& rCompare = static_cast< const OverlayRollingRectanglePrimitive& >(rPrimitive); + + return (getRollingRectangle() == rCompare.getRollingRectangle() + && getRGBColorA() == rCompare.getRGBColorA() + && getRGBColorB() == rCompare.getRGBColorB() + && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); + } + + return false; + } + + ImplPrimitrive2DIDBlock(OverlayRollingRectanglePrimitive, PRIMITIVE2D_ID_OVERLAYROLLINGRECTANGLEPRIMITIVE) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaytriangle.cxx b/svx/source/sdr/overlay/overlaytriangle.cxx new file mode 100644 index 000000000000..ecf1cf5866e5 --- /dev/null +++ b/svx/source/sdr/overlay/overlaytriangle.cxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/overlay/overlaytriangle.hxx> +#include <tools/poly.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayTriangle::createOverlayObjectPrimitive2DSequence() + { + basegfx::B2DPolygon aPolygon; + + aPolygon.append(getBasePosition()); + aPolygon.append(getSecondPosition()); + aPolygon.append(getThirdPosition()); + aPolygon.setClosed(true); + + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aPolygon), + getBaseColor().getBColor())); + + return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + OverlayTriangle::OverlayTriangle( + const basegfx::B2DPoint& rBasePos, + const basegfx::B2DPoint& rSecondPos, + const basegfx::B2DPoint& rThirdPos, + Color aTriangleColor) + : OverlayObjectWithBasePosition(rBasePos, aTriangleColor), + maSecondPosition(rSecondPos), + maThirdPosition(rThirdPos) + { + } + + OverlayTriangle::~OverlayTriangle() + { + } + + void OverlayTriangle::setSecondPosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maSecondPosition) + { + // remember new value + maSecondPosition = rNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayTriangle::setThirdPosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maThirdPosition) + { + // remember new value + maThirdPosition = rNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof |