Home | History | Annotate | Download | only in css
      1 /**
      2  * (C) 1999-2003 Lars Knoll (knoll (at) kde.org)
      3  * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Library General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2 of the License, or (at your option) any later version.
      9  *
     10  * This library is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * Library General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Library General Public License
     16  * along with this library; see the file COPYING.LIB.  If not, write to
     17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18  * Boston, MA 02110-1301, USA.
     19  */
     20 
     21 #include "config.h"
     22 #include "CSSProperty.h"
     23 
     24 #include "CSSPropertyNames.h"
     25 #include "PlatformString.h"
     26 #include "RenderStyleConstants.h"
     27 
     28 namespace WebCore {
     29 
     30 String CSSProperty::cssText() const
     31 {
     32     return String(getPropertyName(static_cast<CSSPropertyID>(id()))) + ": " + m_value->cssText() + (isImportant() ? " !important" : "") + "; ";
     33 }
     34 
     35 bool operator==(const CSSProperty& a, const CSSProperty& b)
     36 {
     37     return a.m_id == b.m_id && a.m_important == b.m_important && a.m_value == b.m_value;
     38 }
     39 
     40 enum LogicalBoxSide { BeforeSide, EndSide, AfterSide, StartSide };
     41 enum PhysicalBoxSide { TopSide, RightSide, BottomSide, LeftSide };
     42 
     43 static int resolveToPhysicalProperty(TextDirection direction, WritingMode writingMode, LogicalBoxSide logicalSide, const int* properties)
     44 {
     45     if (direction == LTR) {
     46         if (writingMode == TopToBottomWritingMode) {
     47             // The common case. The logical and physical box sides match.
     48             // Left = Start, Right = End, Before = Top, After = Bottom
     49             return properties[logicalSide];
     50         }
     51 
     52         if (writingMode == BottomToTopWritingMode) {
     53             // Start = Left, End = Right, Before = Bottom, After = Top.
     54             switch (logicalSide) {
     55             case StartSide:
     56                 return properties[LeftSide];
     57             case EndSide:
     58                 return properties[RightSide];
     59             case BeforeSide:
     60                 return properties[BottomSide];
     61             default:
     62                 return properties[TopSide];
     63             }
     64         }
     65 
     66         if (writingMode == LeftToRightWritingMode) {
     67             // Start = Top, End = Bottom, Before = Left, After = Right.
     68             switch (logicalSide) {
     69             case StartSide:
     70                 return properties[TopSide];
     71             case EndSide:
     72                 return properties[BottomSide];
     73             case BeforeSide:
     74                 return properties[LeftSide];
     75             default:
     76                 return properties[RightSide];
     77             }
     78         }
     79 
     80         // Start = Top, End = Bottom, Before = Right, After = Left
     81         switch (logicalSide) {
     82         case StartSide:
     83             return properties[TopSide];
     84         case EndSide:
     85             return properties[BottomSide];
     86         case BeforeSide:
     87             return properties[RightSide];
     88         default:
     89             return properties[LeftSide];
     90         }
     91     }
     92 
     93     if (writingMode == TopToBottomWritingMode) {
     94         // Start = Right, End = Left, Before = Top, After = Bottom
     95         switch (logicalSide) {
     96         case StartSide:
     97             return properties[RightSide];
     98         case EndSide:
     99             return properties[LeftSide];
    100         case BeforeSide:
    101             return properties[TopSide];
    102         default:
    103             return properties[BottomSide];
    104         }
    105     }
    106 
    107     if (writingMode == BottomToTopWritingMode) {
    108         // Start = Right, End = Left, Before = Bottom, After = Top
    109         switch (logicalSide) {
    110         case StartSide:
    111             return properties[RightSide];
    112         case EndSide:
    113             return properties[LeftSide];
    114         case BeforeSide:
    115             return properties[BottomSide];
    116         default:
    117             return properties[TopSide];
    118         }
    119     }
    120 
    121     if (writingMode == LeftToRightWritingMode) {
    122         // Start = Bottom, End = Top, Before = Left, After = Right
    123         switch (logicalSide) {
    124         case StartSide:
    125             return properties[BottomSide];
    126         case EndSide:
    127             return properties[TopSide];
    128         case BeforeSide:
    129             return properties[LeftSide];
    130         default:
    131             return properties[RightSide];
    132         }
    133     }
    134 
    135     // Start = Bottom, End = Top, Before = Right, After = Left
    136     switch (logicalSide) {
    137     case StartSide:
    138         return properties[BottomSide];
    139     case EndSide:
    140         return properties[TopSide];
    141     case BeforeSide:
    142         return properties[RightSide];
    143     default:
    144         return properties[LeftSide];
    145     }
    146 }
    147 
    148 enum LogicalExtent { LogicalWidth, LogicalHeight };
    149 
    150 static int resolveToPhysicalProperty(WritingMode writingMode, LogicalExtent logicalSide, const int* properties)
    151 {
    152     if (writingMode == TopToBottomWritingMode || writingMode == BottomToTopWritingMode)
    153         return properties[logicalSide];
    154     return logicalSide == LogicalWidth ? properties[1] : properties[0];
    155 }
    156 
    157 int CSSProperty::resolveDirectionAwareProperty(int propertyID, TextDirection direction, WritingMode writingMode)
    158 {
    159     switch (static_cast<CSSPropertyID>(propertyID)) {
    160     case CSSPropertyWebkitMarginEnd: {
    161         const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft };
    162         return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
    163     }
    164     case CSSPropertyWebkitMarginStart: {
    165         const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft };
    166         return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
    167     }
    168     case CSSPropertyWebkitMarginBefore: {
    169         const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft };
    170         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
    171     }
    172     case CSSPropertyWebkitMarginAfter: {
    173         const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft };
    174         return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
    175     }
    176     case CSSPropertyWebkitPaddingEnd: {
    177         const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft };
    178         return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
    179     }
    180     case CSSPropertyWebkitPaddingStart: {
    181         const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft };
    182         return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
    183     }
    184     case CSSPropertyWebkitPaddingBefore: {
    185         const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft };
    186         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
    187     }
    188     case CSSPropertyWebkitPaddingAfter: {
    189         const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft };
    190         return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
    191     }
    192     case CSSPropertyWebkitBorderEnd: {
    193         const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
    194         return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
    195     }
    196     case CSSPropertyWebkitBorderStart: {
    197         const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
    198         return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
    199     }
    200     case CSSPropertyWebkitBorderBefore: {
    201         const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
    202         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
    203     }
    204     case CSSPropertyWebkitBorderAfter: {
    205         const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
    206         return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
    207     }
    208     case CSSPropertyWebkitBorderEndColor: {
    209         const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor };
    210         return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
    211     }
    212     case CSSPropertyWebkitBorderStartColor: {
    213         const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor };
    214         return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
    215     }
    216     case CSSPropertyWebkitBorderBeforeColor: {
    217         const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor };
    218         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
    219     }
    220     case CSSPropertyWebkitBorderAfterColor: {
    221         const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor };
    222         return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
    223     }
    224     case CSSPropertyWebkitBorderEndStyle: {
    225         const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle };
    226         return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
    227     }
    228     case CSSPropertyWebkitBorderStartStyle: {
    229         const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle };
    230         return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
    231     }
    232     case CSSPropertyWebkitBorderBeforeStyle: {
    233         const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle };
    234         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
    235     }
    236     case CSSPropertyWebkitBorderAfterStyle: {
    237         const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle };
    238         return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
    239     }
    240     case CSSPropertyWebkitBorderEndWidth: {
    241         const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth };
    242         return resolveToPhysicalProperty(direction, writingMode, EndSide, properties);
    243     }
    244     case CSSPropertyWebkitBorderStartWidth: {
    245         const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth };
    246         return resolveToPhysicalProperty(direction, writingMode, StartSide, properties);
    247     }
    248     case CSSPropertyWebkitBorderBeforeWidth: {
    249         const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth };
    250         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties);
    251     }
    252     case CSSPropertyWebkitBorderAfterWidth: {
    253         const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth };
    254         return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties);
    255     }
    256     case CSSPropertyWebkitLogicalWidth: {
    257         const int properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
    258         return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
    259     }
    260     case CSSPropertyWebkitLogicalHeight: {
    261         const int properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
    262         return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
    263     }
    264     case CSSPropertyWebkitMinLogicalWidth: {
    265         const int properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
    266         return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
    267     }
    268     case CSSPropertyWebkitMinLogicalHeight: {
    269         const int properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
    270         return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
    271     }
    272     case CSSPropertyWebkitMaxLogicalWidth: {
    273         const int properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
    274         return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
    275     }
    276     case CSSPropertyWebkitMaxLogicalHeight: {
    277         const int properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
    278         return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
    279     }
    280     default:
    281         return propertyID;
    282     }
    283 }
    284 
    285 } // namespace WebCore
    286