/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef _NS_DEVICECONTEXT_H_ #define _NS_DEVICECONTEXT_H_ #include // for uint32_t #include // for int32_t #include "gfxTypes.h" // for gfxFloat #include "gfxFont.h" // for gfxFont::Orientation #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 #include "mozilla/RefPtr.h" // for RefPtr #include "nsCOMPtr.h" // for nsCOMPtr #include "nsCoord.h" // for nscoord #include "nsError.h" // for nsresult #include "nsISupports.h" // for NS_INLINE_DECL_REFCOUNTING #include "nsMathUtils.h" // for NS_round #include "nscore.h" // for char16_t, nsAString #include "mozilla/AppUnits.h" // for AppUnits #include "nsFontMetrics.h" // for nsFontMetrics::Params #include "mozilla/gfx/PrintTarget.h" // for PrintTarget::PageDoneCallback class gfxContext; class gfxTextPerfMetrics; class gfxUserFontSet; struct nsFont; class nsFontCache; class nsAtom; class nsIDeviceContextSpec; class nsIScreen; class nsIScreenManager; class nsIWidget; struct nsRect; class nsDeviceContext final { public: typedef mozilla::gfx::PrintTarget PrintTarget; nsDeviceContext(); NS_INLINE_DECL_REFCOUNTING(nsDeviceContext) /** * Initialize the device context from a widget * @param aWidget a widget to initialize the device context from * @return error status */ nsresult Init(nsIWidget* aWidget); /* * Initialize the font cache if it hasn't been initialized yet. * (Needed for stylo) */ void InitFontCache(); void UpdateFontCacheUserFonts(gfxUserFontSet* aUserFontSet); /** * Initialize the device context from a device context spec * @param aDevSpec the specification of the printing device * @return error status */ nsresult InitForPrinting(nsIDeviceContextSpec* aDevSpec); /** * Create a rendering context and initialize it. Only call this * method on device contexts that were initialized for printing. * * @return the new rendering context (guaranteed to be non-null) */ already_AddRefed CreateRenderingContext(); /** * Create a reference rendering context and initialize it. Only call this * method on device contexts that were initialized for printing. * * @return the new rendering context. */ already_AddRefed CreateReferenceRenderingContext(); /** * Gets the number of app units in one device pixel; this number * is usually a factor of AppUnitsPerCSSPixel(), although that is * not guaranteed. */ int32_t AppUnitsPerDevPixel() const { return mAppUnitsPerDevPixel; } /** * Convert device pixels which is used for gfx/thebes to nearest * (rounded) app units */ nscoord GfxUnitsToAppUnits(gfxFloat aGfxUnits) const { return nscoord(NS_round(aGfxUnits * AppUnitsPerDevPixel())); } /** * Convert app units to device pixels which is used for gfx/thebes. */ gfxFloat AppUnitsToGfxUnits(nscoord aAppUnits) const { return gfxFloat(aAppUnits) / AppUnitsPerDevPixel(); } /** * Gets the number of app units in one physical inch; this is the * device's DPI times AppUnitsPerDevPixel(). */ int32_t AppUnitsPerPhysicalInch() const { return mAppUnitsPerPhysicalInch; } /** * Get the ratio of app units to dev pixels that would be used at unit * (100%) full zoom. */ int32_t AppUnitsPerDevPixelAtUnitFullZoom() const { return mAppUnitsPerDevPixelAtUnitFullZoom; } /** * Get the nsFontMetrics that describe the properties of * an nsFont. * @param aFont font description to obtain metrics for */ already_AddRefed GetMetricsFor( const nsFont& aFont, const nsFontMetrics::Params& aParams); /** * Notification when a font metrics instance created for this device is * about to be deleted */ nsresult FontMetricsDeleted(const nsFontMetrics* aFontMetrics); /** * Attempt to free up resources by flushing out any fonts no longer * referenced by anything other than the font cache itself. * @return error status */ nsresult FlushFontCache(); /** * Return the bit depth of the device. */ nsresult GetDepth(uint32_t& aDepth); /** * Get the size of the displayable area of the output device * in app units. * @param aWidth out parameter for width * @param aHeight out parameter for height * @return error status */ nsresult GetDeviceSurfaceDimensions(nscoord& aWidth, nscoord& aHeight); /** * Get the size of the content area of the output device in app * units. This corresponds on a screen device, for instance, to * the entire screen. * @param aRect out parameter for full rect. Position (x,y) will * be (0,0) or relative to the primary monitor if * this is not the primary. * @return error status */ nsresult GetRect(nsRect& aRect); /** * Get the size of the content area of the output device in app * units. This corresponds on a screen device, for instance, to * the area reported by GetDeviceSurfaceDimensions, minus the * taskbar (Windows) or menubar (Macintosh). * @param aRect out parameter for client rect. Position (x,y) will * be (0,0) adjusted for any upper/left non-client * space if present or relative to the primary * monitor if this is not the primary. * @return error status */ nsresult GetClientRect(nsRect& aRect); /** * Returns true if we're currently between BeginDocument() and * EndDocument() calls. */ bool IsCurrentlyPrintingDocument() const { return mIsCurrentlyPrintingDoc; } /** * Inform the output device that output of a document is beginning * Used for print related device contexts. Must be matched 1:1 with * EndDocument() or AbortDocument(). * * @param aTitle - title of Document * @param aPrintToFileName - name of file to print to, if empty then don't * print to file * @param aStartPage - starting page number (must be greater than zero) * @param aEndPage - ending page number (must be less than or * equal to number of pages) * * @return error status */ nsresult BeginDocument(const nsAString& aTitle, const nsAString& aPrintToFileName, int32_t aStartPage, int32_t aEndPage); /** * Inform the output device that output of a document is ending. * Used for print related device contexts. Must be matched 1:1 with * BeginDocument() * @return error status */ nsresult EndDocument(); /** * Inform the output device that output of a document is being aborted. * Must be matched 1:1 with BeginDocument() * @return error status */ nsresult AbortDocument(); /** * Inform the output device that output of a page is beginning * Used for print related device contexts. Must be matched 1:1 with * EndPage() and within a BeginDocument()/EndDocument() pair. * @return error status */ nsresult BeginPage(); /** * Inform the output device that output of a page is ending * Used for print related device contexts. Must be matched 1:1 with * BeginPage() and within a BeginDocument()/EndDocument() pair. * @return error status */ nsresult EndPage(); /** * Check to see if the DPI has changed, or impose a new DPI scale value. * @param aScale - If non-null, the default (unzoomed) CSS to device pixel * scale factor will be returned here; and if it is > 0.0 * on input, the given value will be used instead of * getting it from the widget (if any). This is used to * allow subdocument contexts to inherit the resolution * setting of their parent. * @return whether there was actually a change in the DPI (whether * AppUnitsPerDevPixel() or AppUnitsPerPhysicalInch() * changed) */ bool CheckDPIChange(double* aScale = nullptr); /** * Set the full zoom factor: all lengths are multiplied by this factor * when we convert them to device pixels. Returns whether the ratio of * app units to dev pixels changed because of the zoom factor. */ bool SetFullZoom(float aScale); /** * Returns the page full zoom factor applied. */ float GetFullZoom() const { return mFullZoom; } /** * True if this device context was created for printing. */ bool IsPrinterContext(); mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale(); bool IsSyncPagePrinting() const; void RegisterPageDoneCallback(PrintTarget::PageDoneCallback&& aCallback); void UnregisterPageDoneCallback(); private: // Private destructor, to discourage deletion outside of Release(): ~nsDeviceContext(); /** * Implementation shared by CreateRenderingContext and * CreateReferenceRenderingContext. */ already_AddRefed CreateRenderingContextCommon( bool aWantReferenceContext); void SetDPI(double* aScale = nullptr); void ComputeClientRectUsingScreen(nsRect* outRect); void ComputeFullAreaUsingScreen(nsRect* outRect); void FindScreen(nsIScreen** outScreen); // Return false if the surface is not right bool CalcPrintingSize(); void UpdateAppUnitsForFullZoom(); nscoord mWidth; nscoord mHeight; int32_t mAppUnitsPerDevPixel; int32_t mAppUnitsPerDevPixelAtUnitFullZoom; int32_t mAppUnitsPerPhysicalInch; float mFullZoom; float mPrintingScale; gfxPoint mPrintingTranslate; RefPtr mFontCache; nsCOMPtr mWidget; nsCOMPtr mScreenManager; nsCOMPtr mDeviceContextSpec; RefPtr mPrintTarget; bool mIsCurrentlyPrintingDoc; #ifdef DEBUG bool mIsInitialized; #endif }; #endif /* _NS_DEVICECONTEXT_H_ */