diff options
author | ALONSO Laurent <laurent.alonso@inria.fr> | 2021-09-08 09:44:10 +0200 |
---|---|---|
committer | ALONSO Laurent <laurent.alonso@inria.fr> | 2021-09-08 09:44:10 +0200 |
commit | e3401ce8b6d952304b0079d16c408dd4aa86a596 (patch) | |
tree | f6a454ee80900148dd23597fb7ee198bc5022ce4 | |
parent | 085e849894b9e78134cc9728c451158b13d5c9ed (diff) |
iwa: try to retrieve some cap drop's style, to be improved...
Change-Id: Ia51f7a357b7f80eb716e9506a5c7d0757b7f453e
-rw-r--r-- | src/lib/IWAParser.cpp | 55 | ||||
-rw-r--r-- | src/lib/IWAParser.h | 2 | ||||
-rw-r--r-- | src/lib/IWAText.cpp | 37 | ||||
-rw-r--r-- | src/lib/IWORKProperties.h | 2 | ||||
-rw-r--r-- | src/lib/IWORKText.cpp | 21 | ||||
-rw-r--r-- | src/lib/IWORKTypes.cpp | 2 | ||||
-rw-r--r-- | src/lib/IWORKTypes.h | 2 | ||||
-rw-r--r-- | src/lib/IWORKTypes_fwd.h | 3 |
8 files changed, 76 insertions, 48 deletions
diff --git a/src/lib/IWAParser.cpp b/src/lib/IWAParser.cpp index a161bd2..6de5fe7 100644 --- a/src/lib/IWAParser.cpp +++ b/src/lib/IWAParser.cpp @@ -558,6 +558,26 @@ void IWAParser::readPadding(const IWAMessage &msg, IWORKPadding &padding) padding.m_bottom = msg.float_(4).optional(); } +void IWAParser::readDropCap(const IWAMessage &msg, IWORKDropCap &cap) +{ + using namespace property; + if (msg.message(1)) + { + auto const &capMsg=get(msg.message(1)); + + if (capMsg.uint32(2)) + cap.m_numLines=get(capMsg.uint32(2)); + if (capMsg.uint32(3)) + cap.m_numLinesSpan=get(capMsg.uint32(3)); + if (capMsg.uint32(10)) + cap.m_numCharacters=get(capMsg.uint32(10)); + if (capMsg.double_(11)) + cap.m_decalParagraphLeft=get(capMsg.double_(11)); + if (capMsg.double_(12)) + cap.m_supplementalSpace=get(capMsg.double_(12)); + } +} + bool IWAParser::dispatchShape(const unsigned id) { const ObjectMessage msg(*this, id); @@ -1641,12 +1661,20 @@ void IWAParser::parseDropCapStyle(unsigned id, IWORKStylePtr_t &style) if (parentRef) parent = queryDropCapStyle(get(parentRef)); } - IWORKPropertyMap props; + IWORKDropCap cap; + if (parent && parent->has<property::DropCap>()) + cap=parent->get<property::DropCap>(); if (get(msg).message(11)) + { + IWORKPropertyMap props; parseCharacterProperties(get(get(msg).message(11)), props); + cap.m_style=std::make_shared<IWORKStyle>(props, boost::none, cap.m_style); + } if (get(msg).message(12)) - parseDropCapProperties(get(get(msg).message(12)), props); + readDropCap(get(get(msg).message(12)), cap); + IWORKPropertyMap props; + props.put<property::DropCap>(cap); style = std::make_shared<IWORKStyle>(props, name, parent); } @@ -2273,29 +2301,6 @@ void IWAParser::parseColumnsProperties(const IWAMessage &msg, IWORKPropertyMap & } } -void IWAParser::parseDropCapProperties(const IWAMessage &msg, IWORKPropertyMap &props) -{ - using namespace property; - if (msg.message(1)) - { - auto const &capMsg=get(msg.message(1)); - - auto caps=std::make_shared<IWORKDropCap>(); - if (capMsg.uint32(2)) - caps->m_numLines=get(capMsg.uint32(2)); - if (capMsg.uint32(3)) - caps->m_numLinesSpan=get(capMsg.uint32(3)); - if (capMsg.uint32(10)) - caps->m_numCharacters=get(capMsg.uint32(10)); - if (capMsg.double_(11)) - caps->m_decalParagraphLeft=get(capMsg.double_(11)); - if (capMsg.double_(12)) - caps->m_supplementalSpace=get(capMsg.double_(12)); - - props.put<property::DropCap>(caps); - } -} - void IWAParser::parsePageMaster(unsigned id, PageMaster &pageMaster) { const ObjectMessage msg(*this, id, IWAObjectType::PageMaster); diff --git a/src/lib/IWAParser.h b/src/lib/IWAParser.h index bd4db5a..ecc591a 100644 --- a/src/lib/IWAParser.h +++ b/src/lib/IWAParser.h @@ -103,6 +103,7 @@ protected: static void readGradient(const IWAMessage &msg, IWORKGradient &gradient); static void readShadow(const IWAMessage &msg, IWORKShadow &shadow); static void readPadding(const IWAMessage &msg, IWORKPadding &padding); + static void readDropCap(const IWAMessage &msg, IWORKDropCap &cap); bool dispatchShape(unsigned id); bool dispatchShapeWithMessage(const IWAMessage &msg, unsigned type); @@ -243,7 +244,6 @@ private: bool parseArrowProperties(const IWAMessage &msg, IWORKPropertyMap &props, bool headArrow); void parseCharacterProperties(const IWAMessage &msg, IWORKPropertyMap &props); void parseColumnsProperties(const IWAMessage &msg, IWORKPropertyMap &props); - void parseDropCapProperties(const IWAMessage &msg, IWORKPropertyMap &props); private: IWORKCollector &m_collector; diff --git a/src/lib/IWAText.cpp b/src/lib/IWAText.cpp index 529c59b..3bf2a60 100644 --- a/src/lib/IWAText.cpp +++ b/src/lib/IWAText.cpp @@ -123,6 +123,12 @@ void IWAText::parse(IWORKText &collector, const std::function<void(unsigned, IWO bool isLink = false; string curText; + // to handle drop cap's style, we need to set the drop cap style at + // the beginning of a pararagraph, and then reset the current style + // at the end of the drop cap's letters + IWORKStylePtr_t lastSpanStyle; + boost::optional<std::size_t> endDropCapPos; + std::size_t pos = 0; librevenge::RVNGString::Iter iter(m_text); iter.rewind(); @@ -148,9 +154,10 @@ void IWAText::parse(IWORKText &collector, const std::function<void(unsigned, IWO IWORKStylePtr_t dropCapStyle; bool spanChanged = false; bool langChanged = false; + bool isEndDropCap = bool(endDropCapPos) && get(endDropCapPos)==pos; if ((spanIt != m_spans.end()) && (spanIt->first == pos)) { - spanStyle = spanIt->second; + lastSpanStyle = spanStyle = spanIt->second; spanChanged = true; ++spanIt; } @@ -173,13 +180,16 @@ void IWAText::parse(IWORKText &collector, const std::function<void(unsigned, IWO langChanged = true; ++langIt; } - if (spanChanged || langChanged) + if (spanChanged || langChanged || isEndDropCap) { flushText(curText, collector); if (pos != 0) collector.flushSpan(); - if (spanChanged) - collector.setSpanStyle(spanStyle); + if (spanChanged || isEndDropCap) + { + collector.setSpanStyle(spanChanged ? spanStyle : lastSpanStyle); + endDropCapPos.reset(); + } if (langChanged) collector.setLanguage(langStyle); } @@ -211,9 +221,14 @@ void IWAText::parse(IWORKText &collector, const std::function<void(unsigned, IWO { if (dropCapStyle && dropCapStyle->has<property::DropCap>()) { - // changeme: we must also use the capital's character style + auto const &dropCap=dropCapStyle->get<property::DropCap>(); + if (!dropCap.empty() && dropCap.m_style) + { + collector.setSpanStyle(dropCap.m_style); + endDropCapPos=pos+dropCap.m_numCharacters; + } IWORKPropertyMap props; - props.put<property::DropCap>(dropCapStyle->get<property::DropCap>()); + props.put<property::DropCap>(dropCap); collector.setParagraphStyle(std::make_shared<IWORKStyle>(props, boost::none, paraIt->second)); } else @@ -247,6 +262,16 @@ void IWAText::parse(IWORKText &collector, const std::function<void(unsigned, IWO continue; // handle text const char *const u8Char = iter(); + + if (unsigned(u8Char[0])<=0x1f && bool(endDropCapPos)) + { + // a special character, better to force a span style reset + flushText(curText, collector); + collector.flushSpan(); + collector.setSpanStyle(lastSpanStyle); + endDropCapPos.reset(); + } + switch (u8Char[0]) { case char(4): // new section(ok) diff --git a/src/lib/IWORKProperties.h b/src/lib/IWORKProperties.h index bccb0a3..87285bd 100644 --- a/src/lib/IWORKProperties.h +++ b/src/lib/IWORKProperties.h @@ -26,7 +26,7 @@ IWORK_DECLARE_PROPERTY(Bold, bool); IWORK_DECLARE_PROPERTY(BottomBorder, IWORKStroke); IWORK_DECLARE_PROPERTY(Capitalization, IWORKCapitalization); IWORK_DECLARE_PROPERTY(Columns, IWORKColumns); -IWORK_DECLARE_PROPERTY(DropCap, IWORKDropCapPtr_t); +IWORK_DECLARE_PROPERTY(DropCap, IWORKDropCap); IWORK_DECLARE_PROPERTY(ExternalTextWrap, IWORKExternalTextWrap); IWORK_DECLARE_PROPERTY(EvenPageMaster, IWORKPageMaster); IWORK_DECLARE_PROPERTY(Fill, IWORKFill); diff --git a/src/lib/IWORKText.cpp b/src/lib/IWORKText.cpp index 4edbc19..4f81cc1 100644 --- a/src/lib/IWORKText.cpp +++ b/src/lib/IWORKText.cpp @@ -289,19 +289,16 @@ void fillParaPropList(const IWORKStyleStack &styleStack, RVNGPropertyList &props break; } } - if (styleStack.has<DropCap>() && styleStack.get<DropCap>()) + if (styleStack.has<DropCap>() && !styleStack.get<DropCap>().empty()) { - auto const &dropCap=*styleStack.get<DropCap>(); - if (!dropCap.empty()) - { - librevenge::RVNGPropertyList cap; - cap.insert("style:distance", dropCap.m_supplementalSpace, librevenge::RVNG_POINT); - cap.insert("style:length", int(dropCap.m_numCharacters)); - cap.insert("style:lines", int(dropCap.m_numLines)); - librevenge::RVNGPropertyListVector capVector; - capVector.append(cap); - props.insert("style:drop-cap", capVector); - } + auto const &dropCap=styleStack.get<DropCap>(); + librevenge::RVNGPropertyList cap; + cap.insert("style:distance", dropCap.m_supplementalSpace, librevenge::RVNG_POINT); + cap.insert("style:length", int(dropCap.m_numCharacters)); + cap.insert("style:lines", int(dropCap.m_numLines)); + librevenge::RVNGPropertyListVector capVector; + capVector.append(cap); + props.insert("style:drop-cap", capVector); } } diff --git a/src/lib/IWORKTypes.cpp b/src/lib/IWORKTypes.cpp index d2fbfbb..c4bd5e3 100644 --- a/src/lib/IWORKTypes.cpp +++ b/src/lib/IWORKTypes.cpp @@ -249,6 +249,8 @@ IWORKDropCap::IWORKDropCap() , m_decalParagraphLeft(0) , m_supplementalSpace(0) + + , m_style() { } diff --git a/src/lib/IWORKTypes.h b/src/lib/IWORKTypes.h index 603ca14..ed0d5cd 100644 --- a/src/lib/IWORKTypes.h +++ b/src/lib/IWORKTypes.h @@ -323,6 +323,8 @@ struct IWORKDropCap double m_decalParagraphLeft; // in percent, this decals the left position of the text double m_supplementalSpace; // extra space between the drop cap and the text + + IWORKStylePtr_t m_style; // the caps style (if known) }; struct IWORKShadow diff --git a/src/lib/IWORKTypes_fwd.h b/src/lib/IWORKTypes_fwd.h index 9484bf5..e5fa9a9 100644 --- a/src/lib/IWORKTypes_fwd.h +++ b/src/lib/IWORKTypes_fwd.h @@ -83,9 +83,6 @@ class IWORKTable; typedef std::shared_ptr<IWORKTable> IWORKTablePtr_t; typedef std::unordered_map<ID_t, IWORKTablePtr_t> IWORKTableMap_t; -struct IWORKDropCap; - -typedef std::shared_ptr<IWORKDropCap> IWORKDropCapPtr_t; } #endif // IWORKTYPES_FWD_H_INCLUDED |