Patch from Adam Treat to add ICO support to the Qt build.
authorstaikos <staikos@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jun 2007 05:01:53 +0000 (05:01 +0000)
committerstaikos <staikos@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jun 2007 05:01:53 +0000 (05:01 +0000)
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@23691 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
ChangeLog
WebCore/ChangeLog
WebCore/WebCore.pro
WebCore/platform/graphics/qt/ImageDecoderQt.cpp
WebKit.pro
WebKitQt/Api/qwebpage.cpp
WebKitQt/Api/qwebpage.h
WebKitQt/Api/qwebsettings.cpp
WebKitQt/Api/qwebsettings.h
WebKitQt/ChangeLog
WebKitQt/Plugins/ICOHandler.cpp [new file with mode: 0644]
WebKitQt/Plugins/ICOHandler.h [new file with mode: 0644]
WebKitQt/Plugins/Plugins.pro [new file with mode: 0644]
WebKitQt/WebCoreSupport/FrameLoaderClientQt.cpp

index 9ab4d4b..eb206e6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-06-15  Adam Treat  <adam@staikos.net>
+
+        Reviewed by George Staikos.
+
+        Add ICO support to the Qt build.
+
+        * WebKit.pro:
+
 2007-06-13  George Staikos  <staikos@kde.org>
 
         Reviewed by Lars.
index 16d9c2f..3099944 100644 (file)
@@ -1,3 +1,13 @@
+2007-06-15  Adam Treat <adam@staikos.net>
+
+        Reviewed by George Staikos.
+
+        Add ICO support to the Qt build.
+
+        * WebCore.pro:
+        * platform/graphics/qt/ImageDecoderQt.cpp:
+        (Q_IMPORT_PLUGIN):
+
 2007-06-15  George Staikos  <staikos@kde.org>
 
         Fixing Qt build.
index ba7d1ee..f9bb85c 100644 (file)
@@ -54,6 +54,9 @@ macx {
     LIBS += -lxml2 -lxslt
 }
 
+QTPLUGIN += qtwebico
+LIBS += -L$$OUTPUT_DIR/WebKitQt/Plugins
+
 qt-port {
 INCLUDEPATH += \
                 $$[QT_INSTALL_PREFIX]/src/3rdparty/sqlite/ \
index 406a969..d277a3a 100644 (file)
@@ -35,6 +35,8 @@
 #include <QtGui/QImageReader>
 #include <qdebug.h>
 
+Q_IMPORT_PLUGIN(qtwebico) //For ico format...
+
 namespace {
     const  QImage::Format DesiredFormat = QImage::Format_ARGB32;
     const  bool debugImageDecoderQt = false;
index eae6a46..c679789 100644 (file)
@@ -2,6 +2,7 @@ TEMPLATE = subdirs
 CONFIG += ordered
 !gdk-port:CONFIG += qt-port
 SUBDIRS = \
+        WebKitQt/Plugins \
         WebCore \
         JavaScriptCore/kjs/testkjs.pro
 
index 3cee579..67025d5 100644 (file)
@@ -42,6 +42,8 @@
 #include "Page.h"
 #include "FrameLoader.h"
 #include "KURL.h"
+#include "Image.h"
+#include "IconDatabase.h"
 
 #include <QDebug>
 #include <QDragEnterEvent>
@@ -343,6 +345,19 @@ QWebNetworkInterface *QWebPage::networkInterface() const
         return QWebNetworkInterface::defaultInterface();
 }
 
+QPixmap QWebPage::icon() const
+{
+    Image* image = iconDatabase()->iconForPageURL(url().toString(), IntSize(16, 16));
+    if (!image) {
+      return QPixmap();
+    }
+
+    QPixmap *icon = image->getPixmap();
+    Q_ASSERT(icon);
+    Q_ASSERT(!icon->isNull());
+    return *icon;
+}
+
 void QWebPage::setSettings(const QWebSettings &settings)
 {
     WebCore::Settings *wSettings = d->page->settings();
index aba3466..388f1ef 100644 (file)
@@ -83,6 +83,8 @@ public:
     void setNetworkInterface(QWebNetworkInterface *interface);
     QWebNetworkInterface *networkInterface() const;
 
+    QPixmap icon() const;
+
 public slots:
     /**
      * Stops loading of the page, if loading.
@@ -129,6 +131,10 @@ signals:
      * Signal is emitted when the statusbar text is changed by the page.
      */
     void statusBarTextChanged(const QString& text);
+    /**
+     * Signal is emitted when an icon ("favicon") is loaded from the site.
+     */
+    void iconLoaded();
 
 protected:
     virtual QWebFrame *createFrame(QWebFrame *parentFrame, QWebFrameData *frameData);
index 1510d92..fea9e45 100644 (file)
@@ -29,6 +29,7 @@
 #include "Settings.h"
 #include "KURL.h"
 #include "PlatformString.h"
+#include "IconDatabase.h"
 
 #include <QHash>
 #include <QSharedData>
@@ -130,6 +131,25 @@ QString QWebSettings::userStyleSheetLocation() const
     return d->userStyleSheetLocation;
 }
 
+void QWebSettings::setIconDatabaseEnabled(bool enabled, const QString &location)
+{
+    WebCore::iconDatabase()->setEnabled(enabled);
+    if (enabled) {
+      if (!location.isEmpty()) {
+          WebCore::iconDatabase()->open(location);
+      } else {
+          WebCore::iconDatabase()->open(WebCore::iconDatabase()->defaultDatabaseFilename());
+      }
+    } else {
+      WebCore::iconDatabase()->close();
+    }
+}
+
+bool QWebSettings::iconDatabaseEnabled() const
+{
+    return WebCore::iconDatabase()->enabled() && WebCore::iconDatabase()->isOpen();
+}
+
 QWebSettings::QWebSettings(const QWebSettings &other)
 {
     d = other.d;
index d6addb4..fe410e8 100644 (file)
@@ -80,6 +80,9 @@ public:
     void setUserStyleSheetLocation(const QString &location);
     QString userStyleSheetLocation() const;
 
+    void setIconDatabaseEnabled(bool enabled, const QString &location = QString());
+    bool iconDatabaseEnabled() const;
+
 private:
     QSharedDataPointer<QWebSettingsPrivate> d;
 };
index 32342dd..dfdd1a8 100644 (file)
@@ -1,3 +1,37 @@
+2007-06-15  Adam Treat  <adam@staikos.net>
+
+        Reviewed by George Staikos.
+
+        Add ICO support to the Qt build.
+
+        * Api/qwebpage.cpp:
+        (QWebPage::icon):
+        * Api/qwebpage.h:
+        * Api/qwebsettings.cpp:
+        (QWebSettings::setIconDatabaseEnabled):
+        (QWebSettings::iconDatabaseEnabled):
+        * Api/qwebsettings.h:
+        * Plugins: Added.
+        * Plugins/ICOHandler.cpp: Added.
+        (IcoHeader::operator >>):
+        (IcoHeader::BMP_INFOHDR::):
+        (IcoHeader::operator<<):
+        (IcoHeader::LessDifference::LessDifference):
+        (IcoHeader::LessDifference::operator ()):
+        (IcoHeader::loadFromDIB):
+        (ICOHandler::ICOHandler):
+        (ICOHandler::canRead):
+        (ICOHandler::read):
+        (ICOHandler::write):
+        (ICOHandler::name):
+        (ICOPlugin::keys):
+        (ICOPlugin::capabilities):
+        (ICOPlugin::create):
+        * Plugins/ICOHandler.h: Added.
+        * Plugins/Plugins.pro: Added.
+        * WebCoreSupport/FrameLoaderClientQt.cpp:
+        (WebCore::FrameLoaderClientQt::dispatchDidReceiveIcon):
+
 2007-06-15  George Staikos  <staikos@kde.org>
 
         Fixing the Qt build.
diff --git a/WebKitQt/Plugins/ICOHandler.cpp b/WebKitQt/Plugins/ICOHandler.cpp
new file mode 100644 (file)
index 0000000..97d4d17
--- /dev/null
@@ -0,0 +1,466 @@
+/*
+ * kimgio import filter for MS Windows .ico files
+ *
+ * Distributed under the terms of the LGPL
+ * Copyright (c) 2000 Malte Starostik <malte@kde.org>
+ *
+ */
+
+// remove when QImage::jumpTable is ported
+#define QT3_SUPPORT
+#define QT3_SUPPORT_WARNINGS
+#ifdef __GNUC__
+#warning TODO: remove QT3_SUPPORT
+#endif
+
+#include "ICOHandler.h"
+
+#include <cstring>
+#include <cstdlib>
+#include <algorithm>
+#include <vector>
+
+#include <QtGui/QImage>
+#include <QtGui/QBitmap>
+#include <QtGui/QApplication>
+#include <QtCore/QVector>
+#include <QtGui/QDesktopWidget>
+
+namespace
+{
+    // Global header (see http://www.daubnet.com/formats/ICO.html)
+    struct IcoHeader
+    {
+        enum Type { Icon = 1, Cursor };
+        quint16 reserved;
+        quint16 type;
+        quint16 count;
+    };
+
+    inline QDataStream& operator >>( QDataStream& s, IcoHeader& h )
+    {
+        return s >> h.reserved >> h.type >> h.count;
+    }
+
+    // Based on qt_read_dib et al. from qimage.cpp
+    // (c) 1992-2002 Trolltech AS.
+    struct BMP_INFOHDR
+    {
+        static const quint32 Size = 40;
+        quint32  biSize;                // size of this struct
+        quint32  biWidth;               // pixmap width
+        quint32  biHeight;              // pixmap height
+        quint16  biPlanes;              // should be 1
+        quint16  biBitCount;            // number of bits per pixel
+        enum Compression { RGB = 0 };
+        quint32  biCompression;         // compression method
+        quint32  biSizeImage;           // size of image
+        quint32  biXPelsPerMeter;       // horizontal resolution
+        quint32  biYPelsPerMeter;       // vertical resolution
+        quint32  biClrUsed;             // number of colors used
+        quint32  biClrImportant;        // number of important colors
+    };
+    const quint32 BMP_INFOHDR::Size;
+
+    QDataStream& operator >>( QDataStream &s, BMP_INFOHDR &bi )
+    {
+        s >> bi.biSize;
+        if ( bi.biSize == BMP_INFOHDR::Size )
+        {
+            s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount;
+            s >> bi.biCompression >> bi.biSizeImage;
+            s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter;
+            s >> bi.biClrUsed >> bi.biClrImportant;
+        }
+        return s;
+    }
+
+#if 0
+    QDataStream &operator<<( QDataStream &s, const BMP_INFOHDR &bi )
+    {
+        s << bi.biSize;
+        s << bi.biWidth << bi.biHeight;
+        s << bi.biPlanes;
+        s << bi.biBitCount;
+        s << bi.biCompression;
+        s << bi.biSizeImage;
+        s << bi.biXPelsPerMeter << bi.biYPelsPerMeter;
+        s << bi.biClrUsed << bi.biClrImportant;
+        return s;
+    }
+#endif
+
+    // Header for every icon in the file
+    struct IconRec
+    {
+        unsigned char width;
+        unsigned char height;
+        quint16 colors;
+        quint16 hotspotX;
+        quint16 hotspotY;
+        quint32 size;
+        quint32 offset;
+    };
+
+    inline QDataStream& operator >>( QDataStream& s, IconRec& r )
+    {
+        return s >> r.width >> r.height >> r.colors
+                 >> r.hotspotX >> r.hotspotY >> r.size >> r.offset;
+    }
+
+    struct LessDifference
+    {
+        LessDifference( unsigned s, unsigned c )
+            : size( s ), colors( c ) {}
+
+        bool operator ()( const IconRec& lhs, const IconRec& rhs ) const
+        {
+            // closest size match precedes everything else
+            if ( std::abs( int( lhs.width - size ) ) <
+                 std::abs( int( rhs.width - size ) ) ) return true;
+            else if ( std::abs( int( lhs.width - size ) ) >
+                 std::abs( int( rhs.width - size ) ) ) return false;
+            else if ( colors == 0 )
+            {
+                // high/true color requested
+                if ( lhs.colors == 0 ) return true;
+                else if ( rhs.colors == 0 ) return false;
+                else return lhs.colors > rhs.colors;
+            }
+            else
+            {
+                // indexed icon requested
+                if ( lhs.colors == 0 && rhs.colors == 0 ) return false;
+                else if ( lhs.colors == 0 ) return false;
+                else return std::abs( int( lhs.colors - colors ) ) <
+                            std::abs( int( rhs.colors - colors ) );
+            }
+        }
+        unsigned size;
+        unsigned colors;
+    };
+
+    bool loadFromDIB( QDataStream& stream, const IconRec& rec, QImage& icon )
+    {
+        BMP_INFOHDR header;
+        stream >> header;
+        if ( stream.atEnd() || header.biSize != BMP_INFOHDR::Size ||
+             header.biSize > rec.size ||
+             header.biCompression != BMP_INFOHDR::RGB ||
+             ( header.biBitCount != 1 && header.biBitCount != 4 &&
+               header.biBitCount != 8 && header.biBitCount != 24 &&
+               header.biBitCount != 32 ) ) return false;
+
+        unsigned paletteSize, paletteEntries;
+
+        if (header.biBitCount > 8)
+        {
+            paletteEntries = 0;
+            paletteSize    = 0;
+        }
+        else
+        {
+            paletteSize    = (1 << header.biBitCount);
+            paletteEntries = paletteSize;
+            if (header.biClrUsed && header.biClrUsed < paletteSize)
+                paletteEntries = header.biClrUsed;
+        }
+
+        // Always create a 32-bit image to get the mask right
+        // Note: this is safe as rec.width, rec.height are bytes
+        icon = QImage( rec.width, rec.height, QImage::Format_ARGB32 );
+        if ( icon.isNull() ) return false;
+
+        QVector< QRgb > colorTable( paletteSize );
+
+        colorTable.fill( QRgb( 0 ) );
+        for ( unsigned i = 0; i < paletteEntries; ++i )
+        {
+            unsigned char rgb[ 4 ];
+            stream.readRawData( reinterpret_cast< char* >( &rgb ),
+                                 sizeof( rgb ) );
+            colorTable[ i ] = qRgb( rgb[ 2 ], rgb[ 1 ], rgb[ 0 ] );
+        }
+
+        unsigned bpl = ( rec.width * header.biBitCount + 31 ) / 32 * 4;
+
+        unsigned char* buf = new unsigned char[ bpl ];
+        unsigned char** lines = icon.jumpTable();
+        for ( unsigned y = rec.height; !stream.atEnd() && y--; )
+        {
+            stream.readRawData( reinterpret_cast< char* >( buf ), bpl );
+            unsigned char* pixel = buf;
+            QRgb* p = reinterpret_cast< QRgb* >( lines[ y ] );
+            switch ( header.biBitCount )
+            {
+                case 1:
+                    for ( unsigned x = 0; x < rec.width; ++x )
+                        *p++ = colorTable[
+                            ( pixel[ x / 8 ] >> ( 7 - ( x & 0x07 ) ) ) & 1 ];
+                    break;
+                case 4:
+                    for ( unsigned x = 0; x < rec.width; ++x )
+                        if ( x & 1 ) *p++ = colorTable[ pixel[ x / 2 ] & 0x0f ];
+                        else *p++ = colorTable[ pixel[ x / 2 ] >> 4 ];
+                    break;
+                case 8:
+                    for ( unsigned x = 0; x < rec.width; ++x )
+                        *p++ = colorTable[ pixel[ x ] ];
+                    break;
+                case 24:
+                    for ( unsigned x = 0; x < rec.width; ++x )
+                        *p++ = qRgb( pixel[ 3 * x + 2 ],
+                                     pixel[ 3 * x + 1 ],
+                                     pixel[ 3 * x ] );
+                    break;
+                case 32:
+                    for ( unsigned x = 0; x < rec.width; ++x )
+                        *p++ = qRgba( pixel[ 4 * x + 2 ],
+                                      pixel[ 4 * x + 1 ],
+                                      pixel[ 4 * x ],
+                                      pixel[ 4 * x  + 3] );
+                    break;
+            }
+        }
+        delete[] buf;
+
+        if ( header.biBitCount < 32 )
+        {
+            // Traditional 1-bit mask
+            bpl = ( rec.width + 31 ) / 32 * 4;
+            buf = new unsigned char[ bpl ];
+            for ( unsigned y = rec.height; y--; )
+            {
+                stream.readRawData( reinterpret_cast< char* >( buf ), bpl );
+                QRgb* p = reinterpret_cast< QRgb* >( lines[ y ] );
+                for ( unsigned x = 0; x < rec.width; ++x, ++p )
+                    if ( ( ( buf[ x / 8 ] >> ( 7 - ( x & 0x07 ) ) ) & 1 ) )
+                        *p &= RGB_MASK;
+            }
+            delete[] buf;
+        }
+        return true;
+    }
+}
+
+ICOHandler::ICOHandler()
+{
+}
+
+bool ICOHandler::canRead() const
+{
+    return canRead(device());
+}
+
+bool ICOHandler::read(QImage *outImage)
+{
+
+    qint64 offset = device()->pos();
+
+    QDataStream stream( device() );
+    stream.setByteOrder( QDataStream::LittleEndian );
+    IcoHeader header;
+    stream >> header;
+    if ( stream.atEnd() || !header.count ||
+         ( header.type != IcoHeader::Icon && header.type != IcoHeader::Cursor) )
+        return false;
+
+    unsigned requestedSize = 32;
+    unsigned requestedColors =  QApplication::desktop()->depth() > 8 ? 0 : QApplication::desktop()->depth();
+    int requestedIndex = -1;
+#if 0
+    if ( io->parameters() )
+    {
+        QStringList params = QString(io->parameters()).split( ';', QString::SkipEmptyParts );
+        QMap< QString, QString > options;
+        for ( QStringList::ConstIterator it = params.begin();
+              it != params.end(); ++it )
+        {
+            QStringList tmp = (*it).split( '=', QString::SkipEmptyParts );
+            if ( tmp.count() == 2 ) options[ tmp[ 0 ] ] = tmp[ 1 ];
+        }
+        if ( options[ "index" ].toUInt() )
+            requestedIndex = options[ "index" ].toUInt();
+        if ( options[ "size" ].toUInt() )
+            requestedSize = options[ "size" ].toUInt();
+        if ( options[ "colors" ].toUInt() )
+            requestedColors = options[ "colors" ].toUInt();
+    }
+#endif
+
+    typedef std::vector< IconRec > IconList;
+    IconList icons;
+    for ( unsigned i = 0; i < header.count; ++i )
+    {
+        if ( stream.atEnd() )
+            return false;
+        IconRec rec;
+        stream >> rec;
+        icons.push_back( rec );
+    }
+    IconList::const_iterator selected;
+    if (requestedIndex >= 0) {
+        selected = std::min( icons.begin() + requestedIndex, icons.end() );
+    } else {
+        selected = std::min_element( icons.begin(), icons.end(),
+                                     LessDifference( requestedSize, requestedColors ) );
+    }
+    if ( stream.atEnd() || selected == icons.end() ||
+         offset + selected->offset > device()->size() )
+        return false;
+
+    device()->seek( offset + selected->offset );
+    QImage icon;
+    if ( loadFromDIB( stream, *selected, icon ) )
+    {
+        icon.setText( "X-Index", 0, QString::number( selected - icons.begin() ) );
+        if ( header.type == IcoHeader::Cursor )
+        {
+            icon.setText( "X-HotspotX", 0, QString::number( selected->hotspotX ) );
+            icon.setText( "X-HotspotY", 0, QString::number( selected->hotspotY ) );
+        }
+
+        *outImage = icon;
+        return true;
+    }
+    return false;
+}
+
+bool ICOHandler::write(const QImage &/*image*/)
+{
+#if 0
+    if (image.isNull())
+        return;
+
+    QByteArray dibData;
+    QDataStream dib(dibData, QIODevice::ReadWrite);
+    dib.setByteOrder(QDataStream::LittleEndian);
+
+    QImage pixels = image;
+    QImage mask;
+    if (io->image().hasAlphaBuffer())
+        mask = image.createAlphaMask();
+    else
+        mask = image.createHeuristicMask();
+    mask.invertPixels();
+    for ( int y = 0; y < pixels.height(); ++y )
+        for ( int x = 0; x < pixels.width(); ++x )
+            if ( mask.pixel( x, y ) == 0 ) pixels.setPixel( x, y, 0 );
+
+    if (!qt_write_dib(dib, pixels))
+        return;
+
+   uint hdrPos = dib.device()->at();
+    if (!qt_write_dib(dib, mask))
+        return;
+    memmove(dibData.data() + hdrPos, dibData.data() + hdrPos + BMP_WIN + 8, dibData.size() - hdrPos - BMP_WIN - 8);
+    dibData.resize(dibData.size() - BMP_WIN - 8);
+
+    QDataStream ico(device());
+    ico.setByteOrder(QDataStream::LittleEndian);
+    IcoHeader hdr;
+    hdr.reserved = 0;
+    hdr.type = Icon;
+    hdr.count = 1;
+    ico << hdr.reserved << hdr.type << hdr.count;
+    IconRec rec;
+    rec.width = image.width();
+    rec.height = image.height();
+    if (image.numColors() <= 16)
+        rec.colors = 16;
+    else if (image.depth() <= 8)
+        rec.colors = 256;
+    else
+        rec.colors = 0;
+    rec.hotspotX = 0;
+    rec.hotspotY = 0;
+    rec.dibSize = dibData.size();
+    ico << rec.width << rec.height << rec.colors
+        << rec.hotspotX << rec.hotspotY << rec.dibSize;
+    rec.dibOffset = ico.device()->at() + sizeof(rec.dibOffset);
+    ico << rec.dibOffset;
+
+    BMP_INFOHDR dibHeader;
+    dib.device()->at(0);
+    dib >> dibHeader;
+    dibHeader.biHeight = image.height() << 1;
+    dib.device()->at(0);
+    dib << dibHeader;
+
+    ico.writeRawBytes(dibData.data(), dibData.size());
+    return true;
+#endif
+    return false;
+}
+
+QByteArray ICOHandler::name() const
+{
+    return "ico";
+}
+
+bool ICOHandler::canRead(QIODevice *device)
+{
+    if (!device) {
+        qWarning("ICOHandler::canRead() called with no device");
+        return false;
+    }
+
+    const qint64 oldPos = device->pos();
+
+    char head[8];
+    qint64 readBytes = device->read(head, sizeof(head));
+    const bool readOk = readBytes == sizeof(head);
+
+    if (device->isSequential()) {
+        while (readBytes > 0)
+            device->ungetChar(head[readBytes-- - 1]);
+    } else {
+        device->seek(oldPos);
+    }
+
+    if ( !readOk )
+        return false;
+
+    return head[2] == '\001' && head[3] == '\000' && // type should be 1
+        ( head[6] == 16 || head[6] == 32 || head[6] == 64 ) && // width can only be one of those
+        ( head[7] == 16 || head[7] == 32 || head[7] == 64 );   // same for height
+}
+
+class ICOPlugin : public QImageIOPlugin
+{
+public:
+    QStringList keys() const;
+    Capabilities capabilities(QIODevice *device, const QByteArray &format) const;
+    QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const;
+};
+
+QStringList ICOPlugin::keys() const
+{
+    return QStringList() << "ico" << "ICO";
+}
+
+QImageIOPlugin::Capabilities ICOPlugin::capabilities(QIODevice *device, const QByteArray &format) const
+{
+    if (format == "ico" || format == "ICO")
+        return Capabilities(CanRead);
+    if (!format.isEmpty())
+        return 0;
+    if (!device->isOpen())
+        return 0;
+
+    Capabilities cap;
+    if (device->isReadable() && ICOHandler::canRead(device))
+        cap |= CanRead;
+    return cap;
+}
+
+QImageIOHandler *ICOPlugin::create(QIODevice *device, const QByteArray &format) const
+{
+    QImageIOHandler *handler = new ICOHandler;
+    handler->setDevice(device);
+    handler->setFormat(format);
+    return handler;
+}
+
+Q_EXPORT_STATIC_PLUGIN(ICOPlugin)
+Q_EXPORT_PLUGIN2(qtwebico, ICOPlugin)
diff --git a/WebKitQt/Plugins/ICOHandler.h b/WebKitQt/Plugins/ICOHandler.h
new file mode 100644 (file)
index 0000000..4f1f1d6
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * ico.h - kimgio import filter for MS Windows .ico files
+ *
+ * Distributed under the terms of the LGPL
+ * Copyright (c) 2000 Malte Starostik <malte@kde.org>
+ *
+ */
+
+// You can use QImageIO::setParameters() to request a specific
+// Icon out of an .ico file:
+//
+// Options consist of a name=value pair and are separated by a semicolon.
+// Available options are:
+//     size=<size>   select the icon that most closely matches <size> (pixels)
+//                   default: 32
+//     colors=<num>  select the icon that has <num> colors (or comes closest)
+//                   default: 1 << display depth or 0 (RGB) if display depth > 8
+//     index=<index> select the indexth icon from the file. If this option
+//                   is present, the size and colors options will be ignored.
+//                   default: none
+// If both size and colors are given, size takes precedence.
+//
+// The old format is still supported:
+//     the parameters consist of a single string in the form
+//     "<size>[:<colors>]" which correspond to the options above
+//
+// If an icon was returned (i.e. the file is valid and the index option
+// if present was not out of range), the icon's index within the .ico
+// file is returned in the text tag "X-Index" of the image.
+// If the icon is in fact a cursor, its hotspot coordinates are returned
+// in the text tags "X-HotspotX" and "X-HotspotY".
+
+#ifndef _ICOHANDLER_H_
+#define _ICOHANDLER_H_
+
+#include <QtGui/QImageIOPlugin>
+
+class ICOHandler : public QImageIOHandler
+{
+public:
+    ICOHandler();
+
+    bool canRead() const;
+    bool read(QImage *image);
+    bool write(const QImage &image);
+
+    QByteArray name() const;
+
+    static bool canRead(QIODevice *device);
+};
+
+#endif
diff --git a/WebKitQt/Plugins/Plugins.pro b/WebKitQt/Plugins/Plugins.pro
new file mode 100644 (file)
index 0000000..20e8a3b
--- /dev/null
@@ -0,0 +1,7 @@
+TEMPLATE = lib
+TARGET = qtwebico
+CONFIG += static plugin
+HEADERS += ICOHandler.h
+SOURCES += ICOHandler.cpp
+
+include(../../WebKit.pri)
index a99771a..6884abf 100644 (file)
@@ -587,7 +587,9 @@ String FrameLoaderClientQt::userAgent(const KURL&)
 
 void FrameLoaderClientQt::dispatchDidReceiveIcon()
 {
-    notImplemented();
+    if (m_webFrame) {
+        emit m_webFrame->page()->iconLoaded();
+    }
 }
 
 void FrameLoaderClientQt::frameLoaderDestroyed()