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

📄 html_imageimpl.cpp

📁 monqueror一个很具有参考价值的源玛
💻 CPP
字号:
/** * 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) * * 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. * * $Id: html_imageimpl.cpp,v 1.2 2002/01/28 04:31:02 leon Exp $ */#include <qstring.h>#include <qpoint.h>#include <qregion.h>#include <qstack.h>#include <qmap.h>#include "render_interface.h"#include "html_imageimpl.h"#include "htmlhashes.h"#include "mghtmlview.h"#include "kdebug.h"#include "render_image.h"#include "cssstyleselector.h"#include "cssproperties.h"#include "csshelper.h"#include "html_documentimpl.h"using namespace DOM;using namespace khtml;// -------------------------------------------------------------------------// -------------------------------------------------------------------------HTMLImageElementImpl::HTMLImageElementImpl(DocumentImpl *doc)    : HTMLElementImpl(doc){    ismap = false;}HTMLImageElementImpl::~HTMLImageElementImpl(){}// DOM relatedconst DOMString HTMLImageElementImpl::nodeName() const{    return "IMG";}ushort HTMLImageElementImpl::id() const{    return ID_IMG;}bool HTMLImageElementImpl::mouseEvent( int _x, int _y, int button, MouseEventType type,                                       int _tx, int _ty, DOMString &url,                                       NodeImpl *&innerNode, long &offset){    //kdDebug( 6030 ) << "_x=" << _x << " _tx=" << _tx << " _y=" << _y << ", _ty=" << _ty << endl;    if (usemap.length()>0)    {	if(m_render->parent()->isAnonymousBox())	{	    //kdDebug( 6030 ) << "parent is anonymous!" << endl;	    // we need to add the offset of the anonymous box	    _tx += m_render->parent()->xPos();	    _ty += m_render->parent()->yPos();	}        //cout << "usemap: " << usemap.string() << endl;        HTMLMapElementImpl* map;    	if ( (map = HTMLMapElementImpl::getMap(usemap))!=0)	{	    //kdDebug( 6030 ) << "have map" << endl;            return map->mapMouseEvent(_x-renderer()->xPos()-_tx,                                      _y-renderer()->yPos()-_ty,                                      renderer()->width(), renderer()->height(), button, type, url);	}    }    return HTMLElementImpl::mouseEvent(_x, _y, button, type, _tx, _ty, url, innerNode, offset);}void HTMLImageElementImpl::parseAttribute(AttrImpl *attr){    switch (attr->attrId)    {    case ATTR_SRC:	imageURL = khtml::parseURL(attr->value());	break;    case ATTR_WIDTH:        addCSSLength(CSS_PROP_WIDTH, attr->value(), false);	break;    case ATTR_HEIGHT:        addCSSLength(CSS_PROP_HEIGHT, attr->value(), false);	break;    case ATTR_BORDER:	addCSSLength(CSS_PROP_BORDER_WIDTH, attr->value(), false);        addCSSProperty(CSS_PROP_BORDER_STYLE, "solid", false);	break;    case ATTR_VSPACE:	addCSSLength(CSS_PROP_MARGIN_TOP, attr->value(), false);	addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value(), false);	break;    case ATTR_HSPACE:	addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value(), false);	addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value(), false);	break;    case ATTR_ALIGN:	// vertical alignment with respect to the current baseline of the text	// right or left means floating images	if ( strcasecmp( attr->value(), "left" ) == 0 )	{	    addCSSProperty(CSS_PROP_FLOAT, attr->value(), false);	    addCSSProperty(CSS_PROP_VERTICAL_ALIGN, "top", false);	}	else if ( strcasecmp( attr->value(), "right" ) == 0 )	{	    addCSSProperty(CSS_PROP_FLOAT, attr->value(), false);	    addCSSProperty(CSS_PROP_VERTICAL_ALIGN, "top", false);	}	else	    addCSSProperty(CSS_PROP_VERTICAL_ALIGN, attr->value(), false);	break;    case ATTR_VALIGN:    	    addCSSProperty(CSS_PROP_VERTICAL_ALIGN, attr->value(), false);	break;    case ATTR_USEMAP:	if ( attr->value()[0] == '#' )	{	    usemap = attr->value();	}	else	{	    // ### we remove the part before the anchor and hope the map is on the same html page....	    KURL u( static_cast<HTMLDocumentImpl *>(document)->baseURL().string(), attr->value().string() );	    usemap = khtml::parseURL(u.url());	}    case ATTR_ISMAP:	ismap = true;	break;    case ATTR_ALT:	alt = attr->value();	break;    default:	HTMLElementImpl::parseAttribute(attr);    }}void HTMLImageElementImpl::attach(MGHTMLView *w){//fprintf(stderr,"HTMLImageElementImpl %p parent:%p\n",this,_parent);    //kdDebug( 6030 ) << "HTMLImageImpl::attach" << endl;    m_style = document->styleSelector()->styleForElement(this, w->part());    khtml::RenderObject *r = _parent->renderer();    if(r)    {	RenderImage *renderImage = new RenderImage();    renderImage->setPart (w->part());	renderImage->setStyle(m_style);	renderImage->setAlt(alt);	m_render = renderImage;//fprintf(stderr,"HTMLImageElementImpl m_render:%p r:%p\n",m_render,r);	if(m_render) r->addChild(m_render, _next ? _next->renderer() : 0);	renderImage->setImageUrl(imageURL, static_cast<HTMLDocumentImpl *>(document)->baseURL(),	                         static_cast<HTMLDocumentImpl *>(document)->docLoader());    }    NodeBaseImpl::attach( w );}void HTMLImageElementImpl::applyChanges(bool top, bool force){    //kdDebug(0) << "Image::applyChanges(" << top << ", " << force <<")" << endl;    if(force || changed()) {	recalcStyle();    }    HTMLElementImpl::applyChanges(top,force);    // ### perhaps not the most appropriate place for this.... here so it get's called after    // a script has executed#if 0 	// just because: it's conflicted while loading an outside CSS file.    if (m_render)	static_cast<RenderImage *>(m_render)	    ->setImageUrl(imageURL, static_cast<HTMLDocumentImpl *>(document)->baseURL(),	                  static_cast<HTMLDocumentImpl *>(document)->docLoader());#endif		setChanged(false);}void HTMLImageElementImpl::recalcStyle(){    HTMLElementImpl::recalcStyle();}bool HTMLImageElementImpl::isServerMap() const{  if ( ismap && !usemap.length() )    return true;  else    return false;}// -------------------------------------------------------------------------QMap<QString,HTMLMapElementImpl*> *HTMLMapElementImpl::mapMap = 0;void HTMLMapElementImpl::clear(){    delete mapMap;    mapMap = 0;}HTMLMapElementImpl::HTMLMapElementImpl(DocumentImpl *doc) : HTMLElementImpl(doc){    if(!mapMap) mapMap = new QMap<QString, HTMLMapElementImpl *>();}HTMLMapElementImpl::~HTMLMapElementImpl(){    HTMLMapElementImpl::mapMap->remove(name);}const DOMString HTMLMapElementImpl::nodeName() const{    return "MAP";}ushort HTMLMapElementImpl::id() const{    return ID_MAP;}boolHTMLMapElementImpl::mapMouseEvent(int x_, int y_, int width_, int height_,    	int button_, MouseEventType type_, DOMString& url_){    //cout << "map:mapMouseEvent " << endl;    //cout << x_ << " " << y_ <<" "<< width_ <<" "<< height_ << endl;    bool inside = false;    QStack<NodeImpl> nodeStack;    NodeImpl *current = firstChild();    while(1)    {	if(!current)	{	    if(nodeStack.isEmpty()) break;	    current = nodeStack.pop();	    current = current->nextSibling();	    continue;	}	if(current->id()==ID_AREA)	{	    //cout << "area found " << endl;	    HTMLAreaElementImpl* area=static_cast<HTMLAreaElementImpl*>(current);	    if (area->mapMouseEvent(x_,y_,width_,height_,button_,type_,url_))	    	inside = true;	}	NodeImpl *child = current->firstChild();	if(child)	{	    nodeStack.push(current);	    current = child;	}	else	{	    current = current->nextSibling();	}    }    return inside;}HTMLMapElementImpl*HTMLMapElementImpl::getMap(const DOMString& _url){    // ### should we allow maps from other urls too???    QString url = _url.string();    QString s;    int pos = url.find('#');    //kdDebug(0) << "map pos of #:" << pos << endl;    s = QString(_url.unicode() + pos + 1, _url.length() - pos - 1);    if (mapMap && mapMap->contains(s))	return (*mapMap)[s];    else	return 0;}void HTMLMapElementImpl::parseAttribute(AttrImpl *attr){    switch (attr->attrId)    {    case ATTR_NAME:    {	DOMString s = attr->value();	if(*s.unicode() == '#')	    name = QString(s.unicode()+1, s.length()-1);	else	    name = s.string();	(*mapMap)[name] = this;	break;    }    default:	HTMLElementImpl::parseAttribute(attr);    }}// -------------------------------------------------------------------------HTMLAreaElementImpl::HTMLAreaElementImpl(DocumentImpl *doc)    : HTMLElementImpl(doc){    coords=0L;    href = 0;    target = 0;    shape = Unknown;    lasth = lastw = -1;}HTMLAreaElementImpl::~HTMLAreaElementImpl(){    if( href ) href->deref();    if( target ) target->deref();    if (coords)    	delete coords;}const DOMString HTMLAreaElementImpl::nodeName() const{    return "AREA";}ushort HTMLAreaElementImpl::id() const{    return ID_AREA;}void HTMLAreaElementImpl::parseAttribute(AttrImpl *attr){    switch (attr->attrId)    {    case ATTR_SHAPE:	if ( strcasecmp( attr->value(), "default" ) == 0 )	    shape = Default;	else if ( strcasecmp( attr->value(), "circle" ) == 0 )	    shape = Circle;	else if ( strcasecmp( attr->value(), "poly" ) == 0 )	    shape = Poly;	else if ( strcasecmp( attr->value(), "rect" ) == 0 )	    shape = Rect;	break;    case ATTR_COORDS:    	coords = attr->val()->toLengthList();	break;    case ATTR_NOHREF:	break;    case ATTR_HREF:    {        DOMString s = khtml::parseURL(attr->val());        href = s.implementation();        if(href) href->ref();        break;    }    case ATTR_TARGET:    	target = attr->val();        target->ref();	break;    case ATTR_ALT:	break;    case ATTR_ACCESSKEY:	break;    default:	HTMLElementImpl::parseAttribute(attr);    }}boolHTMLAreaElementImpl::mapMouseEvent(int x_, int y_, int width_, int height_,				   int button, MouseEventType type, DOMString& url_){    //cout << "area:mapMouseEvent " << endl;    bool inside = false;    if (width_ != lastw || height_ != lasth)    {    	region=getRegion(width_, height_);	lastw=width_; lasth=height_;    }    if (region.contains(QPoint(x_,y_)))    {        //cout << "region hit, url " << QConstString(href->s, href->l).string() << endl;    	inside = true;	if(target && href)	{	    DOMString s = DOMString("target://") + DOMString(target) + DOMString("/#") + DOMString(href);	    url_ = s;	}	else	    url_ = href;    }    // dynamic HTML...    if(inside || mouseInside()) mouseEventHandler(button, type, inside);    return inside;}QRegion HTMLAreaElementImpl::getRegion(int width_, int height_){    QRegion region;    if (!coords)    	return region;    // added broken HTML support (Dirk): some pages omit the SHAPE    // attribute, so we try to guess by looking at the coords count    // what the HTML author tried to tell us.    // a Poly needs at least 3 points (6 coords), so this is correct    // just ignore poly's with 2 points or less, because    // QRegion will anyway crash on them.	/*	// TODO    if ((shape==Poly || shape==Unknown) && coords->count() > 4)    {        //cout << " poly " << endl;	bool xcoord=true;	int xx = 0, yy = 0; // shut up egcs...	int i=0;	QListIterator<Length> it(*coords);	QPointArray points(it.count()/2);	for ( ; it.current(); ++it ) {	    Length* len = it.current();	    if (xcoord)	    {		xx = len->minWidth(width_);		xcoord = false;	    } else {		yy = len->minWidth(height_);		xcoord = true;		points.setPoint(i,xx,yy);		i++;	    }	}	region = QRegion(points);    }    else*/ if (shape==Circle && coords->count()>=3 || shape==Unknown && coords->count() == 3)    {    	//cout << " circle " << endl;    	int cx = coords->at(0)->minWidth(width_);	int cy = coords->at(1)->minWidth(height_);	int r1 = coords->at(2)->minWidth(width_);	int r2 = coords->at(2)->minWidth(height_);	int r  = QMIN(r1, r2);    	region = QRegion(cx-r, cy-r, 2*r, 2*r,QRegion::Ellipse);    }    else if (shape==Rect && coords->count()>=4 || shape==Unknown && coords->count() == 4)    {        //cout << " rect " << endl;    	int x0 = coords->at(0)->minWidth(width_);	int y0 = coords->at(1)->minWidth(height_);	int x1 = coords->at(2)->minWidth(width_);	int y1 = coords->at(3)->minWidth(height_);    	region = QRegion(x0,y0,x1-x0,y1-y0);    }    else /*if (shape==Default || shape == Unknown)*/ {        //cout << "default/unknown" << endl;    	region = QRegion(0,0,width_,height_);    }    return region;}

⌨️ 快捷键说明

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