Bug 1547792 - AspectRatio should be a single ratio, not a size. r=dholbert

Differential Revision: https://phabricator.services.mozilla.com/D29244

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2019-05-02 23:28:21 +00:00
Родитель 95888b91d6
Коммит b3863ed908
33 изменённых файлов: 265 добавлений и 284 удалений

Просмотреть файл

@ -214,14 +214,12 @@ ClippedImage::GetIntrinsicSize(nsSize* aSize) {
return NS_OK;
}
NS_IMETHODIMP
ClippedImage::GetIntrinsicRatio(nsSize* aRatio) {
Maybe<AspectRatio> ClippedImage::GetIntrinsicRatio() {
if (!ShouldClip()) {
return InnerImage()->GetIntrinsicRatio(aRatio);
return InnerImage()->GetIntrinsicRatio();
}
*aRatio = nsSize(mClip.Width(), mClip.Height());
return NS_OK;
return Some(AspectRatio::FromSize(mClip.Width(), mClip.Height()));
}
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)

Просмотреть файл

@ -34,7 +34,7 @@ class ClippedImage : public ImageWrapper {
NS_IMETHOD GetWidth(int32_t* aWidth) override;
NS_IMETHOD GetHeight(int32_t* aHeight) override;
NS_IMETHOD GetIntrinsicSize(nsSize* aSize) override;
NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) override;
Maybe<AspectRatio> GetIntrinsicRatio() override;
NS_IMETHOD_(already_AddRefed<SourceSurface>)
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) override;
NS_IMETHOD_(already_AddRefed<SourceSurface>)

Просмотреть файл

@ -104,11 +104,9 @@ DynamicImage::GetIntrinsicSize(nsSize* aSize) {
return NS_OK;
}
NS_IMETHODIMP
DynamicImage::GetIntrinsicRatio(nsSize* aSize) {
IntSize intSize(mDrawable->Size());
*aSize = nsSize(intSize.width, intSize.height);
return NS_OK;
Maybe<AspectRatio> DynamicImage::GetIntrinsicRatio() {
auto size = mDrawable->Size();
return Some(AspectRatio::FromSize(size.width, size.height));
}
NS_IMETHODIMP_(Orientation)

Просмотреть файл

@ -120,9 +120,8 @@ ImageWrapper::GetIntrinsicSize(nsSize* aSize) {
return mInnerImage->GetIntrinsicSize(aSize);
}
NS_IMETHODIMP
ImageWrapper::GetIntrinsicRatio(nsSize* aSize) {
return mInnerImage->GetIntrinsicRatio(aSize);
Maybe<AspectRatio> ImageWrapper::GetIntrinsicRatio() {
return mInnerImage->GetIntrinsicRatio();
}
NS_IMETHODIMP_(Orientation)

Просмотреть файл

@ -67,15 +67,12 @@ OrientedImage::GetIntrinsicSize(nsSize* aSize) {
return rv;
}
NS_IMETHODIMP
OrientedImage::GetIntrinsicRatio(nsSize* aRatio) {
nsresult rv = InnerImage()->GetIntrinsicRatio(aRatio);
if (mOrientation.SwapsWidthAndHeight()) {
swap(aRatio->width, aRatio->height);
Maybe<AspectRatio> OrientedImage::GetIntrinsicRatio() {
Maybe<AspectRatio> ratio = InnerImage()->GetIntrinsicRatio();
if (ratio && mOrientation.SwapsWidthAndHeight()) {
ratio = Some(ratio->Inverted());
}
return rv;
return ratio;
}
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)

Просмотреть файл

@ -31,7 +31,7 @@ class OrientedImage : public ImageWrapper {
NS_IMETHOD GetHeight(int32_t* aHeight) override;
nsresult GetNativeSizes(nsTArray<gfx::IntSize>& aNativeSizes) const override;
NS_IMETHOD GetIntrinsicSize(nsSize* aSize) override;
NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) override;
Maybe<AspectRatio> GetIntrinsicRatio() override;
NS_IMETHOD_(already_AddRefed<SourceSurface>)
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) override;
NS_IMETHOD_(already_AddRefed<SourceSurface>)

Просмотреть файл

@ -254,14 +254,12 @@ RasterImage::GetIntrinsicSize(nsSize* aSize) {
}
//******************************************************************************
NS_IMETHODIMP
RasterImage::GetIntrinsicRatio(nsSize* aRatio) {
Maybe<AspectRatio> RasterImage::GetIntrinsicRatio() {
if (mError) {
return NS_ERROR_FAILURE;
return Nothing();
}
*aRatio = nsSize(mSize.width, mSize.height);
return NS_OK;
return Some(AspectRatio::FromSize(mSize.width, mSize.height));
}
NS_IMETHODIMP_(Orientation)

Просмотреть файл

@ -635,19 +635,17 @@ VectorImage::GetIntrinsicSize(nsSize* aSize) {
}
//******************************************************************************
NS_IMETHODIMP
VectorImage::GetIntrinsicRatio(nsSize* aRatio) {
Maybe<AspectRatio> VectorImage::GetIntrinsicRatio() {
if (mError || !mIsFullyLoaded) {
return NS_ERROR_FAILURE;
return Nothing();
}
nsIFrame* rootFrame = mSVGDocumentWrapper->GetRootLayoutFrame();
if (!rootFrame) {
return NS_ERROR_FAILURE;
return Nothing();
}
*aRatio = rootFrame->GetIntrinsicRatio();
return NS_OK;
return Some(rootFrame->GetIntrinsicRatio());
}
NS_IMETHODIMP_(Orientation)

Просмотреть файл

@ -14,6 +14,7 @@ webidl Document;
#include "gfxMatrix.h"
#include "gfxRect.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/AspectRatio.h"
#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
#include "nsRect.h"
@ -45,6 +46,7 @@ struct Orientation;
%}
native MaybeAspectRatio(mozilla::Maybe<mozilla::AspectRatio>);
native ImgDrawResult(mozilla::image::ImgDrawResult);
[ptr] native gfxContext(gfxContext);
[ref] native gfxMatrix(gfxMatrix);
@ -99,9 +101,9 @@ interface imgIContainer : nsISupports
/**
* The (dimensionless) intrinsic ratio of this image. In the case of any
* error, an exception will be thrown.
* error, Nothing() will be returned.
*/
[noscript] readonly attribute nsSize intrinsicRatio;
[notxpcom, nostdcall] readonly attribute MaybeAspectRatio intrinsicRatio;
/**
* Given a size at which this image will be displayed, and the drawing

Просмотреть файл

@ -4397,7 +4397,7 @@ nsRect nsLayoutUtils::GetTextShadowRectsUnion(
enum ObjectDimensionType { eWidth, eHeight };
static nscoord ComputeMissingDimension(
const nsSize& aDefaultObjectSize, const nsSize& aIntrinsicRatio,
const nsSize& aDefaultObjectSize, const AspectRatio& aIntrinsicRatio,
const Maybe<nscoord>& aSpecifiedWidth,
const Maybe<nscoord>& aSpecifiedHeight,
ObjectDimensionType aDimensionToCompute) {
@ -4407,18 +4407,12 @@ static nscoord ComputeMissingDimension(
// 1. "If the object has an intrinsic aspect ratio, the missing dimension of
// the concrete object size is calculated using the intrinsic aspect
// ratio and the present dimension."
if (aIntrinsicRatio.width > 0 && aIntrinsicRatio.height > 0) {
if (aIntrinsicRatio) {
// Fill in the missing dimension using the intrinsic aspect ratio.
nscoord knownDimensionSize;
float ratio;
if (aDimensionToCompute == eWidth) {
knownDimensionSize = *aSpecifiedHeight;
ratio = aIntrinsicRatio.width / aIntrinsicRatio.height;
} else {
knownDimensionSize = *aSpecifiedWidth;
ratio = aIntrinsicRatio.height / aIntrinsicRatio.width;
return aIntrinsicRatio.ApplyTo(*aSpecifiedHeight);
}
return NSCoordSaturatingNonnegativeMultiply(knownDimensionSize, ratio);
return aIntrinsicRatio.Inverted().ApplyTo(*aSpecifiedWidth);
}
// 2. "Otherwise, if the missing dimension is present in the object's
@ -4458,7 +4452,7 @@ static nscoord ComputeMissingDimension(
*/
static Maybe<nsSize> MaybeComputeObjectFitNoneSize(
const nsSize& aDefaultObjectSize, const IntrinsicSize& aIntrinsicSize,
const nsSize& aIntrinsicRatio) {
const AspectRatio& aIntrinsicRatio) {
// "If the object has an intrinsic height or width, its size is resolved as
// if its intrinsic dimensions were given as the specified size."
//
@ -4496,13 +4490,12 @@ static Maybe<nsSize> MaybeComputeObjectFitNoneSize(
// http://dev.w3.org/csswg/css-images-3/#concrete-size-resolution
static nsSize ComputeConcreteObjectSize(const nsSize& aConstraintSize,
const IntrinsicSize& aIntrinsicSize,
const nsSize& aIntrinsicRatio,
const AspectRatio& aIntrinsicRatio,
uint8_t aObjectFit) {
// Handle default behavior (filling the container) w/ fast early return.
// (Also: if there's no valid intrinsic ratio, then we have the "fill"
// behavior & just use the constraint size.)
if (MOZ_LIKELY(aObjectFit == NS_STYLE_OBJECT_FIT_FILL) ||
aIntrinsicRatio.width == 0 || aIntrinsicRatio.height == 0) {
if (MOZ_LIKELY(aObjectFit == NS_STYLE_OBJECT_FIT_FILL) || !aIntrinsicRatio) {
return aConstraintSize;
}
@ -4580,7 +4573,7 @@ static bool HasInitialObjectFitAndPosition(const nsStylePosition* aStylePos) {
/* static */
nsRect nsLayoutUtils::ComputeObjectDestRect(const nsRect& aConstraintRect,
const IntrinsicSize& aIntrinsicSize,
const nsSize& aIntrinsicRatio,
const AspectRatio& aIntrinsicRatio,
const nsStylePosition* aStylePos,
nsPoint* aAnchorPoint) {
// Step 1: Figure out our "concrete object size"
@ -5439,10 +5432,11 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
!(styleMinBSize.IsAuto() || (styleMinBSize.ConvertsToLength() &&
styleMinBSize.ToLength() == 0)) ||
!styleMaxBSize.IsNone()) {
nsSize ratio(aFrame->GetIntrinsicRatio());
nscoord ratioISize = (horizontalAxis ? ratio.width : ratio.height);
nscoord ratioBSize = (horizontalAxis ? ratio.height : ratio.width);
if (ratioBSize != 0) {
if (AspectRatio ratio = aFrame->GetIntrinsicRatio()) {
// Convert 'ratio' if necessary, so that it's storing ISize/BSize:
if (!horizontalAxis) {
ratio = ratio.Inverted();
}
AddStateBitToAncestors(
aFrame, NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE);
@ -5459,7 +5453,7 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
(aPercentageBasis.isNothing() &&
GetPercentBSize(styleBSize, aFrame, horizontalAxis, h))) {
h = std::max(0, h - bSizeTakenByBoxSizing);
result = NSCoordMulDiv(h, ratioISize, ratioBSize);
result = ratio.ApplyTo(h);
}
if (GetDefiniteSize(styleMaxBSize, aFrame, !isInlineAxis,
@ -5467,7 +5461,7 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
(aPercentageBasis.isNothing() &&
GetPercentBSize(styleMaxBSize, aFrame, horizontalAxis, h))) {
h = std::max(0, h - bSizeTakenByBoxSizing);
nscoord maxISize = NSCoordMulDiv(h, ratioISize, ratioBSize);
nscoord maxISize = ratio.ApplyTo(h);
if (maxISize < result) {
result = maxISize;
}
@ -5481,7 +5475,7 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
(aPercentageBasis.isNothing() &&
GetPercentBSize(styleMinBSize, aFrame, horizontalAxis, h))) {
h = std::max(0, h - bSizeTakenByBoxSizing);
nscoord minISize = NSCoordMulDiv(h, ratioISize, ratioBSize);
nscoord minISize = ratio.ApplyTo(h);
if (minISize > result) {
result = minISize;
}
@ -6867,19 +6861,19 @@ ImgDrawResult nsLayoutUtils::DrawSingleImage(
/* static */
void nsLayoutUtils::ComputeSizeForDrawing(
imgIContainer* aImage, /* outparam */ CSSIntSize& aImageSize,
/* outparam */ nsSize& aIntrinsicRatio,
/* outparam */ AspectRatio& aIntrinsicRatio,
/* outparam */ bool& aGotWidth,
/* outparam */ bool& aGotHeight) {
aGotWidth = NS_SUCCEEDED(aImage->GetWidth(&aImageSize.width));
aGotHeight = NS_SUCCEEDED(aImage->GetHeight(&aImageSize.height));
bool gotRatio = NS_SUCCEEDED(aImage->GetIntrinsicRatio(&aIntrinsicRatio));
Maybe<AspectRatio> intrinsicRatio = aImage->GetIntrinsicRatio();
aIntrinsicRatio = intrinsicRatio.valueOr(AspectRatio());
if (!(aGotWidth && aGotHeight) && !gotRatio) {
if (!(aGotWidth && aGotHeight) && intrinsicRatio.isNothing()) {
// We hit an error (say, because the image failed to load or couldn't be
// decoded) and should return zero size.
aGotWidth = aGotHeight = true;
aImageSize = CSSIntSize(0, 0);
aIntrinsicRatio = nsSize(0, 0);
}
}
@ -6887,7 +6881,7 @@ void nsLayoutUtils::ComputeSizeForDrawing(
CSSIntSize nsLayoutUtils::ComputeSizeForDrawingWithFallback(
imgIContainer* aImage, const nsSize& aFallbackSize) {
CSSIntSize imageSize;
nsSize imageRatio;
AspectRatio imageRatio;
bool gotHeight, gotWidth;
ComputeSizeForDrawing(aImage, imageSize, imageRatio, gotWidth, gotHeight);
@ -6895,17 +6889,13 @@ CSSIntSize nsLayoutUtils::ComputeSizeForDrawingWithFallback(
// intrinsic ratio of the image.
if (gotWidth != gotHeight) {
if (!gotWidth) {
if (imageRatio.height != 0) {
imageSize.width = NSCoordSaturatingNonnegativeMultiply(
imageSize.height,
float(imageRatio.width) / float(imageRatio.height));
if (imageRatio) {
imageSize.width = imageRatio.ApplyTo(imageSize.height);
gotWidth = true;
}
} else {
if (imageRatio.width != 0) {
imageSize.height = NSCoordSaturatingNonnegativeMultiply(
imageSize.width,
float(imageRatio.height) / float(imageRatio.width));
if (imageRatio) {
imageSize.height = imageRatio.Inverted().ApplyTo(imageSize.width);
gotHeight = true;
}
}

Просмотреть файл

@ -62,6 +62,7 @@ struct nsStyleFont;
struct nsOverflowAreas;
namespace mozilla {
struct AspectRatio;
class ComputedStyle;
class PresShell;
enum class PseudoStyleType : uint8_t;
@ -146,6 +147,7 @@ enum class ReparentingDirection {
* is not to define multiple copies of the same static helper.
*/
class nsLayoutUtils {
typedef mozilla::AspectRatio AspectRatio;
typedef mozilla::ComputedStyle ComputedStyle;
typedef mozilla::LengthPercentage LengthPercentage;
typedef mozilla::LengthPercentageOrAuto LengthPercentageOrAuto;
@ -1326,7 +1328,7 @@ class nsLayoutUtils {
*/
static nsRect ComputeObjectDestRect(const nsRect& aConstraintRect,
const IntrinsicSize& aIntrinsicSize,
const nsSize& aIntrinsicRatio,
const AspectRatio& aIntrinsicRatio,
const nsStylePosition* aStylePos,
nsPoint* aAnchorPoint = nullptr);
@ -1926,8 +1928,8 @@ class nsLayoutUtils {
*/
static void ComputeSizeForDrawing(imgIContainer* aImage,
CSSIntSize& aImageSize,
nsSize& aIntrinsicRatio, bool& aGotWidth,
bool& aGotHeight);
AspectRatio& aIntrinsicRatio,
bool& aGotWidth, bool& aGotHeight);
/**
* Given an imgIContainer, this method attempts to obtain an intrinsic

Просмотреть файл

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_AspectRatio_h
#define mozilla_AspectRatio_h
/* The aspect ratio of a box, in a "width / height" format. */
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "nsCoord.h"
namespace mozilla {
struct AspectRatio {
AspectRatio() : mRatio(0.0f) {}
explicit AspectRatio(float aRatio) : mRatio(std::max(aRatio, 0.0f)) {}
static AspectRatio FromSize(float aWidth, float aHeight) {
if (aWidth == 0.0f || aHeight == 0.0f) {
return AspectRatio();
}
return AspectRatio(aWidth / aHeight);
}
explicit operator bool() const { return mRatio != 0.0f; }
nscoord ApplyTo(nscoord aCoord) const {
MOZ_DIAGNOSTIC_ASSERT(*this);
return NSCoordSaturatingNonnegativeMultiply(aCoord, mRatio);
}
// Inverts the ratio, in order to get the height / width ratio.
MOZ_MUST_USE AspectRatio Inverted() const {
return *this ? AspectRatio(1.0f / mRatio) : *this;
}
bool operator==(const AspectRatio& aOther) const {
return mRatio == aOther.mRatio;
}
bool operator!=(const AspectRatio& aOther) const {
return !(*this == aOther);
}
bool operator<(const AspectRatio& aOther) const {
return mRatio < aOther.mRatio;
}
private:
// 0.0f represents no aspect ratio.
float mRatio;
};
} // namespace mozilla
#endif // mozilla_AspectRatio_h

Просмотреть файл

@ -133,6 +133,7 @@ EXPORTS += [
]
EXPORTS.mozilla += [
'AspectRatio.h',
'AutoCopyListener.h',
'CSSAlignUtils.h',
'CSSOrderAwareFrameIterator.h',

Просмотреть файл

@ -392,14 +392,6 @@ class MOZ_STACK_CLASS nsFlexContainerFrame::FlexboxAxisTracker {
// this flag, to avoid reflowing our children in bottom-to-top order.)
bool AreAxesInternallyReversed() const { return mAreAxesInternallyReversed; }
private:
// Delete copy-constructor & reassignment operator, to prevent accidental
// (unnecessary) copying.
FlexboxAxisTracker(const FlexboxAxisTracker&) = delete;
FlexboxAxisTracker& operator=(const FlexboxAxisTracker&) = delete;
// Private because callers shouldn't need to care about physical axes
// (but we do internally, to provide one API).
bool IsMainAxisHorizontal() const {
// If we're row-oriented, and our writing mode is NOT vertical,
// or we're column-oriented and our writing mode IS vertical,
@ -407,6 +399,12 @@ class MOZ_STACK_CLASS nsFlexContainerFrame::FlexboxAxisTracker {
return mIsRowOriented != mWM.IsVertical();
}
private:
// Delete copy-constructor & reassignment operator, to prevent accidental
// (unnecessary) copying.
FlexboxAxisTracker(const FlexboxAxisTracker&) = delete;
FlexboxAxisTracker& operator=(const FlexboxAxisTracker&) = delete;
// Helpers for constructor which determine the orientation of our axes, based
// on legacy box properties (-webkit-box-orient, -webkit-box-direction) or
// modern flexbox properties (flex-direction, flex-wrap) depending on whether
@ -625,10 +623,8 @@ class nsFlexContainerFrame::FlexItem : public LinkedListElement<FlexItem> {
return mFlexShrink * mFlexBaseSize;
}
// Returns a LogicalSize representing the flex item's logical intrinsic ratio
// (ISize:BSize), as expressed in the *flex container's* writing mode.
const LogicalSize& IntrinsicRatio() const { return mIntrinsicRatio; }
bool HasIntrinsicRatio() const { return !mIntrinsicRatio.IsAllZero(); }
const AspectRatio& IntrinsicRatio() const { return mIntrinsicRatio; }
bool HasIntrinsicRatio() const { return !!mIntrinsicRatio; }
// Getters for margin:
// ===================
@ -846,7 +842,7 @@ class nsFlexContainerFrame::FlexItem : public LinkedListElement<FlexItem> {
nsIFrame* const mFrame; // The flex item's frame.
const float mFlexGrow;
const float mFlexShrink;
const LogicalSize mIntrinsicRatio;
const AspectRatio mIntrinsicRatio;
const nsMargin mBorderPadding;
nsMargin mMargin; // non-const because we need to resolve auto margins
@ -1452,16 +1448,17 @@ static nscoord CrossSizeToUseWithRatio(const FlexItem& aFlexItem,
// Convenience function; returns a main-size, given a cross-size and an
// intrinsic ratio. The caller is responsible for ensuring that the passed-in
// intrinsic ratio must not have 0 in its cross-axis component (or else we'll
// divide by 0).
// intrinsic ratio is not zero.
static nscoord MainSizeFromAspectRatio(nscoord aCrossSize,
const LogicalSize& aIntrinsicRatio,
const AspectRatio& aIntrinsicRatio,
const FlexboxAxisTracker& aAxisTracker) {
MOZ_ASSERT(aAxisTracker.GetCrossComponent(aIntrinsicRatio) != 0,
MOZ_ASSERT(aIntrinsicRatio,
"Invalid ratio; will divide by 0! Caller should've checked...");
return NSCoordMulDiv(aCrossSize,
aAxisTracker.GetMainComponent(aIntrinsicRatio),
aAxisTracker.GetCrossComponent(aIntrinsicRatio));
AspectRatio ratio = aAxisTracker.IsMainAxisHorizontal()
? aIntrinsicRatio
: aIntrinsicRatio.Inverted();
return ratio.ApplyTo(aCrossSize);
}
// Partially resolves "min-[width|height]:auto" and returns the resulting value.
@ -1506,7 +1503,7 @@ static nscoord PartiallyResolveAutoMinSize(
// * if the item has an intrinsic aspect ratio, the width (height) calculated
// from the aspect ratio and any definite size constraints in the opposite
// dimension.
if (aAxisTracker.GetCrossComponent(aFlexItem.IntrinsicRatio()) != 0) {
if (aFlexItem.IntrinsicRatio()) {
// We have a usable aspect ratio. (not going to divide by 0)
const bool useMinSizeIfCrossSizeIsIndefinite = true;
nscoord crossSizeToUseWithRatio = CrossSizeToUseWithRatio(
@ -1536,7 +1533,7 @@ static bool ResolveAutoFlexBasisFromRatio(
// - a definite cross size
// then the flex base size is calculated from its inner cross size and the
// flex items intrinsic aspect ratio.
if (aAxisTracker.GetCrossComponent(aFlexItem.IntrinsicRatio()) != 0) {
if (aFlexItem.IntrinsicRatio()) {
// We have a usable aspect ratio. (not going to divide by 0)
const bool useMinSizeIfCrossSizeIsIndefinite = false;
nscoord crossSizeToUseWithRatio = CrossSizeToUseWithRatio(
@ -1611,8 +1608,7 @@ void nsFlexContainerFrame::ResolveAutoFlexBasisAndMinSize(
// (We'll consider that later, if we need to.)
resolvedMinSize =
PartiallyResolveAutoMinSize(aFlexItem, aItemReflowInput, aAxisTracker);
if (resolvedMinSize > 0 &&
aAxisTracker.GetCrossComponent(aFlexItem.IntrinsicRatio()) == 0) {
if (resolvedMinSize > 0 && !aFlexItem.IntrinsicRatio()) {
// We don't have a usable aspect ratio, so we need to consider our
// min-content size as another candidate min-size, which we'll have to
// min() with the current resolvedMinSize.
@ -1872,9 +1868,7 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput, float aFlexGrow,
: mFrame(aFlexItemReflowInput.mFrame),
mFlexGrow(aFlexGrow),
mFlexShrink(aFlexShrink),
// We store the intrinsic ratio in the *flex container's* WM:
mIntrinsicRatio(aAxisTracker.GetWritingMode(),
mFrame->GetIntrinsicRatio()),
mIntrinsicRatio(mFrame->GetIntrinsicRatio()),
mBorderPadding(aFlexItemReflowInput.ComputedPhysicalBorderPadding()),
mMargin(aFlexItemReflowInput.ComputedPhysicalMargin()),
mMainMinSize(aMainMinSize),
@ -1976,7 +1970,6 @@ FlexItem::FlexItem(nsIFrame* aChildFrame, nscoord aCrossSize,
: mFrame(aChildFrame),
mFlexGrow(0.0f),
mFlexShrink(0.0f),
mIntrinsicRatio(aContainerWM),
// mBorderPadding uses default constructor,
// mMargin uses default constructor,
mFlexBaseSize(0),

Просмотреть файл

@ -5521,7 +5521,7 @@ IntrinsicSize nsFrame::GetIntrinsicSize() {
}
/* virtual */
nsSize nsFrame::GetIntrinsicRatio() { return nsSize(0, 0); }
AspectRatio nsFrame::GetIntrinsicRatio() { return AspectRatio(); }
/* virtual */
LogicalSize nsFrame::ComputeSize(gfxContext* aRenderingContext, WritingMode aWM,
@ -5531,7 +5531,7 @@ LogicalSize nsFrame::ComputeSize(gfxContext* aRenderingContext, WritingMode aWM,
const LogicalSize& aBorder,
const LogicalSize& aPadding,
ComputeSizeFlags aFlags) {
MOZ_ASSERT(GetIntrinsicRatio() == nsSize(0, 0),
MOZ_ASSERT(!GetIntrinsicRatio(),
"Please override this method and call "
"nsFrame::ComputeSizeWithIntrinsicDimensions instead.");
LogicalSize result =
@ -5783,10 +5783,12 @@ LogicalSize nsFrame::ComputeSize(gfxContext* aRenderingContext, WritingMode aWM,
LogicalSize nsFrame::ComputeSizeWithIntrinsicDimensions(
gfxContext* aRenderingContext, WritingMode aWM,
const IntrinsicSize& aIntrinsicSize, nsSize aIntrinsicRatio,
const IntrinsicSize& aIntrinsicSize, const AspectRatio& aIntrinsicRatio,
const LogicalSize& aCBSize, const LogicalSize& aMargin,
const LogicalSize& aBorder, const LogicalSize& aPadding,
ComputeSizeFlags aFlags) {
auto logicalRatio =
aWM.IsVertical() ? aIntrinsicRatio.Inverted() : aIntrinsicRatio;
const nsStylePosition* stylePos = StylePosition();
const auto* inlineStyleCoord = &stylePos->ISize(aWM);
const auto* blockStyleCoord = &stylePos->BSize(aWM);
@ -5915,10 +5917,6 @@ LogicalSize nsFrame::ComputeSizeWithIntrinsicDimensions(
const bool hasIntrinsicBSize = bsizeCoord.isSome();
nscoord intrinsicBSize = std::max(0, bsizeCoord.valueOr(0));
NS_ASSERTION(aIntrinsicRatio.width >= 0 && aIntrinsicRatio.height >= 0,
"Intrinsic ratio has a negative component!");
LogicalSize logicalRatio(aWM, aIntrinsicRatio);
if (!isAutoISize) {
iSize = ComputeISizeValue(
aRenderingContext, aCBSize.ISize(aWM), boxSizingAdjust.ISize(aWM),
@ -5937,7 +5935,7 @@ LogicalSize nsFrame::ComputeSizeWithIntrinsicDimensions(
// or ratio in the relevant dimension, otherwise 'stretch'.
// https://drafts.csswg.org/css-grid/#grid-item-sizing
if ((inlineAxisAlignment == NS_STYLE_ALIGN_NORMAL &&
!hasIntrinsicISize && !(logicalRatio.ISize(aWM) > 0)) ||
!hasIntrinsicISize && !logicalRatio) ||
inlineAxisAlignment == NS_STYLE_ALIGN_STRETCH) {
stretchI = eStretch;
}
@ -6004,7 +6002,7 @@ LogicalSize nsFrame::ComputeSizeWithIntrinsicDimensions(
// or ratio in the relevant dimension, otherwise 'stretch'.
// https://drafts.csswg.org/css-grid/#grid-item-sizing
if ((blockAxisAlignment == NS_STYLE_ALIGN_NORMAL &&
!hasIntrinsicBSize && !(logicalRatio.BSize(aWM) > 0)) ||
!hasIntrinsicBSize && !logicalRatio) ||
blockAxisAlignment == NS_STYLE_ALIGN_STRETCH) {
stretchB = eStretch;
}
@ -6059,10 +6057,9 @@ LogicalSize nsFrame::ComputeSizeWithIntrinsicDimensions(
if (hasIntrinsicISize) {
tentISize = intrinsicISize;
} else if (hasIntrinsicBSize && logicalRatio.BSize(aWM) > 0) {
tentISize = NSCoordMulDiv(intrinsicBSize, logicalRatio.ISize(aWM),
logicalRatio.BSize(aWM));
} else if (logicalRatio.ISize(aWM) > 0) {
} else if (hasIntrinsicBSize && logicalRatio) {
tentISize = logicalRatio.ApplyTo(intrinsicBSize);
} else if (logicalRatio) {
tentISize =
aCBSize.ISize(aWM) - boxSizingToMarginEdgeISize; // XXX scrollbar?
if (tentISize < 0) tentISize = 0;
@ -6080,9 +6077,8 @@ LogicalSize nsFrame::ComputeSizeWithIntrinsicDimensions(
if (hasIntrinsicBSize) {
tentBSize = intrinsicBSize;
} else if (logicalRatio.ISize(aWM) > 0) {
tentBSize = NSCoordMulDiv(tentISize, logicalRatio.BSize(aWM),
logicalRatio.ISize(aWM));
} else if (logicalRatio) {
tentBSize = logicalRatio.Inverted().ApplyTo(tentISize);
} else {
tentBSize = nsPresContext::CSSPixelsToAppUnits(150);
}
@ -6093,45 +6089,32 @@ LogicalSize nsFrame::ComputeSizeWithIntrinsicDimensions(
stretchB = (stretchI == eStretch ? eStretch : eStretchPreservingRatio);
}
if (aIntrinsicRatio != nsSize(0, 0)) {
if (logicalRatio) {
if (stretchI == eStretch) {
tentISize = iSize; // * / 'stretch'
if (stretchB == eStretch) {
tentBSize = bSize; // 'stretch' / 'stretch'
} else if (stretchB == eStretchPreservingRatio &&
logicalRatio.ISize(aWM) > 0) {
} else if (stretchB == eStretchPreservingRatio) {
// 'normal' / 'stretch'
tentBSize = NSCoordMulDiv(iSize, logicalRatio.BSize(aWM),
logicalRatio.ISize(aWM));
tentBSize = logicalRatio.Inverted().ApplyTo(iSize);
}
} else if (stretchB == eStretch) {
tentBSize = bSize; // 'stretch' / * (except 'stretch')
if (stretchI == eStretchPreservingRatio &&
logicalRatio.BSize(aWM) > 0) {
if (stretchI == eStretchPreservingRatio) {
// 'stretch' / 'normal'
tentISize = NSCoordMulDiv(bSize, logicalRatio.ISize(aWM),
logicalRatio.BSize(aWM));
tentISize = logicalRatio.ApplyTo(bSize);
}
} else if (stretchI == eStretchPreservingRatio) {
tentISize = iSize; // * (except 'stretch') / 'normal'
if (logicalRatio.ISize(aWM) > 0) {
tentBSize = NSCoordMulDiv(iSize, logicalRatio.BSize(aWM),
logicalRatio.ISize(aWM));
}
tentBSize = logicalRatio.Inverted().ApplyTo(iSize);
if (stretchB == eStretchPreservingRatio && tentBSize > bSize) {
// Stretch within the CB size with preserved intrinsic ratio.
tentBSize = bSize; // 'normal' / 'normal'
if (logicalRatio.BSize(aWM) > 0) {
tentISize = NSCoordMulDiv(bSize, logicalRatio.ISize(aWM),
logicalRatio.BSize(aWM));
}
tentISize = logicalRatio.ApplyTo(bSize);
}
} else if (stretchB == eStretchPreservingRatio) {
tentBSize = bSize; // 'normal' / * (except 'normal' and 'stretch')
if (logicalRatio.BSize(aWM) > 0) {
tentISize = NSCoordMulDiv(bSize, logicalRatio.ISize(aWM),
logicalRatio.BSize(aWM));
}
tentISize = logicalRatio.ApplyTo(bSize);
}
}
@ -6139,8 +6122,7 @@ LogicalSize nsFrame::ComputeSizeWithIntrinsicDimensions(
// applying the min/max-size. We don't want that when we have 'stretch'
// in either axis because tentISize/tentBSize is likely not according to
// ratio now.
if (aIntrinsicRatio != nsSize(0, 0) && stretchI != eStretch &&
stretchB != eStretch) {
if (logicalRatio && stretchI != eStretch && stretchB != eStretch) {
nsSize autoSize = nsLayoutUtils::ComputeAutoSizeWithIntrinsicDimensions(
minISize, minBSize, maxISize, maxBSize, tentISize, tentBSize);
// The nsSize that ComputeAutoSizeWithIntrinsicDimensions returns will
@ -6158,9 +6140,8 @@ LogicalSize nsFrame::ComputeSizeWithIntrinsicDimensions(
// 'auto' iSize, non-'auto' bSize
bSize = NS_CSS_MINMAX(bSize, minBSize, maxBSize);
if (stretchI != eStretch) {
if (logicalRatio.BSize(aWM) > 0) {
iSize = NSCoordMulDiv(bSize, logicalRatio.ISize(aWM),
logicalRatio.BSize(aWM));
if (logicalRatio) {
iSize = logicalRatio.ApplyTo(bSize);
} else if (hasIntrinsicISize) {
if (!((aFlags & ComputeSizeFlags::eIClampMarginBoxMinSize) &&
intrinsicISize > iSize)) {
@ -6177,9 +6158,8 @@ LogicalSize nsFrame::ComputeSizeWithIntrinsicDimensions(
// non-'auto' iSize, 'auto' bSize
iSize = NS_CSS_MINMAX(iSize, minISize, maxISize);
if (stretchB != eStretch) {
if (logicalRatio.ISize(aWM) > 0) {
bSize = NSCoordMulDiv(iSize, logicalRatio.BSize(aWM),
logicalRatio.ISize(aWM));
if (logicalRatio) {
bSize = logicalRatio.Inverted().ApplyTo(iSize);
} else if (hasIntrinsicBSize) {
if (!((aFlags & ComputeSizeFlags::eBClampMarginBoxMinSize) &&
intrinsicBSize > bSize)) {

Просмотреть файл

@ -273,7 +273,7 @@ class nsFrame : public nsBox {
IntrinsicISizeOffsetData IntrinsicISizeOffsets(
nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE) override;
mozilla::IntrinsicSize GetIntrinsicSize() override;
nsSize GetIntrinsicRatio() override;
mozilla::AspectRatio GetIntrinsicRatio() override;
mozilla::LogicalSize ComputeSize(
gfxContext* aRenderingContext, mozilla::WritingMode aWM,
@ -287,7 +287,8 @@ class nsFrame : public nsBox {
*/
mozilla::LogicalSize ComputeSizeWithIntrinsicDimensions(
gfxContext* aRenderingContext, mozilla::WritingMode aWM,
const mozilla::IntrinsicSize& aIntrinsicSize, nsSize aIntrinsicRatio,
const mozilla::IntrinsicSize& aIntrinsicSize,
const mozilla::AspectRatio& aIntrinsicRatio,
const mozilla::LogicalSize& aCBSize, const mozilla::LogicalSize& aMargin,
const mozilla::LogicalSize& aBorder, const mozilla::LogicalSize& aPadding,
ComputeSizeFlags aFlags);

Просмотреть файл

@ -52,9 +52,9 @@ static IntrinsicSize IntrinsicSizeFromCanvasSize(
* by GetCanvasSize().
* @return The canvas's intrinsic ratio, as a nsSize.
*/
static nsSize IntrinsicRatioFromCanvasSize(const nsIntSize& aCanvasSizeInPx) {
return nsSize(nsPresContext::CSSPixelsToAppUnits(aCanvasSizeInPx.width),
nsPresContext::CSSPixelsToAppUnits(aCanvasSizeInPx.height));
static AspectRatio IntrinsicRatioFromCanvasSize(
const nsIntSize& aCanvasSizeInPx) {
return AspectRatio::FromSize(aCanvasSizeInPx.width, aCanvasSizeInPx.height);
}
class nsDisplayCanvas final : public nsDisplayItem {
@ -86,7 +86,7 @@ class nsDisplayCanvas final : public nsDisplayItem {
// Need intrinsic size & ratio, for ComputeObjectDestRect:
nsIntSize canvasSize = f->GetCanvasSize();
IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSize);
nsSize intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSize);
AspectRatio intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSize);
const nsRect destRect = nsLayoutUtils::ComputeObjectDestRect(
constraintRect, intrinsicSize, intrinsicRatio, f->StylePosition());
@ -145,7 +145,8 @@ class nsDisplayCanvas final : public nsDisplayItem {
nsIntSize canvasSizeInPx = data->GetSize();
IntrinsicSize intrinsicSize =
IntrinsicSizeFromCanvasSize(canvasSizeInPx);
nsSize intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSizeInPx);
AspectRatio intrinsicRatio =
IntrinsicRatioFromCanvasSize(canvasSizeInPx);
nsRect area =
mFrame->GetContentRectRelativeToSelf() + ToReferenceFrame();
@ -298,9 +299,9 @@ IntrinsicSize nsHTMLCanvasFrame::GetIntrinsicSize() {
}
/* virtual */
nsSize nsHTMLCanvasFrame::GetIntrinsicRatio() {
AspectRatio nsHTMLCanvasFrame::GetIntrinsicRatio() {
if (StyleDisplay()->IsContainSize()) {
return nsSize(0, 0);
return AspectRatio();
}
return IntrinsicRatioFromCanvasSize(GetCanvasSize());
}
@ -312,10 +313,10 @@ LogicalSize nsHTMLCanvasFrame::ComputeSize(
const LogicalSize& aBorder, const LogicalSize& aPadding,
ComputeSizeFlags aFlags) {
IntrinsicSize intrinsicSize;
nsSize intrinsicRatio;
AspectRatio intrinsicRatio;
if (StyleDisplay()->IsContainSize()) {
intrinsicSize = IntrinsicSize(0, 0);
// intrinsicRatio is already implicitly 0,0 via default ctor.
// intrinsicRatio is already implicitly zero via default ctor.
} else {
nsIntSize canvasSizeInPx = GetCanvasSize();
intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSizeInPx);
@ -416,7 +417,7 @@ already_AddRefed<Layer> nsHTMLCanvasFrame::BuildLayer(
if (!layer) return nullptr;
IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSizeInPx);
nsSize intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSizeInPx);
AspectRatio intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSizeInPx);
nsRect dest = nsLayoutUtils::ComputeObjectDestRect(
area, intrinsicSize, intrinsicRatio, StylePosition());

Просмотреть файл

@ -64,7 +64,7 @@ class nsHTMLCanvasFrame final : public nsContainerFrame {
virtual nscoord GetMinISize(gfxContext* aRenderingContext) override;
virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override;
virtual mozilla::IntrinsicSize GetIntrinsicSize() override;
virtual nsSize GetIntrinsicRatio() override;
virtual mozilla::AspectRatio GetIntrinsicRatio() override;
virtual mozilla::LogicalSize ComputeSize(
gfxContext* aRenderingContext, mozilla::WritingMode aWritingMode,

Просмотреть файл

@ -53,6 +53,7 @@
#include "FrameProperties.h"
#include "LayoutConstants.h"
#include "mozilla/layout/FrameChildList.h"
#include "mozilla/AspectRatio.h"
#include "mozilla/Maybe.h"
#include "mozilla/SmallPointerArray.h"
#include "mozilla/WritingModes.h"
@ -2371,15 +2372,14 @@ class nsIFrame : public nsQueryFrame {
virtual mozilla::IntrinsicSize GetIntrinsicSize() = 0;
/**
* Get the intrinsic ratio of this element, or nsSize(0,0) if it has
* no intrinsic ratio. The intrinsic ratio is the ratio of the
* height/width of a box with an intrinsic size or the intrinsic
* aspect ratio of a scalable vector image without an intrinsic size.
* Get the intrinsic ratio of this element, or a default-constructed
* AspectRatio if it has no intrinsic ratio.
*
* Either one of the sides may be zero, indicating a zero or infinite
* ratio.
* The intrinsic ratio is the ratio of the width/height of a box with an
* intrinsic size or the intrinsic aspect ratio of a scalable vector image
* without an intrinsic size.
*/
virtual nsSize GetIntrinsicRatio() = 0;
virtual mozilla::AspectRatio GetIntrinsicRatio() = 0;
/**
* Bit-flags to pass to ComputeSize in |aFlags| parameter.

Просмотреть файл

@ -209,7 +209,6 @@ nsImageFrame::nsImageFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
: nsAtomicContainerFrame(aStyle, aPresContext, aID),
mComputedSize(0, 0),
mIntrinsicSize(0, 0),
mIntrinsicRatio(0, 0),
mKind(aKind),
mContentURLRequestRegistered(false),
mDisplayingIcon(false),
@ -483,15 +482,13 @@ bool nsImageFrame::UpdateIntrinsicRatio(imgIContainer* aImage) {
if (!aImage) return false;
nsSize oldIntrinsicRatio = mIntrinsicRatio;
// Set intrinsic ratio to match aImage's reported intrinsic ratio.
// But if we have 'contain:size', or aImage hasn't loaded enough to report
// useful ratio, we fall back to 0,0.
if (StyleDisplay()->IsContainSize() ||
NS_FAILED(aImage->GetIntrinsicRatio(&mIntrinsicRatio))) {
mIntrinsicRatio.SizeTo(0, 0);
}
AspectRatio oldIntrinsicRatio = mIntrinsicRatio;
mIntrinsicRatio = StyleDisplay()->IsContainSize()
? AspectRatio()
: aImage->GetIntrinsicRatio().valueOr(AspectRatio());
return mIntrinsicRatio != oldIntrinsicRatio;
}
@ -699,7 +696,7 @@ nsresult nsImageFrame::OnSizeAvailable(imgIRequest* aRequest,
// Have to size to 0,0 so that GetDesiredSize recalculates the size.
mIntrinsicSize = IntrinsicSize(0, 0);
mIntrinsicRatio.SizeTo(0, 0);
mIntrinsicRatio = AspectRatio();
intrinsicSizeChanged = true;
}
@ -820,7 +817,7 @@ void nsImageFrame::NotifyNewCurrentRequest(imgIRequest* aRequest,
// Have to size to 0,0 so that GetDesiredSize recalculates the size
mIntrinsicSize = IntrinsicSize(0, 0);
mIntrinsicRatio.SizeTo(0, 0);
mIntrinsicRatio = AspectRatio();
}
if (GotInitialReflow()) {
@ -907,7 +904,7 @@ void nsImageFrame::EnsureIntrinsicSizeAndRatio() {
// If we have 'contain:size', then our intrinsic size and ratio are 0,0
// regardless of what our underlying image may think.
mIntrinsicSize = IntrinsicSize(0, 0);
mIntrinsicRatio.SizeTo(0, 0);
mIntrinsicRatio = AspectRatio();
return;
}
@ -928,7 +925,7 @@ void nsImageFrame::EnsureIntrinsicSizeAndRatio() {
nscoord edgeLengthToUse = nsPresContext::CSSPixelsToAppUnits(
ICON_SIZE + (2 * (ICON_PADDING + ALT_BORDER_WIDTH)));
mIntrinsicSize = IntrinsicSize(edgeLengthToUse, edgeLengthToUse);
mIntrinsicRatio.SizeTo(1, 1);
mIntrinsicRatio = AspectRatio(1.0f);
}
}
@ -997,7 +994,7 @@ nscoord nsImageFrame::GetPrefISize(gfxContext* aRenderingContext) {
IntrinsicSize nsImageFrame::GetIntrinsicSize() { return mIntrinsicSize; }
/* virtual */
nsSize nsImageFrame::GetIntrinsicRatio() { return mIntrinsicRatio; }
AspectRatio nsImageFrame::GetIntrinsicRatio() { return mIntrinsicRatio; }
void nsImageFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
const ReflowInput& aReflowInput,

Просмотреть файл

@ -84,7 +84,7 @@ class nsImageFrame : public nsAtomicContainerFrame, public nsIReflowCallback {
virtual nscoord GetMinISize(gfxContext* aRenderingContext) override;
virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override;
virtual mozilla::IntrinsicSize GetIntrinsicSize() override;
virtual nsSize GetIntrinsicRatio() override;
virtual mozilla::AspectRatio GetIntrinsicRatio() override;
virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) override;
@ -362,7 +362,7 @@ class nsImageFrame : public nsAtomicContainerFrame, public nsIReflowCallback {
nsCOMPtr<imgIContainer> mPrevImage;
nsSize mComputedSize;
mozilla::IntrinsicSize mIntrinsicSize;
nsSize mIntrinsicRatio;
mozilla::AspectRatio mIntrinsicRatio;
const Kind mKind;
bool mContentURLRequestRegistered;

Просмотреть файл

@ -727,7 +727,7 @@ static bool IsPercentageAware(const nsIFrame* aFrame, WritingMode aWM) {
// is calculated from the constraint equation used for
// block-level, non-replaced elements in normal flow.
nsIFrame* f = const_cast<nsIFrame*>(aFrame);
if (f->GetIntrinsicRatio() != nsSize(0, 0) &&
if (f->GetIntrinsicRatio() &&
// Some percents are treated like 'auto', so check != coord
!pos->BSize(aWM).ConvertsToLength()) {
const IntrinsicSize& intrinsicSize = f->GetIntrinsicSize();

Просмотреть файл

@ -723,7 +723,7 @@ IntrinsicSize nsSubDocumentFrame::GetIntrinsicSize() {
}
/* virtual */
nsSize nsSubDocumentFrame::GetIntrinsicRatio() {
AspectRatio nsSubDocumentFrame::GetIntrinsicRatio() {
nsIFrame* subDocRoot = ObtainIntrinsicSizeFrame();
if (subDocRoot) {
return subDocRoot->GetIntrinsicRatio();
@ -805,7 +805,7 @@ void nsSubDocumentFrame::Reflow(nsPresContext* aPresContext,
// Size & position the view according to 'object-fit' & 'object-position'.
nsIFrame* subDocRoot = ObtainIntrinsicSizeFrame();
IntrinsicSize intrinsSize;
nsSize intrinsRatio;
AspectRatio intrinsRatio;
if (subDocRoot) {
intrinsSize = subDocRoot->GetIntrinsicSize();
intrinsRatio = subDocRoot->GetIntrinsicRatio();

Просмотреть файл

@ -55,7 +55,7 @@ class nsSubDocumentFrame final : public nsAtomicContainerFrame,
nscoord GetPrefISize(gfxContext* aRenderingContext) override;
mozilla::IntrinsicSize GetIntrinsicSize() override;
nsSize GetIntrinsicRatio() override;
mozilla::AspectRatio GetIntrinsicRatio() override;
mozilla::LogicalSize ComputeAutoSize(
gfxContext* aRenderingContext, mozilla::WritingMode aWritingMode,

Просмотреть файл

@ -189,9 +189,11 @@ already_AddRefed<Layer> nsVideoFrame::BuildLayer(
// Convert video size from pixel units into app units, to get an aspect-ratio
// (which has to be represented as a nsSize) and an IntrinsicSize that we
// can pass to ComputeObjectRenderRect.
nsSize aspectRatio(nsPresContext::CSSPixelsToAppUnits(videoSizeInPx.width),
nsPresContext::CSSPixelsToAppUnits(videoSizeInPx.height));
IntrinsicSize intrinsicSize(aspectRatio.width, aspectRatio.height);
auto aspectRatio =
AspectRatio::FromSize(videoSizeInPx.width, videoSizeInPx.height);
IntrinsicSize intrinsicSize(
nsPresContext::CSSPixelsToAppUnits(videoSizeInPx.width),
nsPresContext::CSSPixelsToAppUnits(videoSizeInPx.height));
nsRect dest = nsLayoutUtils::ComputeObjectDestRect(
area, intrinsicSize, aspectRatio, StylePosition());
@ -434,10 +436,11 @@ class nsDisplayVideo : public nsDisplayItem {
// Convert video size from pixel units into app units, to get an
// aspect-ratio (which has to be represented as a nsSize) and an
// IntrinsicSize that we can pass to ComputeObjectRenderRect.
nsSize aspectRatio(
IntrinsicSize intrinsicSize(
nsPresContext::CSSPixelsToAppUnits(videoSizeInPx.width),
nsPresContext::CSSPixelsToAppUnits(videoSizeInPx.height));
IntrinsicSize intrinsicSize(aspectRatio.width, aspectRatio.height);
auto aspectRatio =
AspectRatio::FromSize(videoSizeInPx.width, videoSizeInPx.height);
nsRect dest = nsLayoutUtils::ComputeObjectDestRect(
area, intrinsicSize, aspectRatio, Frame()->StylePosition());
@ -576,7 +579,9 @@ LogicalSize nsVideoFrame::ComputeSize(
IntrinsicSize intrinsicSize(size.width, size.height);
// Only video elements have an intrinsic ratio.
nsSize intrinsicRatio = HasVideoElement() ? size : nsSize(0, 0);
auto intrinsicRatio = HasVideoElement()
? AspectRatio::FromSize(size.width, size.height)
: AspectRatio();
return ComputeSizeWithIntrinsicDimensions(
aRenderingContext, aWM, intrinsicSize, intrinsicRatio, aCBSize, aMargin,
@ -627,13 +632,14 @@ nscoord nsVideoFrame::GetPrefISize(gfxContext* aRenderingContext) {
return result;
}
nsSize nsVideoFrame::GetIntrinsicRatio() {
AspectRatio nsVideoFrame::GetIntrinsicRatio() {
if (!HasVideoElement()) {
// Audio elements have no intrinsic ratio.
return nsSize(0, 0);
return AspectRatio();
}
return GetVideoIntrinsicSize(nullptr);
nsSize size = GetVideoIntrinsicSize(nullptr);
return AspectRatio::FromSize(size.width, size.height);
}
bool nsVideoFrame::ShouldDisplayPoster() {

Просмотреть файл

@ -55,7 +55,7 @@ class nsVideoFrame final : public nsContainerFrame,
/* get the size of the video's display */
nsSize GetVideoIntrinsicSize(gfxContext* aRenderingContext);
nsSize GetIntrinsicRatio() override;
mozilla::AspectRatio GetIntrinsicRatio() override;
mozilla::LogicalSize ComputeSize(
gfxContext* aRenderingContext, mozilla::WritingMode aWritingMode,
const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize,

Просмотреть файл

@ -2888,12 +2888,10 @@ static nsSize ComputeDrawnSizeForBackground(
imageSize.width, aBgPositioningArea.width);
if (!isRepeatRoundInBothDimensions && aLayerSize.IsExplicitSize() &&
aLayerSize.explicit_size.height.IsAuto()) {
// Restore intrinsic rato
if (aIntrinsicSize.mRatio.width) {
float scale =
float(aIntrinsicSize.mRatio.height) / aIntrinsicSize.mRatio.width;
// Restore intrinsic ratio
if (aIntrinsicSize.mRatio) {
imageSize.height =
NSCoordSaturatingNonnegativeMultiply(imageSize.width, scale);
aIntrinsicSize.mRatio.Inverted().ApplyTo(imageSize.width);
}
}
}
@ -2905,12 +2903,9 @@ static nsSize ComputeDrawnSizeForBackground(
imageSize.height, aBgPositioningArea.height);
if (!isRepeatRoundInBothDimensions && aLayerSize.IsExplicitSize() &&
aLayerSize.explicit_size.width.IsAuto()) {
// Restore intrinsic rato
if (aIntrinsicSize.mRatio.height) {
float scale =
float(aIntrinsicSize.mRatio.width) / aIntrinsicSize.mRatio.height;
imageSize.width =
NSCoordSaturatingNonnegativeMultiply(imageSize.height, scale);
// Restore intrinsic ratio
if (aIntrinsicSize.mRatio) {
imageSize.width = aIntrinsicSize.mRatio.ApplyTo(imageSize.height);
}
}
}

Просмотреть файл

@ -38,15 +38,11 @@ nsSize CSSSizeOrRatio::ComputeConcreteSize() const {
return nsSize(mWidth, mHeight);
}
if (mHasWidth) {
nscoord height = NSCoordSaturatingNonnegativeMultiply(
mWidth, double(mRatio.height) / mRatio.width);
return nsSize(mWidth, height);
return nsSize(mWidth, mRatio.Inverted().ApplyTo(mWidth));
}
MOZ_ASSERT(mHasHeight);
nscoord width = NSCoordSaturatingNonnegativeMultiply(
mHeight, double(mRatio.width) / mRatio.height);
return nsSize(width, mHeight);
return nsSize(mRatio.ApplyTo(mHeight), mHeight);
}
nsImageRenderer::nsImageRenderer(nsIFrame* aForFrame,
@ -228,15 +224,12 @@ CSSSizeOrRatio nsImageRenderer::ComputeIntrinsicSize() {
// If we know the aspect ratio and one of the dimensions,
// we can compute the other missing width or height.
if (!haveHeight && haveWidth && result.mRatio.width != 0) {
nscoord intrinsicHeight = NSCoordSaturatingNonnegativeMultiply(
imageIntSize.width,
float(result.mRatio.height) / float(result.mRatio.width));
if (!haveHeight && haveWidth && result.mRatio) {
nscoord intrinsicHeight =
result.mRatio.Inverted().ApplyTo(imageIntSize.width);
result.SetHeight(nsPresContext::CSSPixelsToAppUnits(intrinsicHeight));
} else if (haveHeight && !haveWidth && result.mRatio.height != 0) {
nscoord intrinsicWidth = NSCoordSaturatingNonnegativeMultiply(
imageIntSize.height,
float(result.mRatio.width) / float(result.mRatio.height));
} else if (haveHeight && !haveWidth && result.mRatio) {
nscoord intrinsicWidth = result.mRatio.ApplyTo(imageIntSize.height);
result.SetWidth(nsPresContext::CSSPixelsToAppUnits(intrinsicWidth));
}
@ -317,9 +310,7 @@ nsSize nsImageRenderer::ComputeConcreteSize(
if (aSpecifiedSize.mHasWidth) {
nscoord height;
if (aIntrinsicSize.HasRatio()) {
height = NSCoordSaturatingNonnegativeMultiply(
aSpecifiedSize.mWidth,
double(aIntrinsicSize.mRatio.height) / aIntrinsicSize.mRatio.width);
height = aIntrinsicSize.mRatio.Inverted().ApplyTo(aSpecifiedSize.mWidth);
} else if (aIntrinsicSize.mHasHeight) {
height = aIntrinsicSize.mHeight;
} else {
@ -331,9 +322,7 @@ nsSize nsImageRenderer::ComputeConcreteSize(
MOZ_ASSERT(aSpecifiedSize.mHasHeight);
nscoord width;
if (aIntrinsicSize.HasRatio()) {
width = NSCoordSaturatingNonnegativeMultiply(
aSpecifiedSize.mHeight,
double(aIntrinsicSize.mRatio.width) / aIntrinsicSize.mRatio.height);
width = aIntrinsicSize.mRatio.ApplyTo(aSpecifiedSize.mHeight);
} else if (aIntrinsicSize.mHasWidth) {
width = aIntrinsicSize.mWidth;
} else {
@ -343,20 +332,19 @@ nsSize nsImageRenderer::ComputeConcreteSize(
}
/* static */
nsSize nsImageRenderer::ComputeConstrainedSize(const nsSize& aConstrainingSize,
const nsSize& aIntrinsicRatio,
FitType aFitType) {
if (aIntrinsicRatio.width <= 0 && aIntrinsicRatio.height <= 0) {
nsSize nsImageRenderer::ComputeConstrainedSize(
const nsSize& aConstrainingSize, const AspectRatio& aIntrinsicRatio,
FitType aFitType) {
if (!aIntrinsicRatio) {
return aConstrainingSize;
}
float scaleX = double(aConstrainingSize.width) / aIntrinsicRatio.width;
float scaleY = double(aConstrainingSize.height) / aIntrinsicRatio.height;
auto constrainingRatio =
AspectRatio::FromSize(aConstrainingSize.width, aConstrainingSize.height);
nsSize size;
if ((aFitType == CONTAIN) == (scaleX < scaleY)) {
if ((aFitType == CONTAIN) == (constrainingRatio < aIntrinsicRatio)) {
size.width = aConstrainingSize.width;
size.height =
NSCoordSaturatingNonnegativeMultiply(aIntrinsicRatio.height, scaleX);
size.height = aIntrinsicRatio.Inverted().ApplyTo(aConstrainingSize.width);
// If we're reducing the size by less than one css pixel, then just use the
// constraining size.
if (aFitType == CONTAIN &&
@ -364,13 +352,12 @@ nsSize nsImageRenderer::ComputeConstrainedSize(const nsSize& aConstrainingSize,
size.height = aConstrainingSize.height;
}
} else {
size.width =
NSCoordSaturatingNonnegativeMultiply(aIntrinsicRatio.width, scaleY);
size.height = aConstrainingSize.height;
size.width = aIntrinsicRatio.ApplyTo(aConstrainingSize.height);
if (aFitType == CONTAIN &&
aConstrainingSize.width - size.width < AppUnitsPerCSSPixel()) {
size.width = aConstrainingSize.width;
}
size.height = aConstrainingSize.height;
}
return size;
}

Просмотреть файл

@ -10,6 +10,7 @@
#include "nsLayoutUtils.h"
#include "nsStyleStruct.h"
#include "Units.h"
#include "mozilla/AspectRatio.h"
class gfxDrawable;
namespace mozilla {
@ -31,20 +32,16 @@ class IpcResourceUpdateQueue;
// of these then we can compute a concrete size, that is a width and height.
struct CSSSizeOrRatio {
CSSSizeOrRatio()
: mRatio(0, 0),
mWidth(0),
mHeight(0),
mHasWidth(false),
mHasHeight(false) {}
: mWidth(0), mHeight(0), mHasWidth(false), mHasHeight(false) {}
bool CanComputeConcreteSize() const {
return mHasWidth + mHasHeight + HasRatio() >= 2;
}
bool IsConcrete() const { return mHasWidth && mHasHeight; }
bool HasRatio() const { return mRatio.width > 0 && mRatio.height > 0; }
bool HasRatio() const { return !!mRatio; }
bool IsEmpty() const {
return (mHasWidth && mWidth <= 0) || (mHasHeight && mHeight <= 0) ||
mRatio.width <= 0 || mRatio.height <= 0;
!mRatio;
}
// CanComputeConcreteSize must return true when ComputeConcreteSize is
@ -55,14 +52,14 @@ struct CSSSizeOrRatio {
mWidth = aWidth;
mHasWidth = true;
if (mHasHeight) {
mRatio = nsSize(mWidth, mHeight);
mRatio = AspectRatio::FromSize(mWidth, mHeight);
}
}
void SetHeight(nscoord aHeight) {
mHeight = aHeight;
mHasHeight = true;
if (mHasWidth) {
mRatio = nsSize(mWidth, mHeight);
mRatio = AspectRatio::FromSize(mWidth, mHeight);
}
}
void SetSize(const nsSize& aSize) {
@ -70,16 +67,16 @@ struct CSSSizeOrRatio {
mHeight = aSize.height;
mHasWidth = true;
mHasHeight = true;
mRatio = aSize;
mRatio = AspectRatio::FromSize(mWidth, mHeight);
}
void SetRatio(const nsSize& aRatio) {
void SetRatio(const AspectRatio& aRatio) {
MOZ_ASSERT(
!mHasWidth || !mHasHeight,
"Probably shouldn't be setting a ratio if we have a concrete size");
mRatio = aRatio;
}
nsSize mRatio;
AspectRatio mRatio;
nscoord mWidth;
nscoord mHeight;
bool mHasWidth;
@ -156,12 +153,10 @@ class nsImageRenderer {
/**
* Compute the size of the rendered image using either the 'cover' or
* 'contain' constraints (aFitType).
* aIntrinsicRatio may be an invalid ratio, that is one or both of its
* dimensions can be less than or equal to zero.
*/
static nsSize ComputeConstrainedSize(const nsSize& aConstrainingSize,
const nsSize& aIntrinsicRatio,
FitType aFitType);
static nsSize ComputeConstrainedSize(
const nsSize& aConstrainingSize,
const mozilla::AspectRatio& aIntrinsicRatio, FitType aFitType);
/**
* Compute the size of the rendered image (the concrete size) where no cover/
* contain constraints are given. The 'default algorithm' from the CSS Image

Просмотреть файл

@ -2662,7 +2662,7 @@ static bool SizeDependsOnPositioningAreaSize(const StyleBackgroundSize& aSize,
}
if (imgContainer) {
CSSIntSize imageSize;
nsSize imageRatio;
AspectRatio imageRatio;
bool hasWidth, hasHeight;
nsLayoutUtils::ComputeSizeForDrawing(imgContainer, imageSize, imageRatio,
hasWidth, hasHeight);
@ -2675,7 +2675,7 @@ static bool SizeDependsOnPositioningAreaSize(const StyleBackgroundSize& aSize,
// If the image has an intrinsic ratio, rendering will depend on frame
// size when background-size is all auto.
if (imageRatio != nsSize(0, 0)) {
if (imageRatio) {
return size.width.IsAuto() == size.height.IsAuto();
}

Просмотреть файл

@ -234,9 +234,9 @@ IntrinsicSize nsSVGOuterSVGFrame::GetIntrinsicSize() {
}
/* virtual */
nsSize nsSVGOuterSVGFrame::GetIntrinsicRatio() {
AspectRatio nsSVGOuterSVGFrame::GetIntrinsicRatio() {
if (StyleDisplay()->IsContainSize()) {
return nsSize(0, 0);
return AspectRatio();
}
// We only have an intrinsic size/ratio if our width and height attributes
@ -253,16 +253,8 @@ nsSize nsSVGOuterSVGFrame::GetIntrinsicRatio() {
content->mLengthAttributes[SVGSVGElement::ATTR_HEIGHT];
if (!width.IsPercentage() && !height.IsPercentage()) {
nsSize ratio(
nsPresContext::CSSPixelsToAppUnits(width.GetAnimValue(content)),
nsPresContext::CSSPixelsToAppUnits(height.GetAnimValue(content)));
if (ratio.width < 0) {
ratio.width = 0;
}
if (ratio.height < 0) {
ratio.height = 0;
}
return ratio;
return AspectRatio::FromSize(width.GetAnimValue(content),
height.GetAnimValue(content));
}
SVGViewElement* viewElement = content->GetCurrentViewElement();
@ -276,17 +268,7 @@ nsSize nsSVGOuterSVGFrame::GetIntrinsicRatio() {
}
if (viewbox) {
float viewBoxWidth = viewbox->width;
float viewBoxHeight = viewbox->height;
if (viewBoxWidth < 0.0f) {
viewBoxWidth = 0.0f;
}
if (viewBoxHeight < 0.0f) {
viewBoxHeight = 0.0f;
}
return nsSize(nsPresContext::CSSPixelsToAppUnits(viewBoxWidth),
nsPresContext::CSSPixelsToAppUnits(viewBoxHeight));
return AspectRatio::FromSize(viewbox->width, viewbox->height);
}
return nsSVGDisplayContainerFrame::GetIntrinsicRatio();

Просмотреть файл

@ -50,7 +50,7 @@ class nsSVGOuterSVGFrame final : public nsSVGDisplayContainerFrame,
virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override;
virtual mozilla::IntrinsicSize GetIntrinsicSize() override;
virtual nsSize GetIntrinsicRatio() override;
virtual mozilla::AspectRatio GetIntrinsicRatio() override;
virtual mozilla::LogicalSize ComputeSize(
gfxContext* aRenderingContext, mozilla::WritingMode aWritingMode,

Просмотреть файл

@ -470,16 +470,17 @@ nsRect nsImageBoxFrame::GetDestRect(const nsPoint& aOffset,
// Determine dest rect based on intrinsic size & ratio, along with
// 'object-fit' & 'object-position' properties:
IntrinsicSize intrinsicSize;
nsSize intrinsicRatio;
AspectRatio intrinsicRatio;
if (mIntrinsicSize.width > 0 && mIntrinsicSize.height > 0) {
// Image has a valid size; use it as intrinsic size & ratio.
intrinsicSize =
IntrinsicSize(mIntrinsicSize.width, mIntrinsicSize.height);
intrinsicRatio = mIntrinsicSize;
intrinsicRatio =
AspectRatio::FromSize(mIntrinsicSize.width, mIntrinsicSize.height);
} else {
// Image doesn't have a (valid) intrinsic size.
// Try to look up intrinsic ratio and use that at least.
imgCon->GetIntrinsicRatio(&intrinsicRatio);
intrinsicRatio = imgCon->GetIntrinsicRatio().valueOr(AspectRatio());
}
aAnchorPoint.emplace();
dest = nsLayoutUtils::ComputeObjectDestRect(clientRect, intrinsicSize,