[libmwaw] 01/01: New upstream version 0.3.10
Rene Engelhard
rene at moszumanska.debian.org
Tue Jan 31 20:23:33 UTC 2017
This is an automated email from the git hooks/post-receive script.
rene pushed a commit to branch upstream
in repository libmwaw.
commit d1c23e57de361ede309d847a06f8f028fd0d6d20
Author: Rene Engelhard <rene at rene-engelhard.de>
Date: Tue Jan 31 21:14:59 2017 +0100
New upstream version 0.3.10
---
CHANGES | 5 +
build/win32/libmwaw.dsp | 8 +
build/win32/libmwaw.vcproj | 8 +
build/win32/libmwaw.vcxproj | 5 +
configure | 26 +-
configure.ac | 2 +-
inc/libmwaw/MWAWDocument.hxx | 2 +-
libmwaw.spec | 4 +-
src/lib/MWAWFontConverter.cxx | 2 +
src/lib/MWAWHeader.cxx | 2 +
src/lib/MWAWOLEParser.cxx | 479 +++++++++++++++++-----
src/lib/MWAWOLEParser.hxx | 58 +--
src/lib/MWAWSpreadsheetListener.cxx | 6 +-
src/lib/Makefile.am | 2 +
src/lib/Makefile.in | 22 +-
src/lib/MsWksDBParser.cxx | 2 +-
src/lib/MsWksDocument.cxx | 2 +-
src/lib/MsWksSSParser.cxx | 2 +-
src/lib/PowerPoint1Parser.cxx | 767 +++++++++++++++++++++++++++++-------
src/lib/PowerPoint1Parser.hxx | 6 +
src/lib/PowerPoint3OLE.cxx | 228 +++++++++++
src/lib/PowerPoint3OLE.hxx | 91 +++++
src/lib/PowerPoint3Parser.cxx | 275 +++++++++----
src/lib/PowerPoint3Parser.hxx | 6 +-
src/lib/README | 5 +-
src/lib/ZWrtParser.cxx | 2 +-
26 files changed, 1634 insertions(+), 383 deletions(-)
diff --git a/CHANGES b/CHANGES
index 40ebd74..c00d818 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,10 @@
CHANGES:
+1/23/2017:
+- add some parsers to read Mac PowerPoint v4 files and Windows PowerPoint v2,v4 files
+
+-------- version 0.3.10 (start) -------------
+
11/16/2016
- add some parsers to read Mac PowerPoint v1-v3 files and Windows PowerPoint v3 files
diff --git a/build/win32/libmwaw.dsp b/build/win32/libmwaw.dsp
index 76555fc..957923d 100644
--- a/build/win32/libmwaw.dsp
+++ b/build/win32/libmwaw.dsp
@@ -619,6 +619,10 @@ SOURCE=..\..\src\lib\PowerPoint1Parser.cxx
# End Source File
# Begin Source File
+SOURCE=..\..\src\lib\PowerPoint3OLE.cxx
+# End Source File
+# Begin Source File
+
SOURCE=..\..\src\lib\PowerPoint3Parser.cxx
# End Source File
# Begin Source File
@@ -1259,6 +1263,10 @@ SOURCE=..\..\src\lib\PowerPoint1Parser.hxx
# End Source File
# Begin Source File
+SOURCE=..\..\src\lib\PowerPoint3OLE.hxx
+# End Source File
+# Begin Source File
+
SOURCE=..\..\src\lib\PowerPoint3Parser.hxx
# End Source File
# Begin Source File
diff --git a/build/win32/libmwaw.vcproj b/build/win32/libmwaw.vcproj
index 9c461dd..d9edb76 100644
--- a/build/win32/libmwaw.vcproj
+++ b/build/win32/libmwaw.vcproj
@@ -704,6 +704,10 @@
>
</File>
<File
+ RelativePath="..\..\src\lib\PowerPoint3OLE.cxx"
+ >
+ </File>
+ <File
RelativePath="..\..\src\lib\PowerPoint3Parser.cxx"
>
</File>
@@ -1345,6 +1349,10 @@
>
</File>
<File
+ RelativePath="..\..\src\lib\PowerPoint3OLE.hxx"
+ >
+ </File>
+ <File
RelativePath="..\..\src\lib\PowerPoint3Parser.hxx"
>
</File>
diff --git a/build/win32/libmwaw.vcxproj b/build/win32/libmwaw.vcxproj
index f924662..f0057f5 100644
--- a/build/win32/libmwaw.vcxproj
+++ b/build/win32/libmwaw.vcxproj
@@ -630,6 +630,10 @@
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
+ <ClCompile Include="..\..\src\lib\PowerPoint3OLE.cxx">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
<ClCompile Include="..\..\src\lib\PowerPoint3Parser.cxx">
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -869,6 +873,7 @@
<ClInclude Include="..\..\src\lib\NisusWrtText.hxx" />
<ClInclude Include="..\..\src\lib\PixelPaintParser.hxx" />
<ClInclude Include="..\..\src\lib\PowerPoint1Parser.hxx" />
+ <ClInclude Include="..\..\src\lib\PowerPoint3OLE.hxx" />
<ClInclude Include="..\..\src\lib\PowerPoint3Parser.hxx" />
<ClInclude Include="..\..\src\lib\RagTimeParser.hxx" />
<ClInclude Include="..\..\src\lib\RagTimeSpreadsheet.hxx" />
diff --git a/configure b/configure
index 208f7e3..6f35e2e 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libmwaw 0.3.9.
+# Generated by GNU Autoconf 2.69 for libmwaw 0.3.10.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='libmwaw'
PACKAGE_TARNAME='libmwaw'
-PACKAGE_VERSION='0.3.9'
-PACKAGE_STRING='libmwaw 0.3.9'
+PACKAGE_VERSION='0.3.10'
+PACKAGE_STRING='libmwaw 0.3.10'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1388,7 +1388,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures libmwaw 0.3.9 to adapt to many kinds of systems.
+\`configure' configures libmwaw 0.3.10 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1458,7 +1458,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libmwaw 0.3.9:";;
+ short | recursive ) echo "Configuration of libmwaw 0.3.10:";;
esac
cat <<\_ACEOF
@@ -1604,7 +1604,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-libmwaw configure 0.3.9
+libmwaw configure 0.3.10
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2193,7 +2193,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by libmwaw $as_me 0.3.9, which was
+It was created by libmwaw $as_me 0.3.10, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3059,7 +3059,7 @@ fi
# Define the identity of the package.
PACKAGE='libmwaw'
- VERSION='0.3.9'
+ VERSION='0.3.10'
cat >>confdefs.h <<_ACEOF
@@ -17653,9 +17653,9 @@ MWAW_MAJOR_VERSION=0
MWAW_MINOR_VERSION=3
-MWAW_MICRO_VERSION=9
+MWAW_MICRO_VERSION=10
-MWAW_VERSION=0.3.9
+MWAW_VERSION=0.3.10
# AC_SUBST(LT_RELEASE, [libmwaw_version_major.libmwaw_version_minor])
LT_CURRENT=`expr 100 '*' 0 + 3`
@@ -17663,7 +17663,7 @@ LT_CURRENT=`expr 100 '*' 0 + 3`
LT_AGE=0
# LT_AGE=libmwaw_version_minor
-LT_REVISION=9
+LT_REVISION=10
@@ -19554,7 +19554,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by libmwaw $as_me 0.3.9, which was
+This file was extended by libmwaw $as_me 0.3.10, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -19620,7 +19620,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-libmwaw config.status 0.3.9
+libmwaw config.status 0.3.10
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index e55a8ff..ee23c24 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,7 +7,7 @@ AC_PREREQ([2.60])
# ====================
m4_define([libmwaw_version_major],[0])
m4_define([libmwaw_version_minor],[3])
-m4_define([libmwaw_version_micro],[9])
+m4_define([libmwaw_version_micro],[10])
m4_define([libmwaw_version],[libmwaw_version_major.libmwaw_version_minor.libmwaw_version_micro])
# =============
diff --git a/inc/libmwaw/MWAWDocument.hxx b/inc/libmwaw/MWAWDocument.hxx
index b6b7bd9..7b311a8 100644
--- a/inc/libmwaw/MWAWDocument.hxx
+++ b/inc/libmwaw/MWAWDocument.hxx
@@ -190,7 +190,7 @@ public:
/** MouseWrite: v1
\note same enum as \a MWAW_T_RESERVED7*/
MWAW_T_MOUSEWRITE=MWAW_T_RESERVED7,
- /** PowerPoint: v1-v3 and pc v3
+ /** PowerPoint: v1-v4 and pc v2-v4
\note same enum as \a MWAW_T_RESERVED8*/
MWAW_T_POWERPOINT=MWAW_T_RESERVED8
diff --git a/libmwaw.spec b/libmwaw.spec
index 6a47989..100239a 100644
--- a/libmwaw.spec
+++ b/libmwaw.spec
@@ -1,5 +1,5 @@
%define name libmwaw
-%define version 0.3.9
+%define version 0.3.10
%define RELEASE 1
%define release %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE}
@@ -90,7 +90,7 @@ umask 022
%if %{!?_without_docs:1}%{?_without_docs:0}
%files docs
-%{_datadir}/doc/libmwaw-0.3.9/*
+%{_datadir}/doc/libmwaw-0.3.10/*
%endif
%changelog
diff --git a/src/lib/MWAWFontConverter.cxx b/src/lib/MWAWFontConverter.cxx
index 94ac0f7..613feaf 100644
--- a/src/lib/MWAWFontConverter.cxx
+++ b/src/lib/MWAWFontConverter.cxx
@@ -617,6 +617,8 @@ void KnownConversion::initMaps()
m_cursiveMap[c] = m_mathMap[c] = m_scientificMap[c] = unicode;
m_unknown107Map[c] = m_unknown128Map[c] = m_unknown200Map[c] = unicode;
}
+ for (unsigned long c=0x20; c<=0xff; ++c)
+ m_windowsCP1252Map[static_cast<unsigned char>(c)]= c;
initAMap(s_centralEuroUnicode, sizeof(s_centralEuroUnicode)/(2*sizeof(int)), m_centralEuroMap);
initAMap(s_cyrillicUnicode, sizeof(s_cyrillicUnicode)/(2*sizeof(int)), m_cyrillicMap);
initAMap(s_turkishUnicode, sizeof(s_turkishUnicode)/(2*sizeof(int)), m_turkishMap);
diff --git a/src/lib/MWAWHeader.cxx b/src/lib/MWAWHeader.cxx
index 0b79013..8c419f3 100644
--- a/src/lib/MWAWHeader.cxx
+++ b/src/lib/MWAWHeader.cxx
@@ -770,6 +770,8 @@ std::vector<MWAWHeader> MWAWHeader::constructHeader
break;
}
}
+ if (!mainOle && input->getSubStreamByName("PP40"))
+ res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, 4, MWAWDocument::MWAW_K_PRESENTATION));
}
if ((val[0]==0xfe32 && val[1]==0) || (val[0]==0xfe34 && val[1]==0) ||
diff --git a/src/lib/MWAWOLEParser.cxx b/src/lib/MWAWOLEParser.cxx
index e83cfe1..e9b3141 100644
--- a/src/lib/MWAWOLEParser.cxx
+++ b/src/lib/MWAWOLEParser.cxx
@@ -31,49 +31,6 @@
* instead of those above.
*/
-/*
- * freely inspired from istorage :
- * ------------------------------------------------------------
- * Generic OLE Zones furnished with a copy of the file header
- *
- * Compound Storage (32 bit version)
- * Storage implementation
- *
- * This file contains the compound file implementation
- * of the storage interface.
- *
- * Copyright 1999 Francis Beaudet
- * Copyright 1999 Sylvain St-Germain
- * Copyright 1999 Thuy Nguyen
- * Copyright 2005 Mike McCormack
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * NOTES
- * The compound file implementation of IStorage used for create
- * and manage substorages and streams within a storage object
- * residing in a compound file object.
- *
- * MSDN
- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/stg/stg/istorage_compound_file_implementation.asp
- * ------------------------------------------------------------
- */
-
#include <cstdlib>
#include <cstring>
#include <iostream>
@@ -83,6 +40,7 @@
#include <librevenge/librevenge.h>
+#include "MWAWFontConverter.hxx"
#include "MWAWPosition.hxx"
#include "MWAWOLEParser.hxx"
#include "MWAWPictMac.hxx"
@@ -228,16 +186,45 @@ protected:
/** Internal: internal method to keep ole definition */
struct OleDef {
- OleDef() : m_id(-1), m_subId(-1), m_dir(""), m_name("") { }
+ OleDef() : m_id(-1), m_subId(-1), m_dir(""), m_base(""), m_name("") { }
int m_id /**main id*/, m_subId /**subsversion id */ ;
- std::string m_dir/**the directory*/, m_name/**the base name*/;
+ std::string m_dir/**the directory*/, m_base/**the base*/, m_name/**the complete name*/;
+};
+
+/** Internal: internal state of a MWAWOLEParser */
+struct State {
+ /** constructor */
+ State(MWAWFontConverterPtr fontConverter, int fId)
+ : m_fontConverter(fontConverter), m_fontId(fId), m_metaData(), m_unknownOLEs(),
+ m_objects(), m_objectsPosition(), m_objectsId(), m_objectsType(), m_compObjIdName()
+ {
+ }
+ //! the font converter
+ MWAWFontConverterPtr m_fontConverter;
+ //! the font id used to decode string
+ int m_fontId;
+ //! the meta data
+ librevenge::RVNGPropertyList m_metaData;
+ //! list of ole which can not be parsed
+ std::vector<std::string> m_unknownOLEs;
+
+ //! list of pictures read
+ std::vector<librevenge::RVNGBinaryData> m_objects;
+ //! list of picture size ( if known)
+ std::vector<MWAWPosition> m_objectsPosition;
+ //! list of pictures id
+ std::vector<int> m_objectsId;
+ //! list of picture type
+ std::vector<std::string> m_objectsType;
+
+ //! a smart ptr used to stored the list of compobj id->name
+ shared_ptr<MWAWOLEParserInternal::CompObj> m_compObjIdName;
};
}
// constructor/destructor
-MWAWOLEParser::MWAWOLEParser(std::string mainName)
- : m_avoidOLE(mainName), m_unknownOLEs(),
- m_objects(), m_objectsPosition(), m_objectsId(), m_objectsType(), m_compObjIdName()
+MWAWOLEParser::MWAWOLEParser(std::string mainName, MWAWFontConverterPtr fontConverter, int fId)
+ : m_avoidOLE(mainName), m_state(new MWAWOLEParserInternal::State(fontConverter, fId))
{
}
@@ -245,13 +232,47 @@ MWAWOLEParser::~MWAWOLEParser()
{
}
+void MWAWOLEParser::updateMetaData(librevenge::RVNGPropertyList &metaData) const
+{
+ librevenge::RVNGPropertyList::Iter i(m_state->m_metaData);
+ for (i.rewind(); i.next();) {
+ if (!metaData[i.key()])
+ metaData.insert(i.key(),i()->clone());
+ }
+}
+
+std::vector<std::string> const &MWAWOLEParser::getNotParse() const
+{
+ return m_state->m_unknownOLEs;
+}
+
+std::vector<int> const &MWAWOLEParser::getObjectsId() const
+{
+ return m_state->m_objectsId;
+}
+
+std::vector<MWAWPosition> const &MWAWOLEParser::getObjectsPosition() const
+{
+ return m_state->m_objectsPosition;
+}
+
+std::vector<librevenge::RVNGBinaryData> const &MWAWOLEParser::getObjects() const
+{
+ return m_state->m_objects;
+}
+
+std::vector<std::string> const &MWAWOLEParser::getObjectsType() const
+{
+ return m_state->m_objectsType;
+}
+
bool MWAWOLEParser::getObject(int id, librevenge::RVNGBinaryData &obj, MWAWPosition &pos, std::string &type) const
{
- for (size_t i = 0; i < m_objectsId.size(); i++) {
- if (m_objectsId[i] != id) continue;
- obj = m_objects[i];
- pos = m_objectsPosition[i];
- type = m_objectsType[i];
+ for (size_t i = 0; i < m_state->m_objectsId.size(); i++) {
+ if (m_state->m_objectsId[i] != id) continue;
+ obj = m_state->m_objects[i];
+ pos = m_state->m_objectsPosition[i];
+ type = m_state->m_objectsType[i];
return true;
}
obj.clear();
@@ -261,29 +282,29 @@ bool MWAWOLEParser::getObject(int id, librevenge::RVNGBinaryData &obj, MWAWPosit
void MWAWOLEParser::setObject(int id, librevenge::RVNGBinaryData const &obj, MWAWPosition const &pos,
std::string const &type)
{
- for (size_t i = 0; i < m_objectsId.size(); i++) {
- if (m_objectsId[i] != id) continue;
- m_objects[i] = obj;
- m_objectsPosition[i] = pos;
- m_objectsType[i] = type;
+ for (size_t i = 0; i < m_state->m_objectsId.size(); i++) {
+ if (m_state->m_objectsId[i] != id) continue;
+ m_state->m_objects[i] = obj;
+ m_state->m_objectsPosition[i] = pos;
+ m_state->m_objectsType[i] = type;
return;
}
- m_objects.push_back(obj);
- m_objectsPosition.push_back(pos);
- m_objectsId.push_back(id);
- m_objectsType.push_back(type);
+ m_state->m_objects.push_back(obj);
+ m_state->m_objectsPosition.push_back(pos);
+ m_state->m_objectsId.push_back(id);
+ m_state->m_objectsType.push_back(type);
}
// parsing
bool MWAWOLEParser::parse(MWAWInputStreamPtr file)
{
- if (!m_compObjIdName)
- m_compObjIdName.reset(new MWAWOLEParserInternal::CompObj);
+ if (!m_state->m_compObjIdName)
+ m_state->m_compObjIdName.reset(new MWAWOLEParserInternal::CompObj);
- m_unknownOLEs.resize(0);
- m_objects.resize(0);
- m_objectsId.resize(0);
- m_objectsType.resize(0);
+ m_state->m_unknownOLEs.resize(0);
+ m_state->m_objects.resize(0);
+ m_state->m_objectsId.resize(0);
+ m_state->m_objectsType.resize(0);
if (!file.get()) return false;
@@ -319,7 +340,8 @@ bool MWAWOLEParser::parse(MWAWInputStreamPtr file)
#endif
MWAWOLEParserInternal::OleDef data;
data.m_name = name;
- data.m_dir = base;
+ data.m_dir = dir;
+ data.m_base = base;
// try to retrieve the identificator stored in the directory
// MatOST/MatadorObject1/ -> 1, -1
@@ -379,32 +401,34 @@ bool MWAWOLEParser::parse(MWAWInputStreamPtr file)
bool ok = true;
MWAWPosition pictPos;
- if (strncmp("Ole", dOle.m_dir.c_str(), 3) == 0 ||
- strncmp("CompObj", dOle.m_dir.c_str(), 7) == 0)
+ if (strncmp("Ole", dOle.m_base.c_str(), 3) == 0 ||
+ strncmp("CompObj", dOle.m_base.c_str(), 7) == 0)
ole->setReadInverted(true);
try {
- if (readMM(ole, dOle.m_dir, asciiFile));
- else if (readObjInfo(ole, dOle.m_dir, asciiFile));
- else if (readOle(ole, dOle.m_dir, asciiFile));
- else if (isOlePres(ole, dOle.m_dir) &&
+ librevenge::RVNGPropertyList pList;
+ if (readMM(ole, dOle.m_base, asciiFile));
+ else if (readSummaryInformation(ole, dOle.m_base, dOle.m_dir.empty() ? m_state->m_metaData : pList, asciiFile));
+ else if (readObjInfo(ole, dOle.m_base, asciiFile));
+ else if (readOle(ole, dOle.m_base, asciiFile));
+ else if (isOlePres(ole, dOle.m_base) &&
readOlePres(ole, data, pictPos, asciiFile)) {
hasData = true;
newConfidence = 2;
}
- else if (isOle10Native(ole, dOle.m_dir) &&
+ else if (isOle10Native(ole, dOle.m_base) &&
readOle10Native(ole, data, asciiFile)) {
hasData = true;
// small size can be a symptom that this is a link to a
// basic msworks data file, so we reduce confidence
newConfidence = data.size() > 1000 ? 4 : 2;
}
- else if (readCompObj(ole, dOle.m_dir, asciiFile));
- else if (readContents(ole, dOle.m_dir, data, pictPos, asciiFile)) {
+ else if (readCompObj(ole, dOle.m_base, asciiFile));
+ else if (readContents(ole, dOle.m_base, data, pictPos, asciiFile)) {
hasData = true;
newConfidence = 3;
}
- else if (readCONTENTS(ole, dOle.m_dir, data, pictPos, asciiFile)) {
+ else if (readCONTENTS(ole, dOle.m_base, data, pictPos, asciiFile)) {
hasData = true;
newConfidence = 3;
}
@@ -415,7 +439,7 @@ bool MWAWOLEParser::parse(MWAWInputStreamPtr file)
ok = false;
}
if (!ok) {
- m_unknownOLEs.push_back(dOle.m_name);
+ m_state->m_unknownOLEs.push_back(dOle.m_name);
asciiFile.reset();
continue;
}
@@ -460,18 +484,18 @@ bool MWAWOLEParser::parse(MWAWInputStreamPtr file)
}
if (pict.size()) {
- m_objects.push_back(pict);
+ m_state->m_objects.push_back(pict);
if (actualPos.naturalSize().x() <= 0 || actualPos.naturalSize().y() <= 0) {
MWAWVec2f size = potentialSize.naturalSize();
if (size.x() > 0 && size.y() > 0)
actualPos.setNaturalSize(actualPos.getInvUnitScale(potentialSize.unit())*size);
}
- m_objectsPosition.push_back(actualPos);
- m_objectsId.push_back(id);
+ m_state->m_objectsPosition.push_back(actualPos);
+ m_state->m_objectsId.push_back(id);
if (isPict)
- m_objectsType.push_back("image/pict");
+ m_state->m_objectsType.push_back("image/pict");
else
- m_objectsType.push_back("object/ole");
+ m_state->m_objectsType.push_back("object/ole");
}
}
@@ -626,7 +650,7 @@ bool MWAWOLEParser::readCompObj(MWAWInputStreamPtr ip, std::string const &oleNam
f << "@@CompObj(CLSID):";
if (clsData[1] == 0 && clsData[2] == 0xC0 && clsData[3] == 0x46000000L) {
// normally, a referenced object
- char const *clsName = m_compObjIdName->getCLSName(clsData[0]);
+ char const *clsName = m_state->m_compObjIdName->getCLSName(clsData[0]);
if (clsName)
f << "'" << clsName << "'";
else {
@@ -691,8 +715,13 @@ bool MWAWOLEParser::readCompObj(MWAWInputStreamPtr ip, std::string const &oleNam
long nbElt = 4;
if (ip->seek(actPos+16,librevenge::RVNG_SEEK_SET) != 0 ||
ip->tell() != actPos+16) {
- if ((ip->tell()-actPos)%4)
- return false;
+ if ((ip->tell()-actPos)%4) {
+ f.str("");
+ f << "@@CompObj(Footer):###";
+ ascii.addPos(actPos);
+ ascii.addNote(f.str().c_str());
+ return true;
+ }
nbElt = (ip->tell()-actPos)/4;
}
@@ -710,6 +739,280 @@ bool MWAWOLEParser::readCompObj(MWAWInputStreamPtr ip, std::string const &oleNam
}
//////////////////////////////////////////////////
+// summary and doc summary
+//////////////////////////////////////////////////
+bool MWAWOLEParser::readSummaryInformation(MWAWInputStreamPtr input, std::string const &oleName, librevenge::RVNGPropertyList &pList,
+ libmwaw::DebugFile &ascii) const
+{
+ if (oleName!="SummaryInformation" && oleName!="DocumentSummaryInformation") return false;
+ input->seek(0, librevenge::RVNG_SEEK_SET);
+ libmwaw::DebugStream f;
+ f << "Entries(SumInfo):";
+ bool isDoc=oleName=="DocumentSummaryInformation";
+ if (isDoc) f << "doc,";
+ int val=int(input->readULong(2));
+ if (val==0xfeff) {
+ input->setReadInverted(false);
+ val=0xfffe;
+ }
+ if (input->size()<48 || val!=0xfffe) {
+ MWAW_DEBUG_MSG(("MWAWOLEParser::readSummaryInformation: header seems bad\n"));
+ f << "###";
+ ascii.addPos(0);
+ ascii.addNote(f.str().c_str());
+ return true;
+ }
+ for (int i=0; i<11; ++i) { // f1=1, f2=0-2
+ val=int(input->readULong(2));
+ if (val) f << "f" << i << "=" << val << ",";
+ }
+ val=int(input->readULong(4));
+ if (val==0x1000000) {
+ val=1;
+ input->setReadInverted(!input->readInverted());
+ }
+ if (val!=1) {
+ MWAW_DEBUG_MSG(("MWAWOLEParser::readSummaryInformation: summary info is bad\n"));
+ f << "###sumInfo=" << val << ",";
+ ascii.addPos(0);
+ ascii.addNote(f.str().c_str());
+ return true;
+ }
+ for (int i=0; i<4; ++i) {
+ val=int(input->readULong(4));
+ static int const expected[]= {int(0xf29f85e0),0x10684ff9,0x891ab,int(0xd9b3272b)};
+ static int const docExpected[]= {int(0xd5cdd502),0x101b2e9c,0x89793,int(0xaef92c2b)};
+ if ((!isDoc && val==expected[i]) || (isDoc && val==docExpected[i])) continue;
+ f << "#fmid" << i << "=" << std::hex << val << std::dec << ",";
+ static bool first=true;
+ if (first) {
+ MWAW_DEBUG_MSG(("MWAWOLEParser::readSummaryInformation: fmid is bad\n"));
+ first=false;
+ }
+ }
+ int decal=int(input->readULong(4));
+ if (decal<0x30 || input->size()<decal) {
+ MWAW_DEBUG_MSG(("MWAWOLEParser::readSummaryInformation: decal is bad\n"));
+ f << "decal=" << val << ",";
+ ascii.addPos(0);
+ ascii.addNote(f.str().c_str());
+ return true;
+
+ }
+ ascii.addPos(0);
+ ascii.addNote(f.str().c_str());
+ if (decal!=0x30) {
+ ascii.addPos(0x30);
+ ascii.addNote("_");
+ input->seek(decal, librevenge::RVNG_SEEK_SET);
+ }
+
+ long pos=input->tell();
+ f.str("");
+ f << "SumInfo-A:";
+ long pSetSize=long(input->readULong(4));
+ int N=int(input->readULong(4));
+ f << "N=" << N << ",";
+ if (pSetSize<0 || input->size()-pos<pSetSize || (pSetSize-8)/8<N) {
+ MWAW_DEBUG_MSG(("MWAWOLEParser::readSummaryInformation: psetstruct is bad\n"));
+ f << "###";
+ ascii.addPos(pos);
+ ascii.addNote(f.str().c_str());
+ return true;
+ }
+ f << "[";
+ std::map<long,int> posToTypeMap;
+ for (int i=0; i<N; ++i) {
+ int type=int(input->readULong(4));
+ int depl=int(input->readULong(4));
+ if (depl==0) continue;
+ f << std::hex << depl << std::dec << ":" << type << ",";
+ if (depl<8+8*N || depl+4>pSetSize || posToTypeMap.find(pos+depl)!=posToTypeMap.end()) {
+ f << "###";
+ continue;
+ }
+ posToTypeMap[pos+depl]=type;
+ }
+ f << "],";
+ ascii.addPos(pos);
+ ascii.addNote(f.str().c_str());
+
+ for (std::map<long,int>::const_iterator it=posToTypeMap.begin(); it!=posToTypeMap.end(); ++it) {
+ pos=it->first;
+ long endPos=input->size();
+ std::map<long,int>::const_iterator nextIt=it;
+ if (++nextIt!=posToTypeMap.end()) endPos=nextIt->first;
+ input->seek(pos, librevenge::RVNG_SEEK_SET);
+ f.str("");
+ f << "SumInfo-B" << it->second << ":";
+ int type=int(input->readULong(4));
+ if (type==0x1e && !isDoc && ((it->second>=2 && it->second<=6) || it->second==8)) {
+ librevenge::RVNGString text;
+ if (readSummaryPropertyString(input, endPos, type, text, f) && !text.empty()) {
+ static char const *(attribNames[]) = {
+ "", "", "dc:title", "dc:subject", "meta:initial-creator",
+ "meta:keywords", "dc:description"/*comment*/, "", "dc:creator"
+ };
+ pList.insert(attribNames[it->second], text);
+ }
+ }
+ else if (!readSummaryProperty(input, endPos, type, ascii, f)) {
+ MWAW_DEBUG_MSG(("MWAWOLEParser::readSummaryInformation: find unknown type\n"));
+ f << "##type=" << std::hex << type << std::dec << ",";
+ }
+ if (input->tell()!=endPos && input->tell()!=pos)
+ ascii.addDelimiter(input->tell(),'|');
+ ascii.addPos(pos);
+ ascii.addNote(f.str().c_str());
+ }
+ return true;
+}
+
+bool MWAWOLEParser::readSummaryPropertyString(MWAWInputStreamPtr input, long endPos, int type,
+ librevenge::RVNGString &string, libmwaw::DebugStream &f) const
+{
+ if (!input) return false;
+ long pos=input->tell();
+ string.clear();
+ long sSz=long(input->readULong(4));
+ if (sSz<0 || (endPos-pos-4)<sSz || pos+4+sSz>endPos) {
+ MWAW_DEBUG_MSG(("MWAWOLEParser::readSummaryPropertyString: string size is bad\n"));
+ f << "##stringSz=" << sSz << ",";
+ return false;
+ }
+ std::string text("");
+ for (long c=0; c < sSz; ++c) {
+ char ch=char(input->readULong(1));
+ if (ch) {
+ text+=ch;
+ if (m_state->m_fontConverter) {
+ int unicode=m_state->m_fontConverter->unicode(m_state->m_fontId, static_cast<unsigned char>(ch));
+ if (unicode!=-1)
+ libmwaw::appendUnicode(uint32_t(unicode), string);
+ }
+ }
+ else if (c+1!=sSz)
+ text+="##";
+ }
+ f << text;
+ if (type==0x1f && (sSz%4))
+ input->seek(sSz%4, librevenge::RVNG_SEEK_CUR);
+ return true;
+}
+
+bool MWAWOLEParser::readSummaryProperty(MWAWInputStreamPtr input, long endPos, int type,
+ libmwaw::DebugFile &ascii, libmwaw::DebugStream &f) const
+{
+ if (!input) return false;
+ long pos=input->tell();
+ // see propread.cxx
+ if (type&0x1000) {
+ int N=int(input->readULong(4));
+ f << "N=" << N << ",";
+ f << "[";
+ for (int n=0; n<N; ++n) {
+ pos=input->tell();
+ f << "[";
+ if (!readSummaryProperty(input, endPos, type&0xFFF, ascii, f)) {
+ input->seek(pos, librevenge::RVNG_SEEK_SET);
+ return false;
+ }
+ f << "],";
+ }
+ f << "],";
+ return true;
+ }
+ switch (type) {
+ case 0x10: // int1
+ case 0x11: // uint1
+ if (pos+1>endPos)
+ return false;
+ f << "val=" << char(input->readULong(1));
+ break;
+ case 2: // int
+ case 0xb: // bool
+ case 0x12: // uint
+ if (pos+2>endPos)
+ return false;
+ if (type==2)
+ f << "val=" << int(input->readLong(2)) << ",";
+ else if (type==0x12)
+ f << "val=" << int(input->readULong(2)) << ",";
+ else if (input->readULong(2))
+ f << "true,";
+ break;
+ case 3: // int
+ case 4: // float
+ case 9: // uint
+ if (pos+4>endPos)
+ return false;
+ if (type==3)
+ f << "val=" << int(input->readLong(4)) << ",";
+ else if (type==9)
+ f << "val=" << int(input->readULong(4)) << ",";
+ else
+ f << "val[fl4]=" << std::hex << input->readULong(4) << std::dec << ",";
+ break;
+ case 5: // double
+ case 6:
+ case 7:
+ case 20:
+ case 21:
+ case 0x40:
+ if (pos+8>endPos)
+ return false;
+ ascii.addDelimiter(input->tell(),'|');
+ if (type==5)
+ f << "double,";
+ else if (type==6)
+ f << "cy,";
+ else if (type==7)
+ f << "date,";
+ else if (type==20)
+ f << "long,";
+ else if (type==21)
+ f << "ulong,";
+ else
+ f << "fileTime,"; // readme 8 byte
+ input->seek(pos+8, librevenge::RVNG_SEEK_SET);
+ break;
+ case 0xc: // variant
+ if (pos+4>endPos)
+ return false;
+ type=int(input->readULong(4));
+ return readSummaryProperty(input, endPos, type, ascii, f);
+ // case 20: int64
+ // case 21: uint64
+ case 8:
+ case 0x1e:
+ case 0x1f: {
+ librevenge::RVNGString string;
+ if (!readSummaryPropertyString(input, endPos, type, string, f))
+ return false;
+ break;
+ }
+ case 0x41:
+ case 0x46:
+ case 0x47: {
+ if (pos+4>endPos)
+ return false;
+ f << (type==0x41 ? "blob" : type==0x46 ? "blob[object]" : "clipboard") << ",";
+ long dSz=long(input->readULong(4));
+ if (dSz<0 || pos+4+dSz>endPos)
+ return false;
+ if (dSz) {
+ ascii.skipZone(pos+4, pos+4+dSz-1);
+ input->seek(dSz, librevenge::RVNG_SEEK_CUR);
+ }
+ break;
+ }
+ /* todo type==0x47, vtcf clipboard */
+ default:
+ return false;
+ }
+ return true;
+}
+//////////////////////////////////////////////////
//
// OlePres001 seems to contained standart picture file and size
// extract the picture if it is possible
diff --git a/src/lib/MWAWOLEParser.hxx b/src/lib/MWAWOLEParser.hxx
index 4518a81..5579979 100644
--- a/src/lib/MWAWOLEParser.hxx
+++ b/src/lib/MWAWOLEParser.hxx
@@ -76,6 +76,7 @@
namespace MWAWOLEParserInternal
{
class CompObj;
+struct State;
}
/** \brief a class used to parse some basic oles
@@ -86,7 +87,7 @@ class MWAWOLEParser
public:
/** constructor
\param mainName name of the main ole, we must avoid to parse */
- explicit MWAWOLEParser(std::string mainName);
+ explicit MWAWOLEParser(std::string mainName, MWAWFontConverterPtr fontConverter, int fontId);
/** destructor */
~MWAWOLEParser();
@@ -94,33 +95,18 @@ public:
/** tries to parse basic OLE (excepted mainName)
\return false if fileInput is not an Ole file */
bool parse(MWAWInputStreamPtr fileInput);
-
+ /** update the meta data, using information find in SummaryInformation */
+ void updateMetaData(librevenge::RVNGPropertyList &metaData) const;
//! returns the list of unknown ole
- std::vector<std::string> const &getNotParse() const
- {
- return m_unknownOLEs;
- }
-
+ std::vector<std::string> const &getNotParse() const;
//! returns the list of id for which we have find a representation
- std::vector<int> const &getObjectsId() const
- {
- return m_objectsId;
- }
+ std::vector<int> const &getObjectsId() const;
//! returns the list of data positions which have been read
- std::vector<MWAWPosition> const &getObjectsPosition() const
- {
- return m_objectsPosition;
- }
+ std::vector<MWAWPosition> const &getObjectsPosition() const;
//! returns the list of data which have been read
- std::vector<librevenge::RVNGBinaryData> const &getObjects() const
- {
- return m_objects;
- }
+ std::vector<librevenge::RVNGBinaryData> const &getObjects() const;
//! returns the list of data type
- std::vector<std::string> const &getObjectsType() const
- {
- return m_objectsType;
- }
+ std::vector<std::string> const &getObjectsType() const;
//! returns the picture corresponding to an id
bool getObject(int id, librevenge::RVNGBinaryData &obj, MWAWPosition &pos, std::string &type) const;
@@ -132,6 +118,15 @@ public:
std::string const &type);
protected:
+ //! the summary information and the doc summary information
+ bool readSummaryInformation(MWAWInputStreamPtr input, std::string const &oleName, librevenge::RVNGPropertyList &pList,
+ libmwaw::DebugFile &ascii) const;
+ //! try to read a summary property
+ bool readSummaryProperty(MWAWInputStreamPtr input, long endPos, int type,
+ libmwaw::DebugFile &ascii, libmwaw::DebugStream &f) const;
+ //! try to read a summary property: type 1e
+ bool readSummaryPropertyString(MWAWInputStreamPtr input, long endPos, int type, librevenge::RVNGString &string,
+ libmwaw::DebugStream &f) const;
//! the "Ole" small structure : unknown contain
static bool readOle(MWAWInputStreamPtr ip, std::string const &oleName,
@@ -175,21 +170,8 @@ protected:
//! if filled, does not parse content with this name
std::string m_avoidOLE;
- //! list of ole which can not be parsed
- std::vector<std::string> m_unknownOLEs;
-
- //! list of pictures read
- std::vector<librevenge::RVNGBinaryData> m_objects;
- //! list of picture size ( if known)
- std::vector<MWAWPosition> m_objectsPosition;
- //! list of pictures id
- std::vector<int> m_objectsId;
- //! list of picture type
- std::vector<std::string> m_objectsType;
-
- //! a smart ptr used to stored the list of compobj id->name
- shared_ptr<MWAWOLEParserInternal::CompObj> m_compObjIdName;
-
+ //! the main state
+ shared_ptr<MWAWOLEParserInternal::State> m_state;
};
#endif
diff --git a/src/lib/MWAWSpreadsheetListener.cxx b/src/lib/MWAWSpreadsheetListener.cxx
index 4b1a010..c8c7592 100644
--- a/src/lib/MWAWSpreadsheetListener.cxx
+++ b/src/lib/MWAWSpreadsheetListener.cxx
@@ -1137,7 +1137,11 @@ void MWAWSpreadsheetListener::insertPicture(MWAWPosition const &pos, MWAWEmbedde
///////////////////
bool MWAWSpreadsheetListener::openGroup(MWAWPosition const &/*pos*/)
{
- MWAW_DEBUG_MSG(("MWAWSpreadsheetListener::openGroup is not implemented\n"));
+ static bool first=true;
+ if (first) {
+ MWAW_DEBUG_MSG(("MWAWSpreadsheetListener::openGroup is not implemented\n"));
+ first=false;
+ }
return false;
}
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 145a28f..2b8fe13 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -281,6 +281,8 @@ libmwaw_ at MWAW_MAJOR_VERSION@_ at MWAW_MINOR_VERSION@_la_SOURCES = \
PixelPaintParser.hxx \
PowerPoint1Parser.cxx \
PowerPoint1Parser.hxx \
+ PowerPoint3OLE.cxx \
+ PowerPoint3OLE.hxx \
PowerPoint3Parser.cxx \
PowerPoint3Parser.hxx \
RagTimeParser.cxx \
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
index d011ce0..10be9a1 100644
--- a/src/lib/Makefile.in
+++ b/src/lib/Makefile.in
@@ -180,15 +180,16 @@ am_libmwaw_ at MWAW_MAJOR_VERSION@_ at MWAW_MINOR_VERSION@_la_OBJECTS = \
MWAWStringStream.lo MWAWSubDocument.lo MWAWTable.lo \
MWAWTextListener.lo NisusWrtGraph.lo NisusWrtParser.lo \
NisusWrtStruct.lo NisusWrtText.lo PixelPaintParser.lo \
- PowerPoint1Parser.lo PowerPoint3Parser.lo RagTimeParser.lo \
- RagTimeSpreadsheet.lo RagTimeStruct.lo RagTimeText.lo \
- RagTime5Chart.lo RagTime5ClusterManager.lo RagTime5Graph.lo \
- RagTime5Layout.lo RagTime5Parser.lo RagTime5Pipeline.lo \
- RagTime5Spreadsheet.lo RagTime5StructManager.lo \
- RagTime5StyleManager.lo RagTime5Text.lo StyleParser.lo \
- SuperPaintParser.lo TeachTxtParser.lo WingzParser.lo \
- WriteNowEntry.lo WriteNowParser.lo WriteNowText.lo \
- WriterPlsParser.lo ZWrtParser.lo ZWrtText.lo
+ PowerPoint1Parser.lo PowerPoint3OLE.lo PowerPoint3Parser.lo \
+ RagTimeParser.lo RagTimeSpreadsheet.lo RagTimeStruct.lo \
+ RagTimeText.lo RagTime5Chart.lo RagTime5ClusterManager.lo \
+ RagTime5Graph.lo RagTime5Layout.lo RagTime5Parser.lo \
+ RagTime5Pipeline.lo RagTime5Spreadsheet.lo \
+ RagTime5StructManager.lo RagTime5StyleManager.lo \
+ RagTime5Text.lo StyleParser.lo SuperPaintParser.lo \
+ TeachTxtParser.lo WingzParser.lo WriteNowEntry.lo \
+ WriteNowParser.lo WriteNowText.lo WriterPlsParser.lo \
+ ZWrtParser.lo ZWrtText.lo
libmwaw_ at MWAW_MAJOR_VERSION@_ at MWAW_MINOR_VERSION@_la_OBJECTS = $(am_libmwaw_ at MWAW_MAJOR_VERSION@_ at MWAW_MINOR_VERSION@_la_OBJECTS)
AM_V_lt = $(am__v_lt_ at AM_V@)
am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
@@ -692,6 +693,8 @@ libmwaw_ at MWAW_MAJOR_VERSION@_ at MWAW_MINOR_VERSION@_la_SOURCES = \
PixelPaintParser.hxx \
PowerPoint1Parser.cxx \
PowerPoint1Parser.hxx \
+ PowerPoint3OLE.cxx \
+ PowerPoint3OLE.hxx \
PowerPoint3Parser.cxx \
PowerPoint3Parser.hxx \
RagTimeParser.cxx \
@@ -963,6 +966,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/NisusWrtText.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/PixelPaintParser.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/PowerPoint1Parser.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/PowerPoint3OLE.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/PowerPoint3Parser.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/RagTime5Chart.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/RagTime5ClusterManager.Plo at am__quote@
diff --git a/src/lib/MsWksDBParser.cxx b/src/lib/MsWksDBParser.cxx
index c8966a2..efc57e8 100644
--- a/src/lib/MsWksDBParser.cxx
+++ b/src/lib/MsWksDBParser.cxx
@@ -530,7 +530,7 @@ void MsWksDBParser::parse(librevenge::RVNGSpreadsheetInterface *docInterface)
#ifdef DEBUG
MWAWInputStreamPtr &input= getInput();
if (input->isStructured()) {
- shared_ptr<MWAWOLEParser> oleParser(new MWAWOLEParser("MN0"));
+ shared_ptr<MWAWOLEParser> oleParser(new MWAWOLEParser("MN0", getParserState()->m_fontConverter, 3));
oleParser->parse(input);
}
#endif
diff --git a/src/lib/MsWksDocument.cxx b/src/lib/MsWksDocument.cxx
index fa0e110..7c65579 100644
--- a/src/lib/MsWksDocument.cxx
+++ b/src/lib/MsWksDocument.cxx
@@ -592,7 +592,7 @@ std::vector<std::string> const &MsWksDocument::getUnparsedOLEZones() const
bool MsWksDocument::createOLEZones(MWAWInputStreamPtr input)
{
if (!input || !input->isStructured()) return false;
- m_state->m_oleParser.reset(new MWAWOLEParser("MN0"));
+ m_state->m_oleParser.reset(new MWAWOLEParser("MN0", m_parserState->m_fontConverter, 3));
if (!m_state->m_oleParser->parse(input)) return false;
diff --git a/src/lib/MsWksSSParser.cxx b/src/lib/MsWksSSParser.cxx
index 09f44be..cde8b8b 100644
--- a/src/lib/MsWksSSParser.cxx
+++ b/src/lib/MsWksSSParser.cxx
@@ -253,7 +253,7 @@ void MsWksSSParser::parse(librevenge::RVNGSpreadsheetInterface *docInterface)
#ifdef DEBUG
MWAWInputStreamPtr &input= getInput();
if (input->isStructured()) {
- shared_ptr<MWAWOLEParser> oleParser(new MWAWOLEParser("MN0"));
+ shared_ptr<MWAWOLEParser> oleParser(new MWAWOLEParser("MN0", getParserState()->m_fontConverter, 3));
oleParser->parse(input);
}
#endif
diff --git a/src/lib/PowerPoint1Parser.cxx b/src/lib/PowerPoint1Parser.cxx
index 82f9d06..2f735dc 100644
--- a/src/lib/PowerPoint1Parser.cxx
+++ b/src/lib/PowerPoint1Parser.cxx
@@ -31,6 +31,7 @@
* instead of those above.
*/
+#include <algorithm>
#include <iomanip>
#include <iostream>
#include <set>
@@ -78,14 +79,14 @@ struct Ruler {
o << (i==0 ? "first[margin]" : "left[margin]") << "=" << outline.m_margins[i] << ",";
}
for (int i=0; i<2; ++i) {
- if (outline.m_interlines[i]==10) continue;
- o << (i==0 ? "space[interline]" : "space[paragraph]") << "=" << 10*outline.m_interlines[i] << "%,";
+ if (outline.m_interlines[i]==100) continue;
+ o << (i==0 ? "space[interline]" : "space[paragraph]") << "=" << outline.m_interlines[i] << "%,";
}
return o;
}
//! the first margin and left margin
int m_margins[2];
- //! the interline and paragraph spacing: 10 means 100%
+ //! the interline and paragraph spacing
int m_interlines[2];
};
//! the tabs
@@ -107,13 +108,15 @@ struct TextZone {
//! small structure used to store a line of text and its format
struct Line {
//! constructor
- Line() : m_text(), m_format(), m_justify(MWAWParagraph::JustificationLeft), m_outlineLevel(0)
+ Line() : m_text(), m_format(), m_ruler(), m_justify(MWAWParagraph::JustificationLeft), m_outlineLevel(0)
{
}
//! the text entry
MWAWEntry m_text;
//! the format entry
MWAWEntry m_format;
+ //! the ruler entry (windows v2)
+ MWAWEntry m_ruler;
//! the justification
MWAWParagraph::Justification m_justify;
//! the outline level
@@ -173,7 +176,7 @@ struct Slide {
//! Internal: the state of a PowerPoint1Parser
struct State {
//! constructor
- State() : m_isMacFile(true), m_zoneListBegin(0), m_zonesList(), m_origin(0,0), m_rulersList(), m_idToSlideMap(), m_idToSchemeMap(), m_idToUserColorMap(), m_picturesIdList(), m_schemesIdList(),
+ State() : m_isMacFile(true), m_unit(1), m_zoneListBegin(0), m_zonesList(), m_origin(0,0), m_rulersList(), m_idToSlideMap(), m_idToSchemeMap(), m_idToUserColorMap(), m_picturesIdList(), m_schemesIdList(),
m_badEntry()
{
for (int i=0; i<2; ++i)
@@ -195,6 +198,8 @@ struct State {
bool getPattern(int id, MWAWGraphicStyle::Pattern &pattern) const;
//! flag to know if the file is a mac file or a pc file
bool m_isMacFile;
+ //! the data unit: 1 if the file is a mac file, 1/8 if the file is a windows file
+ float m_unit;
//! the begin position of the list of zones
long m_zoneListBegin;
//! the list of zone entries
@@ -458,8 +463,9 @@ bool PowerPoint1Parser::createZones()
return false;
}
int const vers=version();
- int numStyles=vers<=1 ? 4 : m_state->m_isMacFile ? 5 : 0;
- if (m_state->m_isMacFile) {
+ bool const isMacFile=m_state->m_isMacFile;
+ int numStyles=vers<=1 ? 4 : m_state->m_isMacFile ? 6 : 8;
+ if (isMacFile) {
for (int i=0; i<numStyles; ++i) {
MWAWEntry const &entry=m_state->getZoneEntry(m_state->m_zoneIds[i]);
if (!entry.valid() || entry.isParsed()) continue;
@@ -471,19 +477,26 @@ bool PowerPoint1Parser::createZones()
readFonts(entry);
else if (i==4)
readColorZone(entry);
+ else if (i==5)
+ readZone2(entry);
}
}
else {
- numStyles=3;
- for (int i=0; i<3; ++i) {
- // 0:
- // 1: list of zone list?
- // 2: schemes list?
+ for (int i=0; i<numStyles; ++i) {
MWAWEntry const &entry=m_state->getZoneEntry(m_state->m_zoneIds[i]);
if (!entry.valid() || entry.isParsed()) continue;
- readZoneIdList2(entry, i);
+ if (i<3) // list of 0: picture, 1: rulers, 2: scheme
+ readZoneIdList2(entry, i);
+ else if (i==3)
+ readColorZone(entry);
+ else if (i==4)
+ readZone2(entry);
+ // 5: never seens
+ else if (i==6)
+ readFonts(entry);
+ else if (i==7)
+ readFontNames(entry);
}
- // vers=3: i==3[4] readColorMode, i==4[5] readZone2, i==6[2] readFonts
}
readSchemes();
for (int i=0; i<2; ++i) {
@@ -491,32 +504,38 @@ bool PowerPoint1Parser::createZones()
if (!entry.valid() || entry.isParsed()) continue;
readSlide(entry, m_state->m_slidesIdList[i]);
}
- if (m_state->m_printInfoIds[1]>=0) {
- MWAWEntry const &entry=m_state->getZoneEntry(m_state->m_printInfoIds[1]);
- if (entry.valid() && !entry.isParsed())
- readPrintInfo(entry);
- }
- for (int i=numStyles; i<10; ++i) {
- MWAWEntry const &entry=m_state->getZoneEntry(m_state->m_zoneIds[i]);
+ for (int i=0; i<2; ++i) {
+ MWAWEntry const &entry=m_state->getZoneEntry(m_state->m_printInfoIds[i]);
if (!entry.valid() || entry.isParsed()) continue;
- if (i==5)
- readZone2(entry);
- else { // never seens
- static bool first=true;
- if (first) {
- first=false;
- MWAW_DEBUG_MSG(("PowerPoint1Parser::createZones: find unknown Zone5\n"));
- }
+ if (m_state->m_isMacFile && i==1)
+ readPrintInfo(entry);
+ else {
entry.setParsed(true);
libmwaw::DebugStream f;
- f << "Entries(Zone" << i << ")[Z" << entry.id() << "]:";
+ f << "Entries(PrintInfo" << i << ")[Z" << entry.id() << "]:";
ascii().addPos(entry.begin());
ascii().addNote(f.str().c_str());
ascii().addPos(entry.end());
ascii().addNote("_");
}
}
- return m_state->m_isMacFile && !m_state->m_slidesIdList[0].empty();
+ for (int i=0; i<10; ++i) {
+ MWAWEntry const &entry=m_state->getZoneEntry(m_state->m_zoneIds[i]);
+ if (!entry.valid() || entry.isParsed()) continue;
+ static bool first=true;
+ if (first) {
+ first=false;
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::createZones: find unknown Zone%d\n", i));
+ }
+ entry.setParsed(true);
+ libmwaw::DebugStream f;
+ f << "Entries(Zone" << i << ")[Z" << entry.id() << "]:";
+ ascii().addPos(entry.begin());
+ ascii().addNote(f.str().c_str());
+ ascii().addPos(entry.end());
+ ascii().addNote("_");
+ }
+ return !m_state->m_slidesIdList[0].empty();
}
bool PowerPoint1Parser::readListZones(int &docInfoId)
@@ -676,11 +695,13 @@ bool PowerPoint1Parser::readFramesList(MWAWEntry const &entry, std::vector<Power
{
MWAWInputStreamPtr input=getInput();
int const vers=version();
- int const dataSz=m_state->m_isMacFile ? 28 : 32;
+ int const isMacFile=m_state->m_isMacFile;
+ int dataSz=isMacFile ? 28 : 32;
if (!entry.valid() || (entry.length()%dataSz)!=0) {
MWAW_DEBUG_MSG(("PowerPoint1Parser::readFramesList: the entry seems bad\n"));
return false;
}
+ if (!isMacFile) dataSz=30;
entry.setParsed(true);
input->seek(entry.begin(), librevenge::RVNG_SEEK_SET);
long pos=input->tell();
@@ -699,6 +720,10 @@ bool PowerPoint1Parser::readFramesList(MWAWEntry const &entry, std::vector<Power
f << "Frames[F" << fr << "]:";
int dim[4];
for (int i=0; i<4; ++i) dim[i]=int(input->readLong(2));
+ if (!isMacFile) {
+ std::swap(dim[0],dim[1]);
+ std::swap(dim[2],dim[3]);
+ }
frame.m_dimension=MWAWBox2i(MWAWVec2i(dim[1],dim[0]),MWAWVec2i(dim[3],dim[2]));
f << "dim=" << frame.m_dimension << ",";
frame.m_type=int(input->readULong(1));
@@ -710,7 +735,12 @@ bool PowerPoint1Parser::readFramesList(MWAWEntry const &entry, std::vector<Power
f << "rect,";
break;
case 2:
- f << "textbox,";
+ if (isMacFile)
+ f << "textbox,";
+ else {
+ frame.m_textId=MWAWVec2i(tId,tId);
+ f << "textbox=T" << tId++ << ",";
+ }
break;
case 3:
frame.m_textId=MWAWVec2i(tId,tId);
@@ -740,16 +770,36 @@ bool PowerPoint1Parser::readFramesList(MWAWEntry const &entry, std::vector<Power
}
}
else {
- val=int(input->readULong(1));
- for (int i=0, bit=1; i<5; ++i, bit<<=1) {
- flags[i]=(val&bit);
- if (!flags[i]) continue;
- char const *(wh[])= {"opaque", "frame", "filled", "shadowed", "sized to text"};
- f << wh[i] << ",";
+ if (isMacFile) {
+ val=int(input->readULong(1));
+ for (int i=0, bit=1; i<5; ++i, bit<<=1) {
+ flags[i]=(val&bit);
+ if (!flags[i]) continue;
+ char const *(wh[])= {"opaque", "frame", "filled", "shadowed", "sized to text"};
+ f << wh[i] << ",";
+ }
+ if (val&0xE0) {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readFramesList: find unexpected flags\n"));
+ f << "##fl=" << (val>>5) << ",";
+ }
}
- if (val&0xE0) {
- MWAW_DEBUG_MSG(("PowerPoint1Parser::readFramesList: find unexpected flags\n"));
- f << "##fl=" << (val>>5) << ",";
+ else {
+ val=int(input->readULong(1));
+ if (val) f << "fl0=" << val << ",";
+ val=int(input->readULong(1));
+ for (int i=0, bit=1; i<5; ++i, bit<<=1) {
+ int const(corresp[])= {2,1,3,0,4};
+ flags[corresp[i]]=(val&bit);
+ if (!flags[corresp[i]]) continue;
+ char const *(wh[])= {"filled", "frame", "shadowed", "opaque", "sized to text"};
+ f << wh[i] << ",";
+ }
+ if (val&0xE0) {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readFramesList: find unexpected flags\n"));
+ f << "##fl=" << (val>>5) << ",";
+ }
+ val=int(input->readULong(1));
+ if (val) f << "fl2=" << val << ",";
}
for (int i=0; i<4; ++i) { // frame, fill, shadow, pat2
int col=int(input->readULong(1));
@@ -757,6 +807,7 @@ bool PowerPoint1Parser::readFramesList(MWAWEntry const &entry, std::vector<Power
if (schemeId>=0 && !getColor(col, schemeId, colors[i])) f << "##col,";
if (col!=expected[i]) f << "col" << i << "=" << col << ",";
}
+ if (!isMacFile) std::swap<MWAWColor>(colors[1],colors[3]);
}
MWAWGraphicStyle &style=frame.m_style;
val=int(input->readULong(1));
@@ -817,7 +868,7 @@ bool PowerPoint1Parser::readFramesList(MWAWEntry const &entry, std::vector<Power
pattern.m_colors[1]=colors[3];
if (val!=1)
f << "pat=" << pattern << ",";
- if (flags[2]) { // textbox have no background color
+ if (flags[2]) { // filled
MWAWColor color;
if (pattern.getUniqueColor(color))
style.setSurfaceColor(color);
@@ -838,7 +889,7 @@ bool PowerPoint1Parser::readFramesList(MWAWEntry const &entry, std::vector<Power
f << "##pattern=" << val << ",";
if (flags[0]) style.setSurfaceColor(colors[1]);
}
- if (flags[3]==1) {
+ if (flags[3]) {
style.setShadowColor(colors[2]);
style.m_shadowOffset=MWAWVec2f(3,3);
}
@@ -877,7 +928,7 @@ bool PowerPoint1Parser::readFramesList(MWAWEntry const &entry, std::vector<Power
f << "para=R" << val << ",";
}
val=int(input->readULong(2));
- if (frame.m_type==2) {
+ if (frame.m_type==2 && isMacFile) {
frame.m_textId=MWAWVec2i(tId,tId+val-1);
tId+=val;
f << "text=T" << frame.m_textId[0] << "<->T" << frame.m_textId[1] << ",";
@@ -895,6 +946,10 @@ bool PowerPoint1Parser::readFramesList(MWAWEntry const &entry, std::vector<Power
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
}
+ if (input->tell()!=entry.end()) {
+ ascii().addPos(input->tell());
+ ascii().addNote("Frames:extra");
+ }
ascii().addPos(entry.end());
ascii().addNote("_");
return true;
@@ -903,7 +958,8 @@ bool PowerPoint1Parser::readFramesList(MWAWEntry const &entry, std::vector<Power
bool PowerPoint1Parser::readTextZone(MWAWEntry const &entry, PowerPoint1ParserInternal::TextZone &zone)
{
MWAWInputStreamPtr input=getInput();
- if (!entry.valid() || entry.length()<6) {
+ bool isMacFile=m_state->m_isMacFile;
+ if (!entry.valid() || entry.length()<(isMacFile ? 6 : 32)) {
MWAW_DEBUG_MSG(("PowerPoint1Parser::readTextZone: the entry seems bad\n"));
return false;
}
@@ -911,6 +967,7 @@ bool PowerPoint1Parser::readTextZone(MWAWEntry const &entry, PowerPoint1ParserIn
long pos=input->tell();
libmwaw::DebugStream f;
f << "Entries(TextZone)[Z" << entry.id() << "]:";
+ int val;
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
long const endPos=entry.end();
@@ -918,71 +975,136 @@ bool PowerPoint1Parser::readTextZone(MWAWEntry const &entry, PowerPoint1ParserIn
while (input->tell()+6<=endPos) {
PowerPoint1ParserInternal::TextZone::Line line;
pos=input->tell();
+ if (!isMacFile && pos+32>endPos)
+ break;
f.str("");
f << "TextZone-T" << ++n << ":";
- int val=int(input->readLong(1));
- switch (val) {
- case 0: // left
- break;
- case 1:
- line.m_justify=MWAWParagraph::JustificationCenter;
- f << "center,";
- break;
- case 2:
- line.m_justify=MWAWParagraph::JustificationRight;
- f << "right,";
- break;
- case 3:
- line.m_justify=MWAWParagraph::JustificationFull;
- f << "justify,";
+ if (isMacFile) {
+ val=int(input->readLong(1));
+ switch (val) {
+ case 0: // left
+ break;
+ case 1:
+ line.m_justify=MWAWParagraph::JustificationCenter;
+ f << "center,";
+ break;
+ case 2:
+ line.m_justify=MWAWParagraph::JustificationRight;
+ f << "right,";
+ break;
+ case 3:
+ line.m_justify=MWAWParagraph::JustificationFull;
+ f << "justify,";
+ break;
+ default:
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readTextZone: find unknown justification\n"));
+ f << "##justify=" << val << ",";
+ }
+ line.m_outlineLevel=int(input->readLong(1));
+ if (line.m_outlineLevel) f << "outline[levl]=" << line.m_outlineLevel << ",";
+ }
+ else if (entry.length()>32+16) {
+ for (int i=0; i<16; ++i) { // f0=1|8|c|10,f1=d|12,f2=1|3f,f3=0|c,f5=sz|big number,f6=0-3,f7=0-1a,f9=0|1,f13=0-2,f14=0|5
+ val=int(input->readLong(2));
+ if (val)
+ f << "f" << i << "=" << val << ",";
+ }
+ for (int i=0; i<4; ++i) {
+ val=int(input->readULong(2));
+ if (val) f << "g" << i << "=" << val << ",";
+ }
+ }
+ else {
+ input->seek(pos+32, librevenge::RVNG_SEEK_SET);
+ ascii().addPos(pos);
+ ascii().addNote(f.str().c_str());
+ zone.m_lineList.push_back(line);
break;
- default:
- MWAW_DEBUG_MSG(("PowerPoint1Parser::readTextZone: find unknown justifcation\n"));
- f << "##justify=" << val << ",";
}
- line.m_outlineLevel=int(input->readLong(1));
- if (line.m_outlineLevel) f << "outline[levl]=" << line.m_outlineLevel << ",";
int sSz=int(input->readULong(2));
- if (pos+4+sSz+(sSz&1)+2>endPos) {
+ if (input->tell()+sSz+(isMacFile ? (sSz&1)+2:16)>endPos) {
input->seek(pos, librevenge::RVNG_SEEK_SET);
n--;
break;
}
- line.m_text.setBegin(pos+4);
+ line.m_text.setBegin(input->tell());
line.m_text.setLength(sSz);
std::string text;
for (int i=0; i<sSz; ++i) text+=char(input->readULong(1));
f << text << ",";
- if (sSz&1) input->seek(1, librevenge::RVNG_SEEK_CUR);
+ if (isMacFile && (sSz&1)) input->seek(1, librevenge::RVNG_SEEK_CUR);
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
pos=input->tell();
f.str("");
f << "TextZone-F" << n << ":";
- sSz=int(input->readULong(2));
- if ((sSz!=0 && sSz<6) || pos+2+sSz>endPos) {
- input->seek(pos, librevenge::RVNG_SEEK_SET);
- n--;
- break;
+ if (isMacFile) {
+ sSz=int(input->readULong(2));
+ if ((sSz!=0 && sSz<6) || pos+2+sSz>endPos) {
+ input->seek(pos, librevenge::RVNG_SEEK_SET);
+ n--;
+ break;
+ }
+ line.m_format.setBegin(pos+2);
+ line.m_format.setLength(sSz);
+ input->seek(sSz, librevenge::RVNG_SEEK_CUR);
+ ascii().addPos(pos);
+ ascii().addNote(f.str().c_str());
}
+ else {
+ for (int i=0; i<3; ++i) {
+ val=int(input->readULong(2));
+ if (val) f << "f" << i << "=" << val << ",";
+ }
+ int nFonts=int(input->readULong(2));
+ if (pos+nFonts*14+8>endPos) {
+ input->seek(pos, librevenge::RVNG_SEEK_SET);
+ n--;
+ break;
+ }
+ ascii().addPos(pos);
+ ascii().addNote(f.str().c_str());
+ line.m_format.setBegin(pos+8);
+ line.m_format.setLength(nFonts*14);
+ input->seek(nFonts*14, librevenge::RVNG_SEEK_CUR);
- line.m_format.setBegin(pos+2);
- line.m_format.setLength(sSz);
- ascii().addPos(pos);
- ascii().addNote(f.str().c_str());
- input->seek(sSz, librevenge::RVNG_SEEK_CUR);
+ pos=input->tell();
+ f.str("");
+ f << "TextZone-R" << n << ":";
+ for (int i=0; i<3; ++i) {
+ val=int(input->readULong(2));
+ if (val) f << "f" << i << "=" << val << ",";
+ }
+ int nRulers=int(input->readULong(2));
+ if (pos+nRulers*6>endPos) {
+ input->seek(pos, librevenge::RVNG_SEEK_SET);
+ n--;
+ break;
+ }
+ line.m_ruler.setBegin(pos+8);
+ line.m_ruler.setLength(nRulers*6);
+ ascii().addPos(pos);
+ ascii().addNote(f.str().c_str());
+ input->seek(nRulers*6, librevenge::RVNG_SEEK_CUR);
+ }
zone.m_lineList.push_back(line);
}
- if (n==0) return false;
+ if (n==0 && isMacFile) return false;
entry.setParsed(true);
ascii().addPos(endPos);
ascii().addNote("_");
pos=input->tell();
if (pos!=endPos) {
- MWAW_DEBUG_MSG(("PowerPoint1Parser::readTextZone: find extra data\n"));
- ascii().addPos(pos);
- ascii().addNote("TextZone-###extra");
+ if (!isMacFile && pos<endPos && endPos<pos+32) {
+ ascii().addPos(pos);
+ ascii().addNote("TextZone-extra");
+ }
+ else {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readTextZone: find extra data\n"));
+ ascii().addPos(pos);
+ ascii().addNote("TextZone-###extra");
+ }
}
return true;
}
@@ -1071,6 +1193,12 @@ bool PowerPoint1Parser::readSlide(MWAWEntry const &entry, std::vector<int> &list
f << "#use[master]=" << val << ",";
val=int(input->readLong(1)); // always 0
if (val) f << "f6=" << val << ",";
+ if (!isMacFile) {
+ // maybe junk
+ val=int(input->readULong(2));
+ if (val)
+ f << "f7=" << std::hex << val << std::dec << ",";
+ }
val=int(input->readULong(2));
if (val>=0 && val<int(m_state->m_schemesIdList.size())) {
slide->m_schemeId=val;
@@ -1078,10 +1206,12 @@ bool PowerPoint1Parser::readSlide(MWAWEntry const &entry, std::vector<int> &list
}
else if (val)
f << "#scheme=" << val << ",";
- // maybe junk
- val=int(input->readULong(2));
- if (val)
- f << "f7=" << std::hex << val << std::dec << ",";
+ if (isMacFile) {
+ // maybe junk
+ val=int(input->readULong(2));
+ if (val)
+ f << "f7=" << std::hex << val << std::dec << ",";
+ }
val=int(input->readULong(2)); // 0 or big number
if (val) f << "g0=" << std::hex << val << std::dec << ",";
val=int(input->readLong(2));
@@ -1208,9 +1338,17 @@ bool PowerPoint1Parser::readDocInfo(MWAWEntry const &entry)
if (val) f << "id" << i+4 << "=" << std::hex << val << std::dec << ",";
}
for (int i=0; i<4; ++i) dim[i]=int(input->readLong(2));
+ if (!isMacFile) {
+ std::swap(dim[0],dim[1]);
+ std::swap(dim[2],dim[3]);
+ }
MWAWBox2i pageBox(MWAWVec2i(dim[1],dim[0]),MWAWVec2i(dim[3],dim[2]));
f << "dim[page]=" << pageBox << ",";
for (int i=0; i<4; ++i) dim[i]=int(input->readLong(2));
+ if (!isMacFile) {
+ std::swap(dim[0],dim[1]);
+ std::swap(dim[2],dim[3]);
+ }
MWAWBox2i paperBox(MWAWVec2i(dim[1],dim[0]),MWAWVec2i(dim[3],dim[2]));
paperBox=MWAWBox2i(MWAWVec2i(dim[0],dim[1]),MWAWVec2i(dim[2],dim[3]));
f << "dim[paper]=" << paperBox << ",";
@@ -1222,18 +1360,19 @@ bool PowerPoint1Parser::readDocInfo(MWAWEntry const &entry)
MWAW_DEBUG_MSG(("PowerPoint1Parser::readDocInfo: the page dimension seems bad\n"));
}
else {
+ double const unit=m_state->m_unit;
// checkme, maybe better to define a slide with pageSize and no margins
getPageSpan().setFormOrientation(MWAWPageSpan::PORTRAIT);
if (pageBox[0][1]>=paperBox[0][1])
- getPageSpan().setMarginTop(double(pageBox[0][1]-paperBox[0][1])/72.0);
+ getPageSpan().setMarginTop(double(pageBox[0][1]-paperBox[0][1])*unit/72.0);
if (pageBox[1][1]<=paperBox[1][1])
- getPageSpan().setMarginBottom(double(paperBox[1][1]-pageBox[1][1])/72.0);
+ getPageSpan().setMarginBottom(double(paperBox[1][1]-pageBox[1][1])*unit/72.0);
if (pageBox[0][0]>=paperBox[0][0])
- getPageSpan().setMarginLeft(double(pageBox[0][0]-paperBox[0][0])/72.0);
+ getPageSpan().setMarginLeft(double(pageBox[0][0]-paperBox[0][0])*unit/72.0);
if (pageBox[1][0]<=paperBox[1][0])
- getPageSpan().setMarginRight(double(paperBox[1][0]-pageBox[1][0])/72.0);
- getPageSpan().setFormLength(double(paperSize.y())/72.);
- getPageSpan().setFormWidth(double(paperSize.x())/72.);
+ getPageSpan().setMarginRight(double(paperBox[1][0]-pageBox[1][0])*unit/72.0);
+ getPageSpan().setFormLength(double(paperSize.y())*unit/72.);
+ getPageSpan().setFormWidth(double(paperSize.x())*unit/72.);
}
if (isMacFile) {
val=int(input->readLong(2)); // 0
@@ -1341,6 +1480,71 @@ bool PowerPoint1Parser::readDocInfo(MWAWEntry const &entry)
return true;
}
+bool PowerPoint1Parser::readPictureDefinition(MWAWEntry const &entry, size_t pId)
+{
+ if (!entry.valid() || entry.length()<28) {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readPictureDefinition: the zone seems bad\n"));
+ return false;
+ }
+ MWAWInputStreamPtr input = getInput();
+ long pos = entry.begin();
+ entry.setParsed(true);
+ ascii().addPos(entry.end());
+ ascii().addNote("_");
+ input->seek(pos, librevenge::RVNG_SEEK_SET);
+ libmwaw::DebugStream f;
+ f << "Entries(Picture)[Z"<< entry.id() << "-" << pId << "]:def,";
+ int val=int(input->readULong(2)); // big number [0-3]XXX
+ if (val) f << "id=" << std::hex << val << std::dec << ",";
+ int type=int(input->readULong(2)); // 1-4
+ if (type)
+ f << "type=" << type << ",";
+ int dim[4];
+ for (int i=0; i<4; ++i) dim[i]=int(input->readLong(2));
+ f << "dim=" << MWAWBox2i(MWAWVec2i(dim[0],dim[1]),MWAWVec2i(dim[2],dim[3])) << ",";
+ val=int(input->readULong(2));
+ if (val!=2) {
+ f << "###type2=" << val << ",";
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readPictureDefinition: find unexpected type 2\n"));
+ }
+ int child=int(input->readULong(2));
+ if (child>=0 && child<int(m_state->m_zonesList.size())) {
+ f << "child[id]=Z" << child << ",";
+ if (pId>=m_state->m_picturesIdList.size())
+ m_state->m_picturesIdList.resize(pId+1,-1);
+ m_state->m_picturesIdList[pId]=child;
+ }
+ else {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readPictureDefinition: find some bad child\n"));
+ f << "child[id]=##Z" << child << ",";
+ }
+ if (type==4) {
+ for (int i=0; i<3; ++i) {
+ val=int(input->readULong(2));
+ child=int(input->readULong(2));
+ if (child>=0 && child<int(m_state->m_zonesList.size())) {
+ f << "child" << i << "[id]=Z" << child << "[" << val << "],";
+ MWAWEntry const &cEntry=m_state->getZoneEntry(child);
+ if (!cEntry.valid() || cEntry.isParsed()) continue;
+ // find type=10,14(string: Graph),16(probably the graph structure)
+ cEntry.setParsed(true);
+ libmwaw::DebugStream f2;
+ f2 << "Entries(Pict" << val << "):";
+ ascii().addPos(cEntry.begin());
+ ascii().addNote(f2.str().c_str());
+ }
+ else {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readPictureDefinition: find some bad child\n"));
+ f << "child" << i << "[id]=##Z" << child << "[" << val << "],";
+ }
+ }
+ }
+ ascii().addDelimiter(input->tell(),'|');
+ ascii().addPos(pos);
+ ascii().addNote(f.str().c_str());
+ return true;
+}
+
bool PowerPoint1Parser::readPicture(MWAWEntry const &entry, MWAWEmbeddedObject &picture)
{
if (!entry.valid() || entry.length()<20) {
@@ -1438,7 +1642,8 @@ bool PowerPoint1Parser::readZoneIdList2(MWAWEntry const &entry, int zId)
input->seek(pos, librevenge::RVNG_SEEK_SET);
libmwaw::DebugStream f;
- f << "Entries(UnkList)[" << zId << ",Z"<< entry.id() << "]:";
+ std::string const wh(zId==0 ? "Picture" : zId==1 ? "Ruler" : zId==2 ? "Scheme" : "UnknownList");
+ f << "Entries(" << wh << ")[Z"<< entry.id() << "]:list,";
int val=int(input->readULong(2)); // 8001
if (val!=0x8001) f << "f0=" << std::hex << val << std::dec << ",";
val=int(input->readULong(2)); // big number
@@ -1458,7 +1663,7 @@ bool PowerPoint1Parser::readZoneIdList2(MWAWEntry const &entry, int zId)
val=int(input->readULong(2));
int const(expected[])= {0x7fff, 0, 2, 0, 0};
if (val!=expected[i])
- f << "f" << i+1 << "=" << val << ",";
+ f << "f" << i+2 << "=" << val << ",";
}
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
@@ -1468,7 +1673,14 @@ bool PowerPoint1Parser::readZoneIdList2(MWAWEntry const &entry, int zId)
for (size_t i=0; i<N; ++i) {
pos=input->tell();
f.str("");
- f << "UnkList-" << i << ":";
+ if (zId==0)
+ f << "Picture-P" << i << ":";
+ else if (zId==1)
+ f << "Ruler-R" << i << ":";
+ else if (zId==2)
+ f << "Scheme-S" << i << ":";
+ else
+ f << wh << "-" << i << ":";
int type=int(input->readULong(2));
int id=int(input->readLong(2));
if (type==0 || id==-1) {
@@ -1493,17 +1705,27 @@ bool PowerPoint1Parser::readZoneIdList2(MWAWEntry const &entry, int zId)
}
ascii().addPos(entry.end());
ascii().addNote("_");
- f.str("");
- f << "Entries(Zone" << zId << "):";
- for (size_t i=0; i<N; ++i) {
- if (list[i]==-1) continue;
- MWAWEntry const &cEntry=m_state->getZoneEntry(list[i]);
- if (!cEntry.valid() || cEntry.isParsed()) continue;
- cEntry.setParsed(true);
- ascii().addPos(cEntry.begin());
- ascii().addNote(f.str().c_str());
- ascii().addPos(cEntry.end());
- ascii().addNote("_");
+ if (zId==2)
+ m_state->m_schemesIdList=list;
+ else {
+ f.str("");
+ f << "Entries(UnknList" << zId << "):";
+ for (size_t i=0; i<N; ++i) {
+ if (list[i]==-1) continue;
+ MWAWEntry const &cEntry=m_state->getZoneEntry(list[i]);
+ if (!cEntry.valid() || cEntry.isParsed()) continue;
+ if (zId==0)
+ readPictureDefinition(cEntry, i);
+ else if (zId==1)
+ readRuler(cEntry, i);
+ else {
+ cEntry.setParsed(true);
+ ascii().addPos(cEntry.begin());
+ ascii().addNote(f.str().c_str());
+ ascii().addPos(cEntry.end());
+ ascii().addNote("_");
+ }
+ }
}
return true;
}
@@ -1586,7 +1808,7 @@ bool PowerPoint1Parser::readRulers(MWAWEntry const &entry)
PowerPoint1ParserInternal::Ruler::Outline &outline=ruler.m_outlines[j];
f << "[";
for (int k=0; k<2; ++k) outline.m_margins[k]=int(input->readULong(2));
- for (int k=0; k<2; ++k) outline.m_interlines[k]=int(input->readULong(1));
+ for (int k=0; k<2; ++k) outline.m_interlines[k]=10*int(input->readULong(1));
f << outline << ",";
f << "fl=" << std::hex << input->readULong(2) << std::dec << ",";
f << "],";
@@ -1601,6 +1823,75 @@ bool PowerPoint1Parser::readRulers(MWAWEntry const &entry)
return true;
}
+bool PowerPoint1Parser::readRuler(MWAWEntry const &entry, size_t id)
+{
+ if (!entry.valid() || (entry.length()<54)!=0) {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readRuler: the zone seems bad\n"));
+ return false;
+ }
+ MWAWInputStreamPtr input = getInput();
+ long pos = entry.begin();
+ entry.setParsed(true);
+ input->seek(pos, librevenge::RVNG_SEEK_SET);
+ libmwaw::DebugStream f;
+ f << "Entries(Ruler)[Z"<< entry.id() << "]:R" << id << ",";
+
+ if (m_state->m_rulersList.size()<id+1)
+ m_state->m_rulersList.resize(id+1);
+ PowerPoint1ParserInternal::Ruler &ruler=m_state->m_rulersList[id];
+ f << "levels=[";
+ for (int j=0; j<5; ++j) {
+ PowerPoint1ParserInternal::Ruler::Outline &outline=ruler.m_outlines[j];
+ f << "[";
+ for (int k=0; k<2; ++k) outline.m_margins[k]=int(input->readULong(2));
+ for (int k=0; k<2; ++k) outline.m_interlines[k]=int(input->readULong(2));
+ f << outline << ",";
+ f << "fl=" << std::hex << input->readULong(2) << std::dec << ",";
+ f << "],";
+ }
+ f << "],";
+ int val=int(input->readULong(2)); // 2-3: align?
+ if (val!=3) f << "f0=" << val << ",";
+ int nTabs=int(input->readULong(2));
+ if (input->tell()+4*nTabs>entry.end()) {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readRuler: the number of tab seems bad\n"));
+ f << "###n[tabs]=" << nTabs << ",";
+ nTabs=0;
+ }
+ f << "tabs=[";
+ for (int j=0, bit=1; j<nTabs; ++j, bit<<=1) {
+ MWAWTabStop tab;
+ tab.m_position=double(input->readULong(2))/8./72.;
+ val=int(input->readULong(2));
+ switch (val) {
+ case 0:
+ tab.m_alignment=MWAWTabStop::DECIMAL;
+ break;
+ case 1:
+ tab.m_alignment=MWAWTabStop::RIGHT;
+ break;
+ case 2:
+ tab.m_alignment=MWAWTabStop::CENTER;
+ break;
+ case 3:
+ tab.m_alignment=MWAWTabStop::LEFT;
+ break;
+ default:
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readRuler: find unknown alignment\n"));
+ f << "##align=" << val << ",";
+ break;
+ }
+ ruler.m_tabs.push_back(tab);
+ f << tab << ",";
+ }
+ f << "],";
+ if (input->tell()!=entry.end())
+ ascii().addDelimiter(input->tell(),'|');
+ ascii().addPos(pos);
+ ascii().addNote(f.str().c_str());
+ return true;
+}
+
bool PowerPoint1Parser::readColors(MWAWEntry const &entry)
{
@@ -1612,6 +1903,7 @@ bool PowerPoint1Parser::readColors(MWAWEntry const &entry)
long pos = entry.begin();
entry.setParsed(true);
input->seek(pos, librevenge::RVNG_SEEK_SET);
+ bool const isMacFile=m_state->m_isMacFile;
libmwaw::DebugStream f;
f << "Entries(Color)[Z"<< entry.id() << "]:";
int val;
@@ -1621,7 +1913,7 @@ bool PowerPoint1Parser::readColors(MWAWEntry const &entry)
}
int N=int(input->readULong(2));
f << "N=" << N << ",";
- if (8+(N+1)*8 != int(entry.length())) {
+ if ((isMacFile && 8+(N+1)*8 != int(entry.length())) || (!isMacFile && 8+(N+1)*8 > int(entry.length()))) {
MWAW_DEBUG_MSG(("PowerPoint1Parser::readColors: the N value seems bad\n"));
f << "###";
ascii().addPos(pos);
@@ -1653,12 +1945,17 @@ bool PowerPoint1Parser::readColors(MWAWEntry const &entry)
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
}
+ if (input->tell()!=entry.end()) {
+ ascii().addPos(input->tell());
+ ascii().addNote("Color:extra");
+ }
return true;
}
bool PowerPoint1Parser::readColorZone(MWAWEntry const &entry)
{
- if (!entry.valid() || (entry.length()<48)) {
+ bool const isMacFile=m_state->m_isMacFile;
+ if (!entry.valid() || (entry.length()<(isMacFile ? 48 : 43))) {
MWAW_DEBUG_MSG(("PowerPoint1Parser::readColorZone: the zone seems bad\n"));
return false;
}
@@ -1670,7 +1967,7 @@ bool PowerPoint1Parser::readColorZone(MWAWEntry const &entry)
f << "Entries(Color)[Z"<< entry.id() << "]:menu,";
int N=int(input->readULong(2));
f << "N=" << N << ",";
- if (48+2*N!=int(entry.length())) {
+ if ((isMacFile && 48+2*N!=int(entry.length())) || (!isMacFile && 43+2*N>int(entry.length()))) {
MWAW_DEBUG_MSG(("PowerPoint1Parser::readColorZone: the N value seems bad\n"));
f << "###";
ascii().addPos(pos);
@@ -1681,7 +1978,7 @@ bool PowerPoint1Parser::readColorZone(MWAWEntry const &entry)
}
int val=int(input->readLong(2)); // always a
if (val!=10) f << "f0=" << val << ",";
- int id=int(input->readLong(4));
+ int id=int(input->readLong(isMacFile ? 4 : 2));
int const numZones=int(m_state->m_zonesList.size());
if (id>0 && id<numZones)
f << "colors=Z" << id << ",";
@@ -1694,7 +1991,7 @@ bool PowerPoint1Parser::readColorZone(MWAWEntry const &entry)
}
ascii().addDelimiter(input->tell(),'|');
// unsure probably some dimension here
- input->seek(pos+46, librevenge::RVNG_SEEK_SET);
+ input->seek(pos+(isMacFile ? 46 : 43), librevenge::RVNG_SEEK_SET);
ascii().addDelimiter(input->tell(),'|');
f << "num[used]=[";
for (int i=0; i<N; ++i) { // 0|1|2
@@ -1703,8 +2000,12 @@ bool PowerPoint1Parser::readColorZone(MWAWEntry const &entry)
else f << "_,";
}
f << "],";
- val=int(input->readULong(2));
- if (val) f << "g0=" << std::hex << val << std::dec << ",";
+ if (isMacFile) {
+ val=int(input->readULong(2));
+ if (val) f << "g0=" << std::hex << val << std::dec << ",";
+ }
+ if (input->tell()!=entry.end())
+ ascii().addDelimiter(input->tell(),'|');
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
ascii().addPos(entry.end());
@@ -1717,7 +2018,8 @@ bool PowerPoint1Parser::readColorZone(MWAWEntry const &entry)
bool PowerPoint1Parser::readFonts(MWAWEntry const &entry)
{
- if (!entry.valid() || (entry.length()%6)!=0) {
+ static bool isMacFile=m_state->m_isMacFile;
+ if (!entry.valid() || entry.length()<(isMacFile ? 6 : 13) || (isMacFile && entry.length()%6)!=0) {
MWAW_DEBUG_MSG(("PowerPoint1Parser::readFonts: the zone seems bad\n"));
return false;
}
@@ -1726,19 +2028,28 @@ bool PowerPoint1Parser::readFonts(MWAWEntry const &entry)
entry.setParsed(true);
input->seek(pos, librevenge::RVNG_SEEK_SET);
libmwaw::DebugStream f;
- f << "Entries(Font)[Z"<< entry.id() << "]:";
+ f << "Entries(FontDef)[Z"<< entry.id() << "]:";
+ size_t N=size_t(entry.length()/6);
+ if (!isMacFile) {
+ N=size_t(input->readULong(2)); // always 6?
+ if (long(6+7*N)>entry.length()) {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readFonts: the zone seems bad\n"));
+ return false;
+ }
+ f << "N=" << N << ",";
+ f << "id=" << std::hex << input->readULong(4) << std::dec << ","; // big number
+ }
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
- size_t N=size_t(entry.length()/6);
for (size_t i=0; i<N; ++i) {
pos=input->tell();
f.str("");
- f << "Font-F" << i << ":";
+ f << "FontDef-F" << i << ":";
MWAWFont font;
font.setId(int(input->readULong(2)));
font.setSize(float(input->readULong(2)));
- int flag = int(input->readULong(1));
+ int flag = int(input->readULong(isMacFile ? 1 : 2));
uint32_t flags=0;
if (flag&0x1) flags |= MWAWFont::boldBit;
if (flag&0x2) flags |= MWAWFont::italicBit;
@@ -1748,13 +2059,94 @@ bool PowerPoint1Parser::readFonts(MWAWEntry const &entry)
if (flag&0xE0) f << "#flag=" << (flag>>5) << ",";
font.setFlags(flags);
f << font.getDebugString(getParserState()->m_fontConverter);
- int val=int(input->readULong(1)); // another flag ?
+ int val=int(input->readULong(1)); // 1-4: another flag or maybe the font's color ?
if (val) f << "fl=" << std::hex << val << std::dec << ",";
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
}
ascii().addPos(entry.end());
ascii().addNote("_");
+ if (input->tell()!=entry.end()) {
+ ascii().addPos(input->tell());
+ ascii().addNote("FontDef:extra");
+ }
+ return true;
+}
+
+bool PowerPoint1Parser::readFontNames(MWAWEntry const &entry)
+{
+ if (!entry.valid() || entry.length()<16) {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readFontNames: the zone seems bad\n"));
+ return false;
+ }
+ MWAWInputStreamPtr input = getInput();
+ long pos = entry.begin();
+ entry.setParsed(true);
+ input->seek(pos, librevenge::RVNG_SEEK_SET);
+ libmwaw::DebugStream f;
+ f << "Entries(FontName)[Z"<< entry.id() << "]:";
+ int val;
+ for (int i=0; i<2; ++i) {
+ val=int(input->readULong(2));
+ int const(expected[])= {0x8001,0x25ba};
+ if (val!=expected[i])
+ f << "f" << i << "=" << std::hex << val << std::dec << ",";
+ }
+ size_t N=size_t(input->readULong(2)); // always 6?
+ if (long(16+52*N)>entry.length()) {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::readFontNames: the zone seems bad\n"));
+ return false;
+ }
+ f << "N=" << N << ",";
+ for (int i=0; i<5; ++i) {
+ val=int(input->readULong(2));
+ int const(expected[])= {0x7fff,0,0x32,0,0};
+ if (val!=expected[i])
+ f << "f" << i << "=" << std::hex << val << std::dec << ",";
+ }
+ ascii().addPos(pos);
+ ascii().addNote(f.str().c_str());
+
+ for (size_t i=0; i<N; ++i) {
+ pos=input->tell();
+ f.str("");
+ f << "FontName-FN" << i << ":";
+ val=int(input->readULong(2));
+ if (!val) {
+ f << "_,";
+ input->seek(pos+52,librevenge::RVNG_SEEK_SET);
+ ascii().addPos(pos);
+ ascii().addNote(f.str().c_str());
+ continue;
+ }
+ f << "id=" << val << ",";
+ for (int j=0; j<9; ++j) { // f4=0|190, f8=0|22|52
+ val=int(input->readULong(2));
+ if (val)
+ f << "f" << j << "=" << std::hex << val << std::dec << ",";
+ }
+ std::string name; // Helv, Tms Rmn, ZapfDingbats
+ for (int c=0; c<32; ++c) {
+ char ch=char(input->readULong(1));
+ if (!ch) break;
+ name+=ch;
+ }
+ if (!name.empty()) {
+ f << name << ",";
+ /* FIXME: by default, we force the family to be CP1252,
+ but we may want to use the file/font encoding */
+ getFontConverter()->setCorrespondance(int(i), name, (name=="MonoType Sorts" || name=="Wingdings") ? "" : "CP1252");
+ }
+ input->seek(pos+52,librevenge::RVNG_SEEK_SET);
+ ascii().addPos(pos);
+ ascii().addNote(f.str().c_str());
+ }
+ ascii().addPos(entry.end());
+ ascii().addNote("_");
+ if (input->tell()!=entry.end()) {
+ ascii().addPos(input->tell());
+ ascii().addNote("FontName:extra");
+ }
return true;
}
@@ -1769,7 +2161,8 @@ bool PowerPoint1Parser::readSchemes()
}
bool PowerPoint1Parser::readScheme(MWAWEntry const &entry, int id)
{
- if (!entry.valid() || entry.length()!=86) {
+ bool const isMacFile=m_state->m_isMacFile;
+ if (!entry.valid() || (isMacFile && entry.length()!=86) || (!isMacFile && entry.length() < 96)) {
MWAW_DEBUG_MSG(("PowerPoint1Parser::readScheme: the zone seems bad\n"));
return false;
}
@@ -1781,12 +2174,24 @@ bool PowerPoint1Parser::readScheme(MWAWEntry const &entry, int id)
libmwaw::DebugStream f;
f << "Entries(Scheme)[Z"<< entry.id() << "]:S" << id << ",";
int val;
- for (int i=0; i<11; ++i) { // f8=0|80
- val=int(input->readLong(2));
- int const(expected[])= {16,0,0,100,100,100, 0x101, 0, 0, 0, 7};
- if (val!=expected[i])
- f << "f" << i << "=" << val << ",";
+ if (isMacFile) {
+ for (int i=0; i<10; ++i) { // f8=0|80
+ val=int(input->readLong(2));
+ int const(expected[])= {16,0,0,100,100,100, 0x101, 0, 0, 0};
+ if (val!=expected[i])
+ f << "f" << i << "=" << val << ",";
+ }
+ }
+ else {
+ for (int i=0; i<12; ++i) { // f9=0|80
+ val=int(input->readLong(i==3 ? 1 : 2));
+ int const(expected[])= {0,16,0,0, 100,100,100, 1, 1, 0, 0, 0};
+ if (val!=expected[i])
+ f << "f" << i << "=" << val << ",";
+ }
}
+ val=int(input->readLong(2));
+ if (val!=7) f << "max[color]=##" << val << ",";
f << "colors=[";
for (int i=0; i<8; ++i) {
val=int(input->readULong(2));
@@ -1801,6 +2206,8 @@ bool PowerPoint1Parser::readScheme(MWAWEntry const &entry, int id)
}
else
m_state->m_idToSchemeMap[id]=scheme;
+ if (input->tell()!=entry.end())
+ ascii().addDelimiter(input->tell(),'|');
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
ascii().addPos(entry.end());
@@ -1810,6 +2217,7 @@ bool PowerPoint1Parser::readScheme(MWAWEntry const &entry, int id)
bool PowerPoint1Parser::readZone2(MWAWEntry const &entry)
{
+ // probably the document current style
int const expectedSize=m_state->m_isMacFile ? 22 : 32;
if (!entry.valid() || entry.length()!=expectedSize) {
MWAW_DEBUG_MSG(("PowerPoint1Parser::readZone2: the zone seems bad\n"));
@@ -1913,6 +2321,7 @@ bool PowerPoint1Parser::sendText(PowerPoint1ParserInternal::TextZone const &text
tId[1]=tId[0];
}
PowerPoint1ParserInternal::Ruler ruler;
+ bool const isMacFile=m_state->m_isMacFile;
bool hasRuler=false;
if (rulerId>=0 && rulerId<int(m_state->m_rulersList.size())) {
ruler=m_state->m_rulersList[size_t(rulerId)];
@@ -1924,10 +2333,12 @@ bool PowerPoint1Parser::sendText(PowerPoint1ParserInternal::TextZone const &text
MWAWInputStreamPtr input = getInput();
long pos;
int const vers=version();
+ double const unit=double(m_state->m_unit);
for (int z=tId[0]; z<=tId[1]; ++z) {
if (z!=tId[0]) listener->insertEOL();
PowerPoint1ParserInternal::TextZone::Line const &line=textZone.m_lineList[size_t(z)];
MWAWEntry const &fEntry=line.m_format;
+ MWAWEntry const &rEntry=line.m_ruler;
MWAWEntry const &tEntry=line.m_text;
// update the paragraph
MWAWParagraph para;
@@ -1937,28 +2348,32 @@ bool PowerPoint1Parser::sendText(PowerPoint1ParserInternal::TextZone const &text
PowerPoint1ParserInternal::Ruler::Outline const &outline=ruler.m_outlines[line.m_outlineLevel];
para.m_marginsUnit=librevenge::RVNG_POINT;
for (int i=0; i<2; ++i)
- para.m_margins[i]=double(outline.m_margins[i]);
+ para.m_margins[i]=unit*double(outline.m_margins[i]);
*para.m_margins[0]-=*(para.m_margins[1]);
- para.setInterline(double(outline.m_interlines[0])*0.1, librevenge::RVNG_PERCENT);
+ para.setInterline(double(outline.m_interlines[0])*0.01, librevenge::RVNG_PERCENT);
if (outline.m_interlines[1]>outline.m_interlines[0]) // assume 12 pt
- para.m_spacings[2]=double(outline.m_interlines[1]-outline.m_interlines[0])*0.1*12/72;
+ para.m_spacings[2]=double(outline.m_interlines[1]-outline.m_interlines[0])*0.01*12/72;
}
listener->setParagraph(para);
// now read the format
input->seek(fEntry.begin(), librevenge::RVNG_SEEK_SET);
- int const dtSz=vers==1 ? 6 : 8;
+ int const dtSz=vers==1 ? 6 : isMacFile ? 8 : 14;
int N=(fEntry.length()%dtSz)==0 ? int(fEntry.length()/dtSz) : 0;
libmwaw::DebugStream f;
std::map<int, MWAWFont> posToFontMap;
+ int cPos=0;
for (int i=0; i<N; ++i) {
pos=input->tell();
f.str("");
f << "TextZone-F[" << i << "]:";
- int cPos=int(input->readULong(2));
+ int numC=int(input->readULong(2));
+ if (isMacFile) cPos=numC;
f << "pos=" << cPos << ",";
MWAWFont font;
- font.setSize(float(input->readULong(1)));
- int flag = int(input->readULong(1));
+ if (!isMacFile)
+ font.setId(int(input->readULong(2)));
+ font.setSize(float(input->readULong(isMacFile ? 1 : 2)));
+ int flag = int(input->readULong(isMacFile ? 1 : 2));
uint32_t flags=0;
if (flag&0x1) flags |= MWAWFont::boldBit;
if (flag&0x2) flags |= MWAWFont::italicBit;
@@ -1967,8 +2382,9 @@ bool PowerPoint1Parser::sendText(PowerPoint1ParserInternal::TextZone const &text
if (flag&0x10) flags |= MWAWFont::shadowBit;
if (flag&0xE0) f << "#flag=" << (flag>>5) << ",";
font.setFlags(flags);
- font.setId(int(input->readULong(2)));
- if (dtSz==8) {
+ if (isMacFile)
+ font.setId(int(input->readULong(2)));
+ if (dtSz>=8) {
int col=int(input->readULong(1));
MWAWColor color;
if (textZone.m_schemeId>=0 && getColor(col, textZone.m_schemeId, color)) {
@@ -1988,13 +2404,79 @@ bool PowerPoint1Parser::sendText(PowerPoint1ParserInternal::TextZone const &text
else
posToFontMap[cPos]=font;
f << font.getDebugString(getParserState()->m_fontConverter);
+ if (input->tell()!=pos+dtSz)
+ ascii().addDelimiter(input->tell(),'|');
input->seek(pos+dtSz, librevenge::RVNG_SEEK_SET);
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
+ if (!isMacFile) cPos+=numC;
+ }
+ std::map<int, MWAWParagraph> posToRulerMap;
+ if (rEntry.valid()) {
+ // now read the rulers
+ input->seek(rEntry.begin(), librevenge::RVNG_SEEK_SET);
+ N=(rEntry.length()%6)==0 ? int(rEntry.length()/6) : 0;
+ cPos=0;
+ for (int i=0; i<N; ++i) {
+ pos=input->tell();
+ f.str("");
+ f << "TextZone-R[" << i << "]:";
+ int numC=int(input->readULong(2));
+ f << "pos=" << cPos << ",";
+ MWAWParagraph cPara(para);
+ int outlineLevel=int(input->readULong(2));
+ if (hasRuler && outlineLevel>0 && outlineLevel<=4) {
+ f << "level=" << outlineLevel << ",";
+ PowerPoint1ParserInternal::Ruler::Outline const &outline=ruler.m_outlines[outlineLevel];
+ cPara.m_marginsUnit=librevenge::RVNG_POINT;
+ for (int j=0; j<2; ++j)
+ cPara.m_margins[j]=unit*double(outline.m_margins[j]);
+ *cPara.m_margins[0]-=*(cPara.m_margins[1]);
+ cPara.setInterline(double(outline.m_interlines[0])*0.01, librevenge::RVNG_PERCENT);
+ if (outline.m_interlines[1]>outline.m_interlines[0]) // assume 12 pt
+ cPara.m_spacings[2]=double(outline.m_interlines[1]-outline.m_interlines[0])*0.01*12/72;
+ }
+ else if (outlineLevel>4) {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::sendText: oops, the outline level seems bad\n"));
+ f << "###outlineLevel=" << outlineLevel << ",";
+ }
+ int adjust=int(input->readULong(2));
+ switch (adjust) {
+ case 0: // left
+ cPara.m_justify=MWAWParagraph::JustificationLeft;
+ break;
+ case 1:
+ cPara.m_justify=MWAWParagraph::JustificationCenter;
+ f << "center,";
+ break;
+ case 2:
+ cPara.m_justify=MWAWParagraph::JustificationRight;
+ f << "right,";
+ break;
+ case 3:
+ cPara.m_justify=MWAWParagraph::JustificationFull;
+ f << "justify,";
+ break;
+ default:
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::sendText: find unknown alignment\n"));
+ f << "##align=" << adjust << ",";
+ break;
+ }
+ if (posToRulerMap.find(cPos)!=posToRulerMap.end()) {
+ MWAW_DEBUG_MSG(("PowerPoint1Parser::sendText: oops, find duplicated paragraph\n"));
+ f << "##dup,";
+ }
+ else
+ posToRulerMap[cPos]=cPara;
+ ascii().addPos(pos);
+ ascii().addNote(f.str().c_str());
+ cPos+=numC;
+ }
}
-
input->seek(tEntry.begin(), librevenge::RVNG_SEEK_SET);
for (int i=0; i<int(tEntry.length()); ++i) {
+ if (posToRulerMap.find(i)!=posToRulerMap.end())
+ listener->setParagraph(posToRulerMap.find(i)->second);
if (posToFontMap.find(i)!=posToFontMap.end())
listener->setFont(posToFontMap.find(i)->second);
unsigned char c=static_cast<unsigned char>(input->readULong(1));
@@ -2039,7 +2521,8 @@ bool PowerPoint1Parser::sendFrame(PowerPoint1ParserInternal::Frame const &frame,
MWAW_DEBUG_MSG(("PowerPoint1Parser::sendFrame: can not find the listener\n"));
return false;
}
- MWAWBox2i fBox(frame.m_dimension[0]+m_state->m_origin, frame.m_dimension[1]+m_state->m_origin);
+ MWAWBox2f fBox(m_state->m_unit*MWAWVec2f(frame.m_dimension[0]+m_state->m_origin),
+ m_state->m_unit*MWAWVec2f(frame.m_dimension[1]+m_state->m_origin));
if (frame.m_textId[0]>=0) {
MWAWPosition pos(fBox[0], fBox.size(), librevenge::RVNG_POINT);
pos.m_anchorTo = MWAWPosition::Page;
@@ -2054,7 +2537,7 @@ bool PowerPoint1Parser::sendFrame(PowerPoint1ParserInternal::Frame const &frame,
if (frame.m_type==0)
shape=MWAWGraphicShape::line(fBox[0], fBox[1]);
else {
- if (frame.m_cornerSize >= frame.m_dimension.size()[0] || frame.m_cornerSize >= frame.m_dimension.size()[1])
+ if (frame.m_cornerSize >= fBox.size()[0] || frame.m_cornerSize >= fBox.size()[1])
shape=MWAWGraphicShape::circle(fBox);
else
shape=MWAWGraphicShape::rectangle(fBox, MWAWVec2f(float(frame.m_cornerSize)/2.f, float(frame.m_cornerSize)/2.f));
@@ -2096,17 +2579,13 @@ bool PowerPoint1Parser::checkHeader(MWAWHeader *header, bool strict)
input->setReadInverted(false);
input->seek(pos, librevenge::RVNG_SEEK_SET);
unsigned long signature=input->readULong(4);
-#ifdef DEBUG
if (signature==0xeddead0b) {
input->setReadInverted(true);
m_state->m_isMacFile=false;
+ m_state->m_unit=1.f/8.f;
}
else if (signature!=0xbaddeed)
return false;
-#else
- if (signature!=0xbaddeed)
- return false;
-#endif
f << "FileHeader:";
int vers=int(input->readLong(4));
if (vers!=2) return false;
diff --git a/src/lib/PowerPoint1Parser.hxx b/src/lib/PowerPoint1Parser.hxx
index 58cc2aa..1e02caa 100644
--- a/src/lib/PowerPoint1Parser.hxx
+++ b/src/lib/PowerPoint1Parser.hxx
@@ -101,12 +101,18 @@ protected:
bool readColorZone(MWAWEntry const &entry);
//! try to read a font style list
bool readFonts(MWAWEntry const &entry);
+ //! try to read a font names list
+ bool readFontNames(MWAWEntry const &entry);
//! try to read a picture zone
bool readPicture(MWAWEntry const &entry, MWAWEmbeddedObject &picture);
+ //! try to read the picture definition: windows v2
+ bool readPictureDefinition(MWAWEntry const &entry, size_t id);
//! try to read a print info zone
bool readPrintInfo(MWAWEntry const &entry);
//! try to read the paragraph style
bool readRulers(MWAWEntry const &entry);
+ //! try to read some ruler: windows v2
+ bool readRuler(MWAWEntry const &entry, size_t id);
//! try to read a scheme
bool readScheme(MWAWEntry const &entry, int id);
//! try to read the schemes
diff --git a/src/lib/PowerPoint3OLE.cxx b/src/lib/PowerPoint3OLE.cxx
new file mode 100644
index 0000000..ad7b884
--- /dev/null
+++ b/src/lib/PowerPoint3OLE.cxx
@@ -0,0 +1,228 @@
+/* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
+
+/* libmwaw
+* Version: MPL 2.0 / LGPLv2+
+*
+* The contents of this file are subject to the Mozilla Public License Version
+* 2.0 (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) 2002 William Lachance (wrlach at gmail.com)
+* Copyright (C) 2002,2004 Marc Maurer (uwog at uwog.net)
+* Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba at bluewin.ch)
+* Copyright (C) 2006, 2007 Andrew Ziem
+* Copyright (C) 2011, 2012 Alonso Laurent (alonso at loria.fr)
+*
+*
+* All Rights Reserved.
+*
+* For minor contributions see the git repository.
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
+* in which case the provisions of the LGPLv2+ are applicable
+* instead of those above.
+*/
+
+#include <algorithm>
+#include <iomanip>
+#include <iostream>
+#include <set>
+#include <sstream>
+#include <utility>
+
+#include <librevenge/librevenge.h>
+
+#include "MWAWDebug.hxx"
+#include "MWAWEntry.hxx"
+#include "MWAWOLEParser.hxx"
+
+#include "PowerPoint3OLE.hxx"
+
+/** Internal: the structures of a PowerPoint3OLE */
+namespace PowerPoint3OLEInternal
+{
+////////////////////////////////////////
+//! Internal: the state of a PowerPoint3OLE
+struct State {
+ //! constructor
+ explicit State(MWAWInputStreamPtr input) : m_input(input), m_oleParser(), m_unparsedNameSet()
+ {
+ }
+ /** the input */
+ MWAWInputStreamPtr m_input;
+ /** the ole parser */
+ shared_ptr<MWAWOLEParser> m_oleParser;
+ /** the list of unparsed zone */
+ std::set<std::string> m_unparsedNameSet;
+};
+
+}
+
+////////////////////////////////////////////////////////////
+// constructor/destructor, ...
+////////////////////////////////////////////////////////////
+PowerPoint3OLE::PowerPoint3OLE(MWAWInputStreamPtr input, MWAWFontConverterPtr fontConverter, int fId) : m_state(new PowerPoint3OLEInternal::State(input))
+{
+ if (input && input->isStructured() && input->getSubStreamByName("PP40"))
+ m_state->m_oleParser.reset(new MWAWOLEParser("PP40", fontConverter, fId));
+}
+
+PowerPoint3OLE::~PowerPoint3OLE()
+{
+}
+
+void PowerPoint3OLE::updateMetaData(librevenge::RVNGPropertyList &metaData) const
+{
+ if (m_state->m_oleParser)
+ m_state->m_oleParser->updateMetaData(metaData);
+}
+
+////////////////////////////////////////////////////////////
+// the parser
+////////////////////////////////////////////////////////////
+bool PowerPoint3OLE::parse()
+{
+ MWAWInputStreamPtr input=m_state->m_input;
+ if (!input || !m_state->m_oleParser || !m_state->m_oleParser->parse(input)) return false;
+ std::vector<std::string> unparsed = m_state->m_oleParser->getNotParse();
+
+ size_t numUnparsed = unparsed.size();
+ for (size_t i = 0; i < numUnparsed; i++) {
+ std::string const &name = unparsed[i];
+ // separated the directory and the name
+ // MatOST/MatadorObject1/Ole10Native
+ // -> dir="MatOST/MatadorObject1", base="Ole10Native"
+ std::string::size_type pos = name.find_last_of('/');
+ std::string dir, base;
+ if (pos == std::string::npos) base = name;
+ else if (pos == 0) base = name.substr(1);
+ else {
+ dir = name.substr(0,pos);
+ base = name.substr(pos+1);
+ }
+ if (dir.empty() && base=="PP40") continue;
+
+ MWAWInputStreamPtr ole = input->getSubStreamByName(name.c_str());
+ if (!ole.get()) {
+ MWAW_DEBUG_MSG(("PowerPoint3OLE::createZones: error: can not find OLE part: \"%s\"\n", name.c_str()));
+ continue;
+ }
+ ole->setReadInverted(true);
+ bool done=false;
+ switch (base[0]) {
+ case 'C':
+ if (base=="Current User")
+ done=parseCurrentUser(ole, name);
+ else if (base=="Current ID")
+ done=parseCurrentId(ole, name);
+ break;
+ default:
+ break;
+ }
+ if (done) continue;
+ m_state->m_unparsedNameSet.insert(name);
+ }
+ return true;
+}
+
+void PowerPoint3OLE::checkForUnparsedStream()
+{
+ for (std::set<std::string>::const_iterator it=m_state->m_unparsedNameSet.begin(); it!=m_state->m_unparsedNameSet.end(); ++it) {
+ std::string const &name = *it;
+ std::string::size_type pos = name.find_last_of('/');
+ std::string dir, base;
+ if (pos == std::string::npos) base = name;
+ else if (pos == 0) base = name.substr(1);
+ else {
+ dir = name.substr(0,pos);
+ base = name.substr(pos+1);
+ }
+
+ MWAWInputStreamPtr ole = m_state->m_input->getSubStreamByName(name.c_str());
+ if (!ole.get()) {
+ MWAW_DEBUG_MSG(("PowerPoint3OLE::checkForUnparsedStream: error: can not find OLE part: \"%s\"\n", name.c_str()));
+ continue;
+ }
+ libmwaw::DebugFile asciiFile(ole);
+ asciiFile.open(name);
+ libmwaw::DebugStream f;
+ f << "Entries(" << base << "):";
+ asciiFile.addPos(0);
+ asciiFile.addNote(f.str().c_str());
+ }
+}
+
+////////////////////////////////////////////////////////////
+// try to read the different stream
+////////////////////////////////////////////////////////////
+bool PowerPoint3OLE::parseCurrentId(MWAWInputStreamPtr input, std::string const &name)
+{
+ if (!input||input->size()!=4) {
+ MWAW_DEBUG_MSG(("PowerPoint3OLE::parseCurrentId: can not find the input\n"));
+ return false;
+ }
+ libmwaw::DebugFile ascFile(input);
+ ascFile.open(name);
+ input->seek(0, librevenge::RVNG_SEEK_SET);
+ libmwaw::DebugStream f;
+ f << "Entries(CurrentId):";
+ int val=int(input->readLong(4));
+ if (val) f << "id=" << val << ",";
+ ascFile.addPos(0);
+ ascFile.addNote(f.str().c_str());
+ return true;
+}
+
+bool PowerPoint3OLE::parseCurrentUser(MWAWInputStreamPtr input, std::string const &name)
+{
+ if (!input||input->size()==0) {
+ MWAW_DEBUG_MSG(("PowerPoint3OLE::parseCurrentUser: can not find the input\n"));
+ return false;
+ }
+ libmwaw::DebugFile ascFile(input);
+ ascFile.open(name);
+ input->seek(0, librevenge::RVNG_SEEK_SET);
+ long endPos=input->size();
+ libmwaw::DebugStream f;
+ f << "Entries(CurrentUser):";
+ int sSz=int(input->readULong(1));
+ if (sSz<0 || sSz+1>input->size()) {
+ MWAW_DEBUG_MSG(("PowerPoint3OLE::parseCurrentUser: the stream size seems bad\n"));
+ f << "###sSz,";
+ ascFile.addPos(0);
+ ascFile.addNote(f.str().c_str());
+ return true;
+ }
+ std::string user;
+ for (int c=0; c<sSz; ++c) {
+ char ch=char(input->readULong(1));
+ if (ch)
+ user+=ch;
+ else if (c+1!=sSz)
+ f << "###";
+ }
+ f << user;
+ ascFile.addPos(0);
+ ascFile.addNote(f.str().c_str());
+ if (input->tell()!=endPos) {
+ ascFile.addPos(input->tell());
+ ascFile.addNote("CurrentUser:##extra");
+ }
+ return true;
+}
+
+
+////////////////////////////////////////////////////////////
+// try to send data
+////////////////////////////////////////////////////////////
+
+
+// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
diff --git a/src/lib/PowerPoint3OLE.hxx b/src/lib/PowerPoint3OLE.hxx
new file mode 100644
index 0000000..bb62203
--- /dev/null
+++ b/src/lib/PowerPoint3OLE.hxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
+
+/* libmwaw
+* Version: MPL 2.0 / LGPLv2+
+*
+* The contents of this file are subject to the Mozilla Public License Version
+* 2.0 (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) 2002 William Lachance (wrlach at gmail.com)
+* Copyright (C) 2002,2004 Marc Maurer (uwog at uwog.net)
+* Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba at bluewin.ch)
+* Copyright (C) 2006, 2007 Andrew Ziem
+* Copyright (C) 2011, 2012 Alonso Laurent (alonso at loria.fr)
+*
+*
+* All Rights Reserved.
+*
+* For minor contributions see the git repository.
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
+* in which case the provisions of the LGPLv2+ are applicable
+* instead of those above.
+*/
+
+#ifndef POWER_POINT3_OLE
+# define POWER_POINT3_OLE
+
+#include <string>
+
+#include "MWAWInputStream.hxx"
+
+#include "MWAWParser.hxx"
+
+namespace PowerPoint3OLEInternal
+{
+struct State;
+}
+
+/** \brief the main class to read the ole stream in a Microsoft PowerPoint v4 files (MacOs and Windows)
+ */
+class PowerPoint3OLE
+{
+public:
+ //! constructor
+ PowerPoint3OLE(MWAWInputStreamPtr input, MWAWFontConverterPtr fontConverter, int fId);
+ //! destructor
+ virtual ~PowerPoint3OLE();
+
+ // the main parse function
+ bool parse();
+ /** update the meta data, using information find in SummaryInformation */
+ void updateMetaData(librevenge::RVNGPropertyList &metaData) const;
+ //! check for unparsed stream
+ void checkForUnparsedStream();
+
+protected:
+ //
+ // internal level
+ //
+
+ //! try to parse the "Current User" stream
+ bool parseCurrentUser(MWAWInputStreamPtr input, std::string const &name);
+ //! try to parse the "Current Id" stream
+ bool parseCurrentId(MWAWInputStreamPtr input, std::string const &name);
+
+ //
+ // send data
+ //
+
+ //
+ // low level
+ //
+
+protected:
+ //
+ // data
+ //
+ //! the state
+ shared_ptr<PowerPoint3OLEInternal::State> m_state;
+};
+#endif
+// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
diff --git a/src/lib/PowerPoint3Parser.cxx b/src/lib/PowerPoint3Parser.cxx
index 9ecbe1b..a1eaea1 100644
--- a/src/lib/PowerPoint3Parser.cxx
+++ b/src/lib/PowerPoint3Parser.cxx
@@ -52,6 +52,8 @@
#include "PowerPoint3Parser.hxx"
+#include "PowerPoint3OLE.hxx"
+
/** Internal: the structures of a PowerPoint3Parser */
namespace PowerPoint3ParserInternal
{
@@ -223,7 +225,7 @@ struct Ruler {
{
o << "margins=[";
for (int i=0; i<5; ++i)
- o << double(ruler.m_margins[1]-ruler.m_margins[0])/8 << ":" << double(ruler.m_margins[0])/8 << ",";
+ o << double(ruler.m_margins[2*i+1]-ruler.m_margins[2*i])/8 << ":" << double(ruler.m_margins[2*i])/8 << ",";
o << "],";
o << ruler.m_paragraph;
return o;
@@ -232,7 +234,7 @@ struct Ruler {
void updateParagraph(MWAWParagraph ¶, int level) const
{
if (level<0 || level>4) {
- MWAW_DEBUG_MSG(("PowerPoint3ParserInternal::ListZoneIdParser::parse: the level %d seems bad\n", level));
+ MWAW_DEBUG_MSG(("PowerPoint3ParserInternal::Ruler::updateParagraph: the level %d seems bad\n", level));
level=0;
}
para.m_marginsUnit=librevenge::RVNG_POINT;
@@ -416,7 +418,7 @@ struct Slide {
//! Internal: the state of a PowerPoint3Parser
struct State {
//! constructor
- State() : m_isMacFile(true), m_zoneListBegin(0), m_zonesList(),
+ State() : m_isMacFile(true), m_oleParser(), m_zoneListBegin(0), m_zonesList(),
m_slidesIdList(), m_idToSlideMap(), m_idToSlideContentMap(), m_idToSchemeMap(), m_pictIdToZoneIdMap(), m_idToPictureContentMap(),
m_origin(0,0), m_idToUserColorMap(), m_idToFontIdMap(), m_idToRulerMap(),
m_monoTypeFontId(-1), m_badEntry()
@@ -442,6 +444,8 @@ struct State {
static bool getCustomShape(int id, MWAWGraphicShape &shape);
//! flag to know if the file is a mac file or a pc file
bool m_isMacFile;
+ //! the ole parser
+ shared_ptr<PowerPoint3OLE> m_oleParser;
//! the begin position of the list of zones
long m_zoneListBegin;
//! the list of zone entries
@@ -650,11 +654,11 @@ class SubDocument : public MWAWSubDocument
{
public:
//! constructor for text
- SubDocument(PowerPoint3Parser &pars, MWAWInputStreamPtr input, SlideContent const *slide, int tId, bool mainZone) :
- MWAWSubDocument(&pars, input, MWAWEntry()), m_slide(slide), m_textId(tId), m_mainTextBox(mainZone) {}
+ SubDocument(PowerPoint3Parser &pars, MWAWInputStreamPtr input, SlideContent const *slide, int tId, bool mainZone, bool master) :
+ MWAWSubDocument(&pars, input, MWAWEntry()), m_slide(slide), m_textId(tId), m_mainTextBox(mainZone), m_isMaster(master) {}
//! constructor for note
SubDocument(PowerPoint3Parser &pars, MWAWInputStreamPtr input, SlideContent const *slide) :
- MWAWSubDocument(&pars, input, MWAWEntry()), m_slide(slide), m_textId(-1), m_mainTextBox(false) {}
+ MWAWSubDocument(&pars, input, MWAWEntry()), m_slide(slide), m_textId(-1), m_mainTextBox(false), m_isMaster(false) {}
//! destructor
virtual ~SubDocument() {}
@@ -668,6 +672,7 @@ public:
if (m_slide != sDoc->m_slide) return true;
if (m_textId != sDoc->m_textId) return true;
if (m_mainTextBox != sDoc->m_mainTextBox) return true;
+ if (m_isMaster != sDoc->m_isMaster) return true;
return false;
}
//! operator!==
@@ -686,6 +691,8 @@ protected:
int m_textId;
//! flag to know if we send the title or the body
bool m_mainTextBox;
+ //! flag to know if we send a master text zone
+ bool m_isMaster;
private:
SubDocument(SubDocument const &);
SubDocument &operator=(SubDocument const &);
@@ -708,7 +715,7 @@ void SubDocument::parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType)
}
long pos = m_input->tell();
- parser->sendText(*m_slide, m_textId, m_mainTextBox);
+ parser->sendText(*m_slide, m_textId, m_mainTextBox, m_isMaster);
m_input->seek(pos, librevenge::RVNG_SEEK_SET);
}
}
@@ -751,10 +758,6 @@ void PowerPoint3Parser::parse(librevenge::RVNGPresentationInterface *docInterfac
if (!getInput().get() || !checkHeader(0L)) throw(libmwaw::ParseException());
bool ok = true;
try {
- // create the asciiFile
- ascii().setStream(getInput());
- ascii().open(asciiName());
- checkHeader(0L);
ok = createZones();
if (ok) {
createDocument(docInterface);
@@ -763,6 +766,8 @@ void PowerPoint3Parser::parse(librevenge::RVNGPresentationInterface *docInterfac
#ifdef DEBUG
checkForUnparsedZones();
+ if (m_state->m_oleParser)
+ m_state->m_oleParser->checkForUnparsedStream();
#endif
ascii().reset();
}
@@ -807,6 +812,11 @@ void PowerPoint3Parser::createDocument(librevenge::RVNGPresentationInterface *do
//
MWAWPresentationListenerPtr listen(new MWAWPresentationListener(*getParserState(), pageList, documentInterface));
setPresentationListener(listen);
+ if (m_state->m_oleParser) {
+ librevenge::RVNGPropertyList metaData;
+ m_state->m_oleParser->updateMetaData(metaData);
+ listen->setDocumentMetaData(metaData);
+ }
listen->startDocument();
}
@@ -823,6 +833,31 @@ bool PowerPoint3Parser::createZones()
MWAW_DEBUG_MSG(("PowerPoint3Parser::createZones: can not find the main input\n"));
return false;
}
+ bool const isMacFile=m_state->m_isMacFile;
+
+ shared_ptr<PowerPoint3OLE> oleParser;
+ if (input->isStructured()) {
+ MWAWInputStreamPtr mainOle=input->getSubStreamByName("PP40");
+ if (!mainOle) {
+ MWAW_DEBUG_MSG(("PowerPoint3Parser::createZones: can not find the main ole\n"));
+ return false;
+ }
+ int fId=3;
+ if (!isMacFile) {
+ // create a temporary font, to use a CP1252 encoding
+ fId=99999;
+ getFontConverter()->setCorrespondance(fId, "ConvertOLEFont", "CP1252");
+ }
+ oleParser.reset(new PowerPoint3OLE(input, getFontConverter(), fId));
+ oleParser->parse();
+ getParserState()->m_input=input=mainOle;
+ input->setReadInverted(!isMacFile);
+ }
+ // create the asciiFile
+ ascii().setStream(input);
+ ascii().open(asciiName());
+ if (!checkHeader(0L)) return false;
+ m_state->m_oleParser=oleParser;
int docInfo;
if (!readListZones(docInfo)) return false;
size_t numZones=m_state->m_zonesList.size();
@@ -832,17 +867,21 @@ bool PowerPoint3Parser::createZones()
}
// first try to read the font name and scheme
libmwaw::DebugStream f;
- for (int w=0; w<2; ++w) {
- int id=w==0 ? 11 : 7;
+ for (int w=0; w<3; ++w) {
+ int id=w==0 ? 11 : w==1 ? 7 : 8;
MWAWEntry const &entry=m_state->getZoneEntry(m_state->m_zoneIds[id]);
if (!entry.valid()) continue;
- if (w==0 && !m_state->m_isMacFile) {
+ if (w==2) {
+ readColorZone(entry);
+ continue;
+ }
+ if (w==0 && !isMacFile) {
PowerPoint3ParserInternal::FontNameFieldParser parser(static_cast<int>(numZones));
readStructList(entry, parser);
for (std::map<int, std::string>::const_iterator it=parser.m_idToNameMap.begin(); it!=parser.m_idToNameMap.end(); ++it) {
m_state->m_idToFontIdMap[it->first]=it->first;
/* FIXME: by default, we force the family to be CP1252,
- but we may want to use the font data */
+ but we may want to use the file/font encoding */
getFontConverter()->setCorrespondance(it->first, it->second, it->second=="MonoType Sorts" || it->second=="Wingdings" ? "" : "CP1252");
}
for (size_t c=0; c<parser.m_childList.size(); ++c) {
@@ -899,9 +938,6 @@ bool PowerPoint3Parser::createZones()
}
break;
}
- case 8:
- readColorZone(entry);
- break;
case 9:
readZone9(entry);
break;
@@ -929,7 +965,7 @@ bool PowerPoint3Parser::createZones()
for (int i=0; i<2; ++i) {
MWAWEntry const &entry=m_state->getZoneEntry(m_state->m_printInfoIds[i]);
if (!entry.valid() || entry.isParsed()) continue;
- if (m_state->m_isMacFile && i==0)
+ if (isMacFile && i==0)
readPrintInfo(entry);
else {
entry.setParsed(true);
@@ -989,6 +1025,10 @@ bool PowerPoint3Parser::readListZones(int &docInfoId)
f << "*";
length&=0x7FFFFFFF;
}
+ if (length&0x40000000) {
+ f << "@";
+ length&=0xBFFFFFFF;
+ }
if (length==0) {
f << "_,";
continue;
@@ -1055,7 +1095,8 @@ void PowerPoint3Parser::checkForUnparsedZones()
bool PowerPoint3Parser::readDocInfo(MWAWEntry const &entry)
{
MWAWInputStreamPtr input=getInput();
- if (entry.length()!=142) {
+ int const vers=version();
+ if (entry.length()!=(vers<=3 ? 142 : 146)) {
MWAW_DEBUG_MSG(("PowerPoint3Parser::readDocInfo: the entry %d seems bad\n", entry.id()));
return false;
}
@@ -1076,15 +1117,15 @@ bool PowerPoint3Parser::readDocInfo(MWAWEntry const &entry)
f << "],";
for (int i=0; i<4; ++i) dim[i]=int(input->readLong(2));
if (!m_state->m_isMacFile) {
- std::swap<int>(dim[0],dim[1]);
- std::swap<int>(dim[2],dim[3]);
+ std::swap(dim[0],dim[1]);
+ std::swap(dim[2],dim[3]);
}
MWAWBox2i pageBox(MWAWVec2i(dim[1],dim[0]),MWAWVec2i(dim[3],dim[2]));
f << "dim[page]=" << pageBox << ",";
for (int i=0; i<4; ++i) dim[i]=int(input->readLong(2));
if (!m_state->m_isMacFile) {
- std::swap<int>(dim[0],dim[1]);
- std::swap<int>(dim[2],dim[3]);
+ std::swap(dim[0],dim[1]);
+ std::swap(dim[2],dim[3]);
}
MWAWBox2i paperBox=MWAWBox2i(MWAWVec2i(dim[0],dim[1]),MWAWVec2i(dim[2],dim[3]));
f << "dim[paper]=" << paperBox << ",";
@@ -1190,12 +1231,20 @@ bool PowerPoint3Parser::readDocInfo(MWAWEntry const &entry)
if (val!=expected[i])
f << "g" << i << "=" << val << ",";
}
- for (int i=0; i<2; ++i) { // two big number
- val=int(input->readULong(2));
- if (val) f << "fl" << i << "=" << std::hex << val << std::dec << ",";
+ if (vers<=3) {
+ for (int i=0; i<2; ++i) { // two big number
+ val=int(input->readULong(2));
+ if (val) f << "fl" << i << "=" << std::hex << val << std::dec << ",";
+ }
+ val=int(input->readLong(2)); // 3|4
+ if (val) f << "g3=" << val << ",";
+ }
+ else {
+ for (int i=0; i<5; ++i) { // three big number
+ val=int(input->readULong(2));
+ if (val) f << "fl" << i << "=" << std::hex << val << std::dec << ",";
+ }
}
- val=int(input->readLong(2)); // 3|4
- if (val) f << "g3=" << val << ",";
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
ascii().addPos(entry.end());
@@ -1249,7 +1298,7 @@ bool PowerPoint3Parser::readDocRoot(MWAWEntry const &entry)
int val;
for (int i=0; i<2; ++i) { // fl0=[359][4c], fl1=0|c
val=int(input->readULong(1));
- if (val) f << "fl" << i << std::hex << val << std::dec << ",";
+ if (val) f << "fl" << i << "=" << std::hex << val << std::dec << ",";
}
for (int i=0; i<2; ++i) { // big numbers, maybe a int32t
val=int(input->readLong(2));
@@ -1299,7 +1348,8 @@ bool PowerPoint3Parser::readDocRoot(MWAWEntry const &entry)
bool PowerPoint3Parser::readScheme(MWAWEntry const &entry, int id)
{
- if (!entry.valid() || entry.length()<94) {
+ int const vers=version();
+ if (!entry.valid() || entry.length()<(vers<=3 ? 94 : 118)) {
MWAW_DEBUG_MSG(("PowerPoint3Parser::readScheme: the zone seems bad\n"));
return false;
}
@@ -1311,11 +1361,19 @@ bool PowerPoint3Parser::readScheme(MWAWEntry const &entry, int id)
libmwaw::DebugStream f;
f << "Entries(Scheme)[Z"<< entry.id() << "]:S" << id << ",";
int val;
- for (int i=0; i<15; ++i) { // f0=-2|-6, f2=X, f3=X|0, f4,f5,f6:small number, f7=0|1|101, f8=0|1, f9=0|e1c,f10=0|3715,f11=0|80
+ val=int(input->readLong(2)); // -2|-6
+ if (val!=-2) f << "f0=" << val << ",";
+ if (vers>=4) {
+ for (int i=0; i<12; ++i) {
+ val=int(input->readLong(2));
+ if (val) f << "g" << i << "=" << val << ",";
+ }
+ }
+ for (int i=0; i<14; ++i) { // f2=X, f3=X|0, f4,f5,f6:small number, f7=0|1|101, f8=0|1, f9=0|e1c,f10=0|3715,f11=0|80
val=int(input->readLong(2));
- int const(expected[])= {-2,0,0,0,100,100,100, 0x101, 0, 0, 0, 0, 0, 7, 0};
+ int const(expected[])= {0,0,0,100,100,100, 0x101, 0, 0, 0, 0, 0, 7, 0};
if (val!=expected[i])
- f << "f" << i << "=" << val << ",";
+ f << "f" << i+1 << "=" << val << ",";
}
f << "colors=[";
for (int i=0; i<8; ++i) {
@@ -1412,7 +1470,8 @@ bool PowerPoint3Parser::readSlidesList(MWAWEntry const &entry)
bool PowerPoint3Parser::readSlide(MWAWEntry const &entry, PowerPoint3ParserInternal::Slide &slide, int zId)
{
- if (!entry.valid() || entry.length()!=32) {
+ int const vers=version();
+ if (!entry.valid() || entry.length()!=(vers<=3 ? 32 : 34)) {
MWAW_DEBUG_MSG(("PowerPoint3Parser::readSlide: the zone seems bad\n"));
return false;
}
@@ -1643,7 +1702,9 @@ bool PowerPoint3Parser::readSlideContent(MWAWEntry const &entry, PowerPoint3Pars
bool PowerPoint3Parser::readSlideFormats(MWAWEntry const &entry, std::vector<PowerPoint3ParserInternal::SlideFormat> &formatList)
{
- if (!entry.valid() || (entry.length()%20)!=0) {
+ int const vers=version();
+ int const dSz = vers<=3 ? 20 : 26;
+ if (!entry.valid() || (entry.length()%dSz)!=0) {
MWAW_DEBUG_MSG(("PowerPoint3Parser::readSlideFormats: the zone Z%d seems bad\n", entry.id()));
return false;
}
@@ -1656,7 +1717,7 @@ bool PowerPoint3Parser::readSlideFormats(MWAWEntry const &entry, std::vector<Pow
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
bool const isMacFile=m_state->m_isMacFile;
- size_t N=size_t(entry.length()/20);
+ size_t N=size_t(entry.length()/dSz);
formatList.resize(N);
for (size_t i=0; i<N; ++i) {
PowerPoint3ParserInternal::SlideFormat &format=formatList[i];
@@ -1673,19 +1734,23 @@ bool PowerPoint3Parser::readSlideFormats(MWAWEntry const &entry, std::vector<Pow
if (val) f << "id=" << std::hex << val << std::dec << ",";
int dim[2];
for (int j=0; j<2; ++j) dim[j]=int(input->readLong(2));
- if (!isMacFile) std::swap<int>(dim[0],dim[1]);
+ if (!isMacFile) std::swap(dim[0],dim[1]);
f << "dim0=" << MWAWVec2i(dim[1], dim[0]) << ",";
format.m_gradientOffset=int(input->readLong(2));
if (format.m_gradientOffset) f << "grad[col,offset]=" << format.m_gradientOffset << ",";
for (int j=0; j<2; ++j) dim[j]=int(input->readLong(2));
- if (!isMacFile) std::swap<int>(dim[0],dim[1]);
+ if (!isMacFile) std::swap(dim[0],dim[1]);
format.m_margins=MWAWVec2i(dim[1], dim[0]);
f << "box[margins]=" << format.m_margins << ",";
for (int j=0; j<2; ++j) dim[j]=int(input->readLong(2));
- if (!isMacFile) std::swap<int>(dim[0],dim[1]);
+ if (!isMacFile) std::swap(dim[0],dim[1]);
format.m_shadowOffset=MWAWVec2i(dim[1], dim[0]);
if (format.m_shadowOffset!=MWAWVec2i(0,0))
f << "shadow[offset]=" << format.m_shadowOffset << ",";
+ if (input->tell()!=pos+dSz) {
+ ascii().addDelimiter(input->tell(),'|');
+ input->seek(pos+dSz, librevenge::RVNG_SEEK_SET);
+ }
ascii().addPos(pos);
ascii().addNote(f.str().c_str());
}
@@ -1727,15 +1792,15 @@ bool PowerPoint3Parser::readSlidePolygons(MWAWEntry const &entry, std::vector<Po
int dim[4];
for (int i=0; i<4; ++i) dim[i]=int(input->readLong(2));
if (!isMacFile) {
- std::swap<int>(dim[0],dim[1]);
- std::swap<int>(dim[2],dim[3]);
+ std::swap(dim[0],dim[1]);
+ std::swap(dim[2],dim[3]);
}
poly.m_box=MWAWBox2i(MWAWVec2i(dim[1],dim[0]), MWAWVec2i(dim[3],dim[2]));
f << "box=" << poly.m_box << ",";
f << "pts=[";
for (int pt=0; pt<N; ++pt) {
for (int i=0; i<2; ++i) dim[i]=int(input->readLong(2));
- if (!isMacFile) std::swap<int>(dim[0],dim[1]);
+ if (!isMacFile) std::swap(dim[0],dim[1]);
poly.m_vertices.push_back(MWAWVec2f(float(dim[1])/8.f, float(dim[0])/8.f));
f << poly.m_vertices.back() << ",";
}
@@ -1759,6 +1824,7 @@ bool PowerPoint3Parser::readFramesList(MWAWEntry const &entry, PowerPoint3Parser
MWAW_DEBUG_MSG(("PowerPoint3Parser::readFramesList: the zone seems bad\n"));
return false;
}
+ int const vers=version();
MWAWInputStreamPtr input = getInput();
long pos = entry.begin();
entry.setParsed(true);
@@ -1782,9 +1848,66 @@ bool PowerPoint3Parser::readFramesList(MWAWEntry const &entry, PowerPoint3Parser
f << "Frames-" << i << ":";
PowerPoint3ParserInternal::Frame &frame=content.m_frameList[i];
MWAWGraphicStyle &style=frame.m_style;
- int type=int(input->readULong(1));
- if (!isMacFile) type=PowerPoint3ParserInternal::swapUInt8(type);
- frame.m_type=(type>>4);
+ if (vers<=3) {
+ int type=int(input->readULong(1));
+ if (!isMacFile) type=PowerPoint3ParserInternal::swapUInt8(type);
+ frame.m_type=(type>>4)&7;
+ showTypes[0]=type&0x7;
+ type&=0x88;
+ if (type) f << "fl0=" << std::hex << type << std::dec << ",";
+ int type2=int(input->readULong(1));
+ if (!isMacFile) type2=PowerPoint3ParserInternal::swapUInt8(type2);
+ showTypes[2]=type2&3;
+ showTypes[1]=(type2>>4)&3;
+ type2&=0xCC;
+ if (type2) f << "fl1=" << std::hex << type2 << std::dec << ",";
+ }
+ else {
+ int type=int(input->readULong(2));
+ int dashId=0;
+ if (isMacFile) {
+ frame.m_type=(type>>13)&7;
+ showTypes[0]=(type>>10)&0x7;
+ dashId=(type>>6)&7;
+ showTypes[2]=(type>>4)&3;
+ type &= 0x20F;
+ }
+ else {
+ frame.m_type=(type&7);
+ showTypes[0]=(type>>3)&0x7;
+ dashId=(type>>6)&7;
+ showTypes[2]=(type>>10)&3;
+ type&=0xF200;
+ }
+ showTypes[1]=1;
+ switch (dashId) {
+ case 0: // none
+ case 1: // normal
+ case 2: // unsure
+ showTypes[1]=dashId;
+ break;
+ case 3:
+ style.m_lineDashWidth.resize(2,1);
+ f << "dot,";
+ break;
+ case 4:
+ style.m_lineDashWidth.resize(2,2);
+ f << "dot[2x2],";
+ break;
+ case 5:
+ style.m_lineDashWidth.resize(2,4);
+ f << "dot[4x2],";
+ break;
+ case 6:
+ style.m_lineDashWidth.resize(4,2);
+ style.m_lineDashWidth[2]=1;
+ f << "dot[4,4,1,4],";
+ break;
+ default:
+ f << "##dashId=" << dashId << ",";
+ }
+ if (type) f << "fl0=" << std::hex << type << std::dec << ",";
+ }
switch (frame.m_type) {
case 0:
f << "line,";
@@ -1806,7 +1929,6 @@ bool PowerPoint3Parser::readFramesList(MWAWEntry const &entry, PowerPoint3Parser
f << "type=" << frame.m_type << ",";
break;
}
- showTypes[0]=type&0x7;
switch (showTypes[0]) {
case 0: // none
break;
@@ -1827,13 +1949,6 @@ bool PowerPoint3Parser::readFramesList(MWAWEntry const &entry, PowerPoint3Parser
f << "###surf[type]=" << showTypes[0] << ",";
break;
}
- if (type&0x8) f << "fl0=" << std::hex << (type&0x8) << std::dec << ",";
- int type2=int(input->readULong(1));
- if (!isMacFile) type2=PowerPoint3ParserInternal::swapUInt8(type2);
- showTypes[2]=type2&3;
- if (type2&1) f << "shadow,";
- if (type2&2) f << "emboss,";
- showTypes[1]=(type2>>4)&3;
switch (showTypes[1]) {
case 0:
f << "no[line],";
@@ -1848,7 +1963,8 @@ bool PowerPoint3Parser::readFramesList(MWAWEntry const &entry, PowerPoint3Parser
default:
break;
}
- if (type2&0xCC) f << "fl1=" << std::hex << (type2&0xCC) << std::dec << ",";
+ if (showTypes[2]&1) f << "shadow,";
+ if (showTypes[2]&2) f << "emboss,";
bool hasPicture=false;
int val=int(input->readULong(1));
if (!isMacFile) val=PowerPoint3ParserInternal::swapBool8(val);
@@ -1918,8 +2034,8 @@ bool PowerPoint3Parser::readFramesList(MWAWEntry const &entry, PowerPoint3Parser
int dim[4];
for (int d=0; d<4; ++d) dim[d]=int(input->readLong(2));
if (!isMacFile) {
- std::swap<int>(dim[0],dim[1]);
- std::swap<int>(dim[2],dim[3]);
+ std::swap(dim[0],dim[1]);
+ std::swap(dim[2],dim[3]);
}
frame.m_dimension=MWAWBox2i(MWAWVec2i(dim[1],dim[0]), MWAWVec2i(dim[3],dim[2]));
f << "dim=" << frame.m_dimension << ",";
@@ -2233,8 +2349,8 @@ bool PowerPoint3Parser::readTextZone(MWAWEntry const &entry, PowerPoint3ParserIn
int dim[4];
for (int i=0; i<4; ++i) dim[i]=int(input->readLong(2));
if (!isMacFile) {
- std::swap<int>(dim[0],dim[1]);
- std::swap<int>(dim[2],dim[3]);
+ std::swap(dim[0],dim[1]);
+ std::swap(dim[2],dim[3]);
}
tZone.m_box=MWAWBox2i(MWAWVec2i(dim[1],dim[0]),MWAWVec2i(dim[3],dim[2]));
f << "dim=" << tZone.m_box << ",";
@@ -2256,7 +2372,7 @@ bool PowerPoint3Parser::readTextZone(MWAWEntry const &entry, PowerPoint3ParserIn
val=int(input->readLong(2));
if (val) f << "f3=" << val << ",";
int sSz=int(input->readULong(4));
- if (sSz<0 || pos+58+sSz+8+10>endPos) {
+ if (sSz<0 || endPos-pos-58-8-10<sSz || pos+58+sSz+8+10>endPos) {
input->seek(pos, librevenge::RVNG_SEEK_SET);
break;
}
@@ -2370,8 +2486,8 @@ bool PowerPoint3Parser::readTextZone(MWAWEntry const &entry, PowerPoint3ParserIn
bool PowerPoint3Parser::readStructList(MWAWEntry const &entry, PowerPoint3ParserInternal::FieldParser &parser)
{
- bool const isMacFile=m_state->m_isMacFile;
- int const headerSize= isMacFile ? 18 : 16;
+ bool useInt16 = (!m_state->m_isMacFile && version()<=3);
+ int const headerSize= useInt16 ? 16 : 18;
if (!entry.valid() || entry.length()<headerSize) {
MWAW_DEBUG_MSG(("PowerPoint3Parser::readStructList: the zone seems bad\n"));
return false;
@@ -2385,7 +2501,7 @@ bool PowerPoint3Parser::readStructList(MWAWEntry const &entry, PowerPoint3Parser
int val=int(input->readULong(2));
if (val!=0x8001)
f << "f0=" << std::hex << val << std::dec << ",";
- f << "id=" << std::hex << input->readULong(isMacFile ? 4 : 2) << std::dec << ",";
+ f << "id=" << std::hex << input->readULong(useInt16 ? 2 : 4) << std::dec << ",";
int N=int(input->readULong(2));
f << "N=" << N << ",";
for (int i=0; i<2; ++i) {
@@ -2552,7 +2668,8 @@ bool PowerPoint3Parser::readPictureDefinition(MWAWEntry const &entry, int pId)
bool PowerPoint3Parser::readPictureContent(MWAWEntry const &entry, MWAWEmbeddedObject &pict)
{
bool isMacFile=m_state->m_isMacFile;
- if (!entry.valid() || entry.length()!=(isMacFile ? 50 : 48)) {
+ int const vers=version();
+ if (!entry.valid() || entry.length()!=(vers>=4 ? 60 : isMacFile ? 50 : 48)) {
MWAW_DEBUG_MSG(("PowerPoint3Parser::readPictureContent: the zone seems bad\n"));
return false;
}
@@ -2589,7 +2706,7 @@ bool PowerPoint3Parser::readPictureContent(MWAWEntry const &entry, MWAWEmbeddedO
val=int(input->readLong(2));
if (val) f << "f" << i+1 << "=" << val << ",";
}
- val=int(input->readULong(2));
+ val=int(input->readULong(vers>=4 ? 4 : 2));
if (val!=0x262a) f << "id=" << std::hex << val << std::dec << ",";
int dim[4];
for (int i=0; i<4; ++i) dim[i]=int(input->readLong(2));
@@ -2863,9 +2980,10 @@ bool PowerPoint3Parser::readParagraph(MWAWParagraph ¶, PowerPoint3ParserInte
}
break;
case 4:
- level=val;
+ level=val&0xFF;
ruler.updateParagraph(para, level);
if (level) f << "level=" << level << ",";
+ if (val&0xFF00) f << "level[high]=" << (val>>8) << ",";
break;
case 5:
switch (val) {
@@ -2977,8 +3095,7 @@ bool PowerPoint3Parser::readRuler(MWAWEntry const &entry, int pId)
MWAW_DEBUG_MSG(("PowerPoint3Parser::readRuler: paragraph %d already exists\n", pId));
}
if (input->tell()!=entry.end()) {
- MWAW_DEBUG_MSG(("PowerPoint3Parser::readRuler: find extra data\n"));
- f << "##extra,";
+ f << "#extra,";
ascii().addDelimiter(input->tell(),'|');
}
ascii().addPos(pos);
@@ -3260,7 +3377,7 @@ bool PowerPoint3Parser::readZone10(MWAWEntry const &entry)
////////////////////////////////////////////////////////////
// try to send data
////////////////////////////////////////////////////////////
-bool PowerPoint3Parser::sendText(PowerPoint3ParserInternal::SlideContent const &content, int tId, bool mainText)
+bool PowerPoint3Parser::sendText(PowerPoint3ParserInternal::SlideContent const &content, int tId, bool mainText, bool master)
{
MWAWListenerPtr listener=getPresentationListener();
if (!listener) {
@@ -3376,7 +3493,7 @@ bool PowerPoint3Parser::sendText(PowerPoint3ParserInternal::SlideContent const &
case ':': // time
case '#': { // page number
pos=input->tell();
- if (i+1<int(tEntry.length()) && char(input->readULong(1))==char(c)) {
+ if (master && i+1<int(tEntry.length()) && char(input->readULong(1))==char(c)) {
++i;
listener->insertField(MWAWField(c=='#' ? MWAWField::PageNumber : c=='/' ? MWAWField::Date : MWAWField::Time));
}
@@ -3459,12 +3576,12 @@ bool PowerPoint3Parser::sendSlide(PowerPoint3ParserInternal::SlideContent const
if (master && slide.m_frameList[f].m_mainTextBox) continue;
std::set<int> seen;
seen.insert(int(f));
- sendFrame(slide.m_frameList[f], slide, seen);
+ sendFrame(slide.m_frameList[f], slide, master, seen);
}
return true;
}
-bool PowerPoint3Parser::sendFrame(PowerPoint3ParserInternal::Frame const &frame, PowerPoint3ParserInternal::SlideContent const &content, std::set<int> &seen)
+bool PowerPoint3Parser::sendFrame(PowerPoint3ParserInternal::Frame const &frame, PowerPoint3ParserInternal::SlideContent const &content, bool master, std::set<int> &seen)
{
frame.m_isSent=true;
MWAWListenerPtr listener=getPresentationListener();
@@ -3478,7 +3595,7 @@ bool PowerPoint3Parser::sendFrame(PowerPoint3ParserInternal::Frame const &frame,
if (frame.m_textId>=0) {
MWAWPosition pos(fBox[0], fBox.size(), librevenge::RVNG_POINT);
pos.m_anchorTo = MWAWPosition::Page;
- MWAWSubDocumentPtr subdoc(new PowerPoint3ParserInternal::SubDocument(*this, getInput(), &content, frame.m_textId, frame.m_mainTextBox));
+ MWAWSubDocumentPtr subdoc(new PowerPoint3ParserInternal::SubDocument(*this, getInput(), &content, frame.m_textId, frame.m_mainTextBox, master));
listener->insertTextBox(pos, subdoc, frame.m_style);
return true;
}
@@ -3544,7 +3661,7 @@ bool PowerPoint3Parser::sendFrame(PowerPoint3ParserInternal::Frame const &frame,
case 3: {
float angle[2] = { frame.m_angles[0], frame.m_angles[0]+frame.m_angles[1] };
if (angle[1]<angle[0])
- std::swap<float>(angle[0],angle[1]);
+ std::swap(angle[0],angle[1]);
if (angle[1]>360) {
int numLoop=int(angle[1]/360)-1;
angle[0]-=float(numLoop*360);
@@ -3606,7 +3723,7 @@ bool PowerPoint3Parser::sendFrame(PowerPoint3ParserInternal::Frame const &frame,
continue;
}
seen.insert(i);
- sendFrame(content.m_frameList[size_t(i)], content, seen);
+ sendFrame(content.m_frameList[size_t(i)], content, master, seen);
seen.erase(i);
}
}
@@ -3635,7 +3752,11 @@ bool PowerPoint3Parser::checkHeader(MWAWHeader *header, bool strict)
MWAWInputStreamPtr input = getInput();
if (!input || !input->hasDataFork())
return false;
-
+ if (input->isStructured()) {
+ input=input->getSubStreamByName("PP40");
+ if (!input)
+ return false;
+ }
libmwaw::DebugStream f;
if (!input->checkPosition(24+8)) {
MWAW_DEBUG_MSG(("PowerPoint3Parser::checkHeader: file is too short\n"));
@@ -3653,7 +3774,7 @@ bool PowerPoint3Parser::checkHeader(MWAWHeader *header, bool strict)
return false;
f << "FileHeader:";
int vers=int(input->readLong(4));
- if (vers!=3) return false;
+ if (vers!=3 && vers!=4) return false;
m_state->m_zoneListBegin=long(input->readULong(4));
if (m_state->m_zoneListBegin<24 || !input->checkPosition(m_state->m_zoneListBegin))
return false;
diff --git a/src/lib/PowerPoint3Parser.hxx b/src/lib/PowerPoint3Parser.hxx
index 4cebdc2..799e108 100644
--- a/src/lib/PowerPoint3Parser.hxx
+++ b/src/lib/PowerPoint3Parser.hxx
@@ -58,7 +58,7 @@ struct TextZone;
class SubDocument;
}
-/** \brief the main class to read a Microsoft PowerPoint v3 files (MacOs and Windows)
+/** \brief the main class to read a Microsoft PowerPoint v3 or v4 files (MacOs and Windows)
*/
class PowerPoint3Parser : public MWAWPresentationParser
{
@@ -147,9 +147,9 @@ protected:
//! try to send a slide
bool sendSlide(PowerPoint3ParserInternal::SlideContent const &slide, bool master);
//! try to send a frame zone
- bool sendFrame(PowerPoint3ParserInternal::Frame const &frame, PowerPoint3ParserInternal::SlideContent const &content, std::set<int> &seen);
+ bool sendFrame(PowerPoint3ParserInternal::Frame const &frame, PowerPoint3ParserInternal::SlideContent const &content, bool master, std::set<int> &seen);
//! try to send a text zone
- bool sendText(PowerPoint3ParserInternal::SlideContent const &slide, int tId, bool placeHolder);
+ bool sendText(PowerPoint3ParserInternal::SlideContent const &slide, int tId, bool placeHolder, bool master);
//
// low level
diff --git a/src/lib/README b/src/lib/README
index 96b8d10..1978f30 100644
--- a/src/lib/README
+++ b/src/lib/README
@@ -268,8 +268,9 @@ NisusWrtParser : parser of a Nisus Writer document : v4.0
PixelPaintParser : parser of PixelPaint : v1-v2
-PowerPoint1Parser : parser of PowerPoint : mac v1-v2
-PowerPoint3Parser : parser of PowerPoint : mac v3 and windows v3
+PowerPoint1Parser : parser of PowerPoint : mac v1-v2 and windows v2
+PowerPoint3Parser : parser of PowerPoint : mac v3-v4 and windows v3-v4
+- PowerPoint3OLE : parser of the non essential OLE stream
RagTimeParser : parser of RagTime : v2-3
- RagTimeSpreadsheet: class which reads the spreadsheet's zones
diff --git a/src/lib/ZWrtParser.cxx b/src/lib/ZWrtParser.cxx
index 6c554bc..84db22c 100644
--- a/src/lib/ZWrtParser.cxx
+++ b/src/lib/ZWrtParser.cxx
@@ -884,7 +884,7 @@ bool ZWrtParser::checkHeader(MWAWHeader *header, bool strict)
MWAW_DEBUG_MSG(("ZWrtParser::checkHeader: can not find the RANG[128] resource\n"));
return false;
}
- if (getInput()->hasDataFork()) {
+ if (getInput()->hasDataFork() && getInput()->size()>0) {
MWAW_DEBUG_MSG(("ZWrtParser::checkHeader: find some data fork\n"));
if (strict)
return false;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-openoffice/libmwaw.git
More information about the Pkg-openoffice-commits
mailing list