00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 require_once('Format.php');
00036 require_once('classes/Spreadsheet/Excel/Writer/BIFFwriter.php');
00037 require_once('classes/Spreadsheet/Excel/Writer/Worksheet.php');
00038 require_once('classes/Spreadsheet/Excel/Writer/Parser.php');
00039 require_once('classes/OLE/PPS/Root.php');
00040 require_once('classes/OLE/PPS/File.php');
00041
00050 class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwriter
00051 {
00056 var $_filename;
00057
00062 var $_parser;
00063
00068 var $_1904;
00069
00074 var $_activesheet;
00075
00080 var $_firstsheet;
00081
00086 var $_selected;
00087
00092 var $_xf_index;
00093
00099 var $_fileclosed;
00100
00106 var $_biffsize;
00107
00112 var $_sheetname;
00113
00118 var $_tmp_format;
00119
00124 var $_worksheets;
00125
00130 var $_sheetnames;
00131
00136 var $_formats;
00137
00142 var $_palette;
00143
00148 var $_url_format;
00149
00154 var $_codepage;
00155
00160 var $_country_code;
00161
00166 var $_tmp_dir;
00167
00174 function Spreadsheet_Excel_Writer_Workbook($filename)
00175 {
00176
00177 $this->Spreadsheet_Excel_Writer_BIFFwriter();
00178
00179 $this->_filename = $filename;
00180 $this->_parser =& new Spreadsheet_Excel_Writer_Parser($this->_byte_order, $this->_BIFF_version);
00181 $this->_1904 = 0;
00182 $this->_activesheet = 0;
00183 $this->_firstsheet = 0;
00184 $this->_selected = 0;
00185 $this->_xf_index = 16;
00186 $this->_fileclosed = 0;
00187 $this->_biffsize = 0;
00188 $this->_sheetname = "Sheet";
00189 $this->_tmp_format =& new Spreadsheet_Excel_Writer_Format($this->_BIFF_version);
00190 $this->_worksheets = array();
00191 $this->_sheetnames = array();
00192 $this->_formats = array();
00193 $this->_palette = array();
00194 $this->_codepage = 0x04E4;
00195 $this->_country_code = -1;
00196
00197
00198 $this->_url_format =& $this->addFormat(array('color' => 'blue', 'underline' => 1));
00199 $this->_str_total = 0;
00200 $this->_str_unique = 0;
00201 $this->_str_table = array();
00202 $this->_setPaletteXl97();
00203 $this->_tmp_dir = '';
00204 }
00205
00213 function close()
00214 {
00215 if ($this->_fileclosed) {
00216 return true;
00217 }
00218 $res = $this->_storeWorkbook();
00219 if ($this->isError($res)) {
00220 return $this->raiseError($res->getMessage());
00221 }
00222 $this->_fileclosed = 1;
00223 return true;
00224 }
00225
00235 function sheets()
00236 {
00237 return $this->worksheets();
00238 }
00239
00247 function worksheets()
00248 {
00249 return $this->_worksheets;
00250 }
00251
00262 function setVersion($version)
00263 {
00264 if ($version == 8) {
00265 $version = 0x0600;
00266 $this->_BIFF_version = $version;
00267
00268 $this->_limit = 8224;
00269 $this->_tmp_format->_BIFF_version = $version;
00270 $this->_url_format->_BIFF_version = $version;
00271 $this->_parser->_BIFF_version = $version;
00272 $total_worksheets = count($this->_worksheets);
00273
00274 for ($i = 0; $i < $total_worksheets; $i++) {
00275 $this->_worksheets[$i]->_BIFF_version = $version;
00276 }
00277 $total_formats = count($this->_formats);
00278
00279 for ($i = 0; $i < $total_formats; $i++) {
00280 $this->_formats[$i]->_BIFF_version = $version;
00281 }
00282 }
00283 }
00284
00292 function setCountry($code)
00293 {
00294 $this->_country_code = $code;
00295 }
00296
00307 function &addWorksheet($name = '')
00308 {
00309 $index = count($this->_worksheets);
00310 $sheetname = $this->_sheetname;
00311
00312 if ($name == '') {
00313 $name = $sheetname.($index+1);
00314 }
00315
00316
00317 if (strlen($name) > 31) {
00318 return $this->raiseError("Sheetname $name must be <= 31 chars");
00319 }
00320
00321
00322 $total_worksheets = count($this->_worksheets);
00323 for ($i=0; $i < $total_worksheets; $i++)
00324 {
00325 if ($name == $this->_worksheets[$i]->getName()) {
00326 return $this->raiseError("Worksheet '$name' already exists");
00327 }
00328 }
00329
00330 $worksheet = new Spreadsheet_Excel_Writer_Worksheet($this->_BIFF_version,
00331 $name, $index,
00332 $this->_activesheet, $this->_firstsheet,
00333 $this->_str_total, $this->_str_unique,
00334 $this->_str_table, $this->_url_format,
00335 $this->_parser);
00336
00337 $this->_worksheets[$index] = &$worksheet;
00338 $this->_sheetnames[$index] = $name;
00339 $this->_parser->setExtSheet($name, $index);
00340 return $worksheet;
00341 }
00342
00351 function &addFormat($properties = array())
00352 {
00353 $format = new Spreadsheet_Excel_Writer_Format($this->_BIFF_version, $this->_xf_index,$properties);
00354 $this->_xf_index += 1;
00355 $this->_formats[] = &$format;
00356 return $format;
00357 }
00358
00365 function &addValidator()
00366 {
00367 include_once('Validator.php');
00368
00369 $valid = new Spreadsheet_Excel_Writer_Validator($this->_parser);
00370 return $valid;
00371 }
00372
00383 function setCustomColor($index,$red,$green,$blue)
00384 {
00385
00386
00387
00388
00389
00390
00391 if ($index < 8 or $index > 64) {
00392
00393 return $this->raiseError("Color index $index outside range: 8 <= index <= 64");
00394 }
00395
00396
00397 if ( ($red < 0 or $red > 255) or
00398 ($green < 0 or $green > 255) or
00399 ($blue < 0 or $blue > 255) )
00400 {
00401 return $this->raiseError("Color component outside range: 0 <= color <= 255");
00402 }
00403
00404 $index -= 8;
00405
00406
00407 $this->_palette[$index] = array($red, $green, $blue, 0);
00408 return($index + 8);
00409 }
00410
00416 function _setPaletteXl97()
00417 {
00418 $this->_palette = array(
00419 array(0x00, 0x00, 0x00, 0x00),
00420 array(0xff, 0xff, 0xff, 0x00),
00421 array(0xff, 0x00, 0x00, 0x00),
00422 array(0x00, 0xff, 0x00, 0x00),
00423 array(0x00, 0x00, 0xff, 0x00),
00424 array(0xff, 0xff, 0x00, 0x00),
00425 array(0xff, 0x00, 0xff, 0x00),
00426 array(0x00, 0xff, 0xff, 0x00),
00427 array(0x80, 0x00, 0x00, 0x00),
00428 array(0x00, 0x80, 0x00, 0x00),
00429 array(0x00, 0x00, 0x80, 0x00),
00430 array(0x80, 0x80, 0x00, 0x00),
00431 array(0x80, 0x00, 0x80, 0x00),
00432 array(0x00, 0x80, 0x80, 0x00),
00433 array(0xc0, 0xc0, 0xc0, 0x00),
00434 array(0x80, 0x80, 0x80, 0x00),
00435 array(0x99, 0x99, 0xff, 0x00),
00436 array(0x99, 0x33, 0x66, 0x00),
00437 array(0xff, 0xff, 0xcc, 0x00),
00438 array(0xcc, 0xff, 0xff, 0x00),
00439 array(0x66, 0x00, 0x66, 0x00),
00440 array(0xff, 0x80, 0x80, 0x00),
00441 array(0x00, 0x66, 0xcc, 0x00),
00442 array(0xcc, 0xcc, 0xff, 0x00),
00443 array(0x00, 0x00, 0x80, 0x00),
00444 array(0xff, 0x00, 0xff, 0x00),
00445 array(0xff, 0xff, 0x00, 0x00),
00446 array(0x00, 0xff, 0xff, 0x00),
00447 array(0x80, 0x00, 0x80, 0x00),
00448 array(0x80, 0x00, 0x00, 0x00),
00449 array(0x00, 0x80, 0x80, 0x00),
00450 array(0x00, 0x00, 0xff, 0x00),
00451 array(0x00, 0xcc, 0xff, 0x00),
00452 array(0xcc, 0xff, 0xff, 0x00),
00453 array(0xcc, 0xff, 0xcc, 0x00),
00454 array(0xff, 0xff, 0x99, 0x00),
00455 array(0x99, 0xcc, 0xff, 0x00),
00456 array(0xff, 0x99, 0xcc, 0x00),
00457 array(0xcc, 0x99, 0xff, 0x00),
00458 array(0xff, 0xcc, 0x99, 0x00),
00459 array(0x33, 0x66, 0xff, 0x00),
00460 array(0x33, 0xcc, 0xcc, 0x00),
00461 array(0x99, 0xcc, 0x00, 0x00),
00462 array(0xff, 0xcc, 0x00, 0x00),
00463 array(0xff, 0x99, 0x00, 0x00),
00464 array(0xff, 0x66, 0x00, 0x00),
00465 array(0x66, 0x66, 0x99, 0x00),
00466 array(0x96, 0x96, 0x96, 0x00),
00467 array(0x00, 0x33, 0x66, 0x00),
00468 array(0x33, 0x99, 0x66, 0x00),
00469 array(0x00, 0x33, 0x00, 0x00),
00470 array(0x33, 0x33, 0x00, 0x00),
00471 array(0x99, 0x33, 0x00, 0x00),
00472 array(0x99, 0x33, 0x66, 0x00),
00473 array(0x33, 0x33, 0x99, 0x00),
00474 array(0x33, 0x33, 0x33, 0x00),
00475 );
00476 }
00477
00485 function _storeWorkbook()
00486 {
00487
00488 if ($this->_activesheet == 0) {
00489 $this->_worksheets[0]->selected = 1;
00490 }
00491
00492
00493
00494 $total_worksheets = count($this->_worksheets);
00495 for ($i=0; $i < $total_worksheets; $i++) {
00496 if ($this->_worksheets[$i]->selected) {
00497 $this->_selected++;
00498 }
00499 $this->_worksheets[$i]->close($this->_sheetnames);
00500 }
00501
00502
00503 $this->_storeBof(0x0005);
00504 if ($this->_BIFF_version == 0x0600) {
00505 $this->_storeCodepage();
00506 $this->_storeWindow1();
00507 }
00508 if ($this->_BIFF_version == 0x0500) {
00509 $this->_storeExterns();
00510 }
00511 $this->_storeNames();
00512 if ($this->_BIFF_version == 0x0500) {
00513 $this->_storeWindow1();
00514 }
00515 $this->_storeDatemode();
00516 $this->_storeAllFonts();
00517 $this->_storeAllNumFormats();
00518 $this->_storeAllXfs();
00519 $this->_storeAllStyles();
00520 $this->_storePalette();
00521 $this->_calcSheetOffsets();
00522
00523
00524 for ($i=0; $i < $total_worksheets; $i++) {
00525 $this->_storeBoundsheet($this->_worksheets[$i]->name,$this->_worksheets[$i]->offset);
00526 }
00527
00528 if ($this->_country_code != -1) {
00529 $this->_storeCountry();
00530 }
00531
00532 if ($this->_BIFF_version == 0x0600) {
00533
00534
00535
00536
00537 $this->_storeSharedStringsTable();
00538 }
00539
00540
00541 $this->_storeEof();
00542
00543
00544 $res = $this->_storeOLEFile();
00545 if ($this->isError($res)) {
00546 return $this->raiseError($res->getMessage());
00547 }
00548 return true;
00549 }
00550
00558 function setTempDir($dir)
00559 {
00560 if (is_dir($dir)) {
00561 $this->_tmp_dir = $dir;
00562 return true;
00563 }
00564 return false;
00565 }
00566
00573 function _storeOLEFile()
00574 {
00575 $OLE = new OLE_PPS_File(OLE::Asc2Ucs('Book'));
00576 if ($this->_tmp_dir != '') {
00577 $OLE->setTempDir($this->_tmp_dir);
00578 }
00579 $res = $OLE->init();
00580 if ($this->isError($res)) {
00581 return $this->raiseError("OLE Error: ".$res->getMessage());
00582 }
00583 $OLE->append($this->_data);
00584 $total_worksheets = count($this->_worksheets);
00585 for ($i = 0; $i < $total_worksheets; $i++)
00586 {
00587 while ($tmp = $this->_worksheets[$i]->getData()) {
00588 $OLE->append($tmp);
00589 }
00590 }
00591 $root = new OLE_PPS_Root(time(), time(), array($OLE));
00592 if ($this->_tmp_dir != '') {
00593 $root->setTempDir($this->_tmp_dir);
00594 }
00595 $res = $root->save($this->_filename);
00596 if ($this->isError($res)) {
00597 return $this->raiseError("OLE Error: ".$res->getMessage());
00598 }
00599 return true;
00600 }
00601
00607 function _calcSheetOffsets()
00608 {
00609 if ($this->_BIFF_version == 0x0600) {
00610 $boundsheet_length = 12;
00611 }
00612 else {
00613 $boundsheet_length = 11;
00614 }
00615 $EOF = 4;
00616 $offset = $this->_datasize;
00617
00618 if ($this->_BIFF_version == 0x0600) {
00619
00620
00621 $offset += $this->_calculateSharedStringsSizes();
00622 if ($this->_country_code != -1) {
00623 $offset += 8;
00624 }
00625
00626
00627 }
00628 $total_worksheets = count($this->_worksheets);
00629
00630 for ($i=0; $i < $total_worksheets; $i++) {
00631 $offset += $boundsheet_length + strlen($this->_worksheets[$i]->name);
00632 }
00633 $offset += $EOF;
00634
00635 for ($i=0; $i < $total_worksheets; $i++) {
00636 $this->_worksheets[$i]->offset = $offset;
00637 $offset += $this->_worksheets[$i]->_datasize;
00638 }
00639 $this->_biffsize = $offset;
00640 }
00641
00647 function _storeAllFonts()
00648 {
00649
00650 $format = $this->_tmp_format;
00651 $font = $format->getFont();
00652
00653
00654
00655
00656 for ($i=1; $i <= 5; $i++){
00657 $this->_append($font);
00658 }
00659
00660
00661
00662
00663 $fonts = array();
00664 $index = 6;
00665
00666 $key = $format->getFontKey();
00667 $fonts[$key] = 0;
00668
00669 $total_formats = count($this->_formats);
00670 for ($i=0; $i < $total_formats; $i++)
00671 {
00672 $key = $this->_formats[$i]->getFontKey();
00673 if (isset($fonts[$key])) {
00674
00675 $this->_formats[$i]->font_index = $fonts[$key];
00676 }
00677 else {
00678
00679 $fonts[$key] = $index;
00680 $this->_formats[$i]->font_index = $index;
00681 $index++;
00682 $font = $this->_formats[$i]->getFont();
00683 $this->_append($font);
00684 }
00685 }
00686 }
00687
00693 function _storeAllNumFormats()
00694 {
00695
00696 $hash_num_formats = array();
00697 $num_formats = array();
00698 $index = 164;
00699
00700
00701
00702 $total_formats = count($this->_formats);
00703 for ($i=0; $i < $total_formats; $i++)
00704 {
00705 $num_format = $this->_formats[$i]->_num_format;
00706
00707
00708
00709
00710
00711 if (!preg_match("/^0+\d/",$num_format))
00712 {
00713 if (preg_match("/^\d+$/",$num_format)) {
00714 continue;
00715 }
00716 }
00717
00718 if (isset($hash_num_formats[$num_format])) {
00719
00720 $this->_formats[$i]->_num_format = $hash_num_formats[$num_format];
00721 }
00722 else{
00723
00724 $hash_num_formats[$num_format] = $index;
00725 $this->_formats[$i]->_num_format = $index;
00726 array_push($num_formats,$num_format);
00727 $index++;
00728 }
00729 }
00730
00731
00732 $index = 164;
00733 foreach ($num_formats as $num_format) {
00734 $this->_storeNumFormat($num_format,$index);
00735 $index++;
00736 }
00737 }
00738
00744 function _storeAllXfs()
00745 {
00746
00747
00748
00749 $format = $this->_tmp_format;
00750 for ($i=0; $i <= 14; $i++) {
00751 $xf = $format->getXf('style');
00752 $this->_append($xf);
00753 }
00754
00755 $xf = $format->getXf('cell');
00756 $this->_append($xf);
00757
00758
00759 $total_formats = count($this->_formats);
00760 for ($i=0; $i < $total_formats; $i++) {
00761 $xf = $this->_formats[$i]->getXf('cell');
00762 $this->_append($xf);
00763 }
00764 }
00765
00771 function _storeAllStyles()
00772 {
00773 $this->_storeStyle();
00774 }
00775
00782 function _storeExterns()
00783 {
00784
00785 $this->_storeExterncount(count($this->_worksheets));
00786
00787
00788 foreach ($this->_sheetnames as $sheetname) {
00789 $this->_storeExternsheet($sheetname);
00790 }
00791 }
00792
00798 function _storeNames()
00799 {
00800
00801 $total_worksheets = count($this->_worksheets);
00802 for ($i = 0; $i < $total_worksheets; $i++) {
00803
00804 if (isset($this->_worksheets[$i]->print_rowmin))
00805 {
00806 $this->_storeNameShort(
00807 $this->_worksheets[$i]->index,
00808 0x06,
00809 $this->_worksheets[$i]->print_rowmin,
00810 $this->_worksheets[$i]->print_rowmax,
00811 $this->_worksheets[$i]->print_colmin,
00812 $this->_worksheets[$i]->print_colmax
00813 );
00814 }
00815 }
00816
00817
00818 $total_worksheets = count($this->_worksheets);
00819 for ($i = 0; $i < $total_worksheets; $i++) {
00820 $rowmin = $this->_worksheets[$i]->title_rowmin;
00821 $rowmax = $this->_worksheets[$i]->title_rowmax;
00822 $colmin = $this->_worksheets[$i]->title_colmin;
00823 $colmax = $this->_worksheets[$i]->title_colmax;
00824
00825
00826
00827
00828 if (isset($rowmin) and isset($colmin)) {
00829
00830
00831 $this->_storeNameLong(
00832 $this->_worksheets[$i]->index,
00833 0x07,
00834 $rowmin,
00835 $rowmax,
00836 $colmin,
00837 $colmax
00838 );
00839 }
00840 elseif (isset($rowmin)) {
00841
00842 $this->_storeNameShort(
00843 $this->_worksheets[$i]->index,
00844 0x07,
00845 $rowmin,
00846 $rowmax,
00847 0x00,
00848 0xff
00849 );
00850 }
00851 elseif (isset($colmin)) {
00852
00853 $this->_storeNameShort(
00854 $this->_worksheets[$i]->index,
00855 0x07,
00856 0x0000,
00857 0x3fff,
00858 $colmin,
00859 $colmax
00860 );
00861 }
00862 else {
00863
00864 }
00865 }
00866 }
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00882 function _storeCodepage()
00883 {
00884 $record = 0x0042;
00885 $length = 0x0002;
00886 $cv = $this->_codepage;
00887
00888 $header = pack('vv', $record, $length);
00889 $data = pack('v', $cv);
00890
00891 $this->_append($header.$data);
00892 }
00893
00899 function _storeWindow1()
00900 {
00901 $record = 0x003D;
00902 $length = 0x0012;
00903
00904 $xWn = 0x0000;
00905 $yWn = 0x0000;
00906 $dxWn = 0x25BC;
00907 $dyWn = 0x1572;
00908
00909 $grbit = 0x0038;
00910 $ctabsel = $this->_selected;
00911 $wTabRatio = 0x0258;
00912
00913 $itabFirst = $this->_firstsheet;
00914 $itabCur = $this->_activesheet;
00915
00916 $header = pack("vv", $record, $length);
00917 $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn,
00918 $grbit,
00919 $itabCur, $itabFirst,
00920 $ctabsel, $wTabRatio);
00921 $this->_append($header.$data);
00922 }
00923
00932 function _storeBoundsheet($sheetname,$offset)
00933 {
00934 $record = 0x0085;
00935 if ($this->_BIFF_version == 0x0600) {
00936 $length = 0x08 + strlen($sheetname);
00937 }
00938 else {
00939 $length = 0x07 + strlen($sheetname);
00940 }
00941
00942 $grbit = 0x0000;
00943 $cch = strlen($sheetname);
00944
00945 $header = pack("vv", $record, $length);
00946 if ($this->_BIFF_version == 0x0600) {
00947 $data = pack("Vvv", $offset, $grbit, $cch);
00948 }
00949 else {
00950 $data = pack("VvC", $offset, $grbit, $cch);
00951 }
00952 $this->_append($header.$data.$sheetname);
00953 }
00954
00960 function _storeSupbookInternal()
00961 {
00962 $record = 0x01AE;
00963 $length = 0x0004;
00964
00965 $header = pack("vv", $record, $length);
00966 $data = pack("vv", count($this->_worksheets), 0x0104);
00967 $this->_append($header.$data);
00968 }
00969
00977 function _storeExternsheetBiff8()
00978 {
00979 $total_references = count($this->_parser->_references);
00980 $record = 0x0017;
00981 $length = 2 + 6 * $total_references;
00982
00983 $supbook_index = 0;
00984 $header = pack("vv", $record, $length);
00985 $data = pack('v', $total_references);
00986 for ($i = 0; $i < $total_references; $i++) {
00987 $data .= $this->_parser->_references[$i];
00988 }
00989 $this->_append($header.$data);
00990 }
00991
00997 function _storeStyle()
00998 {
00999 $record = 0x0293;
01000 $length = 0x0004;
01001
01002 $ixfe = 0x8000;
01003 $BuiltIn = 0x00;
01004 $iLevel = 0xff;
01005
01006 $header = pack("vv", $record, $length);
01007 $data = pack("vCC", $ixfe, $BuiltIn, $iLevel);
01008 $this->_append($header.$data);
01009 }
01010
01011
01019 function _storeNumFormat($format,$ifmt)
01020 {
01021 $record = 0x041E;
01022
01023 if ($this->_BIFF_version == 0x0600) {
01024 $length = 5 + strlen($format);
01025 $encoding = 0x0;
01026 }
01027 elseif ($this->_BIFF_version == 0x0500) {
01028 $length = 3 + strlen($format);
01029 }
01030
01031 $cch = strlen($format);
01032
01033 $header = pack("vv", $record, $length);
01034 if ($this->_BIFF_version == 0x0600) {
01035 $data = pack("vvC", $ifmt, $cch, $encoding);
01036 }
01037 elseif ($this->_BIFF_version == 0x0500) {
01038 $data = pack("vC", $ifmt, $cch);
01039 }
01040 $this->_append($header.$data.$format);
01041 }
01042
01048 function _storeDatemode()
01049 {
01050 $record = 0x0022;
01051 $length = 0x0002;
01052
01053 $f1904 = $this->_1904;
01054
01055 $header = pack("vv", $record, $length);
01056 $data = pack("v", $f1904);
01057 $this->_append($header.$data);
01058 }
01059
01060
01074 function _storeExterncount($cxals)
01075 {
01076 $record = 0x0016;
01077 $length = 0x0002;
01078
01079 $header = pack("vv", $record, $length);
01080 $data = pack("v", $cxals);
01081 $this->_append($header.$data);
01082 }
01083
01084
01095 function _storeExternsheet($sheetname)
01096 {
01097 $record = 0x0017;
01098 $length = 0x02 + strlen($sheetname);
01099
01100 $cch = strlen($sheetname);
01101 $rgch = 0x03;
01102
01103 $header = pack("vv", $record, $length);
01104 $data = pack("CC", $cch, $rgch);
01105 $this->_append($header.$data.$sheetname);
01106 }
01107
01108
01121 function _storeNameShort($index,$type,$rowmin,$rowmax,$colmin,$colmax)
01122 {
01123 $record = 0x0018;
01124 $length = 0x0024;
01125
01126 $grbit = 0x0020;
01127 $chKey = 0x00;
01128 $cch = 0x01;
01129 $cce = 0x0015;
01130 $ixals = $index + 1;
01131 $itab = $ixals;
01132 $cchCustMenu = 0x00;
01133 $cchDescription = 0x00;
01134 $cchHelptopic = 0x00;
01135 $cchStatustext = 0x00;
01136 $rgch = $type;
01137
01138 $unknown03 = 0x3b;
01139 $unknown04 = 0xffff-$index;
01140 $unknown05 = 0x0000;
01141 $unknown06 = 0x0000;
01142 $unknown07 = 0x1087;
01143 $unknown08 = 0x8005;
01144
01145 $header = pack("vv", $record, $length);
01146 $data = pack("v", $grbit);
01147 $data .= pack("C", $chKey);
01148 $data .= pack("C", $cch);
01149 $data .= pack("v", $cce);
01150 $data .= pack("v", $ixals);
01151 $data .= pack("v", $itab);
01152 $data .= pack("C", $cchCustMenu);
01153 $data .= pack("C", $cchDescription);
01154 $data .= pack("C", $cchHelptopic);
01155 $data .= pack("C", $cchStatustext);
01156 $data .= pack("C", $rgch);
01157 $data .= pack("C", $unknown03);
01158 $data .= pack("v", $unknown04);
01159 $data .= pack("v", $unknown05);
01160 $data .= pack("v", $unknown06);
01161 $data .= pack("v", $unknown07);
01162 $data .= pack("v", $unknown08);
01163 $data .= pack("v", $index);
01164 $data .= pack("v", $index);
01165 $data .= pack("v", $rowmin);
01166 $data .= pack("v", $rowmax);
01167 $data .= pack("C", $colmin);
01168 $data .= pack("C", $colmax);
01169 $this->_append($header.$data);
01170 }
01171
01172
01187 function _storeNameLong($index,$type,$rowmin,$rowmax,$colmin,$colmax)
01188 {
01189 $record = 0x0018;
01190 $length = 0x003d;
01191 $grbit = 0x0020;
01192 $chKey = 0x00;
01193 $cch = 0x01;
01194 $cce = 0x002e;
01195 $ixals = $index + 1;
01196 $itab = $ixals;
01197 $cchCustMenu = 0x00;
01198 $cchDescription = 0x00;
01199 $cchHelptopic = 0x00;
01200 $cchStatustext = 0x00;
01201 $rgch = $type;
01202
01203 $unknown01 = 0x29;
01204 $unknown02 = 0x002b;
01205 $unknown03 = 0x3b;
01206 $unknown04 = 0xffff-$index;
01207 $unknown05 = 0x0000;
01208 $unknown06 = 0x0000;
01209 $unknown07 = 0x1087;
01210 $unknown08 = 0x8008;
01211
01212 $header = pack("vv", $record, $length);
01213 $data = pack("v", $grbit);
01214 $data .= pack("C", $chKey);
01215 $data .= pack("C", $cch);
01216 $data .= pack("v", $cce);
01217 $data .= pack("v", $ixals);
01218 $data .= pack("v", $itab);
01219 $data .= pack("C", $cchCustMenu);
01220 $data .= pack("C", $cchDescription);
01221 $data .= pack("C", $cchHelptopic);
01222 $data .= pack("C", $cchStatustext);
01223 $data .= pack("C", $rgch);
01224 $data .= pack("C", $unknown01);
01225 $data .= pack("v", $unknown02);
01226
01227 $data .= pack("C", $unknown03);
01228 $data .= pack("v", $unknown04);
01229 $data .= pack("v", $unknown05);
01230 $data .= pack("v", $unknown06);
01231 $data .= pack("v", $unknown07);
01232 $data .= pack("v", $unknown08);
01233 $data .= pack("v", $index);
01234 $data .= pack("v", $index);
01235 $data .= pack("v", 0x0000);
01236 $data .= pack("v", 0x3fff);
01237 $data .= pack("C", $colmin);
01238 $data .= pack("C", $colmax);
01239
01240 $data .= pack("C", $unknown03);
01241 $data .= pack("v", $unknown04);
01242 $data .= pack("v", $unknown05);
01243 $data .= pack("v", $unknown06);
01244 $data .= pack("v", $unknown07);
01245 $data .= pack("v", $unknown08);
01246 $data .= pack("v", $index);
01247 $data .= pack("v", $index);
01248 $data .= pack("v", $rowmin);
01249 $data .= pack("v", $rowmax);
01250 $data .= pack("C", 0x00);
01251 $data .= pack("C", 0xff);
01252
01253 $data .= pack("C", 0x10);
01254 $this->_append($header.$data);
01255 }
01256
01262 function _storeCountry()
01263 {
01264 $record = 0x008C;
01265 $length = 4;
01266
01267 $header = pack('vv', $record, $length);
01268
01269 $data = pack('vv', $this->_country_code, $this->_country_code);
01270 $this->_append($header.$data);
01271 }
01272
01278 function _storePalette()
01279 {
01280 $aref = $this->_palette;
01281
01282 $record = 0x0092;
01283 $length = 2 + 4 * count($aref);
01284 $ccv = count($aref);
01285 $data = '';
01286
01287
01288 foreach($aref as $color)
01289 {
01290 foreach($color as $byte) {
01291 $data .= pack("C",$byte);
01292 }
01293 }
01294
01295 $header = pack("vvv", $record, $length, $ccv);
01296 $this->_append($header.$data);
01297 }
01298
01309 function _calculateSharedStringsSizes()
01310 {
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 $total_offset = 12;
01323 $continue_limit = 8208;
01324 $block_length = 0;
01325 $written = 0;
01326 $this->_block_sizes = array();
01327 $continue = 0;
01328
01329 foreach (array_keys($this->_str_table) as $string) {
01330 $string_length = strlen($string);
01331
01332
01333
01334 $block_length += $string_length;
01335
01336
01337 if ($block_length < $continue_limit) {
01338 $written += $string_length;
01339 $total_offset += $string_length;
01340 continue;
01341 }
01342
01343
01344
01345
01346 while ($block_length >= $continue_limit) {
01347
01348
01349
01350 $header_length = 3;
01351 $space_remaining = $continue_limit - $written - $continue;
01352
01353
01354
01355
01356
01357
01358
01359 if ($space_remaining > $header_length) {
01360
01361 $written += $space_remaining;
01362
01363
01364 $block_length -= $continue_limit + $continue;
01365
01366
01367 $this->_block_sizes[] = $continue_limit;
01368
01369
01370
01371
01372 if ($block_length > 0) {
01373 $continue = 1;
01374 }
01375 else {
01376 $continue = 0;
01377 }
01378
01379 }
01380 else {
01381
01382 $this->_block_sizes[] = $written + $continue;
01383
01384
01385 $block_length -= $continue_limit - $space_remaining - $continue;
01386 $continue = 0;
01387
01388 }
01389
01390
01391
01392
01393 if ($block_length < $continue_limit) {
01394 $written = $block_length;
01395 }
01396 else {
01397 $written = 0;
01398 }
01399 }
01400 }
01401
01402
01403 if ($written + $continue) {
01404 $this->_block_sizes[] = $written + $continue;
01405 }
01406
01407
01408
01409
01410
01411
01412
01413 if (!empty($this->_block_sizes)) {
01414 $total_offset += (count($this->_block_sizes) - 1) * 4;
01415 }
01416 return $total_offset;
01417 }
01418
01430
01431 function _storeSharedStringsTable()
01432 {
01433 $record = 0x00fc;
01434 $length = 8 + array_sum($this->_block_sizes);
01435
01436
01437 $header = pack("vv", $record, $length);
01438 $data = pack("VV", $this->_str_total, $this->_str_unique);
01439 $this->_append($header.$data);
01440
01441
01442
01443 $continue_limit = 8208;
01444 $block_length = 0;
01445 $written = 0;
01446 $continue = 0;
01447
01448
01449
01450 foreach (array_keys($this->_str_table) as $string) {
01451
01452 $string_length = strlen($string);
01453 $encoding = 0;
01454 $split_string = 0;
01455
01456
01457
01458
01459 $block_length += $string_length;
01460
01461
01462
01463 if ($block_length < $continue_limit) {
01464 $this->_append($string);
01465 $written += $string_length;
01466 continue;
01467 }
01468
01469
01470
01471
01472
01473 while ($block_length >= $continue_limit) {
01474
01475
01476
01477
01478 $header_length = 3;
01479 $space_remaining = $continue_limit - $written - $continue;
01480
01481
01482
01483
01484
01485 if ($space_remaining > $header_length) {
01486
01487 $tmp = substr($string, 0, $space_remaining);
01488 $this->_append($tmp);
01489
01490
01491 $string = substr($string, $space_remaining);
01492
01493
01494 $block_length -= $continue_limit - $continue;
01495
01496
01497
01498
01499
01500 if ($block_length > 0) {
01501 $continue = 1;
01502 }
01503 else {
01504 $continue = 0;
01505 }
01506 }
01507 else {
01508
01509 $block_length -= $continue_limit - $space_remaining - $continue;
01510 $continue = 0;
01511 }
01512
01513
01514 if (!empty($this->_block_sizes)) {
01515 $record = 0x003C;
01516 $length = array_pop($this->_block_sizes);
01517
01518 $header = pack('vv', $record, $length);
01519 if ($continue) {
01520 $header .= pack('C', $encoding);
01521 }
01522 $this->_append($header);
01523 }
01524
01525
01526
01527
01528
01529 if ($block_length < $continue_limit) {
01530 $this->_append($string);
01531
01532 $written = $block_length;
01533 }
01534 else {
01535 $written = 0;
01536 }
01537 }
01538 }
01539 }
01540 }
01541 ?>