Closed Bug 288276 Opened 16 years ago Closed 13 years ago
The width and height of SVG embeded by reference isn't overriden
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
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
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?
(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.
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
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>
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.
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 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.
*** Bug 355301 has been marked as a duplicate of this bug. ***
Added a more simple test case.
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: 13 years ago
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.