[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