WebCore/css/MediaQueryEvaluator.cpp
changeset 0 4f2f89ce4247
child 2 303757a437d3
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * CSS Media Query Evaluator
       
     3  *
       
     4  * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>.
       
     5  *
       
     6  * Redistribution and use in source and binary forms, with or without
       
     7  * modification, are permitted provided that the following conditions
       
     8  * are met:
       
     9  * 1. Redistributions of source code must retain the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer.
       
    11  * 2. Redistributions in binary form must reproduce the above copyright
       
    12  *    notice, this list of conditions and the following disclaimer in the
       
    13  *    documentation and/or other materials provided with the distribution.
       
    14  *
       
    15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
       
    16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
       
    19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
       
    23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    26  */
       
    27 
       
    28 #include "config.h"
       
    29 #include "MediaQueryEvaluator.h"
       
    30 
       
    31 #include "Chrome.h"
       
    32 #include "ChromeClient.h"
       
    33 #include "CSSPrimitiveValue.h"
       
    34 #include "CSSStyleSelector.h"
       
    35 #include "CSSValueList.h"
       
    36 #include "FloatRect.h"
       
    37 #include "Frame.h"
       
    38 #include "FrameView.h"
       
    39 #include "IntRect.h"
       
    40 #include "MediaFeatureNames.h"
       
    41 #include "MediaList.h"
       
    42 #include "MediaQuery.h"
       
    43 #include "MediaQueryExp.h"
       
    44 #include "NodeRenderStyle.h"
       
    45 #include "Page.h"
       
    46 #include "RenderView.h"
       
    47 #include "RenderStyle.h"
       
    48 #include "PlatformScreen.h"
       
    49 #include <wtf/HashMap.h>
       
    50 
       
    51 #if ENABLE(3D_RENDERING) && USE(ACCELERATED_COMPOSITING)
       
    52 #include "RenderLayerCompositor.h"
       
    53 #endif
       
    54 
       
    55 namespace WebCore {
       
    56 
       
    57 using namespace MediaFeatureNames;
       
    58 
       
    59 enum MediaFeaturePrefix { MinPrefix, MaxPrefix, NoPrefix };
       
    60 
       
    61 typedef bool (*EvalFunc)(CSSValue*, RenderStyle*, Frame*, MediaFeaturePrefix);
       
    62 typedef HashMap<AtomicStringImpl*, EvalFunc> FunctionMap;
       
    63 static FunctionMap* gFunctionMap;
       
    64 
       
    65 /*
       
    66  * FIXME: following media features are not implemented: color_index, scan, resolution
       
    67  *
       
    68  * color_index, min-color-index, max_color_index: It's unknown how to retrieve
       
    69  * the information if the display mode is indexed
       
    70  * scan: The "scan" media feature describes the scanning process of
       
    71  * tv output devices. It's unknown how to retrieve this information from
       
    72  * the platform
       
    73  * resolution, min-resolution, max-resolution: css parser doesn't seem to
       
    74  * support CSS_DIMENSION
       
    75  */
       
    76 
       
    77 MediaQueryEvaluator::MediaQueryEvaluator(bool mediaFeatureResult)
       
    78     : m_frame(0)
       
    79     , m_style(0)
       
    80     , m_expResult(mediaFeatureResult)
       
    81 {
       
    82 }
       
    83 
       
    84 MediaQueryEvaluator:: MediaQueryEvaluator(const String& acceptedMediaType, bool mediaFeatureResult)
       
    85     : m_mediaType(acceptedMediaType)
       
    86     , m_frame(0)
       
    87     , m_style(0)
       
    88     , m_expResult(mediaFeatureResult)
       
    89 {
       
    90 }
       
    91 
       
    92 MediaQueryEvaluator:: MediaQueryEvaluator(const char* acceptedMediaType, bool mediaFeatureResult)
       
    93     : m_mediaType(acceptedMediaType)
       
    94     , m_frame(0)
       
    95     , m_style(0)
       
    96     , m_expResult(mediaFeatureResult)
       
    97 {
       
    98 }
       
    99 
       
   100 MediaQueryEvaluator:: MediaQueryEvaluator(const String& acceptedMediaType, Frame* frame, RenderStyle* style)
       
   101     : m_mediaType(acceptedMediaType)
       
   102     , m_frame(frame)
       
   103     , m_style(style)
       
   104     , m_expResult(false) // doesn't matter when we have m_frame and m_style
       
   105 {
       
   106 }
       
   107 
       
   108 MediaQueryEvaluator::~MediaQueryEvaluator()
       
   109 {
       
   110 }
       
   111 
       
   112 bool MediaQueryEvaluator::mediaTypeMatch(const String& mediaTypeToMatch) const
       
   113 {
       
   114     return mediaTypeToMatch.isEmpty()
       
   115         || equalIgnoringCase(mediaTypeToMatch, "all")
       
   116         || equalIgnoringCase(mediaTypeToMatch, m_mediaType);
       
   117 }
       
   118 
       
   119 bool MediaQueryEvaluator::mediaTypeMatchSpecific(const char* mediaTypeToMatch) const
       
   120 {
       
   121     // Like mediaTypeMatch, but without the special cases for "" and "all".
       
   122     ASSERT(mediaTypeToMatch);
       
   123     ASSERT(mediaTypeToMatch[0] != '\0');
       
   124     ASSERT(!equalIgnoringCase(mediaTypeToMatch, String("all")));
       
   125     return equalIgnoringCase(mediaTypeToMatch, m_mediaType);
       
   126 }
       
   127 
       
   128 static bool applyRestrictor(MediaQuery::Restrictor r, bool value)
       
   129 {
       
   130     return r == MediaQuery::Not ? !value : value;
       
   131 }
       
   132 
       
   133 bool MediaQueryEvaluator::eval(const MediaList* mediaList, CSSStyleSelector* styleSelector) const
       
   134 {
       
   135     if (!mediaList)
       
   136         return true;
       
   137 
       
   138     const Vector<MediaQuery*>& queries = mediaList->mediaQueries();
       
   139     if (!queries.size())
       
   140         return true; // empty query list evaluates to true
       
   141 
       
   142     // iterate over queries, stop if any of them eval to true (OR semantics)
       
   143     bool result = false;
       
   144     for (size_t i = 0; i < queries.size() && !result; ++i) {
       
   145         MediaQuery* query = queries.at(i);
       
   146 
       
   147         if (query->ignored())
       
   148             continue;
       
   149 
       
   150         if (mediaTypeMatch(query->mediaType())) {
       
   151             const Vector<MediaQueryExp*>* exps = query->expressions();
       
   152             // iterate through expressions, stop if any of them eval to false
       
   153             // (AND semantics)
       
   154             size_t j = 0;
       
   155             for (; j < exps->size(); ++j) {
       
   156                 bool exprResult = eval(exps->at(j));
       
   157                 if (styleSelector && exps->at(j)->isViewportDependent())
       
   158                     styleSelector->addViewportDependentMediaQueryResult(exps->at(j), exprResult);
       
   159                 if (!exprResult)
       
   160                     break;
       
   161             }
       
   162 
       
   163             // assume true if we are at the end of the list,
       
   164             // otherwise assume false
       
   165             result = applyRestrictor(query->restrictor(), exps->size() == j);
       
   166         } else
       
   167             result = applyRestrictor(query->restrictor(), false);
       
   168     }
       
   169 
       
   170     return result;
       
   171 }
       
   172 
       
   173 static bool parseAspectRatio(CSSValue* value, int& h, int& v)
       
   174 {
       
   175     if (value->isValueList()) {
       
   176         CSSValueList* valueList = static_cast<CSSValueList*>(value);
       
   177         if (valueList->length() == 3) {
       
   178             CSSValue* i0 = valueList->itemWithoutBoundsCheck(0);
       
   179             CSSValue* i1 = valueList->itemWithoutBoundsCheck(1);
       
   180             CSSValue* i2 = valueList->itemWithoutBoundsCheck(2);
       
   181             if (i0->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i0)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER
       
   182                 && i1->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i1)->primitiveType() == CSSPrimitiveValue::CSS_STRING
       
   183                 && i2->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i2)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) {
       
   184                 String str = static_cast<CSSPrimitiveValue*>(i1)->getStringValue();
       
   185                 if (!str.isNull() && str.length() == 1 && str[0] == '/') {
       
   186                     h = static_cast<CSSPrimitiveValue*>(i0)->getIntValue(CSSPrimitiveValue::CSS_NUMBER);
       
   187                     v = static_cast<CSSPrimitiveValue*>(i2)->getIntValue(CSSPrimitiveValue::CSS_NUMBER);
       
   188                     return true;
       
   189                 }
       
   190             }
       
   191         }
       
   192     }
       
   193     return false;
       
   194 }
       
   195 
       
   196 template<typename T>
       
   197 bool compareValue(T a, T b, MediaFeaturePrefix op)
       
   198 {
       
   199     switch (op) {
       
   200     case MinPrefix:
       
   201         return a >= b;
       
   202     case MaxPrefix:
       
   203         return a <= b;
       
   204     case NoPrefix:
       
   205         return a == b;
       
   206     }
       
   207     return false;
       
   208 }
       
   209 
       
   210 static bool numberValue(CSSValue* value, float& result)
       
   211 {
       
   212     if (value->isPrimitiveValue()
       
   213         && static_cast<CSSPrimitiveValue*>(value)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) {
       
   214         result = static_cast<CSSPrimitiveValue*>(value)->getFloatValue(CSSPrimitiveValue::CSS_NUMBER);
       
   215         return true;
       
   216     }
       
   217     return false;
       
   218 }
       
   219 
       
   220 static bool colorMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
       
   221 {
       
   222     int bitsPerComponent = screenDepthPerComponent(frame->page()->mainFrame()->view());
       
   223     float number;
       
   224     if (value)
       
   225         return numberValue(value, number) && compareValue(bitsPerComponent, static_cast<int>(number), op);
       
   226 
       
   227     return bitsPerComponent != 0;
       
   228 }
       
   229 
       
   230 static bool monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
       
   231 {
       
   232     if (!screenIsMonochrome(frame->page()->mainFrame()->view())) {
       
   233         if (value) {
       
   234             float number;
       
   235             return numberValue(value, number) && compareValue(0, static_cast<int>(number), op);
       
   236         }
       
   237         return false;
       
   238     }
       
   239 
       
   240     return colorMediaFeatureEval(value, style, frame, op);
       
   241 }
       
   242 
       
   243 static bool orientationMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix)
       
   244 {
       
   245     // A missing parameter should fail
       
   246     if (!value)
       
   247         return false;
       
   248 
       
   249     FrameView* view = frame->view();
       
   250     int width = view->layoutWidth();
       
   251     int height = view->layoutHeight();
       
   252     if (width > height) // Square viewport is portrait
       
   253         return "landscape" == static_cast<CSSPrimitiveValue*>(value)->getStringValue();
       
   254     return "portrait" == static_cast<CSSPrimitiveValue*>(value)->getStringValue();
       
   255 }
       
   256 
       
   257 static bool aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
       
   258 {
       
   259     if (value) {
       
   260         FrameView* view = frame->view();
       
   261         int width = view->layoutWidth();
       
   262         int height = view->layoutHeight();
       
   263         int h = 0;
       
   264         int v = 0;
       
   265         if (parseAspectRatio(value, h, v))
       
   266             return v != 0 && compareValue(width * v, height * h, op);
       
   267         return false;
       
   268     }
       
   269 
       
   270     // ({,min-,max-}aspect-ratio)
       
   271     // assume if we have a device, its aspect ratio is non-zero
       
   272     return true;
       
   273 }
       
   274 
       
   275 static bool device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
       
   276 {
       
   277     if (value) {
       
   278         FloatRect sg = screenRect(frame->page()->mainFrame()->view());
       
   279         int h = 0;
       
   280         int v = 0;
       
   281         if (parseAspectRatio(value, h, v))
       
   282             return v != 0  && compareValue(static_cast<int>(sg.width()) * v, static_cast<int>(sg.height()) * h, op);
       
   283         return false;
       
   284     }
       
   285 
       
   286     // ({,min-,max-}device-aspect-ratio)
       
   287     // assume if we have a device, its aspect ratio is non-zero
       
   288     return true;
       
   289 }
       
   290 
       
   291 static bool device_pixel_ratioMediaFeatureEval(CSSValue *value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
       
   292 {
       
   293     if (value)
       
   294         return value->isPrimitiveValue() && compareValue(frame->page()->chrome()->scaleFactor(), static_cast<CSSPrimitiveValue*>(value)->getFloatValue(), op);
       
   295 
       
   296     return frame->page()->chrome()->scaleFactor() != 0;
       
   297 }
       
   298 
       
   299 static bool gridMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
       
   300 {
       
   301     // if output device is bitmap, grid: 0 == true
       
   302     // assume we have bitmap device
       
   303     float number;
       
   304     if (value && numberValue(value, number))
       
   305         return compareValue(static_cast<int>(number), 0, op);
       
   306     return false;
       
   307 }
       
   308 
       
   309 static bool device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
       
   310 {
       
   311     if (value) {
       
   312         FloatRect sg = screenRect(frame->page()->mainFrame()->view());
       
   313         RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle();
       
   314         return value->isPrimitiveValue() && compareValue(static_cast<int>(sg.height()), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style, rootStyle), op);
       
   315     }
       
   316     // ({,min-,max-}device-height)
       
   317     // assume if we have a device, assume non-zero
       
   318     return true;
       
   319 }
       
   320 
       
   321 static bool device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
       
   322 {
       
   323     if (value) {
       
   324         FloatRect sg = screenRect(frame->page()->mainFrame()->view());
       
   325         RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle();
       
   326         return value->isPrimitiveValue() && compareValue(static_cast<int>(sg.width()), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style, rootStyle), op);
       
   327     }
       
   328     // ({,min-,max-}device-width)
       
   329     // assume if we have a device, assume non-zero
       
   330     return true;
       
   331 }
       
   332 
       
   333 static bool heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
       
   334 {
       
   335     FrameView* view = frame->view();
       
   336     RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle();
       
   337 
       
   338     if (value)
       
   339         return value->isPrimitiveValue() && compareValue(view->layoutHeight(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style, rootStyle), op);
       
   340 
       
   341     return view->layoutHeight() != 0;
       
   342 }
       
   343 
       
   344 static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
       
   345 {
       
   346     FrameView* view = frame->view();
       
   347     RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle();
       
   348 
       
   349     if (value)
       
   350         return value->isPrimitiveValue() && compareValue(view->layoutWidth(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style, rootStyle), op);
       
   351 
       
   352     return view->layoutWidth() != 0;
       
   353 }
       
   354 
       
   355 // rest of the functions are trampolines which set the prefix according to the media feature expression used
       
   356 
       
   357 static bool min_colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   358 {
       
   359     return colorMediaFeatureEval(value, style, frame, MinPrefix);
       
   360 }
       
   361 
       
   362 static bool max_colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   363 {
       
   364     return colorMediaFeatureEval(value, style, frame, MaxPrefix);
       
   365 }
       
   366 
       
   367 static bool min_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   368 {
       
   369     return monochromeMediaFeatureEval(value, style, frame, MinPrefix);
       
   370 }
       
   371 
       
   372 static bool max_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   373 {
       
   374     return monochromeMediaFeatureEval(value, style, frame, MaxPrefix);
       
   375 }
       
   376 
       
   377 static bool min_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   378 {
       
   379     return aspect_ratioMediaFeatureEval(value, style, frame, MinPrefix);
       
   380 }
       
   381 
       
   382 static bool max_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   383 {
       
   384     return aspect_ratioMediaFeatureEval(value, style, frame, MaxPrefix);
       
   385 }
       
   386 
       
   387 static bool min_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   388 {
       
   389     return device_aspect_ratioMediaFeatureEval(value, style, frame, MinPrefix);
       
   390 }
       
   391 
       
   392 static bool max_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   393 {
       
   394     return device_aspect_ratioMediaFeatureEval(value, style, frame, MaxPrefix);
       
   395 }
       
   396 
       
   397 static bool min_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   398 {
       
   399     return device_pixel_ratioMediaFeatureEval(value, style, frame, MinPrefix);
       
   400 }
       
   401 
       
   402 static bool max_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   403 {
       
   404     return device_pixel_ratioMediaFeatureEval(value, style, frame, MaxPrefix);
       
   405 }
       
   406 
       
   407 static bool min_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   408 {
       
   409     return heightMediaFeatureEval(value, style, frame, MinPrefix);
       
   410 }
       
   411 
       
   412 static bool max_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   413 {
       
   414     return heightMediaFeatureEval(value, style, frame, MaxPrefix);
       
   415 }
       
   416 
       
   417 static bool min_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   418 {
       
   419     return widthMediaFeatureEval(value, style, frame, MinPrefix);
       
   420 }
       
   421 
       
   422 static bool max_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   423 {
       
   424     return widthMediaFeatureEval(value, style, frame, MaxPrefix);
       
   425 }
       
   426 
       
   427 static bool min_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   428 {
       
   429     return device_heightMediaFeatureEval(value, style, frame, MinPrefix);
       
   430 }
       
   431 
       
   432 static bool max_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   433 {
       
   434     return device_heightMediaFeatureEval(value, style, frame, MaxPrefix);
       
   435 }
       
   436 
       
   437 static bool min_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   438 {
       
   439     return device_widthMediaFeatureEval(value, style, frame, MinPrefix);
       
   440 }
       
   441 
       
   442 static bool max_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
       
   443 {
       
   444     return device_widthMediaFeatureEval(value, style, frame, MaxPrefix);
       
   445 }
       
   446 
       
   447 static bool animationMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
       
   448 {
       
   449     if (value) {
       
   450         float number;
       
   451         return numberValue(value, number) && compareValue(1, static_cast<int>(number), op);
       
   452     }
       
   453     return true;
       
   454 }
       
   455 
       
   456 static bool transitionMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
       
   457 {
       
   458     if (value) {
       
   459         float number;
       
   460         return numberValue(value, number) && compareValue(1, static_cast<int>(number), op);
       
   461     }
       
   462     return true;
       
   463 }
       
   464 
       
   465 static bool transform_2dMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
       
   466 {
       
   467     if (value) {
       
   468         float number;
       
   469         return numberValue(value, number) && compareValue(1, static_cast<int>(number), op);
       
   470     }
       
   471     return true;
       
   472 }
       
   473 
       
   474 static bool transform_3dMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
       
   475 {
       
   476     bool returnValueIfNoParameter;
       
   477     int have3dRendering;
       
   478 
       
   479 #if ENABLE(3D_RENDERING)
       
   480     bool threeDEnabled = false;
       
   481 #if USE(ACCELERATED_COMPOSITING)
       
   482     if (RenderView* view = frame->contentRenderer())
       
   483         threeDEnabled = view->compositor()->hasAcceleratedCompositing();
       
   484 #endif
       
   485 
       
   486     returnValueIfNoParameter = threeDEnabled;
       
   487     have3dRendering = threeDEnabled ? 1 : 0;
       
   488 #else
       
   489     UNUSED_PARAM(frame);
       
   490     returnValueIfNoParameter = false;
       
   491     have3dRendering = 0;
       
   492 #endif
       
   493 
       
   494     if (value) {
       
   495         float number;
       
   496         return numberValue(value, number) && compareValue(have3dRendering, static_cast<int>(number), op);
       
   497     }
       
   498     return returnValueIfNoParameter;
       
   499 }
       
   500 
       
   501 #if ENABLE(WIDGETS_10_SUPPORT)
       
   502 static bool view_modeMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
       
   503 {
       
   504     if (value) {
       
   505         String mode = static_cast<CSSPrimitiveValue*>(value)->getStringValue();
       
   506         if (ChromeClient* client = frame->page()->chrome()->client()) {
       
   507             if (mode == "windowed" && client->isWindowed())
       
   508                 return true;
       
   509             if (mode == "floating" && client->isFloating())
       
   510                 return true;
       
   511             if (mode == "fullscreen" && client->isFullscreen())
       
   512                 return true;
       
   513             if (mode == "maximized" && client->isMaximized())
       
   514                 return true;
       
   515             if (mode == "minimized" && client->isMinimized())
       
   516                 return true;
       
   517             return false;
       
   518         }
       
   519     }
       
   520     return true;
       
   521 }
       
   522 #endif
       
   523 
       
   524 static void createFunctionMap()
       
   525 {
       
   526     // Create the table.
       
   527     gFunctionMap = new FunctionMap;
       
   528 #define ADD_TO_FUNCTIONMAP(name, str)  \
       
   529     gFunctionMap->set(name##MediaFeature.impl(), name##MediaFeatureEval);
       
   530     CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(ADD_TO_FUNCTIONMAP);
       
   531 #undef ADD_TO_FUNCTIONMAP
       
   532 }
       
   533 
       
   534 bool MediaQueryEvaluator::eval(const MediaQueryExp* expr) const
       
   535 {
       
   536     if (!m_frame || !m_style)
       
   537         return m_expResult;
       
   538 
       
   539     if (!expr->isValid())
       
   540         return false;
       
   541 
       
   542     if (!gFunctionMap)
       
   543         createFunctionMap();
       
   544 
       
   545     // call the media feature evaluation function. Assume no prefix
       
   546     // and let trampoline functions override the prefix if prefix is
       
   547     // used
       
   548     EvalFunc func = gFunctionMap->get(expr->mediaFeature().impl());
       
   549     if (func)
       
   550         return func(expr->value(), m_style, m_frame, NoPrefix);
       
   551 
       
   552     return false;
       
   553 }
       
   554 
       
   555 } // namespace