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

📄 render_replaced.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/** * This file is part of the HTML widget for KDE. * * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) * Copyright (C) 2000-2003 Dirk Mueller (mueller@kde.org) * Copyright (C) 2003 Apple Computer, Inc. * Copyright (C) 2004 Germain Garand (germain@ebooksfrance.org) * * 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 "render_replaced.h"#include "render_canvas.h"#include "render_line.h"#include "render_arena.h"#include <assert.h>#include <qwidget.h>#include <qpainter.h>#include <qevent.h>#include <qapplication.h>#include <qlineedit.h>#include <kglobalsettings.h>#include <qobjectlist.h>#include <qvaluevector.h>#include "khtml_ext.h"#include "khtmlview.h"#include "xml/dom2_eventsimpl.h"#include "khtml_part.h"#include "xml/dom_docimpl.h"#include <kdebug.h>bool khtml::allowWidgetPaintEvents = false;using namespace khtml;using namespace DOM;RenderReplaced::RenderReplaced(DOM::NodeImpl* node)    : RenderBox(node){    // init RenderObject attributes    setReplaced(true);    m_intrinsicWidth = 200;    m_intrinsicHeight = 150;}void RenderReplaced::calcMinMaxWidth(){    KHTMLAssert( !minMaxKnown());#ifdef DEBUG_LAYOUT    kdDebug( 6040 ) << "RenderReplaced::calcMinMaxWidth() known=" << minMaxKnown() << endl;#endif    m_width = calcReplacedWidth();    m_width = calcBoxWidth( m_width );    if ( style()->width().isPercent() || style()->height().isPercent() || 		    style()->maxWidth().isPercent() || style()->maxHeight().isPercent() ||		    style()->minWidth().isPercent() || style()->minHeight().isPercent() ) {        m_minWidth = 0;        m_maxWidth = m_width;    }    else        m_minWidth = m_maxWidth = m_width;    setMinMaxKnown();}void RenderReplaced::position(InlineBox* box, int /*from*/, int /*len*/, bool /*reverse*/){    setPos( box->xPos(), box->yPos() );}// -----------------------------------------------------------------------------RenderWidget::RenderWidget(DOM::NodeImpl* node)        : RenderReplaced(node){    m_widget = 0;    // a widget doesn't support being anonymous    assert(!isAnonymous());    m_view = node->getDocument()->view();    m_resizePending = false;    m_discardResizes = false;    // this is no real reference counting, its just there    // to make sure that we're not deleted while we're recursed    // in an eventFilter of the widget    ref();}void RenderWidget::detach(){    remove();    deleteInlineBoxes();    if ( m_widget ) {        if ( m_view ) {            m_view->setWidgetVisible(this, false);            m_view->removeChild( m_widget );        }        m_widget->removeEventFilter( this );        m_widget->setMouseTracking( false );    }    deref();}RenderWidget::~RenderWidget(){    KHTMLAssert( refCount() <= 0 );    if(m_widget) {        m_widget->hide();        m_widget->deleteLater();    }}class QWidgetResizeEvent : public QEvent{public:    enum { Type = QEvent::User + 0xbee };    QWidgetResizeEvent( int _w,  int _h ) :        QEvent( ( QEvent::Type ) Type ),  w( _w ), h( _h ) {}    int w;    int h;};void  RenderWidget::resizeWidget( int w, int h ){    // ugly hack to limit the maximum size of the widget ( as X11 has problems if    // its bigger )    h = kMin( h, 3072 );    w = kMin( w, 2000 );    if (m_widget->width() != w || m_widget->height() != h) {        m_resizePending = !strcmp(m_widget->name(), "__khtml");        ref();        element()->ref();        QApplication::postEvent( this, new QWidgetResizeEvent( w, h ) );        element()->deref();        deref();    }}void RenderWidget::cancelPendingResize(){    if (!m_widget)        return;    m_discardResizes = true;    QApplication::sendPostedEvents(this, QWidgetResizeEvent::Type);    m_discardResizes = false;}bool RenderWidget::event( QEvent *e ){    if ( m_widget && (e->type() == (QEvent::Type)QWidgetResizeEvent::Type) ) {        m_resizePending = false;        if (m_discardResizes)            return true;        QWidgetResizeEvent *re = static_cast<QWidgetResizeEvent *>(e);        m_widget->resize( re->w,  re->h );        repaint();    }    // eat all events - except if this is a frame (in which case KHTMLView handles it all)    if ( ::qt_cast<KHTMLView *>( m_widget ) )        return QObject::event( e );    return true;}void RenderWidget::flushWidgetResizes() //static{    QApplication::sendPostedEvents( 0, QWidgetResizeEvent::Type );}void RenderWidget::setQWidget(QWidget *widget){    if (widget != m_widget)    {        if (m_widget) {            m_widget->removeEventFilter(this);            disconnect( m_widget, SIGNAL( destroyed()), this, SLOT( slotWidgetDestructed()));            delete m_widget;            m_widget = 0;        }        m_widget = widget;        if (m_widget) {            connect( m_widget, SIGNAL( destroyed()), this, SLOT( slotWidgetDestructed()));            m_widget->installEventFilter(this);            if ( !strcmp(m_widget->name(), "__khtml") && !::qt_cast<QFrame*>(m_widget))                m_widget->setBackgroundMode( QWidget::NoBackground );            if (m_widget->focusPolicy() > QWidget::StrongFocus)                m_widget->setFocusPolicy(QWidget::StrongFocus);            // if we've already received a layout, apply the calculated space to the            // widget immediately, but we have to have really been full constructed (with a non-null            // style pointer).            if (!needsLayout() && style()) {                resizeWidget( m_width-borderLeft()-borderRight()-paddingLeft()-paddingRight(),                              m_height-borderTop()-borderBottom()-paddingTop()-paddingBottom() );            }            else                setPos(xPos(), -500000);        }        m_view->setWidgetVisible(this, false);        m_view->addChild( m_widget, 0, -500000);        if ( m_widget ) m_widget->hide();        m_resizePending = false;    }}void RenderWidget::layout( ){    KHTMLAssert( needsLayout() );    KHTMLAssert( minMaxKnown() );    if ( m_widget )        resizeWidget( m_width-borderLeft()-borderRight()-paddingLeft()-paddingRight(),                      m_height-borderTop()-borderBottom()-paddingTop()-paddingBottom() );    setNeedsLayout(false);}void RenderWidget::updateFromElement(){    if (m_widget) {        // Color:        QColor color = style()->color();        QColor backgroundColor = style()->backgroundColor();        if ( color.isValid() || backgroundColor.isValid() ) {            QPalette pal(QApplication::palette(m_widget));            int contrast_ = KGlobalSettings::contrast();            int highlightVal = 100 + (2*contrast_+4)*16/10;            int lowlightVal = 100 + (2*contrast_+4)*10;            if (backgroundColor.isValid()) {                if (strcmp(widget()->name(), "__khtml"))                    widget()->setEraseColor(backgroundColor );                for ( int i = 0; i < QPalette::NColorGroups; ++i ) {                    pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Background, backgroundColor );                    pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Light, backgroundColor.light(highlightVal) );                    pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Dark, backgroundColor.dark(lowlightVal) );                    pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Mid, backgroundColor.dark(120) );                    pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Midlight, backgroundColor.light(110) );                    pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Button, backgroundColor );                    pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Base, backgroundColor );            }            }            if ( color.isValid() ) {                struct ColorSet {                    QPalette::ColorGroup cg;                    QColorGroup::ColorRole cr;                };                const struct ColorSet toSet [] = {                    { QPalette::Active, QColorGroup::Foreground },                    { QPalette::Active, QColorGroup::ButtonText },                    { QPalette::Active, QColorGroup::Text },                    { QPalette::Inactive, QColorGroup::Foreground },                    { QPalette::Inactive, QColorGroup::ButtonText },                    { QPalette::Inactive, QColorGroup::Text },                    { QPalette::Disabled,QColorGroup::ButtonText },                    { QPalette::NColorGroups, QColorGroup::NColorRoles },                };                const ColorSet *set = toSet;                while( set->cg != QPalette::NColorGroups ) {                    pal.setColor( set->cg, set->cr, color );                    ++set;                }                QColor disfg = color;                int h, s, v;                disfg.hsv( &h, &s, &v );                if (v > 128)                    // dark bg, light fg - need a darker disabled fg                    disfg = disfg.dark(lowlightVal);                else if (disfg != Qt::black)                    // light bg, dark fg - need a lighter disabled fg - but only if !black                    disfg = disfg.light(highlightVal);                else                    // black fg - use darkgray disabled fg                    disfg = Qt::darkGray;                pal.setColor(QPalette::Disabled,QColorGroup::Foreground,disfg);            }            m_widget->setPalette(pal);        }        else            m_widget->unsetPalette();        // Border:        QFrame* frame = ::qt_cast<QFrame*>(m_widget);        if (frame) {            if (shouldPaintBackgroundOrBorder())            {                frame->setFrameShape(QFrame::NoFrame);            }        }    }    RenderReplaced::updateFromElement();}void RenderWidget::slotWidgetDestructed(){    if (m_view)       m_view->setWidgetVisible(this, false);    m_widget = 0;}void RenderWidget::setStyle(RenderStyle *_style){    RenderReplaced::setStyle(_style);    if(m_widget)    {        m_widget->setFont(style()->font());        if (style()->visibility() != VISIBLE) {            if (m_view)                m_view->setWidgetVisible(this, false);            m_widget->hide();        }    }    // Don't paint borders if the border-style is native    // or borders are not supported on this widget    if (!canHaveBorder() ||        (style()->borderLeftStyle()   == BNATIVE &&         style()->borderRightStyle()  == BNATIVE &&         style()->borderTopStyle()    == BNATIVE &&         style()->borderBottomStyle() == BNATIVE))    {        setShouldPaintBackgroundOrBorder(false);    }}void RenderWidget::paint(PaintInfo& paintInfo, int _tx, int _ty){    _tx += m_x;    _ty += m_y;     if (shouldPaintBackgroundOrBorder() &&           (paintInfo.phase == PaintActionChildBackground || paintInfo.phase == PaintActionChildBackgrounds))        paintBoxDecorations(paintInfo, _tx, _ty);    if (!m_widget || !m_view || paintInfo.phase != PaintActionForeground)        return;    // not visible or not even once layouted    if (style()->visibility() != VISIBLE || m_y <= -500000 || m_resizePending )        return;    if ( (_ty > paintInfo.r.bottom()) || (_ty + m_height <= paintInfo.r.top()) ||         (_tx + m_width <= paintInfo.r.left()) || (_tx > paintInfo.r.right()) )        return;    int xPos = _tx+borderLeft()+paddingLeft();    int yPos = _ty+borderTop()+paddingTop();    bool khtmlw = !strcmp(m_widget->name(), "__khtml");    int childw = m_widget->width();    int childh = m_widget->height();    if ( (childw == 2000 || childh == 3072) && m_widget->inherits( "KHTMLView" ) ) {        KHTMLView *vw = static_cast<KHTMLView *>(m_widget);        int cy = m_view->contentsY();        int ch = m_view->visibleHeight();        int childx = m_view->childX( m_widget );        int childy = m_view->childY( m_widget );        int xNew = xPos;        int yNew = childy;        //         qDebug("cy=%d, ch=%d, childy=%d, childh=%d", cy, ch, childy, childh );        if ( childh == 3072 ) {            if ( cy + ch > childy + childh ) {                yNew = cy + ( ch - childh )/2;            } else if ( cy < childy ) {                yNew = cy + ( ch - childh )/2;            }//             qDebug("calculated yNew=%d", yNew);        }        yNew = kMin( yNew, yPos + m_height - childh );        yNew = kMax( yNew, yPos );        if ( yNew != childy || xNew != childx ) {            if ( vw->contentsHeight() < yNew - yPos + childh )                vw->resizeContents( vw->contentsWidth(), yNew - yPos + childh );            vw->setContentsPos( xNew - xPos, yNew - yPos );        }        xPos = xNew;        yPos = yNew;    }    m_view->setWidgetVisible(this, true);    m_view->addChild(m_widget, xPos, yPos );    m_widget->show();    if (khtmlw)        paintWidget(paintInfo, m_widget, xPos, yPos);}#include <private/qinternal_p.h>// The PaintBuffer class provides a shared buffer for widget painting.//// It will grow to encompass the biggest widget encountered, in order to avoid// constantly resizing.// When it grows over maxPixelBuffering, it periodically checks if such a size// is still needed.  If not, it shrinks down to the biggest size < maxPixelBuffering// that was requested during the overflow lapse.class PaintBuffer: public QObject{

⌨️ 快捷键说明

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