Home | History | Annotate | Download | only in css
      1 /*
      2  * (C) 1999-2003 Lars Knoll (knoll (at) kde.org)
      3  * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
      4  * Copyright (C) 2007 Alexey Proskuryakov <ap (at) webkit.org>
      5  *
      6  * This library is free software; you can redistribute it and/or
      7  * modify it under the terms of the GNU Library General Public
      8  * License as published by the Free Software Foundation; either
      9  * version 2 of the License, or (at your option) any later version.
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Library General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU Library General Public License
     17  * along with this library; see the file COPYING.LIB.  If not, write to
     18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     19  * Boston, MA 02110-1301, USA.
     20  */
     21 
     22 #ifndef CSSPrimitiveValue_h
     23 #define CSSPrimitiveValue_h
     24 
     25 #include "CSSValue.h"
     26 #include "Color.h"
     27 #include <wtf/Forward.h>
     28 #include <wtf/PassRefPtr.h>
     29 
     30 namespace WebCore {
     31 
     32 class Counter;
     33 class DashboardRegion;
     34 class Pair;
     35 class RGBColor;
     36 class Rect;
     37 class RenderStyle;
     38 
     39 struct Length;
     40 
     41 template<typename T, T max, T min> inline T roundForImpreciseConversion(double value)
     42 {
     43     // Dimension calculations are imprecise, often resulting in values of e.g.
     44     // 44.99998.  We need to go ahead and round if we're really close to the
     45     // next integer value.
     46     value += (value < 0) ? -0.01 : +0.01;
     47     return ((value > max) || (value < min)) ? 0 : static_cast<T>(value);
     48 }
     49 
     50 class CSSPrimitiveValue : public CSSValue {
     51 public:
     52     enum UnitTypes {
     53         CSS_UNKNOWN = 0,
     54         CSS_NUMBER = 1,
     55         CSS_PERCENTAGE = 2,
     56         CSS_EMS = 3,
     57         CSS_EXS = 4,
     58         CSS_PX = 5,
     59         CSS_CM = 6,
     60         CSS_MM = 7,
     61         CSS_IN = 8,
     62         CSS_PT = 9,
     63         CSS_PC = 10,
     64         CSS_DEG = 11,
     65         CSS_RAD = 12,
     66         CSS_GRAD = 13,
     67         CSS_MS = 14,
     68         CSS_S = 15,
     69         CSS_HZ = 16,
     70         CSS_KHZ = 17,
     71         CSS_DIMENSION = 18,
     72         CSS_STRING = 19,
     73         CSS_URI = 20,
     74         CSS_IDENT = 21,
     75         CSS_ATTR = 22,
     76         CSS_COUNTER = 23,
     77         CSS_RECT = 24,
     78         CSS_RGBCOLOR = 25,
     79         CSS_PAIR = 100, // We envision this being exposed as a means of getting computed style values for pairs (border-spacing/radius, background-position, etc.)
     80         CSS_DASHBOARD_REGION = 101, // FIXME: Dashboard region should not be a primitive value.
     81         CSS_UNICODE_RANGE = 102,
     82 
     83         // These next types are just used internally to allow us to translate back and forth from CSSPrimitiveValues to CSSParserValues.
     84         CSS_PARSER_OPERATOR = 103,
     85         CSS_PARSER_INTEGER = 104,
     86         CSS_PARSER_HEXCOLOR = 105,
     87 
     88         // This is used internally for unknown identifiers
     89         CSS_PARSER_IDENTIFIER = 106,
     90 
     91         // These are from CSS3 Values and Units, but that isn't a finished standard yet
     92         CSS_TURN = 107,
     93         CSS_REMS = 108,
     94 
     95         // This is used internally for counter names (as opposed to counter values)
     96         CSS_COUNTER_NAME = 109
     97     };
     98 
     99     // This enum follows the CSSParser::Units enum augmented with UNIT_FREQUENCY for frequencies.
    100     enum UnitCategory {
    101         UNumber,
    102         UPercent,
    103         ULength,
    104         UAngle,
    105         UTime,
    106         UFrequency,
    107         UOther
    108     };
    109 
    110     static bool isUnitTypeLength(int type) { return (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) ||
    111                                                     type == CSSPrimitiveValue::CSS_REMS; }
    112 
    113     static PassRefPtr<CSSPrimitiveValue> createIdentifier(int identifier) { return adoptRef(new CSSPrimitiveValue(identifier)); }
    114     static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue) { return adoptRef(new CSSPrimitiveValue(rgbValue)); }
    115     static PassRefPtr<CSSPrimitiveValue> create(double value, UnitTypes type) { return adoptRef(new CSSPrimitiveValue(value, type)); }
    116     static PassRefPtr<CSSPrimitiveValue> create(const String& value, UnitTypes type) { return adoptRef(new CSSPrimitiveValue(value, type)); }
    117 
    118     template<typename T> static PassRefPtr<CSSPrimitiveValue> create(T value)
    119     {
    120         return adoptRef(new CSSPrimitiveValue(value));
    121     }
    122 
    123     virtual ~CSSPrimitiveValue();
    124 
    125     void cleanup();
    126 
    127     unsigned short primitiveType() const { return m_type; }
    128 
    129     /*
    130      * computes a length in pixels out of the given CSSValue. Need the RenderStyle to get
    131      * the fontinfo in case val is defined in em or ex.
    132      *
    133      * The metrics have to be a bit different for screen and printer output.
    134      * For screen output we assume 1 inch == 72 px, for printer we assume 300 dpi
    135      *
    136      * this is screen/printer dependent, so we probably need a config option for this,
    137      * and some tool to calibrate.
    138      */
    139     int computeLengthInt(RenderStyle* currStyle, RenderStyle* rootStyle);
    140     int computeLengthInt(RenderStyle* currStyle, RenderStyle* rootStyle, double multiplier);
    141     int computeLengthIntForLength(RenderStyle* currStyle, RenderStyle* rootStyle);
    142     int computeLengthIntForLength(RenderStyle* currStyle, RenderStyle* rootStyle, double multiplier);
    143     short computeLengthShort(RenderStyle* currStyle, RenderStyle* rootStyle);
    144     short computeLengthShort(RenderStyle* currStyle, RenderStyle* rootStyle, double multiplier);
    145     float computeLengthFloat(RenderStyle* currStyle, RenderStyle* rootStyle, bool computingFontSize = false);
    146     float computeLengthFloat(RenderStyle* currStyle, RenderStyle* rootStyle, double multiplier, bool computingFontSize = false);
    147     double computeLengthDouble(RenderStyle* currentStyle, RenderStyle* rootStyle, double multiplier = 1.0, bool computingFontSize = false);
    148 
    149     // use with care!!!
    150     void setPrimitiveType(unsigned short type) { m_type = type; }
    151 
    152     double getDoubleValue(unsigned short unitType, ExceptionCode&) const;
    153     double getDoubleValue(unsigned short unitType) const;
    154     double getDoubleValue() const { return m_value.num; }
    155 
    156     void setFloatValue(unsigned short unitType, double floatValue, ExceptionCode&);
    157     float getFloatValue(unsigned short unitType, ExceptionCode& ec) const { return static_cast<float>(getDoubleValue(unitType, ec)); }
    158     float getFloatValue(unsigned short unitType) const { return static_cast<float>(getDoubleValue(unitType)); }
    159     float getFloatValue() const { return static_cast<float>(m_value.num); }
    160 
    161     int getIntValue(unsigned short unitType, ExceptionCode& ec) const { return static_cast<int>(getDoubleValue(unitType, ec)); }
    162     int getIntValue(unsigned short unitType) const { return static_cast<int>(getDoubleValue(unitType)); }
    163     int getIntValue() const { return static_cast<int>(m_value.num); }
    164 
    165     void setStringValue(unsigned short stringType, const String& stringValue, ExceptionCode&);
    166     String getStringValue(ExceptionCode&) const;
    167     String getStringValue() const;
    168 
    169     Counter* getCounterValue(ExceptionCode&) const;
    170     Counter* getCounterValue() const { return m_type != CSS_COUNTER ? 0 : m_value.counter; }
    171 
    172     Rect* getRectValue(ExceptionCode&) const;
    173     Rect* getRectValue() const { return m_type != CSS_RECT ? 0 : m_value.rect; }
    174 
    175     PassRefPtr<RGBColor> getRGBColorValue(ExceptionCode&) const;
    176     RGBA32 getRGBA32Value() const { return m_type != CSS_RGBCOLOR ? 0 : m_value.rgbcolor; }
    177 
    178     Pair* getPairValue(ExceptionCode&) const;
    179     Pair* getPairValue() const { return m_type != CSS_PAIR ? 0 : m_value.pair; }
    180 
    181     DashboardRegion* getDashboardRegionValue() const { return m_type != CSS_DASHBOARD_REGION ? 0 : m_value.region; }
    182 
    183     int getIdent() const;
    184     template<typename T> inline operator T() const; // Defined in CSSPrimitiveValueMappings.h
    185 
    186     virtual bool parseString(const String&, bool = false);
    187     virtual String cssText() const;
    188 
    189     virtual bool isQuirkValue() { return false; }
    190 
    191     virtual void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*);
    192 
    193 protected:
    194     // FIXME: int vs. unsigned overloading is too subtle to distinguish the color and identifier cases.
    195     CSSPrimitiveValue(int ident);
    196     CSSPrimitiveValue(double, UnitTypes);
    197     CSSPrimitiveValue(const String&, UnitTypes);
    198 
    199 private:
    200     CSSPrimitiveValue();
    201     CSSPrimitiveValue(unsigned color); // RGB value
    202     CSSPrimitiveValue(const Length&);
    203 
    204     template<typename T> CSSPrimitiveValue(T); // Defined in CSSPrimitiveValueMappings.h
    205     template<typename T> CSSPrimitiveValue(T* val) { init(PassRefPtr<T>(val)); }
    206     template<typename T> CSSPrimitiveValue(PassRefPtr<T> val) { init(val); }
    207 
    208     static void create(int); // compile-time guard
    209     static void create(unsigned); // compile-time guard
    210     template<typename T> operator T*(); // compile-time guard
    211 
    212     static PassRefPtr<CSSPrimitiveValue> createUncachedIdentifier(int identifier);
    213     static PassRefPtr<CSSPrimitiveValue> createUncachedColor(unsigned rgbValue);
    214     static PassRefPtr<CSSPrimitiveValue> createUncached(double value, UnitTypes type);
    215 
    216     static UnitTypes canonicalUnitTypeForCategory(UnitCategory category);
    217 
    218     void init(PassRefPtr<Counter>);
    219     void init(PassRefPtr<Rect>);
    220     void init(PassRefPtr<Pair>);
    221     void init(PassRefPtr<DashboardRegion>); // FIXME: Dashboard region should not be a primitive value.
    222     bool getDoubleValueInternal(UnitTypes targetUnitType, double* result) const;
    223 
    224     virtual bool isPrimitiveValue() const { return true; }
    225 
    226     virtual unsigned short cssValueType() const;
    227 
    228     int m_type : 31;
    229     mutable unsigned m_hasCachedCSSText : 1;
    230     union {
    231         int ident;
    232         double num;
    233         StringImpl* string;
    234         Counter* counter;
    235         Rect* rect;
    236         unsigned rgbcolor;
    237         Pair* pair;
    238         DashboardRegion* region;
    239     } m_value;
    240 };
    241 
    242 } // namespace WebCore
    243 
    244 #endif // CSSPrimitiveValue_h
    245