Skip to content

Commit ddb933d

Browse files
committed
Attempt to fix leading
Needed to handle chosen opts for a line separately to those merged into defaults.
1 parent 2c1a5da commit ddb933d

File tree

4 files changed

+78
-23
lines changed

4 files changed

+78
-23
lines changed

lib/mudbrick/text_block.ex

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ defmodule Mudbrick.TextBlock do
105105
%{tb | lines: lines}
106106
end
107107

108-
defp write_lines(tb, text, opts) do
108+
defp write_lines(tb, text, chosen_opts) do
109109
line_texts = String.split(text, "\n")
110110

111111
text_block_opts = [
@@ -115,36 +115,43 @@ defmodule Mudbrick.TextBlock do
115115
leading: tb.leading
116116
]
117117

118-
opts =
118+
merged_opts =
119119
Keyword.merge(
120120
text_block_opts,
121-
opts,
121+
chosen_opts,
122122
&prefer_lhs_over_nil/3
123123
)
124124

125125
Map.update!(tb, :lines, fn
126126
[] ->
127-
add_texts([], line_texts, opts, text_block_opts)
127+
add_texts([], line_texts, merged_opts, text_block_opts)
128128

129129
existing_lines ->
130130
case line_texts do
131131
# \n at beginning of new line
132132
["" | new_line_texts] ->
133133
existing_lines
134-
|> add_texts(new_line_texts, opts, text_block_opts)
134+
|> add_texts(new_line_texts, merged_opts, text_block_opts)
135135

136136
# didn't start with \n, so first part belongs to previous line
137137
[first_new_line_text | new_line_texts] ->
138138
existing_lines
139-
|> update_previous_line(first_new_line_text, opts)
140-
|> add_texts(new_line_texts, opts, text_block_opts)
139+
# Update previous line with chosen opts, to allow logic around
140+
# choices.
141+
|> update_previous_line(first_new_line_text, merged_opts, chosen_opts)
142+
|> add_texts(new_line_texts, merged_opts, text_block_opts)
141143
end
142144
end)
143145
end
144146

145-
defp update_previous_line([previous_line | existing_lines], first_new_line_text, opts) do
147+
defp update_previous_line(
148+
[previous_line | existing_lines],
149+
first_new_line_text,
150+
merged_opts,
151+
opts
152+
) do
146153
[
147-
Line.append(previous_line, first_new_line_text, opts)
154+
Line.append(previous_line, first_new_line_text, merged_opts, opts)
148155
| existing_lines
149156
]
150157
end
@@ -160,6 +167,11 @@ defmodule Mudbrick.TextBlock do
160167
end
161168
end
162169

163-
defp prefer_lhs_over_nil(_key, lhs, nil), do: lhs
164-
defp prefer_lhs_over_nil(_key, _lhs, rhs), do: rhs
170+
defp prefer_lhs_over_nil(_key, lhs, nil) do
171+
lhs
172+
end
173+
174+
defp prefer_lhs_over_nil(_key, _lhs, rhs) do
175+
rhs
176+
end
165177
end

lib/mudbrick/text_block/line.ex

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,11 @@ defmodule Mudbrick.TextBlock.Line do
4141
struct(__MODULE__, Keyword.put(opts, :parts, [Part.new(text, opts)]))
4242
end
4343

44-
def append(line, text, opts) do
45-
line = Map.update!(line, :parts, &[Part.new(text, opts) | &1])
46-
new_leading = Keyword.fetch!(opts, :leading)
44+
def append(line, text, merged_opts, chosen_opts) do
45+
line = Map.update!(line, :parts, &[Part.new(text, merged_opts) | &1])
4746

48-
if new_leading > line.leading do
49-
Map.put(line, :leading, new_leading)
47+
if chosen_opts[:leading] do
48+
Map.put(line, :leading, chosen_opts[:leading])
5049
else
5150
line
5251
end

lib/mudbrick/text_block/output.ex

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ defmodule Mudbrick.TextBlock.Output do
146146
position: position = {x, y}
147147
} = tb
148148
) do
149-
tl = %TL{leading: leading(tb)}
149+
tl = %TL{leading: tb.leading}
150150
tf = %Tf{font: font, size: font_size}
151151

152152
%__MODULE__{position: position, font: font, font_size: font_size}
@@ -175,7 +175,7 @@ defmodule Mudbrick.TextBlock.Output do
175175
|> RightAlign.reduce_lines(tb.lines, fn output, line, line_number ->
176176
right_offset(output, tb, line, line_number)
177177
end)
178-
|> add(%TL{leading: leading(tb)})
178+
|> add(%TL{leading: tb.leading})
179179
|> add(tf)
180180
|> deduplicate(tf)
181181
|> Map.update!(:operations, &Enum.reverse/1)
@@ -227,7 +227,7 @@ defmodule Mudbrick.TextBlock.Output do
227227

228228
add(output, %Td{
229229
tx: x - Line.width(line),
230-
ty: y - leading(tb) * n
230+
ty: y - tb.leading * n
231231
})
232232
end
233233

@@ -263,8 +263,4 @@ defmodule Mudbrick.TextBlock.Output do
263263
defp remove(output, operation) do
264264
Map.update!(output, :operations, &List.delete(&1, operation))
265265
end
266-
267-
defp leading(tb) do
268-
tb.leading || tb.font_size * 1.2
269-
end
270266
end

test/mudbrick/text_block_test.exs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,54 @@ defmodule Mudbrick.TextBlockTest do
164164
end
165165

166166
describe "leading" do
167+
test "is set correctly for lines composed with writes" do
168+
output(fn %{fonts: fonts} ->
169+
heading_leading = 70
170+
overlap_leading = 20
171+
# 120% of default 80 font size
172+
expected_final_leading = 96.0
173+
174+
text_block =
175+
TextBlock.new(
176+
align: :left,
177+
font: fonts.regular,
178+
font_size: 80,
179+
position: {0, 500}
180+
)
181+
|> TextBlock.write("Warning!\n", font_size: 140, leading: heading_leading)
182+
|> TextBlock.write("Leading ", leading: overlap_leading)
183+
|> TextBlock.write("changes")
184+
|> TextBlock.write("\nthis overlaps")
185+
186+
assert [
187+
^expected_final_leading,
188+
^overlap_leading,
189+
^heading_leading
190+
] =
191+
Enum.map(text_block.lines, & &1.leading)
192+
193+
text_block
194+
end)
195+
end
196+
197+
test "is set correctly for linebreaks inside writes" do
198+
output(fn %{fonts: fonts} ->
199+
text_block =
200+
TextBlock.new(
201+
align: :left,
202+
font: fonts.regular,
203+
font_size: 80,
204+
position: {0, 500}
205+
)
206+
|> TextBlock.write("Warning!\n", font_size: 140, leading: 20)
207+
|> TextBlock.write("Steps under\nconstruction", leading: 70)
208+
209+
assert [70, 70, 20] = Enum.map(text_block.lines, & &1.leading)
210+
211+
text_block
212+
end)
213+
end
214+
167215
test "can be set per line" do
168216
block =
169217
TextBlock.new(font_size: 10)

0 commit comments

Comments
 (0)