tdf#149840 Use actual outer size for SmartArt in Writer
SmartArt import needs the outer size of the diagram for to define a background shape in the correct size and calculate the size of the diagram shapes relative to the outer size. The patch passes the values read from wp:extent in writerfilter to DiagramGraphicDataContext in oox. Change-Id: Ib39227bc645ac353336bab2c558d041974188f6f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141223 Tested-by: Jenkins Reviewed-by: Regina Henschel <rb.henschel@t-online.de> Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
This commit is contained in:
parent
9e0dcfbaf0
commit
e4515c1305
7 changed files with 158 additions and 1 deletions
|
@ -95,6 +95,7 @@ public:
|
|||
void pushStartToken( sal_Int32 _starttoken );
|
||||
|
||||
void setPosition(const css::awt::Point& rPosition);
|
||||
void setSize(const css::awt::Size& rSize);
|
||||
|
||||
const bool& getFullWPGSupport() { return m_bFullWPGSUpport; }
|
||||
void setFullWPGSupport(bool bUse) { m_bFullWPGSUpport = bUse; }
|
||||
|
@ -118,6 +119,7 @@ private:
|
|||
std::stack<sal_uInt32> mnStartTokenStack;
|
||||
|
||||
css::awt::Point maPosition;
|
||||
css::awt::Size maSize; // from cx and cy, in EMU
|
||||
bool m_bFullWPGSUpport; // Is this DrawingML shape supposed to be processed as WPG?
|
||||
|
||||
drawingml::ShapePtr mpShape;
|
||||
|
|
|
@ -215,6 +215,7 @@ ShapeContextHandler::getDiagramShapeContext()
|
|||
{
|
||||
auto pFragmentHandler = std::make_shared<ShapeFragmentHandler>(*mxShapeFilterBase, msRelationFragmentPath);
|
||||
mpShape = std::make_shared<Shape>();
|
||||
mpShape->setSize(maSize);
|
||||
mxDiagramShapeContext.set(new DiagramGraphicDataContext(*pFragmentHandler, mpShape));
|
||||
}
|
||||
|
||||
|
@ -564,6 +565,11 @@ void ShapeContextHandler::setPosition(const awt::Point& rPosition)
|
|||
maPosition = rPosition;
|
||||
}
|
||||
|
||||
void ShapeContextHandler::setSize(const awt::Size& rSize)
|
||||
{
|
||||
maSize = rSize;
|
||||
}
|
||||
|
||||
void ShapeContextHandler::setDocumentProperties(const uno::Reference<document::XDocumentProperties>& xDocProps)
|
||||
{
|
||||
mxDocumentProperties = xDocProps;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <com/sun/star/drawing/PointSequenceSequence.hpp>
|
||||
|
||||
#include <basegfx/polygon/b2dpolypolygontools.hxx>
|
||||
#include <officecfg/Office/Common.hxx>
|
||||
|
||||
using namespace ::com::sun::star;
|
||||
|
||||
|
@ -406,6 +407,57 @@ CPPUNIT_TEST_FIXTURE(Test, testLayoutInCellOfHraphics)
|
|||
CPPUNIT_ASSERT(xShape->getPropertyValue("IsFollowingTextFlow") >>= bFollowingTextFlow);
|
||||
CPPUNIT_ASSERT(bFollowingTextFlow);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testTdf149840SmartArtBackground)
|
||||
{
|
||||
// Make sure SmartArt is loaded as group shape
|
||||
bool bUseGroup = officecfg::Office::Common::Filter::Microsoft::Import::SmartArtToShapes::get();
|
||||
if (!bUseGroup)
|
||||
{
|
||||
std::shared_ptr<comphelper::ConfigurationChanges> pChange(
|
||||
comphelper::ConfigurationChanges::create());
|
||||
officecfg::Office::Common::Filter::Microsoft::Import::SmartArtToShapes::set(true, pChange);
|
||||
pChange->commit();
|
||||
}
|
||||
|
||||
OUString aURL
|
||||
= m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf149840_SmartArtBackground.docx";
|
||||
getComponent() = loadFromDesktop(aURL);
|
||||
uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
|
||||
uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
|
||||
uno::Reference<container::XIndexAccess> xGroup(xDrawPage->getByIndex(0), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xGroup->getCount());
|
||||
|
||||
// The first shape in the group, which represents the SmartArt, corresponds to the background of
|
||||
// the diagram. Without fix in place it has widht and height zero, which does not only result in
|
||||
// not visible background but in wrong sizes of the diagram shapes too.
|
||||
uno::Reference<drawing::XShape> xBackgroundShape(xGroup->getByIndex(0), uno::UNO_QUERY);
|
||||
awt::Size aBackgroundSize = xBackgroundShape->getSize();
|
||||
// Toleranzes are for rounding inaccuracies.
|
||||
// The test would have failed with Expected: 9560x5036, Actual: 2x2
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(9560), aBackgroundSize.Width, 1);
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(5036), aBackgroundSize.Height, 1);
|
||||
|
||||
uno::Reference<drawing::XShape> xShapeOne(xGroup->getByIndex(1), uno::UNO_QUERY);
|
||||
awt::Size aShapeOneSize = xShapeOne->getSize();
|
||||
// The test would have failed with Expected: 3282x3709, Actual: 3972x3709
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(3282), aShapeOneSize.Width, 1);
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(3709), aShapeOneSize.Height, 1);
|
||||
|
||||
uno::Reference<drawing::XShape> xShapeTwo(xGroup->getByIndex(2), uno::UNO_QUERY);
|
||||
awt::Size aShapeTwoSize = xShapeTwo->getSize();
|
||||
// The test would have failed with Expected: 2404x5226, Actual: 2910x5226
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(2404), aShapeTwoSize.Width, 1);
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<sal_Int32>(5226), aShapeTwoSize.Height, 1);
|
||||
|
||||
if (!bUseGroup)
|
||||
{
|
||||
std::shared_ptr<comphelper::ConfigurationChanges> pChange(
|
||||
comphelper::ConfigurationChanges::create());
|
||||
officecfg::Office::Common::Filter::Microsoft::Import::SmartArtToShapes::set(false, pChange);
|
||||
pChange->commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
Binary file not shown.
|
@ -324,6 +324,53 @@ sal_Int32 GraphicZOrderHelper::findZOrder( sal_Int32 relativeHeight, bool bOldSt
|
|||
return 0; // this should not(?) happen
|
||||
}
|
||||
|
||||
ExtentHandler::ExtentHandler()
|
||||
{
|
||||
}
|
||||
|
||||
ExtentHandler::~ExtentHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void ExtentHandler::attribute(Id nName, Value & rValue)
|
||||
{
|
||||
sal_Int32 nIntValue = rValue.getInt();
|
||||
switch (nName)
|
||||
{
|
||||
case NS_ooxml::LN_CT_PositiveSize2D_cx:
|
||||
{
|
||||
m_Extent.Width = nIntValue;
|
||||
}
|
||||
break;
|
||||
case NS_ooxml::LN_CT_PositiveSize2D_cy:
|
||||
{
|
||||
m_Extent.Height = nIntValue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ExtentHandler::sprm(Sprm & rSprm)
|
||||
{
|
||||
sal_uInt32 nSprmId = rSprm.getId();
|
||||
switch(nSprmId)
|
||||
{
|
||||
case NS_ooxml::LN_CT_Inline_extent:
|
||||
case NS_ooxml::LN_CT_Anchor_extent:
|
||||
{
|
||||
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
|
||||
if( pProperties )
|
||||
{
|
||||
pProperties->resolve(*this);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -63,6 +63,20 @@ private:
|
|||
sal_Int32 m_nType;
|
||||
sal_Int32 m_nSide;
|
||||
};
|
||||
|
||||
class ExtentHandler : public Properties
|
||||
{
|
||||
css::awt::Size m_Extent; // width and height in EMU
|
||||
|
||||
public:
|
||||
typedef ::tools::SvRef<ExtentHandler> Pointer_t;
|
||||
explicit ExtentHandler();
|
||||
virtual ~ExtentHandler() override;
|
||||
|
||||
virtual void attribute(Id nName, Value& rValue) override;
|
||||
virtual void sprm(Sprm& rSprm) override;
|
||||
css::awt::Size getExtent() const { return m_Extent; }
|
||||
};
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#include <dmapper/PropertyIds.hxx>
|
||||
#include <comphelper/propertysequence.hxx>
|
||||
#include <comphelper/sequenceashashmap.hxx>
|
||||
#include "OOXMLPropertySet.hxx"
|
||||
#include <dmapper/GraphicHelpers.hxx>
|
||||
|
||||
const sal_Unicode uCR = 0xd;
|
||||
const sal_Unicode uFtnEdnRef = 0x2;
|
||||
|
@ -231,7 +233,6 @@ void OOXMLFastContextHandler::lcl_startFastElement
|
|||
inPositionV = true;
|
||||
else if( Element == (NMSP_dmlWordDr|XML_positionH) )
|
||||
inPositionV = false;
|
||||
|
||||
}
|
||||
|
||||
void OOXMLFastContextHandler::lcl_endFastElement
|
||||
|
@ -1684,6 +1685,41 @@ void OOXMLFastContextHandlerShape::lcl_startFastElement
|
|||
|
||||
if (mrShapeContext.is())
|
||||
{
|
||||
if (Element == DGM_TOKEN(relIds))
|
||||
{
|
||||
// It is a SmartArt. Make size available for generated group.
|
||||
// Search for PropertySet in parents
|
||||
OOXMLFastContextHandler* pHandler = getParent();
|
||||
while (pHandler && pHandler->getId() != NS_ooxml::LN_anchor_anchor
|
||||
&& pHandler->getId() != NS_ooxml::LN_inline_inline)
|
||||
{
|
||||
pHandler = pHandler->getParent();
|
||||
}
|
||||
// Search for extent
|
||||
if (pHandler)
|
||||
{
|
||||
if (const OOXMLPropertySet::Pointer_t pPropSet = pHandler->getPropertySet())
|
||||
{
|
||||
auto aIt = pPropSet->begin();
|
||||
auto aItEnd = pPropSet->end();
|
||||
while (aIt != aItEnd && (*aIt)->getId() != NS_ooxml::LN_CT_Inline_extent
|
||||
&& (*aIt)->getId() != NS_ooxml::LN_CT_Anchor_extent)
|
||||
{
|
||||
++aIt;
|
||||
}
|
||||
if (aIt != aItEnd)
|
||||
{
|
||||
writerfilter::Reference<Properties>::Pointer_t pProperties = (*aIt)->getProps();
|
||||
if (pProperties)
|
||||
{
|
||||
writerfilter::dmapper::ExtentHandler::Pointer_t pExtentHandler(new writerfilter::dmapper::ExtentHandler());
|
||||
pProperties->resolve(*pExtentHandler);
|
||||
mrShapeContext->setSize(pExtentHandler->getExtent());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mrShapeContext->startFastElement(Element, Attribs);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue