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
Родитель 6a2bc1186a
Коммит b2cad6ca8d
4 изменённых файлов: 74 добавлений и 71 удалений

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

@ -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);