/**
  * Output the barcode
  *
  * Puts the barcode specified via settext() onto the PDF document.
  * The barcode is scaled to fit into the specified space.
  *
  * @param    float    $xpos     The left starting position
  * @param    float    $ypos     The top starting position
  * @param    float    $width    The width of the barcode
  * @param    float    $height   The height of the barcode
  *
  * @access   public
  */
 function putcode($xpos, $ypos, $width, $height)
 {
     switch ($this->type) {
         default:
         case '39':
             // code 39: narrow=4, wide=11, quiet=7
             $narrow = 4;
             $wide = 11;
             $quiet = 7;
             $convtable[0] = $narrow;
             $convtable[1] = $wide;
             $convtable[2] = $quiet;
             $text = $this->text;
             $codes = array();
             array_push($codes, $this->char2code39('START'));
             for ($i = 0; $i < strlen($text); $i++) {
                 array_push($codes, $this->char2code39(substr($text, $i, 1)));
             }
             array_push($codes, $this->char2code39('STOP'));
             $code = implode('2', $codes);
             // Total width is the sum of:
             // - Widths of the characters' barcode representation (plus
             //   start/stop characters)
             // - Widths of the blank spaces between them
             $fullwidth = (strlen($text) + 2) * (6 * $narrow + 3 * $wide) + (strlen($text) + 1) * $quiet;
             $basewidth = $width / $fullwidth;
             break;
         case '25i':
             $narrow = 1;
             $wide = 2;
             $convtable[0] = $narrow;
             $convtable[1] = $wide;
             $text = $this->text;
             // The length of the text must be even; if not, we
             // pad it with a leading "0"
             if (strlen($text) % 2 != 0) {
                 $text = "0" . $text;
             }
             $code = $this->char2code25i('START');
             for ($i = 0; $i < strlen($text); $i += 2) {
                 $code1 = $this->char2code25i(substr($text, $i, 1));
                 $code2 = $this->char2code25i(substr($text, $i + 1, 1));
                 // Interleaved code: Shake 'em up!
                 for ($j = 0; $j < 5; $j++) {
                     $code .= substr($code1, $j, 1);
                     $code .= substr($code2, $j, 1);
                 }
             }
             $code .= $this->char2code25i('STOP');
             // Total width is the sum of:
             // - Widths of the start/stop characters (6*narrow+1*wide)
             // - Widths of the characters' barcode representation
             $fullwidth = strlen($text) * (3 * $narrow + 2 * $wide) + 6 * $narrow + 1 * $wide;
             $basewidth = $width / $fullwidth;
             break;
         case '128a':
         case '128b':
         case '128c':
             $convtable[1] = 1;
             $convtable[2] = 2;
             $convtable[3] = 3;
             $convtable[4] = 4;
             $text = $this->text;
             switch ($this->type) {
                 case '128a':
                     $char2code128index = char2code128aindex;
                     break;
                 case '128b':
                     $char2code128index = char2code128bindex;
                     break;
                 case '128c':
                     $char2code128index = char2code128cindex;
                     // The length of the text must be even; if not, we
                     // pad it with a leading "0"
                     if (strlen($text) % 2 != 0) {
                         $text = "0" . $text;
                     }
                     break;
             }
             $checksum = 0;
             $index = $this->{$char2code128index}('START');
             $code = $this->code128table[$index];
             $checksum += $index;
             for ($i = 0; $i < strlen($text); $i++) {
                 if ($this->type == '128c') {
                     // 128c encodes two chars in one go
                     $index = $this->{$char2code128index}(substr($text, $i, 2));
                     $i++;
                 } else {
                     $index = $this->{$char2code128index}(substr($text, $i, 1));
                 }
                 $code .= $this->code128table[$index];
                 $checksum += ($i + 1) * $index;
             }
             // Calculate and output the code 128 checksum
             $checksum %= 103;
             $code .= $this->code128table[$checksum];
             $index = $this->{$char2code128index}('STOP');
             $code .= $this->code128table[$index];
             // Total width is the sum of:
             // - Widths of the start character's barcode representation (11)
             // - Widths of the text characters' barcode representation (11)
             // - Widths of the checksum character's barcode representation (11)
             // - Widths of the stop character's barcode representation (13)
             $fullwidth = (strlen($text) + 2) * 11 + 13;
             $basewidth = $width / $fullwidth;
             break;
     }
     $black = true;
     for ($i = 0; $i < strlen($code); $i++) {
         $barwidth = $convtable[$code[$i]] * $basewidth;
         if ($black) {
             PDF_setcolor($this->pdf, "both", "gray", 0, 0, 0, 0);
             PDF_setlinecap($this->pdf, 0);
             PDF_setlinewidth($this->pdf, $barwidth);
             PDF_moveto($this->pdf, $xpos + 0.5 * $barwidth, $ypos);
             PDF_lineto($this->pdf, $xpos + 0.5 * $barwidth, $ypos - $height);
             PDF_stroke($this->pdf);
         }
         $xpos += $barwidth;
         $black = !$black;
     }
     return 1;
 }
 /**
  * Close the table on the current page
  *
  * Draws the bottom border, the vertical table border, the
  * column spacing border and creates a new page.
  *
  * @access   public
  */
 function endtable()
 {
     if (sizeof($this->rowbuffer) > 0) {
         $rowbuffer = $this->rowbuffer;
         $this->rowbuffer = array();
         $this->addrow($rowbuffer);
     }
     if ($this->topborderwidth > 0) {
         if ($this->topbordercolor !== false) {
             PDF_setlinecap($this->pdf, 0);
             PDF_setlinewidth($this->pdf, $this->bottomborderwidth);
             $this->setcolor($this->bottombordercolor);
             PDF_moveto($this->pdf, $this->firstxpos, $this->ypos - 0.5 * $this->bottomborderwidth);
             PDF_lineto($this->pdf, $this->firstxpos + $this->width, $this->ypos - 0.5 * $this->bottomborderwidth);
             PDF_stroke($this->pdf);
         }
         $this->ypos -= $this->bottomborderwidth;
     }
     // When scheduled via setverttableborderwidth() and
     // setverttablebordercolor(), draw vertical lines on the left and
     // the right side of the table
     if ($this->verttableborderwidth && $this->verttablebordercolor !== false) {
         $this->setcolor($this->verttablebordercolor);
         PDF_setlinewidth($this->pdf, $this->verttableborderwidth);
         PDF_moveto($this->pdf, $this->firstxpos + 0.5 * $this->verttableborderwidth, $this->firstypos);
         PDF_lineto($this->pdf, $this->firstxpos + 0.5 * $this->verttableborderwidth, $this->ypos);
         PDF_stroke($this->pdf);
         PDF_moveto($this->pdf, $this->firstxpos + $this->width - 0.5 * $this->verttableborderwidth, $this->firstypos);
         PDF_lineto($this->pdf, $this->firstxpos + $this->width - 0.5 * $this->verttableborderwidth, $this->ypos);
         PDF_stroke($this->pdf);
     }
     // When scheduled via setcolspacingwidth() and
     // setcolspacingcolor(), draw lines between the
     // columns
     if ($this->colspacingwidth && $this->colspacingcolor !== false) {
         for ($c = 1; $c < sizeof($this->colparam); $c++) {
             $cp =& $this->colparam[$c];
             $borderpos = $cp->xpos - 0.5 * $this->colspacingwidth;
             $this->setcolor($this->colspacingcolor);
             PDF_setlinewidth($this->pdf, $this->colspacingwidth);
             PDF_moveto($this->pdf, $borderpos, $this->firstypos);
             PDF_lineto($this->pdf, $borderpos, $this->ypos);
             PDF_stroke($this->pdf);
         }
     }
     for ($c = 0; $c < sizeof($this->colparam); $c++) {
         $cp =& $this->colparam[$c];
         $cnp =& $cp->normcellparam;
         if ($cp->eotcallbackfn) {
             $fn = $cp->eotcallbackfn;
             $fn($cp->xpos, $cp->xpos + $cnp->leftborderwidth + $cnp->leftpadding, $cp->xpos + $cp->width - ($cnp->rightborderwidth + $cnp->rightpadding), $cp->xpos + $cp->width, $this->ypos);
         }
     }
 }