summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorosnola <alonso.laurent@gmail.com>2017-04-19 14:49:12 +0200
committerDavid Tardon <dtardon@redhat.com>2017-04-19 14:49:12 +0200
commit57f11c3ced46dcd25f670ae889ba4e37ff3f184a (patch)
treeae0e1bbe0b593f79862b382b9da3d617c812150d
parentb9044ff16623db8c3651ee3d3055bca206c5aa9e (diff)
retrieve textbox frames
Change-Id: I3b6f4b8186feedfb9932098305f99a40a72a5726
-rw-r--r--src/lib/ABWCollector.h4
-rw-r--r--src/lib/ABWContentCollector.cpp224
-rw-r--r--src/lib/ABWContentCollector.h10
-rw-r--r--src/lib/ABWOutputElements.cpp56
-rw-r--r--src/lib/ABWOutputElements.h4
-rw-r--r--src/lib/ABWParser.cpp81
-rw-r--r--src/lib/ABWParser.h3
-rw-r--r--src/lib/ABWStylesCollector.h6
8 files changed, 289 insertions, 99 deletions
diff --git a/src/lib/ABWCollector.h b/src/lib/ABWCollector.h
index 4d8a47e..b29ebd9 100644
--- a/src/lib/ABWCollector.h
+++ b/src/lib/ABWCollector.h
@@ -16,6 +16,7 @@
namespace libabw
{
+class ABWOutputElements;
enum ABWUnit
{
@@ -149,7 +150,8 @@ public:
virtual void closeCell() = 0;
virtual void openFrame(const char *props, const char *imageId, const char *title, const char *alt) = 0;
- virtual void closeFrame() = 0;
+ virtual void closeFrame(ABWOutputElements *(&elements), bool &pageFrame) = 0;
+ virtual void addFrameElements(ABWOutputElements &elements, bool pageFrame) = 0;
virtual void addMetadataEntry(const char *name, const char *value) = 0;
};
diff --git a/src/lib/ABWContentCollector.cpp b/src/lib/ABWContentCollector.cpp
index bc50660..feec8a6 100644
--- a/src/lib/ABWContentCollector.cpp
+++ b/src/lib/ABWContentCollector.cpp
@@ -330,6 +330,8 @@ libabw::ABWContentParsingState::ABWContentParsingState() :
m_isHeaderOpened(false),
m_isFooterOpened(false),
+ m_isPageFrame(false),
+
m_isSpanOpened(false),
m_isParagraphOpened(false),
m_isListElementOpened(false),
@@ -377,6 +379,8 @@ libabw::ABWContentParsingState::ABWContentParsingState(const ABWContentParsingSt
m_isHeaderOpened(ps.m_isHeaderOpened),
m_isFooterOpened(ps.m_isFooterOpened),
+ m_isPageFrame(ps.m_isPageFrame),
+
m_isSpanOpened(ps.m_isSpanOpened),
m_isParagraphOpened(ps.m_isParagraphOpened),
m_isListElementOpened(ps.m_isListElementOpened),
@@ -1183,6 +1187,13 @@ void libabw::ABWContentCollector::_openParagraph()
if (!m_ps->m_isSectionOpened)
_openSection();
break;
+ case ABW_FRAME_IMAGE:
+ ABW_DEBUG_MSG(("libabw::ABWContentCollector::_openParagraph: can not open a paragraph\n"));
+ m_ps->m_parsingContext=ABW_FRAME_UNKNOWN;
+ break;
+ case ABW_FRAME_TEXTBOX:
+ case ABW_FRAME_UNKNOWN:
+ break;
}
if (!m_ps->m_tableStates.empty() && !m_ps->m_tableStates.top().m_isTableCellOpened)
@@ -1223,6 +1234,13 @@ void libabw::ABWContentCollector::_openListElement()
if (!m_ps->m_isSectionOpened)
_openSection();
break;
+ case ABW_FRAME_IMAGE:
+ ABW_DEBUG_MSG(("libabw::ABWContentCollector::_openListElement: can not open a list\n"));
+ m_ps->m_parsingContext=ABW_FRAME_UNKNOWN;
+ break;
+ case ABW_FRAME_TEXTBOX:
+ case ABW_FRAME_UNKNOWN:
+ break;
}
if (!m_ps->m_tableStates.empty() && !m_ps->m_tableStates.top().m_isTableCellOpened)
@@ -1429,6 +1447,10 @@ void libabw::ABWContentCollector::_openTable()
if (!m_ps->m_isSectionOpened)
_openSection();
break;
+ case ABW_FRAME_IMAGE:
+ case ABW_FRAME_TEXTBOX:
+ case ABW_FRAME_UNKNOWN:
+ break;
}
librevenge::RVNGPropertyList propList;
@@ -1970,6 +1992,10 @@ void libabw::ABWContentCollector::openTable(const char *props)
if (!m_ps->m_isSectionOpened)
_openSection();
break;
+ case ABW_FRAME_IMAGE:
+ case ABW_FRAME_TEXTBOX:
+ case ABW_FRAME_UNKNOWN:
+ break;
}
}
@@ -2057,101 +2083,161 @@ void libabw::ABWContentCollector::openFrame(const char *props, const char *image
ABWPropertyMap propMap;
if (props)
parsePropString(props, propMap);
- ABWPropertyMap::const_iterator iter = propMap.find("frame-type");
- if (iter==propMap.end())
+ ABWPropertyMap::const_iterator iter;
+
+ librevenge::RVNGPropertyList propList;
+ ABWUnit unit(ABW_NONE);
+ double value(0.0);
+ // size
+ iter = propMap.find("frame-height");
+ if (iter != propMap.end() && findDouble(iter->second, value, unit) && ABW_IN == unit)
+ propList.insert("svg:height", value);
+ iter = propMap.find("frame-width");
+ if (iter != propMap.end() && findDouble(iter->second, value, unit) && ABW_IN == unit)
+ propList.insert("svg:width", value);
+ // position
+ bool isParagraph=true;
+ iter = propMap.find("position-to");
+ if (iter != propMap.end())
{
- ABW_DEBUG_MSG(("libabw::ABWContentCollector::openFrame: can not find the frame type\n"));
+ if (iter->second=="page-above-text")
+ isParagraph=false;
+ else if (iter->second=="column-above-text")
+ /* unsure how to retrieve that, so check if the page positions
+ are defined, if yes, use a page anchor. */
+ isParagraph=(propMap.find("frame-page-ypos")==propMap.end());
+ else if (iter->second!="block-above-text")
+ {
+ ABW_DEBUG_MSG(("libabw::ABWContentCollector::openFrame: sorry, unknown pos: %s asume paragraph\n", iter->second.c_str()));
+ }
}
- if (iter->second=="image")
+ iter = propMap.find(isParagraph ? "xpos" : "frame-page-xpos");
+ if (iter != propMap.end() && findDouble(iter->second, value, unit) && ABW_IN == unit)
+ propList.insert("svg:x", value);
+ iter = propMap.find(isParagraph ? "ypos" : "frame-page-ypos");
+ if (iter != propMap.end() && findDouble(iter->second, value, unit) && ABW_IN == unit)
+ propList.insert("svg:y", value);
+ if (!isParagraph)
{
- std::map<std::string, ABWData>::const_iterator imIter;
- if (imageId) imIter= m_data.find(imageId);
- if (imIter==m_data.end())
+ propList.insert("style:vertical-rel", "page");
+ propList.insert("style:horizontal-rel", "page");
+ }
+ if (!isParagraph)
+ {
+ iter = propMap.find("frame-pref-page");
+ int page=0;
+ if (iter != propMap.end() && findInt(iter->second, page))
+ propList.insert("text:anchor-page-number", page+1);
+ }
+ // style
+ int intValue;
+ iter = propMap.find("bg-style"); // 0: none, 1: color=background-color
+ if (iter != propMap.end() && findInt(iter->second, intValue) && intValue==1)
+ {
+ iter = propMap.find("background-color");
+ if (iter != propMap.end())
{
- ABW_DEBUG_MSG(("libabw::ABWContentCollector::openFrame: can not find the image\n"));
- return;
+ std::string color("#");
+ color+=iter->second;
+ propList.insert("fo:background-color", color.c_str());
}
-
- librevenge::RVNGPropertyList propList;
- ABWUnit unit(ABW_NONE);
- double value(0.0);
- iter = propMap.find("frame-height");
- if (iter != propMap.end() && findDouble(iter->second, value, unit) && ABW_IN == unit)
- propList.insert("svg:height", value);
- iter = propMap.find("frame-width");
- if (iter != propMap.end() && findDouble(iter->second, value, unit) && ABW_IN == unit)
- propList.insert("svg:width", value);
- bool isParagraph=true;
- iter = propMap.find("position-to");
- if (iter != propMap.end())
+ }
+ propList.insert("text:anchor-type", isParagraph ? "paragraph" : "page");
+ iter = propMap.find("wrap-mode");
+ if (iter != propMap.end())
+ {
+ if (iter->second=="wrapped-to-left")
+ propList.insert("style:wrap", "left");
+ else if (iter->second=="wrapped-to-right")
+ propList.insert("style:wrap", "right");
+ else if (iter->second=="wrapped-to-both")
+ propList.insert("style:wrap", "parallel");
+ else if (iter->second=="above-text")
{
- if (iter->second=="page-above-text" || iter->second=="column-above-text")
- isParagraph=false;
- else if (iter->second!="block-above-text")
- {
- ABW_DEBUG_MSG(("libabw::ABWContentCollector::openFrame: sorry, unknown pos: %s asume paragraph\n", iter->second.c_str()));
- }
+ propList.insert("style:wrap", "dynamic");
+ propList.insert("style:run-through", "foreground");
+ }
+ else if (iter->second=="below-text")
+ {
+ propList.insert("style:wrap", "dynamic");
+ propList.insert("style:run-through", "background");
}
- iter = propMap.find(isParagraph ? "xpos" : "frame-page-xpos");
- if (iter != propMap.end() && findDouble(iter->second, value, unit) && ABW_IN == unit)
- propList.insert("svg:x", value);
- iter = propMap.find(isParagraph ? "ypos" : "frame-page-ypos");
- if (iter != propMap.end() && findDouble(iter->second, value, unit) && ABW_IN == unit)
- propList.insert("svg:y", value);
- if (isParagraph) _openBlock();
else
{
- iter = propMap.find("frame-pref-page");
- int page=0;
- if (iter != propMap.end() && findInt(iter->second, page))
- propList.insert("text:anchor-page-number", page+1);
+ ABW_DEBUG_MSG(("libabw::ABWContentCollector::openFrame: sorry, unknown wrap mode: %s\n", iter->second.c_str()));
}
- propList.insert("text:anchor-type", isParagraph ? "paragraph" : "page");
- iter = propMap.find("wrap-mode");
- if (iter != propMap.end())
+ }
+ m_ps->m_isPageFrame=!isParagraph;
+ m_outputElements.addOpenFrame(propList);
+
+ iter = propMap.find("frame-type");
+ if (iter==propMap.end())
+ {
+ ABW_DEBUG_MSG(("libabw::ABWContentCollector::openFrame: can not find the frame type\n"));
+ }
+ else if (iter->second=="image")
+ {
+ m_ps->m_parsingContext=ABW_FRAME_IMAGE;
+ std::map<std::string, ABWData>::const_iterator imIter;
+ if (imageId) imIter= m_data.find(imageId);
+ if (imIter==m_data.end())
{
- if (iter->second=="wrapped-to-left")
- propList.insert("style:wrap", "left");
- else if (iter->second=="wrapped-to-right")
- propList.insert("style:wrap", "right");
- else if (iter->second=="wrapped-to-both")
- propList.insert("style:wrap", "parallel");
- else if (iter->second=="above-text")
- {
- propList.insert("style:wrap", "dynamic");
- propList.insert("style:run-through", "foreground");
- }
- else if (iter->second=="below-text")
- {
- propList.insert("style:wrap", "dynamic");
- propList.insert("style:run-through", "background");
- }
- else
- {
- ABW_DEBUG_MSG(("libabw::ABWContentCollector::openFrame: sorry, unknown wrap mode: %s\n", iter->second.c_str()));
- }
+ ABW_DEBUG_MSG(("libabw::ABWContentCollector::openFrame: can not find the image\n"));
+ return;
}
- ABWOutputElements &outputElements=isParagraph ? m_outputElements : m_pageOutputElements;
- outputElements.addOpenFrame(propList);
propList.clear();
propList.insert("librevenge:mime-type", imIter->second.m_mimeType);
propList.insert("office:binary-data", imIter->second.m_binaryData);
- outputElements.addInsertBinaryObject(propList);
+ m_outputElements.addInsertBinaryObject(propList);
- outputElements.addCloseFrame();
return;
}
- if (iter->second=="textbox")
+ else if (iter->second=="textbox")
{
- ABW_DEBUG_MSG(("libabw::ABWContentCollector::openFrame: sorry, opening a text box is not defined\n"));
+ m_ps->m_parsingContext=ABW_FRAME_TEXTBOX;
+ propList.clear();
+ m_outputElements.addOpenTextBox(propList);
return;
}
+ m_ps->m_parsingContext=ABW_FRAME_UNKNOWN;
ABW_DEBUG_MSG(("libabw::ABWContentCollector::openFrame: sorry, unknown frame type: %s\n", iter->second.c_str()));
}
-void libabw::ABWContentCollector::closeFrame()
+void libabw::ABWContentCollector::closeFrame(libabw::ABWOutputElements *(&elements), bool &pageFrame)
+{
+ elements=0;
+ pageFrame=false;
+ if (m_ps->m_isNote)
+ {
+ ABW_DEBUG_MSG(("libabw::ABWContentCollector::closeFrame: sorry, oops, sorry, a note is not closed\n"));
+ return;
+ }
+ if (m_ps->m_parsingContext!=ABW_FRAME_IMAGE && m_ps->m_parsingContext!=ABW_FRAME_TEXTBOX)
+ return;
+
+ while (!m_ps->m_tableStates.empty())
+ _closeTable();
+ _closeBlock();
+ m_ps->m_currentListLevel = 0;
+ _changeList(); // flush the list
+
+ if (m_ps->m_parsingContext==ABW_FRAME_TEXTBOX)
+ m_outputElements.addCloseTextBox();
+ m_outputElements.addCloseFrame();
+ elements=&m_outputElements;
+ pageFrame=m_ps->m_isPageFrame;
+}
+
+void libabw::ABWContentCollector::addFrameElements(ABWOutputElements &elements, bool pageFrame)
{
+ if (pageFrame)
+ m_pageOutputElements.splice(elements);
+ else
+ {
+ _openBlock();
+ m_outputElements.splice(elements);
+ }
}
void libabw::ABWContentCollector::collectData(const char *, const char *, const librevenge::RVNGBinaryData &)
diff --git a/src/lib/ABWContentCollector.h b/src/lib/ABWContentCollector.h
index 9c31f34..faee248 100644
--- a/src/lib/ABWContentCollector.h
+++ b/src/lib/ABWContentCollector.h
@@ -26,7 +26,10 @@ enum ABWContext
{
ABW_SECTION,
ABW_HEADER,
- ABW_FOOTER
+ ABW_FOOTER,
+ ABW_FRAME_IMAGE,
+ ABW_FRAME_TEXTBOX,
+ ABW_FRAME_UNKNOWN
};
struct ABWStyle
@@ -70,6 +73,8 @@ struct ABWContentParsingState
bool m_isHeaderOpened;
bool m_isFooterOpened;
+ bool m_isPageFrame;
+
bool m_isSpanOpened;
bool m_isParagraphOpened;
bool m_isListElementOpened;
@@ -157,7 +162,8 @@ public:
void closeCell();
void openFrame(const char *props, const char *imageId, const char *title, const char *alt);
- void closeFrame();
+ void closeFrame(ABWOutputElements *(&elements), bool &pageFrame);
+ void addFrameElements(ABWOutputElements &elements, bool pageFrame);
void addMetadataEntry(const char *name, const char *value);
diff --git a/src/lib/ABWOutputElements.cpp b/src/lib/ABWOutputElements.cpp
index 2307563..ddb94bf 100644
--- a/src/lib/ABWOutputElements.cpp
+++ b/src/lib/ABWOutputElements.cpp
@@ -187,6 +187,16 @@ public:
const OutputElementsMap_t *headers) const;
};
+class ABWCloseTextBoxElement : public ABWOutputElement
+{
+public:
+ ABWCloseTextBoxElement() {}
+ ~ABWCloseTextBoxElement() {}
+ void write(librevenge::RVNGTextInterface *iface,
+ const OutputElementsMap_t *footers,
+ const OutputElementsMap_t *headers) const;
+};
+
class ABWCloseUnorderedListLevelElement : public ABWOutputElement
{
public:
@@ -494,6 +504,19 @@ private:
librevenge::RVNGPropertyList m_propList;
};
+class ABWOpenTextBoxElement : public ABWOutputElement
+{
+public:
+ ABWOpenTextBoxElement(const librevenge::RVNGPropertyList &propList) :
+ m_propList(propList) {}
+ ~ABWOpenTextBoxElement() {}
+ void write(librevenge::RVNGTextInterface *iface,
+ const OutputElementsMap_t *footers,
+ const OutputElementsMap_t *headers) const;
+private:
+ librevenge::RVNGPropertyList m_propList;
+};
+
class ABWOpenUnorderedListLevelElement : public ABWOutputElement
{
public:
@@ -629,6 +652,14 @@ void libabw::ABWCloseTableRowElement::write(librevenge::RVNGTextInterface *iface
iface->closeTableRow();
}
+void libabw::ABWCloseTextBoxElement::write(librevenge::RVNGTextInterface *iface,
+ const OutputElementsMap_t *,
+ const OutputElementsMap_t *) const
+{
+ if (iface)
+ iface->closeTextBox();
+}
+
void libabw::ABWCloseUnorderedListLevelElement::write(librevenge::RVNGTextInterface *iface,
const OutputElementsMap_t *,
const OutputElementsMap_t *) const
@@ -843,6 +874,14 @@ void libabw::ABWOpenTableRowElement::write(librevenge::RVNGTextInterface *iface,
iface->openTableRow(m_propList);
}
+void libabw::ABWOpenTextBoxElement::write(librevenge::RVNGTextInterface *iface,
+ const OutputElementsMap_t *,
+ const OutputElementsMap_t *) const
+{
+ if (iface)
+ iface->openTextBox(m_propList);
+}
+
void libabw::ABWOpenUnorderedListLevelElement::write(librevenge::RVNGTextInterface *iface,
const OutputElementsMap_t *,
const OutputElementsMap_t *) const
@@ -863,6 +902,11 @@ libabw::ABWOutputElements::~ABWOutputElements()
{
}
+void libabw::ABWOutputElements::splice(ABWOutputElements &elements)
+{
+ m_bodyElements.splice(m_bodyElements.end(), elements.m_bodyElements);
+}
+
void libabw::ABWOutputElements::write(librevenge::RVNGTextInterface *iface) const
{
OutputElements_t::const_iterator iter;
@@ -962,6 +1006,12 @@ void libabw::ABWOutputElements::addCloseTableRow()
m_elements->push_back(make_unique<ABWCloseTableRowElement>());
}
+void libabw::ABWOutputElements::addCloseTextBox()
+{
+ if (m_elements)
+ m_elements->push_back(make_unique<ABWCloseTextBoxElement>());
+}
+
void libabw::ABWOutputElements::addCloseUnorderedListLevel()
{
if (m_elements)
@@ -1110,6 +1160,12 @@ void libabw::ABWOutputElements::addOpenTableRow(const librevenge::RVNGPropertyLi
m_elements->push_back(make_unique<ABWOpenTableRowElement>(propList));
}
+void libabw::ABWOutputElements::addOpenTextBox(const librevenge::RVNGPropertyList &propList)
+{
+ if (m_elements)
+ m_elements->push_back(make_unique<ABWOpenTextBoxElement>(propList));
+}
+
void libabw::ABWOutputElements::addOpenUnorderedListLevel(const librevenge::RVNGPropertyList &propList)
{
if (m_elements)
diff --git a/src/lib/ABWOutputElements.h b/src/lib/ABWOutputElements.h
index ef5d7d5..4286522 100644
--- a/src/lib/ABWOutputElements.h
+++ b/src/lib/ABWOutputElements.h
@@ -29,7 +29,7 @@ public:
ABWOutputElements();
virtual ~ABWOutputElements();
- void append(const ABWOutputElements &elements);
+ void splice(ABWOutputElements &elements);
void write(librevenge::RVNGTextInterface *iface) const;
void addCloseEndnote();
void addCloseFooter();
@@ -46,6 +46,7 @@ public:
void addCloseTable();
void addCloseTableCell();
void addCloseTableRow();
+ void addCloseTextBox();
void addCloseUnorderedListLevel();
void addInsertBinaryObject(const librevenge::RVNGPropertyList &propList);
void addInsertCoveredTableCell(const librevenge::RVNGPropertyList &propList);
@@ -71,6 +72,7 @@ public:
void addOpenTable(const librevenge::RVNGPropertyList &propList);
void addOpenTableCell(const librevenge::RVNGPropertyList &propList);
void addOpenTableRow(const librevenge::RVNGPropertyList &propList);
+ void addOpenTextBox(const librevenge::RVNGPropertyList &propList);
void addOpenUnorderedListLevel(const librevenge::RVNGPropertyList &propList);
void addStartDocument(const librevenge::RVNGPropertyList &propList);
bool empty() const
diff --git a/src/lib/ABWParser.cpp b/src/lib/ABWParser.cpp
index 13aad45..514fa3f 100644
--- a/src/lib/ABWParser.cpp
+++ b/src/lib/ABWParser.cpp
@@ -10,6 +10,8 @@
#include <string.h>
#include <set>
+#include <stack>
+#include <utility>
#include <libxml/xmlIO.h>
#include <libxml/xmlstring.h>
@@ -120,21 +122,36 @@ static void updateListElementIds(std::map<int, ABWListElement *> &listElements)
struct ABWParserState
{
ABWParserState();
+ ~ABWParserState();
+ std::map<int, int> m_tableSizes;
+ std::map<std::string, ABWData> m_data;
+ std::map<int, ABWListElement *> m_listElements;
bool m_inMetadata;
std::string m_currentMetadataKey;
+ bool m_inStyleParsing;
+ std::stack<std::unique_ptr<ABWCollector> > m_collectorStack;
};
ABWParserState::ABWParserState()
- : m_inMetadata(false)
+ : m_tableSizes()
+ , m_data()
+ , m_listElements()
+ , m_inMetadata(false)
, m_currentMetadataKey()
+ , m_inStyleParsing(false)
+ , m_collectorStack()
{
}
+ABWParserState::~ABWParserState()
+{
+ clearListElements(m_listElements);
+}
} // namespace libabw
libabw::ABWParser::ABWParser(librevenge::RVNGInputStream *input, librevenge::RVNGTextInterface *iface)
- : m_input(input), m_iface(iface), m_collector(0), m_state(new ABWParserState())
+ : m_input(input), m_iface(iface), m_collector(), m_state(new ABWParserState())
{
}
@@ -147,33 +164,23 @@ bool libabw::ABWParser::parse()
if (!m_input)
return false;
- std::map<int, ABWListElement *> listElements;
- bool ok=true;
try
{
- std::map<int, int> tableSizes;
- std::map<std::string, ABWData> data;
- ABWStylesCollector stylesCollector(tableSizes, data, listElements);
- m_collector = &stylesCollector;
+ m_collector.reset(new ABWStylesCollector(m_state->m_tableSizes, m_state->m_data, m_state->m_listElements));
m_input->seek(0, librevenge::RVNG_SEEK_SET);
+ m_state->m_inStyleParsing=true;
if (!processXmlDocument(m_input))
- {
- clearListElements(listElements);
return false;
- }
- updateListElementIds(listElements);
- ABWContentCollector contentCollector(m_iface, tableSizes, data, listElements);
- m_collector = &contentCollector;
+ updateListElementIds(m_state->m_listElements);
+ m_collector.reset(new ABWContentCollector(m_iface, m_state->m_tableSizes, m_state->m_data, m_state->m_listElements));
m_input->seek(0, librevenge::RVNG_SEEK_SET);
- if (!processXmlDocument(m_input))
- ok=false;
+ m_state->m_inStyleParsing=false;
+ return processXmlDocument(m_input) && m_state->m_collectorStack.empty();
}
catch (...)
{
- ok=false;
}
- clearListElements(listElements);
- return ok;
+ return false;
}
bool libabw::ABWParser::processXmlDocument(librevenge::RVNGInputStream *input)
@@ -352,7 +359,7 @@ void libabw::ABWParser::processXmlNode(xmlTextReaderPtr reader)
if (XML_READER_TYPE_ELEMENT == tokenType)
readFrame(reader);
if (XML_READER_TYPE_END_ELEMENT == tokenType || emptyToken > 0)
- m_collector->closeFrame();
+ readCloseFrame();
break;
default:
break;
@@ -390,14 +397,14 @@ int libabw::ABWParser::getElementToken(xmlTextReaderPtr reader)
void libabw::ABWParser::readAbiword(xmlTextReaderPtr reader)
{
- const ABWXMLString props = xmlTextReaderGetAttribute(reader, BAD_CAST("props"));
+ const ABWXMLString props = xmlTextReaderGetAttribute(reader, call_BAD_CAST_OnConst("props"));
if (m_collector)
m_collector->collectDocumentProperties(static_cast<const char *>(props));
}
void libabw::ABWParser::readM(xmlTextReaderPtr reader)
{
- const ABWXMLString key = xmlTextReaderGetAttribute(reader, BAD_CAST("key"));
+ const ABWXMLString key = xmlTextReaderGetAttribute(reader, call_BAD_CAST_OnConst("key"));
if (key)
m_state->m_currentMetadataKey = static_cast<const char *>(key);
}
@@ -661,12 +668,38 @@ void libabw::ABWParser::readImage(xmlTextReaderPtr reader)
void libabw::ABWParser::readFrame(xmlTextReaderPtr reader)
{
+ if (!m_collector)
+ return;
ABWXMLString props = xmlTextReaderGetAttribute(reader, call_BAD_CAST_OnConst("props"));
ABWXMLString imageId = xmlTextReaderGetAttribute(reader, call_BAD_CAST_OnConst("strux-image-dataid"));
ABWXMLString title = xmlTextReaderGetAttribute(reader, call_BAD_CAST_OnConst("title"));
ABWXMLString alt = xmlTextReaderGetAttribute(reader, call_BAD_CAST_OnConst("alt"));
- if (m_collector)
- m_collector->openFrame((const char *)props, (const char *) imageId, (const char *) title, (const char *) alt);
+ if (!m_state->m_inStyleParsing)
+ {
+ m_state->m_collectorStack.push(std::move(m_collector));
+ m_collector.reset(new ABWContentCollector(m_iface, m_state->m_tableSizes, m_state->m_data, m_state->m_listElements));
+ }
+ m_collector->openFrame((const char *)props, (const char *) imageId, (const char *) title, (const char *) alt);
+}
+
+void libabw::ABWParser::readCloseFrame()
+{
+ if (!m_collector)
+ return;
+ ABWOutputElements *elements=0;
+ bool pageFrame=false;
+ m_collector->closeFrame(elements,pageFrame);
+ if (m_state->m_inStyleParsing)
+ return;
+ if (m_state->m_collectorStack.empty())
+ {
+ ABW_DEBUG_MSG(("libabw::ABWParser::readCloseFrame: oops, the collector stack is empty\n"));
+ return; // throw ?
+ }
+ if (elements)
+ m_state->m_collectorStack.top()->addFrameElements(*elements, pageFrame);
+ m_collector.swap(m_state->m_collectorStack.top());
+ m_state->m_collectorStack.pop();
}
void libabw::ABWParser::readL(xmlTextReaderPtr reader)
diff --git a/src/lib/ABWParser.h b/src/lib/ABWParser.h
index adf7d4b..6b9907d 100644
--- a/src/lib/ABWParser.h
+++ b/src/lib/ABWParser.h
@@ -64,10 +64,11 @@ private:
void readCell(xmlTextReaderPtr reader);
void readFrame(xmlTextReaderPtr reader);
+ void readCloseFrame();
librevenge::RVNGInputStream *m_input;
librevenge::RVNGTextInterface *m_iface;
- ABWCollector *m_collector;
+ std::unique_ptr<ABWCollector> m_collector;
std::unique_ptr<ABWParserState> m_state;
};
diff --git a/src/lib/ABWStylesCollector.h b/src/lib/ABWStylesCollector.h
index 4fa76b5..dfcb684 100644
--- a/src/lib/ABWStylesCollector.h
+++ b/src/lib/ABWStylesCollector.h
@@ -88,7 +88,11 @@ public:
void closeCell();
void openFrame(const char *, const char *, const char *, const char *) {}
- void closeFrame() {}
+ void closeFrame(ABWOutputElements *(&elements), bool &)
+ {
+ elements=0;
+ }
+ void addFrameElements(ABWOutputElements &, bool) {}
void addMetadataEntry(const char *, const char *) {}