return false;
}
+typedef HashMap<String, CSSPrimitiveValue::UnitTypes> StringToUnitTable;
+
+StringToUnitTable createStringToUnitTable()
+{
+ StringToUnitTable table;
+ table.set(String("em"), CSSPrimitiveValue::CSS_EMS);
+ table.set(String("ex"), CSSPrimitiveValue::CSS_EXS);
+ table.set(String("px"), CSSPrimitiveValue::CSS_PX);
+ table.set(String("cm"), CSSPrimitiveValue::CSS_CM);
+ table.set(String("mm"), CSSPrimitiveValue::CSS_MM);
+ table.set(String("in"), CSSPrimitiveValue::CSS_IN);
+ table.set(String("pt"), CSSPrimitiveValue::CSS_PT);
+ table.set(String("pc"), CSSPrimitiveValue::CSS_PC);
+ table.set(String("deg"), CSSPrimitiveValue::CSS_DEG);
+ table.set(String("rad"), CSSPrimitiveValue::CSS_RAD);
+ table.set(String("grad"), CSSPrimitiveValue::CSS_GRAD);
+ table.set(String("ms"), CSSPrimitiveValue::CSS_MS);
+ table.set(String("s"), CSSPrimitiveValue::CSS_S);
+ table.set(String("hz"), CSSPrimitiveValue::CSS_HZ);
+ table.set(String("khz"), CSSPrimitiveValue::CSS_KHZ);
+ table.set(String("dpi"), CSSPrimitiveValue::CSS_DPI);
+ table.set(String("dpcm"), CSSPrimitiveValue::CSS_DPCM);
+ table.set(String("dppx"), CSSPrimitiveValue::CSS_DPPX);
+ table.set(String("vw"), CSSPrimitiveValue::CSS_VW);
+ table.set(String("vh"), CSSPrimitiveValue::CSS_VH);
+ table.set(String("vmax"), CSSPrimitiveValue::CSS_VMIN);
+ table.set(String("vmin"), CSSPrimitiveValue::CSS_VMAX);
+ return table;
+}
+
+
+CSSPrimitiveValue::UnitTypes CSSPrimitiveValue::fromName(const String& unit)
+{
+ DEFINE_STATIC_LOCAL(StringToUnitTable, unitTable, (createStringToUnitTable()));
+ return unitTable.get(unit.lower());
+}
+
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
m_value.propertyID = propertyID;
}
-CSSPrimitiveValue::CSSPrimitiveValue(int parserOperator)
+CSSPrimitiveValue::CSSPrimitiveValue(int parserOperator, UnitTypes type)
: CSSValue(PrimitiveClass)
{
+ ASSERT(type == CSS_PARSER_OPERATOR);
m_primitiveUnitType = CSS_PARSER_OPERATOR;
m_value.parserOperator = parserOperator;
}
m_value.string->ref();
}
-CSSPrimitiveValue::CSSPrimitiveValue(const LengthSize& lengthSize)
+CSSPrimitiveValue::CSSPrimitiveValue(const LengthSize& lengthSize, const RenderStyle& style)
: CSSValue(PrimitiveClass)
{
- init(lengthSize);
+ init(lengthSize, style);
}
-CSSPrimitiveValue::CSSPrimitiveValue(RGBA32 color)
+CSSPrimitiveValue::CSSPrimitiveValue(RGBA32 color, UnitTypes type)
: CSSValue(PrimitiveClass)
{
+ ASSERT(type == CSS_RGBCOLOR);
m_primitiveUnitType = CSS_RGBCOLOR;
m_value.rgbcolor = color;
}
case ExtendToZoom:
case Percent:
init(length);
- return;
+ break;
case Fixed:
m_primitiveUnitType = CSS_PX;
m_value.num = length.value() / zoom;
- return;
- case Calculated:
- init(CSSCalcValue::create(length.calculationValue(), zoom));
- return;
+ break;
+ case Calculated: {
+ const CalculationValue& calc = length.calculationValue();
+ if (calc.pixels() && calc.percent()) {
+ init(CSSCalcValue::create(
+ CSSCalcValue::createExpressionNode(calc.pixels() / zoom, calc.percent()),
+ calc.isNonNegative() ? ValueRangeNonNegative : ValueRangeAll));
+ break;
+ }
+ if (calc.percent()) {
+ m_primitiveUnitType = CSS_PERCENTAGE;
+ m_value.num = calc.percent();
+ } else {
+ m_primitiveUnitType = CSS_PX;
+ m_value.num = calc.pixels() / zoom;
+ }
+ if (m_value.num < 0 && calc.isNonNegative())
+ m_value.num = 0;
+ break;
+ }
case DeviceWidth:
case DeviceHeight:
case Undefined:
}
}
-// Remove below specialized constructors once all callers of CSSPrimitiveValue(...)
-// have been converted to PassRefPtrWillBeRawPtr, ie. when
-// template<typename T> CSSPrimitiveValue(T* val)
-// template<typename T> CSSPrimitiveValue(PassRefPtr<T> val)
-// both can be converted to use PassRefPtrWillBeRawPtr.
-CSSPrimitiveValue::CSSPrimitiveValue(CSSCalcValue* value)
- : CSSValue(PrimitiveClass)
-{
- init(PassRefPtrWillBeRawPtr<CSSCalcValue>(value));
-}
-CSSPrimitiveValue::CSSPrimitiveValue(PassRefPtrWillBeRawPtr<CSSCalcValue> value)
- : CSSValue(PrimitiveClass)
-{
- init(value);
-}
-CSSPrimitiveValue::CSSPrimitiveValue(Pair* value)
- : CSSValue(PrimitiveClass)
-{
- init(PassRefPtrWillBeRawPtr<Pair>(value));
-}
-CSSPrimitiveValue::CSSPrimitiveValue(PassRefPtrWillBeRawPtr<Pair> value)
- : CSSValue(PrimitiveClass)
-{
- init(value);
-}
-CSSPrimitiveValue::CSSPrimitiveValue(Counter* value)
- : CSSValue(PrimitiveClass)
-{
- init(PassRefPtrWillBeRawPtr<Counter>(value));
-}
-CSSPrimitiveValue::CSSPrimitiveValue(PassRefPtrWillBeRawPtr<Counter> value)
- : CSSValue(PrimitiveClass)
-{
- init(value);
-}
-
void CSSPrimitiveValue::init(const Length& length)
{
switch (length.type()) {
}
}
-void CSSPrimitiveValue::init(const LengthSize& lengthSize)
+void CSSPrimitiveValue::init(const LengthSize& lengthSize, const RenderStyle& style)
{
m_primitiveUnitType = CSS_PAIR;
m_hasCachedCSSText = false;
- m_value.pair = Pair::create(create(lengthSize.width()), create(lengthSize.height()), Pair::KeepIdenticalValues).leakRef();
+ m_value.pair = Pair::create(create(lengthSize.width(), style.effectiveZoom()), create(lengthSize.height(), style.effectiveZoom()), Pair::KeepIdenticalValues).leakRef();
}
void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<Counter> c)
m_value.counter = c.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<Rect> r)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<Rect> r)
{
m_primitiveUnitType = CSS_RECT;
m_hasCachedCSSText = false;
m_value.rect = r.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<Quad> quad)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<Quad> quad)
{
m_primitiveUnitType = CSS_QUAD;
m_hasCachedCSSText = false;
m_value.calc = c.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<CSSBasicShape> shape)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<CSSBasicShape> shape)
{
m_primitiveUnitType = CSS_SHAPE;
m_hasCachedCSSText = false;
#endif
break;
case CSS_RECT:
+ // We must not call deref() when oilpan is enabled because m_value.rect is traced.
+#if !ENABLE(OILPAN)
m_value.rect->deref();
+#endif
break;
case CSS_QUAD:
+ // We must not call deref() when oilpan is enabled because m_value.quad is traced.
+#if !ENABLE(OILPAN)
m_value.quad->deref();
+#endif
break;
case CSS_PAIR:
// We must not call deref() when oilpan is enabled because m_value.pair is traced.
ASSERT_NOT_REACHED();
break;
case CSS_SHAPE:
+ // We must not call deref() when oilpan is enabled because m_value.shape is traced.
+#if !ENABLE(OILPAN)
m_value.shape->deref();
+#endif
break;
case CSS_NUMBER:
case CSS_PARSER_INTEGER:
double CSSPrimitiveValue::computeLengthDouble(const CSSToLengthConversionData& conversionData)
{
+ // The logic in this function is duplicated in MediaValues::computeLength
+ // because MediaValues::computeLength needs nearly identical logic, but we haven't found a way to make
+ // CSSPrimitiveValue::computeLengthDouble more generic (to solve both cases) without hurting performance.
if (m_primitiveUnitType == CSS_CALC)
return m_value.calc->computeLengthPx(conversionData);
const RenderStyle& style = conversionData.style();
- const RenderStyle& rootStyle = conversionData.rootStyle();
+ const RenderStyle* rootStyle = conversionData.rootStyle();
bool computingFontSize = conversionData.computingFontSize();
double factor;
factor = (computingFontSize ? style.fontDescription().specifiedSize() : style.fontDescription().computedSize()) / 2.0;
break;
case CSS_REMS:
- factor = computingFontSize ? rootStyle.fontDescription().specifiedSize() : rootStyle.fontDescription().computedSize();
+ if (rootStyle)
+ factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize();
+ else
+ factor = 1.0;
break;
case CSS_CHS:
factor = style.fontMetrics().zeroWidth();
return result * conversionData.zoom();
}
+void CSSPrimitiveValue::accumulateLengthArray(CSSLengthArray& lengthArray, double multiplier) const
+{
+ ASSERT(lengthArray.size() == LengthUnitTypeCount);
+
+ if (m_primitiveUnitType == CSS_CALC) {
+ cssCalcValue()->accumulateLengthArray(lengthArray, multiplier);
+ return;
+ }
+
+ LengthUnitType lengthType;
+ if (unitTypeToLengthUnitType(m_primitiveUnitType, lengthType))
+ lengthArray.at(lengthType) += m_value.num * conversionToCanonicalUnitsScaleFactor(m_primitiveUnitType) * multiplier;
+}
+
void CSSPrimitiveValue::setFloatValue(unsigned short, double, ExceptionState& exceptionState)
{
// Keeping values immutable makes optimizations easier and allows sharing of the primitive value objects.
return true;
}
+bool CSSPrimitiveValue::unitTypeToLengthUnitType(unsigned short unitType, LengthUnitType& lengthType)
+{
+ switch (unitType) {
+ case CSSPrimitiveValue::CSS_PX:
+ case CSSPrimitiveValue::CSS_CM:
+ case CSSPrimitiveValue::CSS_MM:
+ case CSSPrimitiveValue::CSS_IN:
+ case CSSPrimitiveValue::CSS_PT:
+ case CSSPrimitiveValue::CSS_PC:
+ lengthType = UnitTypePixels;
+ return true;
+ case CSSPrimitiveValue::CSS_EMS:
+ lengthType = UnitTypeFontSize;
+ return true;
+ case CSSPrimitiveValue::CSS_EXS:
+ lengthType = UnitTypeFontXSize;
+ return true;
+ case CSSPrimitiveValue::CSS_REMS:
+ lengthType = UnitTypeRootFontSize;
+ return true;
+ case CSSPrimitiveValue::CSS_CHS:
+ lengthType = UnitTypeZeroCharacterWidth;
+ return true;
+ case CSSPrimitiveValue::CSS_PERCENTAGE:
+ lengthType = UnitTypePercentage;
+ return true;
+ case CSSPrimitiveValue::CSS_VW:
+ lengthType = UnitTypeViewportWidth;
+ return true;
+ case CSSPrimitiveValue::CSS_VH:
+ lengthType = UnitTypeViewportHeight;
+ return true;
+ case CSSPrimitiveValue::CSS_VMIN:
+ lengthType = UnitTypeViewportMin;
+ return true;
+ case CSSPrimitiveValue::CSS_VMAX:
+ lengthType = UnitTypeViewportMax;
+ return true;
+ default:
+ return false;
+ }
+}
+
+unsigned short CSSPrimitiveValue::lengthUnitTypeToUnitType(LengthUnitType type)
+{
+ switch (type) {
+ case UnitTypePixels:
+ return CSSPrimitiveValue::CSS_PX;
+ case UnitTypeFontSize:
+ return CSSPrimitiveValue::CSS_EMS;
+ case UnitTypeFontXSize:
+ return CSSPrimitiveValue::CSS_EXS;
+ case UnitTypeRootFontSize:
+ return CSSPrimitiveValue::CSS_REMS;
+ case UnitTypeZeroCharacterWidth:
+ return CSSPrimitiveValue::CSS_CHS;
+ case UnitTypePercentage:
+ return CSSPrimitiveValue::CSS_PERCENTAGE;
+ case UnitTypeViewportWidth:
+ return CSSPrimitiveValue::CSS_VW;
+ case UnitTypeViewportHeight:
+ return CSSPrimitiveValue::CSS_VH;
+ case UnitTypeViewportMin:
+ return CSSPrimitiveValue::CSS_VMIN;
+ case UnitTypeViewportMax:
+ return CSSPrimitiveValue::CSS_VMAX;
+ case LengthUnitTypeCount:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return CSSPrimitiveValue::CSS_UNKNOWN;
+}
+
void CSSPrimitiveValue::setStringValue(unsigned short, const String&, ExceptionState& exceptionState)
{
// Keeping values immutable makes optimizations easier and allows sharing of the primitive value objects.
return m_value.quad;
}
-PassRefPtr<RGBColor> CSSPrimitiveValue::getRGBColorValue(ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<RGBColor> CSSPrimitiveValue::getRGBColorValue(ExceptionState& exceptionState) const
{
if (m_primitiveUnitType != CSS_RGBCOLOR) {
exceptionState.throwDOMException(InvalidAccessError, "This object is not an RGB color value.");
- return 0;
+ return nullptr;
}
// FIMXE: This should not return a new object for each invocation.
return formatNumber(number, characters, characterCount - 1);
}
+static String formatNumber(double number, const char* characters)
+{
+ return formatNumber(number, characters, strlen(characters));
+}
+
+const char* CSSPrimitiveValue::unitTypeToString(UnitTypes type)
+{
+ switch (type) {
+ case CSS_NUMBER:
+ case CSS_PARSER_INTEGER:
+ return "";
+ case CSS_PERCENTAGE:
+ return "%";
+ case CSS_EMS:
+ return "em";
+ case CSS_EXS:
+ return "ex";
+ case CSS_REMS:
+ return "rem";
+ case CSS_CHS:
+ return "ch";
+ case CSS_PX:
+ return "px";
+ case CSS_CM:
+ return "cm";
+ case CSS_DPPX:
+ return "dppx";
+ case CSS_DPI:
+ return "dpi";
+ case CSS_DPCM:
+ return "dpcm";
+ case CSS_MM:
+ return "mm";
+ case CSS_IN:
+ return "in";
+ case CSS_PT:
+ return "pt";
+ case CSS_PC:
+ return "pc";
+ case CSS_DEG:
+ return "deg";
+ case CSS_RAD:
+ return "rad";
+ case CSS_GRAD:
+ return "grad";
+ case CSS_MS:
+ return "ms";
+ case CSS_S:
+ return "s";
+ case CSS_HZ:
+ return "hz";
+ case CSS_KHZ:
+ return "khz";
+ case CSS_TURN:
+ return "turn";
+ case CSS_FR:
+ return "fr";
+ case CSS_VW:
+ return "vw";
+ case CSS_VH:
+ return "vh";
+ case CSS_VMIN:
+ return "vmin";
+ case CSS_VMAX:
+ return "vmax";
+ case CSS_UNKNOWN:
+ case CSS_DIMENSION:
+ case CSS_STRING:
+ case CSS_URI:
+ case CSS_VALUE_ID:
+ case CSS_PROPERTY_ID:
+ case CSS_ATTR:
+ case CSS_COUNTER_NAME:
+ case CSS_COUNTER:
+ case CSS_RECT:
+ case CSS_QUAD:
+ case CSS_RGBCOLOR:
+ case CSS_PARSER_HEXCOLOR:
+ case CSS_PAIR:
+ case CSS_PARSER_OPERATOR:
+ case CSS_PARSER_IDENTIFIER:
+ case CSS_CALC:
+ case CSS_SHAPE:
+ case CSS_IDENT:
+ case CSS_UNICODE_RANGE:
+ case CSS_CALC_PERCENTAGE_WITH_NUMBER:
+ case CSS_CALC_PERCENTAGE_WITH_LENGTH:
+ break;
+ };
+ ASSERT_NOT_REACHED();
+ return "";
+}
+
String CSSPrimitiveValue::customCSSText(CSSTextFormattingFlags formattingFlag) const
{
// FIXME: return the original value instead of a generated one (e.g. color
break;
case CSS_NUMBER:
case CSS_PARSER_INTEGER:
- text = formatNumber(m_value.num, "");
- break;
case CSS_PERCENTAGE:
- text = formatNumber(m_value.num, "%");
- break;
case CSS_EMS:
- text = formatNumber(m_value.num, "em");
- break;
case CSS_EXS:
- text = formatNumber(m_value.num, "ex");
- break;
case CSS_REMS:
- text = formatNumber(m_value.num, "rem");
- break;
case CSS_CHS:
- text = formatNumber(m_value.num, "ch");
- break;
case CSS_PX:
- text = formatNumber(m_value.num, "px");
- break;
case CSS_CM:
- text = formatNumber(m_value.num, "cm");
- break;
case CSS_DPPX:
- text = formatNumber(m_value.num, "dppx");
- break;
case CSS_DPI:
- text = formatNumber(m_value.num, "dpi");
- break;
case CSS_DPCM:
- text = formatNumber(m_value.num, "dpcm");
- break;
case CSS_MM:
- text = formatNumber(m_value.num, "mm");
- break;
case CSS_IN:
- text = formatNumber(m_value.num, "in");
- break;
case CSS_PT:
- text = formatNumber(m_value.num, "pt");
- break;
case CSS_PC:
- text = formatNumber(m_value.num, "pc");
- break;
case CSS_DEG:
- text = formatNumber(m_value.num, "deg");
- break;
case CSS_RAD:
- text = formatNumber(m_value.num, "rad");
- break;
case CSS_GRAD:
- text = formatNumber(m_value.num, "grad");
- break;
case CSS_MS:
- text = formatNumber(m_value.num, "ms");
- break;
case CSS_S:
- text = formatNumber(m_value.num, "s");
- break;
case CSS_HZ:
- text = formatNumber(m_value.num, "hz");
- break;
case CSS_KHZ:
- text = formatNumber(m_value.num, "khz");
- break;
case CSS_TURN:
- text = formatNumber(m_value.num, "turn");
- break;
+ case CSS_FR:
+ case CSS_VW:
+ case CSS_VH:
+ case CSS_VMIN:
+ case CSS_VMAX:
+ text = formatNumber(m_value.num, unitTypeToString((UnitTypes)m_primitiveUnitType));
case CSS_DIMENSION:
// FIXME: We currently don't handle CSS_DIMENSION properly as we don't store
// the actual dimension, just the numeric value as a string.
text = color.serializedAsCSSComponentValue();
break;
}
- case CSS_FR:
- text = formatNumber(m_value.num, "fr");
- break;
case CSS_PAIR:
text = getPairValue()->cssText();
break;
case CSS_SHAPE:
text = m_value.shape->cssText();
break;
- case CSS_VW:
- text = formatNumber(m_value.num, "vw");
- break;
- case CSS_VH:
- text = formatNumber(m_value.num, "vh");
- break;
- case CSS_VMIN:
- text = formatNumber(m_value.num, "vmin");
- break;
- case CSS_VMAX:
- text = formatNumber(m_value.num, "vmax");
- break;
}
ASSERT(!cssTextCache().contains(this));
PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPrimitiveValue::cloneForCSSOM() const
{
- RefPtrWillBeRawPtr<CSSPrimitiveValue> result;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> result = nullptr;
switch (m_primitiveUnitType) {
case CSS_STRING:
case CSS_COUNTER:
visitor->trace(m_value.counter);
break;
+ case CSS_RECT:
+ visitor->trace(m_value.rect);
+ break;
+ case CSS_QUAD:
+ visitor->trace(m_value.quad);
+ break;
case CSS_PAIR:
visitor->trace(m_value.pair);
break;
case CSS_CALC:
visitor->trace(m_value.calc);
break;
+ case CSS_SHAPE:
+ visitor->trace(m_value.shape);
+ break;
default:
break;
}