Bug 369698: fix dynamic changes to layout.css.dpi pref. r+sr=roc.
This commit is contained in:
Родитель
6a2bc1186a
Коммит
b2cad6ca8d
|
@ -477,6 +477,13 @@ public:
|
|||
*/
|
||||
NS_IMETHOD ClearCachedSystemFonts() = 0;
|
||||
|
||||
/**
|
||||
* Check to see if the DPI has changed
|
||||
* @return whether there was actually a change in the DPI
|
||||
* (whether AppUnitsPerDevPixel() or AppUnitsPerInch() changed)
|
||||
*/
|
||||
virtual PRBool CheckDPIChange() = 0;
|
||||
|
||||
protected:
|
||||
PRInt32 mAppUnitsPerDevPixel;
|
||||
PRInt32 mAppUnitsPerInch;
|
||||
|
|
|
@ -131,36 +131,38 @@ nsThebesDeviceContext::nsThebesDeviceContext()
|
|||
|
||||
nsThebesDeviceContext::~nsThebesDeviceContext()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
prefs->UnregisterCallback("layout.css.dpi",
|
||||
prefChanged, (void *)this);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesDeviceContext::SetDPI(PRInt32 aPrefDPI)
|
||||
nsThebesDeviceContext::SetDPI()
|
||||
{
|
||||
PRInt32 dpi = 96;
|
||||
|
||||
// Set prefVal the value of the preference
|
||||
// "layout.css.dpi"
|
||||
// or -1 if we can't get it.
|
||||
// If it's negative, we pretend it's not set.
|
||||
// If it's 0, it means force use of the operating system's logical
|
||||
// resolution.
|
||||
// If it's positive, we use it as the logical resolution
|
||||
nsresult rv;
|
||||
PRInt32 prefDPI;
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv) && prefs) {
|
||||
rv = prefs->GetIntPref("layout.css.dpi", &prefDPI);
|
||||
if (NS_FAILED(rv)) {
|
||||
prefDPI = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MOZ_ENABLE_GTK2)
|
||||
float screenWidthIn = float(::gdk_screen_width_mm()) / 25.4f;
|
||||
PRInt32 OSVal = NSToCoordRound(float(::gdk_screen_width()) / screenWidthIn);
|
||||
|
||||
if (aPrefDPI > 0) {
|
||||
// If there's a valid pref value for the logical resolution,
|
||||
// use it.
|
||||
dpi = aPrefDPI;
|
||||
} else if ((aPrefDPI == 0) || (OSVal > 96)) {
|
||||
// Either if the pref is 0 (force use of OS value) or the OS
|
||||
// value is bigger than 96, use the OS value.
|
||||
if (prefDPI == 0) // Force the use of the OS dpi
|
||||
dpi = OSVal;
|
||||
} else {
|
||||
// if we couldn't get the pref or it's negative, and the OS
|
||||
// value is under 96ppi, then use 96.
|
||||
dpi = 96;
|
||||
}
|
||||
else // Otherwise, the minimum dpi is 96dpi
|
||||
dpi = PR_MAX(OSVal, 96);
|
||||
|
||||
if (mPrinter) {
|
||||
// cairo printing doesn't really have the
|
||||
|
@ -183,14 +185,16 @@ nsThebesDeviceContext::SetDPI(PRInt32 aPrefDPI)
|
|||
|
||||
#elif defined(XP_MACOSX)
|
||||
|
||||
// XXX Need to get the screen DPI instead of defaulting to 96dpi
|
||||
|
||||
if (mPrinter) {
|
||||
dpi = 72;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (aPrefDPI > 0 && !mPrinter)
|
||||
dpi = aPrefDPI;
|
||||
if (prefDPI > 0 && !mPrinter)
|
||||
dpi = prefDPI;
|
||||
|
||||
mAppUnitsPerDevPixel = AppUnitsPerCSSPixel() / PR_MAX(1, (dpi + 48) / 96);
|
||||
mAppUnitsPerInch = NSIntPixelsToAppUnits(dpi, mAppUnitsPerDevPixel);
|
||||
|
@ -203,28 +207,7 @@ nsThebesDeviceContext::Init(nsNativeWidget aWidget)
|
|||
{
|
||||
mWidget = aWidget;
|
||||
|
||||
PRInt32 prefVal = -1;
|
||||
|
||||
// Set prefVal the value of the preference
|
||||
// "layout.css.dpi"
|
||||
// or -1 if we can't get it.
|
||||
// If it's negative, we pretend it's not set.
|
||||
// If it's 0, it means force use of the operating system's logical
|
||||
// resolution.
|
||||
// If it's positive, we use it as the logical resolution
|
||||
nsresult res;
|
||||
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID, &res));
|
||||
if (NS_SUCCEEDED(res) && prefs) {
|
||||
res = prefs->GetIntPref("layout.css.dpi", &prefVal);
|
||||
if (NS_FAILED(res)) {
|
||||
prefVal = -1;
|
||||
}
|
||||
prefs->RegisterCallback("layout.css.dpi", prefChanged,
|
||||
(void *)this);
|
||||
}
|
||||
|
||||
SetDPI(prefVal);
|
||||
SetDPI();
|
||||
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
|
@ -445,8 +428,8 @@ nsThebesDeviceContext::GetRect(nsRect &aRect)
|
|||
// we have a printer device
|
||||
aRect.x = 0;
|
||||
aRect.y = 0;
|
||||
aRect.width = NSToIntRound(mWidth);
|
||||
aRect.height = NSToIntRound(mHeight);
|
||||
aRect.width = mWidth;
|
||||
aRect.height = mHeight;
|
||||
} else
|
||||
ComputeFullAreaUsingScreen ( &aRect );
|
||||
|
||||
|
@ -460,8 +443,8 @@ nsThebesDeviceContext::GetClientRect(nsRect &aRect)
|
|||
// we have a printer device
|
||||
aRect.x = 0;
|
||||
aRect.y = 0;
|
||||
aRect.width = NSToIntRound(mWidth);
|
||||
aRect.height = NSToIntRound(mHeight);
|
||||
aRect.width = mWidth;
|
||||
aRect.height = mHeight;
|
||||
}
|
||||
else
|
||||
ComputeClientRectUsingScreen(&aRect);
|
||||
|
@ -586,24 +569,6 @@ nsThebesDeviceContext::EndPage(void)
|
|||
|
||||
/** End printing methods **/
|
||||
|
||||
int
|
||||
nsThebesDeviceContext::prefChanged(const char *aPref, void *aClosure)
|
||||
{
|
||||
nsThebesDeviceContext *context = (nsThebesDeviceContext*)aClosure;
|
||||
nsresult rv;
|
||||
|
||||
if (nsCRT::strcmp(aPref, "layout.css.dpi") == 0) {
|
||||
PRInt32 dpi;
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID, &rv));
|
||||
rv = prefs->GetIntPref(aPref, &dpi);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
context->SetDPI(dpi);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsThebesDeviceContext::ComputeClientRectUsingScreen(nsRect* outRect)
|
||||
{
|
||||
|
@ -716,8 +681,8 @@ nsThebesDeviceContext::CalcPrintingSize()
|
|||
}
|
||||
|
||||
if (inPoints) {
|
||||
mWidth = float(size.width) * AppUnitsPerInch() / 72;
|
||||
mHeight = float(size.height) * AppUnitsPerInch() / 72;
|
||||
mWidth = NSToCoordRound(float(size.width) * AppUnitsPerInch() / 72);
|
||||
mHeight = NSToCoordRound(float(size.height) * AppUnitsPerInch() / 72);
|
||||
printf("%f %f\n", size.width, size.height);
|
||||
printf("%d %d\n", (PRInt32)mWidth, (PRInt32)mHeight);
|
||||
} else {
|
||||
|
@ -726,3 +691,12 @@ nsThebesDeviceContext::CalcPrintingSize()
|
|||
}
|
||||
}
|
||||
|
||||
PRBool nsThebesDeviceContext::CheckDPIChange() {
|
||||
PRInt32 oldDevPixels = mAppUnitsPerDevPixel;
|
||||
PRInt32 oldInches = mAppUnitsPerInch;
|
||||
|
||||
SetDPI();
|
||||
|
||||
return oldDevPixels != mAppUnitsPerDevPixel ||
|
||||
oldInches != mAppUnitsPerInch;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ public:
|
|||
|
||||
static void DebugShowCairoSurface (const char *aName, cairo_surface_t *aSurface);
|
||||
|
||||
static int prefChanged(const char *aPref, void *aClosure);
|
||||
virtual PRBool CheckDPIChange();
|
||||
|
||||
nsNativeWidget GetWidget() { return mWidget; }
|
||||
#ifdef XP_WIN
|
||||
|
@ -126,7 +126,7 @@ public:
|
|||
#endif
|
||||
|
||||
protected:
|
||||
nsresult SetDPI(PRInt32 aPrefDPI);
|
||||
nsresult SetDPI();
|
||||
void ComputeClientRectUsingScreen(nsRect* outRect);
|
||||
void ComputeFullAreaUsingScreen(nsRect* outRect);
|
||||
void FindScreen(nsIScreen** outScreen);
|
||||
|
@ -137,8 +137,8 @@ protected:
|
|||
private:
|
||||
nsCOMPtr<nsIScreenManager> mScreenManager;
|
||||
|
||||
PRInt32 mWidth;
|
||||
PRInt32 mHeight;
|
||||
nscoord mWidth;
|
||||
nscoord mHeight;
|
||||
PRBool mPrinter;
|
||||
|
||||
nsRefPtrHashtable<nsISupportsHashKey, gfxASurface> mWidgetSurfaceCache;
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsFrameManager.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIViewManager.h"
|
||||
|
||||
#ifdef IBMBIDI
|
||||
#include "nsBidiPresUtils.h"
|
||||
|
@ -273,6 +274,9 @@ nsPresContext::~nsPresContext()
|
|||
|
||||
delete mBidiUtils;
|
||||
#endif // IBMBIDI
|
||||
nsContentUtils::UnregisterPrefCallback("layout.css.dpi",
|
||||
nsPresContext::PrefChangedCallback,
|
||||
this);
|
||||
|
||||
NS_IF_RELEASE(mDeviceContext);
|
||||
NS_IF_RELEASE(mLookAndFeel);
|
||||
|
@ -654,6 +658,21 @@ nsPresContext::ClearStyleDataAndReflow()
|
|||
void
|
||||
nsPresContext::PreferenceChanged(const char* aPrefName)
|
||||
{
|
||||
if (!nsCRT::strcmp(aPrefName, "layout.css.dpi")) {
|
||||
nsRect bounds(mVisibleArea);
|
||||
bounds *= 1.0f / AppUnitsPerDevPixel();
|
||||
if (mDeviceContext->CheckDPIChange() && mShell) {
|
||||
mDeviceContext->FlushFontCache();
|
||||
|
||||
nsIViewManager* vm = GetViewManager();
|
||||
nscoord width = DevPixelsToAppUnits(bounds.width);
|
||||
nscoord height = DevPixelsToAppUnits(bounds.height);
|
||||
vm->SetWindowDimensions(width, height);
|
||||
|
||||
ClearStyleDataAndReflow();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// we use a zero-delay timer to coalesce multiple pref updates
|
||||
if (!mPrefChangedTimer)
|
||||
{
|
||||
|
@ -743,6 +762,9 @@ nsPresContext::Init(nsIDeviceContext* aDeviceContext)
|
|||
nsContentUtils::RegisterPrefCallback("bidi.", PrefChangedCallback,
|
||||
this);
|
||||
#endif
|
||||
nsContentUtils::RegisterPrefCallback("layout.css.dpi",
|
||||
nsPresContext::PrefChangedCallback,
|
||||
this);
|
||||
|
||||
rv = mEventManager->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
Загрузка…
Ссылка в новой задаче