Changeset 184895 in webkit


Ignore:
Timestamp:
May 26, 2015 9:18:04 PM (9 years ago)
Author:
commit-queue@webkit.org
Message:

An SVG with no intrinsic size does not draw correct slices when used as a border-image for an HTML element.
https://bugs.webkit.org/show_bug.cgi?id=139405

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2015-05-26
Reviewed by Darin Adler.
LayoutTests/imported/mozilla:

  • svg/as-image/border-image-simple-2.html: Add "border: 0px none;" to

style of the <div> although the style has "border-image: url() 0 fill;".
If the border width is not set to zero in the style, the <div> will have
a 3px border. This seems to be a bug in WebKit but should be unrelated to
the non-intrinsic-sized images with border-image.

Source/WebCore:

When using a non-intrinsic-sized image as an image-border, all the source
slices have to be extracted from the top-left corner of the source image.
This is because the right and bottom sides of the image can not be known.
Also all the slices should not be stretched. In other words, the sizes of
source slices for a non-intrinsic-sized image should be equal to the sizes
of the destination container slices.

This is not compliant with the css3 w3c specs. I think the specs makes it
harder to predict what exactly will be drawn for the image-border in this
case. See http://www.w3.org/TR/css3-background/#border-image-slice. This
approach is implemented by FireFox. And I think it gives a more predictable
rendering for image-border in the case of non-intrinsic-sized images.

Test: fast/borders/border-image-fill-no-intrinsic-size.html

  • CMakeLists.txt:
  • WebCore.vcxproj/WebCore.vcxproj:
  • WebCore.vcxproj/WebCore.vcxproj.filters:
  • WebCore.xcodeproj/project.pbxproj:
  • platform/LengthBox.cpp: Removed.
  • platform/graphics/LayoutBoxExtent.cpp: Removed.
  • platform/graphics/LayoutBoxExtent.h: Removed.
  • platform/graphics/LayoutRect.h:

Delete LengthBox.cpp and move all the functionalities to LengthBox.h.
Delete LayoutBoxExtent.cpp since it is the same class as LengthBox.

  • css/CSSProperty.cpp:
  • platform/text/WritingMode.h:

Move the enums LogicalBoxSide and PhysicalBoxSide
from CSSProperty.cpp to WritingMode.h so it can be used by other classes.

  • css/CSSToStyleMap.cpp:

(WebCore::CSSToStyleMap::mapNinePieceImageSlice):
(WebCore::CSSToStyleMap::mapNinePieceImageQuad):

  • css/CSSToStyleMap.h:
  • inspector/InspectorOverlay.cpp:

(WebCore::buildRendererHighlight):

  • rendering/InlineFlowBox.cpp:

(WebCore::InlineFlowBox::addBorderOutsetVisualOverflow):

  • rendering/RenderBox.h:

(WebCore::RenderBox::marginLogicalLeft):
(WebCore::RenderBox::marginLogicalRight):
(WebCore::RenderBox::setMarginBefore):
(WebCore::RenderBox::setMarginAfter):
(WebCore::RenderBox::setMarginStart):
(WebCore::RenderBox::setMarginEnd):

  • rendering/style/RenderStyle.cpp:

(WebCore::RenderStyle::setClip):
(WebCore::RenderStyle::noneDashboardRegions):

  • rendering/style/RenderStyle.h:

Use the new BoxExtent access methods for getting and settings the sides of
LengthBox and LayoutBoxExtent.

  • platform/LengthBox.h:

(WebCore::BoxExtent::BoxExtent):
(WebCore::BoxExtent::at):
(WebCore::BoxExtent::top):
(WebCore::BoxExtent::right):
(WebCore::BoxExtent::bottom):
(WebCore::BoxExtent::left):
(WebCore::BoxExtent::setAt):
(WebCore::BoxExtent::setTop):
(WebCore::BoxExtent::setRight):
(WebCore::BoxExtent::setBottom):
(WebCore::BoxExtent::setLeft):
(WebCore::BoxExtent::before):
(WebCore::BoxExtent::end):
(WebCore::BoxExtent::after):
(WebCore::BoxExtent::start):
(WebCore::BoxExtent::setBefore):
(WebCore::BoxExtent::setEnd):
(WebCore::BoxExtent::setAfter):
(WebCore::BoxExtent::setStart):
(WebCore::BoxExtent::operator==):
(WebCore::BoxExtent::operator!=):
(WebCore::LengthBox::LengthBox):
(WebCore::LengthBox::isZero):
(WebCore::LengthBox::left): Deleted.
(WebCore::LengthBox::right): Deleted.
(WebCore::LengthBox::top): Deleted.
(WebCore::LengthBox::bottom): Deleted.
(WebCore::LengthBox::operator==): Deleted.
(WebCore::LengthBox::operator!=): Deleted.
(WebCore::LengthBox::nonZero): Deleted.
Define a new template class for 'BoxExtent'. A 'BoxExtent' represents the
extent of four sides of a box. Use this class template to define the exiting
classes 'LengthBox' and 'LayoutBoxExtent'. Use it also to and define the
new class FloatBoxExtent

  • rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::calculateImageIntrinsicDimensions):

  • rendering/RenderBoxModelObject.h:

(WebCore::RenderBoxModelObject::calculateFillTileSize):

  • rendering/RenderListMarker.cpp:

(WebCore::RenderListMarker::updateContent):

  • rendering/shapes/ShapeOutsideInfo.cpp:

(WebCore::ShapeOutsideInfo::createShapeForImage):
Change the return value of calculateImageIntrinsicDimensions() to be a
bool which indicates whether the image has an intrinsic size or not. Add
a new reference argument to this function receive the resolved image size.

(WebCore::RenderBoxModelObject::paintNinePieceImage): Move all the painting
code of this function to NinePieceImage::paint()

(WebCore::computeBorderImageSide): Deleted.
Renamed to be NinePieceImage::computeSlice().

  • rendering/style/BorderData.h:

(WebCore::BorderData::borderWidth): Add a new method to return the extents
of the border in a FloatBoxExtent.

  • rendering/style/NinePieceImage.cpp:

(WebCore::NinePieceImage::computeSlice): Moved from NinePieceImage::computeSlice().

(WebCore::NinePieceImage::computeSlices): The first version of this function
computes the slices given their lengths. The slices have to be clamped to
the container size. The second version of this function computes the slices
given their lengths, their actual extents and their source slices.

(WebCore::NinePieceImage::scaleSlicesIfNeeded): Reduce the slices if they
are too large.

(WebCore::NinePieceImage::isEmptyPieceRect): Returns true if an ImagePiece
should not be drawn.

(WebCore::NinePieceImage::horizontalTileRules):
(WebCore::NinePieceImage::verticalTileRules):
Fill vectors of tiling rules to be passed to GraphicsContext::drawTiledImage()

(WebCore::NinePieceImage::computeIntrinsicRects): Computes the nine pieces
rectangles for an intrinsic-sized container.

(WebCore::NinePieceImage::computeNonIntrinsicRects): Computes the nine
pieces rectangles for an non-intrinsic-sized source image. The computed
rectangles have to start at (0, 0) and their sizes should be equal to
the sizes of the nine pieces rectangles of the destination container.

(WebCore::NinePieceImage::computeIntrinsicSideTileScale):
(WebCore::NinePieceImage::computeIntrinsicMiddleTileScale):
(WebCore::NinePieceImage::computeIntrinsicTileScales):
(WebCore::NinePieceImage::computeNonIntrinsicTileScales):
Computes the scaling factors for drawing the tiles. For non-intrinsic source
images, there should not be any scaling factors.

(WebCore::NinePieceImage::paint): Moved from RenderBoxModelObject::paintNinePieceImage()
but simplified and restructured.

(WebCore::NinePieceImageData::NinePieceImageData): Use nullptr instead of 0.

  • rendering/style/NinePieceImage.h:

(WebCore::operator++):
(WebCore::isCornerPiece):
(WebCore::isMiddlePiece):
(WebCore::imagePieceHorizontalSide):
(WebCore::imagePieceVerticalSide):
Add helper functions for the enum ImagePiece.

LayoutTests:

  • fast/borders/border-image-fill-no-intrinsic-size-expected.html: Added.
  • fast/borders/border-image-fill-no-intrinsic-size.html: Added.
  • fast/borders/resources/svg-border-100x100-intrinsic.svg: Added.
  • fast/borders/resources/svg-border-140x140-intrinsic.svg: Added.
  • fast/borders/resources/svg-border-no-intrinsic.svg: Added.

Make sure the slices of the border-image are drawn correctly. When using an
image with no intrinsic size, all the slices has to be gotten from (0, 0)
of the source image.

Location:
trunk
Files:
5 added
3 deleted
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r184894 r184895  
     12015-05-26  Said Abou-Hallawa  <sabouhallawa@apple.com>
     2
     3        An SVG with no intrinsic size does not draw correct slices when used as a border-image for an HTML element.
     4        https://bugs.webkit.org/show_bug.cgi?id=139405
     5
     6        Reviewed by Darin Adler.
     7
     8        * fast/borders/border-image-fill-no-intrinsic-size-expected.html: Added.
     9        * fast/borders/border-image-fill-no-intrinsic-size.html: Added.
     10        * fast/borders/resources/svg-border-100x100-intrinsic.svg: Added.
     11        * fast/borders/resources/svg-border-140x140-intrinsic.svg: Added.
     12        * fast/borders/resources/svg-border-no-intrinsic.svg: Added.
     13        Make sure the slices of the border-image are drawn correctly. When using an
     14        image with no intrinsic size, all the slices has to be gotten from (0, 0)
     15        of the source image.
     16       
     17        * TestExpectations: Removed previously-failing test.
     18
    1192015-05-26  Andreas Kling  <akling@apple.com>
    220
  • trunk/LayoutTests/TestExpectations

    r184881 r184895  
    434434webkit.org/b/139322 imported/mozilla/svg/text/dynamic-non-scaling-stroke.svg [ ImageOnlyFailure ]
    435435webkit.org/b/139407 imported/mozilla/svg/as-image/border-image-simple-1.html [ ImageOnlyFailure ]
    436 webkit.org/b/139405 imported/mozilla/svg/as-image/border-image-simple-2.html [ ImageOnlyFailure ]
    437436webkit.org/b/139412 imported/mozilla/svg/filters/svg-filter-chains/clip-input.svg [ ImageOnlyFailure ]
    438437webkit.org/b/139412 imported/mozilla/svg/filters/svg-filter-chains/clip-output.svg [ ImageOnlyFailure ]
  • trunk/LayoutTests/imported/mozilla/ChangeLog

    r177330 r184895  
     12015-05-26  Said Abou-Hallawa  <sabouhallawa@apple.com>
     2
     3        An SVG with no intrinsic size does not draw correct slices when used as a border-image for an HTML element.
     4        https://bugs.webkit.org/show_bug.cgi?id=139405
     5
     6        Reviewed by Darin Adler.
     7
     8        * svg/as-image/border-image-simple-2.html: Add "border: 0px none;" to
     9        style of the <div> although the style has "border-image: url() 0 fill;".
     10        If the border width is not set to zero in the style, the <div> will have
     11        a 3px border. This seems to be a bug in WebKit but should be unrelated to
     12        the non-intrinsic-sized images with border-image.
     13
    1142014-12-09  Said Abou-Hallawa  <sabouhallawa@apple.com>
    215
  • trunk/LayoutTests/imported/mozilla/svg/as-image/border-image-simple-2.html

    r177330 r184895  
    11<html>
    22<body>
    3   <div style="height: 100px; width: 100px;
     3  <div style="height: 100px; width: 100px; border: 0px none;
    44              border-image: url('resources/lime100x100-noSVGDimensions.svg') 0 fill;"/>
    55</body>
  • trunk/Source/WebCore/CMakeLists.txt

    r184857 r184895  
    20452045    platform/Language.cpp
    20462046    platform/Length.cpp
    2047     platform/LengthBox.cpp
    20482047    platform/LinkHash.cpp
    20492048    platform/Logging.cpp
     
    21522151    platform/graphics/IntSize.cpp
    21532152    platform/graphics/ISOVTTCue.cpp
    2154     platform/graphics/LayoutBoxExtent.cpp
    21552153    platform/graphics/LayoutRect.cpp
    21562154    platform/graphics/MaskImageOperation.cpp
  • trunk/Source/WebCore/ChangeLog

    r184894 r184895  
     12015-05-26  Said Abou-Hallawa  <sabouhallawa@apple.com>
     2
     3        An SVG with no intrinsic size does not draw correct slices when used as a border-image for an HTML element.
     4        https://bugs.webkit.org/show_bug.cgi?id=139405
     5
     6        Reviewed by Darin Adler.
     7       
     8        When using a non-intrinsic-sized image as an image-border, all the source
     9        slices have to be extracted from the top-left corner of the source image.
     10        This is because the right and bottom sides of the image can not be known.
     11        Also all the slices should not be stretched. In other words, the sizes of
     12        source slices for a non-intrinsic-sized image should be equal to the sizes
     13        of the destination container slices.
     14
     15        This is not compliant with the css3 w3c specs. I think the specs makes it
     16        harder to predict what exactly will be drawn for the image-border in this
     17        case. See http://www.w3.org/TR/css3-background/#border-image-slice. This
     18        approach is implemented by FireFox. And I think it gives a more predictable
     19        rendering for image-border in the case of non-intrinsic-sized images.
     20       
     21        Test: fast/borders/border-image-fill-no-intrinsic-size.html
     22
     23        * CMakeLists.txt:
     24        * WebCore.vcxproj/WebCore.vcxproj:
     25        * WebCore.vcxproj/WebCore.vcxproj.filters:
     26        * WebCore.xcodeproj/project.pbxproj:
     27        * platform/LengthBox.cpp: Removed.
     28        * platform/graphics/LayoutBoxExtent.cpp: Removed.
     29        * platform/graphics/LayoutBoxExtent.h: Removed.
     30        * platform/graphics/LayoutRect.h:
     31        Delete LengthBox.cpp and move all the functionalities to LengthBox.h.
     32        Delete LayoutBoxExtent.cpp since it is the same class as LengthBox.
     33       
     34        * css/CSSProperty.cpp:
     35        * platform/text/WritingMode.h:
     36        Move the enums LogicalBoxSide and PhysicalBoxSide
     37        from CSSProperty.cpp to WritingMode.h so it can be used by other classes.
     38       
     39        * css/CSSToStyleMap.cpp:
     40        (WebCore::CSSToStyleMap::mapNinePieceImageSlice):
     41        (WebCore::CSSToStyleMap::mapNinePieceImageQuad):
     42        * css/CSSToStyleMap.h:
     43        * inspector/InspectorOverlay.cpp:
     44        (WebCore::buildRendererHighlight):
     45        * rendering/InlineFlowBox.cpp:
     46        (WebCore::InlineFlowBox::addBorderOutsetVisualOverflow):
     47        * rendering/RenderBox.h:
     48        (WebCore::RenderBox::marginLogicalLeft):
     49        (WebCore::RenderBox::marginLogicalRight):
     50        (WebCore::RenderBox::setMarginBefore):
     51        (WebCore::RenderBox::setMarginAfter):
     52        (WebCore::RenderBox::setMarginStart):
     53        (WebCore::RenderBox::setMarginEnd):
     54        * rendering/style/RenderStyle.cpp:
     55        (WebCore::RenderStyle::setClip):
     56        (WebCore::RenderStyle::noneDashboardRegions):
     57        * rendering/style/RenderStyle.h:
     58        Use the new BoxExtent access methods for getting and settings the sides of
     59        LengthBox and LayoutBoxExtent.
     60       
     61        * platform/LengthBox.h:
     62        (WebCore::BoxExtent::BoxExtent):
     63        (WebCore::BoxExtent::at):
     64        (WebCore::BoxExtent::top):
     65        (WebCore::BoxExtent::right):
     66        (WebCore::BoxExtent::bottom):
     67        (WebCore::BoxExtent::left):
     68        (WebCore::BoxExtent::setAt):
     69        (WebCore::BoxExtent::setTop):
     70        (WebCore::BoxExtent::setRight):
     71        (WebCore::BoxExtent::setBottom):
     72        (WebCore::BoxExtent::setLeft):
     73        (WebCore::BoxExtent::before):
     74        (WebCore::BoxExtent::end):
     75        (WebCore::BoxExtent::after):
     76        (WebCore::BoxExtent::start):
     77        (WebCore::BoxExtent::setBefore):
     78        (WebCore::BoxExtent::setEnd):
     79        (WebCore::BoxExtent::setAfter):
     80        (WebCore::BoxExtent::setStart):
     81        (WebCore::BoxExtent::operator==):
     82        (WebCore::BoxExtent::operator!=):
     83        (WebCore::LengthBox::LengthBox):
     84        (WebCore::LengthBox::isZero):
     85        (WebCore::LengthBox::left): Deleted.
     86        (WebCore::LengthBox::right): Deleted.
     87        (WebCore::LengthBox::top): Deleted.
     88        (WebCore::LengthBox::bottom): Deleted.
     89        (WebCore::LengthBox::operator==): Deleted.
     90        (WebCore::LengthBox::operator!=): Deleted.
     91        (WebCore::LengthBox::nonZero): Deleted.
     92        Define a new template class for 'BoxExtent'. A 'BoxExtent' represents the
     93        extent of four sides of a box. Use this class template to define the exiting
     94        classes 'LengthBox' and 'LayoutBoxExtent'. Use it also to and define the
     95        new class FloatBoxExtent
     96           
     97        * rendering/RenderBoxModelObject.cpp:
     98        (WebCore::RenderBoxModelObject::calculateImageIntrinsicDimensions):
     99        * rendering/RenderBoxModelObject.h:
     100        (WebCore::RenderBoxModelObject::calculateFillTileSize):
     101        * rendering/RenderListMarker.cpp:
     102        (WebCore::RenderListMarker::updateContent):
     103        * rendering/shapes/ShapeOutsideInfo.cpp:
     104        (WebCore::ShapeOutsideInfo::createShapeForImage):
     105        Change the return value of calculateImageIntrinsicDimensions() to be a
     106        bool which indicates whether the image has an intrinsic size or not. Add
     107        a new reference argument to this function receive the resolved image size.
     108       
     109        (WebCore::RenderBoxModelObject::paintNinePieceImage): Move all the painting
     110        code of this function to NinePieceImage::paint()
     111       
     112        (WebCore::computeBorderImageSide): Deleted.
     113        Renamed to be NinePieceImage::computeSlice().
     114       
     115        * rendering/style/BorderData.h:
     116        (WebCore::BorderData::borderWidth): Add a new method to return the extents
     117        of the border in a FloatBoxExtent.
     118       
     119        * rendering/style/NinePieceImage.cpp:
     120        (WebCore::NinePieceImage::computeSlice): Moved from NinePieceImage::computeSlice().
     121       
     122        (WebCore::NinePieceImage::computeSlices): The first version of this function
     123        computes the slices given their lengths. The slices have to be clamped to
     124        the container size. The second version of this function computes the slices
     125        given their lengths, their actual extents and their source slices.
     126       
     127        (WebCore::NinePieceImage::scaleSlicesIfNeeded):  Reduce the slices if they
     128        are too large.
     129       
     130        (WebCore::NinePieceImage::isEmptyPieceRect): Returns true if an ImagePiece
     131        should not be drawn.
     132       
     133        (WebCore::NinePieceImage::horizontalTileRules):
     134        (WebCore::NinePieceImage::verticalTileRules):
     135        Fill vectors of tiling rules to be passed to GraphicsContext::drawTiledImage()
     136       
     137        (WebCore::NinePieceImage::computeIntrinsicRects): Computes the nine pieces
     138        rectangles for an intrinsic-sized container.
     139       
     140        (WebCore::NinePieceImage::computeNonIntrinsicRects): Computes the nine
     141        pieces rectangles for an non-intrinsic-sized source image. The computed
     142        rectangles have to start at (0, 0) and their sizes should be equal to
     143        the sizes of the nine pieces rectangles of the destination container.
     144       
     145        (WebCore::NinePieceImage::computeIntrinsicSideTileScale):
     146        (WebCore::NinePieceImage::computeIntrinsicMiddleTileScale):
     147        (WebCore::NinePieceImage::computeIntrinsicTileScales):
     148        (WebCore::NinePieceImage::computeNonIntrinsicTileScales):
     149        Computes the scaling factors for drawing the tiles. For non-intrinsic source
     150        images, there should not be any scaling factors.
     151       
     152        (WebCore::NinePieceImage::paint): Moved from RenderBoxModelObject::paintNinePieceImage()
     153        but simplified and restructured.
     154       
     155        (WebCore::NinePieceImageData::NinePieceImageData): Use nullptr instead of 0.
     156       
     157        * rendering/style/NinePieceImage.h:
     158        (WebCore::operator++):
     159        (WebCore::isCornerPiece):
     160        (WebCore::isMiddlePiece):
     161        (WebCore::imagePieceHorizontalSide):
     162        (WebCore::imagePieceVerticalSide):
     163        Add helper functions for the enum ImagePiece.
     164
    11652015-05-26  Andreas Kling  <akling@apple.com>
    2166
  • trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj

    r184610 r184895  
    79977997    <ClCompile Include="..\platform\Language.cpp" />
    79987998    <ClCompile Include="..\platform\Length.cpp" />
    7999     <ClCompile Include="..\platform\LengthBox.cpp" />
    80007999    <ClCompile Include="..\platform\LinkHash.cpp" />
    80018000    <ClCompile Include="..\platform\LocalizedStrings.cpp" />
     
    82168215    <ClCompile Include="..\platform\graphics\IntRect.cpp" />
    82178216    <ClCompile Include="..\platform\graphics\IntSize.cpp" />
    8218     <ClCompile Include="..\platform\graphics\LayoutBoxExtent.cpp" />
    82198217    <ClCompile Include="..\platform\graphics\LayoutRect.cpp" />
    82208218    <ClCompile Include="..\platform\graphics\MediaPlayer.cpp" />
     
    2001220010    <ClInclude Include="..\platform\graphics\IntSizeHash.h" />
    2001320011    <ClInclude Include="..\platform\graphics\ISOVTTCue.h" />
    20014     <ClInclude Include="..\platform\graphics\LayoutBoxExtent.h" />
    2001520012    <ClInclude Include="..\platform\graphics\LayoutPoint.h" />
    2001620013    <ClInclude Include="..\platform\graphics\LayoutRect.h" />
  • trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters

    r184610 r184895  
    11141114      <Filter>platform</Filter>
    11151115    </ClCompile>
    1116     <ClCompile Include="..\platform\LengthBox.cpp">
    1117       <Filter>platform</Filter>
    1118     </ClCompile>
    11191116    <ClCompile Include="..\platform\LinkHash.cpp">
    11201117      <Filter>platform</Filter>
     
    13701367    </ClCompile>
    13711368    <ClCompile Include="..\platform\graphics\IntSize.cpp">
    1372       <Filter>platform\graphics</Filter>
    1373     </ClCompile>
    1374     <ClCompile Include="..\platform\graphics\LayoutBoxExtent.cpp">
    13751369      <Filter>platform\graphics</Filter>
    13761370    </ClCompile>
     
    84958489    </ClInclude>
    84968490    <ClInclude Include="..\platform\graphics\IntSizeHash.h">
    8497       <Filter>platform\graphics</Filter>
    8498     </ClInclude>
    8499     <ClInclude Include="..\platform\graphics\LayoutBoxExtent.h">
    85008491      <Filter>platform\graphics</Filter>
    85018492    </ClInclude>
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r184780 r184895  
    591591                1411DCB1164C39A800D49BC1 /* WidthCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1411DCB0164C39A800D49BC1 /* WidthCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
    592592                141DC0481648348F00371E5A /* LayoutUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 141DC0471648348F00371E5A /* LayoutUnit.h */; settings = {ATTRIBUTES = (Private, ); }; };
    593                 141DC04F164834B900371E5A /* LayoutBoxExtent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 141DC049164834B900371E5A /* LayoutBoxExtent.cpp */; };
    594                 141DC050164834B900371E5A /* LayoutBoxExtent.h in Headers */ = {isa = PBXBuildFile; fileRef = 141DC04A164834B900371E5A /* LayoutBoxExtent.h */; settings = {ATTRIBUTES = (Private, ); }; };
    595593                141DC051164834B900371E5A /* LayoutPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 141DC04B164834B900371E5A /* LayoutPoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
    596594                141DC052164834B900371E5A /* LayoutRect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 141DC04C164834B900371E5A /* LayoutRect.cpp */; };
     
    606604                1449E24C107D4A8400B5793F /* JSCallbackData.h in Headers */ = {isa = PBXBuildFile; fileRef = 1449E24A107D4A8400B5793F /* JSCallbackData.h */; };
    607605                1449E287107D4DB400B5793F /* JSCallbackData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1449E286107D4DB400B5793F /* JSCallbackData.cpp */; };
    608                 146CC115156988E400109E37 /* LengthBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 146CC113156988BD00109E37 /* LengthBox.cpp */; };
    609606                1477E7760BF4134A00152872 /* PageCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1477E7740BF4134A00152872 /* PageCache.cpp */; };
    610607                1477E7770BF4134A00152872 /* PageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1477E7750BF4134A00152872 /* PageCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    76667663                141B94EE09EC425A000E9413 /* UIEvent.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = UIEvent.idl; sourceTree = "<group>"; };
    76677664                141DC0471648348F00371E5A /* LayoutUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutUnit.h; sourceTree = "<group>"; };
    7668                 141DC049164834B900371E5A /* LayoutBoxExtent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutBoxExtent.cpp; sourceTree = "<group>"; };
    7669                 141DC04A164834B900371E5A /* LayoutBoxExtent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutBoxExtent.h; sourceTree = "<group>"; };
    76707665                141DC04B164834B900371E5A /* LayoutPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutPoint.h; sourceTree = "<group>"; };
    76717666                141DC04C164834B900371E5A /* LayoutRect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutRect.cpp; sourceTree = "<group>"; };
     
    76827677                1449E24A107D4A8400B5793F /* JSCallbackData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackData.h; sourceTree = "<group>"; };
    76837678                1449E286107D4DB400B5793F /* JSCallbackData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCallbackData.cpp; sourceTree = "<group>"; };
    7684                 146CC113156988BD00109E37 /* LengthBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LengthBox.cpp; sourceTree = "<group>"; };
    76857679                1477E7740BF4134A00152872 /* PageCache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PageCache.cpp; sourceTree = "<group>"; };
    76867680                1477E7750BF4134A00152872 /* PageCache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PageCache.h; sourceTree = "<group>"; };
     
    2088120875                                07AC47001952102100EE9723 /* ISOVTTCue.h */,
    2088220876                                65CC6BED16014EC0000ED27D /* Latin1TextIterator.h */,
    20883                                 141DC049164834B900371E5A /* LayoutBoxExtent.cpp */,
    20884                                 141DC04A164834B900371E5A /* LayoutBoxExtent.h */,
    2088520877                                141DC04B164834B900371E5A /* LayoutPoint.h */,
    2088620878                                141DC04C164834B900371E5A /* LayoutRect.cpp */,
     
    2176821760                                BCE65BE80EACDF16007E4533 /* Length.cpp */,
    2176921761                                BCE65BE90EACDF16007E4533 /* Length.h */,
    21770                                 146CC113156988BD00109E37 /* LengthBox.cpp */,
    2177121762                                BCFF648F0EAD15C200C1D6F7 /* LengthBox.h */,
    2177221763                                BCFF64900EAD15C200C1D6F7 /* LengthSize.h */,
     
    2570925700                                580371641A66F1D300BAF519 /* LayerFragment.h in Headers */,
    2571025701                                7AA3A6A0194B59B6001CBD24 /* LayerPool.h in Headers */,
    25711                                 141DC050164834B900371E5A /* LayoutBoxExtent.h in Headers */,
    2571225702                                931D72F615FE695300C4C07E /* LayoutMilestones.h in Headers */,
    2571325703                                141DC051164834B900371E5A /* LayoutPoint.h in Headers */,
     
    2930529295                                2917B566147349950052C9D0 /* LayerFlushSchedulerMac.cpp in Sources */,
    2930629296                                7AA3A69F194B59B6001CBD24 /* LayerPool.cpp in Sources */,
    29307                                 141DC04F164834B900371E5A /* LayoutBoxExtent.cpp in Sources */,
    2930829297                                141DC052164834B900371E5A /* LayoutRect.cpp in Sources */,
    2930929298                                A120ACA413F998CA00FE4AC7 /* LayoutRepainter.cpp in Sources */,
     
    2931729306                                51B2417B0D931F3F00E83F5C /* LegacyWebArchiveMac.mm in Sources */,
    2931829307                                BCE65BEA0EACDF16007E4533 /* Length.cpp in Sources */,
    29319                                 146CC115156988E400109E37 /* LengthBox.cpp in Sources */,
    2932029308                                E55F497A151B888000BB67DB /* LengthFunctions.cpp in Sources */,
    2932129309                                FFB698CC1833EE0D00158A31 /* LineBreaker.cpp in Sources */,
  • trunk/Source/WebCore/css/CSSProperty.cpp

    r178586 r184895  
    5454    m_value = WTF::move(list);
    5555}
    56 
    57 enum LogicalBoxSide { BeforeSide, EndSide, AfterSide, StartSide };
    58 enum PhysicalBoxSide { TopSide, RightSide, BottomSide, LeftSide };
    5956
    6057static CSSPropertyID resolveToPhysicalProperty(TextDirection direction, WritingMode writingMode, LogicalBoxSide logicalSide, const StylePropertyShorthand& shorthand)
  • trunk/Source/WebCore/css/CSSToStyleMap.cpp

    r182354 r184895  
    619619    Quad* slices = borderImageSlice.slices();
    620620    if (slices->top()->isPercentage())
    621         box.m_top = Length(slices->top()->getDoubleValue(), Percent);
    622     else
    623         box.m_top = Length(slices->top()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
     621        box.top() = Length(slices->top()->getDoubleValue(), Percent);
     622    else
     623        box.top() = Length(slices->top()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
    624624    if (slices->bottom()->isPercentage())
    625         box.m_bottom = Length(slices->bottom()->getDoubleValue(), Percent);
    626     else
    627         box.m_bottom = Length((int)slices->bottom()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
     625        box.bottom() = Length(slices->bottom()->getDoubleValue(), Percent);
     626    else
     627        box.bottom() = Length((int)slices->bottom()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
    628628    if (slices->left()->isPercentage())
    629         box.m_left = Length(slices->left()->getDoubleValue(), Percent);
    630     else
    631         box.m_left = Length(slices->left()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
     629        box.left() = Length(slices->left()->getDoubleValue(), Percent);
     630    else
     631        box.left() = Length(slices->left()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
    632632    if (slices->right()->isPercentage())
    633         box.m_right = Length(slices->right()->getDoubleValue(), Percent);
    634     else
    635         box.m_right = Length(slices->right()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
     633        box.right() = Length(slices->right()->getDoubleValue(), Percent);
     634    else
     635        box.right() = Length(slices->right()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
    636636    image.setImageSlices(box);
    637637
     
    655655    Quad* slices = borderWidths.getQuadValue();
    656656    if (slices->top()->isNumber())
    657         box.m_top = Length(slices->top()->getIntValue(), Relative);
     657        box.top() = Length(slices->top()->getIntValue(), Relative);
    658658    else if (slices->top()->isPercentage())
    659         box.m_top = Length(slices->top()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
     659        box.top() = Length(slices->top()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
    660660    else if (slices->top()->getValueID() != CSSValueAuto)
    661         box.m_top = slices->top()->computeLength<Length>(conversionData);
     661        box.top() = slices->top()->computeLength<Length>(conversionData);
    662662
    663663    if (slices->right()->isNumber())
    664         box.m_right = Length(slices->right()->getIntValue(), Relative);
     664        box.right() = Length(slices->right()->getIntValue(), Relative);
    665665    else if (slices->right()->isPercentage())
    666         box.m_right = Length(slices->right()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
     666        box.right() = Length(slices->right()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
    667667    else if (slices->right()->getValueID() != CSSValueAuto)
    668         box.m_right = slices->right()->computeLength<Length>(conversionData);
     668        box.right() = slices->right()->computeLength<Length>(conversionData);
    669669
    670670    if (slices->bottom()->isNumber())
    671         box.m_bottom = Length(slices->bottom()->getIntValue(), Relative);
     671        box.bottom() = Length(slices->bottom()->getIntValue(), Relative);
    672672    else if (slices->bottom()->isPercentage())
    673         box.m_bottom = Length(slices->bottom()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
     673        box.bottom() = Length(slices->bottom()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
    674674    else if (slices->bottom()->getValueID() != CSSValueAuto)
    675         box.m_bottom = slices->bottom()->computeLength<Length>(conversionData);
     675        box.bottom() = slices->bottom()->computeLength<Length>(conversionData);
    676676
    677677    if (slices->left()->isNumber())
    678         box.m_left = Length(slices->left()->getIntValue(), Relative);
     678        box.left() = Length(slices->left()->getIntValue(), Relative);
    679679    else if (slices->left()->isPercentage())
    680         box.m_left = Length(slices->left()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
     680        box.left() = Length(slices->left()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
    681681    else if (slices->left()->getValueID() != CSSValueAuto)
    682         box.m_left = slices->left()->computeLength<Length>(conversionData);
     682        box.left() = slices->left()->computeLength<Length>(conversionData);
    683683
    684684    return box;
  • trunk/Source/WebCore/css/CSSToStyleMap.h

    r182354 r184895  
    3737class NinePieceImage;
    3838
    39 struct LengthBox;
     39class LengthBox;
    4040
    4141class CSSToStyleMap {
  • trunk/Source/WebCore/inspector/InspectorOverlay.cpp

    r178820 r184895  
    112112                RenderBox::LogicalExtentComputedValues computedValues;
    113113                renderBox.computeLogicalWidthInRegion(computedValues, region);
    114                 margins.mutableLogicalLeft(renderBox.style().writingMode()) = computedValues.m_margins.m_start;
    115                 margins.mutableLogicalRight(renderBox.style().writingMode()) = computedValues.m_margins.m_end;
     114                margins.start(renderBox.style().writingMode()) = computedValues.m_margins.m_start;
     115                margins.end(renderBox.style().writingMode()) = computedValues.m_margins.m_end;
    116116            }
    117117
  • trunk/Source/WebCore/platform/LengthBox.h

    r182207 r184895  
    11/*
    22    Copyright (C) 1999 Lars Knoll (knoll@kde.org)
    3     Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
     3    Copyright (C) 2006, 2008, 2015 Apple Inc. All rights reserved.
    44    Copyright (c) 2012, Google Inc. All rights reserved.
    55
     
    2626#include "TextFlags.h"
    2727#include "WritingMode.h"
     28#include <array>
    2829
    2930namespace WebCore {
    3031
    31 struct LengthBox {
     32template<typename T> class BoxExtent {
     33public:
     34    BoxExtent()
     35        : m_sides({{ T(0), T(0), T(0), T(0) }})
     36    {
     37    }
     38
     39    BoxExtent(const T& top, const T& right, const T& bottom, const T& left)
     40        : m_sides({{ top, right, bottom, left }})
     41    {
     42    }
     43
     44    T& at(PhysicalBoxSide side) { return m_sides[side]; }
     45    T& top() { return at(TopSide); }
     46    T& right() { return at(RightSide); }
     47    T& bottom() { return at(BottomSide); }
     48    T& left() { return at(LeftSide); }
     49
     50    const T& at(PhysicalBoxSide side) const { return m_sides[side]; }
     51    const T& top() const { return at(TopSide); }
     52    const T& right() const { return at(RightSide); }
     53    const T& bottom() const { return at(BottomSide); }
     54    const T& left() const { return at(LeftSide); }
     55
     56    void setAt(PhysicalBoxSide side, const T& v) { at(side) = v; }
     57    void setTop(const T& top) { setAt(TopSide, top); }
     58    void setRight(const T& right) { setAt(RightSide, right); }
     59    void setBottom(const T& bottom) { setAt(BottomSide, bottom); }
     60    void setLeft(const T& left) { setAt(LeftSide, left); }
     61
     62    T& before(WritingMode writingMode)
     63    {
     64        return isHorizontalWritingMode(writingMode) ?
     65            (isFlippedBlocksWritingMode(writingMode) ? bottom() : top()) :
     66            (isFlippedBlocksWritingMode(writingMode) ? right() : left());
     67    }
     68
     69    T& after(WritingMode writingMode)
     70    {
     71        return isHorizontalWritingMode(writingMode) ?
     72            (isFlippedBlocksWritingMode(writingMode) ? top() : bottom()) :
     73            (isFlippedBlocksWritingMode(writingMode) ? left() : right());
     74    }
     75
     76    T& start(WritingMode writingMode, TextDirection direction = LTR)
     77    {
     78        return isHorizontalWritingMode(writingMode) ?
     79            (isLeftToRightDirection(direction) ? left() : right()) :
     80            (isLeftToRightDirection(direction) ? top() : bottom());
     81    }
     82
     83    T& end(WritingMode writingMode, TextDirection direction = LTR)
     84    {
     85        return isHorizontalWritingMode(writingMode) ?
     86            (isLeftToRightDirection(direction) ? right() : left()) :
     87            (isLeftToRightDirection(direction) ? bottom() : top());
     88    }
     89
     90    const T& before(WritingMode writingMode) const
     91    {
     92        return isHorizontalWritingMode(writingMode) ?
     93            (isFlippedBlocksWritingMode(writingMode) ? bottom() : top()) :
     94            (isFlippedBlocksWritingMode(writingMode) ? right() : left());
     95    }
     96
     97    const T& after(WritingMode writingMode) const
     98    {
     99        return isHorizontalWritingMode(writingMode) ?
     100            (isFlippedBlocksWritingMode(writingMode) ? top() : bottom()) :
     101            (isFlippedBlocksWritingMode(writingMode) ? left() : right());
     102    }
     103
     104    const T& start(WritingMode writingMode, TextDirection direction = LTR) const
     105    {
     106        return isHorizontalWritingMode(writingMode) ?
     107            (isLeftToRightDirection(direction) ? left() : right()) :
     108            (isLeftToRightDirection(direction) ? top() : bottom());
     109    }
     110
     111    const T& end(WritingMode writingMode, TextDirection direction = LTR) const
     112    {
     113        return isHorizontalWritingMode(writingMode) ?
     114            (isLeftToRightDirection(direction) ? right() : left()) :
     115            (isLeftToRightDirection(direction) ? bottom() : top());
     116    }
     117
     118    void setBefore(const T& before, WritingMode writingMode) { this->before(writingMode) = before; }
     119    void setAfter(const T& after, WritingMode writingMode) { this->after(writingMode) = after; }
     120    void setStart(const T& start, WritingMode writingMode, TextDirection direction = LTR) { this->start(writingMode, direction) = start; }
     121    void setEnd(const T& end, WritingMode writingMode, TextDirection direction = LTR) { this->end(writingMode, direction) = end; }
     122
     123    bool operator==(const BoxExtent& other) const
     124    {
     125        return m_sides == other.m_sides;
     126    }
     127
     128    bool operator!=(const BoxExtent& other) const
     129    {
     130        return m_sides != other.m_sides;
     131    }
     132
     133protected:
     134    std::array<T, 4> m_sides;
     135};
     136
     137class LengthBox : public BoxExtent<Length> {
     138public:
    32139    LengthBox()
     140        : LengthBox(Auto)
    33141    {
    34142    }
    35143
    36144    explicit LengthBox(LengthType type)
    37         : m_left(type)
    38         , m_right(type)
    39         , m_top(type)
    40         , m_bottom(type)
     145        : BoxExtent(Length(type), Length(type), Length(type), Length(type))
    41146    {
    42147    }
    43148
    44149    explicit LengthBox(int v)
    45         : m_left(Length(v, Fixed))
    46         , m_right(Length(v, Fixed))
    47         , m_top(Length(v, Fixed))
    48         , m_bottom(Length(v, Fixed))
    49     {
    50     }
    51 
    52     LengthBox(Length top, Length right, Length bottom, Length left)
    53         : m_left(WTF::move(left))
    54         , m_right(WTF::move(right))
    55         , m_top(WTF::move(top))
    56         , m_bottom(WTF::move(bottom))
     150        : BoxExtent(Length(v, Fixed), Length(v, Fixed), Length(v, Fixed), Length(v, Fixed))
    57151    {
    58152    }
    59153
    60154    LengthBox(int top, int right, int bottom, int left)
    61         : m_left(Length(left, Fixed))
    62         , m_right(Length(right, Fixed))
    63         , m_top(Length(top, Fixed))
    64         , m_bottom(Length(bottom, Fixed))
     155        : BoxExtent(Length(top, Fixed), Length(right, Fixed), Length(bottom, Fixed), Length(left, Fixed))
    65156    {
    66157    }
    67158
    68     const Length& left() const { return m_left; }
    69     const Length& right() const { return m_right; }
    70     const Length& top() const { return m_top; }
    71     const Length& bottom() const { return m_bottom; }
    72 
    73     const Length& logicalLeft(WritingMode) const;
    74     const Length& logicalRight(WritingMode) const;
    75 
    76     const Length& before(WritingMode) const;
    77     const Length& after(WritingMode) const;
    78     const Length& start(WritingMode, TextDirection) const;
    79     const Length& end(WritingMode, TextDirection) const;
    80 
    81     bool operator==(const LengthBox& other) const
     159    LengthBox(const Length& top, const Length& right, const Length& bottom, const Length& left)
     160        : BoxExtent(top, right, bottom, left)
    82161    {
    83         return m_left == other.m_left && m_right == other.m_right && m_top == other.m_top && m_bottom == other.m_bottom;
    84162    }
    85163
    86     bool operator!=(const LengthBox& other) const
     164    bool isZero() const
    87165    {
    88         return !(*this == other);
     166        return top().isZero() && right().isZero() && bottom().isZero() && left().isZero();
    89167    }
     168};
    90169
    91     bool nonZero() const
    92     {
    93         return !(m_left.isZero() && m_right.isZero() && m_top.isZero() && m_bottom.isZero());
    94     }
    95 
    96     Length m_left;
    97     Length m_right;
    98     Length m_top;
    99     Length m_bottom;
    100 };
     170typedef BoxExtent<LayoutUnit> LayoutBoxExtent;
     171typedef BoxExtent<float> FloatBoxExtent;
    101172
    102173} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/LayoutRect.h

    r178541 r184895  
    3434#include "FloatRect.h"
    3535#include "IntRect.h"
    36 #include "LayoutBoxExtent.h"
    3736#include "LayoutPoint.h"
     37#include "LengthBox.h"
    3838#include <wtf/Vector.h>
    3939
  • trunk/Source/WebCore/platform/text/WritingMode.h

    r128508 r184895  
    5656}
    5757
     58enum LogicalBoxSide {
     59    BeforeSide,
     60    EndSide,
     61    AfterSide,
     62    StartSide
     63};
     64
     65enum PhysicalBoxSide {
     66    NilSide = -1,
     67    TopSide,
     68    RightSide,
     69    BottomSide,
     70    LeftSide
     71};
     72
    5873} // namespace WebCore
    5974
  • trunk/Source/WebCore/rendering/InlineFlowBox.cpp

    r184395 r184895  
    844844    LayoutBoxExtent borderOutsets = lineStyle.borderImageOutsets();
    845845
    846     LayoutUnit borderOutsetLogicalTop = borderOutsets.logicalTop(lineStyle.writingMode());
    847     LayoutUnit borderOutsetLogicalBottom = borderOutsets.logicalBottom(lineStyle.writingMode());
    848     LayoutUnit borderOutsetLogicalLeft = borderOutsets.logicalLeft(lineStyle.writingMode());
    849     LayoutUnit borderOutsetLogicalRight = borderOutsets.logicalRight(lineStyle.writingMode());
     846    LayoutUnit borderOutsetLogicalTop = borderOutsets.before(lineStyle.writingMode());
     847    LayoutUnit borderOutsetLogicalBottom = borderOutsets.after(lineStyle.writingMode());
     848    LayoutUnit borderOutsetLogicalLeft = borderOutsets.start(lineStyle.writingMode());
     849    LayoutUnit borderOutsetLogicalRight = borderOutsets.end(lineStyle.writingMode());
    850850
    851851    // Similar to how glyph overflow works, if our lines are flipped, then it's actually the opposite border that applies, since
  • trunk/Source/WebCore/rendering/RenderBox.h

    r184885 r184895  
    263263    void setMarginRight(LayoutUnit margin) { m_marginBox.setRight(margin); }
    264264
    265     LayoutUnit marginLogicalLeft() const { return m_marginBox.logicalLeft(style().writingMode()); }
    266     LayoutUnit marginLogicalRight() const { return m_marginBox.logicalRight(style().writingMode()); }
     265    LayoutUnit marginLogicalLeft() const { return m_marginBox.start(style().writingMode()); }
     266    LayoutUnit marginLogicalRight() const { return m_marginBox.end(style().writingMode()); }
    267267   
    268268    virtual LayoutUnit marginBefore(const RenderStyle* overrideStyle = nullptr) const override final { return m_marginBox.before((overrideStyle ? overrideStyle : &style())->writingMode()); }
     
    278278        return m_marginBox.end(styleToUse->writingMode(), styleToUse->direction());
    279279    }
    280     void setMarginBefore(LayoutUnit value, const RenderStyle* overrideStyle = nullptr) { m_marginBox.setBefore((overrideStyle ? overrideStyle : &style())->writingMode(), value); }
    281     void setMarginAfter(LayoutUnit value, const RenderStyle* overrideStyle = nullptr) { m_marginBox.setAfter((overrideStyle ? overrideStyle : &style())->writingMode(), value); }
     280    void setMarginBefore(LayoutUnit value, const RenderStyle* overrideStyle = nullptr) { m_marginBox.setBefore(value, (overrideStyle ? overrideStyle : &style())->writingMode()); }
     281    void setMarginAfter(LayoutUnit value, const RenderStyle* overrideStyle = nullptr) { m_marginBox.setAfter(value, (overrideStyle ? overrideStyle : &style())->writingMode()); }
    282282    void setMarginStart(LayoutUnit value, const RenderStyle* overrideStyle = nullptr)
    283283    {
    284284        const RenderStyle* styleToUse = overrideStyle ? overrideStyle : &style();
    285         m_marginBox.setStart(styleToUse->writingMode(), styleToUse->direction(), value);
     285        m_marginBox.setStart(value, styleToUse->writingMode(), styleToUse->direction());
    286286    }
    287287    void setMarginEnd(LayoutUnit value, const RenderStyle* overrideStyle = nullptr)
    288288    {
    289289        const RenderStyle* styleToUse = overrideStyle ? overrideStyle : &style();
    290         m_marginBox.setEnd(styleToUse->writingMode(), styleToUse->direction(), value);
     290        m_marginBox.setEnd(value, styleToUse->writingMode(), styleToUse->direction());
    291291    }
    292292
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r184555 r184895  
    922922}
    923923
    924 LayoutSize RenderBoxModelObject::calculateImageIntrinsicDimensions(StyleImage* image, const LayoutSize& positioningAreaSize, ScaleByEffectiveZoomOrNot shouldScaleOrNot) const
     924bool RenderBoxModelObject::calculateImageIntrinsicDimensions(StyleImage* image, const LayoutSize& positioningAreaSize, ScaleByEffectiveZoomOrNot shouldScaleOrNot, LayoutSize& imageSize) const
    925925{
    926926    // A generated image without a fixed size, will always return the container size as intrinsic size.
    927     if (image->isGeneratedImage() && image->usesImageContainerSize())
    928         return LayoutSize(positioningAreaSize.width(), positioningAreaSize.height());
     927    if (image->isGeneratedImage() && image->usesImageContainerSize()) {
     928        imageSize = LayoutSize(positioningAreaSize.width(), positioningAreaSize.height());
     929        return true;
     930    }
    929931
    930932    Length intrinsicWidth;
     
    936938    ASSERT(!intrinsicHeight.isPercentOrCalculated());
    937939
    938     LayoutSize resolvedSize(intrinsicWidth.value(), intrinsicHeight.value());
    939     LayoutSize minimumSize(resolvedSize.width() > 0 ? 1 : 0, resolvedSize.height() > 0 ? 1 : 0);
     940    imageSize = LayoutSize(intrinsicWidth.value(), intrinsicHeight.value());
     941    LayoutSize minimumSize(imageSize.width() > 0 ? 1 : 0, imageSize.height() > 0 ? 1 : 0);
    940942    if (shouldScaleOrNot == ScaleByEffectiveZoom)
    941         resolvedSize.scale(style().effectiveZoom());
    942     resolvedSize.clampToMinimumSize(minimumSize);
    943 
    944     if (!resolvedSize.isEmpty())
    945         return resolvedSize;
     943        imageSize.scale(style().effectiveZoom());
     944    imageSize.clampToMinimumSize(minimumSize);
     945
     946    if (!imageSize.isEmpty())
     947        return true;
    946948
    947949    // If the image has one of either an intrinsic width or an intrinsic height:
     
    949951    // * and no intrinsic aspect ratio, then the missing dimension is assumed to be the size of the rectangle that
    950952    //   establishes the coordinate system for the 'background-position' property.
    951     if (resolvedSize.width() > 0 || resolvedSize.height() > 0)
    952         return resolveAgainstIntrinsicWidthOrHeightAndRatio(positioningAreaSize, intrinsicRatio, resolvedSize.width(), resolvedSize.height());
     953    if (imageSize.width() > 0 || imageSize.height() > 0) {
     954        imageSize = resolveAgainstIntrinsicWidthOrHeightAndRatio(positioningAreaSize, intrinsicRatio, imageSize.width(), imageSize.height());
     955        return true;
     956    }
    953957
    954958    // If the image has no intrinsic dimensions and has an intrinsic ratio the dimensions must be assumed to be the
    955959    // largest dimensions at that ratio such that neither dimension exceeds the dimensions of the rectangle that
    956960    // establishes the coordinate system for the 'background-position' property.
    957     if (!intrinsicRatio.isEmpty())
    958         return resolveAgainstIntrinsicRatio(positioningAreaSize, intrinsicRatio);
     961    if (!intrinsicRatio.isEmpty()) {
     962        imageSize = resolveAgainstIntrinsicRatio(positioningAreaSize, intrinsicRatio);
     963        return false;
     964    }
    959965
    960966    // If the image has no intrinsic ratio either, then the dimensions must be assumed to be the rectangle that
    961967    // establishes the coordinate system for the 'background-position' property.
    962     return positioningAreaSize;
     968    imageSize = positioningAreaSize;
     969    return false;
    963970}
    964971
     
    970977    LayoutSize imageIntrinsicSize;
    971978    if (image) {
    972         imageIntrinsicSize = calculateImageIntrinsicDimensions(image, positioningAreaSize, ScaleByEffectiveZoom);
     979        calculateImageIntrinsicDimensions(image, positioningAreaSize, ScaleByEffectiveZoom, imageIntrinsicSize);
    973980        imageIntrinsicSize.scale(1 / image->imageScaleFactor(), 1 / image->imageScaleFactor());
    974981    } else
     
    12391246}
    12401247
    1241 static LayoutUnit computeBorderImageSide(Length borderSlice, LayoutUnit borderSide, LayoutUnit imageSide, LayoutUnit boxExtent)
    1242 {
    1243     if (borderSlice.isRelative())
    1244         return borderSlice.value() * borderSide;
    1245     if (borderSlice.isAuto())
    1246         return imageSide;
    1247     return valueForLength(borderSlice, boxExtent);
    1248 }
    1249 
    12501248bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext, const LayoutRect& rect, const RenderStyle& style,
    12511249                                               const NinePieceImage& ninePieceImage, CompositeOperator op)
     
    12641262    // doesn't have any understanding of the zoom that is in effect on the tile.
    12651263    float deviceScaleFactor = document().deviceScaleFactor();
     1264
    12661265    LayoutRect rectWithOutsets = rect;
    12671266    rectWithOutsets.expand(style.imageOutsets(ninePieceImage));
    1268     LayoutRect borderImageRect = LayoutRect(snapRectToDevicePixels(rectWithOutsets, deviceScaleFactor));
    1269 
    1270     LayoutSize imageSize = calculateImageIntrinsicDimensions(styleImage, borderImageRect.size(), DoNotScaleByEffectiveZoom);
     1267    LayoutRect destination = LayoutRect(snapRectToDevicePixels(rectWithOutsets, deviceScaleFactor));
     1268
     1269    LayoutSize source;
     1270    bool intrinsicSource = calculateImageIntrinsicDimensions(styleImage, destination.size(), DoNotScaleByEffectiveZoom, source);
    12711271
    12721272    // If both values are ‘auto’ then the intrinsic width and/or height of the image should be used, if any.
    1273     styleImage->setContainerSizeForRenderer(this, imageSize, style.effectiveZoom());
    1274 
    1275     LayoutUnit imageWidth = imageSize.width();
    1276     LayoutUnit imageHeight = imageSize.height();
    1277 
    1278     float imageScaleFactor = styleImage->imageScaleFactor();
    1279     LayoutUnit topSlice = std::min<LayoutUnit>(imageHeight, valueForLength(ninePieceImage.imageSlices().top(), imageHeight)) * imageScaleFactor;
    1280     LayoutUnit rightSlice = std::min<LayoutUnit>(imageWidth, valueForLength(ninePieceImage.imageSlices().right(), imageWidth)) * imageScaleFactor;
    1281     LayoutUnit bottomSlice = std::min<LayoutUnit>(imageHeight, valueForLength(ninePieceImage.imageSlices().bottom(), imageHeight)) * imageScaleFactor;
    1282     LayoutUnit leftSlice = std::min<LayoutUnit>(imageWidth, valueForLength(ninePieceImage.imageSlices().left(), imageWidth)) * imageScaleFactor;
    1283 
    1284     ENinePieceImageRule hRule = ninePieceImage.horizontalRule();
    1285     ENinePieceImageRule vRule = ninePieceImage.verticalRule();
    1286 
    1287     LayoutUnit topWidth = computeBorderImageSide(ninePieceImage.borderSlices().top(), style.borderTopWidth(), topSlice, borderImageRect.height());
    1288     LayoutUnit rightWidth = computeBorderImageSide(ninePieceImage.borderSlices().right(), style.borderRightWidth(), rightSlice, borderImageRect.width());
    1289     LayoutUnit bottomWidth = computeBorderImageSide(ninePieceImage.borderSlices().bottom(), style.borderBottomWidth(), bottomSlice, borderImageRect.height());
    1290     LayoutUnit leftWidth = computeBorderImageSide(ninePieceImage.borderSlices().left(), style.borderLeftWidth(), leftSlice, borderImageRect.width());
    1291 
    1292     // Reduce the widths if they're too large.
    1293     // The spec says: Given Lwidth as the width of the border image area, Lheight as its height, and Wside as the border image width
    1294     // offset for the side, let f = min(Lwidth/(Wleft+Wright), Lheight/(Wtop+Wbottom)). If f < 1, then all W are reduced by
    1295     // multiplying them by f.
    1296     LayoutUnit borderSideWidth = std::max<LayoutUnit>(1 / deviceScaleFactor, leftWidth + rightWidth);
    1297     LayoutUnit borderSideHeight = std::max<LayoutUnit>(1 / deviceScaleFactor, topWidth + bottomWidth);
    1298     float borderSideScaleFactor = std::min((float)borderImageRect.width() / borderSideWidth, (float)borderImageRect.height() / borderSideHeight);
    1299     if (borderSideScaleFactor < 1) {
    1300         topWidth *= borderSideScaleFactor;
    1301         rightWidth *= borderSideScaleFactor;
    1302         bottomWidth *= borderSideScaleFactor;
    1303         leftWidth *= borderSideScaleFactor;
    1304     }
    1305 
    1306     bool drawLeft = leftSlice > 0 && leftWidth > 0;
    1307     bool drawTop = topSlice > 0 && topWidth > 0;
    1308     bool drawRight = rightSlice > 0 && rightWidth > 0;
    1309     bool drawBottom = bottomSlice > 0 && bottomWidth > 0;
    1310     bool drawMiddle = ninePieceImage.fill() && (imageWidth - leftSlice - rightSlice) > 0 && (borderImageRect.width() - leftWidth - rightWidth) > 0
    1311                       && (imageHeight - topSlice - bottomSlice) > 0 && (borderImageRect.height() - topWidth - bottomWidth) > 0;
    1312 
    1313     RefPtr<Image> image = styleImage->image(this, imageSize);
    1314     ColorSpace colorSpace = style.colorSpace();
    1315    
    1316     float destinationWidth = borderImageRect.width() - leftWidth - rightWidth;
    1317     float destinationHeight = borderImageRect.height() - topWidth - bottomWidth;
    1318    
    1319     float sourceWidth = imageWidth - leftSlice - rightSlice;
    1320     float sourceHeight = imageHeight - topSlice - bottomSlice;
    1321    
    1322     float leftSideScale = drawLeft ? (float)leftWidth / leftSlice : 1;
    1323     float rightSideScale = drawRight ? (float)rightWidth / rightSlice : 1;
    1324     float topSideScale = drawTop ? (float)topWidth / topSlice : 1;
    1325     float bottomSideScale = drawBottom ? (float)bottomWidth / bottomSlice : 1;
    1326 
    1327     float x = borderImageRect.location().x();
    1328     float y = borderImageRect.location().y();
    1329     if (drawLeft) {
    1330         // Paint the top and bottom left corners.
    1331 
    1332         // The top left corner rect is (tx, ty, leftWidth, topWidth)
    1333         // The rect to use from within the image is obtained from our slice, and is (0, 0, leftSlice, topSlice)
    1334         if (drawTop)
    1335             graphicsContext->drawImage(image.get(), colorSpace, snapRectToDevicePixels(x, y, leftWidth, topWidth, deviceScaleFactor),
    1336                 snapRectToDevicePixels(0, 0, leftSlice, topSlice, deviceScaleFactor), op);
    1337 
    1338         // The bottom left corner rect is (tx, ty + h - bottomWidth, leftWidth, bottomWidth)
    1339         // The rect to use from within the image is (0, imageHeight - bottomSlice, leftSlice, botomSlice)
    1340         if (drawBottom)
    1341             graphicsContext->drawImage(image.get(), colorSpace, snapRectToDevicePixels(x, borderImageRect.maxY() - bottomWidth, leftWidth, bottomWidth, deviceScaleFactor),
    1342                 snapRectToDevicePixels(0, imageHeight - bottomSlice, leftSlice, bottomSlice, deviceScaleFactor), op);
    1343 
    1344         // Paint the left edge.
    1345         // Have to scale and tile into the border rect.
    1346         if (sourceHeight > 0)
    1347             graphicsContext->drawTiledImage(image.get(), colorSpace, snapRectToDevicePixels(x, y + topWidth, leftWidth, destinationHeight, deviceScaleFactor),
    1348                 snapRectToDevicePixels(0, topSlice, leftSlice, sourceHeight, deviceScaleFactor), FloatSize(leftSideScale, leftSideScale), Image::StretchTile, (Image::TileRule)vRule, op);
    1349     }
    1350 
    1351     if (drawRight) {
    1352         // Paint the top and bottom right corners
    1353         // The top right corner rect is (tx + w - rightWidth, ty, rightWidth, topWidth)
    1354         // The rect to use from within the image is obtained from our slice, and is (imageWidth - rightSlice, 0, rightSlice, topSlice)
    1355         if (drawTop)
    1356             graphicsContext->drawImage(image.get(), colorSpace, snapRectToDevicePixels(borderImageRect.maxX() - rightWidth, y, rightWidth, topWidth, deviceScaleFactor),
    1357                 snapRectToDevicePixels(imageWidth - rightSlice, 0, rightSlice, topSlice, deviceScaleFactor), op);
    1358 
    1359         // The bottom right corner rect is (tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth)
    1360         // The rect to use from within the image is (imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice)
    1361         if (drawBottom)
    1362             graphicsContext->drawImage(image.get(), colorSpace, snapRectToDevicePixels(borderImageRect.maxX() - rightWidth, borderImageRect.maxY() - bottomWidth,
    1363                 rightWidth, bottomWidth, deviceScaleFactor), snapRectToDevicePixels(imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice, deviceScaleFactor),
    1364                 op);
    1365 
    1366         // Paint the right edge.
    1367         if (sourceHeight > 0)
    1368             graphicsContext->drawTiledImage(image.get(), colorSpace, snapRectToDevicePixels(borderImageRect.maxX() - rightWidth, y + topWidth, rightWidth, destinationHeight, deviceScaleFactor),
    1369                 snapRectToDevicePixels(imageWidth - rightSlice, topSlice, rightSlice, sourceHeight, deviceScaleFactor), FloatSize(rightSideScale, rightSideScale),
    1370                 Image::StretchTile, (Image::TileRule)vRule, op);
    1371     }
    1372 
    1373     // Paint the top edge.
    1374     if (drawTop && sourceWidth > 0)
    1375         graphicsContext->drawTiledImage(image.get(), colorSpace, snapRectToDevicePixels(x + leftWidth, y, destinationWidth, topWidth, deviceScaleFactor),
    1376             snapRectToDevicePixels(leftSlice, 0, sourceWidth, topSlice, deviceScaleFactor), FloatSize(topSideScale, topSideScale), (Image::TileRule)hRule, Image::StretchTile, op);
    1377 
    1378     // Paint the bottom edge.
    1379     if (drawBottom && sourceWidth > 0)
    1380         graphicsContext->drawTiledImage(image.get(), colorSpace, snapRectToDevicePixels(x + leftWidth, borderImageRect.maxY() - bottomWidth, destinationWidth, bottomWidth, deviceScaleFactor),
    1381             snapRectToDevicePixels(leftSlice, imageHeight - bottomSlice, sourceWidth, bottomSlice, deviceScaleFactor), FloatSize(bottomSideScale, bottomSideScale),
    1382             (Image::TileRule)hRule, Image::StretchTile, op);
    1383 
    1384     // Paint the middle.
    1385     if (drawMiddle) {
    1386         FloatSize middleScaleFactor(1, 1);
    1387         if (drawTop)
    1388             middleScaleFactor.setWidth(topSideScale);
    1389         else if (drawBottom)
    1390             middleScaleFactor.setWidth(bottomSideScale);
    1391         if (drawLeft)
    1392             middleScaleFactor.setHeight(leftSideScale);
    1393         else if (drawRight)
    1394             middleScaleFactor.setHeight(rightSideScale);
    1395            
    1396         // For "stretch" rules, just override the scale factor and replace. We only had to do this for the
    1397         // center tile, since sides don't even use the scale factor unless they have a rule other than "stretch".
    1398         // The middle however can have "stretch" specified in one axis but not the other, so we have to
    1399         // correct the scale here.
    1400         if (hRule == StretchImageRule)
    1401             middleScaleFactor.setWidth(destinationWidth / sourceWidth);
    1402            
    1403         if (vRule == StretchImageRule)
    1404             middleScaleFactor.setHeight(destinationHeight / sourceHeight);
    1405        
    1406         graphicsContext->drawTiledImage(image.get(), colorSpace,
    1407             snapRectToDevicePixels(x + leftWidth, y + topWidth, destinationWidth, destinationHeight, deviceScaleFactor),
    1408             snapRectToDevicePixels(leftSlice, topSlice, sourceWidth, sourceHeight, deviceScaleFactor),
    1409             middleScaleFactor, (Image::TileRule)hRule, (Image::TileRule)vRule, op);
    1410     }
    1411 
     1273    styleImage->setContainerSizeForRenderer(this, source, style.effectiveZoom());
     1274
     1275    ninePieceImage.paint(graphicsContext, this, style, destination, source, intrinsicSource, deviceScaleFactor, op);
    14121276    return true;
    14131277}
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.h

    r184395 r184895  
    290290
    291291    enum ScaleByEffectiveZoomOrNot { ScaleByEffectiveZoom, DoNotScaleByEffectiveZoom };
    292     LayoutSize calculateImageIntrinsicDimensions(StyleImage*, const LayoutSize& scaledPositioningAreaSize, ScaleByEffectiveZoomOrNot) const;
     292    bool calculateImageIntrinsicDimensions(StyleImage*, const LayoutSize& scaledPositioningAreaSize, ScaleByEffectiveZoomOrNot, LayoutSize& imageSize) const;
    293293
    294294private:
  • trunk/Source/WebCore/rendering/RenderListMarker.cpp

    r182751 r184895  
    14271427        LayoutUnit bulletWidth = style().fontMetrics().ascent() / LayoutUnit(2);
    14281428        LayoutSize defaultBulletSize(bulletWidth, bulletWidth);
    1429         LayoutSize imageSize = calculateImageIntrinsicDimensions(m_image.get(), defaultBulletSize, DoNotScaleByEffectiveZoom);
     1429        LayoutSize imageSize;
     1430        calculateImageIntrinsicDimensions(m_image.get(), defaultBulletSize, DoNotScaleByEffectiveZoom, imageSize);
    14301431        m_image->setContainerSizeForRenderer(this, imageSize, style().effectiveZoom());
    14311432        return;
  • trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp

    r182560 r184895  
    149149std::unique_ptr<Shape> ShapeOutsideInfo::createShapeForImage(StyleImage* styleImage, float shapeImageThreshold, WritingMode writingMode, float margin) const
    150150{
    151     const LayoutSize& imageSize = m_renderer.calculateImageIntrinsicDimensions(styleImage, m_referenceBoxLogicalSize, RenderImage::ScaleByEffectiveZoom);
     151    LayoutSize imageSize;
     152    m_renderer.calculateImageIntrinsicDimensions(styleImage, m_referenceBoxLogicalSize, RenderImage::ScaleByEffectiveZoom, imageSize);
    152153    styleImage->setContainerSizeForRenderer(&m_renderer, imageSize, m_renderer.style().effectiveZoom());
    153154
  • trunk/Source/WebCore/rendering/style/BorderData.h

    r182197 r184895  
    9393        return m_bottom.width();
    9494    }
     95
     96    FloatBoxExtent borderWidth() const
     97    {
     98        return FloatBoxExtent(borderTopWidth(), borderRightWidth(), borderBottomWidth(), borderLeftWidth());
     99    }
    95100   
    96101    bool operator==(const BorderData& o) const
  • trunk/Source/WebCore/rendering/style/NinePieceImage.cpp

    r177259 r184895  
    33 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2000 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
     5 * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2013, 2015 Apple Inc. All rights reserved.
    66 *
    77 * This library is free software; you can redistribute it and/or
     
    2424#include "config.h"
    2525#include "NinePieceImage.h"
     26
     27#include "GraphicsContext.h"
     28#include "LengthFunctions.h"
     29#include "RenderStyle.h"
    2630#include <wtf/NeverDestroyed.h>
    2731
     
    5155}
    5256
     57LayoutUnit NinePieceImage::computeSlice(Length length, LayoutUnit width, LayoutUnit slice, LayoutUnit extent)
     58{
     59    if (length.isRelative())
     60        return length.value() * width;
     61    if (length.isAuto())
     62        return slice;
     63    return valueForLength(length, extent);
     64}
     65
     66LayoutBoxExtent NinePieceImage::computeSlices(const LayoutSize& size, const LengthBox& lengths, int scaleFactor)
     67{
     68    LayoutUnit top    = std::min<LayoutUnit>(size.height(), valueForLength(lengths.top(),    size.height())) * scaleFactor;
     69    LayoutUnit right  = std::min<LayoutUnit>(size.width(),  valueForLength(lengths.right(),  size.width()))  * scaleFactor;
     70    LayoutUnit bottom = std::min<LayoutUnit>(size.height(), valueForLength(lengths.bottom(), size.height())) * scaleFactor;
     71    LayoutUnit left   = std::min<LayoutUnit>(size.width(),  valueForLength(lengths.left(),   size.width()))  * scaleFactor;
     72    return LayoutBoxExtent(top, right, bottom, left);
     73}
     74
     75LayoutBoxExtent NinePieceImage::computeSlices(const LayoutSize& size, const LengthBox& lengths, const FloatBoxExtent& widths, const LayoutBoxExtent& slices)
     76{
     77    LayoutUnit top    = computeSlice(lengths.top(),    widths.top(),    slices.top(),    size.height());
     78    LayoutUnit right  = computeSlice(lengths.right(),  widths.right(),  slices.right(),  size.width());
     79    LayoutUnit bottom = computeSlice(lengths.bottom(), widths.bottom(), slices.bottom(), size.height());
     80    LayoutUnit left   = computeSlice(lengths.left(),   widths.left(),   slices.left(),   size.width());
     81    return LayoutBoxExtent(top, right, bottom, left);
     82}
     83
     84void NinePieceImage::scaleSlicesIfNeeded(const LayoutSize& size, LayoutBoxExtent& slices, int scaleFactor)
     85{
     86    LayoutUnit width  = std::max<LayoutUnit>(1 / scaleFactor, slices.left() + slices.right());
     87    LayoutUnit height = std::max<LayoutUnit>(1 / scaleFactor, slices.top() + slices.bottom());
     88
     89    float sliceScaleFactor = std::min((float)size.width() / width, (float)size.height() / height);
     90
     91    if (sliceScaleFactor >= 1)
     92        return;
     93
     94    // All slices are reduced by multiplying them by sliceScaleFactor.
     95    slices.top()    *= sliceScaleFactor;
     96    slices.right()  *= sliceScaleFactor;
     97    slices.bottom() *= sliceScaleFactor;
     98    slices.left()   *= sliceScaleFactor;
     99}
     100
     101bool NinePieceImage::isEmptyPieceRect(ImagePiece piece, const LayoutBoxExtent& slices)
     102{
     103    if (piece == MiddlePiece)
     104        return false;
     105
     106    PhysicalBoxSide horizontalSide = imagePieceHorizontalSide(piece);
     107    PhysicalBoxSide verticalSide = imagePieceVerticalSide(piece);
     108    return !((horizontalSide == NilSide || slices.at(horizontalSide)) && (verticalSide == NilSide || slices.at(verticalSide)));
     109}
     110
     111bool NinePieceImage::isEmptyPieceRect(ImagePiece piece, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects)
     112{
     113    return destinationRects[piece].isEmpty() || sourceRects[piece].isEmpty();
     114}
     115
     116Vector<FloatRect> NinePieceImage::computeIntrinsicRects(const FloatRect& outer, const LayoutBoxExtent& slices, float deviceScaleFactor)
     117{
     118    FloatRect inner = outer;
     119    inner.move(slices.left(), slices.top());
     120    inner.contract(slices.left() + slices.right(), slices.top() + slices.bottom());
     121    ASSERT(outer.contains(inner));
     122
     123    Vector<FloatRect> rects(MaxPiece);
     124
     125    rects[TopLeftPiece]     = snapRectToDevicePixels(outer.x(),    outer.y(),    slices.left(),  slices.top(),    deviceScaleFactor);
     126    rects[BottomLeftPiece]  = snapRectToDevicePixels(outer.x(),    inner.maxY(), slices.left(),  slices.bottom(), deviceScaleFactor);
     127    rects[LeftPiece]        = snapRectToDevicePixels(outer.x(),    inner.y(),    slices.left(),  inner.height(),  deviceScaleFactor);
     128
     129    rects[TopRightPiece]    = snapRectToDevicePixels(inner.maxX(), outer.y(),    slices.right(), slices.top(),    deviceScaleFactor);
     130    rects[BottomRightPiece] = snapRectToDevicePixels(inner.maxX(), inner.maxY(), slices.right(), slices.bottom(), deviceScaleFactor);
     131    rects[RightPiece]       = snapRectToDevicePixels(inner.maxX(), inner.y(),    slices.right(), inner.height(),  deviceScaleFactor);
     132
     133    rects[TopPiece]         = snapRectToDevicePixels(inner.x(),    outer.y(),    inner.width(),  slices.top(),    deviceScaleFactor);
     134    rects[BottomPiece]      = snapRectToDevicePixels(inner.x(),    inner.maxY(), inner.width(),  slices.bottom(), deviceScaleFactor);
     135
     136    rects[MiddlePiece]      = snapRectToDevicePixels(inner.x(),    inner.y(),    inner.width(),  inner.height(),  deviceScaleFactor);
     137    return rects;
     138}
     139
     140Vector<FloatRect> NinePieceImage::computeNonIntrinsicRects(const Vector<FloatRect>& intrinsicRects, const LayoutBoxExtent& slices)
     141{
     142    Vector<FloatRect> rects(MaxPiece);
     143
     144    for (ImagePiece piece = MinPiece; piece < MaxPiece; ++piece) {
     145        if (isEmptyPieceRect(piece, slices))
     146            continue;
     147        rects[piece] = FloatRect(FloatPoint(), intrinsicRects[piece].size());
     148    }
     149
     150    return rects;
     151}
     152
     153FloatSize NinePieceImage::computeIntrinsicSideTileScale(ImagePiece piece, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects)
     154{
     155    ASSERT(!isCornerPiece(piece) && !isMiddlePiece(piece));
     156    if (isEmptyPieceRect(piece, destinationRects, sourceRects))
     157        return FloatSize(1, 1);
     158
     159    float scale;
     160    if (isVerticalPiece(piece))
     161        scale = destinationRects[piece].height() / sourceRects[piece].height();
     162    else
     163        scale = destinationRects[piece].width() / sourceRects[piece].width();
     164
     165    return FloatSize(scale, scale);
     166}
     167
     168FloatSize NinePieceImage::computeIntrinsicMiddleTileScale(const Vector<FloatSize>& scales, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects, ENinePieceImageRule hRule, ENinePieceImageRule vRule)
     169{
     170    FloatSize scale(1, 1);
     171    if (isEmptyPieceRect(MiddlePiece, destinationRects, sourceRects))
     172        return scale;
     173
     174    // Unlike the side pieces, the middle piece can have "stretch" specified in one axis but not the other.
     175    // In fact the side pieces don't even use the scale factor unless they have a rule other than "stretch".
     176    if (hRule == StretchImageRule)
     177        scale.setWidth(destinationRects[MiddlePiece].width() / sourceRects[MiddlePiece].width());
     178    else if (!isEmptyPieceRect(TopPiece, destinationRects, sourceRects))
     179        scale.setWidth(scales[TopPiece].width());
     180    else if (!isEmptyPieceRect(BottomPiece, destinationRects, sourceRects))
     181        scale.setWidth(scales[BottomPiece].width());
     182
     183    if (vRule == StretchImageRule)
     184        scale.setHeight(destinationRects[MiddlePiece].height() / sourceRects[MiddlePiece].height());
     185    else if (!isEmptyPieceRect(LeftPiece, destinationRects, sourceRects))
     186        scale.setHeight(scales[LeftPiece].height());
     187    else if (!isEmptyPieceRect(RightPiece, destinationRects, sourceRects))
     188        scale.setHeight(scales[RightPiece].height());
     189
     190    return scale;
     191}
     192
     193Vector<FloatSize> NinePieceImage::computeIntrinsicTileScales(const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects, ENinePieceImageRule hRule, ENinePieceImageRule vRule)
     194{
     195    Vector<FloatSize> scales(MaxPiece, FloatSize(1, 1));
     196
     197    scales[TopPiece]    = computeIntrinsicSideTileScale(TopPiece,    destinationRects, sourceRects);
     198    scales[RightPiece]  = computeIntrinsicSideTileScale(RightPiece,  destinationRects, sourceRects);
     199    scales[BottomPiece] = computeIntrinsicSideTileScale(BottomPiece, destinationRects, sourceRects);
     200    scales[LeftPiece]   = computeIntrinsicSideTileScale(LeftPiece,   destinationRects, sourceRects);
     201
     202    scales[MiddlePiece] = computeIntrinsicMiddleTileScale(scales, destinationRects, sourceRects, hRule, vRule);
     203    return scales;
     204}
     205
     206Vector<FloatSize> NinePieceImage::computeNonIntrinsicTileScales()
     207{
     208    return Vector<FloatSize>(MaxPiece, FloatSize(1, 1));
     209}
     210
     211void NinePieceImage::paint(GraphicsContext* graphicsContext, RenderElement* renderer, const RenderStyle& style, const LayoutRect& destination, const LayoutSize& source,  bool intrinsicSource, float deviceScaleFactor, CompositeOperator op) const
     212{
     213    StyleImage* styleImage = image();
     214    ASSERT(styleImage && styleImage->isLoaded());
     215
     216    LayoutBoxExtent sourceSlices = computeSlices(source, imageSlices(), styleImage->imageScaleFactor());
     217    LayoutBoxExtent destinationSlices = computeSlices(destination.size(), borderSlices(), style.borderWidth(), sourceSlices);
     218
     219    scaleSlicesIfNeeded(destination.size(), destinationSlices, deviceScaleFactor);
     220
     221    Vector<FloatRect> destinationRects = computeIntrinsicRects(destination, destinationSlices, deviceScaleFactor);
     222    Vector<FloatRect> sourceRects;
     223    Vector<FloatSize> tileScales;
     224
     225    if (intrinsicSource) {
     226        sourceRects = computeIntrinsicRects(FloatRect(FloatPoint(), source), sourceSlices, deviceScaleFactor);
     227        tileScales = computeIntrinsicTileScales(destinationRects, sourceRects, horizontalRule(), verticalRule());
     228    } else {
     229        sourceRects = computeNonIntrinsicRects(destinationRects, sourceSlices);
     230        tileScales = computeNonIntrinsicTileScales();
     231    }
     232
     233    RefPtr<Image> image = styleImage->image(renderer, source);
     234    ColorSpace colorSpace = style.colorSpace();
     235
     236    for (ImagePiece piece = MinPiece; piece < MaxPiece; ++piece) {
     237        if ((piece == MiddlePiece && !fill()) || isEmptyPieceRect(piece, destinationRects, sourceRects))
     238            continue;
     239
     240        if (isCornerPiece(piece)) {
     241            graphicsContext->drawImage(image.get(), colorSpace, destinationRects[piece], sourceRects[piece], op);
     242            continue;
     243        }
     244
     245        Image::TileRule hRule = isHorizontalPiece(piece) ? static_cast<Image::TileRule>(horizontalRule()) : Image::StretchTile;
     246        Image::TileRule vRule = isVerticalPiece(piece) ? static_cast<Image::TileRule>(verticalRule()) : Image::StretchTile;
     247        graphicsContext->drawTiledImage(image.get(), colorSpace, destinationRects[piece], sourceRects[piece], tileScales[piece], hRule, vRule, op);
     248    }
     249}
     250
    53251NinePieceImageData::NinePieceImageData()
    54252    : fill(false)
    55253    , horizontalRule(StretchImageRule)
    56254    , verticalRule(StretchImageRule)
    57     , image(0)
     255    , image(nullptr)
    58256    , imageSlices(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent))
    59257    , borderSlices(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative))
  • trunk/Source/WebCore/rendering/style/NinePieceImage.h

    r177259 r184895  
    33 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2000 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
     5 * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2013, 2015 Apple Inc. All rights reserved.
    66 *
    77 * This library is free software; you can redistribute it and/or
     
    2626
    2727#include "DataRef.h"
     28#include "LayoutRect.h"
     29#include "LayoutSize.h"
    2830#include "LayoutUnit.h"
    2931#include "LengthBox.h"
    3032#include "StyleImage.h"
     33#include <wtf/Vector.h>
    3134
    3235namespace WebCore {
     
    3538    StretchImageRule, RoundImageRule, SpaceImageRule, RepeatImageRule
    3639};
     40
     41enum ImagePiece {
     42    MinPiece = 0,
     43    TopLeftPiece = MinPiece,
     44    LeftPiece,
     45    BottomLeftPiece,
     46    TopRightPiece,
     47    RightPiece,
     48    BottomRightPiece,
     49    TopPiece,
     50    BottomPiece,
     51    MiddlePiece,
     52    MaxPiece
     53};
     54
     55inline ImagePiece& operator++(ImagePiece& piece)
     56{
     57    piece = static_cast<ImagePiece>(static_cast<int>(piece) + 1);
     58    return piece;
     59}
     60
     61inline bool isCornerPiece(ImagePiece piece)
     62{
     63    return piece == TopLeftPiece || piece == TopRightPiece || piece == BottomLeftPiece || piece == BottomRightPiece;
     64}
     65
     66inline bool isMiddlePiece(ImagePiece piece)
     67{
     68    return piece == MiddlePiece;
     69}
     70
     71inline bool isHorizontalPiece(ImagePiece piece)
     72{
     73    return piece == TopPiece || piece == BottomPiece || piece == MiddlePiece;
     74}
     75
     76inline bool isVerticalPiece(ImagePiece piece)
     77{
     78    return piece == LeftPiece || piece == RightPiece || piece == MiddlePiece;
     79}
     80
     81inline PhysicalBoxSide imagePieceHorizontalSide(ImagePiece piece)
     82{
     83    if (piece == TopLeftPiece || piece == TopPiece || piece == TopRightPiece)
     84        return TopSide;
     85
     86    if (piece == BottomLeftPiece || piece == BottomPiece || piece == BottomRightPiece)
     87        return BottomSide;
     88
     89    return NilSide;
     90}
     91
     92inline PhysicalBoxSide imagePieceVerticalSide(ImagePiece piece)
     93{
     94    if (piece == TopLeftPiece || piece == LeftPiece || piece == BottomLeftPiece)
     95        return LeftSide;
     96
     97    if (piece == TopRightPiece || piece == RightPiece || piece == BottomRightPiece)
     98        return RightSide;
     99
     100    return NilSide;
     101}
     102
     103class RenderStyle;
    37104
    38105class NinePieceImageData : public RefCounted<NinePieceImageData> {
     
    123190    }
    124191
     192    static LayoutUnit computeSlice(Length, LayoutUnit width, LayoutUnit slice, LayoutUnit extent);
     193    static LayoutBoxExtent computeSlices(const LayoutSize&, const LengthBox& lengths, int scaleFactor);
     194    static LayoutBoxExtent computeSlices(const LayoutSize&, const LengthBox& lengths, const FloatBoxExtent& widths, const LayoutBoxExtent& slices);
     195
     196    static bool isEmptyPieceRect(ImagePiece, const LayoutBoxExtent& slices);
     197    static bool isEmptyPieceRect(ImagePiece, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects);
     198
     199    static Vector<FloatRect> computeIntrinsicRects(const FloatRect& outer, const LayoutBoxExtent& slices, float deviceScaleFactor);
     200    static Vector<FloatRect> computeNonIntrinsicRects(const Vector<FloatRect>& intrinsicRects, const LayoutBoxExtent& slices);
     201
     202    static void scaleSlicesIfNeeded(const LayoutSize&, LayoutBoxExtent& slices, int scaleFactor);
     203
     204    static FloatSize computeIntrinsicSideTileScale(ImagePiece, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects);
     205    static FloatSize computeIntrinsicMiddleTileScale(const Vector<FloatSize>& scales, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects, ENinePieceImageRule hRule, ENinePieceImageRule vRule);
     206    static Vector<FloatSize> computeIntrinsicTileScales(const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects, ENinePieceImageRule hRule, ENinePieceImageRule vRule);
     207    static Vector<FloatSize> computeNonIntrinsicTileScales();
     208
     209    void paint(GraphicsContext*, RenderElement*, const RenderStyle&, const LayoutRect& destination, const LayoutSize& source, bool intrinsicSource, float deviceScaleFactor, CompositeOperator) const;
     210
    125211private:
    126212    DataRef<NinePieceImageData> m_data;
  • trunk/Source/WebCore/rendering/style/RenderStyle.cpp

    r184055 r184895  
    922922{
    923923    StyleVisualData* data = visual.access();
    924     data->clip.m_top = top;
    925     data->clip.m_right = right;
    926     data->clip.m_bottom = bottom;
    927     data->clip.m_left = left;
     924    data->clip.top() = top;
     925    data->clip.right() = right;
     926    data->clip.bottom() = bottom;
     927    data->clip.left() = left;
    928928}
    929929
     
    13101310        StyleDashboardRegion region;
    13111311        region.label = "";
    1312         region.offset.m_top  = Length();
    1313         region.offset.m_right = Length();
    1314         region.offset.m_bottom = Length();
    1315         region.offset.m_left = Length();
     1312        region.offset.top()  = Length();
     1313        region.offset.right() = Length();
     1314        region.offset.bottom() = Length();
     1315        region.offset.left() = Length();
    13161316        region.type = StyleDashboardRegion::None;
    13171317        noneList.append(region);
  • trunk/Source/WebCore/rendering/style/RenderStyle.h

    r183906 r184895  
    3838#include "FontDescription.h"
    3939#include "GraphicsTypes.h"
    40 #include "LayoutBoxExtent.h"
    4140#include "Length.h"
    4241#include "LengthBox.h"
     
    532531    bool operator!=(const RenderStyle& other) const { return !(*this == other); }
    533532    bool isFloating() const { return noninherited_flags.isFloating(); }
    534     bool hasMargin() const { return surround->margin.nonZero(); }
     533    bool hasMargin() const { return !surround->margin.isZero(); }
    535534    bool hasBorder() const { return surround->border.hasBorder(); }
    536535    bool hasBorderFill() const { return surround->border.hasFill(); }
    537536    bool hasBorderDecoration() const { return hasBorder() || hasBorderFill(); }
    538     bool hasPadding() const { return surround->padding.nonZero(); }
    539     bool hasOffset() const { return surround->offset.nonZero(); }
     537    bool hasPadding() const { return !surround->padding.isZero(); }
     538    bool hasOffset() const { return !surround->offset.isZero(); }
    540539    bool hasMarginBeforeQuirk() const { return marginBefore().hasQuirk(); }
    541540    bool hasMarginAfterQuirk() const { return marginAfter().hasQuirk(); }
     
    559558    bool hasBorderImageOutsets() const
    560559    {
    561         return borderImage().hasImage() && borderImage().outset().nonZero();
     560        return borderImage().hasImage() && !borderImage().outset().isZero();
    562561    }
    563562    LayoutBoxExtent borderImageOutsets() const
     
    596595
    597596    // Accessors for positioned object edges that take into account writing mode.
    598     const Length& logicalLeft() const { return surround->offset.logicalLeft(writingMode()); }
    599     const Length& logicalRight() const { return surround->offset.logicalRight(writingMode()); }
     597    const Length& logicalLeft() const { return surround->offset.start(writingMode()); }
     598    const Length& logicalRight() const { return surround->offset.end(writingMode()); }
    600599    const Length& logicalTop() const { return surround->offset.before(writingMode()); }
    601600    const Length& logicalBottom() const { return surround->offset.after(writingMode()); }
     
    663662    EBorderStyle borderBottomStyle() const { return surround->border.bottom().style(); }
    664663    bool borderBottomIsTransparent() const { return surround->border.bottom().isTransparent(); }
    665    
     664    FloatBoxExtent borderWidth() const { return surround->border.borderWidth(); }
     665
    666666    float borderBeforeWidth() const;
    667667    float borderAfterWidth() const;
     
    12011201    void setFloating(EFloat v) { noninherited_flags.setFloating(v); }
    12021202
    1203     void setLeft(Length v) { SET_VAR(surround, offset.m_left, WTF::move(v)); }
    1204     void setRight(Length v) { SET_VAR(surround, offset.m_right, WTF::move(v)); }
    1205     void setTop(Length v) { SET_VAR(surround, offset.m_top, WTF::move(v)); }
    1206     void setBottom(Length v) { SET_VAR(surround, offset.m_bottom, WTF::move(v)); }
     1203    void setLeft(Length v) { SET_VAR(surround, offset.left(), WTF::move(v)); }
     1204    void setRight(Length v) { SET_VAR(surround, offset.right(), WTF::move(v)); }
     1205    void setTop(Length v) { SET_VAR(surround, offset.top(), WTF::move(v)); }
     1206    void setBottom(Length v) { SET_VAR(surround, offset.bottom(), WTF::move(v)); }
    12071207
    12081208    void setWidth(Length v) { SET_VAR(m_box, m_width, WTF::move(v)); }
     
    12401240        StyleDashboardRegion region;
    12411241        region.label = label;
    1242         region.offset.m_top = WTF::move(t);
    1243         region.offset.m_right = WTF::move(r);
    1244         region.offset.m_bottom = WTF::move(b);
    1245         region.offset.m_left = WTF::move(l);
     1242        region.offset.top() = WTF::move(t);
     1243        region.offset.right() = WTF::move(r);
     1244        region.offset.bottom() = WTF::move(b);
     1245        region.offset.left() = WTF::move(l);
    12461246        region.type = type;
    12471247        if (!append)
     
    13241324
    13251325    void setHasClip(bool b = true) { SET_VAR(visual, hasClip, b); }
    1326     void setClipLeft(Length length) { SET_VAR(visual, clip.m_left, WTF::move(length)); }
    1327     void setClipRight(Length length) { SET_VAR(visual, clip.m_right, WTF::move(length)); }
    1328     void setClipTop(Length length) { SET_VAR(visual, clip.m_top, WTF::move(length)); }
    1329     void setClipBottom(Length length) { SET_VAR(visual, clip.m_bottom, WTF::move(length)); }
     1326    void setClipLeft(Length length) { SET_VAR(visual, clip.left(), WTF::move(length)); }
     1327    void setClipRight(Length length) { SET_VAR(visual, clip.right(), WTF::move(length)); }
     1328    void setClipTop(Length length) { SET_VAR(visual, clip.top(), WTF::move(length)); }
     1329    void setClipBottom(Length length) { SET_VAR(visual, clip.bottom(), WTF::move(length)); }
    13301330    void setClip(Length top, Length right, Length bottom, Length left);
    13311331    void setClip(LengthBox box) { SET_VAR(visual, clip, WTF::move(box)); }
     
    14351435
    14361436    void resetMargin() { SET_VAR(surround, margin, LengthBox(Fixed)); }
    1437     void setMarginTop(Length length) { SET_VAR(surround, margin.m_top, WTF::move(length)); }
    1438     void setMarginBottom(Length length) { SET_VAR(surround, margin.m_bottom, WTF::move(length)); }
    1439     void setMarginLeft(Length length) { SET_VAR(surround, margin.m_left, WTF::move(length)); }
    1440     void setMarginRight(Length length) { SET_VAR(surround, margin.m_right, WTF::move(length)); }
     1437    void setMarginTop(Length length) { SET_VAR(surround, margin.top(), WTF::move(length)); }
     1438    void setMarginBottom(Length length) { SET_VAR(surround, margin.bottom(), WTF::move(length)); }
     1439    void setMarginLeft(Length length) { SET_VAR(surround, margin.left(), WTF::move(length)); }
     1440    void setMarginRight(Length length) { SET_VAR(surround, margin.right(), WTF::move(length)); }
    14411441    void setMarginStart(Length);
    14421442    void setMarginEnd(Length);
     
    14441444    void resetPadding() { SET_VAR(surround, padding, LengthBox(Auto)); }
    14451445    void setPaddingBox(LengthBox box) { SET_VAR(surround, padding, WTF::move(box)); }
    1446     void setPaddingTop(Length length) { SET_VAR(surround, padding.m_top, WTF::move(length)); }
    1447     void setPaddingBottom(Length length) { SET_VAR(surround, padding.m_bottom, WTF::move(length)); }
    1448     void setPaddingLeft(Length length) { SET_VAR(surround, padding.m_left, WTF::move(length)); }
    1449     void setPaddingRight(Length length) { SET_VAR(surround, padding.m_right, WTF::move(length)); }
     1446    void setPaddingTop(Length length) { SET_VAR(surround, padding.top(), WTF::move(length)); }
     1447    void setPaddingBottom(Length length) { SET_VAR(surround, padding.bottom(), WTF::move(length)); }
     1448    void setPaddingLeft(Length length) { SET_VAR(surround, padding.left(), WTF::move(length)); }
     1449    void setPaddingRight(Length length) { SET_VAR(surround, padding.right(), WTF::move(length)); }
    14501450
    14511451    void setCursor(ECursor c) { inherited_flags._cursor_style = c; }
Note: See TracChangeset for help on using the changeset viewer.