/**
         * Writes out the MsoDrawing records and Obj records for each image
         * and chart on the sheet
         *
         * @param outputFile the output file
         * @exception IOException
         */
        public void write(File outputFile)
        {
            // If there are no drawings or charts on this sheet then exit
            if (drawings.Count == 0 && charts.Length == 0)
                return;

            // See if any drawing has been modified
            bool modified = drawingsModified;
            int numImages = drawings.Count;

            foreach (DrawingGroupObject d in drawings)
                {
                if (d.getOrigin() != Origin.READ)
                    modified = true;
                }

            // If the drawing order has been muddled at all, then we'll need
            // to regenerate the Escher drawing data
            if (numImages > 0 && !modified)
                {
                DrawingGroupObject d2 = (DrawingGroupObject)drawings[0];
                if (!d2.isFirst())
                    modified = true;
                }

            // Check to see if this sheet consists of just a single chart.  If so
            // there is no MsoDrawingRecord, so write out the data and exit
            if (numImages == 0 &&
                charts.Length == 1 &&
                charts[0].getMsoDrawingRecord() == null)
                modified = false; // this sheet has not been modified

            // If no drawing has been modified, then simply write them straight out
            // again and exit
            if (!modified)
                {
                writeUnmodified(outputFile);
                return;
                }

            object[] spContainerData = new object[numImages + charts.Length];
            int length = 0;
            EscherContainer firstSpContainer = null;

            // Get all the spContainer byte data from the drawings
            // and store in an array
            for (int i = 0; i < numImages; i++)
                {
                DrawingGroupObject drawing = (DrawingGroupObject)drawings[i];

                EscherContainer spc = drawing.getSpContainer();

                if (spc != null)
                    {
                    byte[] data = spc.getData();
                    spContainerData[i] = data;

                    if (i == 0)
                        {
                        firstSpContainer = spc;
                        }
                    else
                        {
                        length += data.Length;
                        }
                    }
                }

            // Get all the spContainer bytes from the charts and add to the array
            for (int i = 0; i < charts.Length; i++)
                {
                EscherContainer spContainer = charts[i].getSpContainer();
                byte[] data = spContainer.getBytes(); //use getBytes instead of getData
                data = spContainer.setHeaderData(data);
                spContainerData[i + numImages] = data;

                if (i == 0 && numImages == 0)
                    firstSpContainer = spContainer;
                else
                    length += data.Length;
                }

            // Put the generalised stuff around the first item
            DgContainer dgContainer = new DgContainer();
            Dg dg = new Dg(numImages + charts.Length);
            dgContainer.add(dg);

            SpgrContainer spgrContainer = new SpgrContainer();

            SpContainer _spContainer = new SpContainer();
            Spgr spgr = new Spgr();
            _spContainer.add(spgr);
            Sp sp = new Sp(ShapeType.MIN,1024,5);
            _spContainer.add(sp);
            spgrContainer.add(_spContainer);

            spgrContainer.add(firstSpContainer);

            dgContainer.add(spgrContainer);

            byte[] firstMsoData = dgContainer.getData();

            // Adjust the length of the DgContainer
            int len = IntegerHelper.getInt(firstMsoData[4],
                                           firstMsoData[5],
                                           firstMsoData[6],
                                           firstMsoData[7]);
            IntegerHelper.getFourBytes(len + length,firstMsoData,4);

            // Adjust the length of the SpgrContainer
            len = IntegerHelper.getInt(firstMsoData[28],
                                       firstMsoData[29],
                                       firstMsoData[30],
                                       firstMsoData[31]);
            IntegerHelper.getFourBytes(len + length,firstMsoData,28);

            // Now write out each MsoDrawing record

            // First MsoRecord
            // test hack for form objects, to remove the ClientTextBox record
            // from the end of the SpContainer
            if (numImages > 0 &&
                ((DrawingGroupObject)drawings[0]).isFormObject())
                {
                byte[] msodata2 = new byte[firstMsoData.Length - 8];
                System.Array.Copy(firstMsoData,0,msodata2,0,msodata2.Length);
                firstMsoData = msodata2;
                }

            MsoDrawingRecord msoDrawingRecord = new MsoDrawingRecord(firstMsoData);
            outputFile.write(msoDrawingRecord);

            if (numImages > 0)
                {
                DrawingGroupObject firstDrawing = (DrawingGroupObject)drawings[0];
                firstDrawing.writeAdditionalRecords(outputFile);
                }
            else
                {
                // first image is a chart
                Chart chart = charts[0];
                ObjRecord objRecord = chart.getObjRecord();
                outputFile.write(objRecord);
                outputFile.write(chart);
                }

            // Now do all the others
            for (int i = 1; i < spContainerData.Length; i++)
                {
                byte[] bytes = (byte[])spContainerData[i];

                // test hack for form objects, to remove the ClientTextBox record
                // from the end of the SpContainer
                if (i < numImages &&
                    ((DrawingGroupObject)drawings[i]).isFormObject())
                    {
                    byte[] bytes2 = new byte[bytes.Length - 8];
                    System.Array.Copy(bytes,0,bytes2,0,bytes2.Length);
                    bytes = bytes2;
                    }

                msoDrawingRecord = new MsoDrawingRecord(bytes);
                outputFile.write(msoDrawingRecord);

                if (i < numImages)
                    {
                    // Write anything else the object needs
                    DrawingGroupObject d = (DrawingGroupObject)drawings[i];
                    d.writeAdditionalRecords(outputFile);
                    }
                else
                    {
                    Chart chart = charts[i - numImages];
                    ObjRecord objRecord = chart.getObjRecord();
                    outputFile.write(objRecord);
                    outputFile.write(chart);
                    }
                }

            // Write any tail records that need to be written
            foreach (DrawingGroupObject dgo2 in drawings)
                dgo2.writeTailRecords(outputFile);
        }
        /**
         * Writes out the drawings and the charts if nothing has been modified
         *
         * @param outputFile the output file
         * @exception IOException
         */
        private void writeUnmodified(File outputFile)
        {
            if (charts.Length == 0 && drawings.Count == 0)
                {
                // No drawings or charts
                return;
                }
            else if (charts.Length == 0 && drawings.Count != 0)
                {
                // If there are no charts, then write out the drawings and return
                foreach (DrawingGroupObject d in drawings)
                    {
                    outputFile.write(d.getMsoDrawingRecord());
                    d.writeAdditionalRecords(outputFile);
                    }

                foreach (DrawingGroupObject d in drawings)
                    d.writeTailRecords(outputFile);
                return;
                }
            else if (drawings.Count == 0 && charts.Length != 0)
                {
                // If there are no drawings, then write out the charts and return
                Chart curChart = null;
                for (int i = 0; i < charts.Length; i++)
                    {
                    curChart = charts[i];
                    if (curChart.getMsoDrawingRecord() != null)
                        outputFile.write(curChart.getMsoDrawingRecord());

                    if (curChart.getObjRecord() != null)
                        outputFile.write(curChart.getObjRecord());

                    outputFile.write(curChart);
                    }

                return;
                }

            // There are both charts and drawings - the output
            // drawing group records will need
            // to be re-jigged in order to write the drawings out first, then the
            // charts
            int numDrawings = drawings.Count;
            int length = 0;
            EscherContainer[] spContainers = new EscherContainer[numDrawings + charts.Length];
            bool[] isFormobject = new bool[numDrawings + charts.Length];

            for (int i = 0; i < numDrawings; i++)
                {
                DrawingGroupObject d = (DrawingGroupObject)drawings[i];
                spContainers[i] = d.getSpContainer();

                if (i > 0)
                    length += spContainers[i].getLength();

                if (d.isFormObject())
                    isFormobject[i] = true;
                }

            for (int i = 0; i < charts.Length; i++)
                {
                spContainers[i + numDrawings] = charts[i].getSpContainer();
                length += spContainers[i + numDrawings].getLength();
                }

            // Put the generalised stuff around the first item
            DgContainer dgContainer = new DgContainer();
            Dg dg = new Dg(numDrawings + charts.Length);
            dgContainer.add(dg);

            SpgrContainer spgrContainer = new SpgrContainer();

            SpContainer spContainer = new SpContainer();
            Spgr spgr = new Spgr();
            spContainer.add(spgr);
            Sp sp = new Sp(ShapeType.MIN,1024,5);
            spContainer.add(sp);
            spgrContainer.add(spContainer);

            spgrContainer.add(spContainers[0]);

            dgContainer.add(spgrContainer);

            byte[] firstMsoData = dgContainer.getData();

            // Adjust the length of the DgContainer
            int len = IntegerHelper.getInt(firstMsoData[4],
                                           firstMsoData[5],
                                           firstMsoData[6],
                                           firstMsoData[7]);
            IntegerHelper.getFourBytes(len + length,firstMsoData,4);

            // Adjust the length of the SpgrContainer
            len = IntegerHelper.getInt(firstMsoData[28],
                                       firstMsoData[29],
                                       firstMsoData[30],
                                       firstMsoData[31]);
            IntegerHelper.getFourBytes(len + length,firstMsoData,28);

            // Now write out each MsoDrawing record and object record

            // Hack to remove the last eight bytes (text box escher record)
            // from the container
            if (isFormobject[0] == true)
                {
                byte[] cbytes = new byte[firstMsoData.Length - 8];
                System.Array.Copy(firstMsoData,0,cbytes,0,cbytes.Length);
                firstMsoData = cbytes;
                }

            // First MsoRecord
            MsoDrawingRecord msoDrawingRecord = new MsoDrawingRecord(firstMsoData);
            outputFile.write(msoDrawingRecord);

            DrawingGroupObject dgo = (DrawingGroupObject)drawings[0];
            dgo.writeAdditionalRecords(outputFile);

            // Now do all the others
            for (int i = 1; i < spContainers.Length; i++)
                {
                byte[] bytes = spContainers[i].getBytes();
                byte[] bytes2 = spContainers[i].setHeaderData(bytes);

                // Hack to remove the last eight bytes (text box escher record)
                // from the container
                if (isFormobject[i] == true)
                    {
                    byte[] cbytes = new byte[bytes2.Length - 8];
                    System.Array.Copy(bytes2,0,cbytes,0,cbytes.Length);
                    bytes2 = cbytes;
                    }

                msoDrawingRecord = new MsoDrawingRecord(bytes2);
                outputFile.write(msoDrawingRecord);

                if (i < numDrawings)
                    {
                    dgo = (DrawingGroupObject)drawings[i];
                    dgo.writeAdditionalRecords(outputFile);
                    }
                else
                    {
                    Chart chart = charts[i - numDrawings];
                    ObjRecord objRecord = chart.getObjRecord();
                    outputFile.write(objRecord);
                    outputFile.write(chart);
                    }
                }

            // Write any tail records that need to be written
            foreach (DrawingGroupObject dgo2 in drawings)
                dgo2.writeTailRecords(outputFile);
        }
Пример #3
0
        /**
         * Displays an escher record
         *
         * @param er the record to display
         * @param level the amount of indentation
         * @exception IOException
         */
        private void displayRecord(EscherRecord er, int level)
        {
            indent(level);

            EscherRecordType type = er.getType();

            // Display the code
            writer.Write(System.String.Format("{0:X}", type.getValue()));
            writer.Write(" - ");

            // Display the name
            if (type == EscherRecordType.DGG_CONTAINER)
            {
                writer.WriteLine("Dgg Container");
            }
            else if (type == EscherRecordType.BSTORE_CONTAINER)
            {
                writer.WriteLine("BStore Container");
            }
            else if (type == EscherRecordType.DG_CONTAINER)
            {
                writer.WriteLine("Dg Container");
            }
            else if (type == EscherRecordType.SPGR_CONTAINER)
            {
                writer.WriteLine("Spgr Container");
            }
            else if (type == EscherRecordType.SP_CONTAINER)
            {
                writer.WriteLine("Sp Container");
            }
            else if (type == EscherRecordType.DGG)
            {
                writer.WriteLine("Dgg");
            }
            else if (type == EscherRecordType.BSE)
            {
                writer.WriteLine("Bse");
            }
            else if (type == EscherRecordType.DG)
            {
                Dg dg = new Dg(er.getEscherData());
                writer.WriteLine("Dg:  drawing id " + dg.getDrawingId() + " shape count " + dg.getShapeCount());
            }
            else if (type == EscherRecordType.SPGR)
            {
                writer.WriteLine("Spgr");
            }
            else if (type == EscherRecordType.SP)
            {
                Sp sp = new Sp(er.getEscherData());
                writer.WriteLine("Sp:  shape id " + sp.getShapeId() + " shape type " + sp.getShapeType());
            }
            else if (type == EscherRecordType.OPT)
            {
                Opt          opt  = new Opt(er.getEscherData());
                Opt.Property p260 = opt.getProperty(260);
                Opt.Property p261 = opt.getProperty(261);
                writer.Write("Opt (value, StringValue): ");
                if (p260 != null)
                {
                    writer.Write("260: " +
                                 p260.value + ", " +
                                 p260.StringValue +
                                 ";");
                }
                if (p261 != null)
                {
                    writer.Write("261: " +
                                 p261.value + ", " +
                                 p261.StringValue +
                                 ";");
                }
                writer.WriteLine(string.Empty);
            }
            else if (type == EscherRecordType.CLIENT_ANCHOR)
            {
                writer.WriteLine("Client Anchor");
            }
            else if (type == EscherRecordType.CLIENT_DATA)
            {
                writer.WriteLine("Client Data");
            }
            else if (type == EscherRecordType.CLIENT_TEXT_BOX)
            {
                writer.WriteLine("Client Text Box");
            }
            else if (type == EscherRecordType.SPLIT_MENU_COLORS)
            {
                writer.WriteLine("Split Menu Colors");
            }
            else
            {
                writer.WriteLine("???");
            }
        }
        /**
         * Initialization
         */
        private void initialize()
        {
            int curpos = getPos() + HEADER_LENGTH;
            int endpos = System.Math.Min(getPos() + getLength(),getStreamLength());

            EscherRecord newRecord = null;

            while (curpos < endpos)
                {
                EscherRecordData erd = new EscherRecordData(getEscherStream(),curpos);

                EscherRecordType type = erd.getType();
                if (type == EscherRecordType.DGG)
                    newRecord = new Dgg(erd);
                else if (type == EscherRecordType.DG)
                    newRecord = new Dg(erd);
                else if (type == EscherRecordType.BSTORE_CONTAINER)
                    newRecord = new BStoreContainer(erd);
                else if (type == EscherRecordType.SPGR_CONTAINER)
                    newRecord = new SpgrContainer(erd);
                else if (type == EscherRecordType.SP_CONTAINER)
                    newRecord = new SpContainer(erd);
                else if (type == EscherRecordType.SPGR)
                    newRecord = new Spgr(erd);
                else if (type == EscherRecordType.SP)
                    newRecord = new Sp(erd);
                else if (type == EscherRecordType.CLIENT_ANCHOR)
                    newRecord = new ClientAnchor(erd);
                else if (type == EscherRecordType.CLIENT_DATA)
                    newRecord = new ClientData(erd);
                else if (type == EscherRecordType.BSE)
                    newRecord = new BlipStoreEntry(erd);
                else if (type == EscherRecordType.OPT)
                    newRecord = new Opt(erd);
                else if (type == EscherRecordType.SPLIT_MENU_COLORS)
                    newRecord = new SplitMenuColors(erd);
                else if (type == EscherRecordType.CLIENT_TEXT_BOX)
                    newRecord = new ClientTextBox(erd);
                else
                    newRecord = new EscherAtom(erd);

                children.Add(newRecord);
                curpos += newRecord.getLength();
                }

            initialized = true;
        }
Пример #5
0
        /**
         * Initialization
         */
        private void initialize()
        {
            int curpos = getPos() + HEADER_LENGTH;
            int endpos = System.Math.Min(getPos() + getLength(), getStreamLength());

            EscherRecord newRecord = null;

            while (curpos < endpos)
            {
                EscherRecordData erd = new EscherRecordData(getEscherStream(), curpos);

                EscherRecordType type = erd.getType();
                if (type == EscherRecordType.DGG)
                {
                    newRecord = new Dgg(erd);
                }
                else if (type == EscherRecordType.DG)
                {
                    newRecord = new Dg(erd);
                }
                else if (type == EscherRecordType.BSTORE_CONTAINER)
                {
                    newRecord = new BStoreContainer(erd);
                }
                else if (type == EscherRecordType.SPGR_CONTAINER)
                {
                    newRecord = new SpgrContainer(erd);
                }
                else if (type == EscherRecordType.SP_CONTAINER)
                {
                    newRecord = new SpContainer(erd);
                }
                else if (type == EscherRecordType.SPGR)
                {
                    newRecord = new Spgr(erd);
                }
                else if (type == EscherRecordType.SP)
                {
                    newRecord = new Sp(erd);
                }
                else if (type == EscherRecordType.CLIENT_ANCHOR)
                {
                    newRecord = new ClientAnchor(erd);
                }
                else if (type == EscherRecordType.CLIENT_DATA)
                {
                    newRecord = new ClientData(erd);
                }
                else if (type == EscherRecordType.BSE)
                {
                    newRecord = new BlipStoreEntry(erd);
                }
                else if (type == EscherRecordType.OPT)
                {
                    newRecord = new Opt(erd);
                }
                else if (type == EscherRecordType.SPLIT_MENU_COLORS)
                {
                    newRecord = new SplitMenuColors(erd);
                }
                else if (type == EscherRecordType.CLIENT_TEXT_BOX)
                {
                    newRecord = new ClientTextBox(erd);
                }
                else
                {
                    newRecord = new EscherAtom(erd);
                }

                children.Add(newRecord);
                curpos += newRecord.getLength();
            }

            initialized = true;
        }
Пример #6
0
        /**
         * Writes out the MsoDrawing records and Obj records for each image
         * and chart on the sheet
         *
         * @param outputFile the output file
         * @exception IOException
         */
        public void write(File outputFile)
        {
            // If there are no drawings or charts on this sheet then exit
            if (drawings.Count == 0 && charts.Length == 0)
            {
                return;
            }

            // See if any drawing has been modified
            bool modified  = drawingsModified;
            int  numImages = drawings.Count;

            foreach (DrawingGroupObject d in drawings)
            {
                if (d.getOrigin() != Origin.READ)
                {
                    modified = true;
                }
            }

            // If the drawing order has been muddled at all, then we'll need
            // to regenerate the Escher drawing data
            if (numImages > 0 && !modified)
            {
                DrawingGroupObject d2 = (DrawingGroupObject)drawings[0];
                if (!d2.isFirst())
                {
                    modified = true;
                }
            }

            // Check to see if this sheet consists of just a single chart.  If so
            // there is no MsoDrawingRecord, so write out the data and exit
            if (numImages == 0 &&
                charts.Length == 1 &&
                charts[0].getMsoDrawingRecord() == null)
            {
                modified = false;                 // this sheet has not been modified
            }
            // If no drawing has been modified, then simply write them straight out
            // again and exit
            if (!modified)
            {
                writeUnmodified(outputFile);
                return;
            }

            object[]        spContainerData  = new object[numImages + charts.Length];
            int             length           = 0;
            EscherContainer firstSpContainer = null;

            // Get all the spContainer byte data from the drawings
            // and store in an array
            for (int i = 0; i < numImages; i++)
            {
                DrawingGroupObject drawing = (DrawingGroupObject)drawings[i];

                EscherContainer spc = drawing.getSpContainer();

                if (spc != null)
                {
                    byte[] data = spc.getData();
                    spContainerData[i] = data;

                    if (i == 0)
                    {
                        firstSpContainer = spc;
                    }
                    else
                    {
                        length += data.Length;
                    }
                }
            }

            // Get all the spContainer bytes from the charts and add to the array
            for (int i = 0; i < charts.Length; i++)
            {
                EscherContainer spContainer = charts[i].getSpContainer();
                byte[]          data        = spContainer.getBytes(); //use getBytes instead of getData
                data = spContainer.setHeaderData(data);
                spContainerData[i + numImages] = data;

                if (i == 0 && numImages == 0)
                {
                    firstSpContainer = spContainer;
                }
                else
                {
                    length += data.Length;
                }
            }

            // Put the generalised stuff around the first item
            DgContainer dgContainer = new DgContainer();
            Dg          dg          = new Dg(numImages + charts.Length);

            dgContainer.add(dg);

            SpgrContainer spgrContainer = new SpgrContainer();

            SpContainer _spContainer = new SpContainer();
            Spgr        spgr         = new Spgr();

            _spContainer.add(spgr);
            Sp sp = new Sp(ShapeType.MIN, 1024, 5);

            _spContainer.add(sp);
            spgrContainer.add(_spContainer);

            spgrContainer.add(firstSpContainer);

            dgContainer.add(spgrContainer);

            byte[] firstMsoData = dgContainer.getData();

            // Adjust the length of the DgContainer
            int len = IntegerHelper.getInt(firstMsoData[4],
                                           firstMsoData[5],
                                           firstMsoData[6],
                                           firstMsoData[7]);

            IntegerHelper.getFourBytes(len + length, firstMsoData, 4);

            // Adjust the length of the SpgrContainer
            len = IntegerHelper.getInt(firstMsoData[28],
                                       firstMsoData[29],
                                       firstMsoData[30],
                                       firstMsoData[31]);
            IntegerHelper.getFourBytes(len + length, firstMsoData, 28);

            // Now write out each MsoDrawing record

            // First MsoRecord
            // test hack for form objects, to remove the ClientTextBox record
            // from the end of the SpContainer
            if (numImages > 0 &&
                ((DrawingGroupObject)drawings[0]).isFormObject())
            {
                byte[] msodata2 = new byte[firstMsoData.Length - 8];
                System.Array.Copy(firstMsoData, 0, msodata2, 0, msodata2.Length);
                firstMsoData = msodata2;
            }

            MsoDrawingRecord msoDrawingRecord = new MsoDrawingRecord(firstMsoData);

            outputFile.write(msoDrawingRecord);

            if (numImages > 0)
            {
                DrawingGroupObject firstDrawing = (DrawingGroupObject)drawings[0];
                firstDrawing.writeAdditionalRecords(outputFile);
            }
            else
            {
                // first image is a chart
                Chart     chart     = charts[0];
                ObjRecord objRecord = chart.getObjRecord();
                outputFile.write(objRecord);
                outputFile.write(chart);
            }

            // Now do all the others
            for (int i = 1; i < spContainerData.Length; i++)
            {
                byte[] bytes = (byte[])spContainerData[i];

                // test hack for form objects, to remove the ClientTextBox record
                // from the end of the SpContainer
                if (i < numImages &&
                    ((DrawingGroupObject)drawings[i]).isFormObject())
                {
                    byte[] bytes2 = new byte[bytes.Length - 8];
                    System.Array.Copy(bytes, 0, bytes2, 0, bytes2.Length);
                    bytes = bytes2;
                }

                msoDrawingRecord = new MsoDrawingRecord(bytes);
                outputFile.write(msoDrawingRecord);

                if (i < numImages)
                {
                    // Write anything else the object needs
                    DrawingGroupObject d = (DrawingGroupObject)drawings[i];
                    d.writeAdditionalRecords(outputFile);
                }
                else
                {
                    Chart     chart     = charts[i - numImages];
                    ObjRecord objRecord = chart.getObjRecord();
                    outputFile.write(objRecord);
                    outputFile.write(chart);
                }
            }

            // Write any tail records that need to be written
            foreach (DrawingGroupObject dgo2 in drawings)
            {
                dgo2.writeTailRecords(outputFile);
            }
        }
Пример #7
0
        /**
         * Writes out the drawings and the charts if nothing has been modified
         *
         * @param outputFile the output file
         * @exception IOException
         */
        private void writeUnmodified(File outputFile)
        {
            if (charts.Length == 0 && drawings.Count == 0)
            {
                // No drawings or charts
                return;
            }
            else if (charts.Length == 0 && drawings.Count != 0)
            {
                // If there are no charts, then write out the drawings and return
                foreach (DrawingGroupObject d in drawings)
                {
                    outputFile.write(d.getMsoDrawingRecord());
                    d.writeAdditionalRecords(outputFile);
                }

                foreach (DrawingGroupObject d in drawings)
                {
                    d.writeTailRecords(outputFile);
                }
                return;
            }
            else if (drawings.Count == 0 && charts.Length != 0)
            {
                // If there are no drawings, then write out the charts and return
                Chart curChart = null;
                for (int i = 0; i < charts.Length; i++)
                {
                    curChart = charts[i];
                    if (curChart.getMsoDrawingRecord() != null)
                    {
                        outputFile.write(curChart.getMsoDrawingRecord());
                    }

                    if (curChart.getObjRecord() != null)
                    {
                        outputFile.write(curChart.getObjRecord());
                    }

                    outputFile.write(curChart);
                }

                return;
            }

            // There are both charts and drawings - the output
            // drawing group records will need
            // to be re-jigged in order to write the drawings out first, then the
            // charts
            int numDrawings = drawings.Count;
            int length      = 0;

            EscherContainer[] spContainers = new EscherContainer[numDrawings + charts.Length];
            bool[]            isFormobject = new bool[numDrawings + charts.Length];

            for (int i = 0; i < numDrawings; i++)
            {
                DrawingGroupObject d = (DrawingGroupObject)drawings[i];
                spContainers[i] = d.getSpContainer();

                if (i > 0)
                {
                    length += spContainers[i].getLength();
                }

                if (d.isFormObject())
                {
                    isFormobject[i] = true;
                }
            }

            for (int i = 0; i < charts.Length; i++)
            {
                spContainers[i + numDrawings] = charts[i].getSpContainer();
                length += spContainers[i + numDrawings].getLength();
            }

            // Put the generalised stuff around the first item
            DgContainer dgContainer = new DgContainer();
            Dg          dg          = new Dg(numDrawings + charts.Length);

            dgContainer.add(dg);

            SpgrContainer spgrContainer = new SpgrContainer();

            SpContainer spContainer = new SpContainer();
            Spgr        spgr        = new Spgr();

            spContainer.add(spgr);
            Sp sp = new Sp(ShapeType.MIN, 1024, 5);

            spContainer.add(sp);
            spgrContainer.add(spContainer);

            spgrContainer.add(spContainers[0]);

            dgContainer.add(spgrContainer);

            byte[] firstMsoData = dgContainer.getData();

            // Adjust the length of the DgContainer
            int len = IntegerHelper.getInt(firstMsoData[4],
                                           firstMsoData[5],
                                           firstMsoData[6],
                                           firstMsoData[7]);

            IntegerHelper.getFourBytes(len + length, firstMsoData, 4);

            // Adjust the length of the SpgrContainer
            len = IntegerHelper.getInt(firstMsoData[28],
                                       firstMsoData[29],
                                       firstMsoData[30],
                                       firstMsoData[31]);
            IntegerHelper.getFourBytes(len + length, firstMsoData, 28);

            // Now write out each MsoDrawing record and object record

            // Hack to remove the last eight bytes (text box escher record)
            // from the container
            if (isFormobject[0] == true)
            {
                byte[] cbytes = new byte[firstMsoData.Length - 8];
                System.Array.Copy(firstMsoData, 0, cbytes, 0, cbytes.Length);
                firstMsoData = cbytes;
            }

            // First MsoRecord
            MsoDrawingRecord msoDrawingRecord = new MsoDrawingRecord(firstMsoData);

            outputFile.write(msoDrawingRecord);

            DrawingGroupObject dgo = (DrawingGroupObject)drawings[0];

            dgo.writeAdditionalRecords(outputFile);

            // Now do all the others
            for (int i = 1; i < spContainers.Length; i++)
            {
                byte[] bytes  = spContainers[i].getBytes();
                byte[] bytes2 = spContainers[i].setHeaderData(bytes);

                // Hack to remove the last eight bytes (text box escher record)
                // from the container
                if (isFormobject[i] == true)
                {
                    byte[] cbytes = new byte[bytes2.Length - 8];
                    System.Array.Copy(bytes2, 0, cbytes, 0, cbytes.Length);
                    bytes2 = cbytes;
                }

                msoDrawingRecord = new MsoDrawingRecord(bytes2);
                outputFile.write(msoDrawingRecord);

                if (i < numDrawings)
                {
                    dgo = (DrawingGroupObject)drawings[i];
                    dgo.writeAdditionalRecords(outputFile);
                }
                else
                {
                    Chart     chart     = charts[i - numDrawings];
                    ObjRecord objRecord = chart.getObjRecord();
                    outputFile.write(objRecord);
                    outputFile.write(chart);
                }
            }

            // Write any tail records that need to be written
            foreach (DrawingGroupObject dgo2 in drawings)
            {
                dgo2.writeTailRecords(outputFile);
            }
        }