diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/rendering/style/FillLayer.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/rendering/style/FillLayer.cpp')
-rw-r--r-- | Source/WebCore/rendering/style/FillLayer.cpp | 190 |
1 files changed, 124 insertions, 66 deletions
diff --git a/Source/WebCore/rendering/style/FillLayer.cpp b/Source/WebCore/rendering/style/FillLayer.cpp index 3c563b278..a4ed82641 100644 --- a/Source/WebCore/rendering/style/FillLayer.cpp +++ b/Source/WebCore/rendering/style/FillLayer.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,39 +22,40 @@ #include "config.h" #include "FillLayer.h" +#include "TextStream.h" +#include <wtf/PointerComparison.h> + namespace WebCore { struct SameSizeAsFillLayer { - FillLayer* m_next; + FillLayer* next; - RefPtr<StyleImage> m_image; + RefPtr<StyleImage> image; - Length m_xPosition; - Length m_yPosition; + Length x; + Length y; - LengthSize m_sizeLength; + LengthSize sizeLength; - unsigned m_bitfields: 32; - unsigned m_bitfields2: 1; + unsigned bitfields : 32; + unsigned bitfields2 : 11; }; COMPILE_ASSERT(sizeof(FillLayer) == sizeof(SameSizeAsFillLayer), FillLayer_should_stay_small); FillLayer::FillLayer(EFillLayerType type) - : m_next(0) - , m_image(FillLayer::initialFillImage(type)) + : m_image(FillLayer::initialFillImage(type)) , m_xPosition(FillLayer::initialFillXPosition(type)) , m_yPosition(FillLayer::initialFillYPosition(type)) - , m_sizeLength(FillLayer::initialFillSizeLength(type)) , m_attachment(FillLayer::initialFillAttachment(type)) , m_clip(FillLayer::initialFillClip(type)) , m_origin(FillLayer::initialFillOrigin(type)) , m_repeatX(FillLayer::initialFillRepeatX(type)) , m_repeatY(FillLayer::initialFillRepeatY(type)) , m_composite(FillLayer::initialFillComposite(type)) - , m_sizeType(FillLayer::initialFillSizeType(type)) + , m_sizeType(SizeNone) , m_blendMode(FillLayer::initialFillBlendMode(type)) - , m_maskSourceType(FillLayer::initialMaskSourceType(type)) + , m_maskSourceType(FillLayer::initialFillMaskSourceType(type)) , m_imageSet(false) , m_attachmentSet(false) , m_clipSet(false) @@ -63,9 +64,10 @@ FillLayer::FillLayer(EFillLayerType type) , m_repeatYSet(false) , m_xPosSet(false) , m_yPosSet(false) - , m_backgroundOriginSet(false) - , m_backgroundXOrigin(LeftEdge) - , m_backgroundYOrigin(TopEdge) + , m_backgroundXOriginSet(false) + , m_backgroundYOriginSet(false) + , m_backgroundXOrigin(static_cast<unsigned>(Edge::Left)) + , m_backgroundYOrigin(static_cast<unsigned>(Edge::Top)) , m_compositeSet(type == MaskFillLayer) , m_blendModeSet(false) , m_maskSourceTypeSet(false) @@ -74,7 +76,7 @@ FillLayer::FillLayer(EFillLayerType type) } FillLayer::FillLayer(const FillLayer& o) - : m_next(o.m_next ? new FillLayer(*o.m_next) : 0) + : m_next(o.m_next ? std::make_unique<FillLayer>(*o.m_next) : nullptr) , m_image(o.m_image) , m_xPosition(o.m_xPosition) , m_yPosition(o.m_yPosition) @@ -96,7 +98,8 @@ FillLayer::FillLayer(const FillLayer& o) , m_repeatYSet(o.m_repeatYSet) , m_xPosSet(o.m_xPosSet) , m_yPosSet(o.m_yPosSet) - , m_backgroundOriginSet(o.m_backgroundOriginSet) + , m_backgroundXOriginSet(o.m_backgroundXOriginSet) + , m_backgroundYOriginSet(o.m_backgroundYOriginSet) , m_backgroundXOrigin(o.m_backgroundXOrigin) , m_backgroundYOrigin(o.m_backgroundYOrigin) , m_compositeSet(o.m_compositeSet) @@ -108,22 +111,21 @@ FillLayer::FillLayer(const FillLayer& o) FillLayer::~FillLayer() { - delete m_next; + // Delete the layers in a loop rather than allowing recursive calls to the destructors. + for (std::unique_ptr<FillLayer> next = WTFMove(m_next); next; next = WTFMove(next->m_next)) { } } FillLayer& FillLayer::operator=(const FillLayer& o) { - if (m_next != o.m_next) { - delete m_next; - m_next = o.m_next ? new FillLayer(*o.m_next) : 0; - } + m_next = o.m_next ? std::make_unique<FillLayer>(*o.m_next) : nullptr; m_image = o.m_image; m_xPosition = o.m_xPosition; m_yPosition = o.m_yPosition; m_backgroundXOrigin = o.m_backgroundXOrigin; m_backgroundYOrigin = o.m_backgroundYOrigin; - m_backgroundOriginSet = o.m_backgroundOriginSet; + m_backgroundXOriginSet = o.m_backgroundXOriginSet; + m_backgroundYOriginSet = o.m_backgroundYOriginSet; m_sizeLength = o.m_sizeLength; m_attachment = o.m_attachment; m_clip = o.m_clip; @@ -155,14 +157,14 @@ FillLayer& FillLayer::operator=(const FillLayer& o) bool FillLayer::operator==(const FillLayer& o) const { // We do not check the "isSet" booleans for each property, since those are only used during initial construction - // to propagate patterns into layers. All layer comparisons happen after values have all been filled in anyway. - return StyleImage::imagesEquivalent(m_image.get(), o.m_image.get()) && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition - && m_backgroundXOrigin == o.m_backgroundXOrigin && m_backgroundYOrigin == o.m_backgroundYOrigin - && m_attachment == o.m_attachment && m_clip == o.m_clip && m_composite == o.m_composite - && m_blendMode == o.m_blendMode && m_origin == o.m_origin && m_repeatX == o.m_repeatX - && m_repeatY == o.m_repeatY && m_sizeType == o.m_sizeType && m_maskSourceType == o.m_maskSourceType - && m_sizeLength == o.m_sizeLength && m_type == o.m_type - && ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next); + // to propagate patterns into layers. All layer comparisons happen after values have all been filled in anyway. + return arePointingToEqualData(m_image.get(), o.m_image.get()) && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition + && m_backgroundXOrigin == o.m_backgroundXOrigin && m_backgroundYOrigin == o.m_backgroundYOrigin + && m_attachment == o.m_attachment && m_clip == o.m_clip && m_composite == o.m_composite + && m_blendMode == o.m_blendMode && m_origin == o.m_origin && m_repeatX == o.m_repeatX + && m_repeatY == o.m_repeatY && m_sizeType == o.m_sizeType && m_maskSourceType == o.m_maskSourceType + && m_sizeLength == o.m_sizeLength && m_type == o.m_type + && ((m_next && o.m_next) ? *m_next == *o.m_next : m_next == o.m_next); } void FillLayer::fillUnsetProperties() @@ -173,10 +175,10 @@ void FillLayer::fillUnsetProperties() // We need to fill in the remaining values with the pattern specified. for (FillLayer* pattern = this; curr; curr = curr->next()) { curr->m_xPosition = pattern->m_xPosition; - if (pattern->isBackgroundOriginSet()) { + if (pattern->isBackgroundXOriginSet()) curr->m_backgroundXOrigin = pattern->m_backgroundXOrigin; + if (pattern->isBackgroundYOriginSet()) curr->m_backgroundYOrigin = pattern->m_backgroundYOrigin; - } pattern = pattern->next(); if (pattern == curr || !pattern) pattern = this; @@ -188,10 +190,10 @@ void FillLayer::fillUnsetProperties() // We need to fill in the remaining values with the pattern specified. for (FillLayer* pattern = this; curr; curr = curr->next()) { curr->m_yPosition = pattern->m_yPosition; - if (pattern->isBackgroundOriginSet()) { + if (pattern->isBackgroundXOriginSet()) curr->m_backgroundXOrigin = pattern->m_backgroundXOrigin; + if (pattern->isBackgroundYOriginSet()) curr->m_backgroundYOrigin = pattern->m_backgroundYOrigin; - } pattern = pattern->next(); if (pattern == curr || !pattern) pattern = this; @@ -290,18 +292,15 @@ void FillLayer::fillUnsetProperties() void FillLayer::cullEmptyLayers() { - FillLayer* next; - for (FillLayer* p = this; p; p = next) { - next = p->m_next; - if (next && !next->isImageSet()) { - delete next; - p->m_next = 0; + for (FillLayer* layer = this; layer; layer = layer->m_next.get()) { + if (layer->m_next && !layer->m_next->isImageSet()) { + layer->m_next = nullptr; break; } } } -static EFillBox clipMax(EFillBox clipA, EFillBox clipB) +static inline EFillBox clipMax(EFillBox clipA, EFillBox clipB) { if (clipA == BorderFillBox || clipB == BorderFillBox) return BorderFillBox; @@ -314,11 +313,15 @@ static EFillBox clipMax(EFillBox clipA, EFillBox clipB) void FillLayer::computeClipMax() const { - if (m_next) { - m_next->computeClipMax(); - m_clipMax = clipMax(clip(), m_next->clip()); - } else - m_clipMax = m_clip; + Vector<const FillLayer*, 4> layers; + for (auto* layer = this; layer; layer = layer->m_next.get()) + layers.append(layer); + EFillBox computedClipMax = TextFillBox; + for (unsigned i = layers.size(); i; --i) { + auto& layer = *layers[i - 1]; + computedClipMax = clipMax(computedClipMax, layer.clip()); + layer.m_clipMax = computedClipMax; + } } bool FillLayer::clipOccludesNextLayers(bool firstLayer) const @@ -328,29 +331,25 @@ bool FillLayer::clipOccludesNextLayers(bool firstLayer) const return m_clip == m_clipMax; } -bool FillLayer::containsImage(StyleImage* s) const +bool FillLayer::containsImage(StyleImage& image) const { - if (!s) - return false; - if (m_image && *s == *m_image) - return true; - if (m_next) - return m_next->containsImage(s); + for (auto* layer = this; layer; layer = layer->m_next.get()) { + if (layer->m_image && image == *layer->m_image) + return true; + } return false; } bool FillLayer::imagesAreLoaded() const { - const FillLayer* curr; - for (curr = this; curr; curr = curr->next()) { - if (curr->m_image && !curr->m_image->isLoaded()) + for (auto* layer = this; layer; layer = layer->m_next.get()) { + if (layer->m_image && !layer->m_image->isLoaded()) return false; } - return true; } -bool FillLayer::hasOpaqueImage(const RenderElement* renderer) const +bool FillLayer::hasOpaqueImage(const RenderElement& renderer) const { if (!m_image) return false; @@ -358,18 +357,77 @@ bool FillLayer::hasOpaqueImage(const RenderElement* renderer) const if (m_composite == CompositeClear || m_composite == CompositeCopy) return true; - if (m_blendMode != BlendModeNormal) - return false; + return m_blendMode == BlendModeNormal && m_composite == CompositeSourceOver && m_image->knownToBeOpaque(&renderer); +} - if (m_composite == CompositeSourceOver) - return m_image->knownToBeOpaque(renderer); +bool FillLayer::hasRepeatXY() const +{ + return m_repeatX == RepeatFill && m_repeatY == RepeatFill; +} +bool FillLayer::hasImage() const +{ + for (auto* layer = this; layer; layer = layer->m_next.get()) { + if (layer->image()) + return true; + } return false; } -bool FillLayer::hasRepeatXY() const +bool FillLayer::hasFixedImage() const { - return m_repeatX == RepeatFill && m_repeatY == RepeatFill; + for (auto* layer = this; layer; layer = layer->m_next.get()) { + if (layer->m_image && layer->m_attachment == FixedBackgroundAttachment) + return true; + } + return false; +} + +bool FillLayer::imagesIdentical(const FillLayer* layer1, const FillLayer* layer2) +{ + for (; layer1 && layer2; layer1 = layer1->next(), layer2 = layer2->next()) { + if (!arePointingToEqualData(layer1->image(), layer2->image())) + return false; + } + + return !layer1 && !layer2; +} + +TextStream& operator<<(TextStream& ts, FillSize fillSize) +{ + return ts << fillSize.type << " " << fillSize.size; +} + +TextStream& operator<<(TextStream& ts, const FillLayer& layer) +{ + TextStream::GroupScope scope(ts); + ts << "fill-layer"; + + ts.startGroup(); + ts << "position " << layer.xPosition() << " " << layer.yPosition(); + ts.endGroup(); + + ts.dumpProperty("size", layer.size()); + + ts.startGroup(); + ts << "background-origin " << layer.backgroundXOrigin() << " " << layer.backgroundYOrigin(); + ts.endGroup(); + + ts.startGroup(); + ts << "repeat " << layer.repeatX() << " " << layer.repeatY(); + ts.endGroup(); + + ts.dumpProperty("clip", layer.clip()); + ts.dumpProperty("origin", layer.origin()); + + ts.dumpProperty("composite", layer.composite()); + ts.dumpProperty("blend-mode", layer.blendMode()); + ts.dumpProperty("mask-type", layer.maskSourceType()); + + if (layer.next()) + ts << *layer.next(); + + return ts; } } // namespace WebCore |