diff options
Diffstat (limited to 'Source/WebCore/rendering/style')
91 files changed, 7904 insertions, 5281 deletions
diff --git a/Source/WebCore/rendering/style/BasicShapes.cpp b/Source/WebCore/rendering/style/BasicShapes.cpp index 916402a7d..06b3e090e 100644 --- a/Source/WebCore/rendering/style/BasicShapes.cpp +++ b/Source/WebCore/rendering/style/BasicShapes.cpp @@ -34,9 +34,15 @@ #include "BasicShapeFunctions.h" #include "CalculationValue.h" #include "FloatRect.h" +#include "FloatRoundedRect.h" #include "LengthFunctions.h" #include "Path.h" #include "RenderBox.h" +#include "SVGPathByteStream.h" +#include "SVGPathUtilities.h" + +#include <wtf/NeverDestroyed.h> +#include <wtf/TinyLRUCache.h> namespace WebCore { @@ -51,103 +57,105 @@ void BasicShapeCenterCoordinate::updateComputedLength() return; } - OwnPtr<CalcExpressionLength> lhs = adoptPtr(new CalcExpressionLength(Length(100, Percent))); - OwnPtr<CalcExpressionLength> rhs = adoptPtr(new CalcExpressionLength(m_length)); - OwnPtr<CalcExpressionBinaryOperation> op = adoptPtr(new CalcExpressionBinaryOperation(lhs.release(), rhs.release(), CalcSubtract)); - m_computedLength = Length(CalculationValue::create(op.release(), CalculationRangeAll)); + auto lhs = std::make_unique<CalcExpressionLength>(Length(100, Percent)); + auto rhs = std::make_unique<CalcExpressionLength>(m_length); + auto op = std::make_unique<CalcExpressionBinaryOperation>(WTFMove(lhs), WTFMove(rhs), CalcSubtract); + m_computedLength = Length(CalculationValue::create(WTFMove(op), ValueRangeAll)); } -bool BasicShape::canBlend(const BasicShape* other) const -{ - // FIXME: Support animations between different shapes in the future. - if (type() != other->type()) - return false; - - // Both shapes must use the same reference box. - if (layoutBox() != other->layoutBox()) - return false; +struct SVGPathTranslatedByteStream { + SVGPathTranslatedByteStream(const FloatPoint& offset, const SVGPathByteStream& rawStream) + : m_offset(offset) + , m_rawStream(rawStream) + { } + + bool operator==(const SVGPathTranslatedByteStream& other) const { return other.m_offset == m_offset && other.m_rawStream == m_rawStream; } + bool operator!=(const SVGPathTranslatedByteStream& other) const { return !(*this == other); } + bool isEmpty() const { return m_rawStream.isEmpty(); } + + Path path() const + { + Path path; + buildPathFromByteStream(m_rawStream, path); + path.translate(toFloatSize(m_offset)); + return path; + } + + FloatPoint m_offset; + SVGPathByteStream m_rawStream; +}; + +struct EllipsePathPolicy : public TinyLRUCachePolicy<FloatRect, Path> { +public: + static bool isKeyNull(const FloatRect& rect) { return rect.isEmpty(); } + + static Path createValueForKey(const FloatRect& rect) + { + Path path; + path.addEllipse(rect); + return path; + } +}; - // Just polygons with same number of vertices can be animated. - if (type() == BasicShape::BasicShapePolygonType - && (static_cast<const BasicShapePolygon*>(this)->values().size() != static_cast<const BasicShapePolygon*>(other)->values().size() - || static_cast<const BasicShapePolygon*>(this)->windRule() != static_cast<const BasicShapePolygon*>(other)->windRule())) - return false; +struct RoundedRectPathPolicy : public TinyLRUCachePolicy<FloatRoundedRect, Path> { +public: + static bool isKeyNull(const FloatRoundedRect& rect) { return rect.isEmpty(); } - // Circles with keywords for radii coordinates cannot be animated. - if (type() == BasicShape::BasicShapeCircleType) { - const BasicShapeCircle* thisCircle = static_cast<const BasicShapeCircle*>(this); - const BasicShapeCircle* otherCircle = static_cast<const BasicShapeCircle*>(other); - if (!thisCircle->radius().canBlend(otherCircle->radius())) - return false; + static Path createValueForKey(const FloatRoundedRect& rect) + { + Path path; + path.addRoundedRect(rect); + return path; } +}; - // Ellipses with keywords for radii coordinates cannot be animated. - if (type() != BasicShape::BasicShapeEllipseType) - return true; +struct PolygonPathPolicy : public TinyLRUCachePolicy<Vector<FloatPoint>, Path> { +public: + static bool isKeyNull(const Vector<FloatPoint>& points) { return !points.size(); } - const BasicShapeEllipse* thisEllipse = static_cast<const BasicShapeEllipse*>(this); - const BasicShapeEllipse* otherEllipse = static_cast<const BasicShapeEllipse*>(other); - return (thisEllipse->radiusX().canBlend(otherEllipse->radiusX()) - && thisEllipse->radiusY().canBlend(otherEllipse->radiusY())); + static Path createValueForKey(const Vector<FloatPoint>& points) { return Path::polygonPathFromPoints(points); } +}; + +struct TranslatedByteStreamPathPolicy : public TinyLRUCachePolicy<SVGPathTranslatedByteStream, Path> { +public: + static bool isKeyNull(const SVGPathTranslatedByteStream& stream) { return stream.isEmpty(); } + + static Path createValueForKey(const SVGPathTranslatedByteStream& stream) { return stream.path(); } +}; + +static const Path& cachedEllipsePath(const FloatRect& rect) +{ + static NeverDestroyed<TinyLRUCache<FloatRect, Path, 4, EllipsePathPolicy>> cache; + return cache.get().get(rect); } -void BasicShapeRectangle::path(Path& path, const FloatRect& boundingBox) +static const Path& cachedRoundedRectPath(const FloatRoundedRect& rect) { - ASSERT(path.isEmpty()); - path.addRoundedRect( - FloatRect( - floatValueForLength(m_x, boundingBox.width()) + boundingBox.x(), - floatValueForLength(m_y, boundingBox.height()) + boundingBox.y(), - floatValueForLength(m_width, boundingBox.width()), - floatValueForLength(m_height, boundingBox.height()) - ), - FloatSize( - floatValueForLength(m_cornerRadiusX, boundingBox.width()), - floatValueForLength(m_cornerRadiusY, boundingBox.height()) - ) - ); + static NeverDestroyed<TinyLRUCache<FloatRoundedRect, Path, 4, RoundedRectPathPolicy>> cache; + return cache.get().get(rect); } -PassRefPtr<BasicShape> BasicShapeRectangle::blend(const BasicShape* other, double progress) const +static const Path& cachedPolygonPath(const Vector<FloatPoint>& points) { - ASSERT(type() == other->type()); - - const BasicShapeRectangle* o = static_cast<const BasicShapeRectangle*>(other); - RefPtr<BasicShapeRectangle> result = BasicShapeRectangle::create(); - result->setX(m_x.blend(o->x(), progress)); - result->setY(m_y.blend(o->y(), progress)); - result->setWidth(m_width.blend(o->width(), progress)); - result->setHeight(m_height.blend(o->height(), progress)); - result->setCornerRadiusX(m_cornerRadiusX.blend(o->cornerRadiusX(), progress)); - result->setCornerRadiusY(m_cornerRadiusY.blend(o->cornerRadiusY(), progress)); - return result.release(); + static NeverDestroyed<TinyLRUCache<Vector<FloatPoint>, Path, 4, PolygonPathPolicy>> cache; + return cache.get().get(points); } -void DeprecatedBasicShapeCircle::path(Path& path, const FloatRect& boundingBox) +static const Path& cachedTranslatedByteStreamPath(const SVGPathByteStream& stream, const FloatPoint& offset) { - ASSERT(path.isEmpty()); - float diagonal = sqrtf((boundingBox.width() * boundingBox.width() + boundingBox.height() * boundingBox.height()) / 2); - float centerX = floatValueForLength(m_centerX, boundingBox.width()); - float centerY = floatValueForLength(m_centerY, boundingBox.height()); - float radius = floatValueForLength(m_radius, diagonal); - path.addEllipse(FloatRect( - centerX - radius + boundingBox.x(), - centerY - radius + boundingBox.y(), - radius * 2, - radius * 2 - )); + static NeverDestroyed<TinyLRUCache<SVGPathTranslatedByteStream, Path, 4, TranslatedByteStreamPathPolicy>> cache; + return cache.get().get(SVGPathTranslatedByteStream(offset, stream)); } -PassRefPtr<BasicShape> DeprecatedBasicShapeCircle::blend(const BasicShape* other, double progress) const +bool BasicShapeCircle::operator==(const BasicShape& other) const { - ASSERT(type() == other->type()); - - const DeprecatedBasicShapeCircle* o = static_cast<const DeprecatedBasicShapeCircle*>(other); - RefPtr<DeprecatedBasicShapeCircle> result = DeprecatedBasicShapeCircle::create(); - result->setCenterX(m_centerX.blend(o->centerX(), progress)); - result->setCenterY(m_centerY.blend(o->centerY(), progress)); - result->setRadius(m_radius.blend(o->radius(), progress)); - return result.release(); + if (type() != other.type()) + return false; + + auto& otherCircle = downcast<BasicShapeCircle>(other); + return m_centerX == otherCircle.m_centerX + && m_centerY == otherCircle.m_centerY + && m_radius == otherCircle.m_radius; } float BasicShapeCircle::floatValueForRadiusInBox(float boxWidth, float boxHeight) const @@ -158,239 +166,268 @@ float BasicShapeCircle::floatValueForRadiusInBox(float boxWidth, float boxHeight float centerX = floatValueForCenterCoordinate(m_centerX, boxWidth); float centerY = floatValueForCenterCoordinate(m_centerY, boxHeight); + float widthDelta = std::abs(boxWidth - centerX); + float heightDelta = std::abs(boxHeight - centerY); if (m_radius.type() == BasicShapeRadius::ClosestSide) - return std::min(std::min(centerX, boxWidth - centerX), std::min(centerY, boxHeight - centerY)); + return std::min(std::min(std::abs(centerX), widthDelta), std::min(std::abs(centerY), heightDelta)); // If radius.type() == BasicShapeRadius::FarthestSide. - return std::max(std::max(centerX, boxWidth - centerX), std::max(centerY, boxHeight - centerY)); + return std::max(std::max(std::abs(centerX), widthDelta), std::max(std::abs(centerY), heightDelta)); } -void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox) +const Path& BasicShapeCircle::path(const FloatRect& boundingBox) { - ASSERT(path.isEmpty()); - float centerX = floatValueForCenterCoordinate(m_centerX, boundingBox.width()); float centerY = floatValueForCenterCoordinate(m_centerY, boundingBox.height()); float radius = floatValueForRadiusInBox(boundingBox.width(), boundingBox.height()); - path.addEllipse(FloatRect( - centerX - radius + boundingBox.x(), - centerY - radius + boundingBox.y(), - radius * 2, - radius * 2 - )); + + return cachedEllipsePath(FloatRect(centerX - radius + boundingBox.x(), centerY - radius + boundingBox.y(), radius * 2, radius * 2)); } -PassRefPtr<BasicShape> BasicShapeCircle::blend(const BasicShape* other, double progress) const +bool BasicShapeCircle::canBlend(const BasicShape& other) const { - ASSERT(type() == other->type()); - const BasicShapeCircle* o = static_cast<const BasicShapeCircle*>(other); - RefPtr<BasicShapeCircle> result = BasicShapeCircle::create(); - - result->setCenterX(m_centerX.blend(o->centerX(), progress)); - result->setCenterY(m_centerY.blend(o->centerY(), progress)); - result->setRadius(m_radius.blend(o->radius(), progress)); - return result.release(); + if (type() != other.type()) + return false; + + return radius().canBlend(downcast<BasicShapeCircle>(other).radius()); } -void DeprecatedBasicShapeEllipse::path(Path& path, const FloatRect& boundingBox) +Ref<BasicShape> BasicShapeCircle::blend(const BasicShape& other, double progress) const { - ASSERT(path.isEmpty()); - float centerX = floatValueForLength(m_centerX, boundingBox.width()); - float centerY = floatValueForLength(m_centerY, boundingBox.height()); - float radiusX = floatValueForLength(m_radiusX, boundingBox.width()); - float radiusY = floatValueForLength(m_radiusY, boundingBox.height()); - path.addEllipse(FloatRect( - centerX - radiusX + boundingBox.x(), - centerY - radiusY + boundingBox.y(), - radiusX * 2, - radiusY * 2 - )); + ASSERT(type() == other.type()); + auto& otherCircle = downcast<BasicShapeCircle>(other); + auto result = BasicShapeCircle::create(); + + result->setCenterX(m_centerX.blend(otherCircle.centerX(), progress)); + result->setCenterY(m_centerY.blend(otherCircle.centerY(), progress)); + result->setRadius(m_radius.blend(otherCircle.radius(), progress)); + return WTFMove(result); } -PassRefPtr<BasicShape> DeprecatedBasicShapeEllipse::blend(const BasicShape* other, double progress) const +bool BasicShapeEllipse::operator==(const BasicShape& other) const { - ASSERT(type() == other->type()); - - const DeprecatedBasicShapeEllipse* o = static_cast<const DeprecatedBasicShapeEllipse*>(other); - RefPtr<DeprecatedBasicShapeEllipse> result = DeprecatedBasicShapeEllipse::create(); - result->setCenterX(m_centerX.blend(o->centerX(), progress)); - result->setCenterY(m_centerY.blend(o->centerY(), progress)); - result->setRadiusX(m_radiusX.blend(o->radiusX(), progress)); - result->setRadiusY(m_radiusY.blend(o->radiusY(), progress)); - return result.release(); + if (type() != other.type()) + return false; + + auto& otherEllipse = downcast<BasicShapeEllipse>(other); + return m_centerX == otherEllipse.m_centerX + && m_centerY == otherEllipse.m_centerY + && m_radiusX == otherEllipse.m_radiusX + && m_radiusY == otherEllipse.m_radiusY; } float BasicShapeEllipse::floatValueForRadiusInBox(const BasicShapeRadius& radius, float center, float boxWidthOrHeight) const { if (radius.type() == BasicShapeRadius::Value) - return floatValueForLength(radius.value(), boxWidthOrHeight); + return floatValueForLength(radius.value(), std::abs(boxWidthOrHeight)); + float widthOrHeightDelta = std::abs(boxWidthOrHeight - center); if (radius.type() == BasicShapeRadius::ClosestSide) - return std::min(center, boxWidthOrHeight - center); + return std::min(std::abs(center), widthOrHeightDelta); ASSERT(radius.type() == BasicShapeRadius::FarthestSide); - return std::max(center, boxWidthOrHeight - center); + return std::max(std::abs(center), widthOrHeightDelta); } -void BasicShapeEllipse::path(Path& path, const FloatRect& boundingBox) +const Path& BasicShapeEllipse::path(const FloatRect& boundingBox) { - ASSERT(path.isEmpty()); - float centerX = floatValueForCenterCoordinate(m_centerX, boundingBox.width()); float centerY = floatValueForCenterCoordinate(m_centerY, boundingBox.height()); float radiusX = floatValueForRadiusInBox(m_radiusX, centerX, boundingBox.width()); float radiusY = floatValueForRadiusInBox(m_radiusY, centerY, boundingBox.height()); - path.addEllipse(FloatRect( - centerX - radiusX + boundingBox.x(), - centerY - radiusY + boundingBox.y(), - radiusX * 2, - radiusY * 2)); + + return cachedEllipsePath(FloatRect(centerX - radiusX + boundingBox.x(), centerY - radiusY + boundingBox.y(), radiusX * 2, radiusY * 2)); +} + +bool BasicShapeEllipse::canBlend(const BasicShape& other) const +{ + if (type() != other.type()) + return false; + + auto& otherEllipse = downcast<BasicShapeEllipse>(other); + return radiusX().canBlend(otherEllipse.radiusX()) && radiusY().canBlend(otherEllipse.radiusY()); } -PassRefPtr<BasicShape> BasicShapeEllipse::blend(const BasicShape* other, double progress) const +Ref<BasicShape> BasicShapeEllipse::blend(const BasicShape& other, double progress) const { - ASSERT(type() == other->type()); - const BasicShapeEllipse* o = static_cast<const BasicShapeEllipse*>(other); - RefPtr<BasicShapeEllipse> result = BasicShapeEllipse::create(); - - if (m_radiusX.type() != BasicShapeRadius::Value || o->radiusX().type() != BasicShapeRadius::Value - || m_radiusY.type() != BasicShapeRadius::Value || o->radiusY().type() != BasicShapeRadius::Value) { - result->setCenterX(o->centerX()); - result->setCenterY(o->centerY()); - result->setRadiusX(o->radiusX()); - result->setRadiusY(o->radiusY()); - return result; + ASSERT(type() == other.type()); + auto& otherEllipse = downcast<BasicShapeEllipse>(other); + auto result = BasicShapeEllipse::create(); + + if (m_radiusX.type() != BasicShapeRadius::Value || otherEllipse.radiusX().type() != BasicShapeRadius::Value + || m_radiusY.type() != BasicShapeRadius::Value || otherEllipse.radiusY().type() != BasicShapeRadius::Value) { + result->setCenterX(otherEllipse.centerX()); + result->setCenterY(otherEllipse.centerY()); + result->setRadiusX(otherEllipse.radiusX()); + result->setRadiusY(otherEllipse.radiusY()); + return WTFMove(result); } - result->setCenterX(m_centerX.blend(o->centerX(), progress)); - result->setCenterY(m_centerY.blend(o->centerY(), progress)); - result->setRadiusX(m_radiusX.blend(o->radiusX(), progress)); - result->setRadiusY(m_radiusY.blend(o->radiusY(), progress)); - return result.release(); + result->setCenterX(m_centerX.blend(otherEllipse.centerX(), progress)); + result->setCenterY(m_centerY.blend(otherEllipse.centerY(), progress)); + result->setRadiusX(m_radiusX.blend(otherEllipse.radiusX(), progress)); + result->setRadiusY(m_radiusY.blend(otherEllipse.radiusY(), progress)); + return WTFMove(result); } -void BasicShapePolygon::path(Path& path, const FloatRect& boundingBox) +bool BasicShapePolygon::operator==(const BasicShape& other) const +{ + if (type() != other.type()) + return false; + + auto& otherPolygon = downcast<BasicShapePolygon>(other); + return m_windRule == otherPolygon.m_windRule + && m_values == otherPolygon.m_values; +} + +const Path& BasicShapePolygon::path(const FloatRect& boundingBox) { - ASSERT(path.isEmpty()); ASSERT(!(m_values.size() % 2)); size_t length = m_values.size(); - - if (!length) - return; - path.moveTo(FloatPoint(floatValueForLength(m_values.at(0), boundingBox.width()) + boundingBox.x(), - floatValueForLength(m_values.at(1), boundingBox.height()) + boundingBox.y())); - for (size_t i = 2; i < length; i = i + 2) { - path.addLineTo(FloatPoint(floatValueForLength(m_values.at(i), boundingBox.width()) + boundingBox.x(), - floatValueForLength(m_values.at(i + 1), boundingBox.height()) + boundingBox.y())); + Vector<FloatPoint> points(length / 2); + for (size_t i = 0; i < points.size(); ++i) { + points[i].setX(floatValueForLength(m_values.at(i * 2), boundingBox.width()) + boundingBox.x()); + points[i].setY(floatValueForLength(m_values.at(i * 2 + 1), boundingBox.height()) + boundingBox.y()); } - path.closeSubpath(); + + return cachedPolygonPath(points); } -PassRefPtr<BasicShape> BasicShapePolygon::blend(const BasicShape* other, double progress) const +bool BasicShapePolygon::canBlend(const BasicShape& other) const { - ASSERT(type() == other->type()); + if (type() != other.type()) + return false; - const BasicShapePolygon* o = static_cast<const BasicShapePolygon*>(other); - ASSERT(m_values.size() == o->values().size()); + auto& otherPolygon = downcast<BasicShapePolygon>(other); + return values().size() == otherPolygon.values().size() && windRule() == otherPolygon.windRule(); +} + +Ref<BasicShape> BasicShapePolygon::blend(const BasicShape& other, double progress) const +{ + ASSERT(type() == other.type()); + + auto& otherPolygon = downcast<BasicShapePolygon>(other); + ASSERT(m_values.size() == otherPolygon.values().size()); ASSERT(!(m_values.size() % 2)); size_t length = m_values.size(); - RefPtr<BasicShapePolygon> result = BasicShapePolygon::create(); + auto result = BasicShapePolygon::create(); if (!length) - return result.release(); + return WTFMove(result); - result->setWindRule(o->windRule()); + result->setWindRule(otherPolygon.windRule()); for (size_t i = 0; i < length; i = i + 2) { - result->appendPoint(m_values.at(i).blend(o->values().at(i), progress), - m_values.at(i + 1).blend(o->values().at(i + 1), progress)); + result->appendPoint( + WebCore::blend(otherPolygon.values().at(i), m_values.at(i), progress), + WebCore::blend(otherPolygon.values().at(i + 1), m_values.at(i + 1), progress)); } - return result.release(); + return WTFMove(result); } -void BasicShapeInsetRectangle::path(Path& path, const FloatRect& boundingBox) +BasicShapePath::BasicShapePath(std::unique_ptr<SVGPathByteStream>&& byteStream) + : m_byteStream(WTFMove(byteStream)) { - ASSERT(path.isEmpty()); - float left = floatValueForLength(m_left, boundingBox.width()); - float top = floatValueForLength(m_top, boundingBox.height()); - path.addRoundedRect( - FloatRect( - left + boundingBox.x(), - top + boundingBox.y(), - std::max<float>(boundingBox.width() - left - floatValueForLength(m_right, boundingBox.width()), 0), - std::max<float>(boundingBox.height() - top - floatValueForLength(m_bottom, boundingBox.height()), 0) - ), - FloatSize( - floatValueForLength(m_cornerRadiusX, boundingBox.width()), - floatValueForLength(m_cornerRadiusY, boundingBox.height()) - ) - ); } -PassRefPtr<BasicShape> BasicShapeInsetRectangle::blend(const BasicShape* other, double progress) const +const Path& BasicShapePath::path(const FloatRect& boundingBox) +{ + return cachedTranslatedByteStreamPath(*m_byteStream, boundingBox.location()); +} + +bool BasicShapePath::operator==(const BasicShape& other) const { - ASSERT(type() == other->type()); - - const BasicShapeInsetRectangle* o = static_cast<const BasicShapeInsetRectangle*>(other); - RefPtr<BasicShapeInsetRectangle> result = BasicShapeInsetRectangle::create(); - result->setTop(m_top.blend(o->top(), progress)); - result->setRight(m_right.blend(o->right(), progress)); - result->setBottom(m_bottom.blend(o->bottom(), progress)); - result->setLeft(m_left.blend(o->left(), progress)); - result->setCornerRadiusX(m_cornerRadiusX.blend(o->cornerRadiusX(), progress)); - result->setCornerRadiusY(m_cornerRadiusY.blend(o->cornerRadiusY(), progress)); - return result.release(); + if (type() != other.type()) + return false; + + auto& otherPath = downcast<BasicShapePath>(other); + return m_windRule == otherPath.m_windRule && *m_byteStream == *otherPath.m_byteStream; +} + +bool BasicShapePath::canBlend(const BasicShape& other) const +{ + if (type() != other.type()) + return false; + + auto& otherPath = downcast<BasicShapePath>(other); + return windRule() == otherPath.windRule() && canBlendSVGPathByteStreams(*m_byteStream, *otherPath.pathData()); } -void BasicShapeInset::path(Path& path, const FloatRect& boundingBox) +Ref<BasicShape> BasicShapePath::blend(const BasicShape& from, double progress) const +{ + ASSERT(type() == from.type()); + + auto& fromPath = downcast<BasicShapePath>(from); + + auto resultingPathBytes = std::make_unique<SVGPathByteStream>(); + buildAnimatedSVGPathByteStream(*fromPath.m_byteStream, *m_byteStream, *resultingPathBytes, progress); + + auto result = BasicShapePath::create(WTFMove(resultingPathBytes)); + result->setWindRule(windRule()); + return WTFMove(result); +} + +bool BasicShapeInset::operator==(const BasicShape& other) const +{ + if (type() != other.type()) + return false; + + auto& otherInset = downcast<BasicShapeInset>(other); + return m_right == otherInset.m_right + && m_top == otherInset.m_top + && m_bottom == otherInset.m_bottom + && m_left == otherInset.m_left + && m_topLeftRadius == otherInset.m_topLeftRadius + && m_topRightRadius == otherInset.m_topRightRadius + && m_bottomRightRadius == otherInset.m_bottomRightRadius + && m_bottomLeftRadius == otherInset.m_bottomLeftRadius; +} + +static FloatSize floatSizeForLengthSize(const LengthSize& lengthSize, const FloatRect& boundingBox) +{ + return { floatValueForLength(lengthSize.width, boundingBox.width()), + floatValueForLength(lengthSize.height, boundingBox.height()) }; +} + +const Path& BasicShapeInset::path(const FloatRect& boundingBox) { - ASSERT(path.isEmpty()); float left = floatValueForLength(m_left, boundingBox.width()); float top = floatValueForLength(m_top, boundingBox.height()); - path.addRoundedRect( - FloatRect( - left + boundingBox.x(), - top + boundingBox.y(), - std::max<float>(boundingBox.width() - left - floatValueForLength(m_right, boundingBox.width()), 0), - std::max<float>(boundingBox.height() - top - floatValueForLength(m_bottom, boundingBox.height()), 0) - ), - FloatSize( - floatValueForLength(m_topLeftRadius.width(), boundingBox.width()), - floatValueForLength(m_topLeftRadius.height(), boundingBox.height()) - ), - FloatSize( - floatValueForLength(m_topRightRadius.width(), boundingBox.width()), - floatValueForLength(m_topRightRadius.height(), boundingBox.height()) - ), - FloatSize( - floatValueForLength(m_bottomRightRadius.width(), boundingBox.width()), - floatValueForLength(m_bottomRightRadius.height(), boundingBox.height()) - ), - FloatSize( - floatValueForLength(m_bottomLeftRadius.width(), boundingBox.width()), - floatValueForLength(m_bottomLeftRadius.height(), boundingBox.height()) - ) - ); + auto rect = FloatRect(left + boundingBox.x(), top + boundingBox.y(), + std::max<float>(boundingBox.width() - left - floatValueForLength(m_right, boundingBox.width()), 0), + std::max<float>(boundingBox.height() - top - floatValueForLength(m_bottom, boundingBox.height()), 0)); + auto radii = FloatRoundedRect::Radii(floatSizeForLengthSize(m_topLeftRadius, boundingBox), + floatSizeForLengthSize(m_topRightRadius, boundingBox), + floatSizeForLengthSize(m_bottomLeftRadius, boundingBox), + floatSizeForLengthSize(m_bottomRightRadius, boundingBox)); + radii.scale(calcBorderRadiiConstraintScaleFor(rect, radii)); + + return cachedRoundedRectPath(FloatRoundedRect(rect, radii)); +} + +bool BasicShapeInset::canBlend(const BasicShape& other) const +{ + return type() == other.type(); } -PassRefPtr<BasicShape> BasicShapeInset::blend(const BasicShape* other, double progress) const +Ref<BasicShape> BasicShapeInset::blend(const BasicShape& from, double progress) const { - ASSERT(type() == other->type()); + ASSERT(type() == from.type()); - const BasicShapeInset* o = static_cast<const BasicShapeInset*>(other); - RefPtr<BasicShapeInset> result = BasicShapeInset::create(); - result->setTop(m_top.blend(o->top(), progress)); - result->setRight(m_right.blend(o->right(), progress)); - result->setBottom(m_bottom.blend(o->bottom(), progress)); - result->setLeft(m_left.blend(o->left(), progress)); + auto& fromInset = downcast<BasicShapeInset>(from); + auto result = BasicShapeInset::create(); + result->setTop(WebCore::blend(fromInset.top(), top(), progress)); + result->setRight(WebCore::blend(fromInset.right(), right(), progress)); + result->setBottom(WebCore::blend(fromInset.bottom(), bottom(), progress)); + result->setLeft(WebCore::blend(fromInset.left(), left(), progress)); - result->setTopLeftRadius(m_topLeftRadius.blend(o->topLeftRadius(), progress)); - result->setTopRightRadius(m_topRightRadius.blend(o->topRightRadius(), progress)); - result->setBottomRightRadius(m_bottomRightRadius.blend(o->bottomRightRadius(), progress)); - result->setBottomLeftRadius(m_bottomLeftRadius.blend(o->bottomLeftRadius(), progress)); + result->setTopLeftRadius(WebCore::blend(fromInset.topLeftRadius(), topLeftRadius(), progress)); + result->setTopRightRadius(WebCore::blend(fromInset.topRightRadius(), topRightRadius(), progress)); + result->setBottomRightRadius(WebCore::blend(fromInset.bottomRightRadius(), bottomRightRadius(), progress)); + result->setBottomLeftRadius(WebCore::blend(fromInset.bottomLeftRadius(), bottomLeftRadius(), progress)); - return result.release(); + return WTFMove(result); } } diff --git a/Source/WebCore/rendering/style/BasicShapes.h b/Source/WebCore/rendering/style/BasicShapes.h index 36464596a..f44962d9d 100644 --- a/Source/WebCore/rendering/style/BasicShapes.h +++ b/Source/WebCore/rendering/style/BasicShapes.h @@ -27,8 +27,7 @@ * SUCH DAMAGE. */ -#ifndef BasicShapes_h -#define BasicShapes_h +#pragma once #include "Length.h" #include "LengthSize.h" @@ -36,6 +35,7 @@ #include "WindRule.h" #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#include <wtf/TypeCasts.h> #include <wtf/Vector.h> namespace WebCore { @@ -43,82 +43,29 @@ namespace WebCore { class FloatRect; class Path; class RenderBox; +class SVGPathByteStream; class BasicShape : public RefCounted<BasicShape> { public: virtual ~BasicShape() { } enum Type { - BasicShapeRectangleType, - DeprecatedBasicShapeCircleType, - DeprecatedBasicShapeEllipseType, BasicShapePolygonType, - BasicShapeInsetRectangleType, + BasicShapePathType, BasicShapeCircleType, BasicShapeEllipseType, BasicShapeInsetType }; - bool canBlend(const BasicShape*) const; - - virtual void path(Path&, const FloatRect&) = 0; - virtual WindRule windRule() const { return RULE_NONZERO; } - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const = 0; - virtual Type type() const = 0; - LayoutBox layoutBox() const { return m_layoutBox; } - void setLayoutBox(LayoutBox layoutBox) { m_layoutBox = layoutBox; } - -protected: - BasicShape() - : m_layoutBox(BoxMissing) - { - } - -private: - LayoutBox m_layoutBox; -}; - -class BasicShapeRectangle : public BasicShape { -public: - static PassRefPtr<BasicShapeRectangle> create() { return adoptRef(new BasicShapeRectangle); } - - const Length& x() const { return m_x; } - const Length& y() const { return m_y; } - const Length& width() const { return m_width; } - const Length& height() const { return m_height; } - const Length& cornerRadiusX() const { return m_cornerRadiusX; } - const Length& cornerRadiusY() const { return m_cornerRadiusY; } - - void setX(Length x) { m_x = std::move(x); } - void setY(Length y) { m_y = std::move(y); } - void setWidth(Length width) { m_width = std::move(width); } - void setHeight(Length height) { m_height = std::move(height); } - void setCornerRadiusX(Length radiusX) - { - ASSERT(!radiusX.isUndefined()); - m_cornerRadiusX = std::move(radiusX); - } - void setCornerRadiusY(Length radiusY) - { - ASSERT(!radiusY.isUndefined()); - m_cornerRadiusY = std::move(radiusY); - } + virtual const Path& path(const FloatRect&) = 0; + virtual WindRule windRule() const { return RULE_NONZERO; } - virtual void path(Path&, const FloatRect&) override; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const override; + virtual bool canBlend(const BasicShape&) const = 0; + virtual Ref<BasicShape> blend(const BasicShape& from, double) const = 0; - virtual Type type() const override { return BasicShapeRectangleType; } -private: - BasicShapeRectangle() { } - - Length m_y; - Length m_x; - Length m_width; - Length m_height; - Length m_cornerRadiusX; - Length m_cornerRadiusY; + virtual bool operator==(const BasicShape&) const = 0; }; class BasicShapeCenterCoordinate { @@ -153,17 +100,24 @@ public: const Length& length() const { return m_length; } const Length& computedLength() const { return m_computedLength; } - BasicShapeCenterCoordinate blend(const BasicShapeCenterCoordinate& other, double progress) const + BasicShapeCenterCoordinate blend(const BasicShapeCenterCoordinate& from, double progress) const { - return BasicShapeCenterCoordinate(TopLeft, m_computedLength.blend(other.m_computedLength, progress)); + return BasicShapeCenterCoordinate(TopLeft, WebCore::blend(from.m_computedLength, m_computedLength, progress)); + } + + bool operator==(const BasicShapeCenterCoordinate& other) const + { + return m_direction == other.m_direction + && m_length == other.m_length + && m_computedLength == other.m_computedLength; } private: + void updateComputedLength(); + Direction m_direction; Length m_length; Length m_computedLength; - - void updateComputedLength(); }; class BasicShapeRadius { @@ -173,10 +127,23 @@ public: ClosestSide, FarthestSide }; - BasicShapeRadius() : m_value(Undefined), m_type(ClosestSide) { } - explicit BasicShapeRadius(Length v) : m_value(v), m_type(Value) { } - explicit BasicShapeRadius(Type t) : m_value(Undefined), m_type(t) { } - BasicShapeRadius(const BasicShapeRadius& other) : m_value(other.value()), m_type(other.type()) { } + BasicShapeRadius() + : m_value(Undefined), + m_type(ClosestSide) + { } + + explicit BasicShapeRadius(Length v) + : m_value(v) + , m_type(Value) + { } + explicit BasicShapeRadius(Type t) + : m_value(Undefined) + , m_type(t) + { } + BasicShapeRadius(const BasicShapeRadius& other) + : m_value(other.value()) + , m_type(other.type()) + { } const Length& value() const { return m_value; } Type type() const { return m_type; } @@ -187,12 +154,17 @@ public: return m_type == Value && other.type() == Value; } - BasicShapeRadius blend(const BasicShapeRadius& other, double progress) const + BasicShapeRadius blend(const BasicShapeRadius& from, double progress) const { - if (m_type != Value || other.type() != Value) - return BasicShapeRadius(other); + if (m_type != Value || from.type() != Value) + return BasicShapeRadius(from); - return BasicShapeRadius(m_value.blend(other.value(), progress)); + return BasicShapeRadius(WebCore::blend(from.value(), value(), progress)); + } + + bool operator==(const BasicShapeRadius& other) const + { + return m_value == other.m_value && m_type == other.m_type; } private: @@ -201,58 +173,39 @@ private: }; -class BasicShapeCircle : public BasicShape { +class BasicShapeCircle final : public BasicShape { public: - static PassRefPtr<BasicShapeCircle> create() { return adoptRef(new BasicShapeCircle); } + static Ref<BasicShapeCircle> create() { return adoptRef(*new BasicShapeCircle); } const BasicShapeCenterCoordinate& centerX() const { return m_centerX; } const BasicShapeCenterCoordinate& centerY() const { return m_centerY; } const BasicShapeRadius& radius() const { return m_radius; } float floatValueForRadiusInBox(float boxWidth, float boxHeight) const; - void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = std::move(centerX); } - void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = std::move(centerY); } - void setRadius(BasicShapeRadius radius) { m_radius = std::move(radius); } - - virtual void path(Path&, const FloatRect&) override; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const override; + void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = WTFMove(centerX); } + void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = WTFMove(centerY); } + void setRadius(BasicShapeRadius radius) { m_radius = WTFMove(radius); } - virtual Type type() const override { return BasicShapeCircleType; } private: - BasicShapeCircle() { } + BasicShapeCircle() = default; - BasicShapeCenterCoordinate m_centerX; - BasicShapeCenterCoordinate m_centerY; - BasicShapeRadius m_radius; -}; - -class DeprecatedBasicShapeCircle : public BasicShape { -public: - static PassRefPtr<DeprecatedBasicShapeCircle> create() { return adoptRef(new DeprecatedBasicShapeCircle); } - - const Length& centerX() const { return m_centerX; } - const Length& centerY() const { return m_centerY; } - const Length& radius() const { return m_radius; } + Type type() const override { return BasicShapeCircleType; } - void setCenterX(Length centerX) { m_centerX = std::move(centerX); } - void setCenterY(Length centerY) { m_centerY = std::move(centerY); } - void setRadius(Length radius) { m_radius = std::move(radius); } + const Path& path(const FloatRect&) override; - virtual void path(Path&, const FloatRect&) override; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const override; + bool canBlend(const BasicShape&) const override; + Ref<BasicShape> blend(const BasicShape& from, double) const override; - virtual Type type() const override { return DeprecatedBasicShapeCircleType; } -private: - DeprecatedBasicShapeCircle() { } + bool operator==(const BasicShape&) const override; - Length m_centerX; - Length m_centerY; - Length m_radius; + BasicShapeCenterCoordinate m_centerX; + BasicShapeCenterCoordinate m_centerY; + BasicShapeRadius m_radius; }; -class BasicShapeEllipse : public BasicShape { +class BasicShapeEllipse final : public BasicShape { public: - static PassRefPtr<BasicShapeEllipse> create() { return adoptRef(new BasicShapeEllipse); } + static Ref<BasicShapeEllipse> create() { return adoptRef(*new BasicShapeEllipse); } const BasicShapeCenterCoordinate& centerX() const { return m_centerX; } const BasicShapeCenterCoordinate& centerY() const { return m_centerY; } @@ -260,121 +213,89 @@ public: const BasicShapeRadius& radiusY() const { return m_radiusY; } float floatValueForRadiusInBox(const BasicShapeRadius&, float center, float boxWidthOrHeight) const; - void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = std::move(centerX); } - void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = std::move(centerY); } - void setRadiusX(BasicShapeRadius radiusX) { m_radiusX = std::move(radiusX); } - void setRadiusY(BasicShapeRadius radiusY) { m_radiusY = std::move(radiusY); } - - virtual void path(Path&, const FloatRect&) override; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const override; + void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = WTFMove(centerX); } + void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = WTFMove(centerY); } + void setRadiusX(BasicShapeRadius radiusX) { m_radiusX = WTFMove(radiusX); } + void setRadiusY(BasicShapeRadius radiusY) { m_radiusY = WTFMove(radiusY); } - virtual Type type() const override { return BasicShapeEllipseType; } private: - BasicShapeEllipse() { } + BasicShapeEllipse() = default; - BasicShapeCenterCoordinate m_centerX; - BasicShapeCenterCoordinate m_centerY; - BasicShapeRadius m_radiusX; - BasicShapeRadius m_radiusY; -}; + Type type() const override { return BasicShapeEllipseType; } -class DeprecatedBasicShapeEllipse : public BasicShape { -public: - static PassRefPtr<DeprecatedBasicShapeEllipse> create() { return adoptRef(new DeprecatedBasicShapeEllipse); } + const Path& path(const FloatRect&) override; - const Length& centerX() const { return m_centerX; } - const Length& centerY() const { return m_centerY; } - const Length& radiusX() const { return m_radiusX; } - const Length& radiusY() const { return m_radiusY; } + bool canBlend(const BasicShape&) const override; + Ref<BasicShape> blend(const BasicShape& from, double) const override; - void setCenterX(Length centerX) { m_centerX = std::move(centerX); } - void setCenterY(Length centerY) { m_centerY = std::move(centerY); } - void setRadiusX(Length radiusX) { m_radiusX = std::move(radiusX); } - void setRadiusY(Length radiusY) { m_radiusY = std::move(radiusY); } + bool operator==(const BasicShape&) const override; - virtual void path(Path&, const FloatRect&) override; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const override; - - virtual Type type() const override { return DeprecatedBasicShapeEllipseType; } -private: - DeprecatedBasicShapeEllipse() { } - - Length m_centerX; - Length m_centerY; - Length m_radiusX; - Length m_radiusY; + BasicShapeCenterCoordinate m_centerX; + BasicShapeCenterCoordinate m_centerY; + BasicShapeRadius m_radiusX; + BasicShapeRadius m_radiusY; }; -class BasicShapePolygon : public BasicShape { +class BasicShapePolygon final : public BasicShape { public: - static PassRefPtr<BasicShapePolygon> create() { return adoptRef(new BasicShapePolygon); } + static Ref<BasicShapePolygon> create() { return adoptRef(*new BasicShapePolygon); } const Vector<Length>& values() const { return m_values; } const Length& getXAt(unsigned i) const { return m_values[2 * i]; } const Length& getYAt(unsigned i) const { return m_values[2 * i + 1]; } void setWindRule(WindRule windRule) { m_windRule = windRule; } - void appendPoint(Length x, Length y) { m_values.append(std::move(x)); m_values.append(std::move(y)); } - - virtual void path(Path&, const FloatRect&) override; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const override; + void appendPoint(Length x, Length y) { m_values.append(WTFMove(x)); m_values.append(WTFMove(y)); } - virtual WindRule windRule() const override { return m_windRule; } + WindRule windRule() const override { return m_windRule; } - virtual Type type() const override { return BasicShapePolygonType; } private: - BasicShapePolygon() - : m_windRule(RULE_NONZERO) - { } + BasicShapePolygon() = default; + + Type type() const override { return BasicShapePolygonType; } + + const Path& path(const FloatRect&) override; - WindRule m_windRule; + bool canBlend(const BasicShape&) const override; + Ref<BasicShape> blend(const BasicShape& from, double) const override; + + bool operator==(const BasicShape&) const override; + + WindRule m_windRule { RULE_NONZERO }; Vector<Length> m_values; }; -class BasicShapeInsetRectangle : public BasicShape { +class BasicShapePath final : public BasicShape { public: - static PassRefPtr<BasicShapeInsetRectangle> create() { return adoptRef(new BasicShapeInsetRectangle); } - - const Length& top() const { return m_top; } - const Length& right() const { return m_right; } - const Length& bottom() const { return m_bottom; } - const Length& left() const { return m_left; } - const Length& cornerRadiusX() const { return m_cornerRadiusX; } - const Length& cornerRadiusY() const { return m_cornerRadiusY; } - - void setTop(Length top) { m_top = std::move(top); } - void setRight(Length right) { m_right = std::move(right); } - void setBottom(Length bottom) { m_bottom = std::move(bottom); } - void setLeft(Length left) { m_left = std::move(left); } - void setCornerRadiusX(Length radiusX) - { - ASSERT(!radiusX.isUndefined()); - m_cornerRadiusX = std::move(radiusX); - } - void setCornerRadiusY(Length radiusY) + static Ref<BasicShapePath> create(std::unique_ptr<SVGPathByteStream>&& byteStream) { - ASSERT(!radiusY.isUndefined()); - m_cornerRadiusY = std::move(radiusY); + return adoptRef(*new BasicShapePath(WTFMove(byteStream))); } - virtual void path(Path&, const FloatRect&) override; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const override; + void setWindRule(WindRule windRule) { m_windRule = windRule; } + WindRule windRule() const override { return m_windRule; } + + const SVGPathByteStream* pathData() const { return m_byteStream.get(); } - virtual Type type() const override { return BasicShapeInsetRectangleType; } private: - BasicShapeInsetRectangle() { } + BasicShapePath(std::unique_ptr<SVGPathByteStream>&&); - Length m_right; - Length m_top; - Length m_bottom; - Length m_left; - Length m_cornerRadiusX; - Length m_cornerRadiusY; + Type type() const override { return BasicShapePathType; } + + const Path& path(const FloatRect&) override; + + bool canBlend(const BasicShape&) const override; + Ref<BasicShape> blend(const BasicShape& from, double) const override; + + bool operator==(const BasicShape&) const override; + + std::unique_ptr<SVGPathByteStream> m_byteStream; + WindRule m_windRule { RULE_NONZERO }; }; -class BasicShapeInset : public BasicShape { +class BasicShapeInset final : public BasicShape { public: - static PassRefPtr<BasicShapeInset> create() { return adoptRef(new BasicShapeInset); } + static Ref<BasicShapeInset> create() { return adoptRef(*new BasicShapeInset); } const Length& top() const { return m_top; } const Length& right() const { return m_right; } @@ -386,22 +307,27 @@ public: const LengthSize& bottomRightRadius() const { return m_bottomRightRadius; } const LengthSize& bottomLeftRadius() const { return m_bottomLeftRadius; } - void setTop(Length top) { m_top = std::move(top); } - void setRight(Length right) { m_right = std::move(right); } - void setBottom(Length bottom) { m_bottom = std::move(bottom); } - void setLeft(Length left) { m_left = std::move(left); } + void setTop(Length top) { m_top = WTFMove(top); } + void setRight(Length right) { m_right = WTFMove(right); } + void setBottom(Length bottom) { m_bottom = WTFMove(bottom); } + void setLeft(Length left) { m_left = WTFMove(left); } - void setTopLeftRadius(LengthSize radius) { m_topLeftRadius = std::move(radius); } - void setTopRightRadius(LengthSize radius) { m_topRightRadius = std::move(radius); } - void setBottomRightRadius(LengthSize radius) { m_bottomRightRadius = std::move(radius); } - void setBottomLeftRadius(LengthSize radius) { m_bottomLeftRadius = std::move(radius); } + void setTopLeftRadius(LengthSize radius) { m_topLeftRadius = WTFMove(radius); } + void setTopRightRadius(LengthSize radius) { m_topRightRadius = WTFMove(radius); } + void setBottomRightRadius(LengthSize radius) { m_bottomRightRadius = WTFMove(radius); } + void setBottomLeftRadius(LengthSize radius) { m_bottomLeftRadius = WTFMove(radius); } - virtual void path(Path&, const FloatRect&) override; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const override; - - virtual Type type() const override { return BasicShapeInsetType; } private: - BasicShapeInset() { } + BasicShapeInset() = default; + + Type type() const override { return BasicShapeInsetType; } + + const Path& path(const FloatRect&) override; + + bool canBlend(const BasicShape&) const override; + Ref<BasicShape> blend(const BasicShape& from, double) const override; + + bool operator==(const BasicShape&) const override; Length m_right; Length m_top; @@ -414,5 +340,15 @@ private: LengthSize m_bottomLeftRadius; }; -} -#endif +} // namespace WebCore + +#define SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(ToValueTypeName, predicate) \ +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ + static bool isType(const WebCore::BasicShape& basicShape) { return basicShape.type() == WebCore::predicate; } \ +SPECIALIZE_TYPE_TRAITS_END() + +SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeCircle, BasicShape::BasicShapeCircleType) +SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeEllipse, BasicShape::BasicShapeEllipseType) +SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapePolygon, BasicShape::BasicShapePolygonType) +SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapePath, BasicShape::BasicShapePathType) +SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeInset, BasicShape::BasicShapeInsetType) diff --git a/Source/WebCore/rendering/style/BorderData.h b/Source/WebCore/rendering/style/BorderData.h index e65628a99..06bcc99f8 100644 --- a/Source/WebCore/rendering/style/BorderData.h +++ b/Source/WebCore/rendering/style/BorderData.h @@ -22,8 +22,7 @@ * */ -#ifndef BorderData_h -#define BorderData_h +#pragma once #include "BorderValue.h" #include "IntRect.h" @@ -35,10 +34,11 @@ namespace WebCore { class BorderData { friend class RenderStyle; public: - BorderData() : m_topLeft(Length(0, Fixed), Length(0, Fixed)) - , m_topRight(Length(0, Fixed), Length(0, Fixed)) - , m_bottomLeft(Length(0, Fixed), Length(0, Fixed)) - , m_bottomRight(Length(0, Fixed), Length(0, Fixed)) + BorderData() + : m_topLeft { { 0, Fixed }, { 0, Fixed } } + , m_topRight { { 0, Fixed }, { 0, Fixed } } + , m_bottomLeft { { 0, Fixed }, { 0, Fixed } } + , m_bottomRight { { 0, Fixed }, { 0, Fixed } } { } bool hasBorder() const @@ -46,47 +46,58 @@ public: bool haveImage = m_image.hasImage(); return m_left.nonZero(!haveImage) || m_right.nonZero(!haveImage) || m_top.nonZero(!haveImage) || m_bottom.nonZero(!haveImage); } + + bool hasVisibleBorder() const + { + bool haveImage = m_image.hasImage(); + return m_left.isVisible(!haveImage) || m_right.isVisible(!haveImage) || m_top.isVisible(!haveImage) || m_bottom.isVisible(!haveImage); + } + bool hasFill() const + { + return m_image.hasImage() && m_image.fill(); + } + bool hasBorderRadius() const { - if (!m_topLeft.width().isZero()) - return true; - if (!m_topRight.width().isZero()) - return true; - if (!m_bottomLeft.width().isZero()) - return true; - if (!m_bottomRight.width().isZero()) - return true; - return false; + return !m_topLeft.width.isZero() + || !m_topRight.width.isZero() + || !m_bottomLeft.width.isZero() + || !m_bottomRight.width.isZero(); } - unsigned borderLeftWidth() const + float borderLeftWidth() const { if (!m_image.hasImage() && (m_left.style() == BNONE || m_left.style() == BHIDDEN)) return 0; return m_left.width(); } - unsigned borderRightWidth() const + float borderRightWidth() const { if (!m_image.hasImage() && (m_right.style() == BNONE || m_right.style() == BHIDDEN)) return 0; return m_right.width(); } - unsigned borderTopWidth() const + float borderTopWidth() const { if (!m_image.hasImage() && (m_top.style() == BNONE || m_top.style() == BHIDDEN)) return 0; return m_top.width(); } - unsigned borderBottomWidth() const + float borderBottomWidth() const { if (!m_image.hasImage() && (m_bottom.style() == BNONE || m_bottom.style() == BHIDDEN)) return 0; return m_bottom.width(); } + + FloatBoxExtent borderWidth() const + { + return FloatBoxExtent(borderTopWidth(), borderRightWidth(), borderBottomWidth(), borderLeftWidth()); + } bool operator==(const BorderData& o) const { @@ -126,5 +137,3 @@ private: }; } // namespace WebCore - -#endif // BorderData_h diff --git a/Source/WebCore/rendering/style/BorderValue.h b/Source/WebCore/rendering/style/BorderValue.h index c8f6512c5..3eeaae401 100644 --- a/Source/WebCore/rendering/style/BorderValue.h +++ b/Source/WebCore/rendering/style/BorderValue.h @@ -22,8 +22,7 @@ * */ -#ifndef BorderValue_h -#define BorderValue_h +#pragma once #include "Color.h" #include "RenderStyleConstants.h" @@ -34,10 +33,7 @@ class BorderValue { friend class RenderStyle; public: BorderValue() - : m_color(0) - , m_colorIsValid(false) - , m_width(3) - , m_style(BNONE) + : m_style(BNONE) , m_isAuto(AUTO_OFF) { } @@ -49,7 +45,7 @@ public: bool isTransparent() const { - return m_colorIsValid && !alphaChannel(m_color); + return m_color.isValid() && !m_color.isVisible(); } bool isVisible(bool checkStyle = true) const @@ -59,7 +55,7 @@ public: bool operator==(const BorderValue& o) const { - return m_width == o.m_width && m_style == o.m_style && m_color == o.m_color && m_colorIsValid == o.m_colorIsValid; + return m_width == o.m_width && m_style == o.m_style && m_color == o.m_color; } bool operator!=(const BorderValue& o) const @@ -69,20 +65,18 @@ public: void setColor(const Color& color) { - m_color = color.rgb(); - m_colorIsValid = color.isValid(); + m_color = color; } - Color color() const { return Color(m_color, m_colorIsValid); } + const Color& color() const { return m_color; } - unsigned width() const { return m_width; } + float width() const { return m_width; } EBorderStyle style() const { return static_cast<EBorderStyle>(m_style); } protected: - RGBA32 m_color; - unsigned m_colorIsValid : 1; + float m_width { 3 }; + Color m_color; - unsigned m_width : 26; unsigned m_style : 4; // EBorderStyle // This is only used by OutlineValue but moved here to keep the bits packed. @@ -90,5 +84,3 @@ protected: }; } // namespace WebCore - -#endif // BorderValue_h diff --git a/Source/WebCore/rendering/style/CollapsedBorderValue.h b/Source/WebCore/rendering/style/CollapsedBorderValue.h index 120173bda..e0f62bf05 100644 --- a/Source/WebCore/rendering/style/CollapsedBorderValue.h +++ b/Source/WebCore/rendering/style/CollapsedBorderValue.h @@ -22,39 +22,35 @@ * */ -#ifndef CollapsedBorderValue_h -#define CollapsedBorderValue_h +#pragma once #include "BorderValue.h" +#include "LayoutUnit.h" namespace WebCore { class CollapsedBorderValue { public: CollapsedBorderValue() - : m_color(0) - , m_colorIsValid(false) - , m_width(0) - , m_style(BNONE) + : m_style(BNONE) , m_precedence(BOFF) , m_transparent(false) { } CollapsedBorderValue(const BorderValue& border, const Color& color, EBorderPrecedence precedence) - : m_color(color.rgb()) - , m_colorIsValid(color.isValid()) - , m_width(border.nonZero() ? border.width() : 0) + : m_width(LayoutUnit(border.nonZero() ? border.width() : 0)) + , m_color(color) , m_style(border.style()) , m_precedence(precedence) , m_transparent(border.isTransparent()) { } - unsigned width() const { return m_style > BHIDDEN ? m_width : 0; } + LayoutUnit width() const { return m_style > BHIDDEN ? m_width : LayoutUnit::fromPixel(0); } EBorderStyle style() const { return static_cast<EBorderStyle>(m_style); } bool exists() const { return m_precedence != BOFF; } - Color color() const { return Color(m_color, m_colorIsValid); } + const Color& color() const { return m_color; } bool isTransparent() const { return m_transparent; } EBorderPrecedence precedence() const { return static_cast<EBorderPrecedence>(m_precedence); } @@ -63,15 +59,20 @@ public: return width() == o.width() && style() == o.style() && precedence() == o.precedence(); } + static LayoutUnit adjustedCollapsedBorderWidth(float borderWidth, float deviceScaleFactor, bool roundUp); + private: - RGBA32 m_color; - unsigned m_colorIsValid : 1; - unsigned m_width : 23; + LayoutUnit m_width; + Color m_color; unsigned m_style : 4; // EBorderStyle unsigned m_precedence : 3; // EBorderPrecedence unsigned m_transparent : 1; }; -} // namespace WebCore +inline LayoutUnit CollapsedBorderValue::adjustedCollapsedBorderWidth(float borderWidth, float deviceScaleFactor, bool roundUp) +{ + float halfCollapsedBorderWidth = (borderWidth + (roundUp ? (1 / deviceScaleFactor) : 0)) / 2; + return floorToDevicePixel(halfCollapsedBorderWidth, deviceScaleFactor); +} -#endif // CollapsedBorderValue_h +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/ContentData.cpp b/Source/WebCore/rendering/style/ContentData.cpp index b0c469b41..c6c0224bc 100644 --- a/Source/WebCore/rendering/style/ContentData.cpp +++ b/Source/WebCore/rendering/style/ContentData.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2004-2017 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -36,30 +36,27 @@ namespace WebCore { std::unique_ptr<ContentData> ContentData::clone() const { auto result = cloneInternal(); - - ContentData* lastNewData = result.get(); - for (const ContentData* contentData = next(); contentData; contentData = contentData->next()) { - auto newData = contentData->cloneInternal(); - lastNewData->setNext(std::move(newData)); + auto* lastNewData = result.get(); + for (auto* contentData = next(); contentData; contentData = contentData->next()) { + lastNewData->setNext(contentData->cloneInternal()); lastNewData = lastNewData->next(); } - return result; } RenderPtr<RenderObject> ImageContentData::createContentRenderer(Document& document, const RenderStyle& pseudoStyle) const { - auto image = createRenderer<RenderImage>(document, RenderStyle::createStyleInheritingFromPseudoStyle(pseudoStyle), m_image.get()); + auto image = createRenderer<RenderImage>(document, RenderStyle::createStyleInheritingFromPseudoStyle(pseudoStyle), const_cast<StyleImage*>(m_image.ptr())); image->initializeStyle(); image->setAltText(altText()); - return std::move(image); + return WTFMove(image); } RenderPtr<RenderObject> TextContentData::createContentRenderer(Document& document, const RenderStyle&) const { auto fragment = createRenderer<RenderTextFragment>(document, m_text); fragment->setAltText(altText()); - return std::move(fragment); + return WTFMove(fragment); } RenderPtr<RenderObject> CounterContentData::createContentRenderer(Document& document, const RenderStyle&) const @@ -71,7 +68,7 @@ RenderPtr<RenderObject> QuoteContentData::createContentRenderer(Document& docume { auto quote = createRenderer<RenderQuote>(document, RenderStyle::createStyleInheritingFromPseudoStyle(pseudoStyle), m_quote); quote->initializeStyle(); - return std::move(quote); + return WTFMove(quote); } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/ContentData.h b/Source/WebCore/rendering/style/ContentData.h index 4d1b9717a..9e97c0235 100644 --- a/Source/WebCore/rendering/style/ContentData.h +++ b/Source/WebCore/rendering/style/ContentData.h @@ -2,7 +2,7 @@ * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * (C) 2000 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) * * This library is free software; you can redistribute it and/or @@ -22,13 +22,12 @@ * */ -#ifndef ContentData_h -#define ContentData_h +#pragma once #include "CounterContent.h" #include "StyleImage.h" #include "RenderPtr.h" -#include <wtf/OwnPtr.h> +#include <wtf/TypeCasts.h> namespace WebCore { @@ -39,149 +38,191 @@ class RenderStyle; class ContentData { WTF_MAKE_FAST_ALLOCATED; public: + enum Type { + CounterDataType, + ImageDataType, + QuoteDataType, + TextDataType + }; virtual ~ContentData() { } - virtual bool isCounter() const { return false; } - virtual bool isImage() const { return false; } - virtual bool isQuote() const { return false; } - virtual bool isText() const { return false; } + Type type() const { return m_type; } + + bool isCounter() const { return type() == CounterDataType; } + bool isImage() const { return type() == ImageDataType; } + bool isQuote() const { return type() == QuoteDataType; } + bool isText() const { return type() == TextDataType; } virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const = 0; std::unique_ptr<ContentData> clone() const; ContentData* next() const { return m_next.get(); } - void setNext(std::unique_ptr<ContentData> next) { m_next = std::move(next); } + void setNext(std::unique_ptr<ContentData> next) { m_next = WTFMove(next); } void setAltText(const String& alt) { m_altText = alt; } const String& altText() const { return m_altText; } - - virtual bool equals(const ContentData&) const = 0; + +protected: + explicit ContentData(Type type) + : m_type(type) + { + } private: virtual std::unique_ptr<ContentData> cloneInternal() const = 0; std::unique_ptr<ContentData> m_next; String m_altText; + Type m_type; }; class ImageContentData final : public ContentData { public: - explicit ImageContentData(PassRefPtr<StyleImage> image) - : m_image(image) + explicit ImageContentData(Ref<StyleImage>&& image) + : ContentData(ImageDataType) + , m_image(WTFMove(image)) { } - const StyleImage* image() const { return m_image.get(); } - StyleImage* image() { return m_image.get(); } - void setImage(PassRefPtr<StyleImage> image) { m_image = image; } - - virtual bool isImage() const override { return true; } - virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override; - - virtual bool equals(const ContentData& data) const override + const StyleImage& image() const { return m_image.get(); } + void setImage(Ref<StyleImage>&& image) { - if (!data.isImage()) - return false; - return *static_cast<const ImageContentData&>(data).image() == *image(); + m_image = WTFMove(image); } private: - virtual std::unique_ptr<ContentData> cloneInternal() const override + RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const final; + std::unique_ptr<ContentData> cloneInternal() const final { - RefPtr<StyleImage> image = const_cast<StyleImage*>(this->image()); - - return std::make_unique<ImageContentData>(image.release()); + auto image = std::make_unique<ImageContentData>(m_image.copyRef()); + image->setAltText(altText()); + return WTFMove(image); } - RefPtr<StyleImage> m_image; + Ref<StyleImage> m_image; }; +inline bool operator==(const ImageContentData& a, const ImageContentData& b) +{ + return &a.image() == &b.image(); +} + +inline bool operator!=(const ImageContentData& a, const ImageContentData& b) +{ + return !(a == b); +} + class TextContentData final : public ContentData { public: explicit TextContentData(const String& text) - : m_text(text) + : ContentData(TextDataType) + , m_text(text) { } const String& text() const { return m_text; } void setText(const String& text) { m_text = text; } - virtual bool isText() const override { return true; } - virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override; - - virtual bool equals(const ContentData& data) const override - { - if (!data.isText()) - return false; - return static_cast<const TextContentData&>(data).text() == text(); - } - private: - virtual std::unique_ptr<ContentData> cloneInternal() const override { return std::make_unique<TextContentData>(text()); } + RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const final; + std::unique_ptr<ContentData> cloneInternal() const final { return std::make_unique<TextContentData>(m_text); } String m_text; }; +inline bool operator==(const TextContentData& a, const TextContentData& b) +{ + return a.text() == b.text(); +} + +inline bool operator!=(const TextContentData& a, const TextContentData& b) +{ + return !(a == b); +} + class CounterContentData final : public ContentData { public: explicit CounterContentData(std::unique_ptr<CounterContent> counter) - : m_counter(std::move(counter)) + : ContentData(CounterDataType) + , m_counter(WTFMove(counter)) { + ASSERT(m_counter); } - const CounterContent* counter() const { return m_counter.get(); } - void setCounter(std::unique_ptr<CounterContent> counter) { m_counter = std::move(counter); } - - virtual bool isCounter() const override { return true; } - virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override; - -private: - virtual std::unique_ptr<ContentData> cloneInternal() const override + const CounterContent& counter() const { return *m_counter; } + void setCounter(std::unique_ptr<CounterContent> counter) { - auto counterData = std::make_unique<CounterContent>(*counter()); - return std::make_unique<CounterContentData>(std::move(counterData)); + ASSERT(counter); + m_counter = WTFMove(counter); } - virtual bool equals(const ContentData& data) const override +private: + RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const final; + std::unique_ptr<ContentData> cloneInternal() const final { - if (!data.isCounter()) - return false; - return *static_cast<const CounterContentData&>(data).counter() == *counter(); + return std::make_unique<CounterContentData>(std::make_unique<CounterContent>(counter())); } std::unique_ptr<CounterContent> m_counter; }; +inline bool operator==(const CounterContentData& a, const CounterContentData& b) +{ + return a.counter() == b.counter(); +} + +inline bool operator!=(const CounterContentData& a, const CounterContentData& b) +{ + return !(a == b); +} + class QuoteContentData final : public ContentData { public: explicit QuoteContentData(QuoteType quote) - : m_quote(quote) + : ContentData(QuoteDataType) + , m_quote(quote) { } QuoteType quote() const { return m_quote; } void setQuote(QuoteType quote) { m_quote = quote; } - virtual bool isQuote() const override { return true; } - virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override; - - virtual bool equals(const ContentData& data) const override - { - if (!data.isQuote()) - return false; - return static_cast<const QuoteContentData&>(data).quote() == quote(); - } - private: - virtual std::unique_ptr<ContentData> cloneInternal() const override { return std::make_unique<QuoteContentData>(quote()); } + RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const final; + std::unique_ptr<ContentData> cloneInternal() const final { return std::make_unique<QuoteContentData>(quote()); } QuoteType m_quote; }; +inline bool operator==(const QuoteContentData& a, const QuoteContentData& b) +{ + return a.quote() == b.quote(); +} + +inline bool operator!=(const QuoteContentData& a, const QuoteContentData& b) +{ + return !(a == b); +} + inline bool operator==(const ContentData& a, const ContentData& b) { - return a.equals(b); + if (a.type() != b.type()) + return false; + + switch (a.type()) { + case ContentData::CounterDataType: + return downcast<CounterContentData>(a) == downcast<CounterContentData>(b); + case ContentData::ImageDataType: + return downcast<ImageContentData>(a) == downcast<ImageContentData>(b); + case ContentData::QuoteDataType: + return downcast<QuoteContentData>(a) == downcast<QuoteContentData>(b); + case ContentData::TextDataType: + return downcast<TextContentData>(a) == downcast<TextContentData>(b); + } + + ASSERT_NOT_REACHED(); + return false; } inline bool operator!=(const ContentData& a, const ContentData& b) @@ -191,4 +232,12 @@ inline bool operator!=(const ContentData& a, const ContentData& b) } // namespace WebCore -#endif // ContentData_h +#define SPECIALIZE_TYPE_TRAITS_CONTENT_DATA(ToClassName, ContentDataName) \ +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToClassName) \ + static bool isType(const WebCore::ContentData& contentData) { return contentData.is##ContentDataName(); } \ +SPECIALIZE_TYPE_TRAITS_END() + +SPECIALIZE_TYPE_TRAITS_CONTENT_DATA(ImageContentData, Image) +SPECIALIZE_TYPE_TRAITS_CONTENT_DATA(TextContentData, Text) +SPECIALIZE_TYPE_TRAITS_CONTENT_DATA(CounterContentData, Counter) +SPECIALIZE_TYPE_TRAITS_CONTENT_DATA(QuoteContentData, Quote) diff --git a/Source/WebCore/rendering/style/CounterContent.h b/Source/WebCore/rendering/style/CounterContent.h index 814039e2d..ffc8befbe 100644 --- a/Source/WebCore/rendering/style/CounterContent.h +++ b/Source/WebCore/rendering/style/CounterContent.h @@ -22,8 +22,7 @@ * */ -#ifndef CounterContent_h -#define CounterContent_h +#pragma once #include "RenderStyleConstants.h" #include <wtf/text/AtomicString.h> @@ -57,7 +56,4 @@ static inline bool operator==(const CounterContent& a, const CounterContent& b) && a.separator() == b.separator(); } - } // namespace WebCore - -#endif // CounterContent_h diff --git a/Source/WebCore/rendering/style/CounterDirectives.cpp b/Source/WebCore/rendering/style/CounterDirectives.cpp index 06d44ddf6..4b7fd7a1e 100644 --- a/Source/WebCore/rendering/style/CounterDirectives.cpp +++ b/Source/WebCore/rendering/style/CounterDirectives.cpp @@ -21,7 +21,6 @@ #include "config.h" #include "CounterDirectives.h" -#include <wtf/PassOwnPtr.h> namespace WebCore { @@ -33,11 +32,11 @@ bool operator==(const CounterDirectives& a, const CounterDirectives& b) && a.resetValue() == b.resetValue(); } -PassOwnPtr<CounterDirectiveMap> clone(const CounterDirectiveMap& counterDirectives) +std::unique_ptr<CounterDirectiveMap> clone(const CounterDirectiveMap& counterDirectives) { - OwnPtr<CounterDirectiveMap> result = adoptPtr(new CounterDirectiveMap); + auto result = std::make_unique<CounterDirectiveMap>(); *result = counterDirectives; - return result.release(); + return result; } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/CounterDirectives.h b/Source/WebCore/rendering/style/CounterDirectives.h index cf793bb8f..e8f347721 100644 --- a/Source/WebCore/rendering/style/CounterDirectives.h +++ b/Source/WebCore/rendering/style/CounterDirectives.h @@ -22,9 +22,9 @@ * */ -#ifndef CounterDirectives_h -#define CounterDirectives_h +#pragma once +#include <memory> #include <wtf/HashMap.h> #include <wtf/MathExtras.h> #include <wtf/RefPtr.h> @@ -104,8 +104,6 @@ inline bool operator!=(const CounterDirectives& a, const CounterDirectives& b) { typedef HashMap<AtomicString, CounterDirectives> CounterDirectiveMap; -PassOwnPtr<CounterDirectiveMap> clone(const CounterDirectiveMap&); +std::unique_ptr<CounterDirectiveMap> clone(const CounterDirectiveMap&); } // namespace WebCore - -#endif // CounterDirectives_h diff --git a/Source/WebCore/rendering/style/CursorData.h b/Source/WebCore/rendering/style/CursorData.h index f8f779a28..56fccd0e9 100644 --- a/Source/WebCore/rendering/style/CursorData.h +++ b/Source/WebCore/rendering/style/CursorData.h @@ -22,8 +22,7 @@ * */ -#ifndef CursorData_h -#define CursorData_h +#pragma once #include "IntPoint.h" #include "StyleImage.h" @@ -32,8 +31,8 @@ namespace WebCore { class CursorData { public: - CursorData(PassRefPtr<StyleImage> image, const IntPoint& hotSpot) - : m_image(image) + CursorData(RefPtr<StyleImage>&& image, const IntPoint& hotSpot) + : m_image(WTFMove(image)) , m_hotSpot(hotSpot) { } @@ -49,7 +48,7 @@ public: } StyleImage* image() const { return m_image.get(); } - void setImage(PassRefPtr<StyleImage> image) { m_image = image; } + void setImage(RefPtr<StyleImage>&& image) { m_image = WTFMove(image); } // Hot spot in the image in logical pixels. const IntPoint& hotSpot() const { return m_hotSpot; } @@ -60,5 +59,3 @@ private: }; } // namespace WebCore - -#endif // CursorData_h diff --git a/Source/WebCore/rendering/style/CursorList.h b/Source/WebCore/rendering/style/CursorList.h index a1d1fe797..29830c6c4 100644 --- a/Source/WebCore/rendering/style/CursorList.h +++ b/Source/WebCore/rendering/style/CursorList.h @@ -22,8 +22,7 @@ * */ -#ifndef CursorList_h -#define CursorList_h +#pragma once #include "CursorData.h" #include <wtf/RefCounted.h> @@ -33,9 +32,9 @@ namespace WebCore { class CursorList : public RefCounted<CursorList> { public: - static PassRefPtr<CursorList> create() + static Ref<CursorList> create() { - return adoptRef(new CursorList); + return adoptRef(*new CursorList); } const CursorData& operator[](int i) const { return m_vector[i]; } @@ -58,5 +57,3 @@ private: }; } // namespace WebCore - -#endif // CursorList_h diff --git a/Source/WebCore/rendering/style/DataRef.h b/Source/WebCore/rendering/style/DataRef.h index 3eb14e1eb..f542d6c2a 100644 --- a/Source/WebCore/rendering/style/DataRef.h +++ b/Source/WebCore/rendering/style/DataRef.h @@ -1,8 +1,5 @@ /* - * Copyright (C) 2000 Lars Knoll (knoll@kde.org) - * (C) 2000 Antti Koivisto (koivisto@kde.org) - * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,40 +18,73 @@ * */ -#ifndef DataRef_h -#define DataRef_h +#pragma once -#include <wtf/PassRef.h> #include <wtf/Ref.h> namespace WebCore { template <typename T> class DataRef { public: - DataRef(PassRef<T> data) : m_data(std::move(data)) { } - DataRef(const DataRef& other) : m_data(const_cast<T&>(other.m_data.get())) { } - DataRef& operator=(const DataRef& other) { m_data = const_cast<T&>(other.m_data.get()); return *this; } + DataRef(Ref<T>&& data) + : m_data(WTFMove(data)) + { + } + + DataRef(const DataRef& other) + : m_data(other.m_data.copyRef()) + { + } + + DataRef& operator=(const DataRef& other) + { + m_data = other.m_data.copyRef(); + return *this; + } + + DataRef(DataRef&&) = default; + DataRef& operator=(DataRef&&) = default; + + DataRef replace(DataRef&& other) + { + return m_data.replace(WTFMove(other.m_data)); + } - const T* get() const { return &m_data.get(); } + operator const T&() const + { + return m_data; + } + + const T& get() const + { + return m_data; + } + + const T& operator*() const + { + return m_data; + } - const T& operator*() const { return *get(); } - const T* operator->() const { return get(); } + const T* operator->() const + { + return m_data.ptr(); + } - T* access() + T& access() { if (!m_data->hasOneRef()) m_data = m_data->copy(); - return &m_data.get(); + return m_data; } - bool operator==(const DataRef<T>& o) const + bool operator==(const DataRef& other) const { - return &m_data.get() == &o.m_data.get() || m_data.get() == o.m_data.get(); + return m_data.ptr() == other.m_data.ptr() || m_data.get() == other.m_data.get(); } - - bool operator!=(const DataRef<T>& o) const + + bool operator!=(const DataRef& other) const { - return &m_data.get() != &o.m_data.get() && m_data.get() != o.m_data.get(); + return !(*this == other); } private: @@ -62,5 +92,3 @@ private: }; } // namespace WebCore - -#endif // DataRef_h diff --git a/Source/WebCore/rendering/style/FillLayer.cpp b/Source/WebCore/rendering/style/FillLayer.cpp index 3c563b278..a4ed82641 100644 --- a/Source/WebCore/rendering/style/FillLayer.cpp +++ b/Source/WebCore/rendering/style/FillLayer.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,39 +22,40 @@ #include "config.h" #include "FillLayer.h" +#include "TextStream.h" +#include <wtf/PointerComparison.h> + namespace WebCore { struct SameSizeAsFillLayer { - FillLayer* m_next; + FillLayer* next; - RefPtr<StyleImage> m_image; + RefPtr<StyleImage> image; - Length m_xPosition; - Length m_yPosition; + Length x; + Length y; - LengthSize m_sizeLength; + LengthSize sizeLength; - unsigned m_bitfields: 32; - unsigned m_bitfields2: 1; + unsigned bitfields : 32; + unsigned bitfields2 : 11; }; COMPILE_ASSERT(sizeof(FillLayer) == sizeof(SameSizeAsFillLayer), FillLayer_should_stay_small); FillLayer::FillLayer(EFillLayerType type) - : m_next(0) - , m_image(FillLayer::initialFillImage(type)) + : m_image(FillLayer::initialFillImage(type)) , m_xPosition(FillLayer::initialFillXPosition(type)) , m_yPosition(FillLayer::initialFillYPosition(type)) - , m_sizeLength(FillLayer::initialFillSizeLength(type)) , m_attachment(FillLayer::initialFillAttachment(type)) , m_clip(FillLayer::initialFillClip(type)) , m_origin(FillLayer::initialFillOrigin(type)) , m_repeatX(FillLayer::initialFillRepeatX(type)) , m_repeatY(FillLayer::initialFillRepeatY(type)) , m_composite(FillLayer::initialFillComposite(type)) - , m_sizeType(FillLayer::initialFillSizeType(type)) + , m_sizeType(SizeNone) , m_blendMode(FillLayer::initialFillBlendMode(type)) - , m_maskSourceType(FillLayer::initialMaskSourceType(type)) + , m_maskSourceType(FillLayer::initialFillMaskSourceType(type)) , m_imageSet(false) , m_attachmentSet(false) , m_clipSet(false) @@ -63,9 +64,10 @@ FillLayer::FillLayer(EFillLayerType type) , m_repeatYSet(false) , m_xPosSet(false) , m_yPosSet(false) - , m_backgroundOriginSet(false) - , m_backgroundXOrigin(LeftEdge) - , m_backgroundYOrigin(TopEdge) + , m_backgroundXOriginSet(false) + , m_backgroundYOriginSet(false) + , m_backgroundXOrigin(static_cast<unsigned>(Edge::Left)) + , m_backgroundYOrigin(static_cast<unsigned>(Edge::Top)) , m_compositeSet(type == MaskFillLayer) , m_blendModeSet(false) , m_maskSourceTypeSet(false) @@ -74,7 +76,7 @@ FillLayer::FillLayer(EFillLayerType type) } FillLayer::FillLayer(const FillLayer& o) - : m_next(o.m_next ? new FillLayer(*o.m_next) : 0) + : m_next(o.m_next ? std::make_unique<FillLayer>(*o.m_next) : nullptr) , m_image(o.m_image) , m_xPosition(o.m_xPosition) , m_yPosition(o.m_yPosition) @@ -96,7 +98,8 @@ FillLayer::FillLayer(const FillLayer& o) , m_repeatYSet(o.m_repeatYSet) , m_xPosSet(o.m_xPosSet) , m_yPosSet(o.m_yPosSet) - , m_backgroundOriginSet(o.m_backgroundOriginSet) + , m_backgroundXOriginSet(o.m_backgroundXOriginSet) + , m_backgroundYOriginSet(o.m_backgroundYOriginSet) , m_backgroundXOrigin(o.m_backgroundXOrigin) , m_backgroundYOrigin(o.m_backgroundYOrigin) , m_compositeSet(o.m_compositeSet) @@ -108,22 +111,21 @@ FillLayer::FillLayer(const FillLayer& o) FillLayer::~FillLayer() { - delete m_next; + // Delete the layers in a loop rather than allowing recursive calls to the destructors. + for (std::unique_ptr<FillLayer> next = WTFMove(m_next); next; next = WTFMove(next->m_next)) { } } FillLayer& FillLayer::operator=(const FillLayer& o) { - if (m_next != o.m_next) { - delete m_next; - m_next = o.m_next ? new FillLayer(*o.m_next) : 0; - } + m_next = o.m_next ? std::make_unique<FillLayer>(*o.m_next) : nullptr; m_image = o.m_image; m_xPosition = o.m_xPosition; m_yPosition = o.m_yPosition; m_backgroundXOrigin = o.m_backgroundXOrigin; m_backgroundYOrigin = o.m_backgroundYOrigin; - m_backgroundOriginSet = o.m_backgroundOriginSet; + m_backgroundXOriginSet = o.m_backgroundXOriginSet; + m_backgroundYOriginSet = o.m_backgroundYOriginSet; m_sizeLength = o.m_sizeLength; m_attachment = o.m_attachment; m_clip = o.m_clip; @@ -155,14 +157,14 @@ FillLayer& FillLayer::operator=(const FillLayer& o) bool FillLayer::operator==(const FillLayer& o) const { // We do not check the "isSet" booleans for each property, since those are only used during initial construction - // to propagate patterns into layers. All layer comparisons happen after values have all been filled in anyway. - return StyleImage::imagesEquivalent(m_image.get(), o.m_image.get()) && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition - && m_backgroundXOrigin == o.m_backgroundXOrigin && m_backgroundYOrigin == o.m_backgroundYOrigin - && m_attachment == o.m_attachment && m_clip == o.m_clip && m_composite == o.m_composite - && m_blendMode == o.m_blendMode && m_origin == o.m_origin && m_repeatX == o.m_repeatX - && m_repeatY == o.m_repeatY && m_sizeType == o.m_sizeType && m_maskSourceType == o.m_maskSourceType - && m_sizeLength == o.m_sizeLength && m_type == o.m_type - && ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next); + // to propagate patterns into layers. All layer comparisons happen after values have all been filled in anyway. + return arePointingToEqualData(m_image.get(), o.m_image.get()) && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition + && m_backgroundXOrigin == o.m_backgroundXOrigin && m_backgroundYOrigin == o.m_backgroundYOrigin + && m_attachment == o.m_attachment && m_clip == o.m_clip && m_composite == o.m_composite + && m_blendMode == o.m_blendMode && m_origin == o.m_origin && m_repeatX == o.m_repeatX + && m_repeatY == o.m_repeatY && m_sizeType == o.m_sizeType && m_maskSourceType == o.m_maskSourceType + && m_sizeLength == o.m_sizeLength && m_type == o.m_type + && ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next); } void FillLayer::fillUnsetProperties() @@ -173,10 +175,10 @@ void FillLayer::fillUnsetProperties() // We need to fill in the remaining values with the pattern specified. for (FillLayer* pattern = this; curr; curr = curr->next()) { curr->m_xPosition = pattern->m_xPosition; - if (pattern->isBackgroundOriginSet()) { + if (pattern->isBackgroundXOriginSet()) curr->m_backgroundXOrigin = pattern->m_backgroundXOrigin; + if (pattern->isBackgroundYOriginSet()) curr->m_backgroundYOrigin = pattern->m_backgroundYOrigin; - } pattern = pattern->next(); if (pattern == curr || !pattern) pattern = this; @@ -188,10 +190,10 @@ void FillLayer::fillUnsetProperties() // We need to fill in the remaining values with the pattern specified. for (FillLayer* pattern = this; curr; curr = curr->next()) { curr->m_yPosition = pattern->m_yPosition; - if (pattern->isBackgroundOriginSet()) { + if (pattern->isBackgroundXOriginSet()) curr->m_backgroundXOrigin = pattern->m_backgroundXOrigin; + if (pattern->isBackgroundYOriginSet()) curr->m_backgroundYOrigin = pattern->m_backgroundYOrigin; - } pattern = pattern->next(); if (pattern == curr || !pattern) pattern = this; @@ -290,18 +292,15 @@ void FillLayer::fillUnsetProperties() void FillLayer::cullEmptyLayers() { - FillLayer* next; - for (FillLayer* p = this; p; p = next) { - next = p->m_next; - if (next && !next->isImageSet()) { - delete next; - p->m_next = 0; + for (FillLayer* layer = this; layer; layer = layer->m_next.get()) { + if (layer->m_next && !layer->m_next->isImageSet()) { + layer->m_next = nullptr; break; } } } -static EFillBox clipMax(EFillBox clipA, EFillBox clipB) +static inline EFillBox clipMax(EFillBox clipA, EFillBox clipB) { if (clipA == BorderFillBox || clipB == BorderFillBox) return BorderFillBox; @@ -314,11 +313,15 @@ static EFillBox clipMax(EFillBox clipA, EFillBox clipB) void FillLayer::computeClipMax() const { - if (m_next) { - m_next->computeClipMax(); - m_clipMax = clipMax(clip(), m_next->clip()); - } else - m_clipMax = m_clip; + Vector<const FillLayer*, 4> layers; + for (auto* layer = this; layer; layer = layer->m_next.get()) + layers.append(layer); + EFillBox computedClipMax = TextFillBox; + for (unsigned i = layers.size(); i; --i) { + auto& layer = *layers[i - 1]; + computedClipMax = clipMax(computedClipMax, layer.clip()); + layer.m_clipMax = computedClipMax; + } } bool FillLayer::clipOccludesNextLayers(bool firstLayer) const @@ -328,29 +331,25 @@ bool FillLayer::clipOccludesNextLayers(bool firstLayer) const return m_clip == m_clipMax; } -bool FillLayer::containsImage(StyleImage* s) const +bool FillLayer::containsImage(StyleImage& image) const { - if (!s) - return false; - if (m_image && *s == *m_image) - return true; - if (m_next) - return m_next->containsImage(s); + for (auto* layer = this; layer; layer = layer->m_next.get()) { + if (layer->m_image && image == *layer->m_image) + return true; + } return false; } bool FillLayer::imagesAreLoaded() const { - const FillLayer* curr; - for (curr = this; curr; curr = curr->next()) { - if (curr->m_image && !curr->m_image->isLoaded()) + for (auto* layer = this; layer; layer = layer->m_next.get()) { + if (layer->m_image && !layer->m_image->isLoaded()) return false; } - return true; } -bool FillLayer::hasOpaqueImage(const RenderElement* renderer) const +bool FillLayer::hasOpaqueImage(const RenderElement& renderer) const { if (!m_image) return false; @@ -358,18 +357,77 @@ bool FillLayer::hasOpaqueImage(const RenderElement* renderer) const if (m_composite == CompositeClear || m_composite == CompositeCopy) return true; - if (m_blendMode != BlendModeNormal) - return false; + return m_blendMode == BlendModeNormal && m_composite == CompositeSourceOver && m_image->knownToBeOpaque(&renderer); +} - if (m_composite == CompositeSourceOver) - return m_image->knownToBeOpaque(renderer); +bool FillLayer::hasRepeatXY() const +{ + return m_repeatX == RepeatFill && m_repeatY == RepeatFill; +} +bool FillLayer::hasImage() const +{ + for (auto* layer = this; layer; layer = layer->m_next.get()) { + if (layer->image()) + return true; + } return false; } -bool FillLayer::hasRepeatXY() const +bool FillLayer::hasFixedImage() const { - return m_repeatX == RepeatFill && m_repeatY == RepeatFill; + for (auto* layer = this; layer; layer = layer->m_next.get()) { + if (layer->m_image && layer->m_attachment == FixedBackgroundAttachment) + return true; + } + return false; +} + +bool FillLayer::imagesIdentical(const FillLayer* layer1, const FillLayer* layer2) +{ + for (; layer1 && layer2; layer1 = layer1->next(), layer2 = layer2->next()) { + if (!arePointingToEqualData(layer1->image(), layer2->image())) + return false; + } + + return !layer1 && !layer2; +} + +TextStream& operator<<(TextStream& ts, FillSize fillSize) +{ + return ts << fillSize.type << " " << fillSize.size; +} + +TextStream& operator<<(TextStream& ts, const FillLayer& layer) +{ + TextStream::GroupScope scope(ts); + ts << "fill-layer"; + + ts.startGroup(); + ts << "position " << layer.xPosition() << " " << layer.yPosition(); + ts.endGroup(); + + ts.dumpProperty("size", layer.size()); + + ts.startGroup(); + ts << "background-origin " << layer.backgroundXOrigin() << " " << layer.backgroundYOrigin(); + ts.endGroup(); + + ts.startGroup(); + ts << "repeat " << layer.repeatX() << " " << layer.repeatY(); + ts.endGroup(); + + ts.dumpProperty("clip", layer.clip()); + ts.dumpProperty("origin", layer.origin()); + + ts.dumpProperty("composite", layer.composite()); + ts.dumpProperty("blend-mode", layer.blendMode()); + ts.dumpProperty("mask-type", layer.maskSourceType()); + + if (layer.next()) + ts << *layer.next(); + + return ts; } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/FillLayer.h b/Source/WebCore/rendering/style/FillLayer.h index be4818fff..1e624cd02 100644 --- a/Source/WebCore/rendering/style/FillLayer.h +++ b/Source/WebCore/rendering/style/FillLayer.h @@ -2,7 +2,7 @@ * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * (C) 2000 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved. * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) * * This library is free software; you can redistribute it and/or @@ -22,11 +22,9 @@ * */ -#ifndef FillLayer_h -#define FillLayer_h +#pragma once #include "GraphicsTypes.h" -#include "Length.h" #include "LengthSize.h" #include "RenderStyleConstants.h" #include "StyleImage.h" @@ -42,36 +40,37 @@ struct FillSize { { } - FillSize(EFillSizeType t, LengthSize size) - : type(t) - , size(std::move(size)) + FillSize(EFillSizeType type, const LengthSize& size) + : type(type) + , size(size) { } - bool operator==(const FillSize& o) const - { - return type == o.type && size == o.size; - } - bool operator!=(const FillSize& o) const - { - return !(*this == o); - } - EFillSizeType type; LengthSize size; }; +inline bool operator==(const FillSize& a, const FillSize& b) +{ + return a.type == b.type && a.size == b.size; +} + +inline bool operator!=(const FillSize& a, const FillSize& b) +{ + return !(a == b); +} + class FillLayer { WTF_MAKE_FAST_ALLOCATED; public: - FillLayer(EFillLayerType); + explicit FillLayer(EFillLayerType); ~FillLayer(); StyleImage* image() const { return m_image.get(); } const Length& xPosition() const { return m_xPosition; } const Length& yPosition() const { return m_yPosition; } - BackgroundEdgeOrigin backgroundXOrigin() const { return static_cast<BackgroundEdgeOrigin>(m_backgroundXOrigin); } - BackgroundEdgeOrigin backgroundYOrigin() const { return static_cast<BackgroundEdgeOrigin>(m_backgroundYOrigin); } + Edge backgroundXOrigin() const { return static_cast<Edge>(m_backgroundXOrigin); } + Edge backgroundYOrigin() const { return static_cast<Edge>(m_backgroundYOrigin); } EFillAttachment attachment() const { return static_cast<EFillAttachment>(m_attachment); } EFillBox clip() const { return static_cast<EFillBox>(m_clip); } EFillBox origin() const { return static_cast<EFillBox>(m_origin); } @@ -84,13 +83,14 @@ public: FillSize size() const { return FillSize(static_cast<EFillSizeType>(m_sizeType), m_sizeLength); } EMaskSourceType maskSourceType() const { return static_cast<EMaskSourceType>(m_maskSourceType); } - const FillLayer* next() const { return m_next; } - FillLayer* next() { return m_next; } + const FillLayer* next() const { return m_next.get(); } + FillLayer* next() { return m_next.get(); } bool isImageSet() const { return m_imageSet; } bool isXPositionSet() const { return m_xPosSet; } bool isYPositionSet() const { return m_yPosSet; } - bool isBackgroundOriginSet() const { return m_backgroundOriginSet; } + bool isBackgroundXOriginSet() const { return m_backgroundXOriginSet; } + bool isBackgroundYOriginSet() const { return m_backgroundYOriginSet; } bool isAttachmentSet() const { return m_attachmentSet; } bool isClipSet() const { return m_clipSet; } bool isOriginSet() const { return m_originSet; } @@ -101,11 +101,11 @@ public: bool isSizeSet() const { return m_sizeType != SizeNone; } bool isMaskSourceTypeSet() const { return m_maskSourceTypeSet; } - void setImage(PassRefPtr<StyleImage> i) { m_image = i; m_imageSet = true; } - void setXPosition(Length length) { m_xPosition = std::move(length); m_xPosSet = true; } - void setYPosition(Length length) { m_yPosition = std::move(length); m_yPosSet = true; } - void setBackgroundXOrigin(BackgroundEdgeOrigin o) { m_backgroundXOrigin = o; m_backgroundOriginSet = true; } - void setBackgroundYOrigin(BackgroundEdgeOrigin o) { m_backgroundYOrigin = o; m_backgroundOriginSet = true; } + void setImage(RefPtr<StyleImage>&& image) { m_image = WTFMove(image); m_imageSet = true; } + void setXPosition(Length length) { m_xPosition = WTFMove(length); m_xPosSet = true; } + void setYPosition(Length length) { m_yPosition = WTFMove(length); m_yPosSet = true; } + void setBackgroundXOrigin(Edge o) { m_backgroundXOrigin = static_cast<unsigned>(o); m_backgroundXOriginSet = true; } + void setBackgroundYOrigin(Edge o) { m_backgroundYOrigin = static_cast<unsigned>(o); m_backgroundYOriginSet = true; } void setAttachment(EFillAttachment attachment) { m_attachment = attachment; m_attachmentSet = true; } void setClip(EFillBox b) { m_clip = b; m_clipSet = true; } void setOrigin(EFillBox b) { m_origin = b; m_originSet = true; } @@ -118,17 +118,10 @@ public: void setSize(FillSize f) { m_sizeType = f.type; m_sizeLength = f.size; } void setMaskSourceType(EMaskSourceType m) { m_maskSourceType = m; m_maskSourceTypeSet = true; } - void clearImage() { m_image.clear(); m_imageSet = false; } - void clearXPosition() - { - m_xPosSet = false; - m_backgroundOriginSet = false; - } - void clearYPosition() - { - m_yPosSet = false; - m_backgroundOriginSet = false; - } + void clearImage() { m_image = nullptr; m_imageSet = false; } + + void clearXPosition() { m_xPosSet = false; m_backgroundXOriginSet = false; } + void clearYPosition() { m_yPosSet = false; m_backgroundYOriginSet = false; } void clearAttachment() { m_attachmentSet = false; } void clearClip() { m_clipSet = false; } @@ -140,35 +133,19 @@ public: void clearSize() { m_sizeType = SizeNone; } void clearMaskSourceType() { m_maskSourceTypeSet = false; } - void setNext(FillLayer* n) { if (m_next != n) { delete m_next; m_next = n; } } + void setNext(std::unique_ptr<FillLayer> next) { m_next = WTFMove(next); } - FillLayer& operator=(const FillLayer& o); - FillLayer(const FillLayer& o); + FillLayer& operator=(const FillLayer&); + FillLayer(const FillLayer&); - bool operator==(const FillLayer& o) const; - bool operator!=(const FillLayer& o) const - { - return !(*this == o); - } + bool operator==(const FillLayer&) const; + bool operator!=(const FillLayer& other) const { return !(*this == other); } - bool containsImage(StyleImage*) const; + bool containsImage(StyleImage&) const; bool imagesAreLoaded() const; - - bool hasImage() const - { - if (m_image) - return true; - return m_next ? m_next->hasImage() : false; - } - - bool hasFixedImage() const - { - if (m_image && m_attachment == FixedBackgroundAttachment) - return true; - return m_next ? m_next->hasFixedImage() : false; - } - - bool hasOpaqueImage(const RenderElement*) const; + bool hasImage() const; + bool hasFixedImage() const; + bool hasOpaqueImage(const RenderElement&) const; bool hasRepeatXY() const; bool clipOccludesNextLayers(bool firstLayer) const; @@ -177,6 +154,8 @@ public: void fillUnsetProperties(); void cullEmptyLayers(); + static bool imagesIdentical(const FillLayer*, const FillLayer*); + static EFillAttachment initialFillAttachment(EFillLayerType) { return ScrollBackgroundAttachment; } static EFillBox initialFillClip(EFillLayerType) { return BorderFillBox; } static EFillBox initialFillOrigin(EFillLayerType type) { return type == BackgroundFillLayer ? PaddingFillBox : BorderFillBox; } @@ -184,22 +163,18 @@ public: static EFillRepeat initialFillRepeatY(EFillLayerType) { return RepeatFill; } static CompositeOperator initialFillComposite(EFillLayerType) { return CompositeSourceOver; } static BlendMode initialFillBlendMode(EFillLayerType) { return BlendModeNormal; } - static EFillSizeType initialFillSizeType(EFillLayerType) { return SizeNone; } - static LengthSize initialFillSizeLength(EFillLayerType) { return LengthSize(); } - static FillSize initialFillSize(EFillLayerType type) { return FillSize(initialFillSizeType(type), initialFillSizeLength(type)); } - static Length initialFillXPosition(EFillLayerType) { return Length(0.0, Percent); } - static Length initialFillYPosition(EFillLayerType) { return Length(0.0, Percent); } - static StyleImage* initialFillImage(EFillLayerType) { return 0; } - static EMaskSourceType initialMaskSourceType(EFillLayerType) { return MaskAlpha; } + static FillSize initialFillSize(EFillLayerType) { return FillSize(); } + static Length initialFillXPosition(EFillLayerType) { return Length(0.0f, Percent); } + static Length initialFillYPosition(EFillLayerType) { return Length(0.0f, Percent); } + static StyleImage* initialFillImage(EFillLayerType) { return nullptr; } + static EMaskSourceType initialFillMaskSourceType(EFillLayerType) { return MaskAlpha; } private: friend class RenderStyle; void computeClipMax() const; - FillLayer() { } - - FillLayer* m_next; + std::unique_ptr<FillLayer> m_next; RefPtr<StyleImage> m_image; @@ -226,9 +201,10 @@ private: unsigned m_repeatYSet : 1; unsigned m_xPosSet : 1; unsigned m_yPosSet : 1; - unsigned m_backgroundOriginSet : 1; - unsigned m_backgroundXOrigin : 2; // BackgroundEdgeOrigin - unsigned m_backgroundYOrigin : 2; // BackgroundEdgeOrigin + unsigned m_backgroundXOriginSet : 1; + unsigned m_backgroundYOriginSet : 1; + unsigned m_backgroundXOrigin : 2; // Edge + unsigned m_backgroundYOrigin : 2; // Edge unsigned m_compositeSet : 1; unsigned m_blendModeSet : 1; unsigned m_maskSourceTypeSet : 1; @@ -238,6 +214,7 @@ private: mutable unsigned m_clipMax : 2; // EFillBox, maximum m_clip value from this to bottom layer }; -} // namespace WebCore +TextStream& operator<<(TextStream&, FillSize); +TextStream& operator<<(TextStream&, const FillLayer&); -#endif // FillLayer_h +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/GridArea.h b/Source/WebCore/rendering/style/GridArea.h new file mode 100644 index 000000000..082620fb3 --- /dev/null +++ b/Source/WebCore/rendering/style/GridArea.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2013 Google Inc. All rights reserved. + * Copyright (C) 2013, 2014, 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "GridPositionsResolver.h" +#include <wtf/HashMap.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +// A span in a single direction (either rows or columns). Note that |startLine| +// and |endLine| are grid lines' indexes. +// Despite line numbers in the spec start in "1", the indexes here start in "0". +class GridSpan { +public: + + static GridSpan untranslatedDefiniteGridSpan(int startLine, int endLine) + { + return GridSpan(startLine, endLine, UntranslatedDefinite); + } + + static GridSpan translatedDefiniteGridSpan(unsigned startLine, unsigned endLine) + { + return GridSpan(startLine, endLine, TranslatedDefinite); + } + + static GridSpan indefiniteGridSpan() + { + return GridSpan(0, 1, Indefinite); + } + + bool operator==(const GridSpan& o) const + { + return m_type == o.m_type && m_startLine == o.m_startLine && m_endLine == o.m_endLine; + } + + unsigned integerSpan() const + { + ASSERT(isTranslatedDefinite()); + return m_endLine - m_startLine; + } + + int untranslatedStartLine() const + { + ASSERT(m_type == UntranslatedDefinite); + return m_startLine; + } + + int untranslatedEndLine() const + { + ASSERT(m_type == UntranslatedDefinite); + return m_endLine; + } + + unsigned startLine() const + { + ASSERT(isTranslatedDefinite()); + ASSERT(m_endLine >= 0); + return m_startLine; + } + + unsigned endLine() const + { + ASSERT(isTranslatedDefinite()); + ASSERT(m_endLine > 0); + return m_endLine; + } + + struct GridSpanIterator { + GridSpanIterator(unsigned value) + : value(value) + { + } + + operator unsigned&() { return value; } + unsigned operator*() const { return value; } + + unsigned value; + }; + + GridSpanIterator begin() const + { + ASSERT(isTranslatedDefinite()); + return m_startLine; + } + + GridSpanIterator end() const + { + ASSERT(isTranslatedDefinite()); + return m_endLine; + } + + bool isTranslatedDefinite() const + { + return m_type == TranslatedDefinite; + } + + bool isIndefinite() const + { + return m_type == Indefinite; + } + + void translate(unsigned offset) + { + ASSERT(m_type == UntranslatedDefinite); + + m_type = TranslatedDefinite; + m_startLine += offset; + m_endLine += offset; + + ASSERT(m_startLine >= 0); + ASSERT(m_endLine > 0); + } + +private: + + enum GridSpanType {UntranslatedDefinite, TranslatedDefinite, Indefinite}; + + GridSpan(int startLine, int endLine, GridSpanType type) + : m_type(type) + { +#if ENABLE(ASSERT) + ASSERT(startLine < endLine); + if (type == TranslatedDefinite) { + ASSERT(startLine >= 0); + ASSERT(endLine > 0); + } +#endif + + m_startLine = std::max(-kGridMaxTracks, std::min(startLine, kGridMaxTracks - 1)); + m_endLine = std::max(-kGridMaxTracks + 1, std::min(endLine, kGridMaxTracks)); + } + + int m_startLine; + int m_endLine; + GridSpanType m_type; + + +}; + +// This represents a grid area that spans in both rows' and columns' direction. +class GridArea { +public: + // HashMap requires a default constuctor. + GridArea() + : columns(GridSpan::indefiniteGridSpan()) + , rows(GridSpan::indefiniteGridSpan()) + { + } + + GridArea(const GridSpan& r, const GridSpan& c) + : columns(c) + , rows(r) + { + } + + bool operator==(const GridArea& o) const + { + return columns == o.columns && rows == o.rows; + } + + bool operator!=(const GridArea& o) const + { + return !(*this == o); + } + + GridSpan columns; + GridSpan rows; +}; + +typedef HashMap<String, GridArea> NamedGridAreaMap; + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/GridCoordinate.h b/Source/WebCore/rendering/style/GridCoordinate.h deleted file mode 100644 index 74a97c7ab..000000000 --- a/Source/WebCore/rendering/style/GridCoordinate.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * Copyright (C) 2013 Igalia S.L. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef GridCoordinate_h -#define GridCoordinate_h - -#include <wtf/HashMap.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/text/WTFString.h> - -namespace WebCore { - -// A span in a single direction (either rows or columns). Note that |initialPositionIndex| -// and |finalPositionIndex| are grid areas' indexes, NOT grid lines'. Iterating over the -// span should include both |initialPositionIndex| and |finalPositionIndex| to be correct. -class GridSpan { -public: - static PassOwnPtr<GridSpan> create(size_t initialPosition, size_t finalPosition) - { - return adoptPtr(new GridSpan(initialPosition, finalPosition)); - } - - GridSpan(size_t initialPosition, size_t finalPosition) - : initialPositionIndex(initialPosition) - , finalPositionIndex(finalPosition) - { - ASSERT(initialPositionIndex <= finalPositionIndex); - } - - bool operator==(const GridSpan& o) const - { - return initialPositionIndex == o.initialPositionIndex && finalPositionIndex == o.finalPositionIndex; - } - - size_t initialPositionIndex; - size_t finalPositionIndex; -}; - -// This represents a grid area that spans in both rows' and columns' direction. -class GridCoordinate { -public: - // HashMap requires a default constuctor. - GridCoordinate() - : columns(0, 0) - , rows(0, 0) - { - } - - GridCoordinate(const GridSpan& r, const GridSpan& c) - : columns(c) - , rows(r) - { - } - - bool operator==(const GridCoordinate& o) const - { - return columns == o.columns && rows == o.rows; - } - - bool operator!=(const GridCoordinate& o) const - { - return !(*this == o); - } - - GridSpan columns; - GridSpan rows; -}; - -typedef HashMap<String, GridCoordinate> NamedGridAreaMap; - -} // namespace WebCore - -#endif // GridCoordinate_h diff --git a/Source/WebCore/rendering/style/GridLength.h b/Source/WebCore/rendering/style/GridLength.h index 3a9ec4e8c..86acd330d 100644 --- a/Source/WebCore/rendering/style/GridLength.h +++ b/Source/WebCore/rendering/style/GridLength.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Google Inc. All rights reserved. - * Copyright (C) 2013 Igalia S.L. + * Copyright (C) 2013, 2014 Igalia S.L. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -29,8 +29,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef GridLength_h -#define GridLength_h +#pragma once #include "Length.h" @@ -41,17 +40,17 @@ namespace WebCore { // an new unit to Length.h. class GridLength { public: - GridLength() - : m_length(Undefined) + GridLength(const Length& length) + : m_length(length) , m_flex(0) , m_type(LengthType) { + ASSERT(!length.isUndefined()); } - GridLength(const Length& length) - : m_length(length) - , m_flex(0) - , m_type(LengthType) + explicit GridLength(double flex) + : m_flex(flex) + , m_type(FlexType) { } @@ -59,14 +58,10 @@ public: bool isFlex() const { return m_type == FlexType; } const Length& length() const { ASSERT(isLength()); return m_length; } - Length& length() { ASSERT(isLength()); return m_length; } double flex() const { ASSERT(isFlex()); return m_flex; } - void setFlex(double flex) - { - m_type = FlexType; - m_flex = flex; - } + + bool isPercentage() const { return m_type == LengthType && m_length.isPercentOrCalculated(); } bool operator==(const GridLength& o) const { @@ -74,6 +69,7 @@ public: } bool isContentSized() const { return m_type == LengthType && (m_length.isAuto() || m_length.isMinContent() || m_length.isMaxContent()); } + bool isAuto() const { return m_type == LengthType && m_length.isAuto(); } private: // Ideally we would put the 2 following fields in a union, but Length has a constructor, @@ -88,5 +84,3 @@ private: }; } // namespace WebCore - -#endif // GridLength_h diff --git a/Source/WebCore/rendering/style/GridPosition.h b/Source/WebCore/rendering/style/GridPosition.h index 5a276144e..7190c4c6e 100644 --- a/Source/WebCore/rendering/style/GridPosition.h +++ b/Source/WebCore/rendering/style/GridPosition.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2012 Google Inc. All rights reserved. + * Copyright (C) 2013, 2014 Igalia S.L. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,13 +29,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef GridPosition_h -#define GridPosition_h +#pragma once #include <wtf/text/WTFString.h> namespace WebCore { +// Recommended maximum size for both explicit and implicit grids. +const int kGridMaxTracks = 1000000; + enum GridPositionType { AutoPosition, ExplicitPosition, // [ <integer> || <string> ] @@ -42,6 +45,13 @@ enum GridPositionType { NamedGridAreaPosition // <ident> }; +enum GridPositionSide { + ColumnStartSide, + ColumnEndSide, + RowStartSide, + RowEndSide +}; + class GridPosition { public: GridPosition() @@ -60,17 +70,23 @@ public: void setExplicitPosition(int position, const String& namedGridLine) { m_type = ExplicitPosition; - m_integerPosition = position; + setIntegerPosition(position); m_namedGridLine = namedGridLine; } + void setAutoPosition() + { + m_type = AutoPosition; + m_integerPosition = 0; + } + // 'span' values cannot be negative, yet we reuse the <integer> position which can // be. This means that we have to convert the span position to an integer, losing // some precision here. It shouldn't be an issue in practice though. void setSpanPosition(int position, const String& namedGridLine) { m_type = SpanPosition; - m_integerPosition = position; + setIntegerPosition(position); m_namedGridLine = namedGridLine; } @@ -100,19 +116,23 @@ public: bool operator==(const GridPosition& other) const { - return m_type == other.m_type && m_integerPosition == other.m_integerPosition; + return m_type == other.m_type && m_integerPosition == other.m_integerPosition && m_namedGridLine == other.m_namedGridLine; } bool shouldBeResolvedAgainstOppositePosition() const { return isAuto() || isSpan(); } + private: + void setIntegerPosition(int integerPosition) + { + m_integerPosition = clampTo(integerPosition, -kGridMaxTracks, kGridMaxTracks); + } + GridPositionType m_type; int m_integerPosition; String m_namedGridLine; }; } // namespace WebCore - -#endif // GridPosition_h diff --git a/Source/WebCore/rendering/style/GridPositionsResolver.cpp b/Source/WebCore/rendering/style/GridPositionsResolver.cpp new file mode 100644 index 000000000..614a35a28 --- /dev/null +++ b/Source/WebCore/rendering/style/GridPositionsResolver.cpp @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2014-2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "GridPositionsResolver.h" + +#include "GridArea.h" +#include "RenderBox.h" +#include <cstdlib> + +namespace WebCore { + +static inline bool isColumnSide(GridPositionSide side) +{ + return side == ColumnStartSide || side == ColumnEndSide; +} + +static inline bool isStartSide(GridPositionSide side) +{ + return side == ColumnStartSide || side == RowStartSide; +} + +static inline GridPositionSide initialPositionSide(GridTrackSizingDirection direction) +{ + return direction == ForColumns ? ColumnStartSide : RowStartSide; +} + +static inline GridPositionSide finalPositionSide(GridTrackSizingDirection direction) +{ + return direction == ForColumns ? ColumnEndSide : RowEndSide; +} + +static inline GridTrackSizingDirection directionFromSide(GridPositionSide side) +{ + return side == ColumnStartSide || side == ColumnEndSide ? ForColumns : ForRows; +} + +static const String implicitNamedGridLineForSide(const String& lineName, GridPositionSide side) +{ + return lineName + (isStartSide(side) ? "-start" : "-end"); +} + +NamedLineCollection::NamedLineCollection(const RenderStyle& gridContainerStyle, const String& namedLine, GridTrackSizingDirection direction, unsigned lastLine, unsigned autoRepeatTracksCount) + : m_lastLine(lastLine) + , m_autoRepeatTotalTracks(autoRepeatTracksCount) +{ + bool isRowAxis = direction == ForColumns; + const NamedGridLinesMap& gridLineNames = isRowAxis ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines(); + const NamedGridLinesMap& autoRepeatGridLineNames = isRowAxis ? gridContainerStyle.autoRepeatNamedGridColumnLines() : gridContainerStyle.autoRepeatNamedGridRowLines(); + + auto linesIterator = gridLineNames.find(namedLine); + m_namedLinesIndexes = linesIterator == gridLineNames.end() ? nullptr : &linesIterator->value; + + auto autoRepeatLinesIterator = autoRepeatGridLineNames.find(namedLine); + m_autoRepeatNamedLinesIndexes = autoRepeatLinesIterator == autoRepeatGridLineNames.end() ? nullptr : &autoRepeatLinesIterator->value; + + m_insertionPoint = isRowAxis ? gridContainerStyle.gridAutoRepeatColumnsInsertionPoint() : gridContainerStyle.gridAutoRepeatRowsInsertionPoint(); + + m_autoRepeatTrackListLength = isRowAxis ? gridContainerStyle.gridAutoRepeatColumns().size() : gridContainerStyle.gridAutoRepeatRows().size(); +} + +bool NamedLineCollection::isValidNamedLineOrArea(const String& namedLine, const RenderStyle& gridContainerStyle, GridPositionSide side) +{ + bool isRowAxis = directionFromSide(side) == ForColumns; + auto& gridLineNames = isRowAxis ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines(); + auto& autoRepeatGridLineNames = isRowAxis ? gridContainerStyle.autoRepeatNamedGridColumnLines() : gridContainerStyle.autoRepeatNamedGridRowLines(); + + if (gridLineNames.contains(namedLine) || autoRepeatGridLineNames.contains(namedLine)) + return true; + + String implicitName = implicitNamedGridLineForSide(namedLine, side); + return gridLineNames.contains(implicitName) || autoRepeatGridLineNames.contains(implicitName); +} + +bool NamedLineCollection::hasNamedLines() const +{ + return m_namedLinesIndexes || m_autoRepeatNamedLinesIndexes; +} + +size_t NamedLineCollection::find(unsigned line) const +{ + if (line > m_lastLine) + return notFound; + + if (!m_autoRepeatNamedLinesIndexes || line < m_insertionPoint) + return m_namedLinesIndexes ? m_namedLinesIndexes->find(line) : notFound; + + if (line <= (m_insertionPoint + m_autoRepeatTotalTracks)) { + size_t localIndex = line - m_insertionPoint; + + size_t indexInFirstRepetition = localIndex % m_autoRepeatTrackListLength; + if (indexInFirstRepetition) + return m_autoRepeatNamedLinesIndexes->find(indexInFirstRepetition); + + // The line names defined in the last line are also present in the first line of the next + // repetition (if any). Same for the line names defined in the first line. + if (localIndex == m_autoRepeatTotalTracks) + return m_autoRepeatNamedLinesIndexes->find(m_autoRepeatTrackListLength); + size_t position = m_autoRepeatNamedLinesIndexes->find(0u); + if (position != notFound) + return position; + return localIndex ? m_autoRepeatNamedLinesIndexes->find(m_autoRepeatTrackListLength) : notFound; + } + + return m_namedLinesIndexes ? m_namedLinesIndexes->find(line - (m_autoRepeatTotalTracks - 1)) : notFound; +} + +bool NamedLineCollection::contains(unsigned line) const +{ + ASSERT(hasNamedLines()); + return find(line) != notFound; +} + +unsigned NamedLineCollection::firstPosition() const +{ + ASSERT(hasNamedLines()); + unsigned firstLine = 0; + + if (!m_autoRepeatNamedLinesIndexes) { + if (!m_insertionPoint || m_insertionPoint < m_namedLinesIndexes->at(firstLine)) + return m_namedLinesIndexes->at(firstLine) + (m_autoRepeatTotalTracks ? m_autoRepeatTotalTracks - 1 : 0); + return m_namedLinesIndexes->at(firstLine); + } + + if (!m_namedLinesIndexes) + return m_autoRepeatNamedLinesIndexes->at(firstLine) + m_insertionPoint; + + if (!m_insertionPoint) + return std::min(m_namedLinesIndexes->at(firstLine) + m_autoRepeatTotalTracks, m_autoRepeatNamedLinesIndexes->at(firstLine)); + + return std::min(m_namedLinesIndexes->at(firstLine), m_autoRepeatNamedLinesIndexes->at(firstLine) + m_insertionPoint); +} + +static void adjustGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, GridPosition& initialPosition, GridPosition& finalPosition) +{ + bool isForColumns = direction == ForColumns; + initialPosition = isForColumns ? gridItem.style().gridItemColumnStart() : gridItem.style().gridItemRowStart(); + finalPosition = isForColumns ? gridItem.style().gridItemColumnEnd() : gridItem.style().gridItemRowEnd(); + + // We must handle the placement error handling code here instead of in the StyleAdjuster because we don't want to + // overwrite the specified values. + if (initialPosition.isSpan() && finalPosition.isSpan()) + finalPosition.setAutoPosition(); + + if (gridItem.isOutOfFlowPositioned()) { + // Early detect the case of non existing named grid lines for positioned items. + if (initialPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide(direction))) + initialPosition.setAutoPosition(); + + if (finalPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide(direction))) + finalPosition.setAutoPosition(); + } + + // If the grid item has an automatic position and a grid span for a named line in a given dimension, instead treat the grid span as one. + if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.namedGridLine().isNull()) + finalPosition.setSpanPosition(1, String()); + if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.namedGridLine().isNull()) + initialPosition.setSpanPosition(1, String()); +} + +unsigned GridPositionsResolver::explicitGridColumnCount(const RenderStyle& gridContainerStyle, unsigned autoRepeatTracksCount) +{ + return std::min<unsigned>(std::max(gridContainerStyle.gridColumns().size() + autoRepeatTracksCount, gridContainerStyle.namedGridAreaColumnCount()), kGridMaxTracks); +} + +unsigned GridPositionsResolver::explicitGridRowCount(const RenderStyle& gridContainerStyle, unsigned autoRepeatTracksCount) +{ + return std::min<unsigned>(std::max(gridContainerStyle.gridRows().size() + autoRepeatTracksCount, gridContainerStyle.namedGridAreaRowCount()), kGridMaxTracks); +} + +static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side, unsigned autoRepeatTracksCount) +{ + return isColumnSide(side) ? GridPositionsResolver::explicitGridColumnCount(gridContainerStyle, autoRepeatTracksCount) : GridPositionsResolver::explicitGridRowCount(gridContainerStyle, autoRepeatTracksCount); +} + +static unsigned lookAheadForNamedGridLine(int start, unsigned numberOfLines, unsigned gridLastLine, NamedLineCollection& linesCollection) +{ + ASSERT(numberOfLines); + + // Only implicit lines on the search direction are assumed to have the given name, so we can start to look from first line. + // See: https://drafts.csswg.org/css-grid/#grid-placement-span-int + unsigned end = std::max(start, 0); + + if (!linesCollection.hasNamedLines()) + return std::max(end, gridLastLine + 1) + numberOfLines - 1; + + for (; numberOfLines; ++end) { + if (end > gridLastLine || linesCollection.contains(end)) + numberOfLines--; + } + + ASSERT(end); + return end - 1; +} + +static int lookBackForNamedGridLine(int end, unsigned numberOfLines, int gridLastLine, NamedLineCollection& linesCollection) +{ + ASSERT(numberOfLines); + + // Only implicit lines on the search direction are assumed to have the given name, so we can start to look from last line. + // See: https://drafts.csswg.org/css-grid/#grid-placement-span-int + int start = std::min(end, gridLastLine); + + if (!linesCollection.hasNamedLines()) + return std::min(start, -1) - numberOfLines + 1; + + for (; numberOfLines; --start) { + if (start < 0 || linesCollection.contains(start)) + numberOfLines--; + } + + return start + 1; +} + +static int resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount) +{ + ASSERT(!position.namedGridLine().isNull()); + + unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount); + NamedLineCollection linesCollection(gridContainerStyle, position.namedGridLine(), directionFromSide(side), lastLine, autoRepeatTracksCount); + + if (position.isPositive()) + return lookAheadForNamedGridLine(0, std::abs(position.integerPosition()), lastLine, linesCollection); + return lookBackForNamedGridLine(lastLine, std::abs(position.integerPosition()), lastLine, linesCollection); +} + +static GridSpan definiteGridSpanWithNamedLineSpanAgainstOpposite(int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned lastLine, NamedLineCollection& linesCollection) +{ + int start, end; + if (side == RowStartSide || side == ColumnStartSide) { + start = lookBackForNamedGridLine(oppositeLine - 1, position.spanPosition(), lastLine, linesCollection); + end = oppositeLine; + } else { + start = oppositeLine; + end = lookAheadForNamedGridLine(oppositeLine + 1, position.spanPosition(), lastLine, linesCollection); + } + + return GridSpan::untranslatedDefiniteGridSpan(start, end); +} + +static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount) +{ + ASSERT(position.isSpan()); + ASSERT(!position.namedGridLine().isNull()); + // Negative positions are not allowed per the specification and should have been handled during parsing. + ASSERT(position.spanPosition() > 0); + + unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount); + NamedLineCollection linesCollection(gridContainerStyle, position.namedGridLine(), directionFromSide(side), lastLine, autoRepeatTracksCount); + return definiteGridSpanWithNamedLineSpanAgainstOpposite(oppositeLine, position, side, lastLine, linesCollection); +} + +static GridSpan resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount) +{ + if (position.isAuto()) { + if (isStartSide(side)) + return GridSpan::untranslatedDefiniteGridSpan(oppositeLine - 1, oppositeLine); + return GridSpan::untranslatedDefiniteGridSpan(oppositeLine, oppositeLine + 1); + } + + ASSERT(position.isSpan()); + ASSERT(position.spanPosition() > 0); + + if (!position.namedGridLine().isNull()) { + // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position. + return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, oppositeLine, position, side, autoRepeatTracksCount); + } + + // 'span 1' is contained inside a single grid track regardless of the direction. + // That's why the CSS span value is one more than the offset we apply. + unsigned positionOffset = position.spanPosition(); + if (isStartSide(side)) + return GridSpan::untranslatedDefiniteGridSpan(oppositeLine - positionOffset, oppositeLine); + + return GridSpan::untranslatedDefiniteGridSpan(oppositeLine, oppositeLine + positionOffset); +} + +unsigned GridPositionsResolver::spanSizeForAutoPlacedItem(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction) +{ + GridPosition initialPosition, finalPosition; + adjustGridPositionsFromStyle(gridContainerStyle, gridItem, direction, initialPosition, finalPosition); + + // This method will only be used when both positions need to be resolved against the opposite one. + ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()); + + if (initialPosition.isAuto() && finalPosition.isAuto()) + return 1; + + GridPosition position = initialPosition.isSpan() ? initialPosition : finalPosition; + ASSERT(position.isSpan()); + + ASSERT(position.spanPosition()); + return position.spanPosition(); +} + +static int resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount) +{ + switch (position.type()) { + case ExplicitPosition: { + ASSERT(position.integerPosition()); + + if (!position.namedGridLine().isNull()) + return resolveNamedGridLinePositionFromStyle(gridContainerStyle, position, side, autoRepeatTracksCount); + + // Handle <integer> explicit position. + if (position.isPositive()) + return position.integerPosition() - 1; + + unsigned resolvedPosition = std::abs(position.integerPosition()) - 1; + const unsigned endOfTrack = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount); + + return endOfTrack - resolvedPosition; + } + case NamedGridAreaPosition: + { + // First attempt to match the grid area's edge to a named grid area: if there is a named line with the name + // ''<custom-ident>-start (for grid-*-start) / <custom-ident>-end'' (for grid-*-end), contributes the first such + // line to the grid item's placement. + String namedGridLine = position.namedGridLine(); + ASSERT(!position.namedGridLine().isNull()); + + unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount); + NamedLineCollection implicitLines(gridContainerStyle, implicitNamedGridLineForSide(namedGridLine, side), directionFromSide(side), lastLine, autoRepeatTracksCount); + if (implicitLines.hasNamedLines()) + return implicitLines.firstPosition(); + + // Otherwise, if there is a named line with the specified name, contributes the first such line to the grid + // item's placement. + NamedLineCollection explicitLines(gridContainerStyle, namedGridLine, directionFromSide(side), lastLine, autoRepeatTracksCount); + if (explicitLines.hasNamedLines()) + return explicitLines.firstPosition(); + + ASSERT(!NamedLineCollection::isValidNamedLineOrArea(namedGridLine, gridContainerStyle, side)); + // If none of the above works specs mandate to assume that all the lines in the implicit grid have this name. + return lastLine + 1; + } + case AutoPosition: + case SpanPosition: + // 'auto' and span depend on the opposite position for resolution (e.g. grid-row: auto / 1 or grid-column: span 3 / "myHeader"). + ASSERT_NOT_REACHED(); + return 0; + } + ASSERT_NOT_REACHED(); + return 0; +} + +GridSpan GridPositionsResolver::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, unsigned autoRepeatTracksCount) +{ + GridPosition initialPosition, finalPosition; + adjustGridPositionsFromStyle(gridContainerStyle, gridItem, direction, initialPosition, finalPosition); + + GridPositionSide initialSide = initialPositionSide(direction); + GridPositionSide finalSide = finalPositionSide(direction); + + // We can't get our grid positions without running the auto placement algorithm. + if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()) + return GridSpan::indefiniteGridSpan(); + + if (initialPosition.shouldBeResolvedAgainstOppositePosition()) { + // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case). + auto endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide, autoRepeatTracksCount); + return resolveGridPositionAgainstOppositePosition(gridContainerStyle, endLine, initialPosition, initialSide, autoRepeatTracksCount); + } + + if (finalPosition.shouldBeResolvedAgainstOppositePosition()) { + // Infer our position from the initial position ('1 / auto' or '3 / span 2' case). + auto startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide, autoRepeatTracksCount); + return resolveGridPositionAgainstOppositePosition(gridContainerStyle, startLine, finalPosition, finalSide, autoRepeatTracksCount); + } + + int startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide, autoRepeatTracksCount); + int endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide, autoRepeatTracksCount); + + if (startLine > endLine) + std::swap(startLine, endLine); + else if (startLine == endLine) + endLine = startLine + 1; + + return GridSpan::untranslatedDefiniteGridSpan(startLine, std::max(startLine, endLine)); +} + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/GridPositionsResolver.h b/Source/WebCore/rendering/style/GridPositionsResolver.h new file mode 100644 index 000000000..f0d26d1fc --- /dev/null +++ b/Source/WebCore/rendering/style/GridPositionsResolver.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2014-2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "GridPosition.h" + +namespace WebCore { + +class GridSpan; +class RenderBox; +class RenderStyle; + +enum GridTrackSizingDirection { + ForColumns, + ForRows +}; + +class NamedLineCollection { + WTF_MAKE_NONCOPYABLE(NamedLineCollection); +public: + NamedLineCollection(const RenderStyle&, const String& namedLine, GridTrackSizingDirection, unsigned lastLine, unsigned autoRepeatTracksCount); + + static bool isValidNamedLineOrArea(const String& namedLine, const RenderStyle&, GridPositionSide); + + bool hasNamedLines() const; + unsigned firstPosition() const; + + bool contains(unsigned line) const; + +private: + size_t find(unsigned line) const; + + const Vector<unsigned>* m_namedLinesIndexes { nullptr }; + const Vector<unsigned>* m_autoRepeatNamedLinesIndexes { nullptr }; + + unsigned m_insertionPoint; + unsigned m_lastLine; + unsigned m_autoRepeatTotalTracks; + unsigned m_autoRepeatTrackListLength; +}; + +// Class with all the code related to grid items positions resolution. +class GridPositionsResolver { +public: + static unsigned spanSizeForAutoPlacedItem(const RenderStyle&, const RenderBox&, GridTrackSizingDirection); + static GridSpan resolveGridPositionsFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection, unsigned autoRepeatTracksCount); + static unsigned explicitGridColumnCount(const RenderStyle&, unsigned autoRepeatColumnsCount); + static unsigned explicitGridRowCount(const RenderStyle&, unsigned autoRepeatRowsCount); +}; + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/GridTrackSize.h b/Source/WebCore/rendering/style/GridTrackSize.h index d5fca8948..a7ec78dbe 100644 --- a/Source/WebCore/rendering/style/GridTrackSize.h +++ b/Source/WebCore/rendering/style/GridTrackSize.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2012 Google Inc. All rights reserved. + * Copyright (C) 2013, 2014 Igalia S.L. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,8 +29,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef GridTrackSize_h -#define GridTrackSize_h +#pragma once #include "GridLength.h" @@ -37,81 +37,107 @@ namespace WebCore { enum GridTrackSizeType { LengthTrackSizing, - MinMaxTrackSizing + MinMaxTrackSizing, + FitContentTrackSizing }; +// This class represents a <track-size> from the spec. Althought there are 3 different types of +// <track-size> there is always an equivalent minmax() representation that could represent any of +// them. The only special case is fit-content(argument) which is similar to minmax(auto, +// max-content) except that the track size is clamped at argument if it is greater than the auto +// minimum. At the GridTrackSize level we don't need to worry about clamping so we treat that case +// exactly as auto. +// +// We're using a separate attribute to store fit-content argument even though we could directly use +// m_maxTrackBreadth. The reason why we don't do it is because the maxTrackBreadh() call is a hot +// spot, so adding a conditional statement there (to distinguish between fit-content and any other +// case) was causing a severe performance drop. class GridTrackSize { public: - GridTrackSize(LengthType type = Undefined) - : m_type(LengthTrackSizing) - , m_minTrackBreadth(type) - , m_maxTrackBreadth(type) + GridTrackSize(const GridLength& length, GridTrackSizeType trackSizeType = LengthTrackSizing) + : m_type(trackSizeType) + , m_minTrackBreadth(trackSizeType == FitContentTrackSizing ? Length(Auto) : length) + , m_maxTrackBreadth(trackSizeType == FitContentTrackSizing ? Length(Auto) : length) + , m_fitContentTrackBreadth(trackSizeType == FitContentTrackSizing ? length : GridLength(Length(Fixed))) { + ASSERT(trackSizeType == LengthTrackSizing || trackSizeType == FitContentTrackSizing); + ASSERT(trackSizeType != FitContentTrackSizing || length.isLength()); + cacheMinMaxTrackBreadthTypes(); } - const GridLength& length() const + GridTrackSize(const GridLength& minTrackBreadth, const GridLength& maxTrackBreadth) + : m_type(MinMaxTrackSizing) + , m_minTrackBreadth(minTrackBreadth) + , m_maxTrackBreadth(maxTrackBreadth) + , m_fitContentTrackBreadth(GridLength(Length(Fixed))) { - ASSERT(m_type == LengthTrackSizing); - ASSERT(m_minTrackBreadth == m_maxTrackBreadth); - const GridLength& minTrackBreadth = m_minTrackBreadth; - ASSERT(!minTrackBreadth.isLength() || !minTrackBreadth.length().isUndefined()); - return minTrackBreadth; + cacheMinMaxTrackBreadthTypes(); } - void setLength(const GridLength& length) + const GridLength& fitContentTrackBreadth() const { - m_type = LengthTrackSizing; - m_minTrackBreadth = length; - m_maxTrackBreadth = length; + ASSERT(m_type == FitContentTrackSizing); + return m_fitContentTrackBreadth; } - const GridLength& minTrackBreadth() const - { - ASSERT(!m_minTrackBreadth.isLength() || !m_minTrackBreadth.length().isUndefined()); - if (m_minTrackBreadth.isLength() && m_minTrackBreadth.length().isAuto()) { - DEFINE_STATIC_LOCAL(GridLength, minContent, (MinContent)); - return minContent; - } - return m_minTrackBreadth; - } - - const GridLength& maxTrackBreadth() const - { - ASSERT(!m_maxTrackBreadth.isLength() || !m_maxTrackBreadth.length().isUndefined()); - if (m_maxTrackBreadth.isLength() && m_maxTrackBreadth.length().isAuto()) { - DEFINE_STATIC_LOCAL(GridLength, maxContent, (MaxContent)); - return maxContent; - } - return m_maxTrackBreadth; - } - - void setMinMax(const GridLength& minTrackBreadth, const GridLength& maxTrackBreadth) - { - m_type = MinMaxTrackSizing; - m_minTrackBreadth = minTrackBreadth; - m_maxTrackBreadth = maxTrackBreadth; - } + const GridLength& minTrackBreadth() const { return m_minTrackBreadth; } + const GridLength& maxTrackBreadth() const { return m_maxTrackBreadth; } GridTrackSizeType type() const { return m_type; } bool isContentSized() const { return m_minTrackBreadth.isContentSized() || m_maxTrackBreadth.isContentSized(); } + bool isFitContent() const { return m_type == FitContentTrackSizing; } bool operator==(const GridTrackSize& other) const { - return m_type == other.m_type && m_minTrackBreadth == other.m_minTrackBreadth && m_maxTrackBreadth == other.m_maxTrackBreadth; + return m_type == other.m_type && m_minTrackBreadth == other.m_minTrackBreadth && m_maxTrackBreadth == other.m_maxTrackBreadth + && m_fitContentTrackBreadth == other.m_fitContentTrackBreadth; + } + + void cacheMinMaxTrackBreadthTypes() + { + m_minTrackBreadthIsAuto = minTrackBreadth().isLength() && minTrackBreadth().length().isAuto(); + m_minTrackBreadthIsMinContent = minTrackBreadth().isLength() && minTrackBreadth().length().isMinContent(); + m_minTrackBreadthIsMaxContent = minTrackBreadth().isLength() && minTrackBreadth().length().isMaxContent(); + m_maxTrackBreadthIsMaxContent = maxTrackBreadth().isLength() && maxTrackBreadth().length().isMaxContent(); + m_maxTrackBreadthIsMinContent = maxTrackBreadth().isLength() && maxTrackBreadth().length().isMinContent(); + m_maxTrackBreadthIsAuto = maxTrackBreadth().isLength() && maxTrackBreadth().length().isAuto(); + + // These values depend on the above ones so keep them here. + m_minTrackBreadthIsIntrinsic = m_minTrackBreadthIsMaxContent || m_minTrackBreadthIsMinContent + || m_minTrackBreadthIsAuto || isFitContent(); + m_maxTrackBreadthIsIntrinsic = m_maxTrackBreadthIsMaxContent || m_maxTrackBreadthIsMinContent + || m_maxTrackBreadthIsAuto || isFitContent(); } - bool hasMinOrMaxContentMinTrackBreadth() const { return minTrackBreadth().isLength() && (minTrackBreadth().length().isMinContent() || minTrackBreadth().length().isMaxContent()); } - bool hasMaxContentMinTrackBreadth() const { return minTrackBreadth().isLength() && minTrackBreadth().length().isMaxContent(); } - bool hasMinOrMaxContentMaxTrackBreadth() const { return maxTrackBreadth().isLength() && (maxTrackBreadth().length().isMinContent() || maxTrackBreadth().length().isMaxContent()); } - bool hasMaxContentMaxTrackBreadth() const { return maxTrackBreadth().isLength() && maxTrackBreadth().length().isMaxContent(); } + bool hasIntrinsicMinTrackBreadth() const { return m_minTrackBreadthIsIntrinsic; } + bool hasIntrinsicMaxTrackBreadth() const { return m_maxTrackBreadthIsIntrinsic; } + bool hasMinOrMaxContentMinTrackBreadth() const { return m_minTrackBreadthIsMaxContent || m_minTrackBreadthIsMinContent; } + bool hasAutoMinTrackBreadth() const { return m_minTrackBreadthIsAuto; } + bool hasAutoMaxTrackBreadth() const { return m_maxTrackBreadthIsAuto; } + bool hasMaxContentMaxTrackBreadth() const { return m_maxTrackBreadthIsMaxContent; } + bool hasMaxContentOrAutoMaxTrackBreadth() const { return m_maxTrackBreadthIsMaxContent || m_maxTrackBreadthIsAuto; } + bool hasMinContentMaxTrackBreadth() const { return m_maxTrackBreadthIsMinContent; } + bool hasMinOrMaxContentMaxTrackBreadth() const { return m_maxTrackBreadthIsMaxContent || m_maxTrackBreadthIsMinContent; } + bool hasMaxContentMinTrackBreadth() const { return m_minTrackBreadthIsMaxContent; } + bool hasMinContentMinTrackBreadth() const { return m_minTrackBreadthIsMinContent; } + bool hasMaxContentMinTrackBreadthAndMaxContentMaxTrackBreadth() const { return m_minTrackBreadthIsMaxContent && m_maxTrackBreadthIsMaxContent; } + bool hasAutoOrMinContentMinTrackBreadthAndIntrinsicMaxTrackBreadth() const { return (m_minTrackBreadthIsMinContent || m_minTrackBreadthIsAuto) && m_maxTrackBreadthIsIntrinsic; } private: GridTrackSizeType m_type; GridLength m_minTrackBreadth; GridLength m_maxTrackBreadth; + GridLength m_fitContentTrackBreadth; + + bool m_minTrackBreadthIsAuto : 1; + bool m_maxTrackBreadthIsAuto : 1; + bool m_minTrackBreadthIsMaxContent : 1; + bool m_minTrackBreadthIsMinContent : 1; + bool m_maxTrackBreadthIsMaxContent : 1; + bool m_maxTrackBreadthIsMinContent : 1; + bool m_minTrackBreadthIsIntrinsic : 1; + bool m_maxTrackBreadthIsIntrinsic : 1; }; } // namespace WebCore - -#endif // GridTrackSize_h diff --git a/Source/WebCore/rendering/style/KeyframeList.cpp b/Source/WebCore/rendering/style/KeyframeList.cpp index a127b468b..97298ab44 100644 --- a/Source/WebCore/rendering/style/KeyframeList.cpp +++ b/Source/WebCore/rendering/style/KeyframeList.cpp @@ -21,13 +21,29 @@ #include "config.h" #include "KeyframeList.h" + +#include "Animation.h" #include "RenderObject.h" namespace WebCore { +TimingFunction* KeyframeValue::timingFunction(const AtomicString& name) const +{ + auto* keyframeStyle = style(); + if (!keyframeStyle || !keyframeStyle->animations()) + return nullptr; + + for (size_t i = 0; i < keyframeStyle->animations()->size(); ++i) { + const Animation& animation = keyframeStyle->animations()->animation(i); + if (name == animation.name()) + return animation.timingFunction(); + } + + return nullptr; +} + KeyframeList::~KeyframeList() { - clear(); } void KeyframeList::clear() @@ -41,57 +57,43 @@ bool KeyframeList::operator==(const KeyframeList& o) const if (m_keyframes.size() != o.m_keyframes.size()) return false; - Vector<KeyframeValue>::const_iterator it2 = o.m_keyframes.begin(); - for (Vector<KeyframeValue>::const_iterator it1 = m_keyframes.begin(); it1 != m_keyframes.end(); ++it1) { + auto it2 = o.m_keyframes.begin(); + for (auto it1 = m_keyframes.begin(); it1 != m_keyframes.end(); ++it1, ++it2) { if (it1->key() != it2->key()) return false; - const RenderStyle& style1 = *it1->style(); - const RenderStyle& style2 = *it2->style(); - if (style1 != style2) + if (*it1->style() != *it2->style()) return false; - ++it2; } return true; } -void KeyframeList::insert(const KeyframeValue& keyframe) +void KeyframeList::insert(KeyframeValue&& keyframe) { if (keyframe.key() < 0 || keyframe.key() > 1) return; bool inserted = false; - bool replaced = false; - for (size_t i = 0; i < m_keyframes.size(); ++i) { + size_t i = 0; + for (; i < m_keyframes.size(); ++i) { if (m_keyframes[i].key() == keyframe.key()) { - m_keyframes[i] = keyframe; - replaced = true; + ASSERT_NOT_REACHED(); break; } if (m_keyframes[i].key() > keyframe.key()) { // insert before - m_keyframes.insert(i, keyframe); + m_keyframes.insert(i, WTFMove(keyframe)); inserted = true; break; } } - if (!replaced && !inserted) - m_keyframes.append(keyframe); - - if (replaced) { - // We have to rebuild the properties list from scratch. - m_properties.clear(); - for (Vector<KeyframeValue>::const_iterator it = m_keyframes.begin(); it != m_keyframes.end(); ++it) { - const KeyframeValue& currKeyframe = *it; - for (HashSet<CSSPropertyID>::const_iterator it = currKeyframe.properties().begin(); it != currKeyframe.properties().end(); ++it) - m_properties.add(*it); - } - } else { - for (HashSet<CSSPropertyID>::const_iterator it = keyframe.properties().begin(); it != keyframe.properties().end(); ++it) - m_properties.add(*it); - } + if (!inserted) + m_keyframes.append(WTFMove(keyframe)); + + for (auto& property : m_keyframes[i].properties()) + m_properties.add(property); } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/KeyframeList.h b/Source/WebCore/rendering/style/KeyframeList.h index 6b8c7f323..8ba0ac76b 100644 --- a/Source/WebCore/rendering/style/KeyframeList.h +++ b/Source/WebCore/rendering/style/KeyframeList.h @@ -22,8 +22,7 @@ * */ -#ifndef KeyframeList_h -#define KeyframeList_h +#pragma once #include "CSSPropertyNames.h" #include "StyleInheritedData.h" @@ -35,12 +34,13 @@ namespace WebCore { class RenderStyle; +class TimingFunction; class KeyframeValue { public: - KeyframeValue(double key, PassRefPtr<RenderStyle> style) + KeyframeValue(double key, std::unique_ptr<RenderStyle> style) : m_key(key) - , m_style(style) + , m_style(WTFMove(style)) { } @@ -52,12 +52,14 @@ public: void setKey(double key) { m_key = key; } const RenderStyle* style() const { return m_style.get(); } - void setStyle(PassRefPtr<RenderStyle> style) { m_style = style; } + void setStyle(std::unique_ptr<RenderStyle> style) { m_style = WTFMove(style); } + + TimingFunction* timingFunction(const AtomicString& name) const; private: double m_key; HashSet<CSSPropertyID> m_properties; // The properties specified in this keyframe. - RefPtr<RenderStyle> m_style; + std::unique_ptr<RenderStyle> m_style; }; class KeyframeList { @@ -75,17 +77,17 @@ public: const AtomicString& animationName() const { return m_animationName; } - void insert(const KeyframeValue& keyframe); + void insert(KeyframeValue&&); void addProperty(CSSPropertyID prop) { m_properties.add(prop); } bool containsProperty(CSSPropertyID prop) const { return m_properties.contains(prop); } - HashSet<CSSPropertyID>::const_iterator beginProperties() const { return m_properties.begin(); } - HashSet<CSSPropertyID>::const_iterator endProperties() const { return m_properties.end(); } + const HashSet<CSSPropertyID>& properties() const { return m_properties; } void clear(); bool isEmpty() const { return m_keyframes.isEmpty(); } size_t size() const { return m_keyframes.size(); } const KeyframeValue& operator[](size_t index) const { return m_keyframes[index]; } + const Vector<KeyframeValue>& keyframes() const { return m_keyframes; } private: AtomicString m_animationName; @@ -94,5 +96,3 @@ private: }; } // namespace WebCore - -#endif // KeyframeList_h diff --git a/Source/WebCore/rendering/style/LineClampValue.h b/Source/WebCore/rendering/style/LineClampValue.h index 2119ca291..fc041c19e 100644 --- a/Source/WebCore/rendering/style/LineClampValue.h +++ b/Source/WebCore/rendering/style/LineClampValue.h @@ -22,8 +22,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LineClampValue_h -#define LineClampValue_h +#pragma once #include "RenderStyleConstants.h" @@ -65,5 +64,3 @@ private: }; } // namespace WebCore - -#endif // LineClampValue_h diff --git a/Source/WebCore/rendering/style/NinePieceImage.cpp b/Source/WebCore/rendering/style/NinePieceImage.cpp index 43bd1b043..e8c9232c1 100644 --- a/Source/WebCore/rendering/style/NinePieceImage.cpp +++ b/Source/WebCore/rendering/style/NinePieceImage.cpp @@ -2,7 +2,7 @@ * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * (C) 2000 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -23,13 +23,19 @@ #include "config.h" #include "NinePieceImage.h" + +#include "GraphicsContext.h" +#include "LengthFunctions.h" +#include "RenderStyle.h" +#include "TextStream.h" #include <wtf/NeverDestroyed.h> +#include <wtf/PointerComparison.h> namespace WebCore { -static DataRef<NinePieceImageData>& defaultData() +inline DataRef<NinePieceImage::Data>& NinePieceImage::defaultData() { - static NeverDestroyed<DataRef<NinePieceImageData>> data(NinePieceImageData::create()); + static NeverDestroyed<DataRef<Data>> data { Data::create() }; return data.get(); } @@ -38,31 +44,203 @@ NinePieceImage::NinePieceImage() { } -NinePieceImage::NinePieceImage(PassRefPtr<StyleImage> image, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule) - : m_data(NinePieceImageData::create()) +NinePieceImage::NinePieceImage(RefPtr<StyleImage>&& image, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule) + : m_data(Data::create(WTFMove(image), imageSlices, fill, borderSlices, outset, horizontalRule, verticalRule)) +{ +} + +LayoutUnit NinePieceImage::computeSlice(Length length, LayoutUnit width, LayoutUnit slice, LayoutUnit extent) +{ + if (length.isRelative()) + return length.value() * width; + if (length.isAuto()) + return slice; + return valueForLength(length, extent); +} + +LayoutBoxExtent NinePieceImage::computeSlices(const LayoutSize& size, const LengthBox& lengths, int scaleFactor) +{ + return { + std::min(size.height(), valueForLength(lengths.top(), size.height())) * scaleFactor, + std::min(size.width(), valueForLength(lengths.right(), size.width())) * scaleFactor, + std::min(size.height(), valueForLength(lengths.bottom(), size.height())) * scaleFactor, + std::min(size.width(), valueForLength(lengths.left(), size.width())) * scaleFactor + }; +} + +LayoutBoxExtent NinePieceImage::computeSlices(const LayoutSize& size, const LengthBox& lengths, const FloatBoxExtent& widths, const LayoutBoxExtent& slices) { - m_data.access()->image = image; - m_data.access()->imageSlices = std::move(imageSlices); - m_data.access()->borderSlices = std::move(borderSlices); - m_data.access()->outset = std::move(outset); - m_data.access()->fill = fill; - m_data.access()->horizontalRule = horizontalRule; - m_data.access()->verticalRule = verticalRule; + return { + computeSlice(lengths.top(), widths.top(), slices.top(), size.height()), + computeSlice(lengths.right(), widths.right(), slices.right(), size.width()), + computeSlice(lengths.bottom(), widths.bottom(), slices.bottom(), size.height()), + computeSlice(lengths.left(), widths.left(), slices.left(), size.width()) + }; } -NinePieceImageData::NinePieceImageData() +void NinePieceImage::scaleSlicesIfNeeded(const LayoutSize& size, LayoutBoxExtent& slices, float deviceScaleFactor) +{ + LayoutUnit width = std::max<LayoutUnit>(1 / deviceScaleFactor, slices.left() + slices.right()); + LayoutUnit height = std::max<LayoutUnit>(1 / deviceScaleFactor, slices.top() + slices.bottom()); + + float sliceScaleFactor = std::min((float)size.width() / width, (float)size.height() / height); + + if (sliceScaleFactor >= 1) + return; + + // All slices are reduced by multiplying them by sliceScaleFactor. + slices.top() *= sliceScaleFactor; + slices.right() *= sliceScaleFactor; + slices.bottom() *= sliceScaleFactor; + slices.left() *= sliceScaleFactor; +} + +bool NinePieceImage::isEmptyPieceRect(ImagePiece piece, const LayoutBoxExtent& slices) +{ + if (piece == MiddlePiece) + return false; + + PhysicalBoxSide horizontalSide = imagePieceHorizontalSide(piece); + PhysicalBoxSide verticalSide = imagePieceVerticalSide(piece); + return !((horizontalSide == NilSide || slices.at(horizontalSide)) && (verticalSide == NilSide || slices.at(verticalSide))); +} + +bool NinePieceImage::isEmptyPieceRect(ImagePiece piece, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects) +{ + return destinationRects[piece].isEmpty() || sourceRects[piece].isEmpty(); +} + +Vector<FloatRect> NinePieceImage::computeNineRects(const FloatRect& outer, const LayoutBoxExtent& slices, float deviceScaleFactor) +{ + FloatRect inner = outer; + inner.move(slices.left(), slices.top()); + inner.contract(slices.left() + slices.right(), slices.top() + slices.bottom()); + ASSERT(outer.contains(inner)); + + Vector<FloatRect> rects(MaxPiece); + + rects[TopLeftPiece] = snapRectToDevicePixels(outer.x(), outer.y(), slices.left(), slices.top(), deviceScaleFactor); + rects[BottomLeftPiece] = snapRectToDevicePixels(outer.x(), inner.maxY(), slices.left(), slices.bottom(), deviceScaleFactor); + rects[LeftPiece] = snapRectToDevicePixels(outer.x(), inner.y(), slices.left(), inner.height(), deviceScaleFactor); + + rects[TopRightPiece] = snapRectToDevicePixels(inner.maxX(), outer.y(), slices.right(), slices.top(), deviceScaleFactor); + rects[BottomRightPiece] = snapRectToDevicePixels(inner.maxX(), inner.maxY(), slices.right(), slices.bottom(), deviceScaleFactor); + rects[RightPiece] = snapRectToDevicePixels(inner.maxX(), inner.y(), slices.right(), inner.height(), deviceScaleFactor); + + rects[TopPiece] = snapRectToDevicePixels(inner.x(), outer.y(), inner.width(), slices.top(), deviceScaleFactor); + rects[BottomPiece] = snapRectToDevicePixels(inner.x(), inner.maxY(), inner.width(), slices.bottom(), deviceScaleFactor); + + rects[MiddlePiece] = snapRectToDevicePixels(inner.x(), inner.y(), inner.width(), inner.height(), deviceScaleFactor); + return rects; +} + +FloatSize NinePieceImage::computeSideTileScale(ImagePiece piece, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects) +{ + ASSERT(!isCornerPiece(piece) && !isMiddlePiece(piece)); + if (isEmptyPieceRect(piece, destinationRects, sourceRects)) + return FloatSize(1, 1); + + float scale; + if (isHorizontalPiece(piece)) + scale = destinationRects[piece].height() / sourceRects[piece].height(); + else + scale = destinationRects[piece].width() / sourceRects[piece].width(); + + return FloatSize(scale, scale); +} + +FloatSize NinePieceImage::computeMiddleTileScale(const Vector<FloatSize>& scales, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects, ENinePieceImageRule hRule, ENinePieceImageRule vRule) +{ + FloatSize scale(1, 1); + if (isEmptyPieceRect(MiddlePiece, destinationRects, sourceRects)) + return scale; + + // Unlike the side pieces, the middle piece can have "stretch" specified in one axis but not the other. + // In fact the side pieces don't even use the scale factor unless they have a rule other than "stretch". + if (hRule == StretchImageRule) + scale.setWidth(destinationRects[MiddlePiece].width() / sourceRects[MiddlePiece].width()); + else if (!isEmptyPieceRect(TopPiece, destinationRects, sourceRects)) + scale.setWidth(scales[TopPiece].width()); + else if (!isEmptyPieceRect(BottomPiece, destinationRects, sourceRects)) + scale.setWidth(scales[BottomPiece].width()); + + if (vRule == StretchImageRule) + scale.setHeight(destinationRects[MiddlePiece].height() / sourceRects[MiddlePiece].height()); + else if (!isEmptyPieceRect(LeftPiece, destinationRects, sourceRects)) + scale.setHeight(scales[LeftPiece].height()); + else if (!isEmptyPieceRect(RightPiece, destinationRects, sourceRects)) + scale.setHeight(scales[RightPiece].height()); + + return scale; +} + +Vector<FloatSize> NinePieceImage::computeTileScales(const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects, ENinePieceImageRule hRule, ENinePieceImageRule vRule) +{ + Vector<FloatSize> scales(MaxPiece, FloatSize(1, 1)); + + scales[TopPiece] = computeSideTileScale(TopPiece, destinationRects, sourceRects); + scales[RightPiece] = computeSideTileScale(RightPiece, destinationRects, sourceRects); + scales[BottomPiece] = computeSideTileScale(BottomPiece, destinationRects, sourceRects); + scales[LeftPiece] = computeSideTileScale(LeftPiece, destinationRects, sourceRects); + + scales[MiddlePiece] = computeMiddleTileScale(scales, destinationRects, sourceRects, hRule, vRule); + return scales; +} + +void NinePieceImage::paint(GraphicsContext& graphicsContext, RenderElement* renderer, const RenderStyle& style, const LayoutRect& destination, const LayoutSize& source, float deviceScaleFactor, CompositeOperator op) const +{ + StyleImage* styleImage = image(); + ASSERT(styleImage); + ASSERT(styleImage->isLoaded()); + + LayoutBoxExtent sourceSlices = computeSlices(source, imageSlices(), styleImage->imageScaleFactor()); + LayoutBoxExtent destinationSlices = computeSlices(destination.size(), borderSlices(), style.borderWidth(), sourceSlices); + + scaleSlicesIfNeeded(destination.size(), destinationSlices, deviceScaleFactor); + + Vector<FloatRect> destinationRects = computeNineRects(destination, destinationSlices, deviceScaleFactor); + Vector<FloatRect> sourceRects = computeNineRects(FloatRect(FloatPoint(), source), sourceSlices, deviceScaleFactor); + Vector<FloatSize> tileScales = computeTileScales(destinationRects, sourceRects, horizontalRule(), verticalRule()); + + RefPtr<Image> image = styleImage->image(renderer, source); + if (!image) + return; + + for (ImagePiece piece = MinPiece; piece < MaxPiece; ++piece) { + if ((piece == MiddlePiece && !fill()) || isEmptyPieceRect(piece, destinationRects, sourceRects)) + continue; + + if (isCornerPiece(piece)) { + graphicsContext.drawImage(*image, destinationRects[piece], sourceRects[piece], op); + continue; + } + + Image::TileRule hRule = isHorizontalPiece(piece) ? static_cast<Image::TileRule>(horizontalRule()) : Image::StretchTile; + Image::TileRule vRule = isVerticalPiece(piece) ? static_cast<Image::TileRule>(verticalRule()) : Image::StretchTile; + graphicsContext.drawTiledImage(*image, destinationRects[piece], sourceRects[piece], tileScales[piece], hRule, vRule, op); + } +} + +inline NinePieceImage::Data::Data() : fill(false) , horizontalRule(StretchImageRule) , verticalRule(StretchImageRule) - , image(0) - , imageSlices(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent)) - , borderSlices(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative)) - , outset(0) { } -inline NinePieceImageData::NinePieceImageData(const NinePieceImageData& other) - : RefCounted<NinePieceImageData>() +inline NinePieceImage::Data::Data(RefPtr<StyleImage>&& image, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule) + : fill(fill) + , horizontalRule(horizontalRule) + , verticalRule(verticalRule) + , image(WTFMove(image)) + , imageSlices(imageSlices) + , borderSlices(borderSlices) + , outset(outset) +{ +} + +inline NinePieceImage::Data::Data(const Data& other) + : RefCounted<Data>() , fill(other.fill) , horizontalRule(other.horizontalRule) , verticalRule(other.verticalRule) @@ -73,14 +251,24 @@ inline NinePieceImageData::NinePieceImageData(const NinePieceImageData& other) { } -PassRef<NinePieceImageData> NinePieceImageData::copy() const +inline Ref<NinePieceImage::Data> NinePieceImage::Data::create() { - return adoptRef(*new NinePieceImageData(*this)); + return adoptRef(*new Data); } -bool NinePieceImageData::operator==(const NinePieceImageData& other) const +inline Ref<NinePieceImage::Data> NinePieceImage::Data::create(RefPtr<StyleImage>&& image, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule) { - return StyleImage::imagesEquivalent(image.get(), other.image.get()) + return adoptRef(*new Data(WTFMove(image), imageSlices, fill, borderSlices, outset, horizontalRule, verticalRule)); +} + +Ref<NinePieceImage::Data> NinePieceImage::Data::copy() const +{ + return adoptRef(*new Data(*this)); +} + +bool NinePieceImage::Data::operator==(const Data& other) const +{ + return arePointingToEqualData(image, other.image) && imageSlices == other.imageSlices && fill == other.fill && borderSlices == other.borderSlices @@ -89,4 +277,10 @@ bool NinePieceImageData::operator==(const NinePieceImageData& other) const && verticalRule == other.verticalRule; } +TextStream& operator<<(TextStream& ts, const NinePieceImage& image) +{ + ts << "style-image " << image.image() << " slices " << image.imageSlices(); + return ts; +} + } diff --git a/Source/WebCore/rendering/style/NinePieceImage.h b/Source/WebCore/rendering/style/NinePieceImage.h index e34924147..2b5fe6554 100644 --- a/Source/WebCore/rendering/style/NinePieceImage.h +++ b/Source/WebCore/rendering/style/NinePieceImage.h @@ -2,7 +2,7 @@ * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * (C) 2000 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,98 +21,140 @@ * */ -#ifndef NinePieceImage_h -#define NinePieceImage_h +#pragma once #include "DataRef.h" -#include "LayoutUnit.h" #include "LengthBox.h" #include "StyleImage.h" +#include <wtf/Vector.h> namespace WebCore { -enum ENinePieceImageRule { - StretchImageRule, RoundImageRule, SpaceImageRule, RepeatImageRule +class LayoutSize; +class LayoutRect; +class RenderStyle; + +enum ENinePieceImageRule { StretchImageRule, RoundImageRule, SpaceImageRule, RepeatImageRule }; + +enum ImagePiece { + MinPiece = 0, + TopLeftPiece = MinPiece, + LeftPiece, + BottomLeftPiece, + TopRightPiece, + RightPiece, + BottomRightPiece, + TopPiece, + BottomPiece, + MiddlePiece, + MaxPiece }; -class NinePieceImageData : public RefCounted<NinePieceImageData> { -public: - static PassRef<NinePieceImageData> create() { return adoptRef(*new NinePieceImageData); } - PassRef<NinePieceImageData> copy() const; +inline ImagePiece& operator++(ImagePiece& piece) +{ + piece = static_cast<ImagePiece>(static_cast<int>(piece) + 1); + return piece; +} - bool operator==(const NinePieceImageData&) const; - bool operator!=(const NinePieceImageData& o) const { return !(*this == o); } +inline bool isCornerPiece(ImagePiece piece) +{ + return piece == TopLeftPiece || piece == TopRightPiece || piece == BottomLeftPiece || piece == BottomRightPiece; +} - bool fill : 1; - unsigned horizontalRule : 2; // ENinePieceImageRule - unsigned verticalRule : 2; // ENinePieceImageRule - RefPtr<StyleImage> image; - LengthBox imageSlices; - LengthBox borderSlices; - LengthBox outset; +inline bool isMiddlePiece(ImagePiece piece) +{ + return piece == MiddlePiece; +} -private: - NinePieceImageData(); - NinePieceImageData(const NinePieceImageData&); -}; +inline bool isHorizontalPiece(ImagePiece piece) +{ + return piece == TopPiece || piece == BottomPiece || piece == MiddlePiece; +} + +inline bool isVerticalPiece(ImagePiece piece) +{ + return piece == LeftPiece || piece == RightPiece || piece == MiddlePiece; +} + +inline PhysicalBoxSide imagePieceHorizontalSide(ImagePiece piece) +{ + if (piece == TopLeftPiece || piece == TopPiece || piece == TopRightPiece) + return TopSide; + + if (piece == BottomLeftPiece || piece == BottomPiece || piece == BottomRightPiece) + return BottomSide; + + return NilSide; +} + +inline PhysicalBoxSide imagePieceVerticalSide(ImagePiece piece) +{ + if (piece == TopLeftPiece || piece == LeftPiece || piece == BottomLeftPiece) + return LeftSide; + + if (piece == TopRightPiece || piece == RightPiece || piece == BottomRightPiece) + return RightSide; + + return NilSide; +} class NinePieceImage { public: NinePieceImage(); - NinePieceImage(PassRefPtr<StyleImage>, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule); + NinePieceImage(RefPtr<StyleImage>&&, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule); bool operator==(const NinePieceImage& other) const { return m_data == other.m_data; } bool operator!=(const NinePieceImage& other) const { return m_data != other.m_data; } bool hasImage() const { return m_data->image; } StyleImage* image() const { return m_data->image.get(); } - void setImage(PassRefPtr<StyleImage> image) { m_data.access()->image = image; } - + void setImage(RefPtr<StyleImage>&& image) { m_data.access().image = WTFMove(image); } + const LengthBox& imageSlices() const { return m_data->imageSlices; } - void setImageSlices(LengthBox slices) { m_data.access()->imageSlices = std::move(slices); } + void setImageSlices(LengthBox slices) { m_data.access().imageSlices = WTFMove(slices); } bool fill() const { return m_data->fill; } - void setFill(bool fill) { m_data.access()->fill = fill; } + void setFill(bool fill) { m_data.access().fill = fill; } const LengthBox& borderSlices() const { return m_data->borderSlices; } - void setBorderSlices(LengthBox slices) { m_data.access()->borderSlices = std::move(slices); } + void setBorderSlices(LengthBox slices) { m_data.access().borderSlices = WTFMove(slices); } const LengthBox& outset() const { return m_data->outset; } - void setOutset(LengthBox outset) { m_data.access()->outset = std::move(outset); } + void setOutset(LengthBox outset) { m_data.access().outset = WTFMove(outset); } ENinePieceImageRule horizontalRule() const { return static_cast<ENinePieceImageRule>(m_data->horizontalRule); } - void setHorizontalRule(ENinePieceImageRule rule) { m_data.access()->horizontalRule = rule; } + void setHorizontalRule(ENinePieceImageRule rule) { m_data.access().horizontalRule = rule; } ENinePieceImageRule verticalRule() const { return static_cast<ENinePieceImageRule>(m_data->verticalRule); } - void setVerticalRule(ENinePieceImageRule rule) { m_data.access()->verticalRule = rule; } + void setVerticalRule(ENinePieceImageRule rule) { m_data.access().verticalRule = rule; } void copyImageSlicesFrom(const NinePieceImage& other) { - m_data.access()->imageSlices = other.m_data->imageSlices; - m_data.access()->fill = other.m_data->fill; + m_data.access().imageSlices = other.m_data->imageSlices; + m_data.access().fill = other.m_data->fill; } void copyBorderSlicesFrom(const NinePieceImage& other) { - m_data.access()->borderSlices = other.m_data->borderSlices; + m_data.access().borderSlices = other.m_data->borderSlices; } void copyOutsetFrom(const NinePieceImage& other) { - m_data.access()->outset = other.m_data->outset; + m_data.access().outset = other.m_data->outset; } void copyRepeatFrom(const NinePieceImage& other) { - m_data.access()->horizontalRule = other.m_data->horizontalRule; - m_data.access()->verticalRule = other.m_data->verticalRule; + m_data.access().horizontalRule = other.m_data->horizontalRule; + m_data.access().verticalRule = other.m_data->verticalRule; } void setMaskDefaults() { - m_data.access()->imageSlices = LengthBox(0); - m_data.access()->fill = true; - m_data.access()->borderSlices = LengthBox(); + m_data.access().imageSlices = LengthBox(0); + m_data.access().fill = true; + m_data.access().borderSlices = LengthBox(); } static LayoutUnit computeOutset(const Length& outsetSide, LayoutUnit borderSide) @@ -122,10 +164,51 @@ public: return outsetSide.value(); } + static LayoutUnit computeSlice(Length, LayoutUnit width, LayoutUnit slice, LayoutUnit extent); + static LayoutBoxExtent computeSlices(const LayoutSize&, const LengthBox& lengths, int scaleFactor); + static LayoutBoxExtent computeSlices(const LayoutSize&, const LengthBox& lengths, const FloatBoxExtent& widths, const LayoutBoxExtent& slices); + + static bool isEmptyPieceRect(ImagePiece, const LayoutBoxExtent& slices); + static bool isEmptyPieceRect(ImagePiece, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects); + + static Vector<FloatRect> computeNineRects(const FloatRect& outer, const LayoutBoxExtent& slices, float deviceScaleFactor); + + static void scaleSlicesIfNeeded(const LayoutSize&, LayoutBoxExtent& slices, float deviceScaleFactor); + + static FloatSize computeSideTileScale(ImagePiece, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects); + static FloatSize computeMiddleTileScale(const Vector<FloatSize>& scales, const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects, ENinePieceImageRule hRule, ENinePieceImageRule vRule); + static Vector<FloatSize> computeTileScales(const Vector<FloatRect>& destinationRects, const Vector<FloatRect>& sourceRects, ENinePieceImageRule hRule, ENinePieceImageRule vRule); + + void paint(GraphicsContext&, RenderElement*, const RenderStyle&, const LayoutRect& destination, const LayoutSize& source, float deviceScaleFactor, CompositeOperator) const; + private: - DataRef<NinePieceImageData> m_data; + struct Data : RefCounted<Data> { + static Ref<Data> create(); + static Ref<Data> create(RefPtr<StyleImage>&&, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule); + Ref<Data> copy() const; + + bool operator==(const Data&) const; + bool operator!=(const Data& other) const { return !(*this == other); } + + bool fill : 1; + unsigned horizontalRule : 2; // ENinePieceImageRule + unsigned verticalRule : 2; // ENinePieceImageRule + RefPtr<StyleImage> image; + LengthBox imageSlices { { 100, Percent }, { 100, Percent }, { 100, Percent }, { 100, Percent } }; + LengthBox borderSlices { { 1, Relative }, { 1, Relative }, { 1, Relative }, { 1, Relative } }; + LengthBox outset { 0 }; + + private: + Data(); + Data(RefPtr<StyleImage>&&, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule); + Data(const Data&); + }; + + static DataRef<Data>& defaultData(); + + DataRef<Data> m_data; }; -} // namespace WebCore +TextStream& operator<<(TextStream&, const NinePieceImage&); -#endif // NinePieceImage_h +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/OutlineValue.h b/Source/WebCore/rendering/style/OutlineValue.h index f380af628..202932c7c 100644 --- a/Source/WebCore/rendering/style/OutlineValue.h +++ b/Source/WebCore/rendering/style/OutlineValue.h @@ -22,8 +22,7 @@ * */ -#ifndef OutlineValue_h -#define OutlineValue_h +#pragma once #include "BorderValue.h" @@ -32,14 +31,9 @@ namespace WebCore { class OutlineValue : public BorderValue { friend class RenderStyle; public: - OutlineValue() - : m_offset(0) - { - } - bool operator==(const OutlineValue& o) const { - return m_width == o.m_width && m_style == o.m_style && m_color == o.m_color && m_colorIsValid == o.m_colorIsValid && m_offset == o.m_offset && m_isAuto == o.m_isAuto; + return m_width == o.m_width && m_style == o.m_style && m_color == o.m_color && m_offset == o.m_offset && m_isAuto == o.m_isAuto; } bool operator!=(const OutlineValue& o) const @@ -47,13 +41,11 @@ public: return !(*this == o); } - int offset() const { return m_offset; } + float offset() const { return m_offset; } OutlineIsAuto isAuto() const { return static_cast<OutlineIsAuto>(m_isAuto); } private: - int m_offset; + float m_offset { 0 }; }; } // namespace WebCore - -#endif // OutlineValue_h diff --git a/Source/WebCore/rendering/style/QuotesData.cpp b/Source/WebCore/rendering/style/QuotesData.cpp index 43b0df24b..2c1acebc7 100644 --- a/Source/WebCore/rendering/style/QuotesData.cpp +++ b/Source/WebCore/rendering/style/QuotesData.cpp @@ -29,10 +29,10 @@ static size_t sizeForQuotesDataWithQuoteCount(unsigned count) return sizeof(QuotesData) + sizeof(std::pair<String, String>) * count; } -PassRefPtr<QuotesData> QuotesData::create(const Vector<std::pair<String, String>>& quotes) +Ref<QuotesData> QuotesData::create(const Vector<std::pair<String, String>>& quotes) { void* slot = fastMalloc(sizeForQuotesDataWithQuoteCount(quotes.size())); - return adoptRef(new (NotNull, slot) QuotesData(quotes)); + return adoptRef(*new (NotNull, slot) QuotesData(quotes)); } QuotesData::QuotesData(const Vector<std::pair<String, String>>& quotes) diff --git a/Source/WebCore/rendering/style/QuotesData.h b/Source/WebCore/rendering/style/QuotesData.h index 07e92530f..3c743aefd 100644 --- a/Source/WebCore/rendering/style/QuotesData.h +++ b/Source/WebCore/rendering/style/QuotesData.h @@ -19,10 +19,8 @@ * */ -#ifndef QuotesData_h -#define QuotesData_h +#pragma once -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/Vector.h> #include <wtf/text/WTFString.h> @@ -36,7 +34,7 @@ namespace WebCore { class QuotesData : public RefCounted<QuotesData> { public: - static PassRefPtr<QuotesData> create(const Vector<std::pair<String, String>>& quotes); + static Ref<QuotesData> create(const Vector<std::pair<String, String>>& quotes); ~QuotesData(); friend bool operator==(const QuotesData&, const QuotesData&); @@ -61,5 +59,3 @@ inline bool operator!=(const QuotesData& a, const QuotesData& b) } } // namespace WebCore - -#endif // QuotesData_h diff --git a/Source/WebCore/rendering/style/RenderStyle.cpp b/Source/WebCore/rendering/style/RenderStyle.cpp index fffd1c19f..eb4447957 100644 --- a/Source/WebCore/rendering/style/RenderStyle.cpp +++ b/Source/WebCore/rendering/style/RenderStyle.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2004-2017 Apple Inc. All rights reserved. * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -24,217 +24,302 @@ #include "RenderStyle.h" #include "ContentData.h" -#include "CursorList.h" +#include "CSSCustomPropertyValue.h" +#include "CSSParser.h" #include "CSSPropertyNames.h" -#include "Font.h" +#include "CursorList.h" +#include "FloatRoundedRect.h" +#include "FontCascade.h" #include "FontSelector.h" +#include "InlineTextBoxStyle.h" #include "Pagination.h" #include "QuotesData.h" #include "RenderObject.h" +#include "RenderTheme.h" +#include "RuntimeEnabledFeatures.h" #include "ScaleTransformOperation.h" #include "ShadowData.h" #include "StyleImage.h" #include "StyleInheritedData.h" #include "StyleResolver.h" -#if ENABLE(TOUCH_EVENTS) -#include "RenderTheme.h" -#endif +#include "StyleScrollSnapPoints.h" +#include "StyleSelfAlignmentData.h" +#include "StyleTreeResolver.h" +#include "WillChangeData.h" #include <wtf/MathExtras.h> +#include <wtf/PointerComparison.h> #include <wtf/StdLibExtras.h> #include <algorithm> -#if ENABLE(IOS_TEXT_AUTOSIZING) -#include <wtf/text/StringHash.h> -#endif - #if ENABLE(TEXT_AUTOSIZING) -#include "TextAutosizer.h" +#include <wtf/text/StringHash.h> #endif namespace WebCore { struct SameSizeAsBorderValue { - RGBA32 m_color; - unsigned m_width; + float m_width; + Color m_color; + int m_restBits; }; COMPILE_ASSERT(sizeof(BorderValue) == sizeof(SameSizeAsBorderValue), BorderValue_should_not_grow); -struct SameSizeAsRenderStyle : public RefCounted<SameSizeAsRenderStyle> { +struct SameSizeAsRenderStyle { void* dataRefs[7]; void* ownPtrs[1]; -#if ENABLE(SVG) void* dataRefSvgStyle; -#endif struct InheritedFlags { unsigned m_bitfields[2]; - } inherited_flags; + } m_inheritedFlags; struct NonInheritedFlags { - unsigned m_bitfields[2]; - } noninherited_flags; + uint64_t m_flags; + } m_nonInheritedFlags; +#if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS) + bool deletionCheck; +#endif }; COMPILE_ASSERT(sizeof(RenderStyle) == sizeof(SameSizeAsRenderStyle), RenderStyle_should_stay_small); -inline RenderStyle& defaultStyle() +RenderStyle& RenderStyle::defaultStyle() { - static RenderStyle& style = RenderStyle::createDefaultStyle().leakRef(); + static NeverDestroyed<RenderStyle> style { CreateDefaultStyle }; return style; } -PassRef<RenderStyle> RenderStyle::create() +RenderStyle RenderStyle::create() { - return adoptRef(*new RenderStyle()); + return clone(defaultStyle()); } -PassRef<RenderStyle> RenderStyle::createDefaultStyle() +std::unique_ptr<RenderStyle> RenderStyle::createPtr() { - return adoptRef(*new RenderStyle(true)); + return clonePtr(defaultStyle()); } -PassRef<RenderStyle> RenderStyle::createAnonymousStyleWithDisplay(const RenderStyle* parentStyle, EDisplay display) +RenderStyle RenderStyle::clone(const RenderStyle& style) { - auto newStyle = RenderStyle::create(); - newStyle.get().inheritFrom(parentStyle); - newStyle.get().inheritUnicodeBidiFrom(parentStyle); - newStyle.get().setDisplay(display); - return newStyle; + return RenderStyle(style, Clone); } -PassRef<RenderStyle> RenderStyle::clone(const RenderStyle* other) +std::unique_ptr<RenderStyle> RenderStyle::clonePtr(const RenderStyle& style) { - return adoptRef(*new RenderStyle(*other)); + return std::make_unique<RenderStyle>(style, Clone); } -PassRef<RenderStyle> RenderStyle::createStyleInheritingFromPseudoStyle(const RenderStyle& pseudoStyle) +RenderStyle RenderStyle::createAnonymousStyleWithDisplay(const RenderStyle& parentStyle, EDisplay display) +{ + auto newStyle = create(); + newStyle.inheritFrom(parentStyle); + newStyle.inheritUnicodeBidiFrom(&parentStyle); + newStyle.setDisplay(display); + return newStyle; +} + +RenderStyle RenderStyle::createStyleInheritingFromPseudoStyle(const RenderStyle& pseudoStyle) { ASSERT(pseudoStyle.styleType() == BEFORE || pseudoStyle.styleType() == AFTER); - // Images are special and must inherit the pseudoStyle so the width and height of - // the pseudo element doesn't change the size of the image. In all other cases we - // can just share the style. - auto style = RenderStyle::create(); - style.get().inheritFrom(&pseudoStyle); + auto style = create(); + style.inheritFrom(pseudoStyle); return style; } -ALWAYS_INLINE RenderStyle::RenderStyle() - : m_box(defaultStyle().m_box) - , visual(defaultStyle().visual) - , m_background(defaultStyle().m_background) - , surround(defaultStyle().surround) - , rareNonInheritedData(defaultStyle().rareNonInheritedData) - , rareInheritedData(defaultStyle().rareInheritedData) - , inherited(defaultStyle().inherited) -#if ENABLE(SVG) - , m_svgStyle(defaultStyle().m_svgStyle) +RenderStyle::RenderStyle(CreateDefaultStyleTag) + : m_boxData(StyleBoxData::create()) + , m_visualData(StyleVisualData::create()) + , m_backgroundData(StyleBackgroundData::create()) + , m_surroundData(StyleSurroundData::create()) + , m_rareNonInheritedData(StyleRareNonInheritedData::create()) + , m_rareInheritedData(StyleRareInheritedData::create()) + , m_inheritedData(StyleInheritedData::create()) + , m_svgStyle(SVGRenderStyle::create()) +{ + m_inheritedFlags.emptyCells = initialEmptyCells(); + m_inheritedFlags.captionSide = initialCaptionSide(); + m_inheritedFlags.listStyleType = initialListStyleType(); + m_inheritedFlags.listStylePosition = initialListStylePosition(); + m_inheritedFlags.visibility = initialVisibility(); + m_inheritedFlags.textAlign = initialTextAlign(); + m_inheritedFlags.textTransform = initialTextTransform(); + m_inheritedFlags.textDecorations = initialTextDecoration(); + m_inheritedFlags.cursor = initialCursor(); +#if ENABLE(CURSOR_VISIBILITY) + m_inheritedFlags.cursorVisibility = initialCursorVisibility(); +#endif + m_inheritedFlags.direction = initialDirection(); + m_inheritedFlags.whiteSpace = initialWhiteSpace(); + m_inheritedFlags.borderCollapse = initialBorderCollapse(); + m_inheritedFlags.rtlOrdering = initialRTLOrdering(); + m_inheritedFlags.boxDirection = initialBoxDirection(); + m_inheritedFlags.printColorAdjust = initialPrintColorAdjust(); + m_inheritedFlags.pointerEvents = initialPointerEvents(); + m_inheritedFlags.insideLink = NotInsideLink; + m_inheritedFlags.insideDefaultButton = false; + m_inheritedFlags.writingMode = initialWritingMode(); + + static_assert((sizeof(InheritedFlags) <= 8), "InheritedFlags does not grow"); + static_assert((sizeof(NonInheritedFlags) <= 8), "NonInheritedFlags does not grow"); +} + +inline RenderStyle::RenderStyle(const RenderStyle& other, CloneTag) + : m_boxData(other.m_boxData) + , m_visualData(other.m_visualData) + , m_backgroundData(other.m_backgroundData) + , m_surroundData(other.m_surroundData) + , m_rareNonInheritedData(other.m_rareNonInheritedData) + , m_nonInheritedFlags(other.m_nonInheritedFlags) + , m_rareInheritedData(other.m_rareInheritedData) + , m_inheritedData(other.m_inheritedData) + , m_inheritedFlags(other.m_inheritedFlags) + , m_svgStyle(other.m_svgStyle) +{ +} + +inline RenderStyle::RenderStyle(RenderStyle& a, RenderStyle&& b) + : m_boxData(a.m_boxData.replace(WTFMove(b.m_boxData))) + , m_visualData(a.m_visualData.replace(WTFMove(b.m_visualData))) + , m_backgroundData(a.m_backgroundData.replace(WTFMove(b.m_backgroundData))) + , m_surroundData(a.m_surroundData.replace(WTFMove(b.m_surroundData))) + , m_rareNonInheritedData(a.m_rareNonInheritedData.replace(WTFMove(b.m_rareNonInheritedData))) + , m_nonInheritedFlags(std::exchange(a.m_nonInheritedFlags, b.m_nonInheritedFlags)) + , m_rareInheritedData(a.m_rareInheritedData.replace(WTFMove(b.m_rareInheritedData))) + , m_inheritedData(a.m_inheritedData.replace(WTFMove(b.m_inheritedData))) + , m_inheritedFlags(std::exchange(a.m_inheritedFlags, b.m_inheritedFlags)) + , m_cachedPseudoStyles(std::exchange(a.m_cachedPseudoStyles, WTFMove(b.m_cachedPseudoStyles))) + , m_svgStyle(a.m_svgStyle.replace(WTFMove(b.m_svgStyle))) +{ +} + +RenderStyle::~RenderStyle() +{ +#if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS) + ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun); + m_deletionHasBegun = true; #endif +} + +RenderStyle RenderStyle::replace(RenderStyle&& newStyle) { - setBitDefaults(); // Would it be faster to copy this from the default style? - COMPILE_ASSERT((sizeof(InheritedFlags) <= 8), InheritedFlags_does_not_grow); - COMPILE_ASSERT((sizeof(NonInheritedFlags) <= 8), NonInheritedFlags_does_not_grow); + return RenderStyle { *this, WTFMove(newStyle) }; } -ALWAYS_INLINE RenderStyle::RenderStyle(bool) - : m_box(StyleBoxData::create()) - , visual(StyleVisualData::create()) - , m_background(StyleBackgroundData::create()) - , surround(StyleSurroundData::create()) - , rareNonInheritedData(StyleRareNonInheritedData::create()) - , rareInheritedData(StyleRareInheritedData::create()) - , inherited(StyleInheritedData::create()) -#if ENABLE(SVG) - , m_svgStyle(SVGRenderStyle::create()) -#endif +bool RenderStyle::isCSSGridLayoutEnabled() { - setBitDefaults(); + return RuntimeEnabledFeatures::sharedFeatures().isCSSGridLayoutEnabled(); } -ALWAYS_INLINE RenderStyle::RenderStyle(const RenderStyle& o) - : RefCounted<RenderStyle>() - , m_box(o.m_box) - , visual(o.visual) - , m_background(o.m_background) - , surround(o.surround) - , rareNonInheritedData(o.rareNonInheritedData) - , rareInheritedData(o.rareInheritedData) - , inherited(o.inherited) -#if ENABLE(SVG) - , m_svgStyle(o.m_svgStyle) -#endif - , inherited_flags(o.inherited_flags) - , noninherited_flags(o.noninherited_flags) +static StyleSelfAlignmentData resolvedSelfAlignment(const StyleSelfAlignmentData& value, ItemPosition normalValueBehavior) { + ASSERT(value.position() != ItemPositionAuto); + if (value.position() == ItemPositionNormal) + return { normalValueBehavior, OverflowAlignmentDefault }; + return value; } -void RenderStyle::inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary isAtShadowBoundary) +StyleSelfAlignmentData RenderStyle::resolvedAlignItems(ItemPosition normalValueBehaviour) const { - if (isAtShadowBoundary == AtShadowBoundary) { - // Even if surrounding content is user-editable, shadow DOM should act as a single unit, and not necessarily be editable - EUserModify currentUserModify = userModify(); - rareInheritedData = inheritParent->rareInheritedData; - setUserModify(currentUserModify); - } else - rareInheritedData = inheritParent->rareInheritedData; - inherited = inheritParent->inherited; - inherited_flags = inheritParent->inherited_flags; -#if ENABLE(SVG) - if (m_svgStyle != inheritParent->m_svgStyle) - m_svgStyle.access()->inheritFrom(inheritParent->m_svgStyle.get()); -#endif + return resolvedSelfAlignment(alignItems(), normalValueBehaviour); } -void RenderStyle::copyNonInheritedFrom(const RenderStyle* other) -{ - m_box = other->m_box; - visual = other->visual; - m_background = other->m_background; - surround = other->surround; - rareNonInheritedData = other->rareNonInheritedData; - // The flags are copied one-by-one because noninherited_flags contains a bunch of stuff other than real style data. - noninherited_flags._effectiveDisplay = other->noninherited_flags._effectiveDisplay; - noninherited_flags._originalDisplay = other->noninherited_flags._originalDisplay; - noninherited_flags._overflowX = other->noninherited_flags._overflowX; - noninherited_flags._overflowY = other->noninherited_flags._overflowY; - noninherited_flags._vertical_align = other->noninherited_flags._vertical_align; - noninherited_flags._clear = other->noninherited_flags._clear; - noninherited_flags._position = other->noninherited_flags._position; - noninherited_flags._floating = other->noninherited_flags._floating; - noninherited_flags._table_layout = other->noninherited_flags._table_layout; - noninherited_flags._unicodeBidi = other->noninherited_flags._unicodeBidi; - noninherited_flags._page_break_before = other->noninherited_flags._page_break_before; - noninherited_flags._page_break_after = other->noninherited_flags._page_break_after; - noninherited_flags._page_break_inside = other->noninherited_flags._page_break_inside; - noninherited_flags.explicitInheritance = other->noninherited_flags.explicitInheritance; -#if ENABLE(SVG) - if (m_svgStyle != other->m_svgStyle) - m_svgStyle.access()->copyNonInheritedFrom(other->m_svgStyle.get()); -#endif - ASSERT(zoom() == initialZoom()); +StyleSelfAlignmentData RenderStyle::resolvedAlignSelf(const RenderStyle& parentStyle, ItemPosition normalValueBehaviour) const +{ + // The auto keyword computes to the parent's align-items computed value. + // We will return the behaviour of 'normal' value if needed, which is specific of each layout model. + if (alignSelf().position() == ItemPositionAuto) + return parentStyle.resolvedAlignItems(normalValueBehaviour); + return resolvedSelfAlignment(alignSelf(), normalValueBehaviour); } -bool RenderStyle::operator==(const RenderStyle& o) const +StyleSelfAlignmentData RenderStyle::resolvedJustifyItems(ItemPosition normalValueBehaviour) const { - // compare everything except the pseudoStyle pointer - return inherited_flags == o.inherited_flags - && noninherited_flags == o.noninherited_flags - && m_box == o.m_box - && visual == o.visual - && m_background == o.m_background - && surround == o.surround - && rareNonInheritedData == o.rareNonInheritedData - && rareInheritedData == o.rareInheritedData - && inherited == o.inherited -#if ENABLE(SVG) - && m_svgStyle == o.m_svgStyle -#endif - ; + // FIXME: justify-items 'auto' value is allowed only to provide the 'legacy' keyword's behavior, which it's still not implemented for layout. + // "If the inherited value of justify-items includes the legacy keyword, auto computes to the inherited value." + // https://drafts.csswg.org/css-align/#justify-items-property + if (justifyItems().position() == ItemPositionAuto) + return { normalValueBehaviour, OverflowAlignmentDefault }; + return resolvedSelfAlignment(justifyItems(), normalValueBehaviour); +} + +StyleSelfAlignmentData RenderStyle::resolvedJustifySelf(const RenderStyle& parentStyle, ItemPosition normalValueBehaviour) const +{ + // The auto keyword computes to the parent's justify-items computed value. + // We will return the behaviour of 'normal' value if needed, which is specific of each layout model. + if (justifySelf().position() == ItemPositionAuto) + return parentStyle.resolvedJustifyItems(normalValueBehaviour); + return resolvedSelfAlignment(justifySelf(), normalValueBehaviour); +} + +static inline ContentPosition resolvedContentAlignmentPosition(const StyleContentAlignmentData& value, const StyleContentAlignmentData& normalValueBehavior) +{ + return (value.position() == ContentPositionNormal && value.distribution() == ContentDistributionDefault) ? normalValueBehavior.position() : value.position(); +} + +static inline ContentDistributionType resolvedContentAlignmentDistribution(const StyleContentAlignmentData& value, const StyleContentAlignmentData& normalValueBehavior) +{ + return (value.position() == ContentPositionNormal && value.distribution() == ContentDistributionDefault) ? normalValueBehavior.distribution() : value.distribution(); +} + +ContentPosition RenderStyle::resolvedJustifyContentPosition(const StyleContentAlignmentData& normalValueBehavior) const +{ + return resolvedContentAlignmentPosition(justifyContent(), normalValueBehavior); +} + +ContentDistributionType RenderStyle::resolvedJustifyContentDistribution(const StyleContentAlignmentData& normalValueBehavior) const +{ + return resolvedContentAlignmentDistribution(justifyContent(), normalValueBehavior); +} + +ContentPosition RenderStyle::resolvedAlignContentPosition(const StyleContentAlignmentData& normalValueBehavior) const +{ + return resolvedContentAlignmentPosition(alignContent(), normalValueBehavior); } -bool RenderStyle::isStyleAvailable() const +ContentDistributionType RenderStyle::resolvedAlignContentDistribution(const StyleContentAlignmentData& normalValueBehavior) const { - return this != StyleResolver::styleNotYetAvailable(); + return resolvedContentAlignmentDistribution(alignContent(), normalValueBehavior); +} + +void RenderStyle::inheritFrom(const RenderStyle& inheritParent) +{ + m_rareInheritedData = inheritParent.m_rareInheritedData; + m_inheritedData = inheritParent.m_inheritedData; + m_inheritedFlags = inheritParent.m_inheritedFlags; + + if (m_svgStyle != inheritParent.m_svgStyle) + m_svgStyle.access().inheritFrom(inheritParent.m_svgStyle.get()); +} + +void RenderStyle::copyNonInheritedFrom(const RenderStyle& other) +{ + m_boxData = other.m_boxData; + m_visualData = other.m_visualData; + m_backgroundData = other.m_backgroundData; + m_surroundData = other.m_surroundData; + m_rareNonInheritedData = other.m_rareNonInheritedData; + m_nonInheritedFlags.copyNonInheritedFrom(other.m_nonInheritedFlags); + + if (m_svgStyle != other.m_svgStyle) + m_svgStyle.access().copyNonInheritedFrom(other.m_svgStyle.get()); + + ASSERT(zoom() == initialZoom()); +} + +bool RenderStyle::operator==(const RenderStyle& other) const +{ + // compare everything except the pseudoStyle pointer + return m_inheritedFlags == other.m_inheritedFlags + && m_nonInheritedFlags == other.m_nonInheritedFlags + && m_boxData == other.m_boxData + && m_visualData == other.m_visualData + && m_backgroundData == other.m_backgroundData + && m_surroundData == other.m_surroundData + && m_rareNonInheritedData == other.m_rareNonInheritedData + && m_rareInheritedData == other.m_rareInheritedData + && m_inheritedData == other.m_inheritedData + && m_svgStyle == other.m_svgStyle; } bool RenderStyle::hasUniquePseudoStyle() const @@ -242,8 +327,7 @@ bool RenderStyle::hasUniquePseudoStyle() const if (!m_cachedPseudoStyles || styleType() != NOPSEUDO) return false; - for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) { - RenderStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get(); + for (auto& pseudoStyle : *m_cachedPseudoStyles) { if (pseudoStyle->unique()) return true; } @@ -254,33 +338,32 @@ bool RenderStyle::hasUniquePseudoStyle() const RenderStyle* RenderStyle::getCachedPseudoStyle(PseudoId pid) const { if (!m_cachedPseudoStyles || !m_cachedPseudoStyles->size()) - return 0; + return nullptr; if (styleType() != NOPSEUDO) - return 0; + return nullptr; - for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) { - RenderStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get(); + for (auto& pseudoStyle : *m_cachedPseudoStyles) { if (pseudoStyle->styleType() == pid) - return pseudoStyle; + return pseudoStyle.get(); } - return 0; + return nullptr; } -RenderStyle* RenderStyle::addCachedPseudoStyle(PassRefPtr<RenderStyle> pseudo) +RenderStyle* RenderStyle::addCachedPseudoStyle(std::unique_ptr<RenderStyle> pseudo) { if (!pseudo) - return 0; + return nullptr; ASSERT(pseudo->styleType() > NOPSEUDO); RenderStyle* result = pseudo.get(); if (!m_cachedPseudoStyles) - m_cachedPseudoStyles = adoptPtr(new PseudoStyleCache); + m_cachedPseudoStyles = std::make_unique<PseudoStyleCache>(); - m_cachedPseudoStyles->append(pseudo); + m_cachedPseudoStyles->append(WTFMove(pseudo)); return result; } @@ -300,81 +383,76 @@ void RenderStyle::removeCachedPseudoStyle(PseudoId pid) bool RenderStyle::inheritedNotEqual(const RenderStyle* other) const { - return inherited_flags != other->inherited_flags - || inherited != other->inherited -#if ENABLE(SVG) - || m_svgStyle->inheritedNotEqual(other->m_svgStyle.get()) -#endif - || rareInheritedData != other->rareInheritedData; + return m_inheritedFlags != other->m_inheritedFlags + || m_inheritedData != other->m_inheritedData + || m_svgStyle->inheritedNotEqual(other->m_svgStyle) + || m_rareInheritedData != other->m_rareInheritedData; } -#if ENABLE(IOS_TEXT_AUTOSIZING) -inline unsigned computeFontHash(const Font& font) +#if ENABLE(TEXT_AUTOSIZING) + +static inline unsigned computeFontHash(const FontCascade& font) { - unsigned hashCodes[2] = { - CaseFoldingHash::hash(font.fontDescription().firstFamily().impl()), - static_cast<unsigned>(font.fontDescription().specifiedSize()) - }; - return StringHasher::computeHash(reinterpret_cast<UChar*>(hashCodes), 2 * sizeof(unsigned) / sizeof(UChar)); + IntegerHasher hasher; + hasher.add(ASCIICaseInsensitiveHash::hash(font.fontDescription().firstFamily())); + hasher.add(font.fontDescription().specifiedSize()); + return hasher.hash(); } -uint32_t RenderStyle::hashForTextAutosizing() const +unsigned RenderStyle::hashForTextAutosizing() const { // FIXME: Not a very smart hash. Could be improved upon. See <https://bugs.webkit.org/show_bug.cgi?id=121131>. - uint32_t hash = 0; - - hash ^= rareNonInheritedData->m_appearance; - hash ^= rareNonInheritedData->marginBeforeCollapse; - hash ^= rareNonInheritedData->marginAfterCollapse; - hash ^= rareNonInheritedData->lineClamp.value(); - hash ^= rareInheritedData->overflowWrap; - hash ^= rareInheritedData->nbspMode; - hash ^= rareInheritedData->lineBreak; - hash ^= WTF::FloatHash<float>::hash(inherited->specifiedLineHeight.value()); - hash ^= computeFontHash(inherited->font); - hash ^= inherited->horizontal_border_spacing; - hash ^= inherited->vertical_border_spacing; - hash ^= inherited_flags._box_direction; - hash ^= inherited_flags.m_rtlOrdering; - hash ^= noninherited_flags._position; - hash ^= noninherited_flags._floating; - hash ^= rareNonInheritedData->textOverflow; - hash ^= rareInheritedData->textSecurity; + unsigned hash = m_rareNonInheritedData->appearance; + hash ^= m_rareNonInheritedData->marginBeforeCollapse; + hash ^= m_rareNonInheritedData->marginAfterCollapse; + hash ^= m_rareNonInheritedData->lineClamp.value(); + hash ^= m_rareInheritedData->overflowWrap; + hash ^= m_rareInheritedData->nbspMode; + hash ^= m_rareInheritedData->lineBreak; + hash ^= WTF::FloatHash<float>::hash(m_inheritedData->specifiedLineHeight.value()); + hash ^= computeFontHash(m_inheritedData->fontCascade); + hash ^= WTF::FloatHash<float>::hash(m_inheritedData->horizontalBorderSpacing); + hash ^= WTF::FloatHash<float>::hash(m_inheritedData->verticalBorderSpacing); + hash ^= m_inheritedFlags.boxDirection; + hash ^= m_inheritedFlags.rtlOrdering; + hash ^= m_nonInheritedFlags.position(); + hash ^= m_nonInheritedFlags.floating(); + hash ^= m_rareNonInheritedData->textOverflow; + hash ^= m_rareInheritedData->textSecurity; return hash; } -bool RenderStyle::equalForTextAutosizing(const RenderStyle* other) const -{ - return rareNonInheritedData->m_appearance == other->rareNonInheritedData->m_appearance - && rareNonInheritedData->marginBeforeCollapse == other->rareNonInheritedData->marginBeforeCollapse - && rareNonInheritedData->marginAfterCollapse == other->rareNonInheritedData->marginAfterCollapse - && rareNonInheritedData->lineClamp == other->rareNonInheritedData->lineClamp - && rareInheritedData->textSizeAdjust == other->rareInheritedData->textSizeAdjust - && rareInheritedData->overflowWrap == other->rareInheritedData->overflowWrap - && rareInheritedData->nbspMode == other->rareInheritedData->nbspMode - && rareInheritedData->lineBreak == other->rareInheritedData->lineBreak - && rareInheritedData->textSecurity == other->rareInheritedData->textSecurity - && inherited->specifiedLineHeight == other->inherited->specifiedLineHeight - && inherited->font.equalForTextAutoSizing(other->inherited->font) - && inherited->horizontal_border_spacing == other->inherited->horizontal_border_spacing - && inherited->vertical_border_spacing == other->inherited->vertical_border_spacing - && inherited_flags._box_direction == other->inherited_flags._box_direction - && inherited_flags.m_rtlOrdering == other->inherited_flags.m_rtlOrdering - && noninherited_flags._position == other->noninherited_flags._position - && noninherited_flags._floating == other->noninherited_flags._floating - && rareNonInheritedData->textOverflow == other->rareNonInheritedData->textOverflow; -} -#endif // ENABLE(IOS_TEXT_AUTOSIZING) +bool RenderStyle::equalForTextAutosizing(const RenderStyle& other) const +{ + return m_rareNonInheritedData->appearance == other.m_rareNonInheritedData->appearance + && m_rareNonInheritedData->marginBeforeCollapse == other.m_rareNonInheritedData->marginBeforeCollapse + && m_rareNonInheritedData->marginAfterCollapse == other.m_rareNonInheritedData->marginAfterCollapse + && m_rareNonInheritedData->lineClamp == other.m_rareNonInheritedData->lineClamp + && m_rareInheritedData->textSizeAdjust == other.m_rareInheritedData->textSizeAdjust + && m_rareInheritedData->overflowWrap == other.m_rareInheritedData->overflowWrap + && m_rareInheritedData->nbspMode == other.m_rareInheritedData->nbspMode + && m_rareInheritedData->lineBreak == other.m_rareInheritedData->lineBreak + && m_rareInheritedData->textSecurity == other.m_rareInheritedData->textSecurity + && m_inheritedData->specifiedLineHeight == other.m_inheritedData->specifiedLineHeight + && m_inheritedData->fontCascade.equalForTextAutoSizing(other.m_inheritedData->fontCascade) + && m_inheritedData->horizontalBorderSpacing == other.m_inheritedData->horizontalBorderSpacing + && m_inheritedData->verticalBorderSpacing == other.m_inheritedData->verticalBorderSpacing + && m_inheritedFlags.boxDirection == other.m_inheritedFlags.boxDirection + && m_inheritedFlags.rtlOrdering == other.m_inheritedFlags.rtlOrdering + && m_nonInheritedFlags.position() == other.m_nonInheritedFlags.position() + && m_nonInheritedFlags.floating() == other.m_nonInheritedFlags.floating() + && m_rareNonInheritedData->textOverflow == other.m_rareNonInheritedData->textOverflow; +} + +#endif // ENABLE(TEXT_AUTOSIZING) bool RenderStyle::inheritedDataShared(const RenderStyle* other) const { // This is a fast check that only looks if the data structures are shared. - return inherited_flags == other->inherited_flags - && inherited.get() == other->inherited.get() -#if ENABLE(SVG) + return m_inheritedFlags == other->m_inheritedFlags + && m_inheritedData.get() == other->m_inheritedData.get() && m_svgStyle.get() == other->m_svgStyle.get() -#endif - && rareInheritedData.get() == other->rareInheritedData.get(); + && m_rareInheritedData.get() == other->m_rareInheritedData.get(); } static bool positionChangeIsMovementOnly(const LengthBox& a, const LengthBox& b, const Length& width) @@ -404,250 +482,254 @@ static bool positionChangeIsMovementOnly(const LengthBox& a, const LengthBox& b, return true; } -bool RenderStyle::changeRequiresLayout(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const +inline bool RenderStyle::changeAffectsVisualOverflow(const RenderStyle& other) const { - if (m_box->width() != other->m_box->width() - || m_box->minWidth() != other->m_box->minWidth() - || m_box->maxWidth() != other->m_box->maxWidth() - || m_box->height() != other->m_box->height() - || m_box->minHeight() != other->m_box->minHeight() - || m_box->maxHeight() != other->m_box->maxHeight()) + if (m_rareNonInheritedData.get() != other.m_rareNonInheritedData.get() + && !arePointingToEqualData(m_rareNonInheritedData->boxShadow, other.m_rareNonInheritedData->boxShadow)) return true; - if (m_box->verticalAlign() != other->m_box->verticalAlign() || noninherited_flags._vertical_align != other->noninherited_flags._vertical_align) + if (m_rareInheritedData.get() != other.m_rareInheritedData.get() + && !arePointingToEqualData(m_rareInheritedData->textShadow, other.m_rareInheritedData->textShadow)) return true; - if (m_box->boxSizing() != other->m_box->boxSizing()) + if (m_inheritedFlags.textDecorations != other.m_inheritedFlags.textDecorations + || m_visualData->textDecoration != other.m_visualData->textDecoration + || m_rareNonInheritedData->textDecorationStyle != other.m_rareNonInheritedData->textDecorationStyle) { + // Underlines are always drawn outside of their textbox bounds when text-underline-position: under; + // is specified. We can take an early out here. + if (textUnderlinePosition() == TextUnderlinePositionUnder + || other.textUnderlinePosition() == TextUnderlinePositionUnder) + return true; + return visualOverflowForDecorations(*this, nullptr) != visualOverflowForDecorations(other, nullptr); + } + + if (hasOutlineInVisualOverflow() != other.hasOutlineInVisualOverflow()) return true; + return false; +} - if (surround->margin != other->surround->margin) +bool RenderStyle::changeRequiresLayout(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const +{ + if (m_boxData->width() != other.m_boxData->width() + || m_boxData->minWidth() != other.m_boxData->minWidth() + || m_boxData->maxWidth() != other.m_boxData->maxWidth() + || m_boxData->height() != other.m_boxData->height() + || m_boxData->minHeight() != other.m_boxData->minHeight() + || m_boxData->maxHeight() != other.m_boxData->maxHeight()) return true; - if (surround->padding != other->surround->padding) + if (m_boxData->verticalAlign() != other.m_boxData->verticalAlign() || m_nonInheritedFlags.verticalAlign() != other.m_nonInheritedFlags.verticalAlign()) return true; - if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) { - if (rareNonInheritedData->m_appearance != other->rareNonInheritedData->m_appearance - || rareNonInheritedData->marginBeforeCollapse != other->rareNonInheritedData->marginBeforeCollapse - || rareNonInheritedData->marginAfterCollapse != other->rareNonInheritedData->marginAfterCollapse - || rareNonInheritedData->lineClamp != other->rareNonInheritedData->lineClamp - || rareNonInheritedData->textOverflow != other->rareNonInheritedData->textOverflow) - return true; + if (m_boxData->boxSizing() != other.m_boxData->boxSizing()) + return true; - if (rareNonInheritedData->m_regionFragment != other->rareNonInheritedData->m_regionFragment) - return true; + if (m_surroundData->margin != other.m_surroundData->margin) + return true; - if (rareNonInheritedData->m_wrapFlow != other->rareNonInheritedData->m_wrapFlow - || rareNonInheritedData->m_wrapThrough != other->rareNonInheritedData->m_wrapThrough) - return true; + if (m_surroundData->padding != other.m_surroundData->padding) + return true; -#if ENABLE(CSS_SHAPES) - if (rareNonInheritedData->m_shapeMargin != other->rareNonInheritedData->m_shapeMargin - || rareNonInheritedData->m_shapePadding != other->rareNonInheritedData->m_shapePadding) - return true; -#endif + // FIXME: We should add an optimized form of layout that just recomputes visual overflow. + if (changeAffectsVisualOverflow(other)) + return true; - if (rareNonInheritedData->m_deprecatedFlexibleBox.get() != other->rareNonInheritedData->m_deprecatedFlexibleBox.get() - && *rareNonInheritedData->m_deprecatedFlexibleBox.get() != *other->rareNonInheritedData->m_deprecatedFlexibleBox.get()) + if (m_rareNonInheritedData.get() != other.m_rareNonInheritedData.get()) { + if (m_rareNonInheritedData->appearance != other.m_rareNonInheritedData->appearance + || m_rareNonInheritedData->marginBeforeCollapse != other.m_rareNonInheritedData->marginBeforeCollapse + || m_rareNonInheritedData->marginAfterCollapse != other.m_rareNonInheritedData->marginAfterCollapse + || m_rareNonInheritedData->lineClamp != other.m_rareNonInheritedData->lineClamp + || m_rareNonInheritedData->initialLetter != other.m_rareNonInheritedData->initialLetter + || m_rareNonInheritedData->textOverflow != other.m_rareNonInheritedData->textOverflow) return true; - if (rareNonInheritedData->m_flexibleBox.get() != other->rareNonInheritedData->m_flexibleBox.get() - && *rareNonInheritedData->m_flexibleBox.get() != *other->rareNonInheritedData->m_flexibleBox.get()) + if (m_rareNonInheritedData->regionFragment != other.m_rareNonInheritedData->regionFragment) return true; - if (rareNonInheritedData->m_order != other->rareNonInheritedData->m_order - || rareNonInheritedData->m_alignContent != other->rareNonInheritedData->m_alignContent - || rareNonInheritedData->m_alignItems != other->rareNonInheritedData->m_alignItems - || rareNonInheritedData->m_alignSelf != other->rareNonInheritedData->m_alignSelf - || rareNonInheritedData->m_justifyContent != other->rareNonInheritedData->m_justifyContent) + + if (m_rareNonInheritedData->shapeMargin != other.m_rareNonInheritedData->shapeMargin) return true; - // FIXME: We should add an optimized form of layout that just recomputes visual overflow. - if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get())) + if (m_rareNonInheritedData->deprecatedFlexibleBox != other.m_rareNonInheritedData->deprecatedFlexibleBox) return true; - if (!rareNonInheritedData->reflectionDataEquivalent(*other->rareNonInheritedData.get())) + if (m_rareNonInheritedData->flexibleBox != other.m_rareNonInheritedData->flexibleBox) return true; - if (rareNonInheritedData->m_multiCol.get() != other->rareNonInheritedData->m_multiCol.get() - && *rareNonInheritedData->m_multiCol.get() != *other->rareNonInheritedData->m_multiCol.get()) + if (m_rareNonInheritedData->order != other.m_rareNonInheritedData->order + || m_rareNonInheritedData->alignContent != other.m_rareNonInheritedData->alignContent + || m_rareNonInheritedData->alignItems != other.m_rareNonInheritedData->alignItems + || m_rareNonInheritedData->alignSelf != other.m_rareNonInheritedData->alignSelf + || m_rareNonInheritedData->justifyContent != other.m_rareNonInheritedData->justifyContent + || m_rareNonInheritedData->justifyItems != other.m_rareNonInheritedData->justifyItems + || m_rareNonInheritedData->justifySelf != other.m_rareNonInheritedData->justifySelf) return true; - if (rareNonInheritedData->m_transform.get() != other->rareNonInheritedData->m_transform.get() - && *rareNonInheritedData->m_transform.get() != *other->rareNonInheritedData->m_transform.get()) { -#if USE(ACCELERATED_COMPOSITING) - changedContextSensitiveProperties |= ContextSensitivePropertyTransform; - // Don't return; keep looking for another change -#else - UNUSED_PARAM(changedContextSensitiveProperties); + if (!arePointingToEqualData(m_rareNonInheritedData->boxReflect, other.m_rareNonInheritedData->boxReflect)) return true; -#endif - } - if (rareNonInheritedData->m_grid.get() != other->rareNonInheritedData->m_grid.get() - || rareNonInheritedData->m_gridItem.get() != other->rareNonInheritedData->m_gridItem.get()) + if (m_rareNonInheritedData->multiCol != other.m_rareNonInheritedData->multiCol) return true; -#if !USE(ACCELERATED_COMPOSITING) - if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) { - if (rareNonInheritedData->m_transformStyle3D != other->rareNonInheritedData->m_transformStyle3D - || rareNonInheritedData->m_backfaceVisibility != other->rareNonInheritedData->m_backfaceVisibility - || rareNonInheritedData->m_perspective != other->rareNonInheritedData->m_perspective - || rareNonInheritedData->m_perspectiveOriginX != other->rareNonInheritedData->m_perspectiveOriginX - || rareNonInheritedData->m_perspectiveOriginY != other->rareNonInheritedData->m_perspectiveOriginY) + if (m_rareNonInheritedData->transform != other.m_rareNonInheritedData->transform) { + if (m_rareNonInheritedData->transform->hasTransform() != other.m_rareNonInheritedData->transform->hasTransform()) return true; + if (*m_rareNonInheritedData->transform != *other.m_rareNonInheritedData->transform) { + changedContextSensitiveProperties |= ContextSensitivePropertyTransform; + // Don't return; keep looking for another change + } } -#endif + + if (m_rareNonInheritedData->grid != other.m_rareNonInheritedData->grid + || m_rareNonInheritedData->gridItem != other.m_rareNonInheritedData->gridItem) + return true; #if ENABLE(DASHBOARD_SUPPORT) // If regions change, trigger a relayout to re-calc regions. - if (rareNonInheritedData->m_dashboardRegions != other->rareNonInheritedData->m_dashboardRegions) + if (m_rareNonInheritedData->dashboardRegions != other.m_rareNonInheritedData->dashboardRegions) return true; #endif -#if ENABLE(CSS_SHAPES) - if (rareNonInheritedData->m_shapeInside != other->rareNonInheritedData->m_shapeInside) - return true; -#endif + if (!arePointingToEqualData(m_rareNonInheritedData->willChange, other.m_rareNonInheritedData->willChange)) { + changedContextSensitiveProperties |= ContextSensitivePropertyWillChange; + // Don't return; keep looking for another change + } } - if (rareInheritedData.get() != other->rareInheritedData.get()) { - if (rareInheritedData->highlight != other->rareInheritedData->highlight - || rareInheritedData->indent != other->rareInheritedData->indent + if (m_rareInheritedData.get() != other.m_rareInheritedData.get()) { + if (m_rareInheritedData->indent != other.m_rareInheritedData->indent #if ENABLE(CSS3_TEXT) - || rareInheritedData->m_textAlignLast != other->rareInheritedData->m_textAlignLast - || rareInheritedData->m_textIndentLine != other->rareInheritedData->m_textIndentLine + || m_rareInheritedData->textAlignLast != other.m_rareInheritedData->textAlignLast + || m_rareInheritedData->textJustify != other.m_rareInheritedData->textJustify + || m_rareInheritedData->textIndentLine != other.m_rareInheritedData->textIndentLine #endif - || rareInheritedData->m_effectiveZoom != other->rareInheritedData->m_effectiveZoom -#if ENABLE(IOS_TEXT_AUTOSIZING) - || rareInheritedData->textSizeAdjust != other->rareInheritedData->textSizeAdjust + || m_rareInheritedData->effectiveZoom != other.m_rareInheritedData->effectiveZoom + || m_rareInheritedData->textZoom != other.m_rareInheritedData->textZoom +#if ENABLE(TEXT_AUTOSIZING) + || m_rareInheritedData->textSizeAdjust != other.m_rareInheritedData->textSizeAdjust #endif - || rareInheritedData->wordBreak != other->rareInheritedData->wordBreak - || rareInheritedData->overflowWrap != other->rareInheritedData->overflowWrap - || rareInheritedData->nbspMode != other->rareInheritedData->nbspMode - || rareInheritedData->lineBreak != other->rareInheritedData->lineBreak - || rareInheritedData->textSecurity != other->rareInheritedData->textSecurity - || rareInheritedData->hyphens != other->rareInheritedData->hyphens - || rareInheritedData->hyphenationLimitBefore != other->rareInheritedData->hyphenationLimitBefore - || rareInheritedData->hyphenationLimitAfter != other->rareInheritedData->hyphenationLimitAfter - || rareInheritedData->hyphenationString != other->rareInheritedData->hyphenationString - || rareInheritedData->locale != other->rareInheritedData->locale - || rareInheritedData->m_rubyPosition != other->rareInheritedData->m_rubyPosition - || rareInheritedData->textEmphasisMark != other->rareInheritedData->textEmphasisMark - || rareInheritedData->textEmphasisPosition != other->rareInheritedData->textEmphasisPosition - || rareInheritedData->textEmphasisCustomMark != other->rareInheritedData->textEmphasisCustomMark - || rareInheritedData->m_textOrientation != other->rareInheritedData->m_textOrientation - || rareInheritedData->m_tabSize != other->rareInheritedData->m_tabSize - || rareInheritedData->m_lineBoxContain != other->rareInheritedData->m_lineBoxContain - || rareInheritedData->m_lineGrid != other->rareInheritedData->m_lineGrid + || m_rareInheritedData->wordBreak != other.m_rareInheritedData->wordBreak + || m_rareInheritedData->overflowWrap != other.m_rareInheritedData->overflowWrap + || m_rareInheritedData->nbspMode != other.m_rareInheritedData->nbspMode + || m_rareInheritedData->lineBreak != other.m_rareInheritedData->lineBreak + || m_rareInheritedData->textSecurity != other.m_rareInheritedData->textSecurity + || m_rareInheritedData->hyphens != other.m_rareInheritedData->hyphens + || m_rareInheritedData->hyphenationLimitBefore != other.m_rareInheritedData->hyphenationLimitBefore + || m_rareInheritedData->hyphenationLimitAfter != other.m_rareInheritedData->hyphenationLimitAfter + || m_rareInheritedData->hyphenationString != other.m_rareInheritedData->hyphenationString + || m_rareInheritedData->rubyPosition != other.m_rareInheritedData->rubyPosition + || m_rareInheritedData->textEmphasisMark != other.m_rareInheritedData->textEmphasisMark + || m_rareInheritedData->textEmphasisPosition != other.m_rareInheritedData->textEmphasisPosition + || m_rareInheritedData->textEmphasisCustomMark != other.m_rareInheritedData->textEmphasisCustomMark + || m_rareInheritedData->textOrientation != other.m_rareInheritedData->textOrientation + || m_rareInheritedData->tabSize != other.m_rareInheritedData->tabSize + || m_rareInheritedData->lineBoxContain != other.m_rareInheritedData->lineBoxContain + || m_rareInheritedData->lineGrid != other.m_rareInheritedData->lineGrid #if ENABLE(CSS_IMAGE_ORIENTATION) - || rareInheritedData->m_imageOrientation != other->rareInheritedData->m_imageOrientation + || m_rareInheritedData->imageOrientation != other.m_rareInheritedData->imageOrientation #endif #if ENABLE(CSS_IMAGE_RESOLUTION) - || rareInheritedData->m_imageResolutionSource != other->rareInheritedData->m_imageResolutionSource - || rareInheritedData->m_imageResolutionSnap != other->rareInheritedData->m_imageResolutionSnap - || rareInheritedData->m_imageResolution != other->rareInheritedData->m_imageResolution + || m_rareInheritedData->imageResolutionSource != other.m_rareInheritedData->imageResolutionSource + || m_rareInheritedData->imageResolutionSnap != other.m_rareInheritedData->imageResolutionSnap + || m_rareInheritedData->imageResolution != other.m_rareInheritedData->imageResolution #endif - || rareInheritedData->m_lineSnap != other->rareInheritedData->m_lineSnap - || rareInheritedData->m_lineAlign != other->rareInheritedData->m_lineAlign + || m_rareInheritedData->lineSnap != other.m_rareInheritedData->lineSnap + || m_rareInheritedData->lineAlign != other.m_rareInheritedData->lineAlign + || m_rareInheritedData->hangingPunctuation != other.m_rareInheritedData->hangingPunctuation #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) - || rareInheritedData->useTouchOverflowScrolling != other->rareInheritedData->useTouchOverflowScrolling + || m_rareInheritedData->useTouchOverflowScrolling != other.m_rareInheritedData->useTouchOverflowScrolling #endif - || rareInheritedData->listStyleImage != other->rareInheritedData->listStyleImage) - return true; - - if (!rareInheritedData->shadowDataEquivalent(*other->rareInheritedData.get())) + || m_rareInheritedData->listStyleImage != other.m_rareInheritedData->listStyleImage) // FIXME: needs arePointingToEqualData()? return true; - if (textStrokeWidth() != other->textStrokeWidth()) + if (textStrokeWidth() != other.textStrokeWidth()) return true; } + if (m_inheritedData->lineHeight != other.m_inheritedData->lineHeight #if ENABLE(TEXT_AUTOSIZING) - if (visual->m_textAutosizingMultiplier != other->visual->m_textAutosizingMultiplier) - return true; -#endif - - if (inherited->line_height != other->inherited->line_height -#if ENABLE(IOS_TEXT_AUTOSIZING) - || inherited->specifiedLineHeight != other->inherited->specifiedLineHeight + || m_inheritedData->specifiedLineHeight != other.m_inheritedData->specifiedLineHeight #endif - || inherited->font != other->inherited->font - || inherited->horizontal_border_spacing != other->inherited->horizontal_border_spacing - || inherited->vertical_border_spacing != other->inherited->vertical_border_spacing - || inherited_flags._box_direction != other->inherited_flags._box_direction - || inherited_flags.m_rtlOrdering != other->inherited_flags.m_rtlOrdering - || noninherited_flags._position != other->noninherited_flags._position - || noninherited_flags._floating != other->noninherited_flags._floating - || noninherited_flags._originalDisplay != other->noninherited_flags._originalDisplay) + || m_inheritedData->fontCascade != other.m_inheritedData->fontCascade + || m_inheritedData->horizontalBorderSpacing != other.m_inheritedData->horizontalBorderSpacing + || m_inheritedData->verticalBorderSpacing != other.m_inheritedData->verticalBorderSpacing + || m_inheritedFlags.boxDirection != other.m_inheritedFlags.boxDirection + || m_inheritedFlags.rtlOrdering != other.m_inheritedFlags.rtlOrdering + || m_nonInheritedFlags.position() != other.m_nonInheritedFlags.position() + || m_nonInheritedFlags.floating() != other.m_nonInheritedFlags.floating() + || m_nonInheritedFlags.originalDisplay() != other.m_nonInheritedFlags.originalDisplay()) return true; - if (((int)noninherited_flags._effectiveDisplay) >= TABLE) { - if (inherited_flags._border_collapse != other->inherited_flags._border_collapse - || inherited_flags._empty_cells != other->inherited_flags._empty_cells - || inherited_flags._caption_side != other->inherited_flags._caption_side - || noninherited_flags._table_layout != other->noninherited_flags._table_layout) + if ((m_nonInheritedFlags.effectiveDisplay()) >= TABLE) { + if (m_inheritedFlags.borderCollapse != other.m_inheritedFlags.borderCollapse + || m_inheritedFlags.emptyCells != other.m_inheritedFlags.emptyCells + || m_inheritedFlags.captionSide != other.m_inheritedFlags.captionSide + || m_nonInheritedFlags.tableLayout() != other.m_nonInheritedFlags.tableLayout()) return true; // In the collapsing border model, 'hidden' suppresses other borders, while 'none' // does not, so these style differences can be width differences. - if (inherited_flags._border_collapse - && ((borderTopStyle() == BHIDDEN && other->borderTopStyle() == BNONE) - || (borderTopStyle() == BNONE && other->borderTopStyle() == BHIDDEN) - || (borderBottomStyle() == BHIDDEN && other->borderBottomStyle() == BNONE) - || (borderBottomStyle() == BNONE && other->borderBottomStyle() == BHIDDEN) - || (borderLeftStyle() == BHIDDEN && other->borderLeftStyle() == BNONE) - || (borderLeftStyle() == BNONE && other->borderLeftStyle() == BHIDDEN) - || (borderRightStyle() == BHIDDEN && other->borderRightStyle() == BNONE) - || (borderRightStyle() == BNONE && other->borderRightStyle() == BHIDDEN))) + if (m_inheritedFlags.borderCollapse + && ((borderTopStyle() == BHIDDEN && other.borderTopStyle() == BNONE) + || (borderTopStyle() == BNONE && other.borderTopStyle() == BHIDDEN) + || (borderBottomStyle() == BHIDDEN && other.borderBottomStyle() == BNONE) + || (borderBottomStyle() == BNONE && other.borderBottomStyle() == BHIDDEN) + || (borderLeftStyle() == BHIDDEN && other.borderLeftStyle() == BNONE) + || (borderLeftStyle() == BNONE && other.borderLeftStyle() == BHIDDEN) + || (borderRightStyle() == BHIDDEN && other.borderRightStyle() == BNONE) + || (borderRightStyle() == BNONE && other.borderRightStyle() == BHIDDEN))) return true; } - if (noninherited_flags._effectiveDisplay == LIST_ITEM) { - if (inherited_flags._list_style_type != other->inherited_flags._list_style_type - || inherited_flags._list_style_position != other->inherited_flags._list_style_position) + if (m_nonInheritedFlags.effectiveDisplay() == LIST_ITEM) { + if (m_inheritedFlags.listStyleType != other.m_inheritedFlags.listStyleType + || m_inheritedFlags.listStylePosition != other.m_inheritedFlags.listStylePosition) return true; } - if (inherited_flags._text_align != other->inherited_flags._text_align - || inherited_flags._text_transform != other->inherited_flags._text_transform - || inherited_flags._direction != other->inherited_flags._direction - || inherited_flags._white_space != other->inherited_flags._white_space - || noninherited_flags._clear != other->noninherited_flags._clear - || noninherited_flags._unicodeBidi != other->noninherited_flags._unicodeBidi) + if (m_inheritedFlags.textAlign != other.m_inheritedFlags.textAlign + || m_inheritedFlags.textTransform != other.m_inheritedFlags.textTransform + || m_inheritedFlags.direction != other.m_inheritedFlags.direction + || m_inheritedFlags.whiteSpace != other.m_inheritedFlags.whiteSpace + || m_nonInheritedFlags.clear() != other.m_nonInheritedFlags.clear() + || m_nonInheritedFlags.unicodeBidi() != other.m_nonInheritedFlags.unicodeBidi()) return true; // Check block flow direction. - if (inherited_flags.m_writingMode != other->inherited_flags.m_writingMode) + if (m_inheritedFlags.writingMode != other.m_inheritedFlags.writingMode) return true; // Check text combine mode. - if (rareNonInheritedData->m_textCombine != other->rareNonInheritedData->m_textCombine) + if (m_rareNonInheritedData->textCombine != other.m_rareNonInheritedData->textCombine) + return true; + + // Check breaks. + if (m_rareNonInheritedData->breakBefore != other.m_rareNonInheritedData->breakBefore + || m_rareNonInheritedData->breakAfter != other.m_rareNonInheritedData->breakAfter + || m_rareNonInheritedData->breakInside != other.m_rareNonInheritedData->breakInside) return true; // Overflow returns a layout hint. - if (noninherited_flags._overflowX != other->noninherited_flags._overflowX - || noninherited_flags._overflowY != other->noninherited_flags._overflowY) + if (m_nonInheritedFlags.overflowX() != other.m_nonInheritedFlags.overflowX() + || m_nonInheritedFlags.overflowY() != other.m_nonInheritedFlags.overflowY()) return true; // If our border widths change, then we need to layout. Other changes to borders // only necessitate a repaint. - if (borderLeftWidth() != other->borderLeftWidth() - || borderTopWidth() != other->borderTopWidth() - || borderBottomWidth() != other->borderBottomWidth() - || borderRightWidth() != other->borderRightWidth()) + if (borderLeftWidth() != other.borderLeftWidth() + || borderTopWidth() != other.borderTopWidth() + || borderBottomWidth() != other.borderBottomWidth() + || borderRightWidth() != other.borderRightWidth()) return true; // If the counter directives change, trigger a relayout to re-calculate counter values and rebuild the counter node tree. - const CounterDirectiveMap* mapA = rareNonInheritedData->m_counterDirectives.get(); - const CounterDirectiveMap* mapB = other->rareNonInheritedData->m_counterDirectives.get(); - if (!(mapA == mapB || (mapA && mapB && *mapA == *mapB))) + if (!arePointingToEqualData(m_rareNonInheritedData->counterDirectives, other.m_rareNonInheritedData->counterDirectives)) return true; - if ((visibility() == COLLAPSE) != (other->visibility() == COLLAPSE)) + if ((visibility() == COLLAPSE) != (other.visibility() == COLLAPSE)) return true; - if (rareNonInheritedData->hasOpacity() != other->rareNonInheritedData->hasOpacity()) { + if (m_rareNonInheritedData->hasOpacity() != other.m_rareNonInheritedData->hasOpacity()) { // FIXME: We would like to use SimplifiedLayout here, but we can't quite do that yet. // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line). @@ -656,18 +738,19 @@ bool RenderStyle::changeRequiresLayout(const RenderStyle* other, unsigned& chang return true; } -#if ENABLE(CSS_FILTERS) - if (rareNonInheritedData->hasFilters() != other->rareNonInheritedData->hasFilters()) + if (m_rareNonInheritedData->hasFilters() != other.m_rareNonInheritedData->hasFilters()) + return true; + +#if ENABLE(FILTERS_LEVEL_2) + if (m_rareNonInheritedData->hasBackdropFilters() != other.m_rareNonInheritedData->hasBackdropFilters()) return true; #endif - const QuotesData* quotesDataA = rareInheritedData->quotes.get(); - const QuotesData* quotesDataB = other->rareInheritedData->quotes.get(); - if (!(quotesDataA == quotesDataB || (quotesDataA && quotesDataB && *quotesDataA == *quotesDataB))) + if (!arePointingToEqualData(m_rareInheritedData->quotes, other.m_rareInheritedData->quotes)) return true; if (position() != StaticPosition) { - if (surround->offset != other->surround->offset) { + if (m_surroundData->offset != other.m_surroundData->offset) { // FIXME: We would like to use SimplifiedLayout for relative positioning, but we can't quite do that yet. // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line). @@ -675,161 +758,183 @@ bool RenderStyle::changeRequiresLayout(const RenderStyle* other, unsigned& chang return true; // Optimize for the case where a positioned layer is moving but not changing size. - if (!positionChangeIsMovementOnly(surround->offset, other->surround->offset, m_box->width())) + if (!positionChangeIsMovementOnly(m_surroundData->offset, other.m_surroundData->offset, m_boxData->width())) return true; } } - + + bool hasFirstLineStyle = hasPseudoStyle(FIRST_LINE); + if (hasFirstLineStyle != other.hasPseudoStyle(FIRST_LINE)) + return true; + if (hasFirstLineStyle) { + auto* firstLineStyle = getCachedPseudoStyle(FIRST_LINE); + if (!firstLineStyle) + return true; + auto* otherFirstLineStyle = other.getCachedPseudoStyle(FIRST_LINE); + if (!otherFirstLineStyle) + return true; + // FIXME: Not all first line style changes actually need layout. + if (*firstLineStyle != *otherFirstLineStyle) + return true; + } + return false; } -bool RenderStyle::changeRequiresPositionedLayoutOnly(const RenderStyle* other, unsigned&) const +bool RenderStyle::changeRequiresPositionedLayoutOnly(const RenderStyle& other, unsigned&) const { if (position() == StaticPosition) return false; - if (surround->offset != other->surround->offset) { + if (m_surroundData->offset != other.m_surroundData->offset) { // Optimize for the case where a positioned layer is moving but not changing size. - if (position() == AbsolutePosition && positionChangeIsMovementOnly(surround->offset, other->surround->offset, m_box->width())) + if (position() == AbsolutePosition && positionChangeIsMovementOnly(m_surroundData->offset, other.m_surroundData->offset, m_boxData->width())) return true; } return false; } -bool RenderStyle::changeRequiresLayerRepaint(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const +bool RenderStyle::changeRequiresLayerRepaint(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const { + // StyleResolver has ensured that zIndex is non-auto only if it's applicable. + if (m_boxData->zIndex() != other.m_boxData->zIndex() || m_boxData->hasAutoZIndex() != other.m_boxData->hasAutoZIndex()) + return true; + if (position() != StaticPosition) { - if (m_box->zIndex() != other->m_box->zIndex() - || m_box->hasAutoZIndex() != other->m_box->hasAutoZIndex() - || visual->clip != other->visual->clip - || visual->hasClip != other->visual->hasClip) + if (m_visualData->clip != other.m_visualData->clip || m_visualData->hasClip != other.m_visualData->hasClip) { + changedContextSensitiveProperties |= ContextSensitivePropertyClipRect; return true; + } } #if ENABLE(CSS_COMPOSITING) - if (rareNonInheritedData->m_effectiveBlendMode != other->rareNonInheritedData->m_effectiveBlendMode) + if (m_rareNonInheritedData->effectiveBlendMode != other.m_rareNonInheritedData->effectiveBlendMode) return true; #endif - if (rareNonInheritedData->opacity != other->rareNonInheritedData->opacity) { -#if USE(ACCELERATED_COMPOSITING) + if (m_rareNonInheritedData->opacity != other.m_rareNonInheritedData->opacity) { changedContextSensitiveProperties |= ContextSensitivePropertyOpacity; // Don't return; keep looking for another change. -#else - UNUSED_PARAM(changedContextSensitiveProperties); - return true; -#endif } -#if ENABLE(CSS_FILTERS) - if (rareNonInheritedData->m_filter.get() != other->rareNonInheritedData->m_filter.get() - && *rareNonInheritedData->m_filter.get() != *other->rareNonInheritedData->m_filter.get()) { -#if USE(ACCELERATED_COMPOSITING) + if (m_rareNonInheritedData->filter != other.m_rareNonInheritedData->filter) { + changedContextSensitiveProperties |= ContextSensitivePropertyFilter; + // Don't return; keep looking for another change. + } + +#if ENABLE(FILTERS_LEVEL_2) + if (m_rareNonInheritedData->backdropFilter != other.m_rareNonInheritedData->backdropFilter) { changedContextSensitiveProperties |= ContextSensitivePropertyFilter; // Don't return; keep looking for another change. -#else - return true; -#endif } #endif - if (rareNonInheritedData->m_mask != other->rareNonInheritedData->m_mask - || rareNonInheritedData->m_maskBoxImage != other->rareNonInheritedData->m_maskBoxImage) + if (m_rareNonInheritedData->mask != other.m_rareNonInheritedData->mask + || m_rareNonInheritedData->maskBoxImage != other.m_rareNonInheritedData->maskBoxImage) return true; return false; } -bool RenderStyle::changeRequiresRepaint(const RenderStyle* other, unsigned&) const +static bool requiresPainting(const RenderStyle& style) { - if (inherited_flags._visibility != other->inherited_flags._visibility - || inherited_flags.m_printColorAdjust != other->inherited_flags.m_printColorAdjust - || inherited_flags._insideLink != other->inherited_flags._insideLink - || surround->border != other->surround->border - || !m_background->isEquivalentForPainting(*other->m_background) - || rareInheritedData->userModify != other->rareInheritedData->userModify - || rareInheritedData->userSelect != other->rareInheritedData->userSelect - || rareNonInheritedData->userDrag != other->rareNonInheritedData->userDrag - || rareNonInheritedData->m_borderFit != other->rareNonInheritedData->m_borderFit - || rareNonInheritedData->m_objectFit != other->rareNonInheritedData->m_objectFit - || rareInheritedData->m_imageRendering != other->rareInheritedData->m_imageRendering) - return true; + if (style.visibility() == HIDDEN) + return false; + if (!style.opacity()) + return false; + return true; +} + +bool RenderStyle::changeRequiresRepaint(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const +{ + if (!requiresPainting(*this) && !requiresPainting(other)) + return false; -#if ENABLE(CSS_SHAPES) - // FIXME: The current spec is being reworked to remove dependencies between exclusions and affected - // content. There's a proposal to use floats instead. In that case, wrap-shape should actually relayout - // the parent container. For sure, I will have to revisit this code, but for now I've added this in order - // to avoid having diff() == StyleDifferenceEqual where wrap-shapes actually differ. - // Tracking bug: https://bugs.webkit.org/show_bug.cgi?id=62991 - if (rareNonInheritedData->m_shapeOutside != other->rareNonInheritedData->m_shapeOutside) + if (m_inheritedFlags.visibility != other.m_inheritedFlags.visibility + || m_inheritedFlags.printColorAdjust != other.m_inheritedFlags.printColorAdjust + || m_inheritedFlags.insideLink != other.m_inheritedFlags.insideLink + || m_inheritedFlags.insideDefaultButton != other.m_inheritedFlags.insideDefaultButton + || m_surroundData->border != other.m_surroundData->border + || !m_backgroundData->isEquivalentForPainting(*other.m_backgroundData) + || m_rareInheritedData->userModify != other.m_rareInheritedData->userModify + || m_rareInheritedData->userSelect != other.m_rareInheritedData->userSelect + || m_rareNonInheritedData->userDrag != other.m_rareNonInheritedData->userDrag + || m_rareNonInheritedData->borderFit != other.m_rareNonInheritedData->borderFit + || m_rareNonInheritedData->objectFit != other.m_rareNonInheritedData->objectFit + || m_rareNonInheritedData->objectPosition != other.m_rareNonInheritedData->objectPosition + || m_rareInheritedData->imageRendering != other.m_rareInheritedData->imageRendering) return true; -#endif - if (rareNonInheritedData->m_clipPath != other->rareNonInheritedData->m_clipPath) + if (m_rareNonInheritedData->shapeOutside != other.m_rareNonInheritedData->shapeOutside) return true; + // FIXME: this should probably be moved to changeRequiresLayerRepaint(). + if (m_rareNonInheritedData->clipPath != other.m_rareNonInheritedData->clipPath) { + changedContextSensitiveProperties |= ContextSensitivePropertyClipPath; + // Don't return; keep looking for another change. + } + return false; } -bool RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline(const RenderStyle* other, unsigned&) const +bool RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline(const RenderStyle& other, unsigned&) const { - if (inherited->color != other->inherited->color - || inherited_flags._text_decorations != other->inherited_flags._text_decorations - || visual->textDecoration != other->visual->textDecoration - || rareNonInheritedData->m_textDecorationStyle != other->rareNonInheritedData->m_textDecorationStyle - || rareNonInheritedData->m_textDecorationColor != other->rareNonInheritedData->m_textDecorationColor - || rareInheritedData->m_textDecorationSkip != other->rareInheritedData->m_textDecorationSkip - || rareInheritedData->textFillColor != other->rareInheritedData->textFillColor - || rareInheritedData->textStrokeColor != other->rareInheritedData->textStrokeColor - || rareInheritedData->textEmphasisColor != other->rareInheritedData->textEmphasisColor - || rareInheritedData->textEmphasisFill != other->rareInheritedData->textEmphasisFill) + if (m_inheritedData->color != other.m_inheritedData->color + || m_inheritedFlags.textDecorations != other.m_inheritedFlags.textDecorations + || m_visualData->textDecoration != other.m_visualData->textDecoration + || m_rareNonInheritedData->textDecorationStyle != other.m_rareNonInheritedData->textDecorationStyle + || m_rareNonInheritedData->textDecorationColor != other.m_rareNonInheritedData->textDecorationColor + || m_rareInheritedData->textDecorationSkip != other.m_rareInheritedData->textDecorationSkip + || m_rareInheritedData->textFillColor != other.m_rareInheritedData->textFillColor + || m_rareInheritedData->textStrokeColor != other.m_rareInheritedData->textStrokeColor + || m_rareInheritedData->textEmphasisColor != other.m_rareInheritedData->textEmphasisColor + || m_rareInheritedData->textEmphasisFill != other.m_rareInheritedData->textEmphasisFill) return true; return false; } -bool RenderStyle::changeRequiresRecompositeLayer(const RenderStyle* other, unsigned&) const +bool RenderStyle::changeRequiresRecompositeLayer(const RenderStyle& other, unsigned&) const { -#if USE(ACCELERATED_COMPOSITING) - if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) { - if (rareNonInheritedData->m_transformStyle3D != other->rareNonInheritedData->m_transformStyle3D - || rareNonInheritedData->m_backfaceVisibility != other->rareNonInheritedData->m_backfaceVisibility - || rareNonInheritedData->m_perspective != other->rareNonInheritedData->m_perspective - || rareNonInheritedData->m_perspectiveOriginX != other->rareNonInheritedData->m_perspectiveOriginX - || rareNonInheritedData->m_perspectiveOriginY != other->rareNonInheritedData->m_perspectiveOriginY) + if (m_rareNonInheritedData.get() != other.m_rareNonInheritedData.get()) { + if (m_rareNonInheritedData->transformStyle3D != other.m_rareNonInheritedData->transformStyle3D + || m_rareNonInheritedData->backfaceVisibility != other.m_rareNonInheritedData->backfaceVisibility + || m_rareNonInheritedData->perspective != other.m_rareNonInheritedData->perspective + || m_rareNonInheritedData->perspectiveOriginX != other.m_rareNonInheritedData->perspectiveOriginX + || m_rareNonInheritedData->perspectiveOriginY != other.m_rareNonInheritedData->perspectiveOriginY) return true; } -#else - UNUSED_PARAM(other); -#endif + return false; } -StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const +StyleDifference RenderStyle::diff(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const { changedContextSensitiveProperties = ContextSensitivePropertyNone; -#if ENABLE(SVG) StyleDifference svgChange = StyleDifferenceEqual; - if (m_svgStyle != other->m_svgStyle) { - svgChange = m_svgStyle->diff(other->m_svgStyle.get()); + if (m_svgStyle != other.m_svgStyle) { + svgChange = m_svgStyle->diff(other.m_svgStyle.get()); if (svgChange == StyleDifferenceLayout) return svgChange; } -#endif + + // These properties affect the cached stroke bounding box rects. + if (m_rareInheritedData->capStyle != other.m_rareInheritedData->capStyle + || m_rareInheritedData->joinStyle != other.m_rareInheritedData->joinStyle + || m_rareInheritedData->strokeWidth != other.m_rareInheritedData->strokeWidth) + return StyleDifferenceLayout; if (changeRequiresLayout(other, changedContextSensitiveProperties)) return StyleDifferenceLayout; -#if ENABLE(SVG) // SVGRenderStyle::diff() might have returned StyleDifferenceRepaint, eg. if fill changes. // If eg. the font-size changed at the same time, we're not allowed to return StyleDifferenceRepaint, // but have to return StyleDifferenceLayout, that's why this if branch comes after all branches // that are relevant for SVG and might return StyleDifferenceLayout. if (svgChange != StyleDifferenceEqual) return svgChange; -#endif if (changeRequiresPositionedLayoutOnly(other, changedContextSensitiveProperties)) return StyleDifferenceLayoutPositionedMovementOnly; @@ -840,10 +945,8 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon if (changeRequiresRepaint(other, changedContextSensitiveProperties)) return StyleDifferenceRepaint; -#if USE(ACCELERATED_COMPOSITING) if (changeRequiresRecompositeLayer(other, changedContextSensitiveProperties)) return StyleDifferenceRecompositeLayer; -#endif if (changeRequiresRepaintIfTextOrBorderOrOutline(other, changedContextSensitiveProperties)) return StyleDifferenceRepaintIfTextOrBorderOrOutline; @@ -856,203 +959,186 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon return StyleDifferenceEqual; } -bool RenderStyle::diffRequiresRepaint(const RenderStyle* style) const +bool RenderStyle::diffRequiresLayerRepaint(const RenderStyle& style, bool isComposited) const { unsigned changedContextSensitiveProperties = 0; - return changeRequiresRepaint(style, changedContextSensitiveProperties); + + if (changeRequiresRepaint(style, changedContextSensitiveProperties)) + return true; + + if (isComposited && changeRequiresLayerRepaint(style, changedContextSensitiveProperties)) + return changedContextSensitiveProperties & ContextSensitivePropertyClipRect; + + return false; } -void RenderStyle::setClip(Length top, Length right, Length bottom, Length left) +void RenderStyle::setClip(Length&& top, Length&& right, Length&& bottom, Length&& left) { - StyleVisualData* data = visual.access(); - data->clip.m_top = top; - data->clip.m_right = right; - data->clip.m_bottom = bottom; - data->clip.m_left = left; + auto& data = m_visualData.access(); + data.clip.top() = WTFMove(top); + data.clip.right() = WTFMove(right); + data.clip.bottom() = WTFMove(bottom); + data.clip.left() = WTFMove(left); } -void RenderStyle::addCursor(PassRefPtr<StyleImage> image, const IntPoint& hotSpot) +void RenderStyle::addCursor(RefPtr<StyleImage>&& image, const IntPoint& hotSpot) { - if (!rareInheritedData.access()->cursorData) - rareInheritedData.access()->cursorData = CursorList::create(); - rareInheritedData.access()->cursorData->append(CursorData(image, hotSpot)); + auto& cursorData = m_rareInheritedData.access().cursorData; + if (!cursorData) + cursorData = CursorList::create(); + cursorData->append(CursorData(WTFMove(image), hotSpot)); } -void RenderStyle::setCursorList(PassRefPtr<CursorList> other) +void RenderStyle::setCursorList(RefPtr<CursorList>&& list) { - rareInheritedData.access()->cursorData = other; + m_rareInheritedData.access().cursorData = WTFMove(list); } -void RenderStyle::setQuotes(PassRefPtr<QuotesData> q) +void RenderStyle::setQuotes(RefPtr<QuotesData>&& q) { - if (rareInheritedData->quotes == q || (rareInheritedData->quotes && q && *rareInheritedData->quotes == *q)) + if (m_rareInheritedData->quotes == q || (m_rareInheritedData->quotes && q && *m_rareInheritedData->quotes == *q)) return; - rareInheritedData.access()->quotes = q; + m_rareInheritedData.access().quotes = WTFMove(q); +} + +void RenderStyle::setWillChange(RefPtr<WillChangeData>&& willChangeData) +{ + if (arePointingToEqualData(m_rareNonInheritedData->willChange.get(), willChangeData.get())) + return; + + m_rareNonInheritedData.access().willChange = WTFMove(willChangeData); } void RenderStyle::clearCursorList() { - if (rareInheritedData->cursorData) - rareInheritedData.access()->cursorData = 0; + if (m_rareInheritedData->cursorData) + m_rareInheritedData.access().cursorData = nullptr; } void RenderStyle::clearContent() { - if (rareNonInheritedData->m_content) - rareNonInheritedData.access()->m_content = nullptr; + if (m_rareNonInheritedData->content) + m_rareNonInheritedData.access().content = nullptr; } -void RenderStyle::appendContent(std::unique_ptr<ContentData> contentData) +static inline ContentData& lastContent(ContentData& firstContent) { - auto& content = rareNonInheritedData.access()->m_content; - ContentData* lastContent = content.get(); - while (lastContent && lastContent->next()) - lastContent = lastContent->next(); + auto* lastContent = &firstContent; + for (auto* content = &firstContent; content; content = content->next()) + lastContent = content; + return *lastContent; +} - if (lastContent) - lastContent->setNext(std::move(contentData)); - else - content = std::move(contentData); +void RenderStyle::setContent(std::unique_ptr<ContentData> contentData, bool add) +{ + auto& data = m_rareNonInheritedData.access(); + if (add && data.content) + lastContent(*data.content).setNext(WTFMove(contentData)); + else { + data.content = WTFMove(contentData); + auto& altText = data.altText; + if (!altText.isNull()) + data.content->setAltText(altText); + } } -void RenderStyle::setContent(PassRefPtr<StyleImage> image, bool add) +void RenderStyle::setContent(RefPtr<StyleImage>&& image, bool add) { if (!image) return; - - if (add) { - appendContent(std::make_unique<ImageContentData>(image)); - return; - } - - rareNonInheritedData.access()->m_content = std::make_unique<ImageContentData>(image); - if (!rareNonInheritedData.access()->m_altText.isNull()) - rareNonInheritedData.access()->m_content->setAltText(rareNonInheritedData.access()->m_altText); + setContent(std::make_unique<ImageContentData>(image.releaseNonNull()), add); } void RenderStyle::setContent(const String& string, bool add) { - auto& content = rareNonInheritedData.access()->m_content; - if (add) { - ContentData* lastContent = content.get(); - while (lastContent && lastContent->next()) - lastContent = lastContent->next(); - - if (lastContent) { - // We attempt to merge with the last ContentData if possible. - if (lastContent->isText()) { - TextContentData* textContent = static_cast<TextContentData*>(lastContent); - textContent->setText(textContent->text() + string); - } else - lastContent->setNext(std::make_unique<TextContentData>(string)); - - if (!rareNonInheritedData.access()->m_altText.isNull()) - lastContent->setAltText(rareNonInheritedData.access()->m_altText); - return; + auto& data = m_rareNonInheritedData.access(); + if (add && data.content) { + auto& last = lastContent(*data.content); + if (!is<TextContentData>(last)) + last.setNext(std::make_unique<TextContentData>(string)); + else { + auto& textContent = downcast<TextContentData>(last); + textContent.setText(textContent.text() + string); } + } else { + data.content = std::make_unique<TextContentData>(string); + auto& altText = data.altText; + if (!altText.isNull()) + data.content->setAltText(altText); } - - content = std::make_unique<TextContentData>(string); - if (!rareNonInheritedData.access()->m_altText.isNull()) - content->setAltText(rareNonInheritedData.access()->m_altText); } void RenderStyle::setContent(std::unique_ptr<CounterContent> counter, bool add) { if (!counter) return; - - if (add) { - appendContent(std::make_unique<CounterContentData>(std::move(counter))); - return; - } - - rareNonInheritedData.access()->m_content = std::make_unique<CounterContentData>(std::move(counter)); + setContent(std::make_unique<CounterContentData>(WTFMove(counter)), add); } void RenderStyle::setContent(QuoteType quote, bool add) { - if (add) { - appendContent(std::make_unique<QuoteContentData>(quote)); - return; - } - - rareNonInheritedData.access()->m_content = std::make_unique<QuoteContentData>(quote); + setContent(std::make_unique<QuoteContentData>(quote), add); } void RenderStyle::setContentAltText(const String& string) { - rareNonInheritedData.access()->m_altText = string; - - if (rareNonInheritedData.access()->m_content) - rareNonInheritedData.access()->m_content->setAltText(string); + auto& data = m_rareNonInheritedData.access(); + data.altText = string; + if (data.content) + data.content->setAltText(string); } const String& RenderStyle::contentAltText() const { - return rareNonInheritedData->m_altText; + return m_rareNonInheritedData->altText; +} + +void RenderStyle::setHasAttrContent() +{ + setUnique(); + SET_VAR(m_rareNonInheritedData, hasAttrContent, true); } -inline bool requireTransformOrigin(const Vector<RefPtr<TransformOperation>>& transformOperations, RenderStyle::ApplyTransformOrigin applyOrigin) +static inline bool requireTransformOrigin(const Vector<RefPtr<TransformOperation>>& transformOperations, RenderStyle::ApplyTransformOrigin applyOrigin) { - // transform-origin brackets the transform with translate operations. - // Optimize for the case where the only transform is a translation, since the transform-origin is irrelevant - // in that case. + // The transform-origin property brackets the transform with translate operations. + // When the only transform is a translation, the transform-origin is irrelevant. + if (applyOrigin != RenderStyle::IncludeTransformOrigin) return false; - unsigned size = transformOperations.size(); - for (unsigned i = 0; i < size; ++i) { - TransformOperation::OperationType type = transformOperations[i]->type(); - if (type != TransformOperation::TRANSLATE_X + for (auto& operation : transformOperations) { + // FIXME: Use affectedByTransformOrigin(). + auto type = operation->type(); + if (type != TransformOperation::TRANSLATE + && type != TransformOperation::TRANSLATE_3D + && type != TransformOperation::TRANSLATE_X && type != TransformOperation::TRANSLATE_Y - && type != TransformOperation::TRANSLATE - && type != TransformOperation::TRANSLATE_Z - && type != TransformOperation::TRANSLATE_3D) + && type != TransformOperation::TRANSLATE_Z) return true; } - + return false; } -void RenderStyle::applyTransform(TransformationMatrix& transform, const LayoutSize& borderBoxSize, ApplyTransformOrigin applyOrigin) const +void RenderStyle::applyTransform(TransformationMatrix& transform, const FloatRect& boundingBox, ApplyTransformOrigin applyOrigin) const { - // FIXME: when subpixel layout is supported (bug 71143) the body of this function could be replaced by - // applyTransform(transform, FloatRect(FloatPoint(), borderBoxSize), applyOrigin); - - const Vector<RefPtr<TransformOperation>>& transformOperations = rareNonInheritedData->m_transform->m_operations.operations(); - bool applyTransformOrigin = requireTransformOrigin(transformOperations, applyOrigin); + auto& operations = m_rareNonInheritedData->transform->operations.operations(); + bool applyTransformOrigin = requireTransformOrigin(operations, applyOrigin); - if (applyTransformOrigin) - transform.translate3d(floatValueForLength(transformOriginX(), borderBoxSize.width()), floatValueForLength(transformOriginY(), borderBoxSize.height()), transformOriginZ()); + float offsetX = transformOriginX().isPercent() ? boundingBox.x() : 0; + float offsetY = transformOriginY().isPercent() ? boundingBox.y() : 0; - unsigned size = transformOperations.size(); - for (unsigned i = 0; i < size; ++i) - transformOperations[i]->apply(transform, borderBoxSize); - - if (applyTransformOrigin) - transform.translate3d(-floatValueForLength(transformOriginX(), borderBoxSize.width()), -floatValueForLength(transformOriginY(), borderBoxSize.height()), -transformOriginZ()); -} - -void RenderStyle::applyTransform(TransformationMatrix& transform, const FloatRect& boundingBox, ApplyTransformOrigin applyOrigin) const -{ - const Vector<RefPtr<TransformOperation>>& transformOperations = rareNonInheritedData->m_transform->m_operations.operations(); - bool applyTransformOrigin = requireTransformOrigin(transformOperations, applyOrigin); - - float offsetX = transformOriginX().type() == Percent ? boundingBox.x() : 0; - float offsetY = transformOriginY().type() == Percent ? boundingBox.y() : 0; - if (applyTransformOrigin) { transform.translate3d(floatValueForLength(transformOriginX(), boundingBox.width()) + offsetX, floatValueForLength(transformOriginY(), boundingBox.height()) + offsetY, transformOriginZ()); } - - unsigned size = transformOperations.size(); - for (unsigned i = 0; i < size; ++i) - transformOperations[i]->apply(transform, boundingBox.size()); - + + for (auto& operation : operations) + operation->apply(transform, boundingBox.size()); + if (applyTransformOrigin) { transform.translate3d(-floatValueForLength(transformOriginX(), boundingBox.width()) - offsetX, -floatValueForLength(transformOriginY(), boundingBox.height()) - offsetY, @@ -1071,101 +1157,96 @@ void RenderStyle::setPageScaleTransform(float scale) setTransformOriginY(Length(0, Fixed)); } -void RenderStyle::setTextShadow(PassOwnPtr<ShadowData> shadowData, bool add) +void RenderStyle::setTextShadow(std::unique_ptr<ShadowData> shadowData, bool add) { ASSERT(!shadowData || (!shadowData->spread() && shadowData->style() == Normal)); - StyleRareInheritedData* rareData = rareInheritedData.access(); + auto& rareData = m_rareInheritedData.access(); if (!add) { - rareData->textShadow = shadowData; + rareData.textShadow = WTFMove(shadowData); return; } - shadowData->setNext(rareData->textShadow.release()); - rareData->textShadow = shadowData; + shadowData->setNext(WTFMove(rareData.textShadow)); + rareData.textShadow = WTFMove(shadowData); } -void RenderStyle::setBoxShadow(PassOwnPtr<ShadowData> shadowData, bool add) +void RenderStyle::setBoxShadow(std::unique_ptr<ShadowData> shadowData, bool add) { - StyleRareNonInheritedData* rareData = rareNonInheritedData.access(); + auto& rareData = m_rareNonInheritedData.access(); if (!add) { - rareData->m_boxShadow = shadowData; + rareData.boxShadow = WTFMove(shadowData); return; } - shadowData->setNext(rareData->m_boxShadow.release()); - rareData->m_boxShadow = shadowData; + shadowData->setNext(WTFMove(rareData.boxShadow)); + rareData.boxShadow = WTFMove(shadowData); } -static RoundedRect::Radii calcRadiiFor(const BorderData& border, IntSize size, RenderView* renderView) +static RoundedRect::Radii calcRadiiFor(const BorderData& border, const LayoutSize& size) { - return RoundedRect::Radii( - IntSize(valueForLength(border.topLeft().width(), size.width(), renderView), - valueForLength(border.topLeft().height(), size.height(), renderView)), - IntSize(valueForLength(border.topRight().width(), size.width(), renderView), - valueForLength(border.topRight().height(), size.height(), renderView)), - IntSize(valueForLength(border.bottomLeft().width(), size.width(), renderView), - valueForLength(border.bottomLeft().height(), size.height(), renderView)), - IntSize(valueForLength(border.bottomRight().width(), size.width(), renderView), - valueForLength(border.bottomRight().height(), size.height(), renderView))); + return { + sizeForLengthSize(border.topLeft(), size), + sizeForLengthSize(border.topRight(), size), + sizeForLengthSize(border.bottomLeft(), size), + sizeForLengthSize(border.bottomRight(), size) + }; } -static float calcConstraintScaleFor(const IntRect& rect, const RoundedRect::Radii& radii) +StyleImage* RenderStyle::listStyleImage() const { return m_rareInheritedData->listStyleImage.get(); } + +void RenderStyle::setListStyleImage(RefPtr<StyleImage>&& v) { - // Constrain corner radii using CSS3 rules: - // http://www.w3.org/TR/css3-background/#the-border-radius - - float factor = 1; - unsigned radiiSum; - - // top - radiiSum = static_cast<unsigned>(radii.topLeft().width()) + static_cast<unsigned>(radii.topRight().width()); // Casts to avoid integer overflow. - if (radiiSum > static_cast<unsigned>(rect.width())) - factor = std::min(static_cast<float>(rect.width()) / radiiSum, factor); - - // bottom - radiiSum = static_cast<unsigned>(radii.bottomLeft().width()) + static_cast<unsigned>(radii.bottomRight().width()); - if (radiiSum > static_cast<unsigned>(rect.width())) - factor = std::min(static_cast<float>(rect.width()) / radiiSum, factor); - - // left - radiiSum = static_cast<unsigned>(radii.topLeft().height()) + static_cast<unsigned>(radii.bottomLeft().height()); - if (radiiSum > static_cast<unsigned>(rect.height())) - factor = std::min(static_cast<float>(rect.height()) / radiiSum, factor); - - // right - radiiSum = static_cast<unsigned>(radii.topRight().height()) + static_cast<unsigned>(radii.bottomRight().height()); - if (radiiSum > static_cast<unsigned>(rect.height())) - factor = std::min(static_cast<float>(rect.height()) / radiiSum, factor); - - ASSERT(factor <= 1); - return factor; + if (m_rareInheritedData->listStyleImage != v) + m_rareInheritedData.access().listStyleImage = WTFMove(v); } -StyleImage* RenderStyle::listStyleImage() const { return rareInheritedData->listStyleImage.get(); } -void RenderStyle::setListStyleImage(PassRefPtr<StyleImage> v) +const Color& RenderStyle::color() const { - if (rareInheritedData->listStyleImage != v) - rareInheritedData.access()->listStyleImage = v; + return m_inheritedData->color; } -Color RenderStyle::color() const { return inherited->color; } -Color RenderStyle::visitedLinkColor() const { return inherited->visitedLinkColor; } -void RenderStyle::setColor(const Color& v) { SET_VAR(inherited, color, v); } -void RenderStyle::setVisitedLinkColor(const Color& v) { SET_VAR(inherited, visitedLinkColor, v); } +const Color& RenderStyle::visitedLinkColor() const +{ + return m_inheritedData->visitedLinkColor; +} -short RenderStyle::horizontalBorderSpacing() const { return inherited->horizontal_border_spacing; } -short RenderStyle::verticalBorderSpacing() const { return inherited->vertical_border_spacing; } -void RenderStyle::setHorizontalBorderSpacing(short v) { SET_VAR(inherited, horizontal_border_spacing, v); } -void RenderStyle::setVerticalBorderSpacing(short v) { SET_VAR(inherited, vertical_border_spacing, v); } +void RenderStyle::setColor(const Color& v) +{ + SET_VAR(m_inheritedData, color, v); +} + +void RenderStyle::setVisitedLinkColor(const Color& v) +{ + SET_VAR(m_inheritedData, visitedLinkColor, v); +} + +float RenderStyle::horizontalBorderSpacing() const +{ + return m_inheritedData->horizontalBorderSpacing; +} -RoundedRect RenderStyle::getRoundedBorderFor(const LayoutRect& borderRect, RenderView* renderView, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const +float RenderStyle::verticalBorderSpacing() const { - IntRect snappedBorderRect(pixelSnappedIntRect(borderRect)); - RoundedRect roundedRect(snappedBorderRect); + return m_inheritedData->verticalBorderSpacing; +} + +void RenderStyle::setHorizontalBorderSpacing(float v) +{ + SET_VAR(m_inheritedData, horizontalBorderSpacing, v); +} + +void RenderStyle::setVerticalBorderSpacing(float v) +{ + SET_VAR(m_inheritedData, verticalBorderSpacing, v); +} + +RoundedRect RenderStyle::getRoundedBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const +{ + RoundedRect roundedRect(borderRect); if (hasBorderRadius()) { - RoundedRect::Radii radii = calcRadiiFor(surround->border, snappedBorderRect.size(), renderView); - radii.scale(calcConstraintScaleFor(snappedBorderRect, radii)); + RoundedRect::Radii radii = calcRadiiFor(m_surroundData->border, borderRect.size()); + radii.scale(calcBorderRadiiConstraintScaleFor(borderRect, radii)); roundedRect.includeLogicalEdges(radii, isHorizontalWritingMode(), includeLogicalLeftEdge, includeLogicalRightEdge); } return roundedRect; @@ -1174,41 +1255,33 @@ RoundedRect RenderStyle::getRoundedBorderFor(const LayoutRect& borderRect, Rende RoundedRect RenderStyle::getRoundedInnerBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const { bool horizontal = isHorizontalWritingMode(); - - int leftWidth = (!horizontal || includeLogicalLeftEdge) ? borderLeftWidth() : 0; - int rightWidth = (!horizontal || includeLogicalRightEdge) ? borderRightWidth() : 0; - int topWidth = (horizontal || includeLogicalLeftEdge) ? borderTopWidth() : 0; - int bottomWidth = (horizontal || includeLogicalRightEdge) ? borderBottomWidth() : 0; - + auto leftWidth = (!horizontal || includeLogicalLeftEdge) ? borderLeftWidth() : 0; + auto rightWidth = (!horizontal || includeLogicalRightEdge) ? borderRightWidth() : 0; + auto topWidth = (horizontal || includeLogicalLeftEdge) ? borderTopWidth() : 0; + auto bottomWidth = (horizontal || includeLogicalRightEdge) ? borderBottomWidth() : 0; return getRoundedInnerBorderFor(borderRect, topWidth, bottomWidth, leftWidth, rightWidth, includeLogicalLeftEdge, includeLogicalRightEdge); } -RoundedRect RenderStyle::getRoundedInnerBorderFor(const LayoutRect& borderRect, - int topWidth, int bottomWidth, int leftWidth, int rightWidth, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const +RoundedRect RenderStyle::getRoundedInnerBorderFor(const LayoutRect& borderRect, LayoutUnit topWidth, LayoutUnit bottomWidth, + LayoutUnit leftWidth, LayoutUnit rightWidth, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const { - LayoutRect innerRect(borderRect.x() + leftWidth, - borderRect.y() + topWidth, - borderRect.width() - leftWidth - rightWidth, - borderRect.height() - topWidth - bottomWidth); - - RoundedRect roundedRect(pixelSnappedIntRect(innerRect)); - + RoundedRect roundedRect { { borderRect.x() + leftWidth, borderRect.y() + topWidth, + borderRect.width() - leftWidth - rightWidth, borderRect.height() - topWidth - bottomWidth } }; if (hasBorderRadius()) { - RoundedRect::Radii radii = getRoundedBorderFor(borderRect).radii(); + auto radii = getRoundedBorderFor(borderRect).radii(); radii.shrink(topWidth, bottomWidth, leftWidth, rightWidth); roundedRect.includeLogicalEdges(radii, isHorizontalWritingMode(), includeLogicalLeftEdge, includeLogicalRightEdge); } return roundedRect; } -static bool allLayersAreFixed(const FillLayer* layer) +static bool allLayersAreFixed(const FillLayer& layers) { - bool allFixed = true; - - for (const FillLayer* currLayer = layer; currLayer; currLayer = currLayer->next()) - allFixed &= (currLayer->image() && currLayer->attachment() == FixedBackgroundAttachment); - - return layer && allFixed; + for (auto* layer = &layers; layer; layer = layer->next()) { + if (!(layer->image() && layer->attachment() == FixedBackgroundAttachment)) + return false; + } + return true; } bool RenderStyle::hasEntirelyFixedBackground() const @@ -1218,14 +1291,14 @@ bool RenderStyle::hasEntirelyFixedBackground() const const CounterDirectiveMap* RenderStyle::counterDirectives() const { - return rareNonInheritedData->m_counterDirectives.get(); + return m_rareNonInheritedData->counterDirectives.get(); } CounterDirectiveMap& RenderStyle::accessCounterDirectives() { - OwnPtr<CounterDirectiveMap>& map = rareNonInheritedData.access()->m_counterDirectives; + auto& map = m_rareNonInheritedData.access().counterDirectives; if (!map) - map = adoptPtr(new CounterDirectiveMap); + map = std::make_unique<CounterDirectiveMap>(); return *map; } @@ -1240,14 +1313,14 @@ const AtomicString& RenderStyle::hyphenString() const { ASSERT(hyphens() != HyphensNone); - const AtomicString& hyphenationString = rareInheritedData.get()->hyphenationString; + auto& hyphenationString = m_rareInheritedData->hyphenationString; if (!hyphenationString.isNull()) return hyphenationString; // FIXME: This should depend on locale. - DEFINE_STATIC_LOCAL(AtomicString, hyphenMinusString, (&hyphenMinus, 1)); - DEFINE_STATIC_LOCAL(AtomicString, hyphenString, (&hyphen, 1)); - return font().primaryFontHasGlyphForCharacter(hyphen) ? hyphenString : hyphenMinusString; + static NeverDestroyed<AtomicString> hyphenMinusString(&hyphenMinus, 1); + static NeverDestroyed<AtomicString> hyphenString(&hyphen, 1); + return fontCascade().primaryFont().glyphForCharacter(hyphen) ? hyphenString : hyphenMinusString; } const AtomicString& RenderStyle::textEmphasisMarkString() const @@ -1258,28 +1331,28 @@ const AtomicString& RenderStyle::textEmphasisMarkString() const case TextEmphasisMarkCustom: return textEmphasisCustomMark(); case TextEmphasisMarkDot: { - DEFINE_STATIC_LOCAL(AtomicString, filledDotString, (&bullet, 1)); - DEFINE_STATIC_LOCAL(AtomicString, openDotString, (&whiteBullet, 1)); + static NeverDestroyed<AtomicString> filledDotString(&bullet, 1); + static NeverDestroyed<AtomicString> openDotString(&whiteBullet, 1); return textEmphasisFill() == TextEmphasisFillFilled ? filledDotString : openDotString; } case TextEmphasisMarkCircle: { - DEFINE_STATIC_LOCAL(AtomicString, filledCircleString, (&blackCircle, 1)); - DEFINE_STATIC_LOCAL(AtomicString, openCircleString, (&whiteCircle, 1)); + static NeverDestroyed<AtomicString> filledCircleString(&blackCircle, 1); + static NeverDestroyed<AtomicString> openCircleString(&whiteCircle, 1); return textEmphasisFill() == TextEmphasisFillFilled ? filledCircleString : openCircleString; } case TextEmphasisMarkDoubleCircle: { - DEFINE_STATIC_LOCAL(AtomicString, filledDoubleCircleString, (&fisheye, 1)); - DEFINE_STATIC_LOCAL(AtomicString, openDoubleCircleString, (&bullseye, 1)); + static NeverDestroyed<AtomicString> filledDoubleCircleString(&fisheye, 1); + static NeverDestroyed<AtomicString> openDoubleCircleString(&bullseye, 1); return textEmphasisFill() == TextEmphasisFillFilled ? filledDoubleCircleString : openDoubleCircleString; } case TextEmphasisMarkTriangle: { - DEFINE_STATIC_LOCAL(AtomicString, filledTriangleString, (&blackUpPointingTriangle, 1)); - DEFINE_STATIC_LOCAL(AtomicString, openTriangleString, (&whiteUpPointingTriangle, 1)); + static NeverDestroyed<AtomicString> filledTriangleString(&blackUpPointingTriangle, 1); + static NeverDestroyed<AtomicString> openTriangleString(&whiteUpPointingTriangle, 1); return textEmphasisFill() == TextEmphasisFillFilled ? filledTriangleString : openTriangleString; } case TextEmphasisMarkSesame: { - DEFINE_STATIC_LOCAL(AtomicString, filledSesameString, (&sesameDot, 1)); - DEFINE_STATIC_LOCAL(AtomicString, openSesameString, (&whiteSesameDot, 1)); + static NeverDestroyed<AtomicString> filledSesameString(&sesameDot, 1); + static NeverDestroyed<AtomicString> openSesameString(&whiteSesameDot, 1); return textEmphasisFill() == TextEmphasisFillFilled ? filledSesameString : openSesameString; } case TextEmphasisMarkAuto: @@ -1292,40 +1365,34 @@ const AtomicString& RenderStyle::textEmphasisMarkString() const } #if ENABLE(DASHBOARD_SUPPORT) + const Vector<StyleDashboardRegion>& RenderStyle::initialDashboardRegions() { - DEFINE_STATIC_LOCAL(Vector<StyleDashboardRegion>, emptyList, ()); + static NeverDestroyed<Vector<StyleDashboardRegion>> emptyList; return emptyList; } const Vector<StyleDashboardRegion>& RenderStyle::noneDashboardRegions() { - DEFINE_STATIC_LOCAL(Vector<StyleDashboardRegion>, noneList, ()); + static NeverDestroyed<Vector<StyleDashboardRegion>> noneList; static bool noneListInitialized = false; - if (!noneListInitialized) { - StyleDashboardRegion region; - region.label = ""; - region.offset.m_top = Length(); - region.offset.m_right = Length(); - region.offset.m_bottom = Length(); - region.offset.m_left = Length(); - region.type = StyleDashboardRegion::None; - noneList.append(region); + noneList.get().append(StyleDashboardRegion { emptyString(), { }, StyleDashboardRegion::None }); noneListInitialized = true; } return noneList; } + #endif void RenderStyle::adjustAnimations() { - AnimationList* animationList = rareNonInheritedData->m_animations.get(); + auto* animationList = m_rareNonInheritedData->animations.get(); if (!animationList) return; // Get rid of empty animations and anything beyond them - for (size_t i = 0; i < animationList->size(); ++i) { + for (size_t i = 0, size = animationList->size(); i < size; ++i) { if (animationList->animation(i).isEmpty()) { animationList->resize(i); break; @@ -1343,12 +1410,12 @@ void RenderStyle::adjustAnimations() void RenderStyle::adjustTransitions() { - AnimationList* transitionList = rareNonInheritedData->m_transitions.get(); + auto* transitionList = m_rareNonInheritedData->transitions.get(); if (!transitionList) return; // Get rid of empty transitions and anything beyond them - for (size_t i = 0; i < transitionList->size(); ++i) { + for (size_t i = 0, size = transitionList->size(); i < size; ++i) { if (transitionList->animation(i).isEmpty()) { transitionList->resize(i); break; @@ -1363,10 +1430,10 @@ void RenderStyle::adjustTransitions() // Repeat patterns into layers that don't have some properties set. transitionList->fillUnsetProperties(); - // Make sure there are no duplicate properties. This is an O(n^2) algorithm - // but the lists tend to be very short, so it is probably ok + // Make sure there are no duplicate properties. + // This is an O(n^2) algorithm but the lists tend to be short, so it is probably OK. for (size_t i = 0; i < transitionList->size(); ++i) { - for (size_t j = i+1; j < transitionList->size(); ++j) { + for (size_t j = i + 1; j < transitionList->size(); ++j) { if (transitionList->animation(i).property() == transitionList->animation(j).property()) { // toss i transitionList->remove(i); @@ -1376,76 +1443,111 @@ void RenderStyle::adjustTransitions() } } -AnimationList* RenderStyle::accessAnimations() +AnimationList& RenderStyle::ensureAnimations() { - if (!rareNonInheritedData.access()->m_animations) - rareNonInheritedData.access()->m_animations = adoptPtr(new AnimationList()); - return rareNonInheritedData->m_animations.get(); + if (!m_rareNonInheritedData.access().animations) + m_rareNonInheritedData.access().animations = std::make_unique<AnimationList>(); + return *m_rareNonInheritedData->animations; } -AnimationList* RenderStyle::accessTransitions() +AnimationList& RenderStyle::ensureTransitions() { - if (!rareNonInheritedData.access()->m_transitions) - rareNonInheritedData.access()->m_transitions = adoptPtr(new AnimationList()); - return rareNonInheritedData->m_transitions.get(); + if (!m_rareNonInheritedData.access().transitions) + m_rareNonInheritedData.access().transitions = std::make_unique<AnimationList>(); + return *m_rareNonInheritedData->transitions; } const Animation* RenderStyle::transitionForProperty(CSSPropertyID property) const { - if (transitions()) { - for (size_t i = 0; i < transitions()->size(); ++i) { - const Animation& p = transitions()->animation(i); - if (p.animationMode() == Animation::AnimateAll || p.property() == property) { - return &p; - } - } + auto* transitions = this->transitions(); + if (!transitions) + return nullptr; + for (size_t i = 0, size = transitions->size(); i < size; ++i) { + auto& animation = transitions->animation(i); + if (animation.animationMode() == Animation::AnimateAll || animation.property() == property) + return &animation; } - return 0; + return nullptr; } -const Font& RenderStyle::font() const { return inherited->font; } -const FontMetrics& RenderStyle::fontMetrics() const { return inherited->font.fontMetrics(); } -const FontDescription& RenderStyle::fontDescription() const { return inherited->font.fontDescription(); } -float RenderStyle::specifiedFontSize() const { return fontDescription().specifiedSize(); } -float RenderStyle::computedFontSize() const { return fontDescription().computedSize(); } -int RenderStyle::fontSize() const { return inherited->font.pixelSize(); } +const FontCascade& RenderStyle::fontCascade() const +{ + return m_inheritedData->fontCascade; +} -const Length& RenderStyle::wordSpacing() const { return rareInheritedData->wordSpacing; } -float RenderStyle::letterSpacing() const { return inherited->font.letterSpacing(); } +const FontMetrics& RenderStyle::fontMetrics() const +{ + return m_inheritedData->fontCascade.fontMetrics(); +} -bool RenderStyle::setFontDescription(const FontDescription& v) +const FontCascadeDescription& RenderStyle::fontDescription() const { - if (inherited->font.fontDescription() != v) { - inherited.access()->font = Font(v, inherited->font.letterSpacing(), inherited->font.wordSpacing()); - return true; - } - return false; + return m_inheritedData->fontCascade.fontDescription(); +} + +float RenderStyle::specifiedFontSize() const +{ + return fontDescription().specifiedSize(); +} + +float RenderStyle::computedFontSize() const +{ + return fontDescription().computedSize(); +} + +int RenderStyle::fontSize() const +{ + return m_inheritedData->fontCascade.pixelSize(); +} + +const Length& RenderStyle::wordSpacing() const +{ + return m_rareInheritedData->wordSpacing; } -#if ENABLE(IOS_TEXT_AUTOSIZING) -const Length& RenderStyle::specifiedLineHeight() const { return inherited->specifiedLineHeight; } -void RenderStyle::setSpecifiedLineHeight(Length v) { SET_VAR(inherited, specifiedLineHeight, v); } +float RenderStyle::letterSpacing() const +{ + return m_inheritedData->fontCascade.letterSpacing(); +} + +bool RenderStyle::setFontDescription(const FontCascadeDescription& description) +{ + if (m_inheritedData->fontCascade.fontDescription() == description) + return false; + auto& cascade = m_inheritedData.access().fontCascade; + cascade = { description, cascade.letterSpacing(), cascade.wordSpacing() }; + return true; +} + +const Length& RenderStyle::specifiedLineHeight() const +{ +#if ENABLE(TEXT_AUTOSIZING) + return m_inheritedData->specifiedLineHeight; #else -const Length& RenderStyle::specifiedLineHeight() const { return inherited->line_height; } + return m_inheritedData->lineHeight; #endif +} -Length RenderStyle::lineHeight() const -{ - const Length& lh = inherited->line_height; #if ENABLE(TEXT_AUTOSIZING) - // Unlike fontDescription().computedSize() and hence fontSize(), this is - // recalculated on demand as we only store the specified line height. - // FIXME: Should consider scaling the fixed part of any calc expressions - // too, though this involves messily poking into CalcExpressionLength. - float multiplier = textAutosizingMultiplier(); - if (multiplier > 1 && lh.isFixed()) - return Length(TextAutosizer::computeAutosizedFontSize(lh.value(), multiplier), Fixed); + +void RenderStyle::setSpecifiedLineHeight(Length&& height) +{ + SET_VAR(m_inheritedData, specifiedLineHeight, WTFMove(height)); +} + #endif - return lh; + +const Length& RenderStyle::lineHeight() const +{ + return m_inheritedData->lineHeight; +} + +void RenderStyle::setLineHeight(Length&& height) +{ + SET_VAR(m_inheritedData, lineHeight, WTFMove(height)); } -void RenderStyle::setLineHeight(Length specifiedLineHeight) { SET_VAR(inherited, line_height, specifiedLineHeight); } -int RenderStyle::computedLineHeight(RenderView* renderView) const +int RenderStyle::computedLineHeight() const { const Length& lh = lineHeight(); @@ -1453,41 +1555,38 @@ int RenderStyle::computedLineHeight(RenderView* renderView) const if (lh.isNegative()) return fontMetrics().lineSpacing(); - if (lh.isPercent()) + if (lh.isPercentOrCalculated()) return minimumValueForLength(lh, fontSize()); - if (lh.isViewportPercentage()) - return valueForLength(lh, 0, renderView); - - return lh.value(); + return clampTo<int>(lh.value()); } -void RenderStyle::setWordSpacing(Length v) +void RenderStyle::setWordSpacing(Length&& value) { float fontWordSpacing; - switch (v.type()) { + switch (value.type()) { case Auto: fontWordSpacing = 0; - FALLTHROUGH; + break; case Percent: - fontWordSpacing = v.getFloatValue() * font().spaceWidth() / 100; + fontWordSpacing = value.percent() * fontCascade().spaceWidth() / 100; break; case Fixed: - fontWordSpacing = v.getFloatValue(); + fontWordSpacing = value.value(); break; case Calculated: - fontWordSpacing = v.nonNanCalculatedValue(maxValueForCssLength); + fontWordSpacing = value.nonNanCalculatedValue(maxValueForCssLength); break; default: ASSERT_NOT_REACHED(); fontWordSpacing = 0; break; } - inherited.access()->font.setWordSpacing(fontWordSpacing); - rareInheritedData.access()->wordSpacing = std::move(v); + m_inheritedData.access().fontCascade.setWordSpacing(fontWordSpacing); + m_rareInheritedData.access().wordSpacing = WTFMove(value); } -void RenderStyle::setLetterSpacing(float v) { inherited.access()->font.setLetterSpacing(v); } +void RenderStyle::setLetterSpacing(float v) { m_inheritedData.access().fontCascade.setLetterSpacing(v); } void RenderStyle::setFontSize(float size) { @@ -1500,24 +1599,28 @@ void RenderStyle::setFontSize(float size) else size = std::min(maximumAllowedFontSize, size); - FontSelector* currentFontSelector = font().fontSelector(); - FontDescription desc(fontDescription()); - desc.setSpecifiedSize(size); - desc.setComputedSize(size); + FontSelector* currentFontSelector = fontCascade().fontSelector(); + auto description = fontDescription(); + description.setSpecifiedSize(size); + description.setComputedSize(size); -#if ENABLE(TEXT_AUTOSIZING) - float multiplier = textAutosizingMultiplier(); - if (multiplier > 1) { - float autosizedFontSize = TextAutosizer::computeAutosizedFontSize(size, multiplier); - desc.setComputedSize(min(maximumAllowedFontSize, autosizedFontSize)); - } -#endif + setFontDescription(description); + fontCascade().update(currentFontSelector); +} - setFontDescription(desc); - font().update(currentFontSelector); +#if ENABLE(VARIATION_FONTS) +void RenderStyle::setFontVariationSettings(FontVariationSettings settings) +{ + FontSelector* currentFontSelector = fontCascade().fontSelector(); + auto description = fontDescription(); + description.setVariationSettings(WTFMove(settings)); + + setFontDescription(description); + fontCascade().update(currentFontSelector); } +#endif -void RenderStyle::getShadowExtent(const ShadowData* shadow, LayoutUnit &top, LayoutUnit &right, LayoutUnit &bottom, LayoutUnit &left) const +void RenderStyle::getShadowExtent(const ShadowData* shadow, LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left) const { top = 0; right = 0; @@ -1616,7 +1719,7 @@ Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) c case CSSPropertyOutlineColor: result = visitedLink ? visitedLinkOutlineColor() : outlineColor(); break; - case CSSPropertyWebkitColumnRuleColor: + case CSSPropertyColumnRuleColor: result = visitedLink ? visitedLinkColumnRuleColor() : columnRuleColor(); break; case CSSPropertyWebkitTextDecorationColor: @@ -1638,7 +1741,7 @@ Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) c if (!result.isValid()) { if (!visitedLink && (borderStyle == INSET || borderStyle == OUTSET || borderStyle == RIDGE || borderStyle == GROOVE)) - result.setRGB(238, 238, 238); + result = Color(238, 238, 238); else result = visitedLink ? visitedLinkColor() : color(); } @@ -1666,7 +1769,7 @@ Color RenderStyle::visitedDependentColor(int colorProperty) const return unvisitedColor; // Take the alpha from the unvisited color, but get the RGB values from the visited color. - return Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), unvisitedColor.alpha()); + return visitedColor.colorWithAlpha(unvisitedColor.alphaAsFloat()); } const BorderValue& RenderStyle::borderBefore() const @@ -1715,7 +1818,7 @@ const BorderValue& RenderStyle::borderEnd() const return isLeftToRightDirection() ? borderBottom() : borderTop(); } -unsigned short RenderStyle::borderBeforeWidth() const +float RenderStyle::borderBeforeWidth() const { switch (writingMode()) { case TopToBottomWritingMode: @@ -1731,7 +1834,7 @@ unsigned short RenderStyle::borderBeforeWidth() const return borderTopWidth(); } -unsigned short RenderStyle::borderAfterWidth() const +float RenderStyle::borderAfterWidth() const { switch (writingMode()) { case TopToBottomWritingMode: @@ -1747,67 +1850,67 @@ unsigned short RenderStyle::borderAfterWidth() const return borderBottomWidth(); } -unsigned short RenderStyle::borderStartWidth() const +float RenderStyle::borderStartWidth() const { if (isHorizontalWritingMode()) return isLeftToRightDirection() ? borderLeftWidth() : borderRightWidth(); return isLeftToRightDirection() ? borderTopWidth() : borderBottomWidth(); } -unsigned short RenderStyle::borderEndWidth() const +float RenderStyle::borderEndWidth() const { if (isHorizontalWritingMode()) return isLeftToRightDirection() ? borderRightWidth() : borderLeftWidth(); return isLeftToRightDirection() ? borderBottomWidth() : borderTopWidth(); } -void RenderStyle::setMarginStart(Length margin) +void RenderStyle::setMarginStart(Length&& margin) { if (isHorizontalWritingMode()) { if (isLeftToRightDirection()) - setMarginLeft(margin); + setMarginLeft(WTFMove(margin)); else - setMarginRight(margin); + setMarginRight(WTFMove(margin)); } else { if (isLeftToRightDirection()) - setMarginTop(margin); + setMarginTop(WTFMove(margin)); else - setMarginBottom(margin); + setMarginBottom(WTFMove(margin)); } } -void RenderStyle::setMarginEnd(Length margin) +void RenderStyle::setMarginEnd(Length&& margin) { if (isHorizontalWritingMode()) { if (isLeftToRightDirection()) - setMarginRight(margin); + setMarginRight(WTFMove(margin)); else - setMarginLeft(margin); + setMarginLeft(WTFMove(margin)); } else { if (isLeftToRightDirection()) - setMarginBottom(margin); + setMarginBottom(WTFMove(margin)); else - setMarginTop(margin); + setMarginTop(WTFMove(margin)); } } TextEmphasisMark RenderStyle::textEmphasisMark() const { - TextEmphasisMark mark = static_cast<TextEmphasisMark>(rareInheritedData->textEmphasisMark); + auto mark = static_cast<TextEmphasisMark>(m_rareInheritedData->textEmphasisMark); if (mark != TextEmphasisMarkAuto) return mark; - if (isHorizontalWritingMode()) return TextEmphasisMarkDot; - return TextEmphasisMarkSesame; } #if ENABLE(TOUCH_EVENTS) + Color RenderStyle::initialTapHighlightColor() { return RenderTheme::tapHighlightColor(); } + #endif LayoutBoxExtent RenderStyle::imageOutsets(const NinePieceImage& image) const @@ -1818,78 +1921,61 @@ LayoutBoxExtent RenderStyle::imageOutsets(const NinePieceImage& image) const NinePieceImage::computeOutset(image.outset().left(), borderLeftWidth())); } -void RenderStyle::getFontAndGlyphOrientation(FontOrientation& fontOrientation, NonCJKGlyphOrientation& glyphOrientation) +std::pair<FontOrientation, NonCJKGlyphOrientation> RenderStyle::fontAndGlyphOrientation() { - if (isHorizontalWritingMode()) { - fontOrientation = Horizontal; - glyphOrientation = NonCJKGlyphOrientationVerticalRight; - return; - } + // FIXME: TextOrientationSideways should map to sideways-left in vertical-lr, which is not supported yet. + + if (isHorizontalWritingMode()) + return { Horizontal, NonCJKGlyphOrientation::Mixed }; switch (textOrientation()) { - case TextOrientationVerticalRight: - fontOrientation = Vertical; - glyphOrientation = NonCJKGlyphOrientationVerticalRight; - return; - case TextOrientationUpright: - fontOrientation = Vertical; - glyphOrientation = NonCJKGlyphOrientationUpright; - return; - case TextOrientationSideways: - if (writingMode() == LeftToRightWritingMode) { - // FIXME: This should map to sideways-left, which is not supported yet. - fontOrientation = Vertical; - glyphOrientation = NonCJKGlyphOrientationVerticalRight; - return; - } - fontOrientation = Horizontal; - glyphOrientation = NonCJKGlyphOrientationVerticalRight; - return; - case TextOrientationSidewaysRight: - fontOrientation = Horizontal; - glyphOrientation = NonCJKGlyphOrientationVerticalRight; - return; + case TextOrientation::Mixed: + return { Vertical, NonCJKGlyphOrientation::Mixed }; + case TextOrientation::Upright: + return { Vertical, NonCJKGlyphOrientation::Upright }; + case TextOrientation::Sideways: + return { Horizontal, NonCJKGlyphOrientation::Mixed }; default: ASSERT_NOT_REACHED(); - fontOrientation = Horizontal; - glyphOrientation = NonCJKGlyphOrientationVerticalRight; - return; + return { Horizontal, NonCJKGlyphOrientation::Mixed }; } } -void RenderStyle::setBorderImageSource(PassRefPtr<StyleImage> image) +void RenderStyle::setBorderImageSource(RefPtr<StyleImage>&& image) { - if (surround->border.m_image.image() == image.get()) + if (m_surroundData->border.m_image.image() == image.get()) return; - surround.access()->border.m_image.setImage(image); + m_surroundData.access().border.m_image.setImage(WTFMove(image)); } -void RenderStyle::setBorderImageSlices(LengthBox slices) +void RenderStyle::setBorderImageSlices(LengthBox&& slices) { - if (surround->border.m_image.imageSlices() == slices) + if (m_surroundData->border.m_image.imageSlices() == slices) return; - surround.access()->border.m_image.setImageSlices(slices); + m_surroundData.access().border.m_image.setImageSlices(WTFMove(slices)); } -void RenderStyle::setBorderImageWidth(LengthBox slices) +void RenderStyle::setBorderImageWidth(LengthBox&& slices) { - if (surround->border.m_image.borderSlices() == slices) + if (m_surroundData->border.m_image.borderSlices() == slices) return; - surround.access()->border.m_image.setBorderSlices(slices); + m_surroundData.access().border.m_image.setBorderSlices(WTFMove(slices)); } -void RenderStyle::setBorderImageOutset(LengthBox outset) +void RenderStyle::setBorderImageOutset(LengthBox&& outset) { - if (surround->border.m_image.outset() == outset) + if (m_surroundData->border.m_image.outset() == outset) return; - surround.access()->border.m_image.setOutset(outset); + m_surroundData.access().border.m_image.setOutset(WTFMove(outset)); } void RenderStyle::setColumnStylesFromPaginationMode(const Pagination::Mode& paginationMode) { if (paginationMode == Pagination::Unpaginated) return; - + + setColumnFill(ColumnFillAuto); + switch (paginationMode) { case Pagination::LeftToRightPaginated: setColumnAxis(HorizontalColumnAxis); @@ -1925,4 +2011,263 @@ void RenderStyle::setColumnStylesFromPaginationMode(const Pagination::Mode& pagi } } +#if ENABLE(CSS_SCROLL_SNAP) + +ScrollSnapType RenderStyle::initialScrollSnapType() +{ + return { }; +} + +ScrollSnapAlign RenderStyle::initialScrollSnapAlign() +{ + return { }; +} + +const StyleScrollSnapArea& RenderStyle::scrollSnapArea() const +{ + return *m_rareNonInheritedData->scrollSnapArea; +} + +const StyleScrollSnapPort& RenderStyle::scrollSnapPort() const +{ + return *m_rareNonInheritedData->scrollSnapPort; +} + +const ScrollSnapType& RenderStyle::scrollSnapType() const +{ + return m_rareNonInheritedData->scrollSnapPort->type; +} + +const LengthBox& RenderStyle::scrollPadding() const +{ + return m_rareNonInheritedData->scrollSnapPort->scrollPadding; +} + +const Length& RenderStyle::scrollPaddingTop() const +{ + return scrollPadding().top(); +} + +const Length& RenderStyle::scrollPaddingBottom() const +{ + return scrollPadding().bottom(); +} + +const Length& RenderStyle::scrollPaddingLeft() const +{ + return scrollPadding().left(); +} + +const Length& RenderStyle::scrollPaddingRight() const +{ + return scrollPadding().right(); +} + +const ScrollSnapAlign& RenderStyle::scrollSnapAlign() const +{ + return m_rareNonInheritedData->scrollSnapArea->alignment; +} + +const LengthBox& RenderStyle::scrollSnapMargin() const +{ + return m_rareNonInheritedData->scrollSnapArea->scrollSnapMargin; +} + +const Length& RenderStyle::scrollSnapMarginTop() const +{ + return scrollSnapMargin().top(); +} + +const Length& RenderStyle::scrollSnapMarginBottom() const +{ + return scrollSnapMargin().bottom(); +} + +const Length& RenderStyle::scrollSnapMarginLeft() const +{ + return scrollSnapMargin().left(); +} + +const Length& RenderStyle::scrollSnapMarginRight() const +{ + return scrollSnapMargin().right(); +} + +void RenderStyle::setScrollSnapType(const ScrollSnapType& type) +{ + SET_NESTED_VAR(m_rareNonInheritedData, scrollSnapPort, type, type); +} + +void RenderStyle::setScrollPaddingTop(Length&& length) +{ + SET_NESTED_VAR(m_rareNonInheritedData, scrollSnapPort, scrollPadding.top(), WTFMove(length)); +} + +void RenderStyle::setScrollPaddingBottom(Length&& length) +{ + SET_NESTED_VAR(m_rareNonInheritedData, scrollSnapPort, scrollPadding.bottom(), WTFMove(length)); +} + +void RenderStyle::setScrollPaddingLeft(Length&& length) +{ + SET_NESTED_VAR(m_rareNonInheritedData, scrollSnapPort, scrollPadding.left(), WTFMove(length)); +} + +void RenderStyle::setScrollPaddingRight(Length&& length) +{ + SET_NESTED_VAR(m_rareNonInheritedData, scrollSnapPort, scrollPadding.right(), WTFMove(length)); +} + +void RenderStyle::setScrollSnapAlign(const ScrollSnapAlign& alignment) +{ + SET_NESTED_VAR(m_rareNonInheritedData, scrollSnapArea, alignment, alignment); +} + +void RenderStyle::setScrollSnapMarginTop(Length&& length) +{ + SET_NESTED_VAR(m_rareNonInheritedData, scrollSnapArea, scrollSnapMargin.top(), WTFMove(length)); +} + +void RenderStyle::setScrollSnapMarginBottom(Length&& length) +{ + SET_NESTED_VAR(m_rareNonInheritedData, scrollSnapArea, scrollSnapMargin.bottom(), WTFMove(length)); +} + +void RenderStyle::setScrollSnapMarginLeft(Length&& length) +{ + SET_NESTED_VAR(m_rareNonInheritedData, scrollSnapArea, scrollSnapMargin.left(), WTFMove(length)); +} + +void RenderStyle::setScrollSnapMarginRight(Length&& length) +{ + SET_NESTED_VAR(m_rareNonInheritedData, scrollSnapArea, scrollSnapMargin.right(), WTFMove(length)); +} + +#endif + +bool RenderStyle::hasReferenceFilterOnly() const +{ + if (!hasFilter()) + return false; + auto& filterOperations = m_rareNonInheritedData->filter->operations; + return filterOperations.size() == 1 && filterOperations.at(0)->type() == FilterOperation::REFERENCE; +} + +void RenderStyle::checkVariablesInCustomProperties() +{ + if (!m_rareInheritedData->customProperties->containsVariables) + return; + + auto& customPropertyData = m_rareInheritedData.access().customProperties.access(); + + // Our first pass checks the variables for validity and replaces any properties that became + // invalid with empty values. + auto& customProperties = customPropertyData.values; + HashSet<AtomicString> invalidProperties; + for (auto entry : customProperties) { + if (!entry.value->containsVariables()) + continue; + HashSet<AtomicString> seenProperties; + entry.value->checkVariablesForCycles(entry.key, customProperties, seenProperties, invalidProperties); + } + + // Now insert invalid values. + if (!invalidProperties.isEmpty()) { + auto invalidValue = CSSCustomPropertyValue::createInvalid(); + for (auto& property : invalidProperties) + customProperties.set(property, invalidValue.copyRef()); + } + + // Now that all of the properties have been tested for validity and replaced with + // invalid values if they failed, we can perform variable substitution on the valid values. + Vector<Ref<CSSCustomPropertyValue>> resolvedValues; + for (auto entry : customProperties) { + if (!entry.value->containsVariables()) + continue; + entry.value->resolveVariableReferences(customProperties, resolvedValues); + } + + // With all results computed, we can now mutate our table to eliminate the variables and + // hold the final values. This way when we inherit, we don't end up resubstituting variables, etc. + for (auto& resolvedValue : resolvedValues) + customProperties.set(resolvedValue->name(), resolvedValue.copyRef()); + + customPropertyData.containsVariables = false; +} + +float RenderStyle::outlineWidth() const +{ + if (m_backgroundData->outline.style() == BNONE) + return 0; + if (outlineStyleIsAuto()) + return std::max(m_backgroundData->outline.width(), RenderTheme::platformFocusRingWidth()); + return m_backgroundData->outline.width(); +} + +float RenderStyle::outlineOffset() const +{ + if (m_backgroundData->outline.style() == BNONE) + return 0; + if (outlineStyleIsAuto()) + return (m_backgroundData->outline.offset() + RenderTheme::platformFocusRingOffset(outlineWidth())); + return m_backgroundData->outline.offset(); +} + +bool RenderStyle::shouldPlaceBlockDirectionScrollbarOnLeft() const +{ + return !isLeftToRightDirection() && isHorizontalWritingMode(); +} + +#if ENABLE(DASHBOARD_SUPPORT) + +void RenderStyle::setDashboardRegion(int type, const String& label, Length&& top, Length&& right, Length&& bottom, Length&& left, bool append) +{ + if (!append) + m_rareNonInheritedData.access().dashboardRegions.clear(); + m_rareNonInheritedData.access().dashboardRegions.append({ label, { WTFMove(top), WTFMove(right), WTFMove(bottom), WTFMove(left) }, type }); +} + +#endif + +Vector<PaintType, 3> RenderStyle::paintTypesForPaintOrder() const +{ + Vector<PaintType, 3> paintOrder; + switch (this->paintOrder()) { + case PaintOrderNormal: + FALLTHROUGH; + case PaintOrderFill: + paintOrder.append(PaintTypeFill); + paintOrder.append(PaintTypeStroke); + paintOrder.append(PaintTypeMarkers); + break; + case PaintOrderFillMarkers: + paintOrder.append(PaintTypeFill); + paintOrder.append(PaintTypeMarkers); + paintOrder.append(PaintTypeStroke); + break; + case PaintOrderStroke: + paintOrder.append(PaintTypeStroke); + paintOrder.append(PaintTypeFill); + paintOrder.append(PaintTypeMarkers); + break; + case PaintOrderStrokeMarkers: + paintOrder.append(PaintTypeStroke); + paintOrder.append(PaintTypeMarkers); + paintOrder.append(PaintTypeFill); + break; + case PaintOrderMarkers: + paintOrder.append(PaintTypeMarkers); + paintOrder.append(PaintTypeFill); + paintOrder.append(PaintTypeStroke); + break; + case PaintOrderMarkersStroke: + paintOrder.append(PaintTypeMarkers); + paintOrder.append(PaintTypeStroke); + paintOrder.append(PaintTypeFill); + break; + }; + return paintOrder; +} + + } // namespace WebCore diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h index 73a5350ce..3a1f0b33a 100644 --- a/Source/WebCore/rendering/style/RenderStyle.h +++ b/Source/WebCore/rendering/style/RenderStyle.h @@ -2,7 +2,7 @@ * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * (C) 2000 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) * * This library is free software; you can redistribute it and/or @@ -22,8 +22,7 @@ * */ -#ifndef RenderStyle_h -#define RenderStyle_h +#pragma once #include "AnimationList.h" #include "BorderValue.h" @@ -31,31 +30,27 @@ #include "CSSPrimitiveValue.h" #include "CSSPropertyNames.h" #include "Color.h" -#include "ColorSpace.h" #include "CounterDirectives.h" #include "DataRef.h" -#include "FontBaseline.h" #include "FontDescription.h" #include "GraphicsTypes.h" -#include "LayoutBoxExtent.h" #include "Length.h" #include "LengthBox.h" -#include "LengthFunctions.h" +#include "LengthPoint.h" #include "LengthSize.h" #include "LineClampValue.h" #include "NinePieceImage.h" -#include "OutlineValue.h" #include "Pagination.h" #include "RenderStyleConstants.h" #include "RoundedRect.h" +#include "SVGRenderStyle.h" #include "ShadowData.h" #include "ShapeValue.h" #include "StyleBackgroundData.h" #include "StyleBoxData.h" #include "StyleDeprecatedFlexibleBoxData.h" +#include "StyleFilterData.h" #include "StyleFlexibleBoxData.h" -#include "StyleGridData.h" -#include "StyleGridItemData.h" #include "StyleMarqueeData.h" #include "StyleMultiColData.h" #include "StyleRareInheritedData.h" @@ -64,53 +59,50 @@ #include "StyleSurroundData.h" #include "StyleTransformData.h" #include "StyleVisualData.h" -#include "TextDirection.h" +#include "TextFlags.h" #include "ThemeTypes.h" #include "TransformOperations.h" #include "UnicodeBidi.h" +#include <memory> #include <wtf/Forward.h> -#include <wtf/OwnPtr.h> -#include <wtf/RefCounted.h> +#include <wtf/NeverDestroyed.h> #include <wtf/StdLibExtras.h> #include <wtf/Vector.h> -#if ENABLE(CSS_FILTERS) -#include "StyleFilterData.h" -#endif +#include "StyleGridData.h" +#include "StyleGridItemData.h" #if ENABLE(DASHBOARD_SUPPORT) #include "StyleDashboardRegion.h" #endif -#if ENABLE(IOS_TEXT_AUTOSIZING) +#if ENABLE(TEXT_AUTOSIZING) #include "TextSizeAdjustment.h" #endif -#if ENABLE(SVG) -#include "SVGPaint.h" -#include "SVGRenderStyle.h" -#endif - -template<typename T, typename U> inline bool compareEqual(const T& t, const U& u) { return t == static_cast<T>(u); } +#define SET_VAR(group, variable, value) do { \ + if (!compareEqual(group->variable, value)) \ + group.access().variable = value; \ + } while (0) -#define SET_VAR(group, variable, value) \ - if (!compareEqual(group->variable, value)) \ - group.access()->variable = value +#define SET_NESTED_VAR(group, parentVariable, variable, value) do { \ + if (!compareEqual(group->parentVariable->variable, value)) \ + group.access().parentVariable.access().variable = value; \ + } while (0) -#define SET_BORDERVALUE_COLOR(group, variable, value) \ - if (!compareEqual(group->variable.color(), value)) \ - group.access()->variable.setColor(value) +#define SET_BORDERVALUE_COLOR(group, variable, value) do { \ + if (!compareEqual(group->variable.color(), value)) \ + group.access().variable.setColor(value); \ + } while (0) namespace WebCore { -#if ENABLE(CSS_FILTERS) -class FilterOperations; -#endif - class BorderData; +class ContentData; class CounterContent; class CursorList; -class Font; +class FilterOperations; +class FontCascade; class FontMetrics; class IntRect; class Pair; @@ -118,360 +110,160 @@ class ShadowData; class StyleImage; class StyleInheritedData; class StyleResolver; +class StyleScrollSnapArea; +class StyleScrollSnapPort; class TransformationMatrix; -class ContentData; +struct ScrollSnapAlign; +struct ScrollSnapType; -typedef Vector<RefPtr<RenderStyle>, 4> PseudoStyleCache; +using PseudoStyleCache = Vector<std::unique_ptr<RenderStyle>, 4>; -class RenderStyle: public RefCounted<RenderStyle> { - friend class CSSPropertyAnimationWrapperMap; // Used by CSS animations. We can't allow them to animate based off visited colors. - friend class ApplyStyleCommand; // Editing has to only reveal unvisited info. - friend class DeprecatedStyleBuilder; // Sets members directly. - friend class EditingStyle; // Editing has to only reveal unvisited info. - friend class ComputedStyleExtractor; // Ignores visited styles, so needs to be able to see unvisited info. - friend class PropertyWrapperMaybeInvalidColor; // Used by CSS animations. We can't allow them to animate based off visited colors. - friend class RenderSVGResource; // FIXME: Needs to alter the visited state by hand. Should clean the SVG code up and move it into RenderStyle perhaps. - friend class RenderTreeAsText; // FIXME: Only needed so the render tree can keep lying and dump the wrong colors. Rebaselining would allow this to be yanked. - friend class StyleResolver; // Sets members directly. -protected: +template<typename T, typename U> inline bool compareEqual(const T& t, const U& u) { return t == static_cast<const T&>(u); } - // non-inherited attributes - DataRef<StyleBoxData> m_box; - DataRef<StyleVisualData> visual; - DataRef<StyleBackgroundData> m_background; - DataRef<StyleSurroundData> surround; - DataRef<StyleRareNonInheritedData> rareNonInheritedData; +class RenderStyle { + WTF_MAKE_FAST_ALLOCATED; - // inherited attributes - DataRef<StyleRareInheritedData> rareInheritedData; - DataRef<StyleInheritedData> inherited; +private: + enum CloneTag { Clone }; + enum CreateDefaultStyleTag { CreateDefaultStyle }; - // list of associated pseudo styles - OwnPtr<PseudoStyleCache> m_cachedPseudoStyles; +public: + RenderStyle(RenderStyle&&) = default; + RenderStyle& operator=(RenderStyle&&) = default; + ~RenderStyle(); -#if ENABLE(SVG) - DataRef<SVGRenderStyle> m_svgStyle; -#endif + RenderStyle replace(RenderStyle&&) WARN_UNUSED_RETURN; -// !START SYNC!: Keep this in sync with the copy constructor in RenderStyle.cpp and implicitlyInherited() in StyleResolver.cpp + explicit RenderStyle(CreateDefaultStyleTag); + RenderStyle(const RenderStyle&, CloneTag); - // inherit - struct InheritedFlags { - bool operator==(const InheritedFlags& other) const - { - return (_empty_cells == other._empty_cells) - && (_caption_side == other._caption_side) - && (_list_style_type == other._list_style_type) - && (_list_style_position == other._list_style_position) - && (_visibility == other._visibility) - && (_text_align == other._text_align) - && (_text_transform == other._text_transform) - && (_text_decorations == other._text_decorations) - && (_cursor_style == other._cursor_style) -#if ENABLE(CURSOR_VISIBILITY) - && (m_cursorVisibility == other.m_cursorVisibility) -#endif - && (_direction == other._direction) - && (_white_space == other._white_space) - && (_border_collapse == other._border_collapse) - && (_box_direction == other._box_direction) - && (m_rtlOrdering == other.m_rtlOrdering) - && (m_printColorAdjust == other.m_printColorAdjust) - && (_pointerEvents == other._pointerEvents) - && (_insideLink == other._insideLink) - && (m_writingMode == other.m_writingMode); - } + static RenderStyle& defaultStyle(); - bool operator!=(const InheritedFlags& other) const { return !(*this == other); } + static RenderStyle create(); + static std::unique_ptr<RenderStyle> createPtr(); - unsigned _empty_cells : 1; // EEmptyCell - unsigned _caption_side : 2; // ECaptionSide - unsigned _list_style_type : 7; // EListStyleType - unsigned _list_style_position : 1; // EListStylePosition - unsigned _visibility : 2; // EVisibility - unsigned _text_align : 4; // ETextAlign - unsigned _text_transform : 2; // ETextTransform - unsigned _text_decorations : TextDecorationBits; - unsigned _cursor_style : 6; // ECursor -#if ENABLE(CURSOR_VISIBILITY) - unsigned m_cursorVisibility : 1; // CursorVisibility -#endif - unsigned _direction : 1; // TextDirection - unsigned _white_space : 3; // EWhiteSpace - // 32 bits - unsigned _border_collapse : 1; // EBorderCollapse - unsigned _box_direction : 1; // EBoxDirection (CSS3 box_direction property, flexible box layout module) - - // non CSS2 inherited - unsigned m_rtlOrdering : 1; // Order - unsigned m_printColorAdjust : PrintColorAdjustBits; - unsigned _pointerEvents : 4; // EPointerEvents - unsigned _insideLink : 2; // EInsideLink - // 43 bits + static RenderStyle clone(const RenderStyle&); + static std::unique_ptr<RenderStyle> clonePtr(const RenderStyle&); - // CSS Text Layout Module Level 3: Vertical writing support - unsigned m_writingMode : 2; // WritingMode - // 45 bits - } inherited_flags; + static RenderStyle createAnonymousStyleWithDisplay(const RenderStyle& parentStyle, EDisplay); + static RenderStyle createStyleInheritingFromPseudoStyle(const RenderStyle& pseudoStyle); -// don't inherit - struct NonInheritedFlags { - bool operator==(const NonInheritedFlags& other) const - { - return _effectiveDisplay == other._effectiveDisplay - && _originalDisplay == other._originalDisplay - && _overflowX == other._overflowX - && _overflowY == other._overflowY - && _vertical_align == other._vertical_align - && _clear == other._clear - && _position == other._position - && _floating == other._floating - && _table_layout == other._table_layout - && _page_break_before == other._page_break_before - && _page_break_after == other._page_break_after - && _page_break_inside == other._page_break_inside - && _styleType == other._styleType - && _affectedByHover == other._affectedByHover - && _affectedByActive == other._affectedByActive - && _affectedByDrag == other._affectedByDrag - && _pseudoBits == other._pseudoBits - && _unicodeBidi == other._unicodeBidi - && explicitInheritance == other.explicitInheritance - && unique == other.unique - && emptyState == other.emptyState - && firstChildState == other.firstChildState - && lastChildState == other.lastChildState - && _isLink == other._isLink; - } - - bool operator!=(const NonInheritedFlags& other) const { return !(*this == other); } - - unsigned _effectiveDisplay : 5; // EDisplay - unsigned _originalDisplay : 5; // EDisplay - unsigned _overflowX : 3; // EOverflow - unsigned _overflowY : 3; // EOverflow - unsigned _vertical_align : 4; // EVerticalAlign - unsigned _clear : 2; // EClear - unsigned _position : 3; // EPosition - unsigned _floating : 2; // EFloat - unsigned _table_layout : 1; // ETableLayout - - unsigned _unicodeBidi : 3; // EUnicodeBidi - // 31 bits - unsigned _page_break_before : 2; // EPageBreak - unsigned _page_break_after : 2; // EPageBreak - unsigned _page_break_inside : 2; // EPageBreak - - unsigned _styleType : 6; // PseudoId - unsigned _pseudoBits : 7; - unsigned explicitInheritance : 1; // Explicitly inherits a non-inherited property - unsigned unique : 1; // Style can not be shared. - unsigned emptyState : 1; - unsigned firstChildState : 1; - unsigned lastChildState : 1; - - bool affectedByHover() const { return _affectedByHover; } - void setAffectedByHover(bool value) { _affectedByHover = value; } - bool affectedByActive() const { return _affectedByActive; } - void setAffectedByActive(bool value) { _affectedByActive = value; } - bool affectedByDrag() const { return _affectedByDrag; } - void setAffectedByDrag(bool value) { _affectedByDrag = value; } - bool isLink() const { return _isLink; } - void setIsLink(bool value) { _isLink = value; } - private: - unsigned _affectedByHover : 1; - unsigned _affectedByActive : 1; - unsigned _affectedByDrag : 1; - unsigned _isLink : 1; - // If you add more style bits here, you will also need to update RenderStyle::copyNonInheritedFrom() - // 59 bits - } noninherited_flags; - -// !END SYNC! - -protected: - void setBitDefaults() - { - inherited_flags._empty_cells = initialEmptyCells(); - inherited_flags._caption_side = initialCaptionSide(); - inherited_flags._list_style_type = initialListStyleType(); - inherited_flags._list_style_position = initialListStylePosition(); - inherited_flags._visibility = initialVisibility(); - inherited_flags._text_align = initialTextAlign(); - inherited_flags._text_transform = initialTextTransform(); - inherited_flags._text_decorations = initialTextDecoration(); - inherited_flags._cursor_style = initialCursor(); -#if ENABLE(CURSOR_VISIBILITY) - inherited_flags.m_cursorVisibility = initialCursorVisibility(); +#if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS) + bool deletionHasBegun() const { return m_deletionHasBegun; } #endif - inherited_flags._direction = initialDirection(); - inherited_flags._white_space = initialWhiteSpace(); - inherited_flags._border_collapse = initialBorderCollapse(); - inherited_flags.m_rtlOrdering = initialRTLOrdering(); - inherited_flags._box_direction = initialBoxDirection(); - inherited_flags.m_printColorAdjust = initialPrintColorAdjust(); - inherited_flags._pointerEvents = initialPointerEvents(); - inherited_flags._insideLink = NotInsideLink; - inherited_flags.m_writingMode = initialWritingMode(); - - noninherited_flags._effectiveDisplay = noninherited_flags._originalDisplay = initialDisplay(); - noninherited_flags._overflowX = initialOverflowX(); - noninherited_flags._overflowY = initialOverflowY(); - noninherited_flags._vertical_align = initialVerticalAlign(); - noninherited_flags._clear = initialClear(); - noninherited_flags._position = initialPosition(); - noninherited_flags._floating = initialFloating(); - noninherited_flags._table_layout = initialTableLayout(); - noninherited_flags._unicodeBidi = initialUnicodeBidi(); - noninherited_flags._page_break_before = initialPageBreak(); - noninherited_flags._page_break_after = initialPageBreak(); - noninherited_flags._page_break_inside = initialPageBreak(); - noninherited_flags._styleType = NOPSEUDO; - noninherited_flags._pseudoBits = 0; - noninherited_flags.explicitInheritance = false; - noninherited_flags.unique = false; - noninherited_flags.emptyState = false; - noninherited_flags.firstChildState = false; - noninherited_flags.lastChildState = false; - noninherited_flags.setAffectedByHover(false); - noninherited_flags.setAffectedByActive(false); - noninherited_flags.setAffectedByDrag(false); - noninherited_flags.setIsLink(false); - } -private: - ALWAYS_INLINE RenderStyle(); - // used to create the default style. - ALWAYS_INLINE RenderStyle(bool); - ALWAYS_INLINE RenderStyle(const RenderStyle&); - -public: - static PassRef<RenderStyle> create(); - static PassRef<RenderStyle> createDefaultStyle(); - static PassRef<RenderStyle> createAnonymousStyleWithDisplay(const RenderStyle* parentStyle, EDisplay); - static PassRef<RenderStyle> clone(const RenderStyle*); - - // Create a RenderStyle for generated content by inheriting from a pseudo style. - static PassRef<RenderStyle> createStyleInheritingFromPseudoStyle(const RenderStyle& pseudoStyle); + bool operator==(const RenderStyle&) const; + bool operator!=(const RenderStyle& other) const { return !(*this == other); } - enum IsAtShadowBoundary { - AtShadowBoundary, - NotAtShadowBoundary, - }; + void inheritFrom(const RenderStyle& inheritParent); + void copyNonInheritedFrom(const RenderStyle&); - void inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary = NotAtShadowBoundary); - void copyNonInheritedFrom(const RenderStyle*); + ContentPosition resolvedJustifyContentPosition(const StyleContentAlignmentData& normalValueBehavior) const; + ContentDistributionType resolvedJustifyContentDistribution(const StyleContentAlignmentData& normalValueBehavior) const; + ContentPosition resolvedAlignContentPosition(const StyleContentAlignmentData& normalValueBehavior) const; + ContentDistributionType resolvedAlignContentDistribution(const StyleContentAlignmentData& normalValueBehavior) const; + StyleSelfAlignmentData resolvedAlignItems(ItemPosition normalValueBehaviour) const; + StyleSelfAlignmentData resolvedAlignSelf(const RenderStyle& parentStyle, ItemPosition normalValueBehaviour) const; + StyleSelfAlignmentData resolvedJustifyItems(ItemPosition normalValueBehaviour) const; + StyleSelfAlignmentData resolvedJustifySelf(const RenderStyle& parentStyle, ItemPosition normalValueBehaviour) const; - PseudoId styleType() const { return static_cast<PseudoId>(noninherited_flags._styleType); } - void setStyleType(PseudoId styleType) { noninherited_flags._styleType = styleType; } + PseudoId styleType() const { return m_nonInheritedFlags.styleType(); } + void setStyleType(PseudoId styleType) { m_nonInheritedFlags.setStyleType(styleType); } RenderStyle* getCachedPseudoStyle(PseudoId) const; - RenderStyle* addCachedPseudoStyle(PassRefPtr<RenderStyle>); + RenderStyle* addCachedPseudoStyle(std::unique_ptr<RenderStyle>); void removeCachedPseudoStyle(PseudoId); const PseudoStyleCache* cachedPseudoStyles() const { return m_cachedPseudoStyles.get(); } - bool affectedByHover() const { return noninherited_flags.affectedByHover(); } - bool affectedByActive() const { return noninherited_flags.affectedByActive(); } - bool affectedByDrag() const { return noninherited_flags.affectedByDrag(); } + const CustomPropertyValueMap& customProperties() const { return m_rareInheritedData->customProperties->values; } + void setCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value) { return m_rareInheritedData.access().customProperties.access().setCustomPropertyValue(name, WTFMove(value)); } + + void setHasViewportUnits(bool hasViewportUnits = true) { m_nonInheritedFlags.setHasViewportUnits(hasViewportUnits); } + bool hasViewportUnits() const { return m_nonInheritedFlags.hasViewportUnits(); } - void setAffectedByHover() { noninherited_flags.setAffectedByHover(true); } - void setAffectedByActive() { noninherited_flags.setAffectedByActive(true); } - void setAffectedByDrag() { noninherited_flags.setAffectedByDrag(true); } + bool affectedByHover() const { return m_nonInheritedFlags.affectedByHover(); } + bool affectedByActive() const { return m_nonInheritedFlags.affectedByActive(); } + bool affectedByDrag() const { return m_nonInheritedFlags.affectedByDrag(); } + + void setAffectedByHover() { m_nonInheritedFlags.setAffectedByHover(true); } + void setAffectedByActive() { m_nonInheritedFlags.setAffectedByActive(true); } + void setAffectedByDrag() { m_nonInheritedFlags.setAffectedByDrag(true); } void setColumnStylesFromPaginationMode(const Pagination::Mode&); - bool operator==(const RenderStyle& other) const; - bool operator!=(const RenderStyle& other) const { return !(*this == other); } - bool isFloating() const { return noninherited_flags._floating != NoFloat; } - bool hasMargin() const { return surround->margin.nonZero(); } - bool hasBorder() const { return surround->border.hasBorder(); } - bool hasPadding() const { return surround->padding.nonZero(); } - bool hasOffset() const { return surround->offset.nonZero(); } - bool hasMarginBeforeQuirk() const { return marginBefore().quirk(); } - bool hasMarginAfterQuirk() const { return marginAfter().quirk(); } - - bool hasBackgroundImage() const { return m_background->background().hasImage(); } - bool hasFixedBackgroundImage() const { return m_background->background().hasFixedImage(); } - + bool isFloating() const { return m_nonInheritedFlags.isFloating(); } + bool hasMargin() const { return !m_surroundData->margin.isZero(); } + bool hasBorder() const { return m_surroundData->border.hasBorder(); } + bool hasBorderFill() const { return m_surroundData->border.hasFill(); } + bool hasVisibleBorderDecoration() const { return hasVisibleBorder() || hasBorderFill(); } + bool hasVisibleBorder() const { return m_surroundData->border.hasVisibleBorder(); } + bool hasPadding() const { return !m_surroundData->padding.isZero(); } + bool hasOffset() const { return !m_surroundData->offset.isZero(); } + bool hasMarginBeforeQuirk() const { return marginBefore().hasQuirk(); } + bool hasMarginAfterQuirk() const { return marginAfter().hasQuirk(); } + + bool hasBackgroundImage() const { return m_backgroundData->background.hasImage(); } + bool hasFixedBackgroundImage() const { return m_backgroundData->background.hasFixedImage(); } + bool hasEntirelyFixedBackground() const; - + bool hasAppearance() const { return appearance() != NoControlPart; } - bool hasBackground() const - { - Color color = visitedDependentColor(CSSPropertyBackgroundColor); - if (color.isValid() && color.alpha()) - return true; - return hasBackgroundImage(); - } + bool hasBackground() const; LayoutBoxExtent imageOutsets(const NinePieceImage&) const; - bool hasBorderImageOutsets() const - { - return borderImage().hasImage() && borderImage().outset().nonZero(); - } - LayoutBoxExtent borderImageOutsets() const - { - return imageOutsets(borderImage()); - } + bool hasBorderImageOutsets() const { return borderImage().hasImage() && !borderImage().outset().isZero(); } + LayoutBoxExtent borderImageOutsets() const { return imageOutsets(borderImage()); } - LayoutBoxExtent maskBoxImageOutsets() const - { - return imageOutsets(maskBoxImage()); - } + LayoutBoxExtent maskBoxImageOutsets() const { return imageOutsets(maskBoxImage()); } -#if ENABLE(CSS_FILTERS) bool hasFilterOutsets() const { return hasFilter() && filter().hasOutsets(); } FilterOutsets filterOutsets() const { return hasFilter() ? filter().outsets() : FilterOutsets(); } -#endif - Order rtlOrdering() const { return static_cast<Order>(inherited_flags.m_rtlOrdering); } - void setRTLOrdering(Order o) { inherited_flags.m_rtlOrdering = o; } + Order rtlOrdering() const { return static_cast<Order>(m_inheritedFlags.rtlOrdering); } + void setRTLOrdering(Order ordering) { m_inheritedFlags.rtlOrdering = ordering; } bool isStyleAvailable() const; bool hasAnyPublicPseudoStyles() const; - bool hasPseudoStyle(PseudoId pseudo) const; - void setHasPseudoStyle(PseudoId pseudo); + bool hasPseudoStyle(PseudoId) const; + void setHasPseudoStyle(PseudoId); + void setHasPseudoStyles(PseudoIdSet); bool hasUniquePseudoStyle() const; // attribute getter methods - EDisplay display() const { return static_cast<EDisplay>(noninherited_flags._effectiveDisplay); } - EDisplay originalDisplay() const { return static_cast<EDisplay>(noninherited_flags._originalDisplay); } + EDisplay display() const { return m_nonInheritedFlags.effectiveDisplay(); } - const Length& left() const { return surround->offset.left(); } - const Length& right() const { return surround->offset.right(); } - const Length& top() const { return surround->offset.top(); } - const Length& bottom() const { return surround->offset.bottom(); } + const Length& left() const { return m_surroundData->offset.left(); } + const Length& right() const { return m_surroundData->offset.right(); } + const Length& top() const { return m_surroundData->offset.top(); } + const Length& bottom() const { return m_surroundData->offset.bottom(); } // Accessors for positioned object edges that take into account writing mode. - const Length& logicalLeft() const { return surround->offset.logicalLeft(writingMode()); } - const Length& logicalRight() const { return surround->offset.logicalRight(writingMode()); } - const Length& logicalTop() const { return surround->offset.before(writingMode()); } - const Length& logicalBottom() const { return surround->offset.after(writingMode()); } + const Length& logicalLeft() const { return m_surroundData->offset.start(writingMode()); } + const Length& logicalRight() const { return m_surroundData->offset.end(writingMode()); } + const Length& logicalTop() const { return m_surroundData->offset.before(writingMode()); } + const Length& logicalBottom() const { return m_surroundData->offset.after(writingMode()); } - // Whether or not a positioned element requires normal flow x/y to be computed - // to determine its position. - bool hasAutoLeftAndRight() const { return left().isAuto() && right().isAuto(); } - bool hasAutoTopAndBottom() const { return top().isAuto() && bottom().isAuto(); } + // Whether or not a positioned element requires normal flow x/y to be computed to determine its position. bool hasStaticInlinePosition(bool horizontal) const { return horizontal ? hasAutoLeftAndRight() : hasAutoTopAndBottom(); } bool hasStaticBlockPosition(bool horizontal) const { return horizontal ? hasAutoTopAndBottom() : hasAutoLeftAndRight(); } - EPosition position() const { return static_cast<EPosition>(noninherited_flags._position); } + EPosition position() const { return m_nonInheritedFlags.position(); } bool hasOutOfFlowPosition() const { return position() == AbsolutePosition || position() == FixedPosition; } bool hasInFlowPosition() const { return position() == RelativePosition || position() == StickyPosition; } bool hasViewportConstrainedPosition() const { return position() == FixedPosition || position() == StickyPosition; } - EFloat floating() const { return static_cast<EFloat>(noninherited_flags._floating); } - - const Length& width() const { return m_box->width(); } - const Length& height() const { return m_box->height(); } - const Length& minWidth() const { return m_box->minWidth(); } - const Length& maxWidth() const { return m_box->maxWidth(); } - const Length& minHeight() const { return m_box->minHeight(); } - const Length& maxHeight() const { return m_box->maxHeight(); } + EFloat floating() const { return m_nonInheritedFlags.floating(); } + + const Length& width() const { return m_boxData->width(); } + const Length& height() const { return m_boxData->height(); } + const Length& minWidth() const { return m_boxData->minWidth(); } + const Length& maxWidth() const { return m_boxData->maxWidth(); } + const Length& minHeight() const { return m_boxData->minHeight(); } + const Length& maxHeight() const { return m_boxData->maxHeight(); } const Length& logicalWidth() const { return isHorizontalWritingMode() ? width() : height(); } const Length& logicalHeight() const { return isHorizontalWritingMode() ? height() : width(); } @@ -480,318 +272,284 @@ public: const Length& logicalMinHeight() const { return isHorizontalWritingMode() ? minHeight() : minWidth(); } const Length& logicalMaxHeight() const { return isHorizontalWritingMode() ? maxHeight() : maxWidth(); } - const BorderData& border() const { return surround->border; } - const BorderValue& borderLeft() const { return surround->border.left(); } - const BorderValue& borderRight() const { return surround->border.right(); } - const BorderValue& borderTop() const { return surround->border.top(); } - const BorderValue& borderBottom() const { return surround->border.bottom(); } + const BorderData& border() const { return m_surroundData->border; } + const BorderValue& borderLeft() const { return m_surroundData->border.left(); } + const BorderValue& borderRight() const { return m_surroundData->border.right(); } + const BorderValue& borderTop() const { return m_surroundData->border.top(); } + const BorderValue& borderBottom() const { return m_surroundData->border.bottom(); } const BorderValue& borderBefore() const; const BorderValue& borderAfter() const; const BorderValue& borderStart() const; const BorderValue& borderEnd() const; - const NinePieceImage& borderImage() const { return surround->border.image(); } - StyleImage* borderImageSource() const { return surround->border.image().image(); } - const LengthBox& borderImageSlices() const { return surround->border.image().imageSlices(); } - const LengthBox& borderImageWidth() const { return surround->border.image().borderSlices(); } - const LengthBox& borderImageOutset() const { return surround->border.image().outset(); } - - const LengthSize& borderTopLeftRadius() const { return surround->border.topLeft(); } - const LengthSize& borderTopRightRadius() const { return surround->border.topRight(); } - const LengthSize& borderBottomLeftRadius() const { return surround->border.bottomLeft(); } - const LengthSize& borderBottomRightRadius() const { return surround->border.bottomRight(); } - bool hasBorderRadius() const { return surround->border.hasBorderRadius(); } - - unsigned borderLeftWidth() const { return surround->border.borderLeftWidth(); } - EBorderStyle borderLeftStyle() const { return surround->border.left().style(); } - bool borderLeftIsTransparent() const { return surround->border.left().isTransparent(); } - unsigned borderRightWidth() const { return surround->border.borderRightWidth(); } - EBorderStyle borderRightStyle() const { return surround->border.right().style(); } - bool borderRightIsTransparent() const { return surround->border.right().isTransparent(); } - unsigned borderTopWidth() const { return surround->border.borderTopWidth(); } - EBorderStyle borderTopStyle() const { return surround->border.top().style(); } - bool borderTopIsTransparent() const { return surround->border.top().isTransparent(); } - unsigned borderBottomWidth() const { return surround->border.borderBottomWidth(); } - EBorderStyle borderBottomStyle() const { return surround->border.bottom().style(); } - bool borderBottomIsTransparent() const { return surround->border.bottom().isTransparent(); } - - unsigned short borderBeforeWidth() const; - unsigned short borderAfterWidth() const; - unsigned short borderStartWidth() const; - unsigned short borderEndWidth() const; - - unsigned short outlineSize() const { return std::max(0, outlineWidth() + outlineOffset()); } - unsigned short outlineWidth() const - { - if (m_background->outline().style() == BNONE) - return 0; - return m_background->outline().width(); - } - bool hasOutline() const { return outlineWidth() > 0 && outlineStyle() > BHIDDEN; } - EBorderStyle outlineStyle() const { return m_background->outline().style(); } - OutlineIsAuto outlineStyleIsAuto() const { return static_cast<OutlineIsAuto>(m_background->outline().isAuto()); } + const NinePieceImage& borderImage() const { return m_surroundData->border.image(); } + StyleImage* borderImageSource() const { return m_surroundData->border.image().image(); } + const LengthBox& borderImageSlices() const { return m_surroundData->border.image().imageSlices(); } + const LengthBox& borderImageWidth() const { return m_surroundData->border.image().borderSlices(); } + const LengthBox& borderImageOutset() const { return m_surroundData->border.image().outset(); } + + const LengthSize& borderTopLeftRadius() const { return m_surroundData->border.topLeft(); } + const LengthSize& borderTopRightRadius() const { return m_surroundData->border.topRight(); } + const LengthSize& borderBottomLeftRadius() const { return m_surroundData->border.bottomLeft(); } + const LengthSize& borderBottomRightRadius() const { return m_surroundData->border.bottomRight(); } + bool hasBorderRadius() const { return m_surroundData->border.hasBorderRadius(); } + + float borderLeftWidth() const { return m_surroundData->border.borderLeftWidth(); } + EBorderStyle borderLeftStyle() const { return m_surroundData->border.left().style(); } + bool borderLeftIsTransparent() const { return m_surroundData->border.left().isTransparent(); } + float borderRightWidth() const { return m_surroundData->border.borderRightWidth(); } + EBorderStyle borderRightStyle() const { return m_surroundData->border.right().style(); } + bool borderRightIsTransparent() const { return m_surroundData->border.right().isTransparent(); } + float borderTopWidth() const { return m_surroundData->border.borderTopWidth(); } + EBorderStyle borderTopStyle() const { return m_surroundData->border.top().style(); } + bool borderTopIsTransparent() const { return m_surroundData->border.top().isTransparent(); } + float borderBottomWidth() const { return m_surroundData->border.borderBottomWidth(); } + EBorderStyle borderBottomStyle() const { return m_surroundData->border.bottom().style(); } + bool borderBottomIsTransparent() const { return m_surroundData->border.bottom().isTransparent(); } + FloatBoxExtent borderWidth() const { return m_surroundData->border.borderWidth(); } + + float borderBeforeWidth() const; + float borderAfterWidth() const; + float borderStartWidth() const; + float borderEndWidth() const; + + float outlineSize() const { return std::max<float>(0, outlineWidth() + outlineOffset()); } + float outlineWidth() const; + bool hasOutline() const { return outlineStyle() > BHIDDEN && outlineWidth() > 0; } + EBorderStyle outlineStyle() const { return m_backgroundData->outline.style(); } + OutlineIsAuto outlineStyleIsAuto() const { return static_cast<OutlineIsAuto>(m_backgroundData->outline.isAuto()); } + bool hasOutlineInVisualOverflow() const { return hasOutline() && outlineSize() > 0; } - EOverflow overflowX() const { return static_cast<EOverflow>(noninherited_flags._overflowX); } - EOverflow overflowY() const { return static_cast<EOverflow>(noninherited_flags._overflowY); } + EOverflow overflowX() const { return m_nonInheritedFlags.overflowX(); } + EOverflow overflowY() const { return m_nonInheritedFlags.overflowY(); } - EVisibility visibility() const { return static_cast<EVisibility>(inherited_flags._visibility); } - EVerticalAlign verticalAlign() const { return static_cast<EVerticalAlign>(noninherited_flags._vertical_align); } - const Length& verticalAlignLength() const { return m_box->verticalAlign(); } + EVisibility visibility() const { return static_cast<EVisibility>(m_inheritedFlags.visibility); } + EVerticalAlign verticalAlign() const { return m_nonInheritedFlags.verticalAlign(); } + const Length& verticalAlignLength() const { return m_boxData->verticalAlign(); } - const Length& clipLeft() const { return visual->clip.left(); } - const Length& clipRight() const { return visual->clip.right(); } - const Length& clipTop() const { return visual->clip.top(); } - const Length& clipBottom() const { return visual->clip.bottom(); } - const LengthBox& clip() const { return visual->clip; } - bool hasClip() const { return visual->hasClip; } + const Length& clipLeft() const { return m_visualData->clip.left(); } + const Length& clipRight() const { return m_visualData->clip.right(); } + const Length& clipTop() const { return m_visualData->clip.top(); } + const Length& clipBottom() const { return m_visualData->clip.bottom(); } + const LengthBox& clip() const { return m_visualData->clip; } + bool hasClip() const { return m_visualData->hasClip; } - EUnicodeBidi unicodeBidi() const { return static_cast<EUnicodeBidi>(noninherited_flags._unicodeBidi); } + EUnicodeBidi unicodeBidi() const { return m_nonInheritedFlags.unicodeBidi(); } - EClear clear() const { return static_cast<EClear>(noninherited_flags._clear); } - ETableLayout tableLayout() const { return static_cast<ETableLayout>(noninherited_flags._table_layout); } + EClear clear() const { return m_nonInheritedFlags.clear(); } + ETableLayout tableLayout() const { return m_nonInheritedFlags.tableLayout(); } - const Font& font() const; - const FontMetrics& fontMetrics() const; - const FontDescription& fontDescription() const; + WEBCORE_EXPORT const FontCascade& fontCascade() const; + WEBCORE_EXPORT const FontMetrics& fontMetrics() const; + WEBCORE_EXPORT const FontCascadeDescription& fontDescription() const; float specifiedFontSize() const; float computedFontSize() const; int fontSize() const; - void getFontAndGlyphOrientation(FontOrientation&, NonCJKGlyphOrientation&); + std::pair<FontOrientation, NonCJKGlyphOrientation> fontAndGlyphOrientation(); -#if ENABLE(TEXT_AUTOSIZING) - float textAutosizingMultiplier() const { return visual->m_textAutosizingMultiplier; } +#if ENABLE(VARIATION_FONTS) + FontVariationSettings fontVariationSettings() const { return fontDescription().variationSettings(); } #endif - const Length& textIndent() const { return rareInheritedData->indent; } + const Length& textIndent() const { return m_rareInheritedData->indent; } + ETextAlign textAlign() const { return static_cast<ETextAlign>(m_inheritedFlags.textAlign); } + ETextTransform textTransform() const { return static_cast<ETextTransform>(m_inheritedFlags.textTransform); } + TextDecoration textDecorationsInEffect() const { return static_cast<TextDecoration>(m_inheritedFlags.textDecorations); } + TextDecoration textDecoration() const { return static_cast<TextDecoration>(m_visualData->textDecoration); } + TextDecorationStyle textDecorationStyle() const { return static_cast<TextDecorationStyle>(m_rareNonInheritedData->textDecorationStyle); } + TextDecorationSkip textDecorationSkip() const { return static_cast<TextDecorationSkip>(m_rareInheritedData->textDecorationSkip); } + TextUnderlinePosition textUnderlinePosition() const { return static_cast<TextUnderlinePosition>(m_rareInheritedData->textUnderlinePosition); } + #if ENABLE(CSS3_TEXT) - TextIndentLine textIndentLine() const { return static_cast<TextIndentLine>(rareInheritedData->m_textIndentLine); } - TextIndentType textIndentType() const { return static_cast<TextIndentType>(rareInheritedData->m_textIndentType); } + TextIndentLine textIndentLine() const { return static_cast<TextIndentLine>(m_rareInheritedData->textIndentLine); } + TextIndentType textIndentType() const { return static_cast<TextIndentType>(m_rareInheritedData->textIndentType); } + TextAlignLast textAlignLast() const { return static_cast<TextAlignLast>(m_rareInheritedData->textAlignLast); } + TextJustify textJustify() const { return static_cast<TextJustify>(m_rareInheritedData->textJustify); } #endif - ETextAlign textAlign() const { return static_cast<ETextAlign>(inherited_flags._text_align); } - ETextTransform textTransform() const { return static_cast<ETextTransform>(inherited_flags._text_transform); } - TextDecoration textDecorationsInEffect() const { return static_cast<TextDecoration>(inherited_flags._text_decorations); } - TextDecoration textDecoration() const { return static_cast<TextDecoration>(visual->textDecoration); } -#if ENABLE(CSS3_TEXT) - TextAlignLast textAlignLast() const { return static_cast<TextAlignLast>(rareInheritedData->m_textAlignLast); } - TextJustify textJustify() const { return static_cast<TextJustify>(rareInheritedData->m_textJustify); } -#endif // CSS3_TEXT - TextDecorationStyle textDecorationStyle() const { return static_cast<TextDecorationStyle>(rareNonInheritedData->m_textDecorationStyle); } - TextDecorationSkip textDecorationSkip() const { return static_cast<TextDecorationSkip>(rareInheritedData->m_textDecorationSkip); } - TextUnderlinePosition textUnderlinePosition() const { return static_cast<TextUnderlinePosition>(rareInheritedData->m_textUnderlinePosition); } const Length& wordSpacing() const; float letterSpacing() const; - float zoom() const { return visual->m_zoom; } - float effectiveZoom() const { return rareInheritedData->m_effectiveZoom; } + float zoom() const { return m_visualData->zoom; } + float effectiveZoom() const { return m_rareInheritedData->effectiveZoom; } + + TextZoom textZoom() const { return static_cast<TextZoom>(m_rareInheritedData->textZoom); } - TextDirection direction() const { return static_cast<TextDirection>(inherited_flags._direction); } + TextDirection direction() const { return static_cast<TextDirection>(m_inheritedFlags.direction); } bool isLeftToRightDirection() const { return direction() == LTR; } + bool hasExplicitlySetDirection() const { return m_nonInheritedFlags.hasExplicitlySetDirection(); } const Length& specifiedLineHeight() const; - Length lineHeight() const; - int computedLineHeight(RenderView* = 0) const; - - EWhiteSpace whiteSpace() const { return static_cast<EWhiteSpace>(inherited_flags._white_space); } - static bool autoWrap(EWhiteSpace ws) - { - // Nowrap and pre don't automatically wrap. - return ws != NOWRAP && ws != PRE; - } - - bool autoWrap() const - { - return autoWrap(whiteSpace()); - } - - static bool preserveNewline(EWhiteSpace ws) - { - // Normal and nowrap do not preserve newlines. - return ws != NORMAL && ws != NOWRAP; - } - - bool preserveNewline() const - { - return preserveNewline(whiteSpace()); - } - - static bool collapseWhiteSpace(EWhiteSpace ws) - { - // Pre and prewrap do not collapse whitespace. - return ws != PRE && ws != PRE_WRAP; - } - - bool collapseWhiteSpace() const - { - return collapseWhiteSpace(whiteSpace()); - } - - bool isCollapsibleWhiteSpace(UChar c) const - { - switch (c) { - case ' ': - case '\t': - return collapseWhiteSpace(); - case '\n': - return !preserveNewline(); - } - return false; - } - - bool breakOnlyAfterWhiteSpace() const - { - return whiteSpace() == PRE_WRAP || lineBreak() == LineBreakAfterWhiteSpace; - } - - bool breakWords() const - { - return wordBreak() == BreakWordBreak || overflowWrap() == BreakOverflowWrap; - } - - EFillRepeat backgroundRepeatX() const { return static_cast<EFillRepeat>(m_background->background().repeatX()); } - EFillRepeat backgroundRepeatY() const { return static_cast<EFillRepeat>(m_background->background().repeatY()); } - CompositeOperator backgroundComposite() const { return static_cast<CompositeOperator>(m_background->background().composite()); } - EFillAttachment backgroundAttachment() const { return static_cast<EFillAttachment>(m_background->background().attachment()); } - EFillBox backgroundClip() const { return static_cast<EFillBox>(m_background->background().clip()); } - EFillBox backgroundOrigin() const { return static_cast<EFillBox>(m_background->background().origin()); } - const Length& backgroundXPosition() const { return m_background->background().xPosition(); } - const Length& backgroundYPosition() const { return m_background->background().yPosition(); } - EFillSizeType backgroundSizeType() const { return m_background->background().sizeType(); } - const LengthSize& backgroundSizeLength() const { return m_background->background().sizeLength(); } - FillLayer* accessBackgroundLayers() { return &(m_background.access()->m_background); } - const FillLayer* backgroundLayers() const { return &(m_background->background()); } - - StyleImage* maskImage() const { return rareNonInheritedData->m_mask.image(); } - EFillRepeat maskRepeatX() const { return static_cast<EFillRepeat>(rareNonInheritedData->m_mask.repeatX()); } - EFillRepeat maskRepeatY() const { return static_cast<EFillRepeat>(rareNonInheritedData->m_mask.repeatY()); } - CompositeOperator maskComposite() const { return static_cast<CompositeOperator>(rareNonInheritedData->m_mask.composite()); } - EFillBox maskClip() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.clip()); } - EFillBox maskOrigin() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.origin()); } - const Length& maskXPosition() const { return rareNonInheritedData->m_mask.xPosition(); } - const Length& maskYPosition() const { return rareNonInheritedData->m_mask.yPosition(); } - EFillSizeType maskSizeType() const { return rareNonInheritedData->m_mask.sizeType(); } - const LengthSize& maskSizeLength() const { return rareNonInheritedData->m_mask.sizeLength(); } - FillLayer* accessMaskLayers() { return &(rareNonInheritedData.access()->m_mask); } - const FillLayer* maskLayers() const { return &(rareNonInheritedData->m_mask); } - const NinePieceImage& maskBoxImage() const { return rareNonInheritedData->m_maskBoxImage; } - StyleImage* maskBoxImageSource() const { return rareNonInheritedData->m_maskBoxImage.image(); } - - EBorderCollapse borderCollapse() const { return static_cast<EBorderCollapse>(inherited_flags._border_collapse); } - short horizontalBorderSpacing() const; - short verticalBorderSpacing() const; - EEmptyCell emptyCells() const { return static_cast<EEmptyCell>(inherited_flags._empty_cells); } - ECaptionSide captionSide() const { return static_cast<ECaptionSide>(inherited_flags._caption_side); } - - EListStyleType listStyleType() const { return static_cast<EListStyleType>(inherited_flags._list_style_type); } + WEBCORE_EXPORT const Length& lineHeight() const; + WEBCORE_EXPORT int computedLineHeight() const; + + EWhiteSpace whiteSpace() const { return static_cast<EWhiteSpace>(m_inheritedFlags.whiteSpace); } + static bool autoWrap(EWhiteSpace); + bool autoWrap() const { return autoWrap(whiteSpace()); } + static bool preserveNewline(EWhiteSpace); + bool preserveNewline() const { return preserveNewline(whiteSpace()); } + static bool collapseWhiteSpace(EWhiteSpace); + bool collapseWhiteSpace() const { return collapseWhiteSpace(whiteSpace()); } + bool isCollapsibleWhiteSpace(UChar) const; + bool breakOnlyAfterWhiteSpace() const; + bool breakWords() const; + + EFillRepeat backgroundRepeatX() const { return static_cast<EFillRepeat>(m_backgroundData->background.repeatX()); } + EFillRepeat backgroundRepeatY() const { return static_cast<EFillRepeat>(m_backgroundData->background.repeatY()); } + CompositeOperator backgroundComposite() const { return static_cast<CompositeOperator>(m_backgroundData->background.composite()); } + EFillAttachment backgroundAttachment() const { return static_cast<EFillAttachment>(m_backgroundData->background.attachment()); } + EFillBox backgroundClip() const { return static_cast<EFillBox>(m_backgroundData->background.clip()); } + EFillBox backgroundOrigin() const { return static_cast<EFillBox>(m_backgroundData->background.origin()); } + const Length& backgroundXPosition() const { return m_backgroundData->background.xPosition(); } + const Length& backgroundYPosition() const { return m_backgroundData->background.yPosition(); } + EFillSizeType backgroundSizeType() const { return m_backgroundData->background.sizeType(); } + const LengthSize& backgroundSizeLength() const { return m_backgroundData->background.sizeLength(); } + FillLayer& ensureBackgroundLayers() { return m_backgroundData.access().background; } + const FillLayer& backgroundLayers() const { return m_backgroundData->background; } + + StyleImage* maskImage() const { return m_rareNonInheritedData->mask.image(); } + EFillRepeat maskRepeatX() const { return static_cast<EFillRepeat>(m_rareNonInheritedData->mask.repeatX()); } + EFillRepeat maskRepeatY() const { return static_cast<EFillRepeat>(m_rareNonInheritedData->mask.repeatY()); } + CompositeOperator maskComposite() const { return static_cast<CompositeOperator>(m_rareNonInheritedData->mask.composite()); } + EFillBox maskClip() const { return static_cast<EFillBox>(m_rareNonInheritedData->mask.clip()); } + EFillBox maskOrigin() const { return static_cast<EFillBox>(m_rareNonInheritedData->mask.origin()); } + const Length& maskXPosition() const { return m_rareNonInheritedData->mask.xPosition(); } + const Length& maskYPosition() const { return m_rareNonInheritedData->mask.yPosition(); } + EFillSizeType maskSizeType() const { return m_rareNonInheritedData->mask.sizeType(); } + const LengthSize& maskSizeLength() const { return m_rareNonInheritedData->mask.sizeLength(); } + FillLayer& ensureMaskLayers() { return m_rareNonInheritedData.access().mask; } + const FillLayer& maskLayers() const { return m_rareNonInheritedData->mask; } + const NinePieceImage& maskBoxImage() const { return m_rareNonInheritedData->maskBoxImage; } + StyleImage* maskBoxImageSource() const { return m_rareNonInheritedData->maskBoxImage.image(); } + + EBorderCollapse borderCollapse() const { return static_cast<EBorderCollapse>(m_inheritedFlags.borderCollapse); } + float horizontalBorderSpacing() const; + float verticalBorderSpacing() const; + EEmptyCell emptyCells() const { return static_cast<EEmptyCell>(m_inheritedFlags.emptyCells); } + ECaptionSide captionSide() const { return static_cast<ECaptionSide>(m_inheritedFlags.captionSide); } + + EListStyleType listStyleType() const { return static_cast<EListStyleType>(m_inheritedFlags.listStyleType); } StyleImage* listStyleImage() const; - EListStylePosition listStylePosition() const { return static_cast<EListStylePosition>(inherited_flags._list_style_position); } - - const Length& marginTop() const { return surround->margin.top(); } - const Length& marginBottom() const { return surround->margin.bottom(); } - const Length& marginLeft() const { return surround->margin.left(); } - const Length& marginRight() const { return surround->margin.right(); } - const Length& marginBefore() const { return surround->margin.before(writingMode()); } - const Length& marginAfter() const { return surround->margin.after(writingMode()); } - const Length& marginStart() const { return surround->margin.start(writingMode(), direction()); } - const Length& marginEnd() const { return surround->margin.end(writingMode(), direction()); } - const Length& marginStartUsing(const RenderStyle* otherStyle) const { return surround->margin.start(otherStyle->writingMode(), otherStyle->direction()); } - const Length& marginEndUsing(const RenderStyle* otherStyle) const { return surround->margin.end(otherStyle->writingMode(), otherStyle->direction()); } - const Length& marginBeforeUsing(const RenderStyle* otherStyle) const { return surround->margin.before(otherStyle->writingMode()); } - const Length& marginAfterUsing(const RenderStyle* otherStyle) const { return surround->margin.after(otherStyle->writingMode()); } - - const LengthBox& paddingBox() const { return surround->padding; } - const Length& paddingTop() const { return surround->padding.top(); } - const Length& paddingBottom() const { return surround->padding.bottom(); } - const Length& paddingLeft() const { return surround->padding.left(); } - const Length& paddingRight() const { return surround->padding.right(); } - const Length& paddingBefore() const { return surround->padding.before(writingMode()); } - const Length& paddingAfter() const { return surround->padding.after(writingMode()); } - const Length& paddingStart() const { return surround->padding.start(writingMode(), direction()); } - const Length& paddingEnd() const { return surround->padding.end(writingMode(), direction()); } - - ECursor cursor() const { return static_cast<ECursor>(inherited_flags._cursor_style); } + EListStylePosition listStylePosition() const { return static_cast<EListStylePosition>(m_inheritedFlags.listStylePosition); } + + const Length& marginTop() const { return m_surroundData->margin.top(); } + const Length& marginBottom() const { return m_surroundData->margin.bottom(); } + const Length& marginLeft() const { return m_surroundData->margin.left(); } + const Length& marginRight() const { return m_surroundData->margin.right(); } + const Length& marginBefore() const { return m_surroundData->margin.before(writingMode()); } + const Length& marginAfter() const { return m_surroundData->margin.after(writingMode()); } + const Length& marginStart() const { return m_surroundData->margin.start(writingMode(), direction()); } + const Length& marginEnd() const { return m_surroundData->margin.end(writingMode(), direction()); } + const Length& marginStartUsing(const RenderStyle* otherStyle) const { return m_surroundData->margin.start(otherStyle->writingMode(), otherStyle->direction()); } + const Length& marginEndUsing(const RenderStyle* otherStyle) const { return m_surroundData->margin.end(otherStyle->writingMode(), otherStyle->direction()); } + const Length& marginBeforeUsing(const RenderStyle* otherStyle) const { return m_surroundData->margin.before(otherStyle->writingMode()); } + const Length& marginAfterUsing(const RenderStyle* otherStyle) const { return m_surroundData->margin.after(otherStyle->writingMode()); } + + const LengthBox& paddingBox() const { return m_surroundData->padding; } + const Length& paddingTop() const { return m_surroundData->padding.top(); } + const Length& paddingBottom() const { return m_surroundData->padding.bottom(); } + const Length& paddingLeft() const { return m_surroundData->padding.left(); } + const Length& paddingRight() const { return m_surroundData->padding.right(); } + const Length& paddingBefore() const { return m_surroundData->padding.before(writingMode()); } + const Length& paddingAfter() const { return m_surroundData->padding.after(writingMode()); } + const Length& paddingStart() const { return m_surroundData->padding.start(writingMode(), direction()); } + const Length& paddingEnd() const { return m_surroundData->padding.end(writingMode(), direction()); } + + ECursor cursor() const { return static_cast<ECursor>(m_inheritedFlags.cursor); } + #if ENABLE(CURSOR_VISIBILITY) - CursorVisibility cursorVisibility() const { return static_cast<CursorVisibility>(inherited_flags.m_cursorVisibility); } + CursorVisibility cursorVisibility() const { return static_cast<CursorVisibility>(m_inheritedFlags.cursorVisibility); } #endif - CursorList* cursors() const { return rareInheritedData->cursorData.get(); } + CursorList* cursors() const { return m_rareInheritedData->cursorData.get(); } - EInsideLink insideLink() const { return static_cast<EInsideLink>(inherited_flags._insideLink); } - bool isLink() const { return noninherited_flags.isLink(); } + EInsideLink insideLink() const { return static_cast<EInsideLink>(m_inheritedFlags.insideLink); } + bool isLink() const { return m_nonInheritedFlags.isLink(); } - short widows() const { return rareInheritedData->widows; } - short orphans() const { return rareInheritedData->orphans; } - bool hasAutoWidows() const { return rareInheritedData->m_hasAutoWidows; } - bool hasAutoOrphans() const { return rareInheritedData->m_hasAutoOrphans; } - EPageBreak pageBreakInside() const { return static_cast<EPageBreak>(noninherited_flags._page_break_inside); } - EPageBreak pageBreakBefore() const { return static_cast<EPageBreak>(noninherited_flags._page_break_before); } - EPageBreak pageBreakAfter() const { return static_cast<EPageBreak>(noninherited_flags._page_break_after); } + bool insideDefaultButton() const { return m_inheritedFlags.insideDefaultButton; } - // CSS3 Getter Methods + short widows() const { return m_rareInheritedData->widows; } + short orphans() const { return m_rareInheritedData->orphans; } + bool hasAutoWidows() const { return m_rareInheritedData->hasAutoWidows; } + bool hasAutoOrphans() const { return m_rareInheritedData->hasAutoOrphans; } - int outlineOffset() const - { - if (m_background->outline().style() == BNONE) - return 0; - return m_background->outline().offset(); - } + BreakInside breakInside() const { return static_cast<BreakInside>(m_rareNonInheritedData->breakInside); } + BreakBetween breakBefore() const { return static_cast<BreakBetween>(m_rareNonInheritedData->breakBefore); } + BreakBetween breakAfter() const { return static_cast<BreakBetween>(m_rareNonInheritedData->breakAfter); } - const ShadowData* textShadow() const { return rareInheritedData->textShadow.get(); } - void getTextShadowExtent(LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left) const { getShadowExtent(textShadow(), top, right, bottom, left); } - void getTextShadowHorizontalExtent(LayoutUnit& left, LayoutUnit& right) const { getShadowHorizontalExtent(textShadow(), left, right); } - void getTextShadowVerticalExtent(LayoutUnit& top, LayoutUnit& bottom) const { getShadowVerticalExtent(textShadow(), top, bottom); } + HangingPunctuation hangingPunctuation() const { return static_cast<HangingPunctuation>(m_rareInheritedData->hangingPunctuation); } + + float outlineOffset() const; + const ShadowData* textShadow() const { return m_rareInheritedData->textShadow.get(); } void getTextShadowInlineDirectionExtent(LayoutUnit& logicalLeft, LayoutUnit& logicalRight) const { getShadowInlineDirectionExtent(textShadow(), logicalLeft, logicalRight); } void getTextShadowBlockDirectionExtent(LayoutUnit& logicalTop, LayoutUnit& logicalBottom) const { getShadowBlockDirectionExtent(textShadow(), logicalTop, logicalBottom); } - float textStrokeWidth() const { return rareInheritedData->textStrokeWidth; } - ColorSpace colorSpace() const { return static_cast<ColorSpace>(rareInheritedData->colorSpace); } - float opacity() const { return rareNonInheritedData->opacity; } - ControlPart appearance() const { return static_cast<ControlPart>(rareNonInheritedData->m_appearance); } - // aspect ratio convenience method - bool hasAspectRatio() const { return rareNonInheritedData->m_hasAspectRatio; } - float aspectRatio() const { return aspectRatioNumerator() / aspectRatioDenominator(); } - float aspectRatioDenominator() const { return rareNonInheritedData->m_aspectRatioDenominator; } - float aspectRatioNumerator() const { return rareNonInheritedData->m_aspectRatioNumerator; } - EBoxAlignment boxAlign() const { return static_cast<EBoxAlignment>(rareNonInheritedData->m_deprecatedFlexibleBox->align); } - EBoxDirection boxDirection() const { return static_cast<EBoxDirection>(inherited_flags._box_direction); } - float boxFlex() const { return rareNonInheritedData->m_deprecatedFlexibleBox->flex; } - unsigned int boxFlexGroup() const { return rareNonInheritedData->m_deprecatedFlexibleBox->flex_group; } - EBoxLines boxLines() const { return static_cast<EBoxLines>(rareNonInheritedData->m_deprecatedFlexibleBox->lines); } - unsigned int boxOrdinalGroup() const { return rareNonInheritedData->m_deprecatedFlexibleBox->ordinal_group; } - EBoxOrient boxOrient() const { return static_cast<EBoxOrient>(rareNonInheritedData->m_deprecatedFlexibleBox->orient); } - EBoxPack boxPack() const { return static_cast<EBoxPack>(rareNonInheritedData->m_deprecatedFlexibleBox->pack); } - - int order() const { return rareNonInheritedData->m_order; } - float flexGrow() const { return rareNonInheritedData->m_flexibleBox->m_flexGrow; } - float flexShrink() const { return rareNonInheritedData->m_flexibleBox->m_flexShrink; } - const Length& flexBasis() const { return rareNonInheritedData->m_flexibleBox->m_flexBasis; } - EAlignContent alignContent() const { return static_cast<EAlignContent>(rareNonInheritedData->m_alignContent); } - EAlignItems alignItems() const { return static_cast<EAlignItems>(rareNonInheritedData->m_alignItems); } - EAlignItems alignSelf() const { return static_cast<EAlignItems>(rareNonInheritedData->m_alignSelf); } - EFlexDirection flexDirection() const { return static_cast<EFlexDirection>(rareNonInheritedData->m_flexibleBox->m_flexDirection); } + float textStrokeWidth() const { return m_rareInheritedData->textStrokeWidth; } + float opacity() const { return m_rareNonInheritedData->opacity; } + ControlPart appearance() const { return static_cast<ControlPart>(m_rareNonInheritedData->appearance); } + AspectRatioType aspectRatioType() const { return static_cast<AspectRatioType>(m_rareNonInheritedData->aspectRatioType); } + float aspectRatioDenominator() const { return m_rareNonInheritedData->aspectRatioDenominator; } + float aspectRatioNumerator() const { return m_rareNonInheritedData->aspectRatioNumerator; } + EBoxAlignment boxAlign() const { return static_cast<EBoxAlignment>(m_rareNonInheritedData->deprecatedFlexibleBox->align); } + EBoxDirection boxDirection() const { return static_cast<EBoxDirection>(m_inheritedFlags.boxDirection); } + float boxFlex() const { return m_rareNonInheritedData->deprecatedFlexibleBox->flex; } + unsigned boxFlexGroup() const { return m_rareNonInheritedData->deprecatedFlexibleBox->flexGroup; } + EBoxLines boxLines() const { return static_cast<EBoxLines>(m_rareNonInheritedData->deprecatedFlexibleBox->lines); } + unsigned boxOrdinalGroup() const { return m_rareNonInheritedData->deprecatedFlexibleBox->ordinalGroup; } + EBoxOrient boxOrient() const { return static_cast<EBoxOrient>(m_rareNonInheritedData->deprecatedFlexibleBox->orient); } + EBoxPack boxPack() const { return static_cast<EBoxPack>(m_rareNonInheritedData->deprecatedFlexibleBox->pack); } + + int order() const { return m_rareNonInheritedData->order; } + float flexGrow() const { return m_rareNonInheritedData->flexibleBox->flexGrow; } + float flexShrink() const { return m_rareNonInheritedData->flexibleBox->flexShrink; } + const Length& flexBasis() const { return m_rareNonInheritedData->flexibleBox->flexBasis; } + const StyleContentAlignmentData& alignContent() const { return m_rareNonInheritedData->alignContent; } + const StyleSelfAlignmentData& alignItems() const { return m_rareNonInheritedData->alignItems; } + const StyleSelfAlignmentData& alignSelf() const { return m_rareNonInheritedData->alignSelf; } + EFlexDirection flexDirection() const { return static_cast<EFlexDirection>(m_rareNonInheritedData->flexibleBox->flexDirection); } bool isColumnFlexDirection() const { return flexDirection() == FlowColumn || flexDirection() == FlowColumnReverse; } bool isReverseFlexDirection() const { return flexDirection() == FlowRowReverse || flexDirection() == FlowColumnReverse; } - EFlexWrap flexWrap() const { return static_cast<EFlexWrap>(rareNonInheritedData->m_flexibleBox->m_flexWrap); } - EJustifyContent justifyContent() const { return static_cast<EJustifyContent>(rareNonInheritedData->m_justifyContent); } - - const Vector<GridTrackSize>& gridColumns() const { return rareNonInheritedData->m_grid->m_gridColumns; } - const Vector<GridTrackSize>& gridRows() const { return rareNonInheritedData->m_grid->m_gridRows; } - const NamedGridLinesMap& namedGridColumnLines() const { return rareNonInheritedData->m_grid->m_namedGridColumnLines; } - const NamedGridLinesMap& namedGridRowLines() const { return rareNonInheritedData->m_grid->m_namedGridRowLines; } - const NamedGridAreaMap& namedGridArea() const { return rareNonInheritedData->m_grid->m_namedGridArea; } - size_t namedGridAreaRowCount() const { return rareNonInheritedData->m_grid->m_namedGridAreaRowCount; } - size_t namedGridAreaColumnCount() const { return rareNonInheritedData->m_grid->m_namedGridAreaColumnCount; } - GridAutoFlow gridAutoFlow() const { return rareNonInheritedData->m_grid->m_gridAutoFlow; } - const GridTrackSize& gridAutoColumns() const { return rareNonInheritedData->m_grid->m_gridAutoColumns; } - const GridTrackSize& gridAutoRows() const { return rareNonInheritedData->m_grid->m_gridAutoRows; } - - const GridPosition& gridItemColumnStart() const { return rareNonInheritedData->m_gridItem->m_gridColumnStart; } - const GridPosition& gridItemColumnEnd() const { return rareNonInheritedData->m_gridItem->m_gridColumnEnd; } - const GridPosition& gridItemRowStart() const { return rareNonInheritedData->m_gridItem->m_gridRowStart; } - const GridPosition& gridItemRowEnd() const { return rareNonInheritedData->m_gridItem->m_gridRowEnd; } - - const ShadowData* boxShadow() const { return rareNonInheritedData->m_boxShadow.get(); } + EFlexWrap flexWrap() const { return static_cast<EFlexWrap>(m_rareNonInheritedData->flexibleBox->flexWrap); } + const StyleContentAlignmentData& justifyContent() const { return m_rareNonInheritedData->justifyContent; } + const StyleSelfAlignmentData& justifyItems() const { return m_rareNonInheritedData->justifyItems; } + const StyleSelfAlignmentData& justifySelf() const { return m_rareNonInheritedData->justifySelf; } + + const Vector<GridTrackSize>& gridColumns() const { return m_rareNonInheritedData->grid->gridColumns; } + const Vector<GridTrackSize>& gridRows() const { return m_rareNonInheritedData->grid->gridRows; } + const Vector<GridTrackSize>& gridAutoRepeatColumns() const { return m_rareNonInheritedData->grid->gridAutoRepeatColumns; } + const Vector<GridTrackSize>& gridAutoRepeatRows() const { return m_rareNonInheritedData->grid->gridAutoRepeatRows; } + unsigned gridAutoRepeatColumnsInsertionPoint() const { return m_rareNonInheritedData->grid->autoRepeatColumnsInsertionPoint; } + unsigned gridAutoRepeatRowsInsertionPoint() const { return m_rareNonInheritedData->grid->autoRepeatRowsInsertionPoint; } + AutoRepeatType gridAutoRepeatColumnsType() const { return m_rareNonInheritedData->grid->autoRepeatColumnsType; } + AutoRepeatType gridAutoRepeatRowsType() const { return m_rareNonInheritedData->grid->autoRepeatRowsType; } + const NamedGridLinesMap& namedGridColumnLines() const { return m_rareNonInheritedData->grid->namedGridColumnLines; } + const NamedGridLinesMap& namedGridRowLines() const { return m_rareNonInheritedData->grid->namedGridRowLines; } + const OrderedNamedGridLinesMap& orderedNamedGridColumnLines() const { return m_rareNonInheritedData->grid->orderedNamedGridColumnLines; } + const OrderedNamedGridLinesMap& orderedNamedGridRowLines() const { return m_rareNonInheritedData->grid->orderedNamedGridRowLines; } + const NamedGridLinesMap& autoRepeatNamedGridColumnLines() const { return m_rareNonInheritedData->grid->autoRepeatNamedGridColumnLines; } + const NamedGridLinesMap& autoRepeatNamedGridRowLines() const { return m_rareNonInheritedData->grid->autoRepeatNamedGridRowLines; } + const OrderedNamedGridLinesMap& autoRepeatOrderedNamedGridColumnLines() const { return m_rareNonInheritedData->grid->autoRepeatOrderedNamedGridColumnLines; } + const OrderedNamedGridLinesMap& autoRepeatOrderedNamedGridRowLines() const { return m_rareNonInheritedData->grid->autoRepeatOrderedNamedGridRowLines; } + const NamedGridAreaMap& namedGridArea() const { return m_rareNonInheritedData->grid->namedGridArea; } + size_t namedGridAreaRowCount() const { return m_rareNonInheritedData->grid->namedGridAreaRowCount; } + size_t namedGridAreaColumnCount() const { return m_rareNonInheritedData->grid->namedGridAreaColumnCount; } + GridAutoFlow gridAutoFlow() const { return static_cast<GridAutoFlow>(m_rareNonInheritedData->grid->gridAutoFlow); } + bool isGridAutoFlowDirectionRow() const { return (m_rareNonInheritedData->grid->gridAutoFlow & InternalAutoFlowDirectionRow); } + bool isGridAutoFlowDirectionColumn() const { return (m_rareNonInheritedData->grid->gridAutoFlow & InternalAutoFlowDirectionColumn); } + bool isGridAutoFlowAlgorithmSparse() const { return (m_rareNonInheritedData->grid->gridAutoFlow & InternalAutoFlowAlgorithmSparse); } + bool isGridAutoFlowAlgorithmDense() const { return (m_rareNonInheritedData->grid->gridAutoFlow & InternalAutoFlowAlgorithmDense); } + const Vector<GridTrackSize>& gridAutoColumns() const { return m_rareNonInheritedData->grid->gridAutoColumns; } + const Vector<GridTrackSize>& gridAutoRows() const { return m_rareNonInheritedData->grid->gridAutoRows; } + const Length& gridColumnGap() const { return m_rareNonInheritedData->grid->gridColumnGap; } + const Length& gridRowGap() const { return m_rareNonInheritedData->grid->gridRowGap; } + + const GridPosition& gridItemColumnStart() const { return m_rareNonInheritedData->gridItem->gridColumnStart; } + const GridPosition& gridItemColumnEnd() const { return m_rareNonInheritedData->gridItem->gridColumnEnd; } + const GridPosition& gridItemRowStart() const { return m_rareNonInheritedData->gridItem->gridRowStart; } + const GridPosition& gridItemRowEnd() const { return m_rareNonInheritedData->gridItem->gridRowEnd; } + + const ShadowData* boxShadow() const { return m_rareNonInheritedData->boxShadow.get(); } void getBoxShadowExtent(LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left) const { getShadowExtent(boxShadow(), top, right, bottom, left); } LayoutBoxExtent getBoxShadowInsetExtent() const { return getShadowInsetExtent(boxShadow()); } void getBoxShadowHorizontalExtent(LayoutUnit& left, LayoutUnit& right) const { getShadowHorizontalExtent(boxShadow(), left, right); } @@ -800,686 +558,739 @@ public: void getBoxShadowBlockDirectionExtent(LayoutUnit& logicalTop, LayoutUnit& logicalBottom) const { getShadowBlockDirectionExtent(boxShadow(), logicalTop, logicalBottom); } #if ENABLE(CSS_BOX_DECORATION_BREAK) - EBoxDecorationBreak boxDecorationBreak() const { return m_box->boxDecorationBreak(); } + EBoxDecorationBreak boxDecorationBreak() const { return m_boxData->boxDecorationBreak(); } #endif - StyleReflection* boxReflect() const { return rareNonInheritedData->m_boxReflect.get(); } - EBoxSizing boxSizing() const { return m_box->boxSizing(); } - const Length& marqueeIncrement() const { return rareNonInheritedData->m_marquee->increment; } - int marqueeSpeed() const { return rareNonInheritedData->m_marquee->speed; } - int marqueeLoopCount() const { return rareNonInheritedData->m_marquee->loops; } - EMarqueeBehavior marqueeBehavior() const { return static_cast<EMarqueeBehavior>(rareNonInheritedData->m_marquee->behavior); } - EMarqueeDirection marqueeDirection() const { return static_cast<EMarqueeDirection>(rareNonInheritedData->m_marquee->direction); } - EUserModify userModify() const { return static_cast<EUserModify>(rareInheritedData->userModify); } - EUserDrag userDrag() const { return static_cast<EUserDrag>(rareNonInheritedData->userDrag); } - EUserSelect userSelect() const { return static_cast<EUserSelect>(rareInheritedData->userSelect); } - TextOverflow textOverflow() const { return static_cast<TextOverflow>(rareNonInheritedData->textOverflow); } - EMarginCollapse marginBeforeCollapse() const { return static_cast<EMarginCollapse>(rareNonInheritedData->marginBeforeCollapse); } - EMarginCollapse marginAfterCollapse() const { return static_cast<EMarginCollapse>(rareNonInheritedData->marginAfterCollapse); } - EWordBreak wordBreak() const { return static_cast<EWordBreak>(rareInheritedData->wordBreak); } - EOverflowWrap overflowWrap() const { return static_cast<EOverflowWrap>(rareInheritedData->overflowWrap); } - ENBSPMode nbspMode() const { return static_cast<ENBSPMode>(rareInheritedData->nbspMode); } - LineBreak lineBreak() const { return static_cast<LineBreak>(rareInheritedData->lineBreak); } - const AtomicString& highlight() const { return rareInheritedData->highlight; } - Hyphens hyphens() const { return static_cast<Hyphens>(rareInheritedData->hyphens); } - short hyphenationLimitBefore() const { return rareInheritedData->hyphenationLimitBefore; } - short hyphenationLimitAfter() const { return rareInheritedData->hyphenationLimitAfter; } - short hyphenationLimitLines() const { return rareInheritedData->hyphenationLimitLines; } - const AtomicString& hyphenationString() const { return rareInheritedData->hyphenationString; } - const AtomicString& locale() const { return rareInheritedData->locale; } - EBorderFit borderFit() const { return static_cast<EBorderFit>(rareNonInheritedData->m_borderFit); } - EResize resize() const { return static_cast<EResize>(rareInheritedData->resize); } - ColumnAxis columnAxis() const { return static_cast<ColumnAxis>(rareNonInheritedData->m_multiCol->m_axis); } - bool hasInlineColumnAxis() const { - ColumnAxis axis = columnAxis(); - return axis == AutoColumnAxis || isHorizontalWritingMode() == (axis == HorizontalColumnAxis); - } - ColumnProgression columnProgression() const { return static_cast<ColumnProgression>(rareNonInheritedData->m_multiCol->m_progression); } - float columnWidth() const { return rareNonInheritedData->m_multiCol->m_width; } - bool hasAutoColumnWidth() const { return rareNonInheritedData->m_multiCol->m_autoWidth; } - unsigned short columnCount() const { return rareNonInheritedData->m_multiCol->m_count; } - bool hasAutoColumnCount() const { return rareNonInheritedData->m_multiCol->m_autoCount; } + + StyleReflection* boxReflect() const { return m_rareNonInheritedData->boxReflect.get(); } + EBoxSizing boxSizing() const { return m_boxData->boxSizing(); } + const Length& marqueeIncrement() const { return m_rareNonInheritedData->marquee->increment; } + int marqueeSpeed() const { return m_rareNonInheritedData->marquee->speed; } + int marqueeLoopCount() const { return m_rareNonInheritedData->marquee->loops; } + EMarqueeBehavior marqueeBehavior() const { return static_cast<EMarqueeBehavior>(m_rareNonInheritedData->marquee->behavior); } + EMarqueeDirection marqueeDirection() const { return static_cast<EMarqueeDirection>(m_rareNonInheritedData->marquee->direction); } + EUserModify userModify() const { return static_cast<EUserModify>(m_rareInheritedData->userModify); } + EUserDrag userDrag() const { return static_cast<EUserDrag>(m_rareNonInheritedData->userDrag); } + EUserSelect userSelect() const { return static_cast<EUserSelect>(m_rareInheritedData->userSelect); } + TextOverflow textOverflow() const { return static_cast<TextOverflow>(m_rareNonInheritedData->textOverflow); } + EMarginCollapse marginBeforeCollapse() const { return static_cast<EMarginCollapse>(m_rareNonInheritedData->marginBeforeCollapse); } + EMarginCollapse marginAfterCollapse() const { return static_cast<EMarginCollapse>(m_rareNonInheritedData->marginAfterCollapse); } + EWordBreak wordBreak() const { return static_cast<EWordBreak>(m_rareInheritedData->wordBreak); } + EOverflowWrap overflowWrap() const { return static_cast<EOverflowWrap>(m_rareInheritedData->overflowWrap); } + ENBSPMode nbspMode() const { return static_cast<ENBSPMode>(m_rareInheritedData->nbspMode); } + LineBreak lineBreak() const { return static_cast<LineBreak>(m_rareInheritedData->lineBreak); } + Hyphens hyphens() const { return static_cast<Hyphens>(m_rareInheritedData->hyphens); } + short hyphenationLimitBefore() const { return m_rareInheritedData->hyphenationLimitBefore; } + short hyphenationLimitAfter() const { return m_rareInheritedData->hyphenationLimitAfter; } + short hyphenationLimitLines() const { return m_rareInheritedData->hyphenationLimitLines; } + const AtomicString& hyphenationString() const { return m_rareInheritedData->hyphenationString; } + const AtomicString& locale() const { return fontDescription().locale(); } + EBorderFit borderFit() const { return static_cast<EBorderFit>(m_rareNonInheritedData->borderFit); } + EResize resize() const { return static_cast<EResize>(m_rareNonInheritedData->resize); } + ColumnAxis columnAxis() const { return static_cast<ColumnAxis>(m_rareNonInheritedData->multiCol->axis); } + bool hasInlineColumnAxis() const; + ColumnProgression columnProgression() const { return static_cast<ColumnProgression>(m_rareNonInheritedData->multiCol->progression); } + float columnWidth() const { return m_rareNonInheritedData->multiCol->width; } + bool hasAutoColumnWidth() const { return m_rareNonInheritedData->multiCol->autoWidth; } + unsigned short columnCount() const { return m_rareNonInheritedData->multiCol->count; } + bool hasAutoColumnCount() const { return m_rareNonInheritedData->multiCol->autoCount; } bool specifiesColumns() const { return !hasAutoColumnCount() || !hasAutoColumnWidth() || !hasInlineColumnAxis(); } - ColumnFill columnFill() const { return static_cast<ColumnFill>(rareNonInheritedData->m_multiCol->m_fill); } - float columnGap() const { return rareNonInheritedData->m_multiCol->m_gap; } - bool hasNormalColumnGap() const { return rareNonInheritedData->m_multiCol->m_normalGap; } - EBorderStyle columnRuleStyle() const { return rareNonInheritedData->m_multiCol->m_rule.style(); } - unsigned short columnRuleWidth() const { return rareNonInheritedData->m_multiCol->ruleWidth(); } - bool columnRuleIsTransparent() const { return rareNonInheritedData->m_multiCol->m_rule.isTransparent(); } - ColumnSpan columnSpan() const { return static_cast<ColumnSpan>(rareNonInheritedData->m_multiCol->m_columnSpan); } - EPageBreak columnBreakBefore() const { return static_cast<EPageBreak>(rareNonInheritedData->m_multiCol->m_breakBefore); } - EPageBreak columnBreakInside() const { return static_cast<EPageBreak>(rareNonInheritedData->m_multiCol->m_breakInside); } - EPageBreak columnBreakAfter() const { return static_cast<EPageBreak>(rareNonInheritedData->m_multiCol->m_breakAfter); } - EPageBreak regionBreakBefore() const { return static_cast<EPageBreak>(rareNonInheritedData->m_regionBreakBefore); } - EPageBreak regionBreakInside() const { return static_cast<EPageBreak>(rareNonInheritedData->m_regionBreakInside); } - EPageBreak regionBreakAfter() const { return static_cast<EPageBreak>(rareNonInheritedData->m_regionBreakAfter); } - const TransformOperations& transform() const { return rareNonInheritedData->m_transform->m_operations; } - const Length& transformOriginX() const { return rareNonInheritedData->m_transform->m_x; } - const Length& transformOriginY() const { return rareNonInheritedData->m_transform->m_y; } - float transformOriginZ() const { return rareNonInheritedData->m_transform->m_z; } - bool hasTransform() const { return !rareNonInheritedData->m_transform->m_operations.operations().isEmpty(); } - - TextEmphasisFill textEmphasisFill() const { return static_cast<TextEmphasisFill>(rareInheritedData->textEmphasisFill); } + ColumnFill columnFill() const { return static_cast<ColumnFill>(m_rareNonInheritedData->multiCol->fill); } + float columnGap() const { return m_rareNonInheritedData->multiCol->gap; } + bool hasNormalColumnGap() const { return m_rareNonInheritedData->multiCol->normalGap; } + EBorderStyle columnRuleStyle() const { return m_rareNonInheritedData->multiCol->rule.style(); } + unsigned short columnRuleWidth() const { return m_rareNonInheritedData->multiCol->ruleWidth(); } + bool columnRuleIsTransparent() const { return m_rareNonInheritedData->multiCol->rule.isTransparent(); } + ColumnSpan columnSpan() const { return static_cast<ColumnSpan>(m_rareNonInheritedData->multiCol->columnSpan); } + + const TransformOperations& transform() const { return m_rareNonInheritedData->transform->operations; } + const Length& transformOriginX() const { return m_rareNonInheritedData->transform->x; } + const Length& transformOriginY() const { return m_rareNonInheritedData->transform->y; } + float transformOriginZ() const { return m_rareNonInheritedData->transform->z; } + bool hasTransform() const { return !m_rareNonInheritedData->transform->operations.operations().isEmpty(); } + + TextEmphasisFill textEmphasisFill() const { return static_cast<TextEmphasisFill>(m_rareInheritedData->textEmphasisFill); } TextEmphasisMark textEmphasisMark() const; - const AtomicString& textEmphasisCustomMark() const { return rareInheritedData->textEmphasisCustomMark; } - TextEmphasisPosition textEmphasisPosition() const { return static_cast<TextEmphasisPosition>(rareInheritedData->textEmphasisPosition); } + const AtomicString& textEmphasisCustomMark() const { return m_rareInheritedData->textEmphasisCustomMark; } + TextEmphasisPosition textEmphasisPosition() const { return static_cast<TextEmphasisPosition>(m_rareInheritedData->textEmphasisPosition); } const AtomicString& textEmphasisMarkString() const; - RubyPosition rubyPosition() const { return static_cast<RubyPosition>(rareInheritedData->m_rubyPosition); } + RubyPosition rubyPosition() const { return static_cast<RubyPosition>(m_rareInheritedData->rubyPosition); } - TextOrientation textOrientation() const { return static_cast<TextOrientation>(rareInheritedData->m_textOrientation); } + TextOrientation textOrientation() const { return static_cast<TextOrientation>(m_rareInheritedData->textOrientation); } - ObjectFit objectFit() const { return static_cast<ObjectFit>(rareNonInheritedData->m_objectFit); } - - // Return true if any transform related property (currently transform, transformStyle3D or perspective) - // indicates that we are transforming + ObjectFit objectFit() const { return static_cast<ObjectFit>(m_rareNonInheritedData->objectFit); } + LengthPoint objectPosition() const { return m_rareNonInheritedData->objectPosition; } + + // Return true if any transform related property (currently transform, transformStyle3D or perspective) + // indicates that we are transforming. bool hasTransformRelatedProperty() const { return hasTransform() || preserves3D() || hasPerspective(); } enum ApplyTransformOrigin { IncludeTransformOrigin, ExcludeTransformOrigin }; - void applyTransform(TransformationMatrix&, const LayoutSize& borderBoxSize, ApplyTransformOrigin = IncludeTransformOrigin) const; void applyTransform(TransformationMatrix&, const FloatRect& boundingBox, ApplyTransformOrigin = IncludeTransformOrigin) const; void setPageScaleTransform(float); - bool hasMask() const { return rareNonInheritedData->m_mask.hasImage() || rareNonInheritedData->m_maskBoxImage.hasImage(); } + bool hasMask() const { return m_rareNonInheritedData->mask.hasImage() || m_rareNonInheritedData->maskBoxImage.hasImage(); } - TextCombine textCombine() const { return static_cast<TextCombine>(rareNonInheritedData->m_textCombine); } + TextCombine textCombine() const { return static_cast<TextCombine>(m_rareNonInheritedData->textCombine); } bool hasTextCombine() const { return textCombine() != TextCombineNone; } - unsigned tabSize() const { return rareInheritedData->m_tabSize; } + unsigned tabSize() const { return m_rareInheritedData->tabSize; } // End CSS3 Getters - const AtomicString& flowThread() const { return rareNonInheritedData->m_flowThread; } - bool hasFlowFrom() const { return !rareNonInheritedData->m_regionThread.isNull(); } - const AtomicString& regionThread() const { return rareNonInheritedData->m_regionThread; } - RegionFragment regionFragment() const { return static_cast<RegionFragment>(rareNonInheritedData->m_regionFragment); } + bool hasFlowInto() const { return !m_rareNonInheritedData->flowThread.isNull(); } + const AtomicString& flowThread() const { return m_rareNonInheritedData->flowThread; } + bool hasFlowFrom() const { return !m_rareNonInheritedData->regionThread.isNull(); } + const AtomicString& regionThread() const { return m_rareNonInheritedData->regionThread; } + RegionFragment regionFragment() const { return static_cast<RegionFragment>(m_rareNonInheritedData->regionFragment); } - const AtomicString& lineGrid() const { return rareInheritedData->m_lineGrid; } - LineSnap lineSnap() const { return static_cast<LineSnap>(rareInheritedData->m_lineSnap); } - LineAlign lineAlign() const { return static_cast<LineAlign>(rareInheritedData->m_lineAlign); } + const AtomicString& lineGrid() const { return m_rareInheritedData->lineGrid; } + LineSnap lineSnap() const { return static_cast<LineSnap>(m_rareInheritedData->lineSnap); } + LineAlign lineAlign() const { return static_cast<LineAlign>(m_rareInheritedData->lineAlign); } - WrapFlow wrapFlow() const { return static_cast<WrapFlow>(rareNonInheritedData->m_wrapFlow); } - WrapThrough wrapThrough() const { return static_cast<WrapThrough>(rareNonInheritedData->m_wrapThrough); } + EPointerEvents pointerEvents() const { return static_cast<EPointerEvents>(m_inheritedFlags.pointerEvents); } + const AnimationList* animations() const { return m_rareNonInheritedData->animations.get(); } + const AnimationList* transitions() const { return m_rareNonInheritedData->transitions.get(); } - // Apple-specific property getter methods - EPointerEvents pointerEvents() const { return static_cast<EPointerEvents>(inherited_flags._pointerEvents); } - const AnimationList* animations() const { return rareNonInheritedData->m_animations.get(); } - const AnimationList* transitions() const { return rareNonInheritedData->m_transitions.get(); } + AnimationList* animations() { return m_rareNonInheritedData->animations.get(); } + AnimationList* transitions() { return m_rareNonInheritedData->transitions.get(); } + + bool hasAnimationsOrTransitions() const { return m_rareNonInheritedData->hasAnimationsOrTransitions(); } - AnimationList* accessAnimations(); - AnimationList* accessTransitions(); + AnimationList& ensureAnimations(); + AnimationList& ensureTransitions(); - bool hasAnimations() const { return rareNonInheritedData->m_animations && rareNonInheritedData->m_animations->size() > 0; } - bool hasTransitions() const { return rareNonInheritedData->m_transitions && rareNonInheritedData->m_transitions->size() > 0; } + bool hasAnimations() const { return m_rareNonInheritedData->animations && m_rareNonInheritedData->animations->size() > 0; } + bool hasTransitions() const { return m_rareNonInheritedData->transitions && m_rareNonInheritedData->transitions->size() > 0; } - // return the first found Animation (including 'all' transitions) + // Return the first found Animation (including 'all' transitions). const Animation* transitionForProperty(CSSPropertyID) const; - ETransformStyle3D transformStyle3D() const { return static_cast<ETransformStyle3D>(rareNonInheritedData->m_transformStyle3D); } - bool preserves3D() const { return rareNonInheritedData->m_transformStyle3D == TransformStyle3DPreserve3D; } + ETransformStyle3D transformStyle3D() const { return static_cast<ETransformStyle3D>(m_rareNonInheritedData->transformStyle3D); } + bool preserves3D() const { return m_rareNonInheritedData->transformStyle3D == TransformStyle3DPreserve3D; } - EBackfaceVisibility backfaceVisibility() const { return static_cast<EBackfaceVisibility>(rareNonInheritedData->m_backfaceVisibility); } - float perspective() const { return rareNonInheritedData->m_perspective; } - bool hasPerspective() const { return rareNonInheritedData->m_perspective > 0; } - const Length& perspectiveOriginX() const { return rareNonInheritedData->m_perspectiveOriginX; } - const Length& perspectiveOriginY() const { return rareNonInheritedData->m_perspectiveOriginY; } - const LengthSize& pageSize() const { return rareNonInheritedData->m_pageSize; } - PageSizeType pageSizeType() const { return static_cast<PageSizeType>(rareNonInheritedData->m_pageSizeType); } + EBackfaceVisibility backfaceVisibility() const { return static_cast<EBackfaceVisibility>(m_rareNonInheritedData->backfaceVisibility); } + float perspective() const { return m_rareNonInheritedData->perspective; } + bool hasPerspective() const { return m_rareNonInheritedData->perspective > 0; } + const Length& perspectiveOriginX() const { return m_rareNonInheritedData->perspectiveOriginX; } + const Length& perspectiveOriginY() const { return m_rareNonInheritedData->perspectiveOriginY; } + const LengthSize& pageSize() const { return m_rareNonInheritedData->pageSize; } + PageSizeType pageSizeType() const { return static_cast<PageSizeType>(m_rareNonInheritedData->pageSizeType); } -#if USE(ACCELERATED_COMPOSITING) - // When set, this ensures that styles compare as different. Used during accelerated animations. - bool isRunningAcceleratedAnimation() const { return rareNonInheritedData->m_runningAcceleratedAnimation; } + LineBoxContain lineBoxContain() const { return m_rareInheritedData->lineBoxContain; } + const LineClampValue& lineClamp() const { return m_rareNonInheritedData->lineClamp; } + const IntSize& initialLetter() const { return m_rareNonInheritedData->initialLetter; } + int initialLetterDrop() const { return initialLetter().width(); } + int initialLetterHeight() const { return initialLetter().height(); } + +#if ENABLE(TOUCH_EVENTS) + TouchAction touchAction() const { return static_cast<TouchAction>(m_rareNonInheritedData->touchAction); } +#endif + +#if ENABLE(CSS_SCROLL_SNAP) + // Scroll snap port style. + const StyleScrollSnapPort& scrollSnapPort() const; + const ScrollSnapType& scrollSnapType() const; + const LengthBox& scrollPadding() const; + const Length& scrollPaddingTop() const; + const Length& scrollPaddingBottom() const; + const Length& scrollPaddingLeft() const; + const Length& scrollPaddingRight() const; + + // Scroll snap area style. + const StyleScrollSnapArea& scrollSnapArea() const; + const ScrollSnapAlign& scrollSnapAlign() const; + const LengthBox& scrollSnapMargin() const; + const Length& scrollSnapMarginTop() const; + const Length& scrollSnapMarginBottom() const; + const Length& scrollSnapMarginLeft() const; + const Length& scrollSnapMarginRight() const; #endif - LineBoxContain lineBoxContain() const { return rareInheritedData->m_lineBoxContain; } - const LineClampValue& lineClamp() const { return rareNonInheritedData->lineClamp; } #if ENABLE(TOUCH_EVENTS) - Color tapHighlightColor() const { return rareInheritedData->tapHighlightColor; } + Color tapHighlightColor() const { return m_rareInheritedData->tapHighlightColor; } #endif + #if PLATFORM(IOS) - bool touchCalloutEnabled() const { return rareInheritedData->touchCalloutEnabled; } - Color compositionFillColor() const { return rareInheritedData->compositionFillColor; } + bool touchCalloutEnabled() const { return m_rareInheritedData->touchCalloutEnabled; } #endif + #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) - bool useTouchOverflowScrolling() const { return rareInheritedData->useTouchOverflowScrolling; } + bool useTouchOverflowScrolling() const { return m_rareInheritedData->useTouchOverflowScrolling; } #endif -#if ENABLE(IOS_TEXT_AUTOSIZING) - TextSizeAdjustment textSizeAdjust() const { return rareInheritedData->textSizeAdjust; } + +#if ENABLE(TEXT_AUTOSIZING) + TextSizeAdjustment textSizeAdjust() const { return m_rareInheritedData->textSizeAdjust; } #endif - ETextSecurity textSecurity() const { return static_cast<ETextSecurity>(rareInheritedData->textSecurity); } - WritingMode writingMode() const { return static_cast<WritingMode>(inherited_flags.m_writingMode); } + ETextSecurity textSecurity() const { return static_cast<ETextSecurity>(m_rareInheritedData->textSecurity); } + + WritingMode writingMode() const { return static_cast<WritingMode>(m_inheritedFlags.writingMode); } bool isHorizontalWritingMode() const { return WebCore::isHorizontalWritingMode(writingMode()); } + bool isVerticalWritingMode() const { return WebCore::isVerticalWritingMode(writingMode()); } bool isFlippedLinesWritingMode() const { return WebCore::isFlippedLinesWritingMode(writingMode()); } - bool isFlippedBlocksWritingMode() const { return WebCore::isFlippedBlocksWritingMode(writingMode()); } + bool isFlippedBlocksWritingMode() const { return WebCore::isFlippedWritingMode(writingMode()); } -#if ENABLE(CSS_IMAGE_ORIENTATION) - ImageOrientationEnum imageOrientation() const { return static_cast<ImageOrientationEnum>(rareInheritedData->m_imageOrientation); } -#endif + ImageOrientationEnum imageOrientation() const; - EImageRendering imageRendering() const { return static_cast<EImageRendering>(rareInheritedData->m_imageRendering); } + EImageRendering imageRendering() const { return static_cast<EImageRendering>(m_rareInheritedData->imageRendering); } #if ENABLE(CSS_IMAGE_RESOLUTION) - ImageResolutionSource imageResolutionSource() const { return static_cast<ImageResolutionSource>(rareInheritedData->m_imageResolutionSource); } - ImageResolutionSnap imageResolutionSnap() const { return static_cast<ImageResolutionSnap>(rareInheritedData->m_imageResolutionSnap); } - float imageResolution() const { return rareInheritedData->m_imageResolution; } + ImageResolutionSource imageResolutionSource() const { return static_cast<ImageResolutionSource>(m_rareInheritedData->imageResolutionSource); } + ImageResolutionSnap imageResolutionSnap() const { return static_cast<ImageResolutionSnap>(m_rareInheritedData->imageResolutionSnap); } + float imageResolution() const { return m_rareInheritedData->imageResolution; } #endif - ESpeak speak() const { return static_cast<ESpeak>(rareInheritedData->speak); } + ESpeak speak() const { return static_cast<ESpeak>(m_rareInheritedData->speak); } -#if ENABLE(CSS_FILTERS) - FilterOperations& mutableFilter() { return rareNonInheritedData.access()->m_filter.access()->m_operations; } - const FilterOperations& filter() const { return rareNonInheritedData->m_filter->m_operations; } - bool hasFilter() const { return !rareNonInheritedData->m_filter->m_operations.operations().isEmpty(); } + FilterOperations& mutableFilter() { return m_rareNonInheritedData.access().filter.access().operations; } + const FilterOperations& filter() const { return m_rareNonInheritedData->filter->operations; } + bool hasFilter() const { return !m_rareNonInheritedData->filter->operations.operations().isEmpty(); } + bool hasReferenceFilterOnly() const; + +#if ENABLE(FILTERS_LEVEL_2) + FilterOperations& mutableBackdropFilter() { return m_rareNonInheritedData.access().backdropFilter.access().operations; } + const FilterOperations& backdropFilter() const { return m_rareNonInheritedData->backdropFilter->operations; } + bool hasBackdropFilter() const { return !m_rareNonInheritedData->backdropFilter->operations.operations().isEmpty(); } #else - bool hasFilter() const { return false; } + bool hasBackdropFilter() const { return false; } #endif #if ENABLE(CSS_COMPOSITING) - BlendMode blendMode() const { return static_cast<BlendMode>(rareNonInheritedData->m_effectiveBlendMode); } - void setBlendMode(BlendMode v) { rareNonInheritedData.access()->m_effectiveBlendMode = v; } - bool hasBlendMode() const { return static_cast<BlendMode>(rareNonInheritedData->m_effectiveBlendMode) != BlendModeNormal; } + BlendMode blendMode() const { return static_cast<BlendMode>(m_rareNonInheritedData->effectiveBlendMode); } + void setBlendMode(BlendMode mode) { SET_VAR(m_rareNonInheritedData, effectiveBlendMode, mode); } + bool hasBlendMode() const { return static_cast<BlendMode>(m_rareNonInheritedData->effectiveBlendMode) != BlendModeNormal; } + + Isolation isolation() const { return static_cast<Isolation>(m_rareNonInheritedData->isolation); } + void setIsolation(Isolation isolation) { SET_VAR(m_rareNonInheritedData, isolation, isolation); } + bool hasIsolation() const { return m_rareNonInheritedData->isolation != IsolationAuto; } #else + BlendMode blendMode() const { return BlendModeNormal; } bool hasBlendMode() const { return false; } + + Isolation isolation() const { return IsolationAuto; } + bool hasIsolation() const { return false; } #endif - -#if USE(RTL_SCROLLBAR) - bool shouldPlaceBlockDirectionScrollbarOnLogicalLeft() const { return !isLeftToRightDirection() && isHorizontalWritingMode(); } -#else - bool shouldPlaceBlockDirectionScrollbarOnLogicalLeft() const { return false; } + + bool shouldPlaceBlockDirectionScrollbarOnLeft() const; + +#if ENABLE(CSS_TRAILING_WORD) + TrailingWord trailingWord() const { return static_cast<TrailingWord>(m_rareInheritedData->trailingWord); } +#endif + +#if ENABLE(APPLE_PAY) + ApplePayButtonStyle applePayButtonStyle() const { return static_cast<ApplePayButtonStyle>(m_rareNonInheritedData->applePayButtonStyle); } + ApplePayButtonType applePayButtonType() const { return static_cast<ApplePayButtonType>(m_rareNonInheritedData->applePayButtonType); } #endif - + + void checkVariablesInCustomProperties(); + // attribute setter methods - void setDisplay(EDisplay v) { noninherited_flags._effectiveDisplay = v; } - void setOriginalDisplay(EDisplay v) { noninherited_flags._originalDisplay = v; } - void setPosition(EPosition v) { noninherited_flags._position = v; } - void setFloating(EFloat v) { noninherited_flags._floating = v; } - - void setLeft(Length v) { SET_VAR(surround, offset.m_left, std::move(v)); } - void setRight(Length v) { SET_VAR(surround, offset.m_right, std::move(v)); } - void setTop(Length v) { SET_VAR(surround, offset.m_top, std::move(v)); } - void setBottom(Length v) { SET_VAR(surround, offset.m_bottom, std::move(v)); } - - void setWidth(Length v) { SET_VAR(m_box, m_width, std::move(v)); } - void setHeight(Length v) { SET_VAR(m_box, m_height, std::move(v)); } - - void setLogicalWidth(Length v) - { - if (isHorizontalWritingMode()) { - SET_VAR(m_box, m_width, std::move(v)); - } else { - SET_VAR(m_box, m_height, std::move(v)); - } - } + void setDisplay(EDisplay v) { m_nonInheritedFlags.setEffectiveDisplay(v); } + void setOriginalDisplay(EDisplay v) { m_nonInheritedFlags.setOriginalDisplay(v); } + void setPosition(EPosition v) { m_nonInheritedFlags.setPosition(v); } + void setFloating(EFloat v) { m_nonInheritedFlags.setFloating(v); } - void setLogicalHeight(Length v) - { - if (isHorizontalWritingMode()) { - SET_VAR(m_box, m_height, std::move(v)); - } else { - SET_VAR(m_box, m_width, std::move(v)); - } - } + void setLeft(Length&& length) { SET_VAR(m_surroundData, offset.left(), WTFMove(length)); } + void setRight(Length&& length) { SET_VAR(m_surroundData, offset.right(), WTFMove(length)); } + void setTop(Length&& length) { SET_VAR(m_surroundData, offset.top(), WTFMove(length)); } + void setBottom(Length&& length) { SET_VAR(m_surroundData, offset.bottom(), WTFMove(length)); } + + void setWidth(Length&& length) { SET_VAR(m_boxData, m_width, WTFMove(length)); } + void setHeight(Length&& length) { SET_VAR(m_boxData, m_height, WTFMove(length)); } - void setMinWidth(Length v) { SET_VAR(m_box, m_minWidth, std::move(v)); } - void setMaxWidth(Length v) { SET_VAR(m_box, m_maxWidth, std::move(v)); } - void setMinHeight(Length v) { SET_VAR(m_box, m_minHeight, std::move(v)); } - void setMaxHeight(Length v) { SET_VAR(m_box, m_maxHeight, std::move(v)); } + void setLogicalWidth(Length&&); + void setLogicalHeight(Length&&); + + void setMinWidth(Length&& length) { SET_VAR(m_boxData, m_minWidth, WTFMove(length)); } + void setMaxWidth(Length&& length) { SET_VAR(m_boxData, m_maxWidth, WTFMove(length)); } + void setMinHeight(Length&& length) { SET_VAR(m_boxData, m_minHeight, WTFMove(length)); } + void setMaxHeight(Length&& length) { SET_VAR(m_boxData, m_maxHeight, WTFMove(length)); } #if ENABLE(DASHBOARD_SUPPORT) - Vector<StyleDashboardRegion> dashboardRegions() const { return rareNonInheritedData->m_dashboardRegions; } - void setDashboardRegions(Vector<StyleDashboardRegion> regions) { SET_VAR(rareNonInheritedData, m_dashboardRegions, regions); } - - void setDashboardRegion(int type, const String& label, Length t, Length r, Length b, Length l, bool append) - { - StyleDashboardRegion region; - region.label = label; - region.offset.m_top = std::move(t); - region.offset.m_right = std::move(r); - region.offset.m_bottom = std::move(b); - region.offset.m_left = std::move(l); - region.type = type; - if (!append) - rareNonInheritedData.access()->m_dashboardRegions.clear(); - rareNonInheritedData.access()->m_dashboardRegions.append(region); - } + const Vector<StyleDashboardRegion>& dashboardRegions() const { return m_rareNonInheritedData->dashboardRegions; } + void setDashboardRegions(const Vector<StyleDashboardRegion>& regions) { SET_VAR(m_rareNonInheritedData, dashboardRegions, regions); } + void setDashboardRegion(int type, const String& label, Length&& top, Length&& right, Length&& bottom, Length&& left, bool append); #endif void resetBorder() { resetBorderImage(); resetBorderTop(); resetBorderRight(); resetBorderBottom(); resetBorderLeft(); resetBorderRadius(); } - void resetBorderTop() { SET_VAR(surround, border.m_top, BorderValue()); } - void resetBorderRight() { SET_VAR(surround, border.m_right, BorderValue()); } - void resetBorderBottom() { SET_VAR(surround, border.m_bottom, BorderValue()); } - void resetBorderLeft() { SET_VAR(surround, border.m_left, BorderValue()); } - void resetBorderImage() { SET_VAR(surround, border.m_image, NinePieceImage()); } + void resetBorderTop() { SET_VAR(m_surroundData, border.m_top, BorderValue()); } + void resetBorderRight() { SET_VAR(m_surroundData, border.m_right, BorderValue()); } + void resetBorderBottom() { SET_VAR(m_surroundData, border.m_bottom, BorderValue()); } + void resetBorderLeft() { SET_VAR(m_surroundData, border.m_left, BorderValue()); } + void resetBorderImage() { SET_VAR(m_surroundData, border.m_image, NinePieceImage()); } void resetBorderRadius() { resetBorderTopLeftRadius(); resetBorderTopRightRadius(); resetBorderBottomLeftRadius(); resetBorderBottomRightRadius(); } - void resetBorderTopLeftRadius() { SET_VAR(surround, border.m_topLeft, initialBorderRadius()); } - void resetBorderTopRightRadius() { SET_VAR(surround, border.m_topRight, initialBorderRadius()); } - void resetBorderBottomLeftRadius() { SET_VAR(surround, border.m_bottomLeft, initialBorderRadius()); } - void resetBorderBottomRightRadius() { SET_VAR(surround, border.m_bottomRight, initialBorderRadius()); } + void resetBorderTopLeftRadius() { SET_VAR(m_surroundData, border.m_topLeft, initialBorderRadius()); } + void resetBorderTopRightRadius() { SET_VAR(m_surroundData, border.m_topRight, initialBorderRadius()); } + void resetBorderBottomLeftRadius() { SET_VAR(m_surroundData, border.m_bottomLeft, initialBorderRadius()); } + void resetBorderBottomRightRadius() { SET_VAR(m_surroundData, border.m_bottomRight, initialBorderRadius()); } - void setBackgroundColor(const Color& v) { SET_VAR(m_background, m_color, v); } + void setBackgroundColor(const Color& v) { SET_VAR(m_backgroundData, color, v); } - void setBackgroundXPosition(Length length) { SET_VAR(m_background, m_background.m_xPosition, std::move(length)); } - void setBackgroundYPosition(Length length) { SET_VAR(m_background, m_background.m_yPosition, std::move(length)); } - void setBackgroundSize(EFillSizeType b) { SET_VAR(m_background, m_background.m_sizeType, b); } - void setBackgroundSizeLength(LengthSize size) { SET_VAR(m_background, m_background.m_sizeLength, std::move(size)); } - - void setBorderImage(const NinePieceImage& b) { SET_VAR(surround, border.m_image, b); } - void setBorderImageSource(PassRefPtr<StyleImage>); - void setBorderImageSlices(LengthBox); - void setBorderImageWidth(LengthBox); - void setBorderImageOutset(LengthBox); - - void setBorderTopLeftRadius(LengthSize size) { SET_VAR(surround, border.m_topLeft, std::move(size)); } - void setBorderTopRightRadius(LengthSize size) { SET_VAR(surround, border.m_topRight, std::move(size)); } - void setBorderBottomLeftRadius(LengthSize size) { SET_VAR(surround, border.m_bottomLeft, std::move(size)); } - void setBorderBottomRightRadius(LengthSize size) { SET_VAR(surround, border.m_bottomRight, std::move(size)); } - - void setBorderRadius(LengthSize s) - { - setBorderTopLeftRadius(s); - setBorderTopRightRadius(s); - setBorderBottomLeftRadius(s); - setBorderBottomRightRadius(s); - } - void setBorderRadius(const IntSize& s) - { - setBorderRadius(LengthSize(Length(s.width(), Fixed), Length(s.height(), Fixed))); - } + void setBackgroundXPosition(Length&& length) { SET_VAR(m_backgroundData, background.m_xPosition, WTFMove(length)); } + void setBackgroundYPosition(Length&& length) { SET_VAR(m_backgroundData, background.m_yPosition, WTFMove(length)); } + void setBackgroundSize(EFillSizeType b) { SET_VAR(m_backgroundData, background.m_sizeType, b); } + void setBackgroundSizeLength(LengthSize&& size) { SET_VAR(m_backgroundData, background.m_sizeLength, WTFMove(size)); } - RoundedRect getRoundedBorderFor(const LayoutRect& borderRect, RenderView* = 0, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const; + void setBorderImage(const NinePieceImage& b) { SET_VAR(m_surroundData, border.m_image, b); } + void setBorderImageSource(RefPtr<StyleImage>&&); + void setBorderImageSlices(LengthBox&&); + void setBorderImageWidth(LengthBox&&); + void setBorderImageOutset(LengthBox&&); + + void setBorderTopLeftRadius(LengthSize&& size) { SET_VAR(m_surroundData, border.m_topLeft, WTFMove(size)); } + void setBorderTopRightRadius(LengthSize&& size) { SET_VAR(m_surroundData, border.m_topRight, WTFMove(size)); } + void setBorderBottomLeftRadius(LengthSize&& size) { SET_VAR(m_surroundData, border.m_bottomLeft, WTFMove(size)); } + void setBorderBottomRightRadius(LengthSize&& size) { SET_VAR(m_surroundData, border.m_bottomRight, WTFMove(size)); } + + void setBorderRadius(LengthSize&&); + void setBorderRadius(const IntSize&); + + RoundedRect getRoundedBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const; RoundedRect getRoundedInnerBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const; - RoundedRect getRoundedInnerBorderFor(const LayoutRect& borderRect, - int topWidth, int bottomWidth, int leftWidth, int rightWidth, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const; - - void setBorderLeftWidth(unsigned v) { SET_VAR(surround, border.m_left.m_width, v); } - void setBorderLeftStyle(EBorderStyle v) { SET_VAR(surround, border.m_left.m_style, v); } - void setBorderLeftColor(const Color& v) { SET_BORDERVALUE_COLOR(surround, border.m_left, v); } - void setBorderRightWidth(unsigned v) { SET_VAR(surround, border.m_right.m_width, v); } - void setBorderRightStyle(EBorderStyle v) { SET_VAR(surround, border.m_right.m_style, v); } - void setBorderRightColor(const Color& v) { SET_BORDERVALUE_COLOR(surround, border.m_right, v); } - void setBorderTopWidth(unsigned v) { SET_VAR(surround, border.m_top.m_width, v); } - void setBorderTopStyle(EBorderStyle v) { SET_VAR(surround, border.m_top.m_style, v); } - void setBorderTopColor(const Color& v) { SET_BORDERVALUE_COLOR(surround, border.m_top, v); } - void setBorderBottomWidth(unsigned v) { SET_VAR(surround, border.m_bottom.m_width, v); } - void setBorderBottomStyle(EBorderStyle v) { SET_VAR(surround, border.m_bottom.m_style, v); } - void setBorderBottomColor(const Color& v) { SET_BORDERVALUE_COLOR(surround, border.m_bottom, v); } - - void setOutlineWidth(unsigned short v) { SET_VAR(m_background, m_outline.m_width, v); } - void setOutlineStyleIsAuto(OutlineIsAuto isAuto) { SET_VAR(m_background, m_outline.m_isAuto, isAuto); } - void setOutlineStyle(EBorderStyle v) { SET_VAR(m_background, m_outline.m_style, v); } - void setOutlineColor(const Color& v) { SET_BORDERVALUE_COLOR(m_background, m_outline, v); } - - void setOverflowX(EOverflow v) { noninherited_flags._overflowX = v; } - void setOverflowY(EOverflow v) { noninherited_flags._overflowY = v; } - void setVisibility(EVisibility v) { inherited_flags._visibility = v; } - void setVerticalAlign(EVerticalAlign v) { noninherited_flags._vertical_align = v; } - void setVerticalAlignLength(Length length) { setVerticalAlign(LENGTH); SET_VAR(m_box, m_verticalAlign, std::move(length)); } - - void setHasClip(bool b = true) { SET_VAR(visual, hasClip, b); } - void setClipLeft(Length length) { SET_VAR(visual, clip.m_left, std::move(length)); } - void setClipRight(Length length) { SET_VAR(visual, clip.m_right, std::move(length)); } - void setClipTop(Length length) { SET_VAR(visual, clip.m_top, std::move(length)); } - void setClipBottom(Length length) { SET_VAR(visual, clip.m_bottom, std::move(length)); } - void setClip(Length top, Length right, Length bottom, Length left); - void setClip(LengthBox box) { SET_VAR(visual, clip, std::move(box)); } - - void setUnicodeBidi(EUnicodeBidi b) { noninherited_flags._unicodeBidi = b; } - - void setClear(EClear v) { noninherited_flags._clear = v; } - void setTableLayout(ETableLayout v) { noninherited_flags._table_layout = v; } - - bool setFontDescription(const FontDescription&); + RoundedRect getRoundedInnerBorderFor(const LayoutRect& borderRect, LayoutUnit topWidth, LayoutUnit bottomWidth, + LayoutUnit leftWidth, LayoutUnit rightWidth, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const; + + void setBorderLeftWidth(float v) { SET_VAR(m_surroundData, border.m_left.m_width, v); } + void setBorderLeftStyle(EBorderStyle v) { SET_VAR(m_surroundData, border.m_left.m_style, v); } + void setBorderLeftColor(const Color& v) { SET_BORDERVALUE_COLOR(m_surroundData, border.m_left, v); } + void setBorderRightWidth(float v) { SET_VAR(m_surroundData, border.m_right.m_width, v); } + void setBorderRightStyle(EBorderStyle v) { SET_VAR(m_surroundData, border.m_right.m_style, v); } + void setBorderRightColor(const Color& v) { SET_BORDERVALUE_COLOR(m_surroundData, border.m_right, v); } + void setBorderTopWidth(float v) { SET_VAR(m_surroundData, border.m_top.m_width, v); } + void setBorderTopStyle(EBorderStyle v) { SET_VAR(m_surroundData, border.m_top.m_style, v); } + void setBorderTopColor(const Color& v) { SET_BORDERVALUE_COLOR(m_surroundData, border.m_top, v); } + void setBorderBottomWidth(float v) { SET_VAR(m_surroundData, border.m_bottom.m_width, v); } + void setBorderBottomStyle(EBorderStyle v) { SET_VAR(m_surroundData, border.m_bottom.m_style, v); } + void setBorderBottomColor(const Color& v) { SET_BORDERVALUE_COLOR(m_surroundData, border.m_bottom, v); } + + void setOutlineWidth(float v) { SET_VAR(m_backgroundData, outline.m_width, v); } + void setOutlineStyleIsAuto(OutlineIsAuto isAuto) { SET_VAR(m_backgroundData, outline.m_isAuto, isAuto); } + void setOutlineStyle(EBorderStyle v) { SET_VAR(m_backgroundData, outline.m_style, v); } + void setOutlineColor(const Color& v) { SET_BORDERVALUE_COLOR(m_backgroundData, outline, v); } + + void setOverflowX(EOverflow v) { m_nonInheritedFlags.setOverflowX(v); } + void setOverflowY(EOverflow v) { m_nonInheritedFlags.setOverflowY(v); } + void setVisibility(EVisibility v) { m_inheritedFlags.visibility = v; } + void setVerticalAlign(EVerticalAlign v) { m_nonInheritedFlags.setVerticalAlign(v); } + void setVerticalAlignLength(Length&& length) { setVerticalAlign(LENGTH); SET_VAR(m_boxData, m_verticalAlign, WTFMove(length)); } + + void setHasClip(bool b = true) { SET_VAR(m_visualData, hasClip, b); } + void setClipLeft(Length&& length) { SET_VAR(m_visualData, clip.left(), WTFMove(length)); } + void setClipRight(Length&& length) { SET_VAR(m_visualData, clip.right(), WTFMove(length)); } + void setClipTop(Length&& length) { SET_VAR(m_visualData, clip.top(), WTFMove(length)); } + void setClipBottom(Length&& length) { SET_VAR(m_visualData, clip.bottom(), WTFMove(length)); } + void setClip(Length&& top, Length&& right, Length&& bottom, Length&& left); + void setClip(LengthBox&& box) { SET_VAR(m_visualData, clip, WTFMove(box)); } + + void setUnicodeBidi(EUnicodeBidi b) { m_nonInheritedFlags.setUnicodeBidi(b); } + + void setClear(EClear v) { m_nonInheritedFlags.setClear(v); } + void setTableLayout(ETableLayout v) { m_nonInheritedFlags.setTableLayout(v); } + + bool setFontDescription(const FontCascadeDescription&); + // Only used for blending font sizes when animating, for MathML anonymous blocks, and for text autosizing. void setFontSize(float); -#if ENABLE(TEXT_AUTOSIZING) - void setTextAutosizingMultiplier(float v) - { - SET_VAR(visual, m_textAutosizingMultiplier, v); - setFontSize(fontDescription().specifiedSize()); - } +#if ENABLE(VARIATION_FONTS) + void setFontVariationSettings(FontVariationSettings); #endif void setColor(const Color&); - void setTextIndent(Length length) { SET_VAR(rareInheritedData, indent, std::move(length)); } -#if ENABLE(CSS3_TEXT) - void setTextIndentLine(TextIndentLine v) { SET_VAR(rareInheritedData, m_textIndentLine, v); } - void setTextIndentType(TextIndentType v) { SET_VAR(rareInheritedData, m_textIndentType, v); } -#endif - void setTextAlign(ETextAlign v) { inherited_flags._text_align = v; } - void setTextTransform(ETextTransform v) { inherited_flags._text_transform = v; } - void addToTextDecorationsInEffect(TextDecoration v) { inherited_flags._text_decorations |= v; } - void setTextDecorationsInEffect(TextDecoration v) { inherited_flags._text_decorations = v; } - void setTextDecoration(TextDecoration v) { SET_VAR(visual, textDecoration, v); } -#if ENABLE(CSS3_TEXT) - void setTextAlignLast(TextAlignLast v) { SET_VAR(rareInheritedData, m_textAlignLast, v); } - void setTextJustify(TextJustify v) { SET_VAR(rareInheritedData, m_textJustify, v); } -#endif // CSS3_TEXT - void setTextDecorationStyle(TextDecorationStyle v) { SET_VAR(rareNonInheritedData, m_textDecorationStyle, v); } - void setTextDecorationSkip(TextDecorationSkip skip) { SET_VAR(rareInheritedData, m_textDecorationSkip, skip); } - void setTextUnderlinePosition(TextUnderlinePosition v) { SET_VAR(rareInheritedData, m_textUnderlinePosition, v); } - void setDirection(TextDirection v) { inherited_flags._direction = v; } -#if ENABLE(IOS_TEXT_AUTOSIZING) - void setSpecifiedLineHeight(Length v); -#endif - void setLineHeight(Length specifiedLineHeight); + void setTextIndent(Length&& length) { SET_VAR(m_rareInheritedData, indent, WTFMove(length)); } + void setTextAlign(ETextAlign v) { m_inheritedFlags.textAlign = v; } + void setTextTransform(ETextTransform v) { m_inheritedFlags.textTransform = v; } + void addToTextDecorationsInEffect(TextDecoration v) { m_inheritedFlags.textDecorations |= v; } + void setTextDecorationsInEffect(TextDecoration v) { m_inheritedFlags.textDecorations = v; } + void setTextDecoration(TextDecoration v) { SET_VAR(m_visualData, textDecoration, v); } + void setTextDecorationStyle(TextDecorationStyle v) { SET_VAR(m_rareNonInheritedData, textDecorationStyle, v); } + void setTextDecorationSkip(TextDecorationSkip skip) { SET_VAR(m_rareInheritedData, textDecorationSkip, skip); } + void setTextUnderlinePosition(TextUnderlinePosition v) { SET_VAR(m_rareInheritedData, textUnderlinePosition, v); } + void setDirection(TextDirection v) { m_inheritedFlags.direction = v; } + void setHasExplicitlySetDirection(bool v) { m_nonInheritedFlags.setHasExplicitlySetDirection(v); } + void setLineHeight(Length&&); bool setZoom(float); void setZoomWithoutReturnValue(float f) { setZoom(f); } bool setEffectiveZoom(float); + void setTextZoom(TextZoom v) { SET_VAR(m_rareInheritedData, textZoom, v); } + +#if ENABLE(CSS3_TEXT) + void setTextIndentLine(TextIndentLine v) { SET_VAR(m_rareInheritedData, textIndentLine, v); } + void setTextIndentType(TextIndentType v) { SET_VAR(m_rareInheritedData, textIndentType, v); } + void setTextAlignLast(TextAlignLast v) { SET_VAR(m_rareInheritedData, textAlignLast, v); } + void setTextJustify(TextJustify v) { SET_VAR(m_rareInheritedData, textJustify, v); } +#endif + +#if ENABLE(TEXT_AUTOSIZING) + void setSpecifiedLineHeight(Length&&); +#endif #if ENABLE(CSS_IMAGE_ORIENTATION) - void setImageOrientation(ImageOrientationEnum v) { SET_VAR(rareInheritedData, m_imageOrientation, static_cast<int>(v)); } + void setImageOrientation(ImageOrientationEnum v) { SET_VAR(m_rareInheritedData, imageOrientation, static_cast<int>(v)); } #endif - void setImageRendering(EImageRendering v) { SET_VAR(rareInheritedData, m_imageRendering, v); } + void setImageRendering(EImageRendering v) { SET_VAR(m_rareInheritedData, imageRendering, v); } #if ENABLE(CSS_IMAGE_RESOLUTION) - void setImageResolutionSource(ImageResolutionSource v) { SET_VAR(rareInheritedData, m_imageResolutionSource, v); } - void setImageResolutionSnap(ImageResolutionSnap v) { SET_VAR(rareInheritedData, m_imageResolutionSnap, v); } - void setImageResolution(float f) { SET_VAR(rareInheritedData, m_imageResolution, f); } + void setImageResolutionSource(ImageResolutionSource v) { SET_VAR(m_rareInheritedData, imageResolutionSource, v); } + void setImageResolutionSnap(ImageResolutionSnap v) { SET_VAR(m_rareInheritedData, imageResolutionSnap, v); } + void setImageResolution(float f) { SET_VAR(m_rareInheritedData, imageResolution, f); } #endif - void setWhiteSpace(EWhiteSpace v) { inherited_flags._white_space = v; } + void setWhiteSpace(EWhiteSpace v) { m_inheritedFlags.whiteSpace = v; } - void setWordSpacing(Length); + void setWordSpacing(Length&&); void setLetterSpacing(float); - void clearBackgroundLayers() { m_background.access()->m_background = FillLayer(BackgroundFillLayer); } - void inheritBackgroundLayers(const FillLayer& parent) { m_background.access()->m_background = parent; } + void clearBackgroundLayers() { m_backgroundData.access().background = FillLayer(BackgroundFillLayer); } + void inheritBackgroundLayers(const FillLayer& parent) { m_backgroundData.access().background = parent; } - void adjustBackgroundLayers() - { - if (backgroundLayers()->next()) { - accessBackgroundLayers()->cullEmptyLayers(); - accessBackgroundLayers()->fillUnsetProperties(); - } - } + void adjustBackgroundLayers(); - void clearMaskLayers() { rareNonInheritedData.access()->m_mask = FillLayer(MaskFillLayer); } - void inheritMaskLayers(const FillLayer& parent) { rareNonInheritedData.access()->m_mask = parent; } + void clearMaskLayers() { m_rareNonInheritedData.access().mask = FillLayer(MaskFillLayer); } + void inheritMaskLayers(const FillLayer& parent) { m_rareNonInheritedData.access().mask = parent; } - void adjustMaskLayers() - { - if (maskLayers()->next()) { - accessMaskLayers()->cullEmptyLayers(); - accessMaskLayers()->fillUnsetProperties(); - } - } + void adjustMaskLayers(); + + void setMaskImage(RefPtr<StyleImage>&& v) { m_rareNonInheritedData.access().mask.setImage(WTFMove(v)); } + + void setMaskBoxImage(const NinePieceImage& b) { SET_VAR(m_rareNonInheritedData, maskBoxImage, b); } + void setMaskBoxImageSource(RefPtr<StyleImage>&& v) { m_rareNonInheritedData.access().maskBoxImage.setImage(WTFMove(v)); } + void setMaskXPosition(Length&& length) { SET_VAR(m_rareNonInheritedData, mask.m_xPosition, WTFMove(length)); } + void setMaskYPosition(Length&& length) { SET_VAR(m_rareNonInheritedData, mask.m_yPosition, WTFMove(length)); } + void setMaskSize(LengthSize size) { SET_VAR(m_rareNonInheritedData, mask.m_sizeLength, WTFMove(size)); } + + void setBorderCollapse(EBorderCollapse collapse) { m_inheritedFlags.borderCollapse = collapse; } + void setHorizontalBorderSpacing(float); + void setVerticalBorderSpacing(float); + void setEmptyCells(EEmptyCell v) { m_inheritedFlags.emptyCells = v; } + void setCaptionSide(ECaptionSide v) { m_inheritedFlags.captionSide = v; } + + void setAspectRatioType(AspectRatioType aspectRatioType) { SET_VAR(m_rareNonInheritedData, aspectRatioType, aspectRatioType); } + void setAspectRatioDenominator(float v) { SET_VAR(m_rareNonInheritedData, aspectRatioDenominator, v); } + void setAspectRatioNumerator(float v) { SET_VAR(m_rareNonInheritedData, aspectRatioNumerator, v); } + + void setListStyleType(EListStyleType v) { m_inheritedFlags.listStyleType = v; } + void setListStyleImage(RefPtr<StyleImage>&&); + void setListStylePosition(EListStylePosition v) { m_inheritedFlags.listStylePosition = v; } - void setMaskImage(PassRefPtr<StyleImage> v) { rareNonInheritedData.access()->m_mask.setImage(v); } - - void setMaskBoxImage(const NinePieceImage& b) { SET_VAR(rareNonInheritedData, m_maskBoxImage, b); } - void setMaskBoxImageSource(PassRefPtr<StyleImage> v) { rareNonInheritedData.access()->m_maskBoxImage.setImage(v); } - void setMaskXPosition(Length length) { SET_VAR(rareNonInheritedData, m_mask.m_xPosition, std::move(length)); } - void setMaskYPosition(Length length) { SET_VAR(rareNonInheritedData, m_mask.m_yPosition, std::move(length)); } - void setMaskSize(LengthSize size) { SET_VAR(rareNonInheritedData, m_mask.m_sizeLength, std::move(size)); } - - void setBorderCollapse(EBorderCollapse collapse) { inherited_flags._border_collapse = collapse; } - void setHorizontalBorderSpacing(short); - void setVerticalBorderSpacing(short); - void setEmptyCells(EEmptyCell v) { inherited_flags._empty_cells = v; } - void setCaptionSide(ECaptionSide v) { inherited_flags._caption_side = v; } - - void setHasAspectRatio(bool b) { SET_VAR(rareNonInheritedData, m_hasAspectRatio, b); } - void setAspectRatioDenominator(float v) { SET_VAR(rareNonInheritedData, m_aspectRatioDenominator, v); } - void setAspectRatioNumerator(float v) { SET_VAR(rareNonInheritedData, m_aspectRatioNumerator, v); } - - void setListStyleType(EListStyleType v) { inherited_flags._list_style_type = v; } - void setListStyleImage(PassRefPtr<StyleImage>); - void setListStylePosition(EListStylePosition v) { inherited_flags._list_style_position = v; } - - void resetMargin() { SET_VAR(surround, margin, LengthBox(Fixed)); } - void setMarginTop(Length length) { SET_VAR(surround, margin.m_top, std::move(length)); } - void setMarginBottom(Length length) { SET_VAR(surround, margin.m_bottom, std::move(length)); } - void setMarginLeft(Length length) { SET_VAR(surround, margin.m_left, std::move(length)); } - void setMarginRight(Length length) { SET_VAR(surround, margin.m_right, std::move(length)); } - void setMarginStart(Length); - void setMarginEnd(Length); - - void resetPadding() { SET_VAR(surround, padding, LengthBox(Auto)); } - void setPaddingBox(LengthBox box) { SET_VAR(surround, padding, std::move(box)); } - void setPaddingTop(Length length) { SET_VAR(surround, padding.m_top, std::move(length)); } - void setPaddingBottom(Length length) { SET_VAR(surround, padding.m_bottom, std::move(length)); } - void setPaddingLeft(Length length) { SET_VAR(surround, padding.m_left, std::move(length)); } - void setPaddingRight(Length length) { SET_VAR(surround, padding.m_right, std::move(length)); } - - void setCursor(ECursor c) { inherited_flags._cursor_style = c; } - void addCursor(PassRefPtr<StyleImage>, const IntPoint& hotSpot = IntPoint()); - void setCursorList(PassRefPtr<CursorList>); + void resetMargin() { SET_VAR(m_surroundData, margin, LengthBox(Fixed)); } + void setMarginTop(Length&& length) { SET_VAR(m_surroundData, margin.top(), WTFMove(length)); } + void setMarginBottom(Length&& length) { SET_VAR(m_surroundData, margin.bottom(), WTFMove(length)); } + void setMarginLeft(Length&& length) { SET_VAR(m_surroundData, margin.left(), WTFMove(length)); } + void setMarginRight(Length&& length) { SET_VAR(m_surroundData, margin.right(), WTFMove(length)); } + void setMarginStart(Length&&); + void setMarginEnd(Length&&); + + void resetPadding() { SET_VAR(m_surroundData, padding, LengthBox(Auto)); } + void setPaddingBox(LengthBox&& box) { SET_VAR(m_surroundData, padding, WTFMove(box)); } + void setPaddingTop(Length&& length) { SET_VAR(m_surroundData, padding.top(), WTFMove(length)); } + void setPaddingBottom(Length&& length) { SET_VAR(m_surroundData, padding.bottom(), WTFMove(length)); } + void setPaddingLeft(Length&& length) { SET_VAR(m_surroundData, padding.left(), WTFMove(length)); } + void setPaddingRight(Length&& length) { SET_VAR(m_surroundData, padding.right(), WTFMove(length)); } + + void setCursor(ECursor c) { m_inheritedFlags.cursor = c; } + void addCursor(RefPtr<StyleImage>&&, const IntPoint& hotSpot = IntPoint()); + void setCursorList(RefPtr<CursorList>&&); void clearCursorList(); #if ENABLE(CURSOR_VISIBILITY) - void setCursorVisibility(CursorVisibility c) { inherited_flags.m_cursorVisibility = c; } + void setCursorVisibility(CursorVisibility c) { m_inheritedFlags.cursorVisibility = c; } #endif - void setInsideLink(EInsideLink insideLink) { inherited_flags._insideLink = insideLink; } - void setIsLink(bool b) { noninherited_flags.setIsLink(b); } + void setInsideLink(EInsideLink insideLink) { m_inheritedFlags.insideLink = insideLink; } + void setIsLink(bool b) { m_nonInheritedFlags.setIsLink(b); } - PrintColorAdjust printColorAdjust() const { return static_cast<PrintColorAdjust>(inherited_flags.m_printColorAdjust); } - void setPrintColorAdjust(PrintColorAdjust value) { inherited_flags.m_printColorAdjust = value; } + void setInsideDefaultButton(bool insideDefaultButton) { m_inheritedFlags.insideDefaultButton = insideDefaultButton; } - bool hasAutoZIndex() const { return m_box->hasAutoZIndex(); } - void setHasAutoZIndex() { SET_VAR(m_box, m_hasAutoZIndex, true); SET_VAR(m_box, m_zIndex, 0); } - int zIndex() const { return m_box->zIndex(); } - void setZIndex(int v) { SET_VAR(m_box, m_hasAutoZIndex, false); SET_VAR(m_box, m_zIndex, v); } + PrintColorAdjust printColorAdjust() const { return static_cast<PrintColorAdjust>(m_inheritedFlags.printColorAdjust); } + void setPrintColorAdjust(PrintColorAdjust value) { m_inheritedFlags.printColorAdjust = value; } - void setHasAutoWidows() { SET_VAR(rareInheritedData, m_hasAutoWidows, true); SET_VAR(rareInheritedData, widows, initialWidows()); } - void setWidows(short w) { SET_VAR(rareInheritedData, m_hasAutoWidows, false); SET_VAR(rareInheritedData, widows, w); } + bool hasAutoZIndex() const { return m_boxData->hasAutoZIndex(); } + void setHasAutoZIndex() { SET_VAR(m_boxData, m_hasAutoZIndex, true); SET_VAR(m_boxData, m_zIndex, 0); } + int zIndex() const { return m_boxData->zIndex(); } + void setZIndex(int v) { SET_VAR(m_boxData, m_hasAutoZIndex, false); SET_VAR(m_boxData, m_zIndex, v); } - void setHasAutoOrphans() { SET_VAR(rareInheritedData, m_hasAutoOrphans, true); SET_VAR(rareInheritedData, orphans, initialOrphans()); } - void setOrphans(short o) { SET_VAR(rareInheritedData, m_hasAutoOrphans, false); SET_VAR(rareInheritedData, orphans, o); } + void setHasAutoWidows() { SET_VAR(m_rareInheritedData, hasAutoWidows, true); SET_VAR(m_rareInheritedData, widows, initialWidows()); } + void setWidows(short w) { SET_VAR(m_rareInheritedData, hasAutoWidows, false); SET_VAR(m_rareInheritedData, widows, w); } - // For valid values of page-break-inside see http://www.w3.org/TR/CSS21/page.html#page-break-props - void setPageBreakInside(EPageBreak b) { ASSERT(b == PBAUTO || b == PBAVOID); noninherited_flags._page_break_inside = b; } - void setPageBreakBefore(EPageBreak b) { noninherited_flags._page_break_before = b; } - void setPageBreakAfter(EPageBreak b) { noninherited_flags._page_break_after = b; } + void setHasAutoOrphans() { SET_VAR(m_rareInheritedData, hasAutoOrphans, true); SET_VAR(m_rareInheritedData, orphans, initialOrphans()); } + void setOrphans(short o) { SET_VAR(m_rareInheritedData, hasAutoOrphans, false); SET_VAR(m_rareInheritedData, orphans, o); } // CSS3 Setters - void setOutlineOffset(int v) { SET_VAR(m_background, m_outline.m_offset, v); } - void setTextShadow(PassOwnPtr<ShadowData>, bool add = false); - void setTextStrokeColor(const Color& c) { SET_VAR(rareInheritedData, textStrokeColor, c); } - void setTextStrokeWidth(float w) { SET_VAR(rareInheritedData, textStrokeWidth, w); } - void setTextFillColor(const Color& c) { SET_VAR(rareInheritedData, textFillColor, c); } - void setColorSpace(ColorSpace space) { SET_VAR(rareInheritedData, colorSpace, space); } - void setOpacity(float f) { float v = clampTo<float>(f, 0, 1); SET_VAR(rareNonInheritedData, opacity, v); } - void setAppearance(ControlPart a) { SET_VAR(rareNonInheritedData, m_appearance, a); } + void setOutlineOffset(float v) { SET_VAR(m_backgroundData, outline.m_offset, v); } + void setTextShadow(std::unique_ptr<ShadowData>, bool add = false); + void setTextStrokeColor(const Color& c) { SET_VAR(m_rareInheritedData, textStrokeColor, c); } + void setTextStrokeWidth(float w) { SET_VAR(m_rareInheritedData, textStrokeWidth, w); } + void setTextFillColor(const Color& c) { SET_VAR(m_rareInheritedData, textFillColor, c); } + void setOpacity(float f) { float v = clampTo<float>(f, 0, 1); SET_VAR(m_rareNonInheritedData, opacity, v); } + void setAppearance(ControlPart a) { SET_VAR(m_rareNonInheritedData, appearance, a); } // For valid values of box-align see http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/#alignment - void setBoxAlign(EBoxAlignment a) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, align, a); } + void setBoxAlign(EBoxAlignment a) { SET_NESTED_VAR(m_rareNonInheritedData, deprecatedFlexibleBox, align, a); } + void setBoxDirection(EBoxDirection d) { m_inheritedFlags.boxDirection = d; } + void setBoxFlex(float f) { SET_NESTED_VAR(m_rareNonInheritedData, deprecatedFlexibleBox, flex, f); } + void setBoxFlexGroup(unsigned group) { SET_NESTED_VAR(m_rareNonInheritedData, deprecatedFlexibleBox, flexGroup, group); } + void setBoxLines(EBoxLines lines) { SET_NESTED_VAR(m_rareNonInheritedData, deprecatedFlexibleBox, lines, lines); } + void setBoxOrdinalGroup(unsigned group) { SET_NESTED_VAR(m_rareNonInheritedData, deprecatedFlexibleBox, ordinalGroup, group); } + void setBoxOrient(EBoxOrient o) { SET_NESTED_VAR(m_rareNonInheritedData, deprecatedFlexibleBox, orient, o); } + void setBoxPack(EBoxPack p) { SET_NESTED_VAR(m_rareNonInheritedData, deprecatedFlexibleBox, pack, p); } + void setBoxShadow(std::unique_ptr<ShadowData>, bool add = false); + void setBoxReflect(RefPtr<StyleReflection>&&); + void setBoxSizing(EBoxSizing s) { SET_VAR(m_boxData, m_boxSizing, s); } + void setFlexGrow(float f) { SET_NESTED_VAR(m_rareNonInheritedData, flexibleBox, flexGrow, f); } + void setFlexShrink(float f) { SET_NESTED_VAR(m_rareNonInheritedData, flexibleBox, flexShrink, f); } + void setFlexBasis(Length&& length) { SET_NESTED_VAR(m_rareNonInheritedData, flexibleBox, flexBasis, WTFMove(length)); } + void setOrder(int o) { SET_VAR(m_rareNonInheritedData, order, o); } + void setAlignContent(const StyleContentAlignmentData& data) { SET_VAR(m_rareNonInheritedData, alignContent, data); } + void setAlignItems(const StyleSelfAlignmentData& data) { SET_VAR(m_rareNonInheritedData, alignItems, data); } + void setAlignItemsPosition(ItemPosition position) { m_rareNonInheritedData.access().alignItems.setPosition(position); } + void setAlignSelf(const StyleSelfAlignmentData& data) { SET_VAR(m_rareNonInheritedData, alignSelf, data); } + void setAlignSelfPosition(ItemPosition position) { m_rareNonInheritedData.access().alignSelf.setPosition(position); } + void setFlexDirection(EFlexDirection direction) { SET_NESTED_VAR(m_rareNonInheritedData, flexibleBox, flexDirection, direction); } + void setFlexWrap(EFlexWrap w) { SET_NESTED_VAR(m_rareNonInheritedData, flexibleBox, flexWrap, w); } + void setJustifyContent(const StyleContentAlignmentData& data) { SET_VAR(m_rareNonInheritedData, justifyContent, data); } + void setJustifyContentPosition(ContentPosition position) { m_rareNonInheritedData.access().justifyContent.setPosition(position); } + void setJustifyItems(const StyleSelfAlignmentData& data) { SET_VAR(m_rareNonInheritedData, justifyItems, data); } + void setJustifySelf(const StyleSelfAlignmentData& data) { SET_VAR(m_rareNonInheritedData, justifySelf, data); } + #if ENABLE(CSS_BOX_DECORATION_BREAK) - void setBoxDecorationBreak(EBoxDecorationBreak b) { SET_VAR(m_box, m_boxDecorationBreak, b); } + void setBoxDecorationBreak(EBoxDecorationBreak b) { SET_VAR(m_boxData, m_boxDecorationBreak, b); } #endif - void setBoxDirection(EBoxDirection d) { inherited_flags._box_direction = d; } - void setBoxFlex(float f) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, flex, f); } - void setBoxFlexGroup(unsigned int fg) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, flex_group, fg); } - void setBoxLines(EBoxLines l) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, lines, l); } - void setBoxOrdinalGroup(unsigned int og) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, ordinal_group, og); } - void setBoxOrient(EBoxOrient o) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, orient, o); } - void setBoxPack(EBoxPack p) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, pack, p); } - void setBoxShadow(PassOwnPtr<ShadowData>, bool add = false); - void setBoxReflect(PassRefPtr<StyleReflection> reflect) { if (rareNonInheritedData->m_boxReflect != reflect) rareNonInheritedData.access()->m_boxReflect = reflect; } - void setBoxSizing(EBoxSizing s) { SET_VAR(m_box, m_boxSizing, s); } - void setFlexGrow(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexGrow, f); } - void setFlexShrink(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexShrink, f); } - void setFlexBasis(Length length) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexBasis, std::move(length)); } - void setOrder(int o) { SET_VAR(rareNonInheritedData, m_order, o); } - void setAlignContent(EAlignContent p) { SET_VAR(rareNonInheritedData, m_alignContent, p); } - void setAlignItems(EAlignItems a) { SET_VAR(rareNonInheritedData, m_alignItems, a); } - void setAlignSelf(EAlignItems a) { SET_VAR(rareNonInheritedData, m_alignSelf, a); } - void setFlexDirection(EFlexDirection direction) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexDirection, direction); } - void setFlexWrap(EFlexWrap w) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexWrap, w); } - void setJustifyContent(EJustifyContent p) { SET_VAR(rareNonInheritedData, m_justifyContent, p); } - void setGridAutoColumns(const GridTrackSize& length) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridAutoColumns, length); } - void setGridAutoRows(const GridTrackSize& length) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridAutoRows, length); } - void setGridColumns(const Vector<GridTrackSize>& lengths) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridColumns, lengths); } - void setGridRows(const Vector<GridTrackSize>& lengths) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridRows, lengths); } - void setNamedGridColumnLines(const NamedGridLinesMap& namedGridColumnLines) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridColumnLines, namedGridColumnLines); } - void setNamedGridRowLines(const NamedGridLinesMap& namedGridRowLines) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridRowLines, namedGridRowLines); } - void setNamedGridArea(const NamedGridAreaMap& namedGridArea) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridArea, namedGridArea); } - void setNamedGridAreaRowCount(size_t rowCount) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridAreaRowCount, rowCount); } - void setNamedGridAreaColumnCount(size_t columnCount) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridAreaColumnCount, columnCount); } - void setGridAutoFlow(GridAutoFlow flow) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridAutoFlow, flow); } - void setGridItemColumnStart(const GridPosition& columnStartPosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridColumnStart, columnStartPosition); } - void setGridItemColumnEnd(const GridPosition& columnEndPosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridColumnEnd, columnEndPosition); } - void setGridItemRowStart(const GridPosition& rowStartPosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridRowStart, rowStartPosition); } - void setGridItemRowEnd(const GridPosition& rowEndPosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridRowEnd, rowEndPosition); } - - void setMarqueeIncrement(Length length) { SET_VAR(rareNonInheritedData.access()->m_marquee, increment, std::move(length)); } - void setMarqueeSpeed(int f) { SET_VAR(rareNonInheritedData.access()->m_marquee, speed, f); } - void setMarqueeDirection(EMarqueeDirection d) { SET_VAR(rareNonInheritedData.access()->m_marquee, direction, d); } - void setMarqueeBehavior(EMarqueeBehavior b) { SET_VAR(rareNonInheritedData.access()->m_marquee, behavior, b); } - void setMarqueeLoopCount(int i) { SET_VAR(rareNonInheritedData.access()->m_marquee, loops, i); } - void setUserModify(EUserModify u) { SET_VAR(rareInheritedData, userModify, u); } - void setUserDrag(EUserDrag d) { SET_VAR(rareNonInheritedData, userDrag, d); } - void setUserSelect(EUserSelect s) { SET_VAR(rareInheritedData, userSelect, s); } - void setTextOverflow(TextOverflow overflow) { SET_VAR(rareNonInheritedData, textOverflow, overflow); } - void setMarginBeforeCollapse(EMarginCollapse c) { SET_VAR(rareNonInheritedData, marginBeforeCollapse, c); } - void setMarginAfterCollapse(EMarginCollapse c) { SET_VAR(rareNonInheritedData, marginAfterCollapse, c); } - void setWordBreak(EWordBreak b) { SET_VAR(rareInheritedData, wordBreak, b); } - void setOverflowWrap(EOverflowWrap b) { SET_VAR(rareInheritedData, overflowWrap, b); } - void setNBSPMode(ENBSPMode b) { SET_VAR(rareInheritedData, nbspMode, b); } - void setLineBreak(LineBreak b) { SET_VAR(rareInheritedData, lineBreak, b); } - void setHighlight(const AtomicString& h) { SET_VAR(rareInheritedData, highlight, h); } - void setHyphens(Hyphens h) { SET_VAR(rareInheritedData, hyphens, h); } - void setHyphenationLimitBefore(short limit) { SET_VAR(rareInheritedData, hyphenationLimitBefore, limit); } - void setHyphenationLimitAfter(short limit) { SET_VAR(rareInheritedData, hyphenationLimitAfter, limit); } - void setHyphenationLimitLines(short limit) { SET_VAR(rareInheritedData, hyphenationLimitLines, limit); } - void setHyphenationString(const AtomicString& h) { SET_VAR(rareInheritedData, hyphenationString, h); } - void setLocale(const AtomicString& locale) { SET_VAR(rareInheritedData, locale, locale); } - void setBorderFit(EBorderFit b) { SET_VAR(rareNonInheritedData, m_borderFit, b); } - void setResize(EResize r) { SET_VAR(rareInheritedData, resize, r); } - void setColumnAxis(ColumnAxis axis) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_axis, axis); } - void setColumnProgression(ColumnProgression progression) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_progression, progression); } - void setColumnWidth(float f) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoWidth, false); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_width, f); } - void setHasAutoColumnWidth() { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoWidth, true); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_width, 0); } - void setColumnCount(unsigned short c) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoCount, false); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_count, c); } - void setHasAutoColumnCount() { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoCount, true); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_count, 0); } - void setColumnFill(ColumnFill columnFill) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_fill, columnFill); } - void setColumnGap(float f) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_normalGap, false); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_gap, f); } - void setHasNormalColumnGap() { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_normalGap, true); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_gap, 0); } - void setColumnRuleColor(const Color& c) { SET_BORDERVALUE_COLOR(rareNonInheritedData.access()->m_multiCol, m_rule, c); } - void setColumnRuleStyle(EBorderStyle b) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule.m_style, b); } - void setColumnRuleWidth(unsigned short w) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule.m_width, w); } - void resetColumnRule() { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule, BorderValue()); } - void setColumnSpan(ColumnSpan columnSpan) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_columnSpan, columnSpan); } - void setColumnBreakBefore(EPageBreak p) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_breakBefore, p); } - // For valid values of column-break-inside see http://www.w3.org/TR/css3-multicol/#break-before-break-after-break-inside - void setColumnBreakInside(EPageBreak p) { ASSERT(p == PBAUTO || p == PBAVOID); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_breakInside, p); } - void setColumnBreakAfter(EPageBreak p) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_breakAfter, p); } - void setRegionBreakBefore(EPageBreak p) { SET_VAR(rareNonInheritedData, m_regionBreakBefore, p); } - void setRegionBreakInside(EPageBreak p) { ASSERT(p == PBAUTO || p == PBAVOID); SET_VAR(rareNonInheritedData, m_regionBreakInside, p); } - void setRegionBreakAfter(EPageBreak p) { SET_VAR(rareNonInheritedData, m_regionBreakAfter, p); } - void inheritColumnPropertiesFrom(RenderStyle* parent) { rareNonInheritedData.access()->m_multiCol = parent->rareNonInheritedData->m_multiCol; } - void setTransform(const TransformOperations& ops) { SET_VAR(rareNonInheritedData.access()->m_transform, m_operations, ops); } - void setTransformOriginX(Length length) { SET_VAR(rareNonInheritedData.access()->m_transform, m_x, std::move(length)); } - void setTransformOriginY(Length length) { SET_VAR(rareNonInheritedData.access()->m_transform, m_y, std::move(length)); } - void setTransformOriginZ(float f) { SET_VAR(rareNonInheritedData.access()->m_transform, m_z, f); } - void setSpeak(ESpeak s) { SET_VAR(rareInheritedData, speak, s); } - void setTextCombine(TextCombine v) { SET_VAR(rareNonInheritedData, m_textCombine, v); } - void setTextDecorationColor(const Color& c) { SET_VAR(rareNonInheritedData, m_textDecorationColor, c); } - void setTextEmphasisColor(const Color& c) { SET_VAR(rareInheritedData, textEmphasisColor, c); } - void setTextEmphasisFill(TextEmphasisFill fill) { SET_VAR(rareInheritedData, textEmphasisFill, fill); } - void setTextEmphasisMark(TextEmphasisMark mark) { SET_VAR(rareInheritedData, textEmphasisMark, mark); } - void setTextEmphasisCustomMark(const AtomicString& mark) { SET_VAR(rareInheritedData, textEmphasisCustomMark, mark); } - void setTextEmphasisPosition(TextEmphasisPosition position) { SET_VAR(rareInheritedData, textEmphasisPosition, position); } + + void setGridAutoColumns(const Vector<GridTrackSize>& trackSizeList) { SET_NESTED_VAR(m_rareNonInheritedData, grid, gridAutoColumns, trackSizeList); } + void setGridAutoRows(const Vector<GridTrackSize>& trackSizeList) { SET_NESTED_VAR(m_rareNonInheritedData, grid, gridAutoRows, trackSizeList); } + void setGridColumns(const Vector<GridTrackSize>& lengths) { SET_NESTED_VAR(m_rareNonInheritedData, grid, gridColumns, lengths); } + void setGridRows(const Vector<GridTrackSize>& lengths) { SET_NESTED_VAR(m_rareNonInheritedData, grid, gridRows, lengths); } + void setGridAutoRepeatColumns(const Vector<GridTrackSize>& lengths) { SET_NESTED_VAR(m_rareNonInheritedData, grid, gridAutoRepeatColumns, lengths); } + void setGridAutoRepeatRows(const Vector<GridTrackSize>& lengths) { SET_NESTED_VAR(m_rareNonInheritedData, grid, gridAutoRepeatRows, lengths); } + void setGridAutoRepeatColumnsInsertionPoint(const unsigned insertionPoint) { SET_NESTED_VAR(m_rareNonInheritedData, grid, autoRepeatColumnsInsertionPoint, insertionPoint); } + void setGridAutoRepeatRowsInsertionPoint(const unsigned insertionPoint) { SET_NESTED_VAR(m_rareNonInheritedData, grid, autoRepeatRowsInsertionPoint, insertionPoint); } + void setGridAutoRepeatColumnsType(const AutoRepeatType autoRepeatType) { SET_NESTED_VAR(m_rareNonInheritedData, grid, autoRepeatColumnsType, autoRepeatType); } + void setGridAutoRepeatRowsType(const AutoRepeatType autoRepeatType) { SET_NESTED_VAR(m_rareNonInheritedData, grid, autoRepeatRowsType, autoRepeatType); } + void setNamedGridColumnLines(const NamedGridLinesMap& namedGridColumnLines) { SET_NESTED_VAR(m_rareNonInheritedData, grid, namedGridColumnLines, namedGridColumnLines); } + void setNamedGridRowLines(const NamedGridLinesMap& namedGridRowLines) { SET_NESTED_VAR(m_rareNonInheritedData, grid, namedGridRowLines, namedGridRowLines); } + void setOrderedNamedGridColumnLines(const OrderedNamedGridLinesMap& orderedNamedGridColumnLines) { SET_NESTED_VAR(m_rareNonInheritedData, grid, orderedNamedGridColumnLines, orderedNamedGridColumnLines); } + void setOrderedNamedGridRowLines(const OrderedNamedGridLinesMap& orderedNamedGridRowLines) { SET_NESTED_VAR(m_rareNonInheritedData, grid, orderedNamedGridRowLines, orderedNamedGridRowLines); } + void setAutoRepeatNamedGridColumnLines(const NamedGridLinesMap& namedGridColumnLines) { SET_NESTED_VAR(m_rareNonInheritedData, grid, autoRepeatNamedGridColumnLines, namedGridColumnLines); } + void setAutoRepeatNamedGridRowLines(const NamedGridLinesMap& namedGridRowLines) { SET_NESTED_VAR(m_rareNonInheritedData, grid, autoRepeatNamedGridRowLines, namedGridRowLines); } + void setAutoRepeatOrderedNamedGridColumnLines(const OrderedNamedGridLinesMap& orderedNamedGridColumnLines) { SET_NESTED_VAR(m_rareNonInheritedData, grid, autoRepeatOrderedNamedGridColumnLines, orderedNamedGridColumnLines); } + void setAutoRepeatOrderedNamedGridRowLines(const OrderedNamedGridLinesMap& orderedNamedGridRowLines) { SET_NESTED_VAR(m_rareNonInheritedData, grid, autoRepeatOrderedNamedGridRowLines, orderedNamedGridRowLines); } + void setNamedGridArea(const NamedGridAreaMap& namedGridArea) { SET_NESTED_VAR(m_rareNonInheritedData, grid, namedGridArea, namedGridArea); } + void setNamedGridAreaRowCount(size_t rowCount) { SET_NESTED_VAR(m_rareNonInheritedData, grid, namedGridAreaRowCount, rowCount); } + void setNamedGridAreaColumnCount(size_t columnCount) { SET_NESTED_VAR(m_rareNonInheritedData, grid, namedGridAreaColumnCount, columnCount); } + void setGridAutoFlow(GridAutoFlow flow) { SET_NESTED_VAR(m_rareNonInheritedData, grid, gridAutoFlow, flow); } + void setGridItemColumnStart(const GridPosition& columnStartPosition) { SET_NESTED_VAR(m_rareNonInheritedData, gridItem, gridColumnStart, columnStartPosition); } + void setGridItemColumnEnd(const GridPosition& columnEndPosition) { SET_NESTED_VAR(m_rareNonInheritedData, gridItem, gridColumnEnd, columnEndPosition); } + void setGridItemRowStart(const GridPosition& rowStartPosition) { SET_NESTED_VAR(m_rareNonInheritedData, gridItem, gridRowStart, rowStartPosition); } + void setGridItemRowEnd(const GridPosition& rowEndPosition) { SET_NESTED_VAR(m_rareNonInheritedData, gridItem, gridRowEnd, rowEndPosition); } + void setGridColumnGap(Length&& length) { SET_NESTED_VAR(m_rareNonInheritedData, grid, gridColumnGap, WTFMove(length)); } + void setGridRowGap(Length&& length) { SET_NESTED_VAR(m_rareNonInheritedData, grid, gridRowGap, WTFMove(length)); } + + void setMarqueeIncrement(Length&& length) { SET_NESTED_VAR(m_rareNonInheritedData, marquee, increment, WTFMove(length)); } + void setMarqueeSpeed(int f) { SET_NESTED_VAR(m_rareNonInheritedData, marquee, speed, f); } + void setMarqueeDirection(EMarqueeDirection d) { SET_NESTED_VAR(m_rareNonInheritedData, marquee, direction, d); } + void setMarqueeBehavior(EMarqueeBehavior b) { SET_NESTED_VAR(m_rareNonInheritedData, marquee, behavior, b); } + void setMarqueeLoopCount(int i) { SET_NESTED_VAR(m_rareNonInheritedData, marquee, loops, i); } + void setUserModify(EUserModify u) { SET_VAR(m_rareInheritedData, userModify, u); } + void setUserDrag(EUserDrag d) { SET_VAR(m_rareNonInheritedData, userDrag, d); } + void setUserSelect(EUserSelect s) { SET_VAR(m_rareInheritedData, userSelect, s); } + void setTextOverflow(TextOverflow overflow) { SET_VAR(m_rareNonInheritedData, textOverflow, overflow); } + void setMarginBeforeCollapse(EMarginCollapse c) { SET_VAR(m_rareNonInheritedData, marginBeforeCollapse, c); } + void setMarginAfterCollapse(EMarginCollapse c) { SET_VAR(m_rareNonInheritedData, marginAfterCollapse, c); } + void setWordBreak(EWordBreak b) { SET_VAR(m_rareInheritedData, wordBreak, b); } + void setOverflowWrap(EOverflowWrap b) { SET_VAR(m_rareInheritedData, overflowWrap, b); } + void setNBSPMode(ENBSPMode b) { SET_VAR(m_rareInheritedData, nbspMode, b); } + void setLineBreak(LineBreak b) { SET_VAR(m_rareInheritedData, lineBreak, b); } + void setHyphens(Hyphens h) { SET_VAR(m_rareInheritedData, hyphens, h); } + void setHyphenationLimitBefore(short limit) { SET_VAR(m_rareInheritedData, hyphenationLimitBefore, limit); } + void setHyphenationLimitAfter(short limit) { SET_VAR(m_rareInheritedData, hyphenationLimitAfter, limit); } + void setHyphenationLimitLines(short limit) { SET_VAR(m_rareInheritedData, hyphenationLimitLines, limit); } + void setHyphenationString(const AtomicString& h) { SET_VAR(m_rareInheritedData, hyphenationString, h); } + void setBorderFit(EBorderFit b) { SET_VAR(m_rareNonInheritedData, borderFit, b); } + void setResize(EResize r) { SET_VAR(m_rareNonInheritedData, resize, r); } + void setColumnAxis(ColumnAxis axis) { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, axis, axis); } + void setColumnProgression(ColumnProgression progression) { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, progression, progression); } + void setColumnWidth(float f) { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, autoWidth, false); SET_NESTED_VAR(m_rareNonInheritedData, multiCol, width, f); } + void setHasAutoColumnWidth() { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, autoWidth, true); SET_NESTED_VAR(m_rareNonInheritedData, multiCol, width, 0); } + void setColumnCount(unsigned short c) { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, autoCount, false); SET_NESTED_VAR(m_rareNonInheritedData, multiCol, count, c); } + void setHasAutoColumnCount() { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, autoCount, true); SET_NESTED_VAR(m_rareNonInheritedData, multiCol, count, 0); } + void setColumnFill(ColumnFill columnFill) { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, fill, columnFill); } + void setColumnGap(float f) { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, normalGap, false); SET_NESTED_VAR(m_rareNonInheritedData, multiCol, gap, f); } + void setHasNormalColumnGap() { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, normalGap, true); SET_NESTED_VAR(m_rareNonInheritedData, multiCol, gap, 0); } + void setColumnRuleColor(const Color& c) { SET_BORDERVALUE_COLOR(m_rareNonInheritedData.access().multiCol, rule, c); } + void setColumnRuleStyle(EBorderStyle b) { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, rule.m_style, b); } + void setColumnRuleWidth(unsigned short w) { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, rule.m_width, w); } + void resetColumnRule() { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, rule, BorderValue()); } + void setColumnSpan(ColumnSpan columnSpan) { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, columnSpan, columnSpan); } + void inheritColumnPropertiesFrom(const RenderStyle& parent) { m_rareNonInheritedData.access().multiCol = parent.m_rareNonInheritedData->multiCol; } + void setTransform(const TransformOperations& ops) { SET_NESTED_VAR(m_rareNonInheritedData, transform, operations, ops); } + void setTransformOriginX(Length&& length) { SET_NESTED_VAR(m_rareNonInheritedData, transform, x, WTFMove(length)); } + void setTransformOriginY(Length&& length) { SET_NESTED_VAR(m_rareNonInheritedData, transform, y, WTFMove(length)); } + void setTransformOriginZ(float f) { SET_NESTED_VAR(m_rareNonInheritedData, transform, z, f); } + void setSpeak(ESpeak s) { SET_VAR(m_rareInheritedData, speak, s); } + void setTextCombine(TextCombine v) { SET_VAR(m_rareNonInheritedData, textCombine, v); } + void setTextDecorationColor(const Color& c) { SET_VAR(m_rareNonInheritedData, textDecorationColor, c); } + void setTextEmphasisColor(const Color& c) { SET_VAR(m_rareInheritedData, textEmphasisColor, c); } + void setTextEmphasisFill(TextEmphasisFill fill) { SET_VAR(m_rareInheritedData, textEmphasisFill, fill); } + void setTextEmphasisMark(TextEmphasisMark mark) { SET_VAR(m_rareInheritedData, textEmphasisMark, mark); } + void setTextEmphasisCustomMark(const AtomicString& mark) { SET_VAR(m_rareInheritedData, textEmphasisCustomMark, mark); } + void setTextEmphasisPosition(TextEmphasisPosition position) { SET_VAR(m_rareInheritedData, textEmphasisPosition, position); } bool setTextOrientation(TextOrientation); - void setObjectFit(ObjectFit fit) { SET_VAR(rareNonInheritedData, m_objectFit, fit); } + void setObjectFit(ObjectFit fit) { SET_VAR(m_rareNonInheritedData, objectFit, fit); } + void setObjectPosition(LengthPoint&& position) { SET_VAR(m_rareNonInheritedData, objectPosition, WTFMove(position)); } - void setRubyPosition(RubyPosition position) { SET_VAR(rareInheritedData, m_rubyPosition, position); } + void setRubyPosition(RubyPosition position) { SET_VAR(m_rareInheritedData, rubyPosition, position); } -#if ENABLE(CSS_FILTERS) - void setFilter(const FilterOperations& ops) { SET_VAR(rareNonInheritedData.access()->m_filter, m_operations, ops); } -#endif + void setFilter(const FilterOperations& ops) { SET_NESTED_VAR(m_rareNonInheritedData, filter, operations, ops); } - void setTabSize(unsigned size) { SET_VAR(rareInheritedData, m_tabSize, size); } +#if ENABLE(FILTERS_LEVEL_2) + void setBackdropFilter(const FilterOperations& ops) { SET_NESTED_VAR(m_rareNonInheritedData, backdropFilter, operations, ops); } +#endif - // End CSS3 Setters + void setTabSize(unsigned size) { SET_VAR(m_rareInheritedData, tabSize, size); } - void setLineGrid(const AtomicString& lineGrid) { SET_VAR(rareInheritedData, m_lineGrid, lineGrid); } - void setLineSnap(LineSnap lineSnap) { SET_VAR(rareInheritedData, m_lineSnap, lineSnap); } - void setLineAlign(LineAlign lineAlign) { SET_VAR(rareInheritedData, m_lineAlign, lineAlign); } + void setBreakBefore(BreakBetween breakBehavior) { SET_VAR(m_rareNonInheritedData, breakBefore, breakBehavior); } + void setBreakAfter(BreakBetween breakBehavior) { SET_VAR(m_rareNonInheritedData, breakAfter, breakBehavior); } + void setBreakInside(BreakInside breakBehavior) { SET_VAR(m_rareNonInheritedData, breakInside, breakBehavior); } + + void setHangingPunctuation(HangingPunctuation punctuation) { SET_VAR(m_rareInheritedData, hangingPunctuation, punctuation); } - void setFlowThread(const AtomicString& flowThread) { SET_VAR(rareNonInheritedData, m_flowThread, flowThread); } - void setRegionThread(const AtomicString& regionThread) { SET_VAR(rareNonInheritedData, m_regionThread, regionThread); } - void setRegionFragment(RegionFragment regionFragment) { SET_VAR(rareNonInheritedData, m_regionFragment, regionFragment); } + // End CSS3 Setters - void setWrapFlow(WrapFlow wrapFlow) { SET_VAR(rareNonInheritedData, m_wrapFlow, wrapFlow); } - void setWrapThrough(WrapThrough wrapThrough) { SET_VAR(rareNonInheritedData, m_wrapThrough, wrapThrough); } + void setLineGrid(const AtomicString& lineGrid) { SET_VAR(m_rareInheritedData, lineGrid, lineGrid); } + void setLineSnap(LineSnap lineSnap) { SET_VAR(m_rareInheritedData, lineSnap, lineSnap); } + void setLineAlign(LineAlign lineAlign) { SET_VAR(m_rareInheritedData, lineAlign, lineAlign); } - // Apple-specific property setters - void setPointerEvents(EPointerEvents p) { inherited_flags._pointerEvents = p; } + void setFlowThread(const AtomicString& flowThread) { SET_VAR(m_rareNonInheritedData, flowThread, flowThread); } + void setRegionThread(const AtomicString& regionThread) { SET_VAR(m_rareNonInheritedData, regionThread, regionThread); } + void setRegionFragment(RegionFragment regionFragment) { SET_VAR(m_rareNonInheritedData, regionFragment, regionFragment); } - void clearAnimations() - { - rareNonInheritedData.access()->m_animations.clear(); - } + void setPointerEvents(EPointerEvents p) { m_inheritedFlags.pointerEvents = p; } - void clearTransitions() - { - rareNonInheritedData.access()->m_transitions.clear(); - } + void clearAnimations(); + void clearTransitions(); - void inheritAnimations(const AnimationList* parent) { rareNonInheritedData.access()->m_animations = parent ? adoptPtr(new AnimationList(*parent)) : nullptr; } - void inheritTransitions(const AnimationList* parent) { rareNonInheritedData.access()->m_transitions = parent ? adoptPtr(new AnimationList(*parent)) : nullptr; } void adjustAnimations(); void adjustTransitions(); - void setTransformStyle3D(ETransformStyle3D b) { SET_VAR(rareNonInheritedData, m_transformStyle3D, b); } - void setBackfaceVisibility(EBackfaceVisibility b) { SET_VAR(rareNonInheritedData, m_backfaceVisibility, b); } - void setPerspective(float p) { SET_VAR(rareNonInheritedData, m_perspective, p); } - void setPerspectiveOriginX(Length length) { SET_VAR(rareNonInheritedData, m_perspectiveOriginX, std::move(length)); } - void setPerspectiveOriginY(Length length) { SET_VAR(rareNonInheritedData, m_perspectiveOriginY, std::move(length)); } - void setPageSize(LengthSize size) { SET_VAR(rareNonInheritedData, m_pageSize, std::move(size)); } - void setPageSizeType(PageSizeType t) { SET_VAR(rareNonInheritedData, m_pageSizeType, t); } - void resetPageSizeType() { SET_VAR(rareNonInheritedData, m_pageSizeType, PAGE_SIZE_AUTO); } - -#if USE(ACCELERATED_COMPOSITING) - void setIsRunningAcceleratedAnimation(bool b = true) { SET_VAR(rareNonInheritedData, m_runningAcceleratedAnimation, b); } + void setTransformStyle3D(ETransformStyle3D b) { SET_VAR(m_rareNonInheritedData, transformStyle3D, b); } + void setBackfaceVisibility(EBackfaceVisibility b) { SET_VAR(m_rareNonInheritedData, backfaceVisibility, b); } + void setPerspective(float p) { SET_VAR(m_rareNonInheritedData, perspective, p); } + void setPerspectiveOriginX(Length&& length) { SET_VAR(m_rareNonInheritedData, perspectiveOriginX, WTFMove(length)); } + void setPerspectiveOriginY(Length&& length) { SET_VAR(m_rareNonInheritedData, perspectiveOriginY, WTFMove(length)); } + void setPageSize(LengthSize size) { SET_VAR(m_rareNonInheritedData, pageSize, WTFMove(size)); } + void setPageSizeType(PageSizeType t) { SET_VAR(m_rareNonInheritedData, pageSizeType, t); } + void resetPageSizeType() { SET_VAR(m_rareNonInheritedData, pageSizeType, PAGE_SIZE_AUTO); } + + void setLineBoxContain(LineBoxContain c) { SET_VAR(m_rareInheritedData, lineBoxContain, c); } + void setLineClamp(LineClampValue c) { SET_VAR(m_rareNonInheritedData, lineClamp, c); } + + void setInitialLetter(const IntSize& size) { SET_VAR(m_rareNonInheritedData, initialLetter, size); } + +#if ENABLE(TOUCH_EVENTS) + void setTouchAction(TouchAction touchAction) { SET_VAR(m_rareNonInheritedData, touchAction, static_cast<unsigned>(touchAction)); } +#endif + +#if ENABLE(CSS_SCROLL_SNAP) + void setScrollSnapType(const ScrollSnapType&); + void setScrollPaddingTop(Length&&); + void setScrollPaddingBottom(Length&&); + void setScrollPaddingLeft(Length&&); + void setScrollPaddingRight(Length&&); + + void setScrollSnapAlign(const ScrollSnapAlign&); + void setScrollSnapMarginTop(Length&&); + void setScrollSnapMarginBottom(Length&&); + void setScrollSnapMarginLeft(Length&&); + void setScrollSnapMarginRight(Length&&); #endif - void setLineBoxContain(LineBoxContain c) { SET_VAR(rareInheritedData, m_lineBoxContain, c); } - void setLineClamp(LineClampValue c) { SET_VAR(rareNonInheritedData, lineClamp, c); } #if ENABLE(TOUCH_EVENTS) - void setTapHighlightColor(const Color& c) { SET_VAR(rareInheritedData, tapHighlightColor, c); } + void setTapHighlightColor(const Color& c) { SET_VAR(m_rareInheritedData, tapHighlightColor, c); } #endif + #if PLATFORM(IOS) - void setTouchCalloutEnabled(bool v) { SET_VAR(rareInheritedData, touchCalloutEnabled, v); } - void setCompositionFillColor(const Color &c) { SET_VAR(rareInheritedData, compositionFillColor, c); } + void setTouchCalloutEnabled(bool v) { SET_VAR(m_rareInheritedData, touchCalloutEnabled, v); } #endif + #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) - void setUseTouchOverflowScrolling(bool v) { SET_VAR(rareInheritedData, useTouchOverflowScrolling, v); } + void setUseTouchOverflowScrolling(bool v) { SET_VAR(m_rareInheritedData, useTouchOverflowScrolling, v); } +#endif + +#if ENABLE(TEXT_AUTOSIZING) + void setTextSizeAdjust(TextSizeAdjustment adjustment) { SET_VAR(m_rareInheritedData, textSizeAdjust, adjustment); } +#endif + + void setTextSecurity(ETextSecurity security) { SET_VAR(m_rareInheritedData, textSecurity, security); } + +#if ENABLE(CSS_TRAILING_WORD) + void setTrailingWord(TrailingWord v) { SET_VAR(m_rareInheritedData, trailingWord, static_cast<unsigned>(v)); } #endif -#if ENABLE(IOS_TEXT_AUTOSIZING) - void setTextSizeAdjust(TextSizeAdjustment anAdjustment) { SET_VAR(rareInheritedData, textSizeAdjust, anAdjustment); } + +#if ENABLE(APPLE_PAY) + void setApplePayButtonStyle(ApplePayButtonStyle style) { SET_VAR(m_rareNonInheritedData, applePayButtonStyle, static_cast<unsigned>(style)); } + void setApplePayButtonType(ApplePayButtonType type) { SET_VAR(m_rareNonInheritedData, applePayButtonType, static_cast<unsigned>(type)); } #endif - void setTextSecurity(ETextSecurity aTextSecurity) { SET_VAR(rareInheritedData, textSecurity, aTextSecurity); } -#if ENABLE(SVG) - const SVGRenderStyle& svgStyle() const { return *m_svgStyle; } - SVGRenderStyle& accessSVGStyle() { return *m_svgStyle.access(); } + // Support for paint-order, stroke-linecap, and stroke-linejoin from https://drafts.fxtf.org/paint/. + void setPaintOrder(PaintOrder order) { SET_VAR(m_rareInheritedData, paintOrder, order); } + PaintOrder paintOrder() const { return static_cast<PaintOrder>(m_rareInheritedData->paintOrder); } + static PaintOrder initialPaintOrder() { return PaintOrderNormal; } + Vector<PaintType, 3> paintTypesForPaintOrder() const; + + void setCapStyle(LineCap val) { SET_VAR(m_rareInheritedData, capStyle, val); } + LineCap capStyle() const { return static_cast<LineCap>(m_rareInheritedData->capStyle); } + static LineCap initialCapStyle() { return ButtCap; } + + void setJoinStyle(LineJoin val) { SET_VAR(m_rareInheritedData, joinStyle, val); } + LineJoin joinStyle() const { return static_cast<LineJoin>(m_rareInheritedData->joinStyle); } + static LineJoin initialJoinStyle() { return MiterJoin; } + + const Length& strokeWidth() const { return m_rareInheritedData->strokeWidth; } + void setStrokeWidth(Length&& w) { SET_VAR(m_rareInheritedData, strokeWidth, WTFMove(w)); } + bool hasVisibleStroke() const { return svgStyle().hasStroke() && !strokeWidth().isZero(); } + + + const SVGRenderStyle& svgStyle() const { return m_svgStyle; } + SVGRenderStyle& accessSVGStyle() { return m_svgStyle.access(); } - const SVGPaint::SVGPaintType& fillPaintType() const { return svgStyle().fillPaintType(); } + const SVGPaintType& fillPaintType() const { return svgStyle().fillPaintType(); } Color fillPaintColor() const { return svgStyle().fillPaintColor(); } - void setFillPaintColor(const Color& c) { accessSVGStyle().setFillPaint(SVGPaint::SVG_PAINTTYPE_RGBCOLOR, c, ""); } + void setFillPaintColor(const Color& color) { accessSVGStyle().setFillPaint(SVG_PAINTTYPE_RGBCOLOR, color, emptyString()); } float fillOpacity() const { return svgStyle().fillOpacity(); } void setFillOpacity(float f) { accessSVGStyle().setFillOpacity(f); } - const SVGPaint::SVGPaintType& strokePaintType() const { return svgStyle().strokePaintType(); } + const SVGPaintType& strokePaintType() const { return svgStyle().strokePaintType(); } Color strokePaintColor() const { return svgStyle().strokePaintColor(); } - void setStrokePaintColor(const Color& c) { accessSVGStyle().setStrokePaint(SVGPaint::SVG_PAINTTYPE_RGBCOLOR, c, ""); } + void setStrokePaintColor(const Color& color) { accessSVGStyle().setStrokePaint(SVG_PAINTTYPE_RGBCOLOR, color, emptyString()); } float strokeOpacity() const { return svgStyle().strokeOpacity(); } void setStrokeOpacity(float f) { accessSVGStyle().setStrokeOpacity(f); } - SVGLength strokeWidth() const { return svgStyle().strokeWidth(); } - void setStrokeWidth(SVGLength w) { accessSVGStyle().setStrokeWidth(w); } - Vector<SVGLength> strokeDashArray() const { return svgStyle().strokeDashArray(); } - void setStrokeDashArray(Vector<SVGLength> array) { accessSVGStyle().setStrokeDashArray(array); } - SVGLength strokeDashOffset() const { return svgStyle().strokeDashOffset(); } - void setStrokeDashOffset(SVGLength d) { accessSVGStyle().setStrokeDashOffset(d); } + Vector<SVGLengthValue> strokeDashArray() const { return svgStyle().strokeDashArray(); } + void setStrokeDashArray(Vector<SVGLengthValue> array) { accessSVGStyle().setStrokeDashArray(array); } + const Length& strokeDashOffset() const { return svgStyle().strokeDashOffset(); } + void setStrokeDashOffset(Length&& d) { accessSVGStyle().setStrokeDashOffset(WTFMove(d)); } float strokeMiterLimit() const { return svgStyle().strokeMiterLimit(); } void setStrokeMiterLimit(float f) { accessSVGStyle().setStrokeMiterLimit(f); } + const Length& cx() const { return svgStyle().cx(); } + void setCx(Length&& cx) { accessSVGStyle().setCx(WTFMove(cx)); } + const Length& cy() const { return svgStyle().cy(); } + void setCy(Length&& cy) { accessSVGStyle().setCy(WTFMove(cy)); } + const Length& r() const { return svgStyle().r(); } + void setR(Length&& r) { accessSVGStyle().setR(WTFMove(r)); } + const Length& rx() const { return svgStyle().rx(); } + void setRx(Length&& rx) { accessSVGStyle().setRx(WTFMove(rx)); } + const Length& ry() const { return svgStyle().ry(); } + void setRy(Length&& ry) { accessSVGStyle().setRy(WTFMove(ry)); } + const Length& x() const { return svgStyle().x(); } + void setX(Length&& x) { accessSVGStyle().setX(WTFMove(x)); } + const Length& y() const { return svgStyle().y(); } + void setY(Length&& y) { accessSVGStyle().setY(WTFMove(y)); } + float floodOpacity() const { return svgStyle().floodOpacity(); } void setFloodOpacity(float f) { accessSVGStyle().setFloodOpacity(f); } @@ -1490,203 +1301,158 @@ public: void setFloodColor(const Color& c) { accessSVGStyle().setFloodColor(c); } void setLightingColor(const Color& c) { accessSVGStyle().setLightingColor(c); } - SVGLength baselineShiftValue() const { return svgStyle().baselineShiftValue(); } - void setBaselineShiftValue(SVGLength s) { accessSVGStyle().setBaselineShiftValue(s); } - SVGLength kerning() const { return svgStyle().kerning(); } - void setKerning(SVGLength k) { accessSVGStyle().setKerning(k); } -#endif - -#if ENABLE(CSS_SHAPES) - void setShapeInside(PassRefPtr<ShapeValue> value) - { - if (rareNonInheritedData->m_shapeInside == value) - return; - rareNonInheritedData.access()->m_shapeInside = value; - } - ShapeValue* shapeInside() const { return rareNonInheritedData->m_shapeInside.get(); } - ShapeValue* resolvedShapeInside() const - { - ShapeValue* shapeInside = this->shapeInside(); - if (shapeInside && shapeInside->type() == ShapeValue::Outside) - return shapeOutside(); - return shapeInside; - } - - void setShapeOutside(PassRefPtr<ShapeValue> value) - { - if (rareNonInheritedData->m_shapeOutside == value) - return; - rareNonInheritedData.access()->m_shapeOutside = value; - } - ShapeValue* shapeOutside() const { return rareNonInheritedData->m_shapeOutside.get(); } - - static ShapeValue* initialShapeInside() { return 0; } - static ShapeValue* initialShapeOutside() { return 0; } + SVGLengthValue baselineShiftValue() const { return svgStyle().baselineShiftValue(); } + void setBaselineShiftValue(SVGLengthValue s) { accessSVGStyle().setBaselineShiftValue(s); } + SVGLengthValue kerning() const { return svgStyle().kerning(); } + void setKerning(SVGLengthValue k) { accessSVGStyle().setKerning(k); } - const Length& shapePadding() const { return rareNonInheritedData->m_shapePadding; } - void setShapePadding(Length shapePadding) { SET_VAR(rareNonInheritedData, m_shapePadding, std::move(shapePadding)); } - static Length initialShapePadding() { return Length(0, Fixed); } + void setShapeOutside(RefPtr<ShapeValue>&&); + ShapeValue* shapeOutside() const { return m_rareNonInheritedData->shapeOutside.get(); } + static ShapeValue* initialShapeOutside() { return nullptr; } - const Length& shapeMargin() const { return rareNonInheritedData->m_shapeMargin; } - void setShapeMargin(Length shapeMargin) { SET_VAR(rareNonInheritedData, m_shapeMargin, std::move(shapeMargin)); } + const Length& shapeMargin() const { return m_rareNonInheritedData->shapeMargin; } + void setShapeMargin(Length&& shapeMargin) { SET_VAR(m_rareNonInheritedData, shapeMargin, WTFMove(shapeMargin)); } static Length initialShapeMargin() { return Length(0, Fixed); } - float shapeImageThreshold() const { return rareNonInheritedData->m_shapeImageThreshold; } - void setShapeImageThreshold(float shapeImageThreshold) - { - float clampedShapeImageThreshold = clampTo<float>(shapeImageThreshold, 0, 1); - SET_VAR(rareNonInheritedData, m_shapeImageThreshold, clampedShapeImageThreshold); - } + float shapeImageThreshold() const { return m_rareNonInheritedData->shapeImageThreshold; } + void setShapeImageThreshold(float); static float initialShapeImageThreshold() { return 0; } -#endif - - void setClipPath(PassRefPtr<ClipPathOperation> operation) - { - if (rareNonInheritedData->m_clipPath != operation) - rareNonInheritedData.access()->m_clipPath = operation; - } - ClipPathOperation* clipPath() const { return rareNonInheritedData->m_clipPath.get(); } - static ClipPathOperation* initialClipPath() { return 0; } + void setClipPath(RefPtr<ClipPathOperation>&&); + ClipPathOperation* clipPath() const { return m_rareNonInheritedData->clipPath.get(); } + static ClipPathOperation* initialClipPath() { return nullptr; } bool hasContent() const { return contentData(); } - const ContentData* contentData() const { return rareNonInheritedData->m_content.get(); } - bool contentDataEquivalent(const RenderStyle* otherStyle) const { return const_cast<RenderStyle*>(this)->rareNonInheritedData->contentDataEquivalent(*const_cast<RenderStyle*>(otherStyle)->rareNonInheritedData); } + const ContentData* contentData() const { return m_rareNonInheritedData->content.get(); } + bool contentDataEquivalent(const RenderStyle* otherStyle) const { return const_cast<RenderStyle*>(this)->m_rareNonInheritedData->contentDataEquivalent(*const_cast<RenderStyle*>(otherStyle)->m_rareNonInheritedData); } void clearContent(); void setContent(const String&, bool add = false); - void setContent(PassRefPtr<StyleImage>, bool add = false); + void setContent(RefPtr<StyleImage>&&, bool add = false); void setContent(std::unique_ptr<CounterContent>, bool add = false); void setContent(QuoteType, bool add = false); void setContentAltText(const String&); const String& contentAltText() const; + bool hasAttrContent() const { return m_rareNonInheritedData->hasAttrContent; } + void setHasAttrContent(); const CounterDirectiveMap* counterDirectives() const; CounterDirectiveMap& accessCounterDirectives(); const CounterDirectives getCounterDirectives(const AtomicString& identifier) const; - QuotesData* quotes() const { return rareInheritedData->quotes.get(); } - void setQuotes(PassRefPtr<QuotesData>); + QuotesData* quotes() const { return m_rareInheritedData->quotes.get(); } + void setQuotes(RefPtr<QuotesData>&&); + + WillChangeData* willChange() const { return m_rareNonInheritedData->willChange.get(); } + void setWillChange(RefPtr<WillChangeData>&&); + + bool willChangeCreatesStackingContext() const; const AtomicString& hyphenString() const; bool inheritedNotEqual(const RenderStyle*) const; bool inheritedDataShared(const RenderStyle*) const; -#if ENABLE(IOS_TEXT_AUTOSIZING) +#if ENABLE(TEXT_AUTOSIZING) uint32_t hashForTextAutosizing() const; - bool equalForTextAutosizing(const RenderStyle *other) const; + bool equalForTextAutosizing(const RenderStyle&) const; #endif - StyleDifference diff(const RenderStyle*, unsigned& changedContextSensitiveProperties) const; - bool diffRequiresRepaint(const RenderStyle*) const; + StyleDifference diff(const RenderStyle&, unsigned& changedContextSensitiveProperties) const; + bool diffRequiresLayerRepaint(const RenderStyle&, bool isComposited) const; - bool isDisplayReplacedType() const { return isDisplayReplacedType(display()); } bool isDisplayInlineType() const { return isDisplayInlineType(display()); } bool isOriginalDisplayInlineType() const { return isDisplayInlineType(originalDisplay()); } - bool isDisplayRegionType() const - { - return display() == BLOCK || display() == INLINE_BLOCK - || display() == TABLE_CELL || display() == TABLE_CAPTION - || display() == LIST_ITEM; - } + bool isDisplayFlexibleOrGridBox() const { return isDisplayFlexibleOrGridBox(display()); } + bool isDisplayRegionType() const; - bool setWritingMode(WritingMode v) - { - if (v == writingMode()) - return false; + bool setWritingMode(WritingMode); - inherited_flags.m_writingMode = v; - return true; - } + bool hasExplicitlySetWritingMode() const { return m_nonInheritedFlags.hasExplicitlySetWritingMode(); } + void setHasExplicitlySetWritingMode(bool v) { m_nonInheritedFlags.setHasExplicitlySetWritingMode(v); } + + bool hasExplicitlySetTextAlign() const { return m_nonInheritedFlags.hasExplicitlySetTextAlign(); } + void setHasExplicitlySetTextAlign(bool value) { m_nonInheritedFlags.setHasExplicitlySetTextAlign(value); } // A unique style is one that has matches something that makes it impossible to share. - bool unique() const { return noninherited_flags.unique; } - void setUnique() { noninherited_flags.unique = true; } + bool unique() const { return m_nonInheritedFlags.isUnique(); } + void setUnique() { m_nonInheritedFlags.setIsUnique(); } - bool emptyState() const { return noninherited_flags.emptyState; } - void setEmptyState(bool b) { setUnique(); noninherited_flags.emptyState = b; } - bool firstChildState() const { return noninherited_flags.firstChildState; } - void setFirstChildState() { setUnique(); noninherited_flags.firstChildState = true; } - bool lastChildState() const { return noninherited_flags.lastChildState; } - void setLastChildState() { setUnique(); noninherited_flags.lastChildState = true; } + bool emptyState() const { return m_nonInheritedFlags.emptyState(); } + void setEmptyState(bool b) { setUnique(); m_nonInheritedFlags.setEmptyState(b); } + bool firstChildState() const { return m_nonInheritedFlags.firstChildState(); } + void setFirstChildState() { setUnique(); m_nonInheritedFlags.setFirstChildState(true); } + bool lastChildState() const { return m_nonInheritedFlags.lastChildState(); } + void setLastChildState() { setUnique(); m_nonInheritedFlags.setLastChildState(true); } - Color visitedDependentColor(int colorProperty) const; + WEBCORE_EXPORT Color visitedDependentColor(int colorProperty) const; + bool backgroundColorEqualsToColorIgnoringVisited(const Color& color) const { return color == backgroundColor(); } - void setHasExplicitlyInheritedProperties() { noninherited_flags.explicitInheritance = true; } - bool hasExplicitlyInheritedProperties() const { return noninherited_flags.explicitInheritance; } + void setHasExplicitlyInheritedProperties() { m_nonInheritedFlags.setHasExplicitlyInheritedProperties(true); } + bool hasExplicitlyInheritedProperties() const { return m_nonInheritedFlags.hasExplicitlyInheritedProperties(); } // Initial values for all the properties + static EOverflow initialOverflowX() { return OVISIBLE; } + static EOverflow initialOverflowY() { return OVISIBLE; } + static EClear initialClear() { return CNONE; } + static EDisplay initialDisplay() { return INLINE; } + static EUnicodeBidi initialUnicodeBidi() { return UBNormal; } + static EPosition initialPosition() { return StaticPosition; } + static EVerticalAlign initialVerticalAlign() { return BASELINE; } + static EFloat initialFloating() { return NoFloat; } + static BreakBetween initialBreakBetween() { return AutoBreakBetween; } + static BreakInside initialBreakInside() { return AutoBreakInside; } + static HangingPunctuation initialHangingPunctuation() { return NoHangingPunctuation; } + static ETableLayout initialTableLayout() { return TAUTO; } static EBorderCollapse initialBorderCollapse() { return BSEPARATE; } static EBorderStyle initialBorderStyle() { return BNONE; } static OutlineIsAuto initialOutlineStyleIsAuto() { return AUTO_OFF; } static NinePieceImage initialNinePieceImage() { return NinePieceImage(); } - static LengthSize initialBorderRadius() { return LengthSize(Length(0, Fixed), Length(0, Fixed)); } + static LengthSize initialBorderRadius() { return { { 0, Fixed }, { 0, Fixed } }; } static ECaptionSide initialCaptionSide() { return CAPTOP; } - static EClear initialClear() { return CNONE; } - static ColorSpace initialColorSpace() { return ColorSpaceDeviceRGB; } static ColumnAxis initialColumnAxis() { return AutoColumnAxis; } static ColumnProgression initialColumnProgression() { return NormalColumnProgression; } static TextDirection initialDirection() { return LTR; } static WritingMode initialWritingMode() { return TopToBottomWritingMode; } static TextCombine initialTextCombine() { return TextCombineNone; } - static TextOrientation initialTextOrientation() { return TextOrientationVerticalRight; } + static TextOrientation initialTextOrientation() { return TextOrientation::Mixed; } static ObjectFit initialObjectFit() { return ObjectFitFill; } - static EDisplay initialDisplay() { return INLINE; } + static LengthPoint initialObjectPosition() { return LengthPoint(Length(50.0f, Percent), Length(50.0f, Percent)); } static EEmptyCell initialEmptyCells() { return SHOW; } - static EFloat initialFloating() { return NoFloat; } static EListStylePosition initialListStylePosition() { return OUTSIDE; } static EListStyleType initialListStyleType() { return Disc; } - static EOverflow initialOverflowX() { return OVISIBLE; } - static EOverflow initialOverflowY() { return OVISIBLE; } - static EPageBreak initialPageBreak() { return PBAUTO; } - static EPosition initialPosition() { return StaticPosition; } - static ETableLayout initialTableLayout() { return TAUTO; } - static EUnicodeBidi initialUnicodeBidi() { return UBNormal; } static ETextTransform initialTextTransform() { return TTNONE; } static EVisibility initialVisibility() { return VISIBLE; } static EWhiteSpace initialWhiteSpace() { return NORMAL; } - static short initialHorizontalBorderSpacing() { return 0; } - static short initialVerticalBorderSpacing() { return 0; } - static ECursor initialCursor() { return CURSOR_AUTO; } -#if ENABLE(CURSOR_VISIBILITY) - static CursorVisibility initialCursorVisibility() { return CursorVisibilityAuto; } -#endif + static float initialHorizontalBorderSpacing() { return 0; } + static float initialVerticalBorderSpacing() { return 0; } + static ECursor initialCursor() { return CursorAuto; } static Color initialColor() { return Color::black; } static StyleImage* initialListStyleImage() { return 0; } - static unsigned initialBorderWidth() { return 3; } + static float initialBorderWidth() { return 3; } static unsigned short initialColumnRuleWidth() { return 3; } - static unsigned short initialOutlineWidth() { return 3; } + static float initialOutlineWidth() { return 3; } static float initialLetterSpacing() { return 0; } static Length initialWordSpacing() { return Length(Fixed); } static Length initialSize() { return Length(); } - static Length initialMinSize() { return Length(Fixed); } + static Length initialMinSize() { return Length(); } static Length initialMaxSize() { return Length(Undefined); } static Length initialOffset() { return Length(); } static Length initialMargin() { return Length(Fixed); } static Length initialPadding() { return Length(Fixed); } static Length initialTextIndent() { return Length(Fixed); } -#if ENABLE(CSS3_TEXT) - static TextIndentLine initialTextIndentLine() { return TextIndentFirstLine; } - static TextIndentType initialTextIndentType() { return TextIndentNormal; } -#endif - static EVerticalAlign initialVerticalAlign() { return BASELINE; } + static Length initialZeroLength() { return Length(Fixed); } + static Length initialOneLength() { return Length(1, Fixed); } static short initialWidows() { return 2; } static short initialOrphans() { return 2; } - static Length initialLineHeight() { return Length(-100.0, Percent); } -#if ENABLE(IOS_TEXT_AUTOSIZING) - static Length initialSpecifiedLineHeight() { return Length(-100, Percent); } -#endif + static Length initialLineHeight() { return Length(-100.0f, Percent); } static ETextAlign initialTextAlign() { return TASTART; } static TextDecoration initialTextDecoration() { return TextDecorationNone; } -#if ENABLE(CSS3_TEXT) - static TextAlignLast initialTextAlignLast() { return TextAlignLastAuto; } - static TextJustify initialTextJustify() { return TextJustifyAuto; } -#endif // CSS3_TEXT static TextDecorationStyle initialTextDecorationStyle() { return TextDecorationStyleSolid; } - static TextDecorationSkip initialTextDecorationSkip() { return TextDecorationSkipInk; } + static TextDecorationSkip initialTextDecorationSkip() { return TextDecorationSkipAuto; } static TextUnderlinePosition initialTextUnderlinePosition() { return TextUnderlinePositionAuto; } static float initialZoom() { return 1.0f; } - static int initialOutlineOffset() { return 0; } + static TextZoom initialTextZoom() { return TextZoomNormal; } + static float initialOutlineOffset() { return 0; } static float initialOpacity() { return 1.0f; } static EBoxAlignment initialBoxAlign() { return BSTRETCH; } static EBoxDecorationBreak initialBoxDecorationBreak() { return DSLICE; } @@ -1695,20 +1461,19 @@ public: static EBoxOrient initialBoxOrient() { return HORIZONTAL; } static EBoxPack initialBoxPack() { return Start; } static float initialBoxFlex() { return 0.0f; } - static unsigned int initialBoxFlexGroup() { return 1; } - static unsigned int initialBoxOrdinalGroup() { return 1; } + static unsigned initialBoxFlexGroup() { return 1; } + static unsigned initialBoxOrdinalGroup() { return 1; } static EBoxSizing initialBoxSizing() { return CONTENT_BOX; } static StyleReflection* initialBoxReflect() { return 0; } static float initialFlexGrow() { return 0; } static float initialFlexShrink() { return 1; } static Length initialFlexBasis() { return Length(Auto); } static int initialOrder() { return 0; } - static EAlignContent initialAlignContent() { return AlignContentStretch; } - static EAlignItems initialAlignItems() { return AlignStretch; } - static EAlignItems initialAlignSelf() { return AlignAuto; } + static StyleSelfAlignmentData initialSelfAlignment() { return StyleSelfAlignmentData(ItemPositionAuto, OverflowAlignmentDefault); } + static StyleSelfAlignmentData initialDefaultAlignment() { return StyleSelfAlignmentData(isCSSGridLayoutEnabled() ? ItemPositionNormal : ItemPositionStretch, OverflowAlignmentDefault); } + static StyleContentAlignmentData initialContentAlignment() { return StyleContentAlignmentData(ContentPositionNormal, ContentDistributionDefault, OverflowAlignmentDefault); } static EFlexDirection initialFlexDirection() { return FlowRow; } static EFlexWrap initialFlexWrap() { return FlexNoWrap; } - static EJustifyContent initialJustifyContent() { return JustifyFlexStart; } static int initialMarqueeLoopCount() { return -1; } static int initialMarqueeSpeed() { return 85; } static Length initialMarqueeIncrement() { return Length(6, Fixed); } @@ -1724,18 +1489,16 @@ public: static EOverflowWrap initialOverflowWrap() { return NormalOverflowWrap; } static ENBSPMode initialNBSPMode() { return NBNORMAL; } static LineBreak initialLineBreak() { return LineBreakAuto; } - static const AtomicString& initialHighlight() { return nullAtom; } static ESpeak initialSpeak() { return SpeakNormal; } static Hyphens initialHyphens() { return HyphensManual; } static short initialHyphenationLimitBefore() { return -1; } static short initialHyphenationLimitAfter() { return -1; } static short initialHyphenationLimitLines() { return -1; } static const AtomicString& initialHyphenationString() { return nullAtom; } - static const AtomicString& initialLocale() { return nullAtom; } static EBorderFit initialBorderFit() { return BorderFitBorder; } static EResize initialResize() { return RESIZE_NONE; } static ControlPart initialAppearance() { return NoControlPart; } - static bool initialHasAspectRatio() { return false; } + static AspectRatioType initialAspectRatioType() { return AspectRatioAuto; } static float initialAspectRatioDenominator() { return 1; } static float initialAspectRatioNumerator() { return 1; } static Order initialRTLOrdering() { return LogicalOrder; } @@ -1743,16 +1506,16 @@ public: static unsigned short initialColumnCount() { return 1; } static ColumnFill initialColumnFill() { return ColumnFillBalance; } static ColumnSpan initialColumnSpan() { return ColumnSpanNone; } - static const TransformOperations& initialTransform() { DEFINE_STATIC_LOCAL(TransformOperations, ops, ()); return ops; } - static Length initialTransformOriginX() { return Length(50.0, Percent); } - static Length initialTransformOriginY() { return Length(50.0, Percent); } + static const TransformOperations& initialTransform() { static NeverDestroyed<TransformOperations> ops; return ops; } + static Length initialTransformOriginX() { return Length(50.0f, Percent); } + static Length initialTransformOriginY() { return Length(50.0f, Percent); } static EPointerEvents initialPointerEvents() { return PE_AUTO; } static float initialTransformOriginZ() { return 0; } static ETransformStyle3D initialTransformStyle3D() { return TransformStyle3DFlat; } static EBackfaceVisibility initialBackfaceVisibility() { return BackfaceVisibilityVisible; } static float initialPerspective() { return 0; } - static Length initialPerspectiveOriginX() { return Length(50.0, Percent); } - static Length initialPerspectiveOriginY() { return Length(50.0, Percent); } + static Length initialPerspectiveOriginX() { return Length(50.0f, Percent); } + static Length initialPerspectiveOriginY() { return Length(50.0f, Percent); } static Color initialBackgroundColor() { return Color::transparent; } static Color initialTextEmphasisColor() { return TextEmphasisFillFilled; } static TextEmphasisFill initialTextEmphasisFill() { return TextEmphasisFillFilled; } @@ -1766,18 +1529,64 @@ public: static ImageResolutionSource initialImageResolutionSource() { return ImageResolutionSpecified; } static ImageResolutionSnap initialImageResolutionSnap() { return ImageResolutionNoSnap; } static float initialImageResolution() { return 1; } - static StyleImage* initialBorderImageSource() { return 0; } - static StyleImage* initialMaskBoxImageSource() { return 0; } + static StyleImage* initialBorderImageSource() { return nullptr; } + static StyleImage* initialMaskBoxImageSource() { return nullptr; } static PrintColorAdjust initialPrintColorAdjust() { return PrintColorAdjustEconomy; } + static QuotesData* initialQuotes() { return nullptr; } + static const AtomicString& initialContentAltText() { return emptyAtom; } + +#if ENABLE(CSS3_TEXT) + static TextIndentLine initialTextIndentLine() { return TextIndentFirstLine; } + static TextIndentType initialTextIndentType() { return TextIndentNormal; } + static TextAlignLast initialTextAlignLast() { return TextAlignLastAuto; } + static TextJustify initialTextJustify() { return TextJustifyAuto; } +#endif + +#if ENABLE(CURSOR_VISIBILITY) + static CursorVisibility initialCursorVisibility() { return CursorVisibilityAuto; } +#endif + +#if ENABLE(TEXT_AUTOSIZING) + static Length initialSpecifiedLineHeight() { return Length(-100.0f, Percent); } + static TextSizeAdjustment initialTextSizeAdjust() { return TextSizeAdjustment(); } +#endif + + static bool isCSSGridLayoutEnabled(); + + static WillChangeData* initialWillChange() { return nullptr; } + +#if ENABLE(TOUCH_EVENTS) + static TouchAction initialTouchAction() { return TouchAction::Auto; } +#endif + +#if ENABLE(CSS_SCROLL_SNAP) + static ScrollSnapType initialScrollSnapType(); + static ScrollSnapAlign initialScrollSnapAlign(); + static Length initialScrollSnapMargin() { return Length(Fixed); } + static Length initialScrollPadding() { return Length(Fixed); } +#endif + +#if ENABLE(CSS_TRAILING_WORD) + static TrailingWord initialTrailingWord() { return TrailingWord::Auto; } +#endif + +#if ENABLE(APPLE_PAY) + static ApplePayButtonStyle initialApplePayButtonStyle() { return ApplePayButtonStyle::Black; } + static ApplePayButtonType initialApplePayButtonType() { return ApplePayButtonType::Plain; } +#endif // The initial value is 'none' for grid tracks. static Vector<GridTrackSize> initialGridColumns() { return Vector<GridTrackSize>(); } static Vector<GridTrackSize> initialGridRows() { return Vector<GridTrackSize>(); } - static GridAutoFlow initialGridAutoFlow() { return AutoFlowNone; } + static Vector<GridTrackSize> initialGridAutoRepeatTracks() { return Vector<GridTrackSize>(); } + static unsigned initialGridAutoRepeatInsertionPoint() { return 0; } + static AutoRepeatType initialGridAutoRepeatType() { return NoAutoRepeat; } - static GridTrackSize initialGridAutoColumns() { return GridTrackSize(Auto); } - static GridTrackSize initialGridAutoRows() { return GridTrackSize(Auto); } + static GridAutoFlow initialGridAutoFlow() { return AutoFlowRow; } + + static Vector<GridTrackSize> initialGridAutoColumns() { return { GridTrackSize(Length(Auto)) }; } + static Vector<GridTrackSize> initialGridAutoRows() { return { GridTrackSize(Length(Auto)) }; } static NamedGridAreaMap initialNamedGridArea() { return NamedGridAreaMap(); } static size_t initialNamedGridAreaCount() { return 0; } @@ -1785,6 +1594,12 @@ public: static NamedGridLinesMap initialNamedGridColumnLines() { return NamedGridLinesMap(); } static NamedGridLinesMap initialNamedGridRowLines() { return NamedGridLinesMap(); } + static OrderedNamedGridLinesMap initialOrderedNamedGridColumnLines() { return OrderedNamedGridLinesMap(); } + static OrderedNamedGridLinesMap initialOrderedNamedGridRowLines() { return OrderedNamedGridLinesMap(); } + + static Length initialGridColumnGap() { return Length(Fixed); } + static Length initialGridRowGap() { return Length(Fixed); } + // 'auto' is the default. static GridPosition initialGridItemColumnStart() { return GridPosition(); } static GridPosition initialGridItemColumnEnd() { return GridPosition(); } @@ -1801,120 +1616,476 @@ public: static const AtomicString& initialRegionThread() { return nullAtom; } static RegionFragment initialRegionFragment() { return AutoRegionFragment; } - static WrapFlow initialWrapFlow() { return WrapFlowAuto; } - static WrapThrough initialWrapThrough() { return WrapThroughWrap; } - - // Keep these at the end. + static IntSize initialInitialLetter() { return IntSize(); } static LineClampValue initialLineClamp() { return LineClampValue(); } static ETextSecurity initialTextSecurity() { return TSNONE; } -#if ENABLE(IOS_TEXT_AUTOSIZING) - static TextSizeAdjustment initialTextSizeAdjust() { return TextSizeAdjustment(); } -#endif + #if PLATFORM(IOS) static bool initialTouchCalloutEnabled() { return true; } - static Color initialCompositionFillColor() { return Color::compositionFill; } #endif + #if ENABLE(TOUCH_EVENTS) static Color initialTapHighlightColor(); #endif + #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) static bool initialUseTouchOverflowScrolling() { return false; } #endif + #if ENABLE(DASHBOARD_SUPPORT) static const Vector<StyleDashboardRegion>& initialDashboardRegions(); static const Vector<StyleDashboardRegion>& noneDashboardRegions(); #endif -#if ENABLE(CSS_FILTERS) - static const FilterOperations& initialFilter() { DEFINE_STATIC_LOCAL(FilterOperations, ops, ()); return ops; } + + static const FilterOperations& initialFilter() { static NeverDestroyed<FilterOperations> ops; return ops; } + +#if ENABLE(FILTERS_LEVEL_2) + static const FilterOperations& initialBackdropFilter() { static NeverDestroyed<FilterOperations> ops; return ops; } #endif + #if ENABLE(CSS_COMPOSITING) static BlendMode initialBlendMode() { return BlendModeNormal; } + static Isolation initialIsolation() { return IsolationAuto; } #endif -private: - bool changeRequiresLayout(const RenderStyle*, unsigned& changedContextSensitiveProperties) const; - bool changeRequiresPositionedLayoutOnly(const RenderStyle*, unsigned& changedContextSensitiveProperties) const; - bool changeRequiresLayerRepaint(const RenderStyle*, unsigned& changedContextSensitiveProperties) const; - bool changeRequiresRepaint(const RenderStyle*, unsigned& changedContextSensitiveProperties) const; - bool changeRequiresRepaintIfTextOrBorderOrOutline(const RenderStyle*, unsigned& changedContextSensitiveProperties) const; - bool changeRequiresRecompositeLayer(const RenderStyle*, unsigned& changedContextSensitiveProperties) const; + bool isPlaceholderStyle() const { return m_rareNonInheritedData->isPlaceholderStyle; } + void setIsPlaceholderStyle() { SET_VAR(m_rareNonInheritedData, isPlaceholderStyle, true); } void setVisitedLinkColor(const Color&); - void setVisitedLinkBackgroundColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBackgroundColor, v); } - void setVisitedLinkBorderLeftColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderLeftColor, v); } - void setVisitedLinkBorderRightColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderRightColor, v); } - void setVisitedLinkBorderBottomColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderBottomColor, v); } - void setVisitedLinkBorderTopColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderTopColor, v); } - void setVisitedLinkOutlineColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkOutlineColor, v); } - void setVisitedLinkColumnRuleColor(const Color& v) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_visitedLinkColumnRuleColor, v); } - void setVisitedLinkTextDecorationColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkTextDecorationColor, v); } - void setVisitedLinkTextEmphasisColor(const Color& v) { SET_VAR(rareInheritedData, visitedLinkTextEmphasisColor, v); } - void setVisitedLinkTextFillColor(const Color& v) { SET_VAR(rareInheritedData, visitedLinkTextFillColor, v); } - void setVisitedLinkTextStrokeColor(const Color& v) { SET_VAR(rareInheritedData, visitedLinkTextStrokeColor, v); } - - void inheritUnicodeBidiFrom(const RenderStyle* parent) { noninherited_flags._unicodeBidi = parent->noninherited_flags._unicodeBidi; } + void setVisitedLinkBackgroundColor(const Color& v) { SET_VAR(m_rareNonInheritedData, visitedLinkBackgroundColor, v); } + void setVisitedLinkBorderLeftColor(const Color& v) { SET_VAR(m_rareNonInheritedData, visitedLinkBorderLeftColor, v); } + void setVisitedLinkBorderRightColor(const Color& v) { SET_VAR(m_rareNonInheritedData, visitedLinkBorderRightColor, v); } + void setVisitedLinkBorderBottomColor(const Color& v) { SET_VAR(m_rareNonInheritedData, visitedLinkBorderBottomColor, v); } + void setVisitedLinkBorderTopColor(const Color& v) { SET_VAR(m_rareNonInheritedData, visitedLinkBorderTopColor, v); } + void setVisitedLinkOutlineColor(const Color& v) { SET_VAR(m_rareNonInheritedData, visitedLinkOutlineColor, v); } + void setVisitedLinkColumnRuleColor(const Color& v) { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, visitedLinkColumnRuleColor, v); } + void setVisitedLinkTextDecorationColor(const Color& v) { SET_VAR(m_rareNonInheritedData, visitedLinkTextDecorationColor, v); } + void setVisitedLinkTextEmphasisColor(const Color& v) { SET_VAR(m_rareInheritedData, visitedLinkTextEmphasisColor, v); } + void setVisitedLinkTextFillColor(const Color& v) { SET_VAR(m_rareInheritedData, visitedLinkTextFillColor, v); } + void setVisitedLinkTextStrokeColor(const Color& v) { SET_VAR(m_rareInheritedData, visitedLinkTextStrokeColor, v); } + + void inheritUnicodeBidiFrom(const RenderStyle* parent) { m_nonInheritedFlags.setUnicodeBidi(parent->m_nonInheritedFlags.unicodeBidi()); } void getShadowExtent(const ShadowData*, LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left) const; - LayoutBoxExtent getShadowInsetExtent(const ShadowData*) const; void getShadowHorizontalExtent(const ShadowData*, LayoutUnit& left, LayoutUnit& right) const; void getShadowVerticalExtent(const ShadowData*, LayoutUnit& top, LayoutUnit& bottom) const; - void getShadowInlineDirectionExtent(const ShadowData* shadow, LayoutUnit& logicalLeft, LayoutUnit& logicalRight) const - { - return isHorizontalWritingMode() ? getShadowHorizontalExtent(shadow, logicalLeft, logicalRight) : getShadowVerticalExtent(shadow, logicalLeft, logicalRight); - } - void getShadowBlockDirectionExtent(const ShadowData* shadow, LayoutUnit& logicalTop, LayoutUnit& logicalBottom) const - { - return isHorizontalWritingMode() ? getShadowVerticalExtent(shadow, logicalTop, logicalBottom) : getShadowHorizontalExtent(shadow, logicalTop, logicalBottom); - } + void getShadowInlineDirectionExtent(const ShadowData*, LayoutUnit& logicalLeft, LayoutUnit& logicalRight) const; + void getShadowBlockDirectionExtent(const ShadowData*, LayoutUnit& logicalTop, LayoutUnit& logicalBottom) const; + + static Color invalidColor() { return Color(); } + const Color& borderLeftColor() const { return m_surroundData->border.left().color(); } + const Color& borderRightColor() const { return m_surroundData->border.right().color(); } + const Color& borderTopColor() const { return m_surroundData->border.top().color(); } + const Color& borderBottomColor() const { return m_surroundData->border.bottom().color(); } + const Color& backgroundColor() const { return m_backgroundData->color; } + const Color& color() const; + const Color& columnRuleColor() const { return m_rareNonInheritedData->multiCol->rule.color(); } + const Color& outlineColor() const { return m_backgroundData->outline.color(); } + const Color& textEmphasisColor() const { return m_rareInheritedData->textEmphasisColor; } + const Color& textFillColor() const { return m_rareInheritedData->textFillColor; } + const Color& textStrokeColor() const { return m_rareInheritedData->textStrokeColor; } + const Color& visitedLinkColor() const; + const Color& visitedLinkBackgroundColor() const { return m_rareNonInheritedData->visitedLinkBackgroundColor; } + const Color& visitedLinkBorderLeftColor() const { return m_rareNonInheritedData->visitedLinkBorderLeftColor; } + const Color& visitedLinkBorderRightColor() const { return m_rareNonInheritedData->visitedLinkBorderRightColor; } + const Color& visitedLinkBorderBottomColor() const { return m_rareNonInheritedData->visitedLinkBorderBottomColor; } + const Color& visitedLinkBorderTopColor() const { return m_rareNonInheritedData->visitedLinkBorderTopColor; } + const Color& visitedLinkOutlineColor() const { return m_rareNonInheritedData->visitedLinkOutlineColor; } + const Color& visitedLinkColumnRuleColor() const { return m_rareNonInheritedData->multiCol->visitedLinkColumnRuleColor; } + const Color& textDecorationColor() const { return m_rareNonInheritedData->textDecorationColor; } + const Color& visitedLinkTextDecorationColor() const { return m_rareNonInheritedData->visitedLinkTextDecorationColor; } + const Color& visitedLinkTextEmphasisColor() const { return m_rareInheritedData->visitedLinkTextEmphasisColor; } + const Color& visitedLinkTextFillColor() const { return m_rareInheritedData->visitedLinkTextFillColor; } + const Color& visitedLinkTextStrokeColor() const { return m_rareInheritedData->visitedLinkTextStrokeColor; } + + const Color& stopColor() const { return svgStyle().stopColor(); } + const Color& floodColor() const { return svgStyle().floodColor(); } + const Color& lightingColor() const { return svgStyle().lightingColor(); } - bool isDisplayReplacedType(EDisplay display) const - { - return display == INLINE_BLOCK || display == INLINE_BOX || display == INLINE_FLEX - || display == INLINE_TABLE || display == INLINE_GRID; - } +private: + struct NonInheritedFlags { + NonInheritedFlags(); - bool isDisplayInlineType(EDisplay display) const - { - return display == INLINE || isDisplayReplacedType(display); - } + bool operator==(const NonInheritedFlags& other) const { return m_flags == other.m_flags; } + bool operator!=(const NonInheritedFlags& other) const { return m_flags != other.m_flags; } - // Color accessors are all private to make sure callers use visitedDependentColor instead to access them. - Color invalidColor() const { static Color invalid; return invalid; } - Color borderLeftColor() const { return surround->border.left().color(); } - Color borderRightColor() const { return surround->border.right().color(); } - Color borderTopColor() const { return surround->border.top().color(); } - Color borderBottomColor() const { return surround->border.bottom().color(); } - Color backgroundColor() const { return m_background->color(); } - Color color() const; - Color columnRuleColor() const { return rareNonInheritedData->m_multiCol->m_rule.color(); } - Color outlineColor() const { return m_background->outline().color(); } - Color textEmphasisColor() const { return rareInheritedData->textEmphasisColor; } - Color textFillColor() const { return rareInheritedData->textFillColor; } - Color textStrokeColor() const { return rareInheritedData->textStrokeColor; } - Color visitedLinkColor() const; - Color visitedLinkBackgroundColor() const { return rareNonInheritedData->m_visitedLinkBackgroundColor; } - Color visitedLinkBorderLeftColor() const { return rareNonInheritedData->m_visitedLinkBorderLeftColor; } - Color visitedLinkBorderRightColor() const { return rareNonInheritedData->m_visitedLinkBorderRightColor; } - Color visitedLinkBorderBottomColor() const { return rareNonInheritedData->m_visitedLinkBorderBottomColor; } - Color visitedLinkBorderTopColor() const { return rareNonInheritedData->m_visitedLinkBorderTopColor; } - Color visitedLinkOutlineColor() const { return rareNonInheritedData->m_visitedLinkOutlineColor; } - Color visitedLinkColumnRuleColor() const { return rareNonInheritedData->m_multiCol->m_visitedLinkColumnRuleColor; } - Color textDecorationColor() const { return rareNonInheritedData->m_textDecorationColor; } - Color visitedLinkTextDecorationColor() const { return rareNonInheritedData->m_visitedLinkTextDecorationColor; } - Color visitedLinkTextEmphasisColor() const { return rareInheritedData->visitedLinkTextEmphasisColor; } - Color visitedLinkTextFillColor() const { return rareInheritedData->visitedLinkTextFillColor; } - Color visitedLinkTextStrokeColor() const { return rareInheritedData->visitedLinkTextStrokeColor; } + void copyNonInheritedFrom(const NonInheritedFlags&); - Color colorIncludingFallback(int colorProperty, bool visitedLink) const; + EOverflow overflowX() const { return static_cast<EOverflow>(getValue(overflowMask, overflowXOffset)); } + void setOverflowX(EOverflow overflowX) { updateValue(overflowX, overflowMask, overflowXOffset); } + + EOverflow overflowY() const { return static_cast<EOverflow>(getValue(overflowMask, overflowYOffset)); } + void setOverflowY(EOverflow overflowY) { updateValue(overflowY, overflowMask, overflowYOffset); } + + EClear clear() const { return static_cast<EClear>(getValue(clearMask, clearOffset)); } + void setClear(EClear clear) { updateValue(clear, clearMask, clearOffset); } + + EDisplay effectiveDisplay() const { return static_cast<EDisplay>(getValue(displayMask, effectiveDisplayOffset)); } + void setEffectiveDisplay(EDisplay effectiveDisplay) { updateValue(effectiveDisplay, displayMask, effectiveDisplayOffset); } -#if ENABLE(SVG) - Color stopColor() const { return svgStyle().stopColor(); } - Color floodColor() const { return svgStyle().floodColor(); } - Color lightingColor() const { return svgStyle().lightingColor(); } + EPosition position() const { return static_cast<EPosition>(getValue(positionMask, positionOffset)); } + void setPosition(EPosition position) { updateValue(position, positionMask, positionOffset); } + + EDisplay originalDisplay() const { return static_cast<EDisplay>(getValue(displayMask, originalDisplayOffset)); } + void setOriginalDisplay(EDisplay originalDisplay) { updateValue(originalDisplay, displayMask, originalDisplayOffset); } + + EUnicodeBidi unicodeBidi() const { return static_cast<EUnicodeBidi>(getValue(unicodeBidiMask, unicodeBidiOffset)); } + void setUnicodeBidi(EUnicodeBidi unicodeBidi) { updateValue(unicodeBidi, unicodeBidiMask, unicodeBidiOffset); } + + bool hasViewportUnits() const { return getBoolean(hasViewportUnitsOffset); } + void setHasViewportUnits(bool value) { updateBoolean(value, hasViewportUnitsOffset); } + + EVerticalAlign verticalAlign() const { return static_cast<EVerticalAlign>(getValue(verticalAlignMask, verticalAlignOffset)); } + void setVerticalAlign(EVerticalAlign verticalAlign) { updateValue(verticalAlign, verticalAlignMask, verticalAlignOffset); } + + bool hasExplicitlyInheritedProperties() const { return getBoolean(explicitInheritanceOffset); } + void setHasExplicitlyInheritedProperties(bool value) { updateBoolean(value, explicitInheritanceOffset); } + + bool isFloating() const { return floating() != NoFloat; } + EFloat floating() const { return static_cast<EFloat>(getValue(floatingMask, floatingOffset)); } + void setFloating(EFloat floating) { updateValue(floating, floatingMask, floatingOffset); } + + bool hasAnyPublicPseudoStyles() const { return PUBLIC_PSEUDOID_MASK & getValue(pseudoBitsMask, pseudoBitsOffset); } + bool hasPseudoStyle(PseudoId) const; + void setHasPseudoStyle(PseudoId); + void setHasPseudoStyles(PseudoIdSet); + + ETableLayout tableLayout() const { return static_cast<ETableLayout>(getValue(tableLayoutBitMask, tableLayoutOffset)); } + void setTableLayout(ETableLayout tableLayout) { updateValue(tableLayout, tableLayoutBitMask, tableLayoutOffset); } + + PseudoId styleType() const { return static_cast<PseudoId>(getValue(styleTypeMask, styleTypeOffset)); } + void setStyleType(PseudoId styleType) { updateValue(styleType, styleTypeMask, styleTypeOffset); } + + bool isUnique() const { return getBoolean(isUniqueOffset); } + void setIsUnique() { updateBoolean(true, isUniqueOffset); } + + bool emptyState() const { return getBoolean(emptyStateOffset); } + void setEmptyState(bool value) { updateBoolean(value, emptyStateOffset); } + + bool firstChildState() const { return getBoolean(firstChildStateOffset); } + void setFirstChildState(bool value) { updateBoolean(value, firstChildStateOffset); } + + bool lastChildState() const { return getBoolean(lastChildStateOffset); } + void setLastChildState(bool value) { updateBoolean(value, lastChildStateOffset); } + + bool affectedByHover() const { return getBoolean(affectedByHoverOffset); } + void setAffectedByHover(bool value) { updateBoolean(value, affectedByHoverOffset); } + + bool affectedByActive() const { return getBoolean(affectedByActiveOffset); } + void setAffectedByActive(bool value) { updateBoolean(value, affectedByActiveOffset); } + + bool affectedByDrag() const { return getBoolean(affectedByDragOffset); } + void setAffectedByDrag(bool value) { updateBoolean(value, affectedByDragOffset); } + + bool isLink() const { return getBoolean(isLinkOffset); } + void setIsLink(bool value) { updateBoolean(value, isLinkOffset); } + + bool hasExplicitlySetDirection() const { return getBoolean(hasExplicitlySetDirectionOffset); } + void setHasExplicitlySetDirection(bool value) { updateBoolean(value, hasExplicitlySetDirectionOffset); } + + bool hasExplicitlySetWritingMode() const { return getBoolean(hasExplicitlySetWritingModeOffset); } + void setHasExplicitlySetWritingMode(bool value) { updateBoolean(value, hasExplicitlySetWritingModeOffset); } + + bool hasExplicitlySetTextAlign() const { return getBoolean(hasExplicitlySetTextAlignOffset); } + void setHasExplicitlySetTextAlign(bool value) { updateBoolean(value, hasExplicitlySetTextAlignOffset); } + + static ptrdiff_t flagsMemoryOffset() { return OBJECT_OFFSETOF(NonInheritedFlags, m_flags); } + static uint64_t flagIsaffectedByActive() { return oneBitMask << affectedByActiveOffset; } + static uint64_t flagIsaffectedByHover() { return oneBitMask << affectedByHoverOffset; } + static uint64_t flagPseudoStyle(PseudoId pseudo) { return oneBitMask << (pseudoBitsOffset - 1 + pseudo); } + static uint64_t setFirstChildStateFlags() { return flagFirstChildState() | flagIsUnique(); } + static uint64_t setLastChildStateFlags() { return flagLastChildState() | flagIsUnique(); } + + private: + void updateBoolean(bool, uint64_t offset); + bool getBoolean(uint64_t offset) const; + void updateValue(uint8_t newValue, uint64_t positionIndependentMask, uint64_t offset); + unsigned getValue(uint64_t positionIndependentMask, uint64_t offset) const; + + static uint64_t flagIsUnique() { return oneBitMask << isUniqueOffset; } + static uint64_t flagFirstChildState() { return oneBitMask << firstChildStateOffset; } + static uint64_t flagLastChildState() { return oneBitMask << lastChildStateOffset; } + + // To type the bit mask properly on 64bits. + static const uint64_t oneBitMask = 0x1; + + // Byte 1. + static const unsigned overflowBitCount = 3; + static const uint64_t overflowMask = (oneBitMask << overflowBitCount) - 1; + static const unsigned overflowXOffset = 0; + static const unsigned overflowYOffset = overflowXOffset + overflowBitCount; + static const unsigned clearBitCount = 2; + static const uint64_t clearMask = (oneBitMask << clearBitCount) - 1; + static const unsigned clearOffset = overflowYOffset + overflowBitCount; + + // Byte 2. + static const unsigned displayBitCount = 5; + static const uint64_t displayMask = (oneBitMask << displayBitCount) - 1; + static const unsigned effectiveDisplayOffset = clearOffset + clearBitCount; + static const unsigned positionBitCount = 3; + static const uint64_t positionMask = (oneBitMask << positionBitCount) - 1; + static const unsigned positionOffset = effectiveDisplayOffset + displayBitCount; + + // Byte 3. + static const unsigned originalDisplayOffset = positionOffset + positionBitCount; + static const unsigned unicodeBidiBitCount = 3; + static const uint64_t unicodeBidiMask = (oneBitMask << unicodeBidiBitCount) - 1; + static const unsigned unicodeBidiOffset = originalDisplayOffset + displayBitCount; + + // Byte 4. + static const unsigned floatingBitCount = 2; + static const uint64_t floatingMask = (oneBitMask << floatingBitCount) - 1; + static const unsigned floatingOffset = unicodeBidiOffset + unicodeBidiBitCount; + static const unsigned hasExplicitlySetDirectionBitcount = 1; + static const unsigned hasExplicitlySetDirectionOffset = floatingOffset + floatingBitCount; + static const unsigned hasExplicitlySetWritingModeBitcount = 1; + static const unsigned hasExplicitlySetWritingModeOffset = hasExplicitlySetDirectionOffset + hasExplicitlySetDirectionBitcount; + + // Byte 5. + static const unsigned explicitInheritanceBitCount = 1; + static const unsigned explicitInheritanceOffset = hasExplicitlySetWritingModeOffset + hasExplicitlySetWritingModeBitcount; + static const unsigned tableLayoutBitCount = 1; + static const uint64_t tableLayoutBitMask = oneBitMask; + static const unsigned tableLayoutOffset = explicitInheritanceOffset + explicitInheritanceBitCount; + static const unsigned verticalAlignBitCount = 4; + static const unsigned verticalAlignPadding = 2; + static const unsigned verticalAlignAndPaddingBitCount = verticalAlignBitCount + verticalAlignPadding; + static const uint64_t verticalAlignMask = (oneBitMask << verticalAlignBitCount) - 1; + static const unsigned verticalAlignOffset = tableLayoutOffset + tableLayoutBitCount; + + // Byte 6. + static const unsigned pseudoBitsBitCount = 7; + static const uint64_t pseudoBitsMask = (oneBitMask << pseudoBitsBitCount) - 1; + static const unsigned pseudoBitsOffset = verticalAlignOffset + verticalAlignBitCount; + + static const unsigned hasViewportUnitsBitCount = 1; + static const uint64_t hasViewportUnitsBitMask = (oneBitMask << hasViewportUnitsBitCount) - 1; + static const unsigned hasViewportUnitsOffset = pseudoBitsOffset + pseudoBitsBitCount; + + // Byte 7. + static const unsigned hasExplicitlySetTextAlignBitCount = 1; + static const unsigned hasExplicitlySetTextAlignOffset = hasViewportUnitsOffset + hasViewportUnitsBitCount; + static const unsigned styleTypeBitCount = 6; + static const unsigned styleTypePadding = 1; + static const unsigned styleTypeAndPaddingBitCount = styleTypeBitCount + styleTypePadding; + static const uint64_t styleTypeMask = (oneBitMask << styleTypeAndPaddingBitCount) - 1; + static const unsigned styleTypeOffset = hasExplicitlySetTextAlignOffset + hasExplicitlySetTextAlignBitCount; + + // Byte 8. + static const unsigned isUniqueOffset = styleTypeOffset + styleTypeAndPaddingBitCount; + static const unsigned emptyStateOffset = isUniqueOffset + 1; + static const unsigned firstChildStateOffset = emptyStateOffset + 1; + static const unsigned lastChildStateOffset = firstChildStateOffset + 1; + static const unsigned affectedByHoverOffset = lastChildStateOffset + 1; + static const unsigned affectedByActiveOffset = affectedByHoverOffset + 1; + static const unsigned affectedByDragOffset = affectedByActiveOffset + 1; + static const unsigned isLinkOffset = affectedByDragOffset + 1; + + // 60 bits are assigned. There are 4 bits available currently used as padding to improve code generation. + // If you add more style bits here, you will also need to update RenderStyle::copyNonInheritedFrom(). + uint64_t m_flags { 0 }; + }; + + struct InheritedFlags { + bool operator==(const InheritedFlags&) const; + bool operator!=(const InheritedFlags& other) const { return !(*this == other); } + + unsigned emptyCells : 1; // EEmptyCell + unsigned captionSide : 2; // ECaptionSide + unsigned listStyleType : 7; // EListStyleType + unsigned listStylePosition : 1; // EListStylePosition + unsigned visibility : 2; // EVisibility + unsigned textAlign : 4; // ETextAlign + unsigned textTransform : 2; // ETextTransform + unsigned textDecorations : TextDecorationBits; + unsigned cursor : 6; // ECursor +#if ENABLE(CURSOR_VISIBILITY) + unsigned cursorVisibility : 1; // CursorVisibility #endif + unsigned direction : 1; // TextDirection + unsigned whiteSpace : 3; // EWhiteSpace + // 32 bits + unsigned borderCollapse : 1; // EBorderCollapse + unsigned boxDirection : 1; // EBoxDirection (CSS3 box_direction property, flexible box layout module) - void appendContent(std::unique_ptr<ContentData>); + // non CSS2 inherited + unsigned rtlOrdering : 1; // Order + unsigned printColorAdjust : PrintColorAdjustBits; + unsigned pointerEvents : 4; // EPointerEvents + unsigned insideLink : 2; // EInsideLink + unsigned insideDefaultButton : 1; + // 44 bits + + // CSS Text Layout Module Level 3: Vertical writing support + unsigned writingMode : 2; // WritingMode + // 46 bits + }; + + // This constructor is used to implement the replace operation. + RenderStyle(RenderStyle&, RenderStyle&&); + + EDisplay originalDisplay() const { return m_nonInheritedFlags.originalDisplay(); } + + bool hasAutoLeftAndRight() const { return left().isAuto() && right().isAuto(); } + bool hasAutoTopAndBottom() const { return top().isAuto() && bottom().isAuto(); } + + void setContent(std::unique_ptr<ContentData>, bool add); + + LayoutBoxExtent getShadowInsetExtent(const ShadowData*) const; + + static bool isDisplayReplacedType(EDisplay); + static bool isDisplayInlineType(EDisplay); + static bool isDisplayFlexibleBox(EDisplay); + static bool isDisplayGridBox(EDisplay); + static bool isDisplayFlexibleOrGridBox(EDisplay); + + Color colorIncludingFallback(int colorProperty, bool visitedLink) const; + + bool changeAffectsVisualOverflow(const RenderStyle&) const; + bool changeRequiresLayout(const RenderStyle&, unsigned& changedContextSensitiveProperties) const; + bool changeRequiresPositionedLayoutOnly(const RenderStyle&, unsigned& changedContextSensitiveProperties) const; + bool changeRequiresLayerRepaint(const RenderStyle&, unsigned& changedContextSensitiveProperties) const; + bool changeRequiresRepaint(const RenderStyle&, unsigned& changedContextSensitiveProperties) const; + bool changeRequiresRepaintIfTextOrBorderOrOutline(const RenderStyle&, unsigned& changedContextSensitiveProperties) const; + bool changeRequiresRecompositeLayer(const RenderStyle&, unsigned& changedContextSensitiveProperties) const; + + // non-inherited attributes + DataRef<StyleBoxData> m_boxData; + DataRef<StyleVisualData> m_visualData; + DataRef<StyleBackgroundData> m_backgroundData; + DataRef<StyleSurroundData> m_surroundData; + DataRef<StyleRareNonInheritedData> m_rareNonInheritedData; + NonInheritedFlags m_nonInheritedFlags; + + // inherited attributes + DataRef<StyleRareInheritedData> m_rareInheritedData; + DataRef<StyleInheritedData> m_inheritedData; + InheritedFlags m_inheritedFlags; + + // list of associated pseudo styles + std::unique_ptr<PseudoStyleCache> m_cachedPseudoStyles; + + DataRef<SVGRenderStyle> m_svgStyle; + +#if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS) + bool m_deletionHasBegun { false }; +#endif }; +int adjustForAbsoluteZoom(int, const RenderStyle&); +float adjustFloatForAbsoluteZoom(float, const RenderStyle&); +LayoutUnit adjustLayoutUnitForAbsoluteZoom(LayoutUnit, const RenderStyle&); + +EBorderStyle collapsedBorderStyle(EBorderStyle); + +bool pseudoElementRendererIsNeeded(const RenderStyle*); + +inline RenderStyle::NonInheritedFlags::NonInheritedFlags() +{ + // All these initial values need to be zero so that zero-initializing m_flags is correct. + ASSERT(!initialOverflowX()); + ASSERT(!initialOverflowY()); + ASSERT(!initialClear()); + ASSERT(!initialDisplay()); + ASSERT(!initialUnicodeBidi()); + ASSERT(!initialPosition()); + ASSERT(!initialVerticalAlign()); + ASSERT(!initialFloating()); + ASSERT(!initialTableLayout()); +} + +inline void RenderStyle::NonInheritedFlags::copyNonInheritedFrom(const NonInheritedFlags& other) +{ + // Only a subset is copied because NonInheritedFlags contains a bunch of stuff other than real style data. + uint64_t nonInheritedMask = overflowMask << overflowXOffset + | overflowMask << overflowYOffset + | clearMask << clearOffset + | displayMask << effectiveDisplayOffset + | positionMask << positionOffset + | displayMask << originalDisplayOffset + | unicodeBidiMask << unicodeBidiOffset + | verticalAlignMask << verticalAlignOffset + | floatingMask << floatingOffset + | oneBitMask << explicitInheritanceOffset + | tableLayoutBitMask << tableLayoutOffset + | hasViewportUnitsBitMask << hasViewportUnitsOffset; + + m_flags = (m_flags & ~nonInheritedMask) | (other.m_flags & nonInheritedMask); +} + +inline bool RenderStyle::NonInheritedFlags::hasPseudoStyle(PseudoId pseudo) const +{ + ASSERT(pseudo > NOPSEUDO); + ASSERT(pseudo < FIRST_INTERNAL_PSEUDOID); + return (oneBitMask << (pseudoBitsOffset - 1 + pseudo)) & m_flags; +} + +inline void RenderStyle::NonInheritedFlags::setHasPseudoStyle(PseudoId pseudo) +{ + ASSERT(pseudo > NOPSEUDO); + ASSERT(pseudo < FIRST_INTERNAL_PSEUDOID); + m_flags |= oneBitMask << (pseudoBitsOffset - 1 + pseudo); +} + +inline void RenderStyle::NonInheritedFlags::setHasPseudoStyles(PseudoIdSet pseudoIdSet) +{ + ASSERT(pseudoIdSet); + uint64_t rawPseudoIdSet = pseudoIdSet.data(); + ASSERT((rawPseudoIdSet & PUBLIC_PSEUDOID_MASK) == rawPseudoIdSet); + static_assert(pseudoBitsOffset >= 1, "(pseudoBitsOffset - 1) should be valid."); + m_flags |= (static_cast<uint64_t>(rawPseudoIdSet) << (pseudoBitsOffset - 1)); +} + +inline void RenderStyle::NonInheritedFlags::updateBoolean(bool isSet, uint64_t offset) +{ + if (isSet) + m_flags |= (oneBitMask << offset); + else + m_flags &= ~(oneBitMask << offset); +} + +inline bool RenderStyle::NonInheritedFlags::getBoolean(uint64_t offset) const +{ + return m_flags & (oneBitMask << offset); +} + +inline void RenderStyle::NonInheritedFlags::updateValue(uint8_t newValue, uint64_t positionIndependentMask, uint64_t offset) +{ + ASSERT(!(newValue & ~positionIndependentMask)); + uint64_t positionDependentMask = positionIndependentMask << offset; + m_flags = (m_flags & ~positionDependentMask) | (static_cast<uint64_t>(newValue) << offset); +} + +inline bool RenderStyle::InheritedFlags::operator==(const InheritedFlags& other) const +{ + return emptyCells == other.emptyCells + && captionSide == other.captionSide + && listStyleType == other.listStyleType + && listStylePosition == other.listStylePosition + && visibility == other.visibility + && textAlign == other.textAlign + && textTransform == other.textTransform + && textDecorations == other.textDecorations + && cursor == other.cursor +#if ENABLE(CURSOR_VISIBILITY) + && cursorVisibility == other.cursorVisibility +#endif + && direction == other.direction + && whiteSpace == other.whiteSpace + && borderCollapse == other.borderCollapse + && boxDirection == other.boxDirection + && rtlOrdering == other.rtlOrdering + && printColorAdjust == other.printColorAdjust + && pointerEvents == other.pointerEvents + && insideLink == other.insideLink + && insideDefaultButton == other.insideDefaultButton + && writingMode == other.writingMode; +} + +inline unsigned RenderStyle::NonInheritedFlags::getValue(uint64_t positionIndependentMask, uint64_t offset) const +{ + return static_cast<unsigned>((m_flags >> offset) & positionIndependentMask); +} + inline int adjustForAbsoluteZoom(int value, const RenderStyle& style) { double zoomFactor = style.effectiveZoom(); @@ -1931,63 +2102,272 @@ inline int adjustForAbsoluteZoom(int value, const RenderStyle& style) return roundForImpreciseConversion<int>(value / zoomFactor); } -inline float adjustFloatForAbsoluteZoom(float value, const RenderStyle* style) +inline float adjustFloatForAbsoluteZoom(float value, const RenderStyle& style) { - return value / style->effectiveZoom(); + return value / style.effectiveZoom(); } -#if ENABLE(SUBPIXEL_LAYOUT) inline LayoutUnit adjustLayoutUnitForAbsoluteZoom(LayoutUnit value, const RenderStyle& style) { return value / style.effectiveZoom(); } + +inline EBorderStyle collapsedBorderStyle(EBorderStyle style) +{ + if (style == OUTSET) + return GROOVE; + if (style == INSET) + return RIDGE; + return style; +} + +inline bool RenderStyle::hasBackground() const +{ + return visitedDependentColor(CSSPropertyBackgroundColor).isVisible() || hasBackgroundImage(); +} + +inline bool RenderStyle::autoWrap(EWhiteSpace whiteSpace) +{ + // Nowrap and pre don't automatically wrap. + return whiteSpace != NOWRAP && whiteSpace != PRE; +} + +inline bool RenderStyle::preserveNewline(EWhiteSpace whiteSpace) +{ + // Normal and nowrap do not preserve newlines. + return whiteSpace != NORMAL && whiteSpace != NOWRAP; +} + +inline bool RenderStyle::collapseWhiteSpace(EWhiteSpace ws) +{ + // Pre and prewrap do not collapse whitespace. + return ws != PRE && ws != PRE_WRAP; +} + +inline bool RenderStyle::isCollapsibleWhiteSpace(UChar character) const +{ + switch (character) { + case ' ': + case '\t': + return collapseWhiteSpace(); + case '\n': + return !preserveNewline(); + default: + return false; + } +} + +inline bool RenderStyle::breakOnlyAfterWhiteSpace() const +{ + return whiteSpace() == PRE_WRAP || lineBreak() == LineBreakAfterWhiteSpace; +} + +inline bool RenderStyle::breakWords() const +{ + return wordBreak() == BreakWordBreak || overflowWrap() == BreakOverflowWrap; +} + +inline bool RenderStyle::hasInlineColumnAxis() const +{ + auto axis = columnAxis(); + return axis == AutoColumnAxis || isHorizontalWritingMode() == (axis == HorizontalColumnAxis); +} + +inline ImageOrientationEnum RenderStyle::imageOrientation() const +{ +#if ENABLE(CSS_IMAGE_ORIENTATION) + return static_cast<ImageOrientationEnum>(m_rareInheritedData->imageOrientation); +#else + return DefaultImageOrientation; #endif +} + +inline void RenderStyle::setLogicalWidth(Length&& logicalWidth) +{ + if (isHorizontalWritingMode()) + setWidth(WTFMove(logicalWidth)); + else + setHeight(WTFMove(logicalWidth)); +} + +inline void RenderStyle::setLogicalHeight(Length&& logicalHeight) +{ + if (isHorizontalWritingMode()) + setHeight(WTFMove(logicalHeight)); + else + setWidth(WTFMove(logicalHeight)); +} + +inline void RenderStyle::setBorderRadius(LengthSize&& size) +{ + auto topLeft = size; + setBorderTopLeftRadius(WTFMove(topLeft)); + auto topRight = size; + setBorderTopRightRadius(WTFMove(topRight)); + auto bottomLeft = size; + setBorderBottomLeftRadius(WTFMove(bottomLeft)); + setBorderBottomRightRadius(WTFMove(size)); +} -inline bool RenderStyle::setZoom(float f) +inline void RenderStyle::setBorderRadius(const IntSize& size) { - if (compareEqual(visual->m_zoom, f)) + setBorderRadius(LengthSize { { size.width(), Fixed }, { size.height(), Fixed } }); +} + +inline bool RenderStyle::setZoom(float zoomLevel) +{ + setEffectiveZoom(effectiveZoom() * zoomLevel); + if (compareEqual(m_visualData->zoom, zoomLevel)) return false; - visual.access()->m_zoom = f; - setEffectiveZoom(effectiveZoom() * zoom()); + m_visualData.access().zoom = zoomLevel; return true; } -inline bool RenderStyle::setEffectiveZoom(float f) +inline bool RenderStyle::setEffectiveZoom(float zoomLevel) { - if (compareEqual(rareInheritedData->m_effectiveZoom, f)) + if (compareEqual(m_rareInheritedData->effectiveZoom, zoomLevel)) return false; - rareInheritedData.access()->m_effectiveZoom = f; + m_rareInheritedData.access().effectiveZoom = zoomLevel; return true; } inline bool RenderStyle::setTextOrientation(TextOrientation textOrientation) { - if (compareEqual(rareInheritedData->m_textOrientation, textOrientation)) + if (compareEqual(m_rareInheritedData->textOrientation, static_cast<unsigned>(textOrientation))) return false; + m_rareInheritedData.access().textOrientation = static_cast<unsigned>(textOrientation); + return true; +} + +inline void RenderStyle::adjustBackgroundLayers() +{ + if (backgroundLayers().next()) { + ensureBackgroundLayers().cullEmptyLayers(); + ensureBackgroundLayers().fillUnsetProperties(); + } +} + +inline void RenderStyle::adjustMaskLayers() +{ + if (maskLayers().next()) { + ensureMaskLayers().cullEmptyLayers(); + ensureMaskLayers().fillUnsetProperties(); + } +} + +inline void RenderStyle::clearAnimations() +{ + m_rareNonInheritedData.access().animations = nullptr; +} + +inline void RenderStyle::clearTransitions() +{ + m_rareNonInheritedData.access().transitions = nullptr; +} + +inline void RenderStyle::setShapeOutside(RefPtr<ShapeValue>&& value) +{ + if (m_rareNonInheritedData->shapeOutside == value) + return; + m_rareNonInheritedData.access().shapeOutside = WTFMove(value); +} + +inline void RenderStyle::setShapeImageThreshold(float shapeImageThreshold) +{ + float clampedShapeImageThreshold = clampTo<float>(shapeImageThreshold, 0, 1); + SET_VAR(m_rareNonInheritedData, shapeImageThreshold, clampedShapeImageThreshold); +} + +inline void RenderStyle::setClipPath(RefPtr<ClipPathOperation>&& operation) +{ + if (m_rareNonInheritedData->clipPath != operation) + m_rareNonInheritedData.access().clipPath = WTFMove(operation); +} + +inline bool RenderStyle::willChangeCreatesStackingContext() const +{ + return willChange() && willChange()->canCreateStackingContext(); +} + +inline bool RenderStyle::isDisplayRegionType() const +{ + return display() == BLOCK || display() == INLINE_BLOCK + || display() == TABLE_CELL || display() == TABLE_CAPTION + || display() == LIST_ITEM; +} - rareInheritedData.access()->m_textOrientation = textOrientation; +inline bool RenderStyle::setWritingMode(WritingMode v) +{ + if (v == writingMode()) + return false; + m_inheritedFlags.writingMode = v; return true; } +inline void RenderStyle::getShadowInlineDirectionExtent(const ShadowData* shadow, LayoutUnit& logicalLeft, LayoutUnit& logicalRight) const +{ + return isHorizontalWritingMode() ? getShadowHorizontalExtent(shadow, logicalLeft, logicalRight) : getShadowVerticalExtent(shadow, logicalLeft, logicalRight); +} + +inline void RenderStyle::getShadowBlockDirectionExtent(const ShadowData* shadow, LayoutUnit& logicalTop, LayoutUnit& logicalBottom) const +{ + return isHorizontalWritingMode() ? getShadowVerticalExtent(shadow, logicalTop, logicalBottom) : getShadowHorizontalExtent(shadow, logicalTop, logicalBottom); +} + +inline bool RenderStyle::isDisplayReplacedType(EDisplay display) +{ + return display == INLINE_BLOCK || display == INLINE_BOX || display == INLINE_FLEX + || display == INLINE_GRID || display == INLINE_TABLE; +} + +inline bool RenderStyle::isDisplayInlineType(EDisplay display) +{ + return display == INLINE || isDisplayReplacedType(display); +} + +inline bool RenderStyle::isDisplayFlexibleBox(EDisplay display) +{ + return display == FLEX || display == INLINE_FLEX; +} + +inline bool RenderStyle::isDisplayGridBox(EDisplay display) +{ + return display == GRID || display == INLINE_GRID; +} + +inline bool RenderStyle::isDisplayFlexibleOrGridBox(EDisplay display) +{ + return isDisplayFlexibleBox(display) || isDisplayGridBox(display); +} + inline bool RenderStyle::hasAnyPublicPseudoStyles() const { - return PUBLIC_PSEUDOID_MASK & noninherited_flags._pseudoBits; + return m_nonInheritedFlags.hasAnyPublicPseudoStyles(); } inline bool RenderStyle::hasPseudoStyle(PseudoId pseudo) const { - ASSERT(pseudo > NOPSEUDO); - ASSERT(pseudo < FIRST_INTERNAL_PSEUDOID); - return (1 << (pseudo - 1)) & noninherited_flags._pseudoBits; + return m_nonInheritedFlags.hasPseudoStyle(pseudo); } inline void RenderStyle::setHasPseudoStyle(PseudoId pseudo) { - ASSERT(pseudo > NOPSEUDO); - ASSERT(pseudo < FIRST_INTERNAL_PSEUDOID); - noninherited_flags._pseudoBits |= 1 << (pseudo - 1); + m_nonInheritedFlags.setHasPseudoStyle(pseudo); } -} // namespace WebCore +inline void RenderStyle::setHasPseudoStyles(PseudoIdSet pseudoIdSet) +{ + m_nonInheritedFlags.setHasPseudoStyles(pseudoIdSet); +} -#endif // RenderStyle_h +inline void RenderStyle::setBoxReflect(RefPtr<StyleReflection>&& reflect) +{ + SET_VAR(m_rareNonInheritedData, boxReflect, WTFMove(reflect)); +} + +inline bool pseudoElementRendererIsNeeded(const RenderStyle* style) +{ + return style && style->display() != NONE && (style->contentData() || style->hasFlowFrom()); +} + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/RenderStyleConstants.cpp b/Source/WebCore/rendering/style/RenderStyleConstants.cpp new file mode 100644 index 000000000..f13cd7bd9 --- /dev/null +++ b/Source/WebCore/rendering/style/RenderStyleConstants.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "RenderStyleConstants.h" + +#include "TextStream.h" + +namespace WebCore { + +TextStream& operator<<(TextStream& ts, EFillSizeType sizeType) +{ + switch (sizeType) { + case Contain: ts << "contain"; break; + case Cover: ts << "cover"; break; + case SizeLength: ts << "size-length"; break; + case SizeNone: ts << "size-none"; break; + } + + return ts; +} + +TextStream& operator<<(TextStream& ts, EFillAttachment attachment) +{ + switch (attachment) { + case ScrollBackgroundAttachment: ts << "scroll"; break; + case LocalBackgroundAttachment: ts << "local"; break; + case FixedBackgroundAttachment: ts << "fixed"; break; + } + return ts; +} + +TextStream& operator<<(TextStream& ts, EFillBox fill) +{ + switch (fill) { + case BorderFillBox: ts << "border"; break; + case PaddingFillBox: ts << "padding"; break; + case ContentFillBox: ts << "content"; break; + case TextFillBox: ts << "text"; break; + } + return ts; +} + +TextStream& operator<<(TextStream& ts, EFillRepeat repeat) +{ + switch (repeat) { + case RepeatFill: ts << "repeat"; break; + case NoRepeatFill: ts << "no-repeat"; break; + case RoundFill: ts << "round"; break; + case SpaceFill: ts << "space"; break; + } + + return ts; +} + +TextStream& operator<<(TextStream& ts, EMaskSourceType maskSource) +{ + switch (maskSource) { + case MaskAlpha: ts << "alpha"; break; + case MaskLuminance: ts << "luminance"; break; + } + + return ts; +} + +TextStream& operator<<(TextStream& ts, Edge edge) +{ + switch (edge) { + case Edge::Top: ts << "top"; break; + case Edge::Right: ts << "right"; break; + case Edge::Bottom: ts << "bottom"; break; + case Edge::Left: ts << "left"; break; + } + return ts; +} + +bool alwaysPageBreak(BreakBetween between) +{ + return between >= PageBreakBetween; +} + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/RenderStyleConstants.h b/Source/WebCore/rendering/style/RenderStyleConstants.h index 11b428559..6daad935f 100644 --- a/Source/WebCore/rendering/style/RenderStyleConstants.h +++ b/Source/WebCore/rendering/style/RenderStyleConstants.h @@ -23,11 +23,14 @@ * */ -#ifndef RenderStyleConstants_h -#define RenderStyleConstants_h +#pragma once + +#include <initializer_list> namespace WebCore { +class TextStream; + static const size_t PrintColorAdjustBits = 1; enum PrintColorAdjust { PrintColorAdjustEconomy, @@ -46,16 +49,15 @@ enum PrintColorAdjust { // - StyleDifferenceLayout - A full layout is required. enum StyleDifference { StyleDifferenceEqual, -#if USE(ACCELERATED_COMPOSITING) StyleDifferenceRecompositeLayer, -#endif StyleDifferenceRepaint, StyleDifferenceRepaintIfTextOrBorderOrOutline, StyleDifferenceRepaintLayer, StyleDifferenceLayoutPositionedMovementOnly, StyleDifferenceSimplifiedLayout, StyleDifferenceSimplifiedLayoutAndPositionedMovement, - StyleDifferenceLayout + StyleDifferenceLayout, + StyleDifferenceNewStyle }; // When some style properties change, different amounts of work have to be done depending on @@ -63,26 +65,91 @@ enum StyleDifference { // A simple StyleDifference does not provide enough information so we return a bit mask of // StyleDifferenceContextSensitiveProperties from RenderStyle::diff() too. enum StyleDifferenceContextSensitiveProperty { - ContextSensitivePropertyNone = 0, - ContextSensitivePropertyTransform = (1 << 0), - ContextSensitivePropertyOpacity = (1 << 1), - ContextSensitivePropertyFilter = (1 << 2) + ContextSensitivePropertyNone = 0, + ContextSensitivePropertyTransform = 1 << 0, + ContextSensitivePropertyOpacity = 1 << 1, + ContextSensitivePropertyFilter = 1 << 2, + ContextSensitivePropertyClipRect = 1 << 3, + ContextSensitivePropertyClipPath = 1 << 4, + ContextSensitivePropertyWillChange = 1 << 5, }; // Static pseudo styles. Dynamic ones are produced on the fly. -enum PseudoId { +enum PseudoId : unsigned char { // The order must be NOP ID, public IDs, and then internal IDs. - NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED, SCROLLBAR, + NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, SCROLLBAR, // Internal IDs follow: SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER, - INPUT_LIST_BUTTON, AFTER_LAST_INTERNAL_PSEUDOID, - FULL_SCREEN, FULL_SCREEN_DOCUMENT, FULL_SCREEN_ANCESTOR, ANIMATING_FULL_SCREEN_TRANSITION, FIRST_PUBLIC_PSEUDOID = FIRST_LINE, FIRST_INTERNAL_PSEUDOID = SCROLLBAR_THUMB, PUBLIC_PSEUDOID_MASK = ((1 << FIRST_INTERNAL_PSEUDOID) - 1) & ~((1 << FIRST_PUBLIC_PSEUDOID) - 1) }; +class PseudoIdSet { +public: + PseudoIdSet() + : m_data(0) + { + } + + PseudoIdSet(std::initializer_list<PseudoId> initializerList) + : m_data(0) + { + for (PseudoId pseudoId : initializerList) + add(pseudoId); + } + + static PseudoIdSet fromMask(unsigned rawPseudoIdSet) + { + return PseudoIdSet(rawPseudoIdSet); + } + + bool has(PseudoId pseudoId) const + { + ASSERT((sizeof(m_data) * 8) > pseudoId); + return m_data & (1U << pseudoId); + } + + void add(PseudoId pseudoId) + { + ASSERT((sizeof(m_data) * 8) > pseudoId); + m_data |= (1U << pseudoId); + } + + void merge(PseudoIdSet source) + { + m_data |= source.m_data; + } + + PseudoIdSet operator &(const PseudoIdSet& pseudoIdSet) const + { + return PseudoIdSet(m_data & pseudoIdSet.m_data); + } + + PseudoIdSet operator |(const PseudoIdSet& pseudoIdSet) const + { + return PseudoIdSet(m_data | pseudoIdSet.m_data); + } + + explicit operator bool() const + { + return m_data; + } + + unsigned data() const { return m_data; } + + static ptrdiff_t dataMemoryOffset() { return OBJECT_OFFSETOF(PseudoIdSet, m_data); } + +private: + explicit PseudoIdSet(unsigned rawPseudoIdSet) + : m_data(rawPseudoIdSet) + { + } + + unsigned m_data; +}; + enum ColumnFill { ColumnFillBalance, ColumnFillAuto }; enum ColumnSpan { ColumnSpanNone = 0, ColumnSpanAll }; @@ -123,7 +190,7 @@ enum EBoxSizing { CONTENT_BOX, BORDER_BOX }; // Random visual rendering model attributes. Not inherited. enum EOverflow { - OVISIBLE, OHIDDEN, OSCROLL, OAUTO, OOVERLAY, OMARQUEE, OPAGEDX, OPAGEDY + OVISIBLE, OHIDDEN, OSCROLL, OAUTO, OOVERLAY, OPAGEDX, OPAGEDY }; enum EVerticalAlign { @@ -162,8 +229,8 @@ enum EFillLayerType { // CSS3 Background Values enum EFillSizeType { Contain, Cover, SizeLength, SizeNone }; -// CSS3 Background Position -enum BackgroundEdgeOrigin { TopEdge, RightEdge, BottomEdge, LeftEdge }; +// CSS3 <position> +enum class Edge { Top, Right, Bottom, Left }; // CSS3 Mask Source Types enum EMaskSourceType { MaskAlpha, MaskLuminance }; @@ -184,10 +251,13 @@ enum EBoxDirection { BNORMAL, BREVERSE }; // CSS3 Flexbox Properties enum EAlignContent { AlignContentFlexStart, AlignContentFlexEnd, AlignContentCenter, AlignContentSpaceBetween, AlignContentSpaceAround, AlignContentStretch }; -enum EAlignItems { AlignAuto, AlignFlexStart, AlignFlexEnd, AlignCenter, AlignStretch, AlignBaseline }; enum EFlexDirection { FlowRow, FlowRowReverse, FlowColumn, FlowColumnReverse }; enum EFlexWrap { FlexNoWrap, FlexWrap, FlexWrapReverse }; -enum EJustifyContent { JustifyFlexStart, JustifyFlexEnd, JustifyCenter, JustifySpaceBetween, JustifySpaceAround }; +enum ItemPosition { ItemPositionAuto, ItemPositionNormal, ItemPositionStretch, ItemPositionBaseline, ItemPositionLastBaseline, ItemPositionCenter, ItemPositionStart, ItemPositionEnd, ItemPositionSelfStart, ItemPositionSelfEnd, ItemPositionFlexStart, ItemPositionFlexEnd, ItemPositionLeft, ItemPositionRight }; +enum OverflowAlignment { OverflowAlignmentDefault, OverflowAlignmentUnsafe, OverflowAlignmentSafe }; +enum ItemPositionType { NonLegacyPosition, LegacyPosition }; +enum ContentPosition { ContentPositionNormal, ContentPositionBaseline, ContentPositionLastBaseline, ContentPositionCenter, ContentPositionStart, ContentPositionEnd, ContentPositionFlexStart, ContentPositionFlexEnd, ContentPositionLeft, ContentPositionRight }; +enum ContentDistributionType { ContentDistributionDefault, ContentDistributionSpaceBetween, ContentDistributionSpaceAround, ContentDistributionSpaceEvenly, ContentDistributionStretch }; enum ETextSecurity { TSNONE, TSDISC, TSCIRCLE, TSSQUARE @@ -216,10 +286,12 @@ enum ObjectFit { ObjectFitFill, ObjectFitContain, ObjectFitCover, ObjectFitNone, ObjectFitScaleDown }; -// Word Break Values. Matches WinIE, rather than CSS3 +enum AspectRatioType { + AspectRatioAuto, AspectRatioFromIntrinsic, AspectRatioFromDimensions, AspectRatioSpecified +}; enum EWordBreak { - NormalWordBreak, BreakAllWordBreak, BreakWordBreak + NormalWordBreak, BreakAllWordBreak, KeepAllWordBreak, BreakWordBreak }; enum EOverflowWrap { @@ -381,13 +453,15 @@ enum TextAlignLast { }; enum TextJustify { - TextJustifyAuto, TextJustifyNone, TextJustifyInterWord, TextJustifyInterIdeograph, TextJustifyInterCluster, TextJustifyDistribute, TextJustifyKashida + TextJustifyAuto, TextJustifyNone, TextJustifyInterWord, TextJustifyDistribute }; #endif // CSS3_TEXT enum TextDecorationSkipItems { TextDecorationSkipNone = 0, - TextDecorationSkipInk = 1 << 0 + TextDecorationSkipInk = 1 << 0, + TextDecorationSkipObjects = 1 << 1, + TextDecorationSkipAuto = 1 << 2 }; typedef unsigned TextDecorationSkip; @@ -396,10 +470,29 @@ enum TextUnderlinePosition { TextUnderlinePositionAuto = 0x1, TextUnderlinePositionAlphabetic = 0x2, TextUnderlinePositionUnder = 0x4 }; -enum EPageBreak { - PBAUTO, PBALWAYS, PBAVOID +enum TextZoom { + TextZoomNormal, TextZoomReset }; +enum BreakBetween { + AutoBreakBetween, AvoidBreakBetween, AvoidColumnBreakBetween, AvoidPageBreakBetween, AvoidRegionBreakBetween, ColumnBreakBetween, RegionBreakBetween, PageBreakBetween, LeftPageBreakBetween, RightPageBreakBetween, RectoPageBreakBetween, VersoPageBreakBetween +}; +bool alwaysPageBreak(BreakBetween); + +enum BreakInside { + AutoBreakInside, AvoidBreakInside, AvoidColumnBreakInside, AvoidPageBreakInside, AvoidRegionBreakInside +}; + +enum HangingPunctuation { + NoHangingPunctuation = 0, + FirstHangingPunctuation = 1 << 0, + LastHangingPunctuation = 1 << 1, + AllowEndHangingPunctuation = 1 << 2, + ForceEndHangingPunctuation = 1 << 3 +}; +inline HangingPunctuation operator| (HangingPunctuation a, HangingPunctuation b) { return HangingPunctuation(int(a) | int(b)); } +inline HangingPunctuation& operator|= (HangingPunctuation& a, HangingPunctuation b) { return a = a | b; } + enum EEmptyCell { SHOW, HIDE }; @@ -414,44 +507,44 @@ enum EVisibility { VISIBLE, HIDDEN, COLLAPSE }; enum ECursor { // The following must match the order in CSSValueKeywords.in. - CURSOR_AUTO, - CURSOR_CROSS, - CURSOR_DEFAULT, - CURSOR_POINTER, - CURSOR_MOVE, - CURSOR_VERTICAL_TEXT, - CURSOR_CELL, - CURSOR_CONTEXT_MENU, - CURSOR_ALIAS, - CURSOR_PROGRESS, - CURSOR_NO_DROP, - CURSOR_NOT_ALLOWED, - CURSOR_WEBKIT_ZOOM_IN, - CURSOR_WEBKIT_ZOOM_OUT, - CURSOR_E_RESIZE, - CURSOR_NE_RESIZE, - CURSOR_NW_RESIZE, - CURSOR_N_RESIZE, - CURSOR_SE_RESIZE, - CURSOR_SW_RESIZE, - CURSOR_S_RESIZE, - CURSOR_W_RESIZE, - CURSOR_EW_RESIZE, - CURSOR_NS_RESIZE, - CURSOR_NESW_RESIZE, - CURSOR_NWSE_RESIZE, - CURSOR_COL_RESIZE, - CURSOR_ROW_RESIZE, - CURSOR_TEXT, - CURSOR_WAIT, - CURSOR_HELP, - CURSOR_ALL_SCROLL, - CURSOR_WEBKIT_GRAB, - CURSOR_WEBKIT_GRABBING, + CursorAuto, + CursorCross, + CursorDefault, + CursorPointer, + CursorMove, + CursorVerticalText, + CursorCell, + CursorContextMenu, + CursorAlias, + CursorProgress, + CursorNoDrop, + CursorNotAllowed, + CursorZoomIn, + CursorZoomOut, + CursorEResize, + CursorNeResize, + CursorNwResize, + CursorNResize, + CursorSeResize, + CursorSwResize, + CursorSResize, + CursorWResize, + CursorEwResize, + CursorNsResize, + CursorNeswResize, + CursorNwseResize, + CursorColResize, + CursorRowResize, + CursorText, + CursorWait, + CursorHelp, + CursorAllScroll, + CursorWebkitGrab, + CursorWebkitGrabbing, // The following are handled as exceptions so don't need to match. - CURSOR_COPY, - CURSOR_NONE + CursorCopy, + CursorNone }; #if ENABLE(CURSOR_VISIBILITY) @@ -463,14 +556,13 @@ enum CursorVisibility { // The order of this enum must match the order of the display values in CSSValueKeywords.in. enum EDisplay { - INLINE, BLOCK, LIST_ITEM, RUN_IN, COMPACT, INLINE_BLOCK, + INLINE, BLOCK, LIST_ITEM, COMPACT, INLINE_BLOCK, TABLE, INLINE_TABLE, TABLE_ROW_GROUP, TABLE_HEADER_GROUP, TABLE_FOOTER_GROUP, TABLE_ROW, TABLE_COLUMN_GROUP, TABLE_COLUMN, TABLE_CELL, TABLE_CAPTION, BOX, INLINE_BOX, - FLEX, INLINE_FLEX, - GRID, INLINE_GRID, - NONE + FLEX, WEBKIT_FLEX, INLINE_FLEX, WEBKIT_INLINE_FLEX, + CONTENTS, GRID, INLINE_GRID, NONE }; enum EInsideLink { @@ -508,11 +600,17 @@ enum TextEmphasisPositions { }; typedef unsigned TextEmphasisPosition; -enum TextOrientation { TextOrientationVerticalRight, TextOrientationUpright, TextOrientationSideways, TextOrientationSidewaysRight }; +enum class TextOrientation { Mixed, Upright, Sideways }; enum TextOverflow { TextOverflowClip = 0, TextOverflowEllipsis }; -enum EImageRendering { ImageRenderingAuto = 0, ImageRenderingOptimizeSpeed, ImageRenderingOptimizeQuality, ImageRenderingCrispEdges }; +enum EImageRendering { + ImageRenderingAuto = 0, + ImageRenderingOptimizeSpeed, + ImageRenderingOptimizeQuality, + ImageRenderingCrispEdges, + ImageRenderingPixelated +}; enum ImageResolutionSource { ImageResolutionSpecified = 0, ImageResolutionFromImage }; @@ -530,13 +628,31 @@ enum LineSnap { LineSnapNone, LineSnapBaseline, LineSnapContain }; enum LineAlign { LineAlignNone, LineAlignEdges }; -enum WrapFlow { WrapFlowAuto, WrapFlowBoth, WrapFlowStart, WrapFlowEnd, WrapFlowMaximum, WrapFlowClear }; +enum RubyPosition { RubyPositionBefore, RubyPositionAfter, RubyPositionInterCharacter }; -enum WrapThrough { WrapThroughWrap, WrapThroughNone }; +static const size_t GridAutoFlowBits = 4; +enum InternalGridAutoFlowAlgorithm { + InternalAutoFlowAlgorithmSparse = 0x1, + InternalAutoFlowAlgorithmDense = 0x2, +}; -enum RubyPosition { RubyPositionBefore, RubyPositionAfter }; +enum InternalGridAutoFlowDirection { + InternalAutoFlowDirectionRow = 0x4, + InternalAutoFlowDirectionColumn = 0x8 +}; + +enum GridAutoFlow { + AutoFlowRow = InternalAutoFlowAlgorithmSparse | InternalAutoFlowDirectionRow, + AutoFlowColumn = InternalAutoFlowAlgorithmSparse | InternalAutoFlowDirectionColumn, + AutoFlowRowDense = InternalAutoFlowAlgorithmDense | InternalAutoFlowDirectionRow, + AutoFlowColumnDense = InternalAutoFlowAlgorithmDense | InternalAutoFlowDirectionColumn +}; -enum GridAutoFlow { AutoFlowNone, AutoFlowColumn, AutoFlowRow }; +enum AutoRepeatType { + NoAutoRepeat, + AutoFill, + AutoFit +}; // Reasonable maximum to prevent insane font sizes from causing crashes on some platforms (such as Windows). static const float maximumAllowedFontSize = 1000000.0f; @@ -546,8 +662,68 @@ enum TextIndentLine { TextIndentFirstLine, TextIndentEachLine }; enum TextIndentType { TextIndentNormal, TextIndentHanging }; #endif -enum LayoutBox { BoxMissing = 0, MarginBox, BorderBox, PaddingBox, ContentBox, BoundingBox }; +enum Isolation { IsolationAuto, IsolationIsolate }; -} // namespace WebCore +// Fill, Stroke, ViewBox are just used for SVG. +enum CSSBoxType { BoxMissing = 0, MarginBox, BorderBox, PaddingBox, ContentBox, Fill, Stroke, ViewBox }; -#endif // RenderStyleConstants_h +#if ENABLE(TOUCH_EVENTS) +enum class TouchAction { + Auto, + Manipulation +}; +#endif + +#if ENABLE(CSS_SCROLL_SNAP) +enum class ScrollSnapStrictness { + None, + Proximity, + Mandatory +}; + +enum class ScrollSnapAxis { + XAxis, + YAxis, + Block, + Inline, + Both +}; + +enum class ScrollSnapAxisAlignType { + None, + Start, + Center, + End +}; +#endif + +#if ENABLE(CSS_TRAILING_WORD) +enum class TrailingWord { + Auto, + PartiallyBalanced +}; +#endif + +#if ENABLE(APPLE_PAY) +enum class ApplePayButtonStyle { + White, + WhiteOutline, + Black, +}; + +enum class ApplePayButtonType { + Plain, + Buy, + SetUp, + Donate, +}; +#endif + +TextStream& operator<<(TextStream&, EFillSizeType); +TextStream& operator<<(TextStream&, EFillAttachment); +TextStream& operator<<(TextStream&, EFillBox); +TextStream& operator<<(TextStream&, EFillRepeat); +TextStream& operator<<(TextStream&, EMaskSourceType); +TextStream& operator<<(TextStream&, Edge); + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/SVGRenderStyle.cpp b/Source/WebCore/rendering/style/SVGRenderStyle.cpp index 06c793f69..c8e55b4fd 100644 --- a/Source/WebCore/rendering/style/SVGRenderStyle.cpp +++ b/Source/WebCore/rendering/style/SVGRenderStyle.cpp @@ -7,7 +7,7 @@ Copyright (C) 1999 Antti Koivisto (koivisto@kde.org) Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) Copyright (C) 2002-2003 Dirk Mueller (mueller@kde.org) - Copyright (C) 2002 Apple Computer, Inc. + Copyright (C) 2002 Apple Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -26,8 +26,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGRenderStyle.h" #include "CSSPrimitiveValue.h" @@ -42,56 +40,59 @@ namespace WebCore { static const SVGRenderStyle& defaultSVGStyle() { static NeverDestroyed<DataRef<SVGRenderStyle>> style(SVGRenderStyle::createDefaultStyle()); - return *style.get().get(); + return *style.get(); } -PassRef<SVGRenderStyle> SVGRenderStyle::createDefaultStyle() +Ref<SVGRenderStyle> SVGRenderStyle::createDefaultStyle() { return adoptRef(*new SVGRenderStyle(CreateDefault)); } SVGRenderStyle::SVGRenderStyle() - : fill(defaultSVGStyle().fill) - , stroke(defaultSVGStyle().stroke) - , text(defaultSVGStyle().text) - , inheritedResources(defaultSVGStyle().inheritedResources) - , stops(defaultSVGStyle().stops) - , misc(defaultSVGStyle().misc) - , shadowSVG(defaultSVGStyle().shadowSVG) - , resources(defaultSVGStyle().resources) + : m_fillData(defaultSVGStyle().m_fillData) + , m_strokeData(defaultSVGStyle().m_strokeData) + , m_textData(defaultSVGStyle().m_textData) + , m_inheritedResourceData(defaultSVGStyle().m_inheritedResourceData) + , m_stopData(defaultSVGStyle().m_stopData) + , m_miscData(defaultSVGStyle().m_miscData) + , m_shadowData(defaultSVGStyle().m_shadowData) + , m_layoutData(defaultSVGStyle().m_layoutData) + , m_nonInheritedResourceData(defaultSVGStyle().m_nonInheritedResourceData) { setBitDefaults(); } SVGRenderStyle::SVGRenderStyle(CreateDefaultType) - : fill(StyleFillData::create()) - , stroke(StyleStrokeData::create()) - , text(StyleTextData::create()) - , inheritedResources(StyleInheritedResourceData::create()) - , stops(StyleStopData::create()) - , misc(StyleMiscData::create()) - , shadowSVG(StyleShadowSVGData::create()) - , resources(StyleResourceData::create()) + : m_fillData(StyleFillData::create()) + , m_strokeData(StyleStrokeData::create()) + , m_textData(StyleTextData::create()) + , m_inheritedResourceData(StyleInheritedResourceData::create()) + , m_stopData(StyleStopData::create()) + , m_miscData(StyleMiscData::create()) + , m_shadowData(StyleShadowSVGData::create()) + , m_layoutData(StyleLayoutData::create()) + , m_nonInheritedResourceData(StyleResourceData::create()) { setBitDefaults(); } inline SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other) : RefCounted<SVGRenderStyle>() - , svg_inherited_flags(other.svg_inherited_flags) - , svg_noninherited_flags(other.svg_noninherited_flags) - , fill(other.fill) - , stroke(other.stroke) - , text(other.text) - , inheritedResources(other.inheritedResources) - , stops(other.stops) - , misc(other.misc) - , shadowSVG(other.shadowSVG) - , resources(other.resources) + , m_inheritedFlags(other.m_inheritedFlags) + , m_nonInheritedFlags(other.m_nonInheritedFlags) + , m_fillData(other.m_fillData) + , m_strokeData(other.m_strokeData) + , m_textData(other.m_textData) + , m_inheritedResourceData(other.m_inheritedResourceData) + , m_stopData(other.m_stopData) + , m_miscData(other.m_miscData) + , m_shadowData(other.m_shadowData) + , m_layoutData(other.m_layoutData) + , m_nonInheritedResourceData(other.m_nonInheritedResourceData) { } -PassRef<SVGRenderStyle> SVGRenderStyle::copy() const +Ref<SVGRenderStyle> SVGRenderStyle::copy() const { return adoptRef(*new SVGRenderStyle(*this)); } @@ -102,149 +103,143 @@ SVGRenderStyle::~SVGRenderStyle() bool SVGRenderStyle::operator==(const SVGRenderStyle& other) const { - return fill == other.fill - && stroke == other.stroke - && text == other.text - && stops == other.stops - && misc == other.misc - && shadowSVG == other.shadowSVG - && inheritedResources == other.inheritedResources - && resources == other.resources - && svg_inherited_flags == other.svg_inherited_flags - && svg_noninherited_flags == other.svg_noninherited_flags; + return m_fillData == other.m_fillData + && m_strokeData == other.m_strokeData + && m_textData == other.m_textData + && m_stopData == other.m_stopData + && m_miscData == other.m_miscData + && m_shadowData == other.m_shadowData + && m_layoutData == other.m_layoutData + && m_inheritedResourceData == other.m_inheritedResourceData + && m_nonInheritedResourceData == other.m_nonInheritedResourceData + && m_inheritedFlags == other.m_inheritedFlags + && m_nonInheritedFlags == other.m_nonInheritedFlags; } -bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle* other) const +bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle& other) const { - return fill != other->fill - || stroke != other->stroke - || text != other->text - || inheritedResources != other->inheritedResources - || svg_inherited_flags != other->svg_inherited_flags; + return m_fillData != other.m_fillData + || m_strokeData != other.m_strokeData + || m_textData != other.m_textData + || m_inheritedResourceData != other.m_inheritedResourceData + || m_inheritedFlags != other.m_inheritedFlags; } -void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent) +void SVGRenderStyle::inheritFrom(const SVGRenderStyle& other) { - if (!svgInheritParent) - return; - - fill = svgInheritParent->fill; - stroke = svgInheritParent->stroke; - text = svgInheritParent->text; - inheritedResources = svgInheritParent->inheritedResources; + m_fillData = other.m_fillData; + m_strokeData = other.m_strokeData; + m_textData = other.m_textData; + m_inheritedResourceData = other.m_inheritedResourceData; - svg_inherited_flags = svgInheritParent->svg_inherited_flags; + m_inheritedFlags = other.m_inheritedFlags; } -void SVGRenderStyle::copyNonInheritedFrom(const SVGRenderStyle* other) +void SVGRenderStyle::copyNonInheritedFrom(const SVGRenderStyle& other) { - svg_noninherited_flags = other->svg_noninherited_flags; - stops = other->stops; - misc = other->misc; - shadowSVG = other->shadowSVG; - resources = other->resources; + m_nonInheritedFlags = other.m_nonInheritedFlags; + m_stopData = other.m_stopData; + m_miscData = other.m_miscData; + m_shadowData = other.m_shadowData; + m_layoutData = other.m_layoutData; + m_nonInheritedResourceData = other.m_nonInheritedResourceData; } -StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const +StyleDifference SVGRenderStyle::diff(const SVGRenderStyle& other) const { // NOTE: All comparisions that may return StyleDifferenceLayout have to go before those who return StyleDifferenceRepaint // If kerning changes, we need a relayout, to force SVGCharacterData to be recalculated in the SVGRootInlineBox. - if (text != other->text) + if (m_textData != other.m_textData) return StyleDifferenceLayout; // If resources change, we need a relayout, as the presence of resources influences the repaint rect. - if (resources != other->resources) + if (m_nonInheritedResourceData != other.m_nonInheritedResourceData) return StyleDifferenceLayout; // If markers change, we need a relayout, as marker boundaries are cached in RenderSVGPath. - if (inheritedResources != other->inheritedResources) + if (m_inheritedResourceData != other.m_inheritedResourceData) return StyleDifferenceLayout; // All text related properties influence layout. - if (svg_inherited_flags._textAnchor != other->svg_inherited_flags._textAnchor - || svg_inherited_flags._writingMode != other->svg_inherited_flags._writingMode - || svg_inherited_flags._glyphOrientationHorizontal != other->svg_inherited_flags._glyphOrientationHorizontal - || svg_inherited_flags._glyphOrientationVertical != other->svg_inherited_flags._glyphOrientationVertical - || svg_noninherited_flags.f._alignmentBaseline != other->svg_noninherited_flags.f._alignmentBaseline - || svg_noninherited_flags.f._dominantBaseline != other->svg_noninherited_flags.f._dominantBaseline - || svg_noninherited_flags.f._baselineShift != other->svg_noninherited_flags.f._baselineShift) + if (m_inheritedFlags.textAnchor != other.m_inheritedFlags.textAnchor + || m_inheritedFlags.glyphOrientationHorizontal != other.m_inheritedFlags.glyphOrientationHorizontal + || m_inheritedFlags.glyphOrientationVertical != other.m_inheritedFlags.glyphOrientationVertical + || m_nonInheritedFlags.flagBits.alignmentBaseline != other.m_nonInheritedFlags.flagBits.alignmentBaseline + || m_nonInheritedFlags.flagBits.dominantBaseline != other.m_nonInheritedFlags.flagBits.dominantBaseline + || m_nonInheritedFlags.flagBits.baselineShift != other.m_nonInheritedFlags.flagBits.baselineShift) return StyleDifferenceLayout; // Text related properties influence layout. - bool miscNotEqual = misc != other->misc; - if (miscNotEqual && misc->baselineShiftValue != other->misc->baselineShiftValue) - return StyleDifferenceLayout; - - // These properties affect the cached stroke bounding box rects. - if (svg_inherited_flags._capStyle != other->svg_inherited_flags._capStyle - || svg_inherited_flags._joinStyle != other->svg_inherited_flags._joinStyle) + bool miscNotEqual = m_miscData != other.m_miscData; + if (miscNotEqual && m_miscData->baselineShiftValue != other.m_miscData->baselineShiftValue) return StyleDifferenceLayout; // Shadow changes require relayouts, as they affect the repaint rects. - if (shadowSVG != other->shadowSVG) + if (m_shadowData != other.m_shadowData) return StyleDifferenceLayout; + // The x or y properties require relayout. + if (m_layoutData != other.m_layoutData) + return StyleDifferenceLayout; + // Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated. - if (stroke != other->stroke) { - if (stroke->width != other->stroke->width - || stroke->paintType != other->stroke->paintType - || stroke->paintColor != other->stroke->paintColor - || stroke->paintUri != other->stroke->paintUri - || stroke->miterLimit != other->stroke->miterLimit - || stroke->dashArray != other->stroke->dashArray - || stroke->dashOffset != other->stroke->dashOffset - || stroke->visitedLinkPaintColor != other->stroke->visitedLinkPaintColor - || stroke->visitedLinkPaintUri != other->stroke->visitedLinkPaintUri - || stroke->visitedLinkPaintType != other->stroke->visitedLinkPaintType) + if (m_strokeData != other.m_strokeData) { + if (m_strokeData->paintType != other.m_strokeData->paintType + || m_strokeData->paintColor != other.m_strokeData->paintColor + || m_strokeData->paintUri != other.m_strokeData->paintUri + || m_strokeData->miterLimit != other.m_strokeData->miterLimit + || m_strokeData->dashArray != other.m_strokeData->dashArray + || m_strokeData->dashOffset != other.m_strokeData->dashOffset + || m_strokeData->visitedLinkPaintColor != other.m_strokeData->visitedLinkPaintColor + || m_strokeData->visitedLinkPaintUri != other.m_strokeData->visitedLinkPaintUri + || m_strokeData->visitedLinkPaintType != other.m_strokeData->visitedLinkPaintType) return StyleDifferenceLayout; // Only the stroke-opacity case remains, where we only need a repaint. - ASSERT(stroke->opacity != other->stroke->opacity); + ASSERT(m_strokeData->opacity != other.m_strokeData->opacity); return StyleDifferenceRepaint; } + // vector-effect changes require a re-layout. + if (m_nonInheritedFlags.flagBits.vectorEffect != other.m_nonInheritedFlags.flagBits.vectorEffect) + return StyleDifferenceLayout; + // NOTE: All comparisions below may only return StyleDifferenceRepaint // Painting related properties only need repaints. if (miscNotEqual) { - if (misc->floodColor != other->misc->floodColor - || misc->floodOpacity != other->misc->floodOpacity - || misc->lightingColor != other->misc->lightingColor) + if (m_miscData->floodColor != other.m_miscData->floodColor + || m_miscData->floodOpacity != other.m_miscData->floodOpacity + || m_miscData->lightingColor != other.m_miscData->lightingColor) return StyleDifferenceRepaint; } - // If fill changes, we just need to repaint. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains. - if (fill->paintType != other->fill->paintType || fill->paintColor != other->fill->paintColor - || fill->paintUri != other->fill->paintUri || fill->opacity != other->fill->opacity) + // If fill data changes, we just need to repaint. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains. + if (m_fillData->paintType != other.m_fillData->paintType || m_fillData->paintColor != other.m_fillData->paintColor + || m_fillData->paintUri != other.m_fillData->paintUri || m_fillData->opacity != other.m_fillData->opacity) return StyleDifferenceRepaint; // If gradient stops change, we just need to repaint. Style updates are already handled through RenderSVGGradientSTop. - if (stops != other->stops) + if (m_stopData != other.m_stopData) return StyleDifferenceRepaint; // Changes of these flags only cause repaints. - if (svg_inherited_flags._colorRendering != other->svg_inherited_flags._colorRendering - || svg_inherited_flags._shapeRendering != other->svg_inherited_flags._shapeRendering - || svg_inherited_flags._clipRule != other->svg_inherited_flags._clipRule - || svg_inherited_flags._fillRule != other->svg_inherited_flags._fillRule - || svg_inherited_flags._colorInterpolation != other->svg_inherited_flags._colorInterpolation - || svg_inherited_flags._colorInterpolationFilters != other->svg_inherited_flags._colorInterpolationFilters) + if (m_inheritedFlags.colorRendering != other.m_inheritedFlags.colorRendering + || m_inheritedFlags.shapeRendering != other.m_inheritedFlags.shapeRendering + || m_inheritedFlags.clipRule != other.m_inheritedFlags.clipRule + || m_inheritedFlags.fillRule != other.m_inheritedFlags.fillRule + || m_inheritedFlags.colorInterpolation != other.m_inheritedFlags.colorInterpolation + || m_inheritedFlags.colorInterpolationFilters != other.m_inheritedFlags.colorInterpolationFilters) return StyleDifferenceRepaint; - // FIXME: vector-effect is not taken into account in the layout-phase. Once this is fixed, we should relayout here. - if (svg_noninherited_flags.f._vectorEffect != other->svg_noninherited_flags.f._vectorEffect) + if (m_nonInheritedFlags.flagBits.bufferedRendering != other.m_nonInheritedFlags.flagBits.bufferedRendering) return StyleDifferenceRepaint; - if (svg_noninherited_flags.f.bufferedRendering != other->svg_noninherited_flags.f.bufferedRendering) - return StyleDifferenceRepaint; - - if (svg_noninherited_flags.f.maskType != other->svg_noninherited_flags.f.maskType) + if (m_nonInheritedFlags.flagBits.maskType != other.m_nonInheritedFlags.flagBits.maskType) return StyleDifferenceRepaint; return StyleDifferenceEqual; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/rendering/style/SVGRenderStyle.h b/Source/WebCore/rendering/style/SVGRenderStyle.h index ff07db54c..24b5e6f25 100644 --- a/Source/WebCore/rendering/style/SVGRenderStyle.h +++ b/Source/WebCore/rendering/style/SVGRenderStyle.h @@ -1,8 +1,9 @@ /* Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> - Copyright (C) 2005, 2006 Apple Computer, Inc. + Copyright (C) 2005-2017 Apple Inc. All rights reserved. Copyright (C) Research In Motion Limited 2010. All rights reserved. + Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -20,40 +21,31 @@ Boston, MA 02110-1301, USA. */ -#ifndef SVGRenderStyle_h -#define SVGRenderStyle_h +#pragma once -#if ENABLE(SVG) -#include "CSSValueList.h" #include "DataRef.h" -#include "ExceptionCodePlaceholder.h" #include "GraphicsTypes.h" #include "Path.h" #include "RenderStyleConstants.h" -#include "SVGPaint.h" #include "SVGRenderStyleDefs.h" namespace WebCore { -class FloatRect; -class IntRect; -class RenderObject; - -class SVGRenderStyle : public RefCounted<SVGRenderStyle> { +class SVGRenderStyle : public RefCounted<SVGRenderStyle> { public: - static PassRef<SVGRenderStyle> createDefaultStyle(); - static PassRef<SVGRenderStyle> create() { return adoptRef(*new SVGRenderStyle); } - PassRef<SVGRenderStyle> copy() const; + static Ref<SVGRenderStyle> createDefaultStyle(); + static Ref<SVGRenderStyle> create() { return adoptRef(*new SVGRenderStyle); } + Ref<SVGRenderStyle> copy() const; ~SVGRenderStyle(); - bool inheritedNotEqual(const SVGRenderStyle*) const; - void inheritFrom(const SVGRenderStyle*); - void copyNonInheritedFrom(const SVGRenderStyle*); + bool inheritedNotEqual(const SVGRenderStyle&) const; + void inheritFrom(const SVGRenderStyle&); + void copyNonInheritedFrom(const SVGRenderStyle&); - StyleDifference diff(const SVGRenderStyle*) const; + StyleDifference diff(const SVGRenderStyle&) const; bool operator==(const SVGRenderStyle&) const; - bool operator!=(const SVGRenderStyle& o) const { return !(*this == o); } + bool operator!=(const SVGRenderStyle& other) const { return !(*this == other); } // Initial values for all the properties static EAlignmentBaseline initialAlignmentBaseline() { return AB_AUTO; } @@ -61,414 +53,443 @@ public: static EBaselineShift initialBaselineShift() { return BS_BASELINE; } static EVectorEffect initialVectorEffect() { return VE_NONE; } static EBufferedRendering initialBufferedRendering() { return BR_AUTO; } - static LineCap initialCapStyle() { return ButtCap; } static WindRule initialClipRule() { return RULE_NONZERO; } static EColorInterpolation initialColorInterpolation() { return CI_SRGB; } static EColorInterpolation initialColorInterpolationFilters() { return CI_LINEARRGB; } static EColorRendering initialColorRendering() { return CR_AUTO; } static WindRule initialFillRule() { return RULE_NONZERO; } - static LineJoin initialJoinStyle() { return MiterJoin; } static EShapeRendering initialShapeRendering() { return SR_AUTO; } static ETextAnchor initialTextAnchor() { return TA_START; } - static SVGWritingMode initialWritingMode() { return WM_LRTB; } static EGlyphOrientation initialGlyphOrientationHorizontal() { return GO_0DEG; } static EGlyphOrientation initialGlyphOrientationVertical() { return GO_AUTO; } static float initialFillOpacity() { return 1; } - static SVGPaint::SVGPaintType initialFillPaintType() { return SVGPaint::SVG_PAINTTYPE_RGBCOLOR; } + static SVGPaintType initialFillPaintType() { return SVG_PAINTTYPE_RGBCOLOR; } static Color initialFillPaintColor() { return Color::black; } static String initialFillPaintUri() { return String(); } static float initialStrokeOpacity() { return 1; } - static SVGPaint::SVGPaintType initialStrokePaintType() { return SVGPaint::SVG_PAINTTYPE_NONE; } + static SVGPaintType initialStrokePaintType() { return SVG_PAINTTYPE_NONE; } static Color initialStrokePaintColor() { return Color(); } static String initialStrokePaintUri() { return String(); } - static Vector<SVGLength> initialStrokeDashArray() { return Vector<SVGLength>(); } + static Vector<SVGLengthValue> initialStrokeDashArray() { return { }; } static float initialStrokeMiterLimit() { return 4; } static float initialStopOpacity() { return 1; } static Color initialStopColor() { return Color(0, 0, 0); } static float initialFloodOpacity() { return 1; } static Color initialFloodColor() { return Color(0, 0, 0); } static Color initialLightingColor() { return Color(255, 255, 255); } - static ShadowData* initialShadow() { return 0; } + static ShadowData* initialShadow() { return nullptr; } static String initialClipperResource() { return String(); } - static String initialFilterResource() { return String(); } static String initialMaskerResource() { return String(); } static String initialMarkerStartResource() { return String(); } static String initialMarkerMidResource() { return String(); } static String initialMarkerEndResource() { return String(); } static EMaskType initialMaskType() { return MT_LUMINANCE; } - - static SVGLength initialBaselineShiftValue() - { - SVGLength length; - length.newValueSpecifiedUnits(LengthTypeNumber, 0, ASSERT_NO_EXCEPTION); - return length; - } - - static SVGLength initialKerning() - { - SVGLength length; - length.newValueSpecifiedUnits(LengthTypeNumber, 0, ASSERT_NO_EXCEPTION); - return length; - } - - static SVGLength initialStrokeDashOffset() - { - SVGLength length; - length.newValueSpecifiedUnits(LengthTypeNumber, 0, ASSERT_NO_EXCEPTION); - return length; - } - - static SVGLength initialStrokeWidth() - { - SVGLength length; - length.newValueSpecifiedUnits(LengthTypeNumber, 1, ASSERT_NO_EXCEPTION); - return length; - } + static SVGLengthValue initialBaselineShiftValue(); + static SVGLengthValue initialKerning(); // SVG CSS Property setters - void setAlignmentBaseline(EAlignmentBaseline val) { svg_noninherited_flags.f._alignmentBaseline = val; } - void setDominantBaseline(EDominantBaseline val) { svg_noninherited_flags.f._dominantBaseline = val; } - void setBaselineShift(EBaselineShift val) { svg_noninherited_flags.f._baselineShift = val; } - void setVectorEffect(EVectorEffect val) { svg_noninherited_flags.f._vectorEffect = val; } - void setBufferedRendering(EBufferedRendering val) { svg_noninherited_flags.f.bufferedRendering = val; } - void setCapStyle(LineCap val) { svg_inherited_flags._capStyle = val; } - void setClipRule(WindRule val) { svg_inherited_flags._clipRule = val; } - void setColorInterpolation(EColorInterpolation val) { svg_inherited_flags._colorInterpolation = val; } - void setColorInterpolationFilters(EColorInterpolation val) { svg_inherited_flags._colorInterpolationFilters = val; } - void setColorRendering(EColorRendering val) { svg_inherited_flags._colorRendering = val; } - void setFillRule(WindRule val) { svg_inherited_flags._fillRule = val; } - void setJoinStyle(LineJoin val) { svg_inherited_flags._joinStyle = val; } - void setShapeRendering(EShapeRendering val) { svg_inherited_flags._shapeRendering = val; } - void setTextAnchor(ETextAnchor val) { svg_inherited_flags._textAnchor = val; } - void setWritingMode(SVGWritingMode val) { svg_inherited_flags._writingMode = val; } - void setGlyphOrientationHorizontal(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationHorizontal = val; } - void setGlyphOrientationVertical(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationVertical = val; } - void setMaskType(EMaskType val) { svg_noninherited_flags.f.maskType = val; } - - void setFillOpacity(float obj) - { - if (!(fill->opacity == obj)) - fill.access()->opacity = obj; - } - - void setFillPaint(SVGPaint::SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false) - { - if (applyToRegularStyle) { - if (!(fill->paintType == type)) - fill.access()->paintType = type; - if (!(fill->paintColor == color)) - fill.access()->paintColor = color; - if (!(fill->paintUri == uri)) - fill.access()->paintUri = uri; - } - if (applyToVisitedLinkStyle) { - if (!(fill->visitedLinkPaintType == type)) - fill.access()->visitedLinkPaintType = type; - if (!(fill->visitedLinkPaintColor == color)) - fill.access()->visitedLinkPaintColor = color; - if (!(fill->visitedLinkPaintUri == uri)) - fill.access()->visitedLinkPaintUri = uri; - } - } - - void setStrokeOpacity(float obj) - { - if (!(stroke->opacity == obj)) - stroke.access()->opacity = obj; - } - - void setStrokePaint(SVGPaint::SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false) - { - if (applyToRegularStyle) { - if (!(stroke->paintType == type)) - stroke.access()->paintType = type; - if (!(stroke->paintColor == color)) - stroke.access()->paintColor = color; - if (!(stroke->paintUri == uri)) - stroke.access()->paintUri = uri; - } - if (applyToVisitedLinkStyle) { - if (!(stroke->visitedLinkPaintType == type)) - stroke.access()->visitedLinkPaintType = type; - if (!(stroke->visitedLinkPaintColor == color)) - stroke.access()->visitedLinkPaintColor = color; - if (!(stroke->visitedLinkPaintUri == uri)) - stroke.access()->visitedLinkPaintUri = uri; - } - } - - void setStrokeDashArray(const Vector<SVGLength>& obj) - { - if (!(stroke->dashArray == obj)) - stroke.access()->dashArray = obj; - } - - void setStrokeMiterLimit(float obj) - { - if (!(stroke->miterLimit == obj)) - stroke.access()->miterLimit = obj; - } - - void setStrokeWidth(const SVGLength& obj) - { - if (!(stroke->width == obj)) - stroke.access()->width = obj; - } - - void setStrokeDashOffset(const SVGLength& obj) - { - if (!(stroke->dashOffset == obj)) - stroke.access()->dashOffset = obj; - } - - void setKerning(const SVGLength& obj) - { - if (!(text->kerning == obj)) - text.access()->kerning = obj; - } - - void setStopOpacity(float obj) - { - if (!(stops->opacity == obj)) - stops.access()->opacity = obj; - } - - void setStopColor(const Color& obj) - { - if (!(stops->color == obj)) - stops.access()->color = obj; - } - - void setFloodOpacity(float obj) - { - if (!(misc->floodOpacity == obj)) - misc.access()->floodOpacity = obj; - } - - void setFloodColor(const Color& obj) - { - if (!(misc->floodColor == obj)) - misc.access()->floodColor = obj; - } - - void setLightingColor(const Color& obj) - { - if (!(misc->lightingColor == obj)) - misc.access()->lightingColor = obj; - } - - void setBaselineShiftValue(const SVGLength& obj) - { - if (!(misc->baselineShiftValue == obj)) - misc.access()->baselineShiftValue = obj; - } - - void setShadow(PassOwnPtr<ShadowData> obj) { shadowSVG.access()->shadow = obj; } + void setAlignmentBaseline(EAlignmentBaseline val) { m_nonInheritedFlags.flagBits.alignmentBaseline = val; } + void setDominantBaseline(EDominantBaseline val) { m_nonInheritedFlags.flagBits.dominantBaseline = val; } + void setBaselineShift(EBaselineShift val) { m_nonInheritedFlags.flagBits.baselineShift = val; } + void setVectorEffect(EVectorEffect val) { m_nonInheritedFlags.flagBits.vectorEffect = val; } + void setBufferedRendering(EBufferedRendering val) { m_nonInheritedFlags.flagBits.bufferedRendering = val; } + void setClipRule(WindRule val) { m_inheritedFlags.clipRule = val; } + void setColorInterpolation(EColorInterpolation val) { m_inheritedFlags.colorInterpolation = val; } + void setColorInterpolationFilters(EColorInterpolation val) { m_inheritedFlags.colorInterpolationFilters = val; } + void setColorRendering(EColorRendering val) { m_inheritedFlags.colorRendering = val; } + void setFillRule(WindRule val) { m_inheritedFlags.fillRule = val; } + void setShapeRendering(EShapeRendering val) { m_inheritedFlags.shapeRendering = val; } + void setTextAnchor(ETextAnchor val) { m_inheritedFlags.textAnchor = val; } + void setGlyphOrientationHorizontal(EGlyphOrientation val) { m_inheritedFlags.glyphOrientationHorizontal = val; } + void setGlyphOrientationVertical(EGlyphOrientation val) { m_inheritedFlags.glyphOrientationVertical = val; } + void setMaskType(EMaskType val) { m_nonInheritedFlags.flagBits.maskType = val; } + void setCx(const Length&); + void setCy(const Length&); + void setR(const Length&); + void setRx(const Length&); + void setRy(const Length&); + void setX(const Length&); + void setY(const Length&); + void setFillOpacity(float); + void setFillPaint(SVGPaintType, const Color&, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false); + void setStrokeOpacity(float); + void setStrokePaint(SVGPaintType, const Color&, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false); + + void setStrokeDashArray(const Vector<SVGLengthValue>&); + void setStrokeMiterLimit(float); + void setStrokeDashOffset(const Length&); + void setKerning(const SVGLengthValue&); + void setStopOpacity(float); + void setStopColor(const Color&); + void setFloodOpacity(float); + void setFloodColor(const Color&); + void setLightingColor(const Color&); + void setBaselineShiftValue(const SVGLengthValue&); + + void setShadow(std::unique_ptr<ShadowData>&& data) { m_shadowData.access().shadow = WTFMove(data); } // Setters for non-inherited resources - void setClipperResource(const String& obj) - { - if (!(resources->clipper == obj)) - resources.access()->clipper = obj; - } - - void setFilterResource(const String& obj) - { - if (!(resources->filter == obj)) - resources.access()->filter = obj; - } - - void setMaskerResource(const String& obj) - { - if (!(resources->masker == obj)) - resources.access()->masker = obj; - } + void setClipperResource(const String&); + void setMaskerResource(const String&); // Setters for inherited resources - void setMarkerStartResource(const String& obj) - { - if (!(inheritedResources->markerStart == obj)) - inheritedResources.access()->markerStart = obj; - } - - void setMarkerMidResource(const String& obj) - { - if (!(inheritedResources->markerMid == obj)) - inheritedResources.access()->markerMid = obj; - } - - void setMarkerEndResource(const String& obj) - { - if (!(inheritedResources->markerEnd == obj)) - inheritedResources.access()->markerEnd = obj; - } + void setMarkerStartResource(const String&); + void setMarkerMidResource(const String&); + void setMarkerEndResource(const String&); // Read accessors for all the properties - EAlignmentBaseline alignmentBaseline() const { return (EAlignmentBaseline) svg_noninherited_flags.f._alignmentBaseline; } - EDominantBaseline dominantBaseline() const { return (EDominantBaseline) svg_noninherited_flags.f._dominantBaseline; } - EBaselineShift baselineShift() const { return (EBaselineShift) svg_noninherited_flags.f._baselineShift; } - EVectorEffect vectorEffect() const { return (EVectorEffect) svg_noninherited_flags.f._vectorEffect; } - EBufferedRendering bufferedRendering() const { return (EBufferedRendering) svg_noninherited_flags.f.bufferedRendering; } - LineCap capStyle() const { return (LineCap) svg_inherited_flags._capStyle; } - WindRule clipRule() const { return (WindRule) svg_inherited_flags._clipRule; } - EColorInterpolation colorInterpolation() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolation; } - EColorInterpolation colorInterpolationFilters() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolationFilters; } - EColorRendering colorRendering() const { return (EColorRendering) svg_inherited_flags._colorRendering; } - WindRule fillRule() const { return (WindRule) svg_inherited_flags._fillRule; } - LineJoin joinStyle() const { return (LineJoin) svg_inherited_flags._joinStyle; } - EShapeRendering shapeRendering() const { return (EShapeRendering) svg_inherited_flags._shapeRendering; } - ETextAnchor textAnchor() const { return (ETextAnchor) svg_inherited_flags._textAnchor; } - SVGWritingMode writingMode() const { return (SVGWritingMode) svg_inherited_flags._writingMode; } - EGlyphOrientation glyphOrientationHorizontal() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationHorizontal; } - EGlyphOrientation glyphOrientationVertical() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationVertical; } - float fillOpacity() const { return fill->opacity; } - const SVGPaint::SVGPaintType& fillPaintType() const { return fill->paintType; } - const Color& fillPaintColor() const { return fill->paintColor; } - const String& fillPaintUri() const { return fill->paintUri; } - float strokeOpacity() const { return stroke->opacity; } - const SVGPaint::SVGPaintType& strokePaintType() const { return stroke->paintType; } - const Color& strokePaintColor() const { return stroke->paintColor; } - const String& strokePaintUri() const { return stroke->paintUri; } - Vector<SVGLength> strokeDashArray() const { return stroke->dashArray; } - float strokeMiterLimit() const { return stroke->miterLimit; } - SVGLength strokeWidth() const { return stroke->width; } - SVGLength strokeDashOffset() const { return stroke->dashOffset; } - SVGLength kerning() const { return text->kerning; } - float stopOpacity() const { return stops->opacity; } - const Color& stopColor() const { return stops->color; } - float floodOpacity() const { return misc->floodOpacity; } - const Color& floodColor() const { return misc->floodColor; } - const Color& lightingColor() const { return misc->lightingColor; } - SVGLength baselineShiftValue() const { return misc->baselineShiftValue; } - ShadowData* shadow() const { return shadowSVG->shadow.get(); } - String clipperResource() const { return resources->clipper; } - String filterResource() const { return resources->filter; } - String maskerResource() const { return resources->masker; } - String markerStartResource() const { return inheritedResources->markerStart; } - String markerMidResource() const { return inheritedResources->markerMid; } - String markerEndResource() const { return inheritedResources->markerEnd; } - EMaskType maskType() const { return (EMaskType) svg_noninherited_flags.f.maskType; } - - const SVGPaint::SVGPaintType& visitedLinkFillPaintType() const { return fill->visitedLinkPaintType; } - const Color& visitedLinkFillPaintColor() const { return fill->visitedLinkPaintColor; } - const String& visitedLinkFillPaintUri() const { return fill->visitedLinkPaintUri; } - const SVGPaint::SVGPaintType& visitedLinkStrokePaintType() const { return stroke->visitedLinkPaintType; } - const Color& visitedLinkStrokePaintColor() const { return stroke->visitedLinkPaintColor; } - const String& visitedLinkStrokePaintUri() const { return stroke->visitedLinkPaintUri; } + EAlignmentBaseline alignmentBaseline() const { return (EAlignmentBaseline) m_nonInheritedFlags.flagBits.alignmentBaseline; } + EDominantBaseline dominantBaseline() const { return (EDominantBaseline) m_nonInheritedFlags.flagBits.dominantBaseline; } + EBaselineShift baselineShift() const { return (EBaselineShift) m_nonInheritedFlags.flagBits.baselineShift; } + EVectorEffect vectorEffect() const { return (EVectorEffect) m_nonInheritedFlags.flagBits.vectorEffect; } + EBufferedRendering bufferedRendering() const { return (EBufferedRendering) m_nonInheritedFlags.flagBits.bufferedRendering; } + WindRule clipRule() const { return (WindRule) m_inheritedFlags.clipRule; } + EColorInterpolation colorInterpolation() const { return (EColorInterpolation) m_inheritedFlags.colorInterpolation; } + EColorInterpolation colorInterpolationFilters() const { return (EColorInterpolation) m_inheritedFlags.colorInterpolationFilters; } + EColorRendering colorRendering() const { return (EColorRendering) m_inheritedFlags.colorRendering; } + WindRule fillRule() const { return (WindRule) m_inheritedFlags.fillRule; } + EShapeRendering shapeRendering() const { return (EShapeRendering) m_inheritedFlags.shapeRendering; } + ETextAnchor textAnchor() const { return (ETextAnchor) m_inheritedFlags.textAnchor; } + EGlyphOrientation glyphOrientationHorizontal() const { return (EGlyphOrientation) m_inheritedFlags.glyphOrientationHorizontal; } + EGlyphOrientation glyphOrientationVertical() const { return (EGlyphOrientation) m_inheritedFlags.glyphOrientationVertical; } + float fillOpacity() const { return m_fillData->opacity; } + const SVGPaintType& fillPaintType() const { return m_fillData->paintType; } + const Color& fillPaintColor() const { return m_fillData->paintColor; } + const String& fillPaintUri() const { return m_fillData->paintUri; } + float strokeOpacity() const { return m_strokeData->opacity; } + const SVGPaintType& strokePaintType() const { return m_strokeData->paintType; } + const Color& strokePaintColor() const { return m_strokeData->paintColor; } + const String& strokePaintUri() const { return m_strokeData->paintUri; } + Vector<SVGLengthValue> strokeDashArray() const { return m_strokeData->dashArray; } + float strokeMiterLimit() const { return m_strokeData->miterLimit; } + const Length& strokeDashOffset() const { return m_strokeData->dashOffset; } + SVGLengthValue kerning() const { return m_textData->kerning; } + float stopOpacity() const { return m_stopData->opacity; } + const Color& stopColor() const { return m_stopData->color; } + float floodOpacity() const { return m_miscData->floodOpacity; } + const Color& floodColor() const { return m_miscData->floodColor; } + const Color& lightingColor() const { return m_miscData->lightingColor; } + SVGLengthValue baselineShiftValue() const { return m_miscData->baselineShiftValue; } + ShadowData* shadow() const { return m_shadowData->shadow.get(); } + const Length& cx() const { return m_layoutData->cx; } + const Length& cy() const { return m_layoutData->cy; } + const Length& r() const { return m_layoutData->r; } + const Length& rx() const { return m_layoutData->rx; } + const Length& ry() const { return m_layoutData->ry; } + const Length& x() const { return m_layoutData->x; } + const Length& y() const { return m_layoutData->y; } + const String& clipperResource() const { return m_nonInheritedResourceData->clipper; } + const String& maskerResource() const { return m_nonInheritedResourceData->masker; } + const String& markerStartResource() const { return m_inheritedResourceData->markerStart; } + const String& markerMidResource() const { return m_inheritedResourceData->markerMid; } + const String& markerEndResource() const { return m_inheritedResourceData->markerEnd; } + EMaskType maskType() const { return (EMaskType) m_nonInheritedFlags.flagBits.maskType; } + + const SVGPaintType& visitedLinkFillPaintType() const { return m_fillData->visitedLinkPaintType; } + const Color& visitedLinkFillPaintColor() const { return m_fillData->visitedLinkPaintColor; } + const String& visitedLinkFillPaintUri() const { return m_fillData->visitedLinkPaintUri; } + const SVGPaintType& visitedLinkStrokePaintType() const { return m_strokeData->visitedLinkPaintType; } + const Color& visitedLinkStrokePaintColor() const { return m_strokeData->visitedLinkPaintColor; } + const String& visitedLinkStrokePaintUri() const { return m_strokeData->visitedLinkPaintUri; } // convenience bool hasClipper() const { return !clipperResource().isEmpty(); } bool hasMasker() const { return !maskerResource().isEmpty(); } - bool hasFilter() const { return !filterResource().isEmpty(); } bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); } - bool hasStroke() const { return strokePaintType() != SVGPaint::SVG_PAINTTYPE_NONE; } - bool hasVisibleStroke() const { return hasStroke() && !strokeWidth().isZero(); } - bool hasFill() const { return fillPaintType() != SVGPaint::SVG_PAINTTYPE_NONE; } - bool isVerticalWritingMode() const { return writingMode() == WM_TBRL || writingMode() == WM_TB; } + bool hasStroke() const { return strokePaintType() != SVG_PAINTTYPE_NONE; } + bool hasFill() const { return fillPaintType() != SVG_PAINTTYPE_NONE; } + bool isolatesBlending() const { return hasMasker() || shadow(); } + +private: + SVGRenderStyle(); + SVGRenderStyle(const SVGRenderStyle&); + + enum CreateDefaultType { CreateDefault }; + SVGRenderStyle(CreateDefaultType); // Used to create the default style. + + void setBitDefaults(); -protected: - // inherit struct InheritedFlags { - bool operator==(const InheritedFlags& other) const - { - return (_colorRendering == other._colorRendering) - && (_shapeRendering == other._shapeRendering) - && (_clipRule == other._clipRule) - && (_fillRule == other._fillRule) - && (_capStyle == other._capStyle) - && (_joinStyle == other._joinStyle) - && (_textAnchor == other._textAnchor) - && (_colorInterpolation == other._colorInterpolation) - && (_colorInterpolationFilters == other._colorInterpolationFilters) - && (_writingMode == other._writingMode) - && (_glyphOrientationHorizontal == other._glyphOrientationHorizontal) - && (_glyphOrientationVertical == other._glyphOrientationVertical); - } - - bool operator!=(const InheritedFlags& other) const - { - return !(*this == other); - } - - unsigned _colorRendering : 2; // EColorRendering - unsigned _shapeRendering : 2; // EShapeRendering - unsigned _clipRule : 1; // WindRule - unsigned _fillRule : 1; // WindRule - unsigned _capStyle : 2; // LineCap - unsigned _joinStyle : 2; // LineJoin - unsigned _textAnchor : 2; // ETextAnchor - unsigned _colorInterpolation : 2; // EColorInterpolation - unsigned _colorInterpolationFilters : 2; // EColorInterpolation - unsigned _writingMode : 3; // SVGWritingMode - unsigned _glyphOrientationHorizontal : 3; // EGlyphOrientation - unsigned _glyphOrientationVertical : 3; // EGlyphOrientation - } svg_inherited_flags; - - // don't inherit + bool operator==(const InheritedFlags&) const; + bool operator!=(const InheritedFlags& other) const { return !(*this == other); } + + unsigned colorRendering : 2; // EColorRendering + unsigned shapeRendering : 2; // EShapeRendering + unsigned clipRule : 1; // WindRule + unsigned fillRule : 1; // WindRule + unsigned textAnchor : 2; // ETextAnchor + unsigned colorInterpolation : 2; // EColorInterpolation + unsigned colorInterpolationFilters : 2; // EColorInterpolation + unsigned glyphOrientationHorizontal : 3; // EGlyphOrientation + unsigned glyphOrientationVertical : 3; // EGlyphOrientation + }; + struct NonInheritedFlags { // 32 bit non-inherited, don't add to the struct, or the operator will break. - bool operator==(const NonInheritedFlags &other) const { return _niflags == other._niflags; } - bool operator!=(const NonInheritedFlags &other) const { return _niflags != other._niflags; } + bool operator==(const NonInheritedFlags& other) const { return flags == other.flags; } + bool operator!=(const NonInheritedFlags& other) const { return flags != other.flags; } union { struct { - unsigned _alignmentBaseline : 4; // EAlignmentBaseline - unsigned _dominantBaseline : 4; // EDominantBaseline - unsigned _baselineShift : 2; // EBaselineShift - unsigned _vectorEffect: 1; // EVectorEffect + unsigned alignmentBaseline : 4; // EAlignmentBaseline + unsigned dominantBaseline : 4; // EDominantBaseline + unsigned baselineShift : 2; // EBaselineShift + unsigned vectorEffect: 1; // EVectorEffect unsigned bufferedRendering: 2; // EBufferedRendering unsigned maskType: 1; // EMaskType // 18 bits unused - } f; - uint32_t _niflags; + } flagBits; + uint32_t flags; }; - } svg_noninherited_flags; + }; + + InheritedFlags m_inheritedFlags; + NonInheritedFlags m_nonInheritedFlags; // inherited attributes - DataRef<StyleFillData> fill; - DataRef<StyleStrokeData> stroke; - DataRef<StyleTextData> text; - DataRef<StyleInheritedResourceData> inheritedResources; + DataRef<StyleFillData> m_fillData; + DataRef<StyleStrokeData> m_strokeData; + DataRef<StyleTextData> m_textData; + DataRef<StyleInheritedResourceData> m_inheritedResourceData; // non-inherited attributes - DataRef<StyleStopData> stops; - DataRef<StyleMiscData> misc; - DataRef<StyleShadowSVGData> shadowSVG; - DataRef<StyleResourceData> resources; - -private: - enum CreateDefaultType { CreateDefault }; - - SVGRenderStyle(); - SVGRenderStyle(const SVGRenderStyle&); - SVGRenderStyle(CreateDefaultType); // Used to create the default style. + DataRef<StyleStopData> m_stopData; + DataRef<StyleMiscData> m_miscData; + DataRef<StyleShadowSVGData> m_shadowData; + DataRef<StyleLayoutData> m_layoutData; + DataRef<StyleResourceData> m_nonInheritedResourceData; +}; - void setBitDefaults() - { - svg_inherited_flags._clipRule = initialClipRule(); - svg_inherited_flags._colorRendering = initialColorRendering(); - svg_inherited_flags._fillRule = initialFillRule(); - svg_inherited_flags._shapeRendering = initialShapeRendering(); - svg_inherited_flags._textAnchor = initialTextAnchor(); - svg_inherited_flags._capStyle = initialCapStyle(); - svg_inherited_flags._joinStyle = initialJoinStyle(); - svg_inherited_flags._colorInterpolation = initialColorInterpolation(); - svg_inherited_flags._colorInterpolationFilters = initialColorInterpolationFilters(); - svg_inherited_flags._writingMode = initialWritingMode(); - svg_inherited_flags._glyphOrientationHorizontal = initialGlyphOrientationHorizontal(); - svg_inherited_flags._glyphOrientationVertical = initialGlyphOrientationVertical(); - - svg_noninherited_flags._niflags = 0; - svg_noninherited_flags.f._alignmentBaseline = initialAlignmentBaseline(); - svg_noninherited_flags.f._dominantBaseline = initialDominantBaseline(); - svg_noninherited_flags.f._baselineShift = initialBaselineShift(); - svg_noninherited_flags.f._vectorEffect = initialVectorEffect(); - svg_noninherited_flags.f.bufferedRendering = initialBufferedRendering(); - svg_noninherited_flags.f.maskType = initialMaskType(); +inline SVGLengthValue SVGRenderStyle::initialBaselineShiftValue() +{ + SVGLengthValue length; + length.newValueSpecifiedUnits(LengthTypeNumber, 0); + return length; +} + +inline SVGLengthValue SVGRenderStyle::initialKerning() +{ + SVGLengthValue length; + length.newValueSpecifiedUnits(LengthTypeNumber, 0); + return length; +} + +inline void SVGRenderStyle::setCx(const Length& length) +{ + if (!(m_layoutData->cx == length)) + m_layoutData.access().cx = length; +} + +inline void SVGRenderStyle::setCy(const Length& length) +{ + if (!(m_layoutData->cy == length)) + m_layoutData.access().cy = length; +} + +inline void SVGRenderStyle::setR(const Length& length) +{ + if (!(m_layoutData->r == length)) + m_layoutData.access().r = length; +} + +inline void SVGRenderStyle::setRx(const Length& length) +{ + if (!(m_layoutData->rx == length)) + m_layoutData.access().rx = length; +} + +inline void SVGRenderStyle::setRy(const Length& length) +{ + if (!(m_layoutData->ry == length)) + m_layoutData.access().ry = length; +} + +inline void SVGRenderStyle::setX(const Length& length) +{ + if (!(m_layoutData->x == length)) + m_layoutData.access().x = length; +} + +inline void SVGRenderStyle::setY(const Length& length) +{ + if (!(m_layoutData->y == length)) + m_layoutData.access().y = length; +} + +inline void SVGRenderStyle::setFillOpacity(float opacity) +{ + if (!(m_fillData->opacity == opacity)) + m_fillData.access().opacity = opacity; +} + +inline void SVGRenderStyle::setFillPaint(SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle, bool applyToVisitedLinkStyle) +{ + if (applyToRegularStyle) { + if (!(m_fillData->paintType == type)) + m_fillData.access().paintType = type; + if (!(m_fillData->paintColor == color)) + m_fillData.access().paintColor = color; + if (!(m_fillData->paintUri == uri)) + m_fillData.access().paintUri = uri; } -}; + if (applyToVisitedLinkStyle) { + if (!(m_fillData->visitedLinkPaintType == type)) + m_fillData.access().visitedLinkPaintType = type; + if (!(m_fillData->visitedLinkPaintColor == color)) + m_fillData.access().visitedLinkPaintColor = color; + if (!(m_fillData->visitedLinkPaintUri == uri)) + m_fillData.access().visitedLinkPaintUri = uri; + } +} + +inline void SVGRenderStyle::setStrokeOpacity(float opacity) +{ + if (!(m_strokeData->opacity == opacity)) + m_strokeData.access().opacity = opacity; +} + +inline void SVGRenderStyle::setStrokePaint(SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle, bool applyToVisitedLinkStyle) +{ + if (applyToRegularStyle) { + if (!(m_strokeData->paintType == type)) + m_strokeData.access().paintType = type; + if (!(m_strokeData->paintColor == color)) + m_strokeData.access().paintColor = color; + if (!(m_strokeData->paintUri == uri)) + m_strokeData.access().paintUri = uri; + } + if (applyToVisitedLinkStyle) { + if (!(m_strokeData->visitedLinkPaintType == type)) + m_strokeData.access().visitedLinkPaintType = type; + if (!(m_strokeData->visitedLinkPaintColor == color)) + m_strokeData.access().visitedLinkPaintColor = color; + if (!(m_strokeData->visitedLinkPaintUri == uri)) + m_strokeData.access().visitedLinkPaintUri = uri; + } +} + +inline void SVGRenderStyle::setStrokeDashArray(const Vector<SVGLengthValue>& array) +{ + if (!(m_strokeData->dashArray == array)) + m_strokeData.access().dashArray = array; +} + +inline void SVGRenderStyle::setStrokeMiterLimit(float limit) +{ + if (!(m_strokeData->miterLimit == limit)) + m_strokeData.access().miterLimit = limit; +} + +inline void SVGRenderStyle::setStrokeDashOffset(const Length& offset) +{ + if (!(m_strokeData->dashOffset == offset)) + m_strokeData.access().dashOffset = offset; +} + +inline void SVGRenderStyle::setKerning(const SVGLengthValue& kerning) +{ + if (!(m_textData->kerning == kerning)) + m_textData.access().kerning = kerning; +} + +inline void SVGRenderStyle::setStopOpacity(float opacity) +{ + if (!(m_stopData->opacity == opacity)) + m_stopData.access().opacity = opacity; +} + +inline void SVGRenderStyle::setStopColor(const Color& color) +{ + if (!(m_stopData->color == color)) + m_stopData.access().color = color; +} + +inline void SVGRenderStyle::setFloodOpacity(float opacity) +{ + if (!(m_miscData->floodOpacity == opacity)) + m_miscData.access().floodOpacity = opacity; +} + +inline void SVGRenderStyle::setFloodColor(const Color& color) +{ + if (!(m_miscData->floodColor == color)) + m_miscData.access().floodColor = color; +} + +inline void SVGRenderStyle::setLightingColor(const Color& color) +{ + if (!(m_miscData->lightingColor == color)) + m_miscData.access().lightingColor = color; +} + +inline void SVGRenderStyle::setBaselineShiftValue(const SVGLengthValue& shiftValue) +{ + if (!(m_miscData->baselineShiftValue == shiftValue)) + m_miscData.access().baselineShiftValue = shiftValue; +} + +inline void SVGRenderStyle::setClipperResource(const String& resource) +{ + if (!(m_nonInheritedResourceData->clipper == resource)) + m_nonInheritedResourceData.access().clipper = resource; +} + +inline void SVGRenderStyle::setMaskerResource(const String& resource) +{ + if (!(m_nonInheritedResourceData->masker == resource)) + m_nonInheritedResourceData.access().masker = resource; +} + +inline void SVGRenderStyle::setMarkerStartResource(const String& resource) +{ + if (!(m_inheritedResourceData->markerStart == resource)) + m_inheritedResourceData.access().markerStart = resource; +} + +inline void SVGRenderStyle::setMarkerMidResource(const String& resource) +{ + if (!(m_inheritedResourceData->markerMid == resource)) + m_inheritedResourceData.access().markerMid = resource; +} + +inline void SVGRenderStyle::setMarkerEndResource(const String& resource) +{ + if (!(m_inheritedResourceData->markerEnd == resource)) + m_inheritedResourceData.access().markerEnd = resource; +} + +inline void SVGRenderStyle::setBitDefaults() +{ + m_inheritedFlags.clipRule = initialClipRule(); + m_inheritedFlags.colorRendering = initialColorRendering(); + m_inheritedFlags.fillRule = initialFillRule(); + m_inheritedFlags.shapeRendering = initialShapeRendering(); + m_inheritedFlags.textAnchor = initialTextAnchor(); + m_inheritedFlags.colorInterpolation = initialColorInterpolation(); + m_inheritedFlags.colorInterpolationFilters = initialColorInterpolationFilters(); + m_inheritedFlags.glyphOrientationHorizontal = initialGlyphOrientationHorizontal(); + m_inheritedFlags.glyphOrientationVertical = initialGlyphOrientationVertical(); + + m_nonInheritedFlags.flags = 0; + m_nonInheritedFlags.flagBits.alignmentBaseline = initialAlignmentBaseline(); + m_nonInheritedFlags.flagBits.dominantBaseline = initialDominantBaseline(); + m_nonInheritedFlags.flagBits.baselineShift = initialBaselineShift(); + m_nonInheritedFlags.flagBits.vectorEffect = initialVectorEffect(); + m_nonInheritedFlags.flagBits.bufferedRendering = initialBufferedRendering(); + m_nonInheritedFlags.flagBits.maskType = initialMaskType(); +} + +inline bool SVGRenderStyle::InheritedFlags::operator==(const InheritedFlags& other) const +{ + return colorRendering == other.colorRendering + && shapeRendering == other.shapeRendering + && clipRule == other.clipRule + && fillRule == other.fillRule + && textAnchor == other.textAnchor + && colorInterpolation == other.colorInterpolation + && colorInterpolationFilters == other.colorInterpolationFilters + && glyphOrientationHorizontal == other.glyphOrientationHorizontal + && glyphOrientationVertical == other.glyphOrientationVertical; +} } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGRenderStyle_h diff --git a/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp b/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp index aed179b9c..9f023e5c8 100644 --- a/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp +++ b/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp @@ -2,12 +2,13 @@ Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2007 Rob Buis <buis@kde.org> Copyright (C) Research In Motion Limited 2010. All rights reserved. + Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved. Based on khtml code by: Copyright (C) 1999 Antti Koivisto (koivisto@kde.org) Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) Copyright (C) 2002-2003 Dirk Mueller (mueller@kde.org) - Copyright (C) 2002 Apple Computer, Inc. + Copyright (C) 2002 Apple Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -26,12 +27,11 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGRenderStyleDefs.h" #include "RenderStyle.h" #include "SVGRenderStyle.h" +#include <wtf/PointerComparison.h> namespace WebCore { @@ -58,7 +58,7 @@ inline StyleFillData::StyleFillData(const StyleFillData& other) { } -PassRef<StyleFillData> StyleFillData::copy() const +Ref<StyleFillData> StyleFillData::copy() const { return adoptRef(*new StyleFillData(*this)); } @@ -77,8 +77,7 @@ bool StyleFillData::operator==(const StyleFillData& other) const StyleStrokeData::StyleStrokeData() : opacity(SVGRenderStyle::initialStrokeOpacity()) , miterLimit(SVGRenderStyle::initialStrokeMiterLimit()) - , width(SVGRenderStyle::initialStrokeWidth()) - , dashOffset(SVGRenderStyle::initialStrokeDashOffset()) + , dashOffset(RenderStyle::initialZeroLength()) , dashArray(SVGRenderStyle::initialStrokeDashArray()) , paintType(SVGRenderStyle::initialStrokePaintType()) , paintColor(SVGRenderStyle::initialStrokePaintColor()) @@ -93,7 +92,6 @@ inline StyleStrokeData::StyleStrokeData(const StyleStrokeData& other) : RefCounted<StyleStrokeData>() , opacity(other.opacity) , miterLimit(other.miterLimit) - , width(other.width) , dashOffset(other.dashOffset) , dashArray(other.dashArray) , paintType(other.paintType) @@ -105,15 +103,14 @@ inline StyleStrokeData::StyleStrokeData(const StyleStrokeData& other) { } -PassRef<StyleStrokeData> StyleStrokeData::copy() const +Ref<StyleStrokeData> StyleStrokeData::copy() const { return adoptRef(*new StyleStrokeData(*this)); } bool StyleStrokeData::operator==(const StyleStrokeData& other) const { - return width == other.width - && opacity == other.opacity + return opacity == other.opacity && miterLimit == other.miterLimit && dashOffset == other.dashOffset && dashArray == other.dashArray @@ -138,7 +135,7 @@ inline StyleStopData::StyleStopData(const StyleStopData& other) { } -PassRef<StyleStopData> StyleStopData::copy() const +Ref<StyleStopData> StyleStopData::copy() const { return adoptRef(*new StyleStopData(*this)); } @@ -160,7 +157,7 @@ inline StyleTextData::StyleTextData(const StyleTextData& other) { } -PassRef<StyleTextData> StyleTextData::copy() const +Ref<StyleTextData> StyleTextData::copy() const { return adoptRef(*new StyleTextData(*this)); } @@ -187,7 +184,7 @@ inline StyleMiscData::StyleMiscData(const StyleMiscData& other) { } -PassRef<StyleMiscData> StyleMiscData::copy() const +Ref<StyleMiscData> StyleMiscData::copy() const { return adoptRef(*new StyleMiscData(*this)); } @@ -206,27 +203,22 @@ StyleShadowSVGData::StyleShadowSVGData() inline StyleShadowSVGData::StyleShadowSVGData(const StyleShadowSVGData& other) : RefCounted<StyleShadowSVGData>() - , shadow(other.shadow ? adoptPtr(new ShadowData(*other.shadow)) : nullptr) + , shadow(other.shadow ? std::make_unique<ShadowData>(*other.shadow) : nullptr) { } -PassRef<StyleShadowSVGData> StyleShadowSVGData::copy() const +Ref<StyleShadowSVGData> StyleShadowSVGData::copy() const { return adoptRef(*new StyleShadowSVGData(*this)); } bool StyleShadowSVGData::operator==(const StyleShadowSVGData& other) const { - if ((!shadow && other.shadow) || (shadow && !other.shadow)) - return false; - if (shadow && other.shadow && (*shadow != *other.shadow)) - return false; - return true; + return arePointingToEqualData(shadow, other.shadow); } StyleResourceData::StyleResourceData() : clipper(SVGRenderStyle::initialClipperResource()) - , filter(SVGRenderStyle::initialFilterResource()) , masker(SVGRenderStyle::initialMaskerResource()) { } @@ -234,12 +226,11 @@ StyleResourceData::StyleResourceData() inline StyleResourceData::StyleResourceData(const StyleResourceData& other) : RefCounted<StyleResourceData>() , clipper(other.clipper) - , filter(other.filter) , masker(other.masker) { } -PassRef<StyleResourceData> StyleResourceData::copy() const +Ref<StyleResourceData> StyleResourceData::copy() const { return adoptRef(*new StyleResourceData(*this)); } @@ -247,7 +238,6 @@ PassRef<StyleResourceData> StyleResourceData::copy() const bool StyleResourceData::operator==(const StyleResourceData& other) const { return clipper == other.clipper - && filter == other.filter && masker == other.masker; } @@ -266,7 +256,7 @@ inline StyleInheritedResourceData::StyleInheritedResourceData(const StyleInherit { } -PassRef<StyleInheritedResourceData> StyleInheritedResourceData::copy() const +Ref<StyleInheritedResourceData> StyleInheritedResourceData::copy() const { return adoptRef(*new StyleInheritedResourceData(*this)); } @@ -278,6 +268,43 @@ bool StyleInheritedResourceData::operator==(const StyleInheritedResourceData& ot && markerEnd == other.markerEnd; } +StyleLayoutData::StyleLayoutData() + : cx(RenderStyle::initialZeroLength()) + , cy(RenderStyle::initialZeroLength()) + , r(RenderStyle::initialZeroLength()) + , rx(RenderStyle::initialZeroLength()) + , ry(RenderStyle::initialZeroLength()) + , x(RenderStyle::initialZeroLength()) + , y(RenderStyle::initialZeroLength()) +{ +} + +inline StyleLayoutData::StyleLayoutData(const StyleLayoutData& other) + : RefCounted<StyleLayoutData>() + , cx(other.cx) + , cy(other.cy) + , r(other.r) + , rx(other.rx) + , ry(other.ry) + , x(other.x) + , y(other.y) +{ +} + +Ref<StyleLayoutData> StyleLayoutData::copy() const +{ + return adoptRef(*new StyleLayoutData(*this)); +} + +bool StyleLayoutData::operator==(const StyleLayoutData& other) const +{ + return cx == other.cx + && cy == other.cy + && r == other.r + && rx == other.rx + && ry == other.ry + && x == other.x + && y == other.y; } -#endif // ENABLE(SVG) +} diff --git a/Source/WebCore/rendering/style/SVGRenderStyleDefs.h b/Source/WebCore/rendering/style/SVGRenderStyleDefs.h index 9c840bc0f..7d39228ff 100644 --- a/Source/WebCore/rendering/style/SVGRenderStyleDefs.h +++ b/Source/WebCore/rendering/style/SVGRenderStyleDefs.h @@ -2,12 +2,13 @@ Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> Copyright (C) Research In Motion Limited 2010. All rights reserved. + Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved. Based on khtml code by: Copyright (C) 2000-2003 Lars Knoll (knoll@kde.org) (C) 2000 Antti Koivisto (koivisto@kde.org) (C) 2000-2003 Dirk Mueller (mueller@kde.org) - (C) 2002-2003 Apple Computer, Inc. + (C) 2002-2003 Apple Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -25,19 +26,24 @@ Boston, MA 02110-1301, USA. */ -#ifndef SVGRenderStyleDefs_h -#define SVGRenderStyleDefs_h +#pragma once -#if ENABLE(SVG) -#include "SVGLength.h" -#include "SVGPaint.h" +#include "Length.h" +#include "SVGLengthValue.h" #include "ShadowData.h" -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> namespace WebCore { + enum SVGPaintType { + SVG_PAINTTYPE_RGBCOLOR, + SVG_PAINTTYPE_NONE, + SVG_PAINTTYPE_CURRENTCOLOR, + SVG_PAINTTYPE_URI_NONE, + SVG_PAINTTYPE_URI_CURRENTCOLOR, + SVG_PAINTTYPE_URI_RGBCOLOR, + SVG_PAINTTYPE_URI + }; enum EBaselineShift { BS_BASELINE, BS_SUB, BS_SUPER, BS_LENGTH @@ -58,10 +64,6 @@ namespace WebCore { SR_AUTO, SR_OPTIMIZESPEED, SR_CRISPEDGES, SR_GEOMETRICPRECISION }; - enum SVGWritingMode { - WM_LRTB, WM_LR, WM_RLTB, WM_RL, WM_TBRL, WM_TB - }; - enum EGlyphOrientation { GO_0DEG, GO_90DEG, GO_180DEG, GO_270DEG, GO_AUTO }; @@ -94,6 +96,23 @@ namespace WebCore { MT_ALPHA }; + // These are all minimized combinations of paint-order. + enum PaintOrder { + PaintOrderNormal = 0, + PaintOrderFill = 1, + PaintOrderFillMarkers = 2, + PaintOrderStroke = 3, + PaintOrderStrokeMarkers = 4, + PaintOrderMarkers = 5, + PaintOrderMarkersStroke = 6 + }; + + enum PaintType { + PaintTypeFill, + PaintTypeStroke, + PaintTypeMarkers + }; + class CSSValue; class CSSValueList; class SVGPaint; @@ -101,8 +120,8 @@ namespace WebCore { // Inherited/Non-Inherited Style Datastructures class StyleFillData : public RefCounted<StyleFillData> { public: - static PassRef<StyleFillData> create() { return adoptRef(*new StyleFillData); } - PassRef<StyleFillData> copy() const; + static Ref<StyleFillData> create() { return adoptRef(*new StyleFillData); } + Ref<StyleFillData> copy() const; bool operator==(const StyleFillData&) const; bool operator!=(const StyleFillData& other) const @@ -111,10 +130,10 @@ namespace WebCore { } float opacity; - SVGPaint::SVGPaintType paintType; + SVGPaintType paintType; Color paintColor; String paintUri; - SVGPaint::SVGPaintType visitedLinkPaintType; + SVGPaintType visitedLinkPaintType; Color visitedLinkPaintColor; String visitedLinkPaintUri; @@ -125,8 +144,8 @@ namespace WebCore { class StyleStrokeData : public RefCounted<StyleStrokeData> { public: - static PassRef<StyleStrokeData> create() { return adoptRef(*new StyleStrokeData); } - PassRef<StyleStrokeData> copy() const; + static Ref<StyleStrokeData> create() { return adoptRef(*new StyleStrokeData); } + Ref<StyleStrokeData> copy() const; bool operator==(const StyleStrokeData&) const; bool operator!=(const StyleStrokeData& other) const @@ -137,14 +156,13 @@ namespace WebCore { float opacity; float miterLimit; - SVGLength width; - SVGLength dashOffset; - Vector<SVGLength> dashArray; + Length dashOffset; + Vector<SVGLengthValue> dashArray; - SVGPaint::SVGPaintType paintType; + SVGPaintType paintType; Color paintColor; String paintUri; - SVGPaint::SVGPaintType visitedLinkPaintType; + SVGPaintType visitedLinkPaintType; Color visitedLinkPaintColor; String visitedLinkPaintUri; @@ -155,8 +173,8 @@ namespace WebCore { class StyleStopData : public RefCounted<StyleStopData> { public: - static PassRef<StyleStopData> create() { return adoptRef(*new StyleStopData); } - PassRef<StyleStopData> copy() const; + static Ref<StyleStopData> create() { return adoptRef(*new StyleStopData); } + Ref<StyleStopData> copy() const; bool operator==(const StyleStopData&) const; bool operator!=(const StyleStopData& other) const @@ -174,8 +192,8 @@ namespace WebCore { class StyleTextData : public RefCounted<StyleTextData> { public: - static PassRef<StyleTextData> create() { return adoptRef(*new StyleTextData); } - PassRef<StyleTextData> copy() const; + static Ref<StyleTextData> create() { return adoptRef(*new StyleTextData); } + Ref<StyleTextData> copy() const; bool operator==(const StyleTextData& other) const; bool operator!=(const StyleTextData& other) const @@ -183,7 +201,7 @@ namespace WebCore { return !(*this == other); } - SVGLength kerning; + SVGLengthValue kerning; private: StyleTextData(); @@ -193,8 +211,8 @@ namespace WebCore { // Note: the rule for this class is, *no inheritance* of these props class StyleMiscData : public RefCounted<StyleMiscData> { public: - static PassRef<StyleMiscData> create() { return adoptRef(*new StyleMiscData); } - PassRef<StyleMiscData> copy() const; + static Ref<StyleMiscData> create() { return adoptRef(*new StyleMiscData); } + Ref<StyleMiscData> copy() const; bool operator==(const StyleMiscData&) const; bool operator!=(const StyleMiscData& other) const @@ -207,7 +225,7 @@ namespace WebCore { Color lightingColor; // non-inherited text stuff lives here not in StyleTextData. - SVGLength baselineShiftValue; + SVGLengthValue baselineShiftValue; private: StyleMiscData(); @@ -216,8 +234,8 @@ namespace WebCore { class StyleShadowSVGData : public RefCounted<StyleShadowSVGData> { public: - static PassRef<StyleShadowSVGData> create() { return adoptRef(*new StyleShadowSVGData); } - PassRef<StyleShadowSVGData> copy() const; + static Ref<StyleShadowSVGData> create() { return adoptRef(*new StyleShadowSVGData); } + Ref<StyleShadowSVGData> copy() const; bool operator==(const StyleShadowSVGData&) const; bool operator!=(const StyleShadowSVGData& other) const @@ -225,7 +243,7 @@ namespace WebCore { return !(*this == other); } - OwnPtr<ShadowData> shadow; + std::unique_ptr<ShadowData> shadow; private: StyleShadowSVGData(); @@ -235,8 +253,8 @@ namespace WebCore { // Non-inherited resources class StyleResourceData : public RefCounted<StyleResourceData> { public: - static PassRef<StyleResourceData> create() { return adoptRef(*new StyleResourceData); } - PassRef<StyleResourceData> copy() const; + static Ref<StyleResourceData> create() { return adoptRef(*new StyleResourceData); } + Ref<StyleResourceData> copy() const; bool operator==(const StyleResourceData&) const; bool operator!=(const StyleResourceData& other) const @@ -245,7 +263,6 @@ namespace WebCore { } String clipper; - String filter; String masker; private: @@ -256,8 +273,8 @@ namespace WebCore { // Inherited resources class StyleInheritedResourceData : public RefCounted<StyleInheritedResourceData> { public: - static PassRef<StyleInheritedResourceData> create() { return adoptRef(*new StyleInheritedResourceData); } - PassRef<StyleInheritedResourceData> copy() const; + static Ref<StyleInheritedResourceData> create() { return adoptRef(*new StyleInheritedResourceData); } + Ref<StyleInheritedResourceData> copy() const; bool operator==(const StyleInheritedResourceData&) const; bool operator!=(const StyleInheritedResourceData& other) const @@ -274,7 +291,29 @@ namespace WebCore { StyleInheritedResourceData(const StyleInheritedResourceData&); }; -} // namespace WebCore + // Positioning and sizing properties. + class StyleLayoutData : public RefCounted<StyleLayoutData> { + public: + static Ref<StyleLayoutData> create() { return adoptRef(*new StyleLayoutData); } + Ref<StyleLayoutData> copy() const; -#endif // ENABLE(SVG) -#endif // SVGRenderStyleDefs_h + bool operator==(const StyleLayoutData&) const; + bool operator!=(const StyleLayoutData& other) const + { + return !(*this == other); + } + + Length cx; + Length cy; + Length r; + Length rx; + Length ry; + Length x; + Length y; + + private: + StyleLayoutData(); + StyleLayoutData(const StyleLayoutData&); + }; + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/ShadowData.cpp b/Source/WebCore/rendering/style/ShadowData.cpp index d91073bd4..4e5cb90f0 100644 --- a/Source/WebCore/rendering/style/ShadowData.cpp +++ b/Source/WebCore/rendering/style/ShadowData.cpp @@ -23,6 +23,7 @@ #include "ShadowData.h" #include "LayoutRect.h" +#include <wtf/PointerComparison.h> namespace WebCore { @@ -33,14 +34,13 @@ ShadowData::ShadowData(const ShadowData& o) , m_color(o.m_color) , m_style(o.m_style) , m_isWebkitBoxShadow(o.m_isWebkitBoxShadow) - , m_next(o.m_next ? adoptPtr(new ShadowData(*o.m_next)) : nullptr) + , m_next(o.m_next ? std::make_unique<ShadowData>(*o.m_next) : nullptr) { } bool ShadowData::operator==(const ShadowData& o) const { - if ((m_next && !o.m_next) || (!m_next && o.m_next) - || (m_next && o.m_next && *m_next != *o.m_next)) + if (!arePointingToEqualData(m_next, o.m_next)) return false; return m_location == o.m_location diff --git a/Source/WebCore/rendering/style/ShadowData.h b/Source/WebCore/rendering/style/ShadowData.h index 19be48d6c..f063043bc 100644 --- a/Source/WebCore/rendering/style/ShadowData.h +++ b/Source/WebCore/rendering/style/ShadowData.h @@ -22,14 +22,11 @@ * */ -#ifndef ShadowData_h -#define ShadowData_h +#pragma once #include "Color.h" #include "FloatRect.h" #include "LayoutRect.h" -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> namespace WebCore { @@ -84,7 +81,7 @@ public: bool isWebkitBoxShadow() const { return m_isWebkitBoxShadow; } const ShadowData* next() const { return m_next.get(); } - void setNext(PassOwnPtr<ShadowData> shadow) { m_next = shadow; } + void setNext(std::unique_ptr<ShadowData> shadow) { m_next = WTFMove(shadow); } void adjustRectForShadow(LayoutRect&, int additionalOutlineSize = 0) const; void adjustRectForShadow(FloatRect&, int additionalOutlineSize = 0) const; @@ -96,9 +93,7 @@ private: Color m_color; ShadowStyle m_style; bool m_isWebkitBoxShadow; - OwnPtr<ShadowData> m_next; + std::unique_ptr<ShadowData> m_next; }; } // namespace WebCore - -#endif // ShadowData_h diff --git a/Source/WebCore/rendering/style/ShapeValue.cpp b/Source/WebCore/rendering/style/ShapeValue.cpp new file mode 100644 index 000000000..ca5f2b293 --- /dev/null +++ b/Source/WebCore/rendering/style/ShapeValue.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014-2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ShapeValue.h" + +#include "CachedImage.h" +#include <wtf/PointerComparison.h> + +namespace WebCore { + +bool ShapeValue::isImageValid() const +{ + if (!m_image) + return false; + if (m_image->isCachedImage()) { + auto* cachedImage = m_image->cachedImage(); + return cachedImage && cachedImage->hasImage(); + } + return m_image->isGeneratedImage(); +} + +bool ShapeValue::operator==(const ShapeValue& other) const +{ + return m_type == other.m_type + && m_cssBox == other.m_cssBox + && arePointingToEqualData(m_shape, other.m_shape) + && arePointingToEqualData(m_image, other.m_image); +} + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/ShapeValue.h b/Source/WebCore/rendering/style/ShapeValue.h index 53c11a7e8..b749a26c0 100644 --- a/Source/WebCore/rendering/style/ShapeValue.h +++ b/Source/WebCore/rendering/style/ShapeValue.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. + * Copyright (C) 2014-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,92 +28,73 @@ * SUCH DAMAGE. */ -#ifndef ShapeValue_h -#define ShapeValue_h +#pragma once #include "BasicShapes.h" -#include "CSSValueKeywords.h" -#include "CachedImage.h" #include "StyleImage.h" -#include <wtf/PassRefPtr.h> namespace WebCore { class ShapeValue : public RefCounted<ShapeValue> { public: - enum ShapeValueType { - // The None value is defined by a null ShapeValue* - Shape, - Box, - Outside, - Image - }; - - static PassRefPtr<ShapeValue> createShapeValue(PassRefPtr<BasicShape> shape, LayoutBox layoutBox) - { - return adoptRef(new ShapeValue(shape, layoutBox)); - } - - static PassRefPtr<ShapeValue> createLayoutBoxValue(LayoutBox layoutBox) + static Ref<ShapeValue> create(Ref<BasicShape>&& shape, CSSBoxType cssBox) { - return adoptRef(new ShapeValue(layoutBox)); + return adoptRef(*new ShapeValue(WTFMove(shape), cssBox)); } - static PassRefPtr<ShapeValue> createOutsideValue() + static Ref<ShapeValue> create(CSSBoxType boxShape) { - return adoptRef(new ShapeValue(Outside)); + return adoptRef(*new ShapeValue(boxShape)); } - static PassRefPtr<ShapeValue> createImageValue(PassRefPtr<StyleImage> image) + static Ref<ShapeValue> create(Ref<StyleImage>&& image) { - return adoptRef(new ShapeValue(image)); + return adoptRef(*new ShapeValue(WTFMove(image))); } - ShapeValueType type() const { return m_type; } + enum class Type { Shape, Box, Image }; + Type type() const { return m_type; } BasicShape* shape() const { return m_shape.get(); } - LayoutBox layoutBox() const { return m_layoutBox; } - + CSSBoxType cssBox() const { return m_cssBox; } StyleImage* image() const { return m_image.get(); } - bool isImageValid() const { return image() && image()->cachedImage() && image()->cachedImage()->hasImage(); } - void setImage(PassRefPtr<StyleImage> image) + bool isImageValid() const; + + void setImage(Ref<StyleImage>&& image) { - ASSERT(type() == Image); - if (m_image != image) - m_image = image; + ASSERT(m_type == Type::Image); + m_image = WTFMove(image); } - bool operator==(const ShapeValue& other) const { return type() == other.type(); } - -private: - ShapeValue(PassRefPtr<BasicShape> shape, LayoutBox layoutBox) - : m_type(Shape) - , m_shape(shape) - , m_layoutBox(layoutBox) + bool operator==(const ShapeValue&) const; + bool operator!=(const ShapeValue& other) const { + return !(*this == other); } - ShapeValue(ShapeValueType type) - : m_type(type) - , m_layoutBox(BoxMissing) + +private: + ShapeValue(Ref<BasicShape>&& shape, CSSBoxType cssBox) + : m_type(Type::Shape) + , m_shape(WTFMove(shape)) + , m_cssBox(cssBox) { } - ShapeValue(PassRefPtr<StyleImage> image) - : m_type(Image) - , m_image(image) - , m_layoutBox(BoxMissing) + + explicit ShapeValue(Ref<StyleImage>&& image) + : m_type(Type::Image) + , m_image(WTFMove(image)) { } - ShapeValue(LayoutBox layoutBox) - : m_type(Box) - , m_layoutBox(layoutBox) + + explicit ShapeValue(CSSBoxType cssBox) + : m_type(Type::Box) + , m_cssBox(cssBox) { } - ShapeValueType m_type; + Type m_type; RefPtr<BasicShape> m_shape; RefPtr<StyleImage> m_image; - LayoutBox m_layoutBox; + CSSBoxType m_cssBox { BoxMissing }; }; } - -#endif diff --git a/Source/WebCore/rendering/style/StyleAllInOne.cpp b/Source/WebCore/rendering/style/StyleAllInOne.cpp new file mode 100644 index 000000000..2850f057f --- /dev/null +++ b/Source/WebCore/rendering/style/StyleAllInOne.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// This all-in-one cpp file cuts down on template bloat to allow us to build our Windows release build. + +#include "BasicShapes.cpp" +#include "ContentData.cpp" +#include "CounterDirectives.cpp" +#include "FillLayer.cpp" +#include "GridPositionsResolver.cpp" +#include "KeyframeList.cpp" +#include "NinePieceImage.cpp" +#include "QuotesData.cpp" +#include "RenderStyle.cpp" +#include "SVGRenderStyle.cpp" +#include "SVGRenderStyleDefs.cpp" +#include "ShadowData.cpp" +#include "ShapeValue.cpp" +#include "StyleBackgroundData.cpp" +#include "StyleBoxData.cpp" +#include "StyleCachedImage.cpp" +#include "StyleDeprecatedFlexibleBoxData.cpp" +#include "StyleFilterData.cpp" +#include "StyleFlexibleBoxData.cpp" +#include "StyleGeneratedImage.cpp" +#include "StyleGridData.cpp" +#include "StyleGridItemData.cpp" +#include "StyleInheritedData.cpp" +#include "StyleMarqueeData.cpp" +#include "StyleMultiColData.cpp" +#include "StyleRareInheritedData.cpp" +#include "StyleRareNonInheritedData.cpp" +#include "StyleScrollSnapPoints.cpp" +#include "StyleSurroundData.cpp" +#include "StyleTransformData.cpp" +#include "StyleVisualData.cpp" +#include "WillChangeData.cpp" diff --git a/Source/WebCore/rendering/style/StyleBackgroundData.cpp b/Source/WebCore/rendering/style/StyleBackgroundData.cpp index c51b8255f..ae3835c79 100644 --- a/Source/WebCore/rendering/style/StyleBackgroundData.cpp +++ b/Source/WebCore/rendering/style/StyleBackgroundData.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004-2017 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -28,36 +28,36 @@ namespace WebCore { StyleBackgroundData::StyleBackgroundData() - : m_background(BackgroundFillLayer) - , m_color(RenderStyle::initialBackgroundColor()) + : background(BackgroundFillLayer) + , color(RenderStyle::initialBackgroundColor()) { } -inline StyleBackgroundData::StyleBackgroundData(const StyleBackgroundData& o) +inline StyleBackgroundData::StyleBackgroundData(const StyleBackgroundData& other) : RefCounted<StyleBackgroundData>() - , m_background(o.m_background) - , m_color(o.m_color) - , m_outline(o.m_outline) + , background(other.background) + , color(other.color) + , outline(other.outline) { } -PassRef<StyleBackgroundData> StyleBackgroundData::copy() const +Ref<StyleBackgroundData> StyleBackgroundData::copy() const { return adoptRef(*new StyleBackgroundData(*this)); } -bool StyleBackgroundData::operator==(const StyleBackgroundData& o) const +bool StyleBackgroundData::operator==(const StyleBackgroundData& other) const { - return m_background == o.m_background && m_color == o.m_color && m_outline == o.m_outline; + return background == other.background && color == other.color && outline == other.outline; } bool StyleBackgroundData::isEquivalentForPainting(const StyleBackgroundData& other) const { - if (m_background != other.m_background || m_color != other.m_color) + if (background != other.background || color != other.color) return false; - if (!m_outline.isVisible() && !other.m_outline.isVisible()) + if (!outline.isVisible() && !other.outline.isVisible()) return true; - return m_outline == other.m_outline; + return outline == other.outline; } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleBackgroundData.h b/Source/WebCore/rendering/style/StyleBackgroundData.h index b2996dcd8..9b95ee0ca 100644 --- a/Source/WebCore/rendering/style/StyleBackgroundData.h +++ b/Source/WebCore/rendering/style/StyleBackgroundData.h @@ -2,7 +2,7 @@ * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * (C) 2000 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) * * This library is free software; you can redistribute it and/or @@ -22,46 +22,33 @@ * */ -#ifndef StyleBackgroundData_h -#define StyleBackgroundData_h +#pragma once #include "Color.h" #include "FillLayer.h" #include "OutlineValue.h" -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> +#include <wtf/Ref.h> namespace WebCore { class StyleBackgroundData : public RefCounted<StyleBackgroundData> { public: - static PassRef<StyleBackgroundData> create() { return adoptRef(*new StyleBackgroundData); } - PassRef<StyleBackgroundData> copy() const; - ~StyleBackgroundData() { } + static Ref<StyleBackgroundData> create() { return adoptRef(*new StyleBackgroundData); } + Ref<StyleBackgroundData> copy() const; - bool operator==(const StyleBackgroundData& o) const; - bool operator!=(const StyleBackgroundData& o) const - { - return !(*this == o); - } + bool operator==(const StyleBackgroundData&) const; + bool operator!=(const StyleBackgroundData& other) const { return !(*this == other); } bool isEquivalentForPainting(const StyleBackgroundData&) const; - const FillLayer& background() const { return m_background; } - const Color& color() const { return m_color; } - const OutlineValue& outline() const { return m_outline; } + FillLayer background; + Color color; + OutlineValue outline; private: - friend class RenderStyle; - StyleBackgroundData(); - StyleBackgroundData(const StyleBackgroundData&); - - FillLayer m_background; - Color m_color; - OutlineValue m_outline; + StyleBackgroundData(const StyleBackgroundData&); }; } // namespace WebCore - -#endif // StyleBackgroundData_h diff --git a/Source/WebCore/rendering/style/StyleBoxData.cpp b/Source/WebCore/rendering/style/StyleBoxData.cpp index a1187ff36..392708aae 100644 --- a/Source/WebCore/rendering/style/StyleBoxData.cpp +++ b/Source/WebCore/rendering/style/StyleBoxData.cpp @@ -67,7 +67,7 @@ inline StyleBoxData::StyleBoxData(const StyleBoxData& o) { } -PassRef<StyleBoxData> StyleBoxData::copy() const +Ref<StyleBoxData> StyleBoxData::copy() const { return adoptRef(*new StyleBoxData(*this)); } diff --git a/Source/WebCore/rendering/style/StyleBoxData.h b/Source/WebCore/rendering/style/StyleBoxData.h index 2c6d03353..55e8fade1 100644 --- a/Source/WebCore/rendering/style/StyleBoxData.h +++ b/Source/WebCore/rendering/style/StyleBoxData.h @@ -22,20 +22,19 @@ * */ -#ifndef StyleBoxData_h -#define StyleBoxData_h +#pragma once #include "Length.h" #include "RenderStyleConstants.h" #include <wtf/RefCounted.h> -#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> namespace WebCore { class StyleBoxData : public RefCounted<StyleBoxData> { public: - static PassRef<StyleBoxData> create() { return adoptRef(*new StyleBoxData); } - PassRef<StyleBoxData> copy() const; + static Ref<StyleBoxData> create() { return adoptRef(*new StyleBoxData); } + Ref<StyleBoxData> copy() const; bool operator==(const StyleBoxData& o) const; bool operator!=(const StyleBoxData& o) const @@ -88,5 +87,3 @@ private: }; } // namespace WebCore - -#endif // StyleBoxData_h diff --git a/Source/WebCore/rendering/style/StyleCachedImage.cpp b/Source/WebCore/rendering/style/StyleCachedImage.cpp index 04d55e942..692395b1e 100644 --- a/Source/WebCore/rendering/style/StyleCachedImage.cpp +++ b/Source/WebCore/rendering/style/StyleCachedImage.cpp @@ -2,7 +2,7 @@ * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * (C) 2000 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2005-2008, 2016 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -24,91 +24,189 @@ #include "config.h" #include "StyleCachedImage.h" +#include "CSSCursorImageValue.h" +#include "CSSImageSetValue.h" +#include "CSSImageValue.h" #include "CachedImage.h" #include "RenderElement.h" namespace WebCore { -StyleCachedImage::StyleCachedImage(CachedImage* image) - : m_image(image) +StyleCachedImage::StyleCachedImage(CSSValue& cssValue) + : m_cssValue(cssValue) { + ASSERT(is<CSSImageValue>(m_cssValue) || is<CSSImageSetValue>(m_cssValue) || is<CSSCursorImageValue>(m_cssValue)); + m_isCachedImage = true; - m_image->addClient(this); + + // CSSImageValue doesn't get invalidated so we can grab the CachedImage immediately if it exists. + if (is<CSSImageValue>(m_cssValue)) { + m_cachedImage = downcast<CSSImageValue>(m_cssValue.get()).cachedImage(); + if (m_cachedImage) + m_isPending = false; + } } StyleCachedImage::~StyleCachedImage() { - m_image->removeClient(this); } -PassRefPtr<CSSValue> StyleCachedImage::cssValue() const +bool StyleCachedImage::operator==(const StyleImage& other) const +{ + if (!is<StyleCachedImage>(other)) + return false; + auto& otherCached = downcast<StyleCachedImage>(other); + if (&otherCached == this) + return true; + if (m_scaleFactor != otherCached.m_scaleFactor) + return false; + if (m_cssValue.ptr() == otherCached.m_cssValue.ptr()) + return true; + if (m_cachedImage && m_cachedImage == otherCached.m_cachedImage) + return true; + return false; +} + +void StyleCachedImage::load(CachedResourceLoader& loader, const ResourceLoaderOptions& options) +{ + ASSERT(m_isPending); + m_isPending = false; + + if (is<CSSImageValue>(m_cssValue)) { + auto& imageValue = downcast<CSSImageValue>(m_cssValue.get()); + m_cachedImage = imageValue.loadImage(loader, options); + return; + } + + if (is<CSSImageSetValue>(m_cssValue)) { + auto& imageSetValue = downcast<CSSImageSetValue>(m_cssValue.get()); + std::tie(m_cachedImage, m_scaleFactor) = imageSetValue.loadBestFitImage(loader, options); + return; + } + + if (is<CSSCursorImageValue>(m_cssValue.get())) { + auto& cursorValue = downcast<CSSCursorImageValue>(m_cssValue.get()); + std::tie(m_cachedImage, m_scaleFactor) = cursorValue.loadImage(loader, options); + return; + } +} + +CachedImage* StyleCachedImage::cachedImage() const +{ + return m_cachedImage.get(); +} + +Ref<CSSValue> StyleCachedImage::cssValue() const +{ + return m_cssValue.copyRef(); +} + +bool StyleCachedImage::canRender(const RenderElement* renderer, float multiplier) const { - return CSSPrimitiveValue::create(m_image->url(), CSSPrimitiveValue::CSS_URI); + if (!m_cachedImage) + return false; + return m_cachedImage->canRender(renderer, multiplier); } -bool StyleCachedImage::canRender(const RenderObject* renderer, float multiplier) const +bool StyleCachedImage::isPending() const { - return m_image->canRender(renderer, multiplier); + return m_isPending; } bool StyleCachedImage::isLoaded() const { - return m_image->isLoaded(); + if (!m_cachedImage) + return false; + return m_cachedImage->isLoaded(); } bool StyleCachedImage::errorOccurred() const { - return m_image->errorOccurred(); + if (!m_cachedImage) + return false; + return m_cachedImage->errorOccurred(); } -LayoutSize StyleCachedImage::imageSize(const RenderElement* renderer, float multiplier) const +FloatSize StyleCachedImage::imageSize(const RenderElement* renderer, float multiplier) const { - return m_image->imageSizeForRenderer(renderer, multiplier); + if (!m_cachedImage) + return { }; + FloatSize size = m_cachedImage->imageSizeForRenderer(renderer, multiplier); + size.scale(1 / m_scaleFactor); + return size; } bool StyleCachedImage::imageHasRelativeWidth() const { - return m_image->imageHasRelativeWidth(); + if (!m_cachedImage) + return false; + return m_cachedImage->imageHasRelativeWidth(); } bool StyleCachedImage::imageHasRelativeHeight() const { - return m_image->imageHasRelativeHeight(); + if (!m_cachedImage) + return false; + return m_cachedImage->imageHasRelativeHeight(); } void StyleCachedImage::computeIntrinsicDimensions(const RenderElement*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) { - m_image->computeIntrinsicDimensions(intrinsicWidth, intrinsicHeight, intrinsicRatio); + if (!m_cachedImage) + return; + m_cachedImage->computeIntrinsicDimensions(intrinsicWidth, intrinsicHeight, intrinsicRatio); } bool StyleCachedImage::usesImageContainerSize() const { - return m_image->usesImageContainerSize(); + if (!m_cachedImage) + return false; + return m_cachedImage->usesImageContainerSize(); } -void StyleCachedImage::setContainerSizeForRenderer(const RenderElement* renderer, const IntSize& imageContainerSize, float imageContainerZoomFactor) +void StyleCachedImage::setContainerSizeForRenderer(const RenderElement* renderer, const FloatSize& imageContainerSize, float imageContainerZoomFactor) { - m_image->setContainerSizeForRenderer(renderer, imageContainerSize, imageContainerZoomFactor); + if (!m_cachedImage) + return; + m_cachedImage->setContainerSizeForRenderer(renderer, LayoutSize(imageContainerSize), imageContainerZoomFactor); } void StyleCachedImage::addClient(RenderElement* renderer) { - m_image->addClient(renderer); + ASSERT(!m_isPending); + if (!m_cachedImage) + return; + ASSERT(renderer); + m_cachedImage->addClient(*renderer); } void StyleCachedImage::removeClient(RenderElement* renderer) { - m_image->removeClient(renderer); + ASSERT(!m_isPending); + if (!m_cachedImage) + return; + ASSERT(renderer); + m_cachedImage->removeClient(*renderer); +} + +RefPtr<Image> StyleCachedImage::image(RenderElement* renderer, const FloatSize&) const +{ + ASSERT(!m_isPending); + if (!m_cachedImage) + return nullptr; + return m_cachedImage->imageForRenderer(renderer); } -PassRefPtr<Image> StyleCachedImage::image(RenderElement* renderer, const IntSize&) const +float StyleCachedImage::imageScaleFactor() const { - return m_image->imageForRenderer(renderer); + return m_scaleFactor; } bool StyleCachedImage::knownToBeOpaque(const RenderElement* renderer) const { - return m_image->currentFrameKnownToBeOpaque(renderer); + if (!m_cachedImage) + return false; + return m_cachedImage->currentFrameKnownToBeOpaque(renderer); } } diff --git a/Source/WebCore/rendering/style/StyleCachedImage.h b/Source/WebCore/rendering/style/StyleCachedImage.h index 0ef45d2d6..b8794a3ad 100644 --- a/Source/WebCore/rendering/style/StyleCachedImage.h +++ b/Source/WebCore/rendering/style/StyleCachedImage.h @@ -21,8 +21,7 @@ * */ -#ifndef StyleCachedImage_h -#define StyleCachedImage_h +#pragma once #include "CachedImageClient.h" #include "CachedResourceHandle.h" @@ -30,39 +29,50 @@ namespace WebCore { +class CSSValue; class CachedImage; +class Document; -class StyleCachedImage final : public StyleImage, private CachedImageClient { +class StyleCachedImage final : public StyleImage { WTF_MAKE_FAST_ALLOCATED; public: - static PassRefPtr<StyleCachedImage> create(CachedImage* image) { return adoptRef(new StyleCachedImage(image)); } + static Ref<StyleCachedImage> create(CSSValue& cssValue) { return adoptRef(*new StyleCachedImage(cssValue)); } virtual ~StyleCachedImage(); - virtual CachedImage* cachedImage() const override { return m_image.get(); } + bool operator==(const StyleImage& other) const override; -private: - virtual WrappedImagePtr data() const override { return m_image.get(); } + CachedImage* cachedImage() const override; + + WrappedImagePtr data() const override { return m_cachedImage.get(); } - virtual PassRefPtr<CSSValue> cssValue() const override; + Ref<CSSValue> cssValue() const override; - virtual bool canRender(const RenderObject*, float multiplier) const override; - virtual bool isLoaded() const override; - virtual bool errorOccurred() const override; - virtual LayoutSize imageSize(const RenderElement*, float multiplier) const override; - virtual bool imageHasRelativeWidth() const override; - virtual bool imageHasRelativeHeight() const override; - virtual void computeIntrinsicDimensions(const RenderElement*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) override; - virtual bool usesImageContainerSize() const override; - virtual void setContainerSizeForRenderer(const RenderElement*, const IntSize&, float) override; - virtual void addClient(RenderElement*) override; - virtual void removeClient(RenderElement*) override; - virtual PassRefPtr<Image> image(RenderElement*, const IntSize&) const override; - virtual bool knownToBeOpaque(const RenderElement*) const override; + bool canRender(const RenderElement*, float multiplier) const override; + bool isPending() const override; + void load(CachedResourceLoader&, const ResourceLoaderOptions&) override; + bool isLoaded() const override; + bool errorOccurred() const override; + FloatSize imageSize(const RenderElement*, float multiplier) const override; + bool imageHasRelativeWidth() const override; + bool imageHasRelativeHeight() const override; + void computeIntrinsicDimensions(const RenderElement*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) override; + bool usesImageContainerSize() const override; + void setContainerSizeForRenderer(const RenderElement*, const FloatSize&, float) override; + void addClient(RenderElement*) override; + void removeClient(RenderElement*) override; + RefPtr<Image> image(RenderElement*, const FloatSize&) const override; + float imageScaleFactor() const override; + bool knownToBeOpaque(const RenderElement*) const override; - explicit StyleCachedImage(CachedImage*); +private: + StyleCachedImage(CSSValue&); - CachedResourceHandle<CachedImage> m_image; + Ref<CSSValue> m_cssValue; + bool m_isPending { true }; + mutable float m_scaleFactor { 1 }; + mutable CachedResourceHandle<CachedImage> m_cachedImage; }; -} -#endif +} // namespace WebCore + +SPECIALIZE_TYPE_TRAITS_STYLE_IMAGE(StyleCachedImage, isCachedImage) diff --git a/Source/WebCore/rendering/style/StyleCachedImageSet.cpp b/Source/WebCore/rendering/style/StyleCachedImageSet.cpp deleted file mode 100644 index f95b2c940..000000000 --- a/Source/WebCore/rendering/style/StyleCachedImageSet.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "StyleCachedImageSet.h" - -#if ENABLE(CSS_IMAGE_SET) - -#include "CSSImageSetValue.h" -#include "CachedImage.h" -#include "RenderElement.h" - -namespace WebCore { - -StyleCachedImageSet::StyleCachedImageSet(CachedImage* image, float imageScaleFactor, CSSImageSetValue* value) - : m_bestFitImage(image) - , m_imageScaleFactor(imageScaleFactor) - , m_imageSetValue(value) -{ - m_isCachedImageSet = true; - m_bestFitImage->addClient(this); -} - - -StyleCachedImageSet::~StyleCachedImageSet() -{ - m_bestFitImage->removeClient(this); -} - -PassRefPtr<CSSValue> StyleCachedImageSet::cssValue() const -{ - return m_imageSetValue; -} - -bool StyleCachedImageSet::canRender(const RenderObject* renderer, float multiplier) const -{ - return m_bestFitImage->canRender(renderer, multiplier); -} - -bool StyleCachedImageSet::isLoaded() const -{ - return m_bestFitImage->isLoaded(); -} - -bool StyleCachedImageSet::errorOccurred() const -{ - return m_bestFitImage->errorOccurred(); -} - -LayoutSize StyleCachedImageSet::imageSize(const RenderElement* renderer, float multiplier) const -{ - LayoutSize scaledImageSize = m_bestFitImage->imageSizeForRenderer(renderer, multiplier); - scaledImageSize.scale(1 / m_imageScaleFactor); - return scaledImageSize; -} - -bool StyleCachedImageSet::imageHasRelativeWidth() const -{ - return m_bestFitImage->imageHasRelativeWidth(); -} - -bool StyleCachedImageSet::imageHasRelativeHeight() const -{ - return m_bestFitImage->imageHasRelativeHeight(); -} - -void StyleCachedImageSet::computeIntrinsicDimensions(const RenderElement*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) -{ - m_bestFitImage->computeIntrinsicDimensions(intrinsicWidth, intrinsicHeight, intrinsicRatio); -} - -bool StyleCachedImageSet::usesImageContainerSize() const -{ - return m_bestFitImage->usesImageContainerSize(); -} - -void StyleCachedImageSet::setContainerSizeForRenderer(const RenderElement* renderer, const IntSize& imageContainerSize, float imageContainerZoomFactor) -{ - m_bestFitImage->setContainerSizeForRenderer(renderer, imageContainerSize, imageContainerZoomFactor); -} - -void StyleCachedImageSet::addClient(RenderElement* renderer) -{ - m_bestFitImage->addClient(renderer); -} - -void StyleCachedImageSet::removeClient(RenderElement* renderer) -{ - m_bestFitImage->removeClient(renderer); -} - -PassRefPtr<Image> StyleCachedImageSet::image(RenderElement* renderer, const IntSize&) const -{ - return m_bestFitImage->imageForRenderer(renderer); -} - -bool StyleCachedImageSet::knownToBeOpaque(const RenderElement* renderer) const -{ - return m_bestFitImage->currentFrameKnownToBeOpaque(renderer); -} - -} // namespace WebCore - -#endif // ENABLE(CSS_IMAGE_SET) diff --git a/Source/WebCore/rendering/style/StyleCachedImageSet.h b/Source/WebCore/rendering/style/StyleCachedImageSet.h deleted file mode 100644 index d0ad5c913..000000000 --- a/Source/WebCore/rendering/style/StyleCachedImageSet.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef StyleCachedImageSet_h -#define StyleCachedImageSet_h - -#if ENABLE(CSS_IMAGE_SET) - -#include "CachedImageClient.h" -#include "CachedResourceHandle.h" -#include "LayoutSize.h" -#include "StyleImage.h" - -namespace WebCore { - -class CachedImage; -class CSSImageSetValue; - -// This class keeps one cached image and has access to a set of alternatives. - -class StyleCachedImageSet final : public StyleImage, private CachedImageClient { - WTF_MAKE_FAST_ALLOCATED; -public: - static PassRefPtr<StyleCachedImageSet> create(CachedImage* image, float imageScaleFactor, CSSImageSetValue* value) - { - return adoptRef(new StyleCachedImageSet(image, imageScaleFactor, value)); - } - virtual ~StyleCachedImageSet(); - - virtual CachedImage* cachedImage() const override { return m_bestFitImage.get(); } - - void clearImageSetValue() { m_imageSetValue = nullptr; } - -private: - virtual PassRefPtr<CSSValue> cssValue() const override; - - // FIXME: This is used by StyleImage for equality comparison, but this implementation - // only looks at the image from the set that we have loaded. I'm not sure if that is - // meaningful enough or not. - virtual WrappedImagePtr data() const override { return m_bestFitImage.get(); } - - virtual bool canRender(const RenderObject*, float multiplier) const override; - virtual bool isLoaded() const override; - virtual bool errorOccurred() const override; - virtual LayoutSize imageSize(const RenderElement*, float multiplier) const override; - virtual bool imageHasRelativeWidth() const override; - virtual bool imageHasRelativeHeight() const override; - virtual void computeIntrinsicDimensions(const RenderElement*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) override; - virtual bool usesImageContainerSize() const override; - virtual void setContainerSizeForRenderer(const RenderElement*, const IntSize&, float) override; - virtual void addClient(RenderElement*) override; - virtual void removeClient(RenderElement*) override; - virtual PassRefPtr<Image> image(RenderElement*, const IntSize&) const override; - virtual float imageScaleFactor() const override { return m_imageScaleFactor; } - virtual bool knownToBeOpaque(const RenderElement*) const override; - - StyleCachedImageSet(CachedImage*, float imageScaleFactor, CSSImageSetValue*); - - CachedResourceHandle<CachedImage> m_bestFitImage; - float m_imageScaleFactor; - CSSImageSetValue* m_imageSetValue; // Not retained; it owns us. -}; - -} // namespace WebCore - -#endif // ENABLE(CSS_IMAGE_SET) - -#endif // StyleCachedImageSet_h diff --git a/Source/WebCore/rendering/style/StyleContentAlignmentData.h b/Source/WebCore/rendering/style/StyleContentAlignmentData.h new file mode 100644 index 000000000..e11c1aee3 --- /dev/null +++ b/Source/WebCore/rendering/style/StyleContentAlignmentData.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2015 Igalia S.L. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "RenderStyleConstants.h" + +namespace WebCore { + +class StyleContentAlignmentData { +public: + // Style data for Content-Distribution properties: align-content, justify-content. + // <content-distribution> || [ <overflow-position>? && <content-position> ] + StyleContentAlignmentData(ContentPosition position, ContentDistributionType distribution, OverflowAlignment overflow = OverflowAlignmentDefault) + : m_position(position) + , m_distribution(distribution) + , m_overflow(overflow) + { + } + + void setPosition(ContentPosition position) { m_position = position; } + void setDistribution(ContentDistributionType distribution) { m_distribution = distribution; } + void setOverflow(OverflowAlignment overflow) { m_overflow = overflow; } + + ContentPosition position() const { return static_cast<ContentPosition>(m_position); } + ContentDistributionType distribution() const { return static_cast<ContentDistributionType>(m_distribution); } + OverflowAlignment overflow() const { return static_cast<OverflowAlignment>(m_overflow); } + + bool operator==(const StyleContentAlignmentData& o) const + { + return m_position == o.m_position && m_distribution == o.m_distribution && m_overflow == o.m_overflow; + } + + bool operator!=(const StyleContentAlignmentData& o) const + { + return !(*this == o); + } + +private: + unsigned m_position : 4; // ContentPosition + unsigned m_distribution : 3; // ContentDistributionType + unsigned m_overflow : 2; // OverflowAlignment +}; + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleCustomPropertyData.h b/Source/WebCore/rendering/style/StyleCustomPropertyData.h new file mode 100644 index 000000000..88f1831c4 --- /dev/null +++ b/Source/WebCore/rendering/style/StyleCustomPropertyData.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#pragma once + +#include "CSSCustomPropertyValue.h" +#include <wtf/Forward.h> +#include <wtf/HashMap.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> +#include <wtf/text/AtomicStringHash.h> + +namespace WebCore { + +class StyleCustomPropertyData : public RefCounted<StyleCustomPropertyData> { +public: + static Ref<StyleCustomPropertyData> create() { return adoptRef(*new StyleCustomPropertyData); } + Ref<StyleCustomPropertyData> copy() const { return adoptRef(*new StyleCustomPropertyData(*this)); } + + bool operator==(const StyleCustomPropertyData& other) const + { + if (containsVariables != other.containsVariables) + return false; + + if (values.size() != other.values.size()) + return false; + + for (auto& entry : values) { + auto otherEntry = other.values.find(entry.key); + if (otherEntry == other.values.end() || !entry.value->equals(*otherEntry->value)) + return false; + } + + return true; + } + + bool operator!=(const StyleCustomPropertyData& other) const { return !(*this == other); } + + void setCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value) + { + if (value->containsVariables()) + containsVariables = true; + values.set(name, WTFMove(value)); + } + + CustomPropertyValueMap values; + bool containsVariables { false }; + +private: + StyleCustomPropertyData() = default; + StyleCustomPropertyData(const StyleCustomPropertyData& other) + : RefCounted<StyleCustomPropertyData>() + , values(other.values) + , containsVariables(other.containsVariables) + { } +}; + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleDashboardRegion.h b/Source/WebCore/rendering/style/StyleDashboardRegion.h index 62992cb8a..a46c7219e 100644 --- a/Source/WebCore/rendering/style/StyleDashboardRegion.h +++ b/Source/WebCore/rendering/style/StyleDashboardRegion.h @@ -22,8 +22,8 @@ * */ -#ifndef StyleDashboardRegion_h -#define StyleDashboardRegion_h +#pragma once + #if ENABLE(DASHBOARD_SUPPORT) #include "LengthBox.h" @@ -58,4 +58,3 @@ struct StyleDashboardRegion { } // namespace WebCore #endif // ENABLE(DASHBOARD_SUPPORT) -#endif // StyleDashboardRegion_h diff --git a/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.cpp b/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.cpp index 3c835923a..1fafa2d88 100644 --- a/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.cpp +++ b/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.cpp @@ -28,8 +28,8 @@ namespace WebCore { StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData() : flex(RenderStyle::initialBoxFlex()) - , flex_group(RenderStyle::initialBoxFlexGroup()) - , ordinal_group(RenderStyle::initialBoxOrdinalGroup()) + , flexGroup(RenderStyle::initialBoxFlexGroup()) + , ordinalGroup(RenderStyle::initialBoxOrdinalGroup()) , align(RenderStyle::initialBoxAlign()) , pack(RenderStyle::initialBoxPack()) , orient(RenderStyle::initialBoxOrient()) @@ -37,28 +37,28 @@ StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData() { } -inline StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData(const StyleDeprecatedFlexibleBoxData& o) +inline StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData(const StyleDeprecatedFlexibleBoxData& other) : RefCounted<StyleDeprecatedFlexibleBoxData>() - , flex(o.flex) - , flex_group(o.flex_group) - , ordinal_group(o.ordinal_group) - , align(o.align) - , pack(o.pack) - , orient(o.orient) - , lines(o.lines) + , flex(other.flex) + , flexGroup(other.flexGroup) + , ordinalGroup(other.ordinalGroup) + , align(other.align) + , pack(other.pack) + , orient(other.orient) + , lines(other.lines) { } -PassRef<StyleDeprecatedFlexibleBoxData> StyleDeprecatedFlexibleBoxData::copy() const +Ref<StyleDeprecatedFlexibleBoxData> StyleDeprecatedFlexibleBoxData::copy() const { return adoptRef(*new StyleDeprecatedFlexibleBoxData(*this)); } -bool StyleDeprecatedFlexibleBoxData::operator==(const StyleDeprecatedFlexibleBoxData& o) const +bool StyleDeprecatedFlexibleBoxData::operator==(const StyleDeprecatedFlexibleBoxData& other) const { - return flex == o.flex && flex_group == o.flex_group && - ordinal_group == o.ordinal_group && align == o.align && - pack == o.pack && orient == o.orient && lines == o.lines; + return flex == other.flex && flexGroup == other.flexGroup + && ordinalGroup == other.ordinalGroup && align == other.align + && pack == other.pack && orient == other.orient && lines == other.lines; } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.h b/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.h index 64c9c7fa0..330cf6473 100644 --- a/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.h +++ b/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.h @@ -22,28 +22,27 @@ * */ -#ifndef StyleDeprecatedFlexibleBoxData_h -#define StyleDeprecatedFlexibleBoxData_h +#pragma once #include <wtf/RefCounted.h> -#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> namespace WebCore { class StyleDeprecatedFlexibleBoxData : public RefCounted<StyleDeprecatedFlexibleBoxData> { public: - static PassRef<StyleDeprecatedFlexibleBoxData> create() { return adoptRef(*new StyleDeprecatedFlexibleBoxData); } - PassRef<StyleDeprecatedFlexibleBoxData> copy() const; + static Ref<StyleDeprecatedFlexibleBoxData> create() { return adoptRef(*new StyleDeprecatedFlexibleBoxData); } + Ref<StyleDeprecatedFlexibleBoxData> copy() const; bool operator==(const StyleDeprecatedFlexibleBoxData&) const; - bool operator!=(const StyleDeprecatedFlexibleBoxData& o) const + bool operator!=(const StyleDeprecatedFlexibleBoxData& other) const { - return !(*this == o); + return !(*this == other); } float flex; - unsigned int flex_group; - unsigned int ordinal_group; + unsigned flexGroup; + unsigned ordinalGroup; unsigned align : 3; // EBoxAlignment unsigned pack: 2; // EBoxPack @@ -56,5 +55,3 @@ private: }; } // namespace WebCore - -#endif // StyleDeprecatedFlexibleBoxData_h diff --git a/Source/WebCore/rendering/style/StyleFilterData.cpp b/Source/WebCore/rendering/style/StyleFilterData.cpp index d1eb94bd4..20dbc08e6 100644 --- a/Source/WebCore/rendering/style/StyleFilterData.cpp +++ b/Source/WebCore/rendering/style/StyleFilterData.cpp @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -26,35 +26,26 @@ #include "config.h" #include "StyleFilterData.h" -#include "FEGaussianBlur.h" - -#if ENABLE(CSS_FILTERS) - -#include "RenderStyle.h" - namespace WebCore { StyleFilterData::StyleFilterData() - : m_operations() { } -inline StyleFilterData::StyleFilterData(const StyleFilterData& o) +inline StyleFilterData::StyleFilterData(const StyleFilterData& other) : RefCounted<StyleFilterData>() - , m_operations(o.m_operations) + , operations(other.operations) { } -PassRef<StyleFilterData> StyleFilterData::copy() const +Ref<StyleFilterData> StyleFilterData::copy() const { return adoptRef(*new StyleFilterData(*this)); } -bool StyleFilterData::operator==(const StyleFilterData& o) const +bool StyleFilterData::operator==(const StyleFilterData& other) const { - return m_operations == o.m_operations; + return operations == other.operations; } } // namespace WebCore - -#endif // ENABLE(CSS_FILTERS) diff --git a/Source/WebCore/rendering/style/StyleFilterData.h b/Source/WebCore/rendering/style/StyleFilterData.h index 25e2f7a3b..a8ba831e2 100644 --- a/Source/WebCore/rendering/style/StyleFilterData.h +++ b/Source/WebCore/rendering/style/StyleFilterData.h @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -23,21 +23,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef StyleFilterData_h -#define StyleFilterData_h - -#if ENABLE(CSS_FILTERS) +#pragma once #include "FilterOperations.h" -#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> #include <wtf/RefCounted.h> namespace WebCore { class StyleFilterData : public RefCounted<StyleFilterData> { public: - static PassRef<StyleFilterData> create() { return adoptRef(*new StyleFilterData); } - PassRef<StyleFilterData> copy() const; + static Ref<StyleFilterData> create() { return adoptRef(*new StyleFilterData); } + Ref<StyleFilterData> copy() const; bool operator==(const StyleFilterData&) const; bool operator!=(const StyleFilterData& o) const @@ -45,7 +42,7 @@ public: return !(*this == o); } - FilterOperations m_operations; + FilterOperations operations; private: StyleFilterData(); @@ -53,7 +50,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(CSS_FILTERS) - -#endif // StyleFilterData_h diff --git a/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp b/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp index 775886b6e..a8218445a 100644 --- a/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp +++ b/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp @@ -31,33 +31,33 @@ namespace WebCore { StyleFlexibleBoxData::StyleFlexibleBoxData() - : m_flexGrow(RenderStyle::initialFlexGrow()) - , m_flexShrink(RenderStyle::initialFlexShrink()) - , m_flexBasis(RenderStyle::initialFlexBasis()) - , m_flexDirection(RenderStyle::initialFlexDirection()) - , m_flexWrap(RenderStyle::initialFlexWrap()) + : flexGrow(RenderStyle::initialFlexGrow()) + , flexShrink(RenderStyle::initialFlexShrink()) + , flexBasis(RenderStyle::initialFlexBasis()) + , flexDirection(RenderStyle::initialFlexDirection()) + , flexWrap(RenderStyle::initialFlexWrap()) { } -inline StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& o) +inline StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& other) : RefCounted<StyleFlexibleBoxData>() - , m_flexGrow(o.m_flexGrow) - , m_flexShrink(o.m_flexShrink) - , m_flexBasis(o.m_flexBasis) - , m_flexDirection(o.m_flexDirection) - , m_flexWrap(o.m_flexWrap) + , flexGrow(other.flexGrow) + , flexShrink(other.flexShrink) + , flexBasis(other.flexBasis) + , flexDirection(other.flexDirection) + , flexWrap(other.flexWrap) { } -PassRef<StyleFlexibleBoxData> StyleFlexibleBoxData::copy() const +Ref<StyleFlexibleBoxData> StyleFlexibleBoxData::copy() const { return adoptRef(*new StyleFlexibleBoxData(*this)); } -bool StyleFlexibleBoxData::operator==(const StyleFlexibleBoxData& o) const +bool StyleFlexibleBoxData::operator==(const StyleFlexibleBoxData& other) const { - return m_flexGrow == o.m_flexGrow && m_flexShrink == o.m_flexShrink && m_flexBasis == o.m_flexBasis - && m_flexDirection == o.m_flexDirection && m_flexWrap == o.m_flexWrap; + return flexGrow == other.flexGrow && flexShrink == other.flexShrink && flexBasis == other.flexBasis + && flexDirection == other.flexDirection && flexWrap == other.flexWrap; } } diff --git a/Source/WebCore/rendering/style/StyleFlexibleBoxData.h b/Source/WebCore/rendering/style/StyleFlexibleBoxData.h index 0e3352c09..f54d85904 100644 --- a/Source/WebCore/rendering/style/StyleFlexibleBoxData.h +++ b/Source/WebCore/rendering/style/StyleFlexibleBoxData.h @@ -23,20 +23,18 @@ * */ -#ifndef StyleFlexibleBoxData_h -#define StyleFlexibleBoxData_h +#pragma once #include "Length.h" - -#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> #include <wtf/RefCounted.h> namespace WebCore { class StyleFlexibleBoxData : public RefCounted<StyleFlexibleBoxData> { public: - static PassRef<StyleFlexibleBoxData> create() { return adoptRef(*new StyleFlexibleBoxData); } - PassRef<StyleFlexibleBoxData> copy() const; + static Ref<StyleFlexibleBoxData> create() { return adoptRef(*new StyleFlexibleBoxData); } + Ref<StyleFlexibleBoxData> copy() const; bool operator==(const StyleFlexibleBoxData&) const; bool operator!=(const StyleFlexibleBoxData& o) const @@ -44,12 +42,12 @@ public: return !(*this == o); } - float m_flexGrow; - float m_flexShrink; - Length m_flexBasis; + float flexGrow; + float flexShrink; + Length flexBasis; - unsigned m_flexDirection : 2; // EFlexDirection - unsigned m_flexWrap : 2; // EFlexWrap + unsigned flexDirection : 2; // EFlexDirection + unsigned flexWrap : 2; // EFlexWrap private: StyleFlexibleBoxData(); @@ -57,5 +55,3 @@ private: }; } // namespace WebCore - -#endif // StyleFlexibleBoxData_h diff --git a/Source/WebCore/rendering/style/StyleGeneratedImage.cpp b/Source/WebCore/rendering/style/StyleGeneratedImage.cpp index 6b59fe7c4..b00637814 100644 --- a/Source/WebCore/rendering/style/StyleGeneratedImage.cpp +++ b/Source/WebCore/rendering/style/StyleGeneratedImage.cpp @@ -30,36 +30,48 @@ namespace WebCore { -StyleGeneratedImage::StyleGeneratedImage(PassRef<CSSImageGeneratorValue> value) - : m_imageGeneratorValue(std::move(value)) +StyleGeneratedImage::StyleGeneratedImage(Ref<CSSImageGeneratorValue>&& value) + : m_imageGeneratorValue(WTFMove(value)) , m_fixedSize(m_imageGeneratorValue->isFixedSize()) { m_isGeneratedImage = true; } -PassRefPtr<CSSValue> StyleGeneratedImage::cssValue() const +Ref<CSSValue> StyleGeneratedImage::cssValue() const { - return &const_cast<CSSImageGeneratorValue&>(m_imageGeneratorValue.get()); + return m_imageGeneratorValue.copyRef(); } -LayoutSize StyleGeneratedImage::imageSize(const RenderElement* renderer, float multiplier) const +bool StyleGeneratedImage::isPending() const { + return m_imageGeneratorValue->isPending(); +} + +void StyleGeneratedImage::load(CachedResourceLoader& loader, const ResourceLoaderOptions& options) +{ + m_imageGeneratorValue->loadSubimages(loader, options); +} + +FloatSize StyleGeneratedImage::imageSize(const RenderElement* renderer, float multiplier) const +{ + ASSERT(renderer); if (m_fixedSize) { - IntSize fixedSize = const_cast<CSSImageGeneratorValue&>(m_imageGeneratorValue.get()).fixedSize(renderer); + FloatSize fixedSize = m_imageGeneratorValue->fixedSize(*renderer); if (multiplier == 1.0f) return fixedSize; - LayoutUnit width = fixedSize.width() * multiplier; - LayoutUnit height = fixedSize.height() * multiplier; + float width = fixedSize.width() * multiplier; + float height = fixedSize.height() * multiplier; - // Don't let images that have a width/height >= 1 shrink below 1 when zoomed. + // Don't let images that have a width/height >= 1 shrink below 1 device pixel when zoomed. + float deviceScaleFactor = renderer ? renderer->document().deviceScaleFactor() : 1; if (fixedSize.width() > 0) - width = std::max<LayoutUnit>(1, width); + width = std::max<float>(1 / deviceScaleFactor, width); if (fixedSize.height() > 0) - height = std::max<LayoutUnit>(1, height); + height = std::max<float>(1 / deviceScaleFactor, height); - return LayoutSize(width, height); + return FloatSize(width, height); } return m_containerSize; @@ -67,8 +79,8 @@ LayoutSize StyleGeneratedImage::imageSize(const RenderElement* renderer, float m void StyleGeneratedImage::computeIntrinsicDimensions(const RenderElement* renderer, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) { - // At a zoom level of 1 the image is guaranteed to have an integer size. - IntSize size = flooredIntSize(imageSize(renderer, 1)); + // At a zoom level of 1 the image is guaranteed to have a device pixel size. + FloatSize size = floorSizeToDevicePixels(LayoutSize(imageSize(renderer, 1)), renderer ? renderer->document().deviceScaleFactor() : 1); intrinsicWidth = Length(size.width(), Fixed); intrinsicHeight = Length(size.height(), Fixed); intrinsicRatio = size; @@ -76,22 +88,26 @@ void StyleGeneratedImage::computeIntrinsicDimensions(const RenderElement* render void StyleGeneratedImage::addClient(RenderElement* renderer) { - m_imageGeneratorValue->addClient(renderer); + ASSERT(renderer); + m_imageGeneratorValue->addClient(*renderer); } void StyleGeneratedImage::removeClient(RenderElement* renderer) { - m_imageGeneratorValue->removeClient(renderer); + ASSERT(renderer); + m_imageGeneratorValue->removeClient(*renderer); } -PassRefPtr<Image> StyleGeneratedImage::image(RenderElement* renderer, const IntSize& size) const +RefPtr<Image> StyleGeneratedImage::image(RenderElement* renderer, const FloatSize& size) const { - return const_cast<CSSImageGeneratorValue&>(m_imageGeneratorValue.get()).image(renderer, size); + ASSERT(renderer); + return m_imageGeneratorValue->image(*renderer, size); } bool StyleGeneratedImage::knownToBeOpaque(const RenderElement* renderer) const { - return m_imageGeneratorValue->knownToBeOpaque(renderer); + ASSERT(renderer); + return m_imageGeneratorValue->knownToBeOpaque(*renderer); } } diff --git a/Source/WebCore/rendering/style/StyleGeneratedImage.h b/Source/WebCore/rendering/style/StyleGeneratedImage.h index 756ca2152..fdaaa68a4 100644 --- a/Source/WebCore/rendering/style/StyleGeneratedImage.h +++ b/Source/WebCore/rendering/style/StyleGeneratedImage.h @@ -21,8 +21,7 @@ * */ -#ifndef StyleGeneratedImage_h -#define StyleGeneratedImage_h +#pragma once #include "StyleImage.h" @@ -33,41 +32,40 @@ class CSSImageGeneratorValue; class StyleGeneratedImage final : public StyleImage { public: - static PassRefPtr<StyleGeneratedImage> create(PassRef<CSSImageGeneratorValue> value) + static Ref<StyleGeneratedImage> create(Ref<CSSImageGeneratorValue>&& value) { - return adoptRef(new StyleGeneratedImage(std::move(value))); + return adoptRef(*new StyleGeneratedImage(WTFMove(value))); } - CSSImageGeneratorValue& imageValue() { return m_imageGeneratorValue.get(); } + CSSImageGeneratorValue& imageValue() { return m_imageGeneratorValue; } private: - virtual WrappedImagePtr data() const override { return &m_imageGeneratorValue.get(); } + bool operator==(const StyleImage& other) const override { return data() == other.data(); } - virtual PassRefPtr<CSSValue> cssValue() const override; + WrappedImagePtr data() const override { return m_imageGeneratorValue.ptr(); } - virtual LayoutSize imageSize(const RenderElement*, float multiplier) const override; - virtual bool imageHasRelativeWidth() const override { return !m_fixedSize; } - virtual bool imageHasRelativeHeight() const override { return !m_fixedSize; } - virtual void computeIntrinsicDimensions(const RenderElement*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) override; - virtual bool usesImageContainerSize() const override { return !m_fixedSize; } - virtual void setContainerSizeForRenderer(const RenderElement*, const IntSize& containerSize, float) override { m_containerSize = containerSize; } - virtual void addClient(RenderElement*) override; - virtual void removeClient(RenderElement*) override; - virtual PassRefPtr<Image> image(RenderElement*, const IntSize&) const override; - virtual bool knownToBeOpaque(const RenderElement*) const override; + Ref<CSSValue> cssValue() const override; - StyleGeneratedImage(PassRef<CSSImageGeneratorValue>); + bool isPending() const override; + void load(CachedResourceLoader&, const ResourceLoaderOptions&) override; + FloatSize imageSize(const RenderElement*, float multiplier) const override; + bool imageHasRelativeWidth() const override { return !m_fixedSize; } + bool imageHasRelativeHeight() const override { return !m_fixedSize; } + void computeIntrinsicDimensions(const RenderElement*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) override; + bool usesImageContainerSize() const override { return !m_fixedSize; } + void setContainerSizeForRenderer(const RenderElement*, const FloatSize& containerSize, float) override { m_containerSize = containerSize; } + void addClient(RenderElement*) override; + void removeClient(RenderElement*) override; + RefPtr<Image> image(RenderElement*, const FloatSize&) const override; + bool knownToBeOpaque(const RenderElement*) const override; + + explicit StyleGeneratedImage(Ref<CSSImageGeneratorValue>&&); Ref<CSSImageGeneratorValue> m_imageGeneratorValue; - IntSize m_containerSize; + FloatSize m_containerSize; bool m_fixedSize; }; -inline StyleGeneratedImage* toStyleGeneratedImage(StyleImage* image) -{ - ASSERT_WITH_SECURITY_IMPLICATION(!image || image->isGeneratedImage()); - return static_cast<StyleGeneratedImage*>(image); -} +} // namespace WebCore -} -#endif +SPECIALIZE_TYPE_TRAITS_STYLE_IMAGE(StyleGeneratedImage, isGeneratedImage) diff --git a/Source/WebCore/rendering/style/StyleGridData.cpp b/Source/WebCore/rendering/style/StyleGridData.cpp index 10eccc0d8..fb75079b7 100644 --- a/Source/WebCore/rendering/style/StyleGridData.cpp +++ b/Source/WebCore/rendering/style/StyleGridData.cpp @@ -31,38 +31,65 @@ namespace WebCore { StyleGridData::StyleGridData() - : m_gridColumns(RenderStyle::initialGridColumns()) - , m_gridRows(RenderStyle::initialGridRows()) - , m_namedGridColumnLines(RenderStyle::initialNamedGridColumnLines()) - , m_namedGridRowLines(RenderStyle::initialNamedGridRowLines()) - , m_gridAutoFlow(RenderStyle::initialGridAutoFlow()) - , m_gridAutoRows(RenderStyle::initialGridAutoRows()) - , m_gridAutoColumns(RenderStyle::initialGridAutoColumns()) - , m_namedGridArea(RenderStyle::initialNamedGridArea()) - , m_namedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount()) - , m_namedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount()) + : gridColumns(RenderStyle::initialGridColumns()) + , gridRows(RenderStyle::initialGridRows()) + , namedGridColumnLines(RenderStyle::initialNamedGridColumnLines()) + , namedGridRowLines(RenderStyle::initialNamedGridRowLines()) + , orderedNamedGridColumnLines(RenderStyle::initialOrderedNamedGridColumnLines()) + , orderedNamedGridRowLines(RenderStyle::initialOrderedNamedGridRowLines()) + , autoRepeatNamedGridColumnLines(RenderStyle::initialNamedGridColumnLines()) + , autoRepeatNamedGridRowLines(RenderStyle::initialNamedGridRowLines()) + , autoRepeatOrderedNamedGridColumnLines(RenderStyle::initialOrderedNamedGridColumnLines()) + , autoRepeatOrderedNamedGridRowLines(RenderStyle::initialOrderedNamedGridRowLines()) + , gridAutoFlow(RenderStyle::initialGridAutoFlow()) + , gridAutoRows(RenderStyle::initialGridAutoRows()) + , gridAutoColumns(RenderStyle::initialGridAutoColumns()) + , namedGridArea(RenderStyle::initialNamedGridArea()) + , namedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount()) + , namedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount()) + , gridColumnGap(RenderStyle::initialGridColumnGap()) + , gridRowGap(RenderStyle::initialGridRowGap()) + , gridAutoRepeatColumns(RenderStyle::initialGridAutoRepeatTracks()) + , gridAutoRepeatRows(RenderStyle::initialGridAutoRepeatTracks()) + , autoRepeatColumnsInsertionPoint(RenderStyle::initialGridAutoRepeatInsertionPoint()) + , autoRepeatRowsInsertionPoint(RenderStyle::initialGridAutoRepeatInsertionPoint()) + , autoRepeatColumnsType(RenderStyle::initialGridAutoRepeatType()) + , autoRepeatRowsType(RenderStyle::initialGridAutoRepeatType()) { } inline StyleGridData::StyleGridData(const StyleGridData& o) : RefCounted<StyleGridData>() - , m_gridColumns(o.m_gridColumns) - , m_gridRows(o.m_gridRows) - , m_namedGridColumnLines(o.m_namedGridColumnLines) - , m_namedGridRowLines(o.m_namedGridRowLines) - , m_gridAutoFlow(o.m_gridAutoFlow) - , m_gridAutoRows(o.m_gridAutoRows) - , m_gridAutoColumns(o.m_gridAutoColumns) - , m_namedGridArea(o.m_namedGridArea) - , m_namedGridAreaRowCount(o.m_namedGridAreaRowCount) - , m_namedGridAreaColumnCount(o.m_namedGridAreaColumnCount) + , gridColumns(o.gridColumns) + , gridRows(o.gridRows) + , namedGridColumnLines(o.namedGridColumnLines) + , namedGridRowLines(o.namedGridRowLines) + , orderedNamedGridColumnLines(o.orderedNamedGridColumnLines) + , orderedNamedGridRowLines(o.orderedNamedGridRowLines) + , autoRepeatNamedGridColumnLines(o.autoRepeatNamedGridColumnLines) + , autoRepeatNamedGridRowLines(o.autoRepeatNamedGridRowLines) + , autoRepeatOrderedNamedGridColumnLines(o.autoRepeatOrderedNamedGridColumnLines) + , autoRepeatOrderedNamedGridRowLines(o.autoRepeatOrderedNamedGridRowLines) + , gridAutoFlow(o.gridAutoFlow) + , gridAutoRows(o.gridAutoRows) + , gridAutoColumns(o.gridAutoColumns) + , namedGridArea(o.namedGridArea) + , namedGridAreaRowCount(o.namedGridAreaRowCount) + , namedGridAreaColumnCount(o.namedGridAreaColumnCount) + , gridColumnGap(o.gridColumnGap) + , gridRowGap(o.gridRowGap) + , gridAutoRepeatColumns(o.gridAutoRepeatColumns) + , gridAutoRepeatRows(o.gridAutoRepeatRows) + , autoRepeatColumnsInsertionPoint(o.autoRepeatColumnsInsertionPoint) + , autoRepeatRowsInsertionPoint(o.autoRepeatRowsInsertionPoint) + , autoRepeatColumnsType(o.autoRepeatColumnsType) + , autoRepeatRowsType(o.autoRepeatRowsType) { } -PassRef<StyleGridData> StyleGridData::copy() const +Ref<StyleGridData> StyleGridData::copy() const { return adoptRef(*new StyleGridData(*this)); } } // namespace WebCore - diff --git a/Source/WebCore/rendering/style/StyleGridData.h b/Source/WebCore/rendering/style/StyleGridData.h index 7fe4c9588..8d2be402f 100644 --- a/Source/WebCore/rendering/style/StyleGridData.h +++ b/Source/WebCore/rendering/style/StyleGridData.h @@ -23,30 +23,41 @@ * */ -#ifndef StyleGridData_h -#define StyleGridData_h +#pragma once -#include "GridCoordinate.h" +#include "GridArea.h" #include "GridTrackSize.h" #include "RenderStyleConstants.h" -#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> #include <wtf/RefCounted.h> #include <wtf/Vector.h> #include <wtf/text/WTFString.h> namespace WebCore { -typedef HashMap<String, Vector<size_t>> NamedGridLinesMap; +typedef HashMap<String, Vector<unsigned>> NamedGridLinesMap; +typedef HashMap<unsigned, Vector<String>, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> OrderedNamedGridLinesMap; class StyleGridData : public RefCounted<StyleGridData> { public: - static PassRef<StyleGridData> create() { return adoptRef(*new StyleGridData); } - PassRef<StyleGridData> copy() const; + static Ref<StyleGridData> create() { return adoptRef(*new StyleGridData); } + Ref<StyleGridData> copy() const; bool operator==(const StyleGridData& o) const { // FIXME: comparing two hashes doesn't look great for performance. Something to keep in mind going forward. - return m_gridColumns == o.m_gridColumns && m_gridRows == o.m_gridRows && m_gridAutoFlow == o.m_gridAutoFlow && m_gridAutoRows == o.m_gridAutoRows && m_gridAutoColumns == o.m_gridAutoColumns && m_namedGridColumnLines == o.m_namedGridColumnLines && m_namedGridRowLines == o.m_namedGridRowLines && m_namedGridArea == o.m_namedGridArea && m_namedGridArea == o.m_namedGridArea && m_namedGridAreaRowCount == o.m_namedGridAreaRowCount && m_namedGridAreaColumnCount == o.m_namedGridAreaColumnCount; + return gridColumns == o.gridColumns && gridRows == o.gridRows + && gridAutoFlow == o.gridAutoFlow && gridAutoRows == o.gridAutoRows && gridAutoColumns == o.gridAutoColumns + && namedGridColumnLines == o.namedGridColumnLines && namedGridRowLines == o.namedGridRowLines + && autoRepeatNamedGridColumnLines == o.autoRepeatNamedGridColumnLines && autoRepeatNamedGridRowLines == o.autoRepeatNamedGridRowLines + && autoRepeatOrderedNamedGridColumnLines == o.autoRepeatOrderedNamedGridColumnLines && autoRepeatOrderedNamedGridRowLines == o.autoRepeatOrderedNamedGridRowLines + && namedGridArea == o.namedGridArea && namedGridArea == o.namedGridArea + && namedGridAreaRowCount == o.namedGridAreaRowCount && namedGridAreaColumnCount == o.namedGridAreaColumnCount + && orderedNamedGridRowLines == o.orderedNamedGridRowLines && orderedNamedGridColumnLines == o.orderedNamedGridColumnLines + && gridColumnGap == o.gridColumnGap && gridRowGap == o.gridRowGap + && gridAutoRepeatColumns == o.gridAutoRepeatColumns && gridAutoRepeatRows == o.gridAutoRepeatRows + && autoRepeatColumnsInsertionPoint == o.autoRepeatColumnsInsertionPoint && autoRepeatRowsInsertionPoint == o.autoRepeatRowsInsertionPoint + && autoRepeatColumnsType == o.autoRepeatColumnsType && autoRepeatRowsType == o.autoRepeatRowsType; } bool operator!=(const StyleGridData& o) const @@ -54,23 +65,42 @@ public: return !(*this == o); } - // FIXME: Update the naming of the following variables. - Vector<GridTrackSize> m_gridColumns; - Vector<GridTrackSize> m_gridRows; + Vector<GridTrackSize> gridColumns; + Vector<GridTrackSize> gridRows; - NamedGridLinesMap m_namedGridColumnLines; - NamedGridLinesMap m_namedGridRowLines; + NamedGridLinesMap namedGridColumnLines; + NamedGridLinesMap namedGridRowLines; - GridAutoFlow m_gridAutoFlow; + OrderedNamedGridLinesMap orderedNamedGridColumnLines; + OrderedNamedGridLinesMap orderedNamedGridRowLines; - GridTrackSize m_gridAutoRows; - GridTrackSize m_gridAutoColumns; + NamedGridLinesMap autoRepeatNamedGridColumnLines; + NamedGridLinesMap autoRepeatNamedGridRowLines; + OrderedNamedGridLinesMap autoRepeatOrderedNamedGridColumnLines; + OrderedNamedGridLinesMap autoRepeatOrderedNamedGridRowLines; - NamedGridAreaMap m_namedGridArea; - // Because m_namedGridArea doesn't store the unnamed grid areas, we need to keep track + unsigned gridAutoFlow : GridAutoFlowBits; + + Vector<GridTrackSize> gridAutoRows; + Vector<GridTrackSize> gridAutoColumns; + + NamedGridAreaMap namedGridArea; + // Because namedGridArea doesn't store the unnamed grid areas, we need to keep track // of the explicit grid size defined by both named and unnamed grid areas. - size_t m_namedGridAreaRowCount; - size_t m_namedGridAreaColumnCount; + unsigned namedGridAreaRowCount; + unsigned namedGridAreaColumnCount; + + Length gridColumnGap; + Length gridRowGap; + + Vector<GridTrackSize> gridAutoRepeatColumns; + Vector<GridTrackSize> gridAutoRepeatRows; + + unsigned autoRepeatColumnsInsertionPoint; + unsigned autoRepeatRowsInsertionPoint; + + AutoRepeatType autoRepeatColumnsType; + AutoRepeatType autoRepeatRowsType; private: StyleGridData(); @@ -78,5 +108,3 @@ private: }; } // namespace WebCore - -#endif // StyleGridData_h diff --git a/Source/WebCore/rendering/style/StyleGridItemData.cpp b/Source/WebCore/rendering/style/StyleGridItemData.cpp index 0c9929a7d..b82e0811d 100644 --- a/Source/WebCore/rendering/style/StyleGridItemData.cpp +++ b/Source/WebCore/rendering/style/StyleGridItemData.cpp @@ -27,6 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include "config.h" #include "StyleGridItemData.h" @@ -35,23 +36,23 @@ namespace WebCore { StyleGridItemData::StyleGridItemData() - : m_gridColumnStart(RenderStyle::initialGridItemColumnStart()) - , m_gridColumnEnd(RenderStyle::initialGridItemColumnEnd()) - , m_gridRowStart(RenderStyle::initialGridItemRowStart()) - , m_gridRowEnd(RenderStyle::initialGridItemRowEnd()) + : gridColumnStart(RenderStyle::initialGridItemColumnStart()) + , gridColumnEnd(RenderStyle::initialGridItemColumnEnd()) + , gridRowStart(RenderStyle::initialGridItemRowStart()) + , gridRowEnd(RenderStyle::initialGridItemRowEnd()) { } inline StyleGridItemData::StyleGridItemData(const StyleGridItemData& o) : RefCounted<StyleGridItemData>() - , m_gridColumnStart(o.m_gridColumnStart) - , m_gridColumnEnd(o.m_gridColumnEnd) - , m_gridRowStart(o.m_gridRowStart) - , m_gridRowEnd(o.m_gridRowEnd) + , gridColumnStart(o.gridColumnStart) + , gridColumnEnd(o.gridColumnEnd) + , gridRowStart(o.gridRowStart) + , gridRowEnd(o.gridRowEnd) { } -PassRef<StyleGridItemData> StyleGridItemData::copy() const +Ref<StyleGridItemData> StyleGridItemData::copy() const { return adoptRef(*new StyleGridItemData(*this)); } diff --git a/Source/WebCore/rendering/style/StyleGridItemData.h b/Source/WebCore/rendering/style/StyleGridItemData.h index c0f9d987a..7ab0d9bd8 100644 --- a/Source/WebCore/rendering/style/StyleGridItemData.h +++ b/Source/WebCore/rendering/style/StyleGridItemData.h @@ -28,26 +28,23 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef StyleGridItemData_h -#define StyleGridItemData_h - +#pragma once #include "GridPosition.h" -#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> #include <wtf/RefCounted.h> -#include <wtf/Vector.h> namespace WebCore { class StyleGridItemData : public RefCounted<StyleGridItemData> { public: - static PassRef<StyleGridItemData> create() { return adoptRef(*new StyleGridItemData); } - PassRef<StyleGridItemData> copy() const; + static Ref<StyleGridItemData> create() { return adoptRef(*new StyleGridItemData); } + Ref<StyleGridItemData> copy() const; bool operator==(const StyleGridItemData& o) const { - return m_gridColumnStart == o.m_gridColumnStart && m_gridColumnEnd == o.m_gridColumnEnd - && m_gridRowStart == o.m_gridRowStart && m_gridRowEnd == o.m_gridRowEnd; + return gridColumnStart == o.gridColumnStart && gridColumnEnd == o.gridColumnEnd + && gridRowStart == o.gridRowStart && gridRowEnd == o.gridRowEnd; } bool operator!=(const StyleGridItemData& o) const @@ -55,10 +52,10 @@ public: return !(*this == o); } - GridPosition m_gridColumnStart; - GridPosition m_gridColumnEnd; - GridPosition m_gridRowStart; - GridPosition m_gridRowEnd; + GridPosition gridColumnStart; + GridPosition gridColumnEnd; + GridPosition gridRowStart; + GridPosition gridRowEnd; private: StyleGridItemData(); @@ -66,5 +63,3 @@ private: }; } // namespace WebCore - -#endif // StyleGridItemData_h diff --git a/Source/WebCore/rendering/style/StyleImage.h b/Source/WebCore/rendering/style/StyleImage.h index a0bd45a6f..bdd81af57 100644 --- a/Source/WebCore/rendering/style/StyleImage.h +++ b/Source/WebCore/rendering/style/StyleImage.h @@ -21,23 +21,23 @@ * */ -#ifndef StyleImage_h -#define StyleImage_h +#pragma once #include "CSSValue.h" +#include "FloatSize.h" #include "Image.h" -#include "IntSize.h" -#include "LayoutSize.h" -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#include <wtf/TypeCasts.h> namespace WebCore { class CachedImage; +class CachedResourceLoader; class CSSValue; class RenderElement; class RenderObject; +struct ResourceLoaderOptions; typedef const void* WrappedImagePtr; @@ -45,53 +45,45 @@ class StyleImage : public RefCounted<StyleImage> { public: virtual ~StyleImage() { } - bool operator==(const StyleImage& other) const - { - return data() == other.data(); - } + virtual bool operator==(const StyleImage& other) const = 0; - virtual PassRefPtr<CSSValue> cssValue() const = 0; + virtual Ref<CSSValue> cssValue() const = 0; - virtual bool canRender(const RenderObject*, float /*multiplier*/) const { return true; } + virtual bool canRender(const RenderElement*, float /*multiplier*/) const { return true; } + virtual bool isPending() const = 0; + virtual void load(CachedResourceLoader&, const ResourceLoaderOptions&) = 0; virtual bool isLoaded() const { return true; } virtual bool errorOccurred() const { return false; } - virtual LayoutSize imageSize(const RenderElement*, float multiplier) const = 0; + virtual FloatSize imageSize(const RenderElement*, float multiplier) const = 0; virtual void computeIntrinsicDimensions(const RenderElement*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) = 0; virtual bool imageHasRelativeWidth() const = 0; virtual bool imageHasRelativeHeight() const = 0; virtual bool usesImageContainerSize() const = 0; - virtual void setContainerSizeForRenderer(const RenderElement*, const IntSize&, float) = 0; + virtual void setContainerSizeForRenderer(const RenderElement*, const FloatSize&, float) = 0; virtual void addClient(RenderElement*) = 0; virtual void removeClient(RenderElement*) = 0; - virtual PassRefPtr<Image> image(RenderElement*, const IntSize&) const = 0; + virtual RefPtr<Image> image(RenderElement*, const FloatSize&) const = 0; virtual WrappedImagePtr data() const = 0; virtual float imageScaleFactor() const { return 1; } virtual bool knownToBeOpaque(const RenderElement*) const = 0; virtual CachedImage* cachedImage() const { return 0; } ALWAYS_INLINE bool isCachedImage() const { return m_isCachedImage; } - ALWAYS_INLINE bool isPendingImage() const { return m_isPendingImage; } ALWAYS_INLINE bool isGeneratedImage() const { return m_isGeneratedImage; } - ALWAYS_INLINE bool isCachedImageSet() const { return m_isCachedImageSet; } - - static bool imagesEquivalent(StyleImage* image1, StyleImage* image2) - { - return image1 == image2 || (image1 && image2 && *image1 == *image2); - } protected: StyleImage() : m_isCachedImage(false) - , m_isPendingImage(false) , m_isGeneratedImage(false) - , m_isCachedImageSet(false) { } bool m_isCachedImage : 1; - bool m_isPendingImage : 1; bool m_isGeneratedImage : 1; - bool m_isCachedImageSet : 1; }; -} -#endif +} // namespace WebCore + +#define SPECIALIZE_TYPE_TRAITS_STYLE_IMAGE(ToClassName, predicate) \ +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToClassName) \ + static bool isType(const WebCore::StyleImage& image) { return image.predicate(); } \ +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/rendering/style/StyleInheritedData.cpp b/Source/WebCore/rendering/style/StyleInheritedData.cpp index 7f2e1c551..a5e357ee9 100644 --- a/Source/WebCore/rendering/style/StyleInheritedData.cpp +++ b/Source/WebCore/rendering/style/StyleInheritedData.cpp @@ -27,10 +27,10 @@ namespace WebCore { StyleInheritedData::StyleInheritedData() - : horizontal_border_spacing(RenderStyle::initialHorizontalBorderSpacing()) - , vertical_border_spacing(RenderStyle::initialVerticalBorderSpacing()) - , line_height(RenderStyle::initialLineHeight()) -#if ENABLE(IOS_TEXT_AUTOSIZING) + : horizontalBorderSpacing(RenderStyle::initialHorizontalBorderSpacing()) + , verticalBorderSpacing(RenderStyle::initialVerticalBorderSpacing()) + , lineHeight(RenderStyle::initialLineHeight()) +#if ENABLE(TEXT_AUTOSIZING) , specifiedLineHeight(RenderStyle::initialLineHeight()) #endif , color(RenderStyle::initialColor()) @@ -38,40 +38,36 @@ StyleInheritedData::StyleInheritedData() { } -StyleInheritedData::~StyleInheritedData() -{ -} - inline StyleInheritedData::StyleInheritedData(const StyleInheritedData& o) : RefCounted<StyleInheritedData>() - , horizontal_border_spacing(o.horizontal_border_spacing) - , vertical_border_spacing(o.vertical_border_spacing) - , line_height(o.line_height) -#if ENABLE(IOS_TEXT_AUTOSIZING) + , horizontalBorderSpacing(o.horizontalBorderSpacing) + , verticalBorderSpacing(o.verticalBorderSpacing) + , lineHeight(o.lineHeight) +#if ENABLE(TEXT_AUTOSIZING) , specifiedLineHeight(o.specifiedLineHeight) #endif - , font(o.font) + , fontCascade(o.fontCascade) , color(o.color) , visitedLinkColor(o.visitedLinkColor) { } -PassRef<StyleInheritedData> StyleInheritedData::copy() const +Ref<StyleInheritedData> StyleInheritedData::copy() const { return adoptRef(*new StyleInheritedData(*this)); } bool StyleInheritedData::operator==(const StyleInheritedData& o) const { - return line_height == o.line_height -#if ENABLE(IOS_TEXT_AUTOSIZING) + return lineHeight == o.lineHeight +#if ENABLE(TEXT_AUTOSIZING) && specifiedLineHeight == o.specifiedLineHeight #endif - && font == o.font + && fontCascade == o.fontCascade && color == o.color && visitedLinkColor == o.visitedLinkColor - && horizontal_border_spacing == o.horizontal_border_spacing - && vertical_border_spacing == o.vertical_border_spacing; + && horizontalBorderSpacing == o.horizontalBorderSpacing + && verticalBorderSpacing == o.verticalBorderSpacing; } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleInheritedData.h b/Source/WebCore/rendering/style/StyleInheritedData.h index a65beff47..d6555835a 100644 --- a/Source/WebCore/rendering/style/StyleInheritedData.h +++ b/Source/WebCore/rendering/style/StyleInheritedData.h @@ -2,7 +2,7 @@ * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * (C) 2000 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) * * This library is free software; you can redistribute it and/or @@ -22,49 +22,38 @@ * */ -#ifndef StyleInheritedData_h -#define StyleInheritedData_h +#pragma once #include "Color.h" -#include "Font.h" +#include "FontCascade.h" #include "Length.h" -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/RefPtr.h> namespace WebCore { class StyleInheritedData : public RefCounted<StyleInheritedData> { public: - static PassRef<StyleInheritedData> create() { return adoptRef(*new StyleInheritedData); } - PassRef<StyleInheritedData> copy() const; - ~StyleInheritedData(); + static Ref<StyleInheritedData> create() { return adoptRef(*new StyleInheritedData); } + Ref<StyleInheritedData> copy() const; - bool operator==(const StyleInheritedData& o) const; - bool operator!=(const StyleInheritedData& o) const - { - return !(*this == o); - } + bool operator==(const StyleInheritedData&) const; + bool operator!=(const StyleInheritedData& other) const { return !(*this == other); } - short horizontal_border_spacing; - short vertical_border_spacing; + float horizontalBorderSpacing; + float verticalBorderSpacing; - // could be packed in a short but doesn't - // make a difference currently because of padding - Length line_height; -#if ENABLE(IOS_TEXT_AUTOSIZING) + Length lineHeight; +#if ENABLE(TEXT_AUTOSIZING) Length specifiedLineHeight; #endif - Font font; + FontCascade fontCascade; Color color; Color visitedLinkColor; private: StyleInheritedData(); StyleInheritedData(const StyleInheritedData&); + void operator=(const StyleInheritedData&) = delete; }; } // namespace WebCore - -#endif // StyleInheritedData_h diff --git a/Source/WebCore/rendering/style/StyleMarqueeData.cpp b/Source/WebCore/rendering/style/StyleMarqueeData.cpp index 5e25e4983..597b3f776 100644 --- a/Source/WebCore/rendering/style/StyleMarqueeData.cpp +++ b/Source/WebCore/rendering/style/StyleMarqueeData.cpp @@ -45,7 +45,7 @@ inline StyleMarqueeData::StyleMarqueeData(const StyleMarqueeData& o) { } -PassRef<StyleMarqueeData> StyleMarqueeData::copy() const +Ref<StyleMarqueeData> StyleMarqueeData::copy() const { return adoptRef(*new StyleMarqueeData(*this)); } diff --git a/Source/WebCore/rendering/style/StyleMarqueeData.h b/Source/WebCore/rendering/style/StyleMarqueeData.h index 69e9dcc3c..d46cf6161 100644 --- a/Source/WebCore/rendering/style/StyleMarqueeData.h +++ b/Source/WebCore/rendering/style/StyleMarqueeData.h @@ -22,20 +22,19 @@ * */ -#ifndef StyleMarqueeData_h -#define StyleMarqueeData_h +#pragma once #include "Length.h" #include "RenderStyleConstants.h" -#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> #include <wtf/RefCounted.h> namespace WebCore { class StyleMarqueeData : public RefCounted<StyleMarqueeData> { public: - static PassRef<StyleMarqueeData> create() { return adoptRef(*new StyleMarqueeData); } - PassRef<StyleMarqueeData> copy() const; + static Ref<StyleMarqueeData> create() { return adoptRef(*new StyleMarqueeData); } + Ref<StyleMarqueeData> copy() const; bool operator==(const StyleMarqueeData& o) const; bool operator!=(const StyleMarqueeData& o) const @@ -57,5 +56,3 @@ private: }; } // namespace WebCore - -#endif // StyleMarqueeData_h diff --git a/Source/WebCore/rendering/style/StyleMultiColData.cpp b/Source/WebCore/rendering/style/StyleMultiColData.cpp index 68b6178ed..b7e794f84 100644 --- a/Source/WebCore/rendering/style/StyleMultiColData.cpp +++ b/Source/WebCore/rendering/style/StyleMultiColData.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004-2013 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -27,55 +27,46 @@ namespace WebCore { StyleMultiColData::StyleMultiColData() - : m_width(0) - , m_count(RenderStyle::initialColumnCount()) - , m_gap(0) - , m_autoWidth(true) - , m_autoCount(true) - , m_normalGap(true) - , m_fill(RenderStyle::initialColumnFill()) - , m_columnSpan(false) - , m_breakBefore(RenderStyle::initialPageBreak()) - , m_breakAfter(RenderStyle::initialPageBreak()) - , m_breakInside(RenderStyle::initialPageBreak()) - , m_axis(RenderStyle::initialColumnAxis()) - , m_progression(RenderStyle::initialColumnProgression()) + : count(RenderStyle::initialColumnCount()) + , autoWidth(true) + , autoCount(true) + , normalGap(true) + , fill(RenderStyle::initialColumnFill()) + , columnSpan(false) + , axis(RenderStyle::initialColumnAxis()) + , progression(RenderStyle::initialColumnProgression()) { } -inline StyleMultiColData::StyleMultiColData(const StyleMultiColData& o) +inline StyleMultiColData::StyleMultiColData(const StyleMultiColData& other) : RefCounted<StyleMultiColData>() - , m_width(o.m_width) - , m_count(o.m_count) - , m_gap(o.m_gap) - , m_rule(o.m_rule) - , m_visitedLinkColumnRuleColor(o.m_visitedLinkColumnRuleColor) - , m_autoWidth(o.m_autoWidth) - , m_autoCount(o.m_autoCount) - , m_normalGap(o.m_normalGap) - , m_fill(o.m_fill) - , m_columnSpan(o.m_columnSpan) - , m_breakBefore(o.m_breakBefore) - , m_breakAfter(o.m_breakAfter) - , m_breakInside(o.m_breakInside) - , m_axis(o.m_axis) - , m_progression(o.m_progression) + , width(other.width) + , count(other.count) + , gap(other.gap) + , rule(other.rule) + , visitedLinkColumnRuleColor(other.visitedLinkColumnRuleColor) + , autoWidth(other.autoWidth) + , autoCount(other.autoCount) + , normalGap(other.normalGap) + , fill(other.fill) + , columnSpan(other.columnSpan) + , axis(other.axis) + , progression(other.progression) { } -PassRef<StyleMultiColData> StyleMultiColData::copy() const +Ref<StyleMultiColData> StyleMultiColData::copy() const { return adoptRef(*new StyleMultiColData(*this)); } -bool StyleMultiColData::operator==(const StyleMultiColData& o) const +bool StyleMultiColData::operator==(const StyleMultiColData& other) const { - return m_width == o.m_width && m_count == o.m_count && m_gap == o.m_gap - && m_rule == o.m_rule && m_visitedLinkColumnRuleColor == o.m_visitedLinkColumnRuleColor && m_breakBefore == o.m_breakBefore - && m_autoWidth == o.m_autoWidth && m_autoCount == o.m_autoCount && m_normalGap == o.m_normalGap - && m_fill == o.m_fill && m_columnSpan == o.m_columnSpan - && m_breakAfter == o.m_breakAfter && m_breakInside == o.m_breakInside - && m_axis == o.m_axis && m_progression == o.m_progression; + return width == other.width && count == other.count && gap == other.gap + && rule == other.rule && visitedLinkColumnRuleColor == other.visitedLinkColumnRuleColor + && autoWidth == other.autoWidth && autoCount == other.autoCount && normalGap == other.normalGap + && fill == other.fill && columnSpan == other.columnSpan + && axis == other.axis && progression == other.progression; } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleMultiColData.h b/Source/WebCore/rendering/style/StyleMultiColData.h index 0e42e6f29..5bdf81d51 100644 --- a/Source/WebCore/rendering/style/StyleMultiColData.h +++ b/Source/WebCore/rendering/style/StyleMultiColData.h @@ -2,7 +2,7 @@ * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * (C) 2000 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) * * This library is free software; you can redistribute it and/or @@ -22,13 +22,11 @@ * */ -#ifndef StyleMultiColData_h -#define StyleMultiColData_h +#pragma once #include "BorderValue.h" #include "Length.h" #include "RenderStyleConstants.h" -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> namespace WebCore { @@ -37,38 +35,32 @@ namespace WebCore { class StyleMultiColData : public RefCounted<StyleMultiColData> { public: - static PassRef<StyleMultiColData> create() { return adoptRef(*new StyleMultiColData); } - PassRef<StyleMultiColData> copy() const; + static Ref<StyleMultiColData> create() { return adoptRef(*new StyleMultiColData); } + Ref<StyleMultiColData> copy() const; - bool operator==(const StyleMultiColData& o) const; - bool operator!=(const StyleMultiColData &o) const - { - return !(*this == o); - } + bool operator==(const StyleMultiColData&) const; + bool operator!=(const StyleMultiColData& other) const { return !(*this == other); } unsigned short ruleWidth() const { - if (m_rule.style() == BNONE || m_rule.style() == BHIDDEN) + if (rule.style() == BNONE || rule.style() == BHIDDEN) return 0; - return m_rule.width(); + return rule.width(); } - float m_width; - unsigned short m_count; - float m_gap; - BorderValue m_rule; - Color m_visitedLinkColumnRuleColor; + float width { 0 }; + unsigned short count; + float gap { 0 }; + BorderValue rule; + Color visitedLinkColumnRuleColor; - bool m_autoWidth : 1; - bool m_autoCount : 1; - bool m_normalGap : 1; - unsigned m_fill : 1; // ColumnFill - unsigned m_columnSpan : 1; - unsigned m_breakBefore : 2; // EPageBreak - unsigned m_breakAfter : 2; // EPageBreak - unsigned m_breakInside : 2; // EPageBreak - unsigned m_axis : 2; // ColumnAxis - unsigned m_progression : 2; // ColumnProgression + bool autoWidth : 1; + bool autoCount : 1; + bool normalGap : 1; + unsigned fill : 1; // ColumnFill + unsigned columnSpan : 1; + unsigned axis : 2; // ColumnAxis + unsigned progression : 2; // ColumnProgression private: StyleMultiColData(); @@ -76,5 +68,3 @@ private: }; } // namespace WebCore - -#endif // StyleMultiColData_h diff --git a/Source/WebCore/rendering/style/StylePendingImage.h b/Source/WebCore/rendering/style/StylePendingImage.h deleted file mode 100644 index 68ca1c222..000000000 --- a/Source/WebCore/rendering/style/StylePendingImage.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef StylePendingImage_h -#define StylePendingImage_h - -#include "CSSCursorImageValue.h" -#include "CSSImageGeneratorValue.h" -#include "CSSImageValue.h" -#include "StyleImage.h" - -#if ENABLE(CSS_IMAGE_SET) -#include "CSSImageSetValue.h" -#endif - -namespace WebCore { - -// StylePendingImage is a placeholder StyleImage that is entered into the RenderStyle during -// style resolution, in order to avoid loading images that are not referenced by the final style. -// They should never exist in a RenderStyle after it has been returned from the style selector. - -class StylePendingImage : public StyleImage { -public: - static PassRefPtr<StylePendingImage> create(CSSValue* value) { return adoptRef(new StylePendingImage(value)); } - - CSSImageValue* cssImageValue() const { return m_value && m_value->isImageValue() ? toCSSImageValue(m_value) : nullptr; } - CSSImageGeneratorValue* cssImageGeneratorValue() const { return m_value && m_value->isImageGeneratorValue() ? static_cast<CSSImageGeneratorValue*>(m_value) : nullptr; } - CSSCursorImageValue* cssCursorImageValue() const { return m_value && m_value->isCursorImageValue() ? toCSSCursorImageValue(m_value) : nullptr; } - -#if ENABLE(CSS_IMAGE_SET) - CSSImageSetValue* cssImageSetValue() const { return m_value && m_value->isImageSetValue() ? toCSSImageSetValue(m_value) : nullptr; } -#endif - - void detachFromCSSValue() { m_value = nullptr; } - -private: - virtual WrappedImagePtr data() const override { return const_cast<StylePendingImage*>(this); } - - virtual PassRefPtr<CSSValue> cssValue() const override { return m_value; } - - virtual LayoutSize imageSize(const RenderElement*, float /*multiplier*/) const override { return LayoutSize(); } - virtual bool imageHasRelativeWidth() const override { return false; } - virtual bool imageHasRelativeHeight() const override { return false; } - virtual void computeIntrinsicDimensions(const RenderElement*, Length& /* intrinsicWidth */ , Length& /* intrinsicHeight */, FloatSize& /* intrinsicRatio */) { } - virtual bool usesImageContainerSize() const override { return false; } - virtual void setContainerSizeForRenderer(const RenderElement*, const IntSize&, float) override { } - virtual void addClient(RenderElement*) override { } - virtual void removeClient(RenderElement*) override { } - - virtual PassRefPtr<Image> image(RenderElement*, const IntSize&) const override - { - ASSERT_NOT_REACHED(); - return nullptr; - } - - virtual bool knownToBeOpaque(const RenderElement*) const override { return false; } - - StylePendingImage(CSSValue* value) - : m_value(value) - { - m_isPendingImage = true; - } - - CSSValue* m_value; // Not retained; it owns us. -}; - -} - -#endif diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp index dcca2021d..7eb5c3c17 100644 --- a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp +++ b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp @@ -23,11 +23,14 @@ #include "StyleRareInheritedData.h" #include "CursorList.h" +#include "DataRef.h" #include "QuotesData.h" #include "RenderStyle.h" #include "RenderStyleConstants.h" #include "ShadowData.h" +#include "StyleCustomPropertyData.h" #include "StyleImage.h" +#include <wtf/PointerComparison.h> namespace WebCore { @@ -41,7 +44,7 @@ struct GreaterThanOrSameSizeAsStyleRareInheritedData : public RefCounted<Greater void* refPtrs[2]; Length lengths[2]; float secondFloat; - unsigned m_bitfields[4]; + unsigned bitfields[4]; short pagedMediaShorts[2]; unsigned unsigneds[1]; short hyphenationShorts[3]; @@ -49,7 +52,7 @@ struct GreaterThanOrSameSizeAsStyleRareInheritedData : public RefCounted<Greater #if PLATFORM(IOS) Color compositionColor; #endif -#if ENABLE(IOS_TEXT_AUTOSIZING) +#if ENABLE(TEXT_AUTOSIZING) TextSizeAdjustment textSizeAdjust; #endif @@ -60,6 +63,8 @@ struct GreaterThanOrSameSizeAsStyleRareInheritedData : public RefCounted<Greater #if ENABLE(TOUCH_EVENTS) Color tapHighlightColor; #endif + + void* customPropertyDataRefs[1]; }; COMPILE_ASSERT(sizeof(StyleRareInheritedData) <= sizeof(GreaterThanOrSameSizeAsStyleRareInheritedData), StyleRareInheritedData_should_bit_pack); @@ -68,67 +73,72 @@ StyleRareInheritedData::StyleRareInheritedData() : listStyleImage(RenderStyle::initialListStyleImage()) , textStrokeWidth(RenderStyle::initialTextStrokeWidth()) , indent(RenderStyle::initialTextIndent()) - , m_effectiveZoom(RenderStyle::initialZoom()) + , effectiveZoom(RenderStyle::initialZoom()) + , customProperties(StyleCustomPropertyData::create()) , widows(RenderStyle::initialWidows()) , orphans(RenderStyle::initialOrphans()) - , m_hasAutoWidows(true) - , m_hasAutoOrphans(true) + , hasAutoWidows(true) + , hasAutoOrphans(true) , textSecurity(RenderStyle::initialTextSecurity()) , userModify(READ_ONLY) , wordBreak(RenderStyle::initialWordBreak()) , overflowWrap(RenderStyle::initialOverflowWrap()) , nbspMode(NBNORMAL) , lineBreak(LineBreakAuto) - , resize(RenderStyle::initialResize()) , userSelect(RenderStyle::initialUserSelect()) - , colorSpace(ColorSpaceDeviceRGB) , speak(SpeakNormal) , hyphens(HyphensManual) , textEmphasisFill(TextEmphasisFillFilled) , textEmphasisMark(TextEmphasisMarkNone) , textEmphasisPosition(TextEmphasisPositionOver | TextEmphasisPositionRight) - , m_textOrientation(TextOrientationVerticalRight) + , textOrientation(static_cast<unsigned>(TextOrientation::Mixed)) #if ENABLE(CSS3_TEXT) - , m_textIndentLine(RenderStyle::initialTextIndentLine()) - , m_textIndentType(RenderStyle::initialTextIndentType()) + , textIndentLine(RenderStyle::initialTextIndentLine()) + , textIndentType(RenderStyle::initialTextIndentType()) #endif - , m_lineBoxContain(RenderStyle::initialLineBoxContain()) + , lineBoxContain(RenderStyle::initialLineBoxContain()) #if ENABLE(CSS_IMAGE_ORIENTATION) - , m_imageOrientation(RenderStyle::initialImageOrientation()) + , imageOrientation(RenderStyle::initialImageOrientation()) #endif - , m_imageRendering(RenderStyle::initialImageRendering()) - , m_lineSnap(RenderStyle::initialLineSnap()) - , m_lineAlign(RenderStyle::initialLineAlign()) + , imageRendering(RenderStyle::initialImageRendering()) + , lineSnap(RenderStyle::initialLineSnap()) + , lineAlign(RenderStyle::initialLineAlign()) #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) , useTouchOverflowScrolling(RenderStyle::initialUseTouchOverflowScrolling()) #endif #if ENABLE(CSS_IMAGE_RESOLUTION) - , m_imageResolutionSource(RenderStyle::initialImageResolutionSource()) - , m_imageResolutionSnap(RenderStyle::initialImageResolutionSnap()) + , imageResolutionSource(RenderStyle::initialImageResolutionSource()) + , imageResolutionSnap(RenderStyle::initialImageResolutionSnap()) #endif #if ENABLE(CSS3_TEXT) - , m_textAlignLast(RenderStyle::initialTextAlignLast()) - , m_textJustify(RenderStyle::initialTextJustify()) -#endif // CSS3_TEXT - , m_textDecorationSkip(RenderStyle::initialTextDecorationSkip()) - , m_textUnderlinePosition(RenderStyle::initialTextUnderlinePosition()) - , m_rubyPosition(RenderStyle::initialRubyPosition()) + , textAlignLast(RenderStyle::initialTextAlignLast()) + , textJustify(RenderStyle::initialTextJustify()) +#endif + , textDecorationSkip(RenderStyle::initialTextDecorationSkip()) + , textUnderlinePosition(RenderStyle::initialTextUnderlinePosition()) + , rubyPosition(RenderStyle::initialRubyPosition()) + , textZoom(RenderStyle::initialTextZoom()) #if PLATFORM(IOS) , touchCalloutEnabled(RenderStyle::initialTouchCalloutEnabled()) #endif +#if ENABLE(CSS_TRAILING_WORD) + , trailingWord(static_cast<unsigned>(RenderStyle::initialTrailingWord())) +#endif + , hangingPunctuation(RenderStyle::initialHangingPunctuation()) + , paintOrder(RenderStyle::initialPaintOrder()) + , capStyle(RenderStyle::initialCapStyle()) + , joinStyle(RenderStyle::initialJoinStyle()) + , strokeWidth(RenderStyle::initialOneLength()) , hyphenationLimitBefore(-1) , hyphenationLimitAfter(-1) , hyphenationLimitLines(-1) - , m_lineGrid(RenderStyle::initialLineGrid()) - , m_tabSize(RenderStyle::initialTabSize()) -#if PLATFORM(IOS) - , compositionFillColor(RenderStyle::initialCompositionFillColor()) -#endif -#if ENABLE(IOS_TEXT_AUTOSIZING) + , lineGrid(RenderStyle::initialLineGrid()) + , tabSize(RenderStyle::initialTabSize()) +#if ENABLE(TEXT_AUTOSIZING) , textSizeAdjust(RenderStyle::initialTextSizeAdjust()) #endif #if ENABLE(CSS_IMAGE_RESOLUTION) - , m_imageResolution(RenderStyle::initialImageResolution()) + , imageResolution(RenderStyle::initialImageResolution()) #endif #if ENABLE(TOUCH_EVENTS) , tapHighlightColor(RenderStyle::initialTapHighlightColor()) @@ -146,74 +156,77 @@ inline StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedDa , visitedLinkTextStrokeColor(o.visitedLinkTextStrokeColor) , visitedLinkTextFillColor(o.visitedLinkTextFillColor) , visitedLinkTextEmphasisColor(o.visitedLinkTextEmphasisColor) - , textShadow(o.textShadow ? adoptPtr(new ShadowData(*o.textShadow)) : nullptr) - , highlight(o.highlight) + , textShadow(o.textShadow ? std::make_unique<ShadowData>(*o.textShadow) : nullptr) , cursorData(o.cursorData) , indent(o.indent) - , m_effectiveZoom(o.m_effectiveZoom) + , effectiveZoom(o.effectiveZoom) + , customProperties(o.customProperties) , widows(o.widows) , orphans(o.orphans) - , m_hasAutoWidows(o.m_hasAutoWidows) - , m_hasAutoOrphans(o.m_hasAutoOrphans) + , hasAutoWidows(o.hasAutoWidows) + , hasAutoOrphans(o.hasAutoOrphans) , textSecurity(o.textSecurity) , userModify(o.userModify) , wordBreak(o.wordBreak) , overflowWrap(o.overflowWrap) , nbspMode(o.nbspMode) , lineBreak(o.lineBreak) - , resize(o.resize) , userSelect(o.userSelect) - , colorSpace(o.colorSpace) , speak(o.speak) , hyphens(o.hyphens) , textEmphasisFill(o.textEmphasisFill) , textEmphasisMark(o.textEmphasisMark) , textEmphasisPosition(o.textEmphasisPosition) - , m_textOrientation(o.m_textOrientation) + , textOrientation(o.textOrientation) #if ENABLE(CSS3_TEXT) - , m_textIndentLine(o.m_textIndentLine) - , m_textIndentType(o.m_textIndentType) + , textIndentLine(o.textIndentLine) + , textIndentType(o.textIndentType) #endif - , m_lineBoxContain(o.m_lineBoxContain) + , lineBoxContain(o.lineBoxContain) #if ENABLE(CSS_IMAGE_ORIENTATION) - , m_imageOrientation(o.m_imageOrientation) + , imageOrientation(o.imageOrientation) #endif - , m_imageRendering(o.m_imageRendering) - , m_lineSnap(o.m_lineSnap) - , m_lineAlign(o.m_lineAlign) + , imageRendering(o.imageRendering) + , lineSnap(o.lineSnap) + , lineAlign(o.lineAlign) #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) , useTouchOverflowScrolling(o.useTouchOverflowScrolling) #endif #if ENABLE(CSS_IMAGE_RESOLUTION) - , m_imageResolutionSource(o.m_imageResolutionSource) - , m_imageResolutionSnap(o.m_imageResolutionSnap) + , imageResolutionSource(o.imageResolutionSource) + , imageResolutionSnap(o.imageResolutionSnap) #endif #if ENABLE(CSS3_TEXT) - , m_textAlignLast(o.m_textAlignLast) - , m_textJustify(o.m_textJustify) -#endif // CSS3_TEXT - , m_textDecorationSkip(o.m_textDecorationSkip) - , m_textUnderlinePosition(o.m_textUnderlinePosition) - , m_rubyPosition(o.m_rubyPosition) + , textAlignLast(o.textAlignLast) + , textJustify(o.textJustify) +#endif + , textDecorationSkip(o.textDecorationSkip) + , textUnderlinePosition(o.textUnderlinePosition) + , rubyPosition(o.rubyPosition) + , textZoom(o.textZoom) #if PLATFORM(IOS) , touchCalloutEnabled(o.touchCalloutEnabled) #endif +#if ENABLE(CSS_TRAILING_WORD) + , trailingWord(o.trailingWord) +#endif + , hangingPunctuation(o.hangingPunctuation) + , paintOrder(o.paintOrder) + , capStyle(o.capStyle) + , joinStyle(o.joinStyle) + , strokeWidth(o.strokeWidth) , hyphenationString(o.hyphenationString) , hyphenationLimitBefore(o.hyphenationLimitBefore) , hyphenationLimitAfter(o.hyphenationLimitAfter) , hyphenationLimitLines(o.hyphenationLimitLines) - , locale(o.locale) , textEmphasisCustomMark(o.textEmphasisCustomMark) - , m_lineGrid(o.m_lineGrid) - , m_tabSize(o.m_tabSize) -#if PLATFORM(IOS) - , compositionFillColor(o.compositionFillColor) -#endif -#if ENABLE(IOS_TEXT_AUTOSIZING) + , lineGrid(o.lineGrid) + , tabSize(o.tabSize) +#if ENABLE(TEXT_AUTOSIZING) , textSizeAdjust(o.textSizeAdjust) #endif #if ENABLE(CSS_IMAGE_RESOLUTION) - , m_imageResolution(o.m_imageResolution) + , imageResolution(o.imageResolution) #endif #if ENABLE(TOUCH_EVENTS) , tapHighlightColor(o.tapHighlightColor) @@ -221,7 +234,7 @@ inline StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedDa { } -PassRef<StyleRareInheritedData> StyleRareInheritedData::copy() const +Ref<StyleRareInheritedData> StyleRareInheritedData::copy() const { return adoptRef(*new StyleRareInheritedData(*this)); } @@ -230,24 +243,6 @@ StyleRareInheritedData::~StyleRareInheritedData() { } -static bool cursorDataEquivalent(const CursorList* c1, const CursorList* c2) -{ - if (c1 == c2) - return true; - if ((!c1 && c2) || (c1 && !c2)) - return false; - return (*c1 == *c2); -} - -static bool quotesDataEquivalent(const QuotesData* q1, const QuotesData* q2) -{ - if (q1 == q2) - return true; - if ((!q1 && q2) || (q1 && !q2)) - return false; - return (*q1 == *q2); -} - bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const { return textStrokeColor == o.textStrokeColor @@ -260,15 +255,14 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const #if ENABLE(TOUCH_EVENTS) && tapHighlightColor == o.tapHighlightColor #endif - && shadowDataEquivalent(o) - && highlight == o.highlight - && cursorDataEquivalent(cursorData.get(), o.cursorData.get()) + && arePointingToEqualData(textShadow, o.textShadow) + && arePointingToEqualData(cursorData, o.cursorData) && indent == o.indent - && m_effectiveZoom == o.m_effectiveZoom + && effectiveZoom == o.effectiveZoom && widows == o.widows && orphans == o.orphans - && m_hasAutoWidows == o.m_hasAutoWidows - && m_hasAutoOrphans == o.m_hasAutoOrphans + && hasAutoWidows == o.hasAutoWidows + && hasAutoOrphans == o.hasAutoOrphans && textSecurity == o.textSecurity && userModify == o.userModify && wordBreak == o.wordBreak @@ -278,12 +272,10 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) && useTouchOverflowScrolling == o.useTouchOverflowScrolling #endif -#if ENABLE(IOS_TEXT_AUTOSIZING) +#if ENABLE(TEXT_AUTOSIZING) && textSizeAdjust == o.textSizeAdjust #endif - && resize == o.resize && userSelect == o.userSelect - && colorSpace == o.colorSpace && speak == o.speak && hyphens == o.hyphens && hyphenationLimitBefore == o.hyphenationLimitBefore @@ -292,50 +284,49 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const && textEmphasisFill == o.textEmphasisFill && textEmphasisMark == o.textEmphasisMark && textEmphasisPosition == o.textEmphasisPosition - && m_textOrientation == o.m_textOrientation + && textOrientation == o.textOrientation #if ENABLE(CSS3_TEXT) - && m_textIndentLine == o.m_textIndentLine - && m_textIndentType == o.m_textIndentType + && textIndentLine == o.textIndentLine + && textIndentType == o.textIndentType #endif - && m_lineBoxContain == o.m_lineBoxContain + && lineBoxContain == o.lineBoxContain #if PLATFORM(IOS) && touchCalloutEnabled == o.touchCalloutEnabled - && compositionFillColor == o.compositionFillColor #endif && hyphenationString == o.hyphenationString - && locale == o.locale && textEmphasisCustomMark == o.textEmphasisCustomMark - && quotesDataEquivalent(quotes.get(), o.quotes.get()) - && m_tabSize == o.m_tabSize - && m_lineGrid == o.m_lineGrid + && arePointingToEqualData(quotes, o.quotes) + && tabSize == o.tabSize + && lineGrid == o.lineGrid #if ENABLE(CSS_IMAGE_ORIENTATION) - && m_imageOrientation == o.m_imageOrientation + && imageOrientation == o.imageOrientation #endif - && m_imageRendering == o.m_imageRendering + && imageRendering == o.imageRendering #if ENABLE(CSS_IMAGE_RESOLUTION) - && m_imageResolutionSource == o.m_imageResolutionSource - && m_imageResolutionSnap == o.m_imageResolutionSnap - && m_imageResolution == o.m_imageResolution + && imageResolutionSource == o.imageResolutionSource + && imageResolutionSnap == o.imageResolutionSnap + && imageResolution == o.imageResolution #endif #if ENABLE(CSS3_TEXT) - && m_textAlignLast == o.m_textAlignLast - && m_textJustify == o.m_textJustify + && textAlignLast == o.textAlignLast + && textJustify == o.textJustify #endif // CSS3_TEXT - && m_textDecorationSkip == o.m_textDecorationSkip - && m_textUnderlinePosition == o.m_textUnderlinePosition - && m_rubyPosition == o.m_rubyPosition - && m_lineSnap == o.m_lineSnap - && m_lineAlign == o.m_lineAlign - && StyleImage::imagesEquivalent(listStyleImage.get(), o.listStyleImage.get()); -} - -bool StyleRareInheritedData::shadowDataEquivalent(const StyleRareInheritedData& o) const -{ - if ((!textShadow && o.textShadow) || (textShadow && !o.textShadow)) - return false; - if (textShadow && o.textShadow && (*textShadow != *o.textShadow)) - return false; - return true; + && textDecorationSkip == o.textDecorationSkip + && textUnderlinePosition == o.textUnderlinePosition + && rubyPosition == o.rubyPosition + && textZoom == o.textZoom + && lineSnap == o.lineSnap + && lineAlign == o.lineAlign +#if ENABLE(CSS_TRAILING_WORD) + && trailingWord == o.trailingWord +#endif + && hangingPunctuation == o.hangingPunctuation + && paintOrder == o.paintOrder + && capStyle == o.capStyle + && joinStyle == o.joinStyle + && strokeWidth == o.strokeWidth + && customProperties == o.customProperties + && arePointingToEqualData(listStyleImage, o.listStyleImage); } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.h b/Source/WebCore/rendering/style/StyleRareInheritedData.h index ec0183544..963c36720 100644 --- a/Source/WebCore/rendering/style/StyleRareInheritedData.h +++ b/Source/WebCore/rendering/style/StyleRareInheritedData.h @@ -22,16 +22,16 @@ * */ -#ifndef StyleRareInheritedData_h -#define StyleRareInheritedData_h +#pragma once #include "Color.h" +#include "DataRef.h" #include "Length.h" +#include "StyleCustomPropertyData.h" #include <wtf/RefCounted.h> -#include <wtf/PassRefPtr.h> #include <wtf/text/AtomicString.h> -#if ENABLE(IOS_TEXT_AUTOSIZING) +#if ENABLE(TEXT_AUTOSIZING) #include "TextSizeAdjustment.h" #endif @@ -47,8 +47,8 @@ class StyleImage; // actually uses one of these properties. class StyleRareInheritedData : public RefCounted<StyleRareInheritedData> { public: - static PassRef<StyleRareInheritedData> create() { return adoptRef(*new StyleRareInheritedData); } - PassRef<StyleRareInheritedData> copy() const; + static Ref<StyleRareInheritedData> create() { return adoptRef(*new StyleRareInheritedData); } + Ref<StyleRareInheritedData> copy() const; ~StyleRareInheritedData(); bool operator==(const StyleRareInheritedData& o) const; @@ -56,7 +56,6 @@ public: { return !(*this == o); } - bool shadowDataEquivalent(const StyleRareInheritedData&) const; RefPtr<StyleImage> listStyleImage; @@ -69,20 +68,21 @@ public: Color visitedLinkTextFillColor; Color visitedLinkTextEmphasisColor; - OwnPtr<ShadowData> textShadow; // Our text shadow information for shadowed text drawing. - AtomicString highlight; // Apple-specific extension for custom highlight rendering. + std::unique_ptr<ShadowData> textShadow; // Our text shadow information for shadowed text drawing. RefPtr<CursorList> cursorData; Length indent; - float m_effectiveZoom; + float effectiveZoom; Length wordSpacing; + DataRef<StyleCustomPropertyData> customProperties; + // Paged media properties. short widows; short orphans; - unsigned m_hasAutoWidows : 1; - unsigned m_hasAutoOrphans : 1; + unsigned hasAutoWidows : 1; + unsigned hasAutoOrphans : 1; unsigned textSecurity : 2; // ETextSecurity unsigned userModify : 2; // EUserModify (editing) @@ -90,7 +90,6 @@ public: unsigned overflowWrap : 1; // EOverflowWrap unsigned nbspMode : 1; // ENBSPMode unsigned lineBreak : 3; // LineBreak - unsigned resize : 2; // EResize unsigned userSelect : 2; // EUserSelect unsigned colorSpace : 1; // ColorSpace unsigned speak : 3; // ESpeak @@ -98,60 +97,67 @@ public: unsigned textEmphasisFill : 1; // TextEmphasisFill unsigned textEmphasisMark : 3; // TextEmphasisMark unsigned textEmphasisPosition : 4; // TextEmphasisPosition - unsigned m_textOrientation : 2; // TextOrientation + unsigned textOrientation : 2; // TextOrientation #if ENABLE(CSS3_TEXT) - unsigned m_textIndentLine : 1; // TextIndentLine - unsigned m_textIndentType : 1; // TextIndentType + unsigned textIndentLine : 1; // TextIndentLine + unsigned textIndentType : 1; // TextIndentType #endif - unsigned m_lineBoxContain: 7; // LineBoxContain + unsigned lineBoxContain: 7; // LineBoxContain // CSS Image Values Level 3 #if ENABLE(CSS_IMAGE_ORIENTATION) - unsigned m_imageOrientation : 4; // ImageOrientationEnum + unsigned imageOrientation : 4; // ImageOrientationEnum #endif - unsigned m_imageRendering : 2; // EImageRendering - unsigned m_lineSnap : 2; // LineSnap - unsigned m_lineAlign : 1; // LineAlign + unsigned imageRendering : 3; // EImageRendering + unsigned lineSnap : 2; // LineSnap + unsigned lineAlign : 1; // LineAlign #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) unsigned useTouchOverflowScrolling: 1; #endif #if ENABLE(CSS_IMAGE_RESOLUTION) - unsigned m_imageResolutionSource : 1; // ImageResolutionSource - unsigned m_imageResolutionSnap : 1; // ImageResolutionSnap + unsigned imageResolutionSource : 1; // ImageResolutionSource + unsigned imageResolutionSnap : 1; // ImageResolutionSnap #endif #if ENABLE(CSS3_TEXT) - unsigned m_textAlignLast : 3; // TextAlignLast - unsigned m_textJustify : 3; // TextJustify -#endif // CSS3_TEXT - unsigned m_textDecorationSkip : 5; // TextDecorationSkip - unsigned m_textUnderlinePosition : 3; // TextUnderlinePosition - unsigned m_rubyPosition : 1; // RubyPosition + unsigned textAlignLast : 3; // TextAlignLast + unsigned textJustify : 2; // TextJustify +#endif + unsigned textDecorationSkip : 5; // TextDecorationSkip + unsigned textUnderlinePosition : 3; // TextUnderlinePosition + unsigned rubyPosition : 2; // RubyPosition + unsigned textZoom: 1; // TextZoom #if PLATFORM(IOS) unsigned touchCalloutEnabled : 1; #endif +#if ENABLE(CSS_TRAILING_WORD) + unsigned trailingWord : 1; +#endif + + unsigned hangingPunctuation : 4; + + unsigned paintOrder : 3; // PaintOrder + unsigned capStyle : 2; // LineCap + unsigned joinStyle : 2; // LineJoin + Length strokeWidth; + AtomicString hyphenationString; short hyphenationLimitBefore; short hyphenationLimitAfter; short hyphenationLimitLines; - AtomicString locale; - AtomicString textEmphasisCustomMark; RefPtr<QuotesData> quotes; - AtomicString m_lineGrid; - unsigned m_tabSize; + AtomicString lineGrid; + unsigned tabSize; -#if PLATFORM(IOS) - Color compositionFillColor; -#endif -#if ENABLE(IOS_TEXT_AUTOSIZING) +#if ENABLE(TEXT_AUTOSIZING) TextSizeAdjustment textSizeAdjust; #endif #if ENABLE(CSS_IMAGE_RESOLUTION) - float m_imageResolution; + float imageResolution; #endif #if ENABLE(TOUCH_EVENTS) @@ -164,5 +170,3 @@ private: }; } // namespace WebCore - -#endif // StyleRareInheritedData_h diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp index d2bd56f70..3b4888857 100644 --- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp +++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004-2017 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -30,154 +30,181 @@ #include "StyleTransformData.h" #include "StyleImage.h" #include "StyleResolver.h" +#include "StyleScrollSnapPoints.h" +#include <wtf/PointerComparison.h> +#include <wtf/RefPtr.h> namespace WebCore { StyleRareNonInheritedData::StyleRareNonInheritedData() : opacity(RenderStyle::initialOpacity()) - , m_aspectRatioDenominator(RenderStyle::initialAspectRatioDenominator()) - , m_aspectRatioNumerator(RenderStyle::initialAspectRatioNumerator()) - , m_perspective(RenderStyle::initialPerspective()) - , m_perspectiveOriginX(RenderStyle::initialPerspectiveOriginX()) - , m_perspectiveOriginY(RenderStyle::initialPerspectiveOriginY()) + , aspectRatioDenominator(RenderStyle::initialAspectRatioDenominator()) + , aspectRatioNumerator(RenderStyle::initialAspectRatioNumerator()) + , perspective(RenderStyle::initialPerspective()) + , perspectiveOriginX(RenderStyle::initialPerspectiveOriginX()) + , perspectiveOriginY(RenderStyle::initialPerspectiveOriginY()) , lineClamp(RenderStyle::initialLineClamp()) - , m_deprecatedFlexibleBox(StyleDeprecatedFlexibleBoxData::create()) - , m_flexibleBox(StyleFlexibleBoxData::create()) - , m_marquee(StyleMarqueeData::create()) - , m_multiCol(StyleMultiColData::create()) - , m_transform(StyleTransformData::create()) -#if ENABLE(CSS_FILTERS) - , m_filter(StyleFilterData::create()) + , initialLetter(RenderStyle::initialInitialLetter()) + , deprecatedFlexibleBox(StyleDeprecatedFlexibleBoxData::create()) + , flexibleBox(StyleFlexibleBoxData::create()) + , marquee(StyleMarqueeData::create()) + , multiCol(StyleMultiColData::create()) + , transform(StyleTransformData::create()) + , filter(StyleFilterData::create()) +#if ENABLE(FILTERS_LEVEL_2) + , backdropFilter(StyleFilterData::create()) #endif - , m_grid(StyleGridData::create()) - , m_gridItem(StyleGridItemData::create()) - , m_mask(FillLayer(MaskFillLayer)) - , m_pageSize() -#if ENABLE(CSS_SHAPES) - , m_shapeInside(RenderStyle::initialShapeInside()) - , m_shapeOutside(RenderStyle::initialShapeOutside()) - , m_shapeMargin(RenderStyle::initialShapeMargin()) - , m_shapePadding(RenderStyle::initialShapePadding()) - , m_shapeImageThreshold(RenderStyle::initialShapeImageThreshold()) + , grid(StyleGridData::create()) + , gridItem(StyleGridItemData::create()) +#if ENABLE(CSS_SCROLL_SNAP) + , scrollSnapPort(StyleScrollSnapPort::create()) + , scrollSnapArea(StyleScrollSnapArea::create()) #endif - , m_clipPath(RenderStyle::initialClipPath()) - , m_visitedLinkBackgroundColor(RenderStyle::initialBackgroundColor()) - , m_order(RenderStyle::initialOrder()) - , m_flowThread(RenderStyle::initialFlowThread()) - , m_regionThread(RenderStyle::initialRegionThread()) - , m_regionFragment(RenderStyle::initialRegionFragment()) - , m_regionBreakAfter(RenderStyle::initialPageBreak()) - , m_regionBreakBefore(RenderStyle::initialPageBreak()) - , m_regionBreakInside(RenderStyle::initialPageBreak()) - , m_pageSizeType(PAGE_SIZE_AUTO) - , m_transformStyle3D(RenderStyle::initialTransformStyle3D()) - , m_backfaceVisibility(RenderStyle::initialBackfaceVisibility()) - , m_alignContent(RenderStyle::initialAlignContent()) - , m_alignItems(RenderStyle::initialAlignItems()) - , m_alignSelf(RenderStyle::initialAlignSelf()) - , m_justifyContent(RenderStyle::initialJustifyContent()) + , willChange(RenderStyle::initialWillChange()) + , mask(FillLayer(MaskFillLayer)) + , objectPosition(RenderStyle::initialObjectPosition()) + , shapeOutside(RenderStyle::initialShapeOutside()) + , shapeMargin(RenderStyle::initialShapeMargin()) + , shapeImageThreshold(RenderStyle::initialShapeImageThreshold()) + , clipPath(RenderStyle::initialClipPath()) + , visitedLinkBackgroundColor(RenderStyle::initialBackgroundColor()) + , order(RenderStyle::initialOrder()) + , flowThread(RenderStyle::initialFlowThread()) + , regionThread(RenderStyle::initialRegionThread()) + , alignContent(RenderStyle::initialContentAlignment()) + , alignItems(RenderStyle::initialDefaultAlignment()) + , alignSelf(RenderStyle::initialSelfAlignment()) + , justifyContent(RenderStyle::initialContentAlignment()) + , justifyItems(RenderStyle::initialSelfAlignment()) + , justifySelf(RenderStyle::initialSelfAlignment()) +#if ENABLE(TOUCH_EVENTS) + , touchAction(static_cast<unsigned>(RenderStyle::initialTouchAction())) +#endif + , regionFragment(RenderStyle::initialRegionFragment()) + , pageSizeType(PAGE_SIZE_AUTO) + , transformStyle3D(RenderStyle::initialTransformStyle3D()) + , backfaceVisibility(RenderStyle::initialBackfaceVisibility()) , userDrag(RenderStyle::initialUserDrag()) , textOverflow(RenderStyle::initialTextOverflow()) , marginBeforeCollapse(MCOLLAPSE) , marginAfterCollapse(MCOLLAPSE) - , m_appearance(RenderStyle::initialAppearance()) - , m_borderFit(RenderStyle::initialBorderFit()) - , m_textCombine(RenderStyle::initialTextCombine()) - , m_textDecorationStyle(RenderStyle::initialTextDecorationStyle()) - , m_wrapFlow(RenderStyle::initialWrapFlow()) - , m_wrapThrough(RenderStyle::initialWrapThrough()) -#if USE(ACCELERATED_COMPOSITING) - , m_runningAcceleratedAnimation(false) -#endif - , m_hasAspectRatio(false) + , appearance(RenderStyle::initialAppearance()) + , borderFit(RenderStyle::initialBorderFit()) + , textCombine(RenderStyle::initialTextCombine()) + , textDecorationStyle(RenderStyle::initialTextDecorationStyle()) + , aspectRatioType(RenderStyle::initialAspectRatioType()) #if ENABLE(CSS_COMPOSITING) - , m_effectiveBlendMode(RenderStyle::initialBlendMode()) + , effectiveBlendMode(RenderStyle::initialBlendMode()) + , isolation(RenderStyle::initialIsolation()) #endif - , m_objectFit(RenderStyle::initialObjectFit()) +#if ENABLE(APPLE_PAY) + , applePayButtonStyle(static_cast<unsigned>(RenderStyle::initialApplePayButtonStyle())) + , applePayButtonType(static_cast<unsigned>(RenderStyle::initialApplePayButtonType())) +#endif + , objectFit(RenderStyle::initialObjectFit()) + , breakBefore(RenderStyle::initialBreakBetween()) + , breakAfter(RenderStyle::initialBreakBetween()) + , breakInside(RenderStyle::initialBreakInside()) + , resize(RenderStyle::initialResize()) + , hasAttrContent(false) + , isPlaceholderStyle(false) { - m_maskBoxImage.setMaskDefaults(); + maskBoxImage.setMaskDefaults(); } inline StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInheritedData& o) : RefCounted<StyleRareNonInheritedData>() , opacity(o.opacity) - , m_aspectRatioDenominator(o.m_aspectRatioDenominator) - , m_aspectRatioNumerator(o.m_aspectRatioNumerator) - , m_perspective(o.m_perspective) - , m_perspectiveOriginX(o.m_perspectiveOriginX) - , m_perspectiveOriginY(o.m_perspectiveOriginY) + , aspectRatioDenominator(o.aspectRatioDenominator) + , aspectRatioNumerator(o.aspectRatioNumerator) + , perspective(o.perspective) + , perspectiveOriginX(o.perspectiveOriginX) + , perspectiveOriginY(o.perspectiveOriginY) , lineClamp(o.lineClamp) - , m_deprecatedFlexibleBox(o.m_deprecatedFlexibleBox) - , m_flexibleBox(o.m_flexibleBox) - , m_marquee(o.m_marquee) - , m_multiCol(o.m_multiCol) - , m_transform(o.m_transform) -#if ENABLE(CSS_FILTERS) - , m_filter(o.m_filter) + , initialLetter(o.initialLetter) + , deprecatedFlexibleBox(o.deprecatedFlexibleBox) + , flexibleBox(o.flexibleBox) + , marquee(o.marquee) + , multiCol(o.multiCol) + , transform(o.transform) + , filter(o.filter) +#if ENABLE(FILTERS_LEVEL_2) + , backdropFilter(o.backdropFilter) +#endif + , grid(o.grid) + , gridItem(o.gridItem) +#if ENABLE(CSS_SCROLL_SNAP) + , scrollSnapPort(o.scrollSnapPort) + , scrollSnapArea(o.scrollSnapArea) #endif - , m_grid(o.m_grid) - , m_gridItem(o.m_gridItem) - , m_content(o.m_content ? o.m_content->clone() : nullptr) - , m_counterDirectives(o.m_counterDirectives ? clone(*o.m_counterDirectives) : nullptr) - , m_boxShadow(o.m_boxShadow ? adoptPtr(new ShadowData(*o.m_boxShadow)) : nullptr) - , m_boxReflect(o.m_boxReflect) - , m_animations(o.m_animations ? adoptPtr(new AnimationList(*o.m_animations)) : nullptr) - , m_transitions(o.m_transitions ? adoptPtr(new AnimationList(*o.m_transitions)) : nullptr) - , m_mask(o.m_mask) - , m_maskBoxImage(o.m_maskBoxImage) - , m_pageSize(o.m_pageSize) -#if ENABLE(CSS_SHAPES) - , m_shapeInside(o.m_shapeInside) - , m_shapeOutside(o.m_shapeOutside) - , m_shapeMargin(o.m_shapeMargin) - , m_shapePadding(o.m_shapePadding) - , m_shapeImageThreshold(o.m_shapeImageThreshold) + , content(o.content ? o.content->clone() : nullptr) + , counterDirectives(o.counterDirectives ? clone(*o.counterDirectives) : nullptr) + , altText(o.altText) + , boxShadow(o.boxShadow ? std::make_unique<ShadowData>(*o.boxShadow) : nullptr) + , willChange(o.willChange) + , boxReflect(o.boxReflect) + , animations(o.animations ? std::make_unique<AnimationList>(*o.animations) : nullptr) + , transitions(o.transitions ? std::make_unique<AnimationList>(*o.transitions) : nullptr) + , mask(o.mask) + , maskBoxImage(o.maskBoxImage) + , pageSize(o.pageSize) + , objectPosition(o.objectPosition) + , shapeOutside(o.shapeOutside) + , shapeMargin(o.shapeMargin) + , shapeImageThreshold(o.shapeImageThreshold) + , clipPath(o.clipPath) + , textDecorationColor(o.textDecorationColor) + , visitedLinkTextDecorationColor(o.visitedLinkTextDecorationColor) + , visitedLinkBackgroundColor(o.visitedLinkBackgroundColor) + , visitedLinkOutlineColor(o.visitedLinkOutlineColor) + , visitedLinkBorderLeftColor(o.visitedLinkBorderLeftColor) + , visitedLinkBorderRightColor(o.visitedLinkBorderRightColor) + , visitedLinkBorderTopColor(o.visitedLinkBorderTopColor) + , visitedLinkBorderBottomColor(o.visitedLinkBorderBottomColor) + , order(o.order) + , flowThread(o.flowThread) + , regionThread(o.regionThread) + , alignContent(o.alignContent) + , alignItems(o.alignItems) + , alignSelf(o.alignSelf) + , justifyContent(o.justifyContent) + , justifyItems(o.justifyItems) + , justifySelf(o.justifySelf) +#if ENABLE(TOUCH_EVENTS) + , touchAction(o.touchAction) #endif - , m_clipPath(o.m_clipPath) - , m_textDecorationColor(o.m_textDecorationColor) - , m_visitedLinkTextDecorationColor(o.m_visitedLinkTextDecorationColor) - , m_visitedLinkBackgroundColor(o.m_visitedLinkBackgroundColor) - , m_visitedLinkOutlineColor(o.m_visitedLinkOutlineColor) - , m_visitedLinkBorderLeftColor(o.m_visitedLinkBorderLeftColor) - , m_visitedLinkBorderRightColor(o.m_visitedLinkBorderRightColor) - , m_visitedLinkBorderTopColor(o.m_visitedLinkBorderTopColor) - , m_visitedLinkBorderBottomColor(o.m_visitedLinkBorderBottomColor) - , m_order(o.m_order) - , m_flowThread(o.m_flowThread) - , m_regionThread(o.m_regionThread) - , m_regionFragment(o.m_regionFragment) - , m_regionBreakAfter(o.m_regionBreakAfter) - , m_regionBreakBefore(o.m_regionBreakBefore) - , m_regionBreakInside(o.m_regionBreakInside) - , m_pageSizeType(o.m_pageSizeType) - , m_transformStyle3D(o.m_transformStyle3D) - , m_backfaceVisibility(o.m_backfaceVisibility) - , m_alignContent(o.m_alignContent) - , m_alignItems(o.m_alignItems) - , m_alignSelf(o.m_alignSelf) - , m_justifyContent(o.m_justifyContent) + , regionFragment(o.regionFragment) + , pageSizeType(o.pageSizeType) + , transformStyle3D(o.transformStyle3D) + , backfaceVisibility(o.backfaceVisibility) , userDrag(o.userDrag) , textOverflow(o.textOverflow) , marginBeforeCollapse(o.marginBeforeCollapse) , marginAfterCollapse(o.marginAfterCollapse) - , m_appearance(o.m_appearance) - , m_borderFit(o.m_borderFit) - , m_textCombine(o.m_textCombine) - , m_textDecorationStyle(o.m_textDecorationStyle) - , m_wrapFlow(o.m_wrapFlow) - , m_wrapThrough(o.m_wrapThrough) -#if USE(ACCELERATED_COMPOSITING) - , m_runningAcceleratedAnimation(o.m_runningAcceleratedAnimation) -#endif - , m_hasAspectRatio(o.m_hasAspectRatio) + , appearance(o.appearance) + , borderFit(o.borderFit) + , textCombine(o.textCombine) + , textDecorationStyle(o.textDecorationStyle) + , aspectRatioType(o.aspectRatioType) #if ENABLE(CSS_COMPOSITING) - , m_effectiveBlendMode(o.m_effectiveBlendMode) + , effectiveBlendMode(o.effectiveBlendMode) + , isolation(o.isolation) +#endif +#if ENABLE(APPLE_PAY) + , applePayButtonStyle(o.applePayButtonStyle) + , applePayButtonType(o.applePayButtonType) #endif - , m_objectFit(o.m_objectFit) + , objectFit(o.objectFit) + , breakBefore(o.breakBefore) + , breakAfter(o.breakAfter) + , breakInside(o.breakInside) + , resize(o.resize) + , hasAttrContent(o.hasAttrContent) + , isPlaceholderStyle(o.isPlaceholderStyle) { } -PassRef<StyleRareNonInheritedData> StyleRareNonInheritedData::copy() const +Ref<StyleRareNonInheritedData> StyleRareNonInheritedData::copy() const { return adoptRef(*new StyleRareNonInheritedData(*this)); } @@ -189,152 +216,120 @@ StyleRareNonInheritedData::~StyleRareNonInheritedData() bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) const { return opacity == o.opacity - && m_aspectRatioDenominator == o.m_aspectRatioDenominator - && m_aspectRatioNumerator == o.m_aspectRatioNumerator - && m_perspective == o.m_perspective - && m_perspectiveOriginX == o.m_perspectiveOriginX - && m_perspectiveOriginY == o.m_perspectiveOriginY + && aspectRatioDenominator == o.aspectRatioDenominator + && aspectRatioNumerator == o.aspectRatioNumerator + && perspective == o.perspective + && perspectiveOriginX == o.perspectiveOriginX + && perspectiveOriginY == o.perspectiveOriginY && lineClamp == o.lineClamp + && initialLetter == o.initialLetter #if ENABLE(DASHBOARD_SUPPORT) - && m_dashboardRegions == o.m_dashboardRegions + && dashboardRegions == o.dashboardRegions #endif - && m_deprecatedFlexibleBox == o.m_deprecatedFlexibleBox - && m_flexibleBox == o.m_flexibleBox - && m_marquee == o.m_marquee - && m_multiCol == o.m_multiCol - && m_transform == o.m_transform -#if ENABLE(CSS_FILTERS) - && m_filter == o.m_filter + && deprecatedFlexibleBox == o.deprecatedFlexibleBox + && flexibleBox == o.flexibleBox + && marquee == o.marquee + && multiCol == o.multiCol + && transform == o.transform + && filter == o.filter +#if ENABLE(FILTERS_LEVEL_2) + && backdropFilter == o.backdropFilter #endif - && m_grid == o.m_grid - && m_gridItem == o.m_gridItem - && contentDataEquivalent(o) - && counterDataEquivalent(o) - && shadowDataEquivalent(o) - && reflectionDataEquivalent(o) - && animationDataEquivalent(o) - && transitionDataEquivalent(o) - && m_mask == o.m_mask - && m_maskBoxImage == o.m_maskBoxImage - && m_pageSize == o.m_pageSize -#if ENABLE(CSS_SHAPES) - && m_shapeInside == o.m_shapeInside - && m_shapeOutside == o.m_shapeOutside - && m_shapeMargin == o.m_shapeMargin - && m_shapePadding == o.m_shapePadding - && m_shapeImageThreshold == o.m_shapeImageThreshold + && grid == o.grid + && gridItem == o.gridItem +#if ENABLE(CSS_SCROLL_SNAP) + && scrollSnapPort == o.scrollSnapPort + && scrollSnapArea == o.scrollSnapArea #endif - && m_clipPath == o.m_clipPath - && m_textDecorationColor == o.m_textDecorationColor - && m_visitedLinkTextDecorationColor == o.m_visitedLinkTextDecorationColor - && m_visitedLinkBackgroundColor == o.m_visitedLinkBackgroundColor - && m_visitedLinkOutlineColor == o.m_visitedLinkOutlineColor - && m_visitedLinkBorderLeftColor == o.m_visitedLinkBorderLeftColor - && m_visitedLinkBorderRightColor == o.m_visitedLinkBorderRightColor - && m_visitedLinkBorderTopColor == o.m_visitedLinkBorderTopColor - && m_visitedLinkBorderBottomColor == o.m_visitedLinkBorderBottomColor - && m_order == o.m_order - && m_flowThread == o.m_flowThread - && m_regionThread == o.m_regionThread - && m_regionFragment == o.m_regionFragment - && m_regionBreakAfter == o.m_regionBreakAfter - && m_regionBreakBefore == o.m_regionBreakBefore - && m_regionBreakInside == o.m_regionBreakInside - && m_pageSizeType == o.m_pageSizeType - && m_transformStyle3D == o.m_transformStyle3D - && m_backfaceVisibility == o.m_backfaceVisibility - && m_alignContent == o.m_alignContent - && m_alignItems == o.m_alignItems - && m_alignSelf == o.m_alignSelf - && m_justifyContent == o.m_justifyContent + && contentDataEquivalent(o) + && arePointingToEqualData(counterDirectives, o.counterDirectives) + && altText == o.altText + && arePointingToEqualData(boxShadow, o.boxShadow) + && arePointingToEqualData(willChange, o.willChange) + && arePointingToEqualData(boxReflect, o.boxReflect) + && arePointingToEqualData(animations, o.animations) + && arePointingToEqualData(transitions, o.transitions) + && mask == o.mask + && maskBoxImage == o.maskBoxImage + && pageSize == o.pageSize + && objectPosition == o.objectPosition + && arePointingToEqualData(shapeOutside, o.shapeOutside) + && shapeMargin == o.shapeMargin + && shapeImageThreshold == o.shapeImageThreshold + && arePointingToEqualData(clipPath, o.clipPath) + && textDecorationColor == o.textDecorationColor + && visitedLinkTextDecorationColor == o.visitedLinkTextDecorationColor + && visitedLinkBackgroundColor == o.visitedLinkBackgroundColor + && visitedLinkOutlineColor == o.visitedLinkOutlineColor + && visitedLinkBorderLeftColor == o.visitedLinkBorderLeftColor + && visitedLinkBorderRightColor == o.visitedLinkBorderRightColor + && visitedLinkBorderTopColor == o.visitedLinkBorderTopColor + && visitedLinkBorderBottomColor == o.visitedLinkBorderBottomColor + && order == o.order + && flowThread == o.flowThread + && alignContent == o.alignContent + && alignItems == o.alignItems + && alignSelf == o.alignSelf + && justifyContent == o.justifyContent + && justifyItems == o.justifyItems + && justifySelf == o.justifySelf + && regionThread == o.regionThread + && regionFragment == o.regionFragment + && pageSizeType == o.pageSizeType + && transformStyle3D == o.transformStyle3D + && backfaceVisibility == o.backfaceVisibility && userDrag == o.userDrag && textOverflow == o.textOverflow && marginBeforeCollapse == o.marginBeforeCollapse && marginAfterCollapse == o.marginAfterCollapse - && m_appearance == o.m_appearance - && m_borderFit == o.m_borderFit - && m_textCombine == o.m_textCombine - && m_textDecorationStyle == o.m_textDecorationStyle - && m_wrapFlow == o.m_wrapFlow - && m_wrapThrough == o.m_wrapThrough -#if USE(ACCELERATED_COMPOSITING) - && !m_runningAcceleratedAnimation && !o.m_runningAcceleratedAnimation + && appearance == o.appearance + && borderFit == o.borderFit + && textCombine == o.textCombine + && textDecorationStyle == o.textDecorationStyle +#if ENABLE(TOUCH_EVENTS) + && touchAction == o.touchAction #endif #if ENABLE(CSS_COMPOSITING) - && m_effectiveBlendMode == o.m_effectiveBlendMode + && effectiveBlendMode == o.effectiveBlendMode + && isolation == o.isolation +#endif +#if ENABLE(APPLE_PAY) + && applePayButtonStyle == o.applePayButtonStyle + && applePayButtonType == o.applePayButtonType #endif - && m_hasAspectRatio == o.m_hasAspectRatio - && m_objectFit == o.m_objectFit; + && aspectRatioType == o.aspectRatioType + && objectFit == o.objectFit + && breakAfter == o.breakAfter + && breakBefore == o.breakBefore + && breakInside == o.breakInside + && resize == o.resize + && hasAttrContent == o.hasAttrContent + && isPlaceholderStyle == o.isPlaceholderStyle; } -bool StyleRareNonInheritedData::contentDataEquivalent(const StyleRareNonInheritedData& o) const +bool StyleRareNonInheritedData::contentDataEquivalent(const StyleRareNonInheritedData& other) const { - ContentData* a = m_content.get(); - ContentData* b = o.m_content.get(); - + auto* a = content.get(); + auto* b = other.content.get(); while (a && b && *a == *b) { a = a->next(); b = b->next(); } - return !a && !b; } -bool StyleRareNonInheritedData::counterDataEquivalent(const StyleRareNonInheritedData& o) const -{ - if (m_counterDirectives.get() == o.m_counterDirectives.get()) - return true; - - if (m_counterDirectives && o.m_counterDirectives && *m_counterDirectives == *o.m_counterDirectives) - return true; - - return false; -} - -bool StyleRareNonInheritedData::shadowDataEquivalent(const StyleRareNonInheritedData& o) const -{ - if ((!m_boxShadow && o.m_boxShadow) || (m_boxShadow && !o.m_boxShadow)) - return false; - if (m_boxShadow && o.m_boxShadow && (*m_boxShadow != *o.m_boxShadow)) - return false; - return true; -} - -bool StyleRareNonInheritedData::reflectionDataEquivalent(const StyleRareNonInheritedData& o) const +bool StyleRareNonInheritedData::hasFilters() const { - if (m_boxReflect != o.m_boxReflect) { - if (!m_boxReflect || !o.m_boxReflect) - return false; - return *m_boxReflect == *o.m_boxReflect; - } - return true; + return !filter->operations.isEmpty(); } -bool StyleRareNonInheritedData::animationDataEquivalent(const StyleRareNonInheritedData& o) const -{ - if ((!m_animations && o.m_animations) || (m_animations && !o.m_animations)) - return false; - if (m_animations && o.m_animations && (*m_animations != *o.m_animations)) - return false; - return true; -} +#if ENABLE(FILTERS_LEVEL_2) -bool StyleRareNonInheritedData::transitionDataEquivalent(const StyleRareNonInheritedData& o) const +bool StyleRareNonInheritedData::hasBackdropFilters() const { - if ((!m_transitions && o.m_transitions) || (m_transitions && !o.m_transitions)) - return false; - if (m_transitions && o.m_transitions && (*m_transitions != *o.m_transitions)) - return false; - return true; + return !backdropFilter->operations.isEmpty(); } -bool StyleRareNonInheritedData::hasFilters() const -{ -#if ENABLE(CSS_FILTERS) - return m_filter.get() && !m_filter->m_operations.isEmpty(); -#else - return false; #endif -} } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h index 4523f3be4..b58abae3e 100644 --- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h +++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h @@ -2,7 +2,7 @@ * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * (C) 2000 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) * * This library is free software; you can redistribute it and/or @@ -22,30 +22,32 @@ * */ -#ifndef StyleRareNonInheritedData_h -#define StyleRareNonInheritedData_h +#pragma once #include "BasicShapes.h" +#include "CSSPropertyNames.h" #include "ClipPathOperation.h" #include "CounterDirectives.h" #include "CursorData.h" #include "DataRef.h" #include "FillLayer.h" +#include "LengthPoint.h" #include "LineClampValue.h" #include "NinePieceImage.h" #include "ShapeValue.h" -#include <wtf/OwnPtr.h> -#include <wtf/PassRefPtr.h> +#include "StyleContentAlignmentData.h" +#include "StyleSelfAlignmentData.h" +#include "WillChangeData.h" +#include <memory> #include <wtf/Vector.h> namespace WebCore { class AnimationList; +class ContentData; class ShadowData; class StyleDeprecatedFlexibleBoxData; -#if ENABLE(CSS_FILTERS) class StyleFilterData; -#endif class StyleFlexibleBoxData; class StyleGridData; class StyleGridItemData; @@ -53,18 +55,16 @@ class StyleMarqueeData; class StyleMultiColData; class StyleReflection; class StyleResolver; +class StyleScrollSnapArea; +class StyleScrollSnapPort; class StyleTransformData; -class ContentData; struct LengthSize; - -#if ENABLE(DASHBOARD_SUPPORT) struct StyleDashboardRegion; -#endif // Page size type. -// StyleRareNonInheritedData::m_pageSize is meaningful only when -// StyleRareNonInheritedData::m_pageSizeType is PAGE_SIZE_RESOLVED. +// StyleRareNonInheritedData::pageSize is meaningful only when +// StyleRareNonInheritedData::pageSizeType is PAGE_SIZE_RESOLVED. enum PageSizeType { PAGE_SIZE_AUTO, // size: auto PAGE_SIZE_AUTO_LANDSCAPE, // size: landscape @@ -77,126 +77,150 @@ enum PageSizeType { // actually uses one of these properties. class StyleRareNonInheritedData : public RefCounted<StyleRareNonInheritedData> { public: - static PassRef<StyleRareNonInheritedData> create() { return adoptRef(*new StyleRareNonInheritedData); } - PassRef<StyleRareNonInheritedData> copy() const; + static Ref<StyleRareNonInheritedData> create() { return adoptRef(*new StyleRareNonInheritedData); } + Ref<StyleRareNonInheritedData> copy() const; ~StyleRareNonInheritedData(); bool operator==(const StyleRareNonInheritedData&) const; - bool operator!=(const StyleRareNonInheritedData& o) const { return !(*this == o); } + bool operator!=(const StyleRareNonInheritedData& other) const { return !(*this == other); } bool contentDataEquivalent(const StyleRareNonInheritedData&) const; - bool counterDataEquivalent(const StyleRareNonInheritedData&) const; - bool shadowDataEquivalent(const StyleRareNonInheritedData&) const; - bool reflectionDataEquivalent(const StyleRareNonInheritedData&) const; - bool animationDataEquivalent(const StyleRareNonInheritedData&) const; - bool transitionDataEquivalent(const StyleRareNonInheritedData&) const; + bool hasFilters() const; + +#if ENABLE(FILTERS_LEVEL_2) + bool hasBackdropFilters() const; +#endif + bool hasOpacity() const { return opacity < 1; } + bool hasAnimationsOrTransitions() const { return animations || transitions; } + float opacity; - float m_aspectRatioDenominator; - float m_aspectRatioNumerator; + float aspectRatioDenominator; + float aspectRatioNumerator; - float m_perspective; - Length m_perspectiveOriginX; - Length m_perspectiveOriginY; + float perspective; + Length perspectiveOriginX; + Length perspectiveOriginY; LineClampValue lineClamp; // An Apple extension. + + IntSize initialLetter; + #if ENABLE(DASHBOARD_SUPPORT) - Vector<StyleDashboardRegion> m_dashboardRegions; + Vector<StyleDashboardRegion> dashboardRegions; +#endif + + DataRef<StyleDeprecatedFlexibleBoxData> deprecatedFlexibleBox; // Flexible box properties + DataRef<StyleFlexibleBoxData> flexibleBox; + DataRef<StyleMarqueeData> marquee; // Marquee properties + DataRef<StyleMultiColData> multiCol; // CSS3 multicol properties + DataRef<StyleTransformData> transform; // Transform properties (rotate, scale, skew, etc.) + DataRef<StyleFilterData> filter; // Filter operations (url, sepia, blur, etc.) + +#if ENABLE(FILTERS_LEVEL_2) + DataRef<StyleFilterData> backdropFilter; // Filter operations (url, sepia, blur, etc.) #endif - DataRef<StyleDeprecatedFlexibleBoxData> m_deprecatedFlexibleBox; // Flexible box properties - DataRef<StyleFlexibleBoxData> m_flexibleBox; - DataRef<StyleMarqueeData> m_marquee; // Marquee properties - DataRef<StyleMultiColData> m_multiCol; // CSS3 multicol properties - DataRef<StyleTransformData> m_transform; // Transform properties (rotate, scale, skew, etc.) + DataRef<StyleGridData> grid; + DataRef<StyleGridItemData> gridItem; -#if ENABLE(CSS_FILTERS) - DataRef<StyleFilterData> m_filter; // Filter operations (url, sepia, blur, etc.) +#if ENABLE(CSS_SCROLL_SNAP) + DataRef<StyleScrollSnapPort> scrollSnapPort; + DataRef<StyleScrollSnapArea> scrollSnapArea; #endif - DataRef<StyleGridData> m_grid; - DataRef<StyleGridItemData> m_gridItem; + std::unique_ptr<ContentData> content; + std::unique_ptr<CounterDirectiveMap> counterDirectives; + String altText; - std::unique_ptr<ContentData> m_content; - OwnPtr<CounterDirectiveMap> m_counterDirectives; - String m_altText; + std::unique_ptr<ShadowData> boxShadow; // For box-shadow decorations. - OwnPtr<ShadowData> m_boxShadow; // For box-shadow decorations. + RefPtr<WillChangeData> willChange; // Null indicates 'auto'. - RefPtr<StyleReflection> m_boxReflect; + RefPtr<StyleReflection> boxReflect; - OwnPtr<AnimationList> m_animations; - OwnPtr<AnimationList> m_transitions; + std::unique_ptr<AnimationList> animations; + std::unique_ptr<AnimationList> transitions; - FillLayer m_mask; - NinePieceImage m_maskBoxImage; + FillLayer mask; + NinePieceImage maskBoxImage; - LengthSize m_pageSize; + LengthSize pageSize; + LengthPoint objectPosition; -#if ENABLE(CSS_SHAPES) - RefPtr<ShapeValue> m_shapeInside; - RefPtr<ShapeValue> m_shapeOutside; - Length m_shapeMargin; - Length m_shapePadding; - float m_shapeImageThreshold; -#endif + RefPtr<ShapeValue> shapeOutside; + Length shapeMargin; + float shapeImageThreshold; - RefPtr<ClipPathOperation> m_clipPath; + RefPtr<ClipPathOperation> clipPath; - Color m_textDecorationColor; - Color m_visitedLinkTextDecorationColor; - Color m_visitedLinkBackgroundColor; - Color m_visitedLinkOutlineColor; - Color m_visitedLinkBorderLeftColor; - Color m_visitedLinkBorderRightColor; - Color m_visitedLinkBorderTopColor; - Color m_visitedLinkBorderBottomColor; + Color textDecorationColor; + Color visitedLinkTextDecorationColor; + Color visitedLinkBackgroundColor; + Color visitedLinkOutlineColor; + Color visitedLinkBorderLeftColor; + Color visitedLinkBorderRightColor; + Color visitedLinkBorderTopColor; + Color visitedLinkBorderBottomColor; - int m_order; + int order; - AtomicString m_flowThread; - AtomicString m_regionThread; - unsigned m_regionFragment : 1; // RegionFragment + AtomicString flowThread; + AtomicString regionThread; - unsigned m_regionBreakAfter : 2; // EPageBreak - unsigned m_regionBreakBefore : 2; // EPageBreak - unsigned m_regionBreakInside : 2; // EPageBreak + StyleContentAlignmentData alignContent; + StyleSelfAlignmentData alignItems; + StyleSelfAlignmentData alignSelf; + StyleContentAlignmentData justifyContent; + StyleSelfAlignmentData justifyItems; + StyleSelfAlignmentData justifySelf; - unsigned m_pageSizeType : 2; // PageSizeType - unsigned m_transformStyle3D : 1; // ETransformStyle3D - unsigned m_backfaceVisibility : 1; // EBackfaceVisibility +#if ENABLE(TOUCH_EVENTS) + unsigned touchAction : 1; // TouchAction +#endif + + unsigned regionFragment : 1; // RegionFragment + + unsigned pageSizeType : 2; // PageSizeType + unsigned transformStyle3D : 1; // ETransformStyle3D + unsigned backfaceVisibility : 1; // EBackfaceVisibility - unsigned m_alignContent : 3; // EAlignContent - unsigned m_alignItems : 3; // EAlignItems - unsigned m_alignSelf : 3; // EAlignItems - unsigned m_justifyContent : 3; // EJustifyContent unsigned userDrag : 2; // EUserDrag unsigned textOverflow : 1; // Whether or not lines that spill out should be truncated with "..." unsigned marginBeforeCollapse : 2; // EMarginCollapse unsigned marginAfterCollapse : 2; // EMarginCollapse - unsigned m_appearance : 6; // EAppearance - unsigned m_borderFit : 1; // EBorderFit - unsigned m_textCombine : 1; // CSS3 text-combine properties - - unsigned m_textDecorationStyle : 3; // TextDecorationStyle - unsigned m_wrapFlow: 3; // WrapFlow - unsigned m_wrapThrough: 1; // WrapThrough + unsigned appearance : 6; // EAppearance + unsigned borderFit : 1; // EBorderFit + unsigned textCombine : 1; // CSS3 text-combine properties -#if USE(ACCELERATED_COMPOSITING) - unsigned m_runningAcceleratedAnimation : 1; -#endif + unsigned textDecorationStyle : 3; // TextDecorationStyle - unsigned m_hasAspectRatio : 1; // Whether or not an aspect ratio has been specified. + unsigned aspectRatioType : 2; #if ENABLE(CSS_COMPOSITING) - unsigned m_effectiveBlendMode: 5; // EBlendMode + unsigned effectiveBlendMode: 5; // EBlendMode + unsigned isolation : 1; // Isolation +#endif + +#if ENABLE(APPLE_PAY) + unsigned applePayButtonStyle : 2; + unsigned applePayButtonType : 3; #endif - unsigned m_objectFit : 3; // ObjectFit + unsigned objectFit : 3; // ObjectFit + + unsigned breakBefore : 4; // BreakBetween + unsigned breakAfter : 4; + unsigned breakInside : 3; // BreakInside + unsigned resize : 2; // EResize + + unsigned hasAttrContent : 1; + + unsigned isPlaceholderStyle : 1; private: StyleRareNonInheritedData(); @@ -204,5 +228,3 @@ private: }; } // namespace WebCore - -#endif // StyleRareNonInheritedData_h diff --git a/Source/WebCore/rendering/style/StyleReflection.h b/Source/WebCore/rendering/style/StyleReflection.h index 45b93e204..c82f84e61 100644 --- a/Source/WebCore/rendering/style/StyleReflection.h +++ b/Source/WebCore/rendering/style/StyleReflection.h @@ -22,8 +22,7 @@ * */ -#ifndef StyleReflection_h -#define StyleReflection_h +#pragma once #include "CSSReflectionDirection.h" #include "Length.h" @@ -34,9 +33,9 @@ namespace WebCore { class StyleReflection : public RefCounted<StyleReflection> { public: - static PassRefPtr<StyleReflection> create() + static Ref<StyleReflection> create() { - return adoptRef(new StyleReflection); + return adoptRef(*new StyleReflection); } bool operator==(const StyleReflection& o) const @@ -50,7 +49,7 @@ public: const NinePieceImage& mask() const { return m_mask; } void setDirection(CSSReflectionDirection dir) { m_direction = dir; } - void setOffset(Length offset) { m_offset = std::move(offset); } + void setOffset(Length offset) { m_offset = WTFMove(offset); } void setMask(const NinePieceImage& image) { m_mask = image; } private: @@ -67,5 +66,3 @@ private: }; } // namespace WebCore - -#endif // StyleReflection_h diff --git a/Source/WebCore/rendering/style/StyleScrollSnapPoints.cpp b/Source/WebCore/rendering/style/StyleScrollSnapPoints.cpp new file mode 100644 index 000000000..bc01ef740 --- /dev/null +++ b/Source/WebCore/rendering/style/StyleScrollSnapPoints.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014-2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "StyleScrollSnapPoints.h" + +#if ENABLE(CSS_SCROLL_SNAP) + +namespace WebCore { + +Ref<StyleScrollSnapPort> StyleScrollSnapPort::copy() const +{ + return adoptRef(*new StyleScrollSnapPort(*this)); +} + +StyleScrollSnapPort::StyleScrollSnapPort() +{ +} + +inline StyleScrollSnapPort::StyleScrollSnapPort(const StyleScrollSnapPort& other) + : RefCounted() + , type(other.type) + , scrollPadding(other.scrollPadding) +{ +} + +Ref<StyleScrollSnapArea> StyleScrollSnapArea::copy() const +{ + return adoptRef(*new StyleScrollSnapArea(*this)); +} + +StyleScrollSnapArea::StyleScrollSnapArea() + : scrollSnapMargin(0, 0, 0, 0) +{ +} + +inline StyleScrollSnapArea::StyleScrollSnapArea(const StyleScrollSnapArea& other) + : RefCounted() + , alignment(other.alignment) + , scrollSnapMargin(other.scrollSnapMargin) +{ +} + +} // namespace WebCore + +#endif /* ENABLE(CSS_SCROLL_SNAP) */ diff --git a/Source/WebCore/rendering/style/StyleScrollSnapPoints.h b/Source/WebCore/rendering/style/StyleScrollSnapPoints.h new file mode 100644 index 000000000..c5f0aeb78 --- /dev/null +++ b/Source/WebCore/rendering/style/StyleScrollSnapPoints.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2014-2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if ENABLE(CSS_SCROLL_SNAP) + +#include "LengthBox.h" +#include "LengthSize.h" +#include "RenderStyleConstants.h" +#include <wtf/RefCounted.h> +#include <wtf/Vector.h> + +namespace WebCore { + +struct ScrollSnapType { + ScrollSnapAxis axis { ScrollSnapAxis::Both }; + ScrollSnapStrictness strictness { ScrollSnapStrictness::None }; +}; + +inline bool operator==(const ScrollSnapType& a, const ScrollSnapType& b) +{ + return a.axis == b.axis && a.strictness == b.strictness; +} + +inline bool operator!=(const ScrollSnapType& a, const ScrollSnapType& b) { return !(a == b); } + +class StyleScrollSnapPort : public RefCounted<StyleScrollSnapPort> { +public: + static Ref<StyleScrollSnapPort> create() { return adoptRef(*new StyleScrollSnapPort); } + Ref<StyleScrollSnapPort> copy() const; + + ScrollSnapType type; + LengthBox scrollPadding { 0, 0, 0, 0 }; + +private: + StyleScrollSnapPort(); + StyleScrollSnapPort(const StyleScrollSnapPort&); +}; + +inline bool operator==(const StyleScrollSnapPort& a, const StyleScrollSnapPort& b) +{ + return a.type == b.type && a.scrollPadding == b.scrollPadding; +} + +inline bool operator!=(const StyleScrollSnapPort& a, const StyleScrollSnapPort& b) { return !(a == b); } + +struct ScrollSnapAlign { + ScrollSnapAxisAlignType x { ScrollSnapAxisAlignType::None }; + ScrollSnapAxisAlignType y { ScrollSnapAxisAlignType::None }; +}; + +inline bool operator==(const ScrollSnapAlign& a, const ScrollSnapAlign& b) +{ + return a.x == b.x && a.y == b.y; +} + +inline bool operator!=(const ScrollSnapAlign& a, const ScrollSnapAlign& b) { return !(a == b); } + +class StyleScrollSnapArea : public RefCounted<StyleScrollSnapArea> { +public: + static Ref<StyleScrollSnapArea> create() { return adoptRef(*new StyleScrollSnapArea); } + Ref<StyleScrollSnapArea> copy() const; + bool hasSnapPosition() const { return alignment.x != ScrollSnapAxisAlignType::None || alignment.y != ScrollSnapAxisAlignType::None; } + + ScrollSnapAlign alignment; + LengthBox scrollSnapMargin { 0, 0, 0, 0 }; + +private: + StyleScrollSnapArea(); + StyleScrollSnapArea(const StyleScrollSnapArea&); +}; + +inline bool operator==(const StyleScrollSnapArea& a, const StyleScrollSnapArea& b) +{ + return a.alignment == b.alignment && a.scrollSnapMargin == b.scrollSnapMargin; +} + +inline bool operator!=(const StyleScrollSnapArea& a, const StyleScrollSnapArea& b) { return !(a == b); } + +} // namespace WebCore + +#endif // ENABLE(CSS_SCROLL_SNAP) diff --git a/Source/WebCore/rendering/style/StyleSelfAlignmentData.h b/Source/WebCore/rendering/style/StyleSelfAlignmentData.h new file mode 100644 index 000000000..4aec7ff18 --- /dev/null +++ b/Source/WebCore/rendering/style/StyleSelfAlignmentData.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2015 Igalia S.L. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "RenderStyleConstants.h" + +namespace WebCore { + +class StyleSelfAlignmentData { +public: + // Style data for Self-Aligment and Default-Alignment properties: align-{self, items}, justify-{self, items}. + // [ <self-position> && <overflow-position>? ] | [ legacy && [ left | right | center ] ] + StyleSelfAlignmentData(ItemPosition position, OverflowAlignment overflow, ItemPositionType positionType = NonLegacyPosition) + : m_position(position) + , m_positionType(positionType) + , m_overflow(overflow) + { + } + + void setPosition(ItemPosition position) { m_position = position; } + void setPositionType(ItemPositionType positionType) { m_positionType = positionType; } + void setOverflow(OverflowAlignment overflow) { m_overflow = overflow; } + + ItemPosition position() const { return static_cast<ItemPosition>(m_position); } + ItemPositionType positionType() const { return static_cast<ItemPositionType>(m_positionType); } + OverflowAlignment overflow() const { return static_cast<OverflowAlignment>(m_overflow); } + + bool operator==(const StyleSelfAlignmentData& o) const + { + return m_position == o.m_position && m_positionType == o.m_positionType && m_overflow == o.m_overflow; + } + + bool operator!=(const StyleSelfAlignmentData& o) const + { + return !(*this == o); + } + +private: + unsigned m_position : 4; // ItemPosition + unsigned m_positionType: 1; // Whether or not alignment uses the 'legacy' keyword. + unsigned m_overflow : 2; // OverflowAlignment +}; + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleSurroundData.cpp b/Source/WebCore/rendering/style/StyleSurroundData.cpp index 766a70f46..5c9bbdbec 100644 --- a/Source/WebCore/rendering/style/StyleSurroundData.cpp +++ b/Source/WebCore/rendering/style/StyleSurroundData.cpp @@ -39,7 +39,7 @@ inline StyleSurroundData::StyleSurroundData(const StyleSurroundData& o) { } -PassRef<StyleSurroundData> StyleSurroundData::copy() const +Ref<StyleSurroundData> StyleSurroundData::copy() const { return adoptRef(*new StyleSurroundData(*this)); } diff --git a/Source/WebCore/rendering/style/StyleSurroundData.h b/Source/WebCore/rendering/style/StyleSurroundData.h index 0dce31811..1f618a044 100644 --- a/Source/WebCore/rendering/style/StyleSurroundData.h +++ b/Source/WebCore/rendering/style/StyleSurroundData.h @@ -22,20 +22,19 @@ * */ -#ifndef StyleSurroundData_h -#define StyleSurroundData_h +#pragma once #include "BorderData.h" #include "LengthBox.h" +#include <wtf/Ref.h> #include <wtf/RefCounted.h> -#include <wtf/PassRefPtr.h> namespace WebCore { class StyleSurroundData : public RefCounted<StyleSurroundData> { public: - static PassRef<StyleSurroundData> create() { return adoptRef(*new StyleSurroundData); } - PassRef<StyleSurroundData> copy() const; + static Ref<StyleSurroundData> create() { return adoptRef(*new StyleSurroundData); } + Ref<StyleSurroundData> copy() const; bool operator==(const StyleSurroundData& o) const; bool operator!=(const StyleSurroundData& o) const @@ -54,5 +53,3 @@ private: }; } // namespace WebCore - -#endif // StyleSurroundData_h diff --git a/Source/WebCore/rendering/style/StyleTransformData.cpp b/Source/WebCore/rendering/style/StyleTransformData.cpp index c3f91ea2a..eaf7a6a43 100644 --- a/Source/WebCore/rendering/style/StyleTransformData.cpp +++ b/Source/WebCore/rendering/style/StyleTransformData.cpp @@ -27,30 +27,30 @@ namespace WebCore { StyleTransformData::StyleTransformData() - : m_operations(RenderStyle::initialTransform()) - , m_x(RenderStyle::initialTransformOriginX()) - , m_y(RenderStyle::initialTransformOriginY()) - , m_z(RenderStyle::initialTransformOriginZ()) + : operations(RenderStyle::initialTransform()) + , x(RenderStyle::initialTransformOriginX()) + , y(RenderStyle::initialTransformOriginY()) + , z(RenderStyle::initialTransformOriginZ()) { } -inline StyleTransformData::StyleTransformData(const StyleTransformData& o) +inline StyleTransformData::StyleTransformData(const StyleTransformData& other) : RefCounted<StyleTransformData>() - , m_operations(o.m_operations) - , m_x(o.m_x) - , m_y(o.m_y) - , m_z(o.m_z) + , operations(other.operations) + , x(other.x) + , y(other.y) + , z(other.z) { } -PassRef<StyleTransformData> StyleTransformData::copy() const +Ref<StyleTransformData> StyleTransformData::copy() const { return adoptRef(*new StyleTransformData(*this)); } -bool StyleTransformData::operator==(const StyleTransformData& o) const +bool StyleTransformData::operator==(const StyleTransformData& other) const { - return m_x == o.m_x && m_y == o.m_y && m_z == o.m_z && m_operations == o.m_operations; + return x == other.x && y == other.y && z == other.z && operations == other.operations; } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleTransformData.h b/Source/WebCore/rendering/style/StyleTransformData.h index e82ea2063..6b46a356b 100644 --- a/Source/WebCore/rendering/style/StyleTransformData.h +++ b/Source/WebCore/rendering/style/StyleTransformData.h @@ -22,31 +22,32 @@ * */ -#ifndef StyleTransformData_h -#define StyleTransformData_h +#pragma once #include "Length.h" #include "TransformOperations.h" -#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> #include <wtf/RefCounted.h> namespace WebCore { class StyleTransformData : public RefCounted<StyleTransformData> { public: - static PassRef<StyleTransformData> create() { return adoptRef(*new StyleTransformData); } - PassRef<StyleTransformData> copy() const; + static Ref<StyleTransformData> create() { return adoptRef(*new StyleTransformData); } + Ref<StyleTransformData> copy() const; - bool operator==(const StyleTransformData& o) const; - bool operator!=(const StyleTransformData& o) const + bool operator==(const StyleTransformData&) const; + bool operator!=(const StyleTransformData& other) const { - return !(*this == o); + return !(*this == other); } + + bool hasTransform() const { return operations.size(); } - TransformOperations m_operations; - Length m_x; - Length m_y; - float m_z; + TransformOperations operations; + Length x; + Length y; + float z; private: StyleTransformData(); @@ -54,5 +55,3 @@ private: }; } // namespace WebCore - -#endif // StyleTransformData_h diff --git a/Source/WebCore/rendering/style/StyleVisualData.cpp b/Source/WebCore/rendering/style/StyleVisualData.cpp index 23e6cd225..10fd5888f 100644 --- a/Source/WebCore/rendering/style/StyleVisualData.cpp +++ b/Source/WebCore/rendering/style/StyleVisualData.cpp @@ -29,10 +29,7 @@ namespace WebCore { StyleVisualData::StyleVisualData() : hasClip(false) , textDecoration(RenderStyle::initialTextDecoration()) -#if ENABLE(TEXT_AUTOSIZING) - , m_textAutosizingMultiplier(1) -#endif - , m_zoom(RenderStyle::initialZoom()) + , zoom(RenderStyle::initialZoom()) { } @@ -40,19 +37,16 @@ StyleVisualData::~StyleVisualData() { } -inline StyleVisualData::StyleVisualData(const StyleVisualData& o) +inline StyleVisualData::StyleVisualData(const StyleVisualData& other) : RefCounted<StyleVisualData>() - , clip(o.clip) - , hasClip(o.hasClip) - , textDecoration(o.textDecoration) -#if ENABLE(TEXT_AUTOSIZING) - , m_textAutosizingMultiplier(o.m_textAutosizingMultiplier) -#endif - , m_zoom(RenderStyle::initialZoom()) + , clip(other.clip) + , hasClip(other.hasClip) + , textDecoration(other.textDecoration) + , zoom(RenderStyle::initialZoom()) { } -PassRef<StyleVisualData> StyleVisualData::copy() const +Ref<StyleVisualData> StyleVisualData::copy() const { return adoptRef(*new StyleVisualData(*this)); } diff --git a/Source/WebCore/rendering/style/StyleVisualData.h b/Source/WebCore/rendering/style/StyleVisualData.h index 2b2d63027..d418acb50 100644 --- a/Source/WebCore/rendering/style/StyleVisualData.h +++ b/Source/WebCore/rendering/style/StyleVisualData.h @@ -22,42 +22,34 @@ * */ -#ifndef StyleVisualData_h -#define StyleVisualData_h +#pragma once #include "LengthBox.h" #include "RenderStyleConstants.h" +#include <wtf/Ref.h> #include <wtf/RefCounted.h> -#include <wtf/PassRefPtr.h> namespace WebCore { class StyleVisualData : public RefCounted<StyleVisualData> { public: - static PassRef<StyleVisualData> create() { return adoptRef(*new StyleVisualData); } - PassRef<StyleVisualData> copy() const; + static Ref<StyleVisualData> create() { return adoptRef(*new StyleVisualData); } + Ref<StyleVisualData> copy() const; ~StyleVisualData(); - bool operator==(const StyleVisualData& o) const + bool operator==(const StyleVisualData& other) const { - return clip == o.clip - && hasClip == o.hasClip - && textDecoration == o.textDecoration -#if ENABLE(TEXT_AUTOSIZING) - && m_textAutosizingMultiplier == o.m_textAutosizingMultiplier -#endif - && m_zoom == o.m_zoom; + return clip == other.clip + && hasClip == other.hasClip + && textDecoration == other.textDecoration + && zoom == other.zoom; } - bool operator!=(const StyleVisualData& o) const { return !(*this == o); } + bool operator!=(const StyleVisualData& other) const { return !(*this == other); } LengthBox clip; bool hasClip : 1; unsigned textDecoration : TextDecorationBits; // Text decorations defined *only* by this element. - -#if ENABLE(TEXT_AUTOSIZING) - float m_textAutosizingMultiplier; -#endif - float m_zoom; + float zoom; private: StyleVisualData(); @@ -65,5 +57,3 @@ private: }; } // namespace WebCore - -#endif // StyleVisualData_h diff --git a/Source/WebCore/rendering/style/TextSizeAdjustment.h b/Source/WebCore/rendering/style/TextSizeAdjustment.h new file mode 100644 index 000000000..f37c30146 --- /dev/null +++ b/Source/WebCore/rendering/style/TextSizeAdjustment.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#pragma once + +#if ENABLE(TEXT_AUTOSIZING) + +namespace WebCore { + +enum TextSizeAdjustmentType { AutoTextSizeAdjustment = -1, NoTextSizeAdjustment = -2 }; + +class TextSizeAdjustment { +public: + TextSizeAdjustment() : m_value(AutoTextSizeAdjustment) { } + TextSizeAdjustment(float value) : m_value(value) { } + + float percentage() const { return m_value; } + float multiplier() const { return m_value / 100; } + + bool isAuto() const { return m_value == AutoTextSizeAdjustment; } + bool isNone() const { return m_value == NoTextSizeAdjustment; } + bool isPercentage() const { return m_value >= 0; } + + bool operator==(const TextSizeAdjustment& anAdjustment) const { return m_value == anAdjustment.m_value; } + bool operator!=(const TextSizeAdjustment& anAdjustment) const { return m_value != anAdjustment.m_value; } + +private: + float m_value; +}; + +} // namespace WebCore + +#endif // ENABLE(TEXT_AUTOSIZING) diff --git a/Source/WebCore/rendering/style/WillChangeData.cpp b/Source/WebCore/rendering/style/WillChangeData.cpp new file mode 100644 index 000000000..6763ea22d --- /dev/null +++ b/Source/WebCore/rendering/style/WillChangeData.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WillChangeData.h" + +namespace WebCore { + +bool WillChangeData::operator==(const WillChangeData& other) const +{ + return m_animatableFeatures == other.m_animatableFeatures; +} + +bool WillChangeData::containsScrollPosition() const +{ + for (const auto& feature : m_animatableFeatures) { + if (feature.feature() == ScrollPosition) + return true; + } + return false; +} + +bool WillChangeData::containsContents() const +{ + for (const auto& feature : m_animatableFeatures) { + if (feature.feature() == Contents) + return true; + } + return false; +} + +bool WillChangeData::containsProperty(CSSPropertyID property) const +{ + for (const auto& feature : m_animatableFeatures) { + if (feature.property() == property) + return true; + } + return false; +} + +// "If any non-initial value of a property would create a stacking context on the element, +// specifying that property in will-change must create a stacking context on the element." +bool WillChangeData::propertyCreatesStackingContext(CSSPropertyID property) +{ + switch (property) { + case CSSPropertyPerspective: + case CSSPropertyTransform: + case CSSPropertyTransformStyle: + case CSSPropertyWebkitTransformStyle: + case CSSPropertyClipPath: + case CSSPropertyWebkitClipPath: + case CSSPropertyMask: + case CSSPropertyOpacity: + case CSSPropertyPosition: + case CSSPropertyZIndex: + case CSSPropertyWebkitBoxReflect: +#if ENABLE(CSS_COMPOSITING) + case CSSPropertyMixBlendMode: + case CSSPropertyIsolation: +#endif + case CSSPropertyFilter: +#if ENABLE(FILTERS_LEVEL_2) + case CSSPropertyWebkitBackdropFilter: +#endif + case CSSPropertyWebkitMask: + case CSSPropertyWebkitMaskImage: + case CSSPropertyWebkitMaskBoxImage: +#if ENABLE(CSS_REGIONS) + case CSSPropertyWebkitFlowFrom: +#endif +#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) + case CSSPropertyWebkitOverflowScrolling: +#endif + return true; + default: + return false; + } +} + +static bool propertyTriggersCompositing(CSSPropertyID property) +{ + switch (property) { + case CSSPropertyOpacity: + case CSSPropertyFilter: +#if ENABLE(FILTERS_LEVEL_2) + case CSSPropertyWebkitBackdropFilter: +#endif + return true; + default: + return false; + } +} + +static bool propertyTriggersCompositingOnBoxesOnly(CSSPropertyID property) +{ + // Don't trigger for perspective and transform-style, because those + // only do compositing if they have a 3d-transformed descendant and + // we don't want to do compositing all the time. + // Similarly, we don't want -webkit-overflow-scrolling-touch to + // always composite if there's no scrollable overflow. + switch (property) { + case CSSPropertyTransform: + return true; + default: + return false; + } +} + +void WillChangeData::addFeature(Feature feature, CSSPropertyID propertyID) +{ + ASSERT(feature == Property || propertyID == CSSPropertyInvalid); + m_animatableFeatures.append(AnimatableFeature(feature, propertyID)); + + m_canCreateStackingContext |= propertyCreatesStackingContext(propertyID); + + m_canTriggerCompositingOnInline |= propertyTriggersCompositing(propertyID); + m_canTriggerCompositing |= m_canTriggerCompositingOnInline | propertyTriggersCompositingOnBoxesOnly(propertyID); +} + +WillChangeData::FeaturePropertyPair WillChangeData::featureAt(size_t index) const +{ + if (index >= m_animatableFeatures.size()) + return FeaturePropertyPair(Invalid, CSSPropertyInvalid); + + return m_animatableFeatures[index].featurePropertyPair(); +} + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/WillChangeData.h b/Source/WebCore/rendering/style/WillChangeData.h new file mode 100644 index 000000000..a336a1082 --- /dev/null +++ b/Source/WebCore/rendering/style/WillChangeData.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "CSSPropertyNames.h" +#include "RenderStyleConstants.h" +#include <wtf/RefCounted.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class WillChangeData : public RefCounted<WillChangeData> { + WTF_MAKE_FAST_ALLOCATED; +public: + static Ref<WillChangeData> create() + { + return adoptRef(*new WillChangeData); + } + + bool operator==(const WillChangeData&) const; + bool operator!=(const WillChangeData& o) const + { + return !(*this == o); + } + + bool isAuto() const { return m_animatableFeatures.isEmpty(); } + size_t numFeatures() const { return m_animatableFeatures.size(); } + + bool containsScrollPosition() const; + bool containsContents() const; + bool containsProperty(CSSPropertyID) const; + + bool canCreateStackingContext() const { return m_canCreateStackingContext; } + bool canTriggerCompositing() const { return m_canTriggerCompositing; } + bool canTriggerCompositingOnInline() const { return m_canTriggerCompositingOnInline; } + + enum Feature { + ScrollPosition, + Contents, + Property, + Invalid + }; + + void addFeature(Feature, CSSPropertyID = CSSPropertyInvalid); + + typedef std::pair<Feature, CSSPropertyID> FeaturePropertyPair; + FeaturePropertyPair featureAt(size_t) const; + + static bool propertyCreatesStackingContext(CSSPropertyID); + +private: + WillChangeData() + { + } + + struct AnimatableFeature { + static const int numCSSPropertyIDBits = 14; + COMPILE_ASSERT(numCSSProperties < (1 << numCSSPropertyIDBits), CSSPropertyID_should_fit_in_14_bits); + + unsigned m_feature : 2; + unsigned m_cssPropertyID : numCSSPropertyIDBits; + + Feature feature() const + { + return static_cast<Feature>(m_feature); + } + + CSSPropertyID property() const + { + return feature() == Property ? static_cast<CSSPropertyID>(m_cssPropertyID) : CSSPropertyInvalid; + } + + FeaturePropertyPair featurePropertyPair() const + { + return FeaturePropertyPair(feature(), property()); + } + + AnimatableFeature(Feature willChange, CSSPropertyID willChangeProperty = CSSPropertyInvalid) + { + switch (willChange) { + case Property: + ASSERT(willChangeProperty != CSSPropertyInvalid); + m_cssPropertyID = willChangeProperty; + FALLTHROUGH; + case ScrollPosition: + case Contents: + m_feature = static_cast<unsigned>(willChange); + break; + case Invalid: + ASSERT_NOT_REACHED(); + break; + } + } + + bool operator==(const AnimatableFeature& other) const + { + return m_feature == other.m_feature && m_cssPropertyID == other.m_cssPropertyID; + } + }; + + Vector<AnimatableFeature, 1> m_animatableFeatures; + bool m_canCreateStackingContext { false }; + bool m_canTriggerCompositing { false }; + bool m_canTriggerCompositingOnInline { false }; +}; + +} // namespace WebCore |