⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 class.pdf.php

📁 完美的在线教育系统
💻 PHP
📖 第 1 页 / 共 5 页
字号:
      break;
    case 'out':
      $res="\n".$id." 0 obj\n<< /Type /Annot";
      switch($o['info']['type']){
        case 'link':
        case 'ilink':
          $res.= "\n/Subtype /Link";
          break;
      }
      $res.="\n/A ".$o['info']['actionId']." 0 R";
      $res.="\n/Border [0 0 0]";
      $res.="\n/H /I";
      $res.="\n/Rect [ ";
      foreach($o['info']['rect'] as $v){
        $res.= sprintf("%.4f ",$v);
      }
      $res.="]";
      $res.="\n>>\nendobj";
      return $res;
      break;
  }
}

/**
* a page object, it also creates a contents object to hold its contents
*/
function o_page($id,$action,$options=''){
  if ($action!='new'){
    $o =& $this->objects[$id];
  }
  switch ($action){
    case 'new':
      $this->numPages++;
      $this->objects[$id]=array('t'=>'page','info'=>array('parent'=>$this->currentNode,'pageNum'=>$this->numPages));
      if (is_array($options)){
        // then this must be a page insertion, array shoudl contain 'rid','pos'=[before|after]
        $options['id']=$id;
        $this->o_pages($this->currentNode,'page',$options);
      } else {
        $this->o_pages($this->currentNode,'page',$id);
      }
      $this->currentPage=$id;
      //make a contents object to go with this page
      $this->numObj++;
      $this->o_contents($this->numObj,'new',$id);
      $this->currentContents=$this->numObj;
      $this->objects[$id]['info']['contents']=array();
      $this->objects[$id]['info']['contents'][]=$this->numObj;
      $match = ($this->numPages%2 ? 'odd' : 'even');
      foreach($this->addLooseObjects as $oId=>$target){
        if ($target=='all' || $match==$target){
          $this->objects[$id]['info']['contents'][]=$oId;
        }
      }
      break;
    case 'content':
      $o['info']['contents'][]=$options;
      break;
    case 'annot':
      // add an annotation to this page
      if (!isset($o['info']['annot'])){
        $o['info']['annot']=array();
      }
      // $options should contain the id of the annotation dictionary
      $o['info']['annot'][]=$options;
      break;
    case 'out':
      $res="\n".$id." 0 obj\n<< /Type /Page";
      $res.="\n/Parent ".$o['info']['parent']." 0 R";
      if (isset($o['info']['annot'])){
        $res.="\n/Annots [";
        foreach($o['info']['annot'] as $aId){
          $res.=" ".$aId." 0 R";
        }
        $res.=" ]";
      }
      $count = count($o['info']['contents']);
      if ($count==1){
        $res.="\n/Contents ".$o['info']['contents'][0]." 0 R";
      } else if ($count>1){
        $res.="\n/Contents [\n";
        foreach ($o['info']['contents'] as $cId){
          $res.=$cId." 0 R\n";
        }
        $res.="]";
      }
      $res.="\n>>\nendobj";
      return $res;
      break;
  }
}

/**
* the contents objects hold all of the content which appears on pages
*/
function o_contents($id,$action,$options=''){
  if ($action!='new'){
    $o =& $this->objects[$id];
  }
  switch ($action){
    case 'new':
      $this->objects[$id]=array('t'=>'contents','c'=>'','info'=>array());
      if (strlen($options) && intval($options)){
        // then this contents is the primary for a page
        $this->objects[$id]['onPage']=$options;
      } else if ($options=='raw'){
        // then this page contains some other type of system object
        $this->objects[$id]['raw']=1;
      }
      break;
    case 'add':
      // add more options to the decleration
      foreach ($options as $k=>$v){
        $o['info'][$k]=$v;
      }
    case 'out':
      $tmp=$o['c'];
      $res= "\n".$id." 0 obj\n";
      if (isset($this->objects[$id]['raw'])){
        $res.=$tmp;
      } else {
        $res.= "<<";
        if (function_exists('gzcompress') && $this->options['compression']){
          // then implement ZLIB based compression on this content stream
          $res.=" /Filter /FlateDecode";
          $tmp = gzcompress($tmp);
        }
        if ($this->encrypted){
          $this->encryptInit($id);
          $tmp = $this->ARC4($tmp);
        }
        foreach($o['info'] as $k=>$v){
          $res .= "\n/".$k.' '.$v;
        }
        $res.="\n/Length ".strlen($tmp)." >>\nstream\n".$tmp."\nendstream";
      }
      $res.="\nendobj\n";
      return $res;
      break;
  }
}

/**
* an image object, will be an XObject in the document, includes description and data
*/
function o_image($id,$action,$options=''){
  if ($action!='new'){
    $o =& $this->objects[$id];
  }
  switch($action){
    case 'new':
      // make the new object
      $this->objects[$id]=array('t'=>'image','data'=>$options['data'],'info'=>array());
      $this->objects[$id]['info']['Type']='/XObject';
      $this->objects[$id]['info']['Subtype']='/Image';
      $this->objects[$id]['info']['Width']=$options['iw'];
      $this->objects[$id]['info']['Height']=$options['ih'];
      if (!isset($options['type']) || $options['type']=='jpg'){
        if (!isset($options['channels'])){
          $options['channels']=3;
        }
        switch($options['channels']){
          case 1:
            $this->objects[$id]['info']['ColorSpace']='/DeviceGray';
            break;
          default:
            $this->objects[$id]['info']['ColorSpace']='/DeviceRGB';
            break;
        }
        $this->objects[$id]['info']['Filter']='/DCTDecode';
        $this->objects[$id]['info']['BitsPerComponent']=8;
      } else if ($options['type']=='png'){
        $this->objects[$id]['info']['Filter']='/FlateDecode';
        $this->objects[$id]['info']['DecodeParms']='<< /Predictor 15 /Colors '.$options['ncolor'].' /Columns '.$options['iw'].' /BitsPerComponent '.$options['bitsPerComponent'].'>>';
        if (strlen($options['pdata'])){
          $tmp = ' [ /Indexed /DeviceRGB '.(strlen($options['pdata'])/3-1).' ';
          $this->numObj++;
          $this->o_contents($this->numObj,'new');
          $this->objects[$this->numObj]['c']=$options['pdata'];
          $tmp.=$this->numObj.' 0 R';
          $tmp .=' ]';
          $this->objects[$id]['info']['ColorSpace'] = $tmp;
          if (isset($options['transparency'])){
            switch($options['transparency']['type']){
              case 'indexed':
                $tmp=' [ '.$options['transparency']['data'].' '.$options['transparency']['data'].'] ';
                $this->objects[$id]['info']['Mask'] = $tmp;
                break;
            }
          }
        } else {
          $this->objects[$id]['info']['ColorSpace']='/'.$options['color'];
        }
        $this->objects[$id]['info']['BitsPerComponent']=$options['bitsPerComponent'];
      }
      // assign it a place in the named resource dictionary as an external object, according to
      // the label passed in with it.
      $this->o_pages($this->currentNode,'xObject',array('label'=>$options['label'],'objNum'=>$id));
      // also make sure that we have the right procset object for it.
      $this->o_procset($this->procsetObjectId,'add','ImageC');
      break;
    case 'out':
      $tmp=$o['data'];
      $res= "\n".$id." 0 obj\n<<";
      foreach($o['info'] as $k=>$v){
        $res.="\n/".$k.' '.$v;
      }
      if ($this->encrypted){
        $this->encryptInit($id);
        $tmp = $this->ARC4($tmp);
      }
      $res.="\n/Length ".strlen($tmp)." >>\nstream\n".$tmp."\nendstream\nendobj\n";
      return $res;
      break;
  }
}

/**
* encryption object.
*/
function o_encryption($id,$action,$options=''){
  if ($action!='new'){
    $o =& $this->objects[$id];
  }
  switch($action){
    case 'new':
      // make the new object
      $this->objects[$id]=array('t'=>'encryption','info'=>$options);
      $this->arc4_objnum=$id;
      // figure out the additional paramaters required
      $pad = chr(0x28).chr(0xBF).chr(0x4E).chr(0x5E).chr(0x4E).chr(0x75).chr(0x8A).chr(0x41).chr(0x64).chr(0x00).chr(0x4E).chr(0x56).chr(0xFF).chr(0xFA).chr(0x01).chr(0x08).chr(0x2E).chr(0x2E).chr(0x00).chr(0xB6).chr(0xD0).chr(0x68).chr(0x3E).chr(0x80).chr(0x2F).chr(0x0C).chr(0xA9).chr(0xFE).chr(0x64).chr(0x53).chr(0x69).chr(0x7A);
      $len = strlen($options['owner']);
      if ($len>32){
        $owner = substr($options['owner'],0,32);
      } else if ($len<32){
        $owner = $options['owner'].substr($pad,0,32-$len);
      } else {
        $owner = $options['owner'];
      }
      $len = strlen($options['user']);
      if ($len>32){
        $user = substr($options['user'],0,32);
      } else if ($len<32){
        $user = $options['user'].substr($pad,0,32-$len);
      } else {
        $user = $options['user'];
      }
      $tmp = $this->md5_16($owner);
      $okey = substr($tmp,0,5);
      $this->ARC4_init($okey);
      $ovalue=$this->ARC4($user);
      $this->objects[$id]['info']['O']=$ovalue;
      // now make the u value, phew.
      $tmp = $this->md5_16($user.$ovalue.chr($options['p']).chr(255).chr(255).chr(255).$this->fileIdentifier);
      $ukey = substr($tmp,0,5);

      $this->ARC4_init($ukey);
      $this->encryptionKey = $ukey;
      $this->encrypted=1;
      $uvalue=$this->ARC4($pad);

      $this->objects[$id]['info']['U']=$uvalue;
      $this->encryptionKey=$ukey;
     
      // initialize the arc4 array
      break;
    case 'out':
      $res= "\n".$id." 0 obj\n<<";
      $res.="\n/Filter /Standard";
      $res.="\n/V 1";
      $res.="\n/R 2";
      $res.="\n/O (".$this->filterText($o['info']['O']).')';
      $res.="\n/U (".$this->filterText($o['info']['U']).')';
      // and the p-value needs to be converted to account for the twos-complement approach
      $o['info']['p'] = (($o['info']['p']^255)+1)*-1;
      $res.="\n/P ".($o['info']['p']);
      $res.="\n>>\nendobj\n";
      
      return $res;
      break;
  }
}
      
/**
* ARC4 functions
* A series of function to implement ARC4 encoding in PHP
*/

/**
* calculate the 16 byte version of the 128 bit md5 digest of the string
*/
function md5_16($string){
  $tmp = md5($string);
  $out='';
  for ($i=0;$i<=30;$i=$i+2){
    $out.=chr(hexdec(substr($tmp,$i,2)));
  }
  return $out;
}

/**
* initialize the encryption for processing a particular object 
*/
function encryptInit($id){
  $tmp = $this->encryptionKey;
  $hex = dechex($id);
  if (strlen($hex)<6){
    $hex = substr('000000',0,6-strlen($hex)).$hex;
  }
  $tmp.= chr(hexdec(substr($hex,4,2))).chr(hexdec(substr($hex,2,2))).chr(hexdec(substr($hex,0,2))).chr(0).chr(0);
  $key = $this->md5_16($tmp);
  $this->ARC4_init(substr($key,0,10));
}

/**
* initialize the ARC4 encryption
*/
function ARC4_init($key=''){
  $this->arc4 = '';
  // setup the control array
  if (strlen($key)==0){
    return;
  }
  $k = '';
  while(strlen($k)<256){
    $k.=$key;
  }
  $k=substr($k,0,256);
  for ($i=0;$i<256;$i++){
    $this->arc4 .= chr($i);
  }
  $j=0;
  for ($i=0;$i<256;$i++){
    $t = $this->arc4[$i];
    $j = ($j + ord($t) + ord($k[$i]))%256;
    $this->arc4[$i]=$this->arc4[$j];
    $this->arc4[$j]=$t;
  }    
}

/**
* ARC4 encrypt a text string
*/
function ARC4($text){
  $len=strlen($text);
  $a=0;
  $b=0;
  $c = $this->arc4;
  $out='';
  for ($i=0;$i<$len;$i++){
    $a = ($a+1)%256;
    $t= $c[$a];
    $b = ($b+ord($t))%256;
    $c[$a]=$c[$b];
    $c[$b]=$t;
    $k = ord($c[(ord($c[$a])+ord($c[$b]))%256]);
    $out.=chr(ord($text[$i]) ^ $k);
  }
  
  return $out;
}

/**
* functions which can be called to adjust or add to the document
*/

/**
* add a link in the document to an external URL
*/
function addLink($url,$x0,$y0,$x1,$y1){
  $this->numObj++;
  $info = array('type'=>'link','url'=>$url,'rect'=>array($x0,$y0,$x1,$y1));
  $this->o_annotation($this->numObj,'new',$info);
}

/**
* add a link in the document to an internal destination (ie. within the document)
*/
function addInternalLink($label,$x0,$y0,$x1,$y1){
  $this->numObj++;
  $info = array('type'=>'ilink','label'=>$label,'rect'=>array($x0,$y0,$x1,$y1));
  $this->o_annotation($this->numObj,'new',$info);
}

/**
* set the encryption of the document
* can be used to turn it on and/or set the passwords which it will have.
* also the functions that the user will have are set here, such as print, modify, add
*/
function setEncryption($userPass='',$ownerPass='',$pc=array()){
  $p=bindec(11000000);

  $options = array(
     'print'=>4
    ,'modify'=>8
    ,'copy'=>16
    ,'add'=>32

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -