diff options
Diffstat (limited to 'Source/WebCore/css/CSSPrimitiveValue.cpp')
-rw-r--r-- | Source/WebCore/css/CSSPrimitiveValue.cpp | 471 |
1 files changed, 260 insertions, 211 deletions
diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp index f3902c7be..32f0121b6 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.cpp +++ b/Source/WebCore/css/CSSPrimitiveValue.cpp @@ -52,7 +52,7 @@ using namespace WTF; namespace WebCore { - + // Max/min values for CSS, needs to slightly smaller/larger than the true max/min values to allow for rounding without overflowing. // Subtract two (rather than one) to allow for values to be converted to float and back without exceeding the LayoutUnit::max. const int maxValueForCssLength = INT_MAX / kFixedPointDenominator - 2; @@ -132,46 +132,46 @@ static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::Unit return false; } -static CSSPrimitiveValue::UnitCategory unitCategory(CSSPrimitiveValue::UnitTypes type) +CSSPrimitiveValue::UnitCategory CSSPrimitiveValue::unitCategory(CSSPrimitiveValue::UnitTypes type) { // Here we violate the spec (http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSPrimitiveValue) and allow conversions // between CSS_PX and relative lengths (see cssPixelsPerInch comment in CSSHelper.h for the topic treatment). switch (type) { - case CSSPrimitiveValue::CSS_NUMBER: - return CSSPrimitiveValue::UNumber; - case CSSPrimitiveValue::CSS_PERCENTAGE: - return CSSPrimitiveValue::UPercent; - case CSSPrimitiveValue::CSS_PX: - case CSSPrimitiveValue::CSS_CM: - case CSSPrimitiveValue::CSS_MM: - case CSSPrimitiveValue::CSS_IN: - case CSSPrimitiveValue::CSS_PT: - case CSSPrimitiveValue::CSS_PC: - return CSSPrimitiveValue::ULength; - case CSSPrimitiveValue::CSS_MS: - case CSSPrimitiveValue::CSS_S: - return CSSPrimitiveValue::UTime; - case CSSPrimitiveValue::CSS_DEG: - case CSSPrimitiveValue::CSS_RAD: - case CSSPrimitiveValue::CSS_GRAD: - case CSSPrimitiveValue::CSS_TURN: - return CSSPrimitiveValue::UAngle; - case CSSPrimitiveValue::CSS_HZ: - case CSSPrimitiveValue::CSS_KHZ: - return CSSPrimitiveValue::UFrequency; - case CSSPrimitiveValue::CSS_VW: - case CSSPrimitiveValue::CSS_VH: - case CSSPrimitiveValue::CSS_VMIN: - case CSSPrimitiveValue::CSS_VMAX: - return CSSPrimitiveValue::UViewportPercentageLength; + case CSS_NUMBER: + return UNumber; + case CSS_PERCENTAGE: + return UPercent; + case CSS_PX: + case CSS_CM: + case CSS_MM: + case CSS_IN: + case CSS_PT: + case CSS_PC: + return ULength; + case CSS_MS: + case CSS_S: + return UTime; + case CSS_DEG: + case CSS_RAD: + case CSS_GRAD: + case CSS_TURN: + return UAngle; + case CSS_HZ: + case CSS_KHZ: + return UFrequency; + case CSS_VW: + case CSS_VH: + case CSS_VMIN: + case CSS_VMAX: + return UViewportPercentageLength; #if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY) - case CSSPrimitiveValue::CSS_DPPX: - case CSSPrimitiveValue::CSS_DPI: - case CSSPrimitiveValue::CSS_DPCM: - return CSSPrimitiveValue::UResolution; + case CSS_DPPX: + case CSS_DPI: + case CSS_DPCM: + return UResolution; #endif default: - return CSSPrimitiveValue::UOther; + return UOther; } } @@ -182,25 +182,31 @@ static CSSTextCache& cssTextCache() return cache; } -unsigned short CSSPrimitiveValue::primitiveType() const +unsigned short CSSPrimitiveValue::primitiveType() const { if (m_primitiveUnitType == CSS_PROPERTY_ID || m_primitiveUnitType == CSS_VALUE_ID) return CSS_IDENT; if (m_primitiveUnitType != CSSPrimitiveValue::CSS_CALC) - return m_primitiveUnitType; - + return m_primitiveUnitType; + switch (m_value.calc->category()) { case CalcNumber: return CSSPrimitiveValue::CSS_NUMBER; - case CalcPercent: - return CSSPrimitiveValue::CSS_PERCENTAGE; case CalcLength: return CSSPrimitiveValue::CSS_PX; + case CalcPercent: + return CSSPrimitiveValue::CSS_PERCENTAGE; case CalcPercentNumber: return CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER; case CalcPercentLength: return CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH; + case CalcAngle: + return CSSPrimitiveValue::CSS_DEG; + case CalcTime: + return CSSPrimitiveValue::CSS_MS; + case CalcFrequency: + return CSSPrimitiveValue::CSS_HZ; #if ENABLE(CSS_VARIABLES) case CalcVariable: return CSSPrimitiveValue::CSS_UNKNOWN; // The type of a calculation containing a variable cannot be known until the value of the variable is determined. @@ -285,65 +291,102 @@ CSSPrimitiveValue::CSSPrimitiveValue(RGBA32 color) CSSPrimitiveValue::CSSPrimitiveValue(const Length& length) : CSSValue(PrimitiveClass) { + init(length); +} + +CSSPrimitiveValue::CSSPrimitiveValue(const Length& length, const RenderStyle* style) + : CSSValue(PrimitiveClass) +{ switch (length.type()) { - case Auto: - m_primitiveUnitType = CSS_VALUE_ID; - m_value.valueID = CSSValueAuto; - break; - case WebCore::Fixed: - m_primitiveUnitType = CSS_PX; - m_value.num = length.value(); - break; - case Intrinsic: - m_primitiveUnitType = CSS_VALUE_ID; - m_value.valueID = CSSValueIntrinsic; - break; - case MinIntrinsic: - m_primitiveUnitType = CSS_VALUE_ID; - m_value.valueID = CSSValueMinIntrinsic; - break; - case MinContent: - m_primitiveUnitType = CSS_VALUE_ID; - m_value.valueID = CSSValueWebkitMinContent; - break; - case MaxContent: - m_primitiveUnitType = CSS_VALUE_ID; - m_value.valueID = CSSValueWebkitMaxContent; - break; - case FillAvailable: - m_primitiveUnitType = CSS_VALUE_ID; - m_value.valueID = CSSValueWebkitFillAvailable; - break; - case FitContent: - m_primitiveUnitType = CSS_VALUE_ID; - m_value.valueID = CSSValueWebkitFitContent; - break; - case Percent: - m_primitiveUnitType = CSS_PERCENTAGE; - ASSERT(std::isfinite(length.percent())); - m_value.num = length.percent(); - break; - case ViewportPercentageWidth: - m_primitiveUnitType = CSS_VW; - m_value.num = length.viewportPercentageLength(); - break; - case ViewportPercentageHeight: - m_primitiveUnitType = CSS_VH; - m_value.num = length.viewportPercentageLength(); - break; - case ViewportPercentageMin: - m_primitiveUnitType = CSS_VMIN; - m_value.num = length.viewportPercentageLength(); - break; - case ViewportPercentageMax: - m_primitiveUnitType = CSS_VMAX; - m_value.num = length.viewportPercentageLength(); - break; - case Calculated: - case Relative: - case Undefined: - ASSERT_NOT_REACHED(); - break; + case Auto: + case Intrinsic: + case MinIntrinsic: + case MinContent: + case MaxContent: + case FillAvailable: + case FitContent: + case Percent: + case ViewportPercentageWidth: + case ViewportPercentageHeight: + case ViewportPercentageMin: + case ViewportPercentageMax: + init(length); + return; + case Fixed: + m_primitiveUnitType = CSS_PX; + m_value.num = adjustFloatForAbsoluteZoom(length.value(), style); + return; + case Calculated: + init(CSSCalcValue::create(length.calculationValue().get(), style)); + return; + case Relative: + case Undefined: + ASSERT_NOT_REACHED(); + break; + } +} + +void CSSPrimitiveValue::init(const Length& length) +{ + switch (length.type()) { + case Auto: + m_primitiveUnitType = CSS_VALUE_ID; + m_value.valueID = CSSValueAuto; + break; + case WebCore::Fixed: + m_primitiveUnitType = CSS_PX; + m_value.num = length.value(); + break; + case Intrinsic: + m_primitiveUnitType = CSS_VALUE_ID; + m_value.valueID = CSSValueIntrinsic; + break; + case MinIntrinsic: + m_primitiveUnitType = CSS_VALUE_ID; + m_value.valueID = CSSValueMinIntrinsic; + break; + case MinContent: + m_primitiveUnitType = CSS_VALUE_ID; + m_value.valueID = CSSValueWebkitMinContent; + break; + case MaxContent: + m_primitiveUnitType = CSS_VALUE_ID; + m_value.valueID = CSSValueWebkitMaxContent; + break; + case FillAvailable: + m_primitiveUnitType = CSS_VALUE_ID; + m_value.valueID = CSSValueWebkitFillAvailable; + break; + case FitContent: + m_primitiveUnitType = CSS_VALUE_ID; + m_value.valueID = CSSValueWebkitFitContent; + break; + case Percent: + m_primitiveUnitType = CSS_PERCENTAGE; + ASSERT(std::isfinite(length.percent())); + m_value.num = length.percent(); + break; + case ViewportPercentageWidth: + m_primitiveUnitType = CSS_VW; + m_value.num = length.viewportPercentageLength(); + break; + case ViewportPercentageHeight: + m_primitiveUnitType = CSS_VH; + m_value.num = length.viewportPercentageLength(); + break; + case ViewportPercentageMin: + m_primitiveUnitType = CSS_VMIN; + m_value.num = length.viewportPercentageLength(); + break; + case ViewportPercentageMax: + m_primitiveUnitType = CSS_VMAX; + m_value.num = length.viewportPercentageLength(); + break; + case Calculated: + case Relative: + case Undefined: + ASSERT_NOT_REACHED(); + break; } } @@ -552,57 +595,63 @@ double CSSPrimitiveValue::computeLengthDouble(const RenderStyle* style, const Re if (m_primitiveUnitType == CSS_CALC) // The multiplier and factor is applied to each value in the calc expression individually return m_value.calc->computeLengthPx(style, rootStyle, multiplier, computingFontSize); - + double factor; switch (primitiveType()) { - case CSS_EMS: - factor = computingFontSize ? style->fontDescription().specifiedSize() : style->fontDescription().computedSize(); - break; - case CSS_EXS: - // FIXME: We have a bug right now where the zoom will be applied twice to EX units. - // We really need to compute EX using fontMetrics for the original specifiedSize and not use - // our actual constructed rendering font. - if (style->fontMetrics().hasXHeight()) - factor = style->fontMetrics().xHeight(); - else - factor = (computingFontSize ? style->fontDescription().specifiedSize() : style->fontDescription().computedSize()) / 2.0; - break; - case CSS_REMS: - if (rootStyle) - factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize(); - else - factor = 1.0; - break; - case CSS_CHS: - factor = style->fontMetrics().zeroWidth(); - break; - case CSS_PX: + case CSS_EMS: + factor = computingFontSize ? style->fontDescription().specifiedSize() : style->fontDescription().computedSize(); + break; + case CSS_EXS: + // FIXME: We have a bug right now where the zoom will be applied twice to EX units. + // We really need to compute EX using fontMetrics for the original specifiedSize and not use + // our actual constructed rendering font. + if (style->fontMetrics().hasXHeight()) + factor = style->fontMetrics().xHeight(); + else + factor = (computingFontSize ? style->fontDescription().specifiedSize() : style->fontDescription().computedSize()) / 2.0; + break; + case CSS_REMS: + if (rootStyle) + factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize(); + else factor = 1.0; - break; - case CSS_CM: - factor = cssPixelsPerInch / 2.54; // (2.54 cm/in) - break; - case CSS_MM: - factor = cssPixelsPerInch / 25.4; - break; - case CSS_IN: - factor = cssPixelsPerInch; - break; - case CSS_PT: - factor = cssPixelsPerInch / 72.0; - break; - case CSS_PC: - // 1 pc == 12 pt - factor = cssPixelsPerInch * 12.0 / 72.0; - break; - case CSS_CALC_PERCENTAGE_WITH_LENGTH: - case CSS_CALC_PERCENTAGE_WITH_NUMBER: - ASSERT_NOT_REACHED(); - return -1.0; - default: - ASSERT_NOT_REACHED(); - return -1.0; + break; + case CSS_CHS: + factor = style->fontMetrics().zeroWidth(); + break; + case CSS_PX: + factor = 1.0; + break; + case CSS_CM: + factor = cssPixelsPerInch / 2.54; // (2.54 cm/in) + break; + case CSS_MM: + factor = cssPixelsPerInch / 25.4; + break; + case CSS_IN: + factor = cssPixelsPerInch; + break; + case CSS_PT: + factor = cssPixelsPerInch / 72.0; + break; + case CSS_PC: + // 1 pc == 12 pt + factor = cssPixelsPerInch * 12.0 / 72.0; + break; + case CSS_CALC_PERCENTAGE_WITH_LENGTH: + case CSS_CALC_PERCENTAGE_WITH_NUMBER: + ASSERT_NOT_REACHED(); + return -1.0; + case CSS_VH: + case CSS_VW: + case CSS_VMAX: + case CSS_VMIN: + factor = 1.0; + break; + default: + ASSERT_NOT_REACHED(); + return -1.0; } // We do not apply the zoom factor when we are computing the value of the font-size property. The zooming @@ -623,53 +672,53 @@ void CSSPrimitiveValue::setFloatValue(unsigned short, double, ExceptionCode& ec) ec = NO_MODIFICATION_ALLOWED_ERR; } -static double conversionToCanonicalUnitsScaleFactor(unsigned short unitType) +double CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(unsigned short unitType) { double factor = 1.0; // FIXME: the switch can be replaced by an array of scale factors. switch (unitType) { - // These are "canonical" units in their respective categories. - case CSSPrimitiveValue::CSS_PX: - case CSSPrimitiveValue::CSS_DEG: - case CSSPrimitiveValue::CSS_MS: - case CSSPrimitiveValue::CSS_HZ: - break; - case CSSPrimitiveValue::CSS_CM: - factor = cssPixelsPerInch / 2.54; // (2.54 cm/in) - break; - case CSSPrimitiveValue::CSS_DPCM: - factor = 2.54 / cssPixelsPerInch; // (2.54 cm/in) - break; - case CSSPrimitiveValue::CSS_MM: - factor = cssPixelsPerInch / 25.4; - break; - case CSSPrimitiveValue::CSS_IN: - factor = cssPixelsPerInch; - break; - case CSSPrimitiveValue::CSS_DPI: - factor = 1 / cssPixelsPerInch; - break; - case CSSPrimitiveValue::CSS_PT: - factor = cssPixelsPerInch / 72.0; - break; - case CSSPrimitiveValue::CSS_PC: - factor = cssPixelsPerInch * 12.0 / 72.0; // 1 pc == 12 pt - break; - case CSSPrimitiveValue::CSS_RAD: - factor = 180 / piDouble; - break; - case CSSPrimitiveValue::CSS_GRAD: - factor = 0.9; - break; - case CSSPrimitiveValue::CSS_TURN: - factor = 360; - break; - case CSSPrimitiveValue::CSS_S: - case CSSPrimitiveValue::CSS_KHZ: - factor = 1000; - break; - default: - break; + // These are "canonical" units in their respective categories. + case CSS_PX: + case CSS_DEG: + case CSS_MS: + case CSS_HZ: + break; + case CSS_CM: + factor = cssPixelsPerInch / 2.54; // (2.54 cm/in) + break; + case CSS_DPCM: + factor = 2.54 / cssPixelsPerInch; // (2.54 cm/in) + break; + case CSS_MM: + factor = cssPixelsPerInch / 25.4; + break; + case CSS_IN: + factor = cssPixelsPerInch; + break; + case CSS_DPI: + factor = 1 / cssPixelsPerInch; + break; + case CSS_PT: + factor = cssPixelsPerInch / 72.0; + break; + case CSS_PC: + factor = cssPixelsPerInch * 12.0 / 72.0; // 1 pc == 12 pt + break; + case CSS_RAD: + factor = 180 / piDouble; + break; + case CSS_GRAD: + factor = 0.9; + break; + case CSS_TURN: + factor = 360; + break; + case CSS_S: + case CSS_KHZ: + factor = 1000; + break; + default: + break; } return factor; @@ -696,7 +745,7 @@ double CSSPrimitiveValue::getDoubleValue(unsigned short unitType) const } double CSSPrimitiveValue::getDoubleValue() const -{ +{ return m_primitiveUnitType != CSS_CALC ? m_value.num : m_value.calc->doubleValue(); } @@ -790,20 +839,20 @@ String CSSPrimitiveValue::getStringValue(ExceptionCode& ec) const { ec = 0; switch (m_primitiveUnitType) { - case CSS_STRING: - case CSS_ATTR: - case CSS_URI: + case CSS_STRING: + case CSS_ATTR: + case CSS_URI: #if ENABLE(CSS_VARIABLES) - case CSS_VARIABLE_NAME: + case CSS_VARIABLE_NAME: #endif - return m_value.string; - case CSS_VALUE_ID: - return valueName(m_value.valueID); - case CSS_PROPERTY_ID: - return propertyName(m_value.propertyID); - default: - ec = INVALID_ACCESS_ERR; - break; + return m_value.string; + case CSS_VALUE_ID: + return valueName(m_value.valueID); + case CSS_PROPERTY_ID: + return propertyName(m_value.propertyID); + default: + ec = INVALID_ACCESS_ERR; + break; } return String(); @@ -812,19 +861,19 @@ String CSSPrimitiveValue::getStringValue(ExceptionCode& ec) const String CSSPrimitiveValue::getStringValue() const { switch (m_primitiveUnitType) { - case CSS_STRING: - case CSS_ATTR: - case CSS_URI: + case CSS_STRING: + case CSS_ATTR: + case CSS_URI: #if ENABLE(CSS_VARIABLES) - case CSS_VARIABLE_NAME: + case CSS_VARIABLE_NAME: #endif - return m_value.string; - case CSS_VALUE_ID: - return valueName(m_value.valueID); - case CSS_PROPERTY_ID: - return propertyName(m_value.propertyID); - default: - break; + return m_value.string; + case CSS_VALUE_ID: + return valueName(m_value.valueID); + case CSS_PROPERTY_ID: + return propertyName(m_value.propertyID); + default: + break; } return String(); |