• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 2000 Simon Hausmann <hausmann@kde.org>
4  *           (C) 2000 Stefan Schimanski (1Stein@gmx.de)
5  * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 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 "core/rendering/RenderEmbeddedObject.h"
26 
27 #include "core/CSSValueKeywords.h"
28 #include "core/HTMLNames.h"
29 #include "core/frame/LocalFrame.h"
30 #include "core/html/HTMLIFrameElement.h"
31 #include "core/html/HTMLPlugInElement.h"
32 #include "core/page/Page.h"
33 #include "core/frame/Settings.h"
34 #include "core/plugins/PluginView.h"
35 #include "core/rendering/PaintInfo.h"
36 #include "core/rendering/RenderTheme.h"
37 #include "core/rendering/RenderView.h"
38 #include "platform/fonts/Font.h"
39 #include "platform/fonts/FontSelector.h"
40 #include "platform/graphics/GraphicsContextStateSaver.h"
41 #include "platform/graphics/Path.h"
42 #include "platform/text/PlatformLocale.h"
43 #include "platform/text/TextRun.h"
44 
45 namespace WebCore {
46 
47 using namespace HTMLNames;
48 
49 static const float replacementTextRoundedRectHeight = 18;
50 static const float replacementTextRoundedRectLeftRightTextMargin = 6;
51 static const float replacementTextRoundedRectOpacity = 0.20f;
52 static const float replacementTextRoundedRectRadius = 5;
53 static const float replacementTextTextOpacity = 0.55f;
54 
RenderEmbeddedObject(Element * element)55 RenderEmbeddedObject::RenderEmbeddedObject(Element* element)
56     : RenderPart(element)
57     , m_showsUnavailablePluginIndicator(false)
58 {
59     view()->frameView()->setIsVisuallyNonEmpty();
60 }
61 
~RenderEmbeddedObject()62 RenderEmbeddedObject::~RenderEmbeddedObject()
63 {
64 }
65 
layerTypeRequired() const66 LayerType RenderEmbeddedObject::layerTypeRequired() const
67 {
68     // This can't just use RenderPart::layerTypeRequired, because RenderLayerCompositor
69     // doesn't loop through RenderEmbeddedObjects the way it does frames in order
70     // to update the self painting bit on their RenderLayer.
71     // Also, unlike iframes, embeds don't used the usesCompositing bit on RenderView
72     // in requiresAcceleratedCompositing.
73     if (requiresAcceleratedCompositing())
74         return NormalLayer;
75     return RenderPart::layerTypeRequired();
76 }
77 
unavailablePluginReplacementText(Node * node,RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason)78 static String unavailablePluginReplacementText(Node* node, RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason)
79 {
80     Locale& locale = node ? toElement(node)->locale() : Locale::defaultLocale();
81     switch (pluginUnavailabilityReason) {
82     case RenderEmbeddedObject::PluginMissing:
83         return locale.queryString(blink::WebLocalizedString::MissingPluginText);
84     case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
85         return locale.queryString(blink::WebLocalizedString::BlockedPluginText);
86     }
87 
88     ASSERT_NOT_REACHED();
89     return String();
90 }
91 
setPluginUnavailabilityReason(PluginUnavailabilityReason pluginUnavailabilityReason)92 void RenderEmbeddedObject::setPluginUnavailabilityReason(PluginUnavailabilityReason pluginUnavailabilityReason)
93 {
94     ASSERT(!m_showsUnavailablePluginIndicator);
95     m_showsUnavailablePluginIndicator = true;
96     m_pluginUnavailabilityReason = pluginUnavailabilityReason;
97 
98     m_unavailablePluginReplacementText = unavailablePluginReplacementText(node(), pluginUnavailabilityReason);
99 }
100 
showsUnavailablePluginIndicator() const101 bool RenderEmbeddedObject::showsUnavailablePluginIndicator() const
102 {
103     return m_showsUnavailablePluginIndicator;
104 }
105 
paintContents(PaintInfo & paintInfo,const LayoutPoint & paintOffset)106 void RenderEmbeddedObject::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
107 {
108     Element* element = toElement(node());
109     if (!isHTMLPlugInElement(element))
110         return;
111 
112     RenderPart::paintContents(paintInfo, paintOffset);
113 }
114 
paint(PaintInfo & paintInfo,const LayoutPoint & paintOffset)115 void RenderEmbeddedObject::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
116 {
117     if (showsUnavailablePluginIndicator()) {
118         RenderReplaced::paint(paintInfo, paintOffset);
119         return;
120     }
121 
122     RenderPart::paint(paintInfo, paintOffset);
123 }
124 
paintReplaced(PaintInfo & paintInfo,const LayoutPoint & paintOffset)125 void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
126 {
127     if (!showsUnavailablePluginIndicator())
128         return;
129 
130     if (paintInfo.phase == PaintPhaseSelection)
131         return;
132 
133     GraphicsContext* context = paintInfo.context;
134     if (context->paintingDisabled())
135         return;
136 
137     FloatRect contentRect;
138     Path path;
139     FloatRect replacementTextRect;
140     Font font;
141     TextRun run("");
142     float textWidth;
143     if (!getReplacementTextGeometry(paintOffset, contentRect, path, replacementTextRect, font, run, textWidth))
144         return;
145 
146     GraphicsContextStateSaver stateSaver(*context);
147     context->clip(contentRect);
148     context->setAlphaAsFloat(replacementTextRoundedRectOpacity);
149     context->setFillColor(Color::white);
150     context->fillPath(path);
151 
152     const FontMetrics& fontMetrics = font.fontMetrics();
153     float labelX = roundf(replacementTextRect.location().x() + (replacementTextRect.size().width() - textWidth) / 2);
154     float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - fontMetrics.height()) / 2 + fontMetrics.ascent());
155     TextRunPaintInfo runInfo(run);
156     runInfo.bounds = replacementTextRect;
157     context->setAlphaAsFloat(replacementTextTextOpacity);
158     context->setFillColor(Color::black);
159     context->drawBidiText(font, runInfo, FloatPoint(labelX, labelY));
160 }
161 
getReplacementTextGeometry(const LayoutPoint & accumulatedOffset,FloatRect & contentRect,Path & path,FloatRect & replacementTextRect,Font & font,TextRun & run,float & textWidth) const162 bool RenderEmbeddedObject::getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, Path& path, FloatRect& replacementTextRect, Font& font, TextRun& run, float& textWidth) const
163 {
164     contentRect = contentBoxRect();
165     contentRect.moveBy(roundedIntPoint(accumulatedOffset));
166 
167     FontDescription fontDescription;
168     RenderTheme::theme().systemFont(CSSValueWebkitSmallControl, fontDescription);
169     fontDescription.setWeight(FontWeightBold);
170     Settings* settings = document().settings();
171     ASSERT(settings);
172     if (!settings)
173         return false;
174     fontDescription.setComputedSize(fontDescription.specifiedSize());
175     font = Font(fontDescription);
176     font.update(nullptr);
177 
178     run = TextRun(m_unavailablePluginReplacementText);
179     textWidth = font.width(run);
180 
181     replacementTextRect.setSize(FloatSize(textWidth + replacementTextRoundedRectLeftRightTextMargin * 2, replacementTextRoundedRectHeight));
182     float x = (contentRect.size().width() / 2 - replacementTextRect.size().width() / 2) + contentRect.location().x();
183     float y = (contentRect.size().height() / 2 - replacementTextRect.size().height() / 2) + contentRect.location().y();
184     replacementTextRect.setLocation(FloatPoint(x, y));
185 
186     path.addRoundedRect(replacementTextRect, FloatSize(replacementTextRoundedRectRadius, replacementTextRoundedRectRadius));
187 
188     return true;
189 }
190 
layout()191 void RenderEmbeddedObject::layout()
192 {
193     ASSERT(needsLayout());
194 
195     updateLogicalWidth();
196     updateLogicalHeight();
197 
198     m_overflow.clear();
199     addVisualEffectOverflow();
200 
201     updateLayerTransformAfterLayout();
202 
203     if (!widget() && frameView())
204         frameView()->addWidgetToUpdate(*this);
205 
206     clearNeedsLayout();
207 }
208 
scroll(ScrollDirection direction,ScrollGranularity granularity,float)209 bool RenderEmbeddedObject::scroll(ScrollDirection direction, ScrollGranularity granularity, float)
210 {
211     return false;
212 }
213 
additionalCompositingReasons(CompositingTriggerFlags triggers) const214 CompositingReasons RenderEmbeddedObject::additionalCompositingReasons(CompositingTriggerFlags triggers) const
215 {
216     if (requiresAcceleratedCompositing())
217         return CompositingReasonPlugin;
218     return CompositingReasonNone;
219 }
220 
embeddedContentBox() const221 RenderBox* RenderEmbeddedObject::embeddedContentBox() const
222 {
223     if (!node() || !widget() || !widget()->isFrameView())
224         return 0;
225     return toFrameView(widget())->embeddedContentBox();
226 }
227 
228 }
229