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 "StrokeStyleApplier.h" 34 35 #include <stdio.h> 36 37 #include <wx/defs.h> 38 #include <wx/graphics.h> 39 40 namespace WebCore { 41 42 int getWxWindRuleForWindRule(WindRule rule) 43 { 44 if (rule == RULE_EVENODD) 45 return wxODDEVEN_RULE; 46 47 return wxWINDING_RULE; 48 } 49 50 Path::Path() 51 { 52 m_path = 0; 53 // NB: This only supports the 'default' renderer as determined by wx on 54 // each platform. If an app uses a non-default renderer (e.g. Cairo on Win), 55 // there will be problems, but there's no way we can determine which 56 // renderer an app is using right now with wx API, so we will just handle 57 // the common case. 58 #if USE(WXGC) 59 wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetDefaultRenderer(); 60 if (renderer) { 61 wxGraphicsPath path = renderer->CreatePath(); 62 m_path = new wxGraphicsPath(path); 63 } 64 #endif 65 } 66 67 Path::~Path() 68 { 69 clear(); 70 } 71 72 Path::Path(const Path& path) 73 { 74 m_path = new wxGraphicsPath(*path.m_path); 75 } 76 77 bool Path::contains(const FloatPoint& point, const WindRule rule) const 78 { 79 #if USE(WXGC) 80 if (m_path) { 81 #if wxCHECK_VERSION(2,9,0) 82 return m_path->Contains(point.x(), point.y(), static_cast<wxPolygonFillMode>(getWxWindRuleForWindRule(rule))); 83 #else 84 return m_path->Contains(point.x(), point.y(), getWxWindRuleForWindRule(rule)); 85 #endif 86 } 87 #endif 88 return false; 89 } 90 91 void Path::translate(const FloatSize&) 92 { 93 notImplemented(); 94 } 95 96 FloatRect Path::boundingRect() const 97 { 98 #if USE(WXGC) 99 if (m_path) { 100 return m_path->GetBox(); 101 } 102 #endif 103 104 return FloatRect(); 105 } 106 107 FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) 108 { 109 notImplemented(); 110 return FloatRect(); 111 } 112 113 Path& Path::operator=(const Path&) 114 { 115 notImplemented(); 116 return*this; 117 } 118 119 void Path::clear() 120 { 121 if (m_path) 122 delete m_path; 123 124 #if USE(WXGC) 125 wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetDefaultRenderer(); 126 if (renderer) { 127 wxGraphicsPath path = renderer->CreatePath(); 128 m_path = new wxGraphicsPath(path); 129 } 130 #endif 131 } 132 133 void Path::moveTo(const FloatPoint& point) 134 { 135 #if USE(WXGC) 136 if (m_path) 137 m_path->MoveToPoint(point.x(), point.y()); 138 #endif 139 } 140 141 void Path::addLineTo(const FloatPoint& point) 142 { 143 #if USE(WXGC) 144 if (m_path) 145 m_path->AddLineToPoint(point.x(), point.y()); 146 #endif 147 } 148 149 void Path::addQuadCurveTo(const FloatPoint& control, const FloatPoint& end) 150 { 151 #if USE(WXGC) 152 if (m_path) 153 m_path->AddQuadCurveToPoint(control.x(), control.y(), end.x(), end.y()); 154 #endif 155 } 156 157 void Path::addBezierCurveTo(const FloatPoint& control1, const FloatPoint& control2, const FloatPoint& end) 158 { 159 #if USE(WXGC) 160 if (m_path) 161 m_path->AddCurveToPoint(control1.x(), control1.y(), control2.x(), control2.y(), end.x(), end.y()); 162 #endif 163 } 164 165 void Path::addArcTo(const FloatPoint& point1, const FloatPoint& point2, float radius) 166 { 167 #if USE(WXGC) 168 if (m_path) 169 m_path->AddArcToPoint(point1.x(), point1.y(), point2.x(), point2.y(), radius); 170 #endif 171 } 172 173 void Path::closeSubpath() 174 { 175 #if USE(WXGC) 176 if (m_path) 177 m_path->CloseSubpath(); 178 #endif 179 } 180 181 void Path::addArc(const FloatPoint& point, float radius, float startAngle, float endAngle, bool clockwise) 182 { 183 #if USE(WXGC) 184 if (m_path) 185 m_path->AddArc(point.x(), point.y(), radius, startAngle, endAngle, clockwise); 186 #endif 187 } 188 189 void Path::addRect(const FloatRect& rect) 190 { 191 #if USE(WXGC) 192 if (m_path) 193 m_path->AddRectangle(rect.x(), rect.y(), rect.width(), rect.height()); 194 #endif 195 } 196 197 void Path::addEllipse(const FloatRect& rect) 198 { 199 #if USE(WXGC) 200 if (m_path) 201 m_path->AddEllipse(rect.x(), rect.y(), rect.width(), rect.height()); 202 #endif 203 } 204 205 void Path::transform(const AffineTransform& transform) 206 { 207 #if USE(WXGC) 208 if (m_path) 209 m_path->Transform(transform); 210 #endif 211 } 212 213 void Path::apply(void* info, PathApplierFunction function) const 214 { 215 notImplemented(); 216 } 217 218 bool Path::isEmpty() const 219 { 220 #if USE(WXGC) 221 if (m_path) { 222 wxDouble width, height; 223 m_path->GetBox(NULL, NULL, &width, &height); 224 return (width == 0 && height == 0); 225 } 226 #endif 227 return true; 228 } 229 230 bool Path::hasCurrentPoint() const 231 { 232 return !isEmpty(); 233 } 234 235 } 236