mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 468568. Main patch: support downloading fonts in printing and print preview. r=smaug
--HG-- extra : rebase_source : 2fbaef2896d218e6900449c9510fc867419eac30
This commit is contained in:
parent
c8bef43a8a
commit
d3cd6b36b2
@ -62,8 +62,11 @@ nsDataDocumentContentPolicy::ShouldLoad(uint32_t aContentType,
|
||||
|
||||
// Nothing else is OK to load for data documents
|
||||
if (doc->IsLoadedAsData()) {
|
||||
*aDecision = nsIContentPolicy::REJECT_TYPE;
|
||||
return NS_OK;
|
||||
// ...but let static (print/print preview) documents to load fonts.
|
||||
if (!doc->IsStaticDocument() || aContentType != nsIContentPolicy::TYPE_FONT) {
|
||||
*aDecision = nsIContentPolicy::REJECT_TYPE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (doc->IsBeingUsedAsImage()) {
|
||||
|
@ -127,6 +127,7 @@
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsIDocumentLoaderFactory.h"
|
||||
#include "nsIDocumentLoader.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIXMLContentSink.h"
|
||||
#include "nsIXULDocument.h"
|
||||
@ -7628,8 +7629,15 @@ nsDocument::CloneDocHelper(nsDocument* clone) const
|
||||
clone->mDocumentBaseURI = mDocumentBaseURI;
|
||||
|
||||
if (mCreatingStaticClone) {
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
|
||||
// |mDocumentContainer| is the container of the document that is being
|
||||
// created and not the original container. See CreateStaticClone function().
|
||||
nsCOMPtr<nsIDocumentLoader> docLoader = do_QueryReferent(mDocumentContainer);
|
||||
if (docLoader) {
|
||||
docLoader->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
}
|
||||
nsCOMPtr<nsIChannel> channel = GetChannel();
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
|
||||
if (channel && loadGroup) {
|
||||
clone->Reset(channel, loadGroup);
|
||||
} else {
|
||||
|
@ -433,7 +433,7 @@ protected:
|
||||
nsCOMPtr<nsIPrintSettings> mCachedPrintSettings;
|
||||
nsCOMPtr<nsIWebProgressListener> mCachedPrintWebProgressListner;
|
||||
|
||||
nsCOMPtr<nsPrintEngine> mPrintEngine;
|
||||
nsRefPtr<nsPrintEngine> mPrintEngine;
|
||||
float mOriginalPrintPreviewScale;
|
||||
float mPrintPreviewZoom;
|
||||
nsAutoPtr<nsPrintEventDispatcher> mBeforeAndAfterPrint;
|
||||
|
@ -37,6 +37,7 @@ include $(topsrcdir)/config/rules.mk
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(srcdir)/../base \
|
||||
-I$(srcdir)/../../content/base/src \
|
||||
-I$(srcdir)/../../view/src \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += -D_IMPL_NS_LAYOUT
|
||||
|
@ -18,6 +18,9 @@
|
||||
#include "nsITextToSubURI.h"
|
||||
#include "nsError.h"
|
||||
|
||||
#include "nsView.h"
|
||||
#include "nsAsyncDOMEvent.h"
|
||||
|
||||
// Print Options
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsIPrintSettingsService.h"
|
||||
@ -209,7 +212,8 @@ protected:
|
||||
// Class IDs
|
||||
static NS_DEFINE_CID(kViewManagerCID, NS_VIEW_MANAGER_CID);
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsPrintEngine, nsIObserver)
|
||||
NS_IMPL_ISUPPORTS3(nsPrintEngine, nsIWebProgressListener,
|
||||
nsISupportsWeakReference, nsIObserver)
|
||||
|
||||
//---------------------------------------------------
|
||||
//-- nsPrintEngine Class Impl
|
||||
@ -225,7 +229,9 @@ nsPrintEngine::nsPrintEngine() :
|
||||
mPageSeqFrame(nullptr),
|
||||
mPrtPreview(nullptr),
|
||||
mOldPrtPreview(nullptr),
|
||||
mDebugFile(nullptr)
|
||||
mDebugFile(nullptr),
|
||||
mLoadCounter(0),
|
||||
mDidLoadDataForPrinting(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -672,6 +678,23 @@ nsPrintEngine::DoCommonPrint(bool aIsPrintPreview,
|
||||
}
|
||||
}
|
||||
|
||||
if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep) {
|
||||
CheckForChildFrameSets(mPrt->mPrintObject);
|
||||
}
|
||||
|
||||
if (NS_FAILED(EnablePOsForPrinting())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Attach progressListener to catch network requests.
|
||||
nsCOMPtr<nsIWebProgress> webProgress = do_QueryInterface(mPrt->mPrintObject->mDocShell);
|
||||
webProgress->AddProgressListener(
|
||||
static_cast<nsIWebProgressListener*>(this),
|
||||
nsIWebProgress::NOTIFY_STATE_REQUEST);
|
||||
|
||||
mLoadCounter = 0;
|
||||
mDidLoadDataForPrinting = false;
|
||||
|
||||
if (aIsPrintPreview) {
|
||||
bool notifyOnInit = false;
|
||||
ShowPrintProgress(false, notifyOnInit);
|
||||
@ -680,19 +703,19 @@ nsPrintEngine::DoCommonPrint(bool aIsPrintPreview,
|
||||
TurnScriptingOn(false);
|
||||
|
||||
if (!notifyOnInit) {
|
||||
rv = FinishPrintPreview();
|
||||
InstallPrintPreviewListener();
|
||||
rv = InitPrintDocConstruction(false);
|
||||
} else {
|
||||
rv = NS_OK;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
bool doNotify;
|
||||
ShowPrintProgress(true, doNotify);
|
||||
if (!doNotify) {
|
||||
// Print listener setup...
|
||||
mPrt->OnStartPrinting();
|
||||
rv = DocumentReadyForPrinting();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = InitPrintDocConstruction(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -804,10 +827,19 @@ nsPrintEngine::GetPrintPreviewNumPages(int32_t *aPrintPreviewNumPages)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPrintPreviewNumPages);
|
||||
|
||||
nsPrintData* prt = nullptr;
|
||||
nsIFrame* seqFrame = nullptr;
|
||||
*aPrintPreviewNumPages = 0;
|
||||
if (!mPrtPreview ||
|
||||
NS_FAILED(GetSeqFrameAndCountPagesInternal(mPrtPreview->mPrintObject, seqFrame, *aPrintPreviewNumPages))) {
|
||||
|
||||
// When calling this function, the FinishPrintPreview() function might not
|
||||
// been called as there are still some
|
||||
if (mPrtPreview) {
|
||||
prt = mPrtPreview;
|
||||
} else {
|
||||
prt = mPrt;
|
||||
}
|
||||
if ((!prt) ||
|
||||
NS_FAILED(GetSeqFrameAndCountPagesInternal(prt->mPrintObject, seqFrame, *aPrintPreviewNumPages))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
@ -1598,39 +1630,81 @@ nsPrintEngine::ShowPrintErrorDialog(nsresult aPrintError, bool aIsPrinting)
|
||||
//-- Section: Reflow Methods
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
nsPrintEngine::ReconstructAndReflow(bool doSetPixelScale)
|
||||
{
|
||||
#if (defined(XP_WIN) || defined(XP_OS2)) && defined(EXTENDED_DEBUG_PRINTING)
|
||||
// We need to clear all the output files here
|
||||
// because they will be re-created with second reflow of the docs
|
||||
if (kPrintingLogMod && kPrintingLogMod->level == DUMP_LAYOUT_LEVEL) {
|
||||
RemoveFilesInDir(".\\");
|
||||
gDumpFileNameCnt = 0;
|
||||
gDumpLOFileNameCnt = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (uint32_t i = 0; i < mPrt->mPrintDocList.Length(); ++i) {
|
||||
nsPrintObject* po = mPrt->mPrintDocList.ElementAt(i);
|
||||
NS_ASSERTION(po, "nsPrintObject can't be null!");
|
||||
|
||||
if (po->mDontPrint || po->mInvisible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
UpdateZoomRatio(po, doSetPixelScale);
|
||||
|
||||
po->mPresContext->SetPageScale(po->mZoomRatio);
|
||||
|
||||
// Calculate scale factor from printer to screen
|
||||
float printDPI = float(mPrt->mPrintDC->AppUnitsPerCSSInch()) /
|
||||
float(mPrt->mPrintDC->AppUnitsPerDevPixel());
|
||||
po->mPresContext->SetPrintPreviewScale(mScreenDPI / printDPI);
|
||||
|
||||
po->mPresShell->ReconstructFrames();
|
||||
|
||||
// For all views except the first one, setup the root view.
|
||||
// ??? Can there be multiple po for the top-level-document?
|
||||
bool documentIsTopLevel = true;
|
||||
if (i != 0) {
|
||||
nsSize adjSize;
|
||||
bool doReturn;
|
||||
nsresult rv = SetRootView(po, doReturn, documentIsTopLevel, adjSize);
|
||||
|
||||
MOZ_ASSERT(!documentIsTopLevel, "How could this happen?");
|
||||
|
||||
if (NS_FAILED(rv) || doReturn) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
po->mPresShell->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
nsresult rv = UpdateSelectionAndShrinkPrintObject(po, documentIsTopLevel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
nsresult
|
||||
nsPrintEngine::SetupToPrintContent()
|
||||
{
|
||||
// In this step we figure out which documents should be printed
|
||||
// i.e. if we are printing the selection then only enable that nsPrintObject
|
||||
// for printing
|
||||
if (NS_FAILED(EnablePOsForPrinting())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
DUMP_DOC_LIST("\nAfter Enable------------------------------------------");
|
||||
nsresult rv;
|
||||
|
||||
// This is an Optimization
|
||||
// If we are in PP then we already know all the shrinkage information
|
||||
// so just transfer it to the PrintData and we will skip the extra shrinkage reflow
|
||||
//
|
||||
// doSetPixelScale tells Reflow whether to set the shrinkage value into the DC
|
||||
// The first time we do not want to do this, the second time through we do
|
||||
bool doSetPixelScale = false;
|
||||
bool ppIsShrinkToFit = mPrtPreview && mPrtPreview->mShrinkToFit;
|
||||
if (ppIsShrinkToFit) {
|
||||
mPrt->mShrinkRatio = mPrtPreview->mShrinkRatio;
|
||||
doSetPixelScale = true;
|
||||
bool didReconstruction = false;
|
||||
|
||||
// If some new content got loaded since the initial reflow rebuild
|
||||
// everything.
|
||||
if (mDidLoadDataForPrinting) {
|
||||
rv = ReconstructAndReflow(DoSetPixelScale());
|
||||
didReconstruction = true;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Here we reflow all the PrintObjects
|
||||
nsresult rv = ReflowDocList(mPrt->mPrintObject, doSetPixelScale);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Here is where we do the extra reflow for shrinking the content
|
||||
// Here is where we figure out if extra reflow for shrinking the content
|
||||
// is required.
|
||||
// But skip this step if we are in PrintPreview
|
||||
bool ppIsShrinkToFit = mPrtPreview && mPrtPreview->mShrinkToFit;
|
||||
if (mPrt->mShrinkToFit && !ppIsShrinkToFit) {
|
||||
// Now look for the PO that has the smallest percent for shrink to fit
|
||||
if (mPrt->mPrintDocList.Length() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) {
|
||||
@ -1645,54 +1719,37 @@ nsPrintEngine::SetupToPrintContent()
|
||||
mPrt->mShrinkRatio = mPrt->mPrintObject->mShrinkRatio;
|
||||
}
|
||||
|
||||
// Only Shrink if we are smaller
|
||||
if (mPrt->mShrinkRatio < 0.998f) {
|
||||
for (uint32_t i=0;i<mPrt->mPrintDocList.Length();i++) {
|
||||
nsPrintObject* po = mPrt->mPrintDocList.ElementAt(i);
|
||||
NS_ASSERTION(po, "nsPrintObject can't be null!");
|
||||
// Wipe out the presentation before we reflow
|
||||
po->DestroyPresentation();
|
||||
}
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_OS2)) && defined(EXTENDED_DEBUG_PRINTING)
|
||||
// We need to clear all the output files here
|
||||
// because they will be re-created with second reflow of the docs
|
||||
if (kPrintingLogMod && kPrintingLogMod->level == DUMP_LAYOUT_LEVEL) {
|
||||
RemoveFilesInDir(".\\");
|
||||
gDumpFileNameCnt = 0;
|
||||
gDumpLOFileNameCnt = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Here we reflow all the PrintObjects a second time
|
||||
// this time using the shrinkage values
|
||||
// The last param here tells reflow to NOT calc the shrinkage values
|
||||
if (NS_FAILED(ReflowDocList(mPrt->mPrintObject, true))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = ReconstructAndReflow(true);
|
||||
didReconstruction = true;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
float calcRatio = 0.0f;
|
||||
if (mPrt->mPrintDocList.Length() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) {
|
||||
nsPrintObject* smallestPO = FindSmallestSTF();
|
||||
NS_ASSERTION(smallestPO, "There must always be an XMost PO!");
|
||||
if (smallestPO) {
|
||||
// Calc the shrinkage based on the entire content area
|
||||
calcRatio = smallestPO->mShrinkRatio;
|
||||
}
|
||||
} else {
|
||||
// Single document so use the Shrink as calculated for the PO
|
||||
calcRatio = mPrt->mPrintObject->mShrinkRatio;
|
||||
float calcRatio = 0.0f;
|
||||
if (mPrt->mPrintDocList.Length() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) {
|
||||
nsPrintObject* smallestPO = FindSmallestSTF();
|
||||
NS_ASSERTION(smallestPO, "There must always be an XMost PO!");
|
||||
if (smallestPO) {
|
||||
// Calc the shrinkage based on the entire content area
|
||||
calcRatio = smallestPO->mShrinkRatio;
|
||||
}
|
||||
PR_PL(("**************************************************************************\n"));
|
||||
PR_PL(("STF Ratio is: %8.5f Effective Ratio: %8.5f Diff: %8.5f\n", mPrt->mShrinkRatio, calcRatio, mPrt->mShrinkRatio-calcRatio));
|
||||
PR_PL(("**************************************************************************\n"));
|
||||
} else {
|
||||
// Single document so use the Shrink as calculated for the PO
|
||||
calcRatio = mPrt->mPrintObject->mShrinkRatio;
|
||||
}
|
||||
PR_PL(("**************************************************************************\n"));
|
||||
PR_PL(("STF Ratio is: %8.5f Effective Ratio: %8.5f Diff: %8.5f\n", mPrt->mShrinkRatio, calcRatio, mPrt->mShrinkRatio-calcRatio));
|
||||
PR_PL(("**************************************************************************\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// If the frames got reconstructed and reflowed the number of pages might
|
||||
// has changed.
|
||||
if (didReconstruction) {
|
||||
FirePrintPreviewUpdateEvent();
|
||||
}
|
||||
|
||||
DUMP_DOC_LIST(("\nAfter Reflow------------------------------------------"));
|
||||
PR_PL(("\n"));
|
||||
PR_PL(("-------------------------------------------------------\n"));
|
||||
@ -1792,21 +1849,7 @@ nsPrintEngine::ReflowDocList(nsPrintObject* aPO, bool aSetPixelScale)
|
||||
}
|
||||
}
|
||||
|
||||
// Here is where we set the shrinkage value into the DC
|
||||
// and this is what actually makes it shrink
|
||||
if (aSetPixelScale && aPO->mFrameType != eIFrame) {
|
||||
float ratio;
|
||||
if (mPrt->mPrintFrameType == nsIPrintSettings::kFramesAsIs || mPrt->mPrintFrameType == nsIPrintSettings::kNoFrames) {
|
||||
ratio = mPrt->mShrinkRatio - 0.005f; // round down
|
||||
} else {
|
||||
ratio = aPO->mShrinkRatio - 0.005f; // round down
|
||||
}
|
||||
aPO->mZoomRatio = ratio;
|
||||
} else if (!mPrt->mShrinkToFit) {
|
||||
double scaling;
|
||||
mPrt->mPrintSettings->GetScaling(&scaling);
|
||||
aPO->mZoomRatio = float(scaling);
|
||||
}
|
||||
UpdateZoomRatio(aPO, aSetPixelScale);
|
||||
|
||||
nsresult rv;
|
||||
// Reflow the PO
|
||||
@ -1821,28 +1864,248 @@ nsPrintEngine::ReflowDocList(nsPrintObject* aPO, bool aSetPixelScale)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Reflow a nsPrintObject
|
||||
nsresult
|
||||
nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO)
|
||||
void
|
||||
nsPrintEngine::FirePrintPreviewUpdateEvent()
|
||||
{
|
||||
NS_ASSERTION(aPO, "Pointer is null!");
|
||||
if (!aPO) return NS_ERROR_FAILURE;
|
||||
// Dispatch the event only while in PrintPreview. When printing, there is no
|
||||
// listener bound to this event and therefore no need to dispatch it.
|
||||
if (mIsDoingPrintPreview && !mIsDoingPrinting) {
|
||||
nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(mDocViewerPrint);
|
||||
(new nsAsyncDOMEvent(
|
||||
cv->GetDocument(), NS_LITERAL_STRING("printPreviewUpdate"), true, true)
|
||||
)->RunDOMEventWhenSafe();
|
||||
}
|
||||
}
|
||||
|
||||
nsSize adjSize;
|
||||
bool documentIsTopLevel;
|
||||
if (!aPO->IsPrintable())
|
||||
nsresult
|
||||
nsPrintEngine::InitPrintDocConstruction(bool aHandleError)
|
||||
{
|
||||
nsresult rv;
|
||||
rv = ReflowDocList(mPrt->mPrintObject, DoSetPixelScale());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
FirePrintPreviewUpdateEvent();
|
||||
|
||||
if (mLoadCounter == 0) {
|
||||
AfterNetworkPrint(aHandleError);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPrintEngine::AfterNetworkPrint(bool aHandleError)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgress> webProgress = do_QueryInterface(mPrt->mPrintObject->mDocShell);
|
||||
|
||||
webProgress->RemoveProgressListener(
|
||||
static_cast<nsIWebProgressListener*>(this));
|
||||
|
||||
nsresult rv;
|
||||
if (mIsDoingPrinting) {
|
||||
rv = DocumentReadyForPrinting();
|
||||
} else {
|
||||
rv = FinishPrintPreview();
|
||||
}
|
||||
|
||||
/* cleaup on failure + notify user */
|
||||
if (aHandleError && NS_FAILED(rv)) {
|
||||
CleanupOnFailure(rv, !mIsDoingPrinting);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIWebProgressListener
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintEngine::OnStateChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
uint32_t aStateFlags,
|
||||
nsresult aStatus)
|
||||
{
|
||||
nsAutoCString name;
|
||||
aRequest->GetName(name);
|
||||
if (name.Equals("about:document-onload-blocker")) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (aStateFlags & STATE_START) {
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
|
||||
++mLoadCounter;
|
||||
} else if (aStateFlags & STATE_STOP) {
|
||||
mDidLoadDataForPrinting = true;
|
||||
--mLoadCounter;
|
||||
|
||||
// If all resources are loaded, then do a small timeout and if there
|
||||
// are still no new requests, then another reflow.
|
||||
if (mLoadCounter == 0) {
|
||||
AfterNetworkPrint(true);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintEngine::OnProgressChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
int32_t aCurSelfProgress,
|
||||
int32_t aMaxSelfProgress,
|
||||
int32_t aCurTotalProgress,
|
||||
int32_t aMaxTotalProgress)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintEngine::OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
nsIURI* aLocation,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintEngine::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintEngine::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
uint32_t aState)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
|
||||
void
|
||||
nsPrintEngine::UpdateZoomRatio(nsPrintObject* aPO, bool aSetPixelScale)
|
||||
{
|
||||
// Here is where we set the shrinkage value into the DC
|
||||
// and this is what actually makes it shrink
|
||||
if (aSetPixelScale && aPO->mFrameType != eIFrame) {
|
||||
float ratio;
|
||||
if (mPrt->mPrintFrameType == nsIPrintSettings::kFramesAsIs || mPrt->mPrintFrameType == nsIPrintSettings::kNoFrames) {
|
||||
ratio = mPrt->mShrinkRatio - 0.005f; // round down
|
||||
} else {
|
||||
ratio = aPO->mShrinkRatio - 0.005f; // round down
|
||||
}
|
||||
aPO->mZoomRatio = ratio;
|
||||
} else if (!mPrt->mShrinkToFit) {
|
||||
double scaling;
|
||||
mPrt->mPrintSettings->GetScaling(&scaling);
|
||||
aPO->mZoomRatio = float(scaling);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPrintEngine::UpdateSelectionAndShrinkPrintObject(nsPrintObject* aPO,
|
||||
bool aDocumentIsTopLevel)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> displayShell;
|
||||
aPO->mDocShell->GetPresShell(getter_AddRefs(displayShell));
|
||||
// Transfer Selection Ranges to the new Print PresShell
|
||||
nsCOMPtr<nsISelection> selection, selectionPS;
|
||||
// It's okay if there is no display shell, just skip copying the selection
|
||||
if (displayShell) {
|
||||
selection = displayShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
|
||||
}
|
||||
selectionPS = aPO->mPresShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
|
||||
|
||||
// Reset all existing selection ranges that might have been added by calling
|
||||
// this function before.
|
||||
if (selectionPS) {
|
||||
selectionPS->RemoveAllRanges();
|
||||
}
|
||||
if (selection && selectionPS) {
|
||||
int32_t cnt;
|
||||
selection->GetRangeCount(&cnt);
|
||||
int32_t inx;
|
||||
for (inx = 0; inx < cnt; ++inx) {
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
if (NS_SUCCEEDED(selection->GetRangeAt(inx, getter_AddRefs(range))))
|
||||
selectionPS->AddRange(range);
|
||||
}
|
||||
}
|
||||
|
||||
// If we are trying to shrink the contents to fit on the page
|
||||
// we must first locate the "pageContent" frame
|
||||
// Then we walk the frame tree and look for the "xmost" frame
|
||||
// this is the frame where the right-hand side of the frame extends
|
||||
// the furthest
|
||||
if (mPrt->mShrinkToFit && aDocumentIsTopLevel) {
|
||||
nsIPageSequenceFrame* pageSequence = aPO->mPresShell->GetPageSequenceFrame();
|
||||
NS_ENSURE_STATE(pageSequence);
|
||||
pageSequence->GetSTFPercent(aPO->mShrinkRatio);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsPrintEngine::DoSetPixelScale()
|
||||
{
|
||||
// This is an Optimization
|
||||
// If we are in PP then we already know all the shrinkage information
|
||||
// so just transfer it to the PrintData and we will skip the extra shrinkage reflow
|
||||
//
|
||||
// doSetPixelScale tells Reflow whether to set the shrinkage value into the DC
|
||||
// The first time we do not want to do this, the second time through we do
|
||||
bool doSetPixelScale = false;
|
||||
bool ppIsShrinkToFit = mPrtPreview && mPrtPreview->mShrinkToFit;
|
||||
if (ppIsShrinkToFit) {
|
||||
mPrt->mShrinkRatio = mPrtPreview->mShrinkRatio;
|
||||
doSetPixelScale = true;
|
||||
}
|
||||
return doSetPixelScale;
|
||||
}
|
||||
|
||||
nsIView*
|
||||
nsPrintEngine::GetParentViewForRoot()
|
||||
{
|
||||
if (mIsCreatingPrintPreview) {
|
||||
nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(mDocViewerPrint);
|
||||
if (cv) {
|
||||
return cv->FindContainerView();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPrintEngine::SetRootView(
|
||||
nsPrintObject* aPO,
|
||||
bool& doReturn,
|
||||
bool& documentIsTopLevel,
|
||||
nsSize& adjSize
|
||||
)
|
||||
{
|
||||
bool canCreateScrollbars = true;
|
||||
|
||||
nsIView* rootView;
|
||||
nsIView* parentView = nullptr;
|
||||
|
||||
doReturn = false;
|
||||
|
||||
if (aPO->mParent && aPO->mParent->IsPrintable()) {
|
||||
nsIFrame* frame = aPO->mContent ? aPO->mContent->GetPrimaryFrame() : nullptr;
|
||||
// Without a frame, this document can't be displayed; therefore, there is no
|
||||
// point to reflowing it
|
||||
if (!frame) {
|
||||
SetPrintPO(aPO, false);
|
||||
doReturn = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1867,21 +2130,51 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO)
|
||||
mPrt->mPrintDC->GetDeviceSurfaceDimensions(pageWidth, pageHeight);
|
||||
adjSize = nsSize(pageWidth, pageHeight);
|
||||
documentIsTopLevel = true;
|
||||
|
||||
if (mIsCreatingPrintPreview) {
|
||||
nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(mDocViewerPrint);
|
||||
if (cv) {
|
||||
parentView = cv->FindContainerView();
|
||||
}
|
||||
}
|
||||
parentView = GetParentViewForRoot();
|
||||
}
|
||||
|
||||
if (aPO->mPresShell->GetViewManager()->GetRootView()) {
|
||||
// Reuse the root view that is already on the root frame.
|
||||
rootView = aPO->mPresShell->GetRootFrame()->GetView();
|
||||
reinterpret_cast<nsView*>(rootView)->SetParent(reinterpret_cast<nsView*>(parentView));
|
||||
} else {
|
||||
// Create a child window of the parent that is our "root view/window"
|
||||
nsRect tbounds = nsRect(nsPoint(0, 0), adjSize);
|
||||
rootView = aPO->mViewManager->CreateView(tbounds, parentView);
|
||||
NS_ENSURE_TRUE(rootView, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
if (mIsCreatingPrintPreview && documentIsTopLevel) {
|
||||
aPO->mPresContext->SetPaginatedScrolling(canCreateScrollbars);
|
||||
}
|
||||
|
||||
// Setup hierarchical relationship in view manager
|
||||
aPO->mViewManager->SetRootView(rootView);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Reflow a nsPrintObject
|
||||
nsresult
|
||||
nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO)
|
||||
{
|
||||
NS_ENSURE_STATE(aPO);
|
||||
|
||||
if (!aPO->IsPrintable()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(!aPO->mPresContext, "Recreating prescontext");
|
||||
|
||||
// create the PresContext
|
||||
aPO->mPresContext = new nsPresContext(aPO->mDocument,
|
||||
mIsCreatingPrintPreview ? nsPresContext::eContext_PrintPreview:
|
||||
nsPresContext::eContext_Print);
|
||||
nsPresContext::nsPresContextType type =
|
||||
mIsCreatingPrintPreview ? nsPresContext::eContext_PrintPreview:
|
||||
nsPresContext::eContext_Print;
|
||||
nsIView* parentView =
|
||||
aPO->mParent && aPO->mParent->IsPrintable() ? nullptr : GetParentViewForRoot();
|
||||
aPO->mPresContext = parentView ?
|
||||
new nsPresContext(aPO->mDocument, type) :
|
||||
new nsRootPresContext(aPO->mDocument, type);
|
||||
NS_ENSURE_TRUE(aPO->mPresContext, NS_ERROR_OUT_OF_MEMORY);
|
||||
aPO->mPresContext->SetPrintSettings(mPrt->mPrintSettings);
|
||||
|
||||
@ -1917,20 +2210,20 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO)
|
||||
|
||||
// The pres shell now owns the style set object.
|
||||
|
||||
PR_PL(("In DV::ReflowPrintObject PO: %p (%9s) Setting w,h to %d,%d\n", aPO,
|
||||
gFrameTypesStr[aPO->mFrameType], adjSize.width, adjSize.height));
|
||||
|
||||
// Create a child window of the parent that is our "root view/window"
|
||||
nsRect tbounds = nsRect(nsPoint(0, 0), adjSize);
|
||||
nsIView* rootView = aPO->mViewManager->CreateView(tbounds, parentView);
|
||||
NS_ENSURE_TRUE(rootView, NS_ERROR_OUT_OF_MEMORY);
|
||||
bool doReturn = false;;
|
||||
bool documentIsTopLevel = false;
|
||||
nsSize adjSize;
|
||||
|
||||
if (mIsCreatingPrintPreview && documentIsTopLevel) {
|
||||
aPO->mPresContext->SetPaginatedScrolling(canCreateScrollbars);
|
||||
rv = SetRootView(aPO, doReturn, documentIsTopLevel, adjSize);
|
||||
|
||||
if (NS_FAILED(rv) || doReturn) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Setup hierarchical relationship in view manager
|
||||
aPO->mViewManager->SetRootView(rootView);
|
||||
PR_PL(("In DV::ReflowPrintObject PO: %p pS: %p (%9s) Setting w,h to %d,%d\n", aPO, aPO->mPresShell.get(),
|
||||
gFrameTypesStr[aPO->mFrameType], adjSize.width, adjSize.height));
|
||||
|
||||
|
||||
// This docshell stuff is weird; will go away when we stop having multiple
|
||||
// presentations per document
|
||||
@ -1961,36 +2254,8 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO)
|
||||
// Process the reflow event Initialize posted
|
||||
aPO->mPresShell->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
nsCOMPtr<nsIPresShell> displayShell;
|
||||
aPO->mDocShell->GetPresShell(getter_AddRefs(displayShell));
|
||||
// Transfer Selection Ranges to the new Print PresShell
|
||||
nsCOMPtr<nsISelection> selection, selectionPS;
|
||||
// It's okay if there is no display shell, just skip copying the selection
|
||||
if (displayShell) {
|
||||
selection = displayShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
|
||||
}
|
||||
selectionPS = aPO->mPresShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
|
||||
if (selection && selectionPS) {
|
||||
int32_t cnt;
|
||||
selection->GetRangeCount(&cnt);
|
||||
int32_t inx;
|
||||
for (inx=0;inx<cnt;inx++) {
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
if (NS_SUCCEEDED(selection->GetRangeAt(inx, getter_AddRefs(range))))
|
||||
selectionPS->AddRange(range);
|
||||
}
|
||||
}
|
||||
|
||||
// If we are trying to shrink the contents to fit on the page
|
||||
// we must first locate the "pageContent" frame
|
||||
// Then we walk the frame tree and look for the "xmost" frame
|
||||
// this is the frame where the right-hand side of the frame extends
|
||||
// the furthest
|
||||
if (mPrt->mShrinkToFit && documentIsTopLevel) {
|
||||
nsIPageSequenceFrame* pageSequence = aPO->mPresShell->GetPageSequenceFrame();
|
||||
NS_ENSURE_STATE(pageSequence);
|
||||
pageSequence->GetSTFPercent(aPO->mShrinkRatio);
|
||||
}
|
||||
rv = UpdateSelectionAndShrinkPrintObject(aPO, documentIsTopLevel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#ifdef EXTENDED_DEBUG_PRINTING
|
||||
if (kPrintingLogMod && kPrintingLogMod->level == DUMP_LAYOUT_LEVEL) {
|
||||
@ -3309,7 +3574,6 @@ nsPrintEngine::FinishPrintPreview()
|
||||
mOldPrtPreview = nullptr;
|
||||
}
|
||||
|
||||
InstallPrintPreviewListener();
|
||||
|
||||
mPrt->OnEndPrinting();
|
||||
|
||||
@ -3352,22 +3616,9 @@ nsPrintEngine::Observe(nsISupports *aSubject, const char *aTopic, const PRUnicha
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if (mIsDoingPrinting) {
|
||||
rv = DocumentReadyForPrinting();
|
||||
|
||||
/* cleaup on failure + notify user */
|
||||
if (NS_FAILED(rv)) {
|
||||
CleanupOnFailure(rv, true);
|
||||
}
|
||||
} else {
|
||||
rv = FinishPrintPreview();
|
||||
if (NS_FAILED(rv)) {
|
||||
CleanupOnFailure(rv, false);
|
||||
}
|
||||
if (mPrtPreview) {
|
||||
rv = InitPrintDocConstruction(true);
|
||||
if (!mIsDoingPrinting && mPrtPreview) {
|
||||
mPrtPreview->OnEndPrinting();
|
||||
}
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -13,7 +13,10 @@
|
||||
#include "nsPrintData.h"
|
||||
#include "nsFrameList.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsHTMLCanvasElement.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
// Interfaces
|
||||
#include "nsIDocument.h"
|
||||
@ -34,7 +37,9 @@ class nsIWeakReference;
|
||||
// nsPrintEngine Class
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class nsPrintEngine MOZ_FINAL : public nsIObserver
|
||||
class nsPrintEngine MOZ_FINAL : public nsIObserver,
|
||||
public nsIWebProgressListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
// nsISupports interface...
|
||||
@ -43,6 +48,8 @@ public:
|
||||
// nsIObserver
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
// Old nsIWebBrowserPrint methods; not cleaned up yet
|
||||
NS_IMETHOD Print(nsIPrintSettings* aPrintSettings,
|
||||
nsIWebProgressListener* aWebProgressListener);
|
||||
@ -271,6 +278,23 @@ protected:
|
||||
|
||||
FILE* mDebugFile;
|
||||
|
||||
int32_t mLoadCounter;
|
||||
bool mDidLoadDataForPrinting;
|
||||
|
||||
nsresult AfterNetworkPrint(bool aHandleError);
|
||||
|
||||
nsresult SetRootView(nsPrintObject* aPO,
|
||||
bool& aDoReturn,
|
||||
bool& aDocumentIsTopLevel,
|
||||
nsSize& aAdjSize);
|
||||
nsIView* GetParentViewForRoot();
|
||||
bool DoSetPixelScale();
|
||||
void UpdateZoomRatio(nsPrintObject* aPO, bool aSetPixelScale);
|
||||
nsresult ReconstructAndReflow(bool aDoSetPixelScale);
|
||||
nsresult UpdateSelectionAndShrinkPrintObject(nsPrintObject* aPO,
|
||||
bool aDocumentIsTopLevel);
|
||||
nsresult InitPrintDocConstruction(bool aHandleError);
|
||||
void FirePrintPreviewUpdateEvent();
|
||||
private:
|
||||
nsPrintEngine& operator=(const nsPrintEngine& aOther) MOZ_DELETE;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user