The width and height of SVG embeded by reference isn't overriden

RESOLVED FIXED

Status

()

defect
P3
critical
RESOLVED FIXED
14 years ago
12 years ago

People

(Reporter: lode_leroy, Unassigned)

Tracking

Trunk
Points:
---
Dependency tree / graph
Bug Flags:
blocking1.8b5 -
blocking1.9 +
in-testsuite +

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [reflow-refactor], )

Attachments

(3 attachments)

Reporter

Description

14 years ago
User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8b2) Gecko/20050323 Firefox/1.0+
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8b2) Gecko/20050323 Firefox/1.0+

an SVG image with 'width' specified is not scaled accordingly,
but equipped with scrollbars (actually, only a horizontal scrolbar)
<object type="image/svg+xml" data="images/svgopen.svg" width="200" height="42">


Reproducible: Always

Steps to Reproduce:
1. visit url above
2.
3.

Actual Results:  
SVG image shown with scrollbars

Expected Results:  
SVG image scaled down

using recent firefox-win32-svg-GDI
dunno if this is related to https://bugzilla.mozilla.org/show_bug.cgi?id=280923

Comment 1

14 years ago
URL seems fine. Could reporter attach a testcase (simple example page where the
bug occurs) - it helps engineers zero into the bug, rather than extraneous noise
in real-life pages.
Summary: svg image not scaled → svg image not scaled
Confirming. According to http://www.w3.org/TR/SVG11/coords.html#ViewportSpace we
should be overriding the width and height specified on the SVG documents root
<svg> tag with the values provided for the <object> tag.

The fact that only a horizontal scrollbar is provided seems strange, but that's
another bug I guess.
Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: Windows XP → All
Hardware: PC → All
Summary: svg image not scaled → The width and height of SVG embeded by reference isn't overriden

Comment 3

14 years ago
Posted patch experimentSplinter Review
Functionally I think this would work, except that the reflowState for an
SVG contained in a object frame has unconstrained height.

Note that the matter of svg DOM width/height being overwritten would need to
be fixed before this goes in the tree.
What exactly is supposed to be overridden?  Any styling on the embedded <svg>? 
Or just the presentational attributes?  Also, is what's supposed to be used the
computed style of the embedding node?  Or the used style?  What happens if the
embedding node should be doing intrinsic sizing?

Comment 5

14 years ago
(In reply to comment #4)
> What exactly is supposed to be overridden?

We're only trying to override the svg's width and height attributes, which
aren't styled.

> Any styling on the embedded <svg>? 
> Or just the presentational attributes?  Also, is what's supposed to be used the
> computed style of the embedding node?  Or the used style?

Not sure where style comes into this.

> What happens if the
> embedding node should be doing intrinsic sizing?

Doesn't unconstrained stateReflow mean that we should be doing intrinsic
sizing, in which case the current tree (and patch) use the size specified
by the svg width/height attributes.
The point is to allow SVG to scale when it's embeded into a viewport with
dimensions that are different to the root <svg> element's 'width' and 'height'
attributes. Those attributes are used only when the SVG is rendered "standalone"
or the viewport width and height can't be determined. Or that's how I understand
it. The more precise definition is given by the second paragraph in the section
of the spec I linked to in comment 2.
bz: Here's how it really works. The "width" and "height" (and "viewBox")
attributes on the <svg> element give the element's intrinsic width and height
(and ratio). These then contribute towards the intrinsic sizing calculations
when inserting a replaced element in CSS.

However, CSS 2.1 doesn't quite cope with the SVG case, so we're fixing the spec
Below are the three edits to the CSS spec that make this work in all cases
(including, in fact, embedding text/plain and other such content, which was
previously undefined).

Replace CSS 2.1 section 10.3.2 "Inline, replaced elements" with:

   A computed value of 'auto' for 'margin-left' or 'margin-right'
   becomes a used value of '0'.

   If 'width' has a computed value of 'auto' and 'height' also has a
   computed value of 'auto', the element's intrinsic width is the used
   value of 'width', if it has one.

   If 'width' has a computed value of 'auto' and 'height' has some
   other computed value, and the replaced element has an intrinsic
   ratio, or, if both 'width' and 'height' have computed values of
   'auto', and the element has no intrinsic width but does have an
   intrinsic height and intrinsic ratio, then the used value of
   'width' is:

     (intrinsic ratio) * (used height)

   Otherwise, if 'width' has a computed value of 'auto', but none of
   the conditions above are met, then the used value of 'width'
   becomes 300px. If 300px is too wide to fit the device, UAs should
   use the width of the largest rectangle that has a 2:1 ratio and
   fits the device instead.

   Percentage intrinsic widths are first evaluated with respect to the
   containing block's width, if that width doesn't itself depend on
   the replaced element's width. If it does, then a percentage
   intrinsic width on that element can't be resolved and the element
   is assumed to have no intrinsic width.

Replace CSS 2.1 section 10.6.2 "Inline replaced elements, block-level
replaced elements in normal flow, 'inline-block' replaced elements in
normal flow and floating replaced elements" with the following:

   If 'margin-top', or 'margin-bottom' are 'auto', their used value is
   0.

   If 'height' has a computed value of 'auto' and 'width' also has a
   computed value of 'auto', the element's intrinsic height is the
   used value of 'height', it has one.

   If 'height' has a computed value of 'auto' and 'width' has some
   other computed value, and the replaced element has an intrinsic
   ratio, or, if both 'height' and 'width' have computed values of
   'auto', and the element has no intrinsic height but does have an
   intrinsic width and intrinsic ratio, then the used value of
   'height' is:

    (used width) / (intrinsic ratio)

   Otherwise, if 'height' has a computed value of 'auto', but none of
   the conditions above are met, then the used value of 'height' must
   be set to 150px. If 300px is too wide to fit the device width, UAs
   should use the height of the largest rectangle that has a 2:1 ratio
   and fits the device width instead.

   Percentage intrinsic heights are evaluated with respect to the
   containing block's height, if that height is specified explicitly,
   or if the replaced element is absolutely positioned. If neither of
   these conditions is met, then percentage values on such replaced
   elements can't be resolved and such elements are assumed to have no
   intrinsic height.

   For 'inline' and 'inline-block' elements, the margin box is used
   when calculating the height of the line box.

Replace the definition of "Replaced element" in section 3.1
"Definitions" with:

   An element that is outside the scope of the CSS formatter, such as
   an image, embedded document, or applet. For example, the content of
   the HTML IMG element is often replaced by the image that its "src"
   attribute designates. Replaced elements often have intrinsic
   dimensions: an intrinsic width, an intrinsic height, and an
   intrinsic ratio. For example, a bitmap image has an intrinsic width
   and an intrinsic height specified in absolute units (from which the
   intrinsic ratio can obviously be determined). On the other hand,
   other documents may not have any intrinsic dimensions (for example
   a blank HTML document).

   User agents may consider a replaced element to not have any
   intrinsic dimensions if it is believed that those dimensions could
   leak sensitive information to a third party. For example, if an
   HTML document changed intrinsic size depending on the user's bank
   balance, then the UA might want to act as if that resource had no
   intrinsic dimensions.
Possibly useful for figuring out how the "viewBox" and "preserveAspectRatio"
attributes work for those who don't already know:

  http://jwatt.org/svg/demos/preserveAspectRatio.xml
> Not sure where style comes into this.

Aren't those attributes mapped into style in svg?  If not, how do they interact
with CSS specified width and height, exactly?  How do CSS width and height on
the root <svg> element interact with a fixed viewport size?

How if having a fixed size because we're included via an <object> different from
having a fixed size because we know what the size of the browser viewport is?

> Doesn't unconstrained stateReflow mean that we should be doing intrinsic
> sizing

Currently any reflow you get as the root of a document would be unconstrained. 
roc's patch for subdocument frames may change this, of course.

Ian, I understand that the idea is that we can use the stuff specified on the
<svg> element in a subdocument to do intrinsic sizing of the subdocument frame.
 The questions I have are about (and this bug seems to be about) information
flow in the opposite direction....
So it seems from reading the spec that the viewport of the embedded SVG content
is just sized to be whatever the <object> is, and you ignore the height and
width styles on the <svg> element itself. Basically, in the case where an SVG
image is a replaced element in some CSS context, you just use the resulting
height and width (from the stuff I quoted above) to give the size of the
viewport, and so the used values of height and width on the <svg> element itself
are derived from that and ignore the specified values (e.g. those on the
attributes).

bz: Does that answer your questions?
So... embedding SVG via <iframe> and <object> should have same result or
different, as far as this stuff is concerned?  What is a "CSS context"? 
Consider the <browser> nodes in Mozilla's XUL, for example.

That aside, that does sort of answer my questions.  Next question is what the
computed values for width/height should reflect here.  That is, is it acceptable
to have UA CSS "rules" that in effect compute the value to whatever it should be
based on the containing element?
Embedding SVG via <iframe>, <object>, <svg:svg>, <img>, <embed>, <input
type="image">, and the 'content' property should all work the same. They all
count as replaced elements.

<browser>, on the other hand, is an implementation detail. It doesn't count as a
CSS context for the purposes of the spec, it counts as an outermost viewport.


> Next question is what the computed values for width/height should reflect 
> here.  That is, is it acceptable to have UA CSS "rules" that in effect compute
> the value to whatever it should be based on the containing element?

I don't follow. The computed values of 'height' and 'width' on the SVG element
should just be the specified values, with relative lengths resolved to the
device-native absolute length (pixels, generally) and %s left as %s. Computed
values are never layout-dependant. Or are you asking about the used values?
> <browser>, on the other hand, is an implementation detail.

Except if you have a XUL document, it's just a way of embedding stuff.  Just
like <xul:iframe>, by the way.  It's not a W3C technology, sure.  But that's a
separate issue.

> it counts as an outermost viewport.

My point was that the idea of "outermost viewport" is very ill-defined.  It's
being defined here as "something that looks like an outermost viewport to the
user".  What should that do in a browser that uses an MDI interface with tiling
of web rendering areas?

I see what you mean about computed values, though.  So basically, in a
"non-outermost viewport" (whatever that is) svg should just size (used value) to
the size of the viewport and the sizing of the replaced element is what should
take into account (or not) the SVG's computed style.
> My point was that the idea of "outermost viewport" is very ill-defined.

Ok, here's a definition for you: "a viewport (represented by an object that
implements the Window and AbstractView interfaces) is an outermost viewport if
its 'parent' DOM attribute is itself". (i.e. if window.parent == window.)


> I see what you mean about computed values, though.  So basically, in a
> "non-outermost viewport" (whatever that is) svg should just size (used value) 
> to the size of the viewport and the sizing of the replaced element is what 
> should take into account (or not) the SVG's computed style.

Correct. But as noted above, it's likely that that size actually got derived
from that computed style originally.

Comment 15

14 years ago
its important that this gets fixed, there are allready public complains about
this behaviour.
see comment 5 of this blog entry:
http://simon.incutio.com/archive/2005/09/11/firefox15
Yes, and this one:

  http://www.alleged.org.uk/pdc/2005/09/09.html#e20050909.svg

etc. I agree, this could end up being one the our most complained about
conformance issues if we don't fix it, but I don't have time to look at the
issue right now and everyone else seems to be at least as busy.
Severity: normal → critical
Flags: blocking1.8b5?

Updated

14 years ago
Flags: blocking1.8b5? → blocking1.8b5-

Comment 17

14 years ago
Scaling with ems and percentages for inline SVG seems to be broken too, unless I
am missing something in the spec.  For example, this is scaled to the width of
the page rather than the width of the p:

<p style="width: 10em"><svg width="100%">...</svg></p>

This fails to appear at all:

<p><svg width="5em">...</svg></p>

Comment 18

14 years ago
Re: Comment 17: I think the problem you are describing is a separate issue.  This one is about scaling of SVG graphics embedded with `embed` or `object`.

Re: Comment 16: There is a workaround for SVG images that are intended to be used embedded in a page (as opposed to shown on their own): set the natural width and height to '100%', so that it starts with something like the following:

    <svg width="100%" height="100%" viewPort="0 0 400 300" ....> 

The downside is that when you look at the image on its own, it fills the entire page, which can look kind of comical.

In terms of a fix I think we need to have the host page saying to the embedded document 'You need to be 100 by 75 pixels', and allow SVG images to respond 'OK, I'll rescale myself', whereas HTML documents (and JPEG images etc.) respond 'I want to be 800 by 1136 pixels; please show scrollbars'.  This in turn requires that a W3C committee be set up to decide how to decide whether a given XML document is SVG or HTML.  My suggestion is to use the MIME media-type; you may prefer to have the XML namespace of the outermost element override that.

Comment 19

14 years ago
Where are we at? Can somebody state in one one phrase what prevents a solution:
(1) Is the correct behavior unclear? I don't think so; the spec cited in Comment #2 says it quite clearly. In a nutshell, for the controversial case: If the size of the containing element is known, and if the SVG root element contains a viewport attribute, then the viewport is scaled to fit the containing element.
(2) Mozilla implementation specifics make a correct implementation difficult to design?
(3) All is clear, but nobody has the time to fix it?
(4) ...?

Re: Comment 18: 
> ...whereas HTML documents (and JPEG images etc.)
> respond 'I want to be 800 by 1136 pixels; please show scrollbars'.
Correction: According to the specs, images are to be scaled (which is logical since they have no way of explicitly stating how much space they want to occupy). All browsers I know do this correctly.

> This in
> turn requires that a W3C committee be set up to decide how to decide whether a
> given XML document is SVG or HTML.
The W3C has already been discussing such issues for a while. I don't see its relevance here though; as long as content is served as XML, for all intents and purposes, its interpretation by Mozilla is clearly defined by the namespaces used.
> (3) All is clear, but nobody has the time to fix it?

That one.
So, given my crappy knowledge of layout land, how much work would it be for me to do this given appropriate pointers?
Well...  We need a way to ask things for intrinsic size.  Then we need to move the code that does replaced element sizing in nsImageFrame into someplace shared (nsLayoutUtils?  Or a new class that's a superclass for image and iframe?).  And comment 7 needs to be implemented.

Comment 24

14 years ago
Comment on attachment 209659 [details] [diff] [review]
sizing of embedded SVG objects based on their aspect ratio

I really needed this functionality. It works well for me now. Executables (Mac/Win) can be found here http://www.mehrvarz.org/public/apps
See also bug 80713.


Some comments on the patch (without thinking about merging with that patch):

I'm hoping that the spec you're trying to implement is what
http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-width says about
intrinsic ratios.

Anyway, some thoughts on the patch: adding additional member variables
to all instances of nsLeafFrame should not be needed; furthermore, the
casting that you do in nsSVGOuterSVGFrame is probably unsafe, and
walking up 5 views isn't a reliable method (it could easily break in the
future).

The general approach I'd suggest instead is:
 * abandon the changes to nsLeafFrame and the additional member
   variables on nsFrameFrame
 * put the additional member variables on nsPresShell instead (with
   accessors on the nsIPresShell interface), and have nsOuterSVGFrame's
   Init method set them there, but only if that outer SVG frame is for
   the root element.
 * have the nsFrameFrame code get them from the nsPresShell inside of
   it whenever they're needed

(Note that you can always get an nsIPresShell from an nsPresContext and
vice-versa; we're planning to combine the two objects at some point.)

I didn't look much at the details of the code yet.
But Boris has a good point in comment 22 as well:  some SVG files do have the same type of intrinsic width information as images, so we really should refactor the code used for nsImageFrame to apply to SVG images that are objects as well, and then extend that same code to work for images that have only an intrinsic ratio, etc.

Comment 27

13 years ago
*** Bug 355301 has been marked as a duplicate of this bug. ***
Whiteboard: [reflow-refactor]

Comment 28

13 years ago
Added a more simple test case.
Flags: blocking1.9?
No longer blocks: 280923
No longer depends on: 367031
Depends on: 294086

Updated

12 years ago
Flags: blocking1.9? → blocking1.9+
Priority: -- → P3
This bug was just fixed by the fix for bug 294086. A lot of the reftests checked in for that bug cover this bug too, so marking in-testsuite+.
Status: NEW → RESOLVED
Closed: 12 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
Oops. I was thinking that the layout/reftests/svg/sizing/object--xxx.html tests from bug 294086 covered this bug, but they don't. They all deal with HTML <object> using the intrinsic size of the SVG if the <object> doesn't have specified dimensions. To cover this bug I've added the test: layout/reftests/svg/sizing/object--pct-pct--0-0.html
You need to log in before you can comment on or make changes to this bug.