Ignore:
Timestamp:
Aug 29, 2013, 5:23:23 PM (12 years ago)
Author:
Simon Fraser
Message:

Implement object-fit CSS property
https://bugs.webkit.org/show_bug.cgi?id=52040

Source/WebCore:

Reviewed by Antti Koivisto, Sam Weinig.

Merge object-fit patch from Blink r156535, which started as a patch
by me.

Since then, the spec has gone to CR. This patch is an
implementation of object-fit as described in
http://www.w3.org/TR/2012/CR-css3-images-20120417/#object-fit

Object-fit is used to maintain the aspect ratio of replaced content
within its content box. All object-fit values but the initial one
('fill') will always ensure that the aspect ratio is retained, in
different ways (fit inside the content box, cover the content box, or
use intrinsic size). Painting is always clipped against the content
box, regardless of the 'overflow' property.

Tests: fast/css/object-fit/object-fit-canvas.html

fast/css/object-fit/object-fit-embed.html
fast/css/object-fit/object-fit-grow-landscape.html
fast/css/object-fit/object-fit-grow-portrait.html
fast/css/object-fit/object-fit-img-svg.html
fast/css/object-fit/object-fit-img-svg2.html
fast/css/object-fit/object-fit-img.html
fast/css/object-fit/object-fit-input-image.html
fast/css/object-fit/object-fit-object.html
fast/css/object-fit/object-fit-shrink.html
fast/css/object-fit/object-fit-video-poster.html
fast/css/parsing-object-fit.html
http/tests/css/object-fit-delayed-img-svg.html
media/video-object-fit-change.html
media/video-object-fit.html

  • css/CSSComputedStyleDeclaration.cpp:

(WebCore::ComputedStyleExtractor::propertyValue):

  • css/CSSParser.cpp:

(WebCore::isValidKeywordPropertyAndValue):
(WebCore::isKeywordPropertyID):
(WebCore::CSSParser::parseValue):

  • css/CSSPrimitiveValueMappings.h:

(WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
(WebCore::CSSPrimitiveValue::operator EObjectFit):

  • css/CSSProperty.cpp:

(WebCore::CSSProperty::isInheritedProperty):

  • css/CSSPropertyNames.in:
  • css/CSSValueKeywords.in:
  • css/DeprecatedStyleBuilder.cpp:

(WebCore::DeprecatedStyleBuilder::DeprecatedStyleBuilder):

  • css/StyleResolver.cpp:

(WebCore::StyleResolver::applyProperty):

  • css/html.css:

(video): Set object-fit to 'contain'. This is how VIDEO elements
work, apparently.

  • loader/cache/CachedImage.cpp:

(WebCore::CachedImage::imageSizeForRenderer):

  • loader/cache/CachedImage.h:
  • platform/graphics/LayoutSize.h:

(WebCore::fitLayoutSizeToAspectRatio): New function to grow or shrink
in one dimension to fit to the aspect ratio.

  • rendering/RenderHTMLCanvas.cpp:

(WebCore::RenderHTMLCanvas::paintReplaced): Apply object-fit and
clip if necessary.

  • rendering/RenderImage.cpp:

(WebCore::RenderImage::updateInnerContentRect):
(WebCore::RenderImage::imageDimensionsChanged): Update intrinsic
size properly, and recalculate the inner content rectangle (the
exact area occupied by the replaced content) again if appropriate.
(WebCore::RenderImage::paintReplaced): Apply object-fit and clip
if necessary.
(WebCore::RenderImage::foregroundIsKnownToBeOpaqueInRect):
object-fit may leave parts of the content box empty, in which case
it won't be fully obscured.
(WebCore::RenderImage::layout):

  • rendering/RenderImage.h:
  • rendering/RenderImageResource.cpp:

(WebCore::RenderImageResource::intrinsicSize): Need this to
differentiate between intrinsic and extrinsic size for SVG images.

  • rendering/RenderImageResource.h:
  • rendering/RenderImageResourceStyleImage.h:
  • rendering/RenderReplaced.cpp:

(WebCore::RenderReplaced::replacedContentRect): Return the
rectangle occupied by the replaced content. This will be identical
to the content box if object-fit is 'fill', but will typically be
something else for other values.

  • rendering/RenderReplaced.h:
  • rendering/RenderVideo.cpp:

(WebCore::RenderVideo::videoBox): Not much left to do here, with
the new RenderReplaced::replacedContentRect() method in place.
(WebCore::RenderVideo::paintReplaced): Apply object-fit and clip
if necessary.

  • rendering/style/RenderStyle.cpp:

(WebCore::RenderStyle::changeRequiresRepaint):

  • rendering/style/RenderStyle.h:
  • rendering/style/RenderStyleConstants.h:
  • rendering/style/StyleRareNonInheritedData.cpp:

(WebCore::StyleRareNonInheritedData::StyleRareNonInheritedData):
(WebCore::StyleRareNonInheritedData::operator==):

  • rendering/style/StyleRareNonInheritedData.h:

LayoutTests:

Reviewed by Antti Koivisto, Sam Weinig.

Tests for object-fit.

  • fast/css/object-fit/object-fit-canvas-expected.html: Added.
  • fast/css/object-fit/object-fit-canvas.html: Added.
  • fast/css/object-fit/object-fit-embed-expected.html: Added.
  • fast/css/object-fit/object-fit-embed.html: Added.
  • fast/css/object-fit/object-fit-grow-landscape-expected.html: Added.
  • fast/css/object-fit/object-fit-grow-landscape.html: Added.
  • fast/css/object-fit/object-fit-grow-portrait-expected.html: Added.
  • fast/css/object-fit/object-fit-grow-portrait.html: Added.
  • fast/css/object-fit/object-fit-img-expected.html: Added.
  • fast/css/object-fit/object-fit-img-svg-expected.html: Added.
  • fast/css/object-fit/object-fit-img-svg.html: Added.
  • fast/css/object-fit/object-fit-img-svg2-expected.html: Added.
  • fast/css/object-fit/object-fit-img-svg2.html: Added.
  • fast/css/object-fit/object-fit-img.html: Added.
  • fast/css/object-fit/object-fit-input-image-expected.html: Added.
  • fast/css/object-fit/object-fit-input-image.html: Added.
  • fast/css/object-fit/object-fit-object-expected.html: Added.
  • fast/css/object-fit/object-fit-object.html: Added.
  • fast/css/object-fit/object-fit-shrink-expected.html: Added.
  • fast/css/object-fit/object-fit-shrink.html: Added.
  • fast/css/object-fit/object-fit-video-poster-expected.html: Added.
  • fast/css/object-fit/object-fit-video-poster.html: Added.
  • fast/css/parsing-object-fit-expected.txt: Added.
  • fast/css/parsing-object-fit.html: Added.
  • fast/css/resources/circle.svg: Added.
  • fast/css/resources/circle2.svg: Added.
  • fast/css/resources/circles-landscape-small.png: Added.
  • fast/css/resources/circles-landscape.png: Added.
  • fast/css/resources/circles-portrait-small.png: Added.
  • fast/css/resources/circles-portrait.png: Added.
  • http/tests/css/object-fit-delayed-img-svg-expected.html: Added.
  • http/tests/css/object-fit-delayed-img-svg.html: Added.
  • media/video-object-fit-change-expected.html: Added.
  • media/video-object-fit-change.html: Added.
  • media/video-object-fit-expected.html: Added.
  • media/video-object-fit.html: Added.
  • platform/mac/TestExpectations:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/rendering/RenderReplaced.cpp

    r154580 r154858  
    299299}
    300300
     301LayoutRect RenderReplaced::replacedContentRect(const LayoutSize& intrinsicSize) const
     302{
     303    LayoutRect contentRect = contentBoxRect();
     304    ObjectFit objectFit = style()->objectFit();
     305    if (objectFit == ObjectFitFill)
     306        return contentRect;
     307
     308    if (!intrinsicSize.width() || !intrinsicSize.height())
     309        return contentRect;
     310
     311    LayoutRect finalRect = contentRect;
     312    switch (objectFit) {
     313    case ObjectFitContain:
     314    case ObjectFitScaleDown:
     315    case ObjectFitCover:
     316        finalRect.setSize(finalRect.size().fitToAspectRatio(intrinsicSize, objectFit == ObjectFitCover ? AspectRatioFitGrow : AspectRatioFitShrink));
     317        if (objectFit != ObjectFitScaleDown || finalRect.width() <= intrinsicSize.width())
     318            break;
     319        // fall through
     320    case ObjectFitNone:
     321        finalRect.setSize(intrinsicSize);
     322        break;
     323    case ObjectFitFill:
     324        ASSERT_NOT_REACHED();
     325    }
     326
     327    // FIXME: This is where object-position should be taken into account, but since it's not
     328    // implemented yet, assume the initial value of "50% 50%".
     329    LayoutUnit xOffset = (contentRect.width() - finalRect.width()) / 2;
     330    LayoutUnit yOffset = (contentRect.height() - finalRect.height()) / 2;
     331    finalRect.move(xOffset, yOffset);
     332
     333    return finalRect;
     334}
     335
    301336void RenderReplaced::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
    302337{
Note: See TracChangeset for help on using the changeset viewer.