diff --git a/.gitignore b/.gitignore index 32f6d7a..db54c2b 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ tags .projections.json .elixir_ls/ +.DS_Store diff --git a/README.md b/README.md index d7a1c81..c58ec0f 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ There are several options to change the appearance of svg or png: | background_opacity | nil or 0.0 <= x <= 1.0 | nil | sets background opacity of svg | | background_color | string or {r, g, b} | "#ffffff" | sets background color of svg | | qrcode_color | string or {r, g, b} | "#000000" | sets color of QR | +| flatten | boolean | false | renders path data instead of rects | | | image | {string, size} or nil | nil | puts the image to the center of svg | | structure | :minify or :readable | :minify | minifies or makes readable svg file | ``` diff --git a/lib/qr_code/render/svg.ex b/lib/qr_code/render/svg.ex index ddff092..6cc6e3f 100644 --- a/lib/qr_code/render/svg.ex +++ b/lib/qr_code/render/svg.ex @@ -44,7 +44,7 @@ defmodule QRCode.Render.Svg do |> construct_svg(settings) end - defp construct_body(matrix, svg, %SvgSettings{scale: scale}) do + defp construct_body(matrix, svg, %SvgSettings{scale: scale, flatten: flatten}) do {rank_matrix, _} = Matrix.size(matrix) %{ @@ -52,7 +52,7 @@ defmodule QRCode.Render.Svg do | body: matrix |> find_nonzero_element() - |> Enum.map(&create_rect(&1, scale)), + |> Enum.map(&create_body(&1, scale, flatten)), rank_matrix: rank_matrix } end @@ -69,6 +69,7 @@ defmodule QRCode.Render.Svg do background_color: bg, image: image, qrcode_color: qc, + flatten: flatten, scale: scale, structure: structure } @@ -79,12 +80,11 @@ defmodule QRCode.Render.Svg do xlink: xlink, width: rank_matrix * scale, height: rank_matrix * scale - }, [background_rect(bg, bg_tr), to_group(body, qc), put_image(image)]} + }, [background_rect(bg, bg_tr), body_type(body, qc, flatten), put_image(image)]} |> XmlBuilder.generate(format: format(structure)) end # Helpers - defp background_settings(color) do %{ width: "100%", @@ -93,10 +93,17 @@ defmodule QRCode.Render.Svg do } end - defp create_rect({x_pos, y_pos}, scale) do + defp body_type(body, qc, false), do: to_group(body, qc) + defp body_type(body, qc, true), do: to_path(body, qc) + + defp create_body({x_pos, y_pos}, scale, false) do {:rect, %{width: scale, height: scale, x: scale * x_pos, y: scale * y_pos}, nil} end + defp create_body({x_pos, y_pos}, scale, true) do + ~s(M#{scale * x_pos} #{scale * y_pos}h#{scale}v#{scale}H#{scale * x_pos}z) + end + defp background_rect(color, nil) do {:rect, background_settings(color), nil} end @@ -115,6 +122,10 @@ defmodule QRCode.Render.Svg do {:g, %{fill: to_hex(color)}, body} end + defp to_path(body, color) do + {:path, %{fill: to_hex(color), d: body}, nil} + end + defp put_image(nil), do: "" defp put_image({path_to_image, size}) when is_binary(path_to_image) and 0 < size do diff --git a/lib/qr_code/render/svg_settings.ex b/lib/qr_code/render/svg_settings.ex index bcfb461..40eb6c8 100644 --- a/lib/qr_code/render/svg_settings.ex +++ b/lib/qr_code/render/svg_settings.ex @@ -17,6 +17,7 @@ defmodule QRCode.Render.SvgSettings do @type background_opacity :: ExMaybe.t(float()) @type background_color :: String.t() | tuple @type qrcode_color :: String.t() | tuple + @type flatten :: boolean() @type structure :: :minify | :readable @type t :: %__MODULE__{ @@ -25,6 +26,7 @@ defmodule QRCode.Render.SvgSettings do background_opacity: background_opacity, background_color: background_color, qrcode_color: qrcode_color, + flatten: flatten, structure: structure } @@ -33,5 +35,6 @@ defmodule QRCode.Render.SvgSettings do background_opacity: nil, background_color: "#ffffff", qrcode_color: "#000000", + flatten: false, structure: :minify end