summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorALONSO Laurent <laurent.alonso@inria.fr>2021-09-08 09:44:10 +0200
committerALONSO Laurent <laurent.alonso@inria.fr>2021-09-08 09:44:10 +0200
commite3401ce8b6d952304b0079d16c408dd4aa86a596 (patch)
treef6a454ee80900148dd23597fb7ee198bc5022ce4
parent085e849894b9e78134cc9728c451158b13d5c9ed (diff)
iwa: try to retrieve some cap drop's style, to be improved...
Change-Id: Ia51f7a357b7f80eb716e9506a5c7d0757b7f453e
-rw-r--r--src/lib/IWAParser.cpp55
-rw-r--r--src/lib/IWAParser.h2
-rw-r--r--src/lib/IWAText.cpp37
-rw-r--r--src/lib/IWORKProperties.h2
-rw-r--r--src/lib/IWORKText.cpp21
-rw-r--r--src/lib/IWORKTypes.cpp2
-rw-r--r--src/lib/IWORKTypes.h2
-rw-r--r--src/lib/IWORKTypes_fwd.h3
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