Kaydet (Commit) 5a43ee13 authored tarafından Miklos Vajna's avatar Miklos Vajna

fdo#32613 RTF export: implemented anchored picture export

RTF originally didn't support anchored pictures: they were always
inline. Then it was invented that pictures can be exported anchored, if
they are in fact shapes, but their "pib" property is set to the hexdump
of the picture contents.

The RTF importer handled this situation for quite some time, but not the
exporter -- this commit implements that.

(cherry picked from commit cb01957a)

Conflicts:
	sw/qa/extras/inc/swmodeltestbase.hxx
	sw/qa/extras/rtfexport/rtfexport.cxx
	sw/source/filter/ww8/rtfattributeoutput.cxx

Change-Id: I173ad9f4f2e24620508ca63c0b892b7d5da4e5b2
üst edbeda30
......@@ -70,6 +70,18 @@ using namespace com::sun::star;
CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \
void TestName::verify()
#if 1
#define DECLARE_RTFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
// For testing during development of a test, you want to use
// DECLARE_OOXMLEXPORT_TEST_ONLY, and change the above to #if 0
// Of course, don't forget to set back to #if 1 when you are done :-)
#else
#define DECLARE_RTFEXPORT_TEST_ONLY(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
#define DECLARE_RTFEXPORT_TEST(TestName, filename) class disabled##TestName : public Test { void disabled(); }; void disabled##TestName::disabled()
#endif
#define DECLARE_SW_IMPORT_TEST(TestName, filename, BaseClass) \
class TestName : public BaseClass { \
public:\
......
......@@ -17,11 +17,12 @@
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/table/BorderLine2.hpp>
#include <com/sun/star/table/ShadowFormat.hpp>
#include <com/sun/star/text/RelOrientation.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp>
#include <com/sun/star/text/XFootnotesSupplier.hpp>
#include <com/sun/star/text/XPageCursor.hpp>
#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
#include <com/sun/star/view/XViewSettingsSupplier.hpp>
#include <com/sun/star/text/RelOrientation.hpp>
#include <vcl/svapp.hxx>
......@@ -49,8 +50,6 @@ public:
}
};
#define DECLARE_RTFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
DECLARE_RTFEXPORT_TEST(testZoom, "zoom.rtf")
{
uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
......@@ -612,6 +611,12 @@ DECLARE_RTFEXPORT_TEST(testFdo77600, "fdo77600.rtf")
CPPUNIT_ASSERT_EQUAL(OUString("Arial"), getProperty<OUString>(getRun(getParagraph(1), 3), "CharFontName"));
}
DECLARE_RTFEXPORT_TEST(testFdo32613, "fdo32613.odt")
{
// This was AS_CHARACTER, RTF export did not support writing anchored pictures.
CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, getProperty<text::TextContentAnchorType>(getShape(1), "AnchorType"));
}
#endif
CPPUNIT_PLUGIN_IMPLEMENT();
......
......@@ -2847,6 +2847,37 @@ void RtfAttributeOutput::FormatSurround( const SwFmtSurround& rSurround )
m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYMAINCNT);
m_aRunText->append( (sal_Int32) aMC.GetValue() );
}
else if (m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax)
{
// See DocxSdrExport::startDMLAnchorInline() for SwFmtSurround -> WR / WRK mappings.
sal_Int32 nWr = -1;
boost::optional<sal_Int32> oWrk;
switch (rSurround.GetValue())
{
case SURROUND_NONE:
nWr = 1; // top and bottom
break;
case SURROUND_THROUGHT:
nWr = 3; // none
break;
case SURROUND_PARALLEL:
nWr = 2; // around
oWrk = 0; // both sides
break;
case SURROUND_IDEAL:
default:
nWr = 2; // around
oWrk = 3; // largest
break;
}
m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_SHPWR;
m_rExport.OutLong(nWr);
if (oWrk)
{
m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_SHPWRK;
m_rExport.OutLong(*oWrk);
}
}
}
void RtfAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert )
......@@ -3454,7 +3485,7 @@ static void lcl_AppendSP( OStringBuffer& rBuffer,
static OString ExportPICT( const SwFlyFrmFmt* pFlyFrmFmt, const Size &rOrig, const Size &rRendered, const Size &rMapped,
const SwCropGrf &rCr, const char *pBLIPType, const sal_uInt8 *pGraphicAry,
unsigned long nSize, const RtfExport& rExport, SvStream *pStream = 0 )
unsigned long nSize, const RtfExport& rExport, SvStream* pStream = 0, bool bWritePicProp = true)
{
OStringBuffer aRet;
bool bIsWMF = std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
......@@ -3462,7 +3493,7 @@ static OString ExportPICT( const SwFlyFrmFmt* pFlyFrmFmt, const Size &rOrig, con
{
aRet.append("{" OOO_STRING_SVTOOLS_RTF_PICT);
if( pFlyFrmFmt )
if (pFlyFrmFmt && bWritePicProp)
{
OUString sDescription = pFlyFrmFmt->GetObjDescription();
//write picture properties - wzDescription at first
......@@ -3675,6 +3706,9 @@ void RtfAttributeOutput::FlyFrameGraphic( const SwFlyFrmFmt* pFlyFrmFmt, const S
aRendered.Height() = rS.GetHeight();
}
const SwPosition* pAnchor = pFlyFrmFmt->GetAnchor().GetCntntAnchor();
sw::Frame aFrame(*pFlyFrmFmt, *pAnchor);
/*
If the graphic is not of type WMF then we will have to store two
graphics, one in the native format wrapped in shppict, and the other in
......@@ -3682,11 +3716,41 @@ void RtfAttributeOutput::FlyFrameGraphic( const SwFlyFrmFmt* pFlyFrmFmt, const S
a wmf already then we don't need any such wrapping
*/
bool bIsWMF = pBLIPType && std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
if (aFrame.IsInline())
{
if (!bIsWMF)
m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT;
}
else
{
m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_SHP "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPINST;
m_pFlyFrameSize = &aRendered;
m_rExport.mpParentFrame = &aFrame;
m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = true;
m_rExport.OutputFormat(aFrame.GetFrmFmt(), false, false, true);
m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = false;
m_rExport.mpParentFrame = NULL;
m_pFlyFrameSize = 0;
std::vector< std::pair<OString, OString> > aFlyProperties;
aFlyProperties.push_back(std::make_pair<OString, OString>("shapeType", OString::number(ESCHER_ShpInst_PictureFrame)));
aFlyProperties.push_back(std::make_pair<OString, OString>("wzDescription", msfilter::rtfutil::OutString(pFlyFrmFmt->GetObjDescription(), m_rExport.eCurrentEncoding)));
aFlyProperties.push_back(std::make_pair<OString, OString>("wzName", msfilter::rtfutil::OutString(pFlyFrmFmt->GetObjTitle(), m_rExport.eCurrentEncoding)));
for (size_t i = 0; i < aFlyProperties.size(); ++i)
{
m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_SP "{";
m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_SN " ";
m_rExport.Strm() << aFlyProperties[i].first.getStr();
m_rExport.Strm() << "}{" OOO_STRING_SVTOOLS_RTF_SV " ";
m_rExport.Strm() << aFlyProperties[i].second.getStr();
m_rExport.Strm() << "}}";
}
m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_SP "{" OOO_STRING_SVTOOLS_RTF_SN " pib" "}{" OOO_STRING_SVTOOLS_RTF_SV " ";
}
bool bWritePicProp = aFrame.IsInline();
if (pBLIPType)
ExportPICT( pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm() );
ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm(), bWritePicProp);
else
{
aStream.Seek(0);
......@@ -3696,9 +3760,11 @@ void RtfAttributeOutput::FlyFrameGraphic( const SwFlyFrmFmt* pFlyFrmFmt, const S
nSize = aStream.Tell();
pGraphicAry = (sal_uInt8*)aStream.GetData();
ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm() );
ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm(), bWritePicProp);
}
if (aFrame.IsInline())
{
if (!bIsWMF)
{
m_rExport.Strm() << "}" "{" OOO_STRING_SVTOOLS_RTF_NONSHPPICT;
......@@ -3714,6 +3780,9 @@ void RtfAttributeOutput::FlyFrameGraphic( const SwFlyFrmFmt* pFlyFrmFmt, const S
m_rExport.Strm() << '}';
}
}
else
m_rExport.Strm() << "}}}}"; // Close SV, SP, SHPINST and SHP.
if (bSwapped)
const_cast<Graphic&>(rGraphic).SwapOut();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment