From: gouldtj Date: Mon, 31 Jul 2006 05:14:00 +0000 (+0000) Subject: r13105@tres: ted | 2006-07-30 11:08:56 -0700 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=90c0f3f444ce065e7f80b1bf0be768f24c6471a5;p=inkscape.git r13105@tres: ted | 2006-07-30 11:08:56 -0700 Copying in libwpg as it seems they have no releases. --- diff --git a/src/extension/internal/libwpg/.cvsignore b/src/extension/internal/libwpg/.cvsignore new file mode 100644 index 000000000..b49f6ba33 --- /dev/null +++ b/src/extension/internal/libwpg/.cvsignore @@ -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 index 000000000..e8b4495d5 --- /dev/null +++ b/src/extension/internal/libwpg/Makefile.am @@ -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 index 000000000..372aa052c --- /dev/null +++ b/src/extension/internal/libwpg/WPG1Parser.cpp @@ -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 index 000000000..fb238352e --- /dev/null +++ b/src/extension/internal/libwpg/WPG1Parser.h @@ -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 index 000000000..43823d0b2 --- /dev/null +++ b/src/extension/internal/libwpg/WPG2Parser.cpp @@ -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 +#include + +// 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 colors; + std::vector 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 index 000000000..e472ccee0 --- /dev/null +++ b/src/extension/internal/libwpg/WPG2Parser.h @@ -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 +#include + +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 m_penStyles; + bool m_layerOpened; + unsigned int m_layerId; + WPG2TransformMatrix m_matrix; + double m_gradientAngle; + WPGPoint m_gradientRef; + unsigned m_subIndex; + std::stack m_indexStack; + + WPGCompoundPolygon m_currentCompound; + std::stack 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 index 000000000..d8c746a4c --- /dev/null +++ b/src/extension/internal/libwpg/WPGBrush.h @@ -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 index 000000000..8867ae5ad --- /dev/null +++ b/src/extension/internal/libwpg/WPGColor.h @@ -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 index 000000000..566789e56 --- /dev/null +++ b/src/extension/internal/libwpg/WPGGradient.cpp @@ -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 + +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 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 index 000000000..70b487259 --- /dev/null +++ b/src/extension/internal/libwpg/WPGGradient.h @@ -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 index 000000000..8daf35700 --- /dev/null +++ b/src/extension/internal/libwpg/WPGHeader.cpp @@ -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 index 000000000..c68a379aa --- /dev/null +++ b/src/extension/internal/libwpg/WPGHeader.h @@ -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 index 000000000..65c3b0b19 --- /dev/null +++ b/src/extension/internal/libwpg/WPGOLEStream.cpp @@ -0,0 +1,991 @@ +/* POLE - Portable C++ library to access OLE Storage + Copyright (C) 2002-2005 Ariya Hidayat + + 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 +#include +#include +#include +#include + +#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 ); + std::vector 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 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 children( unsigned index ); + void load( unsigned char* buffer, unsigned len ); + void save( unsigned char* buffer ); + private: + std::vector 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 sb_blocks; // blocks for "small" files + + std::list streams; + + StorageIO( Storage* storage, const std::stringstream &memorystream ); + ~StorageIO(); + + bool isOle(); + void load(); + + unsigned long loadBigBlocks( std::vector blocks, unsigned char* buffer, unsigned long maxlen ); + + unsigned long loadBigBlock( unsigned long block, unsigned char* buffer, unsigned long maxlen ); + + unsigned long loadSmallBlocks( std::vector 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 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 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 chain ) +{ + if( chain.size() ) + { + for( unsigned i=0; i AllocTable::follow( unsigned long start ) +{ + std::vector 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 chi = children( j ); + for( unsigned i=0; iname; + 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 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::iterator it; + + for( it = names.begin(); it != names.end(); ++it ) + { + // find among the children of index + std::vector 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& 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 DirTree::children( unsigned index ) +{ + std::vector 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]) && (jblockSize = 1 << header->b_shift; + sbat->blockSize = 1 << header->s_shift; +} + +StorageIO::~StorageIO() +{ + delete sbat; + delete bbat; + delete dirtree; + delete header; + + std::list::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 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 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() ) & ( bytesblockSize * ( 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 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 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; ( iblockSize; + 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

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 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 index 000000000..49562bfd6 --- /dev/null +++ b/src/extension/internal/libwpg/WPGOLEStream.h @@ -0,0 +1,120 @@ +/* POLE - Portable C++ library to access OLE Storage + Copyright (C) 2002-2005 Ariya Hidayat + + 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. +*/ + +#ifndef WPGOLESTREAM_H +#define WPGOLESTREAM_H + +#include +#include +#include +#include + +namespace libwpg +{ + +class StorageIO; +class Stream; +class StreamIO; + +class Storage +{ + friend class Stream; + +public: + + // for Storage::result() + enum { Ok, OpenFailed, NotOLE, BadOLE, UnknownError }; + + /** + * 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: + + /** + * Creates a new stream. + */ + // name must be absolute, e.g "/PerfectOffice_MAIN" + Stream( Storage* storage, const std::string& name ); + + /** + * Destroys the stream. + */ + ~Stream(); + + /** + * Returns the stream size. + **/ + unsigned long size(); + + /** + * Reads a block of data. + **/ + unsigned long read( unsigned char* data, unsigned long maxlen ); + +private: + StreamIO* io; + + // 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 index 000000000..71f4a7adf --- /dev/null +++ b/src/extension/internal/libwpg/WPGPaintInterface.h @@ -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 index 000000000..c04754d42 --- /dev/null +++ b/src/extension/internal/libwpg/WPGPath.cpp @@ -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 + +namespace libwpg +{ + +class WPGPathPrivate +{ +public: + std::vector 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 index 000000000..889d4789c --- /dev/null +++ b/src/extension/internal/libwpg/WPGPath.h @@ -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 index 000000000..f59fda661 --- /dev/null +++ b/src/extension/internal/libwpg/WPGPen.cpp @@ -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 + +namespace libwpg +{ +class WPGDashArrayPrivate +{ +public: + std::vector 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 index 000000000..acef05e2b --- /dev/null +++ b/src/extension/internal/libwpg/WPGPen.h @@ -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 index 000000000..4c54c276a --- /dev/null +++ b/src/extension/internal/libwpg/WPGPoint.cpp @@ -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 + +namespace libwpg +{ + +class WPGPointArrayPrivate +{ +public: + std::vector 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 index 000000000..2dcb55a4a --- /dev/null +++ b/src/extension/internal/libwpg/WPGPoint.h @@ -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 index 000000000..b122b43bc --- /dev/null +++ b/src/extension/internal/libwpg/WPGRect.h @@ -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 index 000000000..1b6a46c0a --- /dev/null +++ b/src/extension/internal/libwpg/WPGStream.h @@ -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 index 000000000..bd0c59cd5 --- /dev/null +++ b/src/extension/internal/libwpg/WPGStreamImplementation.cpp @@ -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 +#include +#include + +// 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 index 000000000..d6ebdf83a --- /dev/null +++ b/src/extension/internal/libwpg/WPGStreamImplementation.h @@ -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 index 000000000..dcdc44c50 --- /dev/null +++ b/src/extension/internal/libwpg/WPGXParser.cpp @@ -0,0 +1,103 @@ +/* libwpg + * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl) + * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * 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 "WPGXParser.h" + +using namespace libwpg; + +WPGXParser::WPGXParser(WPGInputStream *input, WPGPaintInterface* painter): + m_input(input), m_painter(painter) +{ +} + +unsigned char WPGXParser::readU8() +{ + return m_input->getc(); +} + +unsigned short WPGXParser::readU16() +{ + unsigned short p0 = (unsigned short)readU8(); + unsigned short p1 = (unsigned short)readU8(); + return p0|(p1<<8); +} + +unsigned long WPGXParser::readU32() +{ + unsigned long p0 = (unsigned short)readU8(); + unsigned long p1 = (unsigned short)readU8(); + unsigned long p2 = (unsigned short)readU8(); + unsigned long p3 = (unsigned short)readU8(); + return p0|(p1<<8)|(p2<<16)|(p3<<24); +} + +char WPGXParser::readS8() +{ + return (char)m_input->getc(); +} + +short WPGXParser::readS16() +{ + short p0 = readU8(); + short p1 = readS8(); + return p0|(p1<<8); +} + +long WPGXParser::readS32() +{ + long p0 = readU8(); + long p1 = readU8(); + long p2 = readU8(); + long p3 = readS8(); + return p0|(p1<<8)|(p2<<16)|(p3<<24); +} + +unsigned int WPGXParser::readVariableLengthInteger() +{ + // read a byte + unsigned char value8 = readU8(); + // if it's in the range 0-0xFE, then we have a 8-bit value + if (value8<=0xFE) { + return (unsigned int)value8; + } else { + // now read a 16 bit value + unsigned short value16 = readU16(); + // if the MSB is 1, we have a 32 bit value + if (value16>>15) { + // read the next 16 bit value (LSB part, in value16 resides the MSB part) + unsigned long lvalue16 = readU16(); + unsigned long value32 = value16 & 0x7fff; // mask out the MSB + return (value32<<16)+lvalue16; + } else { + // we have a 16 bit value, return it + return (unsigned int)value16; + } + } + + // unreachable + return 0; +} diff --git a/src/extension/internal/libwpg/WPGXParser.h b/src/extension/internal/libwpg/WPGXParser.h new file mode 100644 index 000000000..d98fd0ba4 --- /dev/null +++ b/src/extension/internal/libwpg/WPGXParser.h @@ -0,0 +1,59 @@ +/* libwpg + * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl) + * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * 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 __WPGXPARSER_H__ +#define __WPGXPARSER_H__ + +#include "WPGPaintInterface.h" +#include "WPGStream.h" +#include "WPGColor.h" + +#include + +using namespace libwpg; + +class WPGXParser +{ +public: + WPGXParser(WPGInputStream *input, WPGPaintInterface* painter); + virtual bool parse() = 0; + + unsigned char readU8(); + unsigned short readU16(); + unsigned long readU32(); + char readS8(); + short readS16(); + long readS32(); + unsigned int readVariableLengthInteger(); + +protected: + WPGInputStream* m_input; + WPGPaintInterface* m_painter; + std::map m_colorPalette; +}; + +#endif // __WPGXPARSER_H__ diff --git a/src/extension/internal/libwpg/WPGraphics.cpp b/src/extension/internal/libwpg/WPGraphics.cpp new file mode 100644 index 000000000..a7454d2a1 --- /dev/null +++ b/src/extension/internal/libwpg/WPGraphics.cpp @@ -0,0 +1,83 @@ +/* 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 "WPGraphics.h" +#include "WPGHeader.h" +#include "WPGStream.h" +#include "WPGXParser.h" +#include "WPG1Parser.h" +#include "WPG2Parser.h" +#include "libwpg_utils.h" + +using namespace libwpg; + +bool WPGraphics::isSupported(WPGInputStream* input) +{ + WPGHeader header; + if(!header.load(input)) + return false; + + return header.isSupported(); +} + +bool WPGraphics::parse(WPGInputStream* input, WPGPaintInterface* painter) +{ + WPGXParser *parser = 0; + + WPG_DEBUG_MSG(("Loading header...\n")); + WPGHeader header; + if(!header.load(input)) + return false; + + if(!header.isSupported()) + { + WPG_DEBUG_MSG(("Unsupported file format!\n")); + return false; + } + + // seek to the start of document + input->seek(header.startOfDocument()); + + switch (header.majorVersion()) { + case 0x01: // WPG1 + WPG_DEBUG_MSG(("Parsing WPG1\n")); + parser = new WPG1Parser(input, painter); + parser->parse(); + break; + case 0x02: // WPG2 + WPG_DEBUG_MSG(("Parsing WPG2\n")); + parser = new WPG2Parser(input, painter); + parser->parse(); + break; + default: // other :-) + WPG_DEBUG_MSG(("Unknown format\n")); + break; + } + + delete parser; + + return false; +} + diff --git a/src/extension/internal/libwpg/WPGraphics.h b/src/extension/internal/libwpg/WPGraphics.h new file mode 100644 index 000000000..3226835ca --- /dev/null +++ b/src/extension/internal/libwpg/WPGraphics.h @@ -0,0 +1,46 @@ +/* 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 __WPGRAPHICS_H__ +#define __WPGRAPHICS_H__ + +namespace libwpg +{ + +class WPGInputStream; +class WPGPaintInterface; + +class WPGraphics +{ +public: + + static bool isSupported(WPGInputStream* input); + + static bool parse(WPGInputStream* input, WPGPaintInterface* painter); +}; + +} // namespace libwpg + +#endif // __WPGRAPHICS_H__ diff --git a/src/extension/internal/libwpg/libwpg-stream.rc.in b/src/extension/internal/libwpg/libwpg-stream.rc.in new file mode 100644 index 000000000..ad297d222 --- /dev/null +++ b/src/extension/internal/libwpg/libwpg-stream.rc.in @@ -0,0 +1,31 @@ +#include + +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 index 000000000..fcbf99349 --- /dev/null +++ b/src/extension/internal/libwpg/libwpg.h.in @@ -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 index 000000000..e2278a0a0 --- /dev/null +++ b/src/extension/internal/libwpg/libwpg.rc.in @@ -0,0 +1,31 @@ +#include + +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 index 000000000..fa6166131 --- /dev/null +++ b/src/extension/internal/libwpg/libwpg_utils.h @@ -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 + +//#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__