tdf#167641 emfio: render PDF in EMR_COMMENT_MULTIFORMATS with Version=0
MS Office writes the EmrFormat.Version field as 0 in the EMR_COMMENT_MULTIFORMATS record carrying an embedded PDF. Per [MS-EMF] 2.3.3.4.2 EmrFormat, Version MUST be 0x00000001 only when Signature == EPS_SIGNATURE; for any other signature it MUST be ignored. The reader rejected anything but 1, so the embedded PDF was dropped on the floor. Real-world files also use an empty OutputRect (0,0,0,0); per [MS-EMF] 2.3.3.4.3 it is in logical coordinates, so fall back to the EMF's logical bounds (mrclBounds) when it is degenerate, so ResolveBitmapActions has somewhere to draw the PDF bitmap. The new fixture is the existing pdf-in-emf.pptx EMF with the two fields patched to reproduce the regression in 776 bytes. Signed-off-by: Andras Timar <andras.timar@collabora.com> Change-Id: I432f75a1cac11d84448db07c1a1815cd0be60744 Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1904 Tested-by: Jenkins CPCI <releng@collaboraoffice.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com> (cherry picked from commit a5d7b2935718bf7f1f6cc0352c8d8681e6713f4b) Cherry-pick note: the test fails on macOS in CI Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205084 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
committed by
Xisco Fauli
parent
2c0bc4e33c
commit
c043f65f66
@@ -2032,6 +2032,32 @@ CPPUNIT_TEST_FIXTURE(Test, testCreatePen)
|
||||
assertXPath(pDocument, aXPathPrefix + "mask//pointarray[1]/point", "y", u"8918");
|
||||
}
|
||||
|
||||
#if !defined(MACOSX)
|
||||
CPPUNIT_TEST_FIXTURE(Test, testPdfInEmfVersion0)
|
||||
{
|
||||
// tdf#167641 EMF with EMR_COMMENT_MULTIFORMATS carrying a PDF, where the
|
||||
// EmrFormat.Version field is 0 (as written by current MS Office) and the
|
||||
// OutputRect is empty (0,0,0,0). [MS-EMF] 2.3.3.4.2 says Version must be
|
||||
// ignored unless Signature == EPS_SIGNATURE; an empty OutputRect must fall
|
||||
// back to the EMF's logical bounds. Without the fix, the embedded PDF was
|
||||
// not rendered at all.
|
||||
if (!vcl::pdf::PDFiumLibrary::get())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Primitive2DSequence aSequence
|
||||
= parseEmf(u"/emfio/qa/cppunit/emf/data/TestPdfInEmfVersion0.emf");
|
||||
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
|
||||
drawinglayer::Primitive2dXmlDump dumper;
|
||||
xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence));
|
||||
CPPUNIT_ASSERT(pDocument);
|
||||
|
||||
// Without the fix the metafile was empty (no bitmap was drawn).
|
||||
assertXPath(pDocument, "//bitmap"_ostr, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testPdfInEmf)
|
||||
{
|
||||
if (!vcl::pdf::PDFiumLibrary::get())
|
||||
|
||||
Binary file not shown.
@@ -477,6 +477,14 @@ namespace emfio
|
||||
{
|
||||
tools::Rectangle aOutputRect = EmfReader::ReadRectangle();
|
||||
|
||||
// [MS-EMF] 2.3.3.4.3 EMR_COMMENT_MULTIFORMATS: OutputRect is in logical
|
||||
// coordinates. MS Office sometimes writes (0,0,0,0); fall back to the
|
||||
// EMF's logical bounds so the embedded PDF actually gets drawn.
|
||||
if (aOutputRect.GetWidth() <= 1 && aOutputRect.GetHeight() <= 1)
|
||||
{
|
||||
aOutputRect = mrclBounds;
|
||||
}
|
||||
|
||||
sal_uInt32 nCountFormats(0);
|
||||
mpInputStream->ReadUInt32(nCountFormats);
|
||||
if (nCountFormats < 1)
|
||||
@@ -492,12 +500,11 @@ namespace emfio
|
||||
return;
|
||||
}
|
||||
|
||||
sal_uInt32 nVersion(0);
|
||||
mpInputStream->ReadUInt32(nVersion);
|
||||
if (nVersion != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// [MS-EMF] 2.3.3.4.2 EmrFormat: Version MUST be 0x00000001 only when
|
||||
// Signature == EPS_SIGNATURE; for any other signature it MUST be ignored.
|
||||
// MS Office writes Version=0 with Signature="PDF "; older code rejected that.
|
||||
// Skip the Version field without reading it, since its value is irrelevant here.
|
||||
mpInputStream->SeekRel(sizeof(sal_uInt32));
|
||||
|
||||
sal_uInt32 nSizeData(0);
|
||||
mpInputStream->ReadUInt32(nSizeData);
|
||||
|
||||
Reference in New Issue
Block a user