///|
/// `translate_path` translates (moves) an SVG path by the provided offsets.
/// If `invert_y` is true, all `y` values are scaled by -1.
pub fn translate_path(
d : String,
x : Double,
y : Double,
invert_y? : Bool = false,
) -> String raise FontError {
let cmds = split_path(d)
let d = Buffer()
let y_scale = if invert_y { -1.0 } else { 1.0 }
for cmd in cmds {
d.write_string_utf16le(cmd.c)
cmd.p.0
.iter()
.eachi(fn(index, val) {
if index % 2 == 0 {
if index > 0 {
d.write_char_utf16le(' ')
}
d.write_string_utf16le(svg_num(x + val))
} else {
d.write_char_utf16le(' ')
d.write_string_utf16le(svg_num(y + y_scale * val))
}
})
}
d.contents().to_unchecked_string()
}
///|
fn svg_num(val : Double) -> String {
let s = val.to_string()
if s.has_suffix(".0") {
s.unsafe_substring(start=0, end=s.length() - 2) // trim ".0" suffix
} else {
s
}
}
///|
test "translate" {
let d = "M507 24L48 24L48 530L395 530L395 625L48 625L48 723L507 723L507 24ZM395 269L395 433L138 433L138 269L395 269Z"
let got = translate_path(d, 1000.0, 2000.0)
let want = "M1507 2024L1048 2024L1048 2530L1395 2530L1395 2625L1048 2625L1048 2723L1507 2723L1507 2024ZM1395 2269L1395 2433L1138 2433L1138 2269L1395 2269Z"
assert_eq(got, want)
}
///|
test "translate with invert_y=true" {
let d = "M507 24L48 24L48 530L395 530L395 625L48 625L48 723L507 723L507 24ZM395 269L395 433L138 433L138 269L395 269Z"
let got = translate_path(d, 1000.0, 2000.0, invert_y=true)
let want = "M1507 1976L1048 1976L1048 1470L1395 1470L1395 1375L1048 1375L1048 1277L1507 1277L1507 1976ZM1395 1731L1395 1567L1138 1567L1138 1731L1395 1731Z"
assert_eq(got, want)
}