⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 render_replaced.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
public:    static const int maxPixelBuffering = 320*200;    static const int leaseTime = 20*1000;    static QPixmap *grab( QSize s = QSize() ) {        if (!m_inst)            m_inst = new PaintBuffer;        return m_inst->getBuf( s );    }    static void release() { m_inst->m_grabbed = false; }protected:    PaintBuffer(): m_overflow(false), m_grabbed(false),                   m_timer(0), m_resetWidth(0), m_resetHeight(0) {};    void timerEvent(QTimerEvent* e) {        assert( m_timer == e->timerId() );        if (m_grabbed)            return;        m_buf.resize(m_resetWidth, m_resetHeight);        m_resetWidth = m_resetHeight = 0;        killTimer( m_timer );        m_timer = 0;    }    QPixmap *getBuf( QSize s ) {        assert( !m_grabbed );        if (s.isEmpty())            return 0;        m_grabbed = true;        bool cur_overflow = false;        int nw = kMax(m_buf.width(), s.width());        int nh = kMax(m_buf.height(), s.height());        if (!m_overflow && (nw*nh > maxPixelBuffering))            cur_overflow = true;        if (nw != m_buf.width() || nh != m_buf.height())            m_buf.resize(nw, nh);        if (cur_overflow) {            m_overflow = true;            m_timer = startTimer( leaseTime );        } else if (m_overflow) {            if( s.width()*s.height() > maxPixelBuffering ) {                killTimer( m_timer );                m_timer = startTimer( leaseTime );            } else {                if (s.width() > m_resetWidth)                    m_resetWidth = s.width();                if (s.height() > m_resetHeight)                    m_resetHeight = s.height();            }        }        return &m_buf;    }private:    static PaintBuffer* m_inst;    QPixmap m_buf;    bool m_overflow;    bool m_grabbed;    int m_timer;    int m_resetWidth;    int m_resetHeight;};PaintBuffer *PaintBuffer::m_inst = 0;static void copyWidget(const QRect& r, QPainter *p, QWidget *widget, int tx, int ty){    if (r.isNull() || r.isEmpty() )        return;    QRegion blit(r);    QValueVector<QWidget*> cw;    QValueVector<QRect> cr;    if (widget->children()) {        // build region        QObjectListIterator it = *widget->children();        for (; it.current(); ++it) {            QWidget* const w = ::qt_cast<QWidget *>(it.current());	    if ( w && !w->isTopLevel() && !w->isHidden()) {	        QRect r2 = w->geometry();	        blit -= r2;	        r2 = r2.intersect( r );	        r2.moveBy(-w->x(), -w->y());	        cr.append(r2);	        cw.append(w);            }        }    }    QMemArray<QRect> br = blit.rects();    const int cnt = br.size();    const bool external = p->device()->isExtDev();    QPixmap* const pm = PaintBuffer::grab( widget->size() );    if (!pm)    {        kdWarning(6040) << "Rendering widget [ " << widget->className() << " ] failed due to invalid size." << endl;        return;    }    // fill background    if ( external ) {	// even hackier!        QPainter pt( pm );        const QColor c = widget->colorGroup().base();        for (int i = 0; i < cnt; ++i)            pt.fillRect( br[i], c );    } else {        QRect dr;        for (int i = 0; i < cnt; ++i ) {            dr = br[i];	    dr.moveBy( tx, ty );	    dr = p->xForm( dr );	    bitBlt(pm, br[i].topLeft(), p->device(), dr);        }    }    // send paint event    QPainter::redirect(widget, pm);    QPaintEvent e( r, false );    QApplication::sendEvent( widget, &e );    QPainter::redirect(widget, 0);    // transfer result    if ( external )        for ( int i = 0; i < cnt; ++i )            p->drawPixmap(QPoint(tx+br[i].x(), ty+br[i].y()), *pm, br[i]);    else        for ( int i = 0; i < cnt; ++i )            bitBlt(p->device(), p->xForm( QPoint(tx, ty) + br[i].topLeft() ), pm, br[i]);    // cleanup and recurse    PaintBuffer::release();    QValueVector<QWidget*>::iterator cwit = cw.begin();    QValueVector<QWidget*>::iterator cwitEnd = cw.end();    QValueVector<QRect>::const_iterator crit = cr.begin();    for (; cwit != cwitEnd; ++cwit, ++crit)        copyWidget(*crit, p, *cwit, tx+(*cwit)->x(), ty+(*cwit)->y());}void RenderWidget::paintWidget(PaintInfo& pI, QWidget *widget, int tx, int ty){    QPainter* const p = pI.p;    allowWidgetPaintEvents = true;    const bool dsbld = QSharedDoubleBuffer::isDisabled();    QSharedDoubleBuffer::setDisabled(true);    QRect rr = pI.r;    rr.moveBy(-tx, -ty);    const QRect r = widget->rect().intersect( rr );    copyWidget(r, p, widget, tx, ty);    QSharedDoubleBuffer::setDisabled(dsbld);#ifdef Q_WS_QWS    // This breaks the widget z-order, but it allows the view to work without    // the WPaintUnclipped hack    allowWidgetPaintEvents = true;#else    allowWidgetPaintEvents = false;#endif}bool RenderWidget::eventFilter(QObject* /*o*/, QEvent* e){    // no special event processing if this is a frame (in which case KHTMLView handles it all)    if ( ::qt_cast<KHTMLView *>( m_widget ) )        return false;    if ( !element() ) return true;    ref();    element()->ref();    bool filtered = false;    //kdDebug() << "RenderWidget::eventFilter type=" << e->type() << endl;    switch(e->type()) {    case QEvent::FocusOut:        // Don't count popup as a valid reason for losing the focus        // (example: opening the options of a select combobox shouldn't emit onblur)        if ( QFocusEvent::reason() != QFocusEvent::Popup )            handleFocusOut();        break;    case QEvent::FocusIn:        //kdDebug(6000) << "RenderWidget::eventFilter captures FocusIn" << endl;        element()->getDocument()->setFocusNode(element());//         if ( isEditable() ) {//             KHTMLPartBrowserExtension *ext = static_cast<KHTMLPartBrowserExtension *>( element()->view->part()->browserExtension() );//             if ( ext )  ext->editableWidgetFocused( m_widget );//         }        break;    case QEvent::KeyPress:    case QEvent::KeyRelease:    // TODO this seems wrong - Qt events are not correctly translated to DOM ones,    // like in KHTMLView::dispatchKeyEvent()        if (element()->dispatchKeyEvent(static_cast<QKeyEvent*>(e),false))            filtered = true;        break;    case QEvent::Wheel:        if (widget()->parentWidget() == view()->viewport()) {            // don't allow the widget to react to wheel event unless its            // currently focused. this avoids accidentally changing a select box            // or something while wheeling a webpage.            if (qApp->focusWidget() != widget() &&                widget()->focusPolicy() <= QWidget::StrongFocus)  {                static_cast<QWheelEvent*>(e)->ignore();                QApplication::sendEvent(view(), e);                filtered = true;            }        }        break;    default:        break;    };    element()->deref();    // stop processing if the widget gets deleted, but continue in all other cases    if (hasOneRef())        filtered = true;    deref();    return filtered;}void RenderWidget::EventPropagator::sendEvent(QEvent *e) {    switch(e->type()) {    case QEvent::MouseButtonPress:        mousePressEvent(static_cast<QMouseEvent *>(e));        break;    case QEvent::MouseButtonRelease:        mouseReleaseEvent(static_cast<QMouseEvent *>(e));        break;    case QEvent::MouseButtonDblClick:        mouseDoubleClickEvent(static_cast<QMouseEvent *>(e));        break;    case QEvent::MouseMove:        mouseMoveEvent(static_cast<QMouseEvent *>(e));        break;    case QEvent::KeyPress:        keyPressEvent(static_cast<QKeyEvent *>(e));        break;    case QEvent::KeyRelease:        keyReleaseEvent(static_cast<QKeyEvent *>(e));        break;    default:        break;    }}bool RenderWidget::handleEvent(const DOM::EventImpl& ev){    bool ret = false;    switch(ev.id()) {    case EventImpl::MOUSEDOWN_EVENT:    case EventImpl::MOUSEUP_EVENT:    case EventImpl::MOUSEMOVE_EVENT: {        const MouseEventImpl &me = static_cast<const MouseEventImpl &>(ev);        QMouseEvent* const qme = me.qEvent();        int absx = 0;        int absy = 0;        absolutePosition(absx, absy);        const QPoint p(me.clientX() - absx + m_view->contentsX(),                 me.clientY() - absy + m_view->contentsY());        QMouseEvent::Type type;        int button = 0;        int state = 0;        if (qme) {            button = qme->button();            state = qme->state();            type = qme->type();        } else {            switch(me.id())  {            case EventImpl::MOUSEDOWN_EVENT:                type = QMouseEvent::MouseButtonPress;                break;            case EventImpl::MOUSEUP_EVENT:                type = QMouseEvent::MouseButtonRelease;                break;            case EventImpl::MOUSEMOVE_EVENT:            default:                type = QMouseEvent::MouseMove;                break;            }            switch (me.button()) {            case 0:                button = LeftButton;                break;            case 1:                button = MidButton;                break;            case 2:                button = RightButton;                break;            default:                break;            }            if (me.ctrlKey())                state |= ControlButton;            if (me.altKey())                state |= AltButton;            if (me.shiftKey())                state |= ShiftButton;            if (me.metaKey())                state |= MetaButton;        }//     kdDebug(6000) << "sending event to widget "//                   << " pos=" << p << " type=" << type//                   << " button=" << button << " state=" << state << endl;        QMouseEvent e(type, p, button, state);        static_cast<EventPropagator *>(m_widget)->sendEvent(&e);        ret = e.isAccepted();        break;    }    case EventImpl::KEYDOWN_EVENT:        // do nothing; see the mapping table below        break;    case EventImpl::KEYUP_EVENT: {        QKeyEvent* const ke = static_cast<const TextEventImpl &>(ev).qKeyEvent();        static_cast<EventPropagator *>(m_widget)->sendEvent(ke);        ret = ke->isAccepted();        break;    }    case EventImpl::KEYPRESS_EVENT: {        // See KHTMLView::dispatchKeyEvent: autorepeat is just keypress in the DOM        // but it's keyrelease+keypress in Qt. So here we do the inverse mapping as        // the one done in KHTMLView: generate two events for one DOM auto-repeat keypress.        // Similarly, DOM keypress events with non-autorepeat Qt event do nothing here,        // because the matching Qt keypress event was already sent from DOM keydown event.        // Reverse drawing as the one in KHTMLView:        //  DOM:   Down      Press   |       Press                             |     Up        //  Qt:    (nothing) Press   | Release(autorepeat) + Press(autorepeat) |   Release        //        // Qt::KeyPress is sent for DOM keypress and not DOM keydown to allow        // sites to block a key with onkeypress, #99749        QKeyEvent* const ke = static_cast<const TextEventImpl &>(ev).qKeyEvent();        if (ke->isAutoRepeat()) {            QKeyEvent releaseEv( QEvent::KeyRelease, ke->key(), ke->ascii(), ke->state(),                               ke->text(), ke->isAutoRepeat(), ke->count() );            static_cast<EventPropagator *>(m_widget)->sendEvent(&releaseEv);        }        static_cast<EventPropagator *>(m_widget)->sendEvent(ke);        ret = ke->isAccepted();	break;    }    case EventImpl::MOUSEOUT_EVENT: {	QEvent moe( QEvent::Leave );	QApplication::sendEvent(m_widget, &moe);	break;    }    case EventImpl::MOUSEOVER_EVENT: {	QEvent moe( QEvent::Enter );	QApplication::sendEvent(m_widget, &moe);	view()->part()->resetHoverText();	break;    }    default:        break;    }    return ret;}void RenderWidget::deref(){    if (_ref) _ref--;//     qDebug( "deref(%p): width get count is %d", this, _ref);    if (!_ref)        arenaDelete(renderArena());}FindSelectionResult RenderReplaced::checkSelectionPoint(int _x, int _y, int _tx, int _ty, DOM::NodeImpl*& node, int &offset, SelPointState &){#if 0    kdDebug(6040) << "RenderReplaced::checkSelectionPoint(_x="<<_x<<",_y="<<_y<<",_tx="<<_tx<<",_ty="<<_ty<<")" << endl                    << "xPos: " << xPos() << " yPos: " << yPos() << " width: " << width() << " height: " << height() << endl                << "_ty + yPos: " << (_ty + yPos()) << " + height: " << (_ty + yPos() + height()) << "; _tx + xPos: " << (_tx + xPos()) << " + width: " << (_tx + xPos() + width()) << endl;#endif    node = element();    offset = 0;    if ( _y < _ty + yPos() )        return SelectionPointBefore; // above -> before    if ( _y > _ty + yPos() + height() ) {        // below -> after        // Set the offset to the max        offset = 1;        return SelectionPointAfter;    }    if ( _x > _tx + xPos() + width() ) {        // to the right        // ### how to regard bidi in replaced elements? (LS)        offset = 1;        return SelectionPointAfterInLine;    }    // The Y matches, check if we're on the left    if ( _x < _tx + xPos() ) {        // ### how to regard bidi in replaced elements? (LS)        return SelectionPointBeforeInLine;    }    offset = _x > _tx + xPos() + width()/2;    return SelectionPointInside;}#ifdef ENABLE_DUMPvoid RenderWidget::dump(QTextStream &stream, const QString &ind) const{    RenderReplaced::dump(stream,ind);    if ( widget() )        stream << " color=" << widget()->foregroundColor().name()               << " bg=" << widget()->backgroundColor().name();    else        stream << " null widget";}#endif#include "render_replaced.moc"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -