Kaydet (Commit) 97d44109 authored tarafından Miklos Vajna's avatar Miklos Vajna

sw XHTML export: handle replacement graphic of OLE objects

Replacement image of OLE object in XHTML is <object data="...">, not
<img src="...">.

Change-Id: I244000099037869590a71bf49dd94fbf34a71e50
Reviewed-on: https://gerrit.libreoffice.org/50955Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
Tested-by: 's avatarJenkins <ci@libreoffice.org>
üst efbb82b4
......@@ -12,6 +12,8 @@
#include <com/sun/star/awt/Gradient.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/document/XEmbeddedObjectSupplier2.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <rtl/byteseq.hxx>
#include <swmodule.hxx>
......@@ -356,6 +358,45 @@ DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testReqIfOleData, "reqif-ole-data.xhtml")
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xObjects->getCount());
}
DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testReqIfOleImg, "reqif-ole-img.xhtml")
{
uno::Reference<text::XTextEmbeddedObjectsSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<container::XIndexAccess> xObjects(xSupplier->getEmbeddedObjects(),
uno::UNO_QUERY);
uno::Reference<document::XEmbeddedObjectSupplier2> xObject(xObjects->getByIndex(0),
uno::UNO_QUERY);
// This failed, OLE object had no replacement image.
// And then it also failed when the export lost the replacement image.
uno::Reference<graphic::XGraphic> xGraphic = xObject->getReplacementGraphic();
CPPUNIT_ASSERT(xGraphic.is());
uno::Reference<drawing::XShape> xShape(xObject, uno::UNO_QUERY);
OutputDevice* pDevice = Application::GetDefaultDevice();
Size aPixel(64, 64);
// Expected to be 1693.
Size aLogic(pDevice->PixelToLogic(aPixel, MapMode(MapUnit::Map100thMM)));
awt::Size aSize = xShape->getSize();
// This was only 1247, size was not set explicitly.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(aLogic.getWidth()), aSize.Width);
if (mbExported)
// The below is not yet working for export.
return;
// Check mime/media types.
CPPUNIT_ASSERT_EQUAL(OUString("image/png"), getProperty<OUString>(xGraphic, "MimeType"));
uno::Reference<document::XStorageBasedDocument> xStorageProvider(mxComponent, uno::UNO_QUERY);
uno::Reference<embed::XStorage> xStorage = xStorageProvider->getDocumentStorage();
auto aStreamName = getProperty<OUString>(xObject, "StreamName");
uno::Reference<io::XStream> xStream
= xStorage->openStreamElement(aStreamName, embed::ElementModes::READ);
// This was empty.
CPPUNIT_ASSERT_EQUAL(OUString("text/rtf"), getProperty<OUString>(xStream, "MediaType"));
// Check alternate text (it was empty).
CPPUNIT_ASSERT_EQUAL(OUString("OLE Object"), getProperty<OUString>(xObject, "Title").trim());
}
CPPUNIT_PLUGIN_IMPLEMENT();
......
......@@ -295,41 +295,6 @@ DECLARE_HTMLIMPORT_TEST(testReqIfBr, "reqif-br.xhtml")
CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("aaa\nbbb"));
}
DECLARE_HTMLIMPORT_TEST(testReqIfOleImg, "reqif-ole-img.xhtml")
{
uno::Reference<text::XTextEmbeddedObjectsSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<container::XIndexAccess> xObjects(xSupplier->getEmbeddedObjects(),
uno::UNO_QUERY);
uno::Reference<document::XEmbeddedObjectSupplier2> xObject(xObjects->getByIndex(0),
uno::UNO_QUERY);
// This failed, OLE object had no replacement image.
uno::Reference<graphic::XGraphic> xGraphic = xObject->getReplacementGraphic();
CPPUNIT_ASSERT(xGraphic.is());
uno::Reference<drawing::XShape> xShape(xObject, uno::UNO_QUERY);
OutputDevice* pDevice = Application::GetDefaultDevice();
Size aPixel(64, 64);
// Expected to be 1693.
Size aLogic(pDevice->PixelToLogic(aPixel, MapMode(MapUnit::Map100thMM)));
awt::Size aSize = xShape->getSize();
// This was only 1247, size was not set explicitly.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(aLogic.getWidth()), aSize.Width);
// Check mime/media types.
CPPUNIT_ASSERT_EQUAL(OUString("image/png"), getProperty<OUString>(xGraphic, "MimeType"));
uno::Reference<document::XStorageBasedDocument> xStorageProvider(mxComponent, uno::UNO_QUERY);
uno::Reference<embed::XStorage> xStorage = xStorageProvider->getDocumentStorage();
auto aStreamName = getProperty<OUString>(xObject, "StreamName");
uno::Reference<io::XStream> xStream
= xStorage->openStreamElement(aStreamName, embed::ElementModes::READ);
// This was empty.
CPPUNIT_ASSERT_EQUAL(OUString("text/rtf"), getProperty<OUString>(xStream, "MediaType"));
// Check alternate text (it was empty).
CPPUNIT_ASSERT_EQUAL(OUString("OLE Object"), getProperty<OUString>(xObject, "Title").trim());
}
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -808,7 +808,7 @@ void SwHTMLWriter::writeFrameFormatOptions(HtmlWriter& aHtml, const SwFrameForma
// Name
if( (nFrameOptions & (HtmlFrmOpts::Id|HtmlFrmOpts::Name)) &&
!rFrameFormat.GetName().isEmpty() )
!rFrameFormat.GetName().isEmpty() && !(nFrameOptions & HtmlFrmOpts::Replacement))
{
const sal_Char* pAttributeName = (nFrameOptions & HtmlFrmOpts::Id) ? OOO_STRING_SVTOOLS_HTML_O_id : OOO_STRING_SVTOOLS_HTML_O_name;
aHtml.attribute(pAttributeName, rFrameFormat.GetName());
......@@ -823,7 +823,7 @@ void SwHTMLWriter::writeFrameFormatOptions(HtmlWriter& aHtml, const SwFrameForma
}
// alt
if( (nFrameOptions & HtmlFrmOpts::Alt) && !rAlternateText.isEmpty() )
if( (nFrameOptions & HtmlFrmOpts::Alt) && !rAlternateText.isEmpty() && !(nFrameOptions & HtmlFrmOpts::Replacement) )
{
aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_alt, rAlternateText);
}
......@@ -832,7 +832,7 @@ void SwHTMLWriter::writeFrameFormatOptions(HtmlWriter& aHtml, const SwFrameForma
const sal_Char* pAlignString = nullptr;
RndStdIds eAnchorId = rFrameFormat.GetAnchor().GetAnchorId();
if( (nFrameOptions & HtmlFrmOpts::Align) &&
((RndStdIds::FLY_AT_PARA == eAnchorId) || (RndStdIds::FLY_AT_CHAR == eAnchorId)) )
((RndStdIds::FLY_AT_PARA == eAnchorId) || (RndStdIds::FLY_AT_CHAR == eAnchorId)) && !(nFrameOptions & HtmlFrmOpts::Replacement))
{
const SwFormatHoriOrient& rHoriOri = rFrameFormat.GetHoriOrient();
if( !(nFrameOptions & HtmlFrmOpts::SAlign) ||
......@@ -863,7 +863,7 @@ void SwHTMLWriter::writeFrameFormatOptions(HtmlWriter& aHtml, const SwFrameForma
case text::VertOrientation::NONE: break;
}
}
if (pAlignString)
if (pAlignString && !(nFrameOptions & HtmlFrmOpts::Replacement))
{
aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_align, pAlignString);
}
......@@ -1356,7 +1356,11 @@ Writer& OutHTML_Image( Writer& rWrt, const SwFrameFormat &rFrameFormat,
}
}
aHtml.start(OOO_STRING_SVTOOLS_HTML_image);
OString aTag(OOO_STRING_SVTOOLS_HTML_image);
if (nFrameOpts & HtmlFrmOpts::Replacement)
// Write replacement graphic of OLE object as <object>.
aTag = OOO_STRING_SVTOOLS_HTML_object;
aHtml.start(aTag);
OStringBuffer sBuffer;
if(rHTMLWrt.mbEmbedImages)
......@@ -1375,7 +1379,10 @@ Writer& OutHTML_Image( Writer& rWrt, const SwFrameFormat &rFrameFormat,
else
{
sBuffer.append(OUStringToOString(aGraphicURL, RTL_TEXTENCODING_UTF8));
aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_src, sBuffer.makeStringAndClear().getStr());
OString aAttribute(OOO_STRING_SVTOOLS_HTML_O_src);
if (nFrameOpts & HtmlFrmOpts::Replacement)
aAttribute = OOO_STRING_SVTOOLS_HTML_O_data;
aHtml.attribute(aAttribute, sBuffer.makeStringAndClear().getStr());
}
// Events
......
......@@ -1457,6 +1457,8 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame
}
HtmlFrmOpts nFlags = bInCntnr ? HtmlFrmOpts::GenImgAllMask
: HtmlFrmOpts::GenImgMask;
if (bObjectOpened)
nFlags |= HtmlFrmOpts::Replacement;
OutHTML_Image( rWrt, rFrameFormat, aGraphicURL, aGraphic,
pOLENd->GetTitle(), pOLENd->GetTwipSize(),
nFlags, "ole" );
......
......@@ -97,12 +97,14 @@ enum class HtmlFrmOpts {
SPixSize = 1<<18,
Id = 1<<19,
Dir = 1<<20,
/// The graphic frame is a replacement image of an OLE object.
Replacement = 1<<21,
GenImgAllMask = Alt | Size | AbsSize | Name,
GenImgMask = GenImgAllMask | Align | Space | BrClear
};
namespace o3tl {
template<> struct typed_flags<HtmlFrmOpts> : is_typed_flags<HtmlFrmOpts, ((1<<21)-1)> {};
template<> struct typed_flags<HtmlFrmOpts> : is_typed_flags<HtmlFrmOpts, ((1<<22)-1)> {};
}
#define HTMLMODE_BLOCK_SPACER 0x00010000
......
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