[webkit-changes] cvs commit: WebCore/kwq KWQPainter.h KWQPainter.mm KWQPixmap.h KWQPixmap.mm WebCoreImageRenderer.h

David hyatt at opensource.apple.com
Fri Aug 26 17:14:23 PDT 2005


hyatt       05/08/26 17:14:23

  Modified:    .        ChangeLog
               khtml/css css_computedstyle.cpp css_valueimpl.cpp
                        css_valueimpl.h cssparser.cpp cssparser.h
                        cssproperties.in cssstyleselector.cpp
                        cssstyleselector.h cssvalues.in
               khtml/dom css_value.h
               khtml/misc loader.h
               khtml/rendering render_box.cpp render_box.h render_line.cpp
                        render_object.cpp render_object.h render_style.cpp
                        render_style.h
               kwq      KWQPainter.h KWQPainter.mm KWQPixmap.h KWQPixmap.mm
                        WebCoreImageRenderer.h
  Log:
  	Implement four new CSS properties from CSS3.  border-image, background-clip,
  	background-origin, and border-radius.  Border radius support is still in the
  	initial stages, with only transparent borders supported.
  
          Reviewed by darin
  
          * khtml/css/css_computedstyle.cpp:
          (DOM::):
          (DOM::CSSComputedStyleDeclarationImpl::getPropertyCSSValue):
          * khtml/css/css_valueimpl.cpp:
          (DOM::CSSPrimitiveValueImpl::CSSPrimitiveValueImpl):
          (DOM::CSSPrimitiveValueImpl::cssText):
          (DOM::PairImpl::PairImpl):
          (DOM::PairImpl::~PairImpl):
          (DOM::PairImpl::setFirst):
          (DOM::PairImpl::setSecond):
          (DOM::CSSImageValueImpl::~CSSImageValueImpl):
          (DOM::CSSImageValueImpl::image):
          (DOM::CSSBorderImageValueImpl::CSSBorderImageValueImpl):
          (DOM::CSSBorderImageValueImpl::~CSSBorderImageValueImpl):
          (DOM::CSSBorderImageValueImpl::cssText):
          * khtml/css/css_valueimpl.h:
          (DOM::CSSPrimitiveValueImpl::getPairValue):
          (DOM::CSSPrimitiveValueImpl::):
          (DOM::RectImpl::top):
          (DOM::RectImpl::right):
          (DOM::RectImpl::bottom):
          (DOM::RectImpl::left):
          (DOM::PairImpl::first):
          (DOM::PairImpl::second):
          (DOM::CSSBorderImageValueImpl::cssValueType):
          * khtml/css/cssparser.cpp:
          (CSSParser::parseValue):
          (CSSParser::parseBackgroundShorthand):
          (CSSParser::parseBackgroundProperty):
          (BorderImageParseContext::m_verticalRule):
          (BorderImageParseContext::~BorderImageParseContext):
          (BorderImageParseContext::failed):
          (BorderImageParseContext::allowBreak):
          (BorderImageParseContext::allowNumber):
          (BorderImageParseContext::allowSlash):
          (BorderImageParseContext::allowWidth):
          (BorderImageParseContext::allowRule):
          (BorderImageParseContext::commitImage):
          (BorderImageParseContext::commitNumber):
          (BorderImageParseContext::commitSlash):
          (BorderImageParseContext::commitWidth):
          (BorderImageParseContext::commitRule):
          (BorderImageParseContext::commitBorderImage):
          (CSSParser::parseBorderImage):
          * khtml/css/cssparser.h:
          * khtml/css/cssproperties.in:
          * khtml/css/cssstyleselector.cpp:
          (khtml::CSSStyleSelector::applyProperty):
          (khtml::CSSStyleSelector::mapBackgroundClip):
          (khtml::CSSStyleSelector::mapBackgroundOrigin):
          * khtml/css/cssstyleselector.h:
          * khtml/css/cssvalues.in:
          * khtml/dom/css_value.h:
          (DOM::CSSPrimitiveValue::):
          * khtml/misc/loader.h:
          (khtml::CachedObject::isLoaded):
          * khtml/rendering/render_box.cpp:
          (RenderBox::paintBackground):
          (RenderBox::paintBackgroundExtended):
          * khtml/rendering/render_box.h:
          * khtml/rendering/render_line.cpp:
          (khtml::InlineFlowBox::onEndChain):
          (khtml::InlineFlowBox::determineSpacingForFlowBoxes):
          (khtml::InlineFlowBox::paintBackground):
          (khtml::InlineFlowBox::paintBackgroundAndBorder):
          * khtml/rendering/render_object.cpp:
          (RenderObject::paintBorderImage):
          (RenderObject::paintBorder):
          (RenderObject::updateBackgroundImages):
          (RenderObject::setPixmap):
          * khtml/rendering/render_object.h:
          (khtml::RenderObject::paintBackgroundExtended):
          * khtml/rendering/render_style.cpp:
          (m_next):
          (BackgroundLayer::BackgroundLayer):
          (BackgroundLayer::operator=):
          (BackgroundLayer::operator==):
          (BackgroundLayer::fillUnsetProperties):
          (BackgroundLayer::cullEmptyLayers):
          * khtml/rendering/render_style.h:
          (khtml::BorderValue::nonZero):
          (khtml::):
          (khtml::BorderImage::m_verticalRule):
          (khtml::BorderImage::operator==):
          (khtml::BorderImage::hasImage):
          (khtml::BorderImage::image):
          (khtml::BorderData::hasBorder):
          (khtml::BorderData::hasBorderRadius):
          (khtml::BorderData::borderLeftWidth):
          (khtml::BorderData::borderRightWidth):
          (khtml::BorderData::borderTopWidth):
          (khtml::BorderData::borderBottomWidth):
          (khtml::BorderData::operator==):
          (khtml::BackgroundLayer::backgroundClip):
          (khtml::BackgroundLayer::backgroundOrigin):
          (khtml::BackgroundLayer::isBackgroundClipSet):
          (khtml::BackgroundLayer::isBackgroundOriginSet):
          (khtml::BackgroundLayer::setBackgroundClip):
          (khtml::BackgroundLayer::setBackgroundOrigin):
          (khtml::BackgroundLayer::clearBackgroundClip):
          (khtml::BackgroundLayer::clearBackgroundOrigin):
          (khtml::RenderStyle::borderImage):
          (khtml::RenderStyle::borderTopLeftRadius):
          (khtml::RenderStyle::borderTopRightRadius):
          (khtml::RenderStyle::borderBottomLeftRadius):
          (khtml::RenderStyle::borderBottomRightRadius):
          (khtml::RenderStyle::hasBorderRadius):
          (khtml::RenderStyle::borderLeftWidth):
          (khtml::RenderStyle::borderRightWidth):
          (khtml::RenderStyle::borderTopWidth):
          (khtml::RenderStyle::borderBottomWidth):
          (khtml::RenderStyle::backgroundClip):
          (khtml::RenderStyle::backgroundOrigin):
          (khtml::RenderStyle::resetBorder):
          (khtml::RenderStyle::resetBorderImage):
          (khtml::RenderStyle::resetBorderRadius):
          (khtml::RenderStyle::resetBorderTopLeftRadius):
          (khtml::RenderStyle::resetBorderTopRightRadius):
          (khtml::RenderStyle::resetBorderBottomLeftRadius):
          (khtml::RenderStyle::resetBorderBottomRightRadius):
          (khtml::RenderStyle::setBorderImage):
          (khtml::RenderStyle::setBorderTopLeftRadius):
          (khtml::RenderStyle::setBorderTopRightRadius):
          (khtml::RenderStyle::setBorderBottomLeftRadius):
          (khtml::RenderStyle::setBorderBottomRightRadius):
          (khtml::RenderStyle::setBorderRadius):
          (khtml::RenderStyle::initialBackgroundClip):
          (khtml::RenderStyle::initialBackgroundOrigin):
          (khtml::RenderStyle::initialBorderImage):
          (khtml::RenderStyle::initialBorderRadius):
          * kwq/KWQPainter.h:
          (QPainter::):
          * kwq/KWQPainter.mm:
          (QPainter::drawEllipse):
          (QPainter::drawScaledAndTiledPixmap):
          (QPainter::addRoundedRectClip):
          * kwq/KWQPixmap.h:
          * kwq/KWQPixmap.mm:
          (QPixmap::setAnimationRect):
          * kwq/WebCoreImageRenderer.h:
  
  Revision  Changes    Path
  1.18      +149 -0    WebCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebCore/ChangeLog,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- ChangeLog	27 Aug 2005 00:12:33 -0000	1.17
  +++ ChangeLog	27 Aug 2005 00:14:18 -0000	1.18
  @@ -1,5 +1,154 @@
   2005-08-26  David Hyatt  <hyatt at apple.com>
   
  +	Implement four new CSS properties from CSS3.  border-image, background-clip,
  +	background-origin, and border-radius.  Border radius support is still in the
  +	initial stages, with only transparent borders supported.
  +	
  +        Reviewed by darin
  +
  +        * khtml/css/css_computedstyle.cpp:
  +        (DOM::):
  +        (DOM::CSSComputedStyleDeclarationImpl::getPropertyCSSValue):
  +        * khtml/css/css_valueimpl.cpp:
  +        (DOM::CSSPrimitiveValueImpl::CSSPrimitiveValueImpl):
  +        (DOM::CSSPrimitiveValueImpl::cssText):
  +        (DOM::PairImpl::PairImpl):
  +        (DOM::PairImpl::~PairImpl):
  +        (DOM::PairImpl::setFirst):
  +        (DOM::PairImpl::setSecond):
  +        (DOM::CSSImageValueImpl::~CSSImageValueImpl):
  +        (DOM::CSSImageValueImpl::image):
  +        (DOM::CSSBorderImageValueImpl::CSSBorderImageValueImpl):
  +        (DOM::CSSBorderImageValueImpl::~CSSBorderImageValueImpl):
  +        (DOM::CSSBorderImageValueImpl::cssText):
  +        * khtml/css/css_valueimpl.h:
  +        (DOM::CSSPrimitiveValueImpl::getPairValue):
  +        (DOM::CSSPrimitiveValueImpl::):
  +        (DOM::RectImpl::top):
  +        (DOM::RectImpl::right):
  +        (DOM::RectImpl::bottom):
  +        (DOM::RectImpl::left):
  +        (DOM::PairImpl::first):
  +        (DOM::PairImpl::second):
  +        (DOM::CSSBorderImageValueImpl::cssValueType):
  +        * khtml/css/cssparser.cpp:
  +        (CSSParser::parseValue):
  +        (CSSParser::parseBackgroundShorthand):
  +        (CSSParser::parseBackgroundProperty):
  +        (BorderImageParseContext::m_verticalRule):
  +        (BorderImageParseContext::~BorderImageParseContext):
  +        (BorderImageParseContext::failed):
  +        (BorderImageParseContext::allowBreak):
  +        (BorderImageParseContext::allowNumber):
  +        (BorderImageParseContext::allowSlash):
  +        (BorderImageParseContext::allowWidth):
  +        (BorderImageParseContext::allowRule):
  +        (BorderImageParseContext::commitImage):
  +        (BorderImageParseContext::commitNumber):
  +        (BorderImageParseContext::commitSlash):
  +        (BorderImageParseContext::commitWidth):
  +        (BorderImageParseContext::commitRule):
  +        (BorderImageParseContext::commitBorderImage):
  +        (CSSParser::parseBorderImage):
  +        * khtml/css/cssparser.h:
  +        * khtml/css/cssproperties.in:
  +        * khtml/css/cssstyleselector.cpp:
  +        (khtml::CSSStyleSelector::applyProperty):
  +        (khtml::CSSStyleSelector::mapBackgroundClip):
  +        (khtml::CSSStyleSelector::mapBackgroundOrigin):
  +        * khtml/css/cssstyleselector.h:
  +        * khtml/css/cssvalues.in:
  +        * khtml/dom/css_value.h:
  +        (DOM::CSSPrimitiveValue::):
  +        * khtml/misc/loader.h:
  +        (khtml::CachedObject::isLoaded):
  +        * khtml/rendering/render_box.cpp:
  +        (RenderBox::paintBackground):
  +        (RenderBox::paintBackgroundExtended):
  +        * khtml/rendering/render_box.h:
  +        * khtml/rendering/render_line.cpp:
  +        (khtml::InlineFlowBox::onEndChain):
  +        (khtml::InlineFlowBox::determineSpacingForFlowBoxes):
  +        (khtml::InlineFlowBox::paintBackground):
  +        (khtml::InlineFlowBox::paintBackgroundAndBorder):
  +        * khtml/rendering/render_object.cpp:
  +        (RenderObject::paintBorderImage):
  +        (RenderObject::paintBorder):
  +        (RenderObject::updateBackgroundImages):
  +        (RenderObject::setPixmap):
  +        * khtml/rendering/render_object.h:
  +        (khtml::RenderObject::paintBackgroundExtended):
  +        * khtml/rendering/render_style.cpp:
  +        (m_next):
  +        (BackgroundLayer::BackgroundLayer):
  +        (BackgroundLayer::operator=):
  +        (BackgroundLayer::operator==):
  +        (BackgroundLayer::fillUnsetProperties):
  +        (BackgroundLayer::cullEmptyLayers):
  +        * khtml/rendering/render_style.h:
  +        (khtml::BorderValue::nonZero):
  +        (khtml::):
  +        (khtml::BorderImage::m_verticalRule):
  +        (khtml::BorderImage::operator==):
  +        (khtml::BorderImage::hasImage):
  +        (khtml::BorderImage::image):
  +        (khtml::BorderData::hasBorder):
  +        (khtml::BorderData::hasBorderRadius):
  +        (khtml::BorderData::borderLeftWidth):
  +        (khtml::BorderData::borderRightWidth):
  +        (khtml::BorderData::borderTopWidth):
  +        (khtml::BorderData::borderBottomWidth):
  +        (khtml::BorderData::operator==):
  +        (khtml::BackgroundLayer::backgroundClip):
  +        (khtml::BackgroundLayer::backgroundOrigin):
  +        (khtml::BackgroundLayer::isBackgroundClipSet):
  +        (khtml::BackgroundLayer::isBackgroundOriginSet):
  +        (khtml::BackgroundLayer::setBackgroundClip):
  +        (khtml::BackgroundLayer::setBackgroundOrigin):
  +        (khtml::BackgroundLayer::clearBackgroundClip):
  +        (khtml::BackgroundLayer::clearBackgroundOrigin):
  +        (khtml::RenderStyle::borderImage):
  +        (khtml::RenderStyle::borderTopLeftRadius):
  +        (khtml::RenderStyle::borderTopRightRadius):
  +        (khtml::RenderStyle::borderBottomLeftRadius):
  +        (khtml::RenderStyle::borderBottomRightRadius):
  +        (khtml::RenderStyle::hasBorderRadius):
  +        (khtml::RenderStyle::borderLeftWidth):
  +        (khtml::RenderStyle::borderRightWidth):
  +        (khtml::RenderStyle::borderTopWidth):
  +        (khtml::RenderStyle::borderBottomWidth):
  +        (khtml::RenderStyle::backgroundClip):
  +        (khtml::RenderStyle::backgroundOrigin):
  +        (khtml::RenderStyle::resetBorder):
  +        (khtml::RenderStyle::resetBorderImage):
  +        (khtml::RenderStyle::resetBorderRadius):
  +        (khtml::RenderStyle::resetBorderTopLeftRadius):
  +        (khtml::RenderStyle::resetBorderTopRightRadius):
  +        (khtml::RenderStyle::resetBorderBottomLeftRadius):
  +        (khtml::RenderStyle::resetBorderBottomRightRadius):
  +        (khtml::RenderStyle::setBorderImage):
  +        (khtml::RenderStyle::setBorderTopLeftRadius):
  +        (khtml::RenderStyle::setBorderTopRightRadius):
  +        (khtml::RenderStyle::setBorderBottomLeftRadius):
  +        (khtml::RenderStyle::setBorderBottomRightRadius):
  +        (khtml::RenderStyle::setBorderRadius):
  +        (khtml::RenderStyle::initialBackgroundClip):
  +        (khtml::RenderStyle::initialBackgroundOrigin):
  +        (khtml::RenderStyle::initialBorderImage):
  +        (khtml::RenderStyle::initialBorderRadius):
  +        * kwq/KWQPainter.h:
  +        (QPainter::):
  +        * kwq/KWQPainter.mm:
  +        (QPainter::drawEllipse):
  +        (QPainter::drawScaledAndTiledPixmap):
  +        (QPainter::addRoundedRectClip):
  +        * kwq/KWQPixmap.h:
  +        * kwq/KWQPixmap.mm:
  +        (QPixmap::setAnimationRect):
  +        * kwq/WebCoreImageRenderer.h:
  +
  +2005-08-26  David Hyatt  <hyatt at apple.com>
  +
   	Fix comment parsing so that it is lax for <style>.  Better fix eventually
   	will be to not even have the tokenizer do anything with <!-- and --> inside
   	<style> and <script>.
  
  
  
  1.35      +13 -2     WebCore/khtml/css/css_computedstyle.cpp
  
  Index: css_computedstyle.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/css/css_computedstyle.cpp,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- css_computedstyle.cpp	30 Jul 2005 21:19:45 -0000	1.34
  +++ css_computedstyle.cpp	27 Aug 2005 00:14:18 -0000	1.35
  @@ -39,6 +39,7 @@
   #import "KWQLogging.h"
   #endif
   
  +using khtml::EBackgroundBox;
   using khtml::EBorderStyle;
   using khtml::ETextAlign;
   using khtml::Font;
  @@ -60,6 +61,8 @@
       CSS_PROP_BACKGROUND_IMAGE,
       CSS_PROP_BACKGROUND_REPEAT,
       CSS_PROP_BACKGROUND_ATTACHMENT,
  +    CSS_PROP_BACKGROUND_CLIP,
  +    CSS_PROP_BACKGROUND_ORIGIN,
       CSS_PROP_BACKGROUND_POSITION,
       CSS_PROP_BACKGROUND_POSITION_X,
       CSS_PROP_BACKGROUND_POSITION_Y,
  @@ -361,8 +364,16 @@
       case CSS_PROP_BACKGROUND_ATTACHMENT:
           if (style->backgroundAttachment())
               return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL);
  -        else
  -            return new CSSPrimitiveValueImpl(CSS_VAL_FIXED);
  +        return new CSSPrimitiveValueImpl(CSS_VAL_FIXED);
  +    case CSS_PROP_BACKGROUND_CLIP:
  +    case CSS_PROP_BACKGROUND_ORIGIN: {
  +        EBackgroundBox box = (propertyID == CSS_PROP_BACKGROUND_CLIP ? style->backgroundClip() : style->backgroundOrigin());
  +        if (box == khtml::BGBORDER)
  +            return new CSSPrimitiveValueImpl(CSS_VAL_BORDER);
  +        if (box == khtml::BGPADDING)
  +            return new CSSPrimitiveValueImpl(CSS_VAL_PADDING);
  +        return new CSSPrimitiveValueImpl(CSS_VAL_CONTENT);
  +    }
       case CSS_PROP_BACKGROUND_POSITION:
       {
           DOMString string;
  
  
  
  1.75      +92 -3     WebCore/khtml/css/css_valueimpl.cpp
  
  Index: css_valueimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/css/css_valueimpl.cpp,v
  retrieving revision 1.74
  retrieving revision 1.75
  diff -u -r1.74 -r1.75
  --- css_valueimpl.cpp	25 Aug 2005 17:46:57 -0000	1.74
  +++ css_valueimpl.cpp	27 Aug 2005 00:14:18 -0000	1.75
  @@ -53,6 +53,7 @@
   
   using khtml::FontDef;
   using khtml::CSSStyleSelector;
  +using khtml::CachedImage;
   
   namespace DOM {
   
  @@ -800,6 +801,14 @@
       m_type = CSSPrimitiveValue::CSS_RGBCOLOR;
   }
   
  +CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(PairImpl* p)
  +{
  +    m_value.pair = p;
  +    if (p)
  +	p->ref();
  +    m_type = CSSPrimitiveValue::CSS_PAIR;
  +}
  +
   CSSPrimitiveValueImpl::~CSSPrimitiveValueImpl()
   {
       cleanup();
  @@ -1085,6 +1094,12 @@
               text += ")";
               break;
           }
  +        case CSSPrimitiveValue::CSS_PAIR:
  +            text = m_value.pair->first()->cssText();
  +            text += " ";
  +            text += m_value.pair->second()->cssText();
  +            break;
  +
   #if APPLE_CHANGES        
           case CSSPrimitiveValue::CSS_DASHBOARD_REGION: {
               DashboardRegionImpl *region = getDashboardRegionValue();
  @@ -1161,6 +1176,33 @@
   
   // -----------------------------------------------------------------
   
  +PairImpl::PairImpl()
  +{
  +    m_first = m_second = 0;
  +}
  +
  +PairImpl::~PairImpl()
  +{
  +    if (m_first) m_first->deref();
  +    if (m_second) m_second->deref();
  +}
  +
  +void PairImpl::setFirst(CSSPrimitiveValueImpl *first)
  +{
  +    if (first) first->ref();
  +    if (m_first) m_first->deref();
  +    m_first = first;
  +}
  +
  +void PairImpl::setSecond(CSSPrimitiveValueImpl *second)
  +{
  +    if (second) second->ref();
  +    if (m_second) m_second->deref();
  +    m_second = second;
  +}
  +
  +// -----------------------------------------------------------------
  +
   CSSImageValueImpl::CSSImageValueImpl(const DOMString &url, StyleBaseImpl *style)
       : CSSPrimitiveValueImpl(url, CSSPrimitiveValue::CSS_URI), m_image(0), m_accessedImage(false)
   {
  @@ -1173,10 +1215,11 @@
   
   CSSImageValueImpl::~CSSImageValueImpl()
   {
  -    if(m_image) m_image->deref(this);
  +    if (m_image)
  +        m_image->deref(this);
   }
   
  -khtml::CachedImage* CSSImageValueImpl::image(khtml::DocLoader* loader)
  +CachedImage* CSSImageValueImpl::image(khtml::DocLoader* loader)
   {
       if (!m_accessedImage) {
           m_accessedImage = true;
  @@ -1186,7 +1229,8 @@
           else
               m_image = khtml::Cache::requestImage(0, getStringValue());
           
  -        if(m_image) m_image->ref(this);
  +        if (m_image)
  +            m_image->ref(this);
       }
       
       return m_image;
  @@ -1194,6 +1238,51 @@
   
   // ------------------------------------------------------------------------
   
  +CSSBorderImageValueImpl::CSSBorderImageValueImpl(CSSImageValueImpl* image, RectImpl* imageRect,
  +                                                 int horizontalRule, int verticalRule)
  +: m_image(image), m_imageSliceRect(imageRect),
  +  m_horizontalSizeRule(horizontalRule), m_verticalSizeRule(verticalRule)
  +{
  +    if (m_image)
  +        m_image->ref();
  +    if (m_imageSliceRect)
  +        m_imageSliceRect->ref();
  +}
  +
  +CSSBorderImageValueImpl::~CSSBorderImageValueImpl()
  +{
  +    if (m_image)
  +        m_image->deref();
  +    if (m_imageSliceRect)
  +        m_imageSliceRect->deref();
  +}
  +
  +DOMString CSSBorderImageValueImpl::cssText() const
  +{
  +    // Image first.
  +    DOMString text(m_image->cssText());
  +    text += " ";
  +    
  +    // Now the rect, but it isn't really a rect, so we dump manually
  +    text += m_imageSliceRect->top()->cssText();
  +    text += " ";
  +    text += m_imageSliceRect->right()->cssText();
  +    text += " ";
  +    text += m_imageSliceRect->bottom()->cssText();
  +    text += " ";
  +    text += m_imageSliceRect->left()->cssText();
  +    
  +    // Now the keywords.
  +    text += " ";
  +    text += CSSPrimitiveValueImpl(m_horizontalSizeRule).cssText();
  +    text += " ";
  +    text += CSSPrimitiveValueImpl(m_verticalSizeRule).cssText();
  +
  +    return text;
  +}
  +
  +// ------------------------------------------------------------------------
  +
   FontFamilyValueImpl::FontFamilyValueImpl( const QString &string)
   : CSSPrimitiveValueImpl( DOMString(), CSSPrimitiveValue::CSS_STRING)
   {
  
  
  
  1.48      +62 -5     WebCore/khtml/css/css_valueimpl.h
  
  Index: css_valueimpl.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/css/css_valueimpl.h,v
  retrieving revision 1.47
  retrieving revision 1.48
  diff -u -r1.47 -r1.48
  --- css_valueimpl.h	12 May 2005 17:11:21 -0000	1.47
  +++ css_valueimpl.h	27 Aug 2005 00:14:18 -0000	1.48
  @@ -40,6 +40,7 @@
   class CounterImpl;
   class DashboardRegionImpl;
   class RectImpl;
  +class PairImpl;
   
   extern const int inheritableProperties[];
   extern const unsigned numInheritableProperties;
  @@ -143,8 +144,9 @@
       CSSPrimitiveValueImpl(const DOMString &str, CSSPrimitiveValue::UnitTypes type);
       CSSPrimitiveValueImpl(CounterImpl *c);
       CSSPrimitiveValueImpl(RectImpl *r);
  -    CSSPrimitiveValueImpl(DashboardRegionImpl *r);
  +    CSSPrimitiveValueImpl(DashboardRegionImpl *r); // FIXME: Why is dashboard region a primitive value? This makes no sense.
       CSSPrimitiveValueImpl(QRgb color);
  +    CSSPrimitiveValueImpl(PairImpl* p);
   
       virtual ~CSSPrimitiveValueImpl();
   
  @@ -191,6 +193,10 @@
   	return ( m_type != CSSPrimitiveValue::CSS_RGBCOLOR ? 0 : m_value.rgbcolor );
       }
   
  +    PairImpl* getPairValue() const {
  +	return (m_type != CSSPrimitiveValue::CSS_PAIR ? 0 : m_value.pair);
  +    }
  +
       DashboardRegionImpl *getDashboardRegionValue () const {
   	return ( m_type != CSSPrimitiveValue::CSS_DASHBOARD_REGION ? 0 : m_value.region );
       }
  @@ -214,6 +220,7 @@
   	CounterImpl *counter;
   	RectImpl *rect;
           QRgb rgbcolor;
  +        PairImpl *pair;
           DashboardRegionImpl *region;
       } m_value;
   };
  @@ -251,10 +258,10 @@
   
       MAIN_THREAD_ALLOCATED;
   
  -    CSSPrimitiveValueImpl *top() { return m_top; }
  -    CSSPrimitiveValueImpl *right() { return m_right; }
  -    CSSPrimitiveValueImpl *bottom() { return m_bottom; }
  -    CSSPrimitiveValueImpl *left() { return m_left; }
  +    CSSPrimitiveValueImpl *top() const { return m_top; }
  +    CSSPrimitiveValueImpl *right() const { return m_right; }
  +    CSSPrimitiveValueImpl *bottom() const { return m_bottom; }
  +    CSSPrimitiveValueImpl *left() const { return m_left; }
   
       void setTop( CSSPrimitiveValueImpl *top );
       void setRight( CSSPrimitiveValueImpl *right );
  @@ -267,6 +274,28 @@
       CSSPrimitiveValueImpl *m_left;
   };
   
  +// A primitive value representing a pair.  This is useful for properties like border-radius, background-size/position,
  +// and border-spacing (all of which are space-separated sets of two values).  At the moment we are only using it for
  +// border-radius, but (FIXME) border-spacing and background-position could be converted over to use it
  +// (eliminating some extra -khtml- internal properties).
  +class PairImpl : public khtml::Shared<PairImpl> {
  +public:
  +    PairImpl();
  +    virtual ~PairImpl();
  +
  +    MAIN_THREAD_ALLOCATED;
  +
  +    CSSPrimitiveValueImpl *first() const { return m_first; }
  +    CSSPrimitiveValueImpl *second() const { return m_second; }
  +
  +    void setFirst(CSSPrimitiveValueImpl *first);
  +    void setSecond(CSSPrimitiveValueImpl *second);
  +
  +protected:
  +    CSSPrimitiveValueImpl *m_first;
  +    CSSPrimitiveValueImpl *m_second;
  +};
  +
   #if APPLE_CHANGES
   
   class DashboardRegionImpl : public RectImpl {
  @@ -301,6 +330,8 @@
       CSSImageValueImpl(const DOMString &url, StyleBaseImpl *style);
       virtual ~CSSImageValueImpl();
   
  +    MAIN_THREAD_ALLOCATED;
  +
       khtml::CachedImage *image(khtml::DocLoader* loader);
   
   protected:
  @@ -308,6 +339,32 @@
       bool m_accessedImage;
   };
   
  +class CSSBorderImageValueImpl : public CSSValueImpl
  +{
  +public:
  +    CSSBorderImageValueImpl();
  +    CSSBorderImageValueImpl(CSSImageValueImpl* image, RectImpl* imageRect,
  +                            int horizontalRule, int verticalRule);
  +    virtual ~CSSBorderImageValueImpl();
  +
  +    MAIN_THREAD_ALLOCATED;
  +
  +    virtual DOMString cssText() const;
  +    virtual unsigned short cssValueType() const { return CSSValue::CSS_CUSTOM; }
  +
  +public:
  +    // The border image.
  +    CSSImageValueImpl* m_image;
  +
  +    // These four values are used to make "cuts" in the image.  They can be numbers
  +    // or percentages.
  +    RectImpl* m_imageSliceRect;
  +    
  +    // Values for how to handle the scaling/stretching/tiling of the image slices.
  +    int m_horizontalSizeRule; // Rule for how to adjust the widths of the top/middle/bottom
  +    int m_verticalSizeRule; // Rule for how to adjust the heights of the left/middle/right
  +};
  +
   class FontFamilyValueImpl : public CSSPrimitiveValueImpl
   {
   public:
  
  
  
  1.104     +221 -2    WebCore/khtml/css/cssparser.cpp
  
  Index: cssparser.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/css/cssparser.cpp,v
  retrieving revision 1.103
  retrieving revision 1.104
  diff -u -r1.103 -r1.104
  --- cssparser.cpp	25 Aug 2005 17:46:57 -0000	1.103
  +++ cssparser.cpp	27 Aug 2005 00:14:18 -0000	1.104
  @@ -696,7 +696,9 @@
   	break;
   
       case CSS_PROP_BACKGROUND_ATTACHMENT:
  +    case CSS_PROP_BACKGROUND_CLIP:
       case CSS_PROP_BACKGROUND_IMAGE:
  +    case CSS_PROP_BACKGROUND_ORIGIN:
       case CSS_PROP_BACKGROUND_POSITION:
       case CSS_PROP_BACKGROUND_POSITION_X:
       case CSS_PROP_BACKGROUND_POSITION_Y:
  @@ -980,6 +982,43 @@
           }
   #endif
           break;
  +    case CSS_PROP_BORDER_IMAGE:
  +        if (id == CSS_VAL_NONE)
  +            valid_primitive = true;
  +        else
  +            return parseBorderImage(propId, important);
  +        break;
  +    case CSS_PROP_BORDER_TOP_RIGHT_RADIUS:
  +    case CSS_PROP_BORDER_TOP_LEFT_RADIUS:
  +    case CSS_PROP_BORDER_BOTTOM_LEFT_RADIUS:
  +    case CSS_PROP_BORDER_BOTTOM_RIGHT_RADIUS:
  +    case CSS_PROP_BORDER_RADIUS: {
  +        int num = valueList->numValues;
  +        if (num != 1 && num != 2)
  +            return false;
  +        valid_primitive = validUnit(value, FLength, strict);
  +        if (!valid_primitive)
  +            return false;
  +        CSSPrimitiveValueImpl* parsedValue1 = new CSSPrimitiveValueImpl(value->fValue,
  +                                                                        (CSSPrimitiveValue::UnitTypes)value->unit);
  +        CSSPrimitiveValueImpl* parsedValue2 = parsedValue1;
  +        if (num == 2) {
  +            value = valueList->next();
  +            valid_primitive = validUnit(value, FLength, strict);
  +            if (!valid_primitive) {
  +                delete parsedValue1;
  +                return false;
  +            }
  +            parsedValue2 = new CSSPrimitiveValueImpl(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
  +        }
  +        
  +        PairImpl* pair = new PairImpl;
  +        pair->setFirst(parsedValue1);
  +        pair->setSecond(parsedValue2);
  +        CSSPrimitiveValueImpl* val = new CSSPrimitiveValueImpl(pair);
  +        addProperty(propId, val, important);
  +	return true;
  +    }
       case CSS_PROP_OUTLINE_OFFSET:
           valid_primitive = validUnit(value, FLength, strict);
           break;
  @@ -1282,9 +1321,10 @@
   {
       // Position must come before color in this array because a plain old "0" is a legal color
       // in quirks mode but it's usually the X coordinate of a position.
  -    const int numProperties = 5;
  +    const int numProperties = 7;
       const int properties[numProperties] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT,
  -        CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION, CSS_PROP_BACKGROUND_COLOR };
  +        CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION, CSS_PROP_BACKGROUND_CLIP,
  +        CSS_PROP_BACKGROUND_ORIGIN, CSS_PROP_BACKGROUND_COLOR };
       
       inParseShortHand = true;
       
  @@ -1673,6 +1713,13 @@
                       if (currValue)
                           valueList->next();
                       break;
  +                case CSS_PROP_BACKGROUND_CLIP:
  +                case CSS_PROP_BACKGROUND_ORIGIN:
  +                    if (val->id == CSS_VAL_BORDER || val->id == CSS_VAL_PADDING || val->id == CSS_VAL_CONTENT) {
  +                        currValue = new CSSPrimitiveValueImpl(val->id);
  +                        valueList->next();
  +                    }
  +                    break;
                   case CSS_PROP_BACKGROUND_POSITION:
                       parseBackgroundPosition(currValue, currValue2);
                       // unlike the other functions, parseBackgroundPosition advances the valueList pointer
  @@ -2412,6 +2459,178 @@
       return context.failed();
   }
   
  +struct BorderImageParseContext
  +{
  +    BorderImageParseContext()
  +    :m_allowBreak(false), m_allowNumber(false), m_allowSlash(false), m_allowWidth(false),
  +     m_allowRule(false), m_image(0), m_top(0), m_right(0), m_bottom(0), m_left(0), m_borderTop(0), m_borderRight(0), m_borderBottom(0),
  +     m_borderLeft(0), m_horizontalRule(0), m_verticalRule(0)
  +    {}
  +    
  +    ~BorderImageParseContext() {
  +        if (!m_allowBreak) {
  +            delete m_image;
  +            delete m_top; delete m_right; delete m_bottom; delete m_left;
  +            delete m_borderTop; delete m_borderRight; delete m_borderBottom; delete m_borderLeft;
  +        }
  +    }
  +
  +    bool failed() { return m_allowBreak = false; }
  +    bool allowBreak() const { return m_allowBreak; }
  +    bool allowNumber() const { return m_allowNumber; }
  +    bool allowSlash() const { return m_allowSlash; }
  +    bool allowWidth() const { return m_allowWidth; }
  +    bool allowRule() const { return m_allowRule; }
  +
  +    void commitImage(CSSImageValueImpl* image) { m_image = image; m_allowNumber = true; }
  +    void commitNumber(Value* v) {
  +        CSSPrimitiveValueImpl* val = new CSSPrimitiveValueImpl(v->fValue,
  +                                                               (CSSPrimitiveValue::UnitTypes)v->unit);
  +        if (!m_top)
  +            m_top = val;
  +        else if (!m_right)
  +            m_right = val;
  +        else if (!m_bottom)
  +            m_bottom = val;
  +        else {
  +            assert(!m_left);
  +            m_left = val;
  +        }
  +        
  +        m_allowBreak = m_allowSlash = true;
  +        m_allowNumber = !m_left;
  +    }
  +    void commitSlash() { m_allowBreak = m_allowSlash = m_allowNumber = false; m_allowWidth = true; }
  +    void commitWidth(Value* val) {
  +        if (!m_borderTop)
  +            m_borderTop = val;
  +        else if (!m_borderRight)
  +            m_borderRight = val;
  +        else if (!m_borderBottom)
  +            m_borderBottom = val;
  +        else {
  +            assert(!m_borderLeft);
  +            m_borderLeft = val;
  +        }
  +
  +        m_allowBreak = m_allowRule = true;
  +        m_allowWidth = !m_borderLeft;
  +    }
  +    void commitRule(int keyword) {
  +        if (!m_horizontalRule)
  +            m_horizontalRule = keyword;
  +        else if (!m_verticalRule)
  +            m_verticalRule = keyword;
  +        m_allowRule = !m_verticalRule;
  +    }
  +    void commitBorderImage(CSSParser* p, int propId, bool important) {
  +        // We need to clone and repeat values for any omissions.
  +        if (!m_right) {
  +            m_right = new CSSPrimitiveValueImpl(m_top->getFloatValue(m_top->primitiveType()), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
  +            m_bottom = new CSSPrimitiveValueImpl(m_top->getFloatValue(m_top->primitiveType()), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
  +            m_left = new CSSPrimitiveValueImpl(m_top->getFloatValue(m_top->primitiveType()), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
  +        }
  +        if (!m_bottom) {
  +            m_bottom = new CSSPrimitiveValueImpl(m_top->getFloatValue(m_top->primitiveType()), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
  +            m_left = new CSSPrimitiveValueImpl(m_right->getFloatValue(m_right->primitiveType()), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
  +        }
  +        if (!m_left)
  +             m_left = new CSSPrimitiveValueImpl(m_top->getFloatValue(m_top->primitiveType()), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
  +             
  +        // Now build a rect value to hold all four of our primitive values.
  +        RectImpl* rect = new RectImpl;
  +        rect->setTop(m_top); rect->setRight(m_right); rect->setBottom(m_bottom); rect->setLeft(m_left);
  +
  +        // Fill in STRETCH as the default if it wasn't specified.
  +        if (!m_horizontalRule)
  +            m_horizontalRule = CSS_VAL_STRETCH;
  +        if (!m_verticalRule)
  +            m_verticalRule = CSS_VAL_STRETCH;
  +
  +        // Make our new border image value now and add it as the result.
  +        CSSBorderImageValueImpl* borderImage = new CSSBorderImageValueImpl(m_image, rect, m_horizontalRule, m_verticalRule);
  +        p->addProperty(propId, borderImage, important);
  +            
  +        // Now we have to deal with the border widths.  The best way to deal with these is to actually put these values into a value
  +        // list and then make our parsing machinery do the parsing.
  +        if (m_borderTop) {
  +            ValueList newList;
  +            newList.addValue(*m_borderTop);
  +            if (m_borderRight)
  +                newList.addValue(*m_borderRight);
  +            if (m_borderBottom)
  +                newList.addValue(*m_borderBottom);
  +            if (m_borderLeft)
  +                newList.addValue(*m_borderLeft);
  +            p->valueList = &newList;
  +            p->parseValue(CSS_PROP_BORDER_WIDTH, important);
  +            newList.numValues = 0; // Trick valuelist into not destroying the values we put into it.
  +            p->valueList = 0;
  +        }
  +    }
  +    
  +    bool m_allowBreak;
  +    bool m_allowNumber;
  +    bool m_allowSlash;
  +    bool m_allowWidth;
  +    bool m_allowRule;
  +    
  +    CSSImageValueImpl* m_image;
  +    
  +    CSSPrimitiveValueImpl* m_top;
  +    CSSPrimitiveValueImpl* m_right;
  +    CSSPrimitiveValueImpl* m_bottom;
  +    CSSPrimitiveValueImpl* m_left;
  +    
  +    Value* m_borderTop;
  +    Value* m_borderRight;
  +    Value* m_borderBottom;
  +    Value* m_borderLeft;
  +    
  +    int m_horizontalRule;
  +    int m_verticalRule;
  +};
  +
  +bool CSSParser::parseBorderImage(int propId, bool important)
  +{
  +    // Look for an image initially.  If the first value is not a URI, then we're done.
  +    BorderImageParseContext context;
  +    Value* val = valueList->current();
  +    if (val->unit != CSSPrimitiveValue::CSS_URI)
  +        return context.failed();
  +        
  +    DOMString uri = khtml::parseURL(domString(val->string));
  +    if (uri.isEmpty())
  +        return context.failed();
  +    
  +    context.commitImage(new CSSImageValueImpl(DOMString(KURL(styleElement->baseURL().qstring(), uri.qstring()).url()),
  +                                                             styleElement));
  +    while ((val = valueList->next())) {
  +        if (context.allowNumber() && validUnit(val, FInteger|FNonNeg|FPercent, true)) {
  +            context.commitNumber(val);
  +        } else if (context.allowSlash() && val->unit == Value::Operator && val->iValue == '/') {
  +            context.commitSlash();
  +        } else if (context.allowWidth() &&
  +            (val->id == CSS_VAL_THIN || val->id == CSS_VAL_MEDIUM || val->id == CSS_VAL_THICK || validUnit(val, FLength, strict))) {
  +            context.commitWidth(val);
  +        } else if (context.allowRule() &&
  +            (val->id == CSS_VAL_STRETCH || val->id == CSS_VAL_ROUND || val->id == CSS_VAL_REPEAT)) {
  +            context.commitRule(val->id);
  +        } else {
  +            // Something invalid was encountered.
  +            return context.failed();
  +        }
  +    }
  +    
  +    if (context.allowBreak()) {
  +        // Need to fully commit as a single value.
  +        context.commitBorderImage(this, propId, important);
  +        return true;
  +    }
  +    
  +    return context.failed();
  +}
  +
   static inline int yyerror( const char *str ) {
   #ifdef CSS_DEBUG
       kdDebug( 6080 ) << "CSS parse error " << str << endl;
  
  
  
  1.32      +2 -1      WebCore/khtml/css/cssparser.h
  
  Index: cssparser.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/css/cssparser.h,v
  retrieving revision 1.31
  retrieving revision 1.32
  diff -u -r1.31 -r1.32
  --- cssparser.h	9 Jul 2005 20:19:00 -0000	1.31
  +++ cssparser.h	27 Aug 2005 00:14:18 -0000	1.32
  @@ -150,7 +150,8 @@
   
           // CSS3 Parsing Routines (for properties specific to CSS3)
           bool parseShadow(int propId, bool important);
  -        
  +        bool parseBorderImage(int propId, bool important);
  +
   	int yyparse( void );
       public:
   	bool strict;
  
  
  
  1.35      +10 -2     WebCore/khtml/css/cssproperties.in
  
  Index: cssproperties.in
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/css/cssproperties.in,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- cssproperties.in	19 Jul 2005 00:02:07 -0000	1.34
  +++ cssproperties.in	27 Aug 2005 00:14:18 -0000	1.35
  @@ -8,18 +8,26 @@
   # http://msdn.microsoft.com/workshop/author/css/reference/attributes.asp
   #
   -khtml-appearance
  +background-attachment
  +background-clip
   background-color
   background-image
  -background-repeat
  -background-attachment
  +background-origin
   background-position
   background-position-x
   background-position-y
  +background-repeat
   -khtml-binding
   border-collapse
  +border-image
   border-spacing
   -khtml-border-horizontal-spacing
   -khtml-border-vertical-spacing
  +border-radius
  +border-top-left-radius
  +border-top-right-radius
  +border-bottom-left-radius
  +border-bottom-right-radius
   border-top-color
   border-right-color
   border-bottom-color
  
  
  
  1.201     +183 -0    WebCore/khtml/css/cssstyleselector.cpp
  
  Index: cssstyleselector.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/css/cssstyleselector.cpp,v
  retrieving revision 1.200
  retrieving revision 1.201
  diff -u -r1.200 -r1.201
  --- cssstyleselector.cpp	25 Aug 2005 17:46:57 -0000	1.200
  +++ cssstyleselector.cpp	27 Aug 2005 00:14:18 -0000	1.201
  @@ -1806,6 +1806,12 @@
       case CSS_PROP_BACKGROUND_ATTACHMENT:
           HANDLE_BACKGROUND_VALUE(backgroundAttachment, BackgroundAttachment, value)
           break;
  +    case CSS_PROP_BACKGROUND_CLIP:
  +        HANDLE_BACKGROUND_VALUE(backgroundClip, BackgroundClip, value)
  +        break;
  +    case CSS_PROP_BACKGROUND_ORIGIN:
  +        HANDLE_BACKGROUND_VALUE(backgroundOrigin, BackgroundOrigin, value)
  +        break;
       case CSS_PROP_BACKGROUND_REPEAT:
           HANDLE_BACKGROUND_VALUE(backgroundRepeat, BackgroundRepeat, value)
           break;
  @@ -3439,6 +3445,139 @@
           break;
       }
   
  +    case CSS_PROP_BORDER_IMAGE: {
  +        HANDLE_INHERIT_AND_INITIAL(borderImage, BorderImage)
  +        BorderImage image;
  +        if (primitiveValue) {
  +            if (primitiveValue->getIdent() == CSS_VAL_NONE)
  +                style->setBorderImage(image);
  +        } else {
  +            // Retrieve the border image value.
  +            CSSBorderImageValueImpl* borderImage = static_cast<CSSBorderImageValueImpl*>(value);
  +            
  +            // Set the image (this kicks off the load).
  +            image.m_image = borderImage->m_image->image(element->getDocument()->docLoader());
  +            
  +            // Set up a length box to represent our image slices.
  +            LengthBox& l = image.m_slices;
  +            RectImpl* r = borderImage->m_imageSliceRect;
  +            if (r->top()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
  +                l.top = Length((int)r->top()->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
  +            else
  +                l.top = Length((int)r->top()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
  +            if (r->bottom()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
  +                l.bottom = Length((int)r->bottom()->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
  +            else
  +                l.bottom = Length((int)r->bottom()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
  +            if (r->left()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
  +                l.left = Length((int)r->left()->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
  +            else
  +                l.left = Length((int)r->left()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
  +            if (r->right()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
  +                l.right = Length((int)r->right()->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
  +            else
  +                l.right = Length((int)r->right()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
  +            
  +            // Set the appropriate rules for stretch/round/repeat of the slices
  +            switch (borderImage->m_horizontalSizeRule) {
  +                case CSS_VAL_STRETCH:
  +                    image.m_horizontalRule = BI_STRETCH;
  +                    break;
  +                case CSS_VAL_ROUND:
  +                    image.m_horizontalRule = BI_ROUND;
  +                    break;
  +                default: // CSS_VAL_REPEAT
  +                    image.m_horizontalRule = BI_REPEAT;
  +                    break;
  +            }
  +
  +            switch (borderImage->m_verticalSizeRule) {
  +                case CSS_VAL_STRETCH:
  +                    image.m_verticalRule = BI_STRETCH;
  +                    break;
  +                case CSS_VAL_ROUND:
  +                    image.m_verticalRule = BI_ROUND;
  +                    break;
  +                default: // CSS_VAL_REPEAT
  +                    image.m_verticalRule = BI_REPEAT;
  +                    break;
  +            }
  +
  +            style->setBorderImage(image);
  +        }
  +        break;
  +    }
  +
  +    case CSS_PROP_BORDER_RADIUS:
  +        if (isInherit) {
  +            style->setBorderTopLeftRadius(parentStyle->borderTopLeftRadius());
  +            style->setBorderTopRightRadius(parentStyle->borderTopRightRadius());
  +            style->setBorderBottomLeftRadius(parentStyle->borderBottomLeftRadius());
  +            style->setBorderBottomRightRadius(parentStyle->borderBottomRightRadius());
  +            return;
  +        }
  +        if (isInitial) {
  +            style->resetBorderRadius();
  +            return;
  +        }
  +        // Fall through
  +    case CSS_PROP_BORDER_TOP_LEFT_RADIUS:
  +    case CSS_PROP_BORDER_TOP_RIGHT_RADIUS:
  +    case CSS_PROP_BORDER_BOTTOM_LEFT_RADIUS:
  +    case CSS_PROP_BORDER_BOTTOM_RIGHT_RADIUS: {
  +	if (isInherit) {
  +            HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_LEFT_RADIUS, borderTopLeftRadius, BorderTopLeftRadius)
  +            HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_RIGHT_RADIUS, borderTopRightRadius, BorderTopRightRadius)
  +            HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_LEFT_RADIUS, borderBottomLeftRadius, BorderBottomLeftRadius)
  +            HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_RIGHT_RADIUS, borderBottomRightRadius, BorderBottomRightRadius)
  +            return;
  +        }
  +        
  +        if (isInitial) {
  +            HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_TOP_LEFT_RADIUS, BorderTopLeftRadius, BorderRadius)
  +            HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_TOP_RIGHT_RADIUS, BorderTopRightRadius, BorderRadius)
  +            HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_BOTTOM_LEFT_RADIUS, BorderBottomLeftRadius, BorderRadius)
  +            HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_BOTTOM_RIGHT_RADIUS, BorderBottomRightRadius, BorderRadius)
  +            return;
  +        }
  +
  +        if (!primitiveValue)
  +            return;
  +
  +        PairImpl* pair = primitiveValue->getPairValue();
  +        if (!pair)
  +            return;
  +
  +        int width = pair->first()->computeLength(style, paintDeviceMetrics);
  +        int height = pair->second()->computeLength(style, paintDeviceMetrics);
  +        if (width < 0 || height < 0)
  +            return;
  +
  +        if (width == 0)
  +            height = 0; // Null out the other value.
  +        else if (height == 0)
  +            width = 0; // Null out the other value.
  +
  +        QSize size(width, height);
  +        switch (id) {
  +            case CSS_PROP_BORDER_TOP_LEFT_RADIUS:
  +                style->setBorderTopLeftRadius(size);
  +                break;
  +            case CSS_PROP_BORDER_TOP_RIGHT_RADIUS:
  +                style->setBorderTopRightRadius(size);
  +                break;
  +            case CSS_PROP_BORDER_BOTTOM_LEFT_RADIUS:
  +                style->setBorderBottomLeftRadius(size);
  +                break;
  +            case CSS_PROP_BORDER_BOTTOM_RIGHT_RADIUS:
  +                style->setBorderBottomRightRadius(size);
  +                break;
  +            default:
  +                style->setBorderRadius(size);
  +                break;
  +        }
  +    }
  +
       case CSS_PROP_OUTLINE_OFFSET: {
           HANDLE_INHERIT_AND_INITIAL(outlineOffset, OutlineOffset)
   
  @@ -3880,6 +4019,50 @@
       }
   }
   
  +void CSSStyleSelector::mapBackgroundClip(BackgroundLayer* layer, CSSValueImpl* value)
  +{
  +    if (value->cssValueType() == CSSValue::CSS_INITIAL) {
  +        layer->setBackgroundClip(RenderStyle::initialBackgroundClip());
  +        return;
  +    }
  +
  +    if (!value->isPrimitiveValue()) return;
  +    CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value);
  +    switch (primitiveValue->getIdent()) {
  +        case CSS_VAL_BORDER:
  +            layer->setBackgroundClip(BGBORDER);
  +            break;
  +        case CSS_VAL_PADDING:
  +            layer->setBackgroundClip(BGPADDING);
  +            break;
  +        default: // CSS_VAL_CONTENT
  +            layer->setBackgroundClip(BGCONTENT);
  +            break;
  +    }
  +}
  +
  +void CSSStyleSelector::mapBackgroundOrigin(BackgroundLayer* layer, CSSValueImpl* value)
  +{
  +    if (value->cssValueType() == CSSValue::CSS_INITIAL) {
  +        layer->setBackgroundOrigin(RenderStyle::initialBackgroundOrigin());
  +        return;
  +    }
  +
  +    if (!value->isPrimitiveValue()) return;
  +    CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value);
  +    switch (primitiveValue->getIdent()) {
  +        case CSS_VAL_BORDER:
  +            layer->setBackgroundOrigin(BGBORDER);
  +            break;
  +        case CSS_VAL_PADDING:
  +            layer->setBackgroundOrigin(BGPADDING);
  +            break;
  +        default: // CSS_VAL_CONTENT
  +            layer->setBackgroundOrigin(BGCONTENT);
  +            break;
  +    }
  +}
  +
   void CSSStyleSelector::mapBackgroundImage(BackgroundLayer* layer, CSSValueImpl* value)
   {
       if (value->cssValueType() == CSSValue::CSS_INITIAL) {
  
  
  
  1.36      +2 -0      WebCore/khtml/css/cssstyleselector.h
  
  Index: cssstyleselector.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/css/cssstyleselector.h,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- cssstyleselector.h	9 Jul 2005 20:19:00 -0000	1.35
  +++ cssstyleselector.h	27 Aug 2005 00:14:19 -0000	1.36
  @@ -184,6 +184,8 @@
           void init();
           
           void mapBackgroundAttachment(BackgroundLayer* layer, DOM::CSSValueImpl* value);
  +        void mapBackgroundClip(BackgroundLayer* layer, DOM::CSSValueImpl* value);
  +        void mapBackgroundOrigin(BackgroundLayer* layer, DOM::CSSValueImpl* value);
           void mapBackgroundImage(BackgroundLayer* layer, DOM::CSSValueImpl* value);
           void mapBackgroundRepeat(BackgroundLayer* layer, DOM::CSSValueImpl* value);
           void mapBackgroundXPosition(BackgroundLayer* layer, DOM::CSSValueImpl* value);
  
  
  
  1.31      +14 -0     WebCore/khtml/css/cssvalues.in
  
  Index: cssvalues.in
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/css/cssvalues.in,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- cssvalues.in	19 Jul 2005 00:02:07 -0000	1.30
  +++ cssvalues.in	27 Aug 2005 00:14:19 -0000	1.31
  @@ -462,3 +462,17 @@
   searchfield-results
   searchfield-close
   textfield
  +
  +#
  +# CSS_PROP_BORDER_IMAGE
  +#
  +# stretch
  +# repeat
  +round
  +
  +#
  +# CSS_PROP_BACKGROUND_CLIP/ORIGIN
  +#
  +border
  +content
  +padding
  
  
  
  1.9       +2 -1      WebCore/khtml/dom/css_value.h
  
  Index: css_value.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/dom/css_value.h,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- css_value.h	11 May 2005 00:58:28 -0000	1.8
  +++ css_value.h	27 Aug 2005 00:14:20 -0000	1.9
  @@ -436,7 +436,8 @@
           CSS_COUNTER = 23,
           CSS_RECT = 24,
           CSS_RGBCOLOR = 25,
  -        CSS_DASHBOARD_REGION = 26,
  +        CSS_PAIR = 26, // We envision this being exposed as a means of getting computed style values for pairs (border-spacing/radius, background-position, etc.)
  +        CSS_DASHBOARD_REGION = 27, // FIXME: What on earth is this doing as a primitive value? This is insane.
           CSS_HTML_RELATIVE = 255
       };
   
  
  
  
  1.41      +2 -2      WebCore/khtml/misc/loader.h
  
  Index: loader.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/misc/loader.h,v
  retrieving revision 1.40
  retrieving revision 1.41
  diff -u -r1.40 -r1.41
  --- loader.h	27 May 2005 22:55:24 -0000	1.40
  +++ loader.h	27 Aug 2005 00:14:20 -0000	1.41
  @@ -169,6 +169,8 @@
   
   	int size() const { return m_size; }
   
  +        bool isLoaded() const { return !m_loading; }
  +
       int accessCount() const { return m_accessCount; }
       void increaseAccessCount() { m_accessCount++; }
       
  @@ -296,8 +298,6 @@
   
   	void checkNotify();
   
  -        bool isLoaded() const { return !m_loading; }
  -
       protected:
   	DOM::DOMString m_script;
           QTextCodec* m_codec;
  
  
  
  1.164     +68 -28    WebCore/khtml/rendering/render_box.cpp
  
  Index: render_box.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_box.cpp,v
  retrieving revision 1.163
  retrieving revision 1.164
  diff -u -r1.163 -r1.164
  --- render_box.cpp	25 Aug 2005 17:47:14 -0000	1.163
  +++ render_box.cpp	27 Aug 2005 00:14:20 -0000	1.164
  @@ -347,13 +347,36 @@
   void RenderBox::paintBackground(QPainter *p, const QColor& c, const BackgroundLayer* bgLayer, int clipy, int cliph, int _tx, int _ty, int w, int height)
   {
       paintBackgroundExtended(p, c, bgLayer, clipy, cliph, _tx, _ty, w, height,
  -                            borderLeft(), borderRight());
  +                            borderLeft(), borderRight(), paddingLeft(), paddingRight());
   }
   
   void RenderBox::paintBackgroundExtended(QPainter *p, const QColor& c, const BackgroundLayer* bgLayer, int clipy, int cliph,
                                           int _tx, int _ty, int w, int h,
  -                                        int bleft, int bright)
  +                                        int bleft, int bright, int pleft, int pright)
   {
  +    bool clippedToBorderRadius = false;
  +    if (style()->hasBorderRadius()) {
  +        QRect clipRect(_tx, _ty, w, h);
  +        clipRect = p->xForm(clipRect);
  +        p->save();
  +        p->addRoundedRectClip(clipRect, style()->borderTopLeftRadius(), style()->borderTopRightRadius(),
  +                              style()->borderBottomLeftRadius(), style()->borderBottomRightRadius());
  +        clippedToBorderRadius = true;
  +    }
  +    
  +    if (bgLayer->backgroundClip() != BGBORDER) {
  +        // Clip to the padding or content boxes as necessary.
  +        bool includePadding = bgLayer->backgroundClip() == BGCONTENT;
  +        int x = _tx + bleft + (includePadding ? pleft : 0);
  +        int y = _ty + borderTop() + (includePadding ? paddingTop() : 0);
  +        int width = w - bleft - bright - (includePadding ? pleft + pright : 0);
  +        int height = h - borderTop() - borderBottom() - (includePadding ? paddingTop() + paddingBottom() : 0);
  +        QRect clipRect(x, y, width, height);
  +        clipRect = p->xForm(clipRect);
  +        p->save();
  +        p->addClip(clipRect);
  +    }
  +
       CachedImage* bg = bgLayer->backgroundImage();
       bool shouldPaintBackgroundImage = bg && bg->pixmap_size() == bg->valid_rect().size() && !bg->isTransparent() && !bg->isErrorImage();
       QColor bgColor = c;
  @@ -413,17 +436,28 @@
           int sy = 0;
           int cw,ch;
           int cx,cy;
  -        int vpab = bleft + bright;
  -        int hpab = borderTop() + borderBottom();
           
           // CSS2 chapter 14.2.1
   
  -        if (bgLayer->backgroundAttachment())
  -        {
  -            //scroll
  -            int pw = w - vpab;
  -            int ph = h - hpab;
  -            
  +        if (bgLayer->backgroundAttachment()) {
  +            // scroll
  +            int hpab = 0, vpab = 0, left = 0, top = 0; // Init to 0 for background-origin of 'border'
  +            if (bgLayer->backgroundOrigin() != BGBORDER) {
  +                hpab += bleft + bright;
  +                vpab += borderTop() + borderBottom();
  +                left += bleft;
  +                top += borderTop();
  +                if (bgLayer->backgroundOrigin() == BGCONTENT) {
  +                    hpab += pleft + pright;
  +                    vpab += paddingTop() + paddingBottom();
  +                    left += pleft;
  +                    top += paddingTop();
  +                }
  +            }
  +
  +            int pw = w - hpab;
  +            int ph = h - vpab;
  +                        
               int pixw = bg->pixmap_size().width();
               int pixh = bg->pixmap_size().height();
               EBackgroundRepeat bgr = bgLayer->backgroundRepeat();
  @@ -439,20 +473,20 @@
                           cw += xPosition;
                       }
                   }
  -                cx += bleft;
  +                cx += left;
               } else {
                   // repeat over x or background is wider than box
                   cw = w;
                   cx = _tx;
                   if (pixw > 0) {
  -					int xPosition = bgLayer->backgroundXPosition().minWidth(pw-pixw);
  -					if ((xPosition > 0) && (bgr == NO_REPEAT)) {
  -						cx += xPosition;
  -						cw -= xPosition;
  -					} else {
  -						sx =  pixw - (xPosition % pixw );
  -						sx -= bleft % pixw;
  -					}
  +                    int xPosition = bgLayer->backgroundXPosition().minWidth(pw-pixw);
  +                    if ((xPosition > 0) && (bgr == NO_REPEAT)) {
  +                        cx += xPosition;
  +                        cw -= xPosition;
  +                    } else {
  +                        sx =  pixw - (xPosition % pixw );
  +                        sx -= left % pixw;
  +                    }
                   }
               }
   
  @@ -469,20 +503,20 @@
                       }
                   }
                   
  -                cy += borderTop();
  +                cy += top;
               } else {
                   // repeat over y or background is taller than box
                   ch = h;
                   cy = _ty;
                   if (pixh > 0) {
  -					int yPosition = bgLayer->backgroundYPosition().minWidth(ph-pixh);
  -					if ((yPosition > 0) && (bgr == NO_REPEAT)) {
  -						cy += yPosition;
  -						ch -= yPosition;
  -					} else {
  -						sy = pixh - (yPosition % pixh );
  -						sy -= borderTop() % pixh;
  -					}
  +                    int yPosition = bgLayer->backgroundYPosition().minWidth(ph-pixh);
  +                    if ((yPosition > 0) && (bgr == NO_REPEAT)) {
  +                        cy += yPosition;
  +                        ch -= yPosition;
  +                    } else {
  +                        sy = pixh - (yPosition % pixh );
  +                        sy -= top % pixh;
  +                    }
                   }
               }
           }
  @@ -532,6 +566,12 @@
           if (cw>0 && ch>0)
               p->drawTiledPixmap(cx, cy, cw, ch, bg->tiled_pixmap(c), sx, sy);
       }
  +    
  +    if (bgLayer->backgroundClip() != BGBORDER)
  +        p->restore(); // Undo the background clip
  +        
  +    if (clippedToBorderRadius)
  +        p->restore(); // Undo the border radius clip
   }
   
   void RenderBox::outlineBox(QPainter *p, int _tx, int _ty, const char *color)
  
  
  
  1.55      +1 -1      WebCore/khtml/rendering/render_box.h
  
  Index: render_box.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_box.h,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -r1.54 -r1.55
  --- render_box.h	14 Apr 2005 18:33:54 -0000	1.54
  +++ render_box.h	27 Aug 2005 00:14:21 -0000	1.55
  @@ -137,7 +137,7 @@
   
       virtual void paintBackgroundExtended(QPainter *p, const QColor& c, const BackgroundLayer* bgLayer, int clipy, int cliph,
                                            int _tx, int _ty, int w, int height,
  -                                         int bleft, int bright);
  +                                         int bleft, int bright, int pleft, int pright);
   
       virtual void setStaticX(int staticX);
       virtual void setStaticY(int staticY);
  
  
  
  1.48      +42 -6     WebCore/khtml/rendering/render_line.cpp
  
  Index: render_line.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_line.cpp,v
  retrieving revision 1.47
  retrieving revision 1.48
  diff -u -r1.47 -r1.48
  --- render_line.cpp	25 Aug 2005 17:47:15 -0000	1.47
  +++ render_line.cpp	27 Aug 2005 00:14:21 -0000	1.48
  @@ -394,8 +394,9 @@
       RenderObject* curr = endObject;
       RenderObject* parent = curr->parent();
       while (parent && !parent->isRenderBlock()) {
  -        if (parent->lastChild() != curr)
  +        if (parent->lastChild() != curr || parent == object())
               return false;
  +            
           curr = parent;
           parent = curr->parent();
       }
  @@ -446,7 +447,6 @@
                        prevOnLineExists() || onEndChain(endObject)))
                       includeLeftEdge = true;
               }
  -            
           }
       }
   
  @@ -807,7 +807,8 @@
       bool hasBackgroundImage = bg && (bg->pixmap_size() == bg->valid_rect().size()) &&
                                 !bg->isTransparent() && !bg->isErrorImage();
       if (!hasBackgroundImage || (!prevLineBox() && !nextLineBox()) || !parent())
  -        object()->paintBackgroundExtended(p, c, bgLayer, my, mh, _tx, _ty, w, h, borderLeft(), borderRight());
  +        object()->paintBackgroundExtended(p, c, bgLayer, my, mh, _tx, _ty, w, h, 
  +                                          borderLeft(), borderRight(), paddingLeft(), paddingRight());
       else {
           // We have a background image that spans multiple lines.
           // We need to adjust _tx and _ty by the width of all previous lines.
  @@ -815,6 +816,8 @@
           // strip.  Even though that strip has been broken up across multiple lines, you still paint it
           // as though you had one single line.  This means each line has to pick up the background where
           // the previous line left off.
  +        // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
  +        // but it isn't even clear how this should work at all.
           int xOffsetOnLine = 0;
           for (InlineRunBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
               xOffsetOnLine += curr->width();
  @@ -827,7 +830,7 @@
           p->save();
           p->addClip(clipRect);
           object()->paintBackgroundExtended(p, c, bgLayer, my, mh, startX, _ty,
  -                                          totalWidth, h, borderLeft(), borderRight());
  +                                          totalWidth, h, borderLeft(), borderRight(), paddingLeft(), paddingRight());
           p->restore();
       }
   }
  @@ -864,8 +867,41 @@
   
           // :first-line cannot be used to put borders on a line. Always paint borders with our
           // non-first-line style.
  -        if (parent() && object()->style()->hasBorder())
  -            object()->paintBorder(p, _tx, _ty, w, h, object()->style(), includeLeftEdge(), includeRightEdge());
  +        if (parent() && object()->style()->hasBorder()) {
  +            CachedImage* borderImage = object()->style()->borderImage().image();
  +            bool hasBorderImage = borderImage && (borderImage->pixmap_size() == borderImage->valid_rect().size()) &&
  +                                  !borderImage->isTransparent() && !borderImage->isErrorImage();
  +            if (hasBorderImage && !borderImage->isLoaded())
  +                return; // Don't paint anything while we wait for the image to load.
  +            
  +            // The simple case is where we either have no border image or we are the only box for this object.  In those
  +            // cases only a single call to draw is required.
  +            if (!hasBorderImage || (!prevLineBox() && !nextLineBox()))
  +                object()->paintBorder(p, _tx, _ty, w, h, object()->style(), includeLeftEdge(), includeRightEdge());
  +            else {
  +                // We have a border image that spans multiple lines.
  +                // We need to adjust _tx and _ty by the width of all previous lines.
  +                // Think of border image painting on inlines as though you had one long line, a single continuous
  +                // strip.  Even though that strip has been broken up across multiple lines, you still paint it
  +                // as though you had one single line.  This means each line has to pick up the image where
  +                // the previous line left off.
  +                // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
  +                // but it isn't even clear how this should work at all.
  +                int xOffsetOnLine = 0;
  +                for (InlineRunBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
  +                    xOffsetOnLine += curr->width();
  +                int startX = _tx - xOffsetOnLine;
  +                int totalWidth = xOffsetOnLine;
  +                for (InlineRunBox* curr = this; curr; curr = curr->nextLineBox())
  +                    totalWidth += curr->width();
  +                QRect clipRect(_tx, _ty, width(), height());
  +                clipRect = p->xForm(clipRect);
  +                p->save();
  +                p->addClip(clipRect);
  +                object()->paintBorder(p, startX, _ty, totalWidth, h, object()->style());
  +                p->restore();
  +            }
  +        }
       }
   }
   
  
  
  
  1.207     +215 -39   WebCore/khtml/rendering/render_object.cpp
  
  Index: render_object.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_object.cpp,v
  retrieving revision 1.206
  retrieving revision 1.207
  diff -u -r1.206 -r1.207
  --- render_object.cpp	25 Aug 2005 17:47:15 -0000	1.206
  +++ render_object.cpp	27 Aug 2005 00:14:21 -0000	1.207
  @@ -978,8 +978,130 @@
           p->setRasterOp(Qt::CopyROP);
   }
   
  +bool RenderObject::paintBorderImage(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style)
  +{
  +    CachedImage* borderImage = style->borderImage().image();
  +    if (!borderImage->isLoaded())
  +        return true; // Never paint a border image incrementally, but don't paint the fallback borders either.
  +    
  +    // If we have a border radius, the border image gets clipped to the rounded rect.
  +    bool clipped = false;
  +    if (style->hasBorderRadius()) {
  +        QRect clipRect(_tx, _ty, w, h);
  +        clipRect = p->xForm(clipRect);
  +        p->save();
  +        p->addRoundedRectClip(clipRect, style->borderTopLeftRadius(), style->borderTopRightRadius(),
  +                              style->borderBottomLeftRadius(), style->borderBottomRightRadius());
  +        clipped = true;
  +    }
  +
  +    int imageWidth = borderImage->pixmap().width();
  +    int imageHeight = borderImage->pixmap().height();
  +
  +    int topSlice = kMin(imageHeight, style->borderImage().m_slices.top.width(borderImage->pixmap().height()));
  +    int bottomSlice = kMin(imageHeight, style->borderImage().m_slices.bottom.width(borderImage->pixmap().height()));
  +    int leftSlice = kMin(imageWidth, style->borderImage().m_slices.left.width(borderImage->pixmap().width()));    
  +    int rightSlice = kMin(imageWidth, style->borderImage().m_slices.right.width(borderImage->pixmap().width()));
  +
  +    EBorderImageRule hRule = style->borderImage().m_horizontalRule;
  +    EBorderImageRule vRule = style->borderImage().m_verticalRule;
  +    
  +    bool drawLeft = leftSlice > 0 && style->borderLeftWidth() > 0;
  +    bool drawTop = topSlice > 0 && style->borderTopWidth() > 0;
  +    bool drawRight = rightSlice > 0 && style->borderRightWidth() > 0;
  +    bool drawBottom = bottomSlice > 0 && style->borderBottomWidth() > 0;
  +    bool drawMiddle = (imageWidth - leftSlice - rightSlice) > 0 && (w - style->borderLeftWidth() - style->borderRightWidth()) > 0 &&
  +                      (imageHeight - topSlice - bottomSlice) > 0 && (h - style->borderTopWidth() - style->borderBottomWidth()) > 0;
  +
  +    if (drawLeft) {
  +        // Paint the top and bottom left corners.
  +        
  +        // The top left corner rect is (_tx, _ty, leftWidth, topWidth)
  +        // The rect to use from within the image is obtained from our slice, and is (0, 0, leftSlice, topSlice)
  +        if (drawTop)
  +            p->drawPixmap(_tx, _ty, style->borderLeftWidth(), style->borderTopWidth(),
  +                          borderImage->pixmap(), 0, 0, leftSlice, topSlice);
  +        
  +        // The bottom left corner rect is (_tx, _ty + h - bottomWidth, leftWidth, bottomWidth)
  +        // The rect to use from within the image is (0, imageHeight - bottomSlice, leftSlice, botomSlice)
  +        if (drawBottom)
  +            p->drawPixmap(_tx, _ty + h - style->borderBottomWidth(), style->borderLeftWidth(), style->borderBottomWidth(),
  +                          borderImage->pixmap(), 0, imageHeight - bottomSlice, leftSlice, bottomSlice);
  +                      
  +        // Paint the left edge.
  +        // Have to scale and tile into the border rect.
  +        p->drawScaledAndTiledPixmap(_tx, _ty + style->borderTopWidth(), style->borderLeftWidth(),
  +                                    h - style->borderTopWidth() - style->borderBottomWidth(), borderImage->pixmap(),
  +                                    0, topSlice, leftSlice, imageHeight - topSlice - bottomSlice, 
  +                                    QPainter::STRETCH, (QPainter::TileRule)vRule);
  +    }
  +    
  +    if (drawRight) {
  +        // Paint the top and bottom right corners
  +        // The top right corner rect is (_tx + w - rightWidth, _ty, rightWidth, topWidth)
  +        // The rect to use from within the image is obtained from our slice, and is (imageWidth - rightSlice, 0, rightSlice, topSlice)
  +        if (drawTop)
  +            p->drawPixmap(_tx + w - style->borderRightWidth(), _ty, style->borderRightWidth(), style->borderTopWidth(),
  +                          borderImage->pixmap(), imageWidth - rightSlice, 0, rightSlice, topSlice);
  +        
  +        // The bottom right corner rect is (_tx + w - rightWidth, _ty + h - bottomWidth, rightWidth, bottomWidth)
  +        // The rect to use from within the image is (imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, botomSlice)
  +        if (drawBottom)
  +            p->drawPixmap(_tx + w - style->borderRightWidth(), _ty + h - style->borderBottomWidth(), style->borderRightWidth(), style->borderBottomWidth(),
  +                          borderImage->pixmap(), imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice);
  +                      
  +        // Paint the right edge.
  +        p->drawScaledAndTiledPixmap(_tx + w - style->borderRightWidth(), _ty + style->borderTopWidth(), style->borderRightWidth(),
  +                          h - style->borderTopWidth() - style->borderBottomWidth(), borderImage->pixmap(),
  +                          imageWidth - rightSlice, topSlice, rightSlice, imageHeight - topSlice - bottomSlice,
  +                          QPainter::STRETCH, (QPainter::TileRule)vRule);
  +    }
  +
  +    // Paint the top edge.
  +    if (drawTop)
  +        p->drawScaledAndTiledPixmap(_tx + style->borderLeftWidth(), _ty, w - style->borderLeftWidth() - style->borderRightWidth(),
  +                          style->borderTopWidth(), borderImage->pixmap(),
  +                          leftSlice, 0, imageWidth - rightSlice - leftSlice, topSlice,
  +                          (QPainter::TileRule)hRule, QPainter::STRETCH);
  +    
  +    // Paint the bottom edge.
  +    if (drawBottom)
  +        p->drawScaledAndTiledPixmap(_tx + style->borderLeftWidth(), _ty + h - style->borderBottomWidth(), 
  +                          w - style->borderLeftWidth() - style->borderRightWidth(),
  +                          style->borderBottomWidth(), borderImage->pixmap(),
  +                          leftSlice, imageHeight - bottomSlice, imageWidth - rightSlice - leftSlice, bottomSlice,
  +                          (QPainter::TileRule)hRule, QPainter::STRETCH);
  +    
  +    // Paint the middle.
  +    if (drawMiddle)
  +        p->drawScaledAndTiledPixmap(_tx + style->borderLeftWidth(), _ty + style->borderTopWidth(), w - style->borderLeftWidth() - style->borderRightWidth(),
  +                          h - style->borderTopWidth() - style->borderBottomWidth(), borderImage->pixmap(),
  +                          leftSlice, topSlice, imageWidth - rightSlice - leftSlice, imageHeight - topSlice - bottomSlice,
  +                          (QPainter::TileRule)hRule, (QPainter::TileRule)vRule);
  +    
  +    // Because of the bizarre way we do animations in WebKit, WebCore does not get any sort of notification when the image changes
  +    // animation frames.  We have to tell WebKit about the rect so that it can do the animation itself and invalidate the right
  +    // rect.
  +    borderImage->pixmap().setAnimationRect(QRect(_tx, _ty, w, h));
  +    
  +    // Clear the clip for the border radius.
  +    if (clipped)
  +        p->restore();
  +
  +    return true;
  +}
  +
   void RenderObject::paintBorder(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style, bool begin, bool end)
   {
  +    CachedImage* borderImage = style->borderImage().image();
  +    bool shouldPaintBackgroundImage = borderImage && borderImage->pixmap_size() == borderImage->valid_rect().size() && 
  +                                      !borderImage->isTransparent() && !borderImage->isErrorImage();
  +    if (shouldPaintBackgroundImage)
  +        shouldPaintBackgroundImage = paintBorderImage(p, _tx, _ty, w, h, style);
  +    
  +    if (shouldPaintBackgroundImage)
  +        return;
  +
       const QColor& tc = style->borderTopColor();
       const QColor& bc = style->borderBottomColor();
       const QColor& lc = style->borderLeftColor();
  @@ -1000,68 +1122,113 @@
       bool render_r = rs > BHIDDEN && end && !rt;
       bool render_b = bs > BHIDDEN && !bt;
   
  -    if(render_t) {
  -        bool ignore_left =
  -            (tc == lc) && (tt == lt) &&
  +    // Need sufficient width and height to contain border radius curves.  Sanity check our top/bottom
  +    // values and our width/height values to make sure the curves can all fit. If not, then we won't paint
  +    // any border radii.
  +    bool render_radii = false;
  +    QSize topLeft = style->borderTopLeftRadius();
  +    QSize topRight = style->borderTopRightRadius();
  +    QSize bottomLeft = style->borderBottomLeftRadius();
  +    QSize bottomRight = style->borderBottomRightRadius();
  +
  +    if (style->hasBorderRadius()) {
  +        int requiredWidth = kMax(topLeft.width() + topRight.width(), bottomLeft.width() + bottomRight.width());
  +        int requiredHeight = kMax(topLeft.height() + bottomLeft.height(), topRight.height() + bottomRight.height());
  +        render_radii = (requiredWidth <= w && requiredHeight <= h);
  +    }
  +    
  +    // Clip to the rounded rectangle.
  +    if (render_radii)
  +        p->addRoundedRectClip(QRect(_tx, _ty, w, h), topLeft, topRight, bottomLeft, bottomRight);
  +
  +    if (render_t) {
  +        bool ignore_left = (render_radii && topLeft.width() > 0) ||
  +            ((tc == lc) && (tt == lt) &&
               (ts >= OUTSET) &&
  -            (ls == DOTTED || ls == DASHED || ls == SOLID || ls == OUTSET);
  +            (ls == DOTTED || ls == DASHED || ls == SOLID || ls == OUTSET));
   
  -        bool ignore_right =
  -            (tc == rc) && (tt == rt) &&
  +        bool ignore_right = (render_radii && topRight.width() > 0) ||
  +            ((tc == rc) && (tt == rt) &&
               (ts >= OUTSET) &&
  -            (rs == DOTTED || rs == DASHED || rs == SOLID || rs == INSET);
  +            (rs == DOTTED || rs == DASHED || rs == SOLID || rs == INSET));
           
  -        drawBorder(p, _tx, _ty, _tx + w, _ty +  style->borderTopWidth(), BSTop, tc, style->color(), ts,
  -                   ignore_left?0:style->borderLeftWidth(),
  -                   ignore_right?0:style->borderRightWidth());
  +        int x = _tx;
  +        int x2 = _tx + w;
  +        if (render_radii) {
  +            x += topLeft.width();
  +            x2 -= topRight.width();
  +        }
  +        
  +        drawBorder(p, x, _ty, x2, _ty +  style->borderTopWidth(), BSTop, tc, style->color(), ts,
  +                   ignore_left ? 0 : style->borderLeftWidth(),
  +                   ignore_right? 0 : style->borderRightWidth());
       }
   
  -    if(render_b) {
  -        bool ignore_left =
  -        (bc == lc) && (bt == lt) &&
  +    if (render_b) {
  +        bool ignore_left = (render_radii && bottomLeft.width() > 0) ||
  +        ((bc == lc) && (bt == lt) &&
           (bs >= OUTSET) &&
  -        (ls == DOTTED || ls == DASHED || ls == SOLID || ls == OUTSET);
  +        (ls == DOTTED || ls == DASHED || ls == SOLID || ls == OUTSET));
   
  -        bool ignore_right =
  -            (bc == rc) && (bt == rt) &&
  +        bool ignore_right = (render_radii && bottomRight.width() > 0) ||
  +            ((bc == rc) && (bt == rt) &&
               (bs >= OUTSET) &&
  -            (rs == DOTTED || rs == DASHED || rs == SOLID || rs == INSET);
  +            (rs == DOTTED || rs == DASHED || rs == SOLID || rs == INSET));
           
  -        drawBorder(p, _tx, _ty + h - style->borderBottomWidth(), _tx + w, _ty + h, BSBottom, bc, style->color(), bs,
  -                   ignore_left?0:style->borderLeftWidth(),
  -                   ignore_right?0:style->borderRightWidth());
  +        int x = _tx;
  +        int x2 = _tx + w;
  +        if (render_radii) {
  +            x += bottomLeft.width();
  +            x2 -= bottomRight.width();
  +        }
  +
  +        drawBorder(p, x, _ty + h - style->borderBottomWidth(), x2, _ty + h, BSBottom, bc, style->color(), bs,
  +                   ignore_left ? 0 :style->borderLeftWidth(),
  +                   ignore_right? 0 :style->borderRightWidth());
       }
       
  -    if(render_l)
  -    {
  -	bool ignore_top =
  -	  (tc == lc) && (tt == lt) &&
  +    if (render_l) {
  +	bool ignore_top = (render_radii && topLeft.height() > 0) ||
  +	  ((tc == lc) && (tt == lt) &&
   	  (ls >= OUTSET) &&
  -	  (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET);
  +	  (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET));
   
  -	bool ignore_bottom =
  -	  (bc == lc) && (bt == lt) &&
  +	bool ignore_bottom = (render_radii && bottomLeft.height() > 0) ||
  +	  ((bc == lc) && (bt == lt) &&
   	  (ls >= OUTSET) &&
  -	  (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET);
  +	  (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET));
   
  -        drawBorder(p, _tx, _ty, _tx + style->borderLeftWidth(), _ty + h, BSLeft, lc, style->color(), ls,
  +        int y = _ty;
  +        int y2 = _ty + h;
  +        if (render_radii) {
  +            y += topLeft.height();
  +            y2 -= bottomLeft.height();
  +        }
  +        
  +        drawBorder(p, _tx, y, _tx + style->borderLeftWidth(), y2, BSLeft, lc, style->color(), ls,
   		   ignore_top?0:style->borderTopWidth(),
   		   ignore_bottom?0:style->borderBottomWidth());
       }
   
  -    if(render_r)
  -    {
  -	bool ignore_top =
  -	  (tc == rc) && (tt == rt) &&
  +    if (render_r) {
  +	bool ignore_top = (render_radii && topRight.height() > 0) ||
  +	  ((tc == rc) && (tt == rt) &&
   	  (rs >= DOTTED || rs == INSET) &&
  -	  (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET);
  +	  (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET));
   
  -	bool ignore_bottom =
  -	  (bc == rc) && (bt == rt) &&
  +	bool ignore_bottom = (render_radii && bottomRight.height() > 0) ||
  +	  ((bc == rc) && (bt == rt) &&
   	  (rs >= DOTTED || rs == INSET) &&
  -	  (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET);
  +	  (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET));
  +
  +        int y = _ty;
  +        int y2 = _ty + h;
  +        if (render_radii) {
  +            y += topRight.height();
  +            y2 -= bottomRight.height();
  +        }
   
  -        drawBorder(p, _tx + w - style->borderRightWidth(), _ty, _tx + w, _ty + h, BSRight, rc, style->color(), rs,
  +        drawBorder(p, _tx + w - style->borderRightWidth(), y, _tx + w, y2, BSRight, rc, style->color(), rs,
   		   ignore_top?0:style->borderTopWidth(),
   		   ignore_bottom?0:style->borderBottomWidth());
       }
  @@ -1661,6 +1828,15 @@
           if (currNew->backgroundImage() && (!oldLayers || !oldLayers->containsImage(currNew->backgroundImage())))
               currNew->backgroundImage()->ref(this);
       }
  +    
  +    CachedImage* oldBorderImage = oldStyle ? oldStyle->borderImage().image() : 0;
  +    CachedImage* newBorderImage = m_style ? m_style->borderImage().image() : 0;
  +    if (oldBorderImage != newBorderImage) {
  +        if (oldBorderImage)
  +            oldBorderImage->deref(this);
  +        if (newBorderImage)
  +            newBorderImage->ref(this);
  +    }
   }
   
   QRect RenderObject::viewRect() const
  @@ -2320,7 +2496,7 @@
   
   void RenderObject::setPixmap(const QPixmap&, const QRect&, CachedImage *image)
   {
  -    // Repaint when the background image finishes loading.
  +    // Repaint when the background image or border image finishes loading.
       // This is needed for RenderBox objects, and also for table objects that hold
       // backgrounds that are then respected by the table cells (which are RenderBox
       // subclasses). It would be even better to find a more elegant way of doing this that
  
  
  
  1.155     +2 -1      WebCore/khtml/rendering/render_object.h
  
  Index: render_object.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_object.h,v
  retrieving revision 1.154
  retrieving revision 1.155
  diff -u -r1.154 -r1.155
  --- render_object.h	9 Aug 2005 20:58:27 -0000	1.154
  +++ render_object.h	27 Aug 2005 00:14:21 -0000	1.155
  @@ -405,6 +405,7 @@
       };
       virtual void paint(PaintInfo& i, int tx, int ty);
       void paintBorder(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style, bool begin=true, bool end=true);
  +    bool paintBorderImage(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style);
       void paintOutline(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style);
   
       // RenderBox implements this.
  @@ -412,7 +413,7 @@
   
       virtual void paintBackgroundExtended(QPainter *p, const QColor& c, const BackgroundLayer* bgLayer, int clipy, int cliph,
                                            int _tx, int _ty, int w, int height,
  -                                         int bleft, int bright) {};
  +                                         int bleft, int bright, int pleft, int pright) {};
   
       /*
        * This function calculates the minimum & maximum width that the object
  
  
  
  1.69      +36 -3     WebCore/khtml/rendering/render_style.cpp
  
  Index: render_style.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_style.cpp,v
  retrieving revision 1.68
  retrieving revision 1.69
  diff -u -r1.68 -r1.69
  --- render_style.cpp	19 Jul 2005 00:02:08 -0000	1.68
  +++ render_style.cpp	27 Aug 2005 00:14:21 -0000	1.69
  @@ -109,10 +109,12 @@
   BackgroundLayer::BackgroundLayer()
   :m_image(RenderStyle::initialBackgroundImage()),
    m_bgAttachment(RenderStyle::initialBackgroundAttachment()),
  + m_bgClip(RenderStyle::initialBackgroundClip()),
  + m_bgOrigin(RenderStyle::initialBackgroundOrigin()),
    m_bgRepeat(RenderStyle::initialBackgroundRepeat()),
    m_next(0)
   {
  -    m_imageSet = m_attachmentSet = m_repeatSet = m_xPosSet = m_yPosSet = false;     
  +    m_imageSet = m_attachmentSet = m_clipSet = m_originSet = m_repeatSet = m_xPosSet = m_yPosSet = false;     
   }
   
   BackgroundLayer::BackgroundLayer(const BackgroundLayer& o)
  @@ -122,9 +124,13 @@
       m_xPosition = o.m_xPosition;
       m_yPosition = o.m_yPosition;
       m_bgAttachment = o.m_bgAttachment;
  +    m_bgClip = o.m_bgClip;
  +    m_bgOrigin = o.m_bgOrigin;
       m_bgRepeat = o.m_bgRepeat;
       m_imageSet = o.m_imageSet;
       m_attachmentSet = o.m_attachmentSet;
  +    m_clipSet = o.m_clipSet;
  +    m_originSet = o.m_originSet;
       m_repeatSet = o.m_repeatSet;
       m_xPosSet = o.m_xPosSet;
       m_yPosSet = o.m_yPosSet;
  @@ -145,10 +151,14 @@
       m_xPosition = o.m_xPosition;
       m_yPosition = o.m_yPosition;
       m_bgAttachment = o.m_bgAttachment;
  +    m_bgClip = o.m_bgClip;
  +    m_bgOrigin = o.m_bgOrigin;
       m_bgRepeat = o.m_bgRepeat;
       
       m_imageSet = o.m_imageSet;
       m_attachmentSet = o.m_attachmentSet;
  +    m_clipSet = o.m_clipSet;
  +    m_originSet = o.m_originSet;
       m_repeatSet = o.m_repeatSet;
       m_xPosSet = o.m_xPosSet;
       m_yPosSet = o.m_yPosSet;
  @@ -158,7 +168,7 @@
   
   bool BackgroundLayer::operator==(const BackgroundLayer& o) const {
       return m_image == o.m_image && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition &&
  -           m_bgAttachment == o.m_bgAttachment && m_bgRepeat == o.m_bgRepeat && 
  +           m_bgAttachment == o.m_bgAttachment && m_bgClip == o.m_bgClip && m_bgOrigin == o.m_bgOrigin && m_bgRepeat == o.m_bgRepeat && 
              m_imageSet == o.m_imageSet && m_attachmentSet == o.m_attachmentSet && m_repeatSet == o.m_repeatSet &&
              m_xPosSet == o.m_xPosSet && m_yPosSet == o.m_yPosSet &&
              ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next);
  @@ -211,6 +221,28 @@
           }
       }
       
  +    for (curr = this; curr && curr->isBackgroundClipSet(); curr = curr->next());
  +    if (curr && curr != this) {
  +        // We need to fill in the remaining values with the pattern specified.
  +        for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
  +            curr->m_bgClip = pattern->m_bgClip;
  +            pattern = pattern->next();
  +            if (pattern == curr || !pattern)
  +                pattern = this;
  +        }
  +    }
  +
  +    for (curr = this; curr && curr->isBackgroundOriginSet(); curr = curr->next());
  +    if (curr && curr != this) {
  +        // We need to fill in the remaining values with the pattern specified.
  +        for (BackgroundLayer* pattern = this; curr; curr = curr->next()) {
  +            curr->m_bgOrigin = pattern->m_bgOrigin;
  +            pattern = pattern->next();
  +            if (pattern == curr || !pattern)
  +                pattern = this;
  +        }
  +    }
  +
       for (curr = this; curr && curr->isBackgroundRepeatSet(); curr = curr->next());
       if (curr && curr != this) {
           // We need to fill in the remaining values with the pattern specified.
  @@ -230,7 +262,8 @@
           next = p->m_next;
           if (next && !next->isBackgroundImageSet() &&
               !next->isBackgroundXPositionSet() && !next->isBackgroundYPositionSet() &&
  -            !next->isBackgroundAttachmentSet() && !next->isBackgroundRepeatSet()) {
  +            !next->isBackgroundAttachmentSet() && !next->isBackgroundClipSet() &&
  +            !next->isBackgroundOriginSet() && !next->isBackgroundRepeatSet()) {
               delete next;
               p->m_next = 0;
               break;
  
  
  
  1.88      +129 -17   WebCore/khtml/rendering/render_style.h
  
  Index: render_style.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_style.h,v
  retrieving revision 1.87
  retrieving revision 1.88
  diff -u -r1.87 -r1.88
  --- render_style.h	29 Jul 2005 23:02:43 -0000	1.87
  +++ render_style.h	27 Aug 2005 00:14:21 -0000	1.88
  @@ -205,10 +205,8 @@
       unsigned short width : 12;
       EBorderStyle style : 4;
   
  -    bool nonZero() const
  -    {
  -      // rikkus: workaround for gcc 2.95.3
  -      return width!=0 && !(style==BNONE);
  +    bool nonZero(bool checkStyle = true) const {
  +        return width != 0 && (!checkStyle || style != BNONE);
       }
   
       bool isTransparent() const {
  @@ -273,6 +271,32 @@
       EBorderPrecedence precedence;    
   };
   
  +enum EBorderImageRule {
  +    BI_STRETCH, BI_ROUND, BI_REPEAT
  +};
  +
  +class BorderImage
  +{
  +public:
  +    BorderImage() :m_image(0), m_horizontalRule(BI_STRETCH), m_verticalRule(BI_STRETCH) {}
  +    BorderImage(CachedImage* image, LengthBox slices, EBorderImageRule h, EBorderImageRule v) 
  +      :m_image(image), m_slices(slices), m_horizontalRule(h), m_verticalRule(v) {}
  +
  +    bool operator==(const BorderImage& o) const
  +    {
  +        return m_image == o.m_image && m_slices == o.m_slices && m_horizontalRule == o.m_horizontalRule &&
  +               m_verticalRule == o.m_verticalRule;
  +    }
  +
  +    bool hasImage() const { return m_image != 0; }
  +    CachedImage* image() const { return m_image; }
  +
  +    CachedImage* m_image;
  +    LengthBox m_slices;
  +    EBorderImageRule m_horizontalRule : 2;
  +    EBorderImageRule m_verticalRule : 2;
  +};
  +
   class BorderData
   {
   public:
  @@ -280,17 +304,61 @@
       BorderValue right;
       BorderValue top;
       BorderValue bottom;
  +    
  +    BorderImage image;
  +
  +    QSize topLeft;
  +    QSize topRight;
  +    QSize bottomLeft;
  +    QSize bottomRight;
   
       bool hasBorder() const
       {
  -    	return left.nonZero() || right.nonZero() || top.nonZero() || bottom.nonZero();
  +        bool haveImage = image.hasImage();
  +    	return left.nonZero(haveImage) || right.nonZero(haveImage) || top.nonZero(haveImage) || bottom.nonZero(haveImage);
       }
   
  +    bool hasBorderRadius() const {
  +        if (topLeft.width() > 0)
  +            return true;
  +        if (topRight.width() > 0)
  +            return true;
  +        if (bottomLeft.width() > 0)
  +            return true;
  +        if (bottomRight.width() > 0)
  +            return true;
  +        return false;
  +    }
  +    
  +    unsigned short borderLeftWidth() const {
  +        if (!image.hasImage() && (left.style == BNONE || left.style == BHIDDEN))
  +            return 0; 
  +        return left.width;
  +    }
  +    
  +    unsigned short borderRightWidth() const {
  +        if (!image.hasImage() && (right.style == BNONE || right.style == BHIDDEN))
  +            return 0;
  +        return right.width;
  +    }
  +    
  +    unsigned short borderTopWidth() const {
  +        if (!image.hasImage() && (top.style == BNONE || top.style == BHIDDEN))
  +            return 0;
  +        return top.width;
  +    }
  +    
  +    unsigned short borderBottomWidth() const {
  +        if (!image.hasImage() && (bottom.style == BNONE || bottom.style == BHIDDEN))
  +            return 0;
  +        return bottom.width;
  +    }
  +    
       bool operator==(const BorderData& o) const
       {
  -    	return left==o.left && right==o.right && top==o.top && bottom==o.bottom;
  +    	return left == o.left && right == o.right && top == o.top && bottom == o.bottom && image == o.image &&
  +               topLeft == o.topLeft && topRight == o.topRight && bottomLeft == o.bottomLeft && bottomRight == o.bottomRight;
       }
  -
   };
   
   enum EMarginCollapse { MCOLLAPSE, MSEPARATE, MDISCARD };
  @@ -436,6 +504,10 @@
   };
   
   //------------------------------------------------
  +enum EBackgroundBox {
  +    BGBORDER, BGPADDING, BGCONTENT
  +};
  +
   enum EBackgroundRepeat {
       REPEAT, REPEAT_X, REPEAT_Y, NO_REPEAT
   };
  @@ -451,7 +523,10 @@
       Length backgroundXPosition() const { return m_xPosition; }
       Length backgroundYPosition() const { return m_yPosition; }
       bool backgroundAttachment() const { return m_bgAttachment; }
  +    EBackgroundBox backgroundClip() const { return m_bgClip; }
  +    EBackgroundBox backgroundOrigin() const { return m_bgOrigin; }
       EBackgroundRepeat backgroundRepeat() const { return m_bgRepeat; }
  +
       BackgroundLayer* next() const { return m_next; }
       BackgroundLayer* next() { return m_next; }
   
  @@ -459,18 +534,24 @@
       bool isBackgroundXPositionSet() const { return m_xPosSet; }
       bool isBackgroundYPositionSet() const { return m_yPosSet; }
       bool isBackgroundAttachmentSet() const { return m_attachmentSet; }
  +    bool isBackgroundClipSet() const { return m_clipSet; }
  +    bool isBackgroundOriginSet() const { return m_originSet; }
       bool isBackgroundRepeatSet() const { return m_repeatSet; }
  -
  +    
       void setBackgroundImage(CachedImage* i) { m_image = i; m_imageSet = true; }
       void setBackgroundXPosition(const Length& l) { m_xPosition = l; m_xPosSet = true; }
       void setBackgroundYPosition(const Length& l) { m_yPosition = l; m_yPosSet = true; }
       void setBackgroundAttachment(bool b) { m_bgAttachment = b; m_attachmentSet = true; }
  +    void setBackgroundClip(EBackgroundBox b) { m_bgClip = b; m_clipSet = true; }
  +    void setBackgroundOrigin(EBackgroundBox b) { m_bgOrigin = b; m_originSet = true; }
       void setBackgroundRepeat(EBackgroundRepeat r) { m_bgRepeat = r; m_repeatSet = true; }
       
       void clearBackgroundImage() { m_imageSet = false; }
       void clearBackgroundXPosition() { m_xPosSet = false; }
       void clearBackgroundYPosition() { m_yPosSet = false; }
       void clearBackgroundAttachment() { m_attachmentSet = false; }
  +    void clearBackgroundClip() { m_clipSet = false; }
  +    void clearBackgroundOrigin() { m_originSet = false; }
       void clearBackgroundRepeat() { m_repeatSet = false; }
   
       void setNext(BackgroundLayer* n) { if (m_next != n) { delete m_next; m_next = n; } }
  @@ -505,10 +586,14 @@
       Length m_yPosition;
   
       bool m_bgAttachment : 1;
  +    EBackgroundBox m_bgClip : 2;
  +    EBackgroundBox m_bgOrigin : 2;
       EBackgroundRepeat m_bgRepeat : 2;
   
       bool m_imageSet : 1;
       bool m_attachmentSet : 1;
  +    bool m_clipSet : 1;
  +    bool m_originSet : 1;
       bool m_repeatSet : 1;
       bool m_xPosSet : 1;
       bool m_yPosSet : 1;
  @@ -1146,23 +1231,27 @@
       const BorderValue& borderTop() const { return surround->border.top; }
       const BorderValue& borderBottom() const { return surround->border.bottom; }
   
  -    unsigned short  borderLeftWidth() const
  -    { if( surround->border.left.style == BNONE || surround->border.left.style == BHIDDEN) return 0; return surround->border.left.width; }
  +    const BorderImage& borderImage() const { return surround->border.image; }
  +
  +    QSize borderTopLeftRadius() const { return surround->border.topLeft; }
  +    QSize borderTopRightRadius() const { return surround->border.topRight; }
  +    QSize borderBottomLeftRadius() const { return surround->border.bottomLeft; }
  +    QSize borderBottomRightRadius() const { return surround->border.bottomRight; }
  +    bool hasBorderRadius() const { return surround->border.hasBorderRadius(); }
  +
  +    unsigned short  borderLeftWidth() const { return surround->border.borderLeftWidth(); }
       EBorderStyle    borderLeftStyle() const { return surround->border.left.style; }
       const QColor &  borderLeftColor() const { return surround->border.left.color; }
       bool borderLeftIsTransparent() const { return surround->border.left.isTransparent(); }
  -    unsigned short  borderRightWidth() const
  -    { if (surround->border.right.style == BNONE || surround->border.right.style == BHIDDEN) return 0; return surround->border.right.width; }
  +    unsigned short  borderRightWidth() const { return surround->border.borderRightWidth(); }
       EBorderStyle    borderRightStyle() const {  return surround->border.right.style; }
       const QColor &  	    borderRightColor() const {  return surround->border.right.color; }
       bool borderRightIsTransparent() const { return surround->border.right.isTransparent(); }
  -    unsigned short  borderTopWidth() const
  -    { if(surround->border.top.style == BNONE || surround->border.top.style == BHIDDEN) return 0; return surround->border.top.width; }
  +    unsigned short  borderTopWidth() const { return surround->border.borderTopWidth(); }
       EBorderStyle    borderTopStyle() const {return surround->border.top.style; }
       const QColor &  borderTopColor() const {  return surround->border.top.color; }
       bool borderTopIsTransparent() const { return surround->border.top.isTransparent(); }
  -    unsigned short  borderBottomWidth() const
  -    { if(surround->border.bottom.style == BNONE || surround->border.bottom.style == BHIDDEN) return 0; return surround->border.bottom.width; }
  +    unsigned short  borderBottomWidth() const { return surround->border.borderBottomWidth(); }
       EBorderStyle    borderBottomStyle() const {  return surround->border.bottom.style; }
       const QColor &  	    borderBottomColor() const {  return surround->border.bottom.color; }
       bool borderBottomIsTransparent() const { return surround->border.bottom.isTransparent(); }
  @@ -1216,6 +1305,8 @@
       CachedImage *backgroundImage() const { return background->m_background.m_image; }
       EBackgroundRepeat backgroundRepeat() const { return background->m_background.m_bgRepeat; }
       bool backgroundAttachment() const { return background->m_background.m_bgAttachment; }
  +    EBackgroundBox backgroundClip() const { return background->m_background.m_bgClip; }
  +    EBackgroundBox backgroundOrigin() const { return background->m_background.m_bgOrigin; }
       Length backgroundXPosition() const { return background->m_background.m_xPosition; }
       Length backgroundYPosition() const { return background->m_background.m_yPosition; }
       BackgroundLayer* accessBackgroundLayers() { return &(background.access()->m_background); }
  @@ -1334,15 +1425,32 @@
       }
   #endif
   
  -    void resetBorder() { resetBorderTop(); resetBorderRight(); resetBorderBottom(); resetBorderLeft(); }
  +    void resetBorder() { resetBorderImage(); resetBorderTop(); resetBorderRight(); resetBorderBottom(); resetBorderLeft(); resetBorderRadius(); }
       void resetBorderTop() { SET_VAR(surround, border.top, BorderValue()) }
       void resetBorderRight() { SET_VAR(surround, border.right, BorderValue()) }
       void resetBorderBottom() { SET_VAR(surround, border.bottom, BorderValue()) }
       void resetBorderLeft() { SET_VAR(surround, border.left, BorderValue()) }
  +    void resetBorderImage() { SET_VAR(surround, border.image, BorderImage()) }
  +    void resetBorderRadius() { resetBorderTopLeftRadius(); resetBorderTopRightRadius(); resetBorderBottomLeftRadius(); resetBorderBottomRightRadius(); }
  +    void resetBorderTopLeftRadius() { SET_VAR(surround, border.topLeft, initialBorderRadius()) }
  +    void resetBorderTopRightRadius() { SET_VAR(surround, border.topRight, initialBorderRadius()) }
  +    void resetBorderBottomLeftRadius() { SET_VAR(surround, border.bottomLeft, initialBorderRadius()) }
  +    void resetBorderBottomRightRadius() { SET_VAR(surround, border.bottomRight, initialBorderRadius()) }
  +    
       void resetOutline() { SET_VAR(background, m_outline, OutlineValue()) }
       
       void setBackgroundColor(const QColor& v)    { SET_VAR(background, m_color, v) }
   
  +    void setBorderImage(const BorderImage& b)   { SET_VAR(surround, border.image, b) }
  +
  +    void setBorderTopLeftRadius(const QSize& s) { SET_VAR(surround, border.topLeft, s) }
  +    void setBorderTopRightRadius(const QSize& s) { SET_VAR(surround, border.topRight, s) }
  +    void setBorderBottomLeftRadius(const QSize& s) { SET_VAR(surround, border.bottomLeft, s) }
  +    void setBorderBottomRightRadius(const QSize& s) { SET_VAR(surround, border.bottomRight, s) }
  +    void setBorderRadius(const QSize& s) { 
  +        setBorderTopLeftRadius(s); setBorderTopRightRadius(s); setBorderBottomLeftRadius(s); setBorderBottomRightRadius(s);
  +    }
  +
       void setBorderLeftWidth(unsigned short v)   {  SET_VAR(surround,border.left.width,v) }
       void setBorderLeftStyle(EBorderStyle v)     {  SET_VAR(surround,border.left.style,v) }
       void setBorderLeftColor(const QColor & v)   {  SET_VAR(surround,border.left.color,v) }
  @@ -1546,9 +1654,13 @@
   
       // Initial values for all the properties
       static bool initialBackgroundAttachment() { return true; }
  +    static EBackgroundBox initialBackgroundClip() { return BGBORDER; }
  +    static EBackgroundBox initialBackgroundOrigin() { return BGPADDING; }
       static EBackgroundRepeat initialBackgroundRepeat() { return REPEAT; }
       static bool initialBorderCollapse() { return false; }
       static EBorderStyle initialBorderStyle() { return BNONE; }
  +    static BorderImage initialBorderImage() { return BorderImage(); }
  +    static QSize initialBorderRadius() { return QSize(0,0); }
       static ECaptionSide initialCaptionSide() { return CAPTOP; }
       static EClear initialClear() { return CNONE; }
       static EDirection initialDirection() { return LTR; }
  
  
  
  1.78      +5 -0      WebCore/kwq/KWQPainter.h
  
  Index: KWQPainter.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQPainter.h,v
  retrieving revision 1.77
  retrieving revision 1.78
  diff -u -r1.77 -r1.78
  --- KWQPainter.h	15 Aug 2005 02:57:27 -0000	1.77
  +++ KWQPainter.h	27 Aug 2005 00:14:22 -0000	1.78
  @@ -47,6 +47,7 @@
   class QPainter : public Qt {
   public:
       typedef enum { RTL, LTR } TextDirection;
  +    typedef enum { STRETCH, ROUND, REPEAT } TileRule;
   
       QPainter();
       QPainter(bool forPrinting);
  @@ -92,8 +93,12 @@
       void drawFloatPixmap( float x, float y, float w, float h, const QPixmap &,
   			    float sx=0, float sy=0, float sw=-1, float sh=-1, int compositeOperator=-1, CGContextRef context=0);
       void drawTiledPixmap(int, int, int, int, const QPixmap &, int sx=0, int sy=0, CGContextRef context=0);
  +    void drawScaledAndTiledPixmap(int, int, int, int, const QPixmap &, int, int, int, int, TileRule hRule = STRETCH, TileRule vRule = STRETCH,
  +                                  CGContextRef context=0);
   
       void addClip(const QRect &);
  +    void addRoundedRectClip(const QRect& rect, const QSize& topLeft, const QSize& topRight,
  +                            const QSize& bottomLeft, const QSize& bottomRight);
   
       RasterOp rasterOp() const;
       void setRasterOp(RasterOp);
  
  
  
  1.133     +68 -0     WebCore/kwq/KWQPainter.mm
  
  Index: KWQPainter.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQPainter.mm,v
  retrieving revision 1.132
  retrieving revision 1.133
  diff -u -r1.132 -r1.133
  --- KWQPainter.mm	23 Aug 2005 18:32:51 -0000	1.132
  +++ KWQPainter.mm	27 Aug 2005 00:14:22 -0000	1.133
  @@ -330,6 +330,7 @@
   // This method is only used to draw the little circles used in lists.
   void QPainter::drawEllipse(int x, int y, int w, int h)
   {
  +    // FIXME: CG added CGContextAddEllipseinRect in Tiger, so we should be able to quite easily draw an ellipse.
       // This code can only handle circles, not ellipses. But khtml only
       // uses it for circles.
       ASSERT(w == h);
  @@ -540,6 +541,22 @@
       KWQ_UNBLOCK_EXCEPTIONS;
   }
   
  +void QPainter::drawScaledAndTiledPixmap(int x, int y, int w, int h, const QPixmap &pixmap, int sx, int sy, int sw, int sh, 
  +                                        TileRule hRule, TileRule vRule, CGContextRef context)
  +{
  +    if (data->state.paintingDisabled)
  +        return;
  +    
  +    if (hRule == STRETCH && vRule == STRETCH)
  +        // Just do a scale.
  +        return drawPixmap(x, y, w, h, pixmap, sx, sy, sw, sh, -1, context);
  +
  +    KWQ_BLOCK_EXCEPTIONS;
  +    [pixmap.imageRenderer scaleAndTileInRect:NSMakeRect(x, y, w, h) fromRect:NSMakeRect(sx, sy, sw, sh) 
  +                      withHorizontalTileRule:(WebImageTileRule)hRule withVerticalTileRule:(WebImageTileRule)vRule context:context];
  +    KWQ_UNBLOCK_EXCEPTIONS;
  +}
  +
   void QPainter::_updateRenderer()
   {
       if (data->textRenderer == 0 || data->state.font != data->textRendererFont) {
  @@ -746,6 +763,57 @@
       [NSBezierPath clipRect:rect];
   }
   
  +void QPainter::addRoundedRectClip(const QRect& rect, const QSize& topLeft, const QSize& topRight,
  +                                  const QSize& bottomLeft, const QSize& bottomRight)
  +{
  +    // Need sufficient width and height to contain these curves.  Sanity check our top/bottom
  +    // values and our width/height values to make sure the curves can all fit.
  +    int requiredWidth = kMax(topLeft.width() + topRight.width(), bottomLeft.width() + bottomRight.width());
  +    if (requiredWidth > rect.width())
  +        return;
  +    int requiredHeight = kMax(topLeft.height() + bottomLeft.height(), topRight.height() + bottomRight.height());
  +    if (requiredHeight > rect.height())
  +        return;
  + 
  +    // Clip to our rect.
  +    addClip(rect);
  +
  +    // Ok, the curves can fit.
  +    CGContextRef context = (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]);
  +    
  +    // Add the four ellipses to the path.  Technically this really isn't good enough, since we could end up
  +    // not clipping the other 3/4 of the ellipse we don't care about.  We're relying on the fact that for
  +    // normal use cases these ellipses won't overlap one another (or when they do the curvature of one will
  +    // be subsumed by the other).
  +    CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.y(), topLeft.width() * 2, topLeft.height() * 2));
  +    CGContextAddEllipseInRect(context, CGRectMake(rect.x() + rect.width() - topRight.width() * 2, rect.y(),
  +                                                  topRight.width() * 2, topRight.height() * 2));
  +    CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.y() + rect.height() - bottomLeft.height() * 2,
  +                                                  bottomLeft.width() * 2, bottomLeft.height() * 2));
  +    CGContextAddEllipseInRect(context, CGRectMake(rect.x() + rect.width() - bottomRight.width() * 2,
  +                                                  rect.y() + rect.height() - bottomRight.height() * 2,
  +                                                  bottomRight.width() * 2, bottomRight.height() * 2));
  +    
  +    // Now add five rects (one for each edge rect in between the rounded corners and one for the interior).
  +    CGContextAddRect(context, CGRectMake(rect.x() + topLeft.width(), rect.y(),
  +                                         rect.width() - topLeft.width() - topRight.width(),
  +                                         kMax(topLeft.height(), topRight.height())));
  +    CGContextAddRect(context, CGRectMake(rect.x() + bottomLeft.width(), 
  +                                         rect.y() + rect.height() - kMax(bottomLeft.height(), bottomRight.height()),
  +                                         rect.width() - bottomLeft.width() - bottomRight.width(),
  +                                         kMax(bottomLeft.height(), bottomRight.height())));
  +    CGContextAddRect(context, CGRectMake(rect.x(), rect.y() + topLeft.height(),
  +                                         kMax(topLeft.width(), bottomLeft.width()), rect.height() - topLeft.height() - bottomLeft.height()));
  +    CGContextAddRect(context, CGRectMake(rect.x() + rect.width() - kMax(topRight.width(), bottomRight.width()),
  +                                         rect.y() + topRight.height(),
  +                                         kMax(topRight.width(), bottomRight.width()), rect.height() - topRight.height() - bottomRight.height()));
  +    CGContextAddRect(context, CGRectMake(rect.x() + kMax(topLeft.width(), bottomLeft.width()),
  +                                         rect.y() + kMax(topLeft.height(), topRight.height()),
  +                                         rect.width() - kMax(topLeft.width(), bottomLeft.width()) - kMax(topRight.width(), bottomRight.width()),
  +                                         rect.height() - kMax(topLeft.height(), topRight.height()) - kMax(bottomLeft.height(), bottomRight.height())));
  +    CGContextClip(context);
  +}
  +
   Qt::RasterOp QPainter::rasterOp() const
   {
       return CopyROP;
  
  
  
  1.42      +2 -1      WebCore/kwq/KWQPixmap.h
  
  Index: KWQPixmap.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQPixmap.h,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- KWQPixmap.h	5 Jul 2005 07:57:46 -0000	1.41
  +++ KWQPixmap.h	27 Aug 2005 00:14:22 -0000	1.42
  @@ -98,7 +98,8 @@
       static bool shouldUseThreadedDecoding();
   
       void resetAnimation();
  -    
  +    void setAnimationRect(const QRect&) const;
  +
   private:
   
       WebCoreImageRendererPtr imageRenderer;
  
  
  
  1.50      +5 -0      WebCore/kwq/KWQPixmap.mm
  
  Index: KWQPixmap.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQPixmap.mm,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- KWQPixmap.mm	16 Aug 2005 19:03:19 -0000	1.49
  +++ KWQPixmap.mm	27 Aug 2005 00:14:22 -0000	1.50
  @@ -115,6 +115,11 @@
       }
   }
   
  +void QPixmap::setAnimationRect(const QRect& rect) const
  +{
  +    [imageRenderer setAnimationRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
  +}
  +
   @interface WebImageCallback : NSObject
   {
       khtml::CachedImageCallback *callback;
  
  
  
  1.16      +8 -0      WebCore/kwq/WebCoreImageRenderer.h
  
  Index: WebCoreImageRenderer.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/WebCoreImageRenderer.h,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- WebCoreImageRenderer.h	25 Feb 2005 00:25:12 -0000	1.15
  +++ WebCoreImageRenderer.h	27 Aug 2005 00:14:22 -0000	1.16
  @@ -25,6 +25,12 @@
   
   #import <Cocoa/Cocoa.h>
   
  +typedef enum {
  +    WebImageStretch,
  +    WebImageRound,
  +    WebImageRepeat
  +} WebImageTileRule;
  +
   @protocol WebCoreImageRenderer <NSObject, NSCopying>
   
   - (BOOL)incrementalLoadWithBytes:(const void *)bytes length:(unsigned)length complete:(BOOL)isComplete callback:(id)c;
  @@ -35,6 +41,7 @@
   - (void)drawImageInRect:(NSRect)ir fromRect:(NSRect)fr compositeOperator:(NSCompositingOperation)compsiteOperator context:(CGContextRef)context;
   - (void)stopAnimation;
   - (void)tileInRect:(NSRect)r fromPoint:(NSPoint)p context:(CGContextRef)context;
  +- (void)scaleAndTileInRect:(NSRect)ir fromRect:(NSRect)fr withHorizontalTileRule:(WebImageTileRule)hRule withVerticalTileRule:(WebImageTileRule)vRule context:(CGContextRef)context;
   - (BOOL)isNull;
   - (id <WebCoreImageRenderer>)retainOrCopyIfNeeded;
   - (void)increaseUseCount;
  @@ -42,4 +49,5 @@
   - (void)flushRasterCache;
   - (CGImageRef)imageRef;
   - (void)resetAnimation;
  +- (void)setAnimationRect:(NSRect)r;
   @end
  
  
  



More information about the webkit-changes mailing list