Changeset 46295 in webkit


Ignore:
Timestamp:
Jul 23, 2009 4:00:41 PM (15 years ago)
Author:
mitz@apple.com
Message:

WebCore:

Reviewed by Dave Hyatt.

[CSS3 Backgrounds and Borders] Add support for inset box shadows
https://bugs.webkit.org/show_bug.cgi?id=27582

Test: fast/box-shadow/inset.html

  • css/CSSComputedStyleDeclaration.cpp: (WebCore::valueForShadow): Set the ShadowValue’s shadow style to 'inset'

as needed.

  • css/CSSParser.cpp: (WebCore::ShadowParseContext::ShadowParseContext): Added style and allowStyle

members. Initialize the allowStyle member.

(WebCore::ShadowParseContext::commitValue): Pass the style value to the

ShadowValue constructor. Reset allowStyle.

(WebCore::ShadowParseContext::commitLength): Update allowStyle.
(WebCore::ShadowParseContext::commitColor): Ditto.
(WebCore::ShadowParseContext::commitStyle): Added. Sets the style member and

updates the state.

(WebCore::CSSParser::parseShadow): Parse the 'inset' keyword.

  • css/CSSStyleSelector.cpp: (WebCore::CSSStyleSelector::applyProperty): Get the style value from the

shadow value and pass it to the ShadowData constructor.

  • css/ShadowValue.cpp: (WebCore::ShadowValue::ShadowValue): Added style. (WebCore::ShadowValue::cssText): Added style.
  • css/ShadowValue.h: (WebCore::ShadowValue::create): Added style.
  • page/animation/AnimationBase.cpp: (WebCore::blendFunc): Added a blend function for shadow styles. When blending

between normal and inset shadows, all intermediate values map to normal.

(WebCore::PropertyWrapperShadow::blend): Added normal style to the default

shadow.


  • rendering/InlineFlowBox.cpp: (WebCore::InlineFlowBox::paintBoxShadow): Added a shadow style parameter,

which is passed through to RenderBoxModelObject::paintBoxShadow().

(WebCore::InlineFlowBox::paintBoxDecorations): Paint inset shadows on top of

the background.

  • rendering/InlineFlowBox.h:
  • rendering/RenderBox.cpp: (WebCore::RenderBox::paintBoxDecorations): Paint inset shadows on top of the

background.

  • rendering/RenderBoxModelObject.cpp: (WebCore::RenderBoxModelObject::paintBoxShadow): Added a shadow style

parameter, and code to paint inset shadows.

  • rendering/RenderBoxModelObject.h:
  • rendering/RenderFieldset.cpp: (WebCore::RenderFieldset::paintBoxDecorations): Paint inset shadows on top of

the background.

  • rendering/RenderTable.cpp: (WebCore::RenderTable::paintBoxDecorations): Ditto.
  • rendering/RenderTableCell.cpp: (WebCore::RenderTableCell::paintBoxDecorations): Ditto.
  • rendering/style/ShadowData.h: Added a ShadowStyle enum. (WebCore::ShadowData::ShadowData): Add and initialize a style member.

LayoutTests:

Reviewed by Dave Hyatt.

[CSS3 Backgrounds and Borders] Add support for inset box shadows
https://bugs.webkit.org/show_bug.cgi?id=27582

  • fast/box-shadow/inset.html: Added.
  • platform/mac/fast/box-shadow/inset-expected.checksum: Added.
  • platform/mac/fast/box-shadow/inset-expected.png: Added.
  • platform/mac/fast/box-shadow/inset-expected.txt: Added.
Location:
trunk
Files:
4 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r46290 r46295  
     12009-07-23  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Dave Hyatt.
     4
     5        [CSS3 Backgrounds and Borders] Add support for inset box shadows
     6        https://bugs.webkit.org/show_bug.cgi?id=27582
     7
     8        * fast/box-shadow/inset.html: Added.
     9        * platform/mac/fast/box-shadow/inset-expected.checksum: Added.
     10        * platform/mac/fast/box-shadow/inset-expected.png: Added.
     11        * platform/mac/fast/box-shadow/inset-expected.txt: Added.
     12
    1132009-07-23  Mark Rowe  <mrowe@apple.com>
    214
  • trunk/WebCore/ChangeLog

    r46293 r46295  
     12009-07-23  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Dave Hyatt.
     4
     5        [CSS3 Backgrounds and Borders] Add support for inset box shadows
     6        https://bugs.webkit.org/show_bug.cgi?id=27582
     7
     8        Test: fast/box-shadow/inset.html
     9
     10        * css/CSSComputedStyleDeclaration.cpp:
     11        (WebCore::valueForShadow): Set the ShadowValue’s shadow style to 'inset'
     12            as needed.
     13
     14        * css/CSSParser.cpp:
     15        (WebCore::ShadowParseContext::ShadowParseContext): Added style and allowStyle
     16            members. Initialize the allowStyle member.
     17        (WebCore::ShadowParseContext::commitValue): Pass the style value to the
     18            ShadowValue constructor. Reset allowStyle.
     19        (WebCore::ShadowParseContext::commitLength): Update allowStyle.
     20        (WebCore::ShadowParseContext::commitColor): Ditto.
     21        (WebCore::ShadowParseContext::commitStyle): Added. Sets the style member and
     22            updates the state.
     23        (WebCore::CSSParser::parseShadow): Parse the 'inset' keyword.
     24
     25        * css/CSSStyleSelector.cpp:
     26        (WebCore::CSSStyleSelector::applyProperty): Get the style value from the
     27            shadow value and pass it to the ShadowData constructor.
     28
     29        * css/ShadowValue.cpp:
     30        (WebCore::ShadowValue::ShadowValue): Added style.
     31        (WebCore::ShadowValue::cssText): Added style.
     32
     33        * css/ShadowValue.h:
     34        (WebCore::ShadowValue::create): Added style.
     35
     36        * page/animation/AnimationBase.cpp:
     37        (WebCore::blendFunc): Added a blend function for shadow styles. When blending
     38            between normal and inset shadows, all intermediate values map to normal.
     39        (WebCore::PropertyWrapperShadow::blend): Added normal style to the default
     40            shadow.
     41           
     42        * rendering/InlineFlowBox.cpp:
     43        (WebCore::InlineFlowBox::paintBoxShadow): Added a shadow style parameter,
     44            which is passed through to RenderBoxModelObject::paintBoxShadow().
     45
     46        (WebCore::InlineFlowBox::paintBoxDecorations): Paint inset shadows on top of
     47            the background.
     48
     49        * rendering/InlineFlowBox.h:
     50
     51        * rendering/RenderBox.cpp:
     52        (WebCore::RenderBox::paintBoxDecorations): Paint inset shadows on top of the
     53            background.
     54
     55        * rendering/RenderBoxModelObject.cpp:
     56        (WebCore::RenderBoxModelObject::paintBoxShadow): Added a shadow style
     57            parameter, and code to paint inset shadows.
     58
     59        * rendering/RenderBoxModelObject.h:
     60
     61        * rendering/RenderFieldset.cpp:
     62        (WebCore::RenderFieldset::paintBoxDecorations): Paint inset shadows on top of
     63            the background.
     64
     65        * rendering/RenderTable.cpp:
     66        (WebCore::RenderTable::paintBoxDecorations): Ditto.
     67
     68        * rendering/RenderTableCell.cpp:
     69        (WebCore::RenderTableCell::paintBoxDecorations): Ditto.
     70
     71        * rendering/style/ShadowData.h:
     72        Added a ShadowStyle enum.
     73        (WebCore::ShadowData::ShadowData): Add and initialize a style member.
     74
    1752009-07-23  Simon Fraser  <simon.fraser@apple.com>
    276
  • trunk/WebCore/css/CSSComputedStyleDeclaration.cpp

    r46285 r46295  
    276276        RefPtr<CSSPrimitiveValue> blur = CSSPrimitiveValue::create(s->blur, CSSPrimitiveValue::CSS_PX);
    277277        RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? 0 : CSSPrimitiveValue::create(s->spread, CSSPrimitiveValue::CSS_PX);
     278        RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style == Normal ? 0 : CSSPrimitiveValue::createIdentifier(CSSValueInset);
    278279        RefPtr<CSSPrimitiveValue> color = CSSPrimitiveValue::createColor(s->color.rgb());
    279         list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), color.release()));
     280        list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
    280281    }
    281282    return list.release();
  • trunk/WebCore/css/CSSParser.cpp

    r46281 r46295  
    34873487        , allowSpread(false)
    34883488        , allowColor(true)
     3489        , allowStyle(prop == CSSPropertyBoxShadow)
    34893490        , allowBreak(true)
    34903491    {
     
    34963497    {
    34973498        // Handle the ,, case gracefully by doing nothing.
    3498         if (x || y || blur || spread || color) {
     3499        if (x || y || blur || spread || color || style) {
    34993500            if (!values)
    35003501                values = CSSValueList::createCommaSeparated();
    3501            
     3502
    35023503            // Construct the current shadow value and add it to the list.
    3503             values->append(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), color.release()));
     3504            values->append(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
    35043505        }
    35053506
     
    35093510        blur = 0;
    35103511        spread = 0;
     3512        style = 0;
    35113513        color = 0;
    35123514
     
    35163518        allowY = false;
    35173519        allowBlur = false;
    3518         allowSpread = false; 
     3520        allowSpread = false;
     3521        allowStyle = property == CSSPropertyBoxShadow;
    35193522    }
    35203523
     
    35283531            allowY = true;
    35293532            allowColor = false;
     3533            allowStyle = false;
    35303534            allowBreak = false;
    35313535        } else if (allowY) {
     
    35343538            allowBlur = true;
    35353539            allowColor = true;
     3540            allowStyle = property == CSSPropertyBoxShadow;
    35363541            allowBreak = true;
    35373542        } else if (allowBlur) {
     
    35493554        color = val;
    35503555        allowColor = false;
     3556        if (allowX) {
     3557            allowStyle = false;
     3558            allowBreak = false;
     3559        } else {
     3560            allowBlur = false;
     3561            allowSpread = false;
     3562            allowStyle = property == CSSPropertyBoxShadow;
     3563        }
     3564    }
     3565
     3566    void commitStyle(CSSParserValue* v)
     3567    {
     3568        style = CSSPrimitiveValue::createIdentifier(v->id);
     3569        allowStyle = false;
    35513570        if (allowX)
    35523571            allowBreak = false;
     
    35543573            allowBlur = false;
    35553574            allowSpread = false;
     3575            allowColor = false;
    35563576        }
    35573577    }
     
    35643584    RefPtr<CSSPrimitiveValue> blur;
    35653585    RefPtr<CSSPrimitiveValue> spread;
     3586    RefPtr<CSSPrimitiveValue> style;
    35663587    RefPtr<CSSPrimitiveValue> color;
    35673588
     
    35713592    bool allowSpread;
    35723593    bool allowColor;
     3594    bool allowStyle;
    35733595    bool allowBreak;
    35743596};
     
    35953617            // A length is allowed here.  Construct the value and add it.
    35963618            context.commitLength(val);
     3619        } else if (val->id == CSSValueInset) {
     3620            if (!context.allowStyle)
     3621                return false;
     3622
     3623            context.commitStyle(val);
    35973624        } else {
    35983625            // The only other type of value that's ok is a color value.
  • trunk/WebCore/css/CSSStyleSelector.cpp

    r46281 r46295  
    33 *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
    44 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
    5  * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
     5 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
    66 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
    77 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
     
    45434543            int blur = item->blur ? item->blur->computeLengthInt(style(), m_rootElementStyle, zoomFactor) : 0;
    45444544            int spread = item->spread ? item->spread->computeLengthInt(style(), m_rootElementStyle, zoomFactor) : 0;
     4545            ShadowStyle shadowStyle = item->style && item->style->getIdent() == CSSValueInset ? Inset : Normal;
    45454546            Color color;
    45464547            if (item->color)
    45474548                color = getColorFromPrimitiveValue(item->color.get());
    4548             ShadowData* shadowData = new ShadowData(x, y, blur, spread, color.isValid() ? color : Color::transparent);
     4549            ShadowData* shadowData = new ShadowData(x, y, blur, spread, shadowStyle, color.isValid() ? color : Color::transparent);
    45494550            if (id == CSSPropertyTextShadow)
    45504551                m_style->setTextShadow(shadowData, i != 0);
  • trunk/WebCore/css/ShadowValue.cpp

    r46097 r46295  
    33 *
    44 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
    5  * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
     5 * Copyright (C) 2004, 2005, 2006, 2009 Apple Computer, Inc.
    66 *
    77 * This library is free software; you can redistribute it and/or
     
    3333    PassRefPtr<CSSPrimitiveValue> _blur,
    3434    PassRefPtr<CSSPrimitiveValue> _spread,
     35    PassRefPtr<CSSPrimitiveValue> _style,
    3536    PassRefPtr<CSSPrimitiveValue> _color)
    3637    : x(_x)
     
    3839    , blur(_blur)
    3940    , spread(_spread)
     41    , style(_style)
    4042    , color(_color)
    4143{
     
    6870        text += spread->cssText();
    6971    }
     72    if (style) {
     73        if (!text.isEmpty())
     74            text += " ";
     75        text += style->cssText();
     76    }
    7077
    7178    return text;
  • trunk/WebCore/css/ShadowValue.h

    r46097 r46295  
    11/*
    22 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
    3  * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
     3 * Copyright (C) 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved.
    44 *
    55 * This library is free software; you can redistribute it and/or
     
    3737        PassRefPtr<CSSPrimitiveValue> blur,
    3838        PassRefPtr<CSSPrimitiveValue> spread,
     39        PassRefPtr<CSSPrimitiveValue> style,
    3940        PassRefPtr<CSSPrimitiveValue> color)
    4041    {
    41         return adoptRef(new ShadowValue(x, y, blur, spread, color));
     42        return adoptRef(new ShadowValue(x, y, blur, spread, style, color));
    4243    }
    4344
     
    4849    RefPtr<CSSPrimitiveValue> blur;
    4950    RefPtr<CSSPrimitiveValue> spread;
     51    RefPtr<CSSPrimitiveValue> style;
    5052    RefPtr<CSSPrimitiveValue> color;
    5153
     
    5557        PassRefPtr<CSSPrimitiveValue> blur,
    5658        PassRefPtr<CSSPrimitiveValue> spread,
     59        PassRefPtr<CSSPrimitiveValue> style,
    5760        PassRefPtr<CSSPrimitiveValue> color);
    5861};
  • trunk/WebCore/page/animation/AnimationBase.cpp

    r46274 r46295  
    11/*
    2  * Copyright (C) 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    114114}
    115115
     116static inline ShadowStyle blendFunc(const AnimationBase* anim, ShadowStyle from, ShadowStyle to, double progress)
     117{
     118    if (from == to)
     119        return to;
     120
     121    double fromVal = from == Normal ? 1 : 0;
     122    double toVal = to == Normal ? 1 : 0;
     123    double result = blendFunc(anim, fromVal, toVal, progress);
     124    return result > 0 ? Normal : Inset;
     125}
     126
    116127static inline ShadowData* blendFunc(const AnimationBase* anim, const ShadowData* from, const ShadowData* to, double progress)
    117128
     
    119130    return new ShadowData(blendFunc(anim, from->x, to->x, progress), blendFunc(anim, from->y, to->y, progress),
    120131                          blendFunc(anim, from->blur, to->blur, progress), blendFunc(anim, from->spread, to->spread, progress),
    121                           blendFunc(anim, from->color, to->color, progress));
     132                          blendFunc(anim, from->style, to->style, progress), blendFunc(anim, from->color, to->color, progress));
    122133}
    123134
     
    302313        ShadowData* shadowA = (a->*m_getter)();
    303314        ShadowData* shadowB = (b->*m_getter)();
    304         ShadowData defaultShadowData(0, 0, 0, 0, Color::transparent);
     315        ShadowData defaultShadowData(0, 0, 0, 0, Normal, Color::transparent);
    305316
    306317        if (!shadowA)
  • trunk/WebCore/rendering/InlineFlowBox.cpp

    r46097 r46295  
    11/*
    2  * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
    33 *
    44 * This library is free software; you can redistribute it and/or
     
    697697}
    698698
    699 void InlineFlowBox::paintBoxShadow(GraphicsContext* context, RenderStyle* s, int tx, int ty, int w, int h)
     699void InlineFlowBox::paintBoxShadow(GraphicsContext* context, RenderStyle* s, ShadowStyle shadowStyle, int tx, int ty, int w, int h)
    700700{
    701701    if ((!prevLineBox() && !nextLineBox()) || !parent())
    702         boxModelObject()->paintBoxShadow(context, tx, ty, w, h, s);
     702        boxModelObject()->paintBoxShadow(context, tx, ty, w, h, s, shadowStyle);
    703703    else {
    704704        // FIXME: We can do better here in the multi-line case. We want to push a clip so that the shadow doesn't
    705705        // protrude incorrectly at the edges, and we want to possibly include shadows cast from the previous/following lines
    706         boxModelObject()->paintBoxShadow(context, tx, ty, w, h, s, includeLeftEdge(), includeRightEdge());
     706        boxModelObject()->paintBoxShadow(context, tx, ty, w, h, s, shadowStyle, includeLeftEdge(), includeRightEdge());
    707707    }
    708708}
     
    728728        // Shadow comes first and is behind the background and border.
    729729        if (styleToUse->boxShadow())
    730             paintBoxShadow(context, styleToUse, tx, ty, w, h);
     730            paintBoxShadow(context, styleToUse, Normal, tx, ty, w, h);
    731731
    732732        Color c = styleToUse->backgroundColor();
    733733        paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), tx, ty, w, h);
     734
     735        if (styleToUse->boxShadow())
     736            paintBoxShadow(context, styleToUse, Inset, tx, ty, w, h);
    734737
    735738        // :first-line cannot be used to put borders on a line. Always paint borders with our
  • trunk/WebCore/rendering/InlineFlowBox.h

    r45702 r46295  
    9090    void paintFillLayers(const RenderObject::PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int w, int h, CompositeOperator = CompositeSourceOver);
    9191    void paintFillLayer(const RenderObject::PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int w, int h, CompositeOperator = CompositeSourceOver);
    92     void paintBoxShadow(GraphicsContext*, RenderStyle*, int tx, int ty, int w, int h);
     92    void paintBoxShadow(GraphicsContext*, RenderStyle*, ShadowStyle, int tx, int ty, int w, int h);
    9393    virtual void paintTextDecorations(RenderObject::PaintInfo&, int tx, int ty, bool paintedChildren = false);
    9494    virtual void paint(RenderObject::PaintInfo&, int tx, int ty);
  • trunk/WebCore/rendering/RenderBox.cpp

    r45624 r46295  
    44 *           (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
    55 *           (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
    6  * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
     6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
    77 *
    88 * This library is free software; you can redistribute it and/or
     
    608608    // FIXME: Should eventually give the theme control over whether the box shadow should paint, since controls could have
    609609    // custom shadows of their own.
    610     paintBoxShadow(paintInfo.context, tx, ty, w, h, style());
     610    paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Normal);
    611611
    612612    // If we have a native theme appearance, paint that before painting our background.
     
    622622            theme()->paintDecorations(this, paintInfo, IntRect(tx, ty, w, h));
    623623    }
     624    paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Inset);
    624625
    625626    // The theme will tell us whether or not we should also paint the CSS border.
  • trunk/WebCore/rendering/RenderBoxModelObject.cpp

    r46281 r46295  
    11431143}
    11441144
    1145 void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int ty, int w, int h, const RenderStyle* s, bool begin, bool end)
     1145void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int ty, int w, int h, const RenderStyle* s, ShadowStyle shadowStyle, bool begin, bool end)
    11461146{
    11471147    // FIXME: Deal with border-image.  Would be great to use border-image as a mask.
     
    11511151
    11521152    IntRect rect(tx, ty, w, h);
     1153    IntSize topLeft;
     1154    IntSize topRight;
     1155    IntSize bottomLeft;
     1156    IntSize bottomRight;
     1157
    11531158    bool hasBorderRadius = s->hasBorderRadius();
     1159    if (hasBorderRadius && (begin || end)) {
     1160        IntSize topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius;
     1161        s->getBorderRadiiForRect(rect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
     1162
     1163        if (begin) {
     1164            if (shadowStyle == Inset) {
     1165                topLeftRadius.expand(-borderLeft(), -borderTop());
     1166                topLeftRadius.clampNegativeToZero();
     1167                bottomLeftRadius.expand(-borderLeft(), -borderBottom());
     1168                bottomLeftRadius.clampNegativeToZero();
     1169            }
     1170            topLeft = topLeftRadius;
     1171            bottomLeft = bottomLeftRadius;
     1172        }
     1173        if (end) {
     1174            if (shadowStyle == Inset) {
     1175                topRightRadius.expand(-borderRight(), -borderTop());
     1176                topRightRadius.clampNegativeToZero();
     1177                bottomRightRadius.expand(-borderRight(), -borderBottom());
     1178                bottomRightRadius.clampNegativeToZero();
     1179            }
     1180            topRight = topRightRadius;
     1181            bottomRight = bottomRightRadius;
     1182        }
     1183    }
     1184
     1185    if (shadowStyle == Inset) {
     1186        rect.move(begin ? borderLeft() : 0, borderTop());
     1187        rect.setWidth(rect.width() - (begin ? borderLeft() : 0) - (end ? borderRight() : 0));
     1188        rect.setHeight(rect.height() - borderTop() - borderBottom());
     1189    }
     1190
    11541191    bool hasOpaqueBackground = s->backgroundColor().isValid() && s->backgroundColor().alpha() == 255;
    11551192    for (ShadowData* shadow = s->boxShadow(); shadow; shadow = shadow->next) {
     1193        if (shadow->style != shadowStyle)
     1194            continue;
     1195
    11561196        IntSize shadowOffset(shadow->x, shadow->y);
    11571197        int shadowBlur = shadow->blur;
    11581198        int shadowSpread = shadow->spread;
    1159         IntRect fillRect(rect);
    1160         fillRect.inflate(shadowSpread);
    1161         if (fillRect.isEmpty())
    1162             continue;
    1163 
    1164         IntRect shadowRect(rect);
    1165         shadowRect.inflate(shadowBlur + shadowSpread);
    1166         shadowRect.move(shadowOffset);
    1167 
    1168         context->save();
    1169         context->clip(shadowRect);
    1170 
    1171         // Move the fill just outside the clip, adding 1 pixel separation so that the fill does not
    1172         // bleed in (due to antialiasing) if the context is transformed.
    1173         IntSize extraOffset(w + max(0, shadowOffset.width()) + shadowBlur + 2 * shadowSpread + 1, 0);
    1174         shadowOffset -= extraOffset;
    1175         fillRect.move(extraOffset);
    1176 
    1177         context->setShadow(shadowOffset, shadowBlur, shadow->color);
    1178         if (hasBorderRadius) {
    1179             IntSize topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius;
    1180             s->getBorderRadiiForRect(rect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
    1181 
    1182             IntSize topLeft = begin ? topLeftRadius : IntSize();
    1183             IntSize topRight = end ? topRightRadius : IntSize();
    1184             IntSize bottomLeft = begin ? bottomLeftRadius : IntSize();
    1185             IntSize bottomRight = end ? bottomRightRadius : IntSize();
    1186 
    1187             IntRect rectToClipOut = rect;
    1188             IntSize topLeftToClipOut = topLeft;
    1189             IntSize topRightToClipOut = topRight;
    1190             IntSize bottomLeftToClipOut = bottomLeft;
    1191             IntSize bottomRightToClipOut = bottomRight;
    1192 
    1193             if (shadowSpread < 0) {
    1194                 topLeft.expand(shadowSpread, shadowSpread);
    1195                 topLeft.clampNegativeToZero();
    1196 
    1197                 topRight.expand(shadowSpread, shadowSpread);
    1198                 topRight.clampNegativeToZero();
    1199 
    1200                 bottomLeft.expand(shadowSpread, shadowSpread);
    1201                 bottomLeft.clampNegativeToZero();
    1202 
    1203                 bottomRight.expand(shadowSpread, shadowSpread);
    1204                 bottomRight.clampNegativeToZero();
    1205             }
    1206 
    1207             // If the box is opaque, it is unnecessary to clip it out. However, doing so saves time
    1208             // when painting the shadow. On the other hand, it introduces subpixel gaps along the
    1209             // corners. Those are avoided by insetting the clipping path by one pixel.
    1210             if (hasOpaqueBackground) {
    1211                 rectToClipOut.inflate(-1);
    1212 
    1213                 topLeftToClipOut.expand(-1, -1);
    1214                 topLeftToClipOut.clampNegativeToZero();
    1215 
    1216                 topRightToClipOut.expand(-1, -1);
    1217                 topRightToClipOut.clampNegativeToZero();
    1218 
    1219                 bottomLeftToClipOut.expand(-1, -1);
    1220                 bottomLeftToClipOut.clampNegativeToZero();
    1221 
    1222                 bottomRightToClipOut.expand(-1, -1);
    1223                 bottomRightToClipOut.clampNegativeToZero();
    1224             }
    1225 
    1226             if (!rectToClipOut.isEmpty())
    1227                 context->clipOutRoundedRect(rectToClipOut, topLeftToClipOut, topRightToClipOut, bottomLeftToClipOut, bottomRightToClipOut);
    1228             context->fillRoundedRect(fillRect, topLeft, topRight, bottomLeft, bottomRight, Color::black);
     1199        Color& shadowColor = shadow->color;
     1200
     1201        if (shadow->style == Normal) {
     1202            IntRect fillRect(rect);
     1203            fillRect.inflate(shadowSpread);
     1204            if (fillRect.isEmpty())
     1205                continue;
     1206
     1207            IntRect shadowRect(rect);
     1208            shadowRect.inflate(shadowBlur + shadowSpread);
     1209            shadowRect.move(shadowOffset);
     1210
     1211            context->save();
     1212            context->clip(shadowRect);
     1213
     1214            // Move the fill just outside the clip, adding 1 pixel separation so that the fill does not
     1215            // bleed in (due to antialiasing) if the context is transformed.
     1216            IntSize extraOffset(w + max(0, shadowOffset.width()) + shadowBlur + 2 * shadowSpread + 1, 0);
     1217            shadowOffset -= extraOffset;
     1218            fillRect.move(extraOffset);
     1219
     1220            context->setShadow(shadowOffset, shadowBlur, shadowColor);
     1221            if (hasBorderRadius) {
     1222                IntRect rectToClipOut = rect;
     1223                IntSize topLeftToClipOut = topLeft;
     1224                IntSize topRightToClipOut = topRight;
     1225                IntSize bottomLeftToClipOut = bottomLeft;
     1226                IntSize bottomRightToClipOut = bottomRight;
     1227
     1228                if (shadowSpread < 0) {
     1229                    topLeft.expand(shadowSpread, shadowSpread);
     1230                    topLeft.clampNegativeToZero();
     1231
     1232                    topRight.expand(shadowSpread, shadowSpread);
     1233                    topRight.clampNegativeToZero();
     1234
     1235                    bottomLeft.expand(shadowSpread, shadowSpread);
     1236                    bottomLeft.clampNegativeToZero();
     1237
     1238                    bottomRight.expand(shadowSpread, shadowSpread);
     1239                    bottomRight.clampNegativeToZero();
     1240                }
     1241
     1242                // If the box is opaque, it is unnecessary to clip it out. However, doing so saves time
     1243                // when painting the shadow. On the other hand, it introduces subpixel gaps along the
     1244                // corners. Those are avoided by insetting the clipping path by one pixel.
     1245                if (hasOpaqueBackground) {
     1246                    rectToClipOut.inflate(-1);
     1247
     1248                    topLeftToClipOut.expand(-1, -1);
     1249                    topLeftToClipOut.clampNegativeToZero();
     1250
     1251                    topRightToClipOut.expand(-1, -1);
     1252                    topRightToClipOut.clampNegativeToZero();
     1253
     1254                    bottomLeftToClipOut.expand(-1, -1);
     1255                    bottomLeftToClipOut.clampNegativeToZero();
     1256
     1257                    bottomRightToClipOut.expand(-1, -1);
     1258                    bottomRightToClipOut.clampNegativeToZero();
     1259                }
     1260
     1261                if (!rectToClipOut.isEmpty())
     1262                    context->clipOutRoundedRect(rectToClipOut, topLeftToClipOut, topRightToClipOut, bottomLeftToClipOut, bottomRightToClipOut);
     1263                context->fillRoundedRect(fillRect, topLeft, topRight, bottomLeft, bottomRight, Color::black);
     1264            } else {
     1265                IntRect rectToClipOut = rect;
     1266
     1267                // If the box is opaque, it is unnecessary to clip it out. However, doing so saves time
     1268                // when painting the shadow. On the other hand, it introduces subpixel gaps along the
     1269                // edges if they are not pixel-aligned. Those are avoided by insetting the clipping path
     1270                // by one pixel.
     1271                if (hasOpaqueBackground) {
     1272                    TransformationMatrix currentTransformation = context->getCTM();
     1273                    if (currentTransformation.a() != 1 || (currentTransformation.d() != 1 && currentTransformation.d() != -1)
     1274                            || currentTransformation.b() || currentTransformation.c())
     1275                        rectToClipOut.inflate(-1);
     1276                }
     1277
     1278                if (!rectToClipOut.isEmpty())
     1279                    context->clipOut(rectToClipOut);
     1280                context->fillRect(fillRect, Color::black);
     1281            }
     1282
     1283            context->restore();
    12291284        } else {
    1230             IntRect rectToClipOut = rect;
    1231 
    1232             // If the box is opaque, it is unnecessary to clip it out. However, doing so saves time
    1233             // when painting the shadow. On the other hand, it introduces subpixel gaps along the
    1234             // edges if they are not pixel-aligned. Those are avoided by insetting the clipping path
    1235             // by one pixel.
    1236             if (hasOpaqueBackground) {
    1237                 TransformationMatrix currentTransformation = context->getCTM();
    1238                 if (currentTransformation.a() != 1 || (currentTransformation.d() != 1 && currentTransformation.d() != -1)
    1239                         || currentTransformation.b() || currentTransformation.c())
    1240                     rectToClipOut.inflate(-1);
    1241             }
    1242 
    1243             if (!rectToClipOut.isEmpty())
    1244                 context->clipOut(rectToClipOut);
    1245             context->fillRect(fillRect, Color::black);
    1246         }
    1247         context->restore();
     1285            // Inset shadow.
     1286            IntRect holeRect(rect);
     1287            holeRect.inflate(-shadowSpread);
     1288
     1289            if (holeRect.isEmpty()) {
     1290                if (hasBorderRadius)
     1291                    context->fillRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, shadowColor);
     1292                else
     1293                    context->fillRect(rect, shadowColor);
     1294                continue;
     1295            }
     1296            if (!begin) {
     1297                holeRect.move(-max(shadowOffset.width(), 0) - shadowBlur, 0);
     1298                holeRect.setWidth(holeRect.width() + max(shadowOffset.width(), 0) + shadowBlur);
     1299            }
     1300            if (!end)
     1301                holeRect.setWidth(holeRect.width() - min(shadowOffset.width(), 0) + shadowBlur);
     1302
     1303            Color fillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), 255);
     1304
     1305            IntRect outerRect(rect);
     1306            outerRect.inflateX(w - 2 * shadowSpread);
     1307            outerRect.inflateY(h - 2 * shadowSpread);
     1308
     1309            context->save();
     1310
     1311            if (hasBorderRadius)
     1312                context->clip(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight));
     1313            else
     1314                context->clip(rect);
     1315
     1316            IntSize extraOffset(2 * w + max(0, shadowOffset.width()) + shadowBlur - 2 * shadowSpread + 1, 0);
     1317            context->translate(extraOffset.width(), extraOffset.height());
     1318            shadowOffset -= extraOffset;
     1319
     1320            context->beginPath();
     1321            context->addPath(Path::createRectangle(outerRect));
     1322
     1323            if (hasBorderRadius) {
     1324                if (shadowSpread > 0) {
     1325                    topLeft.expand(-shadowSpread, -shadowSpread);
     1326                    topLeft.clampNegativeToZero();
     1327
     1328                    topRight.expand(-shadowSpread, -shadowSpread);
     1329                    topRight.clampNegativeToZero();
     1330
     1331                    bottomLeft.expand(-shadowSpread, -shadowSpread);
     1332                    bottomLeft.clampNegativeToZero();
     1333
     1334                    bottomRight.expand(-shadowSpread, -shadowSpread);
     1335                    bottomRight.clampNegativeToZero();
     1336                }
     1337                context->addPath(Path::createRoundedRectangle(holeRect, topLeft, topRight, bottomLeft, bottomRight));
     1338            } else
     1339                context->addPath(Path::createRectangle(holeRect));
     1340
     1341            context->setFillRule(RULE_EVENODD);
     1342            context->setFillColor(fillColor);
     1343            context->setShadow(shadowOffset, shadowBlur, shadowColor);
     1344            context->fillPath();
     1345
     1346            context->restore();
     1347        }
    12481348    }
    12491349}
  • trunk/WebCore/rendering/RenderBoxModelObject.h

    r45317 r46295  
    9090    void paintBorder(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true);
    9191    bool paintNinePieceImage(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver);
    92     void paintBoxShadow(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true);
     92    void paintBoxShadow(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, ShadowStyle, bool begin = true, bool end = true);
    9393    void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, InlineFlowBox* = 0, CompositeOperator = CompositeSourceOver);
    9494
  • trunk/WebCore/rendering/RenderFieldset.cpp

    r45624 r46295  
    132132    ty += yOff;
    133133
    134     paintBoxShadow(paintInfo.context, tx, ty, w, h, style());
     134    paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Normal);
    135135
    136136    paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), tx, ty, w, h);
     137    paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Inset);
    137138
    138139    if (!style()->hasBorder())
  • trunk/WebCore/rendering/RenderTable.cpp

    r45624 r46295  
    55 *           (C) 1999 Lars Knoll (knoll@kde.org)
    66 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    7  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
     7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
    88 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
    99 *
     
    515515    }
    516516
    517     paintBoxShadow(paintInfo.context, tx, ty, w, h, style());
     517    paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Normal);
    518518   
    519519    paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), tx, ty, w, h);
     520    paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Inset);
    520521
    521522    if (style()->hasBorder() && !collapseBorders())
  • trunk/WebCore/rendering/RenderTableCell.cpp

    r45317 r46295  
    55 *           (C) 1999 Lars Knoll (knoll@kde.org)
    66 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    7  * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
     7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
    88 *
    99 * This library is free software; you can redistribute it and/or
     
    848848   
    849849    if (style()->boxShadow())
    850         paintBoxShadow(paintInfo.context, tx, ty, w, h, style());
     850        paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Normal);
    851851   
    852852    // Paint our cell background.
    853853    paintBackgroundsBehindCell(paintInfo, tx, ty, this);
     854    if (style()->boxShadow())
     855        paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Inset);
    854856
    855857    if (!style()->hasBorder() || tableElt->collapseBorders())
  • trunk/WebCore/rendering/style/ShadowData.h

    r46097 r46295  
    33 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2000 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
     5 * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
    66 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
    77 *
     
    3030namespace WebCore {
    3131
     32enum ShadowStyle { Normal, Inset };
     33
    3234// This struct holds information about shadows for the text-shadow and box-shadow properties.
    3335
     
    3840        , blur(0)
    3941        , spread(0)
     42        , style(Normal)
    4043        , next(0)
    4144    {
    4245    }
    4346
    44     ShadowData(int x, int y, int blur, int spread, const Color& color)
     47    ShadowData(int x, int y, int blur, int spread, ShadowStyle style, const Color& color)
    4548        : x(x)
    4649        , y(y)
    4750        , blur(blur)
    4851        , spread(spread)
     52        , style(style)
    4953        , color(color)
    5054        , next(0)
     
    6670    int blur;
    6771    int spread;
     72    ShadowStyle style;
    6873    Color color;
    6974    ShadowData* next;
Note: See TracChangeset for help on using the changeset viewer.