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

📄 html_imageimpl.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**
 * This file is part of the DOM implementation for KDE.
 *
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 * Copyright (C) 2004 Apple Computer, Inc.
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "html/html_imageimpl.h"
#include "html/html_formimpl.h"
#include "html/html_documentimpl.h"

#include "misc/htmlhashes.h"
#include "khtmlview.h"
#include "khtml_part.h"

#include <kstringhandler.h>
#include <kglobal.h>
#include <kdebug.h>

#include "rendering/render_image.h"
#include "rendering/render_flow.h"
#include "css/cssstyleselector.h"
#include "css/cssproperties.h"
#include "css/cssvalues.h"
#include "css/csshelper.h"
#include "xml/dom2_eventsimpl.h"

#include <qstring.h>
#include <qpoint.h>
#include <qregion.h>
#include <qptrstack.h>
#include <qimage.h>
#include <qpointarray.h>

using namespace DOM;
using namespace khtml;

//#define INSTRUMENT_LAYOUT_SCHEDULING 1

HTMLImageLoader::HTMLImageLoader(ElementImpl* elt)
:m_element(elt), m_image(0), m_firedLoad(true), m_imageComplete(true)
{
}

HTMLImageLoader::~HTMLImageLoader()
{
    if (m_image)
        m_image->deref(this);
    if (m_element->getDocument())
        m_element->getDocument()->removeImage(this);
}

void HTMLImageLoader::updateFromElement()
{
    // If we're not making renderers for the page, then don't load images.  We don't want to slow
    // down the raw HTML parsing case by loading images we don't intend to display.
    if (!element()->getDocument()->renderer())
        return;

    AtomicString attr;
    if (element()->id() == ID_OBJECT)
        attr = element()->getAttribute(ATTR_DATA);
    else
        attr = element()->getAttribute(ATTR_SRC);
    
    // Treat a lack of src or empty string for src as no image at all.
    CachedImage* newImage = 0;
    if (!attr.isEmpty())
        newImage = element()->getDocument()->docLoader()->requestImage(khtml::parseURL(attr));

    if (newImage != m_image) {
        m_firedLoad = false;
        m_imageComplete = false;
        CachedImage* oldImage = m_image;
        m_image = newImage;
        if (m_image)
            m_image->ref(this);
        if (oldImage)
            oldImage->deref(this);
    }
#if APPLE_CHANGES
    khtml::RenderImage *renderer = static_cast<khtml::RenderImage*>(element()->renderer());
    if (renderer)
        renderer->resetAnimation();
#endif
}

void HTMLImageLoader::dispatchLoadEvent()
{
    if (!m_firedLoad) {
        m_firedLoad = true;
        if (m_image->isErrorImage())
            element()->dispatchHTMLEvent(EventImpl::ERROR_EVENT, false, false);
        else
            element()->dispatchHTMLEvent(EventImpl::LOAD_EVENT, false, false);
    }
}

void HTMLImageLoader::notifyFinished(CachedObject* image)
{
    m_imageComplete = true;
    DocumentImpl* document = element()->getDocument();
    if (document) {
        document->dispatchImageLoadEventSoon(this);
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
        if (!document->ownerElement())
            printf("Image loaded at %d\n", element()->getDocument()->elapsedTime());
#endif
    }
    if (element()->renderer()) {
        RenderImage* imageObj = static_cast<RenderImage*>(element()->renderer());
        imageObj->setImage(m_image);
    }
}

// -------------------------------------------------------------------------

HTMLImageElementImpl::HTMLImageElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
    : HTMLElementImpl(doc), m_imageLoader(this), ismap(false), m_form(f)
{
    if (m_form)
        m_form->registerImgElement(this);
}

HTMLImageElementImpl::~HTMLImageElementImpl()
{
    if (m_form)
        m_form->removeImgElement(this);
}

NodeImpl::Id HTMLImageElementImpl::id() const
{
    return ID_IMG;
}

bool HTMLImageElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
{
    switch(attr)
    {
        case ATTR_WIDTH:
        case ATTR_HEIGHT:
        case ATTR_VSPACE:
        case ATTR_HSPACE:
        case ATTR_VALIGN:
            result = eUniversal;
            return false;
        case ATTR_BORDER:
        case ATTR_ALIGN:
            result = eReplaced; // Shared with embeds and iframes
            return false;
        default:
            break;
    }

    return HTMLElementImpl::mapToEntry(attr, result);
}

void HTMLImageElementImpl::parseHTMLAttribute(HTMLAttributeImpl *attr)
{
    switch (attr->id())
    {
    case ATTR_ALT:
        if (m_render) static_cast<RenderImage*>(m_render)->updateAltText();
        break;
    case ATTR_SRC:
        m_imageLoader.updateFromElement();
        break;
    case ATTR_WIDTH:
        addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
        break;
    case ATTR_HEIGHT:
        addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
        break;
    case ATTR_BORDER:
        // border="noborder" -> border="0"
        if(attr->value().toInt()) {
            addCSSLength(attr, CSS_PROP_BORDER_WIDTH, attr->value());
            addCSSProperty(attr, CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID);
            addCSSProperty(attr, CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
            addCSSProperty(attr, CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
            addCSSProperty(attr, CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
        }
        break;
    case ATTR_VSPACE:
        addCSSLength(attr, CSS_PROP_MARGIN_TOP, attr->value());
        addCSSLength(attr, CSS_PROP_MARGIN_BOTTOM, attr->value());
        break;
    case ATTR_HSPACE:
        addCSSLength(attr, CSS_PROP_MARGIN_LEFT, attr->value());
        addCSSLength(attr, CSS_PROP_MARGIN_RIGHT, attr->value());
        break;
    case ATTR_ALIGN:
        addHTMLAlignment(attr);
	break;
    case ATTR_VALIGN:
        addCSSProperty(attr, CSS_PROP_VERTICAL_ALIGN, attr->value());
        break;
    case ATTR_USEMAP:
        if ( attr->value().domString()[0] == '#' )
            usemap = attr->value();
        else {
            QString url = getDocument()->completeURL( khtml::parseURL( attr->value() ).string() );
            // ### we remove the part before the anchor and hope
            // the map is on the same html page....
            usemap = url;
        }
        m_hasAnchor = !attr->isNull();
    case ATTR_ISMAP:
        ismap = true;
        break;
    case ATTR_ONABORT: // ### add support for this
        setHTMLEventListener(EventImpl::ABORT_EVENT,
	    getDocument()->createHTMLEventListener(attr->value().string(), this));
        break;
    case ATTR_ONERROR:
        setHTMLEventListener(EventImpl::ERROR_EVENT,
	    getDocument()->createHTMLEventListener(attr->value().string(), this));
        break;
    case ATTR_ONLOAD:
        setHTMLEventListener(EventImpl::LOAD_EVENT,
	    getDocument()->createHTMLEventListener(attr->value().string(), this));
        break;
    case ATTR_NOSAVE:
	break;
#if APPLE_CHANGES
    case ATTR_COMPOSITE:
        _compositeOperator = attr->value().string();
        break;
#endif
    case ATTR_NAME:
	{
	    QString newNameAttr = attr->value().string();
	    if (attached() && getDocument()->isHTMLDocument()) {
		HTMLDocumentImpl *document = static_cast<HTMLDocumentImpl *>(getDocument());
		document->removeNamedImageOrForm(oldNameAttr);
		document->addNamedImageOrForm(newNameAttr);
	    }
	    oldNameAttr = newNameAttr;
	}
	break;
    case ATTR_ID:
	{
	    QString newIdAttr = attr->value().string();
	    if (attached() && getDocument()->isHTMLDocument()) {
		HTMLDocumentImpl *document = static_cast<HTMLDocumentImpl *>(getDocument());
		document->removeNamedImageOrForm(oldIdAttr);
		document->addNamedImageOrForm(newIdAttr);
	    }
	    oldIdAttr = newIdAttr;
	}
	// fall through
    default:
        HTMLElementImpl::parseHTMLAttribute(attr);
    }
}

DOMString HTMLImageElementImpl::altText() const
{
    // lets figure out the alt text.. magic stuff
    // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
    // also heavily discussed by Hixie on bugzilla
    DOMString alt( getAttribute( ATTR_ALT ) );
    // fall back to title attribute
    if ( alt.isNull() )
        alt = getAttribute( ATTR_TITLE );
#if 0
    if ( alt.isNull() ) {
        QString p = KURL( getDocument()->completeURL( getAttribute(ATTR_SRC).string() ) ).prettyURL();
        int pos;
        if ( ( pos = p.findRev( '.' ) ) > 0 )
            p.truncate( pos );
        alt = DOMString( KStringHandler::csqueeze( p ) );
    }
#endif

    return alt;
}

RenderObject *HTMLImageElementImpl::createRenderer(RenderArena *arena, RenderStyle *style)
{

⌨️ 快捷键说明

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