mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-24 13:52:37 +00:00
Added support for printing multiple pages
This commit is contained in:
parent
f05cc800e4
commit
e89b2bc6c9
@ -31,6 +31,7 @@ class nsIViewManager;
|
||||
class nsIReflowCommand;
|
||||
class nsIDeviceContext;
|
||||
class nsIRenderingContext;
|
||||
class nsIPageSequenceFrame;
|
||||
|
||||
#define NS_IPRESSHELL_IID \
|
||||
{ 0x76e79c60, 0x944e, 0x11d1, \
|
||||
@ -94,6 +95,12 @@ public:
|
||||
|
||||
virtual nsIFrame* GetRootFrame() = 0;
|
||||
|
||||
/**
|
||||
* Returns the page sequence frame associated with the frame hierarchy.
|
||||
* Returns NULL if not a paginated view.
|
||||
*/
|
||||
NS_IMETHOD GetPageSequenceFrame(nsIPageSequenceFrame*& aPageSequenceFrame) = 0;
|
||||
|
||||
virtual nsIFrame* FindFrameWithContent(nsIContent* aContent) = 0;
|
||||
|
||||
virtual void AppendReflowCommand(nsIReflowCommand* aReflowCommand) = 0;
|
||||
|
@ -223,6 +223,7 @@ public:
|
||||
NS_IMETHOD ResizeReflow(nscoord aWidth, nscoord aHeight);
|
||||
NS_IMETHOD StyleChangeReflow();
|
||||
virtual nsIFrame* GetRootFrame();
|
||||
NS_IMETHOD GetPageSequenceFrame(nsIPageSequenceFrame*& aPageSequenceFrame);
|
||||
virtual nsIFrame* FindFrameWithContent(nsIContent* aContent);
|
||||
virtual void AppendReflowCommand(nsIReflowCommand* aReflowCommand);
|
||||
virtual void ProcessReflowCommands();
|
||||
@ -674,6 +675,33 @@ PresShell::GetRootFrame()
|
||||
return mRootFrame;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::GetPageSequenceFrame(nsIPageSequenceFrame*& aPageSequenceFrame)
|
||||
{
|
||||
nsIFrame* child;
|
||||
nsIPageSequenceFrame* pageSequence;
|
||||
|
||||
// The page sequence frame should be either the immediate child or
|
||||
// its child
|
||||
mRootFrame->FirstChild(nsnull, child);
|
||||
if (nsnull != child) {
|
||||
if (NS_SUCCEEDED(child->QueryInterface(kIPageSequenceFrameIID, (void**)&pageSequence))) {
|
||||
aPageSequenceFrame = pageSequence;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
child->FirstChild(nsnull, child);
|
||||
if (nsnull != child) {
|
||||
if (NS_SUCCEEDED(child->QueryInterface(kIPageSequenceFrameIID, (void**)&pageSequence))) {
|
||||
aPageSequenceFrame = pageSequence;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::BeginUpdate(nsIDocument *aDocument)
|
||||
{
|
||||
|
@ -8,6 +8,7 @@ nsIDocumentContainer.h
|
||||
nsIDocumentObserver.h
|
||||
nsIFrame.h
|
||||
nsIFrameImageLoader.h
|
||||
nsIPageSequenceFrame.h
|
||||
nsIPresContext.h
|
||||
nsIPresShell.h
|
||||
nsIReflowCommand.h
|
||||
|
@ -33,6 +33,7 @@ EXPORTS = \
|
||||
nsIFrame.h \
|
||||
nsIFrameReflow.h \
|
||||
nsIFrameImageLoader.h \
|
||||
nsIPageSequenceFrame.h \
|
||||
nsIPresContext.h \
|
||||
nsIPresShell.h \
|
||||
nsIReflowCommand.h \
|
||||
|
@ -26,6 +26,7 @@ EXPORTS = \
|
||||
nsIFrame.h \
|
||||
nsIFrameReflow.h \
|
||||
nsIFrameImageLoader.h \
|
||||
nsIPageSequenceFrame.h \
|
||||
nsIPresContext.h \
|
||||
nsIPresShell.h \
|
||||
nsIReflowCommand.h \
|
||||
|
@ -31,6 +31,7 @@ class nsIViewManager;
|
||||
class nsIReflowCommand;
|
||||
class nsIDeviceContext;
|
||||
class nsIRenderingContext;
|
||||
class nsIPageSequenceFrame;
|
||||
|
||||
#define NS_IPRESSHELL_IID \
|
||||
{ 0x76e79c60, 0x944e, 0x11d1, \
|
||||
@ -94,6 +95,12 @@ public:
|
||||
|
||||
virtual nsIFrame* GetRootFrame() = 0;
|
||||
|
||||
/**
|
||||
* Returns the page sequence frame associated with the frame hierarchy.
|
||||
* Returns NULL if not a paginated view.
|
||||
*/
|
||||
NS_IMETHOD GetPageSequenceFrame(nsIPageSequenceFrame*& aPageSequenceFrame) = 0;
|
||||
|
||||
virtual nsIFrame* FindFrameWithContent(nsIContent* aContent) = 0;
|
||||
|
||||
virtual void AppendReflowCommand(nsIReflowCommand* aReflowCommand) = 0;
|
||||
|
@ -365,6 +365,7 @@ protected:
|
||||
private:
|
||||
nsIView* mView; // must use accessor member functions
|
||||
|
||||
protected:
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
};
|
||||
|
@ -136,19 +136,6 @@ nsPageFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsPageFrame::Paint(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect)
|
||||
{
|
||||
nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect);
|
||||
|
||||
// For the time being paint a border around the page so we know
|
||||
// where each page begins and ends
|
||||
aRenderingContext.SetColor(NS_RGB(0, 0, 0));
|
||||
aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPageFrame::GetFrameName(nsString& aResult) const
|
||||
{
|
||||
|
@ -28,14 +28,10 @@ public:
|
||||
const nsHTMLReflowState& aMaxSize,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aCX,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame*& aContinuingFrame);
|
||||
|
||||
NS_IMETHOD Paint(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aCX,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame*& aContinuingFrame);
|
||||
|
||||
// Debugging
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
|
@ -23,6 +23,26 @@
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
||||
nsresult
|
||||
nsSimplePageSequenceFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
NS_PRECONDITION(0 != aInstancePtr, "null ptr");
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (aIID.Equals(kIPageSequenceFrameIID)) {
|
||||
*aInstancePtr = (void*)(nsIPageSequenceFrame*)this;
|
||||
return NS_OK;
|
||||
}
|
||||
return nsContainerFrame::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// XXX Hack
|
||||
#define PAGE_SPACING_TWIPS 100
|
||||
@ -163,6 +183,8 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext& aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimplePageSequenceFrame::GetFrameName(nsString& aResult) const
|
||||
{
|
||||
@ -175,12 +197,157 @@ nsSimplePageSequenceFrame::Paint(nsIPresContext& aPresContext,
|
||||
const nsRect& aDirtyRect)
|
||||
{
|
||||
// Paint a white background
|
||||
// XXX Crop marks or hash marks would be nice. Use style info...
|
||||
aRenderingContext.SetColor(NS_RGB(255,255,255));
|
||||
aRenderingContext.FillRect(aDirtyRect);
|
||||
// XXX Crop marks or hash marks would be nice. Use style info...
|
||||
return nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect);
|
||||
}
|
||||
|
||||
void
|
||||
nsSimplePageSequenceFrame::PaintChild(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
// Let the page paint
|
||||
nsContainerFrame::PaintChild(aPresContext, aRenderingContext,
|
||||
aDirtyRect, aFrame);
|
||||
|
||||
// XXX Paint a one-pixel border around the page so it's easy to see where
|
||||
// each page begins and ends when we're in print preview mode
|
||||
nsRect pageBounds;
|
||||
float p2t = aPresContext.GetPixelsToTwips();
|
||||
|
||||
aRenderingContext.SetColor(NS_RGB(0, 0, 0));
|
||||
aFrame->GetRect(pageBounds);
|
||||
pageBounds.Inflate(p2t, p2t);
|
||||
aRenderingContext.DrawRect(pageBounds);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Helper function that sends the progress notification. Returns PR_TRUE
|
||||
// if printing should continue and PR_FALSE otherwise
|
||||
static PRBool
|
||||
SendStatusNotification(nsIPrintStatusCallback* aStatusCallback,
|
||||
PRInt32 aPageNumber,
|
||||
PRInt32 aTotalPages,
|
||||
nsPrintStatus aStatus)
|
||||
{
|
||||
PRBool ret = PR_TRUE;
|
||||
|
||||
if (nsnull != aStatusCallback) {
|
||||
aStatusCallback->OnProgress(aPageNumber, aTotalPages, aStatus,ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimplePageSequenceFrame::Print(nsIPresContext& aPresContext,
|
||||
const nsPrintOptions& aPrintOptions,
|
||||
nsIPrintStatusCallback* aStatusCallback)
|
||||
{
|
||||
// If printing a range of pages make sure at least the starting page
|
||||
// number is valid
|
||||
PRInt32 totalPages = LengthOf(mFirstChild);
|
||||
|
||||
if (ePrintRange_SpecifiedRange == aPrintOptions.range) {
|
||||
if (aPrintOptions.startPage > totalPages) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
// Send the notification that we're beginning to print the document
|
||||
if (!SendStatusNotification(aStatusCallback, -1, totalPages,
|
||||
ePrintStatus_StartDoc)) {
|
||||
return NS_ERROR_ABORT; // indicate client cancelled printing
|
||||
}
|
||||
|
||||
// Begin printing of the document
|
||||
nsIDeviceContext* dc = aPresContext.GetDeviceContext();
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
rv = dc->BeginDocument();
|
||||
if (NS_FAILED(rv)) {
|
||||
if (nsnull != aStatusCallback) {
|
||||
aStatusCallback->OnError(ePrintError_Error);
|
||||
}
|
||||
|
||||
} else {
|
||||
nsIPresShell* presShell = aPresContext.GetShell();
|
||||
nsIViewManager* vm = presShell->GetViewManager();
|
||||
NS_RELEASE(presShell);
|
||||
|
||||
// Print each specified page
|
||||
PRInt32 pageNum = 1;
|
||||
for (nsIFrame* page = mFirstChild;
|
||||
nsnull != page;
|
||||
pageNum++, page->GetNextSibling(page)) {
|
||||
|
||||
// If printing a range of pages check whether the page number is in the
|
||||
// range of pages to print
|
||||
if (ePrintRange_SpecifiedRange == aPrintOptions.range) {
|
||||
if (pageNum < aPrintOptions.startPage) {
|
||||
continue;
|
||||
} else if (pageNum > aPrintOptions.endPage) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Start printing of the page
|
||||
if (!SendStatusNotification(aStatusCallback, pageNum, totalPages,
|
||||
ePrintStatus_StartPage)) {
|
||||
rv = NS_ERROR_ABORT;
|
||||
break;
|
||||
}
|
||||
rv = dc->BeginPage();
|
||||
if (NS_FAILED(rv)) {
|
||||
if (nsnull != aStatusCallback) {
|
||||
aStatusCallback->OnError(ePrintError_Error);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Print the page
|
||||
nsIView* view;
|
||||
page->GetView(view);
|
||||
NS_ASSERTION(nsnull != view, "no page view");
|
||||
vm->Display(view);
|
||||
|
||||
// Finish printing of the page
|
||||
if (!SendStatusNotification(aStatusCallback, pageNum, totalPages,
|
||||
ePrintStatus_EndPage)) {
|
||||
rv = NS_ERROR_ABORT;
|
||||
break;
|
||||
}
|
||||
rv = dc->EndPage();
|
||||
if (NS_FAILED(rv)) {
|
||||
if (nsnull != aStatusCallback) {
|
||||
aStatusCallback->OnError(ePrintError_Error);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Finish printing of the document
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = dc->EndDocument();
|
||||
} else {
|
||||
// rv = dc->AbortDocument();
|
||||
}
|
||||
if (NS_FAILED(rv) && (nsnull != aStatusCallback)) {
|
||||
aStatusCallback->OnError(ePrintError_Error);
|
||||
}
|
||||
SendStatusNotification(aStatusCallback, pageNum - 1, totalPages,
|
||||
ePrintStatus_EndDoc);
|
||||
NS_RELEASE(vm);
|
||||
}
|
||||
|
||||
NS_RELEASE(dc);
|
||||
return rv;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
|
@ -19,21 +19,42 @@
|
||||
#define nsSimplePageSequence_h___
|
||||
|
||||
#include "nsHTMLContainerFrame.h"
|
||||
#include "nsIPageSequenceFrame.h"
|
||||
|
||||
// Simple page sequence frame class. Used when we're in paginated mode
|
||||
class nsSimplePageSequenceFrame : public nsContainerFrame {
|
||||
class nsSimplePageSequenceFrame : public nsContainerFrame,
|
||||
public nsIPageSequenceFrame {
|
||||
public:
|
||||
// nsISupports
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
|
||||
// nsIFrameReflow
|
||||
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aMaxSize,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
// nsIFrame
|
||||
NS_IMETHOD Paint(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
|
||||
// nsIPageSequenceFrame
|
||||
NS_IMETHOD Print(nsIPresContext& aPresContext,
|
||||
const nsPrintOptions& aPrintOptions,
|
||||
nsIPrintStatusCallback* aStatusCallback);
|
||||
|
||||
// Debugging
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
|
||||
protected:
|
||||
virtual void PaintChild(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void) {return nsContainerFrame::AddRef();}
|
||||
NS_IMETHOD_(nsrefcnt) Release(void) {return nsContainerFrame::Release();}
|
||||
};
|
||||
|
||||
#endif /* nsSimplePageSequence_h___ */
|
||||
|
@ -365,6 +365,7 @@ protected:
|
||||
private:
|
||||
nsIView* mView; // must use accessor member functions
|
||||
|
||||
protected:
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
};
|
||||
|
@ -20,7 +20,10 @@
|
||||
#include "nsIAbsoluteItems.h"
|
||||
#include "nsIAnchoredItems.h"
|
||||
#include "nsIHTMLReflow.h"
|
||||
#include "nsIPageSequenceFrame.h"
|
||||
|
||||
const nsIID kIAbsoluteItemsIID = NS_IABSOLUTE_ITEMS_IID;
|
||||
const nsIID kIHTMLContentIID = NS_IHTMLCONTENT_IID;
|
||||
const nsIID kIHTMLReflowIID = NS_IHTMLREFLOW_IID;
|
||||
const nsIID kIPageSequenceFrameIID = NS_IPAGESEQUENCEFRAME_IID;
|
||||
|
||||
|
@ -24,5 +24,6 @@ extern const nsIID kIAbsoluteItemsIID;
|
||||
extern const nsIID kIHTMLContentIID;
|
||||
extern const nsIID kIRunaroundIID;
|
||||
extern const nsIID kIHTMLReflowIID;
|
||||
extern const nsIID kIPageSequenceFrameIID;
|
||||
|
||||
#endif /* nsHTMLIIDs_h___ */
|
||||
|
@ -136,19 +136,6 @@ nsPageFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsPageFrame::Paint(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect)
|
||||
{
|
||||
nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect);
|
||||
|
||||
// For the time being paint a border around the page so we know
|
||||
// where each page begins and ends
|
||||
aRenderingContext.SetColor(NS_RGB(0, 0, 0));
|
||||
aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPageFrame::GetFrameName(nsString& aResult) const
|
||||
{
|
||||
|
@ -28,14 +28,10 @@ public:
|
||||
const nsHTMLReflowState& aMaxSize,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aCX,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame*& aContinuingFrame);
|
||||
|
||||
NS_IMETHOD Paint(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aCX,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame*& aContinuingFrame);
|
||||
|
||||
// Debugging
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
|
@ -223,6 +223,7 @@ public:
|
||||
NS_IMETHOD ResizeReflow(nscoord aWidth, nscoord aHeight);
|
||||
NS_IMETHOD StyleChangeReflow();
|
||||
virtual nsIFrame* GetRootFrame();
|
||||
NS_IMETHOD GetPageSequenceFrame(nsIPageSequenceFrame*& aPageSequenceFrame);
|
||||
virtual nsIFrame* FindFrameWithContent(nsIContent* aContent);
|
||||
virtual void AppendReflowCommand(nsIReflowCommand* aReflowCommand);
|
||||
virtual void ProcessReflowCommands();
|
||||
@ -674,6 +675,33 @@ PresShell::GetRootFrame()
|
||||
return mRootFrame;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::GetPageSequenceFrame(nsIPageSequenceFrame*& aPageSequenceFrame)
|
||||
{
|
||||
nsIFrame* child;
|
||||
nsIPageSequenceFrame* pageSequence;
|
||||
|
||||
// The page sequence frame should be either the immediate child or
|
||||
// its child
|
||||
mRootFrame->FirstChild(nsnull, child);
|
||||
if (nsnull != child) {
|
||||
if (NS_SUCCEEDED(child->QueryInterface(kIPageSequenceFrameIID, (void**)&pageSequence))) {
|
||||
aPageSequenceFrame = pageSequence;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
child->FirstChild(nsnull, child);
|
||||
if (nsnull != child) {
|
||||
if (NS_SUCCEEDED(child->QueryInterface(kIPageSequenceFrameIID, (void**)&pageSequence))) {
|
||||
aPageSequenceFrame = pageSequence;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::BeginUpdate(nsIDocument *aDocument)
|
||||
{
|
||||
|
@ -23,6 +23,26 @@
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
||||
nsresult
|
||||
nsSimplePageSequenceFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
NS_PRECONDITION(0 != aInstancePtr, "null ptr");
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (aIID.Equals(kIPageSequenceFrameIID)) {
|
||||
*aInstancePtr = (void*)(nsIPageSequenceFrame*)this;
|
||||
return NS_OK;
|
||||
}
|
||||
return nsContainerFrame::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// XXX Hack
|
||||
#define PAGE_SPACING_TWIPS 100
|
||||
@ -163,6 +183,8 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext& aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimplePageSequenceFrame::GetFrameName(nsString& aResult) const
|
||||
{
|
||||
@ -175,12 +197,157 @@ nsSimplePageSequenceFrame::Paint(nsIPresContext& aPresContext,
|
||||
const nsRect& aDirtyRect)
|
||||
{
|
||||
// Paint a white background
|
||||
// XXX Crop marks or hash marks would be nice. Use style info...
|
||||
aRenderingContext.SetColor(NS_RGB(255,255,255));
|
||||
aRenderingContext.FillRect(aDirtyRect);
|
||||
// XXX Crop marks or hash marks would be nice. Use style info...
|
||||
return nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect);
|
||||
}
|
||||
|
||||
void
|
||||
nsSimplePageSequenceFrame::PaintChild(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
// Let the page paint
|
||||
nsContainerFrame::PaintChild(aPresContext, aRenderingContext,
|
||||
aDirtyRect, aFrame);
|
||||
|
||||
// XXX Paint a one-pixel border around the page so it's easy to see where
|
||||
// each page begins and ends when we're in print preview mode
|
||||
nsRect pageBounds;
|
||||
float p2t = aPresContext.GetPixelsToTwips();
|
||||
|
||||
aRenderingContext.SetColor(NS_RGB(0, 0, 0));
|
||||
aFrame->GetRect(pageBounds);
|
||||
pageBounds.Inflate(p2t, p2t);
|
||||
aRenderingContext.DrawRect(pageBounds);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Helper function that sends the progress notification. Returns PR_TRUE
|
||||
// if printing should continue and PR_FALSE otherwise
|
||||
static PRBool
|
||||
SendStatusNotification(nsIPrintStatusCallback* aStatusCallback,
|
||||
PRInt32 aPageNumber,
|
||||
PRInt32 aTotalPages,
|
||||
nsPrintStatus aStatus)
|
||||
{
|
||||
PRBool ret = PR_TRUE;
|
||||
|
||||
if (nsnull != aStatusCallback) {
|
||||
aStatusCallback->OnProgress(aPageNumber, aTotalPages, aStatus,ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimplePageSequenceFrame::Print(nsIPresContext& aPresContext,
|
||||
const nsPrintOptions& aPrintOptions,
|
||||
nsIPrintStatusCallback* aStatusCallback)
|
||||
{
|
||||
// If printing a range of pages make sure at least the starting page
|
||||
// number is valid
|
||||
PRInt32 totalPages = LengthOf(mFirstChild);
|
||||
|
||||
if (ePrintRange_SpecifiedRange == aPrintOptions.range) {
|
||||
if (aPrintOptions.startPage > totalPages) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
// Send the notification that we're beginning to print the document
|
||||
if (!SendStatusNotification(aStatusCallback, -1, totalPages,
|
||||
ePrintStatus_StartDoc)) {
|
||||
return NS_ERROR_ABORT; // indicate client cancelled printing
|
||||
}
|
||||
|
||||
// Begin printing of the document
|
||||
nsIDeviceContext* dc = aPresContext.GetDeviceContext();
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
rv = dc->BeginDocument();
|
||||
if (NS_FAILED(rv)) {
|
||||
if (nsnull != aStatusCallback) {
|
||||
aStatusCallback->OnError(ePrintError_Error);
|
||||
}
|
||||
|
||||
} else {
|
||||
nsIPresShell* presShell = aPresContext.GetShell();
|
||||
nsIViewManager* vm = presShell->GetViewManager();
|
||||
NS_RELEASE(presShell);
|
||||
|
||||
// Print each specified page
|
||||
PRInt32 pageNum = 1;
|
||||
for (nsIFrame* page = mFirstChild;
|
||||
nsnull != page;
|
||||
pageNum++, page->GetNextSibling(page)) {
|
||||
|
||||
// If printing a range of pages check whether the page number is in the
|
||||
// range of pages to print
|
||||
if (ePrintRange_SpecifiedRange == aPrintOptions.range) {
|
||||
if (pageNum < aPrintOptions.startPage) {
|
||||
continue;
|
||||
} else if (pageNum > aPrintOptions.endPage) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Start printing of the page
|
||||
if (!SendStatusNotification(aStatusCallback, pageNum, totalPages,
|
||||
ePrintStatus_StartPage)) {
|
||||
rv = NS_ERROR_ABORT;
|
||||
break;
|
||||
}
|
||||
rv = dc->BeginPage();
|
||||
if (NS_FAILED(rv)) {
|
||||
if (nsnull != aStatusCallback) {
|
||||
aStatusCallback->OnError(ePrintError_Error);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Print the page
|
||||
nsIView* view;
|
||||
page->GetView(view);
|
||||
NS_ASSERTION(nsnull != view, "no page view");
|
||||
vm->Display(view);
|
||||
|
||||
// Finish printing of the page
|
||||
if (!SendStatusNotification(aStatusCallback, pageNum, totalPages,
|
||||
ePrintStatus_EndPage)) {
|
||||
rv = NS_ERROR_ABORT;
|
||||
break;
|
||||
}
|
||||
rv = dc->EndPage();
|
||||
if (NS_FAILED(rv)) {
|
||||
if (nsnull != aStatusCallback) {
|
||||
aStatusCallback->OnError(ePrintError_Error);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Finish printing of the document
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = dc->EndDocument();
|
||||
} else {
|
||||
// rv = dc->AbortDocument();
|
||||
}
|
||||
if (NS_FAILED(rv) && (nsnull != aStatusCallback)) {
|
||||
aStatusCallback->OnError(ePrintError_Error);
|
||||
}
|
||||
SendStatusNotification(aStatusCallback, pageNum - 1, totalPages,
|
||||
ePrintStatus_EndDoc);
|
||||
NS_RELEASE(vm);
|
||||
}
|
||||
|
||||
NS_RELEASE(dc);
|
||||
return rv;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
|
@ -19,21 +19,42 @@
|
||||
#define nsSimplePageSequence_h___
|
||||
|
||||
#include "nsHTMLContainerFrame.h"
|
||||
#include "nsIPageSequenceFrame.h"
|
||||
|
||||
// Simple page sequence frame class. Used when we're in paginated mode
|
||||
class nsSimplePageSequenceFrame : public nsContainerFrame {
|
||||
class nsSimplePageSequenceFrame : public nsContainerFrame,
|
||||
public nsIPageSequenceFrame {
|
||||
public:
|
||||
// nsISupports
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
|
||||
// nsIFrameReflow
|
||||
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aMaxSize,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
// nsIFrame
|
||||
NS_IMETHOD Paint(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
|
||||
// nsIPageSequenceFrame
|
||||
NS_IMETHOD Print(nsIPresContext& aPresContext,
|
||||
const nsPrintOptions& aPrintOptions,
|
||||
nsIPrintStatusCallback* aStatusCallback);
|
||||
|
||||
// Debugging
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
|
||||
protected:
|
||||
virtual void PaintChild(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void) {return nsContainerFrame::AddRef();}
|
||||
NS_IMETHOD_(nsrefcnt) Release(void) {return nsContainerFrame::Release();}
|
||||
};
|
||||
|
||||
#endif /* nsSimplePageSequence_h___ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user