Current section

Files

Jump to
pdf lib pdf.ex
Raw

lib/pdf.ex

defmodule Pdf do
def new, do: {:ok, :eg_pdf.new}
def new(func) do
{:ok, pid} = new
result = func.(pid)
stop(pid)
result
end
def points(x), do: x
def picas(x), do: x * 6
def inches(x), do: round(x * 72.21)
def cm(x), do: round((x * 72.21) / 2.54)
def white, do: {255, 255, 255}
def black, do: {0, 0, 0}
def text(pid, func) when is_function(func) do
begin_text(pid)
func.(pid)
end_text(pid)
pid
end
def text(pid, str) when is_binary(str) do
:ok = :eg_pdf.text(pid, String.to_char_list(str))
pid
end
def textbr(pid, text) when is_binary(text) do
:ok = :eg_pdf.textbr(pid, String.to_char_list(text))
pid
end
def get_string_width(pid, font_name, size, str) do
:eg_pdf.get_string_width(pid, String.to_char_list(font_name), size, String.to_char_list(str))
end
def set_font(pid, name, size) do
:ok = :eg_pdf.set_font(pid, String.to_char_list(name), size)
pid
end
def text_at(pid, x, y, str) do
:ok = :eg_pdf_lib.moveAndShow(pid, x, y, String.to_char_list(str))
pid
end
def lines(pid, x, y, line_height, list) do
print_lines(pid, x, y, line_height, list)
pid
end
defp print_lines(_pid, _x, _y, _line_height, []), do: nil
defp print_lines(pid, x, y, line_height, [line | tail]) do
text_at(pid, x, y, line)
print_lines(pid, x, y - line_height, line_height, tail)
end
def export(pid) do
{doc, _} = :eg_pdf.export(pid)
doc
end
def export!(pid, path, options \\ [:write, :binary]) do
doc = export(pid)
File.write!(path, doc, options)
end
def stop(pid), do: :eg_pdf.delete(pid)
@methods [
begin_text: 1,
end_text: 1,
save_state: 1,
restore_state: 1,
set_author: 2,
set_title: 2,
set_producer: 2,
set_creator: 2,
set_subject: 2,
set_keywords: 2,
set_page: 2,
set_pagesize: 2,
set_dash: 2,
set_line_width: 2,
set_fill_color: 2,
set_stroke_color: 2,
path: 2,
set_text_pos: 3,
rectangle: 3,
image: 4,
line: 5,
]
Enum.each(@methods, fn
({name, 1}) ->
def unquote(name)(pid) do
:ok = :eg_pdf.unquote(name)(pid)
pid
end
({name, 2}) ->
def unquote(name)(pid, a1) do
:ok = :eg_pdf.unquote(name)(pid, a1)
pid
end
({name, 3}) ->
def unquote(name)(pid, a1, a2) do
:ok = :eg_pdf.unquote(name)(pid, a1, a2)
pid
end
({name, 4}) ->
def unquote(name)(pid, a1, a2, a3) do
:ok = :eg_pdf.unquote(name)(pid, a1, a2, a3)
pid
end
({name, 5}) ->
def unquote(name)(pid, a1, a2, a3, a4) do
:ok = :eg_pdf.unquote(name)(pid, a1, a2, a3, a4)
pid
end
end)
@lint false
def print_grid(pdf) do
[pdfc, _stream] = :gen_server.call(pdf, {:get_state})
{x, y, width, height} = elem(pdfc, 8)
pdf
|> set_line_width(0.1)
|> set_fill_color({127, 127, 127})
|> set_font("Helvetica", 8)
|> set_stroke_color({127, 127, 127})
|> print_horizontal_lines(y, width, cm(0.5), height, fn(pdf, at) ->
if at > 0 && rem(at, cm(1)) == 0 do
pdf |> text_at(4, at, "#{div(at, cm(1))}cm")
else
pdf
end
end)
|> print_vertical_lines(x, height, cm(0.5), width, fn(pdf, at) ->
if at > 0 && rem(at, cm(1)) == 0 do
pdf |> text_at(at - 8, 4, "#{div(at, cm(1))}cm") |> text_at(at - 8, height - 4 - 8, "#{div(at, cm(1))}cm")
else
pdf
end
end)
pdf
end
@lint false
defp print_horizontal_lines(pdf, at, _width, _step, last, _func) when at >= last or at < 0, do: pdf
defp print_horizontal_lines(pdf, at, width, step, last, func) do
pdf
|> line(0, at, width, at)
|> path(:stroke)
|> func.(at)
|> print_horizontal_lines(at + step, width, step, last, func)
end
@lint false
defp print_vertical_lines(pdf, at, _height, _step, last, _func) when at >= last or at < 0, do: pdf
defp print_vertical_lines(pdf, at, height, step, last, func) do
pdf
|> line(at, 0, at, height)
|> path(:stroke)
|> func.(at)
|> print_vertical_lines(at + step, height, step, last, func)
end
end