Skip to content

Commit

Permalink
Fix right-alignment leading and underline
Browse files Browse the repository at this point in the history
Use same code path as left, with a HOF for x offset.
  • Loading branch information
camelpunch committed Nov 13, 2024
1 parent 4326e04 commit 4475d9a
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 104 deletions.
133 changes: 50 additions & 83 deletions lib/mudbrick/text_block/output.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ defmodule Mudbrick.TextBlock.Output do
alias Mudbrick.Path
alias Mudbrick.TextBlock.Line

defmodule LeftAlign do
defmodule Align do
@moduledoc false

alias Mudbrick.TextBlock.Output
Expand All @@ -26,62 +26,80 @@ defmodule Mudbrick.TextBlock.Output do
|> Output.add(%TL{leading: line.leading})
end

def reduce_lines(output, [line]) do
def reduce_lines(output, [line], x_offsetter) do
output
|> leading(line)
|> reduce_parts(line, Tj, :first_line)
|> reset_offset(x_offsetter.(line))
|> reduce_parts(line, Tj, :first_line, x_offsetter)
|> offset(x_offsetter.(line))
end

def reduce_lines(output, [line | lines]) do
def reduce_lines(output, [line | lines], x_offsetter) do
output
|> leading(line)
|> reduce_parts(line, Tj, nil)
|> reduce_lines(lines)
|> reset_offset(x_offsetter.(line))
|> reduce_parts(line, Tj, nil, x_offsetter)
|> offset(x_offsetter.(line))
|> reduce_lines(lines, x_offsetter)
end

defp reduce_parts(output, %Line{parts: []}, _operator, :first_line) do
defp offset(output, offset) do
Output.td(output, {-offset, 0})
end

defp reset_offset(output, offset) do
Output.td(output, {offset, 0})
end

defp reduce_parts(output, %Line{parts: []}, _operator, :first_line, _x_offsetter) do
output
end

defp reduce_parts(output, %Line{parts: [part]}, _operator, :first_line) do
defp reduce_parts(output, %Line{parts: [part]} = line, _operator, :first_line, x_offsetter) do
output
|> Output.add_part(part, Tj)
|> underline(part)
|> underline(part, x_offsetter.(line))
end

defp reduce_parts(output, %Line{parts: []}, _operator, nil) do
defp reduce_parts(output, %Line{parts: []}, _operator, nil, _x_offsetter) do
output
|> Output.add(%Tj{font: output.font, text: ""})
|> Output.add(%TStar{})
end

defp reduce_parts(output, %Line{parts: [part]}, _operator, nil) do
defp reduce_parts(output, %Line{parts: [part]} = line, _operator, nil, x_offsetter) do
output
|> Output.add_part(part, Tj)
|> Output.add(%TStar{})
|> underline(part)
|> underline(part, x_offsetter.(line))
end

defp reduce_parts(output, %Line{parts: [part | parts]} = line, operator, line_kind) do
defp reduce_parts(
output,
%Line{parts: [part | parts]} = line,
operator,
line_kind,
x_offsetter
) do
output
|> Output.add_part(part, operator)
|> underline(part)
|> reduce_parts(%{line | parts: parts}, Tj, line_kind)
|> underline(part, x_offsetter.(line))
|> reduce_parts(%{line | parts: parts}, Tj, line_kind, x_offsetter)
end

defp underline(output, %Line.Part{underline: nil}), do: output
defp underline(output, %Line.Part{underline: nil}, _line_x_offset), do: output

defp underline(output, part) do
defp underline(output, part, line_x_offset) do
Map.update!(output, :drawings, fn drawings ->
[underline_path(output, part) | drawings]
[underline_path(output, part, line_x_offset) | drawings]
end)
end

defp underline_path(output, part) do
defp underline_path(output, part, line_x_offset) do
{x, y} = output.position
{offset_x, offset_y} = part.left_offset

x = x + offset_x
x = x + offset_x - line_x_offset
y = y + offset_y - 2

Path.new()
Expand All @@ -91,43 +109,6 @@ defmodule Mudbrick.TextBlock.Output do
end
end

defmodule RightAlign do
@moduledoc false

alias Mudbrick.TextBlock.Output

def reduce_lines(output, [line], measure) do
output
|> Output.end_block()
|> reduce_parts(line)
|> measure.(line, 1)
|> Output.start_block()
end

def reduce_lines(output, [line | lines], measure) do
output
|> Output.end_block()
|> reduce_parts(line)
|> measure.(line, length(lines) + 1)
|> Output.start_block()
|> reduce_lines(lines, measure)
end

defp reduce_parts(output, %Line{parts: []}) do
output
end

defp reduce_parts(output, %Line{parts: [part]}) do
Output.add_part(output, part, Tj)
end

defp reduce_parts(output, %Line{parts: [part | parts]} = line) do
output
|> Output.add_part(part, Tj)
|> reduce_parts(%{line | parts: parts})
end
end

defp drawings(output) do
Map.update!(output, :operations, fn ops ->
for drawing <- output.drawings, reduce: ops do
Expand All @@ -139,19 +120,21 @@ defmodule Mudbrick.TextBlock.Output do

def from(
%Mudbrick.TextBlock{
align: :left,
font: font,
font_size: font_size,
position: position = {x, y}
position: position
} = tb
) do
tl = %TL{leading: tb.leading}
tf = %Tf{font: font, size: font_size}

%__MODULE__{position: position, font: font, font_size: font_size}
|> end_block()
|> LeftAlign.reduce_lines(tb.lines)
|> add(%Td{tx: x, ty: y})
|> Align.reduce_lines(
tb.lines,
if(tb.align == :left, do: fn _ -> 0 end, else: &Line.width/1)
)
|> td(position)
|> add(tl)
|> add(tf)
|> start_block()
Expand All @@ -161,28 +144,8 @@ defmodule Mudbrick.TextBlock.Output do
|> Map.update!(:operations, &Enum.reverse/1)
end

def from(
%Mudbrick.TextBlock{
align: :right,
font: font,
font_size: font_size
} = tb
) do
tf = %Tf{font: font, size: font_size}

%__MODULE__{font: font, font_size: font_size}
|> RightAlign.reduce_lines(tb.lines, fn output, line, line_number ->
right_offset(output, tb, line, line_number)
end)
|> add(%TL{leading: tb.leading})
|> add(tf)
|> deduplicate(tf)
|> Map.update!(:operations, &Enum.reverse/1)
end

def add(%__MODULE__{} = output, op) do
Map.update!(output, :operations, &[op | &1])
end
def td(output, {0, 0}), do: output
def td(output, {x, y}), do: add(output, %Td{tx: x, ty: y})

def add_part(output, part, operator) do
output
Expand Down Expand Up @@ -230,6 +193,10 @@ defmodule Mudbrick.TextBlock.Output do
})
end

def add(%__MODULE__{} = output, op) do
Map.update!(output, :operations, &[op | &1])
end

defp deduplicate(output, initial_operator) do
Map.update!(output, :operations, fn ops ->
ops
Expand Down
37 changes: 21 additions & 16 deletions test/mudbrick/text_block_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -389,33 +389,36 @@ defmodule Mudbrick.TextBlockTest do
describe "right-aligned" do
test "newlines become Tjs with offsets" do
assert [
"BT",
"/F1 10 Tf",
"12.0 TL",
"BT",
"384.82 500.0 Td",
"400 500 Td",
"-15.180000000000001 0 Td",
"0 0 0 rg",
"<00A5> Tj",
"1 0 0 rg",
"<00A500A5> Tj",
"ET",
"BT",
"379.42 488.0 Td",
"15.180000000000001 0 Td",
"-20.580000000000002 0 Td",
"T*",
"0 0 0 rg",
"<013801380138> Tj",
"ET",
"BT",
"314.3 476.0 Td",
"20.580000000000002 0 Td",
"-85.7 0 Td",
"T*",
"<008800550088> Tj",
"0 1 0 rg",
"<0088005500880055008800550088> Tj",
"ET",
"BT",
"400.0 464.0 Td",
"ET",
"BT",
"390.74 452.0 Td",
"85.7 0 Td",
"-0.0 0 Td",
"T*",
"() Tj",
"0.0 0 Td",
"-9.26 0 Td",
"T*",
"0 0 0 rg",
"<00D500D9> Tj",
"9.26 0 Td",
"ET"
] =
output(fn %{fonts: fonts} ->
Expand Down Expand Up @@ -452,10 +455,11 @@ defmodule Mudbrick.TextBlockTest do

test "inline font change is written with Tfs" do
assert [
"BT",
"/F1 10 Tf",
"12.0 TL",
"BT",
"225.67999999999998 500.0 Td",
"400 500 Td",
"-174.32000000000002 0 Td",
"0 0 0 rg",
"<011D00D500D9011601B700D9011601B7> Tj",
"/F2 10 Tf",
Expand All @@ -465,6 +469,7 @@ defmodule Mudbrick.TextBlockTest do
"/F3 10 Tf",
"<015A01050109015201F00109015201F000FF014B00C30125011B011E01090125> Tj",
"/F1 10 Tf",
"174.32000000000002 0 Td",
"ET"
] =
output(fn %{fonts: fonts} ->
Expand Down
9 changes: 4 additions & 5 deletions test/text_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ defmodule Mudbrick.TextTest do

test "parts inherit fonts" do
assert [
"BT",
"/F1 14 Tf",
"16.8 TL",
"BT",
"171.65 700.0 Td",
"200 700 Td",
"-28.35 0 Td",
"1 0 0 rg",
"<00110055017401B7> Tj",
"28.35 0 Td",
"ET"
] =
new(
Expand Down Expand Up @@ -73,7 +75,6 @@ defmodule Mudbrick.TextTest do
"BT",
"/F1 10 Tf",
"14 TL",
"0 0 Td",
"0 0 0 rg",
"<00D500C000ED00ED00FC01B7011D00D500C0010F00C0> Tj",
"ET"
Expand Down Expand Up @@ -123,7 +124,6 @@ defmodule Mudbrick.TextTest do
BT
/F1 10 Tf
12.0 TL
0 0 Td
1.0 0.0 0.0 rg
<011D00D500D9011601B700D9011601B700A500ED00ED01B7> Tj
<010F00C000BB> Tj
Expand Down Expand Up @@ -153,7 +153,6 @@ defmodule Mudbrick.TextTest do
BT
/F1 10 Tf
12.0 TL
0 0 Td
0 0 0 rg
<00B400ED00A500B500EA01B700A500F400BB01B7> Tj
1.0 0.0 0.0 rg
Expand Down

0 comments on commit 4475d9a

Please sign in to comment.