[Libreoffice-commits] core.git: Branch 'distro/vector/vector-5.4' - 3 commits - sw/qa sw/source vcl/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Fri Nov 8 13:48:49 UTC 2019
sw/qa/extras/htmlexport/htmlexport.cxx | 42 ++++++++++++++++++++++++----
sw/source/filter/html/htmlatr.cxx | 3 +-
vcl/source/gdi/pdfwriter_impl.cxx | 49 ++++++++++++++++++++++++++++++---
3 files changed, 84 insertions(+), 10 deletions(-)
New commits:
commit 3e5bedbb6910053c0cee4112cd382fbd035c9832
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Nov 7 17:17:35 2019 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Nov 8 14:24:31 2019 +0100
sw XHTML export: <blockquote> can't have character children
Fixes the following reqif-xhtml validation error:
ERROR at 214: [XSD] cvc-complex-type.2.3: Element 'reqif-xhtml:blockquote' cannot have character [children], because the type's content type is element-only.
But this is probably useful in the general xhtml case as well.
[ Also add a way to not load a document when we want to cover "store"
behavior in a test. ]
(cherry picked from commit f2eae41e9a85cd1df4190160b7453d3e12b8ccbd)
Change-Id: I88795271475863b9560ac1cb99636c507746f1e9
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index f91fa5ceb2a9..9b5c22c2f3c7 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -41,11 +41,11 @@ public:
* Wraps a reqif-xhtml fragment into an XHTML file, so an XML parser can
* parse it.
*/
- void wrapFragment(SvMemoryStream& rStream)
+ static void wrapFragment(utl::TempFile& rTempFile, SvMemoryStream& rStream)
{
rStream.WriteCharPtr(
"<reqif-xhtml:html xmlns:reqif-xhtml=\"http://www.w3.org/1999/xhtml\">\n");
- SvFileStream aFileStream(maTempFile.GetURL(), StreamMode::READ);
+ SvFileStream aFileStream(rTempFile.GetURL(), StreamMode::READ);
rStream.WriteStream(aFileStream);
rStream.WriteCharPtr("</reqif-xhtml:html>\n");
rStream.Seek(0);
@@ -105,6 +105,11 @@ private:
#define DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, HtmlExportTest)
+/// HTML export of the sw doc model tests.
+class SwHtmlDomExportTest : public SwModelTestBase, public HtmlTestTools
+{
+};
+
DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testFdo81276, "fdo81276.html")
{
uno::Reference<container::XNameAccess> xPageStyles(getStyles("PageStyles"));
@@ -581,7 +586,7 @@ DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testReqIfOle2, "reqif-ole2.xhtml")
{
// Check that the replacement graphic is exported at RTF level.
SvMemoryStream aStream;
- wrapFragment(aStream);
+ wrapFragment(maTempFile, aStream);
xmlDocPtr pDoc = parseXmlStream(&aStream);
CPPUNIT_ASSERT(pDoc);
// Get the path of the RTF data.
@@ -646,7 +651,7 @@ DECLARE_HTMLEXPORT_TEST(testTransparentImage, "transparent-image.odt")
DECLARE_HTMLEXPORT_TEST(testTransparentImageReqIf, "transparent-image.odt")
{
SvMemoryStream aStream;
- wrapFragment(aStream);
+ wrapFragment(maTempFile, aStream);
xmlDocPtr pDoc = parseXmlStream(&aStream);
CPPUNIT_ASSERT(pDoc);
@@ -663,7 +668,7 @@ DECLARE_HTMLEXPORT_TEST(testOleNodataReqIf, "reqif-ole-nodata.odt")
{
// This failed, io::IOException was thrown during the filter() call.
SvMemoryStream aStream;
- wrapFragment(aStream);
+ wrapFragment(maTempFile, aStream);
xmlDocPtr pDoc = parseXmlStream(&aStream);
CPPUNIT_ASSERT(pDoc);
@@ -678,7 +683,7 @@ DECLARE_HTMLEXPORT_TEST(testOleNodataReqIf, "reqif-ole-nodata.odt")
DECLARE_HTMLEXPORT_TEST(testNoLangReqIf, "reqif-no-lang.odt")
{
SvMemoryStream aStream;
- wrapFragment(aStream);
+ wrapFragment(maTempFile, aStream);
xmlDocPtr pDoc = parseXmlStream(&aStream);
CPPUNIT_ASSERT(pDoc);
@@ -716,6 +721,31 @@ DECLARE_HTMLEXPORT_TEST(testFieldShadeReqIf, "field-shade-reqif.odt")
assertXPath(pDoc, "/html/body/div/p[1]/sdfield", 0);
}
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testBlockQuoteReqIf)
+{
+ // Build a document model that uses the Quotations paragraph style.
+ loadURL("private:factory/swriter", nullptr);
+ uno::Reference<beans::XPropertySet> xParagraph(getParagraph(1), uno::UNO_QUERY);
+ xParagraph->setPropertyValue("ParaStyleName", uno::makeAny(OUString("Quotations")));
+
+ // Export it.
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= OUString("HTML (StarWriter)");
+ aMediaDescriptor["FilterOptions"] <<= OUString("xhtmlns=reqif-xhtml");
+ xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+ SvMemoryStream aStream;
+ HtmlExportTest::wrapFragment(maTempFile, aStream);
+ xmlDocPtr pDoc = parseXmlStream(&aStream);
+ CPPUNIT_ASSERT(pDoc);
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 0
+ // i.e. <blackquote> had character (direct) children, which is invalid xhtml.
+ assertXPath(pDoc, "/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:blockquote/reqif-xhtml:p", 1);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx
index b765e4967f0a..e9764e79c0b5 100644
--- a/sw/source/filter/html/htmlatr.cxx
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -798,8 +798,9 @@ void OutHTML_SwFormat( Writer& rWrt, const SwFormat& rFormat,
// for BLOCKQUOTE, ADDRESS and DD we output another paragrah token, if
// - no styles are written and
// - a lower spacing or a paragraph alignment exists
+ // Also, XHTML does not allow character children in this context.
OString aToken = rInfo.aToken;
- if( !rHWrt.m_bCfgOutStyles && rInfo.bParaPossible && !bPara &&
+ if( (!rHWrt.m_bCfgOutStyles || rHWrt.mbXHTML) && rInfo.bParaPossible && !bPara &&
(bHasParSpace || pAdjItem) )
{
HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rHWrt.GetNamespace() + rInfo.aToken );
commit cc7b53d569be3d280b414c94ca7ce2e801eb40a0
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Nov 6 16:48:55 2019 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Nov 8 14:14:32 2019 +0100
vcl PDF export: fix re-exporting PDF images with page-level rotation
PDF images are effectively 1 page PDF documents. The page object may
have a /Rotate key, which was simply ignored before. We turn page
objects into form XObjects on PDF export, such rotation can be expressed
with a /Matrix key.
Add support for the 90 degrees rotation case, this can be generalized
later if wanted.
(cherry picked from commit bd520b177637d4b7d9d93733103cff17a3c91b0a)
Conflicts:
vcl/qa/cppunit/pdfexport/data/pdf-image-resource-inline-xobject-ref.pdf
vcl/qa/cppunit/pdfexport/pdfexport.cxx
Change-Id: I55a4f63e0b986637ccdeba0b783f1db9a85c4d93
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 43e97145ad77..7a341f8d10b2 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -11176,6 +11176,34 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit)
aLine.append(" 0 obj\n");
aLine.append("<< /Type /XObject");
aLine.append(" /Subtype /Form");
+
+ long nWidth = aSize.Width();
+ long nHeight = aSize.Height();
+ if (auto pRotate = dynamic_cast<filter::PDFNumberElement*>(pPage->Lookup("Rotate")))
+ {
+ // The original page was rotated, then construct a transformation matrix which does the
+ // same with our form object.
+ if (rtl::math::approxEqual(pRotate->GetValue(), 90))
+ {
+ std::swap(nWidth, nHeight);
+ basegfx::B2DHomMatrix aMat;
+ aMat.rotate(basegfx::deg2rad(pRotate->GetValue()));
+ // Rotate around the origo (bottom left corner) counter-clockwise, then translate
+ // horizontally to effectively keep the bottom left corner unchanged.
+ aLine.append(" /Matrix [ ");
+ aLine.append(aMat.get(0, 0));
+ aLine.append(" ");
+ aLine.append(aMat.get(0, 1));
+ aLine.append(" ");
+ aLine.append(aMat.get(1, 0));
+ aLine.append(" ");
+ aLine.append(aMat.get(1, 1));
+ aLine.append(" 0 ");
+ aLine.append(nWidth);
+ aLine.append(" ] ");
+ }
+ }
+
aLine.append(" /Resources <<");
static const std::initializer_list<OString> aKeys =
{
@@ -11189,9 +11217,9 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit)
aLine.append(copyExternalResources(*pPage, rKey, aCopiedResources));
aLine.append(">>");
aLine.append(" /BBox [ 0 0 ");
- aLine.append(aSize.Width());
+ aLine.append(nWidth);
aLine.append(" ");
- aLine.append(aSize.Height());
+ aLine.append(nHeight);
aLine.append(" ]");
if (!g_bDebugDisableCompression)
commit b6b7e7b54be0b7d48a12ddd7914f807fc7021c43
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Nov 5 16:12:43 2019 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Nov 8 14:07:44 2019 +0100
vcl PDF export: fix re-exporting PDF images for dict obj resource sub-keys
Re-exporting PDF images works by tokenizing the PDF image, identifying
which PDF object is the page object and then copying that over to the
PDF output, together with the dependencies of that object.
This involves copying the resources of the page object. Previously we
assumed that the sub-keys of the resources are always inline
dictionaries, but the bugdoc shows that they can be references as well,
which point to dictionary objects, so add support for this scenario.
(cherry picked from commit adcdd56471f1cc10ff4135975ecadb3a703db6ad)
Change-Id: I78ee1c726e6ecd958232e9fab64773595e5b9c86
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index a742373d3195..43e97145ad77 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -11033,8 +11033,23 @@ OString PDFWriterImpl::copyExternalResources(filter::PDFObjectElement& rPage, co
if (auto pResources = dynamic_cast<filter::PDFDictionaryElement*>(rPage.Lookup("Resources")))
{
// Resources is a direct dictionary.
- if (auto pDictionary = dynamic_cast<filter::PDFDictionaryElement*>(pResources->LookupElement(rKind)))
+ filter::PDFElement* pLookup = pResources->LookupElement(rKind);
+ if (auto pDictionary = dynamic_cast<filter::PDFDictionaryElement*>(pLookup))
+ {
+ // rKind is an inline dictionary.
aItems = pDictionary->GetItems();
+ }
+ else if (auto pReference = dynamic_cast<filter::PDFReferenceElement*>(pLookup))
+ {
+ // rKind refers to a dictionary.
+ filter::PDFObjectElement* pReferenced = pReference->LookupObject();
+ if (!pReferenced)
+ {
+ return OString();
+ }
+
+ aItems = pReferenced->GetDictionaryItems();
+ }
}
else if (filter::PDFObjectElement* pPageResources = rPage.LookupObject("Resources"))
{
More information about the Libreoffice-commits
mailing list