[Libreoffice-commits] libmspub.git: 2 commits - src/lib

David Tardon dtardon at redhat.com
Sat Dec 30 14:11:39 UTC 2017


 src/lib/MSPUBBlockID.h     |    7 +++
 src/lib/MSPUBCollector.cpp |  102 ++++++++++++++++++++++++++++++++++++++++++---
 src/lib/MSPUBParser.cpp    |   93 ++++++++++++++++++++++++++++++++++++++---
 src/lib/MSPUBParser97.cpp  |   24 +++++-----
 src/lib/MSPUBTypes.h       |   44 ++++++++++++++++---
 5 files changed, 241 insertions(+), 29 deletions(-)

New commits:
commit df9a3b0cc2d2af14f2816477f2ca2e65320234a4
Author: David Tardon <dtardon at redhat.com>
Date:   Sat Dec 30 14:26:06 2017 +0100

    fix parsing of bold and italic in mspub 2002 docs
    
    Change-Id: I3945cdf240cd23c593d413d7d964d33e288d873b

diff --git a/src/lib/MSPUBParser.cpp b/src/lib/MSPUBParser.cpp
index 40cb694..b6d6bbb 100644
--- a/src/lib/MSPUBParser.cpp
+++ b/src/lib/MSPUBParser.cpp
@@ -1476,8 +1476,12 @@ CharacterStyle MSPUBParser::getCharacterStyle(librevenge::RVNGInputStream *input
   {
     dTextSize = textSize1 * (double(POINTS_IN_INCH) / EMUS_IN_INCH);
   }
-  style.italic = seenItalic1 && seenItalic2;
-  style.bold = seenBold1 && seenBold2;
+  // FIXME: What's this with foo1 && foo2? I've only seen foo1 in 2k2
+  // files and either just foo1 or foo1+foo2 in 2k7 files...
+  style.italic = seenItalic1; // && seenItalic2;
+  style.bold = seenBold1; // && seenBold2;
+  (void) seenItalic2;
+  (void) seenBold2;
   style.textSizeInPt = dTextSize;
   style.colorIndex = getColorIndexByQuillEntry(colorIndex);
   style.fontIndex = fontIndex;
commit 45832739afa9280d180d50b34041c4930eb7fd24
Author: David Tardon <dtardon at redhat.com>
Date:   Sat Dec 30 13:31:52 2017 +0100

    parse more text formatting properties
    
    Change-Id: I25aef81ba5b3beaa57726d85b57c7acab79198d1

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


More information about the Libreoffice-commits mailing list