diff options
author | Regina Henschel <rb.henschel@t-online.de> | 2023-01-18 20:19:51 +0100 |
---|---|---|
committer | Regina Henschel <rb.henschel@t-online.de> | 2023-01-22 10:39:27 +0000 |
commit | 7eac3e78abcdece849b8bac61545b0d3ddf5800c (patch) | |
tree | 1f8338714b48f9eaa35b4141b4a3f24054e4b989 /sw | |
parent | a00556ada3214d7584bebd4d6ac33bf5c25a3467 (diff) |
tdf#128568 Improve export to docx of Fontwork with bitmap fill
The modern 'abc transform' in Word is not able to use bitmap fill, but
it is possible in legacy VML. Thus use VML in such cases.
A WordArt shape in VML has the text not in a <txbxContent> element but
as string='...' attribute in the <v:textpath> element. To detect
whether a custom shape is a Fontwork in an easy way without cast, I
have added the already for custom shapes existing method IsTextPath()
to the basis class SdrObject.
Using VML for Fontwork with bitmap fill, errors in the VML code become
visible:
* Using <v:imagedata> element results in Word in a picture of the shape.
The shape itself was lost. A bitmap fill of a shape has to be written
with the <v:fill> element.
* Mode 'stretched' in LO UI becomes type='frame' attribute in VML.
I have adapted the unit test NoFillAttrInImagedata in ooxmlexport2.cxx
in sw. The source file has the background image in a v:fill element.
If you replace the 'wps' namespace with a 'my' namespace in the file
generated by LO and so force Word to use the Fallback, you will see
that with v:imagedata Word does not show a background image. Thus the
assumption in the test was wrong, that there has to be a v:imagedata
element.
Change-Id: I6b2b5b8bb19adcee3b41e536419556465e85d135
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145823
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport2.cxx | 8 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxsdrexport.cxx | 21 |
2 files changed, 21 insertions, 8 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx index 5b47a78aa7e6..1dd6123588ac 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx @@ -1176,11 +1176,13 @@ DECLARE_OOXMLEXPORT_TEST(testTransparentShadow, "transparent-shadow.docx") CPPUNIT_TEST_FIXTURE(Test, NoFillAttrInImagedata) { loadAndSave("NoFillAttrInImagedata.docx"); - //problem was that type and color2 which are v:fill attributes were written in 'v:imagedata' + //problem was that type and color2 which are v:fill attributes were written in 'v:imagedata'. The + //source file has v:fill and no v:imagedata. Same should be in the file written by LO. xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); - assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Fallback/w:pict/v:rect/v:imagedata", "type"); - assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Fallback/w:pict/v:rect/v:imagedata", "color2"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Fallback/w:pict/v:rect/v:imagedata", 0); + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Fallback/w:pict/v:rect/v:fill", 1); + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Fallback/w:pict/v:rect/v:fill", "type", "tile"); } DECLARE_OOXMLEXPORT_TEST(testBnc837302, "bnc837302.docx") diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index c73418df7254..95f7957db5e1 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -490,7 +490,8 @@ public: /// Writes wp wrapper code around an SdrObject, which itself is written using drawingML syntax. void textFrameShadow(const SwFrameFormat& rFrameFormat); - static bool isSupportedDMLShape(const uno::Reference<drawing::XShape>& xShape); + static bool isSupportedDMLShape(const uno::Reference<drawing::XShape>& xShape, + const SdrObject* pSdrObject); void setSerializer(const sax_fastparser::FSHelperPtr& pSerializer) { @@ -1379,7 +1380,7 @@ void DocxSdrExport::writeDMLDrawing(const SdrObject* pSdrObject, const SwFrameFo int nAnchorId) { uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pSdrObject)->getUnoShape()); - if (!Impl::isSupportedDMLShape(xShape)) + if (!Impl::isSupportedDMLShape(xShape, pSdrObject)) return; m_pImpl->getExport().DocxAttrOutput().GetSdtEndBefore(pSdrObject); @@ -1539,23 +1540,33 @@ void DocxSdrExport::Impl::textFrameShadow(const SwFrameFormat& rFrameFormat) XML_offset, aOffset); } -bool DocxSdrExport::Impl::isSupportedDMLShape(const uno::Reference<drawing::XShape>& xShape) +bool DocxSdrExport::Impl::isSupportedDMLShape(const uno::Reference<drawing::XShape>& xShape, + const SdrObject* pSdrObject) { uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW); if (xServiceInfo->supportsService("com.sun.star.drawing.PolyPolygonShape") || xServiceInfo->supportsService("com.sun.star.drawing.PolyLineShape")) return false; + uno::Reference<beans::XPropertySet> xShapeProperties(xShape, uno::UNO_QUERY); // For signature line shapes, we don't want DML, just the VML shape. if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape")) { - uno::Reference<beans::XPropertySet> xShapeProperties(xShape, uno::UNO_QUERY); bool bIsSignatureLineShape = false; xShapeProperties->getPropertyValue("IsSignatureLine") >>= bIsSignatureLineShape; if (bIsSignatureLineShape) return false; } + // A FontWork shape with bitmap fill cannot be expressed as a modern 'abc transform' + // in Word. Only the legacy VML WordArt allows bitmap fill. + if (pSdrObject->IsTextPath()) + { + css::drawing::FillStyle eFillStyle = css::drawing::FillStyle_SOLID; + xShapeProperties->getPropertyValue("FillStyle") >>= eFillStyle; + if (eFillStyle == css::drawing::FillStyle_BITMAP) + return false; + } return true; } @@ -1575,7 +1586,7 @@ void DocxSdrExport::writeDMLAndVMLDrawing(const SdrObject* sdrObj, // In case we are already inside a DML block, then write the shape only as VML, turn out that's allowed to do. // A common service created in util to check for VML shapes which are allowed to have textbox in content - if ((msfilter::util::HasTextBoxContent(eShapeType)) && Impl::isSupportedDMLShape(xShape) + if ((msfilter::util::HasTextBoxContent(eShapeType)) && Impl::isSupportedDMLShape(xShape, sdrObj) && (!bDMLAndVMLDrawingOpen || lcl_isLockedCanvas(xShape))) // Locked canvas is OK inside DML { m_pImpl->getSerializer()->startElementNS(XML_mc, XML_AlternateContent); |