summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2014-04-10 14:08:57 +0000
committerArmin Le Grand <alg@apache.org>2014-04-10 14:08:57 +0000
commit4cff340fbe1f20a3a05cc5e541cfcbd735287e2d (patch)
treef2e7e1aed630425d1ab7960588e28843084c0be0
parent6ca3a9faca825e0e3c44de9f47f4c684d31f86b1 (diff)
in-between results/corrections/improvemnts
-rw-r--r--drawinglayer/source/processor2d/vclhelperbitmaprender.cxx283
-rw-r--r--sd/source/ui/func/fudraw.cxx2
-rw-r--r--sd/source/ui/view/drviews7.cxx177
-rw-r--r--svx/inc/svx/svdlegacy.hxx17
-rw-r--r--svx/source/svdraw/svdedtv1.cxx153
-rw-r--r--svx/source/svdraw/svdlegacy.cxx40
-rw-r--r--svx/source/svdraw/svdmrkv.cxx60
-rw-r--r--svx/source/svdraw/svdograf.cxx2
-rw-r--r--svx/source/svdraw/svdopath.cxx34
-rw-r--r--xmloff/source/draw/ximpshap.cxx9
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());