summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/style/NinePieceImage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/style/NinePieceImage.cpp')
-rw-r--r--Source/WebCore/rendering/style/NinePieceImage.cpp188
1 files changed, 7 insertions, 181 deletions
diff --git a/Source/WebCore/rendering/style/NinePieceImage.cpp b/Source/WebCore/rendering/style/NinePieceImage.cpp
index b4c33f4f0..43bd1b043 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, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2005, 2006, 2007, 2008, 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
@@ -23,12 +23,7 @@
#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 {
@@ -47,188 +42,19 @@ NinePieceImage::NinePieceImage(PassRefPtr<StyleImage> image, LengthBox imageSlic
: m_data(NinePieceImageData::create())
{
m_data.access()->image = image;
- m_data.access()->imageSlices = WTFMove(imageSlices);
- m_data.access()->borderSlices = WTFMove(borderSlices);
- m_data.access()->outset = WTFMove(outset);
+ m_data.access()->imageSlices = std::move(imageSlices);
+ m_data.access()->borderSlices = std::move(borderSlices);
+ m_data.access()->outset = std::move(outset);
m_data.access()->fill = fill;
m_data.access()->horizontalRule = horizontalRule;
m_data.access()->verticalRule = verticalRule;
}
-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(nullptr)
+ , image(0)
, imageSlices(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent))
, borderSlices(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative))
, outset(0)
@@ -247,14 +73,14 @@ inline NinePieceImageData::NinePieceImageData(const NinePieceImageData& other)
{
}
-Ref<NinePieceImageData> NinePieceImageData::copy() const
+PassRef<NinePieceImageData> NinePieceImageData::copy() const
{
return adoptRef(*new NinePieceImageData(*this));
}
bool NinePieceImageData::operator==(const NinePieceImageData& other) const
{
- return arePointingToEqualData(image, other.image)
+ return StyleImage::imagesEquivalent(image.get(), other.image.get())
&& imageSlices == other.imageSlices
&& fill == other.fill
&& borderSlices == other.borderSlices