rqrcode 0.10.1 → 1.0.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +13 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +108 -136
  6. data/Rakefile +10 -0
  7. data/_config.yml +1 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/images/ansi-screen-shot.png +0 -0
  11. data/images/github-qrcode.png +0 -0
  12. data/images/github-qrcode.svg +32 -0
  13. data/lib/rqrcode.rb +8 -19
  14. data/lib/rqrcode/export.rb +6 -0
  15. data/lib/rqrcode/export/ansi.rb +14 -15
  16. data/lib/rqrcode/export/html.rb +6 -8
  17. data/lib/rqrcode/export/png.rb +18 -19
  18. data/lib/rqrcode/export/svg.rb +7 -6
  19. data/lib/rqrcode/qrcode.rb +3 -4
  20. data/lib/rqrcode/qrcode/qrcode.rb +17 -0
  21. data/lib/rqrcode/version.rb +3 -1
  22. data/rqrcode.gemspec +36 -0
  23. metadata +67 -56
  24. data/CHANGELOG +0 -97
  25. data/LICENSE +0 -19
  26. data/lib/rqrcode/core_ext.rb +0 -5
  27. data/lib/rqrcode/core_ext/array.rb +0 -5
  28. data/lib/rqrcode/core_ext/array/behavior.rb +0 -12
  29. data/lib/rqrcode/core_ext/integer.rb +0 -5
  30. data/lib/rqrcode/core_ext/integer/bitwise.rb +0 -13
  31. data/lib/rqrcode/qrcode/qr_8bit_byte.rb +0 -36
  32. data/lib/rqrcode/qrcode/qr_alphanumeric.rb +0 -47
  33. data/lib/rqrcode/qrcode/qr_bit_buffer.rb +0 -99
  34. data/lib/rqrcode/qrcode/qr_code.rb +0 -585
  35. data/lib/rqrcode/qrcode/qr_math.rb +0 -63
  36. data/lib/rqrcode/qrcode/qr_numeric.rb +0 -57
  37. data/lib/rqrcode/qrcode/qr_polynomial.rb +0 -78
  38. data/lib/rqrcode/qrcode/qr_rs_block.rb +0 -314
  39. data/lib/rqrcode/qrcode/qr_util.rb +0 -272
  40. data/test/data.rb +0 -25
  41. data/test/test_helper.rb +0 -5
  42. data/test/test_regresions.rb +0 -10
  43. data/test/test_rqrcode.rb +0 -155
  44. data/test/test_rqrcode_export.rb +0 -27
data/CHANGELOG DELETED
@@ -1,97 +0,0 @@
1
- *0.10.1* (Feb 11, 2016)
2
-
3
- - Changed so that gem wont include images and tests.
4
-
5
- *0.10.0* (Feb 11, 2016)
6
-
7
- - Merged as_ansi by [Andy Brody](https://github.com/ab)
8
-
9
- *0.8.2* (Jan 3, 2016)
10
-
11
- - Fix source encoding problem introduced in 0.8.1
12
-
13
- *0.9.0* (Jan 3, 2016)
14
-
15
- - Added support for auto selecting qrcode size up to level 40. (only worked up to level 10 before)
16
- - Added numeric support during auto selection of qrcode mode.
17
-
18
- *0.8.1* (Jan 3, 2016)
19
-
20
- - Remove active support specific `present?`.
21
- - Fix so that all tests are run.
22
-
23
- *0.8.0* (Dec 18, 2015)
24
-
25
- - Added numeric QR code support
26
- - Dropped Ruby v1.8 support
27
-
28
- *0.7.0* (Aug 15, 2015)
29
-
30
- - Added shape_rendering option for as_svg
31
-
32
- *0.6.0* (Jun 2, 2015)
33
-
34
- - Improved png rendering. Previous png rendering could result in hard to scan qrcodes.
35
- *Big thanks to Bart Jedrocha*
36
-
37
- *0.5.5* (Apr 25, 2015)
38
-
39
- - Fixed major bug. The rs block data was missing resulting in qr codes failing to be generated.
40
- *Upgrade highly recomended!!*
41
-
42
- *0.5.4* (Nov 11th, 2013)
43
-
44
- * Added as_html, Big thanks to Jon Evans!
45
-
46
- *0.4.2* (Sep 1st, 2011)
47
-
48
- * Proper namespace CoreExtensions and only extend when needed [https://github.com/metaskills]
49
- * fix for running tests on 1.9
50
-
51
- *0.4.1* (Aug 16th, 2011)
52
-
53
- * Compute common patterns only once (5% to 10% speedup) [https://github.com/gioele]
54
-
55
- *0.4.0* (Aug 13th, 2011)
56
-
57
- * Code optimization: 30% speedup [https://github.com/gioele]
58
- * refactor gem layout
59
-
60
- *0.3.4* (May 23rd, 2011)
61
-
62
- * add the more Rubyish QRCode#dark? alias for #is_dark [https://github.com/dasch]
63
-
64
- *0.3.3* (Feb 1st, 2011)
65
-
66
- * check to see if the level is valid
67
- * fix for 'rszf' bug by [Rob la Lau https://github.com/ohreally]
68
-
69
- *0.3.2* (Mar 15th, 2009)
70
-
71
- * Ruby 1.9 fixes by [Tore Darell http://tore.darell.no] [Chris Mowforth http://blog.99th.st]
72
-
73
- *0.3.1* (Nov 24th, 2008)
74
-
75
- * expanded RS block table to QRcode version 40 [Vladislav Gorodetskiy]
76
-
77
- *0.3.0* (Feb 28th, 2008)
78
-
79
- * added more documentation
80
- * changed to_console to to_s (what was I thinking)
81
- * add more tests
82
-
83
- *0.2.1* (Feb 24th, 2008)
84
-
85
- * small changes to rakefile and readme
86
- * small change to to_console method
87
- * make console_count method private (use modules.size instead)
88
- * slowy updating rdocs
89
-
90
- *0.2.0* (Feb 23rd, 2008)
91
-
92
- * Split files up [DR]
93
- * added rdoc comment ... more to do there
94
-
95
- *0.1.0* (Feb 22rd, 2008)
96
-
97
- * Initial Release [DR]
data/LICENSE DELETED
@@ -1,19 +0,0 @@
1
- Copyright (c) 2008 Duncan Robertson
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to
5
- deal in the Software without restriction, including without limitation the
6
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
- sell copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in
11
- all copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
- THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
-
@@ -1,5 +0,0 @@
1
- Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].sort.each do |path|
2
- filename = File.basename(path)
3
- require "rqrcode/core_ext/#{filename}"
4
- end
5
-
@@ -1,5 +0,0 @@
1
- require 'rqrcode/core_ext/array/behavior'
2
-
3
- class Array #:nodoc:
4
- include RQRCode::CoreExtensions::Array::Behavior
5
- end
@@ -1,12 +0,0 @@
1
- module RQRCode
2
- module CoreExtensions #:nodoc:
3
- module Array #:nodoc:
4
- module Behavior
5
- def extract_options!
6
- last.is_a?(::Hash) ? pop : {}
7
- end unless [].respond_to?(:extract_options!)
8
- end
9
- end
10
- end
11
- end
12
-
@@ -1,5 +0,0 @@
1
- require 'rqrcode/core_ext/integer/bitwise'
2
-
3
- class Integer #:nodoc:
4
- include RQRCode::CoreExtensions::Integer::Bitwise
5
- end
@@ -1,13 +0,0 @@
1
- module RQRCode
2
- module CoreExtensions #:nodoc:
3
- module Integer #:nodoc:
4
- module Bitwise
5
- def rszf(count)
6
- # zero fill right shift
7
- (self >> count) & ((2 ** ((self.size * 8) - count))-1)
8
- end
9
- end
10
- end
11
- end
12
- end
13
-
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- #--
4
- # Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
5
- # All rights reserved.
6
-
7
- # Permission is granted for use, copying, modification, distribution,
8
- # and distribution of modified versions of this work as long as the
9
- # above copyright notice is included.
10
- #++
11
-
12
- module RQRCode
13
-
14
- class QR8bitByte
15
- attr_reader :mode
16
-
17
- def initialize( data )
18
- @mode = QRMODE[:mode_8bit_byte]
19
- @data = data;
20
- end
21
-
22
-
23
- def get_length
24
- @data.bytesize
25
- end
26
-
27
-
28
- def write( buffer)
29
- buffer.byte_encoding_start(get_length)
30
- @data.each_byte do |b|
31
- buffer.put(b, 8)
32
- end
33
- end
34
- end
35
-
36
- end
@@ -1,47 +0,0 @@
1
- module RQRCode
2
-
3
- ALPHANUMERIC = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',' ','$','%','*','+','-','.','/',':']
4
-
5
- class QRAlphanumeric
6
- attr_reader :mode
7
-
8
- def initialize( data )
9
- @mode = QRMODE[:mode_alpha_numk]
10
-
11
- raise QRCodeArgumentError, "Not a alpha numeric uppercase string `#{data}`" unless QRAlphanumeric.valid_data?(data)
12
-
13
- @data = data;
14
- end
15
-
16
-
17
- def get_length
18
- @data.size
19
- end
20
-
21
- def self.valid_data? data
22
- data.each_char do |s|
23
- return false if ALPHANUMERIC.index(s).nil?
24
- end
25
- true
26
- end
27
-
28
-
29
- def write( buffer)
30
- buffer.alphanumeric_encoding_start(get_length)
31
-
32
- (@data.size).times do |i|
33
- if i % 2 == 0
34
- if i == (@data.size - 1)
35
- value = ALPHANUMERIC.index(@data[i])
36
- buffer.put( value, 6 )
37
- else
38
- value = (ALPHANUMERIC.index(@data[i]) * 45) + ALPHANUMERIC.index(@data[i+1])
39
- buffer.put( value, 11 )
40
- end
41
- end
42
- end
43
-
44
-
45
- end
46
- end
47
- end
@@ -1,99 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- #--
4
- # Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
5
- # All rights reserved.
6
-
7
- # Permission is granted for use, copying, modification, distribution,
8
- # and distribution of modified versions of this work as long as the
9
- # above copyright notice is included.
10
- #++
11
-
12
- module RQRCode
13
-
14
- class QRBitBuffer
15
- attr_reader :buffer
16
-
17
- PAD0 = 0xEC
18
- PAD1 = 0x11
19
-
20
- def initialize(version)
21
- @version = version
22
- @buffer = []
23
- @length = 0
24
- end
25
-
26
-
27
- def get( index )
28
- buf_index = (index / 8).floor
29
- (( (@buffer[buf_index]).rszf(7 - index % 8)) & 1) == 1
30
- end
31
-
32
-
33
- def put( num, length )
34
- ( 0...length ).each do |i|
35
- put_bit((((num).rszf(length - i - 1)) & 1) == 1)
36
- end
37
- end
38
-
39
-
40
- def get_length_in_bits
41
- @length
42
- end
43
-
44
-
45
- def put_bit( bit )
46
- buf_index = ( @length / 8 ).floor
47
- if @buffer.size <= buf_index
48
- @buffer << 0
49
- end
50
-
51
- if bit
52
- @buffer[buf_index] |= ((0x80).rszf(@length % 8))
53
- end
54
-
55
- @length += 1
56
- end
57
-
58
- def byte_encoding_start(length)
59
-
60
- put( QRMODE[:mode_8bit_byte], 4 )
61
- put(length, QRUtil.get_length_in_bits(QRMODE[:mode_8bit_byte], @version))
62
-
63
- end
64
-
65
- def alphanumeric_encoding_start(length)
66
-
67
- put( QRMODE[:mode_alpha_numk], 4 )
68
- put(length, QRUtil.get_length_in_bits(QRMODE[:mode_alpha_numk], @version))
69
-
70
- end
71
-
72
- def numeric_encoding_start(length)
73
-
74
- put( QRMODE[:mode_number], 4 )
75
- put(length, QRUtil.get_length_in_bits(QRMODE[:mode_number], @version))
76
-
77
- end
78
-
79
- def pad_until(prefered_size)
80
- # Align on byte
81
- while get_length_in_bits % 8 != 0
82
- put_bit( false )
83
- end
84
-
85
- # Pad with padding code words
86
- while get_length_in_bits < prefered_size
87
- put( QRBitBuffer::PAD0, 8 )
88
- put( QRBitBuffer::PAD1, 8 ) if get_length_in_bits < prefered_size
89
- end
90
- end
91
-
92
- def end_of_message(max_data_bits)
93
- put( 0, 4 ) unless get_length_in_bits+4 > max_data_bits
94
- end
95
-
96
-
97
- end
98
-
99
- end
@@ -1,585 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- #--
4
- # Copyright 2008 by Duncan Robertson (duncan@whomwah.com).
5
- # All rights reserved.
6
-
7
- # Permission is granted for use, copying, modification, distribution,
8
- # and distribution of modified versions of this work as long as the
9
- # above copyright notice is included.
10
- #++
11
-
12
- module RQRCode #:nodoc:
13
-
14
- QRMODE = {
15
- :mode_number => 1 << 0,
16
- :mode_alpha_numk => 1 << 1,
17
- :mode_8bit_byte => 1 << 2,
18
- }
19
-
20
- QRMODE_NAME = {
21
- :number => :mode_number,
22
- :alphanumeric => :mode_alpha_numk,
23
- :byte_8bit => :mode_8bit_byte
24
- }
25
-
26
- QRERRORCORRECTLEVEL = {
27
- :l => 1,
28
- :m => 0,
29
- :q => 3,
30
- :h => 2
31
- }
32
-
33
- QRMASKPATTERN = {
34
- :pattern000 => 0,
35
- :pattern001 => 1,
36
- :pattern010 => 2,
37
- :pattern011 => 3,
38
- :pattern100 => 4,
39
- :pattern101 => 5,
40
- :pattern110 => 6,
41
- :pattern111 => 7
42
- }
43
-
44
- QRMASKCOMPUTATIONS = [
45
- Proc.new { |i,j| (i + j) % 2 == 0 },
46
- Proc.new { |i,j| i % 2 == 0 },
47
- Proc.new { |i,j| j % 3 == 0 },
48
- Proc.new { |i,j| (i + j) % 3 == 0 },
49
- Proc.new { |i,j| ((i / 2).floor + (j / 3).floor) % 2 == 0 },
50
- Proc.new { |i,j| (i * j) % 2 + (i * j) % 3 == 0 },
51
- Proc.new { |i,j| ((i * j) % 2 + (i * j) % 3) % 2 == 0 },
52
- Proc.new { |i,j| ((i * j) % 3 + (i + j) % 2) % 2 == 0 },
53
- ]
54
-
55
-
56
-
57
- QRPOSITIONPATTERNLENGTH = (7 + 1) * 2 + 1
58
- QRFORMATINFOLENGTH = 15
59
-
60
- #http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable1-e.html
61
- #http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable2-e.html
62
- #http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable3-e.html
63
- #http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable4-e.html
64
- # Each array contains levels max chars from level 1 to level 40
65
- QRMAXDIGITS = {
66
- l: {
67
- mode_number: [
68
- 41, 77, 127, 187, 255, 322, 370, 461, 552, 652, 772,
69
- 883, 1022, 1101, 1250, 1408, 1548, 1725, 1903, 2061,
70
- 2232, 2409, 2620, 2812, 3057, 3283, 3514, 3669, 3909, 4158,
71
- 4417, 4686, 4965, 5253, 5529, 5836, 6153, 6479, 6743, 7089
72
- ],
73
- mode_alpha_numk: [
74
- 25, 47, 77, 114, 154, 195, 224, 279, 335, 395,
75
- 468, 535, 619, 667, 758, 854, 938, 1046, 1153, 1249,
76
- 1352, 1460, 1588, 1704, 1853, 1990, 2132, 2223, 2369, 2520,
77
- 2677, 2840, 3009, 3183, 3351, 3537, 3729, 3927, 4087, 4296
78
- ],
79
- mode_8bit_byte: [
80
- 17, 32, 53, 78, 106, 134, 154, 192, 230, 271,
81
- 321, 367, 425, 458, 520, 586, 644, 718, 792, 858,
82
- 929, 1003, 1091, 1171, 1273, 1367, 1465, 1528, 1628, 1732,
83
- 1840, 1952, 2068, 2188, 2303, 2431, 2563, 2699, 2809, 2953
84
- ],
85
- },
86
- m: {
87
- mode_number: [
88
- 34, 63, 101, 149, 202, 255, 293, 365, 432, 513,
89
- 604, 691, 796, 871, 991, 1082, 1212, 1346, 1500, 1600,
90
- 1708, 1872, 2059, 2188, 2395, 2544, 2701, 2857, 3035, 3289,
91
- 3486, 3693, 3909, 4134, 4343, 4588, 4775, 5039, 5313, 5596,
92
- ],
93
- mode_alpha_numk: [
94
- 20, 38, 61, 90, 122, 154, 178, 221, 262, 311,
95
- 366, 419, 483, 528, 600, 656, 734, 816, 909, 970,
96
- 1035, 1134, 1248, 1326, 1451, 1542, 1637, 1732, 1839, 1994,
97
- 2113, 2238, 2369, 2506, 2632, 2780, 2894, 3054, 3220, 3391
98
- ],
99
- mode_8bit_byte: [
100
- 14, 26, 42, 62, 84, 106, 122, 152, 180, 213,
101
- 251, 287, 331, 362, 412, 450, 504, 560, 624, 666,
102
- 711, 779, 857, 911, 997, 1059, 1125, 1190, 1264, 1370,
103
- 1452, 1538, 1628, 1722, 1809, 1911, 1989, 2099, 2213, 2331
104
- ],
105
- },
106
- q: {
107
- mode_number: [
108
- 27, 48, 77, 111, 144, 178, 207, 259, 312, 364,
109
- 427, 489, 580, 621, 703, 775, 876, 948, 1063, 1159,
110
- 1224, 1358, 1468, 1588, 1718, 1804, 1933, 2085, 2181, 2358,
111
- 2473, 2670, 2805, 2949, 3081, 3244, 3417, 3599, 3791, 3993
112
- ],
113
- mode_alpha_numk: [
114
- 16, 29, 47, 67, 87, 108, 125, 157, 189, 221,
115
- 259, 296, 352, 376, 426, 470, 531, 574, 644, 702,
116
- 742, 823, 890, 963, 1041, 1094, 1172, 1263, 1322, 1429,
117
- 1499, 1618, 1700, 1787, 1867, 1966, 2071, 2181, 2298, 2420
118
- ],
119
- mode_8bit_byte: [
120
- 11, 20, 32, 46, 60, 74, 86, 108, 130, 151,
121
- 177, 203, 241, 258, 292, 22, 364, 394, 442, 482,
122
- 509, 565, 611, 661, 715, 751, 805, 868, 908, 982,
123
- 1030, 1112, 1168, 1228, 1283, 1351, 1423, 1499, 1579, 1663
124
- ],
125
- },
126
- h: {
127
- mode_number: [
128
- 17, 34, 58, 82, 106, 139, 154, 202, 235, 288, 331, 374, 427, 468, 530, 602, 674,
129
- 331, 374, 427, 468, 530, 602, 674, 746, 813, 919,
130
- 969, 1056, 1108, 1228, 1286, 1425, 1501, 1581, 1677, 1782,
131
- 1897, 2022, 2157, 2301, 2361, 2524, 2625, 2735, 2927, 3057
132
-
133
- ],
134
- mode_alpha_numk: [
135
- 10, 20, 35, 50, 64, 84, 93, 122, 143, 174, 200,
136
- 200, 227, 259, 283, 321, 365, 408, 452, 493, 557,
137
- 587, 640, 672, 744, 779, 864, 910, 958, 1016, 1080,
138
- 1150, 1226, 1307, 1394, 1431, 1530, 1591, 1658, 1774, 1852
139
- ],
140
- mode_8bit_byte: [
141
- 7, 14, 24, 34, 44, 58, 64, 84, 98, 119,
142
- 137, 155, 177, 194, 220, 250, 280, 310, 338, 382,
143
- 403, 439, 461, 511, 535, 593, 625, 658, 698, 742,
144
- 790, 842, 898, 958, 983, 1051, 1093, 1139, 1219, 1273
145
- ],
146
- },
147
- }
148
-
149
-
150
- # StandardErrors
151
-
152
- class QRCodeArgumentError < ArgumentError; end
153
- class QRCodeRunTimeError < RuntimeError; end
154
-
155
- # == Creation
156
- #
157
- # QRCode objects expect only one required constructor parameter
158
- # and an optional hash of any other. Here's a few examples:
159
- #
160
- # qr = RQRCode::QRCode.new('hello world')
161
- # qr = RQRCode::QRCode.new('hello world', :size => 1, :level => :m, :mode => :alphanumeric )
162
- #
163
-
164
- class QRCode
165
- attr_reader :modules, :module_count, :version
166
-
167
- # Expects a string to be parsed in, other args are optional
168
- #
169
- # # string - the string you wish to encode
170
- # # size - the size of the qrcode (default 4)
171
- # # level - the error correction level, can be:
172
- # * Level :l 7% of code can be restored
173
- # * Level :m 15% of code can be restored
174
- # * Level :q 25% of code can be restored
175
- # * Level :h 30% of code can be restored (default :h)
176
- # # mode - the mode of the qrcode (defaults to alphanumeric or byte_8bit, depending on the input data):
177
- # * :number
178
- # * :alphanumeric
179
- # * :byte_8bit
180
- # * :kanji
181
- #
182
- # qr = RQRCode::QRCode.new('hello world', :size => 1, :level => :m, :mode => :alphanumeric )
183
- #
184
-
185
- def initialize( string, *args )
186
- if !string.is_a? String
187
- raise QRCodeArgumentError, "The passed data is #{string.class}, not String"
188
- end
189
-
190
- options = args.extract_options!
191
- level = (options[:level] || :h).to_sym
192
-
193
- if !QRERRORCORRECTLEVEL.has_key?(level)
194
- raise QRCodeArgumentError, "Unknown error correction level `#{level.inspect}`"
195
- end
196
-
197
- @data = string
198
-
199
- mode = QRMODE_NAME[(options[:mode] || '').to_sym]
200
- # If mode is not explicitely given choose mode according to data type
201
- mode ||= case
202
- when RQRCode::QRNumeric.valid_data?(@data)
203
- QRMODE_NAME[:number]
204
- when QRAlphanumeric.valid_data?(@data)
205
- QRMODE_NAME[:alphanumeric]
206
- else
207
- QRMODE_NAME[:byte_8bit]
208
- end
209
-
210
- max_size_array = QRMAXDIGITS[level][mode]
211
- size = options[:size] || smallest_size_for(string, max_size_array)
212
-
213
- if size > QRUtil.max_size
214
- raise QRCodeArgumentError, "Given size greater than maximum possible size of #{QRUtil.max_size}"
215
- end
216
-
217
- @error_correct_level = QRERRORCORRECTLEVEL[level]
218
- @version = size
219
- @module_count = @version * 4 + QRPOSITIONPATTERNLENGTH
220
- @modules = Array.new( @module_count )
221
- @data_list =
222
- case mode
223
- when :mode_number
224
- QRNumeric.new( @data )
225
- when :mode_alpha_numk
226
- QRAlphanumeric.new( @data )
227
- else
228
- QR8bitByte.new( @data )
229
- end
230
-
231
- @data_cache = nil
232
- self.make
233
- end
234
-
235
- # <tt>is_dark</tt> is called with a +col+ and +row+ parameter. This will
236
- # return true or false based on whether that coordinate exists in the
237
- # matrix returned. It would normally be called while iterating through
238
- # <tt>modules</tt>. A simple example would be:
239
- #
240
- # instance.is_dark( 10, 10 ) => true
241
- #
242
-
243
- def is_dark( row, col )
244
- if !row.between?(0, @module_count - 1) || !col.between?(0, @module_count - 1)
245
- raise QRCodeRunTimeError, "Invalid row/column pair: #{row}, #{col}"
246
- end
247
- @modules[row][col]
248
- end
249
-
250
- alias dark? is_dark
251
-
252
- # This is a public method that returns the QR Code you have
253
- # generated as a string. It will not be able to be read
254
- # in this format by a QR Code reader, but will give you an
255
- # idea if the final outout. It takes two optional args
256
- # +:true+ and +:false+ which are there for you to choose
257
- # how the output looks. Here's an example of it's use:
258
- #
259
- # instance.to_s =>
260
- # xxxxxxx x x x x x xx xxxxxxx
261
- # x x xxx xxxxxx xxx x x
262
- # x xxx x xxxxx x xx x xxx x
263
- #
264
- # instance._to_s( :dark => 'E', :light => 'Q') =>
265
- # EEEEEEEQEQQEQEQQQEQEQQEEQQEEEEEEE
266
- # EQQQQQEQQEEEQQEEEEEEQEEEQQEQQQQQE
267
- # EQEEEQEQQEEEEEQEQQQQQQQEEQEQEEEQE
268
- #
269
- def to_s( *args )
270
- options = args.extract_options!
271
- dark = options[:dark] || options[:true] || 'x'
272
- light = options[:light] || options[:false] || ' '
273
- quiet_zone_size = options[:quiet_zone_size] || 0
274
-
275
- rows = []
276
-
277
- @modules.each do |row|
278
- cols = light * quiet_zone_size
279
- row.each do |col|
280
- cols += (col ? dark : light)
281
- end
282
- rows << cols
283
- end
284
-
285
- quiet_zone_size.times do
286
- rows.unshift(light * (rows.first.length / light.size))
287
- rows << light * (rows.first.length / light.size)
288
- end
289
- rows.join("\n")
290
- end
291
-
292
- # Return a symbol for current error connection level
293
- def error_correction_level
294
- QRERRORCORRECTLEVEL.invert[@error_correct_level]
295
- end
296
-
297
- # Return a symbol in QRMODE.keys for current mode used
298
- def mode
299
- case @data_list
300
- when QRNumeric
301
- :mode_number
302
- when QRAlphanumeric
303
- :mode_alpha_numk
304
- else
305
- :mode_8bit_byte
306
- end
307
- end
308
-
309
- protected
310
-
311
- def make #:nodoc:
312
- prepare_common_patterns
313
- make_impl( false, get_best_mask_pattern )
314
- end
315
-
316
- private
317
-
318
- def prepare_common_patterns
319
- @modules.map! { |row| Array.new(@module_count) }
320
-
321
- place_position_probe_pattern(0, 0)
322
- place_position_probe_pattern(@module_count - 7, 0)
323
- place_position_probe_pattern(0, @module_count - 7)
324
- place_position_adjust_pattern
325
- place_timing_pattern
326
-
327
- @common_patterns = @modules.map(&:clone)
328
- end
329
-
330
- def make_impl( test, mask_pattern ) #:nodoc:
331
- @modules = @common_patterns.map(&:clone)
332
-
333
- place_format_info(test, mask_pattern)
334
- place_version_info(test) if @version >= 7
335
-
336
- if @data_cache.nil?
337
- @data_cache = QRCode.create_data(
338
- @version, @error_correct_level, @data_list
339
- )
340
- end
341
-
342
- map_data( @data_cache, mask_pattern )
343
- end
344
-
345
-
346
- def place_position_probe_pattern( row, col ) #:nodoc:
347
- (-1..7).each do |r|
348
- next if !(row + r).between?(0, @module_count - 1)
349
-
350
- (-1..7).each do |c|
351
- next if !(col + c).between?(0, @module_count - 1)
352
-
353
- is_vert_line = (r.between?(0, 6) && (c == 0 || c == 6))
354
- is_horiz_line = (c.between?(0, 6) && (r == 0 || r == 6))
355
- is_square = r.between?(2,4) && c.between?(2, 4)
356
-
357
- is_part_of_probe = is_vert_line || is_horiz_line || is_square
358
- @modules[row + r][col + c] = is_part_of_probe
359
- end
360
- end
361
- end
362
-
363
-
364
- def get_best_mask_pattern #:nodoc:
365
- min_lost_point = 0
366
- pattern = 0
367
-
368
- ( 0...8 ).each do |i|
369
- make_impl( true, i )
370
- lost_point = QRUtil.get_lost_points(self.modules)
371
-
372
- if i == 0 || min_lost_point > lost_point
373
- min_lost_point = lost_point
374
- pattern = i
375
- end
376
- end
377
- pattern
378
- end
379
-
380
-
381
- def place_timing_pattern #:nodoc:
382
- ( 8...@module_count - 8 ).each do |i|
383
- @modules[i][6] = @modules[6][i] = i % 2 == 0
384
- end
385
- end
386
-
387
-
388
- def place_position_adjust_pattern #:nodoc:
389
- positions = QRUtil.get_pattern_positions(@version)
390
-
391
- positions.each do |row|
392
- positions.each do |col|
393
- next unless @modules[row][col].nil?
394
-
395
- ( -2..2 ).each do |r|
396
- ( -2..2 ).each do |c|
397
- is_part_of_pattern = (r.abs == 2 || c.abs == 2 || ( r == 0 && c == 0 ))
398
- @modules[row + r][col + c] = is_part_of_pattern
399
- end
400
- end
401
- end
402
- end
403
- end
404
-
405
-
406
- def place_version_info(test) #:nodoc:
407
- bits = QRUtil.get_bch_version(@version)
408
-
409
- ( 0...18 ).each do |i|
410
- mod = ( !test && ( (bits >> i) & 1) == 1 )
411
- @modules[ (i / 3).floor ][ i % 3 + @module_count - 8 - 3 ] = mod
412
- @modules[ i % 3 + @module_count - 8 - 3 ][ (i / 3).floor ] = mod
413
- end
414
- end
415
-
416
-
417
- def place_format_info(test, mask_pattern) #:nodoc:
418
- data = (@error_correct_level << 3 | mask_pattern)
419
- bits = QRUtil.get_bch_format_info(data)
420
-
421
- QRFORMATINFOLENGTH.times do |i|
422
- mod = (!test && ( (bits >> i) & 1) == 1)
423
-
424
- # vertical
425
- if i < 6
426
- row = i
427
- elsif i < 8
428
- row = i + 1
429
- else
430
- row = @module_count - 15 + i
431
- end
432
- @modules[row][8] = mod
433
-
434
- # horizontal
435
- if i < 8
436
- col = @module_count - i - 1
437
- elsif i < 9
438
- col = 15 - i - 1 + 1
439
- else
440
- col = 15 - i - 1
441
- end
442
- @modules[8][col] = mod
443
- end
444
-
445
- # fixed module
446
- @modules[ @module_count - 8 ][8] = !test
447
- end
448
-
449
-
450
- def map_data( data, mask_pattern ) #:nodoc:
451
- inc = -1
452
- row = @module_count - 1
453
- bit_index = 7
454
- byte_index = 0
455
-
456
- ( @module_count - 1 ).step( 1, -2 ) do |col|
457
- col = col - 1 if col <= 6
458
-
459
- while true do
460
- ( 0...2 ).each do |c|
461
-
462
- if @modules[row][ col - c ].nil?
463
- dark = false
464
- if byte_index < data.size && !data[byte_index].nil?
465
- dark = (( (data[byte_index]).rszf( bit_index ) & 1) == 1 )
466
- end
467
- mask = QRUtil.get_mask( mask_pattern, row, col - c )
468
- dark = !dark if mask
469
- @modules[row][ col - c ] = dark
470
- bit_index -= 1
471
-
472
- if bit_index == -1
473
- byte_index += 1
474
- bit_index = 7
475
- end
476
- end
477
- end
478
-
479
- row += inc
480
-
481
- if row < 0 || @module_count <= row
482
- row -= inc
483
- inc = -inc
484
- break
485
- end
486
- end
487
- end
488
- end
489
-
490
- def smallest_size_for(string, max_size_array) #:nodoc:
491
- l = string.bytesize
492
- ver = max_size_array.index{|i| i >= l}
493
- raise QRCodeRunTimeError,"code length overflow. (#{l} digits > any version capacity)" unless ver
494
- ver + 1
495
- end
496
-
497
- def QRCode.count_max_data_bits(rs_blocks)
498
- max_data_bytes = rs_blocks.reduce(0) do |sum, rs_block|
499
- sum + rs_block.data_count
500
- end
501
-
502
- return max_data_bytes * 8
503
- end
504
-
505
- def QRCode.create_data(version, error_correct_level, data_list) #:nodoc:
506
- rs_blocks = QRRSBlock.get_rs_blocks(version, error_correct_level)
507
- max_data_bits = QRCode.count_max_data_bits(rs_blocks)
508
- buffer = QRBitBuffer.new(version)
509
-
510
- data_list.write(buffer)
511
- buffer.end_of_message(max_data_bits)
512
-
513
- if buffer.get_length_in_bits > max_data_bits
514
- raise QRCodeRunTimeError, "code length overflow. (#{buffer.get_length_in_bits}>#{max_data_bits}). (Try a larger size!)"
515
- end
516
-
517
- buffer.pad_until(max_data_bits)
518
-
519
- QRCode.create_bytes( buffer, rs_blocks )
520
- end
521
-
522
-
523
- def QRCode.create_bytes( buffer, rs_blocks ) #:nodoc:
524
- offset = 0
525
- max_dc_count = 0
526
- max_ec_count = 0
527
- dcdata = Array.new( rs_blocks.size )
528
- ecdata = Array.new( rs_blocks.size )
529
-
530
- rs_blocks.each_with_index do |rs_block, r|
531
- dc_count = rs_block.data_count
532
- ec_count = rs_block.total_count - dc_count
533
- max_dc_count = [ max_dc_count, dc_count ].max
534
- max_ec_count = [ max_ec_count, ec_count ].max
535
-
536
- dcdata_block = Array.new(dc_count)
537
- dcdata_block.size.times do |i|
538
- dcdata_block[i] = 0xff & buffer.buffer[ i + offset ]
539
- end
540
- dcdata[r] = dcdata_block
541
-
542
- offset = offset + dc_count
543
- rs_poly = QRUtil.get_error_correct_polynomial( ec_count )
544
- raw_poly = QRPolynomial.new( dcdata[r], rs_poly.get_length - 1 )
545
- mod_poly = raw_poly.mod( rs_poly )
546
-
547
- ecdata_block = Array.new(rs_poly.get_length - 1)
548
- ecdata_block.size.times do |i|
549
- mod_index = i + mod_poly.get_length - ecdata_block.size
550
- ecdata_block[i] = mod_index >= 0 ? mod_poly.get( mod_index ) : 0
551
- end
552
- ecdata[r] = ecdata_block
553
- end
554
-
555
- total_code_count = rs_blocks.reduce(0) do |sum, rs_block|
556
- sum + rs_block.total_count
557
- end
558
-
559
- data = Array.new( total_code_count )
560
- index = 0
561
-
562
- max_dc_count.times do |i|
563
- rs_blocks.size.times do |r|
564
- if i < dcdata[r].size
565
- data[index] = dcdata[r][i]
566
- index += 1
567
- end
568
- end
569
- end
570
-
571
- max_ec_count.times do |i|
572
- rs_blocks.size.times do |r|
573
- if i < ecdata[r].size
574
- data[index] = ecdata[r][i]
575
- index += 1
576
- end
577
- end
578
- end
579
-
580
- data
581
- end
582
-
583
- end
584
-
585
- end