OSDN Git Service

Merge WebKit at r71558: Initial merge by git.
[android-x86/external-webkit.git] / WebCore / rendering / style / RenderStyle.cpp
index f3b3f0c..a6e7d59 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 
 #include "CSSPropertyNames.h"
 #include "CSSStyleSelector.h"
-#include "CachedImage.h"
-#include "CounterContent.h"
 #include "FontSelector.h"
 #include "RenderArena.h"
 #include "RenderObject.h"
+#include "ScaleTransformOperation.h"
 #include "StyleImage.h"
 #include <wtf/StdLibExtras.h>
 #include <algorithm>
@@ -246,6 +245,19 @@ RenderStyle* RenderStyle::addCachedPseudoStyle(PassRefPtr<RenderStyle> pseudo)
     return result;
 }
 
+void RenderStyle::removeCachedPseudoStyle(PseudoId pid)
+{
+    if (!m_cachedPseudoStyles)
+        return;
+    for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
+        RenderStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get();
+        if (pseudoStyle->styleType() == pid) {
+            m_cachedPseudoStyles->remove(i);
+            return;
+        }
+    }
+}
+
 bool RenderStyle::inheritedNotEqual(const RenderStyle* other) const
 {
     return inherited_flags != other->inherited_flags ||
@@ -299,11 +311,12 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
     changedContextSensitiveProperties = ContextSensitivePropertyNone;
 
 #if ENABLE(SVG)
-    // This is horribly inefficient.  Eventually we'll have to integrate
-    // this more directly by calling: Diff svgDiff = svgStyle->diff(other)
-    // and then checking svgDiff and returning from the appropriate places below.
-    if (m_svgStyle != other->m_svgStyle)
-        return StyleDifferenceLayout;
+    StyleDifference svgChange = StyleDifferenceEqual;
+    if (m_svgStyle != other->m_svgStyle) {
+        svgChange = m_svgStyle->diff(other->m_svgStyle.get());
+        if (svgChange == StyleDifferenceLayout)
+            return svgChange;
+    }
 #endif
 
     if (m_box->width() != other->m_box->width() ||
@@ -328,8 +341,8 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
 
     if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
         if (rareNonInheritedData->m_appearance != other->rareNonInheritedData->m_appearance ||
-            rareNonInheritedData->marginTopCollapse != other->rareNonInheritedData->marginTopCollapse ||
-            rareNonInheritedData->marginBottomCollapse != other->rareNonInheritedData->marginBottomCollapse ||
+            rareNonInheritedData->marginBeforeCollapse != other->rareNonInheritedData->marginBeforeCollapse ||
+            rareNonInheritedData->marginAfterCollapse != other->rareNonInheritedData->marginAfterCollapse ||
             rareNonInheritedData->lineClamp != other->rareNonInheritedData->lineClamp ||
             rareNonInheritedData->textOverflow != other->rareNonInheritedData->textOverflow)
             return StyleDifferenceLayout;
@@ -379,12 +392,17 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
 
     if (rareInheritedData.get() != other->rareInheritedData.get()) {
         if (rareInheritedData->highlight != other->rareInheritedData->highlight ||
+            rareInheritedData->indent != other->rareInheritedData->indent ||
+            rareInheritedData->m_effectiveZoom != other->rareInheritedData->m_effectiveZoom ||
             rareInheritedData->textSizeAdjust != other->rareInheritedData->textSizeAdjust ||
             rareInheritedData->wordBreak != other->rareInheritedData->wordBreak ||
             rareInheritedData->wordWrap != other->rareInheritedData->wordWrap ||
             rareInheritedData->nbspMode != other->rareInheritedData->nbspMode ||
             rareInheritedData->khtmlLineBreak != other->rareInheritedData->khtmlLineBreak ||
-            rareInheritedData->textSecurity != other->rareInheritedData->textSecurity)
+            rareInheritedData->textSecurity != other->rareInheritedData->textSecurity ||
+            rareInheritedData->hyphens != other->rareInheritedData->hyphens ||
+            rareInheritedData->hyphenationString != other->rareInheritedData->hyphenationString ||
+            rareInheritedData->hyphenationLocale != other->rareInheritedData->hyphenationLocale)
             return StyleDifferenceLayout;
 
         if (!rareInheritedData->shadowDataEquivalent(*other->rareInheritedData.get()))
@@ -394,15 +412,13 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
             return StyleDifferenceLayout;
     }
 
-    if (inherited->indent != other->inherited->indent ||
-        inherited->line_height != other->inherited->line_height ||
+    if (inherited->line_height != other->inherited->line_height ||
         inherited->list_style_image != other->inherited->list_style_image ||
         inherited->font != other->inherited->font ||
         inherited->horizontal_border_spacing != other->inherited->horizontal_border_spacing ||
         inherited->vertical_border_spacing != other->inherited->vertical_border_spacing ||
         inherited_flags._box_direction != other->inherited_flags._box_direction ||
         inherited_flags._visuallyOrdered != other->inherited_flags._visuallyOrdered ||
-        inherited_flags._htmlHacks != other->inherited_flags._htmlHacks ||
         noninherited_flags._position != other->noninherited_flags._position ||
         noninherited_flags._floating != other->noninherited_flags._floating ||
         noninherited_flags._originalDisplay != other->noninherited_flags._originalDisplay)
@@ -443,6 +459,14 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
         noninherited_flags._clear != other->noninherited_flags._clear)
         return StyleDifferenceLayout;
 
+    // Check block flow direction.
+    if (inherited_flags.m_writingMode != other->inherited_flags.m_writingMode)
+        return StyleDifferenceLayout;
+
+    // Check text combine mode.
+    if (rareNonInheritedData->m_textCombine != other->rareNonInheritedData->m_textCombine)
+        return StyleDifferenceLayout;
+
     // Overflow returns a layout hint.
     if (noninherited_flags._overflowX != other->noninherited_flags._overflowX ||
         noninherited_flags._overflowY != other->noninherited_flags._overflowY)
@@ -461,11 +485,8 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
     const CounterDirectiveMap* mapB = other->rareNonInheritedData->m_counterDirectives.get();
     if (!(mapA == mapB || (mapA && mapB && *mapA == *mapB)))
         return StyleDifferenceLayout;
-    if (visual->counterIncrement != other->visual->counterIncrement ||
-        visual->counterReset != other->visual->counterReset)
-        return StyleDifferenceLayout;
-
-    if (inherited->m_effectiveZoom != other->inherited->m_effectiveZoom)
+    if (rareNonInheritedData->m_counterIncrement != other->rareNonInheritedData->m_counterIncrement ||
+        rareNonInheritedData->m_counterReset != other->rareNonInheritedData->m_counterReset)
         return StyleDifferenceLayout;
 
     if ((rareNonInheritedData->opacity == 1 && other->rareNonInheritedData->opacity < 1) ||
@@ -474,6 +495,18 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
         return StyleDifferenceLayout;
     }
 
+    if ((visibility() == COLLAPSE) != (other->visibility() == COLLAPSE))
+        return StyleDifferenceLayout;
+                    
+#if ENABLE(SVG)
+    // SVGRenderStyle::diff() might have returned StyleDifferenceRepaint, eg. if fill changes.
+    // If eg. the font-size changed at the same time, we're not allowed to return StyleDifferenceRepaint,
+    // but have to return StyleDifferenceLayout, that's why  this if branch comes after all branches
+    // that are relevant for SVG and might return StyleDifferenceLayout.
+    if (svgChange != StyleDifferenceEqual)
+        return svgChange;
+#endif
+
     // Make sure these left/top/right/bottom checks stay below all layout checks and above
     // all visible checks.
     if (position() != StaticPosition) {
@@ -551,22 +584,22 @@ void RenderStyle::setClip(Length top, Length right, Length bottom, Length left)
     data->clip.m_left = left;
 }
 
-void RenderStyle::addCursor(CachedImage* image, const IntPoint& hotSpot)
+void RenderStyle::addCursor(PassRefPtr<StyleImage> image, const IntPoint& hotSpot)
 {
-    if (!inherited.access()->cursorData)
-        inherited.access()->cursorData = CursorList::create();
-    inherited.access()->cursorData->append(CursorData(image, hotSpot));
+    if (!rareInheritedData.access()->cursorData)
+        rareInheritedData.access()->cursorData = CursorList::create();
+    rareInheritedData.access()->cursorData->append(CursorData(image, hotSpot));
 }
 
 void RenderStyle::setCursorList(PassRefPtr<CursorList> other)
 {
-    inherited.access()->cursorData = other;
+    rareInheritedData.access()->cursorData = other;
 }
 
 void RenderStyle::clearCursorList()
 {
-    if (inherited->cursorData)
-        inherited.access()->cursorData = 0;
+    if (rareInheritedData->cursorData)
+        rareInheritedData.access()->cursorData = 0;
 }
 
 void RenderStyle::clearContent()
@@ -575,92 +608,59 @@ void RenderStyle::clearContent()
         rareNonInheritedData->m_content->clear();
 }
 
-void RenderStyle::setContent(PassRefPtr<StyleImage> image, bool add)
+ContentData* RenderStyle::prepareToSetContent(StringImpl* string, bool add)
 {
-    if (!image)
-        return; // The object is null. Nothing to do. Just bail.
-
     OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
     ContentData* lastContent = content.get();
     while (lastContent && lastContent->next())
         lastContent = lastContent->next();
 
+    if (string && add && lastContent && lastContent->isText()) {
+        // Augment the existing string and share the existing ContentData node.
+        String newText = lastContent->text();
+        newText.append(string);
+        lastContent->setText(newText.impl());
+        return 0;
+    }
+
     bool reuseContent = !add;
-    ContentData* newContentData;
+    OwnPtr<ContentData> newContentData;
     if (reuseContent && content) {
         content->clear();
         newContentData = content.release();
     } else
-        newContentData = new ContentData;
+        newContentData = adoptPtr(new ContentData);
+
+    ContentData* result = newContentData.get();
 
     if (lastContent && !reuseContent)
-        lastContent->setNext(newContentData);
+        lastContent->setNext(newContentData.release());
     else
-        content.set(newContentData);
+        content = newContentData.release();
 
-    newContentData->setImage(image);
+    return result;
 }
 
-void RenderStyle::setContent(PassRefPtr<StringImpl> s, bool add)
+void RenderStyle::setContent(PassRefPtr<StyleImage> image, bool add)
 {
-    if (!s)
-        return; // The string is null. Nothing to do. Just bail.
-
-    OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
-    ContentData* lastContent = content.get();
-    while (lastContent && lastContent->next())
-        lastContent = lastContent->next();
-
-    bool reuseContent = !add;
-    if (add && lastContent) {
-        if (lastContent->isText()) {
-            // We can augment the existing string and share this ContentData node.
-            String newStr = lastContent->text();
-            newStr.append(s.get());
-            lastContent->setText(newStr.impl());
-            return;
-        }
-    }
-
-    ContentData* newContentData = 0;
-    if (reuseContent && content) {
-        content->clear();
-        newContentData = content.release();
-    } else
-        newContentData = new ContentData;
-
-    if (lastContent && !reuseContent)
-        lastContent->setNext(newContentData);
-    else
-        content.set(newContentData);
-
-    newContentData->setText(s);
+    if (!image)
+        return;
+    prepareToSetContent(0, add)->setImage(image);
 }
 
-void RenderStyle::setContent(CounterContent* c, bool add)
+void RenderStyle::setContent(PassRefPtr<StringImpl> string, bool add)
 {
-    if (!c)
+    if (!string)
         return;
+    if (ContentData* data = prepareToSetContent(string.get(), add))
+        data->setText(string);
+}
 
-    OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
-    ContentData* lastContent = content.get();
-    while (lastContent && lastContent->next())
-        lastContent = lastContent->next();
-
-    bool reuseContent = !add;
-    ContentData* newContentData = 0;
-    if (reuseContent && content) {
-        content->clear();
-        newContentData = content.release();
-    } else
-        newContentData = new ContentData;
-
-    if (lastContent && !reuseContent)
-        lastContent->setNext(newContentData);
-    else
-        content.set(newContentData);
-
-    newContentData->setCounter(c);
+void RenderStyle::setContent(PassOwnPtr<CounterContent> counter, bool add)
+{
+    if (!counter)
+        return;
+    prepareToSetContent(0, add)->setCounter(counter);
 }
 
 void RenderStyle::applyTransform(TransformationMatrix& transform, const IntSize& borderBoxSize, ApplyTransformOrigin applyOrigin) const
@@ -698,19 +698,16 @@ void RenderStyle::applyTransform(TransformationMatrix& transform, const IntSize&
     }
 }
 
-#if ENABLE(XBL)
-void RenderStyle::addBindingURI(StringImpl* uri)
+void RenderStyle::setPageScaleTransform(float scale)
 {
-    BindingURI* binding = new BindingURI(uri);
-    if (!bindingURIs())
-        SET_VAR(rareNonInheritedData, bindingURI, binding)
-    else
-        for (BindingURI* b = bindingURIs(); b; b = b->next()) {
-            if (!b->next())
-                b->setNext(binding);
-        }
+    if (scale == 1)
+        return;
+    TransformOperations transform;
+    transform.operations().append(ScaleTransformOperation::create(scale, scale, ScaleTransformOperation::SCALE));
+    setTransform(transform);
+    setTransformOriginX(Length(0, Fixed));
+    setTransformOriginY(Length(0, Fixed));
 }
-#endif
 
 void RenderStyle::setTextShadow(ShadowData* val, bool add)
 {
@@ -735,18 +732,12 @@ void RenderStyle::setBoxShadow(ShadowData* shadowData, bool add)
         return;
     }
 
-    shadowData->setNext(rareData->m_boxShadow.release());
+    shadowData->setNext(rareData->m_boxShadow.leakPtr());
     rareData->m_boxShadow.set(shadowData);
 }
 
-void RenderStyle::getBorderRadiiForRect(const IntRect& r, IntSize& topLeft, IntSize& topRight, IntSize& bottomLeft, IntSize& bottomRight) const
+static void constrainCornerRadiiForRect(const IntRect& r, IntSize& topLeft, IntSize& topRight, IntSize& bottomLeft, IntSize& bottomRight)
 {
-    topLeft = surround->border.topLeft();
-    topRight = surround->border.topRight();
-    
-    bottomLeft = surround->border.bottomLeft();
-    bottomRight = surround->border.bottomRight();
-
     // Constrain corner radii using CSS3 rules:
     // http://www.w3.org/TR/css3-background/#the-border-radius
     
@@ -791,6 +782,40 @@ void RenderStyle::getBorderRadiiForRect(const IntRect& r, IntSize& topLeft, IntS
     }
 }
 
+void RenderStyle::getBorderRadiiForRect(const IntRect& r, IntSize& topLeft, IntSize& topRight, IntSize& bottomLeft, IntSize& bottomRight) const
+{
+    topLeft = IntSize(surround->border.topLeft().width().calcValue(r.width()), surround->border.topLeft().height().calcValue(r.height()));
+    topRight = IntSize(surround->border.topRight().width().calcValue(r.width()), surround->border.topRight().height().calcValue(r.height()));
+    
+    bottomLeft = IntSize(surround->border.bottomLeft().width().calcValue(r.width()), surround->border.bottomLeft().height().calcValue(r.height()));
+    bottomRight = IntSize(surround->border.bottomRight().width().calcValue(r.width()), surround->border.bottomRight().height().calcValue(r.height()));
+
+    constrainCornerRadiiForRect(r, topLeft, topRight, bottomLeft, bottomRight);
+}
+
+void RenderStyle::getInnerBorderRadiiForRectWithBorderWidths(const IntRect& innerRect, unsigned short topWidth, unsigned short bottomWidth, unsigned short leftWidth, unsigned short rightWidth, IntSize& innerTopLeft, IntSize& innerTopRight, IntSize& innerBottomLeft, IntSize& innerBottomRight) const
+{
+    innerTopLeft = IntSize(surround->border.topLeft().width().calcValue(innerRect.width()), surround->border.topLeft().height().calcValue(innerRect.height()));
+    innerTopRight = IntSize(surround->border.topRight().width().calcValue(innerRect.width()), surround->border.topRight().height().calcValue(innerRect.height()));
+    innerBottomLeft = IntSize(surround->border.bottomLeft().width().calcValue(innerRect.width()), surround->border.bottomLeft().height().calcValue(innerRect.height()));
+    innerBottomRight = IntSize(surround->border.bottomRight().width().calcValue(innerRect.width()), surround->border.bottomRight().height().calcValue(innerRect.height()));
+
+
+    innerTopLeft.setWidth(max(0, innerTopLeft.width() - leftWidth));
+    innerTopLeft.setHeight(max(0, innerTopLeft.height() - topWidth));
+
+    innerTopRight.setWidth(max(0, innerTopRight.width() - rightWidth));
+    innerTopRight.setHeight(max(0, innerTopRight.height() - topWidth));
+
+    innerBottomLeft.setWidth(max(0, innerBottomLeft.width() - leftWidth));
+    innerBottomLeft.setHeight(max(0, innerBottomLeft.height() - bottomWidth));
+
+    innerBottomRight.setWidth(max(0, innerBottomRight.width() - rightWidth));
+    innerBottomRight.setHeight(max(0, innerBottomRight.height() - bottomWidth));
+
+    constrainCornerRadiiForRect(innerRect, innerTopLeft, innerTopRight, innerBottomLeft, innerBottomRight);
+}
+
 const CounterDirectiveMap* RenderStyle::counterDirectives() const
 {
     return rareNonInheritedData->m_counterDirectives.get();
@@ -804,6 +829,19 @@ CounterDirectiveMap& RenderStyle::accessCounterDirectives()
     return *map.get();
 }
 
+const AtomicString& RenderStyle::hyphenString() const
+{
+    ASSERT(hyphens() != HyphensNone);
+
+    const AtomicString& hyphenationString = rareInheritedData.get()->hyphenationString;
+    if (!hyphenationString.isNull())
+        return hyphenationString;
+
+    // FIXME: This should depend on locale.
+    DEFINE_STATIC_LOCAL(AtomicString, hyphenMinusString, (&hyphen, 1));
+    return hyphenMinusString;
+}
+
 #if ENABLE(DASHBOARD_SUPPORT)
 const Vector<StyleDashboardRegion>& RenderStyle::initialDashboardRegions()
 {
@@ -918,59 +956,60 @@ const Animation* RenderStyle::transitionForProperty(int property) const
 
 void RenderStyle::setBlendedFontSize(int size)
 {
+    FontSelector* currentFontSelector = font().fontSelector();
     FontDescription desc(fontDescription());
     desc.setSpecifiedSize(size);
     desc.setComputedSize(size);
     setFontDescription(desc);
-    font().update(font().fontSelector());
+    font().update(currentFontSelector);
 }
 
-void RenderStyle::getBoxShadowExtent(int &top, int &right, int &bottom, int &left) const
+void RenderStyle::getShadowExtent(const ShadowData* shadow, int &top, int &right, int &bottom, int &left) const
 {
     top = 0;
     right = 0;
     bottom = 0;
     left = 0;
 
-    for (const ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next()) {
-        if (boxShadow->style() == Inset)
+    for ( ; shadow; shadow = shadow->next()) {
+        if (shadow->style() == Inset)
             continue;
-        int blurAndSpread = boxShadow->blur() + boxShadow->spread();
+        int blurAndSpread = shadow->blur() + shadow->spread();
 
-        top = min(top, boxShadow->y() - blurAndSpread);
-        right = max(right, boxShadow->x() + blurAndSpread);
-        bottom = max(bottom, boxShadow->y() + blurAndSpread);
-        left = min(left, boxShadow->x() - blurAndSpread);
+        top = min(top, shadow->y() - blurAndSpread);
+        right = max(right, shadow->x() + blurAndSpread);
+        bottom = max(bottom, shadow->y() + blurAndSpread);
+        left = min(left, shadow->x() - blurAndSpread);
     }
 }
 
-void RenderStyle::getBoxShadowHorizontalExtent(int &left, int &right) const
+void RenderStyle::getShadowHorizontalExtent(const ShadowData* shadow, int &left, int &right) const
 {
     left = 0;
     right = 0;
 
-    for (const ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next()) {
-        if (boxShadow->style() == Inset)
+    for ( ; shadow; shadow = shadow->next()) {
+        if (shadow->style() == Inset)
             continue;
-        int blurAndSpread = boxShadow->blur() + boxShadow->spread();
+        int blurAndSpread = shadow->blur() + shadow->spread();
 
-        left = min(left, boxShadow->x() - blurAndSpread);
-        right = max(right, boxShadow->x() + blurAndSpread);
+        left = min(left, shadow->x() - blurAndSpread);
+        right = max(right, shadow->x() + blurAndSpread);
     }
 }
 
-void RenderStyle::getBoxShadowVerticalExtent(int &top, int &bottom) const
+void RenderStyle::getShadowVerticalExtent(const ShadowData* shadow, int &top, int &bottom) const
 {
     top = 0;
     bottom = 0;
 
-    for (const ShadowData* boxShadow = this->boxShadow(); boxShadow; boxShadow = boxShadow->next()) {
-        if (boxShadow->style() == Inset)
+    for ( ; shadow; shadow = shadow->next()) {
+        if (shadow->style() == Inset)
             continue;
-        int blurAndSpread = boxShadow->blur() + boxShadow->spread();
+        int blurAndSpread = shadow->blur() + shadow->spread();
 
-        top = min(top, boxShadow->y() - blurAndSpread);
-        bottom = max(bottom, boxShadow->y() + blurAndSpread);
+        top = min(top, shadow->y() - blurAndSpread);
+        bottom = max(bottom, shadow->y() + blurAndSpread);
     }
 }
 
@@ -997,45 +1036,44 @@ static EBorderStyle borderStyleForColorProperty(const RenderStyle* style, int co
     return borderStyle;
 }
 
-static Color colorIncludingFallback(const RenderStyle* style, int colorProperty, EBorderStyle borderStyle)
+const Color RenderStyle::colorIncludingFallback(int colorProperty, EBorderStyle borderStyle) const
 {
     Color result;
     switch (colorProperty) {
     case CSSPropertyBackgroundColor:
-        return style->backgroundColor(); // Background color doesn't fall back.
+        return backgroundColor(); // Background color doesn't fall back.
     case CSSPropertyBorderLeftColor:
-        result = style->borderLeftColor();
-        borderStyle = style->borderLeftStyle();
+        result = borderLeftColor();
+        borderStyle = borderLeftStyle();
         break;
     case CSSPropertyBorderRightColor:
-        result = style->borderRightColor();
-        borderStyle = style->borderRightStyle();
+        result = borderRightColor();
+        borderStyle = borderRightStyle();
         break;
     case CSSPropertyBorderTopColor:
-        result = style->borderTopColor();
-        borderStyle = style->borderTopStyle();
+        result = borderTopColor();
+        borderStyle = borderTopStyle();
         break;
     case CSSPropertyBorderBottomColor:
-        result = style->borderBottomColor();
-        borderStyle = style->borderBottomStyle();
+        result = borderBottomColor();
+        borderStyle = borderBottomStyle();
         break;
     case CSSPropertyColor:
-        result = style->color();
+        result = color();
         break;
     case CSSPropertyOutlineColor:
-        result = style->outlineColor();
+        result = outlineColor();
         break;
     case CSSPropertyWebkitColumnRuleColor:
-        result = style->columnRuleColor();
+        result = columnRuleColor();
         break;
     case CSSPropertyWebkitTextFillColor:
-        result = style->textFillColor();
+        result = textFillColor();
         break;
     case CSSPropertyWebkitTextStrokeColor:
-        result = style->textStrokeColor();
+        result = textStrokeColor();
         break;
     default:
-        // FIXME: Add SVG fill and stroke.
         ASSERT_NOT_REACHED();
         break;
     }
@@ -1046,26 +1084,298 @@ static Color colorIncludingFallback(const RenderStyle* style, int colorProperty,
             && (borderStyle == INSET || borderStyle == OUTSET || borderStyle == RIDGE || borderStyle == GROOVE))
             result.setRGB(238, 238, 238);
         else
-            result = style->color();
+            result = color();
     }
 
     return result;
 }
 
-Color RenderStyle::visitedDependentColor(int colorProperty) const
+const Color RenderStyle::visitedDependentColor(int colorProperty) const
 {
     EBorderStyle borderStyle = borderStyleForColorProperty(this, colorProperty);
-    Color unvisitedColor = colorIncludingFallback(this, colorProperty, borderStyle);
+    Color unvisitedColor = colorIncludingFallback(colorProperty, borderStyle);
     if (insideLink() != InsideVisitedLink)
         return unvisitedColor;
 
     RenderStyle* visitedStyle = getCachedPseudoStyle(VISITED_LINK);
     if (!visitedStyle)
         return unvisitedColor;
-    Color visitedColor = colorIncludingFallback(visitedStyle, colorProperty, borderStyle);
+    Color visitedColor = visitedStyle->colorIncludingFallback(colorProperty, borderStyle);
 
     // Take the alpha from the unvisited color, but get the RGB values from the visited color.
     return Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), unvisitedColor.alpha());
 }
 
+Length RenderStyle::logicalWidth() const
+{
+    if (isHorizontalWritingMode())
+        return width();
+    return height();
+}
+
+Length RenderStyle::logicalHeight() const
+{
+    if (isHorizontalWritingMode())
+        return height();
+    return width();
+}
+
+Length RenderStyle::logicalMinWidth() const
+{
+    if (isHorizontalWritingMode())
+        return minWidth();
+    return minHeight();
+}
+
+Length RenderStyle::logicalMaxWidth() const
+{
+    if (isHorizontalWritingMode())
+        return maxWidth();
+    return maxHeight();
+}
+
+Length RenderStyle::logicalMinHeight() const
+{
+    if (isHorizontalWritingMode())
+        return minHeight();
+    return minWidth();
+}
+
+Length RenderStyle::logicalMaxHeight() const
+{
+    if (isHorizontalWritingMode())
+        return maxHeight();
+    return maxWidth();
+}
+
+const BorderValue& RenderStyle::borderBefore() const
+{
+    switch (writingMode()) {
+    case TopToBottomWritingMode:
+        return borderTop();
+    case BottomToTopWritingMode:
+        return borderBottom();
+    case LeftToRightWritingMode:
+        return borderLeft();
+    case RightToLeftWritingMode:
+        return borderRight();
+    }
+    ASSERT_NOT_REACHED();
+    return borderTop();
+}
+
+const BorderValue& RenderStyle::borderAfter() const
+{
+    switch (writingMode()) {
+    case TopToBottomWritingMode:
+        return borderBottom();
+    case BottomToTopWritingMode:
+        return borderTop();
+    case LeftToRightWritingMode:
+        return borderRight();
+    case RightToLeftWritingMode:
+        return borderLeft();
+    }
+    ASSERT_NOT_REACHED();
+    return borderBottom();
+}
+
+const BorderValue& RenderStyle::borderStart() const
+{
+    if (isHorizontalWritingMode())
+        return isLeftToRightDirection() ? borderLeft() : borderRight();
+    return isLeftToRightDirection() ? borderTop() : borderBottom();
+}
+
+const BorderValue& RenderStyle::borderEnd() const
+{
+    if (isHorizontalWritingMode())
+        return isLeftToRightDirection() ? borderRight() : borderLeft();
+    return isLeftToRightDirection() ? borderBottom() : borderTop();
+}
+
+unsigned short RenderStyle::borderBeforeWidth() const
+{
+    switch (writingMode()) {
+    case TopToBottomWritingMode:
+        return borderTopWidth();
+    case BottomToTopWritingMode:
+        return borderBottomWidth();
+    case LeftToRightWritingMode:
+        return borderLeftWidth();
+    case RightToLeftWritingMode:
+        return borderRightWidth();
+    }
+    ASSERT_NOT_REACHED();
+    return borderTopWidth();
+}
+
+unsigned short RenderStyle::borderAfterWidth() const
+{
+    switch (writingMode()) {
+    case TopToBottomWritingMode:
+        return borderBottomWidth();
+    case BottomToTopWritingMode:
+        return borderTopWidth();
+    case LeftToRightWritingMode:
+        return borderRightWidth();
+    case RightToLeftWritingMode:
+        return borderLeftWidth();
+    }
+    ASSERT_NOT_REACHED();
+    return borderBottomWidth();
+}
+
+unsigned short RenderStyle::borderStartWidth() const
+{
+    if (isHorizontalWritingMode())
+        return isLeftToRightDirection() ? borderLeftWidth() : borderRightWidth();
+    return isLeftToRightDirection() ? borderTopWidth() : borderBottomWidth();
+}
+
+unsigned short RenderStyle::borderEndWidth() const
+{
+    if (isHorizontalWritingMode())
+        return isLeftToRightDirection() ? borderRightWidth() : borderLeftWidth();
+    return isLeftToRightDirection() ? borderBottomWidth() : borderTopWidth();
+}
+    
+Length RenderStyle::marginBefore() const
+{
+    switch (writingMode()) {
+    case TopToBottomWritingMode:
+        return marginTop();
+    case BottomToTopWritingMode:
+        return marginBottom();
+    case LeftToRightWritingMode:
+        return marginLeft();
+    case RightToLeftWritingMode:
+        return marginRight();
+    }
+    ASSERT_NOT_REACHED();
+    return marginTop();
+}
+
+Length RenderStyle::marginAfter() const
+{
+    switch (writingMode()) {
+    case TopToBottomWritingMode:
+        return marginBottom();
+    case BottomToTopWritingMode:
+        return marginTop();
+    case LeftToRightWritingMode:
+        return marginRight();
+    case RightToLeftWritingMode:
+        return marginLeft();
+    }
+    ASSERT_NOT_REACHED();
+    return marginBottom();
+}
+
+Length RenderStyle::marginBeforeUsing(const RenderStyle* otherStyle) const
+{
+    switch (otherStyle->writingMode()) {
+    case TopToBottomWritingMode:
+        return marginTop();
+    case BottomToTopWritingMode:
+        return marginBottom();
+    case LeftToRightWritingMode:
+        return marginLeft();
+    case RightToLeftWritingMode:
+        return marginRight();
+    }
+    ASSERT_NOT_REACHED();
+    return marginTop();
+}
+
+Length RenderStyle::marginAfterUsing(const RenderStyle* otherStyle) const
+{
+    switch (otherStyle->writingMode()) {
+    case TopToBottomWritingMode:
+        return marginBottom();
+    case BottomToTopWritingMode:
+        return marginTop();
+    case LeftToRightWritingMode:
+        return marginRight();
+    case RightToLeftWritingMode:
+        return marginLeft();
+    }
+    ASSERT_NOT_REACHED();
+    return marginBottom();
+}
+
+Length RenderStyle::marginStart() const
+{
+    if (isHorizontalWritingMode())
+        return isLeftToRightDirection() ? marginLeft() : marginRight();
+    return isLeftToRightDirection() ? marginTop() : marginBottom();
+}
+
+Length RenderStyle::marginEnd() const
+{
+    if (isHorizontalWritingMode())
+        return isLeftToRightDirection() ? marginRight() : marginLeft();
+    return isLeftToRightDirection() ? marginBottom() : marginTop();
+}
+    
+Length RenderStyle::marginStartUsing(const RenderStyle* otherStyle) const
+{
+    if (otherStyle->isHorizontalWritingMode())
+        return otherStyle->isLeftToRightDirection() ? marginLeft() : marginRight();
+    return otherStyle->isLeftToRightDirection() ? marginTop() : marginBottom();
+}
+
+Length RenderStyle::marginEndUsing(const RenderStyle* otherStyle) const
+{
+    if (otherStyle->isHorizontalWritingMode())
+        return otherStyle->isLeftToRightDirection() ? marginRight() : marginLeft();
+    return otherStyle->isLeftToRightDirection() ? marginBottom() : marginTop();
+}
+
+Length RenderStyle::paddingBefore() const
+{
+    switch (writingMode()) {
+    case TopToBottomWritingMode:
+        return paddingTop();
+    case BottomToTopWritingMode:
+        return paddingBottom();
+    case LeftToRightWritingMode:
+        return paddingLeft();
+    case RightToLeftWritingMode:
+        return paddingRight();
+    }
+    ASSERT_NOT_REACHED();
+    return paddingTop();
+}
+
+Length RenderStyle::paddingAfter() const
+{
+    switch (writingMode()) {
+    case TopToBottomWritingMode:
+        return paddingBottom();
+    case BottomToTopWritingMode:
+        return paddingTop();
+    case LeftToRightWritingMode:
+        return paddingRight();
+    case RightToLeftWritingMode:
+        return paddingLeft();
+    }
+    ASSERT_NOT_REACHED();
+    return paddingBottom();
+}
+
+Length RenderStyle::paddingStart() const
+{
+    if (isHorizontalWritingMode())
+        return isLeftToRightDirection() ? paddingLeft() : paddingRight();
+    return isLeftToRightDirection() ? paddingTop() : paddingBottom();
+}
+
+Length RenderStyle::paddingEnd() const
+{
+    if (isHorizontalWritingMode())
+        return isLeftToRightDirection() ? paddingRight() : paddingLeft();
+    return isLeftToRightDirection() ? paddingBottom() : paddingTop();
+}
+
 } // namespace WebCore