From 49a558574f29c72733c951e1bf67ec4eabd8933b Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Thu, 26 Mar 2020 19:56:35 +0100 Subject: [PATCH] Hypertext: Fix alignment tags adding unwanted newlines (#9548) --- src/gui/guiHyperText.cpp | 33 ++++++++++++++++++++++++--------- src/gui/guiHyperText.h | 6 +++++- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/gui/guiHyperText.cpp b/src/gui/guiHyperText.cpp index 68fb8ea3d..482b74f04 100644 --- a/src/gui/guiHyperText.cpp +++ b/src/gui/guiHyperText.cpp @@ -167,6 +167,7 @@ ParsedText::ParsedText(const wchar_t *text) m_element = NULL; m_paragraph = NULL; + m_end_paragraph_reason = ER_NONE; parse(text); } @@ -191,7 +192,7 @@ void ParsedText::parse(const wchar_t *text) cursor++; // If text has begun, don't skip empty line if (m_paragraph) { - endParagraph(); + endParagraph(ER_NEWLINE); enterElement(ELEMENT_SEPARATOR); } escape = false; @@ -201,7 +202,7 @@ void ParsedText::parse(const wchar_t *text) if (c == L'\n') { // Unix breaks // If text has begun, don't skip empty line if (m_paragraph) { - endParagraph(); + endParagraph(ER_NEWLINE); enterElement(ELEMENT_SEPARATOR); } escape = false; @@ -232,7 +233,7 @@ void ParsedText::parse(const wchar_t *text) pushChar(c); } - endParagraph(); + endParagraph(ER_NONE); } void ParsedText::endElement() @@ -240,11 +241,20 @@ void ParsedText::endElement() m_element = NULL; } -void ParsedText::endParagraph() +void ParsedText::endParagraph(EndReason reason) { if (!m_paragraph) return; + EndReason previous = m_end_paragraph_reason; + m_end_paragraph_reason = reason; + if (m_empty_paragraph && (reason == ER_TAG || + (reason == ER_NEWLINE && previous == ER_TAG))) { + // Ignore last empty paragraph + m_paragraph = nullptr; + m_paragraphs.pop_back(); + return; + } endElement(); m_paragraph = NULL; } @@ -255,6 +265,7 @@ void ParsedText::enterParagraph() m_paragraphs.emplace_back(); m_paragraph = &m_paragraphs.back(); m_paragraph->setStyle(m_style); + m_empty_paragraph = true; } } @@ -274,11 +285,15 @@ void ParsedText::enterElement(ElementType type) void ParsedText::pushChar(wchar_t c) { // New word if needed - if (c == L' ' || c == L'\t') - enterElement(ELEMENT_SEPARATOR); - else + if (c == L' ' || c == L'\t') { + if (!m_empty_paragraph) + enterElement(ELEMENT_SEPARATOR); + else + return; + } else { + m_empty_paragraph = false; enterElement(ELEMENT_TEXT); - + } m_element->text += c; } @@ -571,7 +586,7 @@ u32 ParsedText::parseTag(const wchar_t *text, u32 cursor) } else { openTag(name, attrs)->style = m_paragraphtags[name]; } - endParagraph(); + endParagraph(ER_TAG); } else return 0; // Unknown tag diff --git a/src/gui/guiHyperText.h b/src/gui/guiHyperText.h index 093c84ccd..c55f8a705 100644 --- a/src/gui/guiHyperText.h +++ b/src/gui/guiHyperText.h @@ -134,11 +134,13 @@ public: Tag m_root_tag; protected: + typedef enum { ER_NONE, ER_TAG, ER_NEWLINE } EndReason; + // Parser functions void enterElement(ElementType type); void endElement(); void enterParagraph(); - void endParagraph(); + void endParagraph(EndReason reason); void pushChar(wchar_t c); ParsedText::Tag *newTag(const std::string &name, const AttrsList &attrs); ParsedText::Tag *openTag(const std::string &name, const AttrsList &attrs); @@ -160,6 +162,8 @@ protected: StyleList m_style; Element *m_element; Paragraph *m_paragraph; + bool m_empty_paragraph; + EndReason m_end_paragraph_reason; }; class TextDrawer