diff options
Diffstat (limited to 'WebCore/platform/graphics/qt')
23 files changed, 1514 insertions, 249 deletions
diff --git a/WebCore/platform/graphics/qt/AffineTransformQt.cpp b/WebCore/platform/graphics/qt/AffineTransformQt.cpp index 8bd5c87..2793043 100644 --- a/WebCore/platform/graphics/qt/AffineTransformQt.cpp +++ b/WebCore/platform/graphics/qt/AffineTransformQt.cpp @@ -41,7 +41,7 @@ AffineTransform::AffineTransform(double a, double b, double c, double d, double { } -AffineTransform::AffineTransform(const QMatrix& matrix) +AffineTransform::AffineTransform(const PlatformAffineTransform& matrix) : m_transform(matrix) { } diff --git a/WebCore/platform/graphics/qt/FontCacheQt.cpp b/WebCore/platform/graphics/qt/FontCacheQt.cpp index 8fb3fba..be31d96 100644 --- a/WebCore/platform/graphics/qt/FontCacheQt.cpp +++ b/WebCore/platform/graphics/qt/FontCacheQt.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Trolltech ASA + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -26,14 +26,8 @@ namespace WebCore { -bool FontCache::fontExists(const FontDescription &desc, const AtomicString& family) +void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks) { - // try to construct a QFont inside WebCore::Font to see if we know about this font - FontDescription fnt(desc); - FontFamily fam; - fam.setFamily(family); - fnt.setFamily(fam); - return Font(fnt, /*letterSpacing*/0, /*wordSpacing*/0).font().exactMatch(); } FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription&, const AtomicString& family, bool checkingAlternateName) @@ -51,4 +45,12 @@ FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription&) return 0; } +void FontCache::addClient(FontSelector*) +{ } + +void FontCache::removeClient(FontSelector*) +{ +} + +} // namespace WebCore diff --git a/WebCore/platform/graphics/qt/FontCustomPlatformData.cpp b/WebCore/platform/graphics/qt/FontCustomPlatformData.cpp index 67193d4..8fc3ea0 100644 --- a/WebCore/platform/graphics/qt/FontCustomPlatformData.cpp +++ b/WebCore/platform/graphics/qt/FontCustomPlatformData.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Trolltech ASA + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -33,7 +33,7 @@ FontCustomPlatformData::~FontCustomPlatformData() QFontDatabase::removeApplicationFont(handle); } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode) { FontPlatformData result; result.handle = handle; diff --git a/WebCore/platform/graphics/qt/FontCustomPlatformData.h b/WebCore/platform/graphics/qt/FontCustomPlatformData.h index b7a2b15..da5159d 100644 --- a/WebCore/platform/graphics/qt/FontCustomPlatformData.h +++ b/WebCore/platform/graphics/qt/FontCustomPlatformData.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Trolltech ASA + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -22,6 +22,7 @@ #ifndef FontCustomPlatformData_h_ #define FontCustomPlatformData_h_ +#include "FontRenderingMode.h" #include <wtf/Noncopyable.h> namespace WebCore { @@ -34,7 +35,7 @@ struct FontCustomPlatformData : Noncopyable { int handle; // for use with QFontDatabase::addApplicationFont/removeApplicationFont - FontPlatformData fontPlatformData(int size, bool bold, bool italic); + FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode); }; FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer); diff --git a/WebCore/platform/graphics/qt/FontPlatformData.h b/WebCore/platform/graphics/qt/FontPlatformData.h index 7daf6ed..e4363be 100644 --- a/WebCore/platform/graphics/qt/FontPlatformData.h +++ b/WebCore/platform/graphics/qt/FontPlatformData.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Trolltech ASA + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/WebCore/platform/graphics/qt/FontQt.cpp b/WebCore/platform/graphics/qt/FontQt.cpp index 29b63bf..e2ef605 100644 --- a/WebCore/platform/graphics/qt/FontQt.cpp +++ b/WebCore/platform/graphics/qt/FontQt.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Trolltech ASA + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -15,10 +15,8 @@ along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - This class provides all functionality needed for loading images, style sheets and html - pages from the web. It has a memory cache for these objects. */ + #include "config.h" #include "Font.h" #include "FontDescription.h" @@ -64,12 +62,12 @@ Font::Font(const FontDescription& description, short letterSpacing, short wordSp m_font.setFamily(familyName); m_font.setPixelSize(qRound(description.computedSize())); m_font.setItalic(description.italic()); - if (description.bold()) { - // Qt's Bold is 75, Webkit is 63. + // FIXME: Map all FontWeight values to QFont weights. + if (description.weight() >= FontWeight600) m_font.setWeight(QFont::Bold); - } else { - m_font.setWeight(description.weight()); - } + else + m_font.setWeight(QFont::Normal); + bool smallCaps = description.smallCaps(); m_font.setCapitalization(smallCaps ? QFont::SmallCaps : QFont::MixedCase); @@ -133,6 +131,12 @@ void Font::drawText(GraphicsContext* ctx, const TextRun& run, const FloatPoint& QString string = qstring(run); + // text shadow + IntSize shadowSize; + int shadowBlur; + Color shadowColor; + bool hasShadow = ctx->textDrawingMode() == cTextFill && ctx->getShadow(shadowSize, shadowBlur, shadowColor); + if (from > 0 || to < run.length()) { QTextLayout layout(string, m_font); QTextLine line = setupLayout(&layout, run); @@ -145,9 +149,31 @@ void Font::drawText(GraphicsContext* ctx, const TextRun& run, const FloatPoint& int ascent = fm.ascent(); QRectF clip(point.x() + x1, point.y() - ascent, x2 - x1, fm.height()); + if (hasShadow) { + // TODO: when blur support is added, the clip will need to account + // for the blur radius + qreal dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0; + if (shadowSize.width() > 0) + dx2 = shadowSize.width(); + else + dx1 = -shadowSize.width(); + if (shadowSize.height() > 0) + dy2 = shadowSize.height(); + else + dy1 = -shadowSize.height(); + // expand the clip rect to include the text shadow as well + clip.adjust(dx1, dx2, dy1, dy2); + } p->save(); p->setClipRect(clip.toRect()); QPointF pt(point.x(), point.y() - ascent); + if (hasShadow) { + p->save(); + p->setPen(QColor(shadowColor)); + p->translate(shadowSize.width(), shadowSize.height()); + line.draw(p, pt); + p->restore(); + } line.draw(p, pt); p->restore(); return; @@ -157,6 +183,14 @@ void Font::drawText(GraphicsContext* ctx, const TextRun& run, const FloatPoint& QPointF pt(point.x(), point.y()); int flags = run.rtl() ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight; + if (hasShadow) { + // TODO: text shadow blur support + p->save(); + p->setPen(QColor(shadowColor)); + p->translate(shadowSize.width(), shadowSize.height()); + p->drawText(pt, string, flags, run.padding()); + p->restore(); + } p->drawText(pt, string, flags, run.padding()); } @@ -165,7 +199,9 @@ int Font::width(const TextRun& run) const if (!run.length()) return 0; QString string = qstring(run); - int w = QFontMetrics(m_font).width(string); + QTextLayout layout(string, m_font); + QTextLine line = setupLayout(&layout, run); + int w = int(line.naturalTextWidth()); // WebKit expects us to ignore word spacing on the first character (as opposed to what Qt does) if (treatAsSpace(run[0])) w -= m_wordSpacing; @@ -178,6 +214,13 @@ float Font::floatWidth(const TextRun& run) const return width(run); } +float Font::floatWidth(const TextRun& run, int /*extraCharsAvailable*/, int& charsConsumed, String& glyphName) const +{ + charsConsumed = run.length(); + glyphName = ""; + return width(run); +} + int Font::offsetForPosition(const TextRun& run, int position, bool /*includePartialGlyphs*/) const { QString string = qstring(run); @@ -272,12 +315,12 @@ Font::Font(const FontDescription& description, short letterSpacing, short wordSp m_font.setFamily(familyName); m_font.setPixelSize(qRound(description.computedSize())); m_font.setItalic(description.italic()); - if (description.bold()) { - // Qt's Bold is 75, Webkit is 63. + // FIXME: Map all FontWeight values to QFont weights. + if (description.weight() >= FontWeight600) m_font.setWeight(QFont::Bold); - } else { - m_font.setWeight(description.weight()); - } + else + m_font.setWeight(QFont::Normal); + QFontMetrics metrics = QFontMetrics(m_font); m_spaceWidth = metrics.width(QLatin1Char(' ')); m_scFont = m_font; @@ -469,6 +512,13 @@ float Font::floatWidth(const TextRun& run) const return width(run); } +float Font::floatWidth(const TextRun& run, int /*extraCharsAvailable*/, int& charsConsumed, String& glyphName) const +{ + charsConsumed = run.length(); + glyphName = ""; + return width(run); +} + int Font::offsetForPosition(const TextRun& run, int position, bool includePartialGlyphs) const { Vector<TextRunComponent, 1024> components; @@ -633,6 +683,11 @@ int Font::lineSpacing() const return QFontMetrics(m_font).lineSpacing(); } +int Font::lineGap() const +{ + return QFontMetrics(m_font).leading(); +} + float Font::xHeight() const { return QFontMetrics(m_font).xHeight(); diff --git a/WebCore/platform/graphics/qt/GlyphPageTreeNodeQt.cpp b/WebCore/platform/graphics/qt/GlyphPageTreeNodeQt.cpp index 220807e..d32cc63 100644 --- a/WebCore/platform/graphics/qt/GlyphPageTreeNodeQt.cpp +++ b/WebCore/platform/graphics/qt/GlyphPageTreeNodeQt.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Trolltech ASA + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/WebCore/platform/graphics/qt/GradientQt.cpp b/WebCore/platform/graphics/qt/GradientQt.cpp new file mode 100644 index 0000000..f414efa --- /dev/null +++ b/WebCore/platform/graphics/qt/GradientQt.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2006, 2007, 2008 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Gradient.h" + +#include "CSSParser.h" +#include "NotImplemented.h" + +#include <QGradient> + +namespace WebCore { + +void Gradient::platformDestroy() +{ + delete m_gradient; + m_gradient = 0; +} + +QGradient* Gradient::platformGradient() +{ + if (m_gradient) + return m_gradient; + + if (m_radial) + m_gradient = new QRadialGradient(m_p1.x(), m_p1.y(), m_r1, m_p0.x(), m_p0.y()); + else + m_gradient = new QLinearGradient(m_p0.x(), m_p0.y(), m_p1.x(), m_p1.y()); + + QColor stopColor; + Vector<ColorStop>::iterator stopIterator = m_stops.begin(); + qreal lastStop; + const qreal lastStopDiff = 0.0000001; + while (stopIterator != m_stops.end()) { + stopColor.setRgbF(stopIterator->red, stopIterator->green, stopIterator->blue, stopIterator->alpha); + if (qFuzzyCompare(lastStop, qreal(stopIterator->stop))) + lastStop = stopIterator->stop + lastStopDiff; + else + lastStop = stopIterator->stop; + if (m_radial && m_r0) + lastStop = m_r0 / m_r1 + lastStop * (1.0f - m_r0 / m_r1); + m_gradient->setColorAt(lastStop, stopColor); + ++stopIterator; + } + + return m_gradient; +} + +void Gradient::fill(GraphicsContext* context, const FloatRect& rect) +{ + notImplemented(); +} + +} //namespace diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index cf097c8..600d77c 100644 --- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -5,6 +5,9 @@ * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org> * Copyright (C) 2006 Allan Sandfeld Jensen <sandfeld@kde.org> * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2008 Dirk Schulze <vbs85@gmx.de> * * All rights reserved. * @@ -32,20 +35,32 @@ #include "config.h" +#ifdef Q_WS_WIN +#include <windows.h> +#endif + #include "AffineTransform.h" -#include "Path.h" #include "Color.h" -#include "GraphicsContext.h" +#include "FloatConversion.h" #include "Font.h" +#include "GraphicsContext.h" +#include "GraphicsContextPrivate.h" +#include "ImageBuffer.h" +#include "Path.h" +#include "Pattern.h" #include "Pen.h" #include "NotImplemented.h" -#include <QStack> +#include <QDebug> +#include <QGradient> #include <QPainter> -#include <QPolygonF> -#include <QPainterPath> #include <QPaintDevice> -#include <QDebug> +#include <QPaintEngine> +#include <QPainterPath> +#include <QPixmap> +#include <QPolygonF> +#include <QStack> +#include <QVector> #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -137,6 +152,22 @@ static Qt::PenStyle toQPenStyle(StrokeStyle style) return Qt::NoPen; } +static inline QGradient applySpreadMethod(QGradient gradient, GradientSpreadMethod spreadMethod) +{ + switch (spreadMethod) { + case SpreadMethodPad: + gradient.setSpread(QGradient::PadSpread); + break; + case SpreadMethodReflect: + gradient.setSpread(QGradient::ReflectSpread); + break; + case SpreadMethodRepeat: + gradient.setSpread(QGradient::RepeatSpread); + break; + } + return gradient; +} + struct TransparencyLayer { TransparencyLayer(const QPainter* p, const QRect &rect) @@ -145,13 +176,15 @@ struct TransparencyLayer offset = rect.topLeft(); pixmap.fill(Qt::transparent); painter.begin(&pixmap); + painter.setRenderHint(QPainter::Antialiasing, p->testRenderHint(QPainter::Antialiasing)); painter.translate(-offset); painter.setPen(p->pen()); painter.setBrush(p->brush()); painter.setTransform(p->transform(), true); painter.setOpacity(p->opacity()); painter.setFont(p->font()); - painter.setCompositionMode(p->compositionMode()); + if (painter.paintEngine()->hasFeature(QPaintEngine::PorterDuff)) + painter.setCompositionMode(p->compositionMode()); painter.setClipPath(p->clipPath()); } @@ -168,24 +201,6 @@ private: TransparencyLayer & operator=(const TransparencyLayer &) { return *this; } }; -struct TextShadow -{ - TextShadow() - : x(0) - , y(0) - , blur(0) - { - } - - bool isNull() { return !x && !y && !blur; } - - int x; - int y; - int blur; - - Color color; -}; - class GraphicsContextPlatformPrivate { public: @@ -203,12 +218,12 @@ public: return &layers.top()->painter; } - QPaintDevice* device; + bool antiAliasingForRectsAndLines; QStack<TransparencyLayer *> layers; QPainter* redirect; - TextShadow shadow; + QBrush solidColor; // Only used by SVG for now. QPainterPath currentPath; @@ -221,12 +236,18 @@ private: GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(QPainter* p) { painter = p; - device = painter ? painter->device() : 0; redirect = 0; - // FIXME: Maybe only enable in SVG mode? - if (painter) - painter->setRenderHint(QPainter::Antialiasing); + solidColor = QBrush(Qt::black); + + if (painter) { + // use the default the QPainter was constructed with + antiAliasingForRectsAndLines = painter->testRenderHint(QPainter::Antialiasing); + // FIXME: Maybe only enable in SVG mode? + painter->setRenderHint(QPainter::Antialiasing, true); + } else { + antiAliasingForRectsAndLines = false; + } } GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate() @@ -386,7 +407,13 @@ void GraphicsContext::drawRect(const IntRect& rect) if (paintingDisabled()) return; - m_data->p()->drawRect(rect); + QPainter *p = m_data->p(); + const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); + p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); + + p->drawRect(rect); + + p->setRenderHint(QPainter::Antialiasing, antiAlias); } // FIXME: Now that this is refactored, it should be shared by all contexts. @@ -429,8 +456,25 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) FloatPoint p1 = point1; FloatPoint p2 = point2; + QPainter *p = m_data->p(); + const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); + p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); adjustLineToPixelBoundaries(p1, p2, strokeThickness(), strokeStyle()); - m_data->p()->drawLine(p1, p2); + + IntSize shadowSize; + int shadowBlur; + Color shadowColor; + if (textDrawingMode() == cTextFill && getShadow(shadowSize, shadowBlur, shadowColor)) { + p->save(); + p->translate(shadowSize.width(), shadowSize.height()); + p->setPen(QColor(shadowColor)); + p->drawLine(p1, p2); + p->restore(); + } + + p->drawLine(p1, p2); + + p->setRenderHint(QPainter::Antialiasing, antiAlias); } // This method is only used to draw the little circles used in lists. @@ -447,7 +491,13 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f || !strokeColor().alpha()) return; - m_data->p()->drawArc(rect, startAngle * 16, angleSpan * 16); + QPainter *p = m_data->p(); + const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); + p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); + + p->drawArc(rect, startAngle * 16, angleSpan * 16); + + p->setRenderHint(QPainter::Antialiasing, antiAlias); } void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias) @@ -470,12 +520,80 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points p->restore(); } -void GraphicsContext::fillRect(const IntRect& rect, const Color& c) +void GraphicsContext::fillPath() +{ + if (paintingDisabled()) + return; + + QPainter *p = m_data->p(); + QPainterPath path = m_data->currentPath; + + switch (m_common->state.fillColorSpace) { + case SolidColorSpace: + if (fillColor().alpha()) + p->fillPath(path, p->brush()); + break; + case PatternColorSpace: + p->fillPath(path, QBrush(m_common->state.fillPattern.get()->createPlatformPattern(getCTM()))); + break; + case GradientColorSpace: + QGradient* gradient = m_common->state.fillGradient.get()->platformGradient(); + *gradient = applySpreadMethod(*gradient, spreadMethod()); + p->fillPath(path, QBrush(*gradient)); + break; + } +} + +void GraphicsContext::strokePath() +{ + if (paintingDisabled()) + return; + + QPainter *p = m_data->p(); + QPen pen = p->pen(); + QPainterPath path = m_data->currentPath; + + switch (m_common->state.strokeColorSpace) { + case SolidColorSpace: + if (strokeColor().alpha()) + p->strokePath(path, pen); + break; + case PatternColorSpace: { + pen.setBrush(QBrush(m_common->state.strokePattern.get()->createPlatformPattern(getCTM()))); + p->setPen(pen); + p->strokePath(path, pen); + break; + } + case GradientColorSpace: { + QGradient* gradient = m_common->state.strokeGradient.get()->platformGradient(); + *gradient = applySpreadMethod(*gradient, spreadMethod()); + pen.setBrush(QBrush(*gradient)); + p->setPen(pen); + p->strokePath(path, pen); + break; + } + } +} + +void GraphicsContext::fillRect(const FloatRect& rect) { if (paintingDisabled()) return; - m_data->p()->fillRect(rect, QColor(c)); + QPainter *p = m_data->p(); + + switch (m_common->state.fillColorSpace) { + case SolidColorSpace: + if (fillColor().alpha()) + p->fillRect(rect, p->brush()); + break; + case PatternColorSpace: + p->fillRect(rect, QBrush(m_common->state.fillPattern.get()->createPlatformPattern(getCTM()))); + break; + case GradientColorSpace: + p->fillRect(rect, QBrush(*(m_common->state.fillGradient.get()->platformGradient()))); + break; + } } void GraphicsContext::fillRect(const FloatRect& rect, const Color& c) @@ -483,7 +601,8 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& c) if (paintingDisabled()) return; - m_data->p()->fillRect(rect, QColor(c)); + m_data->solidColor.setColor(QColor(c)); + m_data->p()->fillRect(rect, m_data->solidColor); } void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color) @@ -505,9 +624,9 @@ void GraphicsContext::addPath(const Path& path) m_data->currentPath = *(path.platformPath()); } -void GraphicsContext::setFillRule(WindRule rule) +bool GraphicsContext::inTransparencyLayer() const { - m_data->currentPath.setFillRule(rule == RULE_EVENODD ? Qt::OddEvenFill : Qt::WindingFill); + return !m_data->layers.isEmpty(); } PlatformPath* GraphicsContext::currentPath() @@ -515,7 +634,7 @@ PlatformPath* GraphicsContext::currentPath() return &m_data->currentPath; } -void GraphicsContext::clip(const IntRect& rect) +void GraphicsContext::clip(const FloatRect& rect) { if (paintingDisabled()) return; @@ -531,7 +650,6 @@ void GraphicsContext::clip(const IntRect& rect) * RenderTheme handles drawing focus on widgets which * need it. */ -void setFocusRingColorChangeFunction(void (*)()) { } Color focusRingColor() { return Color(0, 0, 0); } void GraphicsContext::drawFocusRing(const Color& color) { @@ -545,6 +663,8 @@ void GraphicsContext::drawFocusRing(const Color& color) return; QPainter *p = m_data->p(); + const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); + p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); const QPen oldPen = p->pen(); const QBrush oldBrush = p->brush(); @@ -568,6 +688,8 @@ void GraphicsContext::drawFocusRing(const Color& color) #endif p->setPen(oldPen); p->setBrush(oldBrush); + + p->setRenderHint(QPainter::Antialiasing, antiAlias); } void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing) @@ -597,23 +719,16 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect) return FloatRect(QRectF(result)); } -void GraphicsContext::setShadow(const IntSize& pos, int blur, const Color &color) +void GraphicsContext::setPlatformShadow(const IntSize& pos, int blur, const Color &color) { - if (paintingDisabled()) - return; - - m_data->shadow.x = pos.width(); - m_data->shadow.y = pos.height(); - m_data->shadow.blur = blur; - m_data->shadow.color = color; + // Qt doesn't support shadows natively, they are drawn manually in the draw* + // functions } -void GraphicsContext::clearShadow() +void GraphicsContext::clearPlatformShadow() { - if (paintingDisabled()) - return; - - m_data->shadow = TextShadow(); + // Qt doesn't support shadows natively, they are drawn manually in the draw* + // functions } void GraphicsContext::beginTransparencyLayer(float opacity) @@ -623,20 +738,18 @@ void GraphicsContext::beginTransparencyLayer(float opacity) int x, y, w, h; x = y = 0; - w = m_data->device->width(); - h = m_data->device->height(); - QPainter *p = m_data->p(); + const QPaintDevice *device = p->device(); + w = device->width(); + h = device->height(); + QRectF clip = p->clipPath().boundingRect(); - bool ok; - QTransform transform = p->transform().inverted(&ok); - if (ok) { - QRectF deviceClip = transform.mapRect(clip); - x = int(qBound(qreal(0), deviceClip.x(), (qreal)w)); - y = int(qBound(qreal(0), deviceClip.y(), (qreal)h)); - w = int(qBound(qreal(0), deviceClip.width(), (qreal)w) + 2); - h = int(qBound(qreal(0), deviceClip.height(), (qreal)h) + 2); - } + QRectF deviceClip = p->transform().mapRect(clip); + x = int(qBound(qreal(0), deviceClip.x(), (qreal)w)); + y = int(qBound(qreal(0), deviceClip.y(), (qreal)h)); + w = int(qBound(qreal(0), deviceClip.width(), (qreal)w) + 2); + h = int(qBound(qreal(0), deviceClip.height(), (qreal)h) + 2); + TransparencyLayer * layer = new TransparencyLayer(m_data->p(), QRect(x, y, w, h)); layer->opacity = opacity; @@ -668,9 +781,11 @@ void GraphicsContext::clearRect(const FloatRect& rect) QPainter *p = m_data->p(); QPainter::CompositionMode currentCompositionMode = p->compositionMode(); - p->setCompositionMode(QPainter::CompositionMode_Source); + if (p->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) + p->setCompositionMode(QPainter::CompositionMode_Source); p->eraseRect(rect); - p->setCompositionMode(currentCompositionMode); + if (p->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) + p->setCompositionMode(currentCompositionMode); } void GraphicsContext::strokeRect(const FloatRect& rect, float width) @@ -678,12 +793,12 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float width) if (paintingDisabled()) return; - QPainter *p = m_data->p(); QPainterPath path; path.addRect(rect); - QPen nPen = p->pen(); - nPen.setWidthF(width); - p->strokePath(path, nPen); + setStrokeThickness(width); + m_data->currentPath = path; + + strokePath(); } void GraphicsContext::setLineCap(LineCap lc) @@ -697,6 +812,26 @@ void GraphicsContext::setLineCap(LineCap lc) p->setPen(nPen); } +void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset) +{ + QPainter* p = m_data->p(); + QPen pen = p->pen(); + unsigned dashLength = dashes.size(); + if (dashLength) { + QVector<qreal> pattern; + unsigned count = dashLength; + if (dashLength % 2) + count *= 2; + + for (unsigned i = 0; i < count; i++) + pattern.append(dashes[i % dashLength] / narrowPrecisionToFloat(pen.widthF())); + + pen.setDashPattern(pattern); + pen.setDashOffset(dashOffset); + } + p->setPen(pen); +} + void GraphicsContext::setLineJoin(LineJoin lj) { if (paintingDisabled()) @@ -732,7 +867,8 @@ void GraphicsContext::setCompositeOperation(CompositeOperator op) if (paintingDisabled()) return; - m_data->p()->setCompositionMode(toQtCompositionMode(op)); + if (m_data->p()->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) + m_data->p()->setCompositionMode(toQtCompositionMode(op)); } void GraphicsContext::clip(const Path& path) @@ -780,7 +916,7 @@ void GraphicsContext::rotate(float radians) if (paintingDisabled()) return; - m_data->p()->rotate(radians); + m_data->p()->rotate(180/M_PI*radians); } void GraphicsContext::scale(const FloatSize& s) @@ -795,7 +931,7 @@ void GraphicsContext::clipOut(const IntRect& rect) { if (paintingDisabled()) return; - + QPainter *p = m_data->p(); QRectF clipBounds = p->clipPath().boundingRect(); QPainterPath newClip; @@ -810,7 +946,7 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) { if (paintingDisabled()) return; - + QPainter *p = m_data->p(); QRectF clipBounds = p->clipPath().boundingRect(); QPainterPath newClip; @@ -821,6 +957,11 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) p->setClipPath(newClip, Qt::IntersectClip); } +void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*) +{ + notImplemented(); +} + void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) { @@ -872,7 +1013,7 @@ void GraphicsContext::setPlatformStrokeColor(const Color& color) } void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle) -{ +{ if (paintingDisabled()) return; QPainter *p = m_data->p(); @@ -905,6 +1046,101 @@ void GraphicsContext::setUseAntialiasing(bool enable) m_data->p()->setRenderHint(QPainter::Antialiasing, enable); } +#ifdef Q_WS_WIN +#include <windows.h> + +HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap) +{ + // painting through native HDC is only supported for plugin, where mayCreateBitmap is always TRUE + Q_ASSERT(mayCreateBitmap == TRUE); + + if (dstRect.isEmpty()) + return 0; + + // Create a bitmap DC in which to draw. + BITMAPINFO bitmapInfo; + bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bitmapInfo.bmiHeader.biWidth = dstRect.width(); + bitmapInfo.bmiHeader.biHeight = dstRect.height(); + bitmapInfo.bmiHeader.biPlanes = 1; + bitmapInfo.bmiHeader.biBitCount = 32; + bitmapInfo.bmiHeader.biCompression = BI_RGB; + bitmapInfo.bmiHeader.biSizeImage = 0; + bitmapInfo.bmiHeader.biXPelsPerMeter = 0; + bitmapInfo.bmiHeader.biYPelsPerMeter = 0; + bitmapInfo.bmiHeader.biClrUsed = 0; + bitmapInfo.bmiHeader.biClrImportant = 0; + + void* pixels = 0; + HBITMAP bitmap = ::CreateDIBSection(NULL, &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0); + if (!bitmap) + return 0; + + HDC displayDC = ::GetDC(0); + HDC bitmapDC = ::CreateCompatibleDC(displayDC); + ::ReleaseDC(0, displayDC); + + ::SelectObject(bitmapDC, bitmap); + + // Fill our buffer with clear if we're going to alpha blend. + if (supportAlphaBlend) { + BITMAP bmpInfo; + GetObject(bitmap, sizeof(bmpInfo), &bmpInfo); + int bufferSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight; + memset(bmpInfo.bmBits, 0, bufferSize); + } + + // Make sure we can do world transforms. + SetGraphicsMode(bitmapDC, GM_ADVANCED); + + // Apply a translation to our context so that the drawing done will be at (0,0) of the bitmap. + XFORM xform; + xform.eM11 = 1.0f; + xform.eM12 = 0.0f; + xform.eM21 = 0.0f; + xform.eM22 = 1.0f; + xform.eDx = -dstRect.x(); + xform.eDy = -dstRect.y(); + ::SetWorldTransform(bitmapDC, &xform); + + + return bitmapDC; +} + +void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap) +{ + // painting through native HDC is only supported for plugin, where mayCreateBitmap is always TRUE + Q_ASSERT(mayCreateBitmap == TRUE); + + if (hdc) { + + if (!dstRect.isEmpty()) { + + HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP)); + BITMAP info; + GetObject(bitmap, sizeof(info), &info); + ASSERT(info.bmBitsPixel == 32); + + QPixmap pixmap = QPixmap::fromWinHBITMAP(bitmap, supportAlphaBlend ? QPixmap::PremultipliedAlpha : QPixmap::NoAlpha); + m_data->p()->drawPixmap(dstRect, pixmap); + + ::DeleteObject(bitmap); + } + + ::DeleteDC(hdc); + } +} +#endif + +void GraphicsContext::setImageInterpolationQuality(InterpolationQuality) +{ +} + +InterpolationQuality GraphicsContext::imageInterpolationQuality() const +{ + return InterpolationDefault; +} + } // vim: ts=4 sw=4 et diff --git a/WebCore/platform/graphics/qt/IconQt.cpp b/WebCore/platform/graphics/qt/IconQt.cpp index e39d161..b04668c 100644 --- a/WebCore/platform/graphics/qt/IconQt.cpp +++ b/WebCore/platform/graphics/qt/IconQt.cpp @@ -22,7 +22,6 @@ #include "Icon.h" #include "GraphicsContext.h" -#include "DeprecatedString.h" #include "PlatformString.h" #include "IntRect.h" #include "NotImplemented.h" @@ -42,11 +41,17 @@ Icon::~Icon() { } -PassRefPtr<Icon> Icon::newIconForFile(const String& filename) +PassRefPtr<Icon> Icon::createIconForFile(const String& filename) { - Icon *i = new Icon; + RefPtr<Icon> i = adoptRef(new Icon); i->m_icon = QIcon(filename); - return PassRefPtr<Icon>(i); + return i.release(); +} + +PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames) +{ + //FIXME: Implement this + return 0; } void Icon::paint(GraphicsContext* ctx, const IntRect& rect) diff --git a/WebCore/platform/graphics/qt/ImageBufferData.h b/WebCore/platform/graphics/qt/ImageBufferData.h new file mode 100644 index 0000000..222dabe --- /dev/null +++ b/WebCore/platform/graphics/qt/ImageBufferData.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ImageBufferData_h +#define ImageBufferData_h + +#include <QPainter> +#include <QPixmap> + +#include "OwnPtr.h" + +namespace WebCore { + +class IntSize; + +class ImageBufferData { +public: + ImageBufferData(const IntSize&); + + QPixmap m_pixmap; + OwnPtr<QPainter> m_painter; +}; + +} // namespace WebCore + +#endif // ImageBufferData_h diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp index c95d8c8..d4ab59f 100644 --- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp +++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2008 Holger Hans Peter Freyther * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,47 +27,89 @@ #include "config.h" #include "ImageBuffer.h" +#include "CString.h" #include "GraphicsContext.h" +#include "ImageData.h" +#include "MIMETypeRegistry.h" +#include "NotImplemented.h" +#include "StillImageQt.h" +#include <QBuffer> +#include <QImageWriter> #include <QPainter> #include <QPixmap> namespace WebCore { -std::auto_ptr<ImageBuffer> ImageBuffer::create(const IntSize& size, bool grayScale) +ImageBufferData::ImageBufferData(const IntSize& size) + : m_pixmap(size) { - QPixmap px(size); - return std::auto_ptr<ImageBuffer>(new ImageBuffer(px)); + m_pixmap.fill(QColor(Qt::transparent)); + m_painter.set(new QPainter(&m_pixmap)); } -ImageBuffer::ImageBuffer(const QPixmap& px) - : m_pixmap(px), - m_painter(0) +ImageBuffer::ImageBuffer(const IntSize& size, bool grayScale, bool& success) + : m_data(size) + , m_size(size) { - m_painter = new QPainter(&m_pixmap); - m_context.set(new GraphicsContext(m_painter)); + m_context.set(new GraphicsContext(m_data.m_painter.get())); + success = true; } ImageBuffer::~ImageBuffer() { - delete m_painter; } GraphicsContext* ImageBuffer::context() const { - if (!m_painter->isActive()) - m_painter->begin(&m_pixmap); + ASSERT(m_data.m_painter->isActive()); return m_context.get(); } -QPixmap* ImageBuffer::pixmap() const +Image* ImageBuffer::image() const { - if (!m_painter) - return &m_pixmap; - if (m_painter->isActive()) - m_painter->end(); - return &m_pixmap; + if (!m_image) { + // It's assumed that if image() is called, the actual rendering to the + // GraphicsContext must be done. + ASSERT(context()); + m_image = StillImage::create(m_data.m_pixmap); + } + + return m_image.get(); +} + +PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect&) const +{ + notImplemented(); + return 0; +} + +void ImageBuffer::putImageData(ImageData*, const IntRect&, const IntPoint&) +{ + notImplemented(); +} + +// We get a mimeType here but QImageWriter does not support mimetypes but +// only formats (png, gif, jpeg..., xpm). So assume we get image/ as image +// mimetypes and then remove the image/ to get the Qt format. +String ImageBuffer::toDataURL(const String& mimeType) const +{ + ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); + + if (!mimeType.startsWith("image/")) + return "data:,"; + + // prepare our target + QByteArray data; + QBuffer buffer(&data); + buffer.open(QBuffer::WriteOnly); + + if (!m_data.m_pixmap.save(&buffer, mimeType.substring(sizeof "image").utf8().data())) + return "data:,"; + + buffer.close(); + return String::format("data:%s;base64,%s", mimeType.utf8().data(), data.toBase64().data()); } } diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp index 44ab0d3..e3b00a1 100644 --- a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp +++ b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Friedemann Kleint <fkleint@trolltech.com> - * Copyright (C) 2006 Trolltech ASA + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * All rights reserved. * @@ -206,7 +206,7 @@ void ImageDecoderQt::reset() void ImageDecoderQt::setData(const IncomingData &data, bool allDataReceived) { reset(); - ReadContext readContext(data, ReadContext::LoadIncrementally, m_imageList); + ReadContext readContext(data, ReadContext::LoadComplete, m_imageList); if (debugImageDecoderQt) qDebug() << " setData " << data.size() << " image bytes, complete=" << allDataReceived; diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.h b/WebCore/platform/graphics/qt/ImageDecoderQt.h index 32f91d1..3573dd0 100644 --- a/WebCore/platform/graphics/qt/ImageDecoderQt.h +++ b/WebCore/platform/graphics/qt/ImageDecoderQt.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Friedemann Kleint <fkleint@trolltech.com> - * Copyright (C) 2006 Trolltech ASA + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/WebCore/platform/graphics/qt/ImageQt.cpp b/WebCore/platform/graphics/qt/ImageQt.cpp index 206aee3..9234c69 100644 --- a/WebCore/platform/graphics/qt/ImageQt.cpp +++ b/WebCore/platform/graphics/qt/ImageQt.cpp @@ -36,6 +36,7 @@ #include "GraphicsContext.h" #include "AffineTransform.h" #include "NotImplemented.h" +#include "StillImageQt.h" #include "qwebsettings.h" #include <QPixmap> @@ -53,17 +54,15 @@ // This function loads resources into WebKit static QPixmap loadResourcePixmap(const char *name) { - const QString resource = name; - QPixmap pixmap; - if (resource == "missingImage") + if (qstrcmp(name, "missingImage") == 0) pixmap = QWebSettings::webGraphic(QWebSettings::MissingImageGraphic); - else if (resource == "nullPlugin") + else if (qstrcmp(name, "nullPlugin") == 0) pixmap = QWebSettings::webGraphic(QWebSettings::MissingPluginGraphic); - else if (resource == "urlIcon") - pixmap = QWebSettings::webGraphic(QWebSettings::DefaultFaviconGraphic); - else if (resource == "textAreaResizeCorner") - pixmap = QWebSettings::webGraphic(QWebSettings::TextAreaResizeCornerGraphic); + else if (qstrcmp(name, "urlIcon") == 0) + pixmap = QWebSettings::webGraphic(QWebSettings::DefaultFrameIconGraphic); + else if (qstrcmp(name, "textAreaResizeCorner") == 0) + pixmap = QWebSettings::webGraphic(QWebSettings::TextAreaSizeGripCornerGraphic); return pixmap; } @@ -74,8 +73,9 @@ void FrameData::clear() { if (m_frame) { m_frame = 0; - m_duration = 0.0f; - m_hasAlpha = true; + // NOTE: We purposefully don't reset metadata here, so that even if we + // throw away previously-decoded data, animation loops can still access + // properties like frame durations without re-decoding. } } @@ -85,10 +85,9 @@ void FrameData::clear() // Image Class // ================================================ -Image* Image::loadPlatformResource(const char* name) +PassRefPtr<Image> Image::loadPlatformResource(const char* name) { - BitmapImage* img = new BitmapImage(loadResourcePixmap(name)); - return img; + return StillImage::create(loadResourcePixmap(name)); } @@ -98,39 +97,20 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const notImplemented(); } -BitmapImage::BitmapImage(const QPixmap &pixmap, ImageObserver *observer) - : Image(observer) - , m_currentFrame(0) - , m_frames(0) - , m_frameTimer(0) - , m_repetitionCount(0) - , m_repetitionsComplete(0) - , m_isSolidColor(false) - , m_animatingImageType(true) - , m_animationFinished(false) - , m_allDataReceived(false) - , m_haveSize(false) - , m_sizeAvailable(false) - , m_decodedSize(0) -{ - m_pixmap = new QPixmap(pixmap); -} - void BitmapImage::initPlatformData() { - m_pixmap = 0; } void BitmapImage::invalidatePlatformData() { - delete m_pixmap; - m_pixmap = 0; } // Drawing Routines void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatRect& src, CompositeOperator op) { + startAnimation(); + QPixmap* image = nativeImageForCurrentFrame(); if (!image) return; @@ -154,8 +134,6 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, painter->drawPixmap(dst, *image, src); ctxt->restore(); - - startAnimation(); } void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform, @@ -171,23 +149,14 @@ void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, pixmap = pixmap.copy(tr); } - if (patternTransform.isIdentity()) { - ctxt->save(); - ctxt->setCompositeOperation(op); - QPainter* p = ctxt->platformContext(); - p->setBrushOrigin(phase); - p->drawTiledPixmap(destRect, pixmap); - ctxt->restore(); - } else { - QBrush b(pixmap); - b.setMatrix(patternTransform); - ctxt->save(); - ctxt->setCompositeOperation(op); - QPainter* p = ctxt->platformContext(); - p->setBrushOrigin(phase); - p->fillRect(destRect, b); - ctxt->restore(); - } + QBrush b(pixmap); + b.setMatrix(patternTransform); + ctxt->save(); + ctxt->setCompositeOperation(op); + QPainter* p = ctxt->platformContext(); + p->setBrushOrigin(phase); + p->fillRect(destRect, b); + ctxt->restore(); } void BitmapImage::checkForSolidColor() @@ -196,14 +165,6 @@ void BitmapImage::checkForSolidColor() m_isSolidColor = false; } -QPixmap* BitmapImage::getPixmap() const -{ - if (!m_pixmap) - return const_cast<BitmapImage*>(this)->frameAtIndex(0); - else - return m_pixmap; -} - } diff --git a/WebCore/platform/graphics/qt/ImageSourceQt.cpp b/WebCore/platform/graphics/qt/ImageSourceQt.cpp index 84d503f..1d14f9d 100644 --- a/WebCore/platform/graphics/qt/ImageSourceQt.cpp +++ b/WebCore/platform/graphics/qt/ImageSourceQt.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2006 Trolltech ASA + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * All rights reserved. * @@ -31,63 +31,29 @@ #include "ImageDecoderQt.h" #include "SharedBuffer.h" +#include <QBuffer> #include <QImage> -#include <qdebug.h> - +#include <QImageReader> namespace WebCore { - enum ImageFormat { ImageFormat_None, ImageFormat_GIF, ImageFormat_PNG, ImageFormat_JPEG, - ImageFormat_BMP, ImageFormat_ICO, ImageFormat_XBM }; - -ImageFormat detectImageFormat(const SharedBuffer& data) +static bool canHandleImage(const SharedBuffer& _data) { // We need at least 4 bytes to figure out what kind of image we're dealing with. - int length = data.size(); - if (length < 4) - return ImageFormat_None; - - const unsigned char* uContents = (const unsigned char*) data.data(); - const char* contents = data.data(); - - // GIFs begin with GIF8(7 or 9). - if (strncmp(contents, "GIF8", 4) == 0) - return ImageFormat_GIF; - - // Test for PNG. - if (uContents[0] == 0x89 && - uContents[1] == 0x50 && - uContents[2] == 0x4E && - uContents[3] == 0x47) - return ImageFormat_PNG; - - // JPEG - if (uContents[0] == 0xFF && - uContents[1] == 0xD8 && - uContents[2] == 0xFF) - return ImageFormat_JPEG; - - // BMP - if (strncmp(contents, "BM", 2) == 0) - return ImageFormat_BMP; - - // ICOs always begin with a 2-byte 0 followed by a 2-byte 1. - // CURs begin with 2-byte 0 followed by 2-byte 2. - if (!memcmp(contents, "\000\000\001\000", 4) || - !memcmp(contents, "\000\000\002\000", 4)) - return ImageFormat_ICO; - - // XBMs require 8 bytes of info. - if (length >= 8 && strncmp(contents, "#define ", 8) == 0) - return ImageFormat_XBM; - - // Give up. We don't know what the heck this is. - return ImageFormat_None; + if (_data.size() < 4) + return false; + + QByteArray data = QByteArray::fromRawData(_data.data(), _data.size()); + QBuffer buffer(&data); + if (!buffer.open(QBuffer::ReadOnly)) + return false; + + return !QImageReader::imageFormat(&buffer).isEmpty(); } - + ImageDecoderQt* createDecoder(const SharedBuffer& data) { - if (detectImageFormat(data) != ImageFormat_None) - return new ImageDecoderQt(); - return 0; + if (!canHandleImage(data)) + return 0; + return new ImageDecoderQt(); } ImageSource::ImageSource() @@ -136,6 +102,11 @@ IntSize ImageSource::size() const return m_decoder->size(); } +IntSize ImageSource::frameSizeAtIndex(size_t) const +{ + return size(); +} + int ImageSource::repetitionCount() { if (!m_decoder) diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp new file mode 100644 index 0000000..431e68e --- /dev/null +++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp @@ -0,0 +1,533 @@ +/* + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "MediaPlayerPrivatePhonon.h" + +#include <limits> + +#include "CString.h" +#include "FrameView.h" +#include "GraphicsContext.h" +#include "NotImplemented.h" +#include "Widget.h" +#include <wtf/HashSet.h> + +#include <QDebug> +#include <QPainter> +#include <QWidget> +#include <QMetaEnum> +#include <QUrl> +#include <QEvent> +#include <phonon> + +using namespace Phonon; + +#define LOG_MEDIAOBJECT() (LOG(Media,"%s", debugMediaObject(this, *m_mediaObject).constData())) + +static QByteArray debugMediaObject(WebCore::MediaPlayerPrivate* mediaPlayer, const MediaObject& mediaObject) +{ + QByteArray byteArray; + QTextStream stream(&byteArray); + + const QMetaObject* metaObj = mediaPlayer->metaObject(); + QMetaEnum phononStates = metaObj->enumerator(metaObj->indexOfEnumerator("PhononState")); + + stream << "debugMediaObject -> Phonon::MediaObject("; + stream << "State: " << phononStates.valueToKey(mediaObject.state()); + stream << " | Current time: " << mediaObject.currentTime(); + stream << " | Remaining time: " << mediaObject.remainingTime(); + stream << " | Total time: " << mediaObject.totalTime(); + stream << " | Meta-data: "; + QMultiMap<QString, QString> map = mediaObject.metaData(); + for (QMap<QString, QString>::const_iterator it = map.constBegin(); + it != map.constEnd(); ++it) { + stream << "(" << it.key() << ", " << it.value() << ")"; + } + stream << " | Has video: " << mediaObject.hasVideo(); + stream << " | Is seekable: " << mediaObject.isSeekable(); + stream << ")"; + + stream.flush(); + + return byteArray; +} + +using namespace WTF; + +namespace WebCore { + +MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) + : m_player(player) + , m_networkState(MediaPlayer::Empty) + , m_readyState(MediaPlayer::DataUnavailable) + , m_mediaObject(new MediaObject()) + , m_videoWidget(new VideoWidget(0)) + , m_audioOutput(new AudioOutput()) + , m_isVisible(false) +{ + // Hint to Phonon to disable overlay painting + m_videoWidget->setAttribute(Qt::WA_DontShowOnScreen); + + createPath(m_mediaObject, m_videoWidget); + createPath(m_mediaObject, m_audioOutput); + + // Make sure we get updates for each frame + m_videoWidget->installEventFilter(this); + foreach(QWidget* widget, qFindChildren<QWidget*>(m_videoWidget)) { + widget->installEventFilter(this); + } + + connect(m_mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)), + this, SLOT(stateChanged(Phonon::State, Phonon::State))); + connect(m_mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64))); + connect(m_mediaObject, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged())); + connect(m_mediaObject, SIGNAL(seekableChanged(bool)), this, SLOT(seekableChanged(bool))); + connect(m_mediaObject, SIGNAL(hasVideoChanged(bool)), this, SLOT(hasVideoChanged(bool))); + connect(m_mediaObject, SIGNAL(bufferStatus(int)), this, SLOT(bufferStatus(int))); + connect(m_mediaObject, SIGNAL(finished()), this, SLOT(finished())); + connect(m_mediaObject, SIGNAL(currentSourceChanged(const Phonon::MediaSource&)), + this, SLOT(currentSourceChanged(const Phonon::MediaSource&))); + connect(m_mediaObject, SIGNAL(aboutToFinish()), this, SLOT(aboutToFinish())); + connect(m_mediaObject, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(prefinishMarkReached(qint32))); + connect(m_mediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64))); +} + +MediaPlayerPrivate::~MediaPlayerPrivate() +{ + LOG(Media, "MediaPlayerPrivatePhonon::dtor deleting videowidget"); + m_videoWidget->close(); + delete m_videoWidget; + m_videoWidget = 0; + + LOG(Media, "MediaPlayerPrivatePhonon::dtor deleting audiooutput"); + delete m_audioOutput; + m_audioOutput = 0; + + LOG(Media, "MediaPlayerPrivatePhonon::dtor deleting mediaobject"); + delete m_mediaObject; + m_mediaObject = 0; +} + +void MediaPlayerPrivate::getSupportedTypes(HashSet<String>&) +{ + notImplemented(); +} + +bool MediaPlayerPrivate::hasVideo() const +{ + bool hasVideo = m_mediaObject->hasVideo(); + LOG(Media, "MediaPlayerPrivatePhonon::hasVideo() -> %s", hasVideo ? "true" : "false"); + return hasVideo; +} + +void MediaPlayerPrivate::load(String url) +{ + LOG(Media, "MediaPlayerPrivatePhonon::load(\"%s\")", url.utf8().data()); + + // We are now loading + if (m_networkState != MediaPlayer::Loading) { + m_networkState = MediaPlayer::Loading; + m_player->networkStateChanged(); + } + + // And we don't have any data yet + if (m_readyState != MediaPlayer::DataUnavailable) { + m_readyState = MediaPlayer::DataUnavailable; + m_player->readyStateChanged(); + } + + m_mediaObject->setCurrentSource(QUrl(url)); + m_audioOutput->setVolume(m_player->volume()); + setVisible(m_player->visible()); +} + +void MediaPlayerPrivate::cancelLoad() +{ + notImplemented(); +} + + +void MediaPlayerPrivate::play() +{ + LOG(Media, "MediaPlayerPrivatePhonon::play()"); + m_mediaObject->play(); +} + +void MediaPlayerPrivate::pause() +{ + LOG(Media, "MediaPlayerPrivatePhonon::pause()"); + m_mediaObject->pause(); +} + + +bool MediaPlayerPrivate::paused() const +{ + bool paused = m_mediaObject->state() == Phonon::PausedState; + LOG(Media, "MediaPlayerPrivatePhonon::paused() --> %s", paused ? "true" : "false"); + return paused; +} + +void MediaPlayerPrivate::seek(float position) +{ + LOG(Media, "MediaPlayerPrivatePhonon::seek(%f)", position); + + if (!m_mediaObject->isSeekable()) + return; + + if (position > duration()) + position = duration(); + + m_mediaObject->seek(position * 1000.0f); +} + +bool MediaPlayerPrivate::seeking() const +{ + return false; +} + +float MediaPlayerPrivate::duration() const +{ + if (m_networkState < MediaPlayer::LoadedMetaData) + return 0.0f; + + float duration = m_mediaObject->totalTime() / 1000.0f; + + if (duration == 0.0f) // We are streaming + duration = std::numeric_limits<float>::infinity(); + + LOG(Media, "MediaPlayerPrivatePhonon::duration() --> %f", duration); + return duration; +} + +float MediaPlayerPrivate::currentTime() const +{ + float currentTime = m_mediaObject->currentTime() / 1000.0f; + + LOG(Media, "MediaPlayerPrivatePhonon::currentTime() --> %f", currentTime); + return currentTime; +} + +void MediaPlayerPrivate::setEndTime(float endTime) +{ + notImplemented(); +} + +float MediaPlayerPrivate::maxTimeBuffered() const +{ + notImplemented(); + return 0.0f; +} + +float MediaPlayerPrivate::maxTimeSeekable() const +{ + notImplemented(); + return 0.0f; +} + +unsigned MediaPlayerPrivate::bytesLoaded() const +{ + notImplemented(); + return 0; +} + +bool MediaPlayerPrivate::totalBytesKnown() const +{ + //notImplemented(); + return false; +} + +unsigned MediaPlayerPrivate::totalBytes() const +{ + //notImplemented(); + return 0; +} + +void MediaPlayerPrivate::setRate(float) +{ + notImplemented(); +} + +void MediaPlayerPrivate::setVolume(float volume) +{ + LOG(Media, "MediaPlayerPrivatePhonon::setVolume()"); + m_audioOutput->setVolume(volume); +} + +void MediaPlayerPrivate::setMuted(bool muted) +{ + LOG(Media, "MediaPlayerPrivatePhonon::setMuted()"); + m_audioOutput->setMuted(muted); +} + + +int MediaPlayerPrivate::dataRate() const +{ + // This is not used at the moment + return 0; +} + + +MediaPlayer::NetworkState MediaPlayerPrivate::networkState() const +{ + const QMetaObject* metaObj = this->metaObject(); + QMetaEnum networkStates = metaObj->enumerator(metaObj->indexOfEnumerator("NetworkState")); + LOG(Media, "MediaPlayerPrivatePhonon::networkState() --> %s", networkStates.valueToKey(m_networkState)); + return m_networkState; +} + +MediaPlayer::ReadyState MediaPlayerPrivate::readyState() const +{ + const QMetaObject* metaObj = this->metaObject(); + QMetaEnum readyStates = metaObj->enumerator(metaObj->indexOfEnumerator("ReadyState")); + LOG(Media, "MediaPlayerPrivatePhonon::readyState() --> %s", readyStates.valueToKey(m_readyState)); + return m_readyState; +} + +void MediaPlayerPrivate::updateStates() +{ + MediaPlayer::NetworkState oldNetworkState = m_networkState; + MediaPlayer::ReadyState oldReadyState = m_readyState; + + Phonon::State phononState = m_mediaObject->state(); + + if (phononState == Phonon::StoppedState) { + if (oldNetworkState < MediaPlayer::LoadedMetaData) { + m_networkState = MediaPlayer::LoadedMetaData; + m_readyState = MediaPlayer::DataUnavailable; + m_mediaObject->pause(); + } + } else if (phononState == Phonon::PausedState) { + m_networkState = MediaPlayer::LoadedFirstFrame; + m_readyState = MediaPlayer::CanPlayThrough; + } else if (phononState == Phonon::ErrorState) { + if (!m_mediaObject || m_mediaObject->errorType() == Phonon::FatalError) { + m_networkState = MediaPlayer::LoadFailed; + m_readyState = MediaPlayer::DataUnavailable; + cancelLoad(); + } else { + m_mediaObject->pause(); + } + } + + if (seeking()) + m_readyState = MediaPlayer::DataUnavailable; + + if (m_networkState != oldNetworkState) { + const QMetaObject* metaObj = this->metaObject(); + QMetaEnum networkStates = metaObj->enumerator(metaObj->indexOfEnumerator("NetworkState")); + LOG(Media, "Network state changed from '%s' to '%s'", + networkStates.valueToKey(oldNetworkState), + networkStates.valueToKey(m_networkState)); + m_player->networkStateChanged(); + } + + if (m_readyState != oldReadyState) { + const QMetaObject* metaObj = this->metaObject(); + QMetaEnum readyStates = metaObj->enumerator(metaObj->indexOfEnumerator("ReadyState")); + LOG(Media, "Ready state changed from '%s' to '%s'", + readyStates.valueToKey(oldReadyState), + readyStates.valueToKey(m_readyState)); + m_player->readyStateChanged(); + } +} + +void MediaPlayerPrivate::setVisible(bool visible) +{ + m_isVisible = visible; + LOG(Media, "MediaPlayerPrivatePhonon::setVisible(%s)", visible ? "true" : "false"); + + m_videoWidget->setVisible(m_isVisible); +} + +void MediaPlayerPrivate::setRect(const IntRect& newRect) +{ + if (!m_videoWidget) + return; + + LOG(Media, "MediaPlayerPrivatePhonon::setRect(%d,%d %dx%d)", + newRect.x(), newRect.y(), + newRect.width(), newRect.height()); + + QRect currentRect = m_videoWidget->rect(); + + if (newRect.width() != currentRect.width() || newRect.height() != currentRect.height()) + m_videoWidget->resize(newRect.width(), newRect.height()); +} + + +void MediaPlayerPrivate::loadStateChanged() +{ + notImplemented(); +} + +void MediaPlayerPrivate::rateChanged() +{ + notImplemented(); +} + +void MediaPlayerPrivate::sizeChanged() +{ + notImplemented(); +} + +void MediaPlayerPrivate::timeChanged() +{ + notImplemented(); +} + +void MediaPlayerPrivate::volumeChanged() +{ + notImplemented(); +} + +void MediaPlayerPrivate::didEnd() +{ + notImplemented(); +} + +void MediaPlayerPrivate::loadingFailed() +{ + notImplemented(); +} + +IntSize MediaPlayerPrivate::naturalSize() const +{ + if (!hasVideo()) { + LOG(Media, "MediaPlayerPrivatePhonon::naturalSize() -> %dx%d", + 0, 0); + return IntSize(); + } + + if (m_networkState < MediaPlayer::LoadedMetaData) { + LOG(Media, "MediaPlayerPrivatePhonon::naturalSize() -> %dx%d", + 0, 0); + return IntSize(); + } + + QSize videoSize = m_videoWidget->sizeHint(); + IntSize naturalSize(videoSize.width(), videoSize.height()); + LOG(Media, "MediaPlayerPrivatePhonon::naturalSize() -> %dx%d", + naturalSize.width(), naturalSize.height()); + return naturalSize; +} + +bool MediaPlayerPrivate::eventFilter(QObject* obj, QEvent* event) +{ + if (event->type() == QEvent::Paint) + m_player->repaint(); + + return QObject::eventFilter(obj, event); +} + +void MediaPlayerPrivate::repaint() +{ + m_player->repaint(); +} + +void MediaPlayerPrivate::paint(GraphicsContext* graphicsContect, const IntRect& rect) +{ + if (graphicsContect->paintingDisabled()) + return; + + if (!m_isVisible) + return; + + QPainter* painter = graphicsContect->platformContext(); + + painter->fillRect(rect, Qt::black); + + m_videoWidget->render(painter, QPoint(rect.x(), rect.y()), + QRegion(0, 0, rect.width(), rect.height())); +} + +// ====================== Phonon::MediaObject signals ====================== + +void MediaPlayerPrivate::stateChanged(Phonon::State newState, Phonon::State oldState) +{ + const QMetaObject* metaObj = this->metaObject(); + QMetaEnum phononStates = metaObj->enumerator(metaObj->indexOfEnumerator("PhononState")); + LOG(Media, "MediaPlayerPrivatePhonon::stateChanged(newState=%s, oldState=%s)", + phononStates.valueToKey(newState), phononStates.valueToKey(oldState)); + + updateStates(); +} + +void MediaPlayerPrivate::tick(qint64) +{ + updateStates(); + m_player->timeChanged(); +} + +void MediaPlayerPrivate::metaDataChanged() +{ + LOG(Media, "MediaPlayerPrivatePhonon::metaDataChanged()"); + LOG_MEDIAOBJECT(); +} + +void MediaPlayerPrivate::seekableChanged(bool) +{ + notImplemented(); + LOG_MEDIAOBJECT(); +} + +void MediaPlayerPrivate::hasVideoChanged(bool hasVideo) +{ + LOG(Media, "MediaPlayerPrivatePhonon::hasVideoChanged(%s)", hasVideo ? "true" : "false"); +} + +void MediaPlayerPrivate::bufferStatus(int) +{ + notImplemented(); + LOG_MEDIAOBJECT(); +} + +void MediaPlayerPrivate::finished() +{ + notImplemented(); + LOG_MEDIAOBJECT(); +} + +void MediaPlayerPrivate::currentSourceChanged(const Phonon::MediaSource&) +{ + notImplemented(); + LOG_MEDIAOBJECT(); +} + +void MediaPlayerPrivate::aboutToFinish() +{ + notImplemented(); + LOG_MEDIAOBJECT(); +} + +void MediaPlayerPrivate::prefinishMarkReached(qint32) +{ + notImplemented(); + LOG_MEDIAOBJECT(); +} + +void MediaPlayerPrivate::totalTimeChanged(qint64 totalTime) +{ + LOG(Media, "MediaPlayerPrivatePhonon::totalTimeChanged(%d)", totalTime); + LOG_MEDIAOBJECT(); +} + +} // namespace WebCore + +#include "moc_MediaPlayerPrivatePhonon.cpp" diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h new file mode 100644 index 0000000..5eb2a09 --- /dev/null +++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h @@ -0,0 +1,159 @@ +/* + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MediaPlayerPrivatePhonon_h +#define MediaPlayerPrivatePhonon_h + +#include "MediaPlayer.h" +#include <wtf/Noncopyable.h> + +#include <QObject> +#include <phononnamespace.h> + +QT_BEGIN_NAMESPACE +class QWidget; +class QUrl; + +namespace Phonon { + class MediaObject; + class VideoWidget; + class AudioOutput; + class MediaSource; +} +QT_END_NAMESPACE + +namespace WebCore { + + class MediaPlayerPrivate : public QObject, Noncopyable { + + Q_OBJECT + + public: + MediaPlayerPrivate(MediaPlayer*); + ~MediaPlayerPrivate(); + + // These enums are used for debugging + Q_ENUMS(ReadyState NetworkState PhononState) + + enum ReadyState { + DataUnavailable, + CanShowCurrentFrame, + CanPlay, + CanPlayThrough + }; + + enum NetworkState { + Empty, + LoadFailed, + Loading, + LoadedMetaData, + LoadedFirstFrame, + Loaded + }; + + enum PhononState { + LoadingState, + StoppedState, + PlayingState, + BufferingState, + PausedState, + ErrorState + }; + + IntSize naturalSize() const; + bool hasVideo() const; + + void load(String url); + void cancelLoad(); + + void play(); + void pause(); + + bool paused() const; + bool seeking() const; + + float duration() const; + float currentTime() const; + void seek(float); + void setEndTime(float); + + void setRate(float); + void setVolume(float); + void setMuted(bool); + + int dataRate() const; + + MediaPlayer::NetworkState networkState() const; + MediaPlayer::ReadyState readyState() const; + + float maxTimeBuffered() const; + float maxTimeSeekable() const; + unsigned bytesLoaded() const; + bool totalBytesKnown() const; + unsigned totalBytes() const; + + void setVisible(bool); + void setRect(const IntRect&); + + void loadStateChanged(); + void rateChanged(); + void sizeChanged(); + void timeChanged(); + void volumeChanged(); + void didEnd(); + void loadingFailed(); + + void repaint(); + void paint(GraphicsContext*, const IntRect&); + static void getSupportedTypes(HashSet<String>&); + static bool isAvailable() { return true; } + + protected: + bool eventFilter(QObject*, QEvent*); + + private slots: + void stateChanged(Phonon::State, Phonon::State); + void tick(qint64); + void metaDataChanged(); + void seekableChanged(bool); + void hasVideoChanged(bool); + void bufferStatus(int); + void finished(); + void currentSourceChanged(const Phonon::MediaSource&); + void aboutToFinish(); + void prefinishMarkReached(qint32); + void totalTimeChanged(qint64); + + private: + void updateStates(); + + MediaPlayer* m_player; + + MediaPlayer::NetworkState m_networkState; + MediaPlayer::ReadyState m_readyState; + + Phonon::MediaObject* m_mediaObject; + Phonon::VideoWidget* m_videoWidget; + Phonon::AudioOutput* m_audioOutput; + + bool m_isVisible; + }; +} + +#endif // MediaPlayerPrivatePhonon_h diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp index 240350f..76f375c 100644 --- a/WebCore/platform/graphics/qt/PathQt.cpp +++ b/WebCore/platform/graphics/qt/PathQt.cpp @@ -155,7 +155,7 @@ void Path::addArc(const FloatPoint& p, float r, float sar, float ear, bool antic // this is also due to switched coordinate system // we would end up with a 0 span instead of 360 - if (!(qFuzzyCompare(span + (ea - sa), 0.0) && + if (!(qFuzzyCompare(span + (ea - sa) + 1, 1.0) && qFuzzyCompare(qAbs(span), 360.0))) { span += ea - sa; } @@ -194,10 +194,10 @@ String Path::debugString() const switch (cur.type) { case QPainterPath::MoveToElement: - ret += QString("M %1 %2").arg(cur.x).arg(cur.y); + ret += QString(QLatin1String("M %1 %2")).arg(cur.x).arg(cur.y); break; case QPainterPath::LineToElement: - ret += QString("L %1 %2").arg(cur.x).arg(cur.y); + ret += QString(QLatin1String("L %1 %2")).arg(cur.x).arg(cur.y); break; case QPainterPath::CurveToElement: { @@ -207,7 +207,7 @@ String Path::debugString() const Q_ASSERT(c1.type == QPainterPath::CurveToDataElement); Q_ASSERT(c2.type == QPainterPath::CurveToDataElement); - ret += QString("C %1 %2 %3 %4 %5 %6").arg(cur.x).arg(cur.y).arg(c1.x).arg(c1.y).arg(c2.x).arg(c2.y); + ret += QString(QLatin1String("C %1 %2 %3 %4 %5 %6")).arg(cur.x).arg(cur.y).arg(c1.x).arg(c1.y).arg(c2.x).arg(c2.y); i += 2; break; diff --git a/WebCore/platform/graphics/qt/PatternQt.cpp b/WebCore/platform/graphics/qt/PatternQt.cpp new file mode 100644 index 0000000..883a258 --- /dev/null +++ b/WebCore/platform/graphics/qt/PatternQt.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 Eric Seidel <eric@webkit.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Pattern.h" + +#include "AffineTransform.h" +#include "GraphicsContext.h" + +namespace WebCore { + +QBrush Pattern::createPlatformPattern(const AffineTransform& transform) const +{ + QPixmap* pixmap = tileImage()->nativeImageForCurrentFrame(); + if (!pixmap) + return QBrush(); + + QBrush brush(*pixmap); + brush.setMatrix(transform); + + return brush; +} + +} diff --git a/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp index 1a45ce4..1ffce33 100644 --- a/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp +++ b/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Trolltech ASA + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -22,10 +22,14 @@ #include "config.h" #include "SimpleFontData.h" +#include "SVGFontData.h" + namespace WebCore { SimpleFontData::SimpleFontData(const FontPlatformData& font, bool customFont, bool loading, SVGFontData*) - : m_font(font), m_isCustomFont(customFont), m_isLoading(loading) + : m_font(font) + , m_isCustomFont(customFont) + , m_isLoading(loading) { } diff --git a/WebCore/platform/graphics/qt/StillImageQt.cpp b/WebCore/platform/graphics/qt/StillImageQt.cpp new file mode 100644 index 0000000..95b3bc8 --- /dev/null +++ b/WebCore/platform/graphics/qt/StillImageQt.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008 Holger Hans Peter Freyther + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "StillImageQt.h" + +#include "GraphicsContext.h" +#include "IntSize.h" + +#include <QPainter> + +namespace WebCore { + +StillImage::StillImage(const QPixmap& pixmap) + : m_pixmap(pixmap) +{} + +IntSize StillImage::size() const +{ + return IntSize(m_pixmap.width(), m_pixmap.height()); +} + +NativeImagePtr StillImage::nativeImageForCurrentFrame() +{ + return const_cast<NativeImagePtr>(&m_pixmap); +} + +void StillImage::draw(GraphicsContext* ctxt, const FloatRect& dst, + const FloatRect& src, CompositeOperator op) +{ + if (m_pixmap.isNull()) + return; + + ctxt->save(); + ctxt->setCompositeOperation(op); + QPainter* painter(ctxt->platformContext()); + painter->drawPixmap(dst, m_pixmap, src); + ctxt->restore(); +} + +} diff --git a/WebCore/platform/graphics/qt/StillImageQt.h b/WebCore/platform/graphics/qt/StillImageQt.h new file mode 100644 index 0000000..37b8b2c --- /dev/null +++ b/WebCore/platform/graphics/qt/StillImageQt.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008 Holger Hans Peter Freyther + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef StillImageQt_h +#define StillImageQt_h + +#include "Image.h" + +namespace WebCore { + + class StillImage : public Image { + public: + static PassRefPtr<StillImage> create(const QPixmap& pixmap) + { + return adoptRef(new StillImage(pixmap)); + } + + // FIXME: StillImages are underreporting decoded sizes and will be unable + // to prune because these functions are not implemented yet. + virtual void destroyDecodedData(bool incremental = false, bool preserveNearbyFrames = false) { } + virtual unsigned decodedSize() const { return 0; } + + virtual IntSize size() const; + virtual NativeImagePtr nativeImageForCurrentFrame(); + virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator); + + private: + StillImage(const QPixmap& pixmap); + + QPixmap m_pixmap; + }; + +} + +#endif |