Changeset 166860 in webkit
- Timestamp:
- Apr 6, 2014 5:16:35 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 27 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r166858 r166860 1 2014-04-06 Darin Adler <darin@apple.com> 2 3 Rework CSS calc logic, fixing some reference count mistakes in Length 4 https://bugs.webkit.org/show_bug.cgi?id=131280 5 rdar://problem/16400823 6 7 Reviewed by Andreas Kling. 8 9 New unit test in TestWebKitAPI. 10 11 Changed the classes related to CSS "calc" to make the code a bit easier to read by 12 moving code out of class definitions. Also used final some more, made more things private, 13 used references instead of pointers, and other such changes. Biggest change, though, is to 14 Length, which had a broken system for managing reference counted calculated objects. 15 There were multiple bugs including a basic design mistake of not having a reference count 16 and trying to use the reference count in the object itself. Fixed and covered by the unit 17 test now; test found multiple problems in both the old and new implementations. 18 19 * WebCore.exp.in: Updated exports, including symbols to make the unit test practical. 20 21 * WebCore.xcodeproj/project.pbxproj: Made CalculationValue.h a Private file so it can 22 be used in a unit test. Also let Xcode update the file type for a gperf file. 23 24 * css/CSSCalculationValue.cpp: 25 (WebCore::CSSCalcValue::equals): Updated since m_expression is a Ref now. 26 (WebCore::CSSCalcValue::clampToPermittedRange): Marked inline and updated for data member 27 name change. 28 (WebCore::isIntegerResult): Changed argument order to put the operator first and use 29 references instead of pointers. Also marked inline. 30 (WebCore::createBlendHalf): Added. Helper to make the other functions more readable. 31 (WebCore::createExpressionNode): Made non-member function private to this file. Also made 32 many small improvements. 33 (WebCore::CSSCalcValue::create): Updated so both of these call the same constructor. 34 35 * css/CSSCalculationValue.h: Cut down CSSCalcValue class by making more things private 36 and deleting unneeded things. Also use Ref instead of RefPtr. 37 38 * css/CSSComputedStyleDeclaration.cpp: 39 (WebCore::getPositionOffsetValue): Use isFixed function instead of type function. 40 41 * css/CSSGradientValue.cpp: 42 (WebCore::CSSGradientValue::addStops): Updated code since toCalcValue now returns PassRef 43 instead of PassRefPtr. Unfortunately the new code is a bit more verbose. 44 (WebCore::positionFromValue): Ditto. 45 46 * css/CSSParser.cpp: 47 (WebCore::CSSParser::parseCalculation): 48 49 * css/CSSPrimitiveValue.cpp: 50 (WebCore::CSSPrimitiveValue::CSSPrimitiveValue): Updated to pass reference rather than pointer. 51 (WebCore::CSSPrimitiveValue::init): Ditto. 52 53 * css/CSSToStyleMap.h: Removed unneeded include of LengthBox.h. 54 55 * css/DeprecatedStyleBuilder.cpp: 56 (WebCore::ApplyPropertyLength::applyValue): Updated for function name change. 57 (WebCore::ApplyPropertyBorderRadius::applyValue): Removed extra parentheses. 58 (WebCore::ApplyPropertyFontSize::applyValue): Ditto. Also updated since toCalcValue returns Ref. 59 60 * css/LengthFunctions.cpp: 61 (WebCore::floatValueForLength): Updated to call value instead of getFloatValue; both are the same. 62 63 * css/StyleResolver.cpp: 64 (WebCore::addIntrinsicMargins): Updated for function name change. 65 (WebCore::createGridTrackBreadth): Ditto. 66 67 * platform/CalculationValue.cpp: 68 (WebCore::CalculationValue::create): Changed to return PassRef. 69 (WebCore::CalcExpressionNumber::evaluate): Moved this function out of the header, since it's 70 virtual and not really going to be inlined. 71 (WebCore::CalcExpressionNumber::operator==): Ditto. 72 (WebCore::CalculationValue::evaluate): Ditto. 73 (WebCore::CalcExpressionBinaryOperation::operator==): Ditto. 74 (WebCore::CalcExpressionLength::evaluate): Ditto. 75 (WebCore::CalcExpressionLength::operator==): Ditto. 76 (WebCore::CalcExpressionBlendLength::evaluate): Ditto. 77 (WebCore::CalcExpressionBlendLength::operator==): Ditto. 78 79 * platform/CalculationValue.h: Moved most functions out of the class bodies so the classes are 80 easier to see. Made all the == operator functions non-member ones except for the polymorphic 81 one from the base class. Changed the casting functions to work on references instead of pointers. 82 Tweaked name of some members. 83 84 * platform/Length.cpp: Reworked the CalculationValueMap (formerly CalculationValueHandleMap) to 85 use unsigned instead of int, and store reference counts in the map rather than trying to share the 86 reference count of the underlying CalculationValue object, which can lead to storage leaks where 87 handles end up in the map permanently. 88 (WebCore::calculationValues): Use NeverDestroyed instead of DEPRECATED_DEFINE_STATIC_LOCAL. 89 (WebCore::Length::Length): Updated some data member names. 90 (WebCore::Length::calculationValue): Updated to return a reference instead of a PassRefPtr. 91 (WebCore::Length::ref): Renamed and updated for new interface to the map. 92 (WebCore::Length::deref): Ditto. 93 (WebCore::Length::nonNanCalculatedValue): Updated to use a reference instead of a pointer. 94 (WebCore::Length::isCalculatedEqual): Updated since this is now only called if both objects are 95 known to be calculated values. 96 97 * platform/Length.h: Moved most functions out of the class definition to make the class definition 98 easier to read. Reworked the constructors and assignment operators to handle the reference counting 99 correctly. Added various FIXMEs and assertions. Removed some unused functions, made others private. 100 101 * platform/LengthBox.h: Renamed some one-letter arguments to use words instead. 102 103 * rendering/AutoTableLayout.cpp: 104 (WebCore::AutoTableLayout::recalcColumn): Updated for change to Length::setValue. 105 * rendering/FixedTableLayout.cpp: 106 (WebCore::FixedTableLayout::calcWidthArray): Ditto. 107 108 * rendering/style/FillLayer.h: 109 (WebCore::FillLayer::initialFillXPosition): Updated to not convert a double to a float at runtime. 110 (WebCore::FillLayer::initialFillYPosition): Ditto. 111 112 * rendering/style/RenderStyle.cpp: 113 (WebCore::RenderStyle::setWordSpacing): Removed a bogus FALLTHROUGH that was clearly wrong, but 114 harmless. Updated for changes to Length. 115 116 * rendering/style/RenderStyle.h: Updated for name changes and to avoid converting doubles to floats 117 at runtime. 118 1 119 2014-04-06 Brent Fulgham <bfulgham@apple.com> 2 120 -
trunk/Source/WebCore/WebCore.exp.in
r166855 r166860 650 650 __ZN7WebCore16ApplicationCache20deleteCacheForOriginEPNS_14SecurityOriginE 651 651 __ZN7WebCore16CSSParserContextC1ERNS_8DocumentERKNS_3URLERKN3WTF6StringE 652 __ZN7WebCore16CalculationValue6createENSt3__110unique_ptrINS_18CalcExpressionNodeENS1_14default_deleteIS3_EEEENS_30CalculationPermittedValueRangeE 652 653 __ZN7WebCore16DatabaseStrategy17getDatabaseServerEv 653 654 __ZN7WebCore16DatabaseStrategy23createIDBFactoryBackendERKN3WTF6StringE … … 1173 1174 __ZN7WebCore6Editor7outdentEv 1174 1175 __ZN7WebCore6JSNode6s_infoE 1176 __ZN7WebCore6LengthC1EN3WTF7PassRefINS_16CalculationValueEEE 1175 1177 __ZN7WebCore6Region21updateBoundsFromShapeEv 1176 1178 __ZN7WebCore6Region5uniteERKS0_ … … 1856 1858 __ZNK7WebCore6Editor8canPasteEv 1857 1859 __ZNK7WebCore6Editor9canDeleteEv 1858 __ZNK7WebCore6Length 22decrementCalculatedRefEv1859 __ZNK7WebCore6Length 22incrementCalculatedRefEv1860 __ZNK7WebCore6Length3refEv 1861 __ZNK7WebCore6Length5derefEv 1860 1862 __ZNK7WebCore6Region5Shape7isValidEv 1861 1863 __ZNK7WebCore6Region5rectsEv -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r166847 r166860 1599 1599 49AE2D8F134EE50C0072920A /* CSSCalculationValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 49AE2D8D134EE50C0072920A /* CSSCalculationValue.h */; }; 1600 1600 49AE2D96134EE5F90072920A /* CalculationValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49AE2D94134EE5F90072920A /* CalculationValue.cpp */; }; 1601 49AE2D97134EE5F90072920A /* CalculationValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 49AE2D95134EE5F90072920A /* CalculationValue.h */; };1601 49AE2D97134EE5F90072920A /* CalculationValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 49AE2D95134EE5F90072920A /* CalculationValue.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1602 1602 49AF2D6914435D050016A784 /* DisplayRefreshMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 49AF2D6814435D050016A784 /* DisplayRefreshMonitor.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1603 1603 49AF2D6C14435D210016A784 /* DisplayRefreshMonitorMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49AF2D6B14435D210016A784 /* DisplayRefreshMonitorMac.cpp */; }; … … 8433 8433 43B85ED018CBEACE00E31AF4 /* makeSelectorPseudoClassAndCompatibilityElementMap.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = makeSelectorPseudoClassAndCompatibilityElementMap.py; sourceTree = "<group>"; }; 8434 8434 43B85ED218CBEC5200E31AF4 /* SelectorPseudoClassAndCompatibilityElementMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectorPseudoClassAndCompatibilityElementMap.cpp; sourceTree = "<group>"; }; 8435 43B85ED318CBEC5200E31AF4 /* SelectorPseudoClassAndCompatibilityElementMap.gperf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file; path = SelectorPseudoClassAndCompatibilityElementMap.gperf; sourceTree = "<group>"; };8435 43B85ED318CBEC5200E31AF4 /* SelectorPseudoClassAndCompatibilityElementMap.gperf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SelectorPseudoClassAndCompatibilityElementMap.gperf; sourceTree = "<group>"; }; 8436 8436 43B85ED618CBEC9700E31AF4 /* SelectorPseudoClassAndCompatibilityElementMap.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SelectorPseudoClassAndCompatibilityElementMap.in; sourceTree = "<group>"; }; 8437 8437 43B9336713B261B1004584BF /* SVGAnimatedPointList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedPointList.h; sourceTree = "<group>"; }; -
trunk/Source/WebCore/css/CSSCalculationValue.cpp
r163888 r166860 1 1 /* 2 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2014 Apple Inc. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 33 34 34 35 #include "CSSPrimitiveValueMappings.h" 35 #include "CSSValueList.h"36 #include "Length.h"37 36 #include "StyleResolver.h" 38 39 37 #include <wtf/MathExtras.h> 40 38 #include <wtf/text/StringBuilder.h> … … 49 47 50 48 namespace WebCore { 49 50 static PassRefPtr<CSSCalcExpressionNode> createCSS(const CalcExpressionNode&, const RenderStyle&); 51 static PassRefPtr<CSSCalcExpressionNode> createCSS(const Length&, const RenderStyle&); 51 52 52 53 static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type) … … 158 159 bool CSSCalcValue::equals(const CSSCalcValue& other) const 159 160 { 160 return compareCSSValue Ptr(m_expression, other.m_expression);161 } 162 163 double CSSCalcValue::clampToPermittedRange(double value) const164 { 165 return m_ nonNegative && value < 0 ? 0 : value;161 return compareCSSValue(m_expression, other.m_expression); 162 } 163 164 inline double CSSCalcValue::clampToPermittedRange(double value) const 165 { 166 return m_shouldClampToNonNegative && value < 0 ? 0 : value; 166 167 } 167 168 … … 176 177 } 177 178 178 CSSCalcExpressionNode::~CSSCalcExpressionNode() 179 { 180 } 181 182 class CSSCalcPrimitiveValue : public CSSCalcExpressionNode { 179 class CSSCalcPrimitiveValue final : public CSSCalcExpressionNode { 183 180 WTF_MAKE_FAST_ALLOCATED; 184 181 public: 185 186 static PassRefPtr<CSSCalcPrimitiveValue> create(PassRefPtr<CSSPrimitiveValue> value, bool isInteger) 187 { 188 return adoptRef(new CSSCalcPrimitiveValue(value, isInteger)); 182 static PassRef<CSSCalcPrimitiveValue> create(PassRefPtr<CSSPrimitiveValue> value, bool isInteger) 183 { 184 return adoptRef(*new CSSCalcPrimitiveValue(value, isInteger)); 189 185 } 190 186 … … 192 188 { 193 189 if (std::isnan(value) || std::isinf(value)) 194 return 0;190 return nullptr; 195 191 return adoptRef(new CSSCalcPrimitiveValue(CSSPrimitiveValue::create(value, type), isInteger)); 196 192 } 197 193 198 virtual bool isZero() const 194 private: 195 virtual bool isZero() const override 199 196 { 200 197 return !m_value->getDoubleValue(); 201 198 } 202 199 203 virtual String customCSSText() const 200 virtual String customCSSText() const override 204 201 { 205 202 return m_value->cssText(); 206 203 } 207 204 208 virtual std::unique_ptr<CalcExpressionNode> toCalcValue(const RenderStyle* style, const RenderStyle* rootStyle, double zoom) const209 { 210 switch ( m_category) {205 virtual std::unique_ptr<CalcExpressionNode> createCalcExpression(const RenderStyle* style, const RenderStyle* rootStyle, double zoom) const override 206 { 207 switch (category()) { 211 208 case CalcNumber: 212 209 return std::make_unique<CalcExpressionNumber>(m_value->getFloatValue()); … … 228 225 } 229 226 230 virtual double doubleValue() const 227 virtual double doubleValue() const override 231 228 { 232 229 if (hasDoubleValue(primitiveType())) … … 236 233 } 237 234 238 virtual double computeLengthPx(const RenderStyle* currentStyle, const RenderStyle* rootStyle, double multiplier, bool computingFontSize) const 239 { 240 switch ( m_category) {235 virtual double computeLengthPx(const RenderStyle* currentStyle, const RenderStyle* rootStyle, double multiplier, bool computingFontSize) const override 236 { 237 switch (category()) { 241 238 case CalcLength: 242 239 return m_value->computeLength<double>(currentStyle, rootStyle, multiplier, computingFontSize); … … 254 251 } 255 252 256 virtual bool equals(const CSSCalcExpressionNode& other) const 253 virtual bool equals(const CSSCalcExpressionNode& other) const override 257 254 { 258 255 if (type() != other.type()) … … 262 259 } 263 260 264 virtual Type type() const { return CssCalcPrimitiveValue; }265 virtual CSSPrimitiveValue::UnitTypes primitiveType() const 261 virtual Type type() const override { return CssCalcPrimitiveValue; } 262 virtual CSSPrimitiveValue::UnitTypes primitiveType() const override 266 263 { 267 264 return CSSPrimitiveValue::UnitTypes(m_value->primitiveType()); … … 313 310 } 314 311 315 static bool isIntegerResult(const CSSCalcExpressionNode* leftSide, const CSSCalcExpressionNode* rightSide, CalcOperator op)312 static inline bool isIntegerResult(CalcOperator op, const CSSCalcExpressionNode& leftSide, const CSSCalcExpressionNode& rightSide) 316 313 { 317 314 // Performs W3C spec's type checking for calc integers. 318 315 // http://www.w3.org/TR/css3-values/#calc-type-checking 319 return op != CalcDivide && leftSide ->isInteger() && rightSide->isInteger();320 } 321 322 class CSSCalcBinaryOperation : public CSSCalcExpressionNode {323 316 return op != CalcDivide && leftSide.isInteger() && rightSide.isInteger(); 317 } 318 319 class CSSCalcBinaryOperation final : public CSSCalcExpressionNode { 320 WTF_MAKE_FAST_ALLOCATED; 324 321 public: 325 static PassRefPtr<CSSCalc ExpressionNode> create(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)322 static PassRefPtr<CSSCalcBinaryOperation> create(CalcOperator op, PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide) 326 323 { 327 324 ASSERT(leftSide->category() != CalcOther && rightSide->category() != CalcOther); … … 330 327 331 328 if (newCategory == CalcOther) 332 return 0;333 334 return adoptRef(new CSSCalcBinaryOperation( leftSide, rightSide, op, newCategory));335 } 336 337 static PassRefPtr<CSSCalcExpressionNode> createSimplified( PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)329 return nullptr; 330 331 return adoptRef(new CSSCalcBinaryOperation(newCategory, op, leftSide, rightSide)); 332 } 333 334 static PassRefPtr<CSSCalcExpressionNode> createSimplified(CalcOperator op, PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide) 338 335 { 339 336 CalculationCategory leftCategory = leftSide->category(); … … 341 338 ASSERT(leftCategory != CalcOther && rightCategory != CalcOther); 342 339 343 bool isInteger = isIntegerResult( leftSide.get(), rightSide.get(), op);340 bool isInteger = isIntegerResult(op, *leftSide, *rightSide); 344 341 345 342 // Simplify numbers. 346 343 if (leftCategory == CalcNumber && rightCategory == CalcNumber) { 347 344 CSSPrimitiveValue::UnitTypes evaluationType = isInteger ? CSSPrimitiveValue::CSS_PARSER_INTEGER : CSSPrimitiveValue::CSS_NUMBER; 348 return CSSCalcPrimitiveValue::create(evaluateOperator( leftSide->doubleValue(), rightSide->doubleValue(), op), evaluationType, isInteger);345 return CSSCalcPrimitiveValue::create(evaluateOperator(op, leftSide->doubleValue(), rightSide->doubleValue()), evaluationType, isInteger); 349 346 } 350 347 … … 356 353 CSSPrimitiveValue::UnitTypes rightType = rightSide->primitiveType(); 357 354 if (leftType == rightType) 358 return CSSCalcPrimitiveValue::create(evaluateOperator( leftSide->doubleValue(), rightSide->doubleValue(), op), leftType, isInteger);355 return CSSCalcPrimitiveValue::create(evaluateOperator(op, leftSide->doubleValue(), rightSide->doubleValue()), leftType, isInteger); 359 356 CSSPrimitiveValue::UnitCategory leftUnitCategory = CSSPrimitiveValue::unitCategory(leftType); 360 357 if (leftUnitCategory != CSSPrimitiveValue::UOther && leftUnitCategory == CSSPrimitiveValue::unitCategory(rightType)) { … … 363 360 double leftValue = leftSide->doubleValue() * CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(leftType); 364 361 double rightValue = rightSide->doubleValue() * CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(rightType); 365 return CSSCalcPrimitiveValue::create(evaluateOperator( leftValue, rightValue, op), canonicalType, isInteger);362 return CSSCalcPrimitiveValue::create(evaluateOperator(op, leftValue, rightValue), canonicalType, isInteger); 366 363 } 367 364 } … … 371 368 // Simplify multiplying or dividing by a number for simplifiable types. 372 369 ASSERT(op == CalcMultiply || op == CalcDivide); 373 CSSCalcExpressionNode* numberSide = getNumberSide( leftSide.get(), rightSide.get());370 CSSCalcExpressionNode* numberSide = getNumberSide(*leftSide, *rightSide); 374 371 if (!numberSide) 375 return create( leftSide, rightSide, op);372 return create(op, leftSide, rightSide); 376 373 if (numberSide == leftSide && op == CalcDivide) 377 return 0;374 return nullptr; 378 375 CSSCalcExpressionNode* otherSide = leftSide == numberSide ? rightSide.get() : leftSide.get(); 379 376 380 377 double number = numberSide->doubleValue(); 381 378 if (std::isnan(number) || std::isinf(number)) 382 return 0;379 return nullptr; 383 380 if (op == CalcDivide && !number) 384 return 0;381 return nullptr; 385 382 386 383 CSSPrimitiveValue::UnitTypes otherType = otherSide->primitiveType(); 387 384 if (hasDoubleValue(otherType)) 388 return CSSCalcPrimitiveValue::create(evaluateOperator(otherSide->doubleValue(), number, op), otherType, isInteger); 389 } 390 391 return create(leftSide, rightSide, op); 392 } 393 394 virtual bool isZero() const 385 return CSSCalcPrimitiveValue::create(evaluateOperator(op, otherSide->doubleValue(), number), otherType, isInteger); 386 } 387 388 return create(op, leftSide, rightSide); 389 } 390 391 private: 392 virtual bool isZero() const override 395 393 { 396 394 return !doubleValue(); 397 395 } 398 396 399 virtual std::unique_ptr<CalcExpressionNode> toCalcValue(const RenderStyle* style, const RenderStyle* rootStyle, double zoom) const400 { 401 std::unique_ptr<CalcExpressionNode> left(m_leftSide-> toCalcValue(style, rootStyle, zoom));397 virtual std::unique_ptr<CalcExpressionNode> createCalcExpression(const RenderStyle* style, const RenderStyle* rootStyle, double zoom) const override 398 { 399 std::unique_ptr<CalcExpressionNode> left(m_leftSide->createCalcExpression(style, rootStyle, zoom)); 402 400 if (!left) 403 401 return nullptr; 404 std::unique_ptr<CalcExpressionNode> right(m_rightSide-> toCalcValue(style, rootStyle, zoom));402 std::unique_ptr<CalcExpressionNode> right(m_rightSide->createCalcExpression(style, rootStyle, zoom)); 405 403 if (!right) 406 404 return nullptr; … … 408 406 } 409 407 410 virtual double doubleValue() const 408 virtual double doubleValue() const override 411 409 { 412 410 return evaluate(m_leftSide->doubleValue(), m_rightSide->doubleValue()); 413 411 } 414 412 415 virtual double computeLengthPx(const RenderStyle* currentStyle, const RenderStyle* rootStyle, double multiplier, bool computingFontSize) const 413 virtual double computeLengthPx(const RenderStyle* currentStyle, const RenderStyle* rootStyle, double multiplier, bool computingFontSize) const override 416 414 { 417 415 const double leftValue = m_leftSide->computeLengthPx(currentStyle, rootStyle, multiplier, computingFontSize); … … 434 432 } 435 433 436 virtual String customCSSText() const 434 virtual String customCSSText() const override 437 435 { 438 436 return buildCssText(m_leftSide->customCSSText(), m_rightSide->customCSSText(), m_operator); 439 437 } 440 438 441 442 virtual bool equals(const CSSCalcExpressionNode& exp) const 439 virtual bool equals(const CSSCalcExpressionNode& exp) const override 443 440 { 444 441 if (type() != exp.type()) … … 451 448 } 452 449 453 virtual Type type() const { return CssCalcBinaryOperation; }454 455 virtual CSSPrimitiveValue::UnitTypes primitiveType() const 456 { 457 switch ( m_category) {450 virtual Type type() const override { return CssCalcBinaryOperation; } 451 452 virtual CSSPrimitiveValue::UnitTypes primitiveType() const override 453 { 454 switch (category()) { 458 455 case CalcNumber: 459 456 ASSERT(m_leftSide->category() == CalcNumber && m_rightSide->category() == CalcNumber); 460 if ( m_isInteger)457 if (isInteger()) 461 458 return CSSPrimitiveValue::CSS_PARSER_INTEGER; 462 459 return CSSPrimitiveValue::CSS_NUMBER; … … 481 478 } 482 479 483 private: 484 CSSCalcBinaryOperation(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op, CalculationCategory category) 485 : CSSCalcExpressionNode(category, isIntegerResult(leftSide.get(), rightSide.get(), op)) 480 CSSCalcBinaryOperation(CalculationCategory category, CalcOperator op, PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide) 481 : CSSCalcExpressionNode(category, isIntegerResult(op, *leftSide, *rightSide)) 486 482 , m_leftSide(leftSide) 487 483 , m_rightSide(rightSide) … … 490 486 } 491 487 492 static CSSCalcExpressionNode* getNumberSide(CSSCalcExpressionNode * leftSide, CSSCalcExpressionNode*rightSide)493 { 494 if (leftSide ->category() == CalcNumber)495 return leftSide;496 if (rightSide ->category() == CalcNumber)497 return rightSide;498 return 0;488 static CSSCalcExpressionNode* getNumberSide(CSSCalcExpressionNode& leftSide, CSSCalcExpressionNode& rightSide) 489 { 490 if (leftSide.category() == CalcNumber) 491 return &leftSide; 492 if (rightSide.category() == CalcNumber) 493 return &rightSide; 494 return nullptr; 499 495 } 500 496 501 497 double evaluate(double leftSide, double rightSide) const 502 498 { 503 return evaluateOperator( leftSide, rightSide, m_operator);504 } 505 506 static double evaluateOperator( double leftValue, double rightValue, CalcOperator op)499 return evaluateOperator(m_operator, leftSide, rightSide); 500 } 501 502 static double evaluateOperator(CalcOperator op, double leftValue, double rightValue) 507 503 { 508 504 switch (op) { … … 518 514 return std::numeric_limits<double>::quiet_NaN(); 519 515 } 516 ASSERT_NOT_REACHED(); 520 517 return 0; 521 518 } … … 545 542 ASSERT_WITH_SECURITY_IMPLICATION(index <= tokens->size()); 546 543 if (!ok || index != tokens->size()) 547 return 0;544 return nullptr; 548 545 return result.value; 549 546 } … … 619 616 return false; 620 617 621 result->value = CSSCalcBinaryOperation::createSimplified( result->value, rhs.value, static_cast<CalcOperator>(operatorCharacter));618 result->value = CSSCalcBinaryOperation::createSimplified(static_cast<CalcOperator>(operatorCharacter), result->value, rhs.value); 622 619 if (!result->value) 623 620 return false; … … 646 643 return false; 647 644 648 result->value = CSSCalcBinaryOperation::createSimplified( result->value, rhs.value, static_cast<CalcOperator>(operatorCharacter));645 result->value = CSSCalcBinaryOperation::createSimplified(static_cast<CalcOperator>(operatorCharacter), result->value, rhs.value); 649 646 if (!result->value) 650 647 return false; … … 661 658 }; 662 659 663 PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(PassRefPtr<CSSPrimitiveValue> value, bool isInteger) 664 { 665 return CSSCalcPrimitiveValue::create(value, isInteger); 666 } 667 668 PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op) 669 { 670 return CSSCalcBinaryOperation::create(leftSide, rightSide, op); 671 } 672 673 PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(const CalcExpressionNode* node, const RenderStyle* style) 674 { 675 switch (node->type()) { 660 static inline PassRefPtr<CSSCalcBinaryOperation> createBlendHalf(const Length& length, const RenderStyle& style, float progress) 661 { 662 return CSSCalcBinaryOperation::create(CalcMultiply, createCSS(length, style), 663 CSSCalcPrimitiveValue::create(CSSPrimitiveValue::create(progress, CSSPrimitiveValue::CSS_NUMBER), !progress || progress == 1)); 664 } 665 666 static PassRefPtr<CSSCalcExpressionNode> createCSS(const CalcExpressionNode& node, const RenderStyle& style) 667 { 668 switch (node.type()) { 676 669 case CalcExpressionNodeNumber: { 677 float value = toCalcExpressionNumber(node) ->value();678 return createExpressionNode(CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER), value == trunc(value));670 float value = toCalcExpressionNumber(node).value(); 671 return CSSCalcPrimitiveValue::create(CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER), value == truncf(value)); 679 672 } 680 673 case CalcExpressionNodeLength: 681 return create ExpressionNode(toCalcExpressionLength(node)->length(), style);674 return createCSS(toCalcExpressionLength(node).length(), style); 682 675 case CalcExpressionNodeBinaryOperation: { 683 const CalcExpressionBinaryOperation*binaryNode = toCalcExpressionBinaryOperation(node);684 return createExpressionNode(createExpressionNode(binaryNode->leftSide(), style), createExpressionNode(binaryNode->rightSide(), style), binaryNode->getOperator());676 auto& binaryNode = toCalcExpressionBinaryOperation(node); 677 return CSSCalcBinaryOperation::create(binaryNode.getOperator(), createCSS(binaryNode.leftSide(), style), createCSS(binaryNode.rightSide(), style)); 685 678 } 686 679 case CalcExpressionNodeBlendLength: { 687 680 // FIXME: (http://webkit.org/b/122036) Create a CSSCalcExpressionNode equivalent of CalcExpressionBlendLength. 688 const CalcExpressionBlendLength* blendNode = toCalcExpressionBlendLength(node); 689 const double progress = blendNode->progress(); 690 const bool isInteger = !progress || (progress == 1); 691 return createExpressionNode( 692 createExpressionNode( 693 createExpressionNode(blendNode->from(), style), 694 createExpressionNode(CSSPrimitiveValue::create(1 - progress, CSSPrimitiveValue::CSS_NUMBER), isInteger), 695 CalcMultiply), 696 createExpressionNode( 697 createExpressionNode(blendNode->to(), style), 698 createExpressionNode(CSSPrimitiveValue::create(progress, CSSPrimitiveValue::CSS_NUMBER), isInteger), 699 CalcMultiply), 700 CalcAdd); 681 auto& blend = toCalcExpressionBlendLength(node); 682 float progress = blend.progress(); 683 return CSSCalcBinaryOperation::create(CalcAdd, createBlendHalf(blend.from(), style, 1 - progress), createBlendHalf(blend.to(), style, progress)); 701 684 } 702 685 case CalcExpressionNodeUndefined: 703 686 ASSERT_NOT_REACHED(); 704 return 0;687 return nullptr; 705 688 } 706 689 ASSERT_NOT_REACHED(); 707 return 0;708 } 709 710 PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(const Length& length, const RenderStyle*style)690 return nullptr; 691 } 692 693 static PassRefPtr<CSSCalcExpressionNode> createCSS(const Length& length, const RenderStyle& style) 711 694 { 712 695 switch (length.type()) { … … 717 700 case ViewportPercentageMax: 718 701 case Fixed: 719 return createExpressionNode(CSSPrimitiveValue::create(length,style), length.value() == trunc(length.value()));702 return CSSCalcPrimitiveValue::create(CSSPrimitiveValue::create(length, &style), length.value() == trunc(length.value())); 720 703 case Calculated: 721 return create ExpressionNode(length.calculationValue()->expression(), style);704 return createCSS(length.calculationValue().expression(), style); 722 705 case Auto: 723 706 case Intrinsic: … … 730 713 case Undefined: 731 714 ASSERT_NOT_REACHED(); 732 return 0;715 return nullptr; 733 716 } 734 717 ASSERT_NOT_REACHED(); 735 return 0;736 } 737 738 PassRefPtr<CSSCalcValue> CSSCalcValue::create(CSSParserString name, CSSParserValueList *parserValueList, CalculationPermittedValueRange range)718 return nullptr; 719 } 720 721 PassRefPtr<CSSCalcValue> CSSCalcValue::create(CSSParserString name, CSSParserValueList& parserValueList, CalculationPermittedValueRange range) 739 722 { 740 723 CSSCalcExpressionNodeParser parser; … … 742 725 743 726 if (equalIgnoringCase(name, "calc(") || equalIgnoringCase(name, "-webkit-calc(")) 744 expression = parser.parseCalc( parserValueList);727 expression = parser.parseCalc(&parserValueList); 745 728 // FIXME: calc (http://webkit.org/b/16662) Add parsing for min and max here 746 729 747 return expression ? adoptRef(new CSSCalcValue(expression, range)) : 0; 748 } 749 750 PassRef<CSSCalcValue> CSSCalcValue::create(PassRefPtr<CSSCalcExpressionNode> expression, CalculationPermittedValueRange range) 751 { 752 return adoptRef(*new CSSCalcValue(expression, range)); 730 return expression ? adoptRef(new CSSCalcValue(expression.releaseNonNull(), range != CalculationRangeAll)) : nullptr; 731 } 732 733 PassRefPtr<CSSCalcValue> CSSCalcValue::create(const CalculationValue& value, const RenderStyle& style) 734 { 735 RefPtr<CSSCalcExpressionNode> expression = createCSS(value.expression(), style); 736 if (!expression) 737 return nullptr; 738 return adoptRef(new CSSCalcValue(expression.releaseNonNull(), value.shouldClampToNonNegative())); 753 739 } 754 740 -
trunk/Source/WebCore/css/CSSCalculationValue.h
r163439 r166860 34 34 #include "CSSParserValues.h" 35 35 #include "CSSPrimitiveValue.h" 36 #include "CSSValue.h"37 36 #include "CalculationValue.h" 38 #include <memory>39 #include <wtf/RefCounted.h>40 #include <wtf/RefPtr.h>41 37 42 38 namespace WebCore { 43 39 44 class CSSParserValueList;45 class CSSValueList;46 class CalculationValue;47 class CalcExpressionNode;48 40 class RenderStyle; 49 struct Length;50 41 51 42 enum CalculationCategory { … … 65 56 }; 66 57 67 virtual ~CSSCalcExpressionNode() = 0;58 virtual ~CSSCalcExpressionNode() { } 68 59 virtual bool isZero() const = 0; 69 virtual std::unique_ptr<CalcExpressionNode> toCalcValue(const RenderStyle*, const RenderStyle* rootStyle, double zoom = 1.0) const = 0;60 virtual std::unique_ptr<CalcExpressionNode> createCalcExpression(const RenderStyle*, const RenderStyle* rootStyle, double zoom = 1.0) const = 0; 70 61 virtual double doubleValue() const = 0; 71 62 virtual double computeLengthPx(const RenderStyle* currentStyle, const RenderStyle* rootStyle, double multiplier = 1.0, bool computingFontSize = false) const = 0; … … 73 64 virtual bool equals(const CSSCalcExpressionNode& other) const { return m_category == other.m_category && m_isInteger == other.m_isInteger; } 74 65 virtual Type type() const = 0; 66 virtual CSSPrimitiveValue::UnitTypes primitiveType() const = 0; 75 67 76 68 CalculationCategory category() const { return m_category; } 77 virtual CSSPrimitiveValue::UnitTypes primitiveType() const = 0;78 69 bool isInteger() const { return m_isInteger; } 79 70 … … 85 76 } 86 77 78 private: 87 79 CalculationCategory m_category; 88 80 bool m_isInteger; … … 91 83 class CSSCalcValue : public CSSValue { 92 84 public: 93 static PassRefPtr<CSSCalcValue> create(CSSParserString name, CSSParserValueList*, CalculationPermittedValueRange); 94 static PassRef<CSSCalcValue> create(PassRefPtr<CSSCalcExpressionNode>, CalculationPermittedValueRange = CalculationRangeAll); 95 static PassRef<CSSCalcValue> create(const CalculationValue* value, const RenderStyle* style) { return adoptRef(*new CSSCalcValue(value, style)); } 85 static PassRefPtr<CSSCalcValue> create(CSSParserString name, CSSParserValueList& arguments, CalculationPermittedValueRange); 86 static PassRefPtr<CSSCalcValue> create(const CalculationValue&, const RenderStyle&); 96 87 97 static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtr<CSSPrimitiveValue>, bool isInteger = false);98 static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtr<CSSCalcExpressionNode>, PassRefPtr<CSSCalcExpressionNode>, CalcOperator);99 static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(const CalcExpressionNode*, const RenderStyle*);100 static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(const Length&, const RenderStyle*);101 102 PassRefPtr<CalculationValue> toCalcValue(const RenderStyle* style, const RenderStyle* rootStyle, double zoom = 1.0) const103 {104 return CalculationValue::create(m_expression->toCalcValue(style, rootStyle, zoom), m_nonNegative ? CalculationRangeNonNegative : CalculationRangeAll);105 }106 88 CalculationCategory category() const { return m_expression->category(); } 107 89 bool isInt() const { return m_expression->isInteger(); } 108 90 double doubleValue() const; 109 91 bool isNegative() const { return m_expression->doubleValue() < 0; } 110 CalculationPermittedValueRange permittedValueRange() { return m_nonNegative ? CalculationRangeNonNegative : CalculationRangeAll; }111 92 double computeLengthPx(const RenderStyle* currentStyle, const RenderStyle* rootStyle, double multiplier = 1.0, bool computingFontSize = false) const; 112 CSSCalcExpressionNode* expressionNode() const { return m_expression.get(); } 93 94 PassRef<CalculationValue> createCalculationValue(const RenderStyle* currentStyle, const RenderStyle* rootStyle, double zoom = 1.0) const; 113 95 114 96 String customCSSText() const; … … 116 98 117 99 private: 118 CSSCalcValue(PassRefPtr<CSSCalcExpressionNode> expression, CalculationPermittedValueRange range) 119 : CSSValue(CalculationClass) 120 , m_expression(expression) 121 , m_nonNegative(range == CalculationRangeNonNegative) 122 { 123 } 124 CSSCalcValue(const CalculationValue* value, const RenderStyle* style) 125 : CSSValue(CalculationClass) 126 , m_expression(createExpressionNode(value->expression(), style)) 127 , m_nonNegative(value->isNonNegative()) 128 { 129 } 100 CSSCalcValue(PassRef<CSSCalcExpressionNode>, bool shouldClampToNonNegative); 130 101 131 102 double clampToPermittedRange(double) const; 132 103 133 const Ref Ptr<CSSCalcExpressionNode> m_expression;134 const bool m_ nonNegative;104 const Ref<CSSCalcExpressionNode> m_expression; 105 const bool m_shouldClampToNonNegative; 135 106 }; 107 108 inline CSSCalcValue::CSSCalcValue(PassRef<CSSCalcExpressionNode> expression, bool shouldClampToNonNegative) 109 : CSSValue(CalculationClass) 110 , m_expression(std::move(expression)) 111 , m_shouldClampToNonNegative(shouldClampToNonNegative) 112 { 113 } 114 115 inline PassRef<CalculationValue> CSSCalcValue::createCalculationValue(const RenderStyle* style, const RenderStyle* rootStyle, double zoom) const 116 { 117 return CalculationValue::create(m_expression->createCalcExpression(style, rootStyle, zoom), 118 m_shouldClampToNonNegative ? CalculationRangeNonNegative : CalculationRangeAll); 119 } 136 120 137 121 CSS_VALUE_TYPE_CASTS(CSSCalcValue, isCalcValue()) -
trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
r166786 r166860 678 678 679 679 if (style->hasOutOfFlowPosition()) { 680 if (l. type() == WebCore::Fixed)680 if (l.isFixed()) 681 681 return zoomAdjustedPixelValue(l.value(), style); 682 elseif (l.isViewportPercentage())682 if (l.isViewportPercentage()) 683 683 return zoomAdjustedPixelValue(valueForLength(l, 0, renderView), style); 684 684 return cssValuePool().createValue(l); -
trunk/Source/WebCore/css/CSSGradientValue.cpp
r166642 r166860 183 183 if (stop.m_position->isLength()) 184 184 length = stop.m_position->computeLength<float>(&style, &rootStyle, style.effectiveZoom()); 185 else 186 length = stop.m_position->cssCalcValue()->toCalcValue(&style, &rootStyle, style.effectiveZoom())->evaluate(gradientLength); 185 else { 186 Ref<CalculationValue> calculationValue { stop.m_position->cssCalcValue()->createCalculationValue(&style, &rootStyle, style.effectiveZoom()) }; 187 length = calculationValue->evaluate(gradientLength); 188 } 187 189 stops[i].offset = (gradientLength > 0) ? length / gradientLength : 0; 188 190 } else { … … 402 404 return value->getFloatValue() / 100.f * edgeDistance; 403 405 404 if (value->isCalculatedPercentageWithLength()) 405 return value->cssCalcValue()->toCalcValue(&style, &rootStyle, style.effectiveZoom())->evaluate(edgeDistance); 406 if (value->isCalculatedPercentageWithLength()) { 407 Ref<CalculationValue> calculationValue { value->cssCalcValue()->createCalculationValue(&style, &rootStyle, style.effectiveZoom()) }; 408 return calculationValue->evaluate(edgeDistance); 409 } 406 410 407 411 switch (value->getValueID()) { -
trunk/Source/WebCore/css/CSSParser.cpp
r166813 r166860 9570 9570 9571 9571 ASSERT(!m_parsedCalculation); 9572 m_parsedCalculation = CSSCalcValue::create(value->function->name, args, range);9572 m_parsedCalculation = CSSCalcValue::create(value->function->name, *args, range); 9573 9573 9574 9574 if (!m_parsedCalculation) -
trunk/Source/WebCore/css/CSSPrimitiveValue.cpp
r166486 r166860 306 306 return; 307 307 case Calculated: { 308 RefPtr<CSSCalcValue> calcValue = CSSCalcValue::create(length.calculationValue() .get(),style);308 RefPtr<CSSCalcValue> calcValue = CSSCalcValue::create(length.calculationValue(), *style); 309 309 init(calcValue.release()); 310 310 return; … … 313 313 case Undefined: 314 314 ASSERT_NOT_REACHED(); 315 break; 316 } 315 return; 316 } 317 ASSERT_NOT_REACHED(); 317 318 } 318 319 … … 329 330 m_primitiveUnitType = CSS_VALUE_ID; 330 331 m_value.valueID = CSSValueAuto; 331 break;332 return; 332 333 case WebCore::Fixed: 333 334 m_primitiveUnitType = CSS_PX; 334 335 m_value.num = length.value(); 335 break;336 return; 336 337 case Intrinsic: 337 338 m_primitiveUnitType = CSS_VALUE_ID; 338 339 m_value.valueID = CSSValueIntrinsic; 339 break;340 return; 340 341 case MinIntrinsic: 341 342 m_primitiveUnitType = CSS_VALUE_ID; 342 343 m_value.valueID = CSSValueMinIntrinsic; 343 break;344 return; 344 345 case MinContent: 345 346 m_primitiveUnitType = CSS_VALUE_ID; 346 347 m_value.valueID = CSSValueWebkitMinContent; 347 break;348 return; 348 349 case MaxContent: 349 350 m_primitiveUnitType = CSS_VALUE_ID; 350 351 m_value.valueID = CSSValueWebkitMaxContent; 351 break;352 return; 352 353 case FillAvailable: 353 354 m_primitiveUnitType = CSS_VALUE_ID; 354 355 m_value.valueID = CSSValueWebkitFillAvailable; 355 break;356 return; 356 357 case FitContent: 357 358 m_primitiveUnitType = CSS_VALUE_ID; 358 359 m_value.valueID = CSSValueWebkitFitContent; 359 break;360 return; 360 361 case Percent: 361 362 m_primitiveUnitType = CSS_PERCENTAGE; 362 363 ASSERT(std::isfinite(length.percent())); 363 364 m_value.num = length.percent(); 364 break;365 return; 365 366 case ViewportPercentageWidth: 366 367 m_primitiveUnitType = CSS_VW; 367 368 m_value.num = length.viewportPercentageLength(); 368 break;369 return; 369 370 case ViewportPercentageHeight: 370 371 m_primitiveUnitType = CSS_VH; 371 372 m_value.num = length.viewportPercentageLength(); 372 break;373 return; 373 374 case ViewportPercentageMin: 374 375 m_primitiveUnitType = CSS_VMIN; 375 376 m_value.num = length.viewportPercentageLength(); 376 break;377 return; 377 378 case ViewportPercentageMax: 378 379 m_primitiveUnitType = CSS_VMAX; 379 380 m_value.num = length.viewportPercentageLength(); 380 break;381 return; 381 382 case Calculated: 382 383 case Relative: 383 384 case Undefined: 384 385 ASSERT_NOT_REACHED(); 385 break; 386 } 386 return; 387 } 388 ASSERT_NOT_REACHED(); 387 389 } 388 390 -
trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h
r166618 r166860 4647 4647 return Length(Auto); 4648 4648 if ((supported & CalculatedConversion) && isCalculated()) 4649 return Length(cssCalcValue()-> toCalcValue(style, rootStyle, multiplier));4649 return Length(cssCalcValue()->createCalculationValue(style, rootStyle, multiplier)); 4650 4650 if ((supported & ViewportPercentageConversion) && isViewportPercentageLength()) 4651 4651 return viewportPercentageLength(); -
trunk/Source/WebCore/css/CSSToStyleMap.cpp
r157024 r166860 252 252 length = Length(primitiveValue->getDoubleValue(), Percent); 253 253 else if (primitiveValue->isCalculatedPercentageWithLength()) 254 length = Length(primitiveValue->cssCalcValue()-> toCalcValue(style(), rootElementStyle(), zoomFactor));254 length = Length(primitiveValue->cssCalcValue()->createCalculationValue(style(), rootElementStyle(), zoomFactor)); 255 255 else if (primitiveValue->isViewportPercentageLength()) 256 256 length = primitiveValue->viewportPercentageLength(); … … 288 288 length = Length(primitiveValue->getDoubleValue(), Percent); 289 289 else if (primitiveValue->isCalculatedPercentageWithLength()) 290 length = Length(primitiveValue->cssCalcValue()-> toCalcValue(style(), rootElementStyle(), zoomFactor));290 length = Length(primitiveValue->cssCalcValue()->createCalculationValue(style(), rootElementStyle(), zoomFactor)); 291 291 else if (primitiveValue->isViewportPercentageLength()) 292 292 length = primitiveValue->viewportPercentageLength(); -
trunk/Source/WebCore/css/CSSToStyleMap.h
r166138 r166860 24 24 25 25 #include "CSSPropertyNames.h" 26 #include "LengthBox.h"27 26 #include <wtf/FastMalloc.h> 28 27 #include <wtf/Noncopyable.h> … … 30 29 namespace WebCore { 31 30 31 class Animation; 32 class CSSValue; 32 33 class FillLayer; 33 class CSSValue;34 class Animation;35 34 class RenderStyle; 36 35 class StyleImage; 37 36 class StyleResolver; 38 37 class NinePieceImage; 38 39 struct LengthBox; 39 40 40 41 class CSSToStyleMap { -
trunk/Source/WebCore/css/DeprecatedStyleBuilder.cpp
r166786 r166860 389 389 else if (primitiveValue->isLength()) { 390 390 Length length = primitiveValue->computeLength<Length>(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom()); 391 length.set Quirk(primitiveValue->isQuirkValue());391 length.setHasQuirk(primitiveValue->isQuirkValue()); 392 392 setValue(styleResolver->style(), length); 393 393 } else if (primitiveValue->isPercentage()) 394 394 setValue(styleResolver->style(), Length(primitiveValue->getDoubleValue(), Percent)); 395 395 else if (primitiveValue->isCalculatedPercentageWithLength()) 396 setValue(styleResolver->style(), Length(primitiveValue->cssCalcValue()-> toCalcValue(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom())));396 setValue(styleResolver->style(), Length(primitiveValue->cssCalcValue()->createCalculationValue(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom()))); 397 397 else if (primitiveValue->isViewportPercentageLength()) 398 398 setValue(styleResolver->style(), primitiveValue->viewportPercentageLength()); … … 450 450 radiusWidth = Length(styleResolver->viewportPercentageValue(*pair->first(), pair->first()->getIntValue()), Fixed); 451 451 else if (pair->first()->isCalculatedPercentageWithLength()) 452 radiusWidth = Length( (pair->first()->cssCalcValue()->toCalcValue(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom())));452 radiusWidth = Length(pair->first()->cssCalcValue()->createCalculationValue(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom())); 453 453 else 454 454 radiusWidth = pair->first()->computeLength<Length>(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom()); … … 458 458 radiusHeight = Length(styleResolver->viewportPercentageValue(*pair->second(), pair->second()->getIntValue()), Fixed); 459 459 else if (pair->second()->isCalculatedPercentageWithLength()) 460 radiusHeight = Length( (pair->second()->cssCalcValue()->toCalcValue(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom())));460 radiusHeight = Length(pair->second()->cssCalcValue()->createCalculationValue(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom())); 461 461 else 462 462 radiusHeight = pair->second()->computeLength<Length>(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom()); … … 884 884 else if (primitiveValue->isPercentage()) 885 885 size = (primitiveValue->getFloatValue() * parentSize) / 100.0f; 886 else if (primitiveValue->isCalculatedPercentageWithLength()) 887 size = primitiveValue->cssCalcValue()->toCalcValue(styleResolver->parentStyle(), styleResolver->rootElementStyle())->evaluate(parentSize); 888 else if (primitiveValue->isViewportPercentageLength()) 886 else if (primitiveValue->isCalculatedPercentageWithLength()) { 887 Ref<CalculationValue> calculationValue { primitiveValue->cssCalcValue()->createCalculationValue(styleResolver->parentStyle(), styleResolver->rootElementStyle()) }; 888 size = calculationValue->evaluate(parentSize); 889 } else if (primitiveValue->isViewportPercentageLength()) 889 890 size = valueForLength(primitiveValue->viewportPercentageLength(), 0, styleResolver->document().renderView()); 890 891 else -
trunk/Source/WebCore/css/LengthFunctions.cpp
r164697 r166860 123 123 switch (length.type()) { 124 124 case Fixed: 125 return length. getFloatValue();125 return length.value(); 126 126 case Percent: 127 127 return static_cast<float>(maximumValue * length.percent() / 100.0f); … … 169 169 switch (length.type()) { 170 170 case Fixed: 171 return length. getFloatValue();171 return length.value(); 172 172 case Percent: 173 173 return static_cast<float>(maximumValue * length.percent() / 100.0f); -
trunk/Source/WebCore/css/StyleResolver.cpp
r166741 r166860 1042 1042 1043 1043 // FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed. 1044 // FIXME: Using " quirk" to decide the margin wasn't set is kind of lame.1044 // FIXME: Using "hasQuirk" to decide the margin wasn't set is kind of lame. 1045 1045 if (style.width().isIntrinsicOrAuto()) { 1046 if (style.marginLeft(). quirk())1046 if (style.marginLeft().hasQuirk()) 1047 1047 style.setMarginLeft(Length(intrinsicMargin, Fixed)); 1048 if (style.marginRight(). quirk())1048 if (style.marginRight().hasQuirk()) 1049 1049 style.setMarginRight(Length(intrinsicMargin, Fixed)); 1050 1050 } 1051 1051 1052 1052 if (style.height().isAuto()) { 1053 if (style.marginTop(). quirk())1053 if (style.marginTop().hasQuirk()) 1054 1054 style.setMarginTop(Length(intrinsicMargin, Fixed)); 1055 if (style.marginBottom(). quirk())1055 if (style.marginBottom().hasQuirk()) 1056 1056 style.setMarginBottom(Length(intrinsicMargin, Fixed)); 1057 1057 } … … 1861 1861 1862 1862 if (primitiveValue->isLength()) 1863 workingLength.length().set Quirk(primitiveValue->isQuirkValue());1863 workingLength.length().setHasQuirk(primitiveValue->isQuirkValue()); 1864 1864 1865 1865 return true; -
trunk/Source/WebCore/platform/CalculationValue.cpp
r163439 r166860 1 1 /* 2 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2014 Apple Inc. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 36 37 namespace WebCore { 37 38 39 PassRef<CalculationValue> CalculationValue::create(std::unique_ptr<CalcExpressionNode> value, CalculationPermittedValueRange range) 40 { 41 return adoptRef(*new CalculationValue(std::move(value), range)); 42 } 43 44 float CalcExpressionNumber::evaluate(float) const 45 { 46 return m_value; 47 } 48 49 bool CalcExpressionNumber::operator==(const CalcExpressionNode& other) const 50 { 51 return other.type() == CalcExpressionNodeNumber && *this == toCalcExpressionNumber(other); 52 } 53 54 float CalculationValue::evaluate(float maxValue) const 55 { 56 float result = m_expression->evaluate(maxValue); 57 // FIXME: This test was originally needed when we did not detect division by zero at parse time. 58 // It's possible that this is now unneeded code and can be removed. 59 if (std::isnan(result)) 60 return 0; 61 return m_shouldClampToNonNegative && result < 0 ? 0 : result; 62 } 63 38 64 float CalcExpressionBinaryOperation::evaluate(float maxValue) const 39 65 { … … 56 82 } 57 83 58 PassRefPtr<CalculationValue> CalculationValue::create(std::unique_ptr<CalcExpressionNode> value, CalculationPermittedValueRange range) 84 bool CalcExpressionBinaryOperation::operator==(const CalcExpressionNode& other) const 59 85 { 60 return adoptRef(new CalculationValue(std::move(value), range));86 return other.type() == CalcExpressionNodeBinaryOperation && *this == toCalcExpressionBinaryOperation(other); 61 87 } 62 88 63 float Calc ulationValue::evaluate(float maxValue) const89 float CalcExpressionLength::evaluate(float maxValue) const 64 90 { 65 float result = m_value->evaluate(maxValue); 66 // FIXME calc https://webkit.org/b/80411 : result is NaN when there is a division 67 // by zero which isn't found at parse time. 68 if (std::isnan(result)) 69 return 0; 70 return m_isNonNegative && result < 0 ? 0 : result; 91 return floatValueForLength(m_length, maxValue); 92 } 93 94 bool CalcExpressionLength::operator==(const CalcExpressionNode& other) const 95 { 96 return other.type() == CalcExpressionNodeLength && *this == toCalcExpressionLength(other); 97 } 98 99 float CalcExpressionBlendLength::evaluate(float maxValue) const 100 { 101 return (1.0f - m_progress) * floatValueForLength(m_from, maxValue) + m_progress * floatValueForLength(m_to, maxValue); 102 } 103 104 bool CalcExpressionBlendLength::operator==(const CalcExpressionNode& other) const 105 { 106 return other.type() == CalcExpressionNodeBlendLength && *this == toCalcExpressionBlendLength(other); 71 107 } 72 108 -
trunk/Source/WebCore/platform/CalculationValue.h
r163439 r166860 63 63 WTF_MAKE_FAST_ALLOCATED; 64 64 public: 65 CalcExpressionNode() 66 : m_type(CalcExpressionNodeUndefined) 67 { 68 } 69 70 virtual ~CalcExpressionNode() 71 { 72 } 65 explicit CalcExpressionNode(CalcExpressionNodeType = CalcExpressionNodeUndefined); 66 virtual ~CalcExpressionNode() { } 67 68 CalcExpressionNodeType type() const { return m_type; } 73 69 74 70 virtual float evaluate(float maxValue) const = 0; 75 71 virtual bool operator==(const CalcExpressionNode&) const = 0; 76 72 77 CalcExpressionNodeType type() const { return m_type; } 78 79 protected: 73 private: 80 74 CalcExpressionNodeType m_type; 81 75 }; 82 76 83 class CalculationValue : public RefCounted<CalculationValue> { 84 public: 85 static PassRefPtr<CalculationValue> create(std::unique_ptr<CalcExpressionNode> value, CalculationPermittedValueRange); 86 float evaluate(float maxValue) const; 87 88 bool operator==(const CalculationValue& o) const 89 { 90 return *(m_value.get()) == *(o.m_value.get()); 91 } 92 93 bool isNonNegative() const { return m_isNonNegative; } 94 const CalcExpressionNode* expression() const { return m_value.get(); } 95 96 private: 97 CalculationValue(std::unique_ptr<CalcExpressionNode> value, CalculationPermittedValueRange range) 98 : m_value(std::move(value)) 99 , m_isNonNegative(range == CalculationRangeNonNegative) 100 { 101 } 102 103 std::unique_ptr<CalcExpressionNode> m_value; 104 bool m_isNonNegative; 105 }; 106 107 class CalcExpressionNumber : public CalcExpressionNode { 108 public: 109 explicit CalcExpressionNumber(float value) 110 : m_value(value) 111 { 112 m_type = CalcExpressionNodeNumber; 113 } 114 115 bool operator==(const CalcExpressionNumber& o) const 116 { 117 return m_value == o.m_value; 118 } 119 120 virtual bool operator==(const CalcExpressionNode& o) const override 121 { 122 return type() == o.type() && *this == static_cast<const CalcExpressionNumber&>(o); 123 } 124 125 virtual float evaluate(float) const override 126 { 127 return m_value; 128 } 77 class CalcExpressionNumber final : public CalcExpressionNode { 78 public: 79 explicit CalcExpressionNumber(float); 129 80 130 81 float value() const { return m_value; } 131 82 132 83 private: 84 virtual float evaluate(float) const override; 85 virtual bool operator==(const CalcExpressionNode&) const override; 86 133 87 float m_value; 134 88 }; 135 89 136 inline const CalcExpressionNumber* toCalcExpressionNumber(const CalcExpressionNode* value) 137 { 138 ASSERT_WITH_SECURITY_IMPLICATION(!value || value->type() == CalcExpressionNodeNumber); 139 return static_cast<const CalcExpressionNumber*>(value); 140 } 141 142 class CalcExpressionLength : public CalcExpressionNode { 143 public: 144 explicit CalcExpressionLength(Length length) 145 : m_length(length) 146 { 147 m_type = CalcExpressionNodeLength; 148 } 149 150 bool operator==(const CalcExpressionLength& o) const 151 { 152 return m_length == o.m_length; 153 } 154 155 virtual bool operator==(const CalcExpressionNode& o) const override 156 { 157 return type() == o.type() && *this == static_cast<const CalcExpressionLength&>(o); 158 } 159 160 virtual float evaluate(float maxValue) const override 161 { 162 return floatValueForLength(m_length, maxValue); 163 } 90 class CalcExpressionLength final : public CalcExpressionNode { 91 public: 92 explicit CalcExpressionLength(Length); 164 93 165 94 const Length& length() const { return m_length; } 166 95 167 96 private: 97 virtual float evaluate(float maxValue) const override; 98 virtual bool operator==(const CalcExpressionNode&) const override; 99 168 100 Length m_length; 169 101 }; 170 102 171 inline const CalcExpressionLength* toCalcExpressionLength(const CalcExpressionNode* value) 172 { 173 ASSERT_WITH_SECURITY_IMPLICATION(!value || value->type() == CalcExpressionNodeLength); 174 return static_cast<const CalcExpressionLength*>(value); 175 } 176 177 class CalcExpressionBinaryOperation : public CalcExpressionNode { 178 public: 179 CalcExpressionBinaryOperation(std::unique_ptr<CalcExpressionNode> leftSide, std::unique_ptr<CalcExpressionNode> rightSide, CalcOperator op) 180 : m_leftSide(std::move(leftSide)) 181 , m_rightSide(std::move(rightSide)) 182 , m_operator(op) 183 { 184 m_type = CalcExpressionNodeBinaryOperation; 185 } 186 187 bool operator==(const CalcExpressionBinaryOperation& o) const 188 { 189 return m_operator == o.m_operator && *m_leftSide == *o.m_leftSide && *m_rightSide == *o.m_rightSide; 190 } 191 192 virtual bool operator==(const CalcExpressionNode& o) const override 193 { 194 return type() == o.type() && *this == static_cast<const CalcExpressionBinaryOperation&>(o); 195 } 196 197 virtual float evaluate(float) const override; 198 199 const CalcExpressionNode* leftSide() const { return m_leftSide.get(); } 200 const CalcExpressionNode* rightSide() const { return m_rightSide.get(); } 103 class CalcExpressionBinaryOperation final : public CalcExpressionNode { 104 public: 105 CalcExpressionBinaryOperation(std::unique_ptr<CalcExpressionNode> leftSide, std::unique_ptr<CalcExpressionNode> rightSide, CalcOperator); 106 107 const CalcExpressionNode& leftSide() const { return *m_leftSide; } 108 const CalcExpressionNode& rightSide() const { return *m_rightSide; } 201 109 CalcOperator getOperator() const { return m_operator; } 202 110 203 111 private: 112 virtual float evaluate(float maxValue) const override; 113 virtual bool operator==(const CalcExpressionNode&) const override; 114 204 115 std::unique_ptr<CalcExpressionNode> m_leftSide; 205 116 std::unique_ptr<CalcExpressionNode> m_rightSide; … … 207 118 }; 208 119 209 inline const CalcExpressionBinaryOperation* toCalcExpressionBinaryOperation(const CalcExpressionNode* value) 210 { 211 ASSERT_WITH_SECURITY_IMPLICATION(!value || value->type() == CalcExpressionNodeBinaryOperation); 212 return static_cast<const CalcExpressionBinaryOperation*>(value); 213 } 214 215 class CalcExpressionBlendLength : public CalcExpressionNode { 216 public: 217 CalcExpressionBlendLength(Length from, Length to, float progress) 218 : m_from(from) 219 , m_to(to) 220 , m_progress(progress) 221 { 222 m_type = CalcExpressionNodeBlendLength; 223 } 224 225 bool operator==(const CalcExpressionBlendLength& o) const 226 { 227 return m_progress == o.m_progress && m_from == o.m_from && m_to == o.m_to; 228 } 229 230 virtual bool operator==(const CalcExpressionNode& o) const override 231 { 232 return type() == o.type() && *this == static_cast<const CalcExpressionBlendLength&>(o); 233 } 234 235 virtual float evaluate(float maxValue) const override 236 { 237 return (1.0f - m_progress) * floatValueForLength(m_from, maxValue) + m_progress * floatValueForLength(m_to, maxValue); 238 } 120 class CalcExpressionBlendLength final : public CalcExpressionNode { 121 public: 122 CalcExpressionBlendLength(Length from, Length to, float progress); 239 123 240 124 const Length& from() const { return m_from; } … … 243 127 244 128 private: 129 virtual float evaluate(float maxValue) const override; 130 virtual bool operator==(const CalcExpressionNode&) const override; 131 245 132 Length m_from; 246 133 Length m_to; … … 248 135 }; 249 136 250 inline const CalcExpressionBlendLength* toCalcExpressionBlendLength(const CalcExpressionNode* value) 251 { 252 ASSERT_WITH_SECURITY_IMPLICATION(!value || value->type() == CalcExpressionNodeBlendLength); 253 return static_cast<const CalcExpressionBlendLength*>(value); 137 class CalculationValue : public RefCounted<CalculationValue> { 138 public: 139 static PassRef<CalculationValue> create(std::unique_ptr<CalcExpressionNode>, CalculationPermittedValueRange); 140 float evaluate(float maxValue) const; 141 142 bool shouldClampToNonNegative() const { return m_shouldClampToNonNegative; } 143 const CalcExpressionNode& expression() const { return *m_expression; } 144 145 private: 146 CalculationValue(std::unique_ptr<CalcExpressionNode>, CalculationPermittedValueRange); 147 148 std::unique_ptr<CalcExpressionNode> m_expression; 149 bool m_shouldClampToNonNegative; 150 }; 151 152 inline CalcExpressionNode::CalcExpressionNode(CalcExpressionNodeType type) 153 : m_type(type) 154 { 155 } 156 157 inline CalculationValue::CalculationValue(std::unique_ptr<CalcExpressionNode> expression, CalculationPermittedValueRange range) 158 : m_expression(std::move(expression)) 159 , m_shouldClampToNonNegative(range == CalculationRangeNonNegative) 160 { 161 } 162 163 inline bool operator==(const CalculationValue& a, const CalculationValue& b) 164 { 165 return a.expression() == b.expression(); 166 } 167 168 inline CalcExpressionNumber::CalcExpressionNumber(float value) 169 : CalcExpressionNode(CalcExpressionNodeNumber) 170 , m_value(value) 171 { 172 } 173 174 inline bool operator==(const CalcExpressionNumber& a, const CalcExpressionNumber& b) 175 { 176 return a.value() == b.value(); 177 } 178 179 inline const CalcExpressionNumber& toCalcExpressionNumber(const CalcExpressionNode& value) 180 { 181 ASSERT_WITH_SECURITY_IMPLICATION(value.type() == CalcExpressionNodeNumber); 182 return static_cast<const CalcExpressionNumber&>(value); 183 } 184 185 inline CalcExpressionLength::CalcExpressionLength(Length length) 186 : CalcExpressionNode(CalcExpressionNodeLength) 187 , m_length(length) 188 { 189 } 190 191 inline bool operator==(const CalcExpressionLength& a, const CalcExpressionLength& b) 192 { 193 return a.length() == b.length(); 194 } 195 196 inline const CalcExpressionLength& toCalcExpressionLength(const CalcExpressionNode& value) 197 { 198 ASSERT_WITH_SECURITY_IMPLICATION(value.type() == CalcExpressionNodeLength); 199 return static_cast<const CalcExpressionLength&>(value); 200 } 201 202 inline CalcExpressionBinaryOperation::CalcExpressionBinaryOperation(std::unique_ptr<CalcExpressionNode> leftSide, std::unique_ptr<CalcExpressionNode> rightSide, CalcOperator op) 203 : CalcExpressionNode(CalcExpressionNodeBinaryOperation) 204 , m_leftSide(std::move(leftSide)) 205 , m_rightSide(std::move(rightSide)) 206 , m_operator(op) 207 { 208 } 209 210 inline bool operator==(const CalcExpressionBinaryOperation& a, const CalcExpressionBinaryOperation& b) 211 { 212 return a.getOperator() == b.getOperator() && a.leftSide() == b.leftSide() && a.rightSide() == b.rightSide(); 213 } 214 215 inline const CalcExpressionBinaryOperation& toCalcExpressionBinaryOperation(const CalcExpressionNode& value) 216 { 217 ASSERT_WITH_SECURITY_IMPLICATION(value.type() == CalcExpressionNodeBinaryOperation); 218 return static_cast<const CalcExpressionBinaryOperation&>(value); 219 } 220 221 inline CalcExpressionBlendLength::CalcExpressionBlendLength(Length from, Length to, float progress) 222 : CalcExpressionNode(CalcExpressionNodeBlendLength) 223 , m_from(from) 224 , m_to(to) 225 , m_progress(progress) 226 { 227 } 228 229 inline bool operator==(const CalcExpressionBlendLength& a, const CalcExpressionBlendLength& b) 230 { 231 return a.progress() == b.progress() && a.from() == b.from() && a.to() == b.to(); 232 } 233 234 inline const CalcExpressionBlendLength& toCalcExpressionBlendLength(const CalcExpressionNode& value) 235 { 236 ASSERT_WITH_SECURITY_IMPLICATION(value.type() == CalcExpressionNodeBlendLength); 237 return static_cast<const CalcExpressionBlendLength&>(value); 254 238 } 255 239 -
trunk/Source/WebCore/platform/Length.cpp
r165848 r166860 3 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 4 4 * (C) 2001 Dirk Mueller ( mueller@kde.org ) 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved. 6 6 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) 7 7 * … … 28 28 #include "CalculationValue.h" 29 29 #include <wtf/ASCIICType.h> 30 #include <wtf/Assertions.h> 30 #include <wtf/HashMap.h> 31 #include <wtf/NeverDestroyed.h> 31 32 #include <wtf/StdLibExtras.h> 32 33 #include <wtf/text/StringBuffer.h> … … 152 153 return r; 153 154 } 154 155 class CalculationValueHandleMap { 156 WTF_MAKE_FAST_ALLOCATED; 155 156 class CalculationValueMap { 157 157 public: 158 CalculationValueHandleMap() 159 : m_index(1) 160 { 161 } 158 CalculationValueMap(); 159 160 unsigned insert(PassRef<CalculationValue>); 161 void ref(unsigned handle); 162 void deref(unsigned handle); 163 164 CalculationValue& get(unsigned handle) const; 165 166 private: 167 struct Entry { 168 uint64_t referenceCountMinusOne; 169 CalculationValue* value; 170 Entry(); 171 Entry(CalculationValue&); 172 }; 173 174 unsigned m_nextAvailableHandle; 175 HashMap<unsigned, Entry> m_map; 176 }; 177 178 inline CalculationValueMap::Entry::Entry() 179 : referenceCountMinusOne(0) 180 , value(nullptr) 181 { 182 } 183 184 inline CalculationValueMap::Entry::Entry(CalculationValue& value) 185 : referenceCountMinusOne(0) 186 , value(&value) 187 { 188 } 189 190 inline CalculationValueMap::CalculationValueMap() 191 : m_nextAvailableHandle(1) 192 { 193 } 162 194 163 int insert(PassRefPtr<CalculationValue> calcValue) 164 { 165 ASSERT(m_index); 166 // FIXME calc(): https://bugs.webkit.org/show_bug.cgi?id=80489 167 // This monotonically increasing handle generation scheme is potentially wasteful 168 // of the handle space. Consider reusing empty handles. 169 while (m_map.contains(m_index)) 170 m_index++; 171 172 m_map.set(m_index, calcValue); 173 174 return m_index; 175 } 176 177 void remove(int index) 178 { 179 ASSERT(m_map.contains(index)); 180 m_map.remove(index); 181 } 182 183 void remove(HashMap<int, RefPtr<CalculationValue>>::iterator it) 184 { 185 ASSERT(it != m_map.end()); 186 m_map.remove(it); 187 } 188 189 PassRefPtr<CalculationValue> get(int index) 190 { 191 ASSERT(m_map.contains(index)); 192 return m_map.get(index); 193 } 194 195 HashMap<int, RefPtr<CalculationValue>>::iterator find(int index) 196 { 197 ASSERT(m_map.contains(index)); 198 return m_map.find(index); 199 } 200 201 private: 202 int m_index; 203 HashMap<int, RefPtr<CalculationValue>> m_map; 204 }; 205 206 static CalculationValueHandleMap& calcHandles() 207 { 208 DEPRECATED_DEFINE_STATIC_LOCAL(CalculationValueHandleMap, handleMap, ()); 209 return handleMap; 210 } 211 212 Length::Length(PassRefPtr<CalculationValue> calc) 213 : m_quirk(false) 195 inline unsigned CalculationValueMap::insert(PassRef<CalculationValue> value) 196 { 197 ASSERT(m_nextAvailableHandle); 198 199 // The leakRef below is balanced by the deref in the deref member function. 200 Entry leakedValue = value.leakRef(); 201 202 // FIXME: This monotonically increasing handle generation scheme is potentially wasteful 203 // of the handle space. Consider reusing empty handles. https://bugs.webkit.org/show_bug.cgi?id=80489 204 while (!m_map.isValidKey(m_nextAvailableHandle) || !m_map.add(m_nextAvailableHandle, leakedValue).isNewEntry) 205 ++m_nextAvailableHandle; 206 207 return m_nextAvailableHandle++; 208 } 209 210 inline CalculationValue& CalculationValueMap::get(unsigned handle) const 211 { 212 ASSERT(m_map.contains(handle)); 213 214 return *m_map.find(handle)->value.value; 215 } 216 217 inline void CalculationValueMap::ref(unsigned handle) 218 { 219 ASSERT(m_map.contains(handle)); 220 221 ++m_map.find(handle)->value.referenceCountMinusOne; 222 } 223 224 inline void CalculationValueMap::deref(unsigned handle) 225 { 226 ASSERT(m_map.contains(handle)); 227 228 auto it = m_map.find(handle); 229 if (it->value.referenceCountMinusOne) { 230 --it->value.referenceCountMinusOne; 231 return; 232 } 233 234 // The deref below is balanced by the leakRef in the insert member function. 235 it->value.value->deref(); 236 m_map.remove(it); 237 } 238 239 static CalculationValueMap& calculationValues() 240 { 241 static NeverDestroyed<CalculationValueMap> map; 242 return map; 243 } 244 245 Length::Length(PassRef<CalculationValue> value) 246 : m_hasQuirk(false) 214 247 , m_type(Calculated) 215 248 , m_isFloat(false) 216 249 { 217 m_ intValue = calcHandles().insert(calc);250 m_calculationValueHandle = calculationValues().insert(std::move(value)); 218 251 } 219 252 … … 229 262 return Length(CalculationValue::create(std::move(blend), CalculationRangeAll)); 230 263 } 231 232 PassRefPtr<CalculationValue>Length::calculationValue() const264 265 CalculationValue& Length::calculationValue() const 233 266 { 234 267 ASSERT(isCalculated()); 235 return calc Handles().get(calculationHandle());268 return calculationValues().get(m_calculationValueHandle); 236 269 } 237 270 238 void Length:: incrementCalculatedRef() const271 void Length::ref() const 239 272 { 240 273 ASSERT(isCalculated()); 241 calculationValue ()->ref();242 } 243 244 void Length::de crementCalculatedRef() const274 calculationValues().ref(m_calculationValueHandle); 275 } 276 277 void Length::deref() const 245 278 { 246 279 ASSERT(isCalculated()); 247 auto it = calcHandles().find(calculationHandle()); 248 if (it->value->hasOneRef()) 249 calcHandles().remove(it); 280 calculationValues().deref(m_calculationValueHandle); 250 281 } 251 282 … … 253 284 { 254 285 ASSERT(isCalculated()); 255 float result = calculationValue() ->evaluate(maxValue);286 float result = calculationValue().evaluate(maxValue); 256 287 if (std::isnan(result)) 257 288 return 0; … … 259 290 } 260 291 261 bool Length::isCalculatedEqual(const Length& o ) const262 { 263 return isCalculated() && (calculationValue() == o.calculationValue() || *calculationValue() == *o.calculationValue());292 bool Length::isCalculatedEqual(const Length& other) const 293 { 294 return calculationValue() == other.calculationValue(); 264 295 } 265 296 -
trunk/Source/WebCore/platform/Length.h
r156132 r166860 1 1 /* 2 2 Copyright (C) 1999 Lars Knoll (knoll@kde.org) 3 Copyright (C) 2006, 2008 Apple Inc. All rights reserved.3 Copyright (C) 2006, 2008, 2014 Apple Inc. All rights reserved. 4 4 Copyright (C) 2011 Rik Cabanier (cabanier@adobe.com) 5 5 Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved. … … 30 30 #include <wtf/FastMalloc.h> 31 31 #include <wtf/Forward.h> 32 #include <wtf/HashMap.h>33 #include <wtf/MathExtras.h>34 32 35 33 namespace WebCore { … … 49 47 WTF_MAKE_FAST_ALLOCATED; 50 48 public: 51 Length() 52 : m_intValue(0), m_quirk(false), m_type(Auto), m_isFloat(false) 53 { 54 } 55 56 Length(LengthType t) 57 : m_intValue(0), m_quirk(false), m_type(t), m_isFloat(false) 58 { 59 ASSERT(t != Calculated); 60 } 61 62 Length(int v, LengthType t, bool q = false) 63 : m_intValue(v), m_quirk(q), m_type(t), m_isFloat(false) 64 { 65 ASSERT(t != Calculated); 66 } 67 68 Length(LayoutUnit v, LengthType t, bool q = false) 69 : m_floatValue(v.toFloat()), m_quirk(q), m_type(t), m_isFloat(true) 70 { 71 ASSERT(t != Calculated); 72 } 73 74 Length(float v, LengthType t, bool q = false) 75 : m_floatValue(v), m_quirk(q), m_type(t), m_isFloat(true) 76 { 77 ASSERT(t != Calculated); 78 } 79 80 Length(double v, LengthType t, bool q = false) 81 : m_quirk(q), m_type(t), m_isFloat(true) 82 { 83 m_floatValue = static_cast<float>(v); 84 } 85 86 explicit Length(PassRefPtr<CalculationValue>); 87 88 Length(const Length& length) 89 { 90 initFromLength(length); 91 } 92 93 Length(Length&& other) 94 { 95 moveFromLength(std::move(other)); 96 } 97 98 Length& operator=(const Length& length) 99 { 100 initFromLength(length); 101 return *this; 102 } 103 104 Length& operator=(Length&& other) 105 { 106 if (this != &other) 107 moveFromLength(std::move(other)); 108 return *this; 109 } 110 111 ~Length() 112 { 113 if (isCalculated()) 114 decrementCalculatedRef(); 115 } 116 117 bool operator==(const Length& o) const { return (m_type == o.m_type) && (m_quirk == o.m_quirk) && (isUndefined() || (getFloatValue() == o.getFloatValue()) || isCalculatedEqual(o)); } 118 bool operator!=(const Length& o) const { return !(*this == o); } 119 120 const Length& operator*=(float v) 121 { 122 if (isCalculated()) { 123 ASSERT_NOT_REACHED(); 124 return *this; 125 } 126 127 if (m_isFloat) 128 m_floatValue = static_cast<float>(m_floatValue * v); 129 else 130 m_intValue = static_cast<int>(m_intValue * v); 131 132 return *this; 133 } 134 135 inline float value() const 136 { 137 return getFloatValue(); 138 } 139 140 int intValue() const 141 { 142 if (isCalculated()) { 143 ASSERT_NOT_REACHED(); 144 return 0; 145 } 146 return getIntValue(); 147 } 148 149 float percent() const 150 { 151 ASSERT(isPercent()); 152 return getFloatValue(); 153 } 154 155 PassRefPtr<CalculationValue> calculationValue() const; 156 157 LengthType type() const { return static_cast<LengthType>(m_type); } 158 bool quirk() const { return m_quirk; } 159 160 void setQuirk(bool quirk) 161 { 162 m_quirk = quirk; 163 } 164 165 void setValue(LengthType t, int value) 166 { 167 m_type = t; 168 m_intValue = value; 169 m_isFloat = false; 170 } 171 172 void setValue(int value) 173 { 174 if (isCalculated()) { 175 ASSERT_NOT_REACHED(); 176 return; 177 } 178 setValue(Fixed, value); 179 } 180 181 void setValue(LengthType t, float value) 182 { 183 m_type = t; 184 m_floatValue = value; 185 m_isFloat = true; 186 } 187 188 void setValue(LengthType t, LayoutUnit value) 189 { 190 m_type = t; 191 m_floatValue = value; 192 m_isFloat = true; 193 } 194 195 void setValue(float value) 196 { 197 *this = Length(value, Fixed); 198 } 199 200 bool isUndefined() const { return type() == Undefined; } 201 202 // FIXME calc: https://bugs.webkit.org/show_bug.cgi?id=80357. A calculated Length 49 Length(LengthType = Auto); 50 51 Length(int value, LengthType, bool hasQuirk = false); 52 Length(LayoutUnit value, LengthType, bool hasQuirk = false); 53 Length(float value, LengthType, bool hasQuirk = false); 54 Length(double value, LengthType, bool hasQuirk = false); 55 56 explicit Length(PassRef<CalculationValue>); 57 58 Length(const Length&); 59 Length(Length&&); 60 Length& operator=(const Length&); 61 Length& operator=(Length&&); 62 63 ~Length(); 64 65 void setValue(LengthType, int value); 66 void setValue(LengthType, float value); 67 void setValue(LengthType, LayoutUnit value); 68 Length& operator*=(float); 69 70 void setHasQuirk(bool); 71 72 bool operator==(const Length&) const; 73 bool operator!=(const Length&) const; 74 75 float value() const; 76 int intValue() const; 77 float percent() const; 78 float viewportPercentageLength() const; 79 CalculationValue& calculationValue() const; 80 81 LengthType type() const; 82 83 bool isAuto() const; 84 bool isFixed() const; 85 bool isMaxContent() const; 86 bool isMinContent() const; 87 bool isRelative() const; 88 bool isUndefined() const; 89 90 bool hasQuirk() const; 91 92 // FIXME calc: https://bugs.webkit.org/show_bug.cgi?id=80357. A calculated Length 203 93 // always contains a percentage, and without a maxValue passed to these functions 204 // it's impossible to determine the sign or zero-ness. We assume all calc values 205 // are positive and non-zero for now. 206 bool isZero() const 207 { 208 ASSERT(!isUndefined()); 209 if (isCalculated()) 210 return false; 211 212 return m_isFloat ? !m_floatValue : !m_intValue; 213 } 214 bool isPositive() const 215 { 216 if (isUndefined()) 217 return false; 218 if (isCalculated()) 219 return true; 220 221 return getFloatValue() > 0; 222 } 223 bool isNegative() const 224 { 225 if (isUndefined() || isCalculated()) 226 return false; 227 228 return getFloatValue() < 0; 229 } 230 231 bool isAuto() const { return type() == Auto; } 232 bool isRelative() const { return type() == Relative; } 233 bool isPercent() const { return type() == Percent || type() == Calculated; } 234 bool isFixed() const { return type() == Fixed; } 235 bool isIntrinsicOrAuto() const { return type() == Auto || isLegacyIntrinsic() || isIntrinsic(); } 236 bool isLegacyIntrinsic() const { return type() == Intrinsic || type() == MinIntrinsic; } 237 bool isIntrinsic() const { return type() == MinContent || type() == MaxContent || type() == FillAvailable || type() == FitContent; } 238 bool isSpecified() const { return type() == Fixed || type() == Percent || type() == Calculated || isViewportPercentage(); } 239 bool isSpecifiedOrIntrinsic() const { return isSpecified() || isIntrinsic(); } 240 bool isCalculated() const { return type() == Calculated; } 94 // it's impossible to determine the sign or zero-ness. The following three functions 95 // act as if all calculated values are positive. 96 bool isZero() const; 97 bool isPositive() const; 98 bool isNegative() const; 99 100 // Returns true for both Percent and Calculated. 101 // FIXME: Doesn't really seem OK to return true for Calculated given this function's name, 102 // even though all calculated values are treated as percentages. Callers can tell Percent 103 // from a Calculated already by looking at type, so this function only half-hides the distinction. 104 bool isPercent() const; 105 106 bool isIntrinsic() const; 107 bool isIntrinsicOrAuto() const; 108 bool isSpecified() const; 109 bool isSpecifiedOrIntrinsic() const; 110 bool isViewportPercentage() const; 111 112 // Blend two lengths to produce a new length that is in between them. Used for animation. 113 // FIXME: Why is this a member function? 114 Length blend(const Length& from, double progress) const; 115 116 float nonNanCalculatedValue(int maxValue) const; 117 118 private: 119 bool isCalculated() const; 120 bool isLegacyIntrinsic() const; 121 241 122 bool isCalculatedEqual(const Length&) const; 242 bool isMinContent() const { return type() == MinContent; }243 bool isMaxContent() const { return type() == MaxContent; }244 245 Length blend(const Length& from, double progress) const246 {247 // Blend two lengths to produce a new length that is in between them. Used for animation.248 if (from.type() == Calculated || type() == Calculated)249 return blendMixedTypes(from, progress);250 251 if (!from.isZero() && !isZero() && from.type() != type())252 return blendMixedTypes(from, progress);253 254 if (from.isZero() && isZero())255 return *this;256 257 LengthType resultType = type();258 if (isZero())259 resultType = from.type();260 261 if (resultType == Percent) {262 float fromPercent = from.isZero() ? 0 : from.percent();263 float toPercent = isZero() ? 0 : percent();264 return Length(WebCore::blend(fromPercent, toPercent, progress), Percent);265 }266 267 float fromValue = from.isZero() ? 0 : from.value();268 float toValue = isZero() ? 0 : value();269 return Length(WebCore::blend(fromValue, toValue, progress), resultType);270 }271 272 float getFloatValue() const273 {274 ASSERT(!isUndefined());275 return m_isFloat ? m_floatValue : m_intValue;276 }277 float nonNanCalculatedValue(int maxValue) const;278 279 bool isViewportPercentage() const280 {281 LengthType lengthType = type();282 return lengthType >= ViewportPercentageWidth && lengthType <= ViewportPercentageMax;283 }284 float viewportPercentageLength() const285 {286 ASSERT(isViewportPercentage());287 return getFloatValue();288 }289 private:290 int getIntValue() const291 {292 ASSERT(!isUndefined());293 return m_isFloat ? static_cast<int>(m_floatValue) : m_intValue;294 }295 void initFromLength(const Length& length)296 {297 memcpy(this, &length, sizeof(Length));298 if (isCalculated())299 incrementCalculatedRef();300 }301 302 void moveFromLength(Length&& length)303 {304 ASSERT(this != &length);305 memcpy(this, &length, sizeof(Length));306 length.m_type = Auto;307 }308 309 123 Length blendMixedTypes(const Length& from, double progress) const; 310 124 311 int calculationHandle() const 312 { 313 ASSERT(isCalculated()); 314 return getIntValue(); 315 } 316 void incrementCalculatedRef() const; 317 void decrementCalculatedRef() const; 125 void ref() const; 126 void deref() const; 318 127 319 128 union { 320 129 int m_intValue; 321 130 float m_floatValue; 131 unsigned m_calculationValueHandle; 322 132 }; 323 bool m_ quirk;133 bool m_hasQuirk; 324 134 unsigned char m_type; 325 135 bool m_isFloat; 326 136 }; 327 137 328 std::unique_ptr<Length[]> newCoordsArray(const String&, int& len); 329 std::unique_ptr<Length[]> newLengthArray(const String&, int& len); 138 std::unique_ptr<Length[]> newCoordsArray(const String&, int& length); 139 std::unique_ptr<Length[]> newLengthArray(const String&, int& length); 140 141 inline Length::Length(LengthType type) 142 : m_intValue(0), m_hasQuirk(false), m_type(type), m_isFloat(false) 143 { 144 ASSERT(type != Calculated); 145 } 146 147 inline Length::Length(int value, LengthType type, bool hasQuirk) 148 : m_intValue(value), m_hasQuirk(hasQuirk), m_type(type), m_isFloat(false) 149 { 150 ASSERT(type != Calculated); 151 } 152 153 inline Length::Length(LayoutUnit value, LengthType type, bool hasQuirk) 154 : m_floatValue(value.toFloat()), m_hasQuirk(hasQuirk), m_type(type), m_isFloat(true) 155 { 156 ASSERT(type != Calculated); 157 } 158 159 inline Length::Length(float value, LengthType type, bool hasQuirk) 160 : m_floatValue(value), m_hasQuirk(hasQuirk), m_type(type), m_isFloat(true) 161 { 162 ASSERT(type != Calculated); 163 } 164 165 inline Length::Length(double value, LengthType type, bool hasQuirk) 166 : m_floatValue(static_cast<float>(value)), m_hasQuirk(hasQuirk), m_type(type), m_isFloat(true) 167 { 168 ASSERT(type != Calculated); 169 } 170 171 inline Length::Length(const Length& other) 172 { 173 if (other.isCalculated()) 174 other.ref(); 175 176 memcpy(this, &other, sizeof(Length)); 177 } 178 179 inline Length::Length(Length&& other) 180 { 181 memcpy(this, &other, sizeof(Length)); 182 other.m_type = Auto; 183 } 184 185 inline Length& Length::operator=(const Length& other) 186 { 187 if (other.isCalculated()) 188 other.ref(); 189 if (isCalculated()) 190 deref(); 191 192 memcpy(this, &other, sizeof(Length)); 193 return *this; 194 } 195 196 inline Length& Length::operator=(Length&& other) 197 { 198 if (this == &other) 199 return *this; 200 201 if (isCalculated()) 202 deref(); 203 204 memcpy(this, &other, sizeof(Length)); 205 other.m_type = Auto; 206 return *this; 207 } 208 209 inline Length::~Length() 210 { 211 if (isCalculated()) 212 deref(); 213 } 214 215 inline bool Length::operator==(const Length& other) const 216 { 217 // FIXME: This might be too long to be inline. 218 if (type() != other.type() || hasQuirk() != other.hasQuirk()) 219 return false; 220 if (isUndefined()) 221 return true; 222 if (isCalculated()) 223 return isCalculatedEqual(other); 224 return value() == other.value(); 225 } 226 227 inline bool Length::operator!=(const Length& other) const 228 { 229 return !(*this == other); 230 } 231 232 inline Length& Length::operator*=(float value) 233 { 234 ASSERT(!isCalculated()); 235 if (isCalculated()) 236 return *this; 237 238 if (m_isFloat) 239 m_floatValue *= value; 240 else 241 m_intValue *= value; 242 243 return *this; 244 } 245 246 inline float Length::value() const 247 { 248 ASSERT(!isUndefined()); 249 ASSERT(!isCalculated()); 250 return m_isFloat ? m_floatValue : m_intValue; 251 } 252 253 inline int Length::intValue() const 254 { 255 ASSERT(!isUndefined()); 256 ASSERT(!isCalculated()); 257 // FIXME: Makes no sense to return 0 here but not in the value() function above. 258 if (isCalculated()) 259 return 0; 260 return m_isFloat ? static_cast<int>(m_floatValue) : m_intValue; 261 } 262 263 inline float Length::percent() const 264 { 265 ASSERT(isPercent()); 266 return value(); 267 } 268 269 inline float Length::viewportPercentageLength() const 270 { 271 ASSERT(isViewportPercentage()); 272 return value(); 273 } 274 275 inline LengthType Length::type() const 276 { 277 return static_cast<LengthType>(m_type); 278 } 279 280 inline bool Length::hasQuirk() const 281 { 282 return m_hasQuirk; 283 } 284 285 inline void Length::setHasQuirk(bool hasQuirk) 286 { 287 m_hasQuirk = hasQuirk; 288 } 289 290 inline void Length::setValue(LengthType type, int value) 291 { 292 ASSERT(m_type != Calculated); 293 ASSERT(type != Calculated); 294 m_type = type; 295 m_intValue = value; 296 m_isFloat = false; 297 } 298 299 inline void Length::setValue(LengthType type, float value) 300 { 301 ASSERT(m_type != Calculated); 302 ASSERT(type != Calculated); 303 m_type = type; 304 m_floatValue = value; 305 m_isFloat = true; 306 } 307 308 inline void Length::setValue(LengthType type, LayoutUnit value) 309 { 310 ASSERT(m_type != Calculated); 311 ASSERT(type != Calculated); 312 m_type = type; 313 m_floatValue = value; 314 m_isFloat = true; 315 } 316 317 inline bool Length::isAuto() const 318 { 319 return type() == Auto; 320 } 321 322 inline bool Length::isFixed() const 323 { 324 return type() == Fixed; 325 } 326 327 inline bool Length::isMaxContent() const 328 { 329 return type() == MaxContent; 330 } 331 332 inline bool Length::isMinContent() const 333 { 334 return type() == MinContent; 335 } 336 337 inline bool Length::isNegative() const 338 { 339 if (isUndefined() || isCalculated()) 340 return false; 341 return m_isFloat ? (m_floatValue < 0) : (m_intValue < 0); 342 } 343 344 inline bool Length::isRelative() const 345 { 346 return type() == Relative; 347 } 348 349 inline bool Length::isUndefined() const 350 { 351 return type() == Undefined; 352 } 353 354 inline bool Length::isPercent() const 355 { 356 return type() == Percent || isCalculated(); 357 } 358 359 inline bool Length::isPositive() const 360 { 361 if (isUndefined()) 362 return false; 363 if (isCalculated()) 364 return true; 365 return m_isFloat ? (m_floatValue > 0) : (m_intValue > 0); 366 } 367 368 inline bool Length::isZero() const 369 { 370 ASSERT(!isUndefined()); 371 if (isCalculated()) 372 return false; 373 return m_isFloat ? !m_floatValue : !m_intValue; 374 } 375 376 inline bool Length::isCalculated() const 377 { 378 return type() == Calculated; 379 } 380 381 inline bool Length::isLegacyIntrinsic() const 382 { 383 return type() == Intrinsic || type() == MinIntrinsic; 384 } 385 386 inline bool Length::isIntrinsic() const 387 { 388 return type() == MinContent || type() == MaxContent || type() == FillAvailable || type() == FitContent; 389 } 390 391 inline bool Length::isIntrinsicOrAuto() const 392 { 393 return isAuto() || isIntrinsic() || isLegacyIntrinsic(); 394 } 395 396 inline bool Length::isSpecified() const 397 { 398 return isFixed() || type() == Percent || isCalculated() || isViewportPercentage(); 399 } 400 401 inline bool Length::isSpecifiedOrIntrinsic() const 402 { 403 return isSpecified() || isIntrinsic(); 404 } 405 406 inline bool Length::isViewportPercentage() const 407 { 408 return type() >= ViewportPercentageWidth && type() <= ViewportPercentageMax; 409 } 410 411 // FIXME: Does this need to be in the header? Is it valuable to inline? Does it get inlined? 412 inline Length Length::blend(const Length& from, double progress) const 413 { 414 if (from.type() == Calculated || type() == Calculated) 415 return blendMixedTypes(from, progress); 416 417 if (!from.isZero() && !isZero() && from.type() != type()) 418 return blendMixedTypes(from, progress); 419 420 if (from.isZero() && isZero()) 421 return *this; 422 423 LengthType resultType = type(); 424 if (isZero()) 425 resultType = from.type(); 426 427 if (resultType == Percent) { 428 float fromPercent = from.isZero() ? 0 : from.percent(); 429 float toPercent = isZero() ? 0 : percent(); 430 return Length(WebCore::blend(fromPercent, toPercent, progress), Percent); 431 } 432 433 float fromValue = from.isZero() ? 0 : from.value(); 434 float toValue = isZero() ? 0 : value(); 435 return Length(WebCore::blend(fromValue, toValue, progress), resultType); 436 } 330 437 331 438 } // namespace WebCore -
trunk/Source/WebCore/platform/LengthBox.h
r156132 r166860 29 29 namespace WebCore { 30 30 31 class RenderStyle;32 33 31 struct LengthBox { 34 32 LengthBox() … … 36 34 } 37 35 38 LengthBox(LengthType t)39 : m_left(t )40 , m_right(t )41 , m_top(t )42 , m_bottom(t )36 explicit LengthBox(LengthType type) 37 : m_left(type) 38 , m_right(type) 39 , m_top(type) 40 , m_bottom(type) 43 41 { 44 42 } 45 43 46 LengthBox(int v)44 explicit LengthBox(int v) 47 45 : m_left(Length(v, Fixed)) 48 46 , m_right(Length(v, Fixed)) … … 52 50 } 53 51 54 LengthBox(Length t , Length r, Length b, Length l)55 : m_left(std::move(l ))56 , m_right(std::move(r ))57 , m_top(std::move(t ))58 , m_bottom(std::move(b ))52 LengthBox(Length top, Length right, Length bottom, Length left) 53 : m_left(std::move(left)) 54 , m_right(std::move(right)) 55 , m_top(std::move(top)) 56 , m_bottom(std::move(bottom)) 59 57 { 60 58 } 61 62 LengthBox(int t , int r, int b, int l)63 : m_left(Length(l , Fixed))64 , m_right(Length(r , Fixed))65 , m_top(Length(t , Fixed))66 , m_bottom(Length(b , Fixed))59 60 LengthBox(int top, int right, int bottom, int left) 61 : m_left(Length(left, Fixed)) 62 , m_right(Length(right, Fixed)) 63 , m_top(Length(top, Fixed)) 64 , m_bottom(Length(bottom, Fixed)) 67 65 { 68 66 } … … 81 79 const Length& end(WritingMode, TextDirection) const; 82 80 83 bool operator==(const LengthBox& o ) const81 bool operator==(const LengthBox& other) const 84 82 { 85 return m_left == o .m_left && m_right == o.m_right && m_top == o.m_top && m_bottom == o.m_bottom;83 return m_left == other.m_left && m_right == other.m_right && m_top == other.m_top && m_bottom == other.m_bottom; 86 84 } 87 85 88 bool operator!=(const LengthBox& o ) const86 bool operator!=(const LengthBox& other) const 89 87 { 90 return !(*this == o );88 return !(*this == other); 91 89 } 92 90 -
trunk/Source/WebCore/rendering/AutoTableLayout.cpp
r162907 r166860 86 86 Length cellLogicalWidth = cell->styleOrColLogicalWidth(); 87 87 if (cellLogicalWidth.value() > cCellMaxWidth) 88 cellLogicalWidth.setValue( cCellMaxWidth);88 cellLogicalWidth.setValue(Fixed, cCellMaxWidth); 89 89 if (cellLogicalWidth.isNegative()) 90 cellLogicalWidth.setValue( 0);90 cellLogicalWidth.setValue(Fixed, 0); 91 91 switch (cellLogicalWidth.type()) { 92 92 case Fixed: -
trunk/Source/WebCore/rendering/FixedTableLayout.cpp
r159027 r166860 144 144 if (logicalWidth.isFixed() && logicalWidth.isPositive()) { 145 145 fixedBorderBoxLogicalWidth = cell->adjustBorderBoxLogicalWidthForBoxSizing(logicalWidth.value()); 146 logicalWidth.setValue( fixedBorderBoxLogicalWidth);146 logicalWidth.setValue(Fixed, fixedBorderBoxLogicalWidth); 147 147 } 148 148 -
trunk/Source/WebCore/rendering/style/FillLayer.h
r156622 r166860 188 188 static LengthSize initialFillSizeLength(EFillLayerType) { return LengthSize(); } 189 189 static FillSize initialFillSize(EFillLayerType type) { return FillSize(initialFillSizeType(type), initialFillSizeLength(type)); } 190 static Length initialFillXPosition(EFillLayerType) { return Length(0.0 , Percent); }191 static Length initialFillYPosition(EFillLayerType) { return Length(0.0 , Percent); }190 static Length initialFillXPosition(EFillLayerType) { return Length(0.0f, Percent); } 191 static Length initialFillYPosition(EFillLayerType) { return Length(0.0f, Percent); } 192 192 static StyleImage* initialFillImage(EFillLayerType) { return 0; } 193 193 static EMaskSourceType initialMaskSourceType(EFillLayerType) { return MaskAlpha; } -
trunk/Source/WebCore/rendering/style/RenderStyle.cpp
r166618 r166860 1349 1349 } 1350 1350 1351 void RenderStyle::setWordSpacing(Length v )1351 void RenderStyle::setWordSpacing(Length value) 1352 1352 { 1353 1353 float fontWordSpacing; 1354 switch (v .type()) {1354 switch (value.type()) { 1355 1355 case Auto: 1356 1356 fontWordSpacing = 0; 1357 FALLTHROUGH;1357 break; 1358 1358 case Percent: 1359 fontWordSpacing = v .getFloatValue() * font().spaceWidth() / 100;1359 fontWordSpacing = value.percent() * font().spaceWidth() / 100; 1360 1360 break; 1361 1361 case Fixed: 1362 fontWordSpacing = v .getFloatValue();1362 fontWordSpacing = value.value(); 1363 1363 break; 1364 1364 default: … … 1368 1368 } 1369 1369 inherited.access()->font.setWordSpacing(fontWordSpacing); 1370 rareInheritedData.access()->wordSpacing = std::move(v );1370 rareInheritedData.access()->wordSpacing = std::move(value); 1371 1371 } 1372 1372 -
trunk/Source/WebCore/rendering/style/RenderStyle.h
r166696 r166860 523 523 bool hasPadding() const { return surround->padding.nonZero(); } 524 524 bool hasOffset() const { return surround->offset.nonZero(); } 525 bool hasMarginBeforeQuirk() const { return marginBefore(). quirk(); }526 bool hasMarginAfterQuirk() const { return marginAfter(). quirk(); }525 bool hasMarginBeforeQuirk() const { return marginBefore().hasQuirk(); } 526 bool hasMarginAfterQuirk() const { return marginAfter().hasQuirk(); } 527 527 528 528 bool hasBackgroundImage() const { return m_background->background().hasImage(); } … … 1776 1776 static short initialWidows() { return 2; } 1777 1777 static short initialOrphans() { return 2; } 1778 static Length initialLineHeight() { return Length(-100.0 , Percent); }1778 static Length initialLineHeight() { return Length(-100.0f, Percent); } 1779 1779 #if ENABLE(IOS_TEXT_AUTOSIZING) 1780 static Length initialSpecifiedLineHeight() { return Length(-100 , Percent); }1780 static Length initialSpecifiedLineHeight() { return Length(-100.0f, Percent); } 1781 1781 #endif 1782 1782 static ETextAlign initialTextAlign() { return TASTART; } … … 1847 1847 static ColumnSpan initialColumnSpan() { return ColumnSpanNone; } 1848 1848 static const TransformOperations& initialTransform() { DEPRECATED_DEFINE_STATIC_LOCAL(TransformOperations, ops, ()); return ops; } 1849 static Length initialTransformOriginX() { return Length(50.0 , Percent); }1850 static Length initialTransformOriginY() { return Length(50.0 , Percent); }1849 static Length initialTransformOriginX() { return Length(50.0f, Percent); } 1850 static Length initialTransformOriginY() { return Length(50.0f, Percent); } 1851 1851 static EPointerEvents initialPointerEvents() { return PE_AUTO; } 1852 1852 static float initialTransformOriginZ() { return 0; } … … 1854 1854 static EBackfaceVisibility initialBackfaceVisibility() { return BackfaceVisibilityVisible; } 1855 1855 static float initialPerspective() { return 0; } 1856 static Length initialPerspectiveOriginX() { return Length(50.0 , Percent); }1857 static Length initialPerspectiveOriginY() { return Length(50.0 , Percent); }1856 static Length initialPerspectiveOriginX() { return Length(50.0f, Percent); } 1857 static Length initialPerspectiveOriginY() { return Length(50.0f, Percent); } 1858 1858 static Color initialBackgroundColor() { return Color::transparent; } 1859 1859 static Color initialTextEmphasisColor() { return TextEmphasisFillFilled; } -
trunk/Tools/ChangeLog
r166851 r166860 1 2014-04-06 Darin Adler <darin@apple.com> 2 3 Rework CSS calc logic, fixing some reference count mistakes in Length 4 https://bugs.webkit.org/show_bug.cgi?id=131280 5 6 Reviewed by Andreas Kling. 7 8 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: Added CalculationValue.cpp. 9 * TestWebKitAPI/Tests/WebCore/CalculationValue.cpp: Added. 10 1 11 2014-04-04 Brian J. Burg <burg@cs.washington.edu> 2 12 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r166661 r166860 129 129 93A427A9180D9B0700CD24D7 /* RefPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93A427A8180D9B0700CD24D7 /* RefPtr.cpp */; }; 130 130 93A427AB180DA26400CD24D7 /* Ref.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93A427AA180DA26400CD24D7 /* Ref.cpp */; }; 131 93A720E618F1A0E800A848E1 /* CalculationValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93A720E518F1A0E800A848E1 /* CalculationValue.cpp */; }; 131 132 93ABA80916DDAB91002DB2FA /* StringHasher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93ABA80816DDAB91002DB2FA /* StringHasher.cpp */; }; 132 133 93AF4ECE1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AF4ECD1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp */; }; … … 459 460 93A427AC180DA60F00CD24D7 /* MoveOnly.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MoveOnly.h; sourceTree = "<group>"; }; 460 461 93A427AD180DA60F00CD24D7 /* RefLogger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RefLogger.h; sourceTree = "<group>"; }; 462 93A720E518F1A0E800A848E1 /* CalculationValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CalculationValue.cpp; sourceTree = "<group>"; }; 461 463 93ABA80816DDAB91002DB2FA /* StringHasher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringHasher.cpp; sourceTree = "<group>"; }; 462 464 93AF4ECA1506F035007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutForImages.cpp; sourceTree = "<group>"; }; … … 697 699 isa = PBXGroup; 698 700 children = ( 701 93A720E518F1A0E800A848E1 /* CalculationValue.cpp */, 699 702 CDC2C7141797089D00E627FB /* TimeRanges.cpp */, 700 703 440A1D3814A0103A008A66F2 /* URL.cpp */, … … 1256 1259 C0BD669D131D3CF700E18F2A /* ResponsivenessTimerDoesntFireEarly.cpp in Sources */, 1257 1260 C0ADBE8312FCA6AA00D2C129 /* RestoreSessionStateContainingFormData.cpp in Sources */, 1261 93A720E618F1A0E800A848E1 /* CalculationValue.cpp in Sources */, 1258 1262 1AEF994917A09F5400998EF0 /* GetPIDAfterAbortedProcessLaunch.cpp in Sources */, 1259 1263 BC029B181486AD6400817DA9 /* RetainPtr.cpp in Sources */,
Note: See TracChangeset
for help on using the changeset viewer.