Code

r13105@tres: ted | 2006-07-30 11:08:56 -0700
authorgouldtj <gouldtj@users.sourceforge.net>
Mon, 31 Jul 2006 05:14:00 +0000 (05:14 +0000)
committergouldtj <gouldtj@users.sourceforge.net>
Mon, 31 Jul 2006 05:14:00 +0000 (05:14 +0000)
 Copying in libwpg as it seems they have no releases.

33 files changed:
src/extension/internal/libwpg/.cvsignore [new file with mode: 0644]
src/extension/internal/libwpg/Makefile.am [new file with mode: 0644]
src/extension/internal/libwpg/WPG1Parser.cpp [new file with mode: 0644]
src/extension/internal/libwpg/WPG1Parser.h [new file with mode: 0644]
src/extension/internal/libwpg/WPG2Parser.cpp [new file with mode: 0644]
src/extension/internal/libwpg/WPG2Parser.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGBrush.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGColor.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGGradient.cpp [new file with mode: 0644]
src/extension/internal/libwpg/WPGGradient.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGHeader.cpp [new file with mode: 0644]
src/extension/internal/libwpg/WPGHeader.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGOLEStream.cpp [new file with mode: 0644]
src/extension/internal/libwpg/WPGOLEStream.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGPaintInterface.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGPath.cpp [new file with mode: 0644]
src/extension/internal/libwpg/WPGPath.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGPen.cpp [new file with mode: 0644]
src/extension/internal/libwpg/WPGPen.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGPoint.cpp [new file with mode: 0644]
src/extension/internal/libwpg/WPGPoint.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGRect.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGStream.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGStreamImplementation.cpp [new file with mode: 0644]
src/extension/internal/libwpg/WPGStreamImplementation.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGXParser.cpp [new file with mode: 0644]
src/extension/internal/libwpg/WPGXParser.h [new file with mode: 0644]
src/extension/internal/libwpg/WPGraphics.cpp [new file with mode: 0644]
src/extension/internal/libwpg/WPGraphics.h [new file with mode: 0644]
src/extension/internal/libwpg/libwpg-stream.rc.in [new file with mode: 0644]
src/extension/internal/libwpg/libwpg.h.in [new file with mode: 0644]
src/extension/internal/libwpg/libwpg.rc.in [new file with mode: 0644]
src/extension/internal/libwpg/libwpg_utils.h [new file with mode: 0644]

diff --git a/src/extension/internal/libwpg/.cvsignore b/src/extension/internal/libwpg/.cvsignore
new file mode 100644 (file)
index 0000000..b49f6ba
--- /dev/null
@@ -0,0 +1,8 @@
+.deps
+.libs
+libwpg.h
+Makefile
+Makefile.in
+*.lo
+*.rc
+*.la
diff --git a/src/extension/internal/libwpg/Makefile.am b/src/extension/internal/libwpg/Makefile.am
new file mode 100644 (file)
index 0000000..e8b4495
--- /dev/null
@@ -0,0 +1,100 @@
+EXTRA_DIST = \
+       libwpg.h.in \
+       libwpg.rc.in \
+       libwpg-stream.rc.in
+
+# These may be in the builddir too
+BUILD_EXTRA_DIST = \
+       libwpg.rc \
+       libwpg-stream.rc        
+       
+if PLATFORM_WIN32
+no_undefined = -no-undefined
+version_info = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) 
+else
+no_undefined =
+version_info = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
+endif
+
+if OS_WIN32
+install-libtool-import-lib:
+       $(INSTALL) .libs/libwpg-1.dll.a $(DESTDIR)$(libdir)
+       $(INSTALL) .libs/libwpg-stream-1.dll.a $(DESTDIR)$(libdir)
+
+uninstall-libtool-import-lib:
+       -rm $(DESTDIR)$(libdir)/libwpg-1.dll.a
+       -rm $(DESTDIR)$(libdir)/libwpg-stream-1.dll.a
+       
+else
+install-libtool-import-lib:
+uninstall-libtool-import-lib:
+endif
+
+lib_LTLIBRARIES = libwpg-1.la libwpg-stream-1.la
+libwpg_1_includedir = $(includedir)/libwpg-1/libwpg
+libwpg_1_include_HEADERS = \
+       libwpg.h \
+       WPGraphics.h \
+       WPGColor.h \
+       WPGPen.h \
+       WPGBrush.h \
+       WPGGradient.h \
+       WPGPoint.h \
+       WPGRect.h \
+       WPGPath.h \
+       WPGStream.h \
+       WPGPaintInterface.h 
+
+AM_CXXFLAGS = $(LIBWPG_CXXFLAGS) $(DEBUG_CXXFLAGS)
+
+libwpg_1_la_LIBADD  = $(LIBWPG_LIBS) @LIBWPG_WIN32_RESOURCE@
+libwpg_1_la_DEPENDENCIES = @LIBWPG_WIN32_RESOURCE@
+libwpg_1_la_LDFLAGS = $(version_info) -export-dynamic $(no_undefined)
+libwpg_1_la_SOURCES = \
+       WPGraphics.cpp \
+       WPGPen.cpp \
+       WPGGradient.cpp \
+       WPGPoint.cpp \
+       WPGPath.cpp \
+       WPGHeader.cpp \
+       WPGXParser.cpp \
+       WPG1Parser.cpp \
+       WPG2Parser.cpp \
+       libwpg.h \
+       libwpg_utils.h \
+       WPGColor.h \
+       WPGPen.h \
+       WPGBrush.h \
+       WPGPath.h \
+       WPGGradient.h \
+       WPGHeader.h \
+       WPGXParser.h \
+       WPG1Parser.h \
+       WPG2Parser.h \
+       WPGPaintInterface.h 
+
+libwpg_stream_1_includedir = $(includedir)/libwpg-1/libwpg
+libwpg_stream_1_include_HEADERS = WPGStreamImplementation.h
+
+libwpg_stream_1_la_LIBADD  = $(LIBWPG_LIBS) @LIBWPG_STREAM_WIN32_RESOURCE@
+libwpg_stream_1_la_DEPENDENCIES = @LIBWPG_STREAM_WIN32_RESOURCE@
+libwpg_stream_1_la_LDFLAGS = $(version_info) -export-dynamic $(no_undefined)
+libwpg_stream_1_la_SOURCES = \
+       WPGOLEStream.cpp \
+       WPGStreamImplementation.cpp \
+       WPGOLEStream.h
+
+if OS_WIN32
+
+@LIBWPG_WIN32_RESOURCE@ : libwpg.rc
+       $(top_srcdir)/build/win32/lt-compile-resource libwpg.rc @LIBWPG_WIN32_RESOURCE@
+
+@LIBWPG_STREAM_WIN32_RESOURCE@ : libwpg.rc
+       $(top_srcdir)/build/win32/lt-compile-resource libwpg-stream.rc @LIBWPG_STREAM_WIN32_RESOURCE@
+
+endif
+
+
+install-data-local: install-libtool-import-lib
+
+uninstall-local: uninstall-libtool-import-lib
diff --git a/src/extension/internal/libwpg/WPG1Parser.cpp b/src/extension/internal/libwpg/WPG1Parser.cpp
new file mode 100644 (file)
index 0000000..372aa05
--- /dev/null
@@ -0,0 +1,424 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "WPG1Parser.h"
+#include "WPGPaintInterface.h"
+#include "libwpg_utils.h"
+
+static const unsigned char defaultWPG1PaletteRed[] = {
+       0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x7F,
+       0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x00, 0x14, 0x20, 0x2C, 0x38, 0x45, 0x51, 0x61,
+       0x71, 0x82, 0x92, 0xA2, 0xB6, 0xCB, 0xE3, 0xFF,
+       0x00, 0x41, 0x7D, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0x7D, 0x41,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x7D, 0x9E, 0xBE, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xBE, 0x9E,
+       0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D,
+       0xB6, 0xC7, 0xDB, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xDB, 0xC7,
+       0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
+       0x00, 0x1C, 0x38, 0x55, 0x71, 0x71, 0x71, 0x71,
+       0x71, 0x71, 0x71, 0x71, 0x71, 0x55, 0x38, 0x1C,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x38, 0x45, 0x55, 0x61, 0x71, 0x71, 0x71, 0x71,
+       0x71, 0x71, 0x71, 0x71, 0x71, 0x61, 0x55, 0x45,
+       0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+       0x51, 0x59, 0x61, 0x69, 0x71, 0x71, 0x71, 0x71,
+       0x71, 0x71, 0x71, 0x71, 0x71, 0x69, 0x61, 0x59,
+       0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+       0x00, 0x10, 0x20, 0x30, 0x41, 0x41, 0x41, 0x41,
+       0x41, 0x41, 0x41, 0x41, 0x41, 0x30, 0x20, 0x10,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x20, 0x28, 0x30, 0x38, 0x41, 0x41, 0x41, 0x41,
+       0x41, 0x41, 0x41, 0x41, 0x41, 0x38, 0x30, 0x28,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x3C, 0x30, 0x34, 0x3C, 0x41, 0x41, 0x41, 0x41,
+       0x41, 0x41, 0x41, 0x41, 0x41, 0x3C, 0x34, 0x30,
+       0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const unsigned char defaultWPG1PaletteGreen[] = {
+       0x00, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x3F, 0x7F,
+       0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
+       0x00, 0x14, 0x20, 0x2C, 0x38, 0x45, 0x51, 0x61,
+       0x71, 0x82, 0x92, 0xA2, 0xB6, 0xCB, 0xE3, 0xFF,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x41, 0x7D, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0x7D, 0x41,
+       0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D,
+       0x7D, 0x9E, 0xBE, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xBE, 0x9E,
+       0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
+       0xB6, 0xC7, 0xDB, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xDB, 0xC7,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x1C, 0x38, 0x55, 0x71, 0x71, 0x71, 0x71,
+       0x71, 0x71, 0x71, 0x71, 0x71, 0x55, 0x38, 0x1C,
+       0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+       0x38, 0x45, 0x55, 0x61, 0x71, 0x71, 0x71, 0x71,
+       0x71, 0x71, 0x71, 0x71, 0x71, 0x61, 0x55, 0x45,
+       0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+       0x51, 0x59, 0x61, 0x69, 0x71, 0x71, 0x71, 0x71,
+       0x71, 0x71, 0x71, 0x71, 0x71, 0x69, 0x61, 0x59,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x10, 0x20, 0x30, 0x41, 0x41, 0x41, 0x41,
+       0x41, 0x41, 0x41, 0x41, 0x41, 0x30, 0x20, 0x10,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x28, 0x30, 0x38, 0x41, 0x41, 0x41, 0x41,
+       0x41, 0x41, 0x41, 0x41, 0x41, 0x38, 0x30, 0x28,
+       0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
+       0x3C, 0x30, 0x34, 0x3C, 0x41, 0x41, 0x41, 0x41,
+       0x41, 0x41, 0x41, 0x41, 0x41, 0x3C, 0x34, 0x30,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const unsigned char defaultWPG1PaletteBlue[] = {
+       0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F,
+       0xC0, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
+       0x00, 0x14, 0x20, 0x2C, 0x38, 0x45, 0x51, 0x61,
+       0x71, 0x82, 0x92, 0xA2, 0xB6, 0xCB, 0xE3, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0x7D, 0x41,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x41, 0x7D, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xBE, 0x9E,
+       0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D,
+       0x7D, 0x9E, 0xBE, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xDB, 0xC7,
+       0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
+       0xB6, 0xC7, 0xDB, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x71, 0x71, 0x71, 0x71, 0x71, 0x55, 0x38, 0x1C,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x1C, 0x38, 0x55, 0x71, 0x71, 0x71, 0x71,
+       0x71, 0x71, 0x71, 0x71, 0x71, 0x61, 0x55, 0x45,
+       0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+       0x38, 0x45, 0x55, 0x61, 0x71, 0x71, 0x71, 0x71,
+       0x71, 0x71, 0x71, 0x71, 0x71, 0x69, 0x61, 0x59,
+       0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+       0x51, 0x59, 0x61, 0x69, 0x71, 0x71, 0x71, 0x71,
+       0x41, 0x41, 0x41, 0x41, 0x41, 0x30, 0x20, 0x10,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x10, 0x20, 0x30, 0x41, 0x41, 0x41, 0x41,
+       0x41, 0x41, 0x41, 0x41, 0x41, 0x38, 0x30, 0x28,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x28, 0x30, 0x38, 0x41, 0x41, 0x41, 0x41,
+       0x41, 0x41, 0x41, 0x41, 0x41, 0x3C, 0x34, 0x30,
+       0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
+       0x2C, 0x30, 0x34, 0x3C, 0x41, 0x41, 0x41, 0x41,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+
+WPG1Parser::WPG1Parser(WPGInputStream *input, WPGPaintInterface* painter):
+       WPGXParser(input, painter),
+       m_success(true), m_exit(false),
+       m_width(0), m_height(0)
+{
+}
+
+bool WPG1Parser::parse()
+{
+       typedef void (WPG1Parser::*Method)();
+
+       struct RecordHandler
+       {
+               int type;
+               const char *name;
+               Method handler;
+       };
+
+       static const struct RecordHandler handlers[] =
+       {
+               { 0x01, "Fill Attributes",   &WPG1Parser::handleFillAttributes },        
+               { 0x02, "Line Attributes",   &WPG1Parser::handleLineAttributes },        
+               { 0x03, "Marker Atttibutes", 0 },        
+               { 0x04, "Polymarker",        0 },        
+               { 0x05, "Line",              &WPG1Parser::handleLine },  
+               { 0x06, "Polyline",          &WPG1Parser::handlePolyline },      
+               { 0x07, "Rectangle",         &WPG1Parser::handleRectangle },     
+               { 0x08, "Polygon",           &WPG1Parser::handlePolygon },       
+               { 0x09, "Ellipse",           &WPG1Parser::handleEllipse },       
+               { 0x0e, "Colormap",          &WPG1Parser::handleColormap },
+               { 0x0f, "Start WPG",         &WPG1Parser::handleStartWPG },
+               { 0x10, "End WPG",           &WPG1Parser::handleEndWPG },
+               { 0x00, 0, 0 } // end marker
+       };       
+
+       // initialization
+       m_success = true;
+       m_exit = false;
+       
+       // default style
+       m_pen.foreColor = WPGColor(0,0,0);
+       m_pen.backColor = WPGColor(0,0,0);
+       m_pen.width = 0.001;
+       m_pen.height = 0.001;
+       m_pen.solid = true;
+       m_pen.dashArray = WPGDashArray();
+       m_brush.foreColor = WPGColor(0,0,0);
+       m_brush.backColor = WPGColor(0,0,0);
+       resetPalette();
+
+       while(!m_input->atEnd())
+       {
+               long recordPos = m_input->tell();
+               int recordType = readU8();
+               int length = readVariableLengthInteger();
+               long nextPos = m_input->tell() + length;
+
+               // search function to handler this record
+               int index = -1;
+               for(int i = 0; (index < 0) && handlers[i].name; i++)
+                       if(handlers[i].type == recordType)
+                               index = i;
+                               
+               WPG_DEBUG_MSG(("\n"));
+               if(index < 0)
+                       WPG_DEBUG_MSG(("Unknown record type 0x%02x at %d  size %d\n", 
+                               recordType, recordPos, length));
+               else
+               {
+                       Method recordHandler = handlers[index].handler;
+                       if(!recordHandler)
+                               WPG_DEBUG_MSG(("Record '%s' (ignored) type 0x%02x at %d  size %d\n", 
+                                       handlers[index].name, recordType, recordPos, length));
+                       else
+                       {
+                               WPG_DEBUG_MSG(("Record '%s' type 0x%02x at %d  size %d\n", 
+                                       handlers[index].name, recordType, recordPos, length));
+                                       
+                               // invoke the handler for this record
+                               (this->*recordHandler)();
+                       }
+               }
+
+               //if(m_input->tell() > nextPos)
+               {
+                       //WPG_DEBUG_MSG(("Record 0x%x consumes more bytes than necessary!\n", recordType));
+                       WPG_DEBUG_MSG(("Current stream position: %d\n", m_input->tell()));
+               }
+       
+               if(m_exit) break;
+               
+               m_input->seek(nextPos);
+       }
+
+       return m_success;
+}
+
+void WPG1Parser::handleStartWPG()
+{
+       unsigned char version = readU8();
+       unsigned char bitFlags = readU8();
+       m_width = readU16();
+       m_height = readU16();
+
+       double width = (double)m_width / 1200.0;
+       double height = (double)m_height / 1200.0;
+       m_painter->startDocument(width, height);
+
+       WPG_DEBUG_MSG(("StartWPG\n"));
+}
+
+void WPG1Parser::handleEndWPG()
+{
+       m_painter->endDocument();
+       m_exit = true;
+       
+       WPG_DEBUG_MSG(("EndWPG\n"));
+}
+
+void WPG1Parser::handleColormap()
+{
+       unsigned startIndex = readU16();
+       unsigned numEntries = readU16();
+
+       WPG_DEBUG_MSG(("Colormap\n"));
+       for(int i = 0; i < numEntries; i++)
+       {
+               WPGColor color;
+               color.red = readU8();
+               color.green = readU8();
+               color.blue = readU8();
+               m_colorPalette[startIndex+i] = color;
+               WPG_DEBUG_MSG(("Index#%d: RGB %d %d %d\n", startIndex+i, color.red, color.green, color.blue));
+       }
+}
+
+void WPG1Parser::handleFillAttributes()
+{
+       unsigned char style = readU8();
+       unsigned char color = readU8();
+
+       if(style == 0)
+               m_brush.style = WPGBrush::NoBrush;
+       if(style == 1)
+               m_brush.style = WPGBrush::Solid;
+
+       m_brush.foreColor = m_colorPalette[color];
+
+       WPG_DEBUG_MSG(("Fill Attributes\n"));
+       WPG_DEBUG_MSG(("         Fill style: %d\n", style));
+       WPG_DEBUG_MSG(("   Fill color index: %d\n", color));
+}
+
+void WPG1Parser::handleLineAttributes()
+{
+       unsigned char style = readU8();
+       unsigned char color = readU8();
+       unsigned int width = readU16();
+
+       m_pen.solid = style != 0;
+       m_pen.foreColor = m_colorPalette[color];
+       m_pen.width = (double)width / 1200.0;
+
+       WPG_DEBUG_MSG(("Line Attributes\n"));
+       WPG_DEBUG_MSG(("         Line style: %d\n", style));
+       WPG_DEBUG_MSG(("   Line color index: %d\n", color));
+       WPG_DEBUG_MSG(("         Line width: %d\n", width));
+}
+
+void WPG1Parser::handleLine()
+{
+       int sx = readS16();
+       int sy = readS16();
+       int ex = readS16();
+       int ey = readS16();
+
+       WPGPointArray points;
+       points.add(WPGPoint((double)sx/1200.0, (double)(m_height-sy)/1200.0));
+       points.add(WPGPoint((double)ex/1200.0, (double)(m_height-ey)/1200.0));
+
+       m_painter->setBrush(m_brush);
+       m_painter->setPen(m_pen);
+       m_painter->drawPolygon(points);
+
+       WPG_DEBUG_MSG(("Line\n"));
+       WPG_DEBUG_MSG(("    Starting point: %d,%d\n", sx, sy));
+       WPG_DEBUG_MSG(("         End point: %d,%d\n", ex, ey));
+}
+
+void WPG1Parser::handlePolyline()
+{
+       unsigned int count = readU16();
+
+       WPGPointArray points;
+       for(unsigned int i = 0; i < count; i++ )
+       {
+               long x = readS16();
+               long y = readS16();
+               points.add(WPGPoint((double)x/1200.0, (double)(m_height-y)/1200.0));
+       }
+
+       m_painter->setBrush(WPGBrush()); // not filled
+       m_painter->setPen(m_pen);
+       m_painter->drawPolygon(points);
+
+       WPG_DEBUG_MSG(("Polyline\n"));
+}
+
+void WPG1Parser::handleRectangle()
+{
+       int x = readS16();
+       int y = readS16();
+       int w = readS16();
+       int h = readS16();
+
+       WPGRect rect;
+       rect.x1 = (double)x/1200.0;
+       rect.y1 = (double)(m_height-y)/1200.0;
+       rect.x2 = rect.x1 + (double)w/1200.0;
+       rect.y2 = rect.y1 + (double)h/1200.0;
+
+       m_painter->setBrush(m_brush);
+       m_painter->setPen(m_pen);
+       m_painter->drawRectangle(rect, 0, 0);
+
+       WPG_DEBUG_MSG(("Line\n"));
+       WPG_DEBUG_MSG(("    Corner point: %d,%d\n", x, y));
+       WPG_DEBUG_MSG(("           Width: %d\n", w));
+       WPG_DEBUG_MSG(("          Height: %d\n", h));
+}
+
+void WPG1Parser::handlePolygon()
+{
+       unsigned int count = readU16();
+
+       WPGPointArray points;
+       for(unsigned int i = 0; i < count; i++ )
+       {
+               long x = readS16();
+               long y = readS16();
+               points.add(WPGPoint((double)x/1200.0, (double)(m_height-y)/1200.0));
+       }
+
+       m_painter->setBrush(m_brush);
+       m_painter->setPen(m_pen);
+       m_painter->drawPolygon(points);
+
+       WPG_DEBUG_MSG(("Polygon\n"));
+}
+
+void WPG1Parser::handleEllipse()
+{
+       int cx = readS16();
+       int cy = readS16();
+       int rx = readS16();
+       int ry = readS16();
+
+       WPGPoint center;
+       center.x = (double)cx/1200.0;
+       center.y = (double)(m_height-cy)/1200.0;
+
+       double radx = (double)rx/1200.0;
+       double rady = (double)ry/1200.0;
+
+       m_painter->setBrush(m_brush);
+       m_painter->setPen(m_pen);
+       m_painter->drawEllipse(center, radx, rady);
+
+       WPG_DEBUG_MSG(("Ellipse\n"));
+       WPG_DEBUG_MSG(("    Center point: %d,%d\n", cx, cy));
+       WPG_DEBUG_MSG(("        Radius x: %d\n", rx));
+       WPG_DEBUG_MSG(("        Radius y: %d\n", ry));
+}
+
+void WPG1Parser::resetPalette()
+{
+       m_colorPalette.clear();
+       for (int i=0; i<256; i++)
+       {
+               WPGColor color;
+               color.red = defaultWPG1PaletteRed[i];
+               color.green = defaultWPG1PaletteGreen[i];
+               color.blue = defaultWPG1PaletteBlue[i];
+               m_colorPalette[i] = color;
+       }
+}
+
diff --git a/src/extension/internal/libwpg/WPG1Parser.h b/src/extension/internal/libwpg/WPG1Parser.h
new file mode 100644 (file)
index 0000000..fb23835
--- /dev/null
@@ -0,0 +1,66 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPG1PARSER_H__
+#define __WPG1PARSER_H__
+
+#include "WPGXParser.h"
+#include "WPGBrush.h"
+#include "WPGPen.h"
+
+class WPG1Parser : public WPGXParser
+{
+public:
+       WPG1Parser(WPGInputStream *input, WPGPaintInterface* painter);
+       bool parse();
+
+private:
+       void handleStartWPG();
+       void handleEndWPG();
+
+       void handleFillAttributes();
+       void handleLineAttributes();
+       void handleColormap();
+
+       void handleLine();
+       void handlePolyline();
+       void handleRectangle();
+       void handlePolygon();
+       void handleEllipse();
+       
+       void resetPalette();
+
+       // parsing context
+       bool m_success;
+       bool m_exit;
+       int m_width;
+       int m_height;
+       WPGPen m_pen;
+       WPGBrush m_brush;
+};
+
+#endif // __WPG1PARSER_H__
diff --git a/src/extension/internal/libwpg/WPG2Parser.cpp b/src/extension/internal/libwpg/WPG2Parser.cpp
new file mode 100644 (file)
index 0000000..43823d0
--- /dev/null
@@ -0,0 +1,1121 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "WPG2Parser.h"
+#include "WPGPaintInterface.h"
+#include "libwpg_utils.h"
+
+#include <math.h>
+#include <vector>
+
+// MSVC++ 6.0 does not have the macro defined, so we define it
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+static const unsigned char defaultWPG2PaletteRed[] = {
+       0x00, 0xFF, 0x7F, 0xBF, 0x00, 0x00, 0x00, 0x7F,
+       0x7F, 0x7F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
+       0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+       0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE9, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE9, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE9, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x3D, 0x48, 0x53, 0x5E, 0x69, 0x74, 0x7F, 0x8A,
+       0x95, 0xA0, 0xAB, 0xB6, 0xC1, 0xCC, 0xD7, 0xE2,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x3D, 0x48, 0x53, 0x5E, 0x69, 0x74, 0x7F, 0x8A,
+       0x95, 0xA0, 0xAB, 0xB6, 0xC1, 0xCC, 0xD7, 0xE2,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE4, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE4, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x33, 0x47, 0x61, 0x73, 0x87, 0x9C, 0xB0, 0xC7,
+       0xCC, 0xD4, 0xDB, 0xE3, 0xE8, 0xF0, 0xF7, 0xFF,
+};
+
+static const unsigned char defaultWPG2PaletteGreen[] = {
+       0x00, 0xFF, 0x7F, 0xBF, 0x00, 0x7F, 0x7F, 0x00,
+       0x00, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF,
+       0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+       0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x3D, 0x48, 0x53, 0x5E, 0x69, 0x74, 0x7F, 0x8A,
+       0x95, 0xA0, 0xAB, 0xB6, 0xC1, 0xCC, 0xD7, 0xE2,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE9, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE9, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE9, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE9, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE9, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x56, 0x64, 0x72, 0x80, 0x8E, 0x9C, 0xAA, 0xB1,
+       0xB8, 0xBF, 0xC6, 0xCD, 0xD4, 0xDB, 0xE2, 0xE9,
+       0x2B, 0x32, 0x39, 0x40, 0x47, 0x4E, 0x55, 0x63,
+       0x71, 0x7F, 0x8D, 0x9B, 0xA9, 0xB7, 0xC5, 0xD3,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x29, 0x38, 0x45, 0x4F, 0x5C, 0x63, 0x69, 0xD4,
+       0x87, 0x8F, 0x9C, 0xA8, 0xB3, 0xC4, 0xCF, 0xE0,
+};
+
+static const unsigned char defaultWPG2PaletteBlue[] = {
+       0x00, 0xFF, 0x7F, 0xBF, 0x7F, 0x00, 0x7F, 0x00,
+       0x7F, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
+       0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+       0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+       0x2C, 0x42, 0x58, 0x6E, 0x84, 0x9A, 0xB0, 0xC6,
+       0x3D, 0x48, 0x53, 0x5E, 0x69, 0x74, 0x7F, 0x8A,
+       0x95, 0xA0, 0xAB, 0xB6, 0xC1, 0xCC, 0xD7, 0xE2,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE9, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xB0, 0xD3, 0xE4, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE4, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE4, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE4, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x7B, 0x91, 0xA7, 0xBD, 0xD3, 0xE4, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0x3D, 0x48, 0x53, 0x5E, 0x69, 0x74, 0x7F, 0x8A,
+       0x95, 0xA0, 0xAB, 0xB6, 0xC1, 0xCC, 0xD7, 0xE2,
+       0x11, 0x17, 0x1C, 0x24, 0x29, 0x2B, 0x2B, 0x30,
+       0x47, 0x57, 0x69, 0x78, 0x8C, 0x9C, 0xB0, 0xC7,
+};
+
+class WPG2Parser::ObjectCharacterization
+{
+public:
+       bool taper;
+       bool translate;
+       bool skew;
+       bool scale;
+       bool rotate;
+       bool hasObjectId;
+       bool editLock;
+       bool windingRule;
+       bool filled;
+       bool closed;
+       bool framed;
+
+       unsigned long objectId;
+       unsigned long lockFlags;
+       long rotationAngle;
+       long sxcos;
+       long sycos;
+       long kxsin;
+       long kysin;
+       long txinteger;
+       short txfraction;
+       long tyinteger;
+       short tyfraction;
+       long px;
+       long py;
+
+       WPG2TransformMatrix matrix;
+
+       ObjectCharacterization():
+               taper(false),
+               translate(false),
+               skew(false),
+               scale(false),
+               rotate(false),
+               hasObjectId(false),
+               editLock(false),
+               objectId(0),
+               lockFlags(0),
+               windingRule(false),
+               filled(false),
+               closed(false),
+               framed(true),
+               rotationAngle(0),
+               sxcos(0),
+               sycos(0),
+               kxsin(0),
+               kysin(0),
+               txinteger(0),
+               txfraction(0),
+               tyinteger(0),
+               tyfraction(0),
+               px(0),
+               py(0)
+                       {}
+};
+
+WPG2Parser::WPG2Parser(WPGInputStream *input, WPGPaintInterface* painter):
+       WPGXParser(input, painter),
+       m_success(true), m_exit(false),
+       m_xres(1200), m_yres(1200),
+       m_xofs(0), m_yofs(0),
+       m_width(0), m_height(0),
+       m_doublePrecision(false),
+       m_layerOpened(false), m_layerId(0),
+       m_subIndex(0)
+{
+}
+
+bool WPG2Parser::parse()
+{
+       typedef void (WPG2Parser::*Method)();
+
+       struct RecordHandler
+       {
+               int type;
+               const char *name;
+               Method handler;
+       };
+
+       static const struct RecordHandler handlers[] =
+       {
+               { 0x01, "Start WPG",            &WPG2Parser::handleStartWPG },   
+               { 0x02, "End WPG",              &WPG2Parser::handleEndWPG },     
+               { 0x03, "Form Settings",        0 },     // ignored
+               { 0x04, "Ruler Settings",       0 },     // ignored
+               { 0x05, "Grid Settings",        0 },     // ignored
+               { 0x06, "Layer",                &WPG2Parser::handleLayer },
+               { 0x08, "Pen Style Definition", &WPG2Parser::handlePenStyleDefinition },
+               { 0x09, "Pattern Definition",   0 },
+               { 0x0a, "Comment",              0 },     // ignored
+               { 0x0b, "Color Transfer",       0 },
+               { 0x0c, "Color Palette",        &WPG2Parser::handleColorPalette },
+               { 0x0d, "DP Color Palette",     &WPG2Parser::handleDPColorPalette },
+               { 0x0e, "Bitmap Data",          0 },
+               { 0x0f, "Text Data",            0 },
+               { 0x10, "Chart Style",          0 },     // ignored
+               { 0x11, "Chart Data",           0 },     // ignored
+               { 0x12, "Object Image",         0 },
+               { 0x15, "Polyline",             &WPG2Parser::handlePolyline },
+               { 0x16, "Polyspline",           0 },
+               { 0x17, "Polycurve",            &WPG2Parser::handlePolycurve },
+               { 0x18, "Rectangle",            &WPG2Parser::handleRectangle },
+               { 0x19, "Arc",                  &WPG2Parser::handleArc },
+               { 0x1a, "Compound Polygon",     &WPG2Parser::handleCompoundPolygon },
+               { 0x1b, "Bitmap",               0 },
+               { 0x1c, "Text Line",            0 },
+               { 0x1d, "Text Block",           0 },
+               { 0x1e, "Text Path",            0 },
+               { 0x1f, "Chart",                0 },
+               { 0x20, "Group",                0 },
+               { 0x21, "Object Capsule",       0 },
+               { 0x22, "Font Settings",        0 },
+               { 0x25, "Pen Fore Color",       &WPG2Parser::handlePenForeColor },
+               { 0x26, "DP Pen Fore Color",    &WPG2Parser::handleDPPenForeColor },
+               { 0x27, "Pen Back Color",       &WPG2Parser::handlePenBackColor },
+               { 0x28, "DP Pen Back Color",    &WPG2Parser::handleDPPenBackColor },
+               { 0x29, "Pen Style",            &WPG2Parser::handlePenStyle },
+               { 0x2a, "Pen Pattern",          0 },
+               { 0x2b, "Pen Size",             &WPG2Parser::handlePenSize },
+               { 0x2c, "DP Pen Size",          &WPG2Parser::handleDPPenSize  },
+               { 0x2d, "Line Cap",             0 },
+               { 0x2e, "Line Join",            0 },
+               { 0x2f, "Brush Gradient",       &WPG2Parser::handleBrushGradient },
+               { 0x30, "DP Brush Gradient",    &WPG2Parser::handleDPBrushGradient },
+               { 0x31, "Brush Fore Color",     &WPG2Parser::handleBrushForeColor },
+               { 0x32, "DP Brush Fore Color",  &WPG2Parser::handleDPBrushForeColor },
+               { 0x33, "Brush Back Color",     &WPG2Parser::handleBrushBackColor },
+               { 0x34, "DP Brush Back Color",  &WPG2Parser::handleDPBrushBackColor },
+               { 0x35, "Brush Pattern",        &WPG2Parser::handleBrushPattern },
+               { 0x36, "Horizontal Line",      0 },
+               { 0x37, "Vertical Line",        0 },
+               { 0x38, "Poster Settings",      0 },
+               { 0x39, "Image State",          0 },
+               { 0x3a, "Envelope Definition",  0 },
+               { 0x3b, "Envelope",             0 },
+               { 0x3c, "Texture Definition",   0 },
+               { 0x3d, "Brush Texture",        0 },
+               { 0x3e, "Texture Alignment",    0 },
+               { 0x3f, "Pen Texture ",         0 },
+               { 0x00, 0, 0 } // end marker
+       };       
+
+       // initialization
+       m_success = true;
+       m_exit = false;
+       m_xres = m_yres = 1200;
+       m_doublePrecision = false;
+       m_layerOpened = false;
+       m_matrix = WPG2TransformMatrix();
+       m_subIndex = 0;
+       while(!m_indexStack.empty())
+               m_indexStack.pop();
+       
+       // default style
+       m_pen.foreColor = WPGColor(0,0,0);
+       m_pen.backColor = WPGColor(0,0,0);
+       m_pen.width = 0.001;
+       m_pen.height = 0.001;
+       m_pen.solid = true;
+       m_pen.dashArray = WPGDashArray();
+       m_brush.foreColor = WPGColor(0,0,0);
+       m_brush.backColor = WPGColor(0,0,0);
+       resetPalette();
+
+       while(!m_input->atEnd())
+       {
+               long recordPos = m_input->tell();
+               int recordClass = readU8();
+               int recordType = readU8();
+               int extension = readVariableLengthInteger();
+               int length = readVariableLengthInteger();
+               long nextPos = m_input->tell() + length;
+               
+               // inside a subgroup, one less sub record
+               if(m_subIndex > 0)
+                       m_subIndex--;
+
+               // search function to handler this record
+               int index = -1;
+               for(int i = 0; (index < 0) && handlers[i].name; i++)
+                       if(handlers[i].type == recordType)
+                               index = i;
+                               
+               WPG_DEBUG_MSG(("\n"));
+               if(index < 0)
+               {
+                       WPG_DEBUG_MSG(("Unknown record type 0x%02x at %d  size %d  extension %d\n", 
+                               recordType, recordPos, length, extension));
+               }
+               else
+               {
+                       Method recordHandler = handlers[index].handler;
+                       
+                       if(!recordHandler)
+                               WPG_DEBUG_MSG(("Record '%s' (ignored) type 0x%02x at %d  size %d  extension %d\n",
+                                       handlers[index].name, recordType, recordPos, length, extension));
+                       else
+                       {
+                               WPG_DEBUG_MSG(("Record '%s' type 0x%02x at %d  size %d  extension %d\n", 
+                                       handlers[index].name, recordType, recordPos, length, extension));
+                                       
+                               // invoke the handler for this record
+                               (this->*recordHandler)();
+                       }
+               }
+
+               // we enter another subgroup, save the index to stack
+               if(extension > 0)
+               {
+                       m_indexStack.push(m_subIndex);
+                       m_subIndex = extension;
+               }
+
+               //if(m_input->tell() > nextPos)
+               {
+                       //WPG_DEBUG_MSG(("Record 0x%x consumes more bytes than necessary!\n", recordType));
+                       WPG_DEBUG_MSG(("Current stream position: %d\n", m_input->tell()));
+               }
+       
+               if(m_exit) break;
+               
+               m_input->seek(nextPos);
+       }
+
+       return m_success;
+}
+
+static const char* describePrecision(unsigned char precision)
+{
+       const char* result = "Unknown";
+       switch(precision)
+       {
+               case 0: result = "single"; break;
+               case 1: result = "double"; break;
+               default: break;
+       }
+       return result;
+}
+       
+static const char* describeGradient(unsigned char gradientType)
+{
+       const char* result = "Unknown";
+       switch(gradientType)
+       {
+               case 0: result = "None"; break;
+               case 1: result = "Linear"; break;
+               case 2: result = "Polygonal"; break;
+               case 3: result = "Concentric Circles"; break;
+               case 4: result = "Convergent Circles"; break;
+               case 5: result = "Concentric Ellipses"; break;
+               case 6: result = "Convergent Ellipses"; break; 
+               case 7: result = "Concentric Squares"; break; 
+               case 8: result = "Convergent Squares"; break; 
+               case 9: result = "Concentric Rectangles"; break; 
+               case 10: result = "Convergent Rectangles"; break;
+               default: break;
+       }
+       return result;
+}
+
+#define TO_DOUBLE(x) ( (m_doublePrecision) ? ((double)(x)/65536.0) : (double)(x) )
+#define TRANSFORM_XY(x,y) { m_matrix.transform((x),(y)); (x)-= m_xofs; (y)-= m_yofs; (y)=m_height-(y); }
+
+void WPG2Parser::handleStartWPG()
+{
+       unsigned int horizontalUnit = readU16();
+       unsigned int verticalUnit = readU16();
+       unsigned char precision = readU8();
+       
+       // sanity check
+       m_xres = horizontalUnit;
+       m_yres = verticalUnit;
+       if((horizontalUnit==0) || (verticalUnit==0))
+       {
+               m_xres = m_yres = 1200;
+               WPG_DEBUG_MSG(("Warning ! Insane unit of measure"));
+       }
+       
+       // danger if we do not recognize the precision code
+       if(precision != 0)
+       if(precision != 1)
+       {
+               m_success = false;
+               m_exit = true;
+               return;
+       }
+       m_doublePrecision = (precision == 1);
+       
+       long viewportX1 = (m_doublePrecision) ? readS32() : readS16();
+       long viewportY1 = (m_doublePrecision) ? readS32() : readS16();
+       long viewportX2 = (m_doublePrecision) ? readS32() : readS16();
+       long viewportY2 = (m_doublePrecision) ? readS32() : readS16();
+       
+       long imageX1 = (m_doublePrecision) ? readS32() : readS16();
+       long imageY1 = (m_doublePrecision) ? readS32() : readS16();
+       long imageX2 = (m_doublePrecision) ? readS32() : readS16();
+       long imageY2 = (m_doublePrecision) ? readS32() : readS16();
+
+       // used to adjust coordinates   
+       m_xofs = (imageX1 < imageX2) ? imageX1 : imageX2;
+       m_yofs = (imageY1 < imageY2) ? imageY1 : imageX2;
+       m_width = (imageX2 > imageX1 ) ? imageX2-imageX1 : imageX1-imageX2;
+       m_height = (imageY2 > imageY1) ? imageY2-imageY1 : imageY1-imageY2;
+       
+       WPG_DEBUG_MSG(("StartWPG\n"));
+       WPG_DEBUG_MSG(("  Horizontal unit of measure : %d pixels/inch\n", horizontalUnit));
+       WPG_DEBUG_MSG(("    Vertical unit of measure : %d pixels/inch\n", verticalUnit));
+       WPG_DEBUG_MSG(("              Data precision : %d (%s)\n", precision, describePrecision(precision)));
+       WPG_DEBUG_MSG(("                 Viewport X1 : %d\n", viewportX1));
+       WPG_DEBUG_MSG(("                 Viewport Y1 : %d\n", viewportY1));
+       WPG_DEBUG_MSG(("                 Viewport X2 : %d\n", viewportX2));
+       WPG_DEBUG_MSG(("                 Viewport Y2 : %d\n", viewportY2));
+       WPG_DEBUG_MSG(("                    Image X1 : %d\n", imageX1));
+       WPG_DEBUG_MSG(("                    Image Y1 : %d\n", imageY1));
+       WPG_DEBUG_MSG(("                    Image X2 : %d\n", imageX2));
+       WPG_DEBUG_MSG(("                    Image Y2 : %d\n", imageY2));
+       WPG_DEBUG_MSG(("                    X offset : %d\n", m_xofs));
+       WPG_DEBUG_MSG(("                    Y offset : %d\n", m_yofs));
+       WPG_DEBUG_MSG(("                       width : %d\n", m_width));
+       WPG_DEBUG_MSG(("                      height : %d\n", m_height));
+       
+       double width = (TO_DOUBLE(m_width)) / m_xres;
+       double height = (TO_DOUBLE(m_height)) / m_yres;
+       
+       m_painter->startDocument(width, height);
+
+       static const int WPG2_defaultPenDashes[] = {
+               1,   291,  0,                            // style #0 (actually solid)
+               1,   218, 73,                            // style #1
+               1,   145, 73,                            // style #2
+               1,    73, 73,                            // style #3
+               1,    36, 36,                            // style #4
+               1,    18, 18,                            // style #5
+               1,    18, 55,                            // style #6
+               3,    18, 55,  18, 55, 18, 127,          // style #7
+               2,   164, 55,  18, 55,                   // style #8
+               3,   145, 36, 138, 36, 18,  36,          // style #9
+               3,    91, 55,  91, 55, 18,  55,          // style #10
+               4,    91, 36,  91, 36, 18,  36, 18, 36,  // style #11
+               2,   182, 73,  73, 73,                   // style #12
+               3,   182, 36,  55, 36, 55,  36,          // style #13
+               3,   255, 73, 255, 73, 73,  73,          // style #14
+               4,   273, 36, 273, 36, 55,  36, 55, 36,  // style #15
+               0 // end marker
+       };
+       
+       // create default pen styles
+       int styleNo = 0;
+       for(int i = 0; i < sizeof(WPG2_defaultPenDashes)/sizeof(WPG2_defaultPenDashes[0]);)
+       {
+               int segments = 2 * WPG2_defaultPenDashes[i++];
+               if(segments == 0) break;
+               WPGDashArray dashArray;
+               for(int j = 0; j < segments; j++, i++)
+                       dashArray.add(WPG2_defaultPenDashes[i]*3.6/218.0);
+               m_penStyles[styleNo] = dashArray;
+               styleNo++; 
+       }
+}
+
+void WPG2Parser::handleEndWPG()
+{
+       // sentinel
+       if(m_layerOpened)
+               m_painter->endLayer(m_layerId);
+
+       m_painter->endDocument();
+       m_exit = true;
+       
+       WPG_DEBUG_MSG(("EndWPG\n"));
+}
+
+void WPG2Parser::handleLayer()
+{
+       m_layerId = readU16();
+
+       // close previous one
+       if(m_layerOpened)
+               m_painter->endLayer(m_layerId);
+
+       m_painter->startLayer(m_layerId);
+       m_layerOpened = true;
+
+       WPG_DEBUG_MSG(("Layer\n"));
+       WPG_DEBUG_MSG(("  Id: %d\n", m_layerId));
+}
+
+void WPG2Parser::handleCompoundPolygon()
+{
+       ObjectCharacterization objCh;
+       parseCharacterization(&objCh);
+}
+
+void WPG2Parser::handlePenStyleDefinition()
+{
+       unsigned int style = readU16();
+       unsigned int segments = readU16();
+
+       WPGDashArray dashArray;
+       for(int i = 0; i < segments; i++)
+       {
+               unsigned int p = (m_doublePrecision) ? readU32() : readU16();
+               unsigned int q = (m_doublePrecision) ? readU32() : readU16();
+               dashArray.add(TO_DOUBLE(p)*3.6/218.0);
+               dashArray.add(TO_DOUBLE(q)*3.6/218.0);
+       }
+       m_penStyles[style] = dashArray;
+
+       WPG_DEBUG_MSG(("PenStyleDefinition\n"));
+       WPG_DEBUG_MSG(("          Style : %d\n", style));
+       WPG_DEBUG_MSG(("  Segment pairs : %d\n", segments));
+}
+
+// TODO
+void WPG2Parser::handlePatternDefinition()
+{
+       WPG_DEBUG_MSG(("PatternDefinition\n"));
+}
+
+void WPG2Parser::handleColorPalette()
+{
+       unsigned startIndex = readU16();
+       unsigned numEntries = readU16();
+
+       WPG_DEBUG_MSG(("Color Palette\n"));
+       for(int i = 0; i < numEntries; i++)
+       {
+               WPGColor color;
+               color.red = readU8();
+               color.green = readU8();
+               color.blue = readU8();
+               color.alpha = readU8();
+               m_colorPalette[startIndex+i] = color;
+               WPG_DEBUG_MSG(("Index#%d: RGB %d %d %d\n", startIndex+i, color.red, color.green, color.blue));
+       }
+}
+
+void WPG2Parser::handleDPColorPalette()
+{
+       unsigned startIndex = readU16();
+       unsigned numEntries = readU16();
+
+       WPG_DEBUG_MSG(("Color Palette\n"));
+       for(int i = 0; i < numEntries; i++)
+       {
+               WPGColor color;
+               color.red = readU16() >> 8 ;
+               color.green = readU16() >> 8 ;
+               color.blue = readU16() >> 8 ;
+               color.alpha = readU16() >> 8 ;
+               m_colorPalette[startIndex+i] = color;
+               WPG_DEBUG_MSG(("Index#%d: RGB %d %d %d\n", startIndex+i, color.red, color.green, color.blue));
+       }
+}
+
+void WPG2Parser::handlePenForeColor()
+{
+       unsigned char red = readU8();
+       unsigned char green = readU8();
+       unsigned char blue = readU8();
+       unsigned char alpha = readU8();
+
+       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));
+}
+
+void WPG2Parser::handleDPPenForeColor()
+{
+       // 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();
+
+       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));
+}
+
+void WPG2Parser::handlePenBackColor()
+{
+       unsigned char red = readU8();
+       unsigned char green = readU8();
+       unsigned char blue = readU8();
+       unsigned char alpha = readU8();
+
+       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));
+}
+
+void WPG2Parser::handleDPPenBackColor()
+{
+       // 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();
+
+       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));
+}
+
+void WPG2Parser::handlePenStyle()
+{
+       unsigned int style = readU16();
+
+       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()));
+}
+
+void WPG2Parser::handlePenSize()
+{
+       unsigned int width = readU16();
+       unsigned int height = readU16();
+
+       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));
+}
+
+void WPG2Parser::handleDPPenSize()
+{
+       unsigned long width = readU32();
+       unsigned long height = readU32();
+
+       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));
+}
+
+void WPG2Parser::handleBrushGradient()
+{
+       unsigned angleFraction = readU16();
+       unsigned angleInteger = readU16();
+       unsigned xref = readU16();
+       unsigned yref = readU16();
+       unsigned flag = readU16();
+       bool granular = flag & (1<<6);
+       bool anchor = flag & (1<<7);
+       
+       // TODO: get gradient extent
+       
+       m_gradientAngle = angleInteger + (double)angleFraction/65536.0;
+       m_gradientRef.x = xref;
+       m_gradientRef.y = yref;
+       
+       WPG_DEBUG_MSG(("       Gradient angle : %d.%d\n", angleInteger, angleFraction));
+       WPG_DEBUG_MSG(("   Gradient reference : %d.%d\n", xref, yref));
+       WPG_DEBUG_MSG(("   Granular : %s\n", (granular ? "yes" : "no")));
+       WPG_DEBUG_MSG(("   Anchored : %s\n", (anchor ? "yes" : "no")));
+}
+
+void WPG2Parser::handleDPBrushGradient()
+{
+       unsigned angleFraction = readU16();
+       unsigned angleInteger = readU16();
+       unsigned xref = readU16();
+       unsigned yref = readU16();
+       unsigned flag = readU16();
+       bool granular = flag & (1<<6);
+       bool anchor = flag & (1<<7);
+       
+       // TODO: get gradient extent (in double precision)
+       
+       m_gradientAngle = angleFraction + (double)angleInteger/65536.0;
+       m_gradientRef.x = xref;
+       m_gradientRef.y = yref;
+
+       WPG_DEBUG_MSG(("       Gradient angle : %d.%d\n", angleInteger, angleFraction));
+       WPG_DEBUG_MSG(("   Gradient reference : %d.%d\n", xref, yref));
+       WPG_DEBUG_MSG(("   Granular : %s\n", (granular ? "yes" : "no")));
+       WPG_DEBUG_MSG(("   Anchored : %s\n", (anchor ? "yes" : "no")));
+}
+
+void WPG2Parser::handleBrushForeColor()
+{
+       unsigned char gradientType = readU8();
+       WPG_DEBUG_MSG(("   Gradient type : %d (%s)\n", gradientType, describeGradient(gradientType)));
+
+       if(gradientType == 0)
+       {
+               unsigned char red = readU8();
+               unsigned char green = readU8();
+               unsigned char blue = readU8();
+               unsigned char alpha = 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;
+       }
+       else
+       {
+               unsigned count = readU16();
+               std::vector<WPGColor> colors;
+               std::vector<double> positions;
+               WPG_DEBUG_MSG(("  Gradient colors : %d\n", count));
+
+               for(unsigned i = 0; i < count; i++)
+               {
+                       unsigned char red = readU8();
+                       unsigned char green = readU8();
+                       unsigned char blue = readU8();
+                       unsigned char alpha = 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::handleDPBrushForeColor()
+{
+       unsigned char gradientType = readU8();
+
+       // 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();
+
+       m_brush.foreColor = WPGColor(red, green, blue, alpha);
+       if(m_brush.style == WPGBrush::NoBrush)
+               m_brush.style = WPGBrush::Solid;
+
+       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));
+}
+
+void WPG2Parser::handleBrushBackColor()
+{
+       unsigned char red = readU8();
+       unsigned char green = readU8();
+       unsigned char blue = readU8();
+       unsigned char alpha = readU8();
+
+       m_brush.backColor = WPGColor(red, green, blue, alpha);
+       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));
+}
+
+void WPG2Parser::handleDPBrushBackColor()
+{
+       // 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();
+
+       m_brush.backColor = WPGColor(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));
+}
+
+void WPG2Parser::handleBrushPattern()
+{
+       unsigned int pattern = readU16();
+
+       // TODO
+
+       WPG_DEBUG_MSG(("BrushPattern\n"));
+       WPG_DEBUG_MSG(("   Pattern : %d\n", pattern));
+}
+
+void WPG2Parser::parseCharacterization(ObjectCharacterization* ch)
+{
+       // sanity check
+       if(!ch) return;
+
+       // identity
+       ch->matrix = WPG2TransformMatrix();
+
+       unsigned int flags = readU16();
+       ch->taper = (flags & 0x01) != 0;
+       ch->translate = (flags & 0x02) != 0;
+       ch->skew = (flags & 0x04) != 0;
+       ch->scale = (flags & 0x08) != 0;
+       ch->rotate = (flags & 0x10) != 0;
+       ch->hasObjectId = (flags & 0x20) != 0;
+       ch->editLock = (flags & 0x80) != 0;
+       ch->windingRule = (flags & (1<<12)) != 0;
+       ch->filled = (flags & (1<<13)) != 0;
+       ch->closed = (flags & (1<<14)) != 0;
+       ch->framed = (flags & (1<<15)) != 0;
+       
+       if(ch->editLock) ch->lockFlags = readU32();
+
+       // object ID can be 2 or 4 bytes
+       if(ch->hasObjectId) ch->objectId = readU16();
+       if(ch->objectId >> 15) ch->objectId = ((ch->objectId  & 0x7fff) << 16) | readU16();
+
+       if(ch->rotate) ch->rotationAngle = readS32();
+
+       if(ch->rotate || ch->scale)
+       {
+               ch->sxcos = readS32();
+               ch->sycos = readS32();
+               ch->matrix.element[0][0] = (double)(ch->sxcos)/65536;
+               ch->matrix.element[1][1] = (double)(ch->sxcos)/65536;
+       }
+
+       if(ch->rotate || ch->skew)
+       {
+               ch->kxsin = readS32();
+               ch->kysin = readS32();
+               ch->matrix.element[1][0] = (double)(ch->kxsin)/65536;
+               ch->matrix.element[0][1] = (double)(ch->kysin)/65536;
+       }
+
+       if(ch->translate)
+       {
+               ch->txfraction = readU16();
+               ch->txinteger = readS32();
+               ch->tyfraction = readU16();
+               ch->tyinteger = readS32();
+               ch->matrix.element[2][0] = (double)(ch->txinteger);
+               ch->matrix.element[2][1] = (double)(ch->tyinteger);
+       }
+
+       if(ch->taper)
+       {
+               ch->px = readS32();
+               ch->py = readS32();
+               ch->matrix.element[0][2] = (double)(ch->px);
+               ch->matrix.element[1][2] = (double)(ch->py);
+       }
+
+       WPG_DEBUG_MSG(("ObjectCharacterization\n"));
+       WPG_DEBUG_MSG(("       taper : %s\n", (ch->taper ? "yes" : "no")));
+       WPG_DEBUG_MSG(("   translate : %s\n", (ch->translate ? "yes" : "no")));
+       WPG_DEBUG_MSG(("        skew : %s\n", (ch->skew ? "yes" : "no")));
+       WPG_DEBUG_MSG(("       scale : %s\n", (ch->scale ? "yes" : "no")));
+       WPG_DEBUG_MSG(("      rotate : %s\n", (ch->rotate ? "yes" : "no")));
+       WPG_DEBUG_MSG((" hasObjectId : %s\n", (ch->hasObjectId ? "yes" : "no")));
+       WPG_DEBUG_MSG(("    editLock : %s\n", (ch->editLock ? "yes" : "no")));
+       if(ch->editLock) WPG_DEBUG_MSG(("  lock flags : 0x%x\n", ch->lockFlags));
+       if(ch->hasObjectId) WPG_DEBUG_MSG(("   object ID : 0x%x\n", ch->objectId));
+       if(ch->translate) WPG_DEBUG_MSG(("    tx : %d %d\n", ch->txinteger, ch->txfraction));
+       if(ch->translate) WPG_DEBUG_MSG(("    ty : %d %d\n", ch->tyinteger, ch->tyfraction));
+       WPG_DEBUG_MSG(("transform matrix:\n"));
+       WPG_DEBUG_MSG(("%f %f %f\n", ch->matrix.element[0][0], ch->matrix.element[0][1],ch->matrix.element[0][2]));
+       WPG_DEBUG_MSG(("%f %f %f\n", ch->matrix.element[1][0], ch->matrix.element[1][1],ch->matrix.element[1][2]));
+       WPG_DEBUG_MSG(("%f %f %f\n", ch->matrix.element[2][0], ch->matrix.element[2][1],ch->matrix.element[2][2]));
+}
+
+void WPG2Parser::handlePolyline()
+{
+       ObjectCharacterization objCh;
+       parseCharacterization(&objCh);
+       m_matrix = objCh.matrix;
+
+       unsigned long count = readU16();
+
+       WPGPointArray points;
+       for(unsigned long i = 0; i < count; i++ )
+       {
+               long x = (m_doublePrecision) ? readS32() : readS16();
+               long y = (m_doublePrecision) ? readS32() : readS16();
+               TRANSFORM_XY(x,y);
+               WPGPoint p(TO_DOUBLE(x)/m_xres, TO_DOUBLE(y)/m_yres);
+               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);
+       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++ )
+               WPG_DEBUG_MSG(("        Point #%d : %g,%g\n", j+1, points[j].x, points[j].y));
+}
+
+void WPG2Parser::handlePolycurve()
+{
+       ObjectCharacterization objCh;
+       parseCharacterization(&objCh);
+       m_matrix = objCh.matrix;
+
+       unsigned int count = readU16();
+
+       WPGPointArray vertices;
+       WPGPointArray controlPoints;
+       for(int i = 0; i < count; i++ )
+       {
+               long ix = (m_doublePrecision) ? readS32() : readS16();
+               long iy = (m_doublePrecision) ? readS32() : readS16();
+               TRANSFORM_XY(ix,iy);
+               WPGPoint initialPoint( TO_DOUBLE(ix)/m_xres, TO_DOUBLE(iy)/m_yres );
+
+               long ax = (m_doublePrecision) ? readS32() : readS16();
+               long ay = (m_doublePrecision) ? readS32() : readS16();
+               TRANSFORM_XY(ax,ay);
+               WPGPoint anchorPoint( TO_DOUBLE(ax)/m_xres, TO_DOUBLE(ay)/m_yres );
+
+               long tx = (m_doublePrecision) ? readS32() : readS16();
+               long ty = (m_doublePrecision) ? readS32() : readS16();
+               TRANSFORM_XY(tx,ty);
+               WPGPoint terminalPoint( TO_DOUBLE(tx)/m_xres, TO_DOUBLE(ty)/m_yres );
+
+               vertices.add(anchorPoint);
+               if(i > 0)
+                       controlPoints.add(initialPoint);
+               controlPoints.add(terminalPoint);
+       }
+
+       WPGPath path;
+       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);
+       else
+               m_painter->setFillRule(WPGPaintInterface::AlternatingFill);
+       m_painter->drawPath(path);
+}
+
+void WPG2Parser::handleRectangle()
+{
+       ObjectCharacterization objCh;
+       parseCharacterization(&objCh);
+       m_matrix = objCh.matrix;
+       
+       long x1 = (m_doublePrecision) ? readS32() : readS16();
+       long y1 = (m_doublePrecision) ? readS32() : readS16();
+       TRANSFORM_XY(x1,y1);
+
+       long x2 = (m_doublePrecision) ? readS32() : readS16();
+       long y2 = (m_doublePrecision) ? readS32() : readS16();
+       TRANSFORM_XY(x2,y2);
+       
+       long xs1 = (x1 <= x2) ? x1 : x2;
+       long xs2 = (x1 <= x2) ? x2 : x1;
+       long ys1 = (y1 <= y2) ? y1 : y2;
+       long ys2 = (y1 <= y2) ? y2 : y1;
+
+       long rx = (m_doublePrecision) ? readS32() : readS16();
+       long ry = (m_doublePrecision) ? readS32() : readS16();
+
+       WPGRect rect;
+       rect.x1 = TO_DOUBLE(xs1) / m_xres;
+       rect.x2 = TO_DOUBLE(xs2) / m_xres;
+       rect.y1 = TO_DOUBLE(ys1) / m_yres;
+       rect.y2 = TO_DOUBLE(ys2) / m_yres;
+       double roundx = TO_DOUBLE(rx)/m_xres;
+       double roundy = TO_DOUBLE(ry)/m_yres;
+
+       m_painter->setBrush( objCh.filled ? m_brush : WPGBrush() );
+       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));
+       WPG_DEBUG_MSG(("      Y2 : %d\n", y2));
+       WPG_DEBUG_MSG((" Round X : %d\n", rx));
+       WPG_DEBUG_MSG((" Round Y : %d\n", ry));
+}
+
+void WPG2Parser::handleArc()
+{
+       ObjectCharacterization objCh;
+       parseCharacterization(&objCh);
+       m_matrix = objCh.matrix;
+       
+       long cx = (m_doublePrecision) ? readS32() : readS16();
+       long cy = (m_doublePrecision) ? readS32() : readS16();
+
+       long radx = (m_doublePrecision) ? readS32() : readS16();
+       long rady = (m_doublePrecision) ? readS32() : readS16();
+
+       long ix = (m_doublePrecision) ? readS32() : readS16();
+       long iy = (m_doublePrecision) ? readS32() : readS16();
+       TRANSFORM_XY(ix,iy);
+
+       long ex = (m_doublePrecision) ? readS32() : readS16();
+       long ey = (m_doublePrecision) ? readS32() : readS16();
+       TRANSFORM_XY(ex,ey);
+
+       if((ix==ex) && (iy==ey))
+       {
+               WPGPoint center;
+               center.x = TO_DOUBLE(cx) / m_xres;
+               center.y = TO_DOUBLE(cy) / m_xres;
+               double rx = TO_DOUBLE(radx) / m_xres;
+               double ry = TO_DOUBLE(rady) / m_xres;
+               
+               m_painter->setBrush( objCh.filled ? m_brush : WPGBrush() );
+               m_painter->setPen( objCh.framed ? m_pen : WPGPen() );
+               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));
+       WPG_DEBUG_MSG(("         Radius y : %d\n", rady));
+       WPG_DEBUG_MSG(("  Initial point x : %d\n", ix));
+       WPG_DEBUG_MSG(("  Initial point y : %d\n", iy));
+       WPG_DEBUG_MSG(("      End point x : %d\n", ex));
+       WPG_DEBUG_MSG(("      End point y : %d\n", ey));
+}
+
+
+void WPG2Parser::resetPalette()
+{
+       m_colorPalette.clear();
+       for (int i=0; i<256; i++)
+       {
+               WPGColor color;
+               color.red = defaultWPG2PaletteRed[i];
+               color.green = defaultWPG2PaletteGreen[i];
+               color.blue = defaultWPG2PaletteBlue[i];
+               m_colorPalette[i] = color;
+       }
+}
diff --git a/src/extension/internal/libwpg/WPG2Parser.h b/src/extension/internal/libwpg/WPG2Parser.h
new file mode 100644 (file)
index 0000000..e472cce
--- /dev/null
@@ -0,0 +1,156 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPG2PARSER_H__
+#define __WPG2PARSER_H__
+
+#include "WPGXParser.h"
+#include "WPGBrush.h"
+#include "WPGPen.h"
+
+#include <map>
+#include <stack>
+
+class WPG2TransformMatrix
+{
+public:
+       double element[3][3];
+
+       WPG2TransformMatrix()
+       {
+               // identity transformation
+               element[0][0] = element[1][1] = 1; element[2][2] = 1;
+               element[0][1] = element[0][2] = 0;
+               element[1][0] = element[1][2] = 0;
+               element[2][0] = element[2][1] = 0;
+       }
+
+       void transform(long& x, long& y) const
+       {
+               long rx = (long)(element[0][0]*x + element[1][0]*y + element[2][0]); 
+               long ry = (long)(element[0][1]*x + element[1][1]*y + element[2][1]); 
+               x = rx;
+               y = ry;
+       }
+
+       WPGPoint transform(const WPGPoint& p) const
+       {
+               WPGPoint point;
+               point.x = element[0][0]*p.x + element[1][0]*p.y + element[2][0]; 
+               point.y = element[0][1]*p.x + element[1][1]*p.y + element[2][1]; 
+               return point;
+       }
+
+       WPGRect transform(const WPGRect& r) const
+       {
+               WPGRect rect;
+               rect.x1 = element[0][0]*r.x1 + element[1][0]*r.y1 + element[2][0]; 
+               rect.y1 = element[0][1]*r.x1 + element[1][1]*r.y1 + element[2][1]; 
+               rect.x2 = element[0][0]*r.x2 + element[1][0]*r.y2 + element[2][0]; 
+               rect.y2 = element[0][1]*r.x2 + element[1][1]*r.y2 + element[2][1]; 
+               return rect;
+       }
+};
+
+class WPGCompoundPolygon
+{
+public:
+       WPG2TransformMatrix matrix;
+       bool isFilled;
+       bool isFramed;
+       bool isClosed;
+
+       WPGCompoundPolygon(): matrix(), isFilled(true), isFramed(true), isClosed(true) {}
+};
+
+class WPG2Parser : public WPGXParser
+{
+public:
+       WPG2Parser(WPGInputStream *input, WPGPaintInterface* painter);
+       bool parse();
+       
+private:
+       void handleStartWPG();
+       void handleEndWPG();
+       void handleLayer();
+       void handleCompoundPolygon();
+       
+       void handlePenStyleDefinition();
+       void handlePatternDefinition();
+       void handleColorPalette();
+       void handleDPColorPalette();
+       void handlePenForeColor();
+       void handleDPPenForeColor();
+       void handlePenBackColor();
+       void handleDPPenBackColor();
+       void handlePenStyle();
+       void handlePenSize();
+       void handleDPPenSize();
+       void handleBrushGradient();
+       void handleDPBrushGradient();
+       void handleBrushForeColor();
+       void handleDPBrushForeColor();
+       void handleBrushBackColor();
+       void handleDPBrushBackColor();
+       void handleBrushPattern();
+
+       void handlePolyline();
+       void handlePolycurve();
+       void handleRectangle();
+       void handleArc();
+       
+       void resetPalette();
+
+       // parsing context
+       bool m_success;
+       bool m_exit;
+       unsigned int m_xres;
+       unsigned int m_yres;
+       long m_xofs;
+       long m_yofs;
+       long m_width;
+       long m_height;
+       bool m_doublePrecision;  
+       WPGPen m_pen;
+       WPGBrush m_brush;
+       std::map<unsigned int,WPGDashArray> m_penStyles;
+       bool m_layerOpened;
+       unsigned int m_layerId;
+       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;
+
+       class ObjectCharacterization;
+       void parseCharacterization(ObjectCharacterization*);
+};
+
+#endif // __WPG2PARSER_H__
diff --git a/src/extension/internal/libwpg/WPGBrush.h b/src/extension/internal/libwpg/WPGBrush.h
new file mode 100644 (file)
index 0000000..d8c746a
--- /dev/null
@@ -0,0 +1,91 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGBRUSH_H__
+#define __WPGBRUSH_H__
+
+#include "WPGColor.h"
+#include "WPGGradient.h"
+
+namespace libwpg
+{
+
+class WPGBrush
+{
+public:
+
+       typedef enum
+       {
+               NoBrush,
+               Solid,
+               Pattern,
+               Gradient
+       } WPGBrushStyle;
+       
+       WPGBrushStyle style;
+       WPGColor foreColor;
+       WPGColor backColor;
+       
+       WPGGradient gradient;
+
+       WPGBrush(): 
+               style(NoBrush), 
+               foreColor(0,0,0), 
+               backColor(0,0,0) 
+                       {};
+
+       WPGBrush(const WPGColor& fore): 
+               style(Solid), 
+               foreColor(fore),  
+               backColor(0,0,0) 
+                       {};
+
+       WPGBrush(const WPGColor& fore, const WPGColor& back): 
+               style(Solid), 
+               foreColor(fore),  
+               backColor(back) 
+                       {};
+
+       WPGBrush(const WPGBrush& brush)
+       {
+               style = brush.style;
+               foreColor = brush.foreColor; 
+               backColor = brush.backColor; 
+               gradient = brush.gradient;
+       }
+
+       WPGBrush& operator=(const WPGBrush& brush)
+       {
+               style = brush.style;
+               foreColor = brush.foreColor; 
+               backColor = brush.backColor; 
+               gradient = brush.gradient;
+               return *this; 
+       }
+};
+
+} // namespace libwpg
+
+#endif // __WPGBRUSH_H__
diff --git a/src/extension/internal/libwpg/WPGColor.h b/src/extension/internal/libwpg/WPGColor.h
new file mode 100644 (file)
index 0000000..8867ae5
--- /dev/null
@@ -0,0 +1,52 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGCOLOR_H__
+#define __WPGCOLOR_H__
+
+namespace libwpg
+{
+
+class WPGColor
+{
+public:
+       int red, green, blue, alpha;
+       
+       WPGColor(): red(0), green(0), blue(0), alpha(0) {}
+       
+       WPGColor(int r, int g, int b): red(r), green(g), blue(b), alpha(0)  {}
+       
+       WPGColor(int r, int g, int b, int a): red(r), green(g), blue(b), alpha(a)  {}
+
+       WPGColor(const WPGColor& color)
+       { red = color.red; green = color.green; blue = color.blue; alpha = color.alpha; }
+       
+       WPGColor& operator=(const WPGColor& color)
+       { red = color.red; green = color.green; blue = color.blue; alpha = color.alpha; return *this; }
+};
+
+} // namespace libwpg
+
+#endif // __WPGCOLOR_H__
diff --git a/src/extension/internal/libwpg/WPGGradient.cpp b/src/extension/internal/libwpg/WPGGradient.cpp
new file mode 100644 (file)
index 0000000..566789e
--- /dev/null
@@ -0,0 +1,115 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "WPGGradient.h"
+#include "WPGColor.h"
+
+#include <vector>
+
+namespace libwpg
+{
+
+class WPGGradientStop
+{
+public:
+       double offset;
+       WPGColor color;
+       
+       WPGGradientStop(): offset(0) {}
+       
+       WPGGradientStop(double ofs, const WPGColor& c): offset(ofs), color(c) {}
+};
+
+class WPGGradientPrivate
+{
+public:
+    double angle;
+       std::vector<WPGGradientStop> gradientStops;
+};
+
+} // namespace libwpg
+
+using namespace libwpg;
+
+WPGGradient::WPGGradient()
+{
+       d = new WPGGradientPrivate;
+       d->angle = 0.0;
+}
+
+WPGGradient::~WPGGradient()
+{
+       delete d;
+}
+
+WPGGradient::WPGGradient(const WPGGradient& g)
+{
+       d = new WPGGradientPrivate;
+       d->angle = g.d->angle;
+       d->gradientStops = g.d->gradientStops;
+}
+       
+WPGGradient& WPGGradient::operator=(const WPGGradient& g)
+{
+       d->angle = g.d->angle;
+       d->gradientStops = g.d->gradientStops;
+       return *this;
+}
+
+double WPGGradient::angle() const
+{
+       return d->angle;
+}
+
+void WPGGradient::setAngle(double a)
+{
+       d->angle = a;
+}
+       
+unsigned WPGGradient::count() const
+{
+       return d->gradientStops.size();
+}
+
+double WPGGradient::stopOffset(unsigned index) const
+{
+       return d->gradientStops[index].offset;
+}
+
+WPGColor WPGGradient::stopColor(unsigned index) const
+{
+       return d->gradientStops[index].color;
+}
+
+void WPGGradient::clear()
+{
+       d->gradientStops.clear();
+}
+
+void WPGGradient::addStop(double offset, const WPGColor& color)
+{
+       WPGGradientStop stop(offset, color);
+       d->gradientStops.push_back(stop);
+}
diff --git a/src/extension/internal/libwpg/WPGGradient.h b/src/extension/internal/libwpg/WPGGradient.h
new file mode 100644 (file)
index 0000000..70b4872
--- /dev/null
@@ -0,0 +1,68 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGGRADIENT_H__
+#define __WPGGRADIENT_H__
+
+#include "WPGColor.h"
+
+namespace libwpg
+{
+
+class WPGGradientPrivate;
+
+class WPGGradient
+{
+public:
+       
+       WPGGradient();
+       
+       ~WPGGradient();
+       
+       WPGGradient(const WPGGradient&);
+       
+       WPGGradient& operator=(const WPGGradient&);
+       
+       double angle() const; // in radiant
+       
+       void setAngle(double angle);
+
+       unsigned count() const;
+       
+       double stopOffset(unsigned index) const;
+       
+       WPGColor stopColor(unsigned index) const;
+       
+       void clear();
+       
+       void addStop(double offset, const WPGColor& color);
+       
+private:
+       WPGGradientPrivate *d;
+};
+
+} // namespace libwpg
+
+#endif // __WPGGRADIENT_H__
diff --git a/src/extension/internal/libwpg/WPGHeader.cpp b/src/extension/internal/libwpg/WPGHeader.cpp
new file mode 100644 (file)
index 0000000..8daf357
--- /dev/null
@@ -0,0 +1,123 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "WPGHeader.h"
+#include "libwpg_utils.h"
+
+namespace
+{
+static inline unsigned short readU16( const void* p )
+{
+       const unsigned char* ptr = (const unsigned char*) p;
+       return ptr[0]+(ptr[1]<<8);
+}
+
+static inline unsigned long readU32( const void* p )
+{
+       const unsigned char* ptr = (const unsigned char*) p;
+       return ptr[0]+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
+}
+}
+
+using namespace libwpg;
+
+WPGHeader::WPGHeader()
+{
+               // create a sensible default header
+               m_identifier[0] = 0xff;
+               m_identifier[1] = 'W'; 
+               m_identifier[2] = 'P'; 
+               m_identifier[3] = 'C'; 
+               m_productType = 0x01;
+               m_fileType = 0x16;
+               m_encryptionKey = 0x00;
+               m_majorVersion = 0x02;
+               m_minorVersion = 0x00;
+               m_encryptionKey = 0;
+               m_startOfPacketData = 0;
+               m_entryCount = 0;
+               m_resourceComplete = 0;
+               m_encryptionBlockOffset = 0;
+               m_fileSize = 0;
+               m_encryptVersion = 0;
+}
+
+bool WPGHeader::load(WPGInputStream *input)
+{
+       input->seek(0);
+       
+       unsigned char prefix[26];
+       long n = input->read(26, (char*)prefix);
+       if(n < 26)
+               return false;
+       
+       m_identifier[0] = prefix[0];  
+       m_identifier[1] = prefix[1];  
+       m_identifier[2] = prefix[2];  
+       m_identifier[3] = prefix[3];  
+       m_startOfDocument = readU32(prefix+4);
+       m_productType = prefix[8];
+       m_fileType = prefix[9];
+       m_majorVersion = prefix[10];
+       m_minorVersion = prefix[11];
+       m_encryptionKey = readU16(prefix+12);
+       m_startOfPacketData = readU16(prefix+14);
+       
+       WPG_DEBUG_MSG(("Header Identifier  = %c%c%c\n", m_identifier[1], 
+       m_identifier[2], m_identifier[3]));
+       WPG_DEBUG_MSG(("Product type       = 0x%x\n",  m_productType));
+       WPG_DEBUG_MSG(("File type          = 0x%x\n",  m_fileType));
+       WPG_DEBUG_MSG(("Major version      = 0x%x\n",  m_majorVersion));
+       WPG_DEBUG_MSG(("Minor version      = 0x%x\n",  m_minorVersion));
+       WPG_DEBUG_MSG(("Encryption key     = 0x%x\n",  m_encryptionKey));
+       
+       return true;
+}
+
+bool WPGHeader::isSupported() const
+{
+       return (
+               (m_identifier[0] == 0xFF) &&
+               (m_identifier[1] == 'W') &&
+               (m_identifier[2] == 'P') &&
+               (m_identifier[3] == 'C') &&
+               (m_productType == 0x01) &&
+               (m_fileType == 0x16) &&
+               (m_encryptionKey == 0x00) &&     // we don't support encryption
+               ((m_majorVersion == 0x02) || (m_majorVersion == 0x01)) &&
+               (m_minorVersion == 0x00) 
+);
+}
+
+unsigned long WPGHeader::startOfDocument() const
+{
+       return m_startOfDocument;
+}
+
+int WPGHeader::majorVersion() const
+{
+       return m_majorVersion;
+}
diff --git a/src/extension/internal/libwpg/WPGHeader.h b/src/extension/internal/libwpg/WPGHeader.h
new file mode 100644 (file)
index 0000000..c68a379
--- /dev/null
@@ -0,0 +1,63 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGHEADER_H__
+#define __WPGHEADER_H__
+
+#include "WPGStream.h"
+
+using namespace libwpg;
+
+class WPGHeader 
+{
+public:
+       WPGHeader();
+       
+       bool load(WPGInputStream *input);
+       
+       bool isSupported() const;
+       
+       unsigned long startOfDocument() const;
+       
+       int majorVersion() const;
+
+private:
+       unsigned char m_identifier[4];          // should always be 0xFF followed by "WPC"
+       unsigned long m_startOfDocument;        // index into file
+       unsigned char m_productType;            // should always be 1 for WPG files
+       unsigned char m_fileType;               // should always be 22 for WPG files
+       unsigned char m_majorVersion;           // 2 for WPG 8.0 files
+       unsigned char m_minorVersion;           // 0 for WPG 8.0 files
+       unsigned int  m_encryptionKey;          // 0 when not encrypted
+       unsigned int  m_startOfPacketData;      // unused, since according to the docs no packets are defined
+       unsigned char m_entryCount;             // number of entries in extension
+       unsigned char m_resourceComplete;       // resource completeness indicator
+       unsigned int  m_encryptionBlockOffset;  // encryption block offset
+       unsigned long m_fileSize;               // size of the entire wpg file
+       unsigned int  m_encryptVersion;         // encryption version information
+};
+
+#endif // WPGHEADER
diff --git a/src/extension/internal/libwpg/WPGOLEStream.cpp b/src/extension/internal/libwpg/WPGOLEStream.cpp
new file mode 100644 (file)
index 0000000..65c3b0b
--- /dev/null
@@ -0,0 +1,991 @@
+/* POLE - Portable C++ library to access OLE Storage 
+   Copyright (C) 2002-2005 Ariya Hidayat <ariya@kde.org>
+
+   Redistribution and use in source and binary forms, with or without 
+   modification, are permitted provided that the following conditions 
+   are met:
+   * Redistributions of source code must retain the above copyright notice, 
+     this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+   * Neither the name of the authors nor the names of its contributors may be 
+     used to endorse or promote products derived from this software without 
+     specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
+   THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <sstream>
+#include <iostream>
+#include <list>
+#include <string>
+#include <vector>
+
+#include "WPGOLEStream.h"
+#include "libwpg_utils.h"
+
+namespace libwpg
+{
+
+class Header
+{
+  public:
+    unsigned char id[8];       // signature, or magic identifier
+    unsigned b_shift;          // bbat->blockSize = 1 << b_shift
+    unsigned s_shift;          // sbat->blockSize = 1 << s_shift
+    unsigned num_bat;          // blocks allocated for big bat
+    unsigned dirent_start;     // starting block for directory info
+    unsigned threshold;        // switch from small to big file (usually 4K)
+    unsigned sbat_start;       // starting block index to store small bat
+    unsigned num_sbat;         // blocks allocated for small bat
+    unsigned mbat_start;       // starting block to store meta bat
+    unsigned num_mbat;         // blocks allocated for meta bat
+    unsigned long bb_blocks[109];
+    
+    Header();
+    bool valid();
+    void load( const unsigned char* buffer );
+    void save( unsigned char* buffer );
+    void debug();
+};
+
+class AllocTable
+{
+  public:
+    static const unsigned Eof;
+    static const unsigned Avail;
+    static const unsigned Bat;    
+    static const unsigned MetaBat;    
+    unsigned blockSize;
+    AllocTable();
+    void clear();
+    unsigned long count();
+    void resize( unsigned long newsize );
+    void preserve( unsigned long n );
+    void set( unsigned long index, unsigned long val );
+    unsigned unused();
+    void setChain( std::vector<unsigned long> );
+    std::vector<unsigned long> follow( unsigned long start );
+    unsigned long operator[](unsigned long index );
+    void load( const unsigned char* buffer, unsigned len );
+    void save( unsigned char* buffer );
+  private:
+    std::vector<unsigned long> data;
+    AllocTable( const AllocTable& );
+    AllocTable& operator=( const AllocTable& );
+};
+
+class DirEntry
+{
+  public:
+    bool valid;            // false if invalid (should be skipped)
+    std::string name;      // the name, not in unicode anymore 
+    bool dir;              // true if directory   
+    unsigned long size;    // size (not valid if directory)
+    unsigned long start;   // starting block
+    unsigned prev;         // previous sibling
+    unsigned next;         // next sibling
+    unsigned child;        // first child
+};
+
+class DirTree
+{
+  public:
+    static const unsigned End;
+    DirTree();
+    void clear();
+    unsigned entryCount();
+    DirEntry* entry( unsigned index );
+    DirEntry* entry( const std::string& name );
+    int parent( unsigned index );
+    std::string fullName( unsigned index );
+    std::vector<unsigned> children( unsigned index );
+    void load( unsigned char* buffer, unsigned len );
+    void save( unsigned char* buffer );
+  private:
+    std::vector<DirEntry> entries;
+    DirTree( const DirTree& );
+    DirTree& operator=( const DirTree& );
+};
+
+class StorageIO
+{
+  public:
+    Storage* storage;         // owner
+    std::stringstream buf;
+    int result;               // result of operation
+    unsigned long bufsize;    // size of the buffer
+    
+    Header* header;           // storage header 
+    DirTree* dirtree;         // directory tree
+    AllocTable* bbat;         // allocation table for big blocks
+    AllocTable* sbat;         // allocation table for small blocks
+    
+    std::vector<unsigned long> sb_blocks; // blocks for "small" files
+       
+    std::list<Stream*> streams;
+
+    StorageIO( Storage* storage, const std::stringstream &memorystream );
+    ~StorageIO();
+    
+    bool isOle();
+    void load();
+
+    unsigned long loadBigBlocks( std::vector<unsigned long> blocks, unsigned char* buffer, unsigned long maxlen );
+
+    unsigned long loadBigBlock( unsigned long block, unsigned char* buffer, unsigned long maxlen );
+
+    unsigned long loadSmallBlocks( std::vector<unsigned long> blocks, unsigned char* buffer, unsigned long maxlen );
+
+    unsigned long loadSmallBlock( unsigned long block, unsigned char* buffer, unsigned long maxlen );
+    
+    StreamIO* streamIO( const std::string& name ); 
+
+  private:  
+    // no copy or assign
+    StorageIO( const StorageIO& );
+    StorageIO& operator=( const StorageIO& );
+
+};
+
+class StreamIO
+{
+  public:
+    StorageIO* io;
+    DirEntry* entry;
+    std::string fullName;
+    bool eof;
+    bool fail;
+
+    StreamIO( StorageIO* io, DirEntry* entry );
+    ~StreamIO();
+    unsigned long size();
+    unsigned long tell();
+    int getch();
+    unsigned long read( unsigned char* data, unsigned long maxlen );
+    unsigned long read( unsigned long pos, unsigned char* data, unsigned long maxlen );
+
+
+  private:
+    std::vector<unsigned long> blocks;
+
+    // no copy or assign
+    StreamIO( const StreamIO& );
+    StreamIO& operator=( const StreamIO& );
+
+    // pointer for read
+    unsigned long m_pos;
+
+    // simple cache system to speed-up getch()
+    unsigned char* cache_data;
+    unsigned long cache_size;
+    unsigned long cache_pos;
+    void updateCache();
+};
+
+}; // namespace libwpg
+
+using namespace libwpg;
+
+static inline unsigned long readU16( const unsigned char* ptr )
+{
+  return ptr[0]+(ptr[1]<<8);
+}
+
+static inline unsigned long readU32( const unsigned char* ptr )
+{
+  return ptr[0]+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
+}
+
+static const unsigned char wpgole_magic[] = 
+ { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 };
+
+// =========== Header ==========
+
+Header::Header()
+{
+  b_shift = 9;
+  s_shift = 6;
+  num_bat = 0;
+  dirent_start = 0;
+  threshold = 4096;
+  sbat_start = 0;
+  num_sbat = 0;
+  mbat_start = 0;
+  num_mbat = 0;
+
+  for( unsigned i = 0; i < 8; i++ )
+    id[i] = wpgole_magic[i];  
+  for( unsigned j=0; j<109; j++ )
+    bb_blocks[j] = AllocTable::Avail;
+}
+
+bool Header::valid()
+{
+  if( threshold != 4096 ) return false;
+  if( num_bat == 0 ) return false;
+  if( (num_bat > 109) && (num_bat > (num_mbat * 127) + 109)) return false;
+  if( (num_bat < 109) && (num_mbat != 0) ) return false;
+  if( s_shift > b_shift ) return false;
+  if( b_shift <= 6 ) return false;
+  if( b_shift >=31 ) return false;
+  
+  return true;
+}
+
+void Header::load( const unsigned char* buffer )
+{
+  b_shift      = readU16( buffer + 0x1e );
+  s_shift      = readU16( buffer + 0x20 );
+  num_bat      = readU32( buffer + 0x2c );
+  dirent_start = readU32( buffer + 0x30 );
+  threshold    = readU32( buffer + 0x38 );
+  sbat_start   = readU32( buffer + 0x3c );
+  num_sbat     = readU32( buffer + 0x40 );
+  mbat_start   = readU32( buffer + 0x44 );
+  num_mbat     = readU32( buffer + 0x48 );
+  
+  for( unsigned i = 0; i < 8; i++ )
+    id[i] = buffer[i];  
+  for( unsigned j=0; j<109; j++ )
+    bb_blocks[j] = readU32( buffer + 0x4C+j*4 );
+}
+// =========== AllocTable ==========
+
+const unsigned AllocTable::Avail = 0xffffffff;
+const unsigned AllocTable::Eof = 0xfffffffe;
+const unsigned AllocTable::Bat = 0xfffffffd;
+const unsigned AllocTable::MetaBat = 0xfffffffc;
+
+AllocTable::AllocTable()
+{
+  blockSize = 4096;
+  // initial size
+  resize( 128 );
+}
+
+unsigned long AllocTable::count()
+{
+  return data.size();
+}
+
+void AllocTable::resize( unsigned long newsize )
+{
+  unsigned oldsize = data.size();
+  data.resize( newsize );
+  if( newsize > oldsize )
+    for( unsigned i = oldsize; i<newsize; i++ )
+      data[i] = Avail;
+}
+
+// make sure there're still free blocks
+void AllocTable::preserve( unsigned long n )
+{
+  std::vector<unsigned long> pre;
+  for( unsigned i=0; i < n; i++ )
+    pre.push_back( unused() );
+}
+
+unsigned long AllocTable::operator[]( unsigned long index )
+{
+  unsigned long result;
+  result = data[index];
+  return result;
+}
+
+void AllocTable::set( unsigned long index, unsigned long value )
+{
+  if( index >= count() ) resize( index + 1);
+  data[ index ] = value;
+}
+
+void AllocTable::setChain( std::vector<unsigned long> chain )
+{
+  if( chain.size() )
+  {
+    for( unsigned i=0; i<chain.size()-1; i++ )
+      set( chain[i], chain[i+1] );
+    set( chain[ chain.size()-1 ], AllocTable::Eof );
+  }
+}
+
+// follow 
+std::vector<unsigned long> AllocTable::follow( unsigned long start )
+{
+  std::vector<unsigned long> chain;
+
+  if( start >= count() ) return chain; 
+
+  unsigned long p = start;
+  while( p < count() )
+  {
+    if( p == (unsigned long)Eof ) break;
+    if( p == (unsigned long)Bat ) break;
+    if( p == (unsigned long)MetaBat ) break;
+    if( p >= count() ) break;
+    chain.push_back( p );
+    if( data[p] >= count() ) break;
+    p = data[ p ];
+  }
+
+  return chain;
+}
+
+unsigned AllocTable::unused()
+{
+  // find first available block
+  for( unsigned i = 0; i < data.size(); i++ )
+    if( data[i] == Avail )
+      return i;
+  
+  // completely full, so enlarge the table
+  unsigned block = data.size();
+  resize( data.size()+10 );
+  return block;      
+}
+
+void AllocTable::load( const unsigned char* buffer, unsigned len )
+{
+  resize( len / 4 );
+  for( unsigned i = 0; i < count(); i++ )
+    set( i, readU32( buffer + i*4 ) );
+}
+
+// =========== DirTree ==========
+
+const unsigned DirTree::End = 0xffffffff;
+
+DirTree::DirTree()
+{
+  clear();
+}
+
+void DirTree::clear()
+{
+  // leave only root entry
+  entries.resize( 1 );
+  entries[0].valid = true;
+  entries[0].name = "Root Entry";
+  entries[0].dir = true;
+  entries[0].size = 0;
+  entries[0].start = End;
+  entries[0].prev = End;
+  entries[0].next = End;
+  entries[0].child = End;
+}
+
+unsigned DirTree::entryCount()
+{
+  return entries.size();
+}
+
+DirEntry* DirTree::entry( unsigned index )
+{
+  if( index >= entryCount() ) return (DirEntry*) 0;
+  return &entries[ index ];
+}
+
+int DirTree::parent( unsigned index )
+{
+  // brute-force, basically we iterate for each entries, find its children
+  // and check if one of the children is 'index'
+  for( unsigned j=0; j<entryCount(); j++ )
+  {
+    std::vector<unsigned> chi = children( j );
+    for( unsigned i=0; i<chi.size();i++ )
+      if( chi[i] == index )
+        return j;
+  }
+        
+  return -1;
+}
+
+std::string DirTree::fullName( unsigned index )
+{
+  // don't use root name ("Root Entry"), just give "/"
+  if( index == 0 ) return "/";
+
+  std::string result = entry( index )->name;
+  result.insert( 0,  "/" );
+  int p = parent( index );
+  DirEntry * _entry = 0;
+  while( p > 0 )
+  {
+    _entry = entry( p );
+    if (_entry->dir && _entry->valid)
+    {
+      result.insert( 0,  _entry->name);
+      result.insert( 0,  "/" );
+    }
+    --p;
+    index = p;
+    if( index <= 0 ) break;
+  }
+  return result;
+}
+
+// given a fullname (e.g "/ObjectPool/_1020961869"), find the entry
+DirEntry* DirTree::entry( const std::string& name )
+{
+
+   if( !name.length() ) return (DirEntry*)0;
+   // quick check for "/" (that's root)
+   if( name == "/" ) return entry( 0 );
+   
+   // split the names, e.g  "/ObjectPool/_1020961869" will become:
+   // "ObjectPool" and "_1020961869" 
+   std::list<std::string> names;
+   std::string::size_type start = 0, end = 0;
+   if( name[0] == '/' ) start++;
+   while( start < name.length() )
+   {
+     end = name.find_first_of( '/', start );
+     if( end == std::string::npos ) end = name.length();
+     names.push_back( name.substr( start, end-start ) );
+     start = end+1;
+   }
+  
+   // start from root 
+   int index = 0 ;
+
+   // trace one by one   
+   std::list<std::string>::iterator it; 
+
+   for( it = names.begin(); it != names.end(); ++it )
+   {
+     // find among the children of index
+     std::vector<unsigned> chi = children( index );
+     unsigned child = 0;
+     for( unsigned i = 0; i < chi.size(); i++ )
+     {
+       DirEntry* ce = entry( chi[i] );
+       if( ce ) 
+       if( ce->valid && ( ce->name.length()>1 ) )
+       if( ce->name == *it )
+             child = chi[i];
+     }
+     
+     // traverse to the child
+     if( child > 0 ) index = child;
+     else return (DirEntry*)0;
+   }
+
+   return entry( index );
+}
+
+// helper function: recursively find siblings of index
+void dirtree_find_siblings( DirTree* dirtree, std::vector<unsigned>& result, 
+  unsigned index )
+{
+  DirEntry* e = dirtree->entry( index );
+  if( !e ) return;
+  if( !e->valid ) return;
+
+  // prevent infinite loop  
+  for( unsigned i = 0; i < result.size(); i++ )
+    if( result[i] == index ) return;
+
+  // add myself    
+  result.push_back( index );
+  
+  // visit previous sibling, don't go infinitely
+  unsigned prev = e->prev;
+  if( ( prev > 0 ) && ( prev < dirtree->entryCount() ) )
+  {
+    for( unsigned i = 0; i < result.size(); i++ )
+      if( result[i] == prev ) prev = 0;
+    if( prev ) dirtree_find_siblings( dirtree, result, prev );
+  }
+    
+  // visit next sibling, don't go infinitely
+  unsigned next = e->next;
+  if( ( next > 0 ) && ( next < dirtree->entryCount() ) )
+  {
+    for( unsigned i = 0; i < result.size(); i++ )
+      if( result[i] == next ) next = 0;
+    if( next ) dirtree_find_siblings( dirtree, result, next );
+  }
+}
+
+std::vector<unsigned> DirTree::children( unsigned index )
+{
+  std::vector<unsigned> result;
+  
+  DirEntry* e = entry( index );
+  if( e ) if( e->valid && e->child < entryCount() )
+    dirtree_find_siblings( this, result, e->child );
+    
+  return result;
+}
+
+void DirTree::load( unsigned char* buffer, unsigned size )
+{
+  entries.clear();
+  
+  for( unsigned i = 0; i < size/128; i++ )
+  {
+    unsigned p = i * 128;
+    
+    // would be < 32 if first char in the name isn't printable
+    unsigned prefix = 32;
+    
+    // parse name of this entry, which stored as Unicode 16-bit
+    std::string name;
+    int name_len = readU16( buffer + 0x40+p );
+    if( name_len > 64 ) name_len = 64;
+    for( int j=0; ( buffer[j+p]) && (j<name_len); j+= 2 )
+      name.append( 1, buffer[j+p] );
+      
+    // first char isn't printable ? remove it...
+    if( buffer[p] < 32 )
+    { 
+      prefix = buffer[0]; 
+      name.erase( 0,1 ); 
+    }
+    
+    // 2 = file (aka stream), 1 = directory (aka storage), 5 = root
+    unsigned type = buffer[ 0x42 + p];
+    
+    DirEntry e;
+    e.valid = true;
+    e.name = name;
+    e.start = readU32( buffer + 0x74+p );
+    e.size = readU32( buffer + 0x78+p );
+    e.prev = readU32( buffer + 0x44+p );
+    e.next = readU32( buffer + 0x48+p );
+    e.child = readU32( buffer + 0x4C+p );
+    e.dir = ( type!=2 );
+    
+    // sanity checks
+    if( (type != 2) && (type != 1 ) && (type != 5 ) ) e.valid = false;
+    if( name_len < 1 ) e.valid = false;
+    
+    entries.push_back( e );
+  }  
+}
+
+// =========== StorageIO ==========
+
+StorageIO::StorageIO( Storage* st, const std::stringstream &memorystream ) :
+       buf( memorystream.str(), std::ios::binary | std::ios::in )
+{
+  storage = st;
+  result = Storage::Ok;
+  
+  header = new Header();
+  dirtree = new DirTree();
+  bbat = new AllocTable();
+  sbat = new AllocTable();
+  
+  bufsize = 0;
+  bbat->blockSize = 1 << header->b_shift;
+  sbat->blockSize = 1 << header->s_shift;
+}
+
+StorageIO::~StorageIO()
+{
+  delete sbat;
+  delete bbat;
+  delete dirtree;
+  delete header;
+
+  std::list<Stream*>::iterator it;
+  for( it = streams.begin(); it != streams.end(); ++it )
+    delete *it;
+}
+
+bool StorageIO::isOle()
+{
+  load();
+  return (result == Storage::Ok);
+}
+
+void StorageIO::load()
+{
+  unsigned char* buffer = 0;
+  unsigned long buflen = 0;
+  std::vector<unsigned long> blocks;
+  
+  // find size of input file
+  buf.seekg( 0, std::ios::end );
+  bufsize = buf.tellg();
+
+  // load header
+  buffer = new unsigned char[512];
+  buf.seekg( 0 ); 
+  buf.read( (char*)buffer, 512 );
+  header->load( buffer );
+  delete[] buffer;
+
+  // check OLE magic id
+  result = Storage::NotOLE;
+  for( unsigned i=0; i<8; i++ )
+    if( header->id[i] != wpgole_magic[i] )
+      return;
+  // sanity checks
+  result = Storage::BadOLE;
+  if( !header->valid() ) return;
+  if( header->threshold != 4096 ) return;
+
+  // important block size
+  bbat->blockSize = 1 << header->b_shift;
+  sbat->blockSize = 1 << header->s_shift;
+  
+  // find blocks allocated to store big bat
+  // the first 109 blocks are in header, the rest in meta bat
+  blocks.clear();
+  blocks.resize( header->num_bat );
+  for( unsigned j = 0; j < 109; j++ )
+    if( j >= header->num_bat ) break;
+    else blocks[j] = header->bb_blocks[j];
+  if( (header->num_bat > 109) && (header->num_mbat > 0) )
+  {
+    unsigned char* buffer2 = new unsigned char[ bbat->blockSize ];
+    unsigned k = 109;
+    for( unsigned r = 0; r < header->num_mbat; r++ )
+    {
+      loadBigBlock( header->mbat_start+r, buffer2, bbat->blockSize );
+      for( unsigned s=0; s < bbat->blockSize; s+=4 )
+      {
+        if( k >= header->num_bat ) break;
+        else  blocks[k++] = readU32( buffer2 + s );
+      }  
+     }    
+    delete[] buffer2;
+  }
+
+  // load big bat
+  buflen = blocks.size()*bbat->blockSize;
+  if( buflen > 0 )
+  {
+    buffer = new unsigned char[ buflen ];  
+    loadBigBlocks( blocks, buffer, buflen );
+    bbat->load( buffer, buflen );
+    delete[] buffer;
+  }  
+
+  // load small bat
+  blocks.clear();
+  blocks = bbat->follow( header->sbat_start );
+  buflen = blocks.size()*bbat->blockSize;
+  if( buflen > 0 )
+  {
+    buffer = new unsigned char[ buflen ];  
+    loadBigBlocks( blocks, buffer, buflen );
+    sbat->load( buffer, buflen );
+    delete[] buffer;
+  }  
+  
+  // load directory tree
+  blocks.clear();
+  blocks = bbat->follow( header->dirent_start );
+  buflen = blocks.size()*bbat->blockSize;
+  buffer = new unsigned char[ buflen ];  
+  loadBigBlocks( blocks, buffer, buflen );
+  dirtree->load( buffer, buflen );
+  unsigned sb_start = readU32( buffer + 0x74 );
+  delete[] buffer;
+  
+  // fetch block chain as data for small-files
+  sb_blocks = bbat->follow( sb_start ); // small files
+  
+  // so far so good
+  result = Storage::Ok;
+}
+
+StreamIO* StorageIO::streamIO( const std::string& name )
+{
+  load();
+
+  // sanity check
+  if( !name.length() ) return (StreamIO*)0;
+
+  // search in the entries
+  DirEntry* entry = dirtree->entry( name );
+  if( !entry ) return (StreamIO*)0;
+  if( entry->dir ) return (StreamIO*)0;
+
+  StreamIO* result = new StreamIO( this, entry );
+  result->fullName = name;
+  
+  return result;
+}
+
+unsigned long StorageIO::loadBigBlocks( std::vector<unsigned long> blocks,
+  unsigned char* data, unsigned long maxlen )
+{
+  // sentinel
+  if( !data ) return 0;
+  if( blocks.size() < 1 ) return 0;
+  if( maxlen == 0 ) return 0;
+
+  // read block one by one, seems fast enough
+  unsigned long bytes = 0;
+  for( unsigned long i=0; (i < blocks.size() ) & ( bytes<maxlen ); i++ )
+  {
+    unsigned long block = blocks[i];
+    unsigned long pos =  bbat->blockSize * ( block+1 );
+    unsigned long p = (bbat->blockSize < maxlen-bytes) ? bbat->blockSize : maxlen-bytes;
+    if( pos + p > bufsize ) p = bufsize - pos;
+    buf.seekg( pos );
+    buf.read( (char*)data + bytes, p );
+    bytes += p;
+  }
+
+  return bytes;
+}
+
+unsigned long StorageIO::loadBigBlock( unsigned long block,
+  unsigned char* data, unsigned long maxlen )
+{
+  // sentinel
+  if( !data ) return 0;
+
+  // wraps call for loadBigBlocks
+  std::vector<unsigned long> blocks;
+  blocks.resize( 1 );
+  blocks[ 0 ] = block;
+  
+  return loadBigBlocks( blocks, data, maxlen );
+}
+
+// return number of bytes which has been read
+unsigned long StorageIO::loadSmallBlocks( std::vector<unsigned long> blocks,
+  unsigned char* data, unsigned long maxlen )
+{
+  // sentinel
+  if( !data ) return 0;
+  if( blocks.size() < 1 ) return 0;
+  if( maxlen == 0 ) return 0;
+
+  // our own local buffer
+  unsigned char* buf = new unsigned char[ bbat->blockSize ];
+
+  // read small block one by one
+  unsigned long bytes = 0;
+  for( unsigned long i=0; ( i<blocks.size() ) & ( bytes<maxlen ); i++ )
+  {
+    unsigned long block = blocks[i];
+
+    // find where the small-block exactly is
+    unsigned long pos = block * sbat->blockSize;
+    unsigned long bbindex = pos / bbat->blockSize;
+    if( bbindex >= sb_blocks.size() ) break;
+
+    loadBigBlock( sb_blocks[ bbindex ], buf, bbat->blockSize );
+
+    // copy the data
+    unsigned offset = pos % bbat->blockSize;
+    unsigned long p = (maxlen-bytes < bbat->blockSize-offset ) ? maxlen-bytes :  bbat->blockSize-offset;
+    p = (sbat->blockSize<p ) ? sbat->blockSize : p;
+    memcpy( data + bytes, buf + offset, p );
+    bytes += p;
+  }
+  
+  delete[] buf;
+
+  return bytes;
+}
+
+unsigned long StorageIO::loadSmallBlock( unsigned long block,
+  unsigned char* data, unsigned long maxlen )
+{
+  // sentinel
+  if( !data ) return 0;
+
+  // wraps call for loadSmallBlocks
+  std::vector<unsigned long> blocks;
+  blocks.resize( 1 );
+  blocks.assign( 1, block );
+
+  return loadSmallBlocks( blocks, data, maxlen );
+}
+
+// =========== StreamIO ==========
+
+StreamIO::StreamIO( StorageIO* s, DirEntry* e)
+{
+  io = s;
+  entry = e;
+  eof = false;
+  fail = false;
+  
+  m_pos = 0;
+
+  if( entry->size >= io->header->threshold ) 
+    blocks = io->bbat->follow( entry->start );
+  else
+    blocks = io->sbat->follow( entry->start );
+
+  // prepare cache
+  cache_pos = 0;
+  cache_size = 4096; // optimal ?
+  cache_data = new unsigned char[cache_size];
+  updateCache();
+}
+
+// FIXME tell parent we're gone
+StreamIO::~StreamIO()
+{
+  delete[] cache_data;  
+}
+
+unsigned long StreamIO::tell()
+{
+  return m_pos;
+}
+
+int StreamIO::getch()
+{
+  // past end-of-file ?
+  if( m_pos > entry->size ) return -1;
+
+  // need to update cache ?
+  if( !cache_size || ( m_pos < cache_pos ) ||
+    ( m_pos >= cache_pos + cache_size ) )
+      updateCache();
+
+  // something bad if we don't get good cache
+  if( !cache_size ) return -1;
+
+  int data = cache_data[m_pos - cache_pos];
+  m_pos++;
+
+  return data;
+}
+
+unsigned long StreamIO::read( unsigned long pos, unsigned char* data, unsigned long maxlen )
+{
+  // sanity checks
+  if( !data ) return 0;
+  if( maxlen == 0 ) return 0;
+
+  unsigned long totalbytes = 0;
+  
+  if ( entry->size < io->header->threshold )
+  {
+    // small file
+    unsigned long index = pos / io->sbat->blockSize;
+
+    if( index >= blocks.size() ) return 0;
+
+    unsigned char* buf = new unsigned char[ io->sbat->blockSize ];
+    unsigned long offset = pos % io->sbat->blockSize;
+    while( totalbytes < maxlen )
+    {
+      if( index >= blocks.size() ) break;
+      io->loadSmallBlock( blocks[index], buf, io->bbat->blockSize );
+      unsigned long count = io->sbat->blockSize - offset;
+      if( count > maxlen-totalbytes ) count = maxlen-totalbytes;
+      memcpy( data+totalbytes, buf + offset, count );
+      totalbytes += count;
+      offset = 0;
+      index++;
+    }
+    delete[] buf;
+
+  }
+  else
+  {
+    // big file
+    unsigned long index = pos / io->bbat->blockSize;
+    
+    if( index >= blocks.size() ) return 0;
+    
+    unsigned char* buf = new unsigned char[ io->bbat->blockSize ];
+    unsigned long offset = pos % io->bbat->blockSize;
+    while( totalbytes < maxlen )
+    {
+      if( index >= blocks.size() ) break;
+      io->loadBigBlock( blocks[index], buf, io->bbat->blockSize );
+      unsigned long count = io->bbat->blockSize - offset;
+      if( count > maxlen-totalbytes ) count = maxlen-totalbytes;
+      memcpy( data+totalbytes, buf + offset, count );
+      totalbytes += count;
+      index++;
+      offset = 0;
+    }
+    delete [] buf;
+
+  }
+
+  return totalbytes;
+}
+
+unsigned long StreamIO::read( unsigned char* data, unsigned long maxlen )
+{
+  unsigned long bytes = read( tell(), data, maxlen );
+  m_pos += bytes;
+  return bytes;
+}
+
+void StreamIO::updateCache()
+{
+  // sanity check
+  if( !cache_data ) return;
+
+  cache_pos = m_pos - ( m_pos % cache_size );
+  unsigned long bytes = cache_size;
+  if( cache_pos + bytes > entry->size ) bytes = entry->size - cache_pos;
+  cache_size = read( cache_pos, cache_data, bytes );
+}
+
+
+// =========== Storage ==========
+
+Storage::Storage( const std::stringstream &memorystream )
+{
+  io = new StorageIO( this, memorystream );
+}
+
+Storage::~Storage()
+{
+  delete io;
+}
+
+int Storage::result()
+{
+  return io->result;
+}
+
+bool Storage::isOle()
+{
+  return io->isOle();
+}
+
+// =========== Stream ==========
+
+Stream::Stream( Storage* storage, const std::string& name )
+{
+  io = storage->io->streamIO( name );
+}
+
+// FIXME tell parent we're gone
+Stream::~Stream()
+{
+  delete io;
+}
+
+unsigned long Stream::size()
+{
+  return io ? io->entry->size : 0;
+}
+
+unsigned long Stream::read( unsigned char* data, unsigned long maxlen )
+{
+  return io ? io->read( data, maxlen ) : 0;
+}
diff --git a/src/extension/internal/libwpg/WPGOLEStream.h b/src/extension/internal/libwpg/WPGOLEStream.h
new file mode 100644 (file)
index 0000000..49562bf
--- /dev/null
@@ -0,0 +1,120 @@
+/* POLE - Portable C++ library to access OLE Storage 
+   Copyright (C) 2002-2005 Ariya Hidayat <ariya@kde.org>
+\r
+   Redistribution and use in source and binary forms, with or without \r
+   modification, are permitted provided that the following conditions \r
+   are met:\r
+   * Redistributions of source code must retain the above copyright notice, \r
+     this list of conditions and the following disclaimer.\r
+   * Redistributions in binary form must reproduce the above copyright notice, \r
+     this list of conditions and the following disclaimer in the documentation \r
+     and/or other materials provided with the distribution.\r
+   * Neither the name of the authors nor the names of its contributors may be \r
+     used to endorse or promote products derived from this software without \r
+     specific prior written permission.\r
+\r
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" \r
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \r
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \r
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF \r
+   THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef WPGOLESTREAM_H
+#define WPGOLESTREAM_H
+
+#include <string>
+#include <fstream>
+#include <sstream>
+#include <list>
+
+namespace libwpg
+{
+
+class StorageIO;
+class Stream;
+class StreamIO;
+
+class Storage
+{
+  friend class Stream;
+
+public:
+\r
+  // for Storage::result()
+  enum { Ok, OpenFailed, NotOLE, BadOLE, UnknownError };\r
+  \r
+  /**
+   * Constructs a storage with data.
+   **/
+  Storage( const std::stringstream &memorystream );
+
+  /**
+   * Destroys the storage.
+   **/
+  ~Storage();
+  
+  /**
+   * Checks whether the storage is OLE2 storage.
+   **/
+  bool isOle();
+
+  /**
+   * Returns the error code of last operation.
+   **/
+  int result();
+  
+private:
+  StorageIO* io;
+  
+  // no copy or assign
+  Storage( const Storage& );
+  Storage& operator=( const Storage& );
+
+};
+
+class Stream
+{
+  friend class Storage;
+  friend class StorageIO;
+  
+public:\r
+\r
+  /**\r
+   * Creates a new stream.\r
+   */\r
+  // name must be absolute, e.g "/PerfectOffice_MAIN"\r
+  Stream( Storage* storage, const std::string& name );\r
+\r
+  /**\r
+   * Destroys the stream.\r
+   */\r
+  ~Stream();
+\r
+  /**
+   * Returns the stream size.
+   **/
+  unsigned long size();
+
+  /**
+   * Reads a block of data.
+   **/
+  unsigned long read( unsigned char* data, unsigned long maxlen );\r
+  \r
+private:
+  StreamIO* io;
+\r
+  // no copy or assign
+  Stream( const Stream& );
+  Stream& operator=( const Stream& );    
+};
+
+}  // namespace libwpg
+
+#endif // WPGOLESTREAM_H
diff --git a/src/extension/internal/libwpg/WPGPaintInterface.h b/src/extension/internal/libwpg/WPGPaintInterface.h
new file mode 100644 (file)
index 0000000..71f4a7a
--- /dev/null
@@ -0,0 +1,71 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGPAINTINTERFACE_H__
+#define __WPGPAINTINTERFACE_H__
+
+#include "WPGBrush.h"
+#include "WPGPath.h"
+#include "WPGPen.h"
+#include "WPGPoint.h"
+#include "WPGRect.h"
+
+namespace libwpg
+{
+
+class WPGPaintInterface {
+public:
+
+       // none of the other callback functions will be called before this function is called
+       virtual void startDocument(double width, double height) = 0;
+
+       virtual void setPen(const WPGPen& pen) = 0;
+       
+       virtual void setBrush(const WPGBrush& brush) = 0;
+
+       typedef enum { AlternatingFill, WindingFill } FillRule;
+       virtual void setFillRule(FillRule rule ) = 0;
+
+       virtual void startLayer(unsigned int id) = 0;
+
+       virtual void endLayer(unsigned int id) = 0;
+
+       virtual void drawRectangle(const WPGRect& rect, double rx, double ry) = 0;
+
+       virtual void drawEllipse(const WPGPoint& center, double rx, double ry) = 0;
+
+       virtual void drawPolygon(const WPGPointArray& vertices) = 0;
+
+       virtual void drawPath(const WPGPath& path) = 0;
+
+       // none of the other callback functions will be called after this function is called
+       virtual void endDocument() = 0;
+};
+
+} // namespace libwpg
+
+#endif // __WPGPAINTINTERFACE_H__
diff --git a/src/extension/internal/libwpg/WPGPath.cpp b/src/extension/internal/libwpg/WPGPath.cpp
new file mode 100644 (file)
index 0000000..c04754d
--- /dev/null
@@ -0,0 +1,106 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "WPGPath.h"
+#include "WPGPoint.h"
+
+#include <vector>
+
+namespace libwpg
+{
+
+class WPGPathPrivate
+{
+public:
+       std::vector<WPGPathElement> elements;
+};
+
+} // namespace libwpg
+
+using namespace libwpg;
+
+WPGPath::WPGPath()
+{
+       d = new WPGPathPrivate;
+}
+       
+WPGPath::~WPGPath()
+{
+       delete d;
+}
+       
+WPGPath::WPGPath(const WPGPath& path)
+{
+       d = new WPGPathPrivate;
+       d->elements = path.d->elements;
+}
+       
+WPGPath& WPGPath::operator=(const WPGPath& path)
+{
+       d->elements = path.d->elements;
+       return *this;
+}
+       
+unsigned WPGPath::count() const
+{
+       return d->elements.size();
+}
+       
+WPGPathElement WPGPath::element(unsigned index) const
+{
+       return d->elements[index];
+}
+       
+void WPGPath::moveTo(const WPGPoint& point)
+{
+       WPGPathElement element;
+       element.type = WPGPathElement::MoveToElement;
+       element.point = point;
+       addElement(element);
+}
+       
+void WPGPath::lineTo(const WPGPoint& point)
+{
+       WPGPathElement element;
+       element.type = WPGPathElement::LineToElement;
+       element.point = point;
+       addElement(element);
+}
+       
+void WPGPath::curveTo(const WPGPoint& c1, const WPGPoint& c2, const WPGPoint& endPoint)
+{
+       WPGPathElement element;
+       element.type = WPGPathElement::CurveToElement;
+       element.point = endPoint;
+       element.extra1 = c1;
+       element.extra2 = c2;
+       addElement(element);
+}
+       
+void WPGPath::addElement(const WPGPathElement& element)
+{
+       d->elements.push_back(element);
+}
+       
diff --git a/src/extension/internal/libwpg/WPGPath.h b/src/extension/internal/libwpg/WPGPath.h
new file mode 100644 (file)
index 0000000..889d478
--- /dev/null
@@ -0,0 +1,85 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGPATH_H__
+#define __WPGPATH_H__
+
+#include "WPGPoint.h"
+
+namespace libwpg
+{
+
+class WPGPathElement
+{
+public:
+       typedef enum 
+       {
+               NullElement,
+               MoveToElement,
+               LineToElement,
+               CurveToElement
+       } Type;
+       
+       Type type;
+       WPGPoint point;
+       WPGPoint extra1;
+       WPGPoint extra2;
+       
+       WPGPathElement(): type(NullElement) {}
+};
+
+class WPGPathPrivate;
+
+class WPGPath
+{
+public:
+       
+       WPGPath();
+       
+       ~WPGPath();
+       
+       WPGPath(const WPGPath&);
+       
+       WPGPath& operator=(const WPGPath&);
+       
+       unsigned count() const;
+       
+       WPGPathElement element(unsigned index) const;
+       
+       void moveTo(const WPGPoint& point);
+       
+       void lineTo(const WPGPoint& point);
+
+       void curveTo(const WPGPoint& c1, const WPGPoint& c2, const WPGPoint& endPoint);
+       
+       void addElement(const WPGPathElement& element);
+       
+private:
+       WPGPathPrivate *d;
+};
+
+} // namespace libwpg
+
+#endif // __WPGPATH_H__
diff --git a/src/extension/internal/libwpg/WPGPen.cpp b/src/extension/internal/libwpg/WPGPen.cpp
new file mode 100644 (file)
index 0000000..f59fda6
--- /dev/null
@@ -0,0 +1,76 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "WPGPen.h"
+
+#include <vector>
+
+namespace libwpg
+{
+class WPGDashArrayPrivate
+{
+public:
+       std::vector<double> dashes;
+};
+}
+       
+using namespace libwpg;
+
+WPGDashArray::WPGDashArray()
+{
+       d = new WPGDashArrayPrivate;
+}
+
+WPGDashArray::~WPGDashArray()
+{
+       delete d;
+}
+
+WPGDashArray::WPGDashArray(const WPGDashArray& dash)
+{
+       d = new WPGDashArrayPrivate;
+       d->dashes = dash.d->dashes;
+}
+
+WPGDashArray& WPGDashArray::operator=(const WPGDashArray& dash)
+{
+       d->dashes = dash.d->dashes;
+       return *this;
+}
+
+unsigned WPGDashArray::count() const
+{
+       return d->dashes.size();
+}
+
+double WPGDashArray::at(unsigned i) const
+{
+       return d->dashes[i];
+}
+
+void WPGDashArray::add(double p)
+{
+       d->dashes.push_back(p);
+}
diff --git a/src/extension/internal/libwpg/WPGPen.h b/src/extension/internal/libwpg/WPGPen.h
new file mode 100644 (file)
index 0000000..acef05e
--- /dev/null
@@ -0,0 +1,112 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGPEN_H__
+#define __WPGPEN_H__
+
+#include "WPGColor.h"
+
+namespace libwpg
+{
+
+class WPGDashArrayPrivate;
+
+class WPGDashArray
+{
+public:
+       WPGDashArray();
+       ~WPGDashArray();
+       WPGDashArray(const WPGDashArray&);
+       WPGDashArray& operator=(const WPGDashArray&);
+       unsigned count() const;
+       double at(unsigned i) const;
+       void add(double p);
+
+private:
+       WPGDashArrayPrivate *d;
+};
+
+class WPGPen
+{
+public:
+       WPGColor foreColor;
+       WPGColor backColor;
+       double width;
+       double height;
+       bool solid;
+       WPGDashArray dashArray;
+
+       WPGPen(): 
+               foreColor(0,0,0), 
+               backColor(0,0,0), 
+               width(0), 
+               height(0), 
+               solid(true) 
+               {};
+
+       WPGPen(const WPGColor& fore): 
+               foreColor(fore), 
+               backColor(0,0,0), 
+               width(0), 
+               height(0), 
+               solid(true) 
+               {};
+
+       WPGPen(const WPGColor& fore, const WPGColor& back): 
+               foreColor(fore),  
+               backColor(back), 
+               width(0), 
+               height(0), 
+               solid(true) 
+               {};
+
+       WPGPen(const WPGPen& pen)
+       { 
+               foreColor = pen.foreColor; 
+               backColor = pen.backColor;
+               width = pen.width;
+               height = pen.height;
+               solid = pen.solid;
+               dashArray = pen.dashArray;
+       }
+
+       WPGPen& operator=(const WPGPen& pen)
+       { 
+               foreColor = pen.foreColor; 
+               backColor = pen.backColor;
+               width = pen.width;
+               height = pen.height;
+               solid = pen.solid;
+               dashArray = pen.dashArray;
+               return *this;
+       }
+       
+       static WPGPen NoPen;
+};
+
+} // namespace libwpg
+
+
+#endif // __WPGPEN_H__
diff --git a/src/extension/internal/libwpg/WPGPoint.cpp b/src/extension/internal/libwpg/WPGPoint.cpp
new file mode 100644 (file)
index 0000000..4c54c27
--- /dev/null
@@ -0,0 +1,89 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "WPGPoint.h"
+
+#include <vector>
+
+namespace libwpg
+{
+
+class WPGPointArrayPrivate
+{
+public:
+       std::vector<WPGPoint> points;
+};
+
+}
+       
+using namespace libwpg;
+
+
+WPGPointArray::WPGPointArray()
+{
+       d = new WPGPointArrayPrivate;
+}
+
+WPGPointArray::~WPGPointArray()
+{
+       delete d;
+}
+
+WPGPointArray::WPGPointArray(const WPGPointArray& pa)
+{
+       d = new WPGPointArrayPrivate;
+       d->points = pa.d->points;
+}
+
+WPGPointArray& WPGPointArray::operator=(const WPGPointArray& pa)
+{
+       d->points = pa.d->points;
+       return *this;
+}
+
+unsigned WPGPointArray::count() const
+{
+       return d->points.size();
+}
+
+WPGPoint& WPGPointArray::at(unsigned i)
+{
+       return d->points[i];
+}
+
+const WPGPoint& WPGPointArray::at(unsigned i) const
+{
+       return d->points[i];
+}
+
+const WPGPoint& WPGPointArray::operator[](unsigned i) const
+{
+       return d->points[i];
+}
+
+void WPGPointArray::add(const WPGPoint& p)
+{
+       d->points.push_back(p);
+}
diff --git a/src/extension/internal/libwpg/WPGPoint.h b/src/extension/internal/libwpg/WPGPoint.h
new file mode 100644 (file)
index 0000000..2dcb55a
--- /dev/null
@@ -0,0 +1,72 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGPOINT_H__
+#define __WPGPOINT_H__
+
+#include "WPGColor.h"
+
+namespace libwpg
+{
+
+class WPGPoint
+{
+public:
+       double x;
+       double y;
+
+       WPGPoint(): x(0.0), y(0.0) {}
+
+       WPGPoint(double xx, double yy): x(xx), y(yy) {}
+
+       WPGPoint(const WPGPoint& point)
+       { x = point.x; y = point.y; }
+
+       WPGPoint& operator=(const WPGPoint& point)
+       { x = point.x; y = point.y; return *this; }
+};
+
+class WPGPointArrayPrivate;
+
+class WPGPointArray
+{
+public:
+       WPGPointArray();
+       ~WPGPointArray();
+       WPGPointArray(const WPGPointArray&);
+       WPGPointArray& operator=(const WPGPointArray&);
+       unsigned count() const;
+       WPGPoint& at(unsigned i);
+       const WPGPoint& at(unsigned i) const;
+       const WPGPoint& operator[](unsigned i) const;
+       void add(const WPGPoint& p);
+       
+private:
+       WPGPointArrayPrivate *d;
+};
+
+} // namespace libwpg
+
+#endif // __WPGPOINT_H__
diff --git a/src/extension/internal/libwpg/WPGRect.h b/src/extension/internal/libwpg/WPGRect.h
new file mode 100644 (file)
index 0000000..b122b43
--- /dev/null
@@ -0,0 +1,59 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGRECT_H__
+#define __WPGRECT_H__
+
+#include "WPGColor.h"
+
+namespace libwpg
+{
+
+class WPGRect
+{
+public:
+       double x1;
+       double y1;
+       double x2;
+       double y2;
+
+       WPGRect(): x1(0.0), y1(0.0), x2(0.0), y2(0.0) {}
+
+       WPGRect(double xx1, double yy1, double xx2, double yy2): 
+       x1(xx1), y1(yy1), x2(xx2), y2(yy2) {}
+
+       WPGRect(const WPGRect& rect)
+       { x1 = rect.x1; y1 = rect.y1; x2 = rect.x2; y2 = rect.y2; }
+
+       WPGRect& operator=(const WPGRect& rect)
+       { x1 = rect.x1; y1 = rect.y1; x2 = rect.x2; y2 = rect.y2; return *this; }
+
+       double width() const { return x2-x1; }
+       double height() const { return y2-y1; }
+};
+
+} // namespace libwpg
+
+#endif // __WPGRECT_H__
diff --git a/src/extension/internal/libwpg/WPGStream.h b/src/extension/internal/libwpg/WPGStream.h
new file mode 100644 (file)
index 0000000..1b6a46c
--- /dev/null
@@ -0,0 +1,47 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGSTREAM_H__
+#define __WPGSTREAM_H__
+
+namespace libwpg
+{
+
+class WPGInputStream
+{
+public:
+       virtual unsigned char getc() = 0;
+       virtual long read(long n, char* buffer) = 0;
+       virtual long tell() = 0;
+       virtual void seek(long offset) = 0;
+       virtual bool atEnd() = 0;
+
+       virtual bool isOle() = 0;
+       virtual WPGInputStream *getWPGOleStream() = 0;
+};
+
+} // namespace wpg
+
+#endif // __WPGSTREAM_H__
diff --git a/src/extension/internal/libwpg/WPGStreamImplementation.cpp b/src/extension/internal/libwpg/WPGStreamImplementation.cpp
new file mode 100644 (file)
index 0000000..bd0c59c
--- /dev/null
@@ -0,0 +1,239 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "WPGStreamImplementation.h"
+#include "WPGOLEStream.h"
+#include "libwpg_utils.h"
+
+#include <fstream>
+#include <sstream>
+#include <string>
+
+// MSVC++ 6.0 defines getc as macro, so undefine it
+#undef getc
+
+namespace libwpg
+{
+
+class WPGFileStreamPrivate
+{
+public:
+       WPGFileStreamPrivate();
+       std::fstream file;
+       std::stringstream buffer;
+};
+
+class WPGMemoryStreamPrivate
+{
+public:
+       WPGMemoryStreamPrivate(const std::string str);
+       std::stringstream buffer;
+};
+
+} // namespace libwpg
+
+using namespace libwpg;
+
+WPGFileStreamPrivate::WPGFileStreamPrivate() :
+       buffer(std::ios::binary | std::ios::in | std::ios::out)
+{
+}
+
+WPGMemoryStreamPrivate::WPGMemoryStreamPrivate(const std::string str) :
+       buffer(str, std::ios::binary | std::ios::in)
+{
+}
+
+
+WPGFileStream::WPGFileStream(const char* filename)
+{
+       d = new WPGFileStreamPrivate;
+       
+       d->file.open( filename, std::ios::binary | std::ios::in );
+}
+
+WPGFileStream::~WPGFileStream()
+{
+       delete d;
+}
+
+unsigned char WPGFileStream::getc()
+{
+       return d->file.get();
+}
+
+long WPGFileStream::read(long nbytes, char* buffer)
+{
+       long nread = 0;
+       
+       if(d->file.good())
+       {
+       long curpos = d->file.tellg();
+       d->file.read(buffer, nbytes); 
+       nread = (long)d->file.tellg() - curpos;
+       }
+       
+       return nread;
+}
+
+long WPGFileStream::tell()
+{
+       return d->file.good() ? (long)d->file.tellg() : -1L;
+}
+
+void WPGFileStream::seek(long offset)
+{
+       if(d->file.good())
+               d->file.seekg(offset);
+}
+
+bool WPGFileStream::atEnd()
+{
+       return d->file.eof();
+}
+
+bool WPGFileStream::isOle()
+{
+       if (d->buffer.str().empty())
+               d->buffer << d->file.rdbuf();
+       Storage tmpStorage( d->buffer );
+       if (tmpStorage.isOle())
+               return true;
+       return false;
+}
+
+WPGInputStream* WPGFileStream::getWPGOleStream()
+{
+       if (d->buffer.str().empty())
+               d->buffer << d->file.rdbuf();
+       Storage *tmpStorage = new Storage( d->buffer );
+       Stream tmpStream( tmpStorage, "PerfectOffice_MAIN" );
+       if (!tmpStorage || (tmpStorage->result() != Storage::Ok)  || !tmpStream.size())
+       {
+               if (tmpStorage)
+                       delete tmpStorage;
+               return (WPGInputStream*)0;
+       }
+       
+       unsigned char *tmpBuffer = new unsigned char[tmpStream.size()];
+       unsigned long tmpLength;
+       tmpLength = tmpStream.read(tmpBuffer, tmpStream.size());
+
+       // sanity check
+       if (tmpLength > tmpStream.size() || tmpLength < tmpStream.size())
+       /* something went wrong here and we do not trust the
+          resulting buffer */
+       {
+               if (tmpStorage)
+                       delete tmpStorage;
+               return (WPGInputStream*)0;
+       }
+
+       delete tmpStorage;
+       return new WPGMemoryStream((const char *)tmpBuffer, tmpLength);
+}
+
+
+WPGMemoryStream::WPGMemoryStream(const char *data, const unsigned int dataSize)
+{
+       d = new WPGMemoryStreamPrivate(std::string(data, dataSize));
+}
+
+WPGMemoryStream::~WPGMemoryStream()
+{
+       delete d;
+}
+
+unsigned char WPGMemoryStream::getc()
+{
+       return d->buffer.get();
+}
+
+long WPGMemoryStream::read(long nbytes, char* buffer)
+{
+       long nread = 0;
+       
+       if(d->buffer.good())
+       {
+       long curpos = d->buffer.tellg();
+       d->buffer.read(buffer, nbytes); 
+       nread = (long)d->buffer.tellg() - curpos;
+       }
+       
+       return nread;
+}
+
+long WPGMemoryStream::tell()
+{
+       return d->buffer.good() ? (long)d->buffer.tellg() : -1L;
+}
+
+void WPGMemoryStream::seek(long offset)
+{
+       if(d->buffer.good())
+               d->buffer.seekg(offset);
+}
+
+bool WPGMemoryStream::atEnd()
+{
+       return d->buffer.eof();
+}
+
+bool WPGMemoryStream::isOle()
+{
+       Storage tmpStorage( d->buffer );
+       if (tmpStorage.isOle())
+               return true;
+       return false;
+}
+
+WPGInputStream* WPGMemoryStream::getWPGOleStream()
+{
+       Storage *tmpStorage = new Storage( d->buffer );
+       Stream tmpStream( tmpStorage, "PerfectOffice_MAIN" );
+       if (!tmpStorage || (tmpStorage->result() != Storage::Ok)  || !tmpStream.size())
+       {
+               if (tmpStorage)
+                       delete tmpStorage;
+               return (WPGInputStream*)0;
+       }
+       
+       unsigned char *tmpBuffer = new unsigned char[tmpStream.size()];
+       unsigned long tmpLength;
+       tmpLength = tmpStream.read(tmpBuffer, tmpStream.size());
+
+       // sanity check
+       if (tmpLength > tmpStream.size() || tmpLength < tmpStream.size())
+       /* something went wrong here and we do not trust the
+          resulting buffer */
+       {
+               if (tmpStorage)
+                       delete tmpStorage;
+               return (WPGInputStream*)0;
+       }
+
+       delete tmpStorage;
+       return new WPGMemoryStream((const char *)tmpBuffer, tmpLength);
+}
diff --git a/src/extension/internal/libwpg/WPGStreamImplementation.h b/src/extension/internal/libwpg/WPGStreamImplementation.h
new file mode 100644 (file)
index 0000000..d6ebdf8
--- /dev/null
@@ -0,0 +1,82 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __WPGSTREAMIMPLEMENTATION_H__
+#define __WPGSTREAMIMPLEMENTATION_H__
+
+#include "WPGStream.h"
+
+namespace libwpg
+{
+
+class WPGFileStreamPrivate;
+
+class WPGFileStream: public WPGInputStream
+{
+public:
+       WPGFileStream(const char* filename);
+       ~WPGFileStream();
+       
+       virtual unsigned char getc();
+       virtual long read(long n, char* buffer);
+       virtual long tell();
+       virtual void seek(long offset);
+       virtual bool atEnd();
+
+       virtual bool isOle();
+       virtual WPGInputStream *getWPGOleStream();
+
+private:
+       WPGFileStreamPrivate* d;
+       WPGFileStream(const WPGFileStream&); // copy is not allowed
+       WPGFileStream& operator=(const WPGFileStream&); // assignment is not allowed
+};
+
+class WPGMemoryStreamPrivate;
+
+class WPGMemoryStream: public WPGInputStream
+{
+public:
+       WPGMemoryStream(const char *data, const unsigned int dataSize);
+       ~WPGMemoryStream();
+
+       virtual unsigned char getc();
+       virtual long read(long n, char* buffer);
+       virtual long tell();
+       virtual void seek(long offset);
+       virtual bool atEnd();
+
+       virtual bool isOle();
+       virtual WPGInputStream *getWPGOleStream();
+
+private:
+       WPGMemoryStreamPrivate* d;
+       WPGMemoryStream(const WPGMemoryStream&); // copy is not allowed
+       WPGMemoryStream& operator=(const WPGMemoryStream&); // assignment is not allowed
+};
+
+} // namespace wpg
+
+#endif // __WPGSTREAMIMPLEMENTATION_H__
diff --git a/src/extension/internal/libwpg/WPGXParser.cpp b/src/extension/internal/libwpg/WPGXParser.cpp
new file mode 100644 (file)
index 0000000..dcdc44c
--- /dev/null
@@ -0,0 +1,103 @@
+/* libwpg\r
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)\r
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)\r
+ * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Library General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Library General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Library General Public\r
+ * License along with this library; if not, write to the \r
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, \r
+ * Boston, MA  02111-1301 USA\r
+ *\r
+ * For further information visit http://libwpg.sourceforge.net\r
+ */\r
\r
+/* "This product is not manufactured, approved, or supported by\r
+ * Corel Corporation or Corel Corporation Limited."\r
+ */\r
+\r
+#include "WPGXParser.h"\r
+\r
+using namespace libwpg;\r
+\r
+WPGXParser::WPGXParser(WPGInputStream *input, WPGPaintInterface* painter):\r
+  m_input(input), m_painter(painter)\r
+{\r
+}\r
+\r
+unsigned char WPGXParser::readU8()\r
+{\r
+       return m_input->getc();\r
+}\r
+\r
+unsigned short WPGXParser::readU16()\r
+{\r
+       unsigned short p0 = (unsigned short)readU8();\r
+       unsigned short p1 = (unsigned short)readU8();\r
+       return p0|(p1<<8);\r
+}\r
+\r
+unsigned long WPGXParser::readU32()\r
+{\r
+       unsigned long p0 = (unsigned short)readU8();\r
+       unsigned long p1 = (unsigned short)readU8();\r
+       unsigned long p2 = (unsigned short)readU8();\r
+       unsigned long p3 = (unsigned short)readU8();\r
+       return p0|(p1<<8)|(p2<<16)|(p3<<24);\r
+}\r
+\r
+char WPGXParser::readS8()\r
+{\r
+       return (char)m_input->getc();\r
+}\r
+\r
+short WPGXParser::readS16()\r
+{\r
+       short p0 = readU8();\r
+       short p1 = readS8();\r
+       return p0|(p1<<8);\r
+}\r
+\r
+long WPGXParser::readS32()\r
+{\r
+       long p0 = readU8();\r
+       long p1 = readU8();\r
+       long p2 = readU8();\r
+       long p3 = readS8();\r
+       return p0|(p1<<8)|(p2<<16)|(p3<<24);\r
+}\r
+\r
+unsigned int WPGXParser::readVariableLengthInteger()\r
+{\r
+       // read a byte\r
+       unsigned char value8 = readU8();\r
+       // if it's in the range 0-0xFE, then we have a 8-bit value\r
+       if (value8<=0xFE) {\r
+               return (unsigned int)value8;\r
+       } else {\r
+               // now read a 16 bit value\r
+               unsigned short value16 = readU16();\r
+               // if the MSB is 1, we have a 32 bit value\r
+               if (value16>>15) {\r
+                       // read the next 16 bit value (LSB part, in value16 resides the MSB part)\r
+                       unsigned long lvalue16 = readU16();\r
+                       unsigned long value32 = value16 & 0x7fff;  // mask out the MSB\r
+                       return (value32<<16)+lvalue16;\r
+               } else {\r
+                       // we have a 16 bit value, return it\r
+                       return (unsigned int)value16;\r
+               }\r
+       }\r
+       \r
+       // unreachable\r
+       return 0;\r
+}\r
diff --git a/src/extension/internal/libwpg/WPGXParser.h b/src/extension/internal/libwpg/WPGXParser.h
new file mode 100644 (file)
index 0000000..d98fd0b
--- /dev/null
@@ -0,0 +1,59 @@
+/* libwpg\r
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)\r
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)\r
+ * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Library General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Library General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Library General Public\r
+ * License along with this library; if not, write to the \r
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, \r
+ * Boston, MA  02111-1301 USA\r
+ *\r
+ * For further information visit http://libwpg.sourceforge.net\r
+ */\r
+\r
+/* "This product is not manufactured, approved, or supported by\r
+ * Corel Corporation or Corel Corporation Limited."\r
+ */\r
+\r
+#ifndef __WPGXPARSER_H__\r
+#define __WPGXPARSER_H__\r
+\r
+#include "WPGPaintInterface.h"\r
+#include "WPGStream.h"\r
+#include "WPGColor.h"\r
+\r
+#include <map>\r
+\r
+using namespace libwpg;\r
+\r
+class WPGXParser\r
+{\r
+public:\r
+       WPGXParser(WPGInputStream *input, WPGPaintInterface* painter);\r
+       virtual bool parse() = 0;\r
+       \r
+       unsigned char readU8();\r
+       unsigned short readU16();  \r
+       unsigned long readU32();  \r
+       char readS8();\r
+       short readS16();  \r
+       long readS32();  \r
+       unsigned int readVariableLengthInteger();\r
+       \r
+protected:\r
+       WPGInputStream* m_input;\r
+       WPGPaintInterface* m_painter;\r
+       std::map<int,WPGColor> m_colorPalette;\r
+};\r
+\r
+#endif // __WPGXPARSER_H__\r
diff --git a/src/extension/internal/libwpg/WPGraphics.cpp b/src/extension/internal/libwpg/WPGraphics.cpp
new file mode 100644 (file)
index 0000000..a7454d2
--- /dev/null
@@ -0,0 +1,83 @@
+/* libwpg\r
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Library General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Library General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Library General Public\r
+ * License along with this library; if not, write to the \r
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, \r
+ * Boston, MA  02111-1301 USA\r
+ *\r
+ * For further information visit http://libwpg.sourceforge.net\r
+ */\r
+\r
+/* "This product is not manufactured, approved, or supported by\r
+ * Corel Corporation or Corel Corporation Limited."\r
+ */\r
+\r
+#include "WPGraphics.h"\r
+#include "WPGHeader.h"\r
+#include "WPGStream.h"\r
+#include "WPGXParser.h"\r
+#include "WPG1Parser.h"\r
+#include "WPG2Parser.h"\r
+#include "libwpg_utils.h"\r
+\r
+using namespace libwpg;\r
+\r
+bool WPGraphics::isSupported(WPGInputStream* input)\r
+{\r
+       WPGHeader header;\r
+       if(!header.load(input))\r
+               return false;\r
+       \r
+       return header.isSupported();\r
+}\r
+\r
+bool WPGraphics::parse(WPGInputStream* input, WPGPaintInterface* painter)\r
+{\r
+       WPGXParser *parser = 0;\r
+       \r
+       WPG_DEBUG_MSG(("Loading header...\n"));\r
+       WPGHeader header;\r
+       if(!header.load(input))\r
+               return false;\r
+       \r
+       if(!header.isSupported())\r
+       {\r
+               WPG_DEBUG_MSG(("Unsupported file format!\n"));\r
+               return false;  \r
+       }\r
+       \r
+       // seek to the start of document\r
+       input->seek(header.startOfDocument());\r
+       \r
+       switch (header.majorVersion()) {\r
+               case 0x01: // WPG1\r
+                       WPG_DEBUG_MSG(("Parsing WPG1\n"));\r
+                       parser = new WPG1Parser(input, painter);\r
+                       parser->parse();\r
+                       break;\r
+               case 0x02: // WPG2\r
+                       WPG_DEBUG_MSG(("Parsing WPG2\n"));\r
+                       parser = new WPG2Parser(input, painter);\r
+                       parser->parse();\r
+                       break;\r
+               default: // other :-)\r
+                       WPG_DEBUG_MSG(("Unknown format\n"));\r
+                       break;\r
+       }\r
+       \r
+       delete parser;\r
+       \r
+       return false;\r
+}\r
\r
diff --git a/src/extension/internal/libwpg/WPGraphics.h b/src/extension/internal/libwpg/WPGraphics.h
new file mode 100644 (file)
index 0000000..3226835
--- /dev/null
@@ -0,0 +1,46 @@
+/* libwpg\r
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Library General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Library General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Library General Public\r
+ * License along with this library; if not, write to the \r
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, \r
+ * Boston, MA  02111-1301 USA\r
+ *\r
+ * For further information visit http://libwpg.sourceforge.net\r
+ */\r
+\r
+/* "This product is not manufactured, approved, or supported by\r
+ * Corel Corporation or Corel Corporation Limited."\r
+ */\r
+\r
+#ifndef __WPGRAPHICS_H__\r
+#define __WPGRAPHICS_H__\r
+\r
+namespace libwpg\r
+{\r
+\r
+class WPGInputStream;\r
+class WPGPaintInterface;\r
+\r
+class WPGraphics\r
+{\r
+public:\r
+       \r
+       static bool isSupported(WPGInputStream* input);\r
+       \r
+       static bool parse(WPGInputStream* input, WPGPaintInterface* painter);\r
+};\r
+\r
+} // namespace libwpg\r
+\r
+#endif //  __WPGRAPHICS_H__\r
diff --git a/src/extension/internal/libwpg/libwpg-stream.rc.in b/src/extension/internal/libwpg/libwpg-stream.rc.in
new file mode 100644 (file)
index 0000000..ad297d2
--- /dev/null
@@ -0,0 +1,31 @@
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+  FILEVERSION @WPG_MAJOR_VERSION@,@WPG_MINOR_VERSION@,@WPG_MICRO_VERSION@,BUILDNUMBER
+  PRODUCTVERSION @WPG_MAJOR_VERSION@,@WPG_MINOR_VERSION@,@WPG_MICRO_VERSION@,0
+  FILEFLAGSMASK 0
+  FILEFLAGS 0
+  FILEOS VOS__WINDOWS32
+  FILETYPE VFT_DLL
+  FILESUBTYPE VFT2_UNKNOWN
+  BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+      BLOCK "040904B0"
+      BEGIN
+       VALUE "CompanyName", "The libwpg developer community"
+       VALUE "FileDescription", "libwpg-stream"
+       VALUE "FileVersion", "@WPG_MAJOR_VERSION@.@WPG_MINOR_VERSION@.@WPG_MICRO_VERSION@.BUILDNUMBER"
+       VALUE "InternalName", "libwpg-stream-1"
+       VALUE "LegalCopyright", "Copyright (C) 2004 Marc Oude Kotte, other contributers"
+       VALUE "OriginalFilename", "libwpg-stream-1.dll"
+       VALUE "ProductName", "libwpg"
+       VALUE "ProductVersion", "@WPG_MAJOR_VERSION@.@WPG_MINOR_VERSION@.@WPG_MICRO_VERSION@"
+      END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+      VALUE "Translation", 0x409, 1200
+    END
+  END
+
diff --git a/src/extension/internal/libwpg/libwpg.h.in b/src/extension/internal/libwpg/libwpg.h.in
new file mode 100644 (file)
index 0000000..fcbf993
--- /dev/null
@@ -0,0 +1,47 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __LIBWPG_H__
+#define __LIBWPG_H__
+
+#define LIBWPG_VERSION_MAJOR     @WPG_MAJOR_VERSION@
+#define LIBWPG_VERSION_MINOR     @WPG_MINOR_VERSION@
+#define LIBWPG_VERSION_REVISION  @WPG_MICRO_VERSION@
+#define LIBWPG_VERSION_STRING    "@WPG_MAJOR_VERSION@.@WPG_MINOR_VERSION@.@WPG_MICRO_VERSION@"
+
+#include "WPGraphics.h"
+#include "WPGPaintInterface.h"
+#include "WPGStream.h"
+
+#include "WPGColor.h"
+#include "WPGPen.h"
+#include "WPGBrush.h"
+#include "WPGGradient.h"
+#include "WPGPath.h"
+#include "WPGPoint.h"
+#include "WPGRect.h"
+
+#endif
diff --git a/src/extension/internal/libwpg/libwpg.rc.in b/src/extension/internal/libwpg/libwpg.rc.in
new file mode 100644 (file)
index 0000000..e2278a0
--- /dev/null
@@ -0,0 +1,31 @@
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+  FILEVERSION @WPG_MAJOR_VERSION@,@WPG_MINOR_VERSION@,@WPG_MICRO_VERSION@,BUILDNUMBER
+  PRODUCTVERSION @WPG_MAJOR_VERSION@,@WPG_MINOR_VERSION@,@WPG_MICRO_VERSION@,0
+  FILEFLAGSMASK 0
+  FILEFLAGS 0
+  FILEOS VOS__WINDOWS32
+  FILETYPE VFT_DLL
+  FILESUBTYPE VFT2_UNKNOWN
+  BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+      BLOCK "040904B0"
+      BEGIN
+       VALUE "CompanyName", "The libwpg developer community"
+       VALUE "FileDescription", "libwpg"
+       VALUE "FileVersion", "@WPG_MAJOR_VERSION@.@WPG_MINOR_VERSION@.@WPG_MICRO_VERSION@.BUILDNUMBER"
+       VALUE "InternalName", "libwpg-1"
+       VALUE "LegalCopyright", "Copyright (C) 2004 Marc Oude Kotte, other contributers"
+       VALUE "OriginalFilename", "libwpg-1.dll"
+       VALUE "ProductName", "libwpg"
+       VALUE "ProductVersion", "@WPG_MAJOR_VERSION@.@WPG_MINOR_VERSION@.@WPG_MICRO_VERSION@"
+      END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+      VALUE "Translation", 0x409, 1200
+    END
+  END
+
diff --git a/src/extension/internal/libwpg/libwpg_utils.h b/src/extension/internal/libwpg/libwpg_utils.h
new file mode 100644 (file)
index 0000000..fa61661
--- /dev/null
@@ -0,0 +1,50 @@
+/* libwpg
+ * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef __LIBWPG_UTILS_H__
+#define __LIBWPG_UTILS_H__
+
+#include <stdio.h>
+
+//#define DEBUG // FIXME !
+
+// debug message includes source file and line number
+//#define VERBOSE_DEBUG 1
+
+// do nothing with debug messages in a release compile
+#ifdef DEBUG
+       #ifdef VERBOSE_DEBUG
+               #define WPG_DEBUG_MSG(M) printf("%15s:%5d: ", __FILE__, __LINE__); printf M
+               #define WPG_DEBUG(M) M
+       #else
+               #define WPG_DEBUG_MSG(M) printf M
+               #define WPG_DEBUG(M) M
+       #endif
+#else
+       #define WPG_DEBUG_MSG(M)
+       #define WPG_DEBUG(M)
+#endif
+
+#endif // __LIBWPG_UTILS_H__