diff options
author | Fridrich Štrba <fridrich.strba@bluewin.ch> | 2015-12-27 21:31:53 +0100 |
---|---|---|
committer | Fridrich Štrba <fridrich.strba@bluewin.ch> | 2015-12-27 21:31:53 +0100 |
commit | 24a9ae3175685a60079547bfdea65a4a4c7eabc4 (patch) | |
tree | d660a29c4c436c1258874360a3e703fd36f524d6 | |
parent | 1978e2d61843f70a3a6cc688074f7bd99d0fd718 (diff) |
Trying to simplify the _flushText function and make it a bit more readable
Change-Id: I5a94a699ecca68df7957bcd7506ed87ed2162f87
-rw-r--r-- | src/lib/VSDContentCollector.cpp | 318 | ||||
-rw-r--r-- | src/lib/VSDContentCollector.h | 2 |
2 files changed, 141 insertions, 179 deletions
diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp index e0cff20..17a6a38 100644 --- a/src/lib/VSDContentCollector.cpp +++ b/src/lib/VSDContentCollector.cpp @@ -53,8 +53,8 @@ libvisio::VSDContentCollector::VSDContentCollector( m_currentPageNumber(0), m_shapeOutputDrawing(0), m_shapeOutputText(0), m_pageOutputDrawing(), m_pageOutputText(), m_documentPageShapeOrders(documentPageShapeOrders), m_pageShapeOrder(m_documentPageShapeOrders.begin()), m_isFirstGeometry(true), m_NURBSData(), m_polylineData(), - m_textStream(), m_currentText(), m_names(), m_stencilNames(), m_fields(), m_stencilFields(), m_fieldIndex(0), - m_textFormat(VSD_TEXT_ANSI), m_charFormats(), m_paraFormats(), m_lineStyle(), m_fillStyle(), m_textBlockStyle(), + m_currentText(), m_names(), m_stencilNames(), m_fields(), m_stencilFields(), m_fieldIndex(0), + m_charFormats(), m_paraFormats(), m_lineStyle(), m_fillStyle(), m_textBlockStyle(), m_themeReference(), m_defaultCharStyle(), m_defaultParaStyle(), m_currentStyleSheet(0), m_styles(styles), m_stencils(stencils), m_stencilShape(0), m_isStencilStarted(false), m_currentGeometryCount(0), m_backgroundPageID(MINUS_ONE), m_currentPageID(0), m_currentPage(), m_pages(), m_layerList(), @@ -179,7 +179,7 @@ void libvisio::VSDContentCollector::_flushShape() numPathElements++; if (m_currentForeignData.size() && m_currentForeignProps["librevenge:mime-type"] && m_foreignWidth != 0.0 && m_foreignHeight != 0.0) numForeignElements++; - if (m_textStream.size()) + if (!m_currentText.empty()) numTextElements++; if (numPathElements+numForeignElements+numTextElements > 1) @@ -365,7 +365,7 @@ void libvisio::VSDContentCollector::_flushCurrentPath() void libvisio::VSDContentCollector::_flushText() { - if (!m_textStream.size() || m_misc.m_hideText) + if (m_currentText.empty() || m_misc.m_hideText) return; double xmiddle = m_txtxform ? m_txtxform->width / 2.0 : m_xform.width / 2.0; @@ -417,11 +417,22 @@ void libvisio::VSDContentCollector::_flushText() } if (m_charFormats.empty()) + { m_charFormats.push_back(m_defaultCharStyle); + m_charFormats.back().charCount = 0; + } if (m_paraFormats.empty()) + { m_paraFormats.push_back(m_defaultParaStyle); + m_paraFormats.back().charCount = 0; + } + if (m_tabSets.empty()) + { + m_tabSets.push_back(VSDTabSet()); + m_tabSets.back().m_numChars = 0; + } - unsigned numCharsInText = (unsigned)(m_textFormat == VSD_TEXT_UTF16 ? m_textStream.size() / 2 : m_textStream.size()); + unsigned numCharsInText = (unsigned)m_currentText.len(); for (unsigned iChar = 0; iChar < m_charFormats.size(); iChar++) { @@ -431,7 +442,7 @@ void libvisio::VSDContentCollector::_flushText() m_charFormats[iChar].charCount = numCharsInText; } - numCharsInText = (unsigned)(m_textFormat == VSD_TEXT_UTF16 ? m_textStream.size() / 2 : m_textStream.size()); + numCharsInText = (unsigned)m_currentText.len(); for (unsigned iPara = 0; iPara < m_paraFormats.size(); iPara++) { @@ -441,7 +452,7 @@ void libvisio::VSDContentCollector::_flushText() m_paraFormats[iPara].charCount = numCharsInText; } - numCharsInText = (unsigned)(m_textFormat == VSD_TEXT_UTF16 ? m_textStream.size() / 2 : m_textStream.size()); + numCharsInText = (unsigned)m_currentText.len(); for (unsigned iTab = 0; iTab < m_tabSets.size(); iTab++) { @@ -455,81 +466,62 @@ void libvisio::VSDContentCollector::_flushText() m_shapeOutputText->addStartTextObject(textBlockProps); - unsigned charIndex = 0; - unsigned tabIndex = 0; - unsigned paraCharCount = 0; - unsigned long textBufferPosition = 0; - const unsigned char *pTextBuffer = m_textStream.getDataBuffer(); - const unsigned long nTextBufferLength = m_textStream.size(); + bool isParagraphOpened(false); + bool isSpanOpened(false); - VSDBullet currentBullet; - - for (std::vector<VSDParaStyle>::iterator paraIt = m_paraFormats.begin(); - paraIt != m_paraFormats.end() && charIndex < m_charFormats.size(); ++paraIt) - { - librevenge::RVNGPropertyList paraProps; - _fillParagraphProperties(paraProps, *paraIt); + std::vector<VSDParaStyle>::const_iterator paraIt = m_paraFormats.begin(); + std::vector<VSDCharStyle>::const_iterator charIt = m_charFormats.begin(); + std::vector<VSDTabSet>::const_iterator tabIt = m_tabSets.begin(); - if (m_textBlockStyle.defaultTabStop > 0.0) - paraProps.insert("style:tab-stop-distance", m_textBlockStyle.defaultTabStop); + VSDBullet currentBullet; - paraCharCount = (*paraIt).charCount; + unsigned paraNumRemaining(paraIt->charCount); + unsigned charNumRemaining(charIt->charCount); + unsigned tabNumRemaining(tabIt->m_numChars); - if (!m_tabSets.empty()) + librevenge::RVNGString::Iter textIt(m_currentText); + librevenge::RVNGString sOutputText; + // Iterate over the text + for (textIt.rewind(); textIt.next();) + { + if (!isParagraphOpened) { - if (paraCharCount < m_tabSets[tabIndex].m_numChars) - { - // Insert duplicate - std::vector<VSDTabSet>::iterator tabIt = m_tabSets.begin() + tabIndex; - VSDTabSet tmpTabSet = m_tabSets[tabIndex]; - m_tabSets.insert(tabIt, tmpTabSet); - m_tabSets[tabIndex].m_numChars = paraCharCount; - m_tabSets[tabIndex+1].m_numChars -= paraCharCount; - } + librevenge::RVNGPropertyList paraProps; + _fillParagraphProperties(paraProps, *paraIt); - _fillTabSet(paraProps, m_tabSets[tabIndex]); - } + if (m_textBlockStyle.defaultTabStop > 0.0) + paraProps.insert("style:tab-stop-distance", m_textBlockStyle.defaultTabStop); - VSDBullet bullet; - _bulletFromParaFormat(bullet, *paraIt); + _fillTabSet(paraProps, *tabIt); - if (bullet != currentBullet) - { - if (!!currentBullet) - { - m_shapeOutputText->addCloseUnorderedListLevel(); - } + VSDBullet bullet; + _bulletFromParaFormat(bullet, *paraIt); - currentBullet = bullet; - if (!!bullet) + if (bullet != currentBullet) { - librevenge::RVNGPropertyList bulletList; - _listLevelFromBullet(bulletList, bullet); - m_shapeOutputText->addOpenUnorderedListLevel(bulletList); + if (!!currentBullet) + m_shapeOutputText->addCloseUnorderedListLevel(); + + currentBullet = bullet; + if (!!currentBullet) + { + librevenge::RVNGPropertyList bulletList; + _listLevelFromBullet(bulletList, currentBullet); + m_shapeOutputText->addOpenUnorderedListLevel(bulletList); + } } - } - if (!currentBullet) - m_shapeOutputText->addOpenParagraph(paraProps); - else - m_shapeOutputText->addOpenListElement(paraProps); + if (!currentBullet) + m_shapeOutputText->addOpenParagraph(paraProps); + else + m_shapeOutputText->addOpenListElement(paraProps); + isParagraphOpened = true; + } - // Find char format that overlaps - while (charIndex < m_charFormats.size() && paraCharCount) + if (!isSpanOpened && (*(textIt()) != '\n')) // Avoid an empty span { - if (paraCharCount < m_charFormats[charIndex].charCount) - { - // Insert duplicate - std::vector<VSDCharStyle>::iterator charIt = m_charFormats.begin() + charIndex; - VSDCharStyle tmpCharFormat = m_charFormats[charIndex]; - m_charFormats.insert(charIt, tmpCharFormat); - m_charFormats[charIndex].charCount = paraCharCount; - m_charFormats[charIndex+1].charCount -= paraCharCount; - } - paraCharCount -= m_charFormats[charIndex].charCount; - librevenge::RVNGPropertyList textProps; - _fillCharProperties(textProps, m_charFormats[charIndex]); + _fillCharProperties(textProps, *charIt); // TODO: In draw, text span background cannot be specified the same way as in writer span if (m_textBlockStyle.isTextBkgndFilled) @@ -540,139 +532,113 @@ void libvisio::VSDContentCollector::_flushText() textProps.insert("fo:background-opacity", 1.0 - m_textBlockStyle.textBkgndColour.a/255.0, librevenge::RVNG_PERCENT); #endif } + m_shapeOutputText->addOpenSpan(textProps); + isSpanOpened = true; + } - librevenge::RVNGString text; - - if (m_textFormat == VSD_TEXT_UTF16) - { - unsigned long max = m_charFormats[charIndex].charCount <= (m_textStream.size()/2) ? m_charFormats[charIndex].charCount : (m_textStream.size()/2); - VSD_DEBUG_MSG(("Charcount: %d, max: %lu, stream size: %lu\n", m_charFormats[charIndex].charCount, max, (unsigned long)m_textStream.size())); - max = (m_charFormats[charIndex].charCount == 0 && m_textStream.size()) ? m_textStream.size()/2 : max; - VSD_DEBUG_MSG(("Charcount: %d, max: %lu, stream size: %lu\n", m_charFormats[charIndex].charCount, max, (unsigned long)m_textStream.size())); - std::vector<unsigned char> tmpBuffer; - unsigned i = 0; - for (; i < max*2 && textBufferPosition+i <nTextBufferLength; ++i) - tmpBuffer.push_back(pTextBuffer[textBufferPosition+i]); - if (!paraCharCount && tmpBuffer.size() >= 2) - { - while (tmpBuffer.size() >= 2 && tmpBuffer[tmpBuffer.size() - 2] == 0 && tmpBuffer[tmpBuffer.size() - 1] == 0) - { - tmpBuffer.pop_back(); - tmpBuffer.pop_back(); - } - if (tmpBuffer.size() >= 2) - { - if (tmpBuffer[tmpBuffer.size() - 1] == 0 && (tmpBuffer[tmpBuffer.size() - 2] == 0x0a || - tmpBuffer[tmpBuffer.size() - 2] == '\n' || tmpBuffer[tmpBuffer.size() - 2] == 0x0e)) - { - tmpBuffer.pop_back(); - tmpBuffer.pop_back(); - } - } - else - tmpBuffer.clear(); - } - - if (!tmpBuffer.empty()) - appendCharacters(text, tmpBuffer); - textBufferPosition += i; - } - else if (m_textFormat == VSD_TEXT_UTF8) + if (*(textIt()) == '\n') + { + if (!sOutputText.empty()) + m_shapeOutputText->addInsertText(sOutputText); + sOutputText.clear(); + if (isSpanOpened) { - unsigned long max = m_charFormats[charIndex].charCount <= m_textStream.size() ? m_charFormats[charIndex].charCount : m_textStream.size(); - std::vector<unsigned char> tmpBuffer; - unsigned i = 0; - for (; i < max && textBufferPosition+i <nTextBufferLength; ++i) - tmpBuffer.push_back(pTextBuffer[textBufferPosition+i]); - if (!paraCharCount && !tmpBuffer.empty()) - { - while (!tmpBuffer.empty() && tmpBuffer.back() == 0) - tmpBuffer.pop_back(); - if (!tmpBuffer.empty() && (tmpBuffer.back() == 0x0a || tmpBuffer.back() == '\n' || tmpBuffer.back() == 0x0e)) - tmpBuffer.back() = 0; - } - if (!tmpBuffer.empty() && tmpBuffer[0]) - appendCharacters(text, tmpBuffer, VSD_TEXT_UTF8); - textBufferPosition += i; + m_shapeOutputText->addCloseSpan(); + isSpanOpened = false; } - else + + if (isParagraphOpened) { - unsigned long max = m_charFormats[charIndex].charCount <= m_textStream.size() ? m_charFormats[charIndex].charCount : m_textStream.size(); - max = (m_charFormats[charIndex].charCount == 0 && m_textStream.size()) ? m_textStream.size() : max; - std::vector<unsigned char> tmpBuffer; - unsigned i = 0; - for (; i < max && textBufferPosition+i <nTextBufferLength; ++i) - tmpBuffer.push_back(pTextBuffer[textBufferPosition+i]); - if (!paraCharCount && !tmpBuffer.empty()) - { - while (!tmpBuffer.empty() && tmpBuffer.back() == 0) - tmpBuffer.pop_back(); - if (!tmpBuffer.empty() && (tmpBuffer.back() == 0x0a || tmpBuffer.back() == '\n' || tmpBuffer.back() == 0x0e)) - tmpBuffer.back() = 0; - } - if (!tmpBuffer.empty()) - appendCharacters(text, tmpBuffer, m_charFormats[charIndex].font.m_format); - textBufferPosition += i; + if (!currentBullet) + m_shapeOutputText->addCloseParagraph(); + else + m_shapeOutputText->addCloseListElement(); + isParagraphOpened = false; } + } + else if (*(textIt()) == '\t') + { + if (!sOutputText.empty()) + m_shapeOutputText->addInsertText(sOutputText); + sOutputText.clear(); + m_shapeOutputText->addInsertTab(); + } + else if (strlen(textIt()) == 3 && + textIt()[0] == '\xef' && + textIt()[1] == '\xbf' && + textIt()[2] == '\xbc') + _appendField(sOutputText); + else + sOutputText.append(textIt()); - VSD_DEBUG_MSG(("Text: %s\n", text.cstr())); - m_shapeOutputText->addOpenSpan(textProps); + if (paraNumRemaining) + paraNumRemaining--; + if (!paraNumRemaining) + { + paraIt++; + if (paraIt != m_paraFormats.end()) + paraNumRemaining = paraIt->charCount; + else + paraIt--; + } - librevenge::RVNGString::Iter i(text); - i.rewind(); - librevenge::RVNGString sOutputText; - for (i.rewind(); i.next();) + if (charNumRemaining) + charNumRemaining--; + if (!charNumRemaining) + { + charIt++; + if (charIt != m_charFormats.end()) { - if (*(i()) == '\n') - { - m_shapeOutputText->addInsertText(sOutputText); - m_shapeOutputText->addCloseSpan(); - if (!currentBullet) - { - m_shapeOutputText->addCloseParagraph(); - m_shapeOutputText->addOpenParagraph(paraProps); - } - else - { - m_shapeOutputText->addCloseListElement(); - m_shapeOutputText->addOpenListElement(paraProps); - } - m_shapeOutputText->addOpenSpan(textProps); - sOutputText.clear(); - } - else if (*(i()) == '\t') + charNumRemaining = charIt->charCount; + if (isSpanOpened) { if (!sOutputText.empty()) m_shapeOutputText->addInsertText(sOutputText); - m_shapeOutputText->addInsertTab(); sOutputText.clear(); + m_shapeOutputText->addCloseSpan(); + isSpanOpened = false; } - else if (strlen(i()) == 3 && - i()[0] == (char)0xef && - i()[1] == (char)0xbf && - i()[2] == (char)0xbc) - _appendField(sOutputText); - else - sOutputText.append(i()); } + else + charIt--; + } - m_shapeOutputText->addInsertText(sOutputText); - m_shapeOutputText->addCloseSpan(); + if (tabNumRemaining) + tabNumRemaining--; + if (!tabNumRemaining) + { + tabIt++; + if (tabIt != m_tabSets.end()) + tabNumRemaining = tabIt->m_numChars; + else + --tabIt; + } + } - charIndex++; + // Clean up the elements that remained opened + if (isParagraphOpened) + { + if (isSpanOpened) + { + if (!sOutputText.empty()) + m_shapeOutputText->addInsertText(sOutputText); + sOutputText.clear(); + m_shapeOutputText->addCloseSpan(); + isSpanOpened = false; } + if (!currentBullet) m_shapeOutputText->addCloseParagraph(); else m_shapeOutputText->addCloseListElement(); - tabIndex++; + isParagraphOpened = false; } if (!!currentBullet) m_shapeOutputText->addCloseUnorderedListLevel(); m_shapeOutputText->addEndTextObject(); - m_textStream.clear(); + m_currentText.clear(); } void libvisio::VSDContentCollector::_fillCharProperties(librevenge::RVNGPropertyList &propList, const VSDCharStyle &style) @@ -2079,7 +2045,7 @@ void libvisio::VSDContentCollector::collectShape(unsigned id, unsigned level, un m_misc = VSDMisc(); // Save line colour and pattern, fill type and pattern - m_textStream.clear(); + m_currentText.clear(); m_charFormats.clear(); m_paraFormats.clear(); @@ -2222,10 +2188,8 @@ void libvisio::VSDContentCollector::collectText(unsigned level, const librevenge { _handleLevelChange(level); - m_textStream = textStream; - m_textFormat = format; m_currentText.clear(); - if (!m_textStream.empty()) + if (!textStream.empty()) { std::vector<unsigned char> tmpBuffer(textStream.size()); memcpy(&tmpBuffer[0], textStream.getDataBuffer(), textStream.size()); diff --git a/src/lib/VSDContentCollector.h b/src/lib/VSDContentCollector.h index c3aaff2..3497681 100644 --- a/src/lib/VSDContentCollector.h +++ b/src/lib/VSDContentCollector.h @@ -275,13 +275,11 @@ private: std::map<unsigned, NURBSData> m_NURBSData; std::map<unsigned, PolylineData> m_polylineData; - librevenge::RVNGBinaryData m_textStream; librevenge::RVNGString m_currentText; std::map<unsigned, librevenge::RVNGString> m_names, m_stencilNames; std::vector<librevenge::RVNGString> m_fields; VSDFieldList m_stencilFields; unsigned m_fieldIndex; - TextFormat m_textFormat; std::vector<VSDCharStyle> m_charFormats; std::vector<VSDParaStyle> m_paraFormats; |