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