diff --git a/lib/mudbrick.ex b/lib/mudbrick.ex index 05d5425..eb5b91d 100644 --- a/lib/mudbrick.ex +++ b/lib/mudbrick.ex @@ -47,19 +47,40 @@ defmodule Mudbrick do iex> import Mudbrick.TestHelper ...> import Mudbrick ...> new(fonts: %{bodoni: bodoni_bold()}) - ...> |> page(size: {600, 200}) + ...> |> page(size: {400, 100}) ...> |> text( - ...> [{"Warning\\n", underline: [width: 0.5]}, "MORE ", {"efficiency", underline: [width: 0.5]}], + ...> [{"Warning\\n", underline: [width: 0.5]}], ...> font: :bodoni, ...> font_size: 70, - ...> position: {7, 130} + ...> position: {7, 30} ...> ) ...> |> render() ...> |> then(&File.write("examples/auto_kerning.pdf", &1)) Produces [this](examples/auto_kerning.pdf). Notice how the 'a' is underneath the 'W' in 'Warning'. - + + + It's on by default, but we can turn it off: + + iex> import Mudbrick.TestHelper + ...> import Mudbrick + ...> new(fonts: %{bodoni: bodoni_bold()}) + ...> |> page(size: {400, 100}) + ...> |> text( + ...> [{"Warning\\n", underline: [width: 0.5]}], + ...> font: :bodoni, + ...> font_size: 70, + ...> position: {7, 30}, + ...> auto_kern: false + ...> ) + ...> |> render() + ...> |> then(&File.write("examples/auto_kerning_disabled.pdf", &1)) + + Produces [this](examples/auto_kerning_disabled.pdf). + + + """ alias Mudbrick.{ diff --git a/lib/mudbrick/content_stream/tj.ex b/lib/mudbrick/content_stream/tj.ex index b54201f..8fab447 100644 --- a/lib/mudbrick/content_stream/tj.ex +++ b/lib/mudbrick/content_stream/tj.ex @@ -1,6 +1,7 @@ defmodule Mudbrick.ContentStream.TJ do @moduledoc false - defstruct font: nil, + defstruct auto_kern: true, + font: nil, text: nil defimpl Mudbrick.Object do @@ -11,16 +12,23 @@ defmodule Mudbrick.ContentStream.TJ do def to_iodata(op) do [ "[ ", - Mudbrick.Font.kerned(op.font, op.text) - |> Enum.map(fn - {glyph_id, kerning} -> - ["<", glyph_id, "> ", to_string(kerning), " "] - - glyph_id -> - ["<", glyph_id, "> "] - end), + op.font + |> Mudbrick.Font.kerned(op.text) + |> Enum.map(&write_glyph(op, &1)), "] TJ" ] end + + defp write_glyph(%{auto_kern: true} = op, {glyph_id, kerning}) do + write_glyph(op, glyph_id) ++ [to_string(kerning), " "] + end + + defp write_glyph(op, {glyph_id, _kerning}) do + write_glyph(op, glyph_id) + end + + defp write_glyph(_op, glyph_id) do + ["<", glyph_id, "> "] + end end end diff --git a/lib/mudbrick/text_block.ex b/lib/mudbrick/text_block.ex index 10e7c02..cef670e 100644 --- a/lib/mudbrick/text_block.ex +++ b/lib/mudbrick/text_block.ex @@ -8,6 +8,7 @@ defmodule Mudbrick.TextBlock do @type option :: {:align, alignment()} + | {:auto_kern, boolean()} | {:colour, Mudbrick.colour()} | {:font, atom()} | {:font_size, number()} @@ -43,6 +44,7 @@ defmodule Mudbrick.TextBlock do } defstruct align: :left, + auto_kern: true, colour: {0, 0, 0}, font: nil, font_size: 12, @@ -105,6 +107,7 @@ defmodule Mudbrick.TextBlock do line_texts = String.split(text, "\n") text_block_opts = [ + auto_kern: tb.auto_kern, colour: tb.colour, font_size: tb.font_size, font: tb.font, diff --git a/lib/mudbrick/text_block/line.ex b/lib/mudbrick/text_block/line.ex index dc0ec3f..06b5dd4 100644 --- a/lib/mudbrick/text_block/line.ex +++ b/lib/mudbrick/text_block/line.ex @@ -8,12 +8,14 @@ defmodule Mudbrick.TextBlock.Line do @moduledoc false @enforce_keys [ + :auto_kern, :colour, :font, :font_size, :text ] - defstruct colour: {0, 0, 0}, + defstruct auto_kern: true, + colour: {0, 0, 0}, font: nil, font_size: nil, left_offset: nil, diff --git a/lib/mudbrick/text_block/output.ex b/lib/mudbrick/text_block/output.ex index c7c2f66..98e31b2 100644 --- a/lib/mudbrick/text_block/output.ex +++ b/lib/mudbrick/text_block/output.ex @@ -49,7 +49,7 @@ defmodule Mudbrick.TextBlock.Output do defp add_part(output, part) do output |> with_font( - struct!(TJ, font: part.font, text: part.text), + struct!(TJ, auto_kern: part.auto_kern, font: part.font, text: part.text), part ) |> colour(part.colour) diff --git a/test/text_test.exs b/test/text_test.exs index 958e559..6bee135 100644 --- a/test/text_test.exs +++ b/test/text_test.exs @@ -207,6 +207,18 @@ defmodule Mudbrick.TextTest do |> Enum.take(-2) end + test "with auto-kerning disabled, doesn't write kerns" do + assert ["[ <0011> <0055> <0174> ] TJ", "ET"] = + new(fonts: %{bodoni: bodoni_regular()}) + |> page() + |> text([{"\n", auto_kern: true}, {"CO₂", auto_kern: false}], + font_size: 24, + position: {0, 700} + ) + |> operations() + |> Enum.take(-2) + end + test "copes with trailing newlines" do assert new(fonts: %{bodoni: bodoni_regular()}) |> page()