diff options
Diffstat (limited to 'Source/WebCore/platform/graphics/cairo/PathCairo.cpp')
-rw-r--r-- | Source/WebCore/platform/graphics/cairo/PathCairo.cpp | 80 |
1 files changed, 60 insertions, 20 deletions
diff --git a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp index c2bfb05f6..2022777ba 100644 --- a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp @@ -40,44 +40,66 @@ namespace WebCore { Path::Path() - : m_path(new CairoPath()) + : m_path(0) { } Path::~Path() { - delete m_path; + if (m_path) + delete m_path; } Path::Path(const Path& other) - : m_path(new CairoPath()) + : m_path(0) { - cairo_t* cr = platformPath()->context(); + if (other.isNull()) + return; + + cairo_t* cr = ensurePlatformPath()->context(); OwnPtr<cairo_path_t> pathCopy = adoptPtr(cairo_copy_path(other.platformPath()->context())); cairo_append_path(cr, pathCopy.get()); } +PlatformPathPtr Path::ensurePlatformPath() +{ + if (!m_path) + m_path = new CairoPath(); + return m_path; +} + Path& Path::operator=(const Path& other) { if (&other == this) return *this; - clear(); - cairo_t* cr = platformPath()->context(); - OwnPtr<cairo_path_t> pathCopy = adoptPtr(cairo_copy_path(other.platformPath()->context())); - cairo_append_path(cr, pathCopy.get()); + if (other.isNull()) { + if (m_path) { + delete m_path; + m_path = 0; + } + } else { + clear(); + cairo_t* cr = ensurePlatformPath()->context(); + OwnPtr<cairo_path_t> pathCopy = adoptPtr(cairo_copy_path(other.platformPath()->context())); + cairo_append_path(cr, pathCopy.get()); + } + return *this; } void Path::clear() { + if (isNull()) + return; + cairo_t* cr = platformPath()->context(); cairo_new_path(cr); } bool Path::isEmpty() const { - return !cairo_has_current_point(platformPath()->context()); + return isNull() || !cairo_has_current_point(platformPath()->context()); } bool Path::hasCurrentPoint() const @@ -87,6 +109,9 @@ bool Path::hasCurrentPoint() const FloatPoint Path::currentPoint() const { + if (isNull()) + return FloatPoint(); + // FIXME: Is this the correct way? double x; double y; @@ -96,25 +121,25 @@ FloatPoint Path::currentPoint() const void Path::translate(const FloatSize& p) { - cairo_t* cr = platformPath()->context(); + cairo_t* cr = ensurePlatformPath()->context(); cairo_translate(cr, -p.width(), -p.height()); } void Path::moveTo(const FloatPoint& p) { - cairo_t* cr = platformPath()->context(); + cairo_t* cr = ensurePlatformPath()->context(); cairo_move_to(cr, p.x(), p.y()); } void Path::addLineTo(const FloatPoint& p) { - cairo_t* cr = platformPath()->context(); + cairo_t* cr = ensurePlatformPath()->context(); cairo_line_to(cr, p.x(), p.y()); } void Path::addRect(const FloatRect& rect) { - cairo_t* cr = platformPath()->context(); + cairo_t* cr = ensurePlatformPath()->context(); cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height()); } @@ -123,7 +148,7 @@ void Path::addRect(const FloatRect& rect) */ void Path::addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& point) { - cairo_t* cr = platformPath()->context(); + cairo_t* cr = ensurePlatformPath()->context(); double x, y; double x1 = controlPoint.x(); double y1 = controlPoint.y(); @@ -138,7 +163,7 @@ void Path::addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& poin void Path::addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& controlPoint3) { - cairo_t* cr = platformPath()->context(); + cairo_t* cr = ensurePlatformPath()->context(); cairo_curve_to(cr, controlPoint1.x(), controlPoint1.y(), controlPoint2.x(), controlPoint2.y(), controlPoint3.x(), controlPoint3.y()); @@ -151,7 +176,7 @@ void Path::addArc(const FloatPoint& p, float r, float startAngle, float endAngle if (!isfinite(r) || !isfinite(startAngle) || !isfinite(endAngle)) return; - cairo_t* cr = platformPath()->context(); + cairo_t* cr = ensurePlatformPath()->context(); float sweep = endAngle - startAngle; const float twoPI = 2 * piFloat; if ((sweep <= -twoPI || sweep >= twoPI) @@ -177,6 +202,7 @@ static inline float areaOfTriangleFormedByPoints(const FloatPoint& p1, const Flo void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) { + // FIXME: Why do we return if the path is empty? Can't a path start with an arc? if (isEmpty()) return; @@ -257,7 +283,7 @@ void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) void Path::addEllipse(const FloatRect& rect) { - cairo_t* cr = platformPath()->context(); + cairo_t* cr = ensurePlatformPath()->context(); cairo_save(cr); float yRadius = .5 * rect.height(); float xRadius = .5 * rect.width(); @@ -269,12 +295,16 @@ void Path::addEllipse(const FloatRect& rect) void Path::closeSubpath() { - cairo_t* cr = platformPath()->context(); + cairo_t* cr = ensurePlatformPath()->context(); cairo_close_path(cr); } FloatRect Path::boundingRect() const { + // Should this be isEmpty() or can an empty path have a non-zero origin? + if (isNull()) + return FloatRect(); + cairo_t* cr = platformPath()->context(); double x0, x1, y0, y1; cairo_path_extents(cr, &x0, &y0, &x1, &y1); @@ -283,6 +313,10 @@ FloatRect Path::boundingRect() const FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const { + // Should this be isEmpty() or can an empty path have a non-zero origin? + if (isNull()) + return FloatRect(); + cairo_t* cr = platformPath()->context(); if (applier) { GraphicsContext gc(cr); @@ -296,7 +330,7 @@ FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const bool Path::contains(const FloatPoint& point, WindRule rule) const { - if (!isfinite(point.x()) || !isfinite(point.y())) + if (isNull() || !isfinite(point.x()) || !isfinite(point.y())) return false; cairo_t* cr = platformPath()->context(); cairo_fill_rule_t cur = cairo_get_fill_rule(cr); @@ -308,6 +342,9 @@ bool Path::contains(const FloatPoint& point, WindRule rule) const bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) const { + if (isNull()) + return false; + ASSERT(applier); cairo_t* cr = platformPath()->context(); GraphicsContext gc(cr); @@ -318,6 +355,9 @@ bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) void Path::apply(void* info, PathApplierFunction function) const { + if (isNull()) + return; + cairo_t* cr = platformPath()->context(); OwnPtr<cairo_path_t> pathCopy = adoptPtr(cairo_copy_path(cr)); cairo_path_data_t* data; @@ -355,7 +395,7 @@ void Path::apply(void* info, PathApplierFunction function) const void Path::transform(const AffineTransform& trans) { - cairo_t* cr = platformPath()->context(); + cairo_t* cr = ensurePlatformPath()->context(); cairo_matrix_t c_matrix = cairo_matrix_t(trans); cairo_matrix_invert(&c_matrix); cairo_transform(cr, &c_matrix); |