1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef _NS_DEVICECONTEXT_H_ 7 #define _NS_DEVICECONTEXT_H_ 8 9 #include <stdint.h> // for uint32_t 10 #include <sys/types.h> // for int32_t 11 #include "gfxTypes.h" // for gfxFloat 12 #include "gfxFont.h" // for gfxFont::Orientation 13 #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 14 #include "mozilla/RefPtr.h" // for RefPtr 15 #include "nsCOMPtr.h" // for nsCOMPtr 16 #include "nsCoord.h" // for nscoord 17 #include "nsError.h" // for nsresult 18 #include "nsISupports.h" // for NS_INLINE_DECL_REFCOUNTING 19 #include "nsMathUtils.h" // for NS_round 20 #include "nscore.h" // for char16_t, nsAString 21 #include "mozilla/AppUnits.h" // for AppUnits 22 #include "nsFontMetrics.h" // for nsFontMetrics::Params 23 #include "mozilla/gfx/PrintTarget.h" // for PrintTarget::PageDoneCallback 24 25 class gfxContext; 26 class gfxTextPerfMetrics; 27 class gfxUserFontSet; 28 struct nsFont; 29 class nsFontCache; 30 class nsAtom; 31 class nsIDeviceContextSpec; 32 class nsIScreen; 33 class nsIScreenManager; 34 class nsIWidget; 35 struct nsRect; 36 37 class nsDeviceContext final { 38 public: 39 typedef mozilla::gfx::PrintTarget PrintTarget; 40 41 nsDeviceContext(); 42 43 NS_INLINE_DECL_REFCOUNTING(nsDeviceContext) 44 45 /** 46 * Initialize the device context from a widget 47 * @param aWidget a widget to initialize the device context from 48 * @return error status 49 */ 50 nsresult Init(nsIWidget* aWidget); 51 52 /* 53 * Initialize the font cache if it hasn't been initialized yet. 54 * (Needed for stylo) 55 */ 56 void InitFontCache(); 57 58 void UpdateFontCacheUserFonts(gfxUserFontSet* aUserFontSet); 59 60 /** 61 * Initialize the device context from a device context spec 62 * @param aDevSpec the specification of the printing device 63 * @return error status 64 */ 65 nsresult InitForPrinting(nsIDeviceContextSpec* aDevSpec); 66 67 /** 68 * Create a rendering context and initialize it. Only call this 69 * method on device contexts that were initialized for printing. 70 * 71 * @return the new rendering context (guaranteed to be non-null) 72 */ 73 already_AddRefed<gfxContext> CreateRenderingContext(); 74 75 /** 76 * Create a reference rendering context and initialize it. Only call this 77 * method on device contexts that were initialized for printing. 78 * 79 * @return the new rendering context. 80 */ 81 already_AddRefed<gfxContext> CreateReferenceRenderingContext(); 82 83 /** 84 * Gets the number of app units in one device pixel; this number 85 * is usually a factor of AppUnitsPerCSSPixel(), although that is 86 * not guaranteed. 87 */ AppUnitsPerDevPixel()88 int32_t AppUnitsPerDevPixel() const { return mAppUnitsPerDevPixel; } 89 90 /** 91 * Convert device pixels which is used for gfx/thebes to nearest 92 * (rounded) app units 93 */ GfxUnitsToAppUnits(gfxFloat aGfxUnits)94 nscoord GfxUnitsToAppUnits(gfxFloat aGfxUnits) const { 95 return nscoord(NS_round(aGfxUnits * AppUnitsPerDevPixel())); 96 } 97 98 /** 99 * Convert app units to device pixels which is used for gfx/thebes. 100 */ AppUnitsToGfxUnits(nscoord aAppUnits)101 gfxFloat AppUnitsToGfxUnits(nscoord aAppUnits) const { 102 return gfxFloat(aAppUnits) / AppUnitsPerDevPixel(); 103 } 104 105 /** 106 * Gets the number of app units in one physical inch; this is the 107 * device's DPI times AppUnitsPerDevPixel(). 108 */ AppUnitsPerPhysicalInch()109 int32_t AppUnitsPerPhysicalInch() const { return mAppUnitsPerPhysicalInch; } 110 111 /** 112 * Get the ratio of app units to dev pixels that would be used at unit 113 * (100%) full zoom. 114 */ AppUnitsPerDevPixelAtUnitFullZoom()115 int32_t AppUnitsPerDevPixelAtUnitFullZoom() const { 116 return mAppUnitsPerDevPixelAtUnitFullZoom; 117 } 118 119 /** 120 * Get the nsFontMetrics that describe the properties of 121 * an nsFont. 122 * @param aFont font description to obtain metrics for 123 */ 124 already_AddRefed<nsFontMetrics> GetMetricsFor( 125 const nsFont& aFont, const nsFontMetrics::Params& aParams); 126 127 /** 128 * Notification when a font metrics instance created for this device is 129 * about to be deleted 130 */ 131 nsresult FontMetricsDeleted(const nsFontMetrics* aFontMetrics); 132 133 /** 134 * Attempt to free up resources by flushing out any fonts no longer 135 * referenced by anything other than the font cache itself. 136 * @return error status 137 */ 138 nsresult FlushFontCache(); 139 140 /** 141 * Return the bit depth of the device. 142 */ 143 nsresult GetDepth(uint32_t& aDepth); 144 145 /** 146 * Get the size of the displayable area of the output device 147 * in app units. 148 * @param aWidth out parameter for width 149 * @param aHeight out parameter for height 150 * @return error status 151 */ 152 nsresult GetDeviceSurfaceDimensions(nscoord& aWidth, nscoord& aHeight); 153 154 /** 155 * Get the size of the content area of the output device in app 156 * units. This corresponds on a screen device, for instance, to 157 * the entire screen. 158 * @param aRect out parameter for full rect. Position (x,y) will 159 * be (0,0) or relative to the primary monitor if 160 * this is not the primary. 161 * @return error status 162 */ 163 nsresult GetRect(nsRect& aRect); 164 165 /** 166 * Get the size of the content area of the output device in app 167 * units. This corresponds on a screen device, for instance, to 168 * the area reported by GetDeviceSurfaceDimensions, minus the 169 * taskbar (Windows) or menubar (Macintosh). 170 * @param aRect out parameter for client rect. Position (x,y) will 171 * be (0,0) adjusted for any upper/left non-client 172 * space if present or relative to the primary 173 * monitor if this is not the primary. 174 * @return error status 175 */ 176 nsresult GetClientRect(nsRect& aRect); 177 178 /** 179 * Returns true if we're currently between BeginDocument() and 180 * EndDocument() calls. 181 */ IsCurrentlyPrintingDocument()182 bool IsCurrentlyPrintingDocument() const { return mIsCurrentlyPrintingDoc; } 183 184 /** 185 * Inform the output device that output of a document is beginning 186 * Used for print related device contexts. Must be matched 1:1 with 187 * EndDocument() or AbortDocument(). 188 * 189 * @param aTitle - title of Document 190 * @param aPrintToFileName - name of file to print to, if empty then don't 191 * print to file 192 * @param aStartPage - starting page number (must be greater than zero) 193 * @param aEndPage - ending page number (must be less than or 194 * equal to number of pages) 195 * 196 * @return error status 197 */ 198 nsresult BeginDocument(const nsAString& aTitle, 199 const nsAString& aPrintToFileName, int32_t aStartPage, 200 int32_t aEndPage); 201 202 /** 203 * Inform the output device that output of a document is ending. 204 * Used for print related device contexts. Must be matched 1:1 with 205 * BeginDocument() 206 * @return error status 207 */ 208 nsresult EndDocument(); 209 210 /** 211 * Inform the output device that output of a document is being aborted. 212 * Must be matched 1:1 with BeginDocument() 213 * @return error status 214 */ 215 nsresult AbortDocument(); 216 217 /** 218 * Inform the output device that output of a page is beginning 219 * Used for print related device contexts. Must be matched 1:1 with 220 * EndPage() and within a BeginDocument()/EndDocument() pair. 221 * @return error status 222 */ 223 nsresult BeginPage(); 224 225 /** 226 * Inform the output device that output of a page is ending 227 * Used for print related device contexts. Must be matched 1:1 with 228 * BeginPage() and within a BeginDocument()/EndDocument() pair. 229 * @return error status 230 */ 231 nsresult EndPage(); 232 233 /** 234 * Check to see if the DPI has changed, or impose a new DPI scale value. 235 * @param aScale - If non-null, the default (unzoomed) CSS to device pixel 236 * scale factor will be returned here; and if it is > 0.0 237 * on input, the given value will be used instead of 238 * getting it from the widget (if any). This is used to 239 * allow subdocument contexts to inherit the resolution 240 * setting of their parent. 241 * @return whether there was actually a change in the DPI (whether 242 * AppUnitsPerDevPixel() or AppUnitsPerPhysicalInch() 243 * changed) 244 */ 245 bool CheckDPIChange(double* aScale = nullptr); 246 247 /** 248 * Set the full zoom factor: all lengths are multiplied by this factor 249 * when we convert them to device pixels. Returns whether the ratio of 250 * app units to dev pixels changed because of the zoom factor. 251 */ 252 bool SetFullZoom(float aScale); 253 254 /** 255 * Returns the page full zoom factor applied. 256 */ GetFullZoom()257 float GetFullZoom() const { return mFullZoom; } 258 259 /** 260 * True if this device context was created for printing. 261 */ 262 bool IsPrinterContext(); 263 264 mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale(); 265 266 private: 267 // Private destructor, to discourage deletion outside of Release(): 268 ~nsDeviceContext(); 269 270 /** 271 * Implementation shared by CreateRenderingContext and 272 * CreateReferenceRenderingContext. 273 */ 274 already_AddRefed<gfxContext> CreateRenderingContextCommon( 275 bool aWantReferenceContext); 276 277 void SetDPI(double* aScale = nullptr); 278 void ComputeClientRectUsingScreen(nsRect* outRect); 279 void ComputeFullAreaUsingScreen(nsRect* outRect); 280 void FindScreen(nsIScreen** outScreen); 281 282 // Return false if the surface is not right 283 bool CalcPrintingSize(); 284 void UpdateAppUnitsForFullZoom(); 285 286 nscoord mWidth; 287 nscoord mHeight; 288 int32_t mAppUnitsPerDevPixel; 289 int32_t mAppUnitsPerDevPixelAtUnitFullZoom; 290 int32_t mAppUnitsPerPhysicalInch; 291 float mFullZoom; 292 float mPrintingScale; 293 gfxPoint mPrintingTranslate; 294 295 RefPtr<nsFontCache> mFontCache; 296 nsCOMPtr<nsIWidget> mWidget; 297 nsCOMPtr<nsIScreenManager> mScreenManager; 298 nsCOMPtr<nsIDeviceContextSpec> mDeviceContextSpec; 299 RefPtr<PrintTarget> mPrintTarget; 300 bool mIsCurrentlyPrintingDoc; 301 #ifdef DEBUG 302 bool mIsInitialized; 303 #endif 304 }; 305 306 #endif /* _NS_DEVICECONTEXT_H_ */ 307