Milon\Barcode\PDF417::__construct PHP Метод

__construct() публичный Метод

Creates a PDF417 object
public __construct ( $code, $ecl, $aspectratio = 2, $macro = [] )
$code (string) code to represent using PDF417
$ecl (int) error correction level (0-8); default -1 = automatic correction level
$aspectratio (float) the width to height of the symbol (excluding quiet zones)
$macro (array) information for macro block
    public function __construct($code, $ecl = -1, $aspectratio = 2, $macro = array())
    {
        $barcode_array = array();
        if (is_null($code) or $code == '\\0' or $code == '') {
            return false;
        }
        // get the input sequence array
        $sequence = $this->getInputSequences($code);
        $codewords = array();
        // array of code-words
        foreach ($sequence as $seq) {
            $cw = $this->getCompaction($seq[0], $seq[1], true);
            $codewords = array_merge($codewords, $cw);
        }
        if ($codewords[0] == 900) {
            // Text Alpha is the default mode, so remove the first code
            array_shift($codewords);
        }
        // count number of codewords
        $numcw = count($codewords);
        if ($numcw > 925) {
            // reached maximum data codeword capacity
            return false;
        }
        // build macro control block codewords
        if (!empty($macro)) {
            $macrocw = array();
            // beginning of macro control block
            $macrocw[] = 928;
            // segment index
            $cw = $this->getCompaction(902, sprintf('%05d', $macro['segment_index']), false);
            $macrocw = array_merge($macrocw, $cw);
            // file ID
            $cw = $this->getCompaction(900, $macro['file_id'], false);
            $macrocw = array_merge($macrocw, $cw);
            // optional fields
            $optmodes = array(900, 902, 902, 900, 900, 902, 902);
            $optsize = array(-1, 2, 4, -1, -1, -1, 2);
            foreach ($optmodes as $k => $omode) {
                if (isset($macro['option_' . $k])) {
                    $macrocw[] = 923;
                    $macrocw[] = $k;
                    if ($optsize[$k] == 2) {
                        $macro['option_' . $k] = sprintf('%05d', $macro['option_' . $k]);
                    } elseif ($optsize[$k] == 4) {
                        $macro['option_' . $k] = sprintf('%010d', $macro['option_' . $k]);
                    }
                    $cw = $this->getCompaction($omode, $macro['option_' . $k], false);
                    $macrocw = array_merge($macrocw, $cw);
                }
            }
            if ($macro['segment_index'] == $macro['segment_total'] - 1) {
                // end of control block
                $macrocw[] = 922;
            }
            // update total codewords
            $numcw += count($macrocw);
        }
        // set error correction level
        $ecl = $this->getErrorCorrectionLevel($ecl, $numcw);
        // number of codewords for error correction
        $errsize = 2 << $ecl;
        // calculate number of columns (number of codewords per row) and rows
        $nce = $numcw + $errsize + 1;
        $cols = round((sqrt(4761 + 68 * $aspectratio * ROWHEIGHT * $nce) - 69) / 34);
        // adjust cols
        if ($cols < 1) {
            $cols = 1;
        } elseif ($cols > 30) {
            $cols = 30;
        }
        $rows = ceil($nce / $cols);
        $size = $cols * $rows;
        // adjust rows
        if ($rows < 3 or $rows > 90) {
            if ($rows < 3) {
                $rows = 3;
            } elseif ($rows > 90) {
                $rows = 90;
            }
            $cols = ceil($size / $rows);
            $size = $cols * $rows;
        }
        if ($size > 928) {
            // set dimensions to get maximum capacity
            if (abs($aspectratio - 17 * 29 / 32) < abs($aspectratio - 17 * 16 / 58)) {
                $cols = 29;
                $rows = 32;
            } else {
                $cols = 16;
                $rows = 58;
            }
            $size = 928;
        }
        // calculate padding
        $pad = $size - $nce;
        if ($pad > 0) {
            if ($size - $rows == $nce) {
                --$rows;
                $size -= $rows;
            } else {
                // add pading
                $codewords = array_merge($codewords, array_fill(0, $pad, 900));
            }
        }
        if (!empty($macro)) {
            // add macro section
            $codewords = array_merge($codewords, $macrocw);
        }
        // Symbol Lenght Descriptor (number of data codewords including Symbol Lenght Descriptor and pad codewords)
        $sld = $size - $errsize;
        // add symbol length description
        array_unshift($codewords, $sld);
        // calculate error correction
        $ecw = $this->getErrorCorrection($codewords, $ecl);
        // add error correction codewords
        $codewords = array_merge($codewords, $ecw);
        // add horizontal quiet zones to start and stop patterns
        $pstart = str_repeat('0', QUIETH) . $this->start_pattern;
        $pstop = $this->stop_pattern . str_repeat('0', QUIETH);
        $barcode_array['num_rows'] = $rows * ROWHEIGHT + 2 * QUIETV;
        $barcode_array['num_cols'] = ($cols + 2) * 17 + 35 + 2 * QUIETH;
        $barcode_array['bcode'] = array();
        // build rows for vertical quiet zone
        if (QUIETV > 0) {
            $empty_row = array_fill(0, $barcode_array['num_cols'], 0);
            for ($i = 0; $i < QUIETV; ++$i) {
                // add vertical quiet rows
                $barcode_array['bcode'][] = $empty_row;
            }
        }
        $k = 0;
        // codeword index
        $cid = 0;
        // initial cluster
        // for each row
        for ($r = 0; $r < $rows; ++$r) {
            // row start code
            $row = $pstart;
            switch ($cid) {
                case 0:
                    $L = 30 * intval($r / 3) + intval(($rows - 1) / 3);
                    break;
                case 1:
                    $L = 30 * intval($r / 3) + $ecl * 3 + ($rows - 1) % 3;
                    break;
                case 2:
                    $L = 30 * intval($r / 3) + ($cols - 1);
                    break;
            }
            // left row indicator
            $row .= sprintf('%17b', $this->clusters[$cid][$L]);
            // for each column
            for ($c = 0; $c < $cols; ++$c) {
                $row .= sprintf('%17b', $this->clusters[$cid][$codewords[$k]]);
                ++$k;
            }
            switch ($cid) {
                case 0:
                    $L = 30 * intval($r / 3) + ($cols - 1);
                    break;
                case 1:
                    $L = 30 * intval($r / 3) + intval(($rows - 1) / 3);
                    break;
                case 2:
                    $L = 30 * intval($r / 3) + $ecl * 3 + ($rows - 1) % 3;
                    break;
            }
            // right row indicator
            $row .= sprintf('%17b', $this->clusters[$cid][$L]);
            // row stop code
            $row .= $pstop;
            // convert the string to array
            $arow = preg_split('//', $row, -1, PREG_SPLIT_NO_EMPTY);
            // duplicate row to get the desired height
            for ($h = 0; $h < ROWHEIGHT; ++$h) {
                $barcode_array['bcode'][] = $arow;
            }
            ++$cid;
            if ($cid > 2) {
                $cid = 0;
            }
        }
        if (QUIETV > 0) {
            for ($i = 0; $i < QUIETV; ++$i) {
                // add vertical quiet rows
                $barcode_array['bcode'][] = $empty_row;
            }
        }
        $this->barcode_array = $barcode_array;
    }