1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/css/MediaValues.h"
7
8 #include "core/css/CSSHelper.h"
9 #include "core/css/MediaValuesCached.h"
10 #include "core/css/MediaValuesDynamic.h"
11 #include "core/dom/Document.h"
12 #include "core/dom/Element.h"
13 #include "core/frame/FrameHost.h"
14 #include "core/frame/FrameView.h"
15 #include "core/frame/LocalFrame.h"
16 #include "core/frame/Settings.h"
17 #include "core/page/Page.h"
18 #include "core/rendering/RenderObject.h"
19 #include "core/rendering/RenderView.h"
20 #include "core/rendering/compositing/RenderLayerCompositor.h"
21 #include "core/rendering/style/RenderStyle.h"
22 #include "platform/PlatformScreen.h"
23
24 namespace WebCore {
25
createDynamicIfFrameExists(LocalFrame * frame)26 PassRefPtr<MediaValues> MediaValues::createDynamicIfFrameExists(LocalFrame* frame)
27 {
28 if (frame)
29 return MediaValuesDynamic::create(frame);
30 return MediaValuesCached::create();
31 }
32
calculateViewportWidth(LocalFrame * frame) const33 int MediaValues::calculateViewportWidth(LocalFrame* frame) const
34 {
35 ASSERT(frame && frame->view() && frame->document());
36 int viewportWidth = frame->view()->layoutSize(IncludeScrollbars).width();
37 return adjustForAbsoluteZoom(viewportWidth, frame->document()->renderView());
38 }
39
calculateViewportHeight(LocalFrame * frame) const40 int MediaValues::calculateViewportHeight(LocalFrame* frame) const
41 {
42 ASSERT(frame && frame->view() && frame->document());
43 int viewportHeight = frame->view()->layoutSize(IncludeScrollbars).height();
44 return adjustForAbsoluteZoom(viewportHeight, frame->document()->renderView());
45 }
46
calculateDeviceWidth(LocalFrame * frame) const47 int MediaValues::calculateDeviceWidth(LocalFrame* frame) const
48 {
49 ASSERT(frame && frame->view() && frame->settings() && frame->host());
50 int deviceWidth = static_cast<int>(screenRect(frame->view()).width());
51 if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk())
52 deviceWidth = lroundf(deviceWidth * frame->host()->deviceScaleFactor());
53 return deviceWidth;
54 }
55
calculateDeviceHeight(LocalFrame * frame) const56 int MediaValues::calculateDeviceHeight(LocalFrame* frame) const
57 {
58 ASSERT(frame && frame->view() && frame->settings() && frame->host());
59 int deviceHeight = static_cast<int>(screenRect(frame->view()).height());
60 if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk())
61 deviceHeight = lroundf(deviceHeight * frame->host()->deviceScaleFactor());
62 return deviceHeight;
63 }
64
calculateStrictMode(LocalFrame * frame) const65 bool MediaValues::calculateStrictMode(LocalFrame* frame) const
66 {
67 ASSERT(frame && frame->document());
68 return !frame->document()->inQuirksMode();
69 }
70
calculateDevicePixelRatio(LocalFrame * frame) const71 float MediaValues::calculateDevicePixelRatio(LocalFrame* frame) const
72 {
73 return frame->devicePixelRatio();
74 }
75
calculateColorBitsPerComponent(LocalFrame * frame) const76 int MediaValues::calculateColorBitsPerComponent(LocalFrame* frame) const
77 {
78 ASSERT(frame && frame->page() && frame->page()->mainFrame());
79 if (!frame->page()->mainFrame()->isLocalFrame()
80 || screenIsMonochrome(frame->page()->deprecatedLocalMainFrame()->view()))
81 return 0;
82 return screenDepthPerComponent(frame->view());
83 }
84
calculateMonochromeBitsPerComponent(LocalFrame * frame) const85 int MediaValues::calculateMonochromeBitsPerComponent(LocalFrame* frame) const
86 {
87 ASSERT(frame && frame->page() && frame->page()->mainFrame());
88 if (!frame->page()->mainFrame()->isLocalFrame()
89 || !screenIsMonochrome(frame->page()->deprecatedLocalMainFrame()->view()))
90 return 0;
91 return screenDepthPerComponent(frame->view());
92 }
93
calculateDefaultFontSize(LocalFrame * frame) const94 int MediaValues::calculateDefaultFontSize(LocalFrame* frame) const
95 {
96 return frame->host()->settings().defaultFontSize();
97 }
98
calculateScanMediaType(LocalFrame * frame) const99 bool MediaValues::calculateScanMediaType(LocalFrame* frame) const
100 {
101 ASSERT(frame && frame->view());
102 // Scan only applies to 'tv' media.
103 return equalIgnoringCase(frame->view()->mediaType(), "tv");
104 }
105
calculateScreenMediaType(LocalFrame * frame) const106 bool MediaValues::calculateScreenMediaType(LocalFrame* frame) const
107 {
108 ASSERT(frame && frame->view());
109 return equalIgnoringCase(frame->view()->mediaType(), "screen");
110 }
111
calculatePrintMediaType(LocalFrame * frame) const112 bool MediaValues::calculatePrintMediaType(LocalFrame* frame) const
113 {
114 ASSERT(frame && frame->view());
115 return equalIgnoringCase(frame->view()->mediaType(), "print");
116 }
117
calculateThreeDEnabled(LocalFrame * frame) const118 bool MediaValues::calculateThreeDEnabled(LocalFrame* frame) const
119 {
120 ASSERT(frame && frame->contentRenderer() && frame->contentRenderer()->compositor());
121 bool threeDEnabled = false;
122 if (RenderView* view = frame->contentRenderer())
123 threeDEnabled = view->compositor()->hasAcceleratedCompositing();
124 return threeDEnabled;
125 }
126
calculateLeastCapablePrimaryPointerDeviceType(LocalFrame * frame) const127 MediaValues::PointerDeviceType MediaValues::calculateLeastCapablePrimaryPointerDeviceType(LocalFrame* frame) const
128 {
129 ASSERT(frame && frame->settings());
130 if (frame->settings()->deviceSupportsTouch())
131 return MediaValues::TouchPointer;
132
133 // FIXME: We should also try to determine if we know we have a mouse.
134 // When we do this, we'll also need to differentiate between known not to
135 // have mouse or touch screen (NoPointer) and unknown (UnknownPointer).
136 // We could also take into account other preferences like accessibility
137 // settings to decide which of the available pointers should be considered
138 // "primary".
139
140 return MediaValues::UnknownPointer;
141 }
142
computeLengthImpl(double value,CSSPrimitiveValue::UnitType type,unsigned defaultFontSize,unsigned viewportWidth,unsigned viewportHeight,double & result)143 bool MediaValues::computeLengthImpl(double value, CSSPrimitiveValue::UnitType type, unsigned defaultFontSize, unsigned viewportWidth, unsigned viewportHeight, double& result)
144 {
145 // The logic in this function is duplicated from CSSPrimitiveValue::computeLengthDouble
146 // because MediaValues::computeLength needs nearly identical logic, but we haven't found a way to make
147 // CSSPrimitiveValue::computeLengthDouble more generic (to solve both cases) without hurting performance.
148
149 // FIXME - Unite the logic here with CSSPrimitiveValue in a performant way.
150 double factor = 0;
151 switch (type) {
152 case CSSPrimitiveValue::CSS_EMS:
153 case CSSPrimitiveValue::CSS_REMS:
154 factor = defaultFontSize;
155 break;
156 case CSSPrimitiveValue::CSS_PX:
157 factor = 1;
158 break;
159 case CSSPrimitiveValue::CSS_EXS:
160 // FIXME: We have a bug right now where the zoom will be applied twice to EX units.
161 // FIXME: We don't seem to be able to cache fontMetrics related values.
162 // Trying to access them is triggering some sort of microtask. Serving the spec's default instead.
163 factor = defaultFontSize / 2.0;
164 break;
165 case CSSPrimitiveValue::CSS_CHS:
166 // FIXME: We don't seem to be able to cache fontMetrics related values.
167 // Trying to access them is triggering some sort of microtask. Serving the (future) spec default instead.
168 factor = defaultFontSize / 2.0;
169 break;
170 case CSSPrimitiveValue::CSS_VW:
171 factor = viewportWidth / 100.0;
172 break;
173 case CSSPrimitiveValue::CSS_VH:
174 factor = viewportHeight / 100.0;
175 break;
176 case CSSPrimitiveValue::CSS_VMIN:
177 factor = std::min(viewportWidth, viewportHeight) / 100.0;
178 break;
179 case CSSPrimitiveValue::CSS_VMAX:
180 factor = std::max(viewportWidth, viewportHeight) / 100.0;
181 break;
182 case CSSPrimitiveValue::CSS_CM:
183 factor = cssPixelsPerCentimeter;
184 break;
185 case CSSPrimitiveValue::CSS_MM:
186 factor = cssPixelsPerMillimeter;
187 break;
188 case CSSPrimitiveValue::CSS_IN:
189 factor = cssPixelsPerInch;
190 break;
191 case CSSPrimitiveValue::CSS_PT:
192 factor = cssPixelsPerPoint;
193 break;
194 case CSSPrimitiveValue::CSS_PC:
195 factor = cssPixelsPerPica;
196 break;
197 default:
198 return false;
199 }
200
201 ASSERT(factor > 0);
202 result = value * factor;
203 return true;
204 }
205
206 } // namespace
207