diff --git a/lib/eqrcode/svg.ex b/lib/eqrcode/svg.ex index 2ed5ea4..2ea64ab 100644 --- a/lib/eqrcode/svg.ex +++ b/lib/eqrcode/svg.ex @@ -94,38 +94,70 @@ defmodule EQRCode.SVG do |> Enum.to_list() end - defp substitute(data, row_num, col_num, svg_options) + defp substitute(data, row_num, col_num, %{module_size: module_size}) when is_nil(data) or data == 0 do - y = col_num * svg_options[:module_size] - x = row_num * svg_options[:module_size] + %{} + |> Map.put(:height, module_size) + |> Map.put(:style, "fill: transparent;") + |> Map.put(:width, module_size) + |> Map.put(:x, row_num * module_size) + |> Map.put(:y, col_num * module_size) + |> draw_rect + end + + # This pattern match ensures that the QR Codes positional markers are drawn + # as rectangles, regardless of the shape + defp substitute(1, row_num, col_num, %{color: color, module_size: module_size, size: size}) + when (row_num <= 8 and col_num <= 8) or + (row_num >= size - 9 and col_num <= 8) or + (row_num <= 8 and col_num >= size - 9) do + %{} + |> Map.put(:height, module_size) + |> Map.put(:style, "fill:#{color};") + |> Map.put(:width, module_size) + |> Map.put(:x, col_num * module_size) + |> Map.put(:y, row_num * module_size) + |> draw_rect + end - ~s() + defp substitute(1, row_num, col_num, %{ + color: color, + module_size: module_size, + shape: "circle" + }) do + radius = module_size / 2.0 + + %{} + |> Map.put(:cx, row_num * module_size + radius) + |> Map.put(:cy, col_num * module_size + radius) + |> Map.put(:r, radius) + |> Map.put(:style, "fill:#{color};") + |> draw_circle end - defp substitute(1, row_num, col_num, %{shape: "circle", size: size} = svg_options) do - y = col_num * svg_options[:module_size] - x = row_num * svg_options[:module_size] - - if (row_num <= 8 && col_num <= 8) || (row_num >= size - 9 && col_num <= 8) || - (row_num <= 8 && col_num >= size - 9) do - ~s() - else - ~s() - end + defp substitute(1, row_num, col_num, %{color: color, module_size: module_size}) do + %{} + |> Map.put(:height, module_size) + |> Map.put(:style, "fill:#{color};") + |> Map.put(:width, module_size) + |> Map.put(:x, row_num * module_size) + |> Map.put(:y, col_num * module_size) + |> draw_rect end - defp substitute(1, row_num, col_num, svg_options) do - y = col_num * svg_options[:module_size] - x = row_num * svg_options[:module_size] + defp draw_rect(attribute_map) do + attributes = get_attributes(attribute_map) + ~s() + end + + defp draw_circle(attribute_map) do + attributes = get_attributes(attribute_map) + ~s() + end - ~s() + defp get_attributes(attribute_map) do + attribute_map + |> Enum.map(fn {key, value} -> ~s(#{key}="#{value}") end) + |> Enum.join(" ") end end