LCOV - app.info - gfx/src/nsDeviceContext.cpp

LCOV - code coverage report
| Current view: | directory - gfx/src - nsDeviceContext.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 293 | 0 | 0.0 %
| Date: | 2012-07-07 | Functions: | 38 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
           2                 : /* ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is thebes gfx
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is
          18                 :  * mozilla.org.
          19                 :  * Portions created by the Initial Developer are Copyright (C) 2005
          20                 :  * the Initial Developer. All Rights Reserved.
          21                 :  *
          22                 :  * Contributor(s):
          23                 :  *   Vladimir Vukicevic <vladimir@pobox.com>
          24                 :  *   Stuart Parmenter <pavlov@pavlov.net>
          25                 :  *
          26                 :  * Alternatively, the contents of this file may be used under the terms of
          27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          30                 :  * of those above. If you wish to allow use of your version of this file only
          31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          32                 :  * use your version of this file under the terms of the MPL, indicate your
          33                 :  * decision by deleting the provisions above and replace them with the notice
          34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          35                 :  * the provisions above, a recipient may use your version of this file under
          36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          37                 :  *
          38                 :  * ***** END LICENSE BLOCK ***** */
          39                 :
          40                 : #include "nsDeviceContext.h"
          41                 : #include "nsCRT.h"
          42                 : #include "nsFontMetrics.h"
          43                 : #include "nsRenderingContext.h"
          44                 : #include "nsIView.h"
          45                 : #include "nsIWidget.h"
          46                 :
          47                 : #include "mozilla/Attributes.h"
          48                 : #include "mozilla/Services.h"
          49                 : #include "mozilla/Preferences.h"
          50                 : #include "nsIServiceManager.h"
          51                 : #include "nsILanguageAtomService.h"
          52                 : #include "nsIObserver.h"
          53                 : #include "nsIObserverService.h"
          54                 :
          55                 : #include "gfxImageSurface.h"
          56                 :
          57                 : #if !XP_MACOSX
          58                 : #include "gfxPDFSurface.h"
          59                 : #endif
          60                 :
          61                 : #ifdef MOZ_ENABLE_GTK2
          62                 : #include "gfxPSSurface.h"
          63                 : #elif XP_WIN
          64                 : #include "gfxWindowsSurface.h"
          65                 : #elif defined(XP_OS2)
          66                 : #include "gfxOS2Surface.h"
          67                 : #elif XP_MACOSX
          68                 : #include "gfxQuartzSurface.h"
          69                 : #endif
          70                 :
          71                 : using namespace mozilla;
          72                 : using mozilla::services::GetObserverService;
          73                 :
          74                 : class nsFontCache MOZ_FINAL : public nsIObserver
          75                 : {
          76                 : public:
          77               0 :     nsFontCache()   { MOZ_COUNT_CTOR(nsFontCache); }
          78               0 :     ~nsFontCache()  { MOZ_COUNT_DTOR(nsFontCache); }
          79                 :
          80                 :     NS_DECL_ISUPPORTS
          81                 :     NS_DECL_NSIOBSERVER
          82                 :
          83                 :     void Init(nsDeviceContext* aContext);
          84                 :     void Destroy();
          85                 :
          86                 :     nsresult GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
          87                 :                            gfxUserFontSet* aUserFontSet,
          88                 :                            nsFontMetrics*& aMetrics);
          89                 :
          90                 :     void FontMetricsDeleted(const nsFontMetrics* aFontMetrics);
          91                 :     void Compact();
          92                 :     void Flush();
          93                 :
          94                 : protected:
          95                 :     nsDeviceContext*          mContext; // owner
          96                 :     nsCOMPtr<nsIAtom>         mLocaleLanguage;
          97                 :     nsTArray<nsFontMetrics*>  mFontMetrics;
          98                 : };
          99                 :
         100               0 : NS_IMPL_ISUPPORTS1(nsFontCache, nsIObserver)
         101                 :
         102                 : // The Init and Destroy methods are necessary because it's not
         103                 : // safe to call AddObserver from a constructor or RemoveObserver
         104                 : // from a destructor.  That should be fixed.
         105                 : void
         106               0 : nsFontCache::Init(nsDeviceContext* aContext)
         107                 : {
         108               0 :     mContext = aContext;
         109                 :     // register as a memory-pressure observer to free font resources
         110                 :     // in low-memory situations.
         111               0 :     nsCOMPtr<nsIObserverService> obs = GetObserverService();
         112               0 :     if (obs)
         113               0 :         obs->AddObserver(this, "memory-pressure", false);
         114                 :
         115               0 :     nsCOMPtr<nsILanguageAtomService> langService;
         116               0 :     langService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID);
         117               0 :     if (langService) {
         118               0 :         mLocaleLanguage = langService->GetLocaleLanguage();
         119                 :     }
         120               0 :     if (!mLocaleLanguage) {
         121               0 :         mLocaleLanguage = do_GetAtom("x-western");
         122                 :     }
         123               0 : }
         124                 :
         125                 : void
         126               0 : nsFontCache::Destroy()
         127                 : {
         128               0 :     nsCOMPtr<nsIObserverService> obs = GetObserverService();
         129               0 :     if (obs)
         130               0 :         obs->RemoveObserver(this, "memory-pressure");
         131               0 :     Flush();
         132               0 : }
         133                 :
         134                 : NS_IMETHODIMP
         135               0 : nsFontCache::Observe(nsISupports*, const char* aTopic, const PRUnichar*)
         136                 : {
         137               0 :     if (!nsCRT::strcmp(aTopic, "memory-pressure"))
         138               0 :         Compact();
         139               0 :     return NS_OK;
         140                 : }
         141                 :
         142                 : nsresult
         143               0 : nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
         144                 :                            gfxUserFontSet* aUserFontSet,
         145                 :                            nsFontMetrics*& aMetrics)
         146                 : {
         147               0 :     if (!aLanguage)
         148               0 :         aLanguage = mLocaleLanguage;
         149                 :
         150                 :     // First check our cache
         151                 :     // start from the end, which is where we put the most-recent-used element
         152                 :
         153                 :     nsFontMetrics* fm;
         154               0 :     PRInt32 n = mFontMetrics.Length() - 1;
         155               0 :     for (PRInt32 i = n; i >= 0; --i) {
         156               0 :         fm = mFontMetrics[i];
         157               0 :         if (fm->Font().Equals(aFont) && fm->GetUserFontSet() == aUserFontSet &&
         158               0 :             fm->Language() == aLanguage) {
         159               0 :             if (i != n) {
         160                 :                 // promote it to the end of the cache
         161               0 :                 mFontMetrics.RemoveElementAt(i);
         162               0 :                 mFontMetrics.AppendElement(fm);
         163                 :             }
         164               0 :             fm->GetThebesFontGroup()->UpdateFontList();
         165               0 :             NS_ADDREF(aMetrics = fm);
         166               0 :             return NS_OK;
         167                 :         }
         168                 :     }
         169                 :
         170                 :     // It's not in the cache. Get font metrics and then cache them.
         171                 :
         172               0 :     fm = new nsFontMetrics();
         173               0 :     NS_ADDREF(fm);
         174               0 :     nsresult rv = fm->Init(aFont, aLanguage, mContext, aUserFontSet);
         175               0 :     if (NS_SUCCEEDED(rv)) {
         176                 :         // the mFontMetrics list has the "head" at the end, because append
         177                 :         // is cheaper than insert
         178               0 :         mFontMetrics.AppendElement(fm);
         179               0 :         aMetrics = fm;
         180               0 :         NS_ADDREF(aMetrics);
         181               0 :         return NS_OK;
         182                 :     }
         183               0 :     fm->Destroy();
         184               0 :     NS_RELEASE(fm);
         185                 :
         186                 :     // One reason why Init() fails is because the system is running out of
         187                 :     // resources. e.g., on Win95/98 only a very limited number of GDI
         188                 :     // objects are available. Compact the cache and try again.
         189                 :
         190               0 :     Compact();
         191               0 :     fm = new nsFontMetrics();
         192               0 :     NS_ADDREF(fm);
         193               0 :     rv = fm->Init(aFont, aLanguage, mContext, aUserFontSet);
         194               0 :     if (NS_SUCCEEDED(rv)) {
         195               0 :         mFontMetrics.AppendElement(fm);
         196               0 :         aMetrics = fm;
         197               0 :         return NS_OK;
         198                 :     }
         199               0 :     fm->Destroy();
         200               0 :     NS_RELEASE(fm);
         201                 :
         202                 :     // could not setup a new one, send an old one (XXX search a "best
         203                 :     // match"?)
         204                 :
         205               0 :     n = mFontMetrics.Length() - 1; // could have changed in Compact()
         206               0 :     if (n >= 0) {
         207               0 :         aMetrics = mFontMetrics[n];
         208               0 :         NS_ADDREF(aMetrics);
         209               0 :         return NS_OK;
         210                 :     }
         211                 :
         212               0 :     NS_POSTCONDITION(NS_SUCCEEDED(rv),
         213                 :                      "font metrics should not be null - bug 136248");
         214               0 :     return rv;
         215                 : }
         216                 :
         217                 : void
         218               0 : nsFontCache::FontMetricsDeleted(const nsFontMetrics* aFontMetrics)
         219                 : {
         220               0 :     mFontMetrics.RemoveElement(aFontMetrics);
         221               0 : }
         222                 :
         223                 : void
         224               0 : nsFontCache::Compact()
         225                 : {
         226                 :     // Need to loop backward because the running element can be removed on
         227                 :     // the way
         228               0 :     for (PRInt32 i = mFontMetrics.Length()-1; i >= 0; --i) {
         229               0 :         nsFontMetrics* fm = mFontMetrics[i];
         230               0 :         nsFontMetrics* oldfm = fm;
         231                 :         // Destroy() isn't here because we want our device context to be
         232                 :         // notified
         233               0 :         NS_RELEASE(fm); // this will reset fm to nsnull
         234                 :         // if the font is really gone, it would have called back in
         235                 :         // FontMetricsDeleted() and would have removed itself
         236               0 :         if (mFontMetrics.IndexOf(oldfm) != mFontMetrics.NoIndex) {
         237                 :             // nope, the font is still there, so let's hold onto it too
         238               0 :             NS_ADDREF(oldfm);
         239                 :         }
         240                 :     }
         241               0 : }
         242                 :
         243                 : void
         244               0 : nsFontCache::Flush()
         245                 : {
         246               0 :     for (PRInt32 i = mFontMetrics.Length()-1; i >= 0; --i) {
         247               0 :         nsFontMetrics* fm = mFontMetrics[i];
         248                 :         // Destroy() will unhook our device context from the fm so that we
         249                 :         // won't waste time in triggering the notification of
         250                 :         // FontMetricsDeleted() in the subsequent release
         251               0 :         fm->Destroy();
         252               0 :         NS_RELEASE(fm);
         253                 :     }
         254               0 :     mFontMetrics.Clear();
         255               0 : }
         256                 :
         257               0 : nsDeviceContext::nsDeviceContext()
         258                 :     : mWidth(0), mHeight(0), mDepth(0),
         259                 :       mAppUnitsPerDevPixel(-1), mAppUnitsPerDevNotScaledPixel(-1),
         260                 :       mAppUnitsPerPhysicalInch(-1),
         261                 :       mPixelScale(1.0f), mPrintingScale(1.0f),
         262               0 :       mFontCache(nsnull)
         263                 : {
         264               0 : }
         265                 :
         266                 : // Note: we use a bare pointer for mFontCache so that nsFontCache
         267                 : // can be an incomplete type in nsDeviceContext.h.
         268                 : // Therefore we have to do all the refcounting by hand.
         269               0 : nsDeviceContext::~nsDeviceContext()
         270                 : {
         271               0 :     if (mFontCache) {
         272               0 :         mFontCache->Destroy();
         273               0 :         NS_RELEASE(mFontCache);
         274                 :     }
         275               0 : }
         276                 :
         277                 : nsresult
         278               0 : nsDeviceContext::GetMetricsFor(const nsFont& aFont,
         279                 :                                nsIAtom* aLanguage,
         280                 :                                gfxUserFontSet* aUserFontSet,
         281                 :                                nsFontMetrics*& aMetrics)
         282                 : {
         283               0 :     if (!mFontCache) {
         284               0 :         mFontCache = new nsFontCache();
         285               0 :         NS_ADDREF(mFontCache);
         286               0 :         mFontCache->Init(this);
         287                 :     }
         288                 :
         289               0 :     return mFontCache->GetMetricsFor(aFont, aLanguage, aUserFontSet, aMetrics);
         290                 : }
         291                 :
         292                 : nsresult
         293               0 : nsDeviceContext::FlushFontCache(void)
         294                 : {
         295               0 :     if (mFontCache)
         296               0 :         mFontCache->Flush();
         297               0 :     return NS_OK;
         298                 : }
         299                 :
         300                 : nsresult
         301               0 : nsDeviceContext::FontMetricsDeleted(const nsFontMetrics* aFontMetrics)
         302                 : {
         303               0 :     if (mFontCache) {
         304               0 :         mFontCache->FontMetricsDeleted(aFontMetrics);
         305                 :     }
         306               0 :     return NS_OK;
         307                 : }
         308                 :
         309                 : bool
         310               0 : nsDeviceContext::IsPrinterSurface()
         311                 : {
         312               0 :     return(mPrintingSurface != NULL);
         313                 : }
         314                 :
         315                 : void
         316               0 : nsDeviceContext::SetDPI()
         317                 : {
         318               0 :     float dpi = -1.0f;
         319                 :
         320                 :     // PostScript, PDF and Mac (when printing) all use 72 dpi
         321                 :     // Use a printing DC to determine the other dpi values
         322               0 :     if (mPrintingSurface) {
         323               0 :         switch (mPrintingSurface->GetType()) {
         324                 :         case gfxASurface::SurfaceTypePDF:
         325                 :         case gfxASurface::SurfaceTypePS:
         326                 :         case gfxASurface::SurfaceTypeQuartz:
         327               0 :             dpi = 72.0f;
         328               0 :             break;
         329                 : #ifdef XP_WIN
         330                 :         case gfxASurface::SurfaceTypeWin32:
         331                 :         case gfxASurface::SurfaceTypeWin32Printing: {
         332                 :             HDC dc = reinterpret_cast<gfxWindowsSurface*>(mPrintingSurface.get())->GetDC();
         333                 :             PRInt32 OSVal = GetDeviceCaps(dc, LOGPIXELSY);
         334                 :             dpi = 144.0f;
         335                 :             mPrintingScale = float(OSVal) / dpi;
         336                 :             break;
         337                 :         }
         338                 : #endif
         339                 : #ifdef XP_OS2
         340                 :         case gfxASurface::SurfaceTypeOS2: {
         341                 :             LONG lDPI;
         342                 :             HDC dc = GpiQueryDevice(reinterpret_cast<gfxOS2Surface*>(mPrintingSurface.get())->GetPS());
         343                 :             if (DevQueryCaps(dc, CAPS_VERTICAL_FONT_RES, 1, &lDPI))
         344                 :                 dpi = lDPI;
         345                 :             break;
         346                 :         }
         347                 : #endif
         348                 :         default:
         349               0 :             NS_NOTREACHED("Unexpected printing surface type");
         350               0 :             break;
         351                 :         }
         352                 :
         353                 :         mAppUnitsPerDevNotScaledPixel =
         354               0 :             NS_lround((AppUnitsPerCSSPixel() * 96) / dpi);
         355                 :     } else {
         356                 :         // A value of -1 means use the maximum of 96 and the system DPI.
         357                 :         // A value of 0 means use the system DPI. A positive value is used as the DPI.
         358                 :         // This sets the physical size of a device pixel and thus controls the
         359                 :         // interpretation of physical units.
         360               0 :         PRInt32 prefDPI = Preferences::GetInt("layout.css.dpi", -1);
         361                 :
         362               0 :         if (prefDPI > 0) {
         363               0 :             dpi = prefDPI;
         364               0 :         } else if (mWidget) {
         365               0 :             dpi = mWidget->GetDPI();
         366                 :
         367               0 :             if (prefDPI < 0) {
         368               0 :                 dpi = NS_MAX(96.0f, dpi);
         369                 :             }
         370                 :         } else {
         371               0 :             dpi = 96.0f;
         372                 :         }
         373                 :
         374                 :         // The number of device pixels per CSS pixel. A value <= 0 means choose
         375                 :         // automatically based on the DPI. A positive value is used as-is. This effectively
         376                 :         // controls the size of a CSS "px".
         377               0 :         float devPixelsPerCSSPixel = -1.0;
         378                 :
         379               0 :         nsAdoptingCString prefString = Preferences::GetCString("layout.css.devPixelsPerPx");
         380               0 :         if (!prefString.IsEmpty()) {
         381               0 :             devPixelsPerCSSPixel = static_cast<float>(atof(prefString));
         382                 :         }
         383                 :
         384               0 :         if (devPixelsPerCSSPixel <= 0) {
         385               0 :             if (mWidget) {
         386               0 :                 devPixelsPerCSSPixel = mWidget->GetDefaultScale();
         387                 :             } else {
         388               0 :                 devPixelsPerCSSPixel = 1.0;
         389                 :             }
         390                 :         }
         391                 :
         392                 :         mAppUnitsPerDevNotScaledPixel =
         393               0 :             NS_MAX(1, NS_lround(AppUnitsPerCSSPixel() / devPixelsPerCSSPixel));
         394                 :     }
         395                 :
         396               0 :     NS_ASSERTION(dpi != -1.0, "no dpi set");
         397                 :
         398               0 :     mAppUnitsPerPhysicalInch = NS_lround(dpi * mAppUnitsPerDevNotScaledPixel);
         399               0 :     UpdateScaledAppUnits();
         400               0 : }
         401                 :
         402                 : nsresult
         403               0 : nsDeviceContext::Init(nsIWidget *aWidget)
         404                 : {
         405               0 :     if (mScreenManager && mWidget == aWidget)
         406               0 :         return NS_OK;
         407                 :
         408               0 :     mWidget = aWidget;
         409               0 :     SetDPI();
         410                 :
         411               0 :     if (mScreenManager)
         412               0 :         return NS_OK;
         413                 :
         414               0 :     mScreenManager = do_GetService("@mozilla.org/gfx/screenmanager;1");
         415                 :
         416               0 :     return NS_OK;
         417                 : }
         418                 :
         419                 : nsresult
         420               0 : nsDeviceContext::CreateRenderingContext(nsRenderingContext *&aContext)
         421                 : {
         422               0 :     NS_ABORT_IF_FALSE(mPrintingSurface, "only call for printing dcs");
         423                 :
         424               0 :     nsRefPtr<nsRenderingContext> pContext = new nsRenderingContext();
         425                 :
         426               0 :     pContext->Init(this, mPrintingSurface);
         427               0 :     pContext->Scale(mPrintingScale, mPrintingScale);
         428               0 :     aContext = pContext;
         429               0 :     NS_ADDREF(aContext);
         430                 :
         431               0 :     return NS_OK;
         432                 : }
         433                 :
         434                 : nsresult
         435               0 : nsDeviceContext::GetDepth(PRUint32& aDepth)
         436                 : {
         437               0 :     if (mDepth == 0) {
         438               0 :         nsCOMPtr<nsIScreen> primaryScreen;
         439               0 :         mScreenManager->GetPrimaryScreen(getter_AddRefs(primaryScreen));
         440               0 :         primaryScreen->GetColorDepth(reinterpret_cast<PRInt32 *>(&mDepth));
         441                 :     }
         442                 :
         443               0 :     aDepth = mDepth;
         444               0 :     return NS_OK;
         445                 : }
         446                 :
         447                 : nsresult
         448               0 : nsDeviceContext::GetDeviceSurfaceDimensions(nscoord &aWidth, nscoord &aHeight)
         449                 : {
         450               0 :     if (mPrintingSurface) {
         451                 :         // we have a printer device
         452               0 :         aWidth = mWidth;
         453               0 :         aHeight = mHeight;
         454                 :     } else {
         455               0 :         nsRect area;
         456               0 :         ComputeFullAreaUsingScreen(&area);
         457               0 :         aWidth = area.width;
         458               0 :         aHeight = area.height;
         459                 :     }
         460                 :
         461               0 :     return NS_OK;
         462                 : }
         463                 :
         464                 : nsresult
         465               0 : nsDeviceContext::GetRect(nsRect &aRect)
         466                 : {
         467               0 :     if (mPrintingSurface) {
         468                 :         // we have a printer device
         469               0 :         aRect.x = 0;
         470               0 :         aRect.y = 0;
         471               0 :         aRect.width = mWidth;
         472               0 :         aRect.height = mHeight;
         473                 :     } else
         474               0 :         ComputeFullAreaUsingScreen ( &aRect );
         475                 :
         476               0 :     return NS_OK;
         477                 : }
         478                 :
         479                 : nsresult
         480               0 : nsDeviceContext::GetClientRect(nsRect &aRect)
         481                 : {
         482               0 :     if (mPrintingSurface) {
         483                 :         // we have a printer device
         484               0 :         aRect.x = 0;
         485               0 :         aRect.y = 0;
         486               0 :         aRect.width = mWidth;
         487               0 :         aRect.height = mHeight;
         488                 :     }
         489                 :     else
         490               0 :         ComputeClientRectUsingScreen(&aRect);
         491                 :
         492               0 :     return NS_OK;
         493                 : }
         494                 :
         495                 : nsresult
         496               0 : nsDeviceContext::InitForPrinting(nsIDeviceContextSpec *aDevice)
         497                 : {
         498               0 :     NS_ENSURE_ARG_POINTER(aDevice);
         499                 :
         500               0 :     mDeviceContextSpec = aDevice;
         501                 :
         502               0 :     nsresult rv = aDevice->GetSurfaceForPrinter(getter_AddRefs(mPrintingSurface));
         503               0 :     if (NS_FAILED(rv))
         504               0 :         return NS_ERROR_FAILURE;
         505                 :
         506               0 :     Init(nsnull);
         507                 :
         508               0 :     CalcPrintingSize();
         509                 :
         510               0 :     return NS_OK;
         511                 : }
         512                 :
         513                 : nsresult
         514               0 : nsDeviceContext::BeginDocument(PRUnichar*  aTitle,
         515                 :                                PRUnichar*  aPrintToFileName,
         516                 :                                PRInt32     aStartPage,
         517                 :                                PRInt32     aEndPage)
         518                 : {
         519                 :     static const PRUnichar kEmpty[] = { '\0' };
         520                 :     nsresult rv;
         521                 :
         522               0 :     rv = mPrintingSurface->BeginPrinting(nsDependentString(aTitle ? aTitle : kEmpty),
         523               0 :                                          nsDependentString(aPrintToFileName ? aPrintToFileName : kEmpty));
         524                 :
         525               0 :     if (NS_SUCCEEDED(rv) && mDeviceContextSpec)
         526               0 :         rv = mDeviceContextSpec->BeginDocument(aTitle, aPrintToFileName, aStartPage, aEndPage);
         527                 :
         528               0 :     return rv;
         529                 : }
         530                 :
         531                 :
         532                 : nsresult
         533               0 : nsDeviceContext::EndDocument(void)
         534                 : {
         535               0 :     nsresult rv = NS_OK;
         536                 :
         537               0 :     if (mPrintingSurface) {
         538               0 :         rv = mPrintingSurface->EndPrinting();
         539               0 :         if (NS_SUCCEEDED(rv))
         540               0 :             mPrintingSurface->Finish();
         541                 :     }
         542                 :
         543               0 :     if (mDeviceContextSpec)
         544               0 :         mDeviceContextSpec->EndDocument();
         545                 :
         546               0 :     return rv;
         547                 : }
         548                 :
         549                 :
         550                 : nsresult
         551               0 : nsDeviceContext::AbortDocument(void)
         552                 : {
         553               0 :     nsresult rv = mPrintingSurface->AbortPrinting();
         554                 :
         555               0 :     if (mDeviceContextSpec)
         556               0 :         mDeviceContextSpec->EndDocument();
         557                 :
         558               0 :     return rv;
         559                 : }
         560                 :
         561                 :
         562                 : nsresult
         563               0 : nsDeviceContext::BeginPage(void)
         564                 : {
         565               0 :     nsresult rv = NS_OK;
         566                 :
         567               0 :     if (mDeviceContextSpec)
         568               0 :         rv = mDeviceContextSpec->BeginPage();
         569                 :
         570               0 :     if (NS_FAILED(rv)) return rv;
         571                 :
         572                 : #ifdef XP_MACOSX
         573                 :     // We need to get a new surface for each page on the Mac, as the
         574                 :     // CGContextRefs are only good for one page.
         575                 :     // And we don't null it out in EndPage because mPrintingSurface needs
         576                 :     // to be available also in-between EndPage/BeginPage (bug 665218).
         577                 :     mDeviceContextSpec->GetSurfaceForPrinter(getter_AddRefs(mPrintingSurface));
         578                 : #endif
         579                 :
         580               0 :     rv = mPrintingSurface->BeginPage();
         581                 :
         582               0 :     return rv;
         583                 : }
         584                 :
         585                 : nsresult
         586               0 : nsDeviceContext::EndPage(void)
         587                 : {
         588               0 :     nsresult rv = mPrintingSurface->EndPage();
         589                 :
         590               0 :     if (mDeviceContextSpec)
         591               0 :         mDeviceContextSpec->EndPage();
         592                 :
         593               0 :     return rv;
         594                 : }
         595                 :
         596                 : void
         597               0 : nsDeviceContext::ComputeClientRectUsingScreen(nsRect* outRect)
         598                 : {
         599                 :     // we always need to recompute the clientRect
         600                 :     // because the window may have moved onto a different screen. In the single
         601                 :     // monitor case, we only need to do the computation if we haven't done it
         602                 :     // once already, and remember that we have because we're assured it won't change.
         603               0 :     nsCOMPtr<nsIScreen> screen;
         604               0 :     FindScreen (getter_AddRefs(screen));
         605               0 :     if (screen) {
         606                 :         PRInt32 x, y, width, height;
         607               0 :         screen->GetAvailRect(&x, &y, &width, &height);
         608                 :
         609                 :         // convert to device units
         610               0 :         outRect->y = NSIntPixelsToAppUnits(y, AppUnitsPerDevPixel());
         611               0 :         outRect->x = NSIntPixelsToAppUnits(x, AppUnitsPerDevPixel());
         612               0 :         outRect->width = NSIntPixelsToAppUnits(width, AppUnitsPerDevPixel());
         613               0 :         outRect->height = NSIntPixelsToAppUnits(height, AppUnitsPerDevPixel());
         614                 :     }
         615               0 : }
         616                 :
         617                 : void
         618               0 : nsDeviceContext::ComputeFullAreaUsingScreen(nsRect* outRect)
         619                 : {
         620                 :     // if we have more than one screen, we always need to recompute the clientRect
         621                 :     // because the window may have moved onto a different screen. In the single
         622                 :     // monitor case, we only need to do the computation if we haven't done it
         623                 :     // once already, and remember that we have because we're assured it won't change.
         624               0 :     nsCOMPtr<nsIScreen> screen;
         625               0 :     FindScreen ( getter_AddRefs(screen) );
         626               0 :     if ( screen ) {
         627                 :         PRInt32 x, y, width, height;
         628               0 :         screen->GetRect ( &x, &y, &width, &height );
         629                 :
         630                 :         // convert to device units
         631               0 :         outRect->y = NSIntPixelsToAppUnits(y, AppUnitsPerDevPixel());
         632               0 :         outRect->x = NSIntPixelsToAppUnits(x, AppUnitsPerDevPixel());
         633               0 :         outRect->width = NSIntPixelsToAppUnits(width, AppUnitsPerDevPixel());
         634               0 :         outRect->height = NSIntPixelsToAppUnits(height, AppUnitsPerDevPixel());
         635                 :
         636               0 :         mWidth = outRect->width;
         637               0 :         mHeight = outRect->height;
         638                 :     }
         639               0 : }
         640                 :
         641                 : //
         642                 : // FindScreen
         643                 : //
         644                 : // Determines which screen intersects the largest area of the given surface.
         645                 : //
         646                 : void
         647               0 : nsDeviceContext::FindScreen(nsIScreen** outScreen)
         648                 : {
         649               0 :     if (mWidget && mWidget->GetNativeData(NS_NATIVE_WINDOW))
         650               0 :         mScreenManager->ScreenForNativeWidget(mWidget->GetNativeData(NS_NATIVE_WINDOW),
         651               0 :                                               outScreen);
         652                 :     else
         653               0 :         mScreenManager->GetPrimaryScreen(outScreen);
         654               0 : }
         655                 :
         656                 : void
         657               0 : nsDeviceContext::CalcPrintingSize()
         658                 : {
         659               0 :     if (!mPrintingSurface)
         660               0 :         return;
         661                 :
         662               0 :     bool inPoints = true;
         663                 :
         664               0 :     gfxSize size(0, 0);
         665               0 :     switch (mPrintingSurface->GetType()) {
         666                 :     case gfxASurface::SurfaceTypeImage:
         667               0 :         inPoints = false;
         668               0 :         size = reinterpret_cast<gfxImageSurface*>(mPrintingSurface.get())->GetSize();
         669               0 :         break;
         670                 :
         671                 : #if defined(MOZ_PDF_PRINTING)
         672                 :     case gfxASurface::SurfaceTypePDF:
         673               0 :         inPoints = true;
         674               0 :         size = reinterpret_cast<gfxPDFSurface*>(mPrintingSurface.get())->GetSize();
         675               0 :         break;
         676                 : #endif
         677                 :
         678                 : #ifdef MOZ_ENABLE_GTK2
         679                 :     case gfxASurface::SurfaceTypePS:
         680               0 :         inPoints = true;
         681               0 :         size = reinterpret_cast<gfxPSSurface*>(mPrintingSurface.get())->GetSize();
         682               0 :         break;
         683                 : #endif
         684                 :
         685                 : #ifdef XP_MACOSX
         686                 :     case gfxASurface::SurfaceTypeQuartz:
         687                 :         inPoints = true; // this is really only true when we're printing
         688                 :         size = reinterpret_cast<gfxQuartzSurface*>(mPrintingSurface.get())->GetSize();
         689                 :         break;
         690                 : #endif
         691                 :
         692                 : #ifdef XP_WIN
         693                 :     case gfxASurface::SurfaceTypeWin32:
         694                 :     case gfxASurface::SurfaceTypeWin32Printing:
         695                 :         {
         696                 :             inPoints = false;
         697                 :             HDC dc = reinterpret_cast<gfxWindowsSurface*>(mPrintingSurface.get())->GetDC();
         698                 :             if (!dc)
         699                 :                 dc = GetDC((HWND)mWidget->GetNativeData(NS_NATIVE_WIDGET));
         700                 :             size.width = NSFloatPixelsToAppUnits(::GetDeviceCaps(dc, HORZRES)/mPrintingScale, AppUnitsPerDevPixel());
         701                 :             size.height = NSFloatPixelsToAppUnits(::GetDeviceCaps(dc, VERTRES)/mPrintingScale, AppUnitsPerDevPixel());
         702                 :             mDepth = (PRUint32)::GetDeviceCaps(dc, BITSPIXEL);
         703                 :             if (dc != reinterpret_cast<gfxWindowsSurface*>(mPrintingSurface.get())->GetDC())
         704                 :                 ReleaseDC((HWND)mWidget->GetNativeData(NS_NATIVE_WIDGET), dc);
         705                 :             break;
         706                 :         }
         707                 : #endif
         708                 :
         709                 : #ifdef XP_OS2
         710                 :     case gfxASurface::SurfaceTypeOS2:
         711                 :         {
         712                 :             inPoints = false;
         713                 :             // we already set the size in the surface constructor we set for
         714                 :             // printing, so just get those values here
         715                 :             size = reinterpret_cast<gfxOS2Surface*>(mPrintingSurface.get())->GetSize();
         716                 :             // as they are in pixels we need to scale them to app units
         717                 :             size.width = NSFloatPixelsToAppUnits(size.width, AppUnitsPerDevPixel());
         718                 :             size.height = NSFloatPixelsToAppUnits(size.height, AppUnitsPerDevPixel());
         719                 :             // still need to get the depth from the device context
         720                 :             HDC dc = GpiQueryDevice(reinterpret_cast<gfxOS2Surface*>(mPrintingSurface.get())->GetPS());
         721                 :             LONG value;
         722                 :             if (DevQueryCaps(dc, CAPS_COLOR_BITCOUNT, 1, &value))
         723                 :                 mDepth = value;
         724                 :             else
         725                 :                 mDepth = 8; // default to 8bpp, should be enough for printers
         726                 :             break;
         727                 :         }
         728                 : #endif
         729                 :     default:
         730               0 :         NS_ERROR("trying to print to unknown surface type");
         731                 :     }
         732                 :
         733               0 :     if (inPoints) {
         734                 :         // For printing, CSS inches and physical inches are identical
         735                 :         // so it doesn't matter which we use here
         736               0 :         mWidth = NSToCoordRound(float(size.width) * AppUnitsPerPhysicalInch() / 72);
         737               0 :         mHeight = NSToCoordRound(float(size.height) * AppUnitsPerPhysicalInch() / 72);
         738                 :     } else {
         739               0 :         mWidth = NSToIntRound(size.width);
         740               0 :         mHeight = NSToIntRound(size.height);
         741                 :     }
         742                 : }
         743                 :
         744               0 : bool nsDeviceContext::CheckDPIChange() {
         745               0 :     PRInt32 oldDevPixels = mAppUnitsPerDevNotScaledPixel;
         746               0 :     PRInt32 oldInches = mAppUnitsPerPhysicalInch;
         747                 :
         748               0 :     SetDPI();
         749                 :
         750                 :     return oldDevPixels != mAppUnitsPerDevNotScaledPixel ||
         751               0 :         oldInches != mAppUnitsPerPhysicalInch;
         752                 : }
         753                 :
         754                 : bool
         755               0 : nsDeviceContext::SetPixelScale(float aScale)
         756                 : {
         757               0 :     if (aScale <= 0) {
         758               0 :         NS_NOTREACHED("Invalid pixel scale value");
         759               0 :         return false;
         760                 :     }
         761               0 :     PRUint32 oldAppUnitsPerDevPixel = mAppUnitsPerDevPixel;
         762               0 :     mPixelScale = aScale;
         763               0 :     UpdateScaledAppUnits();
         764               0 :     return oldAppUnitsPerDevPixel != mAppUnitsPerDevPixel;
         765                 : }
         766                 :
         767                 : void
         768               0 : nsDeviceContext::UpdateScaledAppUnits()
         769                 : {
         770                 :     mAppUnitsPerDevPixel =
         771               0 :         NS_MAX(1, NSToIntRound(float(mAppUnitsPerDevNotScaledPixel) / mPixelScale));
         772               0 : }

Generated by: LCOV version 1.7