diff options
author | Armin Le Grand <alg@apache.org> | 2014-04-10 14:08:57 +0000 |
---|---|---|
committer | Armin Le Grand <alg@apache.org> | 2014-04-10 14:08:57 +0000 |
commit | 4cff340fbe1f20a3a05cc5e541cfcbd735287e2d (patch) | |
tree | f2e7e1aed630425d1ab7960588e28843084c0be0 | |
parent | 6ca3a9faca825e0e3c44de9f47f4c684d31f86b1 (diff) |
in-between results/corrections/improvemnts
-rw-r--r-- | drawinglayer/source/processor2d/vclhelperbitmaprender.cxx | 283 | ||||
-rw-r--r-- | sd/source/ui/func/fudraw.cxx | 2 | ||||
-rw-r--r-- | sd/source/ui/view/drviews7.cxx | 177 | ||||
-rw-r--r-- | svx/inc/svx/svdlegacy.hxx | 17 | ||||
-rw-r--r-- | svx/source/svdraw/svdedtv1.cxx | 153 | ||||
-rw-r--r-- | svx/source/svdraw/svdlegacy.cxx | 40 | ||||
-rw-r--r-- | svx/source/svdraw/svdmrkv.cxx | 60 | ||||
-rw-r--r-- | svx/source/svdraw/svdograf.cxx | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdopath.cxx | 34 | ||||
-rw-r--r-- | xmloff/source/draw/ximpshap.cxx | 9 |
10 files changed, 285 insertions, 492 deletions
diff --git a/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx b/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx deleted file mode 100644 index 6053c483bb76..000000000000 --- a/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx +++ /dev/null @@ -1,283 +0,0 @@ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ - - - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_drawinglayer.hxx" - -#include <vclhelperbitmaprender.hxx> -#include <svtools/grfmgr.hxx> -#include <basegfx/vector/b2dvector.hxx> -#include <basegfx/matrix/b2dhommatrix.hxx> -#include <basegfx/range/b2drange.hxx> -#include <vcl/outdev.hxx> -#include <vclhelperbitmaptransform.hxx> -#include <basegfx/matrix/b2dhommatrixtools.hxx> - -////////////////////////////////////////////////////////////////////////////// -// support for different kinds of bitmap rendering using vcl - -namespace drawinglayer -{ - void RenderBitmapPrimitive2D_GraphicManager( - OutputDevice& rOutDev, - const BitmapEx& rBitmapEx, - const basegfx::B2DHomMatrix& rTransform) - { - // prepare attributes - GraphicAttr aAttributes; - - // decompose matrix to check for shear, rotate and mirroring - basegfx::B2DVector aScale; - basegfx::B2DPoint aTranslate; - double fRotate, fShearX; - rTransform.decompose(aScale, aTranslate, fRotate, fShearX); - - // mirror flags - const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0)); - const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0)); - aAttributes.SetMirrorFlags((bMirrorX ? BMP_MIRROR_HORZ : 0)|(bMirrorY ? BMP_MIRROR_VERT : 0)); - - // rotation - if(!basegfx::fTools::equalZero(fRotate)) - { - double fRotation(fmod(3600.0 - (fRotate * (10.0 / F_PI180)), 3600.0)); - aAttributes.SetRotation((sal_uInt16)(fRotation)); - } - - // prepare Bitmap - basegfx::B2DRange aOutlineRange(basegfx::B2DRange::getUnitB2DRange()); - - if(basegfx::fTools::equalZero(fRotate)) - { - aOutlineRange.transform(rTransform); - } - else - { - // if rotated, create the unrotated output rectangle for the GraphicManager paint - // #118824# Caution! When mirrored, adapt transformation accordingly - const basegfx::B2DHomMatrix aSimpleObjectMatrix( - basegfx::tools::createScaleTranslateB2DHomMatrix( - fabs(aScale.getX()), - fabs(aScale.getY()), - bMirrorX ? aTranslate.getX() - fabs(aScale.getX()): aTranslate.getX(), - bMirrorY ? aTranslate.getY() - fabs(aScale.getY()): aTranslate.getY())); - - aOutlineRange.transform(aSimpleObjectMatrix); - } - - // prepare dest coordinates - const Point aPoint( - basegfx::fround(aOutlineRange.getMinX()), - basegfx::fround(aOutlineRange.getMinY())); - const Size aSize( - basegfx::fround(aOutlineRange.getWidth()), - basegfx::fround(aOutlineRange.getHeight())); - - // paint it using GraphicManager - Graphic aGraphic(rBitmapEx); - GraphicObject aGraphicObject(aGraphic); - aGraphicObject.Draw(&rOutDev, aPoint, aSize, &aAttributes); - } - - void RenderBitmapPrimitive2D_BitmapEx( - OutputDevice& rOutDev, - const BitmapEx& rBitmapEx, - const basegfx::B2DHomMatrix& rTransform) - { - // only translate and scale, use vcl's DrawBitmapEx(). - BitmapEx aContent(rBitmapEx); - - // prepare dest coor. Necessary to expand since vcl's DrawBitmapEx draws one pix less - const basegfx::B2DRange aOutlineRange(rTransform * basegfx::B2DRange::getUnitB2DRange()); - - // prepare dest coordinates - const Point aPoint( - basegfx::fround(aOutlineRange.getMinX()), - basegfx::fround(aOutlineRange.getMinY())); - const Size aSize( - basegfx::fround(aOutlineRange.getWidth()), - basegfx::fround(aOutlineRange.getHeight())); - - // decompose matrix to check for shear, rotate and mirroring - basegfx::B2DVector aScale; - basegfx::B2DPoint aTranslate; - double fRotate, fShearX; - rTransform.decompose(aScale, aTranslate, fRotate, fShearX); - - // Check mirroring. - sal_uInt32 nMirrorFlags(BMP_MIRROR_NONE); - - if(basegfx::fTools::less(aScale.getX(), 0.0)) - { - nMirrorFlags |= BMP_MIRROR_HORZ; - } - - if(basegfx::fTools::less(aScale.getY(), 0.0)) - { - nMirrorFlags |= BMP_MIRROR_VERT; - } - - if(BMP_MIRROR_NONE != nMirrorFlags) - { - aContent.Mirror(nMirrorFlags); - } - - // draw bitmap - rOutDev.DrawBitmapEx(aPoint, aSize, aContent); - } - - void RenderBitmapPrimitive2D_self( - OutputDevice& rOutDev, - const BitmapEx& rBitmapEx, - const basegfx::B2DHomMatrix& rTransform) - { - // process self with free transformation (containing shear and rotate). Get dest rect in pixels. - const basegfx::B2DRange aOutlineRange(rTransform * basegfx::B2DRange::getUnitB2DRange()); - const Rectangle aDestRectLogic( - basegfx::fround(aOutlineRange.getMinX()), - basegfx::fround(aOutlineRange.getMinY()), - basegfx::fround(aOutlineRange.getMaxX()), - basegfx::fround(aOutlineRange.getMaxY())); - const Rectangle aDestRectPixel(rOutDev.LogicToPixel(aDestRectLogic)); - - // #i96708# check if Metafile is recorded - const GDIMetaFile* pMetaFile = rOutDev.GetConnectMetaFile(); - const bool bRecordToMetaFile(pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause()); - - // intersect with output pixel size, but only - // when not recording to metafile - const Rectangle aOutputRectPixel(Point(), rOutDev.GetOutputSizePixel()); - Rectangle aCroppedRectPixel(bRecordToMetaFile ? aDestRectPixel : aDestRectPixel.GetIntersection(aOutputRectPixel)); - - if(!aCroppedRectPixel.IsEmpty()) - { - // as maximum for destination, orientate at aOutputRectPixel, but - // take a rotation of 45 degrees (sqrt(2)) as maximum expansion into account - const Size aSourceSizePixel(rBitmapEx.GetSizePixel()); - const double fMaximumArea( - - // #121153# With Metafile, aOutputRectPixel may be empty and a virtual - // maximum quadratic size has to be used - bRecordToMetaFile ? 500000.0 : - - (double)aOutputRectPixel.getWidth() * - (double)aOutputRectPixel.getHeight() * - 1.4142136); // 1.4142136 taken as sqrt(2.0) - - // test if discrete view size (pixel) maybe too big and limit it - const double fArea(aCroppedRectPixel.getWidth() * aCroppedRectPixel.getHeight()); - const bool bNeedToReduce(fArea > fMaximumArea); - double fReduceFactor(1.0); - const Size aDestSizePixel(aCroppedRectPixel.GetSize()); - - if(bNeedToReduce) - { - fReduceFactor = sqrt(fMaximumArea / fArea); - aCroppedRectPixel.setWidth(basegfx::fround(aCroppedRectPixel.getWidth() * fReduceFactor)); - aCroppedRectPixel.setHeight(basegfx::fround(aCroppedRectPixel.getHeight() * fReduceFactor)); - } - - // build transform from pixel in aDestination to pixel in rBitmapEx - // from relative in aCroppedRectPixel to relative in aDestRectPixel - // No need to take bNeedToReduce into account, TopLeft is unchanged - basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix( - aCroppedRectPixel.Left() - aDestRectPixel.Left(), - aCroppedRectPixel.Top() - aDestRectPixel.Top())); - - // from relative in aDestRectPixel to absolute Logic. Here it - // is essential to adapt to reduce factor (if used) - double fAdaptedDRPWidth((double)aDestRectPixel.getWidth()); - double fAdaptedDRPHeight((double)aDestRectPixel.getHeight()); - - if(bNeedToReduce) - { - fAdaptedDRPWidth *= fReduceFactor; - fAdaptedDRPHeight *= fReduceFactor; - } - - aTransform = basegfx::tools::createScaleTranslateB2DHomMatrix( - aDestRectLogic.getWidth() / fAdaptedDRPWidth, aDestRectLogic.getHeight() / fAdaptedDRPHeight, - aDestRectLogic.Left(), aDestRectLogic.Top()) - * aTransform; - - // from absolute in Logic to unified object coordinates (0.0 .. 1.0 in x and y) - basegfx::B2DHomMatrix aInvBitmapTransform(rTransform); - aInvBitmapTransform.invert(); - aTransform = aInvBitmapTransform * aTransform; - - // from unit object coordinates to rBitmapEx pixel coordintes - aTransform.scale(aSourceSizePixel.getWidth() - 1L, aSourceSizePixel.getHeight() - 1L); - - // create bitmap using source, destination and linear back-transformation - BitmapEx aDestination = impTransformBitmapEx(rBitmapEx, aCroppedRectPixel, aTransform); - - // paint - if(bNeedToReduce) - { - // paint in target size - if(bRecordToMetaFile) - { - rOutDev.DrawBitmapEx( - rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()), - rOutDev.PixelToLogic(aDestSizePixel), - aDestination); - } - else - { - const bool bWasEnabled(rOutDev.IsMapModeEnabled()); - rOutDev.EnableMapMode(false); - - rOutDev.DrawBitmapEx( - aCroppedRectPixel.TopLeft(), - aDestSizePixel, - aDestination); - - rOutDev.EnableMapMode(bWasEnabled); - } - } - else - { - if(bRecordToMetaFile) - { - rOutDev.DrawBitmapEx( - rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()), - aDestination); - } - else - { - const bool bWasEnabled(rOutDev.IsMapModeEnabled()); - rOutDev.EnableMapMode(false); - - rOutDev.DrawBitmapEx( - aCroppedRectPixel.TopLeft(), - aDestination); - - rOutDev.EnableMapMode(bWasEnabled); - } - } - } - } -} // end of namespace drawinglayer - -////////////////////////////////////////////////////////////////////////////// -// eof diff --git a/sd/source/ui/func/fudraw.cxx b/sd/source/ui/func/fudraw.cxx index ace344ff5e46..0ba5a2fb82bb 100644 --- a/sd/source/ui/func/fudraw.cxx +++ b/sd/source/ui/func/fudraw.cxx @@ -457,7 +457,7 @@ bool FuDraw::KeyInput(const KeyEvent& rKEvt) if(!mpView->MarkNextObj( !aCode.IsShift() )) { //If there is only one object, don't do the UnmarkAlllObj() & MarkNextObj(). - if ( mpView->getSelectedSdrObjectCount() > 1 ) + if ( mpView->areSdrObjectsSelected() && mpView->GetMarkableObjCount() > 1 ) { // #97016# No next object: go over open end and // get first from the other side diff --git a/sd/source/ui/view/drviews7.cxx b/sd/source/ui/view/drviews7.cxx index 517db0e0e50e..2bfb335a3cbe 100644 --- a/sd/source/ui/view/drviews7.cxx +++ b/sd/source/ui/view/drviews7.cxx @@ -19,10 +19,9 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sd.hxx" + #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/lang/Locale.hpp> #include <com/sun/star/linguistic2/XThesaurus.hpp> @@ -46,8 +45,6 @@ #include <editeng/unolingu.hxx> #include <svx/extrusionbar.hxx> #include <svx/fontworkbar.hxx> - -// #UndoRedo# #include <svl/slstitm.hxx> #include <sfx2/app.hxx> #include <svtools/insdlg.hxx> @@ -55,18 +52,17 @@ #include <svl/languageoptions.hxx> #include <comphelper/processfactory.hxx> #include <sfx2/request.hxx> - - +#include <svx/svdoole2.hxx> #include <svx/pfiledlg.hxx> #include <svx/grafctrl.hxx> #include <svtools/cliplistener.hxx> #include <sfx2/viewfrm.hxx> +#include <svx/svdotable.hxx> #include "app.hrc" #include "glob.hrc" #include "res_bmp.hrc" #include "PresentationViewShell.hxx" - #include "misc.hxx" #include "Outliner.hxx" #include "drawdoc.hxx" @@ -1424,125 +1420,110 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet ) for(sal_uInt32 i(0); i < aSelection.size() && !bFoundAny; i++) { SdrObject* pObj = aSelection[i]; - const sal_uInt16 nId(pObj->GetObjIdentifier()); - const sal_uInt32 nInv(pObj->GetObjInventor()); - if(nInv == SdrInventor) + if(pObj) { - // 2D objects - switch( nId ) + if(dynamic_cast< SdrPathObj* >(pObj) || dynamic_cast< SdrCircObj* >(pObj) || dynamic_cast< SdrEdgeObj* >(pObj)) { - case OBJ_POLY: + // OBJ_POLY, OBJ_CIRC and OBJ_EDGE; decision depends on closed or not (fill possible) + if(pObj->IsClosedObj()) { - SdrPathObj* pSdrPathObj = dynamic_cast< SdrPathObj* >(pObj); - - if(pSdrPathObj) - { - switch(pSdrPathObj->getSdrPathObjType()) - { - case PathType_Line: - case PathType_OpenPolygon: - case PathType_OpenBezier: - { - bFoundObjNoArea = true; - bFoundNoGraphicObj = true; - break; - } - default: - break; - } - } - else - { - OSL_ENSURE(false, "OOps, SdrObjKind and dynamic_cast do not fit (!)"); - } - break; + bFoundObjNoArea = true; + bFoundNoGraphicObj = true; } - case OBJ_CIRC: + else { - SdrCircObj* pSdrCircObj = dynamic_cast< SdrCircObj* >(pObj); + bFoundAny = true; + break; + } + } + else if(dynamic_cast< SdrOle2Obj* >(pObj)) + { + // OBJ_OLE2 #i118485# #i118525# Allow Line, Area and Graphic (Metafile, Bitmap) + bSingleGraphicSelected = (1 == aSelection.size()); + bFoundBitmap = true; + bFoundMetafile = true; + } + else if(dynamic_cast< SdrGrafObj* >(pObj)) + { + // OBJ_GRAF + bSingleGraphicSelected = (1 == aSelection.size()); - if(pSdrCircObj) + switch(static_cast< const SdrGrafObj* >(pObj)->GetGraphicType()) + { + case GRAPHIC_BITMAP: { - if(CircleType_Arc == pSdrCircObj->GetSdrCircleObjType()) + bFoundBitmap = true; + + if(static_cast< const SdrGrafObj* >(pObj)->isEmbeddedSvg()) { - bFoundObjNoArea = true; - bFoundNoGraphicObj = true; + bFoundMetafile = true; } + break; } - else + case GRAPHIC_GDIMETAFILE: { - OSL_ENSURE(false, "OOps, SdrObjKind and dynamic_cast do not fit (!)"); + bFoundMetafile = true; + break; } - break; - } - case OBJ_EDGE: - bFoundObjNoArea = true; - bFoundNoGraphicObj = true; - break; - case OBJ_OLE2 : - // #i118485# #i118525# Allow Line, Area and Graphic (Metafile, Bitmap) - bSingleGraphicSelected = (1 == aSelection.size()); - bFoundBitmap = true; - bFoundMetafile = true; - break; - case OBJ_GRAF : - { - bSingleGraphicSelected = (1 == aSelection.size()); - const SdrGrafObj* pSdrGrafObj = static_cast< const SdrGrafObj* >(pObj); - switch(pSdrGrafObj->GetGraphicType()) + default: { - case GRAPHIC_BITMAP : - bFoundBitmap = true; - if(pSdrGrafObj->isEmbeddedSvg()) - { - bFoundMetafile = true; - } - break; - case GRAPHIC_GDIMETAFILE : - bFoundMetafile = true; - break; - default: - break; + break; } - - break; } - case OBJ_TABLE: - bFoundTable = true; - break; - default : - bFoundAny = true; + } + else if(dynamic_cast< sdr::table::SdrTableObj* >(pObj)) + { + // OBJ_TABLE + bFoundTable = true; + } + else + { + // everything else (including 3D objects) + bFoundAny = true; } } - else if(nInv == E3dInventor) + else { - // 3D objects - bFoundAny = true; + OSL_ENSURE(false, "SdrObject selection with empty SdrObjects is not allowed (!)"); } } - if( bFoundTable ) - rSet.DisableItem( SID_ATTRIBUTES_LINE ); + if(bFoundTable) + { + rSet.DisableItem(SID_ATTRIBUTES_LINE); + } - if (!bFoundAny) + if(!bFoundAny) { // Disable menuitem for area-dialog - if( bFoundObjNoArea ) // #i25616# - rSet.DisableItem( SID_ATTRIBUTES_AREA ); + if(bFoundObjNoArea) + { + // #i25616# + rSet.DisableItem(SID_ATTRIBUTES_AREA); + } // Disable menuitem for line-dialog - if( bFoundObjNoLine ) - rSet.DisableItem( SID_ATTRIBUTES_LINE ); - - if( bFoundBitmap && !bFoundMetafile && !bFoundNoGraphicObj ) // only Bitmaps marked - rSet.DisableItem( SID_CONVERT_TO_BITMAP ); - else if( !bFoundBitmap && bFoundMetafile && !bFoundNoGraphicObj ) // only Metafiles marked - rSet.DisableItem( SID_CONVERT_TO_METAFILE ); - else if( !bFoundBitmap && !bFoundMetafile && !bFoundNoGraphicObj ) // nothing to do + if(bFoundObjNoLine) + { + rSet.DisableItem(SID_ATTRIBUTES_LINE); + } + + if(bFoundBitmap && !bFoundMetafile && !bFoundNoGraphicObj) + { + // only Bitmaps marked + rSet.DisableItem(SID_CONVERT_TO_BITMAP); + } + else if(!bFoundBitmap && bFoundMetafile && !bFoundNoGraphicObj) + { + // only Metafiles marked + rSet.DisableItem(SID_CONVERT_TO_METAFILE); + } + else if(!bFoundBitmap && !bFoundMetafile && !bFoundNoGraphicObj) { - rSet.DisableItem( SID_CONVERT_TO_BITMAP ); - rSet.DisableItem( SID_CONVERT_TO_METAFILE ); + // nothing to do + rSet.DisableItem(SID_CONVERT_TO_BITMAP); + rSet.DisableItem(SID_CONVERT_TO_METAFILE); } } } diff --git a/svx/inc/svx/svdlegacy.hxx b/svx/inc/svx/svdlegacy.hxx index a8f35bc9b7e6..a2d819e607db 100644 --- a/svx/inc/svx/svdlegacy.hxx +++ b/svx/inc/svx/svdlegacy.hxx @@ -59,9 +59,22 @@ namespace sdr // old access to anchor as point SVX_DLLPUBLIC Point GetAnchorPos(const SdrObject& rObject); + // back and forth converters for Rotation new (angle in rad [0.0 .. F_2PI[) and + // old (mirrored angle in deg * 100 [0 .. 36000[) + // These converters are used for places where the correct new values are used + // for the UI and similar + long convertRotateAngleNewToLegacy(double fNew); + double convertRotateAngleLegacyToNew(long nOld); + + // back and forth converters for ShearX new (shear x in rad [-F_PI .. F_PI[) and + // old (mirrored shear x in deg * 100 [-18000 .. 18000[) + // These converters are used for places where the correct new values are used + // for the UI and similar + long convertShearAngleXNewToLegacy(double fNew); + double convertShearAngleXLegacyToNew(long nOld); + // old access to rotate and shear (including wrong orientation and - // integer nature). bool bVertical removed and method renamed, - // was not supported anyways + // integer nature, see above converters) SVX_DLLPUBLIC long GetRotateAngle(const SdrObject& rObject); SVX_DLLPUBLIC long GetShearAngleX(const SdrObject& rObject); diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx index d6dfc708c1e1..f565d99e398f 100644 --- a/svx/source/svdraw/svdedtv1.cxx +++ b/svx/source/svdraw/svdedtv1.cxx @@ -268,36 +268,22 @@ void SdrEditView::ResizeMarkedObj(const basegfx::B2DPoint& rRefPoint, const base double SdrEditView::GetMarkedObjRotate() const { - if(!areSdrObjectsSelected()) - { - return 0.0; - } - - SdrObject* pSingle = getSelectedIfSingle(); - - if(pSingle) - { - return pSingle->getSdrObjectRotate(); - } - - const SdrObjectVector aSelection(getSelectedSdrObjectVectorFromSdrMarkView()); + SdrObject* pCandidate = getSelectedIfSingle(); - if(aSelection.size()) + if(!pCandidate) { - SdrObject* pObject = aSelection[0]; + // for multiselection use the rotation angle of the 1st object + const SdrObjectVector aSelection(getSelectedSdrObjectVectorFromSdrMarkView()); - if(pObject) + if(aSelection.size()) { - return pObject->getSdrObjectRotate(); - } - else - { - OSL_ENSURE(false, "OOps, areSdrObjectsSelected() == true, but no first object (!)"); + pCandidate = aSelection[0]; } } - else + + if(pCandidate) { - OSL_ENSURE(false, "OOps, areSdrObjectsSelected() == true, but no objects (!)"); + return pCandidate->getSdrObjectRotate(); } return 0.0; @@ -496,36 +482,30 @@ void SdrEditView::MirrorMarkedObjVertical(bool bCopy) double SdrEditView::GetMarkedObjShearX() const { - double fRetval(0.0); + SdrObject* pCandidate = getSelectedIfSingle(); - if(areSdrObjectsSelected()) + if(!pCandidate) { + // for multiselection use the shear value of the 1st object const SdrObjectVector aSelection(getSelectedSdrObjectVectorFromSdrMarkView()); - for(sal_uInt32 a(0); a < aSelection.size(); a++) + if(aSelection.size()) { - SdrObject* pObject = aSelection[a]; - - if(a) - { - const double fNew(pObject->getSdrObjectShearX()); - - if(!basegfx::fTools::equal(fNew, fRetval)) - { - return 0.0; - } - } - else - { - fRetval = pObject->getSdrObjectShearX(); - } + pCandidate = aSelection[0]; } + } - const double fMaxShearRange(F_PI2 * (89.0/90.0)); - fRetval = basegfx::clamp(fRetval, -fMaxShearRange, fMaxShearRange); + if(pCandidate) + { + OSL_ENSURE( + basegfx::fTools::less(atan(pCandidate->getSdrObjectShearX()), F_PI2 * (89.0/90.0)) && + basegfx::fTools::more(atan(pCandidate->getSdrObjectShearX()), -F_PI2 * (89.0/90.0)), + "Shear angle is out of bounds (inside the one degree extrema corresponding to a +/- 90 degree range)"); + + return pCandidate->getSdrObjectShearX(); } - return fRetval; + return 0.0; } void SdrEditView::ShearMarkedObj(const basegfx::B2DPoint& rRefPoint, double fAngle, bool bVShear, bool bCopy) @@ -962,7 +942,7 @@ void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet& rAttr, bool /*bRep if (rAttr.GetItemState(SDRATTR_ROTATEALL,true,&pPoolItem)==SFX_ITEM_SET) { const sal_Int32 nAngle(((const SdrAngleItem*)pPoolItem)->GetValue()); - const double fNewAngle((((36000 - nAngle) % 36000) * F_PI) / 18000.0); + const double fNewAngle(sdr::legacy::convertRotateAngleLegacyToNew(nAngle)); RotateMarkedObj(rAllSnapRange.getCenter(), fNewAngle); } @@ -970,7 +950,7 @@ void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet& rAttr, bool /*bRep if (rAttr.GetItemState(SDRATTR_HORZSHEARALL,true,&pPoolItem)==SFX_ITEM_SET) { const sal_Int32 nAngle(((const SdrAngleItem*)pPoolItem)->GetValue()); - const double fAngle(tan(((36000 - nAngle) * F_PI) / 18000.0)); + const double fAngle(sdr::legacy::convertShearAngleXLegacyToNew(nAngle)); ShearMarkedObj(rAllSnapRange.getCenter(), fAngle, false); } @@ -978,7 +958,7 @@ void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet& rAttr, bool /*bRep if (rAttr.GetItemState(SDRATTR_VERTSHEARALL,true,&pPoolItem)==SFX_ITEM_SET) { const sal_Int32 nAngle(((const SdrAngleItem*)pPoolItem)->GetValue()); - const double fAngle(tan(((36000 - nAngle) * F_PI) / 18000.0)); + const double fAngle(sdr::legacy::convertShearAngleXLegacyToNew(nAngle)); ShearMarkedObj(rAllSnapRange.getCenter(), fAngle, true); } @@ -1706,8 +1686,12 @@ SfxItemSet SdrEditView::GetGeoAttrFromMarked() const fRotateRefY = aRotateAxe.getY(); } + // get rotation of selection. fAllRotation is in radians [0.0 .. F_2PI[ const double fAllRotation(GetMarkedObjRotate()); - const sal_Int32 nOldAllRot((basegfx::fround(((F_2PI - fAllRotation) * 18000.0) / F_PI)) % 36000); + + // convert to old notation used in the UI; it's orientation is mirrored and its + // degrees * 100 in integer + const sal_Int32 nOldAllRot(sdr::legacy::convertRotateAngleNewToLegacy(fAllRotation)); aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ANGLE,nOldAllRot)); aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X,basegfx::fround(fRotateRefX))); @@ -1724,15 +1708,15 @@ SfxItemSet SdrEditView::GetGeoAttrFromMarked() const fShearRefY = aRotateAxe.getY(); } - double fAllShearX(GetMarkedObjShearX()); - const double fMaxShearRange(F_PI2 * (89.0/90.0)); - - fAllShearX = basegfx::snapToRange(fAllShearX, -F_PI, F_PI); - fAllShearX = basegfx::clamp(fAllShearX, -fMaxShearRange, fMaxShearRange); + // get shear of selection. GetMarkedObjShearX is the tan of the shear angle in radians + // tan(]-F_PI2 .. F_PI2[), so apply atan to get the shear angle + const double fAllShearAngleX(atan(GetMarkedObjShearX())); - const sal_Int32 nOldAllShearX(basegfx::fround(((-fAllShearX) * 18000.0) / F_PI)); + // convert to old notation used in the UI; it's orientation is mirrored and its + // degrees * 100 in integer + const sal_Int32 nOldAllShearAngleX(sdr::legacy::convertShearAngleXNewToLegacy(fAllShearAngleX)); - aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR,nOldAllShearX)); + aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR,nOldAllShearAngleX)); aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X,basegfx::fround(fShearRefX))); aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y,basegfx::fround(fShearRefY))); @@ -1936,13 +1920,16 @@ void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr) } // rotation change? - const double fOldRotateAngle(GetMarkedObjRotate()); + const double fOldRotateAngle(GetMarkedObjRotate()); // radians [0.0 .. F_2PI[ double fNewRotateAngle(fOldRotateAngle); if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ANGLE,true,&pPoolItem)) { const sal_Int32 nAllRot(((const SfxInt32Item*)pPoolItem)->GetValue()); - fNewRotateAngle = (((36000 - nAllRot) % 36000) * F_PI) / 18000.0; + + // convert from old UI units (angle in degree * 100, wrong oriented) + // to correctly orinented radians, same coordinate system as fOldRotateAngle + fNewRotateAngle = sdr::legacy::convertRotateAngleLegacyToNew(nAllRot); } const bool bRotate(!basegfx::fTools::equal(fOldRotateAngle, fNewRotateAngle)); @@ -1960,24 +1947,36 @@ void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr) } // shear change? - double fShearAngle(0.0); + double fShearChange(0.0); basegfx::B2DPoint aShearOffset(0.0, 0.0); - bool bShearVert(false); - bool bShear(false); + bool bDoShearY(false); + bool bDoShearDelta(false); if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_SHEAR,true,&pPoolItem)) { + // get UI shear angle ]-9000 .. 9000[ const sal_Int32 nAllShear(((const SfxInt32Item*)pPoolItem)->GetValue()); + + // convert to correctly oriented shear angle in radians ]-F_PI2 .. F_PI2[ + // limit to partial values (corresponding to +-89 degree) + // convert from shear angle to shear value used in the transformation to + // get to the same coordinate system as fOldShearValue below will use const double fMaxShearRange(F_PI2 * (89.0/90.0)); - double fNewShearAngle(((-nAllShear) * F_PI) / 18000.0); + const double fNewShearValue( + tan( + basegfx::clamp( + sdr::legacy::convertShearAngleXLegacyToNew(nAllShear), + -fMaxShearRange, + fMaxShearRange))); - fNewShearAngle = basegfx::snapToRange(fNewShearAngle, -F_PI, F_PI); - fNewShearAngle = basegfx::clamp(fNewShearAngle, -fMaxShearRange, fMaxShearRange); + // check if we have a ShearY + bDoShearY = ((const SfxBoolItem&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_VERTICAL)).GetValue(); - bShearVert = ((const SfxBoolItem&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_VERTICAL)).GetValue(); - double fOldShearAngle(GetMarkedObjShearX()); + // get current shear value. It is the tan of the shear angle in radians + // tan(]-F_PI .. F_PI[) + double fOldShearValue(GetMarkedObjShearX()); - if(bShearVert) + if(bDoShearY) { // Currently only ShearX is directly used at the SdrObject since the homogen // matrix only has six degrees of freedom and it has to be decided which one @@ -1985,16 +1984,18 @@ void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr) // the same as a 90 degree rotation, a ShearY(-x) and a -90 degree back-rotation. // Exactly this will be used below. It also shows that the ShearY is -ShearX, thus // the compare value can be detected - fOldShearAngle = -fOldShearAngle; + fOldShearValue = -fOldShearValue; } - if(!basegfx::fTools::equal(fNewShearAngle, fOldShearAngle)) + if(!basegfx::fTools::equal(fNewShearValue, fOldShearValue)) { - fShearAngle = fNewShearAngle - fOldShearAngle; - bShear = true; + // create shear diff and convert to shear angle, this is what ShearMarkedObj + // expects + fShearChange = atan(fNewShearValue - fOldShearValue); + bDoShearDelta = true; } - if(bShear) + if(bDoShearDelta) { aShearOffset.setX(((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_X)).GetValue()); aShearOffset.setY(((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_Y)).GetValue()); @@ -2062,20 +2063,20 @@ void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr) } // change shear - if(bShear && mbShearAllowed) + if(bDoShearDelta && mbShearAllowed) { basegfx::B2DPoint aRef(aShearOffset + aPageOrigin); - if(bShearVert) + if(bDoShearY) { - // see explanation at setting bShearVert + // see explanation at setting bDoShearY above RotateMarkedObj(aRef, F_PI2); - ShearMarkedObj(aRef, -fShearAngle, true); + ShearMarkedObj(aRef, -fShearChange, true); RotateMarkedObj(aRef, -F_PI2); } else { - ShearMarkedObj(aRef, fShearAngle, false); + ShearMarkedObj(aRef, fShearChange, false); } } diff --git a/svx/source/svdraw/svdlegacy.cxx b/svx/source/svdraw/svdlegacy.cxx index e5f0a2872fbe..e7c3b43778ce 100644 --- a/svx/source/svdraw/svdlegacy.cxx +++ b/svx/source/svdraw/svdlegacy.cxx @@ -285,14 +285,21 @@ namespace sdr return Point(basegfx::fround(rAnchor.getX()), basegfx::fround(rAnchor.getY())); } + long convertRotateAngleNewToLegacy(double fNew) + { + return basegfx::fround(basegfx::snapToZeroRange(-fNew / F_PI18000, 36000.0)); + } + + double convertRotateAngleLegacyToNew(long nOld) + { + return basegfx::snapToZeroRange(static_cast< double >(nOld) * -F_PI18000, F_2PI); + } + long GetRotateAngle(const SdrObject& rObject) { if(rObject.isRotated()) { - const double fRotate(rObject.getSdrObjectRotate()); - const double fSnapped(basegfx::snapToZeroRange(-fRotate / F_PI18000, 36000.0)); - - return basegfx::fround(fSnapped); + return convertRotateAngleNewToLegacy(rObject.getSdrObjectRotate()); } else { @@ -300,24 +307,21 @@ namespace sdr } } + long convertShearAngleXNewToLegacy(double fNew) + { + return basegfx::fround(basegfx::snapToRange(-fNew / F_PI18000, -18000.0, 18000.0)); + } + + double convertShearAngleXLegacyToNew(long nOld) + { + return basegfx::snapToRange(static_cast< double >(nOld) * -F_PI18000, -F_PI, F_PI); + } + long GetShearAngleX(const SdrObject& rObject) { if(rObject.isSheared()) { - const double fShearX(rObject.getSdrObjectShearX()); - long nRetval(basegfx::fround(-atan(fShearX) / F_PI18000)); - - while(nRetval < -18000) - { - nRetval += 36000; - } - - while(nRetval >= 18000) - { - nRetval -= 36000; - } - - return nRetval; + return convertShearAngleXNewToLegacy(rObject.getSdrObjectShearX()); } else { diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx index b26efb8f0fba..c4b01d604e57 100644 --- a/svx/source/svdraw/svdmrkv.cxx +++ b/svx/source/svdraw/svdmrkv.cxx @@ -530,9 +530,40 @@ void SdrMarkView::BrkMarkGluePoints() bool SdrMarkView::HasMarkableObj() const { - const sal_uInt32 nCount(GetMarkableObjCount()); + SdrPageView* pPV = GetSdrPageView(); + + if(pPV) + { + SdrObjList* pOL = pPV->GetCurrentObjectList(); + + if(pOL) + { + SdrObjectVector aObjects(pOL->getSdrObjectVector()); + + for(sal_uInt32 a(0); a < aObjects.size(); a++) + { + SdrObject* pCandidate = aObjects[a]; - return (0 != nCount); + if(pCandidate) + { + if(IsObjMarkable(*pCandidate)) + { + return true; + } + } + else + { + OSL_ENSURE(false, "SdrObjectVector with empty entries (!)"); + } + } + } + else + { + OSL_ENSURE(false, "Unexpected missing SdrObjList (!)"); + } + } + + return false; } sal_uInt32 SdrMarkView::GetMarkableObjCount() const @@ -543,17 +574,32 @@ sal_uInt32 SdrMarkView::GetMarkableObjCount() const if(pPV) { SdrObjList* pOL = pPV->GetCurrentObjectList(); - sal_uInt32 nObjAnz = pOL->GetObjCount(); - for(sal_uInt32 nObjNum(0); nObjNum < nObjAnz && !nCount; nObjNum++) + if(pOL) { - SdrObject* pObj=pOL->GetObj(nObjNum); + SdrObjectVector aObjects(pOL->getSdrObjectVector()); - if(IsObjMarkable(*pObj)) + for(sal_uInt32 a(0); a < aObjects.size(); a++) { - nCount++; + SdrObject* pCandidate = aObjects[a]; + + if(pCandidate) + { + if(IsObjMarkable(*pCandidate)) + { + nCount++; + } + } + else + { + OSL_ENSURE(false, "SdrObjectVector with empty entries (!)"); + } } } + else + { + OSL_ENSURE(false, "Unexpected missing SdrObjList (!)"); + } } return nCount; diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx index f7619f1a37b4..62c9988fc832 100644 --- a/svx/source/svdraw/svdograf.cxx +++ b/svx/source/svdraw/svdograf.cxx @@ -792,7 +792,7 @@ void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const rInfo.mbShearAllowed = true; rInfo.mbEdgeRadiusAllowed=false; - rInfo.mbCanConvToPath = false; + rInfo.mbCanConvToPath = !IsEPS(); rInfo.mbCanConvToPathLineToArea = false; rInfo.mbCanConvToPolyLineToArea = false; rInfo.mbCanConvToPoly = !IsEPS(); diff --git a/svx/source/svdraw/svdopath.cxx b/svx/source/svdraw/svdopath.cxx index 0ec10ead82c3..845c43572442 100644 --- a/svx/source/svdraw/svdopath.cxx +++ b/svx/source/svdraw/svdopath.cxx @@ -1637,7 +1637,7 @@ void SdrPathObj::impSetPathPolyPolygonWithTransformationAdaption(const basegfx:: // the SdrPathObj has two basic states, line and other. Line is for two points // and no bezier, it uses a specialized geometry (unified line from 0.0, to 1.0) // and a specialized transformation which shows the rotation of the line what is - // wanted. + // wanted. Shear is not preserved due to lines having no shear. // When a third point is added that mode is left and the regular one entered, in // this conversion when using the code below keeping the rotation of the former // line object. This is not wrong and works as intended, but is irritating for the @@ -1750,6 +1750,9 @@ void SdrPathObj::impSetPathPolyPolygonWithTransformationAdaption(const basegfx:: else { // use translate and scale straightforward from new geometry + // when either no mirror, scale and shear or object was a line + // before and reset is wanted (see explanation for + // bResetCoordinateSystemAfterWasLine above) maSdrObjectTransformation.setB2DHomMatrix( basegfx::tools::createScaleTranslateB2DHomMatrix( aRangeNewGeometry.getRange(), @@ -2726,11 +2729,26 @@ void SdrPathObj::setSdrObjectTransformation(const basegfx::B2DHomMatrix& rTransf if(isLine()) { // apply new transformation to (0,0) and (1,0) to create the polygon data + // and set as new geometry + const basegfx::B2DPoint aPointA(rTransformation * basegfx::B2DPoint(0.0, 0.0)); + const basegfx::B2DPoint aPointB(rTransformation * basegfx::B2DPoint(1.0, 0.0)); basegfx::B2DPolygon aLine; - aLine.append(rTransformation * basegfx::B2DPoint(0.0, 0.0)); - aLine.append(rTransformation * basegfx::B2DPoint(1.0, 0.0)); + aLine.append(aPointA); + aLine.append(aPointB); maPathPolyPolygon = basegfx::B2DPolyPolygon(aLine); + + // the geometry is a non-curved line, create unit transformation so that (0,0) is + // 1st point and (1,0) is 2nd point and call the parent method with the new + // transformation. This is needed to trigger all the refresh stuff + const basegfx::B2DVector aDelta(aPointB - aPointA); + + // call parent with new, adapted transformation + SdrTextObj::setSdrObjectTransformation( + basegfx::tools::createScaleRotateTranslateB2DHomMatrix( + basegfx::B2DTuple(aDelta.getLength(), 1.0), + atan2(aDelta.getY(), aDelta.getX()), + aPointA)); } else { @@ -2740,14 +2758,18 @@ void SdrPathObj::setSdrObjectTransformation(const basegfx::B2DHomMatrix& rTransf // take out old and apply new transformation basegfx::B2DHomMatrix aCombined(maSdrObjectTransformation.getB2DHomMatrix()); + // apply minimal scaling before inverting to secure inversion and + // to handle cases where polygons have no width and/or height, but are not a line + aCombined = basegfx::tools::guaranteeMinimalScaling(aCombined); + aCombined.invert(); aCombined = rTransformation * aCombined; maPathPolyPolygon.transform(aCombined); } - } - // call parent - SdrTextObj::setSdrObjectTransformation(rTransformation); + // call parent + SdrTextObj::setSdrObjectTransformation(rTransformation); + } } } diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx index 05d4f7897a81..bdd0acd32019 100644 --- a/xmloff/source/draw/ximpshap.cxx +++ b/xmloff/source/draw/ximpshap.cxx @@ -1390,6 +1390,8 @@ SdXMLPolygonShapeContext::~SdXMLPolygonShapeContext() void SdXMLPolygonShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList) { // Add, set Style and properties from base shape + // The type is no longer relevant for having a closed or open shape; instead use an opened or + // closed polygon (see below) if(mbClosed) AddShape("com.sun.star.drawing.PolyPolygonShape"); else @@ -1423,6 +1425,13 @@ void SdXMLPolygonShapeContext::StartElement(const uno::Reference< xml::sax::XAtt { if(aPolygon.count()) { + // dependent from the ObjectType in the ODF file set the closed state + // of the Polygon. That state is not part of the draw:points definition + // which was imported in importFromSvgPoints, but depends on the object type + // imported (e.g. draw:polyline or draw:polygon) which is reflected in the + // member variable mbClosed + aPolygon.setClosed(mbClosed); + const basegfx::B2DRange aSourceRange( aViewBox.GetX(), aViewBox.GetY(), aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight()); |