diff options
| author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
|---|---|---|
| committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
| commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
| tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/rendering/style | |
| parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
| download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz | |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/WebCore/rendering/style')
95 files changed, 6199 insertions, 3259 deletions
diff --git a/Source/WebCore/rendering/style/BasicShapes.cpp b/Source/WebCore/rendering/style/BasicShapes.cpp index b5927f924..eafeff75b 100644 --- a/Source/WebCore/rendering/style/BasicShapes.cpp +++ b/Source/WebCore/rendering/style/BasicShapes.cpp @@ -31,185 +31,402 @@ #include "BasicShapes.h" +#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 { -bool BasicShape::canBlend(const BasicShape* other) const +void BasicShapeCenterCoordinate::updateComputedLength() +{ + if (m_direction == TopLeft) { + m_computedLength = m_length.isUndefined() ? Length(0, Fixed) : m_length; + return; + } + if (m_length.isUndefined()) { + m_computedLength = Length(100, Percent); + return; + } + + 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), CalculationRangeAll)); +} + +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; + } +}; + +struct RoundedRectPathPolicy : public TinyLRUCachePolicy<FloatRoundedRect, Path> { +public: + static bool isKeyNull(const FloatRoundedRect& rect) { return rect.isEmpty(); } + + static Path createValueForKey(const FloatRoundedRect& rect) + { + Path path; + path.addRoundedRect(rect); + return path; + } +}; + +struct PolygonPathPolicy : public TinyLRUCachePolicy<Vector<FloatPoint>, Path> { +public: + static bool isKeyNull(const Vector<FloatPoint>& points) { return !points.size(); } + + 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); +} + +static const Path& cachedRoundedRectPath(const FloatRoundedRect& rect) +{ + static NeverDestroyed<TinyLRUCache<FloatRoundedRect, Path, 4, RoundedRectPathPolicy>> cache; + return cache.get().get(rect); +} + +static const Path& cachedPolygonPath(const Vector<FloatPoint>& points) +{ + static NeverDestroyed<TinyLRUCache<Vector<FloatPoint>, Path, 4, PolygonPathPolicy>> cache; + return cache.get().get(points); +} + +static const Path& cachedTranslatedByteStreamPath(const SVGPathByteStream& stream, const FloatPoint& offset) +{ + static NeverDestroyed<TinyLRUCache<SVGPathTranslatedByteStream, Path, 4, TranslatedByteStreamPathPolicy>> cache; + return cache.get().get(SVGPathTranslatedByteStream(offset, stream)); +} + +bool BasicShapeCircle::operator==(const BasicShape& other) const { - // FIXME: Support animations between different shapes in the future. - if (type() != other->type()) + if (type() != other.type()) return false; - // 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()) + 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 +{ + if (m_radius.type() == BasicShapeRadius::Value) + return floatValueForLength(m_radius.value(), sqrtf((boxWidth * boxWidth + boxHeight * boxHeight) / 2)); + + 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(std::abs(centerX), widthDelta), std::min(std::abs(centerY), heightDelta)); + + // If radius.type() == BasicShapeRadius::FarthestSide. + return std::max(std::max(std::abs(centerX), widthDelta), std::max(std::abs(centerY), heightDelta)); +} + +const Path& BasicShapeCircle::path(const FloatRect& boundingBox) +{ + float centerX = floatValueForCenterCoordinate(m_centerX, boundingBox.width()); + float centerY = floatValueForCenterCoordinate(m_centerY, boundingBox.height()); + float radius = floatValueForRadiusInBox(boundingBox.width(), boundingBox.height()); + + return cachedEllipsePath(FloatRect(centerX - radius + boundingBox.x(), centerY - radius + boundingBox.y(), radius * 2, radius * 2)); +} + +bool BasicShapeCircle::canBlend(const BasicShape& other) const +{ + if (type() != other.type()) return false; - return true; + return radius().canBlend(downcast<BasicShapeCircle>(other).radius()); } -void BasicShapeRectangle::path(Path& path, const FloatRect& boundingBox) +Ref<BasicShape> BasicShapeCircle::blend(const BasicShape& other, double progress) const { - 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()) - ) - ); + 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> BasicShapeRectangle::blend(const BasicShape* other, double progress) const +bool BasicShapeEllipse::operator==(const BasicShape& other) const { - ASSERT(type() == other->type()); + if (type() != other.type()) + return false; - 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(); + 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; } -void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox) +float BasicShapeEllipse::floatValueForRadiusInBox(const BasicShapeRadius& radius, float center, float boxWidthOrHeight) const { - 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 - )); + if (radius.type() == BasicShapeRadius::Value) + return floatValueForLength(radius.value(), std::abs(boxWidthOrHeight)); + + float widthOrHeightDelta = std::abs(boxWidthOrHeight - center); + if (radius.type() == BasicShapeRadius::ClosestSide) + return std::min(std::abs(center), widthOrHeightDelta); + + ASSERT(radius.type() == BasicShapeRadius::FarthestSide); + return std::max(std::abs(center), widthOrHeightDelta); } -PassRefPtr<BasicShape> BasicShapeCircle::blend(const BasicShape* other, double progress) const +const Path& BasicShapeEllipse::path(const FloatRect& boundingBox) { - ASSERT(type() == other->type()); + 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()); - 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(); + return cachedEllipsePath(FloatRect(centerX - radiusX + boundingBox.x(), centerY - radiusY + boundingBox.y(), radiusX * 2, radiusY * 2)); } -void BasicShapeEllipse::path(Path& path, const FloatRect& boundingBox) +bool BasicShapeEllipse::canBlend(const BasicShape& other) 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 - )); + 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()); + ASSERT(type() == other.type()); + auto& otherEllipse = downcast<BasicShapeEllipse>(other); + auto result = BasicShapeEllipse::create(); - const BasicShapeEllipse* o = static_cast<const BasicShapeEllipse*>(other); - RefPtr<BasicShapeEllipse> result = BasicShapeEllipse::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 (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(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); +} + +bool BasicShapePolygon::canBlend(const BasicShape& other) const +{ + if (type() != other.type()) + return false; + + auto& otherPolygon = downcast<BasicShapePolygon>(other); + return values().size() == otherPolygon.values().size() && windRule() == otherPolygon.windRule(); } -PassRefPtr<BasicShape> BasicShapePolygon::blend(const BasicShape* other, double progress) const +Ref<BasicShape> BasicShapePolygon::blend(const BasicShape& other, double progress) const { - ASSERT(type() == other->type()); + ASSERT(type() == other.type()); - const BasicShapePolygon* o = static_cast<const BasicShapePolygon*>(other); - ASSERT(m_values.size() == o->values().size()); + 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(m_values.at(i).blend(otherPolygon.values().at(i), progress), + m_values.at(i + 1).blend(otherPolygon.values().at(i + 1), progress)); } - return result.release(); + return WTFMove(result); +} + +BasicShapePath::BasicShapePath(std::unique_ptr<SVGPathByteStream>&& byteStream) + : m_byteStream(WTFMove(byteStream)) +{ +} + +const Path& BasicShapePath::path(const FloatRect& boundingBox) +{ + return cachedTranslatedByteStreamPath(*m_byteStream, boundingBox.location()); +} + +bool BasicShapePath::operator==(const BasicShape& other) const +{ + if (type() != other.type()) + return false; + + auto& otherPath = downcast<BasicShapePath>(other); + return m_windRule == otherPath.m_windRule && *m_byteStream == *otherPath.m_byteStream; } -void BasicShapeInsetRectangle::path(Path& path, const FloatRect& boundingBox) +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()); +} + +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 FloatSize(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_cornerRadiusX, boundingBox.width()), - floatValueForLength(m_cornerRadiusY, boundingBox.height()) - ) - ); -} - -PassRefPtr<BasicShape> BasicShapeInsetRectangle::blend(const BasicShape* other, double progress) 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(); + 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(); +} + +Ref<BasicShape> BasicShapeInset::blend(const BasicShape& other, double progress) const +{ + ASSERT(type() == other.type()); + + auto& otherInset = downcast<BasicShapeInset>(other); + auto result = BasicShapeInset::create(); + result->setTop(m_top.blend(otherInset.top(), progress)); + result->setRight(m_right.blend(otherInset.right(), progress)); + result->setBottom(m_bottom.blend(otherInset.bottom(), progress)); + result->setLeft(m_left.blend(otherInset.left(), progress)); + + result->setTopLeftRadius(m_topLeftRadius.blend(otherInset.topLeftRadius(), progress)); + result->setTopRightRadius(m_topRightRadius.blend(otherInset.topRightRadius(), progress)); + result->setBottomRightRadius(m_bottomRightRadius.blend(otherInset.bottomRightRadius(), progress)); + result->setBottomLeftRadius(m_bottomLeftRadius.blend(otherInset.bottomLeftRadius(), progress)); + + return WTFMove(result); } } diff --git a/Source/WebCore/rendering/style/BasicShapes.h b/Source/WebCore/rendering/style/BasicShapes.h index ec027fe91..be1572b13 100644 --- a/Source/WebCore/rendering/style/BasicShapes.h +++ b/Source/WebCore/rendering/style/BasicShapes.h @@ -31,196 +31,327 @@ #define BasicShapes_h #include "Length.h" +#include "LengthSize.h" +#include "RenderStyleConstants.h" #include "WindRule.h" #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#include <wtf/TypeCasts.h> #include <wtf/Vector.h> namespace WebCore { class FloatRect; class Path; +class RenderBox; +class SVGPathByteStream; class BasicShape : public RefCounted<BasicShape> { public: virtual ~BasicShape() { } enum Type { - BasicShapeRectangleType = 1, - BasicShapeCircleType = 2, - BasicShapeEllipseType = 3, - BasicShapePolygonType = 4, - BasicShapeInsetRectangleType = 5 + BasicShapePolygonType, + BasicShapePathType, + BasicShapeCircleType, + BasicShapeEllipseType, + BasicShapeInsetType }; - bool canBlend(const BasicShape*) const; + virtual Type type() const = 0; - virtual void path(Path&, const FloatRect&) = 0; + virtual const 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; -protected: - BasicShape() { } + virtual bool canBlend(const BasicShape&) const = 0; + virtual Ref<BasicShape> blend(const BasicShape&, double) const = 0; + + virtual bool operator==(const BasicShape&) const = 0; }; -class BasicShapeRectangle : public BasicShape { +class BasicShapeCenterCoordinate { public: - static PassRefPtr<BasicShapeRectangle> create() { return adoptRef(new BasicShapeRectangle); } - - Length x() const { return m_x; } - Length y() const { return m_y; } - Length width() const { return m_width; } - Length height() const { return m_height; } - Length cornerRadiusX() const { return m_cornerRadiusX; } - Length cornerRadiusY() const { return m_cornerRadiusY; } - - void setX(Length x) { m_x = x; } - void setY(Length y) { m_y = y; } - void setWidth(Length width) { m_width = width; } - void setHeight(Length height) { m_height = height; } - void setCornerRadiusX(Length radiusX) + enum Direction { + TopLeft, + BottomRight + }; + + BasicShapeCenterCoordinate() + : m_direction(TopLeft) + , m_length(Undefined) { - ASSERT(!radiusX.isUndefined()); - m_cornerRadiusX = radiusX; + updateComputedLength(); } - void setCornerRadiusY(Length radiusY) + + BasicShapeCenterCoordinate(Direction direction, Length length) + : m_direction(direction) + , m_length(length) { - ASSERT(!radiusY.isUndefined()); - m_cornerRadiusY = radiusY; + updateComputedLength(); } - virtual void path(Path&, const FloatRect&) OVERRIDE; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE; + BasicShapeCenterCoordinate(const BasicShapeCenterCoordinate& other) + : m_direction(other.direction()) + , m_length(other.length()) + , m_computedLength(other.m_computedLength) + { + } + + Direction direction() const { return m_direction; } + const Length& length() const { return m_length; } + const Length& computedLength() const { return m_computedLength; } + + BasicShapeCenterCoordinate blend(const BasicShapeCenterCoordinate& other, double progress) const + { + return BasicShapeCenterCoordinate(TopLeft, m_computedLength.blend(other.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; + } - virtual Type type() const { return BasicShapeRectangleType; } private: - BasicShapeRectangle() { } - - Length m_y; - Length m_x; - Length m_width; - Length m_height; - Length m_cornerRadiusX; - Length m_cornerRadiusY; + void updateComputedLength(); + + Direction m_direction; + Length m_length; + Length m_computedLength; }; -class BasicShapeCircle : public BasicShape { +class BasicShapeRadius { public: - static PassRefPtr<BasicShapeCircle> create() { return adoptRef(new BasicShapeCircle); } + enum Type { + Value, + ClosestSide, + FarthestSide + }; + BasicShapeRadius() + : m_value(Undefined), + m_type(ClosestSide) + { } - Length centerX() const { return m_centerX; } - Length centerY() const { return m_centerY; } - Length radius() const { return m_radius; } + 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; } + + bool canBlend(const BasicShapeRadius& other) const + { + // FIXME determine how to interpolate between keywords. See bug 125108. + return m_type == Value && other.type() == Value; + } - void setCenterX(Length centerX) { m_centerX = centerX; } - void setCenterY(Length centerY) { m_centerY = centerY; } - void setRadius(Length radius) { m_radius = radius; } + BasicShapeRadius blend(const BasicShapeRadius& other, double progress) const + { + if (m_type != Value || other.type() != Value) + return BasicShapeRadius(other); - virtual void path(Path&, const FloatRect&) OVERRIDE; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE; + return BasicShapeRadius(m_value.blend(other.value(), progress)); + } + + bool operator==(const BasicShapeRadius& other) const + { + return m_value == other.m_value && m_type == other.m_type; + } - virtual Type type() const { return BasicShapeCircleType; } private: - BasicShapeCircle() { } + Length m_value; + Type m_type; - Length m_centerX; - Length m_centerY; - Length m_radius; }; -class BasicShapeEllipse : public BasicShape { +class BasicShapeCircle final : public BasicShape { public: - static PassRefPtr<BasicShapeEllipse> create() { return adoptRef(new BasicShapeEllipse); } + 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; - Length centerX() const { return m_centerX; } - Length centerY() const { return m_centerY; } - Length radiusX() const { return m_radiusX; } - Length radiusY() const { return m_radiusY; } + void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = WTFMove(centerX); } + void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = WTFMove(centerY); } + void setRadius(BasicShapeRadius radius) { m_radius = WTFMove(radius); } - void setCenterX(Length centerX) { m_centerX = centerX; } - void setCenterY(Length centerY) { m_centerY = centerY; } - void setRadiusX(Length radiusX) { m_radiusX = radiusX; } - void setRadiusY(Length radiusY) { m_radiusY = radiusY; } +private: + BasicShapeCircle() = default; + + virtual Type type() const override { return BasicShapeCircleType; } + + virtual const Path& path(const FloatRect&) override; + + virtual bool canBlend(const BasicShape&) const override; + virtual Ref<BasicShape> blend(const BasicShape&, double) const override; + + virtual bool operator==(const BasicShape&) const override; + + BasicShapeCenterCoordinate m_centerX; + BasicShapeCenterCoordinate m_centerY; + BasicShapeRadius m_radius; +}; + +class BasicShapeEllipse final : public BasicShape { +public: + static Ref<BasicShapeEllipse> create() { return adoptRef(*new BasicShapeEllipse); } - virtual void path(Path&, const FloatRect&) OVERRIDE; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE; + const BasicShapeCenterCoordinate& centerX() const { return m_centerX; } + const BasicShapeCenterCoordinate& centerY() const { return m_centerY; } + const BasicShapeRadius& radiusX() const { return m_radiusX; } + const BasicShapeRadius& radiusY() const { return m_radiusY; } + float floatValueForRadiusInBox(const BasicShapeRadius&, float center, float boxWidthOrHeight) const; + + 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 { return BasicShapeEllipseType; } private: - BasicShapeEllipse() { } + BasicShapeEllipse() = default; + + virtual Type type() const override { return BasicShapeEllipseType; } + + virtual const Path& path(const FloatRect&) override; + + virtual bool canBlend(const BasicShape&) const override; + virtual Ref<BasicShape> blend(const BasicShape&, double) const override; + + virtual bool operator==(const BasicShape&) const override; - 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; } - Length getXAt(unsigned i) const { return m_values.at(2 * i); } - Length getYAt(unsigned i) const { return m_values.at(2 * i + 1); } + 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(x); m_values.append(y); } + void appendPoint(Length x, Length y) { m_values.append(WTFMove(x)); m_values.append(WTFMove(y)); } - virtual void path(Path&, const FloatRect&) OVERRIDE; - virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE; + virtual WindRule windRule() const override { return m_windRule; } - virtual WindRule windRule() const { return m_windRule; } - - virtual Type type() const { return BasicShapePolygonType; } private: - BasicShapePolygon() - : m_windRule(RULE_NONZERO) - { } + BasicShapePolygon() = default; + + virtual Type type() const override { return BasicShapePolygonType; } + + virtual const Path& path(const FloatRect&) override; + + virtual bool canBlend(const BasicShape&) const override; + virtual Ref<BasicShape> blend(const BasicShape&, double) const override; - WindRule m_windRule; + virtual 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); } - - Length top() const { return m_top; } - Length right() const { return m_right; } - Length bottom() const { return m_bottom; } - Length left() const { return m_left; } - Length cornerRadiusX() const { return m_cornerRadiusX; } - Length cornerRadiusY() const { return m_cornerRadiusY; } - - void setTop(Length top) { m_top = top; } - void setRight(Length right) { m_right = right; } - void setBottom(Length bottom) { m_bottom = bottom; } - void setLeft(Length left) { m_left = left; } - void setCornerRadiusX(Length radiusX) - { - ASSERT(!radiusX.isUndefined()); - m_cornerRadiusX = radiusX; - } - void setCornerRadiusY(Length radiusY) + static Ref<BasicShapePath> create(std::unique_ptr<SVGPathByteStream>&& byteStream) { - ASSERT(!radiusY.isUndefined()); - m_cornerRadiusY = 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; } + virtual WindRule windRule() const override { return m_windRule; } + + const SVGPathByteStream* pathData() const { return m_byteStream.get(); } + +private: + BasicShapePath(std::unique_ptr<SVGPathByteStream>&&); + + virtual Type type() const override { return BasicShapePathType; } + + virtual const Path& path(const FloatRect&) override; + + virtual bool canBlend(const BasicShape&) const override; + virtual Ref<BasicShape> blend(const BasicShape&, double) const override; + + virtual bool operator==(const BasicShape&) const override; + + std::unique_ptr<SVGPathByteStream> m_byteStream; + WindRule m_windRule { RULE_NONZERO }; +}; + +class BasicShapeInset final : public BasicShape { +public: + static Ref<BasicShapeInset> create() { return adoptRef(*new BasicShapeInset); } + + 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 LengthSize& topLeftRadius() const { return m_topLeftRadius; } + const LengthSize& topRightRadius() const { return m_topRightRadius; } + const LengthSize& bottomRightRadius() const { return m_bottomRightRadius; } + const LengthSize& bottomLeftRadius() const { return m_bottomLeftRadius; } + + 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 = 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 Type type() const { return BasicShapeInsetRectangleType; } private: - BasicShapeInsetRectangle() { } + BasicShapeInset() = default; + + virtual Type type() const override { return BasicShapeInsetType; } + + virtual const Path& path(const FloatRect&) override; + + virtual bool canBlend(const BasicShape&) const override; + virtual Ref<BasicShape> blend(const BasicShape&, double) const override; + + virtual bool operator==(const BasicShape&) const override; Length m_right; Length m_top; Length m_bottom; Length m_left; - Length m_cornerRadiusX; - Length m_cornerRadiusY; + + LengthSize m_topLeftRadius; + LengthSize m_topRightRadius; + LengthSize m_bottomRightRadius; + 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) + +#endif // BasicShapes_h diff --git a/Source/WebCore/rendering/style/BorderData.h b/Source/WebCore/rendering/style/BorderData.h index e65628a99..cd1a5834c 100644 --- a/Source/WebCore/rendering/style/BorderData.h +++ b/Source/WebCore/rendering/style/BorderData.h @@ -47,6 +47,11 @@ public: return m_left.nonZero(!haveImage) || m_right.nonZero(!haveImage) || m_top.nonZero(!haveImage) || m_bottom.nonZero(!haveImage); } + bool hasFill() const + { + return m_image.hasImage() && m_image.fill(); + } + bool hasBorderRadius() const { if (!m_topLeft.width().isZero()) @@ -60,33 +65,38 @@ public: return false; } - 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 { diff --git a/Source/WebCore/rendering/style/BorderValue.h b/Source/WebCore/rendering/style/BorderValue.h index c8f6512c5..cf340d0f6 100644 --- a/Source/WebCore/rendering/style/BorderValue.h +++ b/Source/WebCore/rendering/style/BorderValue.h @@ -34,9 +34,9 @@ class BorderValue { friend class RenderStyle; public: BorderValue() - : m_color(0) + : m_width(3) + , m_color(0) , m_colorIsValid(false) - , m_width(3) , m_style(BNONE) , m_isAuto(AUTO_OFF) { @@ -75,14 +75,14 @@ public: Color color() const { return Color(m_color, m_colorIsValid); } - unsigned width() const { return m_width; } + float width() const { return m_width; } EBorderStyle style() const { return static_cast<EBorderStyle>(m_style); } protected: + float m_width; RGBA32 m_color; unsigned m_colorIsValid : 1; - unsigned m_width : 26; unsigned m_style : 4; // EBorderStyle // This is only used by OutlineValue but moved here to keep the bits packed. diff --git a/Source/WebCore/rendering/style/CollapsedBorderValue.h b/Source/WebCore/rendering/style/CollapsedBorderValue.h index 120173bda..da9c53a6f 100644 --- a/Source/WebCore/rendering/style/CollapsedBorderValue.h +++ b/Source/WebCore/rendering/style/CollapsedBorderValue.h @@ -26,15 +26,14 @@ #define CollapsedBorderValue_h #include "BorderValue.h" +#include "LayoutUnit.h" namespace WebCore { class CollapsedBorderValue { public: CollapsedBorderValue() - : m_color(0) - , m_colorIsValid(false) - , m_width(0) + : m_colorIsValid(false) , m_style(BNONE) , m_precedence(BOFF) , m_transparent(false) @@ -42,16 +41,16 @@ public: } CollapsedBorderValue(const BorderValue& border, const Color& color, EBorderPrecedence precedence) - : m_color(color.rgb()) + : m_width(LayoutUnit(border.nonZero() ? border.width() : 0)) + , m_color(color.rgb()) , m_colorIsValid(color.isValid()) - , m_width(border.nonZero() ? border.width() : 0) , 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); } @@ -64,9 +63,9 @@ public: } private: - RGBA32 m_color; + LayoutUnit m_width; + RGBA32 m_color { 0 }; unsigned m_colorIsValid : 1; - unsigned m_width : 23; unsigned m_style : 4; // EBorderStyle unsigned m_precedence : 3; // EBorderPrecedence unsigned m_transparent : 1; diff --git a/Source/WebCore/rendering/style/ContentData.cpp b/Source/WebCore/rendering/style/ContentData.cpp index 7a115b915..ea28c4269 100644 --- a/Source/WebCore/rendering/style/ContentData.cpp +++ b/Source/WebCore/rendering/style/ContentData.cpp @@ -33,70 +33,45 @@ namespace WebCore { -PassOwnPtr<ContentData> ContentData::create(PassRefPtr<StyleImage> image) +std::unique_ptr<ContentData> ContentData::clone() const { - return adoptPtr(new ImageContentData(image)); -} - -PassOwnPtr<ContentData> ContentData::create(const String& text) -{ - return adoptPtr(new TextContentData(text)); -} - -PassOwnPtr<ContentData> ContentData::create(PassOwnPtr<CounterContent> counter) -{ - return adoptPtr(new CounterContentData(counter)); -} - -PassOwnPtr<ContentData> ContentData::create(QuoteType quote) -{ - return adoptPtr(new QuoteContentData(quote)); -} - -PassOwnPtr<ContentData> ContentData::clone() const -{ - OwnPtr<ContentData> result = cloneInternal(); + auto result = cloneInternal(); ContentData* lastNewData = result.get(); for (const ContentData* contentData = next(); contentData; contentData = contentData->next()) { - OwnPtr<ContentData> newData = contentData->cloneInternal(); - lastNewData->setNext(newData.release()); + auto newData = contentData->cloneInternal(); + lastNewData->setNext(WTFMove(newData)); lastNewData = lastNewData->next(); } - return result.release(); + return result; } -RenderObject* ImageContentData::createRenderer(Document* doc, RenderStyle* pseudoStyle) const +RenderPtr<RenderObject> ImageContentData::createContentRenderer(Document& document, const RenderStyle& pseudoStyle) const { - RenderImage* image = RenderImage::createAnonymous(doc); - image->setPseudoStyle(pseudoStyle); - if (m_image) - image->setImageResource(RenderImageResourceStyleImage::create(m_image.get())); - else - image->setImageResource(RenderImageResource::create()); - return image; + auto image = createRenderer<RenderImage>(document, RenderStyle::createStyleInheritingFromPseudoStyle(pseudoStyle), m_image.get()); + image->initializeStyle(); + image->setAltText(altText()); + return WTFMove(image); } -RenderObject* TextContentData::createRenderer(Document* doc, RenderStyle* pseudoStyle) const +RenderPtr<RenderObject> TextContentData::createContentRenderer(Document& document, const RenderStyle&) const { - RenderObject* renderer = new (doc->renderArena()) RenderTextFragment(doc, m_text.impl()); - renderer->setPseudoStyle(pseudoStyle); - return renderer; + auto fragment = createRenderer<RenderTextFragment>(document, m_text); + fragment->setAltText(altText()); + return WTFMove(fragment); } -RenderObject* CounterContentData::createRenderer(Document* doc, RenderStyle* pseudoStyle) const +RenderPtr<RenderObject> CounterContentData::createContentRenderer(Document& document, const RenderStyle&) const { - RenderObject* renderer = new (doc->renderArena()) RenderCounter(doc, *m_counter); - renderer->setPseudoStyle(pseudoStyle); - return renderer; + return createRenderer<RenderCounter>(document, *m_counter); } -RenderObject* QuoteContentData::createRenderer(Document* doc, RenderStyle* pseudoStyle) const +RenderPtr<RenderObject> QuoteContentData::createContentRenderer(Document& document, const RenderStyle& pseudoStyle) const { - RenderObject* renderer = new (doc->renderArena()) RenderQuote(doc, m_quote); - renderer->setPseudoStyle(pseudoStyle); - return renderer; + auto quote = createRenderer<RenderQuote>(document, RenderStyle::createStyleInheritingFromPseudoStyle(pseudoStyle), m_quote); + quote->initializeStyle(); + return WTFMove(quote); } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/ContentData.h b/Source/WebCore/rendering/style/ContentData.h index 3346a6516..d97a197b8 100644 --- a/Source/WebCore/rendering/style/ContentData.h +++ b/Source/WebCore/rendering/style/ContentData.h @@ -27,8 +27,8 @@ #include "CounterContent.h" #include "StyleImage.h" -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> +#include "RenderPtr.h" +#include <wtf/TypeCasts.h> namespace WebCore { @@ -39,153 +39,199 @@ class RenderStyle; class ContentData { WTF_MAKE_FAST_ALLOCATED; public: - static PassOwnPtr<ContentData> create(PassRefPtr<StyleImage>); - static PassOwnPtr<ContentData> create(const String&); - static PassOwnPtr<ContentData> create(PassOwnPtr<CounterContent>); - static PassOwnPtr<ContentData> create(QuoteType); - + 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; } - virtual RenderObject* createRenderer(Document*, RenderStyle*) const = 0; + 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 PassOwnPtr<ContentData> clone() const; + virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const = 0; + + std::unique_ptr<ContentData> clone() const; ContentData* next() const { return m_next.get(); } - void setNext(PassOwnPtr<ContentData> next) { m_next = 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 PassOwnPtr<ContentData> cloneInternal() const = 0; + virtual std::unique_ptr<ContentData> cloneInternal() const = 0; - OwnPtr<ContentData> m_next; + std::unique_ptr<ContentData> m_next; + String m_altText; + Type m_type; }; -class ImageContentData : public ContentData { - friend class ContentData; +class ImageContentData final : public ContentData { public: - 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 RenderObject* createRenderer(Document*, RenderStyle*) const OVERRIDE; - - virtual bool equals(const ContentData& data) const OVERRIDE + explicit ImageContentData(PassRefPtr<StyleImage> image) + : ContentData(ImageDataType) + , m_image(image) { - if (!data.isImage()) - return false; - return *static_cast<const ImageContentData&>(data).image() == *image(); + ASSERT(m_image); } -private: - ImageContentData(PassRefPtr<StyleImage> image) - : m_image(image) + const StyleImage& image() const { return *m_image; } + void setImage(PassRefPtr<StyleImage> image) { + ASSERT(image); + m_image = image; } - virtual PassOwnPtr<ContentData> cloneInternal() const + virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override; + +private: + virtual std::unique_ptr<ContentData> cloneInternal() const override { - RefPtr<StyleImage> image = const_cast<StyleImage*>(this->image()); - return create(image.release()); + std::unique_ptr<ContentData> image = std::make_unique<ImageContentData>(m_image.get()); + image->setAltText(altText()); + + return image; } RefPtr<StyleImage> m_image; }; -class TextContentData : public ContentData { - friend class ContentData; -public: - const String& text() const { return m_text; } - void setText(const String& text) { m_text = text; } +inline bool operator==(const ImageContentData& a, const ImageContentData& b) +{ + return a.image() == b.image(); +} - virtual bool isText() const OVERRIDE { return true; } - virtual RenderObject* createRenderer(Document*, RenderStyle*) const OVERRIDE; +inline bool operator!=(const ImageContentData& a, const ImageContentData& b) +{ + return !(a == b); +} - virtual bool equals(const ContentData& data) const OVERRIDE +class TextContentData final : public ContentData { +public: + explicit TextContentData(const String& text) + : ContentData(TextDataType) + , m_text(text) { - if (!data.isText()) - return false; - return static_cast<const TextContentData&>(data).text() == text(); } -private: - TextContentData(const String& text) - : m_text(text) - { - } + const String& text() const { return m_text; } + void setText(const String& text) { m_text = text; } - virtual PassOwnPtr<ContentData> cloneInternal() const { return create(text()); } + virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override; + +private: + virtual std::unique_ptr<ContentData> cloneInternal() const override { return std::make_unique<TextContentData>(text()); } String m_text; }; -class CounterContentData : public ContentData { - friend class ContentData; -public: - const CounterContent* counter() const { return m_counter.get(); } - void setCounter(PassOwnPtr<CounterContent> counter) { m_counter = counter; } +inline bool operator==(const TextContentData& a, const TextContentData& b) +{ + return a.text() == b.text(); +} - virtual bool isCounter() const OVERRIDE { return true; } - virtual RenderObject* createRenderer(Document*, RenderStyle*) const OVERRIDE; +inline bool operator!=(const TextContentData& a, const TextContentData& b) +{ + return !(a == b); +} -private: - CounterContentData(PassOwnPtr<CounterContent> counter) - : m_counter(counter) +class CounterContentData final : public ContentData { +public: + explicit CounterContentData(std::unique_ptr<CounterContent> counter) + : ContentData(CounterDataType) + , m_counter(WTFMove(counter)) { + ASSERT(m_counter); } - virtual PassOwnPtr<ContentData> cloneInternal() const + const CounterContent& counter() const { return *m_counter; } + void setCounter(std::unique_ptr<CounterContent> counter) { - OwnPtr<CounterContent> counterData = adoptPtr(new CounterContent(*counter())); - return create(counterData.release()); + ASSERT(counter); + m_counter = WTFMove(counter); } - virtual bool equals(const ContentData& data) const OVERRIDE + virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override; + +private: + virtual std::unique_ptr<ContentData> cloneInternal() const override { - if (!data.isCounter()) - return false; - return *static_cast<const CounterContentData&>(data).counter() == *counter(); + auto counterData = std::make_unique<CounterContent>(counter()); + return std::make_unique<CounterContentData>(WTFMove(counterData)); } - OwnPtr<CounterContent> m_counter; + std::unique_ptr<CounterContent> m_counter; }; -class QuoteContentData : public ContentData { - friend class ContentData; -public: - QuoteType quote() const { return m_quote; } - void setQuote(QuoteType quote) { m_quote = quote; } +inline bool operator==(const CounterContentData& a, const CounterContentData& b) +{ + return a.counter() == b.counter(); +} - virtual bool isQuote() const OVERRIDE { return true; } - virtual RenderObject* createRenderer(Document*, RenderStyle*) const OVERRIDE; +inline bool operator!=(const CounterContentData& a, const CounterContentData& b) +{ + return !(a == b); +} - virtual bool equals(const ContentData& data) const OVERRIDE +class QuoteContentData final : public ContentData { +public: + explicit QuoteContentData(QuoteType quote) + : ContentData(QuoteDataType) + , m_quote(quote) { - if (!data.isQuote()) - return false; - return static_cast<const QuoteContentData&>(data).quote() == quote(); } -private: - QuoteContentData(QuoteType quote) - : m_quote(quote) - { - } + QuoteType quote() const { return m_quote; } + void setQuote(QuoteType quote) { m_quote = quote; } - virtual PassOwnPtr<ContentData> cloneInternal() const { return create(quote()); } + virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override; + +private: + virtual std::unique_ptr<ContentData> cloneInternal() const override { 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) @@ -195,4 +241,14 @@ inline bool operator!=(const ContentData& a, const ContentData& b) } // namespace WebCore +#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) + #endif // ContentData_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..d5de076cf 100644 --- a/Source/WebCore/rendering/style/CounterDirectives.h +++ b/Source/WebCore/rendering/style/CounterDirectives.h @@ -25,6 +25,7 @@ #ifndef CounterDirectives_h #define CounterDirectives_h +#include <memory> #include <wtf/HashMap.h> #include <wtf/MathExtras.h> #include <wtf/RefPtr.h> @@ -104,7 +105,7 @@ 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 diff --git a/Source/WebCore/rendering/style/CursorList.h b/Source/WebCore/rendering/style/CursorList.h index a1d1fe797..4b3e3d358 100644 --- a/Source/WebCore/rendering/style/CursorList.h +++ b/Source/WebCore/rendering/style/CursorList.h @@ -33,9 +33,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]; } diff --git a/Source/WebCore/rendering/style/DataRef.h b/Source/WebCore/rendering/style/DataRef.h index c8d8072cb..0afb6ecd9 100644 --- a/Source/WebCore/rendering/style/DataRef.h +++ b/Source/WebCore/rendering/style/DataRef.h @@ -24,13 +24,17 @@ #ifndef DataRef_h #define DataRef_h -#include <wtf/RefPtr.h> +#include <wtf/Ref.h> namespace WebCore { template <typename T> class DataRef { public: - const T* get() const { return m_data.get(); } + DataRef(Ref<T>&& data) : m_data(WTFMove(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; } + + const T* get() const { return m_data.ptr(); } const T& operator*() const { return *get(); } const T* operator->() const { return get(); } @@ -39,31 +43,21 @@ public: { if (!m_data->hasOneRef()) m_data = m_data->copy(); - return m_data.get(); - } - - void init() - { - ASSERT(!m_data); - m_data = T::create(); + return m_data.ptr(); } bool operator==(const DataRef<T>& o) const { - ASSERT(m_data); - ASSERT(o.m_data); - return m_data == o.m_data || *m_data == *o.m_data; + return m_data.ptr() == o.m_data.ptr() || m_data.get() == o.m_data.get(); } bool operator!=(const DataRef<T>& o) const { - ASSERT(m_data); - ASSERT(o.m_data); - return m_data != o.m_data && *m_data != *o.m_data; + return m_data.ptr() != o.m_data.ptr() && m_data.get() != o.m_data.get(); } private: - RefPtr<T> m_data; + Ref<T> m_data; }; } // namespace WebCore diff --git a/Source/WebCore/rendering/style/FillLayer.cpp b/Source/WebCore/rendering/style/FillLayer.cpp index b11e24ccd..a0f0abee4 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,38 +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::initialFillMaskSourceType(type)) , m_imageSet(false) , m_attachmentSet(false) , m_clipSet(false) @@ -63,16 +65,17 @@ FillLayer::FillLayer(EFillLayerType type) , m_xPosSet(false) , m_yPosSet(false) , m_backgroundOriginSet(false) - , m_backgroundXOrigin(LeftEdge) - , m_backgroundYOrigin(TopEdge) + , m_backgroundXOrigin(static_cast<unsigned>(Edge::Left)) + , m_backgroundYOrigin(static_cast<unsigned>(Edge::Top)) , m_compositeSet(type == MaskFillLayer) , m_blendModeSet(false) + , m_maskSourceTypeSet(false) , m_type(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) @@ -85,6 +88,7 @@ FillLayer::FillLayer(const FillLayer& o) , m_composite(o.m_composite) , m_sizeType(o.m_sizeType) , m_blendMode(o.m_blendMode) + , m_maskSourceType(o.m_maskSourceType) , m_imageSet(o.m_imageSet) , m_attachmentSet(o.m_attachmentSet) , m_clipSet(o.m_clipSet) @@ -98,21 +102,20 @@ FillLayer::FillLayer(const FillLayer& o) , m_backgroundYOrigin(o.m_backgroundYOrigin) , m_compositeSet(o.m_compositeSet) , m_blendModeSet(o.m_blendModeSet) + , m_maskSourceTypeSet(o.m_maskSourceTypeSet) , m_type(o.m_type) { } 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; @@ -129,6 +132,7 @@ FillLayer& FillLayer::operator=(const FillLayer& o) m_repeatX = o.m_repeatX; m_repeatY = o.m_repeatY; m_sizeType = o.m_sizeType; + m_maskSourceType = o.m_maskSourceType; m_imageSet = o.m_imageSet; m_attachmentSet = o.m_attachmentSet; @@ -140,7 +144,8 @@ FillLayer& FillLayer::operator=(const FillLayer& o) m_repeatYSet = o.m_repeatYSet; m_xPosSet = o.m_xPosSet; m_yPosSet = o.m_yPosSet; - + m_maskSourceTypeSet = o.m_maskSourceTypeSet; + m_type = o.m_type; return *this; @@ -149,13 +154,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_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() @@ -283,18 +289,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; @@ -307,11 +310,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 @@ -321,29 +328,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 RenderObject* renderer) const +bool FillLayer::hasOpaqueImage(const RenderElement& renderer) const { if (!m_image) return false; @@ -351,18 +354,83 @@ bool FillLayer::hasOpaqueImage(const RenderObject* 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; +} + +static inline bool layerImagesIdentical(const FillLayer& layer1, const FillLayer& layer2) +{ + // We just care about pointer equivalency. + return layer1.image() == layer2.image(); +} + +bool FillLayer::imagesIdentical(const FillLayer* layer1, const FillLayer* layer2) +{ + for (; layer1 && layer2; layer1 = layer1->next(), layer2 = layer2->next()) { + if (!layerImagesIdentical(*layer1, *layer2)) + 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 040a3f125..2358b4db2 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 @@ -26,7 +26,6 @@ #define FillLayer_h #include "GraphicsTypes.h" -#include "Length.h" #include "LengthSize.h" #include "RenderStyleConstants.h" #include "StyleImage.h" @@ -34,42 +33,45 @@ namespace WebCore { +class RenderElement; + struct FillSize { FillSize() : type(SizeLength) { } - FillSize(EFillSizeType t, LengthSize l) - : type(t) - , size(l) - { - } - - bool operator==(const FillSize& o) const + FillSize(EFillSizeType type, const LengthSize& size) + : type(type) + , size(size) { - 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(); } - Length xPosition() const { return m_xPosition; } - Length yPosition() const { return m_yPosition; } - BackgroundEdgeOrigin backgroundXOrigin() const { return static_cast<BackgroundEdgeOrigin>(m_backgroundXOrigin); } - BackgroundEdgeOrigin backgroundYOrigin() const { return static_cast<BackgroundEdgeOrigin>(m_backgroundYOrigin); } + const Length& xPosition() const { return m_xPosition; } + const Length& yPosition() const { return m_yPosition; } + 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); } @@ -77,12 +79,13 @@ public: EFillRepeat repeatY() const { return static_cast<EFillRepeat>(m_repeatY); } CompositeOperator composite() const { return static_cast<CompositeOperator>(m_composite); } BlendMode blendMode() const { return static_cast<BlendMode>(m_blendMode); } - LengthSize sizeLength() const { return m_sizeLength; } + const LengthSize& sizeLength() const { return m_sizeLength; } EFillSizeType sizeType() const { return static_cast<EFillSizeType>(m_sizeType); } 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; } @@ -96,12 +99,13 @@ public: bool isCompositeSet() const { return m_compositeSet; } bool isBlendModeSet() const { return m_blendModeSet; } bool isSizeSet() const { return m_sizeType != SizeNone; } - - void setImage(PassRefPtr<StyleImage> i) { m_image = i; m_imageSet = true; } - void setXPosition(Length l) { m_xPosition = l; m_xPosSet = true; } - void setYPosition(Length l) { m_yPosition = l; m_yPosSet = true; } - void setBackgroundXOrigin(BackgroundEdgeOrigin o) { m_backgroundXOrigin = o; m_backgroundOriginSet = true; } - void setBackgroundYOrigin(BackgroundEdgeOrigin o) { m_backgroundYOrigin = o; m_backgroundOriginSet = true; } + bool isMaskSourceTypeSet() const { return m_maskSourceTypeSet; } + + void setImage(PassRefPtr<StyleImage> image) { m_image = 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_backgroundOriginSet = true; } + void setBackgroundYOrigin(Edge o) { m_backgroundYOrigin = static_cast<unsigned>(o); m_backgroundOriginSet = 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; } @@ -112,18 +116,12 @@ public: void setSizeType(EFillSizeType b) { m_sizeType = b; } void setSizeLength(LengthSize l) { m_sizeLength = l; } void setSize(FillSize f) { m_sizeType = f.type; m_sizeLength = f.size; } - - 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 setMaskSourceType(EMaskSourceType m) { m_maskSourceType = m; m_maskSourceTypeSet = true; } + + void clearImage() { m_image = nullptr; m_imageSet = false; } + + void clearXPosition() { m_xPosSet = false; m_backgroundOriginSet = false; } + void clearYPosition() { m_yPosSet = false; m_backgroundOriginSet = false; } void clearAttachment() { m_attachmentSet = false; } void clearClip() { m_clipSet = false; } @@ -133,36 +131,21 @@ public: void clearComposite() { m_compositeSet = false; } void clearBlendMode() { m_blendModeSet = false; } 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 RenderObject*) const; + bool hasImage() const; + bool hasFixedImage() const; + bool hasOpaqueImage(const RenderElement&) const; bool hasRepeatXY() const; bool clipOccludesNextLayers(bool firstLayer) const; @@ -171,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; } @@ -178,21 +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 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; @@ -209,7 +191,8 @@ private: unsigned m_composite : 4; // CompositeOperator unsigned m_sizeType : 2; // EFillSizeType unsigned m_blendMode : 5; // BlendMode - + unsigned m_maskSourceType : 1; // EMaskSourceType + unsigned m_imageSet : 1; unsigned m_attachmentSet : 1; unsigned m_clipSet : 1; @@ -219,16 +202,20 @@ private: unsigned m_xPosSet : 1; unsigned m_yPosSet : 1; unsigned m_backgroundOriginSet : 1; - unsigned m_backgroundXOrigin : 2; // BackgroundEdgeOrigin - unsigned m_backgroundYOrigin : 2; // BackgroundEdgeOrigin + unsigned m_backgroundXOrigin : 2; // Edge + unsigned m_backgroundYOrigin : 2; // Edge unsigned m_compositeSet : 1; unsigned m_blendModeSet : 1; - + unsigned m_maskSourceTypeSet : 1; + unsigned m_type : 1; // EFillLayerType mutable unsigned m_clipMax : 2; // EFillBox, maximum m_clip value from this to bottom layer }; +TextStream& operator<<(TextStream&, FillSize); +TextStream& operator<<(TextStream&, const FillLayer&); + } // namespace WebCore #endif // FillLayer_h diff --git a/Source/WebCore/rendering/style/GridCoordinate.h b/Source/WebCore/rendering/style/GridCoordinate.h new file mode 100644 index 000000000..21e040dc2 --- /dev/null +++ b/Source/WebCore/rendering/style/GridCoordinate.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2013 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 + * 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 + +#if ENABLE(CSS_GRID_LAYOUT) + +#include "GridResolvedPosition.h" +#include <wtf/HashMap.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +// Recommended maximum size for both explicit and implicit grids. +const unsigned kGridMaxTracks = 1000000; + +// A span in a single direction (either rows or columns). Note that |resolvedInitialPosition| +// and |resolvedFinalPosition| are grid lines' indexes. +// Iterating over the span shouldn't include |resolvedFinalPosition| to be correct. +class GridSpan { +public: + + static GridSpan definiteGridSpan(const GridResolvedPosition& resolvedInitialPosition, const GridResolvedPosition& resolvedFinalPosition) + { + return GridSpan(resolvedInitialPosition, resolvedFinalPosition, Definite); + } + + static GridSpan indefiniteGridSpan() + { + return GridSpan(0, 1, Indefinite); + } + + bool operator==(const GridSpan& o) const + { + return m_type == o.m_type && m_resolvedInitialPosition == o.m_resolvedInitialPosition && m_resolvedFinalPosition == o.m_resolvedFinalPosition; + } + + unsigned integerSpan() const + { + ASSERT(isDefinite()); + return m_resolvedFinalPosition.toInt() - m_resolvedInitialPosition.toInt(); + } + + const GridResolvedPosition& resolvedInitialPosition() const + { + ASSERT(isDefinite()); + return m_resolvedInitialPosition; + } + + const GridResolvedPosition& resolvedFinalPosition() const + { + ASSERT(isDefinite()); + return m_resolvedFinalPosition; + } + + typedef GridResolvedPosition iterator; + + iterator begin() const + { + ASSERT(isDefinite()); + return m_resolvedInitialPosition; + } + + iterator end() const + { + ASSERT(isDefinite()); + return m_resolvedFinalPosition; + } + + bool isDefinite() const + { + return m_type == Definite; + } + +private: + + enum GridSpanType {Definite, Indefinite}; + + GridSpan(const GridResolvedPosition& resolvedInitialPosition, const GridResolvedPosition& resolvedFinalPosition, GridSpanType type) + : m_resolvedInitialPosition(std::min(resolvedInitialPosition.toInt(), kGridMaxTracks - 1)) + , m_resolvedFinalPosition(std::min(resolvedFinalPosition.toInt(), kGridMaxTracks)) + , m_type(type) + { + ASSERT(resolvedInitialPosition < resolvedFinalPosition); + } + + GridResolvedPosition m_resolvedInitialPosition; + GridResolvedPosition m_resolvedFinalPosition; + GridSpanType m_type; + + +}; + +// This represents a grid area that spans in both rows' and columns' direction. +class GridCoordinate { +public: + // HashMap requires a default constuctor. + GridCoordinate() + : columns(GridSpan::indefiniteGridSpan()) + , rows(GridSpan::indefiniteGridSpan()) + { + } + + 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 /* ENABLE(CSS_GRID_LAYOUT) */ + +#endif // GridCoordinate_h diff --git a/Source/WebCore/rendering/style/GridLength.h b/Source/WebCore/rendering/style/GridLength.h new file mode 100644 index 000000000..2747007bb --- /dev/null +++ b/Source/WebCore/rendering/style/GridLength.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2013 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 + * 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 GridLength_h +#define GridLength_h + +#if ENABLE(CSS_GRID_LAYOUT) + +#include "Length.h" + +namespace WebCore { + +// This class wraps the <track-breadth> which can be either a <percentage>, <length>, min-content, max-content +// or <flex>. This class avoids spreading the knowledge of <flex> throughout the rendering directory by adding +// an new unit to Length.h. +class GridLength { +public: + GridLength(const Length& length) + : m_length(length) + , m_flex(0) + , m_type(LengthType) + { + ASSERT(!length.isUndefined()); + } + + explicit GridLength(double flex) + : m_flex(flex) + , m_type(FlexType) + { + } + + bool isLength() const { return m_type == LengthType; } + bool isFlex() const { return m_type == FlexType; } + + const Length& length() const { ASSERT(isLength()); return m_length; } + + double flex() const { ASSERT(isFlex()); return m_flex; } + + bool isPercentage() const { return m_type == LengthType && m_length.isPercentOrCalculated(); } + + bool operator==(const GridLength& o) const + { + return m_type == o.m_type && m_flex == o.m_flex && m_length == o.m_length; + } + + bool isContentSized() const { return m_type == LengthType && (m_length.isAuto() || m_length.isMinContent() || m_length.isMaxContent()); } + +private: + // Ideally we would put the 2 following fields in a union, but Length has a constructor, + // a destructor and a copy assignment which isn't allowed. + Length m_length; + double m_flex; + enum GridLengthType { + LengthType, + FlexType + }; + GridLengthType m_type; +}; + +} // namespace WebCore + +#endif /* ENABLE(CSS_GRID_LAYOUT) */ + +#endif // GridLength_h diff --git a/Source/WebCore/rendering/style/GridPosition.h b/Source/WebCore/rendering/style/GridPosition.h index 3f8fe974d..074ae68e2 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 @@ -31,11 +32,24 @@ #ifndef GridPosition_h #define GridPosition_h +#if ENABLE(CSS_GRID_LAYOUT) + +#include <wtf/text/WTFString.h> + namespace WebCore { enum GridPositionType { AutoPosition, - IntegerPosition + ExplicitPosition, // [ <integer> || <string> ] + SpanPosition, // span && [ <integer> || <string> ] + NamedGridAreaPosition // <ident> +}; + +enum GridPositionSide { + ColumnStartSide, + ColumnEndSide, + RowStartSide, + RowEndSide }; class GridPosition { @@ -50,30 +64,73 @@ public: GridPositionType type() const { return m_type; } bool isAuto() const { return m_type == AutoPosition; } + bool isSpan() const { return m_type == SpanPosition; } + bool isNamedGridArea() const { return m_type == NamedGridAreaPosition; } + + void setExplicitPosition(int position, const String& namedGridLine) + { + m_type = ExplicitPosition; + m_integerPosition = position; + m_namedGridLine = namedGridLine; + } + + void setAutoPosition() + { + m_type = AutoPosition; + m_integerPosition = 0; + } - void setIntegerPosition(int position) + // '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 = IntegerPosition; + m_type = SpanPosition; m_integerPosition = position; + m_namedGridLine = namedGridLine; + } + + void setNamedGridArea(const String& namedGridArea) + { + m_type = NamedGridAreaPosition; + m_namedGridLine = namedGridArea; } int integerPosition() const { - ASSERT(type() == IntegerPosition); + ASSERT(type() == ExplicitPosition); + return m_integerPosition; + } + + String namedGridLine() const + { + ASSERT(type() == ExplicitPosition || type() == SpanPosition || type() == NamedGridAreaPosition); + return m_namedGridLine; + } + + int spanPosition() const + { + ASSERT(type() == SpanPosition); return m_integerPosition; } 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: GridPositionType m_type; - // FIXME: This should probably be a size_t but the spec currently allows any <integer>. int m_integerPosition; + String m_namedGridLine; }; } // namespace WebCore +#endif /* ENABLE(CSS_GRID_LAYOUT) */ + #endif // GridPosition_h diff --git a/Source/WebCore/rendering/style/GridResolvedPosition.cpp b/Source/WebCore/rendering/style/GridResolvedPosition.cpp new file mode 100644 index 000000000..7c2101c83 --- /dev/null +++ b/Source/WebCore/rendering/style/GridResolvedPosition.cpp @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2014 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 "GridResolvedPosition.h" + +#if ENABLE(CSS_GRID_LAYOUT) + +#include "GridCoordinate.h" +#include "RenderBox.h" + +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 const NamedGridLinesMap& gridLinesForSide(const RenderStyle& style, GridPositionSide side) +{ + return isColumnSide(side) ? style.namedGridColumnLines() : style.namedGridRowLines(); +} + +static const String implicitNamedGridLineForSide(const String& lineName, GridPositionSide side) +{ + return lineName + (isStartSide(side) ? "-start" : "-end"); +} + +bool GridResolvedPosition::isNonExistentNamedLineOrArea(const String& lineName, const RenderStyle& style, GridPositionSide side) +{ + const NamedGridLinesMap& gridLineNames = gridLinesForSide(style, side); + return !gridLineNames.contains(implicitNamedGridLineForSide(lineName, side)) && !gridLineNames.contains(lineName); +} + +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(); + + // Try to early detect the case of non existing named grid lines. This way we could assume later that + // GridResolvedPosition::resolveGrisPositionFromStyle() won't require the autoplacement to run, i.e., it'll always return a + // valid resolved position. + if (initialPosition.isNamedGridArea() && GridResolvedPosition::isNonExistentNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide(direction))) + initialPosition.setAutoPosition(); + + if (finalPosition.isNamedGridArea() && GridResolvedPosition::isNonExistentNamedLineOrArea(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 GridResolvedPosition::explicitGridColumnCount(const RenderStyle& gridContainerStyle) +{ + return std::min<unsigned>(gridContainerStyle.gridColumns().size(), kGridMaxTracks); +} + +unsigned GridResolvedPosition::explicitGridRowCount(const RenderStyle& gridContainerStyle) +{ + return std::min<unsigned>(gridContainerStyle.gridRows().size(), kGridMaxTracks); +} + +static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side) +{ + return isColumnSide(side) ? GridResolvedPosition::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyle); +} + +static GridResolvedPosition resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side) +{ + ASSERT(!position.namedGridLine().isNull()); + + const NamedGridLinesMap& gridLinesNames = isColumnSide(side) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines(); + NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine()); + if (it == gridLinesNames.end()) { + if (position.isPositive()) + return 0; + const unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side); + return lastLine; + } + + unsigned namedGridLineIndex; + if (position.isPositive()) + namedGridLineIndex = std::min<unsigned>(position.integerPosition(), it->value.size()) - 1; + else + namedGridLineIndex = std::max<int>(0, it->value.size() - abs(position.integerPosition())); + return it->value[namedGridLineIndex]; +} + +static GridSpan resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<unsigned>& gridLines) +{ + if (!resolvedOppositePosition.toInt()) + return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedOppositePosition.next()); + + unsigned firstLineBeforePositionIndex = 0; + auto firstLineBeforePosition = std::lower_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition.toInt()); + if (firstLineBeforePosition != gridLines.end()) + firstLineBeforePositionIndex = firstLineBeforePosition - gridLines.begin(); + + unsigned gridLineIndex = std::max<int>(0, firstLineBeforePositionIndex - position.spanPosition()); + + GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition(gridLines[gridLineIndex]); + if (resolvedGridLinePosition >= resolvedOppositePosition) + resolvedGridLinePosition = resolvedOppositePosition.prev(); + return GridSpan::definiteGridSpan(std::min<GridResolvedPosition>(resolvedGridLinePosition, resolvedOppositePosition), resolvedOppositePosition); +} + +static GridSpan resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<unsigned>& gridLines) +{ + ASSERT(gridLines.size()); + unsigned firstLineAfterOppositePositionIndex = gridLines.size() - 1; + const unsigned* firstLineAfterOppositePosition = std::upper_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition); + if (firstLineAfterOppositePosition != gridLines.end()) + firstLineAfterOppositePositionIndex = firstLineAfterOppositePosition - gridLines.begin(); + + unsigned gridLineIndex = std::min<unsigned>(gridLines.size() - 1, firstLineAfterOppositePositionIndex + position.spanPosition() - 1); + GridResolvedPosition resolvedGridLinePosition = gridLines[gridLineIndex]; + if (resolvedGridLinePosition <= resolvedOppositePosition) + resolvedGridLinePosition = resolvedOppositePosition.next(); + return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedGridLinePosition); +} + +static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) +{ + 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); + + const NamedGridLinesMap& gridLinesNames = isColumnSide(side) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines(); + NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine()); + + // If there is no named grid line of that name, we resolve the position to 'auto' (which is equivalent to 'span 1' in this case). + // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html. + if (it == gridLinesNames.end()) { + if (isStartSide(side) && resolvedOppositePosition.toInt()) + return GridSpan::definiteGridSpan(resolvedOppositePosition.prev(), resolvedOppositePosition); + return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedOppositePosition.next()); + } + + if (side == RowStartSide || side == ColumnStartSide) + return resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value); + + return resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value); +} + +static GridSpan resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) +{ + if (position.isAuto()) { + if (isStartSide(side) && resolvedOppositePosition.toInt()) + return GridSpan::definiteGridSpan(resolvedOppositePosition.prev(), resolvedOppositePosition); + return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedOppositePosition.next()); + } + + 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, resolvedOppositePosition, position, side); + } + + // '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)) { + if (!resolvedOppositePosition.toInt()) + return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedOppositePosition.next()); + + unsigned initialResolvedPosition = std::max<int>(0, resolvedOppositePosition.toInt() - positionOffset); + return GridSpan::definiteGridSpan(initialResolvedPosition, resolvedOppositePosition); + } + + return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedOppositePosition.toInt() + positionOffset); +} + +GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, const GridResolvedPosition& resolvedInitialPosition) +{ + GridPosition initialPosition, finalPosition; + adjustGridPositionsFromStyle(gridContainerStyle, gridItem, direction, initialPosition, finalPosition); + + GridPositionSide finalSide = finalPositionSide(direction); + // This method will only be used when both positions need to be resolved against the opposite one. + ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()); + + GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition.next(); + + if (initialPosition.isSpan()) + return resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, initialPosition, finalSide); + if (finalPosition.isSpan()) + return resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, finalPosition, finalSide); + + return GridSpan::definiteGridSpan(resolvedInitialPosition, resolvedFinalPosition); +} + +static GridResolvedPosition resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side) +{ + switch (position.type()) { + case ExplicitPosition: { + ASSERT(position.integerPosition()); + + if (!position.namedGridLine().isNull()) + return resolveNamedGridLinePositionFromStyle(gridContainerStyle, position, side); + + // Handle <integer> explicit position. + if (position.isPositive()) + return position.integerPosition() - 1; + + unsigned resolvedPosition = abs(position.integerPosition()) - 1; + const unsigned endOfTrack = explicitGridSizeForSide(gridContainerStyle, side); + + // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line. + if (endOfTrack < resolvedPosition) + return 0; + + 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(!GridResolvedPosition::isNonExistentNamedLineOrArea(namedGridLine, gridContainerStyle, side)); + + const NamedGridLinesMap& gridLineNames = gridLinesForSide(gridContainerStyle, side); + auto implicitLine = gridLineNames.find(implicitNamedGridLineForSide(namedGridLine, side)); + if (implicitLine != gridLineNames.end()) + return implicitLine->value[0]; + + // Otherwise, if there is a named line with the specified name, contributes the first such line to the grid + // item's placement. + auto explicitLine = gridLineNames.find(namedGridLine); + if (explicitLine != gridLineNames.end()) + return explicitLine->value[0]; + + // If none of the above works specs mandate us to treat it as auto BUT we should have detected it before calling + // this function in resolveGridPositionsFromStyle(). We should be covered anyway by the ASSERT at the beginning + // of this case block. + ASSERT_NOT_REACHED(); + return 0; + } + 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 GridResolvedPosition(0); + } + ASSERT_NOT_REACHED(); + return GridResolvedPosition(0); +} + +GridSpan GridResolvedPosition::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction) +{ + 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 finalResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide); + return resolveGridPositionAgainstOppositePosition(gridContainerStyle, finalResolvedPosition, initialPosition, initialSide); + } + + if (finalPosition.shouldBeResolvedAgainstOppositePosition()) { + // Infer our position from the initial position ('1 / auto' or '3 / span 2' case). + auto initialResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide); + return resolveGridPositionAgainstOppositePosition(gridContainerStyle, initialResolvedPosition, finalPosition, finalSide); + } + + GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide); + GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide); + + if (resolvedInitialPosition > resolvedFinalPosition) + std::swap(resolvedInitialPosition, resolvedFinalPosition); + else if (resolvedInitialPosition == resolvedFinalPosition) + resolvedFinalPosition = resolvedInitialPosition.next(); + + return GridSpan::definiteGridSpan(resolvedInitialPosition, std::max(resolvedInitialPosition, resolvedFinalPosition)); +} + +} // namespace WebCore + +#endif // ENABLE(CSS_GRID_LAYOUT) diff --git a/Source/WebCore/rendering/style/GridResolvedPosition.h b/Source/WebCore/rendering/style/GridResolvedPosition.h new file mode 100644 index 000000000..3d91eecb0 --- /dev/null +++ b/Source/WebCore/rendering/style/GridResolvedPosition.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2014 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 GridResolvedPosition_h +#define GridResolvedPosition_h + +#if ENABLE(CSS_GRID_LAYOUT) + +#include "GridPosition.h" + +namespace WebCore { + +class GridSpan; +class RenderBox; +class RenderStyle; + +enum GridTrackSizingDirection { + ForColumns, + ForRows +}; + +// This class represents a line index into one of the dimensions of the grid array. +// Wraps an unsigned integer just for the purpose of knowing what we manipulate in the grid code. +class GridResolvedPosition { +public: + GridResolvedPosition(unsigned position) + : m_integerPosition(position) + { + } + + GridResolvedPosition& operator*() + { + return *this; + } + + GridResolvedPosition& operator++() + { + m_integerPosition++; + return *this; + } + + bool operator==(const GridResolvedPosition& other) const + { + return m_integerPosition == other.m_integerPosition; + } + + bool operator!=(const GridResolvedPosition& other) const + { + return m_integerPosition != other.m_integerPosition; + } + + bool operator<(const GridResolvedPosition& other) const + { + return m_integerPosition < other.m_integerPosition; + } + + bool operator>(const GridResolvedPosition& other) const + { + return m_integerPosition > other.m_integerPosition; + } + + bool operator<=(const GridResolvedPosition& other) const + { + return m_integerPosition <= other.m_integerPosition; + } + + bool operator>=(const GridResolvedPosition& other) const + { + return m_integerPosition >= other.m_integerPosition; + } + + unsigned toInt() const + { + return m_integerPosition; + } + + GridResolvedPosition next() const + { + return GridResolvedPosition(m_integerPosition + 1); + } + + GridResolvedPosition prev() const + { + return m_integerPosition ? m_integerPosition - 1 : 0; + } + + static GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderStyle&, const RenderBox&, GridTrackSizingDirection, const GridResolvedPosition&); + static GridSpan resolveGridPositionsFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection); + static unsigned explicitGridColumnCount(const RenderStyle&); + static unsigned explicitGridRowCount(const RenderStyle&); + static bool isNonExistentNamedLineOrArea(const String& lineName, const RenderStyle&, GridPositionSide); + +private: + unsigned m_integerPosition; +}; + +} // namespace WebCore + +#endif // ENABLE(CSS_GRID_LAYOUT) + +#endif // GridResolvedPosition_h diff --git a/Source/WebCore/rendering/style/GridTrackSize.h b/Source/WebCore/rendering/style/GridTrackSize.h index 72f64a687..6063792ca 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 @@ -31,7 +32,10 @@ #ifndef GridTrackSize_h #define GridTrackSize_h -#include "Length.h" +#if ENABLE(CSS_GRID_LAYOUT) + +#include "GridLength.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -42,73 +46,82 @@ enum GridTrackSizeType { class GridTrackSize { public: - GridTrackSize(LengthType type = Undefined) + GridTrackSize(const GridLength& length) : m_type(LengthTrackSizing) - , m_minTrackBreadth(type) - , m_maxTrackBreadth(type) + , m_minTrackBreadth(length) + , m_maxTrackBreadth(length) { + cacheMinMaxTrackBreadthTypes(); } - const Length& length() const + GridTrackSize(const GridLength& minTrackBreadth, const GridLength& maxTrackBreadth) + : m_type(MinMaxTrackSizing) + , m_minTrackBreadth(minTrackBreadth) + , m_maxTrackBreadth(maxTrackBreadth) { - ASSERT(m_type == LengthTrackSizing); - ASSERT(!m_minTrackBreadth.isUndefined()); - ASSERT(m_minTrackBreadth == m_maxTrackBreadth); - return m_minTrackBreadth; + cacheMinMaxTrackBreadthTypes(); } - void setLength(const Length& length) + const GridLength& length() const { - m_type = LengthTrackSizing; - m_minTrackBreadth = length; - m_maxTrackBreadth = length; - } - - const Length& minTrackBreadth() const - { - ASSERT(!m_minTrackBreadth.isUndefined()); - if (m_minTrackBreadth.isAuto()) { - DEFINE_STATIC_LOCAL(Length, minContent, (MinContent)); - return minContent; - } - return m_minTrackBreadth; + ASSERT(m_type == LengthTrackSizing); + ASSERT(m_minTrackBreadth == m_maxTrackBreadth); + const GridLength& minTrackBreadth = m_minTrackBreadth; + return minTrackBreadth; } - const Length& maxTrackBreadth() const - { - ASSERT(!m_maxTrackBreadth.isUndefined()); - if (m_maxTrackBreadth.isAuto()) { - DEFINE_STATIC_LOCAL(Length, maxContent, (MaxContent)); - return maxContent; - } - return m_maxTrackBreadth; - } + const GridLength& minTrackBreadth() const { return m_minTrackBreadth; } - void setMinMax(const Length& minTrackBreadth, const Length& maxTrackBreadth) - { - m_type = MinMaxTrackSizing; - m_minTrackBreadth = minTrackBreadth; - m_maxTrackBreadth = maxTrackBreadth; - } + const GridLength& maxTrackBreadth() const { return m_maxTrackBreadth; } GridTrackSizeType type() const { return m_type; } + bool isContentSized() const { return m_minTrackBreadth.isContentSized() || m_maxTrackBreadth.isContentSized(); } + + bool isPercentage() const { return m_type == LengthTrackSizing && length().isLength() && length().length().isPercentOrCalculated(); } + bool operator==(const GridTrackSize& other) const { return m_type == other.m_type && m_minTrackBreadth == other.m_minTrackBreadth && m_maxTrackBreadth == other.m_maxTrackBreadth; } - bool hasMinOrMaxContentMinTrackBreadth() const { return minTrackBreadth().isMinContent() || minTrackBreadth().isMaxContent(); } - bool hasMaxContentMinTrackBreadth() const { return minTrackBreadth().isMaxContent(); } - bool hasMinOrMaxContentMaxTrackBreadth() const { return maxTrackBreadth().isMinContent() || maxTrackBreadth().isMaxContent(); } - bool hasMaxContentMaxTrackBreadth() const { return maxTrackBreadth().isMaxContent(); } + 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(); + } + + bool hasIntrinsicMinTrackBreadth() const { return m_minTrackBreadthIsMaxContent || m_minTrackBreadthIsMinContent || m_minTrackBreadthIsAuto; } + 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_maxTrackBreadthIsAuto || hasMinOrMaxContentMaxTrackBreadth()); } private: GridTrackSizeType m_type; - Length m_minTrackBreadth; - Length m_maxTrackBreadth; + GridLength m_minTrackBreadth; + GridLength m_maxTrackBreadth; + bool m_minTrackBreadthIsAuto; + bool m_minTrackBreadthIsMaxContent; + bool m_minTrackBreadthIsMinContent; + bool m_maxTrackBreadthIsAuto; + bool m_maxTrackBreadthIsMaxContent; + bool m_maxTrackBreadthIsMinContent; }; } // namespace WebCore +#endif /* ENABLE(CSS_GRID_LAYOUT) */ + #endif // GridTrackSize_h diff --git a/Source/WebCore/rendering/style/KeyframeList.cpp b/Source/WebCore/rendering/style/KeyframeList.cpp index a127b468b..545bca23a 100644 --- a/Source/WebCore/rendering/style/KeyframeList.cpp +++ b/Source/WebCore/rendering/style/KeyframeList.cpp @@ -21,10 +21,27 @@ #include "config.h" #include "KeyframeList.h" + +#include "Animation.h" #include "RenderObject.h" namespace WebCore { +TimingFunction* KeyframeValue::timingFunction(const AtomicString& name) const +{ + const RenderStyle* 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().get(); + } + + return nullptr; +} + KeyframeList::~KeyframeList() { clear(); diff --git a/Source/WebCore/rendering/style/KeyframeList.h b/Source/WebCore/rendering/style/KeyframeList.h index 6193fa67d..4df5f4db6 100644 --- a/Source/WebCore/rendering/style/KeyframeList.h +++ b/Source/WebCore/rendering/style/KeyframeList.h @@ -34,12 +34,12 @@ namespace WebCore { -class RenderObject; class RenderStyle; +class TimingFunction; class KeyframeValue { public: - KeyframeValue(float key, PassRefPtr<RenderStyle> style) + KeyframeValue(double key, PassRefPtr<RenderStyle> style) : m_key(key) , m_style(style) { @@ -49,21 +49,23 @@ public: bool containsProperty(CSSPropertyID prop) const { return m_properties.contains(prop); } const HashSet<CSSPropertyID>& properties() const { return m_properties; } - float key() const { return m_key; } - void setKey(float key) { m_key = key; } + double key() const { return m_key; } + void setKey(double key) { m_key = key; } const RenderStyle* style() const { return m_style.get(); } void setStyle(PassRefPtr<RenderStyle> style) { m_style = style; } + TimingFunction* timingFunction(const AtomicString& name) const; + private: - float m_key; + double m_key; HashSet<CSSPropertyID> m_properties; // The properties specified in this keyframe. RefPtr<RenderStyle> m_style; }; class KeyframeList { public: - KeyframeList(RenderObject*, const AtomicString& animationName) + explicit KeyframeList(const AtomicString& animationName) : m_animationName(animationName) { insert(KeyframeValue(0, 0)); @@ -80,13 +82,13 @@ public: 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; diff --git a/Source/WebCore/rendering/style/NinePieceImage.cpp b/Source/WebCore/rendering/style/NinePieceImage.cpp index a463d815b..b4c33f4f0 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, 2005, 2006, 2007, 2008, 2013, 2015 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,14 +24,18 @@ #include "config.h" #include "NinePieceImage.h" +#include "GraphicsContext.h" +#include "LengthFunctions.h" +#include "RenderStyle.h" +#include <wtf/NeverDestroyed.h> +#include <wtf/PointerComparison.h> + namespace WebCore { static DataRef<NinePieceImageData>& defaultData() { - static DataRef<NinePieceImageData>* data = new DataRef<NinePieceImageData>; - if (!data->get()) - data->init(); - return *data; + static NeverDestroyed<DataRef<NinePieceImageData>> data(NinePieceImageData::create()); + return data.get(); } NinePieceImage::NinePieceImage() @@ -40,29 +44,198 @@ NinePieceImage::NinePieceImage() } NinePieceImage::NinePieceImage(PassRefPtr<StyleImage> image, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule) + : m_data(NinePieceImageData::create()) { - m_data.init(); m_data.access()->image = image; - m_data.access()->imageSlices = imageSlices; - m_data.access()->borderSlices = borderSlices; - m_data.access()->outset = outset; + m_data.access()->imageSlices = WTFMove(imageSlices); + m_data.access()->borderSlices = WTFMove(borderSlices); + m_data.access()->outset = WTFMove(outset); m_data.access()->fill = fill; m_data.access()->horizontalRule = horizontalRule; m_data.access()->verticalRule = 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) +{ + LayoutUnit top = std::min<LayoutUnit>(size.height(), valueForLength(lengths.top(), size.height())) * scaleFactor; + LayoutUnit right = std::min<LayoutUnit>(size.width(), valueForLength(lengths.right(), size.width())) * scaleFactor; + LayoutUnit bottom = std::min<LayoutUnit>(size.height(), valueForLength(lengths.bottom(), size.height())) * scaleFactor; + LayoutUnit left = std::min<LayoutUnit>(size.width(), valueForLength(lengths.left(), size.width())) * scaleFactor; + return LayoutBoxExtent(top, right, bottom, left); +} + +LayoutBoxExtent NinePieceImage::computeSlices(const LayoutSize& size, const LengthBox& lengths, const FloatBoxExtent& widths, const LayoutBoxExtent& slices) +{ + LayoutUnit top = computeSlice(lengths.top(), widths.top(), slices.top(), size.height()); + LayoutUnit right = computeSlice(lengths.right(), widths.right(), slices.right(), size.width()); + LayoutUnit bottom = computeSlice(lengths.bottom(), widths.bottom(), slices.bottom(), size.height()); + LayoutUnit left = computeSlice(lengths.left(), widths.left(), slices.left(), size.width()); + return LayoutBoxExtent(top, right, bottom, left); +} + +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 && 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); + } +} + NinePieceImageData::NinePieceImageData() : fill(false) , horizontalRule(StretchImageRule) , verticalRule(StretchImageRule) - , image(0) + , image(nullptr) , 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) { } -NinePieceImageData::NinePieceImageData(const NinePieceImageData& other) +inline NinePieceImageData::NinePieceImageData(const NinePieceImageData& other) : RefCounted<NinePieceImageData>() , fill(other.fill) , horizontalRule(other.horizontalRule) @@ -74,9 +247,14 @@ NinePieceImageData::NinePieceImageData(const NinePieceImageData& other) { } +Ref<NinePieceImageData> NinePieceImageData::copy() const +{ + return adoptRef(*new NinePieceImageData(*this)); +} + bool NinePieceImageData::operator==(const NinePieceImageData& other) const { - return StyleImage::imagesEquivalent(image.get(), other.image.get()) + return arePointingToEqualData(image, other.image) && imageSlices == other.imageSlices && fill == other.fill && borderSlices == other.borderSlices diff --git a/Source/WebCore/rendering/style/NinePieceImage.h b/Source/WebCore/rendering/style/NinePieceImage.h index 0f3b339ea..414af9d87 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, 2005, 2006, 2007, 2008, 2013, 2015 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 @@ -25,9 +25,12 @@ #define NinePieceImage_h #include "DataRef.h" +#include "LayoutRect.h" +#include "LayoutSize.h" #include "LayoutUnit.h" #include "LengthBox.h" #include "StyleImage.h" +#include <wtf/Vector.h> namespace WebCore { @@ -35,10 +38,74 @@ enum ENinePieceImageRule { StretchImageRule, RoundImageRule, SpaceImageRule, RepeatImageRule }; +enum ImagePiece { + MinPiece = 0, + TopLeftPiece = MinPiece, + LeftPiece, + BottomLeftPiece, + TopRightPiece, + RightPiece, + BottomRightPiece, + TopPiece, + BottomPiece, + MiddlePiece, + MaxPiece +}; + +inline ImagePiece& operator++(ImagePiece& piece) +{ + piece = static_cast<ImagePiece>(static_cast<int>(piece) + 1); + return piece; +} + +inline bool isCornerPiece(ImagePiece piece) +{ + return piece == TopLeftPiece || piece == TopRightPiece || piece == BottomLeftPiece || piece == BottomRightPiece; +} + +inline bool isMiddlePiece(ImagePiece piece) +{ + return piece == MiddlePiece; +} + +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 RenderStyle; + class NinePieceImageData : public RefCounted<NinePieceImageData> { public: - static PassRefPtr<NinePieceImageData> create() { return adoptRef(new NinePieceImageData); } - PassRefPtr<NinePieceImageData> copy() const { return adoptRef(new NinePieceImageData(*this)); } + static Ref<NinePieceImageData> create() { return adoptRef(*new NinePieceImageData); } + Ref<NinePieceImageData> copy() const; bool operator==(const NinePieceImageData&) const; bool operator!=(const NinePieceImageData& o) const { return !(*this == o); } @@ -69,16 +136,16 @@ public: void setImage(PassRefPtr<StyleImage> image) { m_data.access()->image = image; } const LengthBox& imageSlices() const { return m_data->imageSlices; } - void setImageSlices(const LengthBox& slices) { m_data.access()->imageSlices = 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; } const LengthBox& borderSlices() const { return m_data->borderSlices; } - void setBorderSlices(const LengthBox& slices) { m_data.access()->borderSlices = slices; } + void setBorderSlices(LengthBox slices) { m_data.access()->borderSlices = WTFMove(slices); } const LengthBox& outset() const { return m_data->outset; } - void setOutset(const LengthBox& outset) { m_data.access()->outset = 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; } @@ -115,13 +182,30 @@ public: m_data.access()->borderSlices = LengthBox(); } - static LayoutUnit computeOutset(Length outsetSide, LayoutUnit borderSide) + static LayoutUnit computeOutset(const Length& outsetSide, LayoutUnit borderSide) { if (outsetSide.isRelative()) return outsetSide.value() * borderSide; 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; }; diff --git a/Source/WebCore/rendering/style/OutlineValue.h b/Source/WebCore/rendering/style/OutlineValue.h index f380af628..0afe5a812 100644 --- a/Source/WebCore/rendering/style/OutlineValue.h +++ b/Source/WebCore/rendering/style/OutlineValue.h @@ -32,11 +32,6 @@ 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; @@ -47,11 +42,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 diff --git a/Source/WebCore/rendering/style/QuotesData.cpp b/Source/WebCore/rendering/style/QuotesData.cpp index cab873956..43b0df24b 100644 --- a/Source/WebCore/rendering/style/QuotesData.cpp +++ b/Source/WebCore/rendering/style/QuotesData.cpp @@ -29,13 +29,13 @@ 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) +PassRefPtr<QuotesData> QuotesData::create(const Vector<std::pair<String, String>>& quotes) { void* slot = fastMalloc(sizeForQuotesDataWithQuoteCount(quotes.size())); return adoptRef(new (NotNull, slot) QuotesData(quotes)); } -QuotesData::QuotesData(const Vector<std::pair<String, String> >& quotes) +QuotesData::QuotesData(const Vector<std::pair<String, String>>& quotes) : m_quoteCount(quotes.size()) { for (unsigned i = 0; i < m_quoteCount; ++i) diff --git a/Source/WebCore/rendering/style/QuotesData.h b/Source/WebCore/rendering/style/QuotesData.h index df84d62ae..07e92530f 100644 --- a/Source/WebCore/rendering/style/QuotesData.h +++ b/Source/WebCore/rendering/style/QuotesData.h @@ -36,7 +36,7 @@ namespace WebCore { class QuotesData : public RefCounted<QuotesData> { public: - static PassRefPtr<QuotesData> create(const Vector<std::pair<String, String> >& quotes); + static PassRefPtr<QuotesData> create(const Vector<std::pair<String, String>>& quotes); ~QuotesData(); friend bool operator==(const QuotesData&, const QuotesData&); @@ -45,7 +45,7 @@ public: const String& closeQuote(unsigned index) const; private: - explicit QuotesData(const Vector<std::pair<String, String> >& quotes); + explicit QuotesData(const Vector<std::pair<String, String>>& quotes); unsigned m_quoteCount; std::pair<String, String> m_quotePairs[0]; diff --git a/Source/WebCore/rendering/style/RenderStyle.cpp b/Source/WebCore/rendering/style/RenderStyle.cpp index 2d0bb3b90..ebd4c9142 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-2015 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,37 +24,46 @@ #include "RenderStyle.h" #include "ContentData.h" -#include "CursorList.h" +#include "CSSCustomPropertyValue.h" #include "CSSPropertyNames.h" -#include "Font.h" +#include "CSSVariableDependentValue.h" +#include "CursorList.h" +#include "FloatRoundedRect.h" +#include "FontCascade.h" #include "FontSelector.h" +#include "InlineTextBoxStyle.h" #include "Pagination.h" #include "QuotesData.h" -#include "RenderArena.h" #include "RenderObject.h" +#include "RenderTheme.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" #endif -using namespace std; - namespace WebCore { struct SameSizeAsBorderValue { + float m_width; RGBA32 m_color; - unsigned m_width; + int m_restBits; }; COMPILE_ASSERT(sizeof(BorderValue) == sizeof(SameSizeAsBorderValue), BorderValue_should_not_grow); @@ -62,91 +71,92 @@ COMPILE_ASSERT(sizeof(BorderValue) == sizeof(SameSizeAsBorderValue), BorderValue struct SameSizeAsRenderStyle : public RefCounted<SameSizeAsRenderStyle> { void* dataRefs[7]; void* ownPtrs[1]; -#if ENABLE(SVG) void* dataRefSvgStyle; -#endif struct InheritedFlags { unsigned m_bitfields[2]; } inherited_flags; struct NonInheritedFlags { - unsigned m_bitfields[2]; + uint64_t m_flags; } noninherited_flags; }; COMPILE_ASSERT(sizeof(RenderStyle) == sizeof(SameSizeAsRenderStyle), RenderStyle_should_stay_small); -inline RenderStyle* defaultStyle() +inline RenderStyle& defaultStyle() { - static RenderStyle* s_defaultStyle = RenderStyle::createDefaultStyle().leakRef(); - return s_defaultStyle; + static RenderStyle& style = RenderStyle::createDefaultStyle().leakRef(); + return style; } -PassRefPtr<RenderStyle> RenderStyle::create() +Ref<RenderStyle> RenderStyle::create() { - return adoptRef(new RenderStyle()); + return adoptRef(*new RenderStyle(defaultStyle())); } -PassRefPtr<RenderStyle> RenderStyle::createDefaultStyle() +Ref<RenderStyle> RenderStyle::createDefaultStyle() { - return adoptRef(new RenderStyle(true)); + return adoptRef(*new RenderStyle(true)); } -PassRefPtr<RenderStyle> RenderStyle::createAnonymousStyleWithDisplay(const RenderStyle* parentStyle, EDisplay display) +Ref<RenderStyle> RenderStyle::createAnonymousStyleWithDisplay(const RenderStyle* parentStyle, EDisplay display) { - RefPtr<RenderStyle> newStyle = RenderStyle::create(); - newStyle->inheritFrom(parentStyle); - newStyle->inheritUnicodeBidiFrom(parentStyle); - newStyle->setDisplay(display); + auto newStyle = RenderStyle::create(); + newStyle.get().inheritFrom(parentStyle); + newStyle.get().inheritUnicodeBidiFrom(parentStyle); + newStyle.get().setDisplay(display); return newStyle; } -PassRefPtr<RenderStyle> RenderStyle::clone(const RenderStyle* other) +Ref<RenderStyle> RenderStyle::clone(const RenderStyle* other) { - return adoptRef(new RenderStyle(*other)); + return adoptRef(*new RenderStyle(*other)); } -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) -#endif +Ref<RenderStyle> RenderStyle::createStyleInheritingFromPseudoStyle(const RenderStyle& pseudoStyle) { - 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); + ASSERT(pseudoStyle.styleType() == BEFORE || pseudoStyle.styleType() == AFTER); + + auto style = RenderStyle::create(); + style.get().inheritFrom(&pseudoStyle); + return style; } ALWAYS_INLINE RenderStyle::RenderStyle(bool) -{ - setBitDefaults(); - - m_box.init(); - visual.init(); - m_background.init(); - surround.init(); - rareNonInheritedData.init(); - rareNonInheritedData.access()->m_deprecatedFlexibleBox.init(); - rareNonInheritedData.access()->m_flexibleBox.init(); - rareNonInheritedData.access()->m_marquee.init(); - rareNonInheritedData.access()->m_multiCol.init(); - rareNonInheritedData.access()->m_transform.init(); -#if ENABLE(CSS_FILTERS) - rareNonInheritedData.access()->m_filter.init(); -#endif - rareNonInheritedData.access()->m_grid.init(); - rareNonInheritedData.access()->m_gridItem.init(); - rareInheritedData.init(); - inherited.init(); -#if ENABLE(SVG) - m_svgStyle.init(); + : m_box(StyleBoxData::create()) + , visual(StyleVisualData::create()) + , m_background(StyleBackgroundData::create()) + , surround(StyleSurroundData::create()) + , rareNonInheritedData(StyleRareNonInheritedData::create()) + , rareInheritedData(StyleRareInheritedData::create()) + , inherited(StyleInheritedData::create()) + , m_svgStyle(SVGRenderStyle::create()) +{ + 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(); #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._insideDefaultButton = false; + inherited_flags.m_writingMode = initialWritingMode(); + + static_assert((sizeof(InheritedFlags) <= 8), "InheritedFlags does not grow"); + static_assert((sizeof(NonInheritedFlags) <= 8), "NonInheritedFlags does not grow"); } ALWAYS_INLINE RenderStyle::RenderStyle(const RenderStyle& o) @@ -158,14 +168,80 @@ ALWAYS_INLINE RenderStyle::RenderStyle(const RenderStyle& o) , 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 inline StyleSelfAlignmentData resolveAlignmentData(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForRenderer) +{ + // The auto keyword computes to the parent's align-items computed value, or to "stretch", if not set or "auto". + if (childStyle.alignSelfPosition() == ItemPositionAuto) + return (parentStyle.alignItemsPosition() == ItemPositionAuto) ? StyleSelfAlignmentData(resolvedAutoPositionForRenderer, OverflowAlignmentDefault) : parentStyle.alignItems(); + return childStyle.alignSelf(); +} + +static inline StyleSelfAlignmentData resolveJustificationData(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForRenderer) +{ + // The auto keyword computes to the parent's justify-items computed value, or to "stretch", if not set or "auto". + if (childStyle.justifySelfPosition() == ItemPositionAuto) + return (parentStyle.justifyItemsPosition() == ItemPositionAuto) ? StyleSelfAlignmentData(resolvedAutoPositionForRenderer, OverflowAlignmentDefault) : parentStyle.justifyItems(); + return childStyle.justifySelf(); +} + +ItemPosition RenderStyle::resolveAlignment(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForRenderer) +{ + return resolveAlignmentData(parentStyle, childStyle, resolvedAutoPositionForRenderer).position(); +} + +OverflowAlignment RenderStyle::resolveAlignmentOverflow(const RenderStyle& parentStyle, const RenderStyle& childStyle) +{ + return resolveAlignmentData(parentStyle, childStyle, ItemPositionStretch).overflow(); +} + +ItemPosition RenderStyle::resolveJustification(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForRenderer) +{ + return resolveJustificationData(parentStyle, childStyle, resolvedAutoPositionForRenderer).position(); +} + +OverflowAlignment RenderStyle::resolveJustificationOverflow(const RenderStyle& parentStyle, const RenderStyle& childStyle) +{ + return resolveJustificationData(parentStyle, childStyle, ItemPositionStretch).overflow(); +} + +ContentPosition RenderStyle::resolvedAlignContentPosition() const +{ + const StyleContentAlignmentData& align = alignContent(); + if (align.position() != ContentPositionAuto || align.distribution() != ContentDistributionDefault) + return align.position(); + // 'auto' computes to 'stretch' for flexbox, hence it's managed by distribution(). + return isDisplayFlexibleBox() ? ContentPositionAuto : ContentPositionStart; +} + +ContentDistributionType RenderStyle::resolvedAlignContentDistribution() const +{ + const StyleContentAlignmentData& align = alignContent(); + if (align.position() != ContentPositionAuto || align.distribution() != ContentDistributionDefault) + return align.distribution(); + return isDisplayFlexibleBox() ? ContentDistributionStretch : ContentDistributionDefault; +} + +ContentPosition RenderStyle::resolvedJustifyContentPosition() const +{ + const StyleContentAlignmentData& justify = justifyContent(); + if (justify.position() != ContentPositionAuto || justify.distribution() != ContentDistributionDefault) + return justify.position(); + // 'auto' computes to 'stretch' for flexbox, but since flexing in the main axis is controlled by flex, it behaves as flex-start. + return isDisplayFlexibleBox() ? ContentPositionFlexStart : ContentPositionStart; +} + +ContentDistributionType RenderStyle::resolvedJustifyContentDistribution() const +{ + // even that 'auto' computes to 'stretch' for flexbox it behaves as flex-start, hence it's managed by position(). + return justifyContentDistribution(); +} + void RenderStyle::inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary isAtShadowBoundary) { if (isAtShadowBoundary == AtShadowBoundary) { @@ -177,10 +253,9 @@ void RenderStyle::inheritFrom(const RenderStyle* inheritParent, IsAtShadowBounda 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 } void RenderStyle::copyNonInheritedFrom(const RenderStyle* other) @@ -190,25 +265,11 @@ void RenderStyle::copyNonInheritedFrom(const RenderStyle* other) 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) + noninherited_flags.copyNonInheritedFrom(other->noninherited_flags); + if (m_svgStyle != other->m_svgStyle) m_svgStyle.access()->copyNonInheritedFrom(other->m_svgStyle.get()); -#endif + ASSERT(zoom() == initialZoom()); } @@ -224,39 +285,13 @@ bool RenderStyle::operator==(const RenderStyle& o) const && rareNonInheritedData == o.rareNonInheritedData && rareInheritedData == o.rareInheritedData && inherited == o.inherited -#if ENABLE(SVG) && m_svgStyle == o.m_svgStyle -#endif ; } bool RenderStyle::isStyleAvailable() const { - return this != StyleResolver::styleNotYetAvailable(); -} - -static inline int pseudoBit(PseudoId pseudo) -{ - return 1 << (pseudo - 1); -} - -bool RenderStyle::hasAnyPublicPseudoStyles() const -{ - return PUBLIC_PSEUDOID_MASK & noninherited_flags._pseudoBits; -} - -bool RenderStyle::hasPseudoStyle(PseudoId pseudo) const -{ - ASSERT(pseudo > NOPSEUDO); - ASSERT(pseudo < FIRST_INTERNAL_PSEUDOID); - return pseudoBit(pseudo) & noninherited_flags._pseudoBits; -} - -void RenderStyle::setHasPseudoStyle(PseudoId pseudo) -{ - ASSERT(pseudo > NOPSEUDO); - ASSERT(pseudo < FIRST_INTERNAL_PSEUDOID); - noninherited_flags._pseudoBits |= pseudoBit(pseudo); + return !Style::isPlaceholderStyle(*this); } bool RenderStyle::hasUniquePseudoStyle() const @@ -276,10 +311,10 @@ 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(); @@ -287,20 +322,20 @@ RenderStyle* RenderStyle::getCachedPseudoStyle(PseudoId pid) const return pseudoStyle; } - return 0; + return nullptr; } RenderStyle* RenderStyle::addCachedPseudoStyle(PassRefPtr<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); @@ -324,20 +359,73 @@ 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; } +#if ENABLE(IOS_TEXT_AUTOSIZING) + +static inline unsigned computeFontHash(const FontCascade& font) +{ + IntegerHasher hasher; + hasher.add(ASCIICaseInsensitiveHash::hash(font.fontDescription().firstFamily())); + hasher.add(font.fontDescription().specifiedSize()); + return hasher.hash(); +} + +unsigned RenderStyle::hashForTextAutosizing() const +{ + // FIXME: Not a very smart hash. Could be improved upon. See <https://bugs.webkit.org/show_bug.cgi?id=121131>. + unsigned 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->fontCascade); + 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; + 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->fontCascade.equalForTextAutoSizing(other->inherited->fontCascade) + && 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::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) && m_svgStyle.get() == other->m_svgStyle.get() -#endif && rareInheritedData.get() == other->rareInheritedData.get(); } @@ -368,233 +456,263 @@ 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 (rareNonInheritedData.get() != other.rareNonInheritedData.get() + && !arePointingToEqualData(rareNonInheritedData->m_boxShadow, other.rareNonInheritedData->m_boxShadow)) + return true; + + if (rareInheritedData.get() != other.rareInheritedData.get() + && !arePointingToEqualData(rareInheritedData->textShadow, other.rareInheritedData->textShadow)) + return true; + + if (inherited_flags._text_decorations != other.inherited_flags._text_decorations + || visual->textDecoration != other.visual->textDecoration + || rareNonInheritedData->m_textDecorationStyle != other.rareNonInheritedData->m_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 (m_box->verticalAlign() != other->m_box->verticalAlign() || noninherited_flags._vertical_align != other->noninherited_flags._vertical_align) +bool RenderStyle::changeRequiresLayout(const RenderStyle& other, unsigned& changedContextSensitiveProperties) 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()) return true; - if (m_box->boxSizing() != other->m_box->boxSizing()) + if (m_box->verticalAlign() != other.m_box->verticalAlign() || noninherited_flags.verticalAlign() != other.noninherited_flags.verticalAlign()) return true; - if (surround->margin != other->surround->margin) + if (m_box->boxSizing() != other.m_box->boxSizing()) return true; - if (surround->padding != other->surround->padding) + if (surround->margin != other.surround->margin) 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 (surround->padding != other.surround->padding) + return true; - if (rareNonInheritedData->m_regionFragment != other->rareNonInheritedData->m_regionFragment) - return true; + // FIXME: We should add an optimized form of layout that just recomputes visual overflow. + if (changeAffectsVisualOverflow(other)) + return true; - if (rareNonInheritedData->m_wrapFlow != other->rareNonInheritedData->m_wrapFlow - || rareNonInheritedData->m_wrapThrough != other->rareNonInheritedData->m_wrapThrough - || rareNonInheritedData->m_shapeMargin != other->rareNonInheritedData->m_shapeMargin - || rareNonInheritedData->m_shapePadding != other->rareNonInheritedData->m_shapePadding) + 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->m_initialLetter != other.rareNonInheritedData->m_initialLetter + || rareNonInheritedData->textOverflow != other.rareNonInheritedData->textOverflow) return true; - if (rareNonInheritedData->m_deprecatedFlexibleBox.get() != other->rareNonInheritedData->m_deprecatedFlexibleBox.get() - && *rareNonInheritedData->m_deprecatedFlexibleBox.get() != *other->rareNonInheritedData->m_deprecatedFlexibleBox.get()) + if (rareNonInheritedData->m_regionFragment != other.rareNonInheritedData->m_regionFragment) return true; - if (rareNonInheritedData->m_flexibleBox.get() != other->rareNonInheritedData->m_flexibleBox.get() - && *rareNonInheritedData->m_flexibleBox.get() != *other->rareNonInheritedData->m_flexibleBox.get()) - 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 ENABLE(CSS_SHAPES) + if (rareNonInheritedData->m_shapeMargin != other.rareNonInheritedData->m_shapeMargin) return true; +#endif - // FIXME: We should add an optimized form of layout that just recomputes visual overflow. - if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get())) + if (rareNonInheritedData->m_deprecatedFlexibleBox != other.rareNonInheritedData->m_deprecatedFlexibleBox) return true; - if (!rareNonInheritedData->reflectionDataEquivalent(*other->rareNonInheritedData.get())) + if (rareNonInheritedData->m_flexibleBox != other.rareNonInheritedData->m_flexibleBox) return true; - if (rareNonInheritedData->m_multiCol.get() != other->rareNonInheritedData->m_multiCol.get() - && *rareNonInheritedData->m_multiCol.get() != *other->rareNonInheritedData->m_multiCol.get()) + 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 + || rareNonInheritedData->m_justifyItems != other.rareNonInheritedData->m_justifyItems + || rareNonInheritedData->m_justifySelf != other.rareNonInheritedData->m_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 + if (!arePointingToEqualData(rareNonInheritedData->m_boxReflect, other.rareNonInheritedData->m_boxReflect)) return true; -#endif - } - if (rareNonInheritedData->m_grid.get() != other->rareNonInheritedData->m_grid.get() - || rareNonInheritedData->m_gridItem.get() != other->rareNonInheritedData->m_gridItem.get()) + if (rareNonInheritedData->m_multiCol != other.rareNonInheritedData->m_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 (rareNonInheritedData->m_transform != other.rareNonInheritedData->m_transform) { + if (rareNonInheritedData->m_transform->hasTransform() != other.rareNonInheritedData->m_transform->hasTransform()) return true; + if (*rareNonInheritedData->m_transform != *other.rareNonInheritedData->m_transform) { + changedContextSensitiveProperties |= ContextSensitivePropertyTransform; + // Don't return; keep looking for another change + } } + +#if ENABLE(CSS_GRID_LAYOUT) + if (rareNonInheritedData->m_grid != other.rareNonInheritedData->m_grid + || rareNonInheritedData->m_gridItem != other.rareNonInheritedData->m_gridItem) + return true; #endif #if ENABLE(DASHBOARD_SUPPORT) // If regions change, trigger a relayout to re-calc regions. - if (rareNonInheritedData->m_dashboardRegions != other->rareNonInheritedData->m_dashboardRegions) + if (rareNonInheritedData->m_dashboardRegions != other.rareNonInheritedData->m_dashboardRegions) return true; #endif -#if ENABLE(CSS_SHAPES) - if (rareNonInheritedData->m_shapeInside != other->rareNonInheritedData->m_shapeInside) - return true; -#endif + if (!arePointingToEqualData(rareNonInheritedData->m_willChange, other.rareNonInheritedData->m_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 (rareInheritedData.get() != other.rareInheritedData.get()) { + if (rareInheritedData->indent != other.rareInheritedData->indent #if ENABLE(CSS3_TEXT) - || rareInheritedData->m_textIndentLine != other->rareInheritedData->m_textIndentLine + || rareInheritedData->m_textAlignLast != other.rareInheritedData->m_textAlignLast + || rareInheritedData->m_textJustify != other.rareInheritedData->m_textJustify + || rareInheritedData->m_textIndentLine != other.rareInheritedData->m_textIndentLine +#endif + || rareInheritedData->m_effectiveZoom != other.rareInheritedData->m_effectiveZoom + || rareInheritedData->m_textZoom != other.rareInheritedData->m_textZoom +#if ENABLE(IOS_TEXT_AUTOSIZING) + || rareInheritedData->textSizeAdjust != other.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->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 +#if ENABLE(CSS_IMAGE_ORIENTATION) + || rareInheritedData->m_imageOrientation != other.rareInheritedData->m_imageOrientation #endif - || rareInheritedData->m_effectiveZoom != other->rareInheritedData->m_effectiveZoom - || 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 #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 + || rareInheritedData->m_imageResolutionSource != other.rareInheritedData->m_imageResolutionSource + || rareInheritedData->m_imageResolutionSnap != other.rareInheritedData->m_imageResolutionSnap + || rareInheritedData->m_imageResolution != other.rareInheritedData->m_imageResolution #endif - || rareInheritedData->m_lineSnap != other->rareInheritedData->m_lineSnap - || rareInheritedData->m_lineAlign != other->rareInheritedData->m_lineAlign - || rareInheritedData->listStyleImage != other->rareInheritedData->listStyleImage) - return true; - - if (!rareInheritedData->shadowDataEquivalent(*other->rareInheritedData.get())) + || rareInheritedData->m_lineSnap != other.rareInheritedData->m_lineSnap + || rareInheritedData->m_lineAlign != other.rareInheritedData->m_lineAlign + || rareInheritedData->m_hangingPunctuation != other.rareInheritedData->m_hangingPunctuation +#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) + || rareInheritedData->useTouchOverflowScrolling != other.rareInheritedData->useTouchOverflowScrolling +#endif + || rareInheritedData->listStyleImage != other.rareInheritedData->listStyleImage) // FIXME: needs arePointingToEqualData()? return true; - if (textStrokeWidth() != other->textStrokeWidth()) + if (textStrokeWidth() != other.textStrokeWidth()) return true; } #if ENABLE(TEXT_AUTOSIZING) - if (visual->m_textAutosizingMultiplier != other->visual->m_textAutosizingMultiplier) + if (visual->m_textAutosizingMultiplier != other.visual->m_textAutosizingMultiplier) return true; #endif - if (inherited->line_height != other->inherited->line_height - || 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) + if (inherited->line_height != other.inherited->line_height +#if ENABLE(IOS_TEXT_AUTOSIZING) + || inherited->specifiedLineHeight != other.inherited->specifiedLineHeight +#endif + || inherited->fontCascade != other.inherited->fontCascade + || 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()) 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 ((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.tableLayout() != other.noninherited_flags.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))) + && ((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 (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) 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 (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()) return true; // Check block flow direction. - if (inherited_flags.m_writingMode != other->inherited_flags.m_writingMode) + if (inherited_flags.m_writingMode != other.inherited_flags.m_writingMode) return true; // Check text combine mode. - if (rareNonInheritedData->m_textCombine != other->rareNonInheritedData->m_textCombine) + if (rareNonInheritedData->m_textCombine != other.rareNonInheritedData->m_textCombine) + return true; + + // Check breaks. + if (rareNonInheritedData->m_breakBefore != other.rareNonInheritedData->m_breakBefore + || rareNonInheritedData->m_breakAfter != other.rareNonInheritedData->m_breakAfter + || rareNonInheritedData->m_breakInside != other.rareNonInheritedData->m_breakInside) return true; // Overflow returns a layout hint. - if (noninherited_flags._overflowX != other->noninherited_flags._overflowX - || noninherited_flags._overflowY != other->noninherited_flags._overflowY) + if (noninherited_flags.overflowX() != other.noninherited_flags.overflowX() + || noninherited_flags.overflowY() != other.noninherited_flags.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(rareNonInheritedData->m_counterDirectives, other.rareNonInheritedData->m_counterDirectives)) return true; - if ((visibility() == COLLAPSE) != (other->visibility() == COLLAPSE)) + if ((visibility() == COLLAPSE) != (other.visibility() == COLLAPSE)) return true; - if ((rareNonInheritedData->opacity == 1 && other->rareNonInheritedData->opacity < 1) - || (rareNonInheritedData->opacity < 1 && other->rareNonInheritedData->opacity == 1)) { + if (rareNonInheritedData->hasOpacity() != other.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). @@ -603,13 +721,19 @@ bool RenderStyle::changeRequiresLayout(const RenderStyle* other, unsigned& chang return true; } - const QuotesData* quotesDataA = rareInheritedData->quotes.get(); - const QuotesData* quotesDataB = other->rareInheritedData->quotes.get(); - if (!(quotesDataA == quotesDataB || (quotesDataA && quotesDataB && *quotesDataA == *quotesDataB))) + if (rareNonInheritedData->hasFilters() != other.rareNonInheritedData->hasFilters()) + return true; + +#if ENABLE(FILTERS_LEVEL_2) + if (rareNonInheritedData->hasBackdropFilters() != other.rareNonInheritedData->hasBackdropFilters()) + return true; +#endif + + if (!arePointingToEqualData(rareInheritedData->quotes, other.rareInheritedData->quotes)) return true; if (position() != StaticPosition) { - if (surround->offset != other->surround->offset) { + if (surround->offset != other.surround->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). @@ -617,7 +741,7 @@ 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(surround->offset, other.surround->offset, m_box->width())) return true; } } @@ -625,148 +749,136 @@ bool RenderStyle::changeRequiresLayout(const RenderStyle* other, unsigned& chang 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 (surround->offset != other.surround->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(surround->offset, other.surround->offset, m_box->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_box->zIndex() != other.m_box->zIndex() || m_box->hasAutoZIndex() != other.m_box->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 (visual->clip != other.visual->clip || visual->hasClip != other.visual->hasClip) { + changedContextSensitiveProperties |= ContextSensitivePropertyClipRect; return true; + } } #if ENABLE(CSS_COMPOSITING) - if (rareNonInheritedData->m_effectiveBlendMode != other->rareNonInheritedData->m_effectiveBlendMode) + if (rareNonInheritedData->m_effectiveBlendMode != other.rareNonInheritedData->m_effectiveBlendMode) return true; #endif - if (rareNonInheritedData->opacity != other->rareNonInheritedData->opacity) { -#if USE(ACCELERATED_COMPOSITING) + if (rareNonInheritedData->opacity != other.rareNonInheritedData->opacity) { changedContextSensitiveProperties |= ContextSensitivePropertyOpacity; // Don't return; keep looking for another change. -#else - 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 (rareNonInheritedData->m_filter != other.rareNonInheritedData->m_filter) { 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 (rareNonInheritedData->m_mask != other.rareNonInheritedData->m_mask + || rareNonInheritedData->m_maskBoxImage != other.rareNonInheritedData->m_maskBoxImage) return true; return false; } -bool RenderStyle::changeRequiresRepaint(const RenderStyle* other, unsigned&) const -{ - 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 - || rareInheritedData->m_imageRendering != other->rareInheritedData->m_imageRendering) - return true; - - // 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) +bool RenderStyle::changeRequiresRepaint(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const +{ + if (inherited_flags._visibility != other.inherited_flags._visibility + || inherited_flags.m_printColorAdjust != other.inherited_flags.m_printColorAdjust + || inherited_flags._insideLink != other.inherited_flags._insideLink + || inherited_flags._insideDefaultButton != other.inherited_flags._insideDefaultButton + || 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 (rareNonInheritedData->m_clipPath != other->rareNonInheritedData->m_clipPath) +#if ENABLE(CSS_SHAPES) + if (rareNonInheritedData->m_shapeOutside != other.rareNonInheritedData->m_shapeOutside) return true; +#endif + + // FIXME: this should probably be moved to changeRequiresLayerRepaint(). + if (rareNonInheritedData->m_clipPath != other.rareNonInheritedData->m_clipPath) { + changedContextSensitiveProperties |= ContextSensitivePropertyClipPath; + // Don't return; keep looking for another change. + } return false; } -bool RenderStyle::changeRequiresRepaintIfText(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 -#if ENABLE(CSS3_TEXT) - || rareNonInheritedData->m_textDecorationStyle != other->rareNonInheritedData->m_textDecorationStyle - || rareNonInheritedData->m_textDecorationColor != other->rareNonInheritedData->m_textDecorationColor -#endif // CSS3_TEXT - || rareInheritedData->textFillColor != other->rareInheritedData->textFillColor - || rareInheritedData->textStrokeColor != other->rareInheritedData->textStrokeColor - || rareInheritedData->textEmphasisColor != other->rareInheritedData->textEmphasisColor - || rareInheritedData->textEmphasisFill != other->rareInheritedData->textEmphasisFill) + 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) 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 (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) return true; } -#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 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; @@ -777,13 +889,11 @@ 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 (changeRequiresRepaintIfText(other, changedContextSensitiveProperties)) - return StyleDifferenceRepaintIfText; + if (changeRequiresRepaintIfTextOrBorderOrOutline(other, changedContextSensitiveProperties)) + return StyleDifferenceRepaintIfTextOrBorderOrOutline; // Cursors are not checked, since they will be set appropriately in response to mouse events, // so they don't need to cause any repaint or layout. @@ -793,19 +903,26 @@ 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) { StyleVisualData* data = visual.access(); - data->clip.m_top = top; - data->clip.m_right = right; - data->clip.m_bottom = bottom; - data->clip.m_left = left; + data->clip.top() = top; + data->clip.right() = right; + data->clip.bottom() = bottom; + data->clip.left() = left; } void RenderStyle::addCursor(PassRefPtr<StyleImage> image, const IntPoint& hotSpot) @@ -828,10 +945,18 @@ void RenderStyle::setQuotes(PassRefPtr<QuotesData> q) rareInheritedData.access()->quotes = q; } +void RenderStyle::setWillChange(PassRefPtr<WillChangeData> willChangeData) +{ + if (arePointingToEqualData(rareNonInheritedData->m_willChange.get(), willChangeData.get())) + return; + + rareNonInheritedData.access()->m_willChange = WTFMove(willChangeData); +} + void RenderStyle::clearCursorList() { if (rareInheritedData->cursorData) - rareInheritedData.access()->cursorData = 0; + rareInheritedData.access()->cursorData = nullptr; } void RenderStyle::clearContent() @@ -840,17 +965,17 @@ void RenderStyle::clearContent() rareNonInheritedData.access()->m_content = nullptr; } -void RenderStyle::appendContent(PassOwnPtr<ContentData> contentData) +void RenderStyle::appendContent(std::unique_ptr<ContentData> contentData) { - OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content; + auto& content = rareNonInheritedData.access()->m_content; ContentData* lastContent = content.get(); while (lastContent && lastContent->next()) lastContent = lastContent->next(); if (lastContent) - lastContent->setNext(contentData); + lastContent->setNext(WTFMove(contentData)); else - content = contentData; + content = WTFMove(contentData); } void RenderStyle::setContent(PassRefPtr<StyleImage> image, bool add) @@ -859,16 +984,18 @@ void RenderStyle::setContent(PassRefPtr<StyleImage> image, bool add) return; if (add) { - appendContent(ContentData::create(image)); + appendContent(std::make_unique<ImageContentData>(image)); return; } - rareNonInheritedData.access()->m_content = ContentData::create(image); + rareNonInheritedData.access()->m_content = std::make_unique<ImageContentData>(image); + if (!rareNonInheritedData.access()->m_altText.isNull()) + rareNonInheritedData.access()->m_content->setAltText(rareNonInheritedData.access()->m_altText); } void RenderStyle::setContent(const String& string, bool add) { - OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content; + auto& content = rareNonInheritedData.access()->m_content; if (add) { ContentData* lastContent = content.get(); while (lastContent && lastContent->next()) @@ -876,43 +1003,61 @@ void RenderStyle::setContent(const String& string, bool add) 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); + if (is<TextContentData>(*lastContent)) { + TextContentData& textContent = downcast<TextContentData>(*lastContent); + textContent.setText(textContent.text() + string); } else - lastContent->setNext(ContentData::create(string)); + lastContent->setNext(std::make_unique<TextContentData>(string)); + if (!rareNonInheritedData.access()->m_altText.isNull()) + lastContent->setAltText(rareNonInheritedData.access()->m_altText); return; } } - content = ContentData::create(string); + content = std::make_unique<TextContentData>(string); + if (!rareNonInheritedData.access()->m_altText.isNull()) + content->setAltText(rareNonInheritedData.access()->m_altText); } -void RenderStyle::setContent(PassOwnPtr<CounterContent> counter, bool add) +void RenderStyle::setContent(std::unique_ptr<CounterContent> counter, bool add) { if (!counter) return; if (add) { - appendContent(ContentData::create(counter)); + appendContent(std::make_unique<CounterContentData>(WTFMove(counter))); return; } - rareNonInheritedData.access()->m_content = ContentData::create(counter); + rareNonInheritedData.access()->m_content = std::make_unique<CounterContentData>(WTFMove(counter)); } void RenderStyle::setContent(QuoteType quote, bool add) { if (add) { - appendContent(ContentData::create(quote)); + appendContent(std::make_unique<QuoteContentData>(quote)); return; } - rareNonInheritedData.access()->m_content = ContentData::create(quote); + rareNonInheritedData.access()->m_content = std::make_unique<QuoteContentData>(quote); } + +void RenderStyle::setContentAltText(const String& string) +{ + rareNonInheritedData.access()->m_altText = string; -inline bool requireTransformOrigin(const Vector<RefPtr<TransformOperation> >& transformOperations, RenderStyle::ApplyTransformOrigin applyOrigin) + if (rareNonInheritedData.access()->m_content) + rareNonInheritedData.access()->m_content->setAltText(string); +} + +const String& RenderStyle::contentAltText() const +{ + return rareNonInheritedData->m_altText; +} + +// FIXME: use affectedByTransformOrigin(). +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 @@ -920,9 +1065,8 @@ inline bool requireTransformOrigin(const Vector<RefPtr<TransformOperation> >& tr if (applyOrigin != RenderStyle::IncludeTransformOrigin) return false; - unsigned size = transformOperations.size(); - for (unsigned i = 0; i < size; ++i) { - TransformOperation::OperationType type = transformOperations[i]->getOperationType(); + for (auto& operation : transformOperations) { + TransformOperation::OperationType type = operation->type(); if (type != TransformOperation::TRANSLATE_X && type != TransformOperation::TRANSLATE_Y && type != TransformOperation::TRANSLATE @@ -930,47 +1074,27 @@ inline bool requireTransformOrigin(const Vector<RefPtr<TransformOperation> >& tr && type != TransformOperation::TRANSLATE_3D) 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 = rareNonInheritedData->m_transform->m_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, @@ -989,75 +1113,43 @@ 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(); 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(); if (!add) { - rareData->m_boxShadow = shadowData; + rareData->m_boxShadow = WTFMove(shadowData); return; } - shadowData->setNext(rareData->m_boxShadow.release()); - rareData->m_boxShadow = shadowData; + shadowData->setNext(WTFMove(rareData->m_boxShadow)); + rareData->m_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))); -} - -static float calcConstraintScaleFor(const IntRect& rect, const RoundedRect::Radii& radii) -{ - // 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 = 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 = 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 = 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 = min(static_cast<float>(rect.height()) / radiiSum, factor); - - ASSERT(factor <= 1); - return factor; + LayoutSize(valueForLength(border.topLeft().width(), size.width()), + valueForLength(border.topLeft().height(), size.height())), + LayoutSize(valueForLength(border.topRight().width(), size.width()), + valueForLength(border.topRight().height(), size.height())), + LayoutSize(valueForLength(border.bottomLeft().width(), size.width()), + valueForLength(border.bottomLeft().height(), size.height())), + LayoutSize(valueForLength(border.bottomRight().width(), size.width()), + valueForLength(border.bottomRight().height(), size.height()))); } StyleImage* RenderStyle::listStyleImage() const { return rareInheritedData->listStyleImage.get(); } @@ -1077,13 +1169,12 @@ short RenderStyle::verticalBorderSpacing() const { return inherited->vertical_bo void RenderStyle::setHorizontalBorderSpacing(short v) { SET_VAR(inherited, horizontal_border_spacing, v); } void RenderStyle::setVerticalBorderSpacing(short v) { SET_VAR(inherited, vertical_border_spacing, v); } -RoundedRect RenderStyle::getRoundedBorderFor(const LayoutRect& borderRect, RenderView* renderView, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const +RoundedRect RenderStyle::getRoundedBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const { - IntRect snappedBorderRect(pixelSnappedIntRect(borderRect)); - RoundedRect roundedRect(snappedBorderRect); + RoundedRect roundedRect(borderRect); if (hasBorderRadius()) { - RoundedRect::Radii radii = calcRadiiFor(surround->border, snappedBorderRect.size(), renderView); - radii.scale(calcConstraintScaleFor(snappedBorderRect, radii)); + RoundedRect::Radii radii = calcRadiiFor(surround->border, borderRect.size()); + radii.scale(calcBorderRadiiConstraintScaleFor(borderRect, radii)); roundedRect.includeLogicalEdges(radii, isHorizontalWritingMode(), includeLogicalLeftEdge, includeLogicalRightEdge); } return roundedRect; @@ -1093,23 +1184,23 @@ RoundedRect RenderStyle::getRoundedInnerBorderFor(const LayoutRect& borderRect, { 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; + LayoutUnit leftWidth = (!horizontal || includeLogicalLeftEdge) ? borderLeftWidth() : 0; + LayoutUnit rightWidth = (!horizontal || includeLogicalRightEdge) ? borderRightWidth() : 0; + LayoutUnit topWidth = (horizontal || includeLogicalLeftEdge) ? borderTopWidth() : 0; + LayoutUnit 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(innerRect); if (hasBorderRadius()) { RoundedRect::Radii radii = getRoundedBorderFor(borderRect).radii(); @@ -1141,9 +1232,9 @@ const CounterDirectiveMap* RenderStyle::counterDirectives() const CounterDirectiveMap& RenderStyle::accessCounterDirectives() { - OwnPtr<CounterDirectiveMap>& map = rareNonInheritedData.access()->m_counterDirectives; + auto& map = rareNonInheritedData.access()->m_counterDirectives; if (!map) - map = adoptPtr(new CounterDirectiveMap); + map = std::make_unique<CounterDirectiveMap>(); return *map; } @@ -1163,9 +1254,9 @@ const AtomicString& RenderStyle::hyphenString() const 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 @@ -1176,28 +1267,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: @@ -1212,24 +1303,24 @@ 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.offset.top() = Length(); + region.offset.right() = Length(); + region.offset.bottom() = Length(); + region.offset.left() = Length(); region.type = StyleDashboardRegion::None; - noneList.append(region); + noneList.get().append(region); noneListInitialized = true; } return noneList; @@ -1244,7 +1335,7 @@ void RenderStyle::adjustAnimations() // Get rid of empty animations and anything beyond them for (size_t i = 0; i < animationList->size(); ++i) { - if (animationList->animation(i)->isEmpty()) { + if (animationList->animation(i).isEmpty()) { animationList->resize(i); break; } @@ -1267,7 +1358,7 @@ void RenderStyle::adjustTransitions() // Get rid of empty transitions and anything beyond them for (size_t i = 0; i < transitionList->size(); ++i) { - if (transitionList->animation(i)->isEmpty()) { + if (transitionList->animation(i).isEmpty()) { transitionList->resize(i); break; } @@ -1285,7 +1376,7 @@ void RenderStyle::adjustTransitions() // but the lists tend to be very 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) { - if (transitionList->animation(i)->property() == transitionList->animation(j)->property()) { + if (transitionList->animation(i).property() == transitionList->animation(j).property()) { // toss i transitionList->remove(i); j = i; @@ -1294,53 +1385,59 @@ 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(); + rareNonInheritedData.access()->m_animations = std::make_unique<AnimationList>(); + return *rareNonInheritedData->m_animations; } -AnimationList* RenderStyle::accessTransitions() +AnimationList& RenderStyle::ensureTransitions() { if (!rareNonInheritedData.access()->m_transitions) - rareNonInheritedData.access()->m_transitions = adoptPtr(new AnimationList()); - return rareNonInheritedData->m_transitions.get(); + rareNonInheritedData.access()->m_transitions = std::make_unique<AnimationList>(); + return *rareNonInheritedData->m_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; + const Animation& p = transitions()->animation(i); + if (p.animationMode() == Animation::AnimateAll || p.property() == property) { + return &p; } } } return 0; } -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(); } +const FontCascade& RenderStyle::fontCascade() const { return inherited->fontCascade; } +const FontMetrics& RenderStyle::fontMetrics() const { return inherited->fontCascade.fontMetrics(); } +const FontCascadeDescription& RenderStyle::fontDescription() const { return inherited->fontCascade.fontDescription(); } float RenderStyle::specifiedFontSize() const { return fontDescription().specifiedSize(); } float RenderStyle::computedFontSize() const { return fontDescription().computedSize(); } -int RenderStyle::fontSize() const { return inherited->font.pixelSize(); } +int RenderStyle::fontSize() const { return inherited->fontCascade.pixelSize(); } -float RenderStyle::wordSpacing() const { return inherited->font.wordSpacing(); } -float RenderStyle::letterSpacing() const { return inherited->font.letterSpacing(); } +const Length& RenderStyle::wordSpacing() const { return rareInheritedData->wordSpacing; } +float RenderStyle::letterSpacing() const { return inherited->fontCascade.letterSpacing(); } -bool RenderStyle::setFontDescription(const FontDescription& v) +bool RenderStyle::setFontDescription(const FontCascadeDescription& v) { - if (inherited->font.fontDescription() != v) { - inherited.access()->font = Font(v, inherited->font.letterSpacing(), inherited->font.wordSpacing()); + if (inherited->fontCascade.fontDescription() != v) { + inherited.access()->fontCascade = FontCascade(v, inherited->fontCascade.letterSpacing(), inherited->fontCascade.wordSpacing()); return true; } return false; } -Length RenderStyle::specifiedLineHeight() const { return inherited->line_height; } +#if ENABLE(IOS_TEXT_AUTOSIZING) +const Length& RenderStyle::specifiedLineHeight() const { return inherited->specifiedLineHeight; } +void RenderStyle::setSpecifiedLineHeight(Length v) { SET_VAR(inherited, specifiedLineHeight, v); } +#else +const Length& RenderStyle::specifiedLineHeight() const { return inherited->line_height; } +#endif + Length RenderStyle::lineHeight() const { const Length& lh = inherited->line_height; @@ -1357,7 +1454,7 @@ Length RenderStyle::lineHeight() const } 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(); @@ -1365,17 +1462,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 clampTo<int>(lh.value()); +} - return lh.value(); +void RenderStyle::setWordSpacing(Length value) +{ + float fontWordSpacing; + switch (value.type()) { + case Auto: + fontWordSpacing = 0; + break; + case Percent: + fontWordSpacing = value.percent() * fontCascade().spaceWidth() / 100; + break; + case Fixed: + fontWordSpacing = value.value(); + break; + case Calculated: + fontWordSpacing = value.nonNanCalculatedValue(maxValueForCssLength); + break; + default: + ASSERT_NOT_REACHED(); + fontWordSpacing = 0; + break; + } + inherited.access()->fontCascade.setWordSpacing(fontWordSpacing); + rareInheritedData.access()->wordSpacing = WTFMove(value); } -void RenderStyle::setWordSpacing(float v) { inherited.access()->font.setWordSpacing(v); } -void RenderStyle::setLetterSpacing(float v) { inherited.access()->font.setLetterSpacing(v); } +void RenderStyle::setLetterSpacing(float v) { inherited.access()->fontCascade.setLetterSpacing(v); } void RenderStyle::setFontSize(float size) { @@ -1386,23 +1504,23 @@ void RenderStyle::setFontSize(float size) if (!std::isfinite(size) || size < 0) size = 0; else - size = min(maximumAllowedFontSize, size); + 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)); + description.setComputedSize(min(maximumAllowedFontSize, autosizedFontSize)); } #endif - setFontDescription(desc); - font().update(currentFontSelector); + setFontDescription(description); + fontCascade().update(currentFontSelector); } void RenderStyle::getShadowExtent(const ShadowData* shadow, LayoutUnit &top, LayoutUnit &right, LayoutUnit &bottom, LayoutUnit &left) const @@ -1417,10 +1535,10 @@ void RenderStyle::getShadowExtent(const ShadowData* shadow, LayoutUnit &top, Lay continue; int extentAndSpread = shadow->paintingExtent() + shadow->spread(); - top = min<LayoutUnit>(top, shadow->y() - extentAndSpread); - right = max<LayoutUnit>(right, shadow->x() + extentAndSpread); - bottom = max<LayoutUnit>(bottom, shadow->y() + extentAndSpread); - left = min<LayoutUnit>(left, shadow->x() - extentAndSpread); + top = std::min<LayoutUnit>(top, shadow->y() - extentAndSpread); + right = std::max<LayoutUnit>(right, shadow->x() + extentAndSpread); + bottom = std::max<LayoutUnit>(bottom, shadow->y() + extentAndSpread); + left = std::min<LayoutUnit>(left, shadow->x() - extentAndSpread); } } @@ -1436,10 +1554,10 @@ LayoutBoxExtent RenderStyle::getShadowInsetExtent(const ShadowData* shadow) cons continue; int extentAndSpread = shadow->paintingExtent() + shadow->spread(); - top = max<LayoutUnit>(top, shadow->y() + extentAndSpread); - right = min<LayoutUnit>(right, shadow->x() - extentAndSpread); - bottom = min<LayoutUnit>(bottom, shadow->y() - extentAndSpread); - left = max<LayoutUnit>(left, shadow->x() + extentAndSpread); + top = std::max<LayoutUnit>(top, shadow->y() + extentAndSpread); + right = std::min<LayoutUnit>(right, shadow->x() - extentAndSpread); + bottom = std::min<LayoutUnit>(bottom, shadow->y() - extentAndSpread); + left = std::max<LayoutUnit>(left, shadow->x() + extentAndSpread); } return LayoutBoxExtent(top, right, bottom, left); @@ -1455,8 +1573,8 @@ void RenderStyle::getShadowHorizontalExtent(const ShadowData* shadow, LayoutUnit continue; int extentAndSpread = shadow->paintingExtent() + shadow->spread(); - left = min<LayoutUnit>(left, shadow->x() - extentAndSpread); - right = max<LayoutUnit>(right, shadow->x() + extentAndSpread); + left = std::min<LayoutUnit>(left, shadow->x() - extentAndSpread); + right = std::max<LayoutUnit>(right, shadow->x() + extentAndSpread); } } @@ -1470,8 +1588,8 @@ void RenderStyle::getShadowVerticalExtent(const ShadowData* shadow, LayoutUnit & continue; int extentAndSpread = shadow->paintingExtent() + shadow->spread(); - top = min<LayoutUnit>(top, shadow->y() - extentAndSpread); - bottom = max<LayoutUnit>(bottom, shadow->y() + extentAndSpread); + top = std::min<LayoutUnit>(top, shadow->y() - extentAndSpread); + bottom = std::max<LayoutUnit>(bottom, shadow->y() + extentAndSpread); } } @@ -1504,14 +1622,12 @@ Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) c case CSSPropertyOutlineColor: result = visitedLink ? visitedLinkOutlineColor() : outlineColor(); break; - case CSSPropertyWebkitColumnRuleColor: + case CSSPropertyColumnRuleColor: result = visitedLink ? visitedLinkColumnRuleColor() : columnRuleColor(); break; -#if ENABLE(CSS3_TEXT) case CSSPropertyWebkitTextDecorationColor: // Text decoration color fallback is handled in RenderObject::decorationColor. return visitedLink ? visitedLinkTextDecorationColor() : textDecorationColor(); -#endif // CSS3_TEXT case CSSPropertyWebkitTextEmphasisColor: result = visitedLink ? visitedLinkTextEmphasisColor() : textEmphasisColor(); break; @@ -1543,11 +1659,9 @@ Color RenderStyle::visitedDependentColor(int colorProperty) const Color visitedColor = colorIncludingFallback(colorProperty, true); -#if ENABLE(CSS3_TEXT) // Text decoration color validity is preserved (checked in RenderObject::decorationColor). if (colorProperty == CSSPropertyWebkitTextDecorationColor) return visitedColor; -#endif // CSS3_TEXT // FIXME: Technically someone could explicitly specify the color transparent, but for now we'll just // assume that if the background color is transparent that it wasn't set. Note that it's weird that @@ -1607,7 +1721,7 @@ const BorderValue& RenderStyle::borderEnd() const return isLeftToRightDirection() ? borderBottom() : borderTop(); } -unsigned short RenderStyle::borderBeforeWidth() const +float RenderStyle::borderBeforeWidth() const { switch (writingMode()) { case TopToBottomWritingMode: @@ -1623,7 +1737,7 @@ unsigned short RenderStyle::borderBeforeWidth() const return borderTopWidth(); } -unsigned short RenderStyle::borderAfterWidth() const +float RenderStyle::borderAfterWidth() const { switch (writingMode()) { case TopToBottomWritingMode: @@ -1639,14 +1753,14 @@ 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(); @@ -1710,6 +1824,26 @@ LayoutBoxExtent RenderStyle::imageOutsets(const NinePieceImage& image) const NinePieceImage::computeOutset(image.outset().left(), borderLeftWidth())); } +std::pair<FontOrientation, NonCJKGlyphOrientation> RenderStyle::fontAndGlyphOrientation() +{ + // FIXME: TextOrientationSideways should map to sideways-left in vertical-lr, which is not supported yet. + + if (isHorizontalWritingMode()) + return { Horizontal, NonCJKGlyphOrientation::Mixed }; + + switch (textOrientation()) { + 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(); + return { Horizontal, NonCJKGlyphOrientation::Mixed }; + } +} + void RenderStyle::setBorderImageSource(PassRefPtr<StyleImage> image) { if (surround->border.m_image.image() == image.get()) @@ -1738,17 +1872,13 @@ void RenderStyle::setBorderImageOutset(LengthBox outset) surround.access()->border.m_image.setOutset(outset); } -ShapeValue* RenderStyle::initialShapeInside() -{ - DEFINE_STATIC_LOCAL(RefPtr<ShapeValue>, sOutsideValue, (ShapeValue::createOutsideValue())); - return sOutsideValue.get(); -} - void RenderStyle::setColumnStylesFromPaginationMode(const Pagination::Mode& paginationMode) { if (paginationMode == Pagination::Unpaginated) return; - + + setColumnFill(ColumnFillAuto); + switch (paginationMode) { case Pagination::LeftToRightPaginated: setColumnAxis(HorizontalColumnAxis); @@ -1784,4 +1914,149 @@ void RenderStyle::setColumnStylesFromPaginationMode(const Pagination::Mode& pagi } } +#if ENABLE(CSS_SCROLL_SNAP) +LengthSize RenderStyle::initialScrollSnapDestination() +{ + return defaultScrollSnapDestination(); +} + +Vector<LengthSize> RenderStyle::initialScrollSnapCoordinates() +{ + return Vector<LengthSize>(); +} + +const ScrollSnapPoints* RenderStyle::scrollSnapPointsX() const +{ + return rareNonInheritedData->m_scrollSnapPoints->xPoints.get(); +} + +const ScrollSnapPoints* RenderStyle::scrollSnapPointsY() const +{ + return rareNonInheritedData->m_scrollSnapPoints->yPoints.get(); +} + +const LengthSize& RenderStyle::scrollSnapDestination() const +{ + return rareNonInheritedData->m_scrollSnapPoints->destination; +} + +const Vector<LengthSize>& RenderStyle::scrollSnapCoordinates() const +{ + return rareNonInheritedData->m_scrollSnapPoints->coordinates; +} + +void RenderStyle::setScrollSnapPointsX(std::unique_ptr<ScrollSnapPoints> points) +{ + if (rareNonInheritedData->m_scrollSnapPoints->xPoints.get() == points.get()) + return; + rareNonInheritedData.access()->m_scrollSnapPoints.access()->xPoints = WTFMove(points); +} + +void RenderStyle::setScrollSnapPointsY(std::unique_ptr<ScrollSnapPoints> points) +{ + if (rareNonInheritedData->m_scrollSnapPoints->yPoints.get() == points.get()) + return; + rareNonInheritedData.access()->m_scrollSnapPoints.access()->yPoints = WTFMove(points); +} + +void RenderStyle::setScrollSnapDestination(LengthSize destination) +{ + if (rareNonInheritedData->m_scrollSnapPoints->destination == destination) + return; + rareNonInheritedData.access()->m_scrollSnapPoints.access()->destination = WTFMove(destination); +} + +void RenderStyle::setScrollSnapCoordinates(Vector<LengthSize> coordinates) +{ + if (rareNonInheritedData->m_scrollSnapPoints->coordinates == coordinates) + return; + rareNonInheritedData.access()->m_scrollSnapPoints.access()->coordinates = WTFMove(coordinates); +} + +#endif + +bool RenderStyle::hasReferenceFilterOnly() const +{ + if (!hasFilter()) + return false; + + const FilterOperations& filterOperations = rareNonInheritedData->m_filter->m_operations; + if (filterOperations.size() != 1) + return false; + + const FilterOperation& filterOperation = *filterOperations.at(0); + if (filterOperation.type() != FilterOperation::REFERENCE) + return false; + + return true; +} + +void RenderStyle::checkVariablesInCustomProperties() +{ + if (!rareInheritedData->m_customProperties->containsVariables()) + return; + + // Our first pass checks the variables for validity and replaces any properties that became + // invalid with empty values. + auto& customProperties = rareInheritedData.access()->m_customProperties.access()->values(); + HashSet<AtomicString> invalidProperties; + for (auto entry : customProperties) { + if (!entry.value->isVariableDependentValue()) + continue; + HashSet<AtomicString> seenProperties; + downcast<CSSVariableDependentValue>(*entry.value).checkVariablesForCycles(entry.key, customProperties, seenProperties, invalidProperties); + } + + // Now insert invalid values. + if (!invalidProperties.isEmpty()) { + RefPtr<CSSValue> invalidValue = CSSCustomPropertyValue::createInvalid(); + for (auto& property : invalidProperties) + customProperties.set(property, invalidValue); + } + + // 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<RefPtr<CSSCustomPropertyValue>> resolvedValues; + for (auto entry : customProperties) { + if (!entry.value->isVariableDependentValue()) + continue; + + CSSParserValueList parserList; + RefPtr<CSSCustomPropertyValue> result; + if (!downcast<CSSVariableDependentValue>(*entry.value).valueList()->buildParserValueListSubstitutingVariables(&parserList, customProperties)) { + RefPtr<CSSValue> invalidResult = CSSCustomPropertyValue::createInvalid(); + result = CSSCustomPropertyValue::create(entry.key, invalidResult); + } else { + RefPtr<CSSValue> newValueList = CSSValueList::createFromParserValueList(parserList); + result = CSSCustomPropertyValue::create(entry.key, newValueList); + } + resolvedValues.append(result); + } + + // 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->value()); + + rareInheritedData.access()->m_customProperties.access()->setContainsVariables(false); +} + +float RenderStyle::outlineWidth() const +{ + if (m_background->outline().style() == BNONE) + return 0; + if (outlineStyleIsAuto()) + return std::max(m_background->outline().width(), RenderTheme::platformFocusRingWidth()); + return m_background->outline().width(); +} + +float RenderStyle::outlineOffset() const +{ + if (m_background->outline().style() == BNONE) + return 0; + if (outlineStyleIsAuto()) + return (m_background->outline().offset() + RenderTheme::platformFocusRingOffset(outlineWidth())); + return m_background->outline().offset(); +} + } // namespace WebCore diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h index 289c36b49..559df8182 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-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 @@ -37,7 +37,6 @@ #include "FontBaseline.h" #include "FontDescription.h" #include "GraphicsTypes.h" -#include "LayoutBoxExtent.h" #include "Length.h" #include "LengthBox.h" #include "LengthFunctions.h" @@ -48,14 +47,15 @@ #include "Pagination.h" #include "RenderStyleConstants.h" #include "RoundedRect.h" +#include "SVGPaint.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,51 +64,52 @@ #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/NeverDestroyed.h> #include <wtf/RefCounted.h> #include <wtf/StdLibExtras.h> #include <wtf/Vector.h> -#if ENABLE(CSS_FILTERS) -#include "StyleFilterData.h" +#if ENABLE(CSS_GRID_LAYOUT) +#include "StyleGridData.h" +#include "StyleGridItemData.h" #endif #if ENABLE(DASHBOARD_SUPPORT) #include "StyleDashboardRegion.h" #endif -#if ENABLE(SVG) -#include "SVGPaint.h" -#include "SVGRenderStyle.h" +#if ENABLE(IOS_TEXT_AUTOSIZING) +#include "TextSizeAdjustment.h" #endif -template<typename T, typename U> inline bool compareEqual(const T& t, const U& u) { return t == static_cast<T>(u); } +template<typename T, typename U> inline bool compareEqual(const T& t, const U& u) { return t == static_cast<const T&>(u); } #define SET_VAR(group, variable, value) \ if (!compareEqual(group->variable, value)) \ group.access()->variable = value +#define SET_NESTED_VAR(group, parentVariable, variable, value) \ + if (!compareEqual(group->parentVariable->variable, value)) \ + group.access()->parentVariable.access()->variable = value + #define SET_BORDERVALUE_COLOR(group, variable, value) \ if (!compareEqual(group->variable.color(), value)) \ group.access()->variable.setColor(value) namespace WebCore { -using std::max; - -#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,20 +119,273 @@ class StyleInheritedData; class StyleResolver; class TransformationMatrix; -class ContentData; +struct ScrollSnapPoints; typedef Vector<RefPtr<RenderStyle>, 4> PseudoStyleCache; class RenderStyle: public RefCounted<RenderStyle> { - friend class CSSPropertyAnimation; // Used by CSS animations. We can't allow them to animate based off visited colors. + 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 StyleBuilderConverter; // Sets members directly. + friend class StyleBuilderCustom; // Sets members directly. + friend class StyleBuilderFunctions; // Sets members directly. friend class StyleResolver; // Sets members directly. + +public: + struct NonInheritedFlags { + NonInheritedFlags() + { + // The default values should all be zero. + ASSERT(!initialOverflowX()); + ASSERT(!initialOverflowY()); + ASSERT(!initialClear()); + ASSERT(!initialDisplay()); + ASSERT(!initialUnicodeBidi()); + ASSERT(!initialPosition()); + ASSERT(!initialVerticalAlign()); + ASSERT(!initialFloating()); + ASSERT(!initialTableLayout()); + + m_flags = 0; + } + + bool operator==(const NonInheritedFlags& other) const + { + return m_flags == other.m_flags; + } + + bool operator!=(const NonInheritedFlags& other) const { return !(*this == other); } + + void 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); + } + + 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); } + + 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 pseudo) const + { + ASSERT(pseudo > NOPSEUDO); + ASSERT(pseudo < FIRST_INTERNAL_PSEUDOID); + return (oneBitMask << (pseudoBitsOffset - 1 + pseudo)) & m_flags; + } + void setHasPseudoStyle(PseudoId pseudo) + { + ASSERT(pseudo > NOPSEUDO); + ASSERT(pseudo < FIRST_INTERNAL_PSEUDOID); + m_flags |= oneBitMask << (pseudoBitsOffset - 1 + pseudo); + } + void 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)); + } + + 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); } + + 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 isSet, uint64_t offset) + { + if (isSet) + m_flags |= (oneBitMask << offset); + else + m_flags &= ~(oneBitMask << offset); + } + + bool getBoolean(uint64_t offset) const + { + return m_flags & (oneBitMask << offset); + } + + void 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); + } + + unsigned getValue(uint64_t positionIndependentMask, uint64_t offset) const + { + return static_cast<unsigned>((m_flags >> offset) & positionIndependentMask); + } + + 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 styleTypeBitCount = 6; + static const unsigned styleTypePadding = 2; + static const unsigned styleTypeAndPaddingBitCount = styleTypeBitCount + styleTypePadding; + static const uint64_t styleTypeMask = (oneBitMask << styleTypeAndPaddingBitCount) - 1; + static const unsigned styleTypeOffset = hasViewportUnitsBitCount + hasViewportUnitsOffset; + + // 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; + }; + protected: // non-inherited attributes @@ -146,11 +400,9 @@ protected: DataRef<StyleInheritedData> inherited; // list of associated pseudo styles - OwnPtr<PseudoStyleCache> m_cachedPseudoStyles; + std::unique_ptr<PseudoStyleCache> m_cachedPseudoStyles; -#if ENABLE(SVG) DataRef<SVGRenderStyle> m_svgStyle; -#endif // !START SYNC!: Keep this in sync with the copy constructor in RenderStyle.cpp and implicitlyInherited() in StyleResolver.cpp @@ -178,6 +430,7 @@ protected: && (m_printColorAdjust == other.m_printColorAdjust) && (_pointerEvents == other._pointerEvents) && (_insideLink == other._insideLink) + && (_insideDefaultButton == other._insideDefaultButton) && (m_writingMode == other.m_writingMode); } @@ -206,149 +459,40 @@ protected: unsigned m_printColorAdjust : PrintColorAdjustBits; unsigned _pointerEvents : 4; // EPointerEvents unsigned _insideLink : 2; // EInsideLink - // 43 bits + unsigned _insideDefaultButton : 1; + // 44 bits // CSS Text Layout Module Level 3: Vertical writing support unsigned m_writingMode : 2; // WritingMode - // 45 bits + // 46 bits } inherited_flags; // 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; + NonInheritedFlags 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(); -#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 PassRefPtr<RenderStyle> create(); - static PassRefPtr<RenderStyle> createDefaultStyle(); - static PassRefPtr<RenderStyle> createAnonymousStyleWithDisplay(const RenderStyle* parentStyle, EDisplay); - static PassRefPtr<RenderStyle> clone(const RenderStyle*); + static Ref<RenderStyle> create(); + static Ref<RenderStyle> createDefaultStyle(); + static Ref<RenderStyle> createAnonymousStyleWithDisplay(const RenderStyle* parentStyle, EDisplay); + static Ref<RenderStyle> clone(const RenderStyle*); + + // Create a RenderStyle for generated content by inheriting from a pseudo style. + static Ref<RenderStyle> createStyleInheritingFromPseudoStyle(const RenderStyle& pseudoStyle); + + ContentPosition resolvedAlignContentPosition() const; + ContentDistributionType resolvedAlignContentDistribution() const; + ContentPosition resolvedJustifyContentPosition() const; + ContentDistributionType resolvedJustifyContentDistribution() const; + static ItemPosition resolveAlignment(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForRenderer); + static OverflowAlignment resolveAlignmentOverflow(const RenderStyle& parentStyle, const RenderStyle& childStyle); + static ItemPosition resolveJustification(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForRenderer); + static OverflowAlignment resolveJustificationOverflow(const RenderStyle& parentStyle, const RenderStyle& childStyle); enum IsAtShadowBoundary { AtShadowBoundary, @@ -358,8 +502,8 @@ public: void inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary = NotAtShadowBoundary); void copyNonInheritedFrom(const RenderStyle*); - PseudoId styleType() const { return static_cast<PseudoId>(noninherited_flags._styleType); } - void setStyleType(PseudoId styleType) { noninherited_flags._styleType = styleType; } + PseudoId styleType() const { return noninherited_flags.styleType(); } + void setStyleType(PseudoId styleType) { noninherited_flags.setStyleType(styleType); } RenderStyle* getCachedPseudoStyle(PseudoId) const; RenderStyle* addCachedPseudoStyle(PassRefPtr<RenderStyle>); @@ -367,10 +511,13 @@ public: const PseudoStyleCache* cachedPseudoStyles() const { return m_cachedPseudoStyles.get(); } -#if ENABLE(CSS_VARIABLES) - void setVariable(const AtomicString& name, const String& value) { rareInheritedData.access()->m_variables.access()->setVariable(name, value); } - const HashMap<AtomicString, String>* variables() { return &(rareInheritedData->m_variables->m_data); } -#endif + void setCustomPropertyValue(const AtomicString& name, const RefPtr<CSSValue>& value) { rareInheritedData.access()->m_customProperties.access()->setCustomPropertyValue(name, value); } + RefPtr<CSSValue> getCustomPropertyValue(const AtomicString& name) const { return rareInheritedData->m_customProperties->getCustomPropertyValue(name); } + bool hasCustomProperty(const AtomicString& name) const { return rareInheritedData->m_customProperties->hasCustomProperty(name); } + const CustomPropertyValueMap& customProperties() const { return rareInheritedData->m_customProperties->m_values; } + + void setHasViewportUnits(bool hasViewportUnits = true) { noninherited_flags.setHasViewportUnits(hasViewportUnits); } + bool hasViewportUnits() const { return noninherited_flags.hasViewportUnits(); } bool affectedByHover() const { return noninherited_flags.affectedByHover(); } bool affectedByActive() const { return noninherited_flags.affectedByActive(); } @@ -384,13 +531,15 @@ public: 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 isFloating() const { return noninherited_flags.isFloating(); } + bool hasMargin() const { return !surround->margin.isZero(); } 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 hasBorderFill() const { return surround->border.hasFill(); } + bool hasBorderDecoration() const { return hasBorder() || hasBorderFill(); } + bool hasPadding() const { return !surround->padding.isZero(); } + bool hasOffset() const { return !surround->offset.isZero(); } + bool hasMarginBeforeQuirk() const { return marginBefore().hasQuirk(); } + bool hasMarginAfterQuirk() const { return marginAfter().hasQuirk(); } bool hasBackgroundImage() const { return m_background->background().hasImage(); } bool hasFixedBackgroundImage() const { return m_background->background().hasFixedImage(); } @@ -410,7 +559,7 @@ public: LayoutBoxExtent imageOutsets(const NinePieceImage&) const; bool hasBorderImageOutsets() const { - return borderImage().hasImage() && borderImage().outset().nonZero(); + return borderImage().hasImage() && !borderImage().outset().isZero(); } LayoutBoxExtent borderImageOutsets() const { @@ -422,10 +571,8 @@ public: 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; } @@ -435,23 +582,24 @@ public: bool hasAnyPublicPseudoStyles() const; bool hasPseudoStyle(PseudoId pseudo) const; void setHasPseudoStyle(PseudoId pseudo); + 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 noninherited_flags.effectiveDisplay(); } + EDisplay originalDisplay() const { return noninherited_flags.originalDisplay(); } - Length left() const { return surround->offset.left(); } - Length right() const { return surround->offset.right(); } - Length top() const { return surround->offset.top(); } - Length bottom() const { return surround->offset.bottom(); } + 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(); } // Accessors for positioned object edges that take into account writing mode. - Length logicalLeft() const { return surround->offset.logicalLeft(writingMode()); } - Length logicalRight() const { return surround->offset.logicalRight(writingMode()); } - Length logicalTop() const { return surround->offset.before(writingMode()); } - Length logicalBottom() const { return surround->offset.after(writingMode()); } + const Length& logicalLeft() const { return surround->offset.start(writingMode()); } + const Length& logicalRight() const { return surround->offset.end(writingMode()); } + const Length& logicalTop() const { return surround->offset.before(writingMode()); } + const Length& logicalBottom() const { return surround->offset.after(writingMode()); } // Whether or not a positioned element requires normal flow x/y to be computed // to determine its position. @@ -460,25 +608,25 @@ public: 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 noninherited_flags.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); } - - Length width() const { return m_box->width(); } - Length height() const { return m_box->height(); } - Length minWidth() const { return m_box->minWidth(); } - Length maxWidth() const { return m_box->maxWidth(); } - Length minHeight() const { return m_box->minHeight(); } - Length maxHeight() const { return m_box->maxHeight(); } + EFloat floating() const { return 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(); } - Length logicalWidth() const { return isHorizontalWritingMode() ? width() : height(); } - Length logicalHeight() const { return isHorizontalWritingMode() ? height() : width(); } - Length logicalMinWidth() const { return isHorizontalWritingMode() ? minWidth() : minHeight(); } - Length logicalMaxWidth() const { return isHorizontalWritingMode() ? maxWidth() : maxHeight(); } - Length logicalMinHeight() const { return isHorizontalWritingMode() ? minHeight() : minWidth(); } - Length logicalMaxHeight() const { return isHorizontalWritingMode() ? maxHeight() : maxWidth(); } + const Length& logicalWidth() const { return isHorizontalWritingMode() ? width() : height(); } + const Length& logicalHeight() const { return isHorizontalWritingMode() ? height() : width(); } + const Length& logicalMinWidth() const { return isHorizontalWritingMode() ? minWidth() : minHeight(); } + const Length& logicalMaxWidth() const { return isHorizontalWritingMode() ? maxWidth() : maxHeight(); } + 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(); } @@ -493,76 +641,74 @@ public: const NinePieceImage& borderImage() const { return surround->border.image(); } StyleImage* borderImageSource() const { return surround->border.image().image(); } - LengthBox borderImageSlices() const { return surround->border.image().imageSlices(); } - LengthBox borderImageWidth() const { return surround->border.image().borderSlices(); } - LengthBox borderImageOutset() const { return surround->border.image().outset(); } - - LengthSize borderTopLeftRadius() const { return surround->border.topLeft(); } - LengthSize borderTopRightRadius() const { return surround->border.topRight(); } - LengthSize borderBottomLeftRadius() const { return surround->border.bottomLeft(); } - LengthSize borderBottomRightRadius() const { return surround->border.bottomRight(); } + 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(); } + float 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(); } + float 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(); } + float 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(); } + float 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; + FloatBoxExtent borderWidth() const { return surround->border.borderWidth(); } - unsigned short outlineSize() const { return 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; } + 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_background->outline().style(); } OutlineIsAuto outlineStyleIsAuto() const { return static_cast<OutlineIsAuto>(m_background->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 noninherited_flags.overflowX(); } + EOverflow overflowY() const { return noninherited_flags.overflowY(); } EVisibility visibility() const { return static_cast<EVisibility>(inherited_flags._visibility); } - EVerticalAlign verticalAlign() const { return static_cast<EVerticalAlign>(noninherited_flags._vertical_align); } - Length verticalAlignLength() const { return m_box->verticalAlign(); } - - Length clipLeft() const { return visual->clip.left(); } - Length clipRight() const { return visual->clip.right(); } - Length clipTop() const { return visual->clip.top(); } - Length clipBottom() const { return visual->clip.bottom(); } - LengthBox clip() const { return visual->clip; } + EVerticalAlign verticalAlign() const { return noninherited_flags.verticalAlign(); } + const Length& verticalAlignLength() const { return m_box->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; } - EUnicodeBidi unicodeBidi() const { return static_cast<EUnicodeBidi>(noninherited_flags._unicodeBidi); } + EUnicodeBidi unicodeBidi() const { return noninherited_flags.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 noninherited_flags.clear(); } + ETableLayout tableLayout() const { return noninherited_flags.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; + std::pair<FontOrientation, NonCJKGlyphOrientation> fontAndGlyphOrientation(); #if ENABLE(TEXT_AUTOSIZING) float textAutosizingMultiplier() const { return visual->m_textAutosizingMultiplier; } #endif - Length textIndent() const { return rareInheritedData->indent; } + const Length& textIndent() const { return rareInheritedData->indent; } #if ENABLE(CSS3_TEXT) TextIndentLine textIndentLine() const { return static_cast<TextIndentLine>(rareInheritedData->m_textIndentLine); } TextIndentType textIndentType() const { return static_cast<TextIndentType>(rareInheritedData->m_textIndentType); } @@ -572,25 +718,28 @@ public: TextDecoration textDecorationsInEffect() const { return static_cast<TextDecoration>(inherited_flags._text_decorations); } TextDecoration textDecoration() const { return static_cast<TextDecoration>(visual->textDecoration); } #if ENABLE(CSS3_TEXT) - TextDecorationStyle textDecorationStyle() const { return static_cast<TextDecorationStyle>(rareNonInheritedData->m_textDecorationStyle); } TextAlignLast textAlignLast() const { return static_cast<TextAlignLast>(rareInheritedData->m_textAlignLast); } TextJustify textJustify() const { return static_cast<TextJustify>(rareInheritedData->m_textJustify); } - TextUnderlinePosition textUnderlinePosition() const { return static_cast<TextUnderlinePosition>(rareInheritedData->m_textUnderlinePosition); } -#else - TextDecorationStyle textDecorationStyle() const { return TextDecorationStyleSolid; } #endif // CSS3_TEXT - float wordSpacing() const; + 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; } + + TextZoom textZoom() const { return static_cast<TextZoom>(rareInheritedData->m_textZoom); } TextDirection direction() const { return static_cast<TextDirection>(inherited_flags._direction); } bool isLeftToRightDirection() const { return direction() == LTR; } + bool hasExplicitlySetDirection() const { return noninherited_flags.hasExplicitlySetDirection(); } - Length specifiedLineHeight() const; + const Length& specifiedLineHeight() const; Length lineHeight() const; - int computedLineHeight(RenderView* = 0) const; + int computedLineHeight() const; EWhiteSpace whiteSpace() const { return static_cast<EWhiteSpace>(inherited_flags._white_space); } static bool autoWrap(EWhiteSpace ws) @@ -654,11 +803,11 @@ public: 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()); } - Length backgroundXPosition() const { return m_background->background().xPosition(); } - Length backgroundYPosition() const { return m_background->background().yPosition(); } + 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(); } - LengthSize backgroundSizeLength() const { return m_background->background().sizeLength(); } - FillLayer* accessBackgroundLayers() { return &(m_background.access()->m_background); } + const LengthSize& backgroundSizeLength() const { return m_background->background().sizeLength(); } + FillLayer& ensureBackgroundLayers() { return m_background.access()->m_background; } const FillLayer* backgroundLayers() const { return &(m_background->background()); } StyleImage* maskImage() const { return rareNonInheritedData->m_mask.image(); } @@ -667,11 +816,11 @@ public: 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()); } - Length maskXPosition() const { return rareNonInheritedData->m_mask.xPosition(); } - Length maskYPosition() const { return rareNonInheritedData->m_mask.yPosition(); } + 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(); } - LengthSize maskSizeLength() const { return rareNonInheritedData->m_mask.sizeLength(); } - FillLayer* accessMaskLayers() { return &(rareNonInheritedData.access()->m_mask); } + const LengthSize& maskSizeLength() const { return rareNonInheritedData->m_mask.sizeLength(); } + FillLayer& ensureMaskLayers() { 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(); } @@ -686,28 +835,28 @@ public: StyleImage* listStyleImage() const; EListStylePosition listStylePosition() const { return static_cast<EListStylePosition>(inherited_flags._list_style_position); } - Length marginTop() const { return surround->margin.top(); } - Length marginBottom() const { return surround->margin.bottom(); } - Length marginLeft() const { return surround->margin.left(); } - Length marginRight() const { return surround->margin.right(); } - Length marginBefore() const { return surround->margin.before(writingMode()); } - Length marginAfter() const { return surround->margin.after(writingMode()); } - Length marginStart() const { return surround->margin.start(writingMode(), direction()); } - Length marginEnd() const { return surround->margin.end(writingMode(), direction()); } - Length marginStartUsing(const RenderStyle* otherStyle) const { return surround->margin.start(otherStyle->writingMode(), otherStyle->direction()); } - Length marginEndUsing(const RenderStyle* otherStyle) const { return surround->margin.end(otherStyle->writingMode(), otherStyle->direction()); } - Length marginBeforeUsing(const RenderStyle* otherStyle) const { return surround->margin.before(otherStyle->writingMode()); } - Length marginAfterUsing(const RenderStyle* otherStyle) const { return surround->margin.after(otherStyle->writingMode()); } - - LengthBox paddingBox() const { return surround->padding; } - Length paddingTop() const { return surround->padding.top(); } - Length paddingBottom() const { return surround->padding.bottom(); } - Length paddingLeft() const { return surround->padding.left(); } - Length paddingRight() const { return surround->padding.right(); } - Length paddingBefore() const { return surround->padding.before(writingMode()); } - Length paddingAfter() const { return surround->padding.after(writingMode()); } - Length paddingStart() const { return surround->padding.start(writingMode(), direction()); } - Length paddingEnd() const { return surround->padding.end(writingMode(), direction()); } + 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); } #if ENABLE(CURSOR_VISIBILITY) @@ -719,36 +868,32 @@ public: EInsideLink insideLink() const { return static_cast<EInsideLink>(inherited_flags._insideLink); } bool isLink() const { return noninherited_flags.isLink(); } + bool insideDefaultButton() const { return inherited_flags._insideDefaultButton; } + 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); } // CSS3 Getter Methods + BreakInside breakInside() const { return static_cast<BreakInside>(rareNonInheritedData->m_breakInside); } + BreakBetween breakBefore() const { return static_cast<BreakBetween>(rareNonInheritedData->m_breakBefore); } + BreakBetween breakAfter() const { return static_cast<BreakBetween>(rareNonInheritedData->m_breakAfter); } + + HangingPunctuation hangingPunctuation() const { return static_cast<HangingPunctuation>(rareInheritedData->m_hangingPunctuation); } - int outlineOffset() const - { - if (m_background->outline().style() == BNONE) - return 0; - return m_background->outline().offset(); - } - + float outlineOffset() const; 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); } - void getTextShadowInlineDirectionExtent(LayoutUnit& logicalLeft, LayoutUnit& logicalRight) { getShadowInlineDirectionExtent(textShadow(), logicalLeft, logicalRight); } - void getTextShadowBlockDirectionExtent(LayoutUnit& logicalTop, LayoutUnit& logicalBottom) { getShadowBlockDirectionExtent(textShadow(), logicalTop, logicalBottom); } + 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; } + AspectRatioType aspectRatioType() const { return static_cast<AspectRatioType>(rareNonInheritedData->m_aspectRatioType); } float aspectRatio() const { return aspectRatioNumerator() / aspectRatioDenominator(); } float aspectRatioDenominator() const { return rareNonInheritedData->m_aspectRatioDenominator; } float aspectRatioNumerator() const { return rareNonInheritedData->m_aspectRatioNumerator; } @@ -764,41 +909,74 @@ public: 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; } - 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); } + const Length& flexBasis() const { return rareNonInheritedData->m_flexibleBox->m_flexBasis; } + const StyleContentAlignmentData& alignContent() const { return rareNonInheritedData->m_alignContent; } + ContentPosition alignContentPosition() const { return rareNonInheritedData->m_alignContent.position(); } + ContentDistributionType alignContentDistribution() const { return rareNonInheritedData->m_alignContent.distribution(); } + OverflowAlignment alignContentOverflowAlignment() const { return rareNonInheritedData->m_alignContent.overflow(); } + const StyleSelfAlignmentData& alignItems() const { return rareNonInheritedData->m_alignItems; } + ItemPosition alignItemsPosition() const { return rareNonInheritedData->m_alignItems.position(); } + OverflowAlignment alignItemsOverflowAlignment() const { return rareNonInheritedData->m_alignItems.overflow(); } + const StyleSelfAlignmentData& alignSelf() const { return rareNonInheritedData->m_alignSelf; } + ItemPosition alignSelfPosition() const { return rareNonInheritedData->m_alignSelf.position(); } + OverflowAlignment alignSelfOverflowAlignment() const { return rareNonInheritedData->m_alignSelf.overflow(); } EFlexDirection flexDirection() const { return static_cast<EFlexDirection>(rareNonInheritedData->m_flexibleBox->m_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 StyleContentAlignmentData& justifyContent() const { return rareNonInheritedData->m_justifyContent; } + ContentPosition justifyContentPosition() const { return rareNonInheritedData->m_justifyContent.position(); } + ContentDistributionType justifyContentDistribution() const { return rareNonInheritedData->m_justifyContent.distribution(); } + OverflowAlignment justifyContentOverflowAlignment() const { return rareNonInheritedData->m_justifyContent.overflow(); } + const StyleSelfAlignmentData& justifyItems() const { return rareNonInheritedData->m_justifyItems; } + ItemPosition justifyItemsPosition() const { return rareNonInheritedData->m_justifyItems.position(); } + OverflowAlignment justifyItemsOverflowAlignment() const { return rareNonInheritedData->m_justifyItems.overflow(); } + ItemPositionType justifyItemsPositionType() const { return rareNonInheritedData->m_justifyItems.positionType(); } + const StyleSelfAlignmentData& justifySelf() const { return rareNonInheritedData->m_justifySelf; } + ItemPosition justifySelfPosition() const { return rareNonInheritedData->m_justifySelf.position(); } + OverflowAlignment justifySelfOverflowAlignment() const { return rareNonInheritedData->m_justifySelf.overflow(); } + +#if ENABLE(CSS_GRID_LAYOUT) const Vector<GridTrackSize>& gridColumns() const { return rareNonInheritedData->m_grid->m_gridColumns; } const Vector<GridTrackSize>& gridRows() const { return rareNonInheritedData->m_grid->m_gridRows; } - GridAutoFlow gridAutoFlow() const { return rareNonInheritedData->m_grid->m_gridAutoFlow; } + const NamedGridLinesMap& namedGridColumnLines() const { return rareNonInheritedData->m_grid->m_namedGridColumnLines; } + const NamedGridLinesMap& namedGridRowLines() const { return rareNonInheritedData->m_grid->m_namedGridRowLines; } + const OrderedNamedGridLinesMap& orderedNamedGridColumnLines() const { return rareNonInheritedData->m_grid->m_orderedNamedGridColumnLines; } + const OrderedNamedGridLinesMap& orderedNamedGridRowLines() const { return rareNonInheritedData->m_grid->m_orderedNamedGridRowLines; } + 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 static_cast<GridAutoFlow>(rareNonInheritedData->m_grid->m_gridAutoFlow); } + bool isGridAutoFlowDirectionRow() const { return (rareNonInheritedData->m_grid->m_gridAutoFlow & InternalAutoFlowDirectionRow); } + bool isGridAutoFlowDirectionColumn() const { return (rareNonInheritedData->m_grid->m_gridAutoFlow & InternalAutoFlowDirectionColumn); } + bool isGridAutoFlowAlgorithmSparse() const { return (rareNonInheritedData->m_grid->m_gridAutoFlow & InternalAutoFlowAlgorithmSparse); } + bool isGridAutoFlowAlgorithmDense() const { return (rareNonInheritedData->m_grid->m_gridAutoFlow & InternalAutoFlowAlgorithmDense); } const GridTrackSize& gridAutoColumns() const { return rareNonInheritedData->m_grid->m_gridAutoColumns; } const GridTrackSize& gridAutoRows() const { return rareNonInheritedData->m_grid->m_gridAutoRows; } + const Length& gridColumnGap() const { return rareNonInheritedData->m_grid->m_gridColumnGap; } + const Length& gridRowGap() const { return rareNonInheritedData->m_grid->m_gridRowGap; } + - const GridPosition& gridItemStart() const { return rareNonInheritedData->m_gridItem->m_gridStart; } - const GridPosition& gridItemEnd() const { return rareNonInheritedData->m_gridItem->m_gridEnd; } - const GridPosition& gridItemBefore() const { return rareNonInheritedData->m_gridItem->m_gridBefore; } - const GridPosition& gridItemAfter() const { return rareNonInheritedData->m_gridItem->m_gridAfter; } + 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; } +#endif /* ENABLE(CSS_GRID_LAYOUT) */ const ShadowData* boxShadow() const { return rareNonInheritedData->m_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); } void getBoxShadowVerticalExtent(LayoutUnit& top, LayoutUnit& bottom) const { getShadowVerticalExtent(boxShadow(), top, bottom); } - void getBoxShadowInlineDirectionExtent(LayoutUnit& logicalLeft, LayoutUnit& logicalRight) { getShadowInlineDirectionExtent(boxShadow(), logicalLeft, logicalRight); } - void getBoxShadowBlockDirectionExtent(LayoutUnit& logicalTop, LayoutUnit& logicalBottom) { getShadowBlockDirectionExtent(boxShadow(), logicalTop, logicalBottom); } + void getBoxShadowInlineDirectionExtent(LayoutUnit& logicalLeft, LayoutUnit& logicalRight) const { getShadowInlineDirectionExtent(boxShadow(), logicalLeft, logicalRight); } + void getBoxShadowBlockDirectionExtent(LayoutUnit& logicalTop, LayoutUnit& logicalBottom) const { getShadowBlockDirectionExtent(boxShadow(), logicalTop, logicalBottom); } #if ENABLE(CSS_BOX_DECORATION_BREAK) EBoxDecorationBreak boxDecorationBreak() const { return m_box->boxDecorationBreak(); } #endif StyleReflection* boxReflect() const { return rareNonInheritedData->m_boxReflect.get(); } EBoxSizing boxSizing() const { return m_box->boxSizing(); } - Length marqueeIncrement() const { return rareNonInheritedData->m_marquee->increment; } + 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); } @@ -813,15 +991,14 @@ public: 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; } + const AtomicString& locale() const { return fontDescription().locale(); } EBorderFit borderFit() const { return static_cast<EBorderFit>(rareNonInheritedData->m_borderFit); } - EResize resize() const { return static_cast<EResize>(rareInheritedData->resize); } + EResize resize() const { return static_cast<EResize>(rareNonInheritedData->m_resize); } ColumnAxis columnAxis() const { return static_cast<ColumnAxis>(rareNonInheritedData->m_multiCol->m_axis); } bool hasInlineColumnAxis() const { ColumnAxis axis = columnAxis(); @@ -833,21 +1010,17 @@ public: unsigned short columnCount() const { return rareNonInheritedData->m_multiCol->m_count; } bool hasAutoColumnCount() const { return rareNonInheritedData->m_multiCol->m_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; } - Length transformOriginX() const { return rareNonInheritedData->m_transform->m_x; } - Length transformOriginY() const { return rareNonInheritedData->m_transform->m_y; } + 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(); } @@ -860,13 +1033,14 @@ public: RubyPosition rubyPosition() const { return static_cast<RubyPosition>(rareInheritedData->m_rubyPosition); } TextOrientation textOrientation() const { return static_cast<TextOrientation>(rareInheritedData->m_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 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); @@ -879,7 +1053,9 @@ public: // End CSS3 Getters + bool hasFlowInto() const { return !rareNonInheritedData->m_flowThread.isNull(); } 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); } @@ -887,16 +1063,18 @@ public: LineSnap lineSnap() const { return static_cast<LineSnap>(rareInheritedData->m_lineSnap); } LineAlign lineAlign() const { return static_cast<LineAlign>(rareInheritedData->m_lineAlign); } - WrapFlow wrapFlow() const { return static_cast<WrapFlow>(rareNonInheritedData->m_wrapFlow); } - WrapThrough wrapThrough() const { return static_cast<WrapThrough>(rareNonInheritedData->m_wrapThrough); } - // 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* accessAnimations(); - AnimationList* accessTransitions(); + AnimationList* animations() { return rareNonInheritedData->m_animations.get(); } + AnimationList* transitions() { return rareNonInheritedData->m_transitions.get(); } + + bool hasAnimationsOrTransitions() const { return rareNonInheritedData->hasAnimationsOrTransitions(); } + + 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; } @@ -910,34 +1088,63 @@ public: 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; } - Length perspectiveOriginX() const { return rareNonInheritedData->m_perspectiveOriginX; } - Length perspectiveOriginY() const { return rareNonInheritedData->m_perspectiveOriginY; } - LengthSize pageSize() const { return rareNonInheritedData->m_pageSize; } + 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); } -#if USE(ACCELERATED_COMPOSITING) // When set, this ensures that styles compare as different. Used during accelerated animations. bool isRunningAcceleratedAnimation() const { return rareNonInheritedData->m_runningAcceleratedAnimation; } -#endif LineBoxContain lineBoxContain() const { return rareInheritedData->m_lineBoxContain; } const LineClampValue& lineClamp() const { return rareNonInheritedData->lineClamp; } + const IntSize& initialLetter() const { return rareNonInheritedData->m_initialLetter; } + int initialLetterDrop() const { return initialLetter().width(); } + int initialLetterHeight() const { return initialLetter().height(); } + +#if ENABLE(TOUCH_EVENTS) + TouchAction touchAction() const { return static_cast<TouchAction>(rareNonInheritedData->m_touchAction); } +#endif + +#if ENABLE(CSS_SCROLL_SNAP) + ScrollSnapType scrollSnapType() const { return static_cast<ScrollSnapType>(rareNonInheritedData->m_scrollSnapType); } + const ScrollSnapPoints* scrollSnapPointsX() const; + const ScrollSnapPoints* scrollSnapPointsY() const; + const LengthSize& scrollSnapDestination() const; + WEBCORE_EXPORT const Vector<LengthSize>& scrollSnapCoordinates() const; +#endif + #if ENABLE(TOUCH_EVENTS) Color tapHighlightColor() const { return rareInheritedData->tapHighlightColor; } #endif + +#if PLATFORM(IOS) + bool touchCalloutEnabled() const { return rareInheritedData->touchCalloutEnabled; } +#endif + #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) bool useTouchOverflowScrolling() const { return rareInheritedData->useTouchOverflowScrolling; } #endif + +#if ENABLE(IOS_TEXT_AUTOSIZING) + TextSizeAdjustment textSizeAdjust() const { return rareInheritedData->textSizeAdjust; } +#endif + ETextSecurity textSecurity() const { return static_cast<ETextSecurity>(rareInheritedData->textSecurity); } WritingMode writingMode() const { return static_cast<WritingMode>(inherited_flags.m_writingMode); } bool isHorizontalWritingMode() const { return WebCore::isHorizontalWritingMode(writingMode()); } bool isFlippedLinesWritingMode() const { return WebCore::isFlippedLinesWritingMode(writingMode()); } - bool isFlippedBlocksWritingMode() const { return WebCore::isFlippedBlocksWritingMode(writingMode()); } + bool isFlippedBlocksWritingMode() const { return WebCore::isFlippedWritingMode(writingMode()); } + ImageOrientationEnum imageOrientation() const + { #if ENABLE(CSS_IMAGE_ORIENTATION) - ImageOrientationEnum imageOrientation() const { return static_cast<ImageOrientationEnum>(rareInheritedData->m_imageOrientation); } + return static_cast<ImageOrientationEnum>(rareInheritedData->m_imageOrientation); +#else + return DefaultImageOrientation; #endif + } EImageRendering imageRendering() const { return static_cast<EImageRendering>(rareInheritedData->m_imageRendering); } @@ -949,20 +1156,33 @@ public: ESpeak speak() const { return static_cast<ESpeak>(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(); } + bool hasReferenceFilterOnly() const; + +#if ENABLE(FILTERS_LEVEL_2) + FilterOperations& mutableBackdropFilter() { return rareNonInheritedData.access()->m_backdropFilter.access()->m_operations; } + const FilterOperations& backdropFilter() const { return rareNonInheritedData->m_backdropFilter->m_operations; } + bool hasBackdropFilter() const { return !rareNonInheritedData->m_backdropFilter->m_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; } + void setBlendMode(BlendMode blendMode) { SET_VAR(rareNonInheritedData, m_effectiveBlendMode, blendMode); } bool hasBlendMode() const { return static_cast<BlendMode>(rareNonInheritedData->m_effectiveBlendMode) != BlendModeNormal; } + + Isolation isolation() const { return static_cast<Isolation>(rareNonInheritedData->m_isolation); } + void setIsolation(Isolation isolation) { SET_VAR(rareNonInheritedData, m_isolation, isolation); } + bool hasIsolation() const { return rareNonInheritedData->m_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) @@ -970,44 +1190,50 @@ public: #else bool shouldPlaceBlockDirectionScrollbarOnLogicalLeft() const { return false; } #endif - + +#if ENABLE(CSS_TRAILING_WORD) + TrailingWord trailingWord() const { return static_cast<TrailingWord>(rareInheritedData->trailingWord); } +#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 setDisplay(EDisplay v) { noninherited_flags.setEffectiveDisplay(v); } + void setOriginalDisplay(EDisplay v) { noninherited_flags.setOriginalDisplay(v); } + void setPosition(EPosition v) { noninherited_flags.setPosition(v); } + void setFloating(EFloat v) { noninherited_flags.setFloating(v); } - void setLeft(Length v) { SET_VAR(surround, offset.m_left, v); } - void setRight(Length v) { SET_VAR(surround, offset.m_right, v); } - void setTop(Length v) { SET_VAR(surround, offset.m_top, v); } - void setBottom(Length v) { SET_VAR(surround, offset.m_bottom, v); } + void setLeft(Length v) { SET_VAR(surround, offset.left(), WTFMove(v)); } + void setRight(Length v) { SET_VAR(surround, offset.right(), WTFMove(v)); } + void setTop(Length v) { SET_VAR(surround, offset.top(), WTFMove(v)); } + void setBottom(Length v) { SET_VAR(surround, offset.bottom(), WTFMove(v)); } - void setWidth(Length v) { SET_VAR(m_box, m_width, v); } - void setHeight(Length v) { SET_VAR(m_box, m_height, v); } + void setWidth(Length v) { SET_VAR(m_box, m_width, WTFMove(v)); } + void setHeight(Length v) { SET_VAR(m_box, m_height, WTFMove(v)); } void setLogicalWidth(Length v) { if (isHorizontalWritingMode()) { - SET_VAR(m_box, m_width, v); + SET_VAR(m_box, m_width, WTFMove(v)); } else { - SET_VAR(m_box, m_height, v); + SET_VAR(m_box, m_height, WTFMove(v)); } } void setLogicalHeight(Length v) { if (isHorizontalWritingMode()) { - SET_VAR(m_box, m_height, v); + SET_VAR(m_box, m_height, WTFMove(v)); } else { - SET_VAR(m_box, m_width, v); + SET_VAR(m_box, m_width, WTFMove(v)); } } - void setMinWidth(Length v) { SET_VAR(m_box, m_minWidth, v); } - void setMaxWidth(Length v) { SET_VAR(m_box, m_maxWidth, v); } - void setMinHeight(Length v) { SET_VAR(m_box, m_minHeight, v); } - void setMaxHeight(Length v) { SET_VAR(m_box, m_maxHeight, v); } + void setMinWidth(Length v) { SET_VAR(m_box, m_minWidth, WTFMove(v)); } + void setMaxWidth(Length v) { SET_VAR(m_box, m_maxWidth, WTFMove(v)); } + void setMinHeight(Length v) { SET_VAR(m_box, m_minHeight, WTFMove(v)); } + void setMaxHeight(Length v) { SET_VAR(m_box, m_maxHeight, WTFMove(v)); } #if ENABLE(DASHBOARD_SUPPORT) Vector<StyleDashboardRegion> dashboardRegions() const { return rareNonInheritedData->m_dashboardRegions; } @@ -1017,10 +1243,10 @@ public: { StyleDashboardRegion region; region.label = label; - region.offset.m_top = t; - region.offset.m_right = r; - region.offset.m_bottom = b; - region.offset.m_left = l; + region.offset.top() = WTFMove(t); + region.offset.right() = WTFMove(r); + region.offset.bottom() = WTFMove(b); + region.offset.left() = WTFMove(l); region.type = type; if (!append) rareNonInheritedData.access()->m_dashboardRegions.clear(); @@ -1028,11 +1254,6 @@ public: } #endif -#if ENABLE(DRAGGABLE_REGION) - DraggableRegionMode getDraggableRegionMode() const { return rareNonInheritedData->m_draggableRegionMode; } - void setDraggableRegionMode(DraggableRegionMode v) { SET_VAR(rareNonInheritedData, m_draggableRegionMode, v); } -#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()); } @@ -1047,10 +1268,10 @@ public: void setBackgroundColor(const Color& v) { SET_VAR(m_background, m_color, v); } - void setBackgroundXPosition(Length length) { SET_VAR(m_background, m_background.m_xPosition, length); } - void setBackgroundYPosition(Length length) { SET_VAR(m_background, m_background.m_yPosition, length); } + void setBackgroundXPosition(Length length) { SET_VAR(m_background, m_background.m_xPosition, WTFMove(length)); } + void setBackgroundYPosition(Length length) { SET_VAR(m_background, m_background.m_yPosition, WTFMove(length)); } void setBackgroundSize(EFillSizeType b) { SET_VAR(m_background, m_background.m_sizeType, b); } - void setBackgroundSizeLength(LengthSize s) { SET_VAR(m_background, m_background.m_sizeLength, s); } + void setBackgroundSizeLength(LengthSize size) { SET_VAR(m_background, m_background.m_sizeLength, WTFMove(size)); } void setBorderImage(const NinePieceImage& b) { SET_VAR(surround, border.m_image, b); } void setBorderImageSource(PassRefPtr<StyleImage>); @@ -1058,10 +1279,10 @@ public: void setBorderImageWidth(LengthBox); void setBorderImageOutset(LengthBox); - void setBorderTopLeftRadius(LengthSize s) { SET_VAR(surround, border.m_topLeft, s); } - void setBorderTopRightRadius(LengthSize s) { SET_VAR(surround, border.m_topRight, s); } - void setBorderBottomLeftRadius(LengthSize s) { SET_VAR(surround, border.m_bottomLeft, s); } - void setBorderBottomRightRadius(LengthSize s) { SET_VAR(surround, border.m_bottomRight, s); } + void setBorderTopLeftRadius(LengthSize size) { SET_VAR(surround, border.m_topLeft, WTFMove(size)); } + void setBorderTopRightRadius(LengthSize size) { SET_VAR(surround, border.m_topRight, WTFMove(size)); } + void setBorderBottomLeftRadius(LengthSize size) { SET_VAR(surround, border.m_bottomLeft, WTFMove(size)); } + void setBorderBottomRightRadius(LengthSize size) { SET_VAR(surround, border.m_bottomRight, WTFMove(size)); } void setBorderRadius(LengthSize s) { @@ -1075,50 +1296,50 @@ public: setBorderRadius(LengthSize(Length(s.width(), Fixed), Length(s.height(), Fixed))); } - RoundedRect getRoundedBorderFor(const LayoutRect& borderRect, RenderView* = 0, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const; + 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; + RoundedRect getRoundedInnerBorderFor(const LayoutRect& borderRect, LayoutUnit topWidth, LayoutUnit bottomWidth, + LayoutUnit leftWidth, LayoutUnit rightWidth, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const; - void setBorderLeftWidth(unsigned v) { SET_VAR(surround, border.m_left.m_width, v); } + void setBorderLeftWidth(float 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 setBorderRightWidth(float 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 setBorderTopWidth(float 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 setBorderBottomWidth(float 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 setOutlineWidth(float 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 setOverflowX(EOverflow v) { noninherited_flags.setOverflowX(v); } + void setOverflowY(EOverflow v) { noninherited_flags.setOverflowY(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, length); } + void setVerticalAlign(EVerticalAlign v) { noninherited_flags.setVerticalAlign(v); } + void setVerticalAlignLength(Length length) { setVerticalAlign(LENGTH); SET_VAR(m_box, m_verticalAlign, WTFMove(length)); } void setHasClip(bool b = true) { SET_VAR(visual, hasClip, b); } - void setClipLeft(Length v) { SET_VAR(visual, clip.m_left, v); } - void setClipRight(Length v) { SET_VAR(visual, clip.m_right, v); } - void setClipTop(Length v) { SET_VAR(visual, clip.m_top, v); } - void setClipBottom(Length v) { SET_VAR(visual, clip.m_bottom, v); } + void setClipLeft(Length length) { SET_VAR(visual, clip.left(), WTFMove(length)); } + void setClipRight(Length length) { SET_VAR(visual, clip.right(), WTFMove(length)); } + void setClipTop(Length length) { SET_VAR(visual, clip.top(), WTFMove(length)); } + void setClipBottom(Length length) { SET_VAR(visual, clip.bottom(), WTFMove(length)); } void setClip(Length top, Length right, Length bottom, Length left); - void setClip(LengthBox box) { SET_VAR(visual, clip, box); } + void setClip(LengthBox box) { SET_VAR(visual, clip, WTFMove(box)); } - void setUnicodeBidi(EUnicodeBidi b) { noninherited_flags._unicodeBidi = b; } + void setUnicodeBidi(EUnicodeBidi b) { noninherited_flags.setUnicodeBidi(b); } - void setClear(EClear v) { noninherited_flags._clear = v; } - void setTableLayout(ETableLayout v) { noninherited_flags._table_layout = v; } + void setClear(EClear v) { noninherited_flags.setClear(v); } + void setTableLayout(ETableLayout v) { noninherited_flags.setTableLayout(v); } - bool setFontDescription(const FontDescription&); + bool setFontDescription(const FontCascadeDescription&); // Only used for blending font sizes when animating, for MathML anonymous blocks, and for text autosizing. void setFontSize(float); @@ -1131,7 +1352,7 @@ public: #endif void setColor(const Color&); - void setTextIndent(Length v) { SET_VAR(rareInheritedData, indent, v); } + void setTextIndent(Length length) { SET_VAR(rareInheritedData, indent, WTFMove(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); } @@ -1142,17 +1363,23 @@ public: void setTextDecorationsInEffect(TextDecoration v) { inherited_flags._text_decorations = v; } void setTextDecoration(TextDecoration v) { SET_VAR(visual, textDecoration, v); } #if ENABLE(CSS3_TEXT) - void setTextDecorationStyle(TextDecorationStyle v) { SET_VAR(rareNonInheritedData, m_textDecorationStyle, v); } void setTextAlignLast(TextAlignLast v) { SET_VAR(rareInheritedData, m_textAlignLast, v); } void setTextJustify(TextJustify v) { SET_VAR(rareInheritedData, m_textJustify, v); } +#endif + 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); } -#endif // CSS3_TEXT void setDirection(TextDirection v) { inherited_flags._direction = v; } + void setHasExplicitlySetDirection(bool v) { noninherited_flags.setHasExplicitlySetDirection(v); } +#if ENABLE(IOS_TEXT_AUTOSIZING) + void setSpecifiedLineHeight(Length v); +#endif void setLineHeight(Length specifiedLineHeight); bool setZoom(float); void setZoomWithoutReturnValue(float f) { setZoom(f); } bool setEffectiveZoom(float); - + void setTextZoom(TextZoom v) { SET_VAR(rareInheritedData, m_textZoom, v); } + #if ENABLE(CSS_IMAGE_ORIENTATION) void setImageOrientation(ImageOrientationEnum v) { SET_VAR(rareInheritedData, m_imageOrientation, static_cast<int>(v)); } #endif @@ -1167,7 +1394,7 @@ public: void setWhiteSpace(EWhiteSpace v) { inherited_flags._white_space = v; } - void setWordSpacing(float); + void setWordSpacing(Length); void setLetterSpacing(float); void clearBackgroundLayers() { m_background.access()->m_background = FillLayer(BackgroundFillLayer); } @@ -1176,8 +1403,8 @@ public: void adjustBackgroundLayers() { if (backgroundLayers()->next()) { - accessBackgroundLayers()->cullEmptyLayers(); - accessBackgroundLayers()->fillUnsetProperties(); + ensureBackgroundLayers().cullEmptyLayers(); + ensureBackgroundLayers().fillUnsetProperties(); } } @@ -1187,8 +1414,8 @@ public: void adjustMaskLayers() { if (maskLayers()->next()) { - accessMaskLayers()->cullEmptyLayers(); - accessMaskLayers()->fillUnsetProperties(); + ensureMaskLayers().cullEmptyLayers(); + ensureMaskLayers().fillUnsetProperties(); } } @@ -1196,9 +1423,9 @@ public: 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, length); } - void setMaskYPosition(Length length) { SET_VAR(rareNonInheritedData, m_mask.m_yPosition, length); } - void setMaskSize(LengthSize s) { SET_VAR(rareNonInheritedData, m_mask.m_sizeLength, s); } + void setMaskXPosition(Length length) { SET_VAR(rareNonInheritedData, m_mask.m_xPosition, WTFMove(length)); } + void setMaskYPosition(Length length) { SET_VAR(rareNonInheritedData, m_mask.m_yPosition, WTFMove(length)); } + void setMaskSize(LengthSize size) { SET_VAR(rareNonInheritedData, m_mask.m_sizeLength, WTFMove(size)); } void setBorderCollapse(EBorderCollapse collapse) { inherited_flags._border_collapse = collapse; } void setHorizontalBorderSpacing(short); @@ -1206,7 +1433,7 @@ public: 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 setAspectRatioType(AspectRatioType aspectRatioType) { SET_VAR(rareNonInheritedData, m_aspectRatioType, aspectRatioType); } void setAspectRatioDenominator(float v) { SET_VAR(rareNonInheritedData, m_aspectRatioDenominator, v); } void setAspectRatioNumerator(float v) { SET_VAR(rareNonInheritedData, m_aspectRatioNumerator, v); } @@ -1215,19 +1442,19 @@ public: void setListStylePosition(EListStylePosition v) { inherited_flags._list_style_position = v; } void resetMargin() { SET_VAR(surround, margin, LengthBox(Fixed)); } - void setMarginTop(Length v) { SET_VAR(surround, margin.m_top, v); } - void setMarginBottom(Length v) { SET_VAR(surround, margin.m_bottom, v); } - void setMarginLeft(Length v) { SET_VAR(surround, margin.m_left, v); } - void setMarginRight(Length v) { SET_VAR(surround, margin.m_right, v); } + void setMarginTop(Length length) { SET_VAR(surround, margin.top(), WTFMove(length)); } + void setMarginBottom(Length length) { SET_VAR(surround, margin.bottom(), WTFMove(length)); } + void setMarginLeft(Length length) { SET_VAR(surround, margin.left(), WTFMove(length)); } + void setMarginRight(Length length) { SET_VAR(surround, margin.right(), WTFMove(length)); } void setMarginStart(Length); void setMarginEnd(Length); void resetPadding() { SET_VAR(surround, padding, LengthBox(Auto)); } - void setPaddingBox(const LengthBox& b) { SET_VAR(surround, padding, b); } - void setPaddingTop(Length v) { SET_VAR(surround, padding.m_top, v); } - void setPaddingBottom(Length v) { SET_VAR(surround, padding.m_bottom, v); } - void setPaddingLeft(Length v) { SET_VAR(surround, padding.m_left, v); } - void setPaddingRight(Length v) { SET_VAR(surround, padding.m_right, v); } + void setPaddingBox(LengthBox box) { SET_VAR(surround, padding, WTFMove(box)); } + void setPaddingTop(Length length) { SET_VAR(surround, padding.top(), WTFMove(length)); } + void setPaddingBottom(Length length) { SET_VAR(surround, padding.bottom(), WTFMove(length)); } + void setPaddingLeft(Length length) { SET_VAR(surround, padding.left(), WTFMove(length)); } + void setPaddingRight(Length length) { SET_VAR(surround, padding.right(), WTFMove(length)); } void setCursor(ECursor c) { inherited_flags._cursor_style = c; } void addCursor(PassRefPtr<StyleImage>, const IntPoint& hotSpot = IntPoint()); @@ -1241,6 +1468,8 @@ public: void setInsideLink(EInsideLink insideLink) { inherited_flags._insideLink = insideLink; } void setIsLink(bool b) { noninherited_flags.setIsLink(b); } + void setInsideDefaultButton(bool insideDefaultButton) { inherited_flags._insideDefaultButton = insideDefaultButton; } + PrintColorAdjust printColorAdjust() const { return static_cast<PrintColorAdjust>(inherited_flags.m_printColorAdjust); } void setPrintColorAdjust(PrintColorAdjust value) { inherited_flags.m_printColorAdjust = value; } @@ -1255,60 +1484,81 @@ public: 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); } - // 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; } - // CSS3 Setters - void setOutlineOffset(int v) { SET_VAR(m_background, m_outline.m_offset, v); } - void setTextShadow(PassOwnPtr<ShadowData>, bool add = false); + void setOutlineOffset(float v) { SET_VAR(m_background, m_outline.m_offset, v); } + void setTextShadow(std::unique_ptr<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); } // 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(rareNonInheritedData, m_deprecatedFlexibleBox, align, a); } #if ENABLE(CSS_BOX_DECORATION_BREAK) void setBoxDecorationBreak(EBoxDecorationBreak b) { SET_VAR(m_box, 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 setBoxFlex(float f) { SET_NESTED_VAR(rareNonInheritedData, m_deprecatedFlexibleBox, flex, f); } + void setBoxFlexGroup(unsigned int fg) { SET_NESTED_VAR(rareNonInheritedData, m_deprecatedFlexibleBox, flex_group, fg); } + void setBoxLines(EBoxLines l) { SET_NESTED_VAR(rareNonInheritedData, m_deprecatedFlexibleBox, lines, l); } + void setBoxOrdinalGroup(unsigned int og) { SET_NESTED_VAR(rareNonInheritedData, m_deprecatedFlexibleBox, ordinal_group, og); } + void setBoxOrient(EBoxOrient o) { SET_NESTED_VAR(rareNonInheritedData, m_deprecatedFlexibleBox, orient, o); } + void setBoxPack(EBoxPack p) { SET_NESTED_VAR(rareNonInheritedData, m_deprecatedFlexibleBox, pack, p); } + void setBoxShadow(std::unique_ptr<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, length); } + void setFlexGrow(float f) { SET_NESTED_VAR(rareNonInheritedData, m_flexibleBox, m_flexGrow, f); } + void setFlexShrink(float f) { SET_NESTED_VAR(rareNonInheritedData, m_flexibleBox, m_flexShrink, f); } + void setFlexBasis(Length length) { SET_NESTED_VAR(rareNonInheritedData, m_flexibleBox, m_flexBasis, WTFMove(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 setGridAutoFlow(GridAutoFlow flow) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridAutoFlow, flow); } - void setGridItemStart(const GridPosition& startPosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridStart, startPosition); } - void setGridItemEnd(const GridPosition& endPosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridEnd, endPosition); } - void setGridItemBefore(const GridPosition& beforePosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridBefore, beforePosition); } - void setGridItemAfter(const GridPosition& afterPosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridAfter, afterPosition); } - - void setMarqueeIncrement(Length f) { SET_VAR(rareNonInheritedData.access()->m_marquee, increment, f); } - 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 setAlignContent(const StyleContentAlignmentData& data) { SET_VAR(rareNonInheritedData, m_alignContent, data); } + void setAlignContentPosition(ContentPosition position) { rareNonInheritedData.access()->m_alignContent.setPosition(position); } + void setAlignContentOverflow(OverflowAlignment overflow) { rareNonInheritedData.access()->m_alignContent.setOverflow(overflow); } + void setAlignContentDistribution(ContentDistributionType distribution) { rareNonInheritedData.access()->m_alignContent.setDistribution(distribution); } + void setAlignItems(const StyleSelfAlignmentData& data) { SET_VAR(rareNonInheritedData, m_alignItems, data); } + void setAlignItemsPosition(ItemPosition position) { rareNonInheritedData.access()->m_alignItems.setPosition(position); } + void setAlignItemsOverflow(OverflowAlignment overflow) { rareNonInheritedData.access()->m_alignItems.setOverflow(overflow); } + void setAlignSelf(const StyleSelfAlignmentData& data) { SET_VAR(rareNonInheritedData, m_alignSelf, data); } + void setAlignSelfPosition(ItemPosition position) { rareNonInheritedData.access()->m_alignSelf.setPosition(position); } + void setAlignSelfOverflow(OverflowAlignment overflow) { rareNonInheritedData.access()->m_alignSelf.setOverflow(overflow); } + void setFlexDirection(EFlexDirection direction) { SET_NESTED_VAR(rareNonInheritedData, m_flexibleBox, m_flexDirection, direction); } + void setFlexWrap(EFlexWrap w) { SET_NESTED_VAR(rareNonInheritedData, m_flexibleBox, m_flexWrap, w); } + void setJustifyContent(const StyleContentAlignmentData& data) { SET_VAR(rareNonInheritedData, m_justifyContent, data); } + void setJustifyContentPosition(ContentPosition position) { rareNonInheritedData.access()->m_justifyContent.setPosition(position); } + void setJustifyContentOverflow(OverflowAlignment overflow) { rareNonInheritedData.access()->m_justifyContent.setOverflow(overflow); } + void setJustifyContentDistribution(ContentDistributionType distribution) { rareNonInheritedData.access()->m_justifyContent.setDistribution(distribution); } + void setJustifyItems(const StyleSelfAlignmentData& data) { SET_VAR(rareNonInheritedData, m_justifyItems, data); } + void setJustifyItemsPosition(ItemPosition position) { rareNonInheritedData.access()->m_justifyItems.setPosition(position); } + void setJustifyItemsOverflow(OverflowAlignment overflow) { rareNonInheritedData.access()->m_justifyItems.setOverflow(overflow); } + void setJustifyItemsPositionType(ItemPositionType positionType) { rareNonInheritedData.access()->m_justifyItems.setPositionType(positionType); } + void setJustifySelf(const StyleSelfAlignmentData& data) { SET_VAR(rareNonInheritedData, m_justifySelf, data); } + void setJustifySelfPosition(ItemPosition position) { rareNonInheritedData.access()->m_justifySelf.setPosition(position); } + void setJustifySelfOverflow(OverflowAlignment overflow) { rareNonInheritedData.access()->m_justifySelf.setOverflow(overflow); } +#if ENABLE(CSS_GRID_LAYOUT) + void setGridAutoColumns(const GridTrackSize& length) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridAutoColumns, length); } + void setGridAutoRows(const GridTrackSize& length) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridAutoRows, length); } + void setGridColumns(const Vector<GridTrackSize>& lengths) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridColumns, lengths); } + void setGridRows(const Vector<GridTrackSize>& lengths) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridRows, lengths); } + void setNamedGridColumnLines(const NamedGridLinesMap& namedGridColumnLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_namedGridColumnLines, namedGridColumnLines); } + void setNamedGridRowLines(const NamedGridLinesMap& namedGridRowLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_namedGridRowLines, namedGridRowLines); } + void setOrderedNamedGridColumnLines(const OrderedNamedGridLinesMap& orderedNamedGridColumnLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_orderedNamedGridColumnLines, orderedNamedGridColumnLines); } + void setOrderedNamedGridRowLines(const OrderedNamedGridLinesMap& orderedNamedGridRowLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_orderedNamedGridRowLines, orderedNamedGridRowLines); } + void setNamedGridArea(const NamedGridAreaMap& namedGridArea) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_namedGridArea, namedGridArea); } + void setNamedGridAreaRowCount(size_t rowCount) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_namedGridAreaRowCount, rowCount); } + void setNamedGridAreaColumnCount(size_t columnCount) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_namedGridAreaColumnCount, columnCount); } + void setGridAutoFlow(GridAutoFlow flow) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridAutoFlow, flow); } + void setGridItemColumnStart(const GridPosition& columnStartPosition) { SET_NESTED_VAR(rareNonInheritedData, m_gridItem, m_gridColumnStart, columnStartPosition); } + void setGridItemColumnEnd(const GridPosition& columnEndPosition) { SET_NESTED_VAR(rareNonInheritedData, m_gridItem, m_gridColumnEnd, columnEndPosition); } + void setGridItemRowStart(const GridPosition& rowStartPosition) { SET_NESTED_VAR(rareNonInheritedData, m_gridItem, m_gridRowStart, rowStartPosition); } + void setGridItemRowEnd(const GridPosition& rowEndPosition) { SET_NESTED_VAR(rareNonInheritedData, m_gridItem, m_gridRowEnd, rowEndPosition); } + void setGridColumnGap(const Length& v) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridColumnGap, v); } + void setGridRowGap(const Length& v) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridRowGap, v); } +#endif /* ENABLE(CSS_GRID_LAYOUT) */ + void setMarqueeIncrement(Length length) { SET_NESTED_VAR(rareNonInheritedData, m_marquee, increment, WTFMove(length)); } + void setMarqueeSpeed(int f) { SET_NESTED_VAR(rareNonInheritedData, m_marquee, speed, f); } + void setMarqueeDirection(EMarqueeDirection d) { SET_NESTED_VAR(rareNonInheritedData, m_marquee, direction, d); } + void setMarqueeBehavior(EMarqueeBehavior b) { SET_NESTED_VAR(rareNonInheritedData, m_marquee, behavior, b); } + void setMarqueeLoopCount(int i) { SET_NESTED_VAR(rareNonInheritedData, 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); } @@ -1319,45 +1569,35 @@ public: 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 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 setResize(EResize r) { SET_VAR(rareNonInheritedData, m_resize, r); } + void setColumnAxis(ColumnAxis axis) { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_axis, axis); } + void setColumnProgression(ColumnProgression progression) { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_progression, progression); } + void setColumnWidth(float f) { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_autoWidth, false); SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_width, f); } + void setHasAutoColumnWidth() { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_autoWidth, true); SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_width, 0); } + void setColumnCount(unsigned short c) { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_autoCount, false); SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_count, c); } + void setHasAutoColumnCount() { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_autoCount, true); SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_count, 0); } + void setColumnFill(ColumnFill columnFill) { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_fill, columnFill); } + void setColumnGap(float f) { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_normalGap, false); SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_gap, f); } + void setHasNormalColumnGap() { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_normalGap, true); SET_NESTED_VAR(rareNonInheritedData, 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 setColumnRuleStyle(EBorderStyle b) { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_rule.m_style, b); } + void setColumnRuleWidth(unsigned short w) { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_rule.m_width, w); } + void resetColumnRule() { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_rule, BorderValue()); } + void setColumnSpan(ColumnSpan columnSpan) { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_columnSpan, columnSpan); } 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 l) { SET_VAR(rareNonInheritedData.access()->m_transform, m_x, l); } - void setTransformOriginY(Length l) { SET_VAR(rareNonInheritedData.access()->m_transform, m_y, l); } - void setTransformOriginZ(float f) { SET_VAR(rareNonInheritedData.access()->m_transform, m_z, f); } + void setTransform(const TransformOperations& ops) { SET_NESTED_VAR(rareNonInheritedData, m_transform, m_operations, ops); } + void setTransformOriginX(Length length) { SET_NESTED_VAR(rareNonInheritedData, m_transform, m_x, WTFMove(length)); } + void setTransformOriginY(Length length) { SET_NESTED_VAR(rareNonInheritedData, m_transform, m_y, WTFMove(length)); } + void setTransformOriginZ(float f) { SET_NESTED_VAR(rareNonInheritedData, m_transform, m_z, f); } void setSpeak(ESpeak s) { SET_VAR(rareInheritedData, speak, s); } void setTextCombine(TextCombine v) { SET_VAR(rareNonInheritedData, m_textCombine, v); } -#if ENABLE(CSS3_TEXT) void setTextDecorationColor(const Color& c) { SET_VAR(rareNonInheritedData, m_textDecorationColor, c); } -#endif // CSS3_TEXT 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); } @@ -1365,14 +1605,23 @@ public: void setTextEmphasisPosition(TextEmphasisPosition position) { SET_VAR(rareInheritedData, textEmphasisPosition, position); } bool setTextOrientation(TextOrientation); + void setObjectFit(ObjectFit fit) { SET_VAR(rareNonInheritedData, m_objectFit, fit); } + void setRubyPosition(RubyPosition position) { SET_VAR(rareInheritedData, m_rubyPosition, position); } -#if ENABLE(CSS_FILTERS) - void setFilter(const FilterOperations& ops) { SET_VAR(rareNonInheritedData.access()->m_filter, m_operations, ops); } + void setFilter(const FilterOperations& ops) { SET_NESTED_VAR(rareNonInheritedData, m_filter, m_operations, ops); } +#if ENABLE(FILTERS_LEVEL_2) + void setBackdropFilter(const FilterOperations& ops) { SET_NESTED_VAR(rareNonInheritedData, m_backdropFilter, m_operations, ops); } #endif void setTabSize(unsigned size) { SET_VAR(rareInheritedData, m_tabSize, size); } + void setBreakBefore(BreakBetween breakBehavior) { SET_VAR(rareNonInheritedData, m_breakBefore, breakBehavior); } + void setBreakAfter(BreakBetween breakBehavior) { SET_VAR(rareNonInheritedData, m_breakAfter, breakBehavior); } + void setBreakInside(BreakInside breakBehavior) { SET_VAR(rareNonInheritedData, m_breakInside, breakBehavior); } + + void setHangingPunctuation(HangingPunctuation punctuation) { SET_VAR(rareInheritedData, m_hangingPunctuation, punctuation); } + // End CSS3 Setters void setLineGrid(const AtomicString& lineGrid) { SET_VAR(rareInheritedData, m_lineGrid, lineGrid); } @@ -1383,103 +1632,128 @@ public: void setRegionThread(const AtomicString& regionThread) { SET_VAR(rareNonInheritedData, m_regionThread, regionThread); } void setRegionFragment(RegionFragment regionFragment) { SET_VAR(rareNonInheritedData, m_regionFragment, regionFragment); } - void setWrapFlow(WrapFlow wrapFlow) { SET_VAR(rareNonInheritedData, m_wrapFlow, wrapFlow); } - void setWrapThrough(WrapThrough wrapThrough) { SET_VAR(rareNonInheritedData, m_wrapThrough, wrapThrough); } - // Apple-specific property setters void setPointerEvents(EPointerEvents p) { inherited_flags._pointerEvents = p; } void clearAnimations() { - rareNonInheritedData.access()->m_animations.clear(); + rareNonInheritedData.access()->m_animations = nullptr; } void clearTransitions() { - rareNonInheritedData.access()->m_transitions.clear(); + rareNonInheritedData.access()->m_transitions = nullptr; } - 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 inheritAnimations(const AnimationList* parent) { rareNonInheritedData.access()->m_animations = parent ? std::make_unique<AnimationList>(*parent) : nullptr; } + void inheritTransitions(const AnimationList* parent) { rareNonInheritedData.access()->m_transitions = parent ? std::make_unique<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 l) { SET_VAR(rareNonInheritedData, m_perspectiveOriginX, l); } - void setPerspectiveOriginY(Length l) { SET_VAR(rareNonInheritedData, m_perspectiveOriginY, l); } - void setPageSize(LengthSize s) { SET_VAR(rareNonInheritedData, m_pageSize, s); } + void setPerspectiveOriginX(Length length) { SET_VAR(rareNonInheritedData, m_perspectiveOriginX, WTFMove(length)); } + void setPerspectiveOriginY(Length length) { SET_VAR(rareNonInheritedData, m_perspectiveOriginY, WTFMove(length)); } + void setPageSize(LengthSize size) { SET_VAR(rareNonInheritedData, m_pageSize, WTFMove(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); } -#endif void setLineBoxContain(LineBoxContain c) { SET_VAR(rareInheritedData, m_lineBoxContain, c); } void setLineClamp(LineClampValue c) { SET_VAR(rareNonInheritedData, lineClamp, c); } + + void setInitialLetter(const IntSize& size) { SET_VAR(rareNonInheritedData, m_initialLetter, size); } + +#if ENABLE(TOUCH_EVENTS) + void setTouchAction(TouchAction touchAction) { SET_VAR(rareNonInheritedData, m_touchAction, static_cast<unsigned>(touchAction)); } +#endif + +#if ENABLE(CSS_SCROLL_SNAP) + void setScrollSnapType(ScrollSnapType type) { SET_VAR(rareNonInheritedData, m_scrollSnapType, static_cast<unsigned>(type)); } + void setScrollSnapPointsX(std::unique_ptr<ScrollSnapPoints>); + void setScrollSnapPointsY(std::unique_ptr<ScrollSnapPoints>); + void setScrollSnapDestination(LengthSize); + void setScrollSnapCoordinates(Vector<LengthSize>); +#endif + #if ENABLE(TOUCH_EVENTS) void setTapHighlightColor(const Color& c) { SET_VAR(rareInheritedData, tapHighlightColor, c); } #endif + +#if PLATFORM(IOS) + void setTouchCalloutEnabled(bool v) { SET_VAR(rareInheritedData, touchCalloutEnabled, v); } +#endif + #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) void setUseTouchOverflowScrolling(bool v) { SET_VAR(rareInheritedData, useTouchOverflowScrolling, v); } #endif - void setTextSecurity(ETextSecurity aTextSecurity) { SET_VAR(rareInheritedData, textSecurity, aTextSecurity); } -#if ENABLE(SVG) - const SVGRenderStyle* svgStyle() const { return m_svgStyle.get(); } - SVGRenderStyle* accessSVGStyle() { return m_svgStyle.access(); } - - const SVGPaint::SVGPaintType& fillPaintType() const { return svgStyle()->fillPaintType(); } - Color fillPaintColor() const { return svgStyle()->fillPaintColor(); } - void setFillPaintColor(const Color& c) { accessSVGStyle()->setFillPaint(SVGPaint::SVG_PAINTTYPE_RGBCOLOR, c, ""); } - float fillOpacity() const { return svgStyle()->fillOpacity(); } - void setFillOpacity(float f) { accessSVGStyle()->setFillOpacity(f); } - - const SVGPaint::SVGPaintType& strokePaintType() const { return svgStyle()->strokePaintType(); } - Color strokePaintColor() const { return svgStyle()->strokePaintColor(); } - void setStrokePaintColor(const Color& c) { accessSVGStyle()->setStrokePaint(SVGPaint::SVG_PAINTTYPE_RGBCOLOR, c, ""); } - 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); } - SVGLength strokeDashOffset() const { return svgStyle()->strokeDashOffset(); } - void setStrokeDashOffset(SVGLength d) { accessSVGStyle()->setStrokeDashOffset(d); } - float strokeMiterLimit() const { return svgStyle()->strokeMiterLimit(); } - void setStrokeMiterLimit(float f) { accessSVGStyle()->setStrokeMiterLimit(f); } - - float floodOpacity() const { return svgStyle()->floodOpacity(); } - void setFloodOpacity(float f) { accessSVGStyle()->setFloodOpacity(f); } - - float stopOpacity() const { return svgStyle()->stopOpacity(); } - void setStopOpacity(float f) { accessSVGStyle()->setStopOpacity(f); } - - void setStopColor(const Color& c) { accessSVGStyle()->setStopColor(c); } - 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); } +#if ENABLE(IOS_TEXT_AUTOSIZING) + void setTextSizeAdjust(TextSizeAdjustment anAdjustment) { SET_VAR(rareInheritedData, textSizeAdjust, anAdjustment); } #endif - 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 setTextSecurity(ETextSecurity aTextSecurity) { SET_VAR(rareInheritedData, textSecurity, aTextSecurity); } +#if ENABLE(CSS_TRAILING_WORD) + void setTrailingWord(TrailingWord v) { SET_VAR(rareInheritedData, trailingWord, static_cast<unsigned>(v)); } +#endif + + const SVGRenderStyle& svgStyle() const { return *m_svgStyle; } + SVGRenderStyle& accessSVGStyle() { return *m_svgStyle.access(); } + + const SVGPaint::SVGPaintType& fillPaintType() const { return svgStyle().fillPaintType(); } + Color fillPaintColor() const { return svgStyle().fillPaintColor(); } + void setFillPaintColor(const Color& c) { accessSVGStyle().setFillPaint(SVGPaint::SVG_PAINTTYPE_RGBCOLOR, c, ""); } + float fillOpacity() const { return svgStyle().fillOpacity(); } + void setFillOpacity(float f) { accessSVGStyle().setFillOpacity(f); } + + const SVGPaint::SVGPaintType& strokePaintType() const { return svgStyle().strokePaintType(); } + Color strokePaintColor() const { return svgStyle().strokePaintColor(); } + void setStrokePaintColor(const Color& c) { accessSVGStyle().setStrokePaint(SVGPaint::SVG_PAINTTYPE_RGBCOLOR, c, ""); } + float strokeOpacity() const { return svgStyle().strokeOpacity(); } + void setStrokeOpacity(float f) { accessSVGStyle().setStrokeOpacity(f); } + const Length& strokeWidth() const { return svgStyle().strokeWidth(); } + void setStrokeWidth(Length w) { accessSVGStyle().setStrokeWidth(w); } + Vector<SVGLength> strokeDashArray() const { return svgStyle().strokeDashArray(); } + void setStrokeDashArray(Vector<SVGLength> array) { accessSVGStyle().setStrokeDashArray(array); } + const Length& strokeDashOffset() const { return svgStyle().strokeDashOffset(); } + void setStrokeDashOffset(Length d) { accessSVGStyle().setStrokeDashOffset(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(cx); } + const Length& cy() const { return svgStyle().cy(); } + void setCy(Length cy) { accessSVGStyle().setCy(cy); } + const Length& r() const { return svgStyle().r(); } + void setR(Length r) { accessSVGStyle().setR(r); } + const Length& rx() const { return svgStyle().rx(); } + void setRx(Length rx) { accessSVGStyle().setRx(rx); } + const Length& ry() const { return svgStyle().ry(); } + void setRy(Length ry) { accessSVGStyle().setRy(ry); } + const Length& x() const { return svgStyle().x(); } + void setX(Length x) { accessSVGStyle().setX(x); } + const Length& y() const { return svgStyle().y(); } + void setY(Length y) { accessSVGStyle().setY(y); } + + float floodOpacity() const { return svgStyle().floodOpacity(); } + void setFloodOpacity(float f) { accessSVGStyle().setFloodOpacity(f); } + + float stopOpacity() const { return svgStyle().stopOpacity(); } + void setStopOpacity(float f) { accessSVGStyle().setStopOpacity(f); } + + void setStopColor(const Color& c) { accessSVGStyle().setStopColor(c); } + 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); } + +#if ENABLE(CSS_SHAPES) void setShapeOutside(PassRefPtr<ShapeValue> value) { if (rareNonInheritedData->m_shapeOutside == value) @@ -1488,9 +1762,21 @@ public: } ShapeValue* shapeOutside() const { return rareNonInheritedData->m_shapeOutside.get(); } - static ShapeValue* initialShapeInside(); static ShapeValue* initialShapeOutside() { return 0; } + const Length& shapeMargin() const { return rareNonInheritedData->m_shapeMargin; } + void setShapeMargin(Length shapeMargin) { SET_VAR(rareNonInheritedData, m_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); + } + static float initialShapeImageThreshold() { return 0; } +#endif + void setClipPath(PassRefPtr<ClipPathOperation> operation) { if (rareNonInheritedData->m_clipPath != operation) @@ -1498,15 +1784,7 @@ public: } ClipPathOperation* clipPath() const { return rareNonInheritedData->m_clipPath.get(); } - static ClipPathOperation* initialClipPath() { return 0; } - - Length shapePadding() const { return rareNonInheritedData->m_shapePadding; } - void setShapePadding(Length shapePadding) { SET_VAR(rareNonInheritedData, m_shapePadding, shapePadding); } - static Length initialShapePadding() { return Length(0, Fixed); } - - Length shapeMargin() const { return rareNonInheritedData->m_shapeMargin; } - void setShapeMargin(Length shapeMargin) { SET_VAR(rareNonInheritedData, m_shapeMargin, shapeMargin); } - static Length initialShapeMargin() { return Length(0, Fixed); } + static ClipPathOperation* initialClipPath() { return nullptr; } bool hasContent() const { return contentData(); } const ContentData* contentData() const { return rareNonInheritedData->m_content.get(); } @@ -1514,8 +1792,10 @@ public: void clearContent(); void setContent(const String&, bool add = false); void setContent(PassRefPtr<StyleImage>, bool add = false); - void setContent(PassOwnPtr<CounterContent>, 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; const CounterDirectiveMap* counterDirectives() const; CounterDirectiveMap& accessCounterDirectives(); @@ -1524,17 +1804,35 @@ public: QuotesData* quotes() const { return rareInheritedData->quotes.get(); } void setQuotes(PassRefPtr<QuotesData>); + WillChangeData* willChange() const { return rareNonInheritedData->m_willChange.get(); } + void setWillChange(PassRefPtr<WillChangeData>); + + bool willChangeCreatesStackingContext() const + { + if (!willChange()) + return false; + + return willChange()->canCreateStackingContext(); + } + const AtomicString& hyphenString() const; bool inheritedNotEqual(const RenderStyle*) const; bool inheritedDataShared(const RenderStyle*) const; - StyleDifference diff(const RenderStyle*, unsigned& changedContextSensitiveProperties) const; - bool diffRequiresRepaint(const RenderStyle*) const; +#if ENABLE(IOS_TEXT_AUTOSIZING) + uint32_t hashForTextAutosizing() const; + bool equalForTextAutosizing(const RenderStyle *other) const; +#endif + + 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 isDisplayFlexibleOrGridBox() const { return isDisplayFlexibleOrGridBox(display()); } + bool isDisplayFlexibleBox() const { return isDisplayFlexibleBox(display()); } bool isDisplayRegionType() const { return display() == BLOCK || display() == INLINE_BLOCK @@ -1551,89 +1849,103 @@ public: return true; } + bool hasExplicitlySetWritingMode() const { return noninherited_flags.hasExplicitlySetWritingMode(); } + void setHasExplicitlySetWritingMode(bool v) { noninherited_flags.setHasExplicitlySetWritingMode(v); } + // 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 noninherited_flags.isUnique(); } + void setUnique() { noninherited_flags.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 noninherited_flags.emptyState(); } + void setEmptyState(bool b) { setUnique(); noninherited_flags.setEmptyState(b); } + bool firstChildState() const { return noninherited_flags.firstChildState(); } + void setFirstChildState() { setUnique(); noninherited_flags.setFirstChildState(true); } + bool lastChildState() const { return noninherited_flags.lastChildState(); } + void setLastChildState() { setUnique(); noninherited_flags.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() { noninherited_flags.setHasExplicitlyInheritedProperties(true); } + bool hasExplicitlyInheritedProperties() const { return noninherited_flags.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 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 EDisplay initialDisplay() { return INLINE; } + static TextOrientation initialTextOrientation() { return TextOrientation:: + Mixed; } + static ObjectFit initialObjectFit() { return ObjectFitFill; } 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; } + static ECursor initialCursor() { return CursorAuto; } #if ENABLE(CURSOR_VISIBILITY) static CursorVisibility initialCursorVisibility() { return CursorVisibilityAuto; } #endif 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 float initialWordSpacing() { 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); } + static Length initialZeroLength() { return Length(Fixed); } + static Length initialOneLength() { return Length(1, Fixed); } #if ENABLE(CSS3_TEXT) static TextIndentLine initialTextIndentLine() { return TextIndentFirstLine; } static TextIndentType initialTextIndentType() { return TextIndentNormal; } #endif - static EVerticalAlign initialVerticalAlign() { return BASELINE; } static short initialWidows() { return 2; } static short initialOrphans() { return 2; } - static Length initialLineHeight() { return Length(-100.0, Percent); } + static Length initialLineHeight() { return Length(-100.0f, Percent); } +#if ENABLE(IOS_TEXT_AUTOSIZING) + static Length initialSpecifiedLineHeight() { return Length(-100.0f, Percent); } +#endif static ETextAlign initialTextAlign() { return TASTART; } static TextDecoration initialTextDecoration() { return TextDecorationNone; } #if ENABLE(CSS3_TEXT) - static TextDecorationStyle initialTextDecorationStyle() { return TextDecorationStyleSolid; } static TextAlignLast initialTextAlignLast() { return TextAlignLastAuto; } static TextJustify initialTextJustify() { return TextJustifyAuto; } - static TextUnderlinePosition initialTextUnderlinePosition() { return TextUnderlinePositionAuto; } #endif // CSS3_TEXT + static TextDecorationStyle initialTextDecorationStyle() { return TextDecorationStyleSolid; } + 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; } @@ -1650,12 +1962,10 @@ public: 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 StyleContentAlignmentData initialContentAlignment() { return StyleContentAlignmentData(ContentPositionAuto, 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); } @@ -1671,40 +1981,39 @@ 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; } static float initialTextStrokeWidth() { return 0; } 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; } static TextEmphasisMark initialTextEmphasisMark() { return TextEmphasisMarkNone; } static const AtomicString& initialTextEmphasisCustomMark() { return nullAtom; } - static TextEmphasisPosition initialTextEmphasisPosition() { return TextEmphasisPositionOver; } + static TextEmphasisPosition initialTextEmphasisPosition() { return TextEmphasisPositionOver | TextEmphasisPositionRight; } static RubyPosition initialRubyPosition() { return RubyPositionBefore; } static LineBoxContain initialLineBoxContain() { return LineBoxContainBlock | LineBoxContainInline | LineBoxContainReplaced; } static ImageOrientationEnum initialImageOrientation() { return OriginTopLeft; } @@ -1712,21 +2021,58 @@ 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; } + static WillChangeData* initialWillChange() { return nullptr; } + +#if ENABLE(TOUCH_EVENTS) + static TouchAction initialTouchAction() { return TouchAction::Auto; } +#endif + +#if ENABLE(CSS_SCROLL_SNAP) + static ScrollSnapType initialScrollSnapType() { return ScrollSnapType::None; } + static ScrollSnapPoints* initialScrollSnapPointsX() { return nullptr; } + static ScrollSnapPoints* initialScrollSnapPointsY() { return nullptr; } + static LengthSize initialScrollSnapDestination(); + static Vector<LengthSize> initialScrollSnapCoordinates(); +#endif + +#if ENABLE(CSS_TRAILING_WORD) + static TrailingWord initialTrailingWord() { return TrailingWord::Auto; } +#endif + +#if ENABLE(CSS_GRID_LAYOUT) // 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 GridAutoFlow initialGridAutoFlow() { return AutoFlowRow; } + + static GridTrackSize initialGridAutoColumns() { return GridTrackSize(Length(Auto)); } + static GridTrackSize initialGridAutoRows() { return GridTrackSize(Length(Auto)); } - static GridTrackSize initialGridAutoColumns() { return GridTrackSize(Auto); } - static GridTrackSize initialGridAutoRows() { return GridTrackSize(Auto); } + static NamedGridAreaMap initialNamedGridArea() { return NamedGridAreaMap(); } + static size_t initialNamedGridAreaCount() { return 0; } + + 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 initialGridPosition() { return GridPosition(); } + static GridPosition initialGridItemColumnStart() { return GridPosition(); } + static GridPosition initialGridItemColumnEnd() { return GridPosition(); } + static GridPosition initialGridItemRowStart() { return GridPosition(); } + static GridPosition initialGridItemRowEnd() { return GridPosition(); } +#endif /* ENABLE(CSS_GRID_LAYOUT) */ static unsigned initialTabSize() { return 8; } @@ -1738,12 +2084,16 @@ 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; } +#endif #if ENABLE(TOUCH_EVENTS) static Color initialTapHighlightColor(); #endif @@ -1754,20 +2104,25 @@ public: 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 + static ptrdiff_t noninheritedFlagsMemoryOffset() { return OBJECT_OFFSETOF(RenderStyle, noninherited_flags); } + 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 changeRequiresRepaintIfText(const RenderStyle*, unsigned& changedContextSensitiveProperties) const; - bool changeRequiresRecompositeLayer(const RenderStyle*, unsigned& changedContextSensitiveProperties) 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; void setVisitedLinkColor(const Color&); void setVisitedLinkBackgroundColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBackgroundColor, v); } @@ -1776,15 +2131,13 @@ private: 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); } -#if ENABLE(CSS3_TEXT) + void setVisitedLinkColumnRuleColor(const Color& v) { SET_NESTED_VAR(rareNonInheritedData, m_multiCol, m_visitedLinkColumnRuleColor, v); } void setVisitedLinkTextDecorationColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkTextDecorationColor, v); } -#endif // CSS3_TEXT 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 inheritUnicodeBidiFrom(const RenderStyle* parent) { noninherited_flags.setUnicodeBidi(parent->noninherited_flags.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; @@ -1801,7 +2154,10 @@ private: bool isDisplayReplacedType(EDisplay display) const { return display == INLINE_BLOCK || display == INLINE_BOX || display == INLINE_FLEX - || display == INLINE_TABLE || display == INLINE_GRID; +#if ENABLE(CSS_GRID_LAYOUT) + || display == INLINE_GRID +#endif + || display == INLINE_TABLE; } bool isDisplayInlineType(EDisplay display) const @@ -1809,8 +2165,28 @@ private: return display == INLINE || isDisplayReplacedType(display); } + bool isDisplayFlexibleBox(EDisplay display) const + { + return display == FLEX || display == INLINE_FLEX; + } + + bool isDisplayGridBox(EDisplay display) const + { +#if ENABLE(CSS_GRID_LAYOUT) + return display == GRID || display == INLINE_GRID; +#else + UNUSED_PARAM(display); + return false; +#endif + } + + bool isDisplayFlexibleOrGridBox(EDisplay display) const + { + return isDisplayFlexibleBox(display) || isDisplayGridBox(display); + } + // Color accessors are all private to make sure callers use visitedDependentColor instead to access them. - Color invalidColor() const { static Color invalid; return invalid; } + static Color invalidColor() { return Color(); } Color borderLeftColor() const { return surround->border.left().color(); } Color borderRightColor() const { return surround->border.right().color(); } Color borderTopColor() const { return surround->border.top().color(); } @@ -1830,28 +2206,24 @@ private: Color visitedLinkBorderTopColor() const { return rareNonInheritedData->m_visitedLinkBorderTopColor; } Color visitedLinkOutlineColor() const { return rareNonInheritedData->m_visitedLinkOutlineColor; } Color visitedLinkColumnRuleColor() const { return rareNonInheritedData->m_multiCol->m_visitedLinkColumnRuleColor; } -#if ENABLE(CSS3_TEXT) Color textDecorationColor() const { return rareNonInheritedData->m_textDecorationColor; } Color visitedLinkTextDecorationColor() const { return rareNonInheritedData->m_visitedLinkTextDecorationColor; } -#endif // CSS3_TEXT Color visitedLinkTextEmphasisColor() const { return rareInheritedData->visitedLinkTextEmphasisColor; } Color visitedLinkTextFillColor() const { return rareInheritedData->visitedLinkTextFillColor; } Color visitedLinkTextStrokeColor() const { return rareInheritedData->visitedLinkTextStrokeColor; } Color colorIncludingFallback(int colorProperty, bool visitedLink) const; -#if ENABLE(SVG) - Color stopColor() const { return svgStyle()->stopColor(); } - Color floodColor() const { return svgStyle()->floodColor(); } - Color lightingColor() const { return svgStyle()->lightingColor(); } -#endif + Color stopColor() const { return svgStyle().stopColor(); } + Color floodColor() const { return svgStyle().floodColor(); } + Color lightingColor() const { return svgStyle().lightingColor(); } - void appendContent(PassOwnPtr<ContentData>); + void appendContent(std::unique_ptr<ContentData>); }; -inline int adjustForAbsoluteZoom(int value, const RenderStyle* style) +inline int adjustForAbsoluteZoom(int value, const RenderStyle& style) { - double zoomFactor = style->effectiveZoom(); + double zoomFactor = style.effectiveZoom(); if (zoomFactor == 1) return value; // Needed because computeLengthInt truncates (rather than rounds) when scaling up. @@ -1865,24 +2237,31 @@ 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) +inline LayoutUnit adjustLayoutUnitForAbsoluteZoom(LayoutUnit value, const RenderStyle& style) { - return value / style->effectiveZoom(); + return value / style.effectiveZoom(); +} + +inline EBorderStyle collapsedBorderStyle(EBorderStyle style) +{ + if (style == OUTSET) + return GROOVE; + if (style == INSET) + return RIDGE; + return style; } -#endif inline bool RenderStyle::setZoom(float f) { + setEffectiveZoom(effectiveZoom() * f); if (compareEqual(visual->m_zoom, f)) return false; visual.access()->m_zoom = f; - setEffectiveZoom(effectiveZoom() * zoom()); return true; } @@ -1896,13 +2275,33 @@ inline bool RenderStyle::setEffectiveZoom(float f) inline bool RenderStyle::setTextOrientation(TextOrientation textOrientation) { - if (compareEqual(rareInheritedData->m_textOrientation, textOrientation)) + if (compareEqual(rareInheritedData->m_textOrientation, static_cast<unsigned>(textOrientation))) return false; - rareInheritedData.access()->m_textOrientation = textOrientation; + rareInheritedData.access()->m_textOrientation = static_cast<unsigned>(textOrientation); return true; } +inline bool RenderStyle::hasAnyPublicPseudoStyles() const +{ + return noninherited_flags.hasAnyPublicPseudoStyles(); +} + +inline bool RenderStyle::hasPseudoStyle(PseudoId pseudo) const +{ + return noninherited_flags.hasPseudoStyle(pseudo); +} + +inline void RenderStyle::setHasPseudoStyle(PseudoId pseudo) +{ + noninherited_flags.setHasPseudoStyle(pseudo); +} + +inline void RenderStyle::setHasPseudoStyles(PseudoIdSet pseudoIdSet) +{ + noninherited_flags.setHasPseudoStyles(pseudoIdSet); +} + } // namespace WebCore #endif // RenderStyle_h 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 830612e57..492f78c4d 100644 --- a/Source/WebCore/rendering/style/RenderStyleConstants.h +++ b/Source/WebCore/rendering/style/RenderStyleConstants.h @@ -26,8 +26,12 @@ #ifndef RenderStyleConstants_h #define RenderStyleConstants_h +#include <initializer_list> + namespace WebCore { +class TextStream; + static const size_t PrintColorAdjustBits = 1; enum PrintColorAdjust { PrintColorAdjustEconomy, @@ -38,7 +42,7 @@ enum PrintColorAdjust { // - StyleDifferenceEqual - The two styles are identical // - StyleDifferenceRecompositeLayer - The layer needs its position and transform updated, but no repaint // - StyleDifferenceRepaint - The object just needs to be repainted. -// - StyleDifferenceRepaintIfText - The object needs to be repainted if it contains text. +// - StyleDifferenceRepaintIfTextOrBorderOrOutline - The object needs to be repainted if it contains text or a border or outline. // - StyleDifferenceRepaintLayer - The layer and its descendant layers needs to be repainted. // - StyleDifferenceLayoutPositionedMovementOnly - Only the position of this positioned object has been updated // - StyleDifferenceSimplifiedLayout - Only overflow needs to be recomputed @@ -46,16 +50,15 @@ enum PrintColorAdjust { // - StyleDifferenceLayout - A full layout is required. enum StyleDifference { StyleDifferenceEqual, -#if USE(ACCELERATED_COMPOSITING) StyleDifferenceRecompositeLayer, -#endif StyleDifferenceRepaint, - StyleDifferenceRepaintIfText, + 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 +66,93 @@ 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, // 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 }; enum EBorderCollapse { BSEPARATE = 0, BCOLLAPSE = 1 }; @@ -160,8 +230,11 @@ 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 }; // CSS3 Marquee Properties @@ -179,10 +252,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, ItemPositionStretch, ItemPositionBaseline, ItemPositionLastBaseline, ItemPositionCenter, ItemPositionStart, ItemPositionEnd, ItemPositionSelfStart, ItemPositionSelfEnd, ItemPositionFlexStart, ItemPositionFlexEnd, ItemPositionLeft, ItemPositionRight}; +enum OverflowAlignment {OverflowAlignmentDefault, OverflowAlignmentUnsafe, OverflowAlignmentSafe}; +enum ItemPositionType {NonLegacyPosition, LegacyPosition}; +enum ContentPosition {ContentPositionAuto, ContentPositionBaseline, ContentPositionLastBaseline, ContentPositionCenter, ContentPositionStart, ContentPositionEnd, ContentPositionFlexStart, ContentPositionFlexEnd, ContentPositionLeft, ContentPositionRight}; +enum ContentDistributionType {ContentDistributionDefault, ContentDistributionSpaceBetween, ContentDistributionSpaceAround, ContentDistributionSpaceEvenly, ContentDistributionStretch}; enum ETextSecurity { TSNONE, TSDISC, TSCIRCLE, TSSQUARE @@ -206,10 +282,17 @@ enum EUserSelect { SELECT_NONE, SELECT_TEXT, SELECT_ALL }; -// Word Break Values. Matches WinIE, rather than CSS3 +// CSS3 Image Values +enum ObjectFit { + ObjectFitFill, ObjectFitContain, ObjectFitCover, ObjectFitNone, ObjectFitScaleDown +}; + +enum AspectRatioType { + AspectRatioAuto, AspectRatioFromIntrinsic, AspectRatioFromDimensions, AspectRatioSpecified +}; enum EWordBreak { - NormalWordBreak, BreakAllWordBreak, BreakWordBreak + NormalWordBreak, BreakAllWordBreak, KeepAllWordBreak, BreakWordBreak }; enum EOverflowWrap { @@ -339,21 +422,30 @@ enum ETextTransform { CAPITALIZE, UPPERCASE, LOWERCASE, TTNONE }; +#if ENABLE(LETTERPRESS) +static const size_t TextDecorationBits = 5; +#else static const size_t TextDecorationBits = 4; +#endif enum TextDecoration { - TextDecorationNone = 0x0, TextDecorationUnderline = 0x1, TextDecorationOverline = 0x2, TextDecorationLineThrough = 0x4, TextDecorationBlink = 0x8 + TextDecorationNone = 0x0, + TextDecorationUnderline = 0x1, + TextDecorationOverline = 0x2, + TextDecorationLineThrough = 0x4, + TextDecorationBlink = 0x8, +#if ENABLE(LETTERPRESS) + TextDecorationLetterpress = 0x10, +#endif }; inline TextDecoration operator| (TextDecoration a, TextDecoration b) { return TextDecoration(int(a) | int(b)); } inline TextDecoration& operator|= (TextDecoration& a, TextDecoration b) { return a = a | b; } enum TextDecorationStyle { TextDecorationStyleSolid, -#if ENABLE(CSS3_TEXT) TextDecorationStyleDouble, TextDecorationStyleDotted, TextDecorationStyleDashed, TextDecorationStyleWavy -#endif // CSS3_TEXT }; #if ENABLE(CSS3_TEXT) @@ -361,19 +453,46 @@ enum TextAlignLast { TextAlignLastAuto, TextAlignLastStart, TextAlignLastEnd, TextAlignLastLeft, TextAlignLastRight, TextAlignLastCenter, TextAlignLastJustify }; +enum TextJustify { + TextJustifyAuto, TextJustifyNone, TextJustifyInterWord, TextJustifyDistribute +}; +#endif // CSS3_TEXT + +enum TextDecorationSkipItems { + TextDecorationSkipNone = 0, + TextDecorationSkipInk = 1 << 0, + TextDecorationSkipObjects = 1 << 1, + TextDecorationSkipAuto = 1 << 2 +}; +typedef unsigned TextDecorationSkip; + enum TextUnderlinePosition { // FIXME: Implement support for 'under left' and 'under right' values. TextUnderlinePositionAuto = 0x1, TextUnderlinePositionAlphabetic = 0x2, TextUnderlinePositionUnder = 0x4 }; -enum TextJustify { - TextJustifyAuto, TextJustifyNone, TextJustifyInterWord, TextJustifyInterIdeograph, TextJustifyInterCluster, TextJustifyDistribute, TextJustifyKashida +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 }; -#endif // CSS3_TEXT -enum EPageBreak { - PBAUTO, PBALWAYS, PBAVOID +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 @@ -389,44 +508,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) @@ -438,13 +557,15 @@ 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, + FLEX, WEBKIT_FLEX, INLINE_FLEX, WEBKIT_INLINE_FLEX, +#if ENABLE(CSS_GRID_LAYOUT) GRID, INLINE_GRID, +#endif NONE }; @@ -475,13 +596,25 @@ enum TextEmphasisFill { TextEmphasisFillFilled, TextEmphasisFillOpen }; enum TextEmphasisMark { TextEmphasisMarkNone, TextEmphasisMarkAuto, TextEmphasisMarkDot, TextEmphasisMarkCircle, TextEmphasisMarkDoubleCircle, TextEmphasisMarkTriangle, TextEmphasisMarkSesame, TextEmphasisMarkCustom }; -enum TextEmphasisPosition { TextEmphasisPositionOver, TextEmphasisPositionUnder }; +enum TextEmphasisPositions { + TextEmphasisPositionOver = 1 << 0, + TextEmphasisPositionUnder = 1 << 1, + TextEmphasisPositionLeft = 1 << 2, + TextEmphasisPositionRight = 1 << 3 +}; +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 }; @@ -499,16 +632,26 @@ enum LineSnap { LineSnapNone, LineSnapBaseline, LineSnapContain }; enum LineAlign { LineAlignNone, LineAlignEdges }; -enum WrapFlow { WrapFlowAuto, WrapFlowBoth, WrapFlowStart, WrapFlowEnd, WrapFlowMaximum, WrapFlowClear }; - -enum WrapThrough { WrapThroughWrap, WrapThroughNone }; +enum RubyPosition { RubyPositionBefore, RubyPositionAfter, RubyPositionInterCharacter }; -enum RubyPosition { RubyPositionBefore, RubyPositionAfter }; +#if ENABLE(CSS_GRID_LAYOUT) +static const size_t GridAutoFlowBits = 4; +enum InternalGridAutoFlowAlgorithm { + InternalAutoFlowAlgorithmSparse = 0x1, + InternalAutoFlowAlgorithmDense = 0x2, +}; -enum GridAutoFlow { AutoFlowNone, AutoFlowColumn, AutoFlowRow }; +enum InternalGridAutoFlowDirection { + InternalAutoFlowDirectionRow = 0x4, + InternalAutoFlowDirectionColumn = 0x8 +}; -#if ENABLE(DRAGGABLE_REGION) -enum DraggableRegionMode { DraggableRegionNone, DraggableRegionDrag, DraggableRegionNoDrag }; +enum GridAutoFlow { + AutoFlowRow = InternalAutoFlowAlgorithmSparse | InternalAutoFlowDirectionRow, + AutoFlowColumn = InternalAutoFlowAlgorithmSparse | InternalAutoFlowDirectionColumn, + AutoFlowRowDense = InternalAutoFlowAlgorithmDense | InternalAutoFlowDirectionRow, + AutoFlowColumnDense = InternalAutoFlowAlgorithmDense | InternalAutoFlowDirectionColumn +}; #endif // Reasonable maximum to prevent insane font sizes from causing crashes on some platforms (such as Windows). @@ -519,6 +662,40 @@ enum TextIndentLine { TextIndentFirstLine, TextIndentEachLine }; enum TextIndentType { TextIndentNormal, TextIndentHanging }; #endif +enum Isolation { IsolationAuto, IsolationIsolate }; + +// Fill, Stroke, ViewBox are just used for SVG. +enum CSSBoxType { BoxMissing = 0, MarginBox, BorderBox, PaddingBox, ContentBox, Fill, Stroke, ViewBox }; + +#if ENABLE(TOUCH_EVENTS) +enum class TouchAction { + Auto, + Manipulation +}; +#endif + +#if ENABLE(CSS_SCROLL_SNAP) +enum class ScrollSnapType { + None, + Proximity, + Mandatory +}; +#endif + +#if ENABLE(CSS_TRAILING_WORD) +enum class TrailingWord { + Auto, + PartiallyBalanced +}; +#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 #endif // RenderStyleConstants_h diff --git a/Source/WebCore/rendering/style/SVGRenderStyle.cpp b/Source/WebCore/rendering/style/SVGRenderStyle.cpp index aca245aef..df79aff65 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,64 +26,75 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGRenderStyle.h" #include "CSSPrimitiveValue.h" #include "CSSValueList.h" #include "IntRect.h" #include "NodeRenderStyle.h" -#include "SVGStyledElement.h" - -using namespace std; +#include "SVGElement.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { -SVGRenderStyle::SVGRenderStyle() +static const SVGRenderStyle& defaultSVGStyle() { - static SVGRenderStyle* defaultStyle = new SVGRenderStyle(CreateDefault); + static NeverDestroyed<DataRef<SVGRenderStyle>> style(SVGRenderStyle::createDefaultStyle()); + return *style.get().get(); +} - fill = defaultStyle->fill; - stroke = defaultStyle->stroke; - text = defaultStyle->text; - stops = defaultStyle->stops; - misc = defaultStyle->misc; - shadowSVG = defaultStyle->shadowSVG; - inheritedResources = defaultStyle->inheritedResources; - resources = defaultStyle->resources; +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) + , layout(defaultSVGStyle().layout) + , resources(defaultSVGStyle().resources) +{ 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()) + , layout(StyleLayoutData::create()) + , resources(StyleResourceData::create()) { setBitDefaults(); - - fill.init(); - stroke.init(); - text.init(); - stops.init(); - misc.init(); - shadowSVG.init(); - inheritedResources.init(); - resources.init(); } -SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other) +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) + , layout(other.layout) + , resources(other.resources) +{ +} + +Ref<SVGRenderStyle> SVGRenderStyle::copy() const { - 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 adoptRef(*new SVGRenderStyle(*this)); } SVGRenderStyle::~SVGRenderStyle() @@ -98,6 +109,7 @@ bool SVGRenderStyle::operator==(const SVGRenderStyle& other) const && stops == other.stops && misc == other.misc && shadowSVG == other.shadowSVG + && layout == other.layout && inheritedResources == other.inheritedResources && resources == other.resources && svg_inherited_flags == other.svg_inherited_flags @@ -132,9 +144,50 @@ void SVGRenderStyle::copyNonInheritedFrom(const SVGRenderStyle* other) stops = other->stops; misc = other->misc; shadowSVG = other->shadowSVG; + layout = other->layout; resources = other->resources; } +Vector<PaintType, 3> SVGRenderStyle::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; +} + StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const { // NOTE: All comparisions that may return StyleDifferenceLayout have to go before those who return StyleDifferenceRepaint @@ -175,6 +228,10 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const if (shadowSVG != other->shadowSVG) return StyleDifferenceLayout; + // The x or y properties require relayout. + if (layout != other->layout) + 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 @@ -194,6 +251,10 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const return StyleDifferenceRepaint; } + // vector-effect changes require a re-layout. + if (svg_noninherited_flags.f._vectorEffect != other->svg_noninherited_flags.f._vectorEffect) + return StyleDifferenceLayout; + // NOTE: All comparisions below may only return StyleDifferenceRepaint // Painting related properties only need repaints. @@ -222,10 +283,6 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const || svg_inherited_flags._colorInterpolationFilters != other->svg_inherited_flags._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) - return StyleDifferenceRepaint; - if (svg_noninherited_flags.f.bufferedRendering != other->svg_noninherited_flags.f.bufferedRendering) return StyleDifferenceRepaint; @@ -236,5 +293,3 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/rendering/style/SVGRenderStyle.h b/Source/WebCore/rendering/style/SVGRenderStyle.h index 4a224b76e..1eff35685 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, 2006 Apple Inc. 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 @@ -23,7 +24,6 @@ #ifndef SVGRenderStyle_h #define SVGRenderStyle_h -#if ENABLE(SVG) #include "CSSValueList.h" #include "DataRef.h" #include "ExceptionCodePlaceholder.h" @@ -41,8 +41,9 @@ class RenderObject; class SVGRenderStyle : public RefCounted<SVGRenderStyle> { public: - static PassRefPtr<SVGRenderStyle> create() { return adoptRef(new SVGRenderStyle); } - PassRefPtr<SVGRenderStyle> copy() const { return adoptRef(new SVGRenderStyle(*this));} + static Ref<SVGRenderStyle> createDefaultStyle(); + static Ref<SVGRenderStyle> create() { return adoptRef(*new SVGRenderStyle); } + Ref<SVGRenderStyle> copy() const; ~SVGRenderStyle(); bool inheritedNotEqual(const SVGRenderStyle*) const; @@ -89,12 +90,12 @@ public: static Color initialLightingColor() { return Color(255, 255, 255); } static ShadowData* initialShadow() { return 0; } 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 PaintOrder initialPaintOrder() { return PaintOrderNormal; } static SVGLength initialBaselineShiftValue() { @@ -110,20 +111,6 @@ public: 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; - } - // SVG CSS Property setters void setAlignmentBaseline(EAlignmentBaseline val) { svg_noninherited_flags.f._alignmentBaseline = val; } void setDominantBaseline(EDominantBaseline val) { svg_noninherited_flags.f._dominantBaseline = val; } @@ -143,6 +130,42 @@ public: 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 setPaintOrder(PaintOrder val) { svg_inherited_flags.paintOrder = val; } + void setCx(const Length& obj) + { + if (!(layout->cx == obj)) + layout.access()->cx = obj; + } + void setCy(const Length& obj) + { + if (!(layout->cy == obj)) + layout.access()->cy = obj; + } + void setR(const Length& obj) + { + if (!(layout->r == obj)) + layout.access()->r = obj; + } + void setRx(const Length& obj) + { + if (!(layout->rx == obj)) + layout.access()->rx = obj; + } + void setRy(const Length& obj) + { + if (!(layout->ry == obj)) + layout.access()->ry = obj; + } + void setX(const Length& obj) + { + if (!(layout->x == obj)) + layout.access()->x = obj; + } + void setY(const Length& obj) + { + if (!(layout->y == obj)) + layout.access()->y = obj; + } void setFillOpacity(float obj) { @@ -208,13 +231,13 @@ public: stroke.access()->miterLimit = obj; } - void setStrokeWidth(const SVGLength& obj) + void setStrokeWidth(const Length& obj) { if (!(stroke->width == obj)) stroke.access()->width = obj; } - void setStrokeDashOffset(const SVGLength& obj) + void setStrokeDashOffset(const Length& obj) { if (!(stroke->dashOffset == obj)) stroke.access()->dashOffset = obj; @@ -262,7 +285,7 @@ public: misc.access()->baselineShiftValue = obj; } - void setShadow(PassOwnPtr<ShadowData> obj) { shadowSVG.access()->shadow = obj; } + void setShadow(std::unique_ptr<ShadowData> obj) { shadowSVG.access()->shadow = WTFMove(obj); } // Setters for non-inherited resources void setClipperResource(const String& obj) @@ -271,12 +294,6 @@ public: 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)) @@ -330,8 +347,8 @@ public: 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; } + const Length& strokeWidth() const { return stroke->width; } + const Length& strokeDashOffset() const { return stroke->dashOffset; } SVGLength kerning() const { return text->kerning; } float stopOpacity() const { return stops->opacity; } const Color& stopColor() const { return stops->color; } @@ -340,13 +357,21 @@ public: const Color& lightingColor() const { return misc->lightingColor; } SVGLength baselineShiftValue() const { return misc->baselineShiftValue; } ShadowData* shadow() const { return shadowSVG->shadow.get(); } + const Length& cx() const { return layout->cx; } + const Length& cy() const { return layout->cy; } + const Length& r() const { return layout->r; } + const Length& rx() const { return layout->rx; } + const Length& ry() const { return layout->ry; } + const Length& x() const { return layout->x; } + const Length& y() const { return layout->y; } 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; } + PaintOrder paintOrder() const { return (PaintOrder) svg_inherited_flags.paintOrder; } + Vector<PaintType, 3> paintTypesForPaintOrder() const; const SVGPaint::SVGPaintType& visitedLinkFillPaintType() const { return fill->visitedLinkPaintType; } const Color& visitedLinkFillPaintColor() const { return fill->visitedLinkPaintColor; } @@ -358,12 +383,12 @@ public: // 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 isolatesBlending() const { return hasMasker() || shadow(); } protected: // inherit @@ -381,7 +406,8 @@ protected: && (_colorInterpolationFilters == other._colorInterpolationFilters) && (_writingMode == other._writingMode) && (_glyphOrientationHorizontal == other._glyphOrientationHorizontal) - && (_glyphOrientationVertical == other._glyphOrientationVertical); + && (_glyphOrientationVertical == other._glyphOrientationVertical) + && (paintOrder == other.paintOrder); } bool operator!=(const InheritedFlags& other) const @@ -401,6 +427,7 @@ protected: unsigned _writingMode : 3; // SVGWritingMode unsigned _glyphOrientationHorizontal : 3; // EGlyphOrientation unsigned _glyphOrientationVertical : 3; // EGlyphOrientation + unsigned paintOrder : 3; // PaintOrder } svg_inherited_flags; // don't inherit @@ -433,6 +460,7 @@ protected: DataRef<StyleStopData> stops; DataRef<StyleMiscData> misc; DataRef<StyleShadowSVGData> shadowSVG; + DataRef<StyleLayoutData> layout; DataRef<StyleResourceData> resources; private: @@ -456,6 +484,7 @@ private: svg_inherited_flags._writingMode = initialWritingMode(); svg_inherited_flags._glyphOrientationHorizontal = initialGlyphOrientationHorizontal(); svg_inherited_flags._glyphOrientationVertical = initialGlyphOrientationVertical(); + svg_inherited_flags.paintOrder = initialPaintOrder(); svg_noninherited_flags._niflags = 0; svg_noninherited_flags.f._alignmentBaseline = initialAlignmentBaseline(); @@ -469,5 +498,4 @@ private: } // 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 e8c809859..20ded8b8b 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 { @@ -46,7 +46,7 @@ StyleFillData::StyleFillData() { } -StyleFillData::StyleFillData(const StyleFillData& other) +inline StyleFillData::StyleFillData(const StyleFillData& other) : RefCounted<StyleFillData>() , opacity(other.opacity) , paintType(other.paintType) @@ -58,6 +58,11 @@ StyleFillData::StyleFillData(const StyleFillData& other) { } +Ref<StyleFillData> StyleFillData::copy() const +{ + return adoptRef(*new StyleFillData(*this)); +} + bool StyleFillData::operator==(const StyleFillData& other) const { return opacity == other.opacity @@ -72,8 +77,8 @@ bool StyleFillData::operator==(const StyleFillData& other) const StyleStrokeData::StyleStrokeData() : opacity(SVGRenderStyle::initialStrokeOpacity()) , miterLimit(SVGRenderStyle::initialStrokeMiterLimit()) - , width(SVGRenderStyle::initialStrokeWidth()) - , dashOffset(SVGRenderStyle::initialStrokeDashOffset()) + , width(RenderStyle::initialOneLength()) + , dashOffset(RenderStyle::initialZeroLength()) , dashArray(SVGRenderStyle::initialStrokeDashArray()) , paintType(SVGRenderStyle::initialStrokePaintType()) , paintColor(SVGRenderStyle::initialStrokePaintColor()) @@ -84,7 +89,7 @@ StyleStrokeData::StyleStrokeData() { } -StyleStrokeData::StyleStrokeData(const StyleStrokeData& other) +inline StyleStrokeData::StyleStrokeData(const StyleStrokeData& other) : RefCounted<StyleStrokeData>() , opacity(other.opacity) , miterLimit(other.miterLimit) @@ -100,6 +105,11 @@ StyleStrokeData::StyleStrokeData(const StyleStrokeData& other) { } +Ref<StyleStrokeData> StyleStrokeData::copy() const +{ + return adoptRef(*new StyleStrokeData(*this)); +} + bool StyleStrokeData::operator==(const StyleStrokeData& other) const { return width == other.width @@ -121,13 +131,18 @@ StyleStopData::StyleStopData() { } -StyleStopData::StyleStopData(const StyleStopData& other) +inline StyleStopData::StyleStopData(const StyleStopData& other) : RefCounted<StyleStopData>() , opacity(other.opacity) , color(other.color) { } +Ref<StyleStopData> StyleStopData::copy() const +{ + return adoptRef(*new StyleStopData(*this)); +} + bool StyleStopData::operator==(const StyleStopData& other) const { return color == other.color @@ -139,12 +154,17 @@ StyleTextData::StyleTextData() { } -StyleTextData::StyleTextData(const StyleTextData& other) +inline StyleTextData::StyleTextData(const StyleTextData& other) : RefCounted<StyleTextData>() , kerning(other.kerning) { } +Ref<StyleTextData> StyleTextData::copy() const +{ + return adoptRef(*new StyleTextData(*this)); +} + bool StyleTextData::operator==(const StyleTextData& other) const { return kerning == other.kerning; @@ -158,7 +178,7 @@ StyleMiscData::StyleMiscData() { } -StyleMiscData::StyleMiscData(const StyleMiscData& other) +inline StyleMiscData::StyleMiscData(const StyleMiscData& other) : RefCounted<StyleMiscData>() , floodColor(other.floodColor) , floodOpacity(other.floodOpacity) @@ -167,6 +187,11 @@ StyleMiscData::StyleMiscData(const StyleMiscData& other) { } +Ref<StyleMiscData> StyleMiscData::copy() const +{ + return adoptRef(*new StyleMiscData(*this)); +} + bool StyleMiscData::operator==(const StyleMiscData& other) const { return floodOpacity == other.floodOpacity @@ -179,40 +204,43 @@ StyleShadowSVGData::StyleShadowSVGData() { } -StyleShadowSVGData::StyleShadowSVGData(const StyleShadowSVGData& other) +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) +{ +} + +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()) { } -StyleResourceData::StyleResourceData(const StyleResourceData& other) +inline StyleResourceData::StyleResourceData(const StyleResourceData& other) : RefCounted<StyleResourceData>() , clipper(other.clipper) - , filter(other.filter) , masker(other.masker) { } +Ref<StyleResourceData> StyleResourceData::copy() const +{ + return adoptRef(*new StyleResourceData(*this)); +} + bool StyleResourceData::operator==(const StyleResourceData& other) const { return clipper == other.clipper - && filter == other.filter && masker == other.masker; } @@ -223,7 +251,7 @@ StyleInheritedResourceData::StyleInheritedResourceData() { } -StyleInheritedResourceData::StyleInheritedResourceData(const StyleInheritedResourceData& other) +inline StyleInheritedResourceData::StyleInheritedResourceData(const StyleInheritedResourceData& other) : RefCounted<StyleInheritedResourceData>() , markerStart(other.markerStart) , markerMid(other.markerMid) @@ -231,6 +259,11 @@ StyleInheritedResourceData::StyleInheritedResourceData(const StyleInheritedResou { } +Ref<StyleInheritedResourceData> StyleInheritedResourceData::copy() const +{ + return adoptRef(*new StyleInheritedResourceData(*this)); +} + bool StyleInheritedResourceData::operator==(const StyleInheritedResourceData& other) const { return markerStart == other.markerStart @@ -238,6 +271,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)); } -#endif // ENABLE(SVG) +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; +} + +} diff --git a/Source/WebCore/rendering/style/SVGRenderStyleDefs.h b/Source/WebCore/rendering/style/SVGRenderStyleDefs.h index b4c066805..883641970 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 @@ -28,12 +29,10 @@ #ifndef SVGRenderStyleDefs_h #define SVGRenderStyleDefs_h -#if ENABLE(SVG) +#include "Length.h" #include "SVGLength.h" #include "SVGPaint.h" #include "ShadowData.h" -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> @@ -94,6 +93,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 +117,8 @@ namespace WebCore { // Inherited/Non-Inherited Style Datastructures class StyleFillData : public RefCounted<StyleFillData> { public: - static PassRefPtr<StyleFillData> create() { return adoptRef(new StyleFillData); } - PassRefPtr<StyleFillData> copy() const { return adoptRef(new StyleFillData(*this)); } + static Ref<StyleFillData> create() { return adoptRef(*new StyleFillData); } + Ref<StyleFillData> copy() const; bool operator==(const StyleFillData&) const; bool operator!=(const StyleFillData& other) const @@ -125,8 +141,8 @@ namespace WebCore { class StyleStrokeData : public RefCounted<StyleStrokeData> { public: - static PassRefPtr<StyleStrokeData> create() { return adoptRef(new StyleStrokeData); } - PassRefPtr<StyleStrokeData> copy() const { return adoptRef(new StyleStrokeData(*this)); } + static Ref<StyleStrokeData> create() { return adoptRef(*new StyleStrokeData); } + Ref<StyleStrokeData> copy() const; bool operator==(const StyleStrokeData&) const; bool operator!=(const StyleStrokeData& other) const @@ -137,8 +153,8 @@ namespace WebCore { float opacity; float miterLimit; - SVGLength width; - SVGLength dashOffset; + Length width; + Length dashOffset; Vector<SVGLength> dashArray; SVGPaint::SVGPaintType paintType; @@ -155,8 +171,8 @@ namespace WebCore { class StyleStopData : public RefCounted<StyleStopData> { public: - static PassRefPtr<StyleStopData> create() { return adoptRef(new StyleStopData); } - PassRefPtr<StyleStopData> copy() const { return adoptRef(new StyleStopData(*this)); } + 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 +190,8 @@ namespace WebCore { class StyleTextData : public RefCounted<StyleTextData> { public: - static PassRefPtr<StyleTextData> create() { return adoptRef(new StyleTextData); } - PassRefPtr<StyleTextData> copy() const { return adoptRef(new StyleTextData(*this)); } + static Ref<StyleTextData> create() { return adoptRef(*new StyleTextData); } + Ref<StyleTextData> copy() const; bool operator==(const StyleTextData& other) const; bool operator!=(const StyleTextData& other) const @@ -193,8 +209,8 @@ namespace WebCore { // Note: the rule for this class is, *no inheritance* of these props class StyleMiscData : public RefCounted<StyleMiscData> { public: - static PassRefPtr<StyleMiscData> create() { return adoptRef(new StyleMiscData); } - PassRefPtr<StyleMiscData> copy() const { return adoptRef(new StyleMiscData(*this)); } + static Ref<StyleMiscData> create() { return adoptRef(*new StyleMiscData); } + Ref<StyleMiscData> copy() const; bool operator==(const StyleMiscData&) const; bool operator!=(const StyleMiscData& other) const @@ -216,8 +232,8 @@ namespace WebCore { class StyleShadowSVGData : public RefCounted<StyleShadowSVGData> { public: - static PassRefPtr<StyleShadowSVGData> create() { return adoptRef(new StyleShadowSVGData); } - PassRefPtr<StyleShadowSVGData> copy() const { return adoptRef(new StyleShadowSVGData(*this)); } + 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 +241,7 @@ namespace WebCore { return !(*this == other); } - OwnPtr<ShadowData> shadow; + std::unique_ptr<ShadowData> shadow; private: StyleShadowSVGData(); @@ -235,8 +251,8 @@ namespace WebCore { // Non-inherited resources class StyleResourceData : public RefCounted<StyleResourceData> { public: - static PassRefPtr<StyleResourceData> create() { return adoptRef(new StyleResourceData); } - PassRefPtr<StyleResourceData> copy() const { return adoptRef(new StyleResourceData(*this)); } + 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 +261,6 @@ namespace WebCore { } String clipper; - String filter; String masker; private: @@ -256,8 +271,8 @@ namespace WebCore { // Inherited resources class StyleInheritedResourceData : public RefCounted<StyleInheritedResourceData> { public: - static PassRefPtr<StyleInheritedResourceData> create() { return adoptRef(new StyleInheritedResourceData); } - PassRefPtr<StyleInheritedResourceData> copy() const { return adoptRef(new StyleInheritedResourceData(*this)); } + 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 +289,31 @@ namespace WebCore { StyleInheritedResourceData(const StyleInheritedResourceData&); }; + // Positioning and sizing properties. + class StyleLayoutData : public RefCounted<StyleLayoutData> { + public: + static Ref<StyleLayoutData> create() { return adoptRef(*new StyleLayoutData); } + Ref<StyleLayoutData> copy() const; + + 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 -#endif // ENABLE(SVG) #endif // SVGRenderStyleDefs_h diff --git a/Source/WebCore/rendering/style/ShadowData.cpp b/Source/WebCore/rendering/style/ShadowData.cpp index edd5b3755..4e5cb90f0 100644 --- a/Source/WebCore/rendering/style/ShadowData.cpp +++ b/Source/WebCore/rendering/style/ShadowData.cpp @@ -23,8 +23,7 @@ #include "ShadowData.h" #include "LayoutRect.h" - -using namespace std; +#include <wtf/PointerComparison.h> namespace WebCore { @@ -35,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 @@ -58,10 +56,10 @@ static inline void calculateShadowExtent(const ShadowData* shadow, int additiona do { int extentAndSpread = shadow->paintingExtent() + shadow->spread() + additionalOutlineSize; if (shadow->style() == Normal) { - shadowLeft = min(shadow->x() - extentAndSpread, shadowLeft); - shadowRight = max(shadow->x() + extentAndSpread, shadowRight); - shadowTop = min(shadow->y() - extentAndSpread, shadowTop); - shadowBottom = max(shadow->y() + extentAndSpread, shadowBottom); + shadowLeft = std::min(shadow->x() - extentAndSpread, shadowLeft); + shadowRight = std::max(shadow->x() + extentAndSpread, shadowRight); + shadowTop = std::min(shadow->y() - extentAndSpread, shadowTop); + shadowBottom = std::max(shadow->y() + extentAndSpread, shadowBottom); } shadow = shadow->next(); diff --git a/Source/WebCore/rendering/style/ShadowData.h b/Source/WebCore/rendering/style/ShadowData.h index 19be48d6c..4c3dab7a6 100644 --- a/Source/WebCore/rendering/style/ShadowData.h +++ b/Source/WebCore/rendering/style/ShadowData.h @@ -28,8 +28,6 @@ #include "Color.h" #include "FloatRect.h" #include "LayoutRect.h" -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> namespace WebCore { @@ -84,7 +82,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,7 +94,7 @@ private: Color m_color; ShadowStyle m_style; bool m_isWebkitBoxShadow; - OwnPtr<ShadowData> m_next; + std::unique_ptr<ShadowData> m_next; }; } // namespace WebCore diff --git a/Source/WebCore/rendering/style/ShapeValue.cpp b/Source/WebCore/rendering/style/ShapeValue.cpp new file mode 100644 index 000000000..2eef76042 --- /dev/null +++ b/Source/WebCore/rendering/style/ShapeValue.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2014 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" + +namespace WebCore { + +bool ShapeValue::isImageValid() const +{ + if (!image()) + return false; + if (image()->isCachedImage() || image()->isCachedImageSet()) + return image()->cachedImage() && image()->cachedImage()->hasImage(); + return image()->isGeneratedImage(); +} + +template <typename T> +bool pointersOrValuesEqual(T p1, T p2) +{ + if (p1 == p2) + return true; + + if (!p1 || !p2) + return false; + + return *p1 == *p2; +} + +bool ShapeValue::operator==(const ShapeValue& other) const +{ + if (m_type != other.m_type || m_cssBox != other.m_cssBox) + return false; + + return pointersOrValuesEqual(m_shape.get(), other.m_shape.get()) + && pointersOrValuesEqual(m_image.get(), other.m_image.get()); +} + + +} // namespace WebCore diff --git a/Source/WebCore/rendering/style/ShapeValue.h b/Source/WebCore/rendering/style/ShapeValue.h index 674aeeb29..f54678d71 100644 --- a/Source/WebCore/rendering/style/ShapeValue.h +++ b/Source/WebCore/rendering/style/ShapeValue.h @@ -31,6 +31,7 @@ #define ShapeValue_h #include "BasicShapes.h" +#include "CSSValueKeywords.h" #include "StyleImage.h" #include <wtf/PassRefPtr.h> @@ -38,56 +39,76 @@ namespace WebCore { class ShapeValue : public RefCounted<ShapeValue> { public: - enum ShapeValueType { - // The Auto value is defined by a null ShapeValue* + enum class Type { + // The None value is defined by a null ShapeValue* Shape, - Outside, + Box, Image }; - static PassRefPtr<ShapeValue> createShapeValue(PassRefPtr<BasicShape> shape) + static Ref<ShapeValue> createShapeValue(PassRefPtr<BasicShape> shape, CSSBoxType cssBox) { - return adoptRef(new ShapeValue(shape)); + return adoptRef(*new ShapeValue(shape, cssBox)); } - static PassRefPtr<ShapeValue> createOutsideValue() + static Ref<ShapeValue> createBoxShapeValue(CSSBoxType boxShape) { - return adoptRef(new ShapeValue(Outside)); + return adoptRef(*new ShapeValue(boxShape)); } - static PassRefPtr<ShapeValue> createImageValue(PassRefPtr<StyleImage> image) + static Ref<ShapeValue> createImageValue(PassRefPtr<StyleImage> image) { - return adoptRef(new ShapeValue(image)); + return adoptRef(*new ShapeValue(image)); } - ShapeValueType type() const { return m_type; } + Type type() const { return m_type; } BasicShape* shape() const { return m_shape.get(); } + CSSBoxType cssBox() const { return m_cssBox; } + StyleImage* image() const { return m_image.get(); } + + bool isImageValid() const; + void setImage(PassRefPtr<StyleImage> image) { + ASSERT(type() == Type::Image); if (m_image != image) m_image = image; } - bool operator==(const ShapeValue& other) const { return type() == other.type(); } + + bool operator==(const ShapeValue&) const; + bool operator!=(const ShapeValue& other) const + { + return !(*this == other); + } private: - ShapeValue(PassRefPtr<BasicShape> shape) - : m_type(Shape) + ShapeValue(PassRefPtr<BasicShape> shape, CSSBoxType cssBox) + : m_type(Type::Shape) , m_shape(shape) + , m_cssBox(cssBox) { } - ShapeValue(ShapeValueType type) + ShapeValue(Type type) : m_type(type) { } ShapeValue(PassRefPtr<StyleImage> image) - : m_type(Image) + : m_type(Type::Image) , m_image(image) { } - ShapeValueType m_type; + + ShapeValue(CSSBoxType cssBox) + : m_type(Type::Box) + , m_cssBox(cssBox) + { + } + + Type m_type; RefPtr<BasicShape> m_shape; RefPtr<StyleImage> m_image; + CSSBoxType m_cssBox { BoxMissing }; }; } diff --git a/Source/WebCore/rendering/style/StyleAllInOne.cpp b/Source/WebCore/rendering/style/StyleAllInOne.cpp index 74402cc79..7c6c079d6 100644 --- a/Source/WebCore/rendering/style/StyleAllInOne.cpp +++ b/Source/WebCore/rendering/style/StyleAllInOne.cpp @@ -25,9 +25,11 @@ // 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 "GridResolvedPosition.cpp" #include "KeyframeList.cpp" #include "NinePieceImage.cpp" #include "QuotesData.cpp" @@ -35,9 +37,11 @@ #include "SVGRenderStyle.cpp" #include "SVGRenderStyleDefs.cpp" #include "ShadowData.cpp" +#include "ShapeValue.cpp" #include "StyleBackgroundData.cpp" #include "StyleBoxData.cpp" #include "StyleCachedImage.cpp" +#include "StyleCachedImageSet.cpp" #include "StyleDeprecatedFlexibleBoxData.cpp" #include "StyleFilterData.cpp" #include "StyleFlexibleBoxData.cpp" @@ -49,6 +53,8 @@ #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 9407c1283..1ba36c4a8 100644 --- a/Source/WebCore/rendering/style/StyleBackgroundData.cpp +++ b/Source/WebCore/rendering/style/StyleBackgroundData.cpp @@ -33,7 +33,7 @@ StyleBackgroundData::StyleBackgroundData() { } -StyleBackgroundData::StyleBackgroundData(const StyleBackgroundData& o) +inline StyleBackgroundData::StyleBackgroundData(const StyleBackgroundData& o) : RefCounted<StyleBackgroundData>() , m_background(o.m_background) , m_color(o.m_color) @@ -41,6 +41,11 @@ StyleBackgroundData::StyleBackgroundData(const StyleBackgroundData& o) { } +Ref<StyleBackgroundData> StyleBackgroundData::copy() const +{ + return adoptRef(*new StyleBackgroundData(*this)); +} + bool StyleBackgroundData::operator==(const StyleBackgroundData& o) const { return m_background == o.m_background && m_color == o.m_color && m_outline == o.m_outline; diff --git a/Source/WebCore/rendering/style/StyleBackgroundData.h b/Source/WebCore/rendering/style/StyleBackgroundData.h index f632ca292..2e1b69820 100644 --- a/Source/WebCore/rendering/style/StyleBackgroundData.h +++ b/Source/WebCore/rendering/style/StyleBackgroundData.h @@ -35,8 +35,8 @@ namespace WebCore { class StyleBackgroundData : public RefCounted<StyleBackgroundData> { public: - static PassRefPtr<StyleBackgroundData> create() { return adoptRef(new StyleBackgroundData); } - PassRefPtr<StyleBackgroundData> copy() const { return adoptRef(new StyleBackgroundData(*this)); } + static Ref<StyleBackgroundData> create() { return adoptRef(*new StyleBackgroundData); } + Ref<StyleBackgroundData> copy() const; ~StyleBackgroundData() { } bool operator==(const StyleBackgroundData& o) const; diff --git a/Source/WebCore/rendering/style/StyleBoxData.cpp b/Source/WebCore/rendering/style/StyleBoxData.cpp index 3fc00c8dc..392708aae 100644 --- a/Source/WebCore/rendering/style/StyleBoxData.cpp +++ b/Source/WebCore/rendering/style/StyleBoxData.cpp @@ -49,7 +49,7 @@ StyleBoxData::StyleBoxData() { } -StyleBoxData::StyleBoxData(const StyleBoxData& o) +inline StyleBoxData::StyleBoxData(const StyleBoxData& o) : RefCounted<StyleBoxData>() , m_width(o.m_width) , m_height(o.m_height) @@ -67,6 +67,11 @@ StyleBoxData::StyleBoxData(const StyleBoxData& o) { } +Ref<StyleBoxData> StyleBoxData::copy() const +{ + return adoptRef(*new StyleBoxData(*this)); +} + bool StyleBoxData::operator==(const StyleBoxData& o) const { return m_width == o.m_width diff --git a/Source/WebCore/rendering/style/StyleBoxData.h b/Source/WebCore/rendering/style/StyleBoxData.h index 86fd6e922..ec255f291 100644 --- a/Source/WebCore/rendering/style/StyleBoxData.h +++ b/Source/WebCore/rendering/style/StyleBoxData.h @@ -34,8 +34,8 @@ namespace WebCore { class StyleBoxData : public RefCounted<StyleBoxData> { public: - static PassRefPtr<StyleBoxData> create() { return adoptRef(new StyleBoxData); } - PassRefPtr<StyleBoxData> copy() const { return adoptRef(new StyleBoxData(*this)); } + static Ref<StyleBoxData> create() { return adoptRef(*new StyleBoxData); } + Ref<StyleBoxData> copy() const; bool operator==(const StyleBoxData& o) const; bool operator!=(const StyleBoxData& o) const @@ -43,16 +43,16 @@ public: return !(*this == o); } - Length width() const { return m_width; } - Length height() const { return m_height; } + const Length& width() const { return m_width; } + const Length& height() const { return m_height; } - Length minWidth() const { return m_minWidth; } - Length minHeight() const { return m_minHeight; } + const Length& minWidth() const { return m_minWidth; } + const Length& minHeight() const { return m_minHeight; } - Length maxWidth() const { return m_maxWidth; } - Length maxHeight() const { return m_maxHeight; } + const Length& maxWidth() const { return m_maxWidth; } + const Length& maxHeight() const { return m_maxHeight; } - Length verticalAlign() const { return m_verticalAlign; } + const Length& verticalAlign() const { return m_verticalAlign; } int zIndex() const { return m_zIndex; } bool hasAutoZIndex() const { return m_hasAutoZIndex; } diff --git a/Source/WebCore/rendering/style/StyleCachedImage.cpp b/Source/WebCore/rendering/style/StyleCachedImage.cpp index 6a71286e0..e74940725 100644 --- a/Source/WebCore/rendering/style/StyleCachedImage.cpp +++ b/Source/WebCore/rendering/style/StyleCachedImage.cpp @@ -25,7 +25,7 @@ #include "StyleCachedImage.h" #include "CachedImage.h" -#include "RenderObject.h" +#include "RenderElement.h" namespace WebCore { @@ -61,7 +61,7 @@ bool StyleCachedImage::errorOccurred() const return m_image->errorOccurred(); } -LayoutSize StyleCachedImage::imageSize(const RenderObject* renderer, float multiplier) const +FloatSize StyleCachedImage::imageSize(const RenderElement* renderer, float multiplier) const { return m_image->imageSizeForRenderer(renderer, multiplier); } @@ -76,7 +76,7 @@ bool StyleCachedImage::imageHasRelativeHeight() const return m_image->imageHasRelativeHeight(); } -void StyleCachedImage::computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) +void StyleCachedImage::computeIntrinsicDimensions(const RenderElement*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) { m_image->computeIntrinsicDimensions(intrinsicWidth, intrinsicHeight, intrinsicRatio); } @@ -86,27 +86,27 @@ bool StyleCachedImage::usesImageContainerSize() const return m_image->usesImageContainerSize(); } -void StyleCachedImage::setContainerSizeForRenderer(const RenderObject* renderer, const IntSize& imageContainerSize, float imageContainerZoomFactor) +void StyleCachedImage::setContainerSizeForRenderer(const RenderElement* renderer, const FloatSize& imageContainerSize, float imageContainerZoomFactor) { - m_image->setContainerSizeForRenderer(renderer, imageContainerSize, imageContainerZoomFactor); + m_image->setContainerSizeForRenderer(renderer, LayoutSize(imageContainerSize), imageContainerZoomFactor); } -void StyleCachedImage::addClient(RenderObject* renderer) +void StyleCachedImage::addClient(RenderElement* renderer) { m_image->addClient(renderer); } -void StyleCachedImage::removeClient(RenderObject* renderer) +void StyleCachedImage::removeClient(RenderElement* renderer) { m_image->removeClient(renderer); } -PassRefPtr<Image> StyleCachedImage::image(RenderObject* renderer, const IntSize&) const +RefPtr<Image> StyleCachedImage::image(RenderElement* renderer, const FloatSize&) const { return m_image->imageForRenderer(renderer); } -bool StyleCachedImage::knownToBeOpaque(const RenderObject* renderer) const +bool StyleCachedImage::knownToBeOpaque(const RenderElement* renderer) const { return m_image->currentFrameKnownToBeOpaque(renderer); } diff --git a/Source/WebCore/rendering/style/StyleCachedImage.h b/Source/WebCore/rendering/style/StyleCachedImage.h index b81b43a52..2d20c34c8 100644 --- a/Source/WebCore/rendering/style/StyleCachedImage.h +++ b/Source/WebCore/rendering/style/StyleCachedImage.h @@ -32,36 +32,40 @@ namespace WebCore { class CachedImage; -class StyleCachedImage : public StyleImage, private CachedImageClient { +class StyleCachedImage final : public StyleImage, private CachedImageClient { WTF_MAKE_FAST_ALLOCATED; public: - static PassRefPtr<StyleCachedImage> create(CachedImage* image) { return adoptRef(new StyleCachedImage(image)); } + static Ref<StyleCachedImage> create(CachedImage* image) { return adoptRef(*new StyleCachedImage(image)); } virtual ~StyleCachedImage(); - virtual WrappedImagePtr data() const { return m_image.get(); } + virtual CachedImage* cachedImage() const override { return m_image.get(); } - virtual PassRefPtr<CSSValue> cssValue() const; - - virtual bool canRender(const RenderObject*, float multiplier) const; - virtual bool isLoaded() const; - virtual bool errorOccurred() const; - virtual LayoutSize imageSize(const RenderObject*, float multiplier) const OVERRIDE; - virtual bool imageHasRelativeWidth() const; - virtual bool imageHasRelativeHeight() const; - virtual void computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio); - virtual bool usesImageContainerSize() const; - virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize&, float); - virtual void addClient(RenderObject*); - virtual void removeClient(RenderObject*); - virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const; - virtual bool knownToBeOpaque(const RenderObject*) const OVERRIDE; - virtual CachedImage* cachedImage() const OVERRIDE { return m_image.get(); } - private: - explicit StyleCachedImage(CachedImage*); + virtual WrappedImagePtr data() const override { return m_image.get(); } + + virtual PassRefPtr<CSSValue> cssValue() const override; + virtual bool canRender(const RenderObject*, float multiplier) const override; + virtual bool isLoaded() const override; + virtual bool errorOccurred() const override; + virtual FloatSize 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 FloatSize&, float) override; + virtual void addClient(RenderElement*) override; + virtual void removeClient(RenderElement*) override; + virtual RefPtr<Image> image(RenderElement*, const FloatSize&) const override; + virtual bool knownToBeOpaque(const RenderElement*) const override; + + explicit StyleCachedImage(CachedImage*); + CachedResourceHandle<CachedImage> m_image; }; -} -#endif +} // namespace WebCore + +SPECIALIZE_TYPE_TRAITS_STYLE_IMAGE(StyleCachedImage, isCachedImage) + +#endif // StyleCachedImage_h diff --git a/Source/WebCore/rendering/style/StyleCachedImageSet.cpp b/Source/WebCore/rendering/style/StyleCachedImageSet.cpp index f4f2f8b30..19764f372 100644 --- a/Source/WebCore/rendering/style/StyleCachedImageSet.cpp +++ b/Source/WebCore/rendering/style/StyleCachedImageSet.cpp @@ -30,7 +30,7 @@ #include "CSSImageSetValue.h" #include "CachedImage.h" -#include "RenderObject.h" +#include "RenderElement.h" namespace WebCore { @@ -69,9 +69,9 @@ bool StyleCachedImageSet::errorOccurred() const return m_bestFitImage->errorOccurred(); } -LayoutSize StyleCachedImageSet::imageSize(const RenderObject* renderer, float multiplier) const +FloatSize StyleCachedImageSet::imageSize(const RenderElement* renderer, float multiplier) const { - LayoutSize scaledImageSize = m_bestFitImage->imageSizeForRenderer(renderer, multiplier); + FloatSize scaledImageSize = m_bestFitImage->imageSizeForRenderer(renderer, multiplier); scaledImageSize.scale(1 / m_imageScaleFactor); return scaledImageSize; } @@ -86,7 +86,7 @@ bool StyleCachedImageSet::imageHasRelativeHeight() const return m_bestFitImage->imageHasRelativeHeight(); } -void StyleCachedImageSet::computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) +void StyleCachedImageSet::computeIntrinsicDimensions(const RenderElement*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) { m_bestFitImage->computeIntrinsicDimensions(intrinsicWidth, intrinsicHeight, intrinsicRatio); } @@ -96,27 +96,27 @@ bool StyleCachedImageSet::usesImageContainerSize() const return m_bestFitImage->usesImageContainerSize(); } -void StyleCachedImageSet::setContainerSizeForRenderer(const RenderObject* renderer, const IntSize& imageContainerSize, float imageContainerZoomFactor) +void StyleCachedImageSet::setContainerSizeForRenderer(const RenderElement* renderer, const FloatSize& imageContainerSize, float imageContainerZoomFactor) { - m_bestFitImage->setContainerSizeForRenderer(renderer, imageContainerSize, imageContainerZoomFactor); + m_bestFitImage->setContainerSizeForRenderer(renderer, LayoutSize(imageContainerSize), imageContainerZoomFactor); } -void StyleCachedImageSet::addClient(RenderObject* renderer) +void StyleCachedImageSet::addClient(RenderElement* renderer) { m_bestFitImage->addClient(renderer); } -void StyleCachedImageSet::removeClient(RenderObject* renderer) +void StyleCachedImageSet::removeClient(RenderElement* renderer) { m_bestFitImage->removeClient(renderer); } -PassRefPtr<Image> StyleCachedImageSet::image(RenderObject* renderer, const IntSize&) const +RefPtr<Image> StyleCachedImageSet::image(RenderElement* renderer, const FloatSize&) const { return m_bestFitImage->imageForRenderer(renderer); } -bool StyleCachedImageSet::knownToBeOpaque(const RenderObject* renderer) const +bool StyleCachedImageSet::knownToBeOpaque(const RenderElement* renderer) const { return m_bestFitImage->currentFrameKnownToBeOpaque(renderer); } diff --git a/Source/WebCore/rendering/style/StyleCachedImageSet.h b/Source/WebCore/rendering/style/StyleCachedImageSet.h index 21b0e0cab..24d8330d9 100644 --- a/Source/WebCore/rendering/style/StyleCachedImageSet.h +++ b/Source/WebCore/rendering/style/StyleCachedImageSet.h @@ -40,41 +40,42 @@ class CSSImageSetValue; // This class keeps one cached image and has access to a set of alternatives. -class StyleCachedImageSet : public StyleImage, private CachedImageClient { +class StyleCachedImageSet final : public StyleImage, private CachedImageClient { WTF_MAKE_FAST_ALLOCATED; public: - static PassRefPtr<StyleCachedImageSet> create(CachedImage* image, float imageScaleFactor, CSSImageSetValue* value) + static Ref<StyleCachedImageSet> create(CachedImage* image, float imageScaleFactor, CSSImageSetValue* value) { - return adoptRef(new StyleCachedImageSet(image, imageScaleFactor, value)); + return adoptRef(*new StyleCachedImageSet(image, imageScaleFactor, value)); } virtual ~StyleCachedImageSet(); - virtual PassRefPtr<CSSValue> cssValue() const; + virtual CachedImage* cachedImage() const override { return m_bestFitImage.get(); } - // FIXME: This is used by StyleImage for equals comparison, but this implementation + 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 { return m_bestFitImage.get(); } - - void clearImageSetValue() { m_imageSetValue = 0; } - - virtual bool canRender(const RenderObject*, float multiplier) const; - virtual bool isLoaded() const; - virtual bool errorOccurred() const; - virtual LayoutSize imageSize(const RenderObject*, float multiplier) const; - virtual bool imageHasRelativeWidth() const; - virtual bool imageHasRelativeHeight() const; - virtual void computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio); - virtual bool usesImageContainerSize() const; - virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize&, float); - virtual void addClient(RenderObject*); - virtual void removeClient(RenderObject*); - virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const; - virtual float imageScaleFactor() const { return m_imageScaleFactor; } - virtual bool knownToBeOpaque(const RenderObject*) const OVERRIDE; - virtual CachedImage* cachedImage() const OVERRIDE { return m_bestFitImage.get(); } - -private: + 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 FloatSize 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 FloatSize&, float) override; + virtual void addClient(RenderElement*) override; + virtual void removeClient(RenderElement*) override; + virtual RefPtr<Image> image(RenderElement*, const FloatSize&) 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; @@ -84,6 +85,8 @@ private: } // namespace WebCore +SPECIALIZE_TYPE_TRAITS_STYLE_IMAGE(StyleCachedImageSet, isCachedImageSet) + #endif // ENABLE(CSS_IMAGE_SET) #endif // StyleCachedImageSet_h diff --git a/Source/WebCore/rendering/style/StyleCachedShader.cpp b/Source/WebCore/rendering/style/StyleCachedShader.cpp deleted file mode 100644 index d9118a15a..000000000 --- a/Source/WebCore/rendering/style/StyleCachedShader.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2011 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER “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 HOLDER 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" - -#if ENABLE(CSS_SHADERS) - -#include "StyleCachedShader.h" - -#include "CSSPrimitiveValue.h" -#include "CachedShader.h" - -namespace WebCore { - - -StyleCachedShader::StyleCachedShader(CachedShader* shader) - : m_shader(shader) -{ - m_isCachedShader = true; -} - -PassRefPtr<CSSValue> StyleCachedShader::cssValue() const -{ - return CSSPrimitiveValue::create(m_shader->url(), CSSPrimitiveValue::CSS_URI); -} - -} // namespace WebCore - -#endif // ENABLE(CSS_SHADERS) - diff --git a/Source/WebCore/rendering/style/StyleCachedShader.h b/Source/WebCore/rendering/style/StyleCachedShader.h deleted file mode 100644 index 15234295b..000000000 --- a/Source/WebCore/rendering/style/StyleCachedShader.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2011 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER “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 HOLDER 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 StyleCachedShader_h -#define StyleCachedShader_h - -#if ENABLE(CSS_SHADERS) - -#include "CachedResourceHandle.h" -#include "StyleShader.h" -#include <wtf/PassRefPtr.h> - -namespace WebCore { - -class CachedShader; - -class StyleCachedShader : public StyleShader { -public: - // FIXME: Keep a reference to the actual CachedShader in this class. - static PassRefPtr<StyleCachedShader> create(CachedShader* shader) { return adoptRef(new StyleCachedShader(shader)); } - - virtual PassRefPtr<CSSValue> cssValue() const; - - virtual CachedShader* cachedShader() const { return m_shader.get(); } - -private: - StyleCachedShader(CachedShader*); - - CachedResourceHandle<CachedShader> m_shader; -}; - -} -#endif // ENABLE(CSS_SHADERS) - -#endif // StyleCachedShader_h diff --git a/Source/WebCore/rendering/style/StyleContentAlignmentData.h b/Source/WebCore/rendering/style/StyleContentAlignmentData.h new file mode 100644 index 000000000..31b61b4c3 --- /dev/null +++ b/Source/WebCore/rendering/style/StyleContentAlignmentData.h @@ -0,0 +1,69 @@ +/* + * 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. + */ +#ifndef StyleContentAlignmentData_h +#define StyleContentAlignmentData_h + +#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 + +#endif // StyleContentAlignmentData_h diff --git a/Source/WebCore/rendering/style/StyleCustomFilterProgram.cpp b/Source/WebCore/rendering/style/StyleCustomFilterProgram.cpp deleted file mode 100644 index 5f4012f3f..000000000 --- a/Source/WebCore/rendering/style/StyleCustomFilterProgram.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2013 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER “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 HOLDER 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" - -#if ENABLE(CSS_SHADERS) - -#include "StyleCustomFilterProgram.h" - -#include "StyleCustomFilterProgramCache.h" - -namespace WebCore { - -StyleCustomFilterProgram::~StyleCustomFilterProgram() -{ - if (m_cache) - m_cache->remove(this); -} - -} // namespace WebCore - -#endif // ENABLE(CSS_SHADERS) - diff --git a/Source/WebCore/rendering/style/StyleCustomFilterProgram.h b/Source/WebCore/rendering/style/StyleCustomFilterProgram.h deleted file mode 100644 index 26ac02c9b..000000000 --- a/Source/WebCore/rendering/style/StyleCustomFilterProgram.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2012 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER “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 HOLDER 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 StyleCustomFilterProgram_h -#define StyleCustomFilterProgram_h - -#if ENABLE(CSS_SHADERS) -#include "CachedResourceClient.h" -#include "CachedResourceHandle.h" -#include "CachedShader.h" -#include "CustomFilterProgram.h" -#include "KURL.h" -#include "StyleShader.h" -#include <wtf/FastAllocBase.h> - -namespace WebCore { - -// CSS Shaders - -class StyleCustomFilterProgramCache; - -class StyleCustomFilterProgram : public CustomFilterProgram, public CachedResourceClient { - WTF_MAKE_FAST_ALLOCATED; -public: - static PassRefPtr<StyleCustomFilterProgram> create(KURL vertexShaderURL, PassRefPtr<StyleShader> vertexShader, - KURL fragmentShaderURL, PassRefPtr<StyleShader> fragmentShader, CustomFilterProgramType programType, - const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType) - { - return adoptRef(new StyleCustomFilterProgram(vertexShaderURL, vertexShader, fragmentShaderURL, fragmentShader, programType, mixSettings, meshType)); - } - - void setVertexShader(PassRefPtr<StyleShader> shader) - { - // The shader is immutable while in the cache. - ASSERT(!m_cache); - m_vertexShader = shader; - } - StyleShader* vertexShader() const { return m_vertexShader.get(); } - - void setFragmentShader(PassRefPtr<StyleShader> shader) - { - // The shader is immutable while in the cache. - ASSERT(!m_cache); - m_fragmentShader = shader; - } - StyleShader* fragmentShader() const { return m_fragmentShader.get(); } - - virtual String vertexShaderString() const - { - ASSERT(isLoaded()); - return m_cachedVertexShader.get() ? m_cachedVertexShader->shaderString() : String(); - } - - virtual String fragmentShaderString() const - { - ASSERT(isLoaded()); - return m_cachedFragmentShader.get() ? m_cachedFragmentShader->shaderString() : String(); - } - - virtual bool isLoaded() const - { - // Do not use the CachedResource:isLoaded method here, because it actually means !isLoading(), - // so missing and canceled resources will have isLoaded set to true, even if they are not loaded yet. - ASSERT(!m_vertexShader || m_vertexShader->isCachedShader()); - ASSERT(!m_fragmentShader || m_fragmentShader->isCachedShader()); - ASSERT(m_cachedVertexShader.get() || m_cachedFragmentShader.get()); - return (!m_cachedVertexShader.get() || m_isVertexShaderLoaded) - && (!m_cachedFragmentShader.get() || m_isFragmentShaderLoaded); - } - - virtual void willHaveClients() - { - if (m_vertexShader) { - m_cachedVertexShader = m_vertexShader->cachedShader(); - m_cachedVertexShader->addClient(this); - } - if (m_fragmentShader) { - m_cachedFragmentShader = m_fragmentShader->cachedShader(); - m_cachedFragmentShader->addClient(this); - } - } - - virtual void didRemoveLastClient() - { - if (m_cachedVertexShader.get()) { - m_cachedVertexShader->removeClient(this); - m_cachedVertexShader = 0; - m_isVertexShaderLoaded = false; - } - if (m_cachedFragmentShader.get()) { - m_cachedFragmentShader->removeClient(this); - m_cachedFragmentShader = 0; - m_isFragmentShaderLoaded = false; - } - } - - virtual void notifyFinished(CachedResource* resource) - { - if (resource->errorOccurred()) - return; - // Note that m_cachedVertexShader might be equal to m_cachedFragmentShader and it would only get one event in that case. - if (resource == m_cachedVertexShader.get()) - m_isVertexShaderLoaded = true; - if (resource == m_cachedFragmentShader.get()) - m_isFragmentShaderLoaded = true; - if (isLoaded()) - notifyClients(); - } - - bool hasPendingShaders() const - { - return (m_vertexShader && m_vertexShader->isPendingShader()) - || (m_fragmentShader && m_fragmentShader->isPendingShader()); - } - - // StyleCustomFilterProgramCache is responsible with updating the reference to the cache. - void setCache(StyleCustomFilterProgramCache* cache) { m_cache = cache; } - bool inCache() const { return m_cache; } - - KURL vertexShaderURL() const { return m_vertexShaderURL; } - KURL fragmentShaderURL() const { return m_fragmentShaderURL; } - -private: - StyleCustomFilterProgram(KURL vertexShaderURL, PassRefPtr<StyleShader> vertexShader, KURL fragmentShaderURL, PassRefPtr<StyleShader> fragmentShader, - CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType) - : CustomFilterProgram(programType, mixSettings, meshType) - , m_vertexShader(vertexShader) - , m_fragmentShader(fragmentShader) - , m_vertexShaderURL(vertexShaderURL) - , m_fragmentShaderURL(fragmentShaderURL) - , m_cache(0) - , m_isVertexShaderLoaded(false) - , m_isFragmentShaderLoaded(false) - { - } - - ~StyleCustomFilterProgram(); - - RefPtr<StyleShader> m_vertexShader; - RefPtr<StyleShader> m_fragmentShader; - - CachedResourceHandle<CachedShader> m_cachedVertexShader; - CachedResourceHandle<CachedShader> m_cachedFragmentShader; - - // The URLs form the key of the StyleCustomFilterProgram in the cache and are used - // to lookup the StyleCustomFilterProgram when it's removed from the cache. - KURL m_vertexShaderURL; - KURL m_fragmentShaderURL; - - // The Cache is responsible of invalidating this reference. - StyleCustomFilterProgramCache* m_cache; - - bool m_isVertexShaderLoaded; - bool m_isFragmentShaderLoaded; -}; - -} // namespace WebCore - -#endif // ENABLE(CSS_SHADERS) - -#endif // StyleCustomFilterProgram_h diff --git a/Source/WebCore/rendering/style/StyleCustomFilterProgramCache.cpp b/Source/WebCore/rendering/style/StyleCustomFilterProgramCache.cpp deleted file mode 100644 index 16b579f49..000000000 --- a/Source/WebCore/rendering/style/StyleCustomFilterProgramCache.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2013 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER “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 HOLDER 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" - -#if ENABLE(CSS_SHADERS) - -#include "StyleCustomFilterProgramCache.h" - -#include "CustomFilterProgramInfo.h" -#include "StyleCustomFilterProgram.h" - -namespace WebCore { - -static CustomFilterProgramInfo programCacheKey(StyleCustomFilterProgram* program) -{ - ASSERT(program->vertexShaderURL().isValid() || program->fragmentShaderURL().isValid()); - return CustomFilterProgramInfo(program->vertexShaderURL(), program->fragmentShaderURL(), - program->programType(), program->mixSettings(), program->meshType()); -} - -StyleCustomFilterProgramCache::StyleCustomFilterProgramCache() -{ -} - -StyleCustomFilterProgramCache::~StyleCustomFilterProgramCache() -{ - // Make sure the programs are not calling back into this object. - for (CacheMap::iterator iter = m_cache.begin(), end = m_cache.end(); iter != end; ++iter) - iter->value->setCache(0); -} - -StyleCustomFilterProgram* StyleCustomFilterProgramCache::lookup(const CustomFilterProgramInfo& programInfo) const -{ - CacheMap::const_iterator iter = m_cache.find(programInfo); - return iter != m_cache.end() ? iter->value : 0; -} - -StyleCustomFilterProgram* StyleCustomFilterProgramCache::lookup(StyleCustomFilterProgram* program) const -{ - return lookup(programCacheKey(program)); -} - -void StyleCustomFilterProgramCache::add(StyleCustomFilterProgram* program) -{ - CustomFilterProgramInfo key = programCacheKey(program); - ASSERT(m_cache.find(key) == m_cache.end()); - m_cache.set(key, program); - program->setCache(this); -} - -void StyleCustomFilterProgramCache::remove(StyleCustomFilterProgram* program) -{ - CacheMap::iterator iter = m_cache.find(programCacheKey(program)); - ASSERT(iter != m_cache.end()); - m_cache.remove(iter); -} - - -} // namespace WebCore - -#endif // ENABLE(CSS_SHADERS) - diff --git a/Source/WebCore/rendering/style/StyleCustomFilterProgramCache.h b/Source/WebCore/rendering/style/StyleCustomFilterProgramCache.h deleted file mode 100644 index e151836ca..000000000 --- a/Source/WebCore/rendering/style/StyleCustomFilterProgramCache.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2013 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER “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 HOLDER 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 StyleCustomFilterProgramCache_h -#define StyleCustomFilterProgramCache_h - -#if ENABLE(CSS_SHADERS) -#include "CustomFilterProgramInfo.h" -#include <wtf/FastAllocBase.h> -#include <wtf/HashMap.h> - -namespace WebCore { - -class StyleCustomFilterProgram; -class CustomFilterProgramInfo; - -class StyleCustomFilterProgramCache { - WTF_MAKE_FAST_ALLOCATED; -public: - StyleCustomFilterProgramCache(); - ~StyleCustomFilterProgramCache(); - - // Lookups a StyleCustomFilterProgram that has similar parameters with the specified program. - StyleCustomFilterProgram* lookup(StyleCustomFilterProgram*) const; - StyleCustomFilterProgram* lookup(const CustomFilterProgramInfo&) const; - - void add(StyleCustomFilterProgram*); - void remove(StyleCustomFilterProgram*); - -private: - typedef HashMap<CustomFilterProgramInfo, StyleCustomFilterProgram*> CacheMap; - CacheMap m_cache; -}; - -} // namespace WebCore - -#endif // ENABLE(CSS_SHADERS) - -#endif // StyleCustomFilterProgramCache_h diff --git a/Source/WebCore/rendering/style/StyleCustomPropertyData.h b/Source/WebCore/rendering/style/StyleCustomPropertyData.h new file mode 100644 index 000000000..c0a19684d --- /dev/null +++ b/Source/WebCore/rendering/style/StyleCustomPropertyData.h @@ -0,0 +1,88 @@ +/* + * 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. + * + */ + +#ifndef StyleCustomPropertyData_h +#define StyleCustomPropertyData_h + +#include "CSSValue.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& o) const + { + if (m_containsVariables != o.m_containsVariables) + return false; + + if (m_values.size() != o.m_values.size()) + return false; + + for (WTF::KeyValuePair<AtomicString, RefPtr<CSSValue>> entry : m_values) { + RefPtr<CSSValue> other = o.m_values.get(entry.key); + if (!other || !entry.value->equals(*other)) + return false; + } + return true; + } + + bool operator!=(const StyleCustomPropertyData &o) const { return !(*this == o); } + + void setCustomPropertyValue(const AtomicString& name, const RefPtr<CSSValue>& value) + { + m_values.set(name, value); + if (value->isVariableDependentValue()) + m_containsVariables = true; + } + + RefPtr<CSSValue> getCustomPropertyValue(const AtomicString& name) const { return m_values.get(name); } + CustomPropertyValueMap& values() { return m_values; } + + bool hasCustomProperty(const AtomicString& name) const { return m_values.contains(name); } + + bool containsVariables() const { return m_containsVariables; } + void setContainsVariables(bool containsVariables) { m_containsVariables = containsVariables; } + + CustomPropertyValueMap m_values; + bool m_containsVariables { false }; + +private: + explicit StyleCustomPropertyData() + : RefCounted<StyleCustomPropertyData>() + { } + StyleCustomPropertyData(const StyleCustomPropertyData& other) + : RefCounted<StyleCustomPropertyData>() + , m_values(CustomPropertyValueMap(other.m_values)) + , m_containsVariables(other.m_containsVariables) + { } +}; + +} // namespace WebCore + +#endif // StyleCustomPropertyData_h diff --git a/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.cpp b/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.cpp index 33c4c9847..32f7805eb 100644 --- a/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.cpp +++ b/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.cpp @@ -37,7 +37,7 @@ StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData() { } -StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData(const StyleDeprecatedFlexibleBoxData& o) +inline StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData(const StyleDeprecatedFlexibleBoxData& o) : RefCounted<StyleDeprecatedFlexibleBoxData>() , flex(o.flex) , flex_group(o.flex_group) @@ -49,6 +49,11 @@ StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData(const StyleDeprec { } +Ref<StyleDeprecatedFlexibleBoxData> StyleDeprecatedFlexibleBoxData::copy() const +{ + return adoptRef(*new StyleDeprecatedFlexibleBoxData(*this)); +} + bool StyleDeprecatedFlexibleBoxData::operator==(const StyleDeprecatedFlexibleBoxData& o) const { return flex == o.flex && flex_group == o.flex_group && diff --git a/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.h b/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.h index 33337bc67..20fee8bb2 100644 --- a/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.h +++ b/Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.h @@ -32,8 +32,8 @@ namespace WebCore { class StyleDeprecatedFlexibleBoxData : public RefCounted<StyleDeprecatedFlexibleBoxData> { public: - static PassRefPtr<StyleDeprecatedFlexibleBoxData> create() { return adoptRef(new StyleDeprecatedFlexibleBoxData); } - PassRefPtr<StyleDeprecatedFlexibleBoxData> copy() const { return adoptRef(new StyleDeprecatedFlexibleBoxData(*this)); } + static Ref<StyleDeprecatedFlexibleBoxData> create() { return adoptRef(*new StyleDeprecatedFlexibleBoxData); } + Ref<StyleDeprecatedFlexibleBoxData> copy() const; bool operator==(const StyleDeprecatedFlexibleBoxData&) const; bool operator!=(const StyleDeprecatedFlexibleBoxData& o) const diff --git a/Source/WebCore/rendering/style/StyleFilterData.cpp b/Source/WebCore/rendering/style/StyleFilterData.cpp index e55b25bdd..b0d3be110 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 @@ -27,9 +27,6 @@ #include "StyleFilterData.h" #include "FEGaussianBlur.h" - -#if ENABLE(CSS_FILTERS) - #include "RenderStyle.h" namespace WebCore { @@ -39,17 +36,20 @@ StyleFilterData::StyleFilterData() { } -StyleFilterData::StyleFilterData(const StyleFilterData& o) +inline StyleFilterData::StyleFilterData(const StyleFilterData& o) : RefCounted<StyleFilterData>() , m_operations(o.m_operations) { } +Ref<StyleFilterData> StyleFilterData::copy() const +{ + return adoptRef(*new StyleFilterData(*this)); +} + bool StyleFilterData::operator==(const StyleFilterData& o) const { return m_operations == o.m_operations; } } // namespace WebCore - -#endif // ENABLE(CSS_FILTERS) diff --git a/Source/WebCore/rendering/style/StyleFilterData.h b/Source/WebCore/rendering/style/StyleFilterData.h index 16b102e92..210d0ecb9 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 @@ -26,8 +26,6 @@ #ifndef StyleFilterData_h #define StyleFilterData_h -#if ENABLE(CSS_FILTERS) - #include "FilterOperations.h" #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> @@ -36,8 +34,8 @@ namespace WebCore { class StyleFilterData : public RefCounted<StyleFilterData> { public: - static PassRefPtr<StyleFilterData> create() { return adoptRef(new StyleFilterData); } - PassRefPtr<StyleFilterData> copy() const { return adoptRef(new StyleFilterData(*this)); } + static Ref<StyleFilterData> create() { return adoptRef(*new StyleFilterData); } + Ref<StyleFilterData> copy() const; bool operator==(const StyleFilterData&) const; bool operator!=(const StyleFilterData& o) const @@ -54,6 +52,4 @@ 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 a7cfac1ed..99e55eb7e 100644 --- a/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp +++ b/Source/WebCore/rendering/style/StyleFlexibleBoxData.cpp @@ -39,7 +39,7 @@ StyleFlexibleBoxData::StyleFlexibleBoxData() { } -StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& o) +inline StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& o) : RefCounted<StyleFlexibleBoxData>() , m_flexGrow(o.m_flexGrow) , m_flexShrink(o.m_flexShrink) @@ -49,6 +49,11 @@ StyleFlexibleBoxData::StyleFlexibleBoxData(const StyleFlexibleBoxData& o) { } +Ref<StyleFlexibleBoxData> StyleFlexibleBoxData::copy() const +{ + return adoptRef(*new StyleFlexibleBoxData(*this)); +} + bool StyleFlexibleBoxData::operator==(const StyleFlexibleBoxData& o) const { return m_flexGrow == o.m_flexGrow && m_flexShrink == o.m_flexShrink && m_flexBasis == o.m_flexBasis diff --git a/Source/WebCore/rendering/style/StyleFlexibleBoxData.h b/Source/WebCore/rendering/style/StyleFlexibleBoxData.h index 6c070d551..d332de552 100644 --- a/Source/WebCore/rendering/style/StyleFlexibleBoxData.h +++ b/Source/WebCore/rendering/style/StyleFlexibleBoxData.h @@ -35,8 +35,8 @@ namespace WebCore { class StyleFlexibleBoxData : public RefCounted<StyleFlexibleBoxData> { public: - static PassRefPtr<StyleFlexibleBoxData> create() { return adoptRef(new StyleFlexibleBoxData); } - PassRefPtr<StyleFlexibleBoxData> copy() const { return adoptRef(new StyleFlexibleBoxData(*this)); } + static Ref<StyleFlexibleBoxData> create() { return adoptRef(*new StyleFlexibleBoxData); } + Ref<StyleFlexibleBoxData> copy() const; bool operator==(const StyleFlexibleBoxData&) const; bool operator!=(const StyleFlexibleBoxData& o) const diff --git a/Source/WebCore/rendering/style/StyleGeneratedImage.cpp b/Source/WebCore/rendering/style/StyleGeneratedImage.cpp index b8161fefd..24ae933a9 100644 --- a/Source/WebCore/rendering/style/StyleGeneratedImage.cpp +++ b/Source/WebCore/rendering/style/StyleGeneratedImage.cpp @@ -25,13 +25,13 @@ #include "StyleGeneratedImage.h" #include "CSSImageGeneratorValue.h" -#include "RenderObject.h" +#include "RenderElement.h" #include "StyleResolver.h" namespace WebCore { -StyleGeneratedImage::StyleGeneratedImage(PassRefPtr<CSSImageGeneratorValue> value) - : m_imageGeneratorValue(value) +StyleGeneratedImage::StyleGeneratedImage(Ref<CSSImageGeneratorValue>&& value) + : m_imageGeneratorValue(WTFMove(value)) , m_fixedSize(m_imageGeneratorValue->isFixedSize()) { m_isGeneratedImage = true; @@ -39,57 +39,58 @@ StyleGeneratedImage::StyleGeneratedImage(PassRefPtr<CSSImageGeneratorValue> valu PassRefPtr<CSSValue> StyleGeneratedImage::cssValue() const { - return m_imageGeneratorValue; + return const_cast<CSSImageGeneratorValue*>(m_imageGeneratorValue.ptr()); } -LayoutSize StyleGeneratedImage::imageSize(const RenderObject* renderer, float multiplier) const +FloatSize StyleGeneratedImage::imageSize(const RenderElement* renderer, float multiplier) const { if (m_fixedSize) { - IntSize fixedSize = m_imageGeneratorValue->fixedSize(renderer); + FloatSize fixedSize = const_cast<CSSImageGeneratorValue&>(m_imageGeneratorValue.get()).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 = max<LayoutUnit>(1, width); + width = std::max<float>(1 / deviceScaleFactor, width); if (fixedSize.height() > 0) - height = max<LayoutUnit>(1, height); + height = std::max<float>(1 / deviceScaleFactor, height); - return LayoutSize(width, height); + return FloatSize(width, height); } return m_containerSize; } -void StyleGeneratedImage::computeIntrinsicDimensions(const RenderObject* renderer, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) +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; } -void StyleGeneratedImage::addClient(RenderObject* renderer) +void StyleGeneratedImage::addClient(RenderElement* renderer) { m_imageGeneratorValue->addClient(renderer); } -void StyleGeneratedImage::removeClient(RenderObject* renderer) +void StyleGeneratedImage::removeClient(RenderElement* renderer) { m_imageGeneratorValue->removeClient(renderer); } -PassRefPtr<Image> StyleGeneratedImage::image(RenderObject* renderer, const IntSize& size) const +RefPtr<Image> StyleGeneratedImage::image(RenderElement* renderer, const FloatSize& size) const { - return m_imageGeneratorValue->image(renderer, size); + return const_cast<CSSImageGeneratorValue&>(m_imageGeneratorValue.get()).image(renderer, size); } -bool StyleGeneratedImage::knownToBeOpaque(const RenderObject* renderer) const +bool StyleGeneratedImage::knownToBeOpaque(const RenderElement* renderer) const { return m_imageGeneratorValue->knownToBeOpaque(renderer); } diff --git a/Source/WebCore/rendering/style/StyleGeneratedImage.h b/Source/WebCore/rendering/style/StyleGeneratedImage.h index 57f78dd58..db49dd544 100644 --- a/Source/WebCore/rendering/style/StyleGeneratedImage.h +++ b/Source/WebCore/rendering/style/StyleGeneratedImage.h @@ -31,35 +31,40 @@ namespace WebCore { class CSSValue; class CSSImageGeneratorValue; -class StyleGeneratedImage : public StyleImage { +class StyleGeneratedImage final : public StyleImage { public: - static PassRefPtr<StyleGeneratedImage> create(CSSImageGeneratorValue* value) + static Ref<StyleGeneratedImage> create(Ref<CSSImageGeneratorValue>&& value) { - return adoptRef(new StyleGeneratedImage(value)); + return adoptRef(*new StyleGeneratedImage(WTFMove(value))); } - virtual WrappedImagePtr data() const { return m_imageGeneratorValue.get(); } + CSSImageGeneratorValue& imageValue() { return m_imageGeneratorValue; } - virtual PassRefPtr<CSSValue> cssValue() const; - - virtual LayoutSize imageSize(const RenderObject*, float multiplier) const OVERRIDE; - virtual bool imageHasRelativeWidth() const { return !m_fixedSize; } - virtual bool imageHasRelativeHeight() const { return !m_fixedSize; } - virtual void computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio); - virtual bool usesImageContainerSize() const { return !m_fixedSize; } - virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize& containerSize, float) { m_containerSize = containerSize; } - virtual void addClient(RenderObject*); - virtual void removeClient(RenderObject*); - virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const; - virtual bool knownToBeOpaque(const RenderObject*) const OVERRIDE; - private: - StyleGeneratedImage(PassRefPtr<CSSImageGeneratorValue>); + virtual WrappedImagePtr data() const override { return m_imageGeneratorValue.ptr(); } + + virtual PassRefPtr<CSSValue> cssValue() const override; + + virtual FloatSize 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 FloatSize& containerSize, float) override { m_containerSize = containerSize; } + virtual void addClient(RenderElement*) override; + virtual void removeClient(RenderElement*) override; + virtual RefPtr<Image> image(RenderElement*, const FloatSize&) const override; + virtual bool knownToBeOpaque(const RenderElement*) const override; + + explicit StyleGeneratedImage(Ref<CSSImageGeneratorValue>&&); - RefPtr<CSSImageGeneratorValue> m_imageGeneratorValue; - IntSize m_containerSize; + Ref<CSSImageGeneratorValue> m_imageGeneratorValue; + FloatSize m_containerSize; bool m_fixedSize; }; -} -#endif +} // namespace WebCore + +SPECIALIZE_TYPE_TRAITS_STYLE_IMAGE(StyleGeneratedImage, isGeneratedImage) + +#endif // StyleGeneratedImage_h diff --git a/Source/WebCore/rendering/style/StyleGridData.cpp b/Source/WebCore/rendering/style/StyleGridData.cpp index 9cffeabcf..fa22ed2c3 100644 --- a/Source/WebCore/rendering/style/StyleGridData.cpp +++ b/Source/WebCore/rendering/style/StyleGridData.cpp @@ -26,6 +26,8 @@ #include "config.h" #include "StyleGridData.h" +#if ENABLE(CSS_GRID_LAYOUT) + #include "RenderStyle.h" namespace WebCore { @@ -33,21 +35,45 @@ namespace WebCore { StyleGridData::StyleGridData() : m_gridColumns(RenderStyle::initialGridColumns()) , m_gridRows(RenderStyle::initialGridRows()) + , m_namedGridColumnLines(RenderStyle::initialNamedGridColumnLines()) + , m_namedGridRowLines(RenderStyle::initialNamedGridRowLines()) + , m_orderedNamedGridColumnLines(RenderStyle::initialOrderedNamedGridColumnLines()) + , m_orderedNamedGridRowLines(RenderStyle::initialOrderedNamedGridRowLines()) , m_gridAutoFlow(RenderStyle::initialGridAutoFlow()) , m_gridAutoRows(RenderStyle::initialGridAutoRows()) , m_gridAutoColumns(RenderStyle::initialGridAutoColumns()) + , m_namedGridArea(RenderStyle::initialNamedGridArea()) + , m_namedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount()) + , m_namedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount()) + , m_gridColumnGap(RenderStyle::initialGridColumnGap()) + , m_gridRowGap(RenderStyle::initialGridRowGap()) { } -StyleGridData::StyleGridData(const StyleGridData& o) +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_orderedNamedGridColumnLines(o.m_orderedNamedGridColumnLines) + , m_orderedNamedGridRowLines(o.m_orderedNamedGridRowLines) , 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) + , m_gridColumnGap(o.m_gridColumnGap) + , m_gridRowGap(o.m_gridRowGap) +{ +} + +Ref<StyleGridData> StyleGridData::copy() const { + return adoptRef(*new StyleGridData(*this)); } } // namespace WebCore +#endif /* ENABLE(CSS_GRID_LAYOUT) */ diff --git a/Source/WebCore/rendering/style/StyleGridData.h b/Source/WebCore/rendering/style/StyleGridData.h index f6849820c..d895cdaa7 100644 --- a/Source/WebCore/rendering/style/StyleGridData.h +++ b/Source/WebCore/rendering/style/StyleGridData.h @@ -26,22 +26,36 @@ #ifndef StyleGridData_h #define StyleGridData_h +#if ENABLE(CSS_GRID_LAYOUT) + +#include "GridCoordinate.h" #include "GridTrackSize.h" #include "RenderStyleConstants.h" #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/Vector.h> +#include <wtf/text/WTFString.h> namespace WebCore { +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 PassRefPtr<StyleGridData> create() { return adoptRef(new StyleGridData); } - PassRefPtr<StyleGridData> copy() const { return adoptRef(new StyleGridData(*this)); } + static Ref<StyleGridData> create() { return adoptRef(*new StyleGridData); } + Ref<StyleGridData> copy() const; bool operator==(const StyleGridData& o) const { - 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; + // 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 + && m_orderedNamedGridRowLines == o.m_orderedNamedGridRowLines && m_orderedNamedGridColumnLines == o.m_orderedNamedGridColumnLines + && m_gridColumnGap == o.m_gridColumnGap && m_gridRowGap == o.m_gridRowGap; } bool operator!=(const StyleGridData& o) const @@ -53,11 +67,26 @@ public: Vector<GridTrackSize> m_gridColumns; Vector<GridTrackSize> m_gridRows; - GridAutoFlow m_gridAutoFlow; + NamedGridLinesMap m_namedGridColumnLines; + NamedGridLinesMap m_namedGridRowLines; + + OrderedNamedGridLinesMap m_orderedNamedGridColumnLines; + OrderedNamedGridLinesMap m_orderedNamedGridRowLines; + + unsigned m_gridAutoFlow : GridAutoFlowBits; GridTrackSize m_gridAutoRows; GridTrackSize m_gridAutoColumns; + NamedGridAreaMap m_namedGridArea; + // Because m_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. + unsigned m_namedGridAreaRowCount; + unsigned m_namedGridAreaColumnCount; + + Length m_gridColumnGap; + Length m_gridRowGap; + private: StyleGridData(); StyleGridData(const StyleGridData&); @@ -65,4 +94,6 @@ private: } // namespace WebCore +#endif /* ENABLE(CSS_GRID_LAYOUT) */ + #endif // StyleGridData_h diff --git a/Source/WebCore/rendering/style/StyleGridItemData.cpp b/Source/WebCore/rendering/style/StyleGridItemData.cpp index 9a64f051e..102be908d 100644 --- a/Source/WebCore/rendering/style/StyleGridItemData.cpp +++ b/Source/WebCore/rendering/style/StyleGridItemData.cpp @@ -30,25 +30,34 @@ #include "config.h" #include "StyleGridItemData.h" +#if ENABLE(CSS_GRID_LAYOUT) + #include "RenderStyle.h" namespace WebCore { StyleGridItemData::StyleGridItemData() - : m_gridStart(RenderStyle::initialGridPosition()) - , m_gridEnd(RenderStyle::initialGridPosition()) - , m_gridBefore(RenderStyle::initialGridPosition()) - , m_gridAfter(RenderStyle::initialGridPosition()) + : m_gridColumnStart(RenderStyle::initialGridItemColumnStart()) + , m_gridColumnEnd(RenderStyle::initialGridItemColumnEnd()) + , m_gridRowStart(RenderStyle::initialGridItemRowStart()) + , m_gridRowEnd(RenderStyle::initialGridItemRowEnd()) { } -StyleGridItemData::StyleGridItemData(const StyleGridItemData& o) +inline StyleGridItemData::StyleGridItemData(const StyleGridItemData& o) : RefCounted<StyleGridItemData>() - , m_gridStart(o.m_gridStart) - , m_gridEnd(o.m_gridEnd) - , m_gridBefore(o.m_gridBefore) - , m_gridAfter(o.m_gridAfter) + , m_gridColumnStart(o.m_gridColumnStart) + , m_gridColumnEnd(o.m_gridColumnEnd) + , m_gridRowStart(o.m_gridRowStart) + , m_gridRowEnd(o.m_gridRowEnd) { } +Ref<StyleGridItemData> StyleGridItemData::copy() const +{ + return adoptRef(*new StyleGridItemData(*this)); +} + } // namespace WebCore + +#endif /* ENABLE(CSS_GRID_LAYOUT) */ diff --git a/Source/WebCore/rendering/style/StyleGridItemData.h b/Source/WebCore/rendering/style/StyleGridItemData.h index 32fcb6f76..d6678174b 100644 --- a/Source/WebCore/rendering/style/StyleGridItemData.h +++ b/Source/WebCore/rendering/style/StyleGridItemData.h @@ -31,6 +31,7 @@ #ifndef StyleGridItemData_h #define StyleGridItemData_h +#if ENABLE(CSS_GRID_LAYOUT) #include "GridPosition.h" #include <wtf/PassRefPtr.h> @@ -41,13 +42,13 @@ namespace WebCore { class StyleGridItemData : public RefCounted<StyleGridItemData> { public: - static PassRefPtr<StyleGridItemData> create() { return adoptRef(new StyleGridItemData); } - PassRefPtr<StyleGridItemData> copy() const { return adoptRef(new StyleGridItemData(*this)); } + static Ref<StyleGridItemData> create() { return adoptRef(*new StyleGridItemData); } + Ref<StyleGridItemData> copy() const; bool operator==(const StyleGridItemData& o) const { - return m_gridStart == o.m_gridStart && m_gridEnd == o.m_gridEnd - && m_gridBefore == o.m_gridBefore && m_gridAfter == o.m_gridAfter; + return m_gridColumnStart == o.m_gridColumnStart && m_gridColumnEnd == o.m_gridColumnEnd + && m_gridRowStart == o.m_gridRowStart && m_gridRowEnd == o.m_gridRowEnd; } bool operator!=(const StyleGridItemData& o) const @@ -55,10 +56,10 @@ public: return !(*this == o); } - GridPosition m_gridStart; - GridPosition m_gridEnd; - GridPosition m_gridBefore; - GridPosition m_gridAfter; + GridPosition m_gridColumnStart; + GridPosition m_gridColumnEnd; + GridPosition m_gridRowStart; + GridPosition m_gridRowEnd; private: StyleGridItemData(); @@ -67,4 +68,6 @@ private: } // namespace WebCore +#endif /* ENABLE(CSS_GRID_LAYOUT) */ + #endif // StyleGridItemData_h diff --git a/Source/WebCore/rendering/style/StyleImage.h b/Source/WebCore/rendering/style/StyleImage.h index 70f336088..0e83f2e96 100644 --- a/Source/WebCore/rendering/style/StyleImage.h +++ b/Source/WebCore/rendering/style/StyleImage.h @@ -25,20 +25,21 @@ #define StyleImage_h #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 CSSValue; +class RenderElement; class RenderObject; -typedef void* WrappedImagePtr; +typedef const void* WrappedImagePtr; class StyleImage : public RefCounted<StyleImage> { public: @@ -54,18 +55,18 @@ public: virtual bool canRender(const RenderObject*, float /*multiplier*/) const { return true; } virtual bool isLoaded() const { return true; } virtual bool errorOccurred() const { return false; } - virtual LayoutSize imageSize(const RenderObject*, float multiplier) const = 0; - virtual void computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) = 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 RenderObject*, const IntSize&, float) = 0; - virtual void addClient(RenderObject*) = 0; - virtual void removeClient(RenderObject*) = 0; - virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const = 0; + virtual void setContainerSizeForRenderer(const RenderElement*, const FloatSize&, float) = 0; + virtual void addClient(RenderElement*) = 0; + virtual void removeClient(RenderElement*) = 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 RenderObject*) const = 0; + virtual bool knownToBeOpaque(const RenderElement*) const = 0; virtual CachedImage* cachedImage() const { return 0; } ALWAYS_INLINE bool isCachedImage() const { return m_isCachedImage; } @@ -73,16 +74,6 @@ public: ALWAYS_INLINE bool isGeneratedImage() const { return m_isGeneratedImage; } ALWAYS_INLINE bool isCachedImageSet() const { return m_isCachedImageSet; } - static bool imagesEquivalent(StyleImage* image1, StyleImage* image2) - { - if (image1 != image2) { - if (!image1 || !image2) - return false; - return *image1 == *image2; - } - return true; - } - protected: StyleImage() : m_isCachedImage(false) @@ -91,11 +82,17 @@ protected: , m_isCachedImageSet(false) { } - bool m_isCachedImage:1; - bool m_isPendingImage:1; - bool m_isGeneratedImage:1; - bool m_isCachedImageSet:1; + 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() + +#endif // StyleImage_h diff --git a/Source/WebCore/rendering/style/StyleInheritedData.cpp b/Source/WebCore/rendering/style/StyleInheritedData.cpp index b72395631..bfceeca72 100644 --- a/Source/WebCore/rendering/style/StyleInheritedData.cpp +++ b/Source/WebCore/rendering/style/StyleInheritedData.cpp @@ -30,6 +30,9 @@ StyleInheritedData::StyleInheritedData() : horizontal_border_spacing(RenderStyle::initialHorizontalBorderSpacing()) , vertical_border_spacing(RenderStyle::initialVerticalBorderSpacing()) , line_height(RenderStyle::initialLineHeight()) +#if ENABLE(IOS_TEXT_AUTOSIZING) + , specifiedLineHeight(RenderStyle::initialLineHeight()) +#endif , color(RenderStyle::initialColor()) , visitedLinkColor(RenderStyle::initialColor()) { @@ -39,21 +42,32 @@ StyleInheritedData::~StyleInheritedData() { } -StyleInheritedData::StyleInheritedData(const StyleInheritedData& o) +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) - , font(o.font) +#if ENABLE(IOS_TEXT_AUTOSIZING) + , specifiedLineHeight(o.specifiedLineHeight) +#endif + , fontCascade(o.fontCascade) , color(o.color) , visitedLinkColor(o.visitedLinkColor) { } +Ref<StyleInheritedData> StyleInheritedData::copy() const +{ + return adoptRef(*new StyleInheritedData(*this)); +} + bool StyleInheritedData::operator==(const StyleInheritedData& o) const { return line_height == o.line_height - && font == o.font +#if ENABLE(IOS_TEXT_AUTOSIZING) + && specifiedLineHeight == o.specifiedLineHeight +#endif + && fontCascade == o.fontCascade && color == o.color && visitedLinkColor == o.visitedLinkColor && horizontal_border_spacing == o.horizontal_border_spacing diff --git a/Source/WebCore/rendering/style/StyleInheritedData.h b/Source/WebCore/rendering/style/StyleInheritedData.h index 06a79273e..ae2cf678c 100644 --- a/Source/WebCore/rendering/style/StyleInheritedData.h +++ b/Source/WebCore/rendering/style/StyleInheritedData.h @@ -26,9 +26,9 @@ #define StyleInheritedData_h #include "Color.h" -#include "Font.h" +#include "FontCascade.h" #include "Length.h" -#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> @@ -36,8 +36,8 @@ namespace WebCore { class StyleInheritedData : public RefCounted<StyleInheritedData> { public: - static PassRefPtr<StyleInheritedData> create() { return adoptRef(new StyleInheritedData); } - PassRefPtr<StyleInheritedData> copy() const { return adoptRef(new StyleInheritedData(*this)); } + static Ref<StyleInheritedData> create() { return adoptRef(*new StyleInheritedData); } + Ref<StyleInheritedData> copy() const; ~StyleInheritedData(); bool operator==(const StyleInheritedData& o) const; @@ -52,8 +52,11 @@ public: // 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 specifiedLineHeight; +#endif - Font font; + FontCascade fontCascade; Color color; Color visitedLinkColor; diff --git a/Source/WebCore/rendering/style/StyleMarqueeData.cpp b/Source/WebCore/rendering/style/StyleMarqueeData.cpp index f0e824daf..597b3f776 100644 --- a/Source/WebCore/rendering/style/StyleMarqueeData.cpp +++ b/Source/WebCore/rendering/style/StyleMarqueeData.cpp @@ -35,7 +35,7 @@ StyleMarqueeData::StyleMarqueeData() { } -StyleMarqueeData::StyleMarqueeData(const StyleMarqueeData& o) +inline StyleMarqueeData::StyleMarqueeData(const StyleMarqueeData& o) : RefCounted<StyleMarqueeData>() , increment(o.increment) , speed(o.speed) @@ -45,6 +45,11 @@ StyleMarqueeData::StyleMarqueeData(const StyleMarqueeData& o) { } +Ref<StyleMarqueeData> StyleMarqueeData::copy() const +{ + return adoptRef(*new StyleMarqueeData(*this)); +} + bool StyleMarqueeData::operator==(const StyleMarqueeData& o) const { return increment == o.increment && speed == o.speed && direction == o.direction && diff --git a/Source/WebCore/rendering/style/StyleMarqueeData.h b/Source/WebCore/rendering/style/StyleMarqueeData.h index 5765f5d67..dd11a6ed1 100644 --- a/Source/WebCore/rendering/style/StyleMarqueeData.h +++ b/Source/WebCore/rendering/style/StyleMarqueeData.h @@ -34,8 +34,8 @@ namespace WebCore { class StyleMarqueeData : public RefCounted<StyleMarqueeData> { public: - static PassRefPtr<StyleMarqueeData> create() { return adoptRef(new StyleMarqueeData); } - PassRefPtr<StyleMarqueeData> copy() const { return adoptRef(new StyleMarqueeData(*this)); } + static Ref<StyleMarqueeData> create() { return adoptRef(*new StyleMarqueeData); } + Ref<StyleMarqueeData> copy() const; bool operator==(const StyleMarqueeData& o) const; bool operator!=(const StyleMarqueeData& o) const diff --git a/Source/WebCore/rendering/style/StyleMultiColData.cpp b/Source/WebCore/rendering/style/StyleMultiColData.cpp index 610277c20..5c90e20a1 100644 --- a/Source/WebCore/rendering/style/StyleMultiColData.cpp +++ b/Source/WebCore/rendering/style/StyleMultiColData.cpp @@ -33,16 +33,14 @@ StyleMultiColData::StyleMultiColData() , 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()) { } -StyleMultiColData::StyleMultiColData(const StyleMultiColData& o) +inline StyleMultiColData::StyleMultiColData(const StyleMultiColData& o) : RefCounted<StyleMultiColData>() , m_width(o.m_width) , m_count(o.m_count) @@ -52,22 +50,25 @@ StyleMultiColData::StyleMultiColData(const StyleMultiColData& o) , 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) { } +Ref<StyleMultiColData> StyleMultiColData::copy() const +{ + return adoptRef(*new StyleMultiColData(*this)); +} + bool StyleMultiColData::operator==(const StyleMultiColData& o) 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_columnSpan == o.m_columnSpan && m_breakAfter == o.m_breakAfter && m_breakInside == o.m_breakInside && m_axis == o.m_axis - && m_progression == o.m_progression; + && 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_axis == o.m_axis && m_progression == o.m_progression; } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleMultiColData.h b/Source/WebCore/rendering/style/StyleMultiColData.h index 888ae6d56..f16ea5fd9 100644 --- a/Source/WebCore/rendering/style/StyleMultiColData.h +++ b/Source/WebCore/rendering/style/StyleMultiColData.h @@ -37,8 +37,8 @@ namespace WebCore { class StyleMultiColData : public RefCounted<StyleMultiColData> { public: - static PassRefPtr<StyleMultiColData> create() { return adoptRef(new StyleMultiColData); } - PassRefPtr<StyleMultiColData> copy() const { return adoptRef(new StyleMultiColData(*this)); } + static Ref<StyleMultiColData> create() { return adoptRef(*new StyleMultiColData); } + Ref<StyleMultiColData> copy() const; bool operator==(const StyleMultiColData& o) const; bool operator!=(const StyleMultiColData &o) const @@ -62,10 +62,8 @@ public: 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 diff --git a/Source/WebCore/rendering/style/StylePendingImage.h b/Source/WebCore/rendering/style/StylePendingImage.h index 96e825c17..1924fba7a 100644 --- a/Source/WebCore/rendering/style/StylePendingImage.h +++ b/Source/WebCore/rendering/style/StylePendingImage.h @@ -13,7 +13,7 @@ * 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 @@ -34,9 +34,6 @@ #if ENABLE(CSS_IMAGE_SET) #include "CSSImageSetValue.h" #endif -#include "CSSImageValue.h" -#include "Image.h" -#include "StyleImage.h" namespace WebCore { @@ -44,38 +41,42 @@ namespace WebCore { // 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 { +class StylePendingImage final : public StyleImage { public: - static PassRefPtr<StylePendingImage> create(CSSValue* value) { return adoptRef(new StylePendingImage(value)); } + static Ref<StylePendingImage> create(CSSValue* value) { return adoptRef(*new StylePendingImage(value)); } - virtual WrappedImagePtr data() const { return static_cast<CSSImageValue*>(m_value); } + CSSImageValue* cssImageValue() const { return is<CSSImageValue>(m_value) ? downcast<CSSImageValue>(m_value) : nullptr; } + CSSImageGeneratorValue* cssImageGeneratorValue() const { return is<CSSImageGeneratorValue>(m_value) ? static_cast<CSSImageGeneratorValue*>(m_value) : nullptr; } + CSSCursorImageValue* cssCursorImageValue() const { return is<CSSCursorImageValue>(m_value) ? downcast<CSSCursorImageValue>(m_value) : nullptr; } - virtual PassRefPtr<CSSValue> cssValue() const { return m_value; } - CSSImageValue* cssImageValue() const { return m_value && m_value->isImageValue() ? static_cast<CSSImageValue*>(m_value) : 0; } - CSSImageGeneratorValue* cssImageGeneratorValue() const { return m_value && m_value->isImageGeneratorValue() ? static_cast<CSSImageGeneratorValue*>(m_value) : 0; } - CSSCursorImageValue* cssCursorImageValue() const { return m_value && m_value->isCursorImageValue() ? static_cast<CSSCursorImageValue*>(m_value) : 0; } #if ENABLE(CSS_IMAGE_SET) - CSSImageSetValue* cssImageSetValue() const { return m_value && m_value->isImageSetValue() ? static_cast<CSSImageSetValue*>(m_value) : 0; } + CSSImageSetValue* cssImageSetValue() const { return is<CSSImageSetValue>(m_value) ? downcast<CSSImageSetValue>(m_value) : nullptr; } #endif - void detachFromCSSValue() { m_value = 0; } - - virtual LayoutSize imageSize(const RenderObject*, float /*multiplier*/) const OVERRIDE { return LayoutSize(); } - virtual bool imageHasRelativeWidth() const { return false; } - virtual bool imageHasRelativeHeight() const { return false; } - virtual void computeIntrinsicDimensions(const RenderObject*, Length& /* intrinsicWidth */ , Length& /* intrinsicHeight */, FloatSize& /* intrinsicRatio */) { } - virtual bool usesImageContainerSize() const { return false; } - virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize&, float) { } - virtual void addClient(RenderObject*) { } - virtual void removeClient(RenderObject*) { } - virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const + 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 FloatSize imageSize(const RenderElement*, float /*multiplier*/) const override { return FloatSize(); } + 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 */) override { } + virtual bool usesImageContainerSize() const override { return false; } + virtual void setContainerSizeForRenderer(const RenderElement*, const FloatSize&, float) override { } + virtual void addClient(RenderElement*) override { } + virtual void removeClient(RenderElement*) override { } + + virtual RefPtr<Image> image(RenderElement*, const FloatSize&) const override { ASSERT_NOT_REACHED(); - return 0; + return nullptr; } - virtual bool knownToBeOpaque(const RenderObject*) const { return false; } + + virtual bool knownToBeOpaque(const RenderElement*) const override { return false; } -private: StylePendingImage(CSSValue* value) : m_value(value) { @@ -85,6 +86,8 @@ private: CSSValue* m_value; // Not retained; it owns us. }; -} +} // namespace WebCore -#endif +SPECIALIZE_TYPE_TRAITS_STYLE_IMAGE(StylePendingImage, isPendingImage) + +#endif // StylePendingImage_h diff --git a/Source/WebCore/rendering/style/StylePendingShader.h b/Source/WebCore/rendering/style/StylePendingShader.h deleted file mode 100644 index 98ad91c58..000000000 --- a/Source/WebCore/rendering/style/StylePendingShader.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2011 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER “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 HOLDER 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 StylePendingShader_h -#define StylePendingShader_h - -#if ENABLE(CSS_SHADERS) - -#include "CSSValue.h" -#include "StyleShader.h" -#include "WebKitCSSShaderValue.h" -#include <wtf/PassRefPtr.h> - -namespace WebCore { - -class WebKitCSSShaderValue; - -class StylePendingShader : public StyleShader { -public: - static PassRefPtr<StylePendingShader> create(WebKitCSSShaderValue* value) { return adoptRef(new StylePendingShader(value)); } - - virtual PassRefPtr<CSSValue> cssValue() const { return m_value; } - WebKitCSSShaderValue* cssShaderValue() const { return m_value; } -private: - StylePendingShader(WebKitCSSShaderValue* value) - : m_value(value) - { - m_isPendingShader = true; - } - - WebKitCSSShaderValue* m_value; // Not retained; it owns us. -}; - -} -#endif // ENABLE(CSS_SHADERS) - -#endif // StylePendingShader_h diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp index 2e1d9d0a6..2098b9179 100644 --- a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp +++ b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp @@ -23,15 +23,18 @@ #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 { -struct SameSizeAsStyleRareInheritedData : public RefCounted<SameSizeAsStyleRareInheritedData> { +struct GreaterThanOrSameSizeAsStyleRareInheritedData : public RefCounted<GreaterThanOrSameSizeAsStyleRareInheritedData> { void* styleImage; Color firstColor; float firstFloat; @@ -39,33 +42,39 @@ struct SameSizeAsStyleRareInheritedData : public RefCounted<SameSizeAsStyleRareI void* ownPtrs[1]; AtomicString atomicStrings[5]; void* refPtrs[2]; - Length lengths[1]; + Length lengths[2]; float secondFloat; - unsigned m_bitfields[2]; + unsigned m_bitfields[4]; short pagedMediaShorts[2]; unsigned unsigneds[1]; short hyphenationShorts[3]; +#if PLATFORM(IOS) + Color compositionColor; +#endif +#if ENABLE(IOS_TEXT_AUTOSIZING) + TextSizeAdjustment textSizeAdjust; +#endif + #if ENABLE(CSS_IMAGE_RESOLUTION) float imageResolutionFloats; #endif #if ENABLE(TOUCH_EVENTS) - Color touchColors; + Color tapHighlightColor; #endif -#if ENABLE(CSS_VARIABLES) - void* variableDataRefs[1]; -#endif + void* customPropertyDataRefs[1]; }; -COMPILE_ASSERT(sizeof(StyleRareInheritedData) == sizeof(SameSizeAsStyleRareInheritedData), StyleRareInheritedData_should_bit_pack); +COMPILE_ASSERT(sizeof(StyleRareInheritedData) <= sizeof(GreaterThanOrSameSizeAsStyleRareInheritedData), StyleRareInheritedData_should_bit_pack); StyleRareInheritedData::StyleRareInheritedData() : listStyleImage(RenderStyle::initialListStyleImage()) , textStrokeWidth(RenderStyle::initialTextStrokeWidth()) , indent(RenderStyle::initialTextIndent()) , m_effectiveZoom(RenderStyle::initialZoom()) + , m_customProperties(StyleCustomPropertyData::create()) , widows(RenderStyle::initialWidows()) , orphans(RenderStyle::initialOrphans()) , m_hasAutoWidows(true) @@ -76,15 +85,13 @@ StyleRareInheritedData::StyleRareInheritedData() , 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) - , m_textOrientation(TextOrientationVerticalRight) + , textEmphasisPosition(TextEmphasisPositionOver | TextEmphasisPositionRight) + , m_textOrientation(static_cast<unsigned>(TextOrientation::Mixed)) #if ENABLE(CSS3_TEXT) , m_textIndentLine(RenderStyle::initialTextIndentLine()) , m_textIndentType(RenderStyle::initialTextIndentType()) @@ -106,27 +113,36 @@ StyleRareInheritedData::StyleRareInheritedData() #if ENABLE(CSS3_TEXT) , m_textAlignLast(RenderStyle::initialTextAlignLast()) , m_textJustify(RenderStyle::initialTextJustify()) - , m_textUnderlinePosition(RenderStyle::initialTextUnderlinePosition()) #endif // CSS3_TEXT + , m_textDecorationSkip(RenderStyle::initialTextDecorationSkip()) + , m_textUnderlinePosition(RenderStyle::initialTextUnderlinePosition()) , m_rubyPosition(RenderStyle::initialRubyPosition()) + , m_textZoom(RenderStyle::initialTextZoom()) +#if PLATFORM(IOS) + , touchCalloutEnabled(RenderStyle::initialTouchCalloutEnabled()) +#endif +#if ENABLE(CSS_TRAILING_WORD) + , trailingWord(static_cast<unsigned>(RenderStyle::initialTrailingWord())) +#endif + , m_hangingPunctuation(RenderStyle::initialHangingPunctuation()) , hyphenationLimitBefore(-1) , hyphenationLimitAfter(-1) , hyphenationLimitLines(-1) , m_lineGrid(RenderStyle::initialLineGrid()) , m_tabSize(RenderStyle::initialTabSize()) +#if ENABLE(IOS_TEXT_AUTOSIZING) + , textSizeAdjust(RenderStyle::initialTextSizeAdjust()) +#endif #if ENABLE(CSS_IMAGE_RESOLUTION) , m_imageResolution(RenderStyle::initialImageResolution()) #endif #if ENABLE(TOUCH_EVENTS) , tapHighlightColor(RenderStyle::initialTapHighlightColor()) -#endif -{ -#if ENABLE(CSS_VARIABLES) - m_variables.init(); #endif +{ } -StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o) +inline StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o) : RefCounted<StyleRareInheritedData>() , listStyleImage(o.listStyleImage) , textStrokeColor(o.textStrokeColor) @@ -136,11 +152,11 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o) , 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) + , m_customProperties(o.m_customProperties) , widows(o.widows) , orphans(o.orphans) , m_hasAutoWidows(o.m_hasAutoWidows) @@ -151,9 +167,7 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o) , 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) @@ -181,49 +195,44 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o) #if ENABLE(CSS3_TEXT) , m_textAlignLast(o.m_textAlignLast) , m_textJustify(o.m_textJustify) - , m_textUnderlinePosition(o.m_textUnderlinePosition) #endif // CSS3_TEXT + , m_textDecorationSkip(o.m_textDecorationSkip) + , m_textUnderlinePosition(o.m_textUnderlinePosition) , m_rubyPosition(o.m_rubyPosition) + , m_textZoom(o.m_textZoom) +#if PLATFORM(IOS) + , touchCalloutEnabled(o.touchCalloutEnabled) +#endif +#if ENABLE(CSS_TRAILING_WORD) + , trailingWord(o.trailingWord) +#endif + , m_hangingPunctuation(o.m_hangingPunctuation) , 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 ENABLE(IOS_TEXT_AUTOSIZING) + , textSizeAdjust(o.textSizeAdjust) +#endif #if ENABLE(CSS_IMAGE_RESOLUTION) , m_imageResolution(o.m_imageResolution) #endif #if ENABLE(TOUCH_EVENTS) , tapHighlightColor(o.tapHighlightColor) #endif -#if ENABLE(CSS_VARIABLES) - , m_variables(o.m_variables) -#endif -{ -} - -StyleRareInheritedData::~StyleRareInheritedData() { } -static bool cursorDataEquivalent(const CursorList* c1, const CursorList* c2) +Ref<StyleRareInheritedData> StyleRareInheritedData::copy() const { - if (c1 == c2) - return true; - if ((!c1 && c2) || (c1 && !c2)) - return false; - return (*c1 == *c2); + return adoptRef(*new StyleRareInheritedData(*this)); } -static bool quotesDataEquivalent(const QuotesData* q1, const QuotesData* q2) +StyleRareInheritedData::~StyleRareInheritedData() { - if (q1 == q2) - return true; - if ((!q1 && q2) || (q1 && !q2)) - return false; - return (*q1 == *q2); } bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const @@ -238,9 +247,8 @@ 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 && widows == o.widows @@ -256,9 +264,10 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) && useTouchOverflowScrolling == o.useTouchOverflowScrolling #endif - && resize == o.resize +#if ENABLE(IOS_TEXT_AUTOSIZING) + && textSizeAdjust == o.textSizeAdjust +#endif && userSelect == o.userSelect - && colorSpace == o.colorSpace && speak == o.speak && hyphens == o.hyphens && hyphenationLimitBefore == o.hyphenationLimitBefore @@ -273,10 +282,12 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const && m_textIndentType == o.m_textIndentType #endif && m_lineBoxContain == o.m_lineBoxContain +#if PLATFORM(IOS) + && touchCalloutEnabled == o.touchCalloutEnabled +#endif && hyphenationString == o.hyphenationString - && locale == o.locale && textEmphasisCustomMark == o.textEmphasisCustomMark - && quotesDataEquivalent(quotes.get(), o.quotes.get()) + && arePointingToEqualData(quotes, o.quotes) && m_tabSize == o.m_tabSize && m_lineGrid == o.m_lineGrid #if ENABLE(CSS_IMAGE_ORIENTATION) @@ -291,24 +302,19 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const #if ENABLE(CSS3_TEXT) && m_textAlignLast == o.m_textAlignLast && m_textJustify == o.m_textJustify - && m_textUnderlinePosition == o.m_textUnderlinePosition #endif // CSS3_TEXT + && m_textDecorationSkip == o.m_textDecorationSkip + && m_textUnderlinePosition == o.m_textUnderlinePosition && m_rubyPosition == o.m_rubyPosition + && m_textZoom == o.m_textZoom && m_lineSnap == o.m_lineSnap -#if ENABLE(CSS_VARIABLES) - && m_variables == o.m_variables -#endif && 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; +#if ENABLE(CSS_TRAILING_WORD) + && trailingWord == o.trailingWord +#endif + && m_hangingPunctuation == o.m_hangingPunctuation + && m_customProperties == o.m_customProperties + && arePointingToEqualData(listStyleImage, o.listStyleImage); } } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.h b/Source/WebCore/rendering/style/StyleRareInheritedData.h index 34b80ea52..5f7c23636 100644 --- a/Source/WebCore/rendering/style/StyleRareInheritedData.h +++ b/Source/WebCore/rendering/style/StyleRareInheritedData.h @@ -26,14 +26,15 @@ #define StyleRareInheritedData_h #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(CSS_VARIABLES) -#include "DataRef.h" -#include "StyleVariableData.h" +#if ENABLE(IOS_TEXT_AUTOSIZING) +#include "TextSizeAdjustment.h" #endif namespace WebCore { @@ -48,8 +49,8 @@ class StyleImage; // actually uses one of these properties. class StyleRareInheritedData : public RefCounted<StyleRareInheritedData> { public: - static PassRefPtr<StyleRareInheritedData> create() { return adoptRef(new StyleRareInheritedData); } - PassRefPtr<StyleRareInheritedData> copy() const { return adoptRef(new StyleRareInheritedData(*this)); } + static Ref<StyleRareInheritedData> create() { return adoptRef(*new StyleRareInheritedData); } + Ref<StyleRareInheritedData> copy() const; ~StyleRareInheritedData(); bool operator==(const StyleRareInheritedData& o) const; @@ -57,7 +58,6 @@ public: { return !(*this == o); } - bool shadowDataEquivalent(const StyleRareInheritedData&) const; RefPtr<StyleImage> listStyleImage; @@ -70,12 +70,15 @@ 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; + + Length wordSpacing; + + DataRef<StyleCustomPropertyData> m_customProperties; // Paged media properties. short widows; @@ -89,14 +92,13 @@ 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 unsigned hyphens : 2; // Hyphens unsigned textEmphasisFill : 1; // TextEmphasisFill unsigned textEmphasisMark : 3; // TextEmphasisMark - unsigned textEmphasisPosition : 1; // TextEmphasisPosition + unsigned textEmphasisPosition : 4; // TextEmphasisPosition unsigned m_textOrientation : 2; // TextOrientation #if ENABLE(CSS3_TEXT) unsigned m_textIndentLine : 1; // TextIndentLine @@ -107,7 +109,7 @@ public: #if ENABLE(CSS_IMAGE_ORIENTATION) unsigned m_imageOrientation : 4; // ImageOrientationEnum #endif - unsigned m_imageRendering : 2; // EImageRendering + unsigned m_imageRendering : 3; // EImageRendering unsigned m_lineSnap : 2; // LineSnap unsigned m_lineAlign : 1; // LineAlign #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) @@ -119,24 +121,38 @@ public: #endif #if ENABLE(CSS3_TEXT) unsigned m_textAlignLast : 3; // TextAlignLast - unsigned m_textJustify : 3; // TextJustify - unsigned m_textUnderlinePosition : 3; // TextUnderlinePosition + unsigned m_textJustify : 2; // TextJustify #endif // CSS3_TEXT - unsigned m_rubyPosition : 1; // RubyPosition + unsigned m_textDecorationSkip : 5; // TextDecorationSkip + unsigned m_textUnderlinePosition : 3; // TextUnderlinePosition + unsigned m_rubyPosition : 2; // RubyPosition + unsigned m_textZoom: 1; // TextZoom + +#if PLATFORM(IOS) + unsigned touchCalloutEnabled : 1; +#endif + +#if ENABLE(CSS_TRAILING_WORD) + unsigned trailingWord : 1; +#endif + + unsigned m_hangingPunctuation : 4; AtomicString hyphenationString; short hyphenationLimitBefore; short hyphenationLimitAfter; short hyphenationLimitLines; - AtomicString locale; - AtomicString textEmphasisCustomMark; RefPtr<QuotesData> quotes; AtomicString m_lineGrid; unsigned m_tabSize; +#if ENABLE(IOS_TEXT_AUTOSIZING) + TextSizeAdjustment textSizeAdjust; +#endif + #if ENABLE(CSS_IMAGE_RESOLUTION) float m_imageResolution; #endif @@ -145,10 +161,6 @@ public: Color tapHighlightColor; #endif -#if ENABLE(CSS_VARIABLES) - DataRef<StyleVariableData> m_variables; -#endif - private: StyleRareInheritedData(); StyleRareInheritedData(const StyleRareInheritedData&); diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp index 966bfcb15..24ae59cf2 100644 --- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp +++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp @@ -30,6 +30,9 @@ #include "StyleTransformData.h" #include "StyleImage.h" #include "StyleResolver.h" +#include "StyleScrollSnapPoints.h" +#include <wtf/PointerComparison.h> +#include <wtf/RefPtr.h> namespace WebCore { @@ -41,31 +44,51 @@ StyleRareNonInheritedData::StyleRareNonInheritedData() , m_perspectiveOriginX(RenderStyle::initialPerspectiveOriginX()) , m_perspectiveOriginY(RenderStyle::initialPerspectiveOriginY()) , lineClamp(RenderStyle::initialLineClamp()) -#if ENABLE(DRAGGABLE_REGION) - , m_draggableRegionMode(DraggableRegionNone) + , m_initialLetter(RenderStyle::initialInitialLetter()) + , m_deprecatedFlexibleBox(StyleDeprecatedFlexibleBoxData::create()) + , m_flexibleBox(StyleFlexibleBoxData::create()) + , m_marquee(StyleMarqueeData::create()) + , m_multiCol(StyleMultiColData::create()) + , m_transform(StyleTransformData::create()) + , m_filter(StyleFilterData::create()) +#if ENABLE(FILTERS_LEVEL_2) + , m_backdropFilter(StyleFilterData::create()) #endif +#if ENABLE(CSS_GRID_LAYOUT) + , m_grid(StyleGridData::create()) + , m_gridItem(StyleGridItemData::create()) +#endif +#if ENABLE(CSS_SCROLL_SNAP) + , m_scrollSnapPoints(StyleScrollSnapPoints::create()) +#endif + , m_willChange(RenderStyle::initialWillChange()) , m_mask(FillLayer(MaskFillLayer)) - , m_pageSize() - , m_shapeInside(RenderStyle::initialShapeInside()) +#if ENABLE(CSS_SHAPES) , m_shapeOutside(RenderStyle::initialShapeOutside()) , m_shapeMargin(RenderStyle::initialShapeMargin()) - , m_shapePadding(RenderStyle::initialShapePadding()) + , m_shapeImageThreshold(RenderStyle::initialShapeImageThreshold()) +#endif , m_clipPath(RenderStyle::initialClipPath()) , m_visitedLinkBackgroundColor(RenderStyle::initialBackgroundColor()) , m_order(RenderStyle::initialOrder()) , m_flowThread(RenderStyle::initialFlowThread()) , m_regionThread(RenderStyle::initialRegionThread()) + , m_alignContent(RenderStyle::initialContentAlignment()) + , m_alignItems(RenderStyle::initialSelfAlignment()) + , m_alignSelf(RenderStyle::initialSelfAlignment()) + , m_justifyContent(RenderStyle::initialContentAlignment()) + , m_justifyItems(RenderStyle::initialSelfAlignment()) + , m_justifySelf(RenderStyle::initialSelfAlignment()) +#if ENABLE(TOUCH_EVENTS) + , m_touchAction(static_cast<unsigned>(RenderStyle::initialTouchAction())) +#endif +#if ENABLE(CSS_SCROLL_SNAP) + , m_scrollSnapType(static_cast<unsigned>(RenderStyle::initialScrollSnapType())) +#endif , 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()) , userDrag(RenderStyle::initialUserDrag()) , textOverflow(RenderStyle::initialTextOverflow()) , marginBeforeCollapse(MCOLLAPSE) @@ -73,23 +96,23 @@ StyleRareNonInheritedData::StyleRareNonInheritedData() , m_appearance(RenderStyle::initialAppearance()) , m_borderFit(RenderStyle::initialBorderFit()) , m_textCombine(RenderStyle::initialTextCombine()) -#if ENABLE(CSS3_TEXT) , m_textDecorationStyle(RenderStyle::initialTextDecorationStyle()) -#endif // CSS3_TEXT - , m_wrapFlow(RenderStyle::initialWrapFlow()) - , m_wrapThrough(RenderStyle::initialWrapThrough()) -#if USE(ACCELERATED_COMPOSITING) , m_runningAcceleratedAnimation(false) -#endif - , m_hasAspectRatio(false) + , m_aspectRatioType(RenderStyle::initialAspectRatioType()) #if ENABLE(CSS_COMPOSITING) , m_effectiveBlendMode(RenderStyle::initialBlendMode()) + , m_isolation(RenderStyle::initialIsolation()) #endif + , m_objectFit(RenderStyle::initialObjectFit()) + , m_breakBefore(RenderStyle::initialBreakBetween()) + , m_breakAfter(RenderStyle::initialBreakBetween()) + , m_breakInside(RenderStyle::initialBreakInside()) + , m_resize(RenderStyle::initialResize()) { m_maskBoxImage.setMaskDefaults(); } -StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInheritedData& o) +inline StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInheritedData& o) : RefCounted<StyleRareNonInheritedData>() , opacity(o.opacity) , m_aspectRatioDenominator(o.m_aspectRatioDenominator) @@ -98,37 +121,42 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited , m_perspectiveOriginX(o.m_perspectiveOriginX) , m_perspectiveOriginY(o.m_perspectiveOriginY) , lineClamp(o.lineClamp) -#if ENABLE(DRAGGABLE_REGION) - , m_draggableRegionMode(o.m_draggableRegionMode) -#endif + , m_initialLetter(o.m_initialLetter) , 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) +#if ENABLE(FILTERS_LEVEL_2) + , m_backdropFilter(o.m_backdropFilter) #endif +#if ENABLE(CSS_GRID_LAYOUT) , m_grid(o.m_grid) , m_gridItem(o.m_gridItem) +#endif +#if ENABLE(CSS_SCROLL_SNAP) + , m_scrollSnapPoints(o.m_scrollSnapPoints) +#endif , 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_altText(o.m_altText) + , m_boxShadow(o.m_boxShadow ? std::make_unique<ShadowData>(*o.m_boxShadow) : nullptr) + , m_willChange(o.m_willChange) , 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_animations(o.m_animations ? std::make_unique<AnimationList>(*o.m_animations) : nullptr) + , m_transitions(o.m_transitions ? std::make_unique<AnimationList>(*o.m_transitions) : nullptr) , m_mask(o.m_mask) , m_maskBoxImage(o.m_maskBoxImage) , m_pageSize(o.m_pageSize) - , m_shapeInside(o.m_shapeInside) +#if ENABLE(CSS_SHAPES) , m_shapeOutside(o.m_shapeOutside) , m_shapeMargin(o.m_shapeMargin) - , m_shapePadding(o.m_shapePadding) + , m_shapeImageThreshold(o.m_shapeImageThreshold) +#endif , m_clipPath(o.m_clipPath) -#if ENABLE(CSS3_TEXT) , m_textDecorationColor(o.m_textDecorationColor) , m_visitedLinkTextDecorationColor(o.m_visitedLinkTextDecorationColor) -#endif // CSS3_TEXT , m_visitedLinkBackgroundColor(o.m_visitedLinkBackgroundColor) , m_visitedLinkOutlineColor(o.m_visitedLinkOutlineColor) , m_visitedLinkBorderLeftColor(o.m_visitedLinkBorderLeftColor) @@ -138,17 +166,22 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited , 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) + , m_justifyItems(o.m_justifyItems) + , m_justifySelf(o.m_justifySelf) +#if ENABLE(TOUCH_EVENTS) + , m_touchAction(o.m_touchAction) +#endif +#if ENABLE(CSS_SCROLL_SNAP) + , m_scrollSnapType(o.m_scrollSnapType) +#endif + , m_regionFragment(o.m_regionFragment) + , m_pageSizeType(o.m_pageSizeType) + , m_transformStyle3D(o.m_transformStyle3D) + , m_backfaceVisibility(o.m_backfaceVisibility) , userDrag(o.userDrag) , textOverflow(o.textOverflow) , marginBeforeCollapse(o.marginBeforeCollapse) @@ -156,19 +189,24 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited , m_appearance(o.m_appearance) , m_borderFit(o.m_borderFit) , m_textCombine(o.m_textCombine) -#if ENABLE(CSS3_TEXT) , m_textDecorationStyle(o.m_textDecorationStyle) -#endif // CSS3_TEXT - , 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) + , m_aspectRatioType(o.m_aspectRatioType) #if ENABLE(CSS_COMPOSITING) , m_effectiveBlendMode(o.m_effectiveBlendMode) + , m_isolation(o.m_isolation) #endif + , m_objectFit(o.m_objectFit) + , m_breakBefore(o.m_breakBefore) + , m_breakAfter(o.m_breakAfter) + , m_breakInside(o.m_breakInside) + , m_resize(o.m_resize) +{ +} + +Ref<StyleRareNonInheritedData> StyleRareNonInheritedData::copy() const { + return adoptRef(*new StyleRareNonInheritedData(*this)); } StyleRareNonInheritedData::~StyleRareNonInheritedData() @@ -184,40 +222,45 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c && m_perspectiveOriginX == o.m_perspectiveOriginX && m_perspectiveOriginY == o.m_perspectiveOriginY && lineClamp == o.lineClamp + && m_initialLetter == o.m_initialLetter #if ENABLE(DASHBOARD_SUPPORT) && m_dashboardRegions == o.m_dashboardRegions #endif -#if ENABLE(DRAGGABLE_REGION) - && m_draggableRegionMode == o.m_draggableRegionMode -#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 +#if ENABLE(FILTERS_LEVEL_2) + && m_backdropFilter == o.m_backdropFilter #endif +#if ENABLE(CSS_GRID_LAYOUT) && m_grid == o.m_grid && m_gridItem == o.m_gridItem +#endif +#if ENABLE(CSS_SCROLL_SNAP) + && m_scrollSnapPoints == o.m_scrollSnapPoints +#endif && contentDataEquivalent(o) - && counterDataEquivalent(o) - && shadowDataEquivalent(o) - && reflectionDataEquivalent(o) - && animationDataEquivalent(o) - && transitionDataEquivalent(o) + && arePointingToEqualData(m_counterDirectives, o.m_counterDirectives) + && m_altText == o.m_altText + && arePointingToEqualData(m_boxShadow, o.m_boxShadow) + && arePointingToEqualData(m_willChange, o.m_willChange) + && arePointingToEqualData(m_boxReflect, o.m_boxReflect) + && arePointingToEqualData(m_animations, o.m_animations) + && arePointingToEqualData(m_transitions, o.m_transitions) && m_mask == o.m_mask && m_maskBoxImage == o.m_maskBoxImage && m_pageSize == o.m_pageSize - && m_shapeInside == o.m_shapeInside - && m_shapeOutside == o.m_shapeOutside +#if ENABLE(CSS_SHAPES) + && arePointingToEqualData(m_shapeOutside, o.m_shapeOutside) && m_shapeMargin == o.m_shapeMargin - && m_shapePadding == o.m_shapePadding - && m_clipPath == o.m_clipPath -#if ENABLE(CSS3_TEXT) + && m_shapeImageThreshold == o.m_shapeImageThreshold +#endif + && arePointingToEqualData(m_clipPath, o.m_clipPath) && m_textDecorationColor == o.m_textDecorationColor && m_visitedLinkTextDecorationColor == o.m_visitedLinkTextDecorationColor -#endif // CSS3_TEXT && m_visitedLinkBackgroundColor == o.m_visitedLinkBackgroundColor && m_visitedLinkOutlineColor == o.m_visitedLinkOutlineColor && m_visitedLinkBorderLeftColor == o.m_visitedLinkBorderLeftColor @@ -226,18 +269,17 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c && m_visitedLinkBorderBottomColor == o.m_visitedLinkBorderBottomColor && m_order == o.m_order && m_flowThread == o.m_flowThread + && m_alignContent == o.m_alignContent + && m_alignItems == o.m_alignItems + && m_alignSelf == o.m_alignSelf + && m_justifyContent == o.m_justifyContent + && m_justifyItems == o.m_justifyItems + && m_justifySelf == o.m_justifySelf && 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 && userDrag == o.userDrag && textOverflow == o.textOverflow && marginBeforeCollapse == o.marginBeforeCollapse @@ -245,18 +287,24 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c && m_appearance == o.m_appearance && m_borderFit == o.m_borderFit && m_textCombine == o.m_textCombine -#if ENABLE(CSS3_TEXT) && m_textDecorationStyle == o.m_textDecorationStyle -#endif // CSS3_TEXT - && m_wrapFlow == o.m_wrapFlow - && m_wrapThrough == o.m_wrapThrough -#if USE(ACCELERATED_COMPOSITING) - && !m_runningAcceleratedAnimation && !o.m_runningAcceleratedAnimation +#if ENABLE(TOUCH_EVENTS) + && m_touchAction == o.m_touchAction +#endif +#if ENABLE(CSS_SCROLL_SNAP) + && m_scrollSnapType == o.m_scrollSnapType #endif + && !m_runningAcceleratedAnimation && !o.m_runningAcceleratedAnimation #if ENABLE(CSS_COMPOSITING) && m_effectiveBlendMode == o.m_effectiveBlendMode + && m_isolation == o.m_isolation #endif - && m_hasAspectRatio == o.m_hasAspectRatio; + && m_aspectRatioType == o.m_aspectRatioType + && m_objectFit == o.m_objectFit + && m_breakAfter == o.m_breakAfter + && m_breakBefore == o.m_breakBefore + && m_breakInside == o.m_breakInside + && m_resize == o.m_resize; } bool StyleRareNonInheritedData::contentDataEquivalent(const StyleRareNonInheritedData& o) const @@ -272,52 +320,16 @@ bool StyleRareNonInheritedData::contentDataEquivalent(const StyleRareNonInherite return !a && !b; } -bool StyleRareNonInheritedData::counterDataEquivalent(const StyleRareNonInheritedData& o) const +bool StyleRareNonInheritedData::hasFilters() 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 -{ - if (m_boxReflect != o.m_boxReflect) { - if (!m_boxReflect || !o.m_boxReflect) - return false; - return *m_boxReflect == *o.m_boxReflect; - } - return true; -} - -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; + return m_filter.get() && !m_filter->m_operations.isEmpty(); } -bool StyleRareNonInheritedData::transitionDataEquivalent(const StyleRareNonInheritedData& o) const +#if ENABLE(FILTERS_LEVEL_2) +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 m_backdropFilter.get() && !m_backdropFilter->m_operations.isEmpty(); } +#endif } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h index 11625b3de..9b1b2ad53 100644 --- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h +++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h @@ -26,6 +26,7 @@ #define StyleRareNonInheritedData_h #include "BasicShapes.h" +#include "CSSPropertyNames.h" #include "ClipPathOperation.h" #include "CounterDirectives.h" #include "CursorData.h" @@ -34,7 +35,10 @@ #include "LineClampValue.h" #include "NinePieceImage.h" #include "ShapeValue.h" -#include <wtf/OwnPtr.h> +#include "StyleContentAlignmentData.h" +#include "StyleSelfAlignmentData.h" +#include "WillChangeData.h" +#include <memory> #include <wtf/PassRefPtr.h> #include <wtf/Vector.h> @@ -43,17 +47,20 @@ namespace WebCore { class AnimationList; class ShadowData; class StyleDeprecatedFlexibleBoxData; -#if ENABLE(CSS_FILTERS) class StyleFilterData; -#endif class StyleFlexibleBoxData; +#if ENABLE(CSS_GRID_LAYOUT) class StyleGridData; class StyleGridItemData; +#endif class StyleMarqueeData; class StyleMultiColData; class StyleReflection; class StyleResolver; class StyleTransformData; +#if ENABLE(CSS_SCROLL_SNAP) +class StyleScrollSnapPoints; +#endif class ContentData; struct LengthSize; @@ -77,21 +84,24 @@ enum PageSizeType { // actually uses one of these properties. class StyleRareNonInheritedData : public RefCounted<StyleRareNonInheritedData> { public: - static PassRefPtr<StyleRareNonInheritedData> create() { return adoptRef(new StyleRareNonInheritedData); } - PassRefPtr<StyleRareNonInheritedData> copy() const { return adoptRef(new StyleRareNonInheritedData(*this)); } + 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 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; - float opacity; // Whether or not we're transparent. + bool hasFilters() const; +#if ENABLE(FILTERS_LEVEL_2) + bool hasBackdropFilters() const; +#endif + bool hasOpacity() const { return opacity < 1; } + + bool hasAnimationsOrTransitions() const { return m_animations || m_transitions; } + + float opacity; float m_aspectRatioDenominator; float m_aspectRatioNumerator; @@ -101,52 +111,60 @@ public: Length m_perspectiveOriginY; LineClampValue lineClamp; // An Apple extension. + + IntSize m_initialLetter; + #if ENABLE(DASHBOARD_SUPPORT) Vector<StyleDashboardRegion> m_dashboardRegions; #endif -#if ENABLE(DRAGGABLE_REGION) - DraggableRegionMode m_draggableRegionMode; -#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.) - -#if ENABLE(CSS_FILTERS) DataRef<StyleFilterData> m_filter; // Filter operations (url, sepia, blur, etc.) +#if ENABLE(FILTERS_LEVEL_2) + DataRef<StyleFilterData> m_backdropFilter; // Filter operations (url, sepia, blur, etc.) #endif +#if ENABLE(CSS_GRID_LAYOUT) DataRef<StyleGridData> m_grid; DataRef<StyleGridItemData> m_gridItem; +#endif + +#if ENABLE(CSS_SCROLL_SNAP) + DataRef<StyleScrollSnapPoints> m_scrollSnapPoints; +#endif - OwnPtr<ContentData> m_content; - OwnPtr<CounterDirectiveMap> m_counterDirectives; + std::unique_ptr<ContentData> m_content; + std::unique_ptr<CounterDirectiveMap> m_counterDirectives; + String m_altText; - OwnPtr<ShadowData> m_boxShadow; // For box-shadow decorations. + std::unique_ptr<ShadowData> m_boxShadow; // For box-shadow decorations. + + RefPtr<WillChangeData> m_willChange; // Null indicates 'auto'. RefPtr<StyleReflection> m_boxReflect; - OwnPtr<AnimationList> m_animations; - OwnPtr<AnimationList> m_transitions; + std::unique_ptr<AnimationList> m_animations; + std::unique_ptr<AnimationList> m_transitions; FillLayer m_mask; NinePieceImage m_maskBoxImage; LengthSize m_pageSize; - RefPtr<ShapeValue> m_shapeInside; +#if ENABLE(CSS_SHAPES) RefPtr<ShapeValue> m_shapeOutside; Length m_shapeMargin; - Length m_shapePadding; + float m_shapeImageThreshold; +#endif RefPtr<ClipPathOperation> m_clipPath; -#if ENABLE(CSS3_TEXT) Color m_textDecorationColor; Color m_visitedLinkTextDecorationColor; -#endif // CSS3_TEXT Color m_visitedLinkBackgroundColor; Color m_visitedLinkOutlineColor; Color m_visitedLinkBorderLeftColor; @@ -158,20 +176,28 @@ public: AtomicString m_flowThread; AtomicString m_regionThread; - unsigned m_regionFragment : 1; // RegionFragment - unsigned m_regionBreakAfter : 2; // EPageBreak - unsigned m_regionBreakBefore : 2; // EPageBreak - unsigned m_regionBreakInside : 2; // EPageBreak + StyleContentAlignmentData m_alignContent; + StyleSelfAlignmentData m_alignItems; + StyleSelfAlignmentData m_alignSelf; + StyleContentAlignmentData m_justifyContent; + StyleSelfAlignmentData m_justifyItems; + StyleSelfAlignmentData m_justifySelf; + +#if ENABLE(TOUCH_EVENTS) + unsigned m_touchAction : 1; // TouchAction +#endif + +#if ENABLE(CSS_SCROLL_SNAP) + unsigned m_scrollSnapType : 2; // ScrollSnapType +#endif + + unsigned m_regionFragment : 1; // RegionFragment unsigned m_pageSizeType : 2; // PageSizeType unsigned m_transformStyle3D : 1; // ETransformStyle3D unsigned m_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 "..." @@ -181,22 +207,24 @@ public: unsigned m_borderFit : 1; // EBorderFit unsigned m_textCombine : 1; // CSS3 text-combine properties -#if ENABLE(CSS3_TEXT) unsigned m_textDecorationStyle : 3; // TextDecorationStyle -#endif // CSS3_TEXT - unsigned m_wrapFlow: 3; // WrapFlow - unsigned m_wrapThrough: 1; // WrapThrough -#if USE(ACCELERATED_COMPOSITING) unsigned m_runningAcceleratedAnimation : 1; -#endif - unsigned m_hasAspectRatio : 1; // Whether or not an aspect ratio has been specified. + unsigned m_aspectRatioType : 2; #if ENABLE(CSS_COMPOSITING) unsigned m_effectiveBlendMode: 5; // EBlendMode + unsigned m_isolation : 1; // Isolation #endif + unsigned m_objectFit : 3; // ObjectFit + + unsigned m_breakBefore : 4; // BreakBetween + unsigned m_breakAfter : 4; + unsigned m_breakInside : 3; // BreakInside + unsigned m_resize : 2; // EResize + private: StyleRareNonInheritedData(); StyleRareNonInheritedData(const StyleRareNonInheritedData&); diff --git a/Source/WebCore/rendering/style/StyleReflection.h b/Source/WebCore/rendering/style/StyleReflection.h index 9326ce467..17f7f7195 100644 --- a/Source/WebCore/rendering/style/StyleReflection.h +++ b/Source/WebCore/rendering/style/StyleReflection.h @@ -34,9 +34,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 @@ -46,11 +46,11 @@ public: bool operator!=(const StyleReflection& o) const { return !(*this == o); } CSSReflectionDirection direction() const { return m_direction; } - Length offset() const { return m_offset; } + const Length& offset() const { return m_offset; } const NinePieceImage& mask() const { return m_mask; } void setDirection(CSSReflectionDirection dir) { m_direction = dir; } - void setOffset(const Length& l) { m_offset = l; } + void setOffset(Length offset) { m_offset = WTFMove(offset); } void setMask(const NinePieceImage& image) { m_mask = image; } private: diff --git a/Source/WebCore/rendering/style/StyleScrollSnapPoints.cpp b/Source/WebCore/rendering/style/StyleScrollSnapPoints.cpp new file mode 100644 index 000000000..8d8858f84 --- /dev/null +++ b/Source/WebCore/rendering/style/StyleScrollSnapPoints.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2014 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 { + +ScrollSnapPoints::ScrollSnapPoints() + : repeatOffset(100, Percent) + , hasRepeat(true) + , usesElements(false) +{ +} + +bool operator==(const ScrollSnapPoints& a, const ScrollSnapPoints& b) +{ + return a.repeatOffset == b.repeatOffset + && a.hasRepeat == b.hasRepeat + && a.usesElements == b.usesElements + && a.offsets == b.offsets; +} + +LengthSize defaultScrollSnapDestination() +{ + return LengthSize(Length(0, Fixed), Length(0, Fixed)); +} + +StyleScrollSnapPoints::StyleScrollSnapPoints() + : destination(defaultScrollSnapDestination()) +{ +} + +inline StyleScrollSnapPoints::StyleScrollSnapPoints(const StyleScrollSnapPoints& other) + : RefCounted() + , xPoints(other.xPoints ? std::make_unique<ScrollSnapPoints>(*other.xPoints) : nullptr) + , yPoints(other.yPoints ? std::make_unique<ScrollSnapPoints>(*other.yPoints) : nullptr) + , destination(other.destination) + , coordinates(other.coordinates) +{ +} + +Ref<StyleScrollSnapPoints> StyleScrollSnapPoints::copy() const +{ + return adoptRef(*new StyleScrollSnapPoints(*this)); +} + +bool operator==(const StyleScrollSnapPoints& a, const StyleScrollSnapPoints& b) +{ + return a.xPoints == b.xPoints + && a.yPoints == b.yPoints + && a.destination == b.destination + && a.coordinates == b.coordinates; +} + +} // 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..a4861f835 --- /dev/null +++ b/Source/WebCore/rendering/style/StyleScrollSnapPoints.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2014 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 StyleScrollSnapPoints_h +#define StyleScrollSnapPoints_h + +#if ENABLE(CSS_SCROLL_SNAP) + +#include "LengthSize.h" +#include <wtf/RefCounted.h> +#include <wtf/Vector.h> + +namespace WebCore { + +struct ScrollSnapPoints { + Length repeatOffset; + bool hasRepeat; + bool usesElements; + Vector<Length> offsets; + + ScrollSnapPoints(); +}; + +bool operator==(const ScrollSnapPoints&, const ScrollSnapPoints&); +inline bool operator!=(const ScrollSnapPoints& a, const ScrollSnapPoints& b) { return !(a == b); } + +LengthSize defaultScrollSnapDestination(); + +class StyleScrollSnapPoints : public RefCounted<StyleScrollSnapPoints> { +public: + static Ref<StyleScrollSnapPoints> create() { return adoptRef(*new StyleScrollSnapPoints); } + Ref<StyleScrollSnapPoints> copy() const; + + std::unique_ptr<ScrollSnapPoints> xPoints; + std::unique_ptr<ScrollSnapPoints> yPoints; + LengthSize destination; + Vector<LengthSize> coordinates; + +private: + StyleScrollSnapPoints(); + StyleScrollSnapPoints(const StyleScrollSnapPoints&); +}; + +bool operator==(const StyleScrollSnapPoints&, const StyleScrollSnapPoints&); +inline bool operator!=(const StyleScrollSnapPoints& a, const StyleScrollSnapPoints& b) { return !(a == b); } + +} // namespace WebCore + +#endif // ENABLE(CSS_SCROLL_SNAP) + +#endif // StyleScrollSnapPoints_h diff --git a/Source/WebCore/rendering/style/StyleSelfAlignmentData.h b/Source/WebCore/rendering/style/StyleSelfAlignmentData.h new file mode 100644 index 000000000..895558d42 --- /dev/null +++ b/Source/WebCore/rendering/style/StyleSelfAlignmentData.h @@ -0,0 +1,70 @@ +/* + * 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. + */ +#ifndef StyleSelfAlignmentData_h +#define StyleSelfAlignmentData_h + +#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 + +#endif // StyleSelfAlignmentData_h diff --git a/Source/WebCore/rendering/style/StyleShader.h b/Source/WebCore/rendering/style/StyleShader.h deleted file mode 100644 index e38f9bf8f..000000000 --- a/Source/WebCore/rendering/style/StyleShader.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2011 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER “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 HOLDER 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 StyleShader_h -#define StyleShader_h - -#if ENABLE(CSS_SHADERS) - -#include <wtf/RefCounted.h> - -namespace WebCore { - -class CachedShader; -class CSSValue; - -class StyleShader : public RefCounted<StyleShader> { -public: - virtual ~StyleShader() { } - - ALWAYS_INLINE bool isCachedShader() const { return m_isCachedShader; } - ALWAYS_INLINE bool isPendingShader() const { return m_isPendingShader; } - - virtual PassRefPtr<CSSValue> cssValue() const = 0; - - virtual CachedShader* cachedShader() const { return 0; } - -protected: - StyleShader() - : m_isCachedShader(false) - , m_isPendingShader(false) - { - } - bool m_isCachedShader : 1; - bool m_isPendingShader : 1; -}; - -} - -#endif // ENABLE(CSS_SHADERS) - -#endif // StyleShader_h diff --git a/Source/WebCore/rendering/style/StyleSurroundData.cpp b/Source/WebCore/rendering/style/StyleSurroundData.cpp index 8d5e79cb3..5c9bbdbec 100644 --- a/Source/WebCore/rendering/style/StyleSurroundData.cpp +++ b/Source/WebCore/rendering/style/StyleSurroundData.cpp @@ -30,7 +30,7 @@ StyleSurroundData::StyleSurroundData() { } -StyleSurroundData::StyleSurroundData(const StyleSurroundData& o) +inline StyleSurroundData::StyleSurroundData(const StyleSurroundData& o) : RefCounted<StyleSurroundData>() , offset(o.offset) , margin(o.margin) @@ -39,6 +39,11 @@ StyleSurroundData::StyleSurroundData(const StyleSurroundData& o) { } +Ref<StyleSurroundData> StyleSurroundData::copy() const +{ + return adoptRef(*new StyleSurroundData(*this)); +} + bool StyleSurroundData::operator==(const StyleSurroundData& o) const { return offset == o.offset && margin == o.margin && padding == o.padding && border == o.border; diff --git a/Source/WebCore/rendering/style/StyleSurroundData.h b/Source/WebCore/rendering/style/StyleSurroundData.h index b8f21e44c..00bf5f0b3 100644 --- a/Source/WebCore/rendering/style/StyleSurroundData.h +++ b/Source/WebCore/rendering/style/StyleSurroundData.h @@ -34,8 +34,8 @@ namespace WebCore { class StyleSurroundData : public RefCounted<StyleSurroundData> { public: - static PassRefPtr<StyleSurroundData> create() { return adoptRef(new StyleSurroundData); } - PassRefPtr<StyleSurroundData> copy() const { return adoptRef(new StyleSurroundData(*this)); } + static Ref<StyleSurroundData> create() { return adoptRef(*new StyleSurroundData); } + Ref<StyleSurroundData> copy() const; bool operator==(const StyleSurroundData& o) const; bool operator!=(const StyleSurroundData& o) const diff --git a/Source/WebCore/rendering/style/StyleTransformData.cpp b/Source/WebCore/rendering/style/StyleTransformData.cpp index 2baebf9b1..eaf310b63 100644 --- a/Source/WebCore/rendering/style/StyleTransformData.cpp +++ b/Source/WebCore/rendering/style/StyleTransformData.cpp @@ -34,7 +34,7 @@ StyleTransformData::StyleTransformData() { } -StyleTransformData::StyleTransformData(const StyleTransformData& o) +inline StyleTransformData::StyleTransformData(const StyleTransformData& o) : RefCounted<StyleTransformData>() , m_operations(o.m_operations) , m_x(o.m_x) @@ -43,6 +43,11 @@ StyleTransformData::StyleTransformData(const StyleTransformData& o) { } +Ref<StyleTransformData> StyleTransformData::copy() const +{ + return adoptRef(*new StyleTransformData(*this)); +} + bool StyleTransformData::operator==(const StyleTransformData& o) const { return m_x == o.m_x && m_y == o.m_y && m_z == o.m_z && m_operations == o.m_operations; diff --git a/Source/WebCore/rendering/style/StyleTransformData.h b/Source/WebCore/rendering/style/StyleTransformData.h index 6039824d5..b8fb09053 100644 --- a/Source/WebCore/rendering/style/StyleTransformData.h +++ b/Source/WebCore/rendering/style/StyleTransformData.h @@ -34,14 +34,16 @@ namespace WebCore { class StyleTransformData : public RefCounted<StyleTransformData> { public: - static PassRefPtr<StyleTransformData> create() { return adoptRef(new StyleTransformData); } - PassRefPtr<StyleTransformData> copy() const { return adoptRef(new StyleTransformData(*this)); } + static Ref<StyleTransformData> create() { return adoptRef(*new StyleTransformData); } + Ref<StyleTransformData> copy() const; bool operator==(const StyleTransformData& o) const; bool operator!=(const StyleTransformData& o) const { return !(*this == o); } + + bool hasTransform() const { return m_operations.size(); } TransformOperations m_operations; Length m_x; diff --git a/Source/WebCore/rendering/style/StyleVariableData.h b/Source/WebCore/rendering/style/StyleVariableData.h deleted file mode 100644 index bb45989f1..000000000 --- a/Source/WebCore/rendering/style/StyleVariableData.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2012 Google 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: - * - * * 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 StyleVariableData_h -#define StyleVariableData_h -#if ENABLE(CSS_VARIABLES) - -#include <wtf/Forward.h> -#include <wtf/HashMap.h> -#include <wtf/RefCounted.h> -#include <wtf/text/AtomicStringHash.h> - -namespace WebCore { - -class CursorList; -class QuotesData; -class ShadowData; - -class StyleVariableData : public RefCounted<StyleVariableData> { -public: - static PassRefPtr<StyleVariableData> create() { return adoptRef(new StyleVariableData()); } - PassRefPtr<StyleVariableData> copy() const { return adoptRef(new StyleVariableData(*this)); } - - bool operator==(const StyleVariableData& other) const { return other.m_data == m_data; } - bool operator!=(const StyleVariableData& other) const { return !(*this == other); } - - void setVariable(const AtomicString& name, const String& value) { m_data.set(name, value); } - - HashMap<AtomicString, String> m_data; -private: - explicit StyleVariableData() : RefCounted<StyleVariableData>() { } - StyleVariableData(const StyleVariableData& other) : RefCounted<StyleVariableData>(), m_data(HashMap<AtomicString, String>(other.m_data)) { } -}; - -} // namespace WebCore - -#endif /* ENABLE(CSS_VARIABLES) */ -#endif /* StyleVariableData_h */ diff --git a/Source/WebCore/rendering/style/StyleVisualData.cpp b/Source/WebCore/rendering/style/StyleVisualData.cpp index 628a20ace..d8fb8869b 100644 --- a/Source/WebCore/rendering/style/StyleVisualData.cpp +++ b/Source/WebCore/rendering/style/StyleVisualData.cpp @@ -40,7 +40,7 @@ StyleVisualData::~StyleVisualData() { } -StyleVisualData::StyleVisualData(const StyleVisualData& o) +inline StyleVisualData::StyleVisualData(const StyleVisualData& o) : RefCounted<StyleVisualData>() , clip(o.clip) , hasClip(o.hasClip) @@ -52,4 +52,9 @@ StyleVisualData::StyleVisualData(const StyleVisualData& o) { } +Ref<StyleVisualData> StyleVisualData::copy() const +{ + return adoptRef(*new StyleVisualData(*this)); +} + } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleVisualData.h b/Source/WebCore/rendering/style/StyleVisualData.h index 117cff1aa..5b2496ca3 100644 --- a/Source/WebCore/rendering/style/StyleVisualData.h +++ b/Source/WebCore/rendering/style/StyleVisualData.h @@ -34,8 +34,8 @@ namespace WebCore { class StyleVisualData : public RefCounted<StyleVisualData> { public: - static PassRefPtr<StyleVisualData> create() { return adoptRef(new StyleVisualData); } - PassRefPtr<StyleVisualData> copy() const { return adoptRef(new StyleVisualData(*this)); } + static Ref<StyleVisualData> create() { return adoptRef(*new StyleVisualData); } + Ref<StyleVisualData> copy() const; ~StyleVisualData(); bool operator==(const StyleVisualData& o) const diff --git a/Source/WebCore/rendering/style/TextSizeAdjustment.h b/Source/WebCore/rendering/style/TextSizeAdjustment.h new file mode 100644 index 000000000..d56d6760c --- /dev/null +++ b/Source/WebCore/rendering/style/TextSizeAdjustment.h @@ -0,0 +1,49 @@ +/* + * 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. + * + */ + +#ifndef TextSizeAdjustment_h +#define TextSizeAdjustment_h + +#if ENABLE(IOS_TEXT_AUTOSIZING) + +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; +}; + +#endif // ENABLE(IOS_TEXT_AUTOSIZING) + +#endif // TextSizeAdjustment_h diff --git a/Source/WebCore/rendering/style/WillChangeData.cpp b/Source/WebCore/rendering/style/WillChangeData.cpp new file mode 100644 index 000000000..77d4aa871 --- /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." +static bool 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..49e76089d --- /dev/null +++ b/Source/WebCore/rendering/style/WillChangeData.h @@ -0,0 +1,132 @@ +/* + * 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. + */ + +#ifndef WillChangeData_h +#define WillChangeData_h + +#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; + +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 + +#endif // WillChangeData_h |
