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 41 namespace WebCore { 42 43 int getWxWindRuleForWindRule(WindRule rule) 44 { 45 if (rule == RULE_EVENODD) 46 return wxODDEVEN_RULE; 47 48 return wxWINDING_RULE; 49 } 50 51 Path::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 68 Path::~Path() 69 { 70 clear(); 71 } 72 73 Path::Path(const Path& path) 74 { 75 m_path = new wxGraphicsPath(*path.m_path); 76 } 77 78 bool 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 92 void Path::translate(const FloatSize&) 93 { 94 notImplemented(); 95 } 96 97 FloatRect 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 108 FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const 109 { 110 notImplemented(); 111 return FloatRect(); 112 } 113 114 bool Path::strokeContains(StrokeStyleApplier*, const FloatPoint&) const 115 { 116 notImplemented(); 117 return false; 118 } 119 120 Path& Path::operator=(const Path& path) 121 { 122 *m_path = *path.platformPath(); 123 return *this; 124 } 125 126 void 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 140 void 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 148 void 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 156 void 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 164 void 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 172 void 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 180 void Path::closeSubpath() 181 { 182 #if USE(WXGC) 183 if (m_path) 184 m_path->CloseSubpath(); 185 #endif 186 } 187 188 void 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 196 void 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 204 void 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 212 void Path::transform(const AffineTransform& transform) 213 { 214 #if USE(WXGC) 215 if (m_path) 216 m_path->Transform(transform); 217 #endif 218 } 219 220 void Path::apply(void* info, PathApplierFunction function) const 221 { 222 notImplemented(); 223 } 224 225 bool 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 237 bool Path::hasCurrentPoint() const 238 { 239 return !isEmpty(); 240 } 241 242 FloatPoint 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