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 26 PassRefPtr<MediaValues> MediaValues::createDynamicIfFrameExists(LocalFrame* frame) 27 { 28 if (frame) 29 return MediaValuesDynamic::create(frame); 30 return MediaValuesCached::create(); 31 } 32 33 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 40 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 47 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 56 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 65 bool MediaValues::calculateStrictMode(LocalFrame* frame) const 66 { 67 ASSERT(frame && frame->document()); 68 return !frame->document()->inQuirksMode(); 69 } 70 71 float MediaValues::calculateDevicePixelRatio(LocalFrame* frame) const 72 { 73 return frame->devicePixelRatio(); 74 } 75 76 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 85 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 94 int MediaValues::calculateDefaultFontSize(LocalFrame* frame) const 95 { 96 return frame->host()->settings().defaultFontSize(); 97 } 98 99 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 106 bool MediaValues::calculateScreenMediaType(LocalFrame* frame) const 107 { 108 ASSERT(frame && frame->view()); 109 return equalIgnoringCase(frame->view()->mediaType(), "screen"); 110 } 111 112 bool MediaValues::calculatePrintMediaType(LocalFrame* frame) const 113 { 114 ASSERT(frame && frame->view()); 115 return equalIgnoringCase(frame->view()->mediaType(), "print"); 116 } 117 118 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 127 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 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