diff options
author | Christopher Speller <crspeller@gmail.com> | 2016-05-12 15:08:58 -0400 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2016-05-12 16:37:29 -0400 |
commit | 84d2482ddbff9564c9ad75b2d30af66e3ddfd44d (patch) | |
tree | 8bfa567d2b6381f4a996ada2deff8a16aa85a3ac /Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr.go | |
parent | d1efb66ad7b017f0fbfe6f0c20843b30f396e504 (diff) | |
download | chat-84d2482ddbff9564c9ad75b2d30af66e3ddfd44d.tar.gz chat-84d2482ddbff9564c9ad75b2d30af66e3ddfd44d.tar.bz2 chat-84d2482ddbff9564c9ad75b2d30af66e3ddfd44d.zip |
Updating go depencancies. Switching to go1.6 vendoring (#2949)
Diffstat (limited to 'Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr.go')
-rw-r--r-- | Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr.go | 815 |
1 files changed, 0 insertions, 815 deletions
diff --git a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr.go b/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr.go deleted file mode 100644 index 35711a4eb..000000000 --- a/Godeps/_workspace/src/github.com/mattermost/rsc/qr/coding/qr.go +++ /dev/null @@ -1,815 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package coding implements low-level QR coding details. -package coding - -import ( - "fmt" - "strconv" - "strings" - - "github.com/mattermost/rsc/gf256" -) - -// Field is the field for QR error correction. -var Field = gf256.NewField(0x11d, 2) - -// A Version represents a QR version. -// The version specifies the size of the QR code: -// a QR code with version v has 4v+17 pixels on a side. -// Versions number from 1 to 40: the larger the version, -// the more information the code can store. -type Version int - -const MinVersion = 1 -const MaxVersion = 40 - -func (v Version) String() string { - return strconv.Itoa(int(v)) -} - -func (v Version) sizeClass() int { - if v <= 9 { - return 0 - } - if v <= 26 { - return 1 - } - return 2 -} - -// DataBytes returns the number of data bytes that can be -// stored in a QR code with the given version and level. -func (v Version) DataBytes(l Level) int { - vt := &vtab[v] - lev := &vt.level[l] - return vt.bytes - lev.nblock*lev.check -} - -// Encoding implements a QR data encoding scheme. -// The implementations--Numeric, Alphanumeric, and String--specify -// the character set and the mapping from UTF-8 to code bits. -// The more restrictive the mode, the fewer code bits are needed. -type Encoding interface { - Check() error - Bits(v Version) int - Encode(b *Bits, v Version) -} - -type Bits struct { - b []byte - nbit int -} - -func (b *Bits) Reset() { - b.b = b.b[:0] - b.nbit = 0 -} - -func (b *Bits) Bits() int { - return b.nbit -} - -func (b *Bits) Bytes() []byte { - if b.nbit%8 != 0 { - panic("fractional byte") - } - return b.b -} - -func (b *Bits) Append(p []byte) { - if b.nbit%8 != 0 { - panic("fractional byte") - } - b.b = append(b.b, p...) - b.nbit += 8 * len(p) -} - -func (b *Bits) Write(v uint, nbit int) { - for nbit > 0 { - n := nbit - if n > 8 { - n = 8 - } - if b.nbit%8 == 0 { - b.b = append(b.b, 0) - } else { - m := -b.nbit & 7 - if n > m { - n = m - } - } - b.nbit += n - sh := uint(nbit - n) - b.b[len(b.b)-1] |= uint8(v >> sh << uint(-b.nbit&7)) - v -= v >> sh << sh - nbit -= n - } -} - -// Num is the encoding for numeric data. -// The only valid characters are the decimal digits 0 through 9. -type Num string - -func (s Num) String() string { - return fmt.Sprintf("Num(%#q)", string(s)) -} - -func (s Num) Check() error { - for _, c := range s { - if c < '0' || '9' < c { - return fmt.Errorf("non-numeric string %#q", string(s)) - } - } - return nil -} - -var numLen = [3]int{10, 12, 14} - -func (s Num) Bits(v Version) int { - return 4 + numLen[v.sizeClass()] + (10*len(s)+2)/3 -} - -func (s Num) Encode(b *Bits, v Version) { - b.Write(1, 4) - b.Write(uint(len(s)), numLen[v.sizeClass()]) - var i int - for i = 0; i+3 <= len(s); i += 3 { - w := uint(s[i]-'0')*100 + uint(s[i+1]-'0')*10 + uint(s[i+2]-'0') - b.Write(w, 10) - } - switch len(s) - i { - case 1: - w := uint(s[i] - '0') - b.Write(w, 4) - case 2: - w := uint(s[i]-'0')*10 + uint(s[i+1]-'0') - b.Write(w, 7) - } -} - -// Alpha is the encoding for alphanumeric data. -// The valid characters are 0-9A-Z$%*+-./: and space. -type Alpha string - -const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" - -func (s Alpha) String() string { - return fmt.Sprintf("Alpha(%#q)", string(s)) -} - -func (s Alpha) Check() error { - for _, c := range s { - if strings.IndexRune(alphabet, c) < 0 { - return fmt.Errorf("non-alphanumeric string %#q", string(s)) - } - } - return nil -} - -var alphaLen = [3]int{9, 11, 13} - -func (s Alpha) Bits(v Version) int { - return 4 + alphaLen[v.sizeClass()] + (11*len(s)+1)/2 -} - -func (s Alpha) Encode(b *Bits, v Version) { - b.Write(2, 4) - b.Write(uint(len(s)), alphaLen[v.sizeClass()]) - var i int - for i = 0; i+2 <= len(s); i += 2 { - w := uint(strings.IndexRune(alphabet, rune(s[i])))*45 + - uint(strings.IndexRune(alphabet, rune(s[i+1]))) - b.Write(w, 11) - } - - if i < len(s) { - w := uint(strings.IndexRune(alphabet, rune(s[i]))) - b.Write(w, 6) - } -} - -// String is the encoding for 8-bit data. All bytes are valid. -type String string - -func (s String) String() string { - return fmt.Sprintf("String(%#q)", string(s)) -} - -func (s String) Check() error { - return nil -} - -var stringLen = [3]int{8, 16, 16} - -func (s String) Bits(v Version) int { - return 4 + stringLen[v.sizeClass()] + 8*len(s) -} - -func (s String) Encode(b *Bits, v Version) { - b.Write(4, 4) - b.Write(uint(len(s)), stringLen[v.sizeClass()]) - for i := 0; i < len(s); i++ { - b.Write(uint(s[i]), 8) - } -} - -// A Pixel describes a single pixel in a QR code. -type Pixel uint32 - -const ( - Black Pixel = 1 << iota - Invert -) - -func (p Pixel) Offset() uint { - return uint(p >> 6) -} - -func OffsetPixel(o uint) Pixel { - return Pixel(o << 6) -} - -func (r PixelRole) Pixel() Pixel { - return Pixel(r << 2) -} - -func (p Pixel) Role() PixelRole { - return PixelRole(p>>2) & 15 -} - -func (p Pixel) String() string { - s := p.Role().String() - if p&Black != 0 { - s += "+black" - } - if p&Invert != 0 { - s += "+invert" - } - s += "+" + strconv.FormatUint(uint64(p.Offset()), 10) - return s -} - -// A PixelRole describes the role of a QR pixel. -type PixelRole uint32 - -const ( - _ PixelRole = iota - Position // position squares (large) - Alignment // alignment squares (small) - Timing // timing strip between position squares - Format // format metadata - PVersion // version pattern - Unused // unused pixel - Data // data bit - Check // error correction check bit - Extra -) - -var roles = []string{ - "", - "position", - "alignment", - "timing", - "format", - "pversion", - "unused", - "data", - "check", - "extra", -} - -func (r PixelRole) String() string { - if Position <= r && r <= Check { - return roles[r] - } - return strconv.Itoa(int(r)) -} - -// A Level represents a QR error correction level. -// From least to most tolerant of errors, they are L, M, Q, H. -type Level int - -const ( - L Level = iota - M - Q - H -) - -func (l Level) String() string { - if L <= l && l <= H { - return "LMQH"[l : l+1] - } - return strconv.Itoa(int(l)) -} - -// A Code is a square pixel grid. -type Code struct { - Bitmap []byte // 1 is black, 0 is white - Size int // number of pixels on a side - Stride int // number of bytes per row -} - -func (c *Code) Black(x, y int) bool { - return 0 <= x && x < c.Size && 0 <= y && y < c.Size && - c.Bitmap[y*c.Stride+x/8]&(1<<uint(7-x&7)) != 0 -} - -// A Mask describes a mask that is applied to the QR -// code to avoid QR artifacts being interpreted as -// alignment and timing patterns (such as the squares -// in the corners). Valid masks are integers from 0 to 7. -type Mask int - -// http://www.swetake.com/qr/qr5_en.html -var mfunc = []func(int, int) bool{ - func(i, j int) bool { return (i+j)%2 == 0 }, - func(i, j int) bool { return i%2 == 0 }, - func(i, j int) bool { return j%3 == 0 }, - func(i, j int) bool { return (i+j)%3 == 0 }, - func(i, j int) bool { return (i/2+j/3)%2 == 0 }, - func(i, j int) bool { return i*j%2+i*j%3 == 0 }, - func(i, j int) bool { return (i*j%2+i*j%3)%2 == 0 }, - func(i, j int) bool { return (i*j%3+(i+j)%2)%2 == 0 }, -} - -func (m Mask) Invert(y, x int) bool { - if m < 0 { - return false - } - return mfunc[m](y, x) -} - -// A Plan describes how to construct a QR code -// with a specific version, level, and mask. -type Plan struct { - Version Version - Level Level - Mask Mask - - DataBytes int // number of data bytes - CheckBytes int // number of error correcting (checksum) bytes - Blocks int // number of data blocks - - Pixel [][]Pixel // pixel map -} - -// NewPlan returns a Plan for a QR code with the given -// version, level, and mask. -func NewPlan(version Version, level Level, mask Mask) (*Plan, error) { - p, err := vplan(version) - if err != nil { - return nil, err - } - if err := fplan(level, mask, p); err != nil { - return nil, err - } - if err := lplan(version, level, p); err != nil { - return nil, err - } - if err := mplan(mask, p); err != nil { - return nil, err - } - return p, nil -} - -func (b *Bits) Pad(n int) { - if n < 0 { - panic("qr: invalid pad size") - } - if n <= 4 { - b.Write(0, n) - } else { - b.Write(0, 4) - n -= 4 - n -= -b.Bits() & 7 - b.Write(0, -b.Bits()&7) - pad := n / 8 - for i := 0; i < pad; i += 2 { - b.Write(0xec, 8) - if i+1 >= pad { - break - } - b.Write(0x11, 8) - } - } -} - -func (b *Bits) AddCheckBytes(v Version, l Level) { - nd := v.DataBytes(l) - if b.nbit < nd*8 { - b.Pad(nd*8 - b.nbit) - } - if b.nbit != nd*8 { - panic("qr: too much data") - } - - dat := b.Bytes() - vt := &vtab[v] - lev := &vt.level[l] - db := nd / lev.nblock - extra := nd % lev.nblock - chk := make([]byte, lev.check) - rs := gf256.NewRSEncoder(Field, lev.check) - for i := 0; i < lev.nblock; i++ { - if i == lev.nblock-extra { - db++ - } - rs.ECC(dat[:db], chk) - b.Append(chk) - dat = dat[db:] - } - - if len(b.Bytes()) != vt.bytes { - panic("qr: internal error") - } -} - -func (p *Plan) Encode(text ...Encoding) (*Code, error) { - var b Bits - for _, t := range text { - if err := t.Check(); err != nil { - return nil, err - } - t.Encode(&b, p.Version) - } - if b.Bits() > p.DataBytes*8 { - return nil, fmt.Errorf("cannot encode %d bits into %d-bit code", b.Bits(), p.DataBytes*8) - } - b.AddCheckBytes(p.Version, p.Level) - bytes := b.Bytes() - - // Now we have the checksum bytes and the data bytes. - // Construct the actual code. - c := &Code{Size: len(p.Pixel), Stride: (len(p.Pixel) + 7) &^ 7} - c.Bitmap = make([]byte, c.Stride*c.Size) - crow := c.Bitmap - for _, row := range p.Pixel { - for x, pix := range row { - switch pix.Role() { - case Data, Check: - o := pix.Offset() - if bytes[o/8]&(1<<uint(7-o&7)) != 0 { - pix ^= Black - } - } - if pix&Black != 0 { - crow[x/8] |= 1 << uint(7-x&7) - } - } - crow = crow[c.Stride:] - } - return c, nil -} - -// A version describes metadata associated with a version. -type version struct { - apos int - astride int - bytes int - pattern int - level [4]level -} - -type level struct { - nblock int - check int -} - -var vtab = []version{ - {}, - {100, 100, 26, 0x0, [4]level{{1, 7}, {1, 10}, {1, 13}, {1, 17}}}, // 1 - {16, 100, 44, 0x0, [4]level{{1, 10}, {1, 16}, {1, 22}, {1, 28}}}, // 2 - {20, 100, 70, 0x0, [4]level{{1, 15}, {1, 26}, {2, 18}, {2, 22}}}, // 3 - {24, 100, 100, 0x0, [4]level{{1, 20}, {2, 18}, {2, 26}, {4, 16}}}, // 4 - {28, 100, 134, 0x0, [4]level{{1, 26}, {2, 24}, {4, 18}, {4, 22}}}, // 5 - {32, 100, 172, 0x0, [4]level{{2, 18}, {4, 16}, {4, 24}, {4, 28}}}, // 6 - {20, 16, 196, 0x7c94, [4]level{{2, 20}, {4, 18}, {6, 18}, {5, 26}}}, // 7 - {22, 18, 242, 0x85bc, [4]level{{2, 24}, {4, 22}, {6, 22}, {6, 26}}}, // 8 - {24, 20, 292, 0x9a99, [4]level{{2, 30}, {5, 22}, {8, 20}, {8, 24}}}, // 9 - {26, 22, 346, 0xa4d3, [4]level{{4, 18}, {5, 26}, {8, 24}, {8, 28}}}, // 10 - {28, 24, 404, 0xbbf6, [4]level{{4, 20}, {5, 30}, {8, 28}, {11, 24}}}, // 11 - {30, 26, 466, 0xc762, [4]level{{4, 24}, {8, 22}, {10, 26}, {11, 28}}}, // 12 - {32, 28, 532, 0xd847, [4]level{{4, 26}, {9, 22}, {12, 24}, {16, 22}}}, // 13 - {24, 20, 581, 0xe60d, [4]level{{4, 30}, {9, 24}, {16, 20}, {16, 24}}}, // 14 - {24, 22, 655, 0xf928, [4]level{{6, 22}, {10, 24}, {12, 30}, {18, 24}}}, // 15 - {24, 24, 733, 0x10b78, [4]level{{6, 24}, {10, 28}, {17, 24}, {16, 30}}}, // 16 - {28, 24, 815, 0x1145d, [4]level{{6, 28}, {11, 28}, {16, 28}, {19, 28}}}, // 17 - {28, 26, 901, 0x12a17, [4]level{{6, 30}, {13, 26}, {18, 28}, {21, 28}}}, // 18 - {28, 28, 991, 0x13532, [4]level{{7, 28}, {14, 26}, {21, 26}, {25, 26}}}, // 19 - {32, 28, 1085, 0x149a6, [4]level{{8, 28}, {16, 26}, {20, 30}, {25, 28}}}, // 20 - {26, 22, 1156, 0x15683, [4]level{{8, 28}, {17, 26}, {23, 28}, {25, 30}}}, // 21 - {24, 24, 1258, 0x168c9, [4]level{{9, 28}, {17, 28}, {23, 30}, {34, 24}}}, // 22 - {28, 24, 1364, 0x177ec, [4]level{{9, 30}, {18, 28}, {25, 30}, {30, 30}}}, // 23 - {26, 26, 1474, 0x18ec4, [4]level{{10, 30}, {20, 28}, {27, 30}, {32, 30}}}, // 24 - {30, 26, 1588, 0x191e1, [4]level{{12, 26}, {21, 28}, {29, 30}, {35, 30}}}, // 25 - {28, 28, 1706, 0x1afab, [4]level{{12, 28}, {23, 28}, {34, 28}, {37, 30}}}, // 26 - {32, 28, 1828, 0x1b08e, [4]level{{12, 30}, {25, 28}, {34, 30}, {40, 30}}}, // 27 - {24, 24, 1921, 0x1cc1a, [4]level{{13, 30}, {26, 28}, {35, 30}, {42, 30}}}, // 28 - {28, 24, 2051, 0x1d33f, [4]level{{14, 30}, {28, 28}, {38, 30}, {45, 30}}}, // 29 - {24, 26, 2185, 0x1ed75, [4]level{{15, 30}, {29, 28}, {40, 30}, {48, 30}}}, // 30 - {28, 26, 2323, 0x1f250, [4]level{{16, 30}, {31, 28}, {43, 30}, {51, 30}}}, // 31 - {32, 26, 2465, 0x209d5, [4]level{{17, 30}, {33, 28}, {45, 30}, {54, 30}}}, // 32 - {28, 28, 2611, 0x216f0, [4]level{{18, 30}, {35, 28}, {48, 30}, {57, 30}}}, // 33 - {32, 28, 2761, 0x228ba, [4]level{{19, 30}, {37, 28}, {51, 30}, {60, 30}}}, // 34 - {28, 24, 2876, 0x2379f, [4]level{{19, 30}, {38, 28}, {53, 30}, {63, 30}}}, // 35 - {22, 26, 3034, 0x24b0b, [4]level{{20, 30}, {40, 28}, {56, 30}, {66, 30}}}, // 36 - {26, 26, 3196, 0x2542e, [4]level{{21, 30}, {43, 28}, {59, 30}, {70, 30}}}, // 37 - {30, 26, 3362, 0x26a64, [4]level{{22, 30}, {45, 28}, {62, 30}, {74, 30}}}, // 38 - {24, 28, 3532, 0x27541, [4]level{{24, 30}, {47, 28}, {65, 30}, {77, 30}}}, // 39 - {28, 28, 3706, 0x28c69, [4]level{{25, 30}, {49, 28}, {68, 30}, {81, 30}}}, // 40 -} - -func grid(siz int) [][]Pixel { - m := make([][]Pixel, siz) - pix := make([]Pixel, siz*siz) - for i := range m { - m[i], pix = pix[:siz], pix[siz:] - } - return m -} - -// vplan creates a Plan for the given version. -func vplan(v Version) (*Plan, error) { - p := &Plan{Version: v} - if v < 1 || v > 40 { - return nil, fmt.Errorf("invalid QR version %d", int(v)) - } - siz := 17 + int(v)*4 - m := grid(siz) - p.Pixel = m - - // Timing markers (overwritten by boxes). - const ti = 6 // timing is in row/column 6 (counting from 0) - for i := range m { - p := Timing.Pixel() - if i&1 == 0 { - p |= Black - } - m[i][ti] = p - m[ti][i] = p - } - - // Position boxes. - posBox(m, 0, 0) - posBox(m, siz-7, 0) - posBox(m, 0, siz-7) - - // Alignment boxes. - info := &vtab[v] - for x := 4; x+5 < siz; { - for y := 4; y+5 < siz; { - // don't overwrite timing markers - if (x < 7 && y < 7) || (x < 7 && y+5 >= siz-7) || (x+5 >= siz-7 && y < 7) { - } else { - alignBox(m, x, y) - } - if y == 4 { - y = info.apos - } else { - y += info.astride - } - } - if x == 4 { - x = info.apos - } else { - x += info.astride - } - } - - // Version pattern. - pat := vtab[v].pattern - if pat != 0 { - v := pat - for x := 0; x < 6; x++ { - for y := 0; y < 3; y++ { - p := PVersion.Pixel() - if v&1 != 0 { - p |= Black - } - m[siz-11+y][x] = p - m[x][siz-11+y] = p - v >>= 1 - } - } - } - - // One lonely black pixel - m[siz-8][8] = Unused.Pixel() | Black - - return p, nil -} - -// fplan adds the format pixels -func fplan(l Level, m Mask, p *Plan) error { - // Format pixels. - fb := uint32(l^1) << 13 // level: L=01, M=00, Q=11, H=10 - fb |= uint32(m) << 10 // mask - const formatPoly = 0x537 - rem := fb - for i := 14; i >= 10; i-- { - if rem&(1<<uint(i)) != 0 { - rem ^= formatPoly << uint(i-10) - } - } - fb |= rem - invert := uint32(0x5412) - siz := len(p.Pixel) - for i := uint(0); i < 15; i++ { - pix := Format.Pixel() + OffsetPixel(i) - if (fb>>i)&1 == 1 { - pix |= Black - } - if (invert>>i)&1 == 1 { - pix ^= Invert | Black - } - // top left - switch { - case i < 6: - p.Pixel[i][8] = pix - case i < 8: - p.Pixel[i+1][8] = pix - case i < 9: - p.Pixel[8][7] = pix - default: - p.Pixel[8][14-i] = pix - } - // bottom right - switch { - case i < 8: - p.Pixel[8][siz-1-int(i)] = pix - default: - p.Pixel[siz-1-int(14-i)][8] = pix - } - } - return nil -} - -// lplan edits a version-only Plan to add information -// about the error correction levels. -func lplan(v Version, l Level, p *Plan) error { - p.Level = l - - nblock := vtab[v].level[l].nblock - ne := vtab[v].level[l].check - nde := (vtab[v].bytes - ne*nblock) / nblock - extra := (vtab[v].bytes - ne*nblock) % nblock - dataBits := (nde*nblock + extra) * 8 - checkBits := ne * nblock * 8 - - p.DataBytes = vtab[v].bytes - ne*nblock - p.CheckBytes = ne * nblock - p.Blocks = nblock - - // Make data + checksum pixels. - data := make([]Pixel, dataBits) - for i := range data { - data[i] = Data.Pixel() | OffsetPixel(uint(i)) - } - check := make([]Pixel, checkBits) - for i := range check { - check[i] = Check.Pixel() | OffsetPixel(uint(i+dataBits)) - } - - // Split into blocks. - dataList := make([][]Pixel, nblock) - checkList := make([][]Pixel, nblock) - for i := 0; i < nblock; i++ { - // The last few blocks have an extra data byte (8 pixels). - nd := nde - if i >= nblock-extra { - nd++ - } - dataList[i], data = data[0:nd*8], data[nd*8:] - checkList[i], check = check[0:ne*8], check[ne*8:] - } - if len(data) != 0 || len(check) != 0 { - panic("data/check math") - } - - // Build up bit sequence, taking first byte of each block, - // then second byte, and so on. Then checksums. - bits := make([]Pixel, dataBits+checkBits) - dst := bits - for i := 0; i < nde+1; i++ { - for _, b := range dataList { - if i*8 < len(b) { - copy(dst, b[i*8:(i+1)*8]) - dst = dst[8:] - } - } - } - for i := 0; i < ne; i++ { - for _, b := range checkList { - if i*8 < len(b) { - copy(dst, b[i*8:(i+1)*8]) - dst = dst[8:] - } - } - } - if len(dst) != 0 { - panic("dst math") - } - - // Sweep up pair of columns, - // then down, assigning to right then left pixel. - // Repeat. - // See Figure 2 of http://www.pclviewer.com/rs2/qrtopology.htm - siz := len(p.Pixel) - rem := make([]Pixel, 7) - for i := range rem { - rem[i] = Extra.Pixel() - } - src := append(bits, rem...) - for x := siz; x > 0; { - for y := siz - 1; y >= 0; y-- { - if p.Pixel[y][x-1].Role() == 0 { - p.Pixel[y][x-1], src = src[0], src[1:] - } - if p.Pixel[y][x-2].Role() == 0 { - p.Pixel[y][x-2], src = src[0], src[1:] - } - } - x -= 2 - if x == 7 { // vertical timing strip - x-- - } - for y := 0; y < siz; y++ { - if p.Pixel[y][x-1].Role() == 0 { - p.Pixel[y][x-1], src = src[0], src[1:] - } - if p.Pixel[y][x-2].Role() == 0 { - p.Pixel[y][x-2], src = src[0], src[1:] - } - } - x -= 2 - } - return nil -} - -// mplan edits a version+level-only Plan to add the mask. -func mplan(m Mask, p *Plan) error { - p.Mask = m - for y, row := range p.Pixel { - for x, pix := range row { - if r := pix.Role(); (r == Data || r == Check || r == Extra) && p.Mask.Invert(y, x) { - row[x] ^= Black | Invert - } - } - } - return nil -} - -// posBox draws a position (large) box at upper left x, y. -func posBox(m [][]Pixel, x, y int) { - pos := Position.Pixel() - // box - for dy := 0; dy < 7; dy++ { - for dx := 0; dx < 7; dx++ { - p := pos - if dx == 0 || dx == 6 || dy == 0 || dy == 6 || 2 <= dx && dx <= 4 && 2 <= dy && dy <= 4 { - p |= Black - } - m[y+dy][x+dx] = p - } - } - // white border - for dy := -1; dy < 8; dy++ { - if 0 <= y+dy && y+dy < len(m) { - if x > 0 { - m[y+dy][x-1] = pos - } - if x+7 < len(m) { - m[y+dy][x+7] = pos - } - } - } - for dx := -1; dx < 8; dx++ { - if 0 <= x+dx && x+dx < len(m) { - if y > 0 { - m[y-1][x+dx] = pos - } - if y+7 < len(m) { - m[y+7][x+dx] = pos - } - } - } -} - -// alignBox draw an alignment (small) box at upper left x, y. -func alignBox(m [][]Pixel, x, y int) { - // box - align := Alignment.Pixel() - for dy := 0; dy < 5; dy++ { - for dx := 0; dx < 5; dx++ { - p := align - if dx == 0 || dx == 4 || dy == 0 || dy == 4 || dx == 2 && dy == 2 { - p |= Black - } - m[y+dy][x+dx] = p - } - } -} |