double WheelEvent::DeltaZ() { if (!mAppUnitsPerDevPixel) { return mEvent->AsWheelEvent()->mDeltaZ; } return mEvent->AsWheelEvent()->mDeltaZ * mAppUnitsPerDevPixel / AppUnitsPerCSSPixel(); }
TEST_F(APZCSnappingTester, Bug1265510) { const char* layerTreeSyntax = "c(t)"; nsIntRegion layerVisibleRegion[] = { nsIntRegion(IntRect(0, 0, 100, 100)), nsIntRegion(IntRect(0, 100, 100, 100)) }; root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers); SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 100, 200)); SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 200)); SetScrollHandoff(layers[1], root); ScrollSnapInfo snap; snap.mScrollSnapTypeY = NS_STYLE_SCROLL_SNAP_TYPE_MANDATORY; snap.mScrollSnapIntervalY = Some(100 * AppUnitsPerCSSPixel()); ScrollMetadata metadata = root->GetScrollMetadata(0); metadata.SetSnapInfo(ScrollSnapInfo(snap)); root->SetScrollMetadata(metadata); UniquePtr<ScopedLayerTreeRegistration> registration = MakeUnique<ScopedLayerTreeRegistration>(manager, 0, root, mcc); manager->UpdateHitTestingTree(nullptr, root, false, 0, 0); TestAsyncPanZoomController* outer = ApzcOf(layers[0]); TestAsyncPanZoomController* inner = ApzcOf(layers[1]); // Position the mouse near the bottom of the outer frame and scroll by 60px. // (6 lines of 10px each). APZC will actually scroll to y=100 because of the // mandatory snap coordinate there. TimeStamp now = mcc->Time(); SmoothWheel(manager, ScreenIntPoint(50, 80), ScreenPoint(0, 6), now); // Advance in 5ms increments until we've scrolled by 70px. At this point, the // closest snap point is y=100, and the inner frame should be under the mouse // cursor. while (outer->GetCurrentAsyncScrollOffset(AsyncPanZoomController::AsyncMode::NORMAL).y < 70) { mcc->AdvanceByMillis(5); outer->AdvanceAnimations(mcc->Time()); } // Now do another wheel in a new transaction. This should start scrolling the // inner frame; we verify that it does by checking the inner scroll position. TimeStamp newTransactionTime = now + TimeDuration::FromMilliseconds(gfxPrefs::MouseWheelTransactionTimeoutMs() + 100); SmoothWheel(manager, ScreenIntPoint(50, 80), ScreenPoint(0, 6), newTransactionTime); inner->AdvanceAnimationsUntilEnd(); EXPECT_LT(0.0f, inner->GetCurrentAsyncScrollOffset(AsyncPanZoomController::AsyncMode::NORMAL).y); // However, the outer frame should also continue to the snap point, otherwise // it is demonstrating incorrect behaviour by violating the mandatory snapping. outer->AdvanceAnimationsUntilEnd(); EXPECT_EQ(100.0f, outer->GetCurrentAsyncScrollOffset(AsyncPanZoomController::AsyncMode::NORMAL).y); }
nsresult nsThebesDeviceContext::SetDPI() { PRInt32 dpi = -1; PRBool dotsArePixels = PR_TRUE; // The number of device pixels per CSS pixel. A value <= 0 means choose // automatically based on the DPI. A positive value is used as-is. This effectively // controls the size of a CSS "px". float prefDevPixelsPerCSSPixel = -1.0; nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); if (prefs) { nsXPIDLCString prefString; nsresult rv = prefs->GetCharPref("layout.css.devPixelsPerPx", getter_Copies(prefString)); if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) { prefDevPixelsPerCSSPixel = static_cast<float>(atof(prefString)); } } // PostScript, PDF and Mac (when printing) all use 72 dpi // Use a printing DC to determine the other dpi values if (mPrintingSurface) { switch (mPrintingSurface->GetType()) { case gfxASurface::SurfaceTypePDF: case gfxASurface::SurfaceTypePS: case gfxASurface::SurfaceTypeQuartz: dpi = 72; break; #ifdef XP_WIN case gfxASurface::SurfaceTypeWin32: case gfxASurface::SurfaceTypeWin32Printing: { PRInt32 OSVal = GetDeviceCaps(GetPrintHDC(), LOGPIXELSY); dpi = 144; mPrintingScale = float(OSVal) / dpi; break; } #endif #ifdef XP_OS2 case gfxASurface::SurfaceTypeOS2: LONG lDPI; if (DevQueryCaps(GetPrintHDC(), CAPS_VERTICAL_FONT_RES, 1, &lDPI)) dpi = lDPI; break; #endif default: NS_NOTREACHED("Unexpected printing surface type"); break; } dotsArePixels = PR_FALSE; } else { nsresult rv; // A value of -1 means use the minimum of 96 and the system DPI. // A value of 0 means use the system DPI. A positive value is used as the DPI. // This sets the physical size of a device pixel and thus controls the // interpretation of physical units such as "pt". PRInt32 prefDPI = -1; if (prefs) { rv = prefs->GetIntPref("layout.css.dpi", &prefDPI); if (NS_FAILED(rv)) { prefDPI = -1; } } dpi = gfxPlatform::GetDPI(); #ifdef MOZ_ENABLE_GTK2 if (prefDPI < 0) // Clamp the minimum dpi to 96dpi dpi = PR_MAX(dpi, 96); #endif if (prefDPI > 0 && !mPrintingSurface) dpi = prefDPI; } NS_ASSERTION(dpi != -1, "no dpi set"); if (dotsArePixels) { if (prefDevPixelsPerCSSPixel <= 0) { // Round down to multiple of 96, which is the number of dev pixels // per CSS pixel. Then, divide that into AppUnitsPerCSSPixel() // to get the number of app units per dev pixel. The PR_MAXes are // to make sure we don't end up dividing by zero. PRUint32 roundedDPIScaleFactor = dpi/96; mAppUnitsPerDevNotScaledPixel = PR_MAX(1, AppUnitsPerCSSPixel() / PR_MAX(1, roundedDPIScaleFactor)); } else { mAppUnitsPerDevNotScaledPixel = PR_MAX(1, static_cast<PRInt32>(AppUnitsPerCSSPixel() / prefDevPixelsPerCSSPixel)); } } else { /* set mAppUnitsPerDevPixel so we're using exactly 72 dpi, even * though that means we have a non-integer number of device "pixels" * per CSS pixel */ mAppUnitsPerDevNotScaledPixel = (AppUnitsPerCSSPixel() * 96) / dpi; } mAppUnitsPerInch = NSIntPixelsToAppUnits(dpi, mAppUnitsPerDevNotScaledPixel); UpdateScaledAppUnits(); return NS_OK; }
nsresult nsThebesDeviceContext::SetDPI() { float dpi = -1.0f; // PostScript, PDF and Mac (when printing) all use 72 dpi // Use a printing DC to determine the other dpi values if (mPrintingSurface) { switch (mPrintingSurface->GetType()) { case gfxASurface::SurfaceTypePDF: case gfxASurface::SurfaceTypePS: case gfxASurface::SurfaceTypeQuartz: dpi = 72.0f; break; #ifdef XP_WIN case gfxASurface::SurfaceTypeWin32: case gfxASurface::SurfaceTypeWin32Printing: { PRInt32 OSVal = GetDeviceCaps(GetPrintHDC(), LOGPIXELSY); dpi = 144.0f; mPrintingScale = float(OSVal) / dpi; break; } #endif #ifdef XP_OS2 case gfxASurface::SurfaceTypeOS2: LONG lDPI; if (DevQueryCaps(GetPrintHDC(), CAPS_VERTICAL_FONT_RES, 1, &lDPI)) dpi = lDPI; break; #endif default: NS_NOTREACHED("Unexpected printing surface type"); break; } mAppUnitsPerDevNotScaledPixel = NS_lround((AppUnitsPerCSSPixel() * 96) / dpi); } else { nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); // A value of -1 means use the maximum of 96 and the system DPI. // A value of 0 means use the system DPI. A positive value is used as the DPI. // This sets the physical size of a device pixel and thus controls the // interpretation of physical units. PRInt32 prefDPI = -1; if (prefs) { nsresult rv = prefs->GetIntPref("layout.css.dpi", &prefDPI); if (NS_FAILED(rv)) { prefDPI = -1; } } if (prefDPI > 0) { dpi = prefDPI; } else if (mWidget) { dpi = mWidget->GetDPI(); if (prefDPI < 0) { dpi = PR_MAX(96.0f, dpi); } } else { dpi = 96.0f; } // The number of device pixels per CSS pixel. A value <= 0 means choose // automatically based on the DPI. A positive value is used as-is. This effectively // controls the size of a CSS "px". float devPixelsPerCSSPixel = -1.0; if (prefs) { nsXPIDLCString prefString; nsresult rv = prefs->GetCharPref("layout.css.devPixelsPerPx", getter_Copies(prefString)); if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) { devPixelsPerCSSPixel = static_cast<float>(atof(prefString)); } } if (devPixelsPerCSSPixel <= 0) { if (mWidget) { devPixelsPerCSSPixel = mWidget->GetDefaultScale(); } else { devPixelsPerCSSPixel = 1.0; } } mAppUnitsPerDevNotScaledPixel = PR_MAX(1, NS_lround(AppUnitsPerCSSPixel() / devPixelsPerCSSPixel)); } NS_ASSERTION(dpi != -1.0, "no dpi set"); mAppUnitsPerPhysicalInch = NS_lround(dpi * mAppUnitsPerDevNotScaledPixel); UpdateScaledAppUnits(); return NS_OK; }