Closed aparrish closed 4 years ago
Very good catch, thank you!
However, I don't understand that "unexpected" as it should always be 3/4 of size. Here's my thinking: <svg width="75pt" height="75pt">
= <svg width="100px" height="100px">
= <svg width="100" height="100">
= <svg width="100" height="100" viewBox="0 0 100 100">
. But we want <svg width="100" height="100" viewBox="0 0 75 75">
, i.e. <svg width="75pt" height="75pt" viewBox="0 0 75 75">
. Perhaps a tool was ignoring that "pt" unit?
Also, could you please change the order of attributes to "width", "height", "viewBox"? I will then merge it right away.
I mean:
b'width="%spt" height="%spt" '
b'viewBox="0 0 %s %s">\n'
instead of
b'viewBox="0 0 %s %s" '
b'width="%spt" height="%spt">\n'
Attribute order switched as requested!
I called the behavior "unexpected" because on a document whose units are set to (e.g.) in
, I would expect (e.g.) .rectangle(0, 0, 5, 5)
to draw a square 5" on each side. But according to the SVG standard, units inside an <svg>
element without a viewBox
must be interpreted as pixels, even if a unit of measurement is specified in the <svg>
's width
and height
element. Flat uses pt
s internally for everything (72pt = 1in), so a 5" rectangle would have a width of 360
in the generated SVG source code. Because of the missing viewBox
, AxiDraw interprets this as 360 pixels, which it renders (somewhat arbitrarily) at 96dpi, and ends up drawing a 3.75" (= 5 0.75) square. (The 3/4 size thing results from the fact that (1/96) 72 = 0.75.)
I just tried this out in Inkscape and can verify that it interprets SVGs without a viewBox
the same way that AxiDraw does. (In Inkscape, the document has the right size but clicking on any Flat-generated shape shows the units in px
.)
Thank you again!
Not that it matters, because the end-result would be the same, but I believe the mechanism is slightly different. Every dimension without a unit is treated as "user unit" and viewBox
establishes the transformation from absolute dimensions of outermost svg
to these "unitless" values. If there is no viewBox
, both initial viewport and user coordinate systems have to be identical, meaning an implicit viewBox
is set up using CSS ratios from pt
to px
(1/72in, 1/96in). Which in turn means that viewBox
is (always) 3/4 smaller (i.e. more "zoom out") because it is in px
, and not in pt
, but all the "unitless" values were meant to be in pt
.
As I understand the SVG standard, units in SVGs without
viewBox
attributes are interpreted as pixels. Flat exports SVGs without aviewBox
attribute, which leads to unexpected behavior when using these SVGs with downstream tools. (For example, AxiDraw's Python library draws Flat-produced SVGs at three-quarter size, because it interprets Flat's units as pixels and defaults to rendering them at 96dpi.)This pull request adds a
viewBox
attribute to all SVGs produced with Flat. Themin-x
andmin-y
values of theviewBox
are both zero, and the width and the heightviewBox
are set to the width and the height of the Flat document. This helps ensure that downstream SVG implementations understand what the units inside of thesvg
tag are actually intended to mean!