15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * disclaimer. 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * disclaimer in the documentation and/or other materials 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * provided with the distribution. 1553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THE POSSIBILITY OF SUCH DAMAGE. 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 31591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/rendering/shapes/Shape.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/css/BasicShapeFunctions.h" 34e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ImageResource.h" 35a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "core/rendering/shapes/BoxShape.h" 36591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/rendering/shapes/PolygonShape.h" 37e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/rendering/shapes/RasterShape.h" 38591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/rendering/shapes/RectangleShape.h" 39d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/rendering/style/RenderStyle.h" 40bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/LengthFunctions.h" 411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatSize.h" 425d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "platform/graphics/GraphicsContext.h" 43e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "platform/graphics/GraphicsTypes.h" 44a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/ImageBuffer.h" 45591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/MathExtras.h" 46591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/OwnPtr.h" 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static PassOwnPtr<Shape> createInsetShape(const FloatRoundedRect& bounds) 51a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){ 52a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ASSERT(bounds.rect().width() >= 0 && bounds.rect().height() >= 0); 5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return adoptPtr(new BoxShape(bounds)); 54a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)} 55a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 56591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic PassOwnPtr<Shape> createCircleShape(const FloatPoint& center, float radius) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(radius >= 0); 59591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return adoptPtr(new RectangleShape(FloatRect(center.x() - radius, center.y() - radius, radius*2, radius*2), FloatSize(radius, radius))); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 62591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic PassOwnPtr<Shape> createEllipseShape(const FloatPoint& center, const FloatSize& radii) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(radii.width() >= 0 && radii.height() >= 0); 65591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return adoptPtr(new RectangleShape(FloatRect(center.x() - radii.width(), center.y() - radii.height(), radii.width()*2, radii.height()*2), radii)); 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 68591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic PassOwnPtr<Shape> createPolygonShape(PassOwnPtr<Vector<FloatPoint> > vertices, WindRule fillRule) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 70591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return adoptPtr(new PolygonShape(vertices, fillRule)); 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static inline FloatRect physicalRectToLogical(const FloatRect& rect, float logicalBoxHeight, WritingMode writingMode) 74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (isHorizontalWritingMode(writingMode)) 76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return rect; 77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (isFlippedBlocksWritingMode(writingMode)) 78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return FloatRect(rect.y(), logicalBoxHeight - rect.maxX(), rect.height(), rect.width()); 79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return rect.transposedRect(); 80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static inline FloatPoint physicalPointToLogical(const FloatPoint& point, float logicalBoxHeight, WritingMode writingMode) 83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (isHorizontalWritingMode(writingMode)) 85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return point; 86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (isFlippedBlocksWritingMode(writingMode)) 87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return FloatPoint(point.y(), logicalBoxHeight - point.x()); 88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return point.transposedPoint(); 89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static inline FloatSize physicalSizeToLogical(const FloatSize& size, WritingMode writingMode) 92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (isHorizontalWritingMode(writingMode)) 94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return size; 95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return size.transposedSize(); 96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 986f543c786fc42989f552b4daa774ca5ff32fa697Ben MurdochPassOwnPtr<Shape> Shape::createShape(const BasicShape* basicShape, const LayoutSize& logicalBoxSize, WritingMode writingMode, float margin) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(basicShape); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool horizontalWritingMode = isHorizontalWritingMode(writingMode); 10343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) float boxWidth = horizontalWritingMode ? logicalBoxSize.width().toFloat() : logicalBoxSize.height().toFloat(); 10443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) float boxHeight = horizontalWritingMode ? logicalBoxSize.height().toFloat() : logicalBoxSize.width().toFloat(); 105591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<Shape> shape; 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (basicShape->type()) { 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case BasicShape::BasicShapeCircleType: { 110197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch const BasicShapeCircle* circle = toBasicShapeCircle(basicShape); 11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatPoint center = floatPointForCenterCoordinate(circle->centerX(), circle->centerY(), FloatSize(boxWidth, boxHeight)); 11209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) float radius = circle->floatValueForRadiusInBox(FloatSize(boxWidth, boxHeight)); 11343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) FloatPoint logicalCenter = physicalPointToLogical(center, logicalBoxSize.height().toFloat(), writingMode); 11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) shape = createCircleShape(logicalCenter, radius); 11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) break; 11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case BasicShape::BasicShapeEllipseType: { 120197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch const BasicShapeEllipse* ellipse = toBasicShapeEllipse(basicShape); 12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatPoint center = floatPointForCenterCoordinate(ellipse->centerX(), ellipse->centerY(), FloatSize(boxWidth, boxHeight)); 12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) float radiusX = ellipse->floatValueForRadiusInBox(ellipse->radiusX(), center.x(), boxWidth); 12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) float radiusY = ellipse->floatValueForRadiusInBox(ellipse->radiusY(), center.y(), boxHeight); 12443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) FloatPoint logicalCenter = physicalPointToLogical(center, logicalBoxSize.height().toFloat(), writingMode); 12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) shape = createEllipseShape(logicalCenter, FloatSize(radiusX, radiusY)); 12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) break; 12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) case BasicShape::BasicShapePolygonType: { 131197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch const BasicShapePolygon* polygon = toBasicShapePolygon(basicShape); 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Vector<Length>& values = polygon->values(); 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t valuesSize = values.size(); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!(valuesSize % 2)); 13553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) OwnPtr<Vector<FloatPoint> > vertices = adoptPtr(new Vector<FloatPoint>(valuesSize / 2)); 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < valuesSize; i += 2) { 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint vertex( 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) floatValueForLength(values.at(i), boxWidth), 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) floatValueForLength(values.at(i + 1), boxHeight)); 14043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) (*vertices)[i / 2] = physicalPointToLogical(vertex, logicalBoxSize.height().toFloat(), writingMode); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 142591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch shape = createPolygonShape(vertices.release(), polygon->windRule()); 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) case BasicShape::BasicShapeInsetType: { 147197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch const BasicShapeInset& inset = *toBasicShapeInset(basicShape); 14809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) float left = floatValueForLength(inset.left(), boxWidth); 14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) float top = floatValueForLength(inset.top(), boxHeight); 15009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) float right = floatValueForLength(inset.right(), boxWidth); 15109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) float bottom = floatValueForLength(inset.bottom(), boxHeight); 152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) FloatRect rect(left, top, std::max<float>(boxWidth - left - right, 0), std::max<float>(boxHeight - top - bottom, 0)); 15343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) FloatRect logicalRect = physicalRectToLogical(rect, logicalBoxSize.height().toFloat(), writingMode); 15409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 15509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatSize boxSize(boxWidth, boxHeight); 156d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) FloatSize topLeftRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.topLeftRadius(), boxSize), writingMode); 157d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) FloatSize topRightRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.topRightRadius(), boxSize), writingMode); 158d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) FloatSize bottomLeftRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.bottomLeftRadius(), boxSize), writingMode); 159d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) FloatSize bottomRightRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.bottomRightRadius(), boxSize), writingMode); 160d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) FloatRoundedRect::Radii cornerRadii(topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); 161d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 162d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) cornerRadii.scale(calcBorderRadiiConstraintScaleFor(logicalRect, cornerRadii)); 16309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 16409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) shape = createInsetShape(FloatRoundedRect(logicalRect, cornerRadii)); 16509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) break; 16609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 16709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 172591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch shape->m_writingMode = writingMode; 1736f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch shape->m_margin = margin; 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 175591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return shape.release(); 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 178197021e6b966cfb06891637935ef33fff06433d1Ben MurdochPassOwnPtr<Shape> Shape::createEmptyRasterShape(WritingMode writingMode, float margin) 179197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 180197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtr<RasterShapeIntervals> intervals = adoptPtr(new RasterShapeIntervals(0, 0)); 181197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtr<RasterShape> rasterShape = adoptPtr(new RasterShape(intervals.release(), IntSize())); 182197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch rasterShape->m_writingMode = writingMode; 183197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch rasterShape->m_margin = margin; 184197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return rasterShape.release(); 185197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 186197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 1876f543c786fc42989f552b4daa774ca5ff32fa697Ben MurdochPassOwnPtr<Shape> Shape::createRasterShape(Image* image, float threshold, const LayoutRect& imageR, const LayoutRect& marginR, WritingMode writingMode, float margin) 188e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){ 189d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) IntRect imageRect = pixelSnappedIntRect(imageR); 190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) IntRect marginRect = pixelSnappedIntRect(marginR); 191197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 192d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) OwnPtr<RasterShapeIntervals> intervals = adoptPtr(new RasterShapeIntervals(marginRect.height(), -marginRect.y())); 193d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(imageRect.size()); 194e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 195e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (imageBuffer) { 196e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) GraphicsContext* graphicsContext = imageBuffer->context(); 197d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) graphicsContext->drawImage(image, IntRect(IntPoint(), imageRect.size())); 198e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 199197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RefPtr<Uint8ClampedArray> pixelArray = imageBuffer->getImageData(Unmultiplied, IntRect(IntPoint(), imageRect.size())); 200e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) unsigned pixelArrayOffset = 3; // Each pixel is four bytes: RGBA. 201e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) uint8_t alphaPixelThreshold = threshold * 255; 202e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 203d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(static_cast<unsigned>(imageRect.width() * imageRect.height() * 4) == pixelArray->length()); 204d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 205d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) int minBufferY = std::max(0, marginRect.y() - imageRect.y()); 206d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) int maxBufferY = std::min(imageRect.height(), marginRect.maxY() - imageRect.y()); 207e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 208d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (int y = minBufferY; y < maxBufferY; ++y) { 209e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) int startX = -1; 210d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (int x = 0; x < imageRect.width(); ++x, pixelArrayOffset += 4) { 211e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) uint8_t alpha = pixelArray->item(pixelArrayOffset); 212d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) bool alphaAboveThreshold = alpha > alphaPixelThreshold; 213d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (startX == -1 && alphaAboveThreshold) { 214e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) startX = x; 215d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } else if (startX != -1 && (!alphaAboveThreshold || x == imageRect.width() - 1)) { 21610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch int endX = alphaAboveThreshold ? x + 1 : x; 21710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch intervals->intervalAt(y + imageRect.y()).unite(IntShapeInterval(startX + imageRect.x(), endX + imageRect.x())); 218e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) startX = -1; 219e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) } 220e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) } 221e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) } 222e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) } 223e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 224d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) OwnPtr<RasterShape> rasterShape = adoptPtr(new RasterShape(intervals.release(), marginRect.size())); 225e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) rasterShape->m_writingMode = writingMode; 2266f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch rasterShape->m_margin = margin; 227e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return rasterShape.release(); 228e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)} 229e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 2306f543c786fc42989f552b4daa774ca5ff32fa697Ben MurdochPassOwnPtr<Shape> Shape::createLayoutBoxShape(const RoundedRect& roundedRect, WritingMode writingMode, float margin) 231a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){ 23209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect rect(0, 0, roundedRect.rect().width(), roundedRect.rect().height()); 23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRoundedRect bounds(rect, roundedRect.radii()); 23409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<Shape> shape = createInsetShape(bounds); 235a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) shape->m_writingMode = writingMode; 2366f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch shape->m_margin = margin; 237a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 238a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return shape.release(); 239a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)} 240a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 241c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 242