Home | History | Annotate | Download | only in css
      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