153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)/* 253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. 353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 2006 Rob Buis <buis@kde.org> 453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved. 68abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) * Copyright (C) 2013 Intel Corporation. All rights reserved. 753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without 953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * modification, are permitted provided that the following conditions 1053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * are met: 1153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 1253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * notice, this list of conditions and the following disclaimer. 1353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 1453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 1553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * documentation and/or other materials provided with the distribution. 1653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 1753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 1853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 2153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) */ 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "config.h" 31a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/Path.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include <math.h> 341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatPoint.h" 351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatRect.h" 36a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContext.h" 37a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/skia/SkiaUtils.h" 381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/transforms/AffineTransform.h" 39e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "third_party/skia/include/core/SkPathMeasure.h" 40e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "third_party/skia/include/pathops/SkPathOps.h" 417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/MathExtras.h" 4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)namespace WebCore { 4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)Path::Path() 4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) : m_path() 4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)Path::Path(const Path& other) 5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path = SkPath(other.m_path); 5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)Path::~Path() 5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 5753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 5853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 5953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)Path& Path::operator=(const Path& other) 6053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 6153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path = SkPath(other.m_path); 6253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return *this; 6353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 6453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 6553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool Path::operator==(const Path& other) const 6653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 6753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return m_path == other.m_path; 6853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 6953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 7053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool Path::contains(const FloatPoint& point, WindRule rule) const 7153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 7283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch return SkPathContainsPoint(m_path, point, rule == RULE_NONZERO ? SkPath::kWinding_FillType : SkPath::kEvenOdd_FillType); 7353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 7453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 75521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)bool Path::strokeContains(const FloatPoint& point, const StrokeData& strokeData) const 7653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 7753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkPaint paint; 78521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) strokeData.setupPaint(&paint); 7953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkPath strokePath; 8053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) paint.getFillPath(m_path, &strokePath); 8153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 8283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch return SkPathContainsPoint(strokePath, point, SkPath::kWinding_FillType); 8353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 8453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 8553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)FloatRect Path::boundingRect() const 8653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 8753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return m_path.getBounds(); 8853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 8953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 90521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)FloatRect Path::strokeBoundingRect(const StrokeData& strokeData) const 9153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 9253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkPaint paint; 93521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) strokeData.setupPaint(&paint); 9453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkPath boundingPath; 9553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) paint.getFillPath(m_path, &boundingPath); 9653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 97521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return boundingPath.getBounds(); 9853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 9953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 10053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static FloatPoint* convertPathPoints(FloatPoint dst[], const SkPoint src[], int count) 10153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 10253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) for (int i = 0; i < count; i++) { 10353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) dst[i].setX(SkScalarToFloat(src[i].fX)); 10453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) dst[i].setY(SkScalarToFloat(src[i].fY)); 10553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 10653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return dst; 10753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 10853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 10953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::apply(void* info, PathApplierFunction function) const 11053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 11153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkPath::RawIter iter(m_path); 11253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkPoint pts[4]; 11353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) PathElement pathElement; 11453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatPoint pathPoints[3]; 11553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 11653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) for (;;) { 11753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) switch (iter.next(pts)) { 11853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case SkPath::kMove_Verb: 11953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) pathElement.type = PathElementMoveToPoint; 12053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) pathElement.points = convertPathPoints(pathPoints, &pts[0], 1); 12153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) break; 12253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case SkPath::kLine_Verb: 12353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) pathElement.type = PathElementAddLineToPoint; 12453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) pathElement.points = convertPathPoints(pathPoints, &pts[1], 1); 12553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) break; 12653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case SkPath::kQuad_Verb: 12753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) pathElement.type = PathElementAddQuadCurveToPoint; 12853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) pathElement.points = convertPathPoints(pathPoints, &pts[1], 2); 12953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) break; 13053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case SkPath::kCubic_Verb: 13153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) pathElement.type = PathElementAddCurveToPoint; 13253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) pathElement.points = convertPathPoints(pathPoints, &pts[1], 3); 13353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) break; 13453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case SkPath::kClose_Verb: 13553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) pathElement.type = PathElementCloseSubpath; 13653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) pathElement.points = convertPathPoints(pathPoints, 0, 0); 13753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) break; 13853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case SkPath::kDone_Verb: 13953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return; 1405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) default: // place-holder for kConic_Verb, when that lands from skia 1415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) break; 14253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 14353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) function(info, &pathElement); 14453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 14553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 14653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 14753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::transform(const AffineTransform& xform) 14853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 1491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) m_path.transform(affineTransformToSkMatrix(xform)); 15053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 15153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 15253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)float Path::length() const 15353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 154e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) SkScalar length = 0; 155e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) SkPathMeasure measure(m_path, false); 156e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 157e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) do { 158e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) length += measure.getLength(); 159e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } while (measure.nextContour()); 160e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 161e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return SkScalarToFloat(length); 16253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 16353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 16453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)FloatPoint Path::pointAtLength(float length, bool& ok) const 16553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 166e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) FloatPoint point; 167e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) float normal; 168e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) ok = pointAndNormalAtLength(length, point, normal); 169e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return point; 17053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 17153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 17253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)float Path::normalAngleAtLength(float length, bool& ok) const 17353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 174e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) FloatPoint point; 175e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) float normal; 176e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) ok = pointAndNormalAtLength(length, point, normal); 177e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return normal; 178e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 179e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 180e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool Path::pointAndNormalAtLength(float length, FloatPoint& point, float& normal) const 181e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 182e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) SkPathMeasure measure(m_path, false); 183e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 184e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) do { 185e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) SkScalar contourLength = measure.getLength(); 186e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (length <= contourLength) { 187e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) SkVector tangent; 188e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) SkPoint position; 189e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 190e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (measure.getPosTan(length, &position, &tangent)) { 191e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) normal = rad2deg(SkScalarToFloat(SkScalarATan2(tangent.fY, tangent.fX))); 192e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) point = FloatPoint(SkScalarToFloat(position.fX), SkScalarToFloat(position.fY)); 193e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return true; 194e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } 195e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } 196e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) length -= contourLength; 197e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } while (measure.nextContour()); 198e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 199e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) normal = 0; 200e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) point = FloatPoint(0, 0); 201e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return false; 20253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 20353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 20453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::clear() 20553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 20653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.reset(); 20753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 20853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 20953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool Path::isEmpty() const 21053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 21153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return m_path.isEmpty(); 21253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 21353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 21453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool Path::hasCurrentPoint() const 21553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 21653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return m_path.getPoints(0, 0); 21753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 21853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 21953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)FloatPoint Path::currentPoint() const 22053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 22153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (m_path.countPoints() > 0) { 22253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkPoint skResult; 22353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.getLastPt(&skResult); 22453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatPoint result; 22553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) result.setX(SkScalarToFloat(skResult.fX)); 22653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) result.setY(SkScalarToFloat(skResult.fY)); 22753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return result; 22853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 22953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 23053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // FIXME: Why does this return quietNaN? Other ports return 0,0. 23153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) float quietNaN = std::numeric_limits<float>::quiet_NaN(); 23253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return FloatPoint(quietNaN, quietNaN); 23353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 23453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 235e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben MurdochWindRule Path::windRule() const 236e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{ 237e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return m_path.getFillType() == SkPath::kEvenOdd_FillType 238e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ? RULE_EVENODD 239e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch : RULE_NONZERO; 240e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch} 241e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 242e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochvoid Path::setWindRule(const WindRule rule) 243e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{ 244e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch m_path.setFillType(rule == RULE_EVENODD 245e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ? SkPath::kEvenOdd_FillType 246e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch : SkPath::kWinding_FillType); 247e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch} 248e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 24953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::moveTo(const FloatPoint& point) 25053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 25153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.moveTo(point); 25253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 25353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 25453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::addLineTo(const FloatPoint& point) 25553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 25653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.lineTo(point); 25753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 25853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 25953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& ep) 26053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 26153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.quadTo(cp, ep); 26253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 26353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 26453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::addBezierCurveTo(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& ep) 26553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 26653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.cubicTo(p1, p2, ep); 26753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 26853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 26953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) 27053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 27153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.arcTo(p1, p2, WebCoreFloatToSkScalar(radius)); 27253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 27353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 27453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::closeSubpath() 27553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 27653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.close(); 27753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 27853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 2791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void Path::addEllipse(const FloatPoint& p, float radiusX, float radiusY, float startAngle, float endAngle, bool anticlockwise) 28053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 281e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) ASSERT(ellipseIsRenderable(startAngle, endAngle)); 2828abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT(startAngle >= 0 && startAngle < 2 * piFloat); 2838abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT((anticlockwise && (startAngle - endAngle) >= 0) || (!anticlockwise && (endAngle - startAngle) >= 0)); 2848abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 28553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkScalar cx = WebCoreFloatToSkScalar(p.x()); 28653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkScalar cy = WebCoreFloatToSkScalar(p.y()); 2871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) SkScalar radiusXScalar = WebCoreFloatToSkScalar(radiusX); 2881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) SkScalar radiusYScalar = WebCoreFloatToSkScalar(radiusY); 28953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 29053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkRect oval; 2911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) oval.set(cx - radiusXScalar, cy - radiusYScalar, cx + radiusXScalar, cy + radiusYScalar); 29253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 293c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) float sweep = endAngle - startAngle; 294c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) SkScalar startDegrees = WebCoreFloatToSkScalar(startAngle * 180 / piFloat); 29553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkScalar sweepDegrees = WebCoreFloatToSkScalar(sweep * 180 / piFloat); 296e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) SkScalar s360 = SkIntToScalar(360); 2978abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 2988abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // We can't use SkPath::addOval(), because addOval() makes new sub-path. addOval() calls moveTo() and close() internally. 2998abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 3008abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // Use s180, not s360, because SkPath::arcTo(oval, angle, s360, false) draws nothing. 3018abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) SkScalar s180 = SkIntToScalar(180); 302e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) if (SkScalarNearlyEqual(sweepDegrees, s360)) { 3038abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // SkPath::arcTo can't handle the sweepAngle that is equal to or greater than 2Pi. 3048abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_path.arcTo(oval, startDegrees, s180, false); 3058abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_path.arcTo(oval, startDegrees + s180, s180, false); 3068abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return; 3078abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) } 308e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) if (SkScalarNearlyEqual(sweepDegrees, -s360)) { 3098abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_path.arcTo(oval, startDegrees, -s180, false); 3108abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_path.arcTo(oval, startDegrees - s180, -s180, false); 31153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return; 31253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 31353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 31453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.arcTo(oval, startDegrees, sweepDegrees, false); 31553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 31653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void Path::addArc(const FloatPoint& p, float radius, float startAngle, float endAngle, bool anticlockwise) 3181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){ 3191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) addEllipse(p, radius, radius, startAngle, endAngle, anticlockwise); 3201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)} 3211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 32253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::addRect(const FloatRect& rect) 32353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 32453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.addRect(rect); 32553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 32653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 327c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)void Path::addEllipse(const FloatPoint& p, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, bool anticlockwise) 328c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){ 329e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) ASSERT(ellipseIsRenderable(startAngle, endAngle)); 3308abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT(startAngle >= 0 && startAngle < 2 * piFloat); 3318abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT((anticlockwise && (startAngle - endAngle) >= 0) || (!anticlockwise && (endAngle - startAngle) >= 0)); 3328abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 333bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (!rotation) { 334bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) addEllipse(FloatPoint(p.x(), p.y()), radiusX, radiusY, startAngle, endAngle, anticlockwise); 335bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 336c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 337c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 338c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) // Add an arc after the relevant transform. 3391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) AffineTransform ellipseTransform = AffineTransform::translation(p.x(), p.y()).rotate(rad2deg(rotation)); 340c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) ASSERT(ellipseTransform.isInvertible()); 341c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) AffineTransform inverseEllipseTransform = ellipseTransform.inverse(); 342c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) transform(inverseEllipseTransform); 3431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) addEllipse(FloatPoint::zero(), radiusX, radiusY, startAngle, endAngle, anticlockwise); 344c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) transform(ellipseTransform); 345c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)} 346c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 34753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::addEllipse(const FloatRect& rect) 34853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 34953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.addOval(rect); 35053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 35153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 35253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::addRoundedRect(const RoundedRect& r) 35353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 35453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) addRoundedRect(r.rect(), r.radii().topLeft(), r.radii().topRight(), r.radii().bottomLeft(), r.radii().bottomRight()); 35553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 35653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3570019e4eead4d990e4304c54a9028aca9122fb256Ben Murdochvoid Path::addRoundedRect(const FloatRect& rect, const FloatSize& roundingRadii) 35853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 35953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (rect.isEmpty()) 36053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return; 36153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 36253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatSize radius(roundingRadii); 36353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatSize halfSize(rect.width() / 2, rect.height() / 2); 36453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 36553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // Apply the SVG corner radius constraints, per the rect section of the SVG shapes spec: if 36602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // one of rx,ry is negative, then the other corner radius value is used. If both values are 36753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // negative then rx = ry = 0. If rx is greater than half of the width of the rectangle 36853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // then set rx to half of the width; ry is handled similarly. 36953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 37053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (radius.width() < 0) 37153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) radius.setWidth((radius.height() < 0) ? 0 : radius.height()); 37253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 37353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (radius.height() < 0) 37453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) radius.setHeight(radius.width()); 37553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 37653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (radius.width() > halfSize.width()) 37753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) radius.setWidth(halfSize.width()); 37853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 37953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (radius.height() > halfSize.height()) 38053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) radius.setHeight(halfSize.height()); 38153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3820019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch addPathForRoundedRect(rect, radius, radius, radius, radius); 38353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 38453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3850019e4eead4d990e4304c54a9028aca9122fb256Ben Murdochvoid Path::addRoundedRect(const FloatRect& rect, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius) 38653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 38753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (rect.isEmpty()) 38853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return; 38953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 39053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (rect.width() < topLeftRadius.width() + topRightRadius.width() 39153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) || rect.width() < bottomLeftRadius.width() + bottomRightRadius.width() 39253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) || rect.height() < topLeftRadius.height() + bottomLeftRadius.height() 39353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) || rect.height() < topRightRadius.height() + bottomRightRadius.height()) { 39453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // If all the radii cannot be accommodated, return a rect. 39553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) addRect(rect); 39653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return; 39753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 39853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3990019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch addPathForRoundedRect(rect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); 40053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 40153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 4020019e4eead4d990e4304c54a9028aca9122fb256Ben Murdochvoid Path::addPathForRoundedRect(const FloatRect& rect, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius) 40353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 40453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) addBeziersForRoundedRect(rect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); 40553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 40653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 40753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// Approximation of control point positions on a bezier to simulate a quarter of a circle. 40853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// This is 1-kappa, where kappa = 4 * (sqrt(2) - 1) / 3 40953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static const float gCircleControlPoint = 0.447715f; 41053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 41153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::addBeziersForRoundedRect(const FloatRect& rect, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius) 41253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 41353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) moveTo(FloatPoint(rect.x() + topLeftRadius.width(), rect.y())); 41453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 41553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) addLineTo(FloatPoint(rect.maxX() - topRightRadius.width(), rect.y())); 41653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (topRightRadius.width() > 0 || topRightRadius.height() > 0) 41753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) addBezierCurveTo(FloatPoint(rect.maxX() - topRightRadius.width() * gCircleControlPoint, rect.y()), 41853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatPoint(rect.maxX(), rect.y() + topRightRadius.height() * gCircleControlPoint), 41953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatPoint(rect.maxX(), rect.y() + topRightRadius.height())); 42053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) addLineTo(FloatPoint(rect.maxX(), rect.maxY() - bottomRightRadius.height())); 42153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (bottomRightRadius.width() > 0 || bottomRightRadius.height() > 0) 42253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) addBezierCurveTo(FloatPoint(rect.maxX(), rect.maxY() - bottomRightRadius.height() * gCircleControlPoint), 42353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatPoint(rect.maxX() - bottomRightRadius.width() * gCircleControlPoint, rect.maxY()), 42453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatPoint(rect.maxX() - bottomRightRadius.width(), rect.maxY())); 42553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) addLineTo(FloatPoint(rect.x() + bottomLeftRadius.width(), rect.maxY())); 42653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (bottomLeftRadius.width() > 0 || bottomLeftRadius.height() > 0) 42753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) addBezierCurveTo(FloatPoint(rect.x() + bottomLeftRadius.width() * gCircleControlPoint, rect.maxY()), 42853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatPoint(rect.x(), rect.maxY() - bottomLeftRadius.height() * gCircleControlPoint), 42953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatPoint(rect.x(), rect.maxY() - bottomLeftRadius.height())); 43053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) addLineTo(FloatPoint(rect.x(), rect.y() + topLeftRadius.height())); 43153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (topLeftRadius.width() > 0 || topLeftRadius.height() > 0) 43253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) addBezierCurveTo(FloatPoint(rect.x(), rect.y() + topLeftRadius.height() * gCircleControlPoint), 43353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatPoint(rect.x() + topLeftRadius.width() * gCircleControlPoint, rect.y()), 43453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FloatPoint(rect.x() + topLeftRadius.width(), rect.y())); 43553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 43653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) closeSubpath(); 43753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 43853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 43953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void Path::translate(const FloatSize& size) 44053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 44153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_path.offset(WebCoreFloatToSkScalar(size.width()), WebCoreFloatToSkScalar(size.height())); 44253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 44353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 444e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochbool Path::unionPath(const Path& other) 445e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{ 446e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return Op(m_path, other.m_path, kUnion_PathOp, &m_path); 447e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch} 448e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 449e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)#if !ASSERT_DISABLED 450e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)bool ellipseIsRenderable(float startAngle, float endAngle) 451e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles){ 452e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) return (std::abs(endAngle - startAngle) < 2 * piFloat) 453e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) || WebCoreFloatNearlyEqual(std::abs(endAngle - startAngle), 2 * piFloat); 454e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)} 455e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)#endif 456e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) 45753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 458