Bug 1376931 Part 3: Change Gecko media queries of resolution to compare in dppx units without unit conversion. draft
authorBrad Werth <bwerth@mozilla.com>
Wed, 27 Sep 2017 16:53:27 -0700
changeset 675304 d01d87223b630277c024e95e9a74d421bf39ce86
parent 675303 39316b48f3e3fc757a6fbc531e62d543caa1ce6b
child 675305 0fd99b4f97673613300557a9b0d0b6504844c55b
push id83098
push userbwerth@mozilla.com
push dateThu, 05 Oct 2017 04:35:10 +0000
bugs1376931
milestone58.0a1
Bug 1376931 Part 3: Change Gecko media queries of resolution to compare in dppx units without unit conversion. MozReview-Commit-ID: DPdz1Tmv24R
layout/style/nsMediaFeatures.cpp
layout/style/nsMediaList.cpp
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
@@ -274,26 +274,34 @@ GetMonochrome(nsPresContext* aPresContex
   // 0!
   aResult.SetIntValue(0, eCSSUnit_Integer);
 }
 
 static void
 GetResolution(nsPresContext* aPresContext, const nsMediaFeature*,
               nsCSSValue& aResult)
 {
-  float dpi = 96; // Use 96 when resisting fingerprinting.
+  // We're returning resolution in terms of device pixels per css pixel, since
+  // that is the preferred unit for media queries of resolution. This avoids
+  // introducing precision error from conversion to and from less-used
+  // physical units like inches.
+
+  float dppx;
 
   if (!ShouldResistFingerprinting(aPresContext)) {
-    // Resolution measures device pixels per CSS (inch/cm/pixel).  We
-    // return it in device pixels per CSS inches.
-    dpi = float(nsPresContext::AppUnitsPerCSSInch()) /
-          float(aPresContext->AppUnitsPerDevPixel());
+    // Get the actual device pixel ratio, which also takes zoom into account.
+    dppx = float(nsPresContext::AppUnitsPerCSSPixel()) /
+             aPresContext->AppUnitsPerDevPixel();
+  } else {
+    // We are resisting fingerprinting, so pretend we have a device pixel ratio
+    // of 1. In that case, we simply report the zoom level.
+    dppx = aPresContext->GetDeviceFullZoom();
   }
 
-  aResult.SetFloatValue(dpi, eCSSUnit_Inch);
+  aResult.SetFloatValue(dppx, eCSSUnit_Pixel);
 }
 
 static void
 GetScan(nsPresContext* aPresContext, const nsMediaFeature*,
         nsCSSValue& aResult)
 {
   // Since Gecko doesn't support the 'tv' media type, the 'scan'
   // feature is never present.
--- a/layout/style/nsMediaList.cpp
+++ b/layout/style/nsMediaList.cpp
@@ -124,33 +124,33 @@ nsMediaExpression::Matches(nsPresContext
         NS_ASSERTION(actual.GetUnit() == eCSSUnit_Inch ||
                      actual.GetUnit() == eCSSUnit_Pixel ||
                      actual.GetUnit() == eCSSUnit_Centimeter,
                      "bad actual value");
         NS_ASSERTION(required.GetUnit() == eCSSUnit_Inch ||
                      required.GetUnit() == eCSSUnit_Pixel ||
                      required.GetUnit() == eCSSUnit_Centimeter,
                      "bad required value");
-        float actualDPI = actual.GetFloatValue();
+        float actualDPPX = actual.GetFloatValue();
         float overrideDPPX = aPresContext->GetOverrideDPPX();
 
         if (overrideDPPX > 0) {
-          actualDPI = overrideDPPX * 96.0f;
+          actualDPPX = overrideDPPX;
         } else if (actual.GetUnit() == eCSSUnit_Centimeter) {
-          actualDPI = actualDPI * 2.54f;
-        } else if (actual.GetUnit() == eCSSUnit_Pixel) {
-          actualDPI = actualDPI * 96.0f;
+          actualDPPX = actualDPPX * 2.54f / 96.0f;
+        } else if (actual.GetUnit() == eCSSUnit_Inch) {
+          actualDPPX = actualDPPX / 96.0f;
         }
-        float requiredDPI = required.GetFloatValue();
+        float requiredDPPX = required.GetFloatValue();
         if (required.GetUnit() == eCSSUnit_Centimeter) {
-          requiredDPI = requiredDPI * 2.54f;
-        } else if (required.GetUnit() == eCSSUnit_Pixel) {
-          requiredDPI = requiredDPI * 96.0f;
+          requiredDPPX = requiredDPPX * 2.54f / 96.0f;
+        } else if (required.GetUnit() == eCSSUnit_Inch) {
+          requiredDPPX = requiredDPPX / 96.0f;
         }
-        cmp = DoCompare(actualDPI, requiredDPI);
+        cmp = DoCompare(actualDPPX, requiredDPPX);
       }
       break;
     case nsMediaFeature::eEnumerated:
       {
         NS_ASSERTION(actual.GetUnit() == eCSSUnit_Enumerated,
                      "bad actual value");
         NS_ASSERTION(required.GetUnit() == eCSSUnit_Enumerated,
                      "bad required value");