Index: Source/core/css/MediaQueryEvaluator.cpp |
diff --git a/Source/core/css/MediaQueryEvaluator.cpp b/Source/core/css/MediaQueryEvaluator.cpp |
index db54b7745bd630e9548e8c5356a84526e4eac674..80f69690b0b6a899b63a3d8923fb9bef8f9622ae 100644 |
--- a/Source/core/css/MediaQueryEvaluator.cpp |
+++ b/Source/core/css/MediaQueryEvaluator.cpp |
@@ -38,6 +38,7 @@ |
#include "core/css/MediaQuery.h" |
#include "core/css/MediaQueryExp.h" |
#include "core/css/StyleResolver.h" |
+#include "core/css/CSSHelper.h" |
#include "core/dom/NodeRenderStyle.h" |
#include "core/page/Chrome.h" |
#include "core/page/ChromeClient.h" |
@@ -195,23 +196,6 @@ static bool compareAspectRatioValue(CSSValue* value, int width, int height, Medi |
return false; |
} |
-#if ENABLE(RESOLUTION_MEDIA_QUERY) |
-static bool compareResolution(float min, float max, float value, MediaFeaturePrefix op) |
-{ |
- switch (op) { |
- case NoPrefix: |
- // A 'resolution' (without a "min-" or "max-" prefix) query |
- // never matches a device with non-square pixels. |
- return value == min && value == max; |
- case MinPrefix: |
- return min >= value; |
- case MaxPrefix: |
- return max <= value; |
- } |
- return false; |
-} |
-#endif |
- |
static bool numberValue(CSSValue* value, float& result) |
{ |
if (value->isPrimitiveValue() |
@@ -285,7 +269,7 @@ static bool device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle*, F |
return true; |
} |
-static bool device_pixel_ratioMediaFeatureEval(CSSValue *value, RenderStyle*, Frame* frame, MediaFeaturePrefix op) |
+static bool evalResolution(CSSValue* value, Frame* frame, MediaFeaturePrefix op) |
{ |
// FIXME: Possible handle other media types than 'screen' and 'print'. |
float deviceScaleFactor = 0; |
@@ -298,117 +282,48 @@ static bool device_pixel_ratioMediaFeatureEval(CSSValue *value, RenderStyle*, Fr |
if (equalIgnoringCase(mediaType, "screen")) |
deviceScaleFactor = frame->page()->deviceScaleFactor(); |
else if (equalIgnoringCase(mediaType, "print")) { |
- // The resolution of images while printing should not depend on the dpi |
+ // The resolution of images while printing should not depend on the DPI |
// of the screen. Until we support proper ways of querying this info |
// we use 300px which is considered minimum for current printers. |
- deviceScaleFactor = 3.125; // 300dpi / 96dpi; |
+ deviceScaleFactor = 300 / cssPixelsPerInch; |
} |
if (!value) |
return !!deviceScaleFactor; |
- return value->isPrimitiveValue() && compareValue(deviceScaleFactor, static_cast<CSSPrimitiveValue*>(value)->getFloatValue(), op); |
-} |
- |
-static bool resolutionMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op) |
-{ |
-#if ENABLE(RESOLUTION_MEDIA_QUERY) |
- // The DPI below is dots per CSS inch and thus not device inch. The |
- // functions should respect this. |
- // |
- // For square pixels, it is simply the device scale factor (dppx) times 96, |
- // per definition. |
- // |
- // The device scale factor is a predefined value which is calculated per |
- // device given the preferred distance in arms length (considered one arms |
- // length for desktop computers and usually 0.6 arms length for phones). |
- // |
- // The value can be calculated as follows (rounded to quarters): |
- // round((deviceDotsPerInch * distanceInArmsLength / 96) * 4) / 4. |
- // Example (mid-range resolution phone): |
- // round((244 * 0.6 / 96) * 4) / 4 = 1.5 |
- // Example (high-range resolution laptop): |
- // round((220 * 1.0 / 96) * 4) / 4 = 2.0 |
- |
- float horiDPI; |
- float vertDPI; |
- |
- // This checks the actual media type applied to the document, and we know |
- // this method only got called if this media type matches the one defined |
- // in the query. Thus, if if the document's media type is "print", the |
- // media type of the query will either be "print" or "all". |
- String mediaType = frame->view()->mediaType(); |
- if (equalIgnoringCase(mediaType, "screen")) { |
- Screen* screen = frame->document()->domWindow()->screen(); |
- horiDPI = screen->horizontalDPI(); |
- vertDPI = screen->verticalDPI(); |
- } else if (equalIgnoringCase(mediaType, "print")) { |
- // The resolution of images while printing should not depend on the dpi |
- // of the screen. Until we support proper ways of querying this info |
- // we use 300px which is considered minimum for current printers. |
- horiDPI = vertDPI = 300; |
- } else { |
- // FIXME: Possible handle other media types than 'screen' and 'print'. |
- // For now, do not match. |
+ if (!value->isPrimitiveValue()) |
return false; |
- } |
- float leastDenseDPI = std::min(horiDPI, vertDPI); |
- float mostDenseDPI = std::max(horiDPI, vertDPI); |
- |
- // According to spec, (resolution) will evaluate to true if (resolution:x) |
- // will evaluate to true for a value x other than zero or zero followed by |
- // a valid unit identifier (i.e., other than 0, 0dpi, 0dpcm, or 0dppx.), |
- // which is always the case. But the spec special cases 'resolution' to |
- // never matches a device with non-square pixels. |
- if (!value) { |
- ASSERT(op == NoPrefix); |
- return leastDenseDPI == mostDenseDPI; |
- } |
+ CSSPrimitiveValue* resolution = static_cast<CSSPrimitiveValue*>(value); |
- if (!value->isPrimitiveValue()) |
- return false; |
+ if (resolution->isNumber()) |
+ return compareValue(deviceScaleFactor, resolution->getFloatValue(), op); |
- // http://dev.w3.org/csswg/css3-values/#resolution defines resolution as a |
- // dimension, which contains a number (decimal point allowed), not just an |
- // integer. Also, http://dev.w3.org/csswg/css3-values/#numeric-types says |
- // "CSS theoretically supports infinite precision and infinite ranges for |
- // all value types; |
- CSSPrimitiveValue* rawValue = static_cast<CSSPrimitiveValue*>(value); |
- |
- if (rawValue->isDotsPerPixel()) { |
- // http://dev.w3.org/csswg/css3-values/#absolute-lengths recommends |
- // "that the pixel unit refer to the whole number of device pixels that |
- // best approximates the reference pixel". We compare with 3 decimal |
- // points, which aligns with current device-pixel-ratio's in use. |
- float leastDenseDensity = floorf(leastDenseDPI * 1000 / 96) / 1000; |
- float mostDenseDensity = floorf(leastDenseDPI * 1000 / 96) / 1000; |
- float testedDensity = rawValue->getFloatValue(CSSPrimitiveValue::CSS_DPPX); |
- return compareResolution(leastDenseDensity, mostDenseDensity, testedDensity, op); |
- } |
+ if (!resolution->isResolution()) |
+ return false; |
- if (rawValue->isDotsPerInch()) { |
- unsigned testedDensity = rawValue->getFloatValue(CSSPrimitiveValue::CSS_DPI); |
- return compareResolution(leastDenseDPI, mostDenseDPI, testedDensity, op); |
+ if (resolution->isDotsPerCentimeter()) { |
+ // To match DPCM to DPPX values, we limit to 2 decimal points. |
+ // The http://dev.w3.org/csswg/css3-values/#absolute-lengths recommends |
+ // "that the pixel unit refer to the whole number of device pixels that best |
+ // approximates the reference pixel". With that in mind, allowing 2 decimal |
+ // point precision seems appropriate. |
+ return compareValue( |
+ floorf(0.5 + 100 * deviceScaleFactor) / 100, |
+ floorf(0.5 + 100 * resolution->getFloatValue(CSSPrimitiveValue::CSS_DPPX)) / 100, op); |
} |
- // http://dev.w3.org/csswg/css3-values/#absolute-lengths recommends "that |
- // the pixel unit refer to the whole number of device pixels that best |
- // approximates the reference pixel". |
- float leastDenseDPCM = roundf(leastDenseDPI / 2.54); // (2.54 cm/in) |
- float mostDenseDPCM = roundf(mostDenseDPI / 2.54); |
+ return compareValue(deviceScaleFactor, resolution->getFloatValue(CSSPrimitiveValue::CSS_DPPX), op); |
+} |
- if (rawValue->isDotsPerCentimeter()) { |
- float testedDensity = rawValue->getFloatValue(CSSPrimitiveValue::CSS_DPCM); |
- return compareResolution(leastDenseDPCM, mostDenseDPCM, testedDensity, op); |
- } |
-#else |
- UNUSED_PARAM(value); |
- UNUSED_PARAM(frame); |
- UNUSED_PARAM(op); |
-#endif |
+static bool device_pixel_ratioMediaFeatureEval(CSSValue *value, RenderStyle*, Frame* frame, MediaFeaturePrefix op) |
+{ |
+ return (!value || static_cast<CSSPrimitiveValue*>(value)->isNumber()) && evalResolution(value, frame, op); |
+} |
- return false; |
+static bool resolutionMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op) |
+{ |
+ return (!value || static_cast<CSSPrimitiveValue*>(value)->isResolution()) && evalResolution(value, frame, op); |
} |
static bool gridMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op) |