diff options
Diffstat (limited to 'svx/source/sdr')
50 files changed, 3500 insertions, 2643 deletions
diff --git a/svx/source/sdr/attribute/makefile.mk b/svx/source/sdr/attribute/makefile.mk index adbd85f88d94..44e161a3b503 100644 --- a/svx/source/sdr/attribute/makefile.mk +++ b/svx/source/sdr/attribute/makefile.mk @@ -33,6 +33,7 @@ PRJ=..$/..$/.. PRJNAME=svx TARGET=attribute +ENABLE_EXCEPTIONS=TRUE # --- Settings ----------------------------------------------------- @@ -43,6 +44,8 @@ TARGET=attribute SLOFILES=\ $(SLO)$/sdrallattribute.obj \ - $(SLO)$/sdrtextattribute.obj + $(SLO)$/sdrtextattribute.obj \ + $(SLO)$/sdrformtextattribute.obj \ + $(SLO)$/sdrformtextoutlineattribute.obj .INCLUDE : target.mk diff --git a/svx/source/sdr/attribute/sdrallattribute.cxx b/svx/source/sdr/attribute/sdrallattribute.cxx index 6e9d312b8357..9eee8dbccce8 100644 --- a/svx/source/sdr/attribute/sdrallattribute.cxx +++ b/svx/source/sdr/attribute/sdrallattribute.cxx @@ -30,6 +30,7 @@ ************************************************************************/ #include "precompiled_svx.hxx" + #include <svx/sdr/attribute/sdrallattribute.hxx> #include <drawinglayer/attribute/sdrattribute.hxx> #include <drawinglayer/attribute/fillattribute.hxx> @@ -45,20 +46,20 @@ namespace drawinglayer { namespace attribute { - SdrShadowTextAttribute::SdrShadowTextAttribute(SdrShadowAttribute* pShadow, SdrTextAttribute* pTextAttribute) + SdrShadowTextAttribute::SdrShadowTextAttribute( + SdrShadowAttribute* pShadow, + SdrTextAttribute* pTextAttribute) : mpShadow(pShadow), mpTextAttribute(pTextAttribute) { } - SdrShadowTextAttribute::SdrShadowTextAttribute(const SdrShadowTextAttribute& rCandidate) - : mpShadow(0L), - mpTextAttribute(0L) + SdrShadowTextAttribute::SdrShadowTextAttribute( + const SdrShadowTextAttribute& rCandidate) + : mpShadow(0), + mpTextAttribute(0) { - if(!(*this == rCandidate)) - { - *this = rCandidate; - } + *this = rCandidate; } SdrShadowTextAttribute::~SdrShadowTextAttribute() @@ -72,14 +73,14 @@ namespace drawinglayer // handle mpShadow { // delete local mpShadow if necessary - if(mpShadow && ((!rCandidate.mpShadow) || (!(*mpShadow == *rCandidate.mpShadow)))) + if(mpShadow) { delete mpShadow; - mpShadow = 0L; + mpShadow = 0; } // copy mpShadow if necessary - if(!mpShadow && rCandidate.mpShadow) + if(rCandidate.mpShadow) { mpShadow = new SdrShadowAttribute(*rCandidate.mpShadow); } @@ -88,14 +89,14 @@ namespace drawinglayer // handle mpTextAttribute { // delete local mpTextAttribute if necessary - if(mpTextAttribute && ((!rCandidate.mpTextAttribute) || (!(*mpTextAttribute == *rCandidate.mpTextAttribute)))) + if(mpTextAttribute) { delete mpTextAttribute; - mpTextAttribute = 0L; + mpTextAttribute = 0; } // copy mpTextAttribute if necessary - if(!mpTextAttribute && rCandidate.mpTextAttribute) + if(rCandidate.mpTextAttribute) { mpTextAttribute = new SdrTextAttribute(*rCandidate.mpTextAttribute); } @@ -125,22 +126,23 @@ namespace drawinglayer { namespace attribute { - SdrFillTextAttribute::SdrFillTextAttribute(SdrFillAttribute* pFill, FillGradientAttribute* pFillFloatTransGradient, SdrTextAttribute* pTextAttribute) + SdrFillTextAttribute::SdrFillTextAttribute( + SdrFillAttribute* pFill, + FillGradientAttribute* pFillFloatTransGradient, + SdrTextAttribute* pTextAttribute) : mpFill(pFill), mpFillFloatTransGradient(pFillFloatTransGradient), mpTextAttribute(pTextAttribute) { } - SdrFillTextAttribute::SdrFillTextAttribute(const SdrFillTextAttribute& rCandidate) + SdrFillTextAttribute::SdrFillTextAttribute( + const SdrFillTextAttribute& rCandidate) : mpFill(0), mpFillFloatTransGradient(0), mpTextAttribute(0) { - if(!(*this == rCandidate)) - { - *this = rCandidate; - } + *this = rCandidate; } SdrFillTextAttribute::~SdrFillTextAttribute() @@ -155,14 +157,14 @@ namespace drawinglayer // handle mpFill { // delete local mpFill if necessary - if(mpFill && ((!rCandidate.mpFill) || (!(*mpFill == *rCandidate.mpFill)))) + if(mpFill) { delete mpFill; - mpFill = 0L; + mpFill = 0; } // copy mpFill if necessary - if(!mpFill && rCandidate.mpFill) + if(rCandidate.mpFill) { mpFill = new attribute::SdrFillAttribute(*rCandidate.mpFill); } @@ -171,14 +173,14 @@ namespace drawinglayer // handle mpFillFloatTransGradient { // delete local mpFillFloatTransGradient if necessary - if(mpFillFloatTransGradient && ((!rCandidate.mpFillFloatTransGradient) || (!(*mpFillFloatTransGradient == *rCandidate.mpFillFloatTransGradient)))) + if(mpFillFloatTransGradient) { delete mpFillFloatTransGradient; - mpFillFloatTransGradient = 0L; + mpFillFloatTransGradient = 0; } // copy mpFillFloatTransGradient if necessary - if(!mpFillFloatTransGradient && rCandidate.mpFillFloatTransGradient) + if(rCandidate.mpFillFloatTransGradient) { mpFillFloatTransGradient = new FillGradientAttribute(*rCandidate.mpFillFloatTransGradient); } @@ -187,14 +189,14 @@ namespace drawinglayer // handle mpTextAttribute { // delete local mpTextAttribute if necessary - if(mpTextAttribute && ((!rCandidate.mpTextAttribute) || (!(*mpTextAttribute == *rCandidate.mpTextAttribute)))) + if(mpTextAttribute) { delete mpTextAttribute; - mpTextAttribute = 0L; + mpTextAttribute = 0; } // copy mpTextAttribute if necessary - if(!mpTextAttribute && rCandidate.mpTextAttribute) + if(rCandidate.mpTextAttribute) { mpTextAttribute = new SdrTextAttribute(*rCandidate.mpTextAttribute); } @@ -229,23 +231,23 @@ namespace drawinglayer namespace attribute { SdrLineShadowTextAttribute::SdrLineShadowTextAttribute( - SdrLineAttribute* pLine, SdrLineStartEndAttribute* pLineStartEnd, - SdrShadowAttribute* pShadow, SdrTextAttribute* pTextAttribute) + SdrLineAttribute* pLine, + SdrLineStartEndAttribute* pLineStartEnd, + SdrShadowAttribute* pShadow, + SdrTextAttribute* pTextAttribute) : SdrShadowTextAttribute(pShadow, pTextAttribute), mpLine(pLine), mpLineStartEnd(pLineStartEnd) { } - SdrLineShadowTextAttribute::SdrLineShadowTextAttribute(const SdrLineShadowTextAttribute& rCandidate) - : SdrShadowTextAttribute(0L, 0L), - mpLine(0L), - mpLineStartEnd(0L) + SdrLineShadowTextAttribute::SdrLineShadowTextAttribute( + const SdrLineShadowTextAttribute& rCandidate) + : SdrShadowTextAttribute(0, 0), + mpLine(0), + mpLineStartEnd(0) { - if(!(*this == rCandidate)) - { - *this = rCandidate; - } + *this = rCandidate; } SdrLineShadowTextAttribute::~SdrLineShadowTextAttribute() @@ -262,14 +264,14 @@ namespace drawinglayer // handle mpLine { // delete local mpLine if necessary - if(mpLine && ((!rCandidate.mpLine) || (!(*mpLine == *rCandidate.mpLine)))) + if(mpLine) { delete mpLine; - mpLine = 0L; + mpLine = 0; } // copy mpLine if necessary - if(!mpLine && rCandidate.mpLine) + if(rCandidate.mpLine) { mpLine = new SdrLineAttribute(*rCandidate.mpLine); } @@ -278,14 +280,14 @@ namespace drawinglayer // handle mpLineStartEnd { // delete local mpLineStartEnd if necessary - if(mpLineStartEnd && ((!rCandidate.mpLineStartEnd) || (!(*mpLineStartEnd == *rCandidate.mpLineStartEnd)))) + if(mpLineStartEnd) { delete mpLineStartEnd; - mpLineStartEnd = 0L; + mpLineStartEnd = 0; } // copy mpLineStartEnd if necessary - if(!mpLineStartEnd && rCandidate.mpLineStartEnd) + if(rCandidate.mpLineStartEnd) { mpLineStartEnd = new SdrLineStartEndAttribute(*rCandidate.mpLineStartEnd); } @@ -320,23 +322,25 @@ namespace drawinglayer namespace attribute { SdrLineFillShadowTextAttribute::SdrLineFillShadowTextAttribute( - SdrLineAttribute* pLine, attribute::SdrFillAttribute* pFill, SdrLineStartEndAttribute* pLineStartEnd, - SdrShadowAttribute* pShadow, FillGradientAttribute* pFillFloatTransGradient, SdrTextAttribute* pTextAttribute) + SdrLineAttribute* pLine, + attribute::SdrFillAttribute* pFill, + SdrLineStartEndAttribute* pLineStartEnd, + SdrShadowAttribute* pShadow, + FillGradientAttribute* pFillFloatTransGradient, + SdrTextAttribute* pTextAttribute) : SdrLineShadowTextAttribute(pLine, pLineStartEnd, pShadow, pTextAttribute), mpFill(pFill), mpFillFloatTransGradient(pFillFloatTransGradient) { } - SdrLineFillShadowTextAttribute::SdrLineFillShadowTextAttribute(const SdrLineFillShadowTextAttribute& rCandidate) - : SdrLineShadowTextAttribute(0L, 0L, 0L, 0L), - mpFill(0L), - mpFillFloatTransGradient(0L) + SdrLineFillShadowTextAttribute::SdrLineFillShadowTextAttribute( + const SdrLineFillShadowTextAttribute& rCandidate) + : SdrLineShadowTextAttribute(0, 0, 0, 0), + mpFill(0), + mpFillFloatTransGradient(0) { - if(!(*this == rCandidate)) - { - *this = rCandidate; - } + *this = rCandidate; } SdrLineFillShadowTextAttribute::~SdrLineFillShadowTextAttribute() @@ -353,14 +357,14 @@ namespace drawinglayer // handle mpFill { // delete local mpFill if necessary - if(mpFill && ((!rCandidate.mpFill) || (!(*mpFill == *rCandidate.mpFill)))) + if(mpFill) { delete mpFill; - mpFill = 0L; + mpFill = 0; } // copy mpFill if necessary - if(!mpFill && rCandidate.mpFill) + if(rCandidate.mpFill) { mpFill = new attribute::SdrFillAttribute(*rCandidate.mpFill); } @@ -369,14 +373,14 @@ namespace drawinglayer // handle mpFillFloatTransGradient { // delete local mpFillFloatTransGradient if necessary - if(mpFillFloatTransGradient && ((!rCandidate.mpFillFloatTransGradient) || (!(*mpFillFloatTransGradient == *rCandidate.mpFillFloatTransGradient)))) + if(mpFillFloatTransGradient) { delete mpFillFloatTransGradient; - mpFillFloatTransGradient = 0L; + mpFillFloatTransGradient = 0; } // copy mpFillFloatTransGradient if necessary - if(!mpFillFloatTransGradient && rCandidate.mpFillFloatTransGradient) + if(rCandidate.mpFillFloatTransGradient) { mpFillFloatTransGradient = new FillGradientAttribute(*rCandidate.mpFillFloatTransGradient); } diff --git a/svx/source/sdr/attribute/sdrformtextattribute.cxx b/svx/source/sdr/attribute/sdrformtextattribute.cxx new file mode 100644 index 000000000000..0282b519499c --- /dev/null +++ b/svx/source/sdr/attribute/sdrformtextattribute.cxx @@ -0,0 +1,304 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sdrtextattribute.cxx,v $ + * + * $Revision: 1.2 $ + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" + +#include <svx/sdr/attribute/sdrformtextattribute.hxx> +#include <svtools/itemset.hxx> + +#include <svx/xftdiit.hxx> +#include <svx/xftstit.hxx> +#include <svx/xftshxy.hxx> +#include <svx/xftshtit.hxx> +#include <svx/xtextit0.hxx> +#include <svx/xftadit.hxx> +#include <svx/xftshit.hxx> +#include <svx/xftshcit.hxx> +#include <svx/xftmrit.hxx> +#include <svx/xftouit.hxx> + +#include <svx/sdshtitm.hxx> +#include <svx/xlntrit.hxx> +#include <drawinglayer/attribute/lineattribute.hxx> +#include <drawinglayer/attribute/strokeattribute.hxx> +#include <svx/sdshcitm.hxx> +#include <svx/xlnclit.hxx> +#include <svx/xlnwtit.hxx> +#include <xlinjoit.hxx> +#include <svx/xlineit0.hxx> +#include <svx/xdash.hxx> +#include <svx/xlndsit.hxx> +#include <svx/sdr/attribute/sdrformtextoutlineattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// +// pointer compare define +#define pointerOrContentEqual(p, q) ((p == q) || (p && q && *p == *q)) + +////////////////////////////////////////////////////////////////////////////// +// helper to get line, stroke and transparence attributes from SfxItemSet + +namespace +{ + basegfx::B2DLineJoin impGetB2DLineJoin(XLineJoint eLineJoint) + { + switch(eLineJoint) + { + case XLINEJOINT_MIDDLE : + { + return basegfx::B2DLINEJOIN_MIDDLE; + } + case XLINEJOINT_BEVEL : + { + return basegfx::B2DLINEJOIN_BEVEL; + } + case XLINEJOINT_MITER : + { + return basegfx::B2DLINEJOIN_MITER; + } + case XLINEJOINT_ROUND : + { + return basegfx::B2DLINEJOIN_ROUND; + } + default : + { + return basegfx::B2DLINEJOIN_NONE; // XLINEJOINT_NONE + } + } + } + + sal_uInt8 impGetStrokeTransparence(bool bShadow, const SfxItemSet& rSet) + { + sal_uInt8 nRetval; + + if(bShadow) + { + nRetval = (sal_uInt8)((((SdrShadowTransparenceItem&)(rSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue() * 255) / 100); + } + else + { + nRetval = (sal_uInt8)((((XLineTransparenceItem&)(rSet.Get(XATTR_LINETRANSPARENCE))).GetValue() * 255) / 100); + } + + return nRetval; + } + + drawinglayer::attribute::LineAttribute impGetLineAttribute(bool bShadow, const SfxItemSet& rSet) + { + basegfx::BColor aColorAttribute; + + if(bShadow) + { + const Color aShadowColor(((SdrShadowColorItem&)(rSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue()); + aColorAttribute = aShadowColor.getBColor(); + } + else + { + const Color aLineColor(((XLineColorItem&)(rSet.Get(XATTR_LINECOLOR))).GetColorValue()); + aColorAttribute = aLineColor.getBColor(); + } + + const sal_uInt32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue(); + const XLineJoint eLineJoint = ((const XLineJointItem&)(rSet.Get(XATTR_LINEJOINT))).GetValue(); + + return drawinglayer::attribute::LineAttribute(aColorAttribute, (double)nLineWidth, impGetB2DLineJoin(eLineJoint)); + } + + drawinglayer::attribute::StrokeAttribute impGetStrokeAttribute(const SfxItemSet& rSet) + { + const XLineStyle eLineStyle = ((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue(); + double fFullDotDashLen(0.0); + ::std::vector< double > aDotDashArray; + + if(XLINE_DASH == eLineStyle) + { + const XDash& rDash = ((const XLineDashItem&)(rSet.Get(XATTR_LINEDASH))).GetDashValue(); + + if(rDash.GetDots() || rDash.GetDashes()) + { + const sal_uInt32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue(); + fFullDotDashLen = rDash.CreateDotDashArray(aDotDashArray, (double)nLineWidth); + } + } + + return drawinglayer::attribute::StrokeAttribute(aDotDashArray, fFullDotDashLen); + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + SdrFormTextAttribute::SdrFormTextAttribute(const SfxItemSet& rSet) + : mnFormTextDistance(((const XFormTextDistanceItem&)rSet.Get(XATTR_FORMTXTDISTANCE)).GetValue()), + mnFormTextStart(((const XFormTextStartItem&)rSet.Get(XATTR_FORMTXTSTART)).GetValue()), + mnFormTextShdwXVal(((const XFormTextShadowXValItem&)rSet.Get(XATTR_FORMTXTSHDWXVAL)).GetValue()), + mnFormTextShdwYVal(((const XFormTextShadowYValItem&)rSet.Get(XATTR_FORMTXTSHDWYVAL)).GetValue()), + mnFormTextShdwTransp(((const XFormTextShadowTranspItem&)rSet.Get(XATTR_FORMTXTSHDWTRANSP)).GetValue()), + meFormTextStyle(((const XFormTextStyleItem&)rSet.Get(XATTR_FORMTXTSTYLE)).GetValue()), + meFormTextAdjust(((const XFormTextAdjustItem&)rSet.Get(XATTR_FORMTXTADJUST)).GetValue()), + meFormTextShadow(((const XFormTextShadowItem&)rSet.Get(XATTR_FORMTXTSHADOW)).GetValue()), + maFormTextShdwColor(((const XFormTextShadowColorItem&)rSet.Get(XATTR_FORMTXTSHDWCOLOR)).GetColorValue()), + mpOutline(0), + mpShadowOutline(0), + mbFormTextMirror(((const XFormTextMirrorItem&)rSet.Get(XATTR_FORMTXTMIRROR)).GetValue()), + mbFormTextOutline(((const XFormTextOutlineItem&)rSet.Get(XATTR_FORMTXTOUTLINE)).GetValue()) + { + if(getFormTextOutline()) + { + const StrokeAttribute aStrokeAttribute(impGetStrokeAttribute(rSet)); + + // also need to prepare attributes for outlines + { + const LineAttribute aLineAttribute(impGetLineAttribute(false, rSet)); + const sal_uInt8 nTransparence(impGetStrokeTransparence(false, rSet)); + + mpOutline = new SdrFormTextOutlineAttribute( + aLineAttribute, aStrokeAttribute, nTransparence); + } + + if(XFTSHADOW_NONE != getFormTextShadow()) + { + // also need to prepare attributes for shadow outlines + const LineAttribute aLineAttribute(impGetLineAttribute(true, rSet)); + const sal_uInt8 nTransparence(impGetStrokeTransparence(true, rSet)); + + mpShadowOutline = new SdrFormTextOutlineAttribute( + aLineAttribute, aStrokeAttribute, nTransparence); + } + } + } + + SdrFormTextAttribute::~SdrFormTextAttribute() + { + if(mpOutline) + { + delete mpOutline; + mpOutline = 0; + } + + if(mpShadowOutline) + { + delete mpShadowOutline; + mpShadowOutline = 0; + } + } + + SdrFormTextAttribute::SdrFormTextAttribute(const SdrFormTextAttribute& rCandidate) + : mnFormTextDistance(rCandidate.getFormTextDistance()), + mnFormTextStart(rCandidate.getFormTextStart()), + mnFormTextShdwXVal(rCandidate.getFormTextShdwXVal()), + mnFormTextShdwYVal(rCandidate.getFormTextShdwYVal()), + mnFormTextShdwTransp(rCandidate.getFormTextShdwTransp()), + meFormTextStyle(rCandidate.getFormTextStyle()), + meFormTextAdjust(rCandidate.getFormTextAdjust()), + meFormTextShadow(rCandidate.getFormTextShadow()), + maFormTextShdwColor(rCandidate.getFormTextShdwColor()), + mpOutline(0), + mpShadowOutline(0), + mbFormTextMirror(rCandidate.getFormTextMirror()), + mbFormTextOutline(rCandidate.getFormTextOutline()) + { + if(rCandidate.getOutline()) + { + mpOutline = new SdrFormTextOutlineAttribute(*rCandidate.getOutline()); + } + + if(rCandidate.getShadowOutline()) + { + mpShadowOutline = new SdrFormTextOutlineAttribute(*rCandidate.getShadowOutline()); + } + } + + SdrFormTextAttribute& SdrFormTextAttribute::operator=(const SdrFormTextAttribute& rCandidate) + { + mnFormTextDistance = rCandidate.getFormTextDistance(); + mnFormTextStart = rCandidate.getFormTextStart(); + mnFormTextShdwXVal = rCandidate.getFormTextShdwXVal(); + mnFormTextShdwYVal = rCandidate.getFormTextShdwYVal(); + mnFormTextShdwTransp = rCandidate.getFormTextShdwTransp(); + meFormTextStyle = rCandidate.getFormTextStyle(); + meFormTextAdjust = rCandidate.getFormTextAdjust(); + meFormTextShadow = rCandidate.getFormTextShadow(); + maFormTextShdwColor = rCandidate.getFormTextShdwColor(); + + if(mpOutline) + { + delete mpOutline; + } + + mpOutline = 0; + + if(rCandidate.getOutline()) + { + mpOutline = new SdrFormTextOutlineAttribute(*rCandidate.getOutline()); + } + + if(mpShadowOutline) + { + delete mpShadowOutline; + } + + mpShadowOutline = 0; + + if(rCandidate.getShadowOutline()) + { + mpShadowOutline = new SdrFormTextOutlineAttribute(*rCandidate.getShadowOutline()); + } + + mbFormTextMirror = rCandidate.getFormTextMirror(); + mbFormTextOutline = rCandidate.getFormTextOutline(); + + return *this; + } + + bool SdrFormTextAttribute::operator==(const SdrFormTextAttribute& rCandidate) const + { + return (getFormTextDistance() == rCandidate.getFormTextDistance() + && getFormTextStart() == rCandidate.getFormTextStart() + && getFormTextShdwXVal() == rCandidate.getFormTextShdwXVal() + && getFormTextShdwYVal() == rCandidate.getFormTextShdwYVal() + && getFormTextShdwTransp() == rCandidate.getFormTextShdwTransp() + && getFormTextStyle() == rCandidate.getFormTextStyle() + && getFormTextAdjust() == rCandidate.getFormTextAdjust() + && getFormTextShadow() == rCandidate.getFormTextShadow() + && getFormTextShdwColor() == rCandidate.getFormTextShdwColor() + && pointerOrContentEqual(getOutline(), rCandidate.getOutline()) + && pointerOrContentEqual(getShadowOutline(), rCandidate.getShadowOutline()) + && getFormTextMirror() == rCandidate.getFormTextMirror() + && getFormTextOutline() == rCandidate.getFormTextOutline()); + } + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaylinestriped.cxx b/svx/source/sdr/attribute/sdrformtextoutlineattribute.cxx index c00be65908e2..db2fe20ae21b 100644 --- a/svx/source/sdr/overlay/overlaylinestriped.cxx +++ b/svx/source/sdr/attribute/sdrformtextoutlineattribute.cxx @@ -6,8 +6,9 @@ * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: overlaylinestriped.cxx,v $ - * $Revision: 1.4 $ + * $RCSfile: sdrtextattribute.cxx,v $ + * + * $Revision: 1.2 $ * * This file is part of OpenOffice.org. * @@ -28,20 +29,38 @@ * ************************************************************************/ -// MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svx.hxx" -#include <svx/sdr/overlay/overlaylinestriped.hxx> -#include <tools/gen.hxx> -#include <vcl/outdev.hxx> + +#include <svx/sdr/attribute/sdrformtextoutlineattribute.hxx> ////////////////////////////////////////////////////////////////////////////// +// pointer compare define +#define pointerOrContentEqual(p, q) ((p == q) || (p && q && *p == *q)) -namespace sdr +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer { - namespace overlay + namespace attribute { - } // end of namespace overlay -} // end of namespace sdr + SdrFormTextOutlineAttribute::SdrFormTextOutlineAttribute( + const LineAttribute& rLineAttribute, + const StrokeAttribute& rStrokeAttribute, + sal_uInt8 nTransparence) + : maLineAttribute(rLineAttribute), + maStrokeAttribute(rStrokeAttribute), + mnTransparence(nTransparence) + { + } + + bool SdrFormTextOutlineAttribute::operator==(const SdrFormTextOutlineAttribute& rCandidate) const + { + return (getLineAttribute() == rCandidate.getLineAttribute() + && getStrokeAttribute() == rCandidate.getStrokeAttribute() + && getTransparence() == rCandidate.getTransparence()); + } + } // end of namespace attribute +} // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// // eof diff --git a/svx/source/sdr/attribute/sdrtextattribute.cxx b/svx/source/sdr/attribute/sdrtextattribute.cxx index 394f68041d7a..33c958fa6268 100644 --- a/svx/source/sdr/attribute/sdrtextattribute.cxx +++ b/svx/source/sdr/attribute/sdrtextattribute.cxx @@ -30,11 +30,18 @@ ************************************************************************/ #include "precompiled_svx.hxx" + #include <svx/sdr/attribute/sdrtextattribute.hxx> +#include <svx/sdr/attribute/sdrformtextattribute.hxx> #include <svx/svdotext.hxx> #include <svx/outlobj.hxx> #include <svx/editobj.hxx> #include <svx/flditem.hxx> +#include <svx/sdr/properties/properties.hxx> + +////////////////////////////////////////////////////////////////////////////// +// pointer compare define +#define pointerOrContentEqual(p, q) ((p == q) || (p && q && *p == *q)) ////////////////////////////////////////////////////////////////////////////// @@ -56,13 +63,14 @@ namespace drawinglayer bool bBlink, bool bScroll, bool bInEditMode) - : mrSdrText(rSdrText), + : mpSdrText(&rSdrText), maOutlinerParaObject(rOutlinerParaObject), - meFormTextStyle(eFormTextStyle), + mpSdrFormTextAttribute(0), maTextLeftDistance(aTextLeftDistance), maTextUpperDistance(aTextUpperDistance), maTextRightDistance(aTextRightDistance), maTextLowerDistance(aTextLowerDistance), + maPropertiesVersion(0), mbContour(bContour), mbFitToSize(bFitToSize), mbHideContour(bHideContour), @@ -70,16 +78,94 @@ namespace drawinglayer mbScroll(bScroll), mbInEditMode(bInEditMode) { + if(XFT_NONE != eFormTextStyle) + { + // text on path. Create FormText attribute + const SfxItemSet& rSet = getSdrText().GetItemSet(); + mpSdrFormTextAttribute = new SdrFormTextAttribute(rSet); + } + + // #i101556# init with version number to detect changes of single text + // attribute and/or style sheets in primitive data without having to + // copy that data locally (which would be better from principle) + maPropertiesVersion = rSdrText.GetObject().GetProperties().getVersion(); + } + + SdrTextAttribute::~SdrTextAttribute() + { + if(mpSdrFormTextAttribute) + { + delete mpSdrFormTextAttribute; + mpSdrFormTextAttribute = 0; + } + } + + SdrTextAttribute::SdrTextAttribute(const SdrTextAttribute& rCandidate) + : mpSdrText(&rCandidate.getSdrText()), + maOutlinerParaObject(rCandidate.getOutlinerParaObject()), + mpSdrFormTextAttribute(0), + maTextLeftDistance(rCandidate.getTextLeftDistance()), + maTextUpperDistance(rCandidate.getTextUpperDistance()), + maTextRightDistance(rCandidate.getTextRightDistance()), + maTextLowerDistance(rCandidate.getTextLowerDistance()), + mbContour(rCandidate.isContour()), + mbFitToSize(rCandidate.isFitToSize()), + mbHideContour(rCandidate.isHideContour()), + mbBlink(rCandidate.isBlink()), + mbScroll(rCandidate.isScroll()), + mbInEditMode(rCandidate.isInEditMode()) + { + if(rCandidate.getSdrFormTextAttribute()) + { + mpSdrFormTextAttribute = new SdrFormTextAttribute(*rCandidate.getSdrFormTextAttribute()); + } + } + + SdrTextAttribute& SdrTextAttribute::operator=(const SdrTextAttribute& rCandidate) + { + mpSdrText = &rCandidate.getSdrText(); + maOutlinerParaObject = rCandidate.getOutlinerParaObject(); + + if(mpSdrFormTextAttribute) + { + delete mpSdrFormTextAttribute; + } + + mpSdrFormTextAttribute = 0; + + if(rCandidate.getSdrFormTextAttribute()) + { + mpSdrFormTextAttribute = new SdrFormTextAttribute(*rCandidate.getSdrFormTextAttribute()); + } + + maTextLeftDistance = rCandidate.getTextLeftDistance(); + maTextUpperDistance = rCandidate.getTextUpperDistance(); + maTextRightDistance = rCandidate.getTextRightDistance(); + maTextLowerDistance = rCandidate.getTextLowerDistance(); + mbContour = rCandidate.isContour(); + mbFitToSize = rCandidate.isFitToSize(); + mbHideContour = rCandidate.isHideContour(); + mbBlink = rCandidate.isBlink(); + mbScroll = rCandidate.isScroll(); + mbInEditMode = rCandidate.isInEditMode(); + + return *this; } bool SdrTextAttribute::operator==(const SdrTextAttribute& rCandidate) const { return (getOutlinerParaObject() == rCandidate.getOutlinerParaObject() - && getFormTextStyle() == rCandidate.getFormTextStyle() + // #i102062# for primitive visualisation, the WrongList (SpellChecking) + // is important, too, so use isWrongListEqual since there is no WrongList + // comparison in the regular OutlinerParaObject compare (since it's + // not-persistent data) + && getOutlinerParaObject().isWrongListEqual(rCandidate.getOutlinerParaObject()) + && pointerOrContentEqual(getSdrFormTextAttribute(), rCandidate.getSdrFormTextAttribute()) && getTextLeftDistance() == rCandidate.getTextLeftDistance() && getTextUpperDistance() == rCandidate.getTextUpperDistance() && getTextRightDistance() == rCandidate.getTextRightDistance() && getTextLowerDistance() == rCandidate.getTextLowerDistance() + && getPropertiesVersion() == rCandidate.getPropertiesVersion() && isContour() == rCandidate.isContour() && isFitToSize() == rCandidate.isFitToSize() && isHideContour() == rCandidate.isHideContour() @@ -92,7 +178,7 @@ namespace drawinglayer { if(isBlink()) { - mrSdrText.GetObject().impGetBlinkTextTiming(rAnimList); + mpSdrText->GetObject().impGetBlinkTextTiming(rAnimList); } } @@ -100,7 +186,7 @@ namespace drawinglayer { if(isScroll()) { - mrSdrText.GetObject().impGetScrollTextTiming(rAnimList, fFrameLength, fTextLength); + mpSdrText->GetObject().impGetScrollTextTiming(rAnimList, fFrameLength, fTextLength); } } } // end of namespace attribute diff --git a/svx/source/sdr/contact/viewcontactofe3dpolygon.cxx b/svx/source/sdr/contact/viewcontactofe3dpolygon.cxx index 851ee1f3da58..9ae265d29362 100644 --- a/svx/source/sdr/contact/viewcontactofe3dpolygon.cxx +++ b/svx/source/sdr/contact/viewcontactofe3dpolygon.cxx @@ -75,8 +75,8 @@ namespace sdr basegfx::B3DPolyPolygon aPolyPolygon3D(GetE3dPolygonObj().GetPolyPolygon3D()); const basegfx::B3DPolyPolygon aPolyNormals3D(GetE3dPolygonObj().GetPolyNormals3D()); const basegfx::B2DPolyPolygon aPolyTexture2D(GetE3dPolygonObj().GetPolyTexture2D()); - const bool bNormals(aPolyNormals3D.count()); - const bool bTexture(aPolyTexture2D.count()); + const bool bNormals(aPolyNormals3D.count() && aPolyNormals3D.count() == aPolyPolygon3D.count());
+ const bool bTexture(aPolyTexture2D.count() && aPolyTexture2D.count() == aPolyPolygon3D.count());
if(bNormals || bTexture) { @@ -100,12 +100,19 @@ namespace sdr { if(bNormals) { - aCandidate3D.setNormal(b, aNormals3D.getB3DPoint(b)); + sal_uInt32 nNormalCount = aNormals3D.count(); + if( b < nNormalCount ) + aCandidate3D.setNormal(b, aNormals3D.getB3DPoint(b)); + else if( nNormalCount > 0 ) + aCandidate3D.setNormal(b, aNormals3D.getB3DPoint(0)); } - if(bTexture) { - aCandidate3D.setTextureCoordinate(b, aTexture2D.getB2DPoint(b)); + sal_uInt32 nTextureCount = aTexture2D.count(); + if( b < nTextureCount ) + aCandidate3D.setTextureCoordinate(b, aTexture2D.getB2DPoint(b)); + else if( nTextureCount > 0 ) + aCandidate3D.setTextureCoordinate(b, aTexture2D.getB2DPoint(0)); } } diff --git a/svx/source/sdr/contact/viewcontactofgraphic.cxx b/svx/source/sdr/contact/viewcontactofgraphic.cxx index aae01c5d24ff..b083a1014299 100644 --- a/svx/source/sdr/contact/viewcontactofgraphic.cxx +++ b/svx/source/sdr/contact/viewcontactofgraphic.cxx @@ -53,6 +53,18 @@ #include <svdglob.hxx> #include <vcl/svapp.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> +#include <drawinglayer/primitive2d/textprimitive2d.hxx> +#include <drawinglayer/primitive2d/textlayoutdevice.hxx> +#include <drawinglayer/primitive2d/maskprimitive2d.hxx> + +#include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx> +#include <svx/eeitem.hxx> +#include <svx/colritem.hxx> +//#include <svx/xtable.hxx> + ////////////////////////////////////////////////////////////////////////////// namespace sdr @@ -78,6 +90,238 @@ namespace sdr { } + void ViewContactOfGraphic::flushGraphicObjects() + { + // #i102380# The graphic is swapped out. To let that have an effect ist is necessary to + // delete copies of the GraphicObject which are not swapped out and have no SwapHandler set + // (this is what happnes when the GraphicObject gets copied to a SdrGrafPrimitive2D). This + // is best achieved for the VC by clearing the local decomposition cache. It would be possible + // to also do this for the VOC cache, but that VOCs exist exactly expresss that the object + // gets visualised, so this would be wrong. + flushViewIndependentPrimitive2DSequence(); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createVIP2DSForPresObj( + const basegfx::B2DHomMatrix& rObjectMatrix, + const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute, + const GraphicAttr& rLocalGrafInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + GraphicObject aEmptyGraphicObject; + GraphicAttr aEmptyGraphicAttr; + + // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts + const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D( + rObjectMatrix, + rAttribute, + aEmptyGraphicObject, + aEmptyGraphicAttr)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1); + + // SdrGrafPrimitive2D with content (which is the preview graphic) scaled to smaller size and + // without attributes + basegfx::B2DHomMatrix aSmallerMatrix; + + // #i94431# for some reason, i forgot to take the PrefMapMode of the graphic + // into account. Since EmptyPresObj's are only used in Draw/Impress, it is + // safe to assume 100th mm as target. + Size aPrefSize(GetGrafObject().GetGrafPrefSize()); + + if(MAP_PIXEL == GetGrafObject().GetGrafPrefMapMode().GetMapUnit()) + { + aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MAP_100TH_MM); + } + else + { + aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, GetGrafObject().GetGrafPrefMapMode(), MAP_100TH_MM); + } + + // decompose object matrix to get single values + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX); + + const double fOffsetX((aScale.getX() - aPrefSize.getWidth()) / 2.0); + const double fOffsetY((aScale.getY() - aPrefSize.getHeight()) / 2.0); + + if(basegfx::fTools::moreOrEqual(fOffsetX, 0.0) && basegfx::fTools::moreOrEqual(fOffsetY, 0.0)) + { + // create the EmptyPresObj fallback visualisation. The fallback graphic + // is already provided in rGraphicObject in this case, use it + aSmallerMatrix.scale(aPrefSize.getWidth(), aPrefSize.getHeight()); + aSmallerMatrix.translate(fOffsetX, fOffsetY); + aSmallerMatrix.shearX(fShearX); + aSmallerMatrix.rotate(fRotate); + aSmallerMatrix.translate(aTranslate.getX(), aTranslate.getY()); + + const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false); + const drawinglayer::attribute::SdrLineFillShadowTextAttribute aEmptyAttributes(0, 0, 0, 0, 0, 0); + const drawinglayer::primitive2d::Primitive2DReference xReferenceB(new drawinglayer::primitive2d::SdrGrafPrimitive2D( + aSmallerMatrix, + aEmptyAttributes, + rGraphicObject, + rLocalGrafInfo)); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReferenceB); + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createVIP2DSForDraft( + const basegfx::B2DHomMatrix& rObjectMatrix, + const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + GraphicObject aEmptyGraphicObject; + GraphicAttr aEmptyGraphicAttr; + + // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts + const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D( + rObjectMatrix, + rAttribute, + aEmptyGraphicObject, + aEmptyGraphicAttr)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1); + + if(!rAttribute.getLine()) + { + // create a surrounding frame when no linestyle given + const Color aColor(Application::GetSettings().GetStyleSettings().GetShadowColor()); + const basegfx::BColor aBColor(aColor.getBColor()); + const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0); + + basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aUnitRange)); + aOutline.transform(rObjectMatrix); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D( + aOutline, + aBColor))); + } + + // decompose object matrix to get single values + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX); + + // define a distance value, used for distance from bitmap to borders and from bitmap + // to text, too (2 mm) + const double fDistance(200.0); + + // consume borders from values + aScale.setX(std::max(0.0, aScale.getX() - (2.0 * fDistance))); + aScale.setY(std::max(0.0, aScale.getY() - (2.0 * fDistance))); + aTranslate.setX(aTranslate.getX() + fDistance); + aTranslate.setY(aTranslate.getY() + fDistance); + + // draw a draft bitmap + const Bitmap aDraftBitmap(ResId(BMAP_GrafikEi, *ImpGetResMgr())); + + if(!aDraftBitmap.IsEmpty()) + { + Size aPrefSize(aDraftBitmap.GetPrefSize()); + + if(MAP_PIXEL == aDraftBitmap.GetPrefMapMode().GetMapUnit()) + { + aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aDraftBitmap.GetSizePixel(), MAP_100TH_MM); + } + else + { + aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, aDraftBitmap.GetPrefMapMode(), MAP_100TH_MM); + } + + const double fBitmapScaling(2.0); + const double fWidth(aPrefSize.getWidth() * fBitmapScaling); + const double fHeight(aPrefSize.getHeight() * fBitmapScaling); + + if(basegfx::fTools::more(fWidth, 1.0) + && basegfx::fTools::more(fHeight, 1.0) + && basegfx::fTools::lessOrEqual(fWidth, aScale.getX()) + && basegfx::fTools::lessOrEqual(fHeight, aScale.getY())) + { + basegfx::B2DHomMatrix aBitmapMatrix; + + aBitmapMatrix.scale(fWidth, fHeight); + aBitmapMatrix.shearX(fShearX); + aBitmapMatrix.rotate(fRotate); + aBitmapMatrix.translate(aTranslate.getX(), aTranslate.getY()); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::BitmapPrimitive2D( + BitmapEx(aDraftBitmap), + aBitmapMatrix))); + + // consume bitmap size in X + aScale.setX(std::max(0.0, aScale.getX() - (fWidth + fDistance))); + aTranslate.setX(aTranslate.getX() + fWidth + fDistance); + } + } + + // Build the text for the draft object + XubString aDraftText = GetGrafObject().GetFileName(); + + if(!aDraftText.Len()) + { + aDraftText = GetGrafObject().GetName(); + aDraftText.AppendAscii(" ..."); + } + + if(aDraftText.Len() && GetGrafObject().GetModel()) + { + // #i103255# Goal is to produce TextPrimitives which hold the given text as + // BlockText in the available space. It would be very tricky to do + // an own word wrap/line layout here. + // Using SdrBlockTextPrimitive2D OTOH is critical since it internally + // uses the SdrObject it references. To solve this, create a temp + // SdrObject with Attributes and Text, generate a SdrBlockTextPrimitive2D + // directly and immediately decompose it. After that, it is no longer + // needed and can be deleted. + + // create temp RectObj as TextObj and set needed attributes + SdrRectObj aRectObj(OBJ_TEXT); + aRectObj.SetModel(GetGrafObject().GetModel()); + aRectObj.NbcSetText(aDraftText); + aRectObj.SetMergedItem(SvxColorItem(Color(COL_LIGHTRED), EE_CHAR_COLOR)); + + // get SdrText and OPO + SdrText* pSdrText = aRectObj.getText(0); + OutlinerParaObject* pOPO = aRectObj.GetOutlinerParaObject(); + + if(pSdrText && pOPO) + { + // directly use the remaining space as TextRangeTransform + basegfx::B2DHomMatrix aTextRangeTransform; + + aTextRangeTransform.scale(aScale.getX(), aScale.getY()); + aTextRangeTransform.shearX(fShearX); + aTextRangeTransform.rotate(fRotate); + aTextRangeTransform.translate(aTranslate.getX(), aTranslate.getY()); + + // directly create temp SdrBlockTextPrimitive2D + drawinglayer::primitive2d::SdrBlockTextPrimitive2D aBlockTextPrimitive( + pSdrText, + *pOPO, + aTextRangeTransform, + false, + false, + false); + + // decompose immediately with neutral ViewInformation. This will + // layout the text to more simple TextPrimitives from drawinglayer + const drawinglayer::geometry::ViewInformation2D aViewInformation2D(0); + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence( + xRetval, + aBlockTextPrimitive.get2DDecomposition(aViewInformation2D)); + } + } + + return xRetval; + } + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createViewIndependentPrimitive2DSequence() const { drawinglayer::primitive2d::Primitive2DSequence xRetval; @@ -86,7 +330,8 @@ namespace sdr if(pSdrText) { const SfxItemSet& rItemSet = GetGrafObject().GetMergedItemSet(); - drawinglayer::attribute::SdrLineFillShadowTextAttribute* pAttribute = drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute(rItemSet, *pSdrText); + drawinglayer::attribute::SdrLineFillShadowTextAttribute* pAttribute = + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute(rItemSet, *pSdrText); bool bVisible(pAttribute && pAttribute->isVisible()); // create and fill GraphicAttr @@ -131,7 +376,7 @@ namespace sdr // which will use the primitive data we just create in the near future const Rectangle& rRectangle = GetGrafObject().GetGeoRect(); const ::basegfx::B2DRange aObjectRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom()); - ::basegfx::B2DHomMatrix aObjectMatrix; + basegfx::B2DHomMatrix aObjectMatrix; // look for mirroring const GeoStat& rGeoStat(GetGrafObject().GetGeoStat()); @@ -170,60 +415,25 @@ namespace sdr // get the current, unchenged graphic obect from SdrGrafObj const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false); - if(GetGrafObject().IsEmptyPresObj()) + if(visualisationUsesPresObj()) { // it's an EmptyPresObj, create the SdrGrafPrimitive2D without content and another scaled one // with the content which is the placeholder graphic - GraphicObject aEmptyGraphicObject; - GraphicAttr aEmptyGraphicAttr; - drawinglayer::attribute::SdrLineFillShadowTextAttribute aEmptyAttributes(0, 0, 0, 0, 0, 0); - - // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts - const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D( - aObjectMatrix, *pAttribute, aEmptyGraphicObject, aEmptyGraphicAttr)); - xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1); - - // SdrGrafPrimitive2D with content (which is the preview graphic) scaled to smaller size and - // without attributes - basegfx::B2DHomMatrix aSmallerMatrix; - - // #i94431# for some reason, i forgot to take the PrefMapMode of the graphic - // into account. Since EmptyPresObj's are only used in Draw/Impress, it is - // safe to assume 100th mm as target. - Size aPrefSize(GetGrafObject().GetGrafPrefSize()); - - if(MAP_PIXEL == GetGrafObject().GetGrafPrefMapMode().GetMapUnit()) - { - aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MAP_100TH_MM); - } - else - { - aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, GetGrafObject().GetGrafPrefMapMode(), MAP_100TH_MM); - } - - const double fOffsetX((aObjectRange.getWidth() - aPrefSize.getWidth()) / 2.0); - const double fOffsetY((aObjectRange.getHeight() - aPrefSize.getHeight()) / 2.0); - - if(basegfx::fTools::moreOrEqual(fOffsetX, 0.0) && basegfx::fTools::moreOrEqual(fOffsetY, 0.0)) - { - aSmallerMatrix.scale(aPrefSize.getWidth(), aPrefSize.getHeight()); - aSmallerMatrix.translate(fOffsetX, fOffsetY); - aSmallerMatrix.shearX(fShearX); - aSmallerMatrix.rotate(fRotate); - aSmallerMatrix.translate(aObjectRange.getMinX(), aObjectRange.getMinY()); - - const drawinglayer::primitive2d::Primitive2DReference xReferenceB(new drawinglayer::primitive2d::SdrGrafPrimitive2D( - aSmallerMatrix, - aEmptyAttributes, - rGraphicObject, - aLocalGrafInfo)); - - drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReferenceB); - } + xRetval = createVIP2DSForPresObj(aObjectMatrix, *pAttribute, aLocalGrafInfo); + } + else if(visualisationUsesDraft()) + { + // #i102380# The graphic is swapped out. To not force a swap-in here, there is a mechanism + // which shows a swapped-out-visualisation (which gets created here now) and an asynchronious + // visual update mechanism for swapped-out grapgics when they were loaded (see AsynchGraphicLoadingEvent + // and ViewObjectContactOfGraphic implementation). Not forcing the swap-in here allows faster + // (non-blocking) processing here and thus in the effect e.g. fast scrolling through pages + xRetval = createVIP2DSForDraft(aObjectMatrix, *pAttribute); } else { - // create primitive + // create primitive. Info: Calling the copy-constructor of GraphicObject in this + // SdrGrafPrimitive2D constructor will force a full swap-in of the graphic const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::SdrGrafPrimitive2D( aObjectMatrix, *pAttribute, @@ -241,6 +451,31 @@ namespace sdr return xRetval; } + bool ViewContactOfGraphic::visualisationUsesPresObj() const + { + return GetGrafObject().IsEmptyPresObj(); + } + + bool ViewContactOfGraphic::visualisationUsesDraft() const + { + // no draft when already PresObj + if(visualisationUsesPresObj()) + return false; + + // draft when swapped out + const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false); + static bool bAllowReplacements(true); + + if(rGraphicObject.IsSwappedOut() && bAllowReplacements) + return true; + + // draft when no graphic + if(GRAPHIC_NONE == rGraphicObject.GetType() || GRAPHIC_DEFAULT == rGraphicObject.GetType()) + return true; + + return false; + } + } // end of namespace contact } // end of namespace sdr diff --git a/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx b/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx index e1b2867b0d66..3c239b12113c 100644 --- a/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx @@ -45,6 +45,7 @@ #include <svtools/colorcfg.hxx> #include <svx/sdr/primitive2d/sdrattributecreator.hxx> #include <vcl/svapp.hxx> +#include <svx/sdr/primitive2d/sdrolecontentprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -71,7 +72,8 @@ namespace sdr { } - drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrOle2Obj::createPrimitive2DSequenceWithGivenGraphic(const Graphic& rOLEGraphic, bool bScaleContent) const + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrOle2Obj::createPrimitive2DSequenceWithParameters( + bool bHighContrast) const { drawinglayer::primitive2d::Primitive2DSequence xRetval; SdrText* pSdrText = GetOle2Obj().getText(0); @@ -103,80 +105,24 @@ namespace sdr pAttribute = new drawinglayer::attribute::SdrLineFillShadowTextAttribute(0, 0, 0, 0, 0, 0); } - // Prepare OLE filling. This is normally the metafile describing OLE content, but may also - // be the empty OLE bitmap for empty/not loaded OLEs - const GraphicObject aGraphicObject(rOLEGraphic); - const GraphicAttr aGraphicAttr; - drawinglayer::primitive2d::Primitive2DSequence xOLEContent; - - if(bScaleContent) - { - // Create outline and placeholder graphic with some scaling - // #i94431# for some reason, i forgot to take the PrefMapMode of the graphic - // into account. Since EmptyPresObj's are only used in Draw/Impress, it is - // safe to assume 100th mm as target. - Size aPrefSize(rOLEGraphic.GetPrefSize()); - - if(MAP_PIXEL == rOLEGraphic.GetPrefMapMode().GetMapUnit()) - { - aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MAP_100TH_MM); - } - else - { - aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, rOLEGraphic.GetPrefMapMode(), MAP_100TH_MM); - } - - const double fOffsetX((aObjectRange.getWidth() - aPrefSize.getWidth()) / 2.0); - const double fOffsetY((aObjectRange.getHeight() - aPrefSize.getHeight()) / 2.0); - - if(basegfx::fTools::moreOrEqual(fOffsetX, 0.0) && basegfx::fTools::moreOrEqual(fOffsetY, 0.0)) - { - // if content fits into frame, create it - basegfx::B2DHomMatrix aInnerObjectMatrix; - - aInnerObjectMatrix.scale(aPrefSize.getWidth(), aPrefSize.getHeight()); - aInnerObjectMatrix.translate(fOffsetX, fOffsetY); - aInnerObjectMatrix.shearX(fShearX); - aInnerObjectMatrix.rotate(fRotate); - aInnerObjectMatrix.translate(aObjectRange.getMinX(), aObjectRange.getMinY()); - - drawinglayer::primitive2d::Primitive2DReference xScaledContent( - new drawinglayer::primitive2d::GraphicPrimitive2D(aInnerObjectMatrix, aGraphicObject, aGraphicAttr)); - xOLEContent = drawinglayer::primitive2d::Primitive2DSequence(&xScaledContent, 1); - } - } - else - { - // create graphic primitive for content - drawinglayer::primitive2d::Primitive2DReference xDirectContent( - new drawinglayer::primitive2d::GraphicPrimitive2D(aObjectMatrix, aGraphicObject, aGraphicAttr)); - xOLEContent = drawinglayer::primitive2d::Primitive2DSequence(&xDirectContent, 1); - } + // #i102063# embed OLE content in an own primitive; this will be able to decompose accessing + // the weak SdrOle2 reference and will also implement getB2DRange() for fast BoundRect + // calculations without OLE Graphic access (which may trigger e.g. chart recalculation). + // It will also take care of HighContrast and ScaleContent + const drawinglayer::primitive2d::Primitive2DReference xOleContent( + new drawinglayer::primitive2d::SdrOleContentPrimitive2D( + GetOle2Obj(), + aObjectMatrix, + bHighContrast)); // create primitive. Use Ole2 primitive here. Prepare attribute settings, will be used soon anyways. + const drawinglayer::primitive2d::Primitive2DSequence xOLEContent(&xOleContent, 1); const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::SdrOle2Primitive2D( xOLEContent, aObjectMatrix, *pAttribute)); xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); delete pAttribute; - - // a standard gray outline is created for scaled content - if(bScaleContent) - { - const svtools::ColorConfig aColorConfig; - const svtools::ColorConfigValue aColor(aColorConfig.GetColorValue(svtools::OBJECTBOUNDARIES)); - - if(aColor.bIsVisible) - { - basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0, 0, 1, 1))); - const Color aVclColor(aColor.nColor); - aOutline.transform(aObjectMatrix); - const drawinglayer::primitive2d::Primitive2DReference xOutline( - new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aVclColor.getBColor())); - drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xOutline); - } - } } return xRetval; @@ -184,21 +130,8 @@ namespace sdr drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrOle2Obj::createViewIndependentPrimitive2DSequence() const { - const Graphic* pOLEGraphic = GetOle2Obj().GetGraphic(); - - if(pOLEGraphic) - { - // there is a graphic set, use it - return createPrimitive2DSequenceWithGivenGraphic(*pOLEGraphic, GetOle2Obj().IsEmptyPresObj()); - } - else - { - // no graphic, use default empty OLE bitmap - const Bitmap aEmptyOLEBitmap(GetOle2Obj().GetEmtyOLEReplacementBitmap()); - const Graphic aEmtyOLEGraphic(aEmptyOLEBitmap); - - return createPrimitive2DSequenceWithGivenGraphic(aEmtyOLEGraphic, true); - } + // do as if no HC and call standard creator + return createPrimitive2DSequenceWithParameters(false); } } // end of namespace contact } // end of namespace sdr diff --git a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx index dc3fbcfaaa61..0f818ff40f7a 100644 --- a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx @@ -62,59 +62,86 @@ namespace sdr if(pSdrText) { - drawinglayer::attribute::SdrLineFillShadowTextAttribute* pAttribute = drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute(rItemSet, *pSdrText); + drawinglayer::attribute::SdrLineFillShadowTextAttribute* pAttribute = + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + *pSdrText); if(pAttribute) { if(pAttribute->isVisible()) { - // prepare object transformation and unit polygon (direct model data) - ::basegfx::B2DHomMatrix aObjectMatrix; - ::basegfx::B2DPolyPolygon aUnitPolyPolygon(GetPathObj().GetPathPoly()); - const bool bIsLine( - !aUnitPolyPolygon.areControlPointsUsed() - && 1L == aUnitPolyPolygon.count() - && 2L == aUnitPolyPolygon.getB2DPolygon(0L).count()); - - if(bIsLine) - { - // special handling for single line mode (2 points) - const ::basegfx::B2DPolygon aSubPolygon(aUnitPolyPolygon.getB2DPolygon(0L)); - const ::basegfx::B2DPoint aStart(aSubPolygon.getB2DPoint(0L)); - const ::basegfx::B2DPoint aEnd(aSubPolygon.getB2DPoint(1L)); - const ::basegfx::B2DVector aLine(aEnd - aStart); - - // create new polygon - ::basegfx::B2DPolygon aNewPolygon; - aNewPolygon.append(::basegfx::B2DPoint(0.0, 0.0)); - aNewPolygon.append(::basegfx::B2DPoint(aLine.getLength(), 0.0)); - aUnitPolyPolygon.setB2DPolygon(0L, aNewPolygon); - - // fill objectMatrix with rotation and offset (no shear for lines, scale in polygon) - aObjectMatrix.rotate(atan2(aLine.getY(), aLine.getX())); - aObjectMatrix.translate(aStart.getX(), aStart.getY()); - } - else + basegfx::B2DPolyPolygon aUnitPolyPolygon(GetPathObj().GetPathPoly()); + const sal_uInt32 nPolyCount(aUnitPolyPolygon.count()); + + if(nPolyCount) { - // create scaled, but unsheared, unrotated and untranslated polygon - // by creating the object matrix and back-transforming the polygon - const ::basegfx::B2DRange aObjectRange(::basegfx::tools::getRange(aUnitPolyPolygon)); - const GeoStat& rGeoStat(GetPathObj().GetGeoStat()); - - aObjectMatrix.shearX(tan((36000 - rGeoStat.nShearWink) * F_PI18000)); - aObjectMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000); - aObjectMatrix.translate(aObjectRange.getMinX(), aObjectRange.getMinY()); - - // ceate scaled unit polygon from object's absolute path - ::basegfx::B2DHomMatrix aInverse(aObjectMatrix); - aInverse.invert(); - aUnitPolyPolygon.transform(aInverse); + // prepare object transformation and unit polygon (direct model data) + basegfx::B2DHomMatrix aObjectMatrix; + const bool bIsLine( + !aUnitPolyPolygon.areControlPointsUsed() + && 1 == nPolyCount + && 2 == aUnitPolyPolygon.getB2DPolygon(0).count()); + + if(bIsLine) + { + // special handling for single line mode (2 points) + const basegfx::B2DPolygon aSubPolygon(aUnitPolyPolygon.getB2DPolygon(0)); + const basegfx::B2DPoint aStart(aSubPolygon.getB2DPoint(0)); + const basegfx::B2DPoint aEnd(aSubPolygon.getB2DPoint(1)); + const basegfx::B2DVector aLine(aEnd - aStart); + + // #i102548# create new unit polygon for line (horizontal) + basegfx::B2DPolygon aNewPolygon; + aNewPolygon.append(basegfx::B2DPoint(0.0, 0.0)); + aNewPolygon.append(basegfx::B2DPoint(1.0, 0.0)); + aUnitPolyPolygon.setB2DPolygon(0, aNewPolygon); + + // #i102548# fill objectMatrix with rotation and offset (no shear for lines) + aObjectMatrix.scale(aLine.getLength(), 1.0); + aObjectMatrix.rotate(atan2(aLine.getY(), aLine.getX())); + aObjectMatrix.translate(aStart.getX(), aStart.getY()); + } + else + { + // #i102548# create unscaled, unsheared, unrotated and untranslated polygon + // (unit polygon) by creating the object matrix and back-transforming the polygon + const basegfx::B2DRange aObjectRange(basegfx::tools::getRange(aUnitPolyPolygon)); + const GeoStat& rGeoStat(GetPathObj().GetGeoStat()); + const double fWidth(aObjectRange.getWidth()); + const double fHeight(aObjectRange.getHeight()); + + aObjectMatrix.scale( + basegfx::fTools::equalZero(fWidth) ? 1.0 : fWidth, + basegfx::fTools::equalZero(fHeight) ? 1.0 : fHeight); + + if(rGeoStat.nShearWink) + { + aObjectMatrix.shearX(tan((36000 - rGeoStat.nShearWink) * F_PI18000)); + } + + if(rGeoStat.nDrehWink) + { + aObjectMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000); + } + + aObjectMatrix.translate(aObjectRange.getMinX(), aObjectRange.getMinY()); + + // ceate unit polygon from object's absolute path + basegfx::B2DHomMatrix aInverse(aObjectMatrix); + aInverse.invert(); + aUnitPolyPolygon.transform(aInverse); + } + + // create primitive + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrPathPrimitive2D( + aObjectMatrix, + *pAttribute, + aUnitPolyPolygon)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); } - - // create primitive - const drawinglayer::primitive2d::Primitive2DReference xReference( - new drawinglayer::primitive2d::SdrPathPrimitive2D(aObjectMatrix, *pAttribute, aUnitPolyPolygon)); - xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); } delete pAttribute; diff --git a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx index c48d110faaf2..8ba8ae8ab4c9 100644 --- a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx @@ -105,8 +105,14 @@ namespace sdr drawinglayer::primitive2d::calculateRelativeCornerRadius(nCornerRadius, aObjectRange, fCornerRadiusX, fCornerRadiusY); // create primitive - const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::SdrRectanglePrimitive2D( - aObjectMatrix, *pAttribute, fCornerRadiusX, fCornerRadiusY)); + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrRectanglePrimitive2D( + aObjectMatrix, + *pAttribute, + fCornerRadiusX, + fCornerRadiusY, + GetRectObj().IsTextFrame())); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); } diff --git a/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx b/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx index 394ae3141182..5e9ab788e392 100644 --- a/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx @@ -38,6 +38,7 @@ #include <svx/svdograf.hxx> #include <svx/sdr/contact/objectcontact.hxx> #include <svx/svdmodel.hxx> +#include <svx/svdpage.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -219,6 +220,11 @@ namespace sdr SdrGrafObj& rGrafObj = getSdrGrafObj(); rGrafObj.ForceSwapIn(); + // #i103720# forget event to avoid possible deletion by the following ActionChanged call + // which may use createPrimitive2DSequence/impPrepareGraphicWithAsynchroniousLoading again. + // Deletion is actally done by the scheduler who leaded to coming here + mpAsynchLoadEvent = 0; + // Invalidate all paint areas and check existing animation (which may have changed). GetViewContact().ActionChanged(); } @@ -229,11 +235,15 @@ namespace sdr void ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent(sdr::event::AsynchGraphicLoadingEvent* pEvent) { (void) pEvent; // suppress warning - DBG_ASSERT(mpAsynchLoadEvent, "ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent: I did not trigger a event, why am i called (?)"); - DBG_ASSERT(mpAsynchLoadEvent == pEvent, "ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent: Forced to forget another event then i have scheduled (?)"); - // forget event - mpAsynchLoadEvent = 0; + if(mpAsynchLoadEvent) + { + OSL_ENSURE(!pEvent || mpAsynchLoadEvent == pEvent, + "ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent: Forced to forget another event then i have scheduled (?)"); + + // forget event + mpAsynchLoadEvent = 0; + } } SdrGrafObj& ViewObjectContactOfGraphic::getSdrGrafObj() @@ -245,10 +255,19 @@ namespace sdr { // prepare primitive generation with evtl. loading the graphic when it's swapped out SdrGrafObj& rGrafObj = const_cast< ViewObjectContactOfGraphic* >(this)->getSdrGrafObj(); - const bool bDoAsynchronGraphicLoading(rGrafObj.GetModel() && rGrafObj.GetModel()->IsSwapGraphics()); + bool bDoAsynchronGraphicLoading(rGrafObj.GetModel() && rGrafObj.GetModel()->IsSwapGraphics()); static bool bSuppressAsynchLoading(false); bool bSwapInDone(false); + if(bDoAsynchronGraphicLoading + && rGrafObj.IsSwappedOut() + && rGrafObj.GetPage() + && rGrafObj.GetPage()->IsMasterPage()) + { + // #i102380# force Swap-In for GraphicObjects on MasterPage to have a nicer visualisation + bDoAsynchronGraphicLoading = false; + } + if(bDoAsynchronGraphicLoading && !bSuppressAsynchLoading) { bSwapInDone = const_cast< ViewObjectContactOfGraphic* >(this)->impPrepareGraphicWithAsynchroniousLoading(); @@ -261,6 +280,23 @@ namespace sdr // get return value by calling parent drawinglayer::primitive2d::Primitive2DSequence xRetval = ViewObjectContactOfSdrObj::createPrimitive2DSequence(rDisplayInfo); + if(xRetval.hasElements()) + { + // #i103255# suppress when graphic needs draft visualisation and output + // is for PDF export/Printer + const ViewContactOfGraphic& rVCOfGraphic = static_cast< const ViewContactOfGraphic& >(GetViewContact()); + + if(rVCOfGraphic.visualisationUsesDraft()) + { + const ObjectContact& rObjectContact = GetObjectContact(); + + if(rObjectContact.isOutputToPDFFile() || rObjectContact.isOutputToPrinter()) + { + xRetval = drawinglayer::primitive2d::Primitive2DSequence(); + } + } + } + // if swap in was forced only for printing, swap out again const bool bSwapInExclusiveForPrinting(bSwapInDone && GetObjectContact().isOutputToPrinter()); diff --git a/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx index 87288882995e..34fddf088c98 100644 --- a/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx @@ -291,7 +291,8 @@ namespace sdr } // add a gray outline frame, except not when printing - if(!GetObjectContact().isOutputToPrinter()) + // #i102637# add frame also when printing and page exists (handout pages) + if(!GetObjectContact().isOutputToPrinter() || pPage) { const Color aFrameColor(aColorConfig.GetColorValue(svtools::OBJECTBOUNDARIES).nColor); basegfx::B2DPolygon aOwnOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0))); diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrole2obj.cxx b/svx/source/sdr/contact/viewobjectcontactofsdrole2obj.cxx index d5681c60463e..635ae9c7fcc8 100644 --- a/svx/source/sdr/contact/viewobjectcontactofsdrole2obj.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofsdrole2obj.cxx @@ -37,10 +37,13 @@ #include <svx/sdr/contact/viewcontactofsdrole2obj.hxx> #include <svx/svdoole2.hxx> #include <svx/sdr/contact/objectcontact.hxx> +#include <svx/svdview.hxx> #include <drawinglayer/primitive2d/chartprimitive2d.hxx> #include <drawinglayer/attribute/fillattribute.hxx> #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> +#include <com/sun/star/embed/EmbedMisc.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
////////////////////////////////////////////////////////////////////////////// @@ -57,136 +60,173 @@ namespace sdr return static_cast< ViewContactOfSdrOle2Obj& >(GetViewContact()).GetOle2Obj(); } - drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfSdrOle2Obj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfSdrOle2Obj::createPrimitive2DSequence( + const DisplayInfo& /*rDisplayInfo*/) const { // this method is overloaded to do some things the old SdrOle2Obj::DoPaintObject did. // In the future, some of these may be solved different, but ATM try to stay compatible // with the old behaviour drawinglayer::primitive2d::Primitive2DSequence xRetval; const SdrOle2Obj& rSdrOle2 = getSdrOle2Object(); - const bool bIsActive(rSdrOle2.executeOldDoPaintPreparations(GetObjectContact().TryToGetSdrPageView())); - const Rectangle& rObjectRectangle(rSdrOle2.GetGeoRect()); - const basegfx::B2DRange aObjectRange(rObjectRectangle.Left(), rObjectRectangle.Top(), rObjectRectangle.Right(), rObjectRectangle.Bottom()); - - // create object transform - basegfx::B2DHomMatrix aObjectTransform; - aObjectTransform.set(0, 0, aObjectRange.getWidth()); - aObjectTransform.set(1, 1, aObjectRange.getHeight()); - aObjectTransform.set(0, 2, aObjectRange.getMinX()); - aObjectTransform.set(1, 2, aObjectRange.getMinY()); - - if(GetObjectContact().isDrawModeHighContrast()) - { - // directly call at the corresponding VC and force OLE Graphic to HighContrast - const ViewContactOfSdrOle2Obj& rVC = static_cast< const ViewContactOfSdrOle2Obj& >(GetViewContact()); - Graphic* pOLEHighContrastGraphic = rSdrOle2.getEmbeddedObjectRef().GetHCGraphic(); + sal_Int32 nState(-1); - if(pOLEHighContrastGraphic) - { - // there is a graphic set, use it - xRetval = rVC.createPrimitive2DSequenceWithGivenGraphic(*pOLEHighContrastGraphic, rSdrOle2.IsEmptyPresObj()); - } - else - { - // no HighContrast graphic, use default empty OLE bitmap - const Bitmap aEmptyOLEBitmap(rSdrOle2.GetEmtyOLEReplacementBitmap()); - const Graphic aEmtyOLEGraphic(aEmptyOLEBitmap); - - xRetval = rVC.createPrimitive2DSequenceWithGivenGraphic(aEmtyOLEGraphic, true); - } - } - else { - // call parent which will use the regular createViewIndependentPrimitive2DSequence - // at the corresponding VC - xRetval = ViewObjectContactOfSdrObj::createPrimitive2DSequence(rDisplayInfo); + const svt::EmbeddedObjectRef& xObjRef = rSdrOle2.getEmbeddedObjectRef(); + if ( xObjRef.is() ) + nState = xObjRef->getCurrentState(); } - if(rSdrOle2.getEmbeddedObjectRef().IsChart()) + const bool bIsOutplaceActive(nState == embed::EmbedStates::ACTIVE); + const bool bIsInplaceActive((nState == embed::EmbedStates::INPLACE_ACTIVE) || (nState == embed::EmbedStates::UI_ACTIVE)); + const bool bIsChart(rSdrOle2.IsChart()); + bool bDone(false); + + if(!bDone && bIsInplaceActive) { - // for chart, to not lose the current better quality visualisation which - // uses a direct paint, use a primtive wrapper for that exceptional case. The renderers - // will then ATM paint it to an OutputDevice directly. - // In later versions this should be replaced by getting the Primitive2DSequnce from - // the chart and using it. - // to be able to render something in non-VCL using renderers, the wrapper is a - // GroupPrimitive2D which automatically decomposes to the already created Metafile - // content. - // For being completely compatible, ATM Window and VDEV PrettyPrinting is suppressed. - // It works in the VCL renderers, though. So for activating again with VCL primitive - // renderers, change conditions here. - - // determine if embedding and PrettyPrinting shall be done at all - uno::Reference< frame::XModel > xChartModel; - bool bDoChartPrettyPrinting(true); - static bool bPrettyPrintingForBitmaps(false); - - // the original ChartPrettyPainter does not do it for Window - if(!bPrettyPrintingForBitmaps && bDoChartPrettyPrinting && GetObjectContact().isOutputToWindow()) + if( !GetObjectContact().isOutputToPrinter() && !GetObjectContact().isOutputToRecordingMetaFile() ) { - bDoChartPrettyPrinting = false; + //no need to create a primitive sequence here as the OLE object does render itself + //in case of charts the superfluous creation of a metafile is strongly performance relevant! + bDone = true; } + } + + if( !bDone ) + { + const Rectangle& rObjectRectangle(rSdrOle2.GetGeoRect()); + const basegfx::B2DRange aObjectRange(rObjectRectangle.Left(), rObjectRectangle.Top(), rObjectRectangle.Right(), rObjectRectangle.Bottom()); - // the original ChartPrettyPainter does not do it for VDEV - if(!bPrettyPrintingForBitmaps && bDoChartPrettyPrinting && GetObjectContact().isOutputToVirtualDevice()) + // create object transform + basegfx::B2DHomMatrix aObjectTransform; + aObjectTransform.set(0, 0, aObjectRange.getWidth()); + aObjectTransform.set(1, 1, aObjectRange.getHeight()); + aObjectTransform.set(0, 2, aObjectRange.getMinX()); + aObjectTransform.set(1, 2, aObjectRange.getMinY()); + + if(bIsChart) { - if(GetObjectContact().isOutputToPDFFile()) + //charts must be painted resolution dependent!! #i82893#, #i75867# + + // for chart, to not lose the current better quality visualisation which + // uses a direct paint, use a primtive wrapper for that exceptional case. The renderers + // will then ATM paint it to an OutputDevice directly. + // In later versions this should be replaced by getting the Primitive2DSequnce from + // the chart and using it. + // to be able to render something in non-VCL using renderers, the wrapper is a + // GroupPrimitive2D which automatically decomposes to the already created Metafile + // content. + // For being completely compatible, ATM Window and VDEV PrettyPrinting is suppressed. + // It works in the VCL renderers, though. So for activating again with VCL primitive + // renderers, change conditions here. + + // determine if embedding and PrettyPrinting shall be done at all + uno::Reference< frame::XModel > xChartModel; + bool bDoChartPrettyPrinting(true); + + // the original ChartPrettyPainter does not do it for Window + if(bDoChartPrettyPrinting && GetObjectContact().isOutputToWindow()) { - // #i97982# - // For PDF files, allow PrettyPrinting + bDoChartPrettyPrinting = false; } - else + + // the original ChartPrettyPainter does not do it for VDEV + if(bDoChartPrettyPrinting && GetObjectContact().isOutputToVirtualDevice()) { - bDoChartPrettyPrinting = false; + if(GetObjectContact().isOutputToPDFFile()) + { + // #i97982# + // For PDF files, allow PrettyPrinting + } + else + { + bDoChartPrettyPrinting = false; + } } - } - // the chart model is needed. Check if it's available - if(bDoChartPrettyPrinting) - { - // get chart model - xChartModel = rSdrOle2.getXModel(); + // the chart model is needed. Check if it's available + if(bDoChartPrettyPrinting) + { + // get chart model + xChartModel = rSdrOle2.getXModel(); - if(!xChartModel.is()) + if(!xChartModel.is()) + { + bDoChartPrettyPrinting = false; + } + } + + if(bDoChartPrettyPrinting) { - bDoChartPrettyPrinting = false; + // embed MetaFile data in a specialized Wrapper Primitive which holds also the ChartModel needed + // for PrettyPrinting + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::ChartPrimitive2D( + xChartModel, aObjectTransform, xRetval)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + bDone = true; } } - if(bDoChartPrettyPrinting) + if( !bDone ) { - // embed MetaFile data in a specialized Wrapper Primitive which holds also the ChartModel needed - // for PrettyPrinting - const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::ChartPrimitive2D( - xChartModel, aObjectTransform, xRetval)); - xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + //old stuff that should be reworked + { + //if no replacement image is available load the OLE object + if(!rSdrOle2.GetGraphic()) //try to fetch the metafile - this can lead to the actual creation of the metafile what can be extremely expensive (e.g. for big charts)!!! #i101925# + { + // try to create embedded object + rSdrOle2.GetObjRef(); //this loads the OLE object if it is not loaded already + } + const svt::EmbeddedObjectRef& xObjRef = rSdrOle2.getEmbeddedObjectRef(); + if(xObjRef.is()) + { + const sal_Int64 nMiscStatus(xObjRef->getStatus(rSdrOle2.GetAspect())); + + // this hack (to change model data during PAINT argh(!)) should be reworked + if(!rSdrOle2.IsResizeProtect() && (nMiscStatus & embed::EmbedMisc::EMBED_NEVERRESIZE)) + { + const_cast< SdrOle2Obj* >(&rSdrOle2)->SetResizeProtect(true); + } + + SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView(); + if(pPageView && (nMiscStatus & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE)) + { + // connect plugin object + pPageView->GetView().DoConnect(const_cast< SdrOle2Obj* >(&rSdrOle2)); + } + } + }//end old stuff to rework + + // create OLE primitive stuff directly at VC with HC as parameter + const ViewContactOfSdrOle2Obj& rVC = static_cast< const ViewContactOfSdrOle2Obj& >(GetViewContact()); + xRetval = rVC.createPrimitive2DSequenceWithParameters(GetObjectContact().isDrawModeHighContrast()); } - } - if(bIsActive) - { - // do not shade when printing or PDF exporting - if(!GetObjectContact().isOutputToPrinter() && !GetObjectContact().isOutputToRecordingMetaFile()) + if(bIsOutplaceActive) { - // shade the representation if the object is activated outplace - basegfx::B2DPolygon aObjectOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0))); - aObjectOutline.transform(aObjectTransform); - - // Use a FillHatchPrimitive2D with necessary attributes - const drawinglayer::attribute::FillHatchAttribute aFillHatch( - drawinglayer::attribute::HATCHSTYLE_SINGLE, // single hatch - 125.0, // 1.25 mm - 45.0 * F_PI180, // 45 degree diagonal - Color(COL_BLACK).getBColor(), // black color - false); // no filling - - const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolyPolygonHatchPrimitive2D( - basegfx::B2DPolyPolygon(aObjectOutline), - Color(COL_BLACK).getBColor(), - aFillHatch)); - - drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReference); + // do not shade when printing or PDF exporting + if(!GetObjectContact().isOutputToPrinter() && !GetObjectContact().isOutputToRecordingMetaFile()) + { + // shade the representation if the object is activated outplace + basegfx::B2DPolygon aObjectOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0))); + aObjectOutline.transform(aObjectTransform); + + // Use a FillHatchPrimitive2D with necessary attributes + const drawinglayer::attribute::FillHatchAttribute aFillHatch( + drawinglayer::attribute::HATCHSTYLE_SINGLE, // single hatch + 125.0, // 1.25 mm + 45.0 * F_PI180, // 45 degree diagonal + Color(COL_BLACK).getBColor(), // black color + false); // no filling + + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolyPolygonHatchPrimitive2D( + basegfx::B2DPolyPolygon(aObjectOutline), + Color(COL_BLACK).getBColor(), + aFillHatch)); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReference); + } } + } return xRetval; diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx index ea260f3285f7..92003865fde0 100644 --- a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx @@ -35,6 +35,7 @@ #include <svx/sdr/contact/displayinfo.hxx> #include <svx/sdr/properties/properties.hxx> #include <svx/sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> /** === begin UNO includes === **/ #include <com/sun/star/lang/XMultiServiceFactory.hpp> @@ -80,6 +81,7 @@ namespace sdr { namespace contact { using ::com::sun::star::uno::XInterface; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::RuntimeException; using ::com::sun::star::awt::XControl; @@ -175,7 +177,11 @@ namespace sdr { namespace contact { inline void addWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->addWindowListener( _l ); } inline void removeWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->removeWindowListener( _l ); } void setPosSize( const Rectangle& _rPosSize ) const; - void setZoom( const MapMode& _rMapMode ) const; + Rectangle + getPosSize() const; + void setZoom( const ::basegfx::B2DVector& _rScale ) const; + ::basegfx::B2DVector + getZoom() const; inline void setGraphics( const Reference< XGraphics >& _g ) const { m_xControlView->setGraphics( _g ); } inline Reference< XGraphics > @@ -221,10 +227,36 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - void ControlHolder::setZoom( const MapMode& _rMapMode ) const + ::Rectangle ControlHolder::getPosSize() const { // no check whether we're valid, this is the responsibility of the caller - m_xControlView->setZoom( (float)double( _rMapMode.GetScaleX() ), (float)double( _rMapMode.GetScaleY() ) ); + return VCLUnoHelper::ConvertToVCLRect( m_xControlWindow->getPosSize() ); + } + + //-------------------------------------------------------------------- + void ControlHolder::setZoom( const ::basegfx::B2DVector& _rScale ) const + { + // no check whether we're valid, this is the responsibility of the caller + m_xControlView->setZoom( (float)_rScale.getX(), (float)_rScale.getY() ); + } + + //-------------------------------------------------------------------- + ::basegfx::B2DVector ControlHolder::getZoom() const + { + // no check whether we're valid, this is the responsibility of the caller + + // Argh. Why does XView have a setZoom only, but not a getZoom? + Window* pWindow = VCLUnoHelper::GetWindow( m_xControlWindow ); + OSL_ENSURE( pWindow, "ControlHolder::setZoom: no implementation access!" ); + + ::basegfx::B2DVector aZoom( 1, 1 ); + if ( pWindow ) + { + const Fraction& rZoom( pWindow->GetZoom() ); + aZoom.setX( (double)rZoom ); + aZoom.setY( (double)rZoom ); + } + return aZoom; } //==================================================================== @@ -233,37 +265,13 @@ namespace sdr { namespace contact { class UnoControlContactHelper { public: - /** positions a control relative to a device - - @precond <arg>_pDevice</arg> is not <NULL/> + /** positions a control, and sets its zoom mode, using a given transformation and output device */ - static void positionControl_throw( + static void adjustControlGeometry_throw( const ControlHolder& _rControl, const Rectangle& _rLogicBoundingRect, - const OutputDevice* _pDevice - ); - - /** sets the zoom at a UNO control, according to a Device's MapMode - - @precond <arg>_pDevice</arg> is not <NULL/> - */ - static void setControlZoom( - const ControlHolder& _rControl, - const OutputDevice* _pDevice - ); - - /** draws a given control onto it's current XGraphics, at given coordinates - - Note that the control is not drawn onto the given device, instead you must - use ->XView::setGraphics yourself, before calling this method. The given ->OutputDevice - is only used to calculate pixel coordinates from logic coordinates - - @precond <arg>_pDevice</arg> is not <NULL/> - */ - static void drawControl( - const ControlHolder& _rControl, - const Point& _rLogicTopLeft, - const OutputDevice* _pDevice + const ::basegfx::B2DHomMatrix& _rViewTransformation, + const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization ); /** disposes the given control @@ -279,50 +287,28 @@ namespace sdr { namespace contact { }; //-------------------------------------------------------------------- - void UnoControlContactHelper::positionControl_throw( const ControlHolder& _rControl, const Rectangle& _rLogicBoundingRect, - const OutputDevice* _pDevice ) + void UnoControlContactHelper::adjustControlGeometry_throw( const ControlHolder& _rControl, const Rectangle& _rLogicBoundingRect, + const basegfx::B2DHomMatrix& _rViewTransformation, const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization ) { - OSL_PRECOND( _pDevice, "UnoControlContactHelper::positionControl_throw: no device -> no survival!" ); - - if ( _rControl.is() ) - { - const Rectangle aPaintRectPixel( - _pDevice->LogicToPixel( _rLogicBoundingRect.TopLeft() ), - _pDevice->LogicToPixel( _rLogicBoundingRect.GetSize() ) - ); - - _rControl.setPosSize( aPaintRectPixel ); - } - } - - //-------------------------------------------------------------------- - void UnoControlContactHelper::setControlZoom( const ControlHolder& _rControl, const OutputDevice* _pDevice ) - { - OSL_PRECOND( _pDevice, "UnoControlContactHelper::setControlZoom: no device -> no survival!" ); - OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::setControlZoom: illegal control!" ); - - if ( _rControl.is() ) - _rControl.setZoom( _pDevice->GetMapMode() ); - } - - //-------------------------------------------------------------------- - void UnoControlContactHelper::drawControl( const ControlHolder& _rControl, const Point& _rLogicTopLeft, - const OutputDevice* _pDevice ) - { - OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::drawControl: invalid control!" ); + OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::adjustControlGeometry_throw: illegal control!" ); if ( !_rControl.is() ) return; - try - { - _rControl.draw( - _pDevice->LogicToPixel( _rLogicTopLeft ) - ); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION(); - } + // transform the logic bound rect, using the view transformation, to pixel coordinates + ::basegfx::B2DPoint aTopLeft( _rLogicBoundingRect.Left(), _rLogicBoundingRect.Top() ); + aTopLeft *= _rViewTransformation; + ::basegfx::B2DPoint aBottomRight( _rLogicBoundingRect.Right(), _rLogicBoundingRect.Bottom() ); + aBottomRight *= _rViewTransformation; + + const Rectangle aPaintRectPixel( (long)aTopLeft.getX(), (long)aTopLeft.getY(), (long)aBottomRight.getX(), (long)aBottomRight.getY() ); + _rControl.setPosSize( aPaintRectPixel ); + + // determine the scale from the current view transformation, and the normalization matrix + ::basegfx::B2DHomMatrix aObtainResolutionDependentScale( _rViewTransformation * _rZoomLevelNormalization ); + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + aObtainResolutionDependentScale.decompose( aScale, aTranslate, fRotate, fShearX ); + _rControl.setZoom( aScale ); } //-------------------------------------------------------------------- @@ -402,40 +388,7 @@ namespace sdr { namespace contact { } //==================================================================== - //= DummyPageViewAccess - //==================================================================== - /** is a ->IPageViewAccess implementation which defaults all attribute access, and thus can be - operated without an actual ->SdrPageView - */ - class DummyPageViewAccess : public IPageViewAccess - { - public: - virtual bool isDesignMode() const; - virtual Reference< XControlContainer > - getControlContainer( const OutputDevice& _rDevice ) const; - virtual bool isLayerVisible( SdrLayerID _nLayerID ) const; - }; - - //-------------------------------------------------------------------- - bool DummyPageViewAccess::isDesignMode() const - { - return true; - } - - //-------------------------------------------------------------------- - Reference< XControlContainer > DummyPageViewAccess::getControlContainer( const OutputDevice& /*_rDevice*/ ) const - { - return Reference< XControlContainer >(); - } - - //-------------------------------------------------------------------- - bool DummyPageViewAccess::isLayerVisible( SdrLayerID /*_nLayerID*/ ) const - { - return true; - } - - //==================================================================== - //= DummyPageViewAccess + //= InvisibleControlViewAccess //==================================================================== /** is a ->IPageViewAccess implementation which can be used to create an invisble control for an arbitrary device @@ -510,7 +463,7 @@ namespace sdr { namespace contact { Reference< XContainer > m_xContainer; /// the output device for which the control was created - OutputDevice const* m_pOutputDeviceForWindow; + const OutputDevice* m_pOutputDeviceForWindow; /// flag indicating whether the control is currently visible bool m_bControlIsVisible; @@ -527,6 +480,8 @@ namespace sdr { namespace contact { /// is the control currently in design mode? mutable ViewControlMode m_eControlDesignMode; + ::basegfx::B2DHomMatrix m_aZoomLevelNormalization; + public: ViewObjectContactOfUnoControl_Impl( ViewObjectContactOfUnoControl* _pAntiImpl ); @@ -549,17 +504,13 @@ namespace sdr { namespace contact { */ bool getUnoObject( SdrUnoObj*& _out_rpObject ) const; - /** ensures that we have an XControl which can be painted onto the given display - */ - bool ensureControl( const DisplayInfo& _rDisplayInfo ); - /** ensures that we have an ->XControl Must only be called if a control is needed when no DisplayInfo is present, yet. - For creating a control, an ->OutputDevice is needed, and an ->SdrPageView. Both can only be - obtained from a ->DisplayInfo struct, or alternatively a ->ObjectContactOfPageView. So, if - our (anti-impl's) object contact is not a ->ObjectContactOfPageView, this method fill fail. + For creating a control, an ->OutputDevice is needed, and an ->SdrPageView. Both will be obtained + from a ->ObjectContactOfPageView. So, if our (anti-impl's) object contact is not a ->ObjectContactOfPageView, + this method fill fail. Failure of this method will be reported via an assertion in a non-product version. */ @@ -572,22 +523,16 @@ namespace sdr { namespace contact { inline const ControlHolder& getExistentControl() const { return m_aControl; } - /** positions our XControl according to the geometry settings in the SdrUnoObj, - and sets proper zoom settings according to our device + inline bool + hasControl() const { return m_aControl.is(); } + + /** positions our XControl according to the geometry settings in the SdrUnoObj, modified by the given + transformation, and sets proper zoom settings according to our device @precond ->m_pOutputDeviceForWindow and ->m_aControl are not <NULL/> - @tolerant - If the preconditions are not met, nothing is done at all */ - void positionAndZoomControl() const; - - /** positions the control for a paint onto a given device - - If we do not (yet) have a control, or the control does not belong to the - device for which a paint is requested, no positioning happens. - */ - void positionControlForPaint( const DisplayInfo& _rDisplayInfo ) const; + void positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const; /** determines whether or not our control is printable @@ -626,6 +571,13 @@ namespace sdr { namespace contact { struct GuardAccess { friend class VOCGuard; private: GuardAccess() { } }; ::osl::Mutex& getMutex( GuardAccess ) const { return m_aMutex; } + const ViewContactOfUnoControl& + getViewContact() const + { + ENSURE_OR_THROW( !impl_isDisposed_nofail(), "already disposed" ); + return static_cast< const ViewContactOfUnoControl& >( m_pAntiImpl->GetViewContact() ); + } + protected: ~ViewObjectContactOfUnoControl_Impl(); @@ -797,10 +749,11 @@ namespace sdr { namespace contact { This method cares for this, by retrieving the very original OutputDevice. */ - const OutputDevice& imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ) const; + static const OutputDevice& imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ); + const OutputDevice& imp_getPageViewDevice_nothrow() const; private: - ViewObjectContactOfUnoControl_Impl(); // never implemented + ViewObjectContactOfUnoControl_Impl(); // never implemented ViewObjectContactOfUnoControl_Impl( const ViewObjectContactOfUnoControl_Impl& ); // never implemented ViewObjectContactOfUnoControl_Impl& operator=( const ViewObjectContactOfUnoControl_Impl& ); // never implemented }; @@ -812,18 +765,65 @@ namespace sdr { namespace contact { */ class VOCGuard { - const ViewObjectContactOfUnoControl_Impl& m_rImpl; - ::osl::MutexGuard m_aMutexGuard; + private: + ::osl::MutexGuard m_aMutexGuard; public: VOCGuard( const ViewObjectContactOfUnoControl_Impl& _rImpl ) - :m_rImpl( _rImpl ) - ,m_aMutexGuard( _rImpl.getMutex( ViewObjectContactOfUnoControl_Impl::GuardAccess() ) ) + :m_aMutexGuard( _rImpl.getMutex( ViewObjectContactOfUnoControl_Impl::GuardAccess() ) ) { } }; //==================================================================== + //= LazyControlCreationPrimitive2D + //==================================================================== + class LazyControlCreationPrimitive2D : public ::drawinglayer::primitive2d::BasePrimitive2D + { + private: + typedef ::drawinglayer::primitive2d::BasePrimitive2D BasePrimitive2D; + + protected: + virtual ::drawinglayer::primitive2d::Primitive2DSequence + get2DDecomposition( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + virtual ::drawinglayer::primitive2d::Primitive2DSequence + createLocalDecomposition( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + virtual ::basegfx::B2DRange + getB2DRange( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + public: + LazyControlCreationPrimitive2D( const ::rtl::Reference< ViewObjectContactOfUnoControl_Impl >& _pVOCImpl ) + :m_pVOCImpl( _pVOCImpl ) + { + ENSURE_OR_THROW( m_pVOCImpl.is(), "Illegal argument." ); + getTransformation( m_pVOCImpl->getViewContact(), m_aTransformation ); + } + + virtual bool operator==(const BasePrimitive2D& rPrimitive) const; + + // declare unique ID for this primitive class + DeclPrimitrive2DIDBlock() + + static void getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation ); + + private: + ::rtl::Reference< ViewObjectContactOfUnoControl_Impl > m_pVOCImpl; + /** The geometry is part of the identity of an primitive, so we cannot calculate it on demand + (since the data the calculation is based on might have changed then), but need to calc + it at construction time, and remember it. + */ + ::basegfx::B2DHomMatrix m_aTransformation; + }; + + //==================================================================== //= ViewObjectContactOfUnoControl_Impl //==================================================================== DBG_NAME( ViewObjectContactOfUnoControl_Impl ) @@ -834,10 +834,20 @@ namespace sdr { namespace contact { ,m_bControlIsVisible( false ) ,m_bIsDesignModeListening( false ) ,m_eControlDesignMode( eUnknown ) + ,m_aZoomLevelNormalization() { DBG_CTOR( ViewObjectContactOfUnoControl_Impl, NULL ); DBG_ASSERT( m_pAntiImpl, "ViewObjectContactOfUnoControl_Impl::ViewObjectContactOfUnoControl_Impl: invalid AntiImpl!" ); - } + + const OutputDevice& rPageViewDevice( imp_getPageViewDevice_nothrow() ); + m_aZoomLevelNormalization = rPageViewDevice.GetInverseViewTransformation(); + + ::basegfx::B2DHomMatrix aScaleNormalization; + MapMode aCurrentDeviceMapMode( rPageViewDevice.GetMapMode() ); + aScaleNormalization.set( 0, 0, (double)aCurrentDeviceMapMode.GetScaleX() ); + aScaleNormalization.set( 1, 1, (double)aCurrentDeviceMapMode.GetScaleY() ); + m_aZoomLevelNormalization *= aScaleNormalization; + } //-------------------------------------------------------------------- ViewObjectContactOfUnoControl_Impl::~ViewObjectContactOfUnoControl_Impl() @@ -898,27 +908,21 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - void ViewObjectContactOfUnoControl_Impl::positionControlForPaint( const DisplayInfo& /* #i74769# _rDisplayInfo*/ ) const - { - if ( !m_aControl.is() ) - return; - - positionAndZoomControl(); - } - - //-------------------------------------------------------------------- - void ViewObjectContactOfUnoControl_Impl::positionAndZoomControl() const + void ViewObjectContactOfUnoControl_Impl::positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const { - OSL_PRECOND( m_pOutputDeviceForWindow && m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no output device or no control!" ); - if ( !m_pOutputDeviceForWindow || !m_aControl.is() ) + OSL_PRECOND( ( m_pOutputDeviceForWindow != NULL ) && m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no output device or no control!" ); + if ( ( m_pOutputDeviceForWindow == NULL ) || !m_aControl.is() ) return; try { SdrUnoObj* pUnoObject( NULL ); if ( getUnoObject( pUnoObject ) ) - UnoControlContactHelper::positionControl_throw( m_aControl, pUnoObject->GetLogicRect(), m_pOutputDeviceForWindow ); - UnoControlContactHelper::setControlZoom( m_aControl, m_pOutputDeviceForWindow ); + { + UnoControlContactHelper::adjustControlGeometry_throw( m_aControl, pUnoObject->GetLogicRect(), _rViewTransformation, m_aZoomLevelNormalization ); + } + else + OSL_ENSURE( false, "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no SdrUnoObj!" ); } catch( const Exception& ) { @@ -927,37 +931,6 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - bool ViewObjectContactOfUnoControl_Impl::ensureControl( const DisplayInfo& /*_rDisplayInfo*/ ) - { - OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::ensureControl: already disposed()" ); - if ( impl_isDisposed_nofail() ) - return false; - - const OutputDevice* pDeviceForControl( NULL ); - - // if we're working for a page view, use the respective OutputDevice at the proper - // PaintWindow. The DisplayInfo might only contain a temporary (virtual) device, which - // is dangerous to remember - // 2006-10-24 / #i70604# / frank.schoenheit@sun.com - ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); - if ( pPageViewContact ) - pDeviceForControl = &imp_getPageViewDevice_nothrow( *pPageViewContact ); - - if ( !pDeviceForControl && pPageViewContact) - pDeviceForControl = pPageViewContact->TryToGetOutputDevice(); - - DBG_ASSERT( pDeviceForControl, "ViewObjectContactOfUnoControl_Impl::ensureControl: no output device!" ); - if ( !pDeviceForControl ) - return false; - - SdrPageView* pPageView = m_pAntiImpl->GetObjectContact().TryToGetSdrPageView(); - - ::std::auto_ptr< IPageViewAccess > pPVAccess; - pPVAccess.reset( pPageView ? (IPageViewAccess*)new SdrPageViewAccess( *pPageView ) : (IPageViewAccess*)new DummyPageViewAccess() ); - return impl_ensureControl_nothrow( *pPVAccess, *pDeviceForControl ); - } - - //-------------------------------------------------------------------- bool ViewObjectContactOfUnoControl_Impl::ensureControl() { OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::ensureControl: already disposed()" ); @@ -977,13 +950,21 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - const OutputDevice& ViewObjectContactOfUnoControl_Impl::imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ) const + const OutputDevice& ViewObjectContactOfUnoControl_Impl::imp_getPageViewDevice_nothrow() const + { + ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); + ENSURE_OR_THROW( pPageViewContact, "need a ObjectContactOfPageView." ); + return imp_getPageViewDevice_nothrow( *pPageViewContact ); + } + + //-------------------------------------------------------------------- + const OutputDevice& ViewObjectContactOfUnoControl_Impl::imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ) { // if the PageWindow has a patched PaintWindow, use the original PaintWindow // this ensures that our control is _not_ re-created just because somebody // (temporarily) changed the window to paint onto. // #i72429# / 2007-02-20 / frank.schoenheit@sun.com - const SdrPageWindow& rPageWindow( _rObjectContact.GetPageWindow() ); + SdrPageWindow& rPageWindow( _rObjectContact.GetPageWindow() ); if ( rPageWindow.GetOriginalPaintWindow() ) return rPageWindow.GetOriginalPaintWindow()->GetOutputDevice(); @@ -1001,7 +982,7 @@ namespace sdr { namespace contact { // Somebody requested a control for a new device, which means either of // - our PageView's paint window changed since we were last here // - we don't belong to a page view, and are simply painted onto different devices - // The first sounds strange (doens't it?), the second means we could perhaps + // The first sounds strange (doens't it?), the second means we could perhaps // optimize this in the future - there is no need to re-create the control every time, // is it? // #i74523# / 2007-02-15 / frank.schoenheit@sun.com @@ -1063,44 +1044,37 @@ namespace sdr { namespace contact { bool bSuccess = false; try { - do - { - const ::rtl::OUString sControlServiceName( _rUnoObject.GetUnoControlTypeName() ); + const ::rtl::OUString sControlServiceName( _rUnoObject.GetUnoControlTypeName() ); - Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); - if ( xFactory.is() ) - { - _out_rControl = Reference< XControl >( xFactory->createInstance( sControlServiceName ), UNO_QUERY ); - } - DBG_ASSERT( _out_rControl.is(), "ViewObjectContactOfUnoControl_Impl::createControlForDevice: no control could be created!" ); - if ( !_out_rControl.is() ) - break; + Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW ); + _out_rControl = Reference< XControl >( xFactory->createInstance( sControlServiceName ), UNO_QUERY_THROW ); - // knit the model and the control - _out_rControl.setModel( xControlModel ); + // knit the model and the control + _out_rControl.setModel( xControlModel ); - UnoControlContactHelper::positionControl_throw( _out_rControl, _rUnoObject.GetLogicRect(), &_rDevice ); - - // proper zoom - UnoControlContactHelper::setControlZoom( _out_rControl, &_rDevice ); + // proper geometry + UnoControlContactHelper::adjustControlGeometry_throw( + _out_rControl, + _rUnoObject.GetLogicRect(), + _rDevice.GetViewTransformation(), + _rDevice.GetInverseViewTransformation() + ); - // #107049# set design mode before peer is created, - // this is also needed for accessibility - _out_rControl.setDesignMode( _rPageView.isDesignMode() ); + // #107049# set design mode before peer is created, + // this is also needed for accessibility + _out_rControl.setDesignMode( _rPageView.isDesignMode() ); - // adjust the initial visibility according to the visibility of the layer - // 2003-06-03 - #110592# - fs@openoffice.org - impl_adjustControlVisibilityToLayerVisibility_throw( _out_rControl, _rUnoObject, _rPageView, false, true ); + // adjust the initial visibility according to the visibility of the layer + // 2003-06-03 - #110592# - fs@openoffice.org + impl_adjustControlVisibilityToLayerVisibility_throw( _out_rControl, _rUnoObject, _rPageView, false, true ); - // add the control to the respective control container - // #108327# do this last - Reference< XControlContainer > xControlContainer( _rPageView.getControlContainer( _rDevice ) ); - if ( xControlContainer.is() ) - xControlContainer->addControl( sControlServiceName, _out_rControl.getControl() ); + // add the control to the respective control container + // #108327# do this last + Reference< XControlContainer > xControlContainer( _rPageView.getControlContainer( _rDevice ) ); + if ( xControlContainer.is() ) + xControlContainer->addControl( sControlServiceName, _out_rControl.getControl() ); - bSuccess = true; - } - while ( false ); + bSuccess = true; } catch( const Exception& ) { @@ -1257,18 +1231,16 @@ namespace sdr { namespace contact { //-------------------------------------------------------------------- bool ViewObjectContactOfUnoControl_Impl::isPrintableControl() const { - if ( !m_aControl.is() ) + SdrUnoObj* pUnoObject( NULL ); + if ( !getUnoObject( pUnoObject ) ) return false; bool bIsPrintable = false; try { - Reference< XPropertySet > xModelProperties( m_aControl.getModel(), UNO_QUERY ); - Reference< XPropertySetInfo > xPropertyInfo( xModelProperties.is() ? xModelProperties->getPropertySetInfo() : Reference< XPropertySetInfo >() ); - const ::rtl::OUString sPrintablePropertyName( RTL_CONSTASCII_USTRINGPARAM( "Printable" ) ); - - if ( xPropertyInfo.is() && xPropertyInfo->hasPropertyByName( sPrintablePropertyName ) ) - OSL_VERIFY( xModelProperties->getPropertyValue( sPrintablePropertyName ) >>= bIsPrintable ); + Reference< XPropertySet > xModelProperties( pUnoObject->GetUnoControlModel(), UNO_QUERY_THROW ); + static const ::rtl::OUString s_sPrintablePropertyName( RTL_CONSTASCII_USTRINGPARAM( "Printable" ) ); + OSL_VERIFY( xModelProperties->getPropertyValue( s_sPrintablePropertyName ) >>= bIsPrintable ); } catch( const Exception& ) { @@ -1411,15 +1383,20 @@ namespace sdr { namespace contact { if ( !xNewControl.is() ) return; + ENSURE_OR_THROW( m_pOutputDeviceForWindow, "calling this without /me having an output device should be impossible." ); + DBG_ASSERT( xNewControl->getModel() == m_aControl.getModel(), "ViewObjectContactOfUnoControl_Impl::elementReplaced: another model at the new control?" ); // another model should - in the drawing layer - also imply another SdrUnoObj, which // should also result in new ViewContact, and thus in new ViewObjectContacts impl_switchControlListening_nothrow( false ); + ControlHolder aNewControl( xNewControl ); + aNewControl.setZoom( m_aControl.getZoom() ); + aNewControl.setPosSize( m_aControl.getPosSize() ); + aNewControl.setDesignMode( impl_isControlDesignMode_nothrow() ); + m_aControl = xNewControl; - positionAndZoomControl(); - m_aControl.setDesignMode( impl_isControlDesignMode_nothrow() ); m_bControlIsVisible = m_aControl.isVisible(); impl_switchControlListening_nothrow( true ); @@ -1449,30 +1426,96 @@ namespace sdr { namespace contact { } } + //==================================================================== + //= LazyControlCreationPrimitive2D + //==================================================================== //-------------------------------------------------------------------- - bool ViewObjectContactOfUnoControl_Impl::belongsToDevice( const OutputDevice* _pDevice ) const + bool LazyControlCreationPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - DBG_ASSERT( _pDevice, "ViewObjectContactOfUnoControl_Impl::belongsToDevice: invalid device!" ); + if ( !BasePrimitive2D::operator==( rPrimitive ) ) + return false; - OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::belongsToDevice: already disposed!" ); - if ( impl_isDisposed_nofail() ) + const LazyControlCreationPrimitive2D* pRHS = dynamic_cast< const LazyControlCreationPrimitive2D* >( &rPrimitive ); + if ( !pRHS ) return false; - if ( m_pOutputDeviceForWindow ) - { - if ( _pDevice == m_pOutputDeviceForWindow ) - return true; + if ( m_pVOCImpl != pRHS->m_pVOCImpl ) return false; - } - ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); - if ( pPageViewContact ) - return ( _pDevice == &imp_getPageViewDevice_nothrow( *pPageViewContact ) ); + if ( m_aTransformation != pRHS->m_aTransformation ) + return false; - DBG_ERROR( "ViewObjectContactOfUnoControl_Impl::belongsToDevice: could not determine the device I belong to!" ); - return false; + return true; + } + + //-------------------------------------------------------------------- + void LazyControlCreationPrimitive2D::getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation ) + { + // Do use model data directly to create the correct geometry. Do NOT + // use getBoundRect()/getSnapRect() here; tese will use the sequence of + // primitives themselves in the long run. + const Rectangle aSdrGeoData( _rVOC.GetSdrUnoObj().GetGeoRect() ); + const basegfx::B2DRange aRange( + aSdrGeoData.Left(), + aSdrGeoData.Top(), + aSdrGeoData.Right(), + aSdrGeoData.Bottom() + ); + + _out_Transformation.identity(); + _out_Transformation.set( 0, 0, aRange.getWidth() ); + _out_Transformation.set( 1, 1, aRange.getHeight() ); + _out_Transformation.set( 0, 2, aRange.getMinX() ); + _out_Transformation.set( 1, 2, aRange.getMinY() ); } + //-------------------------------------------------------------------- + ::basegfx::B2DRange LazyControlCreationPrimitive2D::getB2DRange( const ::drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/ ) const + { + ::basegfx::B2DRange aRange( 0.0, 0.0, 1.0, 1.0 ); + aRange.transform( m_aTransformation ); + return aRange; + } + + //-------------------------------------------------------------------- + ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::get2DDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const + { + if ( m_pVOCImpl->hasControl() ) + m_pVOCImpl->positionAndZoomControl( _rViewInformation.getObjectToViewTransformation() ); + return BasePrimitive2D::get2DDecomposition( _rViewInformation ); + } + + //-------------------------------------------------------------------- + ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::createLocalDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const + { + // force control here to make it a VCL ChildWindow. Will be fetched + // and used below by getExistentControl() + m_pVOCImpl->ensureControl(); + m_pVOCImpl->positionAndZoomControl( _rViewInformation.getObjectToViewTransformation() ); + + // get needed data + const ViewContactOfUnoControl& rViewContactOfUnoControl( m_pVOCImpl->getViewContact() ); + Reference< XControlModel > xControlModel( rViewContactOfUnoControl.GetSdrUnoObj().GetUnoControlModel() ); + const ControlHolder& rControl( m_pVOCImpl->getExistentControl() ); + + // check if we already have an XControl. + if ( !xControlModel.is() || !rControl.is() ) + // use the default mechanism. This will create a ControlPrimitive2D without + // handing over a XControl. If not even a XControlModel exists, it will + // create the SdrObject fallback visualisation + return rViewContactOfUnoControl.getViewIndependentPrimitive2DSequence(); + + // create a primitive and hand over the existing xControl. This will + // allow the primitive to not need to create another one on demand. + const drawinglayer::primitive2d::Primitive2DReference xRetval( new ::drawinglayer::primitive2d::ControlPrimitive2D( + m_aTransformation, xControlModel, rControl.getControl() ) ); + + return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); + } + + //-------------------------------------------------------------------- + ImplPrimitrive2DIDBlock( LazyControlCreationPrimitive2D, PRIMITIVE2D_ID_SDRCONTROLPRIMITIVE2D ) + //==================================================================== //= ViewObjectContactOfUnoControl //==================================================================== @@ -1522,20 +1565,6 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - void ViewObjectContactOfUnoControl::positionControlForPaint( const DisplayInfo& _rDisplayInfo ) const - { - VOCGuard aGuard( *m_pImpl ); - - // ensure we have a control. If we don't, then the Drawing Layer might be tempted to - // never draw the complete form layer. - // #i75095# / 2007-03-05 / frank.schoenheit@sun.com - m_pImpl->ensureControl( _rDisplayInfo ); - - // position the control - m_pImpl->positionControlForPaint( _rDisplayInfo ); - } - - //-------------------------------------------------------------------- void ViewObjectContactOfUnoControl::ensureControlVisibility( bool _bVisible ) const { VOCGuard aGuard( *m_pImpl ); @@ -1582,70 +1611,32 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - bool ViewObjectContactOfUnoControl::belongsToDevice( const OutputDevice* _pDevice ) const + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfUnoControl::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const { - VOCGuard aGuard( *m_pImpl ); - return m_pImpl->belongsToDevice( _pDevice ); + if ( m_pImpl->isDisposed() ) + // our control already died. + // TODO: Is it worth re-creating the control? Finally, this is a pathological situation, it means some instance + // disposed the control though it doesn't own it. So, /me thinks we should not bother here. + return drawinglayer::primitive2d::Primitive2DSequence();
+
+ ::drawinglayer::primitive2d::Primitive2DReference xPrimitive( new LazyControlCreationPrimitive2D( m_pImpl ) ); + return ::drawinglayer::primitive2d::Primitive2DSequence( &xPrimitive, 1 ); } //-------------------------------------------------------------------- - drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfUnoControl::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const - { - // force control here to make it a VCL ChildWindow. Will be fetched - // and used below by getExistentControl() - m_pImpl->ensureControl(); - m_pImpl->positionControlForPaint(rDisplayInfo); - - // get needed data - const ViewContactOfUnoControl& rViewContactOfUnoControl(static_cast< const ViewContactOfUnoControl& >(GetViewContact())); - Reference< XControlModel > xControlModel(rViewContactOfUnoControl.GetSdrUnoObj().GetUnoControlModel()); - const ControlHolder& rControl(m_pImpl->getExistentControl()); - - // check if we already have a XControl. - if(xControlModel.is() && rControl.is()) - { - // create a primitive and hand over the existing xControl. This will - // allow the primitive to not need to create another one on demand. - // Do use model data directly to create the correct geometry. Do NOT - // use getBoundRect()/getSnapRect() here; tese will use the sequence of - // primitives themselves in the long run. - const Rectangle aUnoControlModelData(rViewContactOfUnoControl.GetSdrUnoObj().GetGeoRect()); - const basegfx::B2DRange aRange(aUnoControlModelData.Left(), aUnoControlModelData.Top(), aUnoControlModelData.Right(), aUnoControlModelData.Bottom()); - - // create object transform - basegfx::B2DHomMatrix aTransform; - aTransform.set(0, 0, aRange.getWidth()); - aTransform.set(1, 1, aRange.getHeight()); - aTransform.set(0, 2, aRange.getMinX()); - aTransform.set(1, 2, aRange.getMinY()); - - // create control primitive with existing XControl - const drawinglayer::primitive2d::Primitive2DReference xRetval(new drawinglayer::primitive2d::ControlPrimitive2D( - aTransform, xControlModel, rControl.getControl())); - - return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); - } - else - { - // use the default mechanism. This will create a ControlPrimitive2D without - // handing over a XControl. If not even a XControlModel exists, it will - // create the SdrObject fallback visualisation - return rViewContactOfUnoControl.getViewIndependentPrimitive2DSequence(); - } - } - void ViewObjectContactOfUnoControl::propertyChange() { // graphical invalidate at all views ActionChanged(); // #i93318# flush Primitive2DSequence to force recreation with updated XControlModel - // since e.g. background color has changed and existing decompositions are evtl. no + // since e.g. background color has changed and existing decompositions are possibly no // longer valid. Unfortunately this is not detected from ControlPrimitive2D::operator== // since it only has a uno reference to the XControlModel flushPrimitive2DSequence(); } + //-------------------------------------------------------------------- void ViewObjectContactOfUnoControl::ActionChanged() { // call parent @@ -1721,6 +1712,14 @@ namespace sdr { namespace contact { DBG_DTOR( UnoControlPrintOrPreviewContact, NULL ); } + //-------------------------------------------------------------------- + drawinglayer::primitive2d::Primitive2DSequence UnoControlPrintOrPreviewContact::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo ) const + { + if ( !m_pImpl->isPrintableControl() ) + return drawinglayer::primitive2d::Primitive2DSequence(); + return ViewObjectContactOfUnoControl::createPrimitive2DSequence( rDisplayInfo ); + } + //==================================================================== //= UnoControlPDFExportContact //==================================================================== diff --git a/svx/source/sdr/overlay/makefile.mk b/svx/source/sdr/overlay/makefile.mk index 1243a71e2585..d202992c090d 100644 --- a/svx/source/sdr/overlay/makefile.mk +++ b/svx/source/sdr/overlay/makefile.mk @@ -43,22 +43,21 @@ ENABLE_EXCEPTIONS=TRUE SLOFILES=\ $(SLO)$/overlayanimatedbitmapex.obj \ - $(SLO)$/overlaybitmap.obj \ $(SLO)$/overlaybitmapex.obj \ + $(SLO)$/overlaycrosshair.obj \ + $(SLO)$/overlayhatchrect.obj \ + $(SLO)$/overlayhelpline.obj \ $(SLO)$/overlayline.obj \ - $(SLO)$/overlaylinestriped.obj \ $(SLO)$/overlaymanager.obj \ $(SLO)$/overlaymanagerbuffered.obj \ $(SLO)$/overlayobject.obj \ + $(SLO)$/overlayobjectcell.obj \ $(SLO)$/overlayobjectlist.obj \ - $(SLO)$/overlaytriangle.obj \ - $(SLO)$/overlaycrosshair.obj \ - $(SLO)$/overlayhelpline.obj \ - $(SLO)$/overlayhatchrect.obj \ - $(SLO)$/overlayrollingrectangle.obj \ $(SLO)$/overlaypolypolygon.obj \ - $(SLO)$/overlaysdrobject.obj \ $(SLO)$/overlayprimitive2dsequenceobject.obj \ - $(SLO)$/overlayobjectcell.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 index 4781cc247e7e..dcfeb0ae3dc2 100644 --- a/svx/source/sdr/overlay/overlayanimatedbitmapex.cxx +++ b/svx/source/sdr/overlay/overlayanimatedbitmapex.cxx @@ -34,9 +34,8 @@ #include <vcl/salbtype.hxx> #include <vcl/outdev.hxx> #include <svx/sdr/overlay/overlaymanager.hxx> - -// #i77674# #include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -57,43 +56,30 @@ namespace sdr } } - void OverlayAnimatedBitmapEx::drawGeometry(OutputDevice& rOutputDevice) - { - // #i77674# calculate discrete top-left - basegfx::B2DPoint aDiscreteTopLeft(rOutputDevice.GetViewTransformation() * getBasePosition()); - aDiscreteTopLeft -= (mbOverlayState) - ? basegfx::B2DPoint((double)mnCenterX1, (double)mnCenterY1) - : basegfx::B2DPoint((double)mnCenterX2, (double)mnCenterY2); - - // remember MapMode and switch to pixels - const bool bMapModeWasEnabled(rOutputDevice.IsMapModeEnabled()); - rOutputDevice.EnableMapMode(false); - - // draw the bitmap - const Point aPixelTopLeft((sal_Int32)floor(aDiscreteTopLeft.getX()), (sal_Int32)floor(aDiscreteTopLeft.getY())); - rOutputDevice.DrawBitmapEx(aPixelTopLeft, (mbOverlayState) ? maBitmapEx1 : maBitmapEx2); - - // restore MapMode - rOutputDevice.EnableMapMode(bMapModeWasEnabled); - } - - void OverlayAnimatedBitmapEx::createBaseRange(OutputDevice& rOutputDevice) + drawinglayer::primitive2d::Primitive2DSequence OverlayAnimatedBitmapEx::createOverlayObjectPrimitive2DSequence() { - // #i77674# calculate discrete top-left - basegfx::B2DPoint aDiscreteTopLeft(rOutputDevice.GetViewTransformation() * getBasePosition()); - aDiscreteTopLeft -= (mbOverlayState) - ? basegfx::B2DPoint((double)mnCenterX1, (double)mnCenterY1) - : basegfx::B2DPoint((double)mnCenterX2, (double)mnCenterY2); - - // calculate discrete range - const Size aBitmapPixelSize((mbOverlayState) ? maBitmapEx1.GetSizePixel() : maBitmapEx2.GetSizePixel()); - const basegfx::B2DRange aDiscreteRange( - aDiscreteTopLeft.getX(), aDiscreteTopLeft.getY(), - aDiscreteTopLeft.getX() + (double)aBitmapPixelSize.getWidth(), aDiscreteTopLeft.getY() + (double)aBitmapPixelSize.getHeight()); - - // set and go back to logic range - maBaseRange = aDiscreteRange; - maBaseRange.transform(rOutputDevice.GetInverseViewTransformation()); + 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( @@ -111,10 +97,10 @@ namespace sdr mnCenterX1(nCenX1), mnCenterY1(nCenY1), mnCenterX2(nCenX2), mnCenterY2(nCenY2), mnBlinkTime(nBlinkTime), - mbOverlayState(sal_False) + mbOverlayState(false) { // set AllowsAnimation flag to mark this object as animation capable - mbAllowsAnimation = sal_True; + mbAllowsAnimation = true; // #i53216# check blink time value range impCheckBlinkTimeValueRange(); @@ -213,11 +199,11 @@ namespace sdr // switch state if(mbOverlayState) { - mbOverlayState = sal_False; + mbOverlayState = false; } else { - mbOverlayState = sal_True; + mbOverlayState = true; } // re-insert me as event @@ -227,12 +213,6 @@ namespace sdr objectChange(); } } - - void OverlayAnimatedBitmapEx::zoomHasChanged() - { - // reset validity of range in logical coor to force recalculation - mbIsChanged = sal_True; - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlaybitmap.cxx b/svx/source/sdr/overlay/overlaybitmap.cxx deleted file mode 100644 index cc782d38bc7d..000000000000 --- a/svx/source/sdr/overlay/overlaybitmap.cxx +++ /dev/null @@ -1,162 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: overlaybitmap.cxx,v $ - * $Revision: 1.5 $ - * - * 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/overlaybitmap.hxx> -#include <vcl/salbtype.hxx> -#include <vcl/outdev.hxx> -#include <vcl/bitmapex.hxx> - -// #i77674# -#include <basegfx/matrix/b2dhommatrix.hxx> - -////////////////////////////////////////////////////////////////////////////// - -namespace sdr -{ - namespace overlay - { - void OverlayBitmap::drawGeometry(OutputDevice& rOutputDevice) - { - // #i77674# calculate discrete top-left - basegfx::B2DPoint aDiscreteTopLeft(rOutputDevice.GetViewTransformation() * getBasePosition()); - aDiscreteTopLeft -= basegfx::B2DPoint((double)mnCenterX, (double)mnCenterY); - - // remember MapMode and switch to pixels - const bool bMapModeWasEnabled(rOutputDevice.IsMapModeEnabled()); - rOutputDevice.EnableMapMode(false); - - // draw the bitmap - const Point aPixelTopLeft((sal_Int32)floor(aDiscreteTopLeft.getX()), (sal_Int32)floor(aDiscreteTopLeft.getY())); - - if(mbUseTransparenceColor) - { - BitmapEx aBitmapEx(maBitmap, getBaseColor()); - rOutputDevice.DrawBitmapEx(aPixelTopLeft, aBitmapEx); - } - else - { - rOutputDevice.DrawBitmap(aPixelTopLeft, maBitmap); - } - - // restore MapMode - rOutputDevice.EnableMapMode(bMapModeWasEnabled); - } - - void OverlayBitmap::createBaseRange(OutputDevice& rOutputDevice) - { - // #i77674# calculate discrete top-left - basegfx::B2DPoint aDiscreteTopLeft(rOutputDevice.GetViewTransformation() * getBasePosition()); - aDiscreteTopLeft -= basegfx::B2DPoint((double)mnCenterX, (double)mnCenterY); - - // calculate discrete range - const Size aBitmapPixelSize(maBitmap.GetSizePixel()); - const basegfx::B2DRange aDiscreteRange( - aDiscreteTopLeft.getX(), aDiscreteTopLeft.getY(), - aDiscreteTopLeft.getX() + (double)aBitmapPixelSize.getWidth(), aDiscreteTopLeft.getY() + (double)aBitmapPixelSize.getHeight()); - - // set and go back to logic range - maBaseRange = aDiscreteRange; - maBaseRange.transform(rOutputDevice.GetInverseViewTransformation()); - } - - OverlayBitmap::OverlayBitmap( - const basegfx::B2DPoint& rBasePos, - const Bitmap& rBitmap, - sal_uInt16 nCenX, sal_uInt16 nCenY, - sal_Bool bUseTransCol, - Color aTransColor) - : OverlayObjectWithBasePosition(rBasePos, aTransColor), - maBitmap(rBitmap), - mnCenterX(nCenX), - mnCenterY(nCenY), - mbUseTransparenceColor(bUseTransCol) - { - } - - OverlayBitmap::~OverlayBitmap() - { - } - - void OverlayBitmap::setBitmap(const Bitmap& rNew) - { - if(rNew != maBitmap) - { - // remember new Bitmap - maBitmap = rNew; - - // register change (after change) - objectChange(); - } - } - - void OverlayBitmap::setTransparenceUsed(sal_Bool bNew) - { - if(bNew != mbUseTransparenceColor) - { - // remember new value - mbUseTransparenceColor = bNew; - - // register change (after change) - objectChange(); - } - } - - void OverlayBitmap::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(); - } - } - - void OverlayBitmap::zoomHasChanged() - { - // reset validity of range in logical coor to force recalculation - mbIsChanged = sal_True; - } - } // 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 index 9f0e183f420c..cd50c9149b27 100644 --- a/svx/source/sdr/overlay/overlaybitmapex.cxx +++ b/svx/source/sdr/overlay/overlaybitmapex.cxx @@ -33,9 +33,8 @@ #include <svx/sdr/overlay/overlaybitmapex.hxx> #include <vcl/salbtype.hxx> #include <vcl/outdev.hxx> - -// #i77674# #include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -43,39 +42,16 @@ namespace sdr { namespace overlay { - void OverlayBitmapEx::drawGeometry(OutputDevice& rOutputDevice) - { - // #i77674# calculate discrete top-left - basegfx::B2DPoint aDiscreteTopLeft(rOutputDevice.GetViewTransformation() * getBasePosition()); - aDiscreteTopLeft -= basegfx::B2DPoint((double)mnCenterX, (double)mnCenterY); - - // remember MapMode and switch to pixels - const bool bMapModeWasEnabled(rOutputDevice.IsMapModeEnabled()); - rOutputDevice.EnableMapMode(false); - - // draw the bitmap - const Point aPixelTopLeft((sal_Int32)floor(aDiscreteTopLeft.getX()), (sal_Int32)floor(aDiscreteTopLeft.getY())); - rOutputDevice.DrawBitmapEx(aPixelTopLeft, maBitmapEx); - - // restore MapMode - rOutputDevice.EnableMapMode(bMapModeWasEnabled); - } - - void OverlayBitmapEx::createBaseRange(OutputDevice& rOutputDevice) + drawinglayer::primitive2d::Primitive2DSequence OverlayBitmapEx::createOverlayObjectPrimitive2DSequence() { - // #i77674# calculate discrete top-left - basegfx::B2DPoint aDiscreteTopLeft(rOutputDevice.GetViewTransformation() * getBasePosition()); - aDiscreteTopLeft -= basegfx::B2DPoint((double)mnCenterX, (double)mnCenterY); - - // calculate discrete range - const Size aBitmapPixelSize(maBitmapEx.GetSizePixel()); - const basegfx::B2DRange aDiscreteRange( - aDiscreteTopLeft.getX(), aDiscreteTopLeft.getY(), - aDiscreteTopLeft.getX() + (double)aBitmapPixelSize.getWidth(), aDiscreteTopLeft.getY() + (double)aBitmapPixelSize.getHeight()); - - // set and go back to logic range - maBaseRange = aDiscreteRange; - maBaseRange.transform(rOutputDevice.GetInverseViewTransformation()); + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::OverlayBitmapExPrimitive( + getBitmapEx(), + getBasePosition(), + getCenterX(), + getCenterY())); + + return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); } OverlayBitmapEx::OverlayBitmapEx( @@ -124,12 +100,6 @@ namespace sdr objectChange(); } } - - void OverlayBitmapEx::zoomHasChanged() - { - // reset validity of range in logical coor to force recalculation - mbIsChanged = sal_True; - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlaycrosshair.cxx b/svx/source/sdr/overlay/overlaycrosshair.cxx index 7107817fad04..90bd99bc289e 100644 --- a/svx/source/sdr/overlay/overlaycrosshair.cxx +++ b/svx/source/sdr/overlay/overlaycrosshair.cxx @@ -34,6 +34,8 @@ #include <tools/gen.hxx> #include <vcl/salbtype.hxx> #include <vcl/outdev.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -41,31 +43,33 @@ namespace sdr { namespace overlay { - void OverlayCrosshairStriped::drawGeometry(OutputDevice& rOutputDevice) + drawinglayer::primitive2d::Primitive2DSequence OverlayCrosshairStriped::createOverlayObjectPrimitive2DSequence() { - const Point aEmptyPoint; - const Rectangle aVisiblePixel(aEmptyPoint, rOutputDevice.GetOutputSizePixel()); - const Rectangle aVisibleLogic(rOutputDevice.PixelToLogic(aVisiblePixel)); + drawinglayer::primitive2d::Primitive2DSequence aRetval; - const basegfx::B2DPoint aStartA(aVisibleLogic.Left(), getBasePosition().getY()); - const basegfx::B2DPoint aEndA(aVisibleLogic.Right(), getBasePosition().getY()); - ImpDrawLineStriped(rOutputDevice, aStartA, aEndA); + 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); + } - const basegfx::B2DPoint aStartB(getBasePosition().getX(), aVisibleLogic.Top()); - const basegfx::B2DPoint aEndB(getBasePosition().getX(), aVisibleLogic.Bottom()); - ImpDrawLineStriped(rOutputDevice, aStartB, aEndB); + return aRetval; } - void OverlayCrosshairStriped::createBaseRange(OutputDevice& rOutputDevice) + void OverlayCrosshairStriped::stripeDefinitionHasChanged() { - // reset range and expand it - const Point aEmptyPoint; - const Rectangle aVisiblePixel(aEmptyPoint, rOutputDevice.GetOutputSizePixel()); - const Rectangle aVisibleLogic(rOutputDevice.PixelToLogic(aVisiblePixel)); - - maBaseRange.reset(); - maBaseRange.expand(basegfx::B2DPoint(aVisibleLogic.Left(), aVisibleLogic.Top())); - maBaseRange.expand(basegfx::B2DPoint(aVisibleLogic.Right(), aVisibleLogic.Bottom())); + // react on OverlayManager's stripe definition change + objectChange(); } OverlayCrosshairStriped::OverlayCrosshairStriped(const basegfx::B2DPoint& rBasePos) @@ -76,64 +80,6 @@ namespace sdr OverlayCrosshairStriped::~OverlayCrosshairStriped() { } - - sal_Bool OverlayCrosshairStriped::isHit(const basegfx::B2DPoint& rPos, double fTol) const - { - if(isHittable()) - { - // test vertical - if(rPos.getY() >= (getBasePosition().getY() - fTol) - && rPos.getY() <= (getBasePosition().getY() + fTol)) - { - return sal_True; - } - - // test horizontal - if(rPos.getX() >= (getBasePosition().getX() - fTol) - && rPos.getX() <= (getBasePosition().getX() + fTol)) - { - return sal_True; - } - } - - return sal_False; - } - } // end of namespace overlay -} // end of namespace sdr - -////////////////////////////////////////////////////////////////////////////// - -namespace sdr -{ - namespace overlay - { - void OverlayCrosshair::drawGeometry(OutputDevice& rOutputDevice) - { - const Point aBasePos(FRound(getBasePosition().getX()), FRound(getBasePosition().getY())); - const Point aEmptyPoint; - const Rectangle aVisiblePixel(aEmptyPoint, rOutputDevice.GetOutputSizePixel()); - const Rectangle aVisibleLogic(rOutputDevice.PixelToLogic(aVisiblePixel)); - - rOutputDevice.SetLineColor(getBaseColor()); - rOutputDevice.SetFillColor(); - - rOutputDevice.DrawLine(Point(aVisibleLogic.Left(), aBasePos.Y()), Point(aVisibleLogic.Right(), aBasePos.Y())); - rOutputDevice.DrawLine(Point(aBasePos.X(), aVisibleLogic.Top()), Point(aBasePos.X(), aVisibleLogic.Bottom())); - } - - OverlayCrosshair::OverlayCrosshair( - const basegfx::B2DPoint& rBasePos, - Color aLineColor) - : OverlayCrosshairStriped(rBasePos) - { - // set base color here, OverlayCrosshairStriped constructor has set - // it to it's own default. - maBaseColor = aLineColor; - } - - OverlayCrosshair::~OverlayCrosshair() - { - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlayhatchrect.cxx b/svx/source/sdr/overlay/overlayhatchrect.cxx index a15d38f16bc9..9bda13816029 100644 --- a/svx/source/sdr/overlay/overlayhatchrect.cxx +++ b/svx/source/sdr/overlay/overlayhatchrect.cxx @@ -38,6 +38,7 @@ #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/numeric/ftools.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -45,81 +46,34 @@ namespace sdr { namespace overlay { - basegfx::B2DPolyPolygon OverlayHatchRect::getGeometry(OutputDevice& rOutputDevice) + drawinglayer::primitive2d::Primitive2DSequence OverlayHatchRect::createOverlayObjectPrimitive2DSequence() { - const basegfx::B2DPoint aDiscreteTopLeft(rOutputDevice.GetViewTransformation() * getBasePosition()); - const basegfx::B2DPoint aDiscreteBottomRight(rOutputDevice.GetViewTransformation() * getSecondPosition()); - - basegfx::B2DRange aInnerRange( - floor(aDiscreteTopLeft.getX()), floor(aDiscreteTopLeft.getY()), - floor(aDiscreteBottomRight.getX()), floor(aDiscreteBottomRight.getY())); - basegfx::B2DRange aOuterRange(aInnerRange); - basegfx::B2DPolyPolygon aRetval; - - aOuterRange.grow(getDiscreteWidth() * 0.5); - aInnerRange.grow(getDiscreteWidth() * -0.5); - - aRetval.append(basegfx::tools::createPolygonFromRect(aOuterRange)); - aRetval.append(basegfx::tools::createPolygonFromRect(aInnerRange)); - - if(!basegfx::fTools::equalZero(mfRotation)) - { - basegfx::B2DHomMatrix aTransform; - - aTransform.translate(-aOuterRange.getMinX(), -aOuterRange.getMinY()); - aTransform.rotate(getRotation()); - aTransform.translate(aOuterRange.getMinX(), aOuterRange.getMinY()); - - aRetval.transform(aTransform); - } - - return aRetval; - } - - void OverlayHatchRect::drawGeometry(OutputDevice& rOutputDevice) - { - const basegfx::B2DPolyPolygon aB2DGeometry(getGeometry(rOutputDevice)); - const bool bMapModeWasEnabled(rOutputDevice.IsMapModeEnabled()); - - // use VCL polygon and methodology for paint - double fFullRotation(getHatchRotation() - getRotation()); - - while(fFullRotation < 0.0) - { - fFullRotation += F_2PI; - } - - while(fFullRotation >= F_2PI) - { - fFullRotation -= F_2PI; - } - - const Hatch aHatch(HATCH_SINGLE, getBaseColor(), 3, (sal_uInt16)basegfx::fround(fFullRotation * ( 10.0 / F_PI180))); - rOutputDevice.EnableMapMode(false); - rOutputDevice.DrawHatch(PolyPolygon(aB2DGeometry), aHatch); - rOutputDevice.EnableMapMode(bMapModeWasEnabled); - } - - void OverlayHatchRect::createBaseRange(OutputDevice& rOutputDevice) - { - // reset range and expand with fresh geometry - maBaseRange = getGeometry(rOutputDevice).getB2DRange(); - - // getGeometry data is in discrete coordinates (pixels), so transform back to - // world coordinates (logic) - maBaseRange.transform(rOutputDevice.GetInverseViewTransformation()); + 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 fDiscreteWidth, + double fDiscreteGrow, + double fDiscreteShrink, double fHatchRotation, double fRotation) : OverlayObjectWithBasePosition(rBasePosition, rHatchColor), maSecondPosition(rSecondPosition), - mfDiscreteWidth(fDiscreteWidth), + mfDiscreteGrow(fDiscreteGrow), + mfDiscreteShrink(fDiscreteShrink), mfHatchRotation(fHatchRotation), mfRotation(fRotation) { @@ -136,12 +90,6 @@ namespace sdr objectChange(); } } - - void OverlayHatchRect::zoomHasChanged() - { - // reset validity of range in logical coor to force recalculation - mbIsChanged = sal_True; - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlayhelpline.cxx b/svx/source/sdr/overlay/overlayhelpline.cxx index 5de8d071a292..12cb5ac660ba 100644 --- a/svx/source/sdr/overlay/overlayhelpline.cxx +++ b/svx/source/sdr/overlay/overlayhelpline.cxx @@ -35,6 +35,8 @@ #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> ////////////////////////////////////////////////////////////////////////////// @@ -42,79 +44,38 @@ namespace sdr { namespace overlay { - void OverlayHelplineStriped::drawGeometry(OutputDevice& rOutputDevice) + drawinglayer::primitive2d::Primitive2DSequence OverlayHelplineStriped::createOverlayObjectPrimitive2DSequence() { - // prepare OutputDevice - const Point aEmptyPoint; - const Rectangle aVisiblePixel(aEmptyPoint, rOutputDevice.GetOutputSizePixel()); - const Rectangle aVisibleLogic(rOutputDevice.PixelToLogic(aVisiblePixel)); + drawinglayer::primitive2d::Primitive2DSequence aRetval; - switch(meKind) + if(getOverlayManager()) { - case SDRHELPLINE_VERTICAL : - { - const basegfx::B2DPoint aStart(getBasePosition().getX(), aVisibleLogic.Top()); - const basegfx::B2DPoint aEnd(getBasePosition().getX(), aVisibleLogic.Bottom()); - ImpDrawLineStriped(rOutputDevice, aStart, aEnd); - break; - } - - case SDRHELPLINE_HORIZONTAL : - { - const basegfx::B2DPoint aStart(aVisibleLogic.Left(), getBasePosition().getY()); - const basegfx::B2DPoint aEnd(aVisibleLogic.Right(), getBasePosition().getY()); - ImpDrawLineStriped(rOutputDevice, aStart, aEnd); - break; - } - - case SDRHELPLINE_POINT : - { - const Size aPixelSize(SDRHELPLINE_POINT_PIXELSIZE, SDRHELPLINE_POINT_PIXELSIZE); - const Size aLogicSize(rOutputDevice.PixelToLogic(aPixelSize)); - - const basegfx::B2DPoint aStartA(getBasePosition().getX(), getBasePosition().getY() - aLogicSize.Height()); - const basegfx::B2DPoint aEndA(getBasePosition().getX(), getBasePosition().getY() + aLogicSize.Height()); - ImpDrawLineStriped(rOutputDevice, aStartA, aEndA); - - const basegfx::B2DPoint aStartB(getBasePosition().getX() - aLogicSize.Width(), getBasePosition().getY()); - const basegfx::B2DPoint aEndB(getBasePosition().getX() + aLogicSize.Width(), getBasePosition().getY()); - ImpDrawLineStriped(rOutputDevice, aStartB, aEndB); - - break; - } + 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::createBaseRange(OutputDevice& rOutputDevice) + void OverlayHelplineStriped::stripeDefinitionHasChanged() { - // reset range and expand it - maBaseRange.reset(); - - if(SDRHELPLINE_POINT == meKind) - { - const Size aPixelSize(SDRHELPLINE_POINT_PIXELSIZE, SDRHELPLINE_POINT_PIXELSIZE); - const Size aLogicSize(rOutputDevice.PixelToLogic(aPixelSize)); - - maBaseRange.expand(basegfx::B2DPoint(getBasePosition().getX() - aLogicSize.Width(), getBasePosition().getY() - aLogicSize.Height())); - maBaseRange.expand(basegfx::B2DPoint(getBasePosition().getX() + aLogicSize.Width(), getBasePosition().getY() + aLogicSize.Height())); - } - else - { - const Point aEmptyPoint; - const Rectangle aVisiblePixel(aEmptyPoint, rOutputDevice.GetOutputSizePixel()); - const Rectangle aVisibleLogic(rOutputDevice.PixelToLogic(aVisiblePixel)); - - if(SDRHELPLINE_HORIZONTAL == meKind) - { - maBaseRange.expand(basegfx::B2DPoint(aVisibleLogic.Left(), getBasePosition().getY())); - maBaseRange.expand(basegfx::B2DPoint(aVisibleLogic.Right(), getBasePosition().getY())); - } - else if(SDRHELPLINE_VERTICAL == meKind) - { - maBaseRange.expand(basegfx::B2DPoint(getBasePosition().getX(), aVisibleLogic.Top())); - maBaseRange.expand(basegfx::B2DPoint(getBasePosition().getX(), aVisibleLogic.Bottom())); - } - } + // react on OverlayManager's stripe definition change + objectChange(); } OverlayHelplineStriped::OverlayHelplineStriped( @@ -128,102 +89,6 @@ namespace sdr OverlayHelplineStriped::~OverlayHelplineStriped() { } - - sal_Bool OverlayHelplineStriped::isHit(const basegfx::B2DPoint& rPos, double fTol) const - { - if(isHittable()) - { - if(SDRHELPLINE_POINT == meKind) - { - // use distance to BasePosition - const basegfx::B2DVector aVector(rPos - getBasePosition()); - - return (aVector.getLength() < fTol); - } - else - { - if(SDRHELPLINE_HORIZONTAL == meKind) - { - // test vertical - if(rPos.getY() >= (getBasePosition().getY() - fTol) - && rPos.getY() <= (getBasePosition().getY() + fTol)) - { - return sal_True; - } - } - else if(SDRHELPLINE_VERTICAL == meKind) - { - // test horizontal - if(rPos.getX() >= (getBasePosition().getX() - fTol) - && rPos.getX() <= (getBasePosition().getX() + fTol)) - { - return sal_True; - } - } - } - } - - return sal_False; - } - } // end of namespace overlay -} // end of namespace sdr - -////////////////////////////////////////////////////////////////////////////// - -namespace sdr -{ - namespace overlay - { - void OverlayHelpline::drawGeometry(OutputDevice& rOutputDevice) - { - Point aBasePos(FRound(getBasePosition().getX()), FRound(getBasePosition().getY())); - - rOutputDevice.SetLineColor(getBaseColor()); - rOutputDevice.SetFillColor(); - - if(SDRHELPLINE_POINT == meKind) - { - Size aPixelSize(SDRHELPLINE_POINT_PIXELSIZE, SDRHELPLINE_POINT_PIXELSIZE); - Size aLogicSize(rOutputDevice.PixelToLogic(aPixelSize)); - - rOutputDevice.DrawLine( - Point(aBasePos.X() - aLogicSize.Width(), aBasePos.Y()), - Point(aBasePos.X() + aLogicSize.Width(), aBasePos.Y())); - rOutputDevice.DrawLine( - Point(aBasePos.X(), aBasePos.Y() - aLogicSize.Height()), - Point(aBasePos.X(), aBasePos.Y() + aLogicSize.Height())); - } - else - { - Point aEmptyPoint; - Rectangle aVisiblePixel(aEmptyPoint, rOutputDevice.GetOutputSizePixel()); - Rectangle aVisibleLogic(rOutputDevice.PixelToLogic(aVisiblePixel)); - - if(SDRHELPLINE_HORIZONTAL == meKind) - { - rOutputDevice.DrawLine(Point(aVisibleLogic.Left(), aBasePos.Y()), Point(aVisibleLogic.Right(), aBasePos.Y())); - } - else if(SDRHELPLINE_VERTICAL == meKind) - { - rOutputDevice.DrawLine(Point(aBasePos.X(), aVisibleLogic.Top()), Point(aBasePos.X(), aVisibleLogic.Bottom())); - } - } - } - - OverlayHelpline::OverlayHelpline( - const basegfx::B2DPoint& rBasePos, - Color aLineColor, - SdrHelpLineKind eNewKind) - : OverlayHelplineStriped(rBasePos, eNewKind) - { - // set base color here, OverlayCrosshairStriped constructor has set - // it to it's own default. - maBaseColor = aLineColor; - } - - OverlayHelpline::~OverlayHelpline() - { - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlayline.cxx b/svx/source/sdr/overlay/overlayline.cxx index 003da41ee31d..90ecb869f4f6 100644 --- a/svx/source/sdr/overlay/overlayline.cxx +++ b/svx/source/sdr/overlay/overlayline.cxx @@ -37,6 +37,9 @@ #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> ////////////////////////////////////////////////////////////////////////////// @@ -44,17 +47,37 @@ namespace sdr { namespace overlay { - void OverlayLineStriped::drawGeometry(OutputDevice& rOutputDevice) + drawinglayer::primitive2d::Primitive2DSequence OverlayLineStriped::createOverlayObjectPrimitive2DSequence() { - ImpDrawLineStriped(rOutputDevice, getBasePosition(), getSecondPosition()); + 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::createBaseRange(OutputDevice& /*rOutputDevice*/) + void OverlayLineStriped::stripeDefinitionHasChanged() { - // reset range and expand it - maBaseRange.reset(); - maBaseRange.expand(getBasePosition()); - maBaseRange.expand(getSecondPosition()); + // react on OverlayManager's stripe definition change + objectChange(); } OverlayLineStriped::OverlayLineStriped( @@ -80,63 +103,6 @@ namespace sdr objectChange(); } } - - sal_Bool OverlayLineStriped::isHit(const basegfx::B2DPoint& rPos, double fTol) const - { - if(isHittable() && !getBasePosition().equal(getSecondPosition())) - { - return basegfx::tools::isInEpsilonRange(getBasePosition(), getSecondPosition(), rPos, fTol); - } - - return sal_False; - } - - void OverlayLineStriped::transform(const basegfx::B2DHomMatrix& rMatrix) - { - if(!rMatrix.isIdentity()) - { - // transform base position - OverlayObjectWithBasePosition::transform(rMatrix); - - // transform maSecondPosition - const basegfx::B2DPoint aNewSecondPosition = rMatrix * getSecondPosition(); - setSecondPosition(aNewSecondPosition); - } - } - } // end of namespace overlay -} // end of namespace sdr - -////////////////////////////////////////////////////////////////////////////// - -namespace sdr -{ - namespace overlay - { - void OverlayLine::drawGeometry(OutputDevice& rOutputDevice) - { - const Point aStart(FRound(getBasePosition().getX()), FRound(getBasePosition().getY())); - const Point aEnd(FRound(getSecondPosition().getX()), FRound(getSecondPosition().getY())); - - rOutputDevice.SetLineColor(getBaseColor()); - rOutputDevice.SetFillColor(); - - rOutputDevice.DrawLine(aStart, aEnd); - } - - OverlayLine::OverlayLine( - const basegfx::B2DPoint& rBasePos, - const basegfx::B2DPoint& rSecondPos, - Color aLineColor) - : OverlayLineStriped(rBasePos, rSecondPos) - { - // set base color here, OverlayCrosshairStriped constructor has set - // it to it's own default. - maBaseColor = aLineColor; - } - - OverlayLine::~OverlayLine() - { - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlaymanager.cxx b/svx/source/sdr/overlay/overlaymanager.cxx index 8c682adfc166..79d493b6d9d0 100644 --- a/svx/source/sdr/overlay/overlaymanager.cxx +++ b/svx/source/sdr/overlay/overlaymanager.cxx @@ -50,33 +50,49 @@ namespace sdr { void OverlayManager::ImpDrawMembers(const basegfx::B2DRange& rRange, OutputDevice& rDestinationDevice) const { - ::sdr::overlay::OverlayObject* pCurrent = mpOverlayObjectStart; + const sal_uInt32 nSize(maOverlayObjects.size()); - if(pCurrent) + if(nSize) { const sal_uInt16 nOriginalAA(rDestinationDevice.GetAntialiasing()); + const bool bIsAntiAliasing(getDrawinglayerOpt().IsAntiAliasing()); - // react on AntiAliasing settings - if(maDrawinglayerOpt.IsAntiAliasing()) - { - rDestinationDevice.SetAntialiasing(nOriginalAA | ANTIALIASING_ENABLE_B2DDRAW); - } - else - { - rDestinationDevice.SetAntialiasing(nOriginalAA & ~ANTIALIASING_ENABLE_B2DDRAW); - } + // create processor + drawinglayer::processor2d::BaseProcessor2D* pProcessor = ::sdr::contact::createBaseProcessor2DFromOutputDevice( + rDestinationDevice, + getCurrentViewInformation2D()); - while(pCurrent) + if(pProcessor) { - if(pCurrent->isVisible()) + for(OverlayObjectVector::const_iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); aIter++) { - if(rRange.overlaps(pCurrent->getBaseRange())) + OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)"); + const OverlayObject& rCandidate = **aIter; + + if(rCandidate.isVisible()) { - pCurrent->drawGeometry(rDestinationDevice); + 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); + } + } } } - pCurrent = pCurrent->mpNext; + delete pProcessor; } // restore AA settings @@ -84,87 +100,162 @@ namespace sdr } } - void OverlayManager::ImpCheckMapModeChange() const + void OverlayManager::ImpStripeDefinitionChanged() { - sal_Bool bZoomHasChanged(sal_False); - MapMode aOutputDeviceMapMode(getOutputDevice().GetMapMode()); - ::sdr::overlay::OverlayObject* pCurrent = mpOverlayObjectStart; + const sal_uInt32 nSize(maOverlayObjects.size()); - if(maMapMode != aOutputDeviceMapMode) + if(nSize) { - bZoomHasChanged = ( - maMapMode.GetScaleX() != aOutputDeviceMapMode.GetScaleX() - || maMapMode.GetScaleY() != aOutputDeviceMapMode.GetScaleY()); - - // remember MapMode - ((OverlayManager*)this)->maMapMode = aOutputDeviceMapMode; - } - - if(bZoomHasChanged && pCurrent) - { - while(pCurrent) + for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); aIter++) { - pCurrent->zoomHasChanged(); - pCurrent = pCurrent->mpNext; + OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)"); + OverlayObject& rCandidate = **aIter; + rCandidate.stripeDefinitionHasChanged(); } } } - void OverlayManager::ImpStripeDefinitionChanged() - { - ::sdr::overlay::OverlayObject* pCurrent = mpOverlayObjectStart; - - while(pCurrent) - { - pCurrent->stripeDefinitionHasChanged(); - pCurrent = pCurrent->mpNext; - } - } - double OverlayManager::getDiscreteOne() const { - if(getOutputDevice().GetViewTransformation() != maViewTransformation) + if(basegfx::fTools::equalZero(mfDiscreteOne)) { - OverlayManager* pThis = const_cast< OverlayManager* >(this); - pThis->maViewTransformation = getOutputDevice().GetViewTransformation(); const basegfx::B2DVector aDiscreteInLogic(getOutputDevice().GetInverseViewTransformation() * basegfx::B2DVector(1.0, 0.0)); - pThis->mfDiscreteOne = aDiscreteInLogic.getLength(); + const_cast< OverlayManager* >(this)->mfDiscreteOne = aDiscreteInLogic.getLength(); } return mfDiscreteOne; } - OverlayManager::OverlayManager(OutputDevice& rOutputDevice) + OverlayManager::OverlayManager( + OutputDevice& rOutputDevice, + OverlayManager* pOldOverlayManager) : Scheduler(), rmOutputDevice(rOutputDevice), - mpOverlayObjectStart(0L), - mpOverlayObjectEnd(0L), + maOverlayObjects(), maStripeColorA(Color(COL_BLACK)), maStripeColorB(Color(COL_WHITE)), - mnStripeLengthPixel(5L), + mnStripeLengthPixel(5), maDrawinglayerOpt(), maViewTransformation(), + maViewInformation2D(0), mfDiscreteOne(0.0) { + 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. - while(mpOverlayObjectStart) + // 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) { - remove(*mpOverlayObjectStart); + 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() && mpOverlayObjectStart) + if(!rRegion.IsEmpty() && maOverlayObjects.size()) { // check for changed MapModes. That may influence the // logical size of pixel based OverlayObjects (like BitmapHandles) - ImpCheckMapModeChange(); + //ImpCheckMapModeChange(); // paint members const Rectangle aRegionBoundRect(rRegion.GetBoundRect()); @@ -195,87 +286,38 @@ namespace sdr void OverlayManager::add(OverlayObject& rOverlayObject) { - // add to the end of chain to preserve display order in paint - DBG_ASSERT(0L == rOverlayObject.mpOverlayManager, - "OverlayManager::add: OverlayObject is added to an OverlayManager (!)"); - - if(mpOverlayObjectEnd) - { - // new element, add to end - rOverlayObject.mpNext = mpOverlayObjectEnd->mpNext; - rOverlayObject.mpPrevious = mpOverlayObjectEnd; - mpOverlayObjectEnd->mpNext = &rOverlayObject; - mpOverlayObjectEnd = &rOverlayObject; - } - else - { - // first element - rOverlayObject.mpNext = rOverlayObject.mpPrevious = 0L; - mpOverlayObjectEnd = mpOverlayObjectStart = &rOverlayObject; - } - - // set manager - rOverlayObject.mpOverlayManager = this; + OSL_ENSURE(0 == rOverlayObject.mpOverlayManager, "OverlayObject is added twice to an OverlayManager (!)"); - // make visible - invalidateRange(rOverlayObject.getBaseRange()); + // add to the end of chain to preserve display order in paint + maOverlayObjects.push_back(&rOverlayObject); - // handle evtl. animation - if(rOverlayObject.allowsAnimation()) - { - // Trigger at current time to get alive. This will do the - // object-specific next time calculation and hand over adding - // again to the scheduler to the animated object, too. This works for - // a paused or non-paused animator. - rOverlayObject.Trigger(GetTime()); - } + // execute add actions + impApplyAddActions(rOverlayObject); } void OverlayManager::remove(OverlayObject& rOverlayObject) { - // handle evtl. animation - if(rOverlayObject.allowsAnimation()) - { - // remove from event chain - RemoveEvent(&rOverlayObject); - } + OSL_ENSURE(rOverlayObject.mpOverlayManager == this, "OverlayObject is removed from wrong OverlayManager (!)"); - // Remove from chain - DBG_ASSERT(rOverlayObject.mpOverlayManager == this, - "OverlayManager::remove: OverlayObject is removed from wrong OverlayManager (!)"); + // execute remove actions + impApplyRemoveActions(rOverlayObject); - if(rOverlayObject.mpPrevious) - { - rOverlayObject.mpPrevious->mpNext = rOverlayObject.mpNext; - } + // 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(rOverlayObject.mpNext) + if(bFound) { - rOverlayObject.mpNext->mpPrevious = rOverlayObject.mpPrevious; + maOverlayObjects.erase(aFindResult); } - - if(&rOverlayObject == mpOverlayObjectStart) - { - mpOverlayObjectStart = rOverlayObject.mpNext; - } - - if(&rOverlayObject == mpOverlayObjectEnd) - { - mpOverlayObjectEnd = rOverlayObject.mpPrevious; - } - - // make invisible - invalidateRange(rOverlayObject.getBaseRange()); - - // clear manager - rOverlayObject.mpOverlayManager = 0L; } void OverlayManager::invalidateRange(const basegfx::B2DRange& rRange) { if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType()) { - if(maDrawinglayerOpt.IsAntiAliasing()) + if(getDrawinglayerOpt().IsAntiAliasing()) { // assume AA needs one pixel more and invalidate one pixel more const double fDiscreteOne(getDiscreteOne()); @@ -331,18 +373,6 @@ namespace sdr ImpStripeDefinitionChanged(); } } - - ::boost::shared_ptr<OverlayObjectVector> OverlayManager::GetOverlayObjects (void) const - { - ::boost::shared_ptr<OverlayObjectVector> pObjectList (new OverlayObjectVector()); - sdr::overlay::OverlayObject* pObject = mpOverlayObjectStart; - while (pObject != NULL) - { - pObjectList->push_back(pObject); - pObject = pObject->mpNext; - } - return pObjectList; - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx index 584faedcdda2..2b664e816d42 100644 --- a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx +++ b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx @@ -36,12 +36,8 @@ #include <basegfx/range/b2drange.hxx> #include <vcl/salbtype.hxx> #include <vcl/window.hxx> - -// #i72754# #include <vcl/bitmap.hxx> #include <tools/stream.hxx> - -// #i75163# #include <basegfx/matrix/b2dhommatrix.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -63,7 +59,7 @@ namespace sdr // compare the MapModes for zoom/scroll changes if(maBufferDevice.GetMapMode() != getOutputDevice().GetMapMode()) { - const sal_Bool bZoomed( + const bool bZoomed( maBufferDevice.GetMapMode().GetScaleX() != getOutputDevice().GetMapMode().GetScaleX() || maBufferDevice.GetMapMode().GetScaleY() != getOutputDevice().GetMapMode().GetScaleY()); @@ -71,7 +67,7 @@ namespace sdr { const Point& rOriginOld = maBufferDevice.GetMapMode().GetOrigin(); const Point& rOriginNew = getOutputDevice().GetMapMode().GetOrigin(); - const sal_Bool bScrolled(rOriginOld != rOriginNew); + const bool bScrolled(rOriginOld != rOriginNew); if(bScrolled) { @@ -81,8 +77,8 @@ namespace sdr const Size aOutputSizePixel(maBufferDevice.GetOutputSizePixel()); // remember and switch off MapMode - const sal_Bool bMapModeWasEnabled(maBufferDevice.IsMapModeEnabled()); - maBufferDevice.EnableMapMode(sal_False); + const bool bMapModeWasEnabled(maBufferDevice.IsMapModeEnabled()); + maBufferDevice.EnableMapMode(false); // scroll internally buffered stuff const Point aDestinationOffsetPixel(aOriginNewPixel - aOriginOldPixel); @@ -132,10 +128,10 @@ namespace sdr Rectangle aRegionRectanglePixel; // MapModes off - const sal_Bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled()); - const sal_Bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled()); - getOutputDevice().EnableMapMode(sal_False); - ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(sal_False); + const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled()); + const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled()); + getOutputDevice().EnableMapMode(false); + ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(false); while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel)) { @@ -200,10 +196,10 @@ namespace sdr Rectangle aRegionRectanglePixel; // MapModes off - const sal_Bool bMapModeWasEnabledDest(rSource.IsMapModeEnabled()); - const sal_Bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled()); - rSource.EnableMapMode(sal_False); - maBufferDevice.EnableMapMode(sal_False); + const bool bMapModeWasEnabledDest(rSource.IsMapModeEnabled()); + const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled()); + rSource.EnableMapMode(false); + maBufferDevice.EnableMapMode(false); while(aRegion.GetEnumRects(aRegionHandle, aRegionRectanglePixel)) { @@ -221,7 +217,7 @@ namespace sdr static bool bDoPaintForVisualControl(false); if(bDoPaintForVisualControl) { - const sal_Bool bMapModeWasEnabledTest(getOutputDevice().IsMapModeEnabled()); + const bool bMapModeWasEnabledTest(getOutputDevice().IsMapModeEnabled()); getOutputDevice().EnableMapMode(false); getOutputDevice().SetLineColor(COL_LIGHTRED); getOutputDevice().SetFillColor(); @@ -282,7 +278,7 @@ namespace sdr } maOutputBufferDevice.SetMapMode(getOutputDevice().GetMapMode()); - maOutputBufferDevice.EnableMapMode(sal_False); + maOutputBufferDevice.EnableMapMode(false); maOutputBufferDevice.SetDrawMode(maBufferDevice.GetDrawMode()); maOutputBufferDevice.SetSettings(maBufferDevice.GetSettings()); maOutputBufferDevice.SetAntialiasing(maBufferDevice.GetAntialiasing()); @@ -320,8 +316,8 @@ namespace sdr const Size aSize(aRegionRectanglePixel.GetSize()); { - const sal_Bool bMapModeWasEnabledDest(maBufferDevice.IsMapModeEnabled()); - maBufferDevice.EnableMapMode(sal_False); + const bool bMapModeWasEnabledDest(maBufferDevice.IsMapModeEnabled()); + maBufferDevice.EnableMapMode(false); maOutputBufferDevice.DrawOutDev( aTopLeft, aSize, // destination @@ -334,14 +330,14 @@ namespace sdr // paint overlay content for remembered region, use // method from base class directly - maOutputBufferDevice.EnableMapMode(sal_True); + maOutputBufferDevice.EnableMapMode(true); OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, maOutputBufferDevice); - maOutputBufferDevice.EnableMapMode(sal_False); + maOutputBufferDevice.EnableMapMode(false); // copy to output { - const sal_Bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled()); - getOutputDevice().EnableMapMode(sal_False); + const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled()); + getOutputDevice().EnableMapMode(false); getOutputDevice().DrawOutDev( aTopLeft, aSize, // destination @@ -417,8 +413,11 @@ namespace sdr return 0; } - OverlayManagerBuffered::OverlayManagerBuffered(OutputDevice& rOutputDevice, sal_Bool bRefreshWithPreRendering) - : OverlayManager(rOutputDevice), + OverlayManagerBuffered::OverlayManagerBuffered( + OutputDevice& rOutputDevice, + OverlayManager* pOldOverlayManager, + bool bRefreshWithPreRendering) + : OverlayManager(rOutputDevice, pOldOverlayManager), mbRefreshWithPreRendering(bRefreshWithPreRendering) { // Init timer @@ -515,9 +514,9 @@ namespace sdr } } - void OverlayManagerBuffered::SetRefreshWithPreRendering(sal_Bool bNew) + void OverlayManagerBuffered::SetRefreshWithPreRendering(bool bNew) { - if(mbRefreshWithPreRendering != bNew) + if((bool)mbRefreshWithPreRendering != bNew) { mbRefreshWithPreRendering = bNew; } diff --git a/svx/source/sdr/overlay/overlayobject.cxx b/svx/source/sdr/overlay/overlayobject.cxx index 658b6719709e..5cddc3c63627 100644 --- a/svx/source/sdr/overlay/overlayobject.cxx +++ b/svx/source/sdr/overlay/overlayobject.cxx @@ -43,7 +43,6 @@ #include <basegfx/polygon/b2dpolypolygontools.hxx> #include <svx/sdr/contact/objectcontacttools.hxx> #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> -#include <drawinglayer/processor2d/baseprocessor2d.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -53,206 +52,94 @@ namespace sdr { void OverlayObject::objectChange() { - if(mpOverlayManager) - { - basegfx::B2DRange aPreviousRange(maBaseRange); - - if(!aPreviousRange.isEmpty()) - { - mpOverlayManager->invalidateRange(aPreviousRange); - } - - mbIsChanged = sal_True; - const basegfx::B2DRange& rCurrentRange = getBaseRange(); - - if(rCurrentRange != aPreviousRange && !rCurrentRange.isEmpty()) - { - mpOverlayManager->invalidateRange(rCurrentRange); - } - } - } + const basegfx::B2DRange aPreviousRange(maBaseRange); + maBaseRange.reset(); + setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DSequence()); - // support method to draw striped geometries - void OverlayObject::ImpDrawRangeStriped(OutputDevice& rOutputDevice, const basegfx::B2DRange& rRange) - { - if(getOverlayManager()) + if(getOverlayManager() && !aPreviousRange.isEmpty()) { - const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(rRange)); - - if(aPolygon.count()) - { - ImpDrawPolygonStriped(rOutputDevice, aPolygon); - } + getOverlayManager()->invalidateRange(aPreviousRange); } - } - void OverlayObject::ImpDrawLineStriped(OutputDevice& rOutputDevice, double x1, double y1, double x2, double y2) - { - if(getOverlayManager()) - { - const basegfx::B2DPoint aStart(x1, y1); - const basegfx::B2DPoint aEnd(x2, y2); + const basegfx::B2DRange& rCurrentRange = getBaseRange(); - if(!aStart.equal(aEnd)) - { - basegfx::B2DPolygon aPolygon; - aPolygon.append(aStart); - aPolygon.append(aEnd); - - ImpDrawPolygonStriped(rOutputDevice, aPolygon); - } + if(getOverlayManager() && rCurrentRange != aPreviousRange && !rCurrentRange.isEmpty()) + { + getOverlayManager()->invalidateRange(rCurrentRange); } } - void OverlayObject::ImpDrawLineStriped(OutputDevice& rOutputDevice, const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd) + // OverlayObject implementations. + drawinglayer::primitive2d::Primitive2DSequence OverlayObject::createOverlayObjectPrimitive2DSequence() { - if(getOverlayManager() && !rStart.equal(rEnd)) - { - basegfx::B2DPolygon aPolygon; - aPolygon.append(rStart); - aPolygon.append(rEnd); - - ImpDrawPolygonStriped(rOutputDevice, aPolygon); - } + // 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::ImpDrawPolygonStriped(OutputDevice& rOutputDevice, const basegfx::B2DPolygon& rPolygon) + void OverlayObject::allowAntiAliase(bool bNew) { - if(getOverlayManager() && rPolygon.count()) + if(bNew != (bool)mbAllowsAntiAliase) { - if(getOverlayManager() && getOverlayManager()->getDrawinglayerOpt().IsAntiAliasing()) - { - // prepare ViewInformation2D - const drawinglayer::geometry::ViewInformation2D aViewInformation2D( - basegfx::B2DHomMatrix(), - rOutputDevice.GetViewTransformation(), - basegfx::B2DRange(), - 0, - 0.0, - 0); - - // create processor - drawinglayer::processor2d::BaseProcessor2D* pProcessor = ::sdr::contact::createBaseProcessor2DFromOutputDevice( - rOutputDevice, - aViewInformation2D); - - if(pProcessor) - { - // prepare primitives - const drawinglayer::primitive2d::Primitive2DReference aPolygonMarkerPrimitive2D( - new drawinglayer::primitive2d::PolygonMarkerPrimitive2D( - rPolygon, - getOverlayManager()->getStripeColorA().getBColor(), - getOverlayManager()->getStripeColorB().getBColor(), - getOverlayManager()->getStripeLengthPixel())); - const drawinglayer::primitive2d::Primitive2DSequence aSequence(&aPolygonMarkerPrimitive2D, 1); - - pProcessor->process(aSequence); - - delete pProcessor; - } - } - else - { - const sal_uInt32 nLenPixel(getOverlayManager()->getStripeLengthPixel()); - const Size aDashSizePixel(nLenPixel, nLenPixel); - const Size aDashSizeLogic(rOutputDevice.PixelToLogic(aDashSizePixel)); - const double fDashLength(aDashSizeLogic.Width()); - const double fFullDotDashLength(fDashLength + fDashLength); - - // fill DashDot vector - ::std::vector<double> aDotDashArray; - aDotDashArray.push_back(fDashLength); - aDotDashArray.push_back(fDashLength); - - // get dash polygons - basegfx::B2DPolyPolygon aStripesA; - basegfx::B2DPolyPolygon aStripesB; - basegfx::tools::applyLineDashing(rPolygon, aDotDashArray, &aStripesA, &aStripesB, fFullDotDashLength); - - // draw stripes A - if(aStripesA.count()) - { - rOutputDevice.SetFillColor(); - rOutputDevice.SetLineColor(getOverlayManager()->getStripeColorA()); - - for(sal_uInt32 a(0L); a < aStripesA.count();a ++) - { - rOutputDevice.DrawPolyLine(aStripesA.getB2DPolygon(a)); - } - } - - // draw stripes B - if(aStripesB.count()) - { - rOutputDevice.SetFillColor(); - rOutputDevice.SetLineColor(getOverlayManager()->getStripeColorB()); + // remember new value + mbAllowsAntiAliase = bNew; - for(sal_uInt32 a(0L); a < aStripesB.count();a ++) - { - rOutputDevice.DrawPolyLine(aStripesB.getB2DPolygon(a)); - } - } - } + // register change (after change) + objectChange(); } } OverlayObject::OverlayObject(Color aBaseColor) - : Event(0L), - mpOverlayManager(0L), - mpNext(0L), - mpPrevious(0L), + : Event(0), + mpOverlayManager(0), maBaseColor(aBaseColor), - mbIsVisible(sal_True), - mbIsChanged(sal_True), - mbIsHittable(sal_True), - mbAllowsAnimation(sal_False) + mbIsVisible(true), + mbIsHittable(true), + mbAllowsAnimation(false), + mbAllowsAntiAliase(true) { } OverlayObject::~OverlayObject() { - DBG_ASSERT(0L == mpOverlayManager, - "OverlayObject is destructed which is still registered at OverlayManager (!)"); + OSL_ENSURE(0 == getOverlayManager(), "OverlayObject is destructed which is still registered at OverlayManager (!)"); } - sal_Bool OverlayObject::isHit(const basegfx::B2DPoint& rPos, double fTol) const + drawinglayer::primitive2d::Primitive2DSequence OverlayObject::getOverlayObjectPrimitive2DSequence() const { - if(isHittable()) + if(!getPrimitive2DSequence().hasElements()) { - if(0.0 != fTol) - { - basegfx::B2DRange aRange(getBaseRange()); - aRange.grow(fTol); - return aRange.isInside(rPos); - } - else - { - return getBaseRange().isInside(rPos); - } + // no existing sequence; create one + const_cast< OverlayObject* >(this)->setPrimitive2DSequence( + const_cast< OverlayObject* >(this)->createOverlayObjectPrimitive2DSequence()); } - return sal_False; + return getPrimitive2DSequence(); } const basegfx::B2DRange& OverlayObject::getBaseRange() const { - if(mbIsChanged) + if(getOverlayManager() && maBaseRange.isEmpty()) { - if(mpOverlayManager) + const drawinglayer::primitive2d::Primitive2DSequence& rSequence = getOverlayObjectPrimitive2DSequence(); + + if(rSequence.hasElements()) { - ((::sdr::overlay::OverlayObject*)this)->createBaseRange(mpOverlayManager->getOutputDevice()); - } + const drawinglayer::geometry::ViewInformation2D aViewInformation2D(getOverlayManager()->getCurrentViewInformation2D()); - ((::sdr::overlay::OverlayObject*)this)->mbIsChanged = sal_False; + const_cast< sdr::overlay::OverlayObject* >(this)->maBaseRange = + drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(rSequence, aViewInformation2D); + } } return maBaseRange; } - void OverlayObject::setVisible(sal_Bool bNew) + void OverlayObject::setVisible(bool bNew) { - if(bNew != mbIsVisible) + if(bNew != (bool)mbIsVisible) { // remember new value mbIsVisible = bNew; @@ -262,9 +149,9 @@ namespace sdr } } - void OverlayObject::setHittable(sal_Bool bNew) + void OverlayObject::setHittable(bool bNew) { - if(bNew != mbIsHittable) + if(bNew != (bool)mbIsHittable) { // remember new value mbIsHittable = bNew; @@ -291,11 +178,6 @@ namespace sdr // default does not register again } - void OverlayObject::zoomHasChanged() - { - // default does not need to do anything - } - void OverlayObject::stripeDefinitionHasChanged() { // default does not need to do anything @@ -330,15 +212,6 @@ namespace sdr objectChange(); } } - - void OverlayObjectWithBasePosition::transform(const basegfx::B2DHomMatrix& rMatrix) - { - if(!rMatrix.isIdentity()) - { - basegfx::B2DPoint aNewBasePosition = rMatrix * getBasePosition(); - setBasePosition(aNewBasePosition); - } - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlayobjectcell.cxx b/svx/source/sdr/overlay/overlayobjectcell.cxx index 25d2dbbdd31b..5df0fc85f8f9 100644 --- a/svx/source/sdr/overlay/overlayobjectcell.cxx +++ b/svx/source/sdr/overlay/overlayobjectcell.cxx @@ -35,6 +35,11 @@ #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/unifiedalphaprimitive2d.hxx> +#include <drawinglayer/primitive2d/invertprimitive2d.hxx> using namespace ::basegfx; @@ -48,83 +53,60 @@ namespace sdr mePaintType( eType ), maRectangles( rRects ) { + // no AA for selection overlays + allowAntiAliase(false); } OverlayObjectCell::~OverlayObjectCell() { } - void OverlayObjectCell::drawGeometry(OutputDevice& rOutputDevice) + drawinglayer::primitive2d::Primitive2DSequence OverlayObjectCell::createOverlayObjectPrimitive2DSequence() { - // set colors - rOutputDevice.SetLineColor(); - rOutputDevice.SetFillColor(getBaseColor()); + drawinglayer::primitive2d::Primitive2DSequence aRetval; + const sal_uInt32 nCount(maRectangles.size()); - if ( mePaintType == CELL_OVERLAY_INVERT ) + if(nCount) { - rOutputDevice.Push(); - rOutputDevice.SetRasterOp( ROP_XOR ); - rOutputDevice.SetFillColor( COL_WHITE ); - } - - for(sal_uInt32 a(0L);a < maRectangles.size(); a++) - { - const basegfx::B2DRange& rRange(maRectangles[a]); - const Rectangle aRectangle(fround(rRange.getMinX()), fround(rRange.getMinY()), fround(rRange.getMaxX()), fround(rRange.getMaxY())); + const basegfx::BColor aRGBColor(getBaseColor().getBColor()); + aRetval.realloc(nCount); - switch(mePaintType) + // create primitives for all ranges + for(sal_uInt32 a(0); a < nCount; a++) { - case CELL_OVERLAY_INVERT : - { - rOutputDevice.DrawRect( aRectangle ); + const basegfx::B2DRange& rRange(maRectangles[a]); + const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(rRange)); - // if(OUTDEV_WINDOW == rOutputDevice.GetOutDevType()) - // { - // ((Window&)rOutputDevice).Invert(aRectangle, INVERT_HIGHLIGHT); - // } - - break; - } - case CELL_OVERLAY_HATCH : - { - rOutputDevice.DrawHatch(PolyPolygon(Polygon(aRectangle)), Hatch(HATCH_SINGLE, getBaseColor(), 2, 450)); - break; - } - case CELL_OVERLAY_TRANSPARENT : - { - rOutputDevice.DrawTransparent(PolyPolygon(Polygon(aRectangle)), 50); - break; - } - case CELL_OVERLAY_LIGHT_TRANSPARENT : - { - rOutputDevice.DrawTransparent(PolyPolygon(Polygon(aRectangle)), 80); - break; - } + aRetval[a] = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aPolygon), + aRGBColor)); } - } - if ( mePaintType == CELL_OVERLAY_INVERT ) - rOutputDevice.Pop(); - } - void OverlayObjectCell::createBaseRange(OutputDevice& /*rOutputDevice*/) - { - maBaseRange.reset(); + if(mePaintType == CELL_OVERLAY_TRANSPARENT) + { + // embed in 50% transparent paint + const drawinglayer::primitive2d::Primitive2DReference aUnifiedAlpha( + new drawinglayer::primitive2d::UnifiedAlphaPrimitive2D( + aRetval, + 0.5)); - for(sal_uInt32 a(0L); a < maRectangles.size(); a++) - { - maBaseRange.expand(maRectangles[a]); - } - } + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedAlpha, 1); + } + else // CELL_OVERLAY_INVERT + { + // embed in invert primitive + const drawinglayer::primitive2d::Primitive2DReference aInvert( + new drawinglayer::primitive2d::InvertPrimitive2D( + aRetval)); - void OverlayObjectCell::transform(const basegfx::B2DHomMatrix& rMatrix) - { - for(sal_uInt32 a(0L); a < maRectangles.size(); a++) - { - maRectangles[a].transform(rMatrix); + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aInvert, 1); + } } - } + return aRetval; + } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlayobjectlist.cxx b/svx/source/sdr/overlay/overlayobjectlist.cxx index 3c9107d94bfe..370b6d66c225 100644 --- a/svx/source/sdr/overlay/overlayobjectlist.cxx +++ b/svx/source/sdr/overlay/overlayobjectlist.cxx @@ -40,6 +40,8 @@ // get access to basic algos like ::std::find #include <algorithm> +#include <drawinglayer/processor2d/hittestprocessor2d.hxx> + ////////////////////////////////////////////////////////////////////////////// namespace sdr @@ -73,63 +75,92 @@ namespace sdr void OverlayObjectList::remove(OverlayObject& rOverlayObject) { const OverlayObjectVector::iterator aFindResult = ::std::find(maVector.begin(), maVector.end(), &rOverlayObject); - DBG_ASSERT((aFindResult != maVector.end()), - "OverlayObjectList::remove: Could not find given object in list (!)"); - maVector.erase(aFindResult); + const bool bFound(aFindResult != maVector.end()); + OSL_ENSURE(bFound, "Could not find given object in list (!)"); + + if(bFound) + { + maVector.erase(aFindResult); + } } - sal_Bool OverlayObjectList::isHit(const basegfx::B2DPoint& rPos, double fTol) const + 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(0.0 == fTol) + if(pManager) { - ::sdr::overlay::OverlayObject* pCandidate = *aStart; - OverlayManager* pManager = pCandidate->getOverlayManager(); - - if(pManager) + if(0.0 == fLogicTolerance) { - Size aSizeLogic(pManager->getOutputDevice().PixelToLogic( + const Size aSizeLogic(pManager->getOutputDevice().PixelToLogic( Size(DEFAULT_VALUE_FOR_HITTEST_PIXEL, DEFAULT_VALUE_FOR_HITTEST_PIXEL))); - fTol = aSizeLogic.Width(); + fLogicTolerance = aSizeLogic.Width(); } - } - for(; aStart != maVector.end(); aStart++) - { - ::sdr::overlay::OverlayObject* pCandidate = *aStart; + const drawinglayer::geometry::ViewInformation2D aViewInformation2D(pManager->getCurrentViewInformation2D()); + drawinglayer::processor2d::HitTestProcessor2D aHitTestProcessor2D( + aViewInformation2D, + rLogicPosition, + fLogicTolerance, + false); - if(pCandidate->isHit(rPos, fTol)) + for(; aStart != maVector.end(); aStart++) { - return sal_True; + 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 sal_False; + return false; } - sal_Bool OverlayObjectList::isHitPixel(const Point& rPos, sal_uInt32 nTol) const + bool OverlayObjectList::isHitPixel(const Point& rDiscretePosition, sal_uInt32 nDiscreteTolerance) const { if(maVector.size()) { OverlayObjectVector::const_iterator aStart(maVector.begin()); - ::sdr::overlay::OverlayObject* pCandidate = *aStart; + sdr::overlay::OverlayObject* pCandidate = *aStart; OverlayManager* pManager = pCandidate->getOverlayManager(); if(pManager) { - Point aPosLogic(pManager->getOutputDevice().PixelToLogic(rPos)); - Size aSizeLogic(pManager->getOutputDevice().PixelToLogic(Size(nTol, nTol))); - basegfx::B2DPoint aPosition(aPosLogic.X(), aPosLogic.Y()); + const Point aPosLogic(pManager->getOutputDevice().PixelToLogic(rDiscretePosition)); + const basegfx::B2DPoint aPosition(aPosLogic.X(), aPosLogic.Y()); - return isHit(aPosition, (double)aSizeLogic.Width()); + if(nDiscreteTolerance) + { + const Size aSizeLogic(pManager->getOutputDevice().PixelToLogic(Size(nDiscreteTolerance, nDiscreteTolerance))); + return isHitLogic(aPosition, (double)aSizeLogic.Width()); + } + else + { + return isHitLogic(aPosition); + } } } - return sal_False; + return false; } basegfx::B2DRange OverlayObjectList::getBaseRange() const @@ -149,20 +180,6 @@ namespace sdr return aRetval; } - - void OverlayObjectList::transform(const basegfx::B2DHomMatrix& rMatrix) - { - if(!rMatrix.isIdentity() && maVector.size()) - { - OverlayObjectVector::iterator aStart(maVector.begin()); - - for(; aStart != maVector.end(); aStart++) - { - ::sdr::overlay::OverlayObject* pCandidate = *aStart; - pCandidate->transform(rMatrix); - } - } - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlaypolypolygon.cxx b/svx/source/sdr/overlay/overlaypolypolygon.cxx index 3d859a9b0659..a94dbdb9d1c4 100644 --- a/svx/source/sdr/overlay/overlaypolypolygon.cxx +++ b/svx/source/sdr/overlay/overlaypolypolygon.cxx @@ -35,6 +35,8 @@ #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> ////////////////////////////////////////////////////////////////////////////// @@ -42,21 +44,33 @@ namespace sdr { namespace overlay { - void OverlayPolyPolygonStriped::drawGeometry(OutputDevice& rOutputDevice) + drawinglayer::primitive2d::Primitive2DSequence OverlayPolyPolygonStriped::createOverlayObjectPrimitive2DSequence() { - if(maPolyPolygon.count()) + drawinglayer::primitive2d::Primitive2DSequence aRetval; + + if(getOverlayManager()) { - for(sal_uInt32 a(0L); a < maPolyPolygon.count(); a++) - { - ImpDrawPolygonStriped(rOutputDevice, maPolyPolygon.getB2DPolygon(a)); - } + 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::createBaseRange(OutputDevice& /*rOutputDevice*/) + void OverlayPolyPolygonStriped::stripeDefinitionHasChanged() { - // use tooling to get range from PolyPolygon - maBaseRange = basegfx::tools::getRange(maPolyPolygon); + // react on OverlayManager's stripe definition change + objectChange(); } OverlayPolyPolygonStriped::OverlayPolyPolygonStriped( @@ -81,67 +95,6 @@ namespace sdr objectChange(); } } - - sal_Bool OverlayPolyPolygonStriped::isHit(const basegfx::B2DPoint& rPos, double fTol) const - { - if(isHittable()) - { - return basegfx::tools::isInEpsilonRange(maPolyPolygon, rPos, fTol); - } - - return sal_False; - } - - void OverlayPolyPolygonStriped::transform(const basegfx::B2DHomMatrix& rMatrix) - { - if(!rMatrix.isIdentity()) - { - // transform maPolyPolygon - maPolyPolygon.transform(rMatrix); - - // register change (after change) - objectChange(); - } - } - } // end of namespace overlay -} // end of namespace sdr - -////////////////////////////////////////////////////////////////////////////// - -namespace sdr -{ - namespace overlay - { - void OverlayPolyPolygon::drawGeometry(OutputDevice& rOutputDevice) - { - if(maPolyPolygon.count()) - { - rOutputDevice.SetLineColor(getBaseColor()); - rOutputDevice.SetFillColor(); - - // iterate self, else the single polygons will be closed when - // using DrawPolyPolygon - for(sal_uInt32 a(0L); a < maPolyPolygon.count(); a++) - { - const Polygon aPaintPoly(maPolyPolygon.getB2DPolygon(a)); - rOutputDevice.DrawPolyLine(aPaintPoly); - } - } - } - - OverlayPolyPolygon::OverlayPolyPolygon( - const basegfx::B2DPolyPolygon& rPolyPolygon, - Color aPolygonColor) - : OverlayPolyPolygonStriped(rPolyPolygon) - { - // set base color here, OverlayCrosshairStriped constructor has set - // it to it's own default. - maBaseColor = aPolygonColor; - } - - OverlayPolyPolygon::~OverlayPolyPolygon() - { - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlayprimitive2dsequenceobject.cxx b/svx/source/sdr/overlay/overlayprimitive2dsequenceobject.cxx index 1383a296709b..c43a9494901f 100644 --- a/svx/source/sdr/overlay/overlayprimitive2dsequenceobject.cxx +++ b/svx/source/sdr/overlay/overlayprimitive2dsequenceobject.cxx @@ -43,55 +43,9 @@ namespace sdr { namespace overlay { - void OverlayPrimitive2DSequenceObject::drawGeometry(OutputDevice& rOutputDevice) + drawinglayer::primitive2d::Primitive2DSequence OverlayPrimitive2DSequenceObject::createOverlayObjectPrimitive2DSequence() { - if(getOverlayManager()) - { - // prepare ViewInformation2D - const drawinglayer::geometry::ViewInformation2D aViewInformation2D( - basegfx::B2DHomMatrix(), - rOutputDevice.GetViewTransformation(), - basegfx::B2DRange(), - 0, - 0.0, - 0); - - // create processor - drawinglayer::processor2d::BaseProcessor2D* pProcessor = ::sdr::contact::createBaseProcessor2DFromOutputDevice( - rOutputDevice, - aViewInformation2D); - - if(pProcessor) - { - pProcessor->process(getSequence()); - - delete pProcessor; - } - } - } - - void OverlayPrimitive2DSequenceObject::createBaseRange(OutputDevice& rOutputDevice) - { - const drawinglayer::geometry::ViewInformation2D aViewInformation2D( - basegfx::B2DHomMatrix(), - rOutputDevice.GetViewTransformation(), - basegfx::B2DRange(), - 0, - 0.0, - 0); - - maBaseRange = drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence( - getSequence(), aViewInformation2D); - } - - sal_Bool OverlayPrimitive2DSequenceObject::isHit(const basegfx::B2DPoint& /*rPos*/, double /*fTol*/) const - { - if(isHittable()) - { - return false; - } - - return false; + return getSequence(); } OverlayPrimitive2DSequenceObject::OverlayPrimitive2DSequenceObject(const drawinglayer::primitive2d::Primitive2DSequence& rSequence) diff --git a/svx/source/sdr/overlay/overlayrollingrectangle.cxx b/svx/source/sdr/overlay/overlayrollingrectangle.cxx index ea5be0e4f400..42a3575288be 100644 --- a/svx/source/sdr/overlay/overlayrollingrectangle.cxx +++ b/svx/source/sdr/overlay/overlayrollingrectangle.cxx @@ -35,6 +35,11 @@ #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> ////////////////////////////////////////////////////////////////////////////// @@ -42,65 +47,59 @@ namespace sdr { namespace overlay { - void OverlayRollingRectangleStriped::drawGeometry(OutputDevice& rOutputDevice) + drawinglayer::primitive2d::Primitive2DSequence OverlayRollingRectangleStriped::createOverlayObjectPrimitive2DSequence() { - const basegfx::B2DRange aRange(getBasePosition(), getSecondPosition()); + drawinglayer::primitive2d::Primitive2DSequence aRetval; - if(getShowBounds()) + if(getOverlayManager() && (getShowBounds() || getExtendedLines())) { - ImpDrawRangeStriped(rOutputDevice, aRange); - } - - if(getExtendedLines()) - { - const Point aEmptyPoint; - const Rectangle aVisiblePixel(aEmptyPoint, rOutputDevice.GetOutputSizePixel()); - const Rectangle aVisibleLogic(rOutputDevice.PixelToLogic(aVisiblePixel)); - - // Left lines - ImpDrawLineStriped(rOutputDevice, aVisibleLogic.Left(), aRange.getMinY(), aRange.getMinX(), aRange.getMinY()); - ImpDrawLineStriped(rOutputDevice, aVisibleLogic.Left(), aRange.getMaxY(), aRange.getMinX(), aRange.getMaxY()); - - // Right lines - ImpDrawLineStriped(rOutputDevice, aRange.getMaxX(), aRange.getMinY(), aVisibleLogic.Right(), aRange.getMinY()); - ImpDrawLineStriped(rOutputDevice, aRange.getMaxX(), aRange.getMaxY(), aVisibleLogic.Right(), aRange.getMaxY()); + 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()); - // Top lines - ImpDrawLineStriped(rOutputDevice, aRange.getMinX(), aVisibleLogic.Top(), aRange.getMinX(), aRange.getMinY()); - ImpDrawLineStriped(rOutputDevice, aRange.getMaxX(), aVisibleLogic.Top(), aRange.getMaxX(), aRange.getMinY()); + 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); + } - // Bottom lines - ImpDrawLineStriped(rOutputDevice, aRange.getMinX(), aRange.getMaxY(), aRange.getMinX(), aVisibleLogic.Bottom()); - ImpDrawLineStriped(rOutputDevice, aRange.getMaxX(), aRange.getMaxY(), aRange.getMaxX(), aVisibleLogic.Bottom()); + 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::createBaseRange(OutputDevice& rOutputDevice) + void OverlayRollingRectangleStriped::stripeDefinitionHasChanged() { - // reset range and expand it - maBaseRange.reset(); - - if(getExtendedLines()) - { - const Point aEmptyPoint; - const Rectangle aVisiblePixel(aEmptyPoint, rOutputDevice.GetOutputSizePixel()); - const Rectangle aVisibleLogic(rOutputDevice.PixelToLogic(aVisiblePixel)); - maBaseRange.expand(basegfx::B2DPoint(aVisibleLogic.Left(), aVisibleLogic.Top())); - maBaseRange.expand(basegfx::B2DPoint(aVisibleLogic.Right(), aVisibleLogic.Bottom())); - } - - if(getShowBounds()) - { - maBaseRange.expand(getBasePosition()); - maBaseRange.expand(getSecondPosition()); - } + // react on OverlayManager's stripe definition change + objectChange(); } OverlayRollingRectangleStriped::OverlayRollingRectangleStriped( const basegfx::B2DPoint& rBasePos, const basegfx::B2DPoint& rSecondPos, - sal_Bool bExtendedLines, - sal_Bool bShowBounds) + bool bExtendedLines, + bool bShowBounds) : OverlayObjectWithBasePosition(rBasePos, Color(COL_BLACK)), maSecondPosition(rSecondPos), mbExtendedLines(bExtendedLines), @@ -124,9 +123,9 @@ namespace sdr } } - void OverlayRollingRectangleStriped::setExtendedLines(sal_Bool bNew) + void OverlayRollingRectangleStriped::setExtendedLines(bool bNew) { - if(bNew != mbExtendedLines) + if(bNew != (bool)mbExtendedLines) { // remember new value mbExtendedLines = bNew; @@ -136,9 +135,9 @@ namespace sdr } } - void OverlayRollingRectangleStriped::setShowBounds(sal_Bool bNew) + void OverlayRollingRectangleStriped::setShowBounds(bool bNew) { - if(bNew != mbShowBounds) + if(bNew != (bool)mbShowBounds) { // remember new value mbShowBounds = bNew; @@ -147,138 +146,6 @@ namespace sdr objectChange(); } } - - sal_Bool OverlayRollingRectangleStriped::isHit(const basegfx::B2DPoint& rPos, double fTol) const - { - if(isHittable()) - { - if(getExtendedLines()) - { - const basegfx::B2DRange aRange(getBaseRange()); - const basegfx::B2DPoint aMinimum(aRange.getMinimum()); - const basegfx::B2DPoint aMaximum(aRange.getMaximum()); - - // test upper line horizontal - if(rPos.getY() > (aMinimum.getY() - fTol) && rPos.getY() < (aMinimum.getY() + fTol)) - { - return sal_True; - } - - // test lower line horizontal - if(rPos.getY() > (aMaximum.getY() - fTol) && rPos.getY() < (aMaximum.getY() + fTol)) - { - return sal_True; - } - - // test left line vertical - if(rPos.getX() > (aMinimum.getX() - fTol) && rPos.getX() < (aMinimum.getX() + fTol)) - { - return sal_True; - } - - // test rightline vertical - if(rPos.getX() > (aMaximum.getX() - fTol) && rPos.getX() < (aMaximum.getX() + fTol)) - { - return sal_True; - } - } - - if(getShowBounds()) - { - // test for inside grown range, outside shrinked one to test for border - // hit without interiour - basegfx::B2DRange aOuterRange(getBaseRange()); - aOuterRange.grow(fTol); - - if(aOuterRange.isInside(rPos)) - { - basegfx::B2DRange aInnerRange(getBaseRange()); - aInnerRange.grow(-fTol); - - return !aInnerRange.isInside(rPos); - } - } - } - - return sal_False; - } - - void OverlayRollingRectangleStriped::transform(const basegfx::B2DHomMatrix& rMatrix) - { - if(!rMatrix.isIdentity()) - { - // transform base position - OverlayObjectWithBasePosition::transform(rMatrix); - - // transform maSecondPosition - const basegfx::B2DPoint aNewSecondPosition = rMatrix * getSecondPosition(); - setSecondPosition(aNewSecondPosition); - } - } - } // end of namespace overlay -} // end of namespace sdr - -////////////////////////////////////////////////////////////////////////////// - -namespace sdr -{ - namespace overlay - { - void OverlayRollingRectangle::drawGeometry(OutputDevice& rOutputDevice) - { - const Point aStart(FRound(getBasePosition().getX()), FRound(getBasePosition().getY())); - const Point aEnd(FRound(getSecondPosition().getX()), FRound(getSecondPosition().getY())); - Rectangle aRectangle(aStart, aEnd); - aRectangle.Justify(); - - if(getShowBounds()) - { - rOutputDevice.SetLineColor(getBaseColor()); - rOutputDevice.SetFillColor(); - - rOutputDevice.DrawRect(aRectangle); - } - - if(getExtendedLines()) - { - const Point aEmptyPoint; - const Rectangle aVisiblePixel(aEmptyPoint, rOutputDevice.GetOutputSizePixel()); - const Rectangle aVisibleLogic(rOutputDevice.PixelToLogic(aVisiblePixel)); - - // Left lines - rOutputDevice.DrawLine(Point(aVisibleLogic.Left(), aRectangle.Top()), aRectangle.TopLeft()); - rOutputDevice.DrawLine(Point(aVisibleLogic.Left(), aRectangle.Bottom()), aRectangle.BottomLeft()); - - // Right lines - rOutputDevice.DrawLine(aRectangle.TopRight(), Point(aVisibleLogic.Right(), aRectangle.Top())); - rOutputDevice.DrawLine(aRectangle.BottomRight(), Point(aVisibleLogic.Right(), aRectangle.Bottom())); - - // Top lines - rOutputDevice.DrawLine(Point(aRectangle.Left(), aVisibleLogic.Top()), aRectangle.TopLeft()); - rOutputDevice.DrawLine(Point(aRectangle.Right(), aVisibleLogic.Top()), aRectangle.TopRight()); - - // Bottom lines - rOutputDevice.DrawLine(aRectangle.BottomLeft(), Point(aRectangle.Left(), aVisibleLogic.Bottom())); - rOutputDevice.DrawLine(aRectangle.BottomRight(), Point(aRectangle.Right(), aVisibleLogic.Bottom())); - } - } - - OverlayRollingRectangle::OverlayRollingRectangle( - const basegfx::B2DPoint& rBasePos, - const basegfx::B2DPoint& rSecondPos, - Color aLineColor, - sal_Bool bExtendedLines, - sal_Bool bShowBounds) - : OverlayRollingRectangleStriped(rBasePos, rSecondPos, bExtendedLines, bShowBounds) - { - // set base color here, OverlayCrosshairStriped constructor has set - // it to it's own default. - maBaseColor = aLineColor; - } - - OverlayRollingRectangle::~OverlayRollingRectangle() - { - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/overlay/overlaysdrobject.cxx b/svx/source/sdr/overlay/overlaysdrobject.cxx deleted file mode 100644 index 7f1dbf2d5a4f..000000000000 --- a/svx/source/sdr/overlay/overlaysdrobject.cxx +++ /dev/null @@ -1,87 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: overlaysdrobject.cxx,v $ - * $Revision: 1.7 $ - * - * 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/overlaysdrobject.hxx> -#include <svx/svdobj.hxx> - -////////////////////////////////////////////////////////////////////////////// - -namespace sdr -{ - namespace overlay - { - void OverlaySdrObject::drawGeometry(OutputDevice& rOutputDevice) - { - mrSdrObject.SingleObjectPainter(rOutputDevice); - } - - void OverlaySdrObject::createBaseRange(OutputDevice& /*rOutputDevice*/) - { - // reset range and expand it - maBaseRange.reset(); - - // get BoundRect - Rectangle aBoundRect(mrSdrObject.GetCurrentBoundRect()); - const basegfx::B2DPoint aTopLeft(aBoundRect.Left(), aBoundRect.Top()); - const basegfx::B2DPoint aBottomRight(aBoundRect.Right(), aBoundRect.Bottom()); - - maBaseRange.expand(aTopLeft); - maBaseRange.expand(aBottomRight); - } - - OverlaySdrObject::OverlaySdrObject( - const basegfx::B2DPoint& rBasePos, - const SdrObject& rObject) - : OverlayObjectWithBasePosition(rBasePos, Color(COL_BLACK)), - mrSdrObject(rObject) - { - } - - OverlaySdrObject::~OverlaySdrObject() - { - } - - sal_Bool OverlaySdrObject::isHit(const basegfx::B2DPoint& rPos, double fTol) const - { - if(isHittable()) - { - Point aPnt( (long)rPos.getX(), (long)rPos.getY() ); - return mrSdrObject.CheckHit(aPnt, (USHORT)fTol, 0) != 0 ? sal_True : sal_False; - } - - return sal_False; - } - } // 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..2411ca3c31b4 --- /dev/null +++ b/svx/source/sdr/overlay/overlayselection.cxx @@ -0,0 +1,233 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: overlayline.cxx,v $ + * $Revision: 1.5 $ + * + * 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/unifiedalphaprimitive2d.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 basegfx::BColor aRGBColor(getBaseColor().getBColor()); + aRetval.realloc(nCount); + + 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(OVERLAY_INVERT == maLastOverlayType) + { + // 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 aUnifiedAlpha( + new drawinglayer::primitive2d::UnifiedAlphaPrimitive2D( + 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] = aUnifiedAlpha; + aRetval[1] = aSelectionOutline; + } + else + { + // just add transparent part + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedAlpha, 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..664c487c7e43 --- /dev/null +++ b/svx/source/sdr/overlay/overlaytools.cxx @@ -0,0 +1,498 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: overlayobject.cxx,v $ + * $Revision: 1.6 $ + * + * 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> + +////////////////////////////////////////////////////////////////////////////// + +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::createLocalDecomposition(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::createLocalDecomposition(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::createLocalDecomposition(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())) + { + basegfx::B2DHomMatrix aTransform; + + aTransform.translate(-getObjectRange().getMinX(), -getObjectRange().getMinY()); + aTransform.rotate(getRotation()); + aTransform.translate(getObjectRange().getMinX(), getObjectRange().getMinY()); + + 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::createLocalDecomposition(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::createLocalDecomposition(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 index 1d01ab24e388..74f23b8f845c 100644 --- a/svx/source/sdr/overlay/overlaytriangle.cxx +++ b/svx/source/sdr/overlay/overlaytriangle.cxx @@ -37,6 +37,9 @@ #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> ////////////////////////////////////////////////////////////////////////////// @@ -44,7 +47,7 @@ namespace sdr { namespace overlay { - void OverlayTriangleStriped::drawGeometry(OutputDevice& rOutputDevice) + drawinglayer::primitive2d::Primitive2DSequence OverlayTriangle::createOverlayObjectPrimitive2DSequence() { basegfx::B2DPolygon aPolygon; @@ -53,33 +56,30 @@ namespace sdr aPolygon.append(getThirdPosition()); aPolygon.setClosed(true); - ImpDrawPolygonStriped(rOutputDevice, aPolygon); - } + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aPolygon), + getBaseColor().getBColor())); - void OverlayTriangleStriped::createBaseRange(OutputDevice& /*rOutputDevice*/) - { - // reset range and expand it - maBaseRange.reset(); - maBaseRange.expand(getBasePosition()); - maBaseRange.expand(getSecondPosition()); - maBaseRange.expand(getThirdPosition()); + return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); } - OverlayTriangleStriped::OverlayTriangleStriped( + OverlayTriangle::OverlayTriangle( const basegfx::B2DPoint& rBasePos, const basegfx::B2DPoint& rSecondPos, - const basegfx::B2DPoint& rThirdPos) - : OverlayObjectWithBasePosition(rBasePos, Color(COL_BLACK)), + const basegfx::B2DPoint& rThirdPos, + Color aTriangleColor) + : OverlayObjectWithBasePosition(rBasePos, aTriangleColor), maSecondPosition(rSecondPos), maThirdPosition(rThirdPos) { } - OverlayTriangleStriped::~OverlayTriangleStriped() + OverlayTriangle::~OverlayTriangle() { } - void OverlayTriangleStriped::setSecondPosition(const basegfx::B2DPoint& rNew) + void OverlayTriangle::setSecondPosition(const basegfx::B2DPoint& rNew) { if(rNew != maSecondPosition) { @@ -91,7 +91,7 @@ namespace sdr } } - void OverlayTriangleStriped::setThirdPosition(const basegfx::B2DPoint& rNew) + void OverlayTriangle::setThirdPosition(const basegfx::B2DPoint& rNew) { if(rNew != maThirdPosition) { @@ -102,96 +102,6 @@ namespace sdr objectChange(); } } - - sal_Bool OverlayTriangleStriped::isHit(const basegfx::B2DPoint& rPos, double fTol) const - { - if(isHittable()) - { - // test with all lines and epsilon-range - if(basegfx::tools::isInEpsilonRange(getBasePosition(), getThirdPosition(), rPos, fTol)) - { - return sal_True; - } - else if(basegfx::tools::isInEpsilonRange(getSecondPosition(), getBasePosition(), rPos, fTol)) - { - return sal_True; - } - else if(basegfx::tools::isInEpsilonRange(getThirdPosition(), getSecondPosition(), rPos, fTol)) - { - return sal_True; - } - - // test if inside triangle - basegfx::B2DPolygon aTestPoly; - aTestPoly.append(getBasePosition()); - aTestPoly.append(getSecondPosition()); - aTestPoly.append(getThirdPosition()); - aTestPoly.setClosed(true); - - return basegfx::tools::isInside(aTestPoly, rPos); - } - - return sal_False; - } - - void OverlayTriangleStriped::transform(const basegfx::B2DHomMatrix& rMatrix) - { - if(!rMatrix.isIdentity()) - { - // transform base position - OverlayObjectWithBasePosition::transform(rMatrix); - - // transform maSecondPosition - const basegfx::B2DPoint aNewSecondPosition = rMatrix * getSecondPosition(); - setSecondPosition(aNewSecondPosition); - - // transform maThirdPosition - const basegfx::B2DPoint aNewThirdPosition = rMatrix * getThirdPosition(); - setThirdPosition(aNewThirdPosition); - } - } - } // end of namespace overlay -} // end of namespace sdr - -////////////////////////////////////////////////////////////////////////////// - -namespace sdr -{ - namespace overlay - { - void OverlayTriangle::drawGeometry(OutputDevice& rOutputDevice) - { - Polygon aPolygon(4); - Point aPosition(FRound(getBasePosition().getX()), FRound(getBasePosition().getY())); - aPolygon[0] = aPolygon[3] = aPosition; - aPosition.X() = FRound(getSecondPosition().getX()); - aPosition.Y() = FRound(getSecondPosition().getY()); - aPolygon[1] = aPosition; - aPosition.X() = FRound(getThirdPosition().getX()); - aPosition.Y() = FRound(getThirdPosition().getY()); - aPolygon[2] = aPosition; - - rOutputDevice.SetLineColor(); - rOutputDevice.SetFillColor(getBaseColor()); - - rOutputDevice.DrawPolygon(aPolygon); - } - - OverlayTriangle::OverlayTriangle( - const basegfx::B2DPoint& rBasePos, - const basegfx::B2DPoint& rSecondPos, - const basegfx::B2DPoint& rThirdPos, - Color aTriangleColor) - : OverlayTriangleStriped(rBasePos, rSecondPos, rThirdPos) - { - // set base color here, OverlayCrosshairStriped constructor has set - // it to it's own default. - maBaseColor = aTriangleColor; - } - - OverlayTriangle::~OverlayTriangle() - { - } } // end of namespace overlay } // end of namespace sdr diff --git a/svx/source/sdr/primitive2d/makefile.mk b/svx/source/sdr/primitive2d/makefile.mk index e9e976d434ed..7510b6a23b35 100644 --- a/svx/source/sdr/primitive2d/makefile.mk +++ b/svx/source/sdr/primitive2d/makefile.mk @@ -51,6 +51,7 @@ SLOFILES=\ $(SLO)$/sdrcaptionprimitive2d.obj \ $(SLO)$/sdrgrafprimitive2d.obj \ $(SLO)$/sdrole2primitive2d.obj \ + $(SLO)$/sdrolecontentprimitive2d.obj \ $(SLO)$/sdrpathprimitive2d.obj \ $(SLO)$/sdrprimitivetools.obj \ $(SLO)$/sdrmeasureprimitive2d.obj \ diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx index a330362dddbc..277ee70f82ca 100644 --- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx +++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx @@ -473,7 +473,14 @@ namespace drawinglayer return pRetval; } - attribute::SdrTextAttribute* createNewSdrTextAttribute(const SfxItemSet& rSet, const SdrText& rText) + // #i101508# Support handing over given text-to-border distances + attribute::SdrTextAttribute* createNewSdrTextAttribute( + const SfxItemSet& rSet, + const SdrText& rText, + const sal_Int32* pLeft, + const sal_Int32* pUpper, + const sal_Int32* pRight, + const sal_Int32* pLower) { attribute::SdrTextAttribute* pRetval(0); const SdrTextObj& rTextObj = rText.GetObject(); @@ -519,10 +526,10 @@ namespace drawinglayer rText, aOutlinerParaObject, ((const XFormTextStyleItem&)rSet.Get(XATTR_FORMTXTSTYLE)).GetValue(), - rTextObj.GetTextLeftDistance(), - rTextObj.GetTextUpperDistance(), - rTextObj.GetTextRightDistance(), - rTextObj.GetTextLowerDistance(), + pLeft ? *pLeft : rTextObj.GetTextLeftDistance(), + pUpper ? *pUpper : rTextObj.GetTextUpperDistance(), + pRight ? *pRight : rTextObj.GetTextRightDistance(), + pLower ? *pLower : rTextObj.GetTextLowerDistance(), ((const SdrTextContourFrameItem&)rSet.Get(SDRATTR_TEXT_CONTOURFRAME)).GetValue(), (SDRTEXTFIT_PROPORTIONAL == eFit || SDRTEXTFIT_ALLLINES == eFit), ((const XFormTextHideFormItem&)rSet.Get(XATTR_FORMTXTHIDEFORM)).GetValue(), @@ -591,10 +598,18 @@ namespace drawinglayer if(aBitmap.GetPrefMapMode() != aDestinationMapUnit) { - // #i96237# need to use LogicToLogic, source is not always pixels - aBitmap.SetPrefSize(Application::GetDefaultDevice()->LogicToLogic( - aBitmap.GetPrefSize(), aBitmap.GetPrefMapMode(), aDestinationMapUnit)); - aBitmap.SetPrefMapMode(aDestinationMapUnit); + // #i100360# for MAP_PIXEL, LogicToLogic will not work properly, + // so fallback to Application::GetDefaultDevice() + if(MAP_PIXEL == aBitmap.GetPrefMapMode().GetMapUnit()) + { + aBitmap.SetPrefSize(Application::GetDefaultDevice()->PixelToLogic( + aBitmap.GetPrefSize(), aDestinationMapUnit)); + } + else + { + aBitmap.SetPrefSize(OutputDevice::LogicToLogic( + aBitmap.GetPrefSize(), aBitmap.GetPrefMapMode(), aDestinationMapUnit)); + } } // get size @@ -665,7 +680,7 @@ namespace drawinglayer // when object has text and text is fontwork and hide contour is set for fontwork, force // line and fill style to empty - if(pText && pText->isFontwork() && pText->isHideContour()) + if(pText && pText->getSdrFormTextAttribute() && pText->isHideContour()) { bFontworkHideContour = true; } @@ -730,7 +745,7 @@ namespace drawinglayer // when object has text and text is fontwork and hide contour is set for fontwork, force // line and fill style to empty - if(pText && pText->isFontwork() && pText->isHideContour()) + if(pText && pText->getSdrFormTextAttribute() && pText->isHideContour()) { bFontworkHideContour = true; } @@ -1023,7 +1038,14 @@ namespace drawinglayer } } - attribute::SdrFillTextAttribute* createNewSdrFillTextAttribute(const SfxItemSet& rSet, const SdrText* pSdrText) + // #i101508# Support handing over given text-to-border distances + attribute::SdrFillTextAttribute* createNewSdrFillTextAttribute( + const SfxItemSet& rSet, + const SdrText* pSdrText, + const sal_Int32* pLeft, + const sal_Int32* pUpper, + const sal_Int32* pRight, + const sal_Int32* pLower) { attribute::SdrFillTextAttribute* pRetval(0L); attribute::SdrFillAttribute* pFill(0L); @@ -1034,12 +1056,12 @@ namespace drawinglayer // look for text first if(pSdrText) { - pText = createNewSdrTextAttribute(rSet, *pSdrText); + pText = createNewSdrTextAttribute(rSet, *pSdrText, pLeft, pUpper, pRight, pLower); } // when object has text and text is fontwork and hide contour is set for fontwork, force // fill style to empty - if(pText && pText->isFontwork() && pText->isHideContour()) + if(pText && pText->getSdrFormTextAttribute() && pText->isHideContour()) { bFontworkHideContour = true; } diff --git a/svx/source/sdr/primitive2d/sdrcaptionprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrcaptionprimitive2d.cxx index 80067901483b..3c8feb7ff2b2 100644 --- a/svx/source/sdr/primitive2d/sdrcaptionprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrcaptionprimitive2d.cxx @@ -50,62 +50,95 @@ namespace drawinglayer Primitive2DSequence SdrCaptionPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const { Primitive2DSequence aRetval; + Primitive2DSequence aHitTestContent; // create unit outline polygon - ::basegfx::B2DPolygon aUnitOutline(::basegfx::tools::createPolygonFromRect(::basegfx::B2DRange(0.0, 0.0, 1.0, 1.0), getCornerRadiusX(), getCornerRadiusY())); + const basegfx::B2DPolygon aUnitOutline(basegfx::tools::createPolygonFromRect( + basegfx::B2DRange(0.0, 0.0, 1.0, 1.0), + getCornerRadiusX(), + getCornerRadiusY())); // add fill if(getSdrLFSTAttribute().getFill()) { - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createPolyPolygonFillPrimitive(::basegfx::B2DPolyPolygon(aUnitOutline), getTransform(), *getSdrLFSTAttribute().getFill(), getSdrLFSTAttribute().getFillFloatTransGradient())); + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + *getSdrLFSTAttribute().getFill(), + getSdrLFSTAttribute().getFillFloatTransGradient())); + } + else + { + // if no fill, create one for HitTest and BoundRect fallback + appendPrimitive2DReferenceToPrimitive2DSequence(aHitTestContent, + createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + attribute::SdrFillAttribute(0.0, basegfx::BColor(0.0, 0.0, 0.0)), + getSdrLFSTAttribute().getFillFloatTransGradient())); } // add line if(getSdrLFSTAttribute().getLine()) { - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createPolygonLinePrimitive(aUnitOutline, getTransform(), *getSdrLFSTAttribute().getLine())); - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createPolygonLinePrimitive(getTail(), getTransform(), *getSdrLFSTAttribute().getLine(), getSdrLFSTAttribute().getLineStartEnd())); + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + aUnitOutline, + getTransform(), + *getSdrLFSTAttribute().getLine())); + + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + getTail(), + getTransform(), + *getSdrLFSTAttribute().getLine(), + getSdrLFSTAttribute().getLineStartEnd())); } else { - // if initially no line is defined, create one for HitTest and BoundRect - Primitive2DSequence aLineSequence(2); - const attribute::SdrLineAttribute aBlackHairline(basegfx::BColor(0.0, 0.0, 0.0)); - - aLineSequence[0] = createPolygonLinePrimitive(aUnitOutline, getTransform(), aBlackHairline); - aLineSequence[1] = createPolygonLinePrimitive(getTail(), getTransform(), aBlackHairline); + // if initially no line is defined, create one for HitTest and BoundRect. It + // is sufficient to use the tail; the body is already ensured with fill creation + appendPrimitive2DReferenceToPrimitive2DSequence(aHitTestContent, + createPolygonLinePrimitive( + getTail(), + getTransform(), + attribute::SdrLineAttribute(basegfx::BColor(0.0, 0.0, 0.0)))); + } - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, Primitive2DReference(new HitTestPrimitive2D(aLineSequence))); + // add HitTest and BoundRect helper geometry (if exists) + if(aHitTestContent.hasElements()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + Primitive2DReference(new HitTestPrimitive2D(aHitTestContent))); } // add text if(getSdrLFSTAttribute().getText()) { - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createTextPrimitive(::basegfx::B2DPolyPolygon(aUnitOutline), getTransform(), *getSdrLFSTAttribute().getText(), getSdrLFSTAttribute().getLine(), false, false)); + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createTextPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + *getSdrLFSTAttribute().getText(), + getSdrLFSTAttribute().getLine(), + false, + false)); } // add shadow if(getSdrLFSTAttribute().getShadow()) { - // attention: shadow is added BEFORE object stuff to render it BEHIND object (!) - const Primitive2DReference xShadow(createShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow())); - - if(xShadow.is()) - { - Primitive2DSequence aContentWithShadow(2L); - aContentWithShadow[0L] = xShadow; - aContentWithShadow[1L] = Primitive2DReference(new GroupPrimitive2D(aRetval)); - aRetval = aContentWithShadow; - } + aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow()); } return aRetval; } SdrCaptionPrimitive2D::SdrCaptionPrimitive2D( - const ::basegfx::B2DHomMatrix& rTransform, + const basegfx::B2DHomMatrix& rTransform, const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute, - const ::basegfx::B2DPolygon& rTail, + const basegfx::B2DPolygon& rTail, double fCornerRadiusX, double fCornerRadiusY) : BasePrimitive2D(), @@ -118,7 +151,7 @@ namespace drawinglayer // transform maTail to unit polygon if(getTail().count()) { - ::basegfx::B2DHomMatrix aInverse(getTransform()); + basegfx::B2DHomMatrix aInverse(getTransform()); aInverse.invert(); maTail.transform(aInverse); } diff --git a/svx/source/sdr/primitive2d/sdrconnectorprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrconnectorprimitive2d.cxx index 5ee00133588f..0edbe1a35046 100644 --- a/svx/source/sdr/primitive2d/sdrconnectorprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrconnectorprimitive2d.cxx @@ -78,15 +78,7 @@ namespace drawinglayer // add shadow if(getSdrLSTAttribute().getShadow()) { - const Primitive2DReference xShadow(createShadowPrimitive(aRetval, *getSdrLSTAttribute().getShadow())); - - if(xShadow.is()) - { - Primitive2DSequence aContentWithShadow(2L); - aContentWithShadow[0L] = xShadow; - aContentWithShadow[1L] = Primitive2DReference(new GroupPrimitive2D(aRetval)); - aRetval = aContentWithShadow; - } + aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrLSTAttribute().getShadow()); } return aRetval; diff --git a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx index 51be7cd03033..c8847624bcdd 100644 --- a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx @@ -60,18 +60,9 @@ namespace drawinglayer } // add shadow - if(getSdrSTAttribute().getShadow()) + if(aRetval.hasElements() && getSdrSTAttribute().getShadow()) { - // attention: shadow is added BEFORE object stuff to render it BEHIND object (!) - const Primitive2DReference xShadow(createShadowPrimitive(aRetval, *getSdrSTAttribute().getShadow())); - - if(xShadow.is()) - { - Primitive2DSequence aContentWithShadow(2L); - aContentWithShadow[0L] = xShadow; - aContentWithShadow[1L] = Primitive2DReference(new GroupPrimitive2D(aRetval)); - aRetval = aContentWithShadow; - } + aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrSTAttribute().getShadow()); } return aRetval; diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx index 4a27eb73de8e..9666bd2c1ac1 100644 --- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx @@ -67,13 +67,13 @@ namespace drawinglayer namespace primitive2d { Primitive2DReference createPolyPolygonFillPrimitive( - const ::basegfx::B2DPolyPolygon& rUnitPolyPolygon, - const ::basegfx::B2DHomMatrix& rObjectTransform, + const basegfx::B2DPolyPolygon& rUnitPolyPolygon, + const basegfx::B2DHomMatrix& rObjectTransform, const attribute::SdrFillAttribute& rFill, const attribute::FillGradientAttribute* pFillGradient) { // prepare fully scaled polygon - ::basegfx::B2DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon); + basegfx::B2DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon); aScaledPolyPolygon.transform(rObjectTransform); BasePrimitive2D* pNewFillPrimitive = 0L; @@ -87,7 +87,7 @@ namespace drawinglayer } else if(rFill.isBitmap()) { - const ::basegfx::B2DRange aRange(::basegfx::tools::getRange(aScaledPolyPolygon)); + const basegfx::B2DRange aRange(basegfx::tools::getRange(aScaledPolyPolygon)); pNewFillPrimitive = new PolyPolygonBitmapPrimitive2D(aScaledPolyPolygon, rFill.getColor(), rFill.getBitmap()->getFillBitmapAttribute(aRange)); } else @@ -110,7 +110,7 @@ namespace drawinglayer // create FillGradientPrimitive2D for transparence and add to new sequence // fillGradientPrimitive is enough here (compared to PolyPolygonGradientPrimitive2D) since float transparence will be masked anyways - const ::basegfx::B2DRange aRange(::basegfx::tools::getRange(aScaledPolyPolygon)); + const basegfx::B2DRange aRange(basegfx::tools::getRange(aScaledPolyPolygon)); const Primitive2DReference xRefB(new FillGradientPrimitive2D(aRange, *pFillGradient)); const Primitive2DSequence aAlpha(&xRefB, 1L); @@ -125,13 +125,13 @@ namespace drawinglayer } Primitive2DReference createPolygonLinePrimitive( - const ::basegfx::B2DPolygon& rUnitPolygon, - const ::basegfx::B2DHomMatrix& rObjectTransform, + const basegfx::B2DPolygon& rUnitPolygon, + const basegfx::B2DHomMatrix& rObjectTransform, const attribute::SdrLineAttribute& rLine, const attribute::SdrLineStartEndAttribute* pStroke) { // prepare fully scaled polygon - ::basegfx::B2DPolygon aScaledPolygon(rUnitPolygon); + basegfx::B2DPolygon aScaledPolygon(rUnitPolygon); aScaledPolygon.transform(rObjectTransform); // create line and stroke attribute @@ -168,15 +168,15 @@ namespace drawinglayer } Primitive2DReference createTextPrimitive( - const ::basegfx::B2DPolyPolygon& rUnitPolyPolygon, - const ::basegfx::B2DHomMatrix& rObjectTransform, + const basegfx::B2DPolyPolygon& rUnitPolyPolygon, + const basegfx::B2DHomMatrix& rObjectTransform, const attribute::SdrTextAttribute& rText, const attribute::SdrLineAttribute* pStroke, bool bCellText, bool bWordWrap) { - ::basegfx::B2DHomMatrix aAnchorTransform(rObjectTransform); - SdrTextPrimitive2D* pNew = 0L; + basegfx::B2DHomMatrix aAnchorTransform(rObjectTransform); + SdrTextPrimitive2D* pNew = 0; if(rText.isContour()) { @@ -185,20 +185,20 @@ namespace drawinglayer { // take line width into account and shrink contour polygon accordingly // decompose to get scale - ::basegfx::B2DVector aScale, aTranslate; + basegfx::B2DVector aScale, aTranslate; double fRotate, fShearX; rObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX); // scale outline to object's size to allow growing with value relative to that size // and also to keep aspect ratio - ::basegfx::B2DHomMatrix aScaleTransform; + basegfx::B2DHomMatrix aScaleTransform; aScaleTransform.set(0, 0, fabs(aScale.getX())); aScaleTransform.set(1, 1, fabs(aScale.getY())); - ::basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon); + basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon); aScaledUnitPolyPolygon.transform(aScaleTransform); // grow the polygon. To shrink, use negative value (half width) - aScaledUnitPolyPolygon = ::basegfx::tools::growInNormalDirection(aScaledUnitPolyPolygon, -(pStroke->getWidth() * 0.5)); + aScaledUnitPolyPolygon = basegfx::tools::growInNormalDirection(aScaledUnitPolyPolygon, -(pStroke->getWidth() * 0.5)); // scale back to unit polygon aScaleTransform.set(0, 0, 0.0 != aScale.getX() ? 1.0 / aScale.getX() : 1.0); @@ -206,48 +206,60 @@ namespace drawinglayer aScaledUnitPolyPolygon.transform(aScaleTransform); // create with unit polygon - pNew = new SdrContourTextPrimitive2D(rText.getSdrText(), rText.getOutlinerParaObject(), aScaledUnitPolyPolygon, rObjectTransform); + pNew = new SdrContourTextPrimitive2D( + &rText.getSdrText(), + rText.getOutlinerParaObject(), + aScaledUnitPolyPolygon, + rObjectTransform); } else { // create with unit polygon - pNew = new SdrContourTextPrimitive2D(rText.getSdrText(), rText.getOutlinerParaObject(), rUnitPolyPolygon, rObjectTransform); + pNew = new SdrContourTextPrimitive2D( + &rText.getSdrText(), + rText.getOutlinerParaObject(), + rUnitPolyPolygon, + rObjectTransform); } } - else if(rText.isFontwork() && !rText.isScroll()) + else if(rText.getSdrFormTextAttribute()) { - // text on path, use scaled polygon. Not allowed when text scrolling is used. - ::basegfx::B2DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon); + // text on path, use scaled polygon + basegfx::B2DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon); aScaledPolyPolygon.transform(rObjectTransform); - pNew = new SdrPathTextPrimitive2D(rText.getSdrText(), rText.getOutlinerParaObject(), aScaledPolyPolygon); + pNew = new SdrPathTextPrimitive2D( + &rText.getSdrText(), + rText.getOutlinerParaObject(), + aScaledPolyPolygon, + *rText.getSdrFormTextAttribute()); } else { // rObjectTransform is the whole SdrObject transformation from unit rectangle // to it's size and position. Decompose to allow working with single values. - ::basegfx::B2DVector aScale, aTranslate; + basegfx::B2DVector aScale, aTranslate; double fRotate, fShearX; rObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX); // extract mirroring - const bool bMirrorX(::basegfx::fTools::less(aScale.getX(), 0.0)); - const bool bMirrorY(::basegfx::fTools::less(aScale.getY(), 0.0)); + const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0)); + const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0)); aScale = basegfx::absolute(aScale); // Get the real size, since polygon ountline and scale // from the object transformation may vary (e.g. ellipse segments) - ::basegfx::B2DHomMatrix aJustScaleTransform; + basegfx::B2DHomMatrix aJustScaleTransform; aJustScaleTransform.set(0, 0, aScale.getX()); aJustScaleTransform.set(1, 1, aScale.getY()); - ::basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon); + basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon); aScaledUnitPolyPolygon.transform(aJustScaleTransform); - const ::basegfx::B2DRange aSnapRange(::basegfx::tools::getRange(aScaledUnitPolyPolygon)); + const basegfx::B2DRange aSnapRange(basegfx::tools::getRange(aScaledUnitPolyPolygon)); // create a range describing the wanted text position and size (aTextAnchorRange). This // means to use the text distance values here - const ::basegfx::B2DPoint aTopLeft(aSnapRange.getMinX() + rText.getTextLeftDistance(), aSnapRange.getMinY() + rText.getTextUpperDistance()); - const ::basegfx::B2DPoint aBottomRight(aSnapRange.getMaxX() - rText.getTextRightDistance(), aSnapRange.getMaxY() - rText.getTextLowerDistance()); - ::basegfx::B2DRange aTextAnchorRange; + const basegfx::B2DPoint aTopLeft(aSnapRange.getMinX() + rText.getTextLeftDistance(), aSnapRange.getMinY() + rText.getTextUpperDistance()); + const basegfx::B2DPoint aBottomRight(aSnapRange.getMaxX() - rText.getTextRightDistance(), aSnapRange.getMaxY() - rText.getTextLowerDistance()); + basegfx::B2DRange aTextAnchorRange; aTextAnchorRange.expand(aTopLeft); aTextAnchorRange.expand(aBottomRight); @@ -267,12 +279,21 @@ namespace drawinglayer if(rText.isFitToSize()) { // streched text in range - pNew = new SdrStretchTextPrimitive2D(rText.getSdrText(), rText.getOutlinerParaObject(), aAnchorTransform); + pNew = new SdrStretchTextPrimitive2D( + &rText.getSdrText(), + rText.getOutlinerParaObject(), + aAnchorTransform); } else // text in range { // build new primitive - pNew = new SdrBlockTextPrimitive2D(rText.getSdrText(), rText.getOutlinerParaObject(), aAnchorTransform, rText.isScroll(), bCellText, bWordWrap); + pNew = new SdrBlockTextPrimitive2D( + &rText.getSdrText(), + rText.getOutlinerParaObject(), + aAnchorTransform, + rText.isScroll(), + bCellText, + bWordWrap); } } @@ -299,154 +320,164 @@ namespace drawinglayer return Primitive2DReference(pNew); } } - else if(rText.isScroll()) - { - // get scroll direction - const SdrTextAniDirection eDirection(rText.getSdrText().GetObject().GetTextAniDirection()); - const bool bHorizontal(SDRTEXTANI_LEFT == eDirection || SDRTEXTANI_RIGHT == eDirection); - - // decompose to get separated values for the scroll box - ::basegfx::B2DVector aScale, aTranslate; - double fRotate, fShearX; - aAnchorTransform.decompose(aScale, aTranslate, fRotate, fShearX); - - // build transform from scaled only to full AnchorTransform and inverse - ::basegfx::B2DHomMatrix aSRT; - aSRT.shearX(fShearX); - aSRT.rotate(fRotate); - aSRT.translate(aTranslate.getX(), aTranslate.getY()); - ::basegfx::B2DHomMatrix aISRT(aSRT); - aISRT.invert(); - - // bring the primitive back to scaled only and get scaled range, create new clone for this - SdrTextPrimitive2D* pNew2 = pNew->createTransformedClone(aISRT); - OSL_ENSURE(pNew2, "createTextPrimitive: Could not create transformed clone of text primitive (!)"); - delete pNew; - pNew = pNew2; - - // create neutral geometry::ViewInformation2D for local range and decompose calls. This is okay - // since the decompose is view-independent - const uno::Sequence< beans::PropertyValue > xViewParameters; - geometry::ViewInformation2D aViewInformation2D(xViewParameters); - - // get range - const ::basegfx::B2DRange aScaledRange(pNew->getB2DRange(aViewInformation2D)); - - // create left outside and right outside transformations. Also take care - // of the clip rectangle - ::basegfx::B2DHomMatrix aLeft, aRight; - ::basegfx::B2DPoint aClipTopLeft(0.0, 0.0); - ::basegfx::B2DPoint aClipBottomRight(aScale.getX(), aScale.getY()); - - if(bHorizontal) - { - aClipTopLeft.setY(aScaledRange.getMinY()); - aClipBottomRight.setY(aScaledRange.getMaxY()); - aLeft.translate(-aScaledRange.getMaxX(), 0.0); - aRight.translate(aScale.getX() - aScaledRange.getMinX(), 0.0); - } - else - { - aClipTopLeft.setX(aScaledRange.getMinX()); - aClipBottomRight.setX(aScaledRange.getMaxX()); - aLeft.translate(0.0, -aScaledRange.getMaxY()); - aRight.translate(0.0, aScale.getY() - aScaledRange.getMinY()); - } - - aLeft *= aSRT; - aRight *= aSRT; - // prepare animation list - drawinglayer::animation::AnimationEntryList aAnimationList; - - if(bHorizontal) - { - rText.getScrollTextTiming(aAnimationList, aScale.getX(), aScaledRange.getWidth()); - } - else + if(rText.isScroll()) + { + // suppress scroll when FontWork + if(!rText.getSdrFormTextAttribute()) { - rText.getScrollTextTiming(aAnimationList, aScale.getY(), aScaledRange.getHeight()); - } + // get scroll direction + const SdrTextAniDirection eDirection(rText.getSdrText().GetObject().GetTextAniDirection()); + const bool bHorizontal(SDRTEXTANI_LEFT == eDirection || SDRTEXTANI_RIGHT == eDirection); - if(0.0 != aAnimationList.getDuration()) - { - // create a new Primitive2DSequence containing the animated text in it's scaled only state. - // use the decomposition to force to simple text primitives, those will no longer - // need the outliner for formatting (alternatively it is also possible to just add - // pNew to aNewPrimitiveSequence) - Primitive2DSequence aAnimSequence(pNew->get2DDecomposition(aViewInformation2D)); + // decompose to get separated values for the scroll box + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + aAnchorTransform.decompose(aScale, aTranslate, fRotate, fShearX); + + // build transform from scaled only to full AnchorTransform and inverse + basegfx::B2DHomMatrix aSRT; + aSRT.shearX(fShearX); + aSRT.rotate(fRotate); + aSRT.translate(aTranslate.getX(), aTranslate.getY()); + basegfx::B2DHomMatrix aISRT(aSRT); + aISRT.invert(); + + // bring the primitive back to scaled only and get scaled range, create new clone for this + SdrTextPrimitive2D* pNew2 = pNew->createTransformedClone(aISRT); + OSL_ENSURE(pNew2, "createTextPrimitive: Could not create transformed clone of text primitive (!)"); delete pNew; + pNew = pNew2; + + // create neutral geometry::ViewInformation2D for local range and decompose calls. This is okay + // since the decompose is view-independent + const uno::Sequence< beans::PropertyValue > xViewParameters; + geometry::ViewInformation2D aViewInformation2D(xViewParameters); + + // get range + const basegfx::B2DRange aScaledRange(pNew->getB2DRange(aViewInformation2D)); + + // create left outside and right outside transformations. Also take care + // of the clip rectangle + basegfx::B2DHomMatrix aLeft, aRight; + basegfx::B2DPoint aClipTopLeft(0.0, 0.0); + basegfx::B2DPoint aClipBottomRight(aScale.getX(), aScale.getY()); + + if(bHorizontal) + { + aClipTopLeft.setY(aScaledRange.getMinY()); + aClipBottomRight.setY(aScaledRange.getMaxY()); + aLeft.translate(-aScaledRange.getMaxX(), 0.0); + aRight.translate(aScale.getX() - aScaledRange.getMinX(), 0.0); + } + else + { + aClipTopLeft.setX(aScaledRange.getMinX()); + aClipBottomRight.setX(aScaledRange.getMaxX()); + aLeft.translate(0.0, -aScaledRange.getMaxY()); + aRight.translate(0.0, aScale.getY() - aScaledRange.getMinY()); + } + + aLeft *= aSRT; + aRight *= aSRT; + + // prepare animation list + drawinglayer::animation::AnimationEntryList aAnimationList; + + if(bHorizontal) + { + rText.getScrollTextTiming(aAnimationList, aScale.getX(), aScaledRange.getWidth()); + } + else + { + rText.getScrollTextTiming(aAnimationList, aScale.getY(), aScaledRange.getHeight()); + } + + if(0.0 != aAnimationList.getDuration()) + { + // create a new Primitive2DSequence containing the animated text in it's scaled only state. + // use the decomposition to force to simple text primitives, those will no longer + // need the outliner for formatting (alternatively it is also possible to just add + // pNew to aNewPrimitiveSequence) + Primitive2DSequence aAnimSequence(pNew->get2DDecomposition(aViewInformation2D)); + delete pNew; + + // create a new animatedInterpolatePrimitive and add it + std::vector< basegfx::B2DHomMatrix > aMatrixStack; + aMatrixStack.push_back(aLeft); + aMatrixStack.push_back(aRight); + const Primitive2DReference xRefA(new AnimatedInterpolatePrimitive2D(aMatrixStack, aAnimationList, aAnimSequence, true)); + const Primitive2DSequence aContent(&xRefA, 1L); + + // scrolling needs an encapsulating clipping primitive + const basegfx::B2DRange aClipRange(aClipTopLeft, aClipBottomRight); + basegfx::B2DPolygon aClipPolygon(basegfx::tools::createPolygonFromRect(aClipRange)); + aClipPolygon.transform(aSRT); + return Primitive2DReference(new MaskPrimitive2D(basegfx::B2DPolyPolygon(aClipPolygon), aContent)); + } + else + { + // add to decomposition + return Primitive2DReference(pNew); + } + } + } - // create a new animatedInterpolatePrimitive and add it - std::vector< basegfx::B2DHomMatrix > aMatrixStack; - aMatrixStack.push_back(aLeft); - aMatrixStack.push_back(aRight); - const Primitive2DReference xRefA(new AnimatedInterpolatePrimitive2D(aMatrixStack, aAnimationList, aAnimSequence, true)); - const Primitive2DSequence aContent(&xRefA, 1L); + if(rText.isInEditMode()) + { + // #i97628# + // encapsulate with TextHierarchyEditPrimitive2D to allow renderers + // to suppress actively edited content if needed + const Primitive2DReference xRefA(pNew); + const Primitive2DSequence aContent(&xRefA, 1L); - // scrolling needs an encapsulating clipping primitive - const ::basegfx::B2DRange aClipRange(aClipTopLeft, aClipBottomRight); - ::basegfx::B2DPolygon aClipPolygon(::basegfx::tools::createPolygonFromRect(aClipRange)); - aClipPolygon.transform(aSRT); - return Primitive2DReference(new MaskPrimitive2D(::basegfx::B2DPolyPolygon(aClipPolygon), aContent)); - } - else - { - // add to decomposition - return Primitive2DReference(pNew); - } + // create and add TextHierarchyEditPrimitive2D primitive + return Primitive2DReference(new TextHierarchyEditPrimitive2D(aContent)); } else { - if(rText.isInEditMode()) - { - // #i97628# - // encapsulate with TextHierarchyEditPrimitive2D to allow renderers - // to suppress actively edited content if needed - const Primitive2DReference xRefA(pNew); - const Primitive2DSequence aContent(&xRefA, 1L); - - // create and add TextHierarchyEditPrimitive2D primitive - return Primitive2DReference(new TextHierarchyEditPrimitive2D(aContent)); - } - else - { - // add to decomposition - return Primitive2DReference(pNew); - } + // add to decomposition + return Primitive2DReference(pNew); } } - Primitive2DReference createShadowPrimitive( - const Primitive2DSequence& rSource, + Primitive2DSequence createEmbeddedShadowPrimitive( + const Primitive2DSequence& rContent, const attribute::SdrShadowAttribute& rShadow) { - // create Shadow primitives. Need to be added in front, should use already created primitives - if(rSource.hasElements()) + if(rContent.hasElements()) { + Primitive2DSequence aRetval(2); + basegfx::B2DHomMatrix aShadowOffset; + // prepare shadow offset - ::basegfx::B2DHomMatrix aShadowOffset; aShadowOffset.set(0, 2, rShadow.getOffset().getX()); aShadowOffset.set(1, 2, rShadow.getOffset().getY()); // create shadow primitive and add content - const Primitive2DReference xRefShadow(new ShadowPrimitive2D(aShadowOffset, rShadow.getColor(), rSource)); + aRetval[0] = Primitive2DReference( + new ShadowPrimitive2D( + aShadowOffset, + rShadow.getColor(), + rContent)); if(0.0 != rShadow.getTransparence()) { // create SimpleTransparencePrimitive2D - const Primitive2DSequence aContent(&xRefShadow, 1L); - return Primitive2DReference(new UnifiedAlphaPrimitive2D(aContent, rShadow.getTransparence())); - } - else - { - // return directly - return xRefShadow; + const Primitive2DSequence aTempContent(&aRetval[0], 1); + + aRetval[0] = Primitive2DReference( + new UnifiedAlphaPrimitive2D( + aTempContent, + rShadow.getTransparence())); } + + aRetval[1] = Primitive2DReference(new GroupPrimitive2D(rContent)); + return aRetval; } else { - return Primitive2DReference(); + return rContent; } } } // end of namespace primitive2d diff --git a/svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx index 814c20b681ac..ed3062184f1a 100644 --- a/svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx @@ -100,16 +100,7 @@ namespace drawinglayer // add shadow if(getSdrLFSTAttribute().getShadow()) { - // attention: shadow is added BEFORE object stuff to render it BEHIND object (!) - const Primitive2DReference xShadow(createShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow())); - - if(xShadow.is()) - { - Primitive2DSequence aContentWithShadow(2L); - aContentWithShadow[0L] = xShadow; - aContentWithShadow[1L] = Primitive2DReference(new GroupPrimitive2D(aRetval)); - aRetval = aContentWithShadow; - } + aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow()); } return aRetval; @@ -206,16 +197,7 @@ namespace drawinglayer // add shadow if(getSdrLFSTAttribute().getShadow()) { - // attention: shadow is added BEFORE object stuff to render it BEHIND object (!) - const Primitive2DReference xShadow(createShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow())); - - if(xShadow.is()) - { - Primitive2DSequence aContentWithShadow(2L); - aContentWithShadow[0L] = xShadow; - aContentWithShadow[1L] = Primitive2DReference(new GroupPrimitive2D(aRetval)); - aRetval = aContentWithShadow; - } + aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow()); } return aRetval; diff --git a/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx index f1f88684dc6c..f5f2f4e876dc 100644 --- a/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx @@ -110,16 +110,7 @@ namespace drawinglayer // add shadow if(getSdrLFSTAttribute().getShadow()) { - // attention: shadow is added BEFORE object stuff to render it BEHIND object (!) - const Primitive2DReference xShadow(createShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow())); - - if(xShadow.is()) - { - Primitive2DSequence aContentWithShadow(2L); - aContentWithShadow[0L] = xShadow; - aContentWithShadow[1L] = Primitive2DReference(new GroupPrimitive2D(aRetval)); - aRetval = aContentWithShadow; - } + aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow()); } return aRetval; diff --git a/svx/source/sdr/primitive2d/sdrmeasureprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrmeasureprimitive2d.cxx index 7f9b47afb2d4..f515b9b6a5e9 100644 --- a/svx/source/sdr/primitive2d/sdrmeasureprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrmeasureprimitive2d.cxx @@ -52,71 +52,71 @@ namespace drawinglayer namespace primitive2d { Primitive2DReference SdrMeasurePrimitive2D::impCreatePart( - const ::basegfx::B2DHomMatrix& rObjectMatrix, - const ::basegfx::B2DPoint& rStart, - const ::basegfx::B2DPoint& rEnd, + const basegfx::B2DHomMatrix& rObjectMatrix, + const basegfx::B2DPoint& rStart, + const basegfx::B2DPoint& rEnd, bool bLeftActive, bool bRightActive) const { - ::basegfx::B2DPolygon aPolygon; + basegfx::B2DPolygon aPolygon; aPolygon.append(rStart); aPolygon.append(rEnd); - if(!maSdrLSTAttribute.getLineStartEnd() || (!bLeftActive && !bRightActive)) + if(!getSdrLSTAttribute().getLineStartEnd() || (!bLeftActive && !bRightActive)) { - return createPolygonLinePrimitive(aPolygon, rObjectMatrix, *maSdrLSTAttribute.getLine(), 0L); + return createPolygonLinePrimitive(aPolygon, rObjectMatrix, *getSdrLSTAttribute().getLine(), 0L); } if(bLeftActive && bRightActive) { - return createPolygonLinePrimitive(aPolygon, rObjectMatrix, *maSdrLSTAttribute.getLine(), maSdrLSTAttribute.getLineStartEnd()); + return createPolygonLinePrimitive(aPolygon, rObjectMatrix, *getSdrLSTAttribute().getLine(), getSdrLSTAttribute().getLineStartEnd()); } - const attribute::SdrLineStartEndAttribute* pLineStartEnd = maSdrLSTAttribute.getLineStartEnd(); - const ::basegfx::B2DPolyPolygon aEmpty; + const attribute::SdrLineStartEndAttribute* pLineStartEnd = getSdrLSTAttribute().getLineStartEnd(); + const basegfx::B2DPolyPolygon aEmpty; const attribute::SdrLineStartEndAttribute aLineStartEnd( bLeftActive ? pLineStartEnd->getStartPolyPolygon() : aEmpty, bRightActive ? pLineStartEnd->getEndPolyPolygon() : aEmpty, bLeftActive ? pLineStartEnd->getStartWidth() : 0.0, bRightActive ? pLineStartEnd->getEndWidth() : 0.0, bLeftActive ? pLineStartEnd->isStartActive() : false, bRightActive ? pLineStartEnd->isEndActive() : false, bLeftActive ? pLineStartEnd->isStartCentered() : false, bRightActive? pLineStartEnd->isEndCentered() : false); - return createPolygonLinePrimitive(aPolygon, rObjectMatrix, *maSdrLSTAttribute.getLine(), &aLineStartEnd); + return createPolygonLinePrimitive(aPolygon, rObjectMatrix, *getSdrLSTAttribute().getLine(), &aLineStartEnd); } Primitive2DSequence SdrMeasurePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& aViewInformation) const { Primitive2DSequence aRetval; SdrBlockTextPrimitive2D* pBlockText = 0L; - ::basegfx::B2DRange aTextRange; - double fTextX((maStart.getX() + maEnd.getX()) * 0.5); - double fTextY((maStart.getX() + maEnd.getX()) * 0.5); - const ::basegfx::B2DVector aLine(maEnd - maStart); + basegfx::B2DRange aTextRange; + double fTextX((getStart().getX() + getEnd().getX()) * 0.5); + double fTextY((getStart().getX() + getEnd().getX()) * 0.5); + const basegfx::B2DVector aLine(getEnd() - getStart()); const double fDistance(aLine.getLength()); const double fAngle(atan2(aLine.getY(), aLine.getX())); bool bAutoUpsideDown(false); - const attribute::SdrTextAttribute* pTextAttribute = maSdrLSTAttribute.getText(); + const attribute::SdrTextAttribute* pTextAttribute = getSdrLSTAttribute().getText(); - ::basegfx::B2DHomMatrix aObjectMatrix; + basegfx::B2DHomMatrix aObjectMatrix; aObjectMatrix.rotate(fAngle); - aObjectMatrix.translate(maStart.getX(), maStart.getY()); + aObjectMatrix.translate(getStart().getX(), getStart().getY()); if(pTextAttribute) { - ::basegfx::B2DHomMatrix aTextMatrix; + basegfx::B2DHomMatrix aTextMatrix; double fTestAngle(fAngle); - if(mbTextRotation) + if(getTextRotation()) { aTextMatrix.rotate(-90.0 * F_PI180); fTestAngle -= (90.0 * F_PI180); - if(mbTextAutoAngle && fTestAngle < -F_PI) + if(getTextAutoAngle() && fTestAngle < -F_PI) { fTestAngle += F_2PI; } } - if(mbTextAutoAngle) + if(getTextAutoAngle()) { if(fTestAngle > (F_PI / 4.0) || fTestAngle < (-F_PI * (3.0 / 4.0))) { @@ -125,13 +125,18 @@ namespace drawinglayer } // create primitive and get text range - pBlockText = new SdrBlockTextPrimitive2D(pTextAttribute->getSdrText(), pTextAttribute->getOutlinerParaObject(), - aTextMatrix, pTextAttribute->isScroll(), false, false); + pBlockText = new SdrBlockTextPrimitive2D( + &pTextAttribute->getSdrText(), + pTextAttribute->getOutlinerParaObject(), + aTextMatrix, + pTextAttribute->isScroll(), + false, + false); aTextRange = pBlockText->getB2DRange(aViewInformation); } // prepare line attribute and result - const attribute::SdrLineAttribute* pLineAttribute(maSdrLSTAttribute.getLine()); + const attribute::SdrLineAttribute* pLineAttribute(getSdrLSTAttribute().getLine()); if(!pLineAttribute) { @@ -142,7 +147,7 @@ namespace drawinglayer { bool bArrowsOutside(false); bool bMainLineSplitted(false); - const attribute::SdrLineStartEndAttribute* pLineStartEnd = maSdrLSTAttribute.getLineStartEnd(); + const attribute::SdrLineStartEndAttribute* pLineStartEnd = getSdrLSTAttribute().getLineStartEnd(); double fStartArrowW(0.0); double fStartArrowH(0.0); double fEndArrowW(0.0); @@ -152,7 +157,7 @@ namespace drawinglayer { if(pLineStartEnd->isStartActive()) { - const ::basegfx::B2DRange aArrowRange(::basegfx::tools::getRange(pLineStartEnd->getStartPolyPolygon())); + const basegfx::B2DRange aArrowRange(basegfx::tools::getRange(pLineStartEnd->getStartPolyPolygon())); fStartArrowW = pLineStartEnd->getStartWidth(); fStartArrowH = aArrowRange.getHeight() * fStartArrowW / aArrowRange.getWidth(); @@ -164,7 +169,7 @@ namespace drawinglayer if(pLineStartEnd->isEndActive()) { - const ::basegfx::B2DRange aArrowRange(::basegfx::tools::getRange(pLineStartEnd->getEndPolyPolygon())); + const basegfx::B2DRange aArrowRange(basegfx::tools::getRange(pLineStartEnd->getEndPolyPolygon())); fEndArrowW = pLineStartEnd->getEndWidth(); fEndArrowH = aArrowRange.getHeight() * fEndArrowW / aArrowRange.getWidth(); @@ -184,8 +189,8 @@ namespace drawinglayer bArrowsOutside = true; } - MeasureTextPosition eHorizontal(meHorizontal); - MeasureTextPosition eVertical(meVertical); + MeasureTextPosition eHorizontal(getHorizontal()); + MeasureTextPosition eVertical(getVertical()); if(MEASURETEXTPOSITION_AUTOMATIC == eVertical) { @@ -232,7 +237,7 @@ namespace drawinglayer } // switch text above/below? - if(mbBelow || (bAutoUpsideDown && !mbTextRotation)) + if(getBelow() || (bAutoUpsideDown && !getTextRotation())) { if(MEASURETEXTPOSITION_NEGATIVE == eVertical) { @@ -244,9 +249,9 @@ namespace drawinglayer } } - const double fMainLineOffset(mbBelow ? mfDistance : -mfDistance); - const ::basegfx::B2DPoint aMainLeft(0.0, fMainLineOffset); - const ::basegfx::B2DPoint aMainRight(fDistance, fMainLineOffset); + const double fMainLineOffset(getBelow() ? getDistance() : -getDistance()); + const basegfx::B2DPoint aMainLeft(0.0, fMainLineOffset); + const basegfx::B2DPoint aMainRight(fDistance, fMainLineOffset); // main line if(bArrowsOutside) @@ -266,8 +271,8 @@ namespace drawinglayer } } - const ::basegfx::B2DPoint aMainLeftLeft(aMainLeft.getX() - fLenLeft, aMainLeft.getY()); - const ::basegfx::B2DPoint aMainRightRight(aMainRight.getX() + fLenRight, aMainRight.getY()); + const basegfx::B2DPoint aMainLeftLeft(aMainLeft.getX() - fLenLeft, aMainLeft.getY()); + const basegfx::B2DPoint aMainRightRight(aMainRight.getX() + fLenRight, aMainRight.getY()); appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(aObjectMatrix, aMainLeftLeft, aMainLeft, false, true)); appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(aObjectMatrix, aMainRight, aMainRightRight, true, false)); @@ -282,8 +287,8 @@ namespace drawinglayer if(bMainLineSplitted) { const double fHalfLength((fDistance - (aTextRange.getWidth() + (fStartArrowH + fEndArrowH) * 0.25)) * 0.5); - const ::basegfx::B2DPoint aMainInnerLeft(aMainLeft.getX() + fHalfLength, aMainLeft.getY()); - const ::basegfx::B2DPoint aMainInnerRight(aMainRight.getX() - fHalfLength, aMainRight.getY()); + const basegfx::B2DPoint aMainInnerLeft(aMainLeft.getX() + fHalfLength, aMainLeft.getY()); + const basegfx::B2DPoint aMainInnerRight(aMainRight.getX() - fHalfLength, aMainRight.getY()); appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(aObjectMatrix, aMainLeft, aMainInnerLeft, true, false)); appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(aObjectMatrix, aMainInnerRight, aMainRight, false, true)); @@ -295,19 +300,19 @@ namespace drawinglayer } // left/right help line value preparation - const double fTopEdge(mbBelow ? mfUpper + mfDistance : -mfUpper - mfDistance); - const double fBottomLeft(mbBelow ? mfLower - mfLeftDelta : mfLeftDelta - mfLower); - const double fBottomRight(mbBelow ? mfLower - mfRightDelta : mfRightDelta - mfLower); + const double fTopEdge(getBelow() ? getUpper() + getDistance() : -getUpper() - getDistance()); + const double fBottomLeft(getBelow() ? getLower() - getLeftDelta() : getLeftDelta() - getLower()); + const double fBottomRight(getBelow() ? getLower() - getRightDelta() : getRightDelta() - getLower()); // left help line - const ::basegfx::B2DPoint aLeftUp(0.0, fTopEdge); - const ::basegfx::B2DPoint aLeftDown(0.0, fBottomLeft); + const basegfx::B2DPoint aLeftUp(0.0, fTopEdge); + const basegfx::B2DPoint aLeftDown(0.0, fBottomLeft); appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(aObjectMatrix, aLeftDown, aLeftUp, false, false)); // right help line - const ::basegfx::B2DPoint aRightUp(fDistance, fTopEdge); - const ::basegfx::B2DPoint aRightDown(fDistance, fBottomRight); + const basegfx::B2DPoint aRightUp(fDistance, fTopEdge); + const basegfx::B2DPoint aRightDown(fDistance, fBottomRight); appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(aObjectMatrix, aRightDown, aRightUp, false, false)); @@ -390,7 +395,7 @@ namespace drawinglayer } } - if(!maSdrLSTAttribute.getLine()) + if(!getSdrLSTAttribute().getLine()) { // embed line geometry to invisible line group const Primitive2DReference xHiddenLines(new HitTestPrimitive2D(aRetval)); @@ -403,7 +408,7 @@ namespace drawinglayer if(pBlockText) { // create transformation to text primitive end position - ::basegfx::B2DHomMatrix aChange; + basegfx::B2DHomMatrix aChange; // handle auto text rotation if(bAutoUpsideDown) @@ -427,18 +432,9 @@ namespace drawinglayer } // add shadow - if(maSdrLSTAttribute.getShadow()) + if(getSdrLSTAttribute().getShadow()) { - // attention: shadow is added BEFORE object stuff to render it BEHIND object (!) - const Primitive2DReference xShadow(createShadowPrimitive(aRetval, *maSdrLSTAttribute.getShadow())); - - if(xShadow.is()) - { - Primitive2DSequence aContentWithShadow(2L); - aContentWithShadow[0L] = xShadow; - aContentWithShadow[1L] = Primitive2DReference(new GroupPrimitive2D(aRetval)); - aRetval = aContentWithShadow; - } + aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrLSTAttribute().getShadow()); } return aRetval; @@ -446,8 +442,8 @@ namespace drawinglayer SdrMeasurePrimitive2D::SdrMeasurePrimitive2D( const attribute::SdrLineShadowTextAttribute& rSdrLSTAttribute, - const ::basegfx::B2DPoint& rStart, - const ::basegfx::B2DPoint& rEnd, + const basegfx::B2DPoint& rStart, + const basegfx::B2DPoint& rEnd, MeasureTextPosition eHorizontal, MeasureTextPosition eVertical, double fDistance, @@ -481,19 +477,19 @@ namespace drawinglayer { const SdrMeasurePrimitive2D& rCompare = (SdrMeasurePrimitive2D&)rPrimitive; - return (maStart == rCompare.maStart - && maEnd == rCompare.maEnd - && meHorizontal == rCompare.meHorizontal - && meVertical == rCompare.meVertical - && mfDistance == rCompare.mfDistance - && mfUpper == rCompare.mfUpper - && mfLower == rCompare.mfLower - && mfLeftDelta == rCompare.mfLeftDelta - && mfRightDelta == rCompare.mfRightDelta - && mbBelow == rCompare.mbBelow - && mbTextRotation == rCompare.mbTextRotation - && mbTextAutoAngle == rCompare.mbTextAutoAngle - && maSdrLSTAttribute == rCompare.maSdrLSTAttribute); + return (getStart() == rCompare.getStart() + && getEnd() == rCompare.getEnd() + && getHorizontal() == rCompare.getHorizontal() + && getVertical() == rCompare.getVertical() + && getDistance() == rCompare.getDistance() + && getUpper() == rCompare.getUpper() + && getLower() == rCompare.getLower() + && getLeftDelta() == rCompare.getLeftDelta() + && getRightDelta() == rCompare.getRightDelta() + && getBelow() == rCompare.getBelow() + && getTextRotation() == rCompare.getTextRotation() + && getTextAutoAngle() == rCompare.getTextAutoAngle() + && getSdrLSTAttribute() == rCompare.getSdrLSTAttribute()); } return false; diff --git a/svx/source/sdr/primitive2d/sdrole2primitive2d.cxx b/svx/source/sdr/primitive2d/sdrole2primitive2d.cxx index 2cedb1bfce29..ab5d23962719 100644 --- a/svx/source/sdr/primitive2d/sdrole2primitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrole2primitive2d.cxx @@ -116,16 +116,7 @@ namespace drawinglayer // add shadow if(!bBehaveCompatibleToPaintVersion && getSdrLFSTAttribute().getShadow()) { - // attention: shadow is added BEFORE object stuff to render it BEHIND object (!) - const Primitive2DReference xShadow(createShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow())); - - if(xShadow.is()) - { - Primitive2DSequence aContentWithShadow(2L); - aContentWithShadow[0L] = xShadow; - aContentWithShadow[1L] = Primitive2DReference(new GroupPrimitive2D(aRetval)); - aRetval = aContentWithShadow; - } + aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow()); } return aRetval; diff --git a/svx/source/sdr/primitive2d/sdrolecontentprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrolecontentprimitive2d.cxx new file mode 100644 index 000000000000..67fee9215b73 --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrolecontentprimitive2d.cxx @@ -0,0 +1,200 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sdrcaptionprimitive2d.cxx,v $ + * + * $Revision: 1.2.18.1 $ + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrolecontentprimitive2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <svx/svdoole2.hxx> +#include <vcl/svapp.hxx> +#include <drawinglayer/primitive2d/graphicprimitive2d.hxx> +#include <svtools/colorcfg.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrOleContentPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const + { + Primitive2DSequence aRetval; + const SdrOle2Obj* pSource = (mpSdrOle2Obj.is() ? static_cast< SdrOle2Obj* >(mpSdrOle2Obj.get()) : 0); + bool bScaleContent(false); + Graphic aGraphic; + + if(pSource) + { + Graphic* pOLEGraphic = (getHighContrast()) + ? pSource->getEmbeddedObjectRef().GetHCGraphic() + : pSource->GetGraphic(); + + if(pOLEGraphic) + { + aGraphic = *pOLEGraphic; + bScaleContent = pSource->IsEmptyPresObj(); + } + } + + if(GRAPHIC_NONE == aGraphic.GetType()) + { + // no source, use fallback ressource emty OLE graphic + const Bitmap aEmptyOLEBitmap(SdrOle2Obj::GetEmtyOLEReplacementBitmap()); + aGraphic = Graphic(aEmptyOLEBitmap); + bScaleContent = true; + } + + if(GRAPHIC_NONE != aGraphic.GetType()) + { + const GraphicObject aGraphicObject(aGraphic); + const GraphicAttr aGraphicAttr; + drawinglayer::primitive2d::Primitive2DSequence xOLEContent; + + if(bScaleContent) + { + // get transformation atoms + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + getObjectTransform().decompose(aScale, aTranslate, fRotate, fShearX); + + // get PrefSize from the graphic in 100th mm + Size aPrefSize(aGraphic.GetPrefSize()); + + if(MAP_PIXEL == aGraphic.GetPrefMapMode().GetMapUnit()) + { + aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MAP_100TH_MM); + } + else + { + aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, aGraphic.GetPrefMapMode(), MAP_100TH_MM); + } + + const double fOffsetX((aScale.getX() - aPrefSize.getWidth()) / 2.0); + const double fOffsetY((aScale.getY() - aPrefSize.getHeight()) / 2.0); + + if(basegfx::fTools::moreOrEqual(fOffsetX, 0.0) && basegfx::fTools::moreOrEqual(fOffsetY, 0.0)) + { + // if content fits into frame, create it + basegfx::B2DHomMatrix aInnerObjectMatrix; + + aInnerObjectMatrix.scale(aPrefSize.getWidth(), aPrefSize.getHeight()); + aInnerObjectMatrix.translate(fOffsetX, fOffsetY); + aInnerObjectMatrix.shearX(fShearX); + aInnerObjectMatrix.rotate(fRotate); + aInnerObjectMatrix.translate(aTranslate.getX(), aTranslate.getY()); + + const drawinglayer::primitive2d::Primitive2DReference aGraphicPrimitive( + new drawinglayer::primitive2d::GraphicPrimitive2D( + aInnerObjectMatrix, + aGraphicObject, + aGraphicAttr)); + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aGraphicPrimitive); + } + } + else + { + // create graphic primitive for content + const drawinglayer::primitive2d::Primitive2DReference aGraphicPrimitive( + new drawinglayer::primitive2d::GraphicPrimitive2D( + getObjectTransform(), + aGraphicObject, + aGraphicAttr)); + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aGraphicPrimitive); + } + + // a standard gray outline is created for scaled content + if(bScaleContent) + { + const svtools::ColorConfig aColorConfig; + const svtools::ColorConfigValue aColor(aColorConfig.GetColorValue(svtools::OBJECTBOUNDARIES)); + + if(aColor.bIsVisible) + { + basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0))); + const Color aVclColor(aColor.nColor); + aOutline.transform(getObjectTransform()); + const drawinglayer::primitive2d::Primitive2DReference xOutline( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aVclColor.getBColor())); + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xOutline); + } + } + } + + // get graphic and check scale content state + return aRetval; + } + + SdrOleContentPrimitive2D::SdrOleContentPrimitive2D( + const SdrOle2Obj& rSdrOle2Obj, + const basegfx::B2DHomMatrix& rObjectTransform, + bool bHighContrast) + : BasePrimitive2D(), + mpSdrOle2Obj(const_cast< SdrOle2Obj* >(&rSdrOle2Obj)), + maObjectTransform(rObjectTransform), + mbHighContrast(bHighContrast) + { + } + + bool SdrOleContentPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BasePrimitive2D::operator==(rPrimitive)) + { + const SdrOleContentPrimitive2D& rCompare = (SdrOleContentPrimitive2D&)rPrimitive; + const bool bBothNot(!mpSdrOle2Obj.is() && !rCompare.mpSdrOle2Obj.is()); + const bool bBothAndEqual(mpSdrOle2Obj.is() && rCompare.mpSdrOle2Obj.is() + && mpSdrOle2Obj.get() == rCompare.mpSdrOle2Obj.get()); + + return ((bBothNot || bBothAndEqual) + && getObjectTransform() == rCompare.getObjectTransform() + && getHighContrast() == rCompare.getHighContrast()); + } + + return false; + } + + basegfx::B2DRange SdrOleContentPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + basegfx::B2DRange aRange(0.0, 0.0, 1.0, 1.0); + aRange.transform(getObjectTransform()); + + return aRange; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrOleContentPrimitive2D, PRIMITIVE2D_ID_SDROLECONTENTPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx index 3b6a653a7bc6..91ed0bd2adce 100644 --- a/svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx @@ -52,22 +52,22 @@ namespace drawinglayer Primitive2DSequence aRetval; // add fill - if(maSdrLFSTAttribute.getFill() && maUnitPolyPolygon.isClosed()) + if(getSdrLFSTAttribute().getFill() && getUnitPolyPolygon().isClosed()) { // take care for orientations - ::basegfx::B2DPolyPolygon aOrientedUnitPolyPolygon(::basegfx::tools::correctOrientations(maUnitPolyPolygon)); + basegfx::B2DPolyPolygon aOrientedUnitPolyPolygon(basegfx::tools::correctOrientations(getUnitPolyPolygon())); - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createPolyPolygonFillPrimitive(aOrientedUnitPolyPolygon, maTransform, *maSdrLFSTAttribute.getFill(), maSdrLFSTAttribute.getFillFloatTransGradient())); + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createPolyPolygonFillPrimitive(aOrientedUnitPolyPolygon, getTransform(), *getSdrLFSTAttribute().getFill(), getSdrLFSTAttribute().getFillFloatTransGradient())); } // add line - if(maSdrLFSTAttribute.getLine()) + if(getSdrLFSTAttribute().getLine()) { - Primitive2DSequence aTemp(maUnitPolyPolygon.count()); + Primitive2DSequence aTemp(getUnitPolyPolygon().count()); - for(sal_uInt32 a(0L); a < maUnitPolyPolygon.count(); a++) + for(sal_uInt32 a(0L); a < getUnitPolyPolygon().count(); a++) { - aTemp[a] = createPolygonLinePrimitive(maUnitPolyPolygon.getB2DPolygon(a), maTransform, *maSdrLFSTAttribute.getLine(), maSdrLFSTAttribute.getLineStartEnd()); + aTemp[a] = createPolygonLinePrimitive(getUnitPolyPolygon().getB2DPolygon(a), getTransform(), *getSdrLFSTAttribute().getLine(), getSdrLFSTAttribute().getLineStartEnd()); } appendPrimitive2DSequenceToPrimitive2DSequence(aRetval, aTemp); @@ -76,44 +76,35 @@ namespace drawinglayer { // if initially no line is defined, create one for HitTest and BoundRect const attribute::SdrLineAttribute aBlackHairline(basegfx::BColor(0.0, 0.0, 0.0)); - Primitive2DSequence xHiddenLineSequence(maUnitPolyPolygon.count()); + Primitive2DSequence xHiddenLineSequence(getUnitPolyPolygon().count()); - for(sal_uInt32 a(0); a < maUnitPolyPolygon.count(); a++) + for(sal_uInt32 a(0); a < getUnitPolyPolygon().count(); a++) { - xHiddenLineSequence[a] = createPolygonLinePrimitive(maUnitPolyPolygon.getB2DPolygon(a), maTransform, aBlackHairline); + xHiddenLineSequence[a] = createPolygonLinePrimitive(getUnitPolyPolygon().getB2DPolygon(a), getTransform(), aBlackHairline); } appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, Primitive2DReference(new HitTestPrimitive2D(xHiddenLineSequence))); } // add text - if(maSdrLFSTAttribute.getText()) + if(getSdrLFSTAttribute().getText()) { - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createTextPrimitive(maUnitPolyPolygon, maTransform, *maSdrLFSTAttribute.getText(), maSdrLFSTAttribute.getLine(), false, false)); + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createTextPrimitive(getUnitPolyPolygon(), getTransform(), *getSdrLFSTAttribute().getText(), getSdrLFSTAttribute().getLine(), false, false)); } // add shadow - if(maSdrLFSTAttribute.getShadow()) + if(getSdrLFSTAttribute().getShadow()) { - // attention: shadow is added BEFORE object stuff to render it BEHIND object (!) - const Primitive2DReference xShadow(createShadowPrimitive(aRetval, *maSdrLFSTAttribute.getShadow())); - - if(xShadow.is()) - { - Primitive2DSequence aContentWithShadow(2L); - aContentWithShadow[0L] = xShadow; - aContentWithShadow[1L] = Primitive2DReference(new GroupPrimitive2D(aRetval)); - aRetval = aContentWithShadow; - } + aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow()); } return aRetval; } SdrPathPrimitive2D::SdrPathPrimitive2D( - const ::basegfx::B2DHomMatrix& rTransform, + const basegfx::B2DHomMatrix& rTransform, const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute, - const ::basegfx::B2DPolyPolygon& rUnitPolyPolygon) + const basegfx::B2DPolyPolygon& rUnitPolyPolygon) : BasePrimitive2D(), maTransform(rTransform), maSdrLFSTAttribute(rSdrLFSTAttribute), @@ -127,9 +118,9 @@ namespace drawinglayer { const SdrPathPrimitive2D& rCompare = (SdrPathPrimitive2D&)rPrimitive; - return (maUnitPolyPolygon == rCompare.maUnitPolyPolygon - && maTransform == rCompare.maTransform - && maSdrLFSTAttribute == rCompare.maSdrLFSTAttribute); + return (getUnitPolyPolygon() == rCompare.getUnitPolyPolygon() + && getTransform() == rCompare.getTransform() + && getSdrLFSTAttribute() == rCompare.getSdrLFSTAttribute()); } return false; diff --git a/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx index 97aaf2735630..64ac716b40e9 100644 --- a/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx @@ -50,65 +50,90 @@ namespace drawinglayer Primitive2DSequence SdrRectanglePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const { Primitive2DSequence aRetval; + Primitive2DSequence aHitTestContent; // create unit outline polygon - ::basegfx::B2DPolygon aUnitOutline(::basegfx::tools::createPolygonFromRect(::basegfx::B2DRange(0.0, 0.0, 1.0, 1.0), getCornerRadiusX(), getCornerRadiusY())); + const basegfx::B2DPolygon aUnitOutline(basegfx::tools::createPolygonFromRect( + basegfx::B2DRange(0.0, 0.0, 1.0, 1.0), + getCornerRadiusX(), + getCornerRadiusY())); // add fill if(getSdrLFSTAttribute().getFill()) { - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createPolyPolygonFillPrimitive(::basegfx::B2DPolyPolygon(aUnitOutline), getTransform(), *getSdrLFSTAttribute().getFill(), getSdrLFSTAttribute().getFillFloatTransGradient())); + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + *getSdrLFSTAttribute().getFill(), + getSdrLFSTAttribute().getFillFloatTransGradient())); + } + else if(getTextFrame()) + { + // if no fill and it's a text frame, create a fill for HitTest and + // BoundRect fallback + appendPrimitive2DReferenceToPrimitive2DSequence(aHitTestContent, + createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + attribute::SdrFillAttribute(0.0, basegfx::BColor(0.0, 0.0, 0.0)), + getSdrLFSTAttribute().getFillFloatTransGradient())); } // add line if(getSdrLFSTAttribute().getLine()) { - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createPolygonLinePrimitive(aUnitOutline, getTransform(), *getSdrLFSTAttribute().getLine())); + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + aUnitOutline, + getTransform(), + *getSdrLFSTAttribute().getLine())); } - else + else if(!getTextFrame()) { - // if initially no line is defined, create one for HitTest and BoundRect - const attribute::SdrLineAttribute aBlackHairline(basegfx::BColor(0.0, 0.0, 0.0)); - const Primitive2DReference xHiddenLineReference(createPolygonLinePrimitive(aUnitOutline, getTransform(), aBlackHairline)); - const Primitive2DSequence xHiddenLineSequence(&xHiddenLineReference, 1); + // if initially no line is defined and it's not a text frame, create + // a line for HitTest and BoundRect + appendPrimitive2DReferenceToPrimitive2DSequence(aHitTestContent, + createPolygonLinePrimitive( + aUnitOutline, + getTransform(), + attribute::SdrLineAttribute(basegfx::BColor(0.0, 0.0, 0.0)))); + } - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, Primitive2DReference(new HitTestPrimitive2D(xHiddenLineSequence))); + // add HitTest and BoundRect helper geometry (if exists) + if(aHitTestContent.hasElements()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + Primitive2DReference(new HitTestPrimitive2D(aHitTestContent))); } // add text if(getSdrLFSTAttribute().getText()) { - appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createTextPrimitive(::basegfx::B2DPolyPolygon(aUnitOutline), getTransform(), *getSdrLFSTAttribute().getText(), getSdrLFSTAttribute().getLine(), false, false)); + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, createTextPrimitive(basegfx::B2DPolyPolygon(aUnitOutline), getTransform(), *getSdrLFSTAttribute().getText(), getSdrLFSTAttribute().getLine(), false, false)); } // add shadow if(getSdrLFSTAttribute().getShadow()) { - // attention: shadow is added BEFORE object stuff to render it BEHIND object (!) - const Primitive2DReference xShadow(createShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow())); - - if(xShadow.is()) - { - Primitive2DSequence aContentWithShadow(2L); - aContentWithShadow[0L] = xShadow; - aContentWithShadow[1L] = Primitive2DReference(new GroupPrimitive2D(aRetval)); - aRetval = aContentWithShadow; - } + aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrLFSTAttribute().getShadow()); } return aRetval; } SdrRectanglePrimitive2D::SdrRectanglePrimitive2D( - const ::basegfx::B2DHomMatrix& rTransform, + const basegfx::B2DHomMatrix& rTransform, const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute, double fCornerRadiusX, - double fCornerRadiusY) + double fCornerRadiusY, + bool bTextFrame) : BasePrimitive2D(), maTransform(rTransform), maSdrLFSTAttribute(rSdrLFSTAttribute), mfCornerRadiusX(fCornerRadiusX), - mfCornerRadiusY(fCornerRadiusY) + mfCornerRadiusY(fCornerRadiusY), + mbTextFrame(bTextFrame) { } @@ -121,7 +146,8 @@ namespace drawinglayer return (getCornerRadiusX() == rCompare.getCornerRadiusX() && getCornerRadiusY() == rCompare.getCornerRadiusY() && getTransform() == rCompare.getTransform() - && getSdrLFSTAttribute() == rCompare.getSdrLFSTAttribute()); + && getSdrLFSTAttribute() == rCompare.getSdrLFSTAttribute() + && getTextFrame() == rCompare.getTextFrame()); } return false; diff --git a/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx index 113cd226d8ba..0cad266f69d1 100644 --- a/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx @@ -41,6 +41,9 @@ #include <drawinglayer/geometry/viewinformation2d.hxx> #include <unoapi.hxx> #include <svx/svdpage.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdoutl.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> ////////////////////////////////////////////////////////////////////////////// @@ -48,6 +51,46 @@ using namespace com::sun::star; ////////////////////////////////////////////////////////////////////////////// +namespace +{ + sal_Int16 getPageNumber(const uno::Reference< drawing::XDrawPage >& rxDrawPage) + { + sal_Int16 nRetval(0); + uno::Reference< beans::XPropertySet > xSet(rxDrawPage, uno::UNO_QUERY); + + if (xSet.is()) + { + try + { + const uno::Any aNumber(xSet->getPropertyValue(::rtl::OUString::createFromAscii("Number"))); + aNumber >>= nRetval; + } + catch(const uno::Exception&) + { + OSL_ASSERT(false); + } + } + + return nRetval; + } + + sal_Int16 getPageCount(const uno::Reference< drawing::XDrawPage >& rxDrawPage) + { + sal_Int16 nRetval(0); + SdrPage* pPage = GetSdrPageFromXDrawPage(rxDrawPage); + + if(pPage && pPage->GetModel()) + { + const sal_uInt16 nPageCount(pPage->GetModel()->GetPageCount()); + nRetval = ((sal_Int16)nPageCount - 1) / 2; + } + + return nRetval; + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + namespace drawinglayer { namespace primitive2d @@ -64,20 +107,28 @@ namespace drawinglayer } SdrTextPrimitive2D::SdrTextPrimitive2D( - const SdrText& rSdrText, + const SdrText* pSdrText, const OutlinerParaObject& rOutlinerParaObject) : BasePrimitive2D(), - mrSdrText(rSdrText), + mrSdrText(const_cast< SdrText* >(pSdrText)), maOutlinerParaObject(rOutlinerParaObject), mxLastVisualizingPage(), + mnLastPageNumber(0), + mnLastPageCount(0), + maLastTextBackgroundColor(), mbLastSpellCheck(false), - mbContainsPageField(false) + mbContainsPageField(false), + mbContainsPageCountField(false), + mbContainsOtherFields(false) { const EditTextObject& rETO = maOutlinerParaObject.GetTextObject(); - mbContainsPageField = rETO.HasField(SvxPageField::StaticType()) - || rETO.HasField(SvxHeaderField::StaticType()) - || rETO.HasField(SvxFooterField::StaticType()) - || rETO.HasField(SvxDateTimeField::StaticType()); +
+ mbContainsPageField = rETO.HasField(SvxPageField::StaticType());
+ mbContainsPageCountField = rETO.HasField(SvxPagesField::StaticType());
+ mbContainsOtherFields = rETO.HasField(SvxHeaderField::StaticType())
+ || rETO.HasField(SvxFooterField::StaticType())
+ || rETO.HasField(SvxDateTimeField::StaticType())
+ || rETO.HasField(SvxAuthorField::StaticType());
} bool SdrTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const @@ -94,21 +145,66 @@ namespace drawinglayer Primitive2DSequence SdrTextPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { - const bool bCurrentSpellCheck(getSdrText().GetObject().impCheckSpellCheckForDecomposeTextPrimitive()); + const bool bCurrentSpellCheck(getSdrText() + ? getSdrText()->GetObject().impCheckSpellCheckForDecomposeTextPrimitive() + : false); uno::Reference< drawing::XDrawPage > xCurrentlyVisualizingPage; + bool bCurrentlyVisualizingPageIsSet(false); + Color aNewTextBackgroundColor; + bool bNewTextBackgroundColorIsSet(false); + sal_Int16 nCurrentlyValidPageNumber(0); + sal_Int16 nCurrentlyValidPageCount(0); if(getLocalDecomposition().hasElements()) { bool bDoDelete(getLastSpellCheck() != bCurrentSpellCheck); - if(!bDoDelete && mbContainsPageField) + // check visualized page + if(!bDoDelete && (mbContainsPageField || mbContainsPageCountField || mbContainsOtherFields)) { + // get visualized page and remember xCurrentlyVisualizingPage = rViewInformation.getVisualizedPage(); + bCurrentlyVisualizingPageIsSet = true; if(xCurrentlyVisualizingPage != mxLastVisualizingPage) { bDoDelete = true; } + + // #i98870# check visualized PageNumber + if(!bDoDelete && mbContainsPageField) + { + nCurrentlyValidPageNumber = getPageNumber(xCurrentlyVisualizingPage); + + if(nCurrentlyValidPageNumber != mnLastPageNumber) + { + bDoDelete = true; + } + } + + // #i98870# check visualized PageCount, too + if(!bDoDelete && mbContainsPageCountField) + { + nCurrentlyValidPageCount = getPageCount(xCurrentlyVisualizingPage); + + if(nCurrentlyValidPageCount != mnLastPageCount) + { + bDoDelete = true; + } + } + } + + // #i101443# check change of TextBackgroundolor + if(!bDoDelete && getSdrText() && getSdrText()->GetModel()) + { + SdrOutliner& rDrawOutliner = getSdrText()->GetModel()->GetDrawOutliner(0); + aNewTextBackgroundColor = rDrawOutliner.GetBackgroundColor(); + bNewTextBackgroundColorIsSet = true; + + if(aNewTextBackgroundColor != maLastTextBackgroundColor) + { + bDoDelete = true; + } } if(bDoDelete) @@ -119,8 +215,32 @@ namespace drawinglayer if(!getLocalDecomposition().hasElements()) { + if(!bCurrentlyVisualizingPageIsSet && mbContainsPageField) + { + xCurrentlyVisualizingPage = rViewInformation.getVisualizedPage(); + } + + if(!nCurrentlyValidPageNumber && mbContainsPageField) + { + nCurrentlyValidPageNumber = getPageNumber(xCurrentlyVisualizingPage); + } + + if(!nCurrentlyValidPageCount && mbContainsPageCountField) + { + nCurrentlyValidPageCount = getPageCount(xCurrentlyVisualizingPage); + } + + if(!bNewTextBackgroundColorIsSet && getSdrText() && getSdrText()->GetModel()) + { + SdrOutliner& rDrawOutliner = getSdrText()->GetModel()->GetDrawOutliner(0); + aNewTextBackgroundColor = rDrawOutliner.GetBackgroundColor(); + } + const_cast< SdrTextPrimitive2D* >(this)->setLastSpellCheck(bCurrentSpellCheck); const_cast< SdrTextPrimitive2D* >(this)->mxLastVisualizingPage = xCurrentlyVisualizingPage; + const_cast< SdrTextPrimitive2D* >(this)->mnLastPageNumber = nCurrentlyValidPageNumber; + const_cast< SdrTextPrimitive2D* >(this)->mnLastPageCount = nCurrentlyValidPageCount; + const_cast< SdrTextPrimitive2D* >(this)->maLastTextBackgroundColor = aNewTextBackgroundColor; } // call parent @@ -138,7 +258,9 @@ namespace drawinglayer Primitive2DSequence SdrContourTextPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& aViewInformation) const { Primitive2DSequence aRetval; - const bool bCurrentSpellCheck(getSdrText().GetObject().impDecomposeContourTextPrimitive(aRetval, *this, aViewInformation)); + const bool bCurrentSpellCheck(getSdrText() + ? getSdrText()->GetObject().impDecomposeContourTextPrimitive(aRetval, *this, aViewInformation) + : false); if(getLastSpellCheck() != bCurrentSpellCheck) { @@ -150,11 +272,11 @@ namespace drawinglayer } SdrContourTextPrimitive2D::SdrContourTextPrimitive2D( - const SdrText& rSdrText, + const SdrText* pSdrText, const OutlinerParaObject& rOutlinerParaObject, - const ::basegfx::B2DPolyPolygon& rUnitPolyPolygon, - const ::basegfx::B2DHomMatrix& rObjectTransform) - : SdrTextPrimitive2D(rSdrText, rOutlinerParaObject), + const basegfx::B2DPolyPolygon& rUnitPolyPolygon, + const basegfx::B2DHomMatrix& rObjectTransform) + : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), maUnitPolyPolygon(rUnitPolyPolygon), maObjectTransform(rObjectTransform) { @@ -166,16 +288,20 @@ namespace drawinglayer { const SdrContourTextPrimitive2D& rCompare = (SdrContourTextPrimitive2D&)rPrimitive; - return (maUnitPolyPolygon == rCompare.maUnitPolyPolygon - && maObjectTransform == rCompare.maObjectTransform); + return (getUnitPolyPolygon() == rCompare.getUnitPolyPolygon() + && getObjectTransform() == rCompare.getObjectTransform()); } return false; } - SdrTextPrimitive2D* SdrContourTextPrimitive2D::createTransformedClone(const ::basegfx::B2DHomMatrix& rTransform) const + SdrTextPrimitive2D* SdrContourTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const { - return new SdrContourTextPrimitive2D(getSdrText(), getOutlinerParaObject(), maUnitPolyPolygon, rTransform * maObjectTransform); + return new SdrContourTextPrimitive2D( + getSdrText(), + getOutlinerParaObject(), + getUnitPolyPolygon(), + rTransform * getObjectTransform()); } // provide unique ID @@ -193,7 +319,9 @@ namespace drawinglayer Primitive2DSequence SdrPathTextPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& aViewInformation) const { Primitive2DSequence aRetval; - const bool bCurrentSpellCheck(getSdrText().GetObject().impDecomposePathTextPrimitive(aRetval, *this, aViewInformation)); + const bool bCurrentSpellCheck(getSdrText() + ? getSdrText()->GetObject().impDecomposePathTextPrimitive(aRetval, *this, aViewInformation) + : false); if(getLastSpellCheck() != bCurrentSpellCheck) { @@ -205,11 +333,13 @@ namespace drawinglayer } SdrPathTextPrimitive2D::SdrPathTextPrimitive2D( - const SdrText& rSdrText, + const SdrText* pSdrText, const OutlinerParaObject& rOutlinerParaObject, - const ::basegfx::B2DPolyPolygon& rPathPolyPolygon) - : SdrTextPrimitive2D(rSdrText, rOutlinerParaObject), - maPathPolyPolygon(rPathPolyPolygon) + const basegfx::B2DPolyPolygon& rPathPolyPolygon, + const attribute::SdrFormTextAttribute& rSdrFormTextAttribute) + : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), + maPathPolyPolygon(rPathPolyPolygon), + maSdrFormTextAttribute(rSdrFormTextAttribute) { } @@ -219,17 +349,23 @@ namespace drawinglayer { const SdrPathTextPrimitive2D& rCompare = (SdrPathTextPrimitive2D&)rPrimitive; - return (maPathPolyPolygon == rCompare.maPathPolyPolygon); + return (getPathPolyPolygon() == rCompare.getPathPolyPolygon() + && getSdrFormTextAttribute() == rCompare.getSdrFormTextAttribute()); } return false; } - SdrTextPrimitive2D* SdrPathTextPrimitive2D::createTransformedClone(const ::basegfx::B2DHomMatrix& rTransform) const + SdrTextPrimitive2D* SdrPathTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const { - ::basegfx::B2DPolyPolygon aNewPolyPolygon(maPathPolyPolygon); + basegfx::B2DPolyPolygon aNewPolyPolygon(getPathPolyPolygon()); aNewPolyPolygon.transform(rTransform); - return new SdrPathTextPrimitive2D(getSdrText(), getOutlinerParaObject(), aNewPolyPolygon); + + return new SdrPathTextPrimitive2D( + getSdrText(), + getOutlinerParaObject(), + aNewPolyPolygon, + getSdrFormTextAttribute()); } // provide unique ID @@ -247,7 +383,9 @@ namespace drawinglayer Primitive2DSequence SdrBlockTextPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& aViewInformation) const { Primitive2DSequence aRetval; - const bool bCurrentSpellCheck(getSdrText().GetObject().impDecomposeBlockTextPrimitive(aRetval, *this, aViewInformation)); + const bool bCurrentSpellCheck(getSdrText() + ? getSdrText()->GetObject().impDecomposeBlockTextPrimitive(aRetval, *this, aViewInformation) + : false); if(getLastSpellCheck() != bCurrentSpellCheck) { @@ -259,13 +397,13 @@ namespace drawinglayer } SdrBlockTextPrimitive2D::SdrBlockTextPrimitive2D( - const SdrText& rSdrText, + const SdrText* pSdrText, const OutlinerParaObject& rOutlinerParaObject, - const ::basegfx::B2DHomMatrix& rTextRangeTransform, + const basegfx::B2DHomMatrix& rTextRangeTransform, bool bUnlimitedPage, bool bCellText, bool bWordWrap) - : SdrTextPrimitive2D(rSdrText, rOutlinerParaObject), + : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), maTextRangeTransform(rTextRangeTransform), mbUnlimitedPage(bUnlimitedPage), mbCellText(bCellText), @@ -288,9 +426,15 @@ namespace drawinglayer return false; } - SdrTextPrimitive2D* SdrBlockTextPrimitive2D::createTransformedClone(const ::basegfx::B2DHomMatrix& rTransform) const + SdrTextPrimitive2D* SdrBlockTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const { - return new SdrBlockTextPrimitive2D(getSdrText(), getOutlinerParaObject(), rTransform * getTextRangeTransform(), getUnlimitedPage(), getCellText(), getWordWrap()); + return new SdrBlockTextPrimitive2D( + getSdrText(), + getOutlinerParaObject(), + rTransform * getTextRangeTransform(), + getUnlimitedPage(), + getCellText(), + getWordWrap()); } // provide unique ID @@ -308,7 +452,9 @@ namespace drawinglayer Primitive2DSequence SdrStretchTextPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& aViewInformation) const { Primitive2DSequence aRetval; - const bool bCurrentSpellCheck(getSdrText().GetObject().impDecomposeStretchTextPrimitive(aRetval, *this, aViewInformation)); + const bool bCurrentSpellCheck(getSdrText() + ? getSdrText()->GetObject().impDecomposeStretchTextPrimitive(aRetval, *this, aViewInformation) + : false); if(getLastSpellCheck() != bCurrentSpellCheck) { @@ -320,10 +466,10 @@ namespace drawinglayer } SdrStretchTextPrimitive2D::SdrStretchTextPrimitive2D( - const SdrText& rSdrText, + const SdrText* pSdrText, const OutlinerParaObject& rOutlinerParaObject, - const ::basegfx::B2DHomMatrix& rTextRangeTransform) - : SdrTextPrimitive2D(rSdrText, rOutlinerParaObject), + const basegfx::B2DHomMatrix& rTextRangeTransform) + : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), maTextRangeTransform(rTextRangeTransform) { } @@ -334,15 +480,18 @@ namespace drawinglayer { const SdrStretchTextPrimitive2D& rCompare = (SdrStretchTextPrimitive2D&)rPrimitive; - return (maTextRangeTransform == rCompare.maTextRangeTransform); + return (getTextRangeTransform() == rCompare.getTextRangeTransform()); } return false; } - SdrTextPrimitive2D* SdrStretchTextPrimitive2D::createTransformedClone(const ::basegfx::B2DHomMatrix& rTransform) const + SdrTextPrimitive2D* SdrStretchTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const { - return new SdrStretchTextPrimitive2D(getSdrText(), getOutlinerParaObject(), rTransform * maTextRangeTransform); + return new SdrStretchTextPrimitive2D( + getSdrText(), + getOutlinerParaObject(), + rTransform * getTextRangeTransform()); } // provide unique ID diff --git a/svx/source/sdr/properties/properties.cxx b/svx/source/sdr/properties/properties.cxx index 3445e134fd0a..b3cc32d71536 100644 --- a/svx/source/sdr/properties/properties.cxx +++ b/svx/source/sdr/properties/properties.cxx @@ -180,6 +180,11 @@ namespace sdr GetSdrObject().SendUserCall(SDRUSERCALL_CHGATTR, rChange.GetRectangle(a)); } } + + sal_uInt32 BaseProperties::getVersion() const + { + return 0; + } } // end of namespace properties } // end of namespace sdr diff --git a/svx/source/sdr/properties/textproperties.cxx b/svx/source/sdr/properties/textproperties.cxx index 5fb566e77dc2..f720e1b9d1b2 100644 --- a/svx/source/sdr/properties/textproperties.cxx +++ b/svx/source/sdr/properties/textproperties.cxx @@ -72,12 +72,14 @@ namespace sdr } TextProperties::TextProperties(SdrObject& rObj) - : AttributeProperties(rObj) + : AttributeProperties(rObj), + maVersion(0) { } TextProperties::TextProperties(const TextProperties& rProps, SdrObject& rObj) - : AttributeProperties(rProps, rObj) + : AttributeProperties(rProps, rObj), + maVersion(rProps.getVersion()) { } @@ -93,10 +95,11 @@ namespace sdr void TextProperties::ItemSetChanged(const SfxItemSet& rSet) { SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); - - sal_Int32 nText = rObj.getTextCount(); + // #i101556# ItemSet has changed -> new version + maVersion++; + while( --nText >= 0 ) { SdrText* pText = rObj.getText( nText ); @@ -237,6 +240,9 @@ namespace sdr // call parent AttributeProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + // #i101556# StyleSheet has changed -> new version + maVersion++; + if( rObj.GetModel() /*&& !rObj.IsTextEditActive()*/ && !rObj.IsLinkedText() ) { SdrOutliner& rOutliner = rObj.ImpGetDrawOutliner(); @@ -577,6 +583,9 @@ namespace sdr rObj.ActionChanged(); //rObj.BroadcastObjectChange(); } + + // #i101556# content of StyleSheet has changed -> new version + maVersion++; } if(SFX_HINT_DYING == nId) @@ -616,6 +625,12 @@ namespace sdr } } } + + // #i101556# Handout version information + sal_uInt32 TextProperties::getVersion() const + { + return maVersion; + } } // end of namespace properties } // end of namespace sdr |