| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523 | <?php/** * PHPExcel * * Copyright (c) 2006 - 2015 PHPExcel * * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA * * @category   PHPExcel * @package    PHPExcel_Writer_Excel5 * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL * @version    ##VERSION##, ##DATE## *//** * PHPExcel_Shared_Escher_DggContainer_BstoreContainer * * @category   PHPExcel * @package    PHPExcel_Writer_Excel5 * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */class PHPExcel_Writer_Excel5_Escher{    /**     * The object we are writing     */    private $object;    /**     * The written binary data     */    private $data;    /**     * Shape offsets. Positions in binary stream where a new shape record begins     *     * @var array     */    private $spOffsets;    /**     * Shape types.     *     * @var array     */    private $spTypes;        /**     * Constructor     *     * @param mixed     */    public function __construct($object)    {        $this->object = $object;    }    /**     * Process the object to be written     */    public function close()    {        // initialize        $this->data = '';        switch (get_class($this->object)) {            case 'PHPExcel_Shared_Escher':                if ($dggContainer = $this->object->getDggContainer()) {                    $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer);                    $this->data = $writer->close();                } elseif ($dgContainer = $this->object->getDgContainer()) {                    $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer);                    $this->data = $writer->close();                    $this->spOffsets = $writer->getSpOffsets();                    $this->spTypes = $writer->getSpTypes();                }                break;            case 'PHPExcel_Shared_Escher_DggContainer':                // this is a container record                // initialize                $innerData = '';                // write the dgg                $recVer            = 0x0;                $recInstance    = 0x0000;                $recType        = 0xF006;                $recVerInstance  = $recVer;                $recVerInstance |= $recInstance << 4;                // dgg data                $dggData =                    pack(                        'VVVV',                        $this->object->getSpIdMax(), // maximum shape identifier increased by one                        $this->object->getCDgSaved() + 1, // number of file identifier clusters increased by one                        $this->object->getCSpSaved(),                        $this->object->getCDgSaved() // count total number of drawings saved                    );                // add file identifier clusters (one per drawing)                $IDCLs = $this->object->getIDCLs();                foreach ($IDCLs as $dgId => $maxReducedSpId) {                    $dggData .= pack('VV', $dgId, $maxReducedSpId + 1);                }                $header = pack('vvV', $recVerInstance, $recType, strlen($dggData));                $innerData .= $header . $dggData;                // write the bstoreContainer                if ($bstoreContainer = $this->object->getBstoreContainer()) {                    $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer);                    $innerData .= $writer->close();                }                // write the record                $recVer            = 0xF;                $recInstance    = 0x0000;                $recType        = 0xF000;                $length            = strlen($innerData);                $recVerInstance  = $recVer;                $recVerInstance |= $recInstance << 4;                $header = pack('vvV', $recVerInstance, $recType, $length);                $this->data = $header . $innerData;                break;            case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer':                // this is a container record                // initialize                $innerData = '';                // treat the inner data                if ($BSECollection = $this->object->getBSECollection()) {                    foreach ($BSECollection as $BSE) {                        $writer = new PHPExcel_Writer_Excel5_Escher($BSE);                        $innerData .= $writer->close();                    }                }                // write the record                $recVer            = 0xF;                $recInstance    = count($this->object->getBSECollection());                $recType        = 0xF001;                $length            = strlen($innerData);                $recVerInstance  = $recVer;                $recVerInstance |= $recInstance << 4;                $header = pack('vvV', $recVerInstance, $recType, $length);                $this->data = $header . $innerData;                break;            case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE':                // this is a semi-container record                // initialize                $innerData = '';                // here we treat the inner data                if ($blip = $this->object->getBlip()) {                    $writer = new PHPExcel_Writer_Excel5_Escher($blip);                    $innerData .= $writer->close();                }                // initialize                $data = '';                $btWin32 = $this->object->getBlipType();                $btMacOS = $this->object->getBlipType();                $data .= pack('CC', $btWin32, $btMacOS);                $rgbUid = pack('VVVV', 0, 0, 0, 0); // todo                $data .= $rgbUid;                $tag = 0;                $size = strlen($innerData);                $cRef = 1;                $foDelay = 0; //todo                $unused1 = 0x0;                $cbName = 0x0;                $unused2 = 0x0;                $unused3 = 0x0;                $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3);                $data .= $innerData;                // write the record                $recVer            = 0x2;                $recInstance    = $this->object->getBlipType();                $recType        = 0xF007;                $length            = strlen($data);                $recVerInstance  = $recVer;                $recVerInstance |=    $recInstance << 4;                $header = pack('vvV', $recVerInstance, $recType, $length);                $this->data = $header;                $this->data .= $data;                break;            case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip':                // this is an atom record                // write the record                switch ($this->object->getParent()->getBlipType()) {                    case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG:                        // initialize                        $innerData = '';                        $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo                        $innerData .= $rgbUid1;                        $tag = 0xFF; // todo                        $innerData .= pack('C', $tag);                        $innerData .= $this->object->getData();                        $recVer            = 0x0;                        $recInstance    = 0x46A;                        $recType        = 0xF01D;                        $length            = strlen($innerData);                        $recVerInstance  = $recVer;                        $recVerInstance |=    $recInstance << 4;                        $header = pack('vvV', $recVerInstance, $recType, $length);                        $this->data = $header;                        $this->data .= $innerData;                        break;                    case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG:                        // initialize                        $innerData = '';                        $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo                        $innerData .= $rgbUid1;                        $tag = 0xFF; // todo                        $innerData .= pack('C', $tag);                        $innerData .= $this->object->getData();                        $recVer            = 0x0;                        $recInstance    = 0x6E0;                        $recType        = 0xF01E;                        $length            = strlen($innerData);                        $recVerInstance  = $recVer;                        $recVerInstance |=    $recInstance << 4;                        $header = pack('vvV', $recVerInstance, $recType, $length);                        $this->data = $header;                        $this->data .= $innerData;                        break;                }                break;            case 'PHPExcel_Shared_Escher_DgContainer':                // this is a container record                // initialize                $innerData = '';                // write the dg                $recVer            = 0x0;                $recInstance    = $this->object->getDgId();                $recType        = 0xF008;                $length            = 8;                $recVerInstance  = $recVer;                $recVerInstance |= $recInstance << 4;                $header = pack('vvV', $recVerInstance, $recType, $length);                // number of shapes in this drawing (including group shape)                $countShapes = count($this->object->getSpgrContainer()->getChildren());                $innerData .= $header . pack('VV', $countShapes, $this->object->getLastSpId());                //$innerData .= $header . pack('VV', 0, 0);                // write the spgrContainer                if ($spgrContainer = $this->object->getSpgrContainer()) {                    $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer);                    $innerData .= $writer->close();                    // get the shape offsets relative to the spgrContainer record                    $spOffsets = $writer->getSpOffsets();                    $spTypes   = $writer->getSpTypes();                                        // save the shape offsets relative to dgContainer                    foreach ($spOffsets as & $spOffset) {                        $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes)                    }                    $this->spOffsets = $spOffsets;                    $this->spTypes = $spTypes;                }                // write the record                $recVer            = 0xF;                $recInstance    = 0x0000;                $recType        = 0xF002;                $length            = strlen($innerData);                $recVerInstance  = $recVer;                $recVerInstance |= $recInstance << 4;                $header = pack('vvV', $recVerInstance, $recType, $length);                $this->data = $header . $innerData;                break;            case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer':                // this is a container record                // initialize                $innerData = '';                // initialize spape offsets                $totalSize = 8;                $spOffsets = array();                $spTypes   = array();                // treat the inner data                foreach ($this->object->getChildren() as $spContainer) {                    $writer = new PHPExcel_Writer_Excel5_Escher($spContainer);                    $spData = $writer->close();                    $innerData .= $spData;                    // save the shape offsets (where new shape records begin)                    $totalSize += strlen($spData);                    $spOffsets[] = $totalSize;                                        $spTypes = array_merge($spTypes, $writer->getSpTypes());                }                // write the record                $recVer            = 0xF;                $recInstance    = 0x0000;                $recType        = 0xF003;                $length            = strlen($innerData);                $recVerInstance  = $recVer;                $recVerInstance |= $recInstance << 4;                $header = pack('vvV', $recVerInstance, $recType, $length);                $this->data = $header . $innerData;                $this->spOffsets = $spOffsets;                $this->spTypes = $spTypes;                break;            case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer':                // initialize                $data = '';                // build the data                // write group shape record, if necessary?                if ($this->object->getSpgr()) {                    $recVer            = 0x1;                    $recInstance    = 0x0000;                    $recType        = 0xF009;                    $length            = 0x00000010;                    $recVerInstance  = $recVer;                    $recVerInstance |= $recInstance << 4;                    $header = pack('vvV', $recVerInstance, $recType, $length);                    $data .= $header . pack('VVVV', 0, 0, 0, 0);                }                $this->spTypes[] = ($this->object->getSpType());                // write the shape record                $recVer            = 0x2;                $recInstance    = $this->object->getSpType(); // shape type                $recType        = 0xF00A;                $length            = 0x00000008;                $recVerInstance  = $recVer;                $recVerInstance |= $recInstance << 4;                $header = pack('vvV', $recVerInstance, $recType, $length);                $data .= $header . pack('VV', $this->object->getSpId(), $this->object->getSpgr() ? 0x0005 : 0x0A00);                // the options                if ($this->object->getOPTCollection()) {                    $optData = '';                    $recVer            = 0x3;                    $recInstance    = count($this->object->getOPTCollection());                    $recType        = 0xF00B;                    foreach ($this->object->getOPTCollection() as $property => $value) {                        $optData .= pack('vV', $property, $value);                    }                    $length            = strlen($optData);                    $recVerInstance  = $recVer;                    $recVerInstance |= $recInstance << 4;                    $header = pack('vvV', $recVerInstance, $recType, $length);                    $data .= $header . $optData;                }                // the client anchor                if ($this->object->getStartCoordinates()) {                    $clientAnchorData = '';                    $recVer            = 0x0;                    $recInstance    = 0x0;                    $recType        = 0xF010;                    // start coordinates                    list($column, $row) = PHPExcel_Cell::coordinateFromString($this->object->getStartCoordinates());                    $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1;                    $r1 = $row - 1;                    // start offsetX                    $startOffsetX = $this->object->getStartOffsetX();                    // start offsetY                    $startOffsetY = $this->object->getStartOffsetY();                    // end coordinates                    list($column, $row) = PHPExcel_Cell::coordinateFromString($this->object->getEndCoordinates());                    $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1;                    $r2 = $row - 1;                    // end offsetX                    $endOffsetX = $this->object->getEndOffsetX();                    // end offsetY                    $endOffsetY = $this->object->getEndOffsetY();                    $clientAnchorData = pack('vvvvvvvvv', $this->object->getSpFlag(), $c1, $startOffsetX, $r1, $startOffsetY, $c2, $endOffsetX, $r2, $endOffsetY);                                        $length            = strlen($clientAnchorData);                    $recVerInstance  = $recVer;                    $recVerInstance |= $recInstance << 4;                    $header = pack('vvV', $recVerInstance, $recType, $length);                    $data .= $header . $clientAnchorData;                }                // the client data, just empty for now                if (!$this->object->getSpgr()) {                    $clientDataData = '';                    $recVer            = 0x0;                    $recInstance    = 0x0;                    $recType        = 0xF011;                    $length = strlen($clientDataData);                    $recVerInstance  = $recVer;                    $recVerInstance |= $recInstance << 4;                    $header = pack('vvV', $recVerInstance, $recType, $length);                    $data .= $header . $clientDataData;                }                // write the record                $recVer            = 0xF;                $recInstance    = 0x0000;                $recType        = 0xF004;                $length            = strlen($data);                $recVerInstance  = $recVer;                $recVerInstance |= $recInstance << 4;                $header = pack('vvV', $recVerInstance, $recType, $length);                $this->data = $header . $data;                break;        }        return $this->data;    }    /**     * Gets the shape offsets     *     * @return array     */    public function getSpOffsets()    {        return $this->spOffsets;    }    /**     * Gets the shape types     *     * @return array     */    public function getSpTypes()    {        return $this->spTypes;    }}
 |