void nsThebesDeviceContext::CalcPrintingSize() { if (!mPrintingSurface) return; PRBool inPoints = PR_TRUE; gfxSize size; switch (mPrintingSurface->GetType()) { case gfxASurface::SurfaceTypeImage: inPoints = PR_FALSE; size = reinterpret_cast<gfxImageSurface*>(mPrintingSurface.get())->GetSize(); break; #if defined(MOZ_ENABLE_GTK2) || defined(XP_WIN) || defined(XP_OS2) case gfxASurface::SurfaceTypePDF: inPoints = PR_TRUE; size = reinterpret_cast<gfxPDFSurface*>(mPrintingSurface.get())->GetSize(); break; #endif #ifdef MOZ_ENABLE_GTK2 case gfxASurface::SurfaceTypePS: inPoints = PR_TRUE; size = reinterpret_cast<gfxPSSurface*>(mPrintingSurface.get())->GetSize(); break; #endif #ifdef XP_MACOSX case gfxASurface::SurfaceTypeQuartz: inPoints = PR_TRUE; // this is really only true when we're printing size = reinterpret_cast<gfxQuartzSurface*>(mPrintingSurface.get())->GetSize(); break; #endif #ifdef XP_WIN case gfxASurface::SurfaceTypeWin32: case gfxASurface::SurfaceTypeWin32Printing: { inPoints = PR_FALSE; HDC dc = GetPrintHDC(); if (!dc) dc = GetDC((HWND)mWidget->GetNativeData(NS_NATIVE_WIDGET)); size.width = NSFloatPixelsToAppUnits(::GetDeviceCaps(dc, HORZRES)/mPrintingScale, AppUnitsPerDevPixel()); size.height = NSFloatPixelsToAppUnits(::GetDeviceCaps(dc, VERTRES)/mPrintingScale, AppUnitsPerDevPixel()); mDepth = (PRUint32)::GetDeviceCaps(dc, BITSPIXEL); if (dc != (HDC)GetPrintHDC()) ReleaseDC((HWND)mWidget->GetNativeData(NS_NATIVE_WIDGET), dc); break; } #endif #ifdef XP_OS2 case gfxASurface::SurfaceTypeOS2: { inPoints = PR_FALSE; // we already set the size in the surface constructor we set for // printing, so just get those values here size = reinterpret_cast<gfxOS2Surface*>(mPrintingSurface.get())->GetSize(); // as they are in pixels we need to scale them to app units size.width = NSFloatPixelsToAppUnits(size.width, AppUnitsPerDevPixel()); size.height = NSFloatPixelsToAppUnits(size.height, AppUnitsPerDevPixel()); // still need to get the depth from the device context HDC dc = GetPrintHDC(); LONG value; if (DevQueryCaps(dc, CAPS_COLOR_BITCOUNT, 1, &value)) mDepth = value; else mDepth = 8; // default to 8bpp, should be enough for printers break; } #endif default: NS_ERROR("trying to print to unknown surface type"); } if (inPoints) { mWidth = NSToCoordRound(float(size.width) * AppUnitsPerInch() / 72); mHeight = NSToCoordRound(float(size.height) * AppUnitsPerInch() / 72); } else { mWidth = NSToIntRound(size.width); mHeight = NSToIntRound(size.height); } }
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; }