diff options
author | David Tardon <dtardon@redhat.com> | 2017-12-30 13:31:52 +0100 |
---|---|---|
committer | David Tardon <dtardon@redhat.com> | 2017-12-30 14:59:30 +0100 |
commit | 45832739afa9280d180d50b34041c4930eb7fd24 (patch) | |
tree | 7d4c5ec32dd95e6de3e8d03b3a9e9465efb6e678 | |
parent | 522860ad23e1aa368fe09885e7973fafc4d456e5 (diff) |
parse more text formatting properties
Change-Id: I25aef81ba5b3beaa57726d85b57c7acab79198d1
-rw-r--r-- | src/lib/MSPUBBlockID.h | 7 | ||||
-rw-r--r-- | src/lib/MSPUBCollector.cpp | 102 | ||||
-rw-r--r-- | src/lib/MSPUBParser.cpp | 89 | ||||
-rw-r--r-- | src/lib/MSPUBParser97.cpp | 24 | ||||
-rw-r--r-- | src/lib/MSPUBTypes.h | 44 |
5 files changed, 237 insertions, 29 deletions
diff --git a/src/lib/MSPUBBlockID.h b/src/lib/MSPUBBlockID.h index 4420e05..bf92664 100644 --- a/src/lib/MSPUBBlockID.h +++ b/src/lib/MSPUBBlockID.h @@ -35,6 +35,13 @@ enum MSPUBBlockID // Don't be alarmed by multiple elements with the same value; ITALIC_1_ID = 0x03, ITALIC_2_ID = 0x38, UNDERLINE_ID = 0x1E, + OUTLINE_ID = 0x4, + SHADOW_ID = 0x5, + SMALL_CAPS_ID = 0x13, + ALL_CAPS_ID = 0x14, + EMBOSS_ID = 0x16, + ENGRAVE_ID = 0x17, + SCALING_ID = 0x20, TEXT_SIZE_1_ID = 0x0C, TEXT_SIZE_2_ID = 0x39, COLOR_INDEX_CONTAINER_ID = 0x44, diff --git a/src/lib/MSPUBCollector.cpp b/src/lib/MSPUBCollector.cpp index dafe561..24c8d08 100644 --- a/src/lib/MSPUBCollector.cpp +++ b/src/lib/MSPUBCollector.cpp @@ -238,6 +238,82 @@ void mapTableTextToCells( assert(paraToCellMap.size() <= tableCellTextEnds.size()); } +void fillUnderline(librevenge::RVNGPropertyList &props, const Underline underline) +{ + switch (underline) + { + case Underline::None: + return; + case Underline::Single: + case Underline::WordsOnly: + case Underline::Double: + case Underline::Thick: + props.insert("style:text-underline-style", "solid"); + break; + case Underline::Dotted: + case Underline::ThickDot: + props.insert("style:text-underline-style", "dotted"); + break; + case Underline::Dash: + case Underline::ThickDash: + props.insert("style:text-underline-style", "dash"); + break; + case Underline::DotDash: + case Underline::ThickDotDash: + props.insert("style:text-underline-style", "dot-dash"); + break; + case Underline::DotDotDash: + case Underline::ThickDotDotDash: + props.insert("style:text-underline-style", "dot-dot-dash"); + break; + case Underline::Wave: + case Underline::ThickWave: + case Underline::DoubleWave: + props.insert("style:text-underline-style", "wave"); + break; + case Underline::LongDash: + case Underline::ThickLongDash: + props.insert("style:text-underline-style", "long-dash"); + break; + } + + switch (underline) + { + case Underline::Double: + case Underline::DoubleWave: + props.insert("style:text-underline-type", "double"); + break; + default: + props.insert("style:text-underline-type", "single"); + break; + } + + switch (underline) + { + case Underline::Thick: + case Underline::ThickWave: + case Underline::ThickDot: + case Underline::ThickDash: + case Underline::ThickDotDash: + case Underline::ThickDotDotDash: + props.insert("style:text-underline-width", "bold"); + break; + default: + props.insert("style:text-underline-width", "auto"); + break; + } + + switch (underline) + { + case Underline::WordsOnly: + props.insert("style:text-underline-mode", "skip-white-space"); + break; + default: + props.insert("style:text-underline-mode", "continuous"); + break; + } +} + } // anonymous namespace void MSPUBCollector::collectMetaData(const librevenge::RVNGPropertyList &metaData) @@ -1514,7 +1590,7 @@ librevenge::RVNGPropertyList MSPUBCollector::getParaStyleProps(const ParagraphSt librevenge::RVNGPropertyList MSPUBCollector::getCharStyleProps(const CharacterStyle &style, boost::optional<unsigned> defaultCharStyleIndex) const { - CharacterStyle _nothing = CharacterStyle(false, false, false); + CharacterStyle _nothing; if (!defaultCharStyleIndex) { defaultCharStyleIndex = 0; @@ -1529,10 +1605,26 @@ librevenge::RVNGPropertyList MSPUBCollector::getCharStyleProps(const CharacterSt { ret.insert("fo:font-weight", "bold"); } - if (style.underline ^ defaultCharStyle.underline) - { - ret.insert("style:text-underline-type", "single"); - } + if (style.outline ^ defaultCharStyle.outline) + ret.insert("style:text-outline", "true"); + if (style.shadow ^ defaultCharStyle.shadow) + ret.insert("fo:text-shadow", "1pt 1pt"); + if (style.smallCaps ^ defaultCharStyle.smallCaps) + ret.insert("fo:font-variant", "small-caps"); + else if (style.allCaps ^ defaultCharStyle.allCaps) + ret.insert("fo:text-transform", "uppercase"); + if (style.emboss ^ defaultCharStyle.emboss) + ret.insert("style:font-relief", "embossed"); + else if (style.engrave ^ defaultCharStyle.engrave) + ret.insert("style:font-relief", "engraved"); + if (style.underline) + fillUnderline(ret, get(style.underline)); + else if (defaultCharStyle.underline) + fillUnderline(ret, get(defaultCharStyle.underline)); + if (style.textScale) + ret.insert("fo:text-scale", get(style.textScale), librevenge::RVNG_PERCENT); + else if (defaultCharStyle.textScale) + ret.insert("fo:text-scale", get(defaultCharStyle.textScale), librevenge::RVNG_PERCENT); if (bool(style.textSizeInPt)) { ret.insert("fo:font-size", style.textSizeInPt.get() / POINTS_IN_INCH); diff --git a/src/lib/MSPUBParser.cpp b/src/lib/MSPUBParser.cpp index 1a66f4e..40cb694 100644 --- a/src/lib/MSPUBParser.cpp +++ b/src/lib/MSPUBParser.cpp @@ -45,6 +45,57 @@ namespace libmspub { +namespace +{ + +Underline readUnderline(const unsigned value) +{ + switch (value & 0xff) + { + case 0x0: + return Underline::None; + default: + MSPUB_DEBUG_MSG(("unknown underline type %u\n", value & 0xff)); + MSPUB_FALLTHROUGH; + case 0x1: + return Underline::Single; + case 0x2: + return Underline::WordsOnly; + case 0x3: + return Underline::Double; + case 0x4: + return Underline::Dotted; + case 0x6: + return Underline::Thick; + case 0x7: + return Underline::Dash; + case 0x9: + return Underline::DotDash; + case 0xa: + return Underline::DotDotDash; + case 0xb: + return Underline::Wave; + case 0x10: + return Underline::ThickWave; + case 0x11: + return Underline::ThickDot; + case 0x12: + return Underline::ThickDash; + case 0x13: + return Underline::ThickDotDash; + case 0x14: + return Underline::ThickDotDotDash; + case 0x15: + return Underline::LongDash; + case 0x16: + return Underline::ThickLongDash; + case 0x17: + return Underline::DoubleWave; + } +} + +} + MSPUBParser::MSPUBParser(librevenge::RVNGInputStream *input, MSPUBCollector *collector) : m_input(input), m_length(boost::numeric_cast<unsigned>(getLength(input))), @@ -1348,10 +1399,11 @@ ParagraphStyle MSPUBParser::getParagraphStyle(librevenge::RVNGInputStream *input CharacterStyle MSPUBParser::getCharacterStyle(librevenge::RVNGInputStream *input) { - bool seenUnderline = false, seenBold1 = false, seenBold2 = false, seenItalic1 = false, seenItalic2 = false; + CharacterStyle style; + + bool seenBold1 = false, seenBold2 = false, seenItalic1 = false, seenItalic2 = false; int textSize1 = -1, /* textSize2 = -1,*/ colorIndex = -1; boost::optional<unsigned> fontIndex; - SuperSubType sst = NO_SUPER_SUB; unsigned offset = input->tell(); unsigned len = readU32(input); while (stillReading(input, offset + len)) @@ -1372,7 +1424,7 @@ CharacterStyle MSPUBParser::getCharacterStyle(librevenge::RVNGInputStream *input seenItalic2 = true; break; case UNDERLINE_ID: - seenUnderline = true; + style.underline = readUnderline(info.data); break; case TEXT_SIZE_1_ID: textSize1 = info.data; @@ -1390,7 +1442,28 @@ CharacterStyle MSPUBParser::getCharacterStyle(librevenge::RVNGInputStream *input fontIndex = getFontIndex(input, info); break; case SUPER_SUB_TYPE_ID: - sst = static_cast<SuperSubType>(info.data); + style.superSubType = static_cast<SuperSubType>(info.data); + break; + case OUTLINE_ID: + style.outline = true; + break; + case SHADOW_ID: + style.shadow = true; + break; + case SMALL_CAPS_ID: + style.smallCaps = true; + break; + case ALL_CAPS_ID: + style.allCaps = true; + break; + case EMBOSS_ID: + style.emboss = true; + break; + case ENGRAVE_ID: + style.engrave = true; + break; + case SCALING_ID: + style.textScale = double(info.data) / 10; break; default: break; @@ -1403,7 +1476,13 @@ CharacterStyle MSPUBParser::getCharacterStyle(librevenge::RVNGInputStream *input { dTextSize = textSize1 * (double(POINTS_IN_INCH) / EMUS_IN_INCH); } - return CharacterStyle(seenUnderline, seenItalic1 && seenItalic2, seenBold1 && seenBold2, dTextSize, getColorIndexByQuillEntry(colorIndex), fontIndex, sst); + style.italic = seenItalic1 && seenItalic2; + style.bold = seenBold1 && seenBold2; + style.textSizeInPt = dTextSize; + style.colorIndex = getColorIndexByQuillEntry(colorIndex); + style.fontIndex = fontIndex; + + return style; } unsigned MSPUBParser::getFontIndex(librevenge::RVNGInputStream *input, const MSPUBBlockInfo &info) diff --git a/src/lib/MSPUBParser97.cpp b/src/lib/MSPUBParser97.cpp index 17ea81a..e34968b 100644 --- a/src/lib/MSPUBParser97.cpp +++ b/src/lib/MSPUBParser97.cpp @@ -197,27 +197,27 @@ std::vector<MSPUBParser97::SpanInfo97> MSPUBParser97::getSpansInfo( CharacterStyle MSPUBParser97::readCharacterStyle( librevenge::RVNGInputStream *input, unsigned length) { + CharacterStyle style; + unsigned begin = input->tell(); - bool underline = false, italic = false, bold = false; - int colorIndex = -1; - unsigned fontIndex = 0; int textSizeVariationFromDefault = 0; if (length >= 1) { unsigned char biFlags = readU8(input); - bold = biFlags & 0x1; - italic = biFlags & 0x2; + style.bold = biFlags & 0x1; + style.italic = biFlags & 0x2; } if (length >= 3) { input->seek(begin + 0x2, librevenge::RVNG_SEEK_SET); - fontIndex = readU8(input); + style.fontIndex = readU8(input); } if (length >= 9) { input->seek(begin + 0x8, librevenge::RVNG_SEEK_SET); - underline = readU8(input) & 0x1; + if (readU8(input) & 0x1) + style.underline = Underline::Single; } if (length >= 5) { @@ -228,12 +228,12 @@ CharacterStyle MSPUBParser97::readCharacterStyle( if (length >= 16) { input->seek(begin + 0xC, librevenge::RVNG_SEEK_SET); - colorIndex = getColorIndexByQuillEntry(readU32(input)); + style.colorIndex = getColorIndexByQuillEntry(readU32(input)); } - double textSizeInPt = 10 + - static_cast<double>(textSizeVariationFromDefault) / 2; - return CharacterStyle(underline, italic, bold, textSizeInPt, colorIndex, - fontIndex); + style.textSizeInPt = 10 + + static_cast<double>(textSizeVariationFromDefault) / 2; + + return style; } MSPUBParser97::TextInfo97 MSPUBParser97::getTextInfo(librevenge::RVNGInputStream *input, unsigned length) diff --git a/src/lib/MSPUBTypes.h b/src/lib/MSPUBTypes.h index 2cf98d1..ec1aa5c 100644 --- a/src/lib/MSPUBTypes.h +++ b/src/lib/MSPUBTypes.h @@ -37,6 +37,28 @@ enum SuperSubType SUBSCRIPT }; +enum class Underline +{ + None, + Single, + WordsOnly, + Double, + Dotted, + Thick, + Dash, + DotDash, + DotDotDash, + Wave, + ThickWave, + ThickDot, + ThickDash, + ThickDotDash, + ThickDotDotDash, + LongDash, + ThickLongDash, + DoubleWave, +}; + enum Alignment { LEFT = 0, @@ -92,21 +114,29 @@ struct CharacterStyle CharacterStyle() : underline(), italic(), bold(), textSizeInPt(), colorIndex(-1), fontIndex(), superSubType(NO_SUPER_SUB) + , outline(false) + , shadow(false) + , smallCaps(false) + , allCaps(false) + , emboss(false) + , engrave(false) + , textScale() { } - CharacterStyle(bool u, bool i, bool b, - boost::optional<double> tSIP = boost::optional<double>(), - int cI = -1, - boost::optional<unsigned> fI = boost::optional<unsigned>(), - SuperSubType sst = NO_SUPER_SUB) : - underline(u), italic(i), bold(b), textSizeInPt(tSIP), colorIndex(cI), fontIndex(fI), superSubType(sst) { } - bool underline; + boost::optional<Underline> underline; bool italic; bool bold; boost::optional<double> textSizeInPt; int colorIndex; boost::optional<unsigned> fontIndex; SuperSubType superSubType; + bool outline; + bool shadow; + bool smallCaps; + bool allCaps; + bool emboss; + bool engrave; + boost::optional<double> textScale; }; enum LineSpacingType |