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

Franz Schmid franz at linux-hp-i7.site
Mon Apr 15 04:48:37 PDT 2013


 src/lib/EscherContainerType.h |    3 -
 src/lib/EscherFieldIds.h      |    6 ++
 src/lib/Fill.cpp              |   41 ++++++++++++-
 src/lib/Fill.h                |    9 ++-
 src/lib/FillType.h            |    6 +-
 src/lib/MSPUBCollector.cpp    |   27 ++++++++-
 src/lib/MSPUBCollector.h      |    3 -
 src/lib/MSPUBParser.cpp       |  125 +++++++++++++++++++++++++++++++++---------
 src/lib/MSPUBParser.h         |    2 
 src/lib/MSPUBTypes.h          |    3 -
 src/lib/PolygonUtils.cpp      |   27 ++++++++-
 src/lib/PolygonUtils.h        |    1 
 src/lib/ShapeInfo.h           |    6 +-
 13 files changed, 215 insertions(+), 44 deletions(-)

New commits:
commit 2b840822cc91f28a8b8d5c0b1b40ddf039778f68
Author: Franz Schmid <franz at linux-hp-i7.site>
Date:   Sun Apr 14 12:17:12 2013 +0200

    Added output of the dash style value as libmspub:dashstyle property

diff --git a/src/lib/MSPUBCollector.cpp b/src/lib/MSPUBCollector.cpp
index 36f51ca..032908b 100644
--- a/src/lib/MSPUBCollector.cpp
+++ b/src/lib/MSPUBCollector.cpp
@@ -760,6 +760,12 @@ boost::function<void(void)> libmspub::MSPUBCollector::paintShape(const ShapeInfo
             graphicsProps.insert(length.cstr(), dash.m_dots[i].m_length.get(), WPX_INCH);
           }
         }
+        if (info.m_dashStyle.is_initialized())
+        {
+          WPXString dst;
+          dst.sprintf("%d", info.m_dashStyle.get());
+          graphicsProps.insert("libmspub:dashstyle", dst);
+        }
       }
       else
       {
@@ -1101,9 +1107,10 @@ void libmspub::MSPUBCollector::setShapeImgIndex(unsigned seqNum, unsigned index)
   m_shapeInfosBySeqNum[seqNum].m_imgIndex = index;
 }
 
-void libmspub::MSPUBCollector::setShapeDash(unsigned seqNum, const Dash &dash)
+void libmspub::MSPUBCollector::setShapeDash(unsigned seqNum, unsigned dashStyle, const Dash &dash)
 {
   m_shapeInfosBySeqNum[seqNum].m_dash = dash;
+  m_shapeInfosBySeqNum[seqNum].m_dashStyle = dashStyle;
 }
 
 void libmspub::MSPUBCollector::setShapeFill(unsigned seqNum, boost::shared_ptr<Fill> fill, bool skipIfNotBg)
diff --git a/src/lib/MSPUBCollector.h b/src/lib/MSPUBCollector.h
index 5755043..e23ba5e 100644
--- a/src/lib/MSPUBCollector.h
+++ b/src/lib/MSPUBCollector.h
@@ -96,7 +96,7 @@ public:
   void setShapeCoordinatesInEmu(unsigned seqNum, int xs, int ys, int xe, int ye);
   void setShapeImgIndex(unsigned seqNum, unsigned index);
   void setShapeFill(unsigned seqNum, boost::shared_ptr<Fill> fill, bool skipIfNotBg);
-  void setShapeDash(unsigned seqNum, const Dash &dash);
+  void setShapeDash(unsigned seqNum, unsigned dashStyle, const Dash &dash);
   void setAdjustValue(unsigned seqNum, unsigned index, int adjust);
   void setShapeRotation(unsigned seqNum, double rotation);
   void setShapeFlip(unsigned, bool, bool);
diff --git a/src/lib/MSPUBParser.cpp b/src/lib/MSPUBParser.cpp
index 50334d3..fd5dea1 100644
--- a/src/lib/MSPUBParser.cpp
+++ b/src/lib/MSPUBParser.cpp
@@ -1679,7 +1679,7 @@ void libmspub::MSPUBParser::parseEscherShape(WPXInputStream *input, const Escher
           }
           if (ptr_lineDashing)
           {
-            m_collector->setShapeDash(*shapeSeqNum, getDash(
+            m_collector->setShapeDash(*shapeSeqNum, *ptr_lineDashing, getDash(
                                         static_cast<MSPUBDashStyle>(*ptr_lineDashing), lineWidth,
                                         dotStyle));
           }
@@ -1771,9 +1771,9 @@ void libmspub::MSPUBParser::parseEscherShape(WPXInputStream *input, const Escher
           if (!wrapVertexData.empty())
           {
             std::vector<libmspub::Vertex> ret = parseVertices(wrapVertexData);
-			m_collector->setShapeClipPath(*shapeSeqNum, ret);
+            m_collector->setShapeClipPath(*shapeSeqNum, ret);
             MSPUB_DEBUG_MSG(("Current Escher shape has wrap Path\n"));
-		  }
+          }
         }
         if (foundAnchor)
         {
diff --git a/src/lib/ShapeInfo.h b/src/lib/ShapeInfo.h
index 9bbac5c..fd4eaad 100644
--- a/src/lib/ShapeInfo.h
+++ b/src/lib/ShapeInfo.h
@@ -70,6 +70,7 @@ struct ShapeInfo
   bool m_stretchBorderArt;
   boost::optional<ColorReference> m_lineBackColor;
   boost::optional<Dash> m_dash;
+  boost::optional<unsigned> m_dashStyle;
   boost::optional<TableInfo> m_tableInfo;
   boost::optional<std::vector<unsigned> > m_tableCellTextEnds;
   boost::optional<unsigned> m_numColumns;
@@ -86,7 +87,7 @@ struct ShapeInfo
     m_textId(), m_adjustValuesByIndex(), m_adjustValues(),
     m_rotation(), m_flips(), m_margins(), m_borderPosition(),
     m_fill(), m_customShape(), m_stretchBorderArt(false),
-    m_lineBackColor(), m_dash(), m_tableInfo(),
+    m_lineBackColor(), m_dash(), m_dashStyle(0), m_tableInfo(),
     m_tableCellTextEnds(), m_numColumns(),
     m_columnSpacing(0), m_beginArrow(), m_endArrow(),
     m_verticalAlign(), m_pictureRecolor(), m_shadow(), m_innerRotation(), m_clipPath()
commit 7089afb7d28f3ceecb7d6d1cd5fd8b3fdfd4d7c5
Author: Franz Schmid <franz at linux-hp-i7.site>
Date:   Sun Apr 14 10:51:31 2013 +0200

    Added output of the wrap path as an svg clip path.

diff --git a/src/lib/EscherFieldIds.h b/src/lib/EscherFieldIds.h
index 7c7446e..7b3ff22 100644
--- a/src/lib/EscherFieldIds.h
+++ b/src/lib/EscherFieldIds.h
@@ -78,6 +78,7 @@
 #define FIELDID_GEO_BOTTOM             0x0143
 #define FIELDID_P_VERTICES             0xC145
 #define FIELDID_P_SEGMENTS             0xC146
+#define FIELDID_P_WRAPPOLYGONVERTICES  0xC383
 #define FIELDID_P_CONNECTION_SITES     0xC151
 #define FIELDID_P_ADJUST_HANDLES       0xC155
 #define FIELDID_P_GUIDES               0xC156
diff --git a/src/lib/MSPUBCollector.cpp b/src/lib/MSPUBCollector.cpp
index 82b7cca..36f51ca 100644
--- a/src/lib/MSPUBCollector.cpp
+++ b/src/lib/MSPUBCollector.cpp
@@ -222,6 +222,11 @@ void libmspub::MSPUBCollector::setShapeCustomPath(unsigned seqNum,
   m_shapeInfosBySeqNum[seqNum].m_customShape = shape;
 }
 
+void libmspub::MSPUBCollector::setShapeClipPath(unsigned seqNum, const std::vector<libmspub::Vertex> &clip)
+{
+  m_shapeInfosBySeqNum[seqNum].m_clipPath = clip;
+}
+
 void libmspub::MSPUBCollector::beginGroup()
 {
   ShapeGroupElement *tmp = new ShapeGroupElement(m_currentShapeGroup);
@@ -409,7 +414,18 @@ boost::function<void(void)> libmspub::MSPUBCollector::paintShape(const ShapeInfo
                    (hasStroke && hasFill) || (hasStroke && hasText) || (hasFill && hasText);
   if (makeLayer)
   {
-    m_painter->startLayer(WPXPropertyList());
+    if (info.m_clipPath.size() > 0)
+    {
+      const Coordinate &coord = info.m_coordinates.get_value_or(Coordinate());
+      double x, y, height, width;
+      x = coord.getXIn(m_width);
+      y = coord.getYIn(m_height);
+      height = coord.getHeightIn();
+      width = coord.getWidthIn();
+      m_painter->startLayer(calcClipPath(info.m_clipPath, x, y, height, width, foldedTransform, info.getCustomShape()));
+    }
+    else
+      m_painter->startLayer(WPXPropertyList());
   }
   graphicsProps.insert("draw:stroke", "none");
   const Coordinate &coord = info.m_coordinates.get_value_or(Coordinate());
diff --git a/src/lib/MSPUBCollector.h b/src/lib/MSPUBCollector.h
index 719eb1e..5755043 100644
--- a/src/lib/MSPUBCollector.h
+++ b/src/lib/MSPUBCollector.h
@@ -105,6 +105,7 @@ public:
   void setShapeCoordinatesRotated90(unsigned seqNum);
   void setShapeCustomPath(unsigned seqNum,
                           const DynamicCustomShape &shape);
+  void setShapeClipPath(unsigned seqNum, const std::vector<libmspub::Vertex> &clip);
   void setShapeVerticalTextAlign(unsigned seqNum, VerticalAlign va);
   void designateMasterPage(unsigned seqNum);
   void setMasterPage(unsigned pageSeqNum, unsigned masterSeqNum);
diff --git a/src/lib/MSPUBParser.cpp b/src/lib/MSPUBParser.cpp
index b8e4c9b..50334d3 100644
--- a/src/lib/MSPUBParser.cpp
+++ b/src/lib/MSPUBParser.cpp
@@ -1767,6 +1767,13 @@ void libmspub::MSPUBParser::parseEscherShape(WPXInputStream *input, const Escher
                                             guideData, p_geoRight ? *p_geoRight : 21600,
                                             p_geoBottom ? *p_geoBottom : 21600));
           }
+          const std::vector<unsigned char> wrapVertexData = foptValues.m_complexValues[FIELDID_P_WRAPPOLYGONVERTICES];
+          if (!wrapVertexData.empty())
+          {
+            std::vector<libmspub::Vertex> ret = parseVertices(wrapVertexData);
+			m_collector->setShapeClipPath(*shapeSeqNum, ret);
+            MSPUB_DEBUG_MSG(("Current Escher shape has wrap Path\n"));
+		  }
         }
         if (foundAnchor)
         {
@@ -2161,6 +2168,7 @@ libmspub::FOPTValues libmspub::MSPUBParser::extractFOPTValues(WPXInputStream *in
     unsigned short id = readU16(input);
     unsigned value  = readU32(input);
     ret.m_scalarValues[id] = value;
+    MSPUB_DEBUG_MSG(("EscherFopt ID %u  Value %u\n", id, value));
     bool complex = id & 0x8000;
     if (complex)
     {
diff --git a/src/lib/PolygonUtils.cpp b/src/lib/PolygonUtils.cpp
index 8fb4c7c..df72a16 100644
--- a/src/lib/PolygonUtils.cpp
+++ b/src/lib/PolygonUtils.cpp
@@ -5896,6 +5896,31 @@ void getRayEllipseIntersection(double initX, double initY, double rx, double ry,
   yOut += cy;
 }
 
+WPXPropertyList libmspub::calcClipPath(const std::vector<libmspub::Vertex> &verts, double x, double y, double height, double width, VectorTransformation2D transform, boost::shared_ptr<const CustomShape> shape)
+{
+  WPXPropertyList vertices;
+  Vector2D center(x + width / 2, y + height / 2);
+  double scaleX = width / shape->m_coordWidth;
+  double scaleY = height / shape->m_coordHeight;
+  WPXString clipString;
+  Vector2D vector(x + scaleX * verts[0].m_x, y + scaleY * verts[0].m_y);
+  vector = transform.transformWithOrigin(vector, center);
+  WPXString sValue;
+  sValue.sprintf("M %f %f", (double)vector.m_x, (double)vector.m_y);
+  clipString.append(sValue);
+  for (unsigned i = 1; i < verts.size(); ++i)
+  {
+    Vector2D vector2(x + scaleX * verts[i].m_x, y + scaleY * verts[i].m_y);
+    vector2 = transform.transformWithOrigin(vector2, center);
+    WPXString sValue2;
+    sValue2.sprintf(" L %f %f", (double)vector2.m_x, (double)vector2.m_y);
+    clipString.append(sValue2);
+  }
+  clipString.append(" Z");
+  vertices.insert("svg:clip-path", clipString);
+  return vertices;
+}
+
 void libmspub::writeCustomShape(ShapeType shapeType, WPXPropertyList &graphicsProps, libwpg::WPGPaintInterface *painter, double x, double y, double height, double width, bool closeEverything, VectorTransformation2D transform, std::vector<Line> lines, boost::function<double(unsigned index)> calculator, const std::vector<Color> &palette, boost::shared_ptr<const CustomShape> shape)
 {
   MSPUB_DEBUG_MSG(("***STARTING CUSTOM SHAPE***\n"));
diff --git a/src/lib/PolygonUtils.h b/src/lib/PolygonUtils.h
index 73d652d..f4ed419 100644
--- a/src/lib/PolygonUtils.h
+++ b/src/lib/PolygonUtils.h
@@ -133,6 +133,7 @@ boost::shared_ptr<const CustomShape> getFromDynamicCustomShape(const DynamicCust
 
 const CustomShape *getCustomShape(ShapeType type);
 bool isShapeTypeRectangle(ShapeType type);
+WPXPropertyList calcClipPath(const std::vector<libmspub::Vertex> &verts, double x, double y, double height, double width, VectorTransformation2D transform, boost::shared_ptr<const CustomShape> shape);
 void writeCustomShape(ShapeType shapeType, WPXPropertyList &graphicsProps, libwpg::WPGPaintInterface *painter, double x, double y, double height, double width, bool closeEverything, VectorTransformation2D transform, std::vector<Line> lines, boost::function<double(unsigned index)> calculator, const std::vector<Color> &palette, boost::shared_ptr<const CustomShape> shape);
 
 } // libmspub
diff --git a/src/lib/ShapeInfo.h b/src/lib/ShapeInfo.h
index 8f33247..9bbac5c 100644
--- a/src/lib/ShapeInfo.h
+++ b/src/lib/ShapeInfo.h
@@ -80,6 +80,7 @@ struct ShapeInfo
   boost::optional<ColorReference> m_pictureRecolor;
   boost::optional<Shadow> m_shadow;
   boost::optional<int> m_innerRotation;
+  std::vector<libmspub::Vertex> m_clipPath;
   ShapeInfo() : m_type(), m_cropType(), m_imgIndex(), m_borderImgIndex(),
     m_coordinates(), m_lines(), m_pageSeqNum(),
     m_textId(), m_adjustValuesByIndex(), m_adjustValues(),
@@ -88,7 +89,7 @@ struct ShapeInfo
     m_lineBackColor(), m_dash(), m_tableInfo(),
     m_tableCellTextEnds(), m_numColumns(),
     m_columnSpacing(0), m_beginArrow(), m_endArrow(),
-    m_verticalAlign(), m_pictureRecolor(), m_shadow(), m_innerRotation()
+    m_verticalAlign(), m_pictureRecolor(), m_shadow(), m_innerRotation(), m_clipPath()
   {
   }
   boost::shared_ptr<const CustomShape> getCustomShape() const
commit 1d36216453944a6f431319a28e9df279f12f0574
Author: Franz Schmid <franz at linux-hp-i7.site>
Date:   Mon Apr 8 22:00:39 2013 +0200

    Added complete multicolor gradient support and fixed pattern colors.

diff --git a/src/lib/EscherContainerType.h b/src/lib/EscherContainerType.h
index 3332b02..7a8ee19 100644
--- a/src/lib/EscherContainerType.h
+++ b/src/lib/EscherContainerType.h
@@ -38,11 +38,12 @@
 #define OFFICE_ART_CLIENT_ANCHOR      0xF010
 #define OFFICE_ART_BLIP_PNG           0xF01E
 #define OFFICE_ART_BLIP_JPEG          0xF01D
+#define OFFICE_ART_BLIP_JPEGCMYK      0xF02A
 #define OFFICE_ART_BLIP_DIB           0xF01F
 #define OFFICE_ART_BLIP_EMF           0xF01A
 #define OFFICE_ART_BLIP_WMF           0xF01B
 #define OFFICE_ART_BLIP_PICT          0xF01C
-#define OFFICE_ART_BLIP_TIFF          0xF020
+#define OFFICE_ART_BLIP_TIFF          0xF029
 #define OFFICE_ART_FOPT               0xF00B
 #define OFFICE_ART_TERTIARY_FOPT      0xF122
 #define OFFICE_ART_FSP                0xF00A
diff --git a/src/lib/EscherFieldIds.h b/src/lib/EscherFieldIds.h
index b770c38..7c7446e 100644
--- a/src/lib/EscherFieldIds.h
+++ b/src/lib/EscherFieldIds.h
@@ -47,6 +47,11 @@
 #define FIELDID_FILL_TYPE              0x0180
 #define FIELDID_FILL_ANGLE             0x018B
 #define FIELDID_FILL_FOCUS             0x018C
+#define FIELDID_FILL_TO_LEFT           0x018D
+#define FIELDID_FILL_TO_TOP            0x018E
+#define FIELDID_FILL_TO_RIGHT          0x018F
+#define FIELDID_FILL_TO_BOTTOM         0x0190
+#define FIELDID_FILL_SHADE_COMPLEX     0xC197
 #define FIELDID_FIELD_STYLE_BOOL_PROPS 0x01BF
 #define FIELDID_ADJUST_VALUE_1         0x0147
 #define FIELDID_ADJUST_VALUE_2         0x0148
diff --git a/src/lib/Fill.cpp b/src/lib/Fill.cpp
index aeaeb37..358c8af 100644
--- a/src/lib/Fill.cpp
+++ b/src/lib/Fill.cpp
@@ -82,14 +82,14 @@ WPXPropertyListVector PatternFill::getProperties(WPXPropertyList *out) const
     if (type == DIB && data->size() >= 0x36 + 8)
     {
       fixedImg.append(data->getDataBuffer(), 0x36);
-      fixedImg.append(bgColor.b);
-      fixedImg.append(bgColor.g);
-      fixedImg.append(bgColor.r);
-      fixedImg.append('\0');
       fixedImg.append(fgColor.b);
       fixedImg.append(fgColor.g);
       fixedImg.append(fgColor.r);
       fixedImg.append('\0');
+      fixedImg.append(bgColor.b);
+      fixedImg.append(bgColor.g);
+      fixedImg.append(bgColor.r);
+      fixedImg.append('\0');
       fixedImg.append(data->getDataBuffer() + 0x36 + 8, data->size() - 0x36 - 8);
       data = &fixedImg;
     }
@@ -116,15 +116,38 @@ WPXPropertyListVector SolidFill::getProperties(WPXPropertyList *out) const
   return WPXPropertyListVector();
 }
 
-GradientFill::GradientFill(const MSPUBCollector *owner, double angle, int type) : Fill(owner), m_stops(), m_angle(angle), m_type(type)
+GradientFill::GradientFill(const MSPUBCollector *owner, double angle, int type) : Fill(owner), m_stops(), m_angle(angle), m_type(type), m_fillLeftVal(0.0), m_fillTopVal(0.0), m_fillRightVal(0.0), m_fillBottomVal(0.0)
 {
 }
 
+void GradientFill::setFillCenter(double left, double top, double right, double bottom)
+{
+  m_fillLeftVal = left;
+  m_fillTopVal = top;
+  m_fillRightVal = right;
+  m_fillBottomVal = bottom;
+}
+
 void GradientFill::addColor(ColorReference c, unsigned offsetPercent, double opacity)
 {
   m_stops.push_back(StopInfo(c, offsetPercent, opacity));
 }
 
+void GradientFill::addColorReverse(ColorReference c, unsigned offsetPercent, double opacity)
+{
+  m_stops.insert(m_stops.begin(), StopInfo(c, offsetPercent, opacity));
+}
+
+void GradientFill::completeComplexFill()
+{
+  unsigned stops = m_stops.size();
+  for (unsigned i = stops; i > 0; i--)
+  {
+    if (m_stops[i-1].m_offsetPercent != 50)
+      m_stops.push_back(StopInfo(m_stops[i-1].m_colorReference, 50 - m_stops[i-1].m_offsetPercent + 50, m_stops[i-1].m_opacity));
+  }
+}
+
 WPXPropertyListVector GradientFill::getProperties(WPXPropertyList *out) const
 {
   WPXPropertyListVector ret;
@@ -139,6 +162,14 @@ WPXPropertyListVector GradientFill::getProperties(WPXPropertyList *out) const
     break;
   case 5:
     out->insert("libmspub:shade", "center");
+    if ((m_fillLeftVal > 0.5) && (m_fillTopVal > 0.5) && (m_fillRightVal > 0.5) && (m_fillBottomVal > 0.5))
+      out->insert("libmspub:shade-ref-point", "bottom-right");
+    else if ((m_fillLeftVal < 0.5) && (m_fillTopVal < 0.5) && (m_fillRightVal < 0.5) && (m_fillBottomVal < 0.5))
+      out->insert("libmspub:shade-ref-point", "top-left");
+    else if ((m_fillLeftVal > 0.5) && (m_fillTopVal < 0.5) && (m_fillRightVal > 0.5) && (m_fillBottomVal < 0.5))
+      out->insert("libmspub:shade-ref-point", "top-right");
+    else if ((m_fillLeftVal < 0.5) && (m_fillTopVal > 0.5) && (m_fillRightVal < 0.5) && (m_fillBottomVal > 0.5))
+      out->insert("libmspub:shade-ref-point", "bottom-left");
     break;
   case 6:
     out->insert("libmspub:shade", "shape");
diff --git a/src/lib/Fill.h b/src/lib/Fill.h
index e226a65..7bded34 100644
--- a/src/lib/Fill.h
+++ b/src/lib/Fill.h
@@ -105,12 +105,19 @@ class GradientFill : public Fill
   std::vector<StopInfo> m_stops;
   double m_angle;
   int m_type;
+  double m_fillLeftVal;
+  double m_fillTopVal;
+  double m_fillRightVal;
+  double m_fillBottomVal;
 public:
   GradientFill(const MSPUBCollector *owner, double angle = 0, int type = 7);
+  void setFillCenter(double left, double top, double right, double bottom);
   void addColor(ColorReference c, unsigned offsetPercent, double opacity);
+  void addColorReverse(ColorReference c, unsigned offsetPercent, double opacity);
+  void completeComplexFill();
   WPXPropertyListVector getProperties(WPXPropertyList *out) const;
 private:
-  GradientFill(const GradientFill &) : Fill(NULL), m_stops(), m_angle(0), m_type(7) { }
+  GradientFill(const GradientFill &) : Fill(NULL), m_stops(), m_angle(0), m_type(7), m_fillLeftVal(0.0), m_fillTopVal(0.0), m_fillRightVal(0.0), m_fillBottomVal(0.0) { }
   GradientFill &operator=(const GradientFill &);
 };
 }
diff --git a/src/lib/FillType.h b/src/lib/FillType.h
index 8978ebd..adde316 100644
--- a/src/lib/FillType.h
+++ b/src/lib/FillType.h
@@ -35,9 +35,9 @@ enum FillType
 {
   SOLID,
   GRADIENT = 0x07, // msofillShadeScale Similar to msofillShade, but the fillAngle
-                   // is additionally scaled by the aspect ratio of
-                   // the shape. If shape is square, it is the
-                   // same as msofillShade
+  // is additionally scaled by the aspect ratio of
+  // the shape. If shape is square, it is the
+  // same as msofillShade
   GRADIENTCENTER = 0x06, // msofillShadeShape  Shade from shape outline to end point
   GRADIENTSHAPE = 0x05,  // msofillShadeCenter Shade from bounding rectangle to end point
   GRADIENTNORMAL = 0x04, // msofillShade       Shade from start to end points
diff --git a/src/lib/MSPUBParser.cpp b/src/lib/MSPUBParser.cpp
index 584c227..b8e4c9b 100644
--- a/src/lib/MSPUBParser.cpp
+++ b/src/lib/MSPUBParser.cpp
@@ -189,6 +189,8 @@ libmspub::ImgType libmspub::MSPUBParser::imgTypeByBlipType(unsigned short type)
     return PNG;
   case OFFICE_ART_BLIP_JPEG:
     return JPEG;
+  case OFFICE_ART_BLIP_JPEGCMYK:
+    return JPEGCMYK;
   case OFFICE_ART_BLIP_WMF:
     return WMF;
   case OFFICE_ART_BLIP_DIB:
@@ -226,10 +228,18 @@ int libmspub::MSPUBParser::getStartOffset(ImgType type, unsigned short initial)
     oneUid = recInstance == 0x46A || recInstance == 0x6E2;
     offset = 0x11;
     break;
+  case JPEGCMYK:
+    oneUid = recInstance == 0x46B || recInstance == 0x6E3;
+    offset = 33;
+    break;
   case DIB:
     oneUid = recInstance == 0x7A8;
     offset = 0x11;
     break;
+  case TIFF:
+    oneUid = recInstance == 0x6E4;
+    offset = 0x11;
+    break;
   default:
     break;
   }
@@ -1545,7 +1555,7 @@ void libmspub::MSPUBParser::parseEscherShape(WPXInputStream *input, const Escher
           bool useLine = lineExistsByFlagPointer(
                            ptr_lineFlags, ptr_geomFlags);
           bool skipIfNotBg = false;
-          boost::shared_ptr<Fill> ptr_fill = getNewFill(foptValues.m_scalarValues, skipIfNotBg);
+          boost::shared_ptr<Fill> ptr_fill = getNewFill(foptValues.m_scalarValues, skipIfNotBg, foptValues.m_complexValues);
           unsigned lineWidth = 0;
           if (useLine)
           {
@@ -1814,7 +1824,7 @@ void libmspub::MSPUBParser::parseEscherShape(WPXInputStream *input, const Escher
 }
 
 boost::shared_ptr<libmspub::Fill> libmspub::MSPUBParser::getNewFill(const std::map<unsigned short, unsigned> &foptProperties,
-    bool &skipIfNotBg)
+    bool &skipIfNotBg, std::map<unsigned short, std::vector<unsigned char> > &foptValues)
 {
   const FillType *ptr_fillType = (FillType *)getIfExists_const(foptProperties, FIELDID_FILL_TYPE);
   FillType fillType = ptr_fillType ? *ptr_fillType : SOLID;
@@ -1835,7 +1845,7 @@ boost::shared_ptr<libmspub::Fill> libmspub::MSPUBParser::getNewFill(const std::m
   case GRADIENTCENTER:
   case GRADIENTSHAPE:
   case GRADIENTNORMAL:
-  case GRADIENT: //FIXME: The handling of multi-color gradients here is quite bad.
+  case GRADIENT:
   {
     int angle;
     const int *ptr_angle = (const int *)getIfExists_const(foptProperties, FIELDID_FILL_ANGLE);
@@ -1865,29 +1875,86 @@ boost::shared_ptr<libmspub::Fill> libmspub::MSPUBParser::getNewFill(const std::m
     default:
       break;
     }
+    double fillLeftVal = 0.0;
+    const unsigned *ptr_fillLeft = getIfExists_const(foptProperties, FIELDID_FILL_TO_LEFT);
+    if (ptr_fillLeft)
+      fillLeftVal = toFixedPoint(*ptr_fillLeft);
+    double fillTopVal = 0.0;
+    const unsigned *ptr_fillTop = getIfExists_const(foptProperties, FIELDID_FILL_TO_TOP);
+    if (ptr_fillTop)
+      fillTopVal = toFixedPoint(*ptr_fillTop);
+    double fillRightVal = 0.0;
+    const unsigned *ptr_fillRight = getIfExists_const(foptProperties, FIELDID_FILL_TO_RIGHT);
+    if (ptr_fillRight)
+      fillRightVal = toFixedPoint(*ptr_fillRight);
+    double fillBottomVal = 0.0;
+    const unsigned *ptr_fillBottom = getIfExists_const(foptProperties, FIELDID_FILL_TO_BOTTOM);
+    if (ptr_fillBottom)
+      fillBottomVal = toFixedPoint(*ptr_fillBottom);
 
     boost::shared_ptr<GradientFill> ret(new GradientFill(m_collector, angle, (int)fillType));
-    if (fillFocus ==  0)
-    {
-      ret->addColor(firstColor, 0, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
-      ret->addColor(secondColor, 100, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
-    }
-    else if (fillFocus == 100)
-    {
-      ret->addColor(secondColor, 0, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
-      ret->addColor(firstColor, 100, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
-    }
-    else if (fillFocus > 0)
+    ret->setFillCenter(fillLeftVal, fillTopVal, fillRightVal, fillBottomVal);
+
+    const unsigned *ptr_fillGrad = getIfExists_const(foptProperties, FIELDID_FILL_SHADE_COMPLEX);
+    if (ptr_fillGrad)
     {
-      ret->addColor(firstColor, 0, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
-      ret->addColor(secondColor, fillFocus, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
-      ret->addColor(firstColor, 100, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+      const std::vector<unsigned char> gradientData = foptValues[FIELDID_FILL_SHADE_COMPLEX];
+      if (gradientData.size() > 6)
+      {
+        unsigned short numEntries = gradientData[0] | (gradientData[1] << 8);
+        unsigned offs = 6;
+        for (unsigned i = 0; i < numEntries; ++i)
+        {
+          unsigned color = gradientData[offs] | (unsigned(gradientData[offs + 1]) << 8) | (unsigned(gradientData[offs + 2]) << 16) | (unsigned(gradientData[offs + 3]) << 24);
+          offs += 4;
+          int posi = (int)(toFixedPoint(gradientData[offs] | (unsigned(gradientData[offs + 1]) << 8) | (unsigned(gradientData[offs + 2]) << 16) | (unsigned(gradientData[offs + 3]) << 24)) * 100);
+          offs += 4;
+          ColorReference sColor(color, color);
+          if (fillFocus ==  0)
+            ret->addColor(sColor, posi, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+          else if (fillFocus == 100)
+            ret->addColorReverse(sColor, 100 - posi, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+          else if (fillFocus > 0)
+            ret->addColor(sColor, posi / 2, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+          else if (fillFocus < 0)
+            ret->addColorReverse(sColor, (100 - posi) / 2, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+        }
+        if ((fillFocus < 0) || ((fillFocus > 0) && (fillFocus < 100)))
+          ret->completeComplexFill();
+      }
     }
-    else if (fillFocus < 0)
+    else
     {
-      ret->addColor(secondColor, 0, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
-      ret->addColor(firstColor, 100 + fillFocus, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
-      ret->addColor(secondColor, 100, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
+      if (fillFocus ==  0)
+      {
+        ret->addColor(firstColor, 0, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+        ret->addColor(secondColor, 100, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
+      }
+      else if (fillFocus == 100)
+      {
+        ret->addColor(secondColor, 0, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
+        ret->addColor(firstColor, 100, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+      }
+      else if (fillFocus > 0)
+      {
+        ret->addColor(secondColor, 0, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
+        ret->addColor(firstColor, fillFocus, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+        ret->addColor(secondColor, 100, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
+
+//        ret->addColor(firstColor, 0, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+//        ret->addColor(secondColor, fillFocus, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
+//        ret->addColor(firstColor, 100, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+      }
+      else if (fillFocus < 0)
+      {
+        ret->addColor(firstColor, 0, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+        ret->addColor(secondColor, 100 + fillFocus, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
+        ret->addColor(firstColor, 100, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+
+//        ret->addColor(secondColor, 0, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
+//        ret->addColor(firstColor, 100 + fillFocus, ptr_fillOpacity ? (double)(*ptr_fillOpacity) / 0xFFFF : 1);
+//        ret->addColor(secondColor, 100, ptr_fillBackOpacity ? (double)(*ptr_fillBackOpacity) / 0xFFFF : 1);
+      }
     }
     return ret;
   }
@@ -1898,10 +1965,7 @@ boost::shared_ptr<libmspub::Fill> libmspub::MSPUBParser::getNewFill(const std::m
     int rotation = 0;
     const int *ptr_rotation = (const int *)getIfExists_const(foptProperties, FIELDID_ROTATION);
     if (ptr_rotation)
-    {
       rotation = (int)doubleModulo(toFixedPoint(*ptr_rotation), 360);
-      MSPUB_DEBUG_MSG(("Rotation value %d\n", rotation));
-    }
     const unsigned *ptr_bgPxId = getIfExists_const(foptProperties, FIELDID_BG_PXID);
     if (ptr_bgPxId && *ptr_bgPxId <= m_escherDelayIndices.size() && m_escherDelayIndices[*ptr_bgPxId - 1] >= 0)
     {
@@ -1915,7 +1979,8 @@ boost::shared_ptr<libmspub::Fill> libmspub::MSPUBParser::getNewFill(const std::m
     const unsigned *ptr_fillColor = getIfExists_const(foptProperties, FIELDID_FILL_COLOR);
     const unsigned *ptr_fillBackColor = getIfExists_const(foptProperties, FIELDID_FILL_BACK_COLOR);
     ColorReference fill = ptr_fillColor ? ColorReference(*ptr_fillColor) : ColorReference(0x00FFFFFF);
-    ColorReference back = ptr_fillBackColor ? ColorReference(*ptr_fillBackColor) : ColorReference(0x08000000);
+//    ColorReference back = ptr_fillBackColor ? ColorReference(*ptr_fillBackColor) : ColorReference(0x08000000);
+    ColorReference back = ptr_fillBackColor ? ColorReference(*ptr_fillBackColor) : ColorReference(0x00FFFFFF);
     if (ptr_bgPxId && *ptr_bgPxId <= m_escherDelayIndices.size() && m_escherDelayIndices[*ptr_bgPxId - 1 ] >= 0)
     {
       return boost::shared_ptr<Fill>(new PatternFill(m_escherDelayIndices[*ptr_bgPxId - 1], m_collector, fill, back));
diff --git a/src/lib/MSPUBParser.h b/src/lib/MSPUBParser.h
index 1cc8215..d7f2514 100644
--- a/src/lib/MSPUBParser.h
+++ b/src/lib/MSPUBParser.h
@@ -162,7 +162,7 @@ protected:
   unsigned getFontIndex(WPXInputStream *input, const MSPUBBlockInfo &info);
   CharacterStyle getCharacterStyle(WPXInputStream *input);
   ParagraphStyle getParagraphStyle(WPXInputStream *input);
-  boost::shared_ptr<Fill> getNewFill(const std::map<unsigned short, unsigned> &foptValues, bool &skipIfNotBg);
+  boost::shared_ptr<Fill> getNewFill(const std::map<unsigned short, unsigned> &foptValues, bool &skipIfNotBg, std::map<unsigned short, std::vector<unsigned char> > &foptVal);
 
   WPXInputStream *m_input;
   MSPUBCollector *m_collector;
diff --git a/src/lib/MSPUBTypes.h b/src/lib/MSPUBTypes.h
index 2950ad5..7884725 100644
--- a/src/lib/MSPUBTypes.h
+++ b/src/lib/MSPUBTypes.h
@@ -203,7 +203,8 @@ enum ImgType
   EMF,
   TIFF,
   DIB,
-  PICT
+  PICT,
+  JPEGCMYK
 };
 
 } // namespace libmspub
diff --git a/src/lib/PolygonUtils.cpp b/src/lib/PolygonUtils.cpp
index ae8f2e4..8fb4c7c 100644
--- a/src/lib/PolygonUtils.cpp
+++ b/src/lib/PolygonUtils.cpp
@@ -5379,7 +5379,7 @@ const CustomShape *libmspub::getCustomShape(ShapeType type)
   case HEART:
     return &CS_HEART;
   case PICTURE_FRAME:
-    return NULL; //FIXME
+    return &CS_RECTANGLE; // treat it as RECTANGLE for now
   case QUAD_ARROW:
     return &CS_QUAD_ARROW;
   case BEVEL:


More information about the Libreoffice-commits mailing list