nsDeviceContext.h (9871B)
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 "gfxTypes.h" // for gfxFloat 11 #include "mozilla/RefPtr.h" // for RefPtr 12 #include "nsCOMPtr.h" // for nsCOMPtr 13 #include "nsCoord.h" // for nscoord 14 #include "nsError.h" // for nsresult 15 #include "nsISupports.h" // for NS_INLINE_DECL_REFCOUNTING 16 #include "nsMathUtils.h" // for NS_round 17 #include "nscore.h" // for char16_t, nsAString 18 #include "mozilla/AppUnits.h" // for AppUnits 19 #include "nsFontMetrics.h" // for nsFontMetrics::Params 20 #include "mozilla/gfx/Point.h" // for IntSize 21 #include "mozilla/gfx/PrintPromise.h" // for PrintEndDocumentPromise 22 23 class gfxContext; 24 class gfxTextPerfMetrics; 25 class gfxUserFontSet; 26 struct nsFont; 27 class nsAtom; 28 class nsIDeviceContextSpec; 29 class nsIScreen; 30 class nsIScreenManager; 31 class nsIWidget; 32 struct nsRect; 33 34 namespace mozilla { 35 namespace dom { 36 enum class ScreenColorGamut : uint8_t; 37 } // namespace dom 38 namespace hal { 39 enum class ScreenOrientation : uint32_t; 40 } // namespace hal 41 namespace widget { 42 class Screen; 43 } // namespace widget 44 namespace gfx { 45 class PrintTarget; 46 } 47 } // namespace mozilla 48 49 class nsDeviceContext final { 50 public: 51 using IntSize = mozilla::gfx::IntSize; 52 using PrintTarget = mozilla::gfx::PrintTarget; 53 54 nsDeviceContext(); 55 56 NS_INLINE_DECL_REFCOUNTING(nsDeviceContext) 57 58 /** 59 * Initialize the device context from a widget 60 * @param aWidget a widget to initialize the device context from 61 */ 62 void Init(nsIWidget* aWidget); 63 64 /** 65 * Initialize the device context from a device context spec 66 * @param aDevSpec the specification of the printing device 67 * @return error status 68 */ 69 nsresult InitForPrinting(nsIDeviceContextSpec* aDevSpec); 70 71 /** 72 * Create a rendering context and initialize it. Only call this 73 * method on device contexts that were initialized for printing. 74 * 75 * @return the new rendering context (guaranteed to be non-null) 76 */ 77 mozilla::UniquePtr<gfxContext> CreateRenderingContext(); 78 79 /** 80 * Create a reference rendering context and initialize it. Only call this 81 * method on device contexts that were initialized for printing. 82 * 83 * @return the new rendering context. 84 */ 85 mozilla::UniquePtr<gfxContext> CreateReferenceRenderingContext(); 86 87 /** 88 * Gets the number of app units in one device pixel; this number 89 * is usually a factor of AppUnitsPerCSSPixel(), although that is 90 * not guaranteed. 91 */ 92 int32_t AppUnitsPerDevPixel() const { return mAppUnitsPerDevPixel; } 93 94 static int32_t ComputeAppUnitsPerDevPixelForWidgetScale( 95 mozilla::CSSToLayoutDeviceScale); 96 static int32_t ApplyFullZoomToAPD(int32_t aAppUnitsPerPixel, float aFullZoom); 97 98 /** 99 * Convert device pixels which is used for gfx/thebes to nearest 100 * (rounded) app units 101 */ 102 nscoord GfxUnitsToAppUnits(gfxFloat aGfxUnits) const { 103 return nscoord(NS_round(aGfxUnits * AppUnitsPerDevPixel())); 104 } 105 106 /** 107 * Convert app units to device pixels which is used for gfx/thebes. 108 */ 109 gfxFloat AppUnitsToGfxUnits(nscoord aAppUnits) const { 110 return gfxFloat(aAppUnits) / AppUnitsPerDevPixel(); 111 } 112 113 /** 114 * Gets the number of app units in one physical inch; this is the 115 * device's DPI times AppUnitsPerDevPixel(). 116 */ 117 int32_t AppUnitsPerPhysicalInch() const { return mAppUnitsPerPhysicalInch; } 118 119 /** 120 * Get the ratio of app units to dev pixels that would be used at unit 121 * (100%) full zoom. 122 */ 123 int32_t AppUnitsPerDevPixelAtUnitFullZoom() const { 124 return mAppUnitsPerDevPixelAtUnitFullZoom; 125 } 126 127 /** 128 * Get the ratio of app units to dev pixels that would be used in a top-level 129 * chrome page such as browser.xhtml. 130 */ 131 int32_t AppUnitsPerDevPixelInTopLevelChromePage() const; 132 133 /** 134 * Return the bit depth of the device. 135 */ 136 uint32_t GetDepth(); 137 138 /** 139 * Return the color gamut of the device. 140 */ 141 mozilla::dom::ScreenColorGamut GetColorGamut(); 142 143 /** 144 * Return the orientation type of the device. 145 * If not screen device, return primary screen's value 146 */ 147 mozilla::hal::ScreenOrientation GetScreenOrientationType(); 148 149 /** 150 * Return the orientation angle of the device. 151 * If not screen device, return primary screen's value 152 */ 153 uint16_t GetScreenOrientationAngle(); 154 155 /** 156 * Get the status of HDR support of the associated screen. 157 */ 158 bool GetScreenIsHDR(); 159 160 /** 161 * Get the size of the displayable area of the output device in app units. 162 */ 163 nsSize GetDeviceSurfaceDimensions(); 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 entire screen. 169 */ 170 nsRect GetRect(); 171 172 /** 173 * Get the size of the content area of the output device in app 174 * units. This corresponds on a screen device, for instance, to 175 * the area reported by GetDeviceSurfaceDimensions, minus the 176 * taskbar (Windows) or menubar (Macintosh). 177 * Position (x,y) will be (0,0) adjusted for any upper/left non-client space 178 * if present or relative to the primary monitor if this is not the primary. 179 */ 180 nsRect GetClientRect(); 181 182 /** 183 * Returns true if we're currently between BeginDocument() and 184 * EndDocument() calls. 185 */ 186 bool IsCurrentlyPrintingDocument() const { return mIsCurrentlyPrintingDoc; } 187 188 /** 189 * Inform the output device that output of a document is beginning 190 * Used for print related device contexts. Must be matched 1:1 with 191 * EndDocument() or AbortDocument(). 192 * 193 * @param aTitle - title of Document 194 * @param aPrintToFileName - name of file to print to, if empty then don't 195 * print to file 196 * @param aStartPage - starting page number (must be greater than zero) 197 * @param aEndPage - ending page number (must be less than or 198 * equal to number of pages) 199 * 200 * @return error status 201 */ 202 nsresult BeginDocument(const nsAString& aTitle, 203 const nsAString& aPrintToFileName, int32_t aStartPage, 204 int32_t aEndPage); 205 206 /** 207 * Inform the output device that output of a document is ending. 208 * Used for print related device contexts. Must be matched 1:1 with 209 * BeginDocument() 210 * @return Promise that can be chained once the operation is complete. 211 */ 212 RefPtr<mozilla::gfx::PrintEndDocumentPromise> EndDocument(); 213 214 /** 215 * Inform the output device that output of a document is being aborted. 216 * Must be matched 1:1 with BeginDocument() 217 * @return error status 218 */ 219 nsresult AbortDocument(); 220 221 /** 222 * Inform the output device that output of a page is beginning 223 * Used for print related device contexts. Must be matched 1:1 with 224 * EndPage() and within a BeginDocument()/EndDocument() pair. 225 * 226 * @param aSizeInPoints - The physical dimensions of the page in points. 227 * Currently only supported (used) by print-to-PDF 228 * print targets, and then only to switch the 229 * orientation for a specific page (arbitrary page 230 * sizes are not supported by the Core Graphics print- 231 * to-PDF APIs, for example). 232 * 233 * @return error status 234 */ 235 nsresult BeginPage(const IntSize& aSizeInPoints); 236 237 /** 238 * Inform the output device that output of a page is ending 239 * Used for print related device contexts. Must be matched 1:1 with 240 * BeginPage() and within a BeginDocument()/EndDocument() pair. 241 * @return error status 242 */ 243 nsresult EndPage(); 244 245 /** 246 * Check to see if the DPI has changed, or impose a new DPI scale value. 247 * @return whether there was actually a change in the DPI (whether 248 * AppUnitsPerDevPixel() or AppUnitsPerPhysicalInch() 249 * changed) 250 */ 251 bool CheckDPIChange(); 252 253 /** 254 * Set the full zoom factor: all lengths are multiplied by this factor 255 * when we convert them to device pixels. Returns whether the ratio of 256 * app units to dev pixels changed because of the zoom factor. 257 */ 258 bool SetFullZoom(float aScale); 259 260 /** 261 * Returns the page full zoom factor applied. 262 */ 263 float GetFullZoom() const { return mFullZoom; } 264 265 /** 266 * True if this device context was created for printing. 267 */ 268 bool IsPrinterContext() const { return !!mPrintTarget; } 269 270 mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale(); 271 272 private: 273 // Private destructor, to discourage deletion outside of Release(): 274 ~nsDeviceContext(); 275 276 /** 277 * Implementation shared by CreateRenderingContext and 278 * CreateReferenceRenderingContext. 279 */ 280 mozilla::UniquePtr<gfxContext> CreateRenderingContextCommon( 281 bool aWantReferenceContext); 282 283 void SetDPI(); 284 285 // Determines which screen intersects the largest area of the given surface, 286 // or returns the primary screen. 287 already_AddRefed<mozilla::widget::Screen> FindScreen(); 288 289 // Return false if the surface is not right 290 bool CalcPrintingSize(); 291 void UpdateAppUnitsForFullZoom(); 292 293 nscoord mWidth; 294 nscoord mHeight; 295 int32_t mAppUnitsPerDevPixel; 296 int32_t mAppUnitsPerDevPixelAtUnitFullZoom; 297 int32_t mAppUnitsPerPhysicalInch; 298 float mFullZoom; 299 float mPrintingScale; 300 gfxPoint mPrintingTranslate; 301 302 nsCOMPtr<nsIWidget> mWidget; 303 nsCOMPtr<nsIDeviceContextSpec> mDeviceContextSpec; 304 RefPtr<PrintTarget> mPrintTarget; 305 bool mIsCurrentlyPrintingDoc; 306 bool mIsInitialized = false; 307 }; 308 309 #endif /* _NS_DEVICECONTEXT_H_ */