static inline IntSize resolveAgainstIntrinsicRatio(const IntSize& size, const FloatSize& intrinsicRatio) { // Two possible solutions: (size.width(), solutionHeight) or (solutionWidth, size.height()) // "... must be assumed to be the largest dimensions..." = easiest answer: the rect with the largest surface area. int solutionWidth = resolveWidthForRatio(size.height(), intrinsicRatio); int solutionHeight = resolveHeightForRatio(size.width(), intrinsicRatio); if (solutionWidth <= size.width()) { if (solutionHeight <= size.height()) { // If both solutions fit, choose the one covering the larger area. int areaOne = solutionWidth * size.height(); int areaTwo = size.width() * solutionHeight; if (areaOne < areaTwo) return IntSize(size.width(), solutionHeight); return IntSize(solutionWidth, size.height()); } // Only the first solution fits. return IntSize(solutionWidth, size.height()); } // Only the second solution fits, assert that. ASSERT(solutionHeight <= size.height()); return IntSize(size.width(), solutionHeight); }
static inline IntSize resolveAgainstIntrinsicWidthOrHeightAndRatio(const IntSize& size, const FloatSize& intrinsicRatio, int useWidth, int useHeight) { if (intrinsicRatio.isEmpty()) { if (useWidth) return IntSize(useWidth, size.height()); return IntSize(size.width(), useHeight); } if (useWidth) return IntSize(useWidth, resolveHeightForRatio(useWidth, intrinsicRatio)); return IntSize(resolveWidthForRatio(useHeight, intrinsicRatio), useHeight); }
FloatSize LayoutSVGImage::calculateObjectSize() const { ImageResourceContent* cachedImage = m_imageResource->cachedImage(); if (!cachedImage || cachedImage->errorOccurred()) return m_objectBoundingBox.size(); FloatSize intrinsicSize = FloatSize(cachedImage->getImage()->size()); if (styleRef().width().isAuto() && styleRef().height().isAuto()) return intrinsicSize; if (styleRef().height().isAuto()) return FloatSize( m_objectBoundingBox.width(), resolveHeightForRatio(m_objectBoundingBox.width(), intrinsicSize)); DCHECK(styleRef().width().isAuto()); return FloatSize( resolveWidthForRatio(m_objectBoundingBox.height(), intrinsicSize), m_objectBoundingBox.height()); }
LayoutUnit LayoutReplaced::computeReplacedLogicalWidth( ShouldComputePreferred shouldComputePreferred) const { if (style()->logicalWidth().isSpecified() || style()->logicalWidth().isIntrinsic()) return computeReplacedLogicalWidthRespectingMinMaxWidth( computeReplacedLogicalWidthUsing(MainOrPreferredSize, style()->logicalWidth()), shouldComputePreferred); LayoutReplaced* contentLayoutObject = embeddedReplacedContent(); // 10.3.2 Inline, replaced elements: // http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-width IntrinsicSizingInfo intrinsicSizingInfo; computeIntrinsicSizingInfoForReplacedContent(contentLayoutObject, intrinsicSizingInfo); FloatSize constrainedSize = constrainIntrinsicSizeToMinMax(intrinsicSizingInfo); if (style()->logicalWidth().isAuto()) { bool computedHeightIsAuto = style()->logicalHeight().isAuto(); // If 'height' and 'width' both have computed values of 'auto' and the // element also has an intrinsic width, then that intrinsic width is the // used value of 'width'. if (computedHeightIsAuto && intrinsicSizingInfo.hasWidth) return computeReplacedLogicalWidthRespectingMinMaxWidth( LayoutUnit(constrainedSize.width()), shouldComputePreferred); if (!intrinsicSizingInfo.aspectRatio.isEmpty()) { // If 'height' and 'width' both have computed values of 'auto' and the // element has no intrinsic width, but does have an intrinsic height and // intrinsic ratio; or if 'width' has a computed value of 'auto', 'height' // has some other computed value, and the element does have an intrinsic // ratio; then the used value of 'width' is: (used height) * (intrinsic // ratio). if ((computedHeightIsAuto && !intrinsicSizingInfo.hasWidth && intrinsicSizingInfo.hasHeight) || !computedHeightIsAuto) { LayoutUnit estimatedUsedWidth = intrinsicSizingInfo.hasWidth ? LayoutUnit(constrainedSize.width()) : computeConstrainedLogicalWidth(shouldComputePreferred); LayoutUnit logicalHeight = computeReplacedLogicalHeight(estimatedUsedWidth); return computeReplacedLogicalWidthRespectingMinMaxWidth( resolveWidthForRatio(logicalHeight, intrinsicSizingInfo.aspectRatio), shouldComputePreferred); } // If 'height' and 'width' both have computed values of 'auto' and the // element has an intrinsic ratio but no intrinsic height or width, then // the used value of 'width' is undefined in CSS 2.1. However, it is // suggested that, if the containing block's width does not itself depend // on the replaced element's width, then the used value of 'width' is // calculated from the constraint equation used for block-level, // non-replaced elements in normal flow. if (computedHeightIsAuto && !intrinsicSizingInfo.hasWidth && !intrinsicSizingInfo.hasHeight) return computeConstrainedLogicalWidth(shouldComputePreferred); } // Otherwise, if 'width' has a computed value of 'auto', and the element has // an intrinsic width, then that intrinsic width is the used value of // 'width'. if (intrinsicSizingInfo.hasWidth) return computeReplacedLogicalWidthRespectingMinMaxWidth( LayoutUnit(constrainedSize.width()), shouldComputePreferred); // 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. // Note: We fall through and instead return intrinsicLogicalWidth() here - // to preserve existing WebKit behavior, which might or might not be // correct, or desired. // Changing this to return cDefaultWidth, will affect lots of test results. // Eg. some tests assume that a blank <img> tag (which implies // width/height=auto) has no intrinsic size, which is wrong per CSS 2.1, but // matches our behavior since a long time. } return computeReplacedLogicalWidthRespectingMinMaxWidth( intrinsicLogicalWidth(), shouldComputePreferred); }