1/* 2 * Copyright (C) 2007 Kevin Ollivier All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "Path.h" 28 29#include "AffineTransform.h" 30#include "FloatPoint.h" 31#include "FloatRect.h" 32#include "NotImplemented.h" 33#include "PlatformString.h" 34#include "StrokeStyleApplier.h" 35 36#include <stdio.h> 37 38#include <wx/defs.h> 39#include <wx/graphics.h> 40 41namespace WebCore { 42 43int getWxWindRuleForWindRule(WindRule rule) 44{ 45 if (rule == RULE_EVENODD) 46 return wxODDEVEN_RULE; 47 48 return wxWINDING_RULE; 49} 50 51Path::Path() 52{ 53 m_path = 0; 54 // NB: This only supports the 'default' renderer as determined by wx on 55 // each platform. If an app uses a non-default renderer (e.g. Cairo on Win), 56 // there will be problems, but there's no way we can determine which 57 // renderer an app is using right now with wx API, so we will just handle 58 // the common case. 59#if USE(WXGC) 60 wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetDefaultRenderer(); 61 if (renderer) { 62 wxGraphicsPath path = renderer->CreatePath(); 63 m_path = new wxGraphicsPath(path); 64 } 65#endif 66} 67 68Path::~Path() 69{ 70 clear(); 71} 72 73Path::Path(const Path& path) 74{ 75 m_path = new wxGraphicsPath(*path.m_path); 76} 77 78bool Path::contains(const FloatPoint& point, const WindRule rule) const 79{ 80#if USE(WXGC) 81 if (m_path) { 82#if wxCHECK_VERSION(2,9,0) 83 return m_path->Contains(point.x(), point.y(), static_cast<wxPolygonFillMode>(getWxWindRuleForWindRule(rule))); 84#else 85 return m_path->Contains(point.x(), point.y(), getWxWindRuleForWindRule(rule)); 86#endif 87 } 88#endif 89 return false; 90} 91 92void Path::translate(const FloatSize&) 93{ 94 notImplemented(); 95} 96 97FloatRect Path::boundingRect() const 98{ 99#if USE(WXGC) 100 if (m_path) { 101 return m_path->GetBox(); 102 } 103#endif 104 105 return FloatRect(); 106} 107 108FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const 109{ 110 notImplemented(); 111 return FloatRect(); 112} 113 114bool Path::strokeContains(StrokeStyleApplier*, const FloatPoint&) const 115{ 116 notImplemented(); 117 return false; 118} 119 120Path& Path::operator=(const Path& path) 121{ 122 *m_path = *path.platformPath(); 123 return *this; 124} 125 126void Path::clear() 127{ 128 if (m_path) 129 delete m_path; 130 131#if USE(WXGC) 132 wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetDefaultRenderer(); 133 if (renderer) { 134 wxGraphicsPath path = renderer->CreatePath(); 135 m_path = new wxGraphicsPath(path); 136 } 137#endif 138} 139 140void Path::moveTo(const FloatPoint& point) 141{ 142#if USE(WXGC) 143 if (m_path) 144 m_path->MoveToPoint(point.x(), point.y()); 145#endif 146} 147 148void Path::addLineTo(const FloatPoint& point) 149{ 150#if USE(WXGC) 151 if (m_path) 152 m_path->AddLineToPoint(point.x(), point.y()); 153#endif 154} 155 156void Path::addQuadCurveTo(const FloatPoint& control, const FloatPoint& end) 157{ 158#if USE(WXGC) 159 if (m_path) 160 m_path->AddQuadCurveToPoint(control.x(), control.y(), end.x(), end.y()); 161#endif 162} 163 164void Path::addBezierCurveTo(const FloatPoint& control1, const FloatPoint& control2, const FloatPoint& end) 165{ 166#if USE(WXGC) 167 if (m_path) 168 m_path->AddCurveToPoint(control1.x(), control1.y(), control2.x(), control2.y(), end.x(), end.y()); 169#endif 170} 171 172void Path::addArcTo(const FloatPoint& point1, const FloatPoint& point2, float radius) 173{ 174#if USE(WXGC) 175 if (m_path) 176 m_path->AddArcToPoint(point1.x(), point1.y(), point2.x(), point2.y(), radius); 177#endif 178} 179 180void Path::closeSubpath() 181{ 182#if USE(WXGC) 183 if (m_path) 184 m_path->CloseSubpath(); 185#endif 186} 187 188void Path::addArc(const FloatPoint& point, float radius, float startAngle, float endAngle, bool clockwise) 189{ 190#if USE(WXGC) 191 if (m_path) 192 m_path->AddArc(point.x(), point.y(), radius, startAngle, endAngle, clockwise); 193#endif 194} 195 196void Path::addRect(const FloatRect& rect) 197{ 198#if USE(WXGC) 199 if (m_path) 200 m_path->AddRectangle(rect.x(), rect.y(), rect.width(), rect.height()); 201#endif 202} 203 204void Path::addEllipse(const FloatRect& rect) 205{ 206#if USE(WXGC) 207 if (m_path) 208 m_path->AddEllipse(rect.x(), rect.y(), rect.width(), rect.height()); 209#endif 210} 211 212void Path::transform(const AffineTransform& transform) 213{ 214#if USE(WXGC) 215 if (m_path) 216 m_path->Transform(transform); 217#endif 218} 219 220void Path::apply(void* info, PathApplierFunction function) const 221{ 222 notImplemented(); 223} 224 225bool Path::isEmpty() const 226{ 227#if USE(WXGC) 228 if (m_path) { 229 wxDouble x, y, width, height; 230 m_path->GetBox(&x, &y, &width, &height); 231 return (width == 0 && height == 0); 232 } 233#endif 234 return true; 235} 236 237bool Path::hasCurrentPoint() const 238{ 239 return !isEmpty(); 240} 241 242FloatPoint Path::currentPoint() const 243{ 244 // FIXME: return current point of subpath. 245 float quietNaN = std::numeric_limits<float>::quiet_NaN(); 246 return FloatPoint(quietNaN, quietNaN); 247} 248 249} 250