Go hog wild
This commit is contained in:
parent
1d82f60465
commit
ea346f1142
|
@ -2,8 +2,8 @@
|
||||||
name = "qrcode"
|
name = "qrcode"
|
||||||
description = "QR code encoder in Rust"
|
description = "QR code encoder in Rust"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
version = "0.12.0"
|
version = "0.13.0"
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
authors = ["kennytm <kennytm@gmail.com>"]
|
authors = ["kennytm <kennytm@gmail.com>"]
|
||||||
keywords = ["qrcode"]
|
keywords = ["qrcode"]
|
||||||
repository = "https://github.com/kennytm/qrcode-rust"
|
repository = "https://github.com/kennytm/qrcode-rust"
|
||||||
|
|
|
@ -101,7 +101,7 @@ impl Canvas {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn to_debug_str(&self) -> String {
|
fn to_debug_str(&self) -> String {
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
let mut res = String::with_capacity((width * (width + 1)) as usize);
|
let mut res = String::with_capacity((width * (width + 1)).as_usize());
|
||||||
for y in 0..width {
|
for y in 0..width {
|
||||||
res.push('\n');
|
res.push('\n');
|
||||||
for x in 0..width {
|
for x in 0..width {
|
||||||
|
@ -1765,7 +1765,7 @@ impl Canvas {
|
||||||
Box::new(|k| self.get(i, k).into())
|
Box::new(|k| self.get(i, k).into())
|
||||||
};
|
};
|
||||||
|
|
||||||
if (j..(j + 7)).map(&*get).ne(PATTERN.iter().cloned()) {
|
if (j..(j + 7)).map(&*get).ne(PATTERN.iter().copied()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1829,6 +1829,7 @@ impl Canvas {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod penalty_tests {
|
mod penalty_tests {
|
||||||
use crate::canvas::{Canvas, MaskPattern};
|
use crate::canvas::{Canvas, MaskPattern};
|
||||||
|
use crate::cast::As;
|
||||||
use crate::types::{Color, EcLevel, Version};
|
use crate::types::{Color, EcLevel, Version};
|
||||||
|
|
||||||
fn create_test_canvas() -> Canvas {
|
fn create_test_canvas() -> Canvas {
|
||||||
|
@ -1941,8 +1942,8 @@ mod penalty_tests {
|
||||||
|
|
||||||
let mut c = Canvas::new(Version::Micro(4), EcLevel::Q);
|
let mut c = Canvas::new(Version::Micro(4), EcLevel::Q);
|
||||||
for i in 0_i16..17 {
|
for i in 0_i16..17 {
|
||||||
c.put(i, -1, HORIZONTAL_SIDE[i as usize]);
|
c.put(i, -1, HORIZONTAL_SIDE[i.as_usize()]);
|
||||||
c.put(-1, i, VERTICAL_SIDE[i as usize]);
|
c.put(-1, i, VERTICAL_SIDE[i.as_usize()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(c.compute_light_side_penalty_score(), 168);
|
assert_eq!(c.compute_light_side_penalty_score(), 168);
|
||||||
|
@ -1970,6 +1971,7 @@ static ALL_PATTERNS_MICRO_QR: [MaskPattern; 4] =
|
||||||
impl Canvas {
|
impl Canvas {
|
||||||
/// Construct a new canvas and apply the best masking that gives the lowest
|
/// Construct a new canvas and apply the best masking that gives the lowest
|
||||||
/// penalty score.
|
/// penalty score.
|
||||||
|
#[must_use]
|
||||||
pub fn apply_best_mask(&self) -> Self {
|
pub fn apply_best_mask(&self) -> Self {
|
||||||
match self.version {
|
match self.version {
|
||||||
Version::Normal(_) => ALL_PATTERNS_QR.iter(),
|
Version::Normal(_) => ALL_PATTERNS_QR.iter(),
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#![deny(warnings, clippy::pedantic)]
|
#![deny(warnings, clippy::pedantic)]
|
||||||
#![allow(
|
#![allow(
|
||||||
clippy::must_use_candidate, // This is just annoying.
|
clippy::must_use_candidate, // This is just annoying.
|
||||||
clippy::use_self, // Rust 1.33 doesn't support Self::EnumVariant, let's try again in 1.37.
|
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(feature = "bench", doc(include = "../README.md"))]
|
#![cfg_attr(feature = "bench", doc(include = "../README.md"))]
|
||||||
// ^ make sure we can test our README.md.
|
// ^ make sure we can test our README.md.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(clippy::unicode_not_nfc)]
|
||||||
//! Find the optimal data mode sequence to encode a piece of data.
|
//! Find the optimal data mode sequence to encode a piece of data.
|
||||||
use crate::types::{Mode, Version};
|
use crate::types::{Mode, Version};
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
|
@ -339,7 +340,7 @@ mod optimize_tests {
|
||||||
use crate::optimize::{total_encoded_len, Optimizer, Segment};
|
use crate::optimize::{total_encoded_len, Optimizer, Segment};
|
||||||
use crate::types::{Mode, Version};
|
use crate::types::{Mode, Version};
|
||||||
|
|
||||||
fn test_optimization_result(given: Vec<Segment>, expected: Vec<Segment>, version: Version) {
|
fn test_optimization_result(given: &[Segment], expected: &[Segment], version: Version) {
|
||||||
let prev_len = total_encoded_len(&*given, version);
|
let prev_len = total_encoded_len(&*given, version);
|
||||||
let opt_segs = Optimizer::new(given.iter().copied(), version).collect::<Vec<_>>();
|
let opt_segs = Optimizer::new(given.iter().copied(), version).collect::<Vec<_>>();
|
||||||
let new_len = total_encoded_len(&*opt_segs, version);
|
let new_len = total_encoded_len(&*opt_segs, version);
|
||||||
|
@ -358,15 +359,12 @@ mod optimize_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_example_1() {
|
fn test_example_1() {
|
||||||
test_optimization_result(
|
test_optimization_result(
|
||||||
vec![
|
&[
|
||||||
Segment { mode: Mode::Alphanumeric, begin: 0, end: 3 },
|
Segment { mode: Mode::Alphanumeric, begin: 0, end: 3 },
|
||||||
Segment { mode: Mode::Numeric, begin: 3, end: 6 },
|
Segment { mode: Mode::Numeric, begin: 3, end: 6 },
|
||||||
Segment { mode: Mode::Byte, begin: 6, end: 10 },
|
Segment { mode: Mode::Byte, begin: 6, end: 10 },
|
||||||
],
|
],
|
||||||
vec![
|
&[Segment { mode: Mode::Alphanumeric, begin: 0, end: 6 }, Segment { mode: Mode::Byte, begin: 6, end: 10 }],
|
||||||
Segment { mode: Mode::Alphanumeric, begin: 0, end: 6 },
|
|
||||||
Segment { mode: Mode::Byte, begin: 6, end: 10 },
|
|
||||||
],
|
|
||||||
Version::Normal(1),
|
Version::Normal(1),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -374,14 +372,14 @@ mod optimize_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_example_2() {
|
fn test_example_2() {
|
||||||
test_optimization_result(
|
test_optimization_result(
|
||||||
vec![
|
&[
|
||||||
Segment { mode: Mode::Numeric, begin: 0, end: 29 },
|
Segment { mode: Mode::Numeric, begin: 0, end: 29 },
|
||||||
Segment { mode: Mode::Alphanumeric, begin: 29, end: 30 },
|
Segment { mode: Mode::Alphanumeric, begin: 29, end: 30 },
|
||||||
Segment { mode: Mode::Numeric, begin: 30, end: 32 },
|
Segment { mode: Mode::Numeric, begin: 30, end: 32 },
|
||||||
Segment { mode: Mode::Alphanumeric, begin: 32, end: 35 },
|
Segment { mode: Mode::Alphanumeric, begin: 32, end: 35 },
|
||||||
Segment { mode: Mode::Numeric, begin: 35, end: 38 },
|
Segment { mode: Mode::Numeric, begin: 35, end: 38 },
|
||||||
],
|
],
|
||||||
vec![
|
&[
|
||||||
Segment { mode: Mode::Numeric, begin: 0, end: 29 },
|
Segment { mode: Mode::Numeric, begin: 0, end: 29 },
|
||||||
Segment { mode: Mode::Alphanumeric, begin: 29, end: 38 },
|
Segment { mode: Mode::Alphanumeric, begin: 29, end: 38 },
|
||||||
],
|
],
|
||||||
|
@ -392,13 +390,13 @@ mod optimize_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_example_3() {
|
fn test_example_3() {
|
||||||
test_optimization_result(
|
test_optimization_result(
|
||||||
vec![
|
&[
|
||||||
Segment { mode: Mode::Kanji, begin: 0, end: 4 },
|
Segment { mode: Mode::Kanji, begin: 0, end: 4 },
|
||||||
Segment { mode: Mode::Alphanumeric, begin: 4, end: 5 },
|
Segment { mode: Mode::Alphanumeric, begin: 4, end: 5 },
|
||||||
Segment { mode: Mode::Byte, begin: 5, end: 6 },
|
Segment { mode: Mode::Byte, begin: 5, end: 6 },
|
||||||
Segment { mode: Mode::Kanji, begin: 6, end: 8 },
|
Segment { mode: Mode::Kanji, begin: 6, end: 8 },
|
||||||
],
|
],
|
||||||
vec![Segment { mode: Mode::Byte, begin: 0, end: 8 }],
|
&[Segment { mode: Mode::Byte, begin: 0, end: 8 }],
|
||||||
Version::Normal(1),
|
Version::Normal(1),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -406,8 +404,8 @@ mod optimize_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_example_4() {
|
fn test_example_4() {
|
||||||
test_optimization_result(
|
test_optimization_result(
|
||||||
vec![Segment { mode: Mode::Kanji, begin: 0, end: 10 }, Segment { mode: Mode::Byte, begin: 10, end: 11 }],
|
&[Segment { mode: Mode::Kanji, begin: 0, end: 10 }, Segment { mode: Mode::Byte, begin: 10, end: 11 }],
|
||||||
vec![Segment { mode: Mode::Kanji, begin: 0, end: 10 }, Segment { mode: Mode::Byte, begin: 10, end: 11 }],
|
&[Segment { mode: Mode::Kanji, begin: 0, end: 10 }, Segment { mode: Mode::Byte, begin: 10, end: 11 }],
|
||||||
Version::Normal(1),
|
Version::Normal(1),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -415,11 +413,11 @@ mod optimize_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_annex_j_guideline_1a() {
|
fn test_annex_j_guideline_1a() {
|
||||||
test_optimization_result(
|
test_optimization_result(
|
||||||
vec![
|
&[
|
||||||
Segment { mode: Mode::Numeric, begin: 0, end: 3 },
|
Segment { mode: Mode::Numeric, begin: 0, end: 3 },
|
||||||
Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 },
|
Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 },
|
||||||
],
|
],
|
||||||
vec![
|
&[
|
||||||
Segment { mode: Mode::Numeric, begin: 0, end: 3 },
|
Segment { mode: Mode::Numeric, begin: 0, end: 3 },
|
||||||
Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 },
|
Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 },
|
||||||
],
|
],
|
||||||
|
@ -430,11 +428,11 @@ mod optimize_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_annex_j_guideline_1b() {
|
fn test_annex_j_guideline_1b() {
|
||||||
test_optimization_result(
|
test_optimization_result(
|
||||||
vec![
|
&[
|
||||||
Segment { mode: Mode::Numeric, begin: 0, end: 2 },
|
Segment { mode: Mode::Numeric, begin: 0, end: 2 },
|
||||||
Segment { mode: Mode::Alphanumeric, begin: 2, end: 4 },
|
Segment { mode: Mode::Alphanumeric, begin: 2, end: 4 },
|
||||||
],
|
],
|
||||||
vec![Segment { mode: Mode::Alphanumeric, begin: 0, end: 4 }],
|
&[Segment { mode: Mode::Alphanumeric, begin: 0, end: 4 }],
|
||||||
Version::Micro(2),
|
Version::Micro(2),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -442,11 +440,11 @@ mod optimize_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_annex_j_guideline_1c() {
|
fn test_annex_j_guideline_1c() {
|
||||||
test_optimization_result(
|
test_optimization_result(
|
||||||
vec![
|
&[
|
||||||
Segment { mode: Mode::Numeric, begin: 0, end: 3 },
|
Segment { mode: Mode::Numeric, begin: 0, end: 3 },
|
||||||
Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 },
|
Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 },
|
||||||
],
|
],
|
||||||
vec![Segment { mode: Mode::Alphanumeric, begin: 0, end: 4 }],
|
&[Segment { mode: Mode::Alphanumeric, begin: 0, end: 4 }],
|
||||||
Version::Micro(3),
|
Version::Micro(3),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,9 @@ pub struct Renderer<'a, P: Pixel> {
|
||||||
|
|
||||||
impl<'a, P: Pixel> Renderer<'a, P> {
|
impl<'a, P: Pixel> Renderer<'a, P> {
|
||||||
/// Creates a new renderer.
|
/// Creates a new renderer.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// panics if content is not `modules_count` squared big
|
||||||
pub fn new(content: &'a [Color], modules_count: usize, quiet_zone: u32) -> Renderer<'a, P> {
|
pub fn new(content: &'a [Color], modules_count: usize, quiet_zone: u32) -> Renderer<'a, P> {
|
||||||
assert!(modules_count * modules_count == content.len());
|
assert!(modules_count * modules_count == content.len());
|
||||||
Renderer {
|
Renderer {
|
||||||
|
|
|
@ -20,7 +20,7 @@ impl Element for char {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_to_string(self, string: &mut String) {
|
fn append_to_string(self, string: &mut String) {
|
||||||
string.push(self)
|
string.push(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ impl<'a> Element for &'a str {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_to_string(self, string: &mut String) {
|
fn append_to_string(self, string: &mut String) {
|
||||||
string.push_str(self)
|
string.push_str(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
//! let svg_xml = code.render::<svg::Color>().build();
|
//! let svg_xml = code.render::<svg::Color>().build();
|
||||||
//! println!("{}", svg_xml);
|
//! println!("{}", svg_xml);
|
||||||
|
|
||||||
#![cfg(feature="svg")]
|
#![cfg(feature = "svg")]
|
||||||
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
@ -62,7 +62,7 @@ impl<'a> RenderCanvas for Canvas<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_dark_pixel(&mut self, x: u32, y: u32) {
|
fn draw_dark_pixel(&mut self, x: u32, y: u32) {
|
||||||
self.draw_dark_rect(x, y, 1, 1)
|
self.draw_dark_rect(x, y, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_dark_rect(&mut self, left: u32, top: u32, width: u32, height: u32) {
|
fn draw_dark_rect(&mut self, left: u32, top: u32, width: u32, height: u32) {
|
||||||
|
|
|
@ -111,7 +111,7 @@ fn integration_render_utf8_1x2() {
|
||||||
+ " ▀███▄ ▀▀ █ ██ \n"
|
+ " ▀███▄ ▀▀ █ ██ \n"
|
||||||
+ " ▀▀▀ ▀ ▀▀ ▀ ▀ \n"
|
+ " ▀▀▀ ▀ ▀▀ ▀ ▀ \n"
|
||||||
+ " "
|
+ " "
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -173,7 +173,7 @@ impl Version {
|
||||||
pub fn mode_bits_count(self) -> usize {
|
pub fn mode_bits_count(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
Version::Micro(a) => (a - 1).as_usize(),
|
Version::Micro(a) => (a - 1).as_usize(),
|
||||||
_ => 4,
|
Version::Normal(_) => 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,6 +273,7 @@ impl Mode {
|
||||||
/// assert!(a <= c);
|
/// assert!(a <= c);
|
||||||
/// assert!(b <= c);
|
/// assert!(b <= c);
|
||||||
///
|
///
|
||||||
|
#[must_use]
|
||||||
pub fn max(self, other: Self) -> Self {
|
pub fn max(self, other: Self) -> Self {
|
||||||
match self.partial_cmp(&other) {
|
match self.partial_cmp(&other) {
|
||||||
Some(Ordering::Less | Ordering::Equal) => other,
|
Some(Ordering::Less | Ordering::Equal) => other,
|
||||||
|
|
Loading…
Reference in a new issue