lib/rqrcode/qrcode/qr_code.rb in rqrcode-0.4.0 vs lib/rqrcode/qrcode/qr_code.rb in rqrcode-0.4.1
- old
+ new
@@ -45,10 +45,13 @@
Proc.new { |i,j| (i * j) % 2 + (i * j) % 3 == 0 },
Proc.new { |i,j| ((i * j) % 2 + (i * j) % 3) % 2 == 0 },
Proc.new { |i,j| ((i * j) % 3 + (i + j) % 2) % 2 == 0 },
]
+ QRPOSITIONPATTERNLENGTH = (7 + 1) * 2 + 1
+ QRFORMATINFOLENGTH = 15
+
# StandardErrors
class QRCodeArgumentError < ArgumentError; end
class QRCodeRunTimeError < RuntimeError; end
@@ -93,12 +96,12 @@
raise QRCodeArgumentError, "Unknown error correction level `#{level.inspect}`"
end
@data = string
@error_correct_level = QRERRORCORRECTLEVEL[level]
- @type_number = size
- @module_count = @type_number * 4 + 17
+ @version = size
+ @module_count = @version * 4 + QRPOSITIONPATTERNLENGTH
@modules = Array.new( @module_count )
@data_list = QR8bitByte.new( @data )
@data_cache = nil
self.make
@@ -111,11 +114,11 @@
#
# instance.is_dark( 10, 10 ) => true
#
def is_dark( row, col )
- if row < 0 || @module_count <= row || col < 0 || @module_count <= col
+ if !row.between?(0, @module_count - 1) || !col.between?(0, @module_count - 1)
raise QRCodeRunTimeError, "Invalid row/column pair: #{row}, #{col}"
end
@modules[row][col]
end
@@ -161,50 +164,57 @@
end
protected
def make #:nodoc:
+ prepare_common_patterns
make_impl( false, get_best_mask_pattern )
end
private
+ def prepare_common_patterns
+ @modules.map! { |row| Array.new(@module_count) }
- def make_impl( test, mask_pattern ) #:nodoc:
+ place_position_probe_pattern(0, 0)
+ place_position_probe_pattern(@module_count - 7, 0)
+ place_position_probe_pattern(0, @module_count - 7)
+ place_position_adjust_pattern
+ place_timing_pattern
- ( 0...@module_count ).each do |row|
- @modules[row] = Array.new( @module_count )
- end
+ @common_patterns = @modules.map(&:clone)
+ end
- setup_position_probe_pattern( 0, 0 )
- setup_position_probe_pattern( @module_count - 7, 0 )
- setup_position_probe_pattern( 0, @module_count - 7 )
- setup_position_adjust_pattern
- setup_timing_pattern
- setup_type_info( test, mask_pattern )
- setup_type_number( test ) if @type_number >= 7
+ def make_impl( test, mask_pattern ) #:nodoc:
+ @modules = @common_patterns.map(&:clone)
+ place_format_info(test, mask_pattern)
+ place_version_info(test) if @version >= 7
+
if @data_cache.nil?
@data_cache = QRCode.create_data(
- @type_number, @error_correct_level, @data_list
+ @version, @error_correct_level, @data_list
)
end
map_data( @data_cache, mask_pattern )
end
- def setup_position_probe_pattern( row, col ) #:nodoc:
- ( -1..7 ).each do |r|
- next if ( row + r ) <= -1 || @module_count <= ( row + r )
- ( -1..7 ).each do |c|
- next if ( col + c ) <= -1 || @module_count <= ( col + c )
- if 0 <= r && r <= 6 && ( c == 0 || c == 6 ) || 0 <= c && c <= 6 && ( r == 0 || r == 6 ) || 2 <= r && r <= 4 && 2 <= c && c <= 4
- @modules[row + r][col + c] = true;
- else
- @modules[row + r][col + c] = false;
- end
+ def place_position_probe_pattern( row, col ) #:nodoc:
+ (-1..7).each do |r|
+ next if !(row + r).between?(0, @module_count - 1)
+
+ (-1..7).each do |c|
+ next if !(col + c).between?(0, @module_count - 1)
+
+ is_vert_line = (r.between?(0, 6) && (c == 0 || c == 6))
+ is_horiz_line = (c.between?(0, 6) && (r == 0 || r == 6))
+ is_square = r.between?(2,4) && c.between?(2, 4)
+
+ is_part_of_probe = is_vert_line || is_horiz_line || is_square
+ @modules[row + r][col + c] = is_part_of_probe
end
end
end
@@ -223,76 +233,72 @@
end
pattern
end
- def setup_timing_pattern #:nodoc:
+ def place_timing_pattern #:nodoc:
( 8...@module_count - 8 ).each do |i|
@modules[i][6] = @modules[6][i] = i % 2 == 0
end
end
- def setup_position_adjust_pattern #:nodoc:
- pos = QRUtil.get_pattern_position(@type_number)
+ def place_position_adjust_pattern #:nodoc:
+ positions = QRUtil.get_pattern_positions(@version)
- ( 0...pos.size ).each do |i|
- ( 0...pos.size ).each do |j|
- row = pos[i]
- col = pos[j]
-
+ positions.each do |row|
+ positions.each do |col|
next unless @modules[row][col].nil?
( -2..2 ).each do |r|
( -2..2 ).each do |c|
- if r == -2 || r == 2 || c == -2 || c == 2 || ( r == 0 && c == 0 )
- @modules[row + r][col + c] = true
- else
- @modules[row + r][col + c] = false
- end
+ is_part_of_pattern = (r.abs == 2 || c.abs == 2 || ( r == 0 && c == 0 ))
+ @modules[row + r][col + c] = is_part_of_pattern
end
end
end
end
end
- def setup_type_number( test ) #:nodoc:
- bits = QRUtil.get_bch_type_number( @type_number )
+ def place_version_info(test) #:nodoc:
+ bits = QRUtil.get_bch_version(@version)
( 0...18 ).each do |i|
mod = ( !test && ( (bits >> i) & 1) == 1 )
@modules[ (i / 3).floor ][ i % 3 + @module_count - 8 - 3 ] = mod
@modules[ i % 3 + @module_count - 8 - 3 ][ (i / 3).floor ] = mod
end
end
- def setup_type_info( test, mask_pattern ) #:nodoc:
+ def place_format_info(test, mask_pattern) #:nodoc:
data = (@error_correct_level << 3 | mask_pattern)
- bits = QRUtil.get_bch_type_info( data )
+ bits = QRUtil.get_bch_format_info(data)
- ( 0...15 ).each do |i|
+ QRFORMATINFOLENGTH.times do |i|
mod = (!test && ( (bits >> i) & 1) == 1)
# vertical
if i < 6
- @modules[i][8] = mod
+ row = i
elsif i < 8
- @modules[ i + 1 ][8] = mod
+ row = i + 1
else
- @modules[ @module_count - 15 + i ][8] = mod
+ row = @module_count - 15 + i
end
+ @modules[row][8] = mod
# horizontal
if i < 8
- @modules[8][ @module_count - i - 1 ] = mod
+ col = @module_count - i - 1
elsif i < 9
- @modules[8][ 15 - i - 1 + 1 ] = mod
+ col = 15 - i - 1 + 1
else
- @modules[8][ 15 - i - 1 ] = mod
+ col = 15 - i - 1
end
+ @modules[8][col] = mod
end
# fixed module
@modules[ @module_count - 8 ][8] = !test
end
@@ -344,17 +350,17 @@
end
return max_data_bytes * 8
end
- def QRCode.create_data( type_number, error_correct_level, data_list ) #:nodoc:
- rs_blocks = QRRSBlock.get_rs_blocks( type_number, error_correct_level )
+ def QRCode.create_data(version, error_correct_level, data_list) #:nodoc:
+ rs_blocks = QRRSBlock.get_rs_blocks(version, error_correct_level)
buffer = QRBitBuffer.new
data = data_list
buffer.put( data.mode, 4 )
buffer.put(
- data.get_length, QRUtil.get_length_in_bits( data.mode, type_number )
+ data.get_length, QRUtil.get_length_in_bits(data.mode, version)
)
data.write( buffer )
max_data_bits = QRCode.count_max_data_bits(rs_blocks)