Bug 369698: fix dynamic changes to layout.css.dpi pref. r+sr=roc.

This commit is contained in:
sharparrow1%yahoo.com 2007-02-15 09:04:25 +00:00
Родитель dec1509dd9
Коммит 1706963a44
4 изменённых файлов: 74 добавлений и 71 удалений

Просмотреть файл

@ -477,6 +477,13 @@ public:
*/ */
NS_IMETHOD ClearCachedSystemFonts() = 0; 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: protected:
PRInt32 mAppUnitsPerDevPixel; PRInt32 mAppUnitsPerDevPixel;
PRInt32 mAppUnitsPerInch; PRInt32 mAppUnitsPerInch;

Просмотреть файл

@ -131,36 +131,38 @@ nsThebesDeviceContext::nsThebesDeviceContext()
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 nsresult
nsThebesDeviceContext::SetDPI(PRInt32 aPrefDPI) nsThebesDeviceContext::SetDPI()
{ {
PRInt32 dpi = 96; 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) #if defined(MOZ_ENABLE_GTK2)
float screenWidthIn = float(::gdk_screen_width_mm()) / 25.4f; float screenWidthIn = float(::gdk_screen_width_mm()) / 25.4f;
PRInt32 OSVal = NSToCoordRound(float(::gdk_screen_width()) / screenWidthIn); PRInt32 OSVal = NSToCoordRound(float(::gdk_screen_width()) / screenWidthIn);
if (aPrefDPI > 0) { if (prefDPI == 0) // Force the use of the OS dpi
// 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.
dpi = OSVal; dpi = OSVal;
} else { else // Otherwise, the minimum dpi is 96dpi
// if we couldn't get the pref or it's negative, and the OS dpi = PR_MAX(OSVal, 96);
// value is under 96ppi, then use 96.
dpi = 96;
}
if (mPrinter) { if (mPrinter) {
// cairo printing doesn't really have the // cairo printing doesn't really have the
@ -183,14 +185,16 @@ nsThebesDeviceContext::SetDPI(PRInt32 aPrefDPI)
#elif defined(XP_MACOSX) #elif defined(XP_MACOSX)
// XXX Need to get the screen DPI instead of defaulting to 96dpi
if (mPrinter) { if (mPrinter) {
dpi = 72; dpi = 72;
} }
#endif #endif
if (aPrefDPI > 0 && !mPrinter) if (prefDPI > 0 && !mPrinter)
dpi = aPrefDPI; dpi = prefDPI;
mAppUnitsPerDevPixel = AppUnitsPerCSSPixel() / PR_MAX(1, (dpi + 48) / 96); mAppUnitsPerDevPixel = AppUnitsPerCSSPixel() / PR_MAX(1, (dpi + 48) / 96);
mAppUnitsPerInch = NSIntPixelsToAppUnits(dpi, mAppUnitsPerDevPixel); mAppUnitsPerInch = NSIntPixelsToAppUnits(dpi, mAppUnitsPerDevPixel);
@ -203,28 +207,7 @@ nsThebesDeviceContext::Init(nsNativeWidget aWidget)
{ {
mWidget = aWidget; mWidget = aWidget;
PRInt32 prefVal = -1; SetDPI();
// 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);
#ifdef MOZ_ENABLE_GTK2 #ifdef MOZ_ENABLE_GTK2
@ -445,8 +428,8 @@ nsThebesDeviceContext::GetRect(nsRect &aRect)
// we have a printer device // we have a printer device
aRect.x = 0; aRect.x = 0;
aRect.y = 0; aRect.y = 0;
aRect.width = NSToIntRound(mWidth); aRect.width = mWidth;
aRect.height = NSToIntRound(mHeight); aRect.height = mHeight;
} else } else
ComputeFullAreaUsingScreen ( &aRect ); ComputeFullAreaUsingScreen ( &aRect );
@ -460,8 +443,8 @@ nsThebesDeviceContext::GetClientRect(nsRect &aRect)
// we have a printer device // we have a printer device
aRect.x = 0; aRect.x = 0;
aRect.y = 0; aRect.y = 0;
aRect.width = NSToIntRound(mWidth); aRect.width = mWidth;
aRect.height = NSToIntRound(mHeight); aRect.height = mHeight;
} }
else else
ComputeClientRectUsingScreen(&aRect); ComputeClientRectUsingScreen(&aRect);
@ -586,24 +569,6 @@ nsThebesDeviceContext::EndPage(void)
/** End printing methods **/ /** 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 void
nsThebesDeviceContext::ComputeClientRectUsingScreen(nsRect* outRect) nsThebesDeviceContext::ComputeClientRectUsingScreen(nsRect* outRect)
{ {
@ -716,8 +681,8 @@ nsThebesDeviceContext::CalcPrintingSize()
} }
if (inPoints) { if (inPoints) {
mWidth = float(size.width) * AppUnitsPerInch() / 72; mWidth = NSToCoordRound(float(size.width) * AppUnitsPerInch() / 72);
mHeight = float(size.height) * AppUnitsPerInch() / 72; mHeight = NSToCoordRound(float(size.height) * AppUnitsPerInch() / 72);
printf("%f %f\n", size.width, size.height); printf("%f %f\n", size.width, size.height);
printf("%d %d\n", (PRInt32)mWidth, (PRInt32)mHeight); printf("%d %d\n", (PRInt32)mWidth, (PRInt32)mHeight);
} else { } 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 void DebugShowCairoSurface (const char *aName, cairo_surface_t *aSurface);
static int prefChanged(const char *aPref, void *aClosure); virtual PRBool CheckDPIChange();
nsNativeWidget GetWidget() { return mWidget; } nsNativeWidget GetWidget() { return mWidget; }
#ifdef XP_WIN #ifdef XP_WIN
@ -126,7 +126,7 @@ public:
#endif #endif
protected: protected:
nsresult SetDPI(PRInt32 aPrefDPI); nsresult SetDPI();
void ComputeClientRectUsingScreen(nsRect* outRect); void ComputeClientRectUsingScreen(nsRect* outRect);
void ComputeFullAreaUsingScreen(nsRect* outRect); void ComputeFullAreaUsingScreen(nsRect* outRect);
void FindScreen(nsIScreen** outScreen); void FindScreen(nsIScreen** outScreen);
@ -137,8 +137,8 @@ protected:
private: private:
nsCOMPtr<nsIScreenManager> mScreenManager; nsCOMPtr<nsIScreenManager> mScreenManager;
PRInt32 mWidth; nscoord mWidth;
PRInt32 mHeight; nscoord mHeight;
PRBool mPrinter; PRBool mPrinter;
nsRefPtrHashtable<nsISupportsHashKey, gfxASurface> mWidgetSurfaceCache; nsRefPtrHashtable<nsISupportsHashKey, gfxASurface> mWidgetSurfaceCache;

Просмотреть файл

@ -76,6 +76,7 @@
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsFrameManager.h" #include "nsFrameManager.h"
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsIViewManager.h"
#ifdef IBMBIDI #ifdef IBMBIDI
#include "nsBidiPresUtils.h" #include "nsBidiPresUtils.h"
@ -273,6 +274,9 @@ nsPresContext::~nsPresContext()
delete mBidiUtils; delete mBidiUtils;
#endif // IBMBIDI #endif // IBMBIDI
nsContentUtils::UnregisterPrefCallback("layout.css.dpi",
nsPresContext::PrefChangedCallback,
this);
NS_IF_RELEASE(mDeviceContext); NS_IF_RELEASE(mDeviceContext);
NS_IF_RELEASE(mLookAndFeel); NS_IF_RELEASE(mLookAndFeel);
@ -654,6 +658,21 @@ nsPresContext::ClearStyleDataAndReflow()
void void
nsPresContext::PreferenceChanged(const char* aPrefName) 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 // we use a zero-delay timer to coalesce multiple pref updates
if (!mPrefChangedTimer) if (!mPrefChangedTimer)
{ {
@ -743,6 +762,9 @@ nsPresContext::Init(nsIDeviceContext* aDeviceContext)
nsContentUtils::RegisterPrefCallback("bidi.", PrefChangedCallback, nsContentUtils::RegisterPrefCallback("bidi.", PrefChangedCallback,
this); this);
#endif #endif
nsContentUtils::RegisterPrefCallback("layout.css.dpi",
nsPresContext::PrefChangedCallback,
this);
rv = mEventManager->Init(); rv = mEventManager->Init();
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);