Changeset 251081 in webkit


Ignore:
Timestamp:
Oct 14, 2019 10:23:14 AM (5 years ago)
Author:
Nikolas Zimmermann
Message:

transform-box: content-box, stroke-box missing
https://bugs.webkit.org/show_bug.cgi?id=201892

Patch by Dirk Schulze <krit@webkit.org> on 2019-10-14
Reviewed by Simon Fraser.

Source/WebCore:

Added the keywords content-box and stroke-box to the
transform-box CSS property.
Those keywords were added to the spec after the implementation
in WebKit.

Test: transforms/transform-box.html

  • css/CSSPrimitiveValueMappings.h:

(WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
(WebCore::CSSPrimitiveValue::operator TransformBox const):

  • css/CSSProperties.json:
  • css/CSSValueKeywords.in:
  • css/parser/CSSPropertyParser.cpp:

(WebCore::CSSPropertyParser::parseSingleValue):

  • rendering/RenderLayer.cpp:

(WebCore::computeReferenceBox):
(WebCore::transformBoxToCSSBoxType):
(WebCore::RenderLayer::currentTransform const):

  • rendering/style/RenderStyleConstants.h:
  • svg/SVGGraphicsElement.cpp:

(WebCore::SVGGraphicsElement::animatedLocalTransform const):

LayoutTests:

  • fast/css/transform-box-parsing.html:
  • svg/transforms/svg-transform-box-expected.html:
  • svg/transforms/svg-transform-box.html:
  • transforms/transform-box-expected.html: Added.
  • transforms/transform-box.html: Added.
Location:
trunk
Files:
2 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r251070 r251081  
     12019-10-14  Dirk Schulze  <krit@webkit.org>
     2
     3        transform-box: content-box, stroke-box missing
     4        https://bugs.webkit.org/show_bug.cgi?id=201892
     5
     6        Reviewed by Simon Fraser.
     7
     8        * fast/css/transform-box-parsing.html:
     9        * svg/transforms/svg-transform-box-expected.html:
     10        * svg/transforms/svg-transform-box.html:
     11        * transforms/transform-box-expected.html: Added.
     12        * transforms/transform-box.html: Added.
     13
    1142019-10-14  Rob Buis  <rbuis@igalia.com>
    215
  • trunk/LayoutTests/fast/css/transform-box-parsing-expected.txt

    r217236 r251081  
    77PASS testPropertyValue("transform-box: fill-box", "transform-box") is "fill-box"
    88PASS testPropertyValue("transform-box: view-box", "transform-box") is "view-box"
     9PASS testPropertyValue("transform-box: content-box", "transform-box") is "content-box"
     10PASS testPropertyValue("transform-box: stroke-box", "transform-box") is "stroke-box"
    911
    1012PASS testComputedStyle("", "transform-box") is "border-box"
    1113PASS testComputedStyle("transform-box: fill-box", "transform-box") is "fill-box"
    1214PASS testComputedStyle("transform-box: view-box", "transform-box") is "view-box"
     15PASS testComputedStyle("transform-box: content-box", "transform-box") is "content-box"
     16PASS testComputedStyle("transform-box: stroke-box", "transform-box") is "stroke-box"
    1317
    1418PASS testSVGComputedStyle("", "transform-box") is "view-box"
    1519PASS testSVGComputedStyle("transform-box: fill-box", "transform-box") is "fill-box"
    1620PASS testSVGComputedStyle("transform-box: border-box", "transform-box") is "border-box"
     21PASS testSVGComputedStyle("transform-box: content-box", "transform-box") is "content-box"
     22PASS testSVGComputedStyle("transform-box: stroke-box", "transform-box") is "stroke-box"
    1723
    1824PASS testComputedStyleOnElementWithId("foreignObject") is "view-box"
  • trunk/LayoutTests/fast/css/transform-box-parsing.html

    r217236 r251081  
    6363        shouldBeEqualToString('testPropertyValue("transform-box: fill-box", "transform-box")', 'fill-box');
    6464        shouldBeEqualToString('testPropertyValue("transform-box: view-box", "transform-box")', 'view-box');
     65        shouldBeEqualToString('testPropertyValue("transform-box: content-box", "transform-box")', 'content-box');
     66        shouldBeEqualToString('testPropertyValue("transform-box: stroke-box", "transform-box")', 'stroke-box');
    6567
    6668        debug('');
     
    6870        shouldBeEqualToString('testComputedStyle("transform-box: fill-box", "transform-box")', 'fill-box');
    6971        shouldBeEqualToString('testComputedStyle("transform-box: view-box", "transform-box")', 'view-box');
     72        shouldBeEqualToString('testComputedStyle("transform-box: content-box", "transform-box")', 'content-box');
     73        shouldBeEqualToString('testComputedStyle("transform-box: stroke-box", "transform-box")', 'stroke-box');
    7074
    7175        debug('');
     
    7377        shouldBeEqualToString('testSVGComputedStyle("transform-box: fill-box", "transform-box")', 'fill-box');
    7478        shouldBeEqualToString('testSVGComputedStyle("transform-box: border-box", "transform-box")', 'border-box');
     79        shouldBeEqualToString('testSVGComputedStyle("transform-box: content-box", "transform-box")', 'content-box');
     80        shouldBeEqualToString('testSVGComputedStyle("transform-box: stroke-box", "transform-box")', 'stroke-box');
    7581
    7682        debug('');
  • trunk/LayoutTests/svg/transforms/svg-transform-box-expected.html

    r217236 r251081  
    11<!DOCTYPE html>
    2 
    32<html>
    43<head>
    54  <style>
    6     svg {
    7         border: 1px solid black;
     5    * {
     6      margin: 0;
     7      padding: 0;
    88    }
    99  </style>
    1010</head>
    11 
    1211<body>
    13 
    14     <div class="container">
    15         <p>You should see no red boxes below</p>
    16         <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 600 400" style=" width: 600px; height: 400px;">
    17             <!-- transform-box: view-box -->
    18             <rect x="20" y="10" width="100" height="50" fill="green" />
    19             <rect x="480" y="40" width="50" height="50" fill="green" />
    20             <rect x="120" y="120" width="50" height="50" fill="green" />
    21             <rect x="20" y="200" width="100" height="50" fill="green" />
    22             <rect x="480" y="260" width="50" height="50" fill="green" />
    23             <rect x="120" y="320" width="50" height="50" fill="green" />
    24         </svg>
    25     </div>
    26 
     12  <p>You should see no red boxes below</p>
     13  <svg width="600" height="300" viewBox="0 0 600 300">
     14    <rect width="120" height="60" fill="green" />
     15    <rect x="150" y="0" width="120" height="60" fill="green" />
     16    <rect x="300" y="0" width="120" height="60" fill="green" />
     17    <rect y="90" width="120" height="60" fill="green" />
     18    <rect x="150" y="90" width="120" height="60" fill="green" />
     19  </svg>
    2720</body>
    2821</html>
  • trunk/LayoutTests/svg/transforms/svg-transform-box.html

    r217236 r251081  
    11<!DOCTYPE html>
    2 
    32<html>
    43<head>
    54  <style>
    6     svg {
    7         border: 1px solid black;
     5    * {
     6      margin: 0;
     7      padding: 0;
    88    }
    99  </style>
    1010</head>
    11 
    1211<body>
    13 
    14     <div class="container">
    15         <p>You should see no red boxes below</p>
    16         <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 600 400" style=" width: 600px; height: 400px;">
    17             <!-- transform-box: view-box -->
    18             <rect x="20" y="10" width="100" height="50" fill="red" />
    19             <rect x="20" y="5" width="50" height="25" fill="green" style="transform: scale(2, 2); transform-origin: 20px 0; transform-box: view-box;" />
    20 
    21             <rect x="480" y="40" width="50" height="50" fill="red" />
    22             <rect x="0" y="0" width="50" height="50" fill="green" style="transform: translate(80%, 10%); transform-box: view-box;" />
    23 
    24             <rect x="120" y="120" width="50" height="50" fill="red" />
    25             <rect x="180" y="10" width="50" height="50" fill="green" style="transform: rotate(90deg); transform-origin: 120px 60px; transform-box: view-box;" />
    26             <rect x="180" y="10" width="50" height="50" fill="green" style="transform: rotate(90deg); transform-origin: 20% 15%; transform-box: view-box;" />
    27 
    28             <!-- transform-box: fill-box -->
    29             <rect x="20" y="200" width="100" height="50" fill="red" />
    30             <rect x="20" y="200" width="50" height="25" fill="green" style="transform: scale(2, 2); transform-box: fill-box;" />
    31 
    32             <rect x="480" y="260" width="50" height="50" fill="red" />
    33             <rect x="430" y="310" width="50" height="50" fill="green" style="transform: translate(100%, -100%); transform-box: fill-box;" />
    34 
    35             <rect x="120" y="320" width="50" height="50" fill="red" />
    36             <rect x="70" y="270" width="50" height="50" fill="green" style="transform: rotate(180deg); transform-origin: 50px 50px; transform-box: fill-box;" />
    37             <rect x="95" y="345" width="50" height="50" fill="green" style="transform: rotate(90deg); transform-origin: 100% 50%; transform-box: fill-box;" />
    38         </svg>
    39     </div>
    40 
     12  <p>You should see no red boxes below</p>
     13  <svg width="600" height="300" viewBox="0 0 600 300">
     14    <g style="transform: translate(20px, 20px)">
     15        <!-- transform-box: border-box -->
     16        <rect x="-19" y="-19" width="118" height="58" fill="red" />
     17        <rect style="transform-box: border-box; transform: rotate(90deg) scale(1, 2) translate(30px, -75%); transform-origin: 50% 0;" width="20" height="20" stroke="green" stroke-width="40" fill="green" />
     18      </g>
     19      <g style="transform: translate(160px, 10px)">
     20        <!-- transform-box: view-box -->
     21        <rect x="-9" y="-9" width="118" height="58" fill="red" />
     22        <rect style="transform-box: view-box; transform: rotate(90deg) scale(1,2) translate(310px, calc(50% - 35px)); transform-origin: 50% 0;" width="20" height="20" stroke="green" stroke-width="40" fill="green" />
     23      </g>
     24      <g style="transform: translate(320px, 20px)">
     25        <!-- transform-box: stroke-box -->
     26        <rect x="-19" y="-19" width="118" height="58" fill="red" />
     27        <rect style="transform-box: stroke-box; transform: rotate(90deg) scale(1, 2) translate(30px, -75%); transform-origin: 50% 0;" width="20" height="20" stroke="green" stroke-width="40" fill="green" />
     28      </g>
     29      <g style="transform: translate(10px, 100px)">
     30        <!-- transform-box: content-box -->
     31        <rect x="-9" y="-9" width="118" height="58" fill="red" />
     32        <rect style="transform-box: content-box; transform: rotate(90deg) scale(1, 2) translate(20px, -87.5%); transform-origin: 50% 0;" width="40" height="40" stroke="green" stroke-width="20" fill="green" />
     33      </g>
     34      <g style="transform: translate(160px, 100px)">
     35        <!-- transform-box: fill-box -->
     36        <rect x="-9" y="-9" width="118" height="58" fill="red" />
     37        <rect style="transform-box: fill-box; transform: rotate(90deg) scale(1, 2) translate(20px, -87.5%); transform-origin: 50% 0;" width="40" height="40" stroke="green" stroke-width="20" fill="green" />
     38      </g>
     39  </svg>
    4140</body>
    4241</html>
  • trunk/Source/WebCore/ChangeLog

    r251074 r251081  
     12019-10-14  Dirk Schulze  <krit@webkit.org>
     2
     3        transform-box: content-box, stroke-box missing
     4        https://bugs.webkit.org/show_bug.cgi?id=201892
     5
     6        Reviewed by Simon Fraser.
     7
     8        Added the keywords content-box and stroke-box to the
     9        transform-box CSS property.
     10        Those keywords were added to the spec after the implementation
     11        in WebKit.
     12
     13        Test: transforms/transform-box.html
     14
     15        * css/CSSPrimitiveValueMappings.h:
     16        (WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
     17        (WebCore::CSSPrimitiveValue::operator TransformBox const):
     18        * css/CSSProperties.json:
     19        * css/CSSValueKeywords.in:
     20        * css/parser/CSSPropertyParser.cpp:
     21        (WebCore::CSSPropertyParser::parseSingleValue):
     22        * rendering/RenderLayer.cpp:
     23        (WebCore::computeReferenceBox):
     24        (WebCore::transformBoxToCSSBoxType):
     25        (WebCore::RenderLayer::currentTransform const):
     26        * rendering/style/RenderStyleConstants.h:
     27        * svg/SVGGraphicsElement.cpp:
     28        (WebCore::SVGGraphicsElement::animatedLocalTransform const):
     29
    1302019-10-14  Truitt Savell  <tsavell@apple.com>
    231
  • trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h

    r251055 r251081  
    43924392    m_primitiveUnitType = CSS_VALUE_ID;
    43934393    switch (box) {
     4394    case TransformBox::StrokeBox:
     4395        m_value.valueID = CSSValueStrokeBox;
     4396        break;
     4397    case TransformBox::ContentBox:
     4398        m_value.valueID = CSSValueContentBox;
     4399        break;
    43944400    case TransformBox::BorderBox:
    43954401        m_value.valueID = CSSValueBorderBox;
     
    44094415
    44104416    switch (m_value.valueID) {
     4417    case CSSValueStrokeBox:
     4418        return TransformBox::StrokeBox;
     4419    case CSSValueContentBox:
     4420        return TransformBox::ContentBox;
    44114421    case CSSValueBorderBox:
    44124422        return TransformBox::BorderBox;
  • trunk/Source/WebCore/css/CSSProperties.json

    r250849 r251081  
    63796379                "border-box",
    63806380                "fill-box",
    6381                 "view-box"
     6381                "view-box",
     6382                "stroke-box",
     6383                "content-box"
    63826384            ],
    63836385            "codegen-properties": {
  • trunk/Source/WebCore/css/CSSValueKeywords.in

    r246285 r251081  
    12981298// border-box
    12991299// view-box
     1300// stroke-box
     1301// content-box
    13001302fill-box
    13011303
  • trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp

    r251058 r251081  
    40554055        return consumeTransform(m_range, m_context.mode);
    40564056    case CSSPropertyTransformBox:
    4057         return consumeIdent<CSSValueBorderBox, CSSValueViewBox, CSSValueFillBox>(m_range);
     4057        return consumeIdent<CSSValueBorderBox, CSSValueViewBox, CSSValueFillBox, CSSValueStrokeBox, CSSValueContentBox>(m_range);
    40584058    case CSSPropertyTransformOriginX:
    40594059    case CSSPropertyPerspectiveOriginX:
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r251055 r251081  
    11/*
    22 * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
     3 * Copyright (C) 2019 Adobe. All rights reserved.
    34 *
    45 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
     
    12441245#endif
    12451246
     1247static inline LayoutRect computeReferenceRectFromBox(const RenderBox& box, const CSSBoxType& boxType, const LayoutSize& offsetFromRoot)
     1248{
     1249    LayoutRect referenceBox;
     1250    switch (boxType) {
     1251    case CSSBoxType::ContentBox:
     1252    case CSSBoxType::FillBox:
     1253        referenceBox = box.contentBoxRect();
     1254        referenceBox.move(offsetFromRoot);
     1255        break;
     1256    case CSSBoxType::PaddingBox:
     1257        referenceBox = box.paddingBoxRect();
     1258        referenceBox.move(offsetFromRoot);
     1259        break;
     1260    case CSSBoxType::MarginBox:
     1261        referenceBox = box.marginBoxRect();
     1262        referenceBox.move(offsetFromRoot);
     1263        break;
     1264    // stroke-box, view-box compute to border-box for HTML elements.
     1265    case CSSBoxType::StrokeBox:
     1266    case CSSBoxType::ViewBox:
     1267    case CSSBoxType::BorderBox:
     1268    case CSSBoxType::BoxMissing:
     1269        referenceBox = box.borderBoxRect();
     1270        referenceBox.move(offsetFromRoot);
     1271        break;
     1272    }
     1273
     1274    return referenceBox;
     1275}
     1276
     1277static inline LayoutRect computeReferenceBox(const RenderObject& renderer, const CSSBoxType& boxType, const LayoutSize& offsetFromRoot, const LayoutRect& rootRelativeBounds)
     1278{
     1279    // FIXME: Support different reference boxes for inline content.
     1280    // https://bugs.webkit.org/show_bug.cgi?id=129047
     1281    if (!renderer.isBox())
     1282        return rootRelativeBounds;
     1283   
     1284    return computeReferenceRectFromBox(downcast<RenderBox>(renderer), boxType, offsetFromRoot);
     1285}
     1286
     1287static inline CSSBoxType transformBoxToCSSBoxType(TransformBox transformBox)
     1288{
     1289    switch (transformBox) {
     1290    case TransformBox::StrokeBox:
     1291        return CSSBoxType::StrokeBox;
     1292    case TransformBox::ContentBox:
     1293        return CSSBoxType::ContentBox;
     1294    case TransformBox::BorderBox:
     1295        return CSSBoxType::BorderBox;
     1296    case TransformBox::FillBox:
     1297        return CSSBoxType::FillBox;
     1298    case TransformBox::ViewBox:
     1299        return CSSBoxType::ViewBox;
     1300    default:
     1301        ASSERT_NOT_REACHED();
     1302        return CSSBoxType::BorderBox;
     1303    }
     1304}
     1305
    12461306void RenderLayer::updateTransform()
    12471307{
     
    12641324        ASSERT(box);
    12651325        m_transform->makeIdentity();
    1266         box->style().applyTransform(*m_transform, snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor()), RenderStyle::IncludeTransformOrigin);
     1326        LayoutSize offsetFromRoot;
     1327        auto computedReferenceBox = computeReferenceRectFromBox(*box, transformBoxToCSSBoxType(box->style().transformBox()), offsetFromRoot);
     1328        box->style().applyTransform(*m_transform, snapRectToDevicePixels(computedReferenceBox, box->document().deviceScaleFactor()), RenderStyle::IncludeTransformOrigin);
    12671329        makeMatrixRenderable(*m_transform, canRender3DTransforms());
    12681330    }
     
    12861348            if (timeline->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform)) {
    12871349                TransformationMatrix currTransform;
    1288                 FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor());
     1350                LayoutSize offsetFromRoot;
    12891351                std::unique_ptr<RenderStyle> style = timeline->animatedStyleForRenderer(renderer());
     1352                auto computedReferenceBox = computeReferenceBox(renderer(), transformBoxToCSSBoxType(style->transformBox()), offsetFromRoot, box->borderBoxRect());
     1353                FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(computedReferenceBox, box->document().deviceScaleFactor());
    12901354                style->applyTransform(currTransform, pixelSnappedBorderRect, applyOrigin);
    12911355                makeMatrixRenderable(currTransform, canRender3DTransforms());
     
    12961360        if (renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform)) {
    12971361            TransformationMatrix currTransform;
    1298             FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor());
    12991362            std::unique_ptr<RenderStyle> style = renderer().animation().animatedStyleForRenderer(renderer());
     1363            LayoutSize offsetFromRoot;
     1364            auto computedReferenceBox = computeReferenceBox(renderer(), transformBoxToCSSBoxType(style->transformBox()), offsetFromRoot, box->borderBoxRect());
     1365            FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(computedReferenceBox, box->document().deviceScaleFactor());
    13001366            style->applyTransform(currTransform, pixelSnappedBorderRect, applyOrigin);
    13011367            makeMatrixRenderable(currTransform, canRender3DTransforms());
     
    13081374    if (applyOrigin == RenderStyle::ExcludeTransformOrigin) {
    13091375        TransformationMatrix currTransform;
    1310         FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor());
     1376        LayoutSize offsetFromRoot;
     1377        std::unique_ptr<RenderStyle> style = renderer().animation().animatedStyleForRenderer(renderer());
     1378        auto computedReferenceBox = computeReferenceBox(renderer(), transformBoxToCSSBoxType(style->transformBox()), offsetFromRoot, box->borderBoxRect());
     1379        FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(computedReferenceBox, box->document().deviceScaleFactor());
    13111380        box->style().applyTransform(currTransform, pixelSnappedBorderRect, RenderStyle::ExcludeTransformOrigin);
    13121381        makeMatrixRenderable(currTransform, canRender3DTransforms());
     
    42724341    }
    42734342    return false;
    4274 }
    4275 
    4276 static inline LayoutRect computeReferenceBox(const RenderObject& renderer, const CSSBoxType& boxType, const LayoutSize& offsetFromRoot, const LayoutRect& rootRelativeBounds)
    4277 {
    4278     // FIXME: Support different reference boxes for inline content.
    4279     // https://bugs.webkit.org/show_bug.cgi?id=129047
    4280     if (!renderer.isBox())
    4281         return rootRelativeBounds;
    4282 
    4283     LayoutRect referenceBox;
    4284     const auto& box = downcast<RenderBox>(renderer);
    4285     switch (boxType) {
    4286     case CSSBoxType::ContentBox:
    4287     case CSSBoxType::FillBox:
    4288         referenceBox = box.contentBoxRect();
    4289         referenceBox.move(offsetFromRoot);
    4290         break;
    4291     case CSSBoxType::PaddingBox:
    4292         referenceBox = box.paddingBoxRect();
    4293         referenceBox.move(offsetFromRoot);
    4294         break;
    4295     case CSSBoxType::MarginBox:
    4296         referenceBox = box.marginBoxRect();
    4297         referenceBox.move(offsetFromRoot);
    4298         break;
    4299     // stroke-box, view-box compute to border-box for HTML elements.
    4300     case CSSBoxType::StrokeBox:
    4301     case CSSBoxType::ViewBox:
    4302     case CSSBoxType::BorderBox:
    4303     case CSSBoxType::BoxMissing:
    4304         referenceBox = box.borderBoxRect();
    4305         referenceBox.move(offsetFromRoot);
    4306         break;
    4307     }
    4308 
    4309     return referenceBox;
    43104343}
    43114344
  • trunk/Source/WebCore/rendering/style/RenderStyleConstants.h

    r251055 r251081  
    916916
    917917enum class TransformBox : uint8_t {
     918    StrokeBox,
     919    ContentBox,
    918920    BorderBox,
    919921    FillBox,
  • trunk/Source/WebCore/svg/SVGGraphicsElement.cpp

    r248846 r251081  
    8181        FloatRect boundingBox;
    8282        switch (style->transformBox()) {
     83        case TransformBox::BorderBox:
     84            // For SVG elements without an associated CSS layout box, the used value for border-box is stroke-box.
     85        case TransformBox::StrokeBox:
     86            boundingBox = renderer()->strokeBoundingBox();
     87            break;
     88        case TransformBox::ContentBox:
     89            // For SVG elements without an associated CSS layout box, the used value for content-box is fill-box.
    8390        case TransformBox::FillBox:
    8491            boundingBox = renderer()->objectBoundingBox();
    8592            break;
    86         case TransformBox::BorderBox:
    87             // For SVG elements without an associated CSS layout box, the used value for border-box is view-box.
    8893        case TransformBox::ViewBox: {
    8994            FloatSize viewportSize;
Note: See TracChangeset for help on using the changeset viewer.