summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
diff options
context:
space:
mode:
authorShimeng (Simon) Wang <swang@google.com>2010-12-07 17:22:45 -0800
committerShimeng (Simon) Wang <swang@google.com>2010-12-22 14:15:40 -0800
commit4576aa36e9a9671459299c7963ac95aa94beaea9 (patch)
tree3863574e050f168c0126ecb47c83319fab0972d8 /WebCore/platform/graphics/qt/GraphicsContextQt.cpp
parent55323ac613cc31553107b68603cb627264d22bb0 (diff)
downloadexternal_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.cpp258
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&)