source: webkit/trunk/Source/WebCore/rendering/RenderEmbeddedObject.cpp

Last change on this file was 295410, checked in by [email protected], 3 years ago

Cache system font shorthand information
https://bugs.webkit.org/show_bug.cgi?id=241404

Reviewed by Cameron McCormack.

This is the fourth piece of https://bugs.webkit.org/show_bug.cgi?id=237817.

System font shorthands are things like "font: caption" or "font: -apple-system-body".

There used to be a cache that was supposed to map each shorthand value to a CTFontDescriptor.
However, the cache didn't work, so I deleted it in
https://github.com/WebKit/WebKit/commit/6ead5274db5f92656360fa1fbae3e0091481fc4f. This patch
reimplements it, but does so in platform/graphics/SystemFontDatabase, which is the natural
place to put it.

One of the repercussions of putting it in platform/ is that it can't use real CSSValuesIDs
as keys into the cache (because it's a layering violation to make things in platform/ see
CSS things). Therefore, this patch creates its own enum, which lives in platform/, which
conveniently exactly matches the relevant values from CSSValueID.

The Cocoa ports already have a SystemFontDatabaseCoreText which does similar things, but this
new cache is not platform-specific, so I'm putting it in SystemFontDatabase instead of
SystemFontDatabaseCoreText. SystemFontDatabaseCoreText will now inherit from SystemFontDatabase,
with 0 virtual methods. I've also taken the existing code that populates the previous cache
and temporarily duplicated it in SystemFontDabase*.cpp to make it populate this cache.

This patch doesn't actually _call_ the new cache, because doing so is somewhat complicated and
deserves its own patch. This patch just implements the cache itself. Also, because callers
aren't migrated to use this new cache yet, this patch doesn't delete the old cache either.
Both of those things will come in a follow-up patch.

  • Source/WebCore/PAL/pal/spi/cf/CoreTextSPI.h:
  • Source/WebCore/PlatformPlayStation.cmake:
  • Source/WebCore/PlatformWin.cmake:
  • Source/WebCore/Sources.txt:
  • Source/WebCore/SourcesCocoa.txt:
  • Source/WebCore/SourcesGTK.txt:
  • Source/WebCore/WebCore.xcodeproj/project.pbxproj:
  • Source/WebCore/platform/graphics/SystemFontDatabase.cpp: Added.

(WebCore::SystemFontDatabase::systemFontShorthandInfo const):
(WebCore::SystemFontDatabase::systemFontShorthandFamily):
(WebCore::SystemFontDatabase::systemFontShorthandSize):
(WebCore::SystemFontDatabase::systemFontShorthandWeight):
(WebCore::SystemFontDatabase::clear):

  • Source/WebCore/platform/graphics/SystemFontDatabase.h: Added.
  • Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:

(WebCore::normalizeCTWeight):
(WebCore::denormalizeCTWeight):

  • Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.h:
  • Source/WebCore/platform/graphics/cocoa/SystemFontDatabaseCocoa.mm: Added.

(WebCore::cocoaFontClass):
(WebCore::SystemFontDatabaseCoreText::smallCaptionFontDescriptor):
(WebCore::SystemFontDatabaseCoreText::menuFontDescriptor):
(WebCore::SystemFontDatabaseCoreText::statusBarFontDescriptor):
(WebCore::SystemFontDatabaseCoreText::miniControlFontDescriptor):
(WebCore::SystemFontDatabaseCoreText::smallControlFontDescriptor):
(WebCore::SystemFontDatabaseCoreText::controlFontDescriptor):

  • Source/WebCore/platform/graphics/cocoa/SystemFontDatabaseCoreText.cpp:

(WebCore::SystemFontDatabase::singleton):
(WebCore::SystemFontDatabaseCoreText::clear):
(WebCore::cssWeightOfSystemFontDescriptor):
(WebCore::SystemFontDatabase::platformSystemFontShorthandInfo):

  • Source/WebCore/platform/graphics/cocoa/SystemFontDatabaseCoreText.h:
  • Source/WebCore/platform/graphics/gtk/SystemFontDatabaseGTK.cpp: Added.

(WebCore::SystemFontDatabase::singleton):
(WebCore::SystemFontDatabase::platformSystemFontShorthandInfo):

  • Source/WebCore/platform/graphics/playstation/SystemFontDatabasePlayStation.cpp: Added.

(WebCore::SystemFontDatabase::singleton):
(WebCore::SystemFontDatabase::platformSystemFontShorthandInfo):

  • Source/WebCore/platform/graphics/win/SystemFontDatabaseWin.cpp: Added.

(WebCore::SystemFontDatabase::singleton):
(WebCore::SystemFontDatabase::platformSystemFontShorthandInfo):

  • Source/WebCore/rendering/RenderEmbeddedObject.cpp:

(WebCore::RenderEmbeddedObject::getReplacementTextGeometry const):

Canonical link: https://commits.webkit.org/251416@main

  • Property svn:eol-style set to native
File size: 17.2 KB
Line 
1/*
2 * Copyright (C) 1999 Lars Knoll ([email protected])
3 * (C) 2000 Simon Hausmann <[email protected]>
4 * (C) 2000 Stefan Schimanski ([email protected])
5 * Copyright (C) 2004-2022 Apple Inc. All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include "config.h"
25#include "RenderEmbeddedObject.h"
26
27#include "CSSValueKeywords.h"
28#include "Chrome.h"
29#include "ChromeClient.h"
30#include "Cursor.h"
31#include "EventHandler.h"
32#include "EventNames.h"
33#include "FontCascade.h"
34#include "FontSelector.h"
35#include "Frame.h"
36#include "FrameLoaderClient.h"
37#include "GraphicsContext.h"
38#include "HTMLEmbedElement.h"
39#include "HTMLNames.h"
40#include "HTMLObjectElement.h"
41#include "HTMLParamElement.h"
42#include "HTMLPlugInElement.h"
43#include "HitTestResult.h"
44#include "LocalizedStrings.h"
45#include "MouseEvent.h"
46#include "Page.h"
47#include "PaintInfo.h"
48#include "Path.h"
49#include "PlatformMouseEvent.h"
50#include "PluginViewBase.h"
51#include "RenderLayoutState.h"
52#include "RenderTheme.h"
53#include "RenderView.h"
54#include "Settings.h"
55#include "SystemFontDatabase.h"
56#include "Text.h"
57#include "TextRun.h"
58#include <wtf/IsoMallocInlines.h>
59#include <wtf/StackStats.h>
60
61namespace WebCore {
62
63using namespace HTMLNames;
64
65WTF_MAKE_ISO_ALLOCATED_IMPL(RenderEmbeddedObject);
66
67static const float replacementTextRoundedRectHeight = 22;
68static const float replacementTextRoundedRectLeftTextMargin = 10;
69static const float replacementTextRoundedRectRightTextMargin = 10;
70static const float replacementTextRoundedRectRightTextMarginWithArrow = 5;
71static const float replacementTextRoundedRectTopTextMargin = -1;
72static const float replacementTextRoundedRectRadius = 11;
73static const float replacementArrowLeftMargin = -4;
74static const float replacementArrowPadding = 4;
75static const float replacementArrowCirclePadding = 3;
76
77static constexpr auto replacementTextRoundedRectPressedColor = SRGBA<uint8_t> { 105, 105, 105, 242 };
78static constexpr auto replacementTextRoundedRectColor = SRGBA<uint8_t> { 125, 125, 125, 242 };
79static constexpr auto replacementTextColor = SRGBA<uint8_t> { 240, 240, 240 };
80static constexpr auto unavailablePluginBorderColor = Color::white.colorWithAlphaByte(216);
81
82RenderEmbeddedObject::RenderEmbeddedObject(HTMLFrameOwnerElement& element, RenderStyle&& style)
83 : RenderWidget(element, WTFMove(style))
84 , m_isPluginUnavailable(false)
85 , m_unavailablePluginIndicatorIsPressed(false)
86 , m_mouseDownWasInUnavailablePluginIndicator(false)
87{
88}
89
90RenderEmbeddedObject::~RenderEmbeddedObject()
91{
92 // Do not add any code here. Add it to willBeDestroyed() instead.
93}
94
95void RenderEmbeddedObject::willBeDestroyed()
96{
97 view().frameView().removeEmbeddedObjectToUpdate(*this);
98 RenderWidget::willBeDestroyed();
99}
100
101bool RenderEmbeddedObject::requiresLayer() const
102{
103 if (RenderWidget::requiresLayer())
104 return true;
105
106 return allowsAcceleratedCompositing();
107}
108
109bool RenderEmbeddedObject::allowsAcceleratedCompositing() const
110{
111#if PLATFORM(IOS_FAMILY)
112 // The timing of layer creation is different on the phone, since the plugin can only be manipulated from the main thread.
113 return is<PluginViewBase>(widget()) && downcast<PluginViewBase>(*widget()).willProvidePluginLayer();
114#else
115 return is<PluginViewBase>(widget()) && downcast<PluginViewBase>(*widget()).platformLayer();
116#endif
117}
118
119#if !PLATFORM(IOS_FAMILY)
120static String unavailablePluginReplacementText(RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason)
121{
122 switch (pluginUnavailabilityReason) {
123 case RenderEmbeddedObject::PluginMissing:
124 return missingPluginText();
125 case RenderEmbeddedObject::PluginCrashed:
126 return crashedPluginText();
127 case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
128 return blockedPluginByContentSecurityPolicyText();
129 case RenderEmbeddedObject::InsecurePluginVersion:
130 return insecurePluginVersionText();
131 case RenderEmbeddedObject::UnsupportedPlugin:
132 return unsupportedPluginText();
133 case RenderEmbeddedObject::PluginTooSmall:
134 return pluginTooSmallText();
135 }
136
137 ASSERT_NOT_REACHED();
138 return String();
139}
140#endif
141
142static bool shouldUnavailablePluginMessageBeButton(Page& page, RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason)
143{
144 return page.chrome().client().shouldUnavailablePluginMessageBeButton(pluginUnavailabilityReason);
145}
146
147void RenderEmbeddedObject::setPluginUnavailabilityReason(PluginUnavailabilityReason pluginUnavailabilityReason)
148{
149#if PLATFORM(IOS_FAMILY)
150 UNUSED_PARAM(pluginUnavailabilityReason);
151#else
152 setPluginUnavailabilityReasonWithDescription(pluginUnavailabilityReason, unavailablePluginReplacementText(pluginUnavailabilityReason));
153#endif
154}
155
156void RenderEmbeddedObject::setPluginUnavailabilityReasonWithDescription(PluginUnavailabilityReason pluginUnavailabilityReason, const String& description)
157{
158#if PLATFORM(IOS_FAMILY)
159 UNUSED_PARAM(pluginUnavailabilityReason);
160 UNUSED_PARAM(description);
161#else
162 ASSERT(!m_isPluginUnavailable);
163 m_isPluginUnavailable = true;
164 m_pluginUnavailabilityReason = pluginUnavailabilityReason;
165
166 if (description.isEmpty())
167 m_unavailablePluginReplacementText = unavailablePluginReplacementText(pluginUnavailabilityReason);
168 else
169 m_unavailablePluginReplacementText = description;
170#endif
171}
172
173void RenderEmbeddedObject::setUnavailablePluginIndicatorIsPressed(bool pressed)
174{
175 if (m_unavailablePluginIndicatorIsPressed == pressed)
176 return;
177 m_unavailablePluginIndicatorIsPressed = pressed;
178 repaint();
179}
180
181void RenderEmbeddedObject::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
182{
183 // The relevant repainted object heuristic is not tuned for plugin documents.
184 bool countsTowardsRelevantObjects = !document().isPluginDocument() && paintInfo.phase == PaintPhase::Foreground;
185
186 if (isPluginUnavailable()) {
187 if (countsTowardsRelevantObjects)
188 page().addRelevantUnpaintedObject(this, visualOverflowRect());
189 RenderReplaced::paint(paintInfo, paintOffset);
190 return;
191 }
192
193 if (countsTowardsRelevantObjects)
194 page().addRelevantRepaintedObject(this, visualOverflowRect());
195
196 RenderWidget::paint(paintInfo, paintOffset);
197}
198
199static void drawReplacementArrow(GraphicsContext& context, const FloatRect& insideRect)
200{
201 GraphicsContextStateSaver stateSaver(context);
202
203 FloatRect rect(insideRect);
204 rect.inflate(-replacementArrowPadding);
205
206 FloatPoint center(rect.center());
207 FloatPoint arrowTip(rect.maxX(), center.y());
208
209 context.setStrokeThickness(2);
210 context.setLineCap(LineCap::Round);
211 context.setLineJoin(LineJoin::Round);
212
213 Path path;
214 path.moveTo(FloatPoint(rect.x(), center.y()));
215 path.addLineTo(arrowTip);
216 path.addLineTo(FloatPoint(center.x(), rect.y()));
217 path.moveTo(arrowTip);
218 path.addLineTo(FloatPoint(center.x(), rect.maxY()));
219 context.strokePath(path);
220}
221
222void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
223{
224 if (!showsUnavailablePluginIndicator())
225 return;
226
227 if (paintInfo.phase == PaintPhase::Selection)
228 return;
229
230 GraphicsContext& context = paintInfo.context();
231 if (context.paintingDisabled())
232 return;
233
234 FloatRect contentRect;
235 FloatRect indicatorRect;
236 FloatRect replacementTextRect;
237 FloatRect arrowRect;
238 FontCascade font;
239 TextRun run(emptyString());
240 float textWidth;
241 getReplacementTextGeometry(paintOffset, contentRect, indicatorRect, replacementTextRect, arrowRect, font, run, textWidth);
242
243 Path background;
244 background.addRoundedRect(indicatorRect, FloatSize(replacementTextRoundedRectRadius, replacementTextRoundedRectRadius));
245
246 GraphicsContextStateSaver stateSaver(context);
247 context.clip(contentRect);
248 context.setFillColor(m_unavailablePluginIndicatorIsPressed ? replacementTextRoundedRectPressedColor : replacementTextRoundedRectColor);
249 context.fillPath(background);
250
251 Path strokePath;
252 FloatRect strokeRect(indicatorRect);
253 strokeRect.inflate(1);
254 strokePath.addRoundedRect(strokeRect, FloatSize(replacementTextRoundedRectRadius + 1, replacementTextRoundedRectRadius + 1));
255
256 context.setStrokeColor(unavailablePluginBorderColor);
257 context.setStrokeThickness(2);
258 context.strokePath(strokePath);
259
260 const FontMetrics& fontMetrics = font.metricsOfPrimaryFont();
261 float labelX = roundf(replacementTextRect.location().x() + replacementTextRoundedRectLeftTextMargin);
262 float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - fontMetrics.height()) / 2 + fontMetrics.ascent() + replacementTextRoundedRectTopTextMargin);
263 context.setFillColor(replacementTextColor);
264 context.drawBidiText(font, run, FloatPoint(labelX, labelY));
265
266 if (shouldUnavailablePluginMessageBeButton(page(), m_pluginUnavailabilityReason)) {
267 arrowRect.inflate(-replacementArrowCirclePadding);
268
269 context.beginTransparencyLayer(1.0);
270 context.setFillColor(replacementTextColor);
271 context.fillEllipse(arrowRect);
272
273 context.setCompositeOperation(CompositeOperator::Clear);
274 drawReplacementArrow(context, arrowRect);
275 context.endTransparencyLayer();
276 }
277}
278
279void RenderEmbeddedObject::setUnavailablePluginIndicatorIsHidden(bool hidden)
280{
281 auto newState = hidden ? UnavailablePluginIndicatorState::Hidden : UnavailablePluginIndicatorState::Visible;
282 if (m_isUnavailablePluginIndicatorState == newState)
283 return;
284 m_isUnavailablePluginIndicatorState = newState;
285 repaint();
286}
287
288LayoutRect RenderEmbeddedObject::getReplacementTextGeometry(const LayoutPoint& accumulatedOffset) const
289{
290 FloatRect contentRect;
291 FloatRect indicatorRect;
292 FloatRect replacementTextRect;
293 FloatRect arrowRect;
294 FontCascade font;
295 TextRun run(emptyString());
296 float textWidth;
297 getReplacementTextGeometry(accumulatedOffset, contentRect, indicatorRect, replacementTextRect, arrowRect, font, run, textWidth);
298 return LayoutRect(indicatorRect);
299}
300
301void RenderEmbeddedObject::getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, FloatRect& indicatorRect, FloatRect& replacementTextRect, FloatRect& arrowRect, FontCascade& font, TextRun& run, float& textWidth) const
302{
303 bool includesArrow = shouldUnavailablePluginMessageBeButton(page(), m_pluginUnavailabilityReason);
304
305 contentRect = contentBoxRect();
306 contentRect.moveBy(roundedIntPoint(accumulatedOffset));
307
308 FontCascadeDescription fontDescription;
309 fontDescription.setOneFamily(SystemFontDatabase::singleton().systemFontShorthandFamily(SystemFontDatabase::FontShorthand::WebkitSmallControl));
310 fontDescription.setWeight(boldWeightValue());
311 fontDescription.setRenderingMode(settings().fontRenderingMode());
312 fontDescription.setComputedSize(12);
313 font = FontCascade(WTFMove(fontDescription), 0, 0);
314 font.update(nullptr);
315
316 run = TextRun(m_unavailablePluginReplacementText);
317 textWidth = font.width(run);
318
319 replacementTextRect.setSize(FloatSize(textWidth + replacementTextRoundedRectLeftTextMargin + (includesArrow ? replacementTextRoundedRectRightTextMarginWithArrow : replacementTextRoundedRectRightTextMargin), replacementTextRoundedRectHeight));
320 replacementTextRect.setLocation(contentRect.location() + (contentRect.size() / 2 - replacementTextRect.size() / 2));
321
322 indicatorRect = replacementTextRect;
323
324 // Expand the background rect to include the arrow, if it will be used.
325 if (includesArrow) {
326 arrowRect = indicatorRect;
327 arrowRect.setX(ceilf(arrowRect.maxX() + replacementArrowLeftMargin));
328 arrowRect.setWidth(arrowRect.height());
329 indicatorRect.unite(arrowRect);
330 }
331}
332
333LayoutRect RenderEmbeddedObject::unavailablePluginIndicatorBounds(const LayoutPoint& accumulatedOffset) const
334{
335 return getReplacementTextGeometry(accumulatedOffset);
336}
337
338void RenderEmbeddedObject::layout()
339{
340 StackStats::LayoutCheckPoint layoutCheckPoint;
341 ASSERT(needsLayout());
342
343 updateLogicalWidth();
344 updateLogicalHeight();
345
346 RenderWidget::layout();
347
348 clearOverflow();
349 addVisualEffectOverflow();
350
351 updateLayerTransform();
352
353 if (!widget())
354 view().frameView().addEmbeddedObjectToUpdate(*this);
355
356 clearNeedsLayout();
357}
358
359bool RenderEmbeddedObject::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
360{
361 if (!RenderWidget::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction))
362 return false;
363
364 if (!is<PluginViewBase>(widget()))
365 return true;
366
367 PluginViewBase& view = downcast<PluginViewBase>(*widget());
368 IntPoint roundedPoint = locationInContainer.roundedPoint();
369
370 if (Scrollbar* horizontalScrollbar = view.horizontalScrollbar()) {
371 if (horizontalScrollbar->shouldParticipateInHitTesting() && horizontalScrollbar->frameRect().contains(roundedPoint)) {
372 result.setScrollbar(horizontalScrollbar);
373 return true;
374 }
375 }
376
377 if (Scrollbar* verticalScrollbar = view.verticalScrollbar()) {
378 if (verticalScrollbar->shouldParticipateInHitTesting() && verticalScrollbar->frameRect().contains(roundedPoint)) {
379 result.setScrollbar(verticalScrollbar);
380 return true;
381 }
382 }
383
384 return true;
385}
386
387bool RenderEmbeddedObject::scroll(ScrollDirection direction, ScrollGranularity granularity, unsigned, Element**, RenderBox*, const IntPoint&)
388{
389 if (!is<PluginViewBase>(widget()))
390 return false;
391
392 return downcast<PluginViewBase>(*widget()).scroll(direction, granularity);
393}
394
395bool RenderEmbeddedObject::logicalScroll(ScrollLogicalDirection direction, ScrollGranularity granularity, unsigned stepCount, Element** stopElement)
396{
397 // Plugins don't expose a writing direction, so assuming horizontal LTR.
398 return scroll(logicalToPhysical(direction, true, false), granularity, stepCount, stopElement);
399}
400
401bool RenderEmbeddedObject::isInUnavailablePluginIndicator(const FloatPoint& point) const
402{
403 return getReplacementTextGeometry(LayoutPoint()).contains(LayoutPoint(point));
404}
405
406bool RenderEmbeddedObject::isInUnavailablePluginIndicator(const MouseEvent& event) const
407{
408 return isInUnavailablePluginIndicator(absoluteToLocal(event.absoluteLocation(), UseTransforms));
409}
410
411void RenderEmbeddedObject::handleUnavailablePluginIndicatorEvent(Event* event)
412{
413 if (!shouldUnavailablePluginMessageBeButton(page(), m_pluginUnavailabilityReason))
414 return;
415
416 if (!is<MouseEvent>(*event))
417 return;
418
419 MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
420 HTMLPlugInElement& element = downcast<HTMLPlugInElement>(frameOwnerElement());
421 if (mouseEvent.type() == eventNames().mousedownEvent && mouseEvent.button() == LeftButton) {
422 m_mouseDownWasInUnavailablePluginIndicator = isInUnavailablePluginIndicator(mouseEvent);
423 if (m_mouseDownWasInUnavailablePluginIndicator) {
424 frame().eventHandler().setCapturingMouseEventsElement(&element);
425 element.setIsCapturingMouseEvents(true);
426 setUnavailablePluginIndicatorIsPressed(true);
427 }
428 mouseEvent.setDefaultHandled();
429 }
430 if (mouseEvent.type() == eventNames().mouseupEvent && mouseEvent.button() == LeftButton) {
431 if (m_unavailablePluginIndicatorIsPressed) {
432 frame().eventHandler().setCapturingMouseEventsElement(nullptr);
433 element.setIsCapturingMouseEvents(false);
434 setUnavailablePluginIndicatorIsPressed(false);
435 }
436 if (m_mouseDownWasInUnavailablePluginIndicator && isInUnavailablePluginIndicator(mouseEvent)) {
437 page().chrome().client().unavailablePluginButtonClicked(element, m_pluginUnavailabilityReason);
438 }
439 m_mouseDownWasInUnavailablePluginIndicator = false;
440 event->setDefaultHandled();
441 }
442 if (mouseEvent.type() == eventNames().mousemoveEvent) {
443 setUnavailablePluginIndicatorIsPressed(m_mouseDownWasInUnavailablePluginIndicator && isInUnavailablePluginIndicator(mouseEvent));
444 mouseEvent.setDefaultHandled();
445 }
446}
447
448CursorDirective RenderEmbeddedObject::getCursor(const LayoutPoint& point, Cursor& cursor) const
449{
450 if (showsUnavailablePluginIndicator() && shouldUnavailablePluginMessageBeButton(page(), m_pluginUnavailabilityReason) && isInUnavailablePluginIndicator(point)) {
451 cursor = handCursor();
452 return SetCursor;
453 }
454 if (widget() && widget()->isPluginViewBase()) {
455 // A plug-in is responsible for setting the cursor when the pointer is over it.
456 return DoNotSetCursor;
457 }
458 return RenderWidget::getCursor(point, cursor);
459}
460
461}
Note: See TracBrowser for help on using the repository browser.