Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion lib/asciinema_web/controllers/recording_svg.ex
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,9 @@ defmodule AsciinemaWeb.RecordingSVG do
end

@font_size 14
@char_width 0.6
@line_height 1.333333
@cell_width 8.42333333
@cell_width @font_size * @char_width

defp x(x), do: x * @cell_width

Expand All @@ -407,6 +408,27 @@ defmodule AsciinemaWeb.RecordingSVG do
defp h(h), do: h * @font_size * @line_height

defp font_size, do: @font_size
defp char_width, do: @char_width

defp x_per_grapheme(offset, text) do
# NOTE: Elixir's `String.length/1` returns the number of **grapheme
# clusters**, not the number of code points. Luckily, that's what we want
# here, as SVG's concept of a "glyph" is closer to the concept of a
# grapheme cluster than it is to a code point (glyph is identical to
# grapheme cluster as long as the font doesn't have ligatures).

# If we ever need to support fonts that _do_ use ligatures (such as a
# version of Fira Code with ligatures enabled), those will need special
# handling. At time of writing, the version of Fira Code used is in TTF
# format, so ligatures are not supported.

# We also manually disable ligatures in the SVG's `<style>` block with
# `font-variant-ligatures: none` for good measure.

Range.new(0, String.length(text) - 1)
|> Enum.map(fn i -> (offset + i) * @cell_width |> Float.round(1) end)
|> Enum.join(" ")
end

defp fg(attrs, theme), do: "fill: #{fg_color(attrs, theme, true)}"

Expand Down
7 changes: 6 additions & 1 deletion lib/asciinema_web/controllers/recording_svg/preview.svg.heex
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
.fa { fill-opacity: 0.5 }
.it { font-style: italic }
.un { text-decoration: underline }

text {
font-size-adjust: ch-width <%= char_width() %>;
font-variant-ligatures: none;
}
</style>

<rect
Expand Down Expand Up @@ -54,7 +59,7 @@
"1em"
end
}
x={x(x)}
x={x_per_grapheme(x, text)}
{text_extra_attrs(attrs, @theme)}
>
<%= html_escape(text) %>
Expand Down