Incorrect evaluation of resolution media queries

https://bugs.webkit.org/show_bug.cgi?id=114029

Patch by Rune Lillesveen <rune@opera.com> on 2013-04-11
Reviewed by Kenneth Rohde Christiansen.

.:

Removed setResolutionOverride from exports.

* Source/autotools/symbols.filter:

Source/WebCore:

The implementation used the physical resolution to evaluate the
resolution media features. Changed to use the actual CSS resolution,
also known as the device-pixel-ratio, instead. Unified the code for
evaluating the resolution and device-pixel-ratio media features.

No new tests, covered by existing tests.

* WebCore.exp.in:
* css/CSSPrimitiveValue.h:
(WebCore::CSSPrimitiveValue::isResolution):
* css/MediaQueryEvaluator.cpp:
(WebCore::evalResolution):
(WebCore::device_pixel_ratioMediaFeatureEval):
(WebCore::resolutionMediaFeatureEval):
* page/Screen.cpp:
* page/Screen.h:
* page/Settings.cpp:
(WebCore):
* page/Settings.h:
(Settings):
* testing/InternalSettings.cpp:
(WebCore::InternalSettings::Backup::Backup):
(WebCore::InternalSettings::Backup::restoreTo):
* testing/InternalSettings.h:
(Backup):
(InternalSettings):
* testing/InternalSettings.idl:

Source/WebKit:

Removed setResolutionOverride from exports.

* WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in:

Source/WebKit/win:

Removed setResolutionOverride from exports.

* WebKit.vcproj/WebKitExports.def.in:

LayoutTests:

Modified tests to change CSS resolution instead of physical resolution.

* fast/media/mq-resolution.html:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@148186 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 24591c7c
2013-04-11 Rune Lillesveen <rune@opera.com>
Incorrect evaluation of resolution media queries
https://bugs.webkit.org/show_bug.cgi?id=114029
Reviewed by Kenneth Rohde Christiansen.
Removed setResolutionOverride from exports.
* Source/autotools/symbols.filter:
2013-04-10 Anton Obzhirov <a.obzhirov@samsung.com>
[GTK] Add support for Page Visibility
......
2013-04-11 Rune Lillesveen <rune@opera.com>
Incorrect evaluation of resolution media queries
https://bugs.webkit.org/show_bug.cgi?id=114029
Reviewed by Kenneth Rohde Christiansen.
Modified tests to change CSS resolution instead of physical resolution.
* fast/media/mq-resolution.html:
2013-04-11 Manuel Rego Casasnovas <rego@igalia.com>
FrameLoaderClient::assignIdentifierToInitialRequest() not called for the main resource when loaded from the memory cache
......@@ -49,19 +49,19 @@
shouldBe("matchMedia('(min-resolution: 0dpi)').matches", "false");
shouldBe("matchMedia('(max-resolution: 0dpi)').matches", "false");
window.internals.settings.setResolutionOverride(144, 144);
window.internals.settings.setPageScaleFactor(1.5, 0, 0);
shouldBe("matchMedia('(resolution: 1.5dppx)').matches", "true");
shouldBe("resolutionFromStyle()", "1.5");
window.internals.settings.setResolutionOverride(192, 192);
window.internals.settings.setPageScaleFactor(2, 0, 0);
shouldBe("matchMedia('(resolution: 2dppx)').matches", "true");
shouldBe("resolutionFromStyle()", "2");
window.internals.settings.setResolutionOverride(96, 96);
window.internals.settings.setPageScaleFactor(1, 0, 0);
shouldBe("matchMedia('(resolution: 1dppx)').matches", "true");
shouldBe("resolutionFromStyle()", "1");
window.internals.settings.setResolutionOverride(216, 216);
window.internals.settings.setPageScaleFactor(2.25, 0, 0);
shouldBe("matchMedia('(resolution: 2.25dppx)').matches", "true");
shouldBe("resolutionFromStyle()", "2.25");
shouldBe("matchMedia('(resolution)').matches", "true");
......@@ -73,26 +73,6 @@
shouldBe("matchMedia('(min-resolution: 85dpcm)').matches", "true");
shouldBe("matchMedia('(max-resolution: 85dpcm)').matches", "true");
window.internals.settings.setResolutionOverride(216, 254);
// Non-square must never match.
shouldBe("matchMedia('(resolution)').matches", "false");
shouldBe("matchMedia('(resolution: 216dpi)').matches", "false");
shouldBe("matchMedia('(resolution: 254dpi)').matches", "false");
shouldBe("matchMedia('(min-resolution: 216dpi)').matches", "true");
shouldBe("matchMedia('(min-resolution: 254dpi)').matches", "false");
shouldBe("matchMedia('(max-resolution: 216dpi)').matches", "false");
shouldBe("matchMedia('(max-resolution: 254dpi)').matches", "true");
// Non-square must never match.
shouldBe("matchMedia('(resolution: 85dpcm)').matches", "false");
shouldBe("matchMedia('(resolution: 100dpcm)').matches", "false");
shouldBe("matchMedia('(min-resolution: 85dpcm)').matches", "true");
shouldBe("matchMedia('(min-resolution: 100dpcm)').matches", "false");
shouldBe("matchMedia('(max-resolution: 85dpcm)').matches", "false");
shouldBe("matchMedia('(max-resolution: 100dpcm)').matches", "true");
// Test printing.
window.internals.settings.setMediaTypeOverride("print");
......
2013-04-11 Rune Lillesveen <rune@opera.com>
Incorrect evaluation of resolution media queries
https://bugs.webkit.org/show_bug.cgi?id=114029
Reviewed by Kenneth Rohde Christiansen.
The implementation used the physical resolution to evaluate the
resolution media features. Changed to use the actual CSS resolution,
also known as the device-pixel-ratio, instead. Unified the code for
evaluating the resolution and device-pixel-ratio media features.
No new tests, covered by existing tests.
* WebCore.exp.in:
* css/CSSPrimitiveValue.h:
(WebCore::CSSPrimitiveValue::isResolution):
* css/MediaQueryEvaluator.cpp:
(WebCore::evalResolution):
(WebCore::device_pixel_ratioMediaFeatureEval):
(WebCore::resolutionMediaFeatureEval):
* page/Screen.cpp:
* page/Screen.h:
* page/Settings.cpp:
(WebCore):
* page/Settings.h:
(Settings):
* testing/InternalSettings.cpp:
(WebCore::InternalSettings::Backup::Backup):
(WebCore::InternalSettings::Backup::restoreTo):
* testing/InternalSettings.h:
(Backup):
(InternalSettings):
* testing/InternalSettings.idl:
2013-04-11 Carlos Garcia Campos <cgarcia@igalia.com>
FrameLoaderClient::assignIdentifierToInitialRequest() not called for the main resource when loaded from the memory cache
......@@ -1064,7 +1064,6 @@ __ZN7WebCore8Settings33setAggressiveTileRetentionEnabledEb
__ZN7WebCore8Settings37setScrollingPerformanceLoggingEnabledEb
__ZN7WebCore8Settings42setHiddenPageCSSAnimationSuspensionEnabledEb
__ZN7WebCore8Settings45setShouldRespectPriorityInCSSAttributeSettersEb
__ZN7WebCore8Settings21setResolutionOverrideERKNS_7IntSizeE
__ZN7WebCore8Settings20setMediaTypeOverrideERKN3WTF6StringE
__ZN7WebCore8Settings30setShowTiledScrollingIndicatorEb
__ZN7WebCore8blankURLEv
......
......@@ -189,6 +189,11 @@ public:
bool isDotsPerInch() const { return primitiveType() == CSS_DPI; }
bool isDotsPerPixel() const { return primitiveType() == CSS_DPPX; }
bool isDotsPerCentimeter() const { return primitiveType() == CSS_DPCM; }
bool isResolution() const
{
unsigned short type = primitiveType();
return type >= CSS_DPPX && type <= CSS_DPCM;
}
#if ENABLE(CSS_VARIABLES)
bool isVariableName() const { return primitiveType() == CSS_VARIABLE_NAME; }
......
......@@ -198,23 +198,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()
......@@ -288,7 +271,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;
......@@ -310,108 +293,28 @@ static bool device_pixel_ratioMediaFeatureEval(CSSValue *value, RenderStyle*, Fr
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.
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;
}
if (!value->isPrimitiveValue())
return false;
// 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 (rawValue->isDotsPerInch()) {
unsigned testedDensity = rawValue->getFloatValue(CSSPrimitiveValue::CSS_DPI);
return compareResolution(leastDenseDPI, mostDenseDPI, testedDensity, op);
}
CSSPrimitiveValue* resolution = static_cast<CSSPrimitiveValue*>(value);
return compareValue(deviceScaleFactor, resolution->isNumber() ? resolution->getFloatValue() : resolution->getFloatValue(CSSPrimitiveValue::CSS_DPPX), 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);
static bool device_pixel_ratioMediaFeatureEval(CSSValue *value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
{
return (!value || static_cast<CSSPrimitiveValue*>(value)->isNumber()) && evalResolution(value, frame, op);
}
if (rawValue->isDotsPerCentimeter()) {
float testedDensity = rawValue->getFloatValue(CSSPrimitiveValue::CSS_DPCM);
return compareResolution(leastDenseDPCM, mostDenseDPCM, testedDensity, op);
}
static bool resolutionMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
{
#if ENABLE(RESOLUTION_MEDIA_QUERY)
return (!value || static_cast<CSSPrimitiveValue*>(value)->isResolution()) && evalResolution(value, frame, op);
#else
UNUSED_PARAM(value);
UNUSED_PARAM(frame);
UNUSED_PARAM(op);
#endif
return false;
#endif
}
static bool gridMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
......
......@@ -45,35 +45,6 @@ Screen::Screen(Frame* frame)
{
}
unsigned Screen::horizontalDPI() const
{
if (!m_frame)
return 0;
// Used by the testing system, can be set from internals.
IntSize override = m_frame->page()->settings()->resolutionOverride();
if (!override.isEmpty())
return override.width();
// The DPI is defined as dots per CSS inch and thus not device inch.
return m_frame->page()->deviceScaleFactor() * 96;
}
unsigned Screen::verticalDPI() const
{
// The DPI is defined as dots per CSS inch and thus not device inch.
if (!m_frame)
return 0;
// Used by the testing system, can be set from internals.
IntSize override = m_frame->page()->settings()->resolutionOverride();
if (!override.isEmpty())
return override.height();
// The DPI is defined as dots per CSS inch and thus not device inch.
return m_frame->page()->deviceScaleFactor() * 96;
}
unsigned Screen::height() const
{
if (!m_frame)
......
......@@ -43,8 +43,6 @@ namespace WebCore {
public:
static PassRefPtr<Screen> create(Frame *frame) { return adoptRef(new Screen(frame)); }
unsigned horizontalDPI() const;
unsigned verticalDPI() const;
unsigned height() const;
unsigned width() const;
unsigned colorDepth() const;
......
......@@ -320,15 +320,6 @@ void Settings::setTextAutosizingFontScaleFactor(float fontScaleFactor)
#endif
void Settings::setResolutionOverride(const IntSize& densityPerInchOverride)
{
if (m_resolutionDensityPerInchOverride == densityPerInchOverride)
return;
m_resolutionDensityPerInchOverride = densityPerInchOverride;
m_page->setNeedsRecalcStyleInAllFrames();
}
void Settings::setMediaTypeOverride(const String& mediaTypeOverride)
{
if (m_mediaTypeOverride == mediaTypeOverride)
......
......@@ -106,10 +106,6 @@ namespace WebCore {
const IntSize& textAutosizingWindowSizeOverride() const { return m_textAutosizingWindowSizeOverride; }
#endif
// Only set by Layout Tests.
void setResolutionOverride(const IntSize&);
const IntSize& resolutionOverride() const { return m_resolutionDensityPerInchOverride; }
// Only set by Layout Tests.
void setMediaTypeOverride(const String&);
const String& mediaTypeOverride() const { return m_mediaTypeOverride; }
......@@ -292,7 +288,6 @@ namespace WebCore {
IntSize m_textAutosizingWindowSizeOverride;
bool m_textAutosizingEnabled : 1;
#endif
IntSize m_resolutionDensityPerInchOverride;
SETTINGS_MEMBER_VARIABLES
......
......@@ -81,7 +81,6 @@ InternalSettings::Backup::Backup(Settings* settings)
, m_originalTextAutosizingWindowSizeOverride(settings->textAutosizingWindowSizeOverride())
, m_originalTextAutosizingFontScaleFactor(settings->textAutosizingFontScaleFactor())
#endif
, m_originalResolutionOverride(settings->resolutionOverride())
, m_originalMediaTypeOverride(settings->mediaTypeOverride())
#if ENABLE(DIALOG_ELEMENT)
, m_originalDialogElementEnabled(RuntimeEnabledFeatures::dialogElementEnabled())
......@@ -119,7 +118,6 @@ void InternalSettings::Backup::restoreTo(Settings* settings)
settings->setTextAutosizingWindowSizeOverride(m_originalTextAutosizingWindowSizeOverride);
settings->setTextAutosizingFontScaleFactor(m_originalTextAutosizingFontScaleFactor);
#endif
settings->setResolutionOverride(m_originalResolutionOverride);
settings->setMediaTypeOverride(m_originalMediaTypeOverride);
#if ENABLE(DIALOG_ELEMENT)
RuntimeEnabledFeatures::setDialogElementEnabled(m_originalDialogElementEnabled);
......@@ -330,13 +328,6 @@ void InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height
#endif
}
void InternalSettings::setResolutionOverride(int dotsPerCSSInchHorizontally, int dotsPerCSSInchVertically, ExceptionCode& ec)
{
InternalSettingsGuardForSettings();
// An empty size resets the override.
settings()->setResolutionOverride(IntSize(dotsPerCSSInchHorizontally, dotsPerCSSInchVertically));
}
void InternalSettings::setMediaTypeOverride(const String& mediaType, ExceptionCode& ec)
{
InternalSettingsGuardForSettings();
......
......@@ -65,7 +65,6 @@ public:
IntSize m_originalTextAutosizingWindowSizeOverride;
float m_originalTextAutosizingFontScaleFactor;
#endif
IntSize m_originalResolutionOverride;
String m_originalMediaTypeOverride;
#if ENABLE(DIALOG_ELEMENT)
bool m_originalDialogElementEnabled;
......@@ -112,7 +111,6 @@ public:
void setTextAutosizingEnabled(bool enabled, ExceptionCode&);
void setTextAutosizingWindowSizeOverride(int width, int height, ExceptionCode&);
void setTextAutosizingFontScaleFactor(float fontScaleFactor, ExceptionCode&);
void setResolutionOverride(int dotsPerCSSInchHorizontally, int dotsPerCSSInchVertically, ExceptionCode&);
void setMediaTypeOverride(const String& mediaType, ExceptionCode&);
void setCSSExclusionsEnabled(bool enabled, ExceptionCode&);
void setCSSVariablesEnabled(bool enabled, ExceptionCode&);
......
......@@ -42,7 +42,6 @@
void setTextAutosizingEnabled(in boolean enabled) raises(DOMException);
void setTextAutosizingWindowSizeOverride(in long width, in long height) raises(DOMException);
void setTextAutosizingFontScaleFactor(in float fontScaleFactor) raises(DOMException);
void setResolutionOverride(in long dotsPerCSSInchHorizontally, in long dotsPerCSSInchVertically) raises(DOMException);
void setMediaTypeOverride(in DOMString mediaTypeOverride) raises(DOMException);
void setCSSExclusionsEnabled(in boolean enabled) raises(DOMException);
void setCSSVariablesEnabled(in boolean enabled) raises(DOMException);
......
2013-04-11 Rune Lillesveen <rune@opera.com>
Incorrect evaluation of resolution media queries
https://bugs.webkit.org/show_bug.cgi?id=114029
Reviewed by Kenneth Rohde Christiansen.
Removed setResolutionOverride from exports.
* WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in:
2013-04-05 Roger Fong <roger_fong@apple.com>
Build fix.
......
......@@ -274,7 +274,6 @@ EXPORTS
?setSuggestedValue@HTMLInputElement@WebCore@@QAEXABVString@WTF@@@Z
?setEditingValue@HTMLInputElement@WebCore@@QAEXABVString@WTF@@@Z
?setPseudo@Element@WebCore@@QAEXABVAtomicString@WTF@@@Z
?setResolutionOverride@Settings@WebCore@@QAEXABVIntSize@2@@Z
?setMediaTypeOverride@Settings@WebCore@@QAEXABVString@WTF@@@Z
?settings@Document@WebCore@@QBEPAVSettings@2@XZ
?settings@Frame@WebCore@@QBEPAVSettings@2@XZ
......
2013-04-11 Rune Lillesveen <rune@opera.com>
Incorrect evaluation of resolution media queries
https://bugs.webkit.org/show_bug.cgi?id=114029
Reviewed by Kenneth Rohde Christiansen.
Removed setResolutionOverride from exports.
* WebKit.vcproj/WebKitExports.def.in:
2013-04-08 Anders Carlsson <andersca@apple.com>
Remove unneeded headers from FrameLoader.h
......
......@@ -274,7 +274,6 @@ EXPORTS
?setSuggestedValue@HTMLInputElement@WebCore@@QAEXABVString@WTF@@@Z
?setEditingValue@HTMLInputElement@WebCore@@QAEXABVString@WTF@@@Z
?setPseudo@Element@WebCore@@QAEXABVAtomicString@WTF@@@Z
?setResolutionOverride@Settings@WebCore@@QAEXABVIntSize@2@@Z
?setMediaTypeOverride@Settings@WebCore@@QAEXABVString@WTF@@@Z
?settings@Document@WebCore@@QBEPAVSettings@2@XZ
?settings@Frame@WebCore@@QBEPAVSettings@2@XZ
......
......@@ -217,7 +217,6 @@ _ZN7WebCore8Settings20setCursiveFontFamilyERKN3WTF12AtomicStringE11UScriptCode;
_ZN7WebCore8Settings20setFantasyFontFamilyERKN3WTF12AtomicStringE11UScriptCode;
_ZN7WebCore8Settings20setMediaTypeOverrideERKN3WTF6StringE;
_ZN7WebCore8Settings21mockScrollbarsEnabledEv;
_ZN7WebCore8Settings21setResolutionOverrideERKNS_7IntSizeE;
_ZN7WebCore8Settings21setShowRepaintCounterEb;
_ZN7WebCore8Settings21setStandardFontFamilyERKN3WTF12AtomicStringE11UScriptCode;
_ZN7WebCore8Settings22setSansSerifFontFamilyERKN3WTF12AtomicStringE11UScriptCode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment