diff options
author | Fridrich Štrba <fridrich.strba@bluewin.ch> | 2012-11-19 17:25:46 +0100 |
---|---|---|
committer | Fridrich Štrba <fridrich.strba@bluewin.ch> | 2012-11-19 17:25:46 +0100 |
commit | 6ac0f95c9e9094a22aab12a7fa09f95d215a8e4e (patch) | |
tree | e9ef1800c815dfe239d4abfe96cee9fe8af6a771 | |
parent | e0d93202b26d305c48505880b8a67226a1000ef4 (diff) |
Simplify the inheritance a little bit
-rw-r--r-- | build/win32/libvisio.dsp | 12 | ||||
-rw-r--r-- | build/win32/libvisio.vcproj | 30 | ||||
-rw-r--r-- | build/win32/libvisio.vcxproj | 11 | ||||
-rw-r--r-- | src/lib/Makefile.am | 2 | ||||
-rw-r--r-- | src/lib/VSD11Parser.cpp | 351 | ||||
-rw-r--r-- | src/lib/VSD11Parser.h | 66 | ||||
-rw-r--r-- | src/lib/VSDParser.cpp | 301 | ||||
-rw-r--r-- | src/lib/VSDParser.h | 14 | ||||
-rw-r--r-- | src/lib/VisioDocument.cpp | 5 | ||||
-rw-r--r-- | src/lib/makefile.mk | 3 |
10 files changed, 359 insertions, 436 deletions
diff --git a/build/win32/libvisio.dsp b/build/win32/libvisio.dsp index 15c4b19..2ff909a 100644 --- a/build/win32/libvisio.dsp +++ b/build/win32/libvisio.dsp @@ -99,7 +99,11 @@ SOURCE=..\..\src\lib\VisioDocument.cpp # End Source File
# Begin Source File
-SOURCE=..\..\src\lib\VSD11Parser.cpp
+SOURCE=..\..\src\lib\VSD2Parser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\lib\VSD5Parser.cpp
# End Source File
# Begin Source File
@@ -215,7 +219,11 @@ SOURCE=..\..\src\lib\VisioDocument.h # End Source File
# Begin Source File
-SOURCE=..\..\src\lib\VSD11Parser.h
+SOURCE=..\..\src\lib\VSD2Parser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\lib\VSD5Parser.h
# End Source File
# Begin Source File
diff --git a/build/win32/libvisio.vcproj b/build/win32/libvisio.vcproj index e675792..5a321b1 100644 --- a/build/win32/libvisio.vcproj +++ b/build/win32/libvisio.vcproj @@ -239,7 +239,29 @@ </FileConfiguration> </File> <File - RelativePath="..\..\src\lib\VSD11Parser.cpp" + RelativePath="..\..\src\lib\VSD2Parser.cpp" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\..\src\lib\VSD5Parser.cpp" > <FileConfiguration Name="Debug|Win32" @@ -752,7 +774,11 @@ > </File> <File - RelativePath="..\..\src\lib\VSD11Parser.h" + RelativePath="..\..\src\lib\VSD2Parser.h" + > + </File> + <File + RelativePath="..\..\src\lib\VSD5Parser.h" > </File> <File diff --git a/build/win32/libvisio.vcxproj b/build/win32/libvisio.vcxproj index b0c9172..70c2540 100644 --- a/build/win32/libvisio.vcxproj +++ b/build/win32/libvisio.vcxproj @@ -120,7 +120,13 @@ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> - <ClCompile Include="..\..\src\lib\VSD11Parser.cpp"> + <ClCompile Include="..\..\src\lib\VSD2Parser.cpp"> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\..\src\lib\VSD5Parser.cpp"> <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> @@ -260,7 +266,8 @@ <ClInclude Include="..\..\src\lib\tokens.h" /> <ClInclude Include="..\..\src\lib\VDXParser.h" /> <ClInclude Include="..\..\src\lib\VisioDocument.h" /> - <ClInclude Include="..\..\src\lib\VSD11Parser.h" /> + <ClInclude Include="..\..\src\lib\VSD2Parser.h" /> + <ClInclude Include="..\..\src\lib\VSD5Parser.h" /> <ClInclude Include="..\..\src\lib\VSD6Parser.h" /> <ClInclude Include="..\..\src\lib\VSDCharacterList.h" /> <ClInclude Include="..\..\src\lib\VSDCollector.h" /> diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 5c3bf0e..df5f8d3 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -24,7 +24,6 @@ libvisio_@VSD_MAJOR_VERSION@_@VSD_MINOR_VERSION@_la_LDFLAGS = $(version_info) -e libvisio_@VSD_MAJOR_VERSION@_@VSD_MINOR_VERSION@_la_SOURCES = \ libvisio_utils.cpp \ VisioDocument.cpp \ - VSD11Parser.cpp \ VSD2Parser.cpp \ VSD5Parser.cpp \ VSD6Parser.cpp \ @@ -46,7 +45,6 @@ libvisio_@VSD_MAJOR_VERSION@_@VSD_MINOR_VERSION@_la_SOURCES = \ VSDXMLHelper.cpp \ VSDZipStream.cpp \ libvisio_utils.h \ - VSD11Parser.h \ VSD2Parser.h \ VSD5Parser.h \ VSD6Parser.h \ diff --git a/src/lib/VSD11Parser.cpp b/src/lib/VSD11Parser.cpp deleted file mode 100644 index 4c883ee..0000000 --- a/src/lib/VSD11Parser.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* libvisio - * Version: MPL 1.1 / GPLv2+ / LGPLv2+ - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License or as specified alternatively below. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * Major Contributor(s): - * Copyright (C) 2011 Fridrich Strba <fridrich.strba@bluewin.ch> - * Copyright (C) 2011 Eilidh McAdam <tibbylickle@gmail.com> - * - * - * All Rights Reserved. - * - * For minor contributions see the git repository. - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPLv2+"), or - * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"), - * in which case the provisions of the GPLv2+ or the LGPLv2+ are applicable - * instead of those above. - */ - -#include <libwpd-stream/libwpd-stream.h> -#include <locale.h> -#include <sstream> -#include <string> -#include "libvisio_utils.h" -#include "VSD11Parser.h" -#include "VSDInternalStream.h" -#include "VSDDocumentStructure.h" -#include "VSDContentCollector.h" -#include "VSDStylesCollector.h" - -libvisio::VSD11Parser::VSD11Parser(WPXInputStream *input, libwpg::WPGPaintInterface *painter) - : VSDParser(input, painter) -{} - -libvisio::VSD11Parser::~VSD11Parser() -{} - -bool libvisio::VSD11Parser::getChunkHeader(WPXInputStream *input) -{ - unsigned char tmpChar = 0; - while (!input->atEOS() && !tmpChar) - tmpChar = readU8(input); - - if (input->atEOS()) - return false; - else - input->seek(-1, WPX_SEEK_CUR); - - m_header.chunkType = readU32(input); - m_header.id = readU32(input); - m_header.list = readU32(input); - - // Certain chunk types seem to always have a trailer - m_header.trailer = 0; - if (m_header.list != 0 || m_header.chunkType == 0x71 || m_header.chunkType == 0x70 || - m_header.chunkType == 0x6b || m_header.chunkType == 0x6a || m_header.chunkType == 0x69 || - m_header.chunkType == 0x66 || m_header.chunkType == 0x65 || m_header.chunkType == 0x2c) - m_header.trailer += 8; // 8 byte trailer - - m_header.dataLength = readU32(input); - m_header.level = readU16(input); - m_header.unknown = readU8(input); - - unsigned trailerChunks [14] = {0x64, 0x65, 0x66, 0x69, 0x6a, 0x6b, 0x6f, 0x71, - 0x92, 0xa9, 0xb4, 0xb6, 0xb9, 0xc7 - }; - // Add word separator under certain circumstances for v11 - // Below are known conditions, may be more or a simpler pattern - if (m_header.list != 0 || (m_header.level == 2 && m_header.unknown == 0x55) || - (m_header.level == 2 && m_header.unknown == 0x54 && m_header.chunkType == 0xaa) - || (m_header.level == 3 && m_header.unknown != 0x50 && m_header.unknown != 0x54)) - { - m_header.trailer += 4; - } - - for (unsigned i = 0; i < 14; i++) - { - if (m_header.chunkType == trailerChunks[i] && m_header.trailer != 12 && m_header.trailer != 4) - { - m_header.trailer += 4; - break; - } - } - - // Some chunks never have a trailer - if (m_header.chunkType == 0x1f || m_header.chunkType == 0xc9 || - m_header.chunkType == 0x2d || m_header.chunkType == 0xd1) - { - m_header.trailer = 0; - } - return true; -} - -void libvisio::VSD11Parser::readText(WPXInputStream *input) -{ - input->seek(8, WPX_SEEK_CUR); - ::WPXBinaryData textStream; - - // Read up to end of chunk in byte pairs (except from last 2 bytes) - unsigned long numBytesRead = 0; - const unsigned char *tmpBuffer = input->read(m_header.dataLength - 8, numBytesRead); - if (numBytesRead) - { - if (m_isStencilStarted) - { - VSD_DEBUG_MSG(("Found stencil text\n")); - } - textStream.append(tmpBuffer, numBytesRead); - m_shape.m_text = textStream; - m_shape.m_textFormat = libvisio::VSD_TEXT_UTF16; - } - -} - -void libvisio::VSD11Parser::readCharIX(WPXInputStream *input) -{ - VSDFont fontFace; - unsigned charCount = readU32(input); - unsigned fontID = readU16(input); - VSDName font; - std::map<unsigned, VSDName>::const_iterator iter = m_fonts.find(fontID); - if (iter != m_fonts.end()) - font = iter->second; - input->seek(1, WPX_SEEK_CUR); // Color ID - Colour fontColour; // Font Colour - fontColour.r = readU8(input); - fontColour.g = readU8(input); - fontColour.b = readU8(input); - fontColour.a = readU8(input); - - bool bold(false); - bool italic(false); - bool underline(false); - bool doubleunderline(false); - bool strikeout(false); - bool doublestrikeout(false); - bool allcaps(false); - bool initcaps(false); - bool smallcaps(false); - bool superscript(false); - bool subscript(false); - unsigned char fontMod = readU8(input); - if (fontMod & 1) bold = true; - if (fontMod & 2) italic = true; - if (fontMod & 4) underline = true; - if (fontMod & 8) smallcaps = true; - fontMod = readU8(input); - if (fontMod & 1) allcaps = true; - if (fontMod & 2) initcaps = true; - fontMod = readU8(input); - if (fontMod & 1) superscript = true; - if (fontMod & 2) subscript = true; - - input->seek(4, WPX_SEEK_CUR); - double fontSize = readDouble(input); - - fontMod = readU8(input); - if (fontMod & 1) doubleunderline = true; - if (fontMod & 4) strikeout = true; - if (fontMod & 0x20) doublestrikeout = true; - - if (m_isInStyles) - m_collector->collectCharIXStyle(m_header.id, m_header.level, charCount, font, fontColour, fontSize, - bold, italic, underline, doubleunderline, strikeout, doublestrikeout, - allcaps, initcaps, smallcaps, superscript, subscript); - else - { - if (m_isStencilStarted) - { - VSD_DEBUG_MSG(("Found stencil character style\n")); - } - - m_shape.m_charStyle.override(VSDOptionalCharStyle(charCount, font, fontColour, fontSize, - bold, italic, underline, doubleunderline, strikeout, doublestrikeout, - allcaps, initcaps, smallcaps, superscript, subscript)); - m_shape.m_charList.addCharIX(m_header.id, m_header.level, charCount, font, fontColour, fontSize, - bold, italic, underline, doubleunderline, strikeout, doublestrikeout, - allcaps, initcaps, smallcaps, superscript, subscript); - } -} - -void libvisio::VSD11Parser::readParaIX(WPXInputStream *input) -{ - unsigned charCount = readU32(input); - input->seek(1, WPX_SEEK_CUR); - double indFirst = readDouble(input); - input->seek(1, WPX_SEEK_CUR); - double indLeft = readDouble(input); - input->seek(1, WPX_SEEK_CUR); - double indRight = readDouble(input); - input->seek(1, WPX_SEEK_CUR); - double spLine = readDouble(input); - input->seek(1, WPX_SEEK_CUR); - double spBefore = readDouble(input); - input->seek(1, WPX_SEEK_CUR); - double spAfter = readDouble(input); - unsigned char align = readU8(input); - input->seek(26, WPX_SEEK_CUR); - unsigned flags = readU32(input); - - if (m_isInStyles) - m_collector->collectParaIXStyle(m_header.id, m_header.level, charCount, indFirst, indLeft, indRight, - spLine, spBefore, spAfter, align, flags); - else - { - if (m_isStencilStarted) - { - VSD_DEBUG_MSG(("Found stencil paragraph style\n")); - } - - m_shape.m_paraStyle.override(VSDOptionalParaStyle(charCount, indFirst, indLeft, indRight, - spLine, spBefore, spAfter, align, flags)); - m_shape.m_paraList.addParaIX(m_header.id, m_header.level, charCount, indFirst, indLeft, indRight, - spLine, spBefore, spAfter, align, flags); - } -} - - -void libvisio::VSD11Parser::readFillAndShadow(WPXInputStream *input) -{ - Colour colourFG = _colourFromIndex(readU8(input)); - input->seek(3, WPX_SEEK_CUR); - double fillFGTransparency = (double)readU8(input) / 255.0; - Colour colourBG = _colourFromIndex(readU8(input)); - input->seek(3, WPX_SEEK_CUR); - double fillBGTransparency = (double)readU8(input) / 255.0; - unsigned char fillPattern = readU8(input); - input->seek(1, WPX_SEEK_CUR); - Colour shfgc; // Shadow Foreground Colour - shfgc.r = readU8(input); - shfgc.g = readU8(input); - shfgc.b = readU8(input); - shfgc.a = readU8(input); - input->seek(5, WPX_SEEK_CUR); // Shadow Background Colour skipped - unsigned char shadowPattern = readU8(input); -// only version 11 after that point - input->seek(2, WPX_SEEK_CUR); // Shadow Type and Value format byte - double shadowOffsetX = readDouble(input); - input->seek(1, WPX_SEEK_CUR); // Value format byte - double shadowOffsetY = readDouble(input); - - - - if (m_isInStyles) - m_collector->collectFillStyle(m_header.level, colourFG, colourBG, fillPattern, - fillFGTransparency, fillBGTransparency, shadowPattern, shfgc, - shadowOffsetX, shadowOffsetY); - else - { - if (m_isStencilStarted) - { - VSD_DEBUG_MSG(("Found stencil fill\n")); - } - m_shape.m_fillStyle.override(VSDOptionalFillStyle(colourFG, colourBG, fillPattern, fillFGTransparency, - fillBGTransparency, shfgc, shadowPattern, shadowOffsetX, shadowOffsetY)); - } -} - -void libvisio::VSD11Parser::readName(WPXInputStream *input) -{ - unsigned long numBytesRead = 0; - const unsigned char *tmpBuffer = input->read(m_header.dataLength, numBytesRead); - if (numBytesRead) - { - ::WPXBinaryData name(tmpBuffer, numBytesRead); - m_shape.m_names[m_header.id] = VSDName(name, libvisio::VSD_TEXT_UTF16); - } -} - -void libvisio::VSD11Parser::readTextField(WPXInputStream *input) -{ - unsigned long initialPosition = input->tell(); - input->seek(7, WPX_SEEK_CUR); - unsigned char tmpCode = readU8(input); - if (tmpCode == 0xe8) - { - int nameId = (int)readU32(input); - input->seek(6, WPX_SEEK_CUR); - int formatStringId = (int)readU32(input); - m_shape.m_fields.addTextField(m_header.id, m_header.level, nameId, formatStringId); - } - else - { - double numericValue = readDouble(input); - input->seek(2, WPX_SEEK_CUR); - int formatStringId = (int)readU32(input); - - unsigned blockIdx = 0; - unsigned length = 0; - unsigned short formatNumber = 0; - input->seek(initialPosition+0x36, WPX_SEEK_SET); - while (blockIdx != 2 && !input->atEOS() && (unsigned long) input->tell() < (unsigned long)(initialPosition+m_header.dataLength+m_header.trailer)) - { - unsigned long inputPos = input->tell(); - length = readU32(input); - if (!length) - break; - input->seek(1, WPX_SEEK_CUR); - blockIdx = readU8(input); - if (blockIdx != 2) - input->seek(inputPos + length, WPX_SEEK_SET); - else - { - input->seek(1, WPX_SEEK_CUR); - formatNumber = readU16(input); - if (0x80 != readU8(input)) - { - input->seek(inputPos + length, WPX_SEEK_SET); - blockIdx = 0; - } - else - { - if (0xc2 != readU8(input)) - { - input->seek(inputPos + length, WPX_SEEK_SET); - blockIdx = 0; - } - else - break; - } - } - } - - if (input->atEOS()) - return; - - if (blockIdx != 2) - { - if (tmpCode == 0x28) - formatNumber = 200; - else - formatNumber = 0xffff; - } - - m_shape.m_fields.addNumericField(m_header.id, m_header.level, formatNumber, numericValue, formatStringId); - } -} - - -/* vim:set shiftwidth=2 softtabstop=2 expandtab: */ diff --git a/src/lib/VSD11Parser.h b/src/lib/VSD11Parser.h deleted file mode 100644 index bf9155a..0000000 --- a/src/lib/VSD11Parser.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* libvisio - * Version: MPL 1.1 / GPLv2+ / LGPLv2+ - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License or as specified alternatively below. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * Major Contributor(s): - * Copyright (C) 2011 Fridrich Strba <fridrich.strba@bluewin.ch> - * Copyright (C) 2011 Eilidh McAdam <tibbylickle@gmail.com> - * - * - * All Rights Reserved. - * - * For minor contributions see the git repository. - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPLv2+"), or - * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"), - * in which case the provisions of the GPLv2+ or the LGPLv2+ are applicable - * instead of those above. - */ - -#ifndef __VSD11PARSER_H__ -#define __VSD11PARSER_H__ - -#include <stdio.h> -#include <iostream> -#include <libwpd/libwpd.h> -#include <libwpg/libwpg.h> -#include "VSDParser.h" -#include "VSDInternalStream.h" - -namespace libvisio -{ - -class VSD11Parser : public VSDParser -{ -public: - explicit VSD11Parser(WPXInputStream *input, libwpg::WPGPaintInterface *painter); - ~VSD11Parser(); -private: - virtual bool getChunkHeader(WPXInputStream *input); - void readText(WPXInputStream *input); - void readCharIX(WPXInputStream *input); - void readParaIX(WPXInputStream *input); - void readFillAndShadow(WPXInputStream *input); - void readName(WPXInputStream *input); - void readTextField(WPXInputStream *input); - - VSD11Parser(); - VSD11Parser(const VSDParser &); - VSD11Parser &operator=(const VSDParser &); -}; - -} // namespace libvisio - -#endif // __VSD11PARSER_H__ -/* vim:set shiftwidth=2 softtabstop=2 expandtab: */ diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp index c332e8c..74bc49c 100644 --- a/src/lib/VSDParser.cpp +++ b/src/lib/VSDParser.cpp @@ -53,6 +53,62 @@ libvisio::VSDParser::~VSDParser() { } +bool libvisio::VSDParser::getChunkHeader(WPXInputStream *input) +{ + unsigned char tmpChar = 0; + while (!input->atEOS() && !tmpChar) + tmpChar = readU8(input); + + if (input->atEOS()) + return false; + else + input->seek(-1, WPX_SEEK_CUR); + + m_header.chunkType = readU32(input); + m_header.id = readU32(input); + m_header.list = readU32(input); + + // Certain chunk types seem to always have a trailer + m_header.trailer = 0; + if (m_header.list != 0 || m_header.chunkType == 0x71 || m_header.chunkType == 0x70 || + m_header.chunkType == 0x6b || m_header.chunkType == 0x6a || m_header.chunkType == 0x69 || + m_header.chunkType == 0x66 || m_header.chunkType == 0x65 || m_header.chunkType == 0x2c) + m_header.trailer += 8; // 8 byte trailer + + m_header.dataLength = readU32(input); + m_header.level = readU16(input); + m_header.unknown = readU8(input); + + unsigned trailerChunks [14] = {0x64, 0x65, 0x66, 0x69, 0x6a, 0x6b, 0x6f, 0x71, + 0x92, 0xa9, 0xb4, 0xb6, 0xb9, 0xc7 + }; + // Add word separator under certain circumstances for v11 + // Below are known conditions, may be more or a simpler pattern + if (m_header.list != 0 || (m_header.level == 2 && m_header.unknown == 0x55) || + (m_header.level == 2 && m_header.unknown == 0x54 && m_header.chunkType == 0xaa) + || (m_header.level == 3 && m_header.unknown != 0x50 && m_header.unknown != 0x54)) + { + m_header.trailer += 4; + } + + for (unsigned i = 0; i < 14; i++) + { + if (m_header.chunkType == trailerChunks[i] && m_header.trailer != 12 && m_header.trailer != 4) + { + m_header.trailer += 4; + break; + } + } + + // Some chunks never have a trailer + if (m_header.chunkType == 0x1f || m_header.chunkType == 0xc9 || + m_header.chunkType == 0x2d || m_header.chunkType == 0xd1) + { + m_header.trailer = 0; + } + return true; +} + bool libvisio::VSDParser::parseMain() { if (!m_input) @@ -1467,6 +1523,251 @@ void libvisio::VSDParser::readPageSheet(WPXInputStream * /* input */) m_collector->collectPageSheet(m_header.id, m_header.level); } +void libvisio::VSDParser::readText(WPXInputStream *input) +{ + input->seek(8, WPX_SEEK_CUR); + ::WPXBinaryData textStream; + + // Read up to end of chunk in byte pairs (except from last 2 bytes) + unsigned long numBytesRead = 0; + const unsigned char *tmpBuffer = input->read(m_header.dataLength - 8, numBytesRead); + if (numBytesRead) + { + if (m_isStencilStarted) + { + VSD_DEBUG_MSG(("Found stencil text\n")); + } + textStream.append(tmpBuffer, numBytesRead); + m_shape.m_text = textStream; + m_shape.m_textFormat = libvisio::VSD_TEXT_UTF16; + } + +} + +void libvisio::VSDParser::readCharIX(WPXInputStream *input) +{ + VSDFont fontFace; + unsigned charCount = readU32(input); + unsigned fontID = readU16(input); + VSDName font; + std::map<unsigned, VSDName>::const_iterator iter = m_fonts.find(fontID); + if (iter != m_fonts.end()) + font = iter->second; + input->seek(1, WPX_SEEK_CUR); // Color ID + Colour fontColour; // Font Colour + fontColour.r = readU8(input); + fontColour.g = readU8(input); + fontColour.b = readU8(input); + fontColour.a = readU8(input); + + bool bold(false); + bool italic(false); + bool underline(false); + bool doubleunderline(false); + bool strikeout(false); + bool doublestrikeout(false); + bool allcaps(false); + bool initcaps(false); + bool smallcaps(false); + bool superscript(false); + bool subscript(false); + unsigned char fontMod = readU8(input); + if (fontMod & 1) bold = true; + if (fontMod & 2) italic = true; + if (fontMod & 4) underline = true; + if (fontMod & 8) smallcaps = true; + fontMod = readU8(input); + if (fontMod & 1) allcaps = true; + if (fontMod & 2) initcaps = true; + fontMod = readU8(input); + if (fontMod & 1) superscript = true; + if (fontMod & 2) subscript = true; + + input->seek(4, WPX_SEEK_CUR); + double fontSize = readDouble(input); + + fontMod = readU8(input); + if (fontMod & 1) doubleunderline = true; + if (fontMod & 4) strikeout = true; + if (fontMod & 0x20) doublestrikeout = true; + + if (m_isInStyles) + m_collector->collectCharIXStyle(m_header.id, m_header.level, charCount, font, fontColour, fontSize, + bold, italic, underline, doubleunderline, strikeout, doublestrikeout, + allcaps, initcaps, smallcaps, superscript, subscript); + else + { + if (m_isStencilStarted) + { + VSD_DEBUG_MSG(("Found stencil character style\n")); + } + + m_shape.m_charStyle.override(VSDOptionalCharStyle(charCount, font, fontColour, fontSize, + bold, italic, underline, doubleunderline, strikeout, doublestrikeout, + allcaps, initcaps, smallcaps, superscript, subscript)); + m_shape.m_charList.addCharIX(m_header.id, m_header.level, charCount, font, fontColour, fontSize, + bold, italic, underline, doubleunderline, strikeout, doublestrikeout, + allcaps, initcaps, smallcaps, superscript, subscript); + } +} + +void libvisio::VSDParser::readParaIX(WPXInputStream *input) +{ + unsigned charCount = readU32(input); + input->seek(1, WPX_SEEK_CUR); + double indFirst = readDouble(input); + input->seek(1, WPX_SEEK_CUR); + double indLeft = readDouble(input); + input->seek(1, WPX_SEEK_CUR); + double indRight = readDouble(input); + input->seek(1, WPX_SEEK_CUR); + double spLine = readDouble(input); + input->seek(1, WPX_SEEK_CUR); + double spBefore = readDouble(input); + input->seek(1, WPX_SEEK_CUR); + double spAfter = readDouble(input); + unsigned char align = readU8(input); + input->seek(26, WPX_SEEK_CUR); + unsigned flags = readU32(input); + + if (m_isInStyles) + m_collector->collectParaIXStyle(m_header.id, m_header.level, charCount, indFirst, indLeft, indRight, + spLine, spBefore, spAfter, align, flags); + else + { + if (m_isStencilStarted) + { + VSD_DEBUG_MSG(("Found stencil paragraph style\n")); + } + + m_shape.m_paraStyle.override(VSDOptionalParaStyle(charCount, indFirst, indLeft, indRight, + spLine, spBefore, spAfter, align, flags)); + m_shape.m_paraList.addParaIX(m_header.id, m_header.level, charCount, indFirst, indLeft, indRight, + spLine, spBefore, spAfter, align, flags); + } +} + + +void libvisio::VSDParser::readFillAndShadow(WPXInputStream *input) +{ + Colour colourFG = _colourFromIndex(readU8(input)); + input->seek(3, WPX_SEEK_CUR); + double fillFGTransparency = (double)readU8(input) / 255.0; + Colour colourBG = _colourFromIndex(readU8(input)); + input->seek(3, WPX_SEEK_CUR); + double fillBGTransparency = (double)readU8(input) / 255.0; + unsigned char fillPattern = readU8(input); + input->seek(1, WPX_SEEK_CUR); + Colour shfgc; // Shadow Foreground Colour + shfgc.r = readU8(input); + shfgc.g = readU8(input); + shfgc.b = readU8(input); + shfgc.a = readU8(input); + input->seek(5, WPX_SEEK_CUR); // Shadow Background Colour skipped + unsigned char shadowPattern = readU8(input); +// only version 11 after that point + input->seek(2, WPX_SEEK_CUR); // Shadow Type and Value format byte + double shadowOffsetX = readDouble(input); + input->seek(1, WPX_SEEK_CUR); // Value format byte + double shadowOffsetY = readDouble(input); + + + + if (m_isInStyles) + m_collector->collectFillStyle(m_header.level, colourFG, colourBG, fillPattern, + fillFGTransparency, fillBGTransparency, shadowPattern, shfgc, + shadowOffsetX, shadowOffsetY); + else + { + if (m_isStencilStarted) + { + VSD_DEBUG_MSG(("Found stencil fill\n")); + } + m_shape.m_fillStyle.override(VSDOptionalFillStyle(colourFG, colourBG, fillPattern, fillFGTransparency, + fillBGTransparency, shfgc, shadowPattern, shadowOffsetX, shadowOffsetY)); + } +} + +void libvisio::VSDParser::readName(WPXInputStream *input) +{ + unsigned long numBytesRead = 0; + const unsigned char *tmpBuffer = input->read(m_header.dataLength, numBytesRead); + if (numBytesRead) + { + ::WPXBinaryData name(tmpBuffer, numBytesRead); + m_shape.m_names[m_header.id] = VSDName(name, libvisio::VSD_TEXT_UTF16); + } +} + +void libvisio::VSDParser::readTextField(WPXInputStream *input) +{ + unsigned long initialPosition = input->tell(); + input->seek(7, WPX_SEEK_CUR); + unsigned char tmpCode = readU8(input); + if (tmpCode == 0xe8) + { + int nameId = (int)readU32(input); + input->seek(6, WPX_SEEK_CUR); + int formatStringId = (int)readU32(input); + m_shape.m_fields.addTextField(m_header.id, m_header.level, nameId, formatStringId); + } + else + { + double numericValue = readDouble(input); + input->seek(2, WPX_SEEK_CUR); + int formatStringId = (int)readU32(input); + + unsigned blockIdx = 0; + unsigned length = 0; + unsigned short formatNumber = 0; + input->seek(initialPosition+0x36, WPX_SEEK_SET); + while (blockIdx != 2 && !input->atEOS() && (unsigned long) input->tell() < (unsigned long)(initialPosition+m_header.dataLength+m_header.trailer)) + { + unsigned long inputPos = input->tell(); + length = readU32(input); + if (!length) + break; + input->seek(1, WPX_SEEK_CUR); + blockIdx = readU8(input); + if (blockIdx != 2) + input->seek(inputPos + length, WPX_SEEK_SET); + else + { + input->seek(1, WPX_SEEK_CUR); + formatNumber = readU16(input); + if (0x80 != readU8(input)) + { + input->seek(inputPos + length, WPX_SEEK_SET); + blockIdx = 0; + } + else + { + if (0xc2 != readU8(input)) + { + input->seek(inputPos + length, WPX_SEEK_SET); + blockIdx = 0; + } + else + break; + } + } + } + + if (input->atEOS()) + return; + + if (blockIdx != 2) + { + if (tmpCode == 0x28) + formatNumber = 200; + else + formatNumber = 0xffff; + } + + m_shape.m_fields.addNumericField(m_header.id, m_header.level, formatNumber, numericValue, formatStringId); + } +} + libvisio::Colour libvisio::VSDParser::_colourFromIndex(unsigned idx) { if (idx < m_colours.size()) diff --git a/src/lib/VSDParser.h b/src/lib/VSDParser.h index 8357a60..a0478e2 100644 --- a/src/lib/VSDParser.h +++ b/src/lib/VSDParser.h @@ -78,7 +78,7 @@ protected: void readForeignData(WPXInputStream *input); void readEllipse(WPXInputStream *input); virtual void readLine(WPXInputStream *input); - virtual void readFillAndShadow(WPXInputStream *input) = 0; + virtual void readFillAndShadow(WPXInputStream *input); virtual void readGeomList(WPXInputStream *input); void readGeometry(WPXInputStream *input); void readMoveTo(WPXInputStream *input); @@ -102,16 +102,16 @@ protected: virtual void readParaList(WPXInputStream *input); virtual void readPropList(WPXInputStream *input); virtual void readPage(WPXInputStream *input); - virtual void readText(WPXInputStream *input) = 0; - virtual void readCharIX(WPXInputStream *input) = 0; - virtual void readParaIX(WPXInputStream *input) = 0; + virtual void readText(WPXInputStream *input); + virtual void readCharIX(WPXInputStream *input); + virtual void readParaIX(WPXInputStream *input); virtual void readTextBlock(WPXInputStream *input); void readNameList(WPXInputStream *input); - virtual void readName(WPXInputStream *input) = 0; + virtual void readName(WPXInputStream *input); void readFieldList(WPXInputStream *input); - virtual void readTextField(WPXInputStream *input) = 0; + virtual void readTextField(WPXInputStream *input); virtual void readStyleSheet(WPXInputStream *input); void readPageSheet(WPXInputStream *input); @@ -136,7 +136,7 @@ protected: virtual void readPointer(WPXInputStream *input, Pointer &ptr); virtual void readPointerInfo(WPXInputStream *input, unsigned ptrType, unsigned shift, unsigned &listSize, int &pointerCount); - virtual bool getChunkHeader(WPXInputStream *input) = 0; + virtual bool getChunkHeader(WPXInputStream *input); void _handleLevelChange(unsigned level); Colour _colourFromIndex(unsigned idx); void _flushShape(); diff --git a/src/lib/VisioDocument.cpp b/src/lib/VisioDocument.cpp index 38076b6..caaa2f9 100644 --- a/src/lib/VisioDocument.cpp +++ b/src/lib/VisioDocument.cpp @@ -39,7 +39,6 @@ #include "VSD2Parser.h" #include "VSD5Parser.h" #include "VSD6Parser.h" -#include "VSD11Parser.h" #include "VSDXMLHelper.h" #include "VSDZipStream.h" @@ -308,7 +307,7 @@ bool libvisio::VisioDocument::parse(::WPXInputStream *input, libwpg::WPGPaintInt parser = new VSD6Parser(docStream, painter); break; case 11: - parser = new VSD11Parser(docStream, painter); + parser = new VSDParser(docStream, painter); break; default: break; @@ -389,7 +388,7 @@ bool libvisio::VisioDocument::parseStencils(::WPXInputStream *input, libwpg::WPG parser = new VSD6Parser(docStream, painter); break; case 11: - parser = new VSD11Parser(docStream, painter); + parser = new VSDParser(docStream, painter); break; default: break; diff --git a/src/lib/makefile.mk b/src/lib/makefile.mk index 30ba870..861042f 100644 --- a/src/lib/makefile.mk +++ b/src/lib/makefile.mk @@ -42,7 +42,8 @@ SLOFILES= \ $(SLO)$/libvisio_utils.obj \ $(SLO)$/VDXParser.obj \ $(SLO)$/VisioDocument.obj \ - $(SLO)$/VSD11Parser.obj \ + $(SLO)$/VSD2Parser.obj \ + $(SLO)$/VSD5Parser.obj \ $(SLO)$/VSD6Parser.obj \ $(SLO)$/VSDCharacterList.obj \ $(SLO)$/VSDContentCollector.obj \ |