/*
* 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>
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 ||
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() ||
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;
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()))
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)
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)
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) ||
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) {
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()
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
}
}
-#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)
{
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
}
}
+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();
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()
{
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);
}
}
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;
}
&& (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