summaryrefslogtreecommitdiffstats
path: root/layout/printing/nsPrintJob.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/printing/nsPrintJob.h')
-rw-r--r--layout/printing/nsPrintJob.h311
1 files changed, 311 insertions, 0 deletions
diff --git a/layout/printing/nsPrintJob.h b/layout/printing/nsPrintJob.h
new file mode 100644
index 0000000000..d2ab0854ba
--- /dev/null
+++ b/layout/printing/nsPrintJob.h
@@ -0,0 +1,311 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 nsPrintJob_h
+#define nsPrintJob_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/layout/RemotePrintJobChild.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/UniquePtr.h"
+
+#include "nsCOMPtr.h"
+
+#include "nsHashKeys.h"
+#include "nsIFrame.h" // For WeakFrame
+#include "nsSize.h"
+#include "nsTArray.h"
+#include "nsTHashtable.h"
+#include "nsWeakReference.h"
+
+// Interfaces
+#include "nsIWebProgress.h"
+#include "nsIWebProgressListener.h"
+
+// Classes
+class nsIFrame;
+class nsIPrintSettings;
+class nsPrintData;
+class nsPagePrintTimer;
+class nsIDocShell;
+class nsIDocumentViewerPrint;
+class nsIFrame;
+class nsPrintObject;
+class nsIDocShell;
+class nsPageSequenceFrame;
+class nsPIDOMWindowOuter;
+class nsView;
+
+namespace mozilla {
+class PresShell;
+namespace dom {
+class Document;
+class PrintPreviewResultInfo;
+} // namespace dom
+} // namespace mozilla
+
+/**
+ * A print job may be instantiated either for printing to an actual physical
+ * printer, or for creating a print preview.
+ */
+class nsPrintJob final : public nsIWebProgressListener,
+ public nsSupportsWeakReference {
+ using Document = mozilla::dom::Document;
+ using PrintPreviewResolver =
+ std::function<void(const mozilla::dom::PrintPreviewResultInfo&)>;
+ using RemotePrintJobChild = mozilla::layout::RemotePrintJobChild;
+
+ public:
+ // nsISupports interface...
+ NS_DECL_ISUPPORTS
+
+ NS_DECL_NSIWEBPROGRESSLISTENER
+
+ /**
+ * Construct & initialize for printing, or for creating a print preview
+ * document.
+ *
+ * aDocViewerPrint owns us.
+ *
+ * When called in preparation for printing, aOriginalDoc is aDocViewerPrint's
+ * document. The document/viewer may be for a sub-document (an iframe).
+ *
+ * When called in preparation for print preview, aOriginalDoc belongs to a
+ * different docViewer, in a different docShell, in a different TabGroup.
+ * In this case our aDocViewerPrint is the docViewer for the about:blank
+ * document in a new tab that the Firefox frontend code has created in
+ * preparation for PrintPreview to generate a print preview document in it.
+ *
+ * NOTE: In the case we're called for print preview, aOriginalDoc actually
+ * may not be the original document that the user selected to print. It
+ * is not the actual original document in the case when the user chooses to
+ * display a simplified version of a print preview document. In that
+ * instance the Firefox frontend code creates a second print preview tab,
+ * with a new docViewer and nsPrintJob, and passes the previous print preview
+ * document as aOriginalDoc (it doesn't want to pass the actual original
+ * document since it may have mutated)!
+ * TODO(dholbert): This^ note is probably somewhat out of date, in part
+ * because frontend code doesn't create "print preview tabs" anymore,
+ * now that we have a tab-modal print/print-preview dialog...
+ */
+ nsPrintJob(nsIDocumentViewerPrint& aDocViewerPrint, nsIDocShell& aDocShell,
+ Document& aOriginalDoc, float aScreenDPI);
+
+ // Our nsIWebBrowserPrint implementation (nsDocumentViewer) defers to the
+ // following methods.
+
+ /**
+ * May be called immediately after initialization, or after one or more
+ * PrintPreview calls.
+ */
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
+ Print(Document& aSourceDoc, nsIPrintSettings* aPrintSettings,
+ RemotePrintJobChild* aRemotePrintJob,
+ nsIWebProgressListener* aWebProgressListener);
+
+ /**
+ * Generates a new print preview document and replaces our docViewer's
+ * document with it. (Note that this breaks the normal invariant that a
+ * Document and its nsDocumentViewer have an unchanging 1:1 relationship.)
+ *
+ * This may be called multiple times on the same instance in order to
+ * recreate the print preview document to take account of settings that the
+ * user has changed in the print preview interface. In this case aSourceDoc
+ * is actually our docViewer's current document!
+ */
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
+ PrintPreview(Document& aSourceDoc, nsIPrintSettings* aPrintSettings,
+ nsIWebProgressListener* aWebProgressListener,
+ PrintPreviewResolver&& aCallback);
+
+ bool IsDoingPrint() const { return mIsDoingPrinting; }
+ bool CreatedForPrintPreview() const { return mCreatedForPrintPreview; }
+ /// If the returned value is not greater than zero, an error occurred.
+ int32_t GetRawNumPages() const;
+ // Returns whether the preview is empty due to page range exclusion.
+ bool GetIsEmpty() const;
+
+ // Returns the total number of PrintedSheetFrames (i.e. faces of a sheet of
+ // paper) for this print job. (This may be less than the raw number of pages,
+ // due to pages having been skipped in a page range or combined into a single
+ // sheet via pages-per-sheet.)
+ int32_t GetPrintPreviewNumSheets() const;
+
+ // The setters here also update the DocViewer
+ void SetIsPrinting(bool aIsPrinting);
+ bool GetIsPrinting() const { return mIsDoingPrinting; }
+ void SetIsPrintPreview(bool aIsPrintPreview);
+ bool GetIsCreatingPrintPreview() const { return mIsCreatingPrintPreview; }
+
+ std::tuple<nsPageSequenceFrame*, int32_t> GetSeqFrameAndCountSheets() const;
+
+ bool PrePrintSheet();
+ bool PrintSheet(nsPrintObject* aPOect, bool& aInRange);
+ bool DonePrintingSheets(nsPrintObject* aPO, nsresult aResult);
+
+ nsresult CleanupOnFailure(nsresult aResult, bool aIsPrinting);
+ // If FinishPrintPreview() fails, caller may need to reset the state of the
+ // object, for example by calling CleanupOnFailure().
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult FinishPrintPreview();
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY void FirePrintingErrorEvent(nsresult aPrintError);
+
+ bool CheckBeforeDestroy() const;
+ nsresult Cancel();
+ void Destroy();
+ void DestroyPrintingData();
+
+ private:
+ nsPrintJob& operator=(const nsPrintJob& aOther) = delete;
+
+ ~nsPrintJob();
+
+ MOZ_CAN_RUN_SCRIPT nsresult DocumentReadyForPrinting();
+ MOZ_CAN_RUN_SCRIPT nsresult SetupToPrintContent();
+ nsresult EnablePOsForPrinting();
+
+ void BuildNestedPrintObjects(
+ const mozilla::UniquePtr<nsPrintObject>& aParentPO);
+
+ bool PrintDocContent(const mozilla::UniquePtr<nsPrintObject>& aPO,
+ nsresult& aStatus);
+ nsresult DoPrint(const mozilla::UniquePtr<nsPrintObject>& aPO);
+
+ nsresult ReflowDocList(const mozilla::UniquePtr<nsPrintObject>& aPO);
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY
+ nsresult ReflowPrintObject(const mozilla::UniquePtr<nsPrintObject>& aPO);
+
+ void CalcNumPrintablePages(int32_t& aNumPages);
+
+ nsresult StartPagePrintTimer(const mozilla::UniquePtr<nsPrintObject>& aPO);
+
+ /// Customizes the behaviour of GetDisplayTitleAndURL.
+ enum class DocTitleDefault : uint32_t { eDocURLElseFallback, eFallback };
+
+ /**
+ * Gets the title and URL of the document for display in save-to-PDF dialogs,
+ * print spooler lists and page headers/footers. This will get the title/URL
+ * from the PrintSettings, if set, otherwise it will get them from the
+ * document.
+ *
+ * For the title specifically, if a value is not provided by the settings
+ * object or the document then, if eDocURLElseFallback is passed, the document
+ * URL will be returned as the title if it's non-empty (which should always be
+ * the case). Otherwise a non-empty fallback title will be returned.
+ */
+ static void GetDisplayTitleAndURL(Document& aDoc, nsIPrintSettings* aSettings,
+ DocTitleDefault aTitleDefault,
+ nsAString& aTitle, nsAString& aURLStr);
+
+ MOZ_CAN_RUN_SCRIPT nsresult CommonPrint(
+ bool aIsPrintPreview, nsIPrintSettings* aPrintSettings,
+ nsIWebProgressListener* aWebProgressListener, Document& aSourceDoc);
+
+ MOZ_CAN_RUN_SCRIPT nsresult DoCommonPrint(
+ bool aIsPrintPreview, nsIPrintSettings* aPrintSettings,
+ nsIWebProgressListener* aWebProgressListener, Document& aSourceDoc);
+
+ void FirePrintCompletionEvent();
+
+ void DisconnectPagePrintTimer();
+
+ /**
+ * This method is called to resume printing after all outstanding resources
+ * referenced by the static clone have finished loading. (It is possibly
+ * called synchronously if there are no resources to load.) While a static
+ * clone will generally just be able to reference the (already loaded)
+ * resources that the original document references, the static clone may
+ * reference additional resources that have not previously been loaded
+ * (if it has a 'print' style sheet, for example).
+ */
+ MOZ_CAN_RUN_SCRIPT nsresult
+ MaybeResumePrintAfterResourcesLoaded(bool aCleanupOnError);
+
+ bool ShouldResumePrint() const;
+
+ nsresult SetRootView(nsPrintObject* aPO, bool& aDoReturn,
+ bool& aDocumentIsTopLevel, nsSize& aAdjSize);
+ nsView* GetParentViewForRoot();
+ void UpdateZoomRatio(nsPrintObject* aPO);
+ MOZ_CAN_RUN_SCRIPT nsresult ReconstructAndReflow();
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult UpdateSelectionAndShrinkPrintObject(
+ nsPrintObject* aPO, bool aDocumentIsTopLevel);
+ MOZ_CAN_RUN_SCRIPT nsresult InitPrintDocConstruction(bool aHandleError);
+ void FirePrintPreviewUpdateEvent();
+
+ void PageDone(nsresult aResult);
+
+ nsCOMPtr<nsIPrintSettings> mPrintSettings;
+
+ // The docViewer that owns us, and its docShell.
+ nsCOMPtr<nsIDocumentViewerPrint> mDocViewerPrint;
+ nsWeakPtr mDocShell;
+
+ WeakFrame mPageSeqFrame;
+
+ // We are the primary owner of our nsPrintData member vars. These vars
+ // are refcounted so that functions (e.g. nsPrintData methods) can create
+ // temporary owning references when they need to fire a callback that
+ // could conceivably destroy this nsPrintJob owner object and all its
+ // member-data.
+ RefPtr<nsPrintData> mPrt;
+
+ RefPtr<nsPagePrintTimer> mPagePrintTimer;
+
+ // Only set if this nsPrintJob was created for a real print.
+ RefPtr<RemotePrintJobChild> mRemotePrintJob;
+
+ // The root print object.
+ mozilla::UniquePtr<nsPrintObject> mPrintObject;
+
+ // If there is a focused iframe, mSelectionRoot is set to its nsPrintObject.
+ // Otherwise, if there is a selection, it is set to the root nsPrintObject.
+ // Otherwise, it is unset.
+ nsPrintObject* mSelectionRoot = nullptr;
+
+ // Array of non-owning pointers to all the nsPrintObjects owned by this
+ // nsPrintJob. This includes mPrintObject, as well as all of its mKids (and
+ // their mKids, etc.)
+ nsTArray<nsPrintObject*> mPrintDocList;
+
+ // If the code that initiates a print preview passes a PrintPreviewResolver
+ // (a std::function) to be notified of the final sheet/page counts (once
+ // we've sufficiently laid out the document to know what those are), that
+ // callback is stored here.
+ PrintPreviewResolver mPrintPreviewCallback;
+
+ // The scale factor that would need to be applied to all pages to make the
+ // widest page fit without overflowing/clipping.
+ float mShrinkToFitFactor = 1.0f;
+
+ float mScreenDPI = 115.0f;
+
+ int32_t mNumPrintablePages = 0;
+
+ // Indicates if the page has a specific orientation from @page { size }.
+ // Stores true if this is landscape, false if this is portrait, or nothing
+ // if there is no page-size-orientation.
+ mozilla::Maybe<bool> mMaybeCSSPageLandscape;
+
+ // Indicates if the page has a specific size from @page { size }.
+ // Stores the page size if one was found.
+ mozilla::Maybe<nsSize> mMaybeCSSPageSize;
+
+ // If true, indicates that we have started Printing but have not gone to the
+ // timer to start printing the pages. It gets turned off right before we go
+ // to the timer.
+ bool mPreparingForPrint = false;
+
+ bool mCreatedForPrintPreview = false;
+ bool mIsCreatingPrintPreview = false;
+ bool mIsDoingPrinting = false;
+ bool mDidLoadDataForPrinting = false;
+ bool mShrinkToFit = false;
+ bool mDoingInitialReflow = false;
+ bool mIsDestroying = false;
+ bool mDisallowSelectionPrint = false;
+};
+
+#endif // nsPrintJob_h