~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/css/CSSCursorImageValue.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2006 Rob Buis <buis@kde.org>
 
3
 *           (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
 
4
 * Copyright (C) 2008 Apple Inc. All rights reserved.
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Library General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Library General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Library General Public License
 
17
 * along with this library; see the file COPYING.LIB.  If not, write to
 
18
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
19
 * Boston, MA 02110-1301, USA.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
#include "CSSCursorImageValue.h"
 
24
 
 
25
#include "CachedResourceLoader.h"
 
26
#include "TreeScope.h"
 
27
#include "WebCoreMemoryInstrumentation.h"
 
28
#include <wtf/MathExtras.h>
 
29
#include <wtf/MemoryInstrumentationHashSet.h>
 
30
#include <wtf/UnusedParam.h>
 
31
#include <wtf/text/WTFString.h>
 
32
 
 
33
#if ENABLE(SVG)
 
34
#include "SVGCursorElement.h"
 
35
#include "SVGLengthContext.h"
 
36
#include "SVGNames.h"
 
37
#include "SVGURIReference.h"
 
38
#endif
 
39
 
 
40
namespace WebCore {
 
41
 
 
42
#if ENABLE(SVG)
 
43
static inline bool isSVGCursorIdentifier(const String& url)
 
44
{
 
45
    KURL kurl(ParsedURLString, url);
 
46
    return kurl.hasFragmentIdentifier();
 
47
}
 
48
 
 
49
static inline SVGCursorElement* resourceReferencedByCursorElement(const String& url, Document* document)
 
50
{
 
51
    Element* element = SVGURIReference::targetElementFromIRIString(url, document);
 
52
    if (element && element->hasTagName(SVGNames::cursorTag))
 
53
        return static_cast<SVGCursorElement*>(element);
 
54
 
 
55
    return 0;
 
56
}
 
57
#endif
 
58
 
 
59
CSSCursorImageValue::CSSCursorImageValue(const String& url, bool hasHotSpot, const IntPoint& hotSpot)
 
60
    : CSSImageValue(CursorImageClass, url)
 
61
    , m_hasHotSpot(hasHotSpot)
 
62
    , m_hotSpot(hotSpot)
 
63
{
 
64
}
 
65
 
 
66
CSSCursorImageValue::~CSSCursorImageValue()
 
67
{
 
68
#if ENABLE(SVG)
 
69
    if (!isSVGCursorIdentifier(url()))
 
70
        return;
 
71
 
 
72
    HashSet<SVGElement*>::const_iterator it = m_referencedElements.begin();
 
73
    HashSet<SVGElement*>::const_iterator end = m_referencedElements.end();
 
74
 
 
75
    for (; it != end; ++it) {
 
76
        SVGElement* referencedElement = *it;
 
77
        referencedElement->cursorImageValueRemoved();
 
78
        if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url(), referencedElement->document()))
 
79
            cursorElement->removeClient(referencedElement);
 
80
    }
 
81
#endif
 
82
}
 
83
 
 
84
String CSSCursorImageValue::customCssText() const
 
85
{
 
86
    StringBuilder result;
 
87
    result.append(CSSImageValue::customCssText());
 
88
    if (m_hasHotSpot) {
 
89
        result.append(' ');
 
90
        result.appendNumber(m_hotSpot.x());
 
91
        result.append(' ');
 
92
        result.appendNumber(m_hotSpot.y());
 
93
    }
 
94
    return result.toString();
 
95
}
 
96
 
 
97
bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element)
 
98
{
 
99
#if !ENABLE(SVG)
 
100
    UNUSED_PARAM(element);
 
101
#else
 
102
    if (!element || !element->isSVGElement())
 
103
        return false;
 
104
 
 
105
    if (!isSVGCursorIdentifier(url()))
 
106
        return false;
 
107
 
 
108
    if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url(), element->document())) {
 
109
        // FIXME: This will override hot spot specified in CSS, which is probably incorrect.
 
110
        SVGLengthContext lengthContext(0);
 
111
        m_hasHotSpot = true;
 
112
        float x = roundf(cursorElement->x().value(lengthContext));
 
113
        m_hotSpot.setX(static_cast<int>(x));
 
114
 
 
115
        float y = roundf(cursorElement->y().value(lengthContext));
 
116
        m_hotSpot.setY(static_cast<int>(y));
 
117
 
 
118
        if (cachedImageURL() != element->document()->completeURL(cursorElement->href()))
 
119
            clearCachedImage();
 
120
 
 
121
        SVGElement* svgElement = static_cast<SVGElement*>(element);
 
122
        m_referencedElements.add(svgElement);
 
123
        svgElement->setCursorImageValue(this);
 
124
        cursorElement->addClient(svgElement);
 
125
        return true;
 
126
    }
 
127
#endif
 
128
 
 
129
    return false;
 
130
}
 
131
 
 
132
StyleCachedImage* CSSCursorImageValue::cachedImage(CachedResourceLoader* loader)
 
133
{
 
134
#if ENABLE(SVG)
 
135
    if (isSVGCursorIdentifier(url()) && loader && loader->document()) {
 
136
        // FIXME: This will fail if the <cursor> element is in a shadow DOM (bug 59827)
 
137
        if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url(), loader->document()))
 
138
            return CSSImageValue::cachedImage(loader, cursorElement->href(), cursorElement);
 
139
    }
 
140
#endif
 
141
 
 
142
    return CSSImageValue::cachedImage(loader, url());
 
143
}
 
144
 
 
145
#if ENABLE(SVG)
 
146
void CSSCursorImageValue::removeReferencedElement(SVGElement* element)
 
147
{
 
148
    m_referencedElements.remove(element);
 
149
}
 
150
#endif
 
151
 
 
152
void CSSCursorImageValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 
153
{
 
154
    MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
 
155
    CSSImageValue::reportDescendantMemoryUsage(memoryObjectInfo);
 
156
#if ENABLE(SVG)
 
157
    info.addMember(m_referencedElements);
 
158
#endif
 
159
}
 
160
 
 
161
} // namespace WebCore