Skip to content

Commit

Permalink
Merge pull request #336 from Mattriks/svg_newlines
Browse files Browse the repository at this point in the history
SVG multiline text
  • Loading branch information
bjarthur authored Dec 16, 2018
2 parents a5f8b81 + 5285fe7 commit 8de6805
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 16 deletions.
17 changes: 17 additions & 0 deletions docs/src/gallery/forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,23 @@ img = compose(context(units=UnitBox(0,0,2,2)),
)
```

```@example
using Compose
set_default_graphic_size(10cm,8cm)
# This graphic illustrates text alignment
txt = [x*"\n"*y for x in ["hleft", "hcenter","hright"],
y in ["vtop","vcenter","vbottom"] ]
x = repeat(0.1w.*[1,5,9], outer=3)
y = repeat(0.1h.*[1,5,9], inner=3)
xp = repeat([hleft,hcenter,hright], outer=3)
yp = repeat([vtop,vcenter,vbottom], inner=3)
img = compose(context(),
(context(), circle(x, y, [0.01]), fill("red")),
text(x, y, txt, xp, yp), fontsize(14pt)
)
```



Expand Down
27 changes: 11 additions & 16 deletions src/svg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,22 +87,13 @@ svg_fmt_color(c::Color) = string("#", hex(c))
svg_fmt_color(c::Nothing) = "none"

# Replace newlines in a string with the appropriate SVG tspan tags.
function svg_newlines(input::AbstractString, x::Float64)
xpos = svg_fmt_float(x)
newline_count = 0
function svg_newlines(input::AbstractString)
output = IOBuffer()
lastpos = 1
for mat in eachmatch(r"\n", input)
write(output, input[lastpos:mat.offset-1])
newline_count += 1
write(output, """<tspan x="$(xpos)" dy="1.2em">""")
lastpos = mat.offset + length(mat.match)
inputs = split(input,"\n")
write(output, inputs[1])
for mat in inputs[2:end]
write(output, """<tspan x="0" dy="1.2em">""", mat, "</tspan>")
end
write(output, input[lastpos:end])
for _ in 1:newline_count
write(output, "</tspan>")
end

return String(take!(output))
end

Expand Down Expand Up @@ -958,12 +949,16 @@ function draw(img::SVG, prim::TextPrimitive, idx::Int)
# NOTE: "dominant-baseline" is the correct way to vertically center text
# in SVG, but implementations are pretty inconsistent (chrome in particular
# does a really bad job). We fake it by shifting by some reasonable amount.
nlines = length(split(prim.value,"\n"))-1
if prim.valign === vcenter
print(img.out, " dy=\"0.35em\"")
# print(img.out, " dy=\"0.35em\"")
print(img.out, " dy=\"$(svg_fmt_float(0.35-0.6*nlines))em\"")
#print(img.out, " style=\"dominant-baseline:central\"")
elseif prim.valign === vtop
print(img.out, " dy=\"0.6em\"")
#print(img.out, " style=\"dominant-baseline:text-before-edge\"")
elseif prim.valign === vbottom
print(img.out, " dy=\"$(svg_fmt_float(-1.2*nlines))em\"")
end

if abs(prim.rot.theta) > 1e-4 || sum(abs.(prim.offset)) > 1e-4mm
Expand All @@ -988,7 +983,7 @@ function draw(img::SVG, prim::TextPrimitive, idx::Int)
end

@printf(img.out, ">%s</text>\n",
svg_newlines(pango_to_svg(prim.value), prim.position[1].value))
svg_newlines(pango_to_svg(prim.value)))

img.indentation -= 1
indent(img)
Expand Down

0 comments on commit 8de6805

Please sign in to comment.