Hi all, my name is Franz Schmid, and i'm one of the core Scribus developers. Finally i had some time to go for a test of the libmspub library. It works very fine and integrates cleanly in our Scribus build. During the integration process i've done some minor improvements to libmspup, namely the detection of some more gradient types and the rotation of images.
Attached is a patch against git master. Use: patch -p1 < Image_Gradients.patch in the main directory of libmspup to apply the patch. Hope you accept my patch. Greetings, Franz Schmid
>From e95ad141cd4b19ef4b0a47a7c70d56a053dd1caf Mon Sep 17 00:00:00 2001 From: Franz Schmid <fr...@linux-hp-i7.site> Date: Wed, 3 Apr 2013 21:14:47 +0200 Subject: [PATCH 1/2] Added parsing of more gradient types and report rotation for images. --- src/lib/Fill.cpp | 26 ++++++++++++++++++++++++-- src/lib/Fill.h | 13 ++++++++----- src/lib/FillType.h | 8 +++++++- src/lib/MSPUBCollector.cpp | 5 ++++- src/lib/MSPUBParser.cpp | 13 ++++++++++++- src/lib/ShapeInfo.h | 3 ++- 6 files changed, 57 insertions(+), 11 deletions(-) diff --git a/src/lib/Fill.cpp b/src/lib/Fill.cpp index cade9b8..b3abd17 100644 --- a/src/lib/Fill.cpp +++ b/src/lib/Fill.cpp @@ -36,7 +36,7 @@ Fill::Fill(const MSPUBCollector *owner) : m_owner(owner) { } -ImgFill::ImgFill(unsigned imgIndex, const MSPUBCollector *owner, bool isTexture) : Fill(owner), m_imgIndex(imgIndex), m_isTexture(isTexture) +ImgFill::ImgFill(unsigned imgIndex, const MSPUBCollector *owner, bool isTexture, int rot) : Fill(owner), m_imgIndex(imgIndex), m_isTexture(isTexture), m_rotation(rot) { } @@ -53,6 +53,12 @@ WPXPropertyListVector ImgFill::getProperties(WPXPropertyList *out) const { out->insert("style:repeat", "stretch"); } + if (m_rotation != 0) + { + WPXString sValue; + sValue.sprintf("%d", m_rotation); + out->insert("libwpg:rotate", sValue); + } } return WPXPropertyListVector(); } @@ -63,7 +63,7 @@ WPXPropertyListVector ImgFill::getProperties(WPXPropertyList *out) const return WPXPropertyListVector(); } -PatternFill::PatternFill(unsigned imgIndex, const MSPUBCollector *owner, ColorReference fg, ColorReference bg) : ImgFill(imgIndex, owner, true), m_fg(fg), m_bg(bg) +PatternFill::PatternFill(unsigned imgIndex, const MSPUBCollector *owner, ColorReference fg, ColorReference bg) : ImgFill(imgIndex, owner, true, 0), m_fg(fg), m_bg(bg) { } @@ -110,7 +116,7 @@ WPXPropertyListVector SolidFill::getProperties(WPXPropertyList *out) const return WPXPropertyListVector(); } -GradientFill::GradientFill(const MSPUBCollector *owner, double angle) : Fill(owner), m_stops(), m_angle(angle) +GradientFill::GradientFill(const MSPUBCollector *owner, double angle, int type) : Fill(owner), m_stops(), m_angle(angle), m_type(type) { } @@ -125,6 +131,22 @@ WPXPropertyListVector GradientFill::getProperties(WPXPropertyList *out) const out->insert("draw:fill", "gradient"); out->insert("svg:fill-rule", "nonzero"); out->insert("draw:angle", -m_angle); // draw:angle is clockwise in odf format + switch (m_type) + { + case 4: + case 7: + out->insert("libmspub:shade", "normal"); + break; + case 5: + out->insert("libmspub:shade", "center"); + break; + case 6: + out->insert("libmspub:shade", "shape"); + break; + default: + out->insert("libmspub:shade", "normal"); + break; + } for (unsigned i = 0; i < m_stops.size(); ++i) { Color c = m_stops[i].m_colorReference.getFinalColor(m_owner->m_paletteColors); diff --git a/src/lib/Fill.h b/src/lib/Fill.h index dc6bc31..e226a65 100644 --- a/src/lib/Fill.h +++ b/src/lib/Fill.h @@ -59,11 +59,13 @@ protected: unsigned m_imgIndex; private: bool m_isTexture; +protected: + int m_rotation; public: - ImgFill(unsigned imgIndex, const MSPUBCollector *owner, bool isTexture); + ImgFill(unsigned imgIndex, const MSPUBCollector *owner, bool isTexture, int rotation); virtual WPXPropertyListVector getProperties(WPXPropertyList *out) const; private: - ImgFill(const ImgFill &) : Fill(NULL), m_imgIndex(0), m_isTexture(false) { } + ImgFill(const ImgFill &) : Fill(NULL), m_imgIndex(0), m_isTexture(false), m_rotation(0) { } ImgFill &operator=(const ImgFill &); }; @@ -75,7 +77,7 @@ public: PatternFill(unsigned imgIndex, const MSPUBCollector *owner, ColorReference fg, ColorReference bg); WPXPropertyListVector getProperties(WPXPropertyList *out) const; private: - PatternFill(const PatternFill &) : ImgFill(0, NULL, true), m_fg(0x08000000), m_bg(0x08000000) { } + PatternFill(const PatternFill &) : ImgFill(0, NULL, true, 0), m_fg(0x08000000), m_bg(0x08000000) { } PatternFill &operator=(const ImgFill &); }; @@ -102,12 +104,13 @@ class GradientFill : public Fill }; std::vector<StopInfo> m_stops; double m_angle; + int m_type; public: - GradientFill(const MSPUBCollector *owner, double angle = 0); + GradientFill(const MSPUBCollector *owner, double angle = 0, int type = 7); void addColor(ColorReference c, unsigned offsetPercent, double opacity); WPXPropertyListVector getProperties(WPXPropertyList *out) const; private: - GradientFill(const GradientFill &) : Fill(NULL), m_stops(), m_angle(0) { } + GradientFill(const GradientFill &) : Fill(NULL), m_stops(), m_angle(0), m_type(7) { } GradientFill &operator=(const GradientFill &); }; } diff --git a/src/lib/FillType.h b/src/lib/FillType.h index 5d8181f..7b1f4cb 100644 --- a/src/lib/FillType.h +++ b/src/lib/FillType.h @@ -34,7 +34,13 @@ namespace libmspub enum FillType { SOLID, - GRADIENT = 0x07, + 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 + 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 BITMAP = 0x03, TEXTURE = 0x02, PATTERN = 0x01 diff --git a/src/lib/MSPUBCollector.cpp b/src/lib/MSPUBCollector.cpp index bceb8f4..07f46ec 100644 --- a/src/lib/MSPUBCollector.cpp +++ b/src/lib/MSPUBCollector.cpp @@ -348,9 +348,12 @@ void libmspub::MSPUBCollector::setupShapeStructures(ShapeGroupElement &elt) if (ptr_info->m_imgIndex.is_initialized()) { unsigned index = ptr_info->m_imgIndex.get(); + int rot = 0; + if (ptr_info->m_innerRotation.is_initialized()) + rot = ptr_info->m_innerRotation.get(); if (index - 1 < m_images.size()) { - ptr_info->m_fill = boost::shared_ptr<const Fill>(new ImgFill(index, this, false)); + ptr_info->m_fill = boost::shared_ptr<const Fill>(new ImgFill(index, this, false, rot)); } } elt.setShapeInfo(*ptr_info); @@ -1035,6 +1035,7 @@ libmspub::MSPUBCollector::~MSPUBCollector() void libmspub::MSPUBCollector::setShapeRotation(unsigned seqNum, double rotation) { m_shapeInfosBySeqNum[seqNum].m_rotation = rotation; + m_shapeInfosBySeqNum[seqNum].m_innerRotation = (int)rotation; } void libmspub::MSPUBCollector::setShapeFlip(unsigned seqNum, bool flipVertical, bool flipHorizontal) diff --git a/src/lib/MSPUBParser.cpp b/src/lib/MSPUBParser.cpp index 414a946..5a38585 100644 --- a/src/lib/MSPUBParser.cpp +++ b/src/lib/MSPUBParser.cpp @@ -1832,6 +1832,9 @@ boost::shared_ptr<libmspub::Fill> libmspub::MSPUBParser::getNewFill(const std::m } return boost::shared_ptr<Fill>(); } + case GRADIENTCENTER: + case GRADIENTSHAPE: + case GRADIENTNORMAL: case GRADIENT: //FIXME: The handling of multi-color gradients here is quite bad. { int angle; @@ -1866,7 +1866,7 @@ boost::shared_ptr<libmspub::Fill> libmspub::MSPUBParser::getNewFill(const std::m break; } - boost::shared_ptr<GradientFill> ret(new GradientFill(m_collector, angle)); + 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); @@ -1891,10 +1894,18 @@ boost::shared_ptr<libmspub::Fill> libmspub::MSPUBParser::getNewFill(const std::m case TEXTURE: case BITMAP: { + // in the case the shape is rotated we must rotate the image too + 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) { - return boost::shared_ptr<Fill>(new ImgFill(m_escherDelayIndices[*ptr_bgPxId - 1], m_collector, fillType == TEXTURE)); + return boost::shared_ptr<Fill>(new ImgFill(m_escherDelayIndices[*ptr_bgPxId - 1], m_collector, fillType == TEXTURE, rotation)); } return boost::shared_ptr<Fill>(); } diff --git a/src/lib/ShapeInfo.h b/src/lib/ShapeInfo.h index a0d193a..8f33247 100644 --- a/src/lib/ShapeInfo.h +++ b/src/lib/ShapeInfo.h @@ -79,6 +79,7 @@ struct ShapeInfo boost::optional<VerticalAlign> m_verticalAlign; boost::optional<ColorReference> m_pictureRecolor; boost::optional<Shadow> m_shadow; + boost::optional<int> m_innerRotation; ShapeInfo() : m_type(), m_cropType(), m_imgIndex(), m_borderImgIndex(), m_coordinates(), m_lines(), m_pageSeqNum(), m_textId(), m_adjustValuesByIndex(), m_adjustValues(), @@ -87,7 +88,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_verticalAlign(), m_pictureRecolor(), m_shadow(), m_innerRotation() { } boost::shared_ptr<const CustomShape> getCustomShape() const -- 1.7.1
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice