diff options
author | Brennan Vincent <brennanv@email.arizona.edu> | 2012-08-14 20:58:20 -0700 |
---|---|---|
committer | Brennan Vincent <brennanv@email.arizona.edu> | 2012-08-14 20:58:20 -0700 |
commit | b01c8df7fd5ed062c246c71e77b960e68cbcc531 (patch) | |
tree | 941275824b23b7ab8c64da6a8b687c551c3413ff | |
parent | 9c42ea0a2557f22f930fe994692a2541e7ef7750 (diff) |
pub2k2+: improve handling of default paragraph styles (fixes spacing issues in TS030002173.pub)
-rw-r--r-- | src/lib/MSPUBCollector.cpp | 51 | ||||
-rw-r--r-- | src/lib/MSPUBCollector.h | 4 | ||||
-rw-r--r-- | src/lib/MSPUBParser.cpp | 43 | ||||
-rw-r--r-- | src/lib/MSPUBTypes.h | 39 |
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 |