[Libreoffice-commits] core.git: external/libepubgen

Mark Hung marklh9 at gmail.com
Wed Apr 4 07:03:45 UTC 2018


 external/libepubgen/0001-Support-writing-mode-for-reflowable-layout-method.patch.1    |  264 ++++++++++
 external/libepubgen/0002-Always-keep-page-properties-when-splitting-the-HTML-.patch.1 |  181 ++++++
 external/libepubgen/0003-Ensure-page-properties-in-the-page-span-works.patch.1        |  225 ++++++++
 external/libepubgen/UnpackedTarball_libepubgen.mk                                     |    6 
 4 files changed, 676 insertions(+)

New commits:
commit 75c166d058717a7edd26273f50a86fe5f2cc7fb0
Author: Mark Hung <marklh9 at gmail.com>
Date:   Wed Mar 28 07:26:08 2018 +0800

    tdf#115623: patch libepubgen to support writing-mode.
    
    Backport three patches from libepubgen master branch to support
    exporting style:writing-mode as body CSS styles.
    
    1. Support writing-mode for reflowable layout method.
    https://sourceforge.net/p/libepubgen/code/ci/9a284081eea4a95235a6d6a6a50cbe3f7ad323ba/
    
    2. Always keep page properties when splitting.
    https://sourceforge.net/p/libepubgen/code/ci/0318031b9094b9180d1d391d0ca31a782b016e99/
    
    3. Ensure page properties in the page span work
    https://sourceforge.net/p/libepubgen/code/ci/1f602fcaa74fc9dbc6457019d11c602ff4040a4e/
    
    Change-Id: I9033cb1f5fcbfedb423308fb29b9bd4d6d7d7a43
    Reviewed-on: https://gerrit.libreoffice.org/52083
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/external/libepubgen/0001-Support-writing-mode-for-reflowable-layout-method.patch.1 b/external/libepubgen/0001-Support-writing-mode-for-reflowable-layout-method.patch.1
new file mode 100644
index 000000000000..d3799d1d6e8b
--- /dev/null
+++ b/external/libepubgen/0001-Support-writing-mode-for-reflowable-layout-method.patch.1
@@ -0,0 +1,264 @@
+From 9b1c3fd42fa256b58dfb4dedd070954406c25596 Mon Sep 17 00:00:00 2001
+From: Mark Hung <marklh9 at gmail.com>
+Date: Mon, 19 Mar 2018 20:36:11 +0800
+Subject: [PATCH 1/3] Support writing-mode for reflowable layout method.
+
+Convert style:writing-mode in page properties to css style for
+HTML body element. The class names of body elements will be like
+"body0".
+---
+ src/lib/EPUBGenerator.cpp          |  1 +
+ src/lib/EPUBHTMLGenerator.cpp      | 18 +++++++++++++--
+ src/lib/EPUBSpanStyleManager.cpp   | 45 ++++++++++++++++++++++++++++++++------
+ src/lib/EPUBSpanStyleManager.h     | 14 ++++++++----
+ src/test/EPUBTextGeneratorTest.cpp | 25 +++++++++++++++++++++
+ 5 files changed, 90 insertions(+), 13 deletions(-)
+
+diff --git a/src/lib/EPUBGenerator.cpp b/src/lib/EPUBGenerator.cpp
+index 83f3f40..56db4dc 100644
+--- a/src/lib/EPUBGenerator.cpp
++++ b/src/lib/EPUBGenerator.cpp
+@@ -122,6 +122,7 @@ void EPUBGenerator::startNewHtmlFile()
+   if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED && m_currentHtml)
+     m_currentHtml->getPageProperties(pageProperties);
+   m_currentHtml = m_htmlManager.create(m_imageManager, m_fontManager, m_listStyleManager, m_paragraphStyleManager, m_spanStyleManager, m_tableStyleManager, m_stylesheetPath, m_stylesMethod, m_layoutMethod, m_version);
++
+   if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED)
+     m_currentHtml->setPageProperties(pageProperties);
+ 
+diff --git a/src/lib/EPUBHTMLGenerator.cpp b/src/lib/EPUBHTMLGenerator.cpp
+index 342213e..d5cc0d2 100644
+--- a/src/lib/EPUBHTMLGenerator.cpp
++++ b/src/lib/EPUBHTMLGenerator.cpp
+@@ -600,6 +600,20 @@ void EPUBHTMLGenerator::endDocument()
+   RVNGPropertyList bodyAttrs;
+   if (m_impl->m_version >= 30)
+     bodyAttrs.insert("xmlns:epub", "http://www.idpf.org/2007/ops");
++
++  if (m_impl->m_actualPageProperties["style:writing-mode"])
++  {
++    switch (m_impl->m_stylesMethod)
++    {
++    case EPUB_STYLES_METHOD_CSS:
++      bodyAttrs.insert("class", m_impl->m_spanManager.getClass(m_impl->m_actualPageProperties, true).c_str());
++      break;
++    case EPUB_STYLES_METHOD_INLINE:
++      bodyAttrs.insert("style", m_impl->m_spanManager.getStyle(m_impl->m_actualPageProperties, true).c_str());
++      break;
++    }
++  }
++
+   m_impl->m_document.openElement("body", bodyAttrs);
+   m_impl->flushUnsent(m_impl->m_document);
+   m_impl->m_document.closeElement("body");
+@@ -710,10 +724,10 @@ void EPUBHTMLGenerator::openSpan(const RVNGPropertyList &propList)
+   switch (m_impl->m_stylesMethod)
+   {
+   case EPUB_STYLES_METHOD_CSS:
+-    attrs.insert("class", m_impl->m_spanManager.getClass(propList).c_str());
++    attrs.insert("class", m_impl->m_spanManager.getClass(propList, false).c_str());
+     break;
+   case EPUB_STYLES_METHOD_INLINE:
+-    attrs.insert("style", m_impl->m_spanManager.getStyle(propList).c_str());
++    attrs.insert("style", m_impl->m_spanManager.getStyle(propList, false).c_str());
+     break;
+   }
+   m_impl->output(false).openElement("span", attrs);
+diff --git a/src/lib/EPUBSpanStyleManager.cpp b/src/lib/EPUBSpanStyleManager.cpp
+index e25fa26..ded34ba 100644
+--- a/src/lib/EPUBSpanStyleManager.cpp
++++ b/src/lib/EPUBSpanStyleManager.cpp
+@@ -21,7 +21,7 @@ namespace libepubgen
+ 
+ using librevenge::RVNGPropertyList;
+ 
+-std::string EPUBSpanStyleManager::getClass(RVNGPropertyList const &pList)
++std::string EPUBSpanStyleManager::getClass(RVNGPropertyList const &pList, bool bIsBody)
+ {
+   if (pList["librevenge:span-id"])
+   {
+@@ -31,20 +31,31 @@ std::string EPUBSpanStyleManager::getClass(RVNGPropertyList const &pList)
+   }
+ 
+   EPUBCSSProperties content;
+-  extractProperties(pList, content);
++  if (bIsBody)
++    extractBodyProperties(pList, content);
++  else
++    extractSpanProperties(pList, content);
++
+   ContentNameMap_t::const_iterator it = m_contentNameMap.find(content);
+   if (it != m_contentNameMap.end())
+     return it->second;
+   std::stringstream s;
+-  s << "span" << m_contentNameMap.size();
++  if (bIsBody)
++    s << "body" << (m_numberBody.next() - 1);
++  else
++    s << "span" << (m_numberSpan.next() - 1);
++
+   m_contentNameMap[content]=s.str();
+   return s.str();
+ }
+ 
+-std::string EPUBSpanStyleManager::getStyle(RVNGPropertyList const &pList)
++std::string EPUBSpanStyleManager::getStyle(RVNGPropertyList const &pList, bool bIsBody)
+ {
+   EPUBCSSProperties content;
+-  extractProperties(pList, content);
++  if (bIsBody)
++    extractBodyProperties(pList, content);
++  else
++    extractSpanProperties(pList, content);
+ 
+   std::stringstream s;
+   for (const auto &property : content)
+@@ -62,7 +73,7 @@ void EPUBSpanStyleManager::defineSpan(RVNGPropertyList const &propList)
+   int id=propList["librevenge:span-id"]->getInt();
+   RVNGPropertyList pList(propList);
+   pList.remove("librevenge:span-id");
+-  m_idNameMap[id]=getClass(pList);
++  m_idNameMap[id]=getClass(pList, false);
+ }
+ 
+ void EPUBSpanStyleManager::send(EPUBCSSSink &out)
+@@ -75,7 +86,7 @@ void EPUBSpanStyleManager::send(EPUBCSSSink &out)
+   }
+ }
+ 
+-void EPUBSpanStyleManager::extractProperties(RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const
++void EPUBSpanStyleManager::extractSpanProperties(RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const
+ {
+   if (pList["fo:background-color"])
+     cssProps["background-color"] = pList["fo:background-color"]->getStr().cstr();
+@@ -227,6 +238,26 @@ void EPUBSpanStyleManager::extractTextPosition(char const *value, EPUBCSSPropert
+   }
+ }
+ 
++void EPUBSpanStyleManager::extractBodyProperties(RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const
++{
++  if (pList["style:writing-mode"])
++  {
++    std::string mode = pList["style:writing-mode"]->getStr().cstr();
++    if (mode == "tb-rl" || mode == "tb")
++      mode = "vertical-rl";
++    else if (mode == "tb-lr")
++      mode = "vertical-lr";
++    else // For the rest: lr, lr-tb, rl, rl-tb
++    {
++      mode = "horizontal-tb";
++      cssProps["direction"] = (mode == "rl-tb" || mode == "rl")?"rtl":"ltr";
++    }
++
++    cssProps["-epub-writing-mode"] = mode;
++    cssProps["-webkit-writing-mode"] = mode;
++    cssProps["writing-mode"] = mode;
++  }
++}
+ }
+ 
+ /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
+diff --git a/src/lib/EPUBSpanStyleManager.h b/src/lib/EPUBSpanStyleManager.h
+index ec9d0e5..6c18392 100644
+--- a/src/lib/EPUBSpanStyleManager.h
++++ b/src/lib/EPUBSpanStyleManager.h
+@@ -19,6 +19,7 @@
+ #include <librevenge/librevenge.h>
+ 
+ #include "EPUBCSSProperties.h"
++#include "EPUBCounter.h"
+ 
+ namespace libepubgen
+ {
+@@ -32,7 +33,7 @@ class EPUBSpanStyleManager
+ 
+ public:
+   //! constructor
+-  EPUBSpanStyleManager() : m_contentNameMap(), m_idNameMap()
++  EPUBSpanStyleManager() : m_contentNameMap(), m_idNameMap(), m_numberSpan(), m_numberBody()
+   {
+   }
+   //! destructor
+@@ -42,14 +43,16 @@ public:
+   //! define a span style
+   void defineSpan(librevenge::RVNGPropertyList const &pList);
+   //! returns the class name corresponding to a propertylist
+-  std::string getClass(librevenge::RVNGPropertyList const &pList);
++  std::string getClass(librevenge::RVNGPropertyList const &pList, bool bIsBody);
+   //! returns the style string corresponding to a propertylist
+-  std::string getStyle(librevenge::RVNGPropertyList const &pList);
++  std::string getStyle(librevenge::RVNGPropertyList const &pList, bool bIsBody);
+   //! send the data to the sink
+   void send(EPUBCSSSink &out);
+ protected:
+   //! convert a property list into a CSS property map
+-  void extractProperties(librevenge::RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const;
++  void extractSpanProperties(librevenge::RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const;
++  //! Extract body styles from a property list into a CSS property map
++  void extractBodyProperties(librevenge::RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const;
+   //! add data corresponding to a text position into the map
+   void extractTextPosition(char const *value, EPUBCSSProperties &cssProps) const;
+   //! add data corresponding to the line decoration into the map
+@@ -59,6 +62,9 @@ protected:
+   //! a map id -> name
+   std::map<int, std::string> m_idNameMap;
+ 
++  EPUBCounter m_numberSpan;
++  EPUBCounter m_numberBody;
++
+ private:
+   EPUBSpanStyleManager(EPUBSpanStyleManager const &orig);
+   EPUBSpanStyleManager operator=(EPUBSpanStyleManager const &orig);
+diff --git a/src/test/EPUBTextGeneratorTest.cpp b/src/test/EPUBTextGeneratorTest.cpp
+index ddf0c90..cf5e35f 100644
+--- a/src/test/EPUBTextGeneratorTest.cpp
++++ b/src/test/EPUBTextGeneratorTest.cpp
+@@ -235,6 +235,7 @@ private:
+   CPPUNIT_TEST(testFixedLayoutSpine);
+   CPPUNIT_TEST(testPageBreak);
+   CPPUNIT_TEST(testPageBreakImage);
++  CPPUNIT_TEST(testWritingMode);
+   CPPUNIT_TEST_SUITE_END();
+ 
+ private:
+@@ -274,6 +275,7 @@ private:
+   void testFixedLayoutSpine();
+   void testPageBreak();
+   void testPageBreakImage();
++  void testWritingMode();
+ 
+   /// Asserts that exactly one xpath exists in buffer, and its content equals content.
+   void assertXPathContent(xmlBufferPtr buffer, const std::string &xpath, const std::string &content);
+@@ -1350,6 +1352,29 @@ void EPUBTextGeneratorTest::testPageBreakImage()
+   CPPUNIT_ASSERT(package.m_streams.find("OEBPS/sections/section0002.xhtml") != package.m_streams.end());
+ }
+ 
++void EPUBTextGeneratorTest::testWritingMode()
++{
++  StringEPUBPackage package;
++  libepubgen::EPUBTextGenerator generator(&package);
++  generator.setOption(libepubgen::EPUB_GENERATOR_OPTION_SPLIT, libepubgen::EPUB_SPLIT_METHOD_PAGE_BREAK);
++  generator.startDocument(librevenge::RVNGPropertyList());
++
++  {
++    librevenge::RVNGPropertyList page;
++    page.insert("style:writing-mode", "tb");
++    generator.openPageSpan(page);
++
++    librevenge::RVNGPropertyList para;
++    generator.openParagraph(para);
++    generator.insertText("Para1");
++    generator.closeParagraph();
++    generator.closePageSpan();
++  }
++  generator.endDocument();
++  assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
++  assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
++}
++
+ CPPUNIT_TEST_SUITE_REGISTRATION(EPUBTextGeneratorTest);
+ 
+ }
+-- 
+2.14.1
+
diff --git a/external/libepubgen/0002-Always-keep-page-properties-when-splitting-the-HTML-.patch.1 b/external/libepubgen/0002-Always-keep-page-properties-when-splitting-the-HTML-.patch.1
new file mode 100644
index 000000000000..9b26c279fa5c
--- /dev/null
+++ b/external/libepubgen/0002-Always-keep-page-properties-when-splitting-the-HTML-.patch.1
@@ -0,0 +1,181 @@
+From c3bd3bee2f6e01f0b5f5a8fb376ce175573a8e96 Mon Sep 17 00:00:00 2001
+From: Mark Hung <marklh9 at gmail.com>
+Date: Sat, 24 Mar 2018 12:50:12 +0800
+Subject: [PATCH 2/3] Always keep page properties when splitting the HTML file.
+
+Those page properties shall be changed only via openPageSpan.
+It was kept only when the layout out method is EPUB_LAYOUT_METHOD_FIXED
+before.
+---
+ src/lib/EPUBGenerator.cpp          |  9 ++--
+ src/test/EPUBTextGeneratorTest.cpp | 98 ++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 99 insertions(+), 8 deletions(-)
+
+diff --git a/src/lib/EPUBGenerator.cpp b/src/lib/EPUBGenerator.cpp
+index 56db4dc..110667f 100644
+--- a/src/lib/EPUBGenerator.cpp
++++ b/src/lib/EPUBGenerator.cpp
+@@ -110,21 +110,20 @@ void EPUBGenerator::setDocumentMetaData(const RVNGPropertyList &props)
+ void EPUBGenerator::startNewHtmlFile()
+ {
+   // close the current HTML file
++  librevenge::RVNGPropertyList pageProperties;
+   if (bool(m_currentHtml))
+   {
+     endHtmlFile();
+     m_currentHtml->endDocument();
++    m_currentHtml->getPageProperties(pageProperties);
+   }
+ 
+   m_splitGuard.onSplit();
+ 
+-  librevenge::RVNGPropertyList pageProperties;
+-  if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED && m_currentHtml)
+-    m_currentHtml->getPageProperties(pageProperties);
+   m_currentHtml = m_htmlManager.create(m_imageManager, m_fontManager, m_listStyleManager, m_paragraphStyleManager, m_spanStyleManager, m_tableStyleManager, m_stylesheetPath, m_stylesMethod, m_layoutMethod, m_version);
+ 
+-  if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED)
+-    m_currentHtml->setPageProperties(pageProperties);
++  // Splitted html file should keep the same page property.
++  m_currentHtml->setPageProperties(pageProperties);
+ 
+   // restore state in the new file
+   m_currentHtml->startDocument(m_documentProps);
+diff --git a/src/test/EPUBTextGeneratorTest.cpp b/src/test/EPUBTextGeneratorTest.cpp
+index cf5e35f..0946408 100644
+--- a/src/test/EPUBTextGeneratorTest.cpp
++++ b/src/test/EPUBTextGeneratorTest.cpp
+@@ -235,7 +235,10 @@ private:
+   CPPUNIT_TEST(testFixedLayoutSpine);
+   CPPUNIT_TEST(testPageBreak);
+   CPPUNIT_TEST(testPageBreakImage);
+-  CPPUNIT_TEST(testWritingMode);
++  CPPUNIT_TEST(testPageSpanProperties);
++  CPPUNIT_TEST(testSplitOnPageBreakInPageSpan);
++  CPPUNIT_TEST(testSplitOnHeadingInPageSpan);
++  CPPUNIT_TEST(testSplitOnSizeInPageSpan);
+   CPPUNIT_TEST_SUITE_END();
+ 
+ private:
+@@ -275,7 +278,10 @@ private:
+   void testFixedLayoutSpine();
+   void testPageBreak();
+   void testPageBreakImage();
+-  void testWritingMode();
++  void testPageSpanProperties();
++  void testSplitOnPageBreakInPageSpan();
++  void testSplitOnHeadingInPageSpan();
++  void testSplitOnSizeInPageSpan();
+ 
+   /// Asserts that exactly one xpath exists in buffer, and its content equals content.
+   void assertXPathContent(xmlBufferPtr buffer, const std::string &xpath, const std::string &content);
+@@ -1352,7 +1358,7 @@ void EPUBTextGeneratorTest::testPageBreakImage()
+   CPPUNIT_ASSERT(package.m_streams.find("OEBPS/sections/section0002.xhtml") != package.m_streams.end());
+ }
+ 
+-void EPUBTextGeneratorTest::testWritingMode()
++void EPUBTextGeneratorTest::testPageSpanProperties()
+ {
+   StringEPUBPackage package;
+   libepubgen::EPUBTextGenerator generator(&package);
+@@ -1368,11 +1374,97 @@ void EPUBTextGeneratorTest::testWritingMode()
+     generator.openParagraph(para);
+     generator.insertText("Para1");
+     generator.closeParagraph();
++  }
++  generator.endDocument();
++  assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
++  assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
++}
++
++void EPUBTextGeneratorTest::testSplitOnPageBreakInPageSpan()
++{
++  StringEPUBPackage package;
++  libepubgen::EPUBTextGenerator generator(&package);
++  generator.setOption(libepubgen::EPUB_GENERATOR_OPTION_SPLIT, libepubgen::EPUB_SPLIT_METHOD_PAGE_BREAK);
++  generator.startDocument(librevenge::RVNGPropertyList());
++
++  {
++    librevenge::RVNGPropertyList page;
++    page.insert("style:writing-mode", "tb");
++    generator.openPageSpan(page);
++
++    librevenge::RVNGPropertyList para;
++    generator.openParagraph(para);
++    generator.insertText("Para1");
++    generator.closeParagraph();
++    // Splitting a new html file inside the page span, the writing-mode shall not change.
++    para.insert("fo:break-before", "page");
++    generator.openParagraph(para);
++    generator.insertText("Para2");
++    generator.closeParagraph();
++    generator.closePageSpan();
++  }
++  generator.endDocument();
++  assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
++  assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
++  assertXPath(package.m_streams["OEBPS/sections/section0002.xhtml"], "//xhtml:body", "class", "body0");
++}
++
++void EPUBTextGeneratorTest::testSplitOnHeadingInPageSpan()
++{
++  StringEPUBPackage package;
++  libepubgen::EPUBTextGenerator generator(&package);
++  generator.setOption(libepubgen::EPUB_GENERATOR_OPTION_SPLIT, libepubgen::EPUB_SPLIT_METHOD_HEADING);
++  generator.startDocument(librevenge::RVNGPropertyList());
++
++  {
++    librevenge::RVNGPropertyList page;
++    page.insert("style:writing-mode", "tb");
++    generator.openPageSpan(page);
++
++    librevenge::RVNGPropertyList para;
++    para.insert("text:outline-level", "1");
++    generator.openParagraph(para);
++    generator.insertText("Chapter1");
++    generator.closeParagraph();
++    // Splitting a new html file inside the page span, the writing-mode shall not change.
++    generator.openParagraph(para);
++    generator.insertText("Chapter2");
++    generator.closeParagraph();
++    generator.closePageSpan();
++  }
++  generator.endDocument();
++  assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
++  assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
++  assertXPath(package.m_streams["OEBPS/sections/section0002.xhtml"], "//xhtml:body", "class", "body0");
++}
++
++void EPUBTextGeneratorTest::testSplitOnSizeInPageSpan()
++{
++  StringEPUBPackage package;
++  libepubgen::EPUBTextGenerator generator(&package);
++  generator.setOption(libepubgen::EPUB_GENERATOR_OPTION_SPLIT, libepubgen::EPUB_SPLIT_METHOD_SIZE);
++  generator.setSplitSize(5);
++  generator.startDocument(librevenge::RVNGPropertyList());
++
++  {
++    librevenge::RVNGPropertyList page;
++    page.insert("style:writing-mode", "tb");
++    generator.openPageSpan(page);
++
++    librevenge::RVNGPropertyList para;
++    generator.openParagraph(para);
++    generator.insertText("Hello!");
++    generator.closeParagraph();
++    // Splitting a new html file inside the page span, the writing-mode shall not change.
++    generator.openParagraph(para);
++    generator.insertText("Hello!");
++    generator.closeParagraph();
+     generator.closePageSpan();
+   }
+   generator.endDocument();
+   assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
+   assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
++  assertXPath(package.m_streams["OEBPS/sections/section0002.xhtml"], "//xhtml:body", "class", "body0");
+ }
+ 
+ CPPUNIT_TEST_SUITE_REGISTRATION(EPUBTextGeneratorTest);
+-- 
+2.14.1
+
diff --git a/external/libepubgen/0003-Ensure-page-properties-in-the-page-span-works.patch.1 b/external/libepubgen/0003-Ensure-page-properties-in-the-page-span-works.patch.1
new file mode 100644
index 000000000000..62dd2cbab5dd
--- /dev/null
+++ b/external/libepubgen/0003-Ensure-page-properties-in-the-page-span-works.patch.1
@@ -0,0 +1,225 @@
+From 715786e10deaa6849a6e46b5a9884edde44e194b Mon Sep 17 00:00:00 2001
+From: Mark Hung <marklh9 at gmail.com>
+Date: Sun, 25 Mar 2018 10:27:07 +0800
+Subject: [PATCH 3/3] Ensure page properties in the page span works.
+
+As the page properties are converted to CSS styles of the
+body element, this patch force it to start a new HTML file
+when openPageSpan is invoked to open the second page span.
+
+This ensures that page properties in every page span works,
+even there are multiple page spans between intentional HTML
+page splits such as on size, on headings, or on page breaks.
+---
+ src/lib/EPUBGenerator.cpp          |  4 +++-
+ src/lib/EPUBSplitGuard.cpp         | 19 ++++++++++++++++++-
+ src/lib/EPUBSplitGuard.h           |  7 ++++++-
+ src/lib/EPUBTextGenerator.cpp      |  5 +++++
+ src/test/EPUBTextGeneratorTest.cpp | 38 ++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 70 insertions(+), 3 deletions(-)
+
+diff --git a/src/lib/EPUBGenerator.cpp b/src/lib/EPUBGenerator.cpp
+index 110667f..9e0c972 100644
+--- a/src/lib/EPUBGenerator.cpp
++++ b/src/lib/EPUBGenerator.cpp
+@@ -44,7 +44,7 @@ EPUBGenerator::EPUBGenerator(EPUBPackage *const package, int version)
+   , m_documentProps()
+   , m_metadata()
+   , m_currentHtml()
+-  , m_splitGuard(EPUB_SPLIT_METHOD_PAGE_BREAK)
++  , m_splitGuard(EPUB_SPLIT_METHOD_PAGE_BREAK,true)
+   , m_version(version)
+   , m_stylesMethod(EPUB_STYLES_METHOD_CSS)
+   , m_layoutMethod(EPUB_LAYOUT_METHOD_REFLOWABLE)
+@@ -173,6 +173,8 @@ void EPUBGenerator::setLayoutMethod(EPUBLayoutMethod layout)
+   if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED)
+     // Fixed layout implies split on page break.
+     m_splitGuard.setSplitMethod(EPUB_SPLIT_METHOD_PAGE_BREAK);
++
++  m_splitGuard.setSplitOnSecondPageSpan(m_layoutMethod == EPUB_LAYOUT_METHOD_REFLOWABLE);
+ }
+ 
+ void EPUBGenerator::writeContainer()
+diff --git a/src/lib/EPUBSplitGuard.cpp b/src/lib/EPUBSplitGuard.cpp
+index 4f7531d..5bee515 100644
+--- a/src/lib/EPUBSplitGuard.cpp
++++ b/src/lib/EPUBSplitGuard.cpp
+@@ -15,8 +15,10 @@ namespace libepubgen
+ static const unsigned DEFAULT_SPLIT_HEADING_LEVEL = 1;
+ static const unsigned DEFAULT_SPLIT_SIZE = 1 << 16;
+ 
+-EPUBSplitGuard::EPUBSplitGuard(const EPUBSplitMethod method)
++EPUBSplitGuard::EPUBSplitGuard(const EPUBSplitMethod method,bool splitOnSecondPageSpan)
+   : m_method(method)
++  , m_splitOnSecondPageSpan(splitOnSecondPageSpan)
++  , m_htmlEverInPageSpan(false)
+   , m_headingLevel(DEFAULT_SPLIT_HEADING_LEVEL)
+   , m_currentHeadingLevel(0)
+   , m_size(DEFAULT_SPLIT_SIZE)
+@@ -25,6 +27,11 @@ EPUBSplitGuard::EPUBSplitGuard(const EPUBSplitMethod method)
+ {
+ }
+ 
++void EPUBSplitGuard::setHtmlEverInPageSpan(bool value)
++{
++  m_htmlEverInPageSpan = value;
++}
++
+ void EPUBSplitGuard::setSplitHeadingLevel(const unsigned level)
+ {
+   m_headingLevel = level;
+@@ -45,6 +52,11 @@ void EPUBSplitGuard::setSplitMethod(EPUBSplitMethod method)
+   m_method = method;
+ }
+ 
++void EPUBSplitGuard::setSplitOnSecondPageSpan(bool value)
++{
++  m_splitOnSecondPageSpan = value;
++}
++
+ void EPUBSplitGuard::openLevel()
+ {
+   ++m_nestingLevel;
+@@ -70,6 +82,11 @@ bool EPUBSplitGuard::splitOnHeading(const unsigned level) const
+   return canSplit(EPUB_SPLIT_METHOD_HEADING) && (m_headingLevel >= level);
+ }
+ 
++bool EPUBSplitGuard::splitOnSecondPageSpan() const
++{
++  return m_splitOnSecondPageSpan && m_htmlEverInPageSpan;
++}
++
+ bool EPUBSplitGuard::inHeading(bool any) const
+ {
+   if (!m_currentHeadingLevel)
+diff --git a/src/lib/EPUBSplitGuard.h b/src/lib/EPUBSplitGuard.h
+index ff55846..a55bad3 100644
+--- a/src/lib/EPUBSplitGuard.h
++++ b/src/lib/EPUBSplitGuard.h
+@@ -18,13 +18,15 @@ namespace libepubgen
+ class EPUBSplitGuard
+ {
+ public:
+-  explicit EPUBSplitGuard(EPUBSplitMethod method);
++  explicit EPUBSplitGuard(EPUBSplitMethod method,bool splitOnSecondPageSpan);
+ 
+   void setSplitHeadingLevel(unsigned level);
+   void setCurrentHeadingLevel(unsigned level);
+   void setSplitSize(unsigned size);
++  void setHtmlEverInPageSpan(bool value);
+   /// Allows overwriting the value given in the constructor.
+   void setSplitMethod(EPUBSplitMethod method);
++  void setSplitOnSecondPageSpan(bool value);
+ 
+   void openLevel();
+   void closeLevel();
+@@ -32,6 +34,7 @@ public:
+ 
+   bool splitOnPageBreak() const;
+   bool splitOnHeading(unsigned level) const;
++  bool splitOnSecondPageSpan() const;
+   bool inHeading(bool any) const;
+   bool splitOnSize() const;
+ 
+@@ -42,6 +45,8 @@ private:
+ 
+ private:
+   EPUBSplitMethod m_method;
++  bool m_splitOnSecondPageSpan;
++  bool m_htmlEverInPageSpan;
+   unsigned m_headingLevel;
+   unsigned m_currentHeadingLevel;
+   unsigned m_size;
+diff --git a/src/lib/EPUBTextGenerator.cpp b/src/lib/EPUBTextGenerator.cpp
+index 8e88adb..db9d360 100644
+--- a/src/lib/EPUBTextGenerator.cpp
++++ b/src/lib/EPUBTextGenerator.cpp
+@@ -110,6 +110,7 @@ void EPUBTextGenerator::Impl::startHtmlFile()
+ 
+ void EPUBTextGenerator::Impl::endHtmlFile()
+ {
++  getSplitGuard().setHtmlEverInPageSpan(false);
+   if (m_inPageSpan)
+     getHtml()->openPageSpan(m_pageSpanProps);
+   if (bool(m_currentHeader))
+@@ -206,10 +207,14 @@ void EPUBTextGenerator::openPageSpan(const librevenge::RVNGPropertyList &propLis
+ {
+   assert(!m_impl->m_inPageSpan);
+ 
++  if (m_impl->getSplitGuard().splitOnSecondPageSpan())
++    m_impl->startNewHtmlFile();
++
+   m_impl->m_inPageSpan = true;
+   m_impl->m_pageSpanProps = propList;
+ 
+   m_impl->getHtml()->openPageSpan(propList);
++  m_impl->getSplitGuard().setHtmlEverInPageSpan(true);
+ }
+ 
+ void EPUBTextGenerator::closePageSpan()
+diff --git a/src/test/EPUBTextGeneratorTest.cpp b/src/test/EPUBTextGeneratorTest.cpp
+index 0946408..b5e43a5 100644
+--- a/src/test/EPUBTextGeneratorTest.cpp
++++ b/src/test/EPUBTextGeneratorTest.cpp
+@@ -239,6 +239,7 @@ private:
+   CPPUNIT_TEST(testSplitOnPageBreakInPageSpan);
+   CPPUNIT_TEST(testSplitOnHeadingInPageSpan);
+   CPPUNIT_TEST(testSplitOnSizeInPageSpan);
++  CPPUNIT_TEST(testManyWritingModes);
+   CPPUNIT_TEST_SUITE_END();
+ 
+ private:
+@@ -282,6 +283,7 @@ private:
+   void testSplitOnPageBreakInPageSpan();
+   void testSplitOnHeadingInPageSpan();
+   void testSplitOnSizeInPageSpan();
++  void testManyWritingModes();
+ 
+   /// Asserts that exactly one xpath exists in buffer, and its content equals content.
+   void assertXPathContent(xmlBufferPtr buffer, const std::string &xpath, const std::string &content);
+@@ -1467,6 +1469,42 @@ void EPUBTextGeneratorTest::testSplitOnSizeInPageSpan()
+   assertXPath(package.m_streams["OEBPS/sections/section0002.xhtml"], "//xhtml:body", "class", "body0");
+ }
+ 
++void EPUBTextGeneratorTest::testManyWritingModes()
++{
++  StringEPUBPackage package;
++  libepubgen::EPUBTextGenerator generator(&package);
++  generator.setOption(libepubgen::EPUB_GENERATOR_OPTION_SPLIT, libepubgen::EPUB_SPLIT_METHOD_PAGE_BREAK);
++  generator.startDocument(librevenge::RVNGPropertyList());
++
++  {
++    librevenge::RVNGPropertyList page;
++    page.insert("style:writing-mode", "tb");
++    generator.openPageSpan(page);
++
++    librevenge::RVNGPropertyList para;
++    generator.openParagraph(para);
++    generator.insertText("Para1");
++    generator.closeParagraph();
++    generator.closePageSpan();
++  }
++  {
++    librevenge::RVNGPropertyList page;
++    page.insert("style:writing-mode", "lr");
++    generator.openPageSpan(page);
++
++    librevenge::RVNGPropertyList para;
++    generator.openParagraph(para);
++    generator.insertText("Para1");
++    generator.closeParagraph();
++    generator.closePageSpan();
++  }
++  generator.endDocument();
++  assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
++  assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body1", "writing-mode: horizontal-tb", true);
++  assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
++  assertXPath(package.m_streams["OEBPS/sections/section0002.xhtml"], "//xhtml:body", "class", "body1");
++}
++
+ CPPUNIT_TEST_SUITE_REGISTRATION(EPUBTextGeneratorTest);
+ 
+ }
+-- 
+2.14.1
+
diff --git a/external/libepubgen/UnpackedTarball_libepubgen.mk b/external/libepubgen/UnpackedTarball_libepubgen.mk
index 47b21d7ee5d0..a6b2020f5f07 100644
--- a/external/libepubgen/UnpackedTarball_libepubgen.mk
+++ b/external/libepubgen/UnpackedTarball_libepubgen.mk
@@ -10,6 +10,12 @@
 epubgen_patches :=
 # Backport of <https://sourceforge.net/p/libepubgen/code/ci/006848cb62225647c418d5143d4e88a9d73829da/>.
 epubgen_patches += libepubgen-epub3.patch.1
+# Backport of <https://sourceforge.net/p/libepubgen/code/ci/9a284081eea4a95235a6d6a6a50cbe3f7ad323ba/>.
+epubgen_patches += 0001-Support-writing-mode-for-reflowable-layout-method.patch.1
+# Backport of <https://sourceforge.net/p/libepubgen/code/ci/0318031b9094b9180d1d391d0ca31a782b016e99/>.
+epubgen_patches += 0002-Always-keep-page-properties-when-splitting-the-HTML-.patch.1
+# Backport of <https://sourceforge.net/p/libepubgen/code/ci/1f602fcaa74fc9dbc6457019d11c602ff4040a4e/>.
+epubgen_patches += 0003-Ensure-page-properties-in-the-page-span-works.patch.1
 
 ifeq ($(COM_IS_CLANG),TRUE)
 ifneq ($(filter -fsanitize=%,$(CC)),)


More information about the Libreoffice-commits mailing list