Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add image_gap to Builder #51

Merged
merged 1 commit into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/convert/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,13 @@ impl Builder for ImageBuilder {
self
}

fn image_size(&mut self, image_size: f64, gap: f64) -> &mut Self {
self.svg_builder.image_size(image_size, gap);
fn image_size(&mut self, image_size: f64) -> &mut Self {
self.svg_builder.image_size(image_size);
self
}

fn image_gap(&mut self, gap: f64) -> &mut Self {
self.svg_builder.image_gap(gap);
self
}

Expand Down
4 changes: 3 additions & 1 deletion src/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,9 @@ pub trait Builder {
-> &mut Self;
/// Updates the image size and the gap between the image and the [`crate::QRCode`]
/// Default is around 30% of the [`crate::QRCode`] size
fn image_size(&mut self, image_size: f64, gap: f64) -> &mut Self;
fn image_size(&mut self, image_size: f64) -> &mut Self;
/// Updates the gap between the image and the [`crate::QRCode`]
fn image_gap(&mut self, gap: f64) -> &mut Self;
/// Updates the image position, anchor is the center of the image. Default is the center of the [`crate::QRCode`]
fn image_position(&mut self, x: f64, y: f64) -> &mut Self;
}
72 changes: 39 additions & 33 deletions src/convert/svg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ pub struct SvgBuilder {
image_background_color: Color,
/// Background shape for the image, default is square
image_background_shape: ImageBackgroundShape,
/// Size of the image, default is ~1/3 of the svg
image_size: Option<(f64, f64)>,
/// Size of the image (in module size), default is ~1/3 of the svg
image_size: Option<f64>,
/// Gap between the image and the border (in module size), default is calculated
image_gap: Option<f64>,
/// Position of the image, default is center
image_position: Option<(f64, f64)>,
}
Expand Down Expand Up @@ -79,6 +81,7 @@ impl Default for SvgBuilder {
image_background_color: [255; 4].into(),
image_background_shape: ImageBackgroundShape::Square,
image_size: None,
image_gap: None,
image_position: None,
}
}
Expand Down Expand Up @@ -130,8 +133,13 @@ impl Builder for SvgBuilder {
self
}

fn image_size(&mut self, image_size: f64, gap: f64) -> &mut Self {
self.image_size = Some((image_size, gap));
fn image_size(&mut self, image_size: f64) -> &mut Self {
self.image_size = Some(image_size);
self
}

fn image_gap(&mut self, gap: f64) -> &mut Self {
self.image_gap = Some(gap);
self
}

Expand All @@ -142,31 +150,26 @@ impl Builder for SvgBuilder {
}

impl SvgBuilder {
fn image_placement(
image_background_shape: ImageBackgroundShape,
margin: usize,
n: usize,
) -> (f64, (f64, f64), f64) {
fn image_placement(image_background_shape: ImageBackgroundShape, n: usize) -> (f64, f64) {
use ImageBackgroundShape::{Circle, RoundedSquare, Square};

// (border_size, placed_coord)
#[rustfmt::skip]
const SQUARE: [(f64, f64); 40] = [
(5f64, 8f64), (9f64, 8f64), (9f64, 10f64), (11f64, 11f64), (13f64, 12f64),
(13f64, 14f64), (15f64, 15f64), (17f64, 16f64), (17f64, 18f64), (19f64, 19f64),
(21f64, 20f64), (21f64, 22f64), (23f64, 23f64), (25f64, 24f64), (25f64, 26f64),
(27f64, 27f64), (29f64, 28f64), (29f64, 30f64), (31f64, 31f64), (33f64, 32f64),
(33f64, 34f64), (35f64, 35f64), (37f64, 36f64), (37f64, 38f64), (39f64, 39f64),
(41f64, 40f64), (41f64, 42f64), (43f64, 43f64), (45f64, 44f64), (45f64, 46f64),
(47f64, 47f64), (49f64, 48f64), (49f64, 50f64), (51f64, 51f64), (53f64, 52f64),
(53f64, 54f64), (55f64, 55f64), (57f64, 56f64), (57f64, 58f64), (59f64, 59f64),
const SQUARE: [f64; 40] = [
5f64, 9f64, 9f64, 11f64, 13f64,
13f64, 15f64, 17f64, 17f64, 19f64,
21f64, 21f64, 23f64, 25f64, 25f64,
27f64, 29f64, 29f64, 31f64, 33f64,
33f64, 35f64, 37f64, 37f64, 39f64,
41f64, 41f64, 43f64, 45f64, 45f64,
47f64, 49f64, 49f64, 51f64, 53f64,
53f64, 55f64, 57f64, 57f64, 59f64,
];
const ROUNDED_SQUARE: [(f64, f64); 40] = SQUARE;
const CIRCLE: [(f64, f64); 40] = SQUARE;
const ROUNDED_SQUARE: [f64; 40] = SQUARE;
const CIRCLE: [f64; 40] = SQUARE;

// Using hardcoded values
let version = Version::from_n(n) as usize;
let (border_size, placed_coord) = match image_background_shape {
let border_size = match image_background_shape {
Square => SQUARE[version],
RoundedSquare => ROUNDED_SQUARE[version],
Circle => CIRCLE[version],
Expand All @@ -179,10 +182,7 @@ impl SvgBuilder {
};
// Make the image border bigger for bigger versions
let gap = gap * (version + 10) as f64 / 10f64;
let placed_coord = placed_coord + margin as f64;
let placed_coord = (placed_coord, placed_coord);

(border_size, placed_coord, border_size - gap)
(border_size, (border_size - gap).round())
}

fn image(&self, n: usize) -> String {
Expand All @@ -193,17 +193,23 @@ impl SvgBuilder {
let image = self.image.as_ref().unwrap();
let mut out = String::with_capacity(image.len() + 100);

let (mut border_size, mut placed_coord, mut image_size) =
Self::image_placement(self.image_background_shape, self.margin, n);
let (mut border_size, mut image_size) =
Self::image_placement(self.image_background_shape, n);

if let Some((override_size, gap)) = self.image_size {
border_size = override_size + gap * 2f64;
let mut placed_coord_x = (self.margin * 2 + n) as f64 - border_size;
placed_coord_x /= 2f64;
placed_coord = (placed_coord_x, placed_coord_x);
if let Some(override_size) = self.image_size {
let gap = -(image_size - border_size);
border_size = override_size + gap;
image_size = override_size;
}

if let Some(override_gap) = self.image_gap {
border_size = image_size + override_gap * 2f64;
}

let mut placed_coord_x = (self.margin * 2 + n) as f64 - border_size;
placed_coord_x /= 2f64;
let mut placed_coord = (placed_coord_x, placed_coord_x);

if let Some((x, y)) = self.image_position {
placed_coord = (x - border_size / 2f64, y - border_size / 2f64);
}
Expand Down
3 changes: 2 additions & 1 deletion src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ pub fn qr_svg(content: &str, options: SvgOptions) -> String {
if options.image_size.len() == 2 {
let size = options.image_size[0];
let gap = options.image_size[1];
builder.image_size(size, gap);
builder.image_size(size);
builder.image_gap(gap);
}

if options.image_size.len() == 2 {
Expand Down