summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 3ec0ca2)
raw | patch | inline | side by side (parent: 3ec0ca2)
author | gouldtj <gouldtj@users.sourceforge.net> | |
Mon, 31 Jul 2006 05:20:20 +0000 (05:20 +0000) | ||
committer | gouldtj <gouldtj@users.sourceforge.net> | |
Mon, 31 Jul 2006 05:20:20 +0000 (05:20 +0000) |
Updates from the libwpg development CVS
diff --git a/src/extension/internal/libwpg/WPG2Parser.cpp b/src/extension/internal/libwpg/WPG2Parser.cpp
index 43823d0b2c26c8924f3d999a688923940ea1d906..8b6a4a674e53193dde77fc6d0be28c9ead1ccd0b 100644 (file)
m_xofs(0), m_yofs(0),
m_width(0), m_height(0),
m_doublePrecision(false),
- m_layerOpened(false), m_layerId(0),
- m_subIndex(0)
+ m_layerOpened(false), m_layerId(0)
{
}
m_doublePrecision = false;
m_layerOpened = false;
m_matrix = WPG2TransformMatrix();
- m_subIndex = 0;
- while(!m_indexStack.empty())
- m_indexStack.pop();
+ m_groupStack = std::stack<WPGGroupContext>();
+ m_compoundMatrix = WPG2TransformMatrix();
+ m_compoundWindingRule = false;
+ m_compoundFilled = false;
+ m_compoundFramed = true;
+ m_compoundClosed = false;
// default style
m_pen.foreColor = WPGColor(0,0,0);
long nextPos = m_input->tell() + length;
// inside a subgroup, one less sub record
- if(m_subIndex > 0)
- m_subIndex--;
+ if(!m_groupStack.empty())
+ m_groupStack.top().subIndex--;
// search function to handler this record
int index = -1;
}
}
- // we enter another subgroup, save the index to stack
+ // the last subgroup
+ if(!m_groupStack.empty())
+ {
+ WPGGroupContext& context = m_groupStack.top();
+ if(context.subIndex == 0)
+ {
+ if(context.isCompoundPolygon())
+ flushCompoundPolygon();
+ m_groupStack.pop();
+ }
+ }
+
+ // we enter another subgroup, save the context to stack
if(extension > 0)
{
- m_indexStack.push(m_subIndex);
- m_subIndex = extension;
+ WPGGroupContext context;
+ context.parentType = recordType;
+ context.subIndex = extension;
+ if(context.isCompoundPolygon())
+ {
+ context.compoundMatrix = m_compoundMatrix;
+ context.compoundFilled = m_compoundFilled;
+ context.compoundFramed = m_compoundFramed;
+ context.compoundClosed = m_compoundClosed;
+ }
+ m_groupStack.push(context);
}
//if(m_input->tell() > nextPos)
m_painter->endDocument();
m_exit = true;
-
- WPG_DEBUG_MSG(("EndWPG\n"));
}
void WPG2Parser::handleLayer()
m_painter->startLayer(m_layerId);
m_layerOpened = true;
- WPG_DEBUG_MSG(("Layer\n"));
- WPG_DEBUG_MSG((" Id: %d\n", m_layerId));
+ WPG_DEBUG_MSG((" Layer Id: %d\n", m_layerId));
}
void WPG2Parser::handleCompoundPolygon()
{
ObjectCharacterization objCh;
parseCharacterization(&objCh);
+
+ m_compoundWindingRule = objCh.windingRule;
+ m_compoundMatrix = objCh.matrix;
+ m_compoundFilled = objCh.filled;
+ m_compoundFramed = objCh.framed;
+ m_compoundClosed = objCh.closed;
+}
+void WPG2Parser::flushCompoundPolygon()
+{
+ WPGGroupContext& context = m_groupStack.top();
+
+ m_painter->setBrush( context.compoundFilled ? m_brush : WPGBrush() );
+ m_painter->setPen( context.compoundFramed ? m_pen : WPGPen() );
+ if(context.compoundWindingRule)
+ m_painter->setFillRule(WPGPaintInterface::WindingFill);
+ else
+ m_painter->setFillRule(WPGPaintInterface::AlternatingFill);
+ context.compoundPath.closed = context.compoundClosed;
+ m_painter->drawPath(context.compoundPath);
}
void WPG2Parser::handlePenStyleDefinition()
unsigned int segments = readU16();
WPGDashArray dashArray;
- for(int i = 0; i < segments; i++)
+ for(unsigned i = 0; i < segments; i++)
{
unsigned int p = (m_doublePrecision) ? readU32() : readU16();
unsigned int q = (m_doublePrecision) ? readU32() : readU16();
}
m_penStyles[style] = dashArray;
- WPG_DEBUG_MSG(("PenStyleDefinition\n"));
WPG_DEBUG_MSG((" Style : %d\n", style));
WPG_DEBUG_MSG((" Segment pairs : %d\n", segments));
}
unsigned startIndex = readU16();
unsigned numEntries = readU16();
- WPG_DEBUG_MSG(("Color Palette\n"));
- for(int i = 0; i < numEntries; i++)
+ for(unsigned i = 0; i < numEntries; i++)
{
WPGColor color;
color.red = readU8();
unsigned startIndex = readU16();
unsigned numEntries = readU16();
- WPG_DEBUG_MSG(("Color Palette\n"));
for(int i = 0; i < numEntries; i++)
{
WPGColor color;
m_pen.foreColor = WPGColor(red, green, blue, alpha);
- WPG_DEBUG_MSG(("PenForeColor\n"));
WPG_DEBUG_MSG((" Foreground color (RGBA): %d %d %d %d\n", red, green, blue, alpha));
}
m_pen.foreColor = WPGColor(red, green, blue, alpha);
- WPG_DEBUG_MSG(("PenForeColor\n"));
WPG_DEBUG_MSG((" Foreground color (RGBA): %d %d %d %d\n", red, green, blue, alpha));
}
m_pen.backColor = WPGColor(red, green, blue, alpha);
- WPG_DEBUG_MSG(("PenBackColor\n"));
WPG_DEBUG_MSG((" Background color (RGBA): %d %d %d %d\n", red, green, blue, alpha));
}
m_pen.backColor = WPGColor(red, green, blue, alpha);
- WPG_DEBUG_MSG(("PenBackColor\n"));
WPG_DEBUG_MSG((" Background color (RGBA): %d %d %d %d\n", red, green, blue, alpha));
}
m_pen.dashArray = m_penStyles[style];
m_pen.solid = (style == 0);
- WPG_DEBUG_MSG(("PenStyle\n"));
WPG_DEBUG_MSG((" Pen style : %d\n", style));
WPG_DEBUG_MSG((" Segments : %d\n", m_pen.dashArray.count()));
}
m_pen.width = TO_DOUBLE(width) / m_xres;
m_pen.height = TO_DOUBLE(height) / m_yres;
- WPG_DEBUG_MSG(("PenSize\n"));
WPG_DEBUG_MSG((" Width: %d\n", width));
WPG_DEBUG_MSG((" Height: %d\n", height));
}
m_pen.width = TO_DOUBLE(width) / m_xres / 256;
m_pen.height = TO_DOUBLE(height) / m_yres / 256;
- WPG_DEBUG_MSG(("PenSize\n"));
WPG_DEBUG_MSG((" Width: %d\n", width));
WPG_DEBUG_MSG((" Height: %d\n", height));
}
unsigned xref = readU16();
unsigned yref = readU16();
unsigned flag = readU16();
- bool granular = flag & (1<<6);
- bool anchor = flag & (1<<7);
+ bool granular = (flag & (1<<6)) == 1;
+ bool anchor = (flag & (1<<7)) == 1;
// TODO: get gradient extent
unsigned xref = readU16();
unsigned yref = readU16();
unsigned flag = readU16();
- bool granular = flag & (1<<6);
- bool anchor = flag & (1<<7);
+ bool granular = (flag & (1<<6)) == 1;
+ bool anchor = (flag & (1<<7)) == 1;
// TODO: get gradient extent (in double precision)
WPG_DEBUG_MSG((" Foreground color (RGBA): %d %d %d %d\n", red, green, blue, alpha));
m_brush.foreColor = WPGColor(red, green, blue, alpha);
- if(m_brush.style == WPGBrush::NoBrush)
+ if(m_brush.style != WPGBrush::Gradient)
m_brush.style = WPGBrush::Solid;
}
else
void WPG2Parser::handleDPBrushForeColor()
{
unsigned char gradientType = readU8();
+ WPG_DEBUG_MSG((" Gradient type : %d (%s)\n", gradientType, describeGradient(gradientType)));
- // we just ignore the least significant 8 bits
- unsigned int red = (m_doublePrecision) ? readU16()>>8 : readU8();
- unsigned int green = (m_doublePrecision) ? readU16()>>8 : readU8();
- unsigned int blue = (m_doublePrecision) ? readU16()>>8 : readU8();
- unsigned int alpha = (m_doublePrecision) ? readU16()>>8 : readU8();
+ if(gradientType == 0)
+ {
+ unsigned char red = (m_doublePrecision) ? readU16()>>8 : readU8();
+ unsigned char green = (m_doublePrecision) ? readU16()>>8 : readU8();
+ unsigned char blue = (m_doublePrecision) ? readU16()>>8 : readU8();
+ unsigned char alpha = (m_doublePrecision) ? readU16()>>8 : readU8();
+ WPG_DEBUG_MSG((" Foreground color (RGBA): %d %d %d %d\n", red, green, blue, alpha));
- m_brush.foreColor = WPGColor(red, green, blue, alpha);
- if(m_brush.style == WPGBrush::NoBrush)
- m_brush.style = WPGBrush::Solid;
+ m_brush.foreColor = WPGColor(red, green, blue, alpha);
+ if(m_brush.style != WPGBrush::NoBrush)
+ m_brush.style = WPGBrush::Solid;
+ }
+ else
+ {
+ unsigned count = readU16();
+ std::vector<WPGColor> colors;
+ std::vector<double> positions;
+ WPG_DEBUG_MSG((" Gradient colors : %d\n", count));
- WPG_DEBUG_MSG(("BrushForeColor\n"));
- WPG_DEBUG_MSG((" Gradient type : %d (%s)\n", gradientType, describeGradient(gradientType)));
- WPG_DEBUG_MSG((" Foreground color (RGBA): %d %d %d %d\n", red, green, blue, alpha));
+ for(unsigned i = 0; i < count; i++)
+ {
+ unsigned char red = (m_doublePrecision) ? readU16()>>8 : readU8();
+ unsigned char green = (m_doublePrecision) ? readU16()>>8 : readU8();
+ unsigned char blue = (m_doublePrecision) ? readU16()>>8 : readU8();
+ unsigned char alpha = (m_doublePrecision) ? readU16()>>8 : readU8();
+ WPGColor color(red, green, blue, alpha);
+ colors.push_back(color);
+ WPG_DEBUG_MSG((" Color #%d (RGBA): %d %d %d %d\n", i+1, red, green, blue, alpha));
+ }
+
+ for(unsigned j = 0; j < count-1; j++)
+ {
+ unsigned pos = readU16();
+ positions.push_back(TO_DOUBLE(pos));
+ WPG_DEBUG_MSG((" Position #%d : %d\n", j+1, pos));
+ }
+
+ // looks like Corel Presentations only create 2 colors gradient
+ // and they are actually in reverse order
+ if(count == 2)
+ {
+ double xref = (double)m_gradientRef.x/65536.0;
+ double yref = (double)m_gradientRef.y/65536.0;
+ double angle = m_gradientAngle*M_PI/180.0;
+ double tanangle = tan(angle);
+ double ref = (tanangle<1e2) ? (yref+xref*tanangle)/(1+tanangle) : xref;
+ WPGGradient gradient;
+ gradient.setAngle(-m_gradientAngle); // upside down
+ gradient.addStop(0, colors[1]);
+ gradient.addStop(ref, colors[0]);
+ if((m_gradientRef.x != 65535) && (m_gradientRef.y != 65536))
+ gradient.addStop(1, colors[1]);
+ m_brush.gradient = gradient;
+ m_brush.style = WPGBrush::Gradient;
+ }
+ }
}
void WPG2Parser::handleBrushBackColor()
if(m_brush.style == WPGBrush::NoBrush)
m_brush.style = WPGBrush::Solid;
- WPG_DEBUG_MSG(("BrushBackColor\n"));
WPG_DEBUG_MSG((" Backround color (RGBA): %d %d %d %d\n", red, green, blue, alpha));
}
if(m_brush.style == WPGBrush::NoBrush)
m_brush.style = WPGBrush::Solid;
- WPG_DEBUG_MSG(("PenBackColor\n"));
WPG_DEBUG_MSG((" Background color (RGBA): %d %d %d %d\n", red, green, blue, alpha));
}
// TODO
- WPG_DEBUG_MSG(("BrushPattern\n"));
WPG_DEBUG_MSG((" Pattern : %d\n", pattern));
}
parseCharacterization(&objCh);
m_matrix = objCh.matrix;
+ bool insideCompound = m_groupStack.empty() ? false :
+ m_groupStack.top().isCompoundPolygon();
+
+ // inside a compound, so take the parent transformation into account
+ if(insideCompound)
+ m_matrix.transformBy(m_groupStack.top().compoundMatrix);
+
unsigned long count = readU16();
WPGPointArray points;
points.add(p);
}
- m_painter->setBrush( objCh.filled ? m_brush : WPGBrush() );
- m_painter->setPen( objCh.framed ? m_pen : WPGPen() );
- if(objCh.windingRule)
- m_painter->setFillRule(WPGPaintInterface::WindingFill);
+ if(insideCompound)
+ {
+ if(count > 0)
+ {
+ // inside a compound ? convert it into path because for compound
+ // we will only use paths
+ WPGPath& path = m_groupStack.top().compoundPath;
+ path.moveTo(points[0]);
+ for(unsigned long ii = 1; ii < count; ii++)
+ path.lineTo(points[ii]);
+ }
+ }
else
- m_painter->setFillRule(WPGPaintInterface::AlternatingFill);
- m_painter->drawPolygon(points);
+ {
+ // otherwise draw directly
+ m_painter->setBrush( objCh.filled ? m_brush : WPGBrush() );
+ m_painter->setPen( objCh.framed ? m_pen : WPGPen() );
+ if(objCh.windingRule)
+ m_painter->setFillRule(WPGPaintInterface::WindingFill);
+ else
+ m_painter->setFillRule(WPGPaintInterface::AlternatingFill);
+ m_painter->drawPolygon(points);
+ }
- WPG_DEBUG_MSG(("Polyline\n"));
WPG_DEBUG_MSG((" Vertices count : %d\n", count));
- for(int j = 0; j < count; j++ )
+ for(unsigned int j = 0; j < count; j++ )
WPG_DEBUG_MSG((" Point #%d : %g,%g\n", j+1, points[j].x, points[j].y));
}
parseCharacterization(&objCh);
m_matrix = objCh.matrix;
+ bool insideCompound = m_groupStack.empty() ? false :
+ m_groupStack.top().isCompoundPolygon();
+
+ // inside a compound, so take the parent transformation into account
+ if(insideCompound)
+ m_matrix.transformBy(m_groupStack.top().compoundMatrix);
+
unsigned int count = readU16();
WPGPointArray vertices;
}
WPGPath path;
+ path.closed = objCh.closed;
path.moveTo(vertices[0]);
for(unsigned j = 1; j < vertices.count(); j++)
path.curveTo(controlPoints[j*2-2], controlPoints[j*2-1], vertices[j]);
- m_painter->setBrush( objCh.filled ? m_brush : WPGBrush() );
- m_painter->setPen( objCh.framed ? m_pen : WPGPen() );
- if(objCh.windingRule)
- m_painter->setFillRule(WPGPaintInterface::WindingFill);
+ if(insideCompound)
+ // inside a compound ? just collect the path together
+ m_groupStack.top().compoundPath.append(path);
else
- m_painter->setFillRule(WPGPaintInterface::AlternatingFill);
- m_painter->drawPath(path);
+ {
+ // otherwise draw directly
+ m_painter->setBrush( objCh.filled ? m_brush : WPGBrush() );
+ m_painter->setPen( objCh.framed ? m_pen : WPGPen() );
+ if(objCh.windingRule)
+ m_painter->setFillRule(WPGPaintInterface::WindingFill);
+ else
+ m_painter->setFillRule(WPGPaintInterface::AlternatingFill);
+ m_painter->drawPath(path);
+ }
}
void WPG2Parser::handleRectangle()
m_painter->setPen( objCh.framed ? m_pen : WPGPen() );
m_painter->drawRectangle(rect, roundx, roundy);
- WPG_DEBUG_MSG(("Rectangle\n"));
WPG_DEBUG_MSG((" X1 : %d\n", x1));
WPG_DEBUG_MSG((" Y1 : %d\n", y1));
WPG_DEBUG_MSG((" X2 : %d\n", x2));
m_painter->drawEllipse(center, rx, ry);
}
- WPG_DEBUG_MSG(("Arc\n"));
WPG_DEBUG_MSG((" Center point x : %d\n", cx));
WPG_DEBUG_MSG((" Center point y : %d\n", cy));
WPG_DEBUG_MSG((" Radius x : %d\n", radx));
diff --git a/src/extension/internal/libwpg/WPG2Parser.h b/src/extension/internal/libwpg/WPG2Parser.h
index e472ccee07e99dcbf1d336a73977730921ba3d9e..8fd0ab4cc970a1be1809d81131890d359463aab0 100644 (file)
rect.y2 = element[0][1]*r.x2 + element[1][1]*r.y2 + element[2][1];
return rect;
}
+
+ WPG2TransformMatrix& transformBy(const WPG2TransformMatrix& m)
+ {
+ double result[3][3];
+
+ for(int i = 0; i < 3; i++)
+ for(int j = 0; j < 3; j++)
+ {
+ result[i][j] = 0;
+ for(int k = 0; k < 3; k++)
+ result[i][j] += m.element[i][k]*element[k][j];
+ }
+
+ for(int x = 0; x < 3; x++)
+ for(int y = 0; y < 3; y++)
+ element[x][y] = result[x][y];
+
+ return *this;
+ }
};
class WPGCompoundPolygon
WPGCompoundPolygon(): matrix(), isFilled(true), isFramed(true), isClosed(true) {}
};
+class WPGGroupContext
+{
+public:
+ unsigned subIndex;
+ int parentType;
+ WPGPath compoundPath;
+ WPG2TransformMatrix compoundMatrix;
+ bool compoundWindingRule;
+ bool compoundFilled;
+ bool compoundFramed;
+ bool compoundClosed;
+
+ WPGGroupContext(): subIndex(0), parentType(0),
+ compoundPath(), compoundMatrix(), compoundWindingRule(false),
+ compoundFilled(false), compoundFramed(true), compoundClosed(false) {}
+
+ bool isCompoundPolygon() const { return parentType == 0x1a; }
+};
+
class WPG2Parser : public WPGXParser
{
public:
void handleArc();
void resetPalette();
+ void flushCompoundPolygon();
// parsing context
bool m_success;
WPG2TransformMatrix m_matrix;
double m_gradientAngle;
WPGPoint m_gradientRef;
- unsigned m_subIndex;
- std::stack<unsigned> m_indexStack;
-
- WPGCompoundPolygon m_currentCompound;
- std::stack<WPGCompoundPolygon> m_compoundStack;
+ std::stack<WPGGroupContext> m_groupStack;
+ WPG2TransformMatrix m_compoundMatrix;
+ bool m_compoundWindingRule;
+ bool m_compoundFilled;
+ bool m_compoundFramed;
+ bool m_compoundClosed;
class ObjectCharacterization;
void parseCharacterization(ObjectCharacterization*);
index c04754d4248f7b987c42b6a4edd7fa9033c3cac3..a69ff3f72319fa5c65afe531996cb52d06b7739a 100644 (file)
WPGPath::WPGPath()
{
d = new WPGPathPrivate;
+ closed = true;
}
WPGPath::~WPGPath()
{
d->elements.push_back(element);
}
-
+
+void WPGPath::append(const WPGPath& path)
+{
+ for(unsigned i = 0; i < path.count(); i++)
+ addElement(path.element(i));
+}
index 889d4789c6ce448af5f1ddb46fbad0745b2a735f..85fcc5c8fc98918a2cd2a033d9a71ca42c5fbda1 100644 (file)
class WPGPath
{
public:
+
+ bool closed;
WPGPath();
void addElement(const WPGPathElement& element);
+ void append(const WPGPath& path);
+
private:
WPGPathPrivate *d;
};
index fc730a3ce6c03369e758d4042645dcb3206b5916..28e9476149c4c3bb736773b4b900c91c13c37fd1 100644 (file)
break;\r
}\r
}\r
+ \r
+ if(path.closed)\r
+ printf("Z");\r
+\r
printf("\" \n");\r
writeStyle();\r
printf("/>\n");\r