[Libreoffice-commits] .: 4 commits - src/docdirstream.py src/docdraw.py src/docrecord.py src/docstream.py

Miklos Vajna vmiklos at kemper.freedesktop.org
Mon Dec 3 07:33:42 PST 2012


 src/docdirstream.py |    4 -
 src/docdraw.py      |  189 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/docrecord.py    |   32 ++++++++
 src/docstream.py    |    5 +
 4 files changed, 228 insertions(+), 2 deletions(-)

New commits:
commit 722ac4623a740aa3c2087c97e88eb4077990c36d
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Mon Dec 3 16:05:04 2012 +0100

    dump OfficeArtDgContainer

diff --git a/src/docdirstream.py b/src/docdirstream.py
index 507f5c2..df1ea54 100644
--- a/src/docdirstream.py
+++ b/src/docdirstream.py
@@ -20,8 +20,10 @@ class DOCDirStream:
         self.mainStream = mainStream
         self.doc = doc
     
-    def printAndSet(self, key, value, hexdump = True, end = True, offset = False):
+    def printAndSet(self, key, value, hexdump = True, end = True, offset = False, silent = False):
         setattr(self, key, value)
+        if silent:
+            return
         if hexdump:
             value = hex(value)
         offstr = ""
diff --git a/src/docdraw.py b/src/docdraw.py
index 11d75e6..707aae6 100644
--- a/src/docdraw.py
+++ b/src/docdraw.py
@@ -13,23 +13,33 @@ import docsprm
 class OfficeArtRecordHeader(DOCDirStream):
     """The OfficeArtRecordHeader record specifies the common record header for all the OfficeArt records."""
     size = 8
-    def __init__(self, parent, name):
+    def __init__(self, parent, name = None, pos = None):
         DOCDirStream.__init__(self, parent.bytes)
         self.name = name
-        self.pos = parent.pos
+        if pos:
+            self.pos = pos
+        else:
+            self.pos = parent.pos
+        self.posOrig = self.pos
         self.parent = parent
 
-    def dump(self):
-        print '<%s type="OfficeArtRecordHeader" offset="%d" size="%d bytes">' % (self.name, self.pos, OfficeArtRecordHeader.size)
+    def dump(self, parseOnly = False):
+        if not parseOnly:
+            print '<%s type="OfficeArtRecordHeader" offset="%d" size="%d bytes">' % (self.name, self.pos, OfficeArtRecordHeader.size)
         buf = self.readuInt16()
-        self.printAndSet("recVer", buf & 0x000f) # 1..4th bits
-        self.printAndSet("recInstance", (buf & 0xfff0) >> 4) # 5..16th bits
+        self.printAndSet("recVer", buf & 0x000f, silent = parseOnly) # 1..4th bits
+        self.printAndSet("recInstance", (buf & 0xfff0) >> 4, silent = parseOnly) # 5..16th bits
 
-        self.printAndSet("recType", self.readuInt16())
-        self.printAndSet("recLen", self.readuInt32())
-        print '</%s>' % self.name
-        assert self.pos == self.parent.pos + OfficeArtRecordHeader.size
-        self.parent.pos = self.pos
+        self.printAndSet("recType", self.readuInt16(), silent = parseOnly)
+        self.printAndSet("recLen", self.readuInt32(), silent = parseOnly)
+        if not parseOnly:
+            print '</%s>' % self.name
+        assert self.pos == self.posOrig + OfficeArtRecordHeader.size
+        if not parseOnly:
+            self.parent.pos = self.pos
+
+    def parse(self):
+        self.dump(True)
 
 class OfficeArtFDGG(DOCDirStream):
     """The OfficeArtFDGG record specifies documnet-wide information about all of the drawings that have been saved in the file."""
@@ -66,14 +76,12 @@ class OfficeArtIDCL(DOCDirStream):
 
 class OfficeArtFDGGBlock(DOCDirStream):
     """The OfficeArtFDGGBlock record specifies document-wide information about all of the drawings that have been saved in the file."""
-    def __init__(self, officeArtDggContainer, name):
+    def __init__(self, officeArtDggContainer, pos):
         DOCDirStream.__init__(self, officeArtDggContainer.bytes)
-        self.name = name
-        self.pos = officeArtDggContainer.pos
-        self.officeArtDggContainer = officeArtDggContainer
+        self.pos = pos
 
     def dump(self):
-        print '<%s type="OfficeArtFDGGBlock" offset="%d">' % (self.name, self.pos)
+        print '<drawingGroup type="OfficeArtFDGGBlock" offset="%d">' % self.pos
         OfficeArtRecordHeader(self, "rh").dump()
         self.head = OfficeArtFDGG(self, "head")
         self.head.dump()
@@ -81,8 +89,7 @@ class OfficeArtFDGGBlock(DOCDirStream):
             print '<Rgidcl index="%d">' % i
             OfficeArtIDCL(self).dump()
             print '</Rgidcl>'
-        print '</%s>' % self.name
-        self.officeArtDggContainer.pos = self.pos
+        print '</drawingGroup>'
 
 class MSOCR(DOCDirStream):
     """The MSOCR record specifies either the RGB color or the scheme color index."""
@@ -106,23 +113,18 @@ class MSOCR(DOCDirStream):
 
 class OfficeArtSplitMenuColorContainer(DOCDirStream):
     """The OfficeArtSplitMenuColorContainer record specifies a container for the colors that were most recently used to format shapes."""
-    def __init__(self, officeArtDggContainer, name):
+    def __init__(self, officeArtDggContainer, pos):
         DOCDirStream.__init__(self, officeArtDggContainer.bytes)
-        self.name = name
-        self.pos = officeArtDggContainer.pos
-        self.officeArtDggContainer = officeArtDggContainer
+        self.pos = pos
 
     def dump(self):
-        print '<%s type="OfficeArtSplitMenuColorContainer" offset="%d">' % (self.name, self.pos)
+        print '<splitColors type="OfficeArtSplitMenuColorContainer" offset="%d">' % self.pos
         OfficeArtRecordHeader(self, "rh").dump()
-        self.head = OfficeArtFDGG(self, "head")
-        self.head.dump()
         for i in ["fill", "line", "shadow", "3d"]:
             print '<smca type="%s">' % i
             MSOCR(self).dump()
             print '</smca>'
-        print '</%s>' % self.name
-        self.officeArtDggContainer.pos = self.pos
+        print '</splitColors>'
 
 class OfficeArtDggContainer(DOCDirStream):
     """The OfficeArtDggContainer record type specifies the container for all the OfficeArt file records that contain document-wide data."""
@@ -132,24 +134,56 @@ class OfficeArtDggContainer(DOCDirStream):
         self.pos = officeArtContent.pos
         self.officeArtContent = officeArtContent
 
-    def getNextType(self):
-        return self.getuInt16(pos = self.pos + 2)
-
     def dump(self):
         print '<%s type="OfficeArtDggContainer" offset="%d">' % (self.name, self.pos)
-        OfficeArtRecordHeader(self, "rh").dump()
-        if self.getNextType() == 0xf006:
-            OfficeArtFDGGBlock(self, "drawingGroup").dump()
-        if self.getNextType() == 0xf001:
-            print '<todo what="OfficeArtDggContainer: unhandled OfficeArtBStoreContainer"/>'
-        if self.getNextType() == 0xf00b:
-            print '<todo what="OfficeArtDggContainer: unhandled OfficeArtFOPT"/>'
-        if self.getNextType() == 0xf122:
-            print '<todo what="OfficeArtDggContainer: unhandled OfficeArtTertiaryFOPT"/>'
-        if self.getNextType() == 0xf11a:
-            print '<todo what="OfficeArtDggContainer: unhandled OfficeArtColorMRUContainer"/>'
-        if self.getNextType() == 0xf11e:
-            OfficeArtSplitMenuColorContainer(self, "splitColors").dump()
+        self.rh = OfficeArtRecordHeader(self, "rh")
+        self.rh.dump()
+        pos = self.pos
+        recMap = {
+                0xf006: OfficeArtFDGGBlock,
+                0xf11e: OfficeArtSplitMenuColorContainer,
+                }
+        while (self.rh.recLen - (pos - self.pos)) > 0:
+            rh = OfficeArtRecordHeader(self, pos = pos)
+            rh.parse()
+            if rh.recType in recMap:
+                child = recMap[rh.recType](self, pos)
+                child.dump()
+                assert child.pos == pos + OfficeArtRecordHeader.size + rh.recLen
+            else:
+                print '<todo what="OfficeArtDggContainer: recType = %s unhandled (size: %d bytes)"/>' % (hex(rh.recType), rh.recLen)
+            pos += OfficeArtRecordHeader.size + rh.recLen
+        print '</%s>' % self.name
+        assert pos == self.pos + self.rh.recLen
+        self.officeArtContent.pos = pos
+
+class OfficeArtDgContainer(DOCDirStream):
+    """The OfficeArtDgContainer record specifies the container for all the file records for the objects in a drawing."""
+    def __init__(self, officeArtContent, name):
+        DOCDirStream.__init__(self, officeArtContent.bytes)
+        self.name = name
+        self.pos = officeArtContent.pos
+        self.officeArtContent = officeArtContent
+
+    def dump(self):
+        print '<%s type="OfficeArtDgContainer" offset="%d">' % (self.name, self.pos)
+        self.rh = OfficeArtRecordHeader(self, "rh")
+        self.rh.dump()
+        pos = self.pos
+        recMap = {
+                }
+        while (self.rh.recLen - (pos - self.pos)) > 0:
+            rh = OfficeArtRecordHeader(self, pos = pos)
+            rh.parse()
+            if rh.recType in recMap:
+                child = recMap[rh.recType](self, pos)
+                child.dump()
+                assert child.pos == pos + OfficeArtRecordHeader.size + rh.recLen
+            else:
+                print '<todo what="OfficeArtDgContainer: recType = %s unhandled (size: %d bytes)"/>' % (hex(rh.recType), rh.recLen)
+            pos += OfficeArtRecordHeader.size + rh.recLen
         print '</%s>' % self.name
+        assert pos == self.pos + self.rh.recLen
+        self.officeArtContent.pos = pos
 
 # vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab:
diff --git a/src/docrecord.py b/src/docrecord.py
index 380ec66..ff54747 100644
--- a/src/docrecord.py
+++ b/src/docrecord.py
@@ -1565,6 +1565,20 @@ class SttbfRMark(DOCDirStream):
         assert self.pos == self.mainStream.fcSttbfRMark + self.size
         print '</sttbfRMark>'
 
+class OfficeArtWordDrawing(DOCDirStream):
+    """The OfficeArtWordDrawing structure specifies information about the drawings in the document."""
+    def __init__(self, officeArtContent):
+        DOCDirStream.__init__(self, officeArtContent.bytes)
+        self.pos = officeArtContent.pos
+        self.officeArtContent = officeArtContent
+
+    def dump(self):
+        print '<officeArtWordDrawing type="OfficeArtWordDrawing" pos="%d">' % self.pos
+        self.printAndSet("dgglbl", self.readuInt8())
+        docdraw.OfficeArtDgContainer(self, "container").dump()
+        print '</officeArtWordDrawing>'
+        self.officeArtContent.pos = self.pos
+
 class OfficeArtContent(DOCDirStream):
     """The OfficeArtContent structure specifies information about a drawing in the document."""
     def __init__(self, mainStream):
@@ -1576,8 +1590,10 @@ class OfficeArtContent(DOCDirStream):
     def dump(self):
         print '<officeArtContent type="OfficeArtContent" offset="%d" size="%d bytes">' % (self.pos, self.size)
         docdraw.OfficeArtDggContainer(self, "DrawingGroupData").dump()
-        # TODO Drawings
-        # assert self.pos == self.mainStream.fcDggInfo + self.size
+        print '<Drawings type="main" offset="%d">' % self.pos
+        OfficeArtWordDrawing(self).dump()
+        print '</Drawings>'
+        assert self.pos == self.mainStream.fcDggInfo + self.size
         print '</officeArtContent>'
 
 class ATNBE(DOCDirStream):
commit 63c8e0ec7e648f249121b6525bef3ea598828be6
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Mon Dec 3 13:13:01 2012 +0100

    dump OfficeArtSplitMenuColorContainer

diff --git a/src/docdraw.py b/src/docdraw.py
index fbb97f4..11d75e6 100644
--- a/src/docdraw.py
+++ b/src/docdraw.py
@@ -23,7 +23,7 @@ class OfficeArtRecordHeader(DOCDirStream):
         print '<%s type="OfficeArtRecordHeader" offset="%d" size="%d bytes">' % (self.name, self.pos, OfficeArtRecordHeader.size)
         buf = self.readuInt16()
         self.printAndSet("recVer", buf & 0x000f) # 1..4th bits
-        self.printAndSet("recInstance", buf & 0xfff0) # 5..16th bits
+        self.printAndSet("recInstance", (buf & 0xfff0) >> 4) # 5..16th bits
 
         self.printAndSet("recType", self.readuInt16())
         self.printAndSet("recLen", self.readuInt32())
@@ -84,6 +84,46 @@ class OfficeArtFDGGBlock(DOCDirStream):
         print '</%s>' % self.name
         self.officeArtDggContainer.pos = self.pos
 
+class MSOCR(DOCDirStream):
+    """The MSOCR record specifies either the RGB color or the scheme color index."""
+    size = 4
+    def __init__(self, parent):
+        DOCDirStream.__init__(self, parent.bytes)
+        self.pos = parent.pos
+        self.parent = parent
+
+    def dump(self):
+        print '<msocr type="MSOCR" offset="%d" size="%d">' % (self.pos, MSOCR.size)
+        buf = self.readuInt32()
+        self.printAndSet("red",           buf & 0x000000ff) # 1..8th bits
+        self.printAndSet("green",        (buf & 0x0000ff00) >> 8) # 9..16th bits
+        self.printAndSet("blue",         (buf & 0x00ff0000) >> 16) # 17..24th bits
+        self.printAndSet("unused1",      (buf & 0x07000000) >> 24) # 25..27th bits
+        self.printAndSet("fSchemeIndex", (buf & 0x08000000) >> 27) # 28th bits
+        self.printAndSet("unused2",      (buf & 0xf0000000) >> 28) # 29..32th bits
+        print '</msocr>'
+        self.parent.pos = self.pos
+
+class OfficeArtSplitMenuColorContainer(DOCDirStream):
+    """The OfficeArtSplitMenuColorContainer record specifies a container for the colors that were most recently used to format shapes."""
+    def __init__(self, officeArtDggContainer, name):
+        DOCDirStream.__init__(self, officeArtDggContainer.bytes)
+        self.name = name
+        self.pos = officeArtDggContainer.pos
+        self.officeArtDggContainer = officeArtDggContainer
+
+    def dump(self):
+        print '<%s type="OfficeArtSplitMenuColorContainer" offset="%d">' % (self.name, self.pos)
+        OfficeArtRecordHeader(self, "rh").dump()
+        self.head = OfficeArtFDGG(self, "head")
+        self.head.dump()
+        for i in ["fill", "line", "shadow", "3d"]:
+            print '<smca type="%s">' % i
+            MSOCR(self).dump()
+            print '</smca>'
+        print '</%s>' % self.name
+        self.officeArtDggContainer.pos = self.pos
+
 class OfficeArtDggContainer(DOCDirStream):
     """The OfficeArtDggContainer record type specifies the container for all the OfficeArt file records that contain document-wide data."""
     def __init__(self, officeArtContent, name):
@@ -92,10 +132,24 @@ class OfficeArtDggContainer(DOCDirStream):
         self.pos = officeArtContent.pos
         self.officeArtContent = officeArtContent
 
+    def getNextType(self):
+        return self.getuInt16(pos = self.pos + 2)
+
     def dump(self):
         print '<%s type="OfficeArtDggContainer" offset="%d">' % (self.name, self.pos)
         OfficeArtRecordHeader(self, "rh").dump()
-        OfficeArtFDGGBlock(self, "drawingGroup").dump()
+        if self.getNextType() == 0xf006:
+            OfficeArtFDGGBlock(self, "drawingGroup").dump()
+        if self.getNextType() == 0xf001:
+            print '<todo what="OfficeArtDggContainer: unhandled OfficeArtBStoreContainer"/>'
+        if self.getNextType() == 0xf00b:
+            print '<todo what="OfficeArtDggContainer: unhandled OfficeArtFOPT"/>'
+        if self.getNextType() == 0xf122:
+            print '<todo what="OfficeArtDggContainer: unhandled OfficeArtTertiaryFOPT"/>'
+        if self.getNextType() == 0xf11a:
+            print '<todo what="OfficeArtDggContainer: unhandled OfficeArtColorMRUContainer"/>'
+        if self.getNextType() == 0xf11e:
+            OfficeArtSplitMenuColorContainer(self, "splitColors").dump()
         print '</%s>' % self.name
 
 # vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab:
commit 00f8fed7102ae41512b14ed00a8601f2d6b5e3eb
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Mon Dec 3 12:48:50 2012 +0100

    dump OfficeArtFDGGBlock and OfficeArtFDGG

diff --git a/src/docdraw.py b/src/docdraw.py
index 0f862c9..fbb97f4 100644
--- a/src/docdraw.py
+++ b/src/docdraw.py
@@ -13,11 +13,11 @@ import docsprm
 class OfficeArtRecordHeader(DOCDirStream):
     """The OfficeArtRecordHeader record specifies the common record header for all the OfficeArt records."""
     size = 8
-    def __init__(self, officeArtDggContainer, name):
-        DOCDirStream.__init__(self, officeArtDggContainer.bytes)
+    def __init__(self, parent, name):
+        DOCDirStream.__init__(self, parent.bytes)
         self.name = name
-        self.pos = officeArtDggContainer.pos
-        self.officeArtDggContainer = officeArtDggContainer
+        self.pos = parent.pos
+        self.parent = parent
 
     def dump(self):
         print '<%s type="OfficeArtRecordHeader" offset="%d" size="%d bytes">' % (self.name, self.pos, OfficeArtRecordHeader.size)
@@ -27,8 +27,62 @@ class OfficeArtRecordHeader(DOCDirStream):
 
         self.printAndSet("recType", self.readuInt16())
         self.printAndSet("recLen", self.readuInt32())
-        assert self.pos == self.officeArtDggContainer.pos + OfficeArtRecordHeader.size
         print '</%s>' % self.name
+        assert self.pos == self.parent.pos + OfficeArtRecordHeader.size
+        self.parent.pos = self.pos
+
+class OfficeArtFDGG(DOCDirStream):
+    """The OfficeArtFDGG record specifies documnet-wide information about all of the drawings that have been saved in the file."""
+    size = 16
+    def __init__(self, officeArtFDGGBlock, name):
+        DOCDirStream.__init__(self, officeArtFDGGBlock.bytes)
+        self.name = name
+        self.pos = officeArtFDGGBlock.pos
+        self.officeArtFDGGBlock = officeArtFDGGBlock
+
+    def dump(self):
+        print '<%s type="OfficeArtFDGG" offset="%d" size="%d bytes">' % (self.name, self.pos, OfficeArtFDGG.size)
+        self.printAndSet("spidMax", self.readuInt32()) # TODO dump MSOSPID
+        self.printAndSet("cidcl", self.readuInt32())
+        self.printAndSet("cspSaved", self.readuInt32())
+        self.printAndSet("cdgSaved", self.readuInt32())
+        print '</%s>' % self.name
+        assert self.pos == self.officeArtFDGGBlock.pos + OfficeArtFDGG.size
+        self.officeArtFDGGBlock.pos = self.pos
+
+class OfficeArtIDCL(DOCDirStream):
+    """The OfficeArtIDCL record specifies a file identifier cluster, which is used to group shape identifiers within a drawing."""
+    def __init__(self, officeArtFDGGBlock):
+        DOCDirStream.__init__(self, officeArtFDGGBlock.bytes)
+        self.pos = officeArtFDGGBlock.pos
+        self.officeArtFDGGBlock = officeArtFDGGBlock
+
+    def dump(self):
+        print '<officeArtIDCL type="OfficeArtIDCL" pos="%d">' % self.pos
+        self.printAndSet("dgid", self.readuInt32()) # TODO dump MSODGID
+        self.printAndSet("cspidCur", self.readuInt32())
+        print '</officeArtIDCL>'
+        self.officeArtFDGGBlock.pos = self.pos
+
+class OfficeArtFDGGBlock(DOCDirStream):
+    """The OfficeArtFDGGBlock record specifies document-wide information about all of the drawings that have been saved in the file."""
+    def __init__(self, officeArtDggContainer, name):
+        DOCDirStream.__init__(self, officeArtDggContainer.bytes)
+        self.name = name
+        self.pos = officeArtDggContainer.pos
+        self.officeArtDggContainer = officeArtDggContainer
+
+    def dump(self):
+        print '<%s type="OfficeArtFDGGBlock" offset="%d">' % (self.name, self.pos)
+        OfficeArtRecordHeader(self, "rh").dump()
+        self.head = OfficeArtFDGG(self, "head")
+        self.head.dump()
+        for i in range(self.head.cidcl - 1):
+            print '<Rgidcl index="%d">' % i
+            OfficeArtIDCL(self).dump()
+            print '</Rgidcl>'
+        print '</%s>' % self.name
+        self.officeArtDggContainer.pos = self.pos
 
 class OfficeArtDggContainer(DOCDirStream):
     """The OfficeArtDggContainer record type specifies the container for all the OfficeArt file records that contain document-wide data."""
@@ -41,7 +95,7 @@ class OfficeArtDggContainer(DOCDirStream):
     def dump(self):
         print '<%s type="OfficeArtDggContainer" offset="%d">' % (self.name, self.pos)
         OfficeArtRecordHeader(self, "rh").dump()
-        # TODO OfficeArtFDGGBlock(self, "drawingGroup").dump()
+        OfficeArtFDGGBlock(self, "drawingGroup").dump()
         print '</%s>' % self.name
 
 # vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab:
commit d9de155a96662324dcbf1f45cd120c6abc27de83
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Mon Dec 3 11:50:00 2012 +0100

    dump OfficeArtRecordHeader

diff --git a/src/docdraw.py b/src/docdraw.py
new file mode 100644
index 0000000..0f862c9
--- /dev/null
+++ b/src/docdraw.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+import struct
+import globals
+from docdirstream import DOCDirStream
+import docsprm
+
+class OfficeArtRecordHeader(DOCDirStream):
+    """The OfficeArtRecordHeader record specifies the common record header for all the OfficeArt records."""
+    size = 8
+    def __init__(self, officeArtDggContainer, name):
+        DOCDirStream.__init__(self, officeArtDggContainer.bytes)
+        self.name = name
+        self.pos = officeArtDggContainer.pos
+        self.officeArtDggContainer = officeArtDggContainer
+
+    def dump(self):
+        print '<%s type="OfficeArtRecordHeader" offset="%d" size="%d bytes">' % (self.name, self.pos, OfficeArtRecordHeader.size)
+        buf = self.readuInt16()
+        self.printAndSet("recVer", buf & 0x000f) # 1..4th bits
+        self.printAndSet("recInstance", buf & 0xfff0) # 5..16th bits
+
+        self.printAndSet("recType", self.readuInt16())
+        self.printAndSet("recLen", self.readuInt32())
+        assert self.pos == self.officeArtDggContainer.pos + OfficeArtRecordHeader.size
+        print '</%s>' % self.name
+
+class OfficeArtDggContainer(DOCDirStream):
+    """The OfficeArtDggContainer record type specifies the container for all the OfficeArt file records that contain document-wide data."""
+    def __init__(self, officeArtContent, name):
+        DOCDirStream.__init__(self, officeArtContent.bytes)
+        self.name = name
+        self.pos = officeArtContent.pos
+        self.officeArtContent = officeArtContent
+
+    def dump(self):
+        print '<%s type="OfficeArtDggContainer" offset="%d">' % (self.name, self.pos)
+        OfficeArtRecordHeader(self, "rh").dump()
+        # TODO OfficeArtFDGGBlock(self, "drawingGroup").dump()
+        print '</%s>' % self.name
+
+# vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab:
diff --git a/src/docrecord.py b/src/docrecord.py
index 5e2b87a..380ec66 100644
--- a/src/docrecord.py
+++ b/src/docrecord.py
@@ -9,6 +9,7 @@ import struct
 import globals
 from docdirstream import DOCDirStream
 import docsprm
+import docdraw
 
 class FcCompressed(DOCDirStream):
     """The FcCompressed structure specifies the location of text in the WordDocument Stream."""
@@ -1564,6 +1565,21 @@ class SttbfRMark(DOCDirStream):
         assert self.pos == self.mainStream.fcSttbfRMark + self.size
         print '</sttbfRMark>'
 
+class OfficeArtContent(DOCDirStream):
+    """The OfficeArtContent structure specifies information about a drawing in the document."""
+    def __init__(self, mainStream):
+        DOCDirStream.__init__(self, mainStream.doc.getDirectoryStreamByName("1Table").bytes)
+        self.pos = mainStream.fcDggInfo
+        self.size = mainStream.lcbDggInfo
+        self.mainStream = mainStream
+
+    def dump(self):
+        print '<officeArtContent type="OfficeArtContent" offset="%d" size="%d bytes">' % (self.pos, self.size)
+        docdraw.OfficeArtDggContainer(self, "DrawingGroupData").dump()
+        # TODO Drawings
+        # assert self.pos == self.mainStream.fcDggInfo + self.size
+        print '</officeArtContent>'
+
 class ATNBE(DOCDirStream):
     """The ATNBE structure contains information about an annotation bookmark in the document."""
     size = 10 # in bytes, see 2.9.4
diff --git a/src/docstream.py b/src/docstream.py
index 0a99009..47f8431 100644
--- a/src/docstream.py
+++ b/src/docstream.py
@@ -304,7 +304,7 @@ class WordDocumentStream(DOCDirStream):
             ["fcUnused4"],
             ["lcbUnused4"],
             ["fcDggInfo"],
-            ["lcbDggInfo"],
+            ["lcbDggInfo", self.handleLcbDggInfo],
             ["fcSttbfRMark"],
             ["lcbSttbfRMark", self.handleLcbSttbfRMark],
             ["fcSttbfCaption"],
@@ -489,6 +489,9 @@ class WordDocumentStream(DOCDirStream):
     def handleLcbSttbfRMark(self):
         docrecord.SttbfRMark(self).dump()
 
+    def handleLcbDggInfo(self):
+        docrecord.OfficeArtContent(self).dump()
+
     def dumpFibRgFcLcb97(self, name):
         print '<%s type="FibRgFcLcb97" size="744 bytes">' % name
         self.__dumpFibRgFcLcb97()


More information about the Libreoffice-commits mailing list