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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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: _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
