summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndras Timar <andras.timar@collabora.com>2015-02-05 22:36:24 +0100
committerAndras Timar <andras.timar@collabora.com>2015-02-06 15:06:02 +0100
commit8cba3c12cb900925dc0aa9b10ef2d3e2a16e9f49 (patch)
treeb5e0a323237cfeffee282a7ec3ff641514c8b4d4
parent9c1d2558a9ebe0ffd35f633be7c74fc9dc22c96e (diff)
bnc#637947 improve DrawingML export of custom shapes
Reviewed-on: https://gerrit.libreoffice.org/14346 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Miklos Vajna <vmiklos@collabora.co.uk> (cherry picked from commit b1751e6ed0fd6d6d26141e4405df92520e3c04cd) Conflicts: sw/qa/extras/ooxmlexport/ooxmlexport4.cxx Change-Id: Iaa880528cf3c899ce66e4349c6d989dfbe5cbeb6
-rw-r--r--filter/source/msfilter/util.cxx1
-rw-r--r--oox/source/export/shapes.cxx113
-rw-r--r--sw/qa/extras/ooxmlexport/data/dml-customgeometry-cubicbezier.docxbin17348 -> 8702 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport.cxx5
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx42
5 files changed, 139 insertions, 22 deletions
diff --git a/filter/source/msfilter/util.cxx b/filter/source/msfilter/util.cxx
index 5aad6fe4f0d5..c98e601e21cc 100644
--- a/filter/source/msfilter/util.cxx
+++ b/filter/source/msfilter/util.cxx
@@ -697,6 +697,7 @@ struct CustomShapeTypeTranslationTable
static const CustomShapeTypeTranslationTable pCustomShapeTypeTranslationTable[] =
{
// { "non-primitive", mso_sptMin },
+ { "frame", "frame" },
{ "rectangle", "rect" },
{ "round-rectangle", "roundRect" },
{ "ellipse", "ellipse" },
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 0b5a8ef35890..5b2f4eec1914 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -289,12 +289,87 @@ ShapeExport& ShapeExport::WriteGroupShape(uno::Reference<drawing::XShape> xShape
return *this;
}
+static bool lcl_IsOnBlacklist(OUString& rShapeType)
+{
+ OUString aBlacklist[] = {
+ "ring",
+ "can",
+ "cube",
+ "paper",
+ "frame",
+ "smiley",
+ "sun",
+ "flower",
+ "forbidden",
+ "bracket-pair",
+ "brace-pair",
+ "col-60da8460",
+ "col-502ad400",
+ "quad-bevel",
+ "cloud-callout",
+ "line-callout-1",
+ "line-callout-2",
+ "line-callout-3",
+ "paper",
+ "vertical-scroll",
+ "horizontal-scroll",
+ "mso-spt34",
+ "mso-spt75",
+ "mso-spt164",
+ "mso-spt180",
+ "flowchart-process",
+ "flowchart-alternate-process",
+ "flowchart-decision",
+ "flowchart-data",
+ "flowchart-predefined-process",
+ "flowchart-internal-storage",
+ "flowchart-document",
+ "flowchart-multidocument",
+ "flowchart-terminator",
+ "flowchart-preparation",
+ "flowchart-manual-input",
+ "flowchart-manual-operation",
+ "flowchart-connector",
+ "flowchart-off-page-connector",
+ "flowchart-card",
+ "flowchart-punched-tape",
+ "flowchart-summing-junction",
+ "flowchart-or",
+ "flowchart-collate",
+ "flowchart-sort",
+ "flowchart-extract",
+ "flowchart-merge",
+ "flowchart-stored-data",
+ "flowchart-delay",
+ "flowchart-sequential-access",
+ "flowchart-magnetic-disk",
+ "flowchart-direct-access-storage",
+ "flowchart-display"
+ };
+ std::vector<OUString> vBlacklist(aBlacklist, aBlacklist + SAL_N_ELEMENTS(aBlacklist));
+
+ return std::find(vBlacklist.begin(), vBlacklist.end(), rShapeType) != vBlacklist.end();
+}
+
+static bool lcl_IsOnWhitelist(OUString& rShapeType)
+{
+ OUString aWhitelist[] = {
+ "heart",
+ "puzzle"
+ };
+ std::vector<OUString> vWhitelist(aWhitelist, aWhitelist + SAL_N_ELEMENTS(aWhitelist));
+
+ return std::find(vWhitelist.begin(), vWhitelist.end(), rShapeType) != vWhitelist.end();
+}
+
+
ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
{
DBG(fprintf(stderr, "write custom shape\n"));
Reference< XPropertySet > rXPropSet( xShape, UNO_QUERY );
bool bPredefinedHandlesUsed = true;
+ bool bHasHandles = false;
OUString sShapeType;
sal_uInt32 nMirrorFlags = 0;
MSO_SPT eShapeType = EscherPropertyContainer::GetCustomShapeType( xShape, nMirrorFlags, sShapeType );
@@ -325,6 +400,7 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
if ( rProp.Name == "AdjustmentValues" )
nAdjustmentValuesIndex = i;
else if ( rProp.Name == "Handles" ) {
+ bHasHandles = true;
if( !bIsDefaultObject )
bPredefinedHandlesUsed = false;
// TODO: update nAdjustmentsWhichNeedsToBeConverted here
@@ -353,11 +429,40 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
// visual shape properties
pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
- WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, false);
-
- if( sShapeType == "ooxml-non-primitive" ) // non-primitiv -> custom geometry
+ // moon is flipped in MSO, and mso-spt89 (right up arrow) is mapped to leftUpArrow
+ if ( sShapeType == "moon" || sShapeType == "mso-spt89" )
+ WriteShapeTransformation( xShape, XML_a, !bFlipH, bFlipV, false);
+ else
+ WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, false);
+
+ // we export non-primitive shapes to custom geometry
+ // we also export non-ooxml shapes which have handles/equations to custom geometry, because
+ // we cannot convert ODF equations to DrawingML equations. TODO: see what binary DOC export filter does.
+ // but our WritePolyPolygon() function is incomplete, therefore we use a blacklist
+ // we use a whitelist for shapes where mapping to MSO preset shape is not optimal
+ bool bCustGeom = true;
+ if( sShapeType == "ooxml-non-primitive" )
+ bCustGeom = true;
+ else if( sShapeType.startsWith("ooxml") )
+ bCustGeom = false;
+ else if( lcl_IsOnWhitelist(sShapeType) )
+ bCustGeom = true;
+ else if( lcl_IsOnBlacklist(sShapeType) )
+ bCustGeom = false;
+ else if( bHasHandles )
+ bCustGeom = true;
+
+ if( bCustGeom )
{
- WritePolyPolygon( EscherPropertyContainer::GetPolyPolygon( xShape ) );
+ basegfx::B2DPolyPolygon aB2DPolyPolygon = SdrObjCustomShape::GetLineGeometry(pShape, true);
+ PolyPolygon aPolyPolygon;
+ for( sal_uInt32 i = 0; i < aB2DPolyPolygon.count(); ++i )
+ {
+ basegfx::B2DPolygon aB2DPolygon = aB2DPolyPolygon.getB2DPolygon(i);
+ aPolyPolygon.Insert( Polygon( aB2DPolygon ), POLYPOLY_APPEND );
+ }
+
+ WritePolyPolygon( aPolyPolygon );
}
else // preset geometry
{
diff --git a/sw/qa/extras/ooxmlexport/data/dml-customgeometry-cubicbezier.docx b/sw/qa/extras/ooxmlexport/data/dml-customgeometry-cubicbezier.docx
index baa47f43c102..9cc84a9271c0 100644
--- a/sw/qa/extras/ooxmlexport/data/dml-customgeometry-cubicbezier.docx
+++ b/sw/qa/extras/ooxmlexport/data/dml-customgeometry-cubicbezier.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index a443d586dd8c..a102018cafa2 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -3040,6 +3040,10 @@ DECLARE_OOXMLEXPORT_TEST(testCitation,"FDO74775.docx")
CPPUNIT_ASSERT(contents.match(" CITATION [Kra06]"));
}
+#if 0
+// Currently LibreOffice exports custom geometry for this up arrow, not preset shape.
+// When LibreOffice can export preset shape with correct modifiers, then this test can be re-enabled.
+
DECLARE_OOXMLEXPORT_TEST(testFdo76016, "fdo76016.docx")
{
// check XML
@@ -3049,6 +3053,7 @@ DECLARE_OOXMLEXPORT_TEST(testFdo76016, "fdo76016.docx")
assertXPath(pXmlDoc, "//a:graphic/a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[1]", "name", "adj1");
assertXPath(pXmlDoc, "//a:graphic/a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[2]", "name", "adj2");
}
+#endif
DECLARE_OOXMLEXPORT_TEST(testLockedCanvas, "fdo78658.docx")
{
diff --git a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
index 700506d2827d..f9d96e4b842f 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
@@ -173,28 +173,28 @@ DECLARE_OOXMLEXPORT_TEST(testDMLCustomGeometry, "dml-customgeometry-cubicbezier.
CPPUNIT_ASSERT_EQUAL(nLength, aPairs.getLength());
std::pair<sal_Int32,sal_Int32> aCoordinates[] =
{
- std::pair<sal_Int32,sal_Int32>(607, 0),
- std::pair<sal_Int32,sal_Int32>(450, 44),
- std::pair<sal_Int32,sal_Int32>(300, 57),
- std::pair<sal_Int32,sal_Int32>(176, 57),
- std::pair<sal_Int32,sal_Int32>(109, 57),
- std::pair<sal_Int32,sal_Int32>(49, 53),
- std::pair<sal_Int32,sal_Int32>(0, 48),
- std::pair<sal_Int32,sal_Int32>(66, 58),
- std::pair<sal_Int32,sal_Int32>(152, 66),
- std::pair<sal_Int32,sal_Int32>(251, 66),
- std::pair<sal_Int32,sal_Int32>(358, 66),
- std::pair<sal_Int32,sal_Int32>(480, 56),
- std::pair<sal_Int32,sal_Int32>(607, 27),
- std::pair<sal_Int32,sal_Int32>(607, 0),
- std::pair<sal_Int32,sal_Int32>(607, 0),
- std::pair<sal_Int32,sal_Int32>(607, 0)
+ std::pair<sal_Int32,sal_Int32>(9084, 0),
+ std::pair<sal_Int32,sal_Int32>(6734, 689),
+ std::pair<sal_Int32,sal_Int32>(4489, 893),
+ std::pair<sal_Int32,sal_Int32>(2633, 893),
+ std::pair<sal_Int32,sal_Int32>(1631, 893),
+ std::pair<sal_Int32,sal_Int32>(733, 830),
+ std::pair<sal_Int32,sal_Int32>(0, 752),
+ std::pair<sal_Int32,sal_Int32>(987, 908),
+ std::pair<sal_Int32,sal_Int32>(2274, 1034),
+ std::pair<sal_Int32,sal_Int32>(3756, 1034),
+ std::pair<sal_Int32,sal_Int32>(5357, 1034),
+ std::pair<sal_Int32,sal_Int32>(7183, 877),
+ std::pair<sal_Int32,sal_Int32>(9084, 423),
+ std::pair<sal_Int32,sal_Int32>(9084, 0),
+ std::pair<sal_Int32,sal_Int32>(9084, 0),
+ std::pair<sal_Int32,sal_Int32>(9084, 0)
};
for( int i = 0; i < nLength; ++i )
{
- CPPUNIT_ASSERT_EQUAL(aCoordinates[i].first, aPairs[i].First.Value.get<sal_Int32>());
- CPPUNIT_ASSERT_EQUAL(aCoordinates[i].second, aPairs[i].Second.Value.get<sal_Int32>());
+ CPPUNIT_ASSERT(abs(aCoordinates[i].first - aPairs[i].First.Value.get<sal_Int32>()) < 20);
+ CPPUNIT_ASSERT(abs(aCoordinates[i].second - aPairs[i].Second.Value.get<sal_Int32>()) < 20);
}
}
@@ -1454,6 +1454,10 @@ DECLARE_OOXMLEXPORT_TEST(testNestedAlternateContent, "nestedAlternateContent.doc
assertXPath(pXmlDoc,"/w:document[1]/w:body[1]/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wpg:wgp[1]/wps:wsp[2]/wps:txbx[1]/w:txbxContent[1]/w:p[1]/w:r[2]/mc:AlternateContent[1]",0);
}
+#if 0
+// Currently LibreOffice exports custom geometry for this hexagon, not preset shape.
+// When LibreOffice can export preset shapes with correct modifiers, then this test can be re-enabled.
+
DECLARE_OOXMLEXPORT_TEST(test76317, "test76317.docx")
{
xmlDocPtr pXmlDoc = parseExport("word/document.xml");
@@ -1461,6 +1465,8 @@ DECLARE_OOXMLEXPORT_TEST(test76317, "test76317.docx")
assertXPath(pXmlDoc, "/w:document[1]/w:body[1]/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:prstGeom[1]", "prst", "hexagon");
}
+#endif
+
DECLARE_OOXMLEXPORT_TEST(fdo76591, "fdo76591.docx")
{
xmlDocPtr pXmlDoc = parseExport("word/document.xml");