コード例 #1
0
void CanvasRenderingContext2D::fillRect(float x, float y, float width, float height, ExceptionCode& ec)
{
    ec = 0;

    if (!(width >= 0 && height >= 0)) {
        ec = INDEX_SIZE_ERR;
        return;
    }

    GraphicsContext* c = drawingContext();
    if (!c)
        return;
    // FIXME: Do this through platform-independent GraphicsContext API.
#if PLATFORM(CG)
    CGRect rect = CGRectMake(x, y, width, height);

    willDraw(rect);

    if (state().m_fillStyle->gradient()) {
        // Shading works on the entire clip region, so convert the rect to a clip.
        c->save();
        CGContextClipToRect(c->platformContext(), rect);
        CGContextDrawShading(c->platformContext(), state().m_fillStyle->gradient()->platformShading());        
        c->restore();
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
        CGContextFillRect(c->platformContext(), rect);
    }
#elif PLATFORM(QT)
    QRectF rect(x, y, width, height);
    willDraw(rect);
    QPainter* p = static_cast<QPainter*>(c->platformContext());
    if (state().m_fillStyle->gradient()) {
        p->fillRect(rect, QBrush(*(state().m_fillStyle->gradient()->platformShading())));
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
        p->fillRect(rect, p->brush());
    }
#elif PLATFORM(CAIRO)
    FloatRect rect(x, y, width, height);
    willDraw(rect);
    cairo_t* cr = c->platformContext();
    cairo_save(cr);
    if (state().m_fillStyle->gradient()) {
        cairo_set_source(cr, state().m_fillStyle->gradient()->platformShading());
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
    }
    cairo_rectangle(cr, x, y, width, height);
    cairo_fill(cr);
    cairo_restore(cr);
#endif
}
コード例 #2
0
void CanvasRenderingContext2D::fill()
{
    GraphicsContext* c = drawingContext();
    if (!c)
        return;
    // FIXME: Do this through platform-independent GraphicsContext API.
#if PLATFORM(CG)
    CGContextBeginPath(c->platformContext());
    CGContextAddPath(c->platformContext(), state().m_path.platformPath());

    if (!state().m_path.isEmpty())
        willDraw(CGContextGetPathBoundingBox(c->platformContext()));

    if (state().m_fillStyle->gradient()) {
        // Shading works on the entire clip region, so convert the current path to a clip.
        c->save();
        CGContextClip(c->platformContext());
        CGContextDrawShading(c->platformContext(), state().m_fillStyle->gradient()->platformShading());        
        c->restore();
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
        CGContextFillPath(c->platformContext());
    }
#elif PLATFORM(QT)
    QPainterPath* path = state().m_path.platformPath();
    QPainter* p = static_cast<QPainter*>(c->platformContext());
    willDraw(path->controlPointRect());
    if (state().m_fillStyle->gradient()) {
        p->fillPath(*path, QBrush(*(state().m_fillStyle->gradient()->platformShading())));
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
        p->fillPath(*path, p->brush());
    }
#elif PLATFORM(CAIRO)
    cairo_t* pathCr = state().m_path.platformPath()->m_cr;
    cairo_t* cr = c->platformContext();
    cairo_save(cr);
    willDraw(state().m_path.boundingRect());
    if (state().m_fillStyle->gradient()) {
        cairo_set_source(cr, state().m_fillStyle->gradient()->platformShading());
        c->addPath(state().m_path);
        cairo_fill(cr);
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
        c->addPath(state().m_path);
        cairo_fill(cr);
    }
    cairo_restore(cr);
#endif

    clearPathForDashboardBackwardCompatibilityMode();
}
コード例 #3
0
// FIXME: Why isn't this just another overload of drawImage? Why have a different name?
void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
    float sx, float sy, float sw, float sh,
    float dx, float dy, float dw, float dh,
    const String& compositeOperation)
{
    if (!image)
        return;

    CachedImage* cachedImage = image->cachedImage();
    if (!cachedImage)
        return;

    GraphicsContext* c = drawingContext();
    if (!c)
        return;

    CompositeOperator op;
    if (!parseCompositeOperator(compositeOperation, op))
        op = CompositeSourceOver;

    FloatRect destRect = FloatRect(dx, dy, dw, dh);
    willDraw(destRect);
#ifdef __OWB__
    c->drawImage(cachedImage->image()->nativeImageForCurrentFrame(), destRect, FloatRect(sx, sy, sw, sh), op);
    cachedImage->image()->startAnimation();
#else
    c->drawImage(cachedImage->image(), destRect, FloatRect(sx, sy, sw, sh), op);
#endif //__OWB__
}
コード例 #4
0
void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float height, float lineWidth, ExceptionCode& ec)
{
    ec = 0;

    if (!(width >= 0 && height >= 0 && lineWidth >= 0)) {
        ec = INDEX_SIZE_ERR;
        return;
    }

    GraphicsContext* c = drawingContext();
    if (!c)
        return;

    FloatRect rect(x, y, width, height);

    FloatRect boundingRect = rect;
    boundingRect.inflate(lineWidth / 2);
    willDraw(boundingRect);

    // FIXME: No support for gradients!
    if (state().m_strokeStyle->pattern())
        applyStrokePattern();

    c->strokeRect(rect, lineWidth);
}
コード例 #5
0
void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect,
    ExceptionCode& ec)
{
    ASSERT(image);

    ec = 0;

    FloatRect imageRect = FloatRect(FloatPoint(), size(image));
    if (!(imageRect.contains(srcRect) && srcRect.width() >= 0 && srcRect.height() >= 0 
            && dstRect.width() >= 0 && dstRect.height() >= 0)) {
        ec = INDEX_SIZE_ERR;
        return;
    }

    if (srcRect.isEmpty() || dstRect.isEmpty())
        return;

    GraphicsContext* c = drawingContext();
    if (!c)
        return;

    CachedImage* cachedImage = image->cachedImage();
    if (!cachedImage)
        return;

    FloatRect sourceRect = c->roundToDevicePixels(srcRect);
    FloatRect destRect = c->roundToDevicePixels(dstRect);
    willDraw(destRect);
#ifdef __OWB__
    c->drawImage(cachedImage->image()->nativeImageForCurrentFrame(), destRect, sourceRect, state().m_globalComposite);
    cachedImage->image()->startAnimation();
#else
    c->drawImage(cachedImage->image(), destRect, sourceRect, state().m_globalComposite);
#endif //__OWB__
}
コード例 #6
0
void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect,
    ExceptionCode& ec)
{
    ASSERT(image);

    ec = 0;

    FloatRect imageRect = FloatRect(FloatPoint(), size(image));
    if (!(imageRect.contains(srcRect) && srcRect.width() >= 0 && srcRect.height() >= 0 
            && dstRect.width() >= 0 && dstRect.height() >= 0)) {
        ec = INDEX_SIZE_ERR;
        return;
    }

    if (srcRect.isEmpty() || dstRect.isEmpty())
        return;

    GraphicsContext* c = drawingContext();
    if (!c)
        return;

    CachedImage* cachedImage = image->cachedImage();
    if (!cachedImage)
        return;

    if (m_canvas->originClean())
        checkOrigin(KURL(cachedImage->url()));

    FloatRect sourceRect = c->roundToDevicePixels(srcRect);
    FloatRect destRect = c->roundToDevicePixels(dstRect);
    willDraw(destRect);
    c->drawImage(cachedImage->image(), destRect, sourceRect, state().m_globalComposite);
}
コード例 #7
0
// FIXME: Why isn't this just another overload of drawImage? Why have a different name?
void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
    float sx, float sy, float sw, float sh,
    float dx, float dy, float dw, float dh,
    const String& compositeOperation)
{
    if (!image)
        return;

    CachedImage* cachedImage = image->cachedImage();
    if (!cachedImage)
        return;

    if (m_canvas->originClean())
        checkOrigin(KURL(cachedImage->url()));

    GraphicsContext* c = drawingContext();
    if (!c)
        return;

    CompositeOperator op;
    if (!parseCompositeOperator(compositeOperation, op))
        op = CompositeSourceOver;

    FloatRect destRect = FloatRect(dx, dy, dw, dh);
    willDraw(destRect);
    c->drawImage(cachedImage->image(), destRect, FloatRect(sx, sy, sw, sh), op);
}
コード例 #8
0
void CanvasRenderingContext2D::stroke()
{
    GraphicsContext* c = drawingContext();
    if (!c)
        return;
    // FIXME: Do this through platform-independent GraphicsContext API.
#if PLATFORM(CG)
    CGContextBeginPath(c->platformContext());
    CGContextAddPath(c->platformContext(), state().m_path.platformPath());

    if (!state().m_path.isEmpty()) {
        float lineWidth = state().m_lineWidth;
        float inset = -lineWidth / 2;
        CGRect boundingRect = CGRectInset(CGContextGetPathBoundingBox(c->platformContext()), inset, inset);
        willDraw(boundingRect);
    }

    if (state().m_strokeStyle->gradient()) {
        // Shading works on the entire clip region, so convert the current path to a clip.
        c->save();
        CGContextReplacePathWithStrokedPath(c->platformContext());
        CGContextClip(c->platformContext());
        CGContextDrawShading(c->platformContext(), state().m_strokeStyle->gradient()->platformShading());        
        c->restore();
    } else {
        if (state().m_strokeStyle->pattern())
            applyStrokePattern();
        CGContextStrokePath(c->platformContext());
    }
#elif PLATFORM(QT)
    QPainterPath* path = state().m_path.platformPath();
    QPainter* p = static_cast<QPainter*>(c->platformContext());
    willDraw(path->controlPointRect());
    if (state().m_strokeStyle->gradient()) {
        p->save();
        p->setBrush(*(state().m_strokeStyle->gradient()->platformShading()));
        p->strokePath(*path, p->pen());
        p->restore();
    } else {
        if (state().m_strokeStyle->pattern())
            applyStrokePattern();
        p->strokePath(*path, p->pen());
    }
#endif

    clearPathForDashboardBackwardCompatibilityMode();
}
コード例 #9
0
void CanvasRenderingContext2D::fill()
{
    GraphicsContext* c = drawingContext();
    if (!c)
        return;

    c->beginPath();
    c->addPath(m_path);
    if (!m_path.isEmpty())
        willDraw(m_path.boundingRect());

#if PLATFORM(CG)
    if (state().m_fillStyle->canvasGradient()) {
        // Shading works on the entire clip region, so convert the current path to a clip.
        c->save();
        CGContextClip(c->platformContext());
        CGContextDrawShading(c->platformContext(), state().m_fillStyle->canvasGradient()->gradient().platformGradient());        
        c->restore();
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
        CGContextFillPath(c->platformContext());
    }
#elif PLATFORM(QT)
    QPainterPath* path = m_path.platformPath();
    QPainter* p = static_cast<QPainter*>(c->platformContext());
    if (state().m_fillStyle->canvasGradient()) {
        p->fillPath(*path, QBrush(*(state().m_fillStyle->canvasGradient()->gradient().platformGradient())));
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
        p->fillPath(*path, p->brush());
    }
#elif PLATFORM(CAIRO) && !PLATFORM(BAL)
    cairo_t* cr = c->platformContext();
    cairo_save(cr);

    if (state().m_fillStyle->canvasGradient()) {
        cairo_set_source(cr, state().m_fillStyle->canvasGradient()->gradient().platformGradient());
        cairo_fill(cr);
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
        cairo_fill(cr);
    }
    cairo_restore(cr);
#elif PLATFORM(BAL)
   //FIXME
   notImplemented();
#endif

#if ENABLE(DASHBOARD_SUPPORT)
    clearPathForDashboardBackwardCompatibilityMode();
#endif
}
コード例 #10
0
void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
{
    if (!validateRectForCanvas(x, y, width, height))
        return;
    GraphicsContext* c = drawingContext();
    if (!c)
        return;
    FloatRect rect(x, y, width, height);
    willDraw(rect);
    c->clearRect(rect);
}
コード例 #11
0
void CanvasRenderingContext2D::fillRect(float x, float y, float width, float height)
{
    if (!validateRectForCanvas(x, y, width, height))
        return;

    GraphicsContext* c = drawingContext();
    if (!c)
        return;

    FloatRect rect(x, y, width, height);
    willDraw(rect);

    // FIXME: Do this through platform-independent GraphicsContext API.
#if PLATFORM(CG)
    if (state().m_fillStyle->canvasGradient()) {
        // Shading works on the entire clip region, so convert the rect to a clip.
        c->save();
        CGContextClipToRect(c->platformContext(), rect);
        CGContextDrawShading(c->platformContext(), state().m_fillStyle->canvasGradient()->gradient().platformGradient());        
        c->restore();
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
        CGContextFillRect(c->platformContext(), rect);
    }
#elif PLATFORM(QT)
    QPainter* p = static_cast<QPainter*>(c->platformContext());
    if (state().m_fillStyle->canvasGradient()) {
        p->fillRect(rect, QBrush(*(state().m_fillStyle->canvasGradient()->gradient().platformGradient())));
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
        p->fillRect(rect, p->brush());
    }
#elif PLATFORM(CAIRO) && !PLATFORM(BAL)
    cairo_t* cr = c->platformContext();
    cairo_save(cr);
    if (state().m_fillStyle->canvasGradient()) {
        cairo_set_source(cr, state().m_fillStyle->canvasGradient()->gradient().platformGradient());
    } else {
        if (state().m_fillStyle->pattern())
            applyFillPattern();
    }
    cairo_rectangle(cr, x, y, width, height);
    cairo_fill(cr);
    cairo_restore(cr);
#elif PLATFORM(BAL)
    //FIXME
    notImplemented();
#endif
}
コード例 #12
0
void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height, ExceptionCode& ec)
{
    ec = 0;
    if (!(width >= 0 && height >= 0)) {
        ec = INDEX_SIZE_ERR;
        return;
    }
    GraphicsContext* c = drawingContext();
    if (!c)
        return;
    FloatRect rect(x, y, width, height);
    willDraw(rect);
    c->clearRect(rect);
}
コード例 #13
0
void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float height, float lineWidth, ExceptionCode& ec)
{
    ec = 0;

    if (!(width >= 0 && height >= 0 && lineWidth >= 0)) {
        ec = INDEX_SIZE_ERR;
        return;
    }

    GraphicsContext* c = drawingContext();
    if (!c)
        return;

    FloatRect rect(x, y, width, height);

    FloatRect boundingRect = rect;
    boundingRect.inflate(lineWidth / 2);
    willDraw(boundingRect);

#if PLATFORM(QT)
    //This is done because underneath doesn't support gradients
    // once we have canvas gradients implemented in the general code
    // just remove this section
    if (state().m_strokeStyle->pattern())
        applyStrokePattern();
    QPainter* p = static_cast<QPainter*>(c->platformContext());
    p->save();
    {
        p->setBrush(Qt::NoBrush);
        QPen pen = p->pen();
        pen.setWidthF(lineWidth);
        if (state().m_strokeStyle->gradient())
            pen.setBrush(QBrush(*(state().m_strokeStyle->gradient()->platformShading())));
        p->setPen(pen);
        p->drawRect(rect);
    }
    p->restore();
#else
    // FIXME: No support for gradients!
    if (state().m_strokeStyle->pattern())
        applyStrokePattern();

    c->strokeRect(rect, lineWidth);
#endif
}
コード例 #14
0
void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, float dirtyX, float dirtyY, 
                                            float dirtyWidth, float dirtyHeight, ExceptionCode& ec)
{
    if (!data) {
        ec = TYPE_MISMATCH_ERR;
        return;
    }
    if (!isfinite(dx) || !isfinite(dy) || !isfinite(dirtyX) || 
        !isfinite(dirtyY) || !isfinite(dirtyWidth) || !isfinite(dirtyHeight)) {
        ec = INDEX_SIZE_ERR;
        return;
    }

    ImageBuffer* buffer = m_canvas ? m_canvas->buffer() : 0;
    if (!buffer)
        return;

    if (dirtyWidth < 0) {
        dirtyX += dirtyWidth;
        dirtyWidth = -dirtyWidth;
    }

    if (dirtyHeight < 0) {
        dirtyY += dirtyHeight;
        dirtyHeight = -dirtyHeight;
    }

    FloatRect clipRect(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
    clipRect.intersect(IntRect(0, 0, data->width(), data->height()));
    IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy));
    IntRect sourceRect = enclosingIntRect(clipRect);
    sourceRect.move(destOffset);
    sourceRect.intersect(IntRect(IntPoint(), buffer->size()));
    if (sourceRect.isEmpty())
        return;
    willDraw(sourceRect);
    sourceRect.move(-destOffset);
    IntPoint destPoint(destOffset.width(), destOffset.height());
    
    buffer->putImageData(data, sourceRect, destPoint);
}
コード例 #15
0
void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, const FloatRect& srcRect,
    const FloatRect& dstRect, ExceptionCode& ec)
{
    ASSERT(canvas);

    ec = 0;

    FloatRect srcCanvasRect = FloatRect(FloatPoint(), canvas->size());
    if (!(srcCanvasRect.contains(srcRect) && srcRect.width() >= 0 && srcRect.height() >= 0 
            && dstRect.width() >= 0 && dstRect.height() >= 0)) {
        ec = INDEX_SIZE_ERR;
        return;
    }

    if (srcRect.isEmpty() || dstRect.isEmpty())
        return;

    GraphicsContext* c = drawingContext();
    if (!c)
        return;
        
    FloatRect sourceRect = c->roundToDevicePixels(srcRect);
    FloatRect destRect = c->roundToDevicePixels(dstRect);
        
    // FIXME: Do this through platform-independent GraphicsContext API.
    ImageBuffer* buffer = canvas->buffer();
    if (!buffer)
        return;

    if (!canvas->originClean())
        m_canvas->setOriginTainted();

    c->drawImage(buffer->image(), destRect, sourceRect);
    willDraw(destRect); // This call comes after drawImage, since the buffer we draw into may be our own, and we need to make sure it is dirty.
                        // FIXME: Arguably willDraw should become didDraw and occur after drawing calls and not before them to avoid problems like this.
}
コード例 #16
0
void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float height, float lineWidth)
{
    if (!validateRectForCanvas(x, y, width, height))
        return;
    
    if (!(lineWidth >= 0))
        return;

    GraphicsContext* c = drawingContext();
    if (!c)
        return;

    FloatRect rect(x, y, width, height);

    FloatRect boundingRect = rect;
    boundingRect.inflate(lineWidth / 2);
    willDraw(boundingRect);

    // FIXME: No support for gradients!
    if (state().m_strokeStyle->pattern())
        applyStrokePattern();

    c->strokeRect(rect, lineWidth);
}
コード例 #17
0
void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, const FloatRect& srcRect,
    const FloatRect& dstRect, ExceptionCode& ec)
{
    ASSERT(canvas);

    ec = 0;

    FloatRect srcCanvasRect = FloatRect(FloatPoint(), canvas->size());
    if (!(srcCanvasRect.contains(srcRect) && srcRect.width() >= 0 && srcRect.height() >= 0 
            && dstRect.width() >= 0 && dstRect.height() >= 0)) {
        ec = INDEX_SIZE_ERR;
        return;
    }

    if (srcRect.isEmpty() || dstRect.isEmpty())
        return;

    GraphicsContext* c = drawingContext();
    if (!c)
        return;
        
    FloatRect sourceRect = c->roundToDevicePixels(srcRect);
    FloatRect destRect = c->roundToDevicePixels(dstRect);
        
    // FIXME: Do this through platform-independent GraphicsContext API.
#if PLATFORM(CG)
    CGImageRef platformImage = canvas->createPlatformImage();
    if (!platformImage)
        return;

    willDraw(destRect);

    float iw = CGImageGetWidth(platformImage);
    float ih = CGImageGetHeight(platformImage);
    if (sourceRect.x() == 0 && sourceRect.y() == 0 && iw == sourceRect.width() && ih == sourceRect.height()) {
        // Fast path, yay!
        CGContextDrawImage(c->platformContext(), destRect, platformImage);
    } else {
        // Slow path, boo!
        // Create a new bitmap of the appropriate size and then draw that into our context.

        size_t csw = static_cast<size_t>(ceilf(sourceRect.width()));
        size_t csh = static_cast<size_t>(ceilf(sourceRect.height()));

        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        size_t bytesPerRow = csw * 4;
        void* buffer = fastMalloc(csh * bytesPerRow);

        CGContextRef clippedSourceContext = CGBitmapContextCreate(buffer, csw, csh,
            8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
        CGColorSpaceRelease(colorSpace);
        CGContextTranslateCTM(clippedSourceContext, -sourceRect.x(), -sourceRect.y());
        CGContextDrawImage(clippedSourceContext, CGRectMake(0, 0, iw, ih), platformImage);

        CGImageRef clippedSourceImage = CGBitmapContextCreateImage(clippedSourceContext);
        CGContextRelease(clippedSourceContext);

        CGContextDrawImage(c->platformContext(), destRect, clippedSourceImage);
        CGImageRelease(clippedSourceImage);
        
        fastFree(buffer);
    }

    CGImageRelease(platformImage);
#elif PLATFORM(QT)
    QPixmap px = canvas->createPlatformImage();
    if (px.isNull())
        return;
    willDraw(dstRect);
    QPainter* painter = static_cast<QPainter*>(c->platformContext());
    painter->drawPixmap(dstRect, px, srcRect);
#endif
}
コード例 #18
0
void CanvasRenderingContext2D::stroke()
{
    GraphicsContext* c = drawingContext();
    if (!c)
        return;
    c->beginPath();
    c->addPath(m_path);

    if (!m_path.isEmpty()) {
        // FIXME: This is insufficient, need to use CGContextReplacePathWithStrokedPath to expand to required bounds
        float lineWidth = state().m_lineWidth;
        float inset = lineWidth / 2;
        FloatRect boundingRect = m_path.boundingRect();
        boundingRect.inflate(inset);
        willDraw(boundingRect);
    }
    
    // FIXME: Do this through platform-independent GraphicsContext API.
#if PLATFORM(CG)
    if (state().m_strokeStyle->canvasGradient()) {
        // Shading works on the entire clip region, so convert the current path to a clip.
        c->save();
        CGContextReplacePathWithStrokedPath(c->platformContext());
        CGContextClip(c->platformContext());
        CGContextDrawShading(c->platformContext(), state().m_strokeStyle->canvasGradient()->gradient().platformGradient());        
        c->restore();
    } else {
        if (state().m_strokeStyle->pattern())
            applyStrokePattern();
        CGContextStrokePath(c->platformContext());
    }
#elif PLATFORM(QT)
    QPainterPath* path = m_path.platformPath();
    QPainter* p = static_cast<QPainter*>(c->platformContext());
    if (state().m_strokeStyle->canvasGradient()) {
        p->save();
        p->setBrush(*(state().m_strokeStyle->canvasGradient()->gradient().platformGradient()));
        p->strokePath(*path, p->pen());
        p->restore();
    } else {
        if (state().m_strokeStyle->pattern())
            applyStrokePattern();
        p->strokePath(*path, p->pen());
    }
#elif PLATFORM(CAIRO) && !PLATFORM(BAL)
    cairo_t* cr = c->platformContext();
    cairo_save(cr);
    if (state().m_strokeStyle->canvasGradient()) {
        cairo_set_source(cr, state().m_strokeStyle->canvasGradient()->gradient().platformGradient());
        c->addPath(m_path);
        cairo_stroke(cr);
    } else {
        if (state().m_strokeStyle->pattern())
            applyStrokePattern();
        c->addPath(m_path);
        cairo_stroke(cr);
    }
    cairo_restore(cr);
#elif PLATFORM(BAL)
    //FIXME
    notImplemented();
#endif

#if ENABLE(DASHBOARD_SUPPORT)
    clearPathForDashboardBackwardCompatibilityMode();
#endif
}