зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1149357: Make nsImageFrame::mIntrinsicSize account for density. r=dholbert
Only doing it in ComputeSize (via GetNaturalSize) is unsound, and the rest of the users of mIntrinsicSize definitely do need scaling accounted for. Move the adjustment to nsImageFrame for two reasons: * Prevents adding more dependencies from nsIImageLoadingContent, which otherwise would need to go away anyway in bug 215083. * Avoids having to duplicate the image orientation logic, since mImage is already an OrientedImage if needed. MozReview-Commit-ID: EA0n0TctZhN
This commit is contained in:
Родитель
3ea22263c0
Коммит
5d4df42dc7
|
@ -43,6 +43,11 @@ public:
|
|||
|
||||
virtual bool Draggable() const override;
|
||||
|
||||
ResponsiveImageSelector* GetResponsiveImageSelector()
|
||||
{
|
||||
return mResponsiveSelector.get();
|
||||
}
|
||||
|
||||
// Element
|
||||
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Helpers.h"
|
||||
#include "mozilla/gfx/PathHelpers.h"
|
||||
#include "mozilla/dom/HTMLImageElement.h"
|
||||
#include "mozilla/dom/ResponsiveImageSelector.h"
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
@ -294,6 +296,33 @@ nsImageFrame::Init(nsIContent* aContent,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ScaleIntrinsicSizeForDensity(nsIContent& aContent, nsSize& aSize)
|
||||
{
|
||||
auto* image = HTMLImageElement::FromNode(aContent);
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResponsiveImageSelector* selector = image->GetResponsiveImageSelector();
|
||||
if (!selector) {
|
||||
return;
|
||||
}
|
||||
|
||||
double density = selector->GetSelectedImageDensity();
|
||||
MOZ_ASSERT(density > 0.0);
|
||||
if (density == 1.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aSize.width != -1) {
|
||||
aSize.width = NSToCoordRound(double(aSize.width) / density);
|
||||
}
|
||||
if (aSize.height != -1) {
|
||||
aSize.height = NSToCoordRound(double(aSize.height) / density);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsImageFrame::UpdateIntrinsicSize(imgIContainer* aImage)
|
||||
{
|
||||
|
@ -307,6 +336,7 @@ nsImageFrame::UpdateIntrinsicSize(imgIContainer* aImage)
|
|||
// Set intrinsic size to match aImage's reported intrinsic width & height.
|
||||
nsSize intrinsicSize;
|
||||
if (NS_SUCCEEDED(aImage->GetIntrinsicSize(&intrinsicSize))) {
|
||||
ScaleIntrinsicSizeForDensity(*mContent, intrinsicSize);
|
||||
// If the image has no intrinsic width, intrinsicSize.width will be -1, and
|
||||
// we can leave mIntrinsicSize.width at its default value of eStyleUnit_None.
|
||||
// Otherwise we use intrinsicSize.width. Height works the same way.
|
||||
|
@ -859,46 +889,8 @@ nsImageFrame::ComputeSize(gfxContext *aRenderingContext,
|
|||
ComputeSizeFlags aFlags)
|
||||
{
|
||||
EnsureIntrinsicSizeAndRatio();
|
||||
|
||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(imageLoader, "No content node??");
|
||||
mozilla::IntrinsicSize intrinsicSize(mIntrinsicSize);
|
||||
|
||||
// XXX(seth): We may sometimes find ourselves in the situation where we have
|
||||
// mImage, but imageLoader's current request does not have a size yet.
|
||||
// This can happen when we load an image speculatively from cache, it fails
|
||||
// to validate, and the new image load hasn't fired SIZE_AVAILABLE yet. In
|
||||
// this situation we should always use mIntrinsicSize, because
|
||||
// GetNaturalWidth/Height will return 0, so we check CurrentRequestHasSize()
|
||||
// below. See bug 1019840. We will fix this in bug 1141395.
|
||||
|
||||
// Content may override our default dimensions. This is termed as overriding
|
||||
// the intrinsic size by the spec, but all other consumers of mIntrinsic*
|
||||
// values are being used to refer to the real/true size of the image data.
|
||||
if (imageLoader && imageLoader->CurrentRequestHasSize() && mImage &&
|
||||
intrinsicSize.width.GetUnit() == eStyleUnit_Coord &&
|
||||
intrinsicSize.height.GetUnit() == eStyleUnit_Coord) {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
if (NS_SUCCEEDED(imageLoader->GetNaturalWidth(&width)) &&
|
||||
NS_SUCCEEDED(imageLoader->GetNaturalHeight(&height))) {
|
||||
nscoord appWidth = nsPresContext::CSSPixelsToAppUnits((int32_t)width);
|
||||
nscoord appHeight = nsPresContext::CSSPixelsToAppUnits((int32_t)height);
|
||||
// If this image is rotated, we'll need to transpose the natural
|
||||
// width/height.
|
||||
bool coordFlip;
|
||||
if (StyleVisibility()->mImageOrientation.IsFromImage()) {
|
||||
coordFlip = mImage->GetOrientation().SwapsWidthAndHeight();
|
||||
} else {
|
||||
coordFlip = StyleVisibility()->mImageOrientation.SwapsWidthAndHeight();
|
||||
}
|
||||
intrinsicSize.width.SetCoordValue(coordFlip ? appHeight : appWidth);
|
||||
intrinsicSize.height.SetCoordValue(coordFlip ? appWidth : appHeight);
|
||||
}
|
||||
}
|
||||
|
||||
return ComputeSizeWithIntrinsicDimensions(aRenderingContext, aWM,
|
||||
intrinsicSize, mIntrinsicRatio,
|
||||
mIntrinsicSize, mIntrinsicRatio,
|
||||
aCBSize, aMargin, aBorder, aPadding,
|
||||
aFlags);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<!doctype html>
|
||||
<html reftest-zoom="2">
|
||||
<title>CSS Test Reference</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<style>
|
||||
.image-container {
|
||||
display: inline;
|
||||
}
|
||||
.content-container {
|
||||
display: inline-block;
|
||||
}
|
||||
.flex-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
<div class="flex-container">
|
||||
<div class="image-container">
|
||||
<img src="200.png" width="100">
|
||||
</div>
|
||||
<div class="content-container">
|
||||
Should see me right by the side of the image.
|
||||
</div>
|
||||
</div>
|
||||
</html>
|
|
@ -0,0 +1,41 @@
|
|||
<!doctype html>
|
||||
<html reftest-zoom="2" class="reftest-wait">
|
||||
<title>CSS Test: srcset intrinsic size isn't confused</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1149357">
|
||||
<style>
|
||||
.image-container {
|
||||
display: inline;
|
||||
}
|
||||
.content-container {
|
||||
display: inline-block;
|
||||
}
|
||||
.flex-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
// reftest-zoom is only applied at onload, so ensure the source-selection
|
||||
// has happened after that
|
||||
function clearWait() {
|
||||
document.documentElement.classList.remove("reftest-wait");
|
||||
}
|
||||
window.addEventListener("load", function() {
|
||||
setTimeout(function() {
|
||||
var img = document.querySelector("img");
|
||||
img.onload = clearWait;
|
||||
img.onerror = clearWait;
|
||||
img.src = img.src;
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
<div class="flex-container">
|
||||
<div class="image-container">
|
||||
<img srcset="50.png 0.5x, 100.png 1x, 200.png 2x, 300.png 3x, 400.png">
|
||||
</div>
|
||||
<div class="content-container">
|
||||
Should see me right by the side of the image.
|
||||
</div>
|
||||
</div>
|
||||
</html>
|
|
@ -118,6 +118,7 @@ fuzzy(1,1) == image-orientation-background.html?90&flip image-orientation-r
|
|||
== image-srcset-default-1x.html image-srcset-default-1x-ref.html
|
||||
== image-srcset-default-src-2x.html image-srcset-default-src-2x-ref.html
|
||||
== image-srcset-default-src-1x.html image-srcset-default-src-1x-ref.html
|
||||
== image-srcset-isize.html image-srcset-isize-ref.html
|
||||
== image-srcset-orientation-2x.html image-srcset-orientation-2x-ref.html
|
||||
== image-srcset-orientation-1x.html image-srcset-orientation-1x-ref.html
|
||||
== image-srcset-svg-3x.html image-srcset-svg-3x-ref.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче