diff options
author | Steve Block <steveblock@google.com> | 2010-08-04 11:41:34 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-08-09 12:04:44 +0100 |
commit | db14019a23d96bc8a444b6576a5da8bd1cfbc8b0 (patch) | |
tree | 9f793c5b0f5e1f2aca8247158920e2c4bf962bbf /WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp | |
parent | bf916837aa84f1e4b00e6ed6268516c2acd27545 (diff) | |
download | external_webkit-db14019a23d96bc8a444b6576a5da8bd1cfbc8b0.zip external_webkit-db14019a23d96bc8a444b6576a5da8bd1cfbc8b0.tar.gz external_webkit-db14019a23d96bc8a444b6576a5da8bd1cfbc8b0.tar.bz2 |
Merge WebKit at r64523 : Initial merge by git.
Change-Id: Ibb796c6802e757b1d9b40f58205cfbe4da95fcd4
Diffstat (limited to 'WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp')
-rw-r--r-- | WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp | 126 |
1 files changed, 84 insertions, 42 deletions
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp index 96cd4ee..f3fc943 100644 --- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp +++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp @@ -4,6 +4,7 @@ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> * Copyright (C) 2008 Nuanti Ltd. * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org> + * Copyright (C) 2010 Igalia S.L. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -143,6 +144,35 @@ static inline void copyContextProperties(cairo_t* srcCr, cairo_t* dstCr) cairo_set_fill_rule(dstCr, cairo_get_fill_rule(srcCr)); } +static void appendPathToCairoContext(cairo_t* to, cairo_t* from) +{ + cairo_path_t* cairoPath = cairo_copy_path(from); + cairo_append_path(to, cairoPath); + cairo_path_destroy(cairoPath); +} + +// We apply the pending path built via addPath to the Cairo context +// lazily. This prevents interaction between the path and other routines +// such as fillRect. +static void setPathOnCairoContext(cairo_t* to, cairo_t* from) +{ + cairo_new_path(to); + appendPathToCairoContext(to, from); +} + +static void appendWebCorePathToCairoContext(cairo_t* context, const Path& path) +{ + appendPathToCairoContext(context, path.platformPath()->context()); +} + +static void addConvexPolygonToContext(cairo_t* context, size_t numPoints, const FloatPoint* points) +{ + cairo_move_to(context, points[0].x(), points[0].y()); + for (size_t i = 1; i < numPoints; i++) + cairo_line_to(context, points[i].x(), points[i].y()); + cairo_close_path(context); +} + void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& kernelSize, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur) { #if ENABLE(FILTERS) @@ -201,6 +231,22 @@ static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPriva #endif } +static void fillCurrentCairoPath(GraphicsContext* context, GraphicsContextPrivate* gcp, cairo_t* cairoContext) +{ + cairo_set_fill_rule(cairoContext, context->fillRule() == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); + drawPathShadow(context, gcp, true, false); + + setPlatformFill(context, cairoContext, gcp); + cairo_new_path(cairoContext); +} + +static void strokeCurrentCairoPath(GraphicsContext* context, GraphicsContextPrivate* gcp, cairo_t* cairoContext) +{ + drawPathShadow(context, gcp, false, true); + setPlatformStroke(context, cairoContext, gcp); + cairo_new_path(cairoContext); +} + GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr) : m_common(createGraphicsContextPrivate()) , m_data(new GraphicsContextPlatformPrivate) @@ -380,9 +426,8 @@ void GraphicsContext::drawEllipse(const IntRect& rect) setColor(cr, strokeColor()); cairo_set_line_width(cr, strokeThickness()); cairo_stroke(cr); - } - - cairo_new_path(cr); + } else + cairo_new_path(cr); } void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) @@ -483,10 +528,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points cairo_save(cr); cairo_set_antialias(cr, shouldAntialias ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE); - cairo_move_to(cr, points[0].x(), points[0].y()); - for (size_t i = 1; i < npoints; i++) - cairo_line_to(cr, points[i].x(), points[i].y()); - cairo_close_path(cr); + addConvexPolygonToContext(cr, npoints, points); if (fillColor().alpha()) { setColor(cr, fillColor()); @@ -498,9 +540,9 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points setColor(cr, strokeColor()); cairo_set_line_width(cr, strokeThickness()); cairo_stroke(cr); - } + } else + cairo_new_path(cr); - cairo_new_path(cr); cairo_restore(cr); } @@ -511,8 +553,20 @@ void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* poin if (numPoints <= 1) return; - - // FIXME: IMPLEMENT! + + cairo_t* cr = m_data->cr; + + cairo_new_path(cr); + cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr); + cairo_antialias_t savedAntialiasRule = cairo_get_antialias(cr); + + cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); + cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING); + addConvexPolygonToContext(cr, numPoints, points); + cairo_clip(cr); + + cairo_set_antialias(cr, savedAntialiasRule); + cairo_set_fill_rule(cr, savedFillRule); } void GraphicsContext::fillPath() @@ -522,11 +576,8 @@ void GraphicsContext::fillPath() cairo_t* cr = m_data->cr; - cairo_set_fill_rule(cr, fillRule() == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); - drawPathShadow(this, m_common, true, false); - - setPlatformFill(this, cr, m_common); - cairo_new_path(cr); + setPathOnCairoContext(cr, m_data->m_pendingPath.context()); + fillCurrentCairoPath(this, m_common, cr); } void GraphicsContext::strokePath() @@ -535,11 +586,8 @@ void GraphicsContext::strokePath() return; cairo_t* cr = m_data->cr; - drawPathShadow(this, m_common, false, true); - - setPlatformStroke(this, cr, m_common); - cairo_new_path(cr); - + setPathOnCairoContext(cr, m_data->m_pendingPath.context()); + strokeCurrentCairoPath(this, m_common, cr); } void GraphicsContext::drawPath() @@ -549,6 +597,8 @@ void GraphicsContext::drawPath() cairo_t* cr = m_data->cr; + setPathOnCairoContext(cr, m_data->m_pendingPath.context()); + cairo_set_fill_rule(cr, fillRule() == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); drawPathShadow(this, m_common, true, true); @@ -565,7 +615,7 @@ void GraphicsContext::fillRect(const FloatRect& rect) cairo_t* cr = m_data->cr; cairo_save(cr); cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height()); - fillPath(); + fillCurrentCairoPath(this, m_common, cr); cairo_restore(cr); } @@ -673,7 +723,7 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int #else int radius = (width - 1) / 2; for (unsigned i = 0; i < rectCount; i++) - addPath(Path::createRoundedRectangle(rects[i], FloatSize(radius, radius))); + appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(rects[i], FloatSize(radius, radius))); // Force the alpha to 50%. This matches what the Mac does with outline rings. Color ringColor(color.red(), color.green(), color.blue(), 127); @@ -700,14 +750,8 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool pr if (paintingDisabled()) return; - // This is a workaround for http://bugs.webkit.org/show_bug.cgi?id=15659 - StrokeStyle savedStrokeStyle = strokeStyle(); - setStrokeStyle(SolidStroke); - IntPoint endPoint = origin + IntSize(width, 0); drawLine(origin, endPoint); - - setStrokeStyle(savedStrokeStyle); } #if !PLATFORM(GTK) @@ -846,6 +890,7 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness if (paintingDisabled()) return; + cairo_t* cr = m_data->cr; clip(rect); Path p; @@ -855,9 +900,8 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness // Add inner ellipse r.inflate(-thickness); p.addEllipse(r); - addPath(p); + appendWebCorePathToCairoContext(cr, p); - cairo_t* cr = m_data->cr; cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_clip(cr); @@ -968,7 +1012,7 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float width) cairo_save(cr); cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height()); cairo_set_line_width(cr, width); - strokePath(); + strokeCurrentCairoPath(this, m_common, cr); cairo_restore(cr); } @@ -1085,8 +1129,7 @@ void GraphicsContext::beginPath() if (paintingDisabled()) return; - cairo_t* cr = m_data->cr; - cairo_new_path(cr); + cairo_new_path(m_data->m_pendingPath.context()); } void GraphicsContext::addPath(const Path& path) @@ -1094,10 +1137,10 @@ void GraphicsContext::addPath(const Path& path) if (paintingDisabled()) return; - cairo_t* cr = m_data->cr; - cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr); - cairo_append_path(cr, p); - cairo_path_destroy(p); + cairo_matrix_t currentMatrix; + cairo_get_matrix(m_data->cr, ¤tMatrix); + cairo_set_matrix(m_data->m_pendingPath.context(), ¤tMatrix); + appendWebCorePathToCairoContext(m_data->m_pendingPath.context(), path); } void GraphicsContext::clip(const Path& path) @@ -1106,7 +1149,7 @@ void GraphicsContext::clip(const Path& path) return; cairo_t* cr = m_data->cr; - cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr); + cairo_path_t* p = cairo_copy_path(path.platformPath()->context()); cairo_append_path(cr, p); cairo_path_destroy(p); cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr); @@ -1130,7 +1173,7 @@ void GraphicsContext::clipOut(const Path& path) double x1, y1, x2, y2; cairo_clip_extents(cr, &x1, &y1, &x2, &y2); cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1); - addPath(path); + appendWebCorePathToCairoContext(cr, path); cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); @@ -1189,8 +1232,7 @@ void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft, cairo_t* cr = m_data->cr; cairo_save(cr); - beginPath(); - addPath(Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight)); + appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight)); setColor(cr, color); drawPathShadow(this, m_common, true, false); cairo_fill(cr); |