From: Ariya H. <ar...@us...> - 2006-06-17 08:13:14
|
Update of /cvsroot/libwpg/libwpg/src/conv/svg In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv14544/src/conv/svg Modified Files: main.cpp Log Message: - important records for WPG2 (pen, brush, lines, curve) - the listener is now PaintInterface, using PostScript-like rendering model - simplified SVG generation (due to the above PaintInterface) - fixed coding style to follow libwpd (tab-indentation, camelcase function names, correct file names, ...) - fixed FSF address - added notices on implementation details (first commit for my Google Summer of Code project) Index: main.cpp =================================================================== RCS file: /cvsroot/libwpg/libwpg/src/conv/svg/main.cpp,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- main.cpp 29 Apr 2006 19:56:53 -0000 1.9 +++ main.cpp 17 Jun 2006 08:11:53 -0000 1.10 @@ -1,4 +1,5 @@ /* libwpg + * Copyright (C) 2006 Ariya Hidayat (ar...@kd...) * Copyright (C) 2005 Fridrich Strba (fri...@bl...) * * This library is free software; you can redistribute it and/or @@ -22,165 +23,201 @@ * Corel Corporation or Corel Corporation Limited." */ -#include <gsf/gsf-utils.h> -#include <gsf/gsf-input-stdio.h> #include <stdio.h> -#include <libwpg.h> -class SvgListener : public WPGListener { +#include "libwpg.h" + +using namespace libwpg; + +class SvgPainter : public libwpg::WPGPaintInterface { public: - SvgListener() : m_imageHeight(0.0f) {} + SvgPainter(); + void startDocument(double imageWidth, double imageHeight); + void setPen(const WPGPen& pen); + void setBrush(const WPGBrush& brush); + void drawPolyline(const WPGPointArray& vertices); + void drawCurve(const WPGPointArray& vertices, const WPGPointArray& controlPoints); + void drawRectangle(const WPGRect& rect, double rx, double ry); + void drawEllipse(const WPGPoint& center, double rx, double ry); + void startLayer(unsigned int id); + void endLayer(unsigned int id); + void endDocument(); - void StartDocument(const float imageWidth, const float imageHeight) { - m_imageHeight = imageHeight; - printf("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"); - printf("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"); - printf("<svg width=\"%.4f\" height=\"%.4f\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">", 72*imageWidth, 72*imageHeight); - } +private: + WPGPen m_pen; + WPGBrush m_brush; + void writeStyle(); +}; - void Line(const float startX, const float startY, const float endX, const float endY, const float lineWidth, - const unsigned char lineStyle, const RGBColor lineColor) { - printf("<line stroke=\""); - if (lineStyle == 0x00) - printf("none\" "); - else - printf("#%.2x%.2x%.2x\" ", lineColor.red, lineColor.green, lineColor.blue); - printf("stroke-width=\"%.4f\" fill=\"none\" x1=\"%.4f\" y1=\"%.4f\" x2=\"%.4f\"y2=\"%.4f\"/>", - 72*lineWidth, 72*startX, 72*(m_imageHeight - startY), 72*endX, 72*(m_imageHeight - endY)); - } +SvgPainter::SvgPainter() +{ +} - void Polyline(const std::vector <WPGPoint> &points, const float lineWidth, const unsigned char lineStyle, const RGBColor lineColor) { - printf("<polyline stroke=\""); - if (lineStyle == 0x00) - printf("none\" "); - else - printf("#%.2x%.2x%.2x\" ", lineColor.red, lineColor.green, lineColor.blue); - printf("stroke-width=\"%.4f\" fill=\"none\" points=\"", 72*lineWidth); - for (std::vector<WPGPoint>::const_iterator iter=points.begin(); iter != points.end(); iter++) { - if (iter != points.begin()) - printf(" "); - printf("%.4f,%4f", 72*(*iter).x, 72*(m_imageHeight - (*iter).y)); - } - printf("\"/>"); - } +void SvgPainter::startDocument(double width, double height) +{ + printf("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); + printf("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\""); + printf(" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); - void Rectangle(const float startX, const float startY, const float width, const float height, const float lineWidth, - const unsigned char lineStyle, const RGBColor lineColor, const unsigned char fillStyle, const RGBColor fillColor) { - printf("<rect stroke=\""); - if (lineStyle == 0x00) - printf("none\" "); - else - printf("#%.2x%.2x%.2x\" ", lineColor.red, lineColor.green, lineColor.blue); - printf("fill=\""); - if (fillStyle == 0x00) - printf("none\" "); - else - printf("#%.2x%.2x%.2x\" ", fillColor.red, fillColor.green, fillColor.blue); - printf("stroke-width=\"%.4f\" x=\"%.4f\" y=\"%.4f\" width=\"%.4f\" height=\"%.4f/>", - 72*lineWidth, 72*startX, 72*(m_imageHeight - startY), 72*width, 72*( -height)); - } + printf("<!-- Created with wpg2svg/libwpg %s -->\n", LIBWPG_VERSION_STRING); - void Polygon(const std::vector <WPGPoint> &points, const float lineWidth, const unsigned char lineStyle, const RGBColor lineColor, - const unsigned char fillStyle, const RGBColor fillColor) { - printf("<polygon stroke=\""); - if (lineStyle == 0x00) - printf("none\" "); - else - printf("#%.2x%.2x%.2x\" ", lineColor.red, lineColor.green, lineColor.blue); - printf("fill=\""); - if (fillStyle == 0x00) - printf("none\" "); - else - printf("#%.2x%.2x%.2x\" ", fillColor.red, fillColor.green, fillColor.blue); - printf("stroke-width=\"%.4f\" points=\"", 72*lineWidth); - for (std::vector<WPGPoint>::const_iterator iter=points.begin(); iter != points.end(); iter++) { - if (iter != points.begin()) - printf(" "); - printf("%.4f,%4f", 72*(*iter).x, 72*(m_imageHeight - (*iter).y)); - } - printf("\"/>"); - } + printf("<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" "); + printf("width=\"%g\" height=\"%f\" >\n", 72*width, 72*height); +} - void Ellipse(const float centerX, const float centerY, const float radiusX, const float radiusY, const unsigned int rotationAngle, - const float lineWidth, const unsigned char lineStyle, const RGBColor lineColor, const unsigned char fillStyle, const RGBColor fillColor) { - printf("<ellipse stroke=\""); - if (lineStyle == 0x00) - printf("none\" "); - else - printf("#%.2x%.2x%.2x\" ", lineColor.red, lineColor.green, lineColor.blue); - printf("fill=\""); - if (fillStyle == 0x00) - printf("none\" "); - else - printf("#%.2x%.2x%.2x\" ", fillColor.red, fillColor.green, fillColor.blue); - printf("stroke-width=\"%.4f\" ", 72*lineWidth); - if (rotationAngle != 0) - printf("transform=\"rotate(%i)\" ", 360-rotationAngle); - printf("cx=\"%.4f\" cy=\"%.4f\" rx=\"%.4f\" ry=\"%.4f\"/>", - 72*centerX, 72*(m_imageHeight - centerY), 72*radiusX, 72*radiusY); - } +void SvgPainter::setPen(const WPGPen& pen) +{ + m_pen = pen; +} - void EndDocument() { - printf("</svg>"); - } -private: - float m_imageHeight; -}; +void SvgPainter::setBrush(const WPGBrush& brush) +{ + m_brush = brush; +} -int main(int argc, char *argv[]) +// create "style" attribute based on current pen and brush +void SvgPainter::writeStyle() { - if (argc < 2) + printf("style=\""); + + const WPGColor& color = m_pen.foreColor; + printf("stroke-width: %f; ", 72*m_pen.width); + if(m_pen.width > 0.0) { - printf("usage: wpg2svg <WordPerfect Graphic>\n"); - return -1; + printf("stroke: rgb(%d,%d,%d); ", color.red, color.green, color.blue); + if(color.alpha != 0) + // alpha = 0 means opacity = 1.0, alpha = 256 means opacity = 0 + printf("stroke-opacity: %f; ", 1.0-(color.alpha/256.0)); } - gsf_init(); - GError *err; - GsfInput * input = GSF_INPUT(gsf_input_stdio_new (argv[1], &err)); - if (input == NULL) + if(!m_pen.solid) + { + printf("stroke-dasharray: "); + for(int i = 0; i < m_pen.dashArray.count(); i++) { - g_return_val_if_fail (err != NULL, 1); - - g_warning ("'%s' error: %s", argv[1], err->message); - g_error_free (err); - return 1; + printf("%f", 72*m_pen.dashArray.at(i)*m_pen.width); + if(i < m_pen.dashArray.count()-1) + printf(", "); } + printf("; "); + } + + if(m_brush.style == WPGBrush::NoBrush) + printf("fill: none; "); - WPGraphics * wpg = new(WPGraphics); + if(m_brush.style == WPGBrush::Solid) + printf("fill: rgb(%d,%d,%d); ", m_brush.foreColor.red, + m_brush.foreColor.green, m_brush.foreColor.blue); - bool isSupportedFormat = wpg->libwpg_file_supported(input); - if (!isSupportedFormat) - { - printf("ERROR: Unsupported file format (unsupported version) or file is encrypted!\n"); - return 1; - } + printf("\""); // style +} - SvgListener listener; - try - { - wpg->libwpg_parse(input, &listener); - } - catch (WPGInvalidInputException) +void SvgPainter::drawPolyline(const WPGPointArray& vertices) +{ + if(vertices.count() < 2) + return; + + if(vertices.count() == 2) { - printf("ERROR: Invalid input given!\n"); - return 1; + const WPGPoint& p1 = vertices[0]; + const WPGPoint& p2 = vertices[1]; + printf("<line "); + printf("x1=\"%f\" y1=\"%f\" ", 72*p1.x, 72*p1.y); + printf("x2=\"%f\" y2=\"%f\"\n", 72*p2.x, 72*p2.y); + writeStyle(); + printf("/>\n"); } - catch (WPGEndOfFileException) + else { - printf("ERROR: Unexpected end of file!\n"); - return 1; + printf("<polyline "); + printf("points=\""); + for(unsigned i = 0; i < vertices.count(); i++) + { + printf("%f %f", 72*vertices[i].x, 72*vertices[i].y); + if(i < vertices.count()-1) printf(", "); + } + printf("\"\n"); + writeStyle(); + printf("/>\n"); } - catch (...) +} + +void SvgPainter::drawCurve(const WPGPointArray& vertices, const WPGPointArray& controlPoints) +{ + if(vertices.count() == 0) + return; + if(controlPoints.count() < vertices.count()*2-1) + return; + + printf("<path d=\""); + printf("M%f,%f \n", 72*vertices[0].x, 72*vertices[0].y ); + for(unsigned i = 1; i < vertices.count(); i++) { - printf("ERROR: Unknown Error!\n"); - return 1; + printf("C"); + printf("%f,%f ", 72*controlPoints[i*2-2].x, 72*controlPoints[i*2-2].y ); + printf("%f,%f ", 72*controlPoints[i*2-1].x, 72*controlPoints[i*2-1].y ); + printf("%f,%f", 72*vertices[i].x, 72*vertices[i].y ); + if(i < vertices.count()-1) + printf("\n"); } + printf("\" \n"); + writeStyle(); + printf("/>\n"); +} - gsf_shutdown(); +void SvgPainter::drawRectangle(const WPGRect& rect, double rx, double ry) +{ + printf("<rect "); + printf("x=\"%f\" y=\"%f\" ", 72*rect.x1, 72*rect.y1); + printf("width=\"%f\" height=\"%f\" ", 72*rect.width(), 72*rect.height()); + if((rx !=0) || (ry !=0)) + printf("rx=\"%f\" ry=\"%f\" ", 72*rx, 72*ry); + writeStyle(); + printf("/>\n"); +} - if (wpg) - delete wpg; +void SvgPainter::drawEllipse(const WPGPoint& center, double rx, double ry) +{ + printf("<ellipse "); + printf("cx=\"%f\" cy=\"%f\" ", 72*center.x, 72*center.y); + printf("rx=\"%f\" ry=\"%f\" ", 72*rx, 72*ry); + writeStyle(); + printf("/>\n"); +} + +void SvgPainter::startLayer(unsigned int id) +{ + printf("<g id=\"Layer%d\" >\n", id); +} +void SvgPainter::endLayer(unsigned int) +{ + printf("</g>\n"); +} + +void SvgPainter::endDocument() +{ + printf("</svg>\n"); +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) + { + printf("usage: wpg2svg <WordPerfect Graphic>\n"); + return -1; + } + + const char* filename = argv[1]; + WPGFileStream* input = new WPGFileStream(filename); + if (!WPGraphics::isSupported(input)) + { + printf("ERROR: Unsupported file format (unsupported version) or file is encrypted!\n"); + return 1; + } + + SvgPainter painter; + WPGraphics::parse(input, &painter); + return 0; } |