📄 loader.cpp
字号:
c->setPixmap( pixmap(), valid_rect(), this); if(!m_loading) c->notifyFinished(this);}void CachedImage::deref( CachedObjectClient *c ){#ifdef CACHE_DEBUG kdDebug( 6060 ) << this << " CachedImage::deref(" << c << ") " << endl;#endif Cache::flush(); CachedObject::deref(c); if(m && m_clients.isEmpty() && m->running()) m->pause(); if ( canDelete() && m_free ) delete this;}#define BGMINWIDTH 32#define BGMINHEIGHT 32const QPixmap &CachedImage::tiled_pixmap(const QColor& newc){#if APPLE_CHANGES return pixmap(); #else static QRgb bgTransparant = qRgba( 0, 0, 0, 0xFF ); if ( (bgColor != bgTransparant) && (bgColor != newc.rgb()) ) { delete bg; bg = 0; } if (bg) return *bg; const QPixmap &r = pixmap(); if (r.isNull()) return r; // no error indication for background images if(errorOccured) return *Cache::nullPixmap; bool isvalid = newc.isValid(); QSize s(pixmap_size()); int w = r.width(); int h = r.height(); if ( w*h < 8192 ) { if ( r.width() < BGMINWIDTH ) w = ((BGMINWIDTH / s.width())+1) * s.width(); if ( r.height() < BGMINHEIGHT ) h = ((BGMINHEIGHT / s.height())+1) * s.height(); } if ( (w != r.width()) || (h != r.height()) || (isvalid && r.mask())) { QPixmap pix = r; if ( w != r.width() || (isvalid && pix.mask())) { bg = new QPixmap(w, r.height()); QPainter p(bg); if(isvalid) p.fillRect(0, 0, w, r.height(), newc); p.drawTiledPixmap(0, 0, w, r.height(), pix); if(!isvalid && pix.mask()) { // unfortunately our anti-transparency trick doesn't work here // we need to create a mask. QBitmap newmask(w, r.height()); QPainter pm(&newmask); pm.drawTiledPixmap(0, 0, w, r.height(), *pix.mask()); bg->setMask(newmask); bgColor = bgTransparant; } else bgColor= newc.rgb(); pix = *bg; } if ( h != r.height() ) { delete bg; bg = new QPixmap(w, h); QPainter p(bg); if(isvalid) p.fillRect(0, 0, w, h, newc); p.drawTiledPixmap(0, 0, w, h, pix); if(!isvalid && pix.mask()) { // unfortunately our anti-transparency trick doesn't work here // we need to create a mask. QBitmap newmask(w, h); QPainter pm(&newmask); pm.drawTiledPixmap(0, 0, w, h, *pix.mask()); bg->setMask(newmask); bgColor = bgTransparant; } else bgColor= newc.rgb(); } return *bg; } return r;#endif}const QPixmap &CachedImage::pixmap( ) const{ if(errorOccured) return *Cache::brokenPixmap;#if APPLE_CHANGES if (p) return *p;#else if(m) { if(m->framePixmap().size() != m->getValidRect().size() && m->getValidRect().size().isValid()) { // pixmap is not yet completely loaded, so we // return a clipped version. asserting here // that the valid rect is always from 0/0 to fullwidth/ someheight if(!pixPart) pixPart = new QPixmap(m->getValidRect().size()); (*pixPart) = m->framePixmap(); pixPart->resize(m->getValidRect().size()); return *pixPart; } else return m->framePixmap(); } else if(p) return *p;#endif // APPLE_CHANGES return *Cache::nullPixmap;}QSize CachedImage::pixmap_size() const{ return (m ? m->framePixmap().size() : ( p ? p->size() : QSize()));}QRect CachedImage::valid_rect() const{ return m ? m->getValidRect() : ( p ? p->rect() : QRect());}void CachedImage::do_notify(const QPixmap& p, const QRect& r){ CachedObjectClientWalker w(m_clients); while (CachedObjectClient *c = w.next()) c->setPixmap(p, r, this);}#if !APPLE_CHANGESvoid CachedImage::movieUpdated( const QRect& r ){#ifdef CACHE_DEBUG qDebug("movie updated %d/%d/%d/%d, pixmap size %d/%d", r.x(), r.y(), r.right(), r.bottom(), m->framePixmap().size().width(), m->framePixmap().size().height());#endif do_notify(m->framePixmap(), r);}void CachedImage::movieStatus(int status){#ifdef CACHE_DEBUG qDebug("movieStatus(%d)", status);#endif // ### the html image objects are supposed to send the load event after every frame (according to // netscape). We have a problem though where an image is present, and js code creates a new Image object, // which uses the same CachedImage, the one in the document is not supposed to be notified // just another Qt 2.2.0 bug. we cannot call // QMovie::frameImage if we're after QMovie::EndOfMovie if(status == QMovie::EndOfFrame) { const QImage& im = m->frameImage(); monochrome = ( ( im.depth() <= 8 ) && ( im.numColors() - int( im.hasAlphaBuffer() ) <= 2 ) ); for (int i = 0; monochrome && i < im.numColors(); ++i) if (im.colorTable()[i] != qRgb(0xff, 0xff, 0xff) && im.colorTable()[i] != qRgb(0x00, 0x00, 0x00)) monochrome = false; if((im.width() < 5 || im.height() < 5) && im.hasAlphaBuffer()) // only evaluate for small images { QImage am = im.createAlphaMask(); if(am.depth() == 1) { bool solid = false; for(int y = 0; y < am.height(); y++) for(int x = 0; x < am.width(); x++) if(am.pixelIndex(x, y)) { solid = true; break; } isFullyTransparent = (!solid); } } // we have to delete our tiled bg variant here // because the frame has changed (in order to keep it in sync) delete bg; bg = 0; } if((status == QMovie::EndOfMovie && (!m || m->frameNumber() <= 1)) || ((status == QMovie::EndOfLoop) && (m_showAnimations == KHTMLSettings::KAnimationLoopOnce)) || ((status == QMovie::EndOfFrame) && (m_showAnimations == KHTMLSettings::KAnimationDisabled)) ) { if(imgSource) { setShowAnimations( KHTMLSettings::KAnimationDisabled ); // monochrome alphamasked images are usually about 10000 times // faster to draw, so this is worth the hack if (p && monochrome && p->depth() > 1 ) { QPixmap* pix = new QPixmap; pix->convertFromImage( p->convertToImage().convertDepth( 1 ), MonoOnly|AvoidDither ); if ( p->mask() ) pix->setMask( *p->mask() ); delete p; p = pix; monochrome = false; } } CachedObjectClientWalker w(m_clients); while (CachedObjectClient *c = w.next()) c->notifyFinished(this); } if((status == QMovie::EndOfFrame) || (status == QMovie::EndOfMovie)) {#ifdef CACHE_DEBUG QRect r(valid_rect()); qDebug("movie Status frame update %d/%d/%d/%d, pixmap size %d/%d", r.x(), r.y(), r.right(), r.bottom(), pixmap().size().width(), pixmap().size().height());#endif do_notify(pixmap(), valid_rect()); }}void CachedImage::movieResize(const QSize& /*s*/){// do_notify(m->framePixmap(), QRect());}#endif // APPLE_CHANGESvoid CachedImage::setShowAnimations( KHTMLSettings::KAnimationAdvice showAnimations ){ m_showAnimations = showAnimations;#if !APPLE_CHANGES if ( (m_showAnimations == KHTMLSettings::KAnimationDisabled) && imgSource ) { imgSource->cleanBuffer(); delete p; p = new QPixmap(m->framePixmap()); m->disconnectUpdate( this, SLOT( movieUpdated( const QRect &) )); m->disconnectStatus( this, SLOT( movieStatus( int ) )); m->disconnectResize( this, SLOT( movieResize( const QSize& ) ) ); QTimer::singleShot(0, this, SLOT( deleteMovie())); imgSource = 0; }#endif}#if !APPLE_CHANGESvoid CachedImage::deleteMovie(){ delete m; m = 0;}#endif // APPLE_CHANGESvoid CachedImage::clear(){ delete m; m = 0; delete p; p = 0; delete bg; bg = 0;#if !APPLE_CHANGES bgColor = qRgba( 0, 0, 0, 0xff );#endif delete pixPart; pixPart = 0; formatType = 0;#if !APPLE_CHANGES typeChecked = false;#endif setSize(0); // No need to delete imageSource - QMovie does it for us imgSource = 0;}void CachedImage::data ( QBuffer &_buffer, bool eof ){#ifdef CACHE_DEBUG kdDebug( 6060 ) << this << "in CachedImage::data(buffersize " << _buffer.buffer().size() <<", eof=" << eof << endl;#endif#if !APPLE_CHANGES if ( !typeChecked ) { formatType = QImageDecoder::formatName( (const uchar*)_buffer.buffer().data(), _buffer.size()); typeChecked = true; if ( formatType ) // movie format exists { imgSource = new ImageSource( _buffer.buffer()); m = new QMovie( imgSource, 8192 ); m->connectUpdate( this, SLOT( movieUpdated( const QRect &) )); m->connectStatus( this, SLOT( movieStatus(int))); m->connectResize( this, SLOT( movieResize( const QSize& ) ) ); } } if ( imgSource ) { imgSource->setEOF(eof); imgSource->maybeReady(); } if(eof) { // QMovie currently doesn't support all kinds of image formats // so we need to use a QPixmap here when we finished loading the complete // picture and display it then all at once. if(typeChecked && !formatType) {#ifdef CACHE_DEBUG kdDebug(6060) << "CachedImage::data(): reloading as pixmap:" << endl;#endif p = new QPixmap( _buffer.buffer() ); // set size of image.#ifdef CACHE_DEBUG kdDebug(6060) << "CachedImage::data(): image is null: " << p->isNull() << endl;#endif if(p->isNull()) { errorOccured = true; do_notify(pixmap(), QRect(0, 0, 16, 16)); // load "broken image" icon } else do_notify(*p, p->rect()); } QSize s = pixmap_size(); setSize(s.width() * s.height() * 2); }#else // APPLE_CHANGES bool canDraw = false; m_dataSize = _buffer.size(); // If we're at eof and don't have a pixmap yet, the data // must have arrived in one chunk. This avoids the attempt // to perform incremental decoding. if (eof && !p) { p = new QPixmap(_buffer.buffer(), KWQResponseMIMEType(m_response)); canDraw = true; } else { // Always attempt to load the image incrementally. // If the AppKit is unable to decode incrementally this pixmap // will not be renderable until all the data has been received. if (!p) p = new QPixmap(KWQResponseMIMEType(m_response)); canDraw = p->receivedData(_buffer.buffer(), eof); } if (canDraw || eof) { if (p->isNull()) { errorOccured = true; QPixmap ep = pixmap(); do_notify (ep, ep.rect()); Cache::removeCacheEntry (this); } else do_notify(*p, p->rect()); QSize s = pixmap_size(); setSize(s.width() * s.height() * 2); } if (eof) { m_loading = false; checkNotify(); }#endif // APPLE_CHANGES}void CachedImage::error( int /*err*/, const char */*text*/ ){#ifdef CACHE_DEBUG kdDebug(6060) << "CahcedImage::error" << endl;#endif clear();#if !APPLE_CHANGES typeChecked = true;#endif errorOccured = true; do_notify(pixmap(), QRect(0, 0, 16, 16));#if APPLE_CHANGES m_loading = false; checkNotify();#endif}void CachedImage::checkNotify(){ if(m_loading) return; CachedObjectClientWalker w(m_clients); while (CachedObjectClient *c = w.next()) c->notifyFinished(this);}// -------------------------------------------------------------------------------------------#ifndef KHTML_NO_XBLCachedXBLDocument::CachedXBLDocument(DocLoader* dl, const DOMString &url, KIO::CacheControl _cachePolicy, time_t _expireDate): CachedObject(url, XBL, _cachePolicy, _expireDate), m_document(0){ // It's XML we want. setAccept( QString::fromLatin1("text/xml, application/xml, application/xml+xhtml") ); // Load the file Cache::loader()->load(dl, this, false); m_loading = true; m_codec = QTextCodec::codecForName("iso8859-1");}CachedXBLDocument::~CachedXBLDocument(){ if (m_document) m_document->deref();}void CachedXBLDocument::ref(CachedObjectClient *c){ CachedObject::ref(c); if (!m_loading) c->setXBLDocument(m_url, m_document);}void CachedXBLDocument::deref(CachedObjectClient *c){ Cache::flush(); CachedObject::deref(c); if (canDelete() && m_free) delete this;}void CachedXBLDocument::data( QBuffer &buffer, bool eof ){ if (!eof) return; assert(!m_document); m_document = new XBL::XBLDocumentImpl(); m_document->ref(); m_document->open(); QString data = m_codec->toUnicode(buffer.buffer().data(), buffer.buffer().size()); m_document->write(data); setSize(buffer.buffer().size()); buffer.close(); m_document->finishParsing(); m_document->close(); m_loading = false; checkNotify();}void CachedXBLDocument::checkNotify(){ if(m_loading) return; #ifdef CACHE_DEBUG kdDebug( 6060 ) << "CachedXBLDocument:: finishedLoading " << m_url.string() << endl;#endif CachedObjectClientWalker w(m_clients); while (CachedObjectClient *c = w.next()) c->setXBLDocument(m_url, m_document);}void CachedXBLDocument::error( int /*err*/, const char */*text*/ ){ m_loading = false; checkNotify();}#endif// ------------------------------------------------------------------------------------------Request::Request(DocLoader* dl, CachedObject *_object, bool _incremental){ object = _object; object->setRequest(this); incremental = _incremental; m_docLoader = dl;}Request::~Request(){ object->setRequest(0);}// ------------------------------------------------------------------------------------------DocLoader::DocLoader(KHTMLPart* part, DocumentImpl* doc){ m_cachePolicy = KIO::CC_Verify; m_expireDate = 0; m_bautoloadImages = true; m_showAnimations = KHTMLSettings::KAnimationEnabled; m_part = part; m_doc = doc;#if APPLE_CHANGES Cache::init();#endif Cache::docloader->append( this );}DocLoader::~DocLoader(){ Cache::docloader->remove( this );}void DocLoader::setExpireDate(time_t _expireDate){ m_expireDate = _expireDate;}bool DocLoader::needReload(const KURL &fullURL){ bool reload = false; if (m_cachePolicy == KIO::CC_Verify) { if (!m_reloadedURLs.contains(fullURL.url())) { CachedObject *existing = Cache::cache->find(fullURL.url()); if (existing && existing->isExpired()) { Cache::removeCacheEntry(existing); m_reloadedURLs.append(fullURL.url()); reload = true; } } } else if ((m_cachePolicy == KIO::CC_Reload) || (m_cachePolicy == KIO::CC_Refresh)) { if (!m_reloadedURLs.contains(fullURL.url())) { CachedObject *existing = Cache::cache->find(fullURL.url()); if (existing) { Cache::removeCacheEntry(existing);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -