summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrennan Vincent <brennanv@email.arizona.edu>2012-08-14 20:58:20 -0700
committerBrennan Vincent <brennanv@email.arizona.edu>2012-08-14 20:58:20 -0700
commitb01c8df7fd5ed062c246c71e77b960e68cbcc531 (patch)
tree941275824b23b7ab8c64da6a8b687c551c3413ff
parent9c42ea0a2557f22f930fe994692a2541e7ef7750 (diff)
pub2k2+: improve handling of default paragraph styles (fixes spacing issues in TS030002173.pub)
-rw-r--r--src/lib/MSPUBCollector.cpp51
-rw-r--r--src/lib/MSPUBCollector.h4
-rw-r--r--src/lib/MSPUBParser.cpp43
-rw-r--r--src/lib/MSPUBTypes.h39
4 files changed, 80 insertions, 57 deletions
diff --git a/src/lib/MSPUBCollector.cpp b/src/lib/MSPUBCollector.cpp
index ab7441b..8c8d28b 100644
--- a/src/lib/MSPUBCollector.cpp
+++ b/src/lib/MSPUBCollector.cpp
@@ -739,14 +739,14 @@ boost::function<void(void)> libmspub::MSPUBCollector::paintShape(const ShapeInfo
m_painter->startTextObject(props, WPXPropertyListVector());
for (unsigned i_lines = 0; i_lines < text.size(); ++i_lines)
{
- WPXPropertyList paraProps = getParaStyleProps(text[i_lines].style, text[i_lines].style.defaultCharStyleIndex);
+ WPXPropertyList paraProps = getParaStyleProps(text[i_lines].style, text[i_lines].style.m_defaultCharStyleIndex);
m_painter->startTextLine(paraProps);
for (unsigned i_spans = 0; i_spans < text[i_lines].spans.size(); ++i_spans)
{
WPXString textString;
appendCharacters(textString, text[i_lines].spans[i_spans].chars,
m_encoding.get_value_or(UTF_16));
- WPXPropertyList charProps = getCharStyleProps(text[i_lines].spans[i_spans].style, text[i_lines].style.defaultCharStyleIndex);
+ WPXPropertyList charProps = getCharStyleProps(text[i_lines].spans[i_spans].style, text[i_lines].style.m_defaultCharStyleIndex);
m_painter->startTextSpan(charProps);
m_painter->insertText(textString);
m_painter->endTextSpan();
@@ -989,12 +989,13 @@ void libmspub::MSPUBCollector::addFont(std::vector<unsigned char> name)
m_fonts.push_back(name);
}
-WPXPropertyList libmspub::MSPUBCollector::getParaStyleProps(const ParagraphStyle &style, unsigned defaultParaStyleIndex) const
+WPXPropertyList libmspub::MSPUBCollector::getParaStyleProps(const ParagraphStyle &style, boost::optional<unsigned> defaultParaStyleIndex) const
{
ParagraphStyle _nothing;
- const ParagraphStyle &defaultParaStyle = defaultParaStyleIndex < m_defaultParaStyles.size() ? m_defaultParaStyles[defaultParaStyleIndex] : _nothing;
+ const ParagraphStyle &defaultStyle = defaultParaStyleIndex.is_initialized() && defaultParaStyleIndex.get() < m_defaultParaStyles.size() ? m_defaultParaStyles[defaultParaStyleIndex.get()] : _nothing;
WPXPropertyList ret;
- Alignment align = style.align >= 0 ? style.align : defaultParaStyle.align;
+ Alignment align = style.m_align.get_value_or(
+ defaultStyle.m_align.get_value_or(LEFT));
switch (align)
{
case RIGHT:
@@ -1011,8 +1012,10 @@ WPXPropertyList libmspub::MSPUBCollector::getParaStyleProps(const ParagraphStyle
ret.insert("fo:text-align", "left");
break;
}
- double lineSpacing = style.lineSpacing;
- LineSpacingType lineSpacingType = style.lineSpacingType;
+ LineSpacingInfo info = style.m_lineSpacing.get_value_or(
+ defaultStyle.m_lineSpacing.get_value_or(LineSpacingInfo()));
+ LineSpacingType lineSpacingType = info.m_type;
+ double lineSpacing = info.m_amount;
if (!(lineSpacingType == LINE_SPACING_SP && lineSpacing == 1))
{
if (lineSpacingType == LINE_SPACING_SP)
@@ -1024,33 +1027,43 @@ WPXPropertyList libmspub::MSPUBCollector::getParaStyleProps(const ParagraphStyle
ret.insert("fo:line-height", lineSpacing, WPX_POINT);
}
}
- if (style.spaceAfterEmu != 0)
+ unsigned spaceAfterEmu = style.m_spaceAfterEmu.get_value_or(
+ defaultStyle.m_spaceAfterEmu.get_value_or(0));
+ unsigned spaceBeforeEmu = style.m_spaceBeforeEmu.get_value_or(
+ defaultStyle.m_spaceBeforeEmu.get_value_or(0));
+ unsigned firstLineIndentEmu = style.m_firstLineIndentEmu.get_value_or(
+ defaultStyle.m_firstLineIndentEmu.get_value_or(0));
+ unsigned leftIndentEmu = style.m_leftIndentEmu.get_value_or(
+ defaultStyle.m_leftIndentEmu.get_value_or(0));
+ unsigned rightIndentEmu = style.m_rightIndentEmu.get_value_or(
+ defaultStyle.m_rightIndentEmu.get_value_or(0));
+ if (spaceAfterEmu != 0)
{
- ret.insert("fo:margin-bottom", (double)style.spaceAfterEmu / EMUS_IN_INCH);
+ ret.insert("fo:margin-bottom", (double)spaceAfterEmu / EMUS_IN_INCH);
}
- if (style.spaceBeforeEmu != 0)
+ if (spaceBeforeEmu != 0)
{
- ret.insert("fo:margin-top", (double)style.spaceBeforeEmu / EMUS_IN_INCH);
+ ret.insert("fo:margin-top", (double)spaceBeforeEmu / EMUS_IN_INCH);
}
- if (style.firstLineIndentEmu != 0)
+ if (firstLineIndentEmu != 0)
{
- ret.insert("fo:text-indent", (double)style.firstLineIndentEmu / EMUS_IN_INCH);
+ ret.insert("fo:text-indent", (double)firstLineIndentEmu / EMUS_IN_INCH);
}
- if (style.leftIndentEmu != 0)
+ if (leftIndentEmu != 0)
{
- ret.insert("fo:margin-left", (double)style.leftIndentEmu / EMUS_IN_INCH);
+ ret.insert("fo:margin-left", (double)leftIndentEmu / EMUS_IN_INCH);
}
- if (style.rightIndentEmu != 0)
+ if (rightIndentEmu != 0)
{
- ret.insert("fo:margin-right", (double)style.rightIndentEmu / EMUS_IN_INCH);
+ ret.insert("fo:margin-right", (double)rightIndentEmu / EMUS_IN_INCH);
}
return ret;
}
-WPXPropertyList libmspub::MSPUBCollector::getCharStyleProps(const CharacterStyle &style, unsigned defaultCharStyleIndex) const
+WPXPropertyList libmspub::MSPUBCollector::getCharStyleProps(const CharacterStyle &style, boost::optional<unsigned> defaultCharStyleIndex) const
{
CharacterStyle _nothing = CharacterStyle(false, false, false);
- const CharacterStyle &defaultCharStyle = defaultCharStyleIndex < m_defaultCharStyles.size() ? m_defaultCharStyles[defaultCharStyleIndex] : _nothing;
+ const CharacterStyle &defaultCharStyle = defaultCharStyleIndex.is_initialized() && defaultCharStyleIndex.get() < m_defaultCharStyles.size() ? m_defaultCharStyles[defaultCharStyleIndex.get()] : _nothing;
WPXPropertyList ret;
if (style.italic ^ defaultCharStyle.italic)
{
diff --git a/src/lib/MSPUBCollector.h b/src/lib/MSPUBCollector.h
index 93edcb1..9b90905 100644
--- a/src/lib/MSPUBCollector.h
+++ b/src/lib/MSPUBCollector.h
@@ -197,8 +197,8 @@ private:
boost::function<void(void)> paintShape(const ShapeInfo &info, const Coordinate &relativeTo, const VectorTransformation2D &foldedTransform, bool isGroup, const VectorTransformation2D &thisTransform) const;
double getCalculationValue(const ShapeInfo &info, unsigned index, bool recursiveEntry, const std::vector<int> &adjustValues) const;
- WPXPropertyList getCharStyleProps(const CharacterStyle &, unsigned defaultCharStyleIndex) const;
- WPXPropertyList getParaStyleProps(const ParagraphStyle &, unsigned defaultParaStyleIndex) const;
+ WPXPropertyList getCharStyleProps(const CharacterStyle &, boost::optional<unsigned> defaultCharStyleIndex) const;
+ WPXPropertyList getParaStyleProps(const ParagraphStyle &, boost::optional<unsigned> defaultParaStyleIndex) const;
double getSpecialValue(const ShapeInfo &info, const CustomShape &shape, int arg, const std::vector<int> &adjustValues) const;
public:
static WPXString getColorString(const Color &);
diff --git a/src/lib/MSPUBParser.cpp b/src/lib/MSPUBParser.cpp
index 7f5953f..b3281cb 100644
--- a/src/lib/MSPUBParser.cpp
+++ b/src/lib/MSPUBParser.cpp
@@ -1083,20 +1083,14 @@ std::vector<libmspub::MSPUBParser::TextSpanReference> libmspub::MSPUBParser::par
}
libmspub::ParagraphStyle libmspub::MSPUBParser::getParagraphStyle(WPXInputStream *input)
{
- Alignment align = (Alignment)-1;
- double lineSpacing = 1;
- LineSpacingType lineSpacingType = LINE_SPACING_SP;
- unsigned defaultCharStyleIndex = 0;
- unsigned spaceBeforeEmu = 0;
- unsigned spaceAfterEmu = 0;
- int firstLineIndentEmu = 0;
- unsigned leftIndentEmu = 0;
- unsigned rightIndentEmu = 0;
+ ParagraphStyle ret;
+
bool isList = false;
uint32_t bulletChar = '\u0000';
NumberingType numberingType = STANDARD_WESTERN;
NumberingDelimiter numberingDelimiter = NO_DELIMITER;
boost::optional<unsigned> numberIfRestarted;
+
unsigned offset = input->tell();
unsigned len = readU32(input);
while (stillReading(input, offset + len))
@@ -1105,10 +1099,10 @@ libmspub::ParagraphStyle libmspub::MSPUBParser::getParagraphStyle(WPXInputStream
switch(info.id)
{
case PARAGRAPH_ALIGNMENT:
- align = (Alignment)(info.data & 0xFF); // Is this correct?
+ ret.m_align = (Alignment)(info.data & 0xFF); // Is this correct?
break;
case PARAGRAPH_DEFAULT_CHAR_STYLE:
- defaultCharStyleIndex = info.data;
+ ret.m_defaultCharStyleIndex = info.data;
break;
case PARAGRAPH_LINE_SPACING:
if (info.data & 1)
@@ -1116,32 +1110,32 @@ libmspub::ParagraphStyle libmspub::MSPUBParser::getParagraphStyle(WPXInputStream
// line spacing expressed in points in the UI,
// in eighths of an emu in the file format.
// (WTF??)
- lineSpacing = static_cast<double>(info.data - 1) / 8 * 72 / EMUS_IN_INCH;
- lineSpacingType = LINE_SPACING_PT;
+ ret.m_lineSpacing = LineSpacingInfo(LINE_SPACING_PT,
+ static_cast<double>(info.data - 1) / 8 * 72 / EMUS_IN_INCH);
}
else if (info.data & 2)
{
// line spacing expressed in SP in the UI,
// in what would be EMUs if font size were 96pt in the file format
// (WTF??)
- lineSpacing = static_cast<double>(info.data - 2) / EMUS_IN_INCH * 72 / 96;
- lineSpacingType = LINE_SPACING_SP;
+ ret.m_lineSpacing = LineSpacingInfo(LINE_SPACING_SP,
+ static_cast<double>(info.data - 2) / EMUS_IN_INCH * 72 / 96);
}
break;
case PARAGRAPH_SPACE_BEFORE:
- spaceBeforeEmu = info.data;
+ ret.m_spaceBeforeEmu = info.data;
break;
case PARAGRAPH_SPACE_AFTER:
- spaceAfterEmu = info.data;
+ ret.m_spaceAfterEmu = info.data;
break;
case PARAGRAPH_FIRST_LINE_INDENT:
- firstLineIndentEmu = (int)info.data;
+ ret.m_firstLineIndentEmu = (int)info.data;
break;
case PARAGRAPH_LEFT_INDENT:
- leftIndentEmu = info.data;
+ ret.m_leftIndentEmu = info.data;
break;
case PARAGRAPH_RIGHT_INDENT:
- rightIndentEmu = info.data;
+ ret.m_rightIndentEmu = info.data;
break;
case PARAGRAPH_LIST_INFO:
{
@@ -1171,21 +1165,20 @@ libmspub::ParagraphStyle libmspub::MSPUBParser::getParagraphStyle(WPXInputStream
break;
}
}
- boost::optional<ListInfo> listInfo;
if (isList)
{
if (bulletChar != '\u0000')
{
- listInfo = ListInfo(bulletChar);
+ ret.m_listInfo = ListInfo(bulletChar);
}
else
{
- listInfo = ListInfo(numberIfRestarted, numberingType,
+ ret.m_listInfo = ListInfo(numberIfRestarted, numberingType,
numberingDelimiter);
}
}
- return ParagraphStyle(align, defaultCharStyleIndex, lineSpacing, lineSpacingType, spaceBeforeEmu, spaceAfterEmu,
- firstLineIndentEmu, leftIndentEmu, rightIndentEmu, listInfo);
+
+ return ret;
}
libmspub::CharacterStyle libmspub::MSPUBParser::getCharacterStyle(WPXInputStream *input)
diff --git a/src/lib/MSPUBTypes.h b/src/lib/MSPUBTypes.h
index 4fffd1b..61e5b56 100644
--- a/src/lib/MSPUBTypes.h
+++ b/src/lib/MSPUBTypes.h
@@ -133,19 +133,36 @@ enum LineSpacingType
LINE_SPACING_PT
};
+struct LineSpacingInfo
+{
+ LineSpacingType m_type;
+ double m_amount;
+ LineSpacingInfo() : m_type(LINE_SPACING_SP), m_amount(1)
+ {
+ }
+ LineSpacingInfo(LineSpacingType type, double amount) :
+ m_type(type), m_amount(amount)
+ {
+ }
+};
+
struct ParagraphStyle
{
- ParagraphStyle(Alignment a = (Alignment)-1, unsigned dCSI = 0, double ls = 1, LineSpacingType lst = LINE_SPACING_SP, unsigned sb = 0, unsigned sa = 0, int fli = 0, unsigned li = 0, unsigned ri = 0, boost::optional<ListInfo> lInfo = boost::optional<ListInfo>()) : align(a), defaultCharStyleIndex(dCSI), lineSpacing(ls), lineSpacingType(lst), spaceBeforeEmu(sb), spaceAfterEmu(sa), firstLineIndentEmu(fli), leftIndentEmu(li), rightIndentEmu(ri), listInfo(lInfo) { }
- Alignment align;
- unsigned defaultCharStyleIndex;
- double lineSpacing;
- LineSpacingType lineSpacingType;
- unsigned spaceBeforeEmu;
- unsigned spaceAfterEmu;
- int firstLineIndentEmu;
- unsigned leftIndentEmu;
- unsigned rightIndentEmu;
- boost::optional<ListInfo> listInfo;
+ boost::optional<Alignment> m_align;
+ boost::optional<unsigned> m_defaultCharStyleIndex;
+ boost::optional<LineSpacingInfo> m_lineSpacing;
+ boost::optional<unsigned> m_spaceBeforeEmu;
+ boost::optional<unsigned> m_spaceAfterEmu;
+ boost::optional<int> m_firstLineIndentEmu;
+ boost::optional<unsigned> m_leftIndentEmu;
+ boost::optional<unsigned> m_rightIndentEmu;
+ boost::optional<ListInfo> m_listInfo;
+ ParagraphStyle() :
+ m_align(), m_defaultCharStyleIndex(), m_lineSpacing(), m_spaceBeforeEmu(),
+ m_spaceAfterEmu(), m_firstLineIndentEmu(), m_leftIndentEmu(),
+ m_rightIndentEmu(), m_listInfo()
+ {
+ }
};
struct TextSpan