tecnickcom/tc-lib-barcode

Incorrect Data Matrix

Xclynaj opened this issue · 4 comments

For the string 0&0&0&0&0&0&0_ the library generates an unreadable Data Matrix barcode. And the string 0&0&0&0&0&0&0 turns into 0&0&0&0&0&0&{0.
<?php require ('vendor/autoload.php'); $barcode = new \Com\Tecnick\Barcode\Barcode(); $bobj = $barcode->getBarcodeObj('DATAMATRIX', '0&0&0&0&0&0&_', -4, -4); echo $bobj->getHtmlDiv(); echo "<p></p>"; $bobj = $barcode->getBarcodeObj('DATAMATRIX', '0&0&0&0&0&0&0', -4, -4); echo $bobj->getHtmlDiv();
Bug?
PHP 7.1.1 and 7.4.10, Windows 7 SP1 x64.

The same error in my code , it adds the "{" before the last character.

If I understood correctly ISO/IEC 16022:2006 "Information technology - Automatic identification and data capture techniques - Data Matrix bar code symbology specification", then it is necessary to correct the encodeEDFfour function located in src/Type/Square/Datamatrix/Encode.php, for example:

public function encodeEDFfour($epos, &$cdw, &$cdw_num, &$pos, &$data_length, &$field_length, &$enc, &$temp_cw)
{
    // BEFORE FIX
    // if (($epos == $data_length) && ($field_length < 3)) {
        // $enc = Data::ENC_ASCII;
        // $cdw[] = $this->getSwitchEncodingCodeword($enc);
        // ++$cdw_num;
        // return true;
    // }
    // AFTER FIX
    if ($epos == $data_length) {
      $enc = Data::ENC_ASCII;
      $exp_cdw_num = $cdw_num + $field_length;
      foreach (Data::$symbattr[$this->shape] as $params) {
        if ($params[11] >= $exp_cdw_num) {
          $exp_paddings_num = $params[11] - $exp_cdw_num;
          break;
        }
      }
      if ($field_length + $exp_paddings_num > 2) {
        $cdw[] = $this->getSwitchEncodingCodeword($enc);
        ++$cdw_num;
      }
      return true;
    }
    // END OF FIX
    if ($field_length < 4) {
        // set unlatch character
        $temp_cw[] = 0x1f;
        ++$field_length;
        // fill empty characters
        for ($i = $field_length; $i < 4; ++$i) {
            $temp_cw[] = 0;
        }
        $enc = Data::ENC_ASCII;
        $this->last_enc = $enc;
    }
    // encodes four data characters in three codewords
    // BEFORE FIX
    // $cdw[] = (($temp_cw[0] & 0x3F) << 2) + (($temp_cw[1] & 0x30) >> 4);
    // $cdw[] = (($temp_cw[1] & 0x0F) << 4) + (($temp_cw[2] & 0x3C) >> 2);
    // $cdw[] = (($temp_cw[2] & 0x03) << 6) + ($temp_cw[3] & 0x3F);
    // $cdw_num += 3;
    // AFTER FIX
    if ($field_length > 0) {
      $cdw[] = (($temp_cw[0] & 0x3F) << 2) + (($temp_cw[1] & 0x30) >> 4);
      $cdw_num++;
    }
    if ($field_length > 1) {
      $cdw[] = (($temp_cw[1] & 0x0F) << 4) + (($temp_cw[2] & 0x3C) >> 2);
      $cdw_num++;
    }
    if ($field_length > 2) {
      $cdw[] = (($temp_cw[2] & 0x03) << 6) + ($temp_cw[3] & 0x3F);
      $cdw_num++;
    }
    // END OF FIX
    $temp_cw = array();
    $pos = $epos;
    $field_length = 0;
    if ($enc == Data::ENC_ASCII) {
        return true; // exit from EDIFACT mode
    }
    return false;
}

Sorry, this is my first time on github. I do not know English and have not yet figured out how everything works here.

Fixed in #62