summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorALONSO Laurent <laurent.alonso@inria.fr>2021-09-07 11:24:25 +0200
committerALONSO Laurent <laurent.alonso@inria.fr>2021-09-07 11:24:25 +0200
commit085e849894b9e78134cc9728c451158b13d5c9ed (patch)
tree5b03c85812be3a7ceddcb0a64bea6b62c36c626b
parent28612b413184ff0a7fd24c0556ff9b2f79fb22e6 (diff)
IWA[pages]: try to recover cap drop, to be improved...
Change-Id: I45d9fd89c9f542cfb5768d0fa0ccbea61f908544
-rw-r--r--src/lib/IWAObjectType.h1
-rw-r--r--src/lib/IWAParser.cpp72
-rw-r--r--src/lib/IWAParser.h4
-rw-r--r--src/lib/IWAText.cpp24
-rw-r--r--src/lib/IWAText.h2
-rw-r--r--src/lib/IWORKProperties.cpp1
-rw-r--r--src/lib/IWORKProperties.h1
-rw-r--r--src/lib/IWORKText.cpp14
-rw-r--r--src/lib/IWORKTypes.cpp10
-rw-r--r--src/lib/IWORKTypes.h16
-rw-r--r--src/lib/IWORKTypes_fwd.h4
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