diff options
author | osnola <alonso.laurent@gmail.com> | 2017-04-19 14:49:12 +0200 |
---|---|---|
committer | David Tardon <dtardon@redhat.com> | 2017-04-19 14:49:12 +0200 |
commit | 57f11c3ced46dcd25f670ae889ba4e37ff3f184a (patch) | |
tree | ae0e1bbe0b593f79862b382b9da3d617c812150d | |
parent | b9044ff16623db8c3651ee3d3055bca206c5aa9e (diff) |
retrieve textbox frames
Change-Id: I3b6f4b8186feedfb9932098305f99a40a72a5726
-rw-r--r-- | src/lib/ABWCollector.h | 4 | ||||
-rw-r--r-- | src/lib/ABWContentCollector.cpp | 224 | ||||
-rw-r--r-- | src/lib/ABWContentCollector.h | 10 | ||||
-rw-r--r-- | src/lib/ABWOutputElements.cpp | 56 | ||||
-rw-r--r-- | src/lib/ABWOutputElements.h | 4 | ||||
-rw-r--r-- | src/lib/ABWParser.cpp | 81 | ||||
-rw-r--r-- | src/lib/ABWParser.h | 3 | ||||
-rw-r--r-- | src/lib/ABWStylesCollector.h | 6 |
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 *) {} |