diff options
author | ALONSO Laurent <laurent.alonso@inria.fr> | 2021-09-07 11:24:25 +0200 |
---|---|---|
committer | ALONSO Laurent <laurent.alonso@inria.fr> | 2021-09-07 11:24:25 +0200 |
commit | 085e849894b9e78134cc9728c451158b13d5c9ed (patch) | |
tree | 5b03c85812be3a7ceddcb0a64bea6b62c36c626b | |
parent | 28612b413184ff0a7fd24c0556ff9b2f79fb22e6 (diff) |
IWA[pages]: try to recover cap drop, to be improved...
Change-Id: I45d9fd89c9f542cfb5768d0fa0ccbea61f908544
-rw-r--r-- | src/lib/IWAObjectType.h | 1 | ||||
-rw-r--r-- | src/lib/IWAParser.cpp | 72 | ||||
-rw-r--r-- | src/lib/IWAParser.h | 4 | ||||
-rw-r--r-- | src/lib/IWAText.cpp | 24 | ||||
-rw-r--r-- | src/lib/IWAText.h | 2 | ||||
-rw-r--r-- | src/lib/IWORKProperties.cpp | 1 | ||||
-rw-r--r-- | src/lib/IWORKProperties.h | 1 | ||||
-rw-r--r-- | src/lib/IWORKText.cpp | 14 | ||||
-rw-r--r-- | src/lib/IWORKTypes.cpp | 10 | ||||
-rw-r--r-- | src/lib/IWORKTypes.h | 16 | ||||
-rw-r--r-- | src/lib/IWORKTypes_fwd.h | 4 |
11 files changed, 146 insertions, 3 deletions
diff --git a/src/lib/IWAObjectType.h b/src/lib/IWAObjectType.h index 1f0d392..b1f74e4 100644 --- a/src/lib/IWAObjectType.h +++ b/src/lib/IWAObjectType.h @@ -60,6 +60,7 @@ enum PageMaster = 10011, PageMasterData = 10016, + DropCapStyle = 10024, HeadersAndFooters = 10143, MetaData = 11006, diff --git a/src/lib/IWAParser.cpp b/src/lib/IWAParser.cpp index a982cfe..a161bd2 100644 --- a/src/lib/IWAParser.cpp +++ b/src/lib/IWAParser.cpp @@ -172,6 +172,7 @@ IWAParser::IWAParser(const RVNGInputStreamPtr_t &fragments, const RVNGInputStrea , m_index(fragments, package) , m_visited() , m_charStyles() + , m_dropCapStyles() , m_paraStyles() , m_sectionStyles() , m_graphicStyles() @@ -671,6 +672,7 @@ bool IWAParser::parseText(const unsigned id, bool createNoteAsFootnote, const st } std::multimap<unsigned, std::function<void(unsigned, bool &)> > attachments; const IWAStringField &text = get(msg).string(3); + // fixme: in Numbers, if text does not exists, the default text string is still displayed if (text || (openPageFunction && get(msg).message(17))) { // special case, when the document is empty and openPageFunction is @@ -910,6 +912,20 @@ bool IWAParser::parseText(const unsigned id, bool createNoteAsFootnote, const st } textParser.setLanguages(langs); } + if (get(msg).message(28)) + { + map<unsigned, IWORKStylePtr_t> dropCaps; + for (const auto &it : get(msg).message(28).message(1)) + { + if (!it.uint32(1)) continue; + const optional<unsigned> &dropCapRef = readRef(it, 2); + if (!dropCapRef) continue; + const IWORKStylePtr_t &dropCapStyle = queryDropCapStyle(get(dropCapRef)); + if (dropCapStyle && dropCapStyle->has<property::DropCap>()) + dropCaps.insert(dropCaps.end(), make_pair(get(it.uint32(1)), dropCapStyle)); + } + textParser.setDropCaps(dropCaps); + } if (get(msg).message(23)) { for (const auto &it : get(msg).message(23).message(1)) @@ -948,7 +964,6 @@ bool IWAParser::parseText(const unsigned id, bool createNoteAsFootnote, const st textParser.setAttachments(attachments); textParser.parse(*m_currentText, openPageFunction); } - return true; } @@ -970,6 +985,11 @@ const IWORKStylePtr_t IWAParser::queryCharacterStyle(const unsigned id) const return queryStyle(id, m_charStyles, bind(&IWAParser::parseCharacterStyle, const_cast<IWAParser *>(this), _1, _2)); } +const IWORKStylePtr_t IWAParser::queryDropCapStyle(const unsigned id) const +{ + return queryStyle(id, m_dropCapStyles, bind(&IWAParser::parseDropCapStyle, const_cast<IWAParser *>(this), _1, _2)); +} + const IWORKStylePtr_t IWAParser::queryParagraphStyle(const unsigned id) const { return queryStyle(id, m_paraStyles, bind(&IWAParser::parseParagraphStyle, const_cast<IWAParser *>(this), _1, _2)); @@ -1606,6 +1626,30 @@ void IWAParser::parseCharacterStyle(const unsigned id, IWORKStylePtr_t &style) style = std::make_shared<IWORKStyle>(props, name, parent); } +void IWAParser::parseDropCapStyle(unsigned id, IWORKStylePtr_t &style) +{ + const ObjectMessage msg(*this, id, IWAObjectType::DropCapStyle); + if (!msg) + return; + optional<string> name; + IWORKStylePtr_t parent; + const IWAMessageField &styleInfo = get(msg).message(1); + if (styleInfo) + { + name = styleInfo.string(2).optional(); + const optional<unsigned> &parentRef = readRef(get(styleInfo), 3); + if (parentRef) + parent = queryDropCapStyle(get(parentRef)); + } + IWORKPropertyMap props; + if (get(msg).message(11)) + parseCharacterProperties(get(get(msg).message(11)), props); + if (get(msg).message(12)) + parseDropCapProperties(get(get(msg).message(12)), props); + + style = std::make_shared<IWORKStyle>(props, name, parent); +} + void IWAParser::parseParagraphStyle(const unsigned id, IWORKStylePtr_t &style) { const ObjectMessage msg(*this, id, IWAObjectType::ParagraphStyle); @@ -1676,6 +1720,7 @@ void IWAParser::parseParagraphStyle(const unsigned id, IWORKStylePtr_t &style) props.put<PageBreakBefore>(get(paraProps.bool_(14))); if (paraProps.uint32(15)) putEnum<ParagraphBorderType>(props, get(paraProps.uint32(15))); + // we need also to read the paragraphborder decal : field 17 if (paraProps.float_(19)) props.put<RightIndent>(get(paraProps.float_(19))); if (paraProps.float_(20)) @@ -2228,6 +2273,29 @@ 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); @@ -3058,7 +3126,7 @@ void IWAParser::parseTileDefinition(unsigned row, unsigned column, RVNGInputStre addPropsToCellStyle=true; props.put<property::SFTCellStylePropertyParagraphStyle>(paragraphStyle); } - /* TODO: when librevenge will allow to define cell styles, use conditionId */ + /* TODO: when librevenge will allow to define cell styles, check if conditionId is defined*/ if (addPropsToCellStyle) cellStyle.reset(new IWORKStyle(props, none, cellStyle)); optional<IWORKDateTimeData> dateTime; diff --git a/src/lib/IWAParser.h b/src/lib/IWAParser.h index 72ab293..bd4db5a 100644 --- a/src/lib/IWAParser.h +++ b/src/lib/IWAParser.h @@ -116,6 +116,7 @@ protected: void updateGeometryUsingTextRef(unsigned id, IWORKGeometry &geometry, unsigned flags); const IWORKStylePtr_t queryCharacterStyle(unsigned id) const; + const IWORKStylePtr_t queryDropCapStyle(unsigned id) const; const IWORKStylePtr_t queryParagraphStyle(unsigned id) const; const IWORKStylePtr_t querySectionStyle(unsigned id) const; @@ -205,6 +206,7 @@ private: void parseObjectIndex(); void parseCharacterStyle(unsigned id, IWORKStylePtr_t &style); + void parseDropCapStyle(unsigned id, IWORKStylePtr_t &style); void parseParagraphStyle(unsigned id, IWORKStylePtr_t &style); void parseSectionStyle(unsigned id, IWORKStylePtr_t &style); @@ -241,6 +243,7 @@ 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; @@ -250,6 +253,7 @@ private: std::deque<unsigned> m_visited; mutable StyleMap_t m_charStyles; + mutable StyleMap_t m_dropCapStyles; mutable StyleMap_t m_paraStyles; mutable StyleMap_t m_sectionStyles; diff --git a/src/lib/IWAText.cpp b/src/lib/IWAText.cpp index 23c0dda..529c59b 100644 --- a/src/lib/IWAText.cpp +++ b/src/lib/IWAText.cpp @@ -50,6 +50,7 @@ IWAText::IWAText(const std::string &text, IWORKLanguageManager &langManager) , m_links() , m_lists() , m_listLevels() + , m_dropCaps() , m_attachments() { @@ -95,6 +96,11 @@ void IWAText::setLists(const std::map<unsigned, IWORKStylePtr_t> &lists) m_lists = lists; } +void IWAText::setDropCaps(const std::map<unsigned, IWORKStylePtr_t> &dropCaps) +{ + m_dropCaps = dropCaps; +} + void IWAText::setAttachments(const std::multimap<unsigned, std::function<void(unsigned, bool &)> > &attachments) { m_attachments = attachments; @@ -105,6 +111,7 @@ void IWAText::parse(IWORKText &collector, const std::function<void(unsigned, IWO auto pageMasterIt = m_pageMasters.begin(); auto sectionIt = m_sections.begin(); map<unsigned, IWORKStylePtr_t>::const_iterator paraIt = m_paras.begin(); + map<unsigned, IWORKStylePtr_t>::const_iterator dropCapIt = m_dropCaps.begin(); map<unsigned, IWORKStylePtr_t>::const_iterator spanIt = m_spans.begin(); map<unsigned, string>::const_iterator langIt = m_langs.begin(); map<unsigned, string>::const_iterator linkIt = m_links.begin(); @@ -138,6 +145,7 @@ void IWAText::parse(IWORKText &collector, const std::function<void(unsigned, IWO // handle span style change IWORKStylePtr_t spanStyle; IWORKStylePtr_t langStyle; + IWORKStylePtr_t dropCapStyle; bool spanChanged = false; bool langChanged = false; if ((spanIt != m_spans.end()) && (spanIt->first == pos)) @@ -192,10 +200,24 @@ void IWAText::parse(IWORKText &collector, const std::function<void(unsigned, IWO ++linkIt; } + // handle list style change + if ((dropCapIt != m_dropCaps.end()) && (dropCapIt->first == pos)) + { + dropCapStyle=dropCapIt->second; + ++dropCapIt; + } // handle paragraph style change if ((paraIt != m_paras.end()) && (paraIt->first == pos)) { - collector.setParagraphStyle(paraIt->second); + if (dropCapStyle && dropCapStyle->has<property::DropCap>()) + { + // changeme: we must also use the capital's character style + IWORKPropertyMap props; + props.put<property::DropCap>(dropCapStyle->get<property::DropCap>()); + collector.setParagraphStyle(std::make_shared<IWORKStyle>(props, boost::none, paraIt->second)); + } + else + collector.setParagraphStyle(paraIt->second); ++paraIt; } diff --git a/src/lib/IWAText.h b/src/lib/IWAText.h index b1f2426..9678d3c 100644 --- a/src/lib/IWAText.h +++ b/src/lib/IWAText.h @@ -41,6 +41,7 @@ public: void setLinks(const std::map<unsigned, std::string> &links); void setListLevels(const std::map<unsigned, unsigned> &levels); void setLists(const std::map<unsigned, IWORKStylePtr_t> &lists); + void setDropCaps(const std::map<unsigned, IWORKStylePtr_t> &dropCaps); void setAttachments(const std::multimap<unsigned, std::function<void(unsigned, bool &)> > &attachments); @@ -59,6 +60,7 @@ private: std::map<unsigned, std::string> m_links; std::map<unsigned, IWORKStylePtr_t> m_lists; std::map<unsigned, unsigned> m_listLevels; + std::map<unsigned, IWORKStylePtr_t> m_dropCaps; std::multimap<unsigned, std::function<void(unsigned, bool &)> > m_attachments; }; diff --git a/src/lib/IWORKProperties.cpp b/src/lib/IWORKProperties.cpp index badbe17..6d876e9 100644 --- a/src/lib/IWORKProperties.cpp +++ b/src/lib/IWORKProperties.cpp @@ -19,6 +19,7 @@ IWORK_IMPLEMENT_PROPERTY(Bold); IWORK_IMPLEMENT_PROPERTY(BottomBorder); IWORK_IMPLEMENT_PROPERTY(Capitalization); IWORK_IMPLEMENT_PROPERTY(Columns); +IWORK_IMPLEMENT_PROPERTY(DropCap); IWORK_IMPLEMENT_PROPERTY(EvenPageMaster); IWORK_IMPLEMENT_PROPERTY(ExternalTextWrap); IWORK_IMPLEMENT_PROPERTY(Fill); diff --git a/src/lib/IWORKProperties.h b/src/lib/IWORKProperties.h index 34fb6e4..bccb0a3 100644 --- a/src/lib/IWORKProperties.h +++ b/src/lib/IWORKProperties.h @@ -26,6 +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(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 6f64ee8..4edbc19 100644 --- a/src/lib/IWORKText.cpp +++ b/src/lib/IWORKText.cpp @@ -289,6 +289,20 @@ void fillParaPropList(const IWORKStyleStack &styleStack, RVNGPropertyList &props break; } } + if (styleStack.has<DropCap>() && styleStack.get<DropCap>()) + { + 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); + } + } } struct FillListLabelProps : public boost::static_visitor<bool> diff --git a/src/lib/IWORKTypes.cpp b/src/lib/IWORKTypes.cpp index 89e15fd..d2fbfbb 100644 --- a/src/lib/IWORKTypes.cpp +++ b/src/lib/IWORKTypes.cpp @@ -242,6 +242,16 @@ IWORKGradient::IWORKGradient() { } +IWORKDropCap::IWORKDropCap() + : m_numLines(1) + , m_numLinesSpan(0) + , m_numCharacters(1) + + , m_decalParagraphLeft(0) + , m_supplementalSpace(0) +{ +} + IWORKShadow::IWORKShadow() : m_visible(true) , m_color() diff --git a/src/lib/IWORKTypes.h b/src/lib/IWORKTypes.h index 3e090b1..603ca14 100644 --- a/src/lib/IWORKTypes.h +++ b/src/lib/IWORKTypes.h @@ -309,6 +309,22 @@ typedef std::unordered_map<ID_t, IWORKGradient> IWORKGradientMap_t; typedef boost::variant<IWORKColor, IWORKGradient, IWORKMediaContent> IWORKFill; typedef std::unordered_map<ID_t, IWORKFill> IWORKFillMap_t; +struct IWORKDropCap +{ + IWORKDropCap(); + + bool empty() const + { + return m_numLines<=1 || m_numCharacters<=0; + } + unsigned m_numLines; + unsigned m_numLinesSpan; // the text begins with numLinesSpan empty lines + unsigned m_numCharacters; + + 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 +}; + struct IWORKShadow { IWORKShadow(); diff --git a/src/lib/IWORKTypes_fwd.h b/src/lib/IWORKTypes_fwd.h index 6271372..9484bf5 100644 --- a/src/lib/IWORKTypes_fwd.h +++ b/src/lib/IWORKTypes_fwd.h @@ -82,6 +82,10 @@ typedef std::shared_ptr<IWORKTableData> IWORKTableDataPtr_t; 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 |