diff --git a/example/go.mod b/example/go.mod index b8d8df6..3da8cae 100644 --- a/example/go.mod +++ b/example/go.mod @@ -5,7 +5,7 @@ go 1.17 require ( github.com/yeqown/go-qrcode v1.5.10 github.com/yeqown/go-qrcode/v2 v2.0.1 - github.com/yeqown/go-qrcode/writer/standard v1.0.0-beta + github.com/yeqown/go-qrcode/writer/standard v1.1.1 github.com/yeqown/go-qrcode/writer/terminal v1.0.0-beta ) @@ -19,6 +19,6 @@ require ( golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect ) -//replace github.com/yeqown/go-qrcode/v2 v2.0.1 => ../ -//replace github.com/yeqown/go-qrcode/writer/standard v1.0.0-beta => ../writer/standard +replace github.com/yeqown/go-qrcode/v2 => ../ +replace github.com/yeqown/go-qrcode/writer/standard => ../writer/standard //replace github.com/yeqown/go-qrcode/writer/terminal v1.0.0-beta => ../writer/terminal diff --git a/matrix/matrix.go b/matrix/matrix.go index 93fb38e..961aae0 100644 --- a/matrix/matrix.go +++ b/matrix/matrix.go @@ -20,26 +20,26 @@ const ( type State uint16 const ( - // StateFalse 0xffff FALSE - StateFalse State = 0xffff + // StateInit represents the initial block state of the matrix + StateInit State = iota + // ZERO represents the initial state. + // Deprecated: use StateInit instead + ZERO = StateInit - // ZERO 0x0 FALSE - ZERO State = 0xeeee + // StateFalse represents the block has been set to false + StateFalse State = 0x1 - // StateTrue 0x0 TRUE - StateTrue State = 0x0 + // StateTrue represents the block has been set to TRUE + StateTrue State = 0x2 - // StateInit 0x9999 use for initial state - StateInit State = 0x9999 + // StateVersion indicates the version block of matrix + StateVersion State = 0x3 - // StateVersion 0x4444 - StateVersion State = 0x4444 + // StateFormat indicates the format block of matrix + StateFormat State = 0x4 - // StateFormat 0x7777 for persisted state - StateFormat State = 0x7777 - - // StateFinder 0x8000 to locate matrix and recognize it. - StateFinder State = 0x8000 + // StateFinder indicates the finder block of matrix + StateFinder State = 0x5 ) func (s State) String() string { @@ -153,13 +153,13 @@ func (m *Matrix) Set(w, h int, c State) error { return nil } -// Get state value from matrix with postion (x, y) +// Get state value from matrix with position {x, y} func (m *Matrix) Get(w, h int) (State, error) { if w >= m.width || w < 0 { - return ZERO, ErrorOutRangeOfW + return StateInit, ErrorOutRangeOfW } if h >= m.height || h < 0 { - return ZERO, ErrorOutRangeOfH + return StateInit, ErrorOutRangeOfH } return m.mat[w][h], nil } diff --git a/matrix/matrix_test.go b/matrix/matrix_test.go index e90a137..20ccb4b 100644 --- a/matrix/matrix_test.go +++ b/matrix/matrix_test.go @@ -3,31 +3,23 @@ package matrix import ( "reflect" "testing" + + "github.com/stretchr/testify/assert" ) func TestMatrix(t *testing.T) { m := New(3, 3) m.print() - if err := m.Set(2, 4, ZERO); err == nil { - t.Errorf("want err, got nil") - t.Fail() - } - - // if err := m.Reset(2, 4); err == nil { - // t.Errorf("want err, got nil") - // t.Fail() - // } + err := m.Set(2, 4, StateTrue) + assert.Error(t, err) - if err := m.Set(2, 2, StateInit); err != nil { - t.Errorf("want nil, got err: %v", err) - t.Fail() - } + err = m.Set(2, 2, StateTrue) + assert.NoError(t, err) - if v, err := m.Get(2, 2); err != nil || v != StateInit { - t.Errorf("want true, got %v and err: %v", v, err) - t.Fail() - } + v, err2 := m.Get(2, 2) + assert.NoError(t, err2) + assert.Equal(t, StateTrue, v) m.print() // m.Reset(2, 2) @@ -78,12 +70,12 @@ func TestState_String(t *testing.T) { { name: "case 1", s: StateFalse, - want: "0xFFFF", + want: "0x1", }, { name: "case 2", s: StateTrue, - want: "0x0", + want: "0x2", }, } for _, tt := range tests { diff --git a/qrcode.go b/qrcode.go index eb7ee5e..a1e3fff 100644 --- a/qrcode.go +++ b/qrcode.go @@ -513,65 +513,60 @@ func reserveVersionBlock(m *matrix.Matrix, dimension int) { } } -// fillIntoMatrix fill q.dataBSet bitset stream into q.mat, ref to: -// http://www.thonky.com/qr-code-tutorial/module-placement-matrix -func (q *QRCode) fillIntoMatrix(m *matrix.Matrix, dimension int) { +// fillDataBinary fill q.dataBSet binary stream into q.mat. +// References: +// * http://www.thonky.com/qr-code-tutorial/module-placement-matrix#Place-the-Data-Bits +// +func (q *QRCode) fillDataBinary(m *matrix.Matrix, dimension int) { var ( + // x always move from right, left right loop (2 rows), y move upward, downward, upward loop x, y = dimension - 1, dimension - 1 l = q.dataBSet.Len() upForward = true - mod2, pos int - - setState, state matrix.State - // turn = false // if last loop, changed forward, this is true - // downForward = false - // once sync.Once - err error + pos int ) for i := 0; pos < l; i++ { - // debugLogf("fillIntoMatrix: dimension: %d, len: %d: pos: %d", dimension, l, pos) - - state, err = m.Get(x, y) - if err == matrix.ErrorOutRangeOfW { - break - } - + // debugLogf("fillDataBinary: dimension: %d, len: %d: pos: %d", dimension, l, pos) + set := matrix.StateFalse if q.dataBSet.At(pos) { - setState = matrix.StateTrue - } else { - setState = matrix.StateFalse + set = matrix.StateTrue } - if state == matrix.StateInit { - _ = m.Set(x, y, setState) - pos++ - // debugLogf("normal set turn forward: upForward: %v, x: %d, y: %d", upForward, x, y) - } else if state == matrix.ZERO { - // turn forward and the new forward's block first pos as value - if upForward { - x = x - 2 - y = y + 1 - } else { - x = x - 2 - y = y - 1 + state, err := m.Get(x, y) + if err != nil { + if err == matrix.ErrorOutRangeOfW { + break } - if x == 7 || x == 6 { - x = x - 1 + if err == matrix.ErrorOutRangeOfH { + // turn around while y is out of range. + x = x - 2 + switch upForward { + case true: + y = y + 1 + default: + y = y - 1 + } + + if x == 7 || x == 6 { + x = x - 1 + } + upForward = !upForward + state, err = m.Get(x, y) // renew state value after turn around writing direction. } + } - upForward = !upForward - // debugLogf("unmoral state turn forward: upForward: %v, x: %d, y: %d", upForward, x, y) - if s, _ := m.Get(x, y); s == matrix.StateInit { - _ = m.Set(x, y, setState) - pos++ - } + // data bit should only be set into un-set block in matrix. + if state == matrix.StateInit { + _ = m.Set(x, y, set) + pos++ + debugLogf("normal set turn forward: upForward: %v, x: %d, y: %d", upForward, x, y) } // DO NOT CHANGE FOLLOWING CODE FOR NOW !!! // change x, y - mod2 = i % 2 + mod2 := i % 2 // in one 8bit block if upForward { @@ -624,7 +619,7 @@ func (q *QRCode) masking() { wg.Add(1) go func(i int) { // fill bitset into matrix - q.fillIntoMatrix(mats[i], dimension) + q.fillDataBinary(mats[i], dimension) _ = debugDraw(fmt.Sprintf("draft/mats_%d.jpeg", i), *mats[i]) _ = debugDraw(fmt.Sprintf("draft/mask_%d.jpeg", i), *masks[i].mat)