Changeset 252161 in webkit


Ignore:
Timestamp:
Nov 6, 2019 4:39:24 PM (4 years ago)
Author:
Simon Fraser
Message:

Box-shadow spread radius does not transition or animate correctly with CSS Transitions & Animations
https://bugs.webkit.org/show_bug.cgi?id=202489

Reviewed by Zalan Bujtas.
Source/WebCore:

Fix box-shadow offset and spread to support subpixel values, and make the rendering subpixel-aware.
This also makes animation of shadow spread and offset be smoother on Retina displays.

Also make ShadowStyle an enum class.

Test: fast/box-shadow/hidpi-box-shadow.html

  • css/CSSComputedStyleDeclaration.cpp:

(WebCore::ComputedStyleExtractor::valueForShadow):
(WebCore::ComputedStyleExtractor::valueForFilter):

  • css/CSSPrimitiveValue.cpp:

(WebCore::CSSPrimitiveValue::computeLength const):

  • page/animation/CSSPropertyAnimation.cpp:

(WebCore::blendFunc):
(WebCore::shadowForBlending):

  • platform/animation/AnimationUtilities.h:

(WebCore::blend):

  • platform/graphics/RoundedRect.h:
  • rendering/InlineFlowBox.cpp:

(WebCore::InlineFlowBox::paintBoxDecorations):

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::paintBoxDecorations):

  • rendering/RenderBoxModelObject.cpp:

(WebCore::applyBoxShadowForBackground):
(WebCore::RenderBoxModelObject::boxShadowShouldBeAppliedToBackground const):
(WebCore::areaCastingShadowInHole):
(WebCore::RenderBoxModelObject::paintBoxShadow):
Move the snapping until after we've adjusted rects for offset and spread. The "extraOffset"
computation makes the snapping a little more complex; we have to snap before and after applying
shadowOffset, and give to GraphicsContext the delta between the snapped values.

  • rendering/RenderTable.cpp:

(WebCore::RenderTable::paintBoxDecorations):

  • rendering/RenderTableCell.cpp:

(WebCore::RenderTableCell::paintBoxDecorations):

  • rendering/style/RenderStyle.cpp:

(WebCore::RenderStyle::setTextShadow):
(WebCore::RenderStyle::getShadowExtent const):
(WebCore::RenderStyle::getShadowInsetExtent const):
(WebCore::RenderStyle::getShadowHorizontalExtent const):
(WebCore::RenderStyle::getShadowVerticalExtent const):

  • rendering/style/ShadowData.cpp:

(WebCore::ShadowData::ShadowData):
(WebCore::calculateShadowExtent):
(WebCore::ShadowData::adjustRectForShadow const):

  • rendering/style/ShadowData.h:

(WebCore::ShadowData::ShadowData):
(WebCore::ShadowData::x const):
(WebCore::ShadowData::y const):
(WebCore::ShadowData::location const):
(WebCore::ShadowData::paintingExtent const):
(WebCore::ShadowData::spread const):

  • style/StyleBuilderCustom.h:

(WebCore::Style::BuilderCustom::applyTextOrBoxShadowValue):

LayoutTests:

  • fast/box-shadow/hidpi-box-shadow-expected.html: Added.
  • fast/box-shadow/hidpi-box-shadow.html: Added.
Location:
trunk
Files:
2 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r252156 r252161  
    615615        https://bugs.webkit.org/show_bug.cgi?id=203089
    616616        https://trac.webkit.org/changeset/251993
     617
     6182019-11-06  Simon Fraser  <simon.fraser@apple.com>
     619
     620        Box-shadow spread radius does not transition or animate correctly with CSS Transitions & Animations
     621        https://bugs.webkit.org/show_bug.cgi?id=202489
     622
     623        Reviewed by Zalan Bujtas.
     624
     625        * fast/box-shadow/hidpi-box-shadow-expected.html: Added.
     626        * fast/box-shadow/hidpi-box-shadow.html: Added.
    617627
    6186282019-11-04  Chris Dumez  <cdumez@apple.com>
  • trunk/Source/WebCore/ChangeLog

    r252156 r252161  
    810810        (WebCore::WebAnimation::hasPendingActivity const):
    811811        * animation/WebAnimation.h:
     812
     8132019-11-06  Simon Fraser  <simon.fraser@apple.com>
     814
     815        Box-shadow spread radius does not transition or animate correctly with CSS Transitions & Animations
     816        https://bugs.webkit.org/show_bug.cgi?id=202489
     817
     818        Reviewed by Zalan Bujtas.
     819       
     820        Fix box-shadow offset and spread to support subpixel values, and make the rendering subpixel-aware.
     821        This also makes animation of shadow spread and offset be smoother on Retina displays.
     822
     823        Also make ShadowStyle an enum class.
     824
     825        Test: fast/box-shadow/hidpi-box-shadow.html
     826
     827        * css/CSSComputedStyleDeclaration.cpp:
     828        (WebCore::ComputedStyleExtractor::valueForShadow):
     829        (WebCore::ComputedStyleExtractor::valueForFilter):
     830        * css/CSSPrimitiveValue.cpp:
     831        (WebCore::CSSPrimitiveValue::computeLength const):
     832        * page/animation/CSSPropertyAnimation.cpp:
     833        (WebCore::blendFunc):
     834        (WebCore::shadowForBlending):
     835        * platform/animation/AnimationUtilities.h:
     836        (WebCore::blend):
     837        * platform/graphics/RoundedRect.h:
     838        * rendering/InlineFlowBox.cpp:
     839        (WebCore::InlineFlowBox::paintBoxDecorations):
     840        * rendering/RenderBox.cpp:
     841        (WebCore::RenderBox::paintBoxDecorations):
     842        * rendering/RenderBoxModelObject.cpp:
     843        (WebCore::applyBoxShadowForBackground):
     844        (WebCore::RenderBoxModelObject::boxShadowShouldBeAppliedToBackground const):
     845        (WebCore::areaCastingShadowInHole):
     846        (WebCore::RenderBoxModelObject::paintBoxShadow):
     847        Move the snapping until after we've adjusted rects for offset and spread. The "extraOffset"
     848        computation makes the snapping a little more complex; we have to snap before and after applying
     849        shadowOffset, and give to GraphicsContext the delta between the snapped values.
     850        * rendering/RenderTable.cpp:
     851        (WebCore::RenderTable::paintBoxDecorations):
     852        * rendering/RenderTableCell.cpp:
     853        (WebCore::RenderTableCell::paintBoxDecorations):
     854        * rendering/style/RenderStyle.cpp:
     855        (WebCore::RenderStyle::setTextShadow):
     856        (WebCore::RenderStyle::getShadowExtent const):
     857        (WebCore::RenderStyle::getShadowInsetExtent const):
     858        (WebCore::RenderStyle::getShadowHorizontalExtent const):
     859        (WebCore::RenderStyle::getShadowVerticalExtent const):
     860        * rendering/style/ShadowData.cpp:
     861        (WebCore::ShadowData::ShadowData):
     862        (WebCore::calculateShadowExtent):
     863        (WebCore::ShadowData::adjustRectForShadow const):
     864        * rendering/style/ShadowData.h:
     865        (WebCore::ShadowData::ShadowData):
     866        (WebCore::ShadowData::x const):
     867        (WebCore::ShadowData::y const):
     868        (WebCore::ShadowData::location const):
     869        (WebCore::ShadowData::paintingExtent const):
     870        (WebCore::ShadowData::spread const):
     871        * style/StyleBuilderCustom.h:
     872        (WebCore::Style::BuilderCustom::applyTextOrBoxShadowValue):
    812873
    8138742019-11-04  Chris Dumez  <cdumez@apple.com>
  • trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp

    r252076 r252161  
    614614        auto blur = adjustLengthForZoom(currShadowData->radius(), style, adjust);
    615615        auto spread = propertyID == CSSPropertyTextShadow ? RefPtr<CSSPrimitiveValue>() : adjustLengthForZoom(currShadowData->spread(), style, adjust);
    616         auto style = propertyID == CSSPropertyTextShadow || currShadowData->style() == Normal ? RefPtr<CSSPrimitiveValue>() : cssValuePool.createIdentifierValue(CSSValueInset);
     616        auto style = propertyID == CSSPropertyTextShadow || currShadowData->style() == ShadowStyle::Normal ? RefPtr<CSSPrimitiveValue>() : cssValuePool.createIdentifierValue(CSSValueInset);
    617617        auto color = cssValuePool.createColorValue(currShadowData->color());
    618618        list->prepend(CSSShadowValue::create(WTFMove(x), WTFMove(y), WTFMove(blur), WTFMove(spread), WTFMove(style), WTFMove(color)));
     
    692692                filterValue = CSSFunctionValue::create(CSSValueDropShadow);
    693693                // We want our computed style to look like that of a text shadow (has neither spread nor inset style).
    694                 ShadowData shadowData = ShadowData(dropShadowOperation.location(), dropShadowOperation.stdDeviation(), 0, Normal, false, dropShadowOperation.color());
     694                ShadowData shadowData = ShadowData(dropShadowOperation.location(), dropShadowOperation.stdDeviation(), 0, ShadowStyle::Normal, false, dropShadowOperation.color());
    695695                filterValue->append(valueForShadow(&shadowData, CSSPropertyTextShadow, style, adjust));
    696696                break;
  • trunk/Source/WebCore/css/CSSPrimitiveValue.cpp

    r251662 r252161  
    595595{
    596596    return computeLengthDouble(conversionData);
     597}
     598
     599template<> LayoutUnit CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
     600{
     601    return LayoutUnit(computeLengthDouble(conversionData));
    597602}
    598603
  • trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp

    r251776 r252161  
    108108        return to;
    109109
    110     double fromVal = from == Normal ? 1 : 0;
    111     double toVal = to == Normal ? 1 : 0;
     110    double fromVal = from == ShadowStyle::Normal ? 1 : 0;
     111    double toVal = to == ShadowStyle::Normal ? 1 : 0;
    112112    double result = blendFunc(anim, fromVal, toVal, progress);
    113     return result > 0 ? Normal : Inset;
     113    return result > 0 ? ShadowStyle::Normal : ShadowStyle::Inset;
    114114}
    115115
     
    760760static inline const ShadowData* shadowForBlending(const ShadowData* srcShadow, const ShadowData* otherShadow)
    761761{
    762     static NeverDestroyed<ShadowData> defaultShadowData(IntPoint(), 0, 0, Normal, false, Color::transparent);
    763     static NeverDestroyed<ShadowData> defaultInsetShadowData(IntPoint(), 0, 0, Inset, false, Color::transparent);
    764     static NeverDestroyed<ShadowData> defaultWebKitBoxShadowData(IntPoint(), 0, 0, Normal, true, Color::transparent);
    765     static NeverDestroyed<ShadowData> defaultInsetWebKitBoxShadowData(IntPoint(), 0, 0, Inset, true, Color::transparent);
     762    static NeverDestroyed<ShadowData> defaultShadowData(LayoutPoint(), 0, 0, ShadowStyle::Normal, false, Color::transparent);
     763    static NeverDestroyed<ShadowData> defaultInsetShadowData(LayoutPoint(), 0, 0, ShadowStyle::Inset, false, Color::transparent);
     764    static NeverDestroyed<ShadowData> defaultWebKitBoxShadowData(LayoutPoint(), 0, 0, ShadowStyle::Normal, true, Color::transparent);
     765    static NeverDestroyed<ShadowData> defaultInsetWebKitBoxShadowData(LayoutPoint(), 0, 0, ShadowStyle::Inset, true, Color::transparent);
    766766
    767767    if (srcShadow)
    768768        return srcShadow;
    769769
    770     if (otherShadow->style() == Inset)
     770    if (otherShadow->style() == ShadowStyle::Inset)
    771771        return otherShadow->isWebkitBoxShadow() ? &defaultInsetWebKitBoxShadowData.get() : &defaultInsetShadowData.get();
    772772
  • trunk/Source/WebCore/platform/animation/AnimationUtilities.h

    r245543 r252161  
    11/*
    2  * Copyright (C) 2011 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2011-2019 Apple Inc.  All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #ifndef AnimationUtilities_h
    27 #define AnimationUtilities_h
     26#pragma once
    2827
    2928#include "IntPoint.h"
    30 #include "LayoutUnit.h"
     29#include "LayoutPoint.h"
    3130
    3231namespace WebCore {
     
    6059{
    6160    return IntPoint(blend(from.x(), to.x(), progress),
    62                     blend(from.y(), to.y(), progress));
     61        blend(from.y(), to.y(), progress));
     62}
     63
     64inline LayoutPoint blend(const LayoutPoint& from, const LayoutPoint& to, double progress)
     65{
     66    return LayoutPoint(blend(from.x(), to.x(), progress),
     67        blend(from.y(), to.y(), progress));
    6368}
    6469
    6570} // namespace WebCore
    66 
    67 #endif // AnimationUtilities_h
  • trunk/Source/WebCore/platform/graphics/RoundedRect.h

    r243674 r252161  
    2525 */
    2626
    27 #ifndef RoundedRect_h
    28 #define RoundedRect_h
     27#pragma once
    2928
    3029#include "FloatQuad.h"
     
    133132
    134133} // namespace WebCore
    135 
    136 #endif // RoundedRect_h
  • trunk/Source/WebCore/rendering/InlineFlowBox.cpp

    r250341 r252161  
    13681368    // Shadow comes first and is behind the background and border.
    13691369    if (!renderer().boxShadowShouldBeAppliedToBackground(adjustedPaintoffset, BackgroundBleedNone, this))
    1370         paintBoxShadow(paintInfo, lineStyle, Normal, paintRect);
     1370        paintBoxShadow(paintInfo, lineStyle, ShadowStyle::Normal, paintRect);
    13711371
    13721372    auto color = lineStyle.visitedDependentColor(CSSPropertyBackgroundColor);
     
    13761376
    13771377    paintFillLayers(paintInfo, color, lineStyle.backgroundLayers(), paintRect, compositeOp);
    1378     paintBoxShadow(paintInfo, lineStyle, Inset, paintRect);
     1378    paintBoxShadow(paintInfo, lineStyle, ShadowStyle::Inset, paintRect);
    13791379
    13801380    // :first-line cannot be used to put borders on a line. Always paint borders with our
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r251055 r252161  
    13221322    // custom shadows of their own.
    13231323    if (!boxShadowShouldBeAppliedToBackground(paintRect.location(), bleedAvoidance))
    1324         paintBoxShadow(paintInfo, paintRect, style(), Normal);
     1324        paintBoxShadow(paintInfo, paintRect, style(), ShadowStyle::Normal);
    13251325
    13261326    GraphicsContextStateSaver stateSaver(paintInfo.context(), false);
     
    13531353            theme().paintDecorations(*this, paintInfo, paintRect);
    13541354    }
    1355     paintBoxShadow(paintInfo, paintRect, style(), Inset);
     1355    paintBoxShadow(paintInfo, paintRect, style(), ShadowStyle::Inset);
    13561356
    13571357    // The theme will tell us whether or not we should also paint the CSS border.
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r249364 r252161  
    681681{
    682682    const ShadowData* boxShadow = style.boxShadow();
    683     while (boxShadow->style() != Normal)
     683    while (boxShadow->style() != ShadowStyle::Normal)
    684684        boxShadow = boxShadow->next();
    685685
     
    22862286    bool hasOneNormalBoxShadow = false;
    22872287    for (const ShadowData* currentShadow = style().boxShadow(); currentShadow; currentShadow = currentShadow->next()) {
    2288         if (currentShadow->style() != Normal)
     2288        if (currentShadow->style() != ShadowStyle::Normal)
    22892289            continue;
    22902290
     
    23232323}
    23242324
    2325 static inline LayoutRect areaCastingShadowInHole(const LayoutRect& holeRect, int shadowExtent, int shadowSpread, const IntSize& shadowOffset)
     2325static inline LayoutRect areaCastingShadowInHole(const LayoutRect& holeRect, LayoutUnit shadowExtent, LayoutUnit shadowSpread, const LayoutSize& shadowOffset)
    23262326{
    23272327    LayoutRect bounds(holeRect);
     
    23442344        return;
    23452345
    2346     RoundedRect border = (shadowStyle == Inset) ? style.getRoundedInnerBorderFor(paintRect, includeLogicalLeftEdge, includeLogicalRightEdge)
     2346    RoundedRect border = (shadowStyle == ShadowStyle::Inset) ? style.getRoundedInnerBorderFor(paintRect, includeLogicalLeftEdge, includeLogicalRightEdge)
    23472347        : style.getRoundedBorderFor(paintRect, includeLogicalLeftEdge, includeLogicalRightEdge);
    23482348
     
    23562356            continue;
    23572357
    2358         // FIXME: Add subpixel support for the shadow values. Soon after the shadow offset becomes fractional,
    2359         // all the early snappings here need to be pushed to the actual painting operations.
    2360         IntSize shadowOffset(shadow->x(), shadow->y());
     2358        LayoutSize shadowOffset(shadow->x(), shadow->y());
     2359        LayoutUnit shadowPaintingExtent = shadow->paintingExtent();
     2360        LayoutUnit shadowSpread = shadow->spread();
    23612361        int shadowRadius = shadow->radius();
    2362         int shadowPaintingExtent = shadow->paintingExtent();
    2363         int shadowSpread = shadow->spread();
    2364        
     2362
    23652363        if (shadowOffset.isZero() && !shadowRadius && !shadowSpread)
    23662364            continue;
     
    23682366        Color shadowColor = style.colorByApplyingColorFilter(shadow->color());
    23692367
    2370         if (shadow->style() == Normal) {
     2368        if (shadow->style() == ShadowStyle::Normal) {
    23712369            RoundedRect fillRect = border;
    23722370            fillRect.inflate(shadowSpread);
     
    23742372                continue;
    23752373
    2376             FloatRect pixelSnappedShadowRect = snapRectToDevicePixels(border.rect(), deviceScaleFactor);
    2377             pixelSnappedShadowRect.inflate(shadowPaintingExtent + shadowSpread);
    2378             pixelSnappedShadowRect.move(shadowOffset);
     2374            LayoutRect shadowRect = border.rect();
     2375            shadowRect.inflate(shadowPaintingExtent + shadowSpread);
     2376            shadowRect.move(shadowOffset);
     2377            FloatRect pixelSnappedShadowRect = snapRectToDevicePixels(shadowRect, deviceScaleFactor);
    23792378
    23802379            GraphicsContextStateSaver stateSaver(context);
    23812380            context.clip(pixelSnappedShadowRect);
    23822381
    2383             // Move the fill just outside the clip, adding 1 pixel separation so that the fill does not
     2382            // Move the fill just outside the clip, adding at least 1 pixel of separation so that the fill does not
    23842383            // bleed in (due to antialiasing) if the context is transformed.
    2385             IntSize extraOffset(roundToInt(paintRect.width()) + std::max(0, shadowOffset.width()) + shadowPaintingExtent + 2 * shadowSpread + 1, 0);
     2384            LayoutUnit xOffset = paintRect.width() + std::max<LayoutUnit>(0, shadowOffset.width()) + shadowPaintingExtent + 2 * shadowSpread + LayoutUnit(1);
     2385            LayoutSize extraOffset(xOffset.ceil(), 0);
    23862386            shadowOffset -= extraOffset;
    23872387            fillRect.move(extraOffset);
    23882388
     2389            FloatRoundedRect pixelSnappedRectToClipOut = border.pixelSnappedRoundedRectForPainting(deviceScaleFactor);
     2390            FloatRoundedRect pixelSnappedFillRect = fillRect.pixelSnappedRoundedRectForPainting(deviceScaleFactor);
     2391           
     2392            LayoutPoint shadowRectOrigin = fillRect.rect().location() + shadowOffset;
     2393            FloatPoint snappedShadowOrigin = FloatPoint(roundToDevicePixel(shadowRectOrigin.x(), deviceScaleFactor), roundToDevicePixel(shadowRectOrigin.y(), deviceScaleFactor));
     2394            FloatSize snappedShadowOffset = snappedShadowOrigin - pixelSnappedFillRect.rect().location();
     2395
    23892396            if (shadow->isWebkitBoxShadow())
    2390                 context.setLegacyShadow(shadowOffset, shadowRadius, shadowColor);
     2397                context.setLegacyShadow(snappedShadowOffset, shadowRadius, shadowColor);
    23912398            else
    2392                 context.setShadow(shadowOffset, shadowRadius, shadowColor);
    2393 
    2394             FloatRoundedRect rectToClipOut = border.pixelSnappedRoundedRectForPainting(deviceScaleFactor);
    2395             FloatRoundedRect pixelSnappedFillRect = fillRect.pixelSnappedRoundedRectForPainting(deviceScaleFactor);
     2399                context.setShadow(snappedShadowOffset, shadowRadius, shadowColor);
     2400
    23962401            if (hasBorderRadius) {
    23972402                // If the box is opaque, it is unnecessary to clip it out. However, doing so saves time
     
    23992404                // corners. Those are avoided by insetting the clipping path by one pixel.
    24002405                if (hasOpaqueBackground)
    2401                     rectToClipOut.inflateWithRadii(-1.0f);
    2402 
    2403                 if (!rectToClipOut.isEmpty())
    2404                     context.clipOutRoundedRect(rectToClipOut);
     2406                    pixelSnappedRectToClipOut.inflateWithRadii(-1.0f);
     2407
     2408                if (!pixelSnappedRectToClipOut.isEmpty())
     2409                    context.clipOutRoundedRect(pixelSnappedRectToClipOut);
    24052410
    24062411                RoundedRect influenceRect(LayoutRect(pixelSnappedShadowRect), border.radii());
     
    24252430                    AffineTransform transform = context.getCTM();
    24262431                    if (transform.a() != 1 || (transform.d() != 1 && transform.d() != -1) || transform.b() || transform.c())
    2427                         rectToClipOut.inflate(-1.0f);
     2432                        pixelSnappedRectToClipOut.inflate(-1.0f);
    24282433                }
    24292434
    2430                 if (!rectToClipOut.isEmpty())
    2431                     context.clipOut(rectToClipOut.rect());
     2435                if (!pixelSnappedRectToClipOut.isEmpty())
     2436                    context.clipOut(pixelSnappedRectToClipOut.rect());
     2437
    24322438                context.fillRect(pixelSnappedFillRect.rect(), Color::black);
    24332439            }
    24342440        } else {
    24352441            // Inset shadow.
     2442            LayoutRect holeRect = border.rect();
     2443            holeRect.inflate(-shadowSpread);
     2444            FloatRect pixelSnappedHoleRect = snapRectToDevicePixels(holeRect, deviceScaleFactor);
    24362445            FloatRoundedRect pixelSnappedBorderRect = border.pixelSnappedRoundedRectForPainting(deviceScaleFactor);
    2437             FloatRect pixelSnappedHoleRect = pixelSnappedBorderRect.rect();
    2438             pixelSnappedHoleRect.inflate(-shadowSpread);
    24392446
    24402447            if (pixelSnappedHoleRect.isEmpty()) {
     
    24482455            if (!includeLogicalLeftEdge) {
    24492456                if (isHorizontal) {
    2450                     pixelSnappedHoleRect.move(-std::max(shadowOffset.width(), 0) - shadowPaintingExtent, 0);
    2451                     pixelSnappedHoleRect.setWidth(pixelSnappedHoleRect.width() + std::max(shadowOffset.width(), 0) + shadowPaintingExtent);
     2457                    holeRect.move(-std::max<LayoutUnit>(shadowOffset.width(), 0) - shadowPaintingExtent, 0);
     2458                    holeRect.setWidth(holeRect.width() + std::max<LayoutUnit>(shadowOffset.width(), 0) + shadowPaintingExtent);
    24522459                } else {
    2453                     pixelSnappedHoleRect.move(0, -std::max(shadowOffset.height(), 0) - shadowPaintingExtent);
    2454                     pixelSnappedHoleRect.setHeight(pixelSnappedHoleRect.height() + std::max(shadowOffset.height(), 0) + shadowPaintingExtent);
     2460                    holeRect.move(0, -std::max<LayoutUnit>(shadowOffset.height(), 0) - shadowPaintingExtent);
     2461                    holeRect.setHeight(holeRect.height() + std::max<LayoutUnit>(shadowOffset.height(), 0) + shadowPaintingExtent);
    24552462                }
    24562463            }
     2464           
    24572465            if (!includeLogicalRightEdge) {
    24582466                if (isHorizontal)
    2459                     pixelSnappedHoleRect.setWidth(pixelSnappedHoleRect.width() - std::min(shadowOffset.width(), 0) + shadowPaintingExtent);
     2467                    holeRect.setWidth(holeRect.width() - std::min<LayoutUnit>(shadowOffset.width(), 0) + shadowPaintingExtent);
    24602468                else
    2461                     pixelSnappedHoleRect.setHeight(pixelSnappedHoleRect.height() - std::min(shadowOffset.height(), 0) + shadowPaintingExtent);
     2469                    holeRect.setHeight(holeRect.height() - std::min<LayoutUnit>(shadowOffset.height(), 0) + shadowPaintingExtent);
    24622470            }
    24632471
     2472            if (!includeLogicalLeftEdge || !includeLogicalRightEdge)
     2473                pixelSnappedHoleRect = snapRectToDevicePixels(holeRect, deviceScaleFactor);
     2474
    24642475            Color fillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), 255);
    24652476
    2466             FloatRect pixelSnappedOuterRect = snapRectToDevicePixels(areaCastingShadowInHole(LayoutRect(pixelSnappedBorderRect.rect()), shadowPaintingExtent, shadowSpread, shadowOffset), deviceScaleFactor);
    2467             FloatRoundedRect pixelSnappedRoundedHole = FloatRoundedRect(pixelSnappedHoleRect, pixelSnappedBorderRect.radii());
     2477            FloatRect pixelSnappedOuterRect = snapRectToDevicePixels(areaCastingShadowInHole(holeRect, shadowPaintingExtent, shadowSpread, shadowOffset), deviceScaleFactor);
     2478            RoundedRect roundedHoleRect(holeRect, border.radii());
     2479            FloatRoundedRect pixelSnappedRoundedHole = roundedHoleRect.pixelSnappedRoundedRectForPainting(deviceScaleFactor);
    24682480
    24692481            GraphicsContextStateSaver stateSaver(context);
     
    24742486                context.clip(pixelSnappedBorderRect.rect());
    24752487
    2476             IntSize extraOffset(2 * roundToInt(paintRect.width()) + std::max(0, shadowOffset.width()) + shadowPaintingExtent - 2 * shadowSpread + 1, 0);
     2488            IntSize extraOffset(2 * roundToInt(paintRect.width()) + std::max<LayoutUnit>(0, shadowOffset.width()) + shadowPaintingExtent - 2 * shadowSpread + 1, 0);
    24772489            context.translate(extraOffset);
    24782490            shadowOffset -= extraOffset;
  • trunk/Source/WebCore/rendering/RenderTable.cpp

    r248846 r252161  
    771771    BackgroundBleedAvoidance bleedAvoidance = determineBackgroundBleedAvoidance(paintInfo.context());
    772772    if (!boxShadowShouldBeAppliedToBackground(rect.location(), bleedAvoidance))
    773         paintBoxShadow(paintInfo, rect, style(), Normal);
     773        paintBoxShadow(paintInfo, rect, style(), ShadowStyle::Normal);
    774774    paintBackground(paintInfo, rect, bleedAvoidance);
    775     paintBoxShadow(paintInfo, rect, style(), Inset);
     775    paintBoxShadow(paintInfo, rect, style(), ShadowStyle::Inset);
    776776
    777777    if (style().hasVisibleBorderDecoration() && !collapseBorders())
  • trunk/Source/WebCore/rendering/RenderTableCell.cpp

    r247184 r252161  
    13191319    adjustBorderBoxRectForPainting(paintRect);
    13201320
    1321     paintBoxShadow(paintInfo, paintRect, style(), Normal);
     1321    paintBoxShadow(paintInfo, paintRect, style(), ShadowStyle::Normal);
    13221322   
    13231323    // Paint our cell background.
    13241324    paintBackgroundsBehindCell(paintInfo, paintOffset, this);
    13251325
    1326     paintBoxShadow(paintInfo, paintRect, style(), Inset);
     1326    paintBoxShadow(paintInfo, paintRect, style(), ShadowStyle::Inset);
    13271327
    13281328    if (!style().hasBorder() || table->collapseBorders())
  • trunk/Source/WebCore/rendering/style/RenderStyle.cpp

    r251059 r252161  
    14091409void RenderStyle::setTextShadow(std::unique_ptr<ShadowData> shadowData, bool add)
    14101410{
    1411     ASSERT(!shadowData || (!shadowData->spread() && shadowData->style() == Normal));
     1411    ASSERT(!shadowData || (!shadowData->spread() && shadowData->style() == ShadowStyle::Normal));
    14121412
    14131413    auto& rareData = m_rareInheritedData.access();
     
    18831883
    18841884    for ( ; shadow; shadow = shadow->next()) {
    1885         if (shadow->style() == Inset)
     1885        if (shadow->style() == ShadowStyle::Inset)
    18861886            continue;
    18871887
    1888         int extentAndSpread = shadow->paintingExtent() + shadow->spread();
     1888        auto extentAndSpread = shadow->paintingExtent() + shadow->spread();
    18891889        top = std::min<LayoutUnit>(top, shadow->y() - extentAndSpread);
    18901890        right = std::max<LayoutUnit>(right, shadow->x() + extentAndSpread);
     
    19021902
    19031903    for ( ; shadow; shadow = shadow->next()) {
    1904         if (shadow->style() == Normal)
     1904        if (shadow->style() == ShadowStyle::Normal)
    19051905            continue;
    19061906
    1907         int extentAndSpread = shadow->paintingExtent() + shadow->spread();
     1907        auto extentAndSpread = shadow->paintingExtent() + shadow->spread();
    19081908        top = std::max<LayoutUnit>(top, shadow->y() + extentAndSpread);
    19091909        right = std::min<LayoutUnit>(right, shadow->x() - extentAndSpread);
     
    19211921
    19221922    for ( ; shadow; shadow = shadow->next()) {
    1923         if (shadow->style() == Inset)
     1923        if (shadow->style() == ShadowStyle::Inset)
    19241924            continue;
    19251925
    1926         int extentAndSpread = shadow->paintingExtent() + shadow->spread();
     1926        auto extentAndSpread = shadow->paintingExtent() + shadow->spread();
    19271927        left = std::min<LayoutUnit>(left, shadow->x() - extentAndSpread);
    19281928        right = std::max<LayoutUnit>(right, shadow->x() + extentAndSpread);
     
    19361936
    19371937    for ( ; shadow; shadow = shadow->next()) {
    1938         if (shadow->style() == Inset)
     1938        if (shadow->style() == ShadowStyle::Inset)
    19391939            continue;
    19401940
    1941         int extentAndSpread = shadow->paintingExtent() + shadow->spread();
     1941        auto extentAndSpread = shadow->paintingExtent() + shadow->spread();
    19421942        top = std::min<LayoutUnit>(top, shadow->y() - extentAndSpread);
    19431943        bottom = std::max<LayoutUnit>(bottom, shadow->y() + extentAndSpread);
  • trunk/Source/WebCore/rendering/style/ShadowData.cpp

    r251326 r252161  
    3030ShadowData::ShadowData(const ShadowData& o)
    3131    : m_location(o.m_location)
     32    , m_spread(o.m_spread)
    3233    , m_radius(o.m_radius)
    33     , m_spread(o.m_spread)
    3434    , m_color(o.m_color)
    3535    , m_style(o.m_style)
     
    5959}
    6060
    61 static inline void calculateShadowExtent(const ShadowData* shadow, int additionalOutlineSize, int& shadowLeft, int& shadowRight, int& shadowTop, int& shadowBottom)
     61static inline void calculateShadowExtent(const ShadowData* shadow, LayoutUnit additionalOutlineSize, LayoutUnit& shadowLeft, LayoutUnit& shadowRight, LayoutUnit& shadowTop, LayoutUnit& shadowBottom)
    6262{
    6363    do {
    64         int extentAndSpread = shadow->paintingExtent() + shadow->spread() + additionalOutlineSize;
    65         if (shadow->style() == Normal) {
     64        LayoutUnit extentAndSpread = shadow->paintingExtent() + shadow->spread() + additionalOutlineSize;
     65        if (shadow->style() == ShadowStyle::Normal) {
    6666            shadowLeft = std::min(shadow->x() - extentAndSpread, shadowLeft);
    6767            shadowRight = std::max(shadow->x() + extentAndSpread, shadowRight);
     
    7676void ShadowData::adjustRectForShadow(LayoutRect& rect, int additionalOutlineSize) const
    7777{
    78     int shadowLeft = 0;
    79     int shadowRight = 0;
    80     int shadowTop = 0;
    81     int shadowBottom = 0;
     78    LayoutUnit shadowLeft;
     79    LayoutUnit shadowRight;
     80    LayoutUnit shadowTop;
     81    LayoutUnit shadowBottom;
    8282    calculateShadowExtent(this, additionalOutlineSize, shadowLeft, shadowRight, shadowTop, shadowBottom);
    8383
     
    8989void ShadowData::adjustRectForShadow(FloatRect& rect, int additionalOutlineSize) const
    9090{
    91     int shadowLeft = 0;
    92     int shadowRight = 0;
    93     int shadowTop = 0;
    94     int shadowBottom = 0;
     91    LayoutUnit shadowLeft = 0;
     92    LayoutUnit shadowRight = 0;
     93    LayoutUnit shadowTop = 0;
     94    LayoutUnit shadowBottom = 0;
    9595    calculateShadowExtent(this, additionalOutlineSize, shadowLeft, shadowRight, shadowTop, shadowBottom);
    9696
  • trunk/Source/WebCore/rendering/style/ShadowData.h

    r251052 r252161  
    3131namespace WebCore {
    3232
    33 enum ShadowStyle { Normal, Inset };
     33enum class ShadowStyle : uint8_t { Normal, Inset };
    3434
    3535// This class holds information about shadows for the text-shadow and box-shadow properties.
     
    3838    WTF_MAKE_FAST_ALLOCATED;
    3939public:
    40     ShadowData()
    41         : m_radius(0)
    42         , m_spread(0)
    43         , m_style(Normal)
    44         , m_isWebkitBoxShadow(false)
    45     {
    46     }
     40    ShadowData() = default;
    4741
    48     ShadowData(const IntPoint& location, int radius, int spread, ShadowStyle style, bool isWebkitBoxShadow, const Color& color)
     42    ShadowData(const LayoutPoint& location, int radius, LayoutUnit spread, ShadowStyle style, bool isWebkitBoxShadow, const Color& color)
    4943        : m_location(location)
     44        , m_spread(spread)
    5045        , m_radius(radius)
    51         , m_spread(spread)
    5246        , m_color(color)
    5347        , m_style(style)
     
    6761    }
    6862   
    69     int x() const { return m_location.x(); }
    70     int y() const { return m_location.y(); }
    71     IntPoint location() const { return m_location; }
     63    LayoutUnit x() const { return m_location.x(); }
     64    LayoutUnit y() const { return m_location.y(); }
     65    LayoutPoint location() const { return m_location; }
    7266    int radius() const { return m_radius; }
    73     int paintingExtent() const
     67    LayoutUnit paintingExtent() const
    7468    {
    7569        // Blurring uses a Gaussian function whose std. deviation is m_radius/2, and which in theory
     
    7771        // undetectable at around 1.4x the radius.
    7872        const float radiusExtentMultiplier = 1.4;
    79         return ceilf(m_radius * radiusExtentMultiplier);
     73        return LayoutUnit(ceilf(m_radius * radiusExtentMultiplier));
    8074    }
    81     int spread() const { return m_spread; }
     75    LayoutUnit spread() const { return m_spread; }
    8276    ShadowStyle style() const { return m_style; }
    8377    const Color& color() const { return m_color; }
     
    9185
    9286private:
    93     IntPoint m_location;
    94     int m_radius; // This is the "blur radius", or twice the standard deviation of the Gaussian blur.
    95     int m_spread;
     87    LayoutPoint m_location;
     88    LayoutUnit m_spread;
     89    int m_radius { 0 }; // This is the "blur radius", or twice the standard deviation of the Gaussian blur.
    9690    Color m_color;
    97     ShadowStyle m_style;
    98     bool m_isWebkitBoxShadow;
     91    ShadowStyle m_style { ShadowStyle::Normal };
     92    bool m_isWebkitBoxShadow { false };
    9993    std::unique_ptr<ShadowData> m_next;
    10094};
  • trunk/Source/WebCore/style/StyleBuilderCustom.h

    r252076 r252161  
    830830        auto& shadowValue = downcast<CSSShadowValue>(item.get());
    831831        auto conversionData = builderState.cssToLengthConversionData();
    832         int x = shadowValue.x->computeLength<int>(conversionData);
    833         int y = shadowValue.y->computeLength<int>(conversionData);
     832        auto x = shadowValue.x->computeLength<LayoutUnit>(conversionData);
     833        auto y = shadowValue.y->computeLength<LayoutUnit>(conversionData);
    834834        int blur = shadowValue.blur ? shadowValue.blur->computeLength<int>(conversionData) : 0;
    835         int spread = shadowValue.spread ? shadowValue.spread->computeLength<int>(conversionData) : 0;
    836         ShadowStyle shadowStyle = shadowValue.style && shadowValue.style->valueID() == CSSValueInset ? Inset : Normal;
     835        auto spread = shadowValue.spread ? shadowValue.spread->computeLength<LayoutUnit>(conversionData) : LayoutUnit(0);
     836        ShadowStyle shadowStyle = shadowValue.style && shadowValue.style->valueID() == CSSValueInset ? ShadowStyle::Inset : ShadowStyle::Normal;
    837837        Color color;
    838838        if (shadowValue.color)
     
    840840        else
    841841            color = builderState.style().color();
    842         auto shadowData = makeUnique<ShadowData>(IntPoint(x, y), blur, spread, shadowStyle, property == CSSPropertyWebkitBoxShadow, color.isValid() ? color : Color::transparent);
     842        auto shadowData = makeUnique<ShadowData>(LayoutPoint(x, y), blur, spread, shadowStyle, property == CSSPropertyWebkitBoxShadow, color.isValid() ? color : Color::transparent);
    843843        if (property == CSSPropertyTextShadow)
    844844            builderState.style().setTextShadow(WTFMove(shadowData), !isFirstEntry); // add to the list if this is not the first entry
  • trunk/Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm

    r247439 r252161  
    286286    [fontPanel toggleShadow];
    287287    EXPECT_WK_STREQ("baz", [webView selectedText]);
    288     EXPECT_WK_STREQ("rgb(0, 0, 0) 0px 1px 8px", textShadowAroundSelection());
     288    EXPECT_WK_STREQ("rgb(0, 0, 0) 0px 1.25px 8px", textShadowAroundSelection());
    289289    {
    290290        NSShadow *shadow = [webView typingAttributes][NSShadowAttributeName];
    291291        EXPECT_EQ(shadow.shadowOffset.width, 0);
    292         EXPECT_EQ(shadow.shadowOffset.height, 1);
     292        EXPECT_EQ(shadow.shadowOffset.height, 1.25);
    293293        EXPECT_EQ(shadow.shadowBlurRadius, 8);
    294294        EXPECT_TRUE([shadow.shadowColor isEqual:[NSColor colorWithRed:0 green:0 blue:0 alpha:1]]);
     
    307307    [fontPanel chooseStrikeThroughMenuItemWithTitle:@"single"];
    308308    EXPECT_WK_STREQ("foo bar baz", [webView selectedText]);
    309     EXPECT_WK_STREQ("rgba(0, 0, 0, 0.2) 0px 1px 5px", textShadowAroundSelection());
     309    EXPECT_WK_STREQ("rgba(0, 0, 0, 0.2) 0px 1.25px 5px", textShadowAroundSelection());
    310310    EXPECT_WK_STREQ("underline line-through", textDecorationsAroundSelection());
    311311    {
     
    316316        NSShadow *shadow = typingAttributes[NSShadowAttributeName];
    317317        EXPECT_EQ(shadow.shadowOffset.width, 0);
    318         EXPECT_EQ(shadow.shadowOffset.height, 1);
     318        EXPECT_EQ(shadow.shadowOffset.height, 1.25);
    319319        EXPECT_EQ(shadow.shadowBlurRadius, 5);
    320320        EXPECT_TRUE([shadow.shadowColor isEqual:[NSColor colorWithRed:0 green:0 blue:0 alpha:0.2]]);
Note: See TracChangeset for help on using the changeset viewer.