rqrcode 0.4.2 → 0.6.0
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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +9 -0
- data/CHANGELOG +14 -0
- data/Gemfile +9 -2
- data/README.md +74 -21
- data/TODO.md +4 -0
- data/lib/rqrcode.rb +3 -0
- data/lib/rqrcode/export/html.rb +53 -0
- data/lib/rqrcode/export/png.rb +117 -0
- data/lib/rqrcode/export/svg.rb +49 -0
- data/lib/rqrcode/qrcode/qr_8bit_byte.rb +5 -6
- data/lib/rqrcode/qrcode/qr_alphanumeric.rb +47 -0
- data/lib/rqrcode/qrcode/qr_bit_buffer.rb +37 -1
- data/lib/rqrcode/qrcode/qr_code.rb +66 -54
- data/lib/rqrcode/qrcode/qr_rs_block.rb +2 -1
- data/lib/rqrcode/qrcode/qr_util.rb +1 -1
- data/lib/rqrcode/version.rb +1 -1
- data/rqrcode.gemspec +10 -8
- data/test/data.rb +2 -0
- data/test/test_regresions.rb +21 -0
- data/test/test_rqrcode.rb +23 -8
- data/test/test_rqrcode_export.rb +40 -0
- metadata +75 -53
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7559f2004d53b9642306d26b1b95926564216889
|
4
|
+
data.tar.gz: df2bbd25ba80e1975f52dfc0bc354cfff547d17f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 814b04bb242a2ee751eafdeb102ef95d8cf53be4c9d71fc7577b1a225fd5fccd702ca19b4f641f0bb3ca150213a7c9e8635e3e9ddb2e3808c8355689465a1a4a
|
7
|
+
data.tar.gz: fdf2cbd54b99a59c1085707799718c84c3f8d28ad0a11754914fa9cece4ecfd4659e23af8faaa8830580296a5e2dece5b32e128461679f5735db865f4aec8e46
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/CHANGELOG
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
*0.6.0* (Jun 2, 2015)
|
2
|
+
|
3
|
+
- Improved png rendering. Previous png rendering could result in hard to scan qrcodes.
|
4
|
+
*Big thanks to Bart Jedrocha*
|
5
|
+
|
6
|
+
*0.5.5* (Apr 25, 2015)
|
7
|
+
|
8
|
+
- Fixed major bug. The rs block data was missing resulting in qr codes failing to be generated.
|
9
|
+
*Upgrade highly recomended!!*
|
10
|
+
|
11
|
+
*0.5.4* (Nov 11th, 2013)
|
12
|
+
|
13
|
+
* Added as_html, Big thanks to Jon Evans!
|
14
|
+
|
1
15
|
*0.4.2* (Sep 1st, 2011)
|
2
16
|
|
3
17
|
* Proper namespace CoreExtensions and only extend when needed [https://github.com/metaskills]
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,18 @@
|
|
1
|
-
# rQRCode, Encode QRCodes
|
1
|
+
# rQRCode, Encode QRCodes
|
2
|
+
|
3
|
+
[](https://travis-ci.org/whomwah/rqrcode)
|
4
|
+
|
5
|
+
## Short changelog
|
6
|
+
|
7
|
+
*0.6.0* (Jun 2, 2015)
|
8
|
+
|
9
|
+
- Improved png rendering. Previous png rendering could result in hard to scan qrcodes.
|
10
|
+
*Big thanks to Bart Jedrocha*
|
11
|
+
|
12
|
+
*0.5.5* (Apr 25, 2015)
|
13
|
+
|
14
|
+
- Fixed major bug. The rs block data was missing resulting in qr codes failing to be generated.
|
15
|
+
*Upgrade highly recomended!!*
|
2
16
|
|
3
17
|
## Overview
|
4
18
|
|
@@ -19,11 +33,11 @@ Let's clear up some rQRCode stuff.
|
|
19
33
|
|
20
34
|
## Installing
|
21
35
|
|
22
|
-
You may get the latest stable version from Rubygems.
|
36
|
+
You may get the latest stable version from Rubygems.
|
23
37
|
|
24
38
|
gem install rqrcode
|
25
39
|
|
26
|
-
You can also get the latest source from
|
40
|
+
You can also get the latest source from https://github.com/whomwah/rqrcode
|
27
41
|
|
28
42
|
git clone git://github.com/whomwah/rqrcode.git
|
29
43
|
|
@@ -32,7 +46,7 @@ You can also get the latest source from http://github.com/whomwah/rqrcode
|
|
32
46
|
To run the tests:
|
33
47
|
|
34
48
|
$ rake
|
35
|
-
|
49
|
+
|
36
50
|
## Loading rQRCode Itself
|
37
51
|
|
38
52
|
You have installed the gem already, yeah?
|
@@ -54,12 +68,12 @@ puts qr.to_s
|
|
54
68
|
```
|
55
69
|
|
56
70
|
## Simple QRCode generation to template (RubyOnRails)
|
57
|
-
|
58
|
-
```
|
59
|
-
# Controller
|
71
|
+
### Controller
|
72
|
+
```ruby
|
60
73
|
@qr = RQRCode::QRCode.new( 'my string to generate', :size => 4, :level => :h )
|
61
|
-
|
62
|
-
|
74
|
+
```
|
75
|
+
### View: (minimal styling added)
|
76
|
+
```erb
|
63
77
|
<style type="text/css">
|
64
78
|
table {
|
65
79
|
border-width: 0;
|
@@ -68,22 +82,28 @@ table {
|
|
68
82
|
border-collapse: collapse;
|
69
83
|
}
|
70
84
|
td {
|
71
|
-
border-width: 0;
|
85
|
+
border-width: 0;
|
72
86
|
border-style: none;
|
73
|
-
border-color: #0000ff;
|
74
|
-
border-collapse: collapse;
|
75
|
-
padding: 0;
|
76
|
-
margin: 0;
|
77
|
-
width: 10px;
|
78
|
-
height: 10px;
|
87
|
+
border-color: #0000ff;
|
88
|
+
border-collapse: collapse;
|
89
|
+
padding: 0;
|
90
|
+
margin: 0;
|
91
|
+
width: 10px;
|
92
|
+
height: 10px;
|
79
93
|
}
|
80
94
|
td.black { background-color: #000; }
|
81
95
|
td.white { background-color: #fff; }
|
82
96
|
</style>
|
83
97
|
|
98
|
+
<%= raw @qr.as_html %>
|
99
|
+
```
|
100
|
+
|
101
|
+
If you want to generate the HTML manually for customization, you can start with the following:
|
102
|
+
|
103
|
+
```erb
|
84
104
|
<table>
|
85
105
|
<% @qr.modules.each_index do |x| %>
|
86
|
-
<tr>
|
106
|
+
<tr>
|
87
107
|
<% @qr.modules.each_index do |y| %>
|
88
108
|
<% if @qr.dark?(x,y) %>
|
89
109
|
<td class="black"/>
|
@@ -96,17 +116,50 @@ td.white { background-color: #fff; }
|
|
96
116
|
</table>
|
97
117
|
```
|
98
118
|
|
119
|
+
## Exporting
|
120
|
+
|
121
|
+
You can also require optional export features:
|
122
|
+
|
123
|
+
* SVG -> no dependencies
|
124
|
+
* PNG -> depends on 'chunky_png' gem
|
125
|
+
* JPG -> depends on 'mini_magick' gem
|
126
|
+
|
127
|
+
Example to render png:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
require 'rqrcode/export/png'
|
131
|
+
image = RQRCode::QRCode.new("nice qr").as_png
|
132
|
+
```
|
133
|
+
|
134
|
+
Notice the 'as\_png'. Same goes for 'as\_svg', 'as\_xxx'.
|
135
|
+
|
136
|
+
### Export Options
|
137
|
+
|
138
|
+
Exporters support these options:
|
139
|
+
|
140
|
+
* size - Image size, in pixels.
|
141
|
+
* fill - Background color, defaults to 'white'
|
142
|
+
* color - Foreground color, defaults to 'black'
|
143
|
+
|
144
|
+
SVG Export supports the parameter `module_size` to generate smaller or larger QR Codes
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
require 'rqrcode/export/svg'
|
148
|
+
svg = RQRCode::QRCode.new("nice qr").as_svg(:module_size => 6)
|
149
|
+
```
|
150
|
+
|
99
151
|
## Authors
|
100
152
|
|
101
153
|
Original author: Duncan Robertson
|
102
154
|
|
103
155
|
Special thanks to the following people for submitting patches:
|
104
156
|
|
105
|
-
* [Gioele Barabucci](https://github.com/gioele)
|
106
|
-
* [Rob la Lau](https://github.com/ohreally)
|
107
157
|
* [Chris Mowforth](http://blog.99th.st)
|
108
|
-
* [Tore Darell](http://tore.darell.no)
|
109
158
|
* [Daniel Schierbeck](https://github.com/dasch)
|
159
|
+
* [Gioele Barabucci](https://github.com/gioele)
|
160
|
+
* [Ken Collins](https://github.com/metaskills)
|
161
|
+
* [Rob la Lau](https://github.com/ohreally)
|
162
|
+
* [Tore Darell](http://tore.darell.no)
|
110
163
|
* Vladislav Gorodetskiy
|
111
164
|
|
112
165
|
## Contributing
|
@@ -116,4 +169,4 @@ Special thanks to the following people for submitting patches:
|
|
116
169
|
|
117
170
|
## Copyright
|
118
171
|
|
119
|
-
MIT
|
172
|
+
MIT License (http://www.opensource.org/licenses/mit-license.html)
|
data/TODO.md
ADDED
data/lib/rqrcode.rb
CHANGED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Use this module to HTML-ify the QR code if you just want the default HTML
|
2
|
+
module RQRCode
|
3
|
+
module Export
|
4
|
+
module HTML
|
5
|
+
|
6
|
+
def as_html
|
7
|
+
['<table>', rows.as_html, '</table>'].join
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def rows
|
13
|
+
Rows.new(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
class Rows < Struct.new(:qr)
|
17
|
+
def as_html
|
18
|
+
rows.map(&:as_html).join
|
19
|
+
end
|
20
|
+
|
21
|
+
def rows
|
22
|
+
qr.modules.each_with_index.map { |qr_module, row_index| Row.new(qr, qr_module, row_index) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Row < Struct.new(:qr, :qr_module, :row_index)
|
27
|
+
def as_html
|
28
|
+
['<tr>', cells.map(&:as_html).join, '</tr>'].join
|
29
|
+
end
|
30
|
+
|
31
|
+
def cells
|
32
|
+
qr.modules.each_with_index.map { |qr_module, col_index| Cell.new(qr, col_index, row_index) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Cell < Struct.new(:qr, :col_index, :row_index)
|
37
|
+
def as_html
|
38
|
+
"<td class=\"#{html_class}\"></td>"
|
39
|
+
end
|
40
|
+
|
41
|
+
def html_class
|
42
|
+
dark? ? 'black' : 'white'
|
43
|
+
end
|
44
|
+
|
45
|
+
def dark?
|
46
|
+
qr.dark?(row_index, col_index)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
RQRCode::QRCode.send :include, RQRCode::Export::HTML
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'chunky_png'
|
2
|
+
|
3
|
+
# This class creates PNG files.
|
4
|
+
# Code from: https://github.com/DCarper/rqrcode
|
5
|
+
module RQRCode
|
6
|
+
module Export
|
7
|
+
module PNG
|
8
|
+
|
9
|
+
# Render the PNG from the Qrcode.
|
10
|
+
#
|
11
|
+
# There are two sizing algoritams.
|
12
|
+
#
|
13
|
+
# - Original that can result in blurry and hard to scan images
|
14
|
+
# - Google's Chart API inspired sizing that risizes the module size to fit within the given image size.
|
15
|
+
#
|
16
|
+
# The Googleis one will be used when no options are given or when the new size option is used.
|
17
|
+
#
|
18
|
+
# Options:
|
19
|
+
# fill - Background ChunkyPNG::Color, defaults to 'white'
|
20
|
+
# color - Foreground ChunkyPNG::Color, defaults to 'black'
|
21
|
+
#
|
22
|
+
# *Googleis*
|
23
|
+
# size - Total size of PNG in pixels. The module size is calculated so it fits. (defaults to 90)
|
24
|
+
# border_modules - Width of white border around in modules. (defaults to 4).
|
25
|
+
#
|
26
|
+
# -- DONT USE border_modules OPTION UNLESS YOU KNOW ABOUT THE QUIET ZONE NEEDS OF QR CODES --
|
27
|
+
#
|
28
|
+
# *Original*
|
29
|
+
# module_px_size - Image size, in pixels.
|
30
|
+
# border - Border thickness, in pixels
|
31
|
+
#
|
32
|
+
# It first creates an image where 1px = 1 module, then resizes.
|
33
|
+
# Defaults to 90x90 pixels, customizable by option.
|
34
|
+
#
|
35
|
+
def as_png(options = {})
|
36
|
+
|
37
|
+
default_img_options = {
|
38
|
+
:resize_gte_to => false,
|
39
|
+
:resize_exactly_to => false,
|
40
|
+
:fill => 'white',
|
41
|
+
:color => 'black',
|
42
|
+
:size => 120,
|
43
|
+
:border_modules => 4,
|
44
|
+
:file => false,
|
45
|
+
:module_px_size => 6
|
46
|
+
}
|
47
|
+
|
48
|
+
googleis = options.length == 0 || (options[:size] != nil)
|
49
|
+
|
50
|
+
options = default_img_options.merge(options) # reverse_merge
|
51
|
+
|
52
|
+
fill = ChunkyPNG::Color(options[:fill])
|
53
|
+
color = ChunkyPNG::Color(options[:color])
|
54
|
+
output_file = options[:file]
|
55
|
+
|
56
|
+
module_px_size = nil
|
57
|
+
border_px = nil
|
58
|
+
png = nil
|
59
|
+
|
60
|
+
if googleis
|
61
|
+
total_image_size = options[:size]
|
62
|
+
border_modules = options[:border_modules]
|
63
|
+
|
64
|
+
module_px_size = (total_image_size.to_f / (self.module_count + 2 * border_modules).to_f).floor.to_i
|
65
|
+
|
66
|
+
img_size = module_px_size * self.module_count
|
67
|
+
|
68
|
+
remaining = total_image_size - img_size
|
69
|
+
border_px = (remaining / 2.0).floor.to_i
|
70
|
+
|
71
|
+
png = ChunkyPNG::Image.new(total_image_size, total_image_size, fill)
|
72
|
+
else
|
73
|
+
border = options[:border_modules]
|
74
|
+
total_border = border * 2
|
75
|
+
module_px_size = if options[:resize_gte_to]
|
76
|
+
(options[:resize_gte_to].to_f / (self.module_count + total_border).to_f).ceil.to_i
|
77
|
+
else
|
78
|
+
options[:module_px_size]
|
79
|
+
end
|
80
|
+
border_px = border * module_px_size
|
81
|
+
total_border_px = border_px * 2
|
82
|
+
resize_to = options[:resize_exactly_to]
|
83
|
+
|
84
|
+
img_size = module_px_size * self.module_count
|
85
|
+
total_img_size = img_size + total_border_px
|
86
|
+
|
87
|
+
png = ChunkyPNG::Image.new(total_img_size, total_img_size, fill)
|
88
|
+
end
|
89
|
+
|
90
|
+
self.modules.each_index do |x|
|
91
|
+
self.modules.each_index do |y|
|
92
|
+
if self.dark?(x, y)
|
93
|
+
(0...module_px_size).each do |i|
|
94
|
+
(0...module_px_size).each do |j|
|
95
|
+
png[(y * module_px_size) + border_px + j , (x * module_px_size) + border_px + i] = color
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
if !googleis && resize_to
|
103
|
+
png = png.resize(resize_to, resize_to)
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
if output_file
|
108
|
+
png.save(output_file,{ :color_mode => ChunkyPNG::COLOR_GRAYSCALE, :bit_depth =>1})
|
109
|
+
end
|
110
|
+
png
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
RQRCode::QRCode.send :include, RQRCode::Export::PNG
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# This class creates a SVG files.
|
2
|
+
# Code from: https://github.com/samvincent/rqrcode-rails3
|
3
|
+
module RQRCode
|
4
|
+
module Export
|
5
|
+
|
6
|
+
# Render the SVG from the Qrcode.
|
7
|
+
#
|
8
|
+
# Options:
|
9
|
+
# offset - Padding around the QR Code (e.g. 10)
|
10
|
+
# fill - Background color (e.g "ffffff" or :white)
|
11
|
+
# color - Foreground color for the code (e.g. "000000" or :black)
|
12
|
+
# module_size - The Pixel size of each module (e.g. 11)
|
13
|
+
module SVG
|
14
|
+
def as_svg(options={})
|
15
|
+
offset = options[:offset].to_i || 0
|
16
|
+
color = options[:color] || "000"
|
17
|
+
module_size = options[:module_size] || 11
|
18
|
+
|
19
|
+
# height and width dependent on offset and QR complexity
|
20
|
+
dimension = (self.module_count*module_size) + (2*offset)
|
21
|
+
|
22
|
+
xml_tag = %{<?xml version="1.0" standalone="yes"?>}
|
23
|
+
open_tag = %{<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" width="#{dimension}" height="#{dimension}">}
|
24
|
+
close_tag = "</svg>"
|
25
|
+
|
26
|
+
result = []
|
27
|
+
self.modules.each_index do |c|
|
28
|
+
tmp = []
|
29
|
+
self.modules.each_index do |r|
|
30
|
+
y = c*module_size + offset
|
31
|
+
x = r*module_size + offset
|
32
|
+
|
33
|
+
next unless self.is_dark(c, r)
|
34
|
+
tmp << %{<rect width="#{module_size}" height="#{module_size}" x="#{x}" y="#{y}" style="fill:##{color}"/>}
|
35
|
+
end
|
36
|
+
result << tmp.join
|
37
|
+
end
|
38
|
+
|
39
|
+
if options[:fill]
|
40
|
+
result.unshift %{<rect width="#{dimension}" height="#{dimension}" x="0" y="0" style="fill:##{options[:fill]}"/>}
|
41
|
+
end
|
42
|
+
|
43
|
+
[xml_tag, open_tag, result, close_tag].flatten.join("\n")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
RQRCode::QRCode.send :include, RQRCode::Export::SVG
|
@@ -21,15 +21,14 @@ module RQRCode
|
|
21
21
|
|
22
22
|
|
23
23
|
def get_length
|
24
|
-
@data.
|
24
|
+
@data.bytesize
|
25
25
|
end
|
26
26
|
|
27
27
|
|
28
|
-
def write( buffer
|
29
|
-
(
|
30
|
-
|
31
|
-
|
32
|
-
buffer.put( c, 8 )
|
28
|
+
def write( buffer)
|
29
|
+
buffer.byte_encoding_start(get_length)
|
30
|
+
@data.each_byte do |b|
|
31
|
+
buffer.put(b, 8)
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
@@ -0,0 +1,47 @@
|
|
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
|
@@ -14,7 +14,11 @@ module RQRCode
|
|
14
14
|
class QRBitBuffer
|
15
15
|
attr_reader :buffer
|
16
16
|
|
17
|
-
|
17
|
+
PAD0 = 0xEC
|
18
|
+
PAD1 = 0x11
|
19
|
+
|
20
|
+
def initialize(version)
|
21
|
+
@version = version
|
18
22
|
@buffer = []
|
19
23
|
@length = 0
|
20
24
|
end
|
@@ -50,6 +54,38 @@ module RQRCode
|
|
50
54
|
|
51
55
|
@length += 1
|
52
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 pad_until(prefered_size)
|
73
|
+
# Align on byte
|
74
|
+
while get_length_in_bits % 8 != 0
|
75
|
+
put_bit( false )
|
76
|
+
end
|
77
|
+
|
78
|
+
# Pad with padding code words
|
79
|
+
while get_length_in_bits < prefered_size
|
80
|
+
put( QRBitBuffer::PAD0, 8 )
|
81
|
+
put( QRBitBuffer::PAD1, 8 ) if get_length_in_bits < prefered_size
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def end_of_message(max_data_bits)
|
86
|
+
put( 0, 4 ) unless get_length_in_bits+4 > max_data_bits
|
87
|
+
end
|
88
|
+
|
53
89
|
|
54
90
|
end
|
55
91
|
|
@@ -47,9 +47,32 @@ module RQRCode #:nodoc:
|
|
47
47
|
Proc.new { |i,j| ((i * j) % 3 + (i + j) % 2) % 2 == 0 },
|
48
48
|
]
|
49
49
|
|
50
|
+
|
51
|
+
|
50
52
|
QRPOSITIONPATTERNLENGTH = (7 + 1) * 2 + 1
|
51
53
|
QRFORMATINFOLENGTH = 15
|
52
54
|
|
55
|
+
#http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable1-e.html
|
56
|
+
QRMAXDIGITS = {
|
57
|
+
:l => {:mode_number => [41, 77, 127, 187, 255, 322, 370, 461, 552, 652],
|
58
|
+
:mode_alpha_numk => [25, 47, 77, 114, 154, 195, 224, 279, 335, 395],
|
59
|
+
:mode_8bit_byte => [17, 32, 53, 78, 106, 134, 154, 192, 230, 271, 321, 367, 425, 458, 520, 586, 644, 718, 792, 858],
|
60
|
+
:mode_kanji => [10, 20, 32, 48, 65, 82, 95, 118, 141, 167]},
|
61
|
+
:m => {:mode_number => [34, 63, 101, 149, 202, 255, 293, 365, 432, 513],
|
62
|
+
:mode_alpha_numk => [20, 38, 61, 90, 122, 154, 178, 221, 262, 311],
|
63
|
+
:mode_8bit_byte => [14, 26, 42, 62, 84, 106, 122, 152, 180, 213, 251, 287, 331, 362, 412, 450, 504, 560, 624, 666],
|
64
|
+
:mode_kanji => [ 8, 16, 26, 38, 54, 65, 75, 93, 111, 131]},
|
65
|
+
:q => {:mode_number => [27, 48, 77, 111, 144, 178, 207, 259, 312, 364],
|
66
|
+
:mode_alpha_numk => [16, 29, 47, 67, 87, 108, 125, 157, 189, 221],
|
67
|
+
:mode_8bit_byte => [11, 20, 32, 46, 60, 74, 86, 108, 130, 151, 177, 203, 241, 258, 292, 22, 364, 394, 442, 482],
|
68
|
+
:mode_kanji => [ 7, 12, 20, 28, 37, 45, 53, 66, 80, 93]},
|
69
|
+
:h => {:mode_number => [17, 34, 58, 82, 106, 139, 154, 202, 235, 288],
|
70
|
+
:mode_alpha_numk => [10, 20, 35, 50, 64, 84, 93, 122, 143, 174],
|
71
|
+
:mode_8bit_byte => [ 7, 14, 24, 34, 44, 58, 64, 84, 98, 119, 137, 155, 177, 194, 220, 250, 280, 310, 338, 382],
|
72
|
+
:mode_kanji => [ 4, 8, 15, 21, 27, 36, 39, 52, 60, 74]},
|
73
|
+
}
|
74
|
+
|
75
|
+
|
53
76
|
# StandardErrors
|
54
77
|
|
55
78
|
class QRCodeArgumentError < ArgumentError; end
|
@@ -58,29 +81,26 @@ module RQRCode #:nodoc:
|
|
58
81
|
# == Creation
|
59
82
|
#
|
60
83
|
# QRCode objects expect only one required constructor parameter
|
61
|
-
# and an optional hash of any other. Here's a few examples:
|
84
|
+
# and an optional hash of any other. Here's a few examples:
|
62
85
|
#
|
63
86
|
# qr = RQRCode::QRCode.new('hello world')
|
64
|
-
# qr = RQRCode::QRCode.new('hello world', :size => 1, :level => :m )
|
87
|
+
# qr = RQRCode::QRCode.new('hello world', :size => 1, :level => :m )
|
65
88
|
#
|
66
89
|
|
67
90
|
class QRCode
|
68
|
-
attr_reader :modules, :module_count
|
69
|
-
|
70
|
-
PAD0 = 0xEC
|
71
|
-
PAD1 = 0x11
|
91
|
+
attr_reader :modules, :module_count, :version, :error_correction_level
|
72
92
|
|
73
|
-
# Expects a string to be parsed in, other args are optional
|
93
|
+
# Expects a string to be parsed in, other args are optional
|
74
94
|
#
|
75
|
-
# # string - the string you wish to encode
|
95
|
+
# # string - the string you wish to encode
|
76
96
|
# # size - the size of the qrcode (default 4)
|
77
97
|
# # level - the error correction level, can be:
|
78
98
|
# * Level :l 7% of code can be restored
|
79
99
|
# * Level :m 15% of code can be restored
|
80
100
|
# * Level :q 25% of code can be restored
|
81
|
-
# * Level :h 30% of code can be restored (default :h)
|
101
|
+
# * Level :h 30% of code can be restored (default :h)
|
82
102
|
#
|
83
|
-
# qr = RQRCode::QRCode.new('hello world', :size => 1, :level => :m )
|
103
|
+
# qr = RQRCode::QRCode.new('hello world', :size => 1, :level => :m )
|
84
104
|
#
|
85
105
|
|
86
106
|
def initialize( string, *args )
|
@@ -90,28 +110,32 @@ module RQRCode #:nodoc:
|
|
90
110
|
|
91
111
|
options = args.extract_options!
|
92
112
|
level = (options[:level] || :h).to_sym
|
93
|
-
size = options[:size] || 4
|
94
113
|
|
95
114
|
if !QRERRORCORRECTLEVEL.has_key?(level)
|
96
115
|
raise QRCodeArgumentError, "Unknown error correction level `#{level.inspect}`"
|
97
116
|
end
|
98
117
|
|
99
118
|
@data = string
|
119
|
+
|
120
|
+
mode = QRAlphanumeric.valid_data?( @data ) ? :mode_alpha_numk : :mode_8bit_byte
|
121
|
+
|
122
|
+
max_size_array = QRMAXDIGITS[level][mode]
|
123
|
+
size = options[:size] || smallest_size_for(string, max_size_array)
|
124
|
+
|
100
125
|
@error_correct_level = QRERRORCORRECTLEVEL[level]
|
101
126
|
@version = size
|
102
127
|
@module_count = @version * 4 + QRPOSITIONPATTERNLENGTH
|
103
128
|
@modules = Array.new( @module_count )
|
104
|
-
@data_list = QR8bitByte.new( @data )
|
129
|
+
@data_list = (mode == :mode_alpha_numk) ? QRAlphanumeric.new( @data ) : QR8bitByte.new( @data )
|
105
130
|
@data_cache = nil
|
106
|
-
|
107
131
|
self.make
|
108
132
|
end
|
109
133
|
|
110
134
|
# <tt>is_dark</tt> is called with a +col+ and +row+ parameter. This will
|
111
|
-
# return true or false based on whether that coordinate exists in the
|
135
|
+
# return true or false based on whether that coordinate exists in the
|
112
136
|
# matrix returned. It would normally be called while iterating through
|
113
137
|
# <tt>modules</tt>. A simple example would be:
|
114
|
-
#
|
138
|
+
#
|
115
139
|
# instance.is_dark( 10, 10 ) => true
|
116
140
|
#
|
117
141
|
|
@@ -144,8 +168,8 @@ module RQRCode #:nodoc:
|
|
144
168
|
|
145
169
|
def to_s( *args )
|
146
170
|
options = args.extract_options!
|
147
|
-
row = options[:true] || 'x'
|
148
|
-
col = options[:false] || ' '
|
171
|
+
row = options[:true] || 'x'
|
172
|
+
col = options[:false] || ' '
|
149
173
|
|
150
174
|
res = []
|
151
175
|
|
@@ -153,11 +177,11 @@ module RQRCode #:nodoc:
|
|
153
177
|
tmp = []
|
154
178
|
@modules.each_index do |r|
|
155
179
|
if is_dark(c,r)
|
156
|
-
tmp << row
|
180
|
+
tmp << row
|
157
181
|
else
|
158
|
-
tmp << col
|
182
|
+
tmp << col
|
159
183
|
end
|
160
|
-
end
|
184
|
+
end
|
161
185
|
res << tmp.join
|
162
186
|
end
|
163
187
|
res.join("\n")
|
@@ -191,9 +215,9 @@ module RQRCode #:nodoc:
|
|
191
215
|
place_version_info(test) if @version >= 7
|
192
216
|
|
193
217
|
if @data_cache.nil?
|
194
|
-
@data_cache = QRCode.create_data(
|
218
|
+
@data_cache = QRCode.create_data(
|
195
219
|
@version, @error_correct_level, @data_list
|
196
|
-
)
|
220
|
+
)
|
197
221
|
end
|
198
222
|
|
199
223
|
map_data( @data_cache, mask_pattern )
|
@@ -237,7 +261,7 @@ module RQRCode #:nodoc:
|
|
237
261
|
|
238
262
|
def place_timing_pattern #:nodoc:
|
239
263
|
( 8...@module_count - 8 ).each do |i|
|
240
|
-
@modules[i][6] = @modules[6][i] = i % 2 == 0
|
264
|
+
@modules[i][6] = @modules[6][i] = i % 2 == 0
|
241
265
|
end
|
242
266
|
end
|
243
267
|
|
@@ -254,7 +278,7 @@ module RQRCode #:nodoc:
|
|
254
278
|
is_part_of_pattern = (r.abs == 2 || c.abs == 2 || ( r == 0 && c == 0 ))
|
255
279
|
@modules[row + r][col + c] = is_part_of_pattern
|
256
280
|
end
|
257
|
-
end
|
281
|
+
end
|
258
282
|
end
|
259
283
|
end
|
260
284
|
end
|
@@ -300,7 +324,7 @@ module RQRCode #:nodoc:
|
|
300
324
|
end
|
301
325
|
|
302
326
|
# fixed module
|
303
|
-
@modules[ @module_count - 8 ][8] = !test
|
327
|
+
@modules[ @module_count - 8 ][8] = !test
|
304
328
|
end
|
305
329
|
|
306
330
|
|
@@ -341,7 +365,14 @@ module RQRCode #:nodoc:
|
|
341
365
|
break
|
342
366
|
end
|
343
367
|
end
|
344
|
-
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
def smallest_size_for(string, max_size_array) #:nodoc:
|
372
|
+
l = string.bytesize
|
373
|
+
ver = max_size_array.index{|i| i >= l}
|
374
|
+
raise QRCodeRunTimeError,"code length overflow. (#{l} digits > any version capacity)" unless ver
|
375
|
+
ver + 1
|
345
376
|
end
|
346
377
|
|
347
378
|
def QRCode.count_max_data_bits(rs_blocks)
|
@@ -354,36 +385,17 @@ module RQRCode #:nodoc:
|
|
354
385
|
|
355
386
|
def QRCode.create_data(version, error_correct_level, data_list) #:nodoc:
|
356
387
|
rs_blocks = QRRSBlock.get_rs_blocks(version, error_correct_level)
|
357
|
-
buffer = QRBitBuffer.new
|
358
|
-
|
359
|
-
data = data_list
|
360
|
-
buffer.put( data.mode, 4 )
|
361
|
-
buffer.put(
|
362
|
-
data.get_length, QRUtil.get_length_in_bits(data.mode, version)
|
363
|
-
)
|
364
|
-
data.write( buffer )
|
365
|
-
|
366
388
|
max_data_bits = QRCode.count_max_data_bits(rs_blocks)
|
389
|
+
buffer = QRBitBuffer.new(version)
|
367
390
|
|
368
|
-
|
369
|
-
|
370
|
-
"code length overflow. (#{buffer.get_length_in_bits}>#{max_data_bits})"
|
371
|
-
end
|
391
|
+
data_list.write(buffer)
|
392
|
+
buffer.end_of_message(max_data_bits)
|
372
393
|
|
373
|
-
if buffer.get_length_in_bits
|
374
|
-
|
375
|
-
end
|
376
|
-
|
377
|
-
while buffer.get_length_in_bits % 8 != 0
|
378
|
-
buffer.put_bit( false )
|
394
|
+
if buffer.get_length_in_bits > max_data_bits
|
395
|
+
raise QRCodeRunTimeError, "code length overflow. (#{buffer.get_length_in_bits}>#{max_data_bits})"
|
379
396
|
end
|
380
397
|
|
381
|
-
|
382
|
-
break if buffer.get_length_in_bits >= max_data_bits
|
383
|
-
buffer.put( QRCode::PAD0, 8 )
|
384
|
-
break if buffer.get_length_in_bits >= max_data_bits
|
385
|
-
buffer.put( QRCode::PAD1, 8 )
|
386
|
-
end
|
398
|
+
buffer.pad_until(max_data_bits)
|
387
399
|
|
388
400
|
QRCode.create_bytes( buffer, rs_blocks )
|
389
401
|
end
|
@@ -433,7 +445,7 @@ module RQRCode #:nodoc:
|
|
433
445
|
if i < dcdata[r].size
|
434
446
|
data[index] = dcdata[r][i]
|
435
447
|
index += 1
|
436
|
-
end
|
448
|
+
end
|
437
449
|
end
|
438
450
|
end
|
439
451
|
|
@@ -442,12 +454,12 @@ module RQRCode #:nodoc:
|
|
442
454
|
if i < ecdata[r].size
|
443
455
|
data[index] = ecdata[r][i]
|
444
456
|
index += 1
|
445
|
-
end
|
457
|
+
end
|
446
458
|
end
|
447
459
|
end
|
448
460
|
|
449
461
|
data
|
450
|
-
end
|
462
|
+
end
|
451
463
|
|
452
464
|
end
|
453
465
|
|
@@ -19,6 +19,7 @@ module RQRCode #:nodoc:
|
|
19
19
|
@data_count = data_count
|
20
20
|
end
|
21
21
|
|
22
|
+
# http://www.thonky.com/qr-code-tutorial/error-correction-table/
|
22
23
|
RQRCode::QRRSBlock::RS_BLOCK_TABLE = [
|
23
24
|
|
24
25
|
# L
|
@@ -114,7 +115,7 @@ RQRCode::QRRSBlock::RS_BLOCK_TABLE = [
|
|
114
115
|
[5, 109, 87, 1, 110, 88],
|
115
116
|
[5, 65, 41, 5, 66, 42],
|
116
117
|
[5, 54, 24, 7, 55, 25],
|
117
|
-
[11, 36, 12],
|
118
|
+
[11, 36, 12, 7, 37, 13],
|
118
119
|
|
119
120
|
# 16
|
120
121
|
[5, 122, 98, 1, 123, 99],
|
@@ -68,7 +68,7 @@ module RQRCode #:nodoc:
|
|
68
68
|
|
69
69
|
BITS_FOR_MODE = {
|
70
70
|
QRMODE[:mode_number] => [10, 12, 14],
|
71
|
-
QRMODE[:
|
71
|
+
QRMODE[:mode_alpha_numk] => [9, 11, 13],
|
72
72
|
QRMODE[:mode_8bit_byte] => [8, 16, 16],
|
73
73
|
QRMODE[:mode_kanji] => [8, 10, 12],
|
74
74
|
}
|
data/lib/rqrcode/version.rb
CHANGED
data/rqrcode.gemspec
CHANGED
@@ -6,23 +6,25 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "rqrcode"
|
7
7
|
s.version = RQRCode::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Duncan Robertson"]
|
10
|
-
s.email = ["
|
11
|
-
s.homepage = "
|
12
|
-
s.summary = "A library to encode QR Codes"
|
9
|
+
s.authors = ["Björn Blomqvist","Duncan Robertson"]
|
10
|
+
s.email = ["darwin@bits2life.com"]
|
11
|
+
s.homepage = "https://github.com/whomwah/rqrcode"
|
12
|
+
s.summary = "A library to encode QR Codes"
|
13
13
|
s.description = <<EOF
|
14
14
|
rQRCode is a library for encoding QR Codes. The simple
|
15
|
-
interface allows you to create QR Code data structures
|
16
|
-
ready to be displayed in the way you choose.
|
15
|
+
interface allows you to create QR Code data structures
|
16
|
+
ready to be displayed in the way you choose.
|
17
17
|
EOF
|
18
|
-
|
18
|
+
|
19
19
|
s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
|
20
|
+
|
21
|
+
s.add_dependency 'chunky_png'
|
20
22
|
|
21
23
|
s.add_development_dependency "rake"
|
22
24
|
s.add_development_dependency("bundler", ">= 1.0.0")
|
23
25
|
|
24
26
|
s.has_rdoc = true
|
25
|
-
s.extra_rdoc_files = ["README.md", "CHANGELOG", "LICENSE"]
|
27
|
+
s.extra_rdoc_files = ["README.md", "CHANGELOG", "LICENSE"]
|
26
28
|
s.files = `git ls-files`.split("\n")
|
27
29
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
28
30
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
data/test/data.rb
CHANGED
@@ -19,3 +19,5 @@ MATRIX_4_L = [[true, true, true, true, true, true, true, false, true, true, true
|
|
19
19
|
MATRIX_4_M = [[true, true, true, true, true, true, true, false, true, true, false, true, false, true, false, true, false, false, true, false, false, false, false, true, true, false, true, true, true, true, true, true, true], [true, false, false, false, false, false, true, false, false, true, false, false, true, true, true, false, true, false, true, true, false, false, false, false, false, false, true, false, false, false, false, false, true], [true, false, true, true, true, false, true, false, false, true, true, false, false, false, true, true, true, true, true, false, true, true, false, false, false, false, true, false, true, true, true, false, true], [true, false, true, true, true, false, true, false, true, true, true, false, false, false, false, false, true, true, false, true, false, true, true, false, false, false, true, false, true, true, true, false, true], [true, false, true, true, true, false, true, false, true, false, false, false, true, true, false, false, true, true, false, true, false, true, true, false, false, false, true, false, true, true, true, false, true], [true, false, false, false, false, false, true, false, true, true, false, false, true, true, true, true, false, false, false, false, true, true, true, true, true, false, true, false, false, false, false, false, true], [true, true, true, true, true, true, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, true, true, true, true, true, true], [false, false, false, false, false, false, false, false, true, false, true, false, false, false, false, false, false, true, true, true, true, true, false, false, true, false, false, false, false, false, false, false, false], [true, false, false, false, true, false, true, true, true, false, true, false, true, false, false, true, true, true, false, false, true, true, true, true, true, true, true, true, true, true, false, false, true], [true, true, false, true, false, false, false, true, false, true, true, false, true, false, true, true, false, true, true, false, false, true, true, true, false, true, false, false, false, true, true, true, true], [false, false, false, false, true, false, true, false, true, false, false, false, true, true, true, true, true, false, true, false, true, false, false, true, true, false, false, false, false, false, true, false, false], [true, false, true, true, true, true, false, true, true, false, true, true, true, true, false, true, true, false, false, false, false, false, true, true, true, true, false, true, true, false, false, true, true], [false, true, true, true, false, true, true, true, true, true, true, true, true, true, false, false, true, false, false, true, false, false, true, false, false, true, true, false, false, true, false, false, true], [true, false, true, true, false, true, false, true, true, false, false, false, true, true, true, false, false, false, true, true, true, false, false, false, true, false, true, true, true, true, false, false, false], [false, true, true, true, false, true, true, false, false, false, true, false, false, true, false, true, false, true, true, false, true, true, true, true, true, true, true, true, false, true, true, true, false], [true, true, false, false, true, false, false, false, false, false, true, true, true, true, false, true, true, true, true, false, false, true, true, true, false, false, true, false, false, false, true, true, true], [false, true, true, true, false, false, true, true, true, false, false, true, true, false, false, false, true, true, false, true, true, true, true, false, false, false, true, false, true, false, true, false, true], [false, false, true, true, true, false, false, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, true, true, false, true, false, true, false, true, true, false, false], [false, false, false, true, false, true, true, true, true, true, true, false, true, true, false, true, true, true, false, false, false, true, true, true, false, true, true, true, false, false, true, true, false], [true, true, false, true, false, false, false, true, false, true, false, false, true, true, true, true, true, true, true, true, false, true, false, false, true, false, true, true, true, true, false, false, false], [false, false, true, false, false, true, true, false, false, false, true, true, false, true, true, false, false, false, true, true, true, false, false, true, true, false, false, true, false, false, false, false, false], [true, true, true, true, false, false, false, false, true, true, true, true, true, false, true, false, true, false, false, true, false, false, true, false, false, true, true, false, false, false, true, false, false], [false, false, false, true, true, true, true, true, true, false, false, true, true, false, true, false, true, false, false, true, false, false, true, false, false, false, false, false, true, false, false, true, false], [false, false, false, false, false, true, false, false, false, true, true, true, false, false, true, false, false, true, true, true, true, true, true, false, true, true, true, true, true, true, false, true, false], [true, true, true, true, true, false, true, true, false, false, true, false, true, false, false, true, true, true, true, false, false, true, true, true, true, true, true, true, true, true, true, true, true], [false, false, false, false, false, false, false, false, true, true, false, false, false, true, false, true, false, true, true, false, false, true, false, false, true, false, false, false, true, true, false, true, false], [true, true, true, true, true, true, true, false, true, true, true, true, true, true, false, true, true, false, true, false, true, false, false, false, true, false, true, false, true, true, true, true, false], [true, false, false, false, false, false, true, false, false, false, true, true, true, false, false, false, true, false, false, true, true, false, true, true, true, false, false, false, true, false, false, false, true], [true, false, true, true, true, false, true, false, true, false, false, true, true, true, true, false, true, false, false, true, false, false, true, false, true, true, true, true, true, false, false, true, true], [true, false, true, true, true, false, true, false, false, false, true, true, true, true, true, false, false, true, true, true, true, true, false, true, false, false, true, false, true, true, false, true, false], [true, false, true, true, true, false, true, false, false, true, false, true, true, false, false, true, false, false, true, false, true, false, false, false, true, false, true, false, true, true, true, false, false], [true, false, false, false, false, false, true, false, false, true, true, false, false, false, false, true, true, true, true, false, false, true, false, false, false, false, false, true, false, false, true, false, false], [true, true, true, true, true, true, true, false, true, true, true, true, false, true, true, false, false, true, false, true, true, true, true, false, true, false, true, false, false, false, true, false, true]]
|
20
20
|
|
21
21
|
MATRIX_4_Q = [[true, true, true, true, true, true, true, false, false, true, true, true, false, true, true, true, false, true, true, false, false, true, true, false, true, false, true, true, true, true, true, true, true], [true, false, false, false, false, false, true, false, true, false, false, true, false, false, false, true, true, false, true, true, false, false, false, false, false, false, true, false, false, false, false, false, true], [true, false, true, true, true, false, true, false, false, false, true, true, true, false, true, false, false, false, false, true, true, true, false, true, true, false, true, false, true, true, true, false, true], [true, false, true, true, true, false, true, false, true, false, false, false, true, true, true, false, true, false, true, true, true, false, true, true, true, false, true, false, true, true, true, false, true], [true, false, true, true, true, false, true, false, true, false, true, true, false, false, true, true, false, false, false, false, false, false, true, true, false, false, true, false, true, true, true, false, true], [true, false, false, false, false, false, true, false, false, true, true, false, true, true, false, true, false, true, false, true, false, true, false, false, true, false, true, false, false, false, false, false, true], [true, true, true, true, true, true, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, true, true, true, true, true, true], [false, false, false, false, false, false, false, false, true, true, false, true, true, true, true, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false], [false, true, false, true, true, true, true, false, true, false, false, false, true, true, false, false, true, true, false, false, false, false, false, true, true, true, true, false, true, true, false, true, false], [false, false, false, true, true, true, false, false, true, true, false, false, true, false, false, true, false, true, true, true, false, true, false, true, false, false, false, false, true, true, true, false, false], [true, false, false, false, true, false, true, false, true, false, true, false, true, true, true, false, true, false, false, false, false, false, true, true, false, false, true, false, true, false, false, true, true], [false, false, false, true, true, false, false, false, false, true, false, false, true, false, true, false, false, false, true, false, false, true, true, true, false, false, true, false, true, false, true, true, true], [true, true, true, false, false, true, true, true, false, true, true, false, true, false, false, true, true, true, false, true, false, true, false, true, false, false, true, true, false, false, false, false, false], [true, false, false, false, true, false, false, false, true, false, false, true, true, false, false, true, false, false, true, true, true, false, false, false, true, true, false, true, false, false, true, false, false], [true, false, true, false, true, true, true, true, false, false, false, false, true, false, true, false, true, true, true, true, true, true, true, false, false, false, true, true, true, false, false, false, false], [true, false, true, true, false, false, false, false, false, true, true, true, true, false, false, false, true, false, false, false, true, false, true, false, true, false, false, false, true, false, true, true, false], [false, false, true, false, false, false, true, false, true, false, true, false, false, true, true, true, false, true, true, false, true, false, true, true, false, true, true, true, true, false, false, true, true], [true, true, false, false, true, false, false, true, false, true, true, false, false, true, false, true, false, true, false, true, true, false, false, false, false, false, true, true, true, false, true, false, true], [true, false, true, true, true, true, true, true, true, false, false, false, true, true, true, false, true, false, false, true, true, true, true, true, true, false, false, true, false, false, false, true, true], [true, false, false, false, true, true, false, false, true, true, false, true, false, false, false, true, true, true, true, false, true, false, true, true, false, true, true, false, false, false, true, false, false], [true, false, true, true, false, true, true, false, true, false, true, true, false, false, false, true, true, true, false, true, false, true, true, true, true, false, false, false, false, false, false, true, false], [true, false, true, false, true, true, false, false, false, true, false, false, false, true, false, false, true, false, true, false, false, false, false, false, false, true, false, false, true, false, true, true, false], [true, false, false, false, true, false, true, false, true, true, false, true, false, false, false, true, true, false, true, true, true, false, false, false, true, false, true, false, false, true, true, true, true], [true, false, false, false, false, false, false, false, true, false, false, false, false, true, true, false, false, true, true, true, true, false, true, false, false, true, true, false, false, true, true, true, false], [true, true, true, false, false, true, true, false, true, true, false, false, true, true, false, false, false, false, true, false, false, false, false, false, true, true, true, true, true, false, false, true, true], [false, false, false, false, false, false, false, false, true, true, false, false, true, false, true, true, true, false, false, false, false, true, false, false, true, false, false, false, true, true, false, false, false], [true, true, true, true, true, true, true, false, false, true, false, true, true, true, true, true, true, false, true, true, true, false, false, true, true, false, true, false, true, false, false, false, false], [true, false, false, false, false, false, true, false, true, true, false, true, true, true, false, false, true, false, false, true, false, true, true, false, true, false, false, false, true, true, true, true, true], [true, false, true, true, true, false, true, false, true, false, true, true, false, false, false, false, true, false, true, false, false, true, true, true, true, true, true, true, true, true, false, true, true], [true, false, true, true, true, false, true, false, true, true, false, false, true, true, true, false, true, false, true, false, false, true, true, false, false, true, false, false, false, true, true, false, true], [true, false, true, true, true, false, true, false, false, true, true, false, true, true, false, false, true, true, true, true, false, false, false, false, false, true, false, false, true, true, true, true, true], [true, false, false, false, false, false, true, false, true, true, false, false, true, false, false, true, false, true, false, true, true, false, true, false, true, false, true, false, true, false, true, true, true], [true, true, true, true, true, true, true, false, false, true, true, false, true, true, true, false, true, false, true, true, false, false, false, false, true, false, true, true, true, true, false, false, false]]
|
22
|
+
|
23
|
+
MATRIX_UTF8_RU_test = [[true, true, true, true, true, true, true, false, true, false, true, true, true, true, true, false, false, false, true, true, true, true, true, true, true], [true, false, false, false, false, false, true, false, false, false, false, false, true, true, true, true, true, false, true, false, false, false, false, false, true], [true, false, true, true, true, false, true, false, true, false, false, true, false, true, true, true, true, false, true, false, true, true, true, false, true], [true, false, true, true, true, false, true, false, false, false, true, false, true, true, false, true, true, false, true, false, true, true, true, false, true], [true, false, true, true, true, false, true, false, true, false, false, true, true, true, false, true, false, false, true, false, true, true, true, false, true], [true, false, false, false, false, false, true, false, false, true, false, false, true, true, false, true, false, false, true, false, false, false, false, false, true], [true, true, true, true, true, true, true, false, true, false, true, false, true, false, true, false, true, false, true, true, true, true, true, true, true], [false, false, false, false, false, false, false, false, true, true, true, false, false, false, false, true, true, false, false, false, false, false, false, false, false], [false, false, false, false, false, true, true, false, false, false, true, false, true, true, false, true, false, false, true, false, true, false, true, false, true], [false, false, false, false, false, true, false, true, true, true, true, true, false, true, true, true, false, false, true, true, false, false, true, true, true], [false, true, true, false, true, true, true, false, false, false, false, false, false, true, false, false, false, false, true, false, true, true, false, true, false], [true, true, false, false, true, false, false, false, false, false, true, false, false, false, false, true, false, true, true, true, true, false, true, false, false], [false, false, false, false, false, false, true, true, false, false, false, false, true, true, false, false, false, true, true, true, true, false, false, true, true], [true, true, true, true, false, true, false, false, false, true, false, true, false, false, true, false, false, true, true, false, false, true, false, false, true], [true, false, false, true, true, false, true, true, true, false, false, true, true, true, false, true, true, true, false, false, true, false, false, false, false], [true, false, false, false, false, false, false, false, true, true, false, false, false, true, false, false, true, false, false, false, true, true, false, true, true], [true, false, true, true, true, true, true, true, false, false, true, false, false, true, true, true, true, true, true, true, true, false, false, false, true], [false, false, false, false, false, false, false, false, true, false, false, false, false, true, true, false, true, false, false, false, true, false, false, true, true], [true, true, true, true, true, true, true, false, false, true, true, true, false, true, false, true, true, false, true, false, true, false, true, false, false], [true, false, false, false, false, false, true, false, true, true, false, false, true, false, true, true, true, false, false, false, true, false, true, false, true], [true, false, true, true, true, false, true, false, false, true, false, true, true, false, false, false, true, true, true, true, true, true, false, false, false], [true, false, true, true, true, false, true, false, false, true, true, true, true, true, false, false, false, true, false, false, true, false, true, false, true], [true, false, true, true, true, false, true, false, false, true, false, false, false, true, false, false, true, false, true, false, true, false, false, false, true], [true, false, false, false, false, false, true, false, false, true, false, false, false, false, true, true, false, false, true, true, false, true, true, false, true], [true, true, true, true, true, true, true, false, false, true, false, true, false, false, false, true, true, false, true, true, true, false, true, false, true]]
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "test/unit"
|
3
|
+
|
4
|
+
# fix for require_relative in < 1.9
|
5
|
+
unless Kernel.respond_to?(:require_relative)
|
6
|
+
module Kernel
|
7
|
+
def require_relative(path)
|
8
|
+
require File.join(File.dirname(caller[0]), path.to_str)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require_relative "../lib/rqrcode"
|
14
|
+
class RegresionTests < Test::Unit::TestCase
|
15
|
+
|
16
|
+
# Rs block information was incomplete.
|
17
|
+
def test_code_length_overflow_bug
|
18
|
+
RQRCode::QRCode.new('s' * 220)
|
19
|
+
RQRCode::QRCode.new('s' * 195)
|
20
|
+
end
|
21
|
+
end
|
data/test/test_rqrcode.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
require "test/unit"
|
2
3
|
|
3
4
|
# fix for require_relative in < 1.9
|
@@ -13,7 +14,7 @@ require_relative "../lib/rqrcode"
|
|
13
14
|
|
14
15
|
class QRCodeTest < Test::Unit::TestCase
|
15
16
|
require_relative "data"
|
16
|
-
|
17
|
+
|
17
18
|
def test_no_data_given
|
18
19
|
assert_raise(RQRCode::QRCodeArgumentError) {
|
19
20
|
RQRCode::QRCode.new( :size => 1, :level => :h )
|
@@ -65,13 +66,13 @@ class QRCodeTest < Test::Unit::TestCase
|
|
65
66
|
|
66
67
|
def test_4_H_
|
67
68
|
qr = RQRCode::QRCode.new('www.bbc.co.uk/programmes/b0090blw',
|
68
|
-
:level => :l )
|
69
|
+
:level => :l, :size => 4 )
|
69
70
|
assert_equal qr.modules, MATRIX_4_L
|
70
71
|
qr = RQRCode::QRCode.new('www.bbc.co.uk/programmes/b0090blw',
|
71
|
-
:level => :m )
|
72
|
+
:level => :m, :size => 4 )
|
72
73
|
assert_equal qr.modules, MATRIX_4_M
|
73
74
|
qr = RQRCode::QRCode.new('www.bbc.co.uk/programmes/b0090blw',
|
74
|
-
:level => :q )
|
75
|
+
:level => :q, :size => 4 )
|
75
76
|
assert_equal qr.modules, MATRIX_4_Q
|
76
77
|
|
77
78
|
qr = RQRCode::QRCode.new('www.bbc.co.uk/programmes/b0090blw')
|
@@ -86,6 +87,14 @@ class QRCodeTest < Test::Unit::TestCase
|
|
86
87
|
qr.to_s( :true => 'q', :false => 'n' )[0..21]
|
87
88
|
assert_equal "@@@@@@@ @@ @ @@@@@@@\n", qr.to_s( :true => '@' )[0..21]
|
88
89
|
end
|
90
|
+
|
91
|
+
def test_auto_alphanumeric
|
92
|
+
# Overflowws without the alpha version
|
93
|
+
assert RQRCode::QRCode.new( '1234567890', :size => 1, :level => :h )
|
94
|
+
|
95
|
+
qr = RQRCode::QRCode.new( 'DUNCAN', :size => 1, :level => :h )
|
96
|
+
assert_equal "xxxxxxx xxx xxxxxxx\n", qr.to_s[0..21]
|
97
|
+
end
|
89
98
|
|
90
99
|
def test_rszf_error_not_thrown
|
91
100
|
assert RQRCode::QRCode.new('2 1058 657682')
|
@@ -98,11 +107,17 @@ class QRCodeTest < Test::Unit::TestCase
|
|
98
107
|
assert RQRCode::QRCode.new("duncan", :level => :m)
|
99
108
|
assert RQRCode::QRCode.new("duncan", :level => :q)
|
100
109
|
assert RQRCode::QRCode.new("duncan", :level => :h)
|
101
|
-
|
102
|
-
|
110
|
+
|
111
|
+
%w(a b c d e f g i j k n o p r s t u v w x y z).each do |ltr|
|
112
|
+
assert_raise(RQRCode::QRCodeArgumentError) {
|
103
113
|
RQRCode::QRCode.new( "duncan", :level => ltr.to_sym )
|
104
|
-
|
105
|
-
|
114
|
+
}
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_utf8
|
119
|
+
qr = RQRCode::QRCode.new('тест')
|
120
|
+
assert_equal qr.modules, MATRIX_UTF8_RU_test
|
106
121
|
end
|
107
122
|
|
108
123
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
require 'rqrcode/export/png'
|
5
|
+
require 'rqrcode/export/svg'
|
6
|
+
require 'rqrcode/export/html'
|
7
|
+
|
8
|
+
# fix for require_relative in < 1.9
|
9
|
+
unless Kernel.respond_to?(:require_relative)
|
10
|
+
module Kernel
|
11
|
+
def require_relative(path)
|
12
|
+
require File.join(File.dirname(caller[0]), path.to_str)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require_relative "../lib/rqrcode"
|
18
|
+
|
19
|
+
describe :QRCodeExportTest do
|
20
|
+
# require_relative "data"
|
21
|
+
|
22
|
+
[:svg, :png, :html].each do |ext|
|
23
|
+
it "must respond_to #{ext}" do
|
24
|
+
RQRCode::QRCode.new('x').must_respond_to :"as_#{ext}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "must export to png file" do
|
29
|
+
RQRCode::QRCode.new('png').as_png.must_be_instance_of ChunkyPNG::Image
|
30
|
+
end
|
31
|
+
|
32
|
+
it "must export to svg file" do
|
33
|
+
RQRCode::QRCode.new('svg').as_svg.must_match(/<\/svg>/)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "must export to html" do
|
37
|
+
RQRCode::QRCode.new('html').as_html.must_match(/<table>.+<\/table>/)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
metadata
CHANGED
@@ -1,69 +1,91 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rqrcode
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.4.2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.6.0
|
6
5
|
platform: ruby
|
7
|
-
authors:
|
6
|
+
authors:
|
7
|
+
- Björn Blomqvist
|
8
8
|
- Duncan Robertson
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
date: 2015-06-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: chunky_png
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
17
22
|
prerelease: false
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '>='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
24
35
|
type: :development
|
25
|
-
version_requirements: *id001
|
26
|
-
- !ruby/object:Gem::Dependency
|
27
|
-
name: bundler
|
28
36
|
prerelease: false
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: bundler
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '>='
|
47
|
+
- !ruby/object:Gem::Version
|
34
48
|
version: 1.0.0
|
35
49
|
type: :development
|
36
|
-
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.0.0
|
37
56
|
description: |
|
38
57
|
rQRCode is a library for encoding QR Codes. The simple
|
39
|
-
interface allows you to create QR Code data structures
|
40
|
-
ready to be displayed in the way you choose.
|
41
|
-
|
42
|
-
|
43
|
-
- duncan@whomwah.com
|
58
|
+
interface allows you to create QR Code data structures
|
59
|
+
ready to be displayed in the way you choose.
|
60
|
+
email:
|
61
|
+
- darwin@bits2life.com
|
44
62
|
executables: []
|
45
|
-
|
46
63
|
extensions: []
|
47
|
-
|
48
|
-
extra_rdoc_files:
|
64
|
+
extra_rdoc_files:
|
49
65
|
- README.md
|
50
66
|
- CHANGELOG
|
51
67
|
- LICENSE
|
52
|
-
files:
|
68
|
+
files:
|
53
69
|
- .gitignore
|
70
|
+
- .travis.yml
|
54
71
|
- CHANGELOG
|
55
72
|
- Gemfile
|
56
73
|
- LICENSE
|
57
74
|
- README.md
|
58
75
|
- Rakefile
|
76
|
+
- TODO.md
|
59
77
|
- lib/rqrcode.rb
|
60
78
|
- lib/rqrcode/core_ext.rb
|
61
79
|
- lib/rqrcode/core_ext/array.rb
|
62
80
|
- lib/rqrcode/core_ext/array/behavior.rb
|
63
81
|
- lib/rqrcode/core_ext/integer.rb
|
64
82
|
- lib/rqrcode/core_ext/integer/bitwise.rb
|
83
|
+
- lib/rqrcode/export/html.rb
|
84
|
+
- lib/rqrcode/export/png.rb
|
85
|
+
- lib/rqrcode/export/svg.rb
|
65
86
|
- lib/rqrcode/qrcode.rb
|
66
87
|
- lib/rqrcode/qrcode/qr_8bit_byte.rb
|
88
|
+
- lib/rqrcode/qrcode/qr_alphanumeric.rb
|
67
89
|
- lib/rqrcode/qrcode/qr_bit_buffer.rb
|
68
90
|
- lib/rqrcode/qrcode/qr_code.rb
|
69
91
|
- lib/rqrcode/qrcode/qr_math.rb
|
@@ -73,34 +95,34 @@ files:
|
|
73
95
|
- lib/rqrcode/version.rb
|
74
96
|
- rqrcode.gemspec
|
75
97
|
- test/data.rb
|
98
|
+
- test/test_regresions.rb
|
76
99
|
- test/test_rqrcode.rb
|
77
|
-
|
100
|
+
- test/test_rqrcode_export.rb
|
101
|
+
homepage: https://github.com/whomwah/rqrcode
|
78
102
|
licenses: []
|
79
|
-
|
103
|
+
metadata: {}
|
80
104
|
post_install_message:
|
81
105
|
rdoc_options: []
|
82
|
-
|
83
|
-
require_paths:
|
106
|
+
require_paths:
|
84
107
|
- lib
|
85
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
96
117
|
version: 1.3.6
|
97
118
|
requirements: []
|
98
|
-
|
99
119
|
rubyforge_project:
|
100
|
-
rubygems_version: 1.
|
120
|
+
rubygems_version: 2.1.11
|
101
121
|
signing_key:
|
102
|
-
specification_version:
|
122
|
+
specification_version: 4
|
103
123
|
summary: A library to encode QR Codes
|
104
|
-
test_files:
|
124
|
+
test_files:
|
105
125
|
- test/data.rb
|
126
|
+
- test/test_regresions.rb
|
106
127
|
- test/test_rqrcode.rb
|
128
|
+
- test/test_rqrcode_export.rb
|