/** * 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, 2005, 2006 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "config.h" #include "HTMLAreaElement.h" #include "Document.h" #include "HTMLNames.h" #include "FloatRect.h" #include "HitTestResult.h" #include "RenderObject.h" using namespace std; namespace WebCore { using namespace HTMLNames; HTMLAreaElement::HTMLAreaElement(Document *doc) : HTMLAnchorElement(areaTag, doc) , m_coords(0) , m_coordsLen(0) , m_lastSize(-1, -1) , m_shape(Unknown) { } HTMLAreaElement::~HTMLAreaElement() { delete [] m_coords; } void HTMLAreaElement::parseMappedAttribute(MappedAttribute *attr) { if (attr->name() == shapeAttr) { if (equalIgnoringCase(attr->value(), "default")) m_shape = Default; else if (equalIgnoringCase(attr->value(), "circle")) m_shape = Circle; else if (equalIgnoringCase(attr->value(), "poly")) m_shape = Poly; else if (equalIgnoringCase(attr->value(), "rect")) m_shape = Rect; } else if (attr->name() == coordsAttr) { delete [] m_coords; m_coords = attr->value().toCoordsArray(m_coordsLen); } else if (attr->name() == altAttr || attr->name() == accesskeyAttr) { // Do nothing. } else HTMLAnchorElement::parseMappedAttribute(attr); } bool HTMLAreaElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestResult& result) { if (m_lastSize != size) { region = getRegion(size); m_lastSize = size; } if (!region.contains(IntPoint(x, y))) return false; result.setInnerNode(this); result.setURLElement(this); return true; } IntRect HTMLAreaElement::getRect(RenderObject* obj) const { int dx, dy; obj->absolutePosition(dx, dy); Path p = getRegion(m_lastSize); p.translate(IntSize(dx, dy)); return enclosingIntRect(p.boundingRect()); } Path HTMLAreaElement::getRegion(const IntSize& size) const { if (!m_coords && m_shape != Default) return Path(); int width = size.width(); int height = size.height(); // If element omits the shape attribute, select shape based on number of coordinates. Shape shape = m_shape; if (shape == Unknown) { if (m_coordsLen == 3) shape = Circle; else if (m_coordsLen == 4) shape = Rect; else if (m_coordsLen >= 6) shape = Poly; } Path path; switch (shape) { case Poly: if (m_coordsLen >= 6) { int numPoints = m_coordsLen / 2; path.moveTo(FloatPoint(m_coords[0].calcMinValue(width), m_coords[1].calcMinValue(height))); for (int i = 1; i < numPoints; ++i) path.addLineTo(FloatPoint(m_coords[i * 2].calcMinValue(width), m_coords[i * 2 + 1].calcMinValue(height))); path.closeSubpath(); } break; case Circle: if (m_coordsLen >= 3) { Length radius = m_coords[2]; int r = min(radius.calcMinValue(width), radius.calcMinValue(height)); path.addEllipse(FloatRect(m_coords[0].calcMinValue(width) - r, m_coords[1].calcMinValue(height) - r, 2 * r, 2 * r)); } break; case Rect: if (m_coordsLen >= 4) { int x0 = m_coords[0].calcMinValue(width); int y0 = m_coords[1].calcMinValue(height); int x1 = m_coords[2].calcMinValue(width); int y1 = m_coords[3].calcMinValue(height); path.addRect(FloatRect(x0, y0, x1 - x0, y1 - y0)); } break; case Default: path.addRect(FloatRect(0, 0, width, height)); break; case Unknown: break; } return path; } String HTMLAreaElement::accessKey() const { return getAttribute(accesskeyAttr); } void HTMLAreaElement::setAccessKey(const String& value) { setAttribute(accesskeyAttr, value); } String HTMLAreaElement::alt() const { return getAttribute(altAttr); } void HTMLAreaElement::setAlt(const String& value) { setAttribute(altAttr, value); } String HTMLAreaElement::coords() const { return getAttribute(coordsAttr); } void HTMLAreaElement::setCoords(const String& value) { setAttribute(coordsAttr, value); } String HTMLAreaElement::href() const { return document()->completeURL(getAttribute(hrefAttr)); } void HTMLAreaElement::setHref(const String& value) { setAttribute(hrefAttr, value); } bool HTMLAreaElement::noHref() const { return !getAttribute(nohrefAttr).isNull(); } void HTMLAreaElement::setNoHref(bool noHref) { setAttribute(nohrefAttr, noHref ? "" : 0); } String HTMLAreaElement::shape() const { return getAttribute(shapeAttr); } void HTMLAreaElement::setShape(const String& value) { setAttribute(shapeAttr, value); } void HTMLAreaElement::setTabIndex(int tabIndex) { setAttribute(tabindexAttr, String::number(tabIndex)); } String HTMLAreaElement::target() const { return getAttribute(targetAttr); } void HTMLAreaElement::setTarget(const String& value) { setAttribute(targetAttr, value); } }