diff options
author | Shimeng (Simon) Wang <swang@google.com> | 2010-12-07 17:22:45 -0800 |
---|---|---|
committer | Shimeng (Simon) Wang <swang@google.com> | 2010-12-22 14:15:40 -0800 |
commit | 4576aa36e9a9671459299c7963ac95aa94beaea9 (patch) | |
tree | 3863574e050f168c0126ecb47c83319fab0972d8 /WebCore/platform/graphics/qt/GraphicsContextQt.cpp | |
parent | 55323ac613cc31553107b68603cb627264d22bb0 (diff) | |
download | external_webkit-4576aa36e9a9671459299c7963ac95aa94beaea9.zip external_webkit-4576aa36e9a9671459299c7963ac95aa94beaea9.tar.gz external_webkit-4576aa36e9a9671459299c7963ac95aa94beaea9.tar.bz2 |
Merge WebKit at r73109: Initial merge by git.
Change-Id: I61f1a66d9642e3d8405d3ac6ccab2a53421c75d8
Diffstat (limited to 'WebCore/platform/graphics/qt/GraphicsContextQt.cpp')
-rw-r--r-- | WebCore/platform/graphics/qt/GraphicsContextQt.cpp | 258 |
1 files changed, 128 insertions, 130 deletions
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index 06e1e1c..a840525 100644 --- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -51,7 +51,6 @@ #include "NotImplemented.h" #include "Path.h" #include "Pattern.h" -#include "Pen.h" #include "TransparencyLayer.h" #include <QBrush> @@ -104,6 +103,8 @@ QPainter::CompositionMode GraphicsContext::toQtCompositionMode(CompositeOperator return QPainter::CompositionMode_SourceOver; case CompositePlusLighter: return QPainter::CompositionMode_Plus; + default: + ASSERT_NOT_REACHED(); } return QPainter::CompositionMode_SourceOver; @@ -118,6 +119,8 @@ static inline Qt::PenCapStyle toQtLineCap(LineCap lc) return Qt::RoundCap; case SquareCap: return Qt::SquareCap; + default: + ASSERT_NOT_REACHED(); } return Qt::FlatCap; @@ -132,9 +135,11 @@ static inline Qt::PenJoinStyle toQtLineJoin(LineJoin lj) return Qt::RoundJoin; case BevelJoin: return Qt::BevelJoin; + default: + ASSERT_NOT_REACHED(); } - return Qt::MiterJoin; + return Qt::SvgMiterJoin; } static Qt::PenStyle toQPenStyle(StrokeStyle style) @@ -152,8 +157,9 @@ static Qt::PenStyle toQPenStyle(StrokeStyle style) case DashedStroke: return Qt::DashLine; break; + default: + ASSERT_NOT_REACHED(); } - qWarning("couldn't recognize the pen style"); return Qt::NoPen; } @@ -164,8 +170,9 @@ static inline Qt::FillRule toQtFillRule(WindRule rule) return Qt::OddEvenFill; case RULE_NONZERO: return Qt::WindingFill; + default: + ASSERT_NOT_REACHED(); } - qDebug("Qt: unrecognized wind rule!"); return Qt::OddEvenFill; } @@ -193,9 +200,6 @@ public: InterpolationQuality imageInterpolationQuality; - // Only used by SVG for now. - QPainterPath currentPath; - ContextShadow shadow; QStack<ContextShadow> shadowStack; @@ -204,13 +208,6 @@ public: return shadow.m_type != ContextShadow::NoShadow; } - inline void clearCurrentPath() - { - if (!currentPath.elementCount()) - return; - currentPath = QPainterPath(); - } - QRectF clipBoundingRect() const { #if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0) @@ -250,8 +247,8 @@ GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate() if (!platformContextIsOwned) return; - painter->end(); QPaintDevice* device = painter->device(); + painter->end(); delete painter; delete device; } @@ -311,11 +308,6 @@ void GraphicsContext::restorePlatformState() m_data->p()->restore(); - if (!m_data->currentPath.isEmpty() && m_common->state.pathTransform.isInvertible()) { - QTransform matrix = m_common->state.pathTransform; - m_data->currentPath = m_data->currentPath * matrix; - } - if (m_data->shadowStack.isEmpty()) m_data->shadow = ContextShadow(); else @@ -444,32 +436,6 @@ void GraphicsContext::drawEllipse(const IntRect& rect) m_data->p()->drawEllipse(rect); } -void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) -{ - if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f) - return; - - QPainter* p = m_data->p(); - const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); - p->setRenderHint(QPainter::Antialiasing, true); - - startAngle *= 16; - angleSpan *= 16; - - if (m_data->hasShadow()) { - p->save(); - p->translate(m_data->shadow.offset()); - QPen pen(p->pen()); - pen.setColor(m_data->shadow.m_color); - p->setPen(pen); - p->drawArc(rect, startAngle, angleSpan); - p->restore(); - } - p->drawArc(rect, startAngle, angleSpan); - - p->setRenderHint(QPainter::Antialiasing, antiAlias); -} - void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias) { if (paintingDisabled()) @@ -484,8 +450,10 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points polygon[i] = points[i]; QPainter* p = m_data->p(); - p->save(); + + const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); p->setRenderHint(QPainter::Antialiasing, shouldAntialias); + if (m_data->hasShadow()) { p->save(); p->translate(m_data->shadow.offset()); @@ -500,7 +468,8 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points p->restore(); } p->drawConvexPolygon(polygon); - p->restore(); + + p->setRenderHint(QPainter::Antialiasing, antiAlias); } void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialiased) @@ -529,64 +498,114 @@ void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* poin p->setRenderHint(QPainter::Antialiasing, painterWasAntialiased); } -void GraphicsContext::fillPath() +void GraphicsContext::fillPath(const Path& path) { if (paintingDisabled()) return; QPainter* p = m_data->p(); - QPainterPath& path = m_data->currentPath; // Avoid detaching the QPainterPath - path.setFillRule(toQtFillRule(fillRule())); + QPainterPath platformPath = path.platformPath(); + platformPath.setFillRule(toQtFillRule(fillRule())); if (m_data->hasShadow()) { - p->translate(m_data->shadow.offset()); - p->fillPath(path, QColor(m_data->shadow.m_color)); - p->translate(-m_data->shadow.offset()); + ContextShadow* shadow = contextShadow(); + if (shadow->m_type != ContextShadow::BlurShadow + && !m_common->state.fillPattern && !m_common->state.fillGradient) + { + QPointF offset = shadow->offset(); + const QTransform& transform = p->transform(); + if (transform.isScaling()) { + // If scaling is required, find the new coord for shadow origin, + // so that the relative offset to its shape is kept. + QPointF translatedOffset(offset.x() / transform.m11(), + offset.y() / transform.m22()); + platformPath.translate(translatedOffset); + p->fillPath(platformPath, QColor(shadow->m_color)); + platformPath.translate(-translatedOffset); + } else { + p->translate(offset); + p->fillPath(platformPath, QColor(shadow->m_color)); + p->translate(-offset); + } + } else { + QPainter* shadowPainter = shadow->beginShadowLayer(p, platformPath.controlPointRect()); + if (shadowPainter) { + shadowPainter->setCompositionMode(QPainter::CompositionMode_Source); + shadowPainter->fillPath(platformPath, QColor(m_data->shadow.m_color)); + shadow->endShadowLayer(p); + } + } + } if (m_common->state.fillPattern) { AffineTransform affine; - p->fillPath(path, QBrush(m_common->state.fillPattern->createPlatformPattern(affine))); + p->fillPath(platformPath, QBrush(m_common->state.fillPattern->createPlatformPattern(affine))); } else if (m_common->state.fillGradient) { QBrush brush(*m_common->state.fillGradient->platformGradient()); brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform()); - p->fillPath(path, brush); + p->fillPath(platformPath, brush); } else - p->fillPath(path, p->brush()); - - m_data->clearCurrentPath(); + p->fillPath(platformPath, p->brush()); } -void GraphicsContext::strokePath() +void GraphicsContext::strokePath(const Path& path) { if (paintingDisabled()) return; QPainter* p = m_data->p(); QPen pen(p->pen()); - QPainterPath& path = m_data->currentPath; // Avoid detaching the QPainterPath - path.setFillRule(toQtFillRule(fillRule())); + QPainterPath platformPath = path.platformPath(); + platformPath.setFillRule(toQtFillRule(fillRule())); if (m_data->hasShadow()) { - p->translate(m_data->shadow.offset()); - QPen shadowPen(pen); - shadowPen.setColor(m_data->shadow.m_color); - p->strokePath(path, shadowPen); - p->translate(-m_data->shadow.offset()); + ContextShadow* shadow = contextShadow(); + + if (shadow->m_type != ContextShadow::BlurShadow + && !m_common->state.strokePattern && !m_common->state.strokeGradient) + { + QPen shadowPen(pen); + shadowPen.setColor(m_data->shadow.m_color); + QPointF offset = shadow->offset(); + const QTransform& transform = p->transform(); + if (transform.isScaling()) { + // If scaling is required, find the new coord for shadow origin, + // so that the relative offset to its shape is kept. + QPointF translatedOffset(offset.x() / transform.m11(), + offset.y() / transform.m22()); + platformPath.translate(translatedOffset); + p->strokePath(platformPath, shadowPen); + platformPath.translate(-translatedOffset); + } else { + p->translate(offset); + p->strokePath(platformPath, shadowPen); + p->translate(-offset); + } + } else { + FloatRect boundingRect = platformPath.controlPointRect(); + boundingRect.inflate(pen.miterLimit() + pen.widthF()); + QPainter* shadowPainter = shadow->beginShadowLayer(p, boundingRect); + if (shadowPainter) { + shadowPainter->setOpacity(static_cast<qreal>(m_data->shadow.m_color.alpha()) / 255); + shadowPainter->strokePath(platformPath, pen); + shadow->endShadowLayer(p); + } + } } + if (m_common->state.strokePattern) { AffineTransform affine; pen.setBrush(QBrush(m_common->state.strokePattern->createPlatformPattern(affine))); p->setPen(pen); - p->strokePath(path, pen); + p->strokePath(platformPath, pen); } else if (m_common->state.strokeGradient) { QBrush brush(*m_common->state.strokeGradient->platformGradient()); brush.setTransform(m_common->state.strokeGradient->gradientSpaceTransform()); pen.setBrush(brush); p->setPen(pen); - p->strokePath(path, pen); + p->strokePath(platformPath, pen); } else - p->strokePath(path, pen); - m_data->clearCurrentPath(); + p->strokePath(platformPath, pen); } static inline void drawRepeatPattern(QPainter* p, QPixmap* image, const FloatRect& rect, const bool repeatX, const bool repeatY) @@ -693,6 +712,7 @@ void GraphicsContext::fillRect(const FloatRect& rect) if (shadow->m_type == ContextShadow::BlurShadow) { QPainter* shadowPainter = shadow->beginShadowLayer(p, normalizedRect); if (shadowPainter) { + shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255); shadowPainter->fillRect(normalizedRect, p->brush()); shadow->endShadowLayer(p); } @@ -701,9 +721,16 @@ void GraphicsContext::fillRect(const FloatRect& rect) // without using the shadow layer at all. QColor shadowColor = shadow->m_color; shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF()); - p->fillRect(normalizedRect.translated(shadow->offset()), shadowColor); + const QTransform& transform = p->transform(); + if (transform.isScaling()) { + p->fillRect(normalizedRect.translated(static_cast<qreal>(shadow->offset().x()) / transform.m11(), + static_cast<qreal>(shadow->offset().y() / transform.m22())), + shadowColor); + } else + p->fillRect(normalizedRect.translated(shadow->offset()), shadowColor); } } + p->fillRect(normalizedRect, p->brush()); } } @@ -765,30 +792,11 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef p->fillPath(path.platformPath(), QColor(color)); } -void GraphicsContext::beginPath() -{ - m_data->clearCurrentPath(); -} - -void GraphicsContext::addPath(const Path& path) -{ - if (!m_data->currentPath.elementCount()) { - m_data->currentPath = path.platformPath(); - return; - } - m_data->currentPath.addPath(path.platformPath()); -} - bool GraphicsContext::inTransparencyLayer() const { return m_data->layerCount; } -PlatformPath* GraphicsContext::currentPath() -{ - return &m_data->currentPath; -} - ContextShadow* GraphicsContext::contextShadow() { return &m_data->shadow; @@ -802,26 +810,45 @@ void GraphicsContext::clip(const FloatRect& rect) m_data->p()->setClipRect(rect, Qt::IntersectClip); } -void GraphicsContext::clipPath(WindRule clipRule) +void GraphicsContext::clipPath(const Path& path, WindRule clipRule) { if (paintingDisabled()) return; QPainter* p = m_data->p(); - QPainterPath newPath = m_data->currentPath; - newPath.setFillRule(clipRule == RULE_EVENODD ? Qt::OddEvenFill : Qt::WindingFill); - p->setClipPath(newPath, Qt::IntersectClip); + QPainterPath platformPath = path.platformPath(); + platformPath.setFillRule(clipRule == RULE_EVENODD ? Qt::OddEvenFill : Qt::WindingFill); + p->setClipPath(platformPath, Qt::IntersectClip); } -void GraphicsContext::drawFocusRing(const Vector<Path>& paths, int width, int offset, const Color& color) +void GraphicsContext::drawFocusRing(const Path& path, int width, int offset, const Color& color) { - // FIXME: implement + // FIXME: Use 'width' and 'offset' for something? http://webkit.org/b/49909 + + if (paintingDisabled() || !color.isValid()) + return; + + QPainter* p = m_data->p(); + const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); + p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); + + const QBrush oldBrush = p->brush(); + + QPen nPen = p->pen(); + nPen.setColor(color); + p->setBrush(Qt::NoBrush); + nPen.setStyle(Qt::DotLine); + + p->strokePath(path.platformPath(), nPen); + p->setBrush(oldBrush); + + p->setRenderHint(QPainter::Antialiasing, antiAlias); } /** - * Focus ring handling is not handled here. Qt style in + * Focus ring handling for form controls is not handled here. Qt style in * RenderTheme handles drawing focus on widgets which - * need it. + * need it. It is still handled here for links. */ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int /* width */, int /* offset */, const Color& color) { @@ -1020,12 +1047,10 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float width) if (paintingDisabled()) return; - QPainterPath path; + Path path; path.addRect(rect); setStrokeThickness(width); - m_data->currentPath = path; - - strokePath(); + strokePath(path); } void GraphicsContext::setLineCap(LineCap lc) @@ -1145,12 +1170,6 @@ void GraphicsContext::translate(float x, float y) return; m_data->p()->translate(x, y); - - if (!m_data->currentPath.isEmpty()) { - QTransform matrix; - m_data->currentPath = m_data->currentPath * matrix.translate(-x, -y); - m_common->state.pathTransform.translate(x, y); - } } void GraphicsContext::rotate(float radians) @@ -1159,12 +1178,6 @@ void GraphicsContext::rotate(float radians) return; m_data->p()->rotate(180 / M_PI*radians); - - if (!m_data->currentPath.isEmpty()) { - QTransform matrix; - m_data->currentPath = m_data->currentPath * matrix.rotate(-180 / M_PI*radians); - m_common->state.pathTransform.rotate(radians); - } } void GraphicsContext::scale(const FloatSize& s) @@ -1173,12 +1186,6 @@ void GraphicsContext::scale(const FloatSize& s) return; m_data->p()->scale(s.width(), s.height()); - - if (!m_data->currentPath.isEmpty()) { - QTransform matrix; - m_data->currentPath = m_data->currentPath * matrix.scale(1 / s.width(), 1 / s.height()); - m_common->state.pathTransform.scaleNonUniform(s.width(), s.height()); - } } void GraphicsContext::clipOut(const IntRect& rect) @@ -1235,15 +1242,6 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) return; m_data->p()->setWorldTransform(transform, true); - - // Transformations to the context shouldn't transform the currentPath. - // We have to undo every change made to the context from the currentPath - // to avoid wrong drawings. - if (!m_data->currentPath.isEmpty() && transform.isInvertible()) { - QTransform matrix = transform.inverse(); - m_data->currentPath = m_data->currentPath * matrix; - m_common->state.pathTransform.multiply(transform.toTransformationMatrix()); - } } void GraphicsContext::setURLForRect(const KURL&, const IntRect&) |