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

📄 class.pdf.php

📁 完美的在线教育系统
💻 PHP
📖 第 1 页 / 共 5 页
字号:
  if ($set && isset($this->fonts[$fontName])){
    // so if for some reason the font was not set in the last one then it will not be selected
    $this->currentBaseFont=$fontName;
    // the next line means that if a new font is selected, then the current text state will be
    // applied to it as well.
    $this->setCurrentFont();
  }
  return $this->currentFontNum;
}

/**
* sets up the current font, based on the font families, and the current text state
* note that this system is quite flexible, a <b><i> font can be completely different to a
* <i><b> font, and even <b><b> will have to be defined within the family to have meaning
* This function is to be called whenever the currentTextState is changed, it will update
* the currentFont setting to whatever the appropriatte family one is.
* If the user calls selectFont themselves then that will reset the currentBaseFont, and the currentFont
* This function will change the currentFont to whatever it should be, but will not change the 
* currentBaseFont.
*
* @access private
*/
function setCurrentFont(){
  if (strlen($this->currentBaseFont)==0){
    // then assume an initial font
    $this->selectFont('./fonts/Helvetica.afm');
  }
  $cf = substr($this->currentBaseFont,strrpos($this->currentBaseFont,'/')+1);
  if (strlen($this->currentTextState)
    && isset($this->fontFamilies[$cf]) 
      && isset($this->fontFamilies[$cf][$this->currentTextState])){
    // then we are in some state or another
    // and this font has a family, and the current setting exists within it
    // select the font, then return it
    $nf = substr($this->currentBaseFont,0,strrpos($this->currentBaseFont,'/')+1).$this->fontFamilies[$cf][$this->currentTextState];
    $this->selectFont($nf,'',0);
    $this->currentFont = $nf;
    $this->currentFontNum = $this->fonts[$nf]['fontNum'];
  } else {
    // the this font must not have the right family member for the current state
    // simply assume the base font
    $this->currentFont = $this->currentBaseFont;
    $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum'];    
  }
}

/**
* function for the user to find out what the ID is of the first page that was created during
* startup - useful if they wish to add something to it later.
*/
function getFirstPageId(){
  return $this->firstPageId;
}

/**
* add content to the currently active object
*
* @access private
*/
function addContent($content){
  $this->objects[$this->currentContents]['c'].=$content;
}

/**
* sets the colour for fill operations
*/
function setColor($r,$g,$b,$force=0){
  if ($r>=0 && ($force || $r!=$this->currentColour['r'] || $g!=$this->currentColour['g'] || $b!=$this->currentColour['b'])){
    $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$r).' '.sprintf('%.3f',$g).' '.sprintf('%.3f',$b).' rg';
    $this->currentColour=array('r'=>$r,'g'=>$g,'b'=>$b);
  }
}

/**
* sets the colour for stroke operations
*/
function setStrokeColor($r,$g,$b,$force=0){
  if ($r>=0 && ($force || $r!=$this->currentStrokeColour['r'] || $g!=$this->currentStrokeColour['g'] || $b!=$this->currentStrokeColour['b'])){
    $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$r).' '.sprintf('%.3f',$g).' '.sprintf('%.3f',$b).' RG';
    $this->currentStrokeColour=array('r'=>$r,'g'=>$g,'b'=>$b);
  }
}

/**
* draw a line from one set of coordinates to another
*/
function line($x1,$y1,$x2,$y2){
  $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$x1).' '.sprintf('%.3f',$y1).' m '.sprintf('%.3f',$x2).' '.sprintf('%.3f',$y2).' l S';
}

/**
* draw a bezier curve based on 4 control points
*/
function curve($x0,$y0,$x1,$y1,$x2,$y2,$x3,$y3){
  // in the current line style, draw a bezier curve from (x0,y0) to (x3,y3) using the other two points
  // as the control points for the curve.
  $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$x0).' '.sprintf('%.3f',$y0).' m '.sprintf('%.3f',$x1).' '.sprintf('%.3f',$y1);
  $this->objects[$this->currentContents]['c'].= ' '.sprintf('%.3f',$x2).' '.sprintf('%.3f',$y2).' '.sprintf('%.3f',$x3).' '.sprintf('%.3f',$y3).' c S';
}

/**
* draw a part of an ellipse
*/
function partEllipse($x0,$y0,$astart,$afinish,$r1,$r2=0,$angle=0,$nSeg=8){
  $this->ellipse($x0,$y0,$r1,$r2,$angle,$nSeg,$astart,$afinish,0);
}

/**
* draw a filled ellipse
*/
function filledEllipse($x0,$y0,$r1,$r2=0,$angle=0,$nSeg=8,$astart=0,$afinish=360){
  return $this->ellipse($x0,$y0,$r1,$r2=0,$angle,$nSeg,$astart,$afinish,1,1);
}

/**
* draw an ellipse
* note that the part and filled ellipse are just special cases of this function
*
* draws an ellipse in the current line style
* centered at $x0,$y0, radii $r1,$r2
* if $r2 is not set, then a circle is drawn
* nSeg is not allowed to be less than 2, as this will simply draw a line (and will even draw a 
* pretty crappy shape at 2, as we are approximating with bezier curves.
*/
function ellipse($x0,$y0,$r1,$r2=0,$angle=0,$nSeg=8,$astart=0,$afinish=360,$close=1,$fill=0){
  if ($r1==0){
    return;
  }
  if ($r2==0){
    $r2=$r1;
  }
  if ($nSeg<2){
    $nSeg=2;
  }

  $astart = deg2rad((float)$astart);
  $afinish = deg2rad((float)$afinish);
  $totalAngle =$afinish-$astart;

  $dt = $totalAngle/$nSeg;
  $dtm = $dt/3;

  if ($angle != 0){
    $a = -1*deg2rad((float)$angle);
    $tmp = "\n q ";
    $tmp .= sprintf('%.3f',cos($a)).' '.sprintf('%.3f',(-1.0*sin($a))).' '.sprintf('%.3f',sin($a)).' '.sprintf('%.3f',cos($a)).' ';
    $tmp .= sprintf('%.3f',$x0).' '.sprintf('%.3f',$y0).' cm';
    $this->objects[$this->currentContents]['c'].= $tmp;
    $x0=0;
    $y0=0;
  }

  $t1 = $astart;
  $a0 = $x0+$r1*cos($t1);
  $b0 = $y0+$r2*sin($t1);
  $c0 = -$r1*sin($t1);
  $d0 = $r2*cos($t1);

  $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$a0).' '.sprintf('%.3f',$b0).' m ';
  for ($i=1;$i<=$nSeg;$i++){
    // draw this bit of the total curve
    $t1 = $i*$dt+$astart;
    $a1 = $x0+$r1*cos($t1);
    $b1 = $y0+$r2*sin($t1);
    $c1 = -$r1*sin($t1);
    $d1 = $r2*cos($t1);
    $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',($a0+$c0*$dtm)).' '.sprintf('%.3f',($b0+$d0*$dtm));
    $this->objects[$this->currentContents]['c'].= ' '.sprintf('%.3f',($a1-$c1*$dtm)).' '.sprintf('%.3f',($b1-$d1*$dtm)).' '.sprintf('%.3f',$a1).' '.sprintf('%.3f',$b1).' c';
    $a0=$a1;
    $b0=$b1;
    $c0=$c1;
    $d0=$d1;    
  }
  if ($fill){
    $this->objects[$this->currentContents]['c'].=' f';
  } else {
    if ($close){

      $this->objects[$this->currentContents]['c'].=' s'; // small 's' signifies closing the path as well
    } else {
      $this->objects[$this->currentContents]['c'].=' S';
    }
  }
  if ($angle !=0){
    $this->objects[$this->currentContents]['c'].=' Q';
  }
}

/**
* this sets the line drawing style.
* width, is the thickness of the line in user units
* cap is the type of cap to put on the line, values can be 'butt','round','square'
*    where the diffference between 'square' and 'butt' is that 'square' projects a flat end past the
*    end of the line.
* join can be 'miter', 'round', 'bevel'
* dash is an array which sets the dash pattern, is a series of length values, which are the lengths of the
*   on and off dashes.
*   (2) represents 2 on, 2 off, 2 on , 2 off ...
*   (2,1) is 2 on, 1 off, 2 on, 1 off.. etc
* phase is a modifier on the dash pattern which is used to shift the point at which the pattern starts. 
*/
function setLineStyle($width=1,$cap='',$join='',$dash='',$phase=0){

  // this is quite inefficient in that it sets all the parameters whenever 1 is changed, but will fix another day
  $string = '';
  if ($width>0){
    $string.= $width.' w';
  }
  $ca = array('butt'=>0,'round'=>1,'square'=>2);
  if (isset($ca[$cap])){
    $string.= ' '.$ca[$cap].' J';
  }
  $ja = array('miter'=>0,'round'=>1,'bevel'=>2);
  if (isset($ja[$join])){
    $string.= ' '.$ja[$join].' j';
  }
  if (is_array($dash)){
    $string.= ' [';
    foreach ($dash as $len){
      $string.=' '.$len;
    }
    $string.= ' ] '.$phase.' d';
  }
  $this->currentLineStyle = $string;
  $this->objects[$this->currentContents]['c'].="\n".$string;
}

/**
* draw a polygon, the syntax for this is similar to the GD polygon command
*/
function polygon($p,$np,$f=0){
  $this->objects[$this->currentContents]['c'].="\n";
  $this->objects[$this->currentContents]['c'].=sprintf('%.3f',$p[0]).' '.sprintf('%.3f',$p[1]).' m ';
  for ($i=2;$i<$np*2;$i=$i+2){
    $this->objects[$this->currentContents]['c'].= sprintf('%.3f',$p[$i]).' '.sprintf('%.3f',$p[$i+1]).' l ';
  }
  if ($f==1){
    $this->objects[$this->currentContents]['c'].=' f';
  } else {
    $this->objects[$this->currentContents]['c'].=' S';
  }
}

/**
* a filled rectangle, note that it is the width and height of the rectangle which are the secondary paramaters, not
* the coordinates of the upper-right corner
*/
function filledRectangle($x1,$y1,$width,$height){
  $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$x1).' '.sprintf('%.3f',$y1).' '.sprintf('%.3f',$width).' '.sprintf('%.3f',$height).' re f';
}

/**
* draw a rectangle, note that it is the width and height of the rectangle which are the secondary paramaters, not
* the coordinates of the upper-right corner
*/
function rectangle($x1,$y1,$width,$height){
  $this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$x1).' '.sprintf('%.3f',$y1).' '.sprintf('%.3f',$width).' '.sprintf('%.3f',$height).' re S';
}

/**
* add a new page to the document
* this also makes the new page the current active object
*/
function newPage($insert=0,$id=0,$pos='after'){

  // if there is a state saved, then go up the stack closing them
  // then on the new page, re-open them with the right setings
  
  if ($this->nStateStack){
    for ($i=$this->nStateStack;$i>=1;$i--){
      $this->restoreState($i);
    }
  }

  $this->numObj++;
  if ($insert){
    // the id from the ezPdf class is the od of the contents of the page, not the page object itself
    // query that object to find the parent
    $rid = $this->objects[$id]['onPage'];
    $opt= array('rid'=>$rid,'pos'=>$pos);
    $this->o_page($this->numObj,'new',$opt);
  } else {
    $this->o_page($this->numObj,'new');
  }
  // if there is a stack saved, then put that onto the page
  if ($this->nStateStack){
    for ($i=1;$i<=$this->nStateStack;$i++){
      $this->saveState($i);
    }
  }  
  // and if there has been a stroke or fill colour set, then transfer them
  if ($this->currentColour['r']>=0){
    $this->setColor($this->currentColour['r'],$this->currentColour['g'],$this->currentColour['b'],1);
  }
  if ($this->currentStrokeColour['r']>=0){
    $this->setStrokeColor($this->currentStrokeColour['r'],$this->currentStrokeColour['g'],$this->currentStrokeColour['b'],1);
  }

  // if there is a line style set, then put this in too
  if (strlen($this->currentLineStyle)){
    $this->objects[$this->currentContents]['c'].="\n".$this->currentLineStyle;
  }

  // the call to the o_page object set currentContents to the present page, so this can be returned as the page id
  return $this->currentContents;
}

/**
* output the pdf code, streaming it to the browser
* the relevant headers are set so that hopefully the browser will recognise it
*/
function stream($options=''){
  // setting the options allows the adjustment of the headers
  // values at the moment are:
  // 'Content-Disposition'=>'filename'  - sets the filename, though not too sure how well this will 
  //        work as in my trial the browser seems to use the filename of the php file with .pdf on the end
  // 'Accept-Ranges'=>1 or 0 - if this is not set to 1, then this header is not included, off by default
  //    this header seems to have caused some problems despite tha fact that it is supposed to solve
  //    them, so I am leaving it off by default.
  // 'compress'=> 1 or 0 - apply content stream compression, this is on (1) by default
  if (!is_array($options)){
    $options=array();
  }
  if ( isset($options['compress']) && $options['compress']==0){
    $tmp = $this->output(1);
  } else {
    $tmp = $this->output();
  }
  header("Content-type: application/pdf");
  header("Content-Length: ".strlen(ltrim($tmp)));
  $fileName = (isset($options['Content-Disposition'])?$options['Content-Disposition']:'file.pdf');
  header("Content-Disposition: inline; filename=".$fileName);
  if (isset($options['Accept-Ranges']) && $options['Accept-Ranges']==1){
    header("Accept-Ranges: ".strlen(ltrim($tmp))); 
  }
  echo ltrim($tmp);
}

/**
* return the height in units of the current font in the given size
*/
function getFontHeight($size){
  if (!$this->numFonts){
    $this->selectFont('./fonts/Helvetica');
  }
  // for the current font, and the given size, what is the height of the font in user units
  $h = $this->fonts[$this->currentFont]['FontBBox'][3]-$this->fonts[$this->currentFont]['FontBBox'][1];
  return $size*$h/1000;
}

/**
* return the font decender, this will normally return a negative number
* if you add this number to the baseline, you get the level of the bottom of the font
* it is in the pdf user units
*/
function getFontDecender($size){
  // note that this will most likely return a negative value
  if (!$this->numFonts){
    $this->selectFont('./fonts/Helvetica');
  }
  $h = $this->fonts[$this->currentFont]['FontBBox'][1];
  return $size*$h/1000;
}

/**
* filter the text, this is applied to all text just before being inserted into the pdf document
* it escapes the various things that need to be escaped, and so on
*
* @access private
*/
function filterText($text){
  $text = str_replace('\\','\\\\',$text);
  $text = str_replace('(','\(',$text);
  $text = str_replace(')','\)',$text);
  $text = str_replace('&lt;','<',$text);
  $text = str_replace('&gt;','>',$text);
  $text = str_replace('&#039;','\'',$text);
  $text = str_replace('&quot;','"',$text);
  $text = str_replace('&amp;','&',$text);

  return $text;
}

/**
* given a start position and information about how text is to be laid out, calculate where 
* on the page the text will end
*
* @access private
*/
function PRVTgetTextPosition($x,$y,$angle,$size,$wa,$text){
  // given this information return an array containing x and y for the end position as elements 0 and 1
  $w = $this->getTextWidth($size,$text);
  // need to adjust for the number of spaces in this text
  $words = explode(' ',$text);
  $nspaces=count($words)-1;
  $w += $wa*$nspaces;
  $a = deg2rad((float)$angle);
  r

⌨️ 快捷键说明

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