• 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 blink {
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(WebLocalizedString::MissingPluginText);
84     case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
85         return locale.queryString(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     FloatRect contentRect;
134     Path path;
135     FloatRect replacementTextRect;
136     Font font;
137     TextRun run("");
138     float textWidth;
139     if (!getReplacementTextGeometry(paintOffset, contentRect, path, replacementTextRect, font, run, textWidth))
140         return;
141 
142     GraphicsContext* context = paintInfo.context;
143     GraphicsContextStateSaver stateSaver(*context);
144     context->clip(contentRect);
145     context->setAlphaAsFloat(replacementTextRoundedRectOpacity);
146     context->setFillColor(Color::white);
147     context->fillPath(path);
148 
149     const FontMetrics& fontMetrics = font.fontMetrics();
150     float labelX = roundf(replacementTextRect.location().x() + (replacementTextRect.size().width() - textWidth) / 2);
151     float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - fontMetrics.height()) / 2 + fontMetrics.ascent());
152     TextRunPaintInfo runInfo(run);
153     runInfo.bounds = replacementTextRect;
154     context->setAlphaAsFloat(replacementTextTextOpacity);
155     context->setFillColor(Color::black);
156     context->drawBidiText(font, runInfo, FloatPoint(labelX, labelY));
157 }
158 
getReplacementTextGeometry(const LayoutPoint & accumulatedOffset,FloatRect & contentRect,Path & path,FloatRect & replacementTextRect,Font & font,TextRun & run,float & textWidth) const159 bool RenderEmbeddedObject::getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, Path& path, FloatRect& replacementTextRect, Font& font, TextRun& run, float& textWidth) const
160 {
161     contentRect = contentBoxRect();
162     contentRect.moveBy(roundedIntPoint(accumulatedOffset));
163 
164     FontDescription fontDescription;
165     RenderTheme::theme().systemFont(CSSValueWebkitSmallControl, fontDescription);
166     fontDescription.setWeight(FontWeightBold);
167     Settings* settings = document().settings();
168     ASSERT(settings);
169     if (!settings)
170         return false;
171     fontDescription.setComputedSize(fontDescription.specifiedSize());
172     font = Font(fontDescription);
173     font.update(nullptr);
174 
175     run = TextRun(m_unavailablePluginReplacementText);
176     textWidth = font.width(run);
177 
178     replacementTextRect.setSize(FloatSize(textWidth + replacementTextRoundedRectLeftRightTextMargin * 2, replacementTextRoundedRectHeight));
179     float x = (contentRect.size().width() / 2 - replacementTextRect.size().width() / 2) + contentRect.location().x();
180     float y = (contentRect.size().height() / 2 - replacementTextRect.size().height() / 2) + contentRect.location().y();
181     replacementTextRect.setLocation(FloatPoint(x, y));
182 
183     path.addRoundedRect(replacementTextRect, FloatSize(replacementTextRoundedRectRadius, replacementTextRoundedRectRadius));
184 
185     return true;
186 }
187 
layout()188 void RenderEmbeddedObject::layout()
189 {
190     ASSERT(needsLayout());
191 
192     updateLogicalWidth();
193     updateLogicalHeight();
194 
195     m_overflow.clear();
196     addVisualEffectOverflow();
197 
198     updateLayerTransformAfterLayout();
199 
200     if (!widget() && frameView())
201         frameView()->addWidgetToUpdate(*this);
202 
203     clearNeedsLayout();
204 }
205 
scroll(ScrollDirection direction,ScrollGranularity granularity,float)206 bool RenderEmbeddedObject::scroll(ScrollDirection direction, ScrollGranularity granularity, float)
207 {
208     return false;
209 }
210 
additionalCompositingReasons() const211 CompositingReasons RenderEmbeddedObject::additionalCompositingReasons() const
212 {
213     if (requiresAcceleratedCompositing())
214         return CompositingReasonPlugin;
215     return CompositingReasonNone;
216 }
217 
embeddedContentBox() const218 RenderBox* RenderEmbeddedObject::embeddedContentBox() const
219 {
220     if (!node() || !widget() || !widget()->isFrameView())
221         return 0;
222     return toFrameView(widget())->embeddedContentBox();
223 }
224 
225 } // namespace blink
226